summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-12-28 03:01:00 +0000
committerNorbert Preining <norbert@preining.info>2021-12-28 03:01:00 +0000
commitecdf859b6ce481abfd530425dcf6f0f764bd0001 (patch)
tree13bc161dc046876ac6c92fce5f9f5034ba9aa573
parent790995b7e79697514364450bf9c04f1b8d500838 (diff)
CTAN sync 202112280300
-rw-r--r--FILES.byname2855
-rw-r--r--FILES.byname.gzbin2403898 -> 2410264 bytes
-rw-r--r--FILES.last07days2020
-rw-r--r--fonts/newtx/README8
-rw-r--r--fonts/newtx/tex/newtx.sty6
-rw-r--r--fonts/newtx/tex/newtxtext.sty10
-rw-r--r--fonts/newtx/type1/zplr.pfbbin171993 -> 0 bytes
-rw-r--r--graphics/asymptote/ChangeLog4362
-rw-r--r--graphics/asymptote/EXRFiles.cc49
-rw-r--r--graphics/asymptote/EXRFiles.h32
-rw-r--r--graphics/asymptote/GLTextures.cc48
-rw-r--r--graphics/asymptote/GLTextures.h127
-rw-r--r--graphics/asymptote/GUI/CustMatTransform.py40
-rw-r--r--graphics/asymptote/GUI/DebugFlags.py3
-rw-r--r--graphics/asymptote/GUI/GuidesManager.py27
-rw-r--r--graphics/asymptote/GUI/InplaceAddObj.py179
-rw-r--r--graphics/asymptote/GUI/PrimitiveShape.py22
-rw-r--r--graphics/asymptote/GUI/SetCustomAnchor.py20
-rw-r--r--graphics/asymptote/GUI/Widg_addLabel.py14
-rw-r--r--graphics/asymptote/GUI/Widg_addPolyOpt.py9
-rw-r--r--graphics/asymptote/GUI/Widg_editBezier.py13
-rw-r--r--graphics/asymptote/GUI/Window1.py837
-rw-r--r--graphics/asymptote/GUI/configs/xasyconfig.cson3
-rw-r--r--graphics/asymptote/GUI/configs/xasykeymap.cson9
-rw-r--r--graphics/asymptote/GUI/icons_rc.py2721
-rw-r--r--graphics/asymptote/GUI/labelEditor.py46
-rw-r--r--graphics/asymptote/GUI/pyUIClass/custMatTransform.py5
-rw-r--r--graphics/asymptote/GUI/pyUIClass/labelTextEditor.py5
-rw-r--r--graphics/asymptote/GUI/pyUIClass/setCustomAnchor.py5
-rw-r--r--graphics/asymptote/GUI/pyUIClass/widg_addLabel.py5
-rw-r--r--graphics/asymptote/GUI/pyUIClass/widg_addPolyOpt.py20
-rw-r--r--graphics/asymptote/GUI/pyUIClass/widg_editBezier.py5
-rw-r--r--graphics/asymptote/GUI/pyUIClass/widgetPointEditor.py5
-rw-r--r--graphics/asymptote/GUI/pyUIClass/window1.py81
-rw-r--r--graphics/asymptote/GUI/res/icons.qrc3
-rw-r--r--graphics/asymptote/GUI/res/icons/brush.svg13
-rw-r--r--graphics/asymptote/GUI/res/icons/bucket.asy4
-rw-r--r--graphics/asymptote/GUI/res/icons/bucket.svg16
-rw-r--r--graphics/asymptote/GUI/res/icons/center.svg12
-rw-r--r--graphics/asymptote/GUI/res/icons/centerorigin.svg16
-rw-r--r--graphics/asymptote/GUI/res/icons/closedcurve.asy2
-rw-r--r--graphics/asymptote/GUI/res/icons/closedcurve.svg24
-rw-r--r--graphics/asymptote/GUI/res/icons/closedpolygon.asy2
-rw-r--r--graphics/asymptote/GUI/res/icons/closedpolygon.svg24
-rw-r--r--graphics/asymptote/GUI/res/icons/filledbucket.svg20
-rw-r--r--graphics/asymptote/GUI/res/icons/opencurve.asy2
-rw-r--r--graphics/asymptote/GUI/res/icons/opencurve.svg24
-rw-r--r--graphics/asymptote/GUI/res/icons/openpolygon.asy2
-rw-r--r--graphics/asymptote/GUI/res/icons/openpolygon.svg24
-rw-r--r--graphics/asymptote/GUI/res/icons/redo.svg40
-rw-r--r--graphics/asymptote/GUI/res/icons/undo.svg40
-rw-r--r--graphics/asymptote/GUI/setup.py2
-rw-r--r--graphics/asymptote/GUI/windows/widg_addPolyOpt.ui29
-rw-r--r--graphics/asymptote/GUI/windows/window1.ui113
-rwxr-xr-xgraphics/asymptote/GUI/xasy.py13
-rw-r--r--graphics/asymptote/GUI/xasy2asy.py823
-rw-r--r--graphics/asymptote/GUI/xasyArgs.py25
-rw-r--r--graphics/asymptote/GUI/xasyBezierInterface.py126
-rw-r--r--graphics/asymptote/GUI/xasyFile.py68
-rw-r--r--graphics/asymptote/GUI/xasyOptions.py104
-rw-r--r--graphics/asymptote/GUI/xasyStrings.py4
-rw-r--r--graphics/asymptote/GUI/xasySvg.py10
-rw-r--r--graphics/asymptote/GUI/xasyTransform.py20
-rw-r--r--graphics/asymptote/GUI/xasyUtils.py10
-rw-r--r--graphics/asymptote/LspCpp/LICENSE21
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/Cancellation.h23
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/Condition.h48
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/Context.cpp35
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/Context.h216
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/Endpoint.cpp46
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/Endpoint.h53
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/GCThreadContext.cpp17
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/GCThreadContext.h19
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageIssue.h182
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageJsonHandler.cpp57
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageJsonHandler.h61
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageProducer.h13
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/NotificationInMessage.h62
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/RemoteEndPoint.cpp612
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/RemoteEndPoint.h340
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/RequestInMessage.h70
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/ScopeExit.h59
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/StreamMessageProducer.cpp191
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/StreamMessageProducer.h48
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/TcpServer.cpp299
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/TcpServer.h40
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/WebSocketServer.cpp341
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/WebSocketServer.h87
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/json.h81
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/lsRequestId.h51
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/lsResponseMessage.h71
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/message.cpp88
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/message.h34
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/optional.hpp1846
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/serializer.cpp214
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/serializer.h378
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/stream.h196
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/threaded_queue.cpp20
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/threaded_queue.h249
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/JsonRpc/traits.h158
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/AbsolutePath.h27
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/ClientPreferences.h306
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/CodeActionParams.h114
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/Directory.h13
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/ExecuteCommandParams.h20
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/IProgressMonitor.h145
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/Markup/Markup.cpp942
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/Markup/Markup.h119
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/Markup/string_ref.h1059
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/ParentProcessWatcher.cpp106
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/ParentProcessWatcher.h17
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/ProcessIoService.h48
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/ProtocolJsonHandler.cpp716
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/ProtocolJsonHandler.h11
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/ResourceOperation.h121
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/SimpleTimer.h49
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/client/registerCapability.h49
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/client/unregisterCapability.h41
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/Move.h14
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/OverridableMethod.h34
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/WorkspaceSymbolParams.h13
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/addOverridableMethods.h19
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/buildWorkspace.h17
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkConstructorsStatus.h29
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkDelegateMethodsStatus.h29
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkHashCodeEqualsStatus.h36
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkToStringStatus.h24
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/classFileContents.h10
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/codeActionResult.h22
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/executeCommand.h29
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/findLinks.h22
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateAccessors.h19
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateConstructors.h19
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateDelegateMethods.h25
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateHashCodeEquals.h25
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateToString.h18
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/getMoveDestinations.h65
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/getRefactorEdit.h77
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/listOverridableMethods.h17
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/organizeImports.h12
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/projectConfigurationUpdate.h13
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/resolveUnimplementedAccessors.h24
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/searchSymbols.h27
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/SCTConfig.h37
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/protocol.h222
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/sct.cpp743
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/sct.h103
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/extention/sonarlint/protocol.h176
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/general/InitializeParams.h128
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/general/exit.h7
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/general/initialize.cpp45
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/general/initialize.h39
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/general/initialized.h13
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/general/lsClientCapabilities.h48
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/general/lsServerCapabilities.h589
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/general/lsTextDocumentClientCapabilities.h713
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/general/lsWorkspaceClientCapabilites.h256
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/general/progress.h16
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/general/shutdown.h15
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/language/language.h170
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/location_type.h63
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lru_cache.h151
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsAny.h159
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsCodeAction.h58
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsCommand.h44
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsDocumentUri.h26
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsFormattingOptions.h43
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsMarkedString.h45
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsPosition.h40
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsRange.h32
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsResponseError.h117
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentEdit.h24
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentIdentifier.h14
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentItem.h26
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentPositionParams.h26
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsTextEdit.h87
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsVersionedTextDocumentIdentifier.h32
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsWorkspaceEdit.h57
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsp.cpp1087
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsp_code_action.h64
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsp_completion.h224
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsp_diagnostic.cpp74
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/lsp_diagnostic.h151
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/method_type.h7
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/out_list.h22
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/symbol.h164
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/SemanticTokens.h267
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/callHierarchy.h121
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/code_action.h37
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/code_lens.h42
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/colorPresentation.h63
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/completion.h82
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/declaration_definition.h29
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/didRenameFiles.h44
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_change.h51
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_close.h33
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_open.h39
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_save.h31
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/documentColor.h73
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/document_link.h44
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/document_symbol.h55
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/foldingRange.h62
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/formatting.h32
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/highlight.h18
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/hover.h55
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/implementation.h16
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/linkedEditingRange.h51
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/onTypeFormatting.h44
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/prepareRename.h40
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/publishDiagnostics.h28
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/range_formatting.h35
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/references.h48
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/rename.h41
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveCodeLens.h10
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveCompletionItem.h21
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveTypeHierarchy.h31
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/selectionRange.h52
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/semanticHighlighting.h66
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/signature_help.h92
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/textDocument.cpp349
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/typeHierarchy.h133
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/type_definition.h16
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/willSave.h71
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/utils.cpp602
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/utils.h141
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/windows/MessageNotify.h83
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/working_files.cpp186
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/working_files.h72
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/workspace/applyEdit.h42
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/workspace/configuration.h37
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/workspace/didChangeWorkspaceFolders.h48
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/workspace/did_change_configuration.h25
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/workspace/did_change_watched_files.h46
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/workspace/execute_command.h24
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/workspace/symbol.h16
-rw-r--r--graphics/asymptote/LspCpp/LibLsp/lsp/workspace/workspaceFolders.h34
-rw-r--r--graphics/asymptote/LspCpp/LspCpp.filters465
-rw-r--r--graphics/asymptote/LspCpp/LspCpp.user4
-rw-r--r--graphics/asymptote/LspCpp/LspCpp.vcxproj668
-rw-r--r--graphics/asymptote/LspCpp/LspCpp.vcxproj.filters669
-rw-r--r--graphics/asymptote/LspCpp/LspCpp.vcxproj.user4
-rw-r--r--graphics/asymptote/LspCpp/Makefile40
-rw-r--r--graphics/asymptote/LspCpp/README.md48
-rw-r--r--graphics/asymptote/LspCpp/example/StdIOClientExample.cpp221
-rw-r--r--graphics/asymptote/LspCpp/example/StdIOServerExample.cpp162
-rw-r--r--graphics/asymptote/LspCpp/example/TcpServerExample.cpp200
-rw-r--r--graphics/asymptote/LspCpp/example/WebsocketExample.cpp297
-rw-r--r--graphics/asymptote/LspCpp/macro_map.h134
-rw-r--r--graphics/asymptote/LspCpp/network/optional.hpp711
-rw-r--r--graphics/asymptote/LspCpp/network/string_view.hpp273
-rw-r--r--graphics/asymptote/LspCpp/network/uri.hpp38
-rw-r--r--graphics/asymptote/LspCpp/network/uri/config.hpp20
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/algorithm.hpp73
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/decode.hpp78
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/encode.hpp169
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/grammar.hpp130
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/translate.hpp89
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/uri_advance_parts.cpp76
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/uri_advance_parts.hpp21
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/uri_normalize.cpp87
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/uri_normalize.hpp20
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/uri_parse.cpp424
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/uri_parse.hpp19
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/uri_parse_authority.cpp130
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/uri_parse_authority.hpp21
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/uri_parts.hpp88
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/uri_percent_encode.hpp80
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/uri_resolve.cpp91
-rw-r--r--graphics/asymptote/LspCpp/network/uri/detail/uri_resolve.hpp22
-rw-r--r--graphics/asymptote/LspCpp/network/uri/uri.cpp701
-rw-r--r--graphics/asymptote/LspCpp/network/uri/uri.hpp758
-rw-r--r--graphics/asymptote/LspCpp/network/uri/uri_builder.cpp152
-rw-r--r--graphics/asymptote/LspCpp/network/uri/uri_builder.hpp277
-rw-r--r--graphics/asymptote/LspCpp/network/uri/uri_errors.cpp72
-rw-r--r--graphics/asymptote/LspCpp/network/uri/uri_errors.hpp122
-rw-r--r--graphics/asymptote/LspCpp/network/uri/uri_io.hpp62
-rw-r--r--graphics/asymptote/LspCpp/packages.config14
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/CHANGE_LOG88
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/COPYING5
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/Jamfile.v213
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/Jamrules1
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/LICENSE_1_0.txt23
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/Makefile32
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/README10
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/TODO36
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool.hpp28
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/future.hpp215
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/locking_ptr.hpp85
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/pool_core.hpp453
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/scope_guard.hpp65
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/worker_thread.hpp115
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/future.hpp144
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/pool.hpp232
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/pool_adaptors.hpp70
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/scheduling_policies.hpp262
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/shutdown_policies.hpp83
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/size_policies.hpp99
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/task_adaptors.hpp168
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/Makefile36
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design.dox145
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design.txt35
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design_header.htm38
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples.dox145
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples.txt14
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples_header.htm38
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer/common_footer.htm17
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer/overview_footer.htm17
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer_sf/common_footer.htm30
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer_sf/overview_footer.htm29
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/index.html9
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview.dox145
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview.txt205
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview_header.htm36
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/reference.dox220
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/reference_header.htm40
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/threadpool.css331
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial.dox145
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial.txt207
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial_header.htm40
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/example/mergesort/Jamfile.v211
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/example/mergesort/mergesort.cpp200
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/Jamfile.v211
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/README7
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/quickstart.cpp50
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/test/compile_all/Jamfile.v211
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/test/compile_all/compile_all.cpp149
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/tutorial/Jamfile.v211
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/tutorial/tutorial.cpp263
-rw-r--r--graphics/asymptote/LspCpp/third_party/threadpool/project-root.jam2
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/CMakeLists.txt42
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/LICENSE23
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/README.md1503
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/samples/docsample.cpp64
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8.h34
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/checked.h335
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/core.h338
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/cpp11.h103
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/cpp17.h103
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/unchecked.h274
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/tests/CMakeLists.txt47
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/tests/docker/Dockerfile5
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/tests/negative.cpp59
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_checked_api.cpp189
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_checked_iterator.cpp32
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_cpp11.cpp109
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_cpp17.cpp88
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_data/utf8_invalid.txtbin0 -> 20010 bytes
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_unchecked_api.cpp161
-rw-r--r--graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_unchecked_iterator.cpp34
-rw-r--r--graphics/asymptote/Makefile.in63
-rw-r--r--graphics/asymptote/README2
-rw-r--r--graphics/asymptote/ReleaseNotes26
-rw-r--r--graphics/asymptote/_config.yml1
-rw-r--r--graphics/asymptote/abs3doutfile.h75
-rw-r--r--graphics/asymptote/absyn.cc3
-rw-r--r--graphics/asymptote/absyn.h4
-rw-r--r--graphics/asymptote/asy-keywords.el6
-rw-r--r--graphics/asymptote/asy.list790
-rw-r--r--graphics/asymptote/asymptote.spec7
-rw-r--r--graphics/asymptote/base/asy-mode.el8
-rw-r--r--graphics/asymptote/base/graph.asy23
-rw-r--r--graphics/asymptote/base/math.asy24
-rw-r--r--graphics/asymptote/base/plain.asy8
-rw-r--r--graphics/asymptote/base/plain_boxes.asy10
-rw-r--r--graphics/asymptote/base/plain_constants.asy18
-rw-r--r--graphics/asymptote/base/plain_filldraw.asy12
-rw-r--r--graphics/asymptote/base/plain_margins.asy20
-rw-r--r--graphics/asymptote/base/plain_markers.asy34
-rw-r--r--graphics/asymptote/base/plain_paths.asy32
-rw-r--r--graphics/asymptote/base/plain_pens.asy23
-rw-r--r--graphics/asymptote/base/plain_picture.asy118
-rw-r--r--graphics/asymptote/base/plain_prethree.asy13
-rw-r--r--graphics/asymptote/base/plain_scaling.asy18
-rw-r--r--graphics/asymptote/base/plain_shipout.asy18
-rw-r--r--graphics/asymptote/base/plain_strings.asy18
-rw-r--r--graphics/asymptote/base/pstoedit.asy2
-rw-r--r--graphics/asymptote/base/rational.asy2
-rw-r--r--graphics/asymptote/base/roundedpath.asy30
-rw-r--r--graphics/asymptote/base/shaders/blend.glsl84
-rw-r--r--graphics/asymptote/base/shaders/count.glsl11
-rw-r--r--graphics/asymptote/base/shaders/count0.glsl11
-rw-r--r--graphics/asymptote/base/shaders/fragment.glsl179
-rw-r--r--graphics/asymptote/base/shaders/offset.glsl11
-rw-r--r--graphics/asymptote/base/shaders/partialsum.glsl54
-rw-r--r--graphics/asymptote/base/shaders/postsum.glsl30
-rw-r--r--graphics/asymptote/base/shaders/presum.glsl34
-rw-r--r--graphics/asymptote/base/shaders/screen.glsl5
-rw-r--r--graphics/asymptote/base/shaders/vertex.glsl15
-rw-r--r--graphics/asymptote/base/simplex.asy6
-rw-r--r--graphics/asymptote/base/slide.asy24
-rw-r--r--graphics/asymptote/base/slopefield.asy8
-rw-r--r--graphics/asymptote/base/smoothcontour3.asy38
-rw-r--r--graphics/asymptote/base/solids.asy24
-rw-r--r--graphics/asymptote/base/stats.asy2
-rw-r--r--graphics/asymptote/base/syzygy.asy8
-rw-r--r--graphics/asymptote/base/three.asy259
-rw-r--r--graphics/asymptote/base/three_arrows.asy24
-rw-r--r--graphics/asymptote/base/three_light.asy6
-rw-r--r--graphics/asymptote/base/three_margins.asy20
-rw-r--r--graphics/asymptote/base/three_surface.asy256
-rw-r--r--graphics/asymptote/base/three_tube.asy25
-rw-r--r--graphics/asymptote/base/trembling.asy12
-rw-r--r--graphics/asymptote/base/v3d.asy643
-rw-r--r--graphics/asymptote/base/v3dheadertypes.asy66
-rw-r--r--graphics/asymptote/base/v3dtypes.asy34
-rw-r--r--graphics/asymptote/base/webgl/asygl.js4
-rw-r--r--graphics/asymptote/base/x11colors.asy2
-rw-r--r--graphics/asymptote/bbox.h15
-rw-r--r--graphics/asymptote/beziercurve.h2
-rw-r--r--graphics/asymptote/bezierpatch.cc311
-rw-r--r--graphics/asymptote/bezierpatch.h11
-rw-r--r--graphics/asymptote/binaries/i386-windows/README2
-rwxr-xr-xgraphics/asymptote/binaries/i386-windows/cygwin1.dllbin3002325 -> 3276463 bytes
-rw-r--r--graphics/asymptote/binaries/x86_64-windows/README2
-rw-r--r--graphics/asymptote/binaries/x86_64-windows/cygwin1.dllbin3541856 -> 3551236 bytes
-rw-r--r--graphics/asymptote/build-scripts/HOWTO-MSWindows5
-rwxr-xr-xgraphics/asymptote/build-scripts/build-asymptote6
-rwxr-xr-xgraphics/asymptote/build-scripts/build-asymptote.dos6
-rw-r--r--graphics/asymptote/camp.tab.cc2710
-rw-r--r--graphics/asymptote/camp.tab.h133
-rw-r--r--graphics/asymptote/camperror.cc2
-rw-r--r--graphics/asymptote/common.h19
-rw-r--r--graphics/asymptote/config.h.in12
-rwxr-xr-xgraphics/asymptote/configure237
-rw-r--r--graphics/asymptote/configure.ac59
-rw-r--r--graphics/asymptote/constructor.cc2
-rw-r--r--graphics/asymptote/cudareflect/EXRFiles.cc104
-rw-r--r--graphics/asymptote/cudareflect/EXRFiles.h71
-rw-r--r--graphics/asymptote/cudareflect/IrradianceGenerator.sln25
-rw-r--r--graphics/asymptote/cudareflect/IrradianceGenerator.vcxproj119
-rw-r--r--graphics/asymptote/cudareflect/Makefile26
-rw-r--r--graphics/asymptote/cudareflect/ReflectanceMapper.cu272
-rw-r--r--graphics/asymptote/cudareflect/ReflectanceMapper.cuh16
-rw-r--r--graphics/asymptote/cudareflect/common.h14
-rw-r--r--graphics/asymptote/cudareflect/helper.cuh44
-rw-r--r--graphics/asymptote/cudareflect/kernel.cu148
-rw-r--r--graphics/asymptote/cudareflect/kernel.h18
-rw-r--r--graphics/asymptote/cudareflect/main.cc305
-rw-r--r--graphics/asymptote/cudareflect/simpson.cuh103
-rw-r--r--graphics/asymptote/cudareflect/tinyexr.cc15
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/CMakeLists.txt74
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/Makefile25
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/Makefile.gcc-mingw18
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/Makefile.gcc-mingw-msys16
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/Makefile.llvm-mingw25
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/README.md568
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/appveyor.yml13
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/asakusa.exrbin0 -> 1127425 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/asakusa.pngbin0 -> 202947 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindASan.cmake59
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindMSan.cmake57
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindSanitizers.cmake94
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindTSan.cmake65
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindUBSan.cmake46
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/asan-wrapper55
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/sanitize-helpers.cmake177
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/config-msvc.py78
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/deps/miniz/ChangeLog.md196
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/deps/miniz/LICENSE22
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example1.c105
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example2.c164
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example3.c269
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example4.c102
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example5.c327
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example6.c162
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/deps/miniz/miniz.c7733
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/deps/miniz/miniz.h1350
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/deps/miniz/readme.md34
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/common/cxxopts.hpp1988
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image.h7462
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image_resize.h2585
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image_write.h1048
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/Makefile28
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/README.md46
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/cube2longlat.cc470
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/deepview/Makefile2
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/deepview/deepview_screencast.gifbin0 -> 3790199 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/deepview/main.cc277
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/deepview/trackball.cc324
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/deepview/trackball.h81
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/Makefile32
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/README.md7
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/exr2fptiff.cc199
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/tiny_dng_writer.h1356
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exr2ldr/Makefile3
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exr2ldr/exr2ldr.cc111
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exr2rgbe/Makefile3
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exr2rgbe/exr2rgbe.cc38
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/Makefile3
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/README.md5
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/exrfilter.cc150
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/DroidSans.ttfbin0 -> 190044 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/CommonWindowInterface.h130
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/MacOpenGLWindow.h118
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/MacOpenGLWindow.mm1169
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/OpenGL2Include.h59
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/OpenGLInclude.h66
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32InternalWindowData.h68
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32OpenGLWindow.cpp200
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32OpenGLWindow.h64
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32Window.cpp810
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32Window.h86
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.cpp1118
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.h78
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/README.md56
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/glew.h19093
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/glxew.h1750
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/wglew.h1421
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/glew.c18897
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/LICENSE16
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/README.md137
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_cocoa.pngbin0 -> 100007 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_gtk3.pngbin0 -> 63193 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_win8.pngbin0 -> 16188 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/SConstruct99
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/common.h21
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/include/nfd.h69
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_cocoa.m235
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_common.c142
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_common.h37
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_gtk.c326
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_win.cpp619
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/SConstruct70
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_opendialog.c29
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_opendialogmultiple.c34
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_savedialog.c28
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/exr-io.cc60
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/exr-io.h16
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/findOpenGLGlewGlut.lua90
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/main.cc541
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/nuklear.h25417
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/nuklear_btgui_gl2.h386
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/premake4.lua87
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/screenshots/exrview.pngbin0 -> 1044671 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/shader.frag12
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/exrview/shader.vert12
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/ldr2exr/Makefile3
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/ldr2exr/ldr2exr.cc85
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/Makefile3
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/README.md13
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/main.cc267
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/resize/Makefile3
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/resize/resize.cc46
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/rgbe2exr/Makefile3
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/rgbe2exr/rgbe2exr.cc81
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/Makefile3
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/README.md15
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/testmapgen.cc86
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/experimental/js/Makefile2
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/experimental/js/README.md38
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/experimental/js/binding.cc79
-rwxr-xr-xgraphics/asymptote/cudareflect/tinyexr/experimental/js/compile_to_js.sh10
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/experimental/js/index.html41
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/experimental/js/test.js21
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/jni/Android.mk12
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/jni/Application.mk2
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/jni/Makefile8
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/jni/README.md4
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/kuroga.py312
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/premake4.lua55
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/CMakeLists.txt23
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/c-binding/Makefile5
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/c-binding/test.c19
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/exrcat/exrcat.cpp127
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/exrwrite/exrwritetest.cpp132
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/fuzzer/Makefile13
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/fuzzer/README.md16
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/fuzzer/fuzz.cc29
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-62-tinyexr_memcpy_heap-buffer-overflowbin0 -> 64 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-63-tinyexr_signed-integer-overflowbin0 -> 503 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-77-heap-buffer-overflowbin0 -> 20829 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/issues/160/README.md1
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/issues/160/main.py57
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/issues/160/requirements.txt3
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/Makefile21
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/README.md30
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/catch.hpp10445
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/config-msvc.py52
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/config-posix.py53
-rwxr-xr-xgraphics/asymptote/cudareflect/tinyexr/test/unit/kuroga.py312
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/2by2.exrbin0 -> 395 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/flaga.exrbin0 -> 4731 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/issue-160-piz-decode.exrbin0 -> 155069 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/piz-bug-issue-100.exrbin0 -> 327 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-1383755b301e5f505b2198dc0508918b537fdf48bbfc6deeffe268822e6f6cd6bin0 -> 473703 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-24322747c47e87a10e4407528b779a1a763a48135384909b3d1010bbba1d4c28_minbin0 -> 630 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-255456016cca60ddb5c5ed6898182e13739bf687b17d1411e97bb60ad95e7a84_minbin0 -> 832 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-360c3b0555cb979ca108f2d178cf8a80959cfeabaa4ec1d310d062fa653a8c6b_minbin0 -> 4738 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-3f1f642c3356fd8e8d2a0787613ec09a56572b3a1e38c9629b6db9e8dead1117_minbin0 -> 4471 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-5ace655ef080932dcc7e4abc9eab1d4f82c845453464993dfa3eb6c5822a1621bin0 -> 298 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-5b66774a7498c635334ad386be0c3b359951738ac47f14878a3346d1c6ea0fe5_minbin0 -> 678 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-d5c9c893e559277a3320c196523095b94db93985620ac338d037487e0e613047_minbin0 -> 132 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-df76d1f27adb8927a1446a603028272140905c168a336128465a1162ec7af270.minibin0 -> 15 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-e7fa6404daa861369d2172fe68e08f9d38c0989f57da7bcfb510bab67e19ca9fbin0 -> 473695 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-eedff3a9e99eb1c0fd3a3b0989e7c44c0a69f04f10b23e5264f362a4773f4397_minbin0 -> 793 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-efe9007bfdcbbe8a1569bf01fa9acadb8261ead49cb83f6e91fcdc4dae2e99a3_minbin0 -> 15 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/regression/tiled_half_1x1_alpha.exrbin0 -> 335 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/tester.cc1714
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/vcbuild.bat4
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/win32-filelist-utf16le.incbin0 -> 50 bytes
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test/unit/win32-filelist-utf8.inc1
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/test_tinyexr.cc469
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/tinyexr.cc8
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/tinyexr.h8535
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/vcbuild.bat11
-rw-r--r--graphics/asymptote/cudareflect/tinyexr/vcsetup2019.bat4
-rw-r--r--graphics/asymptote/cudareflect/utils.cuh84
-rw-r--r--graphics/asymptote/dec.cc268
-rw-r--r--graphics/asymptote/dec.h121
-rw-r--r--graphics/asymptote/doc/CAD.pdfbin186216 -> 198823 bytes
-rw-r--r--graphics/asymptote/doc/FAQ/asy-faq.info2
-rw-r--r--graphics/asymptote/doc/Makefile.in10
-rw-r--r--graphics/asymptote/doc/TeXShopAndAsymptote.pdfbin77206 -> 81162 bytes
-rw-r--r--graphics/asymptote/doc/asy-latex.pdfbin194511 -> 206973 bytes
-rw-r--r--graphics/asymptote/doc/asy.135
-rw-r--r--graphics/asymptote/doc/asyRefCard.pdfbin121128 -> 121145 bytes
-rw-r--r--graphics/asymptote/doc/asymptote.pdfbin1212419 -> 1241549 bytes
-rw-r--r--graphics/asymptote/doc/asymptote.texi836
-rw-r--r--graphics/asymptote/doc/graphwithderiv.asy11
-rw-r--r--graphics/asymptote/doc/latexusage.tex1
-rw-r--r--graphics/asymptote/doc/legend.asy2
-rw-r--r--graphics/asymptote/doc/ocg.sty130
-rw-r--r--graphics/asymptote/doc/png/asymptote.info1250
-rw-r--r--graphics/asymptote/doc/secondaryaxis.asy3
-rw-r--r--graphics/asymptote/drawelement.h38
-rw-r--r--graphics/asymptote/drawlabel.cc5
-rw-r--r--graphics/asymptote/drawlayer.h30
-rw-r--r--graphics/asymptote/drawpath3.cc12
-rw-r--r--graphics/asymptote/drawpath3.h4
-rw-r--r--graphics/asymptote/drawsurface.cc152
-rw-r--r--graphics/asymptote/drawsurface.h160
-rw-r--r--graphics/asymptote/errormsg.cc2
-rw-r--r--graphics/asymptote/errormsg.h40
-rw-r--r--graphics/asymptote/examples/1overx.asy9
-rw-r--r--graphics/asymptote/examples/NURBSsurface.asy2
-rw-r--r--graphics/asymptote/examples/alignedaxis.asy2
-rw-r--r--graphics/asymptote/examples/layers.asy2
-rw-r--r--graphics/asymptote/examples/markregular.asy4
-rw-r--r--graphics/asymptote/examples/orthocenter.asy3
-rw-r--r--graphics/asymptote/examples/spectrum.asy2
-rw-r--r--graphics/asymptote/examples/strokepath.asy1
-rw-r--r--graphics/asymptote/examples/teapot.asy196
-rw-r--r--graphics/asymptote/examples/teapotIBL.asy2
-rw-r--r--graphics/asymptote/examples/transparency.asy3
-rw-r--r--graphics/asymptote/examples/workcone.asy2
-rw-r--r--graphics/asymptote/exp.cc196
-rw-r--r--graphics/asymptote/exp.h106
-rw-r--r--graphics/asymptote/fftw++.cc2
-rw-r--r--graphics/asymptote/fftw++.h59
-rw-r--r--graphics/asymptote/fftw++asy.cc2
-rw-r--r--graphics/asymptote/fileio.cc2
-rw-r--r--graphics/asymptote/fileio.h119
-rw-r--r--graphics/asymptote/fundec.cc87
-rw-r--r--graphics/asymptote/fundec.h27
-rwxr-xr-xgraphics/asymptote/generate_enums.py183
-rw-r--r--graphics/asymptote/glrender.cc661
-rw-r--r--graphics/asymptote/glrender.h32
-rw-r--r--graphics/asymptote/impdatum.cc2
-rw-r--r--graphics/asymptote/index.html9
-rw-r--r--graphics/asymptote/interact.cc10
-rw-r--r--graphics/asymptote/jsfile.cc180
-rw-r--r--graphics/asymptote/jsfile.h95
-rw-r--r--graphics/asymptote/lspserv.cc741
-rw-r--r--graphics/asymptote/lspserv.h188
-rw-r--r--graphics/asymptote/main.cc47
-rw-r--r--graphics/asymptote/makeUnique.h43
-rw-r--r--graphics/asymptote/material.h31
-rw-r--r--graphics/asymptote/memory.h2
-rw-r--r--graphics/asymptote/name.cc19
-rw-r--r--graphics/asymptote/name.h56
-rw-r--r--graphics/asymptote/newexp.cc4
-rw-r--r--graphics/asymptote/pair.h9
-rw-r--r--graphics/asymptote/parser.cc2
-rw-r--r--graphics/asymptote/pen.h14
-rw-r--r--graphics/asymptote/picture.cc215
-rw-r--r--graphics/asymptote/picture.h14
-rw-r--r--graphics/asymptote/prc/oPRCFile.h40
-rw-r--r--graphics/asymptote/predicates.cc22
-rw-r--r--graphics/asymptote/process.cc302
-rw-r--r--graphics/asymptote/process.h83
-rw-r--r--graphics/asymptote/psfile.cc11
-rw-r--r--graphics/asymptote/psfile.h6
-rw-r--r--graphics/asymptote/revision.cc4
-rw-r--r--graphics/asymptote/runfile.cc251
-rw-r--r--graphics/asymptote/runfile.in11
-rw-r--r--graphics/asymptote/runlabel.cc2
-rw-r--r--graphics/asymptote/runlabel.in2
-rw-r--r--graphics/asymptote/runpicture.cc180
-rw-r--r--graphics/asymptote/runpicture.in52
-rw-r--r--graphics/asymptote/runtime.cc1092
-rw-r--r--graphics/asymptote/runtime.in20
-rwxr-xr-xgraphics/asymptote/runtime.pl25
-rw-r--r--graphics/asymptote/settings.cc71
-rw-r--r--graphics/asymptote/settings.h1
-rw-r--r--graphics/asymptote/shaders.cc61
-rw-r--r--graphics/asymptote/shaders.h16
-rw-r--r--graphics/asymptote/stack.cc8
-rw-r--r--graphics/asymptote/statistics.h5
-rw-r--r--graphics/asymptote/stm.cc131
-rw-r--r--graphics/asymptote/stm.h63
-rw-r--r--graphics/asymptote/symbol.cc7
-rw-r--r--graphics/asymptote/symbol.h5
-rw-r--r--graphics/asymptote/symbolmaps.cc828
-rw-r--r--graphics/asymptote/symbolmaps.h945
-rw-r--r--graphics/asymptote/testv3d.asy202
-rw-r--r--graphics/asymptote/texfile.cc44
-rw-r--r--graphics/asymptote/texfile.h101
-rw-r--r--graphics/asymptote/tinyexr.cc14
-rw-r--r--graphics/asymptote/triple.h10
-rw-r--r--graphics/asymptote/v3dfile.cc353
-rw-r--r--graphics/asymptote/v3dfile.h176
-rw-r--r--graphics/asymptote/v3dheadertypes.csv19
-rw-r--r--graphics/asymptote/v3dheadertypes.h69
-rw-r--r--graphics/asymptote/v3dheadertypes.py64
-rw-r--r--graphics/asymptote/v3dtypes.csv38
-rw-r--r--graphics/asymptote/v3dtypes.h37
-rw-r--r--graphics/asymptote/v3dtypes.py32
-rw-r--r--graphics/asymptote/varinit.cc6
-rw-r--r--graphics/asymptote/webgl/fragment.glsl167
-rw-r--r--graphics/asymptote/webgl/gl.js526
-rw-r--r--graphics/asymptote/webgl/license2
-rw-r--r--graphics/asymptote/webgl/vertex.glsl80
-rw-r--r--graphics/asymptote/xstream.h139
-rw-r--r--info/kaytannollista-latexia/README.md153
-rw-r--r--info/kaytannollista-latexia/kaytannollista-latexia.pdfbin0 -> 875011 bytes
-rw-r--r--info/kaytannollista-latexia/kaytannollista-latexia.tex504
-rw-r--r--info/kaytannollista-latexia/kirjallisuutta.bib78
-rw-r--r--info/kaytannollista-latexia/luku-asetukset.tex2952
-rw-r--r--info/kaytannollista-latexia/luku-erikoiset.tex589
-rw-r--r--info/kaytannollista-latexia/luku-esipuhe.tex47
-rw-r--r--info/kaytannollista-latexia/luku-merkintakieli.tex2235
-rw-r--r--info/kaytannollista-latexia/luku-rakenne.tex7903
-rw-r--r--info/kaytannollista-latexia/luku-valmistautuminen.tex430
-rw-r--r--info/kaytannollista-latexia/tavutusvihjeet.tex796
-rw-r--r--info/kaytannollista-latexia/versio.tex1
-rw-r--r--info/mathalphabets/README.md18
-rw-r--r--info/mathalphabets/mathalphabets.pdfbin0 -> 282632 bytes
-rw-r--r--info/mathalphabets/src/maref.bib177
-rw-r--r--info/mathalphabets/src/mathalphabets.tex715
-rw-r--r--macros/latex/contrib/codebox/codebox-doc-en.pdfbin69553 -> 69443 bytes
-rw-r--r--macros/latex/contrib/codebox/codebox.dtx61
-rw-r--r--macros/latex/contrib/codebox/codebox.pdfbin280271 -> 281819 bytes
-rw-r--r--[-rwxr-xr-x]macros/latex/contrib/codebox/hellojava.java0
-rw-r--r--macros/latex/contrib/diffcoeff/README.txt27
-rw-r--r--macros/latex/contrib/diffcoeff/diffcoeff-doc.def7
-rw-r--r--macros/latex/contrib/diffcoeff/diffcoeff.pdf8729
-rw-r--r--macros/latex/contrib/diffcoeff/diffcoeff.sty186
-rw-r--r--macros/latex/contrib/diffcoeff/diffcoeff.tex2675
-rw-r--r--macros/latex/contrib/wrapfig2/README.txt24
-rw-r--r--macros/latex/contrib/wrapfig2/wrapfig2.dtx1397
-rw-r--r--macros/latex/contrib/wrapfig2/wrapfig2.pdfbin0 -> 511808 bytes
-rw-r--r--systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl4
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb117
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.md52
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha5122
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc14
-rw-r--r--systems/texlive/tlnet/tlpkg/texlive.tlpdb.xzbin2335968 -> 2336164 bytes
-rw-r--r--systems/win32/miktex/tm/packages/next/pr.ini8
-rw-r--r--systems/win32/miktex/tm/packages/pr.ini8
-rw-r--r--timestamp2
760 files changed, 211772 insertions, 16150 deletions
diff --git a/FILES.byname b/FILES.byname
index b440a1e4ff..2c3b4adfc5 100644
--- a/FILES.byname
+++ b/FILES.byname
@@ -5107,7 +5107,7 @@
1990/10/02 | 5440 | dviware/vutex/vaxvms.hlp
1990/10/02 | 812 | dviware/vutex/vaxvms.ins
1990/10/02 | 127576 | dviware/vutex/vutex.web
-2021/12/26 | 218575 | FILES.last07days
+2021/12/27 | 220965 | FILES.last07days
2021/07/24 | 1139410 | fonts/aboensis/Aboensis.glyphs
2021/07/24 | 18907382 | fonts/aboensis/aboensis.pdf
2021/07/24 | 137860 | fonts/aboensis/Aboensis-Regular.otf
@@ -82294,7 +82294,7 @@
2021/12/18 | 199896 | fonts/newtx/opentype/TeXGyreTermesX-Italic.otf
2021/12/17 | 207280 | fonts/newtx/opentype/TeXGyreTermesX-Regular.otf
2021/12/18 | 206192 | fonts/newtx/opentype/TeXGyreTermesX-Slanted.otf
-2021/12/24 | 41261 | fonts/newtx/README
+2021/12/27 | 41551 | fonts/newtx/README
2018/06/07 | 312975 | fonts/newtxsf/doc/newtxsf-doc.pdf
2018/06/07 | 6059 | fonts/newtxsf/doc/newtxsf-doc.tex
2014/09/30 | 43780 | fonts/newtxsf/doc/OFL-FAQ.txt
@@ -82339,9 +82339,9 @@
2019/10/01 | 164 | fonts/newtx/tex/newtx-ebgaramond-subs.tex
2019/10/01 | 149 | fonts/newtx/tex/newtx-libertine-subs.tex
2021/12/20 | 139753 | fonts/newtx/tex/newtxmath.sty
-2021/12/24 | 3987 | fonts/newtx/tex/newtx.sty
+2021/12/27 | 4000 | fonts/newtx/tex/newtx.sty
2020/12/19 | 144 | fonts/newtx/tex/newtx-subs.tex
-2021/12/20 | 19108 | fonts/newtx/tex/newtxtext.sty
+2021/12/27 | 19130 | fonts/newtx/tex/newtxtext.sty
2019/10/23 | 818 | fonts/newtx/tex/omlntxebgmi.fd
2016/10/07 | 1919 | fonts/newtx/tex/omlntxmi.fd
2018/04/27 | 781 | fonts/newtx/tex/omlntxstx2mi.fd
@@ -83128,7 +83128,6 @@
2012/05/16 | 29142 | fonts/newtx/type1/txsy5.pfb
2012/05/15 | 29124 | fonts/newtx/type1/txsy7.pfb
2019/09/12 | 40320 | fonts/newtx/type1/txsys.pfb
-2021/12/18 | 171993 | fonts/newtx/type1/zplr.pfb
2021/12/18 | 242844 | fonts/newtx/type1/ztmbi.pfb
2021/12/18 | 239149 | fonts/newtx/type1/ztmb.pfb
2021/12/18 | 243201 | fonts/newtx/type1/ztmbsl.pfb
@@ -83269,7 +83268,7 @@
2019/11/02 | 2656 | fonts/newtx/vf/zutbmi.vf
2021/03/22 | 2176 | fonts/newtx/vf/zutmia.vf
2019/11/02 | 2552 | fonts/newtx/vf/zutmi.vf
-2021/12/25 | 9514335 | fonts/newtx.zip
+2021/12/27 | 9343039 | fonts/newtx.zip
2005/10/24 | 6224 | fonts/niceframe/afm/bbding10.afm
2005/10/24 | 2299 | fonts/niceframe/afm/dingbat.afm
2005/10/24 | 9099 | fonts/niceframe/afm/karta15.afm
@@ -145261,937 +145260,1439 @@
2012/11/17 | 1096 | graphics/AddTeX2Eps/default.tex
2006/04/17 | 836 | graphics/AddTeX2Eps/readme.txt
2012/11/17 | 5620 | graphics/AddTeX2Eps.zip
-2021/03/15 | 472 | graphics/asymptote/absyn.cc
-2021/03/15 | 1030 | graphics/asymptote/absyn.h
-2021/03/15 | 3297 | graphics/asymptote/access.cc
-2021/03/15 | 2964 | graphics/asymptote/access.h
-2021/03/15 | 2266 | graphics/asymptote/align.h
-2021/03/15 | 886 | graphics/asymptote/angle.h
-2021/03/15 | 18578 | graphics/asymptote/application.cc
-2021/03/15 | 9088 | graphics/asymptote/application.h
-2021/03/15 | 4735 | graphics/asymptote/array.cc
-2021/03/15 | 1975 | graphics/asymptote/array.h
-2021/03/15 | 13980 | graphics/asymptote/arrayop.h
-2021/03/15 | 11541 | graphics/asymptote/aspy.py
-2021/03/15 | 4286 | graphics/asymptote/asy.ico
-2021/03/15 | 17820 | graphics/asymptote/asy-keywords.el
-2021/03/15 | 207386 | graphics/asymptote/asy.list
-2021/03/15 | 1612 | graphics/asymptote/asy-list.pl
-2021/03/15 | 6370 | graphics/asymptote/asymptote.nsi
-2021/03/15 | 3001 | graphics/asymptote/asymptote.spec
-2021/03/15 | 770 | graphics/asymptote/asy.rc
-2021/03/15 | 34 | graphics/asymptote/autogen.sh
-2021/03/15 | 12534 | graphics/asymptote/ax_pthread.m4
-2021/03/15 | 42 | graphics/asymptote/base/animate.asy
-2021/03/15 | 5238 | graphics/asymptote/base/animation.asy
-2021/03/15 | 578 | graphics/asymptote/base/annotate.asy
-2021/03/15 | 99 | graphics/asymptote/base/asy_filetype.vim
-2021/03/15 | 268 | graphics/asymptote/base/asy-init.el
-2021/03/15 | 8243 | graphics/asymptote/base/asy-kate.sh
-2021/03/15 | 71241 | graphics/asymptote/base/asy-mode.el
-2021/03/15 | 1276 | graphics/asymptote/base/asymptote.py
-2021/03/15 | 8870 | graphics/asymptote/base/asy.vim
-2021/03/15 | 50 | graphics/asymptote/base/babel.asy
-2021/03/15 | 9562 | graphics/asymptote/base/bezulate.asy
-2021/03/15 | 11656 | graphics/asymptote/base/binarytree.asy
-2021/03/15 | 5279 | graphics/asymptote/base/bsp.asy
-2021/03/15 | 10840 | graphics/asymptote/base/CAD.asy
-2021/03/15 | 205495 | graphics/asymptote/base/colormap.asy
-2021/03/15 | 14749 | graphics/asymptote/base/contour3.asy
-2021/03/15 | 20277 | graphics/asymptote/base/contour.asy
-2021/03/15 | 2109 | graphics/asymptote/base/drawtree.asy
-2021/03/15 | 1178 | graphics/asymptote/base/embed.asy
-2021/03/15 | 1120 | graphics/asymptote/base/external.asy
-2021/03/15 | 21448 | graphics/asymptote/base/feynman.asy
-2021/03/15 | 15277 | graphics/asymptote/base/flowchart.asy
-2021/03/15 | 35 | graphics/asymptote/base/fontsize.asy
-2021/03/15 | 320403 | graphics/asymptote/base/geometry.asy
-2021/03/15 | 70102 | graphics/asymptote/base/graph3.asy
-2021/03/15 | 63520 | graphics/asymptote/base/graph.asy
-2021/03/15 | 314 | graphics/asymptote/base/graph_settings.asy
-2021/03/15 | 7407 | graphics/asymptote/base/graph_splinetype.asy
-2021/03/15 | 13605 | graphics/asymptote/base/grid3.asy
-2021/03/15 | 3936 | graphics/asymptote/base/interpolate.asy
-2021/03/15 | 2451 | graphics/asymptote/base/labelpath3.asy
-2021/03/15 | 729 | graphics/asymptote/base/labelpath.asy
-2021/03/15 | 25357 | graphics/asymptote/base/lmfit.asy
-2021/03/15 | 908 | graphics/asymptote/base/map.asy
-2021/03/15 | 7302 | graphics/asymptote/base/markers.asy
-2021/03/15 | 11008 | graphics/asymptote/base/math.asy
-2021/03/15 | 251 | graphics/asymptote/base/metapost.asy
-2021/03/15 | 39 | graphics/asymptote/base/nopapersize.ps
-2021/03/15 | 3278 | graphics/asymptote/base/obj.asy
-2021/03/15 | 15601 | graphics/asymptote/base/ode.asy
-2021/03/15 | 14982 | graphics/asymptote/base/palette.asy
-2021/03/15 | 2613 | graphics/asymptote/base/patterns.asy
-2021/03/15 | 1213 | graphics/asymptote/base/plain_arcs.asy
-2021/03/15 | 22594 | graphics/asymptote/base/plain_arrows.asy
-2021/03/15 | 7189 | graphics/asymptote/base/plain.asy
-2021/03/15 | 20989 | graphics/asymptote/base/plain_bounds.asy
-2021/03/15 | 4094 | graphics/asymptote/base/plain_boxes.asy
-2021/03/15 | 3716 | graphics/asymptote/base/plain_constants.asy
-2021/03/15 | 2187 | graphics/asymptote/base/plain_debugger.asy
-2021/03/15 | 6292 | graphics/asymptote/base/plain_filldraw.asy
-2021/03/15 | 16492 | graphics/asymptote/base/plain_Label.asy
-2021/03/15 | 2582 | graphics/asymptote/base/plain_margins.asy
-2021/03/15 | 11320 | graphics/asymptote/base/plain_markers.asy
-2021/03/15 | 9309 | graphics/asymptote/base/plain_paths.asy
-2021/03/15 | 8661 | graphics/asymptote/base/plain_pens.asy
-2021/03/15 | 46727 | graphics/asymptote/base/plain_picture.asy
-2021/03/15 | 6285 | graphics/asymptote/base/plain_prethree.asy
-2021/03/15 | 5760 | graphics/asymptote/base/plain_scaling.asy
-2021/03/15 | 4078 | graphics/asymptote/base/plain_shipout.asy
-2021/03/15 | 6169 | graphics/asymptote/base/plain_strings.asy
-2021/03/15 | 358 | graphics/asymptote/base/pstoedit.asy
-2021/03/15 | 5003 | graphics/asymptote/base/rational.asy
-2021/03/15 | 9826 | graphics/asymptote/base/rationalSimplex.asy
-2021/03/15 | 657 | graphics/asymptote/base/reload.js
-2021/03/15 | 289 | graphics/asymptote/base/res/notes.txt
-2021/03/15 | 3430 | graphics/asymptote/base/roundedpath.asy
-2021/03/15 | 5277 | graphics/asymptote/base/shaders/fragment.glsl
-2021/03/15 | 630 | graphics/asymptote/base/shaders/vertex.glsl
-2021/03/15 | 8347 | graphics/asymptote/base/simplex.asy
-2021/03/15 | 608 | graphics/asymptote/base/size10.asy
-2021/03/15 | 600 | graphics/asymptote/base/size11.asy
-2021/03/15 | 16150 | graphics/asymptote/base/slide.asy
-2021/03/15 | 2046 | graphics/asymptote/base/slopefield.asy
-2021/03/15 | 56037 | graphics/asymptote/base/smoothcontour3.asy
-2021/03/15 | 12035 | graphics/asymptote/base/solids.asy
-2021/03/15 | 7307 | graphics/asymptote/base/stats.asy
-2021/03/15 | 22971 | graphics/asymptote/base/syzygy.asy
-2021/03/15 | 2277 | graphics/asymptote/base/texcolors.asy
-2021/03/15 | 23791 | graphics/asymptote/base/three_arrows.asy
-2021/03/15 | 85627 | graphics/asymptote/base/three.asy
-2021/03/15 | 3724 | graphics/asymptote/base/three_light.asy
-2021/03/15 | 2764 | graphics/asymptote/base/three_margins.asy
-2021/03/15 | 72394 | graphics/asymptote/base/three_surface.asy
-2021/03/15 | 5880 | graphics/asymptote/base/three_tube.asy
-2021/03/15 | 1375 | graphics/asymptote/base/tree.asy
-2021/03/15 | 5797 | graphics/asymptote/base/trembling.asy
-2021/03/15 | 4992 | graphics/asymptote/base/tube.asy
-2021/03/15 | 60150 | graphics/asymptote/base/webgl/asygl.js
-2021/03/15 | 4812 | graphics/asymptote/base/x11colors.asy
-2021/03/15 | 3640 | graphics/asymptote/bbox3.h
-2021/03/15 | 4473 | graphics/asymptote/bbox.h
-2021/03/15 | 1828 | graphics/asymptote/beziercurve.cc
-2021/03/15 | 1270 | graphics/asymptote/beziercurve.h
-2021/03/15 | 32094 | graphics/asymptote/bezierpatch.cc
-2021/03/15 | 5595 | graphics/asymptote/bezierpatch.h
-2018/02/02 | 3002325 | graphics/asymptote/binaries/i386-windows/cygwin1.dll
-2021/03/15 | 2505 | graphics/asymptote/binaries/i386-windows/README
-2021/03/15 | 8649728 | graphics/asymptote/binaries/i386-windows/texlive/asy.exe
+2021/12/27 | 2557 | graphics/asymptote/abs3doutfile.h
+2021/12/27 | 504 | graphics/asymptote/absyn.cc
+2021/12/27 | 1140 | graphics/asymptote/absyn.h
+2021/12/27 | 3297 | graphics/asymptote/access.cc
+2021/12/27 | 2964 | graphics/asymptote/access.h
+2021/12/27 | 2266 | graphics/asymptote/align.h
+2021/12/27 | 886 | graphics/asymptote/angle.h
+2021/12/27 | 18578 | graphics/asymptote/application.cc
+2021/12/27 | 9088 | graphics/asymptote/application.h
+2021/12/27 | 4735 | graphics/asymptote/array.cc
+2021/12/27 | 1975 | graphics/asymptote/array.h
+2021/12/27 | 13980 | graphics/asymptote/arrayop.h
+2021/12/27 | 11541 | graphics/asymptote/aspy.py
+2021/12/27 | 4286 | graphics/asymptote/asy.ico
+2021/12/27 | 17902 | graphics/asymptote/asy-keywords.el
+2021/12/27 | 208085 | graphics/asymptote/asy.list
+2021/12/27 | 1612 | graphics/asymptote/asy-list.pl
+2021/12/27 | 6370 | graphics/asymptote/asymptote.nsi
+2021/12/27 | 3040 | graphics/asymptote/asymptote.spec
+2021/12/27 | 770 | graphics/asymptote/asy.rc
+2021/12/27 | 34 | graphics/asymptote/autogen.sh
+2021/12/27 | 12534 | graphics/asymptote/ax_pthread.m4
+2021/12/27 | 42 | graphics/asymptote/base/animate.asy
+2021/12/27 | 5238 | graphics/asymptote/base/animation.asy
+2021/12/27 | 578 | graphics/asymptote/base/annotate.asy
+2021/12/27 | 99 | graphics/asymptote/base/asy_filetype.vim
+2021/12/27 | 268 | graphics/asymptote/base/asy-init.el
+2021/12/27 | 8243 | graphics/asymptote/base/asy-kate.sh
+2021/12/27 | 71368 | graphics/asymptote/base/asy-mode.el
+2021/12/27 | 1276 | graphics/asymptote/base/asymptote.py
+2021/12/27 | 8870 | graphics/asymptote/base/asy.vim
+2021/12/27 | 50 | graphics/asymptote/base/babel.asy
+2021/12/27 | 9562 | graphics/asymptote/base/bezulate.asy
+2021/12/27 | 11656 | graphics/asymptote/base/binarytree.asy
+2021/12/27 | 5279 | graphics/asymptote/base/bsp.asy
+2021/12/27 | 10840 | graphics/asymptote/base/CAD.asy
+2021/12/27 | 205495 | graphics/asymptote/base/colormap.asy
+2021/12/27 | 14749 | graphics/asymptote/base/contour3.asy
+2021/12/27 | 20277 | graphics/asymptote/base/contour.asy
+2021/12/27 | 2109 | graphics/asymptote/base/drawtree.asy
+2021/12/27 | 1178 | graphics/asymptote/base/embed.asy
+2021/12/27 | 1120 | graphics/asymptote/base/external.asy
+2021/12/27 | 21448 | graphics/asymptote/base/feynman.asy
+2021/12/27 | 15277 | graphics/asymptote/base/flowchart.asy
+2021/12/27 | 35 | graphics/asymptote/base/fontsize.asy
+2021/12/27 | 320403 | graphics/asymptote/base/geometry.asy
+2021/12/27 | 70102 | graphics/asymptote/base/graph3.asy
+2021/12/27 | 64207 | graphics/asymptote/base/graph.asy
+2021/12/27 | 314 | graphics/asymptote/base/graph_settings.asy
+2021/12/27 | 7407 | graphics/asymptote/base/graph_splinetype.asy
+2021/12/27 | 13605 | graphics/asymptote/base/grid3.asy
+2021/12/27 | 3936 | graphics/asymptote/base/interpolate.asy
+2021/12/27 | 2451 | graphics/asymptote/base/labelpath3.asy
+2021/12/27 | 729 | graphics/asymptote/base/labelpath.asy
+2021/12/27 | 25357 | graphics/asymptote/base/lmfit.asy
+2021/12/27 | 908 | graphics/asymptote/base/map.asy
+2021/12/27 | 7302 | graphics/asymptote/base/markers.asy
+2021/12/27 | 11122 | graphics/asymptote/base/math.asy
+2021/12/27 | 251 | graphics/asymptote/base/metapost.asy
+2021/12/27 | 39 | graphics/asymptote/base/nopapersize.ps
+2021/12/27 | 3278 | graphics/asymptote/base/obj.asy
+2021/12/27 | 15601 | graphics/asymptote/base/ode.asy
+2021/12/27 | 14982 | graphics/asymptote/base/palette.asy
+2021/12/27 | 2613 | graphics/asymptote/base/patterns.asy
+2021/12/27 | 1213 | graphics/asymptote/base/plain_arcs.asy
+2021/12/27 | 22594 | graphics/asymptote/base/plain_arrows.asy
+2021/12/27 | 7295 | graphics/asymptote/base/plain.asy
+2021/12/27 | 20989 | graphics/asymptote/base/plain_bounds.asy
+2021/12/27 | 4088 | graphics/asymptote/base/plain_boxes.asy
+2021/12/27 | 3706 | graphics/asymptote/base/plain_constants.asy
+2021/12/27 | 2187 | graphics/asymptote/base/plain_debugger.asy
+2021/12/27 | 6278 | graphics/asymptote/base/plain_filldraw.asy
+2021/12/27 | 16492 | graphics/asymptote/base/plain_Label.asy
+2021/12/27 | 2310 | graphics/asymptote/base/plain_margins.asy
+2021/12/27 | 11373 | graphics/asymptote/base/plain_markers.asy
+2021/12/27 | 9334 | graphics/asymptote/base/plain_paths.asy
+2021/12/27 | 8711 | graphics/asymptote/base/plain_pens.asy
+2021/12/27 | 46531 | graphics/asymptote/base/plain_picture.asy
+2021/12/27 | 6287 | graphics/asymptote/base/plain_prethree.asy
+2021/12/27 | 5735 | graphics/asymptote/base/plain_scaling.asy
+2021/12/27 | 4487 | graphics/asymptote/base/plain_shipout.asy
+2021/12/27 | 6159 | graphics/asymptote/base/plain_strings.asy
+2021/12/27 | 354 | graphics/asymptote/base/pstoedit.asy
+2021/12/27 | 4996 | graphics/asymptote/base/rational.asy
+2021/12/27 | 9826 | graphics/asymptote/base/rationalSimplex.asy
+2021/12/27 | 657 | graphics/asymptote/base/reload.js
+2021/12/27 | 289 | graphics/asymptote/base/res/notes.txt
+2021/12/27 | 3374 | graphics/asymptote/base/roundedpath.asy
+2021/12/27 | 1765 | graphics/asymptote/base/shaders/blend.glsl
+2021/12/27 | 176 | graphics/asymptote/base/shaders/count0.glsl
+2021/12/27 | 187 | graphics/asymptote/base/shaders/count.glsl
+2021/12/27 | 5877 | graphics/asymptote/base/shaders/fragment.glsl
+2021/12/27 | 193 | graphics/asymptote/base/shaders/offset.glsl
+2021/12/27 | 1086 | graphics/asymptote/base/shaders/partialsum.glsl
+2021/12/27 | 496 | graphics/asymptote/base/shaders/postsum.glsl
+2021/12/27 | 521 | graphics/asymptote/base/shaders/presum.glsl
+2021/12/27 | 129 | graphics/asymptote/base/shaders/screen.glsl
+2021/12/27 | 677 | graphics/asymptote/base/shaders/vertex.glsl
+2021/12/27 | 8342 | graphics/asymptote/base/simplex.asy
+2021/12/27 | 608 | graphics/asymptote/base/size10.asy
+2021/12/27 | 600 | graphics/asymptote/base/size11.asy
+2021/12/27 | 16089 | graphics/asymptote/base/slide.asy
+2021/12/27 | 2031 | graphics/asymptote/base/slopefield.asy
+2021/12/27 | 55991 | graphics/asymptote/base/smoothcontour3.asy
+2021/12/27 | 12012 | graphics/asymptote/base/solids.asy
+2021/12/27 | 7305 | graphics/asymptote/base/stats.asy
+2021/12/27 | 22946 | graphics/asymptote/base/syzygy.asy
+2021/12/27 | 2277 | graphics/asymptote/base/texcolors.asy
+2021/12/27 | 23717 | graphics/asymptote/base/three_arrows.asy
+2021/12/27 | 86123 | graphics/asymptote/base/three.asy
+2021/12/27 | 3719 | graphics/asymptote/base/three_light.asy
+2021/12/27 | 2492 | graphics/asymptote/base/three_margins.asy
+2021/12/27 | 73066 | graphics/asymptote/base/three_surface.asy
+2021/12/27 | 5975 | graphics/asymptote/base/three_tube.asy
+2021/12/27 | 1375 | graphics/asymptote/base/tree.asy
+2021/12/27 | 5789 | graphics/asymptote/base/trembling.asy
+2021/12/27 | 4992 | graphics/asymptote/base/tube.asy
+2021/12/27 | 14758 | graphics/asymptote/base/v3d.asy
+2021/12/27 | 1323 | graphics/asymptote/base/v3dheadertypes.asy
+2021/12/27 | 670 | graphics/asymptote/base/v3dtypes.asy
+2021/12/27 | 66559 | graphics/asymptote/base/webgl/asygl.js
+2021/12/27 | 4811 | graphics/asymptote/base/x11colors.asy
+2021/12/27 | 3640 | graphics/asymptote/bbox3.h
+2021/12/27 | 4514 | graphics/asymptote/bbox.h
+2021/12/27 | 1828 | graphics/asymptote/beziercurve.cc
+2021/12/27 | 1280 | graphics/asymptote/beziercurve.h
+2021/12/27 | 25325 | graphics/asymptote/bezierpatch.cc
+2021/12/27 | 5712 | graphics/asymptote/bezierpatch.h
+2021/12/03 | 3276463 | graphics/asymptote/binaries/i386-windows/cygwin1.dll
+2021/12/27 | 2505 | graphics/asymptote/binaries/i386-windows/README
+2021/12/27 | 8426496 | graphics/asymptote/binaries/i386-windows/texlive/asy.exe
2020/08/06 | 297 | graphics/asymptote/binaries/i386-windows/texlive/README
-2020/07/09 | 3541856 | graphics/asymptote/binaries/x86_64-windows/cygwin1.dll
-2021/03/15 | 2505 | graphics/asymptote/binaries/x86_64-windows/README
-2021/03/15 | 8617984 | graphics/asymptote/binaries/x86_64-windows/texlive/asy.exe
+2021/12/03 | 3551236 | graphics/asymptote/binaries/x86_64-windows/cygwin1.dll
+2021/12/27 | 2505 | graphics/asymptote/binaries/x86_64-windows/README
+2021/12/27 | 8303104 | graphics/asymptote/binaries/x86_64-windows/texlive/asy.exe
2020/08/06 | 297 | graphics/asymptote/binaries/x86_64-windows/texlive/README
-2021/03/15 | 242 | graphics/asymptote/BUGS
-2021/03/15 | 1588 | graphics/asymptote/build-scripts/asy-format.el
-2021/03/15 | 210 | graphics/asymptote/build-scripts/asy-indent.el
-2021/03/15 | 1227 | graphics/asymptote/build-scripts/build-asygl
-2021/03/15 | 2482 | graphics/asymptote/build-scripts/build-asymptote
-2021/03/15 | 3507 | graphics/asymptote/build-scripts/build-asymptote.dos
-2021/03/15 | 1578 | graphics/asymptote/build-scripts/cc-format.el
-2021/03/15 | 183 | graphics/asymptote/build-scripts/cc-indent.el
-2021/03/15 | 2181 | graphics/asymptote/build-scripts/HOWTO-MSWindows
-2021/03/15 | 297 | graphics/asymptote/build-scripts/README-binaries
-2021/03/15 | 202 | graphics/asymptote/build-scripts/run-in-indent.el
-2021/03/15 | 31342 | graphics/asymptote/builtin.cc
-2021/03/15 | 1630 | graphics/asymptote/builtin.h
-2021/03/15 | 1151 | graphics/asymptote/callable.cc
-2021/03/15 | 1640 | graphics/asymptote/callable.h
-2021/03/15 | 1183 | graphics/asymptote/camperror.cc
-2021/03/15 | 814 | graphics/asymptote/camperror.h
-2021/03/15 | 13357 | graphics/asymptote/camp.l
-2021/03/15 | 127885 | graphics/asymptote/camp.tab.cc
-2021/03/15 | 4089 | graphics/asymptote/camp.tab.h
-2021/03/15 | 20029 | graphics/asymptote/camp.y
-2021/03/15 | 4629 | graphics/asymptote/castop.h
-2021/03/15 | 1876 | graphics/asymptote/cc-mode2.el
-2021/03/15 | 1447427 | graphics/asymptote/ChangeLog
-2021/03/15 | 7790 | graphics/asymptote/coder.cc
-2021/03/15 | 11642 | graphics/asymptote/coder.h
-2021/03/15 | 1126 | graphics/asymptote/coenv.cc
-2021/03/15 | 908 | graphics/asymptote/coenv.h
-2021/03/15 | 1846 | graphics/asymptote/common.h
-2021/03/15 | 48441 | graphics/asymptote/config.guess
-2021/03/15 | 6951 | graphics/asymptote/config.h.in
-2021/03/15 | 31609 | graphics/asymptote/config.sub
-2021/03/15 | 287885 | graphics/asymptote/configure
-2021/03/15 | 15179 | graphics/asymptote/configure.ac
-2021/03/15 | 3668 | graphics/asymptote/constructor.cc
-2021/03/15 | 20840 | graphics/asymptote/dec.cc
-2021/03/15 | 15822 | graphics/asymptote/dec.h
-2021/03/15 | 5883 | graphics/asymptote/Delaunay.cc
-2021/03/15 | 384 | graphics/asymptote/Delaunay.h
-2021/03/15 | 8184 | graphics/asymptote/doc/asy.1
-2021/03/15 | 1005 | graphics/asymptote/doc/asy.1.begin
-2021/03/15 | 333 | graphics/asymptote/doc/asy.1.end
-2021/03/15 | 2800 | graphics/asymptote/doc/asycolors.sty
-2021/03/15 | 18101 | graphics/asymptote/doc/asy-latex.dtx
-2021/03/15 | 194511 | graphics/asymptote/doc/asy-latex.pdf
-2021/03/15 | 1212419 | graphics/asymptote/doc/asymptote.pdf
-2021/03/15 | 9811 | graphics/asymptote/doc/asymptote.sty
-2021/03/15 | 388740 | graphics/asymptote/doc/asymptote.texi
-2021/03/15 | 121128 | graphics/asymptote/doc/asyRefCard.pdf
-2021/03/15 | 20051 | graphics/asymptote/doc/asyRefCard.tex
-2021/03/15 | 246 | graphics/asymptote/doc/axis3.asy
-2021/03/15 | 416 | graphics/asymptote/doc/bezier2.asy
-2021/03/15 | 81 | graphics/asymptote/doc/bezier.asy
-2021/03/15 | 234 | graphics/asymptote/doc/beziercurve.asy
-2021/03/15 | 41 | graphics/asymptote/doc/bigdiagonal.asy
-2021/03/15 | 306 | graphics/asymptote/doc/binarytreetest.asy
-2021/03/15 | 677 | graphics/asymptote/doc/Bode.asy
-2021/03/15 | 524 | graphics/asymptote/doc/brokenaxis.asy
-2021/03/15 | 1391 | graphics/asymptote/doc/CAD1.asy
-2021/03/15 | 186216 | graphics/asymptote/doc/CAD.pdf
-2021/03/15 | 10196 | graphics/asymptote/doc/CAD.tex
-2021/03/15 | 518 | graphics/asymptote/doc/CDlabel.asy
-2021/03/15 | 4348 | graphics/asymptote/doc/colo-asy.tex
-2021/03/15 | 49 | graphics/asymptote/doc/colons.asy
-2021/03/15 | 1620 | graphics/asymptote/doc/colors.asy
-2021/03/15 | 243 | graphics/asymptote/doc/cube.asy
-2021/03/15 | 86 | graphics/asymptote/doc/cylinderskeleton.asy
-2021/03/15 | 218 | graphics/asymptote/doc/datagraph.asy
-2021/03/15 | 24 | graphics/asymptote/doc/diagonal.asy
-2021/03/15 | 2979 | graphics/asymptote/doc/diatom.asy
-2021/03/15 | 4067 | graphics/asymptote/doc/diatom.csv
-2021/03/15 | 49 | graphics/asymptote/doc/dots.asy
-2021/03/15 | 1051 | graphics/asymptote/doc/eetomumu.asy
-2021/03/15 | 2034 | graphics/asymptote/doc/elliptic.asy
-2021/03/15 | 912 | graphics/asymptote/doc/errorbars.asy
-2021/03/15 | 202 | graphics/asymptote/doc/exp.asy
-2021/03/15 | 343 | graphics/asymptote/doc/externalprc.tex
-2021/03/15 | 19597 | graphics/asymptote/doc/external-proposal.html
-2021/03/15 | 25154 | graphics/asymptote/doc/extra/intro.asy
-2021/03/15 | 40899 | graphics/asymptote/doc/FAQ/asy-faq.bfnn
-2021/03/15 | 63136 | graphics/asymptote/doc/FAQ/asy-faq.info
-2021/03/15 | 9328 | graphics/asymptote/doc/FAQ/bfnnconv.pl
-2021/03/15 | 13663 | graphics/asymptote/doc/FAQ/install-sh
-2021/03/15 | 1000 | graphics/asymptote/doc/FAQ/Makefile
-2021/03/15 | 4718 | graphics/asymptote/doc/FAQ/m-ascii.pl
-2021/03/15 | 9822 | graphics/asymptote/doc/FAQ/m-html.pl
-2021/03/15 | 5627 | graphics/asymptote/doc/FAQ/m-info.pl
-2021/03/15 | 6104 | graphics/asymptote/doc/FAQ/m-lout.pl
-2021/03/15 | 4578 | graphics/asymptote/doc/FAQ/m-post.pl
-2021/03/15 | 238 | graphics/asymptote/doc/filegraph.asy
-2021/03/15 | 26 | graphics/asymptote/doc/filegraph.dat
-2021/03/15 | 604 | graphics/asymptote/doc/flow.asy
-2021/03/15 | 897 | graphics/asymptote/doc/flowchartdemo.asy
-2021/03/15 | 464 | graphics/asymptote/doc/GaussianSurface.asy
-2021/03/15 | 376 | graphics/asymptote/doc/generalaxis3.asy
-2021/03/15 | 277 | graphics/asymptote/doc/generalaxis.asy
-2021/03/15 | 754 | graphics/asymptote/doc/graphmarkers.asy
-2021/03/15 | 426 | graphics/asymptote/doc/grid3xyz.asy
-2021/03/15 | 279 | graphics/asymptote/doc/hatch.asy
-2021/03/15 | 423 | graphics/asymptote/doc/helix.asy
-2021/03/15 | 324 | graphics/asymptote/doc/HermiteSpline.asy
-2021/03/15 | 441 | graphics/asymptote/doc/histogram.asy
-2021/03/15 | 521 | graphics/asymptote/doc/Hobbycontrol.asy
-2021/03/15 | 500 | graphics/asymptote/doc/Hobbydir.asy
-2021/03/15 | 378 | graphics/asymptote/doc/icon.asy
-2021/03/15 | 401 | graphics/asymptote/doc/image.asy
-2021/03/15 | 868 | graphics/asymptote/doc/imagecontour.asy
-2021/03/15 | 13663 | graphics/asymptote/doc/install-sh
-2021/03/15 | 357 | graphics/asymptote/doc/irregularcontour.asy
-2021/03/15 | 442 | graphics/asymptote/doc/join3.asy
-2021/03/15 | 261 | graphics/asymptote/doc/join.asy
-2021/03/15 | 417 | graphics/asymptote/doc/knots.asy
-2021/03/15 | 121 | graphics/asymptote/doc/labelsquare.asy
-2021/03/15 | 144 | graphics/asymptote/doc/latexmkrc
-2021/03/15 | 150 | graphics/asymptote/doc/latexmkrc_asydir
-2021/03/15 | 3106 | graphics/asymptote/doc/latexusage.tex
-2021/03/15 | 1008 | graphics/asymptote/doc/leastsquares.asy
-2021/03/15 | 6318 | graphics/asymptote/doc/leastsquares.dat
-2021/03/15 | 397 | graphics/asymptote/doc/legend.asy
-2021/03/15 | 366 | graphics/asymptote/doc/lineargraph0.asy
-2021/03/15 | 373 | graphics/asymptote/doc/lineargraph.asy
-2021/03/15 | 415 | graphics/asymptote/doc/linetype.asy
-2021/03/15 | 423 | graphics/asymptote/doc/log2graph.asy
-2021/03/15 | 262 | graphics/asymptote/doc/loggraph.asy
-2021/03/15 | 382 | graphics/asymptote/doc/loggrid.asy
-2021/03/15 | 480 | graphics/asymptote/doc/logimage.asy
-2021/03/15 | 617 | graphics/asymptote/doc/logo.asy
-2021/03/15 | 314 | graphics/asymptote/doc/logticks.asy
-2021/03/15 | 3023 | graphics/asymptote/doc/Makefile.in
-2021/03/15 | 293 | graphics/asymptote/doc/makepen.asy
-2021/03/15 | 2674 | graphics/asymptote/doc/markers1.asy
-2021/03/15 | 877 | graphics/asymptote/doc/markers2.asy
-2021/03/15 | 288 | graphics/asymptote/doc/mexicanhat.asy
-2021/03/15 | 374 | graphics/asymptote/doc/monthaxis.asy
-2021/03/15 | 458 | graphics/asymptote/doc/multicontour.asy
-2021/03/15 | 3497 | graphics/asymptote/doc/ocg.sty
-2021/03/15 | 115 | graphics/asymptote/doc/onecontour.asy
-2021/03/15 | 240 | graphics/asymptote/doc/parametricgraph.asy
-2021/03/15 | 498 | graphics/asymptote/doc/penfunctionimage.asy
-2021/03/15 | 219 | graphics/asymptote/doc/penimage.asy
-2021/03/15 | 2771 | graphics/asymptote/doc/pixel.pdf
-2021/03/15 | 354 | graphics/asymptote/doc/planes.asy
-2021/03/15 | 465890 | graphics/asymptote/doc/png/asymptote.info
-2021/03/15 | 1469 | graphics/asymptote/doc/png/Makefile.in
-2021/03/15 | 49 | graphics/asymptote/doc/quartercircle.asy
-2021/03/15 | 354 | graphics/asymptote/doc/reloadpdf.tex
-2021/03/15 | 157 | graphics/asymptote/doc/saddle.asy
-2021/03/15 | 355 | graphics/asymptote/doc/scaledgraph.asy
-2021/03/15 | 792 | graphics/asymptote/doc/secondaryaxis.asy
-2021/03/15 | 48847 | graphics/asymptote/doc/secondaryaxis.csv
-2021/03/15 | 256 | graphics/asymptote/doc/shadedtiling.asy
-2021/03/15 | 154 | graphics/asymptote/doc/slopefield1.asy
-2021/03/15 | 52 | graphics/asymptote/doc/square.asy
-2021/03/15 | 341 | graphics/asymptote/doc/subpictures.asy
-2021/03/15 | 123 | graphics/asymptote/doc/superpath.asy
-2021/03/15 | 77206 | graphics/asymptote/doc/TeXShopAndAsymptote.pdf
-2021/03/15 | 2653 | graphics/asymptote/doc/TeXShopAndAsymptote.tex
-2021/03/15 | 390 | graphics/asymptote/doc/tile.asy
-2021/03/15 | 396 | graphics/asymptote/doc/triangulate.asy
-2021/03/15 | 186 | graphics/asymptote/doc/unitcircle3.asy
-2021/03/15 | 147 | graphics/asymptote/doc/vectorfield.asy
-2021/03/15 | 1746 | graphics/asymptote/doc/westnile.asy
-2021/03/15 | 4727 | graphics/asymptote/doc/westnile.csv
-2021/03/15 | 880 | graphics/asymptote/doc/xasy.1x
-2021/03/15 | 1851 | graphics/asymptote/drawclipbegin.h
-2021/03/15 | 1197 | graphics/asymptote/drawclipend.h
-2021/03/15 | 11212 | graphics/asymptote/drawelement.h
-2021/03/15 | 4597 | graphics/asymptote/drawfill.cc
-2021/03/15 | 6525 | graphics/asymptote/drawfill.h
-2021/03/15 | 494 | graphics/asymptote/drawgrestore.h
-2021/03/15 | 2880 | graphics/asymptote/drawgroup.h
-2021/03/15 | 464 | graphics/asymptote/drawgsave.h
-2021/03/15 | 3024 | graphics/asymptote/drawimage.h
-2021/03/15 | 6789 | graphics/asymptote/drawlabel.cc
-2021/03/15 | 2134 | graphics/asymptote/drawlabel.h
-2021/03/15 | 770 | graphics/asymptote/drawlayer.h
-2021/03/15 | 5578 | graphics/asymptote/drawpath3.cc
-2021/03/15 | 5811 | graphics/asymptote/drawpath3.h
-2021/03/15 | 3465 | graphics/asymptote/drawpath.cc
-2021/03/15 | 669 | graphics/asymptote/drawpath.h
-2021/03/15 | 23764 | graphics/asymptote/drawsurface.cc
-2021/03/15 | 19915 | graphics/asymptote/drawsurface.h
-2021/03/15 | 1266 | graphics/asymptote/drawverbatim.h
-2021/03/15 | 17987 | graphics/asymptote/entry.cc
-2021/03/15 | 13615 | graphics/asymptote/entry.h
-2021/03/15 | 5441 | graphics/asymptote/env.cc
-2021/03/15 | 1142 | graphics/asymptote/envcompleter.cc
-2021/03/15 | 845 | graphics/asymptote/envcompleter.h
-2021/03/15 | 4570 | graphics/asymptote/env.h
-2021/03/15 | 10632 | graphics/asymptote/EnvVarUpdate.nsh
-2021/03/15 | 2287 | graphics/asymptote/errormsg.cc
-2021/03/15 | 5052 | graphics/asymptote/errormsg.h
-2021/03/15 | 9251 | graphics/asymptote/errors
-2021/03/15 | 6911 | graphics/asymptote/errortest.asy
-2021/03/15 | 43335 | graphics/asymptote/examples/100d.pdb1
-2021/03/15 | 657 | graphics/asymptote/examples/100d.views
-2021/03/15 | 308 | graphics/asymptote/examples/1overx.asy
-2021/03/15 | 4158 | graphics/asymptote/examples/advection.asy
-2021/03/15 | 245 | graphics/asymptote/examples/alignbox.asy
-2021/03/15 | 2832 | graphics/asymptote/examples/alignedaxis.asy
-2021/03/15 | 946 | graphics/asymptote/examples/animations/cube.asy
-2021/03/15 | 160672 | graphics/asymptote/examples/animations/dice.u3d
-2021/03/15 | 1919 | graphics/asymptote/examples/animations/earthmoon.asy
-2021/03/15 | 503 | graphics/asymptote/examples/animations/embeddedmovie.asy
-2021/03/15 | 196 | graphics/asymptote/examples/animations/embeddedu3d.asy
-2021/03/15 | 411 | graphics/asymptote/examples/animations/externalmovie.asy
-2021/03/15 | 414 | graphics/asymptote/examples/animations/glmovie.asy
-2021/03/15 | 1760 | graphics/asymptote/examples/animations/heatequation.asy
-2021/03/15 | 1037 | graphics/asymptote/examples/animations/inlinemovie3.tex
-2021/03/15 | 1235 | graphics/asymptote/examples/animations/inlinemovie.tex
-2021/03/15 | 326 | graphics/asymptote/examples/animations/pdfmovie.asy
-2021/03/15 | 1247 | graphics/asymptote/examples/animations/slidemovies.asy
-2021/03/15 | 856 | graphics/asymptote/examples/animations/sphere.asy
-2021/03/15 | 798 | graphics/asymptote/examples/animations/torusanimation.asy
-2021/03/15 | 1498 | graphics/asymptote/examples/animations/wavepacket.asy
-2021/03/15 | 1120 | graphics/asymptote/examples/animations/wheel.asy
-2021/03/15 | 236 | graphics/asymptote/examples/annotation.asy
-2021/03/15 | 1240 | graphics/asymptote/examples/arrows3.asy
-2021/03/15 | 61 | graphics/asymptote/examples/axialshade.asy
-2021/03/15 | 496 | graphics/asymptote/examples/bars3.asy
-2021/03/15 | 1033 | graphics/asymptote/examples/basealign.asy
-2021/03/15 | 407 | graphics/asymptote/examples/BezierPatch.asy
-2021/03/15 | 581 | graphics/asymptote/examples/BezierSaddle.asy
-2021/03/15 | 1548 | graphics/asymptote/examples/BezierSurface.asy
-2021/03/15 | 199 | graphics/asymptote/examples/BezierTriangle.asy
-2021/03/15 | 154 | graphics/asymptote/examples/billboard.asy
-2021/03/15 | 513 | graphics/asymptote/examples/buildcycle.asy
-2021/03/15 | 233 | graphics/asymptote/examples/cardioid.asy
-2021/03/15 | 485 | graphics/asymptote/examples/cards.asy
-2021/03/15 | 688 | graphics/asymptote/examples/centroidfg.asy
-2021/03/15 | 322 | graphics/asymptote/examples/cheese.asy
-2021/03/15 | 576 | graphics/asymptote/examples/circles.asy
-2021/03/15 | 228 | graphics/asymptote/examples/circumcircle.asy
-2021/03/15 | 762 | graphics/asymptote/examples/clockarray.asy
-2021/03/15 | 264 | graphics/asymptote/examples/coag.asy
-2021/03/15 | 436 | graphics/asymptote/examples/colorpatch.asy
-2021/03/15 | 472 | graphics/asymptote/examples/colorplanes.asy
-2021/03/15 | 739 | graphics/asymptote/examples/condor.asy
-2021/03/15 | 495 | graphics/asymptote/examples/cones.asy
-2021/03/15 | 1778 | graphics/asymptote/examples/conicurv.asy
-2021/03/15 | 254 | graphics/asymptote/examples/contextfonts.asy
-2021/03/15 | 802 | graphics/asymptote/examples/controlsystem.asy
-2021/03/15 | 123 | graphics/asymptote/examples/Coons.asy
-2021/03/15 | 235 | graphics/asymptote/examples/cos2theta.asy
-2021/03/15 | 582 | graphics/asymptote/examples/cos3.asy
-2021/03/15 | 460 | graphics/asymptote/examples/cosaddition.asy
-2021/03/15 | 5537 | graphics/asymptote/examples/cpkcolors.asy
-2021/03/15 | 572 | graphics/asymptote/examples/curvedlabel3.asy
-2021/03/15 | 177 | graphics/asymptote/examples/curvedlabel.asy
-2021/03/15 | 1835 | graphics/asymptote/examples/cyclohexane.asy
-2021/03/15 | 352 | graphics/asymptote/examples/cylinder.asy
-2021/03/15 | 506 | graphics/asymptote/examples/delu.asy
-2021/03/15 | 509 | graphics/asymptote/examples/dimension.asy
-2021/03/15 | 1216 | graphics/asymptote/examples/dragon.asy
-2021/03/15 | 1298 | graphics/asymptote/examples/electromagnetic.asy
-2021/03/15 | 325 | graphics/asymptote/examples/elevation.asy
-2021/03/15 | 398 | graphics/asymptote/examples/epix.asy
-2021/03/15 | 242 | graphics/asymptote/examples/equilateral.asy
-2021/03/15 | 548 | graphics/asymptote/examples/equilchord.asy
-2021/03/15 | 579 | graphics/asymptote/examples/exp3.asy
-2021/03/15 | 519 | graphics/asymptote/examples/extrudedcontour.asy
-2021/03/15 | 498 | graphics/asymptote/examples/fano.asy
-2021/03/15 | 973 | graphics/asymptote/examples/fequlogo.asy
-2021/03/15 | 727 | graphics/asymptote/examples/fermi.asy
-2021/03/15 | 980 | graphics/asymptote/examples/filesurface.asy
-2021/03/15 | 5543 | graphics/asymptote/examples/filesurface.dat
-2021/03/15 | 570 | graphics/asymptote/examples/fillcontour.asy
-2021/03/15 | 4244 | graphics/asymptote/examples/fin.asy
-2021/03/15 | 710 | graphics/asymptote/examples/fjortoft.asy
-2021/03/15 | 558 | graphics/asymptote/examples/floatingdisk.asy
-2021/03/15 | 500 | graphics/asymptote/examples/floor.asy
-2021/03/15 | 683 | graphics/asymptote/examples/fractaltree.asy
-2021/03/15 | 1185 | graphics/asymptote/examples/functionshading.asy
-2021/03/15 | 499 | graphics/asymptote/examples/galleon.asy
-2021/03/15 | 713 | graphics/asymptote/examples/gamma3.asy
-2021/03/15 | 439 | graphics/asymptote/examples/gamma.asy
-2021/03/15 | 679 | graphics/asymptote/examples/genusthree.asy
-2021/03/15 | 1164 | graphics/asymptote/examples/genustwo.asy
-2021/03/15 | 383 | graphics/asymptote/examples/Gouraud.asy
-2021/03/15 | 616 | graphics/asymptote/examples/Gouraudcontour.asy
-2021/03/15 | 76 | graphics/asymptote/examples/grid.asy
-2021/03/15 | 459 | graphics/asymptote/examples/hierarchy.asy
-2021/03/15 | 315 | graphics/asymptote/examples/hyperboloid.asy
-2021/03/15 | 267 | graphics/asymptote/examples/hyperboloidsilhouette.asy
-2021/03/15 | 1111 | graphics/asymptote/examples/imagehistogram.asy
-2021/03/15 | 610 | graphics/asymptote/examples/impact.asy
-2021/03/15 | 598 | graphics/asymptote/examples/integraltest.asy
-2021/03/15 | 4808 | graphics/asymptote/examples/interpolate1.asy
-2021/03/15 | 289 | graphics/asymptote/examples/jump.asy
-2021/03/15 | 1352 | graphics/asymptote/examples/Klein.asy
-2021/03/15 | 182 | graphics/asymptote/examples/label3.asy
-2021/03/15 | 196 | graphics/asymptote/examples/label3ribbon.asy
-2021/03/15 | 187 | graphics/asymptote/examples/label3solid.asy
-2021/03/15 | 632 | graphics/asymptote/examples/label3zoom.asy
-2021/03/15 | 264 | graphics/asymptote/examples/labelbox.asy
-2021/03/15 | 1114 | graphics/asymptote/examples/laserlattice.asy
-2021/03/15 | 136 | graphics/asymptote/examples/latticeshading.asy
-2021/03/15 | 688 | graphics/asymptote/examples/layers.asy
-2021/03/15 | 460 | graphics/asymptote/examples/lever.asy
-2021/03/15 | 654 | graphics/asymptote/examples/limit.asy
-2021/03/15 | 1910 | graphics/asymptote/examples/linearregression.asy
-2021/03/15 | 168 | graphics/asymptote/examples/lines.asy
-2021/03/15 | 1040 | graphics/asymptote/examples/lmfit1.asy
-2021/03/15 | 206 | graphics/asymptote/examples/log.asy
-2021/03/15 | 349 | graphics/asymptote/examples/logdown.asy
-2021/03/15 | 1461 | graphics/asymptote/examples/logo3.asy
-2021/03/15 | 196 | graphics/asymptote/examples/lowint.asy
-2021/03/15 | 657 | graphics/asymptote/examples/lowupint.asy
-2021/03/15 | 479 | graphics/asymptote/examples/magnetic.asy
-2021/03/15 | 896 | graphics/asymptote/examples/markregular.asy
-2021/03/15 | 1968 | graphics/asymptote/examples/mergeExample.asy
-2021/03/15 | 5216 | graphics/asymptote/examples/mosaic.asy
-2021/03/15 | 2504 | graphics/asymptote/examples/mosquito.asy
-2021/03/15 | 1566 | graphics/asymptote/examples/near_earth.asy
-2021/03/15 | 658 | graphics/asymptote/examples/NURBScurve.asy
-2021/03/15 | 1042 | graphics/asymptote/examples/NURBSsphere.asy
-2021/03/15 | 1551 | graphics/asymptote/examples/NURBSsurface.asy
-2021/03/15 | 1251 | graphics/asymptote/examples/odetest.asy
-2021/03/15 | 308 | graphics/asymptote/examples/oneoverx.asy
-2021/03/15 | 861 | graphics/asymptote/examples/orthocenter.asy
-2021/03/15 | 254 | graphics/asymptote/examples/parametricelevation.asy
-2021/03/15 | 407 | graphics/asymptote/examples/parametricsurface.asy
-2021/03/15 | 711 | graphics/asymptote/examples/partialsurface.asy
-2021/03/15 | 1055 | graphics/asymptote/examples/partitionExample.asy
-2021/03/15 | 426 | graphics/asymptote/examples/pathintersectsurface.asy
-2021/03/15 | 3335 | graphics/asymptote/examples/pdb.asy
-2021/03/15 | 361 | graphics/asymptote/examples/phase.asy
-2021/03/15 | 22873 | graphics/asymptote/examples/piicon.png
-2021/03/15 | 362 | graphics/asymptote/examples/pipeintersection.asy
-2021/03/15 | 3857 | graphics/asymptote/examples/pipes.asy
-2021/03/15 | 418 | graphics/asymptote/examples/planeproject.asy
-2021/03/15 | 930 | graphics/asymptote/examples/polararea.asy
-2021/03/15 | 628 | graphics/asymptote/examples/polarcircle.asy
-2021/03/15 | 326 | graphics/asymptote/examples/polardatagraph.asy
-2021/03/15 | 641 | graphics/asymptote/examples/pOrbital.asy
-2021/03/15 | 954 | graphics/asymptote/examples/poster.asy
-2021/03/15 | 58 | graphics/asymptote/examples/progrid.asy
-2021/03/15 | 373 | graphics/asymptote/examples/projectelevation.asy
-2021/03/15 | 427 | graphics/asymptote/examples/projectrevolution.asy
-2021/03/15 | 747 | graphics/asymptote/examples/pseudosphere.asy
-2021/03/15 | 557 | graphics/asymptote/examples/Pythagoras.asy
-2021/03/15 | 420 | graphics/asymptote/examples/PythagoreanTree.asy
-2021/03/15 | 734 | graphics/asymptote/examples/quilt.asy
-2021/03/15 | 345 | graphics/asymptote/examples/rainbow.asy
-2021/03/15 | 78 | graphics/asymptote/examples/randompath3.asy
-2021/03/15 | 1537 | graphics/asymptote/examples/refs.bib
-2021/03/15 | 990 | graphics/asymptote/examples/RiemannSphere.asy
-2021/03/15 | 348 | graphics/asymptote/examples/RiemannSurface.asy
-2021/03/15 | 384 | graphics/asymptote/examples/RiemannSurfaceRoot.asy
-2021/03/15 | 141 | graphics/asymptote/examples/ring.asy
-2021/03/15 | 184 | graphics/asymptote/examples/roll.asy
-2021/03/15 | 1309 | graphics/asymptote/examples/roundpath.asy
-2021/03/15 | 288 | graphics/asymptote/examples/sacone3D.asy
-2021/03/15 | 445 | graphics/asymptote/examples/sacone.asy
-2021/03/15 | 341 | graphics/asymptote/examples/sacylinder3D.asy
-2021/03/15 | 400 | graphics/asymptote/examples/sacylinder.asy
-2021/03/15 | 66 | graphics/asymptote/examples/shade.asy
-2021/03/15 | 111 | graphics/asymptote/examples/shadestroke.asy
-2021/03/15 | 1065 | graphics/asymptote/examples/shellmethod.asy
-2021/03/15 | 829 | graphics/asymptote/examples/shellsqrtx01.asy
-2021/03/15 | 410 | graphics/asymptote/examples/Sierpinski.asy
-2021/03/15 | 821 | graphics/asymptote/examples/SierpinskiGasket.asy
-2021/03/15 | 2398 | graphics/asymptote/examples/SierpinskiSponge.asy
-2021/03/15 | 327 | graphics/asymptote/examples/sin1x.asy
-2021/03/15 | 579 | graphics/asymptote/examples/sin3.asy
-2021/03/15 | 591 | graphics/asymptote/examples/sinc.asy
-2021/03/15 | 378 | graphics/asymptote/examples/sinxlex.asy
-2021/03/15 | 3358 | graphics/asymptote/examples/slidedemo.asy
-2021/03/15 | 341 | graphics/asymptote/examples/slidedemo_.bbl
-2021/03/15 | 2023 | graphics/asymptote/examples/slope.asy
-2021/03/15 | 520 | graphics/asymptote/examples/smoothelevation.asy
-2021/03/15 | 2680 | graphics/asymptote/examples/soccerball.asy
-2021/03/15 | 2360 | graphics/asymptote/examples/spectrum.asy
-2021/03/15 | 141 | graphics/asymptote/examples/sphere.asy
-2021/03/15 | 150 | graphics/asymptote/examples/spheresilhouette.asy
-2021/03/15 | 162 | graphics/asymptote/examples/sphereskeleton.asy
-2021/03/15 | 376 | graphics/asymptote/examples/sphericalharmonic.asy
-2021/03/15 | 424 | graphics/asymptote/examples/spiral3.asy
-2021/03/15 | 210 | graphics/asymptote/examples/spiral.asy
-2021/03/15 | 608 | graphics/asymptote/examples/spline.asy
-2021/03/15 | 2191 | graphics/asymptote/examples/splitpatch.asy
-2021/03/15 | 38 | graphics/asymptote/examples/spring0.asy
-2021/03/15 | 43 | graphics/asymptote/examples/spring2.asy
-2021/03/15 | 667 | graphics/asymptote/examples/spring.asy
-2021/03/15 | 674 | graphics/asymptote/examples/sqrtx01.asy
-2021/03/15 | 579 | graphics/asymptote/examples/sqrtx01y1.asy
-2021/03/15 | 145 | graphics/asymptote/examples/star.asy
-2021/03/15 | 162 | graphics/asymptote/examples/stereoscopic.asy
-2021/03/15 | 59 | graphics/asymptote/examples/stroke3.asy
-2021/03/15 | 315 | graphics/asymptote/examples/strokepath.asy
-2021/03/15 | 175 | graphics/asymptote/examples/strokeshade.asy
-2021/03/15 | 198 | graphics/asymptote/examples/tanh.asy
-2021/03/15 | 13901 | graphics/asymptote/examples/teapot.asy
-2021/03/15 | 303 | graphics/asymptote/examples/tensor.asy
-2021/03/15 | 547 | graphics/asymptote/examples/tetra.asy
-2021/03/15 | 312 | graphics/asymptote/examples/textpath.asy
-2021/03/15 | 8429 | graphics/asymptote/examples/thermodynamics.asy
-2021/03/15 | 576 | graphics/asymptote/examples/threeviews.asy
-2021/03/15 | 104 | graphics/asymptote/examples/tiling.asy
-2021/03/15 | 419 | graphics/asymptote/examples/torus.asy
-2021/03/15 | 246 | graphics/asymptote/examples/transparency.asy
-2021/03/15 | 250 | graphics/asymptote/examples/transparentCubes.asy
-2021/03/15 | 602 | graphics/asymptote/examples/treetest.asy
-2021/03/15 | 589 | graphics/asymptote/examples/trefoilknot.asy
-2021/03/15 | 972 | graphics/asymptote/examples/triads.asy
-2021/03/15 | 207 | graphics/asymptote/examples/triangle.asy
-2021/03/15 | 441 | graphics/asymptote/examples/triangles.asy
-2021/03/15 | 251 | graphics/asymptote/examples/triceratops.asy
-2021/03/15 | 291 | graphics/asymptote/examples/trumpet.asy
-2021/03/15 | 2101 | graphics/asymptote/examples/truncatedIcosahedron.asy
-2021/03/15 | 40665 | graphics/asymptote/examples/tvgen.asy
-2021/03/15 | 868 | graphics/asymptote/examples/twistedtubes.asy
-2021/03/15 | 26096 | graphics/asymptote/examples/uhrturm.obj
-2021/03/15 | 322 | graphics/asymptote/examples/unitcircle.asy
-2021/03/15 | 430 | graphics/asymptote/examples/unitoctant.asy
-2021/03/15 | 714 | graphics/asymptote/examples/unitoctantx.asy
-2021/03/15 | 199 | graphics/asymptote/examples/upint.asy
-2021/03/15 | 525 | graphics/asymptote/examples/vectorfield3.asy
-2021/03/15 | 351 | graphics/asymptote/examples/vectorfieldsphere.asy
-2021/03/15 | 839 | graphics/asymptote/examples/venn3.asy
-2021/03/15 | 626 | graphics/asymptote/examples/venn.asy
-2021/03/15 | 802 | graphics/asymptote/examples/vertexshading.asy
-2021/03/15 | 360 | graphics/asymptote/examples/washer.asy
-2021/03/15 | 1010 | graphics/asymptote/examples/washermethod.asy
-2021/03/15 | 628 | graphics/asymptote/examples/wedge.asy
-2021/03/15 | 1036 | graphics/asymptote/examples/workcone.asy
-2021/03/15 | 978 | graphics/asymptote/examples/worksheet.asy
-2021/03/15 | 2626 | graphics/asymptote/examples/worldmap.asy
-2021/03/15 | 1261761 | graphics/asymptote/examples/worldmap.dat
-2021/03/15 | 580 | graphics/asymptote/examples/xsin1x.asy
-2021/03/15 | 3739 | graphics/asymptote/examples/xstitch.asy
-2021/03/15 | 743 | graphics/asymptote/examples/xxsq01.asy
-2021/03/15 | 866 | graphics/asymptote/examples/xxsq01x-1.asy
-2021/03/15 | 825 | graphics/asymptote/examples/xxsq01y.asy
-2021/03/15 | 222 | graphics/asymptote/examples/yingyang.asy
-2021/03/15 | 33828 | graphics/asymptote/exp.cc
-2021/03/15 | 28783 | graphics/asymptote/exp.h
-2021/03/15 | 119 | graphics/asymptote/fftw++asy.cc
-2021/03/15 | 1694 | graphics/asymptote/fftw++.cc
-2021/03/15 | 44472 | graphics/asymptote/fftw++.h
-2021/03/15 | 4847 | graphics/asymptote/fileio.cc
-2021/03/15 | 19809 | graphics/asymptote/fileio.h
-2021/03/15 | 1245 | graphics/asymptote/findsym.pl
-2021/03/15 | 1020 | graphics/asymptote/flatguide.cc
-2021/03/15 | 4209 | graphics/asymptote/flatguide.h
-2021/03/15 | 654 | graphics/asymptote/fpu.h
-2021/03/15 | 2164 | graphics/asymptote/frame.h
-2021/03/15 | 7919 | graphics/asymptote/fundec.cc
-2021/03/15 | 4341 | graphics/asymptote/fundec.h
-2021/03/15 | 1160528 | graphics/asymptote/gc-8.0.4.tar.gz
-2021/03/15 | 3153 | graphics/asymptote/genv.cc
-2021/03/15 | 1626 | graphics/asymptote/genv.h
-2021/03/15 | 4520 | graphics/asymptote/getopt1.c
-2021/03/15 | 30147 | graphics/asymptote/getopt.c
-2021/03/15 | 6650 | graphics/asymptote/getopt.h
-2021/03/15 | 202 | graphics/asymptote/glew.c
-2021/03/15 | 1235777 | graphics/asymptote/GL/glew.c
-2021/03/15 | 1186601 | graphics/asymptote/GL/glew.h
-2021/03/15 | 73435 | graphics/asymptote/GL/glxew.h
-2021/03/15 | 76801 | graphics/asymptote/gl-matrix-2.4.0-pruned/dist/gl-matrix.js
-2021/03/15 | 1131 | graphics/asymptote/gl-matrix-2.4.0-pruned/LICENSE.js
-2021/03/15 | 46026 | graphics/asymptote/glrender.cc
-2021/03/15 | 9243 | graphics/asymptote/glrender.h
-2021/03/15 | 63314 | graphics/asymptote/GL/wglew.h
-2021/03/15 | 50437 | graphics/asymptote/gsl.cc
-2021/03/15 | 22 | graphics/asymptote/GUI/configs/__init__.py
-2021/03/15 | 1148 | graphics/asymptote/GUI/configs/xasyconfig.cson
-2021/03/15 | 395 | graphics/asymptote/GUI/configs/xasykeymap.cson
-2021/03/15 | 3503 | graphics/asymptote/GUI/CustMatTransform.py
-2021/03/15 | 131 | graphics/asymptote/GUI/DebugFlags.py
-2021/03/15 | 1149 | graphics/asymptote/guide.cc
-2021/03/15 | 294 | graphics/asymptote/guideflags.h
-2021/03/15 | 6725 | graphics/asymptote/guide.h
-2021/03/15 | 1724 | graphics/asymptote/GUI/GuidesManager.py
-2021/03/15 | 164511 | graphics/asymptote/GUI/icons_rc.py
-2021/03/15 | 23 | graphics/asymptote/GUI/__init__.py
-2021/03/15 | 11528 | graphics/asymptote/GUI/InplaceAddObj.py
-2021/03/15 | 5151 | graphics/asymptote/GUI/labelEditor.py
-2021/03/15 | 700 | graphics/asymptote/GUI/locale/th/LC_MESSAGES/base.po
-2021/03/15 | 2399 | graphics/asymptote/GUI/PrimitiveShape.py
-2021/03/15 | 9945 | graphics/asymptote/GUI/pyUIClass/custMatTransform.py
-2021/03/15 | 6154 | graphics/asymptote/GUI/pyUIClass/labelTextEditor.py
-2021/03/15 | 2825 | graphics/asymptote/GUI/pyUIClass/setCustomAnchor.py
-2021/03/15 | 7129 | graphics/asymptote/GUI/pyUIClass/widg_addLabel.py
-2021/03/15 | 2193 | graphics/asymptote/GUI/pyUIClass/widg_addPolyOpt.py
-2021/03/15 | 4849 | graphics/asymptote/GUI/pyUIClass/widg_editBezier.py
-2021/03/15 | 4668 | graphics/asymptote/GUI/pyUIClass/widgetPointEditor.py
-2021/03/15 | 56646 | graphics/asymptote/GUI/pyUIClass/window1.py
-2021/03/15 | 57 | graphics/asymptote/GUI/requirements.txt
-2021/03/15 | 361 | graphics/asymptote/GUI/res/icons/anchor.svg
-2021/03/15 | 637 | graphics/asymptote/GUI/res/icons/android-arrow-back.svg
-2021/03/15 | 637 | graphics/asymptote/GUI/res/icons/android-arrow-forward.svg
-2021/03/15 | 802 | graphics/asymptote/GUI/res/icons/android-camera.svg
-2021/03/15 | 695 | graphics/asymptote/GUI/res/icons/android-close.svg
-2021/03/15 | 1319 | graphics/asymptote/GUI/res/icons/android-color-palette.svg
-2021/03/15 | 674 | graphics/asymptote/GUI/res/icons/android-delete.svg
-2021/03/15 | 633 | graphics/asymptote/GUI/res/icons/android-done.svg
-2021/03/15 | 822 | graphics/asymptote/GUI/res/icons/android-expand.svg
-2021/03/15 | 850 | graphics/asymptote/GUI/res/icons/android-folder-open.svg
-2021/03/15 | 1482 | graphics/asymptote/GUI/res/icons/android-hand.svg
-2021/03/15 | 1124 | graphics/asymptote/GUI/res/icons/android-locate.svg
-2021/03/15 | 764 | graphics/asymptote/GUI/res/icons/android-radio-button-off.svg
-2021/03/15 | 844 | graphics/asymptote/GUI/res/icons/android-radio-button-on.svg
-2021/03/15 | 806 | graphics/asymptote/GUI/res/icons/android-refresh.svg
-2021/03/15 | 713 | graphics/asymptote/GUI/res/icons/arrow-move.svg
-2021/03/15 | 639 | graphics/asymptote/GUI/res/icons/arrow-resize.svg
-2021/03/15 | 589 | graphics/asymptote/GUI/res/icons/bucket.asy
-2021/03/15 | 1492 | graphics/asymptote/GUI/res/icons/bucket.svg
-2021/03/15 | 111 | graphics/asymptote/GUI/res/icons/center.asy
-2021/03/15 | 124 | graphics/asymptote/GUI/res/icons/centerorigin.asy
-2021/03/15 | 1052 | graphics/asymptote/GUI/res/icons/centerorigin.svg
-2021/03/15 | 892 | graphics/asymptote/GUI/res/icons/center.svg
-2021/03/15 | 780 | graphics/asymptote/GUI/res/icons/check.svg
-2021/03/15 | 1013 | graphics/asymptote/GUI/res/icons/chevron-with-circle-left.svg
-2021/03/15 | 998 | graphics/asymptote/GUI/res/icons/chevron-with-circle-right.svg
-2021/03/15 | 754 | graphics/asymptote/GUI/res/icons/circle.svg
-2021/03/15 | 105 | graphics/asymptote/GUI/res/icons/closedcurve.asy
-2021/03/15 | 1237 | graphics/asymptote/GUI/res/icons/closedcurve.svg
-2021/03/15 | 105 | graphics/asymptote/GUI/res/icons/closedpolygon.asy
-2021/03/15 | 1102 | graphics/asymptote/GUI/res/icons/closedpolygon.svg
-2021/03/15 | 838 | graphics/asymptote/GUI/res/icons/close-round.svg
-2021/03/15 | 1194 | graphics/asymptote/GUI/res/icons/code.svg
-2021/03/15 | 876 | graphics/asymptote/GUI/res/icons/edit.svg
-2021/03/15 | 1003 | graphics/asymptote/GUI/res/icons/eye.svg
-2021/03/15 | 1967 | graphics/asymptote/GUI/res/icons/filledbucket.svg
-2021/03/15 | 1764 | graphics/asymptote/GUI/res/icons/grid.svg
-2021/03/15 | 964 | graphics/asymptote/GUI/res/icons/magnifying-glass.svg
-2021/03/15 | 98 | graphics/asymptote/GUI/res/icons/opencurve.asy
-2021/03/15 | 1186 | graphics/asymptote/GUI/res/icons/opencurve.svg
-2021/03/15 | 98 | graphics/asymptote/GUI/res/icons/openpolygon.asy
-2021/03/15 | 1085 | graphics/asymptote/GUI/res/icons/openpolygon.svg
-2021/03/15 | 759 | graphics/asymptote/GUI/res/icons/plus-round.svg
-2021/03/15 | 1711 | graphics/asymptote/GUI/res/icons.qrc
-2021/03/15 | 673 | graphics/asymptote/GUI/res/icons/save.svg
-2021/03/15 | 1920 | graphics/asymptote/GUI/res/icons/social-python.svg
-2021/03/15 | 108 | graphics/asymptote/GUI/res/icons/subdirectory-left.svg
-2021/03/15 | 284 | graphics/asymptote/GUI/res/icons/text.svg
-2021/03/15 | 1226 | graphics/asymptote/GUI/res/icons/triangle-stroked-15.svg
-2021/03/15 | 1393 | graphics/asymptote/GUI/SetCustomAnchor.py
-2021/03/15 | 394 | graphics/asymptote/GUI/setup.py
-2021/03/15 | 3616 | graphics/asymptote/GUI/UndoRedoStack.py
-2021/03/15 | 3249 | graphics/asymptote/GUI/Widg_addLabel.py
-2021/03/15 | 883 | graphics/asymptote/GUI/Widg_addPolyOpt.py
-2021/03/15 | 1665 | graphics/asymptote/GUI/Widg_editBezier.py
-2021/03/15 | 72687 | graphics/asymptote/GUI/Window1.py
-2021/03/15 | 10271 | graphics/asymptote/GUI/windows/custMatTransform.ui
-2021/03/15 | 6552 | graphics/asymptote/GUI/windows/labelTextEditor.ui
-2021/03/15 | 2631 | graphics/asymptote/GUI/windows/setCustomAnchor.ui
-2021/03/15 | 6896 | graphics/asymptote/GUI/windows/widg_addLabel.ui
-2021/03/15 | 2148 | graphics/asymptote/GUI/windows/widg_addPolyOpt.ui
-2021/03/15 | 4474 | graphics/asymptote/GUI/windows/widg_editBezier.ui
-2021/03/15 | 4166 | graphics/asymptote/GUI/windows/widgetPointEditor.ui
-2021/03/15 | 75576 | graphics/asymptote/GUI/windows/window1.ui
-2021/03/15 | 50600 | graphics/asymptote/GUI/xasy2asy.py
-2021/03/15 | 821 | graphics/asymptote/GUI/xasyArgs.py
-2021/03/15 | 13550 | graphics/asymptote/GUI/xasyBezierInterface.py
-2021/03/15 | 2554 | graphics/asymptote/GUI/xasyFile.py
-2021/03/15 | 5048 | graphics/asymptote/GUI/xasyOptions.py
-2021/03/15 | 503 | graphics/asymptote/GUI/xasy.py
-2021/03/15 | 599 | graphics/asymptote/GUI/xasyStrings.py
-2021/03/15 | 710 | graphics/asymptote/GUI/xasySvg.py
-2021/03/15 | 964 | graphics/asymptote/GUI/xasyTransform.py
-2021/03/15 | 1504 | graphics/asymptote/GUI/xasyUtils.py
-2021/03/15 | 238 | graphics/asymptote/GUI/xasyValidator.py
-2021/03/15 | 12813 | graphics/asymptote/impdatum.cc
-2021/03/15 | 10445 | graphics/asymptote/INSTALL
-2021/03/15 | 15645 | graphics/asymptote/install-sh
-2021/03/15 | 1982 | graphics/asymptote/inst.h
-2021/03/15 | 5505 | graphics/asymptote/interact.cc
-2021/03/15 | 1345 | graphics/asymptote/interact.h
-2021/03/15 | 5733 | graphics/asymptote/item.h
-2021/03/15 | 10072 | graphics/asymptote/jsfile.cc
-2021/03/15 | 2107 | graphics/asymptote/jsfile.h
-2021/03/15 | 609 | graphics/asymptote/keywords.cc
-2021/03/15 | 1253 | graphics/asymptote/keywords.pl
-2021/03/15 | 22345 | graphics/asymptote/knot.cc
-2021/03/15 | 12259 | graphics/asymptote/knot.h
-2021/03/15 | 342 | graphics/asymptote/lexical.h
-2021/03/15 | 83449 | graphics/asymptote/lex.yy.cc
-2021/03/15 | 503734 | graphics/asymptote/libatomic_ops-7.6.10.tar.gz
-2021/03/15 | 35147 | graphics/asymptote/LICENSE
-2021/03/15 | 7639 | graphics/asymptote/LICENSE.LESSER
-2021/03/15 | 2766 | graphics/asymptote/lnkX64IconFix.nsh
-2021/03/15 | 2194 | graphics/asymptote/locate.cc
-2021/03/15 | 631 | graphics/asymptote/locate.h
-2021/03/15 | 5443 | graphics/asymptote/main.cc
-2021/03/15 | 11672 | graphics/asymptote/Makefile.in
-2021/03/15 | 2632 | graphics/asymptote/material.h
-2021/03/15 | 6414 | graphics/asymptote/mathop.h
-2021/03/15 | 4972 | graphics/asymptote/memory.h
-2021/03/15 | 714 | graphics/asymptote/mod.h
-2021/03/15 | 908 | graphics/asymptote/modifier.h
-2021/03/15 | 7435 | graphics/asymptote/name.cc
-2021/03/15 | 5236 | graphics/asymptote/name.h
-2021/03/15 | 4265 | graphics/asymptote/newexp.cc
-2021/03/15 | 1274 | graphics/asymptote/newexp.h
-2021/03/15 | 916 | graphics/asymptote/opcodes.h
-2021/03/15 | 1050 | graphics/asymptote/opsymbols.pl
-2021/03/15 | 5104 | graphics/asymptote/pair.h
-2021/03/15 | 4874 | graphics/asymptote/parser.cc
-2021/03/15 | 1171 | graphics/asymptote/parser.h
-2021/03/15 | 5262 | graphics/asymptote/patches/bison.patch
-2021/03/15 | 1805 | graphics/asymptote/patches/cygwin_freeglut-3.0.0.patch
-2021/03/15 | 1311 | graphics/asymptote/patches/dvipdf
-2021/03/15 | 113 | graphics/asymptote/patches/fixmem.reg
-2021/03/15 | 1524 | graphics/asymptote/patches/flex.patch
-2021/03/15 | 271 | graphics/asymptote/patches/gc6.8_AIX.patch
-2021/03/15 | 489 | graphics/asymptote/patches/gc-7.0nomem.patch
-2021/03/15 | 318 | graphics/asymptote/patches/gcc3.3.2curses.patch
-2021/03/15 | 19462 | graphics/asymptote/patches/gl-matrix-2.4.0-pruned.patch
-2021/03/15 | 1082 | graphics/asymptote/patches/README
-2021/03/15 | 37991 | graphics/asymptote/path3.cc
-2021/03/15 | 10585 | graphics/asymptote/path3.h
-2021/03/15 | 33813 | graphics/asymptote/path.cc
-2021/03/15 | 11663 | graphics/asymptote/path.h
-2021/03/15 | 1594 | graphics/asymptote/pen.cc
-2021/03/15 | 27767 | graphics/asymptote/pen.h
-2021/03/15 | 40310 | graphics/asymptote/picture.cc
-2021/03/15 | 3431 | graphics/asymptote/picture.h
-2021/03/15 | 5250 | graphics/asymptote/pipestream.cc
-2021/03/15 | 2614 | graphics/asymptote/pipestream.h
-2021/03/15 | 138 | graphics/asymptote/Pipfile
-2021/03/15 | 2542 | graphics/asymptote/policy.h
-2021/03/15 | 650 | graphics/asymptote/prcfile.h
-2021/03/15 | 974 | graphics/asymptote/prc/Makefile
-2021/03/15 | 71201 | graphics/asymptote/prc/oPRCFile.cc
-2021/03/15 | 51432 | graphics/asymptote/prc/oPRCFile.h
-2021/03/15 | 8371 | graphics/asymptote/prc/PRCbitStream.cc
-2021/03/15 | 2518 | graphics/asymptote/prc/PRCbitStream.h
-2021/03/15 | 177246 | graphics/asymptote/prc/PRCdouble.cc
-2021/03/15 | 3765 | graphics/asymptote/prc/PRCdouble.h
-2021/03/15 | 30208 | graphics/asymptote/prc/PRC.h
-2021/03/15 | 6021 | graphics/asymptote/prc/PRCTools/bitData.cc
-2021/03/15 | 1860 | graphics/asymptote/prc/PRCTools/bitData.h
-2021/03/15 | 1927 | graphics/asymptote/prc/PRCTools/bitSearchDouble.cc
-2021/03/15 | 1863 | graphics/asymptote/prc/PRCTools/bitSearchUI.cc
-2021/03/15 | 1245 | graphics/asymptote/prc/PRCTools/describeMain.cc
-2021/03/15 | 68126 | graphics/asymptote/prc/PRCTools/describePRC.cc
-2021/03/15 | 4335 | graphics/asymptote/prc/PRCTools/describePRC.h
-2021/03/15 | 1310 | graphics/asymptote/prc/PRCTools/extractSections.cc
-2021/03/15 | 2276 | graphics/asymptote/prc/PRCTools/inflation.cc
-2021/03/15 | 1051 | graphics/asymptote/prc/PRCTools/inflation.h
-2021/03/15 | 1479 | graphics/asymptote/prc/PRCTools/inflationMain.cc
-2021/03/15 | 8792 | graphics/asymptote/prc/PRCTools/iPRCFile.cc
-2021/03/15 | 2341 | graphics/asymptote/prc/PRCTools/iPRCFile.h
-2021/03/15 | 1658 | graphics/asymptote/prc/PRCTools/Makefile
-2021/03/15 | 4716 | graphics/asymptote/prc/PRCTools/makePRC.cc
-2021/03/15 | 95 | graphics/asymptote/prc/test.asy
-2021/03/15 | 36243 | graphics/asymptote/prc/test.cc
-2021/03/15 | 66751 | graphics/asymptote/prc/writePRC.cc
-2021/03/15 | 48481 | graphics/asymptote/prc/writePRC.h
-2021/03/15 | 116025 | graphics/asymptote/predicates.cc
-2021/03/15 | 986 | graphics/asymptote/predicates.h
-2021/03/15 | 1236 | graphics/asymptote/primitives.h
-2021/03/15 | 25223 | graphics/asymptote/process.cc
-2021/03/15 | 2982 | graphics/asymptote/process.h
-2021/03/15 | 2378 | graphics/asymptote/profile.py
-2021/03/15 | 9923 | graphics/asymptote/profiler.h
-2021/03/15 | 3265 | graphics/asymptote/program.cc
-2021/03/15 | 2561 | graphics/asymptote/program.h
-2021/03/15 | 18938 | graphics/asymptote/psfile.cc
-2021/03/15 | 8937 | graphics/asymptote/psfile.h
-2021/03/15 | 2505 | graphics/asymptote/README
-2021/03/15 | 1698 | graphics/asymptote/record.cc
-2021/03/15 | 2732 | graphics/asymptote/record.h
-2021/03/15 | 1096 | graphics/asymptote/refaccess.cc
-2021/03/15 | 1936 | graphics/asymptote/refaccess.h
-2021/03/15 | 124929 | graphics/asymptote/ReleaseNotes
-2021/03/15 | 62 | graphics/asymptote/revision.cc
-2021/03/15 | 3441 | graphics/asymptote/rounding.h
-2021/03/15 | 73254 | graphics/asymptote/runarray.cc
-2021/03/15 | 1492 | graphics/asymptote/runarray.h
-2021/03/15 | 48417 | graphics/asymptote/runarray.in
-2021/03/15 | 2661 | graphics/asymptote/runbacktrace.cc
-2021/03/15 | 169 | graphics/asymptote/runbacktrace.h
-2021/03/15 | 831 | graphics/asymptote/runbacktrace.in
-2021/03/15 | 17690 | graphics/asymptote/runfile.cc
-2021/03/15 | 969 | graphics/asymptote/runfile.h
-2021/03/15 | 5879 | graphics/asymptote/runfile.in
-2021/03/15 | 8096 | graphics/asymptote/runhistory.cc
-2021/03/15 | 161 | graphics/asymptote/runhistory.h
-2021/03/15 | 5064 | graphics/asymptote/runhistory.in
-2021/03/15 | 15829 | graphics/asymptote/runlabel.cc
-2021/03/15 | 153 | graphics/asymptote/runlabel.h
-2021/03/15 | 12089 | graphics/asymptote/runlabel.in
-2021/03/15 | 21926 | graphics/asymptote/runmath.cc
-2021/03/15 | 269 | graphics/asymptote/runmath.h
-2021/03/15 | 8856 | graphics/asymptote/runmath.in
-2021/03/15 | 16483 | graphics/asymptote/runpair.cc
-2021/03/15 | 299 | graphics/asymptote/runpair.h
-2021/03/15 | 4156 | graphics/asymptote/runpair.in
-2021/03/15 | 25701 | graphics/asymptote/runpath3d.cc
-2021/03/15 | 186 | graphics/asymptote/runpath3d.h
-2021/03/15 | 8008 | graphics/asymptote/runpath3d.in
-2021/03/15 | 26844 | graphics/asymptote/runpath.cc
-2021/03/15 | 177 | graphics/asymptote/runpath.h
-2021/03/15 | 8439 | graphics/asymptote/runpath.in
-2021/03/15 | 57126 | graphics/asymptote/runpicture.cc
-2021/03/15 | 191 | graphics/asymptote/runpicture.h
-2021/03/15 | 19455 | graphics/asymptote/runpicture.in
-2021/03/15 | 18739 | graphics/asymptote/runstring.cc
-2021/03/15 | 188 | graphics/asymptote/runstring.h
-2021/03/15 | 9867 | graphics/asymptote/runstring.in
-2021/03/15 | 12604 | graphics/asymptote/runsystem.cc
-2021/03/15 | 157 | graphics/asymptote/runsystem.h
-2021/03/15 | 5111 | graphics/asymptote/runsystem.in
-2021/03/15 | 1341 | graphics/asymptote/runtimebase.in
-2021/03/15 | 60866 | graphics/asymptote/runtime.cc
-2021/03/15 | 1163 | graphics/asymptote/runtime.h
-2021/03/15 | 20622 | graphics/asymptote/runtime.in
-2021/03/15 | 7230 | graphics/asymptote/runtime.pl
-2021/03/15 | 13944 | graphics/asymptote/runtriple.cc
-2021/03/15 | 320 | graphics/asymptote/runtriple.h
-2021/03/15 | 2707 | graphics/asymptote/runtriple.in
-2021/03/15 | 2136 | graphics/asymptote/seconds.h
-2021/03/15 | 52096 | graphics/asymptote/settings.cc
-2021/03/15 | 2661 | graphics/asymptote/settings.h
-2021/03/15 | 2894 | graphics/asymptote/shaders.cc
-2021/03/15 | 882 | graphics/asymptote/shaders.h
-2021/03/15 | 6634 | graphics/asymptote/simpson.cc
-2021/03/15 | 14469 | graphics/asymptote/stack.cc
-2021/03/15 | 3295 | graphics/asymptote/stack.h
-2021/03/15 | 951 | graphics/asymptote/statistics.h
-2021/03/15 | 12024 | graphics/asymptote/stm.cc
-2021/03/15 | 4392 | graphics/asymptote/stm.h
-2021/03/15 | 8960 | graphics/asymptote/symbol.cc
-2021/03/15 | 2654 | graphics/asymptote/symbol.h
-2021/03/15 | 2697 | graphics/asymptote/table.h
-2021/03/15 | 620 | graphics/asymptote/tests/arith/integer.asy
-2021/03/15 | 449 | graphics/asymptote/tests/arith/pair.asy
-2021/03/15 | 193 | graphics/asymptote/tests/arith/random.asy
-2021/03/15 | 383 | graphics/asymptote/tests/arith/real.asy
-2021/03/15 | 1710 | graphics/asymptote/tests/arith/roots.asy
-2021/03/15 | 639 | graphics/asymptote/tests/arith/transform.asy
-2021/03/15 | 244 | graphics/asymptote/tests/arith/triple.asy
-2021/03/15 | 936 | graphics/asymptote/tests/array/array.asy
-2021/03/15 | 680 | graphics/asymptote/tests/array/delete.asy
-2021/03/15 | 737 | graphics/asymptote/tests/array/determinant.asy
-2021/03/15 | 1927 | graphics/asymptote/tests/array/fields.asy
-2021/03/15 | 4841 | graphics/asymptote/tests/array/slice.asy
-2021/03/15 | 966 | graphics/asymptote/tests/array/solve.asy
-2021/03/15 | 746 | graphics/asymptote/tests/array/sort.asy
-2021/03/15 | 1096 | graphics/asymptote/tests/array/transpose.asy
-2021/03/15 | 276 | graphics/asymptote/tests/bench/6000circles.asy
-2021/03/15 | 2222 | graphics/asymptote/tests/frames/loop.asy
-2021/03/15 | 202 | graphics/asymptote/tests/frames/stat2.asy
-2021/03/15 | 158 | graphics/asymptote/tests/frames/stat.asy
-2021/03/15 | 62 | graphics/asymptote/tests/gc/array.asy
-2021/03/15 | 102 | graphics/asymptote/tests/gc/file.asy
-2021/03/15 | 54 | graphics/asymptote/tests/gc/funcall.asy
-2021/03/15 | 65 | graphics/asymptote/tests/gc/guide.asy
-2021/03/15 | 143 | graphics/asymptote/tests/gc/label.asy
-2021/03/15 | 124 | graphics/asymptote/tests/gc/path.asy
-2021/03/15 | 72 | graphics/asymptote/tests/gc/pen.asy
-2021/03/15 | 193 | graphics/asymptote/tests/gc/shipout.asy
-2021/03/15 | 77 | graphics/asymptote/tests/gc/string.asy
-2021/03/15 | 129 | graphics/asymptote/tests/gc/struct.asy
-2021/03/15 | 70 | graphics/asymptote/tests/gc/transform.asy
-2021/03/15 | 369 | graphics/asymptote/tests/gs/ghostscript.asy
-2021/03/15 | 11907 | graphics/asymptote/tests/gsl/random.asy
-2021/03/15 | 1209 | graphics/asymptote/tests/imp/unravel.asy
-2021/03/15 | 308 | graphics/asymptote/tests/Makefile
-2021/03/15 | 18 | graphics/asymptote/tests/output/circle.asy
-2021/03/15 | 22 | graphics/asymptote/tests/output/line.asy
-2021/03/15 | 1284 | graphics/asymptote/tests/output/Makefile
-2021/03/15 | 1384 | graphics/asymptote/tests/pic/trans.asy
-2021/03/15 | 236 | graphics/asymptote/tests/string/erase.asy
-2021/03/15 | 182 | graphics/asymptote/tests/string/find.asy
-2021/03/15 | 109 | graphics/asymptote/tests/string/insert.asy
-2021/03/15 | 132 | graphics/asymptote/tests/string/length.asy
-2021/03/15 | 187 | graphics/asymptote/tests/string/rfind.asy
-2021/03/15 | 118 | graphics/asymptote/tests/string/substr.asy
-2021/03/15 | 238 | graphics/asymptote/tests/TestLib.asy
-2021/03/15 | 159 | graphics/asymptote/tests/types/cast.asy
-2021/03/15 | 6503 | graphics/asymptote/tests/types/constructor.asy
-2021/03/15 | 155 | graphics/asymptote/tests/types/ecast.asy
-2021/03/15 | 3375 | graphics/asymptote/tests/types/guide.asy
-2021/03/15 | 224 | graphics/asymptote/tests/types/init.asy
-2021/03/15 | 4242 | graphics/asymptote/tests/types/keyword.asy
-2021/03/15 | 4072 | graphics/asymptote/tests/types/order.asy
-2021/03/15 | 2731 | graphics/asymptote/tests/types/resolve.asy
-2021/03/15 | 308 | graphics/asymptote/tests/types/shadow.asy
-2021/03/15 | 1331 | graphics/asymptote/tests/types/spec.asy
-2021/03/15 | 1189 | graphics/asymptote/tests/types/var.asy
-2021/03/15 | 18388 | graphics/asymptote/texfile.cc
-2021/03/15 | 11217 | graphics/asymptote/texfile.h
-2021/03/15 | 1293 | graphics/asymptote/TODO
-2021/03/15 | 6288 | graphics/asymptote/transform.h
-2021/03/15 | 10224 | graphics/asymptote/tr.cc
-2021/03/15 | 3912 | graphics/asymptote/tr.h
-2021/03/15 | 9574 | graphics/asymptote/triple.h
-2021/03/15 | 14072 | graphics/asymptote/types.cc
-2021/03/15 | 15451 | graphics/asymptote/types.h
-2021/03/15 | 10093 | graphics/asymptote/util.cc
-2021/03/15 | 4602 | graphics/asymptote/util.h
-2021/03/15 | 1976 | graphics/asymptote/varinit.cc
-2021/03/15 | 2012 | graphics/asymptote/varinit.h
-2021/03/15 | 901 | graphics/asymptote/virtualfieldaccess.cc
-2021/03/15 | 2328 | graphics/asymptote/virtualfieldaccess.h
-2021/03/15 | 766 | graphics/asymptote/vm.h
-2021/03/15 | 222 | graphics/asymptote/wce
-2021/03/15 | 2146 | graphics/asymptote/webgl/fragment.glsl
-2021/03/15 | 83897 | graphics/asymptote/webgl/gl.js
-2021/03/15 | 820 | graphics/asymptote/webgl/license
-2021/03/15 | 1446 | graphics/asymptote/webgl/vertex.glsl
-2021/03/15 | 6585 | graphics/asymptote/xstream.h
-2021/03/15 | 15565665 | graphics/asymptote.zip
+2021/12/27 | 242 | graphics/asymptote/BUGS
+2021/12/27 | 1588 | graphics/asymptote/build-scripts/asy-format.el
+2021/12/27 | 210 | graphics/asymptote/build-scripts/asy-indent.el
+2021/12/27 | 1227 | graphics/asymptote/build-scripts/build-asygl
+2021/12/27 | 2484 | graphics/asymptote/build-scripts/build-asymptote
+2021/12/27 | 3556 | graphics/asymptote/build-scripts/build-asymptote.dos
+2021/12/27 | 1578 | graphics/asymptote/build-scripts/cc-format.el
+2021/12/27 | 183 | graphics/asymptote/build-scripts/cc-indent.el
+2021/12/27 | 2207 | graphics/asymptote/build-scripts/HOWTO-MSWindows
+2021/12/27 | 297 | graphics/asymptote/build-scripts/README-binaries
+2021/12/27 | 202 | graphics/asymptote/build-scripts/run-in-indent.el
+2021/12/27 | 31342 | graphics/asymptote/builtin.cc
+2021/12/27 | 1630 | graphics/asymptote/builtin.h
+2021/12/27 | 1151 | graphics/asymptote/callable.cc
+2021/12/27 | 1640 | graphics/asymptote/callable.h
+2021/12/27 | 1190 | graphics/asymptote/camperror.cc
+2021/12/27 | 814 | graphics/asymptote/camperror.h
+2021/12/27 | 13357 | graphics/asymptote/camp.l
+2021/12/27 | 129790 | graphics/asymptote/camp.tab.cc
+2021/12/27 | 6189 | graphics/asymptote/camp.tab.h
+2021/12/27 | 20029 | graphics/asymptote/camp.y
+2021/12/27 | 4629 | graphics/asymptote/castop.h
+2021/12/27 | 1876 | graphics/asymptote/cc-mode2.el
+2021/12/27 | 1577303 | graphics/asymptote/ChangeLog
+2021/12/27 | 7790 | graphics/asymptote/coder.cc
+2021/12/27 | 11642 | graphics/asymptote/coder.h
+2021/12/27 | 1126 | graphics/asymptote/coenv.cc
+2021/12/27 | 908 | graphics/asymptote/coenv.h
+2021/12/27 | 2187 | graphics/asymptote/common.h
+2021/12/27 | 48441 | graphics/asymptote/config.guess
+2021/12/27 | 7099 | graphics/asymptote/config.h.in
+2021/12/27 | 31609 | graphics/asymptote/config.sub
+2021/12/27 | 292060 | graphics/asymptote/configure
+2021/12/27 | 16523 | graphics/asymptote/configure.ac
+2021/12/27 | 26 | graphics/asymptote/_config.yml
+2021/12/27 | 3676 | graphics/asymptote/constructor.cc
+2021/12/27 | 241 | graphics/asymptote/cudareflect/common.h
+2021/12/27 | 2514 | graphics/asymptote/cudareflect/EXRFiles.cc
+2021/12/27 | 1406 | graphics/asymptote/cudareflect/EXRFiles.h
+2021/12/27 | 883 | graphics/asymptote/cudareflect/helper.cuh
+2021/12/27 | 1070 | graphics/asymptote/cudareflect/IrradianceGenerator.sln
+2021/12/27 | 5820 | graphics/asymptote/cudareflect/IrradianceGenerator.vcxproj
+2021/12/27 | 4371 | graphics/asymptote/cudareflect/kernel.cu
+2021/12/27 | 445 | graphics/asymptote/cudareflect/kernel.h
+2021/12/27 | 7780 | graphics/asymptote/cudareflect/main.cc
+2021/12/27 | 548 | graphics/asymptote/cudareflect/Makefile
+2021/12/27 | 8519 | graphics/asymptote/cudareflect/ReflectanceMapper.cu
+2021/12/27 | 443 | graphics/asymptote/cudareflect/ReflectanceMapper.cuh
+2021/12/27 | 2598 | graphics/asymptote/cudareflect/simpson.cuh
+2021/12/27 | 242 | graphics/asymptote/cudareflect/tinyexr/appveyor.yml
+2021/12/27 | 1127425 | graphics/asymptote/cudareflect/tinyexr/asakusa.exr
+2021/12/27 | 202947 | graphics/asymptote/cudareflect/tinyexr/asakusa.png
+2021/12/27 | 366 | graphics/asymptote/cudareflect/tinyexr.cc
+2021/12/27 | 2479 | graphics/asymptote/cudareflect/tinyexr/CMakeLists.txt
+2021/12/27 | 2011 | graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/asan-wrapper
+2021/12/27 | 2144 | graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindASan.cmake
+2021/12/27 | 2292 | graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindMSan.cmake
+2021/12/27 | 3737 | graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindSanitizers.cmake
+2021/12/27 | 2555 | graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindTSan.cmake
+2021/12/27 | 1696 | graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindUBSan.cmake
+2021/12/27 | 7684 | graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/sanitize-helpers.cmake
+2021/12/27 | 1896 | graphics/asymptote/cudareflect/tinyexr/config-msvc.py
+2021/12/27 | 16705 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/ChangeLog.md
+2021/12/27 | 3109 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example1.c
+2021/12/27 | 6551 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example2.c
+2021/12/27 | 6726 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example3.c
+2021/12/27 | 2675 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example4.c
+2021/12/27 | 10571 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example5.c
+2021/12/27 | 4172 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example6.c
+2021/12/27 | 1162 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/LICENSE
+2021/12/27 | 319839 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/miniz.c
+2021/12/27 | 69441 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/miniz.h
+2021/12/27 | 4254 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/readme.md
+2021/12/27 | 39458 | graphics/asymptote/cudareflect/tinyexr/examples/common/cxxopts.hpp
+2021/12/27 | 260289 | graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image.h
+2021/12/27 | 113565 | graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image_resize.h
+2021/12/27 | 37685 | graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image_write.h
+2021/12/27 | 12630 | graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/cube2longlat.cc
+2021/12/27 | 569 | graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/Makefile
+2021/12/27 | 1072 | graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/README.md
+2021/12/27 | 3790199 | graphics/asymptote/cudareflect/tinyexr/examples/deepview/deepview_screencast.gif
+2021/12/27 | 6553 | graphics/asymptote/cudareflect/tinyexr/examples/deepview/main.cc
+2021/12/27 | 146 | graphics/asymptote/cudareflect/tinyexr/examples/deepview/Makefile
+2021/12/27 | 8456 | graphics/asymptote/cudareflect/tinyexr/examples/deepview/trackball.cc
+2021/12/27 | 3284 | graphics/asymptote/cudareflect/tinyexr/examples/deepview/trackball.h
+2021/12/27 | 5323 | graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/exr2fptiff.cc
+2021/12/27 | 687 | graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/Makefile
+2021/12/27 | 117 | graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/README.md
+2021/12/27 | 37135 | graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/tiny_dng_writer.h
+2021/12/27 | 3135 | graphics/asymptote/cudareflect/tinyexr/examples/exr2ldr/exr2ldr.cc
+2021/12/27 | 189 | graphics/asymptote/cudareflect/tinyexr/examples/exr2ldr/Makefile
+2021/12/27 | 612 | graphics/asymptote/cudareflect/tinyexr/examples/exr2rgbe/exr2rgbe.cc
+2021/12/27 | 161 | graphics/asymptote/cudareflect/tinyexr/examples/exr2rgbe/Makefile
+2021/12/27 | 4635 | graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/exrfilter.cc
+2021/12/27 | 173 | graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/Makefile
+2021/12/27 | 88 | graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/README.md
+2021/12/27 | 190044 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/DroidSans.ttf
+2021/12/27 | 1198 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/exr-io.cc
+2021/12/27 | 248 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/exr-io.h
+2021/12/27 | 2741 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/findOpenGLGlewGlut.lua
+2021/12/27 | 15018 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/main.cc
+2021/12/27 | 13867 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/nuklear_btgui_gl2.h
+2021/12/27 | 952118 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/nuklear.h
+2021/12/27 | 2939 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/CommonWindowInterface.h
+2021/12/27 | 2514 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/MacOpenGLWindow.h
+2021/12/27 | 34316 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/MacOpenGLWindow.mm
+2021/12/27 | 1648 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/OpenGL2Include.h
+2021/12/27 | 1813 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/OpenGLInclude.h
+2021/12/27 | 1318 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32InternalWindowData.h
+2021/12/27 | 4384 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32OpenGLWindow.cpp
+2021/12/27 | 1753 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32OpenGLWindow.h
+2021/12/27 | 18991 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32Window.cpp
+2021/12/27 | 2543 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32Window.h
+2021/12/27 | 36526 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.cpp
+2021/12/27 | 2040 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.h
+2021/12/27 | 2605 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/premake4.lua
+2021/12/27 | 1287 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/README.md
+2021/12/27 | 1044671 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/screenshots/exrview.png
+2021/12/27 | 235 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/shader.frag
+2021/12/27 | 186 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/shader.vert
+2021/12/27 | 989121 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/glew.h
+2021/12/27 | 71994 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/glxew.h
+2021/12/27 | 62206 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/wglew.h
+2021/12/27 | 968193 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/glew.c
+2021/12/27 | 820 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/LICENSE
+2021/12/27 | 4602 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/README.md
+2021/12/27 | 100007 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_cocoa.png
+2021/12/27 | 63193 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_gtk3.png
+2021/12/27 | 16188 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_win8.png
+2021/12/27 | 388 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/common.h
+2021/12/27 | 1733 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/include/nfd.h
+2021/12/27 | 6117 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_cocoa.m
+2021/12/27 | 2772 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_common.c
+2021/12/27 | 615 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_common.h
+2021/12/27 | 9022 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_gtk.c
+2021/12/27 | 17346 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_win.cpp
+2021/12/27 | 2477 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/SConstruct
+2021/12/27 | 1688 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/SConstruct
+2021/12/27 | 530 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_opendialog.c
+2021/12/27 | 741 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_opendialogmultiple.c
+2021/12/27 | 533 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_savedialog.c
+2021/12/27 | 2554 | graphics/asymptote/cudareflect/tinyexr/examples/ldr2exr/ldr2exr.cc
+2021/12/27 | 157 | graphics/asymptote/cudareflect/tinyexr/examples/ldr2exr/Makefile
+2021/12/27 | 6772 | graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/main.cc
+2021/12/27 | 167 | graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/Makefile
+2021/12/27 | 323 | graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/README.md
+2021/12/27 | 188 | graphics/asymptote/cudareflect/tinyexr/examples/resize/Makefile
+2021/12/27 | 1101 | graphics/asymptote/cudareflect/tinyexr/examples/resize/resize.cc
+2021/12/27 | 159 | graphics/asymptote/cudareflect/tinyexr/examples/rgbe2exr/Makefile
+2021/12/27 | 2272 | graphics/asymptote/cudareflect/tinyexr/examples/rgbe2exr/rgbe2exr.cc
+2021/12/27 | 174 | graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/Makefile
+2021/12/27 | 289 | graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/README.md
+2021/12/27 | 1950 | graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/testmapgen.cc
+2021/12/27 | 1955 | graphics/asymptote/cudareflect/tinyexr/experimental/js/binding.cc
+2021/12/27 | 494 | graphics/asymptote/cudareflect/tinyexr/experimental/js/compile_to_js.sh
+2021/12/27 | 1131 | graphics/asymptote/cudareflect/tinyexr/experimental/js/index.html
+2021/12/27 | 25 | graphics/asymptote/cudareflect/tinyexr/experimental/js/Makefile
+2021/12/27 | 612 | graphics/asymptote/cudareflect/tinyexr/experimental/js/README.md
+2021/12/27 | 495 | graphics/asymptote/cudareflect/tinyexr/experimental/js/test.js
+2021/12/27 | 223 | graphics/asymptote/cudareflect/tinyexr/jni/Android.mk
+2021/12/27 | 41 | graphics/asymptote/cudareflect/tinyexr/jni/Application.mk
+2021/12/27 | 160 | graphics/asymptote/cudareflect/tinyexr/jni/Makefile
+2021/12/27 | 108 | graphics/asymptote/cudareflect/tinyexr/jni/README.md
+2021/12/27 | 10561 | graphics/asymptote/cudareflect/tinyexr/kuroga.py
+2021/12/27 | 509 | graphics/asymptote/cudareflect/tinyexr/Makefile
+2021/12/27 | 437 | graphics/asymptote/cudareflect/tinyexr/Makefile.gcc-mingw
+2021/12/27 | 407 | graphics/asymptote/cudareflect/tinyexr/Makefile.gcc-mingw-msys
+2021/12/27 | 535 | graphics/asymptote/cudareflect/tinyexr/Makefile.llvm-mingw
+2021/12/27 | 1156 | graphics/asymptote/cudareflect/tinyexr/premake4.lua
+2021/12/27 | 17614 | graphics/asymptote/cudareflect/tinyexr/README.md
+2021/12/27 | 173 | graphics/asymptote/cudareflect/tinyexr/test/c-binding/Makefile
+2021/12/27 | 283 | graphics/asymptote/cudareflect/tinyexr/test/c-binding/test.c
+2021/12/27 | 339 | graphics/asymptote/cudareflect/tinyexr/test/CMakeLists.txt
+2021/12/27 | 3601 | graphics/asymptote/cudareflect/tinyexr/test/exrcat/exrcat.cpp
+2021/12/27 | 4116 | graphics/asymptote/cudareflect/tinyexr/test/exrwrite/exrwritetest.cpp
+2021/12/27 | 831 | graphics/asymptote/cudareflect/tinyexr/test/fuzzer/fuzz.cc
+2021/12/27 | 64 | graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-62-tinyexr_memcpy_heap-buffer-overflow
+2021/12/27 | 503 | graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-63-tinyexr_signed-integer-overflow
+2021/12/27 | 20829 | graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-77-heap-buffer-overflow
+2021/12/27 | 709 | graphics/asymptote/cudareflect/tinyexr/test/fuzzer/Makefile
+2021/12/27 | 185 | graphics/asymptote/cudareflect/tinyexr/test/fuzzer/README.md
+2021/12/27 | 1548 | graphics/asymptote/cudareflect/tinyexr/test/issues/160/main.py
+2021/12/27 | 61 | graphics/asymptote/cudareflect/tinyexr/test/issues/160/README.md
+2021/12/27 | 28 | graphics/asymptote/cudareflect/tinyexr/test/issues/160/requirements.txt
+2021/12/27 | 15617 | graphics/asymptote/cudareflect/tinyexr/test_tinyexr.cc
+2021/12/27 | 376913 | graphics/asymptote/cudareflect/tinyexr/test/unit/catch.hpp
+2021/12/27 | 867 | graphics/asymptote/cudareflect/tinyexr/test/unit/config-msvc.py
+2021/12/27 | 1347 | graphics/asymptote/cudareflect/tinyexr/test/unit/config-posix.py
+2021/12/27 | 10563 | graphics/asymptote/cudareflect/tinyexr/test/unit/kuroga.py
+2021/12/27 | 400 | graphics/asymptote/cudareflect/tinyexr/test/unit/Makefile
+2021/12/27 | 401 | graphics/asymptote/cudareflect/tinyexr/test/unit/README.md
+2021/12/27 | 395 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/2by2.exr
+2021/12/27 | 4731 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/flaga.exr
+2021/12/27 | 155069 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/issue-160-piz-decode.exr
+2021/12/27 | 327 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/piz-bug-issue-100.exr
+2021/12/27 | 473703 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-1383755b301e5f505b2198dc0508918b537fdf48bbfc6deeffe268822e6f6cd6
+2021/12/27 | 630 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-24322747c47e87a10e4407528b779a1a763a48135384909b3d1010bbba1d4c28_min
+2021/12/27 | 832 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-255456016cca60ddb5c5ed6898182e13739bf687b17d1411e97bb60ad95e7a84_min
+2021/12/27 | 4738 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-360c3b0555cb979ca108f2d178cf8a80959cfeabaa4ec1d310d062fa653a8c6b_min
+2021/12/27 | 4471 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-3f1f642c3356fd8e8d2a0787613ec09a56572b3a1e38c9629b6db9e8dead1117_min
+2021/12/27 | 298 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-5ace655ef080932dcc7e4abc9eab1d4f82c845453464993dfa3eb6c5822a1621
+2021/12/27 | 678 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-5b66774a7498c635334ad386be0c3b359951738ac47f14878a3346d1c6ea0fe5_min
+2021/12/27 | 132 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-d5c9c893e559277a3320c196523095b94db93985620ac338d037487e0e613047_min
+2021/12/27 | 15 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-df76d1f27adb8927a1446a603028272140905c168a336128465a1162ec7af270.mini
+2021/12/27 | 473695 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-e7fa6404daa861369d2172fe68e08f9d38c0989f57da7bcfb510bab67e19ca9f
+2021/12/27 | 793 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-eedff3a9e99eb1c0fd3a3b0989e7c44c0a69f04f10b23e5264f362a4773f4397_min
+2021/12/27 | 15 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-efe9007bfdcbbe8a1569bf01fa9acadb8261ead49cb83f6e91fcdc4dae2e99a3_min
+2021/12/27 | 335 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/tiled_half_1x1_alpha.exr
+2021/12/27 | 52750 | graphics/asymptote/cudareflect/tinyexr/test/unit/tester.cc
+2021/12/27 | 133 | graphics/asymptote/cudareflect/tinyexr/test/unit/vcbuild.bat
+2021/12/27 | 50 | graphics/asymptote/cudareflect/tinyexr/test/unit/win32-filelist-utf16le.inc
+2021/12/27 | 31 | graphics/asymptote/cudareflect/tinyexr/test/unit/win32-filelist-utf8.inc
+2021/12/27 | 121 | graphics/asymptote/cudareflect/tinyexr/tinyexr.cc
+2021/12/27 | 270497 | graphics/asymptote/cudareflect/tinyexr/tinyexr.h
+2021/12/27 | 317 | graphics/asymptote/cudareflect/tinyexr/vcbuild.bat
+2021/12/27 | 85 | graphics/asymptote/cudareflect/tinyexr/vcsetup2019.bat
+2021/12/27 | 1950 | graphics/asymptote/cudareflect/utils.cuh
+2021/12/27 | 26693 | graphics/asymptote/dec.cc
+2021/12/27 | 17734 | graphics/asymptote/dec.h
+2021/12/27 | 5883 | graphics/asymptote/Delaunay.cc
+2021/12/27 | 384 | graphics/asymptote/Delaunay.h
+2021/12/27 | 8836 | graphics/asymptote/doc/asy.1
+2021/12/27 | 1005 | graphics/asymptote/doc/asy.1.begin
+2021/12/27 | 333 | graphics/asymptote/doc/asy.1.end
+2021/12/27 | 2800 | graphics/asymptote/doc/asycolors.sty
+2021/12/27 | 18101 | graphics/asymptote/doc/asy-latex.dtx
+2021/12/27 | 206973 | graphics/asymptote/doc/asy-latex.pdf
+2021/12/27 | 1241549 | graphics/asymptote/doc/asymptote.pdf
+2021/12/27 | 9811 | graphics/asymptote/doc/asymptote.sty
+2021/12/27 | 393676 | graphics/asymptote/doc/asymptote.texi
+2021/12/27 | 121145 | graphics/asymptote/doc/asyRefCard.pdf
+2021/12/27 | 20051 | graphics/asymptote/doc/asyRefCard.tex
+2021/12/27 | 246 | graphics/asymptote/doc/axis3.asy
+2021/12/27 | 416 | graphics/asymptote/doc/bezier2.asy
+2021/12/27 | 81 | graphics/asymptote/doc/bezier.asy
+2021/12/27 | 234 | graphics/asymptote/doc/beziercurve.asy
+2021/12/27 | 41 | graphics/asymptote/doc/bigdiagonal.asy
+2021/12/27 | 306 | graphics/asymptote/doc/binarytreetest.asy
+2021/12/27 | 677 | graphics/asymptote/doc/Bode.asy
+2021/12/27 | 524 | graphics/asymptote/doc/brokenaxis.asy
+2021/12/27 | 1391 | graphics/asymptote/doc/CAD1.asy
+2021/12/27 | 198823 | graphics/asymptote/doc/CAD.pdf
+2021/12/27 | 10196 | graphics/asymptote/doc/CAD.tex
+2021/12/27 | 518 | graphics/asymptote/doc/CDlabel.asy
+2021/12/27 | 4348 | graphics/asymptote/doc/colo-asy.tex
+2021/12/27 | 49 | graphics/asymptote/doc/colons.asy
+2021/12/27 | 1620 | graphics/asymptote/doc/colors.asy
+2021/12/27 | 243 | graphics/asymptote/doc/cube.asy
+2021/12/27 | 86 | graphics/asymptote/doc/cylinderskeleton.asy
+2021/12/27 | 218 | graphics/asymptote/doc/datagraph.asy
+2021/12/27 | 24 | graphics/asymptote/doc/diagonal.asy
+2021/12/27 | 2979 | graphics/asymptote/doc/diatom.asy
+2021/12/27 | 4067 | graphics/asymptote/doc/diatom.csv
+2021/12/27 | 49 | graphics/asymptote/doc/dots.asy
+2021/12/27 | 1051 | graphics/asymptote/doc/eetomumu.asy
+2021/12/27 | 2034 | graphics/asymptote/doc/elliptic.asy
+2021/12/27 | 912 | graphics/asymptote/doc/errorbars.asy
+2021/12/27 | 202 | graphics/asymptote/doc/exp.asy
+2021/12/27 | 343 | graphics/asymptote/doc/externalprc.tex
+2021/12/27 | 19597 | graphics/asymptote/doc/external-proposal.html
+2021/12/27 | 25154 | graphics/asymptote/doc/extra/intro.asy
+2021/12/27 | 40899 | graphics/asymptote/doc/FAQ/asy-faq.bfnn
+2021/12/27 | 63136 | graphics/asymptote/doc/FAQ/asy-faq.info
+2021/12/27 | 9328 | graphics/asymptote/doc/FAQ/bfnnconv.pl
+2021/12/27 | 13663 | graphics/asymptote/doc/FAQ/install-sh
+2021/12/27 | 1000 | graphics/asymptote/doc/FAQ/Makefile
+2021/12/27 | 4718 | graphics/asymptote/doc/FAQ/m-ascii.pl
+2021/12/27 | 9822 | graphics/asymptote/doc/FAQ/m-html.pl
+2021/12/27 | 5627 | graphics/asymptote/doc/FAQ/m-info.pl
+2021/12/27 | 6104 | graphics/asymptote/doc/FAQ/m-lout.pl
+2021/12/27 | 4578 | graphics/asymptote/doc/FAQ/m-post.pl
+2021/12/27 | 238 | graphics/asymptote/doc/filegraph.asy
+2021/12/27 | 26 | graphics/asymptote/doc/filegraph.dat
+2021/12/27 | 604 | graphics/asymptote/doc/flow.asy
+2021/12/27 | 897 | graphics/asymptote/doc/flowchartdemo.asy
+2021/12/27 | 464 | graphics/asymptote/doc/GaussianSurface.asy
+2021/12/27 | 376 | graphics/asymptote/doc/generalaxis3.asy
+2021/12/27 | 277 | graphics/asymptote/doc/generalaxis.asy
+2021/12/27 | 754 | graphics/asymptote/doc/graphmarkers.asy
+2021/12/27 | 219 | graphics/asymptote/doc/graphwithderiv.asy
+2021/12/27 | 426 | graphics/asymptote/doc/grid3xyz.asy
+2021/12/27 | 279 | graphics/asymptote/doc/hatch.asy
+2021/12/27 | 423 | graphics/asymptote/doc/helix.asy
+2021/12/27 | 324 | graphics/asymptote/doc/HermiteSpline.asy
+2021/12/27 | 441 | graphics/asymptote/doc/histogram.asy
+2021/12/27 | 521 | graphics/asymptote/doc/Hobbycontrol.asy
+2021/12/27 | 500 | graphics/asymptote/doc/Hobbydir.asy
+2021/12/27 | 378 | graphics/asymptote/doc/icon.asy
+2021/12/27 | 401 | graphics/asymptote/doc/image.asy
+2021/12/27 | 868 | graphics/asymptote/doc/imagecontour.asy
+2021/12/27 | 13663 | graphics/asymptote/doc/install-sh
+2021/12/27 | 357 | graphics/asymptote/doc/irregularcontour.asy
+2021/12/27 | 442 | graphics/asymptote/doc/join3.asy
+2021/12/27 | 261 | graphics/asymptote/doc/join.asy
+2021/12/27 | 417 | graphics/asymptote/doc/knots.asy
+2021/12/27 | 121 | graphics/asymptote/doc/labelsquare.asy
+2021/12/27 | 144 | graphics/asymptote/doc/latexmkrc
+2021/12/27 | 150 | graphics/asymptote/doc/latexmkrc_asydir
+2021/12/27 | 3125 | graphics/asymptote/doc/latexusage.tex
+2021/12/27 | 1008 | graphics/asymptote/doc/leastsquares.asy
+2021/12/27 | 6318 | graphics/asymptote/doc/leastsquares.dat
+2021/12/27 | 396 | graphics/asymptote/doc/legend.asy
+2021/12/27 | 366 | graphics/asymptote/doc/lineargraph0.asy
+2021/12/27 | 373 | graphics/asymptote/doc/lineargraph.asy
+2021/12/27 | 415 | graphics/asymptote/doc/linetype.asy
+2021/12/27 | 423 | graphics/asymptote/doc/log2graph.asy
+2021/12/27 | 262 | graphics/asymptote/doc/loggraph.asy
+2021/12/27 | 382 | graphics/asymptote/doc/loggrid.asy
+2021/12/27 | 480 | graphics/asymptote/doc/logimage.asy
+2021/12/27 | 617 | graphics/asymptote/doc/logo.asy
+2021/12/27 | 314 | graphics/asymptote/doc/logticks.asy
+2021/12/27 | 3023 | graphics/asymptote/doc/Makefile.in
+2021/12/27 | 293 | graphics/asymptote/doc/makepen.asy
+2021/12/27 | 2674 | graphics/asymptote/doc/markers1.asy
+2021/12/27 | 877 | graphics/asymptote/doc/markers2.asy
+2021/12/27 | 288 | graphics/asymptote/doc/mexicanhat.asy
+2021/12/27 | 374 | graphics/asymptote/doc/monthaxis.asy
+2021/12/27 | 458 | graphics/asymptote/doc/multicontour.asy
+2021/12/27 | 115 | graphics/asymptote/doc/onecontour.asy
+2021/12/27 | 240 | graphics/asymptote/doc/parametricgraph.asy
+2021/12/27 | 498 | graphics/asymptote/doc/penfunctionimage.asy
+2021/12/27 | 219 | graphics/asymptote/doc/penimage.asy
+2021/12/27 | 2771 | graphics/asymptote/doc/pixel.pdf
+2021/12/27 | 354 | graphics/asymptote/doc/planes.asy
+2021/12/27 | 472132 | graphics/asymptote/doc/png/asymptote.info
+2021/12/27 | 1469 | graphics/asymptote/doc/png/Makefile.in
+2021/12/27 | 49 | graphics/asymptote/doc/quartercircle.asy
+2021/12/27 | 354 | graphics/asymptote/doc/reloadpdf.tex
+2021/12/27 | 157 | graphics/asymptote/doc/saddle.asy
+2021/12/27 | 355 | graphics/asymptote/doc/scaledgraph.asy
+2021/12/27 | 792 | graphics/asymptote/doc/secondaryaxis.asy
+2021/12/27 | 48847 | graphics/asymptote/doc/secondaryaxis.csv
+2021/12/27 | 256 | graphics/asymptote/doc/shadedtiling.asy
+2021/12/27 | 154 | graphics/asymptote/doc/slopefield1.asy
+2021/12/27 | 52 | graphics/asymptote/doc/square.asy
+2021/12/27 | 341 | graphics/asymptote/doc/subpictures.asy
+2021/12/27 | 123 | graphics/asymptote/doc/superpath.asy
+2021/12/27 | 81162 | graphics/asymptote/doc/TeXShopAndAsymptote.pdf
+2021/12/27 | 2653 | graphics/asymptote/doc/TeXShopAndAsymptote.tex
+2021/12/27 | 390 | graphics/asymptote/doc/tile.asy
+2021/12/27 | 396 | graphics/asymptote/doc/triangulate.asy
+2021/12/27 | 186 | graphics/asymptote/doc/unitcircle3.asy
+2021/12/27 | 147 | graphics/asymptote/doc/vectorfield.asy
+2021/12/27 | 1746 | graphics/asymptote/doc/westnile.asy
+2021/12/27 | 4727 | graphics/asymptote/doc/westnile.csv
+2021/12/27 | 880 | graphics/asymptote/doc/xasy.1x
+2021/12/27 | 1851 | graphics/asymptote/drawclipbegin.h
+2021/12/27 | 1197 | graphics/asymptote/drawclipend.h
+2021/12/27 | 11468 | graphics/asymptote/drawelement.h
+2021/12/27 | 4597 | graphics/asymptote/drawfill.cc
+2021/12/27 | 6525 | graphics/asymptote/drawfill.h
+2021/12/27 | 494 | graphics/asymptote/drawgrestore.h
+2021/12/27 | 2880 | graphics/asymptote/drawgroup.h
+2021/12/27 | 464 | graphics/asymptote/drawgsave.h
+2021/12/27 | 3024 | graphics/asymptote/drawimage.h
+2021/12/27 | 6787 | graphics/asymptote/drawlabel.cc
+2021/12/27 | 2134 | graphics/asymptote/drawlabel.h
+2021/12/27 | 1096 | graphics/asymptote/drawlayer.h
+2021/12/27 | 5566 | graphics/asymptote/drawpath3.cc
+2021/12/27 | 5823 | graphics/asymptote/drawpath3.h
+2021/12/27 | 3465 | graphics/asymptote/drawpath.cc
+2021/12/27 | 669 | graphics/asymptote/drawpath.h
+2021/12/27 | 25094 | graphics/asymptote/drawsurface.cc
+2021/12/27 | 23679 | graphics/asymptote/drawsurface.h
+2021/12/27 | 1266 | graphics/asymptote/drawverbatim.h
+2021/12/27 | 17987 | graphics/asymptote/entry.cc
+2021/12/27 | 13615 | graphics/asymptote/entry.h
+2021/12/27 | 5441 | graphics/asymptote/env.cc
+2021/12/27 | 1142 | graphics/asymptote/envcompleter.cc
+2021/12/27 | 845 | graphics/asymptote/envcompleter.h
+2021/12/27 | 4570 | graphics/asymptote/env.h
+2021/12/27 | 10632 | graphics/asymptote/EnvVarUpdate.nsh
+2021/12/27 | 2279 | graphics/asymptote/errormsg.cc
+2021/12/27 | 5621 | graphics/asymptote/errormsg.h
+2021/12/27 | 9251 | graphics/asymptote/errors
+2021/12/27 | 6911 | graphics/asymptote/errortest.asy
+2021/12/27 | 43335 | graphics/asymptote/examples/100d.pdb1
+2021/12/27 | 657 | graphics/asymptote/examples/100d.views
+2021/12/27 | 163 | graphics/asymptote/examples/1overx.asy
+2021/12/27 | 4158 | graphics/asymptote/examples/advection.asy
+2021/12/27 | 245 | graphics/asymptote/examples/alignbox.asy
+2021/12/27 | 2830 | graphics/asymptote/examples/alignedaxis.asy
+2021/12/27 | 946 | graphics/asymptote/examples/animations/cube.asy
+2021/12/27 | 160672 | graphics/asymptote/examples/animations/dice.u3d
+2021/12/27 | 1919 | graphics/asymptote/examples/animations/earthmoon.asy
+2021/12/27 | 503 | graphics/asymptote/examples/animations/embeddedmovie.asy
+2021/12/27 | 196 | graphics/asymptote/examples/animations/embeddedu3d.asy
+2021/12/27 | 411 | graphics/asymptote/examples/animations/externalmovie.asy
+2021/12/27 | 414 | graphics/asymptote/examples/animations/glmovie.asy
+2021/12/27 | 1760 | graphics/asymptote/examples/animations/heatequation.asy
+2021/12/27 | 1037 | graphics/asymptote/examples/animations/inlinemovie3.tex
+2021/12/27 | 1235 | graphics/asymptote/examples/animations/inlinemovie.tex
+2021/12/27 | 326 | graphics/asymptote/examples/animations/pdfmovie.asy
+2021/12/27 | 1247 | graphics/asymptote/examples/animations/slidemovies.asy
+2021/12/27 | 856 | graphics/asymptote/examples/animations/sphere.asy
+2021/12/27 | 798 | graphics/asymptote/examples/animations/torusanimation.asy
+2021/12/27 | 1498 | graphics/asymptote/examples/animations/wavepacket.asy
+2021/12/27 | 1120 | graphics/asymptote/examples/animations/wheel.asy
+2021/12/27 | 236 | graphics/asymptote/examples/annotation.asy
+2021/12/27 | 1240 | graphics/asymptote/examples/arrows3.asy
+2021/12/27 | 61 | graphics/asymptote/examples/axialshade.asy
+2021/12/27 | 496 | graphics/asymptote/examples/bars3.asy
+2021/12/27 | 1033 | graphics/asymptote/examples/basealign.asy
+2021/12/27 | 407 | graphics/asymptote/examples/BezierPatch.asy
+2021/12/27 | 581 | graphics/asymptote/examples/BezierSaddle.asy
+2021/12/27 | 1548 | graphics/asymptote/examples/BezierSurface.asy
+2021/12/27 | 199 | graphics/asymptote/examples/BezierTriangle.asy
+2021/12/27 | 154 | graphics/asymptote/examples/billboard.asy
+2021/12/27 | 513 | graphics/asymptote/examples/buildcycle.asy
+2021/12/27 | 233 | graphics/asymptote/examples/cardioid.asy
+2021/12/27 | 485 | graphics/asymptote/examples/cards.asy
+2021/12/27 | 688 | graphics/asymptote/examples/centroidfg.asy
+2021/12/27 | 322 | graphics/asymptote/examples/cheese.asy
+2021/12/27 | 576 | graphics/asymptote/examples/circles.asy
+2021/12/27 | 228 | graphics/asymptote/examples/circumcircle.asy
+2021/12/27 | 762 | graphics/asymptote/examples/clockarray.asy
+2021/12/27 | 264 | graphics/asymptote/examples/coag.asy
+2021/12/27 | 436 | graphics/asymptote/examples/colorpatch.asy
+2021/12/27 | 472 | graphics/asymptote/examples/colorplanes.asy
+2021/12/27 | 739 | graphics/asymptote/examples/condor.asy
+2021/12/27 | 495 | graphics/asymptote/examples/cones.asy
+2021/12/27 | 1778 | graphics/asymptote/examples/conicurv.asy
+2021/12/27 | 254 | graphics/asymptote/examples/contextfonts.asy
+2021/12/27 | 802 | graphics/asymptote/examples/controlsystem.asy
+2021/12/27 | 123 | graphics/asymptote/examples/Coons.asy
+2021/12/27 | 235 | graphics/asymptote/examples/cos2theta.asy
+2021/12/27 | 582 | graphics/asymptote/examples/cos3.asy
+2021/12/27 | 460 | graphics/asymptote/examples/cosaddition.asy
+2021/12/27 | 5537 | graphics/asymptote/examples/cpkcolors.asy
+2021/12/27 | 572 | graphics/asymptote/examples/curvedlabel3.asy
+2021/12/27 | 177 | graphics/asymptote/examples/curvedlabel.asy
+2021/12/27 | 1835 | graphics/asymptote/examples/cyclohexane.asy
+2021/12/27 | 352 | graphics/asymptote/examples/cylinder.asy
+2021/12/27 | 506 | graphics/asymptote/examples/delu.asy
+2021/12/27 | 509 | graphics/asymptote/examples/dimension.asy
+2021/12/27 | 1216 | graphics/asymptote/examples/dragon.asy
+2021/12/27 | 1298 | graphics/asymptote/examples/electromagnetic.asy
+2021/12/27 | 325 | graphics/asymptote/examples/elevation.asy
+2021/12/27 | 398 | graphics/asymptote/examples/epix.asy
+2021/12/27 | 242 | graphics/asymptote/examples/equilateral.asy
+2021/12/27 | 548 | graphics/asymptote/examples/equilchord.asy
+2021/12/27 | 579 | graphics/asymptote/examples/exp3.asy
+2021/12/27 | 519 | graphics/asymptote/examples/extrudedcontour.asy
+2021/12/27 | 498 | graphics/asymptote/examples/fano.asy
+2021/12/27 | 973 | graphics/asymptote/examples/fequlogo.asy
+2021/12/27 | 727 | graphics/asymptote/examples/fermi.asy
+2021/12/27 | 980 | graphics/asymptote/examples/filesurface.asy
+2021/12/27 | 5543 | graphics/asymptote/examples/filesurface.dat
+2021/12/27 | 570 | graphics/asymptote/examples/fillcontour.asy
+2021/12/27 | 4244 | graphics/asymptote/examples/fin.asy
+2021/12/27 | 710 | graphics/asymptote/examples/fjortoft.asy
+2021/12/27 | 558 | graphics/asymptote/examples/floatingdisk.asy
+2021/12/27 | 500 | graphics/asymptote/examples/floor.asy
+2021/12/27 | 683 | graphics/asymptote/examples/fractaltree.asy
+2021/12/27 | 1185 | graphics/asymptote/examples/functionshading.asy
+2021/12/27 | 499 | graphics/asymptote/examples/galleon.asy
+2021/12/27 | 713 | graphics/asymptote/examples/gamma3.asy
+2021/12/27 | 439 | graphics/asymptote/examples/gamma.asy
+2021/12/27 | 679 | graphics/asymptote/examples/genusthree.asy
+2021/12/27 | 1164 | graphics/asymptote/examples/genustwo.asy
+2021/12/27 | 383 | graphics/asymptote/examples/Gouraud.asy
+2021/12/27 | 616 | graphics/asymptote/examples/Gouraudcontour.asy
+2021/12/27 | 76 | graphics/asymptote/examples/grid.asy
+2021/12/27 | 459 | graphics/asymptote/examples/hierarchy.asy
+2021/12/27 | 315 | graphics/asymptote/examples/hyperboloid.asy
+2021/12/27 | 267 | graphics/asymptote/examples/hyperboloidsilhouette.asy
+2021/12/27 | 1111 | graphics/asymptote/examples/imagehistogram.asy
+2021/12/27 | 610 | graphics/asymptote/examples/impact.asy
+2021/12/27 | 598 | graphics/asymptote/examples/integraltest.asy
+2021/12/27 | 4808 | graphics/asymptote/examples/interpolate1.asy
+2021/12/27 | 289 | graphics/asymptote/examples/jump.asy
+2021/12/27 | 1352 | graphics/asymptote/examples/Klein.asy
+2021/12/27 | 182 | graphics/asymptote/examples/label3.asy
+2021/12/27 | 196 | graphics/asymptote/examples/label3ribbon.asy
+2021/12/27 | 187 | graphics/asymptote/examples/label3solid.asy
+2021/12/27 | 632 | graphics/asymptote/examples/label3zoom.asy
+2021/12/27 | 264 | graphics/asymptote/examples/labelbox.asy
+2021/12/27 | 1114 | graphics/asymptote/examples/laserlattice.asy
+2021/12/27 | 136 | graphics/asymptote/examples/latticeshading.asy
+2021/12/27 | 690 | graphics/asymptote/examples/layers.asy
+2021/12/27 | 460 | graphics/asymptote/examples/lever.asy
+2021/12/27 | 654 | graphics/asymptote/examples/limit.asy
+2021/12/27 | 1910 | graphics/asymptote/examples/linearregression.asy
+2021/12/27 | 168 | graphics/asymptote/examples/lines.asy
+2021/12/27 | 1040 | graphics/asymptote/examples/lmfit1.asy
+2021/12/27 | 206 | graphics/asymptote/examples/log.asy
+2021/12/27 | 349 | graphics/asymptote/examples/logdown.asy
+2021/12/27 | 1461 | graphics/asymptote/examples/logo3.asy
+2021/12/27 | 196 | graphics/asymptote/examples/lowint.asy
+2021/12/27 | 657 | graphics/asymptote/examples/lowupint.asy
+2021/12/27 | 479 | graphics/asymptote/examples/magnetic.asy
+2021/12/27 | 879 | graphics/asymptote/examples/markregular.asy
+2021/12/27 | 1968 | graphics/asymptote/examples/mergeExample.asy
+2021/12/27 | 5216 | graphics/asymptote/examples/mosaic.asy
+2021/12/27 | 2504 | graphics/asymptote/examples/mosquito.asy
+2021/12/27 | 1566 | graphics/asymptote/examples/near_earth.asy
+2021/12/27 | 658 | graphics/asymptote/examples/NURBScurve.asy
+2021/12/27 | 1042 | graphics/asymptote/examples/NURBSsphere.asy
+2021/12/27 | 1552 | graphics/asymptote/examples/NURBSsurface.asy
+2021/12/27 | 1251 | graphics/asymptote/examples/odetest.asy
+2021/12/27 | 308 | graphics/asymptote/examples/oneoverx.asy
+2021/12/27 | 810 | graphics/asymptote/examples/orthocenter.asy
+2021/12/27 | 254 | graphics/asymptote/examples/parametricelevation.asy
+2021/12/27 | 407 | graphics/asymptote/examples/parametricsurface.asy
+2021/12/27 | 711 | graphics/asymptote/examples/partialsurface.asy
+2021/12/27 | 1055 | graphics/asymptote/examples/partitionExample.asy
+2021/12/27 | 426 | graphics/asymptote/examples/pathintersectsurface.asy
+2021/12/27 | 3335 | graphics/asymptote/examples/pdb.asy
+2021/12/27 | 361 | graphics/asymptote/examples/phase.asy
+2021/12/27 | 22873 | graphics/asymptote/examples/piicon.png
+2021/12/27 | 362 | graphics/asymptote/examples/pipeintersection.asy
+2021/12/27 | 3857 | graphics/asymptote/examples/pipes.asy
+2021/12/27 | 418 | graphics/asymptote/examples/planeproject.asy
+2021/12/27 | 930 | graphics/asymptote/examples/polararea.asy
+2021/12/27 | 628 | graphics/asymptote/examples/polarcircle.asy
+2021/12/27 | 326 | graphics/asymptote/examples/polardatagraph.asy
+2021/12/27 | 641 | graphics/asymptote/examples/pOrbital.asy
+2021/12/27 | 954 | graphics/asymptote/examples/poster.asy
+2021/12/27 | 58 | graphics/asymptote/examples/progrid.asy
+2021/12/27 | 373 | graphics/asymptote/examples/projectelevation.asy
+2021/12/27 | 427 | graphics/asymptote/examples/projectrevolution.asy
+2021/12/27 | 747 | graphics/asymptote/examples/pseudosphere.asy
+2021/12/27 | 557 | graphics/asymptote/examples/Pythagoras.asy
+2021/12/27 | 420 | graphics/asymptote/examples/PythagoreanTree.asy
+2021/12/27 | 734 | graphics/asymptote/examples/quilt.asy
+2021/12/27 | 345 | graphics/asymptote/examples/rainbow.asy
+2021/12/27 | 78 | graphics/asymptote/examples/randompath3.asy
+2021/12/27 | 1537 | graphics/asymptote/examples/refs.bib
+2021/12/27 | 990 | graphics/asymptote/examples/RiemannSphere.asy
+2021/12/27 | 348 | graphics/asymptote/examples/RiemannSurface.asy
+2021/12/27 | 384 | graphics/asymptote/examples/RiemannSurfaceRoot.asy
+2021/12/27 | 141 | graphics/asymptote/examples/ring.asy
+2021/12/27 | 184 | graphics/asymptote/examples/roll.asy
+2021/12/27 | 1309 | graphics/asymptote/examples/roundpath.asy
+2021/12/27 | 288 | graphics/asymptote/examples/sacone3D.asy
+2021/12/27 | 445 | graphics/asymptote/examples/sacone.asy
+2021/12/27 | 341 | graphics/asymptote/examples/sacylinder3D.asy
+2021/12/27 | 400 | graphics/asymptote/examples/sacylinder.asy
+2021/12/27 | 66 | graphics/asymptote/examples/shade.asy
+2021/12/27 | 111 | graphics/asymptote/examples/shadestroke.asy
+2021/12/27 | 1065 | graphics/asymptote/examples/shellmethod.asy
+2021/12/27 | 829 | graphics/asymptote/examples/shellsqrtx01.asy
+2021/12/27 | 410 | graphics/asymptote/examples/Sierpinski.asy
+2021/12/27 | 821 | graphics/asymptote/examples/SierpinskiGasket.asy
+2021/12/27 | 2398 | graphics/asymptote/examples/SierpinskiSponge.asy
+2021/12/27 | 327 | graphics/asymptote/examples/sin1x.asy
+2021/12/27 | 579 | graphics/asymptote/examples/sin3.asy
+2021/12/27 | 591 | graphics/asymptote/examples/sinc.asy
+2021/12/27 | 378 | graphics/asymptote/examples/sinxlex.asy
+2021/12/27 | 3358 | graphics/asymptote/examples/slidedemo.asy
+2021/12/27 | 341 | graphics/asymptote/examples/slidedemo_.bbl
+2021/12/27 | 2023 | graphics/asymptote/examples/slope.asy
+2021/12/27 | 520 | graphics/asymptote/examples/smoothelevation.asy
+2021/12/27 | 2680 | graphics/asymptote/examples/soccerball.asy
+2021/12/27 | 2362 | graphics/asymptote/examples/spectrum.asy
+2021/12/27 | 141 | graphics/asymptote/examples/sphere.asy
+2021/12/27 | 150 | graphics/asymptote/examples/spheresilhouette.asy
+2021/12/27 | 162 | graphics/asymptote/examples/sphereskeleton.asy
+2021/12/27 | 376 | graphics/asymptote/examples/sphericalharmonic.asy
+2021/12/27 | 424 | graphics/asymptote/examples/spiral3.asy
+2021/12/27 | 210 | graphics/asymptote/examples/spiral.asy
+2021/12/27 | 608 | graphics/asymptote/examples/spline.asy
+2021/12/27 | 2191 | graphics/asymptote/examples/splitpatch.asy
+2021/12/27 | 38 | graphics/asymptote/examples/spring0.asy
+2021/12/27 | 43 | graphics/asymptote/examples/spring2.asy
+2021/12/27 | 667 | graphics/asymptote/examples/spring.asy
+2021/12/27 | 674 | graphics/asymptote/examples/sqrtx01.asy
+2021/12/27 | 579 | graphics/asymptote/examples/sqrtx01y1.asy
+2021/12/27 | 145 | graphics/asymptote/examples/star.asy
+2021/12/27 | 162 | graphics/asymptote/examples/stereoscopic.asy
+2021/12/27 | 59 | graphics/asymptote/examples/stroke3.asy
+2021/12/27 | 300 | graphics/asymptote/examples/strokepath.asy
+2021/12/27 | 175 | graphics/asymptote/examples/strokeshade.asy
+2021/12/27 | 198 | graphics/asymptote/examples/tanh.asy
+2021/12/27 | 14378 | graphics/asymptote/examples/teapot.asy
+2021/12/27 | 34 | graphics/asymptote/examples/teapotIBL.asy
+2021/12/27 | 303 | graphics/asymptote/examples/tensor.asy
+2021/12/27 | 547 | graphics/asymptote/examples/tetra.asy
+2021/12/27 | 312 | graphics/asymptote/examples/textpath.asy
+2021/12/27 | 8429 | graphics/asymptote/examples/thermodynamics.asy
+2021/12/27 | 576 | graphics/asymptote/examples/threeviews.asy
+2021/12/27 | 104 | graphics/asymptote/examples/tiling.asy
+2021/12/27 | 419 | graphics/asymptote/examples/torus.asy
+2021/12/27 | 188 | graphics/asymptote/examples/transparency.asy
+2021/12/27 | 250 | graphics/asymptote/examples/transparentCubes.asy
+2021/12/27 | 602 | graphics/asymptote/examples/treetest.asy
+2021/12/27 | 589 | graphics/asymptote/examples/trefoilknot.asy
+2021/12/27 | 972 | graphics/asymptote/examples/triads.asy
+2021/12/27 | 207 | graphics/asymptote/examples/triangle.asy
+2021/12/27 | 441 | graphics/asymptote/examples/triangles.asy
+2021/12/27 | 251 | graphics/asymptote/examples/triceratops.asy
+2021/12/27 | 291 | graphics/asymptote/examples/trumpet.asy
+2021/12/27 | 2101 | graphics/asymptote/examples/truncatedIcosahedron.asy
+2021/12/27 | 40665 | graphics/asymptote/examples/tvgen.asy
+2021/12/27 | 868 | graphics/asymptote/examples/twistedtubes.asy
+2021/12/27 | 26096 | graphics/asymptote/examples/uhrturm.obj
+2021/12/27 | 322 | graphics/asymptote/examples/unitcircle.asy
+2021/12/27 | 430 | graphics/asymptote/examples/unitoctant.asy
+2021/12/27 | 714 | graphics/asymptote/examples/unitoctantx.asy
+2021/12/27 | 199 | graphics/asymptote/examples/upint.asy
+2021/12/27 | 525 | graphics/asymptote/examples/vectorfield3.asy
+2021/12/27 | 351 | graphics/asymptote/examples/vectorfieldsphere.asy
+2021/12/27 | 839 | graphics/asymptote/examples/venn3.asy
+2021/12/27 | 626 | graphics/asymptote/examples/venn.asy
+2021/12/27 | 802 | graphics/asymptote/examples/vertexshading.asy
+2021/12/27 | 360 | graphics/asymptote/examples/washer.asy
+2021/12/27 | 1010 | graphics/asymptote/examples/washermethod.asy
+2021/12/27 | 628 | graphics/asymptote/examples/wedge.asy
+2021/12/27 | 1030 | graphics/asymptote/examples/workcone.asy
+2021/12/27 | 978 | graphics/asymptote/examples/worksheet.asy
+2021/12/27 | 2626 | graphics/asymptote/examples/worldmap.asy
+2021/12/27 | 1261761 | graphics/asymptote/examples/worldmap.dat
+2021/12/27 | 580 | graphics/asymptote/examples/xsin1x.asy
+2021/12/27 | 3739 | graphics/asymptote/examples/xstitch.asy
+2021/12/27 | 743 | graphics/asymptote/examples/xxsq01.asy
+2021/12/27 | 866 | graphics/asymptote/examples/xxsq01x-1.asy
+2021/12/27 | 825 | graphics/asymptote/examples/xxsq01y.asy
+2021/12/27 | 222 | graphics/asymptote/examples/yingyang.asy
+2021/12/27 | 37783 | graphics/asymptote/exp.cc
+2021/12/27 | 30307 | graphics/asymptote/exp.h
+2021/12/27 | 1188 | graphics/asymptote/EXRFiles.cc
+2021/12/27 | 454 | graphics/asymptote/EXRFiles.h
+2021/12/27 | 178 | graphics/asymptote/fftw++asy.cc
+2021/12/27 | 1694 | graphics/asymptote/fftw++.cc
+2021/12/27 | 45411 | graphics/asymptote/fftw++.h
+2021/12/27 | 4866 | graphics/asymptote/fileio.cc
+2021/12/27 | 21382 | graphics/asymptote/fileio.h
+2021/12/27 | 1245 | graphics/asymptote/findsym.pl
+2021/12/27 | 1020 | graphics/asymptote/flatguide.cc
+2021/12/27 | 4209 | graphics/asymptote/flatguide.h
+2021/12/27 | 654 | graphics/asymptote/fpu.h
+2021/12/27 | 2164 | graphics/asymptote/frame.h
+2021/12/27 | 9772 | graphics/asymptote/fundec.cc
+2021/12/27 | 4895 | graphics/asymptote/fundec.h
+2021/12/27 | 1183225 | graphics/asymptote/gc-8.2.0.tar.gz
+2021/12/27 | 6275 | graphics/asymptote/generate_enums.py
+2021/12/27 | 3153 | graphics/asymptote/genv.cc
+2021/12/27 | 1626 | graphics/asymptote/genv.h
+2021/12/27 | 4520 | graphics/asymptote/getopt1.c
+2021/12/27 | 30147 | graphics/asymptote/getopt.c
+2021/12/27 | 6650 | graphics/asymptote/getopt.h
+2021/12/27 | 202 | graphics/asymptote/glew.c
+2021/12/27 | 1235777 | graphics/asymptote/GL/glew.c
+2021/12/27 | 1186601 | graphics/asymptote/GL/glew.h
+2021/12/27 | 73435 | graphics/asymptote/GL/glxew.h
+2021/12/27 | 76801 | graphics/asymptote/gl-matrix-2.4.0-pruned/dist/gl-matrix.js
+2021/12/27 | 1131 | graphics/asymptote/gl-matrix-2.4.0-pruned/LICENSE.js
+2021/12/27 | 57688 | graphics/asymptote/glrender.cc
+2021/12/27 | 9362 | graphics/asymptote/glrender.h
+2021/12/27 | 818 | graphics/asymptote/GLTextures.cc
+2021/12/27 | 3608 | graphics/asymptote/GLTextures.h
+2021/12/27 | 63314 | graphics/asymptote/GL/wglew.h
+2021/12/27 | 50437 | graphics/asymptote/gsl.cc
+2021/12/27 | 22 | graphics/asymptote/GUI/configs/__init__.py
+2021/12/27 | 1215 | graphics/asymptote/GUI/configs/xasyconfig.cson
+2021/12/27 | 476 | graphics/asymptote/GUI/configs/xasykeymap.cson
+2021/12/27 | 3592 | graphics/asymptote/GUI/CustMatTransform.py
+2021/12/27 | 100 | graphics/asymptote/GUI/DebugFlags.py
+2021/12/27 | 1149 | graphics/asymptote/guide.cc
+2021/12/27 | 294 | graphics/asymptote/guideflags.h
+2021/12/27 | 6725 | graphics/asymptote/guide.h
+2021/12/27 | 1751 | graphics/asymptote/GUI/GuidesManager.py
+2021/12/27 | 23 | graphics/asymptote/GUI/__init__.py
+2021/12/27 | 15895 | graphics/asymptote/GUI/InplaceAddObj.py
+2021/12/27 | 5272 | graphics/asymptote/GUI/labelEditor.py
+2021/12/27 | 700 | graphics/asymptote/GUI/locale/th/LC_MESSAGES/base.po
+2021/12/27 | 2445 | graphics/asymptote/GUI/PrimitiveShape.py
+2021/12/27 | 10038 | graphics/asymptote/GUI/pyUIClass/custMatTransform.py
+2021/12/27 | 6247 | graphics/asymptote/GUI/pyUIClass/labelTextEditor.py
+2021/12/27 | 2918 | graphics/asymptote/GUI/pyUIClass/setCustomAnchor.py
+2021/12/27 | 7222 | graphics/asymptote/GUI/pyUIClass/widg_addLabel.py
+2021/12/27 | 2960 | graphics/asymptote/GUI/pyUIClass/widg_addPolyOpt.py
+2021/12/27 | 4942 | graphics/asymptote/GUI/pyUIClass/widg_editBezier.py
+2021/12/27 | 4761 | graphics/asymptote/GUI/pyUIClass/widgetPointEditor.py
+2021/12/27 | 59583 | graphics/asymptote/GUI/pyUIClass/window1.py
+2021/12/27 | 57 | graphics/asymptote/GUI/requirements.txt
+2021/12/27 | 361 | graphics/asymptote/GUI/res/icons/anchor.svg
+2021/12/27 | 637 | graphics/asymptote/GUI/res/icons/android-arrow-back.svg
+2021/12/27 | 637 | graphics/asymptote/GUI/res/icons/android-arrow-forward.svg
+2021/12/27 | 802 | graphics/asymptote/GUI/res/icons/android-camera.svg
+2021/12/27 | 695 | graphics/asymptote/GUI/res/icons/android-close.svg
+2021/12/27 | 1319 | graphics/asymptote/GUI/res/icons/android-color-palette.svg
+2021/12/27 | 674 | graphics/asymptote/GUI/res/icons/android-delete.svg
+2021/12/27 | 633 | graphics/asymptote/GUI/res/icons/android-done.svg
+2021/12/27 | 822 | graphics/asymptote/GUI/res/icons/android-expand.svg
+2021/12/27 | 850 | graphics/asymptote/GUI/res/icons/android-folder-open.svg
+2021/12/27 | 1482 | graphics/asymptote/GUI/res/icons/android-hand.svg
+2021/12/27 | 1124 | graphics/asymptote/GUI/res/icons/android-locate.svg
+2021/12/27 | 764 | graphics/asymptote/GUI/res/icons/android-radio-button-off.svg
+2021/12/27 | 844 | graphics/asymptote/GUI/res/icons/android-radio-button-on.svg
+2021/12/27 | 806 | graphics/asymptote/GUI/res/icons/android-refresh.svg
+2021/12/27 | 713 | graphics/asymptote/GUI/res/icons/arrow-move.svg
+2021/12/27 | 639 | graphics/asymptote/GUI/res/icons/arrow-resize.svg
+2021/12/27 | 999 | graphics/asymptote/GUI/res/icons/brush.svg
+2021/12/27 | 593 | graphics/asymptote/GUI/res/icons/bucket.asy
+2021/12/27 | 1436 | graphics/asymptote/GUI/res/icons/bucket.svg
+2021/12/27 | 111 | graphics/asymptote/GUI/res/icons/center.asy
+2021/12/27 | 124 | graphics/asymptote/GUI/res/icons/centerorigin.asy
+2021/12/27 | 1022 | graphics/asymptote/GUI/res/icons/centerorigin.svg
+2021/12/27 | 858 | graphics/asymptote/GUI/res/icons/center.svg
+2021/12/27 | 780 | graphics/asymptote/GUI/res/icons/check.svg
+2021/12/27 | 1013 | graphics/asymptote/GUI/res/icons/chevron-with-circle-left.svg
+2021/12/27 | 998 | graphics/asymptote/GUI/res/icons/chevron-with-circle-right.svg
+2021/12/27 | 754 | graphics/asymptote/GUI/res/icons/circle.svg
+2021/12/27 | 109 | graphics/asymptote/GUI/res/icons/closedcurve.asy
+2021/12/27 | 1187 | graphics/asymptote/GUI/res/icons/closedcurve.svg
+2021/12/27 | 109 | graphics/asymptote/GUI/res/icons/closedpolygon.asy
+2021/12/27 | 1058 | graphics/asymptote/GUI/res/icons/closedpolygon.svg
+2021/12/27 | 838 | graphics/asymptote/GUI/res/icons/close-round.svg
+2021/12/27 | 1194 | graphics/asymptote/GUI/res/icons/code.svg
+2021/12/27 | 876 | graphics/asymptote/GUI/res/icons/edit.svg
+2021/12/27 | 1003 | graphics/asymptote/GUI/res/icons/eye.svg
+2021/12/27 | 1884 | graphics/asymptote/GUI/res/icons/filledbucket.svg
+2021/12/27 | 1764 | graphics/asymptote/GUI/res/icons/grid.svg
+2021/12/27 | 964 | graphics/asymptote/GUI/res/icons/magnifying-glass.svg
+2021/12/27 | 102 | graphics/asymptote/GUI/res/icons/opencurve.asy
+2021/12/27 | 1139 | graphics/asymptote/GUI/res/icons/opencurve.svg
+2021/12/27 | 102 | graphics/asymptote/GUI/res/icons/openpolygon.asy
+2021/12/27 | 1043 | graphics/asymptote/GUI/res/icons/openpolygon.svg
+2021/12/27 | 759 | graphics/asymptote/GUI/res/icons/plus-round.svg
+2021/12/27 | 1808 | graphics/asymptote/GUI/res/icons.qrc
+2021/12/27 | 1130 | graphics/asymptote/GUI/res/icons/redo.svg
+2021/12/27 | 673 | graphics/asymptote/GUI/res/icons/save.svg
+2021/12/27 | 1920 | graphics/asymptote/GUI/res/icons/social-python.svg
+2021/12/27 | 108 | graphics/asymptote/GUI/res/icons/subdirectory-left.svg
+2021/12/27 | 284 | graphics/asymptote/GUI/res/icons/text.svg
+2021/12/27 | 1226 | graphics/asymptote/GUI/res/icons/triangle-stroked-15.svg
+2021/12/27 | 1087 | graphics/asymptote/GUI/res/icons/undo.svg
+2021/12/27 | 1449 | graphics/asymptote/GUI/SetCustomAnchor.py
+2021/12/27 | 393 | graphics/asymptote/GUI/setup.py
+2021/12/27 | 3616 | graphics/asymptote/GUI/UndoRedoStack.py
+2021/12/27 | 3267 | graphics/asymptote/GUI/Widg_addLabel.py
+2021/12/27 | 877 | graphics/asymptote/GUI/Widg_addPolyOpt.py
+2021/12/27 | 1658 | graphics/asymptote/GUI/Widg_editBezier.py
+2021/12/27 | 94848 | graphics/asymptote/GUI/Window1.py
+2021/12/27 | 10271 | graphics/asymptote/GUI/windows/custMatTransform.ui
+2021/12/27 | 6552 | graphics/asymptote/GUI/windows/labelTextEditor.ui
+2021/12/27 | 2631 | graphics/asymptote/GUI/windows/setCustomAnchor.ui
+2021/12/27 | 6896 | graphics/asymptote/GUI/windows/widg_addLabel.ui
+2021/12/27 | 2941 | graphics/asymptote/GUI/windows/widg_addPolyOpt.ui
+2021/12/27 | 4474 | graphics/asymptote/GUI/windows/widg_editBezier.ui
+2021/12/27 | 4166 | graphics/asymptote/GUI/windows/widgetPointEditor.ui
+2021/12/27 | 79003 | graphics/asymptote/GUI/windows/window1.ui
+2021/12/27 | 60074 | graphics/asymptote/GUI/xasy2asy.py
+2021/12/27 | 1183 | graphics/asymptote/GUI/xasyArgs.py
+2021/12/27 | 14082 | graphics/asymptote/GUI/xasyBezierInterface.py
+2021/12/27 | 4084 | graphics/asymptote/GUI/xasyFile.py
+2021/12/27 | 6717 | graphics/asymptote/GUI/xasyOptions.py
+2021/12/27 | 611 | graphics/asymptote/GUI/xasy.py
+2021/12/27 | 586 | graphics/asymptote/GUI/xasyStrings.py
+2021/12/27 | 733 | graphics/asymptote/GUI/xasySvg.py
+2021/12/27 | 1015 | graphics/asymptote/GUI/xasyTransform.py
+2021/12/27 | 1542 | graphics/asymptote/GUI/xasyUtils.py
+2021/12/27 | 238 | graphics/asymptote/GUI/xasyValidator.py
+2021/12/27 | 12823 | graphics/asymptote/impdatum.cc
+2021/12/27 | 127 | graphics/asymptote/index.html
+2021/12/27 | 10445 | graphics/asymptote/INSTALL
+2021/12/27 | 15645 | graphics/asymptote/install-sh
+2021/12/27 | 1982 | graphics/asymptote/inst.h
+2021/12/27 | 5586 | graphics/asymptote/interact.cc
+2021/12/27 | 1345 | graphics/asymptote/interact.h
+2021/12/27 | 5733 | graphics/asymptote/item.h
+2021/12/27 | 11846 | graphics/asymptote/jsfile.cc
+2021/12/27 | 3065 | graphics/asymptote/jsfile.h
+2021/12/27 | 609 | graphics/asymptote/keywords.cc
+2021/12/27 | 1253 | graphics/asymptote/keywords.pl
+2021/12/27 | 22345 | graphics/asymptote/knot.cc
+2021/12/27 | 12259 | graphics/asymptote/knot.h
+2021/12/27 | 342 | graphics/asymptote/lexical.h
+2021/12/27 | 83449 | graphics/asymptote/lex.yy.cc
+2021/12/27 | 35147 | graphics/asymptote/LICENSE
+2021/12/27 | 7639 | graphics/asymptote/LICENSE.LESSER
+2021/12/27 | 2766 | graphics/asymptote/lnkX64IconFix.nsh
+2021/12/27 | 2194 | graphics/asymptote/locate.cc
+2021/12/27 | 631 | graphics/asymptote/locate.h
+2021/12/27 | 4973 | graphics/asymptote/LspCpp/example/StdIOClientExample.cpp
+2021/12/27 | 3669 | graphics/asymptote/LspCpp/example/StdIOServerExample.cpp
+2021/12/27 | 4837 | graphics/asymptote/LspCpp/example/TcpServerExample.cpp
+2021/12/27 | 8095 | graphics/asymptote/LspCpp/example/WebsocketExample.cpp
+2021/12/27 | 460 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/Cancellation.h
+2021/12/27 | 867 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/Condition.h
+2021/12/27 | 949 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/Context.cpp
+2021/12/27 | 7671 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/Context.h
+2021/12/27 | 1171 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/Endpoint.cpp
+2021/12/27 | 1665 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/Endpoint.h
+2021/12/27 | 262 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/GCThreadContext.cpp
+2021/12/27 | 217 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/GCThreadContext.h
+2021/12/27 | 2845 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/json.h
+2021/12/27 | 1159 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/lsRequestId.h
+2021/12/27 | 1600 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/lsResponseMessage.h
+2021/12/27 | 2054 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/message.cpp
+2021/12/27 | 628 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/message.h
+2021/12/27 | 4580 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageIssue.h
+2021/12/27 | 1175 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageJsonHandler.cpp
+2021/12/27 | 2122 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageJsonHandler.h
+2021/12/27 | 241 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageProducer.h
+2021/12/27 | 1475 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/NotificationInMessage.h
+2021/12/27 | 54109 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/optional.hpp
+2021/12/27 | 16878 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/RemoteEndPoint.cpp
+2021/12/27 | 10070 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/RemoteEndPoint.h
+2021/12/27 | 1774 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/RequestInMessage.h
+2021/12/27 | 1765 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/ScopeExit.h
+2021/12/27 | 4792 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/serializer.cpp
+2021/12/27 | 10581 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/serializer.h
+2021/12/27 | 2930 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/stream.h
+2021/12/27 | 4366 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/StreamMessageProducer.cpp
+2021/12/27 | 1000 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/StreamMessageProducer.h
+2021/12/27 | 8990 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/TcpServer.cpp
+2021/12/27 | 1183 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/TcpServer.h
+2021/12/27 | 450 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/threaded_queue.cpp
+2021/12/27 | 6386 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/threaded_queue.h
+2021/12/27 | 6369 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/traits.h
+2021/12/27 | 10221 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/WebSocketServer.cpp
+2021/12/27 | 2424 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/WebSocketServer.h
+2021/12/27 | 706 | graphics/asymptote/LspCpp/LibLsp/lsp/AbsolutePath.h
+2021/12/27 | 8521 | graphics/asymptote/LspCpp/LibLsp/lsp/ClientPreferences.h
+2021/12/27 | 1567 | graphics/asymptote/LspCpp/LibLsp/lsp/client/registerCapability.h
+2021/12/27 | 1019 | graphics/asymptote/LspCpp/LibLsp/lsp/client/unregisterCapability.h
+2021/12/27 | 2636 | graphics/asymptote/LspCpp/LibLsp/lsp/CodeActionParams.h
+2021/12/27 | 236 | graphics/asymptote/LspCpp/LibLsp/lsp/Directory.h
+2021/12/27 | 587 | graphics/asymptote/LspCpp/LibLsp/lsp/ExecuteCommandParams.h
+2021/12/27 | 625 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/addOverridableMethods.h
+2021/12/27 | 382 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/buildWorkspace.h
+2021/12/27 | 842 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkConstructorsStatus.h
+2021/12/27 | 827 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkDelegateMethodsStatus.h
+2021/12/27 | 1002 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkHashCodeEqualsStatus.h
+2021/12/27 | 631 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkToStringStatus.h
+2021/12/27 | 294 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/classFileContents.h
+2021/12/27 | 1109 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/codeActionResult.h
+2021/12/27 | 901 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/executeCommand.h
+2021/12/27 | 579 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/findLinks.h
+2021/12/27 | 565 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateAccessors.h
+2021/12/27 | 617 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateConstructors.h
+2021/12/27 | 828 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateDelegateMethods.h
+2021/12/27 | 738 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateHashCodeEquals.h
+2021/12/27 | 514 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateToString.h
+2021/12/27 | 1673 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/getMoveDestinations.h
+2021/12/27 | 2104 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/getRefactorEdit.h
+2021/12/27 | 325 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/listOverridableMethods.h
+2021/12/27 | 320 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/Move.h
+2021/12/27 | 301 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/organizeImports.h
+2021/12/27 | 907 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/OverridableMethod.h
+2021/12/27 | 309 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/projectConfigurationUpdate.h
+2021/12/27 | 748 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/resolveUnimplementedAccessors.h
+2021/12/27 | 722 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/searchSymbols.h
+2021/12/27 | 229 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/WorkspaceSymbolParams.h
+2021/12/27 | 5734 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/protocol.h
+2021/12/27 | 632 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/SCTConfig.h
+2021/12/27 | 16226 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/sct.cpp
+2021/12/27 | 1918 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/sct.h
+2021/12/27 | 4688 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/sonarlint/protocol.h
+2021/12/27 | 203 | graphics/asymptote/LspCpp/LibLsp/lsp/general/exit.h
+2021/12/27 | 1055 | graphics/asymptote/LspCpp/LibLsp/lsp/general/initialize.cpp
+2021/12/27 | 482 | graphics/asymptote/LspCpp/LibLsp/lsp/general/initialized.h
+2021/12/27 | 1380 | graphics/asymptote/LspCpp/LibLsp/lsp/general/initialize.h
+2021/12/27 | 3418 | graphics/asymptote/LspCpp/LibLsp/lsp/general/InitializeParams.h
+2021/12/27 | 1150 | graphics/asymptote/LspCpp/LibLsp/lsp/general/lsClientCapabilities.h
+2021/12/27 | 18994 | graphics/asymptote/LspCpp/LibLsp/lsp/general/lsServerCapabilities.h
+2021/12/27 | 22502 | graphics/asymptote/LspCpp/LibLsp/lsp/general/lsTextDocumentClientCapabilities.h
+2021/12/27 | 6889 | graphics/asymptote/LspCpp/LibLsp/lsp/general/lsWorkspaceClientCapabilites.h
+2021/12/27 | 693 | graphics/asymptote/LspCpp/LibLsp/lsp/general/progress.h
+2021/12/27 | 487 | graphics/asymptote/LspCpp/LibLsp/lsp/general/shutdown.h
+2021/12/27 | 4578 | graphics/asymptote/LspCpp/LibLsp/lsp/IProgressMonitor.h
+2021/12/27 | 2974 | graphics/asymptote/LspCpp/LibLsp/lsp/language/language.h
+2021/12/27 | 1808 | graphics/asymptote/LspCpp/LibLsp/lsp/location_type.h
+2021/12/27 | 4118 | graphics/asymptote/LspCpp/LibLsp/lsp/lru_cache.h
+2021/12/27 | 3294 | graphics/asymptote/LspCpp/LibLsp/lsp/lsAny.h
+2021/12/27 | 1213 | graphics/asymptote/LspCpp/LibLsp/lsp/lsCodeAction.h
+2021/12/27 | 1328 | graphics/asymptote/LspCpp/LibLsp/lsp/lsCommand.h
+2021/12/27 | 778 | graphics/asymptote/LspCpp/LibLsp/lsp/lsDocumentUri.h
+2021/12/27 | 1192 | graphics/asymptote/LspCpp/LibLsp/lsp/lsFormattingOptions.h
+2021/12/27 | 1105 | graphics/asymptote/LspCpp/LibLsp/lsp/lsMarkedString.h
+2021/12/27 | 1411 | graphics/asymptote/LspCpp/LibLsp/lsp/lsp_code_action.h
+2021/12/27 | 7152 | graphics/asymptote/LspCpp/LibLsp/lsp/lsp_completion.h
+2021/12/27 | 23274 | graphics/asymptote/LspCpp/LibLsp/lsp/lsp.cpp
+2021/12/27 | 1661 | graphics/asymptote/LspCpp/LibLsp/lsp/lsp_diagnostic.cpp
+2021/12/27 | 3834 | graphics/asymptote/LspCpp/LibLsp/lsp/lsp_diagnostic.h
+2021/12/27 | 1143 | graphics/asymptote/LspCpp/LibLsp/lsp/lsPosition.h
+2021/12/27 | 842 | graphics/asymptote/LspCpp/LibLsp/lsp/lsRange.h
+2021/12/27 | 3004 | graphics/asymptote/LspCpp/LibLsp/lsp/lsResponseError.h
+2021/12/27 | 688 | graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentEdit.h
+2021/12/27 | 424 | graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentIdentifier.h
+2021/12/27 | 676 | graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentItem.h
+2021/12/27 | 667 | graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentPositionParams.h
+2021/12/27 | 2514 | graphics/asymptote/LspCpp/LibLsp/lsp/lsTextEdit.h
+2021/12/27 | 1154 | graphics/asymptote/LspCpp/LibLsp/lsp/lsVersionedTextDocumentIdentifier.h
+2021/12/27 | 2482 | graphics/asymptote/LspCpp/LibLsp/lsp/lsWorkspaceEdit.h
+2021/12/27 | 33677 | graphics/asymptote/LspCpp/LibLsp/lsp/Markup/Markup.cpp
+2021/12/27 | 3917 | graphics/asymptote/LspCpp/LibLsp/lsp/Markup/Markup.h
+2021/12/27 | 27528 | graphics/asymptote/LspCpp/LibLsp/lsp/Markup/string_ref.h
+2021/12/27 | 74 | graphics/asymptote/LspCpp/LibLsp/lsp/method_type.h
+2021/12/27 | 588 | graphics/asymptote/LspCpp/LibLsp/lsp/out_list.h
+2021/12/27 | 2880 | graphics/asymptote/LspCpp/LibLsp/lsp/ParentProcessWatcher.cpp
+2021/12/27 | 348 | graphics/asymptote/LspCpp/LibLsp/lsp/ParentProcessWatcher.h
+2021/12/27 | 842 | graphics/asymptote/LspCpp/LibLsp/lsp/ProcessIoService.h
+2021/12/27 | 23205 | graphics/asymptote/LspCpp/LibLsp/lsp/ProtocolJsonHandler.cpp
+2021/12/27 | 176 | graphics/asymptote/LspCpp/LibLsp/lsp/ProtocolJsonHandler.h
+2021/12/27 | 2675 | graphics/asymptote/LspCpp/LibLsp/lsp/ResourceOperation.h
+2021/12/27 | 1185 | graphics/asymptote/LspCpp/LibLsp/lsp/SimpleTimer.h
+2021/12/27 | 4265 | graphics/asymptote/LspCpp/LibLsp/lsp/symbol.h
+2021/12/27 | 3731 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/callHierarchy.h
+2021/12/27 | 2668 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/code_action.h
+2021/12/27 | 1129 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/code_lens.h
+2021/12/27 | 1615 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/colorPresentation.h
+2021/12/27 | 2524 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/completion.h
+2021/12/27 | 934 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/declaration_definition.h
+2021/12/27 | 1493 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_change.h
+2021/12/27 | 768 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_close.h
+2021/12/27 | 937 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_open.h
+2021/12/27 | 1056 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/didRenameFiles.h
+2021/12/27 | 808 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_save.h
+2021/12/27 | 1831 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/documentColor.h
+2021/12/27 | 1244 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/document_link.h
+2021/12/27 | 1814 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/document_symbol.h
+2021/12/27 | 1665 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/foldingRange.h
+2021/12/27 | 792 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/formatting.h
+2021/12/27 | 566 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/highlight.h
+2021/12/27 | 1617 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/hover.h
+2021/12/27 | 488 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/implementation.h
+2021/12/27 | 1267 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/linkedEditingRange.h
+2021/12/27 | 1054 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/onTypeFormatting.h
+2021/12/27 | 1033 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/prepareRename.h
+2021/12/27 | 751 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/publishDiagnostics.h
+2021/12/27 | 872 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/range_formatting.h
+2021/12/27 | 1195 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/references.h
+2021/12/27 | 1098 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/rename.h
+2021/12/27 | 223 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveCodeLens.h
+2021/12/27 | 489 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveCompletionItem.h
+2021/12/27 | 789 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveTypeHierarchy.h
+2021/12/27 | 1440 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/selectionRange.h
+2021/12/27 | 2632 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/semanticHighlighting.h
+2021/12/27 | 9945 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/SemanticTokens.h
+2021/12/27 | 3391 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/signature_help.h
+2021/12/27 | 11111 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/textDocument.cpp
+2021/12/27 | 490 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/type_definition.h
+2021/12/27 | 4199 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/typeHierarchy.h
+2021/12/27 | 1924 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/willSave.h
+2021/12/27 | 15516 | graphics/asymptote/LspCpp/LibLsp/lsp/utils.cpp
+2021/12/27 | 4899 | graphics/asymptote/LspCpp/LibLsp/lsp/utils.h
+2021/12/27 | 2257 | graphics/asymptote/LspCpp/LibLsp/lsp/windows/MessageNotify.h
+2021/12/27 | 5328 | graphics/asymptote/LspCpp/LibLsp/lsp/working_files.cpp
+2021/12/27 | 2149 | graphics/asymptote/LspCpp/LibLsp/lsp/working_files.h
+2021/12/27 | 1077 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/applyEdit.h
+2021/12/27 | 1161 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/configuration.h
+2021/12/27 | 580 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/did_change_configuration.h
+2021/12/27 | 1352 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/did_change_watched_files.h
+2021/12/27 | 1321 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/didChangeWorkspaceFolders.h
+2021/12/27 | 794 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/execute_command.h
+2021/12/27 | 428 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/symbol.h
+2021/12/27 | 953 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/workspaceFolders.h
+2021/12/27 | 1066 | graphics/asymptote/LspCpp/LICENSE
+2021/12/27 | 17860 | graphics/asymptote/LspCpp/LspCpp.filters
+2021/12/27 | 165 | graphics/asymptote/LspCpp/LspCpp.user
+2021/12/27 | 39804 | graphics/asymptote/LspCpp/LspCpp.vcxproj
+2021/12/27 | 25452 | graphics/asymptote/LspCpp/LspCpp.vcxproj.filters
+2021/12/27 | 165 | graphics/asymptote/LspCpp/LspCpp.vcxproj.user
+2021/12/27 | 30640 | graphics/asymptote/LspCpp/macro_map.h
+2021/12/27 | 1386 | graphics/asymptote/LspCpp/Makefile
+2021/12/27 | 16421 | graphics/asymptote/LspCpp/network/optional.hpp
+2021/12/27 | 7737 | graphics/asymptote/LspCpp/network/string_view.hpp
+2021/12/27 | 568 | graphics/asymptote/LspCpp/network/uri/config.hpp
+2021/12/27 | 2098 | graphics/asymptote/LspCpp/network/uri/detail/algorithm.hpp
+2021/12/27 | 1898 | graphics/asymptote/LspCpp/network/uri/detail/decode.hpp
+2021/12/27 | 4395 | graphics/asymptote/LspCpp/network/uri/detail/encode.hpp
+2021/12/27 | 3072 | graphics/asymptote/LspCpp/network/uri/detail/grammar.hpp
+2021/12/27 | 2151 | graphics/asymptote/LspCpp/network/uri/detail/translate.hpp
+2021/12/27 | 2176 | graphics/asymptote/LspCpp/network/uri/detail/uri_advance_parts.cpp
+2021/12/27 | 658 | graphics/asymptote/LspCpp/network/uri/detail/uri_advance_parts.hpp
+2021/12/27 | 2259 | graphics/asymptote/LspCpp/network/uri/detail/uri_normalize.cpp
+2021/12/27 | 594 | graphics/asymptote/LspCpp/network/uri/detail/uri_normalize.hpp
+2021/12/27 | 3052 | graphics/asymptote/LspCpp/network/uri/detail/uri_parse_authority.cpp
+2021/12/27 | 730 | graphics/asymptote/LspCpp/network/uri/detail/uri_parse_authority.hpp
+2021/12/27 | 10607 | graphics/asymptote/LspCpp/network/uri/detail/uri_parse.cpp
+2021/12/27 | 552 | graphics/asymptote/LspCpp/network/uri/detail/uri_parse.hpp
+2021/12/27 | 2073 | graphics/asymptote/LspCpp/network/uri/detail/uri_parts.hpp
+2021/12/27 | 1787 | graphics/asymptote/LspCpp/network/uri/detail/uri_percent_encode.hpp
+2021/12/27 | 2827 | graphics/asymptote/LspCpp/network/uri/detail/uri_resolve.cpp
+2021/12/27 | 714 | graphics/asymptote/LspCpp/network/uri/detail/uri_resolve.hpp
+2021/12/27 | 1030 | graphics/asymptote/LspCpp/network/uri.hpp
+2021/12/27 | 4083 | graphics/asymptote/LspCpp/network/uri/uri_builder.cpp
+2021/12/27 | 6917 | graphics/asymptote/LspCpp/network/uri/uri_builder.hpp
+2021/12/27 | 18396 | graphics/asymptote/LspCpp/network/uri/uri.cpp
+2021/12/27 | 2002 | graphics/asymptote/LspCpp/network/uri/uri_errors.cpp
+2021/12/27 | 2609 | graphics/asymptote/LspCpp/network/uri/uri_errors.hpp
+2021/12/27 | 21807 | graphics/asymptote/LspCpp/network/uri/uri.hpp
+2021/12/27 | 1710 | graphics/asymptote/LspCpp/network/uri/uri_io.hpp
+2021/12/27 | 968 | graphics/asymptote/LspCpp/packages.config
+2021/12/27 | 1172 | graphics/asymptote/LspCpp/README.md
+2021/12/27 | 4465 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/future.hpp
+2021/12/27 | 2088 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/locking_ptr.hpp
+2021/12/27 | 13824 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/pool_core.hpp
+2021/12/27 | 1006 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/scope_guard.hpp
+2021/12/27 | 2817 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/worker_thread.hpp
+2021/12/27 | 2649 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/future.hpp
+2021/12/27 | 663 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool.hpp
+2021/12/27 | 2000 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/pool_adaptors.hpp
+2021/12/27 | 7632 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/pool.hpp
+2021/12/27 | 6550 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/scheduling_policies.hpp
+2021/12/27 | 1957 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/shutdown_policies.hpp
+2021/12/27 | 2396 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/size_policies.hpp
+2021/12/27 | 4345 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/task_adaptors.hpp
+2021/12/27 | 3723 | graphics/asymptote/LspCpp/third_party/threadpool/CHANGE_LOG
+2021/12/27 | 221 | graphics/asymptote/LspCpp/third_party/threadpool/COPYING
+2021/12/27 | 319 | graphics/asymptote/LspCpp/third_party/threadpool/Jamfile.v2
+2021/12/27 | 32 | graphics/asymptote/LspCpp/third_party/threadpool/Jamrules
+2021/12/27 | 5196 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design.dox
+2021/12/27 | 1134 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design_header.htm
+2021/12/27 | 1322 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design.txt
+2021/12/27 | 5202 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples.dox
+2021/12/27 | 1122 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples_header.htm
+2021/12/27 | 113 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples.txt
+2021/12/27 | 643 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer/common_footer.htm
+2021/12/27 | 625 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer/overview_footer.htm
+2021/12/27 | 994 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer_sf/common_footer.htm
+2021/12/27 | 967 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer_sf/overview_footer.htm
+2021/12/27 | 184 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/index.html
+2021/12/27 | 801 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/Makefile
+2021/12/27 | 5221 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview.dox
+2021/12/27 | 1188 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview_header.htm
+2021/12/27 | 8296 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview.txt
+2021/12/27 | 8411 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/reference.dox
+2021/12/27 | 1283 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/reference_header.htm
+2021/12/27 | 7619 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/threadpool.css
+2021/12/27 | 5203 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial.dox
+2021/12/27 | 1332 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial_header.htm
+2021/12/27 | 6350 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial.txt
+2021/12/27 | 195 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/example/mergesort/Jamfile.v2
+2021/12/27 | 4465 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/example/mergesort/mergesort.cpp
+2021/12/27 | 194 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/Jamfile.v2
+2021/12/27 | 986 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/quickstart.cpp
+2021/12/27 | 321 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/README
+2021/12/27 | 2315 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/test/compile_all/compile_all.cpp
+2021/12/27 | 199 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/test/compile_all/Jamfile.v2
+2021/12/27 | 190 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/tutorial/Jamfile.v2
+2021/12/27 | 5265 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/tutorial/tutorial.cpp
+2021/12/27 | 1338 | graphics/asymptote/LspCpp/third_party/threadpool/LICENSE_1_0.txt
+2021/12/27 | 1125 | graphics/asymptote/LspCpp/third_party/threadpool/Makefile
+2021/12/27 | 67 | graphics/asymptote/LspCpp/third_party/threadpool/project-root.jam
+2021/12/27 | 279 | graphics/asymptote/LspCpp/third_party/threadpool/README
+2021/12/27 | 1088 | graphics/asymptote/LspCpp/third_party/threadpool/TODO
+2021/12/27 | 1291 | graphics/asymptote/LspCpp/third_party/utfcpp/CMakeLists.txt
+2021/12/27 | 1338 | graphics/asymptote/LspCpp/third_party/utfcpp/LICENSE
+2021/12/27 | 55726 | graphics/asymptote/LspCpp/third_party/utfcpp/README.md
+2021/12/27 | 2123 | graphics/asymptote/LspCpp/third_party/utfcpp/samples/docsample.cpp
+2021/12/27 | 12474 | graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/checked.h
+2021/12/27 | 10928 | graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/core.h
+2021/12/27 | 3306 | graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/cpp11.h
+2021/12/27 | 3298 | graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/cpp17.h
+2021/12/27 | 1521 | graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8.h
+2021/12/27 | 10989 | graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/unchecked.h
+2021/12/27 | 1734 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/CMakeLists.txt
+2021/12/27 | 125 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/docker/Dockerfile
+2021/12/27 | 2143 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/negative.cpp
+2021/12/27 | 5578 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_checked_api.cpp
+2021/12/27 | 1032 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_checked_iterator.cpp
+2021/12/27 | 3036 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_cpp11.cpp
+2021/12/27 | 2611 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_cpp17.cpp
+2021/12/27 | 20010 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_data/utf8_invalid.txt
+2021/12/27 | 4626 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_unchecked_api.cpp
+2021/12/27 | 1002 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_unchecked_iterator.cpp
+2021/12/27 | 21481 | graphics/asymptote/lspserv.cc
+2021/12/27 | 6528 | graphics/asymptote/lspserv.h
+2021/12/27 | 6402 | graphics/asymptote/main.cc
+2021/12/27 | 12632 | graphics/asymptote/Makefile.in
+2021/12/27 | 920 | graphics/asymptote/makeUnique.h
+2021/12/27 | 2968 | graphics/asymptote/material.h
+2021/12/27 | 6414 | graphics/asymptote/mathop.h
+2021/12/27 | 5095 | graphics/asymptote/memory.h
+2021/12/27 | 714 | graphics/asymptote/mod.h
+2021/12/27 | 908 | graphics/asymptote/modifier.h
+2021/12/27 | 8037 | graphics/asymptote/name.cc
+2021/12/27 | 5691 | graphics/asymptote/name.h
+2021/12/27 | 4285 | graphics/asymptote/newexp.cc
+2021/12/27 | 1274 | graphics/asymptote/newexp.h
+2021/12/27 | 916 | graphics/asymptote/opcodes.h
+2021/12/27 | 1050 | graphics/asymptote/opsymbols.pl
+2021/12/27 | 5278 | graphics/asymptote/pair.h
+2021/12/27 | 4873 | graphics/asymptote/parser.cc
+2021/12/27 | 1171 | graphics/asymptote/parser.h
+2021/12/27 | 5262 | graphics/asymptote/patches/bison.patch
+2021/12/27 | 1805 | graphics/asymptote/patches/cygwin_freeglut-3.0.0.patch
+2021/12/27 | 1311 | graphics/asymptote/patches/dvipdf
+2021/12/27 | 113 | graphics/asymptote/patches/fixmem.reg
+2021/12/27 | 1524 | graphics/asymptote/patches/flex.patch
+2021/12/27 | 271 | graphics/asymptote/patches/gc6.8_AIX.patch
+2021/12/27 | 489 | graphics/asymptote/patches/gc-7.0nomem.patch
+2021/12/27 | 318 | graphics/asymptote/patches/gcc3.3.2curses.patch
+2021/12/27 | 19462 | graphics/asymptote/patches/gl-matrix-2.4.0-pruned.patch
+2021/12/27 | 1082 | graphics/asymptote/patches/README
+2021/12/27 | 37991 | graphics/asymptote/path3.cc
+2021/12/27 | 10585 | graphics/asymptote/path3.h
+2021/12/27 | 33813 | graphics/asymptote/path.cc
+2021/12/27 | 11663 | graphics/asymptote/path.h
+2021/12/27 | 1594 | graphics/asymptote/pen.cc
+2021/12/27 | 27856 | graphics/asymptote/pen.h
+2021/12/27 | 42110 | graphics/asymptote/picture.cc
+2021/12/27 | 3472 | graphics/asymptote/picture.h
+2021/12/27 | 5250 | graphics/asymptote/pipestream.cc
+2021/12/27 | 2614 | graphics/asymptote/pipestream.h
+2021/12/27 | 138 | graphics/asymptote/Pipfile
+2021/12/27 | 2542 | graphics/asymptote/policy.h
+2021/12/27 | 650 | graphics/asymptote/prcfile.h
+2021/12/27 | 974 | graphics/asymptote/prc/Makefile
+2021/12/27 | 71201 | graphics/asymptote/prc/oPRCFile.cc
+2021/12/27 | 51640 | graphics/asymptote/prc/oPRCFile.h
+2021/12/27 | 8371 | graphics/asymptote/prc/PRCbitStream.cc
+2021/12/27 | 2518 | graphics/asymptote/prc/PRCbitStream.h
+2021/12/27 | 177246 | graphics/asymptote/prc/PRCdouble.cc
+2021/12/27 | 3765 | graphics/asymptote/prc/PRCdouble.h
+2021/12/27 | 30208 | graphics/asymptote/prc/PRC.h
+2021/12/27 | 6021 | graphics/asymptote/prc/PRCTools/bitData.cc
+2021/12/27 | 1860 | graphics/asymptote/prc/PRCTools/bitData.h
+2021/12/27 | 1927 | graphics/asymptote/prc/PRCTools/bitSearchDouble.cc
+2021/12/27 | 1863 | graphics/asymptote/prc/PRCTools/bitSearchUI.cc
+2021/12/27 | 1245 | graphics/asymptote/prc/PRCTools/describeMain.cc
+2021/12/27 | 68126 | graphics/asymptote/prc/PRCTools/describePRC.cc
+2021/12/27 | 4335 | graphics/asymptote/prc/PRCTools/describePRC.h
+2021/12/27 | 1310 | graphics/asymptote/prc/PRCTools/extractSections.cc
+2021/12/27 | 2276 | graphics/asymptote/prc/PRCTools/inflation.cc
+2021/12/27 | 1051 | graphics/asymptote/prc/PRCTools/inflation.h
+2021/12/27 | 1479 | graphics/asymptote/prc/PRCTools/inflationMain.cc
+2021/12/27 | 8792 | graphics/asymptote/prc/PRCTools/iPRCFile.cc
+2021/12/27 | 2341 | graphics/asymptote/prc/PRCTools/iPRCFile.h
+2021/12/27 | 1658 | graphics/asymptote/prc/PRCTools/Makefile
+2021/12/27 | 4716 | graphics/asymptote/prc/PRCTools/makePRC.cc
+2021/12/27 | 95 | graphics/asymptote/prc/test.asy
+2021/12/27 | 36243 | graphics/asymptote/prc/test.cc
+2021/12/27 | 66751 | graphics/asymptote/prc/writePRC.cc
+2021/12/27 | 48481 | graphics/asymptote/prc/writePRC.h
+2021/12/27 | 116010 | graphics/asymptote/predicates.cc
+2021/12/27 | 986 | graphics/asymptote/predicates.h
+2021/12/27 | 1236 | graphics/asymptote/primitives.h
+2021/12/27 | 23904 | graphics/asymptote/process.cc
+2021/12/27 | 4919 | graphics/asymptote/process.h
+2021/12/27 | 2378 | graphics/asymptote/profile.py
+2021/12/27 | 9923 | graphics/asymptote/profiler.h
+2021/12/27 | 3265 | graphics/asymptote/program.cc
+2021/12/27 | 2561 | graphics/asymptote/program.h
+2021/12/27 | 19107 | graphics/asymptote/psfile.cc
+2021/12/27 | 9015 | graphics/asymptote/psfile.h
+2021/12/27 | 2505 | graphics/asymptote/README
+2021/12/27 | 1698 | graphics/asymptote/record.cc
+2021/12/27 | 2732 | graphics/asymptote/record.h
+2021/12/27 | 1096 | graphics/asymptote/refaccess.cc
+2021/12/27 | 1936 | graphics/asymptote/refaccess.h
+2021/12/27 | 126385 | graphics/asymptote/ReleaseNotes
+2021/12/27 | 62 | graphics/asymptote/revision.cc
+2021/12/27 | 3441 | graphics/asymptote/rounding.h
+2021/12/27 | 73254 | graphics/asymptote/runarray.cc
+2021/12/27 | 1492 | graphics/asymptote/runarray.h
+2021/12/27 | 48417 | graphics/asymptote/runarray.in
+2021/12/27 | 2661 | graphics/asymptote/runbacktrace.cc
+2021/12/27 | 169 | graphics/asymptote/runbacktrace.h
+2021/12/27 | 831 | graphics/asymptote/runbacktrace.in
+2021/12/27 | 17798 | graphics/asymptote/runfile.cc
+2021/12/27 | 969 | graphics/asymptote/runfile.h
+2021/12/27 | 5987 | graphics/asymptote/runfile.in
+2021/12/27 | 8096 | graphics/asymptote/runhistory.cc
+2021/12/27 | 161 | graphics/asymptote/runhistory.h
+2021/12/27 | 5064 | graphics/asymptote/runhistory.in
+2021/12/27 | 15833 | graphics/asymptote/runlabel.cc
+2021/12/27 | 153 | graphics/asymptote/runlabel.h
+2021/12/27 | 12093 | graphics/asymptote/runlabel.in
+2021/12/27 | 21926 | graphics/asymptote/runmath.cc
+2021/12/27 | 269 | graphics/asymptote/runmath.h
+2021/12/27 | 8856 | graphics/asymptote/runmath.in
+2021/12/27 | 16483 | graphics/asymptote/runpair.cc
+2021/12/27 | 299 | graphics/asymptote/runpair.h
+2021/12/27 | 4156 | graphics/asymptote/runpair.in
+2021/12/27 | 25701 | graphics/asymptote/runpath3d.cc
+2021/12/27 | 186 | graphics/asymptote/runpath3d.h
+2021/12/27 | 8008 | graphics/asymptote/runpath3d.in
+2021/12/27 | 26844 | graphics/asymptote/runpath.cc
+2021/12/27 | 177 | graphics/asymptote/runpath.h
+2021/12/27 | 8439 | graphics/asymptote/runpath.in
+2021/12/27 | 57944 | graphics/asymptote/runpicture.cc
+2021/12/27 | 191 | graphics/asymptote/runpicture.h
+2021/12/27 | 20090 | graphics/asymptote/runpicture.in
+2021/12/27 | 18739 | graphics/asymptote/runstring.cc
+2021/12/27 | 188 | graphics/asymptote/runstring.h
+2021/12/27 | 9867 | graphics/asymptote/runstring.in
+2021/12/27 | 12604 | graphics/asymptote/runsystem.cc
+2021/12/27 | 157 | graphics/asymptote/runsystem.h
+2021/12/27 | 5111 | graphics/asymptote/runsystem.in
+2021/12/27 | 1341 | graphics/asymptote/runtimebase.in
+2021/12/27 | 60939 | graphics/asymptote/runtime.cc
+2021/12/27 | 1163 | graphics/asymptote/runtime.h
+2021/12/27 | 20633 | graphics/asymptote/runtime.in
+2021/12/27 | 7274 | graphics/asymptote/runtime.pl
+2021/12/27 | 13944 | graphics/asymptote/runtriple.cc
+2021/12/27 | 320 | graphics/asymptote/runtriple.h
+2021/12/27 | 2707 | graphics/asymptote/runtriple.in
+2021/12/27 | 2136 | graphics/asymptote/seconds.h
+2021/12/27 | 53997 | graphics/asymptote/settings.cc
+2021/12/27 | 2707 | graphics/asymptote/settings.h
+2021/12/27 | 3160 | graphics/asymptote/shaders.cc
+2021/12/27 | 902 | graphics/asymptote/shaders.h
+2021/12/27 | 6634 | graphics/asymptote/simpson.cc
+2021/12/27 | 14532 | graphics/asymptote/stack.cc
+2021/12/27 | 3295 | graphics/asymptote/stack.h
+2021/12/27 | 942 | graphics/asymptote/statistics.h
+2021/12/27 | 14795 | graphics/asymptote/stm.cc
+2021/12/27 | 5183 | graphics/asymptote/stm.h
+2021/12/27 | 9104 | graphics/asymptote/symbol.cc
+2021/12/27 | 2749 | graphics/asymptote/symbol.h
+2021/12/27 | 24784 | graphics/asymptote/symbolmaps.cc
+2021/12/27 | 28337 | graphics/asymptote/symbolmaps.h
+2021/12/27 | 2697 | graphics/asymptote/table.h
+2021/12/27 | 620 | graphics/asymptote/tests/arith/integer.asy
+2021/12/27 | 449 | graphics/asymptote/tests/arith/pair.asy
+2021/12/27 | 193 | graphics/asymptote/tests/arith/random.asy
+2021/12/27 | 383 | graphics/asymptote/tests/arith/real.asy
+2021/12/27 | 1710 | graphics/asymptote/tests/arith/roots.asy
+2021/12/27 | 639 | graphics/asymptote/tests/arith/transform.asy
+2021/12/27 | 244 | graphics/asymptote/tests/arith/triple.asy
+2021/12/27 | 936 | graphics/asymptote/tests/array/array.asy
+2021/12/27 | 680 | graphics/asymptote/tests/array/delete.asy
+2021/12/27 | 737 | graphics/asymptote/tests/array/determinant.asy
+2021/12/27 | 1927 | graphics/asymptote/tests/array/fields.asy
+2021/12/27 | 4841 | graphics/asymptote/tests/array/slice.asy
+2021/12/27 | 966 | graphics/asymptote/tests/array/solve.asy
+2021/12/27 | 746 | graphics/asymptote/tests/array/sort.asy
+2021/12/27 | 1096 | graphics/asymptote/tests/array/transpose.asy
+2021/12/27 | 276 | graphics/asymptote/tests/bench/6000circles.asy
+2021/12/27 | 2222 | graphics/asymptote/tests/frames/loop.asy
+2021/12/27 | 202 | graphics/asymptote/tests/frames/stat2.asy
+2021/12/27 | 158 | graphics/asymptote/tests/frames/stat.asy
+2021/12/27 | 62 | graphics/asymptote/tests/gc/array.asy
+2021/12/27 | 102 | graphics/asymptote/tests/gc/file.asy
+2021/12/27 | 54 | graphics/asymptote/tests/gc/funcall.asy
+2021/12/27 | 65 | graphics/asymptote/tests/gc/guide.asy
+2021/12/27 | 143 | graphics/asymptote/tests/gc/label.asy
+2021/12/27 | 124 | graphics/asymptote/tests/gc/path.asy
+2021/12/27 | 72 | graphics/asymptote/tests/gc/pen.asy
+2021/12/27 | 193 | graphics/asymptote/tests/gc/shipout.asy
+2021/12/27 | 77 | graphics/asymptote/tests/gc/string.asy
+2021/12/27 | 129 | graphics/asymptote/tests/gc/struct.asy
+2021/12/27 | 70 | graphics/asymptote/tests/gc/transform.asy
+2021/12/27 | 369 | graphics/asymptote/tests/gs/ghostscript.asy
+2021/12/27 | 11907 | graphics/asymptote/tests/gsl/random.asy
+2021/12/27 | 1209 | graphics/asymptote/tests/imp/unravel.asy
+2021/12/27 | 308 | graphics/asymptote/tests/Makefile
+2021/12/27 | 18 | graphics/asymptote/tests/output/circle.asy
+2021/12/27 | 22 | graphics/asymptote/tests/output/line.asy
+2021/12/27 | 1284 | graphics/asymptote/tests/output/Makefile
+2021/12/27 | 1384 | graphics/asymptote/tests/pic/trans.asy
+2021/12/27 | 236 | graphics/asymptote/tests/string/erase.asy
+2021/12/27 | 182 | graphics/asymptote/tests/string/find.asy
+2021/12/27 | 109 | graphics/asymptote/tests/string/insert.asy
+2021/12/27 | 132 | graphics/asymptote/tests/string/length.asy
+2021/12/27 | 187 | graphics/asymptote/tests/string/rfind.asy
+2021/12/27 | 118 | graphics/asymptote/tests/string/substr.asy
+2021/12/27 | 238 | graphics/asymptote/tests/TestLib.asy
+2021/12/27 | 159 | graphics/asymptote/tests/types/cast.asy
+2021/12/27 | 6503 | graphics/asymptote/tests/types/constructor.asy
+2021/12/27 | 155 | graphics/asymptote/tests/types/ecast.asy
+2021/12/27 | 3375 | graphics/asymptote/tests/types/guide.asy
+2021/12/27 | 224 | graphics/asymptote/tests/types/init.asy
+2021/12/27 | 4242 | graphics/asymptote/tests/types/keyword.asy
+2021/12/27 | 4072 | graphics/asymptote/tests/types/order.asy
+2021/12/27 | 2731 | graphics/asymptote/tests/types/resolve.asy
+2021/12/27 | 308 | graphics/asymptote/tests/types/shadow.asy
+2021/12/27 | 1331 | graphics/asymptote/tests/types/spec.asy
+2021/12/27 | 1189 | graphics/asymptote/tests/types/var.asy
+2021/12/27 | 14283 | graphics/asymptote/testv3d.asy
+2021/12/27 | 18659 | graphics/asymptote/texfile.cc
+2021/12/27 | 13513 | graphics/asymptote/texfile.h
+2021/12/27 | 351 | graphics/asymptote/tinyexr.cc
+2021/12/27 | 1293 | graphics/asymptote/TODO
+2021/12/27 | 6288 | graphics/asymptote/transform.h
+2021/12/27 | 10224 | graphics/asymptote/tr.cc
+2021/12/27 | 3912 | graphics/asymptote/tr.h
+2021/12/27 | 9754 | graphics/asymptote/triple.h
+2021/12/27 | 14072 | graphics/asymptote/types.cc
+2021/12/27 | 15451 | graphics/asymptote/types.h
+2021/12/27 | 10093 | graphics/asymptote/util.cc
+2021/12/27 | 4602 | graphics/asymptote/util.h
+2021/12/27 | 10039 | graphics/asymptote/v3dfile.cc
+2021/12/27 | 4818 | graphics/asymptote/v3dfile.h
+2021/12/27 | 1061 | graphics/asymptote/v3dheadertypes.csv
+2021/12/27 | 1225 | graphics/asymptote/v3dheadertypes.h
+2021/12/27 | 1597 | graphics/asymptote/v3dheadertypes.py
+2021/12/27 | 422 | graphics/asymptote/v3dtypes.csv
+2021/12/27 | 548 | graphics/asymptote/v3dtypes.h
+2021/12/27 | 821 | graphics/asymptote/v3dtypes.py
+2021/12/27 | 2004 | graphics/asymptote/varinit.cc
+2021/12/27 | 2012 | graphics/asymptote/varinit.h
+2021/12/27 | 901 | graphics/asymptote/virtualfieldaccess.cc
+2021/12/27 | 2328 | graphics/asymptote/virtualfieldaccess.h
+2021/12/27 | 766 | graphics/asymptote/vm.h
+2021/12/27 | 222 | graphics/asymptote/wce
+2021/12/27 | 4531 | graphics/asymptote/webgl/fragment.glsl
+2021/12/27 | 89290 | graphics/asymptote/webgl/gl.js
+2021/12/27 | 820 | graphics/asymptote/webgl/license
+2021/12/27 | 1728 | graphics/asymptote/webgl/vertex.glsl
+2021/12/27 | 8567 | graphics/asymptote/xstream.h
+2021/12/27 | 23682714 | graphics/asymptote.zip
2014/04/16 | 55108 | graphics/asypictureb/asypictureB.dtx
2014/04/16 | 2401 | graphics/asypictureb/asypictureB.ins
2014/04/15 | 637107 | graphics/asypictureb/asypictureB.pdf
@@ -180500,6 +181001,19 @@
2019/01/28 | 1187 | info/joy-of-tex/README
2019/01/29 | 3973964 | info/joy-of-tex.zip
1995/01/19 | 36098 | info/jrtex12a
+2021/12/27 | 875011 | info/kaytannollista-latexia/kaytannollista-latexia.pdf
+2021/12/27 | 15460 | info/kaytannollista-latexia/kaytannollista-latexia.tex
+2021/12/27 | 2622 | info/kaytannollista-latexia/kirjallisuutta.bib
+2021/12/27 | 123910 | info/kaytannollista-latexia/luku-asetukset.tex
+2021/12/27 | 20779 | info/kaytannollista-latexia/luku-erikoiset.tex
+2021/12/27 | 2643 | info/kaytannollista-latexia/luku-esipuhe.tex
+2021/12/27 | 85944 | info/kaytannollista-latexia/luku-merkintakieli.tex
+2021/12/27 | 316381 | info/kaytannollista-latexia/luku-rakenne.tex
+2021/12/27 | 20634 | info/kaytannollista-latexia/luku-valmistautuminen.tex
+2021/12/27 | 6131 | info/kaytannollista-latexia/README.md
+2021/12/27 | 11987 | info/kaytannollista-latexia/tavutusvihjeet.tex
+2021/12/27 | 30 | info/kaytannollista-latexia/versio.tex
+2021/12/27 | 1021951 | info/kaytannollista-latexia.zip
2017/08/18 | 333896 | info/knuth/cwebman.pdf
2021/03/17 | 623768 | info/knuth-pdf/bibtex/bibtex-changes.pdf
2021/03/17 | 1329399 | info/knuth-pdf/bibtex/bibtex.pdf
@@ -181562,6 +182076,11 @@
2009/08/12 | 2366 | info/maketexwork/README
2002/09/17 | 814500 | info/makingtexwork/mtw-1.0.1-html.tar.gz
1993/03/25 | 146224 | info/maltby-intro.tex
+2021/12/27 | 282632 | info/mathalphabets/mathalphabets.pdf
+2021/12/27 | 1074 | info/mathalphabets/README.md
+2021/12/25 | 5965 | info/mathalphabets/src/maref.bib
+2021/12/27 | 49140 | info/mathalphabets/src/mathalphabets.tex
+2021/12/27 | 294288 | info/mathalphabets.zip
2008/08/19 | 112 | info/Math_into_LaTeX-4/gratzer
2008/09/14 | 119332488 | info/Math_into_LaTeX-4/mil4-video-presentations.zip
2008/08/28 | 1436 | info/Math_into_LaTeX-4/README
@@ -205845,17 +206364,17 @@
2015/06/01 | 12155 | macros/latex/contrib/cntperchap/cntperchap.sty
2015/06/01 | 1440 | macros/latex/contrib/cntperchap/README
2015/06/01 | 274186 | macros/latex/contrib/cntperchap.zip
-2021/12/26 | 289 | macros/latex/contrib/codebox/build.sh
-2021/12/26 | 69553 | macros/latex/contrib/codebox/codebox-doc-en.pdf
+2021/12/27 | 289 | macros/latex/contrib/codebox/build.sh
+2021/12/27 | 69443 | macros/latex/contrib/codebox/codebox-doc-en.pdf
2021/12/26 | 11317 | macros/latex/contrib/codebox/codebox-doc-en.tex
-2021/12/26 | 35256 | macros/latex/contrib/codebox/codebox.dtx
-2021/12/26 | 280271 | macros/latex/contrib/codebox/codebox.pdf
+2021/12/27 | 34571 | macros/latex/contrib/codebox/codebox.dtx
+2021/12/27 | 281819 | macros/latex/contrib/codebox/codebox.pdf
2021/12/24 | 29262 | macros/latex/contrib/codebox/ctxdoc-en.cls
2021/12/26 | 122 | macros/latex/contrib/codebox/hellojava.java
2021/12/26 | 888 | macros/latex/contrib/codebox/hellopy.py
-2021/12/26 | 3274 | macros/latex/contrib/codebox/README.md
+2021/12/27 | 3274 | macros/latex/contrib/codebox/README.md
2021/12/26 | 104 | macros/latex/contrib/codebox/test.c
-2021/12/26 | 365836 | macros/latex/contrib/codebox.zip
+2021/12/27 | 367149 | macros/latex/contrib/codebox.zip
2010/03/30 | 46009 | macros/latex/contrib/codedoc/codedoc.cls
2010/03/30 | 598708 | macros/latex/contrib/codedoc/CodeDoc-manual.pdf
2010/03/30 | 156353 | macros/latex/contrib/codedoc/CodeDoc-manual.tex
@@ -207258,12 +207777,12 @@
2010/02/23 | 37530 | macros/latex/contrib/dichokey/rhodocyb.pdf
1999/12/19 | 2877 | macros/latex/contrib/dichokey/rhodocyb.tex
2010/02/23 | 212504 | macros/latex/contrib/dichokey.zip
-2019/01/01 | 2479 | macros/latex/contrib/diffcoeff/diffcoeff-doc.def
-2019/12/28 | 672100 | macros/latex/contrib/diffcoeff/diffcoeff.pdf
-2019/12/28 | 24176 | macros/latex/contrib/diffcoeff/diffcoeff.sty
-2019/12/28 | 87786 | macros/latex/contrib/diffcoeff/diffcoeff.tex
-2019/12/28 | 1093 | macros/latex/contrib/diffcoeff/README.txt
-2019/12/27 | 633563 | macros/latex/contrib/diffcoeff.zip
+2021/12/23 | 2383 | macros/latex/contrib/diffcoeff/diffcoeff-doc.def
+2021/12/28 | 731648 | macros/latex/contrib/diffcoeff/diffcoeff.pdf
+2021/12/24 | 26164 | macros/latex/contrib/diffcoeff/diffcoeff.sty
+2021/12/27 | 98802 | macros/latex/contrib/diffcoeff/diffcoeff.tex
+2021/12/28 | 1279 | macros/latex/contrib/diffcoeff/README.txt
+2021/12/27 | 671830 | macros/latex/contrib/diffcoeff.zip
2018/05/23 | 34904 | macros/latex/contrib/digicap-pro/digicap-pro.dtx
2018/05/13 | 1922 | macros/latex/contrib/digicap-pro/digicap-pro.ins
2018/05/21 | 287595 | macros/latex/contrib/digicap-pro/doc/digicap_man.pdf
@@ -232329,6 +232848,10 @@
2018/08/17 | 14778 | macros/latex/contrib/worksheet/worksheet.sty
2018/08/17 | 16462 | macros/latex/contrib/worksheet/worksheet.tex
2018/08/17 | 99332 | macros/latex/contrib/worksheet.zip
+2021/12/25 | 963 | macros/latex/contrib/wrapfig2/README.txt
+2021/12/24 | 55502 | macros/latex/contrib/wrapfig2/wrapfig2.dtx
+2021/12/24 | 511808 | macros/latex/contrib/wrapfig2/wrapfig2.pdf
+2021/12/27 | 516893 | macros/latex/contrib/wrapfig2.zip
2003/02/24 | 5342 | macros/latex/contrib/wrapfig/multiple-span.txt
2011/04/09 | 330855 | macros/latex/contrib/wrapfig/wrapfig-doc.pdf
2011/04/09 | 15201 | macros/latex/contrib/wrapfig/wrapfig-doc.tex
@@ -278061,8 +278584,8 @@
2020/04/15 | 12216 | systems/texlive/tlnet/archive/askinclude.source.r54725.tar.xz
2020/10/23 | 384640 | systems/texlive/tlnet/archive/askmaps.doc.r56730.tar.xz
2020/10/23 | 3312 | systems/texlive/tlnet/archive/askmaps.r56730.tar.xz
-2021/02/22 | 1473344 | systems/texlive/tlnet/archive/asmeconf.doc.r57833.tar.xz
-2021/02/22 | 24956 | systems/texlive/tlnet/archive/asmeconf.r57833.tar.xz
+2021/12/27 | 1453400 | systems/texlive/tlnet/archive/asmeconf.doc.r61412.tar.xz
+2021/12/27 | 27720 | systems/texlive/tlnet/archive/asmeconf.r61412.tar.xz
2021/12/24 | 638748 | systems/texlive/tlnet/archive/asmejour.doc.r61388.tar.xz
2021/12/24 | 21444 | systems/texlive/tlnet/archive/asmejour.r61388.tar.xz
2019/02/28 | 337268 | systems/texlive/tlnet/archive/aspectratio.doc.r25243.tar.xz
@@ -279730,6 +280253,8 @@
2019/07/13 | 257164 | systems/texlive/tlnet/archive/codeanatomy.doc.r51627.tar.xz
2019/07/13 | 1836 | systems/texlive/tlnet/archive/codeanatomy.r51627.tar.xz
2019/07/13 | 4596 | systems/texlive/tlnet/archive/codeanatomy.source.r51627.tar.xz
+2021/12/27 | 361352 | systems/texlive/tlnet/archive/codebox.doc.r61415.tar.xz
+2021/12/27 | 3596 | systems/texlive/tlnet/archive/codebox.r61415.tar.xz
2019/02/28 | 377460 | systems/texlive/tlnet/archive/codedoc.doc.r17630.tar.xz
2019/02/28 | 10108 | systems/texlive/tlnet/archive/codedoc.r17630.tar.xz
2021/05/13 | 84052 | systems/texlive/tlnet/archive/codehigh.doc.r59173.tar.xz
@@ -279780,7 +280305,7 @@
2020/03/04 | 408 | systems/texlive/tlnet/archive/collection-langpolish.r54074.tar.xz
2020/03/04 | 392 | systems/texlive/tlnet/archive/collection-langportuguese.r54074.tar.xz
2020/03/07 | 380 | systems/texlive/tlnet/archive/collection-langspanish.r54141.tar.xz
-2021/12/24 | 6520 | systems/texlive/tlnet/archive/collection-latexextra.r61391.tar.xz
+2021/12/27 | 6524 | systems/texlive/tlnet/archive/collection-latexextra.r61415.tar.xz
2020/12/03 | 696 | systems/texlive/tlnet/archive/collection-latex.r57048.tar.xz
2021/02/24 | 772 | systems/texlive/tlnet/archive/collection-latexrecommended.r57862.tar.xz
2021/10/15 | 780 | systems/texlive/tlnet/archive/collection-luatex.r60764.tar.xz
@@ -281120,9 +281645,9 @@
2021/07/19 | 313228 | systems/texlive/tlnet/archive/easing.doc.r59975.tar.xz
2021/07/19 | 2220 | systems/texlive/tlnet/archive/easing.r59975.tar.xz
2021/07/19 | 7876 | systems/texlive/tlnet/archive/easing.source.r59975.tar.xz
-2021/12/24 | 616096 | systems/texlive/tlnet/archive/easybook.doc.r61390.tar.xz
-2021/12/24 | 17976 | systems/texlive/tlnet/archive/easybook.r61390.tar.xz
-2021/12/24 | 18020 | systems/texlive/tlnet/archive/easybook.source.r61390.tar.xz
+2021/12/27 | 616460 | systems/texlive/tlnet/archive/easybook.doc.r61413.tar.xz
+2021/12/27 | 17960 | systems/texlive/tlnet/archive/easybook.r61413.tar.xz
+2021/12/27 | 18000 | systems/texlive/tlnet/archive/easybook.source.r61413.tar.xz
2019/02/28 | 4540 | systems/texlive/tlnet/archive/easy.doc.r19440.tar.xz
2020/09/08 | 175976 | systems/texlive/tlnet/archive/easyfig.doc.r56291.tar.xz
2020/09/08 | 1936 | systems/texlive/tlnet/archive/easyfig.r56291.tar.xz
@@ -288635,9 +289160,9 @@
2019/02/28 | 473824 | systems/texlive/tlnet/archive/termmenu.doc.r37700.tar.xz
2019/02/28 | 2016 | systems/texlive/tlnet/archive/termmenu.r37700.tar.xz
2019/02/28 | 6808 | systems/texlive/tlnet/archive/termmenu.source.r37700.tar.xz
-2021/12/25 | 378116 | systems/texlive/tlnet/archive/termsim.doc.r61399.tar.xz
-2021/12/25 | 4028 | systems/texlive/tlnet/archive/termsim.r61399.tar.xz
-2021/12/25 | 9788 | systems/texlive/tlnet/archive/termsim.source.r61399.tar.xz
+2021/12/27 | 390080 | systems/texlive/tlnet/archive/termsim.doc.r61414.tar.xz
+2021/12/27 | 3860 | systems/texlive/tlnet/archive/termsim.r61414.tar.xz
+2021/12/27 | 9472 | systems/texlive/tlnet/archive/termsim.source.r61414.tar.xz
2019/02/28 | 383684 | systems/texlive/tlnet/archive/testhyphens.doc.r38928.tar.xz
2019/02/28 | 2044 | systems/texlive/tlnet/archive/testhyphens.r38928.tar.xz
2019/02/28 | 8036 | systems/texlive/tlnet/archive/testhyphens.source.r38928.tar.xz
@@ -288913,7 +289438,7 @@
2020/05/17 | 592 | systems/texlive/tlnet/archive/texlive-scripts.amd64-freebsd.r55172.tar.xz
2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.amd64-netbsd.r55172.tar.xz
2020/05/17 | 592 | systems/texlive/tlnet/archive/texlive-scripts.armhf-linux.r55172.tar.xz
-2021/12/26 | 402264 | systems/texlive/tlnet/archive/texlive-scripts.doc.r61403.tar.xz
+2021/12/27 | 402268 | systems/texlive/tlnet/archive/texlive-scripts.doc.r61410.tar.xz
2020/01/27 | 916 | systems/texlive/tlnet/archive/texlive-scripts-extra.aarch64-linux.r53577.tar.xz
2020/01/27 | 924 | systems/texlive/tlnet/archive/texlive-scripts-extra.amd64-freebsd.r53577.tar.xz
2020/01/27 | 916 | systems/texlive/tlnet/archive/texlive-scripts-extra.amd64-netbsd.r53577.tar.xz
@@ -288937,7 +289462,7 @@
2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.i386-linux.r55172.tar.xz
2020/05/17 | 592 | systems/texlive/tlnet/archive/texlive-scripts.i386-netbsd.r55172.tar.xz
2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.i386-solaris.r55172.tar.xz
-2021/12/26 | 108268 | systems/texlive/tlnet/archive/texlive-scripts.r61403.tar.xz
+2021/12/27 | 108236 | systems/texlive/tlnet/archive/texlive-scripts.r61410.tar.xz
2021/02/25 | 572 | systems/texlive/tlnet/archive/texlive-scripts.universal-darwin.r57908.tar.xz
2021/04/12 | 36308 | systems/texlive/tlnet/archive/texlive-scripts.win32.r58829.tar.xz
2020/05/17 | 588 | systems/texlive/tlnet/archive/texlive-scripts.x86_64-cygwin.r55172.tar.xz
@@ -290708,16 +291233,16 @@
2020/07/18 | 47816 | systems/texlive/tlnet/archive/zztex.doc.r55862.tar.xz
2020/07/18 | 101724 | systems/texlive/tlnet/archive/zztex.r55862.tar.xz
2021/12/06 | 105168 | systems/texlive/tlnet/install-tl
-2021/12/26 | 6811294 | systems/texlive/tlnet/install-tl-unx.tar.gz
-2021/12/26 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
-2021/12/26 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
+2021/12/27 | 6811313 | systems/texlive/tlnet/install-tl-unx.tar.gz
+2021/12/27 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
+2021/12/27 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
2021/04/11 | 4945 | systems/texlive/tlnet/install-tl-windows.bat
-2021/12/26 | 20873611 | systems/texlive/tlnet/install-tl-windows.exe
-2021/12/26 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
-2021/12/26 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
-2021/12/26 | 25631646 | systems/texlive/tlnet/install-tl.zip
-2021/12/26 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
-2021/12/26 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
+2021/12/27 | 20871137 | systems/texlive/tlnet/install-tl-windows.exe
+2021/12/27 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
+2021/12/27 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
+2021/12/27 | 25631622 | systems/texlive/tlnet/install-tl.zip
+2021/12/27 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
+2021/12/27 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
2021/04/01 | 1229 | systems/texlive/tlnet/README.md
2021/04/01 | 0 | systems/texlive/tlnet/TEXLIVE_2021
2021/07/03 | 7181 | systems/texlive/tlnet/tlpkg/gpg/pubring.gpg
@@ -290727,7 +291252,7 @@
2021/07/03 | 1280 | systems/texlive/tlnet/tlpkg/gpg/trustdb.gpg
2021/12/15 | 49408 | systems/texlive/tlnet/tlpkg/installer/config.guess
2010/11/11 | 11651 | systems/texlive/tlnet/tlpkg/installer/COPYING.MinGW-runtime.txt
-2021/12/25 | 6738 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
+2021/12/26 | 6622 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
2020/04/15 | 223687 | systems/texlive/tlnet/tlpkg/installer/curl/curl-ca-bundle.crt
2020/04/15 | 2606592 | systems/texlive/tlnet/tlpkg/installer/curl/curl.exe
2017/04/16 | 2629 | systems/texlive/tlnet/tlpkg/installer/installer-options.txt
@@ -290769,12 +291294,12 @@
2021/05/16 | 20371 | systems/texlive/tlnet/tlpkg/TeXLive/TLCrypto.pm
2021/12/21 | 5429 | systems/texlive/tlnet/tlpkg/TeXLive/TLDownload.pm
2021/12/21 | 27582 | systems/texlive/tlnet/tlpkg/TeXLive/TLPaper.pm
-2021/12/26 | 17059142 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
-2021/12/26 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
+2021/12/27 | 17060982 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
+2021/12/27 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
2021/12/21 | 86654 | systems/texlive/tlnet/tlpkg/TeXLive/TLPDB.pm
-2021/12/26 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
-2021/12/26 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
-2021/12/26 | 2335968 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
+2021/12/27 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
+2021/12/27 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
+2021/12/27 | 2336164 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
2021/12/21 | 58848 | systems/texlive/tlnet/tlpkg/TeXLive/TLPOBJ.pm
2021/12/21 | 42112 | systems/texlive/tlnet/tlpkg/TeXLive/TLPSRC.pm
2021/12/21 | 16130 | systems/texlive/tlnet/tlpkg/TeXLive/TLTREE.pm
@@ -295800,7 +296325,7 @@
2020/10/03 | 318630 | systems/win32/miktex/tm/packages/filehook.tar.lzma
2012/12/04 | 924573 | systems/win32/miktex/tm/packages/fileinfo.tar.lzma
2011/09/21 | 281409 | systems/win32/miktex/tm/packages/filemod.tar.lzma
-2021/12/26 | 630565 | systems/win32/miktex/tm/packages/files.csv.lzma
+2021/12/27 | 630565 | systems/win32/miktex/tm/packages/files.csv.lzma
2001/05/14 | 5617 | systems/win32/miktex/tm/packages/finbib.tar.lzma
2015/10/20 | 44379 | systems/win32/miktex/tm/packages/findhyph.tar.lzma
2011/10/21 | 89323 | systems/win32/miktex/tm/packages/fink.tar.lzma
@@ -297280,9 +297805,9 @@
2018/01/12 | 157226 | systems/win32/miktex/tm/packages/miktex-zip-bin-x64.tar.lzma
2021/12/09 | 39714 | systems/win32/miktex/tm/packages/miktex-zlib-bin-2.9.tar.lzma
2021/12/09 | 43639 | systems/win32/miktex/tm/packages/miktex-zlib-bin-x64-2.9.tar.lzma
-2021/12/26 | 256780 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
-2021/12/26 | 1396326 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
-2021/12/26 | 1293842 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
+2021/12/27 | 256830 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
+2021/12/27 | 1396779 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
+2021/12/27 | 1293701 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
2021/12/09 | 13527 | systems/win32/miktex/tm/packages/miktex-zzip-bin-2.9.tar.lzma
2021/12/09 | 14417 | systems/win32/miktex/tm/packages/miktex-zzip-bin-x64-2.9.tar.lzma
2016/07/15 | 35914 | systems/win32/miktex/tm/packages/mil3.tar.lzma
@@ -297502,193 +298027,193 @@
2018/04/09 | 400132 | systems/win32/miktex/tm/packages/newunicodechar.tar.lzma
2011/09/19 | 101312 | systems/win32/miktex/tm/packages/newvbtm.tar.lzma
2021/03/17 | 232249 | systems/win32/miktex/tm/packages/newverbs.tar.lzma
-2021/12/26 | 630358 | systems/win32/miktex/tm/packages/next/files.csv.lzma
-2021/12/26 | 51588 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma
-2021/12/26 | 57408 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
-2021/12/26 | 959950 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma
-2021/12/26 | 1087070 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
-2021/12/26 | 28896 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma
-2021/12/26 | 31539 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
-2021/12/26 | 30180 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma
-2021/12/26 | 35263 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
-2021/12/26 | 50732 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma
-2021/12/26 | 58370 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
-2021/12/26 | 86768 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma
-2021/12/26 | 95274 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
-2021/12/26 | 68799 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma
-2021/12/26 | 77072 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
-2021/12/26 | 27243 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma
-2021/12/26 | 31333 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
-2021/12/26 | 332374 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma
-2021/12/26 | 394270 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
-2021/12/26 | 32990 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma
-2021/12/26 | 37092 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
-2021/12/26 | 51430 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma
-2021/12/26 | 57278 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
-2021/12/26 | 256200 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma
-2021/12/26 | 281442 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
-2021/12/26 | 179708 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma
-2021/12/26 | 196120 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
-2021/12/26 | 54950 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma
-2021/12/26 | 62420 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
-2021/12/26 | 21371 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma
-2021/12/26 | 24152 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
-2021/12/26 | 461238 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
-2021/12/26 | 46135 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma
-2021/12/26 | 52095 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
-2021/12/26 | 285455 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma
-2021/12/26 | 326387 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
-2021/12/26 | 41326 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma
-2021/12/26 | 45687 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
-2021/12/26 | 120296 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma
-2021/12/26 | 135071 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
-2021/12/26 | 1299135 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma
-2021/12/26 | 1447745 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
-2021/12/26 | 99759 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma
-2021/12/26 | 113044 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
-2021/12/26 | 43637 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma
-2021/12/26 | 48803 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
-2021/12/26 | 25133 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma
-2021/12/26 | 28545 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
-2021/12/26 | 56963 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma
-2021/12/26 | 63313 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
-2021/12/26 | 135932 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma
-2021/12/26 | 155285 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
-2021/12/26 | 73599 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma
-2021/12/26 | 79137 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
-2021/12/26 | 72256 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma
-2021/12/26 | 81707 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
-2021/12/26 | 259274 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma
-2021/12/26 | 295888 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
-2021/12/26 | 22178 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma
-2021/12/26 | 25061 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
-2021/12/26 | 97104 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma
-2021/12/26 | 112482 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
-2021/12/26 | 64567 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma
-2021/12/26 | 73180 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
-2021/12/26 | 96827 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma
-2021/12/26 | 115671 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
-2021/12/26 | 38460 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma
-2021/12/26 | 43809 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
-2021/12/26 | 484479 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma
-2021/12/26 | 566759 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
-2021/12/26 | 152104 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma
-2021/12/26 | 168851 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
-2021/12/26 | 95449 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma
-2021/12/26 | 109545 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
-2021/12/26 | 16521 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma
-2021/12/26 | 18371 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
-2021/12/26 | 28385 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma
-2021/12/26 | 30567 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
-2021/12/26 | 631001 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma
-2021/12/26 | 682341 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
-2021/12/26 | 532337 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma
-2021/12/26 | 599046 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
-2021/12/26 | 477727 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma
-2021/12/26 | 528531 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
-2021/12/26 | 93989 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma
-2021/12/26 | 103462 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
-2021/12/26 | 1732472 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma
-2021/12/26 | 2012704 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
-2021/12/26 | 67994 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma
-2021/12/26 | 74054 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
-2021/12/26 | 27262 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma
-2021/12/26 | 32155 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
-2021/12/26 | 7756 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma
-2021/12/26 | 8790 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
-2021/12/26 | 197376 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma
-2021/12/26 | 215852 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
-2021/12/26 | 251069 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma
-2021/12/26 | 286703 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
-2021/12/26 | 99372 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma
-2021/12/26 | 104747 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
-2021/12/26 | 64516 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma
-2021/12/26 | 74622 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma
-2021/12/26 | 126741 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma
-2021/12/26 | 139309 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
-2021/12/26 | 181559 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma
-2021/12/26 | 202237 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
-2021/12/26 | 199836 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma
-2021/12/26 | 181466 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
-2021/12/26 | 68619 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma
-2021/12/26 | 76231 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
-2021/12/26 | 31411 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma
-2021/12/26 | 35167 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
-2021/12/26 | 38541 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma
-2021/12/26 | 43894 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
-2021/12/26 | 43275 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma
-2021/12/26 | 47893 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
-2021/12/26 | 45731 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma
-2021/12/26 | 52279 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
-2021/12/26 | 199114 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma
-2021/12/26 | 213460 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
-2021/12/26 | 36041 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma
-2021/12/26 | 41220 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
-2021/12/26 | 753825 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma
-2021/12/26 | 824229 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
-2021/12/26 | 200142 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma
-2021/12/26 | 203080 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
-2021/12/26 | 209937 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma
-2021/12/26 | 244963 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
-2021/12/26 | 78962 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma
-2021/12/26 | 88228 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
-2021/12/26 | 1181004 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma
-2021/12/26 | 1322402 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
-2021/12/26 | 20190 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma
-2021/12/26 | 23931 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
-2021/12/26 | 31579 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma
-2021/12/26 | 37373 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
-2021/12/26 | 64715 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma
-2021/12/26 | 72850 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
-2021/12/26 | 50852 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma
-2021/12/26 | 58547 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
-2021/12/26 | 694124 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-2.9.tar.lzma
-2021/12/26 | 693756 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin.tar.lzma
-2021/12/26 | 763148 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-x64-2.9.tar.lzma
-2021/12/26 | 762930 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-x64.tar.lzma
-2021/12/26 | 1353497 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma
-2021/12/26 | 1497475 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
-2021/12/26 | 42766 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma
-2021/12/26 | 52573 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
-2021/12/26 | 57566 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma
-2021/12/26 | 63699 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
-2021/12/26 | 25671 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma
-2021/12/26 | 27474 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
-2021/12/26 | 16566 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma
-2021/12/26 | 18487 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
-2021/12/26 | 64452 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma
-2021/12/26 | 70993 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
-2021/12/26 | 157439 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma
-2021/12/26 | 172343 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
-2021/12/26 | 58642 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma
-2021/12/26 | 67188 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
-2021/12/26 | 101510 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma
-2021/12/26 | 109263 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
-2021/12/26 | 2675897 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma
-2021/12/26 | 2798719 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
-2021/12/26 | 55294 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma
-2021/12/26 | 62710 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
-2021/12/26 | 37151 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma
-2021/12/26 | 41202 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
-2021/12/26 | 28678 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma
-2021/12/26 | 34090 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
-2021/12/26 | 67857 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma
-2021/12/26 | 71896 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
-2021/12/26 | 318734 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma
-2021/12/26 | 351558 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
-2021/12/26 | 55725 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin.tar.lzma
-2021/12/26 | 57416 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin-x64.tar.lzma
-2021/12/26 | 591064 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma
-2021/12/26 | 629126 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
-2021/12/26 | 39745 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma
-2021/12/26 | 43683 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
-2021/12/26 | 256876 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
-2021/12/26 | 1398132 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
-2021/12/26 | 1294683 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
-2021/12/26 | 13510 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma
-2021/12/26 | 14416 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
+2021/12/27 | 630358 | systems/win32/miktex/tm/packages/next/files.csv.lzma
+2021/12/27 | 51588 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma
+2021/12/27 | 57407 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
+2021/12/27 | 959951 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma
+2021/12/27 | 1087069 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
+2021/12/27 | 28894 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma
+2021/12/27 | 31539 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
+2021/12/27 | 30181 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma
+2021/12/27 | 35264 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
+2021/12/27 | 50733 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma
+2021/12/27 | 58370 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
+2021/12/27 | 86768 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma
+2021/12/27 | 95275 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
+2021/12/27 | 68800 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma
+2021/12/27 | 77073 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
+2021/12/27 | 27243 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma
+2021/12/27 | 31333 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
+2021/12/27 | 332375 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma
+2021/12/27 | 394271 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
+2021/12/27 | 32990 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma
+2021/12/27 | 37092 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
+2021/12/27 | 51430 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma
+2021/12/27 | 57278 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
+2021/12/27 | 256199 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma
+2021/12/27 | 281441 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
+2021/12/27 | 179707 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma
+2021/12/27 | 196120 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
+2021/12/27 | 54950 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma
+2021/12/27 | 62420 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
+2021/12/27 | 21373 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma
+2021/12/27 | 24153 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
+2021/12/27 | 461242 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
+2021/12/27 | 46135 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma
+2021/12/27 | 52095 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
+2021/12/27 | 285454 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma
+2021/12/27 | 326387 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
+2021/12/27 | 41326 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma
+2021/12/27 | 45687 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
+2021/12/27 | 120296 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma
+2021/12/27 | 135070 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
+2021/12/27 | 1299134 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma
+2021/12/27 | 1447743 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
+2021/12/27 | 99760 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma
+2021/12/27 | 113043 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
+2021/12/27 | 43639 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma
+2021/12/27 | 48802 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
+2021/12/27 | 25134 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma
+2021/12/27 | 28545 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
+2021/12/27 | 56962 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma
+2021/12/27 | 63312 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
+2021/12/27 | 135931 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma
+2021/12/27 | 155285 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
+2021/12/27 | 73598 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma
+2021/12/27 | 79137 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
+2021/12/27 | 72256 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma
+2021/12/27 | 81708 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
+2021/12/27 | 259275 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma
+2021/12/27 | 295888 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
+2021/12/27 | 22178 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma
+2021/12/27 | 25061 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
+2021/12/27 | 97105 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma
+2021/12/27 | 112484 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
+2021/12/27 | 64569 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma
+2021/12/27 | 73182 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
+2021/12/27 | 96826 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma
+2021/12/27 | 115673 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
+2021/12/27 | 38460 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma
+2021/12/27 | 43809 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
+2021/12/27 | 484479 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma
+2021/12/27 | 566759 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
+2021/12/27 | 152105 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma
+2021/12/27 | 168850 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
+2021/12/27 | 95449 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma
+2021/12/27 | 109545 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
+2021/12/27 | 16521 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma
+2021/12/27 | 18371 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
+2021/12/27 | 28387 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma
+2021/12/27 | 30569 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
+2021/12/27 | 631000 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma
+2021/12/27 | 682340 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
+2021/12/27 | 532337 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma
+2021/12/27 | 599047 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
+2021/12/27 | 477729 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma
+2021/12/27 | 528532 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
+2021/12/27 | 93990 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma
+2021/12/27 | 103463 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
+2021/12/27 | 1732474 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma
+2021/12/27 | 2012707 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
+2021/12/27 | 67994 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma
+2021/12/27 | 74055 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
+2021/12/27 | 27261 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma
+2021/12/27 | 32155 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
+2021/12/27 | 7755 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma
+2021/12/27 | 8790 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
+2021/12/27 | 197374 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma
+2021/12/27 | 215852 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
+2021/12/27 | 251066 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma
+2021/12/27 | 286703 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
+2021/12/27 | 99372 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma
+2021/12/27 | 104748 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
+2021/12/27 | 64516 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma
+2021/12/27 | 74622 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma
+2021/12/27 | 126741 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma
+2021/12/27 | 139310 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
+2021/12/27 | 181558 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma
+2021/12/27 | 202238 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
+2021/12/27 | 199836 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma
+2021/12/27 | 181466 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
+2021/12/27 | 68618 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma
+2021/12/27 | 76233 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
+2021/12/27 | 31413 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma
+2021/12/27 | 35167 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
+2021/12/27 | 38542 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma
+2021/12/27 | 43894 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
+2021/12/27 | 43275 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma
+2021/12/27 | 47893 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
+2021/12/27 | 45731 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma
+2021/12/27 | 52279 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
+2021/12/27 | 199112 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma
+2021/12/27 | 213457 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
+2021/12/27 | 36043 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma
+2021/12/27 | 41220 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
+2021/12/27 | 753827 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma
+2021/12/27 | 824228 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
+2021/12/27 | 200141 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma
+2021/12/27 | 203081 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
+2021/12/27 | 209935 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma
+2021/12/27 | 244964 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
+2021/12/27 | 78963 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma
+2021/12/27 | 88227 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
+2021/12/27 | 1181005 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma
+2021/12/27 | 1322403 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
+2021/12/27 | 20190 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma
+2021/12/27 | 23933 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
+2021/12/27 | 31578 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma
+2021/12/27 | 37374 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
+2021/12/27 | 64716 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma
+2021/12/27 | 72850 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
+2021/12/27 | 50853 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma
+2021/12/27 | 58548 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
+2021/12/27 | 694124 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-2.9.tar.lzma
+2021/12/27 | 693757 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin.tar.lzma
+2021/12/27 | 763148 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-x64-2.9.tar.lzma
+2021/12/27 | 762929 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-x64.tar.lzma
+2021/12/27 | 1353499 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma
+2021/12/27 | 1497476 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
+2021/12/27 | 42767 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma
+2021/12/27 | 52573 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
+2021/12/27 | 57567 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma
+2021/12/27 | 63700 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
+2021/12/27 | 25671 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma
+2021/12/27 | 27473 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
+2021/12/27 | 16566 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma
+2021/12/27 | 18486 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
+2021/12/27 | 64453 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma
+2021/12/27 | 70994 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
+2021/12/27 | 157440 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma
+2021/12/27 | 172344 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
+2021/12/27 | 58643 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma
+2021/12/27 | 67188 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
+2021/12/27 | 101508 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma
+2021/12/27 | 109263 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
+2021/12/27 | 2675897 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma
+2021/12/27 | 2798717 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
+2021/12/27 | 55293 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma
+2021/12/27 | 62711 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
+2021/12/27 | 37152 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma
+2021/12/27 | 41203 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
+2021/12/27 | 28679 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma
+2021/12/27 | 34092 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
+2021/12/27 | 67857 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma
+2021/12/27 | 71895 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
+2021/12/27 | 318734 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma
+2021/12/27 | 351559 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
+2021/12/27 | 55722 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin.tar.lzma
+2021/12/27 | 57416 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin-x64.tar.lzma
+2021/12/27 | 591063 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma
+2021/12/27 | 629126 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
+2021/12/27 | 39745 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma
+2021/12/27 | 43683 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
+2021/12/27 | 256910 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
+2021/12/27 | 1397611 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
+2021/12/27 | 1294300 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
+2021/12/27 | 13511 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma
+2021/12/27 | 14418 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
2019/03/12 | 1412 | systems/win32/miktex/tm/packages/nextpage.tar.lzma
-2021/12/26 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini
+2021/12/27 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini
2018/07/06 | 145915 | systems/win32/miktex/tm/packages/nexus-otf.tar.lzma
2017/03/30 | 191149 | systems/win32/miktex/tm/packages/nfssext-cfr.tar.lzma
2012/12/20 | 612251 | systems/win32/miktex/tm/packages/nicefilelist.tar.lzma
@@ -298128,7 +298653,7 @@
2020/10/20 | 342254 | systems/win32/miktex/tm/packages/preview.tar.lzma
2019/06/20 | 375963 | systems/win32/miktex/tm/packages/prftree.tar.lzma
2021/04/23 | 274028 | systems/win32/miktex/tm/packages/principia.tar.lzma
-2021/12/26 | 965 | systems/win32/miktex/tm/packages/pr.ini
+2021/12/27 | 965 | systems/win32/miktex/tm/packages/pr.ini
2010/09/27 | 248469 | systems/win32/miktex/tm/packages/printlen.tar.lzma
2008/06/17 | 77313 | systems/win32/miktex/tm/packages/proba.tar.lzma
2017/07/12 | 988486 | systems/win32/miktex/tm/packages/probsoln.tar.lzma
@@ -299837,7 +300362,7 @@
2004/06/04 | 404 | tds/tds.sed
2004/06/23 | 65418 | tds/tds.tex
2019/05/29 | 304264 | tds.zip
-2021/12/27 | 186 | timestamp
+2021/12/28 | 186 | timestamp
2002/08/26 | 61898 | usergrps/dante/antrag.pdf
2002/08/26 | 118217 | usergrps/dante/antrag.ps
2021/11/11 | 917 | usergrps/dante/dtk/doc/beispiel.bib
diff --git a/FILES.byname.gz b/FILES.byname.gz
index b0c82e5ab2..0ec7de0169 100644
--- a/FILES.byname.gz
+++ b/FILES.byname.gz
Binary files differ
diff --git a/FILES.last07days b/FILES.last07days
index f82ce40942..44ec5dce1b 100644
--- a/FILES.last07days
+++ b/FILES.last07days
@@ -1,265 +1,1732 @@
-2021/12/26 | 99759 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma
+2021/12/28 | 731648 | macros/latex/contrib/diffcoeff/diffcoeff.pdf
+2021/12/28 | 1279 | macros/latex/contrib/diffcoeff/README.txt
+2021/12/27 | 99 | graphics/asymptote/base/asy_filetype.vim
+2021/12/27 | 999 | graphics/asymptote/GUI/res/icons/brush.svg
+2021/12/27 | 998 | graphics/asymptote/GUI/res/icons/chevron-with-circle-right.svg
+2021/12/27 | 99760 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-2.9.tar.lzma
+2021/12/27 | 994 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer_sf/common_footer.htm
+2021/12/27 | 9945 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/SemanticTokens.h
+2021/12/27 | 99372 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma
+2021/12/27 | 9923 | graphics/asymptote/profiler.h
+2021/12/27 | 990 | graphics/asymptote/examples/RiemannSphere.asy
+2021/12/27 | 989121 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/glew.h
+2021/12/27 | 98802 | macros/latex/contrib/diffcoeff/diffcoeff.tex
+2021/12/27 | 986 | graphics/asymptote/predicates.h
+2021/12/27 | 986 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/quickstart.cpp
+2021/12/27 | 9867 | graphics/asymptote/runstring.in
+2021/12/27 | 9826 | graphics/asymptote/base/rationalSimplex.asy
+2021/12/27 | 9822 | graphics/asymptote/doc/FAQ/m-html.pl
+2021/12/27 | 9811 | graphics/asymptote/doc/asymptote.sty
+2021/12/27 | 980 | graphics/asymptote/examples/filesurface.asy
+2021/12/27 | 978 | graphics/asymptote/examples/worksheet.asy
+2021/12/27 | 9772 | graphics/asymptote/fundec.cc
+2021/12/27 | 9754 | graphics/asymptote/triple.h
+2021/12/27 | 974 | graphics/asymptote/prc/Makefile
+2021/12/27 | 973 | graphics/asymptote/examples/fequlogo.asy
+2021/12/27 | 972 | graphics/asymptote/examples/triads.asy
+2021/12/27 | 97105 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma
+2021/12/27 | 969 | graphics/asymptote/runfile.h
+2021/12/27 | 968 | graphics/asymptote/LspCpp/packages.config
+2021/12/27 | 96826 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma
+2021/12/27 | 968193 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/glew.c
+2021/12/27 | 967 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer_sf/overview_footer.htm
+2021/12/27 | 966 | graphics/asymptote/tests/array/solve.asy
+2021/12/27 | 965 | systems/win32/miktex/tm/packages/pr.ini
+2021/12/27 | 964 | graphics/asymptote/GUI/res/icons/magnifying-glass.svg
+2021/12/27 | 95 | graphics/asymptote/prc/test.asy
+2021/12/27 | 959951 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma
+2021/12/27 | 9562 | graphics/asymptote/base/bezulate.asy
+2021/12/27 | 954 | graphics/asymptote/examples/poster.asy
+2021/12/27 | 95449 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma
+2021/12/27 | 953 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/workspaceFolders.h
+2021/12/27 | 95275 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
+2021/12/27 | 952118 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/nuklear.h
+2021/12/27 | 949 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/Context.cpp
+2021/12/27 | 94848 | graphics/asymptote/GUI/Window1.py
+2021/12/27 | 9472 | systems/texlive/tlnet/archive/termsim.source.r61414.tar.xz
+2021/12/27 | 946 | graphics/asymptote/examples/animations/cube.asy
+2021/12/27 | 942 | graphics/asymptote/statistics.h
+2021/12/27 | 93990 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma
+2021/12/27 | 937 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_open.h
+2021/12/27 | 936 | graphics/asymptote/tests/array/array.asy
+2021/12/27 | 9362 | graphics/asymptote/glrender.h
+2021/12/27 | 934 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/declaration_definition.h
+2021/12/27 | 9343039 | fonts/newtx.zip
+2021/12/27 | 9334 | graphics/asymptote/base/plain_paths.asy
+2021/12/27 | 9328 | graphics/asymptote/doc/FAQ/bfnnconv.pl
+2021/12/27 | 930 | graphics/asymptote/examples/polararea.asy
+2021/12/27 | 9251 | graphics/asymptote/errors
+2021/12/27 | 920 | graphics/asymptote/makeUnique.h
+2021/12/27 | 916 | graphics/asymptote/opcodes.h
+2021/12/27 | 912 | graphics/asymptote/doc/errorbars.asy
+2021/12/27 | 9104 | graphics/asymptote/symbol.cc
+2021/12/27 | 908 | graphics/asymptote/modifier.h
+2021/12/27 | 908 | graphics/asymptote/coenv.h
+2021/12/27 | 908 | graphics/asymptote/base/map.asy
+2021/12/27 | 9088 | graphics/asymptote/application.h
+2021/12/27 | 907 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/OverridableMethod.h
+2021/12/27 | 902 | graphics/asymptote/shaders.h
+2021/12/27 | 9022 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_gtk.c
+2021/12/27 | 901 | graphics/asymptote/virtualfieldaccess.cc
+2021/12/27 | 901 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/executeCommand.h
+2021/12/27 | 9015 | graphics/asymptote/psfile.h
+2021/12/27 | 8990 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/TcpServer.cpp
+2021/12/27 | 897 | graphics/asymptote/doc/flowchartdemo.asy
+2021/12/27 | 89290 | graphics/asymptote/webgl/gl.js
+2021/12/27 | 88 | graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/README.md
+2021/12/27 | 8870 | graphics/asymptote/base/asy.vim
+2021/12/27 | 886 | graphics/asymptote/angle.h
+2021/12/27 | 8856 | graphics/asymptote/runmath.in
+2021/12/27 | 883 | graphics/asymptote/cudareflect/helper.cuh
+2021/12/27 | 8836 | graphics/asymptote/doc/asy.1
+2021/12/27 | 88227 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
+2021/12/27 | 880 | graphics/asymptote/doc/xasy.1x
+2021/12/27 | 879 | graphics/asymptote/examples/markregular.asy
+2021/12/27 | 8792 | graphics/asymptote/prc/PRCTools/iPRCFile.cc
+2021/12/27 | 8790 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
+2021/12/27 | 877 | graphics/asymptote/GUI/Widg_addPolyOpt.py
+2021/12/27 | 877 | graphics/asymptote/doc/markers2.asy
+2021/12/27 | 876 | graphics/asymptote/GUI/res/icons/edit.svg
+2021/12/27 | 875011 | info/kaytannollista-latexia/kaytannollista-latexia.pdf
+2021/12/27 | 872 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/range_formatting.h
+2021/12/27 | 8711 | graphics/asymptote/base/plain_pens.asy
+2021/12/27 | 86 | graphics/asymptote/doc/cylinderskeleton.asy
+2021/12/27 | 868 | graphics/asymptote/examples/twistedtubes.asy
+2021/12/27 | 868 | graphics/asymptote/doc/imagecontour.asy
+2021/12/27 | 867 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/Condition.h
+2021/12/27 | 867 | graphics/asymptote/cudareflect/tinyexr/test/unit/config-msvc.py
+2021/12/27 | 86768 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma
+2021/12/27 | 866 | graphics/asymptote/examples/xxsq01x-1.asy
+2021/12/27 | 86123 | graphics/asymptote/base/three.asy
+2021/12/27 | 85 | graphics/asymptote/cudareflect/tinyexr/vcsetup2019.bat
+2021/12/27 | 85944 | info/kaytannollista-latexia/luku-merkintakieli.tex
+2021/12/27 | 858 | graphics/asymptote/GUI/res/icons/center.svg
+2021/12/27 | 856 | graphics/asymptote/examples/animations/sphere.asy
+2021/12/27 | 8567 | graphics/asymptote/xstream.h
+2021/12/27 | 8521 | graphics/asymptote/LspCpp/LibLsp/lsp/ClientPreferences.h
+2021/12/27 | 8519 | graphics/asymptote/cudareflect/ReflectanceMapper.cu
+2021/12/27 | 850 | graphics/asymptote/GUI/res/icons/android-folder-open.svg
+2021/12/27 | 845 | graphics/asymptote/envcompleter.h
+2021/12/27 | 8456 | graphics/asymptote/cudareflect/tinyexr/examples/deepview/trackball.cc
+2021/12/27 | 844 | graphics/asymptote/GUI/res/icons/android-radio-button-on.svg
+2021/12/27 | 8439 | graphics/asymptote/runpath.in
+2021/12/27 | 842 | graphics/asymptote/LspCpp/LibLsp/lsp/ProcessIoService.h
+2021/12/27 | 842 | graphics/asymptote/LspCpp/LibLsp/lsp/lsRange.h
+2021/12/27 | 842 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkConstructorsStatus.h
+2021/12/27 | 8429 | graphics/asymptote/examples/thermodynamics.asy
+2021/12/27 | 8426496 | graphics/asymptote/binaries/i386-windows/texlive/asy.exe
+2021/12/27 | 8411 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/reference.dox
+2021/12/27 | 839 | graphics/asymptote/examples/venn3.asy
+2021/12/27 | 838 | graphics/asymptote/GUI/res/icons/close-round.svg
+2021/12/27 | 8371 | graphics/asymptote/prc/PRCbitStream.cc
+2021/12/27 | 83449 | graphics/asymptote/lex.yy.cc
+2021/12/27 | 8342 | graphics/asymptote/base/simplex.asy
+2021/12/27 | 832 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-255456016cca60ddb5c5ed6898182e13739bf687b17d1411e97bb60ad95e7a84_min
+2021/12/27 | 831 | graphics/asymptote/runbacktrace.in
+2021/12/27 | 831 | graphics/asymptote/cudareflect/tinyexr/test/fuzzer/fuzz.cc
+2021/12/27 | 8303104 | graphics/asymptote/binaries/x86_64-windows/texlive/asy.exe
+2021/12/27 | 829 | graphics/asymptote/examples/shellsqrtx01.asy
+2021/12/27 | 8296 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview.txt
+2021/12/27 | 828 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateDelegateMethods.h
+2021/12/27 | 827 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkDelegateMethodsStatus.h
+2021/12/27 | 825 | graphics/asymptote/examples/xxsq01y.asy
+2021/12/27 | 8243 | graphics/asymptote/base/asy-kate.sh
+2021/12/27 | 824228 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
+2021/12/27 | 822 | graphics/asymptote/GUI/res/icons/android-expand.svg
+2021/12/27 | 821 | graphics/asymptote/v3dtypes.py
+2021/12/27 | 821 | graphics/asymptote/examples/SierpinskiGasket.asy
+2021/12/27 | 820 | graphics/asymptote/webgl/license
+2021/12/27 | 820 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/LICENSE
+2021/12/27 | 81 | graphics/asymptote/doc/bezier.asy
+2021/12/27 | 818 | graphics/asymptote/GLTextures.cc
+2021/12/27 | 81708 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
+2021/12/27 | 814 | graphics/asymptote/camperror.h
+2021/12/27 | 81162 | graphics/asymptote/doc/TeXShopAndAsymptote.pdf
+2021/12/27 | 810 | graphics/asymptote/examples/orthocenter.asy
+2021/12/27 | 8096 | graphics/asymptote/runhistory.cc
+2021/12/27 | 8095 | graphics/asymptote/LspCpp/example/WebsocketExample.cpp
+2021/12/27 | 808 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_save.h
+2021/12/27 | 806 | graphics/asymptote/GUI/res/icons/android-refresh.svg
+2021/12/27 | 8037 | graphics/asymptote/name.cc
+2021/12/27 | 802 | graphics/asymptote/GUI/res/icons/android-camera.svg
+2021/12/27 | 802 | graphics/asymptote/examples/vertexshading.asy
+2021/12/27 | 802 | graphics/asymptote/examples/controlsystem.asy
+2021/12/27 | 801 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/Makefile
+2021/12/27 | 8008 | graphics/asymptote/runpath3d.in
+2021/12/27 | 798 | graphics/asymptote/examples/animations/torusanimation.asy
+2021/12/27 | 794 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/execute_command.h
+2021/12/27 | 793 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-eedff3a9e99eb1c0fd3a3b0989e7c44c0a69f04f10b23e5264f362a4773f4397_min
+2021/12/27 | 792 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/formatting.h
+2021/12/27 | 792 | graphics/asymptote/doc/secondaryaxis.asy
+2021/12/27 | 79137 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
+2021/12/27 | 79003 | graphics/asymptote/GUI/windows/window1.ui
+2021/12/27 | 78 | graphics/asymptote/examples/randompath3.asy
+2021/12/27 | 789 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveTypeHierarchy.h
+2021/12/27 | 78963 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma
+2021/12/27 | 780 | graphics/asymptote/GUI/res/icons/check.svg
+2021/12/27 | 77 | graphics/asymptote/tests/gc/string.asy
+2021/12/27 | 7790 | graphics/asymptote/coder.cc
+2021/12/27 | 778 | graphics/asymptote/LspCpp/LibLsp/lsp/lsDocumentUri.h
+2021/12/27 | 7780 | graphics/asymptote/cudareflect/main.cc
+2021/12/27 | 7755 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma
+2021/12/27 | 7737 | graphics/asymptote/LspCpp/network/string_view.hpp
+2021/12/27 | 770 | graphics/asymptote/asy.rc
+2021/12/27 | 77073 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
+2021/12/27 | 76 | graphics/asymptote/examples/grid.asy
+2021/12/27 | 768 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_close.h
+2021/12/27 | 7684 | graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/sanitize-helpers.cmake
+2021/12/27 | 76801 | graphics/asymptote/gl-matrix-2.4.0-pruned/dist/gl-matrix.js
+2021/12/27 | 7671 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/Context.h
+2021/12/27 | 766 | graphics/asymptote/vm.h
+2021/12/27 | 764 | graphics/asymptote/GUI/res/icons/android-radio-button-off.svg
+2021/12/27 | 7639 | graphics/asymptote/LICENSE.LESSER
+2021/12/27 | 7632 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/pool.hpp
+2021/12/27 | 763148 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-x64-2.9.tar.lzma
+2021/12/27 | 762 | graphics/asymptote/examples/clockarray.asy
+2021/12/27 | 762929 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-x64.tar.lzma
+2021/12/27 | 76233 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
+2021/12/27 | 7619 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/threadpool.css
+2021/12/27 | 759 | graphics/asymptote/GUI/res/icons/plus-round.svg
+2021/12/27 | 754 | graphics/asymptote/GUI/res/icons/circle.svg
+2021/12/27 | 754 | graphics/asymptote/doc/graphmarkers.asy
+2021/12/27 | 753827 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma
+2021/12/27 | 751 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/publishDiagnostics.h
+2021/12/27 | 74 | graphics/asymptote/LspCpp/LibLsp/lsp/method_type.h
+2021/12/27 | 748 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/resolveUnimplementedAccessors.h
+2021/12/27 | 747 | graphics/asymptote/examples/pseudosphere.asy
+2021/12/27 | 746 | graphics/asymptote/tests/array/sort.asy
+2021/12/27 | 74622 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma
+2021/12/27 | 743 | graphics/asymptote/examples/xxsq01.asy
+2021/12/27 | 741 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_opendialogmultiple.c
+2021/12/27 | 7407 | graphics/asymptote/base/graph_splinetype.asy
+2021/12/27 | 74055 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
+2021/12/27 | 739 | graphics/asymptote/examples/condor.asy
+2021/12/27 | 738 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateHashCodeEquals.h
+2021/12/27 | 737 | graphics/asymptote/tests/array/determinant.asy
+2021/12/27 | 73598 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma
+2021/12/27 | 734 | graphics/asymptote/examples/quilt.asy
+2021/12/27 | 73435 | graphics/asymptote/GL/glxew.h
+2021/12/27 | 733 | graphics/asymptote/GUI/xasySvg.py
+2021/12/27 | 73254 | graphics/asymptote/runarray.cc
+2021/12/27 | 73182 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
+2021/12/27 | 730 | graphics/asymptote/LspCpp/network/uri/detail/uri_parse_authority.hpp
+2021/12/27 | 73066 | graphics/asymptote/base/three_surface.asy
+2021/12/27 | 7305 | graphics/asymptote/base/stats.asy
+2021/12/27 | 7302 | graphics/asymptote/base/markers.asy
+2021/12/27 | 72 | graphics/asymptote/tests/gc/pen.asy
+2021/12/27 | 729 | graphics/asymptote/base/labelpath.asy
+2021/12/27 | 7295 | graphics/asymptote/base/plain.asy
+2021/12/27 | 72850 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
+2021/12/27 | 727 | graphics/asymptote/examples/fermi.asy
+2021/12/27 | 7274 | graphics/asymptote/runtime.pl
+2021/12/27 | 722 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/searchSymbols.h
+2021/12/27 | 72256 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma
+2021/12/27 | 7222 | graphics/asymptote/GUI/pyUIClass/widg_addLabel.py
+2021/12/27 | 71994 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/glxew.h
+2021/12/27 | 71895 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
+2021/12/27 | 7152 | graphics/asymptote/LspCpp/LibLsp/lsp/lsp_completion.h
+2021/12/27 | 714 | graphics/asymptote/mod.h
+2021/12/27 | 714 | graphics/asymptote/LspCpp/network/uri/detail/uri_resolve.hpp
+2021/12/27 | 714 | graphics/asymptote/examples/unitoctantx.asy
+2021/12/27 | 713 | graphics/asymptote/GUI/res/icons/arrow-move.svg
+2021/12/27 | 713 | graphics/asymptote/examples/gamma3.asy
+2021/12/27 | 71368 | graphics/asymptote/base/asy-mode.el
+2021/12/27 | 71201 | graphics/asymptote/prc/oPRCFile.cc
+2021/12/27 | 711 | graphics/asymptote/examples/partialsurface.asy
+2021/12/27 | 710 | graphics/asymptote/examples/fjortoft.asy
+2021/12/27 | 70 | graphics/asymptote/tests/gc/transform.asy
+2021/12/27 | 709 | graphics/asymptote/cudareflect/tinyexr/test/fuzzer/Makefile
+2021/12/27 | 7099 | graphics/asymptote/config.h.in
+2021/12/27 | 70994 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
+2021/12/27 | 706 | graphics/asymptote/LspCpp/LibLsp/lsp/AbsolutePath.h
+2021/12/27 | 70102 | graphics/asymptote/base/graph3.asy
+2021/12/27 | 700 | graphics/asymptote/GUI/locale/th/LC_MESSAGES/base.po
+2021/12/27 | 695 | graphics/asymptote/GUI/res/icons/android-close.svg
+2021/12/27 | 69443 | macros/latex/contrib/codebox/codebox-doc-en.pdf
+2021/12/27 | 69441 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/miniz.h
+2021/12/27 | 694124 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-2.9.tar.lzma
+2021/12/27 | 693 | graphics/asymptote/LspCpp/LibLsp/lsp/general/progress.h
+2021/12/27 | 693757 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin.tar.lzma
+2021/12/27 | 6917 | graphics/asymptote/LspCpp/network/uri/uri_builder.hpp
+2021/12/27 | 6911 | graphics/asymptote/errortest.asy
+2021/12/27 | 690 | graphics/asymptote/examples/layers.asy
+2021/12/27 | 6896 | graphics/asymptote/GUI/windows/widg_addLabel.ui
+2021/12/27 | 688 | graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentEdit.h
+2021/12/27 | 688 | graphics/asymptote/examples/centroidfg.asy
+2021/12/27 | 6889 | graphics/asymptote/LspCpp/LibLsp/lsp/general/lsWorkspaceClientCapabilites.h
+2021/12/27 | 68800 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma
+2021/12/27 | 687 | graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/Makefile
+2021/12/27 | 68618 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma
+2021/12/27 | 683 | graphics/asymptote/examples/fractaltree.asy
+2021/12/27 | 682340 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
+2021/12/27 | 68126 | graphics/asymptote/prc/PRCTools/describePRC.cc
+2021/12/27 | 6811313 | systems/texlive/tlnet/install-tl-unx.tar.gz
+2021/12/27 | 680 | graphics/asymptote/tests/array/delete.asy
+2021/12/27 | 67 | graphics/asymptote/LspCpp/third_party/threadpool/project-root.jam
+2021/12/27 | 679 | graphics/asymptote/examples/genusthree.asy
+2021/12/27 | 67994 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma
+2021/12/27 | 678 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-5b66774a7498c635334ad386be0c3b359951738ac47f14878a3346d1c6ea0fe5_min
+2021/12/27 | 6787 | graphics/asymptote/drawlabel.cc
+2021/12/27 | 67857 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma
+2021/12/27 | 677 | graphics/asymptote/doc/Bode.asy
+2021/12/27 | 677 | graphics/asymptote/base/shaders/vertex.glsl
+2021/12/27 | 6772 | graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/main.cc
+2021/12/27 | 676 | graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentItem.h
+2021/12/27 | 674 | graphics/asymptote/GUI/res/icons/android-delete.svg
+2021/12/27 | 674 | graphics/asymptote/examples/sqrtx01.asy
+2021/12/27 | 673 | graphics/asymptote/GUI/res/icons/save.svg
+2021/12/27 | 6726 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example3.c
+2021/12/27 | 6725 | graphics/asymptote/guide.h
+2021/12/27 | 67188 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
+2021/12/27 | 671830 | macros/latex/contrib/diffcoeff.zip
+2021/12/27 | 6717 | graphics/asymptote/GUI/xasyOptions.py
+2021/12/27 | 670 | graphics/asymptote/base/v3dtypes.asy
+2021/12/27 | 66 | graphics/asymptote/examples/shade.asy
+2021/12/27 | 669 | graphics/asymptote/drawpath.h
+2021/12/27 | 667 | graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentPositionParams.h
+2021/12/27 | 667 | graphics/asymptote/examples/spring.asy
+2021/12/27 | 66751 | graphics/asymptote/prc/writePRC.cc
+2021/12/27 | 66559 | graphics/asymptote/base/webgl/asygl.js
+2021/12/27 | 6650 | graphics/asymptote/getopt.h
+2021/12/27 | 663 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool.hpp
+2021/12/27 | 6634 | graphics/asymptote/simpson.cc
+2021/12/27 | 65 | graphics/asymptote/tests/gc/guide.asy
+2021/12/27 | 658 | graphics/asymptote/LspCpp/network/uri/detail/uri_advance_parts.hpp
+2021/12/27 | 658 | graphics/asymptote/examples/NURBScurve.asy
+2021/12/27 | 657 | graphics/asymptote/examples/lowupint.asy
+2021/12/27 | 657 | graphics/asymptote/examples/100d.views
+2021/12/27 | 657 | graphics/asymptote/base/reload.js
+2021/12/27 | 6553 | graphics/asymptote/cudareflect/tinyexr/examples/deepview/main.cc
+2021/12/27 | 6552 | graphics/asymptote/GUI/windows/labelTextEditor.ui
+2021/12/27 | 6551 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example2.c
+2021/12/27 | 6550 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/scheduling_policies.hpp
+2021/12/27 | 654 | graphics/asymptote/fpu.h
+2021/12/27 | 654 | graphics/asymptote/examples/limit.asy
+2021/12/27 | 6528 | graphics/asymptote/lspserv.h
+2021/12/27 | 6525 | graphics/asymptote/drawfill.h
+2021/12/27 | 6524 | systems/texlive/tlnet/archive/collection-latexextra.r61415.tar.xz
+2021/12/27 | 650 | graphics/asymptote/prcfile.h
+2021/12/27 | 6503 | graphics/asymptote/tests/types/constructor.asy
+2021/12/27 | 64 | graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-62-tinyexr_memcpy_heap-buffer-overflow
+2021/12/27 | 64716 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma
+2021/12/27 | 64569 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma
+2021/12/27 | 64516 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma
+2021/12/27 | 64453 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma
+2021/12/27 | 643 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer/common_footer.htm
+2021/12/27 | 64207 | graphics/asymptote/base/graph.asy
+2021/12/27 | 641 | graphics/asymptote/examples/pOrbital.asy
+2021/12/27 | 6414 | graphics/asymptote/mathop.h
+2021/12/27 | 6402 | graphics/asymptote/main.cc
+2021/12/27 | 639 | graphics/asymptote/tests/arith/transform.asy
+2021/12/27 | 639 | graphics/asymptote/GUI/res/icons/arrow-resize.svg
+2021/12/27 | 6386 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/threaded_queue.h
+2021/12/27 | 637 | graphics/asymptote/GUI/res/icons/android-arrow-forward.svg
+2021/12/27 | 637 | graphics/asymptote/GUI/res/icons/android-arrow-back.svg
+2021/12/27 | 6370 | graphics/asymptote/asymptote.nsi
+2021/12/27 | 63700 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
+2021/12/27 | 6369 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/traits.h
+2021/12/27 | 6350 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial.txt
+2021/12/27 | 633 | graphics/asymptote/GUI/res/icons/android-done.svg
+2021/12/27 | 63314 | graphics/asymptote/GL/wglew.h
+2021/12/27 | 63312 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
+2021/12/27 | 632 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/SCTConfig.h
+2021/12/27 | 632 | graphics/asymptote/examples/label3zoom.asy
+2021/12/27 | 631 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkToStringStatus.h
+2021/12/27 | 631 | graphics/asymptote/locate.h
+2021/12/27 | 63193 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_gtk3.png
+2021/12/27 | 6318 | graphics/asymptote/doc/leastsquares.dat
+2021/12/27 | 63136 | graphics/asymptote/doc/FAQ/asy-faq.info
+2021/12/27 | 631000 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma
+2021/12/27 | 630 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-24322747c47e87a10e4407528b779a1a763a48135384909b3d1010bbba1d4c28_min
+2021/12/27 | 630565 | systems/win32/miktex/tm/packages/files.csv.lzma
+2021/12/27 | 630358 | systems/win32/miktex/tm/packages/next/files.csv.lzma
+2021/12/27 | 62 | graphics/asymptote/tests/gc/array.asy
+2021/12/27 | 62 | graphics/asymptote/revision.cc
+2021/12/27 | 629126 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
+2021/12/27 | 628 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/message.h
+2021/12/27 | 628 | graphics/asymptote/examples/wedge.asy
+2021/12/27 | 628 | graphics/asymptote/examples/polarcircle.asy
+2021/12/27 | 6288 | graphics/asymptote/transform.h
+2021/12/27 | 6287 | graphics/asymptote/base/plain_prethree.asy
+2021/12/27 | 6278 | graphics/asymptote/base/plain_filldraw.asy
+2021/12/27 | 6275 | graphics/asymptote/generate_enums.py
+2021/12/27 | 62711 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
+2021/12/27 | 626 | graphics/asymptote/examples/venn.asy
+2021/12/27 | 625 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer/overview_footer.htm
+2021/12/27 | 625 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/addOverridableMethods.h
+2021/12/27 | 6247 | graphics/asymptote/GUI/pyUIClass/labelTextEditor.py
+2021/12/27 | 62420 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
+2021/12/27 | 62206 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/wglew.h
+2021/12/27 | 620 | graphics/asymptote/tests/arith/integer.asy
+2021/12/27 | 61 | graphics/asymptote/examples/axialshade.asy
+2021/12/27 | 61 | graphics/asymptote/cudareflect/tinyexr/test/issues/160/README.md
+2021/12/27 | 6189 | graphics/asymptote/camp.tab.h
+2021/12/27 | 617 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateConstructors.h
+2021/12/27 | 617 | graphics/asymptote/doc/logo.asy
+2021/12/27 | 616 | graphics/asymptote/examples/Gouraudcontour.asy
+2021/12/27 | 616460 | systems/texlive/tlnet/archive/easybook.doc.r61413.tar.xz
+2021/12/27 | 615 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_common.h
+2021/12/27 | 6159 | graphics/asymptote/base/plain_strings.asy
+2021/12/27 | 6131 | info/kaytannollista-latexia/README.md
+2021/12/27 | 612 | graphics/asymptote/cudareflect/tinyexr/experimental/js/README.md
+2021/12/27 | 612 | graphics/asymptote/cudareflect/tinyexr/examples/exr2rgbe/exr2rgbe.cc
+2021/12/27 | 611 | graphics/asymptote/GUI/xasy.py
+2021/12/27 | 6117 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_cocoa.m
+2021/12/27 | 610 | graphics/asymptote/examples/impact.asy
+2021/12/27 | 6104 | graphics/asymptote/doc/FAQ/m-lout.pl
+2021/12/27 | 609 | graphics/asymptote/keywords.cc
+2021/12/27 | 60939 | graphics/asymptote/runtime.cc
+2021/12/27 | 608 | graphics/asymptote/examples/spline.asy
+2021/12/27 | 608 | graphics/asymptote/base/size10.asy
+2021/12/27 | 604 | graphics/asymptote/doc/flow.asy
+2021/12/27 | 602 | graphics/asymptote/examples/treetest.asy
+2021/12/27 | 6021 | graphics/asymptote/prc/PRCTools/bitData.cc
+2021/12/27 | 600 | graphics/asymptote/base/size11.asy
+2021/12/27 | 60074 | graphics/asymptote/GUI/xasy2asy.py
+2021/12/27 | 59 | graphics/asymptote/examples/stroke3.asy
+2021/12/27 | 599047 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
+2021/12/27 | 598 | graphics/asymptote/examples/integraltest.asy
+2021/12/27 | 5987 | graphics/asymptote/runfile.in
+2021/12/27 | 5975 | graphics/asymptote/base/three_tube.asy
+2021/12/27 | 59583 | graphics/asymptote/GUI/pyUIClass/window1.py
+2021/12/27 | 594 | graphics/asymptote/LspCpp/network/uri/detail/uri_normalize.hpp
+2021/12/27 | 593 | graphics/asymptote/GUI/res/icons/bucket.asy
+2021/12/27 | 591 | graphics/asymptote/examples/sinc.asy
+2021/12/27 | 591063 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma
+2021/12/27 | 58 | graphics/asymptote/examples/progrid.asy
+2021/12/27 | 589 | graphics/asymptote/examples/trefoilknot.asy
+2021/12/27 | 588 | graphics/asymptote/LspCpp/LibLsp/lsp/out_list.h
+2021/12/27 | 5883 | graphics/asymptote/Delaunay.cc
+2021/12/27 | 587 | graphics/asymptote/LspCpp/LibLsp/lsp/ExecuteCommandParams.h
+2021/12/27 | 5877 | graphics/asymptote/base/shaders/fragment.glsl
+2021/12/27 | 586 | graphics/asymptote/GUI/xasyStrings.py
+2021/12/27 | 58643 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma
+2021/12/27 | 58548 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
+2021/12/27 | 58370 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
+2021/12/27 | 582 | graphics/asymptote/examples/cos3.asy
+2021/12/27 | 5823 | graphics/asymptote/drawpath3.h
+2021/12/27 | 5820 | graphics/asymptote/cudareflect/IrradianceGenerator.vcxproj
+2021/12/27 | 581 | graphics/asymptote/examples/BezierSaddle.asy
+2021/12/27 | 580 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/did_change_configuration.h
+2021/12/27 | 580 | graphics/asymptote/examples/xsin1x.asy
+2021/12/27 | 57 | graphics/asymptote/GUI/requirements.txt
+2021/12/27 | 579 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/findLinks.h
+2021/12/27 | 579 | graphics/asymptote/examples/sqrtx01y1.asy
+2021/12/27 | 579 | graphics/asymptote/examples/sin3.asy
+2021/12/27 | 579 | graphics/asymptote/examples/exp3.asy
+2021/12/27 | 57944 | graphics/asymptote/runpicture.cc
+2021/12/27 | 578 | graphics/asymptote/base/annotate.asy
+2021/12/27 | 5789 | graphics/asymptote/base/trembling.asy
+2021/12/27 | 576 | graphics/asymptote/examples/threeviews.asy
+2021/12/27 | 576 | graphics/asymptote/examples/circles.asy
+2021/12/27 | 57688 | graphics/asymptote/glrender.cc
+2021/12/27 | 57567 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma
+2021/12/27 | 57416 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin-x64.tar.lzma
+2021/12/27 | 57407 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
+2021/12/27 | 5735 | graphics/asymptote/base/plain_scaling.asy
+2021/12/27 | 5734 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/protocol.h
+2021/12/27 | 5733 | graphics/asymptote/item.h
+2021/12/27 | 572 | graphics/asymptote/examples/curvedlabel3.asy
+2021/12/27 | 57278 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
+2021/12/27 | 5712 | graphics/asymptote/bezierpatch.h
+2021/12/27 | 570 | graphics/asymptote/examples/fillcontour.asy
+2021/12/27 | 569 | graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/Makefile
+2021/12/27 | 56962 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma
+2021/12/27 | 5691 | graphics/asymptote/name.h
+2021/12/27 | 568 | graphics/asymptote/LspCpp/network/uri/config.hpp
+2021/12/27 | 566 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/highlight.h
+2021/12/27 | 566759 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
+2021/12/27 | 565 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateAccessors.h
+2021/12/27 | 5627 | graphics/asymptote/doc/FAQ/m-info.pl
+2021/12/27 | 5621 | graphics/asymptote/errormsg.h
+2021/12/27 | 55991 | graphics/asymptote/base/smoothcontour3.asy
+2021/12/27 | 558 | graphics/asymptote/examples/floatingdisk.asy
+2021/12/27 | 5586 | graphics/asymptote/interact.cc
+2021/12/27 | 557 | graphics/asymptote/examples/Pythagoras.asy
+2021/12/27 | 5578 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_checked_api.cpp
+2021/12/27 | 55726 | graphics/asymptote/LspCpp/third_party/utfcpp/README.md
+2021/12/27 | 55722 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin.tar.lzma
+2021/12/27 | 5566 | graphics/asymptote/drawpath3.cc
+2021/12/27 | 5543 | graphics/asymptote/examples/filesurface.dat
+2021/12/27 | 5537 | graphics/asymptote/examples/cpkcolors.asy
+2021/12/27 | 552 | graphics/asymptote/LspCpp/network/uri/detail/uri_parse.hpp
+2021/12/27 | 55293 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma
+2021/12/27 | 54 | graphics/asymptote/tests/gc/funcall.asy
+2021/12/27 | 54950 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma
+2021/12/27 | 548 | graphics/asymptote/v3dtypes.h
+2021/12/27 | 548 | graphics/asymptote/examples/equilchord.asy
+2021/12/27 | 548 | graphics/asymptote/cudareflect/Makefile
+2021/12/27 | 547 | graphics/asymptote/examples/tetra.asy
+2021/12/27 | 5441 | graphics/asymptote/env.cc
+2021/12/27 | 54109 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/optional.hpp
+2021/12/27 | 53997 | graphics/asymptote/settings.cc
+2021/12/27 | 535 | graphics/asymptote/cudareflect/tinyexr/Makefile.llvm-mingw
+2021/12/27 | 533 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_savedialog.c
+2021/12/27 | 5328 | graphics/asymptote/LspCpp/LibLsp/lsp/working_files.cpp
+2021/12/27 | 5323 | graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/exr2fptiff.cc
+2021/12/27 | 532337 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma
+2021/12/27 | 530 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_opendialog.c
+2021/12/27 | 52 | graphics/asymptote/doc/square.asy
+2021/12/27 | 528532 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
+2021/12/27 | 5279 | graphics/asymptote/base/bsp.asy
+2021/12/27 | 5278 | graphics/asymptote/pair.h
+2021/12/27 | 52750 | graphics/asymptote/cudareflect/tinyexr/test/unit/tester.cc
+2021/12/27 | 5272 | graphics/asymptote/GUI/labelEditor.py
+2021/12/27 | 5265 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/tutorial/tutorial.cpp
+2021/12/27 | 5262 | graphics/asymptote/patches/bison.patch
+2021/12/27 | 525 | graphics/asymptote/examples/vectorfield3.asy
+2021/12/27 | 52573 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
+2021/12/27 | 5250 | graphics/asymptote/pipestream.cc
+2021/12/27 | 524 | graphics/asymptote/doc/brokenaxis.asy
+2021/12/27 | 5238 | graphics/asymptote/base/animation.asy
+2021/12/27 | 52279 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
+2021/12/27 | 5221 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview.dox
+2021/12/27 | 521 | graphics/asymptote/doc/Hobbycontrol.asy
+2021/12/27 | 521 | graphics/asymptote/base/shaders/presum.glsl
+2021/12/27 | 5216 | graphics/asymptote/examples/mosaic.asy
+2021/12/27 | 520 | graphics/asymptote/examples/smoothelevation.asy
+2021/12/27 | 52095 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
+2021/12/27 | 5203 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial.dox
+2021/12/27 | 5202 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples.dox
+2021/12/27 | 519 | graphics/asymptote/examples/extrudedcontour.asy
+2021/12/27 | 5196 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design.dox
+2021/12/27 | 518 | graphics/asymptote/doc/CDlabel.asy
+2021/12/27 | 5183 | graphics/asymptote/stm.h
+2021/12/27 | 516893 | macros/latex/contrib/wrapfig2.zip
+2021/12/27 | 51640 | graphics/asymptote/prc/oPRCFile.h
+2021/12/27 | 51588 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma
+2021/12/27 | 514 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateToString.h
+2021/12/27 | 51430 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma
+2021/12/27 | 513 | graphics/asymptote/examples/buildcycle.asy
+2021/12/27 | 5111 | graphics/asymptote/runsystem.in
+2021/12/27 | 50 | graphics/asymptote/cudareflect/tinyexr/test/unit/win32-filelist-utf16le.inc
+2021/12/27 | 50 | graphics/asymptote/base/babel.asy
+2021/12/27 | 509 | graphics/asymptote/examples/dimension.asy
+2021/12/27 | 509 | graphics/asymptote/cudareflect/tinyexr/Makefile
+2021/12/27 | 5095 | graphics/asymptote/memory.h
+2021/12/27 | 50853 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma
+2021/12/27 | 50733 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma
+2021/12/27 | 506 | graphics/asymptote/examples/delu.asy
+2021/12/27 | 5064 | graphics/asymptote/runhistory.in
+2021/12/27 | 504 | graphics/asymptote/absyn.cc
+2021/12/27 | 50437 | graphics/asymptote/gsl.cc
+2021/12/27 | 503 | graphics/asymptote/examples/animations/embeddedmovie.asy
+2021/12/27 | 503 | graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-63-tinyexr_signed-integer-overflow
+2021/12/27 | 500 | graphics/asymptote/examples/floor.asy
+2021/12/27 | 500 | graphics/asymptote/doc/Hobbydir.asy
+2021/12/27 | 49 | graphics/asymptote/doc/quartercircle.asy
+2021/12/27 | 49 | graphics/asymptote/doc/dots.asy
+2021/12/27 | 49 | graphics/asymptote/doc/colons.asy
+2021/12/27 | 499 | graphics/asymptote/examples/galleon.asy
+2021/12/27 | 4996 | graphics/asymptote/base/rational.asy
+2021/12/27 | 4992 | graphics/asymptote/base/tube.asy
+2021/12/27 | 498 | graphics/asymptote/examples/fano.asy
+2021/12/27 | 498 | graphics/asymptote/doc/penfunctionimage.asy
+2021/12/27 | 4973 | graphics/asymptote/LspCpp/example/StdIOClientExample.cpp
+2021/12/27 | 496 | graphics/asymptote/examples/bars3.asy
+2021/12/27 | 496 | graphics/asymptote/base/shaders/postsum.glsl
+2021/12/27 | 495 | graphics/asymptote/examples/cones.asy
+2021/12/27 | 495 | graphics/asymptote/cudareflect/tinyexr/experimental/js/test.js
+2021/12/27 | 494 | graphics/asymptote/drawgrestore.h
+2021/12/27 | 494 | graphics/asymptote/cudareflect/tinyexr/experimental/js/compile_to_js.sh
+2021/12/27 | 4942 | graphics/asymptote/GUI/pyUIClass/widg_editBezier.py
+2021/12/27 | 4919 | graphics/asymptote/process.h
+2021/12/27 | 49140 | info/mathalphabets/src/mathalphabets.tex
+2021/12/27 | 490 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/type_definition.h
+2021/12/27 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
+2021/12/27 | 489 | graphics/asymptote/patches/gc-7.0nomem.patch
+2021/12/27 | 489 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveCompletionItem.h
+2021/12/27 | 4899 | graphics/asymptote/LspCpp/LibLsp/lsp/utils.h
+2021/12/27 | 4895 | graphics/asymptote/fundec.h
+2021/12/27 | 488 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/implementation.h
+2021/12/27 | 48847 | graphics/asymptote/doc/secondaryaxis.csv
+2021/12/27 | 48802 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
+2021/12/27 | 487 | graphics/asymptote/LspCpp/LibLsp/lsp/general/shutdown.h
+2021/12/27 | 4873 | graphics/asymptote/parser.cc
+2021/12/27 | 4866 | graphics/asymptote/fileio.cc
+2021/12/27 | 485 | graphics/asymptote/examples/cards.asy
+2021/12/27 | 48481 | graphics/asymptote/prc/writePRC.h
+2021/12/27 | 484479 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma
+2021/12/27 | 48441 | graphics/asymptote/config.guess
+2021/12/27 | 4841 | graphics/asymptote/tests/array/slice.asy
+2021/12/27 | 48417 | graphics/asymptote/runarray.in
+2021/12/27 | 4837 | graphics/asymptote/LspCpp/example/TcpServerExample.cpp
+2021/12/27 | 482 | graphics/asymptote/LspCpp/LibLsp/lsp/general/initialized.h
+2021/12/27 | 4818 | graphics/asymptote/v3dfile.h
+2021/12/27 | 4811 | graphics/asymptote/base/x11colors.asy
+2021/12/27 | 480 | graphics/asymptote/doc/logimage.asy
+2021/12/27 | 4808 | graphics/asymptote/examples/interpolate1.asy
+2021/12/27 | 479 | graphics/asymptote/examples/magnetic.asy
+2021/12/27 | 4792 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/serializer.cpp
+2021/12/27 | 47893 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
+2021/12/27 | 477729 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma
+2021/12/27 | 476 | graphics/asymptote/GUI/configs/xasykeymap.cson
+2021/12/27 | 4761 | graphics/asymptote/GUI/pyUIClass/widgetPointEditor.py
+2021/12/27 | 4738 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-360c3b0555cb979ca108f2d178cf8a80959cfeabaa4ec1d310d062fa653a8c6b_min
+2021/12/27 | 473703 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-1383755b301e5f505b2198dc0508918b537fdf48bbfc6deeffe268822e6f6cd6
+2021/12/27 | 473695 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-e7fa6404daa861369d2172fe68e08f9d38c0989f57da7bcfb510bab67e19ca9f
+2021/12/27 | 4735 | graphics/asymptote/array.cc
+2021/12/27 | 4731 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/flaga.exr
+2021/12/27 | 472 | graphics/asymptote/examples/colorplanes.asy
+2021/12/27 | 4727 | graphics/asymptote/doc/westnile.csv
+2021/12/27 | 472132 | graphics/asymptote/doc/png/asymptote.info
+2021/12/27 | 4718 | graphics/asymptote/doc/FAQ/m-ascii.pl
+2021/12/27 | 4716 | graphics/asymptote/prc/PRCTools/makePRC.cc
+2021/12/27 | 4688 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/sonarlint/protocol.h
+2021/12/27 | 46531 | graphics/asymptote/base/plain_picture.asy
+2021/12/27 | 464 | graphics/asymptote/drawgsave.h
+2021/12/27 | 464 | graphics/asymptote/doc/GaussianSurface.asy
+2021/12/27 | 4635 | graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/exrfilter.cc
+2021/12/27 | 4629 | graphics/asymptote/castop.h
+2021/12/27 | 4626 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_unchecked_api.cpp
+2021/12/27 | 46135 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma
+2021/12/27 | 461242 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
+2021/12/27 | 460 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/Cancellation.h
+2021/12/27 | 460 | graphics/asymptote/examples/lever.asy
+2021/12/27 | 460 | graphics/asymptote/examples/cosaddition.asy
+2021/12/27 | 4602 | graphics/asymptote/util.h
+2021/12/27 | 4602 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/README.md
+2021/12/27 | 459 | graphics/asymptote/examples/hierarchy.asy
+2021/12/27 | 4597 | graphics/asymptote/drawfill.cc
+2021/12/27 | 458 | graphics/asymptote/doc/multicontour.asy
+2021/12/27 | 4580 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageIssue.h
+2021/12/27 | 4578 | graphics/asymptote/LspCpp/LibLsp/lsp/IProgressMonitor.h
+2021/12/27 | 4578 | graphics/asymptote/doc/FAQ/m-post.pl
+2021/12/27 | 45731 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma
+2021/12/27 | 4570 | graphics/asymptote/env.h
+2021/12/27 | 45687 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
+2021/12/27 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
+2021/12/27 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
+2021/12/27 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
+2021/12/27 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
+2021/12/27 | 454 | graphics/asymptote/EXRFiles.h
+2021/12/27 | 45411 | graphics/asymptote/fftw++.h
+2021/12/27 | 4531 | graphics/asymptote/webgl/fragment.glsl
+2021/12/27 | 4520 | graphics/asymptote/getopt1.c
+2021/12/27 | 4514 | graphics/asymptote/bbox.h
+2021/12/27 | 450 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/threaded_queue.cpp
+2021/12/27 | 449 | graphics/asymptote/tests/arith/pair.asy
+2021/12/27 | 4487 | graphics/asymptote/base/plain_shipout.asy
+2021/12/27 | 4474 | graphics/asymptote/GUI/windows/widg_editBezier.ui
+2021/12/27 | 4471 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-3f1f642c3356fd8e8d2a0787613ec09a56572b3a1e38c9629b6db9e8dead1117_min
+2021/12/27 | 4465 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/example/mergesort/mergesort.cpp
+2021/12/27 | 4465 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/future.hpp
+2021/12/27 | 445 | graphics/asymptote/examples/sacone.asy
+2021/12/27 | 445 | graphics/asymptote/cudareflect/kernel.h
+2021/12/27 | 443 | graphics/asymptote/cudareflect/ReflectanceMapper.cuh
+2021/12/27 | 442 | graphics/asymptote/doc/join3.asy
+2021/12/27 | 441 | graphics/asymptote/examples/triangles.asy
+2021/12/27 | 441 | graphics/asymptote/doc/histogram.asy
+2021/12/27 | 43 | graphics/asymptote/examples/spring2.asy
+2021/12/27 | 439 | graphics/asymptote/examples/gamma.asy
+2021/12/27 | 4395 | graphics/asymptote/LspCpp/network/uri/detail/encode.hpp
+2021/12/27 | 43894 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
+2021/12/27 | 4384 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32OpenGLWindow.cpp
+2021/12/27 | 43809 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
+2021/12/27 | 437 | graphics/asymptote/cudareflect/tinyexr/Makefile.gcc-mingw
+2021/12/27 | 4371 | graphics/asymptote/cudareflect/kernel.cu
+2021/12/27 | 436 | graphics/asymptote/examples/colorpatch.asy
+2021/12/27 | 43683 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
+2021/12/27 | 4366 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/StreamMessageProducer.cpp
+2021/12/27 | 43639 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma
+2021/12/27 | 4348 | graphics/asymptote/doc/colo-asy.tex
+2021/12/27 | 4345 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/task_adaptors.hpp
+2021/12/27 | 4335 | graphics/asymptote/prc/PRCTools/describePRC.h
+2021/12/27 | 43335 | graphics/asymptote/examples/100d.pdb1
+2021/12/27 | 43275 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma
+2021/12/27 | 430 | graphics/asymptote/examples/unitoctant.asy
+2021/12/27 | 42 | graphics/asymptote/base/animate.asy
+2021/12/27 | 428 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/symbol.h
+2021/12/27 | 4286 | graphics/asymptote/asy.ico
+2021/12/27 | 4285 | graphics/asymptote/newexp.cc
+2021/12/27 | 427 | graphics/asymptote/examples/projectrevolution.asy
+2021/12/27 | 42767 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma
+2021/12/27 | 426 | graphics/asymptote/examples/pathintersectsurface.asy
+2021/12/27 | 426 | graphics/asymptote/doc/grid3xyz.asy
+2021/12/27 | 4265 | graphics/asymptote/LspCpp/LibLsp/lsp/symbol.h
+2021/12/27 | 4254 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/readme.md
+2021/12/27 | 424 | graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentIdentifier.h
+2021/12/27 | 424 | graphics/asymptote/examples/spiral3.asy
+2021/12/27 | 4244 | graphics/asymptote/examples/fin.asy
+2021/12/27 | 4242 | graphics/asymptote/tests/types/keyword.asy
+2021/12/27 | 423 | graphics/asymptote/doc/log2graph.asy
+2021/12/27 | 423 | graphics/asymptote/doc/helix.asy
+2021/12/27 | 422 | graphics/asymptote/v3dtypes.csv
+2021/12/27 | 42110 | graphics/asymptote/picture.cc
+2021/12/27 | 420 | graphics/asymptote/examples/PythagoreanTree.asy
+2021/12/27 | 4209 | graphics/asymptote/flatguide.h
+2021/12/27 | 41 | graphics/asymptote/doc/bigdiagonal.asy
+2021/12/27 | 41 | graphics/asymptote/cudareflect/tinyexr/jni/Application.mk
+2021/12/27 | 419 | graphics/asymptote/examples/torus.asy
+2021/12/27 | 4199 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/typeHierarchy.h
+2021/12/27 | 418 | graphics/asymptote/examples/planeproject.asy
+2021/12/27 | 417 | graphics/asymptote/doc/knots.asy
+2021/12/27 | 4172 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example6.c
+2021/12/27 | 416 | graphics/asymptote/doc/bezier2.asy
+2021/12/27 | 4166 | graphics/asymptote/GUI/windows/widgetPointEditor.ui
+2021/12/27 | 415 | graphics/asymptote/doc/linetype.asy
+2021/12/27 | 4158 | graphics/asymptote/examples/advection.asy
+2021/12/27 | 4156 | graphics/asymptote/runpair.in
+2021/12/27 | 41551 | fonts/newtx/README
+2021/12/27 | 414 | graphics/asymptote/examples/animations/glmovie.asy
+2021/12/27 | 41326 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma
+2021/12/27 | 41220 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
+2021/12/27 | 41203 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
+2021/12/27 | 411 | graphics/asymptote/examples/animations/externalmovie.asy
+2021/12/27 | 4118 | graphics/asymptote/LspCpp/LibLsp/lsp/lru_cache.h
+2021/12/27 | 4116 | graphics/asymptote/cudareflect/tinyexr/test/exrwrite/exrwritetest.cpp
+2021/12/27 | 410 | graphics/asymptote/examples/Sierpinski.asy
+2021/12/27 | 40899 | graphics/asymptote/doc/FAQ/asy-faq.bfnn
+2021/12/27 | 4088 | graphics/asymptote/base/plain_boxes.asy
+2021/12/27 | 4084 | graphics/asymptote/GUI/xasyFile.py
+2021/12/27 | 4083 | graphics/asymptote/LspCpp/network/uri/uri_builder.cpp
+2021/12/27 | 407 | graphics/asymptote/examples/parametricsurface.asy
+2021/12/27 | 407 | graphics/asymptote/examples/BezierPatch.asy
+2021/12/27 | 407 | graphics/asymptote/cudareflect/tinyexr/Makefile.gcc-mingw-msys
+2021/12/27 | 4072 | graphics/asymptote/tests/types/order.asy
+2021/12/27 | 4067 | graphics/asymptote/doc/diatom.csv
+2021/12/27 | 40665 | graphics/asymptote/examples/tvgen.asy
+2021/12/27 | 402268 | systems/texlive/tlnet/archive/texlive-scripts.doc.r61410.tar.xz
+2021/12/27 | 401 | graphics/asymptote/doc/image.asy
+2021/12/27 | 401 | graphics/asymptote/cudareflect/tinyexr/test/unit/README.md
+2021/12/27 | 400 | graphics/asymptote/examples/sacylinder.asy
+2021/12/27 | 400 | graphics/asymptote/cudareflect/tinyexr/test/unit/Makefile
+2021/12/27 | 4000 | fonts/newtx/tex/newtx.sty
+2021/12/27 | 39 | graphics/asymptote/base/nopapersize.ps
+2021/12/27 | 398 | graphics/asymptote/examples/epix.asy
+2021/12/27 | 39804 | graphics/asymptote/LspCpp/LspCpp.vcxproj
+2021/12/27 | 39745 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma
+2021/12/27 | 396 | graphics/asymptote/doc/triangulate.asy
+2021/12/27 | 396 | graphics/asymptote/doc/legend.asy
+2021/12/27 | 395 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/2by2.exr
+2021/12/27 | 39458 | graphics/asymptote/cudareflect/tinyexr/examples/common/cxxopts.hpp
+2021/12/27 | 394271 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
+2021/12/27 | 393 | graphics/asymptote/GUI/setup.py
+2021/12/27 | 3936 | graphics/asymptote/base/interpolate.asy
+2021/12/27 | 393676 | graphics/asymptote/doc/asymptote.texi
+2021/12/27 | 3917 | graphics/asymptote/LspCpp/LibLsp/lsp/Markup/Markup.h
+2021/12/27 | 3912 | graphics/asymptote/tr.h
+2021/12/27 | 390 | graphics/asymptote/doc/tile.asy
+2021/12/27 | 390080 | systems/texlive/tlnet/archive/termsim.doc.r61414.tar.xz
+2021/12/27 | 38 | graphics/asymptote/examples/spring0.asy
+2021/12/27 | 388 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/common.h
+2021/12/27 | 3860 | systems/texlive/tlnet/archive/termsim.r61414.tar.xz
+2021/12/27 | 3857 | graphics/asymptote/examples/pipes.asy
+2021/12/27 | 38542 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma
+2021/12/27 | 384 | graphics/asymptote/examples/RiemannSurfaceRoot.asy
+2021/12/27 | 384 | graphics/asymptote/Delaunay.h
+2021/12/27 | 38460 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma
+2021/12/27 | 383 | graphics/asymptote/tests/arith/real.asy
+2021/12/27 | 383 | graphics/asymptote/examples/Gouraud.asy
+2021/12/27 | 3834 | graphics/asymptote/LspCpp/LibLsp/lsp/lsp_diagnostic.h
+2021/12/27 | 382 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/buildWorkspace.h
+2021/12/27 | 382 | graphics/asymptote/doc/loggrid.asy
+2021/12/27 | 37991 | graphics/asymptote/path3.cc
+2021/12/27 | 3790199 | graphics/asymptote/cudareflect/tinyexr/examples/deepview/deepview_screencast.gif
+2021/12/27 | 378 | graphics/asymptote/examples/sinxlex.asy
+2021/12/27 | 378 | graphics/asymptote/doc/icon.asy
+2021/12/27 | 37783 | graphics/asymptote/exp.cc
+2021/12/27 | 376 | graphics/asymptote/examples/sphericalharmonic.asy
+2021/12/27 | 376 | graphics/asymptote/doc/generalaxis3.asy
+2021/12/27 | 376913 | graphics/asymptote/cudareflect/tinyexr/test/unit/catch.hpp
+2021/12/27 | 37685 | graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image_write.h
+2021/12/27 | 3765 | graphics/asymptote/prc/PRCdouble.h
+2021/12/27 | 374 | graphics/asymptote/doc/monthaxis.asy
+2021/12/27 | 373 | graphics/asymptote/examples/projectelevation.asy
+2021/12/27 | 373 | graphics/asymptote/doc/lineargraph.asy
+2021/12/27 | 3739 | graphics/asymptote/examples/xstitch.asy
+2021/12/27 | 3737 | graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindSanitizers.cmake
+2021/12/27 | 37374 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
+2021/12/27 | 3731 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/callHierarchy.h
+2021/12/27 | 3723 | graphics/asymptote/LspCpp/third_party/threadpool/CHANGE_LOG
+2021/12/27 | 3719 | graphics/asymptote/base/three_light.asy
+2021/12/27 | 37152 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma
+2021/12/27 | 37135 | graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/tiny_dng_writer.h
+2021/12/27 | 37092 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
+2021/12/27 | 3706 | graphics/asymptote/base/plain_constants.asy
+2021/12/27 | 369 | graphics/asymptote/tests/gs/ghostscript.asy
+2021/12/27 | 3676 | graphics/asymptote/constructor.cc
+2021/12/27 | 367149 | macros/latex/contrib/codebox.zip
+2021/12/27 | 366 | graphics/asymptote/doc/lineargraph0.asy
+2021/12/27 | 366 | graphics/asymptote/cudareflect/tinyexr.cc
+2021/12/27 | 3669 | graphics/asymptote/LspCpp/example/StdIOServerExample.cpp
+2021/12/27 | 36526 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.cpp
+2021/12/27 | 3640 | graphics/asymptote/bbox3.h
+2021/12/27 | 362 | graphics/asymptote/examples/pipeintersection.asy
+2021/12/27 | 36243 | graphics/asymptote/prc/test.cc
+2021/12/27 | 361 | graphics/asymptote/GUI/res/icons/anchor.svg
+2021/12/27 | 361 | graphics/asymptote/examples/phase.asy
+2021/12/27 | 3616 | graphics/asymptote/GUI/UndoRedoStack.py
+2021/12/27 | 361352 | systems/texlive/tlnet/archive/codebox.doc.r61415.tar.xz
+2021/12/27 | 360 | graphics/asymptote/examples/washer.asy
+2021/12/27 | 3608 | graphics/asymptote/GLTextures.h
+2021/12/27 | 36043 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma
+2021/12/27 | 3601 | graphics/asymptote/cudareflect/tinyexr/test/exrcat/exrcat.cpp
+2021/12/27 | 35 | graphics/asymptote/base/fontsize.asy
+2021/12/27 | 3596 | systems/texlive/tlnet/archive/codebox.r61415.tar.xz
+2021/12/27 | 3592 | graphics/asymptote/GUI/CustMatTransform.py
+2021/12/27 | 357 | graphics/asymptote/doc/irregularcontour.asy
+2021/12/27 | 355 | graphics/asymptote/doc/scaledgraph.asy
+2021/12/27 | 3556 | graphics/asymptote/build-scripts/build-asymptote.dos
+2021/12/27 | 354 | graphics/asymptote/doc/reloadpdf.tex
+2021/12/27 | 354 | graphics/asymptote/doc/planes.asy
+2021/12/27 | 354 | graphics/asymptote/base/pstoedit.asy
+2021/12/27 | 352 | graphics/asymptote/examples/cylinder.asy
+2021/12/27 | 35264 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
+2021/12/27 | 351 | graphics/asymptote/tinyexr.cc
+2021/12/27 | 351 | graphics/asymptote/examples/vectorfieldsphere.asy
+2021/12/27 | 35167 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
+2021/12/27 | 351559 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
+2021/12/27 | 35147 | graphics/asymptote/LICENSE
+2021/12/27 | 34 | graphics/asymptote/examples/teapotIBL.asy
+2021/12/27 | 34 | graphics/asymptote/autogen.sh
+2021/12/27 | 349 | graphics/asymptote/examples/logdown.asy
+2021/12/27 | 348 | graphics/asymptote/LspCpp/LibLsp/lsp/ParentProcessWatcher.h
+2021/12/27 | 348 | graphics/asymptote/examples/RiemannSurface.asy
+2021/12/27 | 3472 | graphics/asymptote/picture.h
+2021/12/27 | 3465 | graphics/asymptote/drawpath.cc
+2021/12/27 | 345 | graphics/asymptote/examples/rainbow.asy
+2021/12/27 | 34571 | macros/latex/contrib/codebox/codebox.dtx
+2021/12/27 | 3441 | graphics/asymptote/rounding.h
+2021/12/27 | 343 | graphics/asymptote/doc/externalprc.tex
+2021/12/27 | 34316 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/MacOpenGLWindow.mm
+2021/12/27 | 342 | graphics/asymptote/lexical.h
+2021/12/27 | 341 | graphics/asymptote/examples/slidedemo_.bbl
+2021/12/27 | 341 | graphics/asymptote/examples/sacylinder3D.asy
+2021/12/27 | 341 | graphics/asymptote/doc/subpictures.asy
+2021/12/27 | 3418 | graphics/asymptote/LspCpp/LibLsp/lsp/general/InitializeParams.h
+2021/12/27 | 34092 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
+2021/12/27 | 339 | graphics/asymptote/cudareflect/tinyexr/test/CMakeLists.txt
+2021/12/27 | 3391 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/signature_help.h
+2021/12/27 | 33813 | graphics/asymptote/path.cc
+2021/12/27 | 3375 | graphics/asymptote/tests/types/guide.asy
+2021/12/27 | 3374 | graphics/asymptote/base/roundedpath.asy
+2021/12/27 | 33677 | graphics/asymptote/LspCpp/LibLsp/lsp/Markup/Markup.cpp
+2021/12/27 | 335 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/tiled_half_1x1_alpha.exr
+2021/12/27 | 3358 | graphics/asymptote/examples/slidedemo.asy
+2021/12/27 | 333 | graphics/asymptote/doc/asy.1.end
+2021/12/27 | 3335 | graphics/asymptote/examples/pdb.asy
+2021/12/27 | 332375 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma
+2021/12/27 | 3306 | graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/cpp11.h
+2021/12/27 | 32 | graphics/asymptote/LspCpp/third_party/threadpool/Jamrules
+2021/12/27 | 32990 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma
+2021/12/27 | 3298 | graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/cpp17.h
+2021/12/27 | 3297 | graphics/asymptote/access.cc
+2021/12/27 | 3295 | graphics/asymptote/stack.h
+2021/12/27 | 3294 | graphics/asymptote/LspCpp/LibLsp/lsp/lsAny.h
+2021/12/27 | 3284 | graphics/asymptote/cudareflect/tinyexr/examples/deepview/trackball.h
+2021/12/27 | 327 | graphics/asymptote/examples/sin1x.asy
+2021/12/27 | 327 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/piz-bug-issue-100.exr
+2021/12/27 | 3278 | graphics/asymptote/base/obj.asy
+2021/12/27 | 3274 | macros/latex/contrib/codebox/README.md
+2021/12/27 | 326 | graphics/asymptote/examples/polardatagraph.asy
+2021/12/27 | 326 | graphics/asymptote/examples/animations/pdfmovie.asy
+2021/12/27 | 3267 | graphics/asymptote/GUI/Widg_addLabel.py
+2021/12/27 | 3265 | graphics/asymptote/program.cc
+2021/12/27 | 326387 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
+2021/12/27 | 325 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/listOverridableMethods.h
+2021/12/27 | 325 | graphics/asymptote/examples/elevation.asy
+2021/12/27 | 324 | graphics/asymptote/doc/HermiteSpline.asy
+2021/12/27 | 323 | graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/README.md
+2021/12/27 | 322 | graphics/asymptote/examples/unitcircle.asy
+2021/12/27 | 322 | graphics/asymptote/examples/cheese.asy
+2021/12/27 | 321 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/README
+2021/12/27 | 32155 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
+2021/12/27 | 320 | graphics/asymptote/runtriple.h
+2021/12/27 | 320 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/Move.h
+2021/12/27 | 320403 | graphics/asymptote/base/geometry.asy
+2021/12/27 | 31 | graphics/asymptote/cudareflect/tinyexr/test/unit/win32-filelist-utf8.inc
+2021/12/27 | 319 | graphics/asymptote/LspCpp/third_party/threadpool/Jamfile.v2
+2021/12/27 | 319839 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/miniz.c
+2021/12/27 | 318 | graphics/asymptote/patches/gcc3.3.2curses.patch
+2021/12/27 | 318734 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma
+2021/12/27 | 317 | graphics/asymptote/cudareflect/tinyexr/vcbuild.bat
+2021/12/27 | 316381 | info/kaytannollista-latexia/luku-rakenne.tex
+2021/12/27 | 3160 | graphics/asymptote/shaders.cc
+2021/12/27 | 31609 | graphics/asymptote/config.sub
+2021/12/27 | 315 | graphics/asymptote/examples/hyperboloid.asy
+2021/12/27 | 31578 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma
+2021/12/27 | 3153 | graphics/asymptote/genv.cc
+2021/12/27 | 31539 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
+2021/12/27 | 314 | graphics/asymptote/doc/logticks.asy
+2021/12/27 | 314 | graphics/asymptote/base/graph_settings.asy
+2021/12/27 | 31413 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma
+2021/12/27 | 3135 | graphics/asymptote/cudareflect/tinyexr/examples/exr2ldr/exr2ldr.cc
+2021/12/27 | 31342 | graphics/asymptote/builtin.cc
+2021/12/27 | 31333 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
+2021/12/27 | 312 | graphics/asymptote/examples/textpath.asy
+2021/12/27 | 3125 | graphics/asymptote/doc/latexusage.tex
+2021/12/27 | 3109 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example1.c
+2021/12/27 | 30 | info/kaytannollista-latexia/versio.tex
+2021/12/27 | 309 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/projectConfigurationUpdate.h
+2021/12/27 | 308 | graphics/asymptote/tests/types/shadow.asy
+2021/12/27 | 308 | graphics/asymptote/tests/Makefile
+2021/12/27 | 308 | graphics/asymptote/examples/oneoverx.asy
+2021/12/27 | 3072 | graphics/asymptote/LspCpp/network/uri/detail/grammar.hpp
+2021/12/27 | 306 | graphics/asymptote/doc/binarytreetest.asy
+2021/12/27 | 3065 | graphics/asymptote/jsfile.h
+2021/12/27 | 30640 | graphics/asymptote/LspCpp/macro_map.h
+2021/12/27 | 30569 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
+2021/12/27 | 3052 | graphics/asymptote/LspCpp/network/uri/detail/uri_parse_authority.cpp
+2021/12/27 | 3040 | graphics/asymptote/asymptote.spec
+2021/12/27 | 303 | graphics/asymptote/examples/tensor.asy
+2021/12/27 | 3036 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_cpp11.cpp
+2021/12/27 | 30307 | graphics/asymptote/exp.h
+2021/12/27 | 3024 | graphics/asymptote/drawimage.h
+2021/12/27 | 3023 | graphics/asymptote/doc/Makefile.in
+2021/12/27 | 30208 | graphics/asymptote/prc/PRC.h
+2021/12/27 | 301 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/organizeImports.h
+2021/12/27 | 30181 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma
+2021/12/27 | 30147 | graphics/asymptote/getopt.c
+2021/12/27 | 300 | graphics/asymptote/examples/strokepath.asy
+2021/12/27 | 3004 | graphics/asymptote/LspCpp/LibLsp/lsp/lsResponseError.h
+2021/12/27 | 299 | graphics/asymptote/runpair.h
+2021/12/27 | 298 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-5ace655ef080932dcc7e4abc9eab1d4f82c845453464993dfa3eb6c5822a1621
+2021/12/27 | 297 | graphics/asymptote/build-scripts/README-binaries
+2021/12/27 | 2979 | graphics/asymptote/doc/diatom.asy
+2021/12/27 | 2974 | graphics/asymptote/LspCpp/LibLsp/lsp/language/language.h
+2021/12/27 | 2968 | graphics/asymptote/material.h
+2021/12/27 | 2964 | graphics/asymptote/access.h
+2021/12/27 | 2960 | graphics/asymptote/GUI/pyUIClass/widg_addPolyOpt.py
+2021/12/27 | 295888 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
+2021/12/27 | 294 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/classFileContents.h
+2021/12/27 | 294 | graphics/asymptote/guideflags.h
+2021/12/27 | 294288 | info/mathalphabets.zip
+2021/12/27 | 2941 | graphics/asymptote/GUI/windows/widg_addPolyOpt.ui
+2021/12/27 | 293 | graphics/asymptote/doc/makepen.asy
+2021/12/27 | 2939 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/CommonWindowInterface.h
+2021/12/27 | 2930 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/stream.h
+2021/12/27 | 292060 | graphics/asymptote/configure
+2021/12/27 | 291 | graphics/asymptote/examples/trumpet.asy
+2021/12/27 | 2918 | graphics/asymptote/GUI/pyUIClass/setCustomAnchor.py
+2021/12/27 | 28 | graphics/asymptote/cudareflect/tinyexr/test/issues/160/requirements.txt
+2021/12/27 | 289 | macros/latex/contrib/codebox/build.sh
+2021/12/27 | 289 | graphics/asymptote/examples/jump.asy
+2021/12/27 | 289 | graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/README.md
+2021/12/27 | 289 | graphics/asymptote/base/res/notes.txt
+2021/12/27 | 288 | graphics/asymptote/examples/sacone3D.asy
+2021/12/27 | 288 | graphics/asymptote/doc/mexicanhat.asy
+2021/12/27 | 28894 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma
+2021/12/27 | 2880 | graphics/asymptote/LspCpp/LibLsp/lsp/ParentProcessWatcher.cpp
+2021/12/27 | 2880 | graphics/asymptote/drawgroup.h
+2021/12/27 | 28679 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma
+2021/12/27 | 286703 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
+2021/12/27 | 28545 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
+2021/12/27 | 285454 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma
+2021/12/27 | 284 | graphics/asymptote/GUI/res/icons/text.svg
+2021/12/27 | 2845 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/json.h
+2021/12/27 | 283 | graphics/asymptote/cudareflect/tinyexr/test/c-binding/test.c
+2021/12/27 | 28387 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma
+2021/12/27 | 28337 | graphics/asymptote/symbolmaps.h
+2021/12/27 | 2830 | graphics/asymptote/examples/alignedaxis.asy
+2021/12/27 | 2827 | graphics/asymptote/LspCpp/network/uri/detail/uri_resolve.cpp
+2021/12/27 | 282632 | info/mathalphabets/mathalphabets.pdf
+2021/12/27 | 281819 | macros/latex/contrib/codebox/codebox.pdf
+2021/12/27 | 2817 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/worker_thread.hpp
+2021/12/27 | 281441 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
+2021/12/27 | 2800 | graphics/asymptote/doc/asycolors.sty
+2021/12/27 | 279 | graphics/asymptote/LspCpp/third_party/threadpool/README
+2021/12/27 | 279 | graphics/asymptote/doc/hatch.asy
+2021/12/27 | 2798717 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
+2021/12/27 | 27856 | graphics/asymptote/pen.h
+2021/12/27 | 277 | graphics/asymptote/doc/generalaxis.asy
+2021/12/27 | 2772 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_common.c
+2021/12/27 | 27720 | systems/texlive/tlnet/archive/asmeconf.r61412.tar.xz
+2021/12/27 | 2771 | graphics/asymptote/doc/pixel.pdf
+2021/12/27 | 276 | graphics/asymptote/tests/bench/6000circles.asy
+2021/12/27 | 2766 | graphics/asymptote/lnkX64IconFix.nsh
+2021/12/27 | 27528 | graphics/asymptote/LspCpp/LibLsp/lsp/Markup/string_ref.h
+2021/12/27 | 2749 | graphics/asymptote/symbol.h
+2021/12/27 | 27473 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
+2021/12/27 | 2741 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/findOpenGLGlewGlut.lua
+2021/12/27 | 2732 | graphics/asymptote/record.h
+2021/12/27 | 2731 | graphics/asymptote/tests/types/resolve.asy
+2021/12/27 | 27261 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma
+2021/12/27 | 27243 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma
+2021/12/27 | 271 | graphics/asymptote/patches/gc6.8_AIX.patch
+2021/12/27 | 2707 | graphics/asymptote/settings.h
+2021/12/27 | 2707 | graphics/asymptote/runtriple.in
+2021/12/27 | 270497 | graphics/asymptote/cudareflect/tinyexr/tinyexr.h
+2021/12/27 | 26 | graphics/asymptote/doc/filegraph.dat
+2021/12/27 | 26 | graphics/asymptote/_config.yml
+2021/12/27 | 269 | graphics/asymptote/runmath.h
+2021/12/27 | 2697 | graphics/asymptote/table.h
+2021/12/27 | 268 | graphics/asymptote/base/asy-init.el
+2021/12/27 | 26844 | graphics/asymptote/runpath.cc
+2021/12/27 | 2680 | graphics/asymptote/examples/soccerball.asy
+2021/12/27 | 267 | graphics/asymptote/examples/hyperboloidsilhouette.asy
+2021/12/27 | 2675 | graphics/asymptote/LspCpp/LibLsp/lsp/ResourceOperation.h
+2021/12/27 | 2675 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example4.c
+2021/12/27 | 2675897 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma
+2021/12/27 | 2674 | graphics/asymptote/doc/markers1.asy
+2021/12/27 | 26693 | graphics/asymptote/dec.cc
+2021/12/27 | 2668 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/code_action.h
+2021/12/27 | 2661 | graphics/asymptote/runbacktrace.cc
+2021/12/27 | 2653 | graphics/asymptote/doc/TeXShopAndAsymptote.tex
+2021/12/27 | 264 | graphics/asymptote/examples/labelbox.asy
+2021/12/27 | 264 | graphics/asymptote/examples/coag.asy
+2021/12/27 | 2649 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/future.hpp
+2021/12/27 | 2643 | info/kaytannollista-latexia/luku-esipuhe.tex
+2021/12/27 | 2636 | graphics/asymptote/LspCpp/LibLsp/lsp/CodeActionParams.h
+2021/12/27 | 2632 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/semanticHighlighting.h
+2021/12/27 | 2631 | graphics/asymptote/GUI/windows/setCustomAnchor.ui
+2021/12/27 | 262 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/GCThreadContext.cpp
+2021/12/27 | 262 | graphics/asymptote/doc/loggraph.asy
+2021/12/27 | 2626 | graphics/asymptote/examples/worldmap.asy
+2021/12/27 | 2622 | info/kaytannollista-latexia/kirjallisuutta.bib
+2021/12/27 | 261 | graphics/asymptote/doc/join.asy
+2021/12/27 | 2614 | graphics/asymptote/pipestream.h
+2021/12/27 | 2613 | graphics/asymptote/base/patterns.asy
+2021/12/27 | 2611 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_cpp17.cpp
+2021/12/27 | 2609 | graphics/asymptote/LspCpp/network/uri/uri_errors.hpp
+2021/12/27 | 26096 | graphics/asymptote/examples/uhrturm.obj
+2021/12/27 | 2605 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/premake4.lua
+2021/12/27 | 260289 | graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image.h
+2021/12/27 | 25 | graphics/asymptote/cudareflect/tinyexr/experimental/js/Makefile
+2021/12/27 | 2598 | graphics/asymptote/cudareflect/simpson.cuh
+2021/12/27 | 259275 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma
+2021/12/27 | 25701 | graphics/asymptote/runpath3d.cc
+2021/12/27 | 256 | graphics/asymptote/doc/shadedtiling.asy
+2021/12/27 | 256910 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
+2021/12/27 | 256830 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
+2021/12/27 | 25671 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma
+2021/12/27 | 25631622 | systems/texlive/tlnet/install-tl.zip
+2021/12/27 | 2561 | graphics/asymptote/program.h
+2021/12/27 | 256199 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma
+2021/12/27 | 2557 | graphics/asymptote/abs3doutfile.h
+2021/12/27 | 2555 | graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindTSan.cmake
+2021/12/27 | 2554 | graphics/asymptote/cudareflect/tinyexr/examples/ldr2exr/ldr2exr.cc
+2021/12/27 | 254 | graphics/asymptote/examples/parametricelevation.asy
+2021/12/27 | 254 | graphics/asymptote/examples/contextfonts.asy
+2021/12/27 | 25452 | graphics/asymptote/LspCpp/LspCpp.vcxproj.filters
+2021/12/27 | 2543 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32Window.h
+2021/12/27 | 2542 | graphics/asymptote/policy.h
+2021/12/27 | 25357 | graphics/asymptote/base/lmfit.asy
+2021/12/27 | 25325 | graphics/asymptote/bezierpatch.cc
+2021/12/27 | 2524 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/completion.h
+2021/12/27 | 251 | graphics/asymptote/examples/triceratops.asy
+2021/12/27 | 251 | graphics/asymptote/base/metapost.asy
+2021/12/27 | 2518 | graphics/asymptote/prc/PRCbitStream.h
+2021/12/27 | 25154 | graphics/asymptote/doc/extra/intro.asy
+2021/12/27 | 2514 | graphics/asymptote/LspCpp/LibLsp/lsp/lsTextEdit.h
+2021/12/27 | 2514 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/MacOpenGLWindow.h
+2021/12/27 | 2514 | graphics/asymptote/cudareflect/EXRFiles.cc
+2021/12/27 | 25134 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma
+2021/12/27 | 251066 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma
+2021/12/27 | 250 | graphics/asymptote/examples/transparentCubes.asy
+2021/12/27 | 25094 | graphics/asymptote/drawsurface.cc
+2021/12/27 | 25061 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
+2021/12/27 | 2505 | graphics/asymptote/README
+2021/12/27 | 2505 | graphics/asymptote/binaries/x86_64-windows/README
+2021/12/27 | 2505 | graphics/asymptote/binaries/i386-windows/README
+2021/12/27 | 2504 | graphics/asymptote/examples/mosquito.asy
+2021/12/27 | 24 | graphics/asymptote/doc/diagonal.asy
+2021/12/27 | 2492 | graphics/asymptote/base/three_margins.asy
+2021/12/27 | 248 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/exr-io.h
+2021/12/27 | 2484 | graphics/asymptote/build-scripts/build-asymptote
+2021/12/27 | 2482 | graphics/asymptote/LspCpp/LibLsp/lsp/lsWorkspaceEdit.h
+2021/12/27 | 2479 | graphics/asymptote/cudareflect/tinyexr/CMakeLists.txt
+2021/12/27 | 24784 | graphics/asymptote/symbolmaps.cc
+2021/12/27 | 2477 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/SConstruct
+2021/12/27 | 246 | graphics/asymptote/doc/axis3.asy
+2021/12/27 | 245 | graphics/asymptote/examples/alignbox.asy
+2021/12/27 | 2451 | graphics/asymptote/base/labelpath3.asy
+2021/12/27 | 244 | graphics/asymptote/tests/arith/triple.asy
+2021/12/27 | 244964 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
+2021/12/27 | 2445 | graphics/asymptote/GUI/PrimitiveShape.py
+2021/12/27 | 243 | graphics/asymptote/doc/cube.asy
+2021/12/27 | 242 | graphics/asymptote/examples/equilateral.asy
+2021/12/27 | 242 | graphics/asymptote/cudareflect/tinyexr/appveyor.yml
+2021/12/27 | 242 | graphics/asymptote/BUGS
+2021/12/27 | 2424 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/WebSocketServer.h
+2021/12/27 | 241 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageProducer.h
+2021/12/27 | 241 | graphics/asymptote/cudareflect/common.h
+2021/12/27 | 24153 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
+2021/12/27 | 240 | graphics/asymptote/doc/parametricgraph.asy
+2021/12/27 | 23 | graphics/asymptote/GUI/__init__.py
+2021/12/27 | 2398 | graphics/asymptote/examples/SierpinskiSponge.asy
+2021/12/27 | 2396 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/size_policies.hpp
+2021/12/27 | 23933 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
+2021/12/27 | 23904 | graphics/asymptote/process.cc
+2021/12/27 | 238 | graphics/asymptote/tests/TestLib.asy
+2021/12/27 | 238 | graphics/asymptote/GUI/xasyValidator.py
+2021/12/27 | 238 | graphics/asymptote/doc/filegraph.asy
+2021/12/27 | 2378 | graphics/asymptote/profile.py
+2021/12/27 | 23717 | graphics/asymptote/base/three_arrows.asy
+2021/12/27 | 236 | graphics/asymptote/tests/string/erase.asy
+2021/12/27 | 236 | graphics/asymptote/LspCpp/LibLsp/lsp/Directory.h
+2021/12/27 | 236 | graphics/asymptote/examples/annotation.asy
+2021/12/27 | 23682714 | graphics/asymptote.zip
+2021/12/27 | 23679 | graphics/asymptote/drawsurface.h
+2021/12/27 | 2362 | graphics/asymptote/examples/spectrum.asy
+2021/12/27 | 235 | graphics/asymptote/examples/cos2theta.asy
+2021/12/27 | 235 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/shader.frag
+2021/12/27 | 234 | graphics/asymptote/doc/beziercurve.asy
+2021/12/27 | 2341 | graphics/asymptote/prc/PRCTools/iPRCFile.h
+2021/12/27 | 233 | graphics/asymptote/examples/cardioid.asy
+2021/12/27 | 2336164 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
+2021/12/27 | 2328 | graphics/asymptote/virtualfieldaccess.h
+2021/12/27 | 23274 | graphics/asymptote/LspCpp/LibLsp/lsp/lsp.cpp
+2021/12/27 | 23205 | graphics/asymptote/LspCpp/LibLsp/lsp/ProtocolJsonHandler.cpp
+2021/12/27 | 2315 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/test/compile_all/compile_all.cpp
+2021/12/27 | 2310 | graphics/asymptote/base/plain_margins.asy
+2021/12/27 | 22 | graphics/asymptote/tests/output/line.asy
+2021/12/27 | 22 | graphics/asymptote/GUI/configs/__init__.py
+2021/12/27 | 229 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/WorkspaceSymbolParams.h
+2021/12/27 | 22946 | graphics/asymptote/base/syzygy.asy
+2021/12/27 | 2292 | graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindMSan.cmake
+2021/12/27 | 228 | graphics/asymptote/examples/circumcircle.asy
+2021/12/27 | 22873 | graphics/asymptote/examples/piicon.png
+2021/12/27 | 2279 | graphics/asymptote/errormsg.cc
+2021/12/27 | 2277 | graphics/asymptote/base/texcolors.asy
+2021/12/27 | 2276 | graphics/asymptote/prc/PRCTools/inflation.cc
+2021/12/27 | 2272 | graphics/asymptote/cudareflect/tinyexr/examples/rgbe2exr/rgbe2exr.cc
+2021/12/27 | 2266 | graphics/asymptote/align.h
+2021/12/27 | 2259 | graphics/asymptote/LspCpp/network/uri/detail/uri_normalize.cpp
+2021/12/27 | 22594 | graphics/asymptote/base/plain_arrows.asy
+2021/12/27 | 2257 | graphics/asymptote/LspCpp/LibLsp/lsp/windows/MessageNotify.h
+2021/12/27 | 22502 | graphics/asymptote/LspCpp/LibLsp/lsp/general/lsTextDocumentClientCapabilities.h
+2021/12/27 | 224 | graphics/asymptote/tests/types/init.asy
+2021/12/27 | 223 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveCodeLens.h
+2021/12/27 | 223 | graphics/asymptote/cudareflect/tinyexr/jni/Android.mk
+2021/12/27 | 22345 | graphics/asymptote/knot.cc
+2021/12/27 | 222 | graphics/asymptote/wce
+2021/12/27 | 222 | graphics/asymptote/examples/yingyang.asy
+2021/12/27 | 2222 | graphics/asymptote/tests/frames/loop.asy
+2021/12/27 | 221 | graphics/asymptote/LspCpp/third_party/threadpool/COPYING
+2021/12/27 | 22178 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma
+2021/12/27 | 2207 | graphics/asymptote/build-scripts/HOWTO-MSWindows
+2021/12/27 | 219 | graphics/asymptote/doc/penimage.asy
+2021/12/27 | 219 | graphics/asymptote/doc/graphwithderiv.asy
+2021/12/27 | 2194 | graphics/asymptote/locate.cc
+2021/12/27 | 21926 | graphics/asymptote/runmath.cc
+2021/12/27 | 2191 | graphics/asymptote/examples/splitpatch.asy
+2021/12/27 | 218 | graphics/asymptote/doc/datagraph.asy
+2021/12/27 | 2187 | graphics/asymptote/common.h
+2021/12/27 | 2187 | graphics/asymptote/base/plain_debugger.asy
+2021/12/27 | 21807 | graphics/asymptote/LspCpp/network/uri/uri.hpp
+2021/12/27 | 217 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/GCThreadContext.h
+2021/12/27 | 2176 | graphics/asymptote/LspCpp/network/uri/detail/uri_advance_parts.cpp
+2021/12/27 | 2164 | graphics/asymptote/frame.h
+2021/12/27 | 215852 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
+2021/12/27 | 2151 | graphics/asymptote/LspCpp/network/uri/detail/translate.hpp
+2021/12/27 | 2149 | graphics/asymptote/LspCpp/LibLsp/lsp/working_files.h
+2021/12/27 | 21481 | graphics/asymptote/lspserv.cc
+2021/12/27 | 2144 | graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindASan.cmake
+2021/12/27 | 21448 | graphics/asymptote/base/feynman.asy
+2021/12/27 | 2143 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/negative.cpp
+2021/12/27 | 21382 | graphics/asymptote/fileio.h
+2021/12/27 | 21373 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma
+2021/12/27 | 2136 | graphics/asymptote/seconds.h
+2021/12/27 | 2134 | graphics/asymptote/drawlabel.h
+2021/12/27 | 213457 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
+2021/12/27 | 2123 | graphics/asymptote/LspCpp/third_party/utfcpp/samples/docsample.cpp
+2021/12/27 | 2122 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageJsonHandler.h
+2021/12/27 | 210 | graphics/asymptote/examples/spiral.asy
+2021/12/27 | 210 | graphics/asymptote/build-scripts/asy-indent.el
+2021/12/27 | 2109 | graphics/asymptote/base/drawtree.asy
+2021/12/27 | 2104 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/getRefactorEdit.h
+2021/12/27 | 2101 | graphics/asymptote/examples/truncatedIcosahedron.asy
+2021/12/27 | 209935 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma
+2021/12/27 | 2098 | graphics/asymptote/LspCpp/network/uri/detail/algorithm.hpp
+2021/12/27 | 20989 | graphics/asymptote/base/plain_bounds.asy
+2021/12/27 | 2088 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/locking_ptr.hpp
+2021/12/27 | 20871137 | systems/texlive/tlnet/install-tl-windows.exe
+2021/12/27 | 20829 | graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-77-heap-buffer-overflow
+2021/12/27 | 208085 | graphics/asymptote/asy.list
+2021/12/27 | 207 | graphics/asymptote/examples/triangle.asy
+2021/12/27 | 20779 | info/kaytannollista-latexia/luku-erikoiset.tex
+2021/12/27 | 2073 | graphics/asymptote/LspCpp/network/uri/detail/uri_parts.hpp
+2021/12/27 | 206 | graphics/asymptote/examples/log.asy
+2021/12/27 | 206973 | graphics/asymptote/doc/asy-latex.pdf
+2021/12/27 | 20634 | info/kaytannollista-latexia/luku-valmistautuminen.tex
+2021/12/27 | 20633 | graphics/asymptote/runtime.in
+2021/12/27 | 2054 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/message.cpp
+2021/12/27 | 205495 | graphics/asymptote/base/colormap.asy
+2021/12/27 | 2040 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.h
+2021/12/27 | 203 | graphics/asymptote/LspCpp/LibLsp/lsp/general/exit.h
+2021/12/27 | 2034 | graphics/asymptote/doc/elliptic.asy
+2021/12/27 | 2031 | graphics/asymptote/base/slopefield.asy
+2021/12/27 | 203081 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
+2021/12/27 | 202 | graphics/asymptote/tests/frames/stat2.asy
+2021/12/27 | 202 | graphics/asymptote/glew.c
+2021/12/27 | 202 | graphics/asymptote/doc/exp.asy
+2021/12/27 | 202 | graphics/asymptote/build-scripts/run-in-indent.el
+2021/12/27 | 202947 | graphics/asymptote/cudareflect/tinyexr/asakusa.png
+2021/12/27 | 20277 | graphics/asymptote/base/contour.asy
+2021/12/27 | 2023 | graphics/asymptote/examples/slope.asy
+2021/12/27 | 202238 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
+2021/12/27 | 20190 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma
+2021/12/27 | 2012 | graphics/asymptote/varinit.h
+2021/12/27 | 2012707 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
+2021/12/27 | 2011 | graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/asan-wrapper
+2021/12/27 | 20090 | graphics/asymptote/runpicture.in
+2021/12/27 | 20051 | graphics/asymptote/doc/asyRefCard.tex
+2021/12/27 | 2004 | graphics/asymptote/varinit.cc
+2021/12/27 | 2002 | graphics/asymptote/LspCpp/network/uri/uri_errors.cpp
+2021/12/27 | 20029 | graphics/asymptote/camp.y
+2021/12/27 | 200141 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma
+2021/12/27 | 20010 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_data/utf8_invalid.txt
+2021/12/27 | 2000 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/pool_adaptors.hpp
+2021/12/27 | 199 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/test/compile_all/Jamfile.v2
+2021/12/27 | 199 | graphics/asymptote/examples/upint.asy
+2021/12/27 | 199 | graphics/asymptote/examples/BezierTriangle.asy
+2021/12/27 | 199836 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma
+2021/12/27 | 199112 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma
+2021/12/27 | 198 | graphics/asymptote/examples/tanh.asy
+2021/12/27 | 198823 | graphics/asymptote/doc/CAD.pdf
+2021/12/27 | 1982 | graphics/asymptote/inst.h
+2021/12/27 | 1975 | graphics/asymptote/array.h
+2021/12/27 | 197374 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma
+2021/12/27 | 196 | graphics/asymptote/examples/lowint.asy
+2021/12/27 | 196 | graphics/asymptote/examples/label3ribbon.asy
+2021/12/27 | 196 | graphics/asymptote/examples/animations/embeddedu3d.asy
+2021/12/27 | 1968 | graphics/asymptote/examples/mergeExample.asy
+2021/12/27 | 196120 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
+2021/12/27 | 195 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/example/mergesort/Jamfile.v2
+2021/12/27 | 19597 | graphics/asymptote/doc/external-proposal.html
+2021/12/27 | 1957 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/shutdown_policies.hpp
+2021/12/27 | 1955 | graphics/asymptote/cudareflect/tinyexr/experimental/js/binding.cc
+2021/12/27 | 1950 | graphics/asymptote/cudareflect/utils.cuh
+2021/12/27 | 1950 | graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/testmapgen.cc
+2021/12/27 | 194 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/Jamfile.v2
+2021/12/27 | 19462 | graphics/asymptote/patches/gl-matrix-2.4.0-pruned.patch
+2021/12/27 | 193 | graphics/asymptote/tests/gc/shipout.asy
+2021/12/27 | 193 | graphics/asymptote/tests/arith/random.asy
+2021/12/27 | 193 | graphics/asymptote/base/shaders/offset.glsl
+2021/12/27 | 1936 | graphics/asymptote/refaccess.h
+2021/12/27 | 1927 | graphics/asymptote/tests/array/fields.asy
+2021/12/27 | 1927 | graphics/asymptote/prc/PRCTools/bitSearchDouble.cc
+2021/12/27 | 1924 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/willSave.h
+2021/12/27 | 1920 | graphics/asymptote/GUI/res/icons/social-python.svg
+2021/12/27 | 191 | graphics/asymptote/runpicture.h
+2021/12/27 | 1919 | graphics/asymptote/examples/animations/earthmoon.asy
+2021/12/27 | 1918 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/sct.h
+2021/12/27 | 19130 | fonts/newtx/tex/newtxtext.sty
+2021/12/27 | 1910 | graphics/asymptote/examples/linearregression.asy
+2021/12/27 | 19107 | graphics/asymptote/psfile.cc
+2021/12/27 | 190 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/tutorial/Jamfile.v2
+2021/12/27 | 190044 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/DroidSans.ttf
+2021/12/27 | 18 | graphics/asymptote/tests/output/circle.asy
+2021/12/27 | 189 | graphics/asymptote/cudareflect/tinyexr/examples/exr2ldr/Makefile
+2021/12/27 | 18994 | graphics/asymptote/LspCpp/LibLsp/lsp/general/lsServerCapabilities.h
+2021/12/27 | 18991 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32Window.cpp
+2021/12/27 | 1898 | graphics/asymptote/LspCpp/network/uri/detail/decode.hpp
+2021/12/27 | 1896 | graphics/asymptote/cudareflect/tinyexr/config-msvc.py
+2021/12/27 | 188 | graphics/asymptote/runstring.h
+2021/12/27 | 188 | graphics/asymptote/examples/transparency.asy
+2021/12/27 | 188 | graphics/asymptote/cudareflect/tinyexr/examples/resize/Makefile
+2021/12/27 | 1884 | graphics/asymptote/GUI/res/icons/filledbucket.svg
+2021/12/27 | 187 | graphics/asymptote/tests/string/rfind.asy
+2021/12/27 | 187 | graphics/asymptote/examples/label3solid.asy
+2021/12/27 | 187 | graphics/asymptote/base/shaders/count.glsl
+2021/12/27 | 1876 | graphics/asymptote/cc-mode2.el
+2021/12/27 | 18739 | graphics/asymptote/runstring.cc
+2021/12/27 | 186 | graphics/asymptote/runpath3d.h
+2021/12/27 | 186 | graphics/asymptote/doc/unitcircle3.asy
+2021/12/27 | 186 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/shader.vert
+2021/12/27 | 18659 | graphics/asymptote/texfile.cc
+2021/12/27 | 1863 | graphics/asymptote/prc/PRCTools/bitSearchUI.cc
+2021/12/27 | 1860 | graphics/asymptote/prc/PRCTools/bitData.h
+2021/12/27 | 185 | graphics/asymptote/cudareflect/tinyexr/test/fuzzer/README.md
+2021/12/27 | 18578 | graphics/asymptote/application.cc
+2021/12/27 | 1851 | graphics/asymptote/drawclipbegin.h
+2021/12/27 | 184 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/index.html
+2021/12/27 | 184 | graphics/asymptote/examples/roll.asy
+2021/12/27 | 18486 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
+2021/12/27 | 183 | graphics/asymptote/build-scripts/cc-indent.el
+2021/12/27 | 18396 | graphics/asymptote/LspCpp/network/uri/uri.cpp
+2021/12/27 | 18371 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
+2021/12/27 | 1835 | graphics/asymptote/examples/cyclohexane.asy
+2021/12/27 | 1831 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/documentColor.h
+2021/12/27 | 182 | graphics/asymptote/tests/string/find.asy
+2021/12/27 | 182 | graphics/asymptote/examples/label3.asy
+2021/12/27 | 1828 | graphics/asymptote/beziercurve.cc
+2021/12/27 | 181558 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma
+2021/12/27 | 1814 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/document_symbol.h
+2021/12/27 | 181466 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
+2021/12/27 | 1813 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/OpenGLInclude.h
+2021/12/27 | 18101 | graphics/asymptote/doc/asy-latex.dtx
+2021/12/27 | 1808 | graphics/asymptote/LspCpp/LibLsp/lsp/location_type.h
+2021/12/27 | 1808 | graphics/asymptote/GUI/res/icons.qrc
+2021/12/27 | 1805 | graphics/asymptote/patches/cygwin_freeglut-3.0.0.patch
+2021/12/27 | 18000 | systems/texlive/tlnet/archive/easybook.source.r61413.tar.xz
+2021/12/27 | 17987 | graphics/asymptote/entry.cc
+2021/12/27 | 179707 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma
+2021/12/27 | 17960 | systems/texlive/tlnet/archive/easybook.r61413.tar.xz
+2021/12/27 | 17902 | graphics/asymptote/asy-keywords.el
+2021/12/27 | 178 | graphics/asymptote/fftw++asy.cc
+2021/12/27 | 1787 | graphics/asymptote/LspCpp/network/uri/detail/uri_percent_encode.hpp
+2021/12/27 | 17860 | graphics/asymptote/LspCpp/LspCpp.filters
+2021/12/27 | 177 | graphics/asymptote/runpath.h
+2021/12/27 | 177 | graphics/asymptote/examples/curvedlabel.asy
+2021/12/27 | 17798 | graphics/asymptote/runfile.cc
+2021/12/27 | 1778 | graphics/asymptote/examples/conicurv.asy
+2021/12/27 | 1774 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/RequestInMessage.h
+2021/12/27 | 17734 | graphics/asymptote/dec.h
+2021/12/27 | 177246 | graphics/asymptote/prc/PRCdouble.cc
+2021/12/27 | 176 | graphics/asymptote/LspCpp/LibLsp/lsp/ProtocolJsonHandler.h
+2021/12/27 | 176 | graphics/asymptote/base/shaders/count0.glsl
+2021/12/27 | 1765 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/ScopeExit.h
+2021/12/27 | 1765 | graphics/asymptote/base/shaders/blend.glsl
+2021/12/27 | 1764 | graphics/asymptote/GUI/res/icons/grid.svg
+2021/12/27 | 17614 | graphics/asymptote/cudareflect/tinyexr/README.md
+2021/12/27 | 1760 | graphics/asymptote/examples/animations/heatequation.asy
+2021/12/27 | 175 | graphics/asymptote/examples/strokeshade.asy
+2021/12/27 | 1753 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32OpenGLWindow.h
+2021/12/27 | 1751 | graphics/asymptote/GUI/GuidesManager.py
+2021/12/27 | 174 | graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/Makefile
+2021/12/27 | 1746 | graphics/asymptote/doc/westnile.asy
+2021/12/27 | 173 | graphics/asymptote/cudareflect/tinyexr/test/c-binding/Makefile
+2021/12/27 | 173 | graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/Makefile
+2021/12/27 | 1734 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/CMakeLists.txt
+2021/12/27 | 17346 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_win.cpp
+2021/12/27 | 1733 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/include/nfd.h
+2021/12/27 | 1732474 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma
+2021/12/27 | 1728 | graphics/asymptote/webgl/vertex.glsl
+2021/12/27 | 172344 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
+2021/12/27 | 1710 | graphics/asymptote/tests/arith/roots.asy
+2021/12/27 | 1710 | graphics/asymptote/LspCpp/network/uri/uri_io.hpp
+2021/12/27 | 17060982 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
+2021/12/27 | 169 | graphics/asymptote/runbacktrace.h
+2021/12/27 | 1698 | graphics/asymptote/record.cc
+2021/12/27 | 1696 | graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindUBSan.cmake
+2021/12/27 | 1694 | graphics/asymptote/fftw++.cc
+2021/12/27 | 168 | graphics/asymptote/examples/lines.asy
+2021/12/27 | 1688 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/SConstruct
+2021/12/27 | 168850 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
+2021/12/27 | 16878 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/RemoteEndPoint.cpp
+2021/12/27 | 167 | graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/Makefile
+2021/12/27 | 1673 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/getMoveDestinations.h
+2021/12/27 | 16705 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/ChangeLog.md
+2021/12/27 | 1665 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/foldingRange.h
+2021/12/27 | 1665 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/Endpoint.h
+2021/12/27 | 1661 | graphics/asymptote/LspCpp/LibLsp/lsp/lsp_diagnostic.cpp
+2021/12/27 | 165 | graphics/asymptote/LspCpp/LspCpp.vcxproj.user
+2021/12/27 | 165 | graphics/asymptote/LspCpp/LspCpp.user
+2021/12/27 | 1658 | graphics/asymptote/prc/PRCTools/Makefile
+2021/12/27 | 1658 | graphics/asymptote/GUI/Widg_editBezier.py
+2021/12/27 | 16566 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma
+2021/12/27 | 16523 | graphics/asymptote/configure.ac
+2021/12/27 | 16521 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma
+2021/12/27 | 16492 | graphics/asymptote/base/plain_Label.asy
+2021/12/27 | 1648 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/OpenGL2Include.h
+2021/12/27 | 16483 | graphics/asymptote/runpair.cc
+2021/12/27 | 16421 | graphics/asymptote/LspCpp/network/optional.hpp
+2021/12/27 | 1640 | graphics/asymptote/callable.h
+2021/12/27 | 163 | graphics/asymptote/examples/1overx.asy
+2021/12/27 | 1630 | graphics/asymptote/builtin.h
+2021/12/27 | 162 | graphics/asymptote/examples/stereoscopic.asy
+2021/12/27 | 162 | graphics/asymptote/examples/sphereskeleton.asy
+2021/12/27 | 1626 | graphics/asymptote/genv.h
+2021/12/27 | 16226 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/sct.cpp
+2021/12/27 | 1620 | graphics/asymptote/doc/colors.asy
+2021/12/27 | 161 | graphics/asymptote/runhistory.h
+2021/12/27 | 161 | graphics/asymptote/cudareflect/tinyexr/examples/exr2rgbe/Makefile
+2021/12/27 | 16188 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_win8.png
+2021/12/27 | 1617 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/hover.h
+2021/12/27 | 1615 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/colorPresentation.h
+2021/12/27 | 1612 | graphics/asymptote/asy-list.pl
+2021/12/27 | 160 | graphics/asymptote/cudareflect/tinyexr/jni/Makefile
+2021/12/27 | 16089 | graphics/asymptote/base/slide.asy
+2021/12/27 | 160672 | graphics/asymptote/examples/animations/dice.u3d
+2021/12/27 | 1600 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/lsResponseMessage.h
+2021/12/27 | 15 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-efe9007bfdcbbe8a1569bf01fa9acadb8261ead49cb83f6e91fcdc4dae2e99a3_min
+2021/12/27 | 15 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-df76d1f27adb8927a1446a603028272140905c168a336128465a1162ec7af270.mini
+2021/12/27 | 159 | graphics/asymptote/tests/types/cast.asy
+2021/12/27 | 159 | graphics/asymptote/cudareflect/tinyexr/examples/rgbe2exr/Makefile
+2021/12/27 | 1597 | graphics/asymptote/v3dheadertypes.py
+2021/12/27 | 1594 | graphics/asymptote/pen.cc
+2021/12/27 | 158 | graphics/asymptote/tests/frames/stat.asy
+2021/12/27 | 15895 | graphics/asymptote/GUI/InplaceAddObj.py
+2021/12/27 | 1588 | graphics/asymptote/build-scripts/asy-format.el
+2021/12/27 | 15833 | graphics/asymptote/runlabel.cc
+2021/12/27 | 157 | graphics/asymptote/runsystem.h
+2021/12/27 | 157 | graphics/asymptote/doc/saddle.asy
+2021/12/27 | 157 | graphics/asymptote/cudareflect/tinyexr/examples/ldr2exr/Makefile
+2021/12/27 | 1578 | graphics/asymptote/build-scripts/cc-format.el
+2021/12/27 | 1577303 | graphics/asymptote/ChangeLog
+2021/12/27 | 157440 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma
+2021/12/27 | 1567 | graphics/asymptote/LspCpp/LibLsp/lsp/client/registerCapability.h
+2021/12/27 | 1566 | graphics/asymptote/examples/near_earth.asy
+2021/12/27 | 15645 | graphics/asymptote/install-sh
+2021/12/27 | 15617 | graphics/asymptote/cudareflect/tinyexr/test_tinyexr.cc
+2021/12/27 | 15601 | graphics/asymptote/base/ode.asy
+2021/12/27 | 155 | graphics/asymptote/tests/types/ecast.asy
+2021/12/27 | 1552 | graphics/asymptote/examples/NURBSsurface.asy
+2021/12/27 | 155285 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
+2021/12/27 | 15516 | graphics/asymptote/LspCpp/LibLsp/lsp/utils.cpp
+2021/12/27 | 155069 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/issue-160-piz-decode.exr
+2021/12/27 | 154 | graphics/asymptote/examples/billboard.asy
+2021/12/27 | 154 | graphics/asymptote/doc/slopefield1.asy
+2021/12/27 | 1548 | graphics/asymptote/examples/BezierSurface.asy
+2021/12/27 | 1548 | graphics/asymptote/cudareflect/tinyexr/test/issues/160/main.py
+2021/12/27 | 15460 | info/kaytannollista-latexia/kaytannollista-latexia.tex
+2021/12/27 | 15451 | graphics/asymptote/types.h
+2021/12/27 | 1542 | graphics/asymptote/GUI/xasyUtils.py
+2021/12/27 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
+2021/12/27 | 153 | graphics/asymptote/runlabel.h
+2021/12/27 | 1537 | graphics/asymptote/examples/refs.bib
+2021/12/27 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
+2021/12/27 | 15277 | graphics/asymptote/base/flowchart.asy
+2021/12/27 | 1524 | graphics/asymptote/patches/flex.patch
+2021/12/27 | 1521 | graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8.h
+2021/12/27 | 152105 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma
+2021/12/27 | 150 | graphics/asymptote/examples/spheresilhouette.asy
+2021/12/27 | 150 | graphics/asymptote/doc/latexmkrc_asydir
+2021/12/27 | 15018 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/main.cc
+2021/12/27 | 1498 | graphics/asymptote/examples/animations/wavepacket.asy
+2021/12/27 | 14982 | graphics/asymptote/base/palette.asy
+2021/12/27 | 1497476 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
+2021/12/27 | 1493 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_change.h
+2021/12/27 | 1492 | graphics/asymptote/runarray.h
+2021/12/27 | 1482 | graphics/asymptote/GUI/res/icons/android-hand.svg
+2021/12/27 | 147 | graphics/asymptote/doc/vectorfield.asy
+2021/12/27 | 1479 | graphics/asymptote/prc/PRCTools/inflationMain.cc
+2021/12/27 | 14795 | graphics/asymptote/stm.cc
+2021/12/27 | 1475 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/NotificationInMessage.h
+2021/12/27 | 14758 | graphics/asymptote/base/v3d.asy
+2021/12/27 | 14749 | graphics/asymptote/base/contour3.asy
+2021/12/27 | 146 | graphics/asymptote/cudareflect/tinyexr/examples/deepview/Makefile
+2021/12/27 | 1469 | graphics/asymptote/doc/png/Makefile.in
+2021/12/27 | 1461 | graphics/asymptote/examples/logo3.asy
+2021/12/27 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
+2021/12/27 | 145 | graphics/asymptote/examples/star.asy
+2021/12/27 | 1453400 | systems/texlive/tlnet/archive/asmeconf.doc.r61412.tar.xz
+2021/12/27 | 14532 | graphics/asymptote/stack.cc
+2021/12/27 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
+2021/12/27 | 144 | graphics/asymptote/doc/latexmkrc
+2021/12/27 | 1449 | graphics/asymptote/GUI/SetCustomAnchor.py
+2021/12/27 | 1447743 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
+2021/12/27 | 14418 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
+2021/12/27 | 1440 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/selectionRange.h
+2021/12/27 | 143 | graphics/asymptote/tests/gc/label.asy
+2021/12/27 | 14378 | graphics/asymptote/examples/teapot.asy
+2021/12/27 | 1436 | graphics/asymptote/GUI/res/icons/bucket.svg
+2021/12/27 | 14283 | graphics/asymptote/testv3d.asy
+2021/12/27 | 141 | graphics/asymptote/examples/sphere.asy
+2021/12/27 | 141 | graphics/asymptote/examples/ring.asy
+2021/12/27 | 1411 | graphics/asymptote/LspCpp/LibLsp/lsp/lsp_code_action.h
+2021/12/27 | 14082 | graphics/asymptote/GUI/xasyBezierInterface.py
+2021/12/27 | 14072 | graphics/asymptote/types.cc
+2021/12/27 | 1406 | graphics/asymptote/cudareflect/EXRFiles.h
+2021/12/27 | 13980 | graphics/asymptote/arrayop.h
+2021/12/27 | 1397611 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
+2021/12/27 | 1396779 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
+2021/12/27 | 13944 | graphics/asymptote/runtriple.cc
+2021/12/27 | 139310 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
+2021/12/27 | 1391 | graphics/asymptote/doc/CAD1.asy
+2021/12/27 | 138 | graphics/asymptote/Pipfile
+2021/12/27 | 1386 | graphics/asymptote/LspCpp/Makefile
+2021/12/27 | 13867 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/nuklear_btgui_gl2.h
+2021/12/27 | 1384 | graphics/asymptote/tests/pic/trans.asy
+2021/12/27 | 13824 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/pool_core.hpp
+2021/12/27 | 1380 | graphics/asymptote/LspCpp/LibLsp/lsp/general/initialize.h
+2021/12/27 | 1375 | graphics/asymptote/base/tree.asy
+2021/12/27 | 136 | graphics/asymptote/examples/latticeshading.asy
+2021/12/27 | 13663 | graphics/asymptote/doc/install-sh
+2021/12/27 | 13663 | graphics/asymptote/doc/FAQ/install-sh
+2021/12/27 | 13615 | graphics/asymptote/entry.h
+2021/12/27 | 13605 | graphics/asymptote/base/grid3.asy
+2021/12/27 | 135931 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma
+2021/12/27 | 1353499 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma
+2021/12/27 | 1352 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/did_change_watched_files.h
+2021/12/27 | 1352 | graphics/asymptote/examples/Klein.asy
+2021/12/27 | 13513 | graphics/asymptote/texfile.h
+2021/12/27 | 13511 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma
+2021/12/27 | 135070 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
+2021/12/27 | 1347 | graphics/asymptote/cudareflect/tinyexr/test/unit/config-posix.py
+2021/12/27 | 1345 | graphics/asymptote/interact.h
+2021/12/27 | 1341 | graphics/asymptote/runtimebase.in
+2021/12/27 | 133 | graphics/asymptote/cudareflect/tinyexr/test/unit/vcbuild.bat
+2021/12/27 | 1338 | graphics/asymptote/LspCpp/third_party/utfcpp/LICENSE
+2021/12/27 | 1338 | graphics/asymptote/LspCpp/third_party/threadpool/LICENSE_1_0.txt
+2021/12/27 | 13357 | graphics/asymptote/camp.l
+2021/12/27 | 1332 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial_header.htm
+2021/12/27 | 1331 | graphics/asymptote/tests/types/spec.asy
+2021/12/27 | 132 | graphics/asymptote/tests/string/length.asy
+2021/12/27 | 132 | graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-d5c9c893e559277a3320c196523095b94db93985620ac338d037487e0e613047_min
+2021/12/27 | 1328 | graphics/asymptote/LspCpp/LibLsp/lsp/lsCommand.h
+2021/12/27 | 1323 | graphics/asymptote/base/v3dheadertypes.asy
+2021/12/27 | 1322 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design.txt
+2021/12/27 | 1322403 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
+2021/12/27 | 1321 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/didChangeWorkspaceFolders.h
+2021/12/27 | 1319 | graphics/asymptote/GUI/res/icons/android-color-palette.svg
+2021/12/27 | 1318 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32InternalWindowData.h
+2021/12/27 | 1311 | graphics/asymptote/patches/dvipdf
+2021/12/27 | 1310 | graphics/asymptote/prc/PRCTools/extractSections.cc
+2021/12/27 | 1309 | graphics/asymptote/examples/roundpath.asy
+2021/12/27 | 129 | graphics/asymptote/tests/gc/struct.asy
+2021/12/27 | 129 | graphics/asymptote/base/shaders/screen.glsl
+2021/12/27 | 1299134 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma
+2021/12/27 | 1298 | graphics/asymptote/examples/electromagnetic.asy
+2021/12/27 | 129790 | graphics/asymptote/camp.tab.cc
+2021/12/27 | 1294300 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
+2021/12/27 | 1293 | graphics/asymptote/TODO
+2021/12/27 | 1293701 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
+2021/12/27 | 1291 | graphics/asymptote/LspCpp/third_party/utfcpp/CMakeLists.txt
+2021/12/27 | 1287 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/README.md
+2021/12/27 | 1284 | graphics/asymptote/tests/output/Makefile
+2021/12/27 | 1283 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/reference_header.htm
+2021/12/27 | 12823 | graphics/asymptote/impdatum.cc
+2021/12/27 | 1280 | graphics/asymptote/beziercurve.h
+2021/12/27 | 127 | graphics/asymptote/index.html
+2021/12/27 | 1276 | graphics/asymptote/base/asymptote.py
+2021/12/27 | 1274 | graphics/asymptote/newexp.h
+2021/12/27 | 1267 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/linkedEditingRange.h
+2021/12/27 | 126741 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma
+2021/12/27 | 1266 | graphics/asymptote/drawverbatim.h
+2021/12/27 | 126385 | graphics/asymptote/ReleaseNotes
+2021/12/27 | 12632 | graphics/asymptote/Makefile.in
+2021/12/27 | 12630 | graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/cube2longlat.cc
+2021/12/27 | 1261761 | graphics/asymptote/examples/worldmap.dat
+2021/12/27 | 12604 | graphics/asymptote/runsystem.cc
+2021/12/27 | 125 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/docker/Dockerfile
+2021/12/27 | 1253 | graphics/asymptote/keywords.pl
+2021/12/27 | 12534 | graphics/asymptote/ax_pthread.m4
+2021/12/27 | 1251 | graphics/asymptote/examples/odetest.asy
+2021/12/27 | 124 | graphics/asymptote/tests/gc/path.asy
+2021/12/27 | 124 | graphics/asymptote/GUI/res/icons/centerorigin.asy
+2021/12/27 | 1247 | graphics/asymptote/examples/animations/slidemovies.asy
+2021/12/27 | 12474 | graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/checked.h
+2021/12/27 | 1245 | graphics/asymptote/prc/PRCTools/describeMain.cc
+2021/12/27 | 1245 | graphics/asymptote/findsym.pl
+2021/12/27 | 1244 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/document_link.h
+2021/12/27 | 1241549 | graphics/asymptote/doc/asymptote.pdf
+2021/12/27 | 1240 | graphics/asymptote/examples/arrows3.asy
+2021/12/27 | 123 | graphics/asymptote/examples/Coons.asy
+2021/12/27 | 123 | graphics/asymptote/doc/superpath.asy
+2021/12/27 | 123910 | info/kaytannollista-latexia/luku-asetukset.tex
+2021/12/27 | 1236 | graphics/asymptote/primitives.h
+2021/12/27 | 1235 | graphics/asymptote/examples/animations/inlinemovie.tex
+2021/12/27 | 1235777 | graphics/asymptote/GL/glew.c
+2021/12/27 | 1227 | graphics/asymptote/build-scripts/build-asygl
+2021/12/27 | 1226 | graphics/asymptote/GUI/res/icons/triangle-stroked-15.svg
+2021/12/27 | 1225 | graphics/asymptote/v3dheadertypes.h
+2021/12/27 | 12259 | graphics/asymptote/knot.h
+2021/12/27 | 121 | graphics/asymptote/doc/labelsquare.asy
+2021/12/27 | 121 | graphics/asymptote/cudareflect/tinyexr/tinyexr.cc
+2021/12/27 | 1216 | graphics/asymptote/examples/dragon.asy
+2021/12/27 | 1215 | graphics/asymptote/GUI/configs/xasyconfig.cson
+2021/12/27 | 1213 | graphics/asymptote/LspCpp/LibLsp/lsp/lsCodeAction.h
+2021/12/27 | 1213 | graphics/asymptote/base/plain_arcs.asy
+2021/12/27 | 121145 | graphics/asymptote/doc/asyRefCard.pdf
+2021/12/27 | 1209 | graphics/asymptote/tests/imp/unravel.asy
+2021/12/27 | 12093 | graphics/asymptote/runlabel.in
+2021/12/27 | 120296 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma
+2021/12/27 | 12012 | graphics/asymptote/base/solids.asy
+2021/12/27 | 1198 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/exr-io.cc
+2021/12/27 | 11987 | info/kaytannollista-latexia/tavutusvihjeet.tex
+2021/12/27 | 1197 | graphics/asymptote/drawclipend.h
+2021/12/27 | 1195 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/references.h
+2021/12/27 | 1194 | graphics/asymptote/GUI/res/icons/code.svg
+2021/12/27 | 1192 | graphics/asymptote/LspCpp/LibLsp/lsp/lsFormattingOptions.h
+2021/12/27 | 1190 | graphics/asymptote/camperror.cc
+2021/12/27 | 11907 | graphics/asymptote/tests/gsl/random.asy
+2021/12/27 | 118 | graphics/asymptote/tests/string/substr.asy
+2021/12/27 | 1189 | graphics/asymptote/tests/types/var.asy
+2021/12/27 | 1188 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview_header.htm
+2021/12/27 | 1188 | graphics/asymptote/EXRFiles.cc
+2021/12/27 | 1187 | graphics/asymptote/GUI/res/icons/closedcurve.svg
+2021/12/27 | 1186601 | graphics/asymptote/GL/glew.h
+2021/12/27 | 1185 | graphics/asymptote/LspCpp/LibLsp/lsp/SimpleTimer.h
+2021/12/27 | 1185 | graphics/asymptote/examples/functionshading.asy
+2021/12/27 | 11846 | graphics/asymptote/jsfile.cc
+2021/12/27 | 1183 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/TcpServer.h
+2021/12/27 | 1183 | graphics/asymptote/GUI/xasyArgs.py
+2021/12/27 | 1183225 | graphics/asymptote/gc-8.2.0.tar.gz
+2021/12/27 | 1181005 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma
+2021/12/27 | 117 | graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/README.md
+2021/12/27 | 1178 | graphics/asymptote/base/embed.asy
+2021/12/27 | 1175 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageJsonHandler.cpp
+2021/12/27 | 1172 | graphics/asymptote/LspCpp/README.md
+2021/12/27 | 1171 | graphics/asymptote/parser.h
+2021/12/27 | 1171 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/Endpoint.cpp
+2021/12/27 | 11663 | graphics/asymptote/path.h
+2021/12/27 | 11656 | graphics/asymptote/base/binarytree.asy
+2021/12/27 | 1164 | graphics/asymptote/examples/genustwo.asy
+2021/12/27 | 11642 | graphics/asymptote/coder.h
+2021/12/27 | 1163 | graphics/asymptote/runtime.h
+2021/12/27 | 1162 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/LICENSE
+2021/12/27 | 1161 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/configuration.h
+2021/12/27 | 116010 | graphics/asymptote/predicates.cc
+2021/12/27 | 115 | graphics/asymptote/doc/onecontour.asy
+2021/12/27 | 1159 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/lsRequestId.h
+2021/12/27 | 1156 | graphics/asymptote/cudareflect/tinyexr/premake4.lua
+2021/12/27 | 115673 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
+2021/12/27 | 1154 | graphics/asymptote/LspCpp/LibLsp/lsp/lsVersionedTextDocumentIdentifier.h
+2021/12/27 | 11541 | graphics/asymptote/aspy.py
+2021/12/27 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini
+2021/12/27 | 1151 | graphics/asymptote/callable.cc
+2021/12/27 | 1150 | graphics/asymptote/LspCpp/LibLsp/lsp/general/lsClientCapabilities.h
+2021/12/27 | 1149 | graphics/asymptote/guide.cc
+2021/12/27 | 11468 | graphics/asymptote/drawelement.h
+2021/12/27 | 1143 | graphics/asymptote/LspCpp/LibLsp/lsp/lsPosition.h
+2021/12/27 | 1142 | graphics/asymptote/envcompleter.cc
+2021/12/27 | 1140 | graphics/asymptote/absyn.h
+2021/12/27 | 113 | graphics/asymptote/patches/fixmem.reg
+2021/12/27 | 113 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples.txt
+2021/12/27 | 1139 | graphics/asymptote/GUI/res/icons/opencurve.svg
+2021/12/27 | 11373 | graphics/asymptote/base/plain_markers.asy
+2021/12/27 | 113565 | graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image_resize.h
+2021/12/27 | 1134 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design_header.htm
+2021/12/27 | 1131 | graphics/asymptote/gl-matrix-2.4.0-pruned/LICENSE.js
+2021/12/27 | 1131 | graphics/asymptote/cudareflect/tinyexr/experimental/js/index.html
+2021/12/27 | 1130 | graphics/asymptote/GUI/res/icons/redo.svg
+2021/12/27 | 113043 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
+2021/12/27 | 1129 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/code_lens.h
+2021/12/27 | 1127425 | graphics/asymptote/cudareflect/tinyexr/asakusa.exr
+2021/12/27 | 1126 | graphics/asymptote/coenv.cc
+2021/12/27 | 1125 | graphics/asymptote/LspCpp/third_party/threadpool/Makefile
+2021/12/27 | 1124 | graphics/asymptote/GUI/res/icons/android-locate.svg
+2021/12/27 | 112484 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
+2021/12/27 | 1122 | graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples_header.htm
+2021/12/27 | 1120 | graphics/asymptote/examples/animations/wheel.asy
+2021/12/27 | 1120 | graphics/asymptote/base/external.asy
+2021/12/27 | 111 | graphics/asymptote/GUI/res/icons/center.asy
+2021/12/27 | 111 | graphics/asymptote/examples/shadestroke.asy
+2021/12/27 | 1114 | graphics/asymptote/examples/laserlattice.asy
+2021/12/27 | 11122 | graphics/asymptote/base/math.asy
+2021/12/27 | 1111 | graphics/asymptote/examples/imagehistogram.asy
+2021/12/27 | 11111 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/textDocument.cpp
+2021/12/27 | 1109 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/codeActionResult.h
+2021/12/27 | 1105 | graphics/asymptote/LspCpp/LibLsp/lsp/lsMarkedString.h
+2021/12/27 | 1101 | graphics/asymptote/cudareflect/tinyexr/examples/resize/resize.cc
+2021/12/27 | 109 | graphics/asymptote/tests/string/insert.asy
+2021/12/27 | 109 | graphics/asymptote/GUI/res/icons/closedpolygon.asy
+2021/12/27 | 109 | graphics/asymptote/GUI/res/icons/closedcurve.asy
+2021/12/27 | 1098 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/rename.h
+2021/12/27 | 10989 | graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/unchecked.h
+2021/12/27 | 1096 | graphics/asymptote/tests/array/transpose.asy
+2021/12/27 | 1096 | graphics/asymptote/refaccess.cc
+2021/12/27 | 1096 | graphics/asymptote/drawlayer.h
+2021/12/27 | 109545 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
+2021/12/27 | 10928 | graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/core.h
+2021/12/27 | 109263 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
+2021/12/27 | 108 | graphics/asymptote/GUI/res/icons/subdirectory-left.svg
+2021/12/27 | 108 | graphics/asymptote/cudareflect/tinyexr/jni/README.md
+2021/12/27 | 1088 | graphics/asymptote/LspCpp/third_party/threadpool/TODO
+2021/12/27 | 1087 | graphics/asymptote/GUI/res/icons/undo.svg
+2021/12/27 | 1087069 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
+2021/12/27 | 1086 | graphics/asymptote/base/shaders/partialsum.glsl
+2021/12/27 | 10840 | graphics/asymptote/base/CAD.asy
+2021/12/27 | 1082 | graphics/asymptote/patches/README
+2021/12/27 | 108236 | systems/texlive/tlnet/archive/texlive-scripts.r61410.tar.xz
+2021/12/27 | 1077 | graphics/asymptote/LspCpp/LibLsp/lsp/workspace/applyEdit.h
+2021/12/27 | 1074 | info/mathalphabets/README.md
+2021/12/27 | 1072 | graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/README.md
+2021/12/27 | 1070 | graphics/asymptote/cudareflect/IrradianceGenerator.sln
+2021/12/27 | 1066 | graphics/asymptote/LspCpp/LICENSE
+2021/12/27 | 1065 | graphics/asymptote/examples/shellmethod.asy
+2021/12/27 | 10632 | graphics/asymptote/EnvVarUpdate.nsh
+2021/12/27 | 1061 | graphics/asymptote/v3dheadertypes.csv
+2021/12/27 | 10607 | graphics/asymptote/LspCpp/network/uri/detail/uri_parse.cpp
+2021/12/27 | 1058 | graphics/asymptote/GUI/res/icons/closedpolygon.svg
+2021/12/27 | 10585 | graphics/asymptote/path3.h
+2021/12/27 | 10581 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/serializer.h
+2021/12/27 | 10571 | graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example5.c
+2021/12/27 | 1056 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/didRenameFiles.h
+2021/12/27 | 10563 | graphics/asymptote/cudareflect/tinyexr/test/unit/kuroga.py
+2021/12/27 | 10561 | graphics/asymptote/cudareflect/tinyexr/kuroga.py
+2021/12/27 | 1055 | graphics/asymptote/LspCpp/LibLsp/lsp/general/initialize.cpp
+2021/12/27 | 1055 | graphics/asymptote/examples/partitionExample.asy
+2021/12/27 | 1054 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/onTypeFormatting.h
+2021/12/27 | 1051 | graphics/asymptote/prc/PRCTools/inflation.h
+2021/12/27 | 1051 | graphics/asymptote/doc/eetomumu.asy
+2021/12/27 | 1050 | graphics/asymptote/opsymbols.pl
+2021/12/27 | 104 | graphics/asymptote/examples/tiling.asy
+2021/12/27 | 104748 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
+2021/12/27 | 1044671 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/screenshots/exrview.png
+2021/12/27 | 10445 | graphics/asymptote/INSTALL
+2021/12/27 | 1043 | graphics/asymptote/GUI/res/icons/openpolygon.svg
+2021/12/27 | 1042 | graphics/asymptote/examples/NURBSsphere.asy
+2021/12/27 | 1040 | graphics/asymptote/examples/lmfit1.asy
+2021/12/27 | 1037 | graphics/asymptote/examples/animations/inlinemovie3.tex
+2021/12/27 | 103463 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
+2021/12/27 | 1033 | graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/prepareRename.h
+2021/12/27 | 1033 | graphics/asymptote/examples/basealign.asy
+2021/12/27 | 1032 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_checked_iterator.cpp
+2021/12/27 | 1030 | graphics/asymptote/LspCpp/network/uri.hpp
+2021/12/27 | 1030 | graphics/asymptote/examples/workcone.asy
+2021/12/27 | 102 | graphics/asymptote/tests/gc/file.asy
+2021/12/27 | 102 | graphics/asymptote/GUI/res/icons/openpolygon.asy
+2021/12/27 | 102 | graphics/asymptote/GUI/res/icons/opencurve.asy
+2021/12/27 | 10271 | graphics/asymptote/GUI/windows/custMatTransform.ui
+2021/12/27 | 1022 | graphics/asymptote/GUI/res/icons/centerorigin.svg
+2021/12/27 | 10224 | graphics/asymptote/tr.cc
+2021/12/27 | 10221 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/WebSocketServer.cpp
+2021/12/27 | 1021951 | info/kaytannollista-latexia.zip
+2021/12/27 | 1020 | graphics/asymptote/flatguide.cc
+2021/12/27 | 1019 | graphics/asymptote/LspCpp/LibLsp/lsp/client/unregisterCapability.h
+2021/12/27 | 10196 | graphics/asymptote/doc/CAD.tex
+2021/12/27 | 1015 | graphics/asymptote/GUI/xasyTransform.py
+2021/12/27 | 101508 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma
+2021/12/27 | 1013 | graphics/asymptote/GUI/res/icons/chevron-with-circle-left.svg
+2021/12/27 | 1010 | graphics/asymptote/examples/washermethod.asy
+2021/12/27 | 100 | graphics/asymptote/GUI/DebugFlags.py
+2021/12/27 | 10093 | graphics/asymptote/util.cc
+2021/12/27 | 1008 | graphics/asymptote/doc/leastsquares.asy
+2021/12/27 | 10070 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/RemoteEndPoint.h
+2021/12/27 | 1006 | graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/scope_guard.hpp
+2021/12/27 | 1005 | graphics/asymptote/doc/asy.1.begin
+2021/12/27 | 1003 | graphics/asymptote/GUI/res/icons/eye.svg
+2021/12/27 | 10039 | graphics/asymptote/v3dfile.cc
+2021/12/27 | 10038 | graphics/asymptote/GUI/pyUIClass/custMatTransform.py
+2021/12/27 | 1002 | graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_unchecked_iterator.cpp
+2021/12/27 | 1002 | graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkHashCodeEqualsStatus.h
+2021/12/27 | 1000 | graphics/asymptote/LspCpp/LibLsp/JsonRpc/StreamMessageProducer.h
+2021/12/27 | 1000 | graphics/asymptote/doc/FAQ/Makefile
+2021/12/27 | 100007 | graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_cocoa.png
2021/12/26 | 9955 | macros/latex/contrib/asmeconf/examples/asmeconf-lualatex-ode-example.tex
-2021/12/26 | 99372 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-2.9.tar.lzma
-2021/12/26 | 97104 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-2.9.tar.lzma
-2021/12/26 | 96827 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-2.9.tar.lzma
-2021/12/26 | 965 | systems/win32/miktex/tm/packages/pr.ini
-2021/12/26 | 959950 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-2.9.tar.lzma
2021/12/26 | 9592 | systems/texlive/tlnet/archive/minted.r61405.tar.xz
-2021/12/26 | 95449 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-2.9.tar.lzma
-2021/12/26 | 95274 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-x64-2.9.tar.lzma
-2021/12/26 | 93989 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-2.9.tar.lzma
2021/12/26 | 9157 | macros/latex/contrib/asmeconf/README.md
2021/12/26 | 9152100 | systems/texlive/tlnet/archive/pstricks-add.doc.r61407.tar.xz
2021/12/26 | 888 | macros/latex/contrib/codebox/hellopy.py
2021/12/26 | 88313 | macros/latex/contrib/asmeconf/asmeconf.cls
-2021/12/26 | 88228 | systems/win32/miktex/tm/packages/next/miktex-png-bin-x64-2.9.tar.lzma
-2021/12/26 | 8790 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-x64-2.9.tar.lzma
2021/12/26 | 875831 | macros/latex/contrib/asmejour.zip
-2021/12/26 | 86768 | systems/win32/miktex/tm/packages/next/miktex-bibtex8bit-bin-2.9.tar.lzma
2021/12/26 | 84780 | macros/latex/contrib/easybook/easybook.tex
2021/12/26 | 83394 | macros/latex/contrib/easybook/easybook.dtx
-2021/12/26 | 824229 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-x64-2.9.tar.lzma
2021/12/26 | 824148 | systems/texlive/tlnet/archive/minted.doc.r61405.tar.xz
-2021/12/26 | 81707 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-x64-2.9.tar.lzma
-2021/12/26 | 79137 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-x64-2.9.tar.lzma
2021/12/26 | 7900 | macros/latex/contrib/asmejour/README.md
-2021/12/26 | 78962 | systems/win32/miktex/tm/packages/next/miktex-png-bin-2.9.tar.lzma
-2021/12/26 | 7756 | systems/win32/miktex/tm/packages/next/miktex-md5-bin-2.9.tar.lzma
2021/12/26 | 77433 | macros/latex/contrib/termsim/termsim-doc-en.pdf
-2021/12/26 | 77072 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-x64-2.9.tar.lzma
-2021/12/26 | 763148 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-x64-2.9.tar.lzma
-2021/12/26 | 762930 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-x64.tar.lzma
-2021/12/26 | 76231 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-x64-2.9.tar.lzma
-2021/12/26 | 753825 | systems/win32/miktex/tm/packages/next/miktex-pdftex-bin-2.9.tar.lzma
-2021/12/26 | 74622 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-x64-2.9.tar.lzma
-2021/12/26 | 74054 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-x64-2.9.tar.lzma
-2021/12/26 | 73599 | systems/win32/miktex/tm/packages/next/miktex-fonts-bin-2.9.tar.lzma
-2021/12/26 | 73180 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-x64-2.9.tar.lzma
-2021/12/26 | 72850 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-x64-2.9.tar.lzma
-2021/12/26 | 72256 | systems/win32/miktex/tm/packages/next/miktex-freeglut-bin-2.9.tar.lzma
-2021/12/26 | 71896 | systems/win32/miktex/tm/packages/next/miktex-web-bin-x64-2.9.tar.lzma
-2021/12/26 | 70993 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-x64-2.9.tar.lzma
-2021/12/26 | 69553 | macros/latex/contrib/codebox/codebox-doc-en.pdf
-2021/12/26 | 694124 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin-2.9.tar.lzma
-2021/12/26 | 693756 | systems/win32/miktex/tm/packages/next/miktex-ptex-bin.tar.lzma
-2021/12/26 | 68799 | systems/win32/miktex/tm/packages/next/miktex-bibtex-bin-2.9.tar.lzma
-2021/12/26 | 68619 | systems/win32/miktex/tm/packages/next/miktex-mpmcli-bin-2.9.tar.lzma
-2021/12/26 | 682341 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-x64-2.9.tar.lzma
-2021/12/26 | 6811294 | systems/texlive/tlnet/install-tl-unx.tar.gz
-2021/12/26 | 67994 | systems/win32/miktex/tm/packages/next/miktex-lzma-bin-2.9.tar.lzma
-2021/12/26 | 67857 | systems/win32/miktex/tm/packages/next/miktex-web-bin-2.9.tar.lzma
-2021/12/26 | 67188 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-x64-2.9.tar.lzma
2021/12/26 | 670642 | macros/latex/contrib/asmejour/asmejour-template.pdf
+2021/12/26 | 6622 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
2021/12/26 | 6537272 | systems/texlive/tlnet/archive/newtx.r61408.tar.xz
-2021/12/26 | 64715 | systems/win32/miktex/tm/packages/next/miktex-ps2pk-bin-2.9.tar.lzma
-2021/12/26 | 64567 | systems/win32/miktex/tm/packages/next/miktex-graphite2-bin-2.9.tar.lzma
-2021/12/26 | 64516 | systems/win32/miktex/tm/packages/next/miktex-mkfntmap-bin-2.9.tar.lzma
-2021/12/26 | 64452 | systems/win32/miktex/tm/packages/next/miktex-tex4ht-bin-2.9.tar.lzma
2021/12/26 | 643458 | macros/latex/contrib/asmeconf/asmeconf-template.pdf
2021/12/26 | 639103 | macros/latex/contrib/asmeconf/examples/asmeconf-authorgrid-example.pdf
2021/12/26 | 637591 | macros/latex/contrib/easybook.zip
-2021/12/26 | 63699 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin-x64.tar.lzma
2021/12/26 | 633692 | systems/texlive/tlnet/archive/newtx.doc.r61408.tar.xz
-2021/12/26 | 63313 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-x64-2.9.tar.lzma
-2021/12/26 | 631001 | systems/win32/miktex/tm/packages/next/miktex-lcdf-typetools-bin-2.9.tar.lzma
-2021/12/26 | 630565 | systems/win32/miktex/tm/packages/files.csv.lzma
-2021/12/26 | 630358 | systems/win32/miktex/tm/packages/next/files.csv.lzma
-2021/12/26 | 629126 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-x64-2.9.tar.lzma
-2021/12/26 | 62710 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-x64-2.9.tar.lzma
-2021/12/26 | 62420 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-x64-2.9.tar.lzma
-2021/12/26 | 599046 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-x64-2.9.tar.lzma
2021/12/26 | 5953884 | info/visualfaq-fr.zip
2021/12/26 | 594563 | macros/latex/contrib/easybook/easybook.pdf
-2021/12/26 | 591064 | systems/win32/miktex/tm/packages/next/miktex-yap-bin-2.9.tar.lzma
-2021/12/26 | 58642 | systems/win32/miktex/tm/packages/next/miktex-texify-bin-2.9.tar.lzma
-2021/12/26 | 58547 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-x64-2.9.tar.lzma
-2021/12/26 | 58370 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-x64-2.9.tar.lzma
-2021/12/26 | 57566 | systems/win32/miktex/tm/packages/next/miktex-tdsutil-bin.tar.lzma
-2021/12/26 | 57416 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin-x64.tar.lzma
-2021/12/26 | 57408 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-x64-2.9.tar.lzma
-2021/12/26 | 57278 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-x64-2.9.tar.lzma
-2021/12/26 | 56963 | systems/win32/miktex/tm/packages/next/miktex-fmt-bin-2.9.tar.lzma
-2021/12/26 | 566759 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-x64-2.9.tar.lzma
-2021/12/26 | 55725 | systems/win32/miktex/tm/packages/next/miktex-xml2pmx-bin.tar.lzma
-2021/12/26 | 55294 | systems/win32/miktex/tm/packages/next/miktex-ttf2pk2-bin-2.9.tar.lzma
-2021/12/26 | 54950 | systems/win32/miktex/tm/packages/next/miktex-cweb-bin-2.9.tar.lzma
-2021/12/26 | 532337 | systems/win32/miktex/tm/packages/next/miktex-libressl-bin-2.9.tar.lzma
-2021/12/26 | 528531 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-x64-2.9.tar.lzma
-2021/12/26 | 52573 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-x64-2.9.tar.lzma
-2021/12/26 | 52279 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-x64-2.9.tar.lzma
-2021/12/26 | 52095 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-x64-2.9.tar.lzma
-2021/12/26 | 51588 | systems/win32/miktex/tm/packages/next/miktex-arctrl-bin-2.9.tar.lzma
-2021/12/26 | 51430 | systems/win32/miktex/tm/packages/next/miktex-cjkutils-bin-2.9.tar.lzma
-2021/12/26 | 50852 | systems/win32/miktex/tm/packages/next/miktex-psutils-bin-2.9.tar.lzma
-2021/12/26 | 50732 | systems/win32/miktex/tm/packages/next/miktex-bibarts-bin-2.9.tar.lzma
-2021/12/26 | 48 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
-2021/12/26 | 48803 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-x64-2.9.tar.lzma
-2021/12/26 | 484479 | systems/win32/miktex/tm/packages/next/miktex-harfbuzz-bin-2.9.tar.lzma
-2021/12/26 | 47893 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-x64-2.9.tar.lzma
-2021/12/26 | 477727 | systems/win32/miktex/tm/packages/next/miktex-log4cxx-bin-2.9.tar.lzma
-2021/12/26 | 46135 | systems/win32/miktex/tm/packages/next/miktex-dvicopy-bin-2.9.tar.lzma
-2021/12/26 | 461238 | systems/win32/miktex/tm/packages/next/miktex-doc.tar.lzma
-2021/12/26 | 45731 | systems/win32/miktex/tm/packages/next/miktex-m-tx-bin-2.9.tar.lzma
2021/12/26 | 45728 | macros/latex/contrib/termsim/termsim.dtx
-2021/12/26 | 45687 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-x64-2.9.tar.lzma
-2021/12/26 | 455 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
-2021/12/26 | 455 | systems/texlive/tlnet/install-tl.zip.sha512.asc
-2021/12/26 | 455 | systems/texlive/tlnet/install-tl-windows.exe.sha512.asc
-2021/12/26 | 455 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512.asc
2021/12/26 | 45492 | systems/texlive/tlnet/archive/minted.source.r61405.tar.xz
2021/12/26 | 44075 | macros/latex/contrib/asmejour/asmejour.cls
-2021/12/26 | 43894 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-x64-2.9.tar.lzma
-2021/12/26 | 43809 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-x64-2.9.tar.lzma
-2021/12/26 | 43683 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-x64-2.9.tar.lzma
-2021/12/26 | 43637 | systems/win32/miktex/tm/packages/next/miktex-expat-bin-2.9.tar.lzma
-2021/12/26 | 43275 | systems/win32/miktex/tm/packages/next/miktex-mtprint-bin-2.9.tar.lzma
2021/12/26 | 42772 | macros/latex/contrib/asmejour/asmejour-template.tex
-2021/12/26 | 42766 | systems/win32/miktex/tm/packages/next/miktex-synctex-bin-2.9.tar.lzma
2021/12/26 | 42180 | macros/latex/contrib/asmeconf/asmeconf-template.tex
2021/12/26 | 42105 | macros/latex/contrib/asmeconf/examples/asmeconf-authorgrid-example.tex
-2021/12/26 | 41326 | systems/win32/miktex/tm/packages/next/miktex-dvipng-bin-2.9.tar.lzma
-2021/12/26 | 41220 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin-x64.tar.lzma
-2021/12/26 | 41202 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin-x64.tar.lzma
2021/12/26 | 404704 | macros/latex/contrib/termsim.zip
-2021/12/26 | 402264 | systems/texlive/tlnet/archive/texlive-scripts.doc.r61403.tar.xz
-2021/12/26 | 39745 | systems/win32/miktex/tm/packages/next/miktex-zlib-bin-2.9.tar.lzma
-2021/12/26 | 394270 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-x64-2.9.tar.lzma
-2021/12/26 | 38541 | systems/win32/miktex/tm/packages/next/miktex-mthelp-bin-2.9.tar.lzma
-2021/12/26 | 38460 | systems/win32/miktex/tm/packages/next/miktex-gsf2pk-bin-2.9.tar.lzma
2021/12/26 | 3759 | macros/latex/contrib/termsim/README.md
-2021/12/26 | 37373 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-x64-2.9.tar.lzma
-2021/12/26 | 37151 | systems/win32/miktex/tm/packages/next/miktex-upmendex-bin.tar.lzma
-2021/12/26 | 37092 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-x64-2.9.tar.lzma
2021/12/26 | 370592 | macros/latex/contrib/asmeconf/examples/asmeconf-fontspec.pdf
-2021/12/26 | 365836 | macros/latex/contrib/codebox.zip
-2021/12/26 | 36041 | systems/win32/miktex/tm/packages/next/miktex-patgen-bin.tar.lzma
-2021/12/26 | 35263 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-x64-2.9.tar.lzma
-2021/12/26 | 35256 | macros/latex/contrib/codebox/codebox.dtx
-2021/12/26 | 35167 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-x64-2.9.tar.lzma
-2021/12/26 | 351558 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-x64-2.9.tar.lzma
2021/12/26 | 3436552 | info/visualfaq-fr/visualFAQ-fr.pdf
-2021/12/26 | 34090 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-x64-2.9.tar.lzma
-2021/12/26 | 332374 | systems/win32/miktex/tm/packages/next/miktex-cairo-bin-2.9.tar.lzma
2021/12/26 | 3313 | info/visualfaq-fr/source/README
-2021/12/26 | 32990 | systems/win32/miktex/tm/packages/next/miktex-chktex-bin-2.9.tar.lzma
-2021/12/26 | 3274 | macros/latex/contrib/codebox/README.md
-2021/12/26 | 326387 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-x64-2.9.tar.lzma
-2021/12/26 | 32155 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-x64-2.9.tar.lzma
2021/12/26 | 320848 | systems/texlive/tlnet/archive/biblatex-apa.doc.r61406.tar.xz
-2021/12/26 | 318734 | systems/win32/miktex/tm/packages/next/miktex-xetex-bin-2.9.tar.lzma
-2021/12/26 | 31579 | systems/win32/miktex/tm/packages/next/miktex-posix-bin-2.9.tar.lzma
-2021/12/26 | 31539 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-x64-2.9.tar.lzma
-2021/12/26 | 31411 | systems/win32/miktex/tm/packages/next/miktex-mspack-bin-2.9.tar.lzma
-2021/12/26 | 31333 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-x64-2.9.tar.lzma
2021/12/26 | 313173 | macros/latex/contrib/termsim/termsim.pdf
-2021/12/26 | 30567 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-x64-2.9.tar.lzma
2021/12/26 | 3024 | info/visualfaq-fr/README
-2021/12/26 | 30180 | systems/win32/miktex/tm/packages/next/miktex-axohelp-bin-2.9.tar.lzma
-2021/12/26 | 295888 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-x64-2.9.tar.lzma
2021/12/26 | 29262 | macros/latex/contrib/termsim/ctxdoc-en.cls
2021/12/26 | 289 | macros/latex/contrib/termsim/build.sh
-2021/12/26 | 289 | macros/latex/contrib/codebox/build.sh
-2021/12/26 | 28896 | systems/win32/miktex/tm/packages/next/miktex-autosp-bin-2.9.tar.lzma
2021/12/26 | 2880413 | macros/latex/contrib/asmeconf.zip
-2021/12/26 | 28678 | systems/win32/miktex/tm/packages/next/miktex-uriparser-bin-2.9.tar.lzma
-2021/12/26 | 286703 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-x64-2.9.tar.lzma
2021/12/26 | 2859480 | systems/texlive/tlnet/archive/newpx.r61404.tar.xz
-2021/12/26 | 28545 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-x64-2.9.tar.lzma
-2021/12/26 | 285455 | systems/win32/miktex/tm/packages/next/miktex-dvipdfmx-bin-2.9.tar.lzma
-2021/12/26 | 28385 | systems/win32/miktex/tm/packages/next/miktex-lacheck-bin-2.9.tar.lzma
-2021/12/26 | 281442 | systems/win32/miktex/tm/packages/next/miktex-console-bin-x64-2.9.tar.lzma
2021/12/26 | 280349 | macros/latex/contrib/asmeconf/examples/asmeconf-lualatex-ode-example.pdf
-2021/12/26 | 280271 | macros/latex/contrib/codebox/codebox.pdf
-2021/12/26 | 2798719 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-x64-2.9.tar.lzma
2021/12/26 | 27502 | macros/latex/contrib/asmeconf/examples/asmeconf-fontspec.tex
-2021/12/26 | 27474 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-x64-2.9.tar.lzma
-2021/12/26 | 27262 | systems/win32/miktex/tm/packages/next/miktex-makeindex-bin-2.9.tar.lzma
-2021/12/26 | 27243 | systems/win32/miktex/tm/packages/next/miktex-bzip2-bin-2.9.tar.lzma
2021/12/26 | 27172 | systems/texlive/tlnet/archive/biblatex-apa.r61406.tar.xz
-2021/12/26 | 2675897 | systems/win32/miktex/tm/packages/next/miktex-texworks-bin-2.9.tar.lzma
-2021/12/26 | 259274 | systems/win32/miktex/tm/packages/next/miktex-freetype2-bin-2.9.tar.lzma
-2021/12/26 | 256876 | systems/win32/miktex/tm/packages/next/miktex-zzdb1-2.9.tar.lzma
-2021/12/26 | 256780 | systems/win32/miktex/tm/packages/miktex-zzdb1-2.9.tar.lzma
-2021/12/26 | 25671 | systems/win32/miktex/tm/packages/next/miktex-teckit-bin-2.9.tar.lzma
-2021/12/26 | 25631646 | systems/texlive/tlnet/install-tl.zip
-2021/12/26 | 256200 | systems/win32/miktex/tm/packages/next/miktex-console-bin-2.9.tar.lzma
2021/12/26 | 256024 | systems/texlive/tlnet/archive/newpx.doc.r61404.tar.xz
-2021/12/26 | 25133 | systems/win32/miktex/tm/packages/next/miktex-findtexmf-bin-2.9.tar.lzma
-2021/12/26 | 251069 | systems/win32/miktex/tm/packages/next/miktex-metapost-bin-2.9.tar.lzma
-2021/12/26 | 25061 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-x64-2.9.tar.lzma
-2021/12/26 | 244963 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-x64-2.9.tar.lzma
-2021/12/26 | 24152 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-x64-2.9.tar.lzma
-2021/12/26 | 23931 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-x64-2.9.tar.lzma
-2021/12/26 | 2335968 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
-2021/12/26 | 22178 | systems/win32/miktex/tm/packages/next/miktex-fribidixetex-bin-2.9.tar.lzma
2021/12/26 | 21888 | systems/texlive/tlnet/archive/pstricks-add.r61407.tar.xz
-2021/12/26 | 215852 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-x64-2.9.tar.lzma
-2021/12/26 | 21371 | systems/win32/miktex/tm/packages/next/miktex-devnag-bin-2.9.tar.lzma
-2021/12/26 | 213460 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-x64-2.9.tar.lzma
-2021/12/26 | 209937 | systems/win32/miktex/tm/packages/next/miktex-pmx-bin-2.9.tar.lzma
-2021/12/26 | 20873611 | systems/texlive/tlnet/install-tl-windows.exe
-2021/12/26 | 203080 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-x64-2.9.tar.lzma
-2021/12/26 | 202237 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-x64-2.9.tar.lzma
-2021/12/26 | 20190 | systems/win32/miktex/tm/packages/next/miktex-popt-bin-2.9.tar.lzma
-2021/12/26 | 2012704 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-x64-2.9.tar.lzma
-2021/12/26 | 200142 | systems/win32/miktex/tm/packages/next/miktex-pixman-bin-2.9.tar.lzma
-2021/12/26 | 199836 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-2.9.tar.lzma
-2021/12/26 | 199114 | systems/win32/miktex/tm/packages/next/miktex-omegaware-bin-2.9.tar.lzma
-2021/12/26 | 197376 | systems/win32/miktex/tm/packages/next/miktex-metafont-bin-2.9.tar.lzma
-2021/12/26 | 196120 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-x64-2.9.tar.lzma
2021/12/26 | 18927 | macros/latex/contrib/termsim/termsim-doc-en.tex
-2021/12/26 | 18487 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-x64-2.9.tar.lzma
-2021/12/26 | 18371 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-x64-2.9.tar.lzma
-2021/12/26 | 181559 | systems/win32/miktex/tm/packages/next/miktex-mo-bin-2.9.tar.lzma
-2021/12/26 | 181466 | systems/win32/miktex/tm/packages/next/miktex-mpfr-bin-x64-2.9.tar.lzma
-2021/12/26 | 179708 | systems/win32/miktex/tm/packages/next/miktex-curl-bin-2.9.tar.lzma
-2021/12/26 | 1732472 | systems/win32/miktex/tm/packages/next/miktex-luatex-bin-2.9.tar.lzma
-2021/12/26 | 172343 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-x64-2.9.tar.lzma
-2021/12/26 | 17059142 | systems/texlive/tlnet/tlpkg/texlive.tlpdb
-2021/12/26 | 168851 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-x64-2.9.tar.lzma
-2021/12/26 | 16566 | systems/win32/miktex/tm/packages/next/miktex-tex2xindy-bin-2.9.tar.lzma
-2021/12/26 | 16521 | systems/win32/miktex/tm/packages/next/miktex-kpathsea-bin-2.9.tar.lzma
-2021/12/26 | 157439 | systems/win32/miktex/tm/packages/next/miktex-tex-bin-2.9.tar.lzma
-2021/12/26 | 155285 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-x64-2.9.tar.lzma
-2021/12/26 | 153 | systems/texlive/tlnet/install-tl-windows.exe.sha512
-2021/12/26 | 152 | systems/texlive/tlnet/install-tl-unx.tar.gz.sha512
-2021/12/26 | 152104 | systems/win32/miktex/tm/packages/next/miktex-hunspell-bin-2.9.tar.lzma
-2021/12/26 | 1497475 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-x64-2.9.tar.lzma
-2021/12/26 | 145 | systems/texlive/tlnet/install-tl.zip.sha512
-2021/12/26 | 144 | systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
-2021/12/26 | 1447745 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-x64-2.9.tar.lzma
-2021/12/26 | 14416 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-x64-2.9.tar.lzma
2021/12/26 | 140180 | info/visualfaq-fr/source/visualFAQ-fr.tex
-2021/12/26 | 1398132 | systems/win32/miktex/tm/packages/next/miktex-zzdb2-2.9.tar.lzma
-2021/12/26 | 1396326 | systems/win32/miktex/tm/packages/miktex-zzdb2-2.9.tar.lzma
-2021/12/26 | 139309 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-x64-2.9.tar.lzma
-2021/12/26 | 135932 | systems/win32/miktex/tm/packages/next/miktex-fontconfig-bin-2.9.tar.lzma
-2021/12/26 | 1353497 | systems/win32/miktex/tm/packages/next/miktex-runtime-bin-2.9.tar.lzma
-2021/12/26 | 13510 | systems/win32/miktex/tm/packages/next/miktex-zzip-bin-2.9.tar.lzma
-2021/12/26 | 135071 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-x64-2.9.tar.lzma
-2021/12/26 | 1322402 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-x64-2.9.tar.lzma
-2021/12/26 | 1299135 | systems/win32/miktex/tm/packages/next/miktex-dvisvgm-bin-2.9.tar.lzma
-2021/12/26 | 1294683 | systems/win32/miktex/tm/packages/next/miktex-zzdb3-2.9.tar.lzma
-2021/12/26 | 1293842 | systems/win32/miktex/tm/packages/miktex-zzdb3-2.9.tar.lzma
-2021/12/26 | 126741 | systems/win32/miktex/tm/packages/next/miktex-mktex-bin-2.9.tar.lzma
2021/12/26 | 122 | macros/latex/contrib/codebox/hellojava.java
-2021/12/26 | 120296 | systems/win32/miktex/tm/packages/next/miktex-dvips-bin-2.9.tar.lzma
2021/12/26 | 11 | info/visualfaq-fr/VERSION
-2021/12/26 | 1181004 | systems/win32/miktex/tm/packages/next/miktex-poppler-bin-2.9.tar.lzma
-2021/12/26 | 115671 | systems/win32/miktex/tm/packages/next/miktex-gregorio-bin-x64-2.9.tar.lzma
-2021/12/26 | 1153 | systems/win32/miktex/tm/packages/next/pr.ini
2021/12/26 | 11317 | macros/latex/contrib/codebox/codebox-doc-en.tex
-2021/12/26 | 113044 | systems/win32/miktex/tm/packages/next/miktex-epstopdf-bin-x64-2.9.tar.lzma
-2021/12/26 | 112482 | systems/win32/miktex/tm/packages/next/miktex-gd-bin-x64-2.9.tar.lzma
-2021/12/26 | 109545 | systems/win32/miktex/tm/packages/next/miktex-jpeg-bin-x64-2.9.tar.lzma
-2021/12/26 | 109263 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-x64-2.9.tar.lzma
-2021/12/26 | 1087070 | systems/win32/miktex/tm/packages/next/miktex-asymptote-bin-x64-2.9.tar.lzma
-2021/12/26 | 108268 | systems/texlive/tlnet/archive/texlive-scripts.r61403.tar.xz
2021/12/26 | 104 | macros/latex/contrib/codebox/test.c
-2021/12/26 | 104747 | systems/win32/miktex/tm/packages/next/miktex-mfware-bin-x64-2.9.tar.lzma
-2021/12/26 | 103462 | systems/win32/miktex/tm/packages/next/miktex-lua53-bin-x64-2.9.tar.lzma
-2021/12/26 | 101510 | systems/win32/miktex/tm/packages/next/miktex-texware-bin-2.9.tar.lzma
2021/12/25 | 9985 | graphics/pstricks/contrib/pstricks-add/doc/data/data.data
2021/12/25 | 9972 | fonts/newpx/tfm/zpl-BoldItalic-lf-scl-t1.tfm
2021/12/25 | 9956 | fonts/newpx/tfm/zpl-BoldItalic-osf-scl-t1.tfm
@@ -270,12 +1737,11 @@
2021/12/25 | 9844 | fonts/newpx/tfm/zpl-BoldItalic-tlf-sc-t1.tfm
2021/12/25 | 9840 | fonts/newpx/tfm/zpl-BoldItalic-tosf-sc-t1.tfm
2021/12/25 | 982832 | systems/texlive/tlnet/archive/europecv.doc.r61398.tar.xz
-2021/12/25 | 9788 | systems/texlive/tlnet/archive/termsim.source.r61399.tar.xz
2021/12/25 | 9684 | fonts/newpx/tfm/zpl-BoldItalic-lf-t1.tfm
2021/12/25 | 9672 | fonts/newpx/tfm/zpl-BoldItalic-osf-t1.tfm
+2021/12/25 | 963 | macros/latex/contrib/wrapfig2/README.txt
2021/12/25 | 9628 | fonts/newpx/tfm/zpl-BoldItalic-tlf-t1.tfm
2021/12/25 | 9624 | fonts/newpx/tfm/zpl-BoldItalic-tosf-t1.tfm
-2021/12/25 | 9514335 | fonts/newtx.zip
2021/12/25 | 91089 | graphics/pstricks/contrib/pstricks-add/tex/pstricks-add.tex
2021/12/25 | 8372 | fonts/newpx/tfm/ztm-BoldItalic-osf-sc-ly1.tfm
2021/12/25 | 8372 | fonts/newpx/tfm/ztm-BoldItalic-lf-sc-ly1.tfm
@@ -367,7 +1833,6 @@
2021/12/25 | 7140 | fonts/newpx/tfm/zpl-Bold-tlf-ly1.tfm
2021/12/25 | 6780 | fonts/newpx/tfm/zpl-BoldItalic-lf-scl-ly1.tfm
2021/12/25 | 6760 | fonts/newpx/tfm/zpl-BoldItalic-osf-scl-ly1.tfm
-2021/12/25 | 6738 | systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
2021/12/25 | 6720 | fonts/newpx/tfm/zpl-BoldItalic-tlf-scl-ly1.tfm
2021/12/25 | 6716 | fonts/newpx/tfm/zpl-BoldItalic-tosf-scl-ly1.tfm
2021/12/25 | 6712 | fonts/newpx/tfm/zpl-BoldItalic-lf-sc-ly1.tfm
@@ -387,6 +1852,7 @@
2021/12/25 | 6008 | fonts/newpx/tfm/zpl-BoldSlanted-osf-scl-t1.tfm
2021/12/25 | 5980 | fonts/newpx/tfm/zpl-BoldSlanted-tosf-scl-t1.tfm
2021/12/25 | 5980 | fonts/newpx/tfm/zpl-BoldSlanted-tlf-scl-t1.tfm
+2021/12/25 | 5965 | info/mathalphabets/src/maref.bib
2021/12/25 | 516 | systems/texlive/tlnet/archive/dtk-bibliography.r61396.tar.xz
2021/12/25 | 5069 | graphics/pstricks/contrib/pstricks-add/dvips/pstricks-add.pro
2021/12/25 | 4859033 | fonts/newpx.zip
@@ -404,13 +1870,11 @@
2021/12/25 | 420 | graphics/pstricks/contrib/pstricks-add/doc/data/demo0.data
2021/12/25 | 40546 | systems/win32/miktex/tm/packages/ptex-fontmaps.tar.lzma
2021/12/25 | 405245 | macros/latex/contrib/biblatex-contrib/biblatex-apa.zip
-2021/12/25 | 4028 | systems/texlive/tlnet/archive/termsim.r61399.tar.xz
2021/12/25 | 39052 | systems/texlive/tlnet/archive/europecv.r61398.tar.xz
2021/12/25 | 38765 | graphics/pstricks/contrib/pstricks-add/doc/data/olympic.eps
2021/12/25 | 3840 | fonts/newpx/tfm/npxsups-Italic-ly1.tfm
2021/12/25 | 3828 | fonts/newpx/tfm/npxsups-BoldItalic-ly1.tfm
2021/12/25 | 3784 | fonts/newpx/tfm/npxsups-Italic-t1.tfm
-2021/12/25 | 378116 | systems/texlive/tlnet/archive/termsim.doc.r61399.tar.xz
2021/12/25 | 3776 | fonts/newpx/tfm/npxsups-BoldItalic-t1.tfm
2021/12/25 | 377608 | systems/texlive/tlnet/archive/erewhon.doc.r61395.tar.xz
2021/12/25 | 3764 | fonts/newpx/tfm/npxsups-Regular-ly1.tfm
@@ -676,16 +2140,16 @@
2021/12/24 | 66825 | macros/latex/contrib/biblatex-contrib/biblatex-apa/biblatex-apa.pdf
2021/12/24 | 664 | macros/latex/contrib/europecv/templates/europecv_biber.conf
2021/12/24 | 6593 | macros/latex/contrib/europecv/templates/europecv_photo.jpg
-2021/12/24 | 6520 | systems/texlive/tlnet/archive/collection-latexextra.r61391.tar.xz
2021/12/24 | 652056 | macros/latex/contrib/europecv/europecv.pdf
2021/12/24 | 64920 | macros/latex/contrib/biblatex-contrib/biblatex-apa/apa.bbx
2021/12/24 | 638748 | systems/texlive/tlnet/archive/asmejour.doc.r61388.tar.xz
-2021/12/24 | 616096 | systems/texlive/tlnet/archive/easybook.doc.r61390.tar.xz
2021/12/24 | 59916 | macros/latex/contrib/europecv/europecv.tex
+2021/12/24 | 55502 | macros/latex/contrib/wrapfig2/wrapfig2.dtx
2021/12/24 | 5336715 | fonts/erewhon.zip
2021/12/24 | 525897 | info/dtk-bibliography/dtk-bibliography.bib
2021/12/24 | 520 | info/dtk-bibliography/dtk-authoryear.dbx
2021/12/24 | 517290 | fonts/newpx/afm/zplr.afm
+2021/12/24 | 511808 | macros/latex/contrib/wrapfig2/wrapfig2.pdf
2021/12/24 | 510 | macros/latex/contrib/europecv/templates/europecv_thesis.bib
2021/12/24 | 4834 | info/dtk-bibliography/dtk-logos.sty
2021/12/24 | 4778 | macros/latex/contrib/europecv/templates/cv_template_en.tex
@@ -699,8 +2163,6 @@
2021/12/24 | 437961 | info/dtk-bibliography.zip
2021/12/24 | 423 | macros/latex/contrib/europecv/templates/europecv_pub.bib
2021/12/24 | 4207 | macros/latex/contrib/europecv/CONTRIBUTING.md
-2021/12/24 | 41261 | fonts/newtx/README
-2021/12/24 | 3987 | fonts/newtx/tex/newtx.sty
2021/12/24 | 38240 | macros/latex/contrib/europecv/templates/cv_template_academic_en.pdf
2021/12/24 | 382394 | info/dtk-bibliography/dtk-bibliography.pdf
2021/12/24 | 37766 | macros/latex/contrib/europecv/examples/europasslogo.eps
@@ -717,6 +2179,7 @@
2021/12/24 | 2690 | macros/latex/contrib/europecv/examples/europass-cv.tex
2021/12/24 | 2676 | macros/latex/contrib/biblatex-contrib/biblatex-apa/apa.dbx
2021/12/24 | 26706 | macros/latex/contrib/europecv/europecv.cls
+2021/12/24 | 26164 | macros/latex/contrib/diffcoeff/diffcoeff.sty
2021/12/24 | 2575 | macros/latex/contrib/europecv/README.md
2021/12/24 | 2498 | macros/latex/contrib/europecv/ecvbg.def
2021/12/24 | 235877 | macros/latex/contrib/europecv/examples/europass-cv.pdf
@@ -755,8 +2218,6 @@
2021/12/24 | 19106 | macros/latex/contrib/europecv/LICENSE
2021/12/24 | 1869 | info/dtk-bibliography/dtk-authoryear.bbx
2021/12/24 | 1810 | macros/latex/contrib/europecv/ecvlv.def
-2021/12/24 | 18020 | systems/texlive/tlnet/archive/easybook.source.r61390.tar.xz
-2021/12/24 | 17976 | systems/texlive/tlnet/archive/easybook.r61390.tar.xz
2021/12/24 | 1790 | macros/latex/contrib/europecv/ecvmt.def
2021/12/24 | 1755 | macros/latex/contrib/europecv/ecvpl.def
2021/12/24 | 1744 | macros/latex/contrib/biblatex-contrib/biblatex-apa/README
@@ -1290,6 +2751,7 @@
2021/12/23 | 246216 | fonts/erewhon/opentype/Erewhon-Bold.otf
2021/12/23 | 243568 | fonts/erewhon/opentype/Erewhon-RegularSlanted.otf
2021/12/23 | 243016 | fonts/erewhon/type1/Erewhon-BoldSlanted.pfb
+2021/12/23 | 2383 | macros/latex/contrib/diffcoeff/diffcoeff-doc.def
2021/12/23 | 238264 | fonts/erewhon/opentype/Erewhon-BoldSlanted.otf
2021/12/23 | 232524 | systems/win32/miktex/tm/packages/tcolorbox.tar.lzma
2021/12/23 | 2320 | macros/latex/contrib/bfh-ci/example/DEMO-BFHBeamer-Sidebar.tex
@@ -2905,113 +4367,3 @@
2021/12/21 | 1050 | support/arara/scripts/rules/arara-rule-tex.yaml
2021/12/21 | 1046 | support/arara/doc/rules/quickstart.yaml
2021/12/21 | 1032 | support/arara/doc/rules/manual.yaml
-2021/12/20 | 9907 | macros/latex/contrib/tcolorbox/tcolorbox.doc.coremacros.tex
-2021/12/20 | 9359 | macros/latex/contrib/tcolorbox/tcbraster.code.tex
-2021/12/20 | 90399 | macros/latex/contrib/tcolorbox/tcolorbox.sty
-2021/12/20 | 9035 | macros/latex/contrib/tcolorbox/tcbexternal.code.tex
-2021/12/20 | 89820 | macros/latex/contrib/zref-check/zref-check.dtx
-2021/12/20 | 88290 | macros/latex/contrib/tcolorbox/tcbskins.code.tex
-2021/12/20 | 882448 | systems/texlive/tlnet/archive/beebe.r61345.tar.xz
-2021/12/20 | 8722 | macros/latex/contrib/tcolorbox/tcolorbox.doc.intro.tex
-2021/12/20 | 862450 | macros/latex/contrib/knowledge.zip
-2021/12/20 | 8355 | macros/latex/contrib/tcolorbox/tcolorbox-example.tex
-2021/12/20 | 8120 | macros/latex/contrib/tcolorbox/tcbhooks.code.tex
-2021/12/20 | 7936 | macros/latex/contrib/knowledge/knowledge-configuration.dtx
-2021/12/20 | 7928 | macros/latex/contrib/tcolorbox/tcolorbox.doc.graphics.tex
-2021/12/20 | 76829 | macros/latex/contrib/tcolorbox/goldshade.png
-2021/12/20 | 767239 | macros/latex/contrib/knowledge/knowledge.pdf
-2021/12/20 | 7597754 | macros/latex/contrib/tcolorbox/tcolorbox.pdf
-2021/12/20 | 739886 | macros/latex/contrib/zref-check/zref-check-code.pdf
-2021/12/20 | 7168 | macros/latex/contrib/zref-check/MANIFEST.md
-2021/12/20 | 6699 | macros/latex/contrib/knowledge/knowledge-example.tex
-2021/12/20 | 6691 | macros/latex/contrib/tcolorbox/tcolorbox.doc.s_snippet.sty
-2021/12/20 | 64621 | graphics/pgf/contrib/xistercian/xistercian.dtx
-2021/12/20 | 6424 | macros/latex/contrib/tcolorbox/tcolorbox.doc.beamer.tex
-2021/12/20 | 6386 | macros/latex/contrib/tcolorbox/tcolorbox.doc.recording.tex
-2021/12/20 | 6351730 | macros/latex/contrib/tcolorbox.zip
-2021/12/20 | 6318038 | install/macros/latex/contrib/tcolorbox.tds.zip
-2021/12/20 | 62882 | macros/latex/contrib/tcolorbox/blueshade.png
-2021/12/20 | 6182 | macros/latex/contrib/tcolorbox/tcolorbox.doc.bib
-2021/12/20 | 59934 | macros/latex/contrib/tcolorbox/CHANGES.md
-2021/12/20 | 5990 | macros/latex/contrib/tcolorbox/tcolorbox-example-poster.tex
-2021/12/20 | 58854 | macros/latex/contrib/tcolorbox/tcolorbox.doc.listings.tex
-2021/12/20 | 5749 | macros/luatex/latex/autopuncitems/autopuncitems.tex
-2021/12/20 | 56438 | macros/latex/contrib/tcolorbox/tcolorbox.doc.documentation.tex
-2021/12/20 | 5632 | macros/latex/contrib/tcolorbox/tcbmagazine.code.tex
-2021/12/20 | 56212 | macros/latex/contrib/tcolorbox/tcolorbox.doc.skincatalog.tex
-2021/12/20 | 5577 | macros/latex/contrib/tcolorbox/tcolorbox.doc.quickref.tex
-2021/12/20 | 5404 | macros/latex/contrib/tcolorbox/tcolorbox.doc.abstract.tex
-2021/12/20 | 5048 | macros/latex/contrib/tcolorbox/README.md
-2021/12/20 | 469092 | macros/latex/contrib/tcolorbox/tcolorbox-example.pdf
-2021/12/20 | 456837 | macros/latex/contrib/zref-check/zref-check.pdf
-2021/12/20 | 455894 | macros/latex/contrib/tcolorbox/tcolorbox-tutorial-poster.pdf
-2021/12/20 | 44711 | graphics/mcf2graph/mcf_man_soc.mf
-2021/12/20 | 44697 | macros/latex/contrib/knowledge/knowledge-utils.dtx
-2021/12/20 | 4456 | macros/latex/contrib/tcolorbox/tcbminted.code.tex
-2021/12/20 | 44098 | macros/latex/contrib/tcolorbox/tcolorbox-tutorial-poster.tex
-2021/12/20 | 4030 | macros/luatex/latex/autopuncitems/autopuncitems.lua
-2021/12/20 | 39859 | macros/latex/contrib/tcolorbox/tcolorbox.doc.breakable.tex
-2021/12/20 | 39347 | macros/latex/contrib/tcolorbox/tcolorbox.doc.theorems.tex
-2021/12/20 | 38 | macros/latex/contrib/zref-check/DEPENDS.txt
-2021/12/20 | 383173 | graphics/mcf2graph/mcf_manual.pdf
-2021/12/20 | 353337 | graphics/pgf/contrib/xistercian.zip
-2021/12/20 | 35326 | macros/luatex/latex/autopuncitems/autopuncitems.pdf
-2021/12/20 | 35224 | macros/latex/contrib/tcolorbox/lichtspiel.jpg
-2021/12/20 | 351990 | graphics/pgf/contrib/xistercian/xistercian.pdf
-2021/12/20 | 3448 | macros/latex/contrib/tcolorbox/tcolorbox.doc.verbatim.tex
-2021/12/20 | 34192 | macros/latex/contrib/tcolorbox/tcbbreakable.code.tex
-2021/12/20 | 3414 | macros/latex/contrib/tcolorbox/tcblistings.code.tex
-2021/12/20 | 3367 | macros/latex/contrib/tcolorbox/tcolorbox.tex
-2021/12/20 | 33131 | macros/latex/contrib/tcolorbox/tcolorbox.doc.raster.tex
-2021/12/20 | 312162 | graphics/mcf2graph/mcf_example.pdf
-2021/12/20 | 29849 | macros/latex/contrib/tcolorbox/tcolorbox.doc.technical.tex
-2021/12/20 | 28432 | macros/latex/contrib/tcolorbox/tcolorbox.doc.vignette.tex
-2021/12/20 | 28148 | macros/latex/contrib/tcolorbox/tcbdocumentation.code.tex
-2021/12/20 | 281300 | macros/latex/contrib/tcolorbox/tcolorbox-example-poster.pdf
-2021/12/20 | 27086 | macros/latex/contrib/tcolorbox/tcolorbox.doc.xparse.tex
-2021/12/20 | 2614 | macros/latex/contrib/knowledge/makefile
-2021/12/20 | 2591 | macros/latex/contrib/tcolorbox/tcbprocessing.code.tex
-2021/12/20 | 25816 | macros/latex/contrib/tcolorbox/tcolorbox.doc.external.tex
-2021/12/20 | 2573 | macros/latex/contrib/zref-check/zref-check.ins
-2021/12/20 | 25557 | macros/latex/contrib/tcolorbox/tcolorbox.doc.poster.tex
-2021/12/20 | 2497 | macros/luatex/latex/autopuncitems/autopuncitems.sty
-2021/12/20 | 2492 | macros/latex/contrib/zref-check/zref-check.tex
-2021/12/20 | 24548 | macros/latex/contrib/tcolorbox/tcolorbox.doc.hooks.tex
-2021/12/20 | 22407 | macros/latex/contrib/tcolorbox/Basilica_5.png
-2021/12/20 | 217656 | systems/texlive/tlnet/archive/schulmathematik.doc.r61347.tar.xz
-2021/12/20 | 21663 | macros/latex/contrib/tcolorbox/crinklepaper.png
-2021/12/20 | 2158 | macros/latex/contrib/zref-check/zref-check-code.tex
-2021/12/20 | 2112 | macros/latex/contrib/zref-check/CHANGELOG.md
-2021/12/20 | 2055 | macros/latex/contrib/knowledge/README.md
-2021/12/20 | 20274 | macros/latex/contrib/tcolorbox/tcolorbox.doc.magazine.tex
-2021/12/20 | 20201 | macros/latex/contrib/tcolorbox/tcolorbox.doc.filling.tex
-2021/12/20 | 19956 | macros/latex/contrib/tcolorbox/tcolorbox.doc.fitting.tex
-2021/12/20 | 183634 | graphics/mcf2graph/mcf_mplib_exa.pdf
-2021/12/20 | 179904 | macros/latex/contrib/knowledge/knowledge.tex
-2021/12/20 | 1759 | macros/latex/contrib/knowledge/knowledge.ins
-2021/12/20 | 172713 | macros/latex/contrib/knowledge/knowledge-code.dtx
-2021/12/20 | 171255 | support/TeX4ht/source/ChangeLog
-2021/12/20 | 169300 | macros/latex/contrib/tcolorbox/tcolorbox.doc.coreoptions.tex
-2021/12/20 | 15656 | macros/latex/contrib/tcolorbox/tcolorbox.doc.initoptions.tex
-2021/12/20 | 15166 | macros/latex/contrib/tcolorbox/pink_marble.png
-2021/12/20 | 148 | macros/latex/contrib/tcolorbox/tcolorbox.doc.references.tex
-2021/12/20 | 14877 | macros/latex/contrib/tcolorbox/tcbfitting.code.tex
-2021/12/20 | 1414 | macros/latex/contrib/tcolorbox/tcblistingsutf8.code.tex
-2021/12/20 | 13913 | macros/latex/contrib/tcolorbox/tcblistingscore.code.tex
-2021/12/20 | 13613 | macros/latex/contrib/tcolorbox/tcolorbox.doc.sidebyside.tex
-2021/12/20 | 1284 | graphics/pgf/contrib/xistercian/README.md
-2021/12/20 | 12747 | macros/latex/contrib/tcolorbox/tcbvignette.code.tex
-2021/12/20 | 12453 | macros/latex/contrib/tcolorbox/tcbposter.code.tex
-2021/12/20 | 120668 | graphics/mcf2graph/mcf2graph.mf
-2021/12/20 | 1186240 | macros/latex/contrib/zref-check.zip
-2021/12/20 | 1167 | macros/luatex/latex/autopuncitems/README.md
-2021/12/20 | 11606 | macros/latex/contrib/tcolorbox/tcolorbox.doc.s_main.sty
-2021/12/20 | 11544 | systems/texlive/tlnet/archive/schulmathematik.r61347.tar.xz
-2021/12/20 | 11530 | macros/latex/contrib/tcolorbox/tcbtheorems.code.tex
-2021/12/20 | 113296 | macros/latex/contrib/tcolorbox/tcolorbox.doc.skins.tex
-2021/12/20 | 112 | macros/latex/contrib/tcolorbox/tcolorbox.doc.index.tex
-2021/12/20 | 1106 | macros/latex/contrib/tcolorbox/tcolorbox.doc.picturecredits.tex
-2021/12/20 | 1103001 | support/TeX4ht/source/tex4ht-4ht.tex
-2021/12/20 | 10268 | macros/latex/contrib/tcolorbox/tcbxparse.code.tex
-2021/12/20 | 10040 | macros/latex/contrib/tcolorbox/tcbskinsjigsaw.code.tex
-2021/12/20 | 1002 | macros/latex/contrib/zref-check/README.md
diff --git a/fonts/newtx/README b/fonts/newtx/README
index c28e7d17cd..dc559c9d80 100644
--- a/fonts/newtx/README
+++ b/fonts/newtx/README
@@ -1,10 +1,16 @@
This package, initially based on txfonts, provides many fixes and enhancements to the txfonts package, splitting it into two separate packages---newtxtext and newtxmath, which may be run independently of one another. It provides scaling, improved metrics, and other options. In particular, newtxmath offers a libertine option which substitutes Linux Libertine (provided with TeXLive and MikTeX) italic and Greek letters for the default Times letters, providing a good match for the Libertine text font, which is heavier than Computer Modern but lighter than Times, and in my experience, looks very sharp and clear on the screen.
-Current version: 1.7 2021-12-24
+Current version: 1.702 2021-12-27
This material is subject to the LaTeX Project Public License. See http://www.ctan.org/license/lppl1.3
for the details of that license.
+Changes in version 1.702
+The line to require the packages ifxetex and ifluatex in newtx.sty seems to have been deleted after testing was complete. Fixed.
+
+Changes in version 1.701
+A missing \fi in newtxtext.sty in a branch I had apparently not test after a change caused a crash. Fixed.
+
Changes in version 1.7
1. Very substantial modifications to newtxtext, adding new options and
permitting use under all latex engines.
diff --git a/fonts/newtx/tex/newtx.sty b/fonts/newtx/tex/newtx.sty
index bafd31db15..2734fed4cc 100644
--- a/fonts/newtx/tex/newtx.sty
+++ b/fonts/newtx/tex/newtx.sty
@@ -1,14 +1,14 @@
\NeedsTeXFormat{LaTeX2e}
%Package to simplify loading of newtxtext with newtxmath for all latex engines
-\def\fileversion{1.7}
-\def\filedate{2021/12/23}
+\def\fileversion{1.702}
+\def\filedate{2021/12/27}
\ProvidesPackage{newtx}[%
\filedate\space v\fileversion (Michael Sharpe) latex and unicode latex support for newtxtext with newtxmath]
\message{`newtx'v\fileversion,\filedate\space Integrated\space loading\space of\space newtxtext\space and\space newtxmath
\space for\space all\space latex\space engines\space (msharpe)}
-\RequirePackage{ifthen,trace}
+\RequirePackage{ifthen,ifxetex,ifluatex}
\def\ntx@mathlst{vecsep,amsthm,nosubscriptcorrection,subscriptcorrection,subscriptcorrectionfile,timesmathacc,varbb,vvarbb,nosymbolsc,noamssymbols,amssymbols,uprightscript,uprightGreek,slantedGreek,frenchmath,nonewtxmathopt,upint,smallerops,useBImacros,varg,varvw,noOT1}
\def\ntx@textlst{type1,nofontspec,no-math,defaultfeatures,lining,lf,oldstyle,osf,tabular,t,proportional,p,defaultsups,largesc,nott,nohelv,helvratio,spcfactor,spacing,stretch,shrink,defaultfeatures,oldSS,slashedzero,theoremfont,thmlining,trueslanted,scosf,tighter,looser}
diff --git a/fonts/newtx/tex/newtxtext.sty b/fonts/newtx/tex/newtxtext.sty
index 5c4b9aa2a8..9060ebd322 100644
--- a/fonts/newtx/tex/newtxtext.sty
+++ b/fonts/newtx/tex/newtxtext.sty
@@ -8,8 +8,8 @@
% Text is now directed to an extension of TeXGyreTermes rather than tx.
% 2.0 is first version of newtxtext to support both [pdf]latex and unicode latex.
-\def\fileversion{1.7}
-\def\filedate{2021/12/15}
+\def\fileversion{1.701}
+\def\filedate{2021/12/26}
\ProvidesPackage{newtxtext}[%
\filedate\space v\fileversion (Michael Sharpe) latex and unicode latex support for TeXGyreTermesX]
@@ -46,7 +46,7 @@
\else % [pdf]LaTeX
\ntxotffalse
\fi\fi
-\ifntxotf\ntx@origotftrue
+\ifntxotf\ntx@origotftrue\fi
}{\ntx@newtxtrue%
%\ifntxotf\typeout{ntxotftrue.^^J}\else\typeout{ntxotffalse.^^J}\fi
}
@@ -60,7 +60,9 @@
}
%%%%Start Options
\@ifpackageloaded{newtx}%
-{\@for\ntx@x:=\ntx@mathlst\do{\expandafter\DeclareOptionX\expandafter{\ntx@x}{}}}{}
+{\ntx@newtxtrue%
+\@for\ntx@x:=\ntx@mathlst\do{\expandafter\DeclareOptionX\expandafter{\ntx@x}{}}}{}
+
\newif\ifntx@nomath\ntx@nomathfalse
\newif\ifntx@lining\ntx@liningtrue
\newif\ifntx@tabular\ntx@tabulartrue % default is tabular lining figures
diff --git a/fonts/newtx/type1/zplr.pfb b/fonts/newtx/type1/zplr.pfb
deleted file mode 100644
index 497d533af1..0000000000
--- a/fonts/newtx/type1/zplr.pfb
+++ /dev/null
Binary files differ
diff --git a/graphics/asymptote/ChangeLog b/graphics/asymptote/ChangeLog
index 9b738aa108..23f6922e9b 100644
--- a/graphics/asymptote/ChangeLog
+++ b/graphics/asymptote/ChangeLog
@@ -1,3 +1,4304 @@
+commit d1641723495c25a4cf84da33a477078903c2ef4c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 27 12:42:11 2021 -0700
+
+ Fix MSDOS build script.
+
+commit 4700d4983ff030293279af1a87edaa76aaf24169
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 27 12:20:27 2021 -0700
+
+ Fix offscreen rendering.
+
+commit 292c58c4a3522a176dc173a41785e6b1027dbb05
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 27 12:19:21 2021 -0700
+
+ Standardize function name.
+
+commit f41d05416a79d7ed1d94b4e8e91d814107fe5821
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 27 12:10:50 2021 -0700
+
+ Support compilation without OpenGL again.
+
+commit 6fbfb9af1200e3c11d8a1addc31208b13e7e7d2d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 27 09:18:23 2021 -0700
+
+ Fix last revision.
+
+commit 02a7e2ef41b6a07387bcd0a2240db7ada758334f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 27 08:20:37 2021 -0700
+
+ Port to clang.
+
+commit 61dc2f16e833f8ce42a982ba41650521bcfc0997
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 27 00:31:54 2021 -0700
+
+ Revert "Revert "Disable link-time optimization when rpmbuild compiles Boehm GC.""
+
+ This reverts commit 5784093ef9a119ec07baf652247c1ddc5864b598.
+
+commit 95bb2394d155aa6387a62ec88cf9f32f0e42aedd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 27 00:28:36 2021 -0700
+
+ Update asymptote.spec.
+
+commit 5784093ef9a119ec07baf652247c1ddc5864b598
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 27 00:27:52 2021 -0700
+
+ Revert "Disable link-time optimization when rpmbuild compiles Boehm GC."
+
+ This reverts commit e5f413d9b889175e328ece23d0f17b7a7459deb8.
+
+commit 15c101fbb22d40899442779ea5dd9e1d40dc66f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 27 00:23:27 2021 -0700
+
+ Update MSDOS build script.
+
+commit d670d1fc6684ab72898a9fa290587bdc560745d5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 26 23:25:13 2021 -0700
+
+ Update asymptote.spec.
+
+commit 3aae0c65b207b91f0e3d2b5ed6822a1fa965dea2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 26 22:32:34 2021 -0700
+
+ Fix multiple output formats in threaded interactive mode; simplify code.
+
+commit 4af116e9191211a45adbe69f9ea998a95a4c11e3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 26 14:52:16 2021 -0700
+
+ Simplify webgl output.
+
+commit 187b2bb4bc29b294da4ab30f1eae3be72a7d9730
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 26 14:50:38 2021 -0700
+
+ Restore example.
+
+commit d887164de252ab1afb64b07181143b2700235dfd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 26 14:46:58 2021 -0700
+
+ Update asygl.
+
+commit 829efda683a36c22b5057336c2523584e2995670
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 26 14:44:59 2021 -0700
+
+ Enable webgl2 by default only for image-based lighting.
+
+commit 65408d84d6269f29d9c5d5fb56ebc2d5dc52c3c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 26 13:07:47 2021 -0700
+
+ Remove invisible files from CTAN archive.
+
+commit 69b4e78c4f94c710dcc45d56aaba0d34896ca54a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 26 11:56:43 2021 -0700
+
+ Fix issue #284: revert to CPU indexing if compute shader compilation fails.
+
+commit 23716cdcd6c925662351a74368ddbc1c906793ec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 25 18:31:50 2021 -0700
+
+ Set ibl=false when webgl2=false in HTML file.
+
+commit 5d28a10561b2c7a70367fed2df1180ab42d93f10
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 25 18:21:13 2021 -0700
+
+ Add missing newline.
+
+commit a2a608868151ac6c1bfa3d957f1db56af4c66cfd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 25 18:17:05 2021 -0700
+
+ Update asygl.
+
+commit 8712b3c391f55fd69710f7402470ba20090cbb4b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 25 18:12:05 2021 -0700
+
+ Implement setting for disabling webgl2 in resource-intensive examples.
+
+commit c7fa16084909b857d15aca90b137737c629a48db
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 25 09:27:58 2021 -0700
+
+ Remove unwanted files. Fix warning. Update README.
+
+commit bc331c961715af38f7d1d058273df1c90aa2a4b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 25 01:31:25 2021 -0700
+
+ Increment version to 2.72.
+
+commit b320257106f4e71db722bb86f9f6f6512ec4251d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 25 00:47:02 2021 -0700
+
+ Revert last commit.
+
+commit 21ac0d5289f25ebca72878f01cf334dc8cef492b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 25 00:34:16 2021 -0700
+
+ Update latexusage example.
+
+commit 10ffc44e992354ec0fa8fb0b0eb2b8f4f3db0c55
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 25 00:31:30 2021 -0700
+
+ Update example.
+
+commit a97127a82c4fb2410f8676ba674d1d665c0cf000
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 25 00:16:39 2021 -0700
+
+ Fix MSDOS Xasy installation.
+
+commit 71d25abd29c3108d323acd625d56a320a2fb9e14
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 24 23:37:58 2021 -0700
+
+ Update documentation.
+
+commit 55b405472c0cb603829b2216d1901ae3df5bde8a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 24 23:32:48 2021 -0700
+
+ Update diagnostic.
+
+commit e1943baa46f882e1556b576b6d793a20525cc41f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 24 23:14:41 2021 -0700
+
+ Reformat.
+
+commit cd318ded572ee29051d2b8cd24f69911f44bd58c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 24 23:13:00 2021 -0700
+
+ Port to MSDOS.
+
+commit 5263140b82b5306f4485ed822142893fdd878d0e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 24 22:43:14 2021 -0700
+
+ V3D: Add initial material list.
+
+commit 59321f61e940937155f0c89d9203d3038e99e2f4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 24 21:41:44 2021 -0700
+
+ Remove obsolete reference to ocg.sty.
+
+commit d21af153506234b038fe944a2de2312b479b8fa0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 24 19:56:55 2021 -0700
+
+ Update to Boehm gc-8.2.0.
+
+commit e5f413d9b889175e328ece23d0f17b7a7459deb8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 24 19:02:06 2021 -0700
+
+ Disable link-time optimization when rpmbuild compiles Boehm GC.
+
+commit e2f5c5d6794fa401f07d3448a7727a260c8a4a03
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 24 11:46:38 2021 -0700
+
+ Fix Makefile.in.
+
+commit a19237cf81f905a19a2d10abc912824b7a72afec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 23 21:59:53 2021 -0700
+
+ Document support for the Language Server Protocol.
+
+commit 769dd2e257f5161d64f7d4b83a3ecc667fc07836
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 23 20:46:18 2021 -0700
+
+ Disable Language Server Protocol under MSDOS until boost 1.69.0 or later is available for CYGWIN.
+
+commit 6b58bf411ee8d4f36989b389cb247a4d6f18aa28
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 23 20:44:17 2021 -0700
+
+ Port to MSDOS.
+
+commit 58e42f9ccbf4dc89594f1cc7a649bba811f929df
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 23 05:50:51 2021 -0700
+
+ Downgrade to Boehm GC 8.0.4.
+
+commit 17ed662797381269f0794da09a86a929f68e797a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 23 05:36:12 2021 -0700
+
+ Work around missing __log_finite function.
+
+commit 701f6679a0ed012ee9414ae7be056cee921198e1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 23 05:35:22 2021 -0700
+
+ git subrepo pull (merge) LspCpp
+
+ subrepo:
+ subdir: "LspCpp"
+ merged: "b1c5308e"
+ upstream:
+ origin: "git@github.com:vectorgraphics/LspCpp"
+ branch: "master"
+ commit: "9d772e36"
+ git-subrepo:
+ version: "0.4.1"
+ origin: "https://github.com/ingydotnet/git-subrepo"
+ commit: "a04d8c2"
+
+commit c1c34559a17c49a15c0f9eb7908b8e322b09962e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 23 04:44:34 2021 -0700
+
+ Downgrade to Boehm GC 8.0.6.
+
+commit ac47d91ec2bef01cfa58beb861eb4b6bcc58c4b1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 23 00:01:41 2021 -0700
+
+ Document command-line interface to http://asymptote.ualberta.ca.
+
+commit 863347f183c82f4b64c1e67c34207227c828d179
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 22 14:02:00 2021 -0700
+
+ Document V3D output format specification; fix Makefile dependencies.
+
+commit 1210cc36ca7a6d018887e59cc56478a309856804
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 22 12:50:10 2021 -0700
+
+ Support compilation again without XDR.
+
+commit c46a45481f3db464115cb091f6c696ccc674ae7c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 21 11:08:43 2021 -0700
+
+ Port to MSDOS.
+
+commit 0151a7887fd90a977ca2e8f6c8f1e072d7d6f408
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 21 00:07:39 2021 -0700
+
+ Update configure.ac.
+
+commit dfb0dad25d6846802e47b49026de547d558ecc96
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 20 23:29:56 2021 -0700
+
+ Fix typo.
+
+commit 20b3bd3020f6547478eea70f307fb3f8c13d5034
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 20 22:44:10 2021 -0700
+
+ Fix Makefile dependency on Boehm GC includes.
+
+commit a031db668c7b382979b032fba087a79c493264b4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 20 20:34:25 2021 -0700
+
+ Fix Makefile dependency.
+
+commit d2bdbbda821a807f8ef9622b52263a50a832470d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 20 18:48:40 2021 -0700
+
+ Update to Boehm gc-8.2.0.
+
+commit 734cc1b4cd8a464b9780bdf48ca01754eb5d99e7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 20 15:11:42 2021 -0700
+
+ Replace RETSIGTYPE with void.
+
+commit 032127e7c97232468b3bb92e95aad1ae80e99fc5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 20 14:59:01 2021 -0700
+
+ Update configure.ac.
+
+commit 0ab436e4ed8dd9e7cda392bf88216aba551b2525
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 20 14:30:10 2021 -0700
+
+ Fix virtual function signature.
+
+commit 2542600b2fb805a7c1ed79604bbccee762ac6709
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 20 13:50:22 2021 -0700
+
+ Fix clang++ warnings.
+
+commit acb1f93544b977131caa684205e1492990d1d87e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 20 13:20:19 2021 -0700
+
+ git subrepo pull (merge) LspCpp
+
+ subrepo:
+ subdir: "LspCpp"
+ merged: "fc6491ae"
+ upstream:
+ origin: "git@github.com:vectorgraphics/LspCpp"
+ branch: "master"
+ commit: "c3ee4473"
+ git-subrepo:
+ version: "0.4.1"
+ origin: "https://github.com/ingydotnet/git-subrepo"
+ commit: "a04d8c2"
+
+commit 353c1124aacece2e29240fe7b9b223a2eb5da8e6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 20 12:48:59 2021 -0700
+
+ git subrepo pull (merge) LspCpp
+
+ subrepo:
+ subdir: "LspCpp"
+ merged: "bae08636"
+ upstream:
+ origin: "git@github.com:vectorgraphics/LspCpp"
+ branch: "master"
+ commit: "89de4a84"
+ git-subrepo:
+ version: "0.4.1"
+ origin: "https://github.com/ingydotnet/git-subrepo"
+ commit: "a04d8c2"
+
+commit 7ec627d96e114196c5abe3f1b73adfafb98048c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 20 12:47:43 2021 -0700
+
+ Remove -Llib from OPTS.
+
+commit 48eb765869f1a1fb63a6873cdf592137995ff4f3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 20 10:29:58 2021 -0700
+
+ Port to MacOS X.
+
+commit 804c3527ef71140b0de45ef62582d1d7b2a4f742
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 20 09:14:44 2021 -0700
+
+ Enable offscreen viewing.
+
+commit 8223db3db7e15670f627f2fe07f19b9419f940ba
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 19 22:11:58 2021 -0700
+
+ Revert "Fix hang on display."
+
+ This reverts commit 9aee221cb61a00c2ef275c4eb0415e7b913b234e.
+
+commit 16ba97539f36338fa065c0679631185021be42f1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 19 17:54:09 2021 -0700
+
+ Fix last revision.
+
+commit e4d18621486bc4d5452cfdd3558844fa894eadd7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 19 15:04:25 2021 -0700
+
+ Fix boost header file dependencies.
+
+commit 588d4d204cb0874c1e4a4229c5b8108e9785e049
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 19 12:04:02 2021 -0700
+
+ Undo commit 3f58c24ceb5ef71066fbd6a5b9746bc9638558bd.
+
+commit 70e1cfcdb33779813fe4ebd76aabcb14b082b1f4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 19 13:57:02 2021 -0700
+
+ Remove boost header file dependencies.
+
+commit 96e143cd4af5541dac04a4f1220f6aa613af413c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 19 09:51:18 2021 -0700
+
+ Fix git submodule status errors due to empty git subrepo directories.
+
+commit ebbdaa960a8824c209d30b0059516469df563a10
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 19 09:34:10 2021 -0700
+
+ Revert "Disable jekyll on GitHub Pages."
+
+ This reverts commit 044d7837773f2845b1f8257927040d5df986d81d.
+
+commit 56fad9d2ad0d0bf6ee626f1952ef5744ab43a6bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 18 22:29:55 2021 -0700
+
+ Disable orthographic adjustment in commit ab6c72c152ec8ad0e052706ac16023bf044ab550 for PRC output.
+
+commit 1a9bd32158e27bb11c134b8dc2521ccb5500872c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 18 21:16:15 2021 -0700
+
+ V3D: Apply lossy setting also to headers; fix xstream xbyte reads.
+
+commit d81d2287f3438ef936de2ca72632ac8540cf908b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 18 20:40:38 2021 -0700
+
+ Fix render parameters.
+ Add PRC compression=Single value to approximate single precision,
+ for benchmarking against V3D with settings.lossy.
+
+commit 0057b91fd6e47da2f09c8e00cd56c3621b6b510f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 18 12:33:07 2021 -0700
+
+ Simplify code.
+
+commit 044d7837773f2845b1f8257927040d5df986d81d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 18 08:56:42 2021 -0700
+
+ Disable jekyll on GitHub Pages.
+
+commit d385f531c03e6b2548d4f38bf3b0b07d94e3066d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 18 08:47:10 2021 -0700
+
+ Remove unused binary image.
+
+commit a410a2940d93b2ef8ff97458e1bf506e6f5a5fdb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 18 08:01:14 2021 -0700
+
+ Add minimal index.html for GitHub Pages.
+
+commit 21519f9d97d15cdc83f27bd869a294b2bc302ca0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 18 07:47:20 2021 -0700
+
+ Set theme jekyll-theme-cayman
+
+commit fd20ee1eb8fbf69e2d7bddfb98728b3d487abda0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 18 00:08:57 2021 -0700
+
+ PRC: Fix last commit.
+
+commit 6f4f179e121eb7002f75cd8ad9fa49244fb9b1ae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 17 22:39:48 2021 -0700
+
+ PRC: Suppress viewing of prc output.
+
+commit aee35e71a1ea3cf086dc1fcf104e973f9d4071f0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 16 00:07:18 2021 -0700
+
+ V3D: Use global explicitNI and explictCI flags for better triangle group compression.
+
+commit b2811f9072e39e1172b86a58079bb187f24dd53e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 15 15:00:32 2021 -0700
+
+ V3D: Remove unused parameter.
+
+commit 6d686ea349ca7b3a08b4972c88b7c1d2472838b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 14 17:43:29 2021 -0700
+
+ V3D: Add on v3d extension if needed.
+
+commit e68834bb93296e670eafc3bb084a1831e6cfaaff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 14 13:47:48 2021 -0700
+
+ Check for existence of v3d input file.
+
+commit ef941786820e1d10cb06c29dcc4d311550a1057c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 14 11:44:30 2021 -0700
+
+ Fix rendering of triangle groups.
+
+commit d3a6d07ed3d63a1bcc9d799ff1d378c6b850e3aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 13 22:55:32 2021 -0700
+
+ V3D: Fix LightHeader size.
+
+commit 10fbb46a8b1f889bab093578439c2af5d380c69e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 13 17:54:31 2021 -0700
+
+ Fix issue #280.
+
+commit 7eb3221ee32816207d8f99af26eaf9c2c2fc5654
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 13 17:51:50 2021 -0700
+
+ Fix commit b979946b3e9c7bef55f53421a711c823c5585a8e.
+
+commit 297dcd00a1333349bd5e8fe7a49341fe757ab721
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 13 11:36:04 2021 -0700
+
+ git subrepo pull (merge) LspCpp
+
+ subrepo:
+ subdir: "LspCpp"
+ merged: "0ecc0ecd"
+ upstream:
+ origin: "git@github.com:vectorgraphics/LspCpp"
+ branch: "master"
+ commit: "200001e9"
+ git-subrepo:
+ version: "0.4.1"
+ origin: "https://github.com/ingydotnet/git-subrepo"
+ commit: "a04d8c2"
+
+commit 0c78f5d505c86e0483fa86564c95cdccd1936142
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 13 00:20:42 2021 -0700
+
+ Fix last revision.
+
+commit fbea3a770be6e95fdcc5040724bbd26b731740b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Dec 13 00:15:30 2021 -0700
+
+ Fix compilation for configure --disable-lsp.
+
+commit b60ef92ffde1edd6b0a8a589c1a937317dc3a3c2
+Merge: 117f64ba bc239956
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 12 23:30:34 2021 -0700
+
+ Merge branch 'lsp'.
+
+commit bc2399563cc1325e92cb35eab1ac19c0cd7b593e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 12 23:22:05 2021 -0700
+
+ LSP: Check for boost library and adjust C++ version if needed.
+
+commit 725532eada03a5eba8f0364ae32761c6637b6a27
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 12 20:56:11 2021 -0700
+
+ git subrepo clone (merge) git@github.com:vectorgraphics/LspCpp
+
+ subrepo:
+ subdir: "LspCpp"
+ merged: "47760384"
+ upstream:
+ origin: "git@github.com:vectorgraphics/LspCpp"
+ branch: "master"
+ commit: "47760384"
+ git-subrepo:
+ version: "0.4.1"
+ origin: "https://github.com/ingydotnet/git-subrepo"
+ commit: "a04d8c2"
+
+commit 117f64ba06c983e67daacce64391d0521ad9a3ff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 12 11:18:46 2021 -0700
+
+ V3D: Add placeholder 2D types.
+
+commit 95c04ac3dea4fd20a7a13a33f767062950796d1e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 11 22:08:02 2021 -0700
+
+ Remove blank comments from v3dheadertypes.csv.
+
+commit b979946b3e9c7bef55f53421a711c823c5585a8e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 11 21:37:18 2021 -0700
+
+ Move byteinv to C++ code.
+
+commit 82d1eacc0115a3b44a8d2e51e6885228a226b810
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 11 21:25:24 2021 -0700
+
+ Improve make_unique support.
+
+commit b0617bb6a1c830498aaaebb37cbbb13fd6b5704a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 11 18:02:31 2021 -0700
+
+ LSP: Port to C++14.
+
+commit 6f238b01ae31f81b7a20730b1413077e0837e08c
+Merge: 895c90e8 5f2f5ba5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 11 12:18:57 2021 -0700
+
+ Merge branch 'master' into lsp.
+
+commit 5f2f5ba5515b6585e49f1c3983be15f71f59411c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 11 11:47:55 2021 -0700
+
+ Port to C++-11.
+
+commit f73647c9b9bac0fbdc2a63915968a68b28fa8792
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 10 23:14:10 2021 -0700
+
+ Update documentation and example.
+
+commit 0a99516528f94ba5ef447ab075f448080dae7697
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 10 20:05:22 2021 -0700
+
+ Port to C++-14.
+
+commit 1b51a78ca2730484282c3f76db40c2781059a106
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 10 19:01:42 2021 -0700
+
+ XASY: Avoid unwanted line offset.
+
+commit fac7a3db5e93b6401c63e8faaab479a53e1f337e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 10 18:07:49 2021 -0700
+
+ XASY: Implement -render option.
+
+commit 39b596f9253727d2a3c64a18696fe9c80f138f27
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 10 17:57:56 2021 -0700
+
+ XASY: Fix 3D picture sizing.
+
+commit 11f0eb133aff09d23428ae53ebc5aa6f001bf317
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 9 12:16:26 2021 -0700
+
+ Fix last revision.
+
+commit 3f58c24ceb5ef71066fbd6a5b9746bc9638558bd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 9 10:46:00 2021 -0700
+
+ XASY: Combine 2D and 3D pictures.
+
+commit 4d07369721fe15cbf92411c7b6d013f7b76aad9a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 9 10:42:13 2021 -0700
+
+ XASY: Assign initial key to all nodes of a 3D picture.
+
+commit c451cf62bcae8234d9074886ebeb6264cdab34b7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 9 10:39:17 2021 -0700
+
+ Fix infinite loop.
+
+commit eb1968c76b3b46cddc03fc5f6e7fd994cb206619
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 9 10:15:14 2021 -0700
+
+ Fix uninitialized variables.
+
+commit 303906eff9f4d147d3fcece633928692ac9d6395
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 8 19:26:47 2021 -0700
+
+ Update example.
+
+commit 8db6799673c2a1df4bbcdbbb12f8f13283f33b6d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 8 16:36:37 2021 -0700
+
+ Update asygl.
+
+commit 611c636b4b2f1e163f65ae93a3973a4df664ae8f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 8 16:34:46 2021 -0700
+
+ Allow embedded webgl and weblg2 contexts to coexist.
+
+commit 61262aede26d4b3b940f00cbe7db52a92948f222
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 8 15:09:24 2021 -0700
+
+ Revert "Require EXT_color_buffer_float for webgl2."
+
+ This reverts commit 12618432904d0ef9ab52a9b6390bf20c015ca7b3.
+
+commit b4d6f5f936ea5d09b82d816131aadebeb7543d7f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 8 12:42:09 2021 -0700
+
+ Update asygl.
+
+commit 12618432904d0ef9ab52a9b6390bf20c015ca7b3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 8 12:38:54 2021 -0700
+
+ Require EXT_color_buffer_float for webgl2.
+
+commit 0820480eeca20ba83dd0c6dfa12e7f1678dc07da
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 8 12:05:00 2021 -0700
+
+ Update asygl.
+
+commit 1cfa9d36ce6a0bf1a51265f1f25463ec77a46561
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 8 12:04:01 2021 -0700
+
+ Remove obsolete alerts.
+
+commit 23bfe9b348c5e3f186acbf4d8579adac8b4b0bd2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 8 11:19:27 2021 -0700
+
+ Fix offscreen rendering.
+
+commit 5f156092e8fa7924ded2299080fff4260c966686
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 8 11:05:52 2021 -0700
+
+ Delete trailing whitespace.
+
+commit 8edad4e3e6c4f2c31b291dbb81cda576d84c7195
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 8 10:05:50 2021 -0700
+
+ XASY: Only edit asy code: wait for editor and then reload.
+
+commit be2b3a80c4734f444d6a571159d9b9946dd8c6b1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 8 07:57:41 2021 -0700
+
+ XASY: Calculate maxKey explicitly.
+
+commit 1fd9331d4dc8e3a6d49645a52b42cac0f2942894
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 7 23:18:43 2021 -0700
+
+ XASY: Remove duplicate objects.
+
+commit d1d8d9710c641dfd84c5aa4dce3ebde66d41bafe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 7 21:06:30 2021 -0700
+
+ XASY: Update maxKey and globalObjectCounter on loading xasy file.
+
+commit 4b123f011329554e602aa945e0c91fbcda802290
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 7 16:00:12 2021 -0700
+
+ Reformat.
+
+commit 61798c5a195cafc22eb64fc02675e227ebd83cd8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 7 13:01:59 2021 -0700
+
+ Restore example.
+
+commit f7a84bdad76882658a1248417f418fcb9de47845
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Dec 7 10:41:00 2021 -0700
+
+ XASY: Correctly account for xmap line offset.
+
+commit 49371c4f04ebf906904c3242aeb6bbe5985e272e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 5 22:51:20 2021 -0700
+
+ Check array index.
+
+commit e8447947f359ce1d832ba42c7c03779de7fd62de
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 5 22:34:42 2021 -0700
+
+ Add plus and diamond markers to Mark and MarkFill arrays.
+
+commit d66b7c757a87f7a747730ab31fa59e93a4716d8d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 5 21:15:37 2021 -0700
+
+ XASY: Assign correct KEY to 3D images.
+
+commit 01c144622b1c880929bb8eadcabd20373aa37093
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 5 10:52:55 2021 -0700
+
+ Simplify code.
+
+commit 9d99a2af7f6c690cbe3dde266cf6d3fba20eac24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Dec 5 05:53:55 2021 -0700
+
+ Delete pictures at end of scope.
+
+commit 23b76b2cdd39c57e29dbbd0ac7787fa587ecdcfe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 4 22:28:57 2021 -0700
+
+ Ensure rendering width and height are positive.
+
+commit 86245eca5e591b823696a5d8e551a42fcbdbc8aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 4 21:34:32 2021 -0700
+
+ Embed png images within svg output again.
+
+commit efafcec14de4fbf94023705face48e3c5eeb41fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 4 15:16:21 2021 -0700
+
+ Restore example.
+
+commit 1aee785b3fd7d7648644f9727a2605744fe0578d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 4 14:23:21 2021 -0700
+
+ XASY: Support context TeX engine.
+
+commit 1f86d94950fb6a9e00fa9e0160b64f7f1c0ffa42
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Dec 4 08:42:54 2021 -0700
+
+ Support luatex TeX engine again.
+
+commit ad1365d78a6d41dcabf3ad363b85a4d7b90d68ae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Dec 3 10:02:32 2021 -0700
+
+ XASY: Simplify support for multiple PostScript files on dvisvgm command line.
+
+commit 1a32da79a8c674a1b0d5a7060f62a11cdd9facda
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 2 22:02:38 2021 -0700
+
+ XASY: Support multiple PostScript files on dvisvgm command line.
+
+commit e1d9c115b923dabb42f69c5034d20b9924fb2c9e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 2 05:28:31 2021 -0700
+
+ Delete texput files.
+
+commit 92d2ceafbf87a50d70711e4bef0e102f64acd126
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 2 04:27:43 2021 -0700
+
+ XASY: Rename debug flag.
+
+commit 35736fbd98a3f9aed49bfca1f195a27e9483a00f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 2 04:01:33 2021 -0700
+
+ XASY: Don't overwrite extension in loadFile.
+
+commit 571d1eadab6c5edd743320c7a12f60d971cf58f8
+Merge: b47ab404 20fe8cd8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 2 03:41:32 2021 -0700
+
+ Merge branch 'Qt'.
+
+commit 20fe8cd80ad7bba8745a0515a3f1722d445f463b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Dec 2 03:38:26 2021 -0700
+
+ Revert "XASY: Set up work for adding 3d objects in the interface."
+
+ This reverts commit 98ba7ecd29378505c57c6579ab9ed06680a4584b.
+
+commit b47ab4045cde9113111415a810cf75cc95f3eacf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 1 22:14:58 2021 -0700
+
+ Add example of image-based lighting.
+
+commit c01e1750697868bb0f5136c6ebde021a82034834
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 1 22:12:03 2021 -0700
+
+ XASY: Support xelatex and lualatex tex engines again.
+
+commit fd584e400cbc982792494e5e0b05b34dcc7ac335
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 1 21:45:08 2021 -0700
+
+ Make bshift return a new bbox.
+
+commit 45ddd44e7c39666c62f1058e0472e5fdc1f113f4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 1 20:51:02 2021 -0700
+
+ Check for cson module; remove obsolete option formats.
+
+commit 50c67e8ea73e1053037bf0dfaa67c2a0f6f28bec
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 1 20:29:49 2021 -0700
+
+ XASY: Make .asy the default extension again.
+
+commit 6504f81c83507a4754701e26668c006a10a13fbe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 1 19:40:36 2021 -0700
+
+ Remove obsolete code.
+
+commit d61699ad72f7ee95262cf6831b1618e382eb530a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 1 19:22:34 2021 -0700
+
+ Batch deconstruction.
+
+commit bf8956b682d61eaddfeb68e7950769c269cd6e51
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Dec 1 18:37:23 2021 -0700
+
+ XASY: Re-enable rendering of 3D images.
+
+commit 2cb129d85a32ae80b0652da1a50f5e6fb717db35
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 22:09:21 2021 -0700
+
+ XASY: Fix segmentation fault.
+
+commit e5f45896916caf91fd6e304413dd8dcb8477b230
+Merge: 2fac9e58 86954d86
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 17:40:50 2021 -0700
+
+ Merge branch 'master' into Qt.
+
+commit 2fac9e58b131a3879fa461ca16d25d6f21d63e05
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 17:37:31 2021 -0700
+
+ Fix deletion of asy objects.
+
+commit 294de4a41db9f2240d2651cb5271cf18cefb2f4e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 16:17:47 2021 -0700
+
+ XASY: Remove spurious xmap comments.
+
+commit fc0ae4f8a6566fd2b17c4d7de8a4ff8ef4ebcf1e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 15:39:51 2021 -0700
+
+ GUI: Retain deleted objects and their keys.
+
+commit 86954d8680ae6a6d3e416fa3a7dea56c97e39662
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 21 00:03:27 2021 -0700
+
+ Remove redundant patch from teapot example.
+
+commit 1d9322c22f2c3bae7ff87a083ec174f74f7047f7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 20 23:52:20 2021 -0700
+
+ Update asygl.
+
+commit 8fd0a9426a2efd1036f0b38a05059689973d2753
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 20 23:49:55 2021 -0700
+
+ Implement WebGL2 optimizations.
+
+commit cf00aca4c825cc37d14938fa0210b948bffd2e67
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 20 23:48:33 2021 -0700
+
+ IBL: Enable image-based-lighting for transparent WebGL objects.
+
+commit aa5be72ec60608e1940df034e63602440ace0bf2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 20 21:22:15 2021 -0700
+
+ Update asygl.
+
+commit b21d65aafe245d8ac57e6778dfc1c6132b16089e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 20 21:21:21 2021 -0700
+
+ Fix WebGL errors.
+
+commit 242785789a0bd458ca0c798669f41d5cf106d7f4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Nov 20 09:59:35 2021 -0700
+
+ Improve missing EXR image diagnostic.
+
+commit bdd70abb16f23e1e76d3768455805fc3a0ddda15
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 19 17:59:07 2021 -0700
+
+ Fix buffer overflow.
+
+commit 194fcc875bdc43b88eb030818b424ac1bff11274
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 19 16:39:35 2021 -0700
+
+ Improve clamping.
+
+commit a6c5dfef30582c2ce80c0f8c5b4e0738d927b371
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 19 15:38:16 2021 -0700
+
+ Update diagnostic.
+
+commit e91b0f87d347fa1ea7ed98717cb40ab29cb59515
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 19 14:13:12 2021 -0700
+
+ IBL: Move precomputed image files to gitlab.
+
+commit 10a602f4de8754a3ea6a9e55d3f87ced11aa40b0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 18 23:36:57 2021 -0700
+
+ Remove snowyField images.
+
+commit 45285c1da090797f8bb28733339ee76de643419e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 18 23:17:25 2021 -0700
+
+ IBL: clamp oversaturated values.
+
+commit b182a0d4b72c5511e7aa83629f0f3c7dbac8cf65
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 18 20:24:23 2021 -0700
+
+ IBL: Improve EXR diagnostic.
+
+commit 541038fedb724214b2c22858b78df2e7dcd6134a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 18 14:32:16 2021 -0700
+
+ Fix directory permissions.
+
+commit c59a4039317b66b3e6091113ee6a408184c65f2a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 18 14:30:51 2021 -0700
+
+ Change default imageURL to https://asymptote.sourceforge.io/ibl.
+
+commit c47263d97a92f28bb6ce1554f2c2673d8402f17d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 23:24:11 2021 -0700
+
+ Implement int[] sequence(int n, int m, int skip).
+
+commit cdfda4400beb12521ddb143a43df3d8aac793e13
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 23:18:47 2021 -0700
+
+ CUDA: Add usage information.
+
+commit dede658f8fecbec2f62d12255eac534d07dffe32
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 22:56:47 2021 -0700
+
+ Fix buffer overflow on small images.
+
+commit 166e21507e2191e499c8b4acedddc4eb4fae82bb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 17:32:50 2021 -0700
+
+ Update asygl.
+
+commit 0a85d36a173fefbfdb2c9a0f42a707990878b307
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 17:32:11 2021 -0700
+
+ IBL: Rename default image.
+
+commit 2931c7c098ac8d11955a52cf9ac7d83dbf45b7ef
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 17:28:24 2021 -0700
+
+ IBL: Fix texture alignment.
+
+commit 36b88dcfe3934bd505263047ab2d76d86eed0d10
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 13:20:46 2021 -0700
+
+ Update asygl.
+
+commit e429470b41ef1385869f4e80538520e99327b68d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 13:20:17 2021 -0700
+
+ IBL: Port to Safari browser.
+
+commit 4904634cce7a015bb5b38f0e3da8ef25cda8d98f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 12:12:09 2021 -0700
+
+ Update asygl.
+
+commit 971afe2dbd98295a09518d97144b7aa9a00b0594
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 12:10:45 2021 -0700
+
+ IBL: Wait for Module.ok.
+
+commit de52f109ce7524d8135b689174ea01a07178c67c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 10:24:20 2021 -0700
+
+ Update asygl.
+
+commit 78ce79108e5ba301b263ab630b11cfcdf500a7d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 10:21:43 2021 -0700
+
+ IBL: Wait for EXRLoader to become available.
+
+commit 1e62b2adc3a9c576cd809354c8b28c88aed9d552
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Nov 17 09:58:42 2021 -0700
+
+ IBL: test single file version of tinyexr.
+
+commit df370d54fec4b4defdaf00bc3a6adf9128ffa18f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 16 23:57:42 2021 -0700
+
+ Update asygl.
+
+commit 6fde5c414cfa02e3771126a29d7d376d9d0ee414
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 16 23:55:56 2021 -0700
+
+ Standardize location of image-independent refl.exr.
+
+commit 7c82febdb56ee320cf7b89c8ce3b68e2ed6fd7aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 16 22:58:27 2021 -0700
+
+ Fix ibl orientation and offset; re-organize fragment shaders.
+
+commit 4b32c102bebd2e95737ba492f42468857a1752b7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 16 22:57:30 2021 -0700
+
+ CUDA: Fix logic.
+
+commit 2f842c4773e56850cc6f1d85a82b120cdbdd5702
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 16 16:17:01 2021 -0700
+
+ Exit gracefully on missing EXR file.
+
+commit 11afb32b51e6f4f7508d9063552d266788aa6da8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 16 16:15:59 2021 -0700
+
+ Separate image name from imageDir and imageURL.
+
+commit c69fcaa50d93930451b0828454beedee069ee8ab
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 16 16:15:14 2021 -0700
+
+ Fix logic.
+
+commit 753e3d13eee10066fb63ab491a008e634ddbc3eb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 15 22:28:52 2021 -0700
+
+ Replace deprecated OpenGL function.
+
+commit 53e1291eabc60e9d8cb1bee8481c6fdefdd22ee9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 15 21:41:39 2021 -0700
+
+ Fix compilation warning.
+
+commit 32e5a3a766cc17e26740ad1bf7d93062abc46316
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 14 22:59:46 2021 -0700
+
+ Add tinyexr JavaScript support files.
+
+commit 40a222986d8869296975732e9c30298dc66aaf09
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 14 22:52:57 2021 -0700
+
+ Update asygl.
+
+commit 11e4f084422311f4049ae30690706f32d5f0e4b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 14 22:45:00 2021 -0700
+
+ Add sample IBL files.
+
+commit 278261e685996a747f3aca51358293653be87a7c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 14 22:38:26 2021 -0700
+
+ Standardize image-based lighting; port successively halved version to WebGL.
+
+commit 9e723d1c0c18d7983c870c987f34ec53df1b5bca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Nov 14 10:29:00 2021 -0700
+
+ Recompile tinyexr.js.
+
+commit b048f3ed57ea6700cbf73225e642c23b3c707263
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 12 11:47:19 2021 -0700
+
+ git subrepo pull (merge) cudareflect/tinyexr
+
+ subrepo:
+ subdir: "cudareflect/tinyexr"
+ merged: "67010eae"
+ upstream:
+ origin: "https://github.com/syoyo/tinyexr"
+ branch: "master"
+ commit: "67010eae"
+ git-subrepo:
+ version: "0.4.1"
+ origin: "https://github.com/ingydotnet/git-subrepo"
+ commit: "a04d8c2"
+
+commit 150a1ec3c1460b49a4a7c6940c8ca4ab6b5088c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Nov 12 10:03:17 2021 -0700
+
+ Update gl.js.
+
+commit a49741358f3f9c9b79bb24dac263c4dec8d1d785
+Merge: c7c084b6 568da114
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 11 22:05:36 2021 -0700
+
+ Merge branch 'master' into cudareflect.
+
+commit c7c084b64b93bb3dab3f95a2077e7aa96a132114
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 1 10:09:16 2021 -0600
+
+ Remove obsolete comments.
+
+commit 568da1148099379911849355cff8d2afde5ec148
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 11 21:31:24 2021 -0700
+
+ Fix vertex-dependent colors.
+
+commit 6c9c98f5969ded7634da1be6e6360c6213253914
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Nov 9 19:44:32 2021 -0700
+
+ V3D: Fix garbage collection.
+
+commit 1f3330aa53c1f7b17de27c85f67e89be654d6dd3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 22:49:27 2021 -0700
+
+ Fix commit 263285fa05e0cae294b1ec8abda292407a6eb83b.
+
+commit da93b0f2fe7616f9dafddc346da292fe67fa261b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 11:54:51 2021 -0700
+
+ Interpolate vertex-dependent colors as floats.
+
+commit 12315bf7b99311b434d0662e362012f83b35b76e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 10:36:04 2021 -0700
+
+ Restore efficient Bezier rendering engine; fix prerendering for vertex-dependent colors.
+
+commit ddeaab0ce72488ea08c05415d5170647f6e8c866
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Nov 8 10:32:26 2021 -0700
+
+ Fix byteinv.
+
+commit bf21a3428f7dcf3466fa78a10ab01b1c01fa8486
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Nov 4 05:21:29 2021 -0600
+
+ Allow compilation without OpenGL support again.
+
+commit 24ab461a7e2c7768b7735620af723b4d1a04bee3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 31 10:45:22 2021 -0600
+
+ Standardize AsyGL and v3d; remove alpha channel from light direction.
+ Increment asygl to version 1.01.
+
+commit f9e36b082ae4516e143552b685efb5f9860be252
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 31 10:41:14 2021 -0600
+
+ V3D: Mention source file in header comment.
+
+commit 9f9b9cfdb450048341f4eac3778e4e1f5999b8a9
+Merge: ae624c44 3b3f33bb
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 31 09:59:52 2021 -0600
+
+ Merge branch 'master' into v3d.
+
+commit 3b3f33bb7f0ded94761de6f03497bbadc7169d70
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 30 21:49:04 2021 -0600
+
+ Cache background color.
+
+commit 263285fa05e0cae294b1ec8abda292407a6eb83b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 30 21:40:03 2021 -0600
+
+ Keep 2D and 3D pictures separate.
+
+commit 4cd7ad1080819d88c1887e4e645124ed94c9a5e8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 30 21:39:54 2021 -0600
+
+ Fix last revision.
+
+commit b9a1aa0b3835ace3cfc0c5978abc75e7e61b1bb0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 30 13:48:14 2021 -0600
+
+ Clear offset buffer in blend shader.
+
+commit 7988a6f01a3e45e9099d89bcdad0ddc8a20f9337
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 29 17:21:53 2021 -0600
+
+ Enforce std430 layout.
+
+commit 7257d628a6c49dd982787e05a8778a284c1faaf2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 29 00:25:56 2021 -0600
+
+ Choose unique buffer names.
+
+commit 39be6abe5afbc2cc846ee41b08db6a13a8bd8059
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 29 00:17:46 2021 -0600
+
+ Fix outline and wireframe mode.
+
+commit 70e20fc773e68d2fe3ed4da86bb77c218c6bc431
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 26 22:34:36 2021 -0600
+
+ Remove troublesome u qualifiers from preprocessor constants.
+
+commit 3724879c8b1ca767c75559406c578df13670d52d
+Merge: 44a1a06a 172dda0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 25 22:31:48 2021 -0600
+
+ Merge branch 'oit9'.
+
+commit 172dda0ba85335690722f17fd1d2131ea2109b86
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 25 09:53:42 2021 -0600
+
+ Use highest available GLSL version; detect compute shaders.
+
+commit b52992a66893b34a6d69812b9a900a7822afc2ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 25 08:26:55 2021 -0600
+
+ Improve check on available number of GPU processors.
+
+commit b4e3174a085da72c9af55d044d319a96eba5c3d4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Oct 25 00:43:15 2021 -0600
+
+ Use CPU indexing for offscreen rendering; add setting GPUindexing=true.
+ Fix exporting.
+
+commit a13e84d544c12f10a13e8d5935c1d45fcfb92729
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 24 17:22:46 2021 -0600
+
+ Improve frame rate diagnostic.
+
+commit 999c701e41507c7f54863c0a7b4536bb7061d559
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 24 17:00:34 2021 -0600
+
+ Improve shader compilation diagnostics.
+
+commit 97ce07d029ab3f6f961e1673ce1db548b0d39d0d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 24 16:57:32 2021 -0600
+
+ Unroll initial loop.
+
+commit ae34f5364218ab2b0ce3fc8d95c7614c6b9a6213
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 24 13:20:47 2021 -0600
+
+ Use maximum number of available GPU processors.
+
+commit 44a1a06a99e5fd18b5d7557de2c6e3197597d256
+Merge: 7f57426f 025e14b2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Oct 24 11:15:13 2021 -0600
+
+ Merge pull request #273 from descodess/cleanup-code
+
+ Cleanup code.
+
+commit 025e14b2b58fcd63c70df34f76e1a8af1c783d31
+Author: descodess <87569405+descodess@users.noreply.github.com>
+Date: Sun Oct 24 15:06:34 2021 +0200
+
+ fix syntax
+
+ remove trailing semicolon
+
+commit 832a7718661c83d96865a71efc4ace8b6b6796cf
+Author: descodess <87569405+descodess@users.noreply.github.com>
+Date: Sun Oct 24 14:54:15 2021 +0200
+
+ unify and cleanup code
+
+ - unify code
+ - cleanup code
+
+commit f4ddc1d7d9031189411010932aed3b3a6add867b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 23 17:10:04 2021 -0600
+
+ Fix offscreen rendering.
+
+commit 1f916adbd5532786b3d1ffd45cc8a26257976b46
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 23 16:35:17 2021 -0600
+
+ Optimize code.
+
+commit 00bc732b403334793bd6c28dcfb678e7c00b3572
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 23 16:35:17 2021 -0600
+
+ Simplify code.
+
+commit 5d2717ca3d552023f50d237dceb55c2108213602
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 23 15:21:17 2021 -0600
+
+ Backport HAVE_SSBO case to GLSL 1.50 with extensions; simplify shader calls.
+
+commit 82d54b08a1ba9082d022394bb9e3baac4edf087e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 23 13:37:52 2021 -0600
+
+ Remove unused glClearBufferData.
+
+commit 0f3904629e4f14d825ac4e26075d7a04c0de9a46
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 23 13:07:47 2021 -0600
+
+ Rename transparentfragment shader to blend shader.
+
+commit de5ffab119e32dd93e7aa1b507c69d7052648895
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 23 12:54:15 2021 -0600
+
+ Defer memory barrier as long as possible.
+
+commit c567e4b482d2f58eccde51aa510e61a549d49778
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 23 01:33:43 2021 -0600
+
+ Simplify code.
+
+commit 152c3c22fae4f5614aa82c520892c5cad61c6a14
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Oct 23 00:41:41 2021 -0600
+
+ Implement presum and postsum shaders with smaller workgroups.
+
+commit ca2c624141aae22b68d92e8f729fd01365468d49
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 22 11:38:01 2021 -0600
+
+ Slightly overallocate fragmentBuffer.
+
+commit 1fdb1497f1349c3abc3b23f2aac1867c146d2253
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 22 11:18:55 2021 -0600
+
+ Use glGetBufferSubData for better performance.
+
+commit 62bcdd35ae8378fd3624e039dc8951a02fa5f81b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 22 10:00:19 2021 -0600
+
+ Add missing column.
+
+commit 0cd38189fd8e236c480278f5c1dffc9321f1da5b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Oct 12 23:25:20 2021 -0600
+
+ Detect SSBOs at configure time.
+
+commit a6626dc8476d85777b4935e200f80443155cfe3a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 7 17:01:37 2021 -0600
+
+ Fix screen resizing.
+
+commit 8b705bda0c1d378e06ccfbe63d23c37f04fddba3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 21 21:06:50 2021 -0600
+
+ Reduce sharedData size by 1.
+
+commit e16b6696a73fea89e247afcc8b3ca3f8fe1124a7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Oct 21 17:56:28 2021 -0600
+
+ Optimize partial summation.
+
+commit 7f57426f17798f6e7b67a3278b7b0123fa8ff188
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 22 22:59:16 2021 -0600
+
+ Disable PRC output by default.
+
+commit 5278c0bc9ac8f7aec120d756849db6972fdac7ed
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 1 12:18:52 2021 -0600
+
+ Reduce the number of writes.
+
+commit 2d5c76615a5656a69947fe52dbedc81d644d589f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Oct 1 11:59:34 2021 -0600
+
+ Fix transparent wireframe mode.
+
+commit e4adee2dc5dd930057cd52fe017b56635fa50149
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 30 22:18:26 2021 -0600
+
+ Add missing files.
+
+commit c28f97f86e8b58ec5b77e68b041948583081b59a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 30 18:08:05 2021 -0600
+
+ Clear counter array directly on GPU.
+
+commit 7bfd346e4570d4feb54ff606d6ac0cc1f868ba5b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Sep 30 17:19:30 2021 -0600
+
+ Compute partial sums on GPU.
+
+commit b90c8b2e5fefd1a2a8ffafdc964889c79e0d75c0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 28 16:56:07 2021 -0600
+
+ Blend transparent objects with background.
+
+commit 71aff16107856f58661358b727ba354d30cf0370
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Sep 27 02:18:26 2021 -0600
+
+ Only reallocate zbuffer as needed.
+ Fall back to centroid sorting for legacy GLSL versions.
+
+commit 43719418bac6b96a747727a38a012be4b60e63f9
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Sep 26 01:37:22 2021 -0600
+
+ Improve performance by not clearing depth buffer.
+
+commit 64224e276958ea86635722a36867830cf44abbf2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 25 16:30:58 2021 -0600
+
+ Invoke mergeShader once per pixel; sort large fragment lists in place.
+
+commit 63df2147cc8406171a9da3b8b36a58bed4c5e38e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 25 02:22:00 2021 -0600
+
+ Compress fragment list.
+
+commit 4e711e64b3b24a14f2e2f8c07b637c19cefd6406
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 24 18:15:35 2021 -0600
+
+ Handle errors gracefully.
+
+commit 95f5f2cf1b944abc994a8de363723afdcdc3ae66
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 24 17:51:03 2021 -0600
+
+ Remove unused extension.
+
+commit 6d43aa48cd703fc90c118d1dd2437919df081748
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Sep 24 17:03:51 2021 -0600
+
+ Remove unused code; reduce GLSL version.
+
+commit cf6880d79c87a4ae1a0ecd557be9cfb0de19be35
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 22 01:41:04 2021 -0600
+
+ Implement order-independent transparency up to fixed depth.
+
+commit 1a03ddc1990e6c98c668b000447a2d26a9816846
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Sep 11 22:51:11 2021 -0600
+
+ Update example.
+
+commit 4a471d9f141325e44af2090a00e7f80daa75d730
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 7 15:10:03 2021 -0600
+
+ Revert "SETTINGS: Implement once option that limits to one shipout."
+
+ This reverts commit 51be72a7c0dcb66d9dfd54e490a7f9c0dffdfe29.
+
+commit acfacda74b6eb1e2c51432700b792e58d41e8703
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 7 15:09:40 2021 -0600
+
+ Revert "SETTINGS: Improve once setting."
+
+ This reverts commit 863550d54f2fd73907829af9f10e28a158d8d8aa.
+
+commit 9aee221cb61a00c2ef275c4eb0415e7b913b234e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 7 15:08:20 2021 -0600
+
+ Fix hang on display.
+
+commit 26fee75283f3087df8174610707f437e43123e72
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Sep 7 14:53:50 2021 -0600
+
+ Update FFTW++.
+
+commit a21ba3043207290b82d3ef100f12e1f9c80f5799
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Sep 6 20:08:13 2021 -0600
+
+ XASY: Fix copy translation bug.
+
+commit 302d588b0498a9272152e2e262245d6d2a4d6b60
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Sat Sep 4 20:43:55 2021 -0600
+
+ XASY: Fix object copying translation glitch.
+
+commit e331cefff6f6136c691a69a0e0292b9f07feba48
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Sep 1 00:48:47 2021 -0600
+
+ Clamp oversaturated values.
+
+commit 781c2f8ba80b3a2b5a81103f838a249c7f98794c
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Tue Aug 31 23:42:25 2021 -0600
+
+ XASY: Change errors with pasting.
+
+commit f8359c15510ea5b383347892c85f90e386d78f46
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Tue Aug 31 15:59:07 2021 -0600
+
+ VS: Move linalg.cuh to utils.cuh.
+
+commit 4d4e1c433652076ff791942e52e3683a012d380f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 31 15:58:17 2021 -0600
+
+ Add missing file.
+
+commit c070d3cd7076c97d41d17f9de93d3a3bdb712d41
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 31 15:57:25 2021 -0600
+
+ Add reference.
+
+commit db0ef4c4955dca0853052fa81c9e1c4b01d64fae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 31 15:54:36 2021 -0600
+
+ Rename file.
+
+commit 52a4bfbdd063f31abce9adb5c3202d7061c1e6f3
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Tue Aug 31 15:31:48 2021 -0600
+
+ CXX: Include abs2 in the DefaultVec3 function.
+
+commit e4e2a750179e8f6d6892ffeb6cc262d2a96a6914
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Tue Aug 31 15:31:30 2021 -0600
+
+ VS: Include simpson.cuh in vcxproj file.
+
+commit e0ae066f4968fa980899158ea6759d578479e304
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 31 00:40:46 2021 -0600
+
+ Integrate diffuse image with adaptive simpson integration.
+
+commit 79c8e33e7d7fc3f08fb7172de3ca8b96ae11699b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 30 21:38:52 2021 -0600
+
+ Simplify example.
+
+commit 37833d712a1993a13a0e0f82a8ae8e8c16a46352
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Mon Aug 30 19:05:08 2021 -0600
+
+ HEADER: Remove any unneeded functions from linalg.cuh.
+
+commit 866733b926da9ca839cfb52d305ab4737b64d784
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Mon Aug 30 18:55:16 2021 -0600
+
+ GLM: Migrate internal integraiton code to glm::vec3/mat3.
+
+commit 84f678b57544f677592b808678251b21c7d227d2
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Mon Aug 30 02:37:20 2021 -0600
+
+ WEBGL: Add missing closing bracket to fragment shader.
+
+commit 39ac3e241f5777f1dba1051d57b922b9755e84c4
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Mon Aug 30 02:33:50 2021 -0600
+
+ CUDA: Use Simpson's method for inner loop also.
+
+commit 6d5f8b735f5c0759a1073fe845e24b44b39de045
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Mon Aug 30 02:19:19 2021 -0600
+
+ CUDA: Use a template simpson's method for integration.
+
+commit e1165ce48521067074e6ef09062e3df11cd10354
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Mon Aug 30 01:59:29 2021 -0600
+
+ Refine simpson's method for integration.
+
+commit a9133135d236bb592814c19e92ddd87dc9e73729
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Aug 30 01:38:03 2021 -0600
+
+ XASY: Pasted objects follow mouse.
+
+commit 48d25978a7103a1b8485cb80ce4b7297dddcdb96
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Aug 30 01:16:52 2021 -0600
+
+ XASY: Fix copy/paste graphical bug.
+
+commit d82bb2de9416ce0a209b138c46850e211e5943d3
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Mon Aug 30 01:11:17 2021 -0600
+
+ GLM: Use glm for irradiation generation.
+
+commit 2d7af868033a42d6dbf1f0f024db3f3266caa2d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 28 22:36:56 2021 -0600
+
+ Fix endpoint.
+
+commit d477d8577575831f57ad53ecb8df8bf808d490bc
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Sat Aug 28 18:08:59 2021 -0600
+
+ WEBGL: Add support for PBR Texture sampling.
+
+commit c7869c3face0d2ab79d8dac49d3c3af12b137a8c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 28 08:31:37 2021 -0600
+
+ Fix last commit.
+
+commit 1199f6db6b255f675f855b54ebb8f2d570b68c15
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 27 23:02:27 2021 -0600
+
+ Use Simpson's rule for integration over phi.
+
+commit 0cb2bc4b7c2f4ac82d98df80b3460d4b5797be44
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Fri Aug 27 22:28:34 2021 -0600
+
+ REFL: Allow for output size different to input and enable halving of sizes for mipmap.
+
+commit 6fce80c00b769c98fc53b5fc317ed31a99bc76a8
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Fri Aug 27 21:53:24 2021 -0600
+
+ CU: Extract integrand to a separate function.
+
+commit 77f18124bc5788561990d1d560053e26099c497a
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Fri Aug 27 21:42:49 2021 -0600
+
+ CU: Move integration function to a class.
+
+commit 89c414a94693d2be041dd9f9623e5e1186351809
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Fri Aug 27 17:00:57 2021 -0600
+
+ CXX: Use C++17 for structured bindings temporarily.
+
+commit e07757a43286d883642a2f5013ca0ab60c230e84
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 27 00:03:40 2021 -0600
+
+ Simplify code.
+
+commit d1ca5ca3c6400ba26c6da27dc74967c251cf7bdc
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Thu Aug 26 21:08:58 2021 -0600
+
+ EXR: Enable PIZ compression by default.
+
+commit 150323ec482871cf181aa7d809ee2ed5d6beb5fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 26 20:10:02 2021 -0600
+
+ Output missing directory.
+
+commit 881f038851e9f8c642344205b517e78eb84f33df
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Thu Aug 26 19:49:04 2021 -0600
+
+ CXX: Add copying file and extract some functions.
+
+commit 15e5b4783c6761592909d1b0048b251bcef8675b
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 25 16:53:29 2021 -0600
+
+ GL: Fix texture parameter bindings.
+
+commit 7b36e0e262b881f0b7da255e074818c4229ec359
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 25 16:42:41 2021 -0600
+
+ Extract loading IBL Data to a separate function.
+
+commit 722723098b87c74d6dfda6c4dfeb2391457950af
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 25 15:55:52 2021 -0600
+
+ GLSL: Extract IBL to a separate function.
+
+commit 096b673db236faab237f9a922ba78a9a00effc4d
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Tue Aug 24 23:59:06 2021 -0600
+
+ XASY: Remove debug message.
+
+commit 326bc7a96d283849ed4f88fba194985a19b6ddf0
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Tue Aug 24 23:51:31 2021 -0600
+
+ XASY: Expand functionality of copy and paste.
+
+commit 997e4ee59793d6136aec080368ed66220193b989
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Aug 24 22:17:39 2021 -0600
+
+ GLSL: Update shaders to use IBL.
+
+commit 8e8cb4e54072a87c736bd57f40011117a6753c2d
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Aug 24 22:03:25 2021 -0600
+
+ GL: Update parameters level.
+
+commit 5635f37214c2bd13c94dc52fa38f37e6831f923a
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Aug 24 15:43:20 2021 -0600
+
+ GL: Add basic texturing system to asy.
+
+commit 6e4fb11ab637a16076edc4673c35a94c7d54f674
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Aug 23 10:17:14 2021 -0600
+
+ XASY: Add message for copying unsupported types.
+
+commit 1a0127e0f4789974fe6dd8e7c214e7f0d2941bdd
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Aug 23 00:50:05 2021 -0600
+
+ XASY: Fix major copying bug.
+
+commit ae624c444c41b4441b6745e96528b0fe3b1bb79d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 22 22:59:16 2021 -0600
+
+ Disable PRC output by default.
+
+commit e3f895e6dcee599193b369b501d72d562161cee6
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Sun Aug 22 18:58:44 2021 -0600
+
+ REFL: Formalize arguments for program.
+
+commit df676f0b62ce1b223fb62d509707c7aacd783352
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Sun Aug 22 17:55:14 2021 -0600
+
+ REFL: Add EXR and argument handling.
+
+commit 6a136116ddbb664241ac5a7cd2169e9f58f351ca
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Sun Aug 22 17:09:48 2021 -0600
+
+ REFL: Update Visual Studio solution to use vcpkg instead of nuget.
+
+commit b029cb065cc50bee50e611d9dddcb5e233820f29
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Sat Aug 21 23:48:58 2021 -0600
+
+ XASY: Fix crash bug with copying.
+
+commit 43bf5ad9483e40b42968fae7650bc624c0c28591
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 21 23:06:07 2021 -0600
+
+ REFL: Port to UNIX.
+
+commit ba4a5a979cca422caf5440c519c22ed5b05936a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 21 22:01:29 2021 -0600
+
+ git subrepo clone https://github.com/syoyo/tinyexr cudareflectance/tinyexr
+
+ subrepo:
+ subdir: "cudareflectance/tinyexr"
+ merged: "b0d2abbd"
+ upstream:
+ origin: "https://github.com/syoyo/tinyexr"
+ branch: "master"
+ commit: "b0d2abbd"
+ git-subrepo:
+ version: "0.4.1"
+ origin: "https://github.com/ingydotnet/git-subrepo"
+ commit: "a04d8c2"
+
+commit 283dbec8d3d31b538a397d4c7f8d737561f720a3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 21 21:45:23 2021 -0600
+
+ THREE: Add missing center transform.
+
+commit abbce6ee1dcfc13628eab49cc45ab3e4f4335dc5
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Sat Aug 21 18:22:53 2021 -0600
+
+ REFL: Use importance sampling for pre-computing fresnel values.
+ (Is this the right value?)
+
+commit 75d4cdd93180d0d81149b7a9aa5f28e244ba59d9
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Fri Aug 20 21:32:40 2021 -0600
+
+ CUDA: Add error checking to free and intellisense improvements.
+
+commit 89dfe5eec19fcec2e8cd1276bff6a5e94e392e11
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Fri Aug 20 21:32:26 2021 -0600
+
+ CUDA: Include a currently (broken) roughness/CosV map to reflectance values.
+
+commit 34fafd8d6b08f83fa2f505368593d75d3603ac6f
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Fri Aug 20 17:10:17 2021 -0600
+
+ CUDA: Add separate VC++ Irradiance generator code.
+ Note that our goal is to convert this VC++ project build script to a Makefile script and ensure it is compilable under linux.
+
+commit f6a8a83ba8f75119fdf9665b397b0992fa00f584
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Thu Aug 19 00:45:47 2021 -0600
+
+ XASY: Forbid changing fill status on open curves.
+
+commit 5f5e10a1de1aab07e046f9dda5dcec86fdd45e0a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 19 00:06:05 2021 -0600
+
+ Remove diagnostics.
+
+commit 3cbb0dbef8873f99fa7f447e337a862769222c2a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 19 00:03:14 2021 -0600
+
+ Avoid duplicate centers.
+
+commit 9d2892af776569e465f993c9324135eff612241e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 17 04:04:58 2021 -0600
+
+ Update asygl.
+
+commit 4acc17ed4c8f7530dd848ca43e7579a190541a31
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 17 04:01:27 2021 -0600
+
+ Support centerIndex in WebGL triangle groups.
+
+commit bcff5923ef657f7ea579179f63b7701208c8e993
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 17 04:07:56 2021 -0600
+
+ V3D: Add billboard support to triangle groups;
+ suppress primitives when prerendering.
+
+commit 0817a2f368dcb040d8fb0823df96a3e671782ba6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 17 04:04:58 2021 -0600
+
+ Update asygl.
+
+commit 82aa6d237153b7f3ac60e44b86402f1052c7e7cd
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 17 04:01:27 2021 -0600
+
+ Support centerIndex in WebGL triangle groups.
+
+commit 22a784d251242440f4cbdaa8ae2349ba031cf8db
+Merge: b0729f18 79137914
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 16 17:29:43 2021 -0600
+
+ Merge branch 'master' into v3d.
+
+commit b0729f182305c81242487207e4be370951ec791f
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Mon Aug 16 13:53:08 2021 -0600
+
+ V3D: Render triangle if primtiive flag is >0.
+
+commit 5c2379943e53d576dfa301afe20e209161f4eccb
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Mon Aug 16 12:45:56 2021 -0600
+
+ V3D: Add center to triangle groups.
+
+commit 79137914157f38ce1fb548e26d2a409cc36445d7
+Merge: d56f0966 3fdfbd69
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 16 10:13:34 2021 -0600
+
+ Merge branch 'Qt'.
+
+commit 8a9407456564b94c087791f51614cfe03a02b0b1
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Sun Aug 15 22:13:42 2021 -0600
+
+ XASY: Add alpha version of copy/paste.
+
+commit e5ab80073a29e25b3b9d94a96f22f312a79ec9b4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 14 02:36:43 2021 -0600
+
+ V3D: Simplify and optimize V3D workflow.
+
+commit 3d31566beae8f39b12a9b4b83f4627d92dbb0377
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Fri Aug 13 21:09:20 2021 -0600
+
+ V3D: Remove Min/Max from V3D generation.
+
+commit 9eefbed0d0c58736f12b67d5df4c2f7590d6b6df
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 13 18:43:54 2021 -0600
+
+ Fix prerender resolution.
+
+commit 906a5be824a2a7c6b4e800800f11e678d974e543
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 13 18:18:18 2021 -0600
+
+ Make prerender a real setting.
+
+commit 7afa49892cd20e38d19c3a18d4d2c956941db0d1
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 13 17:34:14 2021 -0600
+
+ Support reading material triangle arrays.
+
+commit d56f09667ca0e9f2b3b6fc4aadfe330e99915a9c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 13 00:23:05 2021 -0600
+
+ PEN: Make byte(double r) map [0,1] to [0,255] uniformly, with 0.5 mapping to 128.
+
+commit 98ba7ecd29378505c57c6579ab9ed06680a4584b
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Tue Aug 3 00:18:26 2021 -0600
+
+ XASY: Set up work for adding 3d objects in the interface.
+
+commit 3fdfbd69f7d75fecc4908ec07684553f897d9e47
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Wed Aug 11 22:34:21 2021 -0600
+
+ XASY: Remove unreachable code.
+
+commit f8fd80407962c18deee37029c764455e0050fc3c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 11 17:59:25 2021 -0600
+
+ Makefile: avoid python dependency in releases.
+
+commit 90608841304c3d233cd5194c05eb8783da60bd70
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Wed Aug 11 17:14:18 2021 -0600
+
+ V3D: Add java support for enum generation.
+
+commit 7448d4f8789152cd71cd2406d8299320ca37c5eb
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Wed Aug 11 16:55:27 2021 -0600
+
+ V3D: Add comment support for enum types.
+
+commit 4c633b4c95589cc029da7e99666bd26e7fac74f0
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Wed Aug 11 16:02:30 2021 -0600
+
+ V3D: Enable asy header generation to base/*.asy file.
+
+commit f2e2d37759a8514e0f51dc8535fbbe5bf1e061e8
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Wed Aug 11 15:58:47 2021 -0600
+
+ V3D: Move enumheader directories to the asy dir.
+
+commit c8ce4c0454d3c4b9a1f39cf854384c87ddaabaf9
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Wed Aug 11 15:24:36 2021 -0600
+
+ V3D: Use gzipped file as the reading mode for V3D.
+
+commit 676ee735c0715d1bf89322ea24f12d3e122d65df
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Wed Aug 11 15:24:17 2021 -0600
+
+ V3D: Add gzfile as igzxfile option.
+
+commit ff9766b6139e60c2db1feb0eed9ba4e28c28c98f
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Wed Aug 11 15:22:55 2021 -0600
+
+ V3D: Add memixstream to support input from memory.
+
+commit 50a11030172f594158e561b578bf42ba4a060eea
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 11 01:00:05 2021 -0600
+
+ V3D: Use global instead of local bounding box for drawTube.
+
+commit 8dbffd7305b72a6b5325d064581c0dd01e430478
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 11 00:59:30 2021 -0600
+
+ V3D: Fix WebGL sphere syntax.
+
+commit 4b855feb8728f7440219e2502af264a8d2043a6c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 11 00:25:13 2021 -0600
+
+ V3D: Implement light in v3d.asy.
+
+commit 60c849655df07657d2f3224afd9a193dda2bc06f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 10 01:27:47 2021 -0600
+
+ V3D: Improve description of lossy setting.
+
+commit a55a50c7cedd4a5c5ad7600ae73d1a63fa1f5e64
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Tue Aug 10 21:23:40 2021 -0600
+
+ V3D: Add in light information for v3d.
+
+commit 806c67a373c8dda38fc38d8638fe35235c798c55
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Tue Aug 10 21:53:31 2021 -0600
+
+ XASY: Add messages upon saving files.
+
+commit f921075a3738ab968dc594fcb6bcb29bb0f54e21
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Tue Aug 10 21:23:40 2021 -0600
+
+ V3D: Add in light information for v3d.
+
+commit 863550d54f2fd73907829af9f10e28a158d8d8aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 10 21:14:59 2021 -0600
+
+ SETTINGS: Improve once setting.
+
+commit 51be72a7c0dcb66d9dfd54e490a7f9c0dffdfe29
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 10 20:45:55 2021 -0600
+
+ SETTINGS: Implement once option that limits to one shipout.
+
+commit e361cf952267d786d462dda40ddcf8d6ddfb584b
+Author: Supakorn Rassameemasmuang <jamievlin@outlook.com>
+Date: Tue Aug 10 19:35:06 2021 -0600
+
+ REPO: Add clang-format file.
+
+commit bc75527b354ef090064aa4777f779413a0339a9d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 10 01:20:10 2021 -0600
+
+ V3D: Fix precision, hemisphere alignment, curves, and cores.
+ Add primitve support.
+
+commit 0fc1a6bb15667544aecf77c0aafb014c45227742
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Aug 10 01:16:23 2021 -0600
+
+ THREE: Expose drawTube primitive.
+
+commit 5acc87fcfea6737a451c97301c52332ca7e8713f
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Aug 9 22:05:46 2021 -0600
+
+ V3D: Detect single real in v3d.
+
+commit 0d4ae3663c998315ba5c51694631621e7709b650
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Aug 9 21:55:24 2021 -0600
+
+ V3D: Add single precision as an option with -lossy.
+
+commit 45303157fed6b5525de65b10ee7206c42668f079
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 9 21:43:38 2021 -0600
+
+ V3D: Fix dependency.
+
+commit 486166359a2d6dd02101c9292370973c4827b22e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 9 21:35:18 2021 -0600
+
+ V3D: Simplify code.
+
+commit 84ab496c2a4e8e0957fdceb705b62c885b0f8920
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Aug 9 20:00:27 2021 -0600
+
+ V3D: Add gz as an option.
+
+commit 2fe8816e92ac59e28f14e8ef0aa7d24b2607dcd3
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Aug 9 18:26:51 2021 -0600
+
+ V3D: Use open_memstream for in-memory files.
+
+commit 9da89c31033c68fe8ed414b71725d93fa9206918
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Aug 9 17:44:00 2021 -0600
+
+ XASY: Fix changing text labels.
+
+commit aceb3d56f81f1552b3ccdc3a12c9eead22cc6984
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 9 17:14:17 2021 -0600
+
+ XASY: Color filledbucket and nodes of curve and polygon icons.
+
+commit 2c52f34e4439309cba661ef7d82c3328afcfdf41
+Merge: 71cb3f68 a6a23c75
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 9 16:06:52 2021 -0600
+
+ Merge branch 'master' into Qt.
+
+commit 7c8b9134cbca36073401b980b34c7870b0922267
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Aug 9 16:06:30 2021 -0600
+
+ V3D: Add memv3dfile option.
+
+commit 15fe906d4e07c81fa408a11c58fe04c9c522e15e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Aug 9 15:17:48 2021 -0600
+
+ V3D: Abstractize v3dfile to absv3dfile.
+
+commit 2a533bc20aae3b1b50cffd644e81dc00e39de7d8
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Aug 9 15:17:07 2021 -0600
+
+ V3D: Add python as an makefile option.
+
+commit 71cb3f68c3ca463eb4ad6515cd25986b86a73d85
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Aug 9 15:02:45 2021 -0600
+
+ XASY: Fix saving bug.
+
+commit a6a23c75f8b9fd9c126c06509feb638a2eeb808a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 9 10:29:23 2021 -0600
+
+ Rename renderMode to renderDensity.
+
+commit 4603ec03cd7bdfa97e8c91559c115049d62593ba
+Merge: 867f44da 9c6677a2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 9 09:49:17 2021 -0600
+
+ Merge branch 'master' into Qt.
+
+commit 867f44da7c079b5c35512c3ddb35d23f9887902d
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Aug 9 00:38:08 2021 -0600
+
+ XASY: Add option to change keymaps.
+
+commit 9c6677a2e51a2503be8dd97924a061db47a1b9ee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 7 10:57:08 2021 -0600
+
+ Revert "Disable threads again by default under MSDOS."
+
+ This reverts commit 29f965b7050b6ffb4da77a73b66d277e76ae77d8.
+
+commit 8f07a8bca008738c5ee0ff6f8fa04482f4d69c3d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Aug 7 00:02:31 2021 -0600
+
+ PARSER: Fix declaration of yyparse.
+
+commit 787c1c397476890ae20abb0b6ed54d8f99471048
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 6 23:48:58 2021 -0600
+
+ V3D: Standardize names.
+
+commit 4b8c2489044c9fba4b2186889ed33bd22576665a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 6 22:35:44 2021 -0600
+
+ XASY: Add renderMode to default xasyconfig.cson.
+
+commit 2a5bd095a0492c66e5492cbe8c7523421e0f8e05
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 6 22:35:18 2021 -0600
+
+ Support prerelease suffixes.
+
+commit 922ab672ec7bd0e76d597eda23988e02ae7675c4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 6 21:33:19 2021 -0600
+
+ Port support for 3D rendered xasy pictures to MSDOS.
+
+commit 2b2a6926a92ff8022ba3ae7edcf0a0538adfa601
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 6 21:26:47 2021 -0600
+
+ V3D: Add more information to V3D header.
+
+commit c267db95d8c6fbf483e0a6a30d460b223d27b5d0
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 6 21:14:09 2021 -0600
+
+ V3D: Add Zoom0 and margin information to v3d.
+
+commit 1631e3967dd23bb03c051f060218475c9dfb5f9b
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 6 20:48:30 2021 -0600
+
+ V3D: Set camera info in V3D.
+
+commit 825fc91b375c160a92fc08573e6fe916daa6b29e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 6 20:39:50 2021 -0600
+
+ V3D: Add Header reading in asy.
+
+commit 924c58c89d226cce0b5377ffa2baca2e90a8f96d
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 6 20:28:48 2021 -0600
+
+ V3D: Add enum generation for asy.
+
+commit 8bbce6486cb265e5b86308ee9ea9d660f83274bc
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 6 20:11:51 2021 -0600
+
+ V3D: Output header data.
+
+commit e44d572c6f8f0ed7fb8ae8921525b99d693dca1f
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 6 18:27:25 2021 -0600
+
+ V3D: Fix V3D Makefile generalization.
+
+commit 8dbbf33bcddc584cccdeb8027e58bdda1f8cf64c
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 6 17:39:30 2021 -0600
+
+ V3D: Add v3dheadertypes to enum headers.
+
+commit 455c5954a351315dec9575fe49ea32d72d7d7d5d
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 6 16:48:03 2021 -0600
+
+ V3D: Generalize Makefile rule for enum headers.
+
+commit 52a3fe49cb2e7b215beb88a295b3c20a21c75693
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 6 16:41:06 2021 -0600
+
+ V3D: Move csv and generated headers to enumheaders.
+
+commit fe5ea8845d6ec6288d021223b01ab5f98cefad65
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Aug 6 16:19:46 2021 -0600
+
+ V3D: Add script for v3dtypes generation from csv.
+
+commit 29f965b7050b6ffb4da77a73b66d277e76ae77d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 6 09:00:30 2021 -0600
+
+ Disable threads again by default under MSDOS.
+
+commit af811ec03dccd4fab73dfe00d78bc9318f8e717f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 6 08:58:30 2021 -0600
+
+ Fix infinite loop on EOF when readline support is disabled.
+
+commit 52657aa0f28ffff1b884d09ccbe1f9f9fcef17a6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Aug 6 08:10:16 2021 -0600
+
+ Fix typo.
+
+commit e59b0fadcd1e2ef689f299dbad49f624db1b5469
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 5 23:19:24 2021 -0600
+
+ Update documentation.
+
+commit a5eda4eed14198827bcba139206faa0fbcc488d8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 5 22:13:18 2021 -0600
+
+ Suppress internal Qt diagnostics.
+
+commit 0995689e8505f85329b000c50e74daab196e887c
+Merge: 57b93d55 7dead80b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 5 21:45:03 2021 -0600
+
+ Merge branch 'Qt'.
+
+commit 7dead80b436bb90ed81090315538b21d20c3cbc0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 5 21:34:42 2021 -0600
+
+ Revert "XASY: Fix closing bug."
+
+ This reverts commit 35aaf24d8bdf1db19ea001f88bfe44cecc6ec1ec.
+
+commit adc58bc87e608c8f6706115d8a71a0c738ac8b83
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 5 21:33:45 2021 -0600
+
+ Revert "XASY: Fix freehand saving bug."
+
+ This reverts commit aac59af3405e51726a708b6ca06fb3fc35c5f45b.
+
+commit 57b93d5513b734a676a7633ddbf7b33a65fb42bf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 5 18:06:07 2021 -0600
+
+ Revert "XASY: Set up work for adding 3d objects in the interface."
+
+ This reverts commit bad1b04a2aaf6e21eacf07b046d99e07a839c18f.
+
+commit 94651febdff5250fb6bc98393817a578737a8ee4
+Merge: 2d4c3cde c2f559c8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 5 18:05:32 2021 -0600
+
+ Merge branch 'Qt'.
+
+commit 2d4c3cde07d7498301f337277522c69586deae76
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 5 15:34:23 2021 -0600
+
+ Add missing fuzz parameters to routines that call intersections.
+
+commit c2f559c8b7f6083542b650b5f3909e688ffe95be
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Aug 5 12:13:06 2021 -0600
+
+ XASY: Remove addressed note.
+
+commit aac59af3405e51726a708b6ca06fb3fc35c5f45b
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Thu Aug 5 10:33:43 2021 -0600
+
+ XASY: Fix freehand saving bug.
+
+commit 3850f9948b6d535b61988e5096514890fbb16d4d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 4 22:05:56 2021 -0600
+
+ V3D: Fix color triangle.
+
+commit 5c387a68c6912c6434434042b56e3ed35a8fa6af
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Wed Aug 4 20:05:02 2021 -0600
+
+ XASY: Fix fill status errors for freehand objects.
+
+commit 648015672687357ca36f94e503b9d8976a42286b
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Wed Aug 4 19:51:32 2021 -0600
+
+ XASY: Improves quality of fix to text saving bug.
+
+commit e6ac8c6ae41c8bd93f2df18670cd13965f843eb7
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Wed Aug 4 19:42:04 2021 -0600
+
+ XASY: Add option to fix text.
+
+commit af70420fdfc859862fca6ba760d2b7cda54e67c6
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Wed Aug 4 19:33:13 2021 -0600
+
+ XASY: Fix closing bug regarding text.
+
+commit 6bd3ad893a819b7020150db5c1ec82195bfe3b27
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Wed Aug 4 19:19:08 2021 -0600
+
+ XASY: Fix text saving bug with xasy format.
+
+commit 05e5ca886fec7372b0ada8d6305eb2b16efc7c0b
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 4 17:35:04 2021 -0600
+
+ V3D: Add generation for triangle lists.
+
+commit 7103e5c70ab519927d38b7f9bc549643caa034e8
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 4 17:27:29 2021 -0600
+
+ V3D: Add generation for path lists and pxiel lists.
+
+commit 379d8f71a73f900a6b6e3c192ba186d3c8d51332
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 4 17:14:12 2021 -0600
+
+ V3D: Fix surface typo.
+
+commit cab1f904c16b490711498a21d7954cfd95aa5e30
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 4 17:12:02 2021 -0600
+
+ V3D: Output Min and Max on bezier patches and triangles.
+
+commit 6843d56c53ecc246c1ca8523ccd56723084530bb
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Aug 4 17:08:09 2021 -0600
+
+ V3D: Add support for straight patches and triangles.
+
+commit 7e49626efc399d7b5581857fc16ab00a5a17936b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 4 00:48:56 2021 -0600
+
+ Fix alignment issues.
+
+commit 098789a4f4446125ffa3f16071c1f111d83cd76e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Aug 4 00:47:40 2021 -0600
+
+ V3D: Generate primitives for both v3d and webgl.
+
+commit fd7b1f0f8c3e2ead714f30ad88291c782d648e02
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Aug 3 18:47:10 2021 -0600
+
+ V3D: Add triangles and pixel to reading V3D.
+
+commit 51eb5ae116173a9e9fdbfd128bd8abf6e16a8d5d
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Aug 3 17:48:30 2021 -0600
+
+ V3D: Add pixel and curves to v3dfile.cc.
+
+commit 141a1fdde34df2908a0e6723e89142962bb5319e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Aug 3 17:31:20 2021 -0600
+
+ V3D: Add multiple primitives function to importv3d.
+
+commit bad1b04a2aaf6e21eacf07b046d99e07a839c18f
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Tue Aug 3 00:18:26 2021 -0600
+
+ XASY: Set up work for adding 3d objects in the interface.
+
+commit 0689fcebfc49ac58f569ca0539a0c3f0134db5ae
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 2 22:31:58 2021 -0600
+
+ V3D: Fix pixels.
+
+commit 66d0aa1f9b0dbf08e5aabab94fc94589a93347fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Aug 2 21:04:49 2021 -0600
+
+ V3D: fix hang with -V option.
+
+commit e6e9739dd37b9e47fb2af647398d83ee31618b48
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Sun Aug 1 17:27:25 2021 -0600
+
+ XASY: Add beta version of changing fill status.
+
+commit bb9bfde7ff2e0d881a8d493a9c67a2adf89a8523
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 1 11:35:26 2021 -0600
+
+ Support billboard labels.
+
+commit fb90ea9ec15ca2249dab02590a5fe15edcef5b4f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Aug 1 11:29:32 2021 -0600
+
+ Support billboard interaction mode for general patches via render argument.
+
+commit 35aaf24d8bdf1db19ea001f88bfe44cecc6ec1ec
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Sat Jul 31 22:26:39 2021 -0600
+
+ XASY: Fix closing bug.
+
+commit 32e4ede32ac0b9b74c5fbd65cd069f1720324348
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Sat Jul 31 22:11:45 2021 -0600
+
+ XASY: Change name of render mode.
+
+commit a6c2218a87ec02ba11ad96b2b520d40bf0650e9e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jul 31 19:20:15 2021 -0600
+
+ V3D: Enable generation of surface lists.
+
+commit 45447153388fa3bf4ddef89cbc6871de92ebc4cb
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jul 31 19:14:53 2021 -0600
+
+ V3D: Enable reading color data.
+
+commit 4ca2bb85002f2cd5fb48d27fba0c533860e91945
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jul 31 19:14:40 2021 -0600
+
+ V3D: Fix adding color information for v3d.
+
+commit 7b929621a7acbd322e6b2580c75cd7d39a5d4aef
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jul 31 18:44:02 2021 -0600
+
+ V3D: Add reading in center information to importv3d.
+
+commit 8908226e183dd6b8d71a0035e5e5506855d244c9
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jul 31 18:43:44 2021 -0600
+
+ V3D: Add center information to v3d file.
+
+commit cc3ce0aef490a62b616b16ec9ea8330979b92d04
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jul 30 22:00:13 2021 -0600
+
+ V3D: Add a draft v3d import script.
+
+commit 6d957f4d713ca58fa0a17f9a16ad04c11435ec1b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 30 18:08:50 2021 -0600
+
+ XASY: Standardize case.
+
+commit 0c81a76bb5a7546a1e75992c664512dd7b27f3e4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 30 17:16:50 2021 -0600
+
+ Update demo.
+
+commit 4e4e49a9a39a108ab11cebe04309e78632649b5c
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Fri Jul 30 13:21:45 2021 -0600
+
+ XASY: Fix crash on 'Exporting as Asy' for new files.
+
+commit 88a10b46356cf14d1ef91faeea7261f346b3a226
+Merge: 63eea214 9650c998
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Fri Jul 30 13:16:58 2021 -0600
+
+ Merge branch 'Qt' of https://github.com/vectorgraphics/asymptote into Qt.
+
+commit 63eea2141b1fbb356542d18a4116969f899f8db0
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Fri Jul 30 12:06:56 2021 -0600
+
+ XASY: Add ability to cancel operation if file changed while making new file or loading file.
+
+commit 1ca12fe7d1217efb4eb6acc4bc7384fda41c6dbb
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Fri Jul 30 11:48:50 2021 -0600
+
+ XASY: Change saving asy import file warning dialogue.
+
+commit 8b9d0d7e85a1a39e01fa2cb98885513eb73a3d87
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Fri Jul 30 11:45:50 2021 -0600
+
+ XASY: Move exportXasy code into xasyFile.py for modularity.
+
+commit cbbe012edfba70fdf101716d6e401e58ee72f7ca
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 29 17:58:17 2021 -0600
+
+ V3D: Standardize element types.
+
+commit 3da65efbabfc69660b1616f28fe27a0582038301
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 29 17:38:14 2021 -0600
+
+ V3D: Update demo.
+
+commit 0a8cda8f9d0989c22b6325a841ca595d2197dd2f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 29 17:00:55 2021 -0600
+
+ Update asygl.
+
+commit d1c850efb3edd7d5cc07e2233f07358507668e12
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 29 16:55:39 2021 -0600
+
+ ASYGL: Reformat gl.js.
+
+commit 8f6820ed364f37e5cb669dd669e21c78111b986c
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 29 16:44:53 2021 -0600
+
+ ASYGl: preallocate vertices array in Triangles.
+
+commit a5401fe15e3273d24ffa395f7670d74a1cebf7c2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 29 17:00:55 2021 -0600
+
+ Update asygl.
+
+commit 466763c02e5e0e4c005465f463be69076f125927
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 29 16:55:39 2021 -0600
+
+ ASYGL: Reformat gl.js.
+
+commit b968e9311ccd087285c105539f8fd9b5f576b00f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 29 16:54:39 2021 -0600
+
+ Port to C++-11.
+
+commit f5c34d02ab5cf4514234b8b1dc33ec419c387934
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 29 16:44:53 2021 -0600
+
+ ASYGl: preallocate vertices array in Triangles.
+
+commit 9650c9989582f20a02c72668f303c71bab15080a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 29 11:41:11 2021 -0600
+
+ XASY: override outformat rather than entire user config file.
+
+commit 63112fceb984838facceef072c87d79d5be76eff
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 29 11:38:20 2021 -0600
+
+ XASY: ignore user config file.
+
+commit cc7d93f40a7895cfc9599c9ada0f2655f4db7cee
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 29 11:33:02 2021 -0600
+
+ Use single quotes.
+
+commit bd449cf33f10a9dad41e34b91dbf161ad429d093
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jul 29 02:00:42 2021 -0600
+
+ XASY: Ensure consitency of dialog for found identical files.
+
+commit 363acfd36317d6c46fc6fa12c01312bd980d2ad9
+Merge: 3d91532e 9161d8bf
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jul 29 01:51:40 2021 -0600
+
+ Merge branch 'Qt' of https://github.com/vectorgraphics/asymptote into Qt.
+
+commit 3d91532e0068d2679eea9f441d52159535d13a34
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jul 29 01:51:18 2021 -0600
+
+ XASY: Xasy file saves asy2psmap + fix actionSave() dialogs.
+
+commit 0ac652ef39eff2fbeb2cf31acce4691d4edf701e
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jul 29 01:01:15 2021 -0600
+
+ XASY: Make saving xasy the default and remove previous link functionality.
+
+commit 9161d8bfae033bf1245785327904735e89ba0e3b
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Wed Jul 28 23:30:52 2021 -0600
+
+ XASY: Add customizability to 3d rendering.
+
+commit feebc7304af30531b2749a5d15d2098531f14067
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 28 18:32:07 2021 -0600
+
+ V3D: Unify v3d and jsfile to reduce code redundancy.
+
+commit d5644b3dc7dd8605eabf38be8ab870e5422b86e2
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Wed Jul 28 17:24:05 2021 -0600
+
+ XASY: Add ability to Export to Asy straight from file menu.
+
+commit 28cf5abe4ca5cd95687d6bfd9f7246ea1d2af811
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 28 17:14:49 2021 -0600
+
+ V3D: Abstractize jsfile to abstract 3d out file.
+
+commit a8eb62ffff5002f40220c88522865746a005baed
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Wed Jul 28 15:48:33 2021 -0600
+
+ XASY: Add ability to export to Asymptote file.
+
+commit 8ccc7c9139c022e412258cd4882c777ad3b94cbf
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Wed Jul 28 15:07:42 2021 -0600
+
+ XASY: Save pen data (color/linewidth) into xasy file.
+
+commit 4903f5cd10db64a3cf535f766f44fc43e539c599
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Wed Jul 28 15:06:47 2021 -0600
+
+ XASY: Fix labels not being added with color.
+
+commit c4c749e854829467bcf0791d0cb9b0844f0acc19
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 28 14:53:44 2021 -0600
+
+ V3D: Fix bezier triangle render function.
+
+commit d907057302a43768268b51a70c493cadb1680b37
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 28 14:47:30 2021 -0600
+
+ V3D: Allow baking options in bezier triangles.
+
+commit 1cea79b09f410a04a6643e3f7ef846134c15ee01
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 28 14:43:02 2021 -0600
+
+ V3D: Make BezierTriangle function standalone.
+
+commit 21ceb4e9c9bc1aef1318af9dad5b68d56e90f910
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 28 14:11:28 2021 -0600
+
+ V3D: Enable baking patches option.
+
+commit 20eb389ef5bdb6fde4a4ce57b88fe423d6996b42
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 28 14:11:15 2021 -0600
+
+ V3D: Enable rendering of raw vertexBuffer.
+
+commit 478e300281b1348add88364ceee0d89c103e2258
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 28 13:58:30 2021 -0600
+
+ V3D: Encapsulate existing information on render to a parameter struct.
+
+commit 45910d98e58b274fb213f0208477c93e66fc5a1a
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 28 00:00:28 2021 -0600
+
+ V3D: Simplify V3D specs.
+
+commit 399bbb1bc618ccc05a3f7ecf33f574b21cf74c90
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Wed Jul 28 13:38:34 2021 -0600
+
+ XASY: Save xasyText to xasy file without going through asy script.
+
+commit b4041c7da61e56c27a6f1bad48f9e1174ef27fb4
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 28 01:03:25 2021 -0600
+
+ Add override qualifiers.
+
+commit 694b4cd9770eb597a7c19696e7fe997119273f46
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 28 00:32:44 2021 -0600
+
+ Port to clang under MacOS.
+
+commit 0a79d4e6f6cbb4f206c7703a02985bccf0926b69
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jul 28 00:11:26 2021 -0600
+
+ V3D: Infer number of control points from element type.
+
+commit b4739fee01e50b97b34fc7df9032afb33a467534
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Jul 27 22:20:48 2021 -0600
+
+ V3D: Allow rendering target to an arbitrary vertexBuffer.
+
+commit 12cfa6ed19f7be372faa9a132ff0b5c2d1f60a14
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Jul 27 18:05:08 2021 -0600
+
+ V3D: Dynamically add indices based on if they are distinct or not.
+
+commit 01fbf32a46bd1bd28178bb1f647a8243ed0931e3
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Jul 27 17:46:19 2021 -0600
+
+ V3D: Use operator<< for triple and prc::PRCColour.
+
+commit c4f171f513b5021c49453e8909d17e2e0039cd53
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Tue Jul 27 16:17:23 2021 -0600
+
+ XASY: Make add button naming conventions the same.
+
+commit dbac7243b20b8de74827a256146f6ae676c80982
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 27 09:29:29 2021 -0600
+
+ FILE: Fix bug #258: support compilation when COMPACT=0.
+
+commit dd0d7033a7c0ec45f3fc1fce12b89f7f0e4b6b43
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 27 00:48:06 2021 -0600
+
+ Patch lasy-mode to work with Emacs >= 23.
+
+commit c46633df7ff517701b488d60a55fb51755df6c87
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 26 19:50:29 2021 -0600
+
+ XDR: Add triangles to v3d file.
+
+commit 35ee832a48783d2378adb508ca0724b0058de7be
+Merge: 3a338ba8 04a5d074
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 26 17:32:37 2021 -0600
+
+ Merge branch 'v3d' of ssh://cascade.math.ualberta.ca/git/asymptote into v3d
+
+commit 3a338ba8a4b30c24d9033fa94b8a7eabebd7570e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 26 17:32:31 2021 -0600
+
+ Update v3dstd.md.
+
+commit 70e3a5e2e53a3a8d028b8807f8bc5d124ca3ba57
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Jul 26 17:16:10 2021 -0600
+
+ XASY: Update icon clicking statuses.
+
+commit 0c74479fa00167fa0b5da22e927eb505019eb3f4
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Jul 26 16:32:18 2021 -0600
+
+ XASY: Set translate mode to be default state.
+
+commit 04a5d074d6496a8eb9bbe4b772d5c27f8cdbfe87
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 26 16:15:26 2021 -0600
+
+ V3D: Add options for other primitives.
+
+commit 461d011a67fff47587e5ea4757aebc237cae2446
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 26 16:15:13 2021 -0600
+
+ V3D: Add oxstream values for rvalue.
+
+commit 5df8b4e8e430e5808c7da03b37737bc3127c0f32
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Jul 26 16:08:31 2021 -0600
+
+ XASY: Fix save prompt mid-edit.
+
+commit b64c1f1a95361a0dd0aeeb599418a7647ad3c0f3
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 26 14:50:32 2021 -0600
+
+ V3D: Support bezier triangles.
+
+commit cfc1559b82cf43958b56b566656a8b92f7ec2795
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 26 14:19:14 2021 -0600
+
+ MAKE: Add v3dfile to makefile.
+
+commit da012aee1fbfa2448fd9dec6a39d465ec7493011
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 26 14:19:06 2021 -0600
+
+ ASY: Set format as v3d in three.asy.
+
+commit e8d02dadc8beec57e6fdf6bc2c2929a0a3bd453e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 26 14:18:53 2021 -0600
+
+ V3D: Add support for bezier patches to v3d.
+
+commit a42c801b4bd00e36741fdd9f2f64ff9c993c8112
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 26 14:17:36 2021 -0600
+
+ V3D: Add v3dfile class.
+
+commit 1fc32e3b49fad691b5c34c2654794aa1d8da3321
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 26 14:17:04 2021 -0600
+
+ XDR: Add vector<double> and array<double,n> xdr packing.
+
+commit 9ead0267da5fbc0b6a1fcad95c4921e1e326d65f
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jul 26 12:16:59 2021 -0600
+
+ XASY: Check if file does not exist when loading file from command line.
+
+commit d17303f0fd9e14dfbf2923ab580de1fac2b4adf0
+Merge: 51367354 17c8855b
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jul 26 12:12:32 2021 -0600
+
+ XASY: Merge branch 'Qt' into 'Qt'.
+
+commit 51367354ca25fd96fd39f572ae246e47fc345181
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jul 26 12:10:11 2021 -0600
+
+ XASY: Opening files from command line now the same as in-app file loading.
+
+commit 6f73ced1b1db27e4880b5aad95682a47325337c6
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jul 26 11:51:55 2021 -0600
+
+ XASY: Change save to open dialog for default .xasy save.
+
+commit 17c8855b0acc7b736700ac4f7964486a7106781a
+Merge: 2a9d492d 9e6ef1e0
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Jul 26 11:21:12 2021 -0600
+
+ Merge branch 'Qt' of https://github.com/vectorgraphics/asymptote into Qt
+
+commit 2a9d492d0a1e43806b2c552c4d044edc417af129
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Jul 26 11:20:53 2021 -0600
+
+ XASY: Fix magnification error in bezier editor.
+
+commit 9e6ef1e0bbf41279563a02fc452c5f957cdc6906
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 26 11:19:31 2021 -0600
+
+ Force rendering of 3D objects.
+
+commit af78f0e9d7d2bd19c15854fcaa739ff887734f3a
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jul 26 11:05:46 2021 -0600
+
+ XASY: Remove debugging code & prevent .xasy load crash.
+
+commit adb4b1d1931ca4450a8833e98294ad78239b1ac4
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jul 26 00:41:27 2021 -0600
+
+ XASY: Handle undo from accepted edits in Edit Mode (i.e. controls/nodes).
+
+commit 11af899bc8fd2396c5a511201149bf98371b6f72
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Sat Jul 24 23:51:31 2021 -0600
+
+ XASY: Re-add code in 32cdfc22, deleted accidently in 14dfff01.
+
+commit 5415ca365f5c4bfee018cfa492d89cbfcab833ee
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Sat Jul 24 23:36:34 2021 -0600
+
+ XASY: Fix exporting recently made xasy objects to both .asy and .xasy.
+
+commit e6541aa352cb6b65a82057b24ad08158bd7804fc
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Sat Jul 24 19:56:34 2021 -0600
+
+ XASY: Create handler for loading legacy .xasy files.
+
+commit 7ff8049248cecd24b1c24139b72abbb8512d3dd5
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Sat Jul 24 19:38:42 2021 -0600
+
+ XASY: Add linked .asy file on title when editing .xasy file.
+
+commit 52cd9e7c2499fb6c8a6e9a57417a73b73ef31687
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Sat Jul 24 19:09:30 2021 -0600
+
+ XASY: Delete duplicate objects if user saved new objects to both .asy and .xasy.
+
+commit c854dd2c6bf04d0e3d48c65cc51831a6a281f5b5
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Sat Jul 24 01:54:05 2021 -0600
+
+ XASY: Load xasyScript object directly from linked .asy file while loading from .xasy.
+
+commit 8a650dc18fdd0989fc1f1879a2952d0dbeef2182
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 23 23:30:09 2021 -0600
+
+ Use pointer for WebGL cursor.
+
+commit e2640c1a08838801bed347122b0dfbd3c9b700c0
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 23 17:32:48 2021 -0600
+
+ Add preliminary v3d standard.
+
+commit 8c1d863d3c332b91490598c84d9bcc51ff9bb37d
+Merge: cfd3121e c84c526a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 23 16:42:22 2021 -0600
+
+ Merge branch 'master' into v3d.
+
+commit b8d4e3a39f9b5acc99e0219954139f5fe0b64a82
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Fri Jul 23 15:26:50 2021 -0600
+
+ XASY: Save .asy objects into linked .asy file when saving via .xasy.
+
+commit 14dfff01756801fe1f30f98f9bc6d7683f476b45
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Fri Jul 23 13:19:23 2021 -0600
+
+ XASY: Save corresponding .asy file on .xasy save + typo fixes.
+
+commit c84c526ae94c420b0555ef33c2c37fc2177f34d7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 22 11:35:52 2021 -0600
+
+ Update documentation.
+
+commit edfcc7bf88f0c1054d77a99bdaaf0d9acc8d1230
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Thu Jul 22 00:31:30 2021 -0600
+
+ XASY: Fix some drawing issues with the bezier editor.
+
+commit 5d5c43d366f876a28472c71838726294e4086efc
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Tue Jul 20 22:07:02 2021 -0600
+
+ XASY: Add more possible messages to the status bar.
+
+commit 32cdfc22ddbd02f779296db7db72f19713e51b8e
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Jul 19 11:13:13 2021 -0600
+
+ XASY: Fix closing bug.
+
+commit b8b046786d83fcc8f1728c2c084a4718ed8c13b4
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Jul 19 11:08:05 2021 -0600
+
+ XASY: Fix Bezier editor transform bug.
+
+commit ad84064b6721d033ea95ece4aa7702bd99ed5f29
+Merge: 86c8c792 f69347fe
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 19 10:42:16 2021 -0600
+
+ Merge branch 'Qt'.
+
+commit 86c8c7924bbf1c85d64f2b0939c2f70e5d614044
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 17 12:43:59 2021 -0600
+
+ Fix last revision.
+
+commit 92f6ecaed7ed3a90a3a83511fb26b153ce6f6bf6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 17 01:08:41 2021 -0600
+
+ TRANSPARENCY: Fix bug #253.
+
+commit 895c90e88d01515a784be33fc9c7923b1bfbe408
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jul 17 00:25:13 2021 -0600
+
+ LSP: Properly stop DFS search if getExternalRef is empty (i.e. file does not exist).
+
+commit 34782cd981a38d9e7387f3c6a48c98e1905a8688
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jul 17 00:17:37 2021 -0600
+
+ LSP: Skip BFS step if file fails to parse.
+
+commit 0a4009bde77cfaeb5003040f73a92f5e6d4c3013
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jul 17 00:15:37 2021 -0600
+
+ LSP: Refine checks for virtual files: settings and gsl.
+
+commit b16efc20fdb0d22eb51bd2c250a0f924e1772138
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 16 20:23:24 2021 -0600
+
+ Fix segmentation fault.
+
+commit 9893e3d6a11d3c1c5169da4fd66d074e54ebf0e5
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 15 23:23:51 2021 -0600
+
+ LSP: Exclude settings from search traversal.
+
+commit a939cea6be4b5e31ec0298b8d43a0ce26058a24e
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 15 18:08:42 2021 -0600
+
+ Distinguish between std::string and mem::string.
+
+commit fa5598cf9efccf17c9a8e2da31ee96d7a1b753d6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jul 15 00:45:42 2021 -0600
+
+ Work around null pointers.
+
+commit f69347fe1a84d77c7c024e6e453066140c224152
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Wed Jul 14 23:01:15 2021 -0600
+
+ XASY: Implement 'New File' functionality.
+
+commit ec6fcb25edeba2b88d19d91b05c4eaedbb99a5a5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jul 13 22:26:22 2021 -0600
+
+ Make lspport and lsphost environment settings.
+
+commit 4dc77c0eed54202ccafdbea6db7a851463e900d4
+Merge: 224a60e7 9cae116c
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Tue Jul 13 15:05:43 2021 -0600
+
+ Merge branch 'Qt' of https://github.com/vectorgraphics/asymptote into Qt
+
+commit 224a60e7195965740ac3b4e647192a8780c0ac80
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Tue Jul 13 15:05:36 2021 -0600
+
+ XASY: Remove window1.ui debugging code.
+
+commit 9cae116c1af47da0d237693e541fe20b347f7cb9
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Tue Jul 13 15:02:34 2021 -0600
+
+ XASY: Restores fixes with bounding box.
+
+commit 33fc5d9246c23ec1dab506fe302cbecf83f90831
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Tue Jul 13 12:35:00 2021 -0600
+
+ XASY: Fix tool tip name.
+
+commit 158b39a6a3f38d0f04a71a840bcc951940504176
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Tue Jul 13 00:15:29 2021 -0600
+
+ XASY: Fix crash on clearing recently opened menu.
+
+commit 63be9dc26f51af40d4d9430a29880cc4ce2e9777
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 12 20:14:19 2021 -0600
+
+ LSP: Use unique_ptr instead of manual new/delete initialization of remote end point.
+
+commit 5dc62f6c3c445077ff5782c9c3d53511b3fba90e
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jul 12 18:12:26 2021 -0600
+
+ XASY: Remove debugging code for .xasy binaries.
+
+commit c51dc292f0495aefefc6eff147aadff2204f5094
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jul 12 18:01:29 2021 -0600
+
+ XASY: Include .xasy binary export into main save/load flow.
+
+commit bacaf250eadf77a64ad6e4c05cd7a772d5a86868
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Jul 12 16:48:17 2021 -0600
+
+ XASY: Fix translation bounding box issue.
+
+commit 884f7ccf9e670e848ef7d5a8cdac44641677238b
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 12 14:35:02 2021 -0600
+
+ CXX: Set all errors to const& and exceptions from std::exception.
+
+commit bfb52602761c2fd0abaf4ac9da54e784828cd765
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jul 12 14:31:43 2021 -0600
+
+ LSP: Split Asymptote LSP Server into separate stdio/tcp components.
+
+commit 5a8403f3e22a568fc0e90c77134a0a36f93f18e5
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jul 12 14:17:03 2021 -0600
+
+ XASY: Include transformations into .xasy binary export/import.
+
+commit 15f814e7a6c8d897e10bec86a9dd15937c6abf2e
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jul 12 13:58:48 2021 -0600
+
+ XASY: Reverse previous bounding box calculation change.
+
+commit 4d38b8ecc211b7ad73910b91d1333aa6a2263a00
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon Jul 12 09:48:52 2021 -0600
+
+ Update year.
+
+commit ed73fd37a91dd6827a4bf1e9be2bde37f666eaa8
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jul 10 23:15:33 2021 -0600
+
+ Remove unused code.
+
+commit ad6f30f006b1bb277ec7d241c1696073c80a4d34
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jul 10 15:26:04 2021 -0600
+
+ BUILD: Change C++ standard to -std=c++17.
+
+commit e3fc67832f9e3336234de399f8402d16d6ec2270
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Sat Jul 10 15:24:47 2021 -0600
+
+ LSP: Make mem::string explicit in dec.h.
+
+commit aa1ff6b608b06642d1103a1f0474c1a7992caa8f
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Fri Jul 9 13:04:24 2021 -0600
+
+ XASY: Include saving xasyScript and xasyTest while exporting to *.xasy binary.
+
+commit 9dfeff919260de7bc32acbd898abf944c7009c7c
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Fri Jul 9 13:01:13 2021 -0600
+
+ XASY: Break xf.saveFile function into creating and writing the asy string.
+
+commit b5da1baeb9fb335d28a802acc2042cb93aa8e612
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 8 16:37:26 2021 -0600
+
+ LSP: Search through struct declarations for functions.
+
+commit 4f85dfc3d70a0287dd93141dd0996fd1275e0a29
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 8 15:50:43 2021 -0600
+
+ LSP: Search unravel struct values alongside filenames.
+
+commit 7d158258b3ac1e6adc07aa2890d776d361af0854
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu Jul 8 15:44:26 2021 -0600
+
+ LSP: Check if unravel values is a fileId.
+
+commit 41f9ca54b1cb64ff597fff41f6df08c0662e9c9f
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Wed Jul 7 20:47:04 2021 -0600
+
+ Fix bounding box pen glitch and remove unused code.
+
+commit 74ecf40126466d16c20a26afeab1e84deb321757
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Wed Jul 7 19:46:07 2021 -0600
+
+ XASY: Add testing functions for export into .xasy binary.
+
+commit 546a841ba755f7696972438016f4b82251d98513
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Wed Jul 7 19:41:57 2021 -0600
+
+ XASY: Fix typo and makePenCosmetic issues.
+
+commit 7f08ed403043840051fd78a1d93c2e02e6cad3d6
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Wed Jul 7 19:39:41 2021 -0600
+
+ XASY: Set-up framework for export to .xasy binary.
+
+commit 8a06b5701099e1941d8ea61acfcb27f039619f6a
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 7 15:46:50 2021 -0600
+
+ LSP: Search from access declarations for functions.
+
+commit 2fbdcbee88202969b31f2c52a4cf344d326c30e7
+Merge: cb0f82f3 20e1d214
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 7 14:36:20 2021 -0600
+
+ Merge branch 'lsp' of github.com:vectorgraphics/asymptote into lsp
+
+commit cb0f82f3bc1d60d3217c1ad744b9dd551cc41ee1
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 7 14:35:07 2021 -0600
+
+ LSP: Append the directory of the file to Asymptote's search path.
+
+commit 5ff8870351dda4586c6398b1245b10c78674c7b6
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 7 14:34:19 2021 -0600
+
+ LSP: Search "from" access declarations for variables.
+
+commit a1038310513b1b4c1025d8e98b30da0d68eeba27
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 7 14:29:05 2021 -0600
+
+ LSP: Enable recording of from declarations access.
+
+commit 9460297463f97d30aeba20d0669a24b74713538a
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jul 7 14:28:32 2021 -0600
+
+ LSP: Add general processing list function.
+
+commit be32229b074117fc2c44d7023f1162fbff21d78c
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Tue Jul 6 17:29:55 2021 -0600
+
+ XASY: Replace undo/redo icons.
+
+commit ce507966cfd81f01e62fd6a066ae0a307a46e31e
+Merge: 3726940a 2fe124e7
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Tue Jul 6 13:38:31 2021 -0600
+
+ XASY: Merge bounding box change with last commit.
+
+commit 2fe124e733c9d3e9accdf290d2463dbece1975ce
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Jul 5 10:46:38 2021 -0600
+
+ Fix bounding box branching.
+
+commit 20e1d214eb06570fed06aa4b26264a64a50362d8
+Author: Supakorn "Jamie" Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jul 2 16:37:16 2021 -0600
+
+ LSP: Add symbolmaps to Makefile temporarily.
+
+commit 9a94a6e4978fa677c5344bdb7c828b523a1eb0bd
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jul 2 15:35:10 2021 -0600
+
+ LSP: Enable symbol context search for access declarations.
+
+commit d43f8971b3c9de2bb8a67e33b686dc711910cc29
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jul 2 14:35:49 2021 -0600
+
+ REPO: Update vscode settings to disable js format and python language server.
+
+commit a6a88e866411b88ec8038fc28f5173824c7f3a67
+Merge: e38a3c3f 84451cf2
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 2 12:51:24 2021 -0600
+
+ Merge pull request #255 from Honghe/patch-1
+
+ Update asymptote.texi.
+
+commit 84451cf2def1d149e6c4b26046263983ac58fd41
+Author: Honghe <leopardsaga@gmail.com>
+Date: Sat Jul 3 00:00:31 2021 +0800
+
+ Update asymptote.texi
+
+ `GSView 6.0` is end of life.
+ `Sumatra PDF` can auto reload when the `.eps` is changed, and supports latest Ghostcript 9.54+.
+ https://forum.sumatrapdfreader.org/t/ghostscript-not-working-error-loading-on-ps-files/3826
+ https://github.com/sumatrapdfreader/sumatrapdf/commit/5a295db98381f925aa81d13988ffadf74953b8de
+
+commit 2a41b3468a2aeb18575b6cf5e54e1460eac94b72
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 30 17:17:15 2021 -0600
+
+ LSP: Centralize the logging process for LSP.
+
+commit 71bfb9ae3c11d31cea544632d7d9439de1cfba9f
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 30 16:40:51 2021 -0600
+
+ LSP: Remove filename from update file contents table.
+
+commit bfdf27e8c3ec27ac20bf7e317fa683e1a00e0c99
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 30 16:40:14 2021 -0600
+
+ LSP: Start in IO mode without tcp.
+
+commit 1a5d0f0e5c9ac0a5c484a18e781252b3dd3a9308
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 30 16:39:58 2021 -0600
+
+ LSP: Add StartIO mode for production.
+
+commit 7641b7ff4c18289d464d09b44414600c6dc88212
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 30 16:38:57 2021 -0600
+
+ LSP: Fix the initialization of NullResponse in shutdown request.
+
+commit ee5284574753a06d309d39a685db9c740d7a87f8
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 30 16:24:55 2021 -0600
+
+ LSP: Log level based on asymptote verbosity.
+
+commit 7131a2a5ef504c5178b875911dfff62f5ed03ab2
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed Jun 30 16:24:20 2021 -0600
+
+ LSP: Add onClose and onExit notification.
+
+commit 702a2344c7354fbc2dd79abea747d9f8236db9bd
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Jun 29 16:01:19 2021 -0600
+
+ LSP: Enable gc thread registration.
+
+commit 593e6337348fcca451a16ee64a906b2c80a9b9f1
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Jun 29 16:01:03 2021 -0600
+
+ LSP: Add LSP port and host option for tcp.
+
+commit ec04bce3d635af4efd6acc02ea5339104907ad99
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue Jun 29 15:52:19 2021 -0600
+
+ LSP: Fetch multiple definitions for functions.
+
+commit 3726940ad274b9c6fd96cbb98e5b7e274148ad84
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Tue Jun 29 13:13:28 2021 -0600
+
+ XASY: Fix typo on self.ui.txtLineWidth.
+
+commit 0fa72a41d4cb04feca7f7be71c2598b11692542f
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Tue Jun 29 13:12:43 2021 -0600
+
+ XASY: Make bounding box calculation factor in pen line width.
+
+commit 7d193e5188cf12035b4d50090e3534abb2e42e69
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 28 18:49:22 2021 -0600
+
+ LSP: Add the file's directory to the search path during symbol map construction.
+
+commit 3e161069eeb6c500f9e8cc47b239a9f6f691ed7b
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 28 18:48:53 2021 -0600
+
+ LSP: Update file contents on change if applicable.
+
+commit 06f7086af1f839e36b69d61c0cfd2329554cbb4a
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 28 18:42:15 2021 -0600
+
+ LSP: Enable full search of access and struct symbols.
+
+commit df92e1dfd81f33805ce3b59b71b800381dacb47d
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 28 18:38:31 2021 -0600
+
+ LSP: Add unravel ids to SymbolMaps.
+
+commit 249ce56ae2f13aee520ef22d21a640ce6f42c19b
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 28 18:36:29 2021 -0600
+
+ LSP: Move external reference data to a separate struct.
+
+commit 97513e53db27f902e9a79b6464751eff71b1c567
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 28 13:45:50 2021 -0600
+
+ PEN: Add rgba function to plain_pens.asy.
+
+commit 7f9811bae2afd80dd7efbe92e101145f5b39617a
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 18 22:47:55 2021 -0600
+
+ PARSER: Move icode and istring to header for accessibility.
+
+commit 0490c9d64ba49fe688cc9521947249c0d7f31e4d
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 18 22:26:20 2021 -0600
+
+ LSP: Handle crude document color request.
+
+commit 55b8c513140ca0475f786869bb8d516a036b4faf
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 18 22:25:35 2021 -0600
+
+ LSP: Extract out the SymContextPtr* fetch process.
+
+commit f249b2d8ea8275aba93050b3c82f48629f9b1420
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 18 22:22:27 2021 -0600
+
+ LSP: Clean up SymContextInfo.
+
+commit e38a3c3f7318691fadfde0cb3864687f48428aa6
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Jun 26 16:18:56 2021 -0600
+
+ Upgrade from ocgx to ocgx2.
+
+commit 8da12dc8ad0f4e56f0c0bd8f7300e9d3d4770572
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jun 25 14:23:59 2021 -0600
+
+ Upgrade from ocg to ocgx.
+
+commit 40022b3d35bd8321be2a86c8fc53bacf69eed787
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jun 21 22:52:41 2021 -0600
+
+ XASY: Change title when file is modified.
+
+commit 618d74c8f63bf8d419b40b400be9e4fc3a906d2e
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jun 21 22:28:36 2021 -0600
+
+ XASY: Update TODO comments.
+
+commit a0b6f422ee0e37705459246ccf04f3f73d538562
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jun 21 22:17:36 2021 -0600
+
+ XASY: Place xasyrecents.txt in ~/.asy folder along with other config files.
+
+commit ea62ca6f1e96938200f55125865bd30855cd0149
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jun 21 22:16:46 2021 -0600
+
+ XASY: Fix recently opened QActions from menu not linking to correct file.
+
+commit 3cad6938e2d4f8cf03b6e23dfb682e3a433d731d
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 18 22:17:55 2021 -0600
+
+ LSP: Add retrieval of color information from exp.
+
+commit f9fc032ab1df26434649f6ee0000fbc68750b184
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 18 22:14:09 2021 -0600
+
+ LSP: Fix decid createSymMap with type.
+
+commit 3ad2a131e12979daa5cea59bbd012ac8fa70b49f
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 18 22:13:43 2021 -0600
+
+ LIB: Update LspCpp library to use boost::optional.
+
+commit afa8dfd2c8d87b27ab8e8a678fff46fea0a6dd44
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jun 17 19:51:32 2021 -0600
+
+ XASY: Delete extraneous code on freehand drawing handler.
+
+commit faf82d60feca29fdcc5a8ab5d7aec71d09071ead
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jun 17 19:28:24 2021 -0600
+
+ XASY: Add placeholder function for freehand draw tool.
+
+commit 95e4a77a87a8deb4d9168b65fa36e59c4e06fe78
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jun 17 18:31:45 2021 -0600
+
+ XASY: Connect freehand drawing button on UI to to-be-implemented action handler.
+
+commit 75799ae0a1e079429021d7fc8cf402f747155bd2
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jun 17 18:23:37 2021 -0600
+
+ XASY: Change icons.qrc to include brush svg.
+
+commit 988439ac7dc406dcd0507b488e741f4b6b474de0
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jun 17 17:44:14 2021 -0600
+
+ XASY: GUI elements for freehand drawing.
+
+commit 3c7c07b2c47919c22a93774f8728db9514952e92
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jun 17 11:27:54 2021 -0600
+
+ XASY: Add TODO comment and recent.txt file in config directory.
+
+commit 26cc499ee03aa3200531282a67c41d94fffd0394
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jun 17 11:13:22 2021 -0600
+
+ XASY: Open recent class to handle paths
+
+commit 0f41b3af1bea5ad1c88c740502ee52b369e922e8
+Merge: 8dfb98bc 0d799204
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jun 17 11:11:11 2021 -0600
+
+ Merge branch 'Qt' of https://github.com/vectorgraphics/asymptote into Qt
+
+commit 8dfb98bc5bb4f5e9acb1a93d358cbe3592506a91
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jun 17 11:11:03 2021 -0600
+
+ XASY: UI elements for menu of recently opened files.
+
+commit 0d7992042bf973680d8c5e3b876fba156c885821
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Jun 14 00:00:46 2021 -0600
+
+ Fix bounding box sizing issue.
+
+commit f0b6d339c51a7d02176400fe2de468b58f4752a0
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Sat Jun 12 01:17:45 2021 -0600
+
+ Fix bounding box drawing under scaling.
+
+commit 99cadc21e19a82eddbcd54b84b19cf0aa14c70d6
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Sat Jun 12 00:49:01 2021 -0600
+
+ Fix line thickness of objects after magnification.
+
+commit 48af59ba9e87c530c260886ceb0ec168ed9ea87c
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 11 16:10:30 2021 -0600
+
+ LSP: Add createSymMap for range-based for loops.
+
+commit 01aefbdb8a911bad63c5d67b05db61990b82d9a9
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 11 16:10:13 2021 -0600
+
+ CXX: Format code files and add attributes.
+
+commit 8812cf49fe43371bac49d6480b838e595e87672a
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 11 16:09:08 2021 -0600
+
+ LSP: Add signature searching of struct contexts.
+
+commit 33db4bbc39ef70f55ff14564dc20ac5407c3d20c
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Fri Jun 11 02:32:37 2021 -0600
+
+ Fix some scaling bugs.
+
+commit 3b7bef84dec6b9b09e294f2d018abae9f6ee4daa
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon Jun 7 23:39:10 2021 -0600
+
+ LSP: Allow for multiple functions loading in hover request.
+
+commit f1f36b434958c125be2c110c81c52ae3266df1b0
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jun 7 16:31:01 2021 -0600
+
+ XASY: Change MainWindow1.erase() to fix crashing after opening a file then undo.
+
+commit e8f7946db8ac78ef73a64ff2cfe50daffd6048e2
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jun 7 15:42:03 2021 -0600
+
+ XASY: Make undo/redo menu button available after script object delete.
+
+commit 190676f02243ba514a4dad351a5834921d6469a7
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jun 7 15:01:20 2021 -0600
+
+ XASY: Change softDelete key name, and ncrease readibility on UI of addPolyOpt menu.
+
+commit 9be0e9269b1dca5eb651bca81b45d46cff046081
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jun 7 13:01:42 2021 -0600
+
+ XASY: Fix undo/redo for deleted objects imported from .asy scripts.
+
+commit 170743bcf5a9b00c8173059acdd96227676762e9
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Mon Jun 7 12:06:32 2021 -0600
+
+ XASY: Fix untransformed deleted objects not saving
+
+commit 5f3e93cd8118118154e97c8d3743998b668bfee8
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon Jun 7 09:01:27 2021 -0600
+
+ Fix line thickness issue with scaling.
+
+commit 21bafac812f6a9d0a28c64666db0572ac6e06ec4
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Fri Jun 4 21:29:55 2021 -0600
+
+ Fix exit error on startup.
+
+commit 138dc26012377f36b9b8a5a4457e5095a2ee70ae
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Fri Jun 4 21:24:24 2021 -0600
+
+ Add cancel feature to exit box.
+
+commit 74f24be64e1a18b8aa30424400eef5db718186c8
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 4 15:15:42 2021 -0600
+
+ LPS: Enable searching in external file locations.
+
+commit a517a4349086d6765bf5b0bb2b7bf383ee01775b
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri Jun 4 15:14:43 2021 -0600
+
+ LSP: only recurse statements if value is not null.
+
+commit aa5f5aecac3e399dda3e39eecfa67b82bc814b0b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 3 22:13:51 2021 -0600
+
+ FILE: Fix bug #247.
+
+commit 638206d86745878a746548d9ecc2d5fb1945d725
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jun 3 21:18:06 2021 -0600
+
+ fixed: undo create object crashes if selected object is deleted
+
+commit 8e95228aff14dbd37821bca7b519a20d4bcc73f5
+Merge: 0442d6c4 c195c1fc
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 3 14:03:32 2021 -0600
+
+ Merge branch 'Qt'.
+
+commit c195c1fc4c5b0631aae84cc75b3b9bf27da677e5
+Merge: bbacc4f8 ded4ea86
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Jun 3 13:55:00 2021 -0600
+
+ Merge pull request #249 from vectorgraphics/Qt-macos-accessibility
+
+ Qt macos accessibility
+
+commit ded4ea8607cf1478871d6c1b9b951773b8e177b3
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jun 3 13:19:57 2021 -0600
+
+ accidental change to QMenuBar height
+
+commit ea63eb31c5925a01ea3219bead12dc6725201ec6
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jun 3 13:10:37 2021 -0600
+
+ changed git ignore to include python virtual environment
+
+commit 0433358c31035f123a8c2d9a0e4f304197b3030f
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Thu Jun 3 13:08:38 2021 -0600
+
+ Added possibility of keyboard focus on main screen so textbox shortcuts don't override global ones
+
+commit bbacc4f870f38222dff57f6de82d053a813b1cea
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Thu Jun 3 12:28:04 2021 -0600
+
+ Fix issues with checking buttons.
+
+commit 0442d6c4230ad48cd793f661812a17a106bfb17d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Wed Jun 2 17:31:15 2021 -0600
+
+ Update example.
+
+commit 7a46888f213770564bfbcf38fe63dda320393e1c
+Author: RubberNoodles <ocheng@ualberta.ca>
+Date: Wed Jun 2 13:25:42 2021 -0600
+
+ fixed btnAlignX/Y not showing on Mac due to insufficient container width
+
+commit 76702591d248278c20260206bd1d8f6bff27993a
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Jun 1 13:13:31 2021 -0600
+
+ Force all threads to return error code.
+
+commit 0caac12482845a6d450730a76c6fc658c3475505
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 31 10:09:39 2021 -0600
+
+ Fix Y icon font.
+
+commit 4c83ba7857355dca85fc8c2c6bbbb83f8d4e3cd7
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 31 10:09:39 2021 -0600
+
+ Fix Y icon font.
+
+commit 15d3f030d7ec999213a8aaa75b9de42487485a2a
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon May 31 09:20:51 2021 -0600
+
+ Fix saving prompts and add hotkeys.
+
+commit 2ae710ed1822dc925f09a4f27ea895b9f7df3bdb
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 27 15:36:42 2021 -0600
+
+ LSP: Simplify hover requests and enable signature lookup.
+
+commit b0524e3dd020c76d0a49cb2bdd3cfb6f28131d6c
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 27 15:35:22 2021 -0600
+
+ LSP: Add fromMarkedStr for asymptote labelling.
+
+commit 2de9f75df81a4506b8748a58b15f3a99916975b0
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 27 15:34:42 2021 -0600
+
+ LSP: Build tree on open/save.
+
+commit 4b9bebd7df6a74706c803ad2c3ed57f562a32627
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 27 15:34:06 2021 -0600
+
+ LSP: Allow for type-searching in LSP lookup.
+
+commit 8e390ad19a5aab015f1501f07793a49f90ad7c29
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 27 15:32:19 2021 -0600
+
+ LSP: Add FunctionInfo struct to LSP.
+
+commit b94942859d268e7fc12f6e846dfb586f1a7b51a9
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Thu May 27 15:27:46 2021 -0600
+
+ LSP: Support exp statements createSymMap.
+
+commit 97926071c5b5e698192dfcd30d0be92df904ff22
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 27 14:10:15 2021 -0600
+
+ Fix bitwise negation operator.
+
+commit d4a09ce89a8d3541ef2f26e844db68f504bef8fe
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed May 26 13:57:22 2021 -0600
+
+ LSP: Support goto definitions.
+
+commit 5000b66451ff5bb88316fe68bc826c79c2894c81
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Wed May 26 13:55:48 2021 -0600
+
+ LSP: Add createSymbolMaps for more statements.
+
+commit e312cdf36414011f635329fdece0c45c02033220
+Author: John Bowman <bowman@ualberta.ca>
+Date: Mon May 24 23:59:49 2021 -0600
+
+ TRANSPARENCY: Fixed bug #245.
+
+commit 512c2dfc64a44dfdbc574b689668f9406d74db02
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 24 16:13:26 2021 -0600
+
+ RUNFILE: Explicitly use camp namespace to avoid conflicts.
+
+commit 369e43e3f821952c52cea45d3857300e284e3418
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 24 16:12:57 2021 -0600
+
+ LSP: Add createSymbols for exp and stm for blocks and symbols.
+
+commit f1ae4e1b35cbae7089ee3b2bdbd1e609d3328393
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 24 16:11:50 2021 -0600
+
+ LSP: Remove lineUsage and use the vector instead.
+
+commit b8b7dc4a5b023b452a34839c0fccdbe7cce3aa43
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 24 16:10:54 2021 -0600
+
+ LSP: Contextualize symbolmaps to support block codes.
+
+commit d2e6b12a8faeadccdc056e76a036743e3cdaea0b
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 24 16:08:05 2021 -0600
+
+ LSP: Add lt comparsion for positions.
+
+commit 9dac66a12fc7178d88ed0ab7a63544924b9b4018
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 24 16:00:55 2021 -0600
+
+ LSP: Add explicit operator to std::string.
+
+commit 5c35e19aaf39d58f8209b5e4956de8c935c2f355
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Tue May 18 19:07:26 2021 -0600
+
+ LSP: Separete Symbolmaps into a cc file.
+
+commit 7376cb1111d319e1eabda96f46270dc6ea9e340c
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 17 17:04:23 2021 -0600
+
+ LSP: Enable Asymptote to start in LSP mode.
+
+commit f8014e0ecc8096bfb32d86c767070901b67146de
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 17 17:03:43 2021 -0600
+
+ MAKE: Add temporary new files to Makefile.
+ This is a temporary change, it is meant to be added
+ to a proper place later on.
+
+commit f219b8caae79fe131999badfa8435fb0f9995eee
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 17 17:02:57 2021 -0600
+
+ LSP: Add basic LSP server code to Asymptote.
+
+commit 930e13f9530f1b8db05f4296369f5bd0da543c74
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 17 17:02:21 2021 -0600
+
+ LSP: Add crude symmap creation function to absyn.
+
+commit 4fe425671a58432291dd5daa0a81996209ab2d5e
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 17 16:59:08 2021 -0600
+
+ LSP: Add crude symbols data table.
+
+commit d7327c68d886a8856aa981fd7fca1409b603752c
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 17 16:56:22 2021 -0600
+
+ CXX: Add smart pointers to common.h for future convinence.
+
+commit a7ef5ded5503256a7607fd42e8643d4894735e56
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Mon May 17 16:52:50 2021 -0600
+
+ GDB: Add .gdbinit to ignore Boehm and asy signals.
+
+commit 2c33f258c58ae7df32139690eee606081cba61ad
+Author: Supakorn Rassameemasmuang <rassamee@ualberta.ca>
+Date: Fri May 14 21:32:48 2021 -0600
+
+ Move ifile/tree/core declarations to process.h.
+
+commit ffa71972faef1b242cc9141440a0c7210dfe630b
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon May 10 10:39:53 2021 -0600
+
+ fixed y-axis inversion bug in initialized and load-fail states
+
+commit c71330188e834f3f4e47452dfd26eb51ec688649
+Author: chaumont-arch <chaumont@ualberta.ca>
+Date: Mon May 10 10:39:53 2021 -0600
+
+ fixed y-axis inversion bug in initialized and load-fail states
+
+commit e1eb7e2c3c22caa8052e70b38055ca45420eebe2
+Merge: 634e1b8f c71d3faf
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 6 22:52:55 2021 -0600
+
+ Merge pull request #243 from vectorgraphics/graphwithderiv.
+
+ Add graphwithderiv function.
+
+commit 634e1b8f97e8572d8448053f7f64c24657f3dc64
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 6 15:39:40 2021 -0600
+
+ Fix bug #229: Duplicate KEY in xasy.
+
+commit 0ecf39dbc3509938c568a254cb3acda77b8ac37d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 6 14:15:49 2021 -0600
+
+ Calculate maxKey.
+
+commit cbb05a8e2a46c2c1ab9f081d9ef469da71dbd382
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 6 15:39:40 2021 -0600
+
+ Fix bug #229: Duplicate KEY in xasy.
+
+commit e9c003d4b50402be1009f906dc97f6b8ba89b1f3
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 6 14:15:49 2021 -0600
+
+ Calculate maxKey.
+
+commit fc8b0803744cb892d670455c9d86d56ad348ad04
+Merge: b4bf0803 bbb1ed00
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu May 6 09:44:31 2021 -0600
+
+ Merge branch 'master' into Qt.
+
+commit 986cd0a49e4bcdae31bf3b49af04978c5e7e505b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue May 4 23:29:52 2021 -0600
+
+ Begin support for language server protocol.
+
+commit bbb1ed004e0962870889e85cf37b3b5ce0ef961b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 23 08:15:57 2021 -0600
+
+ Fix typo in documentation.
+
+commit 37295db17c2d7fc305a9c587ac474f4d9da40e0f
+Author: John Bowman <bowman@ualberta.ca>
+Date: Tue Mar 23 08:12:32 2021 -0600
+
+ Fix asyPath in Xasy label editor.
+
+commit c2e38436032772e7d4a9ab5b093e0bb9ab03e59d
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sat Mar 20 10:58:24 2021 -0600
+
+ Override Xasy settings upon every load.
+
+commit 764e47fe845a27167d5d7f24f69dc454d6da4b24
+Author: John Bowman <bowman@ualberta.ca>
+Date: Sun Mar 14 19:33:31 2021 -0600
+
+ Increment version to 2.71.
+
commit cef479451a35b8a242d68e45666f97583270df0d
Author: John Bowman <bowman@ualberta.ca>
Date: Sun Mar 14 18:29:38 2021 -0600
@@ -1397,6 +5698,12 @@ Date: Sun May 10 22:08:53 2020 -0600
Raise logo3 camera.
+commit b4bf080363fc22960634ce565b5418db28692bd3
+Author: Pedram Emami <emami1@ualberta.ca>
+Date: Fri May 8 18:14:45 2020 -0600
+
+ Fix typo.
+
commit d9bbb71b151c1ff1ee920045607240ed80ead95f
Author: John Bowman <bowman@ualberta.ca>
Date: Wed May 6 01:00:21 2020 -0600
@@ -1578,6 +5885,37 @@ Date: Tue Mar 10 14:56:11 2020 -0600
Detect failure of TeX pipe.
+commit 40dc7d7b71fa5d02c5558a12b99b13385e460a75
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 5 18:49:30 2020 -0700
+
+ Update documentation.
+
+commit 4891f4653598b70f2a9e1f5836f7e7bc2d4187aa
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 5 18:08:42 2020 -0700
+
+ Fix typos.
+
+commit 4f54a5bedca4fb42418e49960ea8d82a4023e043
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 5 18:00:46 2020 -0700
+
+ Fix typos.
+
+commit ce34396977cd41e372180d1cedbd5206891ff314
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 5 18:00:32 2020 -0700
+
+ Update documentation.
+
+commit 79ec5d5c2b5bd432709265d53bcbe51d0cafe1ce
+Merge: c161ffe7 f9bc3f2b
+Author: John Bowman <bowman@ualberta.ca>
+Date: Thu Mar 5 14:15:05 2020 -0700
+
+ Merge branch 'master' into Qt.
+
commit f9bc3f2bbdbb382a1cbf15b7b977608900b2d804
Author: John Bowman <bowman@ualberta.ca>
Date: Wed Mar 4 22:44:32 2020 -0700
@@ -1931,6 +6269,12 @@ Date: Wed Feb 12 13:42:05 2020 +0100
Sync
+commit c161ffe7b7e4b84a0e0767fd3e881587660cc7a1
+Author: Pedram Emami <emami1@ualberta.ca>
+Date: Thu Feb 6 14:05:54 2020 -0700
+
+ Pulish the code and include incode documentation
+
commit 9beb5b6c72ce47c8fad8c33f14b78015c9baa40f
Author: John Bowman <bowman@ualberta.ca>
Date: Wed Feb 5 22:26:02 2020 -0700
@@ -2011,6 +6355,12 @@ Date: Tue Jan 28 16:43:43 2020 -0700
Fix degenerate surface normals.
+commit 7300f0c37ca036f7b47ea2197026a58f3b1a03d4
+Author: Pedram Emami <emami1@ualberta.ca>
+Date: Mon Jan 27 21:17:21 2020 -0700
+
+ Apply patch and modify getObjectCode() in xasy2asy.py
+
commit fdf8aeae3c1a11fb04f70674ca060a814fe2b12c
Author: John Bowman <bowman@ualberta.ca>
Date: Wed Jan 22 09:24:35 2020 -0700
@@ -6942,6 +11292,12 @@ Date: Sat Jul 14 10:34:17 2018 -0600
Fix segmentation fault.
+commit cfd3121e4a997376e8cebf3ee6c53cac9ed689c5
+Author: John Bowman <bowman@ualberta.ca>
+Date: Fri Jul 13 17:06:40 2018 -0600
+
+ Add preliminary test of v3d format.
+
commit e1f68286465d275a5677860950e266288ade44a1
Author: John Bowman <bowman@ualberta.ca>
Date: Thu Jul 12 15:13:59 2018 -0600
@@ -10066,6 +14422,12 @@ Date: Sat Jan 7 19:16:44 2017 -0700
Add deepyellow synonym for olive color.
+commit c71d3faf1bd0370b6ad3e464e2c0dbed934d15a6
+Author: Charles Staats III <charles.staats.iii@gmail.com>
+Date: Mon Dec 26 17:15:00 2016 -0500
+
+ Add graphwithderiv function
+
commit 1cc7f83d73cbe2ece3e7e4f0e7640b2ec5cbe684
Author: John Bowman <bowman@ualberta.ca>
Date: Sat Nov 26 10:56:46 2016 -0700
diff --git a/graphics/asymptote/EXRFiles.cc b/graphics/asymptote/EXRFiles.cc
new file mode 100644
index 0000000000..3f16f1edc9
--- /dev/null
+++ b/graphics/asymptote/EXRFiles.cc
@@ -0,0 +1,49 @@
+//
+// Created by jamie on 8/23/21.
+//
+
+#include "EXRFiles.h"
+#include "locate.h"
+
+namespace camp
+{
+using std::cout;
+using std::cerr;
+using std::endl;
+
+IEXRFile::IEXRFile(const string& File)
+{
+ char const* err;
+ int ret;
+ string file=settings::locateFile(File);
+ string image=settings::getSetting<string>("image");
+ if(file.empty()) {
+ cerr << "EXR file not found: " << File << endl
+ << "Precomputed image directories like ibl/" << image << " can be "
+ << "downloaded into the Asymptote search path like this:"
+ << endl << endl
+ << "wget -q --show-progress -nH -np -r --cut-dirs=1 "
+ << settings::getSetting<string>("imageURL") << "/refl.exr" << endl
+ << "wget -q --show-progress -nH -np -r --cut-dirs=1 "
+ << settings::getSetting<string>("imageURL") << "/" << image
+ << endl;
+ exit(-1);
+ }
+ const char *filename=file.c_str();
+ if((ret=LoadEXR(&data,&width,&height,filename,&err)) != TINYEXR_SUCCESS)
+ {
+ cerr << "TinyEXR Error: " << err << " " << filename << endl;
+ FreeEXRErrorMessage(err);
+ exit(-1);
+ }
+}
+
+IEXRFile::~IEXRFile()
+{
+ if(data) {
+ free(data);
+ data=nullptr;
+ }
+}
+
+}
diff --git a/graphics/asymptote/EXRFiles.h b/graphics/asymptote/EXRFiles.h
new file mode 100644
index 0000000000..36bd8b9b57
--- /dev/null
+++ b/graphics/asymptote/EXRFiles.h
@@ -0,0 +1,32 @@
+//
+// Created by jamie on 8/23/21.
+//
+
+#pragma once
+#include "common.h"
+#include "cudareflect/tinyexr/tinyexr.h"
+
+namespace camp
+{
+class IEXRFile
+{
+public:
+ IEXRFile(string const& file);
+ ~IEXRFile();
+
+ [[nodiscard]]
+ float const* getData() const {
+ return data;
+ }
+
+ [[nodiscard]]
+ std::pair<int,int> size() const {
+ return std::make_pair(width, height);
+ }
+
+private:
+ float* data=nullptr;
+ int width=0, height=0;
+};
+
+} // namespace gl;
diff --git a/graphics/asymptote/GLTextures.cc b/graphics/asymptote/GLTextures.cc
new file mode 100644
index 0000000000..81ab5faaee
--- /dev/null
+++ b/graphics/asymptote/GLTextures.cc
@@ -0,0 +1,48 @@
+//
+// Created by jamie on 8/23/21.
+//
+
+#include "GLTextures.h"
+
+#ifdef HAVE_GL
+
+namespace gl
+{
+
+#ifdef __CYGWIN__
+#define glDeleteTextures glDeleteTexturesEXT // Missing in 32-bit CYGWIN
+#endif
+
+AGLTexture::~AGLTexture()
+{
+ if (textureId != 0)
+ {
+ glDeleteTextures(1, &textureId);
+ }
+}
+
+AGLTexture& AGLTexture::operator=(AGLTexture&& glTex) noexcept
+{
+ textureId = glTex.textureId;
+ textureNumber = glTex.textureNumber;
+ glTex.textureId = 0;
+ glTex.textureNumber = -1;
+
+ return *this;
+}
+
+AGLTexture::AGLTexture(AGLTexture&& glTex) noexcept:
+ textureId(glTex.textureId), textureNumber(glTex.textureNumber)
+{
+}
+
+AGLTexture::AGLTexture(int textureNumber) : textureNumber(textureNumber) {}
+
+void AGLTexture::setActive() const
+{
+ glActiveTexture(GL_TEXTURE0+textureNumber);
+}
+
+} // namespace gl
+
+#endif
diff --git a/graphics/asymptote/GLTextures.h b/graphics/asymptote/GLTextures.h
new file mode 100644
index 0000000000..3b6bf11763
--- /dev/null
+++ b/graphics/asymptote/GLTextures.h
@@ -0,0 +1,127 @@
+//
+// Created by jamie on 8/23/21.
+//
+
+#pragma once
+#include "common.h"
+#include "GL/glew.h"
+
+namespace gl
+{
+struct GLTexturesFmt
+{
+ GLint minFilter=GL_LINEAR_MIPMAP_LINEAR;
+ GLint magFilter=GL_LINEAR;
+ GLint wrapS=GL_REPEAT;
+ GLint wrapT=GL_REPEAT;
+ GLint wrapR=GL_REPEAT;
+
+ GLuint format=GL_RGBA;
+ GLuint internalFmt=GL_RGBA;
+};
+
+class AGLTexture
+{
+protected:
+ AGLTexture() = default;
+ explicit AGLTexture(int textureNumber);
+
+ AGLTexture(AGLTexture const&) = delete;
+ AGLTexture& operator=(AGLTexture const&) = delete;
+
+ AGLTexture(AGLTexture&& glTex) noexcept;
+ AGLTexture& operator=(AGLTexture&& glTex) noexcept;
+
+public:
+ virtual ~AGLTexture();
+ void setActive() const;
+ virtual void setUniform(GLint uniformNumber) const = 0;
+
+protected:
+ GLuint textureId=0;
+ int textureNumber=-1;
+};
+
+template<typename T=float, GLuint GLDataType=GL_FLOAT>
+class GLTexture2 : public AGLTexture
+{
+public:
+ GLTexture2() = default;
+ GLTexture2(GLTexture2 const& glTex)=delete;
+ GLTexture2& operator= (GLTexture2 const& glTex)=delete;
+
+ GLTexture2(GLTexture2&& glTex) noexcept: AGLTexture(std::move(glTex))
+ {
+ }
+
+ GLTexture2& operator=(GLTexture2&& glTex) noexcept
+ {
+ AGLTexture::operator=(std::move(glTex));
+ return *this;
+ }
+
+ GLTexture2(T const* data, std::pair<int, int> size,
+ int textureNumber, GLTexturesFmt const& fmt) : AGLTexture(textureNumber)
+ {
+ glGenTextures(1, &textureId);
+
+ glActiveTexture(GL_TEXTURE0+textureNumber);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, fmt.minFilter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, fmt.magFilter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, fmt.wrapS);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, fmt.wrapT);
+ glTexImage2D(GL_TEXTURE_2D, 0, fmt.internalFmt, size.first, size.second, 0,
+ fmt.format, GLDataType, data);
+ glGenerateMipmap(GL_TEXTURE_2D);
+ glActiveTexture(0);
+ }
+
+ void setUniform(GLint uniformNumber) const override
+ {
+ glActiveTexture(GL_TEXTURE0+textureNumber);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ glUniform1i(uniformNumber, textureNumber);
+ glActiveTexture(0);
+ }
+};
+
+template<typename T=float, GLuint GLDataType=GL_FLOAT>
+class GLTexture3 : public AGLTexture
+{
+public:
+ GLTexture3() = default;
+ GLTexture3(T const* data, std::tuple<int, int, int> size,
+ int textureNumber, GLTexturesFmt const& fmt) : AGLTexture(textureNumber)
+ {
+ int width=std::get<0>(size);
+ int height=std::get<1>(size);
+ int depth=std::get<2>(size);
+ glEnable(GL_TEXTURE_3D);
+
+ glGenTextures(1, &textureId);
+ glActiveTexture(GL_TEXTURE0+textureNumber);
+ glBindTexture(GL_TEXTURE_3D, textureId);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, fmt.wrapS);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, fmt.wrapT);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, fmt.wrapR);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, fmt.minFilter);
+ glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, fmt.magFilter);
+
+ glTexImage3D(GL_TEXTURE_3D, 0, fmt.internalFmt, width, height, depth, 0, fmt.format,
+ GLDataType, data);
+ glGenerateMipmap(GL_TEXTURE_3D);
+ glActiveTexture(0);
+ }
+
+ void setUniform(GLint uniformNumber) const override
+ {
+ glActiveTexture(GL_TEXTURE0+textureNumber);
+ glBindTexture(GL_TEXTURE_3D, textureId);
+ glUniform1i(uniformNumber, textureNumber);
+ glActiveTexture(0);
+ }
+};
+
+} // namespace gl
diff --git a/graphics/asymptote/GUI/CustMatTransform.py b/graphics/asymptote/GUI/CustMatTransform.py
index 563907fc50..0a66807d35 100644
--- a/graphics/asymptote/GUI/CustMatTransform.py
+++ b/graphics/asymptote/GUI/CustMatTransform.py
@@ -1,14 +1,14 @@
#!/usr/bin/env python3
-import PyQt5.QtWidgets as Qw
-import PyQt5.QtGui as Qg
-import PyQt5.QtCore as Qc
-import numpy as np
-import xasy2asy as x2a
+import PyQt5.QtWidgets as QtWidgets
+import PyQt5.QtGui as QtGui
+import PyQt5.QtCore as QtCore
+import numpy as numpy
+import xasy2asy as xasy2asy
from pyUIClass.custMatTransform import Ui_Dialog
-class CustMatTransform(Qw.QDialog):
+class CustMatTransform(QtWidgets.QDialog):
def __init__(self):
super().__init__()
self.ui = Ui_Dialog()
@@ -18,14 +18,14 @@ class CustMatTransform(Qw.QDialog):
self.ui.btnCancel.clicked.connect(self.reject)
self.ui.btnReset.clicked.connect(self.resetDialog)
- self.mainTransformation = Qg.QTransform()
+ self.mainTransformation = QtGui.QTransform()
self.mainTransformation.scale(1, -1)
self.matrixLineInputs = [
self.ui.lineMat00, self.ui.lineMat01, self.ui.lineMatTx,
self.ui.lineMat10, self.ui.lineMat11, self.ui.lineMatTy]
- validator = Qg.QDoubleValidator()
+ validator = QtGui.QDoubleValidator()
for lineInput in self.matrixLineInputs:
lineInput.setValidator(validator)
lineInput.textChanged.connect(self.handleUpdateText)
@@ -37,7 +37,7 @@ class CustMatTransform(Qw.QDialog):
def createCanvas(self):
self.canvSize = self.ui.imgPreview.size()
- self.previewPixmap = Qg.QPixmap(self.canvSize)
+ self.previewPixmap = QtGui.QPixmap(self.canvSize)
tx, ty = self.canvSize.width() / 2, self.canvSize.height() / 2
self.mainTransformation.translate(tx, -ty)
@@ -52,27 +52,27 @@ class CustMatTransform(Qw.QDialog):
def updatePreview(self):
self.previewPixmap.fill()
- canvas = Qg.QPainter(self.previewPixmap)
+ canvas = QtGui.QPainter(self.previewPixmap)
if not canvas.isActive():
return
canvas.setTransform(self.mainTransformation)
canvas.save()
- canvas.setPen(Qc.Qt.lightGray)
+ canvas.setPen(QtCore.Qt.lightGray)
self.drawBasicGrid(canvas)
- transform = x2a.asyTransform.fromNumpyMatrix(self.getTransformationMatrix())
+ transform = xasy2asy.asyTransform.fromNumpyMatrix(self.getTransformationMatrix())
canvTransform = transform.toQTransform()
canvas.setTransform(canvTransform, True)
- canvas.setPen(Qc.Qt.black)
+ canvas.setPen(QtCore.Qt.black)
if canvTransform.isInvertible():
self.drawBasicGrid(canvas, False)
if canvTransform.determinant() <= 0:
- canvas.setPen(Qc.Qt.red)
+ canvas.setPen(QtCore.Qt.red)
- canvas.drawRect(Qc.QRect(Qc.QPoint(0, 0), Qc.QSize(20, 20)))
+ canvas.drawRect(QtCore.QRect(QtCore.QPoint(0, 0), QtCore.QSize(20, 20)))
self.ui.imgPreview.setPixmap(self.previewPixmap)
@@ -86,17 +86,17 @@ class CustMatTransform(Qw.QDialog):
self.ui.lineMat11.setText('1')
def drawBasicGrid(self, canvas, grid=True):
- canvas.drawLine(Qc.QLine(-9999, 0, 9999, 0))
- canvas.drawLine(Qc.QLine(0, -9999, 0, 9999))
+ canvas.drawLine(QtCore.QLine(-9999, 0, 9999, 0))
+ canvas.drawLine(QtCore.QLine(0, -9999, 0, 9999))
fromIter, toIter = -7, 7
gridSize = 20
if grid:
for iterIndex in range(fromIter, toIter + 1):
- canvas.drawLine(Qc.QLine(-9999, iterIndex * gridSize, 9999, iterIndex * gridSize))
- canvas.drawLine(Qc.QLine(iterIndex * gridSize, -9999, iterIndex * gridSize, 9999))
+ canvas.drawLine(QtCore.QLine(-9999, iterIndex * gridSize, 9999, iterIndex * gridSize))
+ canvas.drawLine(QtCore.QLine(iterIndex * gridSize, -9999, iterIndex * gridSize, 9999))
def getTransformationMatrix(self):
rawMatrixNum = [float(lineInput.text()) for lineInput in self.matrixLineInputs]
rawMatrixNum.extend([0, 0, 1])
- return np.matrix(rawMatrixNum).reshape((3, 3))
+ return numpy.matrix(rawMatrixNum).reshape((3, 3))
diff --git a/graphics/asymptote/GUI/DebugFlags.py b/graphics/asymptote/GUI/DebugFlags.py
index 8a7eb4b282..c8f8af897a 100644
--- a/graphics/asymptote/GUI/DebugFlags.py
+++ b/graphics/asymptote/GUI/DebugFlags.py
@@ -1,6 +1,5 @@
#!/usr/bin/env python3
keepFiles = False
-printFoutTranscript = False
+printAsyTranscript = False
printDeconstTranscript = False
-forceRasterizationSVG = False
diff --git a/graphics/asymptote/GUI/GuidesManager.py b/graphics/asymptote/GUI/GuidesManager.py
index 5467843377..fd317439d4 100644
--- a/graphics/asymptote/GUI/GuidesManager.py
+++ b/graphics/asymptote/GUI/GuidesManager.py
@@ -1,18 +1,17 @@
#!/usr/bin/env python3
-import PyQt5.QtWidgets as Qw
-import PyQt5.QtGui as Qg
-import PyQt5.QtCore as Qc
-import numpy as np
+import PyQt5.QtGui as QtGui
+import PyQt5.QtCore as QtCore
+import numpy as numpy
class Guide:
def __init__(self, pen=None):
if pen is None:
- pen = Qg.QPen()
- assert isinstance(pen, Qg.QPen)
+ pen = QtGui.QPen()
+ assert isinstance(pen, QtGui.QPen)
self.pen = pen
def drawShape(self, pen):
- assert isinstance(pen, Qg.QPainter)
+ assert isinstance(pen, QtGui.QPainter)
pen.save()
pen.setPen(self.pen)
@@ -24,19 +23,19 @@ class LineGuide(Guide):
def drawShape(self, pen):
super().drawShape(pen)
- p1 = self.origin + (9999 * Qc.QPointF(np.cos(self.direction), np.sin(self.direction)))
- p2 = self.origin - (9999 * Qc.QPointF(np.cos(self.direction), np.sin(self.direction)))
- pen.drawLine(Qc.QLineF(p1, p2))
+ p1 = self.origin + (9999 * QtCore.QPointF(numpy.cos(self.direction), numpy.sin(self.direction)))
+ p2 = self.origin - (9999 * QtCore.QPointF(numpy.cos(self.direction), numpy.sin(self.direction)))
+ pen.drawLine(QtCore.QLineF(p1, p2))
pen.restore()
class ArcGuide(Guide):
@classmethod
def radTo16Deg(cls, radians):
- return int(round(np.rad2deg(radians) * 16))
+ return int(round(numpy.rad2deg(radians) * 16))
- def __init__(self, center=None, radius=1, startAng=0, endAng=(2*np.pi), pen=None):
+ def __init__(self, center=None, radius=1, startAng=0, endAng=(2*numpy.pi), pen=None):
if center is None:
- center = Qc.QPointF(0, 0)
+ center = QtCore.QPointF(0, 0)
super().__init__(pen)
self.center = center
self.radius = int(radius)
@@ -45,7 +44,7 @@ class ArcGuide(Guide):
def drawShape(self, pen):
super().drawShape(pen)
- assert isinstance(pen, Qg.QPainter)
+ assert isinstance(pen, QtGui.QPainter)
x, y = int(round(self.center.x())), int(round(self.center.y()))
pen.drawArc(x - self.radius, y - self.radius, 2 * self.radius, 2 * self.radius, ArcGuide.radTo16Deg(self.startAng),
-ArcGuide.radTo16Deg(self.endAng - self.startAng))
diff --git a/graphics/asymptote/GUI/InplaceAddObj.py b/graphics/asymptote/GUI/InplaceAddObj.py
index 132969dad1..9bacd5f51f 100644
--- a/graphics/asymptote/GUI/InplaceAddObj.py
+++ b/graphics/asymptote/GUI/InplaceAddObj.py
@@ -1,8 +1,8 @@
#!/usr/bin/env python3
-import PyQt5.QtCore as Qc
-import PyQt5.QtGui as Qg
-import xasy2asy as x2a
+import PyQt5.QtCore as QtCore
+import PyQt5.QtGui as QtGui
+import xasy2asy as xasy2asy
import PrimitiveShape
import math
@@ -11,9 +11,9 @@ import Widg_addPolyOpt
import Widg_addLabel
-class InplaceObjProcess(Qc.QObject):
- objectCreated = Qc.pyqtSignal(Qc.QObject)
- objectUpdated = Qc.pyqtSignal()
+class InplaceObjProcess(QtCore.QObject):
+ objectCreated = QtCore.pyqtSignal(QtCore.QObject)
+ objectUpdated = QtCore.pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
@@ -24,10 +24,10 @@ class InplaceObjProcess(Qc.QObject):
def active(self):
return self._active
- def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None):
raise NotImplementedError
- def mouseMove(self, pos, event: Qg.QMouseEvent):
+ def mouseMove(self, pos, event: QtGui.QMouseEvent):
raise NotImplementedError
def mouseRelease(self):
@@ -45,7 +45,7 @@ class InplaceObjProcess(Qc.QObject):
def getXasyObject(self):
raise NotImplementedError
- def postDrawPreview(self, canvas: Qg.QPainter):
+ def postDrawPreview(self, canvas: QtGui.QPainter):
pass
def createOptWidget(self, info):
@@ -55,10 +55,10 @@ class InplaceObjProcess(Qc.QObject):
class AddCircle(InplaceObjProcess):
def __init__(self, parent=None):
super().__init__(parent)
- self.center = Qc.QPointF(0, 0)
+ self.center = QtCore.QPointF(0, 0)
self.radius = 0
- def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None):
x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
self.radius = 0
self.center.setX(x)
@@ -75,9 +75,9 @@ class AddCircle(InplaceObjProcess):
def getPreview(self):
x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(self.center)
- boundRect = Qc.QRectF(x - self.radius, y - self.radius, 2 * self.radius, 2 * self.radius)
+ boundRect = QtCore.QRectF(x - self.radius, y - self.radius, 2 * self.radius, 2 * self.radius)
# because the internal image is flipped...
- newPath = Qg.QPainterPath()
+ newPath = QtGui.QPainterPath()
newPath.addEllipse(boundRect)
# newPath.addRect(boundRect)
return newPath
@@ -87,9 +87,9 @@ class AddCircle(InplaceObjProcess):
def getXasyObject(self):
if self.fill:
- newObj = x2a.xasyFilledShape(self.getObject(), None)
+ newObj = xasy2asy.xasyFilledShape(self.getObject(), None)
else:
- newObj = x2a.xasyShape(self.getObject(), None)
+ newObj = xasy2asy.xasyShape(self.getObject(), None)
return newObj
def forceFinalize(self):
@@ -102,8 +102,9 @@ class AddLabel(InplaceObjProcess):
self.alignMode = None
self.opt = None
self.text = None
- self.anchor = Qc.QPointF(0, 0)
+ self.anchor = QtCore.QPointF(0, 0)
self._active = False
+ self.fontSize = 12
def createOptWidget(self, info):
self.opt = Widg_addLabel.Widg_addLabel(info)
@@ -121,7 +122,7 @@ class AddLabel(InplaceObjProcess):
self.anchor.setX(x)
self.anchor.setY(y)
- def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None):
if self.opt is not None:
self.text = self.opt.labelText
x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
@@ -140,7 +141,7 @@ class AddLabel(InplaceObjProcess):
text = self.text
align = str(self.alignMode)
anchor = PrimitiveShape.PrimitiveShape.pos_to_tuple(self.anchor)
- newLabel = x2a.xasyText(text=text, location=anchor, pen=None,
+ newLabel = xasy2asy.xasyText(text=text, location=anchor, pen=None,
align=align, asyengine=None, fontsize=self.fontSize)
newLabel.asyfied = False
return newLabel
@@ -164,11 +165,11 @@ class AddBezierShape(InplaceObjProcess):
# Linkmode should be to the last point.
# (x, y, linkmode), (u, v, lm2) <==> (x, y) <=lm2=> (u, v)
self.pointsList = []
- self.currentPoint = Qc.QPointF(0, 0)
+ self.currentPoint = QtCore.QPointF(0, 0)
self.pendingPoint = None
self.useLegacy = False
- def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None):
x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
self.currentPoint.setX(x)
self.currentPoint.setY(y)
@@ -222,7 +223,7 @@ class AddBezierShape(InplaceObjProcess):
# self.updateBasePath()
def updateBasePath(self):
- self.basePath = x2a.asyPath(asyengine=self.asyengine, forceCurve=self.useBezierBase)
+ self.basePath = xasy2asy.asyPath(asyengine=self.asyengine, forceCurve=self.useBezierBase)
newNode = [(x, y) for x, y, _ in self.pointsList]
newLink = [lnk for *args, lnk in self.pointsList[1:]]
if self.useLegacy:
@@ -237,7 +238,7 @@ class AddBezierShape(InplaceObjProcess):
self.basePath.computeControls()
def updateBasePathPreview(self):
- self.basePathPreview = x2a.asyPath(
+ self.basePathPreview = xasy2asy.asyPath(
asyengine=self.asyengine, forceCurve=self.useBezierBase)
newNode = [(x, y) for x, y, _ in self.pointsList] + [(self.currentPoint.x(), self.currentPoint.y())]
newLink = [lnk for *args, lnk in self.pointsList[1:]] + [self._getLinkType()]
@@ -271,16 +272,16 @@ class AddBezierShape(InplaceObjProcess):
def getXasyObject(self):
if self.fill:
- return x2a.xasyFilledShape(self.getObject(), None)
+ return xasy2asy.xasyFilledShape(self.getObject(), None)
else:
- return x2a.xasyShape(self.getObject(), None)
+ return xasy2asy.xasyShape(self.getObject(), None)
class AddPoly(InplaceObjProcess):
def __init__(self, parent=None):
super().__init__(parent)
- self.center = Qc.QPointF(0, 0)
- self.currPos = Qc.QPointF(0, 0)
+ self.center = QtCore.QPointF(0, 0)
+ self.currPos = QtCore.QPointF(0, 0)
self.sides = None
self.inscribed = None
self.centermode = None
@@ -288,18 +289,18 @@ class AddPoly(InplaceObjProcess):
self.fill = None
self.opt = None
- def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None):
self._active = True
self.sides = info['sides']
self.inscribed = info['inscribed']
self.centermode = info['centermode']
self.fill = info['fill']
-
+
x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
self.center.setX(x)
self.center.setY(y)
- self.currPos = Qc.QPointF(self.center)
+ self.currPos = QtCore.QPointF(self.center)
def mouseMove(self, pos, event):
x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
@@ -329,7 +330,7 @@ class AddPoly(InplaceObjProcess):
else:
poly = PrimitiveShape.PrimitiveShape.exscribedRegPolygon(self.sides, self.center, self._rad(),
self._angle(), qpoly=True)
- newPath = Qg.QPainterPath()
+ newPath = QtGui.QPainterPath()
newPath.addPolygon(poly)
return newPath
@@ -350,7 +351,121 @@ class AddPoly(InplaceObjProcess):
def getXasyObject(self):
if self.fill:
- newObj = x2a.xasyFilledShape(self.getObject(), None)
+ newObj = xasy2asy.xasyFilledShape(self.getObject(), None)
else:
- newObj = x2a.xasyShape(self.getObject(), None)
+ newObj = xasy2asy.xasyShape(self.getObject(), None)
return newObj
+
+class AddFreehand(InplaceObjProcess):
+ # TODO: At the moment this is just a copy-paste of the AddBezierObj.
+ # Must find a better algorithm for constructing the obj rather than
+ # a node for every pixel the mouse moves.
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.asyengine = None
+ self.basePath = None
+ self.basePathPreview = None
+ self.closedPath = None
+ self.info = None
+ self.fill = False
+ self.opt = None
+
+ # list of "committed" points with Linkage information.
+ # Linkmode should be to the last point.
+ # (x, y, linkmode), (u, v, lm2) <==> (x, y) <=lm2=> (u, v)
+ self.pointsList = []
+ self.currentPoint = QtCore.QPointF(0, 0)
+ self.pendingPoint = None
+ self.useLegacy = False
+
+ def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None):
+ x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
+ self.currentPoint.setX(x)
+ self.currentPoint.setY(y)
+ self.info = info
+
+ if not self._active:
+ self._active = True
+ self.fill = info['fill']
+ self.asyengine = info['asyengine']
+ self.closedPath = info['closedPath']
+ self.useBezierBase = info['useBezier']
+ self.useLegacy = self.info['options']['useLegacyDrawMode']
+ self.pointsList.clear()
+ self.pointsList.append((x, y, None))
+ else:
+ # see http://doc.qt.io/archives/qt-4.8/qt.html#MouseButton-enum
+ if (int(mouseEvent.buttons()) if mouseEvent is not None else 0) & 0x2 and self.useLegacy:
+ self.forceFinalize()
+
+ def _getLinkType(self):
+ if self.info['useBezier']:
+ return '..'
+ else:
+ return '--'
+
+ def mouseMove(self, pos, event):
+ # in postscript coords.
+ if self._active:
+ x, y = PrimitiveShape.PrimitiveShape.pos_to_tuple(pos)
+
+ if self.useLegacy or int(event.buttons()) != 0:
+ self.currentPoint.setX(x)
+ self.currentPoint.setY(y)
+ self.pointsList.append((x, y, self._getLinkType()))
+
+
+ def createOptWidget(self, info):
+ return None
+
+ def mouseRelease(self):
+ self.updateBasePath()
+ self._active = False
+ self.pointsList.clear()
+ self.objectCreated.emit(self.getXasyObject())
+ self.basePath = None
+
+ def updateBasePath(self):
+ self.basePath = xasy2asy.asyPath(asyengine=self.asyengine, forceCurve=self.useBezierBase)
+ newNode = [(x, y) for x, y, _ in self.pointsList]
+ newLink = [lnk for *args, lnk in self.pointsList[1:]]
+ if self.useLegacy:
+ newNode += [(self.currentPoint.x(), self.currentPoint.y())]
+ newLink += [self._getLinkType()]
+ if self.closedPath:
+ newNode.append('cycle')
+ newLink.append(self._getLinkType())
+ self.basePath.initFromNodeList(newNode, newLink)
+
+ if self.useBezierBase:
+ self.basePath.computeControls()
+
+ def updateBasePathPreview(self):
+ self.basePathPreview = xasy2asy.asyPath(
+ asyengine=self.asyengine, forceCurve=self.useBezierBase)
+ newNode = [(x, y) for x, y, _ in self.pointsList] + [(self.currentPoint.x(), self.currentPoint.y())]
+ newLink = [lnk for *args, lnk in self.pointsList[1:]] + [self._getLinkType()]
+ if self.closedPath:
+ newNode.append('cycle')
+ newLink.append(self._getLinkType())
+ self.basePathPreview.initFromNodeList(newNode, newLink)
+
+ if self.useBezierBase:
+ self.basePathPreview.computeControls()
+
+ def getObject(self):
+ if self.basePath is None:
+ raise RuntimeError('BasePath is None')
+ self.basePath.asyengine = self.asyengine
+ return self.basePath
+
+ def getPreview(self):
+ if self._active:
+ if self.pointsList:
+ self.updateBasePathPreview()
+ newPath = self.basePathPreview.toQPainterPath()
+ return newPath
+
+ def getXasyObject(self):
+ self.fill = False
+ return xasy2asy.xasyShape(self.getObject(), None)
diff --git a/graphics/asymptote/GUI/PrimitiveShape.py b/graphics/asymptote/GUI/PrimitiveShape.py
index c75e014079..bbb2414866 100644
--- a/graphics/asymptote/GUI/PrimitiveShape.py
+++ b/graphics/asymptote/GUI/PrimitiveShape.py
@@ -1,10 +1,10 @@
#!/usr/bin/env python3
-import xasy2asy as x2a
-import numpy as np
+import xasy2asy as xasy2asy
+import numpy as numpy
import math
-import PyQt5.QtCore as Qc
-import PyQt5.QtGui as Qg
+import PyQt5.QtCore as QtCore
+import PyQt5.QtGui as QtGui
class PrimitiveShape:
@@ -14,9 +14,9 @@ class PrimitiveShape:
@staticmethod
def pos_to_tuple(pos):
- if isinstance(pos, tuple) or isinstance(pos, np.ndarray):
+ if isinstance(pos, tuple) or isinstance(pos, numpy.ndarray):
return pos
- elif isinstance(pos, Qc.QPoint) or isinstance(pos, Qc.QPointF):
+ elif isinstance(pos, QtCore.QPoint) or isinstance(pos, QtCore.QPointF):
return pos.x(), pos.y()
else:
raise TypeError("Position must be a valid type!")
@@ -32,7 +32,7 @@ class PrimitiveShape:
@classmethod
def circle(cls, position, radius):
pos_x, pos_y = PrimitiveShape.pos_to_tuple(position)
- newCircle = x2a.asyPath()
+ newCircle = xasy2asy.asyPath()
ptsList = [(pos_x + radius, pos_y), (pos_x, pos_y + radius), (pos_x - radius, pos_y), (pos_x, pos_y - radius),
'cycle']
# cycle doesn't work for now.
@@ -45,16 +45,16 @@ class PrimitiveShape:
pos_x, pos_y = PrimitiveShape.pos_to_tuple(position)
lkList = ['--'] * sides
ptsList = []
- for ang in np.linspace(starting_rad, starting_rad + math.tau, sides, endpoint=False):
+ for ang in numpy.linspace(starting_rad, starting_rad + math.tau, sides, endpoint=False):
ptsList.append((pos_x + radius * math.cos(ang), pos_y + radius * math.sin(ang)))
if qpoly:
ptsList.append((pos_x + radius * math.cos(starting_rad), pos_y + radius * math.sin(starting_rad)))
- qpoints = [Qc.QPointF(x, y) for (x, y) in ptsList]
- return Qg.QPolygonF(qpoints)
+ qpoints = [QtCore.QPointF(x, y) for (x, y) in ptsList]
+ return QtGui.QPolygonF(qpoints)
else:
ptsList.append('cycle')
- newPoly = x2a.asyPath()
+ newPoly = xasy2asy.asyPath()
newPoly.initFromNodeList(ptsList, lkList)
return newPoly
diff --git a/graphics/asymptote/GUI/SetCustomAnchor.py b/graphics/asymptote/GUI/SetCustomAnchor.py
index ad5925cddb..e4414fecc4 100644
--- a/graphics/asymptote/GUI/SetCustomAnchor.py
+++ b/graphics/asymptote/GUI/SetCustomAnchor.py
@@ -1,20 +1,20 @@
#!/usr/bin/env python3
-import PyQt5.QtWidgets as Qw
-import PyQt5.QtGui as Qg
-import PyQt5.QtCore as Qc
+import PyQt5.QtWidgets as QtWidgets
+import PyQt5.QtGui as QtGui
+import PyQt5.QtCore as QtCore
from pyUIClass.setCustomAnchor import Ui_Dialog
-class CustomAnchorDialog(Qw.QDialog):
+class CustomAnchorDialog(QtWidgets.QDialog):
def __init__(self):
super().__init__()
self.ui = Ui_Dialog()
self.ui.setupUi(self)
- self.ui.buttonBox.button(Qw.QDialogButtonBox.Reset).clicked.connect(self.resetDialog)
+ self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Reset).clicked.connect(self.resetDialog)
- validator = Qg.QDoubleValidator()
+ validator = QtGui.QDoubleValidator()
self.ui.lineEditX.setValidator(validator)
self.ui.lineEditY.setValidator(validator)
@@ -24,18 +24,18 @@ class CustomAnchorDialog(Qw.QDialog):
def checkTextChanged(self, text):
if str(text) not in {'.', '-', '.-', '-.'} and str(text):
- self.ui.buttonBox.button(Qw.QDialogButtonBox.Ok).setEnabled(True)
+ self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(True)
else:
- self.ui.buttonBox.button(Qw.QDialogButtonBox.Ok).setEnabled(False)
+ self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(False)
def getPoint(self):
xPoint = float(self.ui.lineEditX.text())
yPoint = float(self.ui.lineEditY.text())
- return Qc.QPointF(xPoint, yPoint)
+ return QtCore.QPointF(xPoint, yPoint)
def handleBtnBoxClick(self, button):
- assert isinstance(button, Qw.QAbstractButton)
+ assert isinstance(button, QtWidgets.QAbstractButton)
if button.text() == 'Reset':
self.resetDialog()
diff --git a/graphics/asymptote/GUI/Widg_addLabel.py b/graphics/asymptote/GUI/Widg_addLabel.py
index 776d3e02df..a5a6503503 100644
--- a/graphics/asymptote/GUI/Widg_addLabel.py
+++ b/graphics/asymptote/GUI/Widg_addLabel.py
@@ -1,14 +1,14 @@
#!/usr/bin/env python3
from pyUIClass.widg_addLabel import Ui_Form
-import PyQt5.QtWidgets as Qw
-import PyQt5.QtGui as Qg
+import PyQt5.QtWidgets as QtWidgets
+import PyQt5.QtGui as QtGui
import labelEditor
import xasyUtils as xu
-class Widg_addLabel(Qw.QWidget):
+class Widg_addLabel(QtWidgets.QWidget):
def __init__(self, info):
super().__init__()
self.ui = Ui_Form()
@@ -34,11 +34,11 @@ class Widg_addLabel(Qw.QWidget):
if self.info['shift_y'] is not None:
self.ui.txtShiftY.setText(str(self.info['shift_y']))
-
+
self.ui.cmbFontSize.setCurrentText(str(self.info['fontSize']) if self.info['fontSize'] is not None else '-')
self.ui.cmbAlign.setCurrentIndex(self.info['alignIndex'])
- validator = Qg.QDoubleValidator()
+ validator = QtGui.QDoubleValidator()
self.ui.txtShiftX.setValidator(validator)
self.ui.txtShiftY.setValidator(validator)
@@ -53,7 +53,7 @@ class Widg_addLabel(Qw.QWidget):
self.updateCheck(self.ui.cmbAlign.currentText())
- def cmbFontSizeTextChanged(self, text: str):
+ def cmbFontSizeTextChanged(self, text: str):
tryParseVal = xu.tryParse(text, float)
self.info['fontSize'] = tryParseVal
@@ -61,7 +61,7 @@ class Widg_addLabel(Qw.QWidget):
advancedEditDialog = labelEditor.labelEditor(self.ui.txtLabelText.text())
advancedEditDialog.show()
result = advancedEditDialog.exec_()
- if result == Qw.QDialog.Accepted:
+ if result == QtWidgets.QDialog.Accepted:
self.ui.txtLabelText.setText(advancedEditDialog.getText())
@property
diff --git a/graphics/asymptote/GUI/Widg_addPolyOpt.py b/graphics/asymptote/GUI/Widg_addPolyOpt.py
index b9b9a77f7a..3d1e419d89 100644
--- a/graphics/asymptote/GUI/Widg_addPolyOpt.py
+++ b/graphics/asymptote/GUI/Widg_addPolyOpt.py
@@ -1,14 +1,13 @@
#!/usr/bin/env python3
from pyUIClass.widg_addPolyOpt import Ui_Form
-import PyQt5.QtWidgets as Qw
-import PyQt5.QtGui as Qg
-import PyQt5.QtCore as Qc
+import PyQt5.QtWidgets as QtWidgets
+import PyQt5.QtGui as QtGui
import sys
-class Widg_addPolyOpt(Qw.QWidget):
+class Widg_addPolyOpt(QtWidgets.QWidget):
def __init__(self, info):
super().__init__()
self.ui = Ui_Form()
@@ -18,7 +17,7 @@ class Widg_addPolyOpt(Qw.QWidget):
self.ui.chkInscribed.setChecked(self.info['inscribed'])
self.ui.txtSides.setText(str(self.info['sides']))
- self.ui.txtSides.setValidator(Qg.QIntValidator())
+ self.ui.txtSides.setValidator(QtGui.QIntValidator())
self.ui.chkInscribed.stateChanged.connect(self.chkInscribedUpdate)
self.ui.txtSides.textChanged.connect(self.txtSidesUpdate)
diff --git a/graphics/asymptote/GUI/Widg_editBezier.py b/graphics/asymptote/GUI/Widg_editBezier.py
index 3a3cbab94a..161715e0fc 100644
--- a/graphics/asymptote/GUI/Widg_editBezier.py
+++ b/graphics/asymptote/GUI/Widg_editBezier.py
@@ -2,16 +2,15 @@
from pyUIClass.widg_editBezier import Ui_Form
-import PyQt5.QtCore as Qc
-import PyQt5.QtWidgets as Qw
-import PyQt5.QtGui as Qg
+import PyQt5.QtWidgets as QtWidgets
+import PyQt5.QtCore as QtCore
class LockMode:
noLock = 0
angleLock = 1
angleAndScaleLock = 2
-class Widg_editBezier(Qw.QWidget):
+class Widg_editBezier(QtWidgets.QWidget):
def __init__(self, info: dict, enableCurveFeatures: bool=True):
super().__init__()
self.ui = Ui_Form()
@@ -38,16 +37,16 @@ class Widg_editBezier(Qw.QWidget):
def lockMode(self) -> int:
return self.ui.cmbLockMode.currentIndex()
- @Qc.pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def cmbLockIndexChange(self, index: int):
self.info['editBezierlockMode'] = index
- @Qc.pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def chkRecomputeChanged(self, checked: int):
isChecked = (checked == 2)
for obj in self.disableOnAutoRecompute:
obj.setEnabled(not checked)
self.info['autoRecompute'] = checked
-
+
if isChecked:
self.ui.btnForceRecompute.clicked.emit()
diff --git a/graphics/asymptote/GUI/Window1.py b/graphics/asymptote/GUI/Window1.py
index 1f7b67b1fa..134d3cd196 100644
--- a/graphics/asymptote/GUI/Window1.py
+++ b/graphics/asymptote/GUI/Window1.py
@@ -18,6 +18,7 @@ import tempfile
import datetime
import string
import atexit
+import pickle
import xasyUtils as xu
import xasy2asy as x2a
@@ -50,7 +51,6 @@ class TransformationChanges(ActionChanges):
self.transformation = transformation
self.isLocal = isLocal
-
class ObjCreationChanges(ActionChanges):
def __init__(self, obj):
self.object = obj
@@ -60,6 +60,18 @@ class HardDeletionChanges(ActionChanges):
self.item = obj
self.objIndex = pos
+class SoftDeletionChanges(ActionChanges):
+ def __init__(self, obj, keyPos):
+ self.item = obj
+ self.keyMap = keyPos
+
+class EditBezierChanges(ActionChanges):
+ def __init__(self, obj, pos, oldPath, newPath):
+ self.item = obj
+ self.objIndex = pos
+ self.oldPath = oldPath
+ self.newPath = newPath
+
class AnchorMode:
center = 0
origin = 1
@@ -68,7 +80,7 @@ class AnchorMode:
bottomRight = 4
bottomLeft = 5
customAnchor = 6
-
+
class GridMode:
cartesian = 0
@@ -84,6 +96,14 @@ class SelectionMode:
delete = 5
setAnchor = 6
selectEdit = 7
+ openPoly = 8
+ closedPoly = 9
+ openCurve = 10
+ closedCurve = 11
+ addPoly = 12
+ addCircle = 13
+ addLabel = 14
+ addFreehand = 15
class AddObjectMode:
Circle = 0
@@ -92,14 +112,15 @@ class AddObjectMode:
class MainWindow1(Qw.QMainWindow):
defaultFrameStyle = """
- QFrame{{
+ QFrame{{
padding: 4.0;
- border-radius: 3.0;
+ border-radius: 3.0;
background: rgb({0}, {1}, {2})
}}
"""
def __init__(self):
+ self.testingActions = []
super().__init__()
self.ui = Ui_MainWindow()
global devicePixelRatio
@@ -109,12 +130,13 @@ class MainWindow1(Qw.QMainWindow):
self.settings = xo.BasicConfigs.defaultOpt
self.keyMaps = xo.BasicConfigs.keymaps
+ self.openRecent = xo.BasicConfigs.openRecent
self.raw_args = Qc.QCoreApplication.arguments()
self.args = xa.parseArgs(self.raw_args)
self.strings = xs.xasyString(self.args.language)
- self.asy2psmap = x2a.identity()
+ self.asy2psmap = x2a.yflip()
if self.settings['asyBaseLocation'] is not None:
os.environ['ASYMPTOTE_DIR'] = self.settings['asyBaseLocation']
@@ -134,7 +156,8 @@ class MainWindow1(Qw.QMainWindow):
# For initialization purposes
self.canvSize = Qc.QSize()
- self.filename = None
+ self.fileName = None
+ self.asyFileName = None
self.currDir = None
self.mainCanvas = None
self.dpi = 300
@@ -165,9 +188,9 @@ class MainWindow1(Qw.QMainWindow):
self.inMidTransformation = False
self.addMode = None
self.currentlySelectedObj = {'key': None, 'allSameKey': set(), 'selectedIndex': None, 'keyIndex': None}
- self.pendingSelectedObjList = []
+ self.pendingSelectedObjList = []
self.pendingSelectedObjIndex = -1
-
+
self.savedMousePosition = None
self.currentBoundingBox = None
self.selectionDelta = None
@@ -177,9 +200,12 @@ class MainWindow1(Qw.QMainWindow):
self.scaleFactor = 1
self.panOffset = [0, 0]
+ # Keyboard can focus outside of textboxes
+ self.setFocusPolicy(Qc.Qt.StrongFocus)
+
super().setMouseTracking(True)
# setMouseTracking(True)
-
+
self.undoRedoStack = Urs.actionStack()
self.lockX = False
@@ -211,8 +237,10 @@ class MainWindow1(Qw.QMainWindow):
self.modeButtons = {
self.ui.btnTranslate, self.ui.btnRotate, self.ui.btnScale, # self.ui.btnSelect,
- self.ui.btnPan, self.ui.btnDeleteMode, self.ui.btnAnchor,
- self.ui.btnSelectEdit
+ self.ui.btnPan, self.ui.btnDeleteMode, self.ui.btnAnchor,
+ self.ui.btnSelectEdit, self.ui.btnOpenPoly, self.ui.btnClosedPoly,
+ self.ui.btnOpenCurve, self.ui.btnClosedCurve, self.ui.btnAddPoly,
+ self.ui.btnAddCircle, self.ui.btnAddLabel, self.ui.btnAddFreehand
}
self.objButtons = {self.ui.btnCustTransform, self.ui.actionTransform, self.ui.btnSendForwards,
@@ -225,17 +253,17 @@ class MainWindow1(Qw.QMainWindow):
self.currAddOptionsWgt = None
self.currAddOptions = {
- 'options': self.settings,
+ 'options': self.settings,
'inscribed': True,
'sides': 3,
'centermode': True,
- 'fontSize': None,
+ 'fontSize': None,
'asyengine': self.asyEngine,
'fill': self.ui.btnFill.isChecked(),
'closedPath': False,
- 'useBezier': True,
+ 'useBezier': True,
'magnification': self.magnification,
- 'editBezierlockMode': xbi.Web.LockMode.angleLock,
+ 'editBezierlockMode': xbi.Web.LockMode.angleLock,
'autoRecompute': False
}
@@ -249,7 +277,7 @@ class MainWindow1(Qw.QMainWindow):
# commands switchboard
self.commandsFunc = {
- 'quit': Qc.QCoreApplication.quit,
+ 'quit': self.btnCloseFileonClick,
'undo': self.btnUndoOnClick,
'redo': self.btnRedoOnClick,
'manual': self.actionManual,
@@ -261,10 +289,10 @@ class MainWindow1(Qw.QMainWindow):
'commandPalette': self.enterCustomCommand,
'clearGuide': self.clearGuides,
'finalizeAddObj': self.finalizeAddObj,
- 'finalizeCurve': self.finalizeCurve,
- 'finalizeCurveClosed': self.finalizeCurveClosed,
+ 'finalizeCurve': self.finalizeCurve,
+ 'finalizeCurveClosed': self.finalizeCurveClosed,
'setMag': self.setMagPrompt,
- 'deleteObject': self.btnSelectiveDeleteOnClick,
+ 'deleteObject': self.btnSelectiveDeleteOnClick,
'anchorMode': self.switchToAnchorMode,
'moveUp': lambda: self.translate(0, -1),
'moveDown': lambda: self.translate(0, 1),
@@ -274,10 +302,17 @@ class MainWindow1(Qw.QMainWindow):
'scrollLeft': lambda: self.arrowButtons(-1, 0, True),
'scrollRight': lambda: self.arrowButtons(1, 0, True),
'scrollUp': lambda: self.arrowButtons(0, 1, True),
- 'scrollDown': lambda: self.arrowButtons(0, -1, True),
+ 'scrollDown': lambda: self.arrowButtons(0, -1, True),
+
+ 'zoomIn': lambda: self.arrowButtons(0, 1, False, True),
+ 'zoomOut': lambda: self.arrowButtons(0, -1, False, True),
+
+ 'open': self.btnLoadFileonClick,
+ 'save': self.actionSave,
+ 'export': self.btnExportAsymptoteOnClick,
- 'zoomIn': lambda: self.arrowButtons(0, 1, False, True),
- 'zoomOut': lambda: self.arrowButtons(0, -1, False, True)
+ 'copy': self.copyItem,
+ 'paste': self.pasteItem
}
self.hiddenKeys = set()
@@ -291,6 +326,7 @@ class MainWindow1(Qw.QMainWindow):
# from xasyoptions config file
self.loadKeyMaps()
self.setupXasyOptions()
+ self.populateOpenRecent()
self.colorDialog = Qw.QColorDialog(x2a.asyPen.convertToQColor(self._currentPen.color), self)
self.initPenInterface()
@@ -320,7 +356,7 @@ class MainWindow1(Qw.QMainWindow):
def getScrsTransform(self):
# pipeline:
# assuming origin <==> top left
- # (Pan) * (Translate) * (Flip the images) * (Zoom) * (Obj transform) * (Base Information)
+ # (Pan) * (Translate) * (Flip the images) * (Zoom) * (Obj transform) * (Base Information)
# pipeline --> let x, y be the postscript point
# p = (mx + cx + panoffset, -ny + cy + panoffset)
@@ -366,6 +402,12 @@ class MainWindow1(Qw.QMainWindow):
self.settings.load()
self.quickUpdate()
+ def openAndReloadKeymaps(self):
+ keymapsFile = self.keyMaps.settingsFileLocation()
+ subprocess.run(args=self.getExternalEditor(asypath=keymapsFile))
+ self.settings.load()
+ self.quickUpdate()
+
def setMagPrompt(self):
commandText, result = Qw.QInputDialog.getText(self, '', 'Enter magnification:')
if result:
@@ -373,6 +415,11 @@ class MainWindow1(Qw.QMainWindow):
self.currAddOptions['magnification'] = self.magnification
self.quickUpdate()
+ def setTextPrompt(self):
+ commandText, result = Qw.QInputDialog.getText(self, '', 'Enter new text:')
+ if result:
+ return commandText
+
def btnTogglePythonOnClick(self, checked):
self.terminalPythonMode = checked
@@ -381,7 +428,10 @@ class MainWindow1(Qw.QMainWindow):
def handleArguments(self):
if self.args.filename is not None:
- self.loadFile(self.args.filename)
+ if os.path.exists(self.args.filename):
+ self.actionOpen(os.path.abspath(self.args.filename))
+ else:
+ self.loadFile(self.args.filename)
else:
self.initializeEmptyFile()
@@ -417,14 +467,18 @@ class MainWindow1(Qw.QMainWindow):
self.ui.actionRedo.triggered.connect(lambda: self.execCustomCommand('redo'))
self.ui.actionTransform.triggered.connect(lambda: self.execCustomCommand('transform'))
+ self.ui.actionNewFile.triggered.connect(self.actionNewFile)
self.ui.actionOpen.triggered.connect(self.actionOpen)
+ self.ui.actionClearRecent.triggered.connect(self.actionClearRecent)
self.ui.actionSave.triggered.connect(self.actionSave)
self.ui.actionSaveAs.triggered.connect(self.actionSaveAs)
self.ui.actionManual.triggered.connect(self.actionManual)
self.ui.actionAbout.triggered.connect(self.actionAbout)
self.ui.actionSettings.triggered.connect(self.openAndReloadSettings)
+ self.ui.actionKeymaps.triggered.connect(self.openAndReloadKeymaps)
self.ui.actionEnterCommand.triggered.connect(self.enterCustomCommand)
- self.ui.actionExportAsymptote.triggered.connect(self.btnExportAsyOnClick)
+ self.ui.actionExportAsymptote.triggered.connect(self.btnExportAsymptoteOnClick)
+ self.ui.actionExportToAsy.triggered.connect(self.btnExportToAsyOnClick)
def setupXasyOptions(self):
if self.settings['debugMode']:
@@ -443,7 +497,7 @@ class MainWindow1(Qw.QMainWindow):
self.ui.btnSave.clicked.connect(self.btnSaveonClick)
self.ui.btnQuickScreenshot.clicked.connect(self.btnQuickScreenshotOnClick)
- # self.ui.btnExportAsy.clicked.connect(self.btnExportAsyOnClick)
+ # self.ui.btnExportAsy.clicked.connect(self.btnExportAsymptoteOnClick)
self.ui.btnDrawAxes.clicked.connect(self.btnDrawAxesOnClick)
# self.ui.btnAsyfy.clicked.connect(lambda: self.asyfyCanvas(True))
@@ -467,7 +521,7 @@ class MainWindow1(Qw.QMainWindow):
self.ui.btnAnchor.clicked.connect(self.btnAnchorModeOnClick)
self.ui.btnSelectColor.clicked.connect(self.btnColorSelectOnClick)
- self.ui.txtLineWidth.textEdited.connect(self.txtLineWithEdited)
+ self.ui.txtLineWidth.textEdited.connect(self.txtLineWidthEdited)
# self.ui.btnCreateCurve.clicked.connect(self.btnCreateCurveOnClick)
self.ui.btnDrawGrid.clicked.connect(self.btnDrawGridOnClick)
@@ -475,6 +529,7 @@ class MainWindow1(Qw.QMainWindow):
self.ui.btnAddCircle.clicked.connect(self.btnAddCircleOnClick)
self.ui.btnAddPoly.clicked.connect(self.btnAddPolyOnClick)
self.ui.btnAddLabel.clicked.connect(self.btnAddLabelOnClick)
+ self.ui.btnAddFreehand.clicked.connect(self.btnAddFreehandOnClick)
# self.ui.btnAddBezierInplace.clicked.connect(self.btnAddBezierInplaceOnClick)
self.ui.btnClosedCurve.clicked.connect(self.btnAddClosedCurveOnClick)
self.ui.btnOpenCurve.clicked.connect(self.btnAddOpenCurveOnClick)
@@ -489,16 +544,19 @@ class MainWindow1(Qw.QMainWindow):
self.ui.btnDeleteMode.clicked.connect(self.btnDeleteModeOnClick)
# self.ui.btnSoftDelete.clicked.connect(self.btnSoftDeleteOnClick)
self.ui.btnToggleVisible.clicked.connect(self.btnSetVisibilityOnClick)
-
+
self.ui.btnEnterCommand.clicked.connect(self.btnTerminalCommandOnClick)
self.ui.btnTogglePython.clicked.connect(self.btnTogglePythonOnClick)
self.ui.btnSelectEdit.clicked.connect(self.btnSelectEditOnClick)
def btnDeleteModeOnClick(self):
- self.currentModeStack = [SelectionMode.delete]
- self.ui.statusbar.showMessage('Delete Mode')
- self.clearSelection()
- self.updateChecks()
+ if self.currentModeStack[-1] != SelectionMode.delete:
+ self.currentModeStack = [SelectionMode.delete]
+ self.ui.statusbar.showMessage('Delete mode')
+ self.clearSelection()
+ self.updateChecks()
+ else:
+ self.btnTranslateonClick()
def btnTerminalCommandOnClick(self):
if self.terminalPythonMode:
@@ -507,18 +565,25 @@ class MainWindow1(Qw.QMainWindow):
else:
pass
# TODO: How to handle this case?
- # Like AutoCAD?
+ # Like AutoCAD?
self.ui.txtTerminalPrompt.clear()
- def btnFillOnClick(self, checked):
+ def btnFillOnClick(self, checked):
+ if self.currentModeStack == [SelectionMode.selectEdit]:
+ if isinstance(self.addMode,xbi.InteractiveBezierEditor):
+ self.addMode.swapObjFill() #Check for crashes
self.currAddOptions['fill'] = checked
self.ui.btnOpenCurve.setEnabled(not checked)
self.ui.btnOpenPoly.setEnabled(not checked)
def btnSelectEditOnClick(self):
- self.ui.statusbar.showMessage('Edit mode')
- self.currentModeStack = [SelectionMode.selectEdit]
- self.updateChecks()
+ if self.currentModeStack[-1] != SelectionMode.selectEdit:
+ self.currentModeStack = [SelectionMode.selectEdit]
+ self.ui.statusbar.showMessage('Edit mode')
+ self.clearSelection()
+ self.updateChecks()
+ else:
+ self.btnTranslateonClick()
@property
def currentPen(self):
@@ -544,7 +609,7 @@ class MainWindow1(Qw.QMainWindow):
except Exception:
pass
- self.currentModeStack[-1] = None
+ #self.currentModeStack[-1] = None
self.addMode.objectCreated.connect(self.addInPlace)
self.updateModeBtnsOnly()
@@ -557,7 +622,10 @@ class MainWindow1(Qw.QMainWindow):
def addInPlace(self, obj):
obj.asyengine = self.asyEngine
- obj.pen = self.currentPen
+ if isinstance(obj, x2a.xasyText):
+ obj.label.pen = self.currentPen
+ else:
+ obj.pen = self.currentPen
obj.onCanvas = self.xasyDrawObj
obj.setKey(str(self.globalObjectCounter))
self.globalObjectCounter = self.globalObjectCounter + 1
@@ -576,11 +644,6 @@ class MainWindow1(Qw.QMainWindow):
self.currentGuides.clear()
self.quickUpdate()
- def btnAddCircleOnClick(self):
- self.addMode = InplaceAddObj.AddCircle(self)
- self.ui.statusbar.showMessage('')
- self.updateOptionWidget()
-
LegacyHint='Click and drag to draw; right click or space bar to finalize'
Hint='Click and drag to draw; release and click in place to add node; continue dragging'
HintClose=' or c to close.'
@@ -598,49 +661,90 @@ class MainWindow1(Qw.QMainWindow):
self.ui.statusbar.showMessage(self.Hint+self.HintClose)
def btnAddBezierInplaceOnClick(self):
+ self.fileChanged = True
self.addMode = InplaceAddObj.AddBezierShape(self)
self.updateOptionWidget()
def btnAddOpenLineOnClick(self):
- self.currAddOptions['useBezier'] = False
- self.currAddOptions['closedPath'] = False
- self.drawHintOpen()
- self.btnAddBezierInplaceOnClick()
+ if self.currentModeStack[-1] != SelectionMode.openPoly:
+ self.currentModeStack = [SelectionMode.openPoly]
+ self.currAddOptions['useBezier'] = False
+ self.currAddOptions['closedPath'] = False
+ self.drawHintOpen()
+ self.btnAddBezierInplaceOnClick()
+ else:
+ self.btnTranslateonClick()
def btnAddClosedLineOnClick(self):
- self.currAddOptions['useBezier'] = False
- self.currAddOptions['closedPath'] = True
- self.drawHint()
- self.btnAddBezierInplaceOnClick()
+ if self.currentModeStack[-1] != SelectionMode.closedPoly:
+ self.currentModeStack = [SelectionMode.closedPoly]
+ self.currAddOptions['useBezier'] = False
+ self.currAddOptions['closedPath'] = True
+ self.drawHint()
+ self.btnAddBezierInplaceOnClick()
+ else:
+ self.btnTranslateonClick()
def btnAddOpenCurveOnClick(self):
- self.currAddOptions['useBezier'] = True
- self.currAddOptions['closedPath'] = False
- self.drawHintOpen()
- self.btnAddBezierInplaceOnClick()
+ if self.currentModeStack[-1] != SelectionMode.openCurve:
+ self.currentModeStack = [SelectionMode.openCurve]
+ self.currAddOptions['useBezier'] = True
+ self.currAddOptions['closedPath'] = False
+ self.drawHintOpen()
+ self.btnAddBezierInplaceOnClick()
+ else:
+ self.btnTranslateonClick()
def btnAddClosedCurveOnClick(self):
- self.currAddOptions['useBezier'] = True
- self.currAddOptions['closedPath'] = True
- self.drawHint()
- self.btnAddBezierInplaceOnClick()
+ if self.currentModeStack[-1] != SelectionMode.closedCurve:
+ self.currentModeStack = [SelectionMode.closedCurve]
+ self.currAddOptions['useBezier'] = True
+ self.currAddOptions['closedPath'] = True
+ self.drawHint()
+ self.btnAddBezierInplaceOnClick()
+ else:
+ self.btnTranslateonClick()
def btnAddPolyOnClick(self):
- self.addMode = InplaceAddObj.AddPoly(self)
- self.ui.statusbar.showMessage('')
- self.updateOptionWidget()
+ if self.currentModeStack[-1] != SelectionMode.addPoly:
+ self.currentModeStack = [SelectionMode.addPoly]
+ self.addMode = InplaceAddObj.AddPoly(self)
+ self.ui.statusbar.showMessage('Add polygon on click')
+ self.updateOptionWidget()
+ else:
+ self.btnTranslateonClick()
- def btnAddLabelOnClick(self):
- self.addMode = InplaceAddObj.AddLabel(self)
- self.ui.statusbar.showMessage('')
- self.updateOptionWidget()
+ def btnAddCircleOnClick(self):
+ if self.currentModeStack[-1] != SelectionMode.addCircle:
+ self.currentModeStack = [SelectionMode.addCircle]
+ self.addMode = InplaceAddObj.AddCircle(self)
+ self.ui.statusbar.showMessage('Add circle on click')
+ self.updateOptionWidget()
+ else:
+ self.btnTranslateonClick()
- def updateCurve(self, valid, newCurve):
- self.previewCurve = newCurve
- self.quickUpdate()
+ def btnAddLabelOnClick(self):
+ if self.currentModeStack[-1] != SelectionMode.addLabel:
+ self.currentModeStack = [SelectionMode.addLabel]
+ self.addMode = InplaceAddObj.AddLabel(self)
+ self.ui.statusbar.showMessage('Add label on click')
+ self.updateOptionWidget()
+ else:
+ self.btnTranslateonClick()
+
+ def btnAddFreehandOnClick(self):
+ if self.currentModeStack[-1] != SelectionMode.addFreehand:
+ self.currentModeStack = [SelectionMode.addFreehand]
+ self.currAddOptions['useBezier'] = False
+ self.currAddOptions['closedPath'] = False
+ self.ui.statusbar.showMessage("Draw freehand")
+ self.addMode = InplaceAddObj.AddFreehand(self)
+ self.updateOptionWidget()
+ else:
+ self.btnTranslateonClick()
def addTransformationChanges(self, objIndex, transform, isLocal=False):
- self.undoRedoStack.add(self.createAction(TransformationChanges(objIndex,
+ self.undoRedoStack.add(self.createAction(TransformationChanges(objIndex,
transform, isLocal)))
self.checkUndoRedoButtons()
@@ -665,7 +769,11 @@ class MainWindow1(Qw.QMainWindow):
parent = selectedObj.parent()
if isinstance(parent, x2a.xasyScript):
- self.hiddenKeys.add((selectedObj.key, selectedObj.keyIndex))
+ objKey=(selectedObj.key, selectedObj.keyIndex)
+ self.hiddenKeys.add(objKey)
+ self.undoRedoStack.add(self.createAction(
+ SoftDeletionChanges(selectedObj.parent(), objKey)
+ ))
self.softDeleteObj((maj, minor))
else:
index = self.fileItems.index(selectedObj.parent())
@@ -673,10 +781,10 @@ class MainWindow1(Qw.QMainWindow):
self.undoRedoStack.add(self.createAction(
HardDeletionChanges(selectedObj.parent(), index)
))
- self.checkUndoRedoButtons()
-
+
self.fileItems.remove(selectedObj.parent())
+ self.checkUndoRedoButtons()
self.fileChanged = True
self.clearSelection()
self.asyfyCanvas()
@@ -709,8 +817,16 @@ class MainWindow1(Qw.QMainWindow):
def btnUndoOnClick(self):
- self.undoRedoStack.undo()
- self.checkUndoRedoButtons()
+ if self.currentlySelectedObj['selectedIndex'] is not None:
+ # avoid deleting currently selected object
+ maj, minor = self.currentlySelectedObj['selectedIndex']
+ selectedObj = self.drawObjects[maj][minor]
+ if selectedObj != self.drawObjects[-1][0]:
+ self.undoRedoStack.undo()
+ self.checkUndoRedoButtons()
+ else:
+ self.undoRedoStack.undo()
+ self.checkUndoRedoButtons()
def btnRedoOnClick(self):
self.undoRedoStack.redo()
@@ -731,6 +847,12 @@ class MainWindow1(Qw.QMainWindow):
self.fileItems.pop()
elif isinstance(change, HardDeletionChanges):
self.fileItems.insert(change.objIndex, change.item)
+ elif isinstance(change, SoftDeletionChanges):
+ key, keyIndex = change.keyMap
+ self.hiddenKeys.remove((key, keyIndex))
+ change.item.transfKeymap[key][keyIndex].deleted = False
+ elif isinstance(change, EditBezierChanges):
+ self.fileItems[change.objIndex].path = change.oldPath
self.asyfyCanvas()
def handleRedoChanges(self, change):
@@ -742,6 +864,12 @@ class MainWindow1(Qw.QMainWindow):
self.fileItems.append(change.object)
elif isinstance(change, HardDeletionChanges):
self.fileItems.remove(change.item)
+ elif isinstance(change, SoftDeletionChanges):
+ key, keyIndex = change.keyMap
+ self.hiddenKeys.add((key, keyIndex))
+ change.item.transfKeymap[key][keyIndex].deleted = True
+ elif isinstance(change, EditBezierChanges):
+ self.fileItems[change.objIndex].path = change.newPath
self.asyfyCanvas()
# is this a "pythonic" way?
@@ -765,11 +893,26 @@ class MainWindow1(Qw.QMainWindow):
if result:
self.execCustomCommand(commandText)
- def addItemFromPath(self, path):
- newItem = x2a.xasyShape(path, self.asyEngine, pen=self.currentPen)
+ def addXasyShapeFromPath(self, path, pen = None, transform = x2a.identity(), key = None):
+ if not pen:
+ pen = self.currentPen
+ else:
+ pen = x2a.asyPen(self.asyEngine, color = pen['color'], width = pen['width'], pen_options = pen['options'])
+
+ newItem = x2a.xasyShape(path, self.asyEngine, pen = pen, transform = transform)
+ newItem.setKey(key)
self.fileItems.append(newItem)
- self.fileChanged = True
- self.asyfyCanvas()
+
+ def addXasyTextFromData(self, text, location, pen, transform, key, align, fontSize):
+ if not pen:
+ pen = self.currentPen
+ else:
+ pen = x2a.asyPen(self.asyEngine, color = pen['color'], width = pen['width'], pen_options = pen['options'])
+ newItem = x2a.xasyText(text, location, self.asyEngine, pen, transform, key, align, fontSize)
+ newItem.setKey(key)
+ newItem.onCanvas = self.xasyDrawObj
+ self.fileItems.append(newItem)
+
def actionManual(self):
asyManualURL = 'https://asymptote.sourceforge.io/asymptote.pdf'
@@ -778,11 +921,35 @@ class MainWindow1(Qw.QMainWindow):
def actionAbout(self):
Qw.QMessageBox.about(self,"xasy","This is xasy "+xasyVersion.xasyVersion+"; a graphical front end to the Asymptote vector graphics language: https://asymptote.sourceforge.io/")
- def btnExportAsyOnClick(self):
+ def actionExport(self, pathToFile):
+ asyFile = io.open(os.path.realpath(pathToFile), 'w')
+ xf.saveFile(asyFile, self.fileItems, self.asy2psmap)
+ asyFile.close()
+ self.ui.statusbar.showMessage(f"Exported to '{pathToFile}' as Asymptote File.")
+
+ def btnExportToAsyOnClick(self):
+ if self.fileName:
+ pathToFile = os.path.splitext(self.fileName)[0]+'.asy'
+ else:
+ self.btnExportAsymptoteOnClick()
+ return
+ if os.path.isfile(pathToFile):
+ reply = Qw.QMessageBox.question(self, 'Message',
+ f'"{os.path.split(pathToFile)[1]}" already exists. Do you want to overwrite it?',
+ Qw.QMessageBox.Yes, Qw.QMessageBox.No)
+ if reply == Qw.QMessageBox.No:
+ return
+ self.actionExport(pathToFile)
+
+ def btnExportAsymptoteOnClick(self):
diag = Qw.QFileDialog(self)
diag.setAcceptMode(Qw.QFileDialog.AcceptSave)
formatId = {
+ 'asy': {
+ 'name': 'Asymptote Files',
+ 'ext': ['*.asy']
+ },
'pdf': {
'name': 'PDF Files',
'ext': ['*.pdf']
@@ -805,14 +972,14 @@ class MainWindow1(Qw.QMainWindow):
}
}
- formats = ['pdf', 'svg', 'eps', 'png', '*']
+ formats = ['asy', 'pdf', 'svg', 'eps', 'png', '*']
formatText = ';;'.join('{0:s} ({1:s})'.format(formatId[form]['name'], ' '.join(formatId[form]['ext']))
for form in formats)
if self.currDir is not None:
diag.setDirectory(self.currDir)
- rawFile = os.path.splitext(os.path.basename(self.filename))[0] + '.pdf'
+ rawFile = os.path.splitext(os.path.basename(self.fileName))[0] + '.asy'
diag.selectFile(rawFile)
diag.setNameFilter(formatText)
@@ -823,25 +990,107 @@ class MainWindow1(Qw.QMainWindow):
return
finalFiles = diag.selectedFiles()
-
- with io.StringIO() as finalCode:
- xf.saveFile(finalCode, self.fileItems, self.asy2psmap)
- finalString = finalCode.getvalue()
+ finalString = xf.xasy2asyCode(self.fileItems, self.asy2psmap)
for file in finalFiles:
ext = os.path.splitext(file)
if len(ext) < 2:
- ext = 'pdf'
+ ext = 'asy'
else:
ext = ext[1][1:]
+ if ext == 'asy':
+ pathToFile = os.path.splitext(file)[0]+'.'+ext
+ asyFile = io.open(os.path.realpath(pathToFile), 'w')
+ xf.saveFile(asyFile, self.fileItems, self.asy2psmap)
+ asyFile.close()
+ else:
+ with subprocess.Popen(args=[self.asyPath, '-f{0}'.format(ext), '-o{0}'.format(file), '-'], encoding='utf-8',
+ stdin=subprocess.PIPE) as asy:
+
+ asy.stdin.write(finalString)
+ asy.stdin.close()
+ asy.wait(timeout=35)
+
+ def actionExportXasy(self, file):
+ xasyObjects, asyItems = xf.xasyToDict(self.fileName, self.fileItems, self.asy2psmap)
- with subprocess.Popen(args=[self.asyPath, '-f{0}'.format(ext), '-o{0}'.format(file), '-'], encoding='utf-8',
- stdin=subprocess.PIPE) as asy:
- print('test:', finalString)
- asy.stdin.write(finalString)
- asy.stdin.close()
- asy.wait(timeout=35)
+ if asyItems:
+ # Save imported items into the twin asy file
+ asyScriptItems = [item['item'] for item in asyItems if item['type'] == 'xasyScript']
+
+ prefix = os.path.splitext(self.fileName)[0]
+ asyFilePath = prefix + '.asy'
+
+ saveAsyFile = io.open(asyFilePath, 'w')
+ xf.saveFile(saveAsyFile, asyScriptItems, self.asy2psmap)
+ saveAsyFile.close()
+ self.updateScript()
+
+ openFile = open(file, 'wb')
+ pickle.dump(xasyObjects, openFile)
+ openFile.close()
+
+ def actionLoadXasy(self, file):
+ self.erase()
+ self.ui.statusbar.showMessage('Load {0}'.format(file)) # TODO: This doesn't show on the UI
+ self.fileName = file
+ self.currDir = os.path.dirname(self.fileName)
+
+ input_file = open(file, 'rb')
+ xasyObjects = pickle.load(input_file)
+ input_file.close()
+
+ prefix = os.path.splitext(self.fileName)[0]
+ asyFilePath = prefix + '.asy'
+ rawText = None
+ existsAsy = False
+
+ if os.path.isfile(asyFilePath):
+ asyFile = io.open(asyFilePath, 'r')
+ rawText = asyFile.read()
+ asyFile.close()
+ rawText, transfDict = xf.extractTransformsFromFile(rawText)
+ obj = x2a.xasyScript(canvas=self.xasyDrawObj, engine=self.asyEngine, transfKeyMap=transfDict)
+ obj.setScript(rawText)
+ self.fileItems.append(obj)
+ existsAsy = True
+
+ self.asyfyCanvas(force=True)
+
+ for item in xasyObjects['objects']:
+ key=item['transfKey']
+ if(key) in obj.transfKeymap.keys():
+ continue
+ obj.maxKey=max(obj.maxKey,int(key))
+ if item['type'] == 'xasyScript':
+ print("Uh oh, there should not be any asy objects loaded")
+
+ elif item['type'] == 'xasyText':
+ self.addXasyTextFromData( text = item['text'],
+ location = item['location'], pen = None,
+ transform = x2a.asyTransform(item['transform']), key = item['transfKey'],
+ align = item['align'], fontSize = item['fontSize']
+ )
+
+ elif item['type'] == 'xasyShape':
+ nodeSet = item['nodes']
+ linkSet = item['links']
+ path = x2a.asyPath(self.asyEngine)
+ path.initFromNodeList(nodeSet, linkSet)
+ self.addXasyShapeFromPath(path, pen = item['pen'], transform = x2a.asyTransform(item['transform']), key = item['transfKey'])
+ else:
+ print("ERROR")
+
+ self.asy2psmap = x2a.asyTransform(xasyObjects['asy2psmap'])
+ self.globalObjectCounter = obj.maxKey+1
+
+ self.asyfyCanvas()
+
+ if existsAsy:
+ self.ui.statusbar.showMessage(f"Corresponding Asymptote File '{os.path.basename(asyFilePath)}' found. Loaded both files.")
+ else:
+ self.ui.statusbar.showMessage("No Asymptote file found. Loaded exclusively GUI objects.")
def loadKeyMaps(self):
"""Inverts the mapping of the key
@@ -865,28 +1114,147 @@ class MainWindow1(Qw.QMainWindow):
def erase(self):
self.fileItems.clear()
+ self.hiddenKeys.clear()
+ self.undoRedoStack.clear()
+ self.checkUndoRedoButtons()
self.fileChanged = False
- def actionOpen(self):
+ #We include this function to keep the general program flow consistent
+ def closeEvent(self, event):
+ if self.actionClose() == Qw.QMessageBox.Cancel:
+ event.ignore()
+
+ def actionNewFile(self):
if self.fileChanged:
- save="Save current file?"
- reply=Qw.QMessageBox.question(self,'Message',save,Qw.QMessageBox.Yes,
- Qw.QMessageBox.No)
+ reply = self.saveDialog()
if reply == Qw.QMessageBox.Yes:
self.actionSave()
+ elif reply == Qw.QMessageBox.Cancel:
+ return
+ self.erase()
+ self.asyfyCanvas(force=True)
+ self.fileName = None
+ self.updateTitle()
+
+
+ def actionOpen(self, fileName = None):
+ if self.fileChanged:
+ reply = self.saveDialog()
+ if reply == Qw.QMessageBox.Yes:
+ self.actionSave()
+ elif reply == Qw.QMessageBox.Cancel:
+ return
- filename = Qw.QFileDialog.getOpenFileName(self, 'Open Asymptote File','', '*.asy')
- if filename[0]:
- self.loadFile(filename[0])
+ if fileName:
+ # Opening via open recent or cmd args
+ _, file_extension = os.path.splitext(fileName)
+ if file_extension == '.xasy':
+ self.actionLoadXasy(fileName)
+ else:
+ self.loadFile(fileName)
+ self.populateOpenRecent(fileName)
+ else:
+ filename = Qw.QFileDialog.getOpenFileName(self, 'Open Xasy/Asymptote File','', '(*.xasy *.asy)')
+ if filename[0]:
+ _, file_extension = os.path.splitext(filename[0])
+ if file_extension == '.xasy':
+ self.actionLoadXasy(filename[0])
+ else:
+ self.loadFile(filename[0])
+
+ self.populateOpenRecent(filename[0].strip())
+
+ def actionClearRecent(self):
+ self.ui.menuOpenRecent.clear()
+ self.openRecent.clear()
+ self.ui.menuOpenRecent.addAction("Clear", self.actionClearRecent)
+
+ def populateOpenRecent(self, recentOpenedFile = None):
+ self.ui.menuOpenRecent.clear()
+ if recentOpenedFile:
+ self.openRecent.insert(recentOpenedFile)
+ for count, path in enumerate(self.openRecent.pathList):
+ if count > 8:
+ break
+ action = Qw.QAction(path, self, triggered = lambda state, path = path: self.actionOpen(fileName = path))
+ self.ui.menuOpenRecent.addAction(action)
+ self.ui.menuOpenRecent.addSeparator()
+ self.ui.menuOpenRecent.addAction("Clear", self.actionClearRecent)
+
+ def saveDialog(self) -> bool:
+ save = "Save current file?"
+ replyBox = Qw.QMessageBox()
+ replyBox.setText("Save current file?")
+ replyBox.setWindowTitle("Message")
+ replyBox.setStandardButtons(Qw.QMessageBox.Yes | Qw.QMessageBox.No | Qw.QMessageBox.Cancel)
+ reply = replyBox.exec()
+
+ return reply
+
+ def actionClose(self):
+ if self.fileChanged:
+ reply = self.saveDialog()
+ if reply == Qw.QMessageBox.Yes:
+ self.actionSave()
+ Qc.QCoreApplication.quit()
+ elif reply == Qw.QMessageBox.No:
+ Qc.QCoreApplication.quit()
+ else:
+ return reply
+ else:
+ Qc.QCoreApplication.quit()
def actionSave(self):
- if self.filename is None:
+ if self.fileName is None:
self.actionSaveAs()
+
else:
- saveFile = io.open(self.filename, 'w')
- xf.saveFile(saveFile, self.fileItems, self.asy2psmap)
- saveFile.close()
+ _, file_extension = os.path.splitext(self.fileName)
+ if file_extension == ".asy":
+ if self.existsXasy():
+ warning = "Choose save format. Note that objects saved in asy format cannot be edited graphically."
+ replyBox = Qw.QMessageBox()
+ replyBox.setWindowTitle('Warning')
+ replyBox.setText(warning)
+ replyBox.addButton("Save as .xasy", replyBox.NoRole)
+ replyBox.addButton("Save as .asy", replyBox.YesRole)
+ replyBox.addButton(Qw.QMessageBox.Cancel)
+ reply = replyBox.exec()
+ if reply == 1:
+ saveFile = io.open(self.fileName, 'w')
+ xf.saveFile(saveFile, self.fileItems, self.asy2psmap)
+ saveFile.close()
+ self.ui.statusbar.showMessage('File saved as {}'.format(self.fileName))
+ self.fileChanged = False
+ elif reply == 0:
+ prefix = os.path.splitext(self.fileName)[0]
+ xasyFilePath = prefix + '.xasy'
+ if os.path.isfile(xasyFilePath):
+ warning = f'"{os.path.basename(xasyFilePath)}" already exists. Do you want to overwrite it?'
+ reply = Qw.QMessageBox.question(self, "Same File", warning, Qw.QMessageBox.No, Qw.QMessageBox.Yes)
+ if reply == Qw.QMessageBox.No:
+ return
+
+ self.actionExportXasy(xasyFilePath)
+ self.fileName = xasyFilePath
+ self.ui.statusbar.showMessage('File saved as {}'.format(self.fileName))
+ self.fileChanged = False
+ else:
+ return
+
+ else:
+ saveFile = io.open(self.fileName, 'w')
+ xf.saveFile(saveFile, self.fileItems, self.asy2psmap)
+ saveFile.close()
+ self.fileChanged = False
+ elif file_extension == ".xasy":
+ self.actionExportXasy(self.fileName)
+ self.ui.statusbar.showMessage('File saved as {}'.format(self.fileName))
+ self.fileChanged = False
+ else:
+ print("ERROR: file extension not supported")
self.updateScript()
+ self.updateTitle()
def updateScript(self):
for item in self.fileItems:
@@ -895,15 +1263,30 @@ class MainWindow1(Qw.QMainWindow):
item.setScript(item.updatedCode)
item.updatedCode = None
+ def existsXasy(self):
+ for item in self.fileItems:
+ if not isinstance(item, x2a.xasyScript):
+ return True
+ return False
+
def actionSaveAs(self):
- saveLocation = Qw.QFileDialog.getSaveFileName(self, 'Save File')[0]
+ initSave = os.path.splitext(str(self.fileName))[0]+'.xasy'
+ saveLocation = Qw.QFileDialog.getSaveFileName(self, 'Save File', initSave, "Xasy File (*.xasy)")[0]
if saveLocation:
- saveFile = io.open(saveLocation, 'w')
- xf.saveFile(saveFile, self.fileItems, self.asy2psmap)
- saveFile.close()
- self.filename = saveLocation
+ _, file_extension = os.path.splitext(saveLocation)
+ if not file_extension:
+ saveLocation += '.xasy'
+ self.actionExportXasy(saveLocation)
+ elif file_extension == ".xasy":
+ self.actionExportXasy(saveLocation)
+ else:
+ print("ERROR: file extension not supported")
+ self.fileName = saveLocation
self.updateScript()
-
+ self.fileChanged = False
+ self.updateTitle()
+ self.populateOpenRecent(saveLocation)
+
def btnQuickScreenshotOnClick(self):
saveLocation = Qw.QFileDialog.getSaveFileName(self, 'Save Screenshot','')
@@ -913,6 +1296,9 @@ class MainWindow1(Qw.QMainWindow):
def btnLoadFileonClick(self):
self.actionOpen()
+ def btnCloseFileonClick(self):
+ self.actionClose()
+
def btnSaveonClick(self):
self.actionSave()
@@ -933,7 +1319,7 @@ class MainWindow1(Qw.QMainWindow):
self._currentPen.setColorFromQColor(self.colorDialog.selectedColor())
self.updateFrameDispColor()
- def txtLineWithEdited(self, text):
+ def txtLineWidthEdited(self, text):
new_val = xu.tryParse(text, float)
if new_val is not None:
if new_val > 0:
@@ -985,12 +1371,12 @@ class MainWindow1(Qw.QMainWindow):
def mouseMoveEvent(self, mouseEvent: Qg.QMouseEvent): # TODO: Actually refine grid snapping...
if not self.ui.imgLabel.underMouse() and not self.mouseDown:
- return
+ return
self.updateMouseCoordLabel()
asyPos, canvasPos = self.getAsyCoordinates()
- # add mode
+ # add mode
if self.addMode is not None:
if self.addMode.active:
self.addMode.mouseMove(asyPos, mouseEvent)
@@ -1016,7 +1402,7 @@ class MainWindow1(Qw.QMainWindow):
self.quickUpdate()
return
- # otherwise, in transformation
+ # otherwise, in transformation
if self.inMidTransformation:
if self.currentModeStack[-1] == SelectionMode.translate:
newPos = canvasPos - self.savedMousePosition
@@ -1080,11 +1466,11 @@ class MainWindow1(Qw.QMainWindow):
self.pendingSelectedObjList.clear()
self.pendingSelectedObjIndex = -1
self.quickUpdate()
- return
+ return
def mouseReleaseEvent(self, mouseEvent):
- assert isinstance(mouseEvent, Qg.QMouseEvent)
+ assert isinstance(mouseEvent, Qg.QMouseEvent)
if not self.mouseDown:
return
@@ -1124,8 +1510,7 @@ class MainWindow1(Qw.QMainWindow):
keyModifiers = keyModifiers | defaultModifiers
if keyModifiers & int(Qc.Qt.ControlModifier):
oldMag = self.magnification
-
- factor=0.5/devicePixelRatio;
+ factor = 0.5/devicePixelRatio
cx, cy = self.canvSize.width()*factor, self.canvSize.height()*factor
centerPoint = Qc.QPointF(cx, cy) * self.getScrsTransform().inverted()[0]
@@ -1203,7 +1588,7 @@ class MainWindow1(Qw.QMainWindow):
if self.addMode is not None:
if self.addMode.active and isinstance(self.addMode, InplaceAddObj.AddBezierShape):
bezierException = True
-
+
if not self.ui.imgLabel.underMouse() and not bezierException:
return
@@ -1252,7 +1637,15 @@ class MainWindow1(Qw.QMainWindow):
self.addMode = None
self.deleteAddOptions()
- def editFinalized(self):
+ def editAccepted(self, obj, objIndex):
+ self.undoRedoStack.add(self.createAction(
+ EditBezierChanges(obj, objIndex,
+ self.addMode.asyPathBackup,
+ self.addMode.asyPath
+ )
+ ))
+ self.checkUndoRedoButtons()
+
self.addMode.forceFinalize()
self.removeAddMode()
self.fileChanged = True
@@ -1260,7 +1653,10 @@ class MainWindow1(Qw.QMainWindow):
def editRejected(self):
self.addMode.resetObj()
- self.editFinalized()
+ self.addMode.forceFinalize()
+ self.removeAddMode()
+ self.fileChanged = True
+ self.quickUpdate()
def setupSelectEdit(self):
"""For Select-Edit mode. For now, if the object selected is a bezier curve, opens up a bezier editor"""
@@ -1270,12 +1666,20 @@ class MainWindow1(Qw.QMainWindow):
# bezier path
self.addMode = xbi.InteractiveBezierEditor(self, obj, self.currAddOptions)
self.addMode.objectUpdated.connect(self.objectUpdated)
- self.addMode.editAccepted.connect(self.editFinalized)
+ self.addMode.editAccepted.connect(lambda: self.editAccepted(obj, maj))
self.addMode.editRejected.connect(self.editRejected)
self.updateOptionWidget()
self.currentModeStack[-1] = SelectionMode.selectEdit
self.fileChanged = True
+ elif isinstance(obj, x2a.xasyText):
+ newText = self.setTextPrompt()
+ if newText:
+ self.drawObjects.remove(obj.generateDrawObjects(False))
+ obj.label.setText(newText)
+ self.drawObjects.append(obj.generateDrawObjects(True))
+ self.fileChanged = True
else:
+ self.ui.statusbar.showMessage('Warning: Selected object cannot be edited')
self.clearSelection()
self.quickUpdate()
@@ -1359,7 +1763,7 @@ class MainWindow1(Qw.QMainWindow):
# but it's much more work...
newCenter = self.magnification * newCenter
self.panOffset = [-newCenter.x(), newCenter.y()]
-
+
self.quickUpdate()
def selectObject(self):
@@ -1410,7 +1814,7 @@ class MainWindow1(Qw.QMainWindow):
def getWindowCoordinates(self):
# assert self.ui.imgLabel.underMouse()
return self.mapFromGlobal(Qg.QCursor.pos())
-
+
def refreshCanvas(self):
if self.mainCanvas.isActive():
self.mainCanvas.end()
@@ -1430,16 +1834,20 @@ class MainWindow1(Qw.QMainWindow):
self.coordLabel.setText('{0:.2f}, {1:.2f} '.format(nx, ny))
def quickUpdate(self):
+ # TODO: Some documentation here would be nice since this is one of the
+ # main functions that gets called everywhere.
self.updateMouseCoordLabel()
self.refreshCanvas()
- self.preDraw(self.mainCanvas)
+ self.preDraw(self.mainCanvas) # coordinates/background
self.quickDraw()
self.mainCanvas.end()
self.postDraw()
self.updateScreen()
+ self.updateTitle()
+
def quickDraw(self):
assert self.isReady()
dpi = self.magnification * self.dpi
@@ -1466,7 +1874,7 @@ class MainWindow1(Qw.QMainWindow):
if self.pendingSelectedObjList:
maj, minor = self.pendingSelectedObjList[self.pendingSelectedObjIndex]
self.drawObjects[maj][minor].draw(canvas=self.mainCanvas, dpi=dpi)
- # and apply the preview too...
+ # and apply the preview too...
elif activeItem is not None:
if self.useGlobalCoords:
activeItem.draw(self.newTransform, canvas=self.mainCanvas, dpi=dpi)
@@ -1474,6 +1882,17 @@ class MainWindow1(Qw.QMainWindow):
activeItem.draw(self.newTransform, applyReverse=True, canvas=self.mainCanvas, dpi=dpi)
activeItem = None
+ def updateTitle(self):
+ # TODO: Undo redo doesn't update appropriately. Have to find a fix for this.
+ title = ''
+ if self.fileName:
+ title += os.path.basename(self.fileName)
+ else:
+ title += "[Not Saved]"
+ if self.fileChanged:
+ title += ' *'
+ self.setWindowTitle(title)
+
def updateScreen(self):
self.finalPixmap = Qg.QPixmap(self.canvSize)
self.finalPixmap.setDevicePixelRatio(devicePixelRatio)
@@ -1502,6 +1921,7 @@ class MainWindow1(Qw.QMainWindow):
for x in np.arange(0, 2 * x_range + 1, majorGrid): # have to do
# this in two stages...
preCanvas.setPen(minorGridCol)
+ self.makePenCosmetic(preCanvas)
for xMinor in range(1, minorGridCount + 1):
xCoord = x + ((xMinor / (minorGridCount + 1)) * majorGrid)
preCanvas.drawLine(Qc.QLine(xCoord, -9999, xCoord, 9999))
@@ -1509,17 +1929,20 @@ class MainWindow1(Qw.QMainWindow):
for y in np.arange(0, 2 * y_range + 1, majorGrid):
preCanvas.setPen(minorGridCol)
+ self.makePenCosmetic(preCanvas)
for yMinor in range(1, minorGridCount + 1):
yCoord = y + ((yMinor / (minorGridCount + 1)) * majorGrid)
preCanvas.drawLine(Qc.QLine(-9999, yCoord, 9999, yCoord))
preCanvas.drawLine(Qc.QLine(-9999, -yCoord, 9999, -yCoord))
preCanvas.setPen(majorGridCol)
+ self.makePenCosmetic(preCanvas)
preCanvas.drawLine(Qc.QLine(-9999, y, 9999, y))
preCanvas.drawLine(Qc.QLine(-9999, -y, 9999, -y))
for x in np.arange(0, 2 * x_range + 1, majorGrid):
preCanvas.setPen(majorGridCol)
+ self.makePenCosmetic(preCanvas)
preCanvas.drawLine(Qc.QLine(x, -9999, x, 9999))
preCanvas.drawLine(Qc.QLine(-x, -9999, -x, 9999))
@@ -1568,6 +1991,7 @@ class MainWindow1(Qw.QMainWindow):
if self.drawAxes:
preCanvas.setPen(Qc.Qt.gray)
+ self.makePenCosmetic(preCanvas)
preCanvas.drawLine(Qc.QLine(-9999, 0, 9999, 0))
preCanvas.drawLine(Qc.QLine(0, -9999, 0, 9999))
@@ -1590,13 +2014,14 @@ class MainWindow1(Qw.QMainWindow):
painter.setPen(self.currentPen.toQPen())
painter.drawPath(self.addMode.getPreview())
self.addMode.postDrawPreview(painter)
-
+
def drawTransformPreview(self, painter):
if self.currentBoundingBox is not None and self.currentlySelectedObj['selectedIndex'] is not None:
painter.save()
maj, minor = self.currentlySelectedObj['selectedIndex']
selObj = self.drawObjects[maj][minor]
+ self.makePenCosmetic(painter)
if not self.useGlobalCoords:
painter.save()
painter.setTransform(
@@ -1621,13 +2046,14 @@ class MainWindow1(Qw.QMainWindow):
with Qg.QPainter(self.postCanvasPixmap) as postCanvas:
postCanvas.setRenderHints(self.mainCanvas.renderHints())
postCanvas.setTransform(self.getScrsTransform())
+ # self.makePenCosmetic(postCanvas)
self.drawTransformPreview(postCanvas)
if self.pendingSelectedObjList:
maj, minor = self.pendingSelectedObjList[self.pendingSelectedObjIndex]
postCanvas.drawRect(self.drawObjects[maj][minor].boundingBox)
-
+
self.drawAddModePreview(postCanvas)
if self.customAnchor is not None and self.anchorMode == AnchorMode.customAnchor:
@@ -1657,11 +2083,29 @@ class MainWindow1(Qw.QMainWindow):
activeBtn = self.ui.btnDeleteMode
elif self.currentModeStack[-1] == SelectionMode.selectEdit:
activeBtn = self.ui.btnSelectEdit
+ elif self.currentModeStack[-1] == SelectionMode.openPoly:
+ activeBtn = self.ui.btnOpenPoly
+ elif self.currentModeStack[-1] == SelectionMode.closedPoly:
+ activeBtn = self.ui.btnClosedPoly
+ elif self.currentModeStack[-1] == SelectionMode.openCurve:
+ activeBtn = self.ui.btnOpenCurve
+ elif self.currentModeStack[-1] == SelectionMode.closedCurve:
+ activeBtn = self.ui.btnClosedCurve
+ elif self.currentModeStack[-1] == SelectionMode.addPoly:
+ activeBtn = self.ui.btnAddPoly
+ elif self.currentModeStack[-1] == SelectionMode.addCircle:
+ activeBtn = self.ui.btnAddCircle
+ elif self.currentModeStack[-1] == SelectionMode.addLabel:
+ activeBtn = self.ui.btnAddLabel
+ elif self.currentModeStack[-1] == SelectionMode.addFreehand:
+ activeBtn = self.ui.btnAddFreehand
else:
activeBtn = None
-
+
disableFill = isinstance(self.addMode, InplaceAddObj.AddBezierShape) and not self.currAddOptions['closedPath']
+ if isinstance(self.addMode, xbi.InteractiveBezierEditor):
+ disableFill = disableFill or not (self.addMode.obj.path.nodeSet[-1] == "cycle")
self.ui.btnFill.setEnabled(not disableFill)
if disableFill and self.ui.btnFill.isEnabled():
self.ui.btnFill.setChecked(not disableFill)
@@ -1670,22 +2114,36 @@ class MainWindow1(Qw.QMainWindow):
for button in self.modeButtons:
button.setChecked(button is activeBtn)
+ if activeBtn in [self.ui.btnDeleteMode,self.ui.btnSelectEdit]:
+ self.ui.btnAlignX.setEnabled(False)
+ self.ui.btnAlignY.setEnabled(False)
+ else:
+ self.ui.btnAlignX.setEnabled(True)
+ self.ui.btnAlignY.setEnabled(True)
+
+
def updateChecks(self):
self.removeAddMode()
self.updateModeBtnsOnly()
self.quickUpdate()
def btnAlignXOnClick(self, checked):
- self.lockY = checked
- if self.lockX:
- self.lockX = False
- self.ui.btnAlignY.setChecked(False)
+ if self.currentModeStack[0] in [SelectionMode.selectEdit,SelectionMode.delete]:
+ self.ui.btnAlignX.setChecked(False)
+ else:
+ self.lockY = checked
+ if self.lockX:
+ self.lockX = False
+ self.ui.btnAlignY.setChecked(False)
def btnAlignYOnClick(self, checked):
- self.lockX = checked
- if self.lockY:
- self.lockY = False
- self.ui.btnAlignX.setChecked(False)
+ if self.currentModeStack[0] in [SelectionMode.selectEdit,SelectionMode.delete]:
+ self.ui.btnAlignY.setChecked(False)
+ else:
+ self.lockX = checked
+ if self.lockY:
+ self.lockY = False
+ self.ui.btnAlignX.setChecked(False)
def btnAnchorModeOnClick(self):
if self.currentModeStack[-1] != SelectionMode.setAnchor:
@@ -1704,22 +2162,31 @@ class MainWindow1(Qw.QMainWindow):
self.updateChecks()
def btnRotateOnClick(self):
- self.currentModeStack = [SelectionMode.rotate]
- self.ui.statusbar.showMessage('Rotate mode')
- self.clearSelection()
- self.updateChecks()
+ if self.currentModeStack[-1] != SelectionMode.rotate:
+ self.currentModeStack = [SelectionMode.rotate]
+ self.ui.statusbar.showMessage('Rotate mode')
+ self.clearSelection()
+ self.updateChecks()
+ else:
+ self.btnTranslateonClick()
def btnScaleOnClick(self):
- self.currentModeStack = [SelectionMode.scale]
- self.ui.statusbar.showMessage('Scale mode')
- self.clearSelection()
- self.updateChecks()
+ if self.currentModeStack[-1] != SelectionMode.scale:
+ self.currentModeStack = [SelectionMode.scale]
+ self.ui.statusbar.showMessage('Scale mode')
+ self.clearSelection()
+ self.updateChecks()
+ else:
+ self.btnTranslateonClick()
def btnPanOnClick(self):
- self.currentModeStack = [SelectionMode.pan]
- self.ui.statusbar.showMessage('Pan mode')
- self.clearSelection()
- self.updateChecks()
+ if self.currentModeStack[-1] != SelectionMode.pan:
+ self.currentModeStack = [SelectionMode.pan]
+ self.ui.statusbar.showMessage('Pan mode')
+ self.clearSelection()
+ self.updateChecks()
+ else:
+ self.btnTranslateonClick()
def btnWorldCoordsOnClick(self, checked):
self.useGlobalCoords = checked
@@ -1754,24 +2221,26 @@ class MainWindow1(Qw.QMainWindow):
self.quickUpdate()
def btnLoadEditorOnClick(self):
+ pathToFile = os.path.splitext(self.fileName)[0]+'.asy'
if self.fileChanged:
save = "Save current file?"
reply = Qw.QMessageBox.question(self, 'Message', save, Qw.QMessageBox.Yes,
Qw.QMessageBox.No)
if reply == Qw.QMessageBox.Yes:
- self.actionSave()
-
- subprocess.Popen(args=self.getExternalEditor(asypath=self.filename));
+ self.actionExport(pathToFile)
+
+ subprocess.run(args=self.getExternalEditor(asypath=pathToFile));
+ self.loadFile(pathToFile)
def btnAddCodeOnClick(self):
header = """
-// xasy object created at $time
+// xasy object created at $time
// Object Number: $uid
-// This header is automatically generated by xasy.
+// This header is automatically generated by xasy.
// Your code here
"""
header = string.Template(header).substitute(time=str(datetime.datetime.now()), uid=str(self.globalObjectCounter))
-
+
with tempfile.TemporaryDirectory() as tmpdir:
newPath = os.path.join(tmpdir, 'tmpcode.asy')
f = io.open(newPath, 'w')
@@ -1791,6 +2260,7 @@ class MainWindow1(Qw.QMainWindow):
self.asyfyCanvas()
self.globalObjectCounter = self.globalObjectCounter + 1
+
def softDeleteObj(self, objKey):
maj, minor = objKey
drawObj = self.drawObjects[maj][minor]
@@ -1869,7 +2339,7 @@ class MainWindow1(Qw.QMainWindow):
s = editor.split()
rawExternalEditor = s[0]
rawExtEditorArgs = s[1:]+["$asypath"]
-
+
execEditor = [rawExternalEditor]
for arg in rawExtEditorArgs:
@@ -1881,34 +2351,37 @@ class MainWindow1(Qw.QMainWindow):
def loadFile(self, name):
filename = os.path.abspath(name)
if not os.path.isfile(filename):
- filename = filename + '.asy'
+ parts = os.path.splitext(filename)
+ if parts[1] == '':
+ filename = parts[0] + '.asy'
if not os.path.isfile(filename):
self.ui.statusbar.showMessage('File {0} not found'.format(filename))
return
self.ui.statusbar.showMessage('Load {0}'.format(filename))
- self.filename = filename
- self.currDir = os.path.dirname(self.filename)
+ self.fileName = filename
+ self.asyFileName = filename
+ self.currDir = os.path.dirname(self.fileName)
self.erase()
- f = open(self.filename, 'rt')
+ f = open(self.fileName, 'rt')
try:
rawFileStr = f.read()
except IOError:
Qw.QMessageBox.critical(self, self.strings.fileOpenFailed, self.strings.fileOpenFailedText)
else:
- rawText, transfDict, maxKey = xf.extractTransformsFromFile(rawFileStr)
+ rawText, transfDict = xf.extractTransformsFromFile(rawFileStr)
item = x2a.xasyScript(canvas=self.xasyDrawObj, engine=self.asyEngine, transfKeyMap=transfDict)
item.setScript(rawText)
self.fileItems.append(item)
- self.asyfyCanvas(True)
+ self.asyfyCanvas(force=True)
- maxKey2 = item.getMaxKeyCounter()
+ self.globalObjectCounter = item.maxKey+1
self.asy2psmap = item.asy2psmap
- self.globalObjectCounter = max(maxKey + 1, maxKey2)
+
finally:
f.close()
@@ -1916,3 +2389,37 @@ class MainWindow1(Qw.QMainWindow):
self.itemCount = 0
for item in self.fileItems:
self.drawObjects.append(item.generateDrawObjects(forceUpdate))
+
+ def makePenCosmetic(self, painter):
+ localPen = painter.pen()
+ localPen.setCosmetic(True)
+ painter.setPen(localPen)
+
+ def copyItem(self):
+ self.selectOnHover()
+ if self.currentlySelectedObj['selectedIndex'] is not None:
+ maj, minor = self.currentlySelectedObj['selectedIndex']
+ if isinstance(self.fileItems[maj],x2a.xasyShape) or isinstance(self.fileItems[maj],x2a.xasyText):
+ self.copiedObject = self.fileItems[maj].copy()
+ else:
+ self.ui.statusbar.showMessage('Copying not supported with current item type')
+ else:
+ self.ui.statusbar.showMessage('No object selected to copy')
+ self.copiedObject = None
+ self.clearSelection()
+
+ def pasteItem(self):
+ if hasattr(self, 'copiedObject') and not self.copiedObject is None:
+ self.copiedObject = self.copiedObject.copy()
+ self.addInPlace(self.copiedObject)
+ mousePos = self.getWindowCoordinates() - self.copiedObject.path.toQPainterPath().boundingRect().center() - (Qc.QPointF(self.canvSize.width(), self.canvSize.height()) + Qc.QPointF(62, 201))/2 #I don't really know what that last constant is? Is it the size of the framing?
+ newTransform = Qg.QTransform.fromTranslate(mousePos.x(), mousePos.y())
+ self.currentlySelectedObj['selectedIndex'] = (self.globalObjectCounter - 1,0)
+ self.currentlySelectedObj['key'], self.currentlySelectedObj['allSameKey'] = self.selectObjectSet()
+ newTransform = x2a.asyTransform.fromQTransform(newTransform)
+ objKey = self.currentlySelectedObj['selectedIndex']
+ self.addTransformationChanges(objKey, newTransform, not self.useGlobalCoords)
+ self.transformObject(objKey, newTransform, not self.useGlobalCoords)
+ self.quickUpdate()
+ else:
+ self.ui.statusbar.showMessage('No object to paste')
diff --git a/graphics/asymptote/GUI/configs/xasyconfig.cson b/graphics/asymptote/GUI/configs/xasyconfig.cson
index c87f8c5b53..5f0c1abc17 100644
--- a/graphics/asymptote/GUI/configs/xasyconfig.cson
+++ b/graphics/asymptote/GUI/configs/xasyconfig.cson
@@ -45,6 +45,9 @@ gridMinorAxesColor: "#dddddd"
gridMajorAxesSpacing: 5
gridMinorAxesCount: 9
+# Number of pixels per bp in 3D rendered bitmaps
+renderDensity: 2
+
# Magnification Settings
minimumMagnification: 0.01
maximumMagnification: 100
diff --git a/graphics/asymptote/GUI/configs/xasykeymap.cson b/graphics/asymptote/GUI/configs/xasykeymap.cson
index 1e3e3b0a11..867c08db7d 100644
--- a/graphics/asymptote/GUI/configs/xasykeymap.cson
+++ b/graphics/asymptote/GUI/configs/xasykeymap.cson
@@ -23,4 +23,11 @@ scrollLeft: 'Shift+Left'
scrollRight: 'Shift+Right'
zoomIn: 'Ctrl+Up'
-zoomOut: 'Ctrl+Down' \ No newline at end of file
+zoomOut: 'Ctrl+Down'
+
+open: 'Ctrl+O'
+save: 'Ctrl+S'
+export: 'Ctrl+E'
+
+copy: 'Ctrl+C'
+paste: 'Ctrl+V'
diff --git a/graphics/asymptote/GUI/icons_rc.py b/graphics/asymptote/GUI/icons_rc.py
deleted file mode 100644
index e74ded8d75..0000000000
--- a/graphics/asymptote/GUI/icons_rc.py
+++ /dev/null
@@ -1,2721 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Resource object code
-#
-# Created by: The Resource Compiler for PyQt5 (Qt v5.12.5)
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt5 import QtCore
-
-qt_resource_data = b"\
-\x00\x00\x04\xa2\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
-\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
-\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
-\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
-\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
-\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
-\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
-\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
-\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
-\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
-\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
-\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
-\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
-\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\
-\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\
-\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x43\x20\x34\
-\x2e\x31\x35\x35\x35\x36\x20\x2d\x33\x39\x2e\x32\x37\x34\x35\x20\
-\x36\x2e\x39\x38\x34\x37\x33\x20\x2d\x34\x36\x2e\x31\x30\x34\x37\
-\x20\x31\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\
-\x39\x43\x20\x32\x37\x2e\x34\x34\x31\x31\x20\x2d\x36\x37\x2e\x37\
-\x32\x36\x39\x20\x35\x33\x2e\x33\x30\x32\x31\x20\x2d\x36\x31\x2e\
-\x35\x34\x30\x35\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\
-\x2e\x35\x30\x32\x32\x43\x20\x35\x37\x2e\x36\x32\x37\x20\x2d\x33\
-\x32\x2e\x36\x35\x31\x39\x20\x35\x30\x2e\x35\x38\x35\x36\x20\x2d\
-\x32\x33\x2e\x35\x36\x32\x31\x20\x34\x30\x2e\x36\x37\x39\x34\x20\
-\x2d\x32\x32\x2e\x35\x32\x38\x31\x27\x20\x66\x69\x6c\x6c\x3d\x27\
-\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\
-\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\
-\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\
-\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\
-\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\
-\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\
-\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\
-\x32\x2e\x35\x30\x39\x33\x37\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
-\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
-\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
-\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\
-\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\
-\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x33\x2e\x39\x35\x37\x33\
-\x35\x27\x20\x63\x79\x3d\x27\x2d\x33\x32\x2e\x31\x32\x27\x20\x66\
-\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\
-\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
-\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
-\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
-\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\
-\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\
-\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x31\x31\x2e\x39\x30\x33\
-\x36\x27\x20\x63\x79\x3d\x27\x2d\x35\x31\x2e\x33\x30\x33\x39\x27\
-\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\
-\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\
-\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\
-\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
-\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\
-\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\
-\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x35\x36\x2e\x31\
-\x35\x32\x33\x27\x20\x63\x79\x3d\x27\x2d\x34\x32\x2e\x35\x30\x32\
-\x32\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\
-\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\
-\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\
-\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\
-\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\
-\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\
-\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x34\x30\
-\x2e\x36\x37\x39\x34\x27\x20\x63\x79\x3d\x27\x2d\x32\x32\x2e\x35\
-\x32\x38\x31\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\
-\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\
-\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\
-\x3e\
-\x00\x00\x03\x0c\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x43\x68\x65\x63\x6b\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\x79\
-\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\
-\x78\x3d\x22\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\x65\x6e\
-\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\
-\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x20\
-\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\
-\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\
-\x4d\x38\x2e\x32\x39\x34\x2c\x31\x36\x2e\x39\x39\x38\x63\x2d\x30\
-\x2e\x34\x33\x35\x2c\x30\x2d\x30\x2e\x38\x34\x37\x2d\x30\x2e\x32\
-\x30\x33\x2d\x31\x2e\x31\x31\x31\x2d\x30\x2e\x35\x35\x33\x4c\x33\
-\x2e\x36\x31\x2c\x31\x31\x2e\x37\x32\x34\x63\x2d\x30\x2e\x34\x36\
-\x35\x2d\x30\x2e\x36\x31\x33\x2d\x30\x2e\x33\x34\x34\x2d\x31\x2e\
-\x34\x38\x36\x2c\x30\x2e\x32\x37\x2d\x31\x2e\x39\x35\x31\x0d\x0a\
-\x09\x63\x30\x2e\x36\x31\x35\x2d\x30\x2e\x34\x36\x37\x2c\x31\x2e\
-\x34\x38\x38\x2d\x30\x2e\x33\x34\x34\x2c\x31\x2e\x39\x35\x33\x2c\
-\x30\x2e\x32\x37\x6c\x32\x2e\x33\x35\x31\x2c\x33\x2e\x31\x30\x34\
-\x6c\x35\x2e\x39\x31\x31\x2d\x39\x2e\x34\x39\x32\x63\x30\x2e\x34\
-\x30\x37\x2d\x30\x2e\x36\x35\x32\x2c\x31\x2e\x32\x36\x37\x2d\x30\
-\x2e\x38\x35\x32\x2c\x31\x2e\x39\x32\x31\x2d\x30\x2e\x34\x34\x35\
-\x0d\x0a\x09\x63\x30\x2e\x36\x35\x33\x2c\x30\x2e\x34\x30\x36\x2c\
-\x30\x2e\x38\x35\x34\x2c\x31\x2e\x32\x36\x36\x2c\x30\x2e\x34\x34\
-\x36\x2c\x31\x2e\x39\x32\x4c\x39\x2e\x34\x37\x38\x2c\x31\x36\x2e\
-\x33\x34\x63\x2d\x30\x2e\x32\x34\x32\x2c\x30\x2e\x33\x39\x31\x2d\
-\x30\x2e\x36\x36\x31\x2c\x30\x2e\x36\x33\x35\x2d\x31\x2e\x31\x32\
-\x2c\x30\x2e\x36\x35\x36\x43\x38\x2e\x33\x33\x36\x2c\x31\x36\x2e\
-\x39\x39\x38\x2c\x38\x2e\x33\x31\x36\x2c\x31\x36\x2e\x39\x39\x38\
-\x2c\x38\x2e\x32\x39\x34\x2c\x31\x36\x2e\x39\x39\x38\x7a\x22\x2f\
-\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x03\xc4\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4d\x61\x67\x6e\x69\x66\x79\x69\x6e\x67\x5f\x67\x6c\x61\
-\x73\x73\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
-\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\
-\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\
-\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\x6c\x69\x6e\x6b\
-\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x79\x3d\x22\
-\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\
-\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\x6e\x61\x62\x6c\
-\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3d\x22\x6e\x65\
-\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x78\
-\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\
-\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x32\x34\x20\x30\x20\
-\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\x3e\x0d\x0a\x3c\x70\x61\
-\x74\x68\x20\x64\x3d\x22\x4d\x31\x37\x2e\x35\x34\x35\x2c\x31\x35\
-\x2e\x34\x36\x37\x6c\x2d\x33\x2e\x37\x37\x39\x2d\x33\x2e\x37\x37\
-\x39\x63\x30\x2e\x35\x37\x2d\x30\x2e\x39\x33\x35\x2c\x30\x2e\x38\
-\x39\x38\x2d\x32\x2e\x30\x33\x35\x2c\x30\x2e\x38\x39\x38\x2d\x33\
-\x2e\x32\x31\x63\x30\x2d\x33\x2e\x34\x31\x37\x2d\x32\x2e\x39\x36\
-\x31\x2d\x36\x2e\x33\x37\x37\x2d\x36\x2e\x33\x37\x38\x2d\x36\x2e\
-\x33\x37\x37\x0d\x0a\x09\x43\x34\x2e\x38\x36\x39\x2c\x32\x2e\x31\
-\x2c\x32\x2e\x31\x2c\x34\x2e\x38\x37\x2c\x32\x2e\x31\x2c\x38\x2e\
-\x32\x38\x37\x63\x30\x2c\x33\x2e\x34\x31\x36\x2c\x32\x2e\x39\x36\
-\x31\x2c\x36\x2e\x33\x37\x37\x2c\x36\x2e\x33\x37\x37\x2c\x36\x2e\
-\x33\x37\x37\x63\x31\x2e\x31\x33\x37\x2c\x30\x2c\x32\x2e\x32\x2d\
-\x30\x2e\x33\x30\x39\x2c\x33\x2e\x31\x31\x35\x2d\x30\x2e\x38\x34\
-\x34\x6c\x33\x2e\x37\x39\x39\x2c\x33\x2e\x38\x30\x31\x0d\x0a\x09\
-\x63\x30\x2e\x33\x37\x32\x2c\x30\x2e\x33\x37\x31\x2c\x30\x2e\x39\
-\x37\x35\x2c\x30\x2e\x33\x37\x31\x2c\x31\x2e\x33\x34\x36\x2c\x30\
-\x6c\x30\x2e\x39\x34\x33\x2d\x30\x2e\x39\x34\x33\x43\x31\x38\x2e\
-\x30\x35\x31\x2c\x31\x36\x2e\x33\x30\x37\x2c\x31\x37\x2e\x39\x31\
-\x36\x2c\x31\x35\x2e\x38\x33\x38\x2c\x31\x37\x2e\x35\x34\x35\x2c\
-\x31\x35\x2e\x34\x36\x37\x7a\x20\x4d\x34\x2e\x30\x30\x34\x2c\x38\
-\x2e\x32\x38\x37\x0d\x0a\x09\x63\x30\x2d\x32\x2e\x33\x36\x36\x2c\
-\x31\x2e\x39\x31\x37\x2d\x34\x2e\x32\x38\x33\x2c\x34\x2e\x32\x38\
-\x32\x2d\x34\x2e\x32\x38\x33\x63\x32\x2e\x33\x36\x36\x2c\x30\x2c\
-\x34\x2e\x34\x37\x34\x2c\x32\x2e\x31\x30\x37\x2c\x34\x2e\x34\x37\
-\x34\x2c\x34\x2e\x34\x37\x34\x63\x30\x2c\x32\x2e\x33\x36\x35\x2d\
-\x31\x2e\x39\x31\x38\x2c\x34\x2e\x32\x38\x33\x2d\x34\x2e\x32\x38\
-\x33\x2c\x34\x2e\x32\x38\x33\x0d\x0a\x09\x43\x36\x2e\x31\x31\x31\
-\x2c\x31\x32\x2e\x37\x36\x2c\x34\x2e\x30\x30\x34\x2c\x31\x30\x2e\
-\x36\x35\x32\x2c\x34\x2e\x30\x30\x34\x2c\x38\x2e\x32\x38\x37\x7a\
-\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\
-\x3e\x0d\x0a\
-\x00\x00\x01\x69\
-\x3c\
-\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
-\x30\x2f\x73\x76\x67\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x35\x31\
-\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x35\x31\x32\
-\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\
-\x20\x35\x31\x32\x20\x35\x31\x32\x22\x3e\x3c\x67\x20\x74\x72\x61\
-\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x32\
-\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\x3e\x3c\
-\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x2e\x33\x34\x20\x31\x35\
-\x2e\x36\x36\x41\x37\x2e\x39\x37\x20\x37\x2e\x39\x37\x20\x30\x20\
-\x30\x20\x30\x20\x39\x20\x31\x37\x2e\x39\x34\x56\x31\x30\x48\x35\
-\x56\x38\x68\x34\x56\x35\x2e\x38\x33\x61\x33\x20\x33\x20\x30\x20\
-\x31\x20\x31\x20\x32\x20\x30\x56\x38\x68\x34\x76\x32\x68\x2d\x34\
-\x76\x37\x2e\x39\x34\x61\x37\x2e\x39\x37\x20\x37\x2e\x39\x37\x20\
-\x30\x20\x30\x20\x30\x20\x34\x2e\x36\x36\x2d\x32\x2e\x32\x38\x6c\
-\x2d\x31\x2e\x34\x32\x2d\x31\x2e\x34\x32\x68\x35\x2e\x36\x36\x6c\
-\x2d\x32\x2e\x38\x33\x20\x32\x2e\x38\x33\x61\x31\x30\x20\x31\x30\
-\x20\x30\x20\x30\x20\x31\x2d\x31\x34\x2e\x31\x34\x20\x30\x4c\x2e\
-\x31\x20\x31\x34\x2e\x32\x34\x68\x35\x2e\x36\x36\x6c\x2d\x31\x2e\
-\x34\x32\x20\x31\x2e\x34\x32\x7a\x4d\x31\x30\x20\x34\x61\x31\x20\
-\x31\x20\x30\x20\x31\x20\x30\x20\x30\x2d\x32\x20\x31\x20\x31\x20\
-\x30\x20\x30\x20\x30\x20\x30\x20\x32\x7a\x22\x2f\x3e\x3c\x2f\x67\
-\x3e\x3c\x2f\x73\x76\x67\x3e\x0a\
-\x00\x00\x03\x7c\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
-\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
-\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
-\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
-\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
-\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
-\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
-\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
-\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
-\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
-\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
-\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
-\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
-\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\x35\x38\
-\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x32\
-\x2e\x30\x30\x37\x35\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\x36\
-\x32\x2e\x32\x33\x32\x35\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\
-\x36\x32\x2e\x32\x33\x32\x35\x20\x2d\x36\x32\x2e\x32\x33\x32\x35\
-\x4c\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x36\x32\x2e\x32\x33\x32\
-\x35\x4c\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x32\x2e\x30\x30\x37\
-\x35\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\
-\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\
-\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\
-\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\
-\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\
-\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\
-\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\
-\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x34\x2e\x30\x31\x35\x27\
-\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\
-\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\
-\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\
-\x36\x34\x20\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\
-\x35\x38\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\
-\x20\x34\x37\x2e\x31\x37\x36\x32\x20\x2d\x33\x32\x2e\x31\x32\x43\
-\x20\x34\x37\x2e\x31\x37\x36\x32\x20\x2d\x34\x30\x2e\x34\x33\x35\
-\x33\x20\x34\x30\x2e\x34\x33\x35\x33\x20\x2d\x34\x37\x2e\x31\x37\
-\x36\x32\x20\x33\x32\x2e\x31\x32\x20\x2d\x34\x37\x2e\x31\x37\x36\
-\x32\x43\x20\x32\x33\x2e\x38\x30\x34\x37\x20\x2d\x34\x37\x2e\x31\
-\x37\x36\x32\x20\x31\x37\x2e\x30\x36\x33\x37\x20\x2d\x34\x30\x2e\
-\x34\x33\x35\x33\x20\x31\x37\x2e\x30\x36\x33\x37\x20\x2d\x33\x32\
-\x2e\x31\x32\x43\x20\x31\x37\x2e\x30\x36\x33\x37\x20\x2d\x32\x33\
-\x2e\x38\x30\x34\x37\x20\x32\x33\x2e\x38\x30\x34\x37\x20\x2d\x31\
-\x37\x2e\x30\x36\x33\x37\x20\x33\x32\x2e\x31\x32\x20\x2d\x31\x37\
-\x2e\x30\x36\x33\x37\x43\x20\x34\x30\x2e\x34\x33\x35\x33\x20\x2d\
-\x31\x37\x2e\x30\x36\x33\x37\x20\x34\x37\x2e\x31\x37\x36\x32\x20\
-\x2d\x32\x33\x2e\x38\x30\x34\x37\x20\x34\x37\x2e\x31\x37\x36\x32\
-\x20\x2d\x33\x32\x2e\x31\x32\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\
-\x23\x30\x30\x30\x30\x30\x30\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
-\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x02\x21\
-\x00\
-\x00\x07\xaf\x78\x9c\xdd\x55\x4d\x6f\x9c\x30\x10\xbd\xf7\x57\x4c\
-\xd5\x83\xdb\x03\xc6\xdf\x86\x28\x24\x52\x57\xea\x29\xbd\x25\x97\
-\xde\x68\xf0\x82\x9b\x5d\x58\x01\x5d\xb6\xff\xbe\x66\xd7\x60\x4a\
-\xaa\xf4\x92\x43\x15\x90\x30\xf3\x18\xbf\x99\xe7\xf1\x98\xeb\xdb\
-\xd3\x7e\x07\x47\xd3\x76\xb6\xa9\x33\x44\x31\x41\x60\xea\xc7\xa6\
-\xb0\x75\x99\xa1\x87\xfb\x2f\x51\x82\x6e\x6f\xde\x5d\xbf\x8f\x22\
-\xb8\xaf\x6c\x07\x5b\xbb\x33\x30\xe4\x1d\x94\xa6\x36\x6d\xde\x9b\
-\x02\xbe\xff\x82\xe2\x68\xbb\x63\xb9\x07\x86\x13\x88\x22\xe7\xef\
-\xac\x25\x2b\x45\xe0\xe2\xd4\x5d\x86\xaa\xbe\x3f\x5c\xc5\xf1\x30\
-\x0c\x78\xe0\xb8\x69\xcb\x98\x11\x42\x62\xe7\xef\x5d\xae\x4e\x3b\
-\x5b\x3f\xfd\xcd\x91\xa6\x69\x1a\x9f\xbf\x22\x18\x6c\xd1\x57\x19\
-\x52\x1c\x3b\x50\x1d\x7a\x04\x95\xb1\x65\xd5\x4f\x90\x1e\xa1\xa3\
-\x35\xc3\xe7\xe6\x94\x21\xa9\xb0\x20\xa9\x00\xc9\x71\x22\x13\x0e\
-\x7e\x9a\x1f\x35\x72\x09\x97\x60\x8b\x0c\x1d\xf2\xd2\xd0\x8b\xd9\
-\xb7\x79\xdd\x6d\x9b\x76\x9f\xa1\x7d\xde\xb7\xf6\xf4\x91\x38\x67\
-\xc5\x94\x00\x32\xde\x93\x31\x71\x53\xaa\x47\xf2\x4f\xe3\xec\x43\
-\xde\x57\xe0\xe8\xbe\x42\x8a\xb9\xd0\x82\x41\xc4\x38\x26\x94\xde\
-\x05\xc0\xbf\x3c\x47\x36\xcf\x90\x7f\x03\x8b\x39\x12\x53\x29\x29\
-\x05\x9a\x62\x29\x38\x85\x88\x62\x2d\x95\x54\xc0\x19\xa6\x6c\x36\
-\x37\x20\x04\x56\xa9\x4a\x83\x83\x14\x38\x49\x99\x0a\x14\x33\x30\
-\xe7\xfa\x02\x32\x09\x9c\x01\xae\xb0\xd2\x42\x6e\x02\x22\x08\x4e\
-\x94\x4a\x42\x64\xf7\xc2\x94\x14\x53\x6a\xde\xdc\x84\xdc\x27\x87\
-\x59\xdd\x44\x31\x03\x3e\xca\xdd\x7a\xa5\xbf\xa1\x71\xab\xee\x32\
-\xf4\x41\x6f\xc7\x1b\xc5\xae\x2e\x71\xf9\x8a\xa5\x0d\x42\x53\xac\
-\x29\x49\x97\x42\xdd\xbe\x22\x9c\x2d\x84\x6a\xcc\x09\xd5\xb3\xd0\
-\x8b\xb9\x14\xea\x1d\x82\x50\x4f\x11\x84\x4e\x51\x02\x22\xb1\xa4\
-\x89\x0c\x24\x17\x76\x1f\xe3\x3c\x2c\xaa\x7c\x81\x43\xd2\x7e\xf2\
-\x5a\xc5\xbc\x6e\x75\x53\x1b\x04\x5d\xdf\x36\x4f\xc6\xad\x22\x39\
-\x5f\x13\x10\xb9\x2e\x34\x8f\xf9\x21\x43\x6d\xf3\xb3\x2e\xfe\x80\
-\x7f\x34\xb6\x5e\xe3\x7b\xdb\x9b\x76\x67\xdd\xe0\x4e\x03\x82\x09\
-\xd7\x72\xfe\xe6\x5b\x99\xbb\x7c\x38\x65\xaf\x5f\xa7\xf5\x0a\xbe\
-\xe1\x1e\xf4\x0a\xdf\x5c\x09\x5f\x68\x35\xc9\x30\x4b\xf4\xe2\x4c\
-\x51\x0c\x8b\x84\xcf\x67\x8a\x37\x17\xad\x36\x39\x84\x6a\x79\x8a\
-\xf5\x46\xf9\x6f\x96\xf1\xf2\x70\xbf\xc8\x9b\xdf\xf9\x80\xe2\xe1\
-\
-\x00\x00\x04\x1c\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
-\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
-\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
-\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
-\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
-\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
-\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
-\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
-\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
-\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
-\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
-\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
-\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
-\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\x35\x38\
-\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x32\
-\x2e\x30\x30\x37\x35\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\x36\
-\x32\x2e\x32\x33\x32\x35\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\
-\x36\x32\x2e\x32\x33\x32\x35\x20\x2d\x36\x32\x2e\x32\x33\x32\x35\
-\x4c\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x36\x32\x2e\x32\x33\x32\
-\x35\x4c\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x32\x2e\x30\x30\x37\
-\x35\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\
-\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\
-\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\
-\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\
-\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\
-\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\
-\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\
-\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x34\x2e\x30\x31\x35\x27\
-\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\
-\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\
-\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\
-\x36\x34\x20\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\
-\x35\x38\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\
-\x20\x32\x2e\x30\x30\x37\x35\x20\x2d\x33\x32\x2e\x31\x32\x4c\x20\
-\x36\x32\x2e\x32\x33\x32\x35\x20\x2d\x33\x32\x2e\x31\x32\x27\x20\
-\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\
-\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\
-\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\
-\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\
-\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\
-\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\
-\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\
-\x69\x64\x74\x68\x3d\x27\x34\x2e\x30\x31\x35\x27\x2f\x3e\x0a\x3c\
-\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\
-\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\
-\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\
-\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\
-\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\x32\x2e\
-\x31\x32\x20\x2d\x32\x2e\x30\x30\x37\x35\x4c\x20\x33\x32\x2e\x31\
-\x32\x20\x2d\x36\x32\x2e\x32\x33\x32\x35\x27\x20\x66\x69\x6c\x6c\
-\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\
-\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
-\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\
-\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\
-\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\
-\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\
-\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\
-\x3d\x27\x34\x2e\x30\x31\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
-\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x02\xa1\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x53\x61\x76\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\
-\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\
-\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
-\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\
-\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x35\x31\x32\x70\x78\x22\x20\
-\x79\x3d\x22\x35\x31\x32\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\
-\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\
-\x6f\x75\x6e\x64\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\
-\x32\x20\x35\x31\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\
-\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\
-\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\
-\x69\x78\x28\x32\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\
-\x29\x27\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\
-\x35\x2e\x31\x37\x33\x2c\x32\x48\x34\x43\x32\x2e\x38\x39\x39\x2c\
-\x32\x2c\x32\x2c\x32\x2e\x39\x2c\x32\x2c\x34\x76\x31\x32\x63\x30\
-\x2c\x31\x2e\x31\x2c\x30\x2e\x38\x39\x39\x2c\x32\x2c\x32\x2c\x32\
-\x68\x31\x32\x63\x31\x2e\x31\x30\x31\x2c\x30\x2c\x32\x2d\x30\x2e\
-\x39\x2c\x32\x2d\x32\x56\x35\x2e\x31\x32\x37\x4c\x31\x35\x2e\x31\
-\x37\x33\x2c\x32\x7a\x20\x4d\x31\x34\x2c\x38\x63\x30\x2c\x30\x2e\
-\x35\x34\x39\x2d\x30\x2e\x34\x35\x2c\x31\x2d\x31\x2c\x31\x48\x37\
-\x0d\x0a\x09\x43\x36\x2e\x34\x35\x2c\x39\x2c\x36\x2c\x38\x2e\x35\
-\x34\x39\x2c\x36\x2c\x38\x56\x33\x68\x38\x56\x38\x7a\x20\x4d\x31\
-\x33\x2c\x34\x68\x2d\x32\x76\x34\x68\x32\x56\x34\x7a\x22\x2f\x3e\
-\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\
-\x00\x00\x02\xf7\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
-\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
-\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
-\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
-\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
-\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x31\x37\x2e\x34\
-\x2c\x32\x32\x34\x48\x32\x38\x38\x56\x39\x34\x2e\x36\x63\x30\x2d\
-\x31\x36\x2e\x39\x2d\x31\x34\x2e\x33\x2d\x33\x30\x2e\x36\x2d\x33\
-\x32\x2d\x33\x30\x2e\x36\x63\x2d\x31\x37\x2e\x37\x2c\x30\x2d\x33\
-\x32\x2c\x31\x33\x2e\x37\x2d\x33\x32\x2c\x33\x30\x2e\x36\x56\x32\
-\x32\x34\x48\x39\x34\x2e\x36\x43\x37\x37\x2e\x37\x2c\x32\x32\x34\
-\x2c\x36\x34\x2c\x32\x33\x38\x2e\x33\x2c\x36\x34\x2c\x32\x35\x36\
-\x0d\x0a\x09\x63\x30\x2c\x31\x37\x2e\x37\x2c\x31\x33\x2e\x37\x2c\
-\x33\x32\x2c\x33\x30\x2e\x36\x2c\x33\x32\x48\x32\x32\x34\x76\x31\
-\x32\x39\x2e\x34\x63\x30\x2c\x31\x36\x2e\x39\x2c\x31\x34\x2e\x33\
-\x2c\x33\x30\x2e\x36\x2c\x33\x32\x2c\x33\x30\x2e\x36\x63\x31\x37\
-\x2e\x37\x2c\x30\x2c\x33\x32\x2d\x31\x33\x2e\x37\x2c\x33\x32\x2d\
-\x33\x30\x2e\x36\x56\x32\x38\x38\x68\x31\x32\x39\x2e\x34\x63\x31\
-\x36\x2e\x39\x2c\x30\x2c\x33\x30\x2e\x36\x2d\x31\x34\x2e\x33\x2c\
-\x33\x30\x2e\x36\x2d\x33\x32\x0d\x0a\x09\x43\x34\x34\x38\x2c\x32\
-\x33\x38\x2e\x33\x2c\x34\x33\x34\x2e\x33\x2c\x32\x32\x34\x2c\x34\
-\x31\x37\x2e\x34\x2c\x32\x32\x34\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\
-\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x03\x22\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x22\x32\x35\x36\x22\
-\x20\x63\x79\x3d\x22\x32\x38\x30\x22\x20\x72\x3d\x22\x36\x33\x22\
-\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\
-\x34\x30\x2c\x39\x36\x68\x2d\x38\x38\x6c\x2d\x33\x32\x2d\x33\x32\
-\x48\x31\x39\x32\x6c\x2d\x33\x32\x2c\x33\x32\x48\x37\x32\x63\x2d\
-\x32\x32\x2e\x30\x39\x32\x2c\x30\x2d\x34\x30\x2c\x31\x37\x2e\x39\
-\x30\x38\x2d\x34\x30\x2c\x34\x30\x76\x32\x37\x32\x63\x30\x2c\x32\
-\x32\x2e\x30\x39\x32\x2c\x31\x37\x2e\x39\x30\x38\x2c\x34\x30\x2c\
-\x34\x30\x2c\x34\x30\x68\x33\x36\x38\x63\x32\x32\x2e\x30\x39\x32\
-\x2c\x30\x2c\x34\x30\x2d\x31\x37\x2e\x39\x30\x38\x2c\x34\x30\x2d\
-\x34\x30\x0d\x0a\x09\x09\x56\x31\x33\x36\x43\x34\x38\x30\x2c\x31\
-\x31\x33\x2e\x39\x30\x38\x2c\x34\x36\x32\x2e\x30\x39\x32\x2c\x39\
-\x36\x2c\x34\x34\x30\x2c\x39\x36\x7a\x20\x4d\x32\x35\x36\x2c\x33\
-\x39\x32\x63\x2d\x36\x31\x2e\x38\x35\x35\x2c\x30\x2d\x31\x31\x32\
-\x2d\x35\x30\x2e\x31\x34\x35\x2d\x31\x31\x32\x2d\x31\x31\x32\x73\
-\x35\x30\x2e\x31\x34\x35\x2d\x31\x31\x32\x2c\x31\x31\x32\x2d\x31\
-\x31\x32\x73\x31\x31\x32\x2c\x35\x30\x2e\x31\x34\x35\x2c\x31\x31\
-\x32\x2c\x31\x31\x32\x0d\x0a\x09\x09\x53\x33\x31\x37\x2e\x38\x35\
-\x35\x2c\x33\x39\x32\x2c\x32\x35\x36\x2c\x33\x39\x32\x7a\x22\x2f\
-\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
-\x0a\
-\x00\x00\x02\xfc\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x32\x30\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
-\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
-\x35\x36\x2c\x34\x38\x43\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\
-\x2c\x34\x38\x2c\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x32\
-\x35\x36\x73\x39\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\x2c\x32\x30\
-\x38\x2c\x32\x30\x38\x73\x32\x30\x38\x2d\x39\x33\x2e\x36\x30\x31\
-\x2c\x32\x30\x38\x2d\x32\x30\x38\x53\x33\x37\x30\x2e\x33\x39\x39\
-\x2c\x34\x38\x2c\x32\x35\x36\x2c\x34\x38\x7a\x20\x4d\x32\x35\x36\
-\x2c\x34\x32\x32\x2e\x33\x39\x39\x0d\x0a\x09\x09\x09\x63\x2d\x39\
-\x31\x2e\x35\x31\x38\x2c\x30\x2d\x31\x36\x36\x2e\x33\x39\x39\x2d\
-\x37\x34\x2e\x38\x38\x32\x2d\x31\x36\x36\x2e\x33\x39\x39\x2d\x31\
-\x36\x36\x2e\x33\x39\x39\x53\x31\x36\x34\x2e\x34\x38\x32\x2c\x38\
-\x39\x2e\x36\x2c\x32\x35\x36\x2c\x38\x39\x2e\x36\x53\x34\x32\x32\
-\x2e\x34\x2c\x31\x36\x34\x2e\x34\x38\x32\x2c\x34\x32\x32\x2e\x34\
-\x2c\x32\x35\x36\x53\x33\x34\x37\x2e\x35\x31\x38\x2c\x34\x32\x32\
-\x2e\x33\x39\x39\x2c\x32\x35\x36\x2c\x34\x32\x32\x2e\x33\x39\x39\
-\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\
-\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x03\xf5\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x43\x68\x65\x76\x72\x6f\x6e\x5f\x63\x69\x72\x63\x6c\x65\
-\x64\x5f\x6c\x65\x66\x74\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\
-\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\
-\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
-\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\
-\x6c\x69\x6e\x6b\x22\x0d\x0a\x09\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x74\x72\x61\
-\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x32\
-\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\x3e\x0d\
-\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x31\x2e\x33\x30\
-\x32\x2c\x36\x2e\x37\x37\x36\x63\x2d\x30\x2e\x31\x39\x36\x2d\x30\
-\x2e\x31\x39\x37\x2d\x30\x2e\x35\x31\x35\x2d\x30\x2e\x31\x39\x37\
-\x2d\x30\x2e\x37\x31\x2c\x30\x4c\x37\x2e\x37\x38\x35\x2c\x39\x2e\
-\x36\x34\x31\x63\x2d\x30\x2e\x31\x39\x36\x2c\x30\x2e\x31\x39\x39\
-\x2d\x30\x2e\x31\x39\x36\x2c\x30\x2e\x35\x32\x2c\x30\x2c\x30\x2e\
-\x37\x31\x37\x6c\x32\x2e\x38\x30\x37\x2c\x32\x2e\x38\x36\x34\x0d\
-\x0a\x09\x63\x30\x2e\x31\x39\x35\x2c\x30\x2e\x31\x39\x39\x2c\x30\
-\x2e\x35\x31\x34\x2c\x30\x2e\x31\x39\x38\x2c\x30\x2e\x37\x31\x2c\
-\x30\x63\x30\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2c\x30\x2e\
-\x31\x39\x36\x2d\x30\x2e\x35\x31\x38\x2c\x30\x2d\x30\x2e\x37\x31\
-\x37\x4c\x39\x2c\x31\x30\x6c\x32\x2e\x33\x30\x32\x2d\x32\x2e\x35\
-\x30\x36\x43\x31\x31\x2e\x34\x39\x38\x2c\x37\x2e\x32\x39\x36\x2c\
-\x31\x31\x2e\x34\x39\x38\x2c\x36\x2e\x39\x37\x36\x2c\x31\x31\x2e\
-\x33\x30\x32\x2c\x36\x2e\x37\x37\x36\x7a\x0d\x0a\x09\x20\x4d\x31\
-\x30\x2c\x30\x2e\x34\x63\x2d\x35\x2e\x33\x30\x32\x2c\x30\x2d\x39\
-\x2e\x36\x2c\x34\x2e\x32\x39\x38\x2d\x39\x2e\x36\x2c\x39\x2e\x36\
-\x63\x30\x2c\x35\x2e\x33\x30\x33\x2c\x34\x2e\x32\x39\x38\x2c\x39\
-\x2e\x36\x2c\x39\x2e\x36\x2c\x39\x2e\x36\x73\x39\x2e\x36\x2d\x34\
-\x2e\x32\x39\x37\x2c\x39\x2e\x36\x2d\x39\x2e\x36\x43\x31\x39\x2e\
-\x36\x2c\x34\x2e\x36\x39\x38\x2c\x31\x35\x2e\x33\x30\x32\x2c\x30\
-\x2e\x34\x2c\x31\x30\x2c\x30\x2e\x34\x7a\x20\x4d\x31\x30\x2c\x31\
-\x38\x2e\x33\x35\x34\x0d\x0a\x09\x63\x2d\x34\x2e\x36\x31\x35\x2c\
-\x30\x2d\x38\x2e\x33\x35\x34\x2d\x33\x2e\x37\x34\x2d\x38\x2e\x33\
-\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x30\x2d\x34\x2e\x36\x31\x34\
-\x2c\x33\x2e\x37\x33\x39\x2d\x38\x2e\x33\x35\x34\x2c\x38\x2e\x33\
-\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x34\x2e\x36\x31\x33\x2c\x30\
-\x2c\x38\x2e\x33\x35\x34\x2c\x33\x2e\x37\x34\x2c\x38\x2e\x33\x35\
-\x34\x2c\x38\x2e\x33\x35\x34\x0d\x0a\x09\x43\x31\x38\x2e\x33\x35\
-\x34\x2c\x31\x34\x2e\x36\x31\x34\x2c\x31\x34\x2e\x36\x31\x33\x2c\
-\x31\x38\x2e\x33\x35\x34\x2c\x31\x30\x2c\x31\x38\x2e\x33\x35\x34\
-\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\
-\x67\x3e\x0d\x0a\
-\x00\x00\x02\xb7\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x35\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
-\x0d\x0a\x09\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\
-\x6e\x74\x73\x3d\x22\x34\x30\x35\x2c\x31\x33\x36\x2e\x37\x39\x38\
-\x20\x33\x37\x35\x2e\x32\x30\x32\x2c\x31\x30\x37\x20\x32\x35\x36\
-\x2c\x32\x32\x36\x2e\x32\x30\x32\x20\x31\x33\x36\x2e\x37\x39\x38\
-\x2c\x31\x30\x37\x20\x31\x30\x37\x2c\x31\x33\x36\x2e\x37\x39\x38\
-\x20\x32\x32\x36\x2e\x32\x30\x32\x2c\x32\x35\x36\x20\x31\x30\x37\
-\x2c\x33\x37\x35\x2e\x32\x30\x32\x20\x31\x33\x36\x2e\x37\x39\x38\
-\x2c\x34\x30\x35\x20\x32\x35\x36\x2c\x32\x38\x35\x2e\x37\x39\x38\
-\x20\x0d\x0a\x09\x09\x09\x33\x37\x35\x2e\x32\x30\x32\x2c\x34\x30\
-\x35\x20\x34\x30\x35\x2c\x33\x37\x35\x2e\x32\x30\x32\x20\x32\x38\
-\x35\x2e\x37\x39\x38\x2c\x32\x35\x36\x20\x09\x09\x22\x2f\x3e\x0d\
-\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
-\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x04\xca\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\x72\
-\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\x75\
-\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x39\x2e\x32\x2e\x31\x2c\x20\
-\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\x2d\
-\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\x6e\
-\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\x20\
-\x20\x2d\x2d\x3e\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\x20\x73\
-\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\x57\x33\
-\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\x2f\x2f\
-\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\
-\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\x73\x2f\
-\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\x67\x31\
-\x31\x2e\x64\x74\x64\x22\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\
-\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x0a\x09\x20\x69\x64\x3d\
-\x22\x73\x76\x67\x34\x36\x31\x39\x22\x20\x69\x6e\x6b\x73\x63\x61\
-\x70\x65\x3a\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x30\x2e\x39\x31\
-\x2b\x64\x65\x76\x65\x6c\x2b\x6f\x73\x78\x6d\x65\x6e\x75\x20\x72\
-\x31\x32\x39\x31\x31\x22\x20\x73\x6f\x64\x69\x70\x6f\x64\x69\x3a\
-\x64\x6f\x63\x6e\x61\x6d\x65\x3d\x22\x74\x72\x69\x61\x6e\x67\x6c\
-\x65\x2d\x73\x74\x72\x6f\x6b\x65\x64\x2d\x31\x35\x2e\x73\x76\x67\
-\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x63\x63\x3d\x22\x68\x74\x74\x70\
-\x3a\x2f\x2f\x63\x72\x65\x61\x74\x69\x76\x65\x63\x6f\x6d\x6d\x6f\
-\x6e\x73\x2e\x6f\x72\x67\x2f\x6e\x73\x23\x22\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x64\x63\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x70\x75\x72\
-\x6c\x2e\x6f\x72\x67\x2f\x64\x63\x2f\x65\x6c\x65\x6d\x65\x6e\x74\
-\x73\x2f\x31\x2e\x31\x2f\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x69\x6e\
-\x6b\x73\x63\x61\x70\x65\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
-\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\x6f\x72\x67\x2f\
-\x6e\x61\x6d\x65\x73\x70\x61\x63\x65\x73\x2f\x69\x6e\x6b\x73\x63\
-\x61\x70\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3a\x72\x64\x66\x3d\x22\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x31\x39\x39\x39\x2f\x30\x32\x2f\x32\x32\x2d\x72\x64\x66\
-\x2d\x73\x79\x6e\x74\x61\x78\x2d\x6e\x73\x23\x22\x20\x78\x6d\x6c\
-\x6e\x73\x3a\x73\x6f\x64\x69\x70\x6f\x64\x69\x3d\x22\x68\x74\x74\
-\x70\x3a\x2f\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2e\x73\x6f\x75\
-\x72\x63\x65\x66\x6f\x72\x67\x65\x2e\x6e\x65\x74\x2f\x44\x54\x44\
-\x2f\x73\x6f\x64\x69\x70\x6f\x64\x69\x2d\x30\x2e\x64\x74\x64\x22\
-\x20\x78\x6d\x6c\x6e\x73\x3a\x73\x76\x67\x3d\x22\x68\x74\x74\x70\
-\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\
-\x30\x30\x2f\x73\x76\x67\x22\x0a\x09\x20\x78\x6d\x6c\x6e\x73\x3d\
-\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\
-\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\
-\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\
-\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\
-\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\x20\
-\x79\x3d\x22\x30\x70\x78\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x36\
-\x34\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x36\x34\x70\
-\x78\x22\x0a\x09\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\
-\x30\x20\x31\x35\x20\x31\x35\x22\x20\x73\x74\x79\x6c\x65\x3d\x22\
-\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
-\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\x31\x35\x20\x31\x35\x3b\
-\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\x65\
-\x73\x65\x72\x76\x65\x22\x3e\x0a\x3c\x70\x61\x74\x68\x20\x69\x64\
-\x3d\x22\x72\x65\x63\x74\x33\x33\x33\x38\x22\x20\x69\x6e\x6b\x73\
-\x63\x61\x70\x65\x3a\x63\x6f\x6e\x6e\x65\x63\x74\x6f\x72\x2d\x63\
-\x75\x72\x76\x61\x74\x75\x72\x65\x3d\x22\x30\x22\x20\x73\x6f\x64\
-\x69\x70\x6f\x64\x69\x3a\x6e\x6f\x64\x65\x74\x79\x70\x65\x73\x3d\
-\x22\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x63\x22\x20\x64\
-\x3d\x22\x4d\x37\x2e\x35\x32\x34\x33\x2c\x31\x2e\x35\x30\x30\x34\
-\x0a\x09\x43\x37\x2e\x32\x34\x32\x39\x2c\x31\x2e\x34\x39\x31\x33\
-\x2c\x36\x2e\x39\x37\x38\x37\x2c\x31\x2e\x36\x34\x32\x33\x2c\x36\
-\x2e\x38\x33\x33\x36\x2c\x31\x2e\x38\x39\x35\x32\x6c\x2d\x35\x2e\
-\x35\x2c\x39\x2e\x38\x36\x39\x32\x43\x31\x2e\x30\x32\x31\x38\x2c\
-\x31\x32\x2e\x33\x30\x37\x38\x2c\x31\x2e\x33\x39\x35\x2c\x31\x32\
-\x2e\x39\x39\x39\x39\x2c\x32\x2c\x31\x33\x68\x31\x31\x0a\x09\x63\
-\x30\x2e\x36\x30\x35\x2d\x30\x2e\x30\x30\x30\x31\x2c\x30\x2e\x39\
-\x37\x38\x32\x2d\x30\x2e\x36\x39\x32\x32\x2c\x30\x2e\x36\x36\x36\
-\x34\x2d\x31\x2e\x32\x33\x35\x35\x6c\x2d\x35\x2e\x35\x2d\x39\x2e\
-\x38\x36\x39\x32\x43\x38\x2e\x30\x33\x30\x32\x2c\x31\x2e\x36\x35\
-\x37\x39\x2c\x37\x2e\x37\x38\x38\x34\x2c\x31\x2e\x35\x30\x39\x32\
-\x2c\x37\x2e\x35\x32\x34\x33\x2c\x31\x2e\x35\x30\x30\x34\x7a\x20\
-\x4d\x37\x2e\x35\x2c\x33\x2e\x38\x39\x39\x33\x6c\x34\x2e\x31\x32\
-\x36\x37\x2c\x37\x2e\x34\x37\x30\x34\x0a\x09\x48\x33\x2e\x33\x37\
-\x33\x33\x4c\x37\x2e\x35\x2c\x33\x2e\x38\x39\x39\x33\x7a\x22\x2f\
-\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\
-\x00\x00\x01\xdd\
-\x00\
-\x00\x06\xe4\x78\x9c\xcd\x54\x4d\x6f\x9b\x40\x10\x3d\x13\x29\xff\
-\x61\xba\xb7\x4a\xec\x17\xc4\xd4\xa6\xa6\x51\xfd\x21\xcb\x52\x9a\
-\x58\x6a\xea\xaa\xa7\x0a\xc3\x16\x50\x28\x20\x58\xc0\xce\xaf\xef\
-\xee\x92\x54\x51\x95\xfa\x18\xfb\xb0\x33\xda\x79\x6f\xde\xbc\x65\
-\x24\xa6\xd7\xfb\xdf\x39\x74\xa2\x6e\xb2\xb2\x08\x10\x27\x0c\x81\
-\x28\xa2\x32\xce\x8a\x24\x40\xad\xfc\x85\xc7\xe8\xfa\xd3\xe5\xc5\
-\xf4\x1d\xc6\xb0\x12\x85\xa8\x43\x59\xd6\x3e\x7c\x8e\xcb\x9d\x80\
-\x75\x9e\xb7\x8d\x34\x25\xe0\x1e\x71\x08\xb7\xe1\xeb\x76\x05\xcb\
-\x7d\x55\xd6\x12\x36\x79\x9b\xe0\x75\x01\xc4\x14\xb7\xc3\x10\x1f\
-\x3c\xc2\x18\xcc\xda\x2c\x8f\x81\xbd\x07\xc0\xd8\xe8\x2f\xee\xe6\
-\xf7\x3f\x36\x4b\x68\xba\x04\x36\xdf\x66\x37\xeb\x39\x20\x4c\xe9\
-\x77\x77\x4e\xe9\xe2\x7e\x61\x24\x38\xe1\x94\x2e\x6f\x11\xa0\x54\
-\xca\xca\xa7\xb4\xef\x7b\xd2\xbb\xa4\xac\x13\xba\xaa\xc3\x2a\xcd\
-\xa2\x86\x2a\x22\xd5\x44\xd5\x44\x95\x18\xe7\x24\x96\x31\xd2\x33\
-\xb4\xf4\x8b\xa7\x72\x04\x59\x1c\xa0\x9b\xf0\x20\xea\x9f\xea\xa2\
-\xbe\x44\xd1\x04\xaf\x48\x3b\x8c\x31\x2d\xf5\x44\xf1\xf7\x79\x56\
-\x3c\xbc\x46\xe4\x93\xc9\x84\x1a\x54\x51\x03\xc4\xaa\x3d\x82\xc3\
-\x90\x2f\x2f\x2c\xe8\xb3\x58\xa6\x01\x1a\x71\x47\x03\xa9\xc8\x92\
-\x54\xfe\xbd\x76\x99\xe8\x67\xa5\xee\x02\x06\xaa\xa6\x0f\x82\x46\
-\x1e\x72\x11\x20\x51\x84\xbb\x5c\xe0\x5d\x18\x3d\x24\x75\xd9\x16\
-\xb1\x5f\x88\x1e\x5e\x30\x3f\x1a\x6f\x7e\x53\x85\x91\xa2\x57\xb5\
-\x68\x44\xdd\x09\xf3\xea\x44\x05\x6b\x88\xd6\xb4\x0a\x65\x0a\xea\
-\xd1\x5f\xb8\xc7\x6c\x3e\x72\x89\x1b\x31\xdb\x25\x1f\xb0\x6b\x7b\
-\x2a\xaa\xa3\x73\x8a\x47\x8c\x8c\x22\xac\x00\x9b\xe9\x22\x76\xf1\
-\x13\xdc\x0d\x10\x33\x98\xfb\xdc\xa0\x73\x6a\x00\xd3\xa2\x4b\xb6\
-\x51\xd4\x67\x6b\xe6\x3c\xea\x4f\x60\x59\xf4\x1f\x1f\xce\x78\x7c\
-\x16\x3e\xae\xb8\x77\x3a\x1f\x53\xfa\xff\x25\x39\x63\xfe\x26\xa6\
-\xcc\x9c\x23\x4b\x3a\x07\x1f\x7a\x49\x27\xf3\x71\x6c\x49\x57\x6c\
-\xf2\x26\xa6\xcc\x9c\x23\x4b\x3a\x07\x1f\x7a\x49\x27\xf3\x31\x2c\
-\xe9\x39\xaa\x7f\xb6\xca\x7f\x00\x99\x18\x96\x19\
-\x00\x00\x03\x46\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
-\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
-\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
-\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
-\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
-\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x33\x37\x2e\x35\
-\x2c\x33\x38\x36\x2e\x36\x4c\x33\x30\x36\x2e\x39\x2c\x32\x35\x36\
-\x6c\x31\x33\x30\x2e\x36\x2d\x31\x33\x30\x2e\x36\x63\x31\x34\x2e\
-\x31\x2d\x31\x34\x2e\x31\x2c\x31\x34\x2e\x31\x2d\x33\x36\x2e\x38\
-\x2c\x30\x2d\x35\x30\x2e\x39\x63\x2d\x31\x34\x2e\x31\x2d\x31\x34\
-\x2e\x31\x2d\x33\x36\x2e\x38\x2d\x31\x34\x2e\x31\x2d\x35\x30\x2e\
-\x39\x2c\x30\x4c\x32\x35\x36\x2c\x32\x30\x35\x2e\x31\x4c\x31\x32\
-\x35\x2e\x34\x2c\x37\x34\x2e\x35\x0d\x0a\x09\x63\x2d\x31\x34\x2e\
-\x31\x2d\x31\x34\x2e\x31\x2d\x33\x36\x2e\x38\x2d\x31\x34\x2e\x31\
-\x2d\x35\x30\x2e\x39\x2c\x30\x63\x2d\x31\x34\x2e\x31\x2c\x31\x34\
-\x2e\x31\x2d\x31\x34\x2e\x31\x2c\x33\x36\x2e\x38\x2c\x30\x2c\x35\
-\x30\x2e\x39\x4c\x32\x30\x35\x2e\x31\x2c\x32\x35\x36\x4c\x37\x34\
-\x2e\x35\x2c\x33\x38\x36\x2e\x36\x63\x2d\x31\x34\x2e\x31\x2c\x31\
-\x34\x2e\x31\x2d\x31\x34\x2e\x31\x2c\x33\x36\x2e\x38\x2c\x30\x2c\
-\x35\x30\x2e\x39\x0d\x0a\x09\x63\x31\x34\x2e\x31\x2c\x31\x34\x2e\
-\x31\x2c\x33\x36\x2e\x38\x2c\x31\x34\x2e\x31\x2c\x35\x30\x2e\x39\
-\x2c\x30\x4c\x32\x35\x36\x2c\x33\x30\x36\x2e\x39\x6c\x31\x33\x30\
-\x2e\x36\x2c\x31\x33\x30\x2e\x36\x63\x31\x34\x2e\x31\x2c\x31\x34\
-\x2e\x31\x2c\x33\x36\x2e\x38\x2c\x31\x34\x2e\x31\x2c\x35\x30\x2e\
-\x39\x2c\x30\x43\x34\x35\x31\x2e\x35\x2c\x34\x32\x33\x2e\x34\x2c\
-\x34\x35\x31\x2e\x35\x2c\x34\x30\x30\x2e\x36\x2c\x34\x33\x37\x2e\
-\x35\x2c\x33\x38\x36\x2e\x36\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\
-\x76\x67\x3e\x0d\x0a\
-\x00\x00\x03\x26\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x35\x36\x2c\x33\x38\
-\x38\x63\x2d\x37\x32\x2e\x35\x39\x37\x2c\x30\x2d\x31\x33\x32\x2d\
-\x35\x39\x2e\x34\x30\x35\x2d\x31\x33\x32\x2d\x31\x33\x32\x63\x30\
-\x2d\x37\x32\x2e\x36\x30\x31\x2c\x35\x39\x2e\x34\x30\x33\x2d\x31\
-\x33\x32\x2c\x31\x33\x32\x2d\x31\x33\x32\x63\x33\x36\x2e\x33\x2c\
-\x30\x2c\x36\x39\x2e\x32\x39\x39\x2c\x31\x35\x2e\x34\x2c\x39\x32\
-\x2e\x34\x30\x36\x2c\x33\x39\x2e\x36\x30\x31\x4c\x32\x37\x38\x2c\
-\x32\x33\x34\x68\x31\x35\x34\x56\x38\x30\x0d\x0a\x09\x09\x6c\x2d\
-\x35\x31\x2e\x36\x39\x38\x2c\x35\x31\x2e\x37\x30\x32\x43\x33\x34\
-\x38\x2e\x34\x30\x36\x2c\x39\x39\x2e\x37\x39\x38\x2c\x33\x30\x34\
-\x2e\x34\x30\x36\x2c\x38\x30\x2c\x32\x35\x36\x2c\x38\x30\x63\x2d\
-\x39\x36\x2e\x37\x39\x37\x2c\x30\x2d\x31\x37\x36\x2c\x37\x39\x2e\
-\x32\x30\x33\x2d\x31\x37\x36\x2c\x31\x37\x36\x73\x37\x38\x2e\x30\
-\x39\x34\x2c\x31\x37\x36\x2c\x31\x37\x36\x2c\x31\x37\x36\x0d\x0a\
-\x09\x09\x63\x38\x31\x2e\x30\x34\x35\x2c\x30\x2c\x31\x34\x38\x2e\
-\x32\x38\x37\x2d\x35\x34\x2e\x31\x33\x34\x2c\x31\x36\x39\x2e\x34\
-\x30\x31\x2d\x31\x32\x38\x48\x33\x37\x38\x2e\x38\x35\x43\x33\x36\
-\x30\x2e\x31\x30\x35\x2c\x33\x35\x33\x2e\x35\x36\x31\x2c\x33\x31\
-\x31\x2e\x37\x31\x32\x2c\x33\x38\x38\x2c\x32\x35\x36\x2c\x33\x38\
-\x38\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
-\x76\x67\x3e\x0d\x0a\
-\x00\x00\x05\xd4\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
-\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
-\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
-\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
-\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
-\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
-\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
-\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
-\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
-\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
-\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
-\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
-\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
-\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x35\x36\x2e\x34\x30\x39\x34\x20\x31\x31\x37\x2e\x38\x35\x38\
-\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x35\
-\x34\x2e\x38\x39\x32\x36\x20\x2d\x33\x39\x2e\x37\x31\x30\x39\x43\
-\x20\x35\x34\x2e\x38\x39\x32\x36\x20\x2d\x34\x33\x2e\x39\x30\x33\
-\x32\x20\x34\x34\x2e\x36\x39\x36\x39\x20\x2d\x34\x37\x2e\x33\x30\
-\x31\x37\x20\x33\x32\x2e\x31\x32\x20\x2d\x34\x37\x2e\x33\x30\x31\
-\x37\x43\x20\x31\x39\x2e\x35\x34\x33\x31\x20\x2d\x34\x37\x2e\x33\
-\x30\x31\x37\x20\x39\x2e\x33\x34\x37\x34\x32\x20\x2d\x34\x33\x2e\
-\x39\x30\x33\x32\x20\x39\x2e\x33\x34\x37\x34\x32\x20\x2d\x33\x39\
-\x2e\x37\x31\x30\x39\x43\x20\x39\x2e\x33\x34\x37\x34\x32\x20\x2d\
-\x33\x35\x2e\x35\x31\x38\x35\x20\x31\x39\x2e\x35\x34\x33\x31\x20\
-\x2d\x33\x32\x2e\x31\x32\x20\x33\x32\x2e\x31\x32\x20\x2d\x33\x32\
-\x2e\x31\x32\x43\x20\x34\x34\x2e\x36\x39\x36\x39\x20\x2d\x33\x32\
-\x2e\x31\x32\x20\x35\x34\x2e\x38\x39\x32\x36\x20\x2d\x33\x35\x2e\
-\x35\x31\x38\x35\x20\x35\x34\x2e\x38\x39\x32\x36\x20\x2d\x33\x39\
-\x2e\x37\x31\x30\x39\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\
-\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\
-\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\
-\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\
-\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\
-\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\
-\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\
-\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x33\x2e\
-\x35\x31\x33\x31\x32\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\
-\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\
-\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\
-\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x36\x2e\x34\x30\x39\x34\
-\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x70\x61\x74\
-\x68\x20\x64\x3d\x27\x4d\x20\x39\x2e\x33\x34\x37\x34\x32\x20\x2d\
-\x33\x39\x2e\x37\x31\x30\x39\x4c\x20\x39\x2e\x33\x34\x37\x34\x32\
-\x20\x2d\x39\x2e\x33\x34\x37\x34\x32\x4c\x20\x39\x2e\x33\x34\x37\
-\x34\x32\x20\x2d\x39\x2e\x33\x34\x37\x34\x32\x43\x20\x39\x2e\x33\
-\x34\x37\x34\x32\x20\x2d\x39\x2e\x33\x34\x37\x34\x32\x20\x39\x2e\
-\x33\x34\x37\x34\x32\x20\x2d\x39\x2e\x33\x34\x37\x34\x32\x20\x39\
-\x2e\x33\x34\x37\x34\x32\x20\x2d\x39\x2e\x33\x34\x37\x34\x32\x43\
-\x20\x39\x2e\x33\x34\x37\x34\x32\x20\x2d\x35\x2e\x31\x35\x35\x31\
-\x31\x20\x31\x39\x2e\x35\x34\x33\x31\x20\x2d\x31\x2e\x37\x35\x36\
-\x35\x36\x20\x33\x32\x2e\x31\x32\x20\x2d\x31\x2e\x37\x35\x36\x35\
-\x36\x43\x20\x34\x34\x2e\x36\x39\x36\x39\x20\x2d\x31\x2e\x37\x35\
-\x36\x35\x36\x20\x35\x34\x2e\x38\x39\x32\x36\x20\x2d\x35\x2e\x31\
-\x35\x35\x31\x31\x20\x35\x34\x2e\x38\x39\x32\x36\x20\x2d\x39\x2e\
-\x33\x34\x37\x34\x32\x4c\x20\x35\x34\x2e\x38\x39\x32\x36\x20\x2d\
-\x39\x2e\x33\x34\x37\x34\x32\x4c\x20\x35\x34\x2e\x38\x39\x32\x36\
-\x20\x2d\x33\x39\x2e\x37\x31\x30\x39\x27\x20\x66\x69\x6c\x6c\x3d\
-\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\
-\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\
-\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\
-\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\
-\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\
-\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\
-\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\
-\x27\x33\x2e\x35\x31\x33\x31\x32\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\
-\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\
-\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\
-\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x36\x2e\x34\
-\x30\x39\x34\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\
-\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x35\x34\x2e\x38\x39\x32\
-\x36\x20\x2d\x33\x39\x2e\x37\x31\x30\x39\x43\x20\x35\x34\x2e\x38\
-\x39\x32\x36\x20\x2d\x35\x32\x2e\x32\x38\x37\x38\x20\x34\x34\x2e\
-\x36\x39\x36\x39\x20\x2d\x36\x32\x2e\x34\x38\x33\x34\x20\x33\x32\
-\x2e\x31\x32\x20\x2d\x36\x32\x2e\x34\x38\x33\x34\x43\x20\x31\x39\
-\x2e\x35\x34\x33\x31\x20\x2d\x36\x32\x2e\x34\x38\x33\x34\x20\x39\
-\x2e\x33\x34\x37\x34\x32\x20\x2d\x35\x32\x2e\x32\x38\x37\x38\x20\
-\x39\x2e\x33\x34\x37\x34\x32\x20\x2d\x33\x39\x2e\x37\x31\x30\x39\
-\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\
-\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\
-\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\
-\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\
-\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\
-\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\
-\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\
-\x2d\x77\x69\x64\x74\x68\x3d\x27\x33\x2e\x35\x31\x33\x31\x32\x27\
-\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\
-\x76\x67\x3e\
-\x00\x00\x03\xe6\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x43\x68\x65\x76\x72\x6f\x6e\x5f\x63\x69\x72\x63\x6c\x65\
-\x64\x5f\x72\x69\x67\x68\x74\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x22\x0d\x0a\x09\x20\x78\x3d\x22\x30\x70\x78\
-\x22\x20\x79\x3d\x22\x30\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\
-\x78\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\
-\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\
-\x64\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\
-\x31\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\
-\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x74\x72\
-\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\
-\x32\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\x3e\
-\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x31\x2c\x31\
-\x30\x4c\x38\x2e\x36\x39\x38\x2c\x37\x2e\x34\x39\x34\x63\x2d\x30\
-\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x38\x2d\x30\x2e\x31\x39\x36\
-\x2d\x30\x2e\x35\x31\x39\x2c\x30\x2d\x30\x2e\x37\x31\x38\x63\x30\
-\x2e\x31\x39\x36\x2d\x30\x2e\x31\x39\x37\x2c\x30\x2e\x35\x31\x35\
-\x2d\x30\x2e\x31\x39\x37\x2c\x30\x2e\x37\x31\x2c\x30\x6c\x32\x2e\
-\x38\x30\x37\x2c\x32\x2e\x38\x36\x34\x0d\x0a\x09\x63\x30\x2e\x31\
-\x39\x36\x2c\x30\x2e\x31\x39\x39\x2c\x30\x2e\x31\x39\x36\x2c\x30\
-\x2e\x35\x32\x2c\x30\x2c\x30\x2e\x37\x31\x37\x6c\x2d\x32\x2e\x38\
-\x30\x37\x2c\x32\x2e\x38\x36\x34\x63\x2d\x30\x2e\x31\x39\x35\x2c\
-\x30\x2e\x31\x39\x39\x2d\x30\x2e\x35\x31\x34\x2c\x30\x2e\x31\x39\
-\x38\x2d\x30\x2e\x37\x31\x2c\x30\x63\x2d\x30\x2e\x31\x39\x36\x2d\
-\x30\x2e\x31\x39\x37\x2d\x30\x2e\x31\x39\x36\x2d\x30\x2e\x35\x31\
-\x38\x2c\x30\x2d\x30\x2e\x37\x31\x37\x4c\x31\x31\x2c\x31\x30\x7a\
-\x20\x4d\x31\x30\x2c\x30\x2e\x34\x0d\x0a\x09\x63\x35\x2e\x33\x30\
-\x32\x2c\x30\x2c\x39\x2e\x36\x2c\x34\x2e\x32\x39\x38\x2c\x39\x2e\
-\x36\x2c\x39\x2e\x36\x63\x30\x2c\x35\x2e\x33\x30\x33\x2d\x34\x2e\
-\x32\x39\x38\x2c\x39\x2e\x36\x2d\x39\x2e\x36\x2c\x39\x2e\x36\x53\
-\x30\x2e\x34\x2c\x31\x35\x2e\x33\x30\x33\x2c\x30\x2e\x34\x2c\x31\
-\x30\x43\x30\x2e\x34\x2c\x34\x2e\x36\x39\x38\x2c\x34\x2e\x36\x39\
-\x38\x2c\x30\x2e\x34\x2c\x31\x30\x2c\x30\x2e\x34\x7a\x20\x4d\x31\
-\x30\x2c\x31\x38\x2e\x33\x35\x34\x0d\x0a\x09\x63\x34\x2e\x36\x31\
-\x33\x2c\x30\x2c\x38\x2e\x33\x35\x34\x2d\x33\x2e\x37\x34\x2c\x38\
-\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x30\x2d\x34\x2e\x36\
-\x31\x34\x2d\x33\x2e\x37\x34\x31\x2d\x38\x2e\x33\x35\x34\x2d\x38\
-\x2e\x33\x35\x34\x2d\x38\x2e\x33\x35\x34\x63\x2d\x34\x2e\x36\x31\
-\x35\x2c\x30\x2d\x38\x2e\x33\x35\x34\x2c\x33\x2e\x37\x34\x2d\x38\
-\x2e\x33\x35\x34\x2c\x38\x2e\x33\x35\x34\x0d\x0a\x09\x43\x31\x2e\
-\x36\x34\x35\x2c\x31\x34\x2e\x36\x31\x34\x2c\x35\x2e\x33\x38\x35\
-\x2c\x31\x38\x2e\x33\x35\x34\x2c\x31\x30\x2c\x31\x38\x2e\x33\x35\
-\x34\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
-\x76\x67\x3e\x0d\x0a\
-\x00\x00\x01\x1c\
-\x3c\
-\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
-\x30\x2f\x73\x76\x67\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x35\x31\
-\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x35\x31\x32\
-\x70\x78\x22\x0a\x20\x20\x20\x20\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x3e\x0a\
-\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
-\x74\x72\x69\x78\x28\x34\x38\x20\x30\x20\x30\x20\x34\x38\x20\x34\
-\x38\x20\x34\x38\x29\x27\x3e\x0a\x20\x20\x3c\x70\x61\x74\x68\x20\
-\x64\x3d\x22\x4d\x30\x20\x30\x76\x32\x68\x2e\x35\x63\x30\x2d\x2e\
-\x35\x35\x2e\x34\x35\x2d\x31\x20\x31\x2d\x31\x68\x31\x2e\x35\x76\
-\x35\x2e\x35\x63\x30\x20\x2e\x32\x38\x2d\x2e\x32\x32\x2e\x35\x2d\
-\x2e\x35\x2e\x35\x68\x2d\x2e\x35\x76\x31\x68\x34\x76\x2d\x31\x68\
-\x2d\x2e\x35\x63\x2d\x2e\x32\x38\x20\x30\x2d\x2e\x35\x2d\x2e\x32\
-\x32\x2d\x2e\x35\x2d\x2e\x35\x76\x2d\x35\x2e\x35\x68\x31\x2e\x35\
-\x63\x2e\x35\x35\x20\x30\x20\x31\x20\x2e\x34\x35\x20\x31\x20\x31\
-\x68\x2e\x35\x76\x2d\x32\x68\x2d\x38\x7a\x22\x20\x2f\x3e\x0a\x3c\
-\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\x0a\
-\x00\x00\x04\x64\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\x0d\x0a\x09\
-\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x35\x36\x2c\x31\
-\x37\x36\x63\x2d\x34\x34\x2e\x30\x30\x34\x2c\x30\x2d\x38\x30\x2e\
-\x30\x30\x31\x2c\x33\x36\x2d\x38\x30\x2e\x30\x30\x31\x2c\x38\x30\
-\x63\x30\x2c\x34\x34\x2e\x30\x30\x34\x2c\x33\x35\x2e\x39\x39\x37\
-\x2c\x38\x30\x2c\x38\x30\x2e\x30\x30\x31\x2c\x38\x30\x63\x34\x34\
-\x2e\x30\x30\x35\x2c\x30\x2c\x37\x39\x2e\x39\x39\x39\x2d\x33\x35\
-\x2e\x39\x39\x36\x2c\x37\x39\x2e\x39\x39\x39\x2d\x38\x30\x0d\x0a\
-\x09\x09\x09\x43\x33\x33\x35\x2e\x39\x39\x39\x2c\x32\x31\x32\x2c\
-\x33\x30\x30\x2e\x30\x30\x35\x2c\x31\x37\x36\x2c\x32\x35\x36\x2c\
-\x31\x37\x36\x7a\x20\x4d\x34\x34\x36\x2e\x39\x33\x38\x2c\x32\x33\
-\x34\x2e\x36\x36\x37\x63\x2d\x39\x2e\x36\x30\x35\x2d\x38\x38\x2e\
-\x35\x33\x31\x2d\x38\x31\x2e\x30\x37\x34\x2d\x31\x36\x30\x2d\x31\
-\x36\x39\x2e\x36\x30\x35\x2d\x31\x36\x39\x2e\x35\x39\x39\x56\x33\
-\x32\x68\x2d\x34\x32\x2e\x36\x36\x36\x76\x33\x33\x2e\x30\x36\x37\
-\x0d\x0a\x09\x09\x09\x63\x2d\x38\x38\x2e\x35\x33\x31\x2c\x39\x2e\
-\x35\x39\x39\x2d\x31\x36\x30\x2c\x38\x31\x2e\x30\x36\x38\x2d\x31\
-\x36\x39\x2e\x36\x30\x34\x2c\x31\x36\x39\x2e\x35\x39\x39\x48\x33\
-\x32\x76\x34\x32\x2e\x36\x36\x37\x68\x33\x33\x2e\x30\x36\x32\x63\
-\x39\x2e\x36\x30\x34\x2c\x38\x38\x2e\x35\x33\x31\x2c\x38\x31\x2e\
-\x30\x37\x32\x2c\x31\x36\x30\x2c\x31\x36\x39\x2e\x36\x30\x34\x2c\
-\x31\x36\x39\x2e\x36\x30\x34\x56\x34\x38\x30\x68\x34\x32\x2e\x36\
-\x36\x36\x76\x2d\x33\x33\x2e\x30\x36\x32\x0d\x0a\x09\x09\x09\x63\
-\x38\x38\x2e\x35\x33\x31\x2d\x39\x2e\x36\x30\x34\x2c\x31\x36\x30\
-\x2d\x38\x31\x2e\x30\x37\x33\x2c\x31\x36\x39\x2e\x36\x30\x35\x2d\
-\x31\x36\x39\x2e\x36\x30\x34\x48\x34\x38\x30\x76\x2d\x34\x32\x2e\
-\x36\x36\x37\x48\x34\x34\x36\x2e\x39\x33\x38\x7a\x20\x4d\x32\x35\
-\x36\x2c\x34\x30\x35\x2e\x33\x33\x33\x63\x2d\x38\x32\x2e\x31\x33\
-\x37\x2c\x30\x2d\x31\x34\x39\x2e\x33\x33\x34\x2d\x36\x37\x2e\x31\
-\x39\x38\x2d\x31\x34\x39\x2e\x33\x33\x34\x2d\x31\x34\x39\x2e\x33\
-\x33\x33\x0d\x0a\x09\x09\x09\x63\x30\x2d\x38\x32\x2e\x31\x33\x36\
-\x2c\x36\x37\x2e\x31\x39\x37\x2d\x31\x34\x39\x2e\x33\x33\x33\x2c\
-\x31\x34\x39\x2e\x33\x33\x34\x2d\x31\x34\x39\x2e\x33\x33\x33\x63\
-\x38\x32\x2e\x31\x33\x35\x2c\x30\x2c\x31\x34\x39\x2e\x33\x33\x32\
-\x2c\x36\x37\x2e\x31\x39\x38\x2c\x31\x34\x39\x2e\x33\x33\x32\x2c\
-\x31\x34\x39\x2e\x33\x33\x33\x43\x34\x30\x35\x2e\x33\x33\x32\x2c\
-\x33\x33\x38\x2e\x31\x33\x35\x2c\x33\x33\x38\x2e\x31\x33\x35\x2c\
-\x34\x30\x35\x2e\x33\x33\x33\x2c\x32\x35\x36\x2c\x34\x30\x35\x2e\
-\x33\x33\x33\x7a\x0d\x0a\x09\x09\x09\x22\x2f\x3e\x0d\x0a\x09\x3c\
-\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\
-\x3e\x0d\x0a\
-\x00\x00\x03\x36\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\x3d\
-\x22\x33\x39\x36\x2e\x37\x39\x35\x2c\x33\x39\x36\x2e\x38\x20\x33\
-\x32\x30\x2c\x33\x39\x36\x2e\x38\x20\x33\x32\x30\x2c\x34\x34\x38\
-\x20\x34\x34\x38\x2c\x34\x34\x38\x20\x34\x34\x38\x2c\x33\x32\x30\
-\x20\x33\x39\x36\x2e\x37\x39\x35\x2c\x33\x32\x30\x20\x09\x22\x2f\
-\x3e\x0d\x0a\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\
-\x6e\x74\x73\x3d\x22\x33\x39\x36\x2e\x38\x2c\x31\x31\x35\x2e\x32\
-\x30\x35\x20\x33\x39\x36\x2e\x38\x2c\x31\x39\x32\x20\x34\x34\x38\
-\x2c\x31\x39\x32\x20\x34\x34\x38\x2c\x36\x34\x20\x33\x32\x30\x2c\
-\x36\x34\x20\x33\x32\x30\x2c\x31\x31\x35\x2e\x32\x30\x35\x20\x09\
-\x22\x2f\x3e\x0d\x0a\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\
-\x6f\x69\x6e\x74\x73\x3d\x22\x31\x31\x35\x2e\x32\x30\x35\x2c\x31\
-\x31\x35\x2e\x32\x20\x31\x39\x32\x2c\x31\x31\x35\x2e\x32\x20\x31\
-\x39\x32\x2c\x36\x34\x20\x36\x34\x2c\x36\x34\x20\x36\x34\x2c\x31\
-\x39\x32\x20\x31\x31\x35\x2e\x32\x30\x35\x2c\x31\x39\x32\x20\x09\
-\x22\x2f\x3e\x0d\x0a\x09\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\
-\x6f\x69\x6e\x74\x73\x3d\x22\x31\x31\x35\x2e\x32\x2c\x33\x39\x36\
-\x2e\x37\x39\x35\x20\x31\x31\x35\x2e\x32\x2c\x33\x32\x30\x20\x36\
-\x34\x2c\x33\x32\x30\x20\x36\x34\x2c\x34\x34\x38\x20\x31\x39\x32\
-\x2c\x34\x34\x38\x20\x31\x39\x32\x2c\x33\x39\x36\x2e\x37\x39\x35\
-\x20\x09\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\
-\x76\x67\x3e\x0d\x0a\
-\x00\x00\x04\xaa\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x43\x6f\x64\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\
-\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\
-\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\
-\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\x78\
-\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x32\x34\x70\x78\x22\x20\x79\
-\x3d\x22\x32\x34\x70\x78\x22\x0d\x0a\x09\x20\x76\x69\x65\x77\x42\
-\x6f\x78\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\
-\x20\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\
-\x6e\x64\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\
-\x35\x31\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\
-\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x74\
-\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\
-\x28\x32\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\x20\x30\x29\x27\
-\x3e\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x35\x2e\x37\x31\x39\
-\x2c\x31\x34\x2e\x37\x35\x63\x2d\x30\x2e\x32\x33\x36\x2c\x30\x2d\
-\x30\x2e\x34\x37\x34\x2d\x30\x2e\x30\x38\x33\x2d\x30\x2e\x36\x36\
-\x34\x2d\x30\x2e\x32\x35\x32\x4c\x2d\x30\x2e\x30\x30\x35\x2c\x31\
-\x30\x6c\x35\x2e\x33\x34\x31\x2d\x34\x2e\x37\x34\x38\x43\x35\x2e\
-\x37\x34\x38\x2c\x34\x2e\x38\x38\x37\x2c\x36\x2e\x33\x38\x2c\x34\
-\x2e\x39\x32\x32\x2c\x36\x2e\x37\x34\x37\x2c\x35\x2e\x33\x33\x35\
-\x0d\x0a\x09\x63\x30\x2e\x33\x36\x37\x2c\x30\x2e\x34\x31\x33\x2c\
-\x30\x2e\x33\x33\x2c\x31\x2e\x30\x34\x35\x2d\x30\x2e\x30\x38\x33\
-\x2c\x31\x2e\x34\x31\x32\x4c\x33\x2e\x30\x30\x35\x2c\x31\x30\x6c\
-\x33\x2e\x33\x37\x38\x2c\x33\x2e\x30\x30\x32\x63\x30\x2e\x34\x31\
-\x33\x2c\x30\x2e\x33\x36\x37\x2c\x30\x2e\x34\x35\x2c\x30\x2e\x39\
-\x39\x39\x2c\x30\x2e\x30\x38\x33\x2c\x31\x2e\x34\x31\x32\x0d\x0a\
-\x09\x43\x36\x2e\x32\x36\x39\x2c\x31\x34\x2e\x36\x33\x37\x2c\x35\
-\x2e\x39\x39\x34\x2c\x31\x34\x2e\x37\x35\x2c\x35\x2e\x37\x31\x39\
-\x2c\x31\x34\x2e\x37\x35\x7a\x20\x4d\x31\x34\x2e\x36\x36\x34\x2c\
-\x31\x34\x2e\x37\x34\x38\x4c\x32\x30\x2e\x30\x30\x35\x2c\x31\x30\
-\x6c\x2d\x35\x2e\x30\x36\x2d\x34\x2e\x34\x39\x38\x63\x2d\x30\x2e\
-\x34\x31\x33\x2d\x30\x2e\x33\x36\x37\x2d\x31\x2e\x30\x34\x35\x2d\
-\x30\x2e\x33\x33\x2d\x31\x2e\x34\x31\x31\x2c\x30\x2e\x30\x38\x33\
-\x0d\x0a\x09\x63\x2d\x30\x2e\x33\x36\x37\x2c\x30\x2e\x34\x31\x33\
-\x2d\x30\x2e\x33\x33\x2c\x31\x2e\x30\x34\x35\x2c\x30\x2e\x30\x38\
-\x33\x2c\x31\x2e\x34\x31\x32\x4c\x31\x36\x2e\x39\x39\x35\x2c\x31\
-\x30\x6c\x2d\x33\x2e\x36\x35\x39\x2c\x33\x2e\x32\x35\x32\x63\x2d\
-\x30\x2e\x34\x31\x33\x2c\x30\x2e\x33\x36\x37\x2d\x30\x2e\x34\x35\
-\x2c\x30\x2e\x39\x39\x39\x2d\x30\x2e\x30\x38\x33\x2c\x31\x2e\x34\
-\x31\x32\x43\x31\x33\x2e\x34\x35\x2c\x31\x34\x2e\x38\x38\x37\x2c\
-\x31\x33\x2e\x37\x32\x35\x2c\x31\x35\x2c\x31\x34\x2c\x31\x35\x0d\
-\x0a\x09\x43\x31\x34\x2e\x32\x33\x36\x2c\x31\x35\x2c\x31\x34\x2e\
-\x34\x37\x34\x2c\x31\x34\x2e\x39\x31\x37\x2c\x31\x34\x2e\x36\x36\
-\x34\x2c\x31\x34\x2e\x37\x34\x38\x7a\x20\x4d\x39\x2e\x39\x38\x36\
-\x2c\x31\x36\x2e\x31\x36\x35\x6c\x32\x2d\x31\x32\x63\x30\x2e\x30\
-\x39\x31\x2d\x30\x2e\x35\x34\x35\x2d\x30\x2e\x32\x37\x37\x2d\x31\
-\x2e\x30\x36\x2d\x30\x2e\x38\x32\x32\x2d\x31\x2e\x31\x35\x31\x0d\
-\x0a\x09\x63\x2d\x30\x2e\x35\x34\x37\x2d\x30\x2e\x30\x39\x32\x2d\
-\x31\x2e\x30\x36\x31\x2c\x30\x2e\x32\x37\x37\x2d\x31\x2e\x31\x35\
-\x2c\x30\x2e\x38\x32\x32\x6c\x2d\x32\x2c\x31\x32\x63\x2d\x30\x2e\
-\x30\x39\x31\x2c\x30\x2e\x35\x34\x35\x2c\x30\x2e\x32\x37\x37\x2c\
-\x31\x2e\x30\x36\x2c\x30\x2e\x38\x32\x32\x2c\x31\x2e\x31\x35\x31\
-\x43\x38\x2e\x38\x39\x32\x2c\x31\x36\x2e\x39\x39\x36\x2c\x38\x2e\
-\x39\x34\x36\x2c\x31\x37\x2c\x39\x2e\x30\x30\x31\x2c\x31\x37\x0d\
-\x0a\x09\x43\x39\x2e\x34\x38\x31\x2c\x31\x37\x2c\x39\x2e\x39\x30\
-\x35\x2c\x31\x36\x2e\x36\x35\x33\x2c\x39\x2e\x39\x38\x36\x2c\x31\
-\x36\x2e\x31\x36\x35\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\
-\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x02\x7d\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x38\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
-\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x38\x35\
-\x2c\x32\x37\x37\x2e\x33\x37\x35\x68\x32\x35\x39\x2e\x37\x30\x34\
-\x4c\x32\x32\x35\x2e\x30\x30\x32\x2c\x33\x39\x37\x2e\x30\x37\x37\
-\x4c\x32\x35\x36\x2c\x34\x32\x37\x6c\x31\x37\x31\x2d\x31\x37\x31\
-\x4c\x32\x35\x36\x2c\x38\x35\x6c\x2d\x32\x39\x2e\x39\x32\x32\x2c\
-\x32\x39\x2e\x39\x32\x34\x6c\x31\x31\x38\x2e\x36\x32\x36\x2c\x31\
-\x31\x39\x2e\x37\x30\x31\x48\x38\x35\x56\x32\x37\x37\x2e\x33\x37\
-\x35\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
-\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x04\x4e\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
-\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
-\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
-\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
-\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
-\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
-\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
-\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
-\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
-\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
-\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
-\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
-\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
-\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\
-\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\
-\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x4c\x20\x31\
-\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\x39\x4c\
-\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\x2e\x35\x30\x32\
-\x32\x4c\x20\x34\x30\x2e\x36\x37\x39\x34\x20\x2d\x32\x32\x2e\x35\
-\x32\x38\x31\x4c\x20\x33\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\
-\x2e\x31\x32\x5a\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\
-\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\
-\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\
-\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\
-\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\
-\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\
-\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\
-\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x32\x2e\x35\x30\
-\x39\x33\x37\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\
-\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\
-\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\
-\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\
-\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\
-\x65\x20\x63\x78\x3d\x27\x33\x2e\x39\x35\x37\x33\x35\x27\x20\x63\
-\x79\x3d\x27\x2d\x33\x32\x2e\x31\x32\x27\x20\x66\x69\x6c\x6c\x3d\
-\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\
-\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\
-\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\
-\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\
-\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\
-\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\
-\x65\x20\x63\x78\x3d\x27\x31\x31\x2e\x39\x30\x33\x36\x27\x20\x63\
-\x79\x3d\x27\x2d\x35\x31\x2e\x33\x30\x33\x39\x27\x20\x66\x69\x6c\
-\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\
-\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\
-\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\
-\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\
-\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\
-\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\
-\x63\x6c\x65\x20\x63\x78\x3d\x27\x35\x36\x2e\x31\x35\x32\x33\x27\
-\x20\x63\x79\x3d\x27\x2d\x34\x32\x2e\x35\x30\x32\x32\x27\x20\x66\
-\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\
-\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\
-\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
-\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\
-\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\
-\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\
-\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x34\x30\x2e\x36\x37\x39\
-\x34\x27\x20\x63\x79\x3d\x27\x2d\x32\x32\x2e\x35\x32\x38\x31\x27\
-\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\
-\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\
-\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x04\xd5\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
-\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
-\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
-\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
-\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
-\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
-\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
-\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
-\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
-\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
-\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
-\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
-\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
-\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\
-\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\
-\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x43\x20\x32\
-\x2e\x32\x38\x39\x32\x32\x20\x2d\x33\x39\x2e\x33\x31\x31\x33\x20\
-\x36\x2e\x33\x36\x37\x30\x32\x20\x2d\x34\x36\x2e\x32\x33\x38\x36\
-\x20\x31\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\
-\x39\x43\x20\x32\x39\x2e\x36\x36\x38\x37\x20\x2d\x36\x37\x2e\x35\
-\x35\x36\x38\x20\x35\x35\x2e\x32\x32\x39\x32\x20\x2d\x36\x30\x2e\
-\x36\x34\x32\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\x2e\
-\x35\x30\x32\x32\x43\x20\x35\x36\x2e\x36\x31\x33\x36\x20\x2d\x33\
-\x33\x2e\x34\x33\x38\x31\x20\x34\x39\x2e\x31\x31\x33\x32\x20\x2d\
-\x32\x36\x2e\x35\x39\x35\x39\x20\x34\x30\x2e\x36\x37\x39\x34\x20\
-\x2d\x32\x32\x2e\x35\x32\x38\x31\x43\x20\x32\x35\x2e\x33\x39\x39\
-\x35\x20\x2d\x31\x35\x2e\x31\x35\x38\x32\x20\x37\x2e\x31\x39\x39\
-\x33\x35\x20\x2d\x31\x38\x2e\x31\x34\x33\x36\x20\x33\x2e\x39\x35\
-\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x5a\x27\x20\x66\x69\x6c\
-\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\x20\x73\x74\x72\x6f\x6b\x65\x3d\
-\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x73\x74\x72\x6f\x6b\x65\
-\x2d\x6c\x69\x6e\x65\x63\x61\x70\x3d\x27\x72\x6f\x75\x6e\x64\x27\
-\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\
-\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
-\x6d\x69\x74\x65\x72\x6c\x69\x6d\x69\x74\x3d\x27\x31\x30\x2e\x30\
-\x33\x37\x35\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x77\x69\x64\x74\
-\x68\x3d\x27\x32\x2e\x35\x30\x39\x33\x37\x27\x2f\x3e\x0a\x3c\x2f\
-\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\
-\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\
-\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\
-\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x33\x2e\x39\
-\x35\x37\x33\x35\x27\x20\x63\x79\x3d\x27\x2d\x33\x32\x2e\x31\x32\
-\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\
-\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\
-\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\
-\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\
-\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\
-\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x31\x31\x2e\
-\x39\x30\x33\x36\x27\x20\x63\x79\x3d\x27\x2d\x35\x31\x2e\x33\x30\
-\x33\x39\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\
-\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\
-\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\
-\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\
-\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\
-\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\
-\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x35\
-\x36\x2e\x31\x35\x32\x33\x27\x20\x63\x79\x3d\x27\x2d\x34\x32\x2e\
-\x35\x30\x32\x32\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\
-\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\
-\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\
-\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\
-\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\
-\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\
-\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\x20\x63\x78\x3d\
-\x27\x34\x30\x2e\x36\x37\x39\x34\x27\x20\x63\x79\x3d\x27\x2d\x32\
-\x32\x2e\x35\x32\x38\x31\x27\x20\x66\x69\x6c\x6c\x3d\x27\x23\x30\
-\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\x32\x35\
-\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\
-\x73\x76\x67\x3e\
-\x00\x00\x02\xf2\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x38\x2e\x31\x2e\x30\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x43\x69\x72\x63\x6c\x65\x22\x20\x78\x6d\x6c\x6e\x73\x3d\
-\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\
-\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\x6c\
-\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\x2f\
-\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\
-\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x35\x31\x32\x70\x78\
-\x22\x20\x79\x3d\x22\x35\x31\x32\x70\x78\x22\x0d\x0a\x09\x20\x76\
-\x69\x65\x77\x42\x6f\x78\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\
-\x35\x31\x32\x22\x20\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\
-\x67\x72\x6f\x75\x6e\x64\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\
-\x35\x31\x32\x20\x35\x31\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\
-\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\
-\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\
-\x74\x72\x69\x78\x28\x32\x34\x20\x30\x20\x30\x20\x32\x34\x20\x30\
-\x20\x30\x29\x27\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\
-\x4d\x31\x30\x2c\x30\x2e\x34\x43\x34\x2e\x36\x39\x38\x2c\x30\x2e\
-\x34\x2c\x30\x2e\x34\x2c\x34\x2e\x36\x39\x38\x2c\x30\x2e\x34\x2c\
-\x31\x30\x43\x30\x2e\x34\x2c\x31\x35\x2e\x33\x30\x32\x2c\x34\x2e\
-\x36\x39\x38\x2c\x31\x39\x2e\x36\x2c\x31\x30\x2c\x31\x39\x2e\x36\
-\x63\x35\x2e\x33\x30\x31\x2c\x30\x2c\x39\x2e\x36\x2d\x34\x2e\x32\
-\x39\x38\x2c\x39\x2e\x36\x2d\x39\x2e\x36\x30\x31\x0d\x0a\x09\x43\
-\x31\x39\x2e\x36\x2c\x34\x2e\x36\x39\x38\x2c\x31\x35\x2e\x33\x30\
-\x31\x2c\x30\x2e\x34\x2c\x31\x30\x2c\x30\x2e\x34\x7a\x20\x4d\x31\
-\x30\x2c\x31\x37\x2e\x35\x39\x39\x63\x2d\x34\x2e\x31\x39\x37\x2c\
-\x30\x2d\x37\x2e\x36\x2d\x33\x2e\x34\x30\x32\x2d\x37\x2e\x36\x2d\
-\x37\x2e\x36\x53\x35\x2e\x38\x30\x32\x2c\x32\x2e\x34\x2c\x31\x30\
-\x2c\x32\x2e\x34\x63\x34\x2e\x31\x39\x37\x2c\x30\x2c\x37\x2e\x36\
-\x30\x31\x2c\x33\x2e\x34\x30\x32\x2c\x37\x2e\x36\x30\x31\x2c\x37\
-\x2e\x36\x0d\x0a\x09\x53\x31\x34\x2e\x31\x39\x37\x2c\x31\x37\x2e\
-\x35\x39\x39\x2c\x31\x30\x2c\x31\x37\x2e\x35\x39\x39\x7a\x22\x2f\
-\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
-\x0a\
-\x00\x00\x03\x4c\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x32\x31\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
-\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
-\x35\x36\x2c\x31\x35\x32\x63\x2d\x35\x37\x2e\x32\x2c\x30\x2d\x31\
-\x30\x34\x2c\x34\x36\x2e\x38\x2d\x31\x30\x34\x2c\x31\x30\x34\x73\
-\x34\x36\x2e\x38\x2c\x31\x30\x34\x2c\x31\x30\x34\x2c\x31\x30\x34\
-\x73\x31\x30\x34\x2d\x34\x36\x2e\x38\x2c\x31\x30\x34\x2d\x31\x30\
-\x34\x53\x33\x31\x33\x2e\x32\x2c\x31\x35\x32\x2c\x32\x35\x36\x2c\
-\x31\x35\x32\x7a\x20\x4d\x32\x35\x36\x2c\x34\x38\x0d\x0a\x09\x09\
-\x09\x43\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x34\x38\x2c\
-\x31\x34\x31\x2e\x36\x30\x31\x2c\x34\x38\x2c\x32\x35\x36\x73\x39\
-\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\x2c\x32\x30\x38\x2c\x32\x30\
-\x38\x73\x32\x30\x38\x2d\x39\x33\x2e\x36\x30\x31\x2c\x32\x30\x38\
-\x2d\x32\x30\x38\x53\x33\x37\x30\x2e\x33\x39\x39\x2c\x34\x38\x2c\
-\x32\x35\x36\x2c\x34\x38\x7a\x20\x4d\x32\x35\x36\x2c\x34\x32\x32\
-\x2e\x34\x0d\x0a\x09\x09\x09\x63\x2d\x39\x31\x2e\x35\x31\x38\x2c\
-\x30\x2d\x31\x36\x36\x2e\x34\x2d\x37\x34\x2e\x38\x38\x33\x2d\x31\
-\x36\x36\x2e\x34\x2d\x31\x36\x36\x2e\x34\x53\x31\x36\x34\x2e\x34\
-\x38\x32\x2c\x38\x39\x2e\x36\x2c\x32\x35\x36\x2c\x38\x39\x2e\x36\
-\x53\x34\x32\x32\x2e\x34\x2c\x31\x36\x34\x2e\x34\x38\x32\x2c\x34\
-\x32\x32\x2e\x34\x2c\x32\x35\x36\x53\x33\x34\x37\x2e\x35\x31\x38\
-\x2c\x34\x32\x32\x2e\x34\x2c\x32\x35\x36\x2c\x34\x32\x32\x2e\x34\
-\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\
-\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x02\x7f\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
-\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
-\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
-\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
-\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
-\x0a\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\
-\x3d\x22\x32\x38\x38\x2c\x39\x36\x20\x33\x33\x37\x2e\x39\x2c\x31\
-\x34\x35\x2e\x39\x20\x32\x37\x34\x2c\x32\x30\x39\x2e\x37\x20\x32\
-\x37\x34\x2c\x32\x30\x39\x2e\x37\x20\x31\x34\x35\x2e\x39\x2c\x33\
-\x33\x37\x2e\x39\x20\x39\x36\x2c\x32\x38\x38\x20\x39\x36\x2c\x34\
-\x31\x36\x20\x32\x32\x34\x2c\x34\x31\x36\x20\x31\x37\x34\x2e\x31\
-\x2c\x33\x36\x36\x2e\x31\x20\x33\x35\x37\x2e\x34\x2c\x31\x38\x32\
-\x2e\x39\x20\x33\x36\x36\x2e\x31\x2c\x31\x37\x34\x2e\x31\x20\x0d\
-\x0a\x09\x34\x31\x36\x2c\x32\x32\x34\x20\x34\x31\x36\x2c\x39\x36\
-\x20\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x02\xa2\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x32\x38\x2c\x34\x30\
-\x35\x2e\x34\x32\x39\x43\x31\x32\x38\x2c\x34\x32\x38\x2e\x38\x34\
-\x36\x2c\x31\x34\x37\x2e\x31\x39\x38\x2c\x34\x34\x38\x2c\x31\x37\
-\x30\x2e\x36\x36\x37\x2c\x34\x34\x38\x68\x31\x37\x30\x2e\x36\x36\
-\x37\x43\x33\x36\x34\x2e\x38\x30\x32\x2c\x34\x34\x38\x2c\x33\x38\
-\x34\x2c\x34\x32\x38\x2e\x38\x34\x36\x2c\x33\x38\x34\x2c\x34\x30\
-\x35\x2e\x34\x32\x39\x56\x31\x36\x30\x48\x31\x32\x38\x56\x34\x30\
-\x35\x2e\x34\x32\x39\x7a\x20\x4d\x34\x31\x36\x2c\x39\x36\x0d\x0a\
-\x09\x09\x68\x2d\x38\x30\x6c\x2d\x32\x36\x2e\x37\x38\x35\x2d\x33\
-\x32\x48\x32\x30\x32\x2e\x37\x38\x36\x4c\x31\x37\x36\x2c\x39\x36\
-\x48\x39\x36\x76\x33\x32\x68\x33\x32\x30\x56\x39\x36\x7a\x22\x2f\
-\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
-\x0a\
-\x00\x00\x04\x3d\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x27\x31\x2e\
-\x30\x27\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x27\x55\x54\x46\
-\x2d\x38\x27\x3f\x3e\x0a\x3c\x21\x2d\x2d\x20\x54\x68\x69\x73\x20\
-\x66\x69\x6c\x65\x20\x77\x61\x73\x20\x67\x65\x6e\x65\x72\x61\x74\
-\x65\x64\x20\x62\x79\x20\x64\x76\x69\x73\x76\x67\x6d\x20\x32\x2e\
-\x38\x20\x2d\x2d\x3e\x0a\x3c\x73\x76\x67\x20\x76\x65\x72\x73\x69\
-\x6f\x6e\x3d\x27\x31\x2e\x31\x27\x20\x78\x6d\x6c\x6e\x73\x3d\x27\
-\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\
-\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x27\x20\x78\x6d\x6c\x6e\
-\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x27\x68\x74\x74\x70\x3a\x2f\x2f\
-\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\x39\x2f\
-\x78\x6c\x69\x6e\x6b\x27\x20\x77\x69\x64\x74\x68\x3d\x27\x36\x33\
-\x2e\x39\x39\x39\x36\x70\x74\x27\x20\x68\x65\x69\x67\x68\x74\x3d\
-\x27\x36\x33\x2e\x39\x39\x39\x37\x70\x74\x27\x20\x76\x69\x65\x77\
-\x42\x6f\x78\x3d\x27\x35\x36\x2e\x34\x30\x39\x34\x20\x35\x33\x2e\
-\x38\x35\x38\x33\x20\x36\x33\x2e\x39\x39\x39\x36\x20\x36\x33\x2e\
-\x39\x39\x39\x37\x27\x3e\x0a\x3c\x67\x20\x69\x64\x3d\x27\x70\x61\
-\x67\x65\x31\x27\x3e\x0a\x3c\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\
-\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\x30\x2e\x39\x39\x36\
-\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\x39\x36\x32\x36\x34\
-\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\x37\x2e\x38\x35\x38\
-\x29\x27\x3e\x0a\x3c\x70\x61\x74\x68\x20\x64\x3d\x27\x4d\x20\x33\
-\x2e\x39\x35\x37\x33\x35\x20\x2d\x33\x32\x2e\x31\x32\x4c\x20\x31\
-\x31\x2e\x39\x30\x33\x36\x20\x2d\x35\x31\x2e\x33\x30\x33\x39\x4c\
-\x20\x35\x36\x2e\x31\x35\x32\x33\x20\x2d\x34\x32\x2e\x35\x30\x32\
-\x32\x4c\x20\x34\x30\x2e\x36\x37\x39\x34\x20\x2d\x32\x32\x2e\x35\
-\x32\x38\x31\x27\x20\x66\x69\x6c\x6c\x3d\x27\x6e\x6f\x6e\x65\x27\
-\x20\x73\x74\x72\x6f\x6b\x65\x3d\x27\x23\x30\x30\x30\x30\x30\x30\
-\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6c\x69\x6e\x65\x63\x61\x70\
-\x3d\x27\x72\x6f\x75\x6e\x64\x27\x20\x73\x74\x72\x6f\x6b\x65\x2d\
-\x6c\x69\x6e\x65\x6a\x6f\x69\x6e\x3d\x27\x72\x6f\x75\x6e\x64\x27\
-\x20\x73\x74\x72\x6f\x6b\x65\x2d\x6d\x69\x74\x65\x72\x6c\x69\x6d\
-\x69\x74\x3d\x27\x31\x30\x2e\x30\x33\x37\x35\x27\x20\x73\x74\x72\
-\x6f\x6b\x65\x2d\x77\x69\x64\x74\x68\x3d\x27\x32\x2e\x35\x30\x39\
-\x33\x37\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\
-\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\
-\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\
-\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\
-\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\
-\x20\x63\x78\x3d\x27\x33\x2e\x39\x35\x37\x33\x35\x27\x20\x63\x79\
-\x3d\x27\x2d\x33\x32\x2e\x31\x32\x27\x20\x66\x69\x6c\x6c\x3d\x27\
-\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\x30\x32\
-\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\x74\x72\
-\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\x78\x28\
-\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\x2e\x39\
-\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\x31\x31\
-\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\x6c\x65\
-\x20\x63\x78\x3d\x27\x31\x31\x2e\x39\x30\x33\x36\x27\x20\x63\x79\
-\x3d\x27\x2d\x35\x31\x2e\x33\x30\x33\x39\x27\x20\x66\x69\x6c\x6c\
-\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\x36\x2e\
-\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\x67\x20\
-\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\x72\x69\
-\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\x20\x30\
-\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\x39\x20\
-\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\x72\x63\
-\x6c\x65\x20\x63\x78\x3d\x27\x35\x36\x2e\x31\x35\x32\x33\x27\x20\
-\x63\x79\x3d\x27\x2d\x34\x32\x2e\x35\x30\x32\x32\x27\x20\x66\x69\
-\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\x3d\x27\
-\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\x0a\x3c\
-\x67\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x27\x6d\x61\x74\
-\x72\x69\x78\x28\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x30\x20\x30\
-\x20\x30\x2e\x39\x39\x36\x32\x36\x34\x20\x35\x38\x2e\x34\x36\x36\
-\x39\x20\x31\x31\x37\x2e\x38\x35\x38\x29\x27\x3e\x0a\x3c\x63\x69\
-\x72\x63\x6c\x65\x20\x63\x78\x3d\x27\x34\x30\x2e\x36\x37\x39\x34\
-\x27\x20\x63\x79\x3d\x27\x2d\x32\x32\x2e\x35\x32\x38\x31\x27\x20\
-\x66\x69\x6c\x6c\x3d\x27\x23\x30\x30\x30\x30\x30\x30\x27\x20\x72\
-\x3d\x27\x36\x2e\x30\x32\x32\x35\x27\x2f\x3e\x0a\x3c\x2f\x67\x3e\
-\x0a\x3c\x2f\x67\x3e\x0a\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x02\x7d\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x38\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
-\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\x32\
-\x37\x2c\x32\x33\x34\x2e\x36\x32\x35\x48\x31\x36\x37\x2e\x32\x39\
-\x36\x6c\x31\x31\x39\x2e\x37\x30\x32\x2d\x31\x31\x39\x2e\x37\x30\
-\x32\x4c\x32\x35\x36\x2c\x38\x35\x4c\x38\x35\x2c\x32\x35\x36\x6c\
-\x31\x37\x31\x2c\x31\x37\x31\x6c\x32\x39\x2e\x39\x32\x32\x2d\x32\
-\x39\x2e\x39\x32\x34\x4c\x31\x36\x37\x2e\x32\x39\x36\x2c\x32\x37\
-\x37\x2e\x33\x37\x35\x48\x34\x32\x37\x56\x32\x33\x34\x2e\x36\x32\
-\x35\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
-\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x02\xc9\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
-\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
-\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
-\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
-\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
-\x0a\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\
-\x3d\x22\x34\x38\x30\x2c\x32\x35\x36\x20\x33\x38\x34\x2c\x31\x36\
-\x30\x20\x33\x38\x34\x2c\x32\x33\x36\x20\x32\x37\x36\x2c\x32\x33\
-\x36\x20\x32\x37\x36\x2c\x31\x32\x38\x20\x33\x35\x32\x2c\x31\x32\
-\x38\x20\x32\x35\x36\x2c\x33\x32\x20\x31\x36\x30\x2c\x31\x32\x38\
-\x20\x32\x33\x36\x2c\x31\x32\x38\x20\x32\x33\x36\x2c\x32\x33\x36\
-\x20\x31\x32\x38\x2c\x32\x33\x36\x20\x31\x32\x38\x2c\x31\x36\x30\
-\x20\x33\x32\x2c\x32\x35\x36\x20\x31\x32\x38\x2c\x33\x35\x32\x20\
-\x0d\x0a\x09\x31\x32\x38\x2c\x32\x37\x36\x20\x32\x33\x36\x2c\x32\
-\x37\x36\x20\x32\x33\x36\x2c\x33\x38\x34\x20\x31\x36\x30\x2c\x33\
-\x38\x34\x20\x32\x35\x36\x2c\x34\x38\x30\x20\x33\x35\x32\x2c\x33\
-\x38\x34\x20\x32\x37\x35\x2e\x38\x2c\x33\x38\x34\x20\x32\x37\x35\
-\x2e\x34\x2c\x32\x37\x35\x2e\x35\x20\x33\x38\x34\x2c\x32\x37\x35\
-\x2e\x38\x20\x33\x38\x34\x2c\x33\x35\x32\x20\x22\x2f\x3e\x0d\x0a\
-\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x05\xca\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\
-\x64\x3d\x22\x4d\x34\x35\x30\x2e\x36\x37\x39\x2c\x32\x37\x33\x2e\
-\x35\x63\x2d\x31\x34\x2e\x35\x38\x35\x2d\x31\x34\x2e\x35\x37\x37\
-\x2d\x33\x36\x2e\x30\x35\x34\x2d\x31\x35\x2e\x38\x39\x2d\x35\x30\
-\x2e\x36\x33\x39\x2d\x31\x2e\x33\x31\x32\x6c\x2d\x34\x31\x2e\x36\
-\x38\x37\x2c\x34\x31\x2e\x36\x36\x34\x63\x2d\x31\x30\x2e\x38\x35\
-\x32\x2c\x31\x30\x2e\x38\x33\x36\x2d\x32\x33\x2e\x39\x33\x2c\x31\
-\x30\x2e\x38\x35\x39\x2d\x33\x31\x2e\x35\x36\x34\x2c\x31\x2e\x38\
-\x35\x32\x0d\x0a\x09\x63\x2d\x35\x2e\x30\x35\x37\x2d\x35\x2e\x39\
-\x36\x38\x2d\x33\x2e\x30\x36\x31\x2d\x32\x34\x2e\x33\x37\x34\x2d\
-\x31\x2e\x36\x34\x34\x2d\x33\x36\x2e\x30\x34\x39\x6c\x32\x30\x2e\
-\x39\x30\x37\x2d\x31\x37\x31\x2e\x38\x34\x39\x63\x31\x2e\x38\x36\
-\x37\x2d\x31\x35\x2e\x33\x35\x33\x2d\x39\x2e\x30\x37\x2d\x33\x30\
-\x2e\x31\x38\x35\x2d\x32\x34\x2e\x34\x33\x2d\x33\x32\x2e\x30\x35\
-\x31\x0d\x0a\x09\x63\x2d\x31\x35\x2e\x33\x35\x38\x2d\x31\x2e\x38\
-\x36\x37\x2d\x32\x39\x2e\x33\x32\x32\x2c\x39\x2e\x39\x33\x39\x2d\
-\x33\x31\x2e\x31\x39\x31\x2c\x32\x35\x2e\x32\x38\x39\x4c\x32\x36\
-\x37\x2e\x33\x37\x2c\x32\x33\x36\x2e\x30\x32\x31\x63\x2d\x31\x2e\
-\x32\x30\x35\x2c\x33\x2e\x33\x35\x38\x2d\x33\x2e\x37\x39\x2c\x33\
-\x2e\x39\x33\x38\x2d\x34\x2e\x30\x38\x31\x2d\x30\x2e\x35\x38\x32\
-\x4c\x32\x35\x35\x2e\x34\x34\x2c\x36\x30\x0d\x0a\x09\x63\x30\x2d\
-\x31\x35\x2e\x34\x36\x35\x2d\x31\x32\x2e\x35\x34\x32\x2d\x32\x38\
-\x2d\x32\x38\x2e\x30\x31\x34\x2d\x32\x38\x63\x2d\x31\x35\x2e\x34\
-\x37\x33\x2c\x30\x2d\x32\x38\x2e\x30\x31\x35\x2c\x31\x32\x2e\x35\
-\x33\x35\x2d\x32\x38\x2e\x30\x31\x35\x2c\x32\x38\x6c\x2d\x30\x2e\
-\x35\x35\x32\x2c\x31\x37\x36\x2e\x37\x35\x32\x63\x30\x2e\x31\x34\
-\x36\x2c\x32\x2e\x30\x34\x2d\x31\x2e\x36\x30\x34\x2c\x32\x2e\x36\
-\x32\x34\x2d\x31\x2e\x39\x32\x2c\x30\x2e\x32\x39\x34\x4c\x31\x37\
-\x32\x2e\x30\x31\x36\x2c\x39\x39\x2e\x30\x37\x37\x0d\x0a\x09\x63\
-\x2d\x32\x2e\x37\x35\x2d\x31\x35\x2e\x32\x31\x39\x2d\x31\x37\x2e\
-\x33\x32\x33\x2d\x32\x36\x2e\x32\x30\x33\x2d\x33\x32\x2e\x35\x34\
-\x38\x2d\x32\x33\x2e\x34\x35\x33\x63\x2d\x31\x35\x2e\x32\x32\x37\
-\x2c\x32\x2e\x37\x34\x38\x2d\x32\x35\x2e\x33\x33\x39\x2c\x31\x38\
-\x2e\x31\x38\x37\x2d\x32\x32\x2e\x35\x39\x31\x2c\x33\x33\x2e\x34\
-\x30\x33\x6c\x32\x32\x2e\x31\x39\x33\x2c\x31\x36\x31\x2e\x34\x35\
-\x35\x0d\x0a\x09\x63\x30\x2e\x30\x32\x33\x2c\x32\x2e\x38\x37\x32\
-\x2d\x30\x2e\x39\x34\x31\x2c\x34\x2e\x35\x31\x33\x2d\x32\x2e\x33\
-\x30\x38\x2c\x30\x2e\x38\x33\x31\x6c\x2d\x33\x33\x2e\x31\x30\x39\
-\x2d\x38\x38\x2e\x35\x31\x37\x63\x2d\x35\x2e\x31\x38\x2d\x31\x34\
-\x2e\x35\x37\x32\x2d\x32\x31\x2e\x31\x39\x36\x2d\x32\x33\x2e\x30\
-\x36\x35\x2d\x33\x35\x2e\x37\x37\x36\x2d\x31\x37\x2e\x38\x38\x39\
-\x0d\x0a\x09\x63\x2d\x31\x34\x2e\x35\x37\x39\x2c\x35\x2e\x31\x37\
-\x37\x2d\x32\x32\x2e\x32\x30\x31\x2c\x32\x32\x2e\x30\x36\x31\x2d\
-\x31\x37\x2e\x30\x32\x33\x2c\x33\x36\x2e\x36\x33\x31\x6c\x35\x38\
-\x2e\x30\x34\x32\x2c\x31\x38\x39\x2e\x36\x32\x35\x63\x30\x2e\x33\
-\x30\x33\x2c\x31\x2e\x30\x34\x36\x2c\x30\x2e\x36\x32\x34\x2c\x32\
-\x2e\x30\x38\x35\x2c\x30\x2e\x39\x35\x33\x2c\x33\x2e\x31\x31\x38\
-\x6c\x30\x2e\x31\x32\x31\x2c\x30\x2e\x33\x39\x0d\x0a\x09\x63\x30\
-\x2e\x30\x31\x31\x2c\x30\x2e\x30\x33\x31\x2c\x30\x2e\x30\x32\x35\
-\x2c\x30\x2e\x30\x35\x38\x2c\x30\x2e\x30\x33\x35\x2c\x30\x2e\x30\
-\x38\x38\x43\x31\x32\x36\x2e\x30\x37\x39\x2c\x34\x34\x34\x2e\x32\
-\x33\x33\x2c\x31\x37\x32\x2e\x35\x37\x2c\x34\x38\x30\x2c\x32\x32\
-\x37\x2e\x34\x32\x37\x2c\x34\x38\x30\x63\x33\x35\x2e\x31\x31\x36\
-\x2c\x30\x2c\x37\x31\x2e\x35\x39\x31\x2d\x31\x32\x2e\x33\x37\x38\
-\x2c\x39\x39\x2e\x33\x35\x37\x2d\x33\x33\x2e\x36\x37\x32\x0d\x0a\
-\x09\x63\x30\x2e\x30\x30\x31\x2c\x30\x2c\x30\x2e\x30\x30\x33\x2d\
-\x30\x2e\x30\x30\x32\x2c\x30\x2e\x30\x30\x33\x2d\x30\x2e\x30\x30\
-\x32\x63\x32\x39\x2e\x39\x39\x2d\x31\x38\x2e\x30\x35\x31\x2c\x31\
-\x32\x36\x2e\x30\x37\x31\x2d\x31\x32\x31\x2e\x33\x34\x37\x2c\x31\
-\x32\x36\x2e\x30\x37\x31\x2d\x31\x32\x31\x2e\x33\x34\x37\x43\x34\
-\x36\x37\x2e\x34\x34\x35\x2c\x33\x31\x30\x2e\x34\x30\x32\x2c\x34\
-\x36\x35\x2e\x32\x36\x36\x2c\x32\x38\x38\x2e\x30\x38\x2c\x34\x35\
-\x30\x2e\x36\x37\x39\x2c\x32\x37\x33\x2e\x35\x7a\x22\x2f\x3e\x0d\
-\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x03\x52\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x70\x61\x74\x68\x20\
-\x64\x3d\x22\x4d\x34\x33\x37\x2e\x33\x33\x34\x2c\x31\x34\x34\x48\
-\x32\x35\x36\x2e\x30\x30\x36\x6c\x2d\x34\x32\x2e\x36\x36\x38\x2d\
-\x34\x38\x48\x37\x34\x2e\x36\x36\x36\x43\x35\x31\x2e\x31\x39\x37\
-\x2c\x39\x36\x2c\x33\x32\x2c\x31\x31\x35\x2e\x31\x39\x38\x2c\x33\
-\x32\x2c\x31\x33\x38\x2e\x36\x36\x37\x76\x32\x33\x34\x2e\x36\x36\
-\x36\x43\x33\x32\x2c\x33\x39\x36\x2e\x38\x30\x32\x2c\x35\x31\x2e\
-\x31\x39\x37\x2c\x34\x31\x36\x2c\x37\x34\x2e\x36\x36\x36\x2c\x34\
-\x31\x36\x68\x33\x36\x32\x2e\x36\x36\x38\x0d\x0a\x09\x43\x34\x36\
-\x30\x2e\x38\x30\x33\x2c\x34\x31\x36\x2c\x34\x38\x30\x2c\x33\x39\
-\x36\x2e\x38\x30\x32\x2c\x34\x38\x30\x2c\x33\x37\x33\x2e\x33\x33\
-\x33\x56\x31\x38\x36\x2e\x36\x36\x37\x43\x34\x38\x30\x2c\x31\x36\
-\x33\x2e\x31\x39\x38\x2c\x34\x36\x30\x2e\x38\x30\x33\x2c\x31\x34\
-\x34\x2c\x34\x33\x37\x2e\x33\x33\x34\x2c\x31\x34\x34\x7a\x20\x4d\
-\x34\x34\x38\x2c\x33\x37\x33\x2e\x33\x33\x33\x0d\x0a\x09\x63\x30\
-\x2c\x35\x2e\x37\x38\x32\x2d\x34\x2e\x38\x38\x35\x2c\x31\x30\x2e\
-\x36\x36\x37\x2d\x31\x30\x2e\x36\x36\x36\x2c\x31\x30\x2e\x36\x36\
-\x37\x48\x37\x34\x2e\x36\x36\x36\x43\x36\x38\x2e\x38\x38\x34\x2c\
-\x33\x38\x34\x2c\x36\x34\x2c\x33\x37\x39\x2e\x31\x31\x35\x2c\x36\
-\x34\x2c\x33\x37\x33\x2e\x33\x33\x33\x56\x31\x37\x36\x68\x33\x37\
-\x33\x2e\x33\x33\x34\x63\x35\x2e\x37\x38\x31\x2c\x30\x2c\x31\x30\
-\x2e\x36\x36\x36\x2c\x34\x2e\x38\x38\x35\x2c\x31\x30\x2e\x36\x36\
-\x36\x2c\x31\x30\x2e\x36\x36\x37\x0d\x0a\x09\x56\x33\x37\x33\x2e\
-\x33\x33\x33\x7a\x22\x2f\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\
-\x0a\
-\x00\x00\x00\x6c\
-\x3c\
-\x73\x76\x67\x20\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\
-\x30\x2f\x73\x76\x67\x22\x20\x76\x69\x65\x77\x42\x6f\x78\x3d\x22\
-\x30\x20\x30\x20\x32\x30\x20\x32\x30\x22\x3e\x3c\x70\x61\x74\x68\
-\x20\x64\x3d\x22\x4d\x31\x38\x20\x31\x32\x76\x31\x48\x38\x76\x35\
-\x6c\x2d\x36\x2d\x36\x20\x36\x2d\x36\x76\x35\x68\x38\x56\x32\x68\
-\x32\x7a\x22\x2f\x3e\x3c\x2f\x73\x76\x67\x3e\
-\x00\x00\x02\x79\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x31\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\x3e\
-\x0d\x0a\x09\x09\x3c\x67\x3e\x0d\x0a\x09\x09\x09\x3c\x70\x6f\x6c\
-\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\x3d\x22\x31\x38\x36\
-\x2e\x33\x30\x31\x2c\x33\x33\x39\x2e\x38\x39\x33\x20\x39\x36\x2c\
-\x32\x34\x39\x2e\x34\x36\x31\x20\x36\x34\x2c\x32\x37\x39\x2e\x39\
-\x36\x38\x20\x31\x38\x36\x2e\x33\x30\x31\x2c\x34\x30\x32\x20\x34\
-\x34\x38\x2c\x31\x34\x30\x2e\x35\x30\x36\x20\x34\x31\x36\x2c\x31\
-\x31\x30\x20\x09\x09\x09\x22\x2f\x3e\x0d\x0a\x09\x09\x3c\x2f\x67\
-\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\
-\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x03\x6c\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x0d\x0a\x09\x09\x3c\x72\x65\x63\x74\x20\x78\x3d\x22\x31\x37\x38\
-\x2e\x38\x34\x36\x22\x20\x79\x3d\x22\x39\x32\x2e\x30\x38\x37\x22\
-\x20\x74\x72\x61\x6e\x73\x66\x6f\x72\x6d\x3d\x22\x6d\x61\x74\x72\
-\x69\x78\x28\x2d\x30\x2e\x37\x30\x37\x31\x20\x2d\x30\x2e\x37\x30\
-\x37\x31\x20\x30\x2e\x37\x30\x37\x31\x20\x2d\x30\x2e\x37\x30\x37\
-\x31\x20\x32\x32\x34\x2e\x33\x34\x37\x36\x20\x36\x33\x31\x2e\x31\
-\x34\x39\x38\x29\x22\x20\x77\x69\x64\x74\x68\x3d\x22\x31\x32\x38\
-\x2e\x30\x38\x35\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x33\x35\
-\x34\x2e\x30\x34\x39\x22\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\
-\x20\x64\x3d\x22\x4d\x34\x37\x31\x2e\x37\x32\x33\x2c\x38\x38\x2e\
-\x33\x39\x33\x6c\x2d\x34\x38\x2e\x31\x31\x35\x2d\x34\x38\x2e\x31\
-\x31\x34\x63\x2d\x31\x31\x2e\x37\x32\x33\x2d\x31\x31\x2e\x37\x32\
-\x34\x2d\x33\x31\x2e\x35\x35\x38\x2d\x31\x30\x2e\x38\x39\x36\x2d\
-\x34\x34\x2e\x33\x30\x34\x2c\x31\x2e\x38\x35\x6c\x2d\x34\x35\x2e\
-\x32\x30\x32\x2c\x34\x35\x2e\x32\x30\x33\x6c\x39\x30\x2e\x35\x36\
-\x39\x2c\x39\x30\x2e\x35\x36\x38\x6c\x34\x35\x2e\x32\x30\x32\x2d\
-\x34\x35\x2e\x32\x30\x32\x0d\x0a\x09\x09\x43\x34\x38\x32\x2e\x36\
-\x31\x36\x2c\x31\x31\x39\x2e\x39\x35\x32\x2c\x34\x38\x33\x2e\x34\
-\x34\x35\x2c\x31\x30\x30\x2e\x31\x31\x36\x2c\x34\x37\x31\x2e\x37\
-\x32\x33\x2c\x38\x38\x2e\x33\x39\x33\x7a\x22\x2f\x3e\x0d\x0a\x09\
-\x3c\x70\x6f\x6c\x79\x67\x6f\x6e\x20\x70\x6f\x69\x6e\x74\x73\x3d\
-\x22\x36\x34\x2e\x30\x32\x31\x2c\x33\x36\x33\x2e\x32\x35\x32\x20\
-\x33\x32\x2c\x34\x38\x30\x20\x31\x34\x38\x2e\x37\x33\x37\x2c\x34\
-\x34\x37\x2e\x39\x37\x39\x20\x09\x22\x2f\x3e\x0d\x0a\x3c\x2f\x67\
-\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x05\x27\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x20\x69\x64\x3d\
-\x22\x49\x63\x6f\x6e\x5f\x31\x32\x5f\x22\x3e\x0d\x0a\x09\x3c\x67\
-\x3e\x0d\x0a\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\
-\x35\x36\x2c\x36\x34\x43\x31\x35\x30\x2e\x34\x30\x31\x2c\x36\x34\
-\x2c\x36\x34\x2c\x31\x35\x30\x2e\x34\x30\x31\x2c\x36\x34\x2c\x32\
-\x35\x36\x63\x30\x2c\x31\x30\x35\x2e\x36\x30\x34\x2c\x38\x36\x2e\
-\x34\x30\x31\x2c\x31\x39\x32\x2c\x31\x39\x32\x2c\x31\x39\x32\x63\
-\x31\x38\x2e\x31\x33\x36\x2c\x30\x2c\x33\x32\x2d\x31\x33\x2e\x38\
-\x36\x34\x2c\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\x09\x63\x30\x2d\
-\x38\x2e\x35\x33\x31\x2d\x33\x2e\x31\x39\x38\x2d\x31\x36\x2d\x38\
-\x2e\x35\x33\x31\x2d\x32\x31\x2e\x33\x33\x33\x63\x2d\x35\x2e\x33\
-\x33\x33\x2d\x35\x2e\x33\x33\x34\x2d\x38\x2e\x35\x33\x31\x2d\x31\
-\x32\x2e\x38\x30\x33\x2d\x38\x2e\x35\x33\x31\x2d\x32\x31\x2e\x33\
-\x33\x34\x63\x30\x2d\x31\x38\x2e\x31\x33\x35\x2c\x31\x33\x2e\x38\
-\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x68\x33\x38\x2e\x33\
-\x39\x36\x0d\x0a\x09\x09\x09\x63\x35\x38\x2e\x36\x36\x37\x2c\x30\
-\x2c\x31\x30\x36\x2e\x36\x36\x37\x2d\x34\x38\x2c\x31\x30\x36\x2e\
-\x36\x36\x37\x2d\x31\x30\x36\x2e\x36\x36\x36\x43\x34\x34\x38\x2c\
-\x31\x34\x30\x2e\x38\x30\x32\x2c\x33\x36\x31\x2e\x36\x30\x34\x2c\
-\x36\x34\x2c\x32\x35\x36\x2c\x36\x34\x7a\x20\x4d\x31\x33\x38\x2e\
-\x36\x36\x37\x2c\x32\x35\x36\x63\x2d\x31\x38\x2e\x31\x33\x36\x2c\
-\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x34\x2d\x33\x32\x2d\x33\
-\x32\x73\x31\x33\x2e\x38\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\
-\x32\x0d\x0a\x09\x09\x09\x63\x31\x38\x2e\x31\x33\x35\x2c\x30\x2c\
-\x33\x32\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x53\
-\x31\x35\x36\x2e\x38\x30\x32\x2c\x32\x35\x36\x2c\x31\x33\x38\x2e\
-\x36\x36\x37\x2c\x32\x35\x36\x7a\x20\x4d\x32\x30\x32\x2e\x36\x36\
-\x37\x2c\x31\x37\x30\x2e\x36\x36\x37\x63\x2d\x31\x38\x2e\x31\x33\
-\x36\x2c\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x35\x2d\x33\x32\
-\x2d\x33\x32\x63\x30\x2d\x31\x38\x2e\x31\x33\x36\x2c\x31\x33\x2e\
-\x38\x36\x34\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\
-\x09\x63\x31\x38\x2e\x31\x33\x35\x2c\x30\x2c\x33\x32\x2c\x31\x33\
-\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x43\x32\x33\x34\x2e\x36\
-\x36\x37\x2c\x31\x35\x36\x2e\x38\x30\x32\x2c\x32\x32\x30\x2e\x38\
-\x30\x32\x2c\x31\x37\x30\x2e\x36\x36\x37\x2c\x32\x30\x32\x2e\x36\
-\x36\x37\x2c\x31\x37\x30\x2e\x36\x36\x37\x7a\x20\x4d\x33\x30\x39\
-\x2e\x33\x33\x33\x2c\x31\x37\x30\x2e\x36\x36\x37\x63\x2d\x31\x38\
-\x2e\x31\x33\x35\x2c\x30\x2d\x33\x32\x2d\x31\x33\x2e\x38\x36\x35\
-\x2d\x33\x32\x2d\x33\x32\x0d\x0a\x09\x09\x09\x63\x30\x2d\x31\x38\
-\x2e\x31\x33\x36\x2c\x31\x33\x2e\x38\x36\x35\x2d\x33\x32\x2c\x33\
-\x32\x2d\x33\x32\x63\x31\x38\x2e\x31\x33\x36\x2c\x30\x2c\x33\x32\
-\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\x2c\x33\x32\x43\x33\x34\
-\x31\x2e\x33\x33\x33\x2c\x31\x35\x36\x2e\x38\x30\x32\x2c\x33\x32\
-\x37\x2e\x34\x36\x39\x2c\x31\x37\x30\x2e\x36\x36\x37\x2c\x33\x30\
-\x39\x2e\x33\x33\x33\x2c\x31\x37\x30\x2e\x36\x36\x37\x7a\x20\x4d\
-\x33\x37\x33\x2e\x33\x33\x33\x2c\x32\x35\x36\x0d\x0a\x09\x09\x09\
-\x63\x2d\x31\x38\x2e\x31\x33\x35\x2c\x30\x2d\x33\x32\x2d\x31\x33\
-\x2e\x38\x36\x34\x2d\x33\x32\x2d\x33\x32\x73\x31\x33\x2e\x38\x36\
-\x35\x2d\x33\x32\x2c\x33\x32\x2d\x33\x32\x63\x31\x38\x2e\x31\x33\
-\x36\x2c\x30\x2c\x33\x32\x2c\x31\x33\x2e\x38\x36\x34\x2c\x33\x32\
-\x2c\x33\x32\x53\x33\x39\x31\x2e\x34\x36\x39\x2c\x32\x35\x36\x2c\
-\x33\x37\x33\x2e\x33\x33\x33\x2c\x32\x35\x36\x7a\x22\x2f\x3e\x0d\
-\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\
-\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x07\x80\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x65\
-\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\
-\x3d\x22\x6e\x65\x77\x20\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\
-\x32\x22\x20\x78\x6d\x6c\x3a\x73\x70\x61\x63\x65\x3d\x22\x70\x72\
-\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\x0a\x3c\x67\x3e\x0d\x0a\x09\
-\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x31\x39\x33\x2e\x34\x36\
-\x2c\x32\x34\x39\x2e\x30\x35\x36\x63\x33\x2e\x37\x32\x33\x2d\x30\
-\x2e\x36\x37\x2c\x37\x2e\x35\x38\x39\x2d\x31\x2e\x30\x34\x31\x2c\
-\x31\x31\x2e\x35\x38\x36\x2d\x31\x2e\x30\x34\x31\x4c\x32\x30\x31\
-\x2e\x39\x32\x34\x2c\x32\x34\x38\x68\x31\x30\x33\x2e\x38\x32\x33\
-\x63\x34\x2e\x35\x30\x33\x2c\x30\x2c\x38\x2e\x38\x30\x36\x2d\x30\
-\x2e\x36\x31\x37\x2c\x31\x32\x2e\x39\x30\x38\x2d\x31\x2e\x37\x35\
-\x34\x0d\x0a\x09\x09\x63\x31\x39\x2e\x33\x37\x2d\x35\x2e\x33\x36\
-\x33\x2c\x33\x33\x2e\x33\x34\x35\x2d\x32\x32\x2e\x35\x33\x37\x2c\
-\x33\x33\x2e\x33\x34\x35\x2d\x34\x33\x2e\x36\x36\x33\x76\x2d\x33\
-\x30\x2e\x38\x32\x32\x76\x2d\x35\x36\x2e\x34\x30\x32\x63\x30\x2d\
-\x32\x34\x2e\x38\x33\x32\x2d\x32\x31\x2e\x31\x35\x2d\x34\x33\x2e\
-\x34\x38\x34\x2d\x34\x36\x2e\x32\x38\x39\x2d\x34\x37\x2e\x36\x30\
-\x36\x0d\x0a\x09\x09\x63\x2d\x31\x35\x2e\x39\x33\x31\x2d\x32\x2e\
-\x36\x32\x34\x2d\x33\x39\x2e\x32\x35\x38\x2d\x33\x2e\x38\x32\x37\
-\x2d\x35\x35\x2e\x30\x38\x39\x2d\x33\x2e\x37\x34\x39\x63\x2d\x31\
-\x35\x2e\x38\x32\x39\x2c\x30\x2e\x30\x38\x36\x2d\x33\x30\x2e\x39\
-\x38\x31\x2c\x31\x2e\x34\x30\x34\x2d\x34\x34\x2e\x32\x37\x37\x2c\
-\x33\x2e\x37\x34\x39\x43\x31\x36\x37\x2e\x31\x34\x33\x2c\x37\x34\
-\x2e\x35\x37\x36\x2c\x31\x36\x30\x2c\x38\x38\x2e\x39\x32\x38\x2c\
-\x31\x36\x30\x2c\x31\x31\x35\x2e\x33\x35\x39\x56\x31\x34\x34\x68\
-\x39\x36\x0d\x0a\x09\x09\x76\x31\x36\x48\x31\x32\x38\x2e\x38\x32\
-\x63\x2d\x33\x35\x2e\x36\x32\x38\x2c\x30\x2d\x36\x34\x2e\x35\x33\
-\x38\x2c\x34\x32\x2e\x35\x37\x31\x2d\x36\x34\x2e\x38\x31\x33\x2c\
-\x39\x35\x2e\x32\x34\x32\x43\x36\x34\x2e\x30\x30\x35\x2c\x32\x35\
-\x35\x2e\x34\x39\x35\x2c\x36\x34\x2c\x32\x35\x35\x2e\x37\x34\x37\
-\x2c\x36\x34\x2c\x32\x35\x36\x63\x30\x2c\x39\x2e\x35\x32\x33\x2c\
-\x30\x2e\x39\x34\x2c\x31\x38\x2e\x37\x32\x2c\x32\x2e\x36\x38\x35\
-\x2c\x32\x37\x2e\x34\x30\x34\x0d\x0a\x09\x09\x43\x37\x34\x2e\x36\
-\x34\x38\x2c\x33\x32\x33\x2e\x30\x37\x2c\x39\x39\x2e\x34\x35\x31\
-\x2c\x33\x35\x32\x2c\x31\x32\x38\x2e\x38\x32\x2c\x33\x35\x32\x48\
-\x31\x34\x34\x76\x2d\x32\x2e\x36\x36\x32\x76\x2d\x34\x33\x2e\x32\
-\x37\x33\x43\x31\x34\x34\x2c\x32\x37\x39\x2e\x32\x33\x38\x2c\x31\
-\x36\x34\x2e\x31\x34\x36\x2c\x32\x35\x34\x2e\x33\x33\x32\x2c\x31\
-\x39\x33\x2e\x34\x36\x2c\x32\x34\x39\x2e\x30\x35\x36\x7a\x20\x4d\
-\x32\x30\x33\x2e\x36\x35\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x0d\
-\x0a\x09\x09\x63\x2d\x39\x2e\x35\x39\x32\x2c\x30\x2d\x31\x37\x2e\
-\x33\x38\x34\x2d\x37\x2e\x37\x38\x35\x2d\x31\x37\x2e\x33\x38\x34\
-\x2d\x31\x37\x2e\x34\x30\x33\x63\x30\x2d\x39\x2e\x36\x36\x34\x2c\
-\x37\x2e\x37\x37\x34\x2d\x31\x37\x2e\x35\x32\x2c\x31\x37\x2e\x33\
-\x38\x34\x2d\x31\x37\x2e\x35\x32\x63\x39\x2e\x35\x37\x34\x2c\x30\
-\x2c\x31\x37\x2e\x33\x39\x39\x2c\x37\x2e\x38\x35\x35\x2c\x31\x37\
-\x2e\x33\x39\x39\x2c\x31\x37\x2e\x35\x32\x0d\x0a\x09\x09\x43\x32\
-\x32\x31\x2e\x30\x35\x36\x2c\x31\x31\x39\x2e\x32\x31\x37\x2c\x32\
-\x31\x33\x2e\x32\x34\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x2c\x32\
-\x30\x33\x2e\x36\x35\x36\x2c\x31\x32\x37\x2e\x30\x30\x32\x7a\x22\
-\x2f\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x34\
-\x34\x33\x2e\x39\x35\x31\x2c\x32\x32\x32\x2e\x35\x34\x33\x43\x34\
-\x33\x34\x2e\x37\x38\x2c\x31\x38\x36\x2e\x30\x32\x31\x2c\x34\x31\
-\x31\x2e\x30\x33\x33\x2c\x31\x36\x30\x2c\x33\x38\x33\x2e\x31\x38\
-\x2c\x31\x36\x30\x48\x33\x36\x38\x76\x32\x2e\x36\x32\x36\x76\x33\
-\x38\x2e\x30\x34\x36\x63\x30\x2c\x33\x33\x2e\x39\x31\x35\x2d\x32\
-\x32\x2e\x32\x38\x36\x2c\x35\x38\x2e\x34\x37\x34\x2d\x34\x39\x2e\
-\x34\x38\x39\x2c\x36\x32\x2e\x36\x38\x31\x0d\x0a\x09\x09\x63\x2d\
-\x32\x2e\x37\x33\x37\x2c\x30\x2e\x34\x32\x34\x2d\x35\x2e\x34\x38\
-\x33\x2c\x30\x2e\x36\x34\x36\x2d\x38\x2e\x33\x30\x31\x2c\x30\x2e\
-\x36\x34\x36\x48\x32\x30\x36\x2e\x33\x35\x31\x63\x2d\x34\x2e\x35\
-\x31\x38\x2c\x30\x2d\x38\x2e\x39\x30\x34\x2c\x30\x2e\x35\x38\x34\
-\x2d\x31\x33\x2e\x30\x34\x39\x2c\x31\x2e\x36\x37\x32\x43\x31\x37\
-\x34\x2e\x31\x38\x2c\x32\x37\x30\x2e\x36\x38\x39\x2c\x31\x36\x30\
-\x2c\x32\x38\x36\x2e\x36\x2c\x31\x36\x30\x2c\x33\x30\x37\x2e\x32\
-\x33\x36\x76\x33\x32\x2e\x39\x32\x32\x0d\x0a\x09\x09\x76\x35\x34\
-\x2e\x33\x30\x35\x63\x30\x2c\x32\x34\x2e\x38\x33\x32\x2c\x32\x34\
-\x2e\x39\x37\x37\x2c\x33\x39\x2e\x34\x32\x36\x2c\x34\x39\x2e\x34\
-\x38\x31\x2c\x34\x36\x2e\x35\x35\x31\x63\x32\x39\x2e\x33\x32\x37\
-\x2c\x38\x2e\x35\x33\x31\x2c\x36\x31\x2e\x32\x36\x37\x2c\x31\x30\
-\x2e\x30\x36\x38\x2c\x39\x36\x2e\x33\x36\x36\x2c\x30\x43\x33\x32\
-\x39\x2e\x31\x35\x2c\x34\x33\x34\x2e\x33\x35\x34\x2c\x33\x35\x32\
-\x2c\x34\x32\x30\x2e\x38\x39\x33\x2c\x33\x35\x32\x2c\x33\x39\x34\
-\x2e\x34\x36\x33\x56\x33\x36\x38\x0d\x0a\x09\x09\x68\x2d\x39\x36\
-\x76\x2d\x31\x36\x68\x31\x32\x37\x2e\x31\x38\x63\x32\x35\x2e\x32\
-\x34\x2c\x30\x2c\x34\x37\x2e\x31\x30\x37\x2d\x32\x31\x2e\x33\x36\
-\x35\x2c\x35\x37\x2e\x38\x31\x34\x2d\x35\x32\x2e\x35\x34\x39\x43\
-\x34\x34\x35\x2e\x34\x37\x34\x2c\x32\x38\x36\x2e\x34\x30\x34\x2c\
-\x34\x34\x38\x2c\x32\x37\x31\x2e\x36\x34\x31\x2c\x34\x34\x38\x2c\
-\x32\x35\x36\x0d\x0a\x09\x09\x43\x34\x34\x38\x2c\x32\x34\x34\x2e\
-\x32\x33\x32\x2c\x34\x34\x36\x2e\x35\x36\x37\x2c\x32\x33\x32\x2e\
-\x39\x36\x32\x2c\x34\x34\x33\x2e\x39\x35\x31\x2c\x32\x32\x32\x2e\
-\x35\x34\x33\x7a\x20\x4d\x33\x30\x37\x2e\x38\x36\x37\x2c\x33\x38\
-\x32\x2e\x38\x32\x63\x39\x2e\x35\x39\x2c\x30\x2c\x31\x37\x2e\x33\
-\x38\x31\x2c\x37\x2e\x37\x38\x35\x2c\x31\x37\x2e\x33\x38\x31\x2c\
-\x31\x37\x2e\x34\x0d\x0a\x09\x09\x63\x30\x2c\x39\x2e\x36\x35\x2d\
-\x37\x2e\x37\x39\x31\x2c\x31\x37\x2e\x35\x32\x31\x2d\x31\x37\x2e\
-\x33\x38\x31\x2c\x31\x37\x2e\x35\x32\x31\x63\x2d\x39\x2e\x35\x37\
-\x37\x2c\x30\x2d\x31\x37\x2e\x33\x39\x39\x2d\x37\x2e\x38\x37\x31\
-\x2d\x31\x37\x2e\x33\x39\x39\x2d\x31\x37\x2e\x35\x32\x31\x43\x32\
-\x39\x30\x2e\x34\x36\x38\x2c\x33\x39\x30\x2e\x35\x39\x2c\x32\x39\
-\x38\x2e\x32\x37\x34\x2c\x33\x38\x32\x2e\x38\x32\x2c\x33\x30\x37\
-\x2e\x38\x36\x37\x2c\x33\x38\x32\x2e\x38\x32\x7a\x22\x2f\x3e\x0d\
-\x0a\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-\x00\x00\x03\xeb\
-\x3c\
-\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
-\x30\x22\x20\x65\x6e\x63\x6f\x64\x69\x6e\x67\x3d\x22\x75\x74\x66\
-\x2d\x38\x22\x3f\x3e\x0d\x0a\x3c\x21\x2d\x2d\x20\x47\x65\x6e\x65\
-\x72\x61\x74\x6f\x72\x3a\x20\x41\x64\x6f\x62\x65\x20\x49\x6c\x6c\
-\x75\x73\x74\x72\x61\x74\x6f\x72\x20\x31\x36\x2e\x32\x2e\x31\x2c\
-\x20\x53\x56\x47\x20\x45\x78\x70\x6f\x72\x74\x20\x50\x6c\x75\x67\
-\x2d\x49\x6e\x20\x2e\x20\x53\x56\x47\x20\x56\x65\x72\x73\x69\x6f\
-\x6e\x3a\x20\x36\x2e\x30\x30\x20\x42\x75\x69\x6c\x64\x20\x30\x29\
-\x20\x20\x2d\x2d\x3e\x0d\x0a\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\
-\x20\x73\x76\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\
-\x57\x33\x43\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\
-\x2f\x2f\x45\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
-\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\
-\x73\x2f\x53\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\
-\x67\x31\x31\x2e\x64\x74\x64\x22\x3e\x0d\x0a\x3c\x73\x76\x67\x20\
-\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\x69\x64\
-\x3d\x22\x4c\x61\x79\x65\x72\x5f\x31\x22\x20\x78\x6d\x6c\x6e\x73\
-\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\
-\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\x67\x22\x20\x78\x6d\
-\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\x3a\
-\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\x39\
-\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x78\x3d\x22\x30\x70\x78\x22\
-\x20\x79\x3d\x22\x30\x70\x78\x22\x0d\x0a\x09\x20\x77\x69\x64\x74\
-\x68\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x68\x65\x69\x67\x68\x74\
-\x3d\x22\x35\x31\x32\x70\x78\x22\x20\x76\x69\x65\x77\x42\x6f\x78\
-\x3d\x22\x30\x20\x30\x20\x35\x31\x32\x20\x35\x31\x32\x22\x20\x73\
-\x74\x79\x6c\x65\x3d\x22\x65\x6e\x61\x62\x6c\x65\x2d\x62\x61\x63\
-\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x6e\x65\x77\x20\x30\x20\x30\x20\
-\x35\x31\x32\x20\x35\x31\x32\x3b\x22\x20\x78\x6d\x6c\x3a\x73\x70\
-\x61\x63\x65\x3d\x22\x70\x72\x65\x73\x65\x72\x76\x65\x22\x3e\x0d\
-\x0a\x3c\x67\x3e\x0d\x0a\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\
-\x4d\x32\x35\x36\x2c\x31\x32\x38\x63\x2d\x38\x31\x2e\x39\x2c\x30\
-\x2d\x31\x34\x35\x2e\x37\x2c\x34\x38\x2e\x38\x2d\x32\x32\x34\x2c\
-\x31\x32\x38\x63\x36\x37\x2e\x34\x2c\x36\x37\x2e\x37\x2c\x31\x32\
-\x34\x2c\x31\x32\x38\x2c\x32\x32\x34\x2c\x31\x32\x38\x63\x39\x39\
-\x2e\x39\x2c\x30\x2c\x31\x37\x33\x2e\x34\x2d\x37\x36\x2e\x34\x2c\
-\x32\x32\x34\x2d\x31\x32\x36\x2e\x36\x0d\x0a\x09\x09\x43\x34\x32\
-\x38\x2e\x32\x2c\x31\x39\x38\x2e\x36\x2c\x33\x35\x34\x2e\x38\x2c\
-\x31\x32\x38\x2c\x32\x35\x36\x2c\x31\x32\x38\x7a\x20\x4d\x32\x35\
-\x36\x2c\x33\x34\x37\x2e\x33\x63\x2d\x34\x39\x2e\x34\x2c\x30\x2d\
-\x38\x39\x2e\x36\x2d\x34\x31\x2d\x38\x39\x2e\x36\x2d\x39\x31\x2e\
-\x33\x63\x30\x2d\x35\x30\x2e\x34\x2c\x34\x30\x2e\x32\x2d\x39\x31\
-\x2e\x33\x2c\x38\x39\x2e\x36\x2d\x39\x31\x2e\x33\x73\x38\x39\x2e\
-\x36\x2c\x34\x31\x2c\x38\x39\x2e\x36\x2c\x39\x31\x2e\x33\x0d\x0a\
-\x09\x09\x43\x33\x34\x35\x2e\x36\x2c\x33\x30\x36\x2e\x34\x2c\x33\
-\x30\x35\x2e\x34\x2c\x33\x34\x37\x2e\x33\x2c\x32\x35\x36\x2c\x33\
-\x34\x37\x2e\x33\x7a\x22\x2f\x3e\x0d\x0a\x09\x3c\x67\x3e\x0d\x0a\
-\x09\x09\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x35\x36\x2c\
-\x32\x32\x34\x63\x30\x2d\x37\x2e\x39\x2c\x32\x2e\x39\x2d\x31\x35\
-\x2e\x31\x2c\x37\x2e\x36\x2d\x32\x30\x2e\x37\x63\x2d\x32\x2e\x35\
-\x2d\x30\x2e\x34\x2d\x35\x2d\x30\x2e\x36\x2d\x37\x2e\x36\x2d\x30\
-\x2e\x36\x63\x2d\x32\x38\x2e\x38\x2c\x30\x2d\x35\x32\x2e\x33\x2c\
-\x32\x33\x2e\x39\x2d\x35\x32\x2e\x33\x2c\x35\x33\x2e\x33\x63\x30\
-\x2c\x32\x39\x2e\x34\x2c\x32\x33\x2e\x35\x2c\x35\x33\x2e\x33\x2c\
-\x35\x32\x2e\x33\x2c\x35\x33\x2e\x33\x0d\x0a\x09\x09\x09\x73\x35\
-\x32\x2e\x33\x2d\x32\x33\x2e\x39\x2c\x35\x32\x2e\x33\x2d\x35\x33\
-\x2e\x33\x63\x30\x2d\x32\x2e\x33\x2d\x30\x2e\x32\x2d\x34\x2e\x36\
-\x2d\x30\x2e\x34\x2d\x36\x2e\x39\x63\x2d\x35\x2e\x35\x2c\x34\x2e\
-\x33\x2d\x31\x32\x2e\x33\x2c\x36\x2e\x39\x2d\x31\x39\x2e\x38\x2c\
-\x36\x2e\x39\x43\x32\x37\x30\x2e\x33\x2c\x32\x35\x36\x2c\x32\x35\
-\x36\x2c\x32\x34\x31\x2e\x37\x2c\x32\x35\x36\x2c\x32\x32\x34\x7a\
-\x22\x2f\x3e\x0d\x0a\x09\x3c\x2f\x67\x3e\x0d\x0a\x3c\x2f\x67\x3e\
-\x0d\x0a\x3c\x2f\x73\x76\x67\x3e\x0d\x0a\
-"
-
-qt_resource_name = b"\
-\x00\x05\
-\x00\x6f\xa6\x53\
-\x00\x69\
-\x00\x63\x00\x6f\x00\x6e\x00\x73\
-\x00\x0d\
-\x05\x20\xce\x87\
-\x00\x6f\
-\x00\x70\x00\x65\x00\x6e\x00\x63\x00\x75\x00\x72\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x09\
-\x0b\x9e\x89\x07\
-\x00\x63\
-\x00\x68\x00\x65\x00\x63\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x14\
-\x0f\xa5\xe0\xc7\
-\x00\x6d\
-\x00\x61\x00\x67\x00\x6e\x00\x69\x00\x66\x00\x79\x00\x69\x00\x6e\x00\x67\x00\x2d\x00\x67\x00\x6c\x00\x61\x00\x73\x00\x73\x00\x2e\
-\x00\x73\x00\x76\x00\x67\
-\x00\x0a\
-\x0f\x68\x53\xe7\
-\x00\x61\
-\x00\x6e\x00\x63\x00\x68\x00\x6f\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x0a\
-\x0a\xc8\x62\x67\
-\x00\x63\
-\x00\x65\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x10\
-\x04\xa9\x22\xc7\
-\x00\x66\
-\x00\x69\x00\x6c\x00\x6c\x00\x65\x00\x64\x00\x62\x00\x75\x00\x63\x00\x6b\x00\x65\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x10\
-\x08\x89\xfa\x47\
-\x00\x63\
-\x00\x65\x00\x6e\x00\x74\x00\x65\x00\x72\x00\x6f\x00\x72\x00\x69\x00\x67\x00\x69\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x08\
-\x08\xc8\x55\xe7\
-\x00\x73\
-\x00\x61\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x0e\
-\x0f\xcb\xd5\xc7\
-\x00\x70\
-\x00\x6c\x00\x75\x00\x73\x00\x2d\x00\x72\x00\x6f\x00\x75\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x12\
-\x08\x79\x97\xe7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x61\x00\x6d\x00\x65\x00\x72\x00\x61\x00\x2e\x00\x73\x00\x76\
-\x00\x67\
-\x00\x1c\
-\x08\x8a\x79\x07\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x61\x00\x64\x00\x69\x00\x6f\x00\x2d\x00\x62\x00\x75\x00\x74\
-\x00\x74\x00\x6f\x00\x6e\x00\x2d\x00\x6f\x00\x66\x00\x66\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x1c\
-\x04\x66\xe1\x67\
-\x00\x63\
-\x00\x68\x00\x65\x00\x76\x00\x72\x00\x6f\x00\x6e\x00\x2d\x00\x77\x00\x69\x00\x74\x00\x68\x00\x2d\x00\x63\x00\x69\x00\x72\x00\x63\
-\x00\x6c\x00\x65\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x11\
-\x0c\xdb\x38\xe7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\
-\x00\x17\
-\x06\xc6\x02\xa7\
-\x00\x74\
-\x00\x72\x00\x69\x00\x61\x00\x6e\x00\x67\x00\x6c\x00\x65\x00\x2d\x00\x73\x00\x74\x00\x72\x00\x6f\x00\x6b\x00\x65\x00\x64\x00\x2d\
-\x00\x31\x00\x35\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x08\
-\x08\xf7\x57\x07\
-\x00\x67\
-\x00\x72\x00\x69\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x0f\
-\x09\x76\x60\xc7\
-\x00\x63\
-\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x2d\x00\x72\x00\x6f\x00\x75\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x13\
-\x03\x24\x75\x47\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x65\x00\x66\x00\x72\x00\x65\x00\x73\x00\x68\x00\x2e\x00\x73\
-\x00\x76\x00\x67\
-\x00\x0a\
-\x01\xca\x6d\x87\
-\x00\x62\
-\x00\x75\x00\x63\x00\x6b\x00\x65\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x1d\
-\x06\xec\xf4\xc7\
-\x00\x63\
-\x00\x68\x00\x65\x00\x76\x00\x72\x00\x6f\x00\x6e\x00\x2d\x00\x77\x00\x69\x00\x74\x00\x68\x00\x2d\x00\x63\x00\x69\x00\x72\x00\x63\
-\x00\x6c\x00\x65\x00\x2d\x00\x72\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x08\
-\x0c\xf7\x55\x87\
-\x00\x74\
-\x00\x65\x00\x78\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x12\
-\x0c\x5e\xd4\xa7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x6c\x00\x6f\x00\x63\x00\x61\x00\x74\x00\x65\x00\x2e\x00\x73\x00\x76\
-\x00\x67\
-\x00\x12\
-\x04\xb2\x21\x47\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x65\x00\x78\x00\x70\x00\x61\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\
-\x00\x67\
-\x00\x08\
-\x05\xa8\x57\x87\
-\x00\x63\
-\x00\x6f\x00\x64\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x19\
-\x0a\x43\x45\xc7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x66\x00\x6f\x00\x72\
-\x00\x77\x00\x61\x00\x72\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x11\
-\x0c\xa7\xc7\x47\
-\x00\x63\
-\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x70\x00\x6f\x00\x6c\x00\x79\x00\x67\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\
-\x00\x0f\
-\x04\xf2\xa7\x87\
-\x00\x63\
-\x00\x6c\x00\x6f\x00\x73\x00\x65\x00\x64\x00\x63\x00\x75\x00\x72\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x0a\
-\x0a\x2d\x1b\xc7\
-\x00\x63\
-\x00\x69\x00\x72\x00\x63\x00\x6c\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x1b\
-\x0e\xb5\x68\xe7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x72\x00\x61\x00\x64\x00\x69\x00\x6f\x00\x2d\x00\x62\x00\x75\x00\x74\
-\x00\x74\x00\x6f\x00\x6e\x00\x2d\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x10\
-\x0c\x57\x65\x47\
-\x00\x61\
-\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x72\x00\x65\x00\x73\x00\x69\x00\x7a\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x12\
-\x08\x55\xef\xc7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x64\x00\x65\x00\x6c\x00\x65\x00\x74\x00\x65\x00\x2e\x00\x73\x00\x76\
-\x00\x67\
-\x00\x0f\
-\x07\x0e\xc4\x87\
-\x00\x6f\
-\x00\x70\x00\x65\x00\x6e\x00\x70\x00\x6f\x00\x6c\x00\x79\x00\x67\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x16\
-\x01\xfb\x76\x27\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x61\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x62\x00\x61\x00\x63\
-\x00\x6b\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x0e\
-\x05\xed\x38\x67\
-\x00\x61\
-\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x6d\x00\x6f\x00\x76\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x10\
-\x06\xe3\xaf\xe7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x68\x00\x61\x00\x6e\x00\x64\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x17\
-\x07\x87\x48\x27\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x66\x00\x6f\x00\x6c\x00\x64\x00\x65\x00\x72\x00\x2d\x00\x6f\x00\x70\
-\x00\x65\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x15\
-\x0f\xc4\x59\xe7\
-\x00\x73\
-\x00\x75\x00\x62\x00\x64\x00\x69\x00\x72\x00\x65\x00\x63\x00\x74\x00\x6f\x00\x72\x00\x79\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\
-\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x10\
-\x08\xe4\xaf\x47\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x64\x00\x6f\x00\x6e\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x08\
-\x0b\x07\x57\xa7\
-\x00\x65\
-\x00\x64\x00\x69\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x19\
-\x0f\xef\x7b\xe7\
-\x00\x61\
-\x00\x6e\x00\x64\x00\x72\x00\x6f\x00\x69\x00\x64\x00\x2d\x00\x63\x00\x6f\x00\x6c\x00\x6f\x00\x72\x00\x2d\x00\x70\x00\x61\x00\x6c\
-\x00\x65\x00\x74\x00\x74\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-\x00\x11\
-\x01\x60\xbc\x47\
-\x00\x73\
-\x00\x6f\x00\x63\x00\x69\x00\x61\x00\x6c\x00\x2d\x00\x70\x00\x79\x00\x74\x00\x68\x00\x6f\x00\x6e\x00\x2e\x00\x73\x00\x76\x00\x67\
-\
-\x00\x07\
-\x0c\xf8\x5a\x07\
-\x00\x65\
-\x00\x79\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\
-"
-
-qt_resource_struct_v1 = b"\
-\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
-\x00\x00\x00\x00\x00\x02\x00\x00\x00\x29\x00\x00\x00\x02\
-\x00\x00\x06\x10\x00\x00\x00\x00\x00\x01\x00\x00\x82\xd5\
-\x00\x00\x02\x96\x00\x00\x00\x00\x00\x01\x00\x00\x36\x4d\
-\x00\x00\x04\xbe\x00\x00\x00\x00\x00\x01\x00\x00\x68\xdb\
-\x00\x00\x02\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x33\x23\
-\x00\x00\x01\x96\x00\x00\x00\x00\x00\x01\x00\x00\x22\x76\
-\x00\x00\x00\xaa\x00\x01\x00\x00\x00\x01\x00\x00\x10\x6b\
-\x00\x00\x03\x30\x00\x00\x00\x00\x00\x01\x00\x00\x45\x97\
-\x00\x00\x03\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x54\x52\
-\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
-\x00\x00\x03\x5a\x00\x00\x00\x00\x00\x01\x00\x00\x48\xd1\
-\x00\x00\x04\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x6b\x5c\
-\x00\x00\x01\xfc\x00\x00\x00\x00\x00\x01\x00\x00\x29\x2a\
-\x00\x00\x05\x12\x00\x00\x00\x00\x00\x01\x00\x00\x6e\x29\
-\x00\x00\x02\xb0\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x25\
-\x00\x00\x04\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x64\x9a\
-\x00\x00\x05\x38\x00\x00\x00\x00\x00\x01\x00\x00\x73\xf7\
-\x00\x00\x04\x70\x00\x00\x00\x00\x00\x01\x00\x00\x61\xf4\
-\x00\x00\x01\x2e\x00\x00\x00\x00\x00\x01\x00\x00\x1c\x50\
-\x00\x00\x00\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x12\x90\
-\x00\x00\x01\x58\x00\x00\x00\x00\x00\x01\x00\x00\x1f\x76\
-\x00\x00\x00\xf6\x00\x00\x00\x00\x00\x01\x00\x00\x16\xb0\
-\x00\x00\x05\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x77\xbd\
-\x00\x00\x02\x30\x00\x01\x00\x00\x00\x01\x00\x00\x2d\xf8\
-\x00\x00\x02\x46\x00\x00\x00\x00\x00\x01\x00\x00\x2f\xd9\
-\x00\x00\x03\xf4\x00\x00\x00\x00\x00\x01\x00\x00\x59\x2b\
-\x00\x00\x03\x70\x00\x00\x00\x00\x00\x01\x00\x00\x4d\x7f\
-\x00\x00\x00\x90\x00\x00\x00\x00\x00\x01\x00\x00\x0c\xeb\
-\x00\x00\x05\xc2\x00\x00\x00\x00\x00\x01\x00\x00\x7a\x3a\
-\x00\x00\x00\x30\x00\x00\x00\x00\x00\x01\x00\x00\x04\xa6\
-\x00\x00\x04\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x5f\x71\
-\x00\x00\x03\x06\x00\x00\x00\x00\x00\x01\x00\x00\x41\x2f\
-\x00\x00\x03\xa8\x00\x00\x00\x00\x00\x01\x00\x00\x50\x00\
-\x00\x00\x01\xd4\x00\x00\x00\x00\x00\x01\x00\x00\x26\x6f\
-\x00\x00\x02\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x40\x0f\
-\x00\x00\x06\x38\x00\x00\x00\x00\x00\x01\x00\x00\x8a\x59\
-\x00\x00\x04\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x5c\x21\
-\x00\x00\x00\x76\x00\x00\x00\x00\x00\x01\x00\x00\x0b\x7e\
-\x00\x00\x00\x48\x00\x00\x00\x00\x00\x01\x00\x00\x07\xb6\
-\x00\x00\x05\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x77\x4d\
-\x00\x00\x01\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x19\x55\
-\x00\x00\x05\xd8\x00\x00\x00\x00\x00\x01\x00\x00\x7d\xaa\
-"
-
-qt_resource_struct_v2 = b"\
-\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
-\x00\x00\x00\x00\x00\x00\x00\x00\
-\x00\x00\x00\x00\x00\x02\x00\x00\x00\x29\x00\x00\x00\x02\
-\x00\x00\x00\x00\x00\x00\x00\x00\
-\x00\x00\x06\x10\x00\x00\x00\x00\x00\x01\x00\x00\x82\xd5\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x02\x96\x00\x00\x00\x00\x00\x01\x00\x00\x36\x4d\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x04\xbe\x00\x00\x00\x00\x00\x01\x00\x00\x68\xdb\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x02\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x33\x23\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x01\x96\x00\x00\x00\x00\x00\x01\x00\x00\x22\x76\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x00\xaa\x00\x01\x00\x00\x00\x01\x00\x00\x10\x6b\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x03\x30\x00\x00\x00\x00\x00\x01\x00\x00\x45\x97\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x03\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x54\x52\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x03\x5a\x00\x00\x00\x00\x00\x01\x00\x00\x48\xd1\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x04\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x6b\x5c\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x01\xfc\x00\x00\x00\x00\x00\x01\x00\x00\x29\x2a\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x05\x12\x00\x00\x00\x00\x00\x01\x00\x00\x6e\x29\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x02\xb0\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x25\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x04\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x64\x9a\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x05\x38\x00\x00\x00\x00\x00\x01\x00\x00\x73\xf7\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x04\x70\x00\x00\x00\x00\x00\x01\x00\x00\x61\xf4\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x01\x2e\x00\x00\x00\x00\x00\x01\x00\x00\x1c\x50\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x00\xd0\x00\x00\x00\x00\x00\x01\x00\x00\x12\x90\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x01\x58\x00\x00\x00\x00\x00\x01\x00\x00\x1f\x76\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x00\xf6\x00\x00\x00\x00\x00\x01\x00\x00\x16\xb0\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x05\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x77\xbd\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x02\x30\x00\x01\x00\x00\x00\x01\x00\x00\x2d\xf8\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x02\x46\x00\x00\x00\x00\x00\x01\x00\x00\x2f\xd9\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x03\xf4\x00\x00\x00\x00\x00\x01\x00\x00\x59\x2b\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x03\x70\x00\x00\x00\x00\x00\x01\x00\x00\x4d\x7f\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x00\x90\x00\x00\x00\x00\x00\x01\x00\x00\x0c\xeb\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x05\xc2\x00\x00\x00\x00\x00\x01\x00\x00\x7a\x3a\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x00\x30\x00\x00\x00\x00\x00\x01\x00\x00\x04\xa6\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x04\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x5f\x71\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x03\x06\x00\x00\x00\x00\x00\x01\x00\x00\x41\x2f\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x03\xa8\x00\x00\x00\x00\x00\x01\x00\x00\x50\x00\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x01\xd4\x00\x00\x00\x00\x00\x01\x00\x00\x26\x6f\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x02\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x40\x0f\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x06\x38\x00\x00\x00\x00\x00\x01\x00\x00\x8a\x59\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x04\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x5c\x21\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x00\x76\x00\x00\x00\x00\x00\x01\x00\x00\x0b\x7e\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-\x00\x00\x00\x48\x00\x00\x00\x00\x00\x01\x00\x00\x07\xb6\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x05\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x77\x4d\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x01\x0c\x00\x00\x00\x00\x00\x01\x00\x00\x19\x55\
-\x00\x00\x01\x78\x33\x4a\x26\xbc\
-\x00\x00\x05\xd8\x00\x00\x00\x00\x00\x01\x00\x00\x7d\xaa\
-\x00\x00\x01\x78\x33\x4a\x26\xbb\
-"
-
-qt_version = [int(v) for v in QtCore.qVersion().split('.')]
-if qt_version < [5, 8, 0]:
- rcc_version = 1
- qt_resource_struct = qt_resource_struct_v1
-else:
- rcc_version = 2
- qt_resource_struct = qt_resource_struct_v2
-
-def qInitResources():
- QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
-
-def qCleanupResources():
- QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
-
-qInitResources()
diff --git a/graphics/asymptote/GUI/labelEditor.py b/graphics/asymptote/GUI/labelEditor.py
index 76bc8d7d0a..7da1c5f903 100644
--- a/graphics/asymptote/GUI/labelEditor.py
+++ b/graphics/asymptote/GUI/labelEditor.py
@@ -1,22 +1,22 @@
#!/usr/bin/env python3
from pyUIClass.labelTextEditor import Ui_Dialog
-import PyQt5.QtWidgets as Qw
-import PyQt5.QtSvg as Qs
-import PyQt5.QtGui as Qg
-import PyQt5.QtCore as Qc
-import xasyArgs as xa
-import xasy2asy as x2a
+import PyQt5.QtWidgets as QtWidgets
+import PyQt5.QtSvg as QtSvg
+import PyQt5.QtGui as QtGui
+import PyQt5.QtCore as QtCore
+import xasyArgs as xasyArgs
+import xasy2asy as xasy2asy
+import xasyOptions as xasyOptions
+import xasyUtils as xasyUtils
import subprocess
-import xasyOptions as xo
-import xasyUtils as xu
import tempfile
import uuid
import os
import io
-class labelEditor(Qw.QDialog):
+class labelEditor(QtWidgets.QDialog):
def __init__(self, text=''):
super().__init__()
self.ui = Ui_Dialog()
@@ -67,9 +67,9 @@ class labelEditor(Qw.QDialog):
return rawText
def btnPreviewOnClick(self):
- path = xa.getArgs().asypath
+ path = xasyArgs.getArgs().asypath
if path is None:
- opt = xo.xasyOptions().load()
+ opt = xo.BasicConfigs.defaultOpt
path = opt['asyPath']
asyInput = """
@@ -80,7 +80,7 @@ class labelEditor(Qw.QDialog):
shipout(f);
"""
- self.svgPreview = Qs.QSvgRenderer()
+ self.svgPreview = QtSvg.QSvgRenderer()
with tempfile.TemporaryDirectory(prefix='xasylbl_') as tmpdir:
id = str(uuid.uuid4())
tmpFile = os.path.join(tmpdir, 'lbl-{0}.svg'.format(id))
@@ -95,8 +95,8 @@ class labelEditor(Qw.QDialog):
bounds_1, bounds_2 = [val.strip() for val in raw_array]
- min_bounds = xu.listize(bounds_1, (float, float))
- max_bounds = xu.listize(bounds_2, (float, float))
+ min_bounds = xasyUtils.listize(bounds_1, (float, float))
+ max_bounds = xasyUtils.listize(bounds_2, (float, float))
new_rect = self.processBounds(min_bounds, max_bounds)
self.svgPreview.load(tmpFile)
@@ -106,12 +106,12 @@ class labelEditor(Qw.QDialog):
self.drawPreview(new_rect)
def drawPreview(self, naturalBounds):
- img = Qg.QPixmap(self.ui.lblLabelPreview.size())
- img.fill(Qg.QColor.fromRgbF(1, 1, 1, 1))
+ img = QtGui.QPixmap(self.ui.lblLabelPreview.size())
+ img.fill(QtGui.QColor.fromRgbF(1, 1, 1, 1))
if self.svgPreview is None:
pass
else:
- with Qg.QPainter(img) as pnt:
+ with QtGui.QPainter(img) as pnt:
scale_ratio = self.getIdealScaleRatio(naturalBounds, self.ui.lblLabelPreview.rect())
pnt.translate(self.ui.lblLabelPreview.rect().center())
@@ -121,8 +121,8 @@ class labelEditor(Qw.QDialog):
def getIdealScaleRatio(self, rect, boundsRect):
- assert isinstance(rect, (Qc.QRect, Qc.QRectF))
- assert isinstance(rect, (Qc.QRect, Qc.QRectF))
+ assert isinstance(rect, (QtCore.QRect, QtCore.QRectF))
+ assert isinstance(rect, (QtCore.QRect, QtCore.QRectF))
magic_ratio = 0.50
idealRatioHeight = (magic_ratio * boundsRect.height()) / rect.height()
@@ -139,15 +139,15 @@ class labelEditor(Qw.QDialog):
p1x, p1y = minPt
p2x, p2y = maxPt
- minPt = Qc.QPointF(p1x, p1y)
- maxPt = Qc.QPointF(p2x, p2y)
+ minPt = QtCore.QPointF(p1x, p1y)
+ maxPt = QtCore.QPointF(p2x, p2y)
- newRect = Qc.QRectF(minPt, maxPt)
+ newRect = QtCore.QRectF(minPt, maxPt)
return newRect
def btnGetTextOnClick(self):
- msgbox = Qw.QMessageBox()
+ msgbox = QtWidgets.QMessageBox()
msgbox.setText('Text Preview:\n' + self.getText())
msgbox.setWindowTitle('Text preview')
msgbox.show()
diff --git a/graphics/asymptote/GUI/pyUIClass/custMatTransform.py b/graphics/asymptote/GUI/pyUIClass/custMatTransform.py
index d0bddd4645..aeaf61f9a2 100644
--- a/graphics/asymptote/GUI/pyUIClass/custMatTransform.py
+++ b/graphics/asymptote/GUI/pyUIClass/custMatTransform.py
@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file 'GUI/windows/custMatTransform.ui'
#
-# Created by: PyQt5 UI code generator 5.13.1
+# Created by: PyQt5 UI code generator 5.15.0
#
-# WARNING! All changes made in this file will be lost!
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
diff --git a/graphics/asymptote/GUI/pyUIClass/labelTextEditor.py b/graphics/asymptote/GUI/pyUIClass/labelTextEditor.py
index 3cb24c9e2f..fc35454c83 100644
--- a/graphics/asymptote/GUI/pyUIClass/labelTextEditor.py
+++ b/graphics/asymptote/GUI/pyUIClass/labelTextEditor.py
@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file 'GUI/windows/labelTextEditor.ui'
#
-# Created by: PyQt5 UI code generator 5.13.1
+# Created by: PyQt5 UI code generator 5.15.0
#
-# WARNING! All changes made in this file will be lost!
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
diff --git a/graphics/asymptote/GUI/pyUIClass/setCustomAnchor.py b/graphics/asymptote/GUI/pyUIClass/setCustomAnchor.py
index 9b76e5d6d0..ab0fc77c0b 100644
--- a/graphics/asymptote/GUI/pyUIClass/setCustomAnchor.py
+++ b/graphics/asymptote/GUI/pyUIClass/setCustomAnchor.py
@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file 'GUI/windows/setCustomAnchor.ui'
#
-# Created by: PyQt5 UI code generator 5.13.1
+# Created by: PyQt5 UI code generator 5.15.0
#
-# WARNING! All changes made in this file will be lost!
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
diff --git a/graphics/asymptote/GUI/pyUIClass/widg_addLabel.py b/graphics/asymptote/GUI/pyUIClass/widg_addLabel.py
index 0412fc550d..9b17990e6b 100644
--- a/graphics/asymptote/GUI/pyUIClass/widg_addLabel.py
+++ b/graphics/asymptote/GUI/pyUIClass/widg_addLabel.py
@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file 'GUI/windows/widg_addLabel.ui'
#
-# Created by: PyQt5 UI code generator 5.13.1
+# Created by: PyQt5 UI code generator 5.15.0
#
-# WARNING! All changes made in this file will be lost!
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
diff --git a/graphics/asymptote/GUI/pyUIClass/widg_addPolyOpt.py b/graphics/asymptote/GUI/pyUIClass/widg_addPolyOpt.py
index 2c91681bce..69cf2a4630 100644
--- a/graphics/asymptote/GUI/pyUIClass/widg_addPolyOpt.py
+++ b/graphics/asymptote/GUI/pyUIClass/widg_addPolyOpt.py
@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file 'GUI/windows/widg_addPolyOpt.ui'
#
-# Created by: PyQt5 UI code generator 5.13.1
+# Created by: PyQt5 UI code generator 5.15.0
#
-# WARNING! All changes made in this file will be lost!
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
@@ -31,11 +32,21 @@ class Ui_Form(object):
self.chkInscribed = QtWidgets.QCheckBox(Form)
self.chkInscribed.setObjectName("chkInscribed")
self.horizontalLayout.addWidget(self.chkInscribed)
+ spacerItem = QtWidgets.QSpacerItem(19, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem)
+ self.label = QtWidgets.QLabel(Form)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
+ self.label.setSizePolicy(sizePolicy)
+ self.label.setObjectName("label")
+ self.horizontalLayout.addWidget(self.label)
self.txtSides = QtWidgets.QLineEdit(Form)
self.txtSides.setObjectName("txtSides")
self.horizontalLayout.addWidget(self.txtSides)
- spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
- self.horizontalLayout.addItem(spacerItem)
+ spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem1)
self.horizontalLayout_2.addLayout(self.horizontalLayout)
self.retranslateUi(Form)
@@ -45,5 +56,6 @@ class Ui_Form(object):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.chkInscribed.setText(_translate("Form", "Start at Vertex"))
+ self.label.setText(_translate("Form", "Sides: "))
self.txtSides.setToolTip(_translate("Form", "Number of Sides"))
self.txtSides.setPlaceholderText(_translate("Form", "Sides"))
diff --git a/graphics/asymptote/GUI/pyUIClass/widg_editBezier.py b/graphics/asymptote/GUI/pyUIClass/widg_editBezier.py
index d39e49e4b9..4c2d90d712 100644
--- a/graphics/asymptote/GUI/pyUIClass/widg_editBezier.py
+++ b/graphics/asymptote/GUI/pyUIClass/widg_editBezier.py
@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file 'GUI/windows/widg_editBezier.ui'
#
-# Created by: PyQt5 UI code generator 5.13.1
+# Created by: PyQt5 UI code generator 5.15.0
#
-# WARNING! All changes made in this file will be lost!
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
diff --git a/graphics/asymptote/GUI/pyUIClass/widgetPointEditor.py b/graphics/asymptote/GUI/pyUIClass/widgetPointEditor.py
index a38790bdec..0b4f5d9493 100644
--- a/graphics/asymptote/GUI/pyUIClass/widgetPointEditor.py
+++ b/graphics/asymptote/GUI/pyUIClass/widgetPointEditor.py
@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file 'GUI/windows/widgetPointEditor.ui'
#
-# Created by: PyQt5 UI code generator 5.13.1
+# Created by: PyQt5 UI code generator 5.15.0
#
-# WARNING! All changes made in this file will be lost!
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
diff --git a/graphics/asymptote/GUI/pyUIClass/window1.py b/graphics/asymptote/GUI/pyUIClass/window1.py
index 6180d5fed3..edf87b84c1 100644
--- a/graphics/asymptote/GUI/pyUIClass/window1.py
+++ b/graphics/asymptote/GUI/pyUIClass/window1.py
@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file 'GUI/windows/window1.ui'
#
-# Created by: PyQt5 UI code generator 5.13.1
+# Created by: PyQt5 UI code generator 5.15.0
#
-# WARNING! All changes made in this file will be lost!
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
@@ -62,7 +63,7 @@ class Ui_MainWindow(object):
self.btnUndo.setBaseSize(QtCore.QSize(32, 32))
self.btnUndo.setText("")
icon = QtGui.QIcon()
- icon.addPixmap(QtGui.QPixmap(":/icons/android-arrow-back.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon.addPixmap(QtGui.QPixmap(":/icons/undo.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnUndo.setIcon(icon)
self.btnUndo.setIconSize(QtCore.QSize(16, 16))
self.btnUndo.setFlat(True)
@@ -79,7 +80,7 @@ class Ui_MainWindow(object):
self.btnRedo.setBaseSize(QtCore.QSize(32, 32))
self.btnRedo.setText("")
icon1 = QtGui.QIcon()
- icon1.addPixmap(QtGui.QPixmap(":/icons/android-arrow-forward.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon1.addPixmap(QtGui.QPixmap(":/icons/redo.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnRedo.setIcon(icon1)
self.btnRedo.setIconSize(QtCore.QSize(16, 16))
self.btnRedo.setFlat(True)
@@ -251,7 +252,7 @@ class Ui_MainWindow(object):
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.btnAlignX.sizePolicy().hasHeightForWidth())
self.btnAlignX.setSizePolicy(sizePolicy)
- self.btnAlignX.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnAlignX.setMaximumSize(QtCore.QSize(32, 25))
self.btnAlignX.setBaseSize(QtCore.QSize(32, 32))
font = QtGui.QFont()
font.setFamily("Roboto")
@@ -269,9 +270,10 @@ class Ui_MainWindow(object):
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.btnAlignY.sizePolicy().hasHeightForWidth())
self.btnAlignY.setSizePolicy(sizePolicy)
- self.btnAlignY.setMaximumSize(QtCore.QSize(25, 25))
+ self.btnAlignY.setMaximumSize(QtCore.QSize(32, 25))
self.btnAlignY.setBaseSize(QtCore.QSize(32, 32))
font = QtGui.QFont()
+ font.setFamily("Roboto")
font.setBold(True)
font.setWeight(75)
self.btnAlignY.setFont(font)
@@ -295,6 +297,7 @@ class Ui_MainWindow(object):
icon11.addPixmap(QtGui.QPixmap(":/icons/edit.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnSelectEdit.setIcon(icon11)
self.btnSelectEdit.setIconSize(QtCore.QSize(16, 16))
+ self.btnSelectEdit.setCheckable(True)
self.btnSelectEdit.setFlat(True)
self.btnSelectEdit.setObjectName("btnSelectEdit")
self.horizontalLayout.addWidget(self.btnSelectEdit)
@@ -312,7 +315,7 @@ class Ui_MainWindow(object):
icon12.addPixmap(QtGui.QPixmap(":/icons/android-delete.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnDeleteMode.setIcon(icon12)
self.btnDeleteMode.setIconSize(QtCore.QSize(16, 16))
- self.btnDeleteMode.setCheckable(False)
+ self.btnDeleteMode.setCheckable(True)
self.btnDeleteMode.setFlat(True)
self.btnDeleteMode.setObjectName("btnDeleteMode")
self.horizontalLayout.addWidget(self.btnDeleteMode)
@@ -646,6 +649,7 @@ class Ui_MainWindow(object):
icon24.addPixmap(QtGui.QPixmap(":/icons/openpolygon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnOpenPoly.setIcon(icon24)
self.btnOpenPoly.setIconSize(QtCore.QSize(16, 16))
+ self.btnOpenPoly.setCheckable(True)
self.btnOpenPoly.setFlat(True)
self.btnOpenPoly.setObjectName("btnOpenPoly")
self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.btnOpenPoly)
@@ -662,6 +666,7 @@ class Ui_MainWindow(object):
icon25.addPixmap(QtGui.QPixmap(":/icons/closedpolygon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnClosedPoly.setIcon(icon25)
self.btnClosedPoly.setIconSize(QtCore.QSize(16, 16))
+ self.btnClosedPoly.setCheckable(True)
self.btnClosedPoly.setFlat(True)
self.btnClosedPoly.setObjectName("btnClosedPoly")
self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.btnClosedPoly)
@@ -678,6 +683,7 @@ class Ui_MainWindow(object):
icon26.addPixmap(QtGui.QPixmap(":/icons/opencurve.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnOpenCurve.setIcon(icon26)
self.btnOpenCurve.setIconSize(QtCore.QSize(16, 16))
+ self.btnOpenCurve.setCheckable(True)
self.btnOpenCurve.setFlat(True)
self.btnOpenCurve.setObjectName("btnOpenCurve")
self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.btnOpenCurve)
@@ -694,6 +700,7 @@ class Ui_MainWindow(object):
icon27.addPixmap(QtGui.QPixmap(":/icons/closedcurve.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnClosedCurve.setIcon(icon27)
self.btnClosedCurve.setIconSize(QtCore.QSize(16, 16))
+ self.btnClosedCurve.setCheckable(True)
self.btnClosedCurve.setFlat(True)
self.btnClosedCurve.setObjectName("btnClosedCurve")
self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.btnClosedCurve)
@@ -710,6 +717,7 @@ class Ui_MainWindow(object):
icon28.addPixmap(QtGui.QPixmap(":/icons/triangle-stroked-15.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnAddPoly.setIcon(icon28)
self.btnAddPoly.setIconSize(QtCore.QSize(16, 16))
+ self.btnAddPoly.setCheckable(True)
self.btnAddPoly.setFlat(True)
self.btnAddPoly.setObjectName("btnAddPoly")
self.formLayout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.btnAddPoly)
@@ -726,6 +734,7 @@ class Ui_MainWindow(object):
icon29.addPixmap(QtGui.QPixmap(":/icons/circle.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnAddCircle.setIcon(icon29)
self.btnAddCircle.setIconSize(QtCore.QSize(16, 16))
+ self.btnAddCircle.setCheckable(True)
self.btnAddCircle.setFlat(True)
self.btnAddCircle.setObjectName("btnAddCircle")
self.formLayout.setWidget(10, QtWidgets.QFormLayout.LabelRole, self.btnAddCircle)
@@ -742,9 +751,27 @@ class Ui_MainWindow(object):
icon30.addPixmap(QtGui.QPixmap(":/icons/text.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.btnAddLabel.setIcon(icon30)
self.btnAddLabel.setIconSize(QtCore.QSize(16, 16))
+ self.btnAddLabel.setCheckable(True)
self.btnAddLabel.setFlat(True)
self.btnAddLabel.setObjectName("btnAddLabel")
self.formLayout.setWidget(11, QtWidgets.QFormLayout.LabelRole, self.btnAddLabel)
+ self.btnAddFreehand = QtWidgets.QPushButton(self.formFrame)
+ self.btnAddFreehand.setEnabled(True)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.btnAddFreehand.sizePolicy().hasHeightForWidth())
+ self.btnAddFreehand.setSizePolicy(sizePolicy)
+ self.btnAddFreehand.setMaximumSize(QtCore.QSize(32, 32))
+ self.btnAddFreehand.setText("")
+ icon31 = QtGui.QIcon()
+ icon31.addPixmap(QtGui.QPixmap(":/icons/brush.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnAddFreehand.setIcon(icon31)
+ self.btnAddFreehand.setIconSize(QtCore.QSize(16, 16))
+ self.btnAddFreehand.setCheckable(True)
+ self.btnAddFreehand.setFlat(True)
+ self.btnAddFreehand.setObjectName("btnAddFreehand")
+ self.formLayout.setWidget(12, QtWidgets.QFormLayout.LabelRole, self.btnAddFreehand)
self.horizontalLayout_7.addWidget(self.formFrame)
self.imgFrame = QtWidgets.QFrame(self.mainWidget)
self.imgFrame.setMinimumSize(QtCore.QSize(0, 6))
@@ -783,9 +810,9 @@ class Ui_MainWindow(object):
sizePolicy.setHeightForWidth(self.btnTogglePython.sizePolicy().hasHeightForWidth())
self.btnTogglePython.setSizePolicy(sizePolicy)
self.btnTogglePython.setText("")
- icon31 = QtGui.QIcon()
- icon31.addPixmap(QtGui.QPixmap(":/icons/social-python.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.btnTogglePython.setIcon(icon31)
+ icon32 = QtGui.QIcon()
+ icon32.addPixmap(QtGui.QPixmap(":/icons/social-python.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnTogglePython.setIcon(icon32)
self.btnTogglePython.setIconSize(QtCore.QSize(16, 16))
self.btnTogglePython.setCheckable(True)
self.btnTogglePython.setFlat(True)
@@ -807,9 +834,9 @@ class Ui_MainWindow(object):
sizePolicy.setHeightForWidth(self.btnEnterCommand.sizePolicy().hasHeightForWidth())
self.btnEnterCommand.setSizePolicy(sizePolicy)
self.btnEnterCommand.setText("")
- icon32 = QtGui.QIcon()
- icon32.addPixmap(QtGui.QPixmap(":/icons/subdirectory-left.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
- self.btnEnterCommand.setIcon(icon32)
+ icon33 = QtGui.QIcon()
+ icon33.addPixmap(QtGui.QPixmap(":/icons/subdirectory-left.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.btnEnterCommand.setIcon(icon33)
self.btnEnterCommand.setIconSize(QtCore.QSize(16, 16))
self.btnEnterCommand.setFlat(True)
self.btnEnterCommand.setObjectName("btnEnterCommand")
@@ -820,10 +847,12 @@ class Ui_MainWindow(object):
self.horizontalLayout_4.addWidget(self.mainWidget)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
- self.menubar.setGeometry(QtCore.QRect(0, 0, 1000, 29))
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 1000, 26))
self.menubar.setObjectName("menubar")
self.menuFIle = QtWidgets.QMenu(self.menubar)
self.menuFIle.setObjectName("menuFIle")
+ self.menuOpenRecent = QtWidgets.QMenu(self.menuFIle)
+ self.menuOpenRecent.setObjectName("menuOpenRecent")
self.menuEdit = QtWidgets.QMenu(self.menubar)
self.menuEdit.setObjectName("menuEdit")
self.menuOptions = QtWidgets.QMenu(self.menubar)
@@ -869,9 +898,22 @@ class Ui_MainWindow(object):
self.actionSave.setObjectName("actionSave")
self.actionOpen = QtWidgets.QAction(MainWindow)
self.actionOpen.setObjectName("actionOpen")
+ self.actionClearRecent = QtWidgets.QAction(MainWindow)
+ self.actionClearRecent.setObjectName("actionClearRecent")
+ self.actionNewFile = QtWidgets.QAction(MainWindow)
+ self.actionNewFile.setObjectName("actionNewFile")
+ self.actionExportToAsy = QtWidgets.QAction(MainWindow)
+ self.actionExportToAsy.setObjectName("actionExportToAsy")
+ self.actionKeymaps = QtWidgets.QAction(MainWindow)
+ self.actionKeymaps.setObjectName("actionKeymaps")
+ self.menuOpenRecent.addSeparator()
+ self.menuOpenRecent.addAction(self.actionClearRecent)
+ self.menuFIle.addAction(self.actionNewFile)
self.menuFIle.addAction(self.actionOpen)
+ self.menuFIle.addAction(self.menuOpenRecent.menuAction())
self.menuFIle.addAction(self.actionSave)
self.menuFIle.addAction(self.actionSaveAs)
+ self.menuFIle.addAction(self.actionExportToAsy)
self.menuFIle.addAction(self.actionExportAsymptote)
self.menuFIle.addSeparator()
self.menuFIle.addAction(self.actionQuit)
@@ -879,6 +921,7 @@ class Ui_MainWindow(object):
self.menuEdit.addAction(self.actionRedo)
self.menuEdit.addSeparator()
self.menuOptions.addAction(self.actionSettings)
+ self.menuOptions.addAction(self.actionKeymaps)
self.menuHelp.addAction(self.actionManual)
self.menuHelp.addAction(self.actionAbout)
self.menuTools.addAction(self.actionEnterCommand)
@@ -941,7 +984,9 @@ class Ui_MainWindow(object):
self.btnAddPoly.setToolTip(_translate("MainWindow", "<html><head/><body><p>Regular polygon</p></body></html>"))
self.btnAddCircle.setToolTip(_translate("MainWindow", "<html><head/><body><p>Circle</p></body></html>"))
self.btnAddLabel.setToolTip(_translate("MainWindow", "<html><head/><body><p>Text</p></body></html>"))
+ self.btnAddFreehand.setToolTip(_translate("MainWindow", "<html><head/><body><p>Freehand</p></body></html>"))
self.menuFIle.setTitle(_translate("MainWindow", "&File"))
+ self.menuOpenRecent.setTitle(_translate("MainWindow", "Open Recent"))
self.menuEdit.setTitle(_translate("MainWindow", "&Edit"))
self.menuOptions.setTitle(_translate("MainWindow", "Optio&ns"))
self.menuHelp.setTitle(_translate("MainWindow", "&Help"))
@@ -950,7 +995,7 @@ class Ui_MainWindow(object):
self.actionManual.setText(_translate("MainWindow", "&Manual"))
self.actionSettings.setText(_translate("MainWindow", "&Settings"))
self.actionPause.setText(_translate("MainWindow", "Pause "))
- self.actionSaveAs.setText(_translate("MainWindow", "&Save As"))
+ self.actionSaveAs.setText(_translate("MainWindow", "&Save as"))
self.actionEnterCommand.setText(_translate("MainWindow", "&Enter Command"))
self.actionQuit.setText(_translate("MainWindow", "&Quit"))
self.actionUndo.setText(_translate("MainWindow", "&Undo"))
@@ -958,7 +1003,11 @@ class Ui_MainWindow(object):
self.actionShow_Grid.setText(_translate("MainWindow", "&Show Grid"))
self.actionShow_Local_Grid.setText(_translate("MainWindow", "Show &Local Grid"))
self.actionTransform.setText(_translate("MainWindow", "&Transform"))
- self.actionExportAsymptote.setText(_translate("MainWindow", "Export"))
+ self.actionExportAsymptote.setText(_translate("MainWindow", "Export as..."))
self.actionSave.setText(_translate("MainWindow", "Save"))
self.actionOpen.setText(_translate("MainWindow", "Open"))
+ self.actionClearRecent.setText(_translate("MainWindow", "Clear Menu"))
+ self.actionNewFile.setText(_translate("MainWindow", "New File"))
+ self.actionExportToAsy.setText(_translate("MainWindow", "Export as Asy"))
+ self.actionKeymaps.setText(_translate("MainWindow", "&Keymaps"))
import icons_rc
diff --git a/graphics/asymptote/GUI/res/icons.qrc b/graphics/asymptote/GUI/res/icons.qrc
index 50928ef9b7..5ca468acc2 100644
--- a/graphics/asymptote/GUI/res/icons.qrc
+++ b/graphics/asymptote/GUI/res/icons.qrc
@@ -41,5 +41,8 @@
<file>icons/android-radio-button-off.svg</file>
<file>icons/android-locate.svg</file>
<file>icons/close-round.svg</file>
+ <file>icons/brush.svg</file>
+ <file>icons/undo.svg</file>
+ <file>icons/redo.svg</file>
</qresource>
</RCC>
diff --git a/graphics/asymptote/GUI/res/icons/brush.svg b/graphics/asymptote/GUI/res/icons/brush.svg
new file mode 100644
index 0000000000..0c6a54340b
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/brush.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g>
+ <path d="M48.451,464.828c40.023-0.315,45.01-9.955,58.052-50.132c24.057-63.408,132.419,16.591,65.269,44.374
+ C104.622,486.852,8.428,465.143,48.451,464.828z"/>
+ <path d="M458.857,46.902c-19.417-15.647-51.592-7.938-71.864,17.219L181.645,355.849c-20.272,25.154-20.171,20.347-0.754,35.992
+ c19.417,15.648,14.738,16.77,35.011-8.388l241.406-262.669C477.581,95.628,478.275,62.55,458.857,46.902z M406.065,81.825
+ c0,0-3-3.5-13-11.5c15-24.5,44.5-20,44.5-20C409.565,66.825,406.065,81.825,406.065,81.825z"/>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/bucket.asy b/graphics/asymptote/GUI/res/icons/bucket.asy
index 8744743698..5f6e071cce 100644
--- a/graphics/asymptote/GUI/res/icons/bucket.asy
+++ b/graphics/asymptote/GUI/res/icons/bucket.asy
@@ -9,7 +9,7 @@ path left=(-r,h)--(-r,0);
path right=(r,0)--(r,h);
path bottom=xscale(r)*arc(0,1,180,360);
-real H=0.9h;
+real H=0.8h;
path Left=(-r,H/2)--(-r,0);
path Right=(r,0)--(r,H/2);
@@ -17,7 +17,7 @@ bool fill=false; // Set to true for filled bucket.
usersetting();
if(fill)
- fill(Left--bottom--Right--shift(0,H)*xscale(r)*arc(0,1,0,180)--cycle,gray);
+ fill(Left--bottom--Right--shift(0,H)*xscale(r)*arc(0,1,0,180)--cycle,paleblue);
draw(shift(0,h)*xscale(r)*unitcircle);
draw(left--bottom--right);
diff --git a/graphics/asymptote/GUI/res/icons/bucket.svg b/graphics/asymptote/GUI/res/icons/bucket.svg
index 4a41e9873b..11a867ac9f 100644
--- a/graphics/asymptote/GUI/res/icons/bucket.svg
+++ b/graphics/asymptote/GUI/res/icons/bucket.svg
@@ -1,15 +1,15 @@
<?xml version='1.0' encoding='UTF-8'?>
-<!-- This file was generated by dvisvgm 2.8 -->
-<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'>
+<!-- This file was generated by dvisvgm 2.11.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='64pt' viewBox='56.4094 117.858 63.9996 64'>
<g id='page1'>
-<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'>
-<path d='M 54.8926 -39.7109C 54.8926 -43.9032 44.6969 -47.3017 32.12 -47.3017C 19.5431 -47.3017 9.34742 -43.9032 9.34742 -39.7109C 9.34742 -35.5185 19.5431 -32.12 32.12 -32.12C 44.6969 -32.12 54.8926 -35.5185 54.8926 -39.7109Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/>
+<g transform='translate(56.4094 117.858)scale(.996264)'>
+<path d='M 54.8926 24.5291C 54.8926 20.3368 44.6969 16.9383 32.12 16.9383C 19.5431 16.9383 9.34742 20.3368 9.34742 24.5291C 9.34742 28.7215 19.5431 32.12 32.12 32.12C 44.6969 32.12 54.8926 28.7215 54.8926 24.5291Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'>
-<path d='M 9.34742 -39.7109L 9.34742 -9.34742L 9.34742 -9.34742C 9.34742 -9.34742 9.34742 -9.34742 9.34742 -9.34742C 9.34742 -5.15511 19.5431 -1.75656 32.12 -1.75656C 44.6969 -1.75656 54.8926 -5.15511 54.8926 -9.34742L 54.8926 -9.34742L 54.8926 -39.7109' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/>
+<g transform='translate(56.4094 117.858)scale(.996264)'>
+<path d='M 9.34742 24.5291L 9.34742 54.8926L 9.34742 54.8926C 9.34742 54.8926 9.34742 54.8926 9.34742 54.8926C 9.34742 59.0849 19.5431 62.4834 32.12 62.4834C 44.6969 62.4834 54.8926 59.0849 54.8926 54.8926L 54.8926 54.8926L 54.8926 24.5291' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'>
-<path d='M 54.8926 -39.7109C 54.8926 -52.2878 44.6969 -62.4834 32.12 -62.4834C 19.5431 -62.4834 9.34742 -52.2878 9.34742 -39.7109' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/>
+<g transform='translate(56.4094 117.858)scale(.996264)'>
+<path d='M 54.8926 24.5291C 54.8926 11.9522 44.6969 1.75656 32.12 1.75656C 19.5431 1.75656 9.34742 11.9522 9.34742 24.5291' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/>
</g>
</g>
</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/center.svg b/graphics/asymptote/GUI/res/icons/center.svg
index 9a7cb1b17d..6c378d1e7e 100644
--- a/graphics/asymptote/GUI/res/icons/center.svg
+++ b/graphics/asymptote/GUI/res/icons/center.svg
@@ -1,12 +1,12 @@
<?xml version='1.0' encoding='UTF-8'?>
-<!-- This file was generated by dvisvgm 2.8 -->
-<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'>
+<!-- This file was generated by dvisvgm 2.11.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='64pt' viewBox='56.4094 117.858 63.9996 64'>
<g id='page1'>
-<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'>
-<path d='M 2.0075 -2.0075L 62.2325 -2.0075L 62.2325 -62.2325L 2.0075 -62.2325L 2.0075 -2.0075Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/>
+<g transform='translate(56.4094 117.858)scale(.996264)'>
+<path d='M 2.0075 62.2325L 62.2325 62.2325L 62.2325 2.0075L 2.0075 2.0075L 2.0075 62.2325Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'>
-<path d='M 47.1762 -32.12C 47.1762 -40.4353 40.4353 -47.1762 32.12 -47.1762C 23.8047 -47.1762 17.0637 -40.4353 17.0637 -32.12C 17.0637 -23.8047 23.8047 -17.0637 32.12 -17.0637C 40.4353 -17.0637 47.1762 -23.8047 47.1762 -32.12Z' fill='#000000'/>
+<g transform='translate(56.4094 117.858)scale(.996264)'>
+<path d='M 47.1762 32.12C 47.1762 23.8047 40.4353 17.0637 32.12 17.0637C 23.8047 17.0637 17.0637 23.8047 17.0637 32.12C 17.0637 40.4353 23.8047 47.1762 32.12 47.1762C 40.4353 47.1762 47.1762 40.4353 47.1762 32.12Z' fill='#000000'/>
</g>
</g>
</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/centerorigin.svg b/graphics/asymptote/GUI/res/icons/centerorigin.svg
index ee3cca2629..cce97c373b 100644
--- a/graphics/asymptote/GUI/res/icons/centerorigin.svg
+++ b/graphics/asymptote/GUI/res/icons/centerorigin.svg
@@ -1,15 +1,15 @@
<?xml version='1.0' encoding='UTF-8'?>
-<!-- This file was generated by dvisvgm 2.8 -->
-<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'>
+<!-- This file was generated by dvisvgm 2.11.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='64pt' viewBox='56.4094 117.858 63.9996 64'>
<g id='page1'>
-<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'>
-<path d='M 2.0075 -2.0075L 62.2325 -2.0075L 62.2325 -62.2325L 2.0075 -62.2325L 2.0075 -2.0075Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/>
+<g transform='translate(56.4094 117.858)scale(.996264)'>
+<path d='M 2.0075 62.2325L 62.2325 62.2325L 62.2325 2.0075L 2.0075 2.0075L 2.0075 62.2325Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'>
-<path d='M 2.0075 -32.12L 62.2325 -32.12' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/>
+<g transform='translate(56.4094 117.858)scale(.996264)'>
+<path d='M 2.0075 32.12L 62.2325 32.12' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'>
-<path d='M 32.12 -2.0075L 32.12 -62.2325' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/>
+<g transform='translate(56.4094 117.858)scale(.996264)'>
+<path d='M 32.12 62.2325L 32.12 2.0075' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='4.015'/>
</g>
</g>
</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/closedcurve.asy b/graphics/asymptote/GUI/res/icons/closedcurve.asy
index 80e7061971..9d1679b499 100644
--- a/graphics/asymptote/GUI/res/icons/closedcurve.asy
+++ b/graphics/asymptote/GUI/res/icons/closedcurve.asy
@@ -2,6 +2,6 @@ defaultpen(2.5);
path p=W..NW..ENE..0.5*SE..cycle;
draw(p);
-dot(p,linewidth(12));
+dot(p,red+linewidth(12));
shipout(pad(64,64));
diff --git a/graphics/asymptote/GUI/res/icons/closedcurve.svg b/graphics/asymptote/GUI/res/icons/closedcurve.svg
index 32cf982cf1..33de78fc38 100644
--- a/graphics/asymptote/GUI/res/icons/closedcurve.svg
+++ b/graphics/asymptote/GUI/res/icons/closedcurve.svg
@@ -1,21 +1,21 @@
<?xml version='1.0' encoding='UTF-8'?>
-<!-- This file was generated by dvisvgm 2.8 -->
-<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'>
+<!-- This file was generated by dvisvgm 2.11.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='64.0001pt' height='64pt' viewBox='58.4669 117.858 64.0001 64'>
<g id='page1'>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<path d='M 3.95735 -32.12C 2.28922 -39.3113 6.36702 -46.2386 11.9036 -51.3039C 29.6687 -67.5568 55.2292 -60.642 56.1523 -42.5022C 56.6136 -33.4381 49.1132 -26.5959 40.6794 -22.5281C 25.3995 -15.1582 7.19935 -18.1436 3.95735 -32.12Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<path d='M 6.0225 32.12C 4.35438 24.9287 8.43217 18.0014 13.9687 12.9361C 31.7339 -3.31675 57.2943 3.59797 58.2175 21.7378C 58.6788 30.8019 51.1783 37.6441 42.7445 41.7119C 27.4646 49.0818 9.26451 46.0964 6.0225 32.12Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='3.95735' cy='-32.12' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='6.0225' cy='32.12' fill='#ff0000' r='6.0225'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='11.9036' cy='-51.3039' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='13.9687' cy='12.9361' fill='#ff0000' r='6.0225'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='56.1523' cy='-42.5022' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='58.2175' cy='21.7378' fill='#ff0000' r='6.0225'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='40.6794' cy='-22.5281' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='42.7445' cy='41.7119' fill='#ff0000' r='6.0225'/>
</g>
</g>
</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/closedpolygon.asy b/graphics/asymptote/GUI/res/icons/closedpolygon.asy
index 612bdcf010..871af18c85 100644
--- a/graphics/asymptote/GUI/res/icons/closedpolygon.asy
+++ b/graphics/asymptote/GUI/res/icons/closedpolygon.asy
@@ -2,6 +2,6 @@ defaultpen(2.5);
path p=W--NW--ENE--0.5*SE--cycle;
draw(p);
-dot(p,linewidth(12));
+dot(p,red+linewidth(12));
shipout(pad(64,64));
diff --git a/graphics/asymptote/GUI/res/icons/closedpolygon.svg b/graphics/asymptote/GUI/res/icons/closedpolygon.svg
index 89e2c5f230..ce6960bb84 100644
--- a/graphics/asymptote/GUI/res/icons/closedpolygon.svg
+++ b/graphics/asymptote/GUI/res/icons/closedpolygon.svg
@@ -1,21 +1,21 @@
<?xml version='1.0' encoding='UTF-8'?>
-<!-- This file was generated by dvisvgm 2.8 -->
-<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'>
+<!-- This file was generated by dvisvgm 2.11.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='64.0001pt' height='64pt' viewBox='58.4669 117.858 64.0001 64'>
<g id='page1'>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<path d='M 3.95735 -32.12L 11.9036 -51.3039L 56.1523 -42.5022L 40.6794 -22.5281L 3.95735 -32.12Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<path d='M 6.0225 32.12L 13.9687 12.9361L 58.2175 21.7378L 42.7445 41.7119L 6.0225 32.12Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='3.95735' cy='-32.12' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='6.0225' cy='32.12' fill='#ff0000' r='6.0225'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='11.9036' cy='-51.3039' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='13.9687' cy='12.9361' fill='#ff0000' r='6.0225'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='56.1523' cy='-42.5022' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='58.2175' cy='21.7378' fill='#ff0000' r='6.0225'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='40.6794' cy='-22.5281' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='42.7445' cy='41.7119' fill='#ff0000' r='6.0225'/>
</g>
</g>
</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/filledbucket.svg b/graphics/asymptote/GUI/res/icons/filledbucket.svg
index d2197375b9..b6b279840f 100644
--- a/graphics/asymptote/GUI/res/icons/filledbucket.svg
+++ b/graphics/asymptote/GUI/res/icons/filledbucket.svg
@@ -1,18 +1,18 @@
<?xml version='1.0' encoding='UTF-8'?>
-<!-- This file was generated by dvisvgm 2.8 -->
-<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'>
+<!-- This file was generated by dvisvgm 2.11.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='64pt' viewBox='56.4094 117.858 63.9996 64'>
<g id='page1'>
-<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'>
-<path d='M 9.34742 -23.011L 9.34742 -9.34742L 9.34742 -9.34742C 9.34742 -9.34742 9.34742 -9.34742 9.34742 -9.34742C 9.34742 -5.15511 19.5431 -1.75656 32.12 -1.75656C 44.6969 -1.75656 54.8926 -5.15511 54.8926 -9.34742L 54.8926 -9.34742L 54.8926 -23.011L 54.8926 -36.6745C 54.8926 -40.8668 44.6969 -44.2654 32.12 -44.2654C 19.5431 -44.2654 9.34742 -40.8668 9.34742 -36.6745L 9.34742 -23.011Z' fill='#7f7f7f'/>
+<g transform='translate(56.4094 117.858)scale(.996264)'>
+<path d='M 9.34742 42.7472L 9.34742 54.8926L 9.34742 54.8926C 9.34742 54.8926 9.34742 54.8926 9.34742 54.8926C 9.34742 59.0849 19.5431 62.4834 32.12 62.4834C 44.6969 62.4834 54.8926 59.0849 54.8926 54.8926L 54.8926 54.8926L 54.8926 42.7472L 54.8926 30.6018C 54.8926 26.4095 44.6969 23.011 32.12 23.011C 19.5431 23.011 9.34742 26.4095 9.34742 30.6018L 9.34742 42.7472Z' fill='#bfbfff'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'>
-<path d='M 54.8926 -39.7109C 54.8926 -43.9032 44.6969 -47.3017 32.12 -47.3017C 19.5431 -47.3017 9.34742 -43.9032 9.34742 -39.7109C 9.34742 -35.5185 19.5431 -32.12 32.12 -32.12C 44.6969 -32.12 54.8926 -35.5185 54.8926 -39.7109Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/>
+<g transform='translate(56.4094 117.858)scale(.996264)'>
+<path d='M 54.8926 24.5291C 54.8926 20.3368 44.6969 16.9383 32.12 16.9383C 19.5431 16.9383 9.34742 20.3368 9.34742 24.5291C 9.34742 28.7215 19.5431 32.12 32.12 32.12C 44.6969 32.12 54.8926 28.7215 54.8926 24.5291Z' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'>
-<path d='M 9.34742 -39.7109L 9.34742 -9.34742L 9.34742 -9.34742C 9.34742 -9.34742 9.34742 -9.34742 9.34742 -9.34742C 9.34742 -5.15511 19.5431 -1.75656 32.12 -1.75656C 44.6969 -1.75656 54.8926 -5.15511 54.8926 -9.34742L 54.8926 -9.34742L 54.8926 -39.7109' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/>
+<g transform='translate(56.4094 117.858)scale(.996264)'>
+<path d='M 9.34742 24.5291L 9.34742 54.8926L 9.34742 54.8926C 9.34742 54.8926 9.34742 54.8926 9.34742 54.8926C 9.34742 59.0849 19.5431 62.4834 32.12 62.4834C 44.6969 62.4834 54.8926 59.0849 54.8926 54.8926L 54.8926 54.8926L 54.8926 24.5291' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 56.4094 117.858)'>
-<path d='M 54.8926 -39.7109C 54.8926 -52.2878 44.6969 -62.4834 32.12 -62.4834C 19.5431 -62.4834 9.34742 -52.2878 9.34742 -39.7109' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/>
+<g transform='translate(56.4094 117.858)scale(.996264)'>
+<path d='M 54.8926 24.5291C 54.8926 11.9522 44.6969 1.75656 32.12 1.75656C 19.5431 1.75656 9.34742 11.9522 9.34742 24.5291' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='3.51312'/>
</g>
</g>
</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/opencurve.asy b/graphics/asymptote/GUI/res/icons/opencurve.asy
index e8fca0f2e8..8094e3ea7b 100644
--- a/graphics/asymptote/GUI/res/icons/opencurve.asy
+++ b/graphics/asymptote/GUI/res/icons/opencurve.asy
@@ -2,6 +2,6 @@ defaultpen(2.5);
path p=W..NW..ENE..0.5*SE;
draw(p);
-dot(p,linewidth(12));
+dot(p,red+linewidth(12));
shipout(pad(64,64));
diff --git a/graphics/asymptote/GUI/res/icons/opencurve.svg b/graphics/asymptote/GUI/res/icons/opencurve.svg
index 3c02ba2906..16151d7e98 100644
--- a/graphics/asymptote/GUI/res/icons/opencurve.svg
+++ b/graphics/asymptote/GUI/res/icons/opencurve.svg
@@ -1,21 +1,21 @@
<?xml version='1.0' encoding='UTF-8'?>
-<!-- This file was generated by dvisvgm 2.8 -->
-<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'>
+<!-- This file was generated by dvisvgm 2.11.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='64.0001pt' height='64pt' viewBox='58.4669 117.858 64.0001 64'>
<g id='page1'>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<path d='M 3.95735 -32.12C 4.15556 -39.2745 6.98473 -46.1047 11.9036 -51.3039C 27.4411 -67.7269 53.3021 -61.5405 56.1523 -42.5022C 57.627 -32.6519 50.5856 -23.5621 40.6794 -22.5281' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<path d='M 6.0225 32.12C 6.22072 24.9655 9.04989 18.1353 13.9687 12.9361C 29.5062 -3.48686 55.3673 2.6995 58.2175 21.7378C 59.6922 31.5881 52.6508 40.6779 42.7445 41.7119' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='3.95735' cy='-32.12' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='6.0225' cy='32.12' fill='#ff0000' r='6.0225'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='11.9036' cy='-51.3039' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='13.9687' cy='12.9361' fill='#ff0000' r='6.0225'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='56.1523' cy='-42.5022' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='58.2175' cy='21.7378' fill='#ff0000' r='6.0225'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='40.6794' cy='-22.5281' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='42.7445' cy='41.7119' fill='#ff0000' r='6.0225'/>
</g>
</g>
</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/openpolygon.asy b/graphics/asymptote/GUI/res/icons/openpolygon.asy
index 22f7b09da7..976cc7b1cf 100644
--- a/graphics/asymptote/GUI/res/icons/openpolygon.asy
+++ b/graphics/asymptote/GUI/res/icons/openpolygon.asy
@@ -2,6 +2,6 @@ defaultpen(2.5);
path p=W--NW--ENE--0.5*SE;
draw(p);
-dot(p,linewidth(12));
+dot(p,red+linewidth(12));
shipout(pad(64,64));
diff --git a/graphics/asymptote/GUI/res/icons/openpolygon.svg b/graphics/asymptote/GUI/res/icons/openpolygon.svg
index 5386aa6433..eb38eef8c1 100644
--- a/graphics/asymptote/GUI/res/icons/openpolygon.svg
+++ b/graphics/asymptote/GUI/res/icons/openpolygon.svg
@@ -1,21 +1,21 @@
<?xml version='1.0' encoding='UTF-8'?>
-<!-- This file was generated by dvisvgm 2.8 -->
-<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='63.9996pt' height='63.9997pt' viewBox='56.4094 53.8583 63.9996 63.9997'>
+<!-- This file was generated by dvisvgm 2.11.1 -->
+<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='64.0001pt' height='64pt' viewBox='58.4669 117.858 64.0001 64'>
<g id='page1'>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<path d='M 3.95735 -32.12L 11.9036 -51.3039L 56.1523 -42.5022L 40.6794 -22.5281' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<path d='M 6.0225 32.12L 13.9687 12.9361L 58.2175 21.7378L 42.7445 41.7119' fill='none' stroke='#000000' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='10.0375' stroke-width='2.50937'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='3.95735' cy='-32.12' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='6.0225' cy='32.12' fill='#ff0000' r='6.0225'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='11.9036' cy='-51.3039' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='13.9687' cy='12.9361' fill='#ff0000' r='6.0225'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='56.1523' cy='-42.5022' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='58.2175' cy='21.7378' fill='#ff0000' r='6.0225'/>
</g>
-<g transform='matrix(0.996264 0 0 0.996264 58.4669 117.858)'>
-<circle cx='40.6794' cy='-22.5281' fill='#000000' r='6.0225'/>
+<g transform='translate(58.4669 117.858)scale(.996264)'>
+<circle cx='42.7445' cy='41.7119' fill='#ff0000' r='6.0225'/>
</g>
</g>
</svg> \ No newline at end of file
diff --git a/graphics/asymptote/GUI/res/icons/redo.svg b/graphics/asymptote/GUI/res/icons/redo.svg
new file mode 100644
index 0000000000..a8647d7a3c
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/redo.svg
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 423.754 423.754" style="enable-background:new 0 0 423.754 423.754;" xml:space="preserve">
+<path d="M407.516,123.239l-27.717,11.48c18.585,44.869,18.585,94.291,0,139.159c-18.585,44.869-53.531,79.815-98.4,98.4
+ c-22.438,9.293-46.004,13.94-69.579,13.939c-23.569-0.001-47.147-4.647-69.579-13.939c-44.869-18.585-79.815-53.531-98.4-98.4
+ C13.507,200.647,34.758,118.71,90.758,68.644l60.801,60.801V7.521H29.635L69.514,47.4C5.222,105.826-18.985,200.6,16.123,285.359
+ c21.652,52.272,62.364,92.984,114.636,114.636c26.137,10.826,53.599,16.239,81.061,16.239s54.924-5.413,81.06-16.239
+ c52.272-21.652,92.984-62.364,114.637-114.636C429.167,233.087,429.167,175.511,407.516,123.239z"/>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/res/icons/undo.svg b/graphics/asymptote/GUI/res/icons/undo.svg
new file mode 100644
index 0000000000..76a7f0d32c
--- /dev/null
+++ b/graphics/asymptote/GUI/res/icons/undo.svg
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 423.754 423.754" style="enable-background:new 0 0 423.754 423.754;" xml:space="preserve">
+<path d="M354.24,47.4l39.879-39.879H272.196v121.924l60.801-60.801c56,50.066,77.251,132.004,46.918,205.235
+ c-18.585,44.869-53.531,79.815-98.4,98.4c-44.866,18.585-94.288,18.585-139.158,0c-44.869-18.585-79.815-53.531-98.4-98.4
+ c-18.585-44.869-18.585-94.29,0-139.159l-27.717-11.48c-21.651,52.272-21.651,109.848,0,162.12
+ c21.652,52.272,62.364,92.984,114.637,114.636c26.14,10.827,53.595,16.24,81.06,16.239c27.459-0.001,54.927-5.414,81.061-16.239
+ c52.271-21.652,92.983-62.364,114.636-114.636C442.739,200.6,418.532,105.826,354.24,47.4z"/>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
diff --git a/graphics/asymptote/GUI/setup.py b/graphics/asymptote/GUI/setup.py
index e49e3468d7..a1b25d809a 100644
--- a/graphics/asymptote/GUI/setup.py
+++ b/graphics/asymptote/GUI/setup.py
@@ -7,7 +7,7 @@ setup(
name="xasy",
version=xasyVersion.xasyVersion,
author="Supakorn Rassameemasmuang, Orest Shardt, and John C. Bowman",
- description="User interface for Asymptote, a vector graphics language",
+ description="User interface for Asymptote, a vector graphics language",
url="https://asymptote.sourceforge.io",
download_url="https://sourceforge.net/projects/asymptote/"
)
diff --git a/graphics/asymptote/GUI/windows/widg_addPolyOpt.ui b/graphics/asymptote/GUI/windows/widg_addPolyOpt.ui
index b8bde4236a..01fbc3e761 100644
--- a/graphics/asymptote/GUI/windows/widg_addPolyOpt.ui
+++ b/graphics/asymptote/GUI/windows/widg_addPolyOpt.ui
@@ -60,6 +60,35 @@
</widget>
</item>
<item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>19</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Sides: </string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QLineEdit" name="txtSides">
<property name="toolTip">
<string>Number of Sides</string>
diff --git a/graphics/asymptote/GUI/windows/window1.ui b/graphics/asymptote/GUI/windows/window1.ui
index ed7c964e15..d16400a884 100644
--- a/graphics/asymptote/GUI/windows/window1.ui
+++ b/graphics/asymptote/GUI/windows/window1.ui
@@ -127,7 +127,7 @@
</property>
<property name="icon">
<iconset resource="../res/icons.qrc">
- <normaloff>:/icons/android-arrow-back.svg</normaloff>:/icons/android-arrow-back.svg</iconset>
+ <normaloff>:/icons/undo.svg</normaloff>:/icons/undo.svg</iconset>
</property>
<property name="iconSize">
<size>
@@ -171,7 +171,7 @@
</property>
<property name="icon">
<iconset resource="../res/icons.qrc">
- <normaloff>:/icons/android-arrow-forward.svg</normaloff>:/icons/android-arrow-forward.svg</iconset>
+ <normaloff>:/icons/redo.svg</normaloff>:/icons/redo.svg</iconset>
</property>
<property name="iconSize">
<size>
@@ -605,7 +605,7 @@
</property>
<property name="maximumSize">
<size>
- <width>25</width>
+ <width>32</width>
<height>25</height>
</size>
</property>
@@ -652,7 +652,7 @@
</property>
<property name="maximumSize">
<size>
- <width>25</width>
+ <width>32</width>
<height>25</height>
</size>
</property>
@@ -664,6 +664,7 @@
</property>
<property name="font">
<font>
+ <family>Roboto</family>
<weight>75</weight>
<bold>true</bold>
</font>
@@ -737,6 +738,9 @@
<height>16</height>
</size>
</property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
<property name="flat">
<bool>true</bool>
</property>
@@ -782,7 +786,7 @@
</size>
</property>
<property name="checkable">
- <bool>false</bool>
+ <bool>true</bool>
</property>
<property name="flat">
<bool>true</bool>
@@ -1644,6 +1648,9 @@ background: rgb(0, 0, 0)
<height>16</height>
</size>
</property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
<property name="flat">
<bool>true</bool>
</property>
@@ -1682,6 +1689,9 @@ background: rgb(0, 0, 0)
<height>16</height>
</size>
</property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
<property name="flat">
<bool>true</bool>
</property>
@@ -1720,6 +1730,9 @@ background: rgb(0, 0, 0)
<height>16</height>
</size>
</property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
<property name="flat">
<bool>true</bool>
</property>
@@ -1758,6 +1771,9 @@ background: rgb(0, 0, 0)
<height>16</height>
</size>
</property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
<property name="flat">
<bool>true</bool>
</property>
@@ -1796,6 +1812,9 @@ background: rgb(0, 0, 0)
<height>16</height>
</size>
</property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
<property name="flat">
<bool>true</bool>
</property>
@@ -1834,6 +1853,9 @@ background: rgb(0, 0, 0)
<height>16</height>
</size>
</property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
<property name="flat">
<bool>true</bool>
</property>
@@ -1872,6 +1894,50 @@ background: rgb(0, 0, 0)
<height>16</height>
</size>
</property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="0">
+ <widget class="QPushButton" name="btnAddFreehand">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Freehand&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../res/icons.qrc">
+ <normaloff>:/icons/brush.svg</normaloff>:/icons/brush.svg</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
<property name="flat">
<bool>true</bool>
</property>
@@ -2039,16 +2105,26 @@ background: rgb(0, 0, 0)
<x>0</x>
<y>0</y>
<width>1000</width>
- <height>29</height>
+ <height>26</height>
</rect>
</property>
<widget class="QMenu" name="menuFIle">
<property name="title">
<string>&amp;File</string>
</property>
+ <widget class="QMenu" name="menuOpenRecent">
+ <property name="title">
+ <string>Open Recent</string>
+ </property>
+ <addaction name="separator"/>
+ <addaction name="actionClearRecent"/>
+ </widget>
+ <addaction name="actionNewFile"/>
<addaction name="actionOpen"/>
+ <addaction name="menuOpenRecent"/>
<addaction name="actionSave"/>
<addaction name="actionSaveAs"/>
+ <addaction name="actionExportToAsy"/>
<addaction name="actionExportAsymptote"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
@@ -2066,6 +2142,7 @@ background: rgb(0, 0, 0)
<string>Optio&amp;ns</string>
</property>
<addaction name="actionSettings"/>
+ <addaction name="actionKeymaps"/>
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
@@ -2113,7 +2190,7 @@ background: rgb(0, 0, 0)
</action>
<action name="actionSaveAs">
<property name="text">
- <string>&amp;Save As</string>
+ <string>&amp;Save as</string>
</property>
</action>
<action name="actionEnterCommand">
@@ -2159,7 +2236,7 @@ background: rgb(0, 0, 0)
</action>
<action name="actionExportAsymptote">
<property name="text">
- <string>Export</string>
+ <string>Export as...</string>
</property>
</action>
<action name="actionSave">
@@ -2172,6 +2249,26 @@ background: rgb(0, 0, 0)
<string>Open</string>
</property>
</action>
+ <action name="actionClearRecent">
+ <property name="text">
+ <string>Clear Menu</string>
+ </property>
+ </action>
+ <action name="actionNewFile">
+ <property name="text">
+ <string>New File</string>
+ </property>
+ </action>
+ <action name="actionExportToAsy">
+ <property name="text">
+ <string>Export as Asy</string>
+ </property>
+ </action>
+ <action name="actionKeymaps">
+ <property name="text">
+ <string>&amp;Keymaps</string>
+ </property>
+ </action>
</widget>
<layoutdefault spacing="6" margin="9"/>
<resources>
diff --git a/graphics/asymptote/GUI/xasy.py b/graphics/asymptote/GUI/xasy.py
index 7a8ee9b2f7..a078690b68 100755
--- a/graphics/asymptote/GUI/xasy.py
+++ b/graphics/asymptote/GUI/xasy.py
@@ -1,14 +1,15 @@
#!/usr/bin/env python3
-import sys,signal,os
-import PyQt5.QtWidgets as Qw
-import PyQt5.QtCore as Qc
+import sys, signal, os
+import PyQt5.QtWidgets as QtWidgets
+import PyQt5.QtCore as QtCore
from Window1 import MainWindow1
def main(args):
- Qw.QApplication.setAttribute(Qc.Qt.AA_UseHighDpiPixmaps,True)
- Qw.QApplication.setAttribute(Qc.Qt.AA_EnableHighDpiScaling,True)
- qtApp = Qw.QApplication(args)
+ os.environ["QT_LOGGING_RULES"]="*.debug=false;qt.qpa.*=false"
+ QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps,True)
+ QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling,True)
+ qtApp = QtWidgets.QApplication(args)
signal.signal(signal.SIGINT,signal.SIG_DFL)
mainWin1 = MainWindow1()
mainWin1.show()
diff --git a/graphics/asymptote/GUI/xasy2asy.py b/graphics/asymptote/GUI/xasy2asy.py
index 12bccb453c..1829ce436b 100644
--- a/graphics/asymptote/GUI/xasy2asy.py
+++ b/graphics/asymptote/GUI/xasy2asy.py
@@ -9,12 +9,12 @@
#
###########################################################################
-import PyQt5.QtWidgets as Qw
-import PyQt5.QtGui as Qg
-import PyQt5.QtCore as Qc
-import PyQt5.QtSvg as Qs
+import PyQt5.QtWidgets as QtWidgets
+import PyQt5.QtGui as QtGui
+import PyQt5.QtCore as QtCore
+import PyQt5.QtSvg as QtSvg
-import numpy as np
+import numpy as numpy
import sys
import os
@@ -37,8 +37,39 @@ import xasyOptions as xo
import xasySvg as xs
class AsymptoteEngine:
- xasy=chr(4)+"\n"
-
+ """
+ Purpose:
+ --------
+ Class that makes it possible for xasy to communicate with asy
+ through a background pipe. It communicates with asy through a
+ subprocess of an existing xasy process.
+
+ Attributes:
+ -----------
+ istream : input stream
+ ostream : output stream
+ keepFiles : keep communicated files
+ tmpdir : temporary directory
+ args : system call arguments to start a required subprocess
+ asyPath : directory path to asymptote
+ asyProcess : the subprocess through which xasy communicates with asy
+
+ Virtual Methods: NULL
+ ----------------
+ Static Methods:
+ --------------- NULL
+ Class Methods:
+ -------------- NULL
+
+ Object Methods:
+ ---------------
+ start()
+ wait()
+ stop()
+ cleanup()
+ """
+
+ xasy=chr(4)+'\n'
def __init__(self, path=None, keepFiles=DebugFlags.keepFiles, keepDefaultArgs=True):
if path is None:
path = xa.getArgs().asypath
@@ -59,19 +90,29 @@ class AsymptoteEngine:
os.set_inheritable(wa, True)
self.ostream = os.fdopen(wx, 'w')
self.istream = os.fdopen(ra, 'r')
-
+
self.keepFiles = keepFiles
if sys.platform[:3] == 'win':
self.tmpdir = tempfile.mkdtemp(prefix='xasyData_',dir='./')+'/'
else:
self.tmpdir = tempfile.mkdtemp(prefix='xasyData_')+os.sep
- self.args=['-xasy', '-noV', '-q', '-inpipe=' + str(rx), '-outpipe=' + str(wa), '-o', self.tmpdir]
+ if xa.getArgs().render:
+ renderDensity=xa.getArgs().render
+ else:
+ try:
+ renderDensity = xo.BasicConfigs.defaultOpt['renderDensity']
+ except:
+ renderDensity = 2
+ renderDensity=max(renderDensity,1)
+
+ self.args=['-xasy', '-noV', '-q', '-outformat=', '-inpipe=' + str(rx), '-outpipe=' + str(wa), '-render='+str(renderDensity), '-o', self.tmpdir]
self.asyPath = path
self.asyProcess = None
def start(self):
+ """ starts a subprocess (opens a pipe) """
try:
if sys.platform[:3] == 'win':
self.asyProcess = subprocess.Popen([self.asyPath] + self.args,
@@ -85,6 +126,7 @@ class AsymptoteEngine:
atexit.register(self.cleanup)
def wait(self):
+ """ wait for the pipe to finish any outstanding communication """
if self.asyProcess.returncode is not None:
return
else:
@@ -114,10 +156,12 @@ class AsymptoteEngine:
return self.asyProcess.returncode is None
def stop(self):
+ """ kill an active asyProcess and close the pipe """
if self.active:
self.asyProcess.kill()
def cleanup(self):
+ """ terminate processes and cleans up communication files """
self.stop()
if self.asyProcess is not None:
self.asyProcess.wait()
@@ -125,11 +169,46 @@ class AsymptoteEngine:
if os.path.isdir(self.tempDirName + os.sep):
shutil.rmtree(self.tempDirName, ignore_errors=True)
-class asyTransform(Qc.QObject):
- """A python implementation of an asy transform"""
+class asyTransform(QtCore.QObject):
+ """
+ Purpose:
+ --------
+ A python implementation of an asy transform. This class takes care of calibrating asymptote
+ coordinate system with the one used in PyQt to handle all existing inconsistencies.
+ To understand how this class works, having enough acquaintance with asymptote transform
+ feature is required. It is a child class of QtCore.QObject class.
+
+ Attributes:
+ -----------
+ t : The tuple
+ x, y, xx, xy, yx, yy : Coordinates corresponding to 6 entries
+ _deleted : Private local flag
+
+ Virtual Methods: NULL
+ ----------------
+ Static Methods: NULL
+ ---------------
+
+ Class Methods:
+ --------------
+ zero : Class method that returns an asyTransform object initialized with 6 zero entries
+ fromQTransform : Class method that converts QTransform object to asyTransform object
+ fromNumpyMatrix : Class method that converts transform matrix object to asyTransform object
+
+ Object Methods:
+ --------------
+ getRawCode : Returns the tuple entries
+ getCode : Returns the textual format of the asy code corresponding to the given transform
+ scale : Returns the scales version of the existing asyTransform
+ toQTransform : Converts asy transform object to QTransform object
+ identity : Return Identity asyTransform object
+ isIdentity : Check whether the asyTransform object is identity object
+ inverted : Applies the QTransform object's inverted method on the asyTransform object
+ yflip : Returns y-flipped asyTransform object
+ """
def __init__(self, initTuple, delete=False):
- """Initialize the transform with a 6 entry tuple"""
+ """ Initialize the transform with a 6 entry tuple """
super().__init__()
if isinstance(initTuple, (tuple, list)) and len(initTuple) == 6:
self.t = initTuple
@@ -151,14 +230,14 @@ class asyTransform(Qc.QObject):
return asyTransform((0, 0, 0, 0, 0, 0))
@classmethod
- def fromQTransform(cls, transform: Qg.QTransform):
+ def fromQTransform(cls, transform: QtGui.QTransform):
tx, ty = transform.dx(), transform.dy()
xx, xy, yx, yy = transform.m11(), transform.m21(), transform.m12(), transform.m22()
return asyTransform((tx, ty, xx, xy, yx, yy))
@classmethod
- def fromNumpyMatrix(cls, transform: np.ndarray):
+ def fromNumpyMatrix(cls, transform: numpy.ndarray):
assert transform.shape == (3, 3)
tx = transform[0, 2]
@@ -171,8 +250,8 @@ class asyTransform(Qc.QObject):
def getRawCode(self):
return xu.tuple2StrWOspaces(self.t)
- def getCode(self, asy2psmap=None):
- """Obtain the asy code that represents this transform"""
+ def getCode(self, asy2psmap = None):
+ """ Obtain the asy code that represents this transform """
if asy2psmap is None:
asy2psmap = asyTransform((0, 0, 1, 0, 0, 1))
if self.deleted:
@@ -184,10 +263,10 @@ class asyTransform(Qc.QObject):
return asyTransform((0, 0, s, 0, 0, s)) * self
def toQTransform(self):
- return Qg.QTransform(self.xx, self.yx, self.xy, self.yy, self.x, self.y)
+ return QtGui.QTransform(self.xx, self.yx, self.xy, self.yy, self.x, self.y)
def __str__(self):
- """Equivalent functionality to getCode(). It allows the expression str(asyTransform) to be meaningful."""
+ """ Equivalent functionality to getCode(). It allows the expression str(asyTransform) to be meaningful """
return self.getCode()
def isIdentity(self):
@@ -200,7 +279,7 @@ class asyTransform(Qc.QObject):
return list(self.t) == list(other.t)
def __mul__(self, other):
- """Define multiplication of transforms as composition."""
+ """ Define multiplication of transforms as composition """
if isinstance(other, tuple):
if len(other) == 6:
return self * asyTransform(other)
@@ -234,25 +313,88 @@ def identity():
def yflip():
return asyTransform((0, 0, 1, 0, 0, -1))
-class asyObj(Qc.QObject):
- """A base class for asy objects: an item represented by asymptote code."""
+class asyObj(QtCore.QObject):
+ """
+ Purpose:
+ --------
+ A base class to create a Python object which contains all common
+ data and behaviors required during the translation of an xasy
+ object to its Asymptote code.
+
+ Attributes:
+ -----------
+ asyCode :The corresponding Asymptote code for the asyObj instance
+
+ Virtual Methods:
+ ----------------
+ updateCode :Must to be re-implemented
+
+ Static Methods: NULL
+ --------------
+ Class Methods: NULL
+ --------------
+
+ Object Methods:
+ ---------------
+ getCode :Return the Asymptote code that corresponds to the passed object
+
+ """
+
def __init__(self):
- """Initialize the object"""
+ """ Initialize the object """
super().__init__()
self.asyCode = ''
- def updateCode(self, ps2asymap=identity()):
- """Update the object's code: should be overriden."""
+ def updateCode(self, ps2asymap = identity()):
+ """ Update the object's code: should be overridden """
raise NotImplementedError
- def getCode(self, ps2asymap=identity()):
- """Return the code describing the object"""
+ def getCode(self, ps2asymap = identity()):
+ """ Return the code describing the object """
self.updateCode(ps2asymap)
return self.asyCode
class asyPen(asyObj):
- """A python wrapper for an asymptote pen"""
+ """
+ Purpose:
+ --------
+ A Python object that corresponds to an Asymptote pen type. It
+ extends the 'asyObj' class to include a pen object. This object
+ will be used to make the corresponding Asymptote pen when
+ an xasy object gets translated to Asymptote code.
+
+ Attributes:
+ -----------
+ color : The color of Path
+ options : The options that can be passed to the path
+ width : The path width
+ _asyengine : The Asymptote engine that will be used
+ _deferAsyfy : ?
+
+ Virtual Methods: NULL
+ ----------------
+ Static Methods:
+ ---------------
+ getColorFromQColor :
+ convertToQColor :
+
+ Class Methods:
+ --------------
+ fromAsyPen :
+
+ Object Methods:
+ ---------------
+ asyEngine :
+ updateCode :
+ setWidth :
+ setColor :
+ setColorFromQColor :
+ computeColor :
+ tkColor :
+ toQPen :
+ """
+
@staticmethod
def getColorFromQColor(color):
return color.redF(), color.greenF(), color.blueF()
@@ -260,15 +402,16 @@ class asyPen(asyObj):
@staticmethod
def convertToQColor(color):
r, g, b = color
- return Qg.QColor.fromRgbF(r, g, b)
+ return QtGui.QColor.fromRgbF(r, g, b)
@classmethod
def fromAsyPen(cls, pen):
assert isinstance(pen, cls)
- return cls(asyengine=pen._asyengine, color=pen.color, width=pen.width, pen_options=pen.options)
+ return cls(asyengine = pen._asyengine, color = pen.color, width = pen.width,
+ pen_options = pen.options)
- def __init__(self, asyengine=None, color=(0, 0, 0), width=0.5, pen_options=""):
- """Initialize the pen"""
+ def __init__(self, asyengine = None, color=(0, 0, 0), width = 0.5, pen_options = ""):
+ """ Initialize the pen """
asyObj.__init__(self)
self.color = (0, 0, 0)
self.options = pen_options
@@ -288,8 +431,8 @@ class asyPen(asyObj):
def asyEngine(self, value):
self._asyengine = value
- def updateCode(self, asy2psmap=identity()):
- """Generate the pen's code"""
+ def updateCode(self, asy2psmap = identity()):
+ """ Generate the pen's code """
if self._deferAsyfy:
self.computeColor()
self.asyCode = 'rgb({:g},{:g},{:g})+{:s}'.format(self.color[0], self.color[1], self.color[2], str(self.width))
@@ -297,12 +440,12 @@ class asyPen(asyObj):
self.asyCode = self.asyCode + '+' + self.options
def setWidth(self, newWidth):
- """Set the pen's width"""
+ """ Set the pen's width """
self.width = newWidth
self.updateCode()
def setColor(self, color):
- """Set the pen's color"""
+ """ Set the pen's color """
if isinstance(color, tuple) and len(color) == 3:
self.color = color
else:
@@ -313,13 +456,12 @@ class asyPen(asyObj):
self.setColor(asyPen.getColorFromQColor(color))
def computeColor(self):
- """Find out the color of an arbitrary asymptote pen."""
+ """ Find out the color of an arbitrary Asymptote pen """
assert isinstance(self.asyEngine, AsymptoteEngine)
assert self.asyEngine.active
fout = self.asyEngine.ostream
fin = self.asyEngine.istream
-
fout.write("pen p=" + self.getCode() + ';\n')
fout.write("write(_outpipe,colorspace(p),newl);\n")
fout.write("write(_outpipe,colors(p));\n")
@@ -347,15 +489,10 @@ class asyPen(asyObj):
self.color = (r, g, b)
self._deferAsyfy = False
- def tkColor(self):
- """Return the tk version of the pen's color"""
- self.computeColor()
- return '#{}'.format("".join(["{:02x}".format(min(int(256 * a), 255)) for a in self.color]))
-
def toQPen(self):
if self._deferAsyfy:
self.computeColor()
- newPen = Qg.QPen()
+ newPen = QtGui.QPen()
newPen.setColor(asyPen.convertToQColor(self.color))
newPen.setWidthF(self.width)
@@ -363,10 +500,34 @@ class asyPen(asyObj):
class asyPath(asyObj):
- """A python wrapper for an asymptote path"""
+ """
+ Purpose:
+ --------
+ A Python object that corresponds to an Asymptote path type. It
+ extends the 'asyObj' class to include a path object. This object
+ will be used to make the corresponding Asymptote path object when
+ an xasy object gets translated to its Asymptote code.
+
+ Attributes:
+ -----------
+
+ Virtual Methods:
+ ----------------
+
+ Static Methods:
+ ---------------
+
+ Class Methods:
+ --------------
+
+ Object Methods:
+ ---------------
+
+ """
+
def __init__(self, asyengine: AsymptoteEngine=None, forceCurve=False):
- """Initialize the path to be an empty path: a path with no nodes, control points, or links."""
+ """ Initialize the path to be an empty path: a path with no nodes, control points, or links """
super().__init__()
self.nodeSet = []
self.linkSet = []
@@ -374,12 +535,14 @@ class asyPath(asyObj):
self.controlSet = []
self.computed = False
self.asyengine = asyengine
+ self.fill = False
@classmethod
def fromPath(cls, oldPath):
newObj = asyPath(None)
newObj.nodeSet = copy.copy(oldPath.nodeSet)
newObj.linkSet = copy.copy(oldPath.linkSet)
+ newObj.fill = copy.copy(oldPath.fill)
newObj.controlSet = copy.deepcopy(oldPath.controlSet)
newObj.computed = oldPath.computed
newObj.asyengine = oldPath.asyengine
@@ -406,6 +569,7 @@ class asyPath(asyObj):
def setInfo(self, path):
self.nodeSet = copy.copy(path.nodeSet)
self.linkSet = copy.copy(path.linkSet)
+ self.fill = copy.copy(path.fill)
self.controlSet = copy.deepcopy(path.controlSet)
self.computed = path.computed
@@ -417,12 +581,12 @@ class asyPath(asyObj):
def isDrawable(self):
return len(self.nodeSet) >= 2
- def toQPainterPath(self) -> Qg.QPainterPath:
+ def toQPainterPath(self) -> QtGui.QPainterPath:
return self.toQPainterPathCurve() if self.containsCurve else self.toQPainterPathLine()
def toQPainterPathLine(self):
baseX, baseY = self.nodeSet[0]
- painterPath = Qg.QPainterPath(Qc.QPointF(baseX, baseY))
+ painterPath = QtGui.QPainterPath(QtCore.QPointF(baseX, baseY))
for pointIndex in range(1, len(self.nodeSet)):
node = self.nodeSet[pointIndex]
@@ -439,43 +603,43 @@ class asyPath(asyObj):
self.computeControls()
baseX, baseY = self.nodeSet[0]
- painterPath = Qg.QPainterPath(Qc.QPointF(baseX, baseY))
+ painterPath = QtGui.QPainterPath(QtCore.QPointF(baseX, baseY))
for pointIndex in range(1, len(self.nodeSet)):
node = self.nodeSet[pointIndex]
if self.nodeSet[pointIndex] == 'cycle':
node = self.nodeSet[0]
- endPoint = Qc.QPointF(node[0], node[1])
- ctrlPoint1 = Qc.QPointF(self.controlSet[pointIndex-1][0][0], self.controlSet[pointIndex-1][0][1])
- ctrlPoint2 = Qc.QPointF(self.controlSet[pointIndex-1][1][0], self.controlSet[pointIndex-1][1][1])
+ endPoint = QtCore.QPointF(node[0], node[1])
+ ctrlPoint1 = QtCore.QPointF(self.controlSet[pointIndex-1][0][0], self.controlSet[pointIndex-1][0][1])
+ ctrlPoint2 = QtCore.QPointF(self.controlSet[pointIndex-1][1][0], self.controlSet[pointIndex-1][1][1])
painterPath.cubicTo(ctrlPoint1, ctrlPoint2, endPoint)
return painterPath
def initFromNodeList(self, nodeSet, linkSet):
- """Initialize the path from a set of nodes and link types, "--", "..", or "::" """
+ """ Initialize the path from a set of nodes and link types, '--', '..', or '::' """
if len(nodeSet) > 0:
self.nodeSet = nodeSet[:]
self.linkSet = linkSet[:]
self.computed = False
def initFromControls(self, nodeSet, controlSet):
- """Initialize the path from nodes and control points"""
+ """ Initialize the path from nodes and control points """
self.controlSet = controlSet[:]
self.nodeSet = nodeSet[:]
self.computed = True
def makeNodeStr(self, node):
- """Represent a node as a string"""
+ """ Represent a node as a string """
if node == 'cycle':
return node
else:
# if really want to, disable this rounding
- # shouldn't be to much of a problem since 10e-6 is quite small...
+ # shouldn't be to much of a problem since 10e-6 is quite small...
return '({:.6g},{:.6g})'.format(node[0], node[1])
def updateCode(self, ps2asymap=identity()):
- """Generate the code describing the path"""
+ """ Generate the code describing the path """
# currently at postscript. Convert to asy
asy2psmap = ps2asymap.inverted()
with io.StringIO() as rawAsyCode:
@@ -499,28 +663,28 @@ class asyPath(asyObj):
return '..' in self.linkSet or self.forceCurve
def getNode(self, index):
- """Return the requested node"""
+ """ Return the requested node """
return self.nodeSet[index]
def getLink(self, index):
- """Return the requested link"""
+ """ Return the requested link """
return self.linkSet[index]
def setNode(self, index, newNode):
- """Set a node to a new position"""
+ """ Set a node to a new position """
self.nodeSet[index] = newNode
def moveNode(self, index, offset):
- """Translate a node"""
+ """ Translate a node """
if self.nodeSet[index] != "cycle":
self.nodeSet[index] = (self.nodeSet[index][0] + offset[0], self.nodeSet[index][1] + offset[1])
def setLink(self, index, ltype):
- """Change the specified link"""
+ """ Change the specified link """
self.linkSet[index] = ltype
def addNode(self, point, ltype):
- """Add a node to the end of a path"""
+ """ Add a node to the end of a path """
self.nodeSet.append(point)
if len(self.nodeSet) != 1:
self.linkSet.append(ltype)
@@ -528,14 +692,14 @@ class asyPath(asyObj):
self.computeControls()
def insertNode(self, index, point, ltype=".."):
- """Insert a node, and its corresponding link, at the given index"""
+ """ Insert a node, and its corresponding link, at the given index """
self.nodeSet.insert(index, point)
self.linkSet.insert(index, ltype)
if self.computed:
self.computeControls()
def setControl(self, index, position):
- """Set a control point to a new position"""
+ """ Set a control point to a new position """
self.controlSet[index] = position
def popNode(self):
@@ -545,11 +709,11 @@ class asyPath(asyObj):
self.linkSet.pop()
def moveControl(self, index, offset):
- """Translate a control point"""
+ """ Translate a control point """
self.controlSet[index] = (self.controlSet[index][0] + offset[0], self.controlSet[index][1] + offset[1])
def computeControls(self):
- """Evaluate the code of the path to obtain its control points"""
+ """ Evaluate the code of the path to obtain its control points """
# For now, if no asymptote process is given spawns a new one.
# Only happens if asyengine is None.
if self.asyengine is not None:
@@ -595,9 +759,33 @@ class asyPath(asyObj):
asy.stop()
class asyLabel(asyObj):
- """A python wrapper for an asy label"""
+ """
+ Purpose:
+ --------
+ A Python object that corresponds to an asymptote label
+ type. It extends the 'asyObj' class to include a label
+ object. This object will be used to make the corresponding
+ Asymptote label object when an xasy object gets translated to its
+ asymptote code.
+
+ Attributes:
+ -----------
+
+ Virtual Methods:
+ ----------------
- def __init__(self, text="", location=(0, 0), pen=None, align=None, fontSize:int=None):
+ Static Methods:
+ ---------------
+
+ Class Methods:
+ --------------
+
+ Object Methods:
+ ---------------
+
+ """
+
+ def __init__(self, text = "", location = (0, 0), pen = None, align = None, fontSize:int = None):
"""Initialize the label with the given test, location, and pen"""
asyObj.__init__(self)
self.align = align
@@ -610,8 +798,8 @@ class asyLabel(asyObj):
self.text = text
self.location = location
- def updateCode(self, asy2psmap=identity()):
- """Generate the code describing the label"""
+ def updateCode(self, asy2psmap = identity()):
+ """ Generate the code describing the label """
newLoc = asy2psmap.inverted() * self.location
locStr = xu.tuple2StrWOspaces(newLoc)
self.asyCode = 'Label("{0}",{1},p={2}{4},align={3})'.format(self.text, locStr, self.pen.getCode(), self.align,
@@ -624,22 +812,45 @@ class asyLabel(asyObj):
return ''
def setText(self, text):
- """Set the label's text"""
+ """ Set the label's text """
self.text = text
self.updateCode()
def setPen(self, pen):
- """Set the label's pen"""
+ """ Set the label's pen """
self.pen = pen
self.updateCode()
def moveTo(self, newl):
- """Translate the label's location"""
+ """ Translate the label's location """
self.location = newl
class asyImage:
- """A structure containing an image and its format, bbox, and IDTag"""
+ """
+ Purpose:
+ --------
+ A Python object that is a container for an image coming from
+ Asymptote that is populated with the format, bounding box, and
+ IDTag, Asymptote key.
+
+ Attributes:
+ -----------
+
+ Virtual Methods:
+ ----------------
+
+ Static Methods:
+ ---------------
+
+ Class Methods:
+ --------------
+
+ Object Methods:
+ ---------------
+
+ """
+
def __init__(self, image, format, bbox, transfKey=None, keyIndex=0):
self.image = image
self.format = format
@@ -648,15 +859,38 @@ class asyImage:
self.key = transfKey
self.keyIndex = keyIndex
-class xasyItem(Qc.QObject):
- """A base class for items in the xasy GUI"""
+class xasyItem(QtCore.QObject):
+ """
+ Purpose:
+ --------
+ A base class for any xasy object that can be drawn in PyQt. This class takes
+ care of all common behaviors available on any xasy item as well as all common
+ actions that can be done or applied to every xasy item.
+
+ Attributes:
+ -----------
+
+ Virtual Methods:
+ ----------------
+
+ Static Methods:
+ ---------------
+
+ Class Methods:
+ --------------
+
+ Object Methods:
+ ---------------
+
+ """
+
mapString = 'xmap'
setKeyFormatStr = string.Template('$map("{:s}",{:s});').substitute(map=mapString)
setKeyAloneFormatStr = string.Template('$map("{:s}");').substitute(map=mapString)
resizeComment="// Resize to initial xasy transform"
asySize=""
def __init__(self, canvas=None, asyengine=None):
- """Initialize the item to an empty item"""
+ """ Initialize the item to an empty item """
super().__init__()
self.transfKeymap = {} # the new keymap.
# should be a dictionary to a list...
@@ -672,18 +906,17 @@ class xasyItem(Qc.QObject):
self.setKeyed = True
self.unsetKeys = set()
self.userKeys = set()
- self.lineOffset = 0
self.imageHandleQueue = queue.Queue()
- def updateCode(self, ps2asymap=identity()):
- """Update the item's code: to be overriden"""
+ def updateCode(self, ps2asymap = identity()):
+ """ Update the item's code: to be overridden """
with io.StringIO() as rawCode:
transfCode = self.getTransformCode()
objCode = self.getObjectCode()
rawCode.write(transfCode)
rawCode.write(objCode)
- self.asyCode = rawCode.getvalue()
+ self.asyCode = rawCode.getvalue()
return len(transfCode.splitlines()), len(objCode.splitlines())
@@ -695,34 +928,32 @@ class xasyItem(Qc.QObject):
def asyengine(self, value):
self._asyengine = value
- def getCode(self, ps2asymap=identity()):
- """Return the code describing the item"""
+ def getCode(self, ps2asymap = identity()):
+ """ Return the code describing the item """
self.updateCode(ps2asymap)
return self.asyCode
- def getTransformCode(self, asy2psmap=identity()):
+ def getTransformCode(self, asy2psmap = identity()):
raise NotImplementedError
- def getObjectCode(self, asy2psmap=identity()):
+ def getObjectCode(self, asy2psmap = identity()):
raise NotImplementedError
def generateDrawObjects(self):
raise NotImplementedError
- def handleImageReception(self, file, fileformat, bbox, count, key=None, localCount=0, containsClip=False):
- """Receive an image from an asy deconstruction. It replaces the default n asyProcess."""
+ def handleImageReception(self, file, fileformat, bbox, count, key = None, localCount = 0, containsClip = False):
+ """ Receive an image from an asy deconstruction. It replaces the default n asyProcess """
# image = Image.open(file).transpose(Image.FLIP_TOP_BOTTOM)
- if fileformat == 'png':
- image = Qg.QImage(file)
- elif fileformat == 'svg':
+ if fileformat == 'svg':
if containsClip:
image = xs.SvgObject(self.asyengine.tempDirName+file)
else:
- image = Qs.QSvgRenderer(file)
+ image = QtSvg.QSvgRenderer(file)
assert image.isValid()
else:
- raise Exception('Format not supported!')
- self.imageList.append(asyImage(image, fileformat, bbox, transfKey=key, keyIndex=localCount))
+ raise Exception('Format {} not supported!'.format(fileformat))
+ self.imageList.append(asyImage(image, fileformat, bbox, transfKey = key, keyIndex = localCount))
if self.onCanvas is not None:
# self.imageList[-1].iqt = ImageTk.PhotoImage(image)
currImage = self.imageList[-1]
@@ -733,7 +964,7 @@ class xasyItem(Qc.QObject):
currImage.performCanvasTransform = False
# handle this case if transform is not in the map yet.
- # if deleted - set transform to 0, 0, 0, 0, 0
+ # if deleted - set transform to (0,0,0,0,0,0)
transfExists = key in self.transfKeymap.keys()
if transfExists:
transfExists = localCount <= len(self.transfKeymap[key]) - 1
@@ -745,7 +976,7 @@ class xasyItem(Qc.QObject):
if (not transfExists) or validKey:
currImage.IDTag = str(file)
newDrawObj = DrawObject(currImage.iqt, self.onCanvas['canvas'], transform=identity(),
- btmRightanchor=Qc.QPointF(bbox[0], bbox[2]), drawOrder=-1, key=key,
+ btmRightanchor=QtCore.QPointF(bbox[0], bbox[2]), drawOrder=-1, key=key,
parentObj=self, keyIndex=localCount)
newDrawObj.setBoundingBoxPs(bbox)
newDrawObj.setParent(self)
@@ -757,7 +988,8 @@ class xasyItem(Qc.QObject):
else:
self.drawObjectsMap[key].append(newDrawObj)
return containsClip
- def asyfy(self, force=False):
+
+ def asyfy(self, force = False):
if self.asyengine is None:
return 1
if self.asyfied and not force:
@@ -772,7 +1004,7 @@ class xasyItem(Qc.QObject):
self.userKeys.clear()
self.imageHandleQueue = queue.Queue()
- worker = threading.Thread(target=self.asyfyThread, args=[])
+ worker = threading.Thread(target = self.asyfyThread, args = [])
worker.start()
item = self.imageHandleQueue.get()
cwd=os.getcwd();
@@ -797,22 +1029,25 @@ class xasyItem(Qc.QObject):
worker.join()
def asyfyThread(self):
- """Convert the item to a list of images by deconstructing this item's code"""
+ """
+ Convert the item to a list of images by deconstructing this item's code
+ """
assert self.asyengine.active
fout = self.asyengine.ostream
fin = self.asyengine.istream
- self.lineOffset = len(self.getTransformCode().splitlines())
+ self.maxKey=0
fout.write("reset\n")
fout.flush();
for line in self.getCode().splitlines():
- if DebugFlags.printDeconstTranscript:
- print('fout:', line)
+ if DebugFlags.printAsyTranscript:
+ print(line)
fout.write(line+"\n")
fout.write(self.asySize)
- fout.write("deconstruct();\n")
+
+ fout.write('deconstruct();\n')
fout.write('write(_outpipe,yscale(-1)*currentpicture.calculateTransform(),endl);\n')
fout.write(self.asyengine.xasy)
fout.flush()
@@ -826,37 +1061,44 @@ class xasyItem(Qc.QObject):
for i in range(len(imageInfos)):
box, key, localCount, useClip = imageInfos[i]
l, b, r, t = [float(a) for a in box.split()]
- name = "_{:d}.{:s}".format(i, fileformat)
+ name = '_{:d}.{:s}'.format(1+i, fileformat)
self.imageHandleQueue.put((name, fileformat, (l, -t, r, -b), i, key, localCount, useClip))
# key first, box second.
- # if key is "Done"
+ # if key is 'Done'
raw_text = fin.readline()
- text = ""
+ text = ''
if DebugFlags.printDeconstTranscript:
+ print(self.asyengine.tmpdir)
print(raw_text.strip())
- # template=AsyTempDir+"%d_%d.%s"
- fileformat = 'svg'
+ fileformat = 'svg' # Output format
- while raw_text != "Done\n" and raw_text != "Error\n":
+ while raw_text != 'Done\n' and raw_text != 'Error\n':
# print(raw_text)
text = fin.readline() # the actual bounding box.
# print('TESTING:', text)
keydata = raw_text.strip().replace('KEY=', '', 1) # key
clipflag = keydata[-1] == '1'
+ deleted = keydata[-1] == '2'
userkey = keydata[-2] == '1'
keydata = keydata[:-3]
if not userkey:
- self.unsetKeys.add(keydata) # the line and column to replace.
+ self.unsetKeys.add(keydata) # the line and column to replace.
else:
+ if keydata.isdigit():
+ self.maxKey=max(self.maxKey,int(keydata))
self.userKeys.add(keydata)
-
+
# print(line, col)
+ if deleted:
+ raw_text = fin.readline()
+ continue
+
if keydata not in keyCounts.keys():
keyCounts[keydata] = 0
@@ -873,23 +1115,45 @@ class xasyItem(Qc.QObject):
n += 1
- if raw_text != "Error\n":
- if text == "Error\n":
- self.imageHandleQueue.put(("ERROR", fin.readline()))
+ if raw_text != 'Error\n':
+ if text == 'Error\n':
+ self.imageHandleQueue.put(('ERROR', fin.readline()))
else:
render()
self.asy2psmap = asyTransform(xu.listize(fin.readline().rstrip(),float))
else:
- self.asy2psmap = identity()
+ self.asy2psmap = yflip()
self.imageHandleQueue.put((None,))
self.asyfied = True
class xasyDrawnItem(xasyItem):
- """A base class for GUI items was drawn by the user. It combines a path, a pen, and a transform."""
+ """
+ Purpose:
+ --------
+ A base class dedicated to any xasy item that is drawn on GUI. Every object of this class
+ will correspond to a particular drawn xasy item on GUI, which contains all its particular
+ data.
+
+ Attributes:
+ -----------
+
+ Virtual Methods:
+ ----------------
+
+ Static Methods:
+ ---------------
- def __init__(self, path, engine, pen=None, transform=identity(), key=None):
- """Initialize the item with a path, pen, and transform"""
+ Class Methods:
+ --------------
+
+ Object Methods:
+ ---------------
+
+ """
+
+ def __init__(self, path, engine, pen = None, transform = identity(), key = None):
+ """ Initialize the item with a path, pen, and transform """
super().__init__(canvas=None, asyengine=engine)
if pen is None:
pen = asyPen()
@@ -921,7 +1185,9 @@ class xasyDrawnItem(xasyItem):
raise NotImplementedError
def appendPoint(self, point, link=None):
- """Append a point to the path. If the path is cyclic, add this point before the 'cycle' node."""
+ """ Append a point to the path. If the path is cyclic, add this point before the 'cycle'
+ node
+ """
if self.path.nodeSet[-1] == 'cycle':
self.path.nodeSet[-1] = point
self.path.nodeSet.append('cycle')
@@ -933,12 +1199,14 @@ class xasyDrawnItem(xasyItem):
self.path.linkSet.append(link)
def clearTransform(self):
- """Reset the item's transform"""
+ """ Reset the item's transform """
self.transform = [identity()]
self.asyfied = False
def removeLastPoint(self):
- """Remove the last point in the path. If the path is cyclic, remove the node before the 'cycle' node."""
+ """ Remove the last point in the path. If the path is cyclic, remove the node before the 'cycle'
+ node
+ """
if self.path.nodeSet[-1] == 'cycle':
del self.path.nodeSet[-2]
else:
@@ -948,7 +1216,9 @@ class xasyDrawnItem(xasyItem):
self.asyfied = False
def setLastPoint(self, point):
- """Modify the last point in the path. If the path is cyclic, modify the node before the 'cycle' node."""
+ """ Modify the last point in the path. If the path is cyclic, modify the node before the 'cycle'
+ node
+ """
if self.path.nodeSet[-1] == 'cycle':
self.path.nodeSet[-2] = point
else:
@@ -958,13 +1228,38 @@ class xasyDrawnItem(xasyItem):
class xasyShape(xasyDrawnItem):
- """An outlined shape drawn on the GUI"""
+ """ An outlined shape drawn on the GUI """
+ """
+ Purpose:
+ --------
+
+ Attributes:
+ -----------
+
+ Virtual Methods:
+ ----------------
+
+ Static Methods:
+ ---------------
+
+ Class Methods:
+ --------------
+
+ Object Methods:
+ ---------------
+
+ """
+
+
def __init__(self, path, asyengine, pen=None, transform=identity()):
"""Initialize the shape with a path, pen, and transform"""
super().__init__(path=path, engine=asyengine, pen=pen, transform=transform)
def getObjectCode(self, asy2psmap=identity()):
- return 'draw(KEY="{0}",{1},{2});'.format(self.transfKey, self.path.getCode(asy2psmap), self.pen.getCode())+'\n\n'
+ if self.path.fill:
+ return 'fill(KEY="{0}",{1},{2});'.format(self.transfKey, self.path.getCode(asy2psmap), self.pen.getCode())+'\n\n'
+ else:
+ return 'draw(KEY="{0}",{1},{2});'.format(self.transfKey, self.path.getCode(asy2psmap), self.pen.getCode())+'\n\n'
def getTransformCode(self, asy2psmap=identity()):
transf = self.transfKeymap[self.transfKey][0]
@@ -982,63 +1277,121 @@ class xasyShape(xasyDrawnItem):
key=self.transfKey)
newObj.originalObj = self
newObj.setParent(self)
+ newObj.fill=self.path.fill
return [newObj]
def __str__(self):
- """Create a string describing this shape"""
+ """ Create a string describing this shape """
return "xasyShape code:{:s}".format("\n\t".join(self.getCode().splitlines()))
+ def swapFill(self):
+ self.path.fill = not self.path.fill
+
+ def copy(self):
+ return type(self)(self.path,self._asyengine,self.pen)
+
class xasyFilledShape(xasyShape):
- """A filled shape drawn on the GUI"""
+ """ A filled shape drawn on the GUI """
- def __init__(self, path, asyengine, pen=None, transform=identity()):
- """Initialize this shape with a path, pen, and transform"""
+ """
+ Purpose:
+ --------
+
+ Attributes:
+ -----------
+
+ Virtual Methods:
+ ----------------
+
+ Static Methods:
+ ---------------
+
+ Class Methods:
+ --------------
+
+ Object Methods:
+ ---------------
+
+ """
+
+ def __init__(self, path, asyengine, pen = None, transform = identity()):
+ """ Initialize this shape with a path, pen, and transform """
if path.nodeSet[-1] != 'cycle':
raise Exception("Filled paths must be cyclic")
super().__init__(path, asyengine, pen, transform)
+ self.path.fill=True
def getObjectCode(self, asy2psmap=identity()):
- return 'fill(KEY="{0}",{1},{2});'.format(self.transfKey, self.path.getCode(asy2psmap), self.pen.getCode())+'\n\n'
+ if self.path.fill:
+ return 'fill(KEY="{0}",{1},{2});'.format(self.transfKey, self.path.getCode(asy2psmap), self.pen.getCode())+'\n\n'
+ else:
+ return 'draw(KEY="{0}",{1},{2});'.format(self.transfKey, self.path.getCode(asy2psmap), self.pen.getCode())+'\n\n'
- def generateDrawObjects(self, forceUpdate=False):
+ def generateDrawObjects(self, forceUpdate = False):
if self.path.containsCurve:
self.path.computeControls()
- newObj = DrawObject(self.path.toQPainterPath(), None, drawOrder=0, transform=self.transfKeymap[self.transfKey][0],
- pen=self.pen, key=self.transfKey, fill=True)
+ newObj = DrawObject(self.path.toQPainterPath(), None, drawOrder = 0, transform = self.transfKeymap[self.transfKey][0],
+ pen = self.pen, key = self.transfKey, fill = True)
newObj.originalObj = self
newObj.setParent(self)
+ newObj.fill=self.path.fill
return [newObj]
def __str__(self):
- """Return a string describing this shape"""
+ """ Return a string describing this shape """
return "xasyFilledShape code:{:s}".format("\n\t".join(self.getCode().splitlines()))
+ def swapFill(self):
+ self.path.fill = not self.path.fill
+
class xasyText(xasyItem):
- """Text created by the GUI"""
+ """ Text created by the GUI """
+
+ """
+ Purpose:
+ --------
+
+ Attributes:
+ -----------
+
+ Virtual Methods:
+ ----------------
+
+ Static Methods:
+ ---------------
- def __init__(self, text, location, asyengine, pen=None, transform=yflip(), key=None, align=None, fontsize:int=None):
- """Initialize this item with text, a location, pen, and transform"""
- super().__init__(asyengine=asyengine)
+ Class Methods:
+ --------------
+
+ Object Methods:
+ ---------------
+
+ """
+
+ def __init__(self, text, location, asyengine, pen = None, transform = yflip(), key = None, align = None, fontsize:int = None):
+ """ Initialize this item with text, a location, pen, and transform """
+ super().__init__(asyengine = asyengine)
if pen is None:
- pen = asyPen(asyengine=asyengine)
+ pen = asyPen(asyengine = asyengine)
if pen.asyEngine is None:
pen.asyEngine = asyengine
- self.label = asyLabel(text, location, pen, align, fontSize=fontsize)
+ self.label = asyLabel(text, location, pen, align, fontSize = fontsize)
# self.transform = [transform]
self.transfKey = key
self.transfKeymap = {self.transfKey: [transform]}
self.asyfied = False
self.onCanvas = None
-
- def setKey(self, newKey=None):
+ self.pen = pen
+
+ def setKey(self, newKey = None):
transform = self.transfKeymap[self.transfKey][0]
self.transfKey = newKey
self.transfKeymap = {self.transfKey: [transform]}
- def getTransformCode(self, asy2psmap=yflip()):
+ def getTransformCode(self, asy2psmap = yflip()):
transf = self.transfKeymap[self.transfKey][0]
if transf == yflip():
# return xasyItem.setKeyAloneFormatStr.format(self.transfKey)
@@ -1046,10 +1399,10 @@ class xasyText(xasyItem):
else:
return xasyItem.setKeyFormatStr.format(self.transfKey, transf.getCode(asy2psmap))+"\n"
- def getObjectCode(self, asy2psmap=yflip()):
+ def getObjectCode(self, asy2psmap = yflip()):
return 'label(KEY="{0}",{1});'.format(self.transfKey, self.label.getCode(asy2psmap))+'\n'
- def generateDrawObjects(self, forceUpdate=False):
+ def generateDrawObjects(self, forceUpdate = False):
self.asyfy(forceUpdate)
return self.drawObjects
@@ -1060,12 +1413,36 @@ class xasyText(xasyItem):
def __str__(self):
return "xasyText code:{:s}".format("\n\t".join(self.getCode().splitlines()))
+ def copy(self):
+ return type(self)(self.label.text,self.label.location,self._asyengine)
+
class xasyScript(xasyItem):
- """A set of images create from asymptote code. It is always deconstructed."""
+ """ A set of images create from asymptote code. It is always deconstructed """
+
+ """
+ Purpose:
+ --------
+
+ Attributes:
+ -----------
+
+ Virtual Methods:
+ ----------------
+
+ Static Methods:
+ ---------------
+
+ Class Methods:
+ --------------
+
+ Object Methods:
+ ---------------
+
+ """
def __init__(self, canvas, engine, script="", transforms=None, transfKeyMap=None):
- """Initialize this script item"""
+ """ Initialize this script item """
super().__init__(canvas, asyengine=engine)
if transfKeyMap is not None:
self.transfKeymap = transfKeyMap
@@ -1080,7 +1457,7 @@ class xasyScript(xasyItem):
self.updatedPrefix = True
def clearTransform(self):
- """Reset the transforms for each of the deconstructed images"""
+ """ Reset the transforms for each of the deconstructed images """
# self.transform = [identity()] * len(self.imageList)
keyCount = {}
@@ -1093,14 +1470,6 @@ class xasyScript(xasyItem):
for key in keyCount:
self.transfKeymap[key] = [identity()] * keyCount[key]
- def getMaxKeyCounter(self):
- maxCounter = -1
- for key in self.transfKeymap:
- testNum = re.match(r'^x(\d+)$', key)
- if testNum is not None:
- maxCounter = max(maxCounter, int(testNum.group(1)))
- return maxCounter + 1
-
def getTransformCode(self, asy2psmap=identity()):
with io.StringIO() as rawAsyCode:
if self.transfKeymap:
@@ -1109,21 +1478,22 @@ class xasyScript(xasyItem):
writeval = list(reversed(val))
# need to map all transforms in a list if there is any non-identity
- # unfortunately, have to check all transformations in the list.
- while not all(checktransf == identity() for checktransf in writeval) and writeval:
+ # unfortunately, have to check all transformations in the list.
+ while not all((checktransf == identity() and not checktransf.deleted) for checktransf in writeval) and writeval:
transf = writeval.pop()
if transf.deleted:
- rawAsyCode.write(xasyItem.setKeyFormatStr.format(key, transf.getCode(asy2psmap)) + '\n//')
- if transf == identity() and not transf.deleted:
- rawAsyCode.write(xasyItem.setKeyAloneFormatStr.format(key))
- else:
rawAsyCode.write(xasyItem.setKeyFormatStr.format(key, transf.getCode(asy2psmap)))
+ else:
+ if transf == identity():
+ rawAsyCode.write(xasyItem.setKeyAloneFormatStr.format(key))
+ else:
+ rawAsyCode.write(xasyItem.setKeyFormatStr.format(key, transf.getCode(asy2psmap)))
rawAsyCode.write('\n')
result = rawAsyCode.getvalue()
return result
def findNonIdKeys(self):
- return {key for key in self.transfKeymap if not all(transf == identity() for transf in self.transfKeymap[key]) }
+ return {key for key in self.transfKeymap if not all(not transf.deleted and transf == identity() for transf in self.transfKeymap[key]) }
def getObjectCode(self, asy2psmap=identity()):
numeric=r'([-+]?(?:(?:\d*\.\d+)|(?:\d+\.?)))'
@@ -1144,7 +1514,7 @@ class xasyScript(xasyItem):
return self.updatedCode
def setScript(self, script):
- """Sets the content of the script item."""
+ """ Sets the content of the script item """
self.script = script
self.updateCode()
@@ -1155,7 +1525,7 @@ class xasyScript(xasyItem):
def getReplacedKeysCode(self, key2replace: set=None) -> str:
keylist = {}
prefix = ''
-
+
key2replaceSet = self.unsetKeys if key2replace is None else \
self.unsetKeys & key2replace
@@ -1180,9 +1550,8 @@ class xasyScript(xasyItem):
raw_code_lines = self.script.splitlines()
with io.StringIO() as raw_str:
- for i_0 in range(len(raw_code_lines)):
- i = i_0 + self.lineOffset
- curr_str = raw_code_lines[i_0]
+ for i in range(len(raw_code_lines)):
+ curr_str = raw_code_lines[i]
if i + 1 in keylist.keys():
# this case, we have a key.
with io.StringIO() as raw_line:
@@ -1205,11 +1574,13 @@ class xasyScript(xasyItem):
baseCounter += 1
return newKey
- def asyfy(self, keyOnly=False):
- """Generate the list of images described by this object and adjust the length of the transform list."""
+ def asyfy(self, keyOnly = False):
+ """ Generate the list of images described by this object and adjust the length of the
+ transform list
+ """
super().asyfy()
- # Id --> Transf --> asy-fied --> Transf
+ # Id --> Transf --> asyfied --> Transf
# Transf should keep the original, raw transformation
# but for all new drawn objects - assign Id as transform.
@@ -1246,7 +1617,7 @@ class xasyScript(xasyItem):
else:
self.key2imagemap[im.key].append(im)
-
+
for key in keyCount:
if key not in self.transfKeymap.keys():
@@ -1258,7 +1629,7 @@ class xasyScript(xasyItem):
# while len(self.transfKeymap[key]) > keyCount[key]:
# self.transfKeymap[key].pop()
- # change of basis
+ # change of basis
for keylist in self.transfKeymap.values():
for i in range(len(keylist)):
if keylist[i] != identity():
@@ -1272,17 +1643,41 @@ class xasyScript(xasyItem):
return self.drawObjects
def __str__(self):
- """Return a string describing this script"""
+ """ Return a string describing this script """
retVal = "xasyScript\n\tTransforms:\n"
for xform in self.transform:
retVal += "\t" + str(xform) + "\n"
- retVal += "\tCode Ommitted"
+ retVal += "\tCode Omitted"
return retVal
-class DrawObject(Qc.QObject):
- def __init__(self, drawObject, mainCanvas=None, transform=identity(), btmRightanchor=Qc.QPointF(0, 0),
- drawOrder=(-1, -1), pen=None, key=None, parentObj=None, fill=False, keyIndex=0):
+class DrawObject(QtCore.QObject):
+ """
+ Purpose:
+ --------
+ The main Python class to draw an object with the help of PyQt graphical library.
+ Every instance of the class is
+
+
+ Attributes:
+ -----------
+
+ Virtual Methods:
+ ----------------
+
+ Static Methods:
+ ---------------
+
+ Class Methods:
+ --------------
+
+ Object Methods:
+ ---------------
+
+ """
+
+ def __init__(self, drawObject, mainCanvas = None, transform = identity(), btmRightanchor = QtCore.QPointF(0, 0),
+ drawOrder = (-1, -1), pen = None, key = None, parentObj = None, fill = False, keyIndex = 0):
super().__init__()
self.drawObject = drawObject
self.mainCanvas = mainCanvas
@@ -1302,8 +1697,8 @@ class DrawObject(Qc.QObject):
self.fill = fill
def getInteriorScrTransform(self, transform):
- """Generates the transform with Interior transform applied beforehand."""
- if isinstance(transform, Qg.QTransform):
+ """ Generates the transform with Interior transform applied beforehand """
+ if isinstance(transform, QtGui.QTransform):
transform = asyTransform.fromQTransform(transform)
return self.transform * transform * self.baseTransform.inverted()
@@ -1317,25 +1712,36 @@ class DrawObject(Qc.QObject):
def setBoundingBoxPs(self, bbox):
l, b, r, t = bbox
- self.explicitBoundingBox = Qc.QRectF(Qc.QPointF(l, b), Qc.QPointF(r, t))
- # self.explicitBoundingBox = Qc.QRectF(0, 0, 100, 100)
+ self.explicitBoundingBox = QtCore.QRectF(QtCore.QPointF(l, b), QtCore.QPointF(r, t))
+ # self.explicitBoundingBox = QtCore.QRectF(0, 0, 100, 100)
@property
def boundingBox(self):
if self.explicitBoundingBox is not None:
- testBbox = self.explicitBoundingBox
+ tempItem = self.baseTransform.toQTransform().mapRect(self.explicitBoundingBox)
+ testBbox = self.getScreenTransform().toQTransform().mapRect(tempItem)
+ elif isinstance(self.drawObject, QtGui.QPainterPath):
+ tempItem = self.baseTransform.toQTransform().map(self.drawObject)
+ testBbox = self.getScreenTransform().toQTransform().map(tempItem).boundingRect()
else:
- if isinstance(self.drawObject, Qg.QImage):
- testBbox = self.drawObject.rect()
- testBbox.moveTo(self.btmRightAnchor.toPoint())
- elif isinstance(self.drawObject, Qg.QPainterPath):
- testBbox = self.baseTransform.toQTransform().mapRect(self.drawObject.boundingRect())
- else:
- raise TypeError('drawObject is not a valid type!')
- pointList = [self.getScreenTransform().toQTransform().map(point) for point in [
- testBbox.topLeft(), testBbox.topRight(), testBbox.bottomLeft(), testBbox.bottomRight()
- ]]
- return Qg.QPolygonF(pointList).boundingRect()
+ raise TypeError('drawObject is not a valid type!')
+
+ if self.pen is not None:
+ lineWidth = self.pen.width
+ const = lineWidth/2
+ bl = QtCore.QPointF(-const, const)
+ br = QtCore.QPointF(const, const)
+ tl = QtCore.QPointF(-const, -const)
+ tr = QtCore.QPointF(const, -const)
+
+ pointList = [testBbox.topLeft(), testBbox.topRight(), testBbox.bottomLeft(), testBbox.bottomRight()
+ ]
+
+ else:
+ pointList = [testBbox.topLeft(), testBbox.topRight(), testBbox.bottomLeft(), testBbox.bottomRight()
+ ]
+
+ return QtGui.QPolygonF(pointList).boundingRect()
@property
def localBoundingBox(self):
@@ -1345,22 +1751,25 @@ class DrawObject(Qc.QObject):
def getScreenTransform(self):
scrTransf = self.baseTransform.toQTransform().inverted()[0] * self.pTransform.toQTransform()
+ # print(asyTransform.fromQTransform(scrTransf).t)
return asyTransform.fromQTransform(scrTransf)
- def draw(self, additionalTransformation=None, applyReverse=False, canvas: Qg.QPainter=None, dpi=300):
+ def draw(self, additionalTransformation = None, applyReverse = False, canvas: QtGui.QPainter = None, dpi = 300):
if canvas is None:
canvas = self.mainCanvas
if additionalTransformation is None:
- additionalTransformation = Qg.QTransform()
-
+ additionalTransformation = QtGui.QTransform()
+
assert canvas.isActive()
canvas.save()
if self.pen:
- oldPen = Qg.QPen(canvas.pen())
- canvas.setPen(self.pen.toQPen())
+ oldPen = QtGui.QPen(canvas.pen())
+ localPen = self.pen.toQPen()
+ # localPen.setCosmetic(True)
+ canvas.setPen(localPen) #this fixes the object but not the box
else:
- oldPen = Qg.QPen()
+ oldPen = QtGui.QPen()
if not applyReverse:
canvas.setTransform(additionalTransformation, True)
@@ -1371,11 +1780,9 @@ class DrawObject(Qc.QObject):
canvas.setTransform(self.baseTransform.toQTransform().inverted()[0], True)
- if isinstance(self.drawObject, Qg.QImage):
- canvas.drawImage(self.explicitBoundingBox, self.drawObject)
- elif isinstance(self.drawObject, xs.SvgObject):
+ if isinstance(self.drawObject, xs.SvgObject):
threshold = 1.44
-
+
if self.cachedDPI is None or self.cachedSvgImg is None \
or dpi > self.maxDPI*threshold:
self.cachedDPI = dpi
@@ -1383,15 +1790,15 @@ class DrawObject(Qc.QObject):
self.cachedSvgImg = self.drawObject.render(dpi)
canvas.drawImage(self.explicitBoundingBox, self.cachedSvgImg)
- elif isinstance(self.drawObject, Qs.QSvgRenderer):
+ elif isinstance(self.drawObject, QtSvg.QSvgRenderer):
self.drawObject.render(canvas, self.explicitBoundingBox)
- elif isinstance(self.drawObject, Qg.QPainterPath):
+ elif isinstance(self.drawObject, QtGui.QPainterPath):
path = self.baseTransform.toQTransform().map(self.drawObject)
if self.fill:
if self.pen:
brush = self.pen.toQPen().brush()
else:
- brush = Qg.QBrush()
+ brush = QtGui.QBrush()
canvas.fillPath(path, brush)
else:
canvas.drawPath(path)
@@ -1400,14 +1807,14 @@ class DrawObject(Qc.QObject):
canvas.setPen(oldPen)
canvas.restore()
- def collide(self, coords, canvasCoordinates=True):
- # modify these values to grow/shrink the fuzz.
+ def collide(self, coords, canvasCoordinates = True):
+ # modify these values to grow/shrink the fuzz.
fuzzTolerance = 1
marginGrowth = 1
leftMargin = marginGrowth if self.boundingBox.width() < fuzzTolerance else 0
topMargin = marginGrowth if self.boundingBox.height() < fuzzTolerance else 0
- newMargin = Qc.QMarginsF(leftMargin, topMargin, leftMargin, topMargin)
+ newMargin = QtCore.QMarginsF(leftMargin, topMargin, leftMargin, topMargin)
return self.boundingBox.marginsAdded(newMargin).contains(coords)
def getID(self):
diff --git a/graphics/asymptote/GUI/xasyArgs.py b/graphics/asymptote/GUI/xasyArgs.py
index 045f4bc669..b9e1518f1e 100644
--- a/graphics/asymptote/GUI/xasyArgs.py
+++ b/graphics/asymptote/GUI/xasyArgs.py
@@ -1,23 +1,32 @@
#!/usr/bin/env python3
import argparse
import xasyVersion
-import PyQt5.QtCore as Qc
+import PyQt5.QtCore as QtCore
# Add arguments here.
def parseArgs(args):
parser = argparse.ArgumentParser(args)
- parser.add_argument('-p', '--asypath', help='Custom Asymptote asy executable')
- parser.add_argument('-v', '--version', help='Version number', action='version',
+ parser.add_argument('-p', '-asypath', '--asypath',
+ help='Custom path to asy executable')
+ parser.add_argument('-v', '-version', '--version',
+ help='Version number', action='version',
version='xasy v{0}'.format(xasyVersion.xasyVersion))
- parser.add_argument('-l', '--language', help='language')
- parser.add_argument('-x', '--mag', help='Magnification. Defaults to 1', default=1, type=float)
-
+ parser.add_argument('-l', '-language', '--language',
+ help='language')
+ parser.add_argument('-x', '-mag', '--mag',
+ help='Initial magnification. Defaults to 1',
+ default=1, type=float)
+ parser.add_argument('-render', '--render',
+ help='Number of pixels per bp in 3D rendered bitmaps',
+ default=None, type=float)
parser.add_argument(
- 'filename', help='Filename to load. If empty, initializes empty xasy canvas.', nargs='?', default=None)
+ 'filename',
+ help='Filename to load (if omitted, initialize blank canvas)',
+ nargs='?', default=None)
return parser.parse_args()
def getArgs():
- return parseArgs(Qc.QCoreApplication.arguments())
+ return parseArgs(QtCore.QCoreApplication.arguments())
diff --git a/graphics/asymptote/GUI/xasyBezierInterface.py b/graphics/asymptote/GUI/xasyBezierInterface.py
index 0a5c689bff..b10c8d4350 100644
--- a/graphics/asymptote/GUI/xasyBezierInterface.py
+++ b/graphics/asymptote/GUI/xasyBezierInterface.py
@@ -1,16 +1,14 @@
#!/usr/bin/env python3
-import xasy2asy as x2a
-import xasyUtils as xu
-
-import PyQt5.QtCore as Qc
-import PyQt5.QtGui as Qg
-import PyQt5.QtWidgets as Qw
+import PyQt5.QtWidgets as QtWidgets
+import PyQt5.QtCore as QtCore
+import PyQt5.QtGui as QtGui
+import xasy2asy as xasy2asy
+import xasyUtils as xasyUtils
import Widg_editBezier as Web
import InplaceAddObj
-
import math
class CurrentlySelctedType:
@@ -19,16 +17,16 @@ class CurrentlySelctedType:
ctrlPoint = 1
class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
- editAccepted = Qc.pyqtSignal()
- editRejected = Qc.pyqtSignal()
+ editAccepted = QtCore.pyqtSignal()
+ editRejected = QtCore.pyqtSignal()
- def __init__(self, parent: Qc.QObject, obj: x2a.xasyDrawnItem, info: dict={}):
+ def __init__(self, parent: QtCore.QObject, obj: xasy2asy.xasyDrawnItem, info: dict={}):
super().__init__(parent)
self.info = info
- self.asyPathBackup = x2a.asyPath.fromPath(obj.path)
+ self.asyPathBackup = xasy2asy.asyPath.fromPath(obj.path)
self.asyPath = obj.path
self.curveMode = self.asyPath.containsCurve
- assert isinstance(self.asyPath, x2a.asyPath)
+ assert isinstance(self.asyPath, xasy2asy.asyPath)
self.transf = obj.transfKeymap[obj.transfKey][0]
self._active = True
@@ -47,10 +45,20 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
self.inTransformMode = False
self.opt = None
+ self.obj = obj
self.prosectiveNodes = []
self.prospectiveCtrlPts = []
+ #The magnification isn't being set. Here I'm manually setting it to be the square root of the determinant.
+ self.info['magnification'] = math.sqrt(self.transf.xx * self.transf.yy - self.transf.xy * self.transf.yx)
+ self.parent = parent
+ if isinstance(obj,xasy2asy.xasyFilledShape) or isinstance(obj,xasy2asy.xasyShape):
+ parent.ui.btnFill.setChecked(obj.path.fill)
+
+ def swapObjFill(self):
+ self.obj.swapFill() #This may end up being more in the future
+
def setSelectionBoundaries(self):
self.nodeSelRects = self.handleNodeSelectionBounds()
@@ -66,11 +74,11 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
continue
selEpsilon = 6/self.info['magnification']
- newRect = Qc.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon)
+ newRect = QtCore.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon)
x, y = self.transf * node
x = int(round(x))
y = int(round(y))
- newRect.moveCenter(Qc.QPoint(x, y))
+ newRect.moveCenter(QtCore.QPoint(x, y))
nodeSelectionBoundaries.append(newRect)
@@ -84,8 +92,8 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
selEpsilon = 6/self.info['magnification']
- newRect = Qc.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon)
- newRectb = Qc.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon)
+ newRect = QtCore.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon)
+ newRectb = QtCore.QRect(0, 0, 2 * selEpsilon, 2 * selEpsilon)
x, y = self.transf * nodea
x2, y2 = self.transf * nodeb
@@ -96,18 +104,19 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
x2 = int(round(x2))
y2 = int(round(y2))
- newRect.moveCenter(Qc.QPoint(x, y))
- newRectb.moveCenter(Qc.QPoint(x2, y2))
+ newRect.moveCenter(QtCore.QPoint(x, y))
+ newRectb.moveCenter(QtCore.QPoint(x2, y2))
ctrlPointSelBoundaries.append((newRect, newRectb))
return ctrlPointSelBoundaries
- def postDrawPreview(self, canvas: Qg.QPainter):
+
+ def postDrawPreview(self, canvas: QtGui.QPainter):
assert canvas.isActive()
- dashedPen = Qg.QPen(Qc.Qt.DashLine)
- dashedPen.setWidthF(1/self.info['magnification'])
+ dashedPen = QtGui.QPen(QtCore.Qt.DashLine)
+ dashedPen.setCosmetic(True)
# draw the base points
canvas.save()
canvas.setWorldTransform(self.transf.toQTransform(), True)
@@ -123,27 +132,27 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
canvas.drawPath(self.asyPath.toQPainterPath())
- nodePen = Qg.QPen(Qg.QColor('blue'))
- nodePen.setWidthF(1/self.info['magnification'])
+ nodePen = QtGui.QPen(QtGui.QColor('blue'))
+ nodePen.setCosmetic(True)
- ctlPtsPen = Qg.QPen(Qg.QColor(ctrlPtsColor))
- ctlPtsPen.setWidthF(1/self.info['magnification'])
+ ctlPtsPen = QtGui.QPen(QtGui.QColor(ctrlPtsColor))
+ ctlPtsPen.setCosmetic(True)
for index in range(len(self.asyPath.nodeSet)):
point = self.asyPath.nodeSet[index]
-
+
if point != 'cycle':
- basePoint = Qc.QPointF(point[0], point[1])
+ basePoint = QtCore.QPointF(point[0], point[1])
canvas.setPen(nodePen)
canvas.drawEllipse(basePoint, epsilonSize, epsilonSize)
else:
point = self.asyPath.nodeSet[0]
- basePoint = Qc.QPointF(point[0], point[1])
- if self.curveMode:
+ basePoint = QtCore.QPointF(point[0], point[1])
+ if self.curveMode:
if index != 0:
canvas.setPen(ctlPtsPen)
postCtrolSet = self.asyPath.controlSet[index - 1][1]
- postCtrlPoint = Qc.QPointF(postCtrolSet[0], postCtrolSet[1])
+ postCtrlPoint = QtCore.QPointF(postCtrolSet[0], postCtrolSet[1])
canvas.drawEllipse(postCtrlPoint, epsilonSize, epsilonSize)
canvas.setPen(dashedPen)
@@ -152,7 +161,7 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
if index != len(self.asyPath.nodeSet) - 1:
canvas.setPen(ctlPtsPen)
preCtrlSet = self.asyPath.controlSet[index][0]
- preCtrlPoint = Qc.QPointF(preCtrlSet[0], preCtrlSet[1])
+ preCtrlPoint = QtCore.QPointF(preCtrlSet[0], preCtrlSet[1])
canvas.drawEllipse(preCtrlPoint, epsilonSize, epsilonSize)
canvas.setPen(dashedPen)
@@ -189,7 +198,7 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
self.asyPath.setInfo(self.asyPathBackup)
self.setSelectionBoundaries()
- def mouseDown(self, pos, info, mouseEvent: Qg.QMouseEvent=None):
+ def mouseDown(self, pos, info, mouseEvent: QtGui.QMouseEvent=None):
self.lastSelPoint = pos
if self.inTransformMode:
return
@@ -204,13 +213,13 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
self.currentSelIndex = self.prospectiveCtrlPts[0]
self.inTransformMode = True
self.parentNodeIndex = self.findLinkingNode(*self.currentSelIndex)
-
+
if self.inTransformMode:
parentNode = self.asyPath.nodeSet[self.parentNodeIndex]
# find the offset of each control point to the node
if not self.curveMode:
- return
+ return
preCtrl, postCtrl = self.getPreAndPostCtrlPts(self.parentNodeIndex)
@@ -219,20 +228,20 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
self.parentNodeIndex = 0
if preCtrl is not None:
- self.preCtrlOffset = xu.funcOnList(
+ self.preCtrlOffset = xasyUtils.funcOnList(
preCtrl, parentNode, lambda a, b: a - b)
else:
self.preCtrlOffset = None
if postCtrl is not None:
- self.postCtrlOffset = xu.funcOnList(
+ self.postCtrlOffset = xasyUtils.funcOnList(
postCtrl, parentNode, lambda a, b: a - b)
else:
self.postCtrlOffset = None
- def mouseMove(self, pos, event: Qg.QMouseEvent):
+ def mouseMove(self, pos, event: QtGui.QMouseEvent):
if self.currentSelMode is None and not self.inTransformMode:
- # in this case, search for prosective nodes.
+ # in this case, search for prosective nodes.
prospectiveNodes = []
prospectiveCtrlpts = []
@@ -262,32 +271,31 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
if self.inTransformMode:
index, subindex = self.currentSelIndex
- deltaPos = pos - self.lastSelPoint
- newNode = (pos.x(), pos.y())
+ newNode = (self.transf.inverted().toQTransform().map(pos.x(), pos.y()))
if self.currentSelMode == CurrentlySelctedType.node:
# static throughout the moving
if self.asyPath.nodeSet[index] == 'cycle':
return
self.asyPath.setNode(index, newNode)
- # if also move node:
+ # if also move node:
if self.curveMode:
checkPre, checkPost = self.getPreAndPostCtrlPts(index)
- if 1 == 1: # TODO: Replace this with an option to also move control pts.
+ if 1 == 1: # TODO: Replace this with an option to also move control pts.
if checkPre is not None:
- self.asyPath.controlSet[index - 1][1] = xu.funcOnList(
+ self.asyPath.controlSet[index - 1][1] = xasyUtils.funcOnList(
newNode, self.preCtrlOffset, lambda a, b: a + b
)
if checkPost is not None:
- self.asyPath.controlSet[index][0] = xu.funcOnList(
+ self.asyPath.controlSet[index][0] = xasyUtils.funcOnList(
newNode, self.postCtrlOffset, lambda a, b: a + b
)
if self.info['autoRecompute']:
self.quickRecalculateCtrls()
-
+
elif self.currentSelMode == CurrentlySelctedType.ctrlPoint and self.curveMode:
self.asyPath.controlSet[index][subindex] = newNode
@@ -302,46 +310,46 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
if self.parentNodeIndex == 0 and self.asyPath.nodeSet[-1] == 'cycle':
isCycle = True
- rawNewNode = xu.funcOnList(newNode, parentNode, lambda a, b: a - b)
+ rawNewNode = xasyUtils.funcOnList(newNode, parentNode, lambda a, b: a - b)
rawAngle = math.atan2(rawNewNode[1], rawNewNode[0])
- newNorm = xu.twonorm(rawNewNode)
+ newNorm = xasyUtils.twonorm(rawNewNode)
if self.info['editBezierlockMode'] >= Web.LockMode.angleLock:
- otherIndex = 1 - subindex # 1 if 0, 0 otherwise.
+ otherIndex = 1 - subindex # 1 if 0, 0 otherwise.
if otherIndex == 0:
if index < (len(self.asyPath.controlSet) - 1) or isCycle:
newIndex = 0 if isCycle else index + 1
- oldOtherCtrlPnt = xu.funcOnList(
+ oldOtherCtrlPnt = xasyUtils.funcOnList(
self.asyPath.controlSet[newIndex][0], parentNode, lambda a, b: a - b)
-
+
if self.info['editBezierlockMode'] >= Web.LockMode.angleAndScaleLock:
rawNorm = newNorm
else:
- rawNorm = xu.twonorm(oldOtherCtrlPnt)
+ rawNorm = xasyUtils.twonorm(oldOtherCtrlPnt)
- newPnt = (rawNorm * math.cos(rawAngle + math.pi),
+ newPnt = (rawNorm * math.cos(rawAngle + math.pi),
rawNorm * math.sin(rawAngle + math.pi))
-
- self.asyPath.controlSet[newIndex][0] = xu.funcOnList(
+
+ self.asyPath.controlSet[newIndex][0] = xasyUtils.funcOnList(
newPnt, parentNode, lambda a, b: a + b)
else:
if index > 0 or isCycle:
newIndex = -1 if isCycle else index - 1
- oldOtherCtrlPnt = xu.funcOnList(
+ oldOtherCtrlPnt = xasyUtils.funcOnList(
self.asyPath.controlSet[newIndex][1], parentNode, lambda a, b: a - b)
if self.info['editBezierlockMode'] >= Web.LockMode.angleAndScaleLock:
rawNorm = newNorm
else:
- rawNorm = xu.twonorm(oldOtherCtrlPnt)
+ rawNorm = xasyUtils.twonorm(oldOtherCtrlPnt)
newPnt = (rawNorm * math.cos(rawAngle + math.pi),
rawNorm * math.sin(rawAngle + math.pi))
- self.asyPath.controlSet[newIndex][1] = xu.funcOnList(
+ self.asyPath.controlSet[newIndex][1] = xasyUtils.funcOnList(
newPnt, parentNode, lambda a, b: a + b)
-
+
def recalculateCtrls(self):
self.quickRecalculateCtrls()
self.setSelectionBoundaries()
@@ -356,7 +364,7 @@ class InteractiveBezierEditor(InplaceAddObj.InplaceObjProcess):
self.currentSelMode = None
self.setSelectionBoundaries()
-
+
def forceFinalize(self):
self.objectUpdated.emit()
diff --git a/graphics/asymptote/GUI/xasyFile.py b/graphics/asymptote/GUI/xasyFile.py
index eee6d69a85..54c70cf5c2 100644
--- a/graphics/asymptote/GUI/xasyFile.py
+++ b/graphics/asymptote/GUI/xasyFile.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
###########################################################################
#
-# xasyFile implements the loading, parsing, and saving of an xasy file.
+# xasyFile implements the loading, parsing, and saving of an asy file.
#
#
# Author: Orest Shardt
@@ -10,7 +10,7 @@
############################################################################
from string import *
-import xasy2asy as x2a
+import xasy2asy as xasy2asy
import io
import re
@@ -28,7 +28,7 @@ class xasyFileError(Exception):
def extractTransform(line):
"""Returns key and the new transform."""
# see https://regex101.com/r/6DqkRJ/4 for info
- mapString = x2a.xasyItem.mapString
+ mapString = xasy2asy.xasyItem.mapString
testMatch = re.match(
r'^{0:s}\s*\(\s*\"([^\"]+)\"\s*,\s*\(([-\d, .]+)\)\s*\)'.format(mapString), line.strip())
if testMatch is None:
@@ -37,7 +37,7 @@ def extractTransform(line):
return None
else:
key = mapOnlyMatch.group(1)
- return key, x2a.identity()
+ return key, xasy2asy.identity()
else:
key = testMatch.group(1)
rawStr = testMatch.group(2)
@@ -46,7 +46,7 @@ def extractTransform(line):
if len(rawStrArray) != 6:
return None
transf = [float(val.strip()) for val in rawStrArray]
- return key, x2a.asyTransform(transf)
+ return key, xasy2asy.asyTransform(transf)
def extractTransformsFromFile(fileStr):
@@ -62,22 +62,58 @@ def extractTransformsFromFile(fileStr):
if key not in transfDict.keys():
transfDict[key] = []
transfDict[key].append(transf)
-
- # see https://regex101.com/r/RgeBVc/2 for regex
-
- testNum = re.match(r'^x(\d+)($|:.*$)', key)
- if testNum is not None:
- maxItemCount = max(maxItemCount, int(testNum.group(1)))
final_str = rawCode.getvalue()
- return final_str, transfDict, maxItemCount
+ return final_str, transfDict
+
+def xasy2asyCode(xasyItems, asy2psmap):
+ asyCode = ''
+ for item in xasyItems:
+ asyCode += item.getTransformCode(asy2psmap)
+ for item in xasyItems:
+ asyCode += item.getObjectCode(asy2psmap)
+ asyCode += 'size('+str(asy2psmap*xasy2asy.yflip())+'); '+ xasy2asy.xasyItem.resizeComment+'\n'
+ return asyCode
def saveFile(file, xasyItems, asy2psmap):
"""Write a list of xasyItems to a file"""
- for item in xasyItems:
- file.write(item.getTransformCode(asy2psmap))
+ file.write(xasy2asyCode(xasyItems, asy2psmap))
+def xasyToDict(file, xasyItems, asy2psmap):
+ fileItems = []
+ asyItems = []
for item in xasyItems:
- file.write(item.getObjectCode(asy2psmap))
+ if isinstance(item, xasy2asy.xasyScript):
+ # reusing xasyFile code for objects
+ # imported from asy script.
+ asyItems.append({'item':item, 'type': 'xasyScript'})
+
+ elif isinstance(item, xasy2asy.xasyText):
+ # At the moment xasyText cannot be edited
+ # so we treat it the same as xasyScript
+ penData = {'color': item.pen.color, 'width': item.pen.width, 'options': item.pen.options}
+ fileItems.append({'type': 'xasyText',
+ 'align': item.label.align,
+ 'location': item.label.location,
+ 'fontSize': item.label.fontSize,
+ 'text': item.label.text,
+ 'transform': item.transfKeymap[item.transfKey][0].t,
+ 'transfKey': item.transfKey,
+ 'pen': penData
+ })
+
+ elif isinstance(item, xasy2asy.xasyShape):
+ penData = {'color': item.pen.color, 'width': item.pen.width, 'options': item.pen.options}
+ fileItems.append({'type': 'xasyShape',
+ 'nodes': item.path.nodeSet,
+ 'links': item.path.linkSet,
+ 'transform': item.transfKeymap[item.transfKey][0].t,
+ 'transfKey': item.transfKey,
+ 'pen': penData
+ })
+
+ else:
+ # DEBUGGING PURPOSES ONLY
+ print(type(item))
- file.write('size('+str(asy2psmap*x2a.yflip())+'); '+ x2a.xasyItem.resizeComment+'\n')
+ return {'objects': fileItems, 'asy2psmap': asy2psmap.t}, asyItems
diff --git a/graphics/asymptote/GUI/xasyOptions.py b/graphics/asymptote/GUI/xasyOptions.py
index 1923990fae..458dd9cb3c 100644
--- a/graphics/asymptote/GUI/xasyOptions.py
+++ b/graphics/asymptote/GUI/xasyOptions.py
@@ -10,25 +10,13 @@
#
###########################################################################
-import json
import sys
import io
import os
import platform
import shutil
-
import configs
-
-try:
- import cson
-except ModuleNotFoundError:
- cson = None
-
-try:
- pass
-# import yaml
-except ModuleNotFoundError:
- yaml = None
+import cson
class xasyOptions:
def defaultOptions(self):
@@ -49,12 +37,12 @@ class xasyOptions:
for key in self.options[settingsName]:
self.options[key] = self.options[settingsName][key]
-
-
+
+
def settingsFileLocation(self):
folder = os.path.expanduser("~/.asy/")
- searchOrder = ['.cson', '.yaml', '.json', '']
+ searchOrder = ['.cson', '']
searchIndex = 0
found = False
@@ -64,7 +52,7 @@ class xasyOptions:
if os.path.isfile(currentFile):
found = True
searchIndex += 1
-
+
if found:
return os.path.normcase(currentFile)
else:
@@ -79,7 +67,6 @@ class xasyOptions:
self.options = self.defaultOptions()
self.load()
- self.overrideSettings()
def __getitem__(self, item):
return self.options[item]
@@ -100,16 +87,7 @@ class xasyOptions:
f = io.open(fileName, 'r')
try:
ext = os.path.splitext(fileName)[1]
- if ext == '.cson':
- if cson is None:
- raise ModuleNotFoundError
- newOptions = cson.loads(f.read())
- elif ext in {'.yml', '.yaml'}:
- if yaml is None:
- raise ModuleNotFoundError
- newOptions = yaml.load(f)
- else:
- newOptions = json.loads(f.read())
+ newOptions = cson.loads(f.read())
except (IOError, ModuleNotFoundError):
self.setDefaults()
else:
@@ -121,6 +99,7 @@ class xasyOptions:
self.options = newOptions
finally:
f.close()
+ self.overrideSettings()
def setDefaults(self):
self.options = self.defaultOptions()
@@ -130,7 +109,7 @@ class xasyOptions:
folder = os.path.expanduser("~/.asy/")
defaultPath = os.path.join(folder, self.configName + '.cson')
shutil.copy2(self._defaultOptLocation, defaultPath)
-
+
# TODO: Figure out how to merge this back.
"""
@@ -150,6 +129,72 @@ def setAsyPathFromWindowsRegistry():
registry.CloseKey(key)
"""
+class xasyOpenRecent:
+ def __init__(self, configName, defaultConfigLocation):
+ self.configName = configName
+ self.fileName = self.settingsFileLocation()
+ if not os.path.isfile(self.fileName):
+ f = io.open(self.fileName, 'w')
+ f.write('')
+ f.close()
+
+ def settingsFileLocation(self):
+ folder = os.path.expanduser("~/.asy/")
+
+ currentFile = os.path.join(folder, self.configName + '.txt')
+ return os.path.normcase(currentFile)
+
+ def insert(self, path):
+ if not os.path.exists(self.fileName):
+ # make folder
+ thedir = os.path.dirname(self.fileName)
+ if not os.path.exists(thedir):
+ os.makedirs(thedir)
+ if not os.path.isdir(thedir):
+ raise Exception("Configuration folder path does not point to a folder")
+
+ f = io.open(self.fileName, 'r')
+ lines = f.readlines()
+ f.close()
+
+ f = io.open(self.fileName, 'w')
+ f.write(path.strip() + '\n')
+ for line in lines:
+ if line.strip() != path.strip():
+ f.write(line.strip() + '\n')
+ f.close()
+
+ @property
+ def pathList(self):
+ self.findingPaths=True
+ return self.findPath()
+
+ def findPath(self):
+ f = io.open(self.fileName, 'r')
+ paths = [path.strip() for path in f.readlines()]
+ f.close()
+
+ trueFiles = list(map(lambda path: os.path.isfile(os.path.expanduser(path)), paths))
+ if all(trueFiles):
+ return paths
+ else:
+ if self.findingPaths == False:
+ raise RecursionError
+ self.findingPaths = False
+ self.removeNotFound(list(trueFiles), paths)
+ return self.findPath()
+
+ def removeNotFound(self, trueFiles, paths):
+ f = io.open(self.fileName, 'w')
+ for index, path in enumerate(paths):
+ if trueFiles[index] == True:
+ f.write(path + '\n')
+ f.close()
+
+ def clear(self):
+ f = io.open(self.fileName, 'w')
+ f.write('')
+ f.close()
class BasicConfigs:
_configPath = list(configs.__path__)[0]
@@ -157,3 +202,4 @@ class BasicConfigs:
'xasyconfig', os.path.join(_configPath, 'xasyconfig.cson'))
keymaps = xasyOptions('xasykeymap', os.path.join(
_configPath, 'xasykeymap.cson'))
+ openRecent = xasyOpenRecent('xasyrecents', os.path.join( _configPath, "xasyrecent.txt"))
diff --git a/graphics/asymptote/GUI/xasyStrings.py b/graphics/asymptote/GUI/xasyStrings.py
index 53f83a64f1..4f2ca0d2ed 100644
--- a/graphics/asymptote/GUI/xasyStrings.py
+++ b/graphics/asymptote/GUI/xasyStrings.py
@@ -8,12 +8,12 @@ class xasyString:
def __init__(self, lang=None):
s = self
if lang is None:
- _ = lambda x: x
+ _ = lambda x: x
else:
lng = gettext.translation('base', localedir='GUI/locale', languages=[lang])
lng.install()
_ = lng.gettext
-
+
s.rotate = _('Rotate')
s.scale = _('Scale')
s.translate = _('Translate')
diff --git a/graphics/asymptote/GUI/xasySvg.py b/graphics/asymptote/GUI/xasySvg.py
index a5325f9bdd..7261dc5b69 100644
--- a/graphics/asymptote/GUI/xasySvg.py
+++ b/graphics/asymptote/GUI/xasySvg.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
-import PyQt5.QtGui as Qg
-import PyQt5.QtWidgets as Qw
+import PyQt5.QtGui as QtGui
+import PyQt5.QtWidgets as QtWidgets
import io
import subprocess
import sys
@@ -10,13 +10,13 @@ class SvgObject():
def __init__(self, file: str):
self.file=file
- def render(self, dpi:int) -> Qg.QImage:
+ def render(self, dpi:int) -> QtGui.QImage:
try:
rawDataProc = subprocess.Popen(['rsvg-convert', '--dpi-x', str(dpi),
'--dpi-y', str(dpi), self.file],
stdout=subprocess.PIPE)
except:
- Qw.QMessageBox.about(None,'rsvg-convert missing','Please install rsvg-convert version >= 2.40 in your path.')
+ QtWidgets.QMessageBox.about(None,'rsvg-convert missing','Please install rsvg-convert version >= 2.40 in your path.')
sys.exit(-1)
- return Qg.QImage.fromData(rawDataProc.stdout.read(), 'PNG')
+ return QtGui.QImage.fromData(rawDataProc.stdout.read(), 'PNG')
diff --git a/graphics/asymptote/GUI/xasyTransform.py b/graphics/asymptote/GUI/xasyTransform.py
index 928e9011f0..cb70bf1edb 100644
--- a/graphics/asymptote/GUI/xasyTransform.py
+++ b/graphics/asymptote/GUI/xasyTransform.py
@@ -1,24 +1,24 @@
#!/usr/bin/env python3
-import xasy2asy as x2a
-import PyQt5.QtGui as Qg
-import PyQt5.QtCore as Qc
-import numpy as np
+import xasy2asy as xasy2asy
+import PyQt5.QtGui as QtGui
+import PyQt5.QtCore as QtCore
+import numpy as numpy
import math
class xasyTransform:
@classmethod
def makeRotTransform(cls, theta, origin):
- if isinstance(origin, Qc.QPointF) or isinstance(origin, Qc.QPoint):
+ if isinstance(origin, QtCore.QPointF) or isinstance(origin, QtCore.QPoint):
origin = (origin.x(), origin.y())
rotMat = (math.cos(theta), -math.sin(theta), math.sin(theta), math.cos(theta))
- shift = x2a.asyTransform((0, 0, 1 - rotMat[0], -rotMat[1], -rotMat[2], 1 - rotMat[3])) * origin
- return x2a.asyTransform((shift[0], shift[1], rotMat[0], rotMat[1], rotMat[2], rotMat[3]))
+ shift = xasy2asy.asyTransform((0, 0, 1 - rotMat[0], -rotMat[1], -rotMat[2], 1 - rotMat[3])) * origin
+ return xasy2asy.asyTransform((shift[0], shift[1], rotMat[0], rotMat[1], rotMat[2], rotMat[3]))
@classmethod
def makeScaleTransform(cls, sx, sy, origin):
- if isinstance(origin, Qc.QPointF) or isinstance(origin, Qc.QPoint):
+ if isinstance(origin, QtCore.QPointF) or isinstance(origin, QtCore.QPoint):
origin = (origin.x(), origin.y())
- shiftMat = x2a.asyTransform((0, 0, 1 - sx, 0, 0, 1 - sy)) * origin
- return x2a.asyTransform((shiftMat[0], shiftMat[1], sx, 0, 0, sy))
+ shiftMat = xasy2asy.asyTransform((0, 0, 1 - sx, 0, 0, 1 - sy)) * origin
+ return xasy2asy.asyTransform((shiftMat[0], shiftMat[1], sx, 0, 0, sy))
diff --git a/graphics/asymptote/GUI/xasyUtils.py b/graphics/asymptote/GUI/xasyUtils.py
index 255e8b6add..04e327bb44 100644
--- a/graphics/asymptote/GUI/xasyUtils.py
+++ b/graphics/asymptote/GUI/xasyUtils.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
import re
-import typing as ty
+import typing as typing
import math
import itertools
@@ -15,12 +15,12 @@ def tryParse(val, typ=float):
except ValueError:
return None
-def funcOnList(list1: ty.Union[ty.List, ty.Tuple], list2: ty.Union[ty.List, ty.Tuple], func: ty.Callable) -> tuple:
- """Returns [f(x[i], y[i]) : i in 1, ..., n - 1] in order with f as func
+def funcOnList(list1: typing.Union[typing.List, typing.Tuple], list2: typing.Union[typing.List, typing.Tuple], func: typing.Callable) -> tuple:
+ """Returns [f(x[i], y[i]) : i in 1, ..., n - 1] in order with f as func
and x and y as list1 and 2. """
assert len(list1) == len(list2)
- return tuple([func(list1[i], list2[i]) for i in range(len(list1))])
+ return tuple([func(list1[i], list2[i]) for i in range(len(list1))])
def listize(str, typ, delim='()') -> list:
@@ -39,7 +39,7 @@ def listize(str, typ, delim='()') -> list:
final_list.append(typ(elem.strip()))
return final_list
-def twonorm(vec: ty.Iterable[ty.Union[float, int]]) -> float:
+def twonorm(vec: typing.Iterable[typing.Union[float, int]]) -> float:
rawSquared = sum(map(lambda x: x*x, vec))
return math.sqrt(rawSquared)
diff --git a/graphics/asymptote/LspCpp/LICENSE b/graphics/asymptote/LspCpp/LICENSE
new file mode 100644
index 0000000000..e2016d4801
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 kuafuwang
+
+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
+AUTHORS OR COPYRIGHT HOLDERS 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.
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Cancellation.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Cancellation.h
new file mode 100644
index 0000000000..b89f32f166
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Cancellation.h
@@ -0,0 +1,23 @@
+#pragma once
+#include <functional>
+#include "lsRequestId.h"
+#include <LibLsp/JsonRpc/NotificationInMessage.h>
+using CancelMonitor = std::function<int()>;
+namespace Cancellation
+{
+
+ struct Params {
+ /**
+ * The request id to cancel.
+ */
+ lsRequestId id;
+
+ MAKE_SWAP_METHOD(Cancellation::Params, id);
+ };
+
+};
+MAKE_REFLECT_STRUCT(Cancellation::Params, id);
+
+DEFINE_NOTIFICATION_TYPE(Notify_Cancellation, Cancellation::Params,"$/cancelRequest");
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Condition.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Condition.h
new file mode 100644
index 0000000000..a5f550041d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Condition.h
@@ -0,0 +1,48 @@
+#pragma once
+#include <condition_variable>
+template <class T>
+class Condition
+{
+public:
+
+ std::mutex m_mutex;
+ std::condition_variable m_condition;
+ ~Condition() {
+ m_condition.notify_all();
+ }
+ void notify(std::unique_ptr<T> data) noexcept
+ {
+ {
+ std::lock_guard<std::mutex> eventLock(m_mutex);
+ any.swap(data);
+ }
+ // wake up one waiter
+ m_condition.notify_one();
+ };
+
+
+ std::unique_ptr<T> wait(unsigned timeout=0)
+ {
+ std::unique_lock<std::mutex> ul(m_mutex);
+ if (!timeout) {
+ m_condition.wait(ul,[&]() {
+ if (!any)
+ return false;
+ return true;
+ });
+ }
+ else{
+ if(!any){
+ std::cv_status status = m_condition.wait_for(ul, std::chrono::milliseconds(timeout));
+ if (status == std::cv_status::timeout)
+ {
+ return {};
+ }
+ }
+ }
+ return std::unique_ptr<T>(any.release());
+
+ }
+private:
+ std::unique_ptr<T> any;
+};
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Context.cpp b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Context.cpp
new file mode 100644
index 0000000000..5fb1ad4d45
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Context.cpp
@@ -0,0 +1,35 @@
+//===--- Context.cpp ---------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Context.h"
+#include <cassert>
+
+namespace lsp {
+
+
+Context Context::empty() { return Context(/*dataPtr=*/nullptr); }
+
+Context::Context(std::shared_ptr<const Data> DataPtr)
+ : dataPtr(std::move(DataPtr)) {}
+
+Context Context::clone() const { return Context(dataPtr); }
+
+static Context &currentContext() {
+ static thread_local auto c = Context::empty();
+ return c;
+}
+
+const Context &Context::current() { return currentContext(); }
+
+Context Context::swapCurrent(Context Replacement) {
+ std::swap(Replacement, currentContext());
+ return Replacement;
+}
+
+
+} // lsp clang
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Context.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Context.h
new file mode 100644
index 0000000000..20edf71b1c
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Context.h
@@ -0,0 +1,216 @@
+//===--- Context.h - Mechanism for passing implicit data --------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Context for storing and retrieving implicit data. Useful for passing implicit
+// parameters on a per-request basis.
+//
+//===----------------------------------------------------------------------===//
+
+#pragma once
+
+#include <memory>
+#include <type_traits>
+
+namespace lsp {
+
+
+/// Values in a Context are indexed by typed keys.
+/// Key<T> serves two purposes:
+/// - it provides a lookup key for the context (each Key is unique),
+/// - it makes lookup type-safe: a Key<T> can only map to a T (or nothing).
+///
+/// Example:
+/// Key<int> RequestID;
+/// Key<int> Version;
+///
+/// Context Ctx = Context::empty().derive(RequestID, 10).derive(Version, 3);
+/// assert(*Ctx.get(RequestID) == 10);
+/// assert(*Ctx.get(Version) == 3);
+///
+/// Keys are typically used across multiple functions, so most of the time you
+/// would want to make them static class members or global variables.
+template <class Type> class Key {
+public:
+ static_assert(!std::is_reference<Type>::value,
+ "Reference arguments to Key<> are not allowed");
+
+ constexpr Key() = default;
+
+ Key(Key const &) = delete;
+ Key &operator=(Key const &) = delete;
+ Key(Key &&) = delete;
+ Key &operator=(Key &&) = delete;
+};
+
+/// A context is an immutable container for per-request data that must be
+/// propagated through layers that don't care about it. An example is a request
+/// ID that we may want to use when logging.
+///
+/// Conceptually, a context is a heterogeneous map<Key<T>, T>. Each key has
+/// an associated value type, which allows the map to be typesafe.
+///
+/// There is an "ambient" context for each thread, Context::current().
+/// Most functions should read from this, and use WithContextValue or
+/// WithContext to extend or replace the context within a block scope.
+/// Only code dealing with threads and extension points should need to use
+/// other Context objects.
+///
+/// You can't add data to an existing context, instead you create a new
+/// immutable context derived from it with extra data added. When you retrieve
+/// data, the context will walk up the parent chain until the key is found.
+class Context {
+public:
+ /// Returns an empty root context that contains no data.
+ static Context empty();
+ /// Returns the context for the current thread, creating it if needed.
+ static const Context &current();
+ // Sets the current() context to Replacement, and returns the old context.
+ // Prefer to use WithContext or WithContextValue to do this safely.
+ static Context swapCurrent(Context Replacement);
+
+private:
+ struct Data;
+ Context(std::shared_ptr<const Data> DataPtr);
+
+public:
+ /// Same as Context::empty(), please use Context::empty() instead.
+ Context() = default;
+
+ /// Copy operations for this class are deleted, use an explicit clone() method
+ /// when you need a copy of the context instead.
+ Context(Context const &) = delete;
+ Context &operator=(const Context &) = delete;
+
+ Context(Context &&) = default;
+ Context &operator=(Context &&) = default;
+
+ /// Get data stored for a typed \p Key. If values are not found
+ /// \returns Pointer to the data associated with \p Key. If no data is
+ /// specified for \p Key, return null.
+ template <class Type> const Type *get(const Key<Type> &Key) const {
+ for (const Data *DataPtr = this->dataPtr.get(); DataPtr != nullptr;
+ DataPtr = DataPtr->parent.get()) {
+ if (DataPtr->KeyPtr == &Key)
+ return static_cast<const Type *>(DataPtr->value->getValuePtr());
+ }
+ return nullptr;
+ }
+
+ /// A helper to get a reference to a \p Key that must exist in the map.
+ /// Must not be called for keys that are not in the map.
+ template <class Type> const Type &getExisting(const Key<Type> &Key) const {
+ auto Val = get(Key);
+ assert(Val && "Key does not exist");
+ return *Val;
+ }
+
+ /// Derives a child context
+ /// It is safe to move or destroy a parent context after calling derive().
+ /// The child will keep its parent alive, and its data remains accessible.
+ template <class Type>
+ Context derive(const Key<Type> &Key,
+ typename std::decay<Type>::type Value) const & {
+ return Context(std::make_shared<Data>(
+ Data{/*parent=*/dataPtr, &Key,
+ std::make_unique<TypedAnyStorage<typename std::decay<Type>::type>>(
+ std::move(Value))}));
+ }
+
+ template <class Type>
+ Context
+ derive(const Key<Type> &Key,
+ typename std::decay<Type>::type Value) && /* takes ownership */ {
+ return Context(std::make_shared<Data>(
+ Data{/*parent=*/std::move(dataPtr), &Key,
+ std::make_unique<TypedAnyStorage<typename std::decay<Type>::type>>(
+ std::move(Value))}));
+ }
+
+ /// Derives a child context, using an anonymous key.
+ /// Intended for objects stored only for their destructor's side-effect.
+ template <class Type> Context derive(Type &&Value) const & {
+ static Key<typename std::decay<Type>::type> Private;
+ return derive(Private, std::forward<Type>(Value));
+ }
+
+ template <class Type> Context derive(Type &&Value) && {
+ static Key<typename std::decay<Type>::type> Private;
+ return std::move(*this).derive(Private, std::forward<Type>(Value));
+ }
+
+ /// Clone this context object.
+ Context clone() const;
+
+private:
+ class AnyStorage {
+ public:
+ virtual ~AnyStorage() = default;
+ virtual void *getValuePtr() = 0;
+ };
+
+ template <class T> class TypedAnyStorage : public Context::AnyStorage {
+ static_assert(std::is_same<typename std::decay<T>::type, T>::value,
+ "Argument to TypedAnyStorage must be decayed");
+
+ public:
+ TypedAnyStorage(T &&Value) : value(std::move(Value)) {}
+
+ void *getValuePtr() override { return &value; }
+
+ private:
+ T value;
+ };
+
+ struct Data {
+ // We need to make sure parent outlives the value, so the order of members
+ // is important. We do that to allow classes stored in Context's child
+ // layers to store references to the data in the parent layers.
+ std::shared_ptr<const Data> parent;
+ const void *KeyPtr;
+ std::unique_ptr<AnyStorage> value;
+ };
+
+ std::shared_ptr<const Data> dataPtr;
+};
+
+/// WithContext replaces Context::current() with a provided scope.
+/// When the WithContext is destroyed, the original scope is restored.
+/// For extending the current context with new value, prefer WithContextValue.
+class WithContext {
+public:
+ WithContext(Context C) : restore(Context::swapCurrent(std::move(C))) {}
+ ~WithContext() { Context::swapCurrent(std::move(restore)); }
+ WithContext(const WithContext &) = delete;
+ WithContext &operator=(const WithContext &) = delete;
+ WithContext(WithContext &&) = delete;
+ WithContext &operator=(WithContext &&) = delete;
+
+private:
+ Context restore;
+};
+
+/// WithContextValue extends Context::current() with a single value.
+/// When the WithContextValue is destroyed, the original scope is restored.
+class WithContextValue {
+public:
+ template <typename T>
+ WithContextValue(const Key<T> &K, typename std::decay<T>::type V)
+ : restore(Context::current().derive(K, std::move(V))) {}
+
+ // Anonymous values can be used for the destructor side-effect.
+ template <typename T>
+ WithContextValue(T &&V)
+ : restore(Context::current().derive(std::forward<T>(V))) {}
+
+private:
+ WithContext restore;
+};
+
+
+} // namespace lsp
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Endpoint.cpp b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Endpoint.cpp
new file mode 100644
index 0000000000..549744555b
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Endpoint.cpp
@@ -0,0 +1,46 @@
+#include "Endpoint.h"
+#include "message.h"
+
+
+bool GenericEndpoint::notify(std::unique_ptr<LspMessage> msg)
+{
+ auto findIt = method2notification.find(msg->GetMethodType());
+
+ if (findIt != method2notification.end())
+ {
+ return findIt->second(std::move(msg));
+ }
+ std::string info = "can't find method2notification for notification:\n" + msg->ToJson() + "\n";
+ log.log(lsp::Log::Level::SEVERE, info);
+ return false;
+}
+
+bool GenericEndpoint::onResponse(const std::string& method, std::unique_ptr<LspMessage>msg)
+{
+ auto findIt = method2response.find(method);
+
+ if (findIt != method2response.end())
+ {
+ return findIt->second(std::move(msg));
+ }
+
+ std::string info = "can't find method2response for response:\n" + msg->ToJson() + "\n";
+ log.log(lsp::Log::Level::SEVERE, info);
+
+ return false;
+}
+
+
+
+bool GenericEndpoint::onRequest(std::unique_ptr<LspMessage> request)
+{
+ auto findIt = method2request.find(request->GetMethodType());
+
+ if (findIt != method2request.end())
+ {
+ return findIt->second(std::move(request));
+ }
+ std::string info = "can't find method2request for request:\n" + request->ToJson() + "\n";
+ log.log(lsp::Log::Level::SEVERE, info);
+ return false;
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Endpoint.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Endpoint.h
new file mode 100644
index 0000000000..01d8e8ca91
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/Endpoint.h
@@ -0,0 +1,53 @@
+#pragma once
+#include <map>
+#include <functional>
+#include <memory>
+#include "MessageIssue.h"
+struct LspMessage;
+struct NotificationInMessage;
+struct lsBaseOutMessage;
+struct RequestInMessage;
+
+using GenericResponseHandler = std::function< bool(std::unique_ptr<LspMessage>) >;
+using GenericRequestHandler = std::function< bool(std::unique_ptr<LspMessage>) >;
+using GenericNotificationHandler = std::function< bool(std::unique_ptr<LspMessage>) >;
+
+class Endpoint
+{
+public:
+ virtual ~Endpoint() = default;
+ virtual bool onRequest(std::unique_ptr<LspMessage>) = 0;
+ virtual bool notify(std::unique_ptr<LspMessage>) = 0;
+
+ virtual bool onResponse(const std::string&, std::unique_ptr<LspMessage>) = 0;
+ virtual void registerRequestHandler(const std::string&, GenericResponseHandler ) = 0;
+ virtual void registerNotifyHandler(const std::string&, GenericNotificationHandler ) = 0;
+};
+
+class GenericEndpoint :public Endpoint
+{
+
+public:
+ GenericEndpoint(lsp::Log& l):log(l){}
+ bool notify(std::unique_ptr<LspMessage>) override;
+ bool onResponse(const std::string&, std::unique_ptr<LspMessage>) override;
+
+ bool onRequest(std::unique_ptr<LspMessage>) override;
+ std::map< std::string, GenericRequestHandler > method2request;
+ std::map< std::string, GenericResponseHandler > method2response;
+ std::map< std::string, GenericNotificationHandler > method2notification;
+
+ void registerRequestHandler(const std::string& method, GenericResponseHandler cb) override
+ {
+ method2request[method] = cb;
+ }
+
+ void registerNotifyHandler(const std::string& method, GenericNotificationHandler cb) override
+ {
+ method2notification[method] = cb;
+ }
+ lsp::Log& log;
+
+
+
+};
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/GCThreadContext.cpp b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/GCThreadContext.cpp
new file mode 100644
index 0000000000..15253411a1
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/GCThreadContext.cpp
@@ -0,0 +1,17 @@
+#include "GCThreadContext.h"
+#include <iostream>
+
+GCThreadContext::GCThreadContext()
+{
+#ifdef USEGC
+ GC_get_stack_base(&gsb);
+ GC_register_my_thread(&gsb);
+#endif
+}
+
+GCThreadContext::~GCThreadContext()
+{
+#ifdef USEGC
+ GC_unregister_my_thread();
+#endif
+} \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/GCThreadContext.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/GCThreadContext.h
new file mode 100644
index 0000000000..a0f7db288d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/GCThreadContext.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#if defined(USEGC)
+#define GC_THREADS
+#include <gc.h>
+#endif
+
+class GCThreadContext
+{
+public:
+ GCThreadContext();
+ ~GCThreadContext();
+
+private:
+#if defined(USEGC)
+ GC_stack_base gsb;
+#endif
+
+}; \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageIssue.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageIssue.h
new file mode 100644
index 0000000000..bda6e65d46
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageIssue.h
@@ -0,0 +1,182 @@
+#pragma once
+#include <string>
+#include <functional>
+#include <vector>
+namespace lsp
+{
+ class Log
+ {
+ public:
+ virtual ~Log() = default;
+
+ enum class Level
+ {
+ /**
+ * OFF is a special level that can be used to turn off logging.
+
+ */
+ OFF = 1,
+
+ /**
+ * SEVERE is a message level indicating a serious failure.
+ * <p>
+ * In general SEVERE messages should describe events that are
+ * of considerable importance and which will prevent normal
+ * program execution. They should be reasonably intelligible
+ * to end users and to system administrators.
+
+ */
+ SEVERE = 2,
+
+ /**
+ * WARNING is a message level indicating a potential problem.
+ * <p>
+ * In general WARNING messages should describe events that will
+ * be of interest to end users or system managers, or which
+ * indicate potential problems.
+
+ *
+ */
+ WARNING = 3,
+ /**
+ * INFO is a message level for informational messages.
+ * <p>
+ * Typically INFO messages will be written to the console
+ * or its equivalent. So the INFO level should only be
+ * used for reasonably significant messages that will
+ * make sense to end users and system administrators.
+
+ */
+ INFO = 3,
+ /**
+ * CONFIG is a message level for static configuration messages.
+ * <p>
+ * CONFIG messages are intended to provide a variety of static
+ * configuration information, to assist in debugging problems
+ * that may be associated with particular configurations.
+ * For example, CONFIG message might include the CPU type,
+ * the graphics depth, the GUI look-and-feel, etc.
+ * This level is initialized to <CODE>4</CODE>.
+ */
+
+ CONFIG = 4,
+
+
+
+ /**
+ * FINE is a message level providing tracing information.
+ * <p>
+ * All of FINE, FINER, and FINEST are intended for relatively
+ * detailed tracing. The exact meaning of the three levels will
+ * vary between subsystems, but in general, FINEST should be used
+ * for the most voluminous detailed output, FINER for somewhat
+ * less detailed output, and FINE for the lowest volume (and
+ * most important) messages.
+ * <p>
+ * In general the FINE level should be used for information
+ * that will be broadly interesting to developers who do not have
+ * a specialized interest in the specific subsystem.
+ * <p>
+ * FINE messages might include things like minor (recoverable)
+ * failures. Issues indicating potential performance problems
+ * are also worth logging as FINE.
+ * This level is initialized to <CODE>5</CODE>.
+ */
+ FINE = 5,
+
+ /**
+ * FINER indicates a fairly detailed tracing message.
+ * By default logging calls for entering, returning, or throwing
+ * an exception are traced at this level.
+ * This level is initialized to <CODE>400</CODE>.
+ */
+ FINER = 6,
+
+ /**
+ * FINEST indicates a highly detailed tracing message.
+ * This level is initialized to <CODE>300</CODE>.
+ */
+ FINEST = 7,
+
+ /**
+ * ALL indicates that all messages should be logged.
+ * This level is initialized to <CODE>Integer.MIN_VALUE</CODE>.
+ */
+ ALL,
+ };
+ virtual void log(Level level, std::wstring&& msg) = 0;
+ virtual void log(Level level, const std::wstring& msg) = 0;
+ virtual void log(Level level, std::string&& msg) = 0;
+ virtual void log(Level level, const std::string& msg) = 0;
+
+ void info(const std::string& msg)
+ {
+ log(Level::INFO, msg);
+ }
+ void info(const std::wstring& msg)
+ {
+ log(Level::INFO, msg);
+ }
+ void error(const std::string& msg)
+ {
+ log(Level::SEVERE, msg);
+ }
+ void error(const std::wstring& msg)
+ {
+ log(Level::SEVERE, msg);
+ }
+ void warning(const std::string& msg)
+ {
+ log(Level::WARNING, msg);
+ }
+ void warning(const std::wstring& msg)
+ {
+ log(Level::WARNING, msg);
+ }
+ };
+}
+
+class MessageIssue {
+
+public:
+ std::string text;
+
+ lsp::Log::Level code;
+
+ MessageIssue(const std::string& text, lsp::Log::Level code) :text(text), code(code)
+ {
+
+
+ }
+ MessageIssue(std::string&& text, lsp::Log::Level code) :text(text), code(code)
+ {
+
+
+ }
+
+
+ std::string getText() {
+ return text;
+ }
+
+ lsp::Log::Level getIssueCode() {
+ return code;
+ }
+
+
+ std::string toString() {
+ return getText();
+ }
+
+};
+class MessageIssueHandler
+{
+public:
+ /**
+ * Handle issues found while parsing or validating a message. The list of issues must not be empty.
+ */
+ virtual ~MessageIssueHandler() = default;
+
+ virtual void handle(std::vector<MessageIssue>&&) = 0;
+ virtual void handle( MessageIssue&&) = 0;
+};
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageJsonHandler.cpp b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageJsonHandler.cpp
new file mode 100644
index 0000000000..111b29aa1c
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageJsonHandler.cpp
@@ -0,0 +1,57 @@
+#include "MessageJsonHandler.h"
+#include <string>
+#include <rapidjson/document.h>
+
+
+
+std::unique_ptr<LspMessage> MessageJsonHandler::parseResponseMessage(const std::string& method, Reader& r)
+{
+ auto findIt = method2response.find(method);
+
+ if( findIt != method2response.end())
+ {
+ return findIt->second(r);
+ }
+ return nullptr;
+}
+
+std::unique_ptr<LspMessage> MessageJsonHandler::parseRequstMessage(const std::string& method, Reader&r)
+{
+ auto findIt = method2request.find(method);
+
+ if (findIt != method2request.end())
+ {
+ return findIt->second(r);
+ }
+ return nullptr;
+}
+
+bool MessageJsonHandler::resovleResponseMessage(Reader&r, std::pair<std::string, std::unique_ptr<LspMessage>>& result)
+{
+ for (auto& handler : method2response)
+ {
+ try
+ {
+ auto msg = handler.second(r);
+ result.first = handler.first;
+ result.second = std::move(msg);
+ return true;
+ }
+ catch (...)
+ {
+
+ }
+ }
+ return false;
+}
+
+std::unique_ptr<LspMessage> MessageJsonHandler::parseNotificationMessage(const std::string& method, Reader& r)
+{
+ auto findIt = method2notification.find(method);
+
+ if (findIt != method2notification.end())
+ {
+ return findIt->second(r);
+ }
+ return nullptr;
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageJsonHandler.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageJsonHandler.h
new file mode 100644
index 0000000000..7e238b0cf6
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageJsonHandler.h
@@ -0,0 +1,61 @@
+#pragma once
+#include <string>
+#include <map>
+#include <functional>
+#include <LibLsp/JsonRpc/message.h>
+class Reader;
+
+
+using GenericRequestJsonHandler = std::function< std::unique_ptr<LspMessage>(Reader&) >;
+using GenericResponseJsonHandler = std::function< std::unique_ptr<LspMessage>(Reader&) >;
+using GenericNotificationJsonHandler = std::function< std::unique_ptr<LspMessage>(Reader&) >;
+
+class MessageJsonHandler
+{
+public:
+ std::map< std::string, GenericRequestJsonHandler > method2request;
+ std::map< std::string, GenericResponseJsonHandler > method2response;
+ std::map< std::string, GenericNotificationJsonHandler > method2notification;
+
+
+ const GenericRequestJsonHandler* GetRequestJsonHandler(const char* methodInfo) const
+ {
+ const auto findIt = method2request.find(methodInfo);
+ return findIt == method2request.end() ? nullptr : &findIt->second;
+ }
+
+ void SetRequestJsonHandler(const std::string& methodInfo, GenericRequestJsonHandler handler)
+ {
+ method2request[methodInfo] = handler;
+ }
+
+ const GenericResponseJsonHandler* GetResponseJsonHandler(const char* methodInfo) const
+ {
+ const auto findIt = method2response.find(methodInfo);
+ return findIt == method2response.end() ? nullptr : &findIt->second;
+ }
+
+ void SetResponseJsonHandler(const std::string& methodInfo,GenericResponseJsonHandler handler)
+ {
+ method2response[methodInfo] = handler;
+ }
+
+ const GenericNotificationJsonHandler* GetNotificationJsonHandler(const char* methodInfo) const
+ {
+ const auto findIt = method2notification.find(methodInfo);
+ return findIt == method2notification.end() ? nullptr : &findIt->second;
+ }
+
+ void SetNotificationJsonHandler(const std::string& methodInfo, GenericNotificationJsonHandler handler)
+ {
+ method2notification[methodInfo] = handler;
+ }
+
+
+
+ std::unique_ptr<LspMessage> parseResponseMessage(const std::string&, Reader&);
+ std::unique_ptr<LspMessage> parseRequstMessage(const std::string&, Reader&);
+ bool resovleResponseMessage(Reader&, std::pair<std::string, std::unique_ptr<LspMessage>>& result);
+ std::unique_ptr<LspMessage> parseNotificationMessage(const std::string&, Reader&);
+};
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageProducer.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageProducer.h
new file mode 100644
index 0000000000..ab7a29a17f
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/MessageProducer.h
@@ -0,0 +1,13 @@
+#pragma once
+#include <string>
+#include <functional>
+
+class MessageProducer
+{
+public:
+
+
+ typedef std::function< void(std::string&&) > MessageConsumer;
+ virtual ~MessageProducer() = default;
+ virtual void listen(MessageConsumer) = 0;
+};
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/NotificationInMessage.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/NotificationInMessage.h
new file mode 100644
index 0000000000..e4841b5703
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/NotificationInMessage.h
@@ -0,0 +1,62 @@
+#pragma once
+
+
+#include "lsRequestId.h"
+#include "LibLsp/JsonRpc/message.h"
+
+
+
+// NotificationInMessage does not have |id|.
+struct NotificationInMessage : public LspMessage {
+
+ Kind GetKid() override
+ {
+ return NOTIFICATION_MESSAGE;
+ }
+ MethodType GetMethodType() const override
+ {
+ return method.c_str();
+ }
+ void SetMethodType(MethodType _t) override
+ {
+ method = _t;
+ }
+ std::string method;
+};
+template <class T, class TDerived >
+struct lsNotificationInMessage : NotificationInMessage {
+
+ void ReflectWriter(Writer& writer) override {
+ Reflect(writer, static_cast<TDerived&>(*this));
+ }
+ lsNotificationInMessage(MethodType _method)
+ {
+ method = _method;
+ }
+
+ static std::unique_ptr<LspMessage> ReflectReader(Reader& visitor) {
+
+ TDerived* temp = new TDerived();
+
+ std::unique_ptr<TDerived> message = std::unique_ptr<TDerived>(temp);
+ // Reflect may throw and *message will be partially deserialized.
+ Reflect(visitor, static_cast<TDerived&>(*temp));
+ return message;
+
+ }
+ void swap(lsNotificationInMessage& arg) noexcept
+ {
+ method.swap(method);
+ std::swap(params, arg.params);
+ }
+ T params;
+};
+
+#define DEFINE_NOTIFICATION_TYPE(MSG,paramType,methodInfo)\
+namespace MSG {\
+ struct notify : public lsNotificationInMessage< paramType , notify >{\
+ static constexpr MethodType kMethodInfo = methodInfo;\
+ notify():lsNotificationInMessage(kMethodInfo){} \
+ };\
+};\
+MAKE_REFLECT_STRUCT(MSG::notify, jsonrpc,method, params)
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/RemoteEndPoint.cpp b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/RemoteEndPoint.cpp
new file mode 100644
index 0000000000..46f09ec686
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/RemoteEndPoint.cpp
@@ -0,0 +1,612 @@
+#include "MessageJsonHandler.h"
+#include "Endpoint.h"
+#include "message.h"
+#include "RemoteEndPoint.h"
+#include <future>
+#include "Cancellation.h"
+#include "StreamMessageProducer.h"
+#include "NotificationInMessage.h"
+#include "lsResponseMessage.h"
+#include "Condition.h"
+#include "Context.h"
+#include "rapidjson/error/en.h"
+#include "json.h"
+#include "GCThreadContext.h"
+#include "ScopeExit.h"
+#include "stream.h"
+
+#define BOOST_BIND_GLOBAL_PLACEHOLDERS
+#include "boost/threadpool.hpp"
+#include <atomic>
+namespace lsp {
+
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//===----------------------------------------------------------------------===//
+
+// Cancellation mechanism for long-running tasks.
+//
+// This manages interactions between:
+//
+// 1. Client code that starts some long-running work, and maybe cancels later.
+//
+// std::pair<Context, Canceler> Task = cancelableTask();
+// {
+// WithContext Cancelable(std::move(Task.first));
+// Expected
+// deepThoughtAsync([](int answer){ errs() << answer; });
+// }
+// // ...some time later...
+// if (User.fellAsleep())
+// Task.second();
+//
+// (This example has an asynchronous computation, but synchronous examples
+// work similarly - the Canceler should be invoked from another thread).
+//
+// 2. Library code that executes long-running work, and can exit early if the
+// result is not needed.
+//
+// void deepThoughtAsync(std::function<void(int)> Callback) {
+// runAsync([Callback]{
+// int A = ponder(6);
+// if (getCancelledMonitor())
+// return;
+// int B = ponder(9);
+// if (getCancelledMonitor())
+// return;
+// Callback(A * B);
+// });
+// }
+//
+// (A real example may invoke the callback with an error on cancellation,
+// the CancelledError is provided for this purpose).
+//
+// Cancellation has some caveats:
+// - the work will only stop when/if the library code next checks for it.
+// Code outside clangd such as Sema will not do this.
+// - it's inherently racy: client code must be prepared to accept results
+// even after requesting cancellation.
+// - it's Context-based, so async work must be dispatched to threads in
+// ways that preserve the context. (Like runAsync() or TUScheduler).
+//
+
+ /// A canceller requests cancellation of a task, when called.
+ /// Calling it again has no effect.
+ using Canceler = std::function<void()>;
+
+ // We don't want a cancelable scope to "shadow" an enclosing one.
+ struct CancelState {
+ std::shared_ptr<std::atomic<int>> cancelled;
+ const CancelState* parent = nullptr;
+ lsRequestId id;
+ };
+ static Key<CancelState> g_stateKey;
+
+ /// Defines a new task whose cancellation may be requested.
+ /// The returned Context defines the scope of the task.
+ /// When the context is active, getCancelledMonitor() is 0 until the Canceler is
+ /// invoked, and equal to Reason afterwards.
+ /// Conventionally, Reason may be the LSP error code to return.
+ std::pair<Context, Canceler> cancelableTask(const lsRequestId& id,int reason = 1){
+ assert(reason != 0 && "Can't detect cancellation if Reason is zero");
+ CancelState state;
+ state.id = id;
+ state.cancelled = std::make_shared<std::atomic<int>>();
+ state.parent = Context::current().get(g_stateKey);
+ return {
+ Context::current().derive(g_stateKey, state),
+ [reason, cancelled(state.cancelled)] { *cancelled = reason; },
+ };
+ }
+ /// If the current context is within a cancelled task, returns the reason.
+/// (If the context is within multiple nested tasks, true if any are cancelled).
+/// Always zero if there is no active cancelable task.
+/// This isn't free (context lookup) - don't call it in a tight loop.
+ boost::optional<CancelMonitor> getCancelledMonitor(const lsRequestId& id, const Context& ctx = Context::current()){
+ for (const CancelState* state = ctx.get(g_stateKey); state != nullptr;
+ state = state->parent)
+ {
+ if (id != state->id)continue;
+ const std::shared_ptr<std::atomic<int> > cancelled = state->cancelled;
+ std::function<int()> temp = [=]{
+ return cancelled->load();
+ };
+ return std::move(temp);
+ }
+
+ return {};
+ }
+} // namespace lsp
+
+using namespace lsp;
+class PendingRequestInfo
+{
+ using RequestCallBack = std::function< bool(std::unique_ptr<LspMessage>) >;
+public:
+ PendingRequestInfo(const std::string& md,
+ const RequestCallBack& callback);
+ PendingRequestInfo(const std::string& md);
+ PendingRequestInfo() {}
+ std::string method;
+ RequestCallBack futureInfo;
+};
+
+PendingRequestInfo::PendingRequestInfo(const std::string& _md,
+ const RequestCallBack& callback) : method(_md),
+ futureInfo(callback)
+{
+}
+
+PendingRequestInfo::PendingRequestInfo(const std::string& md) : method(md)
+{
+}
+struct RemoteEndPoint::Data
+{
+ explicit Data(lsp::Log& _log , RemoteEndPoint* owner)
+ : m_id(0), next_request_cookie(0), message_producer(new StreamMessageProducer(*owner)), log(_log)
+ {
+
+ }
+ ~Data()
+ {
+ delete message_producer;
+ }
+ std::atomic<unsigned> m_id;
+ boost::threadpool::pool tp;
+ // Method calls may be cancelled by ID, so keep track of their state.
+ // This needs a mutex: handlers may finish on a different thread, and that's
+ // when we clean up entries in the map.
+ mutable std::mutex request_cancelers_mutex;
+
+ std::map< lsRequestId, std::pair<Canceler, /*Cookie*/ unsigned> > requestCancelers;
+
+ std::atomic<unsigned> next_request_cookie; // To disambiguate reused IDs, see below.
+ void onCancel(Notify_Cancellation::notify* notify) {
+ std::lock_guard<std::mutex> Lock(request_cancelers_mutex);
+ const auto it = requestCancelers.find(notify->params.id);
+ if (it != requestCancelers.end())
+ it->second.first(); // Invoke the canceler.
+ }
+
+ // We run cancelable requests in a context that does two things:
+ // - allows cancellation using requestCancelers[ID]
+ // - cleans up the entry in requestCancelers when it's no longer needed
+ // If a client reuses an ID, the last wins and the first cannot be canceled.
+ Context cancelableRequestContext(lsRequestId id) {
+ auto task = cancelableTask(id,
+ /*Reason=*/static_cast<int>(lsErrorCodes::RequestCancelled));
+ unsigned cookie;
+ {
+ std::lock_guard<std::mutex> Lock(request_cancelers_mutex);
+ cookie = next_request_cookie.fetch_add(1, std::memory_order_relaxed);
+ requestCancelers[id] = { std::move(task.second), cookie };
+ }
+ // When the request ends, we can clean up the entry we just added.
+ // The cookie lets us check that it hasn't been overwritten due to ID
+ // reuse.
+ return task.first.derive(lsp::make_scope_exit([this, id, cookie] {
+ std::lock_guard<std::mutex> lock(request_cancelers_mutex);
+ const auto& it = requestCancelers.find(id);
+ if (it != requestCancelers.end() && it->second.second == cookie)
+ requestCancelers.erase(it);
+ }));
+ }
+
+ std::map <lsRequestId, std::shared_ptr<PendingRequestInfo>> _client_request_futures;
+ StreamMessageProducer* message_producer;
+ std::atomic<bool> quit{};
+ lsp::Log& log;
+ std::shared_ptr<lsp::istream> input;
+ std::shared_ptr<lsp::ostream> output;
+
+ void pendingRequest(RequestInMessage& info, GenericResponseHandler&& handler)
+ {
+ auto id = m_id.fetch_add(1, std::memory_order_relaxed);
+ info.id.set(id);
+ std::lock_guard<std::mutex> lock(m_requsetInfo);
+ _client_request_futures[info.id] = std::make_shared<PendingRequestInfo>(info.method, handler);
+
+ }
+ const std::shared_ptr<const PendingRequestInfo> getRequestInfo(const lsRequestId& _id)
+ {
+ std::lock_guard<std::mutex> lock(m_requsetInfo);
+ auto findIt = _client_request_futures.find(_id);
+ if (findIt != _client_request_futures.end())
+ {
+ return findIt->second;
+ }
+ return nullptr;
+ }
+
+ std::mutex m_requsetInfo;
+ void removeRequestInfo(const lsRequestId& _id)
+ {
+ std::lock_guard<std::mutex> lock(m_requsetInfo);
+ auto findIt = _client_request_futures.find(_id);
+ if (findIt != _client_request_futures.end())
+ {
+ _client_request_futures.erase(findIt);
+ }
+ }
+ void clear()
+ {
+ {
+ std::lock_guard<std::mutex> lock(m_requsetInfo);
+ _client_request_futures.clear();
+
+ }
+ tp.clear();
+ quit.store(true, std::memory_order_relaxed);
+ }
+};
+
+namespace
+{
+void WriterMsg(std::shared_ptr<lsp::ostream>& output, LspMessage& msg)
+{
+ const auto& s = msg.ToJson();
+ const auto value =
+ std::string("Content-Length: ") + std::to_string(s.size()) + "\r\n\r\n" + s;
+ output->write(value);
+ output->flush();
+}
+
+bool isResponseMessage(JsonReader& visitor)
+{
+
+ if (!visitor.HasMember("id"))
+ {
+ return false;
+ }
+
+ if (!visitor.HasMember("result") && !visitor.HasMember("error"))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool isRequestMessage(JsonReader& visitor)
+{
+ if (!visitor.HasMember("method"))
+ {
+ return false;
+ }
+ if (!visitor["method"]->IsString())
+ {
+ return false;
+ }
+ if (!visitor.HasMember("id"))
+ {
+ return false;
+ }
+ return true;
+}
+bool isNotificationMessage(JsonReader& visitor)
+{
+ if (!visitor.HasMember("method"))
+ {
+ return false;
+ }
+ if (!visitor["method"]->IsString())
+ {
+ return false;
+ }
+ if (visitor.HasMember("id"))
+ {
+ return false;
+ }
+ return true;
+}
+}
+
+CancelMonitor RemoteEndPoint::getCancelMonitor(const lsRequestId& id)
+{
+ auto monitor = getCancelledMonitor(id);
+ if(monitor.has_value())
+ {
+ return monitor.value();
+ }
+ return [] {
+ return 0;
+ };
+
+}
+
+RemoteEndPoint::RemoteEndPoint(
+ const std::shared_ptr < MessageJsonHandler >& json_handler,const std::shared_ptr < Endpoint>& localEndPoint, lsp::Log& _log, uint8_t max_workers):
+ d_ptr(new Data(_log,this)),jsonHandler(json_handler), local_endpoint(localEndPoint)
+{
+ jsonHandler->method2notification[Notify_Cancellation::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_Cancellation::notify::ReflectReader(visitor);
+ };
+
+ d_ptr->quit.store(false, std::memory_order_relaxed);
+ d_ptr->tp.size_controller().resize(max_workers);
+}
+
+RemoteEndPoint::~RemoteEndPoint()
+{
+ delete d_ptr;
+ d_ptr->quit.store(true, std::memory_order_relaxed);
+}
+
+bool RemoteEndPoint::dispatch(const std::string& content)
+{
+ rapidjson::Document document;
+ document.Parse(content.c_str(), content.length());
+ if (document.HasParseError())
+ {
+ std::string info ="lsp msg format error:";
+ rapidjson::GetParseErrorFunc GetParseError = rapidjson::GetParseError_En; // or whatever
+ info+= GetParseError(document.GetParseError());
+ info += "\n";
+ info += "ErrorContext offset:\n";
+ info += content.substr(document.GetErrorOffset());
+ d_ptr->log.log(Log::Level::SEVERE, info);
+
+ return false;
+ }
+
+ JsonReader visitor{ &document };
+ if (!visitor.HasMember("jsonrpc") ||
+ std::string(visitor["jsonrpc"]->GetString()) != "2.0")
+ {
+ std::string reason;
+ reason = "Reason:Bad or missing jsonrpc version\n";
+ reason += "content:\n" + content;
+ d_ptr->log.log(Log::Level::SEVERE, reason);
+ return false;
+
+ }
+ LspMessage::Kind _kind = LspMessage::NOTIFICATION_MESSAGE;
+ try {
+ if (isRequestMessage(visitor))
+ {
+ _kind = LspMessage::REQUEST_MESSAGE;
+ auto msg = jsonHandler->parseRequstMessage(visitor["method"]->GetString(), visitor);
+ if (msg) {
+ mainLoop(std::move(msg));
+ }
+ else {
+ std::string info = "Unknown support request message when consumer message:\n";
+ info += content;
+ d_ptr->log.log(Log::Level::WARNING, info);
+ return false;
+ }
+ }
+ else if (isResponseMessage(visitor))
+ {
+ _kind = LspMessage::RESPONCE_MESSAGE;
+ lsRequestId id;
+ ReflectMember(visitor, "id", id);
+
+ auto msgInfo = d_ptr->getRequestInfo(id);
+ if (!msgInfo)
+ {
+ std::pair<std::string, std::unique_ptr<LspMessage>> result;
+ auto b = jsonHandler->resovleResponseMessage(visitor, result);
+ if (b)
+ {
+ result.second->SetMethodType(result.first.c_str());
+ mainLoop(std::move(result.second));
+ }
+ else
+ {
+ std::string info = "Unknown response message :\n";
+ info += content;
+ d_ptr->log.log(Log::Level::INFO, info);
+ }
+ }
+ else
+ {
+
+ auto msg = jsonHandler->parseResponseMessage(msgInfo->method, visitor);
+ if (msg) {
+ mainLoop(std::move(msg));
+ }
+ else
+ {
+ std::string info = "Unknown response message :\n";
+ info += content;
+ d_ptr->log.log(Log::Level::SEVERE, info);
+ return false;
+ }
+
+ }
+ }
+ else if (isNotificationMessage(visitor))
+ {
+ auto msg = jsonHandler->parseNotificationMessage(visitor["method"]->GetString(), visitor);
+ if (!msg)
+ {
+ std::string info = "Unknown notification message :\n";
+ info += content;
+ d_ptr->log.log(Log::Level::SEVERE, info);
+ return false;
+ }
+ mainLoop(std::move(msg));
+ }
+ else
+ {
+ std::string info = "Unknown lsp message when consumer message:\n";
+ info += content;
+ d_ptr->log.log(Log::Level::WARNING, info);
+ return false;
+ }
+ }
+ catch (std::exception& e)
+ {
+
+ std::string info = "Exception when process ";
+ if(_kind==LspMessage::REQUEST_MESSAGE)
+ {
+ info += "request";
+ }
+ if (_kind == LspMessage::RESPONCE_MESSAGE)
+ {
+ info += "response";
+ }
+ else
+ {
+ info += "notification";
+ }
+ info += " message:\n";
+ info += e.what();
+ std::string reason = "Reason:" + info + "\n";
+ reason += "content:\n" + content;
+ d_ptr->log.log(Log::Level::SEVERE, reason);
+ return false;
+ }
+ return true;
+}
+
+
+
+void RemoteEndPoint::internalSendRequest( RequestInMessage& info, GenericResponseHandler handler)
+{
+ std::lock_guard<std::mutex> lock(m_sendMutex);
+ if (!d_ptr->output || d_ptr->output->bad())
+ {
+ std::string desc = "Output isn't good any more:\n";
+ d_ptr->log.log(Log::Level::INFO, desc);
+ return ;
+ }
+ d_ptr->pendingRequest(info, std::move(handler));
+ WriterMsg(d_ptr->output, info);
+}
+
+
+std::unique_ptr<LspMessage> RemoteEndPoint::internalWaitResponse(RequestInMessage& request, unsigned time_out)
+{
+ auto eventFuture = std::make_shared< Condition< LspMessage > >();
+ internalSendRequest(request, [=](std::unique_ptr<LspMessage> data)
+ {
+ eventFuture->notify(std::move(data));
+ return true;
+ });
+ return eventFuture->wait(time_out);
+}
+
+void RemoteEndPoint::mainLoop(std::unique_ptr<LspMessage>msg)
+{
+ if(d_ptr->quit.load(std::memory_order_relaxed))
+ {
+ return;
+ }
+ const auto _kind = msg->GetKid();
+ if (_kind == LspMessage::REQUEST_MESSAGE)
+ {
+ auto req = static_cast<RequestInMessage*>(msg.get());
+ // Calls can be canceled by the client. Add cancellation context.
+ WithContext WithCancel(d_ptr->cancelableRequestContext(req->id));
+ local_endpoint->onRequest(std::move(msg));
+ }
+
+ else if (_kind == LspMessage::RESPONCE_MESSAGE)
+ {
+ auto response = static_cast<ResponseInMessage*>(msg.get());
+ auto msgInfo = d_ptr->getRequestInfo(response->id);
+ if (!msgInfo)
+ {
+ const auto _method_desc = msg->GetMethodType();
+ local_endpoint->onResponse(_method_desc, std::move(msg));
+ }
+ else
+ {
+ bool needLocal = true;
+ if (msgInfo->futureInfo)
+ {
+ if (msgInfo->futureInfo(std::move(msg)))
+ {
+ needLocal = false;
+ }
+ }
+ if (needLocal)
+ {
+ local_endpoint->onResponse(msgInfo->method, std::move(msg));
+ }
+ d_ptr->removeRequestInfo(response->id);
+ }
+ }
+ else if (_kind == LspMessage::NOTIFICATION_MESSAGE)
+ {
+ if (strcmp(Notify_Cancellation::notify::kMethodInfo, msg->GetMethodType())==0)
+ {
+ d_ptr->onCancel(static_cast<Notify_Cancellation::notify*>(msg.get()));
+ }
+ else
+ {
+ local_endpoint->notify(std::move(msg));
+ }
+
+ }
+ else
+ {
+ std::string info = "Unknown lsp message when process message in mainLoop:\n";
+ d_ptr->log.log(Log::Level::WARNING, info);
+ }
+}
+
+void RemoteEndPoint::handle(std::vector<MessageIssue>&& issue)
+{
+ for(auto& it : issue)
+ {
+ d_ptr->log.log(it.code, it.text);
+ }
+}
+
+void RemoteEndPoint::handle(MessageIssue&& issue)
+{
+ d_ptr->log.log(issue.code, issue.text);
+}
+
+
+void RemoteEndPoint::startProcessingMessages(std::shared_ptr<lsp::istream> r,
+ std::shared_ptr<lsp::ostream> w)
+{
+ d_ptr->quit.store(false, std::memory_order_relaxed);
+ d_ptr->input = r;
+ d_ptr->output = w;
+ d_ptr->message_producer->bind(r);
+ message_producer_thread_ = std::make_shared<std::thread>([&]()
+ {
+ d_ptr->message_producer->listen([&](std::string&& content){
+ const auto temp = std::make_shared<std::string>(std::move(content));
+ d_ptr->tp.schedule([this, temp]{
+#ifdef USEGC
+ GCThreadContext gcContext;
+#endif
+
+ dispatch(*temp);
+ });
+ });
+ });
+}
+
+void RemoteEndPoint::Stop()
+{
+ if(message_producer_thread_ && message_producer_thread_->joinable())
+ {
+ message_producer_thread_->detach();
+ }
+ d_ptr->clear();
+
+}
+
+void RemoteEndPoint::sendMsg( LspMessage& msg)
+{
+
+ std::lock_guard<std::mutex> lock(m_sendMutex);
+ if (!d_ptr->output || d_ptr->output->bad())
+ {
+ std::string info = "Output isn't good any more:\n";
+ d_ptr->log.log(Log::Level::INFO, info);
+ return;
+ }
+ WriterMsg(d_ptr->output, msg);
+
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/RemoteEndPoint.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/RemoteEndPoint.h
new file mode 100644
index 0000000000..3ae6b567a5
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/RemoteEndPoint.h
@@ -0,0 +1,340 @@
+#pragma once
+#include "LibLsp/lsp/lsp_diagnostic.h"
+#include "LibLsp/JsonRpc/Cancellation.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+#include "traits.h"
+#include <future>
+#include <string>
+#include "threaded_queue.h"
+#include <unordered_map>
+#include "MessageIssue.h"
+#include "LibLsp/JsonRpc/MessageJsonHandler.h"
+#include "Endpoint.h"
+
+
+class MessageJsonHandler;
+class Endpoint;
+struct LspMessage;
+class RemoteEndPoint;
+namespace lsp {
+ class ostream;
+ class istream;
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // ResponseOrError<T>
+ ////////////////////////////////////////////////////////////////////////////////
+
+ // ResponseOrError holds either the response to a request or an error
+ // message.
+ template <typename T>
+ struct ResponseOrError {
+ using Request = T;
+ ResponseOrError();
+ ResponseOrError(const T& response);
+ ResponseOrError(T&& response);
+ ResponseOrError(const Rsp_Error& error);
+ ResponseOrError(Rsp_Error&& error);
+ ResponseOrError(const ResponseOrError& other);
+ ResponseOrError(ResponseOrError&& other) noexcept;
+
+ ResponseOrError& operator=(const ResponseOrError& other);
+ ResponseOrError& operator=(ResponseOrError&& other) noexcept;
+ bool IsError() const { return is_error; }
+ std::string ToJson()
+ {
+ if (is_error) return error.ToJson();
+ return response.ToJson();
+ }
+ T response;
+ Rsp_Error error; // empty represents success.
+ bool is_error;
+ };
+
+ template <typename T>
+ ResponseOrError<T>::ResponseOrError(): is_error(false)
+ {
+ }
+
+ template <typename T>
+ ResponseOrError<T>::ResponseOrError(const T& resp) : response(resp), is_error(false) {}
+ template <typename T>
+ ResponseOrError<T>::ResponseOrError(T&& resp) : response(std::move(resp)), is_error(false) {}
+ template <typename T>
+ ResponseOrError<T>::ResponseOrError(const Rsp_Error& err) : error(err), is_error(true) {}
+ template <typename T>
+ ResponseOrError<T>::ResponseOrError(Rsp_Error&& err) : error(std::move(err)), is_error(true) {}
+ template <typename T>
+ ResponseOrError<T>::ResponseOrError(const ResponseOrError& other)
+ : response(other.response), error(other.error), is_error(other.is_error) {}
+ template <typename T>
+ ResponseOrError<T>::ResponseOrError(ResponseOrError&& other) noexcept
+ : response(std::move(other.response)), error(std::move(other.error)), is_error(other.is_error) {}
+ template <typename T>
+ ResponseOrError<T>& ResponseOrError<T>::operator=(
+ const ResponseOrError& other) {
+ response = other.response;
+ error = other.error;
+ is_error = other.is_error;
+ return *this;
+ }
+ template <typename T>
+ ResponseOrError<T>& ResponseOrError<T>::operator=(ResponseOrError&& other) noexcept
+ {
+ response = std::move(other.response);
+ error = std::move(other.error);
+ is_error = other.is_error;
+ return *this;
+ }
+
+}
+
+
+class RemoteEndPoint :MessageIssueHandler
+{
+
+ template <typename F, int N>
+ using ParamType = lsp::traits::ParameterType<F, N>;
+
+ template <typename T>
+ using IsRequest = lsp::traits::EnableIfIsType<RequestInMessage, T>;
+
+ template <typename T>
+ using IsResponse = lsp::traits::EnableIfIsType<ResponseInMessage, T>;
+
+ template <typename T>
+ using IsNotify = lsp::traits::EnableIfIsType<NotificationInMessage, T>;
+
+
+ template <typename F, typename ReturnType>
+ using IsRequestHandler = lsp::traits::EnableIf<lsp::traits::CompatibleWith<
+ F,
+ std::function<ReturnType(const RequestInMessage&)>>::
+ value>;
+
+ template <typename F, typename ReturnType>
+ using IsRequestHandlerWithMonitor = lsp::traits::EnableIf<lsp::traits::CompatibleWith<
+ F,
+ std::function<ReturnType(const RequestInMessage&,const CancelMonitor&)>>::
+ value>;
+
+public:
+
+
+ RemoteEndPoint(const std::shared_ptr <MessageJsonHandler>& json_handler,
+ const std::shared_ptr < Endpoint >& localEndPoint,
+ lsp::Log& _log, uint8_t max_workers = 2);
+
+ ~RemoteEndPoint() override;
+ template <typename F, typename RequestType = ParamType<F, 0>, typename ResponseType = typename RequestType::Response>
+ IsRequestHandler< F, lsp::ResponseOrError<ResponseType> > registerHandler(F&& handler)
+ {
+ ProcessRequestJsonHandler(handler);
+ local_endpoint->registerRequestHandler(RequestType::kMethodInfo, [=](std::unique_ptr<LspMessage> msg) {
+ auto req = reinterpret_cast<const RequestType*>(msg.get());
+ lsp::ResponseOrError<ResponseType> res(handler(*req));
+ if (res.is_error) {
+ res.error.id = req->id;
+ send(res.error);
+ }
+ else
+ {
+ res.response.id = req->id;
+ send(res.response);
+ }
+ return true;
+ });
+ }
+ template <typename F, typename RequestType = ParamType<F, 0>, typename ResponseType = typename RequestType::Response>
+ IsRequestHandlerWithMonitor< F, lsp::ResponseOrError<ResponseType> > registerHandler(F&& handler) {
+ ProcessRequestJsonHandler(handler);
+ local_endpoint->registerRequestHandler(RequestType::kMethodInfo, [=](std::unique_ptr<LspMessage> msg) {
+ auto req = static_cast<const RequestType*>(msg.get());
+ lsp::ResponseOrError<ResponseType> res(handler(*req , getCancelMonitor(req->id)));
+ if (res.is_error) {
+ res.error.id = req->id;
+ send(res.error);
+ }
+ else
+ {
+ res.response.id = req->id;
+ send(res.response);
+ }
+ return true;
+ });
+ }
+ using RequestErrorCallback = std::function<void(const Rsp_Error&)>;
+
+ template <typename T, typename F, typename ResponseType = ParamType<F, 0> >
+ void send(T& request, F&& handler, RequestErrorCallback onError)
+ {
+ ProcessRequestJsonHandler(handler);
+ auto cb = [=](std::unique_ptr<LspMessage> msg) {
+ if (!msg)
+ return true;
+ const auto result = msg.get();
+
+ if (static_cast<ResponseInMessage*>(result)->IsErrorType()) {
+ const auto rsp_error = static_cast<const Rsp_Error*>(result);
+ onError(*rsp_error);
+ }
+ else {
+ handler(*static_cast<ResponseType*>(result));
+ }
+
+ return true;
+ };
+ internalSendRequest(request, cb);
+ }
+
+
+ template <typename F, typename NotifyType = ParamType<F, 0> >
+ IsNotify<NotifyType> registerHandler(F&& handler) {
+ {
+ std::lock_guard<std::mutex> lock(m_sendMutex);
+ if (!jsonHandler->GetNotificationJsonHandler(NotifyType::kMethodInfo))
+ {
+ jsonHandler->SetNotificationJsonHandler(NotifyType::kMethodInfo,
+ [](Reader& visitor)
+ {
+ return NotifyType::ReflectReader(visitor);
+ });
+ }
+ }
+ local_endpoint->registerNotifyHandler(NotifyType::kMethodInfo, [=](std::unique_ptr<LspMessage> msg) {
+ handler(*static_cast<NotifyType*>(msg.get()));
+ return true;
+ });
+ }
+
+ template <typename T, typename = IsRequest<T>>
+ std::future< lsp::ResponseOrError<typename T::Response> > send(T& request) {
+
+ ProcessResponseJsonHandler(request);
+ using Response = typename T::Response;
+ auto promise = std::make_shared< std::promise<lsp::ResponseOrError<Response>>>();
+ auto cb = [=](std::unique_ptr<LspMessage> msg) {
+ if (!msg)
+ return true;
+ auto result = msg.get();
+
+ if (reinterpret_cast<ResponseInMessage*>(result)->IsErrorType())
+ {
+ Rsp_Error* rsp_error = static_cast<Rsp_Error*>(result);
+ Rsp_Error temp;
+ std::swap(temp, *rsp_error);
+ promise->set_value(std::move(lsp::ResponseOrError<Response>(std::move(temp))));
+ }
+ else
+ {
+ Response temp;
+ std::swap(temp, *static_cast<Response*>(result));
+ promise->set_value(std::move(lsp::ResponseOrError<Response>(std::move(temp))));
+ }
+ return true;
+ };
+ internalSendRequest(request, cb);
+ return promise->get_future();
+ }
+
+ template <typename T, typename = IsRequest<T>>
+ std::unique_ptr<lsp::ResponseOrError<typename T::Response>> waitResponse(T& request, const unsigned time_out = 0)
+ {
+ auto future_rsp = send(request);
+ if (time_out == 0)
+ {
+ future_rsp.wait();
+ }
+ else
+ {
+ auto state = future_rsp.wait_for(std::chrono::milliseconds(time_out));
+ if (std::future_status::timeout == state)
+ {
+ return {};
+ }
+ }
+
+ using Response = typename T::Response;
+ return std::make_unique<lsp::ResponseOrError<Response>>(std::move(future_rsp.get()));
+ }
+
+ void send(NotificationInMessage& msg)
+ {
+ sendMsg(msg);
+ }
+
+ void send(ResponseInMessage& msg)
+ {
+ sendMsg(msg);
+ }
+
+ void sendNotification(NotificationInMessage& msg)
+ {
+ send(msg);
+ }
+ void sendResponse(ResponseInMessage& msg)
+ {
+ send(msg);
+ }
+ void startProcessingMessages(std::shared_ptr<lsp::istream> r,
+ std::shared_ptr<lsp::ostream> w);
+
+ bool IsWorking() const
+ {
+ if (message_producer_thread_)
+ return true;
+ return false;
+ }
+ void Stop();
+
+ std::unique_ptr<LspMessage> internalWaitResponse(RequestInMessage&, unsigned time_out = 0);
+
+ void internalSendRequest(RequestInMessage&, GenericResponseHandler);
+
+ void handle(std::vector<MessageIssue>&&) override;
+ void handle(MessageIssue&&) override;
+private:
+ CancelMonitor getCancelMonitor(const lsRequestId&);
+ void sendMsg(LspMessage& msg);
+ void mainLoop(std::unique_ptr<LspMessage>);
+ bool dispatch(const std::string&);
+ template <typename F, typename RequestType = ParamType<F, 0>>
+ IsRequest<RequestType> ProcessRequestJsonHandler(const F& handler) {
+ std::lock_guard<std::mutex> lock(m_sendMutex);
+ if (!jsonHandler->GetRequestJsonHandler(RequestType::kMethodInfo))
+ {
+ jsonHandler->SetRequestJsonHandler(RequestType::kMethodInfo,
+ [](Reader& visitor)
+ {
+ return RequestType::ReflectReader(visitor);
+ });
+ }
+ }
+ template <typename T, typename = IsRequest<T>>
+ void ProcessResponseJsonHandler(T& request)
+ {
+ using Response = typename T::Response;
+ std::lock_guard<std::mutex> lock(m_sendMutex);
+ if (!jsonHandler->GetResponseJsonHandler(T::kMethodInfo))
+ {
+ jsonHandler->SetResponseJsonHandler(T::kMethodInfo, [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return Response::ReflectReader(visitor);
+ });
+ }
+ }
+
+ struct Data;
+
+ Data* d_ptr;
+
+ std::shared_ptr < MessageJsonHandler> jsonHandler;
+ std::mutex m_sendMutex;
+
+ std::shared_ptr < Endpoint > local_endpoint;
+public:
+ std::shared_ptr < std::thread > message_producer_thread_;
+};
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/RequestInMessage.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/RequestInMessage.h
new file mode 100644
index 0000000000..163d038a2e
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/RequestInMessage.h
@@ -0,0 +1,70 @@
+#pragma once
+
+
+#include "serializer.h"
+#include <atomic>
+#include <mutex>
+#include "lsRequestId.h"
+#include "LibLsp/JsonRpc/message.h"
+#include "LibLsp/lsp/method_type.h"
+#include "lsResponseMessage.h"
+
+struct RequestInMessage : public LspMessage {
+ // number or string, actually no null
+ lsRequestId id;
+ std::string method;
+ Kind GetKid() override
+ {
+ return REQUEST_MESSAGE;
+ }
+
+};
+
+
+
+template <class T, class TDerived >
+struct lsRequest : public RequestInMessage
+{
+ lsRequest(MethodType _method)
+ {
+ method = _method;
+ }
+ MethodType GetMethodType() const override { return method.c_str(); }
+ void SetMethodType(MethodType _method) override
+ {
+ method = _method;
+ } \
+ void ReflectWriter(Writer& writer) override {
+ Reflect(writer, static_cast<TDerived&>(*this));
+ }
+
+ static std::unique_ptr<LspMessage> ReflectReader(Reader& visitor) {
+
+ TDerived* temp = new TDerived();
+ std::unique_ptr<TDerived> message = std::unique_ptr<TDerived>(temp);
+ // Reflect may throw and *message will be partially deserialized.
+ Reflect(visitor, static_cast<TDerived&>(*temp));
+ return message;
+ }
+ void swap(lsRequest& arg) noexcept
+ {
+ id.swap(arg.id);
+ method.swap(method);
+ std::swap(params, arg.params);
+ }
+ T params;
+};
+
+
+#define DEFINE_REQUEST_RESPONSE_TYPE(MSG,request_param,response_result,methodInfo)\
+namespace MSG {\
+ struct response :public ResponseMessage< response_result, response> {}; \
+ struct request : public lsRequest< request_param , request >{\
+ static constexpr MethodType kMethodInfo = methodInfo;\
+ request():lsRequest(kMethodInfo){} \
+ using Response = response;\
+ };\
+};\
+MAKE_REFLECT_STRUCT(MSG::request, jsonrpc, id, method, params);\
+MAKE_REFLECT_STRUCT(MSG::response, jsonrpc, id, result);
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/ScopeExit.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/ScopeExit.h
new file mode 100644
index 0000000000..024b700b4a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/ScopeExit.h
@@ -0,0 +1,59 @@
+//===- llvm/ADT/ScopeExit.h - Execute code at scope exit --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the make_scope_exit function, which executes user-defined
+// cleanup logic at scope exit.
+//
+//===----------------------------------------------------------------------===//
+#pragma once
+#include <type_traits>
+#include <utility>
+
+namespace lsp {
+namespace detail {
+
+template <typename Callable> class scope_exit {
+ Callable ExitFunction;
+ bool Engaged = true; // False once moved-from or release()d.
+
+public:
+ template <typename Fp>
+ explicit scope_exit(Fp &&F) : ExitFunction(std::forward<Fp>(F)) {}
+
+ scope_exit(scope_exit &&Rhs)
+ : ExitFunction(std::move(Rhs.ExitFunction)), Engaged(Rhs.Engaged) {
+ Rhs.release();
+ }
+ scope_exit(const scope_exit &) = delete;
+ scope_exit &operator=(scope_exit &&) = delete;
+ scope_exit &operator=(const scope_exit &) = delete;
+
+ void release() { Engaged = false; }
+
+ ~scope_exit() {
+ if (Engaged)
+ ExitFunction();
+ }
+};
+
+} // end namespace detail
+
+// Keeps the callable object that is passed in, and execute it at the
+// destruction of the returned object (usually at the scope exit where the
+// returned object is kept).
+//
+// Interface is specified by p0052r2.
+template <typename Callable>
+ detail::scope_exit<typename std::decay<Callable>::type>
+make_scope_exit(Callable &&F) {
+ return detail::scope_exit<typename std::decay<Callable>::type>(
+ std::forward<Callable>(F));
+}
+
+} // end namespace lsp
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/StreamMessageProducer.cpp b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/StreamMessageProducer.cpp
new file mode 100644
index 0000000000..c9df407980
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/StreamMessageProducer.cpp
@@ -0,0 +1,191 @@
+
+#include "StreamMessageProducer.h"
+#include <cassert>
+
+#include "stream.h"
+
+
+bool StartsWith(std::string value, std::string start);
+bool StartsWith(std::string value, std::string start) {
+ if (start.size() > value.size())
+ return false;
+ return std::equal(start.begin(), start.end(), value.begin());
+}
+
+using namespace std;
+namespace
+{
+ string JSONRPC_VERSION = "2.0";
+ string CONTENT_LENGTH_HEADER = "Content-Length";
+ string CONTENT_TYPE_HEADER = "Content-Type";
+ string JSON_MIME_TYPE = "application/json";
+ string CRLF = "\r\n";
+
+}
+
+ void StreamMessageProducer::parseHeader(std::string& line, StreamMessageProducer::Headers& headers)
+ {
+ int sepIndex = line.find(':');
+ if (sepIndex >= 0) {
+ auto key = line.substr(0, sepIndex);
+ if(key == CONTENT_LENGTH_HEADER)
+ {
+ headers.contentLength = atoi(line.substr(sepIndex + 1).data());
+ }
+ else if(key == CONTENT_TYPE_HEADER)
+ {
+ int charsetIndex = line.find("charset=");
+ if (charsetIndex >= 0)
+ headers.charset = line.substr(charsetIndex + 8);
+ }
+ }
+ }
+
+
+void StreamMessageProducer::listen(MessageConsumer callBack)
+{
+ if(!input)
+ return;
+
+ keepRunning = true;
+ bool newLine = false;
+ Headers headers;
+ string headerBuilder ;
+ string debugBuilder ;
+ // Read the content length. It is terminated by the "\r\n" sequence.
+ while (keepRunning)
+ {
+ if(input->bad())
+ {
+ std::string info = "Input stream is bad.";
+ auto what = input->what();
+ if (what.size())
+ {
+ info += "Reason:";
+ info += input->what();
+ }
+ MessageIssue issue(info, lsp::Log::Level::SEVERE);
+ issueHandler.handle(std::move(issue));
+ return;
+ }
+ if(input->fail())
+ {
+ std::string info = "Input fail.";
+ auto what = input->what();
+ if(what.size())
+ {
+ info += "Reason:";
+ info += input->what();
+ }
+ MessageIssue issue(info, lsp::Log::Level::WARNING);
+ issueHandler.handle(std::move(issue));
+ if(input->need_to_clear_the_state())
+ input->clear();
+ else
+ {
+ return;
+ }
+ }
+ int c = input->get();
+ if (c == EOF) {
+ // End of input stream has been reached
+ keepRunning = false;
+ }
+ else
+ {
+
+ debugBuilder.push_back((char)c);
+ if (c == '\n')
+ {
+ if (newLine) {
+ // Two consecutive newlines have been read, which signals the start of the message content
+ if (headers.contentLength <= 0)
+ {
+ string info = "Unexpected token:" + debugBuilder;
+ info = +" (expected Content-Length: sequence);";
+ MessageIssue issue(info, lsp::Log::Level::WARNING);
+ issueHandler.handle(std::move(issue));
+ }
+ else {
+ bool result = handleMessage(headers,callBack);
+ if (!result)
+ keepRunning = false;
+ newLine = false;
+ }
+ headers.clear();
+ debugBuilder.clear();
+ }
+ else if (!headerBuilder.empty()) {
+ // A single newline ends a header line
+ parseHeader(headerBuilder, headers);
+ headerBuilder.clear();
+ }
+ newLine = true;
+ }
+ else if (c != '\r') {
+ // Add the input to the current header line
+
+ headerBuilder.push_back((char)c);
+ newLine = false;
+ }
+ }
+ }
+
+}
+
+void StreamMessageProducer::bind(std::shared_ptr<lsp::istream>_in)
+{
+ input = _in;
+}
+
+bool StreamMessageProducer::handleMessage(Headers& headers ,MessageConsumer callBack)
+{
+ // Read content.
+ auto content_length = headers.contentLength;
+ std::string content(content_length,0);
+ auto data = &content[0];
+ input->read(data, content_length);
+ if (input->bad())
+ {
+ std::string info = "Input stream is bad.";
+ auto what = input->what();
+ if (!what.empty())
+ {
+ info += "Reason:";
+ info += input->what();
+ }
+ MessageIssue issue(info, lsp::Log::Level::SEVERE);
+ issueHandler.handle(std::move(issue));
+ return false;
+ }
+
+ if (input->eof())
+ {
+ MessageIssue issue("No more input when reading content body", lsp::Log::Level::INFO);
+ issueHandler.handle(std::move(issue));
+ return false;
+ }
+ if (input->fail())
+ {
+ std::string info = "Input fail.";
+ auto what = input->what();
+ if (!what.empty())
+ {
+ info += "Reason:";
+ info += input->what();
+ }
+ MessageIssue issue(info, lsp::Log::Level::WARNING);
+ issueHandler.handle(std::move(issue));
+ if (input->need_to_clear_the_state())
+ input->clear();
+ else
+ {
+ return false;
+ }
+ }
+
+ callBack(std::move(content));
+
+ return true;
+}
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/StreamMessageProducer.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/StreamMessageProducer.h
new file mode 100644
index 0000000000..439a9f1b0e
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/StreamMessageProducer.h
@@ -0,0 +1,48 @@
+#pragma once
+#include <string>
+#include <functional>
+#include "MessageProducer.h"
+#include <iostream>
+#include <memory>
+#include "MessageIssue.h"
+
+namespace lsp {
+ class istream;
+}
+
+class StreamMessageProducer : public MessageProducer
+{
+public:
+ struct Headers
+ {
+ int contentLength = -1;
+ std::string charset;
+ void clear()
+ {
+ contentLength = -1;
+ charset.clear();
+ }
+ };
+ bool handleMessage(Headers& headers, MessageConsumer callBack);
+ StreamMessageProducer(
+ MessageIssueHandler& message_issue_handler, std::shared_ptr < lsp::istream> _input)
+ : issueHandler(message_issue_handler),
+ input(_input)
+ {
+ }
+ StreamMessageProducer(
+ MessageIssueHandler& message_issue_handler)
+ : issueHandler(message_issue_handler)
+ {
+ }
+
+ bool keepRunning = false;
+ void listen(MessageConsumer) override;
+ void bind(std::shared_ptr < lsp::istream>);
+ void parseHeader(std::string& line, Headers& headers);
+private:
+ MessageIssueHandler& issueHandler;
+ std::shared_ptr < lsp::istream> input;
+
+
+};
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/TcpServer.cpp b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/TcpServer.cpp
new file mode 100644
index 0000000000..9188356473
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/TcpServer.cpp
@@ -0,0 +1,299 @@
+//
+// server.cpp
+
+#include "TcpServer.h"
+#include <signal.h>
+#include <utility>
+#include <boost/bind/bind.hpp>
+
+#include "MessageIssue.h"
+#include "stream.h"
+
+
+namespace lsp {
+ struct tcp_connect_session;
+
+
+ class tcp_stream_wrapper :public istream, public ostream
+ {
+ public:
+ tcp_stream_wrapper(tcp_connect_session& _w);
+
+ tcp_connect_session& session;
+ std::atomic<bool> quit{};
+ std::shared_ptr < MultiQueueWaiter> request_waiter;
+ ThreadedQueue< char > on_request;
+ std::string error_message;
+
+
+ bool fail() override
+ {
+ return bad();
+ }
+
+
+
+ bool eof() override
+ {
+ return bad();
+ }
+ bool good() override
+ {
+ return !bad();
+ }
+ tcp_stream_wrapper& read(char* str, std::streamsize count)
+ override
+ {
+ auto some = on_request.TryDequeueSome(static_cast<size_t>( count ));
+ for (size_t i = 0; i < some.size(); ++i)
+ {
+ str[i] = some[i];
+ }
+ for (std::streamsize i = 0; i < count; ++i)
+ {
+ str[i] = static_cast<char>(get());
+ }
+
+ return *this;
+ }
+ int get() override
+ {
+ return on_request.Dequeue();
+ }
+
+ bool bad() override;
+
+ tcp_stream_wrapper& write(const std::string& c) override;
+
+ tcp_stream_wrapper& write(std::streamsize _s) override;
+
+ tcp_stream_wrapper& flush() override
+ {
+ return *this;
+ }
+ void reset_state()
+ {
+ return;
+ }
+
+ void clear() override
+ {
+
+ }
+
+ std::string what() override;
+ bool need_to_clear_the_state() override
+ {
+ return false;
+ }
+ };
+ struct tcp_connect_session:std::enable_shared_from_this<tcp_connect_session>
+ {
+ /// Buffer for incoming data.
+ std::array<unsigned char, 8192> buffer_;
+ boost::asio::ip::tcp::socket socket_;
+ /// Strand to ensure the connection's handlers are not called concurrently.
+ boost::asio::io_context::strand strand_;
+ std::shared_ptr<tcp_stream_wrapper> proxy_;
+ explicit tcp_connect_session(boost::asio::io_context& io_context, boost::asio::ip::tcp::socket&& _socket)
+ : socket_(std::move(_socket)), strand_(io_context), proxy_(new tcp_stream_wrapper(*this))
+ {
+ do_read();
+ }
+ void do_write(const std::string& data)
+ {
+ socket_.async_write_some(boost::asio::buffer(data.data(), data.size()),
+ boost::asio::bind_executor(strand_,[this](boost::system::error_code ec, std::size_t n)
+ {
+ if (!ec)
+ {
+ return;
+ }
+ proxy_->error_message = ec.message();
+
+ }));
+ }
+ void do_read()
+ {
+ socket_.async_read_some(boost::asio::buffer(buffer_),
+ boost::asio::bind_executor(strand_,
+ [this](boost::system::error_code ec, size_t bytes_transferred)
+ {
+ if (!ec)
+ {
+ std::vector<char> elements(buffer_.data(), buffer_.data() + bytes_transferred);
+ proxy_->on_request.EnqueueAll(std::move(elements), false);
+ do_read();
+ return;
+ }
+ proxy_->error_message = ec.message();
+
+ }));
+ }
+ };
+
+ tcp_stream_wrapper::tcp_stream_wrapper(tcp_connect_session& _w): session(_w)
+ {
+ }
+
+ bool tcp_stream_wrapper::bad()
+ {
+ return !session.socket_.is_open();
+ }
+
+ tcp_stream_wrapper& tcp_stream_wrapper::write(const std::string& c)
+ {
+ session.do_write(c);
+ return *this;
+ }
+
+ tcp_stream_wrapper& tcp_stream_wrapper::write(std::streamsize _s)
+ {
+ session.do_write(std::to_string(_s));
+ return *this;
+ }
+
+ std::string tcp_stream_wrapper::what()
+ {
+ if (error_message.size())
+ return error_message;
+
+ if(! session.socket_.is_open())
+ {
+ return "Socket is not open.";
+ }
+ return {};
+ }
+
+ struct TcpServer::Data
+ {
+ Data(
+ lsp::Log& log, uint32_t _max_workers) :
+ acceptor_(io_context_), _log(log)
+ {
+ }
+
+ ~Data()
+ {
+
+ }
+ /// The io_context used to perform asynchronous operations.
+ boost::asio::io_context io_context_;
+
+ std::shared_ptr<boost::asio::io_service::work> work;
+
+ std::shared_ptr<tcp_connect_session> _connect_session;
+ /// Acceptor used to listen for incoming connections.
+ boost::asio::ip::tcp::acceptor acceptor_;
+
+ lsp::Log& _log;
+
+ };
+
+ TcpServer::~TcpServer()
+ {
+ delete d_ptr;
+ }
+
+ TcpServer::TcpServer(const std::string& address, const std::string& port,
+ std::shared_ptr < MessageJsonHandler> json_handler,
+ std::shared_ptr < Endpoint> localEndPoint, lsp::Log& log, uint32_t _max_workers)
+ : point(json_handler, localEndPoint, log, _max_workers),d_ptr(new Data( log, _max_workers))
+
+ {
+
+ d_ptr->work = std::make_shared<boost::asio::io_service::work>(d_ptr->io_context_);
+
+ // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
+ boost::asio::ip::tcp::resolver resolver(d_ptr->io_context_);
+ boost::asio::ip::tcp::endpoint endpoint =
+ *resolver.resolve(address, port).begin();
+ d_ptr->acceptor_.open(endpoint.protocol());
+ d_ptr->acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
+ try
+ {
+ d_ptr->acceptor_.bind(endpoint);
+ }
+ catch (boost::system::system_error & e)
+ {
+ std::string temp = "Socket Server bind failed.";
+ d_ptr->_log.log(lsp::Log::Level::INFO , temp + e.what());
+ return;
+ }
+ d_ptr->acceptor_.listen();
+
+ do_accept();
+ std::string desc = "Socket TcpServer " + address + " " + port + " start.";
+ d_ptr->_log.log(lsp::Log::Level::INFO, desc);
+ }
+
+ void TcpServer::run()
+ {
+ // The io_context::run() call will block until all asynchronous operations
+ // have finished. While the TcpServer is running, there is always at least one
+ // asynchronous operation outstanding: the asynchronous accept call waiting
+ // for new incoming connections.
+ d_ptr->io_context_.run();
+
+ }
+
+ void TcpServer::stop()
+ {
+ try
+ {
+ if(d_ptr->work)
+ d_ptr->work.reset();
+
+ do_stop();
+ }
+ catch (...)
+ {
+ }
+ }
+
+ void TcpServer::do_accept()
+ {
+ d_ptr->acceptor_.async_accept(
+ [this](boost::system::error_code ec, boost::asio::ip::tcp::socket socket)
+ {
+ // Check whether the TcpServer was stopped by a signal before this
+ // completion handler had a chance to run.
+ if (!d_ptr->acceptor_.is_open())
+ {
+ return;
+ }
+
+ if (!ec)
+ {
+ if(d_ptr->_connect_session)
+ {
+ if(d_ptr->_connect_session->socket_.is_open())
+ {
+ std::string desc = "Disconnect previous client " + d_ptr->_connect_session->socket_.local_endpoint().address().to_string();
+ d_ptr->_log.log(lsp::Log::Level::INFO, desc);
+ d_ptr->_connect_session->socket_.close();
+ }
+
+ point.Stop();
+ }
+ auto local_point = socket.local_endpoint();
+
+ std::string desc = ("New client " + local_point.address().to_string() + " connect.");
+ d_ptr->_log.log(lsp::Log::Level::INFO, desc);
+ d_ptr->_connect_session = std::make_shared<tcp_connect_session>(d_ptr->io_context_,std::move(socket));
+
+ point.startProcessingMessages(d_ptr->_connect_session->proxy_, d_ptr->_connect_session->proxy_);
+ do_accept();
+ }
+ });
+ }
+
+ void TcpServer::do_stop()
+ {
+ d_ptr->acceptor_.close();
+
+ point.Stop();
+
+ }
+
+ } // namespace
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/TcpServer.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/TcpServer.h
new file mode 100644
index 0000000000..e533acf056
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/TcpServer.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <boost/asio.hpp>
+#include <string>
+#include "RemoteEndPoint.h"
+
+namespace lsp {
+ class Log;
+}
+namespace lsp
+{
+ /// The top-level class of the HTTP server.
+ class TcpServer
+ {
+ public:
+ TcpServer(const TcpServer&) = delete;
+ TcpServer& operator=(const TcpServer&) = delete;
+ ~TcpServer();
+ /// Construct the server to listen on the specified TCP address and port, and
+ /// serve up files from the given directory.
+ explicit TcpServer(const std::string& address, const std::string& port,
+ std::shared_ptr < MessageJsonHandler> json_handler,
+ std::shared_ptr < Endpoint> localEndPoint, lsp::Log& ,uint32_t _max_workers = 2);
+
+ /// Run the server's io_context loop.
+ void run();
+ void stop();
+
+ RemoteEndPoint point;
+ private:
+ struct Data;
+ /// Perform an asynchronous accept operation.
+ void do_accept();
+
+ /// Wait for a request to stop the server.
+ void do_stop();
+ Data* d_ptr = nullptr;
+ };
+} // namespace
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/WebSocketServer.cpp b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/WebSocketServer.cpp
new file mode 100644
index 0000000000..2cb83099c3
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/WebSocketServer.cpp
@@ -0,0 +1,341 @@
+#include "MessageIssue.h"
+#include "WebSocketServer.h"
+#include <iostream>
+#include <signal.h>
+#include <utility>
+#include "stream.h"
+#include <boost/beast/core.hpp>
+#include <boost/beast/websocket.hpp>
+#include <boost/asio/dispatch.hpp>
+namespace beast = boost::beast; // from <boost/beast.hpp>
+namespace http = beast::http; // from <boost/beast/http.hpp>
+namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
+namespace net = boost::asio; // from <boost/asio.hpp>
+using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
+namespace lsp {
+
+ // Echoes back all received WebSocket messages
+ class server_session : public std::enable_shared_from_this<server_session>
+ {
+ websocket::stream<beast::tcp_stream> ws_;
+
+ beast::flat_buffer buffer_;
+ std::string user_agent_;
+ public:
+ std::shared_ptr<websocket_stream_wrapper> proxy_;
+ // Take ownership of the socket
+ explicit
+ server_session(tcp::socket&& socket,const std::string& user_agent)
+ : ws_(std::move(socket)),user_agent_(user_agent)
+ {
+ proxy_ = std::make_shared<websocket_stream_wrapper>(ws_);
+ }
+
+ // Get on the correct executor
+ void
+ run()
+ {
+ // We need to be executing within a strand to perform async operations
+ // on the I/O objects in this server_session. Although not strictly necessary
+ // for single-threaded contexts, this example code is written to be
+ // thread-safe by default.
+ net::dispatch(ws_.get_executor(),
+ beast::bind_front_handler(
+ &server_session::on_run,
+ shared_from_this()));
+ }
+
+ // Start the asynchronous operation
+ void
+ on_run()
+ {
+ // Set suggested timeout settings for the websocket
+ ws_.set_option(
+ websocket::stream_base::timeout::suggested(
+ beast::role_type::server));
+
+ // Set a decorator to change the Server of the handshake
+ ws_.set_option(websocket::stream_base::decorator(
+ [=](websocket::response_type& res)
+ {
+ res.set(http::field::server, user_agent_.c_str());
+ }));
+ // Accept the websocket handshake
+ ws_.async_accept(
+ beast::bind_front_handler(
+ &server_session::on_accept,
+ shared_from_this()));
+ }
+
+ void
+ on_accept(beast::error_code ec)
+ {
+ if (ec)
+ return ;
+
+ // Read a message
+ // Read a message into our buffer
+ ws_.async_read(
+ buffer_,
+ beast::bind_front_handler(
+ &server_session::on_read,
+ shared_from_this()));
+ }
+
+
+
+ void
+ on_read(
+ beast::error_code ec,
+ std::size_t bytes_transferred)
+ {
+
+ if(!ec)
+ {
+ char* data = reinterpret_cast<char*>(buffer_.data().data());
+ std::vector<char> elements(data, data + bytes_transferred);
+
+ buffer_.clear();
+ proxy_->on_request.EnqueueAll(std::move(elements), false);
+
+ // Read a message into our buffer
+ ws_.async_read(
+ buffer_,
+ beast::bind_front_handler(
+ &server_session::on_read,
+ shared_from_this()));
+ return;
+ }
+ if (ec){
+ proxy_->error_message = ec.message();
+ }
+ }
+
+
+
+ void close()
+ {
+ if(ws_.is_open())
+ {
+ boost::system::error_code ec;
+ ws_.close(websocket::close_code::normal, ec);
+ }
+
+ }
+ };
+
+ //------------------------------------------------------------------------------
+
+ struct WebSocketServer::Data
+ {
+ Data(const std::string& user_agent, lsp::Log& log) :
+ acceptor_(io_context_), user_agent_(user_agent), _log(log)
+
+ {
+ }
+
+ ~Data()
+ {
+
+ }
+ /// The io_context used to perform asynchronous operations.
+ boost::asio::io_context io_context_;
+
+ std::shared_ptr<boost::asio::io_service::work> work;
+
+ /// Acceptor used to listen for incoming connections.
+ boost::asio::ip::tcp::acceptor acceptor_;
+
+ std::shared_ptr < server_session> _server_session;
+
+ std::string user_agent_;
+ lsp::Log& _log;
+
+ };
+
+ websocket_stream_wrapper::websocket_stream_wrapper(boost::beast::websocket::stream<boost::beast::tcp_stream>& _w):
+ ws_(_w), request_waiter(new MultiQueueWaiter()),
+ on_request(request_waiter)
+ {
+ }
+
+ bool websocket_stream_wrapper::fail()
+ {
+ return bad();
+ }
+
+ bool websocket_stream_wrapper::eof()
+ {
+ return bad();
+ }
+
+ bool websocket_stream_wrapper::good()
+ {
+ return !bad();
+ }
+
+ websocket_stream_wrapper& websocket_stream_wrapper::read(char* str, std::streamsize count)
+ {
+ auto some = on_request.TryDequeueSome(static_cast<size_t>(count));
+
+ for (size_t i = 0; i < some.size(); ++i)
+ {
+ str[i] = some[i];
+ }
+ for (std::streamsize i = 0; i < count; ++i)
+ {
+ str[i] = static_cast<char>(get());
+ }
+ return *this;
+ }
+
+ int websocket_stream_wrapper::get()
+ {
+ return on_request.Dequeue();
+ }
+
+ bool websocket_stream_wrapper::bad()
+ {
+ return !ws_.next_layer().socket().is_open();
+ }
+
+ websocket_stream_wrapper& websocket_stream_wrapper::write(const std::string& c)
+ {
+ ws_.write(boost::asio::buffer(std::string(c)));
+ return *this;
+ }
+
+
+ websocket_stream_wrapper& websocket_stream_wrapper::write(std::streamsize _s)
+ {
+ std::ostringstream temp;
+ temp << _s;
+ ws_.write(boost::asio::buffer(temp.str()));
+ return *this;
+ }
+
+ websocket_stream_wrapper& websocket_stream_wrapper::flush()
+ {
+ return *this;
+ }
+
+ void websocket_stream_wrapper::clear()
+ {
+ }
+
+ std::string websocket_stream_wrapper::what()
+ {
+ if (!error_message.empty())
+ return error_message;
+
+ if (!ws_.next_layer().socket().is_open())
+ {
+ return "Socket is not open.";
+ }
+ return {};
+ }
+
+ WebSocketServer::~WebSocketServer()
+ {
+ delete d_ptr;
+ }
+
+ WebSocketServer::WebSocketServer(const std::string& user_agent, const std::string& address, const std::string& port,
+ std::shared_ptr < MessageJsonHandler> json_handler,
+ std::shared_ptr < Endpoint> localEndPoint, lsp::Log& log, uint32_t _max_workers)
+ : point(json_handler,localEndPoint,log, _max_workers),d_ptr(new Data(user_agent,log))
+
+ {
+
+ d_ptr->work = std::make_shared<boost::asio::io_service::work>(d_ptr->io_context_);
+
+ // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
+ boost::asio::ip::tcp::resolver resolver(d_ptr->io_context_);
+ boost::asio::ip::tcp::endpoint endpoint =
+ *resolver.resolve(address, port).begin();
+ d_ptr->acceptor_.open(endpoint.protocol());
+ d_ptr->acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
+ try
+ {
+ d_ptr->acceptor_.bind(endpoint);
+ }
+ catch (boost::system::system_error & e)
+ {
+ std::string temp = "Socket Server blid faild.";
+ d_ptr->_log.log(lsp::Log::Level::INFO , temp + e.what());
+ return;
+ }
+ d_ptr->acceptor_.listen();
+
+ do_accept();
+ std::string desc = "Socket WebSocketServer " + address + " " + port + " start.";
+ d_ptr->_log.log(lsp::Log::Level::INFO, desc);
+ }
+
+ void WebSocketServer::run()
+ {
+ // The io_context::run() call will block until all asynchronous operations
+ // have finished. While the WebSocketServer is running, there is always at least one
+ // asynchronous operation outstanding: the asynchronous accept call waiting
+ // for new incoming connections.
+ d_ptr->io_context_.run();
+
+ }
+
+ void WebSocketServer::stop()
+ {
+ try
+ {
+ if(d_ptr->work)
+ d_ptr->work.reset();
+
+ do_stop();
+ }
+ catch (...)
+ {
+ }
+ }
+
+ void WebSocketServer::do_accept()
+ {
+ d_ptr->acceptor_.async_accept(
+ [this](boost::system::error_code ec, boost::asio::ip::tcp::socket socket)
+ {
+ // Check whether the WebSocketServer was stopped by a signal before this
+ // completion handler had a chance to run.
+ if (!d_ptr->acceptor_.is_open())
+ {
+ return;
+ }
+ if (!ec)
+ {
+ if(d_ptr->_server_session)
+ {
+ try
+ {
+ d_ptr->_server_session->close();
+ point.Stop();
+ }
+ catch (...)
+ {
+ }
+ }
+ d_ptr->_server_session = std::make_shared<server_session>(std::move(socket), d_ptr->user_agent_);
+ d_ptr->_server_session->run();
+
+ point.startProcessingMessages(d_ptr->_server_session->proxy_, d_ptr->_server_session->proxy_);
+ do_accept();
+ }
+
+ });
+ }
+
+ void WebSocketServer::do_stop()
+ {
+ d_ptr->acceptor_.close();
+
+ point.Stop();
+
+ }
+
+ } // namespace
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/WebSocketServer.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/WebSocketServer.h
new file mode 100644
index 0000000000..5206525ceb
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/WebSocketServer.h
@@ -0,0 +1,87 @@
+#pragma once
+
+#include <boost/asio.hpp>
+#include <string>
+#include <boost/beast/core/tcp_stream.hpp>
+#include <boost/beast/websocket/stream.hpp>
+
+
+#include "RemoteEndPoint.h"
+#include "stream.h"
+#include "threaded_queue.h"
+
+namespace lsp {
+ class Log;
+}
+
+
+namespace lsp
+{
+
+
+
+ class websocket_stream_wrapper :public istream, public ostream
+ {
+ public:
+
+ websocket_stream_wrapper(boost::beast::websocket::stream<boost::beast::tcp_stream>& _w);
+
+ boost::beast::websocket::stream<boost::beast::tcp_stream>& ws_;
+ std::atomic<bool> quit{};
+ std::shared_ptr < MultiQueueWaiter> request_waiter;
+ ThreadedQueue< char > on_request;
+ std::string error_message;
+ bool fail() override;
+
+ bool eof() override;
+
+ bool good() override;
+
+ websocket_stream_wrapper& read(char* str, std::streamsize count) override;
+
+ int get() override;
+
+ bool bad() override;
+
+ websocket_stream_wrapper& write(const std::string& c) override;
+
+ websocket_stream_wrapper& write(std::streamsize _s) override;
+
+ websocket_stream_wrapper& flush() override;
+
+ void clear() override;
+
+ std::string what() override;
+ };
+
+ /// The top-level class of the HTTP server.
+ class WebSocketServer
+ {
+ public:
+ WebSocketServer(const WebSocketServer&) = delete;
+ WebSocketServer& operator=(const WebSocketServer&) = delete;
+ ~WebSocketServer();
+ /// Construct the server to listen on the specified TCP address and port, and
+ /// serve up files from the given directory.
+ explicit WebSocketServer(const std::string& user_agent, const std::string& address, const std::string& port,
+ std::shared_ptr < MessageJsonHandler> json_handler,
+ std::shared_ptr < Endpoint> localEndPoint, lsp::Log& ,uint32_t _max_workers = 2);
+
+ /// Run the server's io_context loop.
+ void run();
+ void stop();
+
+ RemoteEndPoint point;
+ private:
+ struct Data;
+ /// Perform an asynchronous accept operation.
+ void do_accept();
+
+ /// Wait for a request to stop the server.
+ void do_stop();
+ Data* d_ptr = nullptr;
+
+
+ };
+
+ } // namespace
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/json.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/json.h
new file mode 100644
index 0000000000..98ee91b544
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/json.h
@@ -0,0 +1,81 @@
+#pragma once
+
+#include "serializer.h"
+
+#include <rapidjson/document.h>
+#include <rapidjson/prettywriter.h>
+
+class JsonReader : public Reader {
+
+ std::vector<const char*> path_;
+
+ public:
+ rapidjson::GenericValue<rapidjson::UTF8<>>* m_;
+ JsonReader(rapidjson::GenericValue<rapidjson::UTF8<>>* m) : m_(m) {}
+ SerializeFormat Format() const override { return SerializeFormat::Json; }
+
+ bool IsBool() override { return m_->IsBool(); }
+ bool IsNull() override { return m_->IsNull(); }
+ bool IsArray() override { return m_->IsArray(); }
+ bool IsInt() override { return m_->IsInt(); }
+ bool IsInt64() override { return m_->IsInt64(); }
+ bool IsUint64() override { return m_->IsUint64(); }
+ bool IsDouble() override { return m_->IsDouble(); }
+ bool IsNumber() override { return m_->IsNumber(); }
+ bool IsString() override { return m_->IsString(); }
+
+ void GetNull() override {}
+ bool GetBool() override { return m_->GetBool(); }
+ int GetInt() override { return m_->GetInt(); }
+ uint32_t GetUint32() override { return uint32_t(m_->GetUint64()); }
+ int64_t GetInt64() override { return m_->GetInt64(); }
+ uint64_t GetUint64() override { return m_->GetUint64(); }
+ double GetDouble() override { return m_->GetDouble(); }
+ std::string GetString() override { return m_->GetString(); }
+
+ bool HasMember(const char* x) override
+ {
+ if (m_->IsObject())
+ return m_->HasMember(x);
+ else
+ return false;
+ }
+ std::unique_ptr<Reader> operator[](const char* x) override {
+ auto& sub = (*m_)[x];
+ return std::unique_ptr<JsonReader>(new JsonReader(&sub));
+ }
+
+ std::string ToString() const override;
+
+ void IterMap(std::function<void(const char*, Reader&)> fn) override;
+
+ void IterArray(std::function<void(Reader&)> fn) override;
+
+ void DoMember(const char* name, std::function<void(Reader&)> fn) override;
+
+ std::string GetPath() const;
+};
+
+class JsonWriter : public Writer {
+
+ public:
+ rapidjson::Writer<rapidjson::StringBuffer>* m_;
+
+ JsonWriter(rapidjson::Writer<rapidjson::StringBuffer>* m) : m_(m) {}
+ SerializeFormat Format() const override { return SerializeFormat::Json; }
+
+ void Null() override { m_->Null(); }
+ void Bool(bool x) override { m_->Bool(x); }
+ void Int(int x) override { m_->Int(x); }
+ void Uint32(uint32_t x) override { m_->Uint64(x); }
+ void Int64(int64_t x) override { m_->Int64(x); }
+ void Uint64(uint64_t x) override { m_->Uint64(x); }
+ void Double(double x) override { m_->Double(x); }
+ void String(const char* x) override { m_->String(x); }
+ void String(const char* x, size_t len) override { m_->String(x, len); }
+ void StartArray(size_t) override { m_->StartArray(); }
+ void EndArray() override { m_->EndArray(); }
+ void StartObject() override { m_->StartObject(); }
+ void EndObject() override { m_->EndObject(); }
+ void Key(const char* name) override { m_->Key(name); }
+};
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/lsRequestId.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/lsRequestId.h
new file mode 100644
index 0000000000..87e94669ab
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/lsRequestId.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+
+struct lsRequestId {
+ // The client can send the request id as an int or a string. We should output
+ // the same format we received.
+ enum Type { kNone, kInt, kString };
+ Type type = kNone;
+
+ int value = -1;
+ std::string k_string;
+ bool has_value() const { return type != kNone; }
+ void swap(lsRequestId& arg) noexcept
+ {
+ std::swap(arg, *this);
+ }
+ void set(int v)
+ {
+ value = v;
+ type = kInt;
+ }
+ void set(const std::string& v)
+ {
+ k_string = v;
+ type = kString;
+ }
+ bool operator==(const lsRequestId& rhs) const
+ {
+ if (type != rhs.type) return false;
+ if (type == kInt)
+ return value == rhs.value;
+ return k_string == rhs.k_string;
+ }
+ bool operator!=(const lsRequestId& rhs) const
+ {
+ return !operator==(rhs);
+ }
+ bool operator<(const lsRequestId& rhs) const
+ {
+ if (type != rhs.type) return false;
+ if (type == kInt)
+ return value < rhs.value;
+ return k_string < rhs.k_string;
+ }
+};
+void Reflect(Reader& visitor, lsRequestId& value);
+void Reflect(Writer& visitor, lsRequestId& value);
+
+// Debug method to convert an id to a string.
+std::string ToString(const lsRequestId& id); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/lsResponseMessage.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/lsResponseMessage.h
new file mode 100644
index 0000000000..ba94167cf8
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/lsResponseMessage.h
@@ -0,0 +1,71 @@
+#pragma once
+#include "serializer.h"
+#include "lsRequestId.h"
+#include "LibLsp/JsonRpc/message.h"
+#include "LibLsp/lsp/method_type.h"
+
+
+struct ResponseInMessage :public LspMessage {
+
+ lsRequestId id;
+ std::string m_methodType;
+
+ virtual MethodType GetMethodType() const override
+ {
+ return m_methodType.data();
+ };
+ virtual void SetMethodType(MethodType _type) override
+ {
+ m_methodType = _type;
+ };
+
+ Kind GetKid() override
+ {
+ return RESPONCE_MESSAGE;
+ }
+ virtual bool IsErrorType()
+ {
+ return false;
+ }
+};
+template <class TDerived >
+struct BaseResponseMessage : ResponseInMessage {
+
+ void ReflectWriter(Writer& writer) override {
+ Reflect(writer, static_cast<TDerived&>(*this));
+ }
+ static std::unique_ptr<LspMessage> ReflectReader(Reader& visitor) {
+
+ TDerived* temp = new TDerived();
+ std::unique_ptr<TDerived> message = std::unique_ptr<TDerived>(temp);
+ // Reflect may throw and *message will be partially deserialized.
+ Reflect(visitor, static_cast<TDerived&>(*temp));
+ return message;
+ }
+
+};
+
+
+template <class T, class TDerived >
+struct ResponseMessage : BaseResponseMessage<TDerived> {
+ T result;
+ void swap(ResponseMessage<T, TDerived>& arg) noexcept
+ {
+ std::swap(result, arg.result);
+ this->id.swap(arg.id);
+ this->m_methodType.swap(arg.m_methodType);
+ }
+};
+
+template <class T, class TDerived >
+struct ResponseError : BaseResponseMessage<TDerived> {
+ T error;
+ bool IsErrorType() override { return true; }
+ void swap(ResponseError<T, TDerived>& arg) noexcept
+ {
+
+ this->id.swap(arg.id);
+ this->m_methodType.swap(arg.m_methodType);
+ std::swap(error, arg.error);
+ }
+};
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/message.cpp b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/message.cpp
new file mode 100644
index 0000000000..e84455402c
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/message.cpp
@@ -0,0 +1,88 @@
+#include "message.h"
+#include <rapidjson/stringbuffer.h>
+#include <rapidjson/writer.h>
+#include "serializer.h"
+#include "lsRequestId.h"
+#include "RequestInMessage.h"
+#include "Condition.h"
+#include "json.h"
+
+void LspMessage::Write(std::ostream& out) {
+ rapidjson::StringBuffer output;
+ rapidjson::Writer<rapidjson::StringBuffer> writer(output);
+ JsonWriter json_writer{ &writer };
+ ReflectWriter(json_writer);
+
+ const auto value = std::string("Content-Length: ") + std::to_string(output.GetSize()) + "\r\n\r\n" + output.GetString();
+ out << value;
+ out.flush();
+}
+
+std::string LspMessage::ToJson() {
+ rapidjson::StringBuffer output;
+ rapidjson::Writer<rapidjson::StringBuffer> writer(output);
+ JsonWriter json_writer{ &writer };
+ this->ReflectWriter(json_writer);
+ return output.GetString();
+}
+
+void Reflect(Reader& visitor, lsRequestId& value) {
+ if (visitor.IsInt()) {
+ value.type = lsRequestId::kInt;
+ value.value = visitor.GetInt();
+ }
+ else if (visitor.IsInt64()) {
+ value.type = lsRequestId::kInt;
+ // `lsRequestId.value` is an `int`, so we're forced to truncate.
+ value.value = static_cast<int>(visitor.GetInt64());
+ }
+ else if (visitor.IsString()) {
+ value.type = lsRequestId::kString;
+ value.k_string = visitor.GetString();
+ value.value = atoi(value.k_string.c_str());
+
+ }
+ else {
+ value.type = lsRequestId::kNone;
+ value.value = -1;
+ }
+}
+
+void Reflect(Writer& visitor, lsRequestId& value) {
+ switch (value.type) {
+ case lsRequestId::kNone:
+ visitor.Null();
+ break;
+ case lsRequestId::kInt:
+ visitor.Int(value.value);
+ break;
+ case lsRequestId::kString:
+
+ if(value.k_string.empty())
+ {
+ std::string str = std::to_string(value.value);
+ visitor.String(str.c_str(), str.length());
+ }
+ else
+ {
+ visitor.String(value.k_string.c_str(), value.k_string.length());
+ }
+ break;
+ }
+}
+
+std::string ToString(const lsRequestId& id) {
+ if (id.type != lsRequestId::kNone)
+ {
+ if(id.type == lsRequestId::kString)
+ {
+ if (!id.k_string.empty())
+ return id.k_string;
+ }
+ return std::to_string(id.value);
+ }
+
+ return "";
+}
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/message.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/message.h
new file mode 100644
index 0000000000..6603f3fb3a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/message.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <atomic>
+#include <string>
+#include <iostream>
+#include <LibLsp/JsonRpc/serializer.h>
+#include "LibLsp/lsp/method_type.h"
+
+struct LspMessage
+{
+public:
+ std::string jsonrpc = "2.0";
+ virtual void ReflectWriter(Writer&) = 0;
+
+ // Send the message to the language client by writing it to stdout.
+ void Write(std::ostream& out);
+
+
+ virtual MethodType GetMethodType() const = 0;
+ virtual void SetMethodType(MethodType) = 0;
+
+ virtual ~LspMessage()=default;
+ enum Kind
+ {
+ REQUEST_MESSAGE,
+ RESPONCE_MESSAGE,
+ NOTIFICATION_MESSAGE
+ };
+
+ virtual Kind GetKid() = 0;
+ virtual std::string ToJson() ;
+
+};
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/optional.hpp b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/optional.hpp
new file mode 100644
index 0000000000..86e3b407c6
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/optional.hpp
@@ -0,0 +1,1846 @@
+//
+// Copyright (c) 2014-2021 Martin Moene
+//
+// https://github.com/martinmoene/optional-lite
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#pragma once
+
+#ifndef NONSTD_OPTIONAL_LITE_HPP
+#define NONSTD_OPTIONAL_LITE_HPP
+
+#define optional_lite_MAJOR 3
+#define optional_lite_MINOR 5
+#define optional_lite_PATCH 0
+
+#define optional_lite_VERSION optional_STRINGIFY(optional_lite_MAJOR) "." optional_STRINGIFY(optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH)
+
+#define optional_STRINGIFY( x ) optional_STRINGIFY_( x )
+#define optional_STRINGIFY_( x ) #x
+
+// optional-lite configuration:
+
+#define optional_OPTIONAL_DEFAULT 0
+#define optional_OPTIONAL_NONSTD 1
+#define optional_OPTIONAL_STD 2
+
+// tweak header support:
+
+#ifdef __has_include
+# if __has_include(<nonstd/optional.tweak.hpp>)
+# include <nonstd/optional.tweak.hpp>
+# endif
+#define optional_HAVE_TWEAK_HEADER 1
+#else
+#define optional_HAVE_TWEAK_HEADER 0
+//# pragma message("optional.hpp: Note: Tweak header not supported.")
+#endif
+
+// optional selection and configuration:
+
+#if !defined( optional_CONFIG_SELECT_OPTIONAL )
+# define optional_CONFIG_SELECT_OPTIONAL ( optional_HAVE_STD_OPTIONAL ? optional_OPTIONAL_STD : optional_OPTIONAL_NONSTD )
+#endif
+
+// Control presence of extensions:
+
+#ifndef optional_CONFIG_NO_EXTENSIONS
+#define optional_CONFIG_NO_EXTENSIONS 0
+#endif
+
+// Control presence of exception handling (try and auto discover):
+
+#ifndef optional_CONFIG_NO_EXCEPTIONS
+# if defined(_MSC_VER)
+# include <cstddef> // for _HAS_EXCEPTIONS
+# endif
+# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
+# define optional_CONFIG_NO_EXCEPTIONS 0
+# else
+# define optional_CONFIG_NO_EXCEPTIONS 1
+# endif
+#endif
+
+// C++ language version detection (C++20 is speculative):
+// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
+
+#ifndef optional_CPLUSPLUS
+# if defined(_MSVC_LANG ) && !defined(__clang__)
+# define optional_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
+# else
+# define optional_CPLUSPLUS __cplusplus
+# endif
+#endif
+
+#define optional_CPP98_OR_GREATER ( optional_CPLUSPLUS >= 199711L )
+#define optional_CPP11_OR_GREATER ( optional_CPLUSPLUS >= 201103L )
+#define optional_CPP11_OR_GREATER_ ( optional_CPLUSPLUS >= 201103L )
+#define optional_CPP14_OR_GREATER ( optional_CPLUSPLUS >= 201402L )
+#define optional_CPP17_OR_GREATER ( optional_CPLUSPLUS >= 201703L )
+#define optional_CPP20_OR_GREATER ( optional_CPLUSPLUS >= 202000L )
+
+// C++ language version (represent 98 as 3):
+
+#define optional_CPLUSPLUS_V ( optional_CPLUSPLUS / 100 - (optional_CPLUSPLUS > 200000 ? 2000 : 1994) )
+
+// Use C++17 std::optional if available and requested:
+
+#if optional_CPP17_OR_GREATER && defined(__has_include )
+# if __has_include( <optional> )
+# define optional_HAVE_STD_OPTIONAL 1
+# else
+# define optional_HAVE_STD_OPTIONAL 0
+# endif
+#else
+# define optional_HAVE_STD_OPTIONAL 0
+#endif
+
+#define optional_USES_STD_OPTIONAL ( (optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_STD) || ((optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_DEFAULT) && optional_HAVE_STD_OPTIONAL) )
+
+//
+// in_place: code duplicated in any-lite, expected-lite, optional-lite, value-ptr-lite, variant-lite:
+//
+
+#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
+#define nonstd_lite_HAVE_IN_PLACE_TYPES 1
+
+// C++17 std::in_place in <utility>:
+
+#if optional_CPP17_OR_GREATER
+
+#include <utility>
+
+namespace nonstd {
+
+using std::in_place;
+using std::in_place_type;
+using std::in_place_index;
+using std::in_place_t;
+using std::in_place_type_t;
+using std::in_place_index_t;
+
+#define nonstd_lite_in_place_t( T) std::in_place_t
+#define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T>
+#define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
+
+#define nonstd_lite_in_place( T) std::in_place_t{}
+#define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{}
+#define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{}
+
+} // namespace nonstd
+
+#else // optional_CPP17_OR_GREATER
+
+#include <cstddef>
+
+namespace nonstd {
+namespace detail {
+
+template< class T >
+struct in_place_type_tag {};
+
+template< std::size_t K >
+struct in_place_index_tag {};
+
+} // namespace detail
+
+struct in_place_t {};
+
+template< class T >
+inline in_place_t in_place( detail::in_place_type_tag<T> /*unused*/ = detail::in_place_type_tag<T>() )
+{
+ return in_place_t();
+}
+
+template< std::size_t K >
+inline in_place_t in_place( detail::in_place_index_tag<K> /*unused*/ = detail::in_place_index_tag<K>() )
+{
+ return in_place_t();
+}
+
+template< class T >
+inline in_place_t in_place_type( detail::in_place_type_tag<T> /*unused*/ = detail::in_place_type_tag<T>() )
+{
+ return in_place_t();
+}
+
+template< std::size_t K >
+inline in_place_t in_place_index( detail::in_place_index_tag<K> /*unused*/ = detail::in_place_index_tag<K>() )
+{
+ return in_place_t();
+}
+
+// mimic templated typedef:
+
+#define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
+#define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
+#define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
+
+#define nonstd_lite_in_place( T) nonstd::in_place_type<T>
+#define nonstd_lite_in_place_type( T) nonstd::in_place_type<T>
+#define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
+
+} // namespace nonstd
+
+#endif // optional_CPP17_OR_GREATER
+#endif // nonstd_lite_HAVE_IN_PLACE_TYPES
+
+//
+// Using std::optional:
+//
+
+#if optional_USES_STD_OPTIONAL
+
+#include <optional>
+
+namespace nonstd {
+
+ using std::optional;
+ using std::bad_optional_access;
+ using std::hash;
+
+ using std::nullopt;
+ using std::nullopt_t;
+
+ using std::operator==;
+ using std::operator!=;
+ using std::operator<;
+ using std::operator<=;
+ using std::operator>;
+ using std::operator>=;
+ using std::make_optional;
+ using std::swap;
+}
+
+#else // optional_USES_STD_OPTIONAL
+
+#include <cassert>
+#include <utility>
+
+// optional-lite alignment configuration:
+
+#ifndef optional_CONFIG_MAX_ALIGN_HACK
+# define optional_CONFIG_MAX_ALIGN_HACK 0
+#endif
+
+#ifndef optional_CONFIG_ALIGN_AS
+// no default, used in #if defined()
+#endif
+
+#ifndef optional_CONFIG_ALIGN_AS_FALLBACK
+# define optional_CONFIG_ALIGN_AS_FALLBACK double
+#endif
+
+// Compiler warning suppression:
+
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wundef"
+#elif defined(__GNUC__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wundef"
+#elif defined(_MSC_VER )
+# pragma warning( push )
+#endif
+
+// half-open range [lo..hi):
+#define optional_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
+
+// Compiler versions:
+//
+// MSVC++ 6.0 _MSC_VER == 1200 optional_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0)
+// MSVC++ 7.0 _MSC_VER == 1300 optional_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002)
+// MSVC++ 7.1 _MSC_VER == 1310 optional_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003)
+// MSVC++ 8.0 _MSC_VER == 1400 optional_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005)
+// MSVC++ 9.0 _MSC_VER == 1500 optional_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008)
+// MSVC++ 10.0 _MSC_VER == 1600 optional_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010)
+// MSVC++ 11.0 _MSC_VER == 1700 optional_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012)
+// MSVC++ 12.0 _MSC_VER == 1800 optional_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013)
+// MSVC++ 14.0 _MSC_VER == 1900 optional_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015)
+// MSVC++ 14.1 _MSC_VER >= 1910 optional_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017)
+// MSVC++ 14.2 _MSC_VER >= 1920 optional_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019)
+
+#if defined(_MSC_VER ) && !defined(__clang__)
+# define optional_COMPILER_MSVC_VER (_MSC_VER )
+# define optional_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
+#else
+# define optional_COMPILER_MSVC_VER 0
+# define optional_COMPILER_MSVC_VERSION 0
+#endif
+
+#define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * (major) + (minor) ) + (patch) )
+
+#if defined(__GNUC__) && !defined(__clang__)
+# define optional_COMPILER_GNUC_VERSION optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
+#else
+# define optional_COMPILER_GNUC_VERSION 0
+#endif
+
+#if defined(__clang__)
+# define optional_COMPILER_CLANG_VERSION optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
+#else
+# define optional_COMPILER_CLANG_VERSION 0
+#endif
+
+#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140 )
+# pragma warning( disable: 4345 ) // initialization behavior changed
+#endif
+
+#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150 )
+# pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const'
+#endif
+
+// Presence of language and library features:
+
+#define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE )
+
+#ifdef _HAS_CPP0X
+# define optional_HAS_CPP0X _HAS_CPP0X
+#else
+# define optional_HAS_CPP0X 0
+#endif
+
+// Unless defined otherwise below, consider VC14 as C++11 for optional-lite:
+
+#if optional_COMPILER_MSVC_VER >= 1900
+# undef optional_CPP11_OR_GREATER
+# define optional_CPP11_OR_GREATER 1
+#endif
+
+#define optional_CPP11_90 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1500)
+#define optional_CPP11_100 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1600)
+#define optional_CPP11_110 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1700)
+#define optional_CPP11_120 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1800)
+#define optional_CPP11_140 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1900)
+#define optional_CPP11_141 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1910)
+
+#define optional_CPP14_000 (optional_CPP14_OR_GREATER)
+#define optional_CPP17_000 (optional_CPP17_OR_GREATER)
+
+// clang >= 2.9, gcc >= 4.9, msvc >= vc14.0/1900 (vs15):
+#define optional_CPP11_140_C290_G490 ((optional_CPP11_OR_GREATER_ && (optional_COMPILER_CLANG_VERSION >= 290 || optional_COMPILER_GNUC_VERSION >= 490)) || (optional_COMPILER_MSVC_VER >= 1900))
+
+// clang >= 3.5, msvc >= vc11 (vs12):
+#define optional_CPP11_110_C350 ( optional_CPP11_110 && !optional_BETWEEN( optional_COMPILER_CLANG_VERSION, 1, 350 ) )
+
+// clang >= 3.5, gcc >= 5.0, msvc >= vc11 (vs12):
+#define optional_CPP11_110_C350_G500 \
+ ( optional_CPP11_110 && \
+ !( optional_BETWEEN( optional_COMPILER_CLANG_VERSION, 1, 350 ) \
+ || optional_BETWEEN( optional_COMPILER_GNUC_VERSION , 1, 500 ) ) )
+
+// Presence of C++11 language features:
+
+#define optional_HAVE_CONSTEXPR_11 optional_CPP11_140
+#define optional_HAVE_IS_DEFAULT optional_CPP11_140
+#define optional_HAVE_NOEXCEPT optional_CPP11_140
+#define optional_HAVE_NULLPTR optional_CPP11_100
+#define optional_HAVE_REF_QUALIFIER optional_CPP11_140_C290_G490
+#define optional_HAVE_STATIC_ASSERT optional_CPP11_110
+#define optional_HAVE_INITIALIZER_LIST optional_CPP11_140
+
+// Presence of C++14 language features:
+
+#define optional_HAVE_CONSTEXPR_14 optional_CPP14_000
+
+// Presence of C++17 language features:
+
+#define optional_HAVE_NODISCARD optional_CPP17_000
+
+// Presence of C++ library features:
+
+#define optional_HAVE_CONDITIONAL optional_CPP11_120
+#define optional_HAVE_REMOVE_CV optional_CPP11_120
+#define optional_HAVE_TYPE_TRAITS optional_CPP11_90
+
+#define optional_HAVE_TR1_TYPE_TRAITS (!! optional_COMPILER_GNUC_VERSION )
+#define optional_HAVE_TR1_ADD_POINTER (!! optional_COMPILER_GNUC_VERSION )
+
+#define optional_HAVE_IS_ASSIGNABLE optional_CPP11_110_C350
+#define optional_HAVE_IS_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350
+#define optional_HAVE_IS_NOTHROW_MOVE_ASSIGNABLE optional_CPP11_110_C350
+#define optional_HAVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350
+#define optional_HAVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE optional_CPP11_110_C350_G500
+#define optional_HAVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350_G500
+
+// C++ feature usage:
+
+#if optional_HAVE( CONSTEXPR_11 )
+# define optional_constexpr constexpr
+#else
+# define optional_constexpr /*constexpr*/
+#endif
+
+#if optional_HAVE( IS_DEFAULT )
+# define optional_is_default = default;
+#else
+# define optional_is_default {}
+#endif
+
+#if optional_HAVE( CONSTEXPR_14 )
+# define optional_constexpr14 constexpr
+#else
+# define optional_constexpr14 /*constexpr*/
+#endif
+
+#if optional_HAVE( NODISCARD )
+# define optional_nodiscard [[nodiscard]]
+#else
+# define optional_nodiscard /*[[nodiscard]]*/
+#endif
+
+#if optional_HAVE( NOEXCEPT )
+# define optional_noexcept noexcept
+#else
+# define optional_noexcept /*noexcept*/
+#endif
+
+#if optional_HAVE( NULLPTR )
+# define optional_nullptr nullptr
+#else
+# define optional_nullptr NULL
+#endif
+
+#if optional_HAVE( REF_QUALIFIER )
+// NOLINTNEXTLINE( bugprone-macro-parentheses )
+# define optional_ref_qual &
+# define optional_refref_qual &&
+#else
+# define optional_ref_qual /*&*/
+# define optional_refref_qual /*&&*/
+#endif
+
+#if optional_HAVE( STATIC_ASSERT )
+# define optional_static_assert(expr, text) static_assert(expr, text);
+#else
+# define optional_static_assert(expr, text) /*static_assert(expr, text);*/
+#endif
+
+// additional includes:
+
+#if optional_CONFIG_NO_EXCEPTIONS
+// already included: <cassert>
+#else
+# include <stdexcept>
+#endif
+
+#if optional_CPP11_OR_GREATER
+# include <functional>
+#endif
+
+#if optional_HAVE( INITIALIZER_LIST )
+# include <initializer_list>
+#endif
+
+#if optional_HAVE( TYPE_TRAITS )
+# include <type_traits>
+#elif optional_HAVE( TR1_TYPE_TRAITS )
+# include <tr1/type_traits>
+#endif
+
+// Method enabling
+
+#if optional_CPP11_OR_GREATER
+
+#define optional_REQUIRES_0(...) \
+ template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
+
+#define optional_REQUIRES_T(...) \
+ , typename std::enable_if< (__VA_ARGS__), int >::type = 0
+
+#define optional_REQUIRES_R(R, ...) \
+ typename std::enable_if< (__VA_ARGS__), R>::type
+
+#define optional_REQUIRES_A(...) \
+ , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr
+
+#endif
+
+//
+// optional:
+//
+
+namespace nonstd { namespace optional_lite {
+
+namespace std11 {
+
+template< class T, T v > struct integral_constant { enum { value = v }; };
+template< bool B > struct bool_constant : integral_constant<bool, B>{};
+
+typedef bool_constant< true > true_type;
+typedef bool_constant< false > false_type;
+
+#if optional_CPP11_OR_GREATER
+ using std::move;
+#else
+ template< typename T > T & move( T & t ) { return t; }
+#endif
+
+#if optional_HAVE( CONDITIONAL )
+ using std::conditional;
+#else
+ template< bool B, typename T, typename F > struct conditional { typedef T type; };
+ template< typename T, typename F > struct conditional<false, T, F> { typedef F type; };
+#endif // optional_HAVE_CONDITIONAL
+
+#if optional_HAVE( IS_ASSIGNABLE )
+ using std::is_assignable;
+#else
+ template< class T, class U > struct is_assignable : std11::true_type{};
+#endif
+
+#if optional_HAVE( IS_MOVE_CONSTRUCTIBLE )
+ using std::is_move_constructible;
+#else
+ template< class T > struct is_move_constructible : std11::true_type{};
+#endif
+
+#if optional_HAVE( IS_NOTHROW_MOVE_ASSIGNABLE )
+ using std::is_nothrow_move_assignable;
+#else
+ template< class T > struct is_nothrow_move_assignable : std11::true_type{};
+#endif
+
+#if optional_HAVE( IS_NOTHROW_MOVE_CONSTRUCTIBLE )
+ using std::is_nothrow_move_constructible;
+#else
+ template< class T > struct is_nothrow_move_constructible : std11::true_type{};
+#endif
+
+#if optional_HAVE( IS_TRIVIALLY_COPY_CONSTRUCTIBLE )
+ using std::is_trivially_copy_constructible;
+#else
+ template< class T > struct is_trivially_copy_constructible : std11::true_type{};
+#endif
+
+#if optional_HAVE( IS_TRIVIALLY_MOVE_CONSTRUCTIBLE )
+ using std::is_trivially_move_constructible;
+#else
+ template< class T > struct is_trivially_move_constructible : std11::true_type{};
+#endif
+
+} // namespace std11
+
+#if optional_CPP11_OR_GREATER
+
+/// type traits C++17:
+
+namespace std17 {
+
+#if optional_CPP17_OR_GREATER
+
+using std::is_swappable;
+using std::is_nothrow_swappable;
+
+#elif optional_CPP11_OR_GREATER
+
+namespace detail {
+
+using std::swap;
+
+struct is_swappable
+{
+ template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
+ static std11::true_type test( int /*unused*/ );
+
+ template< typename >
+ static std11::false_type test(...);
+};
+
+struct is_nothrow_swappable
+{
+ // wrap noexcept(expr) in separate function as work-around for VC140 (VS2015):
+
+ template< typename T >
+ static constexpr bool satisfies()
+ {
+ return noexcept( swap( std::declval<T&>(), std::declval<T&>() ) );
+ }
+
+ template< typename T >
+ static auto test( int /*unused*/ ) -> std11::integral_constant<bool, satisfies<T>()>{}
+
+ template< typename >
+ static auto test(...) -> std11::false_type;
+};
+
+} // namespace detail
+
+// is [nothow] swappable:
+
+template< typename T >
+struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
+
+template< typename T >
+struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
+
+#endif // optional_CPP17_OR_GREATER
+
+} // namespace std17
+
+/// type traits C++20:
+
+namespace std20 {
+
+template< typename T >
+struct remove_cvref
+{
+ typedef typename std::remove_cv< typename std::remove_reference<T>::type >::type type;
+};
+
+} // namespace std20
+
+#endif // optional_CPP11_OR_GREATER
+
+/// class optional
+
+template< typename T >
+class optional;
+
+namespace detail {
+
+// C++11 emulation:
+
+struct nulltype{};
+
+template< typename Head, typename Tail >
+struct typelist
+{
+ typedef Head head;
+ typedef Tail tail;
+};
+
+#if optional_CONFIG_MAX_ALIGN_HACK
+
+// Max align, use most restricted type for alignment:
+
+#define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ )
+#define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line )
+#define optional_UNIQUE3( name, line ) name ## line
+
+#define optional_ALIGN_TYPE( type ) \
+ type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st )
+
+template< typename T >
+struct struct_t { T _; };
+
+union max_align_t
+{
+ optional_ALIGN_TYPE( char );
+ optional_ALIGN_TYPE( short int );
+ optional_ALIGN_TYPE( int );
+ optional_ALIGN_TYPE( long int );
+ optional_ALIGN_TYPE( float );
+ optional_ALIGN_TYPE( double );
+ optional_ALIGN_TYPE( long double );
+ optional_ALIGN_TYPE( char * );
+ optional_ALIGN_TYPE( short int * );
+ optional_ALIGN_TYPE( int * );
+ optional_ALIGN_TYPE( long int * );
+ optional_ALIGN_TYPE( float * );
+ optional_ALIGN_TYPE( double * );
+ optional_ALIGN_TYPE( long double * );
+ optional_ALIGN_TYPE( void * );
+
+#ifdef HAVE_LONG_LONG
+ optional_ALIGN_TYPE( long long );
+#endif
+
+ struct Unknown;
+
+ Unknown ( * optional_UNIQUE(_) )( Unknown );
+ Unknown * Unknown::* optional_UNIQUE(_);
+ Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown );
+
+ struct_t< Unknown ( * )( Unknown) > optional_UNIQUE(_);
+ struct_t< Unknown * Unknown::* > optional_UNIQUE(_);
+ struct_t< Unknown ( Unknown::* )(Unknown) > optional_UNIQUE(_);
+};
+
+#undef optional_UNIQUE
+#undef optional_UNIQUE2
+#undef optional_UNIQUE3
+
+#undef optional_ALIGN_TYPE
+
+#elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK
+
+// Use user-specified type for alignment:
+
+#define optional_ALIGN_AS( unused ) \
+ optional_CONFIG_ALIGN_AS
+
+#else // optional_CONFIG_MAX_ALIGN_HACK
+
+// Determine POD type to use for alignment:
+
+#define optional_ALIGN_AS( to_align ) \
+ typename type_of_size< alignment_types, alignment_of< to_align >::value >::type
+
+template< typename T >
+struct alignment_of;
+
+template< typename T >
+struct alignment_of_hack
+{
+ char c;
+ T t;
+ alignment_of_hack();
+};
+
+template< size_t A, size_t S >
+struct alignment_logic
+{
+ enum { value = A < S ? A : S };
+};
+
+template< typename T >
+struct alignment_of
+{
+ enum { value = alignment_logic<
+ sizeof( alignment_of_hack<T> ) - sizeof(T), sizeof(T) >::value };
+};
+
+template< typename List, size_t N >
+struct type_of_size
+{
+ typedef typename std11::conditional<
+ N == sizeof( typename List::head ),
+ typename List::head,
+ typename type_of_size<typename List::tail, N >::type >::type type;
+};
+
+template< size_t N >
+struct type_of_size< nulltype, N >
+{
+ typedef optional_CONFIG_ALIGN_AS_FALLBACK type;
+};
+
+template< typename T>
+struct struct_t { T _; };
+
+#define optional_ALIGN_TYPE( type ) \
+ typelist< type , typelist< struct_t< type >
+
+struct Unknown;
+
+typedef
+ optional_ALIGN_TYPE( char ),
+ optional_ALIGN_TYPE( short ),
+ optional_ALIGN_TYPE( int ),
+ optional_ALIGN_TYPE( long ),
+ optional_ALIGN_TYPE( float ),
+ optional_ALIGN_TYPE( double ),
+ optional_ALIGN_TYPE( long double ),
+
+ optional_ALIGN_TYPE( char *),
+ optional_ALIGN_TYPE( short * ),
+ optional_ALIGN_TYPE( int * ),
+ optional_ALIGN_TYPE( long * ),
+ optional_ALIGN_TYPE( float * ),
+ optional_ALIGN_TYPE( double * ),
+ optional_ALIGN_TYPE( long double * ),
+
+ optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ),
+ optional_ALIGN_TYPE( Unknown * Unknown::* ),
+ optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ),
+
+ nulltype
+ > > > > > > > > > > > > > >
+ > > > > > > > > > > > > > >
+ > > > > > >
+ alignment_types;
+
+#undef optional_ALIGN_TYPE
+
+#endif // optional_CONFIG_MAX_ALIGN_HACK
+
+/// C++03 constructed union to hold value.
+
+template< typename T >
+union storage_t
+{
+//private:
+// template< typename > friend class optional;
+
+ typedef T value_type;
+
+ storage_t() optional_is_default
+
+ explicit storage_t( value_type const & v )
+ {
+ construct_value( v );
+ }
+
+ void construct_value( value_type const & v )
+ {
+ ::new( value_ptr() ) value_type( v );
+ }
+
+#if optional_CPP11_OR_GREATER
+
+ explicit storage_t( value_type && v )
+ {
+ construct_value( std::move( v ) );
+ }
+
+ void construct_value( value_type && v )
+ {
+ ::new( value_ptr() ) value_type( std::move( v ) );
+ }
+
+ template< class... Args >
+ storage_t( nonstd_lite_in_place_t(T), Args&&... args )
+ {
+ emplace( std::forward<Args>(args)... );
+ }
+
+ template< class... Args >
+ void emplace( Args&&... args )
+ {
+ ::new( value_ptr() ) value_type( std::forward<Args>(args)... );
+ }
+
+ template< class U, class... Args >
+ void emplace( std::initializer_list<U> il, Args&&... args )
+ {
+ ::new( value_ptr() ) value_type( il, std::forward<Args>(args)... );
+ }
+
+#endif
+
+ void destruct_value()
+ {
+ value_ptr()->~T();
+ }
+
+ optional_nodiscard value_type const * value_ptr() const
+ {
+ return as<value_type>();
+ }
+
+ value_type * value_ptr()
+ {
+ return as<value_type>();
+ }
+
+ optional_nodiscard value_type const & value() const optional_ref_qual
+ {
+ return * value_ptr();
+ }
+
+ value_type & value() optional_ref_qual
+ {
+ return * value_ptr();
+ }
+
+#if optional_HAVE( REF_QUALIFIER )
+
+ optional_nodiscard value_type const && value() const optional_refref_qual
+ {
+ return std::move( value() );
+ }
+
+ value_type && value() optional_refref_qual
+ {
+ return std::move( value() );
+ }
+
+#endif
+
+#if optional_CPP11_OR_GREATER
+
+ using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type;
+ aligned_storage_t data;
+
+#elif optional_CONFIG_MAX_ALIGN_HACK
+
+ typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t;
+
+ max_align_t hack;
+ aligned_storage_t data;
+
+#else
+ typedef optional_ALIGN_AS(value_type) align_as_type;
+
+ typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t;
+ aligned_storage_t data;
+
+# undef optional_ALIGN_AS
+
+#endif // optional_CONFIG_MAX_ALIGN_HACK
+
+ optional_nodiscard void * ptr() optional_noexcept
+ {
+ return &data;
+ }
+
+ optional_nodiscard void const * ptr() const optional_noexcept
+ {
+ return &data;
+ }
+
+ template <typename U>
+ optional_nodiscard U * as()
+ {
+ return reinterpret_cast<U*>( ptr() );
+ }
+
+ template <typename U>
+ optional_nodiscard U const * as() const
+ {
+ return reinterpret_cast<U const *>( ptr() );
+ }
+};
+
+} // namespace detail
+
+/// disengaged state tag
+
+struct nullopt_t
+{
+ struct init{};
+ explicit optional_constexpr nullopt_t( init /*unused*/ ) optional_noexcept {}
+};
+
+#if optional_HAVE( CONSTEXPR_11 )
+constexpr nullopt_t nullopt{ nullopt_t::init{} };
+#else
+// extra parenthesis to prevent the most vexing parse:
+const nullopt_t nullopt(( nullopt_t::init() ));
+#endif
+
+/// optional access error
+
+#if ! optional_CONFIG_NO_EXCEPTIONS
+
+class bad_optional_access : public std::logic_error
+{
+public:
+ explicit bad_optional_access()
+ : logic_error( "bad optional access" ) {}
+};
+
+#endif //optional_CONFIG_NO_EXCEPTIONS
+
+/// optional
+
+template< typename T>
+class optional
+{
+ optional_static_assert(( !std::is_same<typename std::remove_cv<T>::type, nullopt_t>::value ),
+ "T in optional<T> must not be of type 'nullopt_t'.")
+
+ optional_static_assert(( !std::is_same<typename std::remove_cv<T>::type, in_place_t>::value ),
+ "T in optional<T> must not be of type 'in_place_t'.")
+
+ optional_static_assert(( std::is_object<T>::value && std::is_destructible<T>::value && !std::is_array<T>::value ),
+ "T in optional<T> must meet the Cpp17Destructible requirements.")
+
+private:
+ template< typename > friend class optional;
+
+ typedef void (optional::*safe_bool)() const;
+
+public:
+ typedef T value_type;
+
+ // x.x.3.1, constructors
+
+ // 1a - default construct
+ optional_constexpr optional() optional_noexcept
+ : has_value_( false )
+ , contained()
+ {}
+
+ // 1b - construct explicitly empty
+ // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
+ optional_constexpr optional( nullopt_t /*unused*/ ) optional_noexcept
+ : has_value_( false )
+ , contained()
+ {}
+
+ // 2 - copy-construct
+#if optional_CPP11_OR_GREATER
+ // template< typename U = T
+ // optional_REQUIRES_T(
+ // std::is_copy_constructible<U>::value
+ // || std11::is_trivially_copy_constructible<U>::value
+ // )
+ // >
+#endif
+ optional_constexpr14 optional( optional const & other )
+ : has_value_( other.has_value() )
+ {
+ if ( other.has_value() )
+ {
+ contained.construct_value( other.contained.value() );
+ }
+ }
+
+#if optional_CPP11_OR_GREATER
+
+ // 3 (C++11) - move-construct from optional
+ template< typename U = T
+ optional_REQUIRES_T(
+ std11::is_move_constructible<U>::value
+ || std11::is_trivially_move_constructible<U>::value
+ )
+ >
+ optional_constexpr14 optional( optional && other )
+ // NOLINTNEXTLINE( performance-noexcept-move-constructor )
+ noexcept( std11::is_nothrow_move_constructible<T>::value )
+ : has_value_( other.has_value() )
+ {
+ if ( other.has_value() )
+ {
+ contained.construct_value( std::move( other.contained.value() ) );
+ }
+ }
+
+ // 4a (C++11) - explicit converting copy-construct from optional
+ template< typename U
+ optional_REQUIRES_T(
+ std::is_constructible<T, U const &>::value
+ && !std::is_constructible<T, optional<U> & >::value
+ && !std::is_constructible<T, optional<U> && >::value
+ && !std::is_constructible<T, optional<U> const & >::value
+ && !std::is_constructible<T, optional<U> const && >::value
+ && !std::is_convertible< optional<U> & , T>::value
+ && !std::is_convertible< optional<U> && , T>::value
+ && !std::is_convertible< optional<U> const & , T>::value
+ && !std::is_convertible< optional<U> const &&, T>::value
+ && !std::is_convertible< U const & , T>::value /*=> explicit */
+ )
+ >
+ explicit optional( optional<U> const & other )
+ : has_value_( other.has_value() )
+ {
+ if ( other.has_value() )
+ {
+ contained.construct_value( T{ other.contained.value() } );
+ }
+ }
+#endif // optional_CPP11_OR_GREATER
+
+ // 4b (C++98 and later) - non-explicit converting copy-construct from optional
+ template< typename U
+#if optional_CPP11_OR_GREATER
+ optional_REQUIRES_T(
+ std::is_constructible<T, U const &>::value
+ && !std::is_constructible<T, optional<U> & >::value
+ && !std::is_constructible<T, optional<U> && >::value
+ && !std::is_constructible<T, optional<U> const & >::value
+ && !std::is_constructible<T, optional<U> const && >::value
+ && !std::is_convertible< optional<U> & , T>::value
+ && !std::is_convertible< optional<U> && , T>::value
+ && !std::is_convertible< optional<U> const & , T>::value
+ && !std::is_convertible< optional<U> const &&, T>::value
+ && std::is_convertible< U const & , T>::value /*=> non-explicit */
+ )
+#endif // optional_CPP11_OR_GREATER
+ >
+ // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
+ /*non-explicit*/ optional( optional<U> const & other )
+ : has_value_( other.has_value() )
+ {
+ if ( other.has_value() )
+ {
+ contained.construct_value( other.contained.value() );
+ }
+ }
+
+#if optional_CPP11_OR_GREATER
+
+ // 5a (C++11) - explicit converting move-construct from optional
+ template< typename U
+ optional_REQUIRES_T(
+ std::is_constructible<T, U &&>::value
+ && !std::is_constructible<T, optional<U> & >::value
+ && !std::is_constructible<T, optional<U> && >::value
+ && !std::is_constructible<T, optional<U> const & >::value
+ && !std::is_constructible<T, optional<U> const && >::value
+ && !std::is_convertible< optional<U> & , T>::value
+ && !std::is_convertible< optional<U> && , T>::value
+ && !std::is_convertible< optional<U> const & , T>::value
+ && !std::is_convertible< optional<U> const &&, T>::value
+ && !std::is_convertible< U &&, T>::value /*=> explicit */
+ )
+ >
+ explicit optional( optional<U> && other
+ )
+ : has_value_( other.has_value() )
+ {
+ if ( other.has_value() )
+ {
+ contained.construct_value( T{ std::move( other.contained.value() ) } );
+ }
+ }
+
+ // 5a (C++11) - non-explicit converting move-construct from optional
+ template< typename U
+ optional_REQUIRES_T(
+ std::is_constructible<T, U &&>::value
+ && !std::is_constructible<T, optional<U> & >::value
+ && !std::is_constructible<T, optional<U> && >::value
+ && !std::is_constructible<T, optional<U> const & >::value
+ && !std::is_constructible<T, optional<U> const && >::value
+ && !std::is_convertible< optional<U> & , T>::value
+ && !std::is_convertible< optional<U> && , T>::value
+ && !std::is_convertible< optional<U> const & , T>::value
+ && !std::is_convertible< optional<U> const &&, T>::value
+ && std::is_convertible< U &&, T>::value /*=> non-explicit */
+ )
+ >
+ // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
+ /*non-explicit*/ optional( optional<U> && other )
+ : has_value_( other.has_value() )
+ {
+ if ( other.has_value() )
+ {
+ contained.construct_value( std::move( other.contained.value() ) );
+ }
+ }
+
+ // 6 (C++11) - in-place construct
+ template< typename... Args
+ optional_REQUIRES_T(
+ std::is_constructible<T, Args&&...>::value
+ )
+ >
+ optional_constexpr explicit optional( nonstd_lite_in_place_t(T), Args&&... args )
+ : has_value_( true )
+ , contained( in_place, std::forward<Args>(args)... )
+ {}
+
+ // 7 (C++11) - in-place construct, initializer-list
+ template< typename U, typename... Args
+ optional_REQUIRES_T(
+ std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value
+ )
+ >
+ optional_constexpr explicit optional( nonstd_lite_in_place_t(T), std::initializer_list<U> il, Args&&... args )
+ : has_value_( true )
+ , contained( T( il, std::forward<Args>(args)...) )
+ {}
+
+ // 8a (C++11) - explicit move construct from value
+ template< typename U = T
+ optional_REQUIRES_T(
+ std::is_constructible<T, U&&>::value
+ && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
+ && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
+ && !std::is_convertible<U&&, T>::value /*=> explicit */
+ )
+ >
+ optional_constexpr explicit optional( U && value )
+ : has_value_( true )
+ , contained( nonstd_lite_in_place(T), std::forward<U>( value ) )
+ {}
+
+ // 8b (C++11) - non-explicit move construct from value
+ template< typename U = T
+ optional_REQUIRES_T(
+ std::is_constructible<T, U&&>::value
+ && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
+ && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
+ && std::is_convertible<U&&, T>::value /*=> non-explicit */
+ )
+ >
+ // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
+ optional_constexpr /*non-explicit*/ optional( U && value )
+ : has_value_( true )
+ , contained( nonstd_lite_in_place(T), std::forward<U>( value ) )
+ {}
+
+#else // optional_CPP11_OR_GREATER
+
+ // 8 (C++98)
+ optional( value_type const & value )
+ : has_value_( true )
+ , contained( value )
+ {}
+
+#endif // optional_CPP11_OR_GREATER
+
+ // x.x.3.2, destructor
+
+ ~optional()
+ {
+ if ( has_value() )
+ {
+ contained.destruct_value();
+ }
+ }
+
+ // x.x.3.3, assignment
+
+ // 1 (C++98and later) - assign explicitly empty
+ optional & operator=( nullopt_t /*unused*/) optional_noexcept
+ {
+ reset();
+ return *this;
+ }
+
+ // 2 (C++98and later) - copy-assign from optional
+#if optional_CPP11_OR_GREATER
+ // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
+ optional_REQUIRES_R(
+ optional &,
+ true
+// std::is_copy_constructible<T>::value
+// && std::is_copy_assignable<T>::value
+ )
+ operator=( optional const & other )
+ noexcept(
+ std11::is_nothrow_move_assignable<T>::value
+ && std11::is_nothrow_move_constructible<T>::value
+ )
+#else
+ optional & operator=( optional const & other )
+#endif
+ {
+ if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); }
+ else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( *other ); }
+ else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = *other; }
+ return *this;
+ }
+
+#if optional_CPP11_OR_GREATER
+
+ // 3 (C++11) - move-assign from optional
+ // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
+ optional_REQUIRES_R(
+ optional &,
+ true
+// std11::is_move_constructible<T>::value
+// && std::is_move_assignable<T>::value
+ )
+ operator=( optional && other ) noexcept
+ {
+ if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); }
+ else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std::move( *other ) ); }
+ else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = std::move( *other ); }
+ return *this;
+ }
+
+ // 4 (C++11) - move-assign from value
+ template< typename U = T >
+ // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
+ optional_REQUIRES_R(
+ optional &,
+ std::is_constructible<T , U>::value
+ && std11::is_assignable<T&, U>::value
+ && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
+ && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
+ && !(std::is_scalar<T>::value && std::is_same<T, typename std::decay<U>::type>::value)
+ )
+ operator=( U && value )
+ {
+ if ( has_value() )
+ {
+ contained.value() = std::forward<U>( value );
+ }
+ else
+ {
+ initialize( T( std::forward<U>( value ) ) );
+ }
+ return *this;
+ }
+
+#else // optional_CPP11_OR_GREATER
+
+ // 4 (C++98) - copy-assign from value
+ template< typename U /*= T*/ >
+ optional & operator=( U const & value )
+ {
+ if ( has_value() ) contained.value() = value;
+ else initialize( T( value ) );
+ return *this;
+ }
+
+#endif // optional_CPP11_OR_GREATER
+
+ // 5 (C++98 and later) - converting copy-assign from optional
+ template< typename U >
+#if optional_CPP11_OR_GREATER
+ // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
+ optional_REQUIRES_R(
+ optional&,
+ std::is_constructible< T , U const &>::value
+ && std11::is_assignable< T&, U const &>::value
+ && !std::is_constructible<T, optional<U> & >::value
+ && !std::is_constructible<T, optional<U> && >::value
+ && !std::is_constructible<T, optional<U> const & >::value
+ && !std::is_constructible<T, optional<U> const && >::value
+ && !std::is_convertible< optional<U> & , T>::value
+ && !std::is_convertible< optional<U> && , T>::value
+ && !std::is_convertible< optional<U> const & , T>::value
+ && !std::is_convertible< optional<U> const &&, T>::value
+ && !std11::is_assignable< T&, optional<U> & >::value
+ && !std11::is_assignable< T&, optional<U> && >::value
+ && !std11::is_assignable< T&, optional<U> const & >::value
+ && !std11::is_assignable< T&, optional<U> const && >::value
+ )
+#else
+ optional&
+#endif // optional_CPP11_OR_GREATER
+ operator=( optional<U> const & other )
+ {
+ return *this = optional( other );
+ }
+
+#if optional_CPP11_OR_GREATER
+
+ // 6 (C++11) - converting move-assign from optional
+ template< typename U >
+ // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
+ optional_REQUIRES_R(
+ optional&,
+ std::is_constructible< T , U>::value
+ && std11::is_assignable< T&, U>::value
+ && !std::is_constructible<T, optional<U> & >::value
+ && !std::is_constructible<T, optional<U> && >::value
+ && !std::is_constructible<T, optional<U> const & >::value
+ && !std::is_constructible<T, optional<U> const && >::value
+ && !std::is_convertible< optional<U> & , T>::value
+ && !std::is_convertible< optional<U> && , T>::value
+ && !std::is_convertible< optional<U> const & , T>::value
+ && !std::is_convertible< optional<U> const &&, T>::value
+ && !std11::is_assignable< T&, optional<U> & >::value
+ && !std11::is_assignable< T&, optional<U> && >::value
+ && !std11::is_assignable< T&, optional<U> const & >::value
+ && !std11::is_assignable< T&, optional<U> const && >::value
+ )
+ operator=( optional<U> && other )
+ {
+ return *this = optional( std::move( other ) );
+ }
+
+ // 7 (C++11) - emplace
+ template< typename... Args
+ optional_REQUIRES_T(
+ std::is_constructible<T, Args&&...>::value
+ )
+ >
+ T& emplace( Args&&... args )
+ {
+ *this = nullopt;
+ contained.emplace( std::forward<Args>(args)... );
+ has_value_ = true;
+ return contained.value();
+ }
+
+ // 8 (C++11) - emplace, initializer-list
+ template< typename U, typename... Args
+ optional_REQUIRES_T(
+ std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value
+ )
+ >
+ T& emplace( std::initializer_list<U> il, Args&&... args )
+ {
+ *this = nullopt;
+ contained.emplace( il, std::forward<Args>(args)... );
+ has_value_ = true;
+ return contained.value();
+ }
+
+#endif // optional_CPP11_OR_GREATER
+
+ // x.x.3.4, swap
+
+ void swap( optional & other )
+#if optional_CPP11_OR_GREATER
+ noexcept(
+ std11::is_nothrow_move_constructible<T>::value
+ && std17::is_nothrow_swappable<T>::value
+ )
+#endif
+ {
+ using std::swap;
+ if ( (has_value() == true ) && (other.has_value() == true ) ) { swap( **this, *other ); }
+ else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std11::move(*other) ); other.reset(); }
+ else if ( (has_value() == true ) && (other.has_value() == false) ) { other.initialize( std11::move(**this) ); reset(); }
+ }
+
+ // x.x.3.5, observers
+
+ optional_constexpr value_type const * operator ->() const
+ {
+ return assert( has_value() ),
+ contained.value_ptr();
+ }
+
+ optional_constexpr14 value_type * operator ->()
+ {
+ return assert( has_value() ),
+ contained.value_ptr();
+ }
+
+ optional_constexpr value_type const & operator *() const optional_ref_qual
+ {
+ return assert( has_value() ),
+ contained.value();
+ }
+
+ optional_constexpr14 value_type & operator *() optional_ref_qual
+ {
+ return assert( has_value() ),
+ contained.value();
+ }
+
+#if optional_HAVE( REF_QUALIFIER )
+
+ optional_constexpr value_type const && operator *() const optional_refref_qual
+ {
+ return std::move( **this );
+ }
+
+ optional_constexpr14 value_type && operator *() optional_refref_qual
+ {
+ return std::move( **this );
+ }
+
+#endif
+
+#if optional_CPP11_OR_GREATER
+ optional_constexpr explicit operator bool() const optional_noexcept
+ {
+ return has_value();
+ }
+#else
+ optional_constexpr operator safe_bool() const optional_noexcept
+ {
+ return has_value() ? &optional::this_type_does_not_support_comparisons : 0;
+ }
+#endif
+
+ // NOLINTNEXTLINE( modernize-use-nodiscard )
+ /*optional_nodiscard*/ optional_constexpr bool has_value() const optional_noexcept
+ {
+ return has_value_;
+ }
+
+ // NOLINTNEXTLINE( modernize-use-nodiscard )
+ /*optional_nodiscard*/ optional_constexpr14 value_type const & value() const optional_ref_qual
+ {
+#if optional_CONFIG_NO_EXCEPTIONS
+ assert( has_value() );
+#else
+ if ( ! has_value() )
+ {
+ throw bad_optional_access();
+ }
+#endif
+ return contained.value();
+ }
+
+ optional_constexpr14 value_type & value() optional_ref_qual
+ {
+#if optional_CONFIG_NO_EXCEPTIONS
+ assert( has_value() );
+#else
+ if ( ! has_value() )
+ {
+ throw bad_optional_access();
+ }
+#endif
+ return contained.value();
+ }
+
+#if optional_HAVE( REF_QUALIFIER ) && ( !optional_COMPILER_GNUC_VERSION || optional_COMPILER_GNUC_VERSION >= 490 )
+
+ // NOLINTNEXTLINE( modernize-use-nodiscard )
+ /*optional_nodiscard*/ optional_constexpr value_type const && value() const optional_refref_qual
+ {
+ return std::move( value() );
+ }
+
+ optional_constexpr14 value_type && value() optional_refref_qual
+ {
+ return std::move( value() );
+ }
+
+#endif
+
+#if optional_HAVE( REF_QUALIFIER )
+
+ template< typename U >
+ optional_constexpr value_type value_or( U && v ) const optional_ref_qual
+ {
+ return has_value() ? contained.value() : static_cast<T>(std::forward<U>( v ) );
+ }
+
+ template< typename U >
+ optional_constexpr14 value_type value_or( U && v ) optional_refref_qual
+ {
+#if optional_COMPILER_CLANG_VERSION
+ return has_value() ? /*std::move*/( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
+#else
+ return has_value() ? std::move( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
+#endif
+ }
+
+#else
+
+ template< typename U >
+ optional_constexpr value_type value_or( U const & v ) const
+ {
+ return has_value() ? contained.value() : static_cast<value_type>( v );
+ }
+
+#endif // optional_HAVE( REF_QUALIFIER )
+
+#if !optional_CONFIG_NO_EXTENSIONS
+#if optional_HAVE( REF_QUALIFIER )
+
+ template< typename F >
+ optional_constexpr value_type value_or_eval( F f ) const &
+ {
+ return has_value() ? contained.value() : f();
+ }
+
+ template< typename F >
+ optional_constexpr14 value_type value_or_eval( F f ) &&
+ {
+ if ( has_value() )
+ {
+ return std::move( contained.value() );
+ }
+ else
+ {
+ return f();
+ }
+ }
+
+#else
+
+ template< typename F >
+ optional_constexpr value_type value_or_eval( F f ) const
+ {
+ return has_value() ? contained.value() : f();
+ }
+
+#endif // optional_HAVE( REF_QUALIFIER )
+#endif // !optional_CONFIG_NO_EXTENSIONS
+
+ // x.x.3.6, modifiers
+
+ void reset() optional_noexcept
+ {
+ if ( has_value() )
+ {
+ contained.destruct_value();
+ }
+
+ has_value_ = false;
+ }
+
+private:
+ void this_type_does_not_support_comparisons() const {}
+
+ template< typename V >
+ void initialize( V const & value )
+ {
+ assert( ! has_value() );
+ contained.construct_value( value );
+ has_value_ = true;
+ }
+
+#if optional_CPP11_OR_GREATER
+ template< typename V >
+ void initialize( V && value )
+ {
+ assert( ! has_value() );
+ contained.construct_value( std::move( value ) );
+ has_value_ = true;
+ }
+
+#endif
+
+private:
+ bool has_value_;
+ detail::storage_t< value_type > contained;
+
+};
+
+// Relational operators
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator==( optional<T> const & x, optional<U> const & y )
+{
+ return bool(x) != bool(y) ? false : !bool( x ) ? true : *x == *y;
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator!=( optional<T> const & x, optional<U> const & y )
+{
+ return !(x == y);
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator<( optional<T> const & x, optional<U> const & y )
+{
+ return (!y) ? false : (!x) ? true : *x < *y;
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator>( optional<T> const & x, optional<U> const & y )
+{
+ return (y < x);
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator<=( optional<T> const & x, optional<U> const & y )
+{
+ return !(y < x);
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator>=( optional<T> const & x, optional<U> const & y )
+{
+ return !(x < y);
+}
+
+// Comparison with nullopt
+
+template< typename T >
+optional_nodiscard optional_constexpr bool operator==( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
+{
+ return (!x);
+}
+
+template< typename T >
+optional_nodiscard optional_constexpr bool operator==( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
+{
+ return (!x);
+}
+
+template< typename T >
+optional_nodiscard optional_constexpr bool operator!=( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
+{
+ return bool(x);
+}
+
+template< typename T >
+optional_nodiscard optional_constexpr bool operator!=( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
+{
+ return bool(x);
+}
+
+template< typename T >
+optional_nodiscard optional_constexpr bool operator<( optional<T> const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept
+{
+ return false;
+}
+
+template< typename T >
+optional_nodiscard optional_constexpr bool operator<( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
+{
+ return bool(x);
+}
+
+template< typename T >
+optional_nodiscard optional_constexpr bool operator<=( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
+{
+ return (!x);
+}
+
+template< typename T >
+optional_nodiscard optional_constexpr bool operator<=( nullopt_t /*unused*/, optional<T> const & /*unused*/ ) optional_noexcept
+{
+ return true;
+}
+
+template< typename T >
+optional_nodiscard optional_constexpr bool operator>( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
+{
+ return bool(x);
+}
+
+template< typename T >
+optional_nodiscard optional_constexpr bool operator>( nullopt_t /*unused*/, optional<T> const & /*unused*/ ) optional_noexcept
+{
+ return false;
+}
+
+template< typename T >
+optional_nodiscard optional_constexpr bool operator>=( optional<T> const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept
+{
+ return true;
+}
+
+template< typename T >
+optional_nodiscard optional_constexpr bool operator>=( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
+{
+ return (!x);
+}
+
+// Comparison with T
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator==( optional<T> const & x, U const & v )
+{
+ return bool(x) ? *x == v : false;
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator==( U const & v, optional<T> const & x )
+{
+ return bool(x) ? v == *x : false;
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator!=( optional<T> const & x, U const & v )
+{
+ return bool(x) ? *x != v : true;
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator!=( U const & v, optional<T> const & x )
+{
+ return bool(x) ? v != *x : true;
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator<( optional<T> const & x, U const & v )
+{
+ return bool(x) ? *x < v : true;
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator<( U const & v, optional<T> const & x )
+{
+ return bool(x) ? v < *x : false;
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator<=( optional<T> const & x, U const & v )
+{
+ return bool(x) ? *x <= v : true;
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator<=( U const & v, optional<T> const & x )
+{
+ return bool(x) ? v <= *x : false;
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator>( optional<T> const & x, U const & v )
+{
+ return bool(x) ? *x > v : false;
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator>( U const & v, optional<T> const & x )
+{
+ return bool(x) ? v > *x : true;
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator>=( optional<T> const & x, U const & v )
+{
+ return bool(x) ? *x >= v : false;
+}
+
+template< typename T, typename U >
+optional_nodiscard optional_constexpr bool operator>=( U const & v, optional<T> const & x )
+{
+ return bool(x) ? v >= *x : true;
+}
+
+// Specialized algorithms
+
+template< typename T
+#if optional_CPP11_OR_GREATER
+ optional_REQUIRES_T(
+ std11::is_move_constructible<T>::value
+ && std17::is_swappable<T>::value )
+#endif
+>
+void swap( optional<T> & x, optional<T> & y )
+#if optional_CPP11_OR_GREATER
+ noexcept( noexcept( x.swap(y) ) )
+#endif
+{
+ x.swap( y );
+}
+
+#if optional_CPP11_OR_GREATER
+
+template< typename T >
+optional_constexpr optional< typename std::decay<T>::type > make_optional( T && value )
+{
+ return optional< typename std::decay<T>::type >( std::forward<T>( value ) );
+}
+
+template< typename T, typename...Args >
+optional_constexpr optional<T> make_optional( Args&&... args )
+{
+ return optional<T>( nonstd_lite_in_place(T), std::forward<Args>(args)...);
+}
+
+template< typename T, typename U, typename... Args >
+optional_constexpr optional<T> make_optional( std::initializer_list<U> il, Args&&... args )
+{
+ return optional<T>( nonstd_lite_in_place(T), il, std::forward<Args>(args)...);
+}
+
+#else
+
+template< typename T >
+optional<T> make_optional( T const & value )
+{
+ return optional<T>( value );
+}
+
+#endif // optional_CPP11_OR_GREATER
+
+} // namespace optional_lite
+
+using optional_lite::optional;
+using optional_lite::nullopt_t;
+using optional_lite::nullopt;
+
+#if ! optional_CONFIG_NO_EXCEPTIONS
+using optional_lite::bad_optional_access;
+#endif
+
+using optional_lite::make_optional;
+
+} // namespace nonstd
+
+#if optional_CPP11_OR_GREATER
+
+// specialize the std::hash algorithm:
+
+namespace std {
+
+template< class T >
+struct hash< nonstd::optional<T> >
+{
+public:
+ std::size_t operator()( nonstd::optional<T> const & v ) const optional_noexcept
+ {
+ return bool( v ) ? std::hash<T>{}( *v ) : 0;
+ }
+};
+
+} //namespace std
+
+#endif // optional_CPP11_OR_GREATER
+
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#elif defined(__GNUC__)
+# pragma GCC diagnostic pop
+#elif defined(_MSC_VER )
+# pragma warning( pop )
+#endif
+
+#endif // optional_USES_STD_OPTIONAL
+
+#endif // NONSTD_OPTIONAL_LITE_HPP
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/serializer.cpp b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/serializer.cpp
new file mode 100644
index 0000000000..356d803b5d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/serializer.cpp
@@ -0,0 +1,214 @@
+#include "serializer.h"
+#include <stdexcept>
+#include <rapidjson/allocators.h>
+#include "json.h"
+
+
+
+//// Elementary types
+
+void JsonNull::swap(JsonNull& arg) noexcept
+{
+}
+
+
+void Reflect(Reader& visitor, uint8_t& value) {
+ if (!visitor.IsInt())
+ throw std::invalid_argument("uint8_t");
+ value = (uint8_t)visitor.GetInt();
+}
+void Reflect(Writer& visitor, uint8_t& value) {
+ visitor.Int(value);
+}
+
+void Reflect(Reader& visitor, short& value) {
+ if (!visitor.IsInt())
+ throw std::invalid_argument("short");
+ value = (short)visitor.GetInt();
+}
+void Reflect(Writer& visitor, short& value) {
+ visitor.Int(value);
+}
+
+void Reflect(Reader& visitor, unsigned short& value) {
+ if (!visitor.IsInt())
+ throw std::invalid_argument("unsigned short");
+ value = (unsigned short)visitor.GetInt();
+}
+void Reflect(Writer& visitor, unsigned short& value) {
+ visitor.Int(value);
+}
+
+void Reflect(Reader& visitor, int& value) {
+ if (!visitor.IsInt())
+ throw std::invalid_argument("int");
+ value = visitor.GetInt();
+}
+void Reflect(Writer& visitor, int& value) {
+ visitor.Int(value);
+}
+
+void Reflect(Reader& visitor, unsigned& value) {
+ if (!visitor.IsUint64())
+ throw std::invalid_argument("unsigned");
+ value = visitor.GetUint32();
+}
+void Reflect(Writer& visitor, unsigned& value) {
+ visitor.Uint32(value);
+}
+
+void Reflect(Reader& visitor, long& value) {
+ if (!visitor.IsInt64())
+ throw std::invalid_argument("long");
+ value = long(visitor.GetInt64());
+}
+void Reflect(Writer& visitor, long& value) {
+ visitor.Int64(value);
+}
+
+void Reflect(Reader& visitor, unsigned long& value) {
+ if (!visitor.IsUint64())
+ throw std::invalid_argument("unsigned long");
+ value = (unsigned long)visitor.GetUint64();
+}
+void Reflect(Writer& visitor, unsigned long& value) {
+ visitor.Uint64(value);
+}
+
+void Reflect(Reader& visitor, long long& value) {
+ if (!visitor.IsInt64())
+ throw std::invalid_argument("long long");
+ value = visitor.GetInt64();
+}
+void Reflect(Writer& visitor, long long& value) {
+ visitor.Int64(value);
+}
+
+void Reflect(Reader& visitor, unsigned long long& value) {
+ if (!visitor.IsUint64())
+ throw std::invalid_argument("unsigned long long");
+ value = visitor.GetUint64();
+}
+void Reflect(Writer& visitor, unsigned long long& value) {
+ visitor.Uint64(value);
+}
+
+void Reflect(Reader& visitor, double& value) {
+ if (!visitor.IsNumber())
+ throw std::invalid_argument("double");
+ value = visitor.GetDouble();
+}
+void Reflect(Writer& visitor, double& value) {
+ visitor.Double(value);
+}
+
+void Reflect(Reader& visitor, bool& value) {
+ if (!visitor.IsBool())
+ throw std::invalid_argument("bool");
+ value = visitor.GetBool();
+}
+void Reflect(Writer& visitor, bool& value) {
+ visitor.Bool(value);
+}
+
+void Reflect(Reader& visitor, std::string& value) {
+ if (!visitor.IsString())
+ throw std::invalid_argument("std::string");
+ value = visitor.GetString();
+}
+void Reflect(Writer& visitor, std::string& value) {
+ visitor.String(value.c_str(), (rapidjson::SizeType)value.size());
+}
+
+void Reflect(Reader& visitor, JsonNull& value) {
+ visitor.GetNull();
+}
+
+void Reflect(Writer& visitor, JsonNull& value) {
+ visitor.Null();
+}
+
+
+void Reflect(Reader& visitor, SerializeFormat& value) {
+ std::string fmt = visitor.GetString();
+ value = fmt[0] == 'm' ? SerializeFormat::MessagePack : SerializeFormat::Json;
+}
+
+void Reflect(Writer& visitor, SerializeFormat& value) {
+ switch (value) {
+ case SerializeFormat::Json:
+ visitor.String("json");
+ break;
+ case SerializeFormat::MessagePack:
+ visitor.String("msgpack");
+ break;
+ }
+}
+
+
+std::string JsonReader::ToString() const
+{
+ rapidjson::StringBuffer strBuf;
+ strBuf.Clear();
+ rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf);
+ m_->Accept(writer);
+ std::string strJson = strBuf.GetString();
+ return strJson;
+}
+
+void JsonReader::IterMap(std::function<void(const char*, Reader&)> fn)
+{
+ path_.push_back("0");
+ for (auto& entry : m_->GetObject())
+ {
+ auto saved = m_;
+ m_ = &(entry.value);
+
+ fn(entry.name.GetString(), *this);
+ m_ = saved;
+ }
+ path_.pop_back();
+}
+
+ void JsonReader::IterArray(std::function<void(Reader&)> fn)
+{
+ if (!m_->IsArray())
+ throw std::invalid_argument("array");
+ // Use "0" to indicate any element for now.
+ path_.push_back("0");
+ for (auto& entry : m_->GetArray())
+ {
+ auto saved = m_;
+ m_ = &entry;
+ fn(*this);
+ m_ = saved;
+ }
+ path_.pop_back();
+}
+
+void JsonReader::DoMember(const char* name, std::function<void(Reader&)> fn)
+{
+ path_.push_back(name);
+ auto it = m_->FindMember(name);
+ if (it != m_->MemberEnd())
+ {
+ auto saved = m_;
+ m_ = &it->value;
+ fn(*this);
+ m_ = saved;
+ }
+ path_.pop_back();
+}
+
+std::string JsonReader::GetPath() const
+{
+ std::string ret;
+ for (auto& t : path_)
+ {
+ ret += '/';
+ ret += t;
+ }
+ ret.pop_back();
+ return ret;
+}
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/serializer.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/serializer.h
new file mode 100644
index 0000000000..10456f40b5
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/serializer.h
@@ -0,0 +1,378 @@
+#pragma once
+
+
+#include <macro_map.h>
+#ifdef boost
+#include "optional.hpp"
+#else
+#include <boost/optional.hpp>
+#endif
+#include <cassert>
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <vector>
+#include <functional>
+#include <map>
+#include <algorithm>
+
+
+struct AbsolutePath;
+
+enum class SerializeFormat { Json, MessagePack };
+
+// A tag type that can be used to write `null` to json.
+struct JsonNull
+{
+ void swap(JsonNull& arg) noexcept;
+};
+
+
+
+class Reader {
+public:
+ virtual ~Reader() {}
+ virtual SerializeFormat Format() const = 0;
+
+ virtual bool IsBool() = 0;
+ virtual bool IsNull() = 0;
+ virtual bool IsArray() = 0;
+ virtual bool IsInt() = 0;
+ virtual bool IsInt64() = 0;
+ virtual bool IsUint64() = 0;
+ virtual bool IsDouble() = 0;
+ virtual bool IsNumber() = 0;
+ virtual bool IsString() = 0;
+
+ virtual void GetNull() = 0;
+ virtual bool GetBool() = 0;
+ virtual int GetInt() = 0;
+ virtual uint32_t GetUint32() = 0;
+ virtual int64_t GetInt64() = 0;
+ virtual uint64_t GetUint64() = 0;
+ virtual double GetDouble() = 0;
+ virtual std::string GetString() = 0;
+
+ virtual bool HasMember(const char* x) = 0;
+ virtual std::unique_ptr<Reader> operator[](const char* x) = 0;
+ virtual void IterMap( std::function<void(const char*, Reader&)> fn) = 0;
+ virtual void IterArray(std::function<void(Reader&)> fn) = 0;
+ virtual void DoMember(const char* name, std::function<void(Reader&)> fn) = 0;
+ virtual std::string ToString() const = 0;
+};
+
+
+
+class Writer {
+public:
+ virtual ~Writer() {}
+ virtual SerializeFormat Format() const = 0;
+
+ virtual void Null() = 0;
+ virtual void Bool(bool x) = 0;
+ virtual void Int(int x) = 0;
+ virtual void Uint32(uint32_t x) = 0;
+ virtual void Int64(int64_t x) = 0;
+ virtual void Uint64(uint64_t x) = 0;
+ virtual void Double(double x) = 0;
+ virtual void String(const char* x) = 0;
+ virtual void String(const char* x, size_t len) = 0;
+ virtual void StartArray(size_t) = 0;
+ virtual void EndArray() = 0;
+ virtual void StartObject() = 0;
+ virtual void EndObject() = 0;
+ virtual void Key(const char* name) = 0;
+};
+
+
+
+struct optionals_mandatory_tag {};
+
+#define REFLECT_MEMBER_START() ReflectMemberStart(visitor, value)
+#define REFLECT_MEMBER_END() ReflectMemberEnd(visitor, value);
+#define REFLECT_MEMBER_END1(value) ReflectMemberEnd(visitor, value);
+#define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name)
+#define REFLECT_MEMBER_OPTIONALS(name) \
+ ReflectMember(visitor, #name, value.name, optionals_mandatory_tag{})
+#define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value)
+
+#define MAKE_REFLECT_TYPE_PROXY(type_name) \
+ MAKE_REFLECT_TYPE_PROXY2(type_name, std::underlying_type<type_name>::type)
+#define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \
+ inline void Reflect(Reader& visitor, type& value) { \
+ as_type value0; \
+ ::Reflect(visitor, value0); \
+ value = static_cast<type>(value0); \
+ } \
+ inline void Reflect(Writer& visitor, type& value) { \
+ auto value0 = static_cast<as_type>(value); \
+ ::Reflect(visitor, value0); \
+ }
+
+#define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name);
+#define _MAPPABLE_REFLECT_MEMBER_OPTIONALS(name) REFLECT_MEMBER_OPTIONALS(name);
+
+#define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \
+ template <typename TVisitor> \
+ void Reflect(TVisitor& visitor, type& value) { \
+ REFLECT_MEMBER_START(); \
+ REFLECT_MEMBER_END(); \
+ }
+
+#define MAKE_REFLECT_STRUCT(type, ...) \
+ template <typename TVisitor> \
+ void Reflect(TVisitor& visitor, type& value) { \
+ REFLECT_MEMBER_START(); \
+ MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \
+ REFLECT_MEMBER_END(); \
+ }
+
+
+#define _MAPPABLE_SWAP_MEMBER(name) std::swap(name,arg.name);
+
+#define MAKE_SWAP_METHOD(type, ...) \
+void swap(type& arg) noexcept{ \
+ MACRO_MAP(_MAPPABLE_SWAP_MEMBER, __VA_ARGS__) \
+}
+
+#define MAKE_REFLECT_STRUCT_OPTIONALS_MANDATORY(type, ...) \
+ template <typename TVisitor> \
+ void Reflect(TVisitor& visitor, type& value) { \
+ REFLECT_MEMBER_START(); \
+ MACRO_MAP(_MAPPABLE_REFLECT_MEMBER_OPTIONALS, __VA_ARGS__) \
+ REFLECT_MEMBER_END(); \
+ }
+
+// clang-format off
+// Config has many fields, we need to support at least its number of fields.
+#define NUM_VA_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,N,...) N
+#define NUM_VA_ARGS(...) NUM_VA_ARGS_IMPL(__VA_ARGS__,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
+// clang-format on
+
+#define _MAPPABLE_REFLECT_ARRAY(name) Reflect(visitor, value.name);
+
+// Reflects the struct so it is serialized as an array instead of an object.
+// This currently only supports writers.
+#define MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(type, ...) \
+ inline void Reflect(Writer& visitor, type& value) { \
+ visitor.StartArray(NUM_VA_ARGS(__VA_ARGS__)); \
+ MACRO_MAP(_MAPPABLE_REFLECT_ARRAY, __VA_ARGS__) \
+ visitor.EndArray(); \
+ }
+
+//// Elementary types
+
+void Reflect(Reader& visitor, uint8_t& value);
+void Reflect(Writer& visitor, uint8_t& value);
+
+void Reflect(Reader& visitor, short& value);
+void Reflect(Writer& visitor, short& value);
+
+void Reflect(Reader& visitor, unsigned short& value);
+void Reflect(Writer& visitor, unsigned short& value);
+
+void Reflect(Reader& visitor, int& value);
+void Reflect(Writer& visitor, int& value);
+
+void Reflect(Reader& visitor, unsigned& value);
+void Reflect(Writer& visitor, unsigned& value);
+
+void Reflect(Reader& visitor, long& value);
+void Reflect(Writer& visitor, long& value);
+
+void Reflect(Reader& visitor, unsigned long& value);
+void Reflect(Writer& visitor, unsigned long& value);
+
+void Reflect(Reader& visitor, long long& value);
+void Reflect(Writer& visitor, long long& value);
+
+void Reflect(Reader& visitor, unsigned long long& value);
+void Reflect(Writer& visitor, unsigned long long& value);
+
+void Reflect(Reader& visitor, double& value);
+void Reflect(Writer& visitor, double& value);
+
+void Reflect(Reader& visitor, bool& value);
+void Reflect(Writer& visitor, bool& value);
+
+void Reflect(Reader& visitor, std::string& value);
+void Reflect(Writer& visitor, std::string& value);
+
+void Reflect(Reader& visitor, JsonNull& value);
+void Reflect(Writer& visitor, JsonNull& value);
+
+void Reflect(Reader& visitor, SerializeFormat& value);
+void Reflect(Writer& visitor, SerializeFormat& value);
+
+//// Type constructors
+
+template <typename T>
+void Reflect(Reader& visitor, boost::optional<T>& value) {
+ if (visitor.IsNull()) {
+ visitor.GetNull();
+ return;
+ }
+ T real_value;
+ Reflect(visitor, real_value);
+ value = std::move(real_value);
+}
+template <typename T>
+void Reflect(Writer& visitor, boost::optional<T>& value) {
+ if (value)
+ Reflect(visitor, *value);
+ else
+ visitor.Null();
+}
+
+
+template <typename T>
+void ReflectMember(Writer& visitor, const char* name, boost::optional<T>& value) {
+ // For TypeScript optional property key?: value in the spec,
+ // We omit both key and value if value is std::nullopt (null) for JsonWriter
+ // to reduce output. But keep it for other serialization formats.
+ if (value || visitor.Format() != SerializeFormat::Json) {
+ visitor.Key(name);
+ Reflect(visitor, value);
+ }
+}
+
+
+
+template <typename T>
+void ReflectMember(Writer& visitor,
+ const char* name,
+ T& value,
+ optionals_mandatory_tag) {
+ visitor.Key(name);
+ Reflect(visitor, value);
+}
+template <typename T>
+void ReflectMember(Reader& visitor,
+ const char* name,
+ T& value,
+ optionals_mandatory_tag) {
+ Reflect(visitor, value);
+}
+
+template<class T >
+void Reflect(Reader& visitor, std::map<std::string, T>& value)
+{
+ visitor.IterMap([&](const char* name,Reader& entry) {
+ T entry_value;
+ Reflect(entry, entry_value);
+ value[name]=(std::move(entry_value));
+ });
+}
+template<class _Ty >
+void Reflect(Writer& visitor, std::map<std::string, _Ty>& value)
+{
+ REFLECT_MEMBER_START();
+ for (auto& it : value)
+ {
+ visitor.Key(it.first.c_str());
+ Reflect(visitor, it.second);
+ }
+ REFLECT_MEMBER_END();
+}
+
+// std::vector
+template <typename T>
+void Reflect(Reader& visitor, std::vector<T>& values) {
+ visitor.IterArray([&](Reader& entry) {
+ T entry_value;
+ Reflect(entry, entry_value);
+ values.push_back(std::move(entry_value));
+ });
+}
+
+
+template <typename T>
+void Reflect(Writer& visitor, std::vector<T>& values) {
+ visitor.StartArray(values.size());
+ for (auto& value : values)
+ Reflect(visitor, value);
+ visitor.EndArray();
+}
+
+// ReflectMember
+
+inline void DefaultReflectMemberStart(Writer& visitor) {
+ visitor.StartObject();
+}
+inline void DefaultReflectMemberStart(Reader& visitor) {}
+
+template <typename T>
+bool ReflectMemberStart(Reader& visitor, T& value) {
+ return false;
+}
+template <typename T>
+bool ReflectMemberStart(Writer& visitor, T& value) {
+ visitor.StartObject();
+ return true;
+}
+
+template <typename T>
+void ReflectMemberEnd(Reader& visitor, T& value) {}
+template <typename T>
+void ReflectMemberEnd(Writer& visitor, T& value) {
+ visitor.EndObject();
+}
+
+template <typename T>
+void ReflectMember(Reader& visitor, const char* name, T& value) {
+ visitor.DoMember(name, [&](Reader& child) { Reflect(child, value); });
+}
+template <typename T>
+void ReflectMember(Writer& visitor, const char* name, T& value) {
+ visitor.Key(name);
+ Reflect(visitor, value);
+}
+
+template<class _Ty1, class _Ty2>
+void Reflect(Writer& visitor, std::pair< boost::optional<_Ty1>, boost::optional<_Ty2> >& value)
+{
+ if (value.first)
+ {
+ Reflect(visitor, value.first);
+ }
+ else
+ {
+ Reflect(visitor, value.second);
+ }
+}
+template<class _Ty2>
+void Reflect(Reader& visitor, std::pair< boost::optional<bool>, boost::optional<_Ty2> >& value)
+{
+ if(visitor.IsBool())
+ {
+ Reflect(visitor, value.first);
+ return;
+ }
+
+ Reflect(visitor, value.second);
+}
+template<class _Ty2>
+void Reflect(Reader& visitor, std::pair< boost::optional<std::string>, boost::optional<_Ty2> >& value)
+{
+ if (visitor.IsString())
+ {
+ Reflect(visitor, value.first);
+ return;
+ }
+
+ Reflect(visitor, value.second);
+}
+
+
+template<class _Ty1, class _Ty2>
+void Reflect(Reader& visitor, std::pair< boost::optional<_Ty1>, boost::optional<_Ty2> >& value)
+{
+ try
+ {
+ Reflect(visitor, value.second);
+ }
+ catch (...)
+ {
+ Reflect(visitor, value.first);
+ }
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/stream.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/stream.h
new file mode 100644
index 0000000000..549c361950
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/stream.h
@@ -0,0 +1,196 @@
+#pragma once
+#include <mutex>
+#include <string>
+namespace lsp
+{
+ class stream
+ {
+ public:
+ virtual ~stream() = default;
+ virtual bool fail() = 0;
+ virtual bool bad() = 0;
+ virtual bool eof() = 0;
+ virtual bool good() = 0;
+ virtual void clear() = 0;
+ virtual std::string what() = 0;
+ virtual bool need_to_clear_the_state()
+ {
+ return false;
+ }
+
+ bool operator!()
+ {
+ return bad();
+ }
+ };
+ class istream : public stream
+ {
+ public:
+ virtual int get() = 0;
+ virtual ~istream() = default;
+ virtual istream& read(char* str, std::streamsize count) = 0;
+ };
+ template <class T >
+ class base_istream : public istream
+ {
+ public:
+ explicit base_istream(T& _t) :_impl(_t)
+ {
+
+ }
+
+ int get() override
+ {
+ return _impl.get();
+ }
+ bool fail() override
+ {
+ return _impl.fail();
+ }
+ bool bad() override
+ {
+ return _impl.bad();
+ }
+ bool eof() override
+ {
+ return _impl.eof();
+ }
+ bool good() override
+ {
+ return _impl.good();
+ }
+ istream& read(char* str, std::streamsize count) override
+ {
+ _impl.read(str, count);
+ return *this;
+ }
+
+ void clear() override
+ {
+ _impl.clear();
+ }
+ T& _impl;
+ };
+ class ostream : public stream
+ {
+ public:
+ virtual ~ostream() = default;
+
+ virtual ostream& write(const std::string&) = 0;
+ virtual ostream& write(std::streamsize) = 0;
+ virtual ostream& flush() = 0;
+
+ };
+ template <class T >
+ class base_ostream : public ostream
+ {
+ public:
+ explicit base_ostream(T& _t) :_impl(_t)
+ {
+
+ }
+
+ bool fail() override
+ {
+ return _impl.fail();
+ }
+ bool good() override
+ {
+ return _impl.good();
+ }
+ bool bad() override
+ {
+ return _impl.bad();
+ }
+ bool eof() override
+ {
+ return _impl.eof();
+ }
+
+ ostream& write(const std::string& c) override
+ {
+ _impl << c;
+ return *this;
+ }
+
+ ostream& write(std::streamsize _s) override
+ {
+
+ _impl << std::to_string(_s);
+ return *this;
+ }
+
+ ostream& flush() override
+ {
+ _impl.flush();
+ return *this;
+ }
+
+ void clear() override
+ {
+ _impl.clear();
+ }
+ protected:
+ T& _impl;
+ };
+
+ template <class T >
+ class base_iostream : public istream, public ostream
+ {
+ public:
+ explicit base_iostream(T& _t) :_impl(_t)
+ {
+
+ }
+
+ int get() override
+ {
+ return _impl.get();
+ }
+ bool fail() override
+ {
+ return _impl.fail();
+ }
+ bool bad() override
+ {
+ return _impl.bad();
+ }
+ bool eof() override
+ {
+ return _impl.eof();
+ }
+ bool good() override
+ {
+ return _impl.good();
+ }
+ istream& read(char* str, std::streamsize count) override
+ {
+ _impl.read(str, count);
+ return *this;
+ }
+ ostream& write(const std::string& c) override
+ {
+ _impl << c;
+ return *this;
+ }
+
+ ostream& write(std::streamsize _s) override
+ {
+ _impl << std::to_string(_s);
+ return *this;
+ }
+
+ ostream& flush() override
+ {
+ _impl.flush();
+ return *this;
+ }
+
+ void clear() override
+ {
+ _impl.clear();
+ }
+ protected:
+ T& _impl;
+ };
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/threaded_queue.cpp b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/threaded_queue.cpp
new file mode 100644
index 0000000000..17e965eadf
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/threaded_queue.cpp
@@ -0,0 +1,20 @@
+#include "threaded_queue.h"
+
+// static
+bool MultiQueueWaiter::HasState(
+ std::initializer_list<BaseThreadQueue*> queues) {
+ for (BaseThreadQueue* queue : queues) {
+ if (!queue->IsEmpty())
+ return true;
+ }
+ return false;
+}
+
+bool MultiQueueWaiter::ValidateWaiter(
+ std::initializer_list<BaseThreadQueue*> queues) {
+ for (BaseThreadQueue* queue : queues) {
+ if (queue->waiter.get() != this)
+ return false;
+ }
+ return true;
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/threaded_queue.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/threaded_queue.h
new file mode 100644
index 0000000000..cca9f9a486
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/threaded_queue.h
@@ -0,0 +1,249 @@
+#pragma once
+
+#include <boost/optional/optional.hpp>
+#include <algorithm>
+#include <atomic>
+#include <condition_variable>
+#include <deque>
+#include <memory>
+#include <mutex>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+
+struct MultiQueueWaiter;
+
+struct BaseThreadQueue {
+ virtual ~BaseThreadQueue() = default;
+
+ virtual bool IsEmpty() = 0;
+
+ std::shared_ptr<MultiQueueWaiter> waiter;
+};
+
+// std::lock accepts two or more arguments. We define an overload for one
+// argument.
+namespace std {
+template <typename Lockable>
+void lock(Lockable& l) {
+ l.lock();
+}
+} // namespace std
+
+template <typename... Queue>
+struct MultiQueueLock {
+ MultiQueueLock(Queue... lockable) : tuple_{lockable...} { lock(); }
+ ~MultiQueueLock() { unlock(); }
+ void lock() { lock_impl(typename std::index_sequence_for<Queue...>{}); }
+ void unlock() { unlock_impl(typename std::index_sequence_for<Queue...>{}); }
+
+ private:
+ template <size_t... Is>
+ void lock_impl(std::index_sequence<Is...>) {
+ std::lock(std::get<Is>(tuple_)->mutex...);
+ }
+
+ template <size_t... Is>
+ void unlock_impl(std::index_sequence<Is...>) {
+ (void)std::initializer_list<int>{
+ (std::get<Is>(tuple_)->mutex.unlock(), 0)...};
+ }
+
+ std::tuple<Queue...> tuple_;
+};
+
+struct MultiQueueWaiter {
+ static bool HasState(std::initializer_list<BaseThreadQueue*> queues);
+
+ bool ValidateWaiter(std::initializer_list<BaseThreadQueue*> queues);
+
+ template <typename... BaseThreadQueue>
+ bool Wait(std::atomic<bool>& quit, BaseThreadQueue... queues) {
+ MultiQueueLock<BaseThreadQueue...> l(queues...);
+ while (!quit.load(std::memory_order_relaxed)) {
+ if (HasState({ queues... }))
+ return false;
+ cv.wait(l);
+ }
+ return true;
+ }
+ template <typename... BaseThreadQueue>
+ void WaitUntil(std::chrono::steady_clock::time_point t,
+ BaseThreadQueue... queues) {
+ MultiQueueLock<BaseThreadQueue...> l(queues...);
+ if (!HasState({ queues... }))
+ cv.wait_until(l, t);
+ }
+ template <typename... BaseThreadQueue>
+ void Wait(BaseThreadQueue... queues) {
+ assert(ValidateWaiter({queues...}));
+
+ MultiQueueLock<BaseThreadQueue...> l(queues...);
+ while (!HasState({queues...}))
+ cv.wait(l);
+ }
+
+ std::condition_variable_any cv;
+};
+
+// A threadsafe-queue. http://stackoverflow.com/a/16075550
+template <class T>
+struct ThreadedQueue : public BaseThreadQueue {
+ public:
+ ThreadedQueue() : ThreadedQueue(std::make_shared<MultiQueueWaiter>()) {}
+
+ explicit ThreadedQueue(std::shared_ptr<MultiQueueWaiter> waiter)
+ : total_count_(0) {
+ this->waiter = waiter;
+ }
+
+ // Returns the number of elements in the queue. This is lock-free.
+ size_t Size() const { return total_count_; }
+
+ // Add an element to the queue.
+ void Enqueue(T&& t, bool priority) {
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ if (priority)
+ priority_.push_back(std::move(t));
+ else
+ queue_.push_back(std::move(t));
+ ++total_count_;
+ }
+ waiter->cv.notify_one();
+ }
+
+ // Add a set of elements to the queue.
+ void EnqueueAll(std::vector<T>&& elements, bool priority) {
+ if (elements.empty())
+ return;
+
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ total_count_ += elements.size();
+ for (T& element : elements) {
+ if (priority)
+ priority_.push_back(std::move(element));
+ else
+ queue_.push_back(std::move(element));
+ }
+ elements.clear();
+ }
+
+ waiter->cv.notify_all();
+ }
+
+ // Returns true if the queue is empty. This is lock-free.
+ bool IsEmpty() { return total_count_ == 0; }
+
+ // Get the first element from the queue. Blocks until one is available.
+ T Dequeue() {
+ std::unique_lock<std::mutex> lock(mutex);
+ waiter->cv.wait(lock,
+ [&]() { return !priority_.empty() || !queue_.empty(); });
+
+ auto execute = [&](std::deque<T>* q) {
+ auto val = std::move(q->front());
+ q->pop_front();
+ --total_count_;
+ return std::move(val);
+ };
+ if (!priority_.empty())
+ return execute(&priority_);
+ return execute(&queue_);
+ }
+
+ // Get the first element from the queue without blocking. Returns a null
+ // value if the queue is empty.
+ boost::optional<T> TryDequeue(bool priority) {
+ std::lock_guard<std::mutex> lock(mutex);
+
+ auto pop = [&](std::deque<T>* q) {
+ auto val = std::move(q->front());
+ q->pop_front();
+ --total_count_;
+ return std::move(val);
+ };
+
+ auto get_result = [&](std::deque<T>* first,
+ std::deque<T>* second) -> boost::optional<T> {
+ if (!first->empty())
+ return pop(first);
+ if (!second->empty())
+ return pop(second);
+ return {};
+ };
+
+ if (priority)
+ return get_result(&priority_, &queue_);
+ return get_result(&queue_, &priority_);
+ }
+ // Return all elements in the queue.
+ std::vector<T> DequeueAll() {
+ std::lock_guard<std::mutex> lock(mutex);
+
+ total_count_ = 0;
+
+ std::vector<T> result;
+ result.reserve(priority_.size() + queue_.size());
+ while (!priority_.empty()) {
+ result.emplace_back(std::move(priority_.front()));
+ priority_.pop_front();
+ }
+ while (!queue_.empty()) {
+ result.emplace_back(std::move(queue_.front()));
+ queue_.pop_front();
+ }
+
+ return result;
+ }
+ std::vector<T> TryDequeueSome(size_t num) {
+ std::lock_guard<std::mutex> lock(mutex);
+
+ std::vector<T> result;
+ num = std::min(num, priority_.size() + queue_.size());
+ total_count_ -= num;
+ result.reserve(num);
+ while (num)
+ {
+ if(!priority_.empty()) {
+ result.emplace_back(std::move(priority_.front()));
+ priority_.pop_front();
+ }
+ else
+ {
+ break;
+ }
+ num -= 1;
+ }
+ while (num)
+ {
+ if (!queue_.empty()) {
+ result.emplace_back(std::move(queue_.front()));
+ queue_.pop_front();
+ }
+ else
+ {
+ break;
+ }
+ num -= 1;
+ }
+ return result;
+ }
+ template <typename Fn>
+ void Iterate(Fn fn) {
+ std::lock_guard<std::mutex> lock(mutex);
+ for (auto& entry : priority_)
+ fn(entry);
+ for (auto& entry : queue_)
+ fn(entry);
+ }
+
+ mutable std::mutex mutex;
+
+ private:
+ std::atomic<int> total_count_;
+ std::deque<T> priority_;
+ std::deque<T> queue_;
+};
diff --git a/graphics/asymptote/LspCpp/LibLsp/JsonRpc/traits.h b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/traits.h
new file mode 100644
index 0000000000..ce8905a840
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/JsonRpc/traits.h
@@ -0,0 +1,158 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+
+#include <tuple>
+#include <type_traits>
+
+namespace lsp {
+namespace traits {
+
+// NthTypeOf returns the `N`th type in `Types`
+template <int N, typename... Types>
+using NthTypeOf = typename std::tuple_element<N, std::tuple<Types...>>::type;
+
+// `IsTypeOrDerived<BASE, T>::value` is true iff `T` is of type `BASE`, or
+// derives from `BASE`.
+template <typename BASE, typename T>
+using IsTypeOrDerived = std::integral_constant<
+ bool,
+ std::is_base_of<BASE, typename std::decay<T>::type>::value ||
+ std::is_same<BASE, typename std::decay<T>::type>::value>;
+
+// `EachIsTypeOrDerived<N, BASES, TYPES>::value` is true iff all of the types in
+// the std::tuple `TYPES` is of, or derives from the corresponding indexed type
+// in the std::tuple `BASES`.
+// `N` must be equal to the number of types in both the std::tuple `BASES` and
+// `TYPES`.
+template <int N, typename BASES, typename TYPES>
+struct EachIsTypeOrDerived {
+ using base = typename std::tuple_element<N - 1, BASES>::type;
+ using type = typename std::tuple_element<N - 1, TYPES>::type;
+ using last_matches = IsTypeOrDerived<base, type>;
+ using others_match = EachIsTypeOrDerived<N - 1, BASES, TYPES>;
+ static constexpr bool value = last_matches::value && others_match::value;
+};
+
+// EachIsTypeOrDerived specialization for N = 1
+template <typename BASES, typename TYPES>
+struct EachIsTypeOrDerived<1, BASES, TYPES> {
+ using base = typename std::tuple_element<0, BASES>::type;
+ using type = typename std::tuple_element<0, TYPES>::type;
+ static constexpr bool value = IsTypeOrDerived<base, type>::value;
+};
+
+// EachIsTypeOrDerived specialization for N = 0
+template <typename BASES, typename TYPES>
+struct EachIsTypeOrDerived<0, BASES, TYPES> {
+ static constexpr bool value = true;
+};
+
+// Signature describes the signature of a function.
+template <typename RETURN, typename... PARAMETERS>
+struct Signature {
+ // The return type of the function signature
+ using ret = RETURN;
+ // The parameters of the function signature held in a std::tuple
+ using parameters = std::tuple<PARAMETERS...>;
+ // The type of the Nth parameter of function signature
+ template <std::size_t N>
+ using parameter = NthTypeOf<N, PARAMETERS...>;
+ // The total number of parameters
+ static constexpr std::size_t parameter_count = sizeof...(PARAMETERS);
+};
+
+// SignatureOf is a traits helper that infers the signature of the function,
+// method, static method, lambda, or function-like object `F`.
+template <typename F>
+struct SignatureOf {
+ // The signature of the function-like object `F`
+ using type = typename SignatureOf<decltype(&F::operator())>::type;
+};
+
+// SignatureOf specialization for a regular function or static method.
+template <typename R, typename... ARGS>
+struct SignatureOf<R (*)(ARGS...)> {
+ // The signature of the function-like object `F`
+ using type = Signature<typename std::decay<R>::type,
+ typename std::decay<ARGS>::type...>;
+};
+
+// SignatureOf specialization for a non-static method.
+template <typename R, typename C, typename... ARGS>
+struct SignatureOf<R (C::*)(ARGS...)> {
+ // The signature of the function-like object `F`
+ using type = Signature<typename std::decay<R>::type,
+ typename std::decay<ARGS>::type...>;
+};
+
+// SignatureOf specialization for a non-static, const method.
+template <typename R, typename C, typename... ARGS>
+struct SignatureOf<R (C::*)(ARGS...) const> {
+ // The signature of the function-like object `F`
+ using type = Signature<typename std::decay<R>::type,
+ typename std::decay<ARGS>::type...>;
+};
+
+// SignatureOfT is an alias to `typename SignatureOf<F>::type`.
+template <typename F>
+using SignatureOfT = typename SignatureOf<F>::type;
+
+// ParameterType is an alias to `typename SignatureOf<F>::type::parameter<N>`.
+template <typename F, std::size_t N>
+using ParameterType = typename SignatureOfT<F>::template parameter<N>;
+
+// `HasSignature<F, S>::value` is true iff the function-like `F` has a matching
+// signature to the function-like `S`.
+template <typename F, typename S>
+using HasSignature = std::integral_constant<
+ bool,
+ std::is_same<SignatureOfT<F>, SignatureOfT<S>>::value>;
+
+// `Min<A, B>::value` resolves to the smaller value of A and B.
+template <std::size_t A, std::size_t B>
+using Min = std::integral_constant<std::size_t, (A < B ? A : B)>;
+
+// `CompatibleWith<F, S>::value` is true iff the function-like `F`
+// can be called with the argument types of the function-like `S`. Return type
+// of the two functions are not considered.
+template <typename F, typename S>
+using CompatibleWith = std::integral_constant<
+ bool,
+ (SignatureOfT<S>::parameter_count == SignatureOfT<F>::parameter_count) &&
+ EachIsTypeOrDerived<Min<SignatureOfT<S>::parameter_count,
+ SignatureOfT<F>::parameter_count>::value,
+ typename SignatureOfT<S>::parameters,
+ typename SignatureOfT<F>::parameters>::value>;
+
+// If `CONDITION` is true then EnableIf resolves to type T, otherwise an
+// invalid type.
+template <bool CONDITION, typename T = void>
+using EnableIf = typename std::enable_if<CONDITION, T>::type;
+
+// If `BASE` is a base of `T` then EnableIfIsType resolves to type `TRUE`,
+// otherwise an invalid type.
+template <typename BASE, typename T, typename TRUE_ = void>
+using EnableIfIsType = EnableIf<IsTypeOrDerived<BASE, T>::value, TRUE_>;
+
+// If the function-like `F` has a matching signature to the function-like `S`
+// then EnableIfHasSignature resolves to type `TRUE`, otherwise an invalid type.
+template <typename F, typename S, typename TRUE_ = void>
+using EnableIfHasSignature = EnableIf<HasSignature<F, S>::value, TRUE_>;
+
+} // namespace traits
+} // namespace lsp
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/AbsolutePath.h b/graphics/asymptote/LspCpp/LibLsp/lsp/AbsolutePath.h
new file mode 100644
index 0000000000..ef1ee43860
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/AbsolutePath.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <LibLsp/JsonRpc/serializer.h>
+#include <string>
+
+struct AbsolutePath {
+ static AbsolutePath BuildDoNotUse(const std::string& path);
+
+ // Try not to use this.
+ AbsolutePath();
+
+ // Provide implicit conversions to std::string for the time being.
+ AbsolutePath(const std::string& path, bool validate = true);
+ operator std::string() const;
+
+ bool operator==(const AbsolutePath& rhs) const;
+ bool operator!=(const AbsolutePath& rhs) const;
+ bool operator<(const AbsolutePath& rhs) const;
+ bool operator>(const AbsolutePath& rhs) const;
+ std::string path;
+ bool qualify = true;
+};
+
+
+void Reflect(Reader& visitor, AbsolutePath& value);
+void Reflect(Writer& visitor, AbsolutePath& value);
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/ClientPreferences.h b/graphics/asymptote/LspCpp/LibLsp/lsp/ClientPreferences.h
new file mode 100644
index 0000000000..7adf557f83
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/ClientPreferences.h
@@ -0,0 +1,306 @@
+#pragma once
+#include <LibLsp/lsp/general/lsClientCapabilities.h>
+#include <LibLsp/lsp/utils.h>
+#include <memory>
+#include <vector>
+#include <string>
+
+class ClientPreferences
+{
+public:
+
+ std::shared_ptr<lsWorkspaceClientCapabilites> workspace;
+ lsTextDocumentClientCapabilities textDocument ;
+
+ ClientPreferences(const lsClientCapabilities& capabilities)
+ {
+ v3supported = capabilities.textDocument.has_value();
+ if (v3supported)
+ textDocument = capabilities.textDocument.value();
+ if(capabilities.workspace)
+ {
+ workspace = std::make_shared<lsWorkspaceClientCapabilites>(capabilities.workspace.value());
+ }
+ }
+
+ bool v3supported=false;
+
+ bool isSignatureHelpSupported() {
+
+ return v3supported && (textDocument.signatureHelp);
+ }
+ bool isWorkspaceDidChangeConfigurationSupported() const
+ {
+ return workspace && isDynamicRegistrationSupported(workspace->didChangeConfiguration);
+ }
+ bool isWorkspaceFoldersSupported() {
+ return workspace != nullptr && isTrue(workspace->workspaceFolders);
+ }
+
+ bool isCompletionDynamicRegistered() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.completion);
+ }
+
+ bool isCompletionSnippetsSupported() {
+ //@formatter:off
+ if(!v3supported || !textDocument.completion)
+ {
+ return false;
+ }
+ const auto& completion = textDocument.completion.value();
+ if(completion.completionItem)
+ {
+ return isTrue(completion.completionItem.value().snippetSupport);
+ }
+ return false;
+ }
+
+ bool isV3Supported() {
+ return v3supported;
+ }
+
+ bool isFormattingDynamicRegistrationSupported() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.formatting);
+ }
+
+ bool isRangeFormattingDynamicRegistrationSupported() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.rangeFormatting);
+ }
+
+ bool isOnTypeFormattingDynamicRegistrationSupported() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.onTypeFormatting);
+ }
+
+ bool isCodeLensDynamicRegistrationSupported() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.codeLens);
+ }
+
+ bool isSignatureHelpDynamicRegistrationSupported() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.signatureHelp);
+ }
+ template<typename T>
+ static bool isDynamicRegistrationSupported(boost::optional<T>& capability)
+ {
+ if(capability)
+ return (capability.value().dynamicRegistration.value());
+ return false;
+ }
+
+ bool isTrue(const boost::optional<bool>& value)
+ {
+ return value.get_value_or(false);
+ }
+
+ bool isRenameDynamicRegistrationSupported() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.rename);
+ }
+
+ bool isExecuteCommandDynamicRegistrationSupported() {
+ return v3supported && workspace != nullptr && isDynamicRegistrationSupported(workspace->executeCommand);
+ }
+
+ bool isWorkspaceSymbolDynamicRegistered() {
+ return v3supported && workspace != nullptr && isDynamicRegistrationSupported(workspace->symbol);
+ }
+
+ bool isWorkspaceChangeWatchedFilesDynamicRegistered() {
+ return v3supported && workspace != nullptr && isDynamicRegistrationSupported(workspace->didChangeWatchedFiles);
+ }
+
+ bool isDocumentSymbolDynamicRegistered() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.documentSymbol);
+ }
+
+ bool isCodeActionDynamicRegistered() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.codeAction);
+ }
+
+ bool isDefinitionDynamicRegistered() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.definition);
+ }
+
+ bool isTypeDefinitionDynamicRegistered() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.typeDefinition);
+ }
+
+ bool isHoverDynamicRegistered() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.hover);
+ }
+
+ bool isReferencesDynamicRegistered() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.references);
+ }
+
+ bool isDocumentHighlightDynamicRegistered() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.documentHighlight);
+ }
+
+ bool isFoldgingRangeDynamicRegistered() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.foldingRange);
+ }
+
+ bool isImplementationDynamicRegistered() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.implementation);
+ }
+
+ bool isSelectionRangeDynamicRegistered() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.selectionRange);
+ }
+
+ bool isWillSaveRegistered() {
+ return v3supported && isTrue(textDocument.synchronization.willSave);
+ }
+
+ bool isWillSaveWaitUntilRegistered() {
+ return v3supported && isTrue(textDocument.synchronization.willSaveWaitUntil);
+ }
+
+ bool isWorkspaceApplyEditSupported() {
+ return workspace != nullptr && isTrue(workspace->applyEdit);
+ }
+
+ bool isSupportsCompletionDocumentationMarkdown() {
+
+ if (!v3supported || !textDocument.completion)
+ {
+ return false;
+ }
+ const auto& completion = textDocument.completion.value();
+ if (completion.completionItem)
+ {
+ auto& documentationFormat = completion.completionItem.value().documentationFormat;
+ if(documentationFormat)
+ {
+ auto& data = documentationFormat.value();
+ for(auto& it : data)
+ {
+ if(it == "markdown")
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+
+ }
+
+
+ bool isWorkspaceEditResourceChangesSupported() {
+ if(!workspace) return false;
+
+ if(workspace->workspaceEdit)
+ {
+ return isTrue(workspace->workspaceEdit.value().resourceChanges);
+ }
+ return false;
+ }
+ static bool contains(const std::vector<std::string>& v, const std::string& target)
+ {
+ for(auto& it : v)
+ {
+ if(it == target) return true;
+ }
+ return false;
+ }
+ bool isResourceOperationSupported() const
+ {
+ if (!workspace) return false;
+ if (!workspace->workspaceEdit)
+ {
+ return false;
+ }
+ auto& it = (workspace->workspaceEdit.value());
+ if(!it.resourceOperations) return false;
+ const auto& resourceOperations = it.resourceOperations.value();
+ return contains(resourceOperations, "create") && contains(resourceOperations, "rename") && contains(resourceOperations, "delete");
+
+ }
+
+ /**
+ * {@code true} if the client has explicitly set the
+ * {@code textDocument.documentSymbol.hierarchicalDocumentSymbolSupport} to
+ * {@code true} when initializing the LS. Otherwise, {@code false}.
+ */
+ bool isHierarchicalDocumentSymbolSupported() {
+ if(!v3supported || !textDocument.documentSymbol) return false;
+ return isTrue(textDocument.documentSymbol.value().hierarchicalDocumentSymbolSupport);
+
+ }
+
+ bool isSemanticHighlightingSupported() {
+ //@formatter:off
+ if (!v3supported || !textDocument.semanticHighlightingCapabilities) return false;
+ return isTrue(textDocument.semanticHighlightingCapabilities.value().semanticHighlighting);
+ //@formatter:on
+ }
+
+ /**
+ * {@code true} if the client has explicitly set the
+ * {@code textDocument.codeAction.codeActionLiteralSupport.codeActionKind.valueSet}
+ * value. Otherwise, {@code false}.
+ */
+ bool isSupportedCodeActionKind(const std::string& kind) {
+ if (!v3supported || !textDocument.codeAction) return false;
+ //@formatter:off
+ const auto& codeAction = textDocument.codeAction.value();
+ if(codeAction.codeActionLiteralSupport)
+ {
+ const auto& codeActionKind = codeAction.codeActionLiteralSupport.value().codeActionKind;
+ if(codeActionKind)
+ {
+ const auto& valueSet = codeActionKind.value().valueSet;
+ if(valueSet)
+ {
+ for(auto& k : valueSet.value())
+ {
+ if(lsp::StartsWith(kind,k))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+
+ //@formatter:on
+ }
+
+ /**
+ * {@code true} if the client has explicitly set the
+ * {@code textDocument.publishDiagnostics.tagSupport} to
+ * {@code true} when initializing the LS. Otherwise, {@code false}.
+ */
+ bool isDiagnosticTagSupported() {
+ if (!v3supported || !textDocument.publishDiagnostics) return false;
+ const auto& publishDiagnostics = textDocument.publishDiagnostics.value();
+ if(publishDiagnostics.tagSupport)
+ {
+ isTagSupported(publishDiagnostics.tagSupport);
+ }
+ return false;
+ }
+
+ bool isTagSupported(const boost::optional < std::pair<boost::optional<bool>,
+ boost::optional<DiagnosticsTagSupport> > >& tagSupport) {
+ if(tagSupport)
+ {
+ auto &v = tagSupport.value();
+ if (v.first)
+ {
+ return v.first.value();
+ }
+ if (v.second) {
+ return !v.second.value().valueSet.empty();
+ }
+ }
+ return false;
+ }
+
+ bool isCallHierarchyDynamicRegistered() {
+ return v3supported && isDynamicRegistrationSupported(textDocument.callHierarchy);
+ }
+
+};
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/CodeActionParams.h b/graphics/asymptote/LspCpp/LibLsp/lsp/CodeActionParams.h
new file mode 100644
index 0000000000..a1e3f1dcc1
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/CodeActionParams.h
@@ -0,0 +1,114 @@
+#pragma once
+#include "LibLsp/lsp/method_type.h"
+#include "LibLsp/JsonRpc/message.h"
+#include "LibLsp/lsp/lsp_diagnostic.h"
+#include "LibLsp/lsp/workspace/execute_command.h"
+#include "LibLsp/lsp/lsTextDocumentIdentifier.h"
+#include "LibLsp/lsp/lsCodeAction.h"
+namespace JDT
+{
+ namespace CodeActionKind {
+
+
+ /**
+ * Base kind for quickfix actions: 'quickfix'
+ */
+ extern const char* QuickFix;
+
+ /**
+ * Base kind for refactoring actions: 'refactor'
+ */
+ extern const char* Refactor;
+
+ /**
+ * Base kind for refactoring extraction actions: 'refactor.extract'
+ *
+ * Example extract actions:
+ *
+ * - Extract method - Extract function - Extract variable - Extract interface
+ * from class - ...
+ */
+ extern const char* RefactorExtract;
+
+ /**
+ * Base kind for refactoring inline actions: 'refactor.inline'
+ *
+ * Example inline actions:
+ *
+ * - Inline function - Inline variable - Inline constant - ...
+ */
+ extern const char* RefactorInline;
+
+ /**
+ * Base kind for refactoring rewrite actions: 'refactor.rewrite'
+ *
+ * Example rewrite actions:
+ *
+ * - Convert JavaScript function to class - Add or remove parameter -
+ * Encapsulate field - Make method static - Move method to base class - ...
+ */
+ extern const char* RefactorRewrite;
+
+ /**
+ * Base kind for source actions: `source`
+ *
+ * Source code actions apply to the entire file.
+ */
+ extern const char* Source ;
+
+ /**
+ * Base kind for an organize imports source action: `source.organizeImports`
+ */
+ extern const char* SourceOrganizeImports;
+
+ extern const char* COMMAND_ID_APPLY_EDIT;
+ };
+
+
+}
+struct lsCodeActionContext {
+ // An array of diagnostics.
+ std::vector<lsDiagnostic> diagnostics;
+ /**
+ * Requested kind of actions to return.
+ *
+ * Actions not of this kind are filtered out by the client before being shown. So servers
+ * can omit computing them.
+ *
+ * See {@link CodeActionKind} for allowed values.
+ */
+ boost::optional<std::vector<std::string>> only;
+
+ MAKE_SWAP_METHOD(lsCodeActionContext,
+ diagnostics, only);
+};
+MAKE_REFLECT_STRUCT(lsCodeActionContext,
+ diagnostics, only);
+
+
+// Params for the CodeActionRequest
+struct lsCodeActionParams {
+ // The document in which the command was invoked.
+ lsTextDocumentIdentifier textDocument;
+ // The range for which the command was invoked.
+ lsRange range;
+ // Context carrying additional information.
+ lsCodeActionContext context;
+
+ MAKE_SWAP_METHOD(lsCodeActionParams,
+ textDocument,
+ range,
+ context);
+};
+MAKE_REFLECT_STRUCT(lsCodeActionParams,
+ textDocument,
+ range,
+ context);
+
+
+
+
+
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/Directory.h b/graphics/asymptote/LspCpp/LibLsp/lsp/Directory.h
new file mode 100644
index 0000000000..93f2c0807d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/Directory.h
@@ -0,0 +1,13 @@
+#pragma once
+#include <string>
+
+struct AbsolutePath;
+
+struct Directory {
+ explicit Directory(const AbsolutePath& path);
+
+ bool operator==(const Directory& rhs) const;
+ bool operator!=(const Directory& rhs) const;
+
+ std::string path;
+};
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/ExecuteCommandParams.h b/graphics/asymptote/LspCpp/LibLsp/lsp/ExecuteCommandParams.h
new file mode 100644
index 0000000000..c06eed4b1c
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/ExecuteCommandParams.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "lsAny.h"
+struct ExecuteCommandParams {
+ /**
+ * The identifier of the actual command handler.
+ */
+
+ std::string command;
+
+ /**
+ * Arguments that the command should be invoked with.
+ * The arguments are typically specified when a command is returned from the server to the client.
+ * Example requests that return a command are textDocument/codeAction or textDocument/codeLens.
+ */
+ boost::optional<std::vector<lsp::Any>> arguments;
+
+ MAKE_SWAP_METHOD(ExecuteCommandParams, command, arguments);
+};
+MAKE_REFLECT_STRUCT(ExecuteCommandParams,command,arguments)
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/IProgressMonitor.h b/graphics/asymptote/LspCpp/LibLsp/lsp/IProgressMonitor.h
new file mode 100644
index 0000000000..bf1337e44f
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/IProgressMonitor.h
@@ -0,0 +1,145 @@
+#pragma once
+
+
+#include <string>
+namespace lsp {
+/**
+ * The <code>IProgressMonitor</code> interface is implemented
+ * by objects that monitor the progress of an activity; the methods
+ * in this interface are invoked by code that performs the activity.
+ * <p>
+ * All activity is broken down into a linear sequence of tasks against
+ * which progress is reported. When a task begins, a <code>beginTask(const wstring&, int)
+ * </code> notification is reported, followed by any number and mixture of
+ * progress reports (<code>worked()</code>) and subtask notifications
+ * (<code>subTask(const wstring&)</code>). When the task is eventually completed, a
+ * <code>done()</code> notification is reported. After the <code>done()</code>
+ * notification, the progress monitor cannot be reused; i.e., <code>
+ * beginTask(const wstring&, int)</code> cannot be called again after the call to
+ * <code>done()</code>.
+ * </p>
+ * <p>
+ * A request to cancel an operation can be signaled using the
+ * <code>setCanceled</code> method. Operations taking a progress
+ * monitor are expected to poll the monitor (using <code>isCanceled</code>)
+ * periodically and abort at their earliest convenience. Operation can however
+ * choose to ignore cancelation requests.
+ * </p>
+ * <p>
+ * Since notification is synchronous with the activity itself, the listener should
+ * provide a fast and robust implementation. If the handling of notifications would
+ * involve blocking operations, or operations which might throw uncaught exceptions,
+ * the notifications should be queued, and the actual processing deferred (or perhaps
+ * delegated to a separate thread).
+ * </p>
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ */
+ class IProgressMonitor {
+ public:
+ virtual ~IProgressMonitor()
+ {
+ }
+
+ /** Constant indicating an unknown amount of work.
+ */
+
+ const static int UNKNOWN = -1;
+
+ /**
+ * Notifies that the main task is beginning. This must only be called once
+ * on a given progress monitor instance.
+ *
+ * @param name the name (or description) of the main task
+ * @param totalWork the total number of work units into which
+ * the main task is been subdivided. If the value is <code>UNKNOWN</code>
+ * the implemenation is free to indicate progress in a way which
+ * doesn't require the total number of work units in advance.
+ */
+ virtual void beginTask(void* , int totalWork)
+ {
+
+ };
+ /**
+ * Notifies that the work is done; that is, either the main task is completed
+ * or the user canceled it. This method may be called more than once
+ * (implementations should be prepared to handle this case).
+ */
+
+ virtual void endTask(void*, int totalWork)
+ {
+
+ }
+
+ virtual void done(void*) = 0;
+
+ /**
+ * Internal method to handle scaling correctly. This method
+ * must not be called by a client. Clients should
+ * always use the method </code>worked(int)</code>.
+ */
+ virtual void internalWorked(double work)
+ {
+
+ }
+ /**
+ * Returns whether cancelation of current operation has been requested.
+ * Long-running operations should poll to see if cancelation
+ * has been requested.
+ *
+ * @return <code>true</code> if cancellation has been requested,
+ * and <code>false</code> otherwise
+ * @see #setCanceled
+ */
+ virtual bool isCanceled() = 0;
+ /**
+ * Sets the cancel state to the given value.
+ *
+ * @param value <code>true</code> indicates that cancelation has
+ * been requested (but not necessarily acknowledged);
+ * <code>false</code> clears this flag
+ *
+ * @see #isCanceled
+ */
+ virtual void setCanceled(bool value) = 0;
+ /**
+ * Sets the task name to the given value. This method is used to
+ * restore the task label after a nested operation was executed.
+ * Normally there is no need for clients to call this method.
+ *
+ * @param name the name (or description) of the main task
+ * @see #beginTask(java.lang.const wstring&, int)
+ */
+ virtual void setTaskName(void*)
+ {
+
+ };
+ /**
+ * Notifies that a subtask of the main task is beginning.
+ * Subtasks are optional; the main task might not have subtasks.
+ *
+ * @param name the name (or description) of the subtask
+ */
+ virtual void subTask(void* )
+ {
+
+ }
+ /**
+ * Notifies that a given number of work unit of the main task
+ * has been completed. Note that this amount represents an
+ * installment, as opposed to a cumulative amount of work done
+ * to date.
+ *
+ * @param work the number of work units just completed
+ */
+ virtual void worked(int work)
+ {
+
+ };
+
+ virtual void catch_exception(void*) = 0;
+ };
+}
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/Markup/Markup.cpp b/graphics/asymptote/LspCpp/LibLsp/lsp/Markup/Markup.cpp
new file mode 100644
index 0000000000..f65f8ad3ce
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/Markup/Markup.cpp
@@ -0,0 +1,942 @@
+//===--- Markup.cpp -----------------------------------------*- C++-*------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://lsp.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "Markup.h"
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <memory>
+#include <string>
+#include <vector>
+#include <boost/algorithm/string.hpp>
+
+namespace lsp {
+
+ /// hexdigit - Return the hexadecimal character for the
+ /// given number \p X (which should be less than 16).
+ inline char hexdigit(unsigned X, bool LowerCase = false) {
+ const char HexChar = LowerCase ? 'a' : 'A';
+ return X < 10 ? '0' + X : HexChar + X - 10;
+ }
+
+ /// Given an array of c-style strings terminated by a null pointer, construct
+ /// a vector of StringRefs representing the same strings without the terminating
+ /// null string.
+ inline std::vector< std::string_ref> toStringRefArray(const char* const* Strings) {
+ std::vector< std::string_ref> Result;
+ while (*Strings)
+ Result.push_back(*Strings++);
+ return Result;
+ }
+
+ /// Construct a string ref from a boolean.
+ inline std::string_ref toStringRef(bool B) { return std::string_ref(B ? "true" : "false"); }
+
+ /// Construct a string ref from an array ref of unsigned chars.
+ inline std::string_ref toStringRef(const std::vector<uint8_t>& Input) {
+ return std::string_ref(Input.begin(), Input.end());
+ }
+
+ /// Construct a string ref from an array ref of unsigned chars.
+ inline std::vector<uint8_t> arrayRefFromStringRef(const std::string_ref& Input) {
+ return { Input.begin(), Input.end() };
+ }
+
+ /// Interpret the given character \p C as a hexadecimal digit and return its
+ /// value.
+ ///
+ /// If \p C is not a valid hex digit, -1U is returned.
+ inline unsigned hexDigitValue(char C) {
+ struct HexTable {
+ unsigned LUT[255] = {};
+ constexpr HexTable() {
+ // Default initialize everything to invalid.
+ for (int i = 0; i < 255; ++i)
+ LUT[i] = ~0U;
+ // Initialize `0`-`9`.
+ for (int i = 0; i < 10; ++i)
+ LUT['0' + i] = i;
+ // Initialize `A`-`F` and `a`-`f`.
+ for (int i = 0; i < 6; ++i)
+ LUT['A' + i] = LUT['a' + i] = 10 + i;
+ }
+ };
+ constexpr HexTable Table;
+ return Table.LUT[static_cast<unsigned char>(C)];
+ }
+
+ /// Checks if character \p C is one of the 10 decimal digits.
+ inline bool isDigit(char C) { return C >= '0' && C <= '9'; }
+
+ /// Checks if character \p C is a hexadecimal numeric character.
+ inline bool isHexDigit(char C) { return hexDigitValue(C) != ~0U; }
+
+ /// Checks if character \p C is a valid letter as classified by "C" locale.
+ inline bool isAlpha(char C) {
+ return ('a' <= C && C <= 'z') || ('A' <= C && C <= 'Z');
+ }
+
+ /// Checks whether character \p C is either a decimal digit or an uppercase or
+ /// lowercase letter as classified by "C" locale.
+ inline bool isAlnum(char C) { return isAlpha(C) || isDigit(C); }
+
+ /// Checks whether character \p C is valid ASCII (high bit is zero).
+ inline bool isASCII(char C) { return static_cast<unsigned char>(C) <= 127; }
+
+ /// Checks whether all characters in S are ASCII.
+ inline bool isASCII(std::string_ref S) {
+ for (char C : S)
+ {
+ if(!isASCII(C))return true;
+ }
+ return true;
+ }
+
+ /// Checks whether character \p C is printable.
+ ///
+ /// Locale-independent version of the C standard library isprint whose results
+ /// may differ on different platforms.
+ inline bool isPrint(char C) {
+ unsigned char UC = static_cast<unsigned char>(C);
+ return (0x20 <= UC) && (UC <= 0x7E);
+ }
+
+ /// Checks whether character \p C is whitespace in the "C" locale.
+ ///
+ /// Locale-independent version of the C standard library isspace.
+ inline bool isSpace(char C) {
+ return C == ' ' || C == '\f' || C == '\n' || C == '\r' || C == '\t' ||
+ C == '\v';
+ }
+
+ /// Returns the corresponding lowercase character if \p x is uppercase.
+ inline char toLower(char x) {
+ if (x >= 'A' && x <= 'Z')
+ return x - 'A' + 'a';
+ return x;
+ }
+
+ /// Returns the corresponding uppercase character if \p x is lowercase.
+ inline char toUpper(char x) {
+ if (x >= 'a' && x <= 'z')
+ return x - 'a' + 'A';
+ return x;
+ }
+
+ inline std::string utohexstr(uint64_t X, bool LowerCase = false) {
+ char Buffer[17];
+ char* BufPtr = std::end(Buffer);
+
+ if (X == 0) *--BufPtr = '0';
+
+ while (X) {
+ unsigned char Mod = static_cast<unsigned char>(X) & 15;
+ *--BufPtr = hexdigit(Mod, LowerCase);
+ X >>= 4;
+ }
+
+ return std::string(BufPtr, std::end(Buffer));
+ }
+
+ /// Convert buffer \p Input to its hexadecimal representation.
+ /// The returned string is double the size of \p Input.
+ inline std::string toHex( std::string_ref Input, bool LowerCase = false) {
+ static const char* const LUT = "0123456789ABCDEF";
+ const uint8_t Offset = LowerCase ? 32 : 0;
+ size_t Length = Input.size();
+
+ std::string Output;
+ Output.reserve(2 * Length);
+ for (size_t i = 0; i < Length; ++i) {
+ const unsigned char c = Input[i];
+ Output.push_back(LUT[c >> 4] | Offset);
+ Output.push_back(LUT[c & 15] | Offset);
+ }
+ return Output;
+ }
+
+ inline std::string toHex(std::vector<uint8_t> Input, bool LowerCase = false) {
+ return toHex(toStringRef(Input), LowerCase);
+ }
+
+ /// Store the binary representation of the two provided values, \p MSB and
+ /// \p LSB, that make up the nibbles of a hexadecimal digit. If \p MSB or \p LSB
+ /// do not correspond to proper nibbles of a hexadecimal digit, this method
+ /// returns false. Otherwise, returns true.
+ inline bool tryGetHexFromNibbles(char MSB, char LSB, uint8_t& Hex) {
+ unsigned U1 = hexDigitValue(MSB);
+ unsigned U2 = hexDigitValue(LSB);
+ if (U1 == ~0U || U2 == ~0U)
+ return false;
+
+ Hex = static_cast<uint8_t>((U1 << 4) | U2);
+ return true;
+ }
+
+ /// Return the binary representation of the two provided values, \p MSB and
+ /// \p LSB, that make up the nibbles of a hexadecimal digit.
+ inline uint8_t hexFromNibbles(char MSB, char LSB) {
+ uint8_t Hex = 0;
+ bool GotHex = tryGetHexFromNibbles(MSB, LSB, Hex);
+ (void)GotHex;
+ assert(GotHex && "MSB and/or LSB do not correspond to hex digits");
+ return Hex;
+ }
+
+ /// Convert hexadecimal string \p Input to its binary representation and store
+ /// the result in \p Output. Returns true if the binary representation could be
+ /// converted from the hexadecimal string. Returns false if \p Input contains
+ /// non-hexadecimal digits. The output string is half the size of \p Input.
+ inline bool tryGetFromHex( std::string_ref Input, std::string& Output) {
+ if (Input.empty())
+ return true;
+
+ Output.reserve((Input.size() + 1) / 2);
+ if (Input.size() % 2 == 1) {
+ uint8_t Hex = 0;
+ if (!tryGetHexFromNibbles('0', Input.front(), Hex))
+ return false;
+
+ Output.push_back(Hex);
+ Input = Input.drop_front();
+ }
+
+ assert(Input.size() % 2 == 0);
+ while (!Input.empty()) {
+ uint8_t Hex = 0;
+ if (!tryGetHexFromNibbles(Input[0], Input[1], Hex))
+ return false;
+
+ Output.push_back(Hex);
+ Input = Input.drop_front(2);
+ }
+ return true;
+ }
+
+ /// Convert hexadecimal string \p Input to its binary representation.
+ /// The return string is half the size of \p Input.
+ inline std::string fromHex( std::string_ref Input) {
+ std::string Hex;
+ bool GotHex = tryGetFromHex(Input, Hex);
+ (void)GotHex;
+ assert(GotHex && "Input contains non hex digits");
+ return Hex;
+ }
+
+
+
+ inline std::string utostr(uint64_t X, bool isNeg = false) {
+ char Buffer[21];
+ char* BufPtr = std::end(Buffer);
+
+ if (X == 0) *--BufPtr = '0'; // Handle special case...
+
+ while (X) {
+ *--BufPtr = '0' + char(X % 10);
+ X /= 10;
+ }
+
+ if (isNeg) *--BufPtr = '-'; // Add negative sign...
+ return std::string(BufPtr, std::end(Buffer));
+ }
+
+ inline std::string itostr(int64_t X) {
+ if (X < 0)
+ return utostr(static_cast<uint64_t>(1) + ~static_cast<uint64_t>(X), true);
+ else
+ return utostr(static_cast<uint64_t>(X));
+ }
+
+ /// StrInStrNoCase - Portable version of strcasestr. Locates the first
+ /// occurrence of string 's1' in string 's2', ignoring case. Returns
+ /// the offset of s2 in s1 or npos if s2 cannot be found.
+ std::string_ref::size_type StrInStrNoCase( std::string_ref s1, std::string_ref s2);
+
+ /// getToken - This function extracts one token from source, ignoring any
+ /// leading characters that appear in the Delimiters string, and ending the
+ /// token at any of the characters that appear in the Delimiters string. If
+ /// there are no tokens in the source string, an empty string is returned.
+ /// The function returns a pair containing the extracted token and the
+ /// remaining tail string.
+ std::pair< std::string_ref, std::string_ref> getToken( std::string_ref Source,
+ std::string_ref Delimiters = " \t\n\v\f\r");
+
+
+
+ /// Returns the English suffix for an ordinal integer (-st, -nd, -rd, -th).
+ inline std::string_ref getOrdinalSuffix(unsigned Val) {
+ // It is critically important that we do this perfectly for
+ // user-written sequences with over 100 elements.
+ switch (Val % 100) {
+ case 11:
+ case 12:
+ case 13:
+ return "th";
+ default:
+ switch (Val % 10) {
+ case 1: return "st";
+ case 2: return "nd";
+ case 3: return "rd";
+ default: return "th";
+ }
+ }
+ }
+
+ namespace detail {
+
+ template <typename IteratorT>
+ inline std::string join_impl(IteratorT Begin, IteratorT End,
+ std::string_ref Separator, std::input_iterator_tag) {
+ std::string S;
+ if (Begin == End)
+ return S;
+
+ S += (*Begin);
+ while (++Begin != End) {
+ S += Separator;
+ S += (*Begin);
+ }
+ return S;
+ }
+
+ template <typename IteratorT>
+ inline std::string join_impl(IteratorT Begin, IteratorT End,
+ std::string_ref Separator, std::forward_iterator_tag) {
+ std::string S;
+ if (Begin == End)
+ return S;
+
+ size_t Len = (std::distance(Begin, End) - 1) * Separator.size();
+ for (IteratorT I = Begin; I != End; ++I)
+ Len += (*I).size();
+ S.reserve(Len);
+ size_t PrevCapacity = S.capacity();
+ (void)PrevCapacity;
+ S += (*Begin);
+ while (++Begin != End) {
+ S += Separator;
+ S += (*Begin);
+ }
+ assert(PrevCapacity == S.capacity() && "String grew during building");
+ return S;
+ }
+
+ template <typename Sep>
+ inline void join_items_impl(std::string& Result, Sep Separator) {}
+
+ template <typename Sep, typename Arg>
+ inline void join_items_impl(std::string& Result, Sep Separator,
+ const Arg& Item) {
+ Result += Item;
+ }
+
+ template <typename Sep, typename Arg1, typename... Args>
+ inline void join_items_impl(std::string& Result, Sep Separator, const Arg1& A1,
+ Args &&... Items) {
+ Result += A1;
+ Result += Separator;
+ join_items_impl(Result, Separator, std::forward<Args>(Items)...);
+ }
+
+ inline size_t join_one_item_size(char) { return 1; }
+ inline size_t join_one_item_size(const char* S) { return S ? ::strlen(S) : 0; }
+
+ template <typename T> inline size_t join_one_item_size(const T& Str) {
+ return Str.size();
+ }
+
+ inline size_t join_items_size() { return 0; }
+
+ template <typename A1> inline size_t join_items_size(const A1& A) {
+ return join_one_item_size(A);
+ }
+ template <typename A1, typename... Args>
+ inline size_t join_items_size(const A1& A, Args &&... Items) {
+ return join_one_item_size(A) + join_items_size(std::forward<Args>(Items)...);
+ }
+
+ } // end namespace detail
+
+ /// Joins the strings in the range [Begin, End), adding Separator between
+ /// the elements.
+ template <typename IteratorT>
+ inline std::string join(IteratorT Begin, IteratorT End, std::string_ref Separator) {
+ using tag = typename std::iterator_traits<IteratorT>::iterator_category;
+ return detail::join_impl(Begin, End, Separator, tag());
+ }
+
+ /// Joins the strings in the range [R.begin(), R.end()), adding Separator
+ /// between the elements.
+ template <typename Range>
+ inline std::string join(Range&& R, std::string_ref Separator) {
+ return join(R.begin(), R.end(), Separator);
+ }
+
+ /// Joins the strings in the parameter pack \p Items, adding \p Separator
+ /// between the elements. All arguments must be implicitly convertible to
+ /// std::string, or there should be an overload of std::string::operator+=()
+ /// that accepts the argument explicitly.
+ template <typename Sep, typename... Args>
+ inline std::string join_items(Sep Separator, Args &&... Items) {
+ std::string Result;
+ if (sizeof...(Items) == 0)
+ return Result;
+
+ size_t NS = detail::join_one_item_size(Separator);
+ size_t NI = detail::join_items_size(std::forward<Args>(Items)...);
+ Result.reserve(NI + (sizeof...(Items) - 1) * NS + 1);
+ detail::join_items_impl(Result, Separator, std::forward<Args>(Items)...);
+ return Result;
+ }
+
+ /// A helper class to return the specified delimiter string after the first
+ /// invocation of operator std::string_ref(). Used to generate a comma-separated
+ /// list from a loop like so:
+ ///
+ /// \code
+ /// ListSeparator LS;
+ /// for (auto &I : C)
+ /// OS << LS << I.getName();
+ /// \end
+ class ListSeparator {
+ bool First = true;
+ std::string_ref Separator;
+
+ public:
+ ListSeparator( std::string_ref Separator = ", ") : Separator(Separator) {}
+ operator std::string_ref() {
+ if (First) {
+ First = false;
+ return {};
+ }
+ return Separator;
+ }
+ };
+
+} // end namespace lsp
+
+namespace lsp{
+
+// Is <contents a plausible start to an HTML tag?
+// Contents may not be the rest of the line, but it's the rest of the plain
+// text, so we expect to see at least the tag name.
+bool looksLikeTag(std::string_ref& Contents) {
+ if (Contents.empty())
+ return false;
+ if (Contents.front() == '!' || Contents.front() == '?' ||
+ Contents.front() == '/')
+ return true;
+ // Check the start of the tag name.
+ if (!lsp::isAlpha(Contents.front()))
+ return false;
+ // Drop rest of the tag name, and following whitespace.
+ Contents = Contents
+ .drop_while([](char C) {
+ return lsp::isAlnum(C) || C == '-' || C == '_' || C == ':';
+ })
+ .drop_while(lsp::isSpace);
+ // The rest of the tag consists of attributes, which have restrictive names.
+ // If we hit '=', all bets are off (attribute values can contain anything).
+ for (; !Contents.empty(); Contents = Contents.drop_front()) {
+ if (lsp::isAlnum(Contents.front()) || lsp::isSpace(Contents.front()))
+ continue;
+ if (Contents.front() == '>' || Contents.start_with("/>"))
+ return true; // May close the tag.
+ if (Contents.front() == '=')
+ return true; // Don't try to parse attribute values.
+ return false; // Random punctuation means this isn't a tag.
+ }
+ return true; // Potentially incomplete tag.
+}
+
+// Tests whether C should be backslash-escaped in markdown.
+// The string being escaped is Before + C + After. This is part of a paragraph.
+// StartsLine indicates whether `Before` is the start of the line.
+// After may not be everything until the end of the line.
+//
+// It's always safe to escape punctuation, but want minimal escaping.
+// The strategy is to escape the first character of anything that might start
+// a markdown grammar construct.
+bool needsLeadingEscape(char C, std::string_ref Before, std::string_ref After,
+ bool StartsLine) {
+
+ auto RulerLength = [&]() -> /*Length*/ unsigned {
+ if (!StartsLine || !Before.empty())
+ return false;
+ std::string_ref A = After.trim_right();
+ return std::all_of(A.begin(),A.end(), [C](char D) { return C == D; }) ? 1 + A.size() : 0;
+ };
+ auto IsBullet = [&]() {
+ return StartsLine && Before.empty() &&
+ (After.empty() || After.start_with(" "));
+ };
+ auto SpaceSurrounds = [&]() {
+ return (After.empty() || std::isspace(After.front())) &&
+ (Before.empty() || std::isspace(Before.back()));
+ };
+
+ auto WordSurrounds = [&]() {
+ return (!After.empty() && std::isalnum(After.front())) &&
+ (!Before.empty() && std::isalnum(Before.back()));
+ };
+
+ switch (C) {
+ case '\\': // Escaped character.
+ return true;
+ case '`': // Code block or inline code
+ // Any number of backticks can delimit an inline code block that can end
+ // anywhere (including on another line). We must escape them all.
+ return true;
+ case '~': // Code block
+ return StartsLine && Before.empty() && After.start_with("~~");
+ case '#': { // ATX heading.
+ if (!StartsLine || !Before.empty())
+ return false;
+ std::string_ref& Rest = After.trim_left(C);
+ return Rest.empty() || Rest.start_with(" ");
+ }
+ case ']': // Link or link reference.
+ // We escape ] rather than [ here, because it's more constrained:
+ // ](...) is an in-line link
+ // ]: is a link reference
+ // The following are only links if the link reference exists:
+ // ] by itself is a shortcut link
+ // ][...] is an out-of-line link
+ // Because we never emit link references, we don't need to handle these.
+ return After.start_with(":") || After.start_with("(");
+ case '=': // Setex heading.
+ return RulerLength() > 0;
+ case '_': // Horizontal ruler or matched delimiter.
+ if (RulerLength() >= 3)
+ return true;
+ // Not a delimiter if surrounded by space, or inside a word.
+ // (The rules at word boundaries are subtle).
+ return !(SpaceSurrounds() || WordSurrounds());
+ case '-': // Setex heading, horizontal ruler, or bullet.
+ if (RulerLength() > 0)
+ return true;
+ return IsBullet();
+ case '+': // Bullet list.
+ return IsBullet();
+ case '*': // Bullet list, horizontal ruler, or delimiter.
+ return IsBullet() || RulerLength() >= 3 || !SpaceSurrounds();
+ case '<': // HTML tag (or autolink, which we choose not to escape)
+ return looksLikeTag(After);
+ case '>': // Quote marker. Needs escaping at start of line.
+ return StartsLine && Before.empty();
+ case '&': { // HTML entity reference
+ auto End = After.find(';');
+ if (End == std::string_ref::npos)
+ return false;
+ std::string_ref Content = After.substr(0, End);
+ if (Content.consume_front("#"))
+ {
+ if (Content.consume_front("x") || Content.consume_front("X"))
+ {
+ return std::all_of(Content.begin(),Content.end(), lsp::isHexDigit);
+ }
+
+ return std::all_of(Content.begin(), Content.end(), [](char c)
+ {
+ return lsp::isDigit(c);
+ });
+ }
+ return std::all_of(Content.begin(), Content.end(), [](char c)
+ {
+ return lsp::isAlpha(c);
+ });
+ }
+ case '.': // Numbered list indicator. Escape 12. -> 12\. at start of line.
+ case ')':
+ return StartsLine && !Before.empty() &&
+ std::all_of(Before.begin(), Before.end(), [](char c)
+ {
+ return lsp::isDigit(c);
+ }) && After.start_with(" ");
+ default:
+ return false;
+ }
+}
+
+/// Escape a markdown text block. Ensures the punctuation will not introduce
+/// any of the markdown constructs.
+ std::string_ref renderText(const std::string_ref& Input, bool StartsLine) {
+ std::string_ref R;
+ for (unsigned I = 0; I < Input.size(); ++I) {
+ if (needsLeadingEscape(Input[I], Input.substr(0, I), Input.substr(I + 1),
+ StartsLine))
+ R.push_back('\\');
+ R.push_back(Input[I]);
+ }
+ return R;
+}
+
+/// Renders \p Input as an inline block of code in markdown. The returned value
+/// is surrounded by backticks and the inner contents are properly escaped.
+ std::string_ref renderInlineBlock(const std::string_ref& Input) {
+ std::string_ref R;
+ // Double all backticks to make sure we don't close the inline block early.
+ for (size_t From = 0; From < Input.size();) {
+ size_t Next = Input.find("`", From);
+ R += Input.substr(From, Next - From);
+ if (Next == std::string_ref::npos)
+ break;
+ R += "``"; // double the found backtick.
+
+ From = Next + 1;
+ }
+ // If results starts with a backtick, add spaces on both sides. The spaces
+ // are ignored by markdown renderers.
+ if (std::string_ref(R).start_with("`") || std::string_ref(R).end_with("`"))
+ return "` " + std::move(R) + " `";
+ // Markdown render should ignore first and last space if both are there. We
+ // add an extra pair of spaces in that case to make sure we render what the
+ // user intended.
+ if (std::string_ref(R).start_with(" ") && std::string_ref(R).end_with(" "))
+ return "` " + std::move(R) + " `";
+ return "`" + std::move(R) + "`";
+}
+
+/// Get marker required for \p Input to represent a markdown codeblock. It
+/// consists of at least 3 backticks(`). Although markdown also allows to use
+/// tilde(~) for code blocks, they are never used.
+ std::string_ref getMarkerForCodeBlock(const std::string_ref& Input) {
+ // Count the maximum number of consecutive backticks in \p Input. We need to
+ // start and end the code block with more.
+ unsigned MaxBackticks = 0;
+ unsigned Backticks = 0;
+ for (char C : Input) {
+ if (C == '`') {
+ ++Backticks;
+ continue;
+ }
+ MaxBackticks = std::max(MaxBackticks, Backticks);
+ Backticks = 0;
+ }
+ MaxBackticks = std::max(Backticks, MaxBackticks);
+ // Use the corresponding number of backticks to start and end a code block.
+ return std::string_ref(/*Repeat=*/std::max(3u, MaxBackticks + 1), '`');
+}
+
+ /// SplitString - Split up the specified string according to the specified
+/// delimiters, appending the result fragments to the output list.
+ void SplitString(const std::string& Source,
+ std::vector<std::string_ref>& OutFragments,
+ std::string Delimiters = " \t\n\v\f\r")
+{
+ boost::split(OutFragments, Source, boost::is_any_of(Delimiters));
+}
+
+
+// Trims the input and concatenates whitespace blocks into a single ` `.
+ std::string_ref canonicalizeSpaces(const std::string_ref& Input) {
+ std::vector<std::string_ref> Words;
+ SplitString(Input, Words);
+
+ return lsp::join(Words, " ");
+}
+
+
+ std::string_ref renderBlocks( std::vector<Block*>&& Children,
+ void (Block::* RenderFunc)(std::ostringstream&) const) {
+ std::string_ref R;
+ std::ostringstream OS(R);
+
+ std::vector<int> v{ 1, 2, 3 };
+
+ // Trim rulers.
+ Children.erase(std::remove_if(Children.begin(), Children.end(), [](const Block* C)
+ {
+ return C->isRuler();
+ }), Children.end());
+
+ bool LastBlockWasRuler = true;
+ for (const auto& C : Children) {
+ if (C->isRuler() && LastBlockWasRuler)
+ continue;
+ LastBlockWasRuler = C->isRuler();
+ ((*C).*RenderFunc)(OS);
+ }
+
+ // Get rid of redundant empty lines introduced in plaintext while imitating
+ // padding in markdown.
+ std::string_ref AdjustedResult;
+ std::string_ref TrimmedText(OS.str());
+ TrimmedText = TrimmedText.trim();
+
+ std::copy_if(TrimmedText.begin(), TrimmedText.end(),
+ std::back_inserter(AdjustedResult),
+ [&TrimmedText](const char& C) {
+ return !std::string_ref(TrimmedText.data(),
+ &C - TrimmedText.data() + 1)
+ // We allow at most two newlines.
+ .end_with("\n\n\n");
+ });
+
+ return AdjustedResult;
+ };
+ std::string_ref renderBlocks(const std::vector<std::unique_ptr<Block> >& children,
+ void (Block::* renderFunc)(std::ostringstream&) const)
+ {
+ std::vector<Block*> temp(children.size(), nullptr);
+ for(size_t i = 0 ; i < children.size() ; ++i)
+ {
+ temp[i]=(children[i].get());
+ }
+ return renderBlocks(std::move(temp), renderFunc);
+ }
+// Separates two blocks with extra spacing. Note that it might render strangely
+// in vscode if the trailing block is a codeblock, see
+// https://github.com/microsoft/vscode/issues/88416 for details.
+class Ruler : public Block {
+public:
+ void renderMarkdown(std::ostringstream &OS) const override {
+ // Note that we need an extra new line before the ruler, otherwise we might
+ // make previous block a title instead of introducing a ruler.
+ OS << "\n---\n";
+ }
+ void renderPlainText(std::ostringstream &OS) const override { OS << '\n'; }
+ std::unique_ptr<Block> clone() const override {
+ return std::make_unique<Ruler>(*this);
+ }
+ bool isRuler() const override { return true; }
+};
+
+class CodeBlock : public Block {
+public:
+ void renderMarkdown(std::ostringstream &OS) const override {
+ std::string_ref Marker = getMarkerForCodeBlock(Contents);
+ // No need to pad from previous blocks, as they should end with a new line.
+ OS << Marker << Language << '\n' << Contents << '\n' << Marker << '\n';
+ }
+
+ void renderPlainText(std::ostringstream &OS) const override {
+ // In plaintext we want one empty line before and after codeblocks.
+ OS << '\n' << Contents << "\n\n";
+ }
+
+ std::unique_ptr<Block> clone() const override {
+ return std::make_unique<CodeBlock>(*this);
+ }
+
+ CodeBlock( std::string_ref Contents, std::string_ref Language)
+ : Contents(std::move(Contents)), Language(std::move(Language)) {}
+
+private:
+
+ std::string_ref Contents;
+ std::string_ref Language;
+};
+
+// Inserts two spaces after each `\n` to indent each line. First line is not
+// indented.
+ std::string_ref indentLines(const std::string_ref& Input) {
+ assert(!Input.end_with("\n") && "Input should've been trimmed.");
+ std::string_ref IndentedR;
+ // We'll add 2 spaces after each new line.
+ IndentedR.reserve(Input.size() + Input.count("\n") * 2);
+ for (char C : Input) {
+ IndentedR += C;
+ if (C == '\n')
+ IndentedR.append(" ");
+ }
+ return IndentedR;
+}
+
+class Heading : public Paragraph {
+public:
+ Heading(size_t Level) : Level(Level) {}
+ void renderMarkdown(std::ostringstream &OS) const override {
+ OS << std::string_ref(Level, '#') << ' ';
+ Paragraph::renderMarkdown(OS);
+ }
+
+private:
+ size_t Level;
+};
+
+
+
+
+
+ std::string_ref Block::asMarkdown() const {
+ std::string_ref R;
+ std::ostringstream OS(R);
+ renderMarkdown(OS);
+ return std::string_ref(OS.str()).trim();
+}
+
+ std::string_ref Block::asPlainText() const {
+ std::string_ref R;
+ std::ostringstream OS(R);
+ renderPlainText(OS);
+ return std::string_ref(OS.str()).trim().c_str();
+}
+
+ void Paragraph::renderMarkdown(std::ostringstream& OS) const {
+ bool NeedsSpace = false;
+ bool HasChunks = false;
+ for (auto& C : Chunks) {
+ if (C.SpaceBefore || NeedsSpace)
+ OS << " ";
+ switch (C.Kind) {
+ case Chunk::PlainText:
+ OS << renderText(C.Contents, !HasChunks);
+ break;
+ case Chunk::InlineCode:
+ OS << renderInlineBlock(C.Contents);
+ break;
+ }
+ HasChunks = true;
+ NeedsSpace = C.SpaceAfter;
+ }
+ // Paragraphs are translated into markdown lines, not markdown paragraphs.
+ // Therefore it only has a single linebreak afterwards.
+ // VSCode requires two spaces at the end of line to start a new one.
+ OS << " \n";
+ }
+
+ std::unique_ptr<Block> Paragraph::clone() const {
+ return std::make_unique<Paragraph>(*this);
+ }
+
+ /// Choose a marker to delimit `Text` from a prioritized list of options.
+ /// This is more readable than escaping for plain-text.
+ std::string_ref chooseMarker(std::vector<std::string_ref> Options,
+ const std::string_ref& Text)
+ {
+ // Prefer a delimiter whose characters don't appear in the text.
+ for (std::string_ref& S : Options)
+ if (Text.find_first_of(S) == std::string_ref::npos)
+ return S;
+ return Options.front();
+ }
+
+ void Paragraph::renderPlainText(std::ostringstream& OS) const {
+ bool NeedsSpace = false;
+ for (auto& C : Chunks) {
+ if (C.SpaceBefore || NeedsSpace)
+ OS << " ";
+ std::string_ref Marker = "";
+ if (C.Preserve && C.Kind == Chunk::InlineCode)
+ Marker = chooseMarker({ "`", "'", "\"" }, C.Contents);
+ OS << Marker << C.Contents << Marker;
+ NeedsSpace = C.SpaceAfter;
+ }
+ OS << '\n';
+ }
+
+ void BulletList::renderMarkdown(std::ostringstream& OS) const {
+ for (auto& D : Items) {
+ // Instead of doing this we might prefer passing Indent to children to get
+ // rid of the copies, if it turns out to be a bottleneck.
+
+ OS << "- ";
+ OS << indentLines(D.asMarkdown()) << '\n';
+ }
+ // We need a new line after list to terminate it in markdown.
+ OS << '\n';
+ }
+
+ void BulletList::renderPlainText(std::ostringstream& OS) const {
+ for (auto& D : Items) {
+ // Instead of doing this we might prefer passing Indent to children to get
+ // rid of the copies, if it turns out to be a bottleneck.
+ OS << "- " << indentLines(D.asPlainText()) << '\n';
+ }
+ }
+
+ Paragraph& Paragraph::appendSpace() {
+ if (!Chunks.empty())
+ Chunks.back().SpaceAfter = true;
+ return *this;
+ }
+
+ Paragraph& Paragraph::appendText(const std::string_ref& Text) {
+ std::string_ref Norm = canonicalizeSpaces(Text);
+ if (Norm.empty())
+ return *this;
+ Chunks.emplace_back();
+ Chunk& C = Chunks.back();
+ C.Contents = std::move(Norm);
+ C.Kind = Chunk::PlainText;
+
+ C.SpaceBefore = std::isspace(Text.front());
+ C.SpaceAfter = std::isspace(Text.back());
+ return *this;
+ }
+
+ Paragraph& Paragraph::appendCode(const std::string_ref& Code, bool Preserve) {
+ bool AdjacentCode =
+ !Chunks.empty() && Chunks.back().Kind == Chunk::InlineCode;
+ std::string_ref Norm = canonicalizeSpaces(Code);
+ if (Norm.empty())
+ return *this;
+ Chunks.emplace_back();
+ Chunk& C = Chunks.back();
+ C.Contents = std::move(Norm);
+ C.Kind = Chunk::InlineCode;
+ C.Preserve = Preserve;
+ // Disallow adjacent code spans without spaces, markdown can't render them.
+ C.SpaceBefore = AdjacentCode;
+ return *this;
+ }
+
+ std::unique_ptr<Block> BulletList::clone() const {
+ return std::make_unique<BulletList>(*this);
+ }
+
+ class Document& BulletList::addItem() {
+ Items.emplace_back();
+ return Items.back();
+ }
+
+ Document& Document::operator=(const Document& Other) {
+ Children.clear();
+ for (const auto& C : Other.Children)
+ Children.push_back(C->clone());
+ return *this;
+ }
+
+ void Document::append(Document Other) {
+ std::move(Other.Children.begin(), Other.Children.end(),
+ std::back_inserter(Children));
+ }
+
+ Paragraph& Document::addParagraph() {
+ Children.push_back(std::make_unique<Paragraph>());
+ return *static_cast<Paragraph*>(Children.back().get());
+ }
+
+ void Document::addRuler() { Children.push_back(std::make_unique<Ruler>()); }
+
+ void Document::addCodeBlock(std::string_ref Code, std::string_ref Language) {
+ Children.emplace_back(
+ std::make_unique<CodeBlock>(std::move(Code), std::move(Language)));
+ }
+
+ std::string_ref Document::asMarkdown() const {
+ return renderBlocks(Children, &Block::renderMarkdown);
+ }
+
+ std::string_ref Document::asPlainText() const {
+ return renderBlocks(Children, &Block::renderPlainText);
+ }
+
+ BulletList& Document::addBulletList() {
+ Children.emplace_back(std::make_unique<BulletList>());
+ return *static_cast<BulletList*>(Children.back().get());
+ }
+
+ Paragraph& Document::addHeading(size_t Level) {
+ assert(Level > 0);
+ Children.emplace_back(std::make_unique<Heading>(Level));
+ return *static_cast<Paragraph*>(Children.back().get());
+ }
+ }; \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/Markup/Markup.h b/graphics/asymptote/LspCpp/LibLsp/lsp/Markup/Markup.h
new file mode 100644
index 0000000000..92d773db0c
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/Markup/Markup.h
@@ -0,0 +1,119 @@
+#pragma once
+#include <cctype>
+#include <clocale>
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <vector>
+#include <sstream>
+
+#include "string_ref.h"
+
+namespace lsp
+{
+
+/// Holds text and knows how to lay it out. Multiple blocks can be grouped to
+/// form a document. Blocks include their own trailing newlines, std::string_ref
+/// should trim them if need be.
+class Block {
+public:
+ virtual void renderMarkdown(std::ostringstream &OS) const = 0;
+ virtual void renderPlainText(std::ostringstream &OS) const = 0;
+ virtual std::unique_ptr<Block> clone() const = 0;
+ std::string_ref asMarkdown() const;
+ std::string_ref asPlainText() const;
+
+ virtual bool isRuler() const { return false; }
+ virtual ~Block() = default;
+};
+
+/// Represents parts of the markup that can contain strings, like inline code,
+/// code block or plain text.
+/// One must introduce different paragraphs to create separate blocks.
+class Paragraph : public Block {
+public:
+ void renderMarkdown(std::ostringstream &OS) const override;
+ void renderPlainText(std::ostringstream &OS) const override;
+ std::unique_ptr<Block> clone() const override;
+
+ /// Append plain text to the end of the string.
+ Paragraph &appendText(const std::string_ref& Text);
+
+ /// Append inline code, this translates to the ` block in markdown.
+ /// \p Preserve indicates the code span must be apparent even in plaintext.
+ Paragraph &appendCode(const std::string_ref& Code, bool Preserve = false);
+
+ /// Ensure there is space between the surrounding chunks.
+ /// Has no effect at the beginning or end of a paragraph.
+ Paragraph &appendSpace();
+
+private:
+ struct Chunk {
+ enum {
+ PlainText,
+ InlineCode,
+ } Kind = PlainText;
+ // Preserve chunk markers in plaintext.
+ bool Preserve = false;
+ std::string_ref Contents;
+ // Whether this chunk should be surrounded by whitespace.
+ // Consecutive SpaceAfter and SpaceBefore will be collapsed into one space.
+ // Code spans don't usually set this: their spaces belong "inside" the span.
+ bool SpaceBefore = false;
+ bool SpaceAfter = false;
+ };
+ std::vector<Chunk> Chunks;
+};
+
+/// Represents a sequence of one or more documents. Knows how to print them in a
+/// list like format, e.g. by prepending with "- " and indentation.
+class BulletList : public Block {
+public:
+ void renderMarkdown(std::ostringstream &OS) const override;
+ void renderPlainText(std::ostringstream &OS) const override;
+ std::unique_ptr<Block> clone() const override;
+
+ class Document &addItem();
+
+private:
+ std::vector<class Document> Items;
+};
+
+/// A format-agnostic representation for structured text. Allows rendering into
+/// markdown and plaintext.
+class Document {
+public:
+ Document() = default;
+ Document(const Document &Other) { *this = Other; }
+ Document &operator=(const Document &);
+ Document(Document &&) = default;
+ Document &operator=(Document &&) = default;
+
+ void append(Document Other);
+
+ /// Adds a semantical block that will be separate from others.
+ Paragraph &addParagraph();
+ /// Inserts a horizontal separator to the document.
+ void addRuler();
+ /// Adds a block of code. This translates to a ``` block in markdown. In plain
+ /// text representation, the code block will be surrounded by newlines.
+ void addCodeBlock( std::string_ref Code, std::string_ref Language = "cpp");
+ /// Heading is a special type of paragraph that will be prepended with \p
+ /// Level many '#'s in markdown.
+ Paragraph &addHeading(size_t Level);
+
+ BulletList &addBulletList();
+
+ /// Doesn't contain any trailing newlines.
+ /// We try to make the markdown human-readable, e.g. avoid extra escaping.
+ /// At least one client (coc.nvim) displays the markdown verbatim!
+ std::string_ref asMarkdown() const;
+ /// Doesn't contain any trailing newlines.
+ std::string_ref asPlainText() const;
+
+private:
+ std::vector<std::unique_ptr<Block>> Children;
+};
+
+
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/Markup/string_ref.h b/graphics/asymptote/LspCpp/LibLsp/lsp/Markup/string_ref.h
new file mode 100644
index 0000000000..d7ee423944
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/Markup/string_ref.h
@@ -0,0 +1,1059 @@
+
+#pragma once
+#include <algorithm>
+#include <string>
+#include <vector>
+#include <stdarg.h>
+#include<functional>
+
+#ifndef _WIN32
+#include <cstring>
+#endif
+namespace std
+{
+
+ /**
+ * An extension of STL's string providing additional functionality that is often availiable in
+ * higher-level languages such as Python.
+ */
+ class string_ref : public string
+ {
+ public:
+
+ //static unsigned GetAutoSenseRadix(string_ref& Str) {
+ // if (Str.empty())
+ // return 10;
+
+ // if (Str.start_with("0x") || Str.start_with("0X")) {
+ // Str = Str.substr(2);
+ // return 16;
+ // }
+
+ // if (Str.start_with("0b") || Str.start_with("0B")) {
+ // Str = Str.substr(2);
+ // return 2;
+ // }
+
+ // if (Str.start_with("0o")) {
+ // Str = Str.substr(2);
+ // return 8;
+ // }
+
+ // if (Str[0] == '0' && Str.size() > 1 && std::isdigit(Str[1])) {
+ // Str = Str.substr(1);
+ // return 8;
+ // }
+
+ // return 10;
+ //}
+
+ //static bool consumeUnsignedInteger(string_ref& Str, unsigned Radix,
+ // unsigned long long& Result) {
+ // // Autosense radix if not specified.
+ // if (Radix == 0)
+ // Radix = GetAutoSenseRadix(Str);
+
+ // // Empty strings (after the radix autosense) are invalid.
+ // if (Str.empty()) return true;
+
+ // // Parse all the bytes of the string given this radix. Watch for overflow.
+ // string_ref Str2 = Str;
+ // Result = 0;
+ // while (!Str2.empty()) {
+ // unsigned CharVal;
+ // if (Str2[0] >= '0' && Str2[0] <= '9')
+ // CharVal = Str2[0] - '0';
+ // else if (Str2[0] >= 'a' && Str2[0] <= 'z')
+ // CharVal = Str2[0] - 'a' + 10;
+ // else if (Str2[0] >= 'A' && Str2[0] <= 'Z')
+ // CharVal = Str2[0] - 'A' + 10;
+ // else
+ // break;
+
+ // // If the parsed value is larger than the integer radix, we cannot
+ // // consume any more characters.
+ // if (CharVal >= Radix)
+ // break;
+
+ // // Add in this character.
+ // unsigned long long PrevResult = Result;
+ // Result = Result * Radix + CharVal;
+
+ // // Check for overflow by shifting back and seeing if bits were lost.
+ // if (Result / Radix < PrevResult)
+ // return true;
+
+ // Str2 = Str2.substr(1);
+ // }
+
+ // // We consider the operation a failure if no characters were consumed
+ // // successfully.
+ // if (Str.size() == Str2.size())
+ // return true;
+
+ // Str = Str2;
+ // return false;
+ //}
+
+ //static bool consumeSignedInteger(string_ref& Str, unsigned Radix,
+ // long long& Result) {
+ // unsigned long long ULLVal;
+
+ // // Handle positive strings first.
+ // if (Str.empty() || Str.front() != '-') {
+ // if (consumeUnsignedInteger(Str, Radix, ULLVal) ||
+ // // Check for value so large it overflows a signed value.
+ // (long long)ULLVal < 0)
+ // return true;
+ // Result = ULLVal;
+ // return false;
+ // }
+
+ // // Get the positive part of the value.
+ // string_ref Str2 = Str.drop_front(1);
+ // if (consumeUnsignedInteger(Str2, Radix, ULLVal) ||
+ // // Reject values so large they'd overflow as negative signed, but allow
+ // // "-0". This negates the unsigned so that the negative isn't undefined
+ // // on signed overflow.
+ // (long long)-ULLVal > 0)
+ // return true;
+
+ // Str = Str2;
+ // Result = -ULLVal;
+ // return false;
+ //}
+
+ ///// GetAsUnsignedInteger - Workhorse method that converts a integer character
+ ///// sequence of radix up to 36 to an unsigned long long value.
+ //static bool getAsUnsignedInteger(string_ref Str, unsigned Radix,
+ // unsigned long long& Result) {
+ // if (consumeUnsignedInteger(Str, Radix, Result))
+ // return true;
+
+ // // For getAsUnsignedInteger, we require the whole string to be consumed or
+ // // else we consider it a failure.
+ // return !Str.empty();
+ //}
+
+ //static bool getAsSignedInteger(string_ref Str, unsigned Radix,
+ // long long& Result) {
+ // if (consumeSignedInteger(Str, Radix, Result))
+ // return true;
+
+ // // For getAsSignedInteger, we require the whole string to be consumed or else
+ // // we consider it a failure.
+ // return !Str.empty();
+ //}
+
+
+ ///// Parse the current string as an integer of the specified radix. If
+ ///// \p Radix is specified as zero, this does radix autosensing using
+ ///// extended C rules: 0 is octal, 0x is hex, 0b is binary.
+ /////
+ ///// If the string is invalid or if only a subset of the string is valid,
+ ///// this returns true to signify the error. The string is considered
+ ///// erroneous if empty or if it overflows T.
+ //template <typename T>
+ //std::enable_if_t<std::numeric_limits<T>::is_signed, bool>
+ // getAsInteger(unsigned Radix, T& Result) const {
+ // long long LLVal;
+ // if (getAsSignedInteger(*this, Radix, LLVal) ||
+ // static_cast<T>(LLVal) != LLVal)
+ // return true;
+ // Result = LLVal;
+ // return false;
+ //}
+
+ //template <typename T>
+ //std::enable_if_t<!std::numeric_limits<T>::is_signed, bool>
+ // getAsInteger(unsigned Radix, T& Result) const {
+ // unsigned long long ULLVal;
+ // // The additional cast to unsigned long long is required to avoid the
+ // // Visual C++ warning C4805: '!=' : unsafe mix of type 'bool' and type
+ // // 'unsigned __int64' when instantiating getAsInteger with T = bool.
+ // if (getAsUnsignedInteger(*this, Radix, ULLVal) ||
+ // static_cast<unsigned long long>(static_cast<T>(ULLVal)) != ULLVal)
+ // return true;
+ // Result = ULLVal;
+ // return false;
+ //}
+
+
+
+ /**`
+ * Default constructor
+ *
+ * Constructs an empty string_ref ("")
+ */
+ string_ref() : string() { }
+
+ /**
+ * Duplicate the STL string copy constructor
+ *
+ * @param[in] s The string to copy
+ * @param[in] pos The starting position in the string to copy from
+ * @param[in] n The number of characters to copy
+ */
+ string_ref(const string &s, size_type pos = 0, size_type n = npos) : string(s, pos, npos) { }
+
+ /**
+ * Construct an string_ref from a null-terminated character array
+ *
+ * @param[in] s The character array to copy into the new string
+ */
+ string_ref(const value_type *s) : string(s) { }
+
+ /**
+ * Construct an string_ref from a character array and a length
+ *
+ * @param[in] s The character array to copy into the new string
+ * @param[in] n The number of characters to copy
+ */
+ string_ref(const value_type *s, size_type n) : string(s, n) { }
+
+ /**
+ * Create an string_ref with @p n copies of @p c
+ *
+ * @param[in] n The number of copies
+ * @param[in] c The character to copy @p n times
+ */
+ string_ref(size_type n, value_type c) : string(n, c) { }
+
+ /**
+ * Create a string from a range
+ *
+ * @param[in] first The first element to copy in
+ * @param[in] last The last element to copy in
+ */
+ template <class InputIterator>
+ string_ref(InputIterator first, InputIterator last) : string(first, last) { }
+
+ /**
+ * The destructor
+ */
+ ~string_ref() { }
+
+ /**
+ * Split a string by whitespace
+ *
+ * @return A vector of strings, each of which is a substring of the string
+ */
+ vector<string_ref> split(size_type limit = npos) const
+ {
+ vector<string_ref> v;
+
+ const_iterator
+ i = begin(),
+ last = i;
+ for (; i != end(); i++)
+ {
+ if (*i == ' ' || *i == '\n' || *i == '\t' || *i == '\r')
+ {
+ if (i + 1 != end() && (i[1] == ' ' || i[1] == '\n' || i[1] == '\t' || i[1] == '\r'))
+ continue;
+ v.push_back(string_ref(last, i));
+ last = i + 1;
+ if (v.size() >= limit - 1)
+ {
+ v.push_back(string_ref(last, end()));
+ return v;
+ }
+ }
+ }
+
+ if (last != i)
+ v.push_back(string_ref(last, i));
+
+ return v;
+ }
+
+ /**
+ * Split a string by a character
+ *
+ * Returns a vector of ext_strings, each of which is a substring of the string formed by splitting
+ * it on boundaries formed by the character @p separator. If @p limit is set, the returned vector
+ * will contain a maximum of @p limit elements with the last element containing the rest of
+ * the string.
+ *
+ * If @p separator is not found in the string, a single element will be returned in the vector
+ * containing the entire string.
+ *
+ * The separators are removed from the output
+ *
+ * @param[in] separator The character separator to split the string on
+ * @param[in] limit The maximum number of output elements
+ * @return A vector of strings, each of which is a substring of the string
+ *
+ * @section split_ex Example
+ * @code
+ * std::string_ref s("This|is|a|test.");
+ * std::vector<std::string_ref> v = s.split('|');
+ * std::copy(v.begin(), v.end(), std::ostream_iterator<std::string_ref>(std::cout, "\n"));
+ *
+ * This
+ * is
+ * a
+ * test.
+ * @endcode
+ */
+ vector<string_ref> split(value_type separator, size_type limit = npos) const
+ {
+ vector<string_ref> v;
+
+ const_iterator
+ i = begin(),
+ last = i;
+ for (; i != end(); i++)
+ {
+ if (*i == separator)
+ {
+ v.push_back(string_ref(last, i));
+ last = i + 1;
+ if (v.size() >= limit - 1)
+ {
+ v.push_back(string_ref(last, end()));
+ return v;
+ }
+ }
+ }
+
+ if (last != i)
+ v.push_back(string_ref(last, i));
+
+ return v;
+ }
+
+ /**
+ * Split a string by another string
+ *
+ * Returns a vector of ext_strings, each of which is a substring of the string formed by
+ * splitting it on boundaries formed by the string @p separator. If @p limit is set, the
+ * returned vector will contain a maximum of @p limit elements with the last element
+ * containing the rest of the string.
+ *
+ * If @p separator is not found in the string, a single element will be returned in the
+ * vector containing the entire string.
+ *
+ * The separators are removed from the output
+ *
+ * @param[in] separator The string separator to split the string on
+ * @param[in] limit The maximum number of output elements
+ * @return A vector of strings, each of which is a substring of the string
+ *
+ * @ref split_ex
+ */
+ vector<string_ref> split(const string &separator, size_type limit = npos) const
+ {
+ vector<string_ref> v;
+
+ const_iterator
+ i = begin(),
+ last = i;
+ for (; i != end(); i++)
+ {
+ if (string(i, i + separator.length()) == separator)
+ {
+ v.push_back(string_ref(last, i));
+ last = i + separator.length();
+
+ if (v.size() >= limit - 1)
+ {
+ v.push_back(string_ref(last, end()));
+ return v;
+ }
+ }
+ }
+
+ if (last != i)
+ v.push_back(string_ref(last, i));
+
+ return v;
+ }
+
+ /**
+ * Convert a string into an integer
+ *
+ * Convert the initial portion of a string into a signed integer. Once a non-numeric
+ * character is reached, the remainder of @p string is ignored and the integer that was
+ * read returned.
+ *
+ * @param s The string to convert
+ * @return The integer converted from @p string
+ */
+ static long int integer(const string &s)
+ {
+ long int retval = 0;
+ bool neg = false;
+
+ for (const_iterator i = s.begin(); i != s.end(); i++)
+ {
+ if (i == s.begin())
+ {
+ if (*i == '-')
+ {
+ neg = true;
+ continue;
+ }
+ else if (*i == '+')
+ continue;
+ }
+ if (*i >= '0' && *i <= '9')
+ {
+ retval *= 10;
+ retval += *i - '0';
+ }
+ else
+ break;
+ }
+
+ if (neg)
+ retval *= -1;
+
+ return retval;
+ }
+
+ /**
+ * Convert the string to an integer
+ *
+ * Convert the initial portion of the string into a signed integer. Once a non-numeric
+ * character is reached, the remainder of the string is ignored and the integer that had
+ * been read thus far is returned.
+ *
+ * @return The integer converted from the string
+ */
+ long int integer() const
+ {
+ return integer(*this);
+ }
+
+ /**
+ * Split a string into chunks of size @p chunklen. Returns a vector of strings.
+ *
+ * Splits a string into chunks of the given size. The final chunk may not fill its
+ * entire allocated number of characters.
+ *
+ * @param[in] chunklen The number of characters per chunk
+ * @return A vector of strings, each of length <= chunklen
+ *
+ * @section chunk_split-ex Example
+ * @code
+ * std::string_ref s("abcdefghijk");
+ * std::vector<std::string_ref> v = s.chunk_split(3);
+ * std::copy(v.begin(), v.end(), ostream_iterator<std::string_ref>(cout, " "));
+ *
+ * abc def ghi jk
+ * @endcode
+ */
+ vector<string_ref> chunk_split(size_type chunklen) const
+ {
+ vector<string_ref> retval;
+ retval.reserve(size() / chunklen + 1);
+
+ size_type count = 0;
+ const_iterator
+ i = begin(),
+ last = i;
+ for (; i != end(); i++, count++)
+ {
+ if (count == chunklen)
+ {
+ count = 0;
+ retval.push_back(string_ref(last, i));
+ last = i;
+ }
+ }
+
+ if (last != i)
+ retval.push_back(string_ref(last, i));
+
+ return retval;
+ }
+
+ /**
+ * Join a sequence of strings by some glue to create a new string
+ *
+ * Glue is not added to the end of the string.
+ *
+ * @pre [first, last) is a valid range
+ * @pre InputIterator is a model of STL's Input Iterator
+ * @pre InputIterator must point to a string type (std::string, std::string_ref, char *)
+ *
+ * @param[in] glue The glue to join strings with
+ * @param[in] first The beginning of the range to join
+ * @param[in] last The end of the range to join
+ * @return A string constructed of each element of the range connected together with @p glue
+ *
+ * @section join_ex Example
+ * @code
+ * std::vector<std::string_ref> v;
+ * v.push_back("This");
+ * v.push_back("is");
+ * v.push_back("a");
+ * v.push_back("test.");
+ * std::cout << std::string_ref::join("|", v.begin(), v.end()) << std::endl;
+ *
+ * This|is|a|test.
+ * @endcode
+ */
+ template <class InputIterator>
+ static string_ref join(const string &glue, InputIterator first, InputIterator last)
+ {
+ string_ref retval;
+
+ for (; first != last; ++first)
+ {
+ retval.append(*first);
+ retval.append(glue);
+ }
+ retval.erase(retval.length() - glue.length());
+
+ return retval;
+ }
+
+ /**
+ * Join a sequence of strings by some glue to create a new string
+ *
+ * @copydoc join
+ * @ref join_ex
+ */
+ template <class InputIterator>
+ static string_ref join(value_type glue, InputIterator first, InputIterator last)
+ {
+ string_ref retval;
+
+ for (; first != last; ++first)
+ {
+ retval.append(*first);
+ retval.append(1, glue);
+ }
+ retval.erase(retval.length() - 1);
+
+ return retval;
+ }
+
+ /**
+ * Search for any instances of @p needle and replace them with @p s
+ *
+ * @param[in] needle The string to replace
+ * @param[in] s The replacement string
+ * @return *this
+ * @post All instances of @p needle in the string are replaced with @p s
+ *
+ * @section replace-ex Example
+ * @code
+ * std::string_ref s("This is a test.");
+ * s.replace("is", "ere");
+ * std::cout << s << std::endl;
+ *
+ * There ere a test.
+ * @endcode
+ */
+ string_ref &replace(const string &needle, const string &s)
+ {
+ size_type
+ lastpos = 0,
+ thispos;
+
+ while ((thispos = find(needle, lastpos)) != npos)
+ {
+ string::replace(thispos, needle.length(), s);
+ lastpos = thispos + 1;
+ }
+ return *this;
+ }
+ string_ref &replace_first(const string &needle, const string &s)
+ {
+ size_type
+ lastpos = 0,
+ thispos;
+
+ if ((thispos = find(needle, lastpos)) != npos)
+ {
+ string::replace(thispos, needle.length(), s);
+ lastpos = thispos + 1;
+ }
+ return *this;
+ }
+ /**
+ * Search of any instances of @p needle and replace them with @p c
+ *
+ * @param[in] needle The character to replace
+ * @param[in] c The replacement character
+ * @return *this
+ * @post All instances of @p needle in the string are replaced with @p c
+ *
+ * @ref replace-ex
+ */
+ string_ref &replace(value_type needle, value_type c)
+ {
+ for (iterator i = begin(); i != end(); i++)
+ if (*i == needle)
+ *i = c;
+
+ return *this;
+ }
+
+ /**
+ * Repeat a string @p n times
+ *
+ * @param[in] n The number of times to repeat the string
+ * @return string_ref containing @p n copies of the string
+ *
+ * @section repeat-ex Example
+ * @code
+ * std::string_ref s("123");
+ * s = s * 3;
+ * std::cout << s << std::endl;
+ *
+ * 123123123
+ * @endcode
+ */
+ string_ref operator*(size_type n)
+ {
+ string_ref retval;
+ for (size_type i = 0; i < n; i++)
+ retval.append(*this);
+
+ return retval;
+ }
+
+ /**
+ * Convert the string to lowercase
+ *
+ * @return *this
+ * @post The string is converted to lowercase
+ */
+ string_ref &tolower()
+ {
+ for (iterator i = begin(); i != end(); i++)
+ if (*i >= 'A' && *i <= 'Z')
+ *i = (*i) + ('a' - 'A');
+ return *this;
+ }
+
+ /**
+ * Convert the string to uppercase
+ *
+ * @return *this
+ * @post The string is converted to uppercase
+ */
+ string_ref &toupper()
+ {
+ for (iterator i = begin(); i != end(); i++)
+ if (*i >= 'a' && *i <= 'z')
+ *i = (*i) - ('a' - 'A');
+ return *this;
+ }
+
+ /**
+ * Count the occurances of @p str in the string.
+ *
+ * @return The count of substrings @p str in the string
+ */
+ size_type count(const string &str) const
+ {
+ size_type
+ count = 0,
+ last = 0,
+ cur = 0;
+
+ while ((cur = find(str, last + 1)) != npos)
+ {
+ count++;
+ last = cur;
+ }
+
+ return count;
+ }
+
+ /**
+ * Determine if the string is alphanumeric
+ *
+ * @return true if the string contains only characters between a-z, A-Z and 0-9 and
+ * contains at least one character, else false
+ */
+ bool is_alnum() const
+ {
+ if (length() == 0)
+ return false;
+
+ for (const_iterator i = begin(); i != end(); i++)
+ {
+ if (*i < 'A' || *i > 'Z')
+ if (*i < '0' || *i > '9')
+ if (*i < 'a' || *i > 'z')
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Determine if the string is alphabetic only
+ *
+ * @return true of the string contains only characters between a-z and A-Z and contains at
+ * least one character, else false
+ */
+ bool is_alpha() const
+ {
+ if (length() == 0)
+ return false;
+
+ for (const_iterator i = begin(); i != end(); i++)
+ if (*i < 'A' || (*i > 'Z' && (*i < 'a' || *i > 'z')))
+ return false;
+
+ return true;
+ }
+
+ /**
+ * Determine if the string is numeric only
+ *
+ * @return true if the string contains only characters between 0-9 and contains at least
+ * one character, else false
+ */
+ bool is_numeric() const
+ {
+ if (length() == 0)
+ return false;
+
+ for (const_iterator i = begin(); i != end(); i++)
+ if (*i < '0' || *i > '9')
+ return false;
+
+ return true;
+ }
+
+ /**
+ * Determine if a string is all lower case
+ *
+ * @return true if there is at least one character, and all characters are lowercase
+ * letters, else false
+ */
+ bool is_lower() const
+ {
+ if (length() == 0)
+ return false;
+
+ for (const_iterator i = begin(); i != end(); i++)
+ if (*i < 'a' || *i < 'z')
+ return false;
+
+ return true;
+ }
+
+ /**
+ * Determine if a string is all upper case
+ *
+ * @return true if there is at least one character, and all characters are uppercase
+ * letters, else false
+ */
+ bool is_upper() const
+ {
+ if (length() == 0)
+ return false;
+
+ for (const_iterator i = begin(); i != end(); i++)
+ if (*i < 'A' || *i > 'Z')
+ return false;
+
+ return true;
+ }
+
+ /**
+ * Swap the case of a string
+ *
+ * @post Converts all uppercase to lowercase, and all lowercase to uppercase in the string
+ * @return *this
+ */
+ string_ref &swapcase()
+ {
+ for (iterator i = begin(); i != end(); i++)
+ if (*i >= 'A' && *i <= 'Z')
+ *i += ('a' - 'A');
+ else if (*i >= 'a' && *i <= 'z')
+ *i -= ('a' - 'A');
+
+ return *this;
+ }
+
+ /*******************************************************************************
+ Function: std::string_ref::start_with
+ Access: public
+ Qualifier: const
+ Parameter: const string & str
+ Returns: bool
+
+ Purpose: is the string start with str
+ *******************************************************************************/
+ bool start_with(const string& str) const
+ {
+ return ( this->find(str) == 0 );
+ }
+
+ /// Return a string_ref equal to 'this' but with only the last \p N
+ /// elements remaining. If \p N is greater than the length of the
+ /// string, the entire string is returned.
+
+ string_ref take_back(size_t N = 1) const {
+ if (N >= size())
+ return *this;
+ return drop_front(size() - N);
+ }
+ /// Return a string_ref equal to 'this' but with the first \p N elements
+ /// dropped.
+
+ string_ref drop_front(size_t N = 1) const {
+ //assert(size() >= N && "Dropping more elements than exist");
+ return substr(N);
+ }
+
+
+
+ /// Return a string_ref equal to 'this' but with the last \p N elements
+ /// dropped.
+
+ string_ref drop_back(size_t N = 1) const {
+
+ return substr(0, size() - N);
+ }
+
+ /// Return a string_ref equal to 'this', but with all characters satisfying
+ /// the given predicate dropped from the beginning of the string.
+
+ string_ref drop_while(std::function<bool(char)> F) const {
+ return substr(std::find_if_not(begin(),end(),F)-begin());
+ }
+
+ /// Return a string_ref equal to 'this', but with all characters not
+ /// satisfying the given predicate dropped from the beginning of the string.
+
+ string_ref drop_until(std::function<bool(char)> F) const {
+ return substr(std::find_if(begin(), end(), F) - begin());
+ }
+
+ /// Returns true if this string_ref has the given prefix and removes that
+ /// prefix.
+ bool consume_front(string_ref Prefix) {
+ if (!start_with(Prefix))
+ return false;
+
+ *this = drop_front(Prefix.size());
+ return true;
+ }
+
+ /// Returns true if this string_ref has the given suffix and removes that
+ /// suffix.
+ bool consume_back(string_ref Suffix) {
+ if (!end_with(Suffix))
+ return false;
+
+ *this = drop_back(Suffix.size());
+ return true;
+ }
+
+ /*******************************************************************************
+ Function: std::string_ref::end_with
+ Access: public
+ Qualifier: const
+ Parameter: const string & str
+ Returns: bool
+
+ Purpose: is the string end with str
+ *******************************************************************************/
+ bool end_with(const string& str) const
+ {
+ if (str.length() > this->length())
+ {
+ return false;
+ }
+ size_type off = this->length() - str.length();
+ return ( find(str, off) == off);
+ }
+
+ /*******************************************************************************
+ Function: hl_lib::string_ref::format
+ Access: public
+ Qualifier:
+ Parameter: const char * format_string
+ Parameter: ...
+ Returns: string_ref&
+
+ Purpose: format the string
+ *******************************************************************************/
+ string_ref& format(const char* format_string, ...)
+ {
+ if (format_string == 0)
+ {
+ return *this;
+ }
+
+ va_list argList;
+ char* pbuf = 0;
+ va_start( argList, format_string );
+#ifdef _WIN32
+ int len = _vscprintf( format_string, argList );
+#else
+ int len = vsnprintf(nullptr, 0, format_string, argList);
+#endif
+ pbuf = new char[len + 1];
+ if (pbuf != 0)
+ {
+#ifdef _WIN32
+ vsprintf_s( pbuf, len + 1, format_string, argList );
+#else
+ vsprintf(pbuf, format_string, argList);
+#endif
+ *this = pbuf;
+ }
+ delete[] pbuf;
+ va_end( argList );
+
+ return *this;
+ }
+
+ /*******************************************************************************
+ Function: hl_lib::string_ref::trim_left
+ Access: public
+ Qualifier:
+ Parameter: value_type ch
+ Returns: string_ref&
+
+ Purpose: delete all char which is ch at the left of the string
+ *******************************************************************************/
+ string_ref& trim_left(value_type ch = ' ')
+ {
+ size_type off = this->find_first_not_of(ch);
+ if (off != string::npos)
+ {
+ this->erase(0, off);
+ }
+ return *this;
+ }
+
+ /*******************************************************************************
+ Function: hl_lib::string_ref::trim_right
+ Access: public
+ Qualifier:
+ Parameter: value_type ch
+ Returns: string_ref&
+
+ Purpose: delete all char which is ch at the right of the string
+ *******************************************************************************/
+ string_ref& trim_right(value_type ch = ' ')
+ {
+ size_type off = this->find_last_not_of(ch);
+ if (off == string::npos)
+ {
+ off = 0;
+ }
+ else
+ {
+ off++;
+ }
+ this->erase(off, length() - off);
+ return *this;
+ }
+
+ /*******************************************************************************
+ Function: hl_lib::string_ref::trim
+ Access: public
+ Qualifier:
+ Parameter: value_type ch
+ Returns: string_ref&
+
+ Purpose: delete all char which is ch at the left and right of the string
+ *******************************************************************************/
+ string_ref& trim(value_type ch = ' ')
+ {
+ trim_left(ch);
+ trim_right(ch);
+ return *this;
+ }
+
+ /*******************************************************************************
+ Function: hl_lib::string_ref::float_num
+ Access: public static
+ Qualifier:
+ Parameter: const string & str
+ Returns: double
+
+ Purpose: parse str to a float number
+ *******************************************************************************/
+ static double float_num(const string& str)
+ {
+ return atof(str.c_str());
+ }
+
+ /*******************************************************************************
+ Function: hl_lib::string_ref::float_num
+ Access: public static
+ Qualifier:
+ Returns: double
+
+ Purpose: parse this to a float number
+ *******************************************************************************/
+ double float_num() const
+ {
+ return float_num(*this);
+ }
+
+ /*******************************************************************************
+ Function: hl_lib::string_ref::compare_nocase
+ Access: public
+ Qualifier: const
+ Parameter: const string & str
+ Returns: int
+
+ Purpose: compare string no case
+ *******************************************************************************/
+ int compare_nocase(const string& str) const
+ {
+#ifdef _WIN32
+ return _stricmp(this->c_str(), str.c_str());
+#else
+ return strcasecmp(this->c_str(), str.c_str());
+#endif
+ }
+
+ /*******************************************************************************
+ Function: hl_lib::string_ref::compare_nocase
+ Access: public
+ Qualifier: const
+ Parameter: size_type index
+ Parameter: size_type length
+ Parameter: const string & str
+ Returns: int
+
+ Purpose: compare substring no case
+ *******************************************************************************/
+ int compare_nocase( size_type index, size_type length, const string &str ) const
+ {
+ string_ref temp = this->substr(index, length);
+ return temp.compare_nocase(str);
+ }
+
+ /*******************************************************************************
+ Function: hl_lib::string_ref::compare_nocase
+ Access: public
+ Qualifier: const
+ Parameter: size_type index
+ Parameter: size_type length
+ Parameter: const string & str
+ Parameter: size_type index2
+ Parameter: size_type length2
+ Returns: int
+
+ Purpose: compare two substring no case
+ *******************************************************************************/
+ int compare_nocase( size_type index, size_type length, const string &str, size_type index2, size_type length2) const
+ {
+ string_ref temp1 = this->substr(index, length);
+ string_ref temp2 = str.substr(index2, length2);
+ return temp1.compare_nocase(temp2);
+ }
+
+ };
+
+}
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/ParentProcessWatcher.cpp b/graphics/asymptote/LspCpp/LibLsp/lsp/ParentProcessWatcher.cpp
new file mode 100644
index 0000000000..6769f5112d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/ParentProcessWatcher.cpp
@@ -0,0 +1,106 @@
+#include "ParentProcessWatcher.h"
+#include <boost/process.hpp>
+
+#ifdef _WIN32
+#include <boost/process/windows.hpp>
+#endif
+
+#include <boost/filesystem.hpp>
+#include <boost/asio.hpp>
+#include <iostream>
+
+#include "ProcessIoService.h"
+#include "SimpleTimer.h"
+
+
+using namespace boost::asio::ip;
+using namespace std;
+
+struct ParentProcessWatcher::ParentProcessWatcherData : std::enable_shared_from_this<ParentProcessWatcherData>
+{
+ std::unique_ptr<SimpleTimer<boost::posix_time::seconds>> timer;
+ lsp::Log& _log;
+ std::function<void()> on_exit;
+ lsp::ProcessIoService asio_io;
+ std::shared_ptr < boost::process::opstream> write_to_service;
+ std::shared_ptr< boost::process::ipstream > read_from_service;
+ int pid;
+ const int _poll_delay_secs /*= 10*/;
+ std::string command;
+ std::shared_ptr<boost::process::child> c;
+
+ ParentProcessWatcherData(lsp::Log& log, int _pid,
+ const std::function<void()>&& callback, uint32_t poll_delay_secs) :
+ _log(log), on_exit(callback), pid(_pid), _poll_delay_secs(poll_delay_secs)
+ {
+#ifdef _WIN32
+ command = "cmd /c \"tasklist /FI \"PID eq " + std::to_string(pid) + "\" | findstr " +
+ std::to_string(pid) + "\"";
+#else
+ command = "ps -p " + std::to_string(pid);
+#endif
+
+ }
+
+ void run()
+ {
+ write_to_service = std::make_shared<boost::process::opstream>();
+ read_from_service = std::make_shared<boost::process::ipstream>();
+
+// const uint32_t POLL_DELAY_SECS = _poll_delay_secs;
+ auto self(shared_from_this());
+ std::error_code ec;
+ namespace bp = boost::process;
+ c = std::make_shared<bp::child>(asio_io.getIOService(), command,
+ ec,
+#ifdef _WIN32
+ bp::windows::hide,
+#endif
+ bp::std_out > *read_from_service,
+ bp::std_in < *write_to_service,
+ bp::on_exit([self](int exit_code, const std::error_code& ec_in) {
+ // the tasklist command should return 0 (parent process exists) or 1 (parent process doesn't exist)
+ if (exit_code == 1)//
+ {
+ if (self->on_exit)
+ {
+
+ std::thread([=]()
+ {
+ std::this_thread::sleep_for(std::chrono::seconds(3));
+ self->on_exit();
+ }).detach();
+ }
+ }
+ else
+ {
+ if (exit_code > 1)
+ {
+ self->_log.log(lsp::Log::Level::WARNING, "The tasklist command: '" + self->command + "' returns " + std::to_string(exit_code));
+ }
+
+ self->timer = std::make_unique<SimpleTimer<boost::posix_time::seconds>>(self->_poll_delay_secs, [=]() {
+ self->run();
+ });
+ }
+
+ }));
+ if (ec)
+ {
+ // fail
+ _log.log(lsp::Log::Level::SEVERE, "Start parent process watcher failed.");
+ }
+ }
+};
+
+ParentProcessWatcher::ParentProcessWatcher(lsp::Log& log, int pid,
+ const std::function<void()>&& callback, uint32_t poll_delay_secs) : d_ptr(new ParentProcessWatcherData(log, pid, std::move(callback), poll_delay_secs))
+{
+ d_ptr->run();
+}
+
+ParentProcessWatcher::~ParentProcessWatcher()
+{
+ if (d_ptr->timer)
+ d_ptr->timer->Stop();
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/ParentProcessWatcher.h b/graphics/asymptote/LspCpp/LibLsp/lsp/ParentProcessWatcher.h
new file mode 100644
index 0000000000..fa84e4109a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/ParentProcessWatcher.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/MessageIssue.h"
+#include <memory>
+
+class ParentProcessWatcher
+{
+public:
+ struct ParentProcessWatcherData;
+
+ ParentProcessWatcher(lsp::Log& log, int pid, const std::function<void()>&& callback, uint32_t poll_delay_secs = 10);
+
+ ~ParentProcessWatcher();
+
+ std::shared_ptr<ParentProcessWatcherData> d_ptr;
+};
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/ProcessIoService.h b/graphics/asymptote/LspCpp/LibLsp/lsp/ProcessIoService.h
new file mode 100644
index 0000000000..1389a1d5b7
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/ProcessIoService.h
@@ -0,0 +1,48 @@
+#pragma once
+#include <boost/asio.hpp>
+#include <iostream>
+
+namespace lsp
+{
+ class ProcessIoService
+ {
+ public:
+ using IOService = boost::asio::io_service;
+ using Work = boost::asio::io_service::work;
+ using WorkPtr = std::unique_ptr<Work>;
+
+ ProcessIoService() {
+
+ work_ = std::unique_ptr<Work>(new Work(ioService_));
+ auto temp_thread_ = new std::thread([this]
+ {
+ ioService_.run();
+ });
+ thread_ = std::unique_ptr<std::thread>(temp_thread_);
+ }
+
+ ProcessIoService(const ProcessIoService&) = delete;
+ ProcessIoService& operator=(const ProcessIoService&) = delete;
+
+ boost::asio::io_service& getIOService()
+ {
+ return ioService_;
+ }
+
+ void stop()
+ {
+
+ work_.reset();
+
+ thread_->join();
+
+ }
+
+ private:
+ IOService ioService_;
+ WorkPtr work_;
+ std::unique_ptr<std::thread> thread_;
+
+ };
+
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/ProtocolJsonHandler.cpp b/graphics/asymptote/LspCpp/LibLsp/lsp/ProtocolJsonHandler.cpp
new file mode 100644
index 0000000000..90e3fcda08
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/ProtocolJsonHandler.cpp
@@ -0,0 +1,716 @@
+#include "ProtocolJsonHandler.h"
+#include "general/initialize.h"
+#include "general/shutdown.h"
+#include "textDocument/code_action.h"
+#include "textDocument/code_lens.h"
+#include "textDocument/completion.h"
+
+
+#include "textDocument/did_close.h"
+
+#include "textDocument/highlight.h"
+#include "textDocument/document_link.h"
+#include "textDocument/formatting.h"
+#include "textDocument/hover.h"
+#include "textDocument/implementation.h"
+#include "textDocument/range_formatting.h"
+#include "textDocument/references.h"
+#include "textDocument/rename.h"
+#include "textDocument/signature_help.h"
+#include "textDocument/type_definition.h"
+#include "workspace/symbol.h"
+#include "textDocument/typeHierarchy.h"
+#include "out_list.h"
+#include "extention/jdtls/codeActionResult.h"
+#include "textDocument/declaration_definition.h"
+#include "textDocument/resolveCompletionItem.h"
+#include "textDocument/resolveCodeLens.h"
+#include "textDocument/colorPresentation.h"
+#include "textDocument/foldingRange.h"
+#include "textDocument/prepareRename.h"
+#include "textDocument/resolveTypeHierarchy.h"
+#include "textDocument/callHierarchy.h"
+#include "textDocument/selectionRange.h"
+#include "extention/jdtls/classFileContents.h"
+#include "extention/jdtls/buildWorkspace.h"
+#include "extention/jdtls/listOverridableMethods.h"
+#include "extention/jdtls/addOverridableMethods.h"
+#include "extention/jdtls/checkHashCodeEqualsStatus.h"
+#include "extention/jdtls/checkConstructorsStatus.h"
+#include "extention/jdtls/checkDelegateMethodsStatus.h"
+#include "extention/jdtls/checkToStringStatus.h"
+#include "extention/jdtls/executeCommand.h"
+#include "extention/jdtls/findLinks.h"
+#include "extention/jdtls/generateAccessors.h"
+#include "extention/jdtls/generateConstructors.h"
+#include "extention/jdtls/generateDelegateMethods.h"
+#include "extention/jdtls/generateHashCodeEquals.h"
+#include "extention/jdtls/generateToString.h"
+#include "extention/jdtls/getMoveDestinations.h"
+#include "extention/jdtls/Move.h"
+#include "extention/jdtls/organizeImports.h"
+#include "general/exit.h"
+#include "general/initialized.h"
+#include "extention/jdtls/projectConfigurationUpdate.h"
+#include "textDocument/did_change.h"
+#include "textDocument/did_open.h"
+#include "textDocument/did_save.h"
+#include "textDocument/publishDiagnostics.h"
+#include "textDocument/willSave.h"
+
+#include "workspace/didChangeWorkspaceFolders.h"
+#include "workspace/did_change_configuration.h"
+#include "workspace/did_change_watched_files.h"
+#include "windows/MessageNotify.h"
+#include "language/language.h"
+#include "client/registerCapability.h"
+#include "client/unregisterCapability.h"
+#include "LibLsp/JsonRpc/Cancellation.h"
+#include "textDocument/didRenameFiles.h"
+#include "textDocument/semanticHighlighting.h"
+#include "workspace/configuration.h"
+
+
+void AddStadardResponseJsonRpcMethod(MessageJsonHandler& handler)
+{
+
+ handler.method2response[td_initialize::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if(visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return td_initialize::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[td_shutdown::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_shutdown::response::ReflectReader(visitor);
+ };
+ handler.method2response[td_codeAction::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return td_codeAction::response::ReflectReader(visitor);
+ };
+ handler.method2response[td_codeLens::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_codeLens::response::ReflectReader(visitor);
+ };
+ handler.method2response[td_completion::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_completion::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[td_definition::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_definition::response::ReflectReader(visitor);
+ };
+ handler.method2response[td_declaration::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_declaration::response::ReflectReader(visitor);
+ };
+ handler.method2response[td_willSaveWaitUntil::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_willSaveWaitUntil::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[td_highlight::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_highlight::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[td_links::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_links::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[td_linkResolve::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_linkResolve::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[td_symbol::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_symbol::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[td_formatting::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_formatting::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[td_hover::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_hover::response::ReflectReader(visitor);
+
+ };
+
+ handler.method2response[td_implementation::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_implementation::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[td_rangeFormatting::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_rangeFormatting::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[td_references::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_references::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[td_rename::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_rename::response::ReflectReader(visitor);
+ };
+
+
+ handler.method2response[td_signatureHelp::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_signatureHelp::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[td_typeDefinition::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_typeDefinition::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[wp_executeCommand::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return wp_executeCommand::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[wp_symbol::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return wp_symbol::response::ReflectReader(visitor);
+ };
+ handler.method2response[td_typeHierarchy::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_typeHierarchy::response::ReflectReader(visitor);
+ };
+ handler.method2response[completionItem_resolve::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return completionItem_resolve::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[codeLens_resolve::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return codeLens_resolve::response::ReflectReader(visitor);
+
+ };
+
+ handler.method2response[td_colorPresentation::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return td_colorPresentation::response::ReflectReader(visitor);
+
+ };
+ handler.method2response[td_documentColor::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return td_documentColor::response::ReflectReader(visitor);
+
+ };
+ handler.method2response[td_foldingRange::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return td_foldingRange::response::ReflectReader(visitor);
+
+ };
+ handler.method2response[td_prepareRename::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return td_prepareRename::response::ReflectReader(visitor);
+
+ };
+ handler.method2response[typeHierarchy_resolve::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return typeHierarchy_resolve::response::ReflectReader(visitor);
+
+ };
+
+ handler.method2response[td_selectionRange::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return td_selectionRange::response::ReflectReader(visitor);
+
+ };
+ handler.method2response[td_didRenameFiles::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return td_didRenameFiles::response::ReflectReader(visitor);
+
+ };
+ handler.method2response[td_willRenameFiles::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return td_willRenameFiles::response::ReflectReader(visitor);
+
+ };
+
+}
+
+
+void AddJavaExtentionResponseJsonRpcMethod(MessageJsonHandler& handler)
+{
+ handler.method2response[java_classFileContents::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_classFileContents::response::ReflectReader(visitor);
+ };
+ handler.method2response[java_buildWorkspace::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_buildWorkspace::response::ReflectReader(visitor);
+ };
+ handler.method2response[java_listOverridableMethods::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_listOverridableMethods::response::ReflectReader(visitor);
+ };
+ handler.method2response[java_listOverridableMethods::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_listOverridableMethods::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[java_checkHashCodeEqualsStatus::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_checkHashCodeEqualsStatus::response::ReflectReader(visitor);
+ };
+
+
+ handler.method2response[java_addOverridableMethods::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_addOverridableMethods::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[java_checkConstructorsStatus::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_checkConstructorsStatus::response::ReflectReader(visitor);
+ };
+
+
+ handler.method2response[java_checkDelegateMethodsStatus::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_checkDelegateMethodsStatus::response::ReflectReader(visitor);
+ };
+ handler.method2response[java_checkToStringStatus::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_checkToStringStatus::response::ReflectReader(visitor);
+ };
+
+
+ handler.method2response[java_generateAccessors::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_generateAccessors::response::ReflectReader(visitor);
+ };
+ handler.method2response[java_generateConstructors::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_generateConstructors::response::ReflectReader(visitor);
+ };
+ handler.method2response[java_generateDelegateMethods::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_generateDelegateMethods::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[java_generateHashCodeEquals::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_generateHashCodeEquals::response::ReflectReader(visitor);
+ };
+ handler.method2response[java_generateToString::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_generateToString::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[java_generateToString::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_generateToString::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[java_getMoveDestinations::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_getMoveDestinations::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[java_getRefactorEdit::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_getRefactorEdit::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[java_move::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_move::response ::ReflectReader(visitor);
+ };
+
+ handler.method2response[java_organizeImports::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_organizeImports::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[java_resolveUnimplementedAccessors::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_resolveUnimplementedAccessors::response::ReflectReader(visitor);
+ };
+
+ handler.method2response[java_searchSymbols::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return java_searchSymbols::response::ReflectReader(visitor);
+ };
+
+ handler.method2request[WorkspaceConfiguration::request::kMethodInfo] = [](Reader& visitor)
+ {
+ return WorkspaceConfiguration::request::ReflectReader(visitor);
+ };
+ handler.method2request[WorkspaceFolders::request::kMethodInfo] = [](Reader& visitor)
+ {
+ return WorkspaceFolders::request::ReflectReader(visitor);
+ };
+
+}
+
+void AddNotifyJsonRpcMethod(MessageJsonHandler& handler)
+{
+
+ handler.method2notification[Notify_Exit::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_Exit::notify::ReflectReader(visitor);
+ };
+ handler.method2notification[Notify_InitializedNotification::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_InitializedNotification::notify::ReflectReader(visitor);
+ };
+
+ handler.method2notification[java_projectConfigurationUpdate::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return java_projectConfigurationUpdate::notify::ReflectReader(visitor);
+ };
+
+ handler.method2notification[Notify_TextDocumentDidChange::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_TextDocumentDidChange::notify::ReflectReader(visitor);
+ };
+
+ handler.method2notification[Notify_TextDocumentDidClose::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_TextDocumentDidClose::notify::ReflectReader(visitor);
+ };
+
+
+ handler.method2notification[Notify_TextDocumentDidOpen::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_TextDocumentDidOpen::notify::ReflectReader(visitor);
+ };
+
+ handler.method2notification[Notify_TextDocumentDidSave::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_TextDocumentDidSave::notify::ReflectReader(visitor);
+ };
+
+ handler.method2notification[Notify_TextDocumentPublishDiagnostics::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_TextDocumentPublishDiagnostics::notify::ReflectReader(visitor);
+ };
+ handler.method2notification[Notify_semanticHighlighting::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_semanticHighlighting::notify::ReflectReader(visitor);
+ };
+ handler.method2notification[td_willSave::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return td_willSave::notify::ReflectReader(visitor);
+ };
+
+ handler.method2notification[Notify_LogMessage::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_LogMessage::notify::ReflectReader(visitor);
+ };
+ handler.method2notification[Notify_ShowMessage::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_ShowMessage::notify::ReflectReader(visitor);
+ };
+ handler.method2notification[Notify_WorkspaceDidChangeWorkspaceFolders::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_WorkspaceDidChangeWorkspaceFolders::notify::ReflectReader(visitor);
+ };
+
+ handler.method2notification[Notify_WorkspaceDidChangeConfiguration::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_WorkspaceDidChangeConfiguration::notify::ReflectReader(visitor);
+ };
+
+
+ handler.method2notification[Notify_WorkspaceDidChangeWatchedFiles::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_WorkspaceDidChangeWatchedFiles::notify::ReflectReader(visitor);
+ };
+
+ handler.method2notification[Notify_sendNotification::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_sendNotification::notify::ReflectReader(visitor);
+ };
+ handler.method2notification[lang_status::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return lang_status::notify::ReflectReader(visitor);
+ };
+ handler.method2notification[lang_actionableNotification::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return lang_actionableNotification::notify::ReflectReader(visitor);
+ };
+ handler.method2notification[lang_progressReport::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return lang_progressReport::notify::ReflectReader(visitor);
+ };
+ handler.method2notification[lang_eventNotification::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return lang_eventNotification::notify::ReflectReader(visitor);
+ };
+}
+
+void AddRequstJsonRpcMethod(MessageJsonHandler& handler)
+{
+ handler.method2request[Req_ClientRegisterCapability::request::kMethodInfo]= [](Reader& visitor)
+ {
+
+ return Req_ClientRegisterCapability::request::ReflectReader(visitor);
+ };
+ handler.method2request[Req_ClientUnregisterCapability::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+ return Req_ClientUnregisterCapability::request::ReflectReader(visitor);
+ };
+}
+
+void AddStandardRequestJsonRpcMethod(MessageJsonHandler& handler)
+{
+
+ handler.method2request[td_initialize::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+ return td_initialize::request::ReflectReader(visitor);
+ };
+ handler.method2request[td_shutdown::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+ return td_shutdown::request::ReflectReader(visitor);
+ };
+ handler.method2request[td_codeAction::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+
+ return td_codeAction::request::ReflectReader(visitor);
+ };
+ handler.method2request[td_codeLens::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+ return td_codeLens::request::ReflectReader(visitor);
+ };
+ handler.method2request[td_completion::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+ return td_completion::request::ReflectReader(visitor);
+ };
+
+ handler.method2request[td_definition::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+ return td_definition::request::ReflectReader(visitor);
+ };
+ handler.method2request[td_declaration::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+ return td_declaration::request::ReflectReader(visitor);
+ };
+ handler.method2request[td_willSaveWaitUntil::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+ return td_willSaveWaitUntil::request::ReflectReader(visitor);
+ };
+
+ handler.method2request[td_highlight::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+ return td_highlight::request::ReflectReader(visitor);
+ };
+
+ handler.method2request[td_links::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+ return td_links::request::ReflectReader(visitor);
+ };
+
+ handler.method2request[td_linkResolve::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+ return td_linkResolve::request::ReflectReader(visitor);
+ };
+
+ handler.method2request[td_symbol::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+ return td_symbol::request::ReflectReader(visitor);
+ };
+
+ handler.method2request[td_formatting::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+ return td_formatting::request::ReflectReader(visitor);
+ };
+
+ handler.method2request[td_hover::request::kMethodInfo] = [](Reader& visitor)
+ {
+ return td_hover::request::ReflectReader(visitor);
+ };
+
+ handler.method2request[td_implementation::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+ return td_implementation::request::ReflectReader(visitor);
+ };
+
+ handler.method2request[td_didRenameFiles::request::kMethodInfo] = [](Reader& visitor)
+ {
+
+ return td_didRenameFiles::request::ReflectReader(visitor);
+ };
+
+ handler.method2request[td_willRenameFiles::request::kMethodInfo] = [](Reader& visitor)
+ {
+ return td_willRenameFiles::request::ReflectReader(visitor);
+ };
+}
+
+
+lsp::ProtocolJsonHandler::ProtocolJsonHandler()
+{
+ AddStadardResponseJsonRpcMethod(*this);
+ AddJavaExtentionResponseJsonRpcMethod(*this);
+ AddNotifyJsonRpcMethod(*this);
+ AddStandardRequestJsonRpcMethod(*this);
+ AddRequstJsonRpcMethod(*this);
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/ProtocolJsonHandler.h b/graphics/asymptote/LspCpp/LibLsp/lsp/ProtocolJsonHandler.h
new file mode 100644
index 0000000000..b563f810d2
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/ProtocolJsonHandler.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/MessageJsonHandler.h"
+namespace lsp {
+ class ProtocolJsonHandler : public MessageJsonHandler
+ {
+ public:
+ ProtocolJsonHandler();
+ };
+
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/ResourceOperation.h b/graphics/asymptote/LspCpp/LibLsp/lsp/ResourceOperation.h
new file mode 100644
index 0000000000..caf2ea5d5f
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/ResourceOperation.h
@@ -0,0 +1,121 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+#include <vector>
+#include "lsDocumentUri.h"
+#include "LibLsp/lsp/lsAny.h"
+#include "LibLsp/lsp/lsTextEdit.h"
+struct ResourceOperation {
+ std::string kind;
+ virtual ~ResourceOperation() = default;
+
+ MAKE_SWAP_METHOD(ResourceOperation, kind);
+};
+MAKE_REFLECT_STRUCT(ResourceOperation, kind);
+extern void Reflect(Writer& visitor, ResourceOperation* value);
+struct CreateFileOptions{
+
+ /**
+ * Overwrite existing file. Overwrite wins over `ignoreIfExists`
+ */
+ boost::optional<bool> overwrite = false;
+
+ /**
+ * Ignore if exists.
+ */
+ boost::optional< bool> ignoreIfExists =false;
+
+ MAKE_SWAP_METHOD(CreateFileOptions, overwrite, ignoreIfExists)
+};
+MAKE_REFLECT_STRUCT(CreateFileOptions, overwrite, ignoreIfExists)
+struct lsCreateFile :public ResourceOperation {
+
+ /**
+ * The resource to create.
+ */
+ lsCreateFile();
+ lsDocumentUri uri;
+
+ /**
+ * Additional options
+ */
+ boost::optional<CreateFileOptions> options;
+
+
+ /**
+ * An optional annotation identifer describing the operation.
+ *
+ * @since 3.16.0
+ */
+ boost::optional<lsChangeAnnotationIdentifier> annotationId;
+
+ MAKE_SWAP_METHOD(lsCreateFile, kind, uri, options, annotationId)
+};
+MAKE_REFLECT_STRUCT(lsCreateFile, kind, uri,options, annotationId)
+
+
+struct DeleteFileOptions {
+ /**
+ * Delete the content recursively if a folder is denoted.
+ */
+ boost::optional<bool> recursive = false;
+
+ /**
+ * Ignore the operation if the file doesn't exist.
+ */
+ boost::optional<bool> ignoreIfNotExists = false;
+
+
+ MAKE_SWAP_METHOD(DeleteFileOptions, recursive, ignoreIfNotExists);
+};
+
+MAKE_REFLECT_STRUCT(DeleteFileOptions, recursive, ignoreIfNotExists)
+
+struct lsDeleteFile :public ResourceOperation {
+ /**
+ * The file to delete.
+ */
+ lsDeleteFile();
+ lsDocumentUri uri;
+
+ /**
+ * Delete options.
+ */
+ boost::optional<DeleteFileOptions> options;
+
+ MAKE_SWAP_METHOD(lsDeleteFile, kind, uri, options);
+};
+MAKE_REFLECT_STRUCT(lsDeleteFile, kind, uri,options);
+
+typedef CreateFileOptions RenameFileOptions;
+struct lsRenameFile :public ResourceOperation {
+ /**
+ * The old (existing) location.
+ */
+ lsRenameFile();
+ lsDocumentUri oldUri;
+
+ /**
+ * The new location.
+ */
+
+ lsDocumentUri newUri;
+
+ /**
+ * Rename options.
+ */
+ boost::optional<RenameFileOptions> options;
+
+ /**
+ * An optional annotation identifer describing the operation.
+ *
+ * @since 3.16.0
+ */
+ boost::optional<lsChangeAnnotationIdentifier> annotationId;
+
+ MAKE_SWAP_METHOD(lsRenameFile, kind, oldUri, newUri, options, annotationId)
+};
+MAKE_REFLECT_STRUCT(lsRenameFile, kind, oldUri, newUri, options, annotationId);
+
+
+extern ResourceOperation* GetResourceOperation(lsp::Any& lspAny); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/SimpleTimer.h b/graphics/asymptote/LspCpp/LibLsp/lsp/SimpleTimer.h
new file mode 100644
index 0000000000..0a2707979d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/SimpleTimer.h
@@ -0,0 +1,49 @@
+#pragma once
+#include <thread>
+#include <atomic>
+#include <functional>
+#include <boost/asio.hpp>
+
+template<typename Duration = boost::posix_time::milliseconds>
+class SimpleTimer
+{
+public:
+ SimpleTimer(unsigned int duration,const std::function<void()>& _call_back)
+ :is_running_(true), call_back(_call_back), _deadline_timer(_ios, Duration(duration))
+ {
+ _deadline_timer.async_wait([&](const boost::system::error_code& e)
+ {
+ if (e.value() == boost::asio::error::operation_aborted)
+ {
+ return;
+ }
+ if(is_running_.load(std::memory_order_relaxed))
+ {
+ call_back();
+ }
+
+ });
+ _thread = std::thread([this] { _ios.run(); });
+ }
+ ~SimpleTimer()
+ {
+ Stop();
+ }
+ void Stop()
+ {
+ is_running_.store(false, std::memory_order_relaxed);
+ _ios.stop();
+ if (_thread.joinable())
+ {
+ _thread.join();
+ }
+ }
+private:
+ std::atomic_bool is_running_;
+ std::function<void()> call_back;
+ boost::asio::io_service _ios;
+ boost::asio::deadline_timer _deadline_timer;
+ std::thread _thread;
+
+
+};
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/client/registerCapability.h b/graphics/asymptote/LspCpp/LibLsp/lsp/client/registerCapability.h
new file mode 100644
index 0000000000..fa5d111403
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/client/registerCapability.h
@@ -0,0 +1,49 @@
+#pragma once
+#include "LibLsp/JsonRpc/message.h"
+#include "LibLsp/lsp/lsDocumentUri.h"
+
+/**
+ * General parameters to register for a capability.
+ */
+
+struct Registration {
+ static Registration Create(const std::string& method);
+ /**
+ * The id used to register the request. The id can be used to deregister
+ * the request again.
+ */
+ std::string id;
+
+ /**
+ * The method / capability to register for.
+ */
+
+ std::string method;
+
+ MAKE_SWAP_METHOD(Registration, id, method);
+};
+
+
+MAKE_REFLECT_STRUCT(Registration, id, method);
+
+/**
+ * The client/registerCapability request is sent from the server to the client to register
+ * for a new capability on the client side. Not all clients need to support dynamic
+ * capability registration. A client opts in via the dynamicRegistration property on the
+ * specific client capabilities. A client can even provide dynamic registration for
+ * capability A but not for capability B (see TextDocumentClientCapabilities as an example).
+ */
+struct RegistrationParams
+{
+ std::vector<Registration> registrations;
+ MAKE_SWAP_METHOD(RegistrationParams, registrations);
+};
+/**
+ * The client/registerCapability request is sent from the server to the client
+ * to register for a new capability on the client side.
+ * Not all clients need to support dynamic capability registration.
+ * A client opts in via the ClientCapabilities.dynamicRegistration property
+ */
+MAKE_REFLECT_STRUCT(RegistrationParams, registrations);
+
+DEFINE_REQUEST_RESPONSE_TYPE(Req_ClientRegisterCapability, RegistrationParams,JsonNull, "client/registerCapability"); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/client/unregisterCapability.h b/graphics/asymptote/LspCpp/LibLsp/lsp/client/unregisterCapability.h
new file mode 100644
index 0000000000..aa51d7efee
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/client/unregisterCapability.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include "LibLsp/lsp/lsDocumentUri.h"
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+/**
+ * General parameters to unregister a capability.
+ */
+
+struct Unregistration {
+ /**
+ * The id used to unregister the request or notification. Usually an id
+ * provided during the register request.
+ */
+
+ std::string id;
+
+ /**
+ * The method / capability to unregister for.
+ */
+
+ std::string method;
+
+ MAKE_SWAP_METHOD(Unregistration, id, method);
+};
+MAKE_REFLECT_STRUCT(Unregistration, id, method);
+/**
+ * The client/unregisterCapability request is sent from the server to the client to unregister
+ * a previously registered capability.
+ */
+struct UnregistrationParams
+{
+ std::vector<Unregistration> unregisterations;
+ MAKE_SWAP_METHOD(UnregistrationParams, unregisterations);
+};
+
+MAKE_REFLECT_STRUCT(UnregistrationParams, unregisterations);
+
+DEFINE_REQUEST_RESPONSE_TYPE(Req_ClientUnregisterCapability, UnregistrationParams,JsonNull, "client/unregisterCapability"); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/Move.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/Move.h
new file mode 100644
index 0000000000..c0beb625f2
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/Move.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include <string>
+#include "LibLsp/lsp/CodeActionParams.h"
+#include "getMoveDestinations.h"
+#include "getRefactorEdit.h"
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_move, MoveParams, RefactorWorkspaceEdit, "java/move");
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/OverridableMethod.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/OverridableMethod.h
new file mode 100644
index 0000000000..cfb17fdf34
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/OverridableMethod.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+#include <string>
+struct OverridableMethod
+{
+ std::string bindingKey;
+ std::string name;
+ std::vector<std::string> parameters;
+ bool unimplemented = false;
+ std::string declaringClass;
+ std::string declaringClassType;
+
+ void swap(OverridableMethod& arg) noexcept
+ {
+ bindingKey.swap(arg.bindingKey);
+ name.swap(arg.name);
+ parameters.swap(arg.parameters);
+ declaringClass.swap(arg.declaringClass);
+ declaringClassType.swap(arg.declaringClassType);
+ std::swap(unimplemented, arg.unimplemented);
+ }
+};
+MAKE_REFLECT_STRUCT(OverridableMethod, bindingKey, name, parameters, unimplemented, declaringClass, declaringClassType);
+
+struct OverridableMethodsResponse
+{
+ std::string type;
+ std::vector<OverridableMethod> methods;
+
+ MAKE_SWAP_METHOD(OverridableMethodsResponse, type, methods)
+};
+
+MAKE_REFLECT_STRUCT(OverridableMethodsResponse, type, methods)
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/WorkspaceSymbolParams.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/WorkspaceSymbolParams.h
new file mode 100644
index 0000000000..c7faa94d6c
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/WorkspaceSymbolParams.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+#include <string>
+
+
+struct WorkspaceSymbolParams
+{
+ std::string query;
+ MAKE_SWAP_METHOD(WorkspaceSymbolParams, query);
+};
+MAKE_REFLECT_STRUCT(WorkspaceSymbolParams, query);
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/addOverridableMethods.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/addOverridableMethods.h
new file mode 100644
index 0000000000..5da14a452a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/addOverridableMethods.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/message.h"
+#include "OverridableMethod.h"
+#include "LibLsp/lsp/CodeActionParams.h"
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+struct AddOverridableMethodParams {
+ lsCodeActionParams context;
+ std::vector<OverridableMethod> overridableMethods;
+
+ MAKE_SWAP_METHOD(AddOverridableMethodParams, context, overridableMethods);
+};
+
+MAKE_REFLECT_STRUCT(AddOverridableMethodParams, context, overridableMethods);
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_addOverridableMethods, AddOverridableMethodParams, lsWorkspaceEdit, "java/addOverridableMethods");
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/buildWorkspace.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/buildWorkspace.h
new file mode 100644
index 0000000000..a2c2c062cc
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/buildWorkspace.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "WorkspaceSymbolParams.h"
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+
+
+
+
+enum class BuildWorkspaceStatus : uint8_t{
+
+ FAILED, SUCCEED, WITH_ERROR, CANCELLED,
+};
+MAKE_REFLECT_TYPE_PROXY(BuildWorkspaceStatus)
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_buildWorkspace, bool, BuildWorkspaceStatus, "java/buildWorkspace"); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkConstructorsStatus.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkConstructorsStatus.h
new file mode 100644
index 0000000000..261a0cc551
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkConstructorsStatus.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include "LibLsp/lsp/CodeActionParams.h"
+#include "checkHashCodeEqualsStatus.h"
+
+struct LspMethodBinding {
+ std::string bindingKey;
+ std::string name;
+ std::vector< std::string> parameters;
+
+ MAKE_SWAP_METHOD(LspMethodBinding, bindingKey, name, parameters);
+};
+MAKE_REFLECT_STRUCT(LspMethodBinding, bindingKey, name, parameters);
+
+
+struct CheckConstructorsResponse {
+ std::vector<LspMethodBinding> constructors;
+ std::vector<LspVariableBinding> fields;
+ MAKE_SWAP_METHOD(CheckConstructorsResponse, constructors, fields)
+};
+MAKE_REFLECT_STRUCT(CheckConstructorsResponse, constructors,fields)
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_checkConstructorsStatus, lsCodeActionParams, CheckConstructorsResponse,"java/checkConstructorsStatus")
+
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkDelegateMethodsStatus.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkDelegateMethodsStatus.h
new file mode 100644
index 0000000000..729639eafa
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkDelegateMethodsStatus.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/CodeActionParams.h"
+#include "checkHashCodeEqualsStatus.h"
+#include "checkConstructorsStatus.h"
+
+struct LspDelegateField {
+ LspVariableBinding field;
+ std::vector<LspMethodBinding> delegateMethods;
+
+ MAKE_SWAP_METHOD(LspDelegateField, field, delegateMethods);
+};
+MAKE_REFLECT_STRUCT(LspDelegateField, field, delegateMethods);
+
+
+struct CheckDelegateMethodsResponse {
+ std::vector<LspDelegateField> delegateFields;
+
+ MAKE_SWAP_METHOD(CheckDelegateMethodsResponse, delegateFields)
+};
+MAKE_REFLECT_STRUCT(CheckDelegateMethodsResponse, delegateFields)
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_checkDelegateMethodsStatus,
+ lsCodeActionParams, CheckDelegateMethodsResponse, "java/checkDelegateMethodsStatus");
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkHashCodeEqualsStatus.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkHashCodeEqualsStatus.h
new file mode 100644
index 0000000000..1d9652dd44
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkHashCodeEqualsStatus.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include <LibLsp/lsp/lsCodeAction.h>
+
+#include "LibLsp/lsp/CodeActionParams.h"
+
+struct LspVariableBinding {
+ std::string bindingKey;
+ std::string name;
+ std::string type;
+ bool isField;
+ void swap(LspVariableBinding& arg) noexcept
+ {
+ bindingKey.swap(arg.bindingKey);
+ name.swap(arg.name);
+ type.swap(arg.type);
+ std::swap(isField, arg.isField);
+ }
+};
+MAKE_REFLECT_STRUCT(LspVariableBinding, bindingKey, name, type, isField)
+
+struct CheckHashCodeEqualsResponse {
+ std::string type;
+ std::vector<LspVariableBinding> fields;
+ std::vector<std::string> existingMethods;
+ MAKE_SWAP_METHOD(CheckHashCodeEqualsResponse, type, fields, type, existingMethods)
+};
+MAKE_REFLECT_STRUCT(CheckHashCodeEqualsResponse, type, fields, type, existingMethods)
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_checkHashCodeEqualsStatus,
+ lsCodeActionParams, CheckHashCodeEqualsResponse, "java/checkHashCodeEqualsStatus")
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkToStringStatus.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkToStringStatus.h
new file mode 100644
index 0000000000..24580d94c0
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/checkToStringStatus.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/CodeActionParams.h"
+#include "checkHashCodeEqualsStatus.h"
+struct CheckToStringResponse {
+ std::string type;
+ std::vector<LspVariableBinding> fields;
+ bool exists;
+ void swap(CheckToStringResponse& arg) noexcept
+ {
+ type.swap(arg.type);
+ fields.swap(arg.fields);
+ std::swap(exists, arg.exists);
+ }
+};
+MAKE_REFLECT_STRUCT(CheckToStringResponse,type,fields,exists)
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_checkToStringStatus,
+ lsCodeActionParams, CheckToStringResponse ,"java/checkToStringStatus")
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/classFileContents.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/classFileContents.h
new file mode 100644
index 0000000000..70eb121b99
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/classFileContents.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include <string>
+#include "LibLsp/lsp/lsTextDocumentIdentifier.h"
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_classFileContents, lsTextDocumentIdentifier, std::string ,"java/classFileContents");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/codeActionResult.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/codeActionResult.h
new file mode 100644
index 0000000000..02024e3d93
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/codeActionResult.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+#include "LibLsp/JsonRpc/message.h"
+#include "LibLsp/lsp/lsCodeAction.h"
+#include "LibLsp/lsp/workspace/execute_command.h"
+#include <set>
+#include "LibLsp/lsp/textDocument/code_action.h"
+
+namespace SourceAssistProcessor {
+
+ /*std::set<std::string> UNSUPPORTED_RESOURCES = { "module-info.java", "package-info.java"
+ };*/
+
+// static const char* COMMAND_ID_ACTION_OVERRIDEMETHODSPROMPT = "java.action.overrideMethodsPrompt";
+// static const char* COMMAND_ID_ACTION_HASHCODEEQUALSPROMPT = "java.action.hashCodeEqualsPrompt";
+// static const char* COMMAND_ID_ACTION_ORGANIZEIMPORTS = "java.action.organizeImports";
+// static const char* COMMAND_ID_ACTION_GENERATETOSTRINGPROMPT = "java.action.generateToStringPrompt";
+// static const char* COMMAND_ID_ACTION_GENERATEACCESSORSPROMPT = "java.action.generateAccessorsPrompt";
+// static const char* COMMAND_ID_ACTION_GENERATECONSTRUCTORSPROMPT = "java.action.generateConstructorsPrompt";
+// static const char* COMMAND_ID_ACTION_GENERATEDELEGATEMETHODSPROMPT = "java.action.generateDelegateMethodsPrompt";
+};
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/executeCommand.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/executeCommand.h
new file mode 100644
index 0000000000..92d4a3627b
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/executeCommand.h
@@ -0,0 +1,29 @@
+#pragma once
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include <string>
+#include "LibLsp/lsp/lsWorkspaceEdit.h"
+#include "LibLsp/lsp/ExecuteCommandParams.h"
+namespace buildpath
+{
+// static const char* EDIT_ORGNIZEIMPORTS = "java.edit.organizeImports";
+// static const char* RESOLVE_SOURCE_ATTACHMENT = "java.project.resolveSourceAttachment";
+
+// static const char* UPDATE_SOURCE_ATTACHMENT = "java.project.updateSourceAttachment";
+
+// static const char* ADD_TO_SOURCEPATH = "java.project.addToSourcePath";
+
+// static const char* REMOVE_FROM_SOURCEPATH = "java.project.removeFromSourcePath";
+
+// static const char* LIST_SOURCEPATHS = "java.project.listSourcePaths";
+ struct Result {
+ bool status;
+ std::string message;
+ };
+
+
+
+}
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_executeCommand, ExecuteCommandParams, lsWorkspaceEdit, "java/executeCommand");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/findLinks.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/findLinks.h
new file mode 100644
index 0000000000..d184c675d8
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/findLinks.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include <string>
+#include "LibLsp/lsp/CodeActionParams.h"
+#include "getRefactorEdit.h"
+#include "LibLsp/lsp/lsTextDocumentPositionParams.h"
+
+struct FindLinksParams {
+ // Supported link types: superImplementation
+ std::string type;
+ lsTextDocumentPositionParams position;
+
+ MAKE_SWAP_METHOD(FindLinksParams, type, position)
+};
+MAKE_REFLECT_STRUCT(FindLinksParams,type,position)
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_findLinks, FindLinksParams,lsp::Any, "java/findLinks");
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateAccessors.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateAccessors.h
new file mode 100644
index 0000000000..200d840e94
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateAccessors.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include <string>
+#include "checkHashCodeEqualsStatus.h"
+#include "resolveUnimplementedAccessors.h"
+
+
+struct GenerateAccessorsParams {
+ lsCodeActionParams context;
+ std::vector<AccessorField> accessors;
+
+
+ MAKE_SWAP_METHOD(GenerateAccessorsParams, context, accessors)
+};
+MAKE_REFLECT_STRUCT(GenerateAccessorsParams, context, accessors)
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_generateAccessors, GenerateAccessorsParams, lsWorkspaceEdit, "java/generateAccessors");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateConstructors.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateConstructors.h
new file mode 100644
index 0000000000..77c49a66a2
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateConstructors.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include <string>
+#include "checkHashCodeEqualsStatus.h"
+#include "checkConstructorsStatus.h"
+
+
+struct GenerateConstructorsParams {
+ lsCodeActionParams context;
+ std::vector<LspMethodBinding> constructors;
+ std::vector< LspVariableBinding >fields;
+ MAKE_SWAP_METHOD(GenerateConstructorsParams, context, fields)
+};
+MAKE_REFLECT_STRUCT(GenerateConstructorsParams, context, fields)
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_generateConstructors, GenerateConstructorsParams, lsWorkspaceEdit, "java/generateConstructors");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateDelegateMethods.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateDelegateMethods.h
new file mode 100644
index 0000000000..8958ae4d7e
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateDelegateMethods.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include <string>
+#include "checkHashCodeEqualsStatus.h"
+#include "checkConstructorsStatus.h"
+
+struct LspDelegateEntry {
+ LspVariableBinding field;
+ LspMethodBinding delegateMethod;
+ MAKE_SWAP_METHOD(LspDelegateEntry, field, delegateMethod);
+};
+MAKE_REFLECT_STRUCT(LspDelegateEntry, field, delegateMethod);
+
+
+struct GenerateDelegateMethodsParams {
+ lsCodeActionParams context;
+ std::vector<LspDelegateEntry> delegateEntries;
+ MAKE_SWAP_METHOD(GenerateDelegateMethodsParams, context, delegateEntries)
+};
+MAKE_REFLECT_STRUCT(GenerateDelegateMethodsParams, context, delegateEntries)
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_generateDelegateMethods, GenerateDelegateMethodsParams, lsWorkspaceEdit, "java/generateDelegateMethods");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateHashCodeEquals.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateHashCodeEquals.h
new file mode 100644
index 0000000000..937c358733
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateHashCodeEquals.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include <LibLsp/lsp/lsCodeAction.h>
+
+#include "LibLsp/lsp/CodeActionParams.h"
+#include "checkHashCodeEqualsStatus.h"
+
+struct GenerateHashCodeEqualsParams {
+ lsCodeActionParams context;
+ std::vector<LspVariableBinding> fields;
+ bool regenerate= false;
+ void swap(GenerateHashCodeEqualsParams& arg) noexcept
+ {
+ context.swap(arg.context);
+ fields.swap(arg.fields);
+ std::swap(regenerate, arg.regenerate);
+ }
+};
+MAKE_REFLECT_STRUCT(GenerateHashCodeEqualsParams, context, fields, regenerate);
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_generateHashCodeEquals, GenerateHashCodeEqualsParams, lsWorkspaceEdit, "java/generateHashCodeEquals")
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateToString.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateToString.h
new file mode 100644
index 0000000000..1f8ccc73b8
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/generateToString.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include <string>
+#include "checkHashCodeEqualsStatus.h"
+
+
+struct GenerateToStringParams {
+ lsCodeActionParams context;
+ std::vector< LspVariableBinding >fields;
+
+ MAKE_SWAP_METHOD(GenerateToStringParams, context, fields)
+
+};
+MAKE_REFLECT_STRUCT(GenerateToStringParams, context, fields)
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_generateToString, GenerateToStringParams, lsWorkspaceEdit, "java/generateToString");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/getMoveDestinations.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/getMoveDestinations.h
new file mode 100644
index 0000000000..bcbf6f8c2b
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/getMoveDestinations.h
@@ -0,0 +1,65 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include <string>
+#include "LibLsp/lsp/lsAny.h"
+#include "LibLsp/lsp/CodeActionParams.h"
+
+struct MoveKindInfo
+{
+ static std::string moveResource()
+ {
+ return "moveResource";
+ }
+ static std::string moveInstanceMethod()
+ {
+ return "moveInstanceMethod";
+ }
+ static std::string moveStaticMember()
+ {
+ return "moveStaticMember";
+ }
+};
+
+struct MoveParams {
+ /**
+ * The supported move kind: moveResource, moveInstanceMethod, moveStaticMember,
+ * moveTypeToNewFile.
+ */
+ std::string moveKind;
+ /**
+ * The selected resource uris when the move operation is triggered.
+ */
+ std::vector<std::string> sourceUris;
+ /**
+ * The code action params when the move operation is triggered.
+ */
+ boost::optional<lsCodeActionParams> params;
+ /**
+ * The possible destination: a folder/package, class, instanceDeclaration.
+ */
+ lsp::Any destination;
+ bool updateReferences;
+ void swap(MoveParams& arg) noexcept
+ {
+ moveKind.swap(arg.moveKind);
+ sourceUris.swap(arg.sourceUris);
+ params.swap(arg.params);
+ destination.swap(arg.destination);
+ std::swap(updateReferences, arg.updateReferences);
+ }
+};
+MAKE_REFLECT_STRUCT(MoveParams, moveKind, sourceUris, params, destination, updateReferences);
+
+struct MoveDestinationsResponse {
+ std::string errorMessage;
+ std::vector<lsp::Any > destinations;
+ MAKE_SWAP_METHOD(MoveDestinationsResponse, errorMessage, destinations);
+};
+MAKE_REFLECT_STRUCT(MoveDestinationsResponse, errorMessage, destinations);
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_getMoveDestinations, MoveParams, MoveDestinationsResponse, "java/getMoveDestinations");
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/getRefactorEdit.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/getRefactorEdit.h
new file mode 100644
index 0000000000..e46327075a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/getRefactorEdit.h
@@ -0,0 +1,77 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+
+
+#include <string>
+#include <vector>
+#include "WorkspaceSymbolParams.h"
+#include "LibLsp/lsp/method_type.h"
+#include "LibLsp/lsp/textDocument/code_action.h"
+#include "LibLsp/lsp/lsFormattingOptions.h"
+
+namespace
+RefactorProposalUtility
+{
+ extern const char* APPLY_REFACTORING_COMMAND_ID;
+ extern const char* EXTRACT_VARIABLE_ALL_OCCURRENCE_COMMAND;
+ extern const char* EXTRACT_VARIABLE_COMMAND;
+ extern const char* EXTRACT_CONSTANT_COMMAND;
+ extern const char* EXTRACT_METHOD_COMMAND;
+ extern const char* EXTRACT_FIELD_COMMAND;
+ extern const char* CONVERT_VARIABLE_TO_FIELD_COMMAND;
+ extern const char* MOVE_FILE_COMMAND;
+ extern const char* MOVE_INSTANCE_METHOD_COMMAND;
+ extern const char* MOVE_STATIC_MEMBER_COMMAND;
+ extern const char* MOVE_TYPE_COMMAND;
+};
+
+
+struct RenamePosition {
+ lsDocumentUri uri;
+ int offset = 0;
+ int length = 0;
+ void swap(RenamePosition& arg) noexcept
+ {
+ uri.swap(arg.uri);
+ std::swap(offset, arg.offset);
+ std::swap(length, arg.length);
+ }
+};
+MAKE_REFLECT_STRUCT(RenamePosition, uri, offset, length);
+
+struct GetRefactorEditParams
+{
+ std::string command;
+ std::vector<lsp::Any> commandArguments;
+ lsCodeActionParams context;
+ boost::optional<lsFormattingOptions> options;
+ MAKE_SWAP_METHOD(GetRefactorEditParams, command, context, options);
+};
+MAKE_REFLECT_STRUCT(GetRefactorEditParams, command, context, options);
+
+
+
+
+struct RefactorWorkspaceEdit {
+ /**
+ * The workspace edit this code action performs.
+ */
+ lsWorkspaceEdit edit;
+ /**
+ * A command this code action executes. If a code action provides a edit and a
+ * command, first the edit is executed and then the command.
+ */
+
+ boost::optional<std::string> errorMessage;
+
+ boost::optional < lsCommandWithAny > command;
+
+ MAKE_SWAP_METHOD(RefactorWorkspaceEdit, edit, command, errorMessage)
+};
+MAKE_REFLECT_STRUCT(RefactorWorkspaceEdit,edit,command,errorMessage)
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_getRefactorEdit, GetRefactorEditParams, RefactorWorkspaceEdit, "java/getRefactorEdit");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/listOverridableMethods.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/listOverridableMethods.h
new file mode 100644
index 0000000000..13b73ce5c2
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/listOverridableMethods.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/CodeActionParams.h"
+#include "OverridableMethod.h"
+
+
+
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_listOverridableMethods, lsCodeActionParams, OverridableMethodsResponse, "java/listOverridableMethods");
+
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/organizeImports.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/organizeImports.h
new file mode 100644
index 0000000000..817d52d32b
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/organizeImports.h
@@ -0,0 +1,12 @@
+#pragma once
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include <LibLsp/lsp/lsCodeAction.h>
+
+#include "LibLsp/lsp/CodeActionParams.h"
+
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_organizeImports, lsCodeActionParams, lsWorkspaceEdit, "java/organizeImports");
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/projectConfigurationUpdate.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/projectConfigurationUpdate.h
new file mode 100644
index 0000000000..342d167093
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/projectConfigurationUpdate.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+
+
+#include <string>
+#include <vector>
+#include "WorkspaceSymbolParams.h"
+
+#include "LibLsp/lsp/lsTextDocumentIdentifier.h"
+
+DEFINE_NOTIFICATION_TYPE(java_projectConfigurationUpdate, lsTextDocumentIdentifier, "java/projectConfigurationUpdate");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/resolveUnimplementedAccessors.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/resolveUnimplementedAccessors.h
new file mode 100644
index 0000000000..ba77041474
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/resolveUnimplementedAccessors.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include <string>
+#include "checkHashCodeEqualsStatus.h"
+
+
+struct AccessorField {
+ std::string fieldName;
+ bool isStatic =false;
+ bool generateGetter = false;
+ bool generateSetter = false;
+ void swap(AccessorField& arg) noexcept{
+ fieldName.swap(arg.fieldName);
+ std::swap(isStatic, arg.isStatic);
+ std::swap(generateGetter, arg.generateGetter);
+ std::swap(generateSetter, arg.generateSetter);
+ }
+};
+
+MAKE_REFLECT_STRUCT(AccessorField, fieldName,isStatic,generateGetter,generateSetter)
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_resolveUnimplementedAccessors, lsCodeActionParams, std::vector<AccessorField>, "java/resolveUnimplementedAccessors");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/searchSymbols.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/searchSymbols.h
new file mode 100644
index 0000000000..ac8a2419f6
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/jdtls/searchSymbols.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+
+#include <string>
+#include <vector>
+#include "WorkspaceSymbolParams.h"
+#include "LibLsp/lsp/method_type.h"
+#include "LibLsp/lsp/symbol.h"
+
+
+struct SearchSymbolParams :public WorkspaceSymbolParams
+{
+ boost::optional<std::string> projectName;
+ boost::optional< bool >sourceOnly;
+ boost::optional< int> maxResults;
+ MAKE_SWAP_METHOD(SearchSymbolParams, query, projectName, sourceOnly, maxResults);
+};
+MAKE_REFLECT_STRUCT(SearchSymbolParams, query, projectName, sourceOnly, maxResults);
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(java_searchSymbols, SearchSymbolParams, std::vector<lsSymbolInformation>, "java/searchSymbols");
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/SCTConfig.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/SCTConfig.h
new file mode 100644
index 0000000000..7b41118c0a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/SCTConfig.h
@@ -0,0 +1,37 @@
+#pragma once
+#include <string>
+#include <vector>
+#include <LibLsp/JsonRpc/serializer.h>
+using namespace std;
+
+
+struct TCP_option
+{
+ std::string host = "127.0.0.1";
+ int port = 8889;
+
+};
+MAKE_REFLECT_STRUCT(TCP_option,host,port)
+
+
+struct SCTConfig
+{
+ static SCTConfig* newInstance(const string& file_path,string& error);
+ std::string version;
+ std::string file_name;
+
+ boost::optional<bool> start_by_jcide;
+
+ boost::optional<TCP_option> tcp;
+ boost::optional<vector<string>> args;
+
+ // internal using
+ bool broken = false;
+ std::string error;
+};
+
+
+MAKE_REFLECT_STRUCT(SCTConfig, version,file_name, tcp, args, start_by_jcide);
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/protocol.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/protocol.h
new file mode 100644
index 0000000000..1f227a6110
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/protocol.h
@@ -0,0 +1,222 @@
+#pragma once
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/lsp/lsDocumentUri.h"
+#include "LibLsp/lsp/lsAny.h"
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+
+struct DownLoadCapFileParams
+{
+ lsDocumentUri uri;
+ MAKE_SWAP_METHOD(DownLoadCapFileParams, uri);
+};
+MAKE_REFLECT_STRUCT(DownLoadCapFileParams, uri);
+
+struct NormalActionResult
+{
+ bool state = false;
+ boost::optional<std::vector<uint8_t>> data;
+ boost::optional<std::string> info;
+ MAKE_SWAP_METHOD(NormalActionResult, state, data, info);
+};
+MAKE_REFLECT_STRUCT(NormalActionResult, data, state, info)
+
+DEFINE_REQUEST_RESPONSE_TYPE(sct_DownLoadCapFile, DownLoadCapFileParams, NormalActionResult, "sct/download_cap");
+
+
+
+
+enum class SctProtocol :uint8_t
+{
+ T01 = 0, T0 = 1, T1 = 2,
+};
+MAKE_REFLECT_TYPE_PROXY(SctProtocol);
+
+struct ConnectParams
+{
+
+ SctProtocol protocol= SctProtocol::T01;
+ boost::optional<std::string> reader;
+ boost::optional<lsp::Any> data;
+ MAKE_SWAP_METHOD(ConnectParams, reader, protocol,data);
+};
+MAKE_REFLECT_STRUCT(ConnectParams, reader, protocol, data);
+DEFINE_REQUEST_RESPONSE_TYPE(sct_Connect, ConnectParams, NormalActionResult, "sct/connect");
+
+
+
+struct SetProtocolParams
+{
+
+ SctProtocol protocol = SctProtocol::T01;
+
+};
+MAKE_REFLECT_STRUCT(SetProtocolParams, protocol);
+
+DEFINE_REQUEST_RESPONSE_TYPE(sct_SetProtocol, SetProtocolParams, NormalActionResult, "sct/set_protocol");
+
+struct GPAuthParams
+{
+ boost::optional < std::string> scp;
+ boost::optional < std::string > key;
+ boost::optional < lsp::Any > option;
+ MAKE_SWAP_METHOD(GPAuthParams, key, scp, option);
+};
+MAKE_REFLECT_STRUCT(GPAuthParams, key, scp, option);
+DEFINE_REQUEST_RESPONSE_TYPE(sct_gp_auth, GPAuthParams, NormalActionResult ,"sct/gp_auth");
+
+
+
+struct InstallAppletParams
+{
+ std::vector<uint8_t> package_aid;
+ std::vector<uint8_t> applet_aid;
+ boost::optional < std::vector<uint8_t>> instance_aid;
+ boost::optional<std::vector<uint8_t>> authority;
+ boost::optional<std::vector<uint8_t>> parameters;
+ MAKE_SWAP_METHOD(InstallAppletParams, package_aid, applet_aid, instance_aid, authority, parameters);
+};
+MAKE_REFLECT_STRUCT(InstallAppletParams, package_aid, applet_aid, instance_aid, authority, parameters);
+DEFINE_REQUEST_RESPONSE_TYPE(sct_InstalllApplet, InstallAppletParams, NormalActionResult, "sct/install_applet");
+
+
+struct TransmitParams
+{
+ std::vector<unsigned char> command;
+ MAKE_SWAP_METHOD(TransmitParams, command);
+};
+MAKE_REFLECT_STRUCT(TransmitParams, command);
+
+DEFINE_REQUEST_RESPONSE_TYPE(sct_Transmit, TransmitParams, NormalActionResult,"sct/transmit");
+
+DEFINE_NOTIFICATION_TYPE(sct_Disconnect,JsonNull, "sct/disconnect")
+
+
+struct SetWindowPosParams{
+ int X = 0;
+ int Y = 0;
+ int cx = 100;
+ int cy = 100;
+
+ MAKE_SWAP_METHOD(SetWindowPosParams, X, Y, cx, cy);
+};
+MAKE_REFLECT_STRUCT(SetWindowPosParams, X, Y, cx, cy);
+DEFINE_NOTIFICATION_TYPE(sct_SetWindowsPos, SetWindowPosParams, "sct/set_windows_pos")
+
+struct SetWindowVisibleParams
+{
+ static const int HIDE = 0;
+ static const int MINSIZE = 1;
+ static const int MAXSIZE = 2;
+ static const int NORMAL = 3;
+ int state = NORMAL;
+ MAKE_SWAP_METHOD(SetWindowVisibleParams, state);
+};
+MAKE_REFLECT_STRUCT(SetWindowVisibleParams, state);
+DEFINE_NOTIFICATION_TYPE(sct_SetWindowsVisible, SetWindowVisibleParams, "sct/set_windows_visible")
+
+
+
+enum CardInfoType:uint32_t
+{
+ ATR_TYPE = 0,
+ ATS_TYPE = 1,
+};
+MAKE_REFLECT_TYPE_PROXY(CardInfoType);
+
+
+struct GetCardInfoParams
+{
+ CardInfoType type_;
+};
+MAKE_REFLECT_STRUCT(GetCardInfoParams, type_);
+
+DEFINE_REQUEST_RESPONSE_TYPE(sct_GetCardInfo, GetCardInfoParams, NormalActionResult, "sct/get_card_info");
+
+
+struct JdwpInfo
+{
+ std::string host="127.0.0.1";
+ uint32_t jdwp_port = 9075;
+
+};
+
+MAKE_REFLECT_STRUCT(JdwpInfo, host, jdwp_port);
+
+struct LaunchResult
+{
+ bool state;
+ boost::optional<JdwpInfo> info;
+ boost::optional<std::string> error;
+ MAKE_SWAP_METHOD(LaunchResult, state, info, error);
+};
+MAKE_REFLECT_STRUCT(LaunchResult, state, info, error);
+
+
+struct JcvmOutputParams
+{
+ std::string data;
+ MAKE_SWAP_METHOD(JcvmOutputParams, data);
+};
+MAKE_REFLECT_STRUCT(JcvmOutputParams, data);
+
+DEFINE_NOTIFICATION_TYPE(sct_NotifyJcvmOutput, JcvmOutputParams,"sct/notify_jcvm_output");
+
+
+struct LaunchParam
+{
+ enum
+ {
+ LAUNCH_FOR_DEBUG = 0,
+ LAUNCH_FOR_RUN = 1
+ };
+ boost::optional<uint32_t> launch_for_what;
+
+};
+MAKE_REFLECT_STRUCT(LaunchParam, launch_for_what);
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(sct_Launch, LaunchParam, LaunchResult , "sct/launch");
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(sct_CheckBeforeLaunch, JsonNull, NormalActionResult, "sct/check_before_launch");
+
+
+
+DEFINE_NOTIFICATION_TYPE(sct_NotifyDisconnect, JsonNull,"sct/notify_disconnect");
+
+
+DEFINE_NOTIFICATION_TYPE(sct_TerminateLaunch, JsonNull, "sct/terminate_launch");
+
+
+
+
+struct sctInitializeParams {
+ // The process Id of the parent process that started
+ // the server. Is null if the process has not been started by another process.
+ // If the parent process is not alive then the server should exit (see exit
+ // notification) its process.
+ boost::optional<int> processId;
+
+ // User provided initialization options.
+ boost::optional<lsp::Any> initializationOptions;
+ boost::optional<int> version;
+
+};
+MAKE_REFLECT_STRUCT(sctInitializeParams,processId,initializationOptions, version);
+
+struct sctServerCapabilities {
+ bool gp_auth = false;
+ bool gp_key = false;
+ boost::optional<int> version;
+ MAKE_SWAP_METHOD(sctServerCapabilities, gp_auth, gp_key, version);
+};
+MAKE_REFLECT_STRUCT(sctServerCapabilities, gp_auth, gp_key, version);
+
+
+struct stcInitializeResult
+{
+ sctServerCapabilities capabilities;
+};
+MAKE_REFLECT_STRUCT(stcInitializeResult, capabilities);
+
+DEFINE_REQUEST_RESPONSE_TYPE(sct_initialize, sctInitializeParams, stcInitializeResult, "sct/initialize");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/sct.cpp b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/sct.cpp
new file mode 100644
index 0000000000..25c21ecddc
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/sct.cpp
@@ -0,0 +1,743 @@
+
+#include <deque>
+#include "sct.h"
+#include "SCTConfig.h"
+#include <rapidjson/document.h>
+#include <rapidjson/istreamwrapper.h>
+#include <fstream>
+#include <boost/filesystem.hpp>
+#include "LibLsp/lsp/general/exit.h"
+#include "LibLsp/lsp/general/initialized.h"
+#include "LibLsp/lsp/windows/MessageNotify.h"
+#include "LibLsp/lsp/language/language.h"
+#include "LibLsp/JsonRpc/Condition.h"
+#include "LibLsp/lsp/workspace/execute_command.h"
+#include "LibLsp/JsonRpc/json.h"
+
+namespace lsp {
+ class Log;
+}
+
+using namespace std;
+using lsp::Log;
+
+
+//
+//MethodType sct_DownLoadCapFile::request::kMethodInfo = "sct/download_cap";
+//
+//MethodType sct_Transmit::request::kMethodInfo = "sct/transmit";
+//
+//MethodType sct_Connect::request::kMethodInfo = "sct/connect";
+//
+//MethodType sct_Disconnect::request::kMethodInfo = "sct/disconnect";
+//
+//MethodType sct_InstalllApplet::request::kMethodInfo = "sct/install_applet";
+//
+//MethodType sct_gp_auth::request::kMethodInfo = "sct/gp_auth";
+//
+//MethodType sct_SetWindowsPos::request::kMethodInfo = "sct/set_windows_pos";
+//
+//MethodType sct_SetWindowsVisible::request::kMethodInfo = "sct/set_windows_visible";
+//
+//
+//MethodType sct_NotifyJcvmOutput::request::kMethodInfo = "sct/notify_jcvm_output";
+//
+//MethodType sct_Launch::request::kMethodInfo = "sct/launch";
+//
+//MethodType sct_SetProtocol::request::kMethodInfo = "sct/set_protocol";
+//
+//MethodType sct_CheckBeforeLaunch::request::kMethodInfo = "sct/check_before_launch";
+//
+//MethodType sct_GetCardInfo::request::kMethodInfo = "sct/get_card_info";
+//
+//MethodType sct_NotifyDisconnect::request::kMethodInfo = "sct/notify_disconnect";
+//MethodType sct_TerminateLaunch::request::kMethodInfo = "sct/terminate_launch";
+//MethodType sct_initialize::request::kMethodInfo = "sct/initialize";
+
+
+ SCTConfig* SCTConfig::newInstance(const string& file_path, string& error)
+{
+ if(!boost::filesystem::exists(file_path))
+ {
+ error = "file no exists.";
+ return nullptr;
+ }
+ using namespace rapidjson;
+ using namespace std;
+ std::unique_ptr<SCTConfig> sct = std::make_unique<SCTConfig>();
+ try
+ {
+ std::wifstream ifs(file_path);
+ WIStreamWrapper isw(ifs);
+
+ Document d;
+ d.ParseStream(isw);
+ if(!d.HasParseError())
+ {
+ JsonReader reader{ &d };
+ Reflect(reader, *sct.get());
+ }
+ }
+ catch (std::exception& e)
+ {
+ string temp = "Reflect failed. exception info:";
+
+ temp += e.what();
+ error = temp;
+ sct.get()->broken = true;
+ sct.get()->error = temp;
+ }
+ return sct.release();
+}
+
+
+SmartCardTool::SmartCardTool(): m_jdwpPort(0), m_curProtocol(SctProtocol::T01), log(nullptr)
+{
+ m_ipAddr = "127.0.0.1";
+}
+
+void AddNotifyJsonRpcMethod(sct::ProtocolJsonHandler& handler)
+{
+ handler.method2notification[Notify_Exit::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_Exit::notify::ReflectReader(visitor);
+ };
+ handler.method2notification[Notify_InitializedNotification::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_InitializedNotification::notify::ReflectReader(visitor);
+ };
+
+
+ handler.method2notification[Notify_LogMessage::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_LogMessage::notify::ReflectReader(visitor);
+ };
+ handler.method2notification[Notify_ShowMessage::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_ShowMessage::notify::ReflectReader(visitor);
+ };
+
+ handler.method2notification[Notify_sendNotification::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return Notify_sendNotification::notify::ReflectReader(visitor);
+ };
+
+ handler.method2notification[lang_actionableNotification::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return lang_actionableNotification::notify::ReflectReader(visitor);
+ };
+ handler.method2notification[lang_progressReport::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return lang_progressReport::notify::ReflectReader(visitor);
+ };
+
+
+ handler.method2notification[sct_NotifyJcvmOutput::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return sct_NotifyJcvmOutput::notify::ReflectReader(visitor);
+ };
+ handler.method2notification[sct_NotifyDisconnect::notify::kMethodInfo] = [](Reader& visitor)
+ {
+ return sct_NotifyDisconnect::notify::ReflectReader(visitor);
+ };
+
+}
+
+sct::ProtocolJsonHandler::ProtocolJsonHandler()
+{
+ AddNotifyJsonRpcMethod(*this);
+
+ method2response[sct_DownLoadCapFile::request::kMethodInfo ] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return sct_DownLoadCapFile::response::ReflectReader(visitor);
+ };
+ method2response[sct_Connect::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return sct_Connect::response::ReflectReader(visitor);
+ };
+ method2response[sct_SetProtocol::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return sct_SetProtocol::response::ReflectReader(visitor);
+ };
+ method2response[sct_gp_auth::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return sct_gp_auth::response::ReflectReader(visitor);
+ };
+ method2response[sct_InstalllApplet::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return sct_InstalllApplet::response::ReflectReader(visitor);
+ };
+ method2response[sct_Transmit::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return sct_Transmit::response::ReflectReader(visitor);
+ };
+
+ method2response[sct_GetCardInfo::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return sct_GetCardInfo::response::ReflectReader(visitor);
+ };
+
+ method2response[sct_Launch::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return sct_Launch::response::ReflectReader(visitor);
+ };
+ method2response[sct_CheckBeforeLaunch::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return sct_CheckBeforeLaunch::response::ReflectReader(visitor);
+ };
+
+
+ method2response[sct_initialize::request::kMethodInfo] = [](Reader& visitor)
+ {
+ if (visitor.HasMember("error"))
+ return Rsp_Error::ReflectReader(visitor);
+
+ return sct_initialize::response::ReflectReader(visitor);
+ };
+
+}
+bool SmartCardTool::check_sct_alive()
+{
+ if (sct)
+ {
+ return true;
+ }
+ if(log)
+ {
+ wstring strPrompt = L"sct is not alvie.";
+ log->log(Log::Level::SEVERE, strPrompt);
+ }
+ return false;
+}
+
+bool SmartCardTool::initialize(int processId, int version)
+{
+
+ if(!check_sct_alive())
+ {
+ return false;
+ }
+ sct_initialize::request request;
+ request.params.processId = processId;
+ request.params.version = version;
+
+ auto msg = sct->waitResponse(request, 100000);
+
+ if (!msg)
+ {
+ return false;
+ }
+
+ if (msg->is_error)
+ {
+ auto error = &msg->error;
+ log->error( error->error.ToString());
+ return false;
+ }
+ auto result = &msg->response;
+ _lsServerCapabilities.swap(result->result.capabilities);
+ return true;
+}
+
+
+
+SmartCardTool::~SmartCardTool()
+{
+
+
+}
+
+bool SmartCardTool::GetCardInfo(CardInfoType type_, std::vector<unsigned char>& out)
+{
+ if (!check_sct_alive())
+ {
+ return false;
+ }
+ sct_GetCardInfo::request request;
+ request.params.type_ = type_;
+
+ auto data = sct->waitResponse(request, 40000);
+
+ if (!data)
+ {
+ if (log)
+ {
+ wstring strPrompt = L"GetCardInfo request timeout.";
+ log->log(Log::Level::SEVERE, strPrompt);
+ }
+ return false;
+ }
+
+ if (data->is_error)
+ {
+ if (log)
+ {
+ string strPrompt = "GetCardInfo request error." + data->error.ToJson();
+ log->log(Log::Level::SEVERE, strPrompt);
+ }
+ return false;
+ }
+ auto rsp = &data->response;
+ if (rsp->result.state)
+ {
+ out.swap(rsp->result.data.value());
+ return true;
+ }
+
+ if (log)
+ {
+ string strPrompt = "GetCardInfo failed. Reason:";
+ strPrompt += rsp->result.info.value();
+ log->log(Log::Level::SEVERE, strPrompt);
+ }
+ return false;
+}
+
+
+
+bool SmartCardTool::Launch(bool for_debug)
+{
+ if (!check_sct_alive())
+ {
+ return false;
+ }
+ sct_Launch::request request;
+ if(for_debug)
+ {
+ request.params.launch_for_what = LaunchParam::LAUNCH_FOR_DEBUG;
+ }
+ else
+ {
+ request.params.launch_for_what = LaunchParam::LAUNCH_FOR_RUN;
+ }
+ auto data = sct->waitResponse(request, 100000);
+
+ if (!data)
+ {
+ if (log)
+ {
+ wstring strPrompt = L"Launch request timeout.";
+ log->log(Log::Level::SEVERE, strPrompt);
+ }
+ return false;
+ }
+
+ if (data->is_error)
+ {
+ if (log)
+ {
+ string strPrompt = "Launch request error." + data->error.ToJson();
+
+ log->log(Log::Level::SEVERE, strPrompt);
+ }
+ return false;
+ }
+ auto rsp = &data->response;
+ if (rsp->result.state)
+ {
+ if (log)
+ {
+ log->log(Log::Level::INFO, L"Launch successfully");
+ }
+ if(rsp->result.info)
+ {
+ m_ipAddr.swap(rsp->result.info.value().host);
+ m_jdwpPort = rsp->result.info.value().jdwp_port;
+
+ }
+ }
+ else
+ {
+ if (log)
+ {
+ string strPrompt = "Launch failed. Reason:";
+ strPrompt += rsp->result.error.value();
+ log->log(Log::Level::SEVERE, strPrompt);
+ }
+ return false;
+ }
+ return true;
+}
+
+void SmartCardTool::TerminateLaunch()
+{
+ if (!check_sct_alive())
+ {
+ return ;
+ }
+ sct_TerminateLaunch::notify notify;
+ sct->send(notify);
+ connect_state = false;
+ return ;
+}
+
+void SmartCardTool::show_message(lsMessageType type_,
+ const std::string& msg)
+{
+ if (!check_sct_alive())
+ {
+ return ;
+ }
+ Notify_ShowMessage::notify notify;
+ notify.params.type = type_;
+ notify.params.message = msg;
+ sct->send(notify);
+}
+
+bool SmartCardTool::CheckBeforeLaunch()
+{
+ if (!check_sct_alive())
+ {
+ return false;
+ }
+ sct_CheckBeforeLaunch::request request;
+ auto data = sct->waitResponse(request, 50000);
+
+ if (!data)
+ {
+ wstring strPrompt = L"CheckBeforeLaunch request timeout.";
+ if(log)
+ {
+ log->log(Log::Level::SEVERE, strPrompt);
+ }
+
+ return false;
+ }
+
+ if (data->is_error)
+ {
+ string strPrompt = "CheckBeforeLaunch request error." + data->error.ToJson();
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+ auto rsp = &data->response;
+ if (rsp->result.state)
+ {
+ return true;
+ }
+
+
+ string strPrompt = "Check Before Launch JCVM failed. Reason:";
+ strPrompt += rsp->result.info.value();
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+
+}
+
+
+bool SmartCardTool::Connect(SctProtocol protocol)
+{
+ if (!check_sct_alive())
+ {
+ return false;
+ }
+ sct_Connect::request request;
+
+ request.params.protocol = protocol;
+
+ auto data = sct->waitResponse(request, 40000);
+
+ if (!data)
+ {
+ wstring strPrompt = L"Connect request timeout.";
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+
+ if (data->is_error)
+ {
+ string strPrompt = "Connect request error." + data->error.ToJson();
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+ auto rsp =&data->response;
+ if (rsp->result.state)
+ {
+ connect_state = true;
+ return true;
+ }
+ else
+ {
+ string strPrompt = "Connect failed. Reason:";
+ strPrompt += rsp->result.info.value();
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+
+}
+
+
+
+
+void SmartCardTool::DisConnect()
+{
+ if (!check_sct_alive())
+ {
+ return ;
+ }
+ sct_Disconnect::notify notify;
+ sct->send(notify);
+ connect_state = false;
+ return ;
+}
+
+bool SmartCardTool::DownLoadCapFile(const string& strCapFileName)
+{
+ if (!check_sct_alive())
+ {
+ return false;
+ }
+ sct_DownLoadCapFile::request request;
+ request.params.uri.raw_uri_ = make_file_scheme_uri(strCapFileName);
+
+ auto data = sct->waitResponse(request, 40000);
+
+ if(!data)
+ {
+ wstring strPrompt = L"DownLoadCapFile request timeout.";
+ log->log(Log::Level::SEVERE,strPrompt);
+ return false;
+ }
+
+ if(data->is_error)
+ {
+ string strPrompt = "DownLoadCapFile request error." + data->error.ToJson();
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+ auto rsp = &data->response;
+ if(rsp->result.state)
+ {
+ string strPrompt = "DownLoadCapFile successfully";
+ if(rsp->result.info)
+ {
+ strPrompt = rsp->result.info.value();
+ }
+ log->log(Log::Level::INFO, strPrompt);
+ return true;
+ }
+ else
+ {
+ string strPrompt = "DownLoadCapFile failed. Reason:";
+ strPrompt += rsp->result.info.value();
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+
+}
+
+void SmartCardTool::SetWindowsVisible(SetWindowVisibleParams& params)
+{
+ if (!check_sct_alive())
+ {
+ return ;
+ }
+ sct_SetWindowsVisible::notify notify;
+ notify.params.swap(params);
+ sct->send(notify);
+
+}
+
+void SmartCardTool::SetWindowPos(SetWindowPosParams& params)
+{
+ sct_SetWindowsPos::notify notify;
+ notify.params.swap(params);
+ sct->send(notify);
+}
+
+bool SmartCardTool::SetProtocol(SctProtocol protocol)
+{
+ if (!check_sct_alive())
+ {
+ return false;
+ }
+ sct_SetProtocol::request request;
+
+ request.params.protocol = protocol;
+
+ auto data = sct->waitResponse(request, 40000);
+
+ if (!data)
+ {
+ wstring strPrompt = L"SetProtocol request timeout.";
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+
+ if (data->is_error)
+ {
+ string strPrompt = "SetProtocol request error." + data->error.ToJson();
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+ auto rsp = &data->response;
+ if (rsp->result.state)
+ {
+ m_curProtocol = protocol;
+ return true;
+ }
+ else
+ {
+ string strPrompt = "SetProtocol failed. Reason:";
+ strPrompt += rsp->result.info.value();
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+
+}
+
+bool SmartCardTool::GpAuth()
+{
+
+ if (!check_sct_alive())
+ {
+ return false;
+ }
+ sct_gp_auth::request request;
+
+ auto data = sct->waitResponse(request, 100000);
+
+ if (!data)
+ {
+ wstring strPrompt = L"gp_auth request timeout.";
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+
+ if (data->is_error)
+ {
+ string strPrompt = "gp_auth request error." + data->error.ToJson();
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+ auto rsp = &data->response;
+ if (rsp->result.state)
+ {
+ string strPrompt = "gp_auth request successfully.";
+ if (rsp->result.info)
+ strPrompt = rsp->result.info.value();
+
+ log->log(Log::Level::INFO, strPrompt);
+ return true;
+ }
+ else
+ {
+ string strPrompt = "gp_auth failed. Reason:";
+ strPrompt += rsp->result.info.value();
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+
+}
+
+bool SmartCardTool::InstallApplet(InstallAppletParams& params)
+{
+ if (!check_sct_alive())
+ {
+ return false;
+ }
+ sct_InstalllApplet::request request;
+ request.params.swap(params);
+ auto data = sct->waitResponse(request);
+
+ if (!data)
+ {
+ wstring strPrompt = L"Install Applet request timeout.";
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+
+ if (data->is_error)
+ {
+ string strPrompt = "Install Applet request error." + data->error.ToJson();
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+ auto rsp = &data->response;
+ if (rsp->result.state)
+ {
+ string strPrompt = "Install Applet successfully.";
+ if (rsp->result.info)
+ strPrompt = rsp->result.info.value();
+ log->log(Log::Level::INFO, strPrompt);
+ return true;
+ }
+ else
+ {
+ string strPrompt = "Install Applet failed. Reason:";
+ strPrompt += rsp->result.info.value();
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+}
+
+
+bool SmartCardTool::Transmit(const std::vector<unsigned char>& cmdApdu, std::vector<unsigned char>& rspApdu)
+{
+
+ if (!check_sct_alive())
+ {
+ return false;
+ }
+ sct_Transmit::request request;
+ request.params.command = cmdApdu;
+
+ auto data = sct->waitResponse(request);
+
+ if (!data)
+ {
+ wstring strPrompt = L"Transmit request timeout.";
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+
+ if (data->is_error)
+ {
+ string strPrompt = "Transmit request error." + data->error.ToJson();
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+ auto rsp = &data->response;
+ if (rsp->result.state)
+ {
+ rspApdu.swap(rsp->result.data.value());
+ //log->log(Log::Level::INFO, L"Transmit successfully");
+ return true;
+ }
+ else
+ {
+ string strPrompt = "Transmit failed. Reason:";
+ strPrompt += rsp->result.info.value();
+ log->log(Log::Level::SEVERE, strPrompt);
+ return false;
+ }
+
+
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/sct.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/sct.h
new file mode 100644
index 0000000000..59ffe02fd7
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sct/sct.h
@@ -0,0 +1,103 @@
+#pragma once
+
+#include <LibLsp/JsonRpc/RemoteEndPoint.h>
+#include <LibLsp/JsonRpc/Endpoint.h>
+#include <LibLsp/lsp/ProtocolJsonHandler.h>
+#include "protocol.h"
+enum class lsMessageType;
+enum CardInfoType : unsigned;
+enum class SctProtocol : unsigned char;
+struct InstallAppletParams;
+
+
+using namespace std;
+
+class ModeState;
+namespace sct
+{
+ class ProtocolJsonHandler : public MessageJsonHandler
+ {
+ public:
+ ProtocolJsonHandler();
+ };
+
+}
+class SmartCardTool
+{
+ //IP �����ֽ���
+ std::string m_ipAddr;
+ volatile uint16_t m_jdwpPort;
+
+
+ SctProtocol m_curProtocol;
+public:
+ enum JCIDE_VERSION
+ {
+ V5_KIND = 5
+ };
+ SmartCardTool();
+ ~SmartCardTool();
+
+
+ bool GetCardInfo(CardInfoType type_,std::vector<unsigned char>&);
+ bool Launch(bool for_debug = false);
+
+ void TerminateLaunch();
+ void show_message(lsMessageType type_,const std::string& msg);
+ bool CheckBeforeLaunch();
+
+ string GetIpAddr(){return m_ipAddr;}
+
+ uint16_t GetJdwpPort(){return m_jdwpPort;}
+
+
+
+ void SetWindowsVisible(SetWindowVisibleParams&);
+ void SetWindowPos(SetWindowPosParams&);
+
+ SctProtocol GetProtocol(){return m_curProtocol;}
+
+
+ bool SetProtocol(SctProtocol protocol = SctProtocol::T01);
+
+ bool GpAuth();
+
+
+ bool InstallApplet(InstallAppletParams&);;
+
+ bool DownLoadCapFile(const string& strCapFileName);
+
+
+
+ bool IsConnected() const {
+
+ return connect_state;
+ }
+
+ string GetErrorString() { return {}; };
+
+ bool Connect(SctProtocol protocol = SctProtocol::T01);
+
+ void DisConnect();
+
+
+
+
+ bool Transmit(const std::vector<unsigned char>& cmdApdu, std::vector<unsigned char>& rspApdu) ;
+
+
+ lsp::Log* log;
+ volatile bool connect_state = false;
+
+ std::shared_ptr<RemoteEndPoint> sct;
+
+
+ bool initialize(int processId,int version);
+ const sctServerCapabilities& getServerCapabilities()const
+ {
+ return _lsServerCapabilities;
+ }
+private:
+ sctServerCapabilities _lsServerCapabilities;
+ bool check_sct_alive();
+};
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sonarlint/protocol.h b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sonarlint/protocol.h
new file mode 100644
index 0000000000..d81c3eaa63
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/extention/sonarlint/protocol.h
@@ -0,0 +1,176 @@
+#pragma once
+#include <string>
+#include <boost/optional.hpp>
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/lsp/lsDocumentUri.h"
+#include "LibLsp/lsp/lsAny.h"
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+#include "LibLsp/lsp/general/InitializeParams.h"
+
+struct LintRule
+{
+ std::string key;
+ std::string name;
+
+
+ std::string Display() const
+ {
+ return name + " (" + key + ")";
+ }
+ bool activeByDefault = true;
+ boost::optional<std::string> severity;
+ boost::optional<std::string> type;
+ int icon_index = -1;
+ MAKE_SWAP_METHOD(LintRule, key, name, activeByDefault, severity, type);
+
+};
+MAKE_REFLECT_STRUCT(LintRule, key, name, activeByDefault, severity, type);
+
+
+struct RuleParameter {
+ std::string name;
+ boost::optional<std::string> description;
+ boost::optional<std::string> defaultValue;
+
+};
+MAKE_REFLECT_STRUCT(RuleParameter, name, description, defaultValue);
+
+struct ShowRuleDescriptionParams {
+
+ boost::optional<std::string> key;
+
+ boost::optional<std::string> name;
+
+ boost::optional<std::string> htmlDescription;
+
+ boost::optional<std::string> type;
+
+ boost::optional<std::string> severity;
+
+ boost::optional< std::vector<RuleParameter> > parameters;
+ MAKE_SWAP_METHOD(ShowRuleDescriptionParams, key, name, htmlDescription, type, severity, parameters)
+
+
+};
+MAKE_REFLECT_STRUCT(ShowRuleDescriptionParams, key, name, htmlDescription, type, severity, parameters);
+
+
+struct GetJavaConfigResponse {
+ std::string projectRoot;
+ std::string sourceLevel;
+ std::vector<std::string> classpath;
+ bool isTest;
+ std::string vmLocation;
+ MAKE_SWAP_METHOD(GetJavaConfigResponse, projectRoot, sourceLevel, classpath, isTest, vmLocation);
+};
+MAKE_REFLECT_STRUCT(GetJavaConfigResponse, projectRoot, sourceLevel, classpath, isTest, vmLocation);
+
+struct SetTraceNotificationParams {
+ lsInitializeParams::lsTrace value;
+};
+MAKE_REFLECT_STRUCT(SetTraceNotificationParams, value);
+
+
+struct ServerConnectionSettings {
+
+ std::string SONARCLOUD_URL = "https://sonarcloud.io";
+ std::vector<std::string>SONARCLOUD_ALIAS = { "https://sonarqube.com",
+ "https://www.sonarqube.com",
+ "https://www.sonarcloud.io",
+ "https://sonarcloud.io" };
+
+ std::string connectionId;
+ std::string serverUrl;
+ std::string token;
+ boost::optional<std::string> organizationKey;
+ MAKE_SWAP_METHOD(ServerConnectionSettings, connectionId, serverUrl, token, organizationKey)
+
+};
+MAKE_REFLECT_STRUCT(ServerConnectionSettings, connectionId, serverUrl, token, organizationKey)
+
+struct RuleSetting
+{
+ bool IsOn();
+ std::string level = "on";
+ RuleSetting(bool activate);
+ RuleSetting() = default;
+ void toggle();
+ void on()
+ {
+ level = "on";
+ }
+ void off()
+ {
+ level = "off";
+ }
+ void turn(bool activate)
+ {
+ if (activate)
+ {
+ on();
+ }
+ else
+ {
+ off();
+ }
+ }
+ boost::optional< std::map<std::string, std::string > > parameters;
+};
+MAKE_REFLECT_STRUCT(RuleSetting, level, parameters)
+
+struct ConsoleParams
+{
+ boost::optional < bool >showAnalyzerLogs;
+ boost::optional < bool >showVerboseLogs;
+ MAKE_SWAP_METHOD(ConsoleParams, showAnalyzerLogs, showVerboseLogs)
+};
+MAKE_REFLECT_STRUCT(ConsoleParams, showAnalyzerLogs, showVerboseLogs)
+
+struct SonarLintWorkspaceSettings
+{
+ boost::optional < bool > disableTelemetry;
+ boost::optional < std::map<std::string, ServerConnectionSettings> >connectedMode;
+ boost::optional<std::map<std::string, RuleSetting>> rules;
+ boost::optional<ConsoleParams> output;
+
+ boost::optional<std::string > pathToNodeExecutable;
+
+ boost::optional< std::map<std::string, std::string > > getConfigurationParameters(const std::string& ruleKey);
+
+
+};
+
+MAKE_REFLECT_STRUCT(SonarLintWorkspaceSettings, disableTelemetry, connectedMode,
+ rules, output, pathToNodeExecutable)
+
+
+
+ DEFINE_REQUEST_RESPONSE_TYPE(slls_listAllRules, JsonNull, lsp::Any, "sonarlint/listAllRules");
+
+
+
+DEFINE_NOTIFICATION_TYPE(Notify_didClasspathUpdate, lsDocumentUri, "sonarlint/didClasspathUpdate")
+
+
+DEFINE_NOTIFICATION_TYPE(Notify_didJavaServerModeChange, std::string, "sonarlint/didJavaServerModeChange")
+
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(slls_showSonarLintOutput, JsonNull, JsonNull, "sonarlint/showSonarLintOutput");
+
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(slls_openJavaHomeSettings, JsonNull, JsonNull, "sonarlint/openJavaHomeSettings");
+
+
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(slls_openPathToNodeSettings, JsonNull, JsonNull, "sonarlint/openPathToNodeSettings");
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(slls_showRuleDescription, ShowRuleDescriptionParams, JsonNull, "sonarlint/showRuleDescription");
+
+DEFINE_REQUEST_RESPONSE_TYPE(slls_getJavaConfig, lsDocumentUri, GetJavaConfigResponse, "sonarlint/getJavaConfig");
+
+
+DEFINE_NOTIFICATION_TYPE(slls_setTraceNotification, SetTraceNotificationParams, "$/setTraceNotification") \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/general/InitializeParams.h b/graphics/asymptote/LspCpp/LibLsp/lsp/general/InitializeParams.h
new file mode 100644
index 0000000000..f10080ea21
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/general/InitializeParams.h
@@ -0,0 +1,128 @@
+#pragma once
+
+#include "LibLsp/lsp/lsDocumentUri.h"
+#include "LibLsp/lsp/lsAny.h"
+#include "lsClientCapabilities.h"
+#include "LibLsp/lsp/workspace/workspaceFolders.h"
+
+struct ClientInfo {
+ std::string name;
+ boost::optional<std::string> version;
+
+ MAKE_SWAP_METHOD(ClientInfo,name,version);
+};
+MAKE_REFLECT_STRUCT(ClientInfo,name,version);
+
+struct lsInitializeParams {
+ // The process Id of the parent process that started
+ // the server. Is null if the process has not been started by another process.
+ // If the parent process is not alive then the server should exit (see exit
+ // notification) its process.
+ boost::optional<int> processId;
+
+ /**
+ * Information about the client
+ *
+ * @since 3.15.0
+ */
+ boost::optional<ClientInfo> clientInfo;
+ /**
+ * The locale the client is currently showing the user interface
+ * in. This must not necessarily be the locale of the operating
+ * system.
+ *
+ * Uses IETF language tags as the value's syntax
+ * (See https://en.wikipedia.org/wiki/IETF_language_tag)
+ *
+ * @since 3.16.0
+ */
+ boost::optional<std::string> locale;
+
+ // The rootPath of the workspace. Is null
+ // if no folder is open.
+ //
+ // @deprecated in favour of rootUri.
+ boost::optional<std::string> rootPath;
+
+ // The rootUri of the workspace. Is null if no
+ // folder is open. If both `rootPath` and `rootUri` are set
+ // `rootUri` wins.
+ boost::optional<lsDocumentUri> rootUri;
+
+ // User provided initialization options.
+ boost::optional<lsp::Any> initializationOptions;
+
+ // The capabilities provided by the client (editor or tool)
+ lsClientCapabilities capabilities;
+
+
+ /**
+ * An boost::optional extension to the protocol.
+ * To tell the server what client (editor) is talking to it.
+ */
+ // @Deprecated
+ boost::optional< std::string >clientName;
+
+
+
+ enum class lsTrace {
+ // NOTE: serialized as a string, one of 'off' | 'messages' | 'verbose';
+ Off, // off
+ Messages, // messages
+ Verbose // verbose
+
+ };
+
+ // The initial trace setting. If omitted trace is disabled ('off').
+ lsTrace trace = lsTrace::Off;
+
+
+ /**
+ * The workspace folders configured in the client when the server starts.
+ * This property is only available if the client supports workspace folders.
+ * It can be `null` if the client supports workspace folders but none are
+ * configured.
+ *
+ * Since 3.6.0
+ */
+ boost::optional< std::vector<WorkspaceFolder> > workspaceFolders;
+
+ MAKE_SWAP_METHOD(lsInitializeParams,
+ processId,
+ rootPath,
+ rootUri,
+ initializationOptions,
+ capabilities, clientName, clientInfo,
+ trace, workspaceFolders, locale)
+};
+
+void Reflect(Reader& reader, lsInitializeParams::lsTrace& value);
+
+
+void Reflect(Writer& writer, lsInitializeParams::lsTrace& value);
+
+
+MAKE_REFLECT_STRUCT(lsInitializeParams,
+ processId,
+ rootPath,
+ rootUri,
+ initializationOptions,
+ capabilities, clientName, clientInfo,
+ trace, workspaceFolders, locale)
+
+struct lsInitializeError {
+ // Indicates whether the client should retry to send the
+ // initilize request after showing the message provided
+ // in the ResponseError.
+ bool retry;
+ void swap(lsInitializeError& arg) noexcept
+ {
+ auto tem = retry;
+ retry = arg.retry;
+ arg.retry = tem;
+ }
+};
+MAKE_REFLECT_STRUCT(lsInitializeError, retry);
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/general/exit.h b/graphics/asymptote/LspCpp/LibLsp/lsp/general/exit.h
new file mode 100644
index 0000000000..02fe216017
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/general/exit.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+/**
+ * A notification to ask the server to exit its process.
+ */
+DEFINE_NOTIFICATION_TYPE(Notify_Exit, boost::optional<JsonNull>, "exit");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/general/initialize.cpp b/graphics/asymptote/LspCpp/LibLsp/lsp/general/initialize.cpp
new file mode 100644
index 0000000000..4886be9b46
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/general/initialize.cpp
@@ -0,0 +1,45 @@
+#include "initialize.h"
+#include "LibLsp/JsonRpc/json.h"
+
+void Reflect(Reader& reader, lsInitializeParams::lsTrace& value)
+{
+ if (!reader.IsString())
+ {
+ value = lsInitializeParams::lsTrace::Off;
+ return;
+ }
+ std::string v = reader.GetString();
+ if (v == "off")
+ value = lsInitializeParams::lsTrace::Off;
+ else if (v == "messages")
+ value = lsInitializeParams::lsTrace::Messages;
+ else if (v == "verbose")
+ value = lsInitializeParams::lsTrace::Verbose;
+}
+
+void Reflect(Writer& writer, lsInitializeParams::lsTrace& value)
+{
+ switch (value)
+ {
+ case lsInitializeParams::lsTrace::Off:
+ writer.String("off");
+ break;
+ case lsInitializeParams::lsTrace::Messages:
+ writer.String("messages");
+ break;
+ case lsInitializeParams::lsTrace::Verbose:
+ writer.String("verbose");
+ break;
+ }
+}
+ void Reflect(Reader& visitor, std::pair<boost::optional<lsTextDocumentSyncKind>, boost::optional<lsTextDocumentSyncOptions> >& value)
+{
+ if(((JsonReader&)visitor).m_->IsObject())
+ {
+ Reflect(visitor, value.second);
+ }
+ else
+ {
+ Reflect(visitor, value.first);
+ }
+} \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/general/initialize.h b/graphics/asymptote/LspCpp/LibLsp/lsp/general/initialize.h
new file mode 100644
index 0000000000..eb8810939a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/general/initialize.h
@@ -0,0 +1,39 @@
+#pragma once
+#include "LibLsp/JsonRpc/message.h"
+#include "InitializeParams.h"
+#include "lsServerCapabilities.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+
+
+
+
+
+
+/**
+ * The capabilities the language server provides.
+ */
+ struct InitializeResult {
+ lsServerCapabilities capabilities;
+ MAKE_SWAP_METHOD(InitializeResult, capabilities);
+ };
+
+MAKE_REFLECT_STRUCT(InitializeResult, capabilities);
+
+
+/**
+ * The initialize request is sent as the first request from the client to
+ * the server.
+ *
+ * If the server receives request or notification before the initialize request it should act as follows:
+ * - for a request the respond should be errored with code: -32001. The message can be picked by the server.
+ * - notifications should be dropped, except for the exit notification. This will allow the exit a server without an initialize request.
+ *
+ * Until the server has responded to the initialize request with an InitializeResult
+ * the client must not sent any additional requests or notifications to the server.
+ *
+ * During the initialize request the server is allowed to sent the notifications window/showMessage,
+ * window/logMessage and telemetry/event as well as the window/showMessageRequest request to the client.
+ */
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_initialize, lsInitializeParams, InitializeResult, "initialize");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/general/initialized.h b/graphics/asymptote/LspCpp/LibLsp/lsp/general/initialized.h
new file mode 100644
index 0000000000..bb6d12511c
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/general/initialized.h
@@ -0,0 +1,13 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+/**
+ * The initialized notification is sent from the client to the server after
+ * the client received the result of the initialize request but before the
+ * client is sending any other request or notification to the server. The
+ * server can use the initialized notification for example to dynamically
+ * register capabilities.
+ */
+DEFINE_NOTIFICATION_TYPE(Notify_InitializedNotification, JsonNull, "initialized");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/general/lsClientCapabilities.h b/graphics/asymptote/LspCpp/LibLsp/lsp/general/lsClientCapabilities.h
new file mode 100644
index 0000000000..fcf6634e13
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/general/lsClientCapabilities.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include "LibLsp/lsp/lsAny.h"
+#include "lsWorkspaceClientCapabilites.h"
+#include "lsTextDocumentClientCapabilities.h"
+
+/**
+ * Client capabilities specific to the used markdown parser.
+ *
+ * @since 3.16.0
+ */
+struct MarkdownClientCapabilities {
+ /**
+ * The name of the parser.
+ */
+ std::string parser;
+
+ /**
+ * The version of the parser.
+ */
+ boost::optional<std::string> version;
+ MAKE_SWAP_METHOD(MarkdownClientCapabilities, parser, version)
+
+};
+MAKE_REFLECT_STRUCT(MarkdownClientCapabilities, parser, version)
+
+struct lsClientCapabilities {
+ // Workspace specific client capabilities.
+ boost::optional<lsWorkspaceClientCapabilites> workspace;
+
+ // Text document specific client capabilities.
+ boost::optional<lsTextDocumentClientCapabilities> textDocument;
+
+ /**
+ * Window specific client capabilities.
+ */
+ boost::optional<lsp::Any> window;
+ /**
+ * Experimental client capabilities.
+ */
+ boost::optional<lsp::Any> experimental;
+
+ MAKE_SWAP_METHOD(lsClientCapabilities, workspace, textDocument, window, experimental)
+};
+MAKE_REFLECT_STRUCT(lsClientCapabilities, workspace, textDocument, window, experimental)
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/general/lsServerCapabilities.h b/graphics/asymptote/LspCpp/LibLsp/lsp/general/lsServerCapabilities.h
new file mode 100644
index 0000000000..66af2ced6b
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/general/lsServerCapabilities.h
@@ -0,0 +1,589 @@
+#pragma once
+#include "LibLsp/lsp/method_type.h"
+
+
+#include <stdexcept>
+#include "LibLsp/JsonRpc/message.h"
+#include "LibLsp/lsp/lsDocumentUri.h"
+#include "LibLsp/lsp/lsAny.h"
+#include "InitializeParams.h"
+#include "LibLsp/lsp/textDocument/SemanticTokens.h"
+
+
+extern void Reflect(Reader&, std::pair<boost::optional<lsTextDocumentSyncKind>, boost::optional<lsTextDocumentSyncOptions> >&);
+
+//
+ // Code Action options.
+ //
+struct CodeActionOptions : WorkDoneProgressOptions {
+ //
+ // CodeActionKinds that this server may return.
+ //
+ // The list of kinds may be generic, such as `CodeActionKind.Refactor`, or the server
+ // may list out every specific kind they provide.
+ //
+ typedef std::string CodeActionKind;
+ std::vector<CodeActionKind> codeActionKinds;
+
+ MAKE_SWAP_METHOD(CodeActionOptions, workDoneProgress, codeActionKinds);
+};
+MAKE_REFLECT_STRUCT(CodeActionOptions, workDoneProgress, codeActionKinds)
+struct CodeLensOptions : WorkDoneProgressOptions {
+ //
+ // Code lens has a resolve provider as well.
+ //
+ boost::optional<bool> resolveProvider ;
+ MAKE_SWAP_METHOD(CodeLensOptions, workDoneProgress, resolveProvider);
+};
+MAKE_REFLECT_STRUCT(CodeLensOptions, workDoneProgress, resolveProvider)
+
+
+// Format document on type options
+struct lsDocumentOnTypeFormattingOptions :WorkDoneProgressOptions {
+ // A character on which formatting should be triggered, like `}`.
+ std::string firstTriggerCharacter;
+
+ // More trigger characters.
+ std::vector<std::string> moreTriggerCharacter;
+ MAKE_SWAP_METHOD(lsDocumentOnTypeFormattingOptions, workDoneProgress,
+ firstTriggerCharacter,
+ moreTriggerCharacter);
+};
+MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingOptions, workDoneProgress,
+ firstTriggerCharacter,
+ moreTriggerCharacter);
+struct RenameOptions : WorkDoneProgressOptions {
+ //
+ // Renames should be checked and tested before being executed.
+ //
+ boost::optional<bool> prepareProvider;
+ MAKE_SWAP_METHOD(RenameOptions, workDoneProgress, prepareProvider);
+};
+MAKE_REFLECT_STRUCT(RenameOptions,workDoneProgress,prepareProvider)
+
+struct DocumentFilter{
+ //
+ // A language id, like `typescript`.
+ //
+ boost::optional<std::string> language;
+ //
+ // A Uri [scheme](#Uri.scheme), like `file` or `untitled`.
+ //
+ boost::optional<std::string>scheme;
+ //
+ // A glob pattern, like `*.{ts,js}`.
+ //
+ // Glob patterns can have the following syntax:
+ // - `*` to match one or more characters in a path segment
+ // - `?` to match on one character in a path segment
+ // - `**` to match any number of path segments, including none
+ // - `{}` to group sub patterns into an OR expression. (e.g. `**/*.{ts,js}
+ // matches all TypeScript and JavaScript files)
+ // - `[]` to declare a range of characters to match in a path segment
+ // (e.g., `example.[0-9]` to match on `example.0`, `example.1`,...)
+ // - `[!...]` to negate a range of characters to match in a path segment
+ // (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but
+ // not `example.0`)
+ //
+ boost::optional<std::string>pattern;
+ MAKE_SWAP_METHOD(DocumentFilter, language, scheme, pattern)
+};
+MAKE_REFLECT_STRUCT(DocumentFilter, language, scheme, pattern)
+
+//A document selector is the combination of one or more document filters.
+using DocumentSelector = std::vector<DocumentFilter>;
+
+// Document link options
+struct lsDocumentLinkOptions :WorkDoneProgressOptions {
+ // Document links have a resolve provider as well.
+ boost::optional<bool> resolveProvider;
+ MAKE_SWAP_METHOD(lsDocumentLinkOptions, workDoneProgress, resolveProvider);
+};
+MAKE_REFLECT_STRUCT(lsDocumentLinkOptions, workDoneProgress,resolveProvider);
+
+// Execute command options.
+struct lsExecuteCommandOptions : WorkDoneProgressOptions {
+ // The commands to be executed on the server
+ std::vector<std::string> commands;
+ MAKE_SWAP_METHOD(lsExecuteCommandOptions, workDoneProgress, commands);
+};
+MAKE_REFLECT_STRUCT(lsExecuteCommandOptions, workDoneProgress, commands);
+
+
+struct TextDocumentRegistrationOptions
+{
+//
+ // A document selector to identify the scope of the registration. If set to null
+ // the document selector provided on the client side will be used.
+ //
+ boost::optional<DocumentSelector> documentSelector;
+
+ MAKE_SWAP_METHOD(TextDocumentRegistrationOptions, documentSelector);
+};
+MAKE_REFLECT_STRUCT(TextDocumentRegistrationOptions, documentSelector);
+
+//
+ // Static registration options to be returned in the initialize request.
+ //
+struct StaticRegistrationOptions :public TextDocumentRegistrationOptions
+{
+ //
+ // The id used to register the request. The id can be used to deregister
+ // the request again. See also Registration#id.
+ //
+ boost::optional<std::string> id;
+ MAKE_SWAP_METHOD(StaticRegistrationOptions, documentSelector, id)
+};
+MAKE_REFLECT_STRUCT(StaticRegistrationOptions, documentSelector,id)
+
+//
+ // The server supports workspace folder.
+ //
+ // Since 3.6.0
+ //
+
+struct WorkspaceFoldersOptions {
+ //
+ // The server has support for workspace folders
+ //
+ boost::optional<bool> supported;
+
+ //
+ // Whether the server wants to receive workspace folder
+ // change notifications.
+ //
+ // If a string is provided, the string is treated as an ID
+ // under which the notification is registered on the client
+ // side. The ID can be used to unregister for these events
+ // using the `client/unregisterCapability` request.
+ //
+ boost::optional<std::pair< boost::optional<std::string>, boost::optional<bool> > > changeNotifications;
+ MAKE_SWAP_METHOD(WorkspaceFoldersOptions, supported, changeNotifications);
+};
+MAKE_REFLECT_STRUCT(WorkspaceFoldersOptions, supported, changeNotifications);
+
+//
+ // A pattern kind describing if a glob pattern matches a file a folder or
+ // both.
+ //
+ // @since 3.16.0
+ //
+enum lsFileOperationPatternKind
+{
+ file,
+ folder
+};
+MAKE_REFLECT_TYPE_PROXY(lsFileOperationPatternKind)
+
+//
+ // Matching options for the file operation pattern.
+ //
+ // @since 3.16.0
+ //
+struct lsFileOperationPatternOptions {
+
+ //
+ // The pattern should be matched ignoring casing.
+ //
+ boost::optional<bool> ignoreCase;
+ MAKE_SWAP_METHOD(lsFileOperationPatternOptions, ignoreCase)
+};
+MAKE_REFLECT_STRUCT(lsFileOperationPatternOptions, ignoreCase)
+//
+ // A pattern to describe in which file operation requests or notifications
+ // the server is interested in.
+ //
+ // @since 3.16.0
+ //
+struct lsFileOperationPattern {
+ //
+ // The glob pattern to match. Glob patterns can have the following syntax:
+ // - `*` to match one or more characters in a path segment
+ // - `?` to match on one character in a path segment
+ // - `**` to match any number of path segments, including none
+ // - `{}` to group sub patterns into an OR expression. (e.g. `**/*.{ts,js}`
+ // matches all TypeScript and JavaScript files)
+ // - `[]` to declare a range of characters to match in a path segment
+ // (e.g., `example.[0-9]` to match on `example.0`, `example.1`,...)
+ // - `[!...]` to negate a range of characters to match in a path segment
+ // (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but
+ // not `example.0`)
+ //
+ std::string glob;
+
+ //
+ // Whether to match files or folders with this pattern.
+ //
+ // Matches both if undefined.
+ //
+ boost::optional<lsFileOperationPatternKind> matches;
+
+ //
+ // Additional options used during matching.
+ //
+ boost::optional<lsFileOperationPatternOptions> options ;
+ MAKE_SWAP_METHOD(lsFileOperationPattern, glob, matches, options)
+};
+MAKE_REFLECT_STRUCT(lsFileOperationPattern, glob, matches, options)
+//
+ // A filter to describe in which file operation requests or notifications
+ // the server is interested in.
+ //
+ // @since 3.16.0
+ //
+struct lsFileOperationFilter {
+
+ //
+ // A Uri like `file` or `untitled`.
+ //
+ boost::optional<std::string> scheme;
+
+ //
+ // The actual file operation pattern.
+ //
+ boost::optional<lsFileOperationPattern> pattern;
+ MAKE_SWAP_METHOD(lsFileOperationFilter, scheme, pattern)
+};
+MAKE_REFLECT_STRUCT(lsFileOperationFilter, scheme, pattern)
+//
+ // The options to register for file operations.
+ //
+ // @since 3.16.0
+ //
+struct lsFileOperationRegistrationOptions {
+ //
+ // The actual filters.
+ //
+ boost::optional<std::vector<lsFileOperationFilter>> filters;
+ MAKE_SWAP_METHOD(lsFileOperationRegistrationOptions, filters)
+};
+MAKE_REFLECT_STRUCT(lsFileOperationRegistrationOptions, filters)
+
+struct WorkspaceServerCapabilities {
+ //
+ // The server supports workspace folder.
+ //
+ // Since 3.6.0
+ //
+ WorkspaceFoldersOptions workspaceFolders;
+
+
+ //
+ // The server is interested in file notifications/requests.
+ //
+ // @since 3.16.0
+ //
+ struct lsFileOperations
+ {
+ //
+ // The server is interested in receiving didCreateFiles
+ // notifications.
+ //
+ boost::optional<lsFileOperationRegistrationOptions> didCreate;
+
+ //
+ // The server is interested in receiving willCreateFiles requests.
+ //
+ boost::optional<lsFileOperationRegistrationOptions> willCreate;
+
+ //
+ // The server is interested in receiving didRenameFiles
+ // notifications.
+ //
+ boost::optional<lsFileOperationRegistrationOptions> didRename;
+
+ //
+ // The server is interested in receiving willRenameFiles requests.
+ //
+ boost::optional<lsFileOperationRegistrationOptions> willRename;
+
+ //
+ // The server is interested in receiving didDeleteFiles file
+ // notifications.
+ //
+ boost::optional<lsFileOperationRegistrationOptions> didDelete;
+
+ //
+ // The server is interested in receiving willDeleteFiles file
+ // requests.
+ //
+ boost::optional<lsFileOperationRegistrationOptions> willDelete;
+ MAKE_SWAP_METHOD(lsFileOperations, didCreate, willCreate, didRename, willRename, didDelete, willDelete)
+ };
+ boost::optional<lsFileOperations>fileOperations;
+
+
+ MAKE_SWAP_METHOD(WorkspaceServerCapabilities, workspaceFolders, fileOperations)
+};
+MAKE_REFLECT_STRUCT(WorkspaceServerCapabilities, workspaceFolders, fileOperations)
+MAKE_REFLECT_STRUCT(WorkspaceServerCapabilities::lsFileOperations, didCreate, willCreate, didRename, willRename, didDelete, willDelete)
+
+//
+ // Semantic highlighting server capabilities.
+ //
+ // <p>
+ // <b>Note:</b> the <a href=
+ // "https://github.com/Microsoft/vscode-languageserver-node/pull/367">{@code textDocument/semanticHighlighting}
+ // language feature</a> is not yet part of the official LSP specification.
+ //
+
+struct SemanticHighlightingServerCapabilities {
+ //
+ // A "lookup table" of semantic highlighting <a href="https://manual.macromates.com/en/language_grammars">TextMate scopes</a>
+ // supported by the language server. If not defined or empty, then the server does not support the semantic highlighting
+ // feature. Otherwise, clients should reuse this "lookup table" when receiving semantic highlighting notifications from
+ // the server.
+ //
+ std::vector< std::vector<std::string> > scopes;
+ MAKE_SWAP_METHOD(SemanticHighlightingServerCapabilities, scopes)
+};
+MAKE_REFLECT_STRUCT(SemanticHighlightingServerCapabilities, scopes)
+
+struct SemanticTokensServerFull
+{
+ //
+ // The server supports deltas for full documents.
+ //
+ bool delta =false;
+ MAKE_SWAP_METHOD(SemanticTokensServerFull, delta)
+};
+MAKE_REFLECT_STRUCT(SemanticTokensServerFull, delta)
+struct SemanticTokensWithRegistrationOptions
+{
+ SemanticTokensLegend legend;
+
+ //
+ // Server supports providing semantic tokens for a specific range
+ // of a document.
+ //
+ boost::optional< std::pair< boost::optional<bool>, boost::optional<lsp::Any> > > range;
+
+ //
+ // Server supports providing semantic tokens for a full document.
+ //
+ boost::optional< std::pair< boost::optional<bool>,
+ boost::optional<SemanticTokensServerFull> > > full;
+
+ //
+ // A document selector to identify the scope of the registration. If set to null
+ // the document selector provided on the client side will be used.
+ //
+ boost::optional < std::vector<DocumentFilter> > documentSelector;
+ //
+ // The id used to register the request. The id can be used to deregister
+ // the request again. See also Registration#id.
+ //
+ boost::optional<std::string> id;
+ MAKE_SWAP_METHOD(SemanticTokensWithRegistrationOptions, legend, range, full, documentSelector, id)
+};
+MAKE_REFLECT_STRUCT(SemanticTokensWithRegistrationOptions, legend, range, full, documentSelector ,id)
+
+using DocumentColorOptions = WorkDoneProgressOptions;
+using FoldingRangeOptions = WorkDoneProgressOptions;
+struct lsServerCapabilities {
+ // Defines how text documents are synced. Is either a detailed structure
+ // defining each notification or for backwards compatibility the
+
+ // TextDocumentSyncKind number.
+ boost::optional< std::pair<boost::optional<lsTextDocumentSyncKind>,
+ boost::optional<lsTextDocumentSyncOptions> >> textDocumentSync;
+
+ // The server provides hover support.
+ boost::optional<bool> hoverProvider;
+
+ // The server provides completion support.
+ boost::optional < lsCompletionOptions > completionProvider;
+
+ // The server provides signature help support.
+ boost::optional < lsSignatureHelpOptions > signatureHelpProvider;
+
+ // The server provides goto definition support.
+ boost::optional< std::pair< boost::optional<bool>, boost::optional<WorkDoneProgressOptions> > > definitionProvider;
+
+
+ //
+ // The server provides Goto Type Definition support.
+ //
+ // Since 3.6.0
+ //
+ boost::optional< std::pair< boost::optional<bool>, boost::optional<StaticRegistrationOptions> > > typeDefinitionProvider ;
+
+ // The server provides implementation support.
+ boost::optional< std::pair< boost::optional<bool>, boost::optional<StaticRegistrationOptions> > > implementationProvider ;
+
+ // The server provides find references support.
+ boost::optional< std::pair< boost::optional<bool>, boost::optional<WorkDoneProgressOptions> > > referencesProvider ;
+
+ // The server provides document highlight support.
+ boost::optional< std::pair< boost::optional<bool>, boost::optional<WorkDoneProgressOptions> > > documentHighlightProvider ;
+
+ // The server provides document symbol support.
+ boost::optional< std::pair< boost::optional<bool>, boost::optional<WorkDoneProgressOptions> > > documentSymbolProvider ;
+
+ // The server provides workspace symbol support.
+ boost::optional< std::pair< boost::optional<bool>, boost::optional<WorkDoneProgressOptions> > > workspaceSymbolProvider ;
+
+ // The server provides code actions.
+ boost::optional< std::pair< boost::optional<bool>, boost::optional<CodeActionOptions> > > codeActionProvider ;
+
+ // The server provides code lens.
+ boost::optional<CodeLensOptions> codeLensProvider;
+
+ // The server provides document formatting.
+ boost::optional< std::pair< boost::optional<bool>, boost::optional<WorkDoneProgressOptions> > > documentFormattingProvider ;
+
+ // The server provides document range formatting.
+ boost::optional< std::pair< boost::optional<bool>, boost::optional<WorkDoneProgressOptions> > > documentRangeFormattingProvider ;
+
+ // The server provides document formatting on typing.
+ boost::optional<lsDocumentOnTypeFormattingOptions> documentOnTypeFormattingProvider;
+
+ // The server provides rename support.
+ boost::optional< std::pair< boost::optional<bool>, boost::optional<RenameOptions> > > renameProvider;
+
+
+ // The server provides document link support.
+ boost::optional<lsDocumentLinkOptions > documentLinkProvider;
+
+
+ //
+ // The server provides color provider support.
+ //
+ // @since 3.6.0
+ //
+ boost::optional< std::pair< boost::optional<bool>, boost::optional<DocumentColorOptions> > > colorProvider;
+
+
+ //
+ // The server provides folding provider support.
+ //
+ // @since 3.10.0
+ //
+ boost::optional < std::pair< boost::optional<bool>, boost::optional<FoldingRangeOptions> > > foldingRangeProvider;
+
+ // The server provides execute command support.
+ boost::optional < lsExecuteCommandOptions >executeCommandProvider;
+
+
+ //
+ // Workspace specific server capabilities
+ //
+ boost::optional< WorkspaceServerCapabilities > workspace;
+
+ //
+ // Semantic highlighting server capabilities.
+ //
+
+ boost::optional< SemanticHighlightingServerCapabilities >semanticHighlighting;
+
+ //
+ // Server capability for calculating super- and subtype hierarchies.
+ // The LS supports the type hierarchy language feature, if this capability is set to {@code true}.
+ //
+ // <p>
+ // <b>Note:</b> the <a href=
+ // "https://github.com/Microsoft/vscode-languageserver-node/pull/426">{@code textDocument/typeHierarchy}
+ // language feature</a> is not yet part of the official LSP specification.
+ //
+
+ boost::optional< std::pair< boost::optional<bool>,
+ boost::optional<StaticRegistrationOptions> > > typeHierarchyProvider;
+
+ //
+ // The server provides Call Hierarchy support.
+ //
+
+ boost::optional< std::pair< boost::optional<bool>,
+ boost::optional<StaticRegistrationOptions> > > callHierarchyProvider;
+
+ //
+ // The server provides selection range support.
+ //
+ // Since 3.15.0
+ //
+ boost::optional< std::pair< boost::optional<bool>,
+ boost::optional<StaticRegistrationOptions> > > selectionRangeProvider;
+
+ //
+ // The server provides linked editing range support.
+ //
+ // Since 3.16.0
+ //
+ boost::optional< std::pair< boost::optional<bool>,
+ boost::optional<StaticRegistrationOptions> > > linkedEditingRangeProvider;
+
+
+ //
+ // The server provides semantic tokens support.
+ //
+ // Since 3.16.0
+ //
+ boost::optional < SemanticTokensWithRegistrationOptions> semanticTokensProvider;
+
+ //
+ // Whether server provides moniker support.
+ //
+ // Since 3.16.0
+ //
+ boost::optional< std::pair< boost::optional<bool>,
+ boost::optional<StaticRegistrationOptions> > > monikerProvider;
+
+ boost::optional<lsp::Any> experimental;
+
+
+ MAKE_SWAP_METHOD(lsServerCapabilities,
+ textDocumentSync,
+ hoverProvider,
+ completionProvider,
+ signatureHelpProvider,
+ definitionProvider,
+ typeDefinitionProvider,
+ implementationProvider,
+ referencesProvider,
+ documentHighlightProvider,
+ documentSymbolProvider,
+ workspaceSymbolProvider,
+ codeActionProvider,
+ codeLensProvider,
+ documentFormattingProvider,
+ documentRangeFormattingProvider,
+ documentOnTypeFormattingProvider,
+ renameProvider,
+ documentLinkProvider,
+ executeCommandProvider,
+ workspace,
+ semanticHighlighting,
+ typeHierarchyProvider,
+ callHierarchyProvider,
+ selectionRangeProvider,
+ experimental, colorProvider, foldingRangeProvider,
+ linkedEditingRangeProvider, monikerProvider, semanticTokensProvider)
+
+};
+MAKE_REFLECT_STRUCT(lsServerCapabilities,
+ textDocumentSync,
+ hoverProvider,
+ completionProvider,
+ signatureHelpProvider,
+ definitionProvider,
+ typeDefinitionProvider,
+ implementationProvider,
+ referencesProvider,
+ documentHighlightProvider,
+ documentSymbolProvider,
+ workspaceSymbolProvider,
+ codeActionProvider,
+ codeLensProvider,
+ documentFormattingProvider,
+ documentRangeFormattingProvider,
+ documentOnTypeFormattingProvider,
+ renameProvider,
+ documentLinkProvider,
+ executeCommandProvider,
+ workspace,
+ semanticHighlighting,
+ typeHierarchyProvider,
+ callHierarchyProvider,
+ selectionRangeProvider,
+ experimental, colorProvider, foldingRangeProvider,
+ linkedEditingRangeProvider, monikerProvider, semanticTokensProvider)
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/general/lsTextDocumentClientCapabilities.h b/graphics/asymptote/LspCpp/LibLsp/lsp/general/lsTextDocumentClientCapabilities.h
new file mode 100644
index 0000000000..569f203c7a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/general/lsTextDocumentClientCapabilities.h
@@ -0,0 +1,713 @@
+#pragma once
+#include "LibLsp/lsp/method_type.h"
+
+
+#include <stdexcept>
+#include "LibLsp/JsonRpc/message.h"
+#include "LibLsp/lsp/lsDocumentUri.h"
+#include "LibLsp/lsp/lsAny.h"
+#include "LibLsp/lsp/extention/jdtls/searchSymbols.h"
+#include "lsWorkspaceClientCapabilites.h"
+#include "LibLsp/lsp/lsp_completion.h"
+#include "LibLsp/lsp/lsp_diagnostic.h"
+
+
+struct WorkDoneProgressOptions
+{
+ boost::optional<bool>workDoneProgress;
+ MAKE_SWAP_METHOD(WorkDoneProgressOptions, workDoneProgress);
+};
+MAKE_REFLECT_STRUCT(WorkDoneProgressOptions, workDoneProgress);
+
+// Completion options.
+struct lsCompletionOptions:WorkDoneProgressOptions
+{
+ // The server provides support to resolve additional
+ // information for a completion item.
+ boost::optional<bool> resolveProvider = false;
+
+ //
+ // Most tools trigger completion request automatically without explicitly requesting
+ // it using a keyboard shortcut (e.g. Ctrl+Space). Typically they do so when the user
+ // starts to type an identifier. For example if the user types `c` in a JavaScript file
+ // code complete will automatically pop up present `console` besides others as a
+ // completion item. Characters that make up identifiers don't need to be listed here.
+ //
+ // If code complete should automatically be trigger on characters not being valid inside
+ // an identifier (for example `.` in JavaScript) list them in `triggerCharacters`.
+ //
+ // https://github.com/Microsoft/language-server-protocol/issues/138.
+ boost::optional< std::vector<std::string> > triggerCharacters ;
+
+ //
+ // The list of all possible characters that commit a completion. This field can be used
+ // if clients don't support individual commmit characters per completion item. See
+ // `ClientCapabilities.textDocument.completion.completionItem.commitCharactersSupport`
+ //
+ boost::optional< std::vector<std::string> > allCommitCharacters;
+
+ MAKE_SWAP_METHOD(lsCompletionOptions, workDoneProgress, resolveProvider, triggerCharacters, allCommitCharacters);
+};
+MAKE_REFLECT_STRUCT(lsCompletionOptions, workDoneProgress, resolveProvider, triggerCharacters,allCommitCharacters);
+
+
+
+// Save options.
+struct lsSaveOptions {
+ // The client is supposed to include the content on save.
+ bool includeText = false;
+ void swap(lsSaveOptions& arg)noexcept
+ {
+ auto temp = includeText;
+ includeText = arg.includeText;
+ arg.includeText = temp;
+ }
+};
+MAKE_REFLECT_STRUCT(lsSaveOptions, includeText);
+
+// Signature help options.
+struct lsSignatureHelpOptions : WorkDoneProgressOptions {
+ // The characters that trigger signature help automatically.
+ // NOTE: If updating signature help tokens make sure to also update
+ // WorkingFile::FindClosestCallNameInBuffer.
+ std::vector<std::string> triggerCharacters;
+ MAKE_SWAP_METHOD(lsSignatureHelpOptions, workDoneProgress, triggerCharacters);
+};
+MAKE_REFLECT_STRUCT(lsSignatureHelpOptions, workDoneProgress, triggerCharacters);
+
+// Defines how the host (editor) should sync document changes to the language
+// server.
+enum class lsTextDocumentSyncKind {
+ // Documents should not be synced at all.
+ None = 0,
+
+ // Documents are synced by always sending the full content
+ // of the document.
+ Full = 1,
+
+ // Documents are synced by sending the full content on open.
+ // After that only incremental updates to the document are
+ // send.
+ Incremental = 2
+};
+
+#if _WIN32
+MAKE_REFLECT_TYPE_PROXY(lsTextDocumentSyncKind)
+#else
+//#pragma clang diagnostic push
+//#pragma clang diagnostic ignored "-Wunused-function"
+MAKE_REFLECT_TYPE_PROXY(lsTextDocumentSyncKind)
+//#pragma clang diagnostic pop
+#endif
+
+struct lsTextDocumentSyncOptions {
+ // Open and close notifications are sent to the server.
+ boost::optional<bool> openClose ;
+ // Change notificatins are sent to the server. See TextDocumentSyncKind.None,
+ // TextDocumentSyncKind.Full and TextDocumentSyncKindIncremental.
+ boost::optional< lsTextDocumentSyncKind> change ;
+ // Will save notifications are sent to the server.
+ boost::optional<bool> willSave;
+ // Will save wait until requests are sent to the server.
+ boost::optional<bool> willSaveWaitUntil;
+ // Save notifications are sent to the server.
+ boost::optional<lsSaveOptions> save;
+
+ MAKE_SWAP_METHOD(lsTextDocumentSyncOptions,
+ openClose,
+ change,
+ willSave,
+ willSaveWaitUntil,
+ save);
+};
+MAKE_REFLECT_STRUCT(lsTextDocumentSyncOptions,
+ openClose,
+ change,
+ willSave,
+ willSaveWaitUntil,
+ save);
+
+struct SynchronizationCapabilities {
+ // Whether text document synchronization supports dynamic registration.
+ boost::optional<bool> dynamicRegistration;
+
+ // The client supports sending will save notifications.
+ boost::optional<bool> willSave;
+
+ // The client supports sending a will save request and
+ // waits for a response providing text edits which will
+ // be applied to the document before it is saved.
+ boost::optional<bool> willSaveWaitUntil;
+
+ // The client supports did save notifications.
+ boost::optional<bool> didSave;
+
+ MAKE_SWAP_METHOD(SynchronizationCapabilities,
+ dynamicRegistration,
+ willSave,
+ willSaveWaitUntil,
+ didSave);
+};
+MAKE_REFLECT_STRUCT(SynchronizationCapabilities,
+ dynamicRegistration,
+ willSave,
+ willSaveWaitUntil,
+ didSave);
+
+struct CompletionItemKindCapabilities
+{
+ boost::optional<std::vector<lsCompletionItemKind> >valueSet;
+ MAKE_SWAP_METHOD(CompletionItemKindCapabilities, valueSet);
+};
+MAKE_REFLECT_STRUCT(CompletionItemKindCapabilities, valueSet);
+
+struct CompletionItemCapabilities {
+ // Client supports snippets as insert text.
+ //
+ // A snippet can define tab stops and placeholders with `$1`, `$2`
+ // and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+ // the end of the snippet. Placeholders with equal identifiers are linked,
+ // that is typing in one will update others too.
+ boost::optional<bool> snippetSupport;
+
+ // Client supports commit characters on a completion item.
+
+ boost::optional<bool> commitCharactersSupport;
+
+
+ // Client supports the following content formats for the documentation
+ // property. The order describes the preferred format of the client.
+
+ boost::optional< std::vector<std::string> > documentationFormat;
+
+ // Client supports the deprecated property on a completion item.
+
+ boost::optional<bool> deprecatedSupport;
+
+ //
+ // Client supports the preselect property on a completion item.
+ //
+ boost::optional<bool> preselectSupport;
+
+ MAKE_SWAP_METHOD(CompletionItemCapabilities,
+ snippetSupport,
+ commitCharactersSupport,
+ documentationFormat,
+ deprecatedSupport, preselectSupport);
+};
+MAKE_REFLECT_STRUCT(CompletionItemCapabilities,
+ snippetSupport,
+ commitCharactersSupport,
+ documentationFormat,
+ deprecatedSupport, preselectSupport);
+
+
+//
+ // Capabilities specific to the `textDocument/completion`
+ //
+struct CompletionCapabilities {
+ // Whether completion supports dynamic registration.
+ boost::optional<bool> dynamicRegistration;
+
+
+
+ // The client supports the following `CompletionItem` specific
+ // capabilities.
+ boost::optional<CompletionItemCapabilities> completionItem;
+
+ //
+ // The client supports the following `CompletionItemKind` specific
+ // capabilities.
+ //
+ boost::optional<CompletionItemKindCapabilities> completionItemKind;
+
+ //
+ // The client supports sending additional context information for a
+ // `textDocument/completion` request.
+ //
+ boost::optional<bool> contextSupport;
+
+
+ MAKE_SWAP_METHOD(CompletionCapabilities,
+ dynamicRegistration,
+ completionItem, completionItemKind);
+};
+
+MAKE_REFLECT_STRUCT(CompletionCapabilities,
+ dynamicRegistration,
+ completionItem , completionItemKind);
+
+
+struct HoverCapabilities:public DynamicRegistrationCapabilities
+{
+ //
+ // Client supports the following content formats for the content
+ // property. The order describes the preferred format of the client.
+ //
+ // See {@link MarkupKind} for allowed values.
+ //
+ boost::optional<std::vector<std::string>> contentFormat;
+
+ MAKE_SWAP_METHOD(HoverCapabilities, dynamicRegistration, contentFormat);
+};
+MAKE_REFLECT_STRUCT(HoverCapabilities, dynamicRegistration, contentFormat);
+
+//
+ // Client capabilities specific to parameter information.
+ //
+struct ParameterInformationCapabilities {
+ //
+ // The client supports processing label offsets instead of a
+ // simple label string.
+ //
+ // Since 3.14.0
+ //
+ boost::optional<bool> labelOffsetSupport;
+
+ MAKE_SWAP_METHOD(ParameterInformationCapabilities, labelOffsetSupport);
+};
+MAKE_REFLECT_STRUCT(ParameterInformationCapabilities, labelOffsetSupport)
+
+
+struct SignatureInformationCapabilities {
+ //
+ // Client supports the following content formats for the documentation
+ // property. The order describes the preferred format of the client.
+ //
+ // See {@link MarkupKind} for allowed values.
+ //
+ std::vector<std::string> documentationFormat;
+
+ //
+ // Client capabilities specific to parameter information.
+ //
+ ParameterInformationCapabilities parameterInformation;
+
+ MAKE_SWAP_METHOD(SignatureInformationCapabilities, documentationFormat, parameterInformation)
+};
+MAKE_REFLECT_STRUCT(SignatureInformationCapabilities,documentationFormat, parameterInformation)
+
+struct SignatureHelpCapabilities :public DynamicRegistrationCapabilities
+{
+ //
+ // The client supports the following `SignatureInformation`
+ // specific properties.
+ //
+ boost::optional< SignatureInformationCapabilities > signatureInformation;
+
+ MAKE_SWAP_METHOD(SignatureHelpCapabilities, dynamicRegistration, signatureInformation)
+};
+MAKE_REFLECT_STRUCT(SignatureHelpCapabilities, dynamicRegistration, signatureInformation)
+
+struct DocumentSymbolCapabilities :public DynamicRegistrationCapabilities {
+ //
+ // Specific capabilities for the `SymbolKind`.
+ //
+ boost::optional<SymbolKindCapabilities> symbolKind;
+
+ //
+ // The client support hierarchical document symbols.
+ //
+ boost::optional<bool> hierarchicalDocumentSymbolSupport;
+
+ MAKE_SWAP_METHOD(DocumentSymbolCapabilities, dynamicRegistration, symbolKind, hierarchicalDocumentSymbolSupport)
+};
+MAKE_REFLECT_STRUCT(DocumentSymbolCapabilities, dynamicRegistration, symbolKind, hierarchicalDocumentSymbolSupport)
+
+struct DeclarationCapabilities:public DynamicRegistrationCapabilities{
+ //
+ // The client supports additional metadata in the form of declaration links.
+ //
+ boost::optional<bool>linkSupport;
+
+ MAKE_SWAP_METHOD(DeclarationCapabilities, dynamicRegistration, linkSupport);
+};
+MAKE_REFLECT_STRUCT(DeclarationCapabilities, dynamicRegistration, linkSupport)
+
+
+struct CodeActionKindCapabilities
+{
+ //
+ // The code action kind values the client supports. When this
+ // property exists the client also guarantees that it will
+ // handle values outside its set gracefully and falls back
+ // to a default value when unknown.
+ //
+ // See {@link CodeActionKind} for allowed values.
+ //
+ boost::optional< std::vector< std::string> >valueSet;
+
+ MAKE_SWAP_METHOD(CodeActionKindCapabilities, valueSet)
+};
+MAKE_REFLECT_STRUCT(CodeActionKindCapabilities,valueSet)
+
+struct CodeActionLiteralSupportCapabilities
+{
+ boost::optional<CodeActionKindCapabilities> codeActionKind;
+
+ MAKE_SWAP_METHOD(CodeActionLiteralSupportCapabilities, codeActionKind)
+};
+MAKE_REFLECT_STRUCT(CodeActionLiteralSupportCapabilities, codeActionKind)
+
+struct CodeActionCapabilities:public DynamicRegistrationCapabilities{
+ //
+ // The client support code action literals as a valid
+ // response of the `textDocument/codeAction` request.
+ //
+ boost::optional<CodeActionLiteralSupportCapabilities> codeActionLiteralSupport;
+
+ MAKE_SWAP_METHOD(CodeActionCapabilities, dynamicRegistration, codeActionLiteralSupport)
+};
+MAKE_REFLECT_STRUCT(CodeActionCapabilities,dynamicRegistration,codeActionLiteralSupport)
+
+struct RenameCapabilities :public DynamicRegistrationCapabilities {
+ //
+ // The client support code action literals as a valid
+ // response of the `textDocument/codeAction` request.
+ //
+ boost::optional<bool> prepareSupport;
+
+ MAKE_SWAP_METHOD(RenameCapabilities, dynamicRegistration, prepareSupport)
+};
+MAKE_REFLECT_STRUCT(RenameCapabilities, dynamicRegistration, prepareSupport)
+
+struct DiagnosticsTagSupport {
+ /**
+ * The tags supported by the client.
+ */
+ std::vector<DiagnosticTag> valueSet;
+ MAKE_SWAP_METHOD(DiagnosticsTagSupport, valueSet)
+};
+MAKE_REFLECT_STRUCT(DiagnosticsTagSupport, valueSet)
+
+struct PublishDiagnosticsClientCapabilities :public DynamicRegistrationCapabilities {
+ /**
+ * The client support code action literals as a valid
+ * response of the `textDocument/codeAction` request.
+ */
+ boost::optional<bool> relatedInformation;
+
+ /**
+ * Client supports the tag property to provide meta data about a diagnostic.
+ * Clients supporting tags have to handle unknown tags gracefully.
+ *
+ * This property had been added and implemented as boolean before it was
+ * added to the specification as {@link DiagnosticsTagSupport}. In order to
+ * keep this implementation compatible with intermediate clients (including
+ * vscode-language-client < 6.0.0) we add an either type here.
+ *
+ * Since 3.15
+ */
+ boost::optional < std::pair<boost::optional<bool>, boost::optional<DiagnosticsTagSupport> > > tagSupport;
+
+ /**
+ * Whether the client interprets the version property of the
+ * `textDocument/publishDiagnostics` notification's parameter.
+ *
+ * Since 3.15.0
+ */
+ boost::optional<bool> versionSupport;
+
+ /**
+ * Client supports a codeDescription property
+ *
+ * @since 3.16.0
+ */
+ boost::optional<bool> codeDescriptionSupport ;
+
+ /**
+ * Whether code action supports the `data` property which is
+ * preserved between a `textDocument/publishDiagnostics` and
+ * `textDocument/codeAction` request.
+ *
+ * @since 3.16.0
+ */
+ boost::optional<bool> dataSupport ;
+
+
+ MAKE_SWAP_METHOD(PublishDiagnosticsClientCapabilities, dynamicRegistration, relatedInformation, tagSupport,versionSupport,codeDescriptionSupport,dataSupport)
+};
+MAKE_REFLECT_STRUCT(PublishDiagnosticsClientCapabilities, dynamicRegistration, relatedInformation, tagSupport, versionSupport, codeDescriptionSupport, dataSupport)
+
+
+struct FoldingRangeCapabilities :public DynamicRegistrationCapabilities {
+ //
+ // The maximum number of folding ranges that the client prefers to receive per document. The value serves as a
+ // hint, servers are free to follow the limit.
+ //
+ boost::optional<int> rangeLimit;
+
+ //
+ // If set, the client signals that it only supports folding complete lines. If set, client will
+ // ignore specified `startCharacter` and `endCharacter` properties in a FoldingRange.
+ //
+ boost::optional<bool> lineFoldingOnly;
+ MAKE_SWAP_METHOD(FoldingRangeCapabilities, dynamicRegistration, rangeLimit, lineFoldingOnly)
+};
+MAKE_REFLECT_STRUCT(FoldingRangeCapabilities, dynamicRegistration, rangeLimit,lineFoldingOnly)
+
+
+struct SemanticHighlightingCapabilities :public DynamicRegistrationCapabilities {
+ //
+ // The client support code action literals as a valid
+ // response of the `textDocument/codeAction` request.
+ //
+ boost::optional<bool> semanticHighlighting;
+
+ MAKE_SWAP_METHOD(SemanticHighlightingCapabilities, dynamicRegistration, semanticHighlighting)
+};
+MAKE_REFLECT_STRUCT(SemanticHighlightingCapabilities, dynamicRegistration, semanticHighlighting)
+
+struct SemanticTokensClientCapabilitiesRequestsFull {
+
+ //
+ // The client will send the `textDocument/semanticTokens/full/delta` request if
+ // the server provides a corresponding handler.
+ //
+ bool delta = false;
+ MAKE_SWAP_METHOD(SemanticTokensClientCapabilitiesRequestsFull, delta)
+};
+MAKE_REFLECT_STRUCT(SemanticTokensClientCapabilitiesRequestsFull, delta)
+
+struct SemanticTokensClientCapabilities : public DynamicRegistrationCapabilities
+{
+ //export TokenFormat = 'relative';
+ struct lsRequests
+ {
+ //
+ // The client will send the `textDocument/semanticTokens/range` request
+ // if the server provides a corresponding handler.
+ //
+ boost::optional<std::pair< boost::optional<bool>,
+ boost::optional<SemanticTokensClientCapabilitiesRequestsFull>>> range;
+ //
+ // The client will send the `textDocument/semanticTokens/full` request
+ // if the server provides a corresponding handler.
+ //
+ boost::optional<std::pair< boost::optional<bool>, boost::optional<lsp::Any>>> full;
+ MAKE_SWAP_METHOD(lsRequests, range, full)
+ };
+
+ lsRequests requests;
+ //
+ // The token types that the client supports.
+ //
+ std::vector<std::string> tokenTypes;
+
+ //
+ // The token modifiers that the client supports.
+ //
+ std::vector<std::string> tokenModifiers;
+ //
+ // The formats the clients supports.
+ //
+ std::vector<std::string> formats;
+ //
+ // Whether the client supports tokens that can overlap each other.
+ //
+ boost::optional < bool >overlappingTokenSupport;
+
+ //
+ // Whether the client supports tokens that can span multiple lines.
+ //
+ boost::optional < bool > multilineTokenSupport;
+
+ MAKE_SWAP_METHOD(SemanticTokensClientCapabilities, dynamicRegistration,requests, tokenTypes, tokenModifiers,
+ formats, overlappingTokenSupport, multilineTokenSupport)
+
+};
+MAKE_REFLECT_STRUCT(SemanticTokensClientCapabilities::lsRequests, range,full)
+MAKE_REFLECT_STRUCT(SemanticTokensClientCapabilities, dynamicRegistration, requests, tokenTypes, tokenModifiers,
+ formats, overlappingTokenSupport, multilineTokenSupport)
+
+// Text document specific client capabilities.
+struct lsTextDocumentClientCapabilities {
+
+ SynchronizationCapabilities synchronization;
+
+
+ // Capabilities specific to the `textDocument/completion`
+ boost::optional<CompletionCapabilities> completion;
+
+
+
+ // Capabilities specific to the `textDocument/hover`
+ boost::optional<HoverCapabilities> hover;
+
+ // Capabilities specific to the `textDocument/signatureHelp`
+ boost::optional<SignatureHelpCapabilities> signatureHelp;
+
+ // Capabilities specific to the `textDocument/references`
+ boost::optional<DynamicRegistrationCapabilities> references;
+
+
+
+
+
+ // Capabilities specific to the `textDocument/documentHighlight`
+ boost::optional<DynamicRegistrationCapabilities> documentHighlight;
+
+ // Capabilities specific to the `textDocument/documentSymbol`
+ boost::optional<DocumentSymbolCapabilities> documentSymbol;
+
+ // Capabilities specific to the `textDocument/formatting`
+ boost::optional<DynamicRegistrationCapabilities> formatting;
+
+ // Capabilities specific to the `textDocument/rangeFormatting`
+ boost::optional<DynamicRegistrationCapabilities> rangeFormatting;
+
+ // Capabilities specific to the `textDocument/onTypeFormatting`
+ boost::optional<DynamicRegistrationCapabilities> onTypeFormatting;
+
+
+ //
+ // Capabilities specific to the `textDocument/declaration`
+ //
+ // Since 3.14.0
+ //
+ boost::optional< DeclarationCapabilities> declaration;
+
+
+ typedef DeclarationCapabilities DefinitionCapabilities;
+ // Capabilities specific to the `textDocument/definition`
+ boost::optional<DefinitionCapabilities> definition;
+
+
+
+ //
+// Capabilities specific to the `textDocument/typeDefinition`
+//
+// Since 3.6.0
+//
+ typedef DeclarationCapabilities TypeDefinitionCapabilities;
+ boost::optional<TypeDefinitionCapabilities> typeDefinition;
+
+
+ typedef DeclarationCapabilities ImplementationCapabilities;
+ // Capabilities specific to the `textDocument/implementation`
+ boost::optional<ImplementationCapabilities> implementation;
+
+
+ // Capabilities specific to the `textDocument/codeAction`
+ boost::optional<CodeActionCapabilities> codeAction;
+
+
+ // Capabilities specific to the `textDocument/codeLens`
+ boost::optional<DynamicRegistrationCapabilities> codeLens;
+
+ // Capabilities specific to the `textDocument/documentLink`
+ boost::optional<DynamicRegistrationCapabilities> documentLink;
+
+ //
+ // Capabilities specific to the `textDocument/documentColor` and the
+ // `textDocument/colorPresentation` request.
+ //
+ // Since 3.6.0
+ //
+ boost::optional<DynamicRegistrationCapabilities> colorProvider;
+
+ // Capabilities specific to the `textDocument/rename`
+ boost::optional<RenameCapabilities> rename;
+
+//
+// Capabilities specific to `textDocument/publishDiagnostics`.
+//
+ boost::optional<PublishDiagnosticsClientCapabilities> publishDiagnostics;
+
+ //
+// Capabilities specific to `textDocument/foldingRange` requests.
+//
+// Since 3.10.0
+//
+ boost::optional< FoldingRangeCapabilities > foldingRange;
+
+
+ //
+ // Capabilities specific to {@code textDocument/semanticHighlighting}.
+ //
+ boost::optional< SemanticHighlightingCapabilities > semanticHighlightingCapabilities;
+
+ //
+ // Capabilities specific to {@code textDocument/typeHierarchy}.
+ //
+ boost::optional< DynamicRegistrationCapabilities > typeHierarchyCapabilities;
+
+
+
+ //
+// Capabilities specific to `textDocument/selectionRange` requests
+//
+
+ boost::optional< DynamicRegistrationCapabilities > selectionRange;
+
+ //
+ // Capabilities specific to the `textDocument/linkedEditingRange` request.
+ //
+ // @since 3.16.0
+ //
+ boost::optional< DynamicRegistrationCapabilities > linkedEditingRange;
+
+ //
+ // Capabilities specific to the various call hierarchy requests.
+ //
+ // @since 3.16.0
+ //
+ boost::optional< DynamicRegistrationCapabilities > callHierarchy;
+
+ //
+ // Capabilities specific to the various semantic token requests.
+ //
+ // @since 3.16.0
+ //
+ boost::optional< SemanticTokensClientCapabilities > semanticTokens;
+
+ //
+ // Capabilities specific to the `textDocument/moniker` request.
+ //
+ // @since 3.16.0
+ //
+ boost::optional< DynamicRegistrationCapabilities > moniker;
+
+ MAKE_SWAP_METHOD(lsTextDocumentClientCapabilities,
+ synchronization,
+ completion,
+ hover,
+ signatureHelp,
+ implementation,
+ references,
+ documentHighlight,
+ documentSymbol,
+ formatting,
+ rangeFormatting,
+ onTypeFormatting,
+ declaration,
+ definition, typeDefinition, implementation,
+ codeAction,
+ codeLens,
+ documentLink, colorProvider,
+ rename, publishDiagnostics, foldingRange,
+ semanticHighlightingCapabilities, typeHierarchyCapabilities,
+ callHierarchy, selectionRange , linkedEditingRange, semanticTokens, moniker)
+};
+
+
+MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities,
+ synchronization,
+ completion,
+ hover,
+ signatureHelp,
+ implementation,
+ references,
+ documentHighlight,
+ documentSymbol,
+ formatting,
+ rangeFormatting,
+ onTypeFormatting,
+ declaration,
+ definition, typeDefinition, implementation,
+ codeAction,
+ codeLens,
+ documentLink, colorProvider,
+ rename, publishDiagnostics, foldingRange,
+ semanticHighlightingCapabilities, typeHierarchyCapabilities,
+ callHierarchy, selectionRange, linkedEditingRange, semanticTokens, moniker)
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/general/lsWorkspaceClientCapabilites.h b/graphics/asymptote/LspCpp/LibLsp/lsp/general/lsWorkspaceClientCapabilites.h
new file mode 100644
index 0000000000..dd37a1af2f
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/general/lsWorkspaceClientCapabilites.h
@@ -0,0 +1,256 @@
+#pragma once
+#include "LibLsp/lsp/method_type.h"
+
+
+#include <stdexcept>
+
+#include "LibLsp/JsonRpc/message.h"
+#include "LibLsp/lsp/lsDocumentUri.h"
+#include "LibLsp/lsp/lsAny.h"
+#include "LibLsp/lsp/extention/jdtls/searchSymbols.h"
+
+/**
+ * Capabilities specific to `WorkspaceEdit`s
+ */
+
+//New in version 3.13: ResourceOperationKind and FailureHandlingKind and the client capability workspace.workspaceEdit.
+//resourceOperations as well as workspace.workspaceEdit.failureHandling.
+
+//The capabilities of a workspace edit has evolved over the time.
+//Clients can describe their support using the following client capability :
+
+struct lschangeAnnotationSupport
+{
+ /**
+ * Whether the client groups edits with equal labels into tree nodes,
+ * for instance all edits labelled with "Changes in Strings" would
+ * be a tree node.
+ */
+ boost::optional<bool> groupsOnLabel;
+ MAKE_SWAP_METHOD(lschangeAnnotationSupport, groupsOnLabel)
+};
+MAKE_REFLECT_STRUCT(lschangeAnnotationSupport, groupsOnLabel)
+
+struct WorkspaceEditCapabilities {
+ /**
+ * The client supports versioned document changes in `WorkspaceEdit`s
+ */
+ boost::optional<bool> documentChanges;
+
+ /**
+ * The client supports resource changes
+ * in `WorkspaceEdit`s.
+ *
+ * @deprecated Since LSP introduces resource operations, use {link #resourceOperations}
+ */
+
+ boost::optional<bool> resourceChanges;
+
+ /**
+ * The resource operations the client supports. Clients should at least
+ * support 'create', 'rename' and 'delete' files and folders.
+ *
+ * @since 3.13.0
+ */
+ boost::optional< std::vector<std::string> > resourceOperations;
+
+ /**
+ * The failure handling strategy of a client if applying the workspace edit
+ * fails.
+ *
+ * See {@link FailureHandlingKind} for allowed values.
+ */
+ boost::optional<std::string > failureHandling;
+
+ /**
+ * Whether the client normalizes line endings to the client specific
+ * setting.
+ * If set to `true` the client will normalize line ending characters
+ * in a workspace edit to the client specific new line character(s).
+ *
+ * @since 3.16.0
+ */
+ boost::optional<bool> normalizesLineEndings;;
+
+ /**
+ * Whether the client in general supports change annotations on text edits,
+ * create file, rename file and delete file changes.
+ *
+ * @since 3.16.0
+ */
+ boost::optional<lschangeAnnotationSupport> changeAnnotationSupport;
+
+ MAKE_SWAP_METHOD(WorkspaceEditCapabilities, documentChanges, resourceChanges, resourceOperations, failureHandling, normalizesLineEndings, changeAnnotationSupport)
+
+};
+MAKE_REFLECT_STRUCT(WorkspaceEditCapabilities,documentChanges, resourceChanges, resourceOperations, failureHandling, normalizesLineEndings, changeAnnotationSupport)
+
+
+struct DynamicRegistrationCapabilities {
+ // Did foo notification supports dynamic registration.
+ boost::optional<bool> dynamicRegistration;
+
+ MAKE_SWAP_METHOD(DynamicRegistrationCapabilities,
+ dynamicRegistration);
+};
+
+MAKE_REFLECT_STRUCT(DynamicRegistrationCapabilities,
+ dynamicRegistration);
+
+
+
+// Workspace specific client capabilities.
+struct SymbolKindCapabilities
+{
+ boost::optional< std::vector<lsSymbolKind> > valueSet;
+
+ MAKE_SWAP_METHOD(SymbolKindCapabilities, valueSet)
+
+
+};
+MAKE_REFLECT_STRUCT(SymbolKindCapabilities, valueSet)
+
+
+
+
+struct SymbolCapabilities :public DynamicRegistrationCapabilities {
+ /**
+ * Specific capabilities for the `SymbolKind` in the `workspace/symbol` request.
+ */
+ boost::optional<SymbolKindCapabilities> symbolKind;
+
+ MAKE_SWAP_METHOD(SymbolCapabilities,
+ symbolKind, dynamicRegistration)
+};
+MAKE_REFLECT_STRUCT(SymbolCapabilities,
+ symbolKind, dynamicRegistration)
+
+
+struct lsFileOperations
+{
+ /**
+ * Whether the client supports dynamic registration for file
+ * requests/notifications.
+ */
+ boost::optional<bool> dynamicRegistration ;
+
+ /**
+ * The client has support for sending didCreateFiles notifications.
+ */
+ boost::optional<bool>didCreate ;
+
+ /**
+ * The client has support for sending willCreateFiles requests.
+ */
+ boost::optional<bool>willCreate ;
+
+ /**
+ * The client has support for sending didRenameFiles notifications.
+ */
+ boost::optional<bool>didRename ;
+
+ /**
+ * The client has support for sending willRenameFiles requests.
+ */
+ boost::optional<bool>willRename ;
+
+ /**
+ * The client has support for sending didDeleteFiles notifications.
+ */
+ boost::optional<bool>didDelete ;
+
+ /**
+ * The client has support for sending willDeleteFiles requests.
+ */
+ boost::optional<bool> willDelete ;
+ MAKE_SWAP_METHOD(lsFileOperations, dynamicRegistration, didCreate, willCreate,
+ didRename, willRename, didDelete, willDelete)
+};
+MAKE_REFLECT_STRUCT(lsFileOperations, dynamicRegistration, didCreate, willCreate,
+ didRename, willRename, didDelete, willDelete)
+
+struct lsWorkspaceClientCapabilites {
+ // The client supports applying batch edits to the workspace.
+ boost::optional<bool> applyEdit;
+
+
+
+ // Capabilities specific to `WorkspaceEdit`s
+ boost::optional<WorkspaceEditCapabilities> workspaceEdit;
+
+
+
+ // Capabilities specific to the `workspace/didChangeConfiguration`
+ // notification.
+ boost::optional<DynamicRegistrationCapabilities> didChangeConfiguration;
+
+ // Capabilities specific to the `workspace/didChangeWatchedFiles`
+ // notification.
+ boost::optional<DynamicRegistrationCapabilities> didChangeWatchedFiles;
+
+ // Capabilities specific to the `workspace/symbol` request.
+ boost::optional<SymbolCapabilities> symbol;
+
+ // Capabilities specific to the `workspace/executeCommand` request.
+ boost::optional<DynamicRegistrationCapabilities> executeCommand;
+
+
+ /**
+ * The client has support for workspace folders.
+ *
+ * Since 3.6.0
+ */
+ boost::optional<bool> workspaceFolders;
+
+ /**
+ * The client supports `workspace/configuration` requests.
+ *
+ * Since 3.6.0
+ */
+ boost::optional<bool> configuration;
+
+
+ /**
+ * Capabilities specific to the semantic token requests scoped to the
+ * workspace.
+ *
+ * @since 3.16.0
+ */
+ boost::optional<DynamicRegistrationCapabilities> semanticTokens ;
+
+ /**
+ * Capabilities specific to the code lens requests scoped to the
+ * workspace.
+ *
+ * @since 3.16.0
+ */
+ boost::optional<DynamicRegistrationCapabilities> codeLens ;
+
+ /**
+ * The client has support for file requests/notifications.
+ *
+ * @since 3.16.0
+ */
+ boost::optional<lsFileOperations> fileOperations;
+
+ MAKE_SWAP_METHOD(lsWorkspaceClientCapabilites,
+ applyEdit,
+ workspaceEdit,
+ didChangeConfiguration,
+ didChangeWatchedFiles,
+ symbol,executeCommand, workspaceFolders,
+ configuration, semanticTokens, codeLens, fileOperations)
+};
+
+MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites,
+ applyEdit,
+ workspaceEdit,
+ didChangeConfiguration,
+ didChangeWatchedFiles,
+ symbol,
+ executeCommand,workspaceFolders,
+ configuration, semanticTokens, codeLens, fileOperations)
+
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/general/progress.h b/graphics/asymptote/LspCpp/LibLsp/lsp/general/progress.h
new file mode 100644
index 0000000000..01cb18d68d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/general/progress.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+#include "LibLsp/lsp/lsAny.h"
+//The base protocol offers also support to report progress in a generic fashion.
+//This mechanism can be used to report any kind of progress including work done
+//progress(usually used to report progress in the user interface using a progress bar)
+//and partial result progress to support streaming of results.
+struct ProgressParams
+{
+ std::pair<boost::optional<std::string> , boost::optional<int> > token;
+ lsp::Any value;
+ MAKE_SWAP_METHOD(ProgressParams, token, value)
+};
+MAKE_REFLECT_STRUCT(ProgressParams, token, value)
+DEFINE_NOTIFICATION_TYPE(Notify_Progress, ProgressParams, "$/progress");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/general/shutdown.h b/graphics/asymptote/LspCpp/LibLsp/lsp/general/shutdown.h
new file mode 100644
index 0000000000..5366ff89d6
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/general/shutdown.h
@@ -0,0 +1,15 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+
+/**
+ * The shutdown request is sent from the client to the server. It asks the
+ * server to shutdown, but to not exit (otherwise the response might not be
+ * delivered correctly to the client). There is a separate exit notification
+ * that asks the server to exit.
+ */
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_shutdown, boost::optional<JsonNull>, boost::optional<lsp::Any>, "shutdown");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/language/language.h b/graphics/asymptote/LspCpp/LibLsp/lsp/language/language.h
new file mode 100644
index 0000000000..b4c7829e95
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/language/language.h
@@ -0,0 +1,170 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+
+#include "LibLsp/lsp/lsDocumentUri.h"
+#include "LibLsp/lsp/lsCommand.h"
+
+#ifdef _WIN32
+#include <ppltasks.h>
+#endif
+
+struct StatusReport {
+
+ std::string ToString() const
+ {
+ std::string info;
+ info += "type:" + type + "\n";
+ info += "message:" + message + "\n";
+ return info;
+ }
+ /**
+ * The message type. See {
+ *
+ */
+
+ std::string type;
+ /**
+ * The actual message
+ *
+ */
+
+ std::string message;
+ MAKE_SWAP_METHOD(StatusReport, type, message);
+};
+MAKE_REFLECT_STRUCT(StatusReport, type, message);
+
+/**
+ * The show message notification is sent from a server to a client to ask
+ * the client to display a particular message in the user interface.
+ */
+DEFINE_NOTIFICATION_TYPE(lang_status, StatusReport, "language/status");
+
+
+enum class MessageType {
+
+ /**
+ * An error message.
+ */
+ Error=(1),
+
+ /**
+ * A warning message.
+ */
+ Warning=(2),
+
+ /**
+ * An information message.
+ */
+ Info=(3),
+
+ /**
+ * A log message.
+ */
+ Log=(4)
+};
+MAKE_REFLECT_TYPE_PROXY(MessageType);
+
+
+struct ActionableNotification {
+
+
+
+ /**
+ * The message type. See {
+ *
+ */
+
+ MessageType severity;
+ /**
+ * The actual message
+ *
+ */
+
+ std::string message;
+
+ /**
+ * Optional data
+ *
+ */
+
+ boost::optional<lsp::Any> data;
+
+
+ /**
+ * Optional commands
+ *
+ */
+
+ std::vector<lsCommandWithAny> commands;
+
+ MAKE_SWAP_METHOD(ActionableNotification, severity, message, data, commands)
+};
+MAKE_REFLECT_STRUCT(ActionableNotification, severity, message, data, commands)
+
+
+/**
+ * The actionable notification is sent from a server to a client to ask the
+ * client to display a particular message in the user interface, and possible
+ * commands to execute. The commands must be implemented on the client side.
+ */
+DEFINE_NOTIFICATION_TYPE(lang_actionableNotification, ActionableNotification, "language/actionableNotification");
+
+
+
+struct ProgressReport {
+ std::string ToString() const;
+
+ std::string id;
+
+
+ std::string task;
+
+
+ std::string subTask;
+
+
+ std::string status;
+
+ int totalWork = 0;
+
+
+ int workDone = 0;
+
+
+ bool complete = false;
+ MAKE_SWAP_METHOD(ProgressReport, id, task, subTask, status, workDone, complete);
+};
+
+
+MAKE_REFLECT_STRUCT(ProgressReport, id, task, subTask, status, workDone, complete);
+
+/**
+ * The progress report notification is sent from a server to be handled by the
+ * client.
+ */
+DEFINE_NOTIFICATION_TYPE(lang_progressReport, ProgressReport, "language/progressReport");
+
+enum EventType {
+ /**
+ * classpath updated event.
+ */
+ ClasspathUpdated = (100),
+
+ /**
+ * projects imported event.
+ */
+ ProjectsImported = (200)
+};
+
+struct EventNotification
+{
+ int eventType;
+ lsp::Any data;
+ std::string ToString() const;
+ MAKE_SWAP_METHOD(EventNotification, eventType, data)
+};
+MAKE_REFLECT_STRUCT(EventNotification, eventType, data);
+
+DEFINE_NOTIFICATION_TYPE(lang_eventNotification, EventNotification, "language/eventNotification"); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/location_type.h b/graphics/asymptote/LspCpp/LibLsp/lsp/location_type.h
new file mode 100644
index 0000000000..14e130f571
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/location_type.h
@@ -0,0 +1,63 @@
+#pragma once
+
+#include "lsDocumentUri.h"
+#include "lsRange.h"
+//Represents a location inside a resource, such as a line inside a text file.
+struct lsLocation {
+ lsLocation();
+ lsLocation(lsDocumentUri uri, lsRange range);
+
+ bool operator==(const lsLocation& other) const;
+ bool operator<(const lsLocation& o) const;
+
+ lsDocumentUri uri;
+ lsRange range;
+ MAKE_SWAP_METHOD(lsLocation, uri, range)
+};
+MAKE_REFLECT_STRUCT(lsLocation, uri, range)
+
+
+
+struct LinkLocation :public lsLocation
+{
+ std::string displayName;
+ std::string kind;
+ MAKE_REFLECT_STRUCT(LinkLocation, uri, range, displayName, kind)
+};
+MAKE_REFLECT_STRUCT(LinkLocation, uri, range, displayName,kind)
+
+//Represents a link between a sourceand a target location.
+struct LocationLink
+{
+ /**
+ * Span of the origin of this link.
+ *
+ * Used as the underlined span for mouse interaction. Defaults to the word range at
+ * the mouse position.
+ */
+ boost::optional<lsRange> originSelectionRange;
+
+ /**
+ * The target resource identifier of this link.
+ */
+
+ lsDocumentUri targetUri;
+
+ /**
+ * The full target range of this link. If the target for example is a symbol then target range is the
+ * range enclosing this symbol not including leading/trailing whitespace but everything else
+ * like comments. This information is typically used to highlight the range in the editor.
+ */
+
+ lsRange targetRange;
+
+ /**
+ * The range that should be selected and revealed when this link is being followed, e.g the name of a function.
+ * Must be contained by the the `targetRange`. See also `DocumentSymbol#range`
+ */
+
+ lsRange targetSelectionRange;
+
+ MAKE_SWAP_METHOD(LocationLink, originSelectionRange, targetUri, targetRange, targetSelectionRange);
+};
+MAKE_REFLECT_STRUCT(LocationLink, originSelectionRange, targetUri, targetRange, targetSelectionRange); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lru_cache.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lru_cache.h
new file mode 100644
index 0000000000..f33bc5627a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lru_cache.h
@@ -0,0 +1,151 @@
+#pragma once
+
+#include <algorithm>
+#include <cassert>
+#include <limits>
+#include <memory>
+#include <vector>
+
+// Cache that evicts old entries which have not been used recently. Implemented
+// using array/linear search so this works well for small array sizes.
+template <typename TKey, typename TValue>
+struct LruCache {
+ explicit LruCache(int max_entries);
+
+ // Fetches an entry for |key|. If it does not exist, |allocator| will be
+ // invoked to create one.
+ template <typename TAllocator>
+ TValue Get(const TKey& key, TAllocator allocator);
+ // Returns true if there is an entry for |key|.
+ bool Has(const TKey& key);
+ // Fetches the entry for |filename| and updates it's usage so it is less
+ // likely to be evicted.
+ bool TryGet(const TKey& key, TValue* dest);
+ // TryGetEntry, except the entry is removed from the cache.
+ bool TryTake(const TKey& key, TValue* dest);
+ // Inserts an entry. Evicts the oldest unused entry if there is no space.
+ void Insert(const TKey& key, const TValue& value);
+
+ // Call |func| on existing entries. If |func| returns false iteration
+ // terminates early.
+ template <typename TFunc>
+ void IterateValues(TFunc func);
+
+ // Empties the cache
+ void Clear(void);
+
+ private:
+ // There is a global score counter, when we access an element we increase
+ // its score to the current global value, so it has the highest overall
+ // score. This means that the oldest/least recently accessed value has the
+ // lowest score.
+ //
+ // There is a bit of special logic to handle score overlow.
+ struct Entry {
+ uint32_t score = 0;
+ TKey key;
+ TValue value;
+ bool operator<(const Entry& other) const { return score < other.score; }
+ };
+
+ void IncrementScore();
+
+ std::vector<Entry> entries_;
+ int max_entries_ = 1;
+ uint32_t next_score_ = 0;
+};
+
+template <typename TKey, typename TValue>
+LruCache<TKey, TValue>::LruCache(int max_entries) : max_entries_(max_entries) {
+ assert(max_entries > 0);
+}
+
+template <typename TKey, typename TValue>
+template <typename TAllocator>
+TValue LruCache<TKey, TValue>::Get(const TKey& key, TAllocator allocator) {
+ for (Entry& entry : entries_) {
+ if (entry.key == key)
+ return entry.value;
+ }
+
+ auto result = allocator();
+ Insert(key, result);
+ return result;
+}
+
+template <typename TKey, typename TValue>
+bool LruCache<TKey, TValue>::Has(const TKey& key) {
+ for (Entry& entry : entries_) {
+ if (entry.key == key)
+ return true;
+ }
+ return false;
+}
+
+template <typename TKey, typename TValue>
+bool LruCache<TKey, TValue>::TryGet(const TKey& key, TValue* dest) {
+ // Assign new score.
+ for (Entry& entry : entries_) {
+ if (entry.key == key) {
+ entry.score = next_score_;
+ IncrementScore();
+ if (dest)
+ *dest = entry.value;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+template <typename TKey, typename TValue>
+bool LruCache<TKey, TValue>::TryTake(const TKey& key, TValue* dest) {
+ for (size_t i = 0; i < entries_.size(); ++i) {
+ if (entries_[i].key == key) {
+ if (dest)
+ *dest = entries_[i].value;
+ entries_.erase(entries_.begin() + i);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+template <typename TKey, typename TValue>
+void LruCache<TKey, TValue>::Insert(const TKey& key, const TValue& value) {
+ if ((int)entries_.size() >= max_entries_)
+ entries_.erase(std::min_element(entries_.begin(), entries_.end()));
+
+ Entry entry;
+ entry.score = next_score_;
+ IncrementScore();
+ entry.key = key;
+ entry.value = value;
+ entries_.push_back(entry);
+}
+
+template <typename TKey, typename TValue>
+template <typename TFunc>
+void LruCache<TKey, TValue>::IterateValues(TFunc func) {
+ for (Entry& entry : entries_) {
+ if (!func(entry.value))
+ break;
+ }
+}
+
+template <typename TKey, typename TValue>
+void LruCache<TKey, TValue>::IncrementScore() {
+ // Overflow.
+ if (++next_score_ == 0) {
+ std::sort(entries_.begin(), entries_.end());
+ for (Entry& entry : entries_)
+ entry.score = next_score_++;
+ }
+}
+
+template <typename TKey, typename TValue>
+void LruCache<TKey, TValue>::Clear(void) {
+ entries_.clear();
+ next_score_ = 0;
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsAny.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsAny.h
new file mode 100644
index 0000000000..3335aa86dc
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsAny.h
@@ -0,0 +1,159 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+#include <string>
+#include "LibLsp/JsonRpc/message.h"
+namespace lsp
+{
+ struct Any
+ {
+ //! Type of JSON value
+ enum Type {
+ kUnKnown=-1,
+ kNullType = 0, //!< null
+ kFalseType = 1, //!< false
+ kTrueType = 2, //!< true
+ kObjectType = 3, //!< object
+ kArrayType = 4, //!< array
+ kStringType = 5, //!< string
+ kNumberType = 6 //!< number
+ };
+
+
+
+ template <typename T>
+ bool Get(T& value);
+
+ template <typename T>
+ void Set(T& value);
+
+ int GuessType();
+ int GetType();
+
+ void Set(std::unique_ptr<LspMessage> value);
+
+ void SetJsonString(std::string&& _data, Type _type);
+
+ void SetJsonString(const std::string& _data, Type _type);
+
+ const std::string& Data()const
+ {
+ return data;
+ }
+
+ void swap(Any& arg) noexcept;
+
+ /*
+ *Example for GetFromMap
+ struct A{
+ std::string visitor;
+ bool verbose;
+ }
+ REFLECT_MAP_TO_STRUCT(A,visitor,verbose)
+
+ std::string data = "{\"visitor\":\"default\",\"verbose\":\"true\"};
+ lsp:Any any;
+ any.SetJsonString(data, static_cast<lsp::Any::Type>(-1));
+ A a_object;
+ any.GetFromMap(a_object);
+ */
+ template <typename T>
+ bool GetFromMap(T& value);
+
+
+ template <typename T>
+ bool GetForMapHelper(T& value);
+ bool GetForMapHelper(std::string& value);
+ bool GetForMapHelper(boost::optional<std::string>& value);
+ private:
+ std::unique_ptr<Reader> GetReader();
+ std::unique_ptr<Writer> GetWriter() const;
+ void SetData(std::unique_ptr<Writer>&);
+
+ std::string data;
+ int jsonType = kUnKnown;
+
+ };
+
+};
+
+
+extern void Reflect(Reader& visitor, lsp::Any& value);
+extern void Reflect(Writer& visitor, lsp::Any& value);
+
+template <typename T>
+void ReflectMember(std::map < std::string, lsp::Any>& visitor, const char* name, T& value) {
+
+ auto it = visitor.find(name);
+ if (it != visitor.end())
+ {
+ it->second.GetForMapHelper(value);
+ }
+}
+template <typename T>
+void ReflectMember(std::map < std::string, std::string>& visitor, const char* name, T& value) {
+
+ auto it = visitor.find(name);
+ if (it != visitor.end())
+ {
+ lsp::Any any;
+ any.SetJsonString(it->second, static_cast<lsp::Any::Type>(-1));
+ any.Get(value);
+ }
+}
+
+#define REFLECT_MAP_TO_STRUCT(type, ...) \
+ template <typename TVisitor> \
+ void ReflectMap(TVisitor& visitor, type& value) { \
+ MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \
+ }
+
+
+namespace lsp
+{
+ template <typename T>
+ bool Any::Get(T& value)
+ {
+ const auto visitor = GetReader();
+ Reflect(*visitor, value);
+ return true;
+ }
+
+ template <typename T>
+ void Any::Set(T& value)
+ {
+ auto visitor = GetWriter();
+ Reflect(*visitor, value);
+ SetData(visitor);
+ }
+
+ template <typename T>
+ bool Any::GetFromMap(T& value)
+ {
+ const auto visitor = GetReader();
+ std::map < std::string, lsp::Any> _temp;
+ Reflect(*visitor, _temp);
+ ReflectMap(_temp, value);
+ return true;
+ }
+
+ template <typename T>
+ bool Any::GetForMapHelper(T& value)
+ {
+ jsonType = GetType();
+ if (jsonType == kStringType)
+ {
+ auto copy = data;
+ copy.erase(copy.find_last_not_of('"') + 1);
+ copy.erase(0, copy.find_first_not_of('"'));
+ lsp::Any any;
+ any.SetJsonString(copy, kUnKnown);
+ any.Get(value);
+ }
+ else
+ {
+ Get(value);
+ }
+ return true;
+ }
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsCodeAction.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsCodeAction.h
new file mode 100644
index 0000000000..06a14f1540
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsCodeAction.h
@@ -0,0 +1,58 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+
+
+
+#include <string>
+#include <vector>
+#include "lsPosition.h"
+#include "lsWorkspaceEdit.h"
+#include "lsp_diagnostic.h"
+#include "lsCommand.h"
+
+struct CodeAction
+{
+ /**
+ * A short, human-readable, title for this code action.
+ */
+
+ std::string title;
+
+ /**
+ * The kind of the code action.
+ *
+ * Used to filter code actions.
+ */
+ boost::optional < std::string> kind;
+
+ /**
+ * The diagnostics that this code action resolves.
+ */
+ boost::optional < std::vector<lsDiagnostic>> diagnostics;
+
+ /**
+ * The workspace edit this code action performs.
+ */
+ boost::optional < lsWorkspaceEdit >edit;
+
+ /**
+ * A command this code action executes. If a code action
+ * provides a edit and a command, first the edit is
+ * executed and then the command.
+ */
+ boost::optional< lsCommandWithAny > command;
+
+ MAKE_SWAP_METHOD(CodeAction, title, kind, diagnostics, edit, command)
+};
+MAKE_REFLECT_STRUCT(CodeAction, title, kind, diagnostics, edit, command)
+struct TextDocumentCodeAction
+
+{
+
+ typedef std::pair<boost::optional<lsCommandWithAny>, boost::optional<CodeAction> > Either;
+
+};
+
+
+extern void Reflect(Reader& visitor, TextDocumentCodeAction::Either& value); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsCommand.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsCommand.h
new file mode 100644
index 0000000000..94307f1479
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsCommand.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+
+
+
+#include <string>
+#include <vector>
+#include "lsAny.h"
+//
+//Represents a reference to a command.Provides a title which will be used to represent a command in the UI.
+//Commands are identified by a string identifier.
+//The recommended way to handle commands is to implement their execution on the server side
+//if the clientand server provides the corresponding capabilities.Alternatively the tool
+//extension code could handle the command.The protocol currently doesnt specify a set of well - known commands.
+template <typename AnyArray>
+struct lsCommand {
+ // Title of the command (ie, 'save')
+ std::string title;
+ // Actual command identifier.
+ std::string command;
+ // Arguments to run the command with.
+ // **NOTE** This must be serialized as an array. Use
+ // MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY.
+ boost::optional<AnyArray> arguments;
+
+ void swap(lsCommand<AnyArray>& arg) noexcept
+ {
+ title.swap(arg.title);
+ command.swap(arg.command);
+ arguments.swap(arg.arguments);
+ }
+};
+template <typename TVisitor, typename T>
+void Reflect(TVisitor& visitor, lsCommand<T>& value) {
+ REFLECT_MEMBER_START();
+ REFLECT_MEMBER(title);
+ REFLECT_MEMBER(command);
+ REFLECT_MEMBER(arguments);
+ REFLECT_MEMBER_END();
+}
+
+
+using lsCommandWithAny = lsCommand< std::vector<lsp::Any>>;
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsDocumentUri.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsDocumentUri.h
new file mode 100644
index 0000000000..5d24f59e3a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsDocumentUri.h
@@ -0,0 +1,26 @@
+#pragma once
+#include "LibLsp/JsonRpc/serializer.h"
+#include <string>
+struct lsDocumentUri {
+ static lsDocumentUri FromPath(const AbsolutePath& path);
+
+ lsDocumentUri();
+
+ lsDocumentUri(const AbsolutePath& path);
+ lsDocumentUri(const lsDocumentUri& other);;
+ bool operator==(const lsDocumentUri& other) const;
+ bool operator==(const std::string& other) const;
+ void SetPath(const AbsolutePath& path);
+ std::string GetRawPath() const;
+ AbsolutePath GetAbsolutePath() const;
+
+
+ std::string raw_uri_;
+ void swap(lsDocumentUri& arg) noexcept
+ {
+ raw_uri_.swap(arg.raw_uri_);
+ }
+};
+extern void Reflect(Writer& visitor, lsDocumentUri& value);
+extern void Reflect(Reader& visitor, lsDocumentUri& value);
+extern std::string make_file_scheme_uri(const std::string& absolute_path);
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsFormattingOptions.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsFormattingOptions.h
new file mode 100644
index 0000000000..a92df9b077
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsFormattingOptions.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+
+struct lsFormattingOptions {
+ struct KeyData {
+ boost::optional<bool> _boolean;
+ boost::optional<int32_t> _integer;
+ boost::optional<std::string> _string;
+ };
+
+ // Size of a tab in spaces.
+ int tabSize =4;
+ // Prefer spaces over tabs.
+ bool insertSpaces = true;
+
+ /**
+ * Trim trailing whitespace on a line.
+ *
+ * @since 3.15.0
+ */
+ boost::optional<bool> trimTrailingWhitespace;
+
+ /**
+ * Insert a newline character at the end of the file if one does not exist.
+ *
+ * @since 3.15.0
+ */
+ boost::optional<bool> insertFinalNewline;
+
+ /**
+ * Trim all newlines after the final newline at the end of the file.
+ *
+ * @since 3.15.0
+ */
+ boost::optional<bool> trimFinalNewlines;
+ boost::optional<KeyData> key;
+ MAKE_SWAP_METHOD(lsFormattingOptions, tabSize, insertSpaces, trimTrailingWhitespace, insertFinalNewline, trimFinalNewlines, key)
+};
+MAKE_REFLECT_STRUCT(lsFormattingOptions, tabSize, insertSpaces, trimTrailingWhitespace, insertFinalNewline, trimFinalNewlines, key);
+
+extern void Reflect(Reader& visitor, lsFormattingOptions::KeyData& value);
+extern void Reflect(Writer& visitor, lsFormattingOptions::KeyData& value); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsMarkedString.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsMarkedString.h
new file mode 100644
index 0000000000..9191aa66d1
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsMarkedString.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+
+#include <string>
+#include <vector>
+
+
+// MarkedString can be used to render human readable text. It is either a
+// markdown string or a code-block that provides a language and a code snippet.
+// The language identifier is sematically equal to the optional language
+// identifier in fenced code blocks in GitHub issues. See
+// https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
+//
+// The pair of a language and a value is an equivalent to markdown:
+// ```${language}
+// ${value}
+// ```
+//
+// Note that markdown strings will be sanitized - that means html will be
+// escaped.
+struct lsMarkedString {
+ boost::optional<std::string> language;
+ std::string value;
+};
+
+struct MarkupContent {
+ /**
+ * The type of the Markup.
+ */
+
+ std::string kind;
+
+ /**
+ * The content itself.
+ */
+
+ std::string value;
+
+ MAKE_SWAP_METHOD(MarkupContent, kind, value);
+};
+MAKE_REFLECT_STRUCT(MarkupContent,kind,value);
+
+void Reflect(Writer& visitor, lsMarkedString& value);
+void Reflect(Reader& visitor, lsMarkedString& value);
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsPosition.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsPosition.h
new file mode 100644
index 0000000000..8c2106e16e
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsPosition.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+
+
+
+#include <string>
+#include <vector>
+
+//Position in a text document expressed as zero - based line and zero - based character offset.
+//A position is between two characters like an insert cursor in a editor.Special values like
+//for example - 1 to denote the end of a line are not supported.
+struct lsPosition {
+ lsPosition();
+ lsPosition(int line, int character);
+
+ bool operator==(const lsPosition& other) const;
+ bool operator<(const lsPosition& other) const;
+
+ std::string ToString() const;
+
+ /**
+ * Line position in a document (zero-based).
+ */
+ // Note: these are 0-based.
+ unsigned line = 0;
+ /**
+ * Character offset on a line in a document (zero-based). Assuming that
+ * the line is represented as a string, the `character` value represents
+ * the gap between the `character` and `character + 1`.
+ *
+ * If the character value is greater than the line length it defaults back
+ * to the line length.
+ */
+ unsigned character = 0;
+ static const lsPosition kZeroPosition;
+
+ MAKE_SWAP_METHOD(lsPosition, line, character)
+};
+MAKE_REFLECT_STRUCT(lsPosition, line, character); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsRange.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsRange.h
new file mode 100644
index 0000000000..6cc01e37a7
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsRange.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+
+
+
+#include <string>
+#include <vector>
+#include "lsPosition.h"
+//A range in a text document expressed as(zero - based) startand end positions.
+//A range is comparable to a selection in an editor.Therefore the end position is exclusive.
+//If you want to specify a range that contains a line including the line ending character(s)
+//then use an end position denoting the start of the next line.
+struct lsRange {
+ lsRange();
+ lsRange(lsPosition start, lsPosition end);
+
+ bool operator==(const lsRange& other) const;
+ bool operator<(const lsRange& other) const;
+ /**
+ * The range's start position.
+ */
+ lsPosition start;
+ /**
+ * The range's end position.
+ */
+ lsPosition end;
+ std::string ToString()const;
+ MAKE_SWAP_METHOD(lsRange, start, end)
+};
+
+MAKE_REFLECT_STRUCT(lsRange, start, end) \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsResponseError.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsResponseError.h
new file mode 100644
index 0000000000..6146d6188f
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsResponseError.h
@@ -0,0 +1,117 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+#include <sstream>
+#include "LibLsp/lsp/lsAny.h"
+
+enum class lsErrorCodes:int32_t {
+ // Defined by JSON RPC
+ ParseError = -32700,
+ InvalidRequest = -32600,
+ MethodNotFound = -32601,
+ InvalidParams = -32602,
+ InternalError = -32603,
+
+ /**
+ * This is the start range of JSON RPC reserved error codes.
+ * It doesn't denote a real error code. No LSP error codes should
+ * be defined between the start and end range. For backwards
+ * compatibility the `ServerNotInitialized` and the `UnknownErrorCode`
+ * are left in the range.
+ *
+ * @since 3.16.0
+ */
+ jsonrpcReservedErrorRangeStart = -32099,
+ /** @deprecated use jsonrpcReservedErrorRangeStart */
+ serverErrorStart = jsonrpcReservedErrorRangeStart,
+
+ /**
+ * This is the start range of JSON RPC reserved error codes.
+ * It doesn't denote a real error code.
+ *
+ * @since 3.16.0
+ */
+ jsonrpcReservedErrorRangeEnd = -32000,
+ /** @deprecated use jsonrpcReservedErrorRangeEnd */
+ serverErrorEnd = jsonrpcReservedErrorRangeEnd,
+
+ /**
+ * Error code indicating that a server received a notification or
+ * request before the server has received the `initialize` request.
+ */
+ ServerNotInitialized = -32002,
+ UnknownErrorCode = -32001,
+
+ /**
+ * This is the start range of LSP reserved error codes.
+ * It doesn't denote a real error code.
+ *
+ * @since 3.16.0
+ */
+ lspReservedErrorRangeStart= -32899,
+
+ /**
+ * The server cancelled the request. This error code should
+ * only be used for requests that explicitly support being
+ * server cancellable.
+ *
+ * @since 3.17.0
+ */
+ ServerCancelled = -32802,
+
+ /**
+ * The server detected that the content of a document got
+ * modified outside normal conditions. A server should
+ * NOT send this error code if it detects a content change
+ * in it unprocessed messages. The result even computed
+ * on an older state might still be useful for the client.
+ *
+ * If a client decides that a result is not of any use anymore
+ * the client should cancel the request.
+ */
+ ContentModified = -32801,
+
+ /**
+ * The client has canceled a request and a server as detected
+ * the cancel.
+ */
+ RequestCancelled = -32800,
+
+ /**
+ * This is the end range of LSP reserved error codes.
+ * It doesn't denote a real error code.
+ *
+ * @since 3.16.0
+ */
+ lspReservedErrorRangeEnd = -32800,
+
+
+
+};
+MAKE_REFLECT_TYPE_PROXY(lsErrorCodes);
+struct lsResponseError {
+ lsResponseError(): code(lsErrorCodes::UnknownErrorCode)
+ {
+ }
+
+ /**
+ * A number indicating the error type that occurred.
+ */
+ lsErrorCodes code;
+ // Short description.
+ /**
+ * A string providing a short description of the error.
+ */
+ std::string message;
+
+ /**
+ * A primitive or structured value that contains additional
+ * information about the error. Can be omitted.
+ */
+ boost::optional<lsp::Any> data;
+ std::string ToString();
+ void Write(Writer& visitor);
+
+ MAKE_SWAP_METHOD(lsResponseError, code, message, data)
+};
+MAKE_REFLECT_STRUCT(lsResponseError, code, message, data) \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentEdit.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentEdit.h
new file mode 100644
index 0000000000..0bab8bc3d8
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentEdit.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+#include <vector>
+#include "LibLsp/JsonRpc/message.h"
+#include "lsVersionedTextDocumentIdentifier.h"
+#include "lsTextEdit.h"
+
+
+struct lsTextDocumentEdit {
+ // The text document to change.
+ lsVersionedTextDocumentIdentifier textDocument;
+
+ /**
+ * The edits to be applied.
+ *
+ * @since 3.16.0 - support for AnnotatedTextEdit. This is guarded by the
+ * client capability `workspace.workspaceEdit.changeAnnotationSupport`
+ */
+ // The edits to be applied.
+ std::vector< lsAnnotatedTextEdit > edits;
+ MAKE_SWAP_METHOD(lsTextDocumentEdit, textDocument, edits);
+};
+MAKE_REFLECT_STRUCT(lsTextDocumentEdit, textDocument, edits); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentIdentifier.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentIdentifier.h
new file mode 100644
index 0000000000..bb316eae5a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentIdentifier.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+#include "lsDocumentUri.h"
+//Text documents are identified using a URI.On the protocol level,
+//URIs are passed as strings.The corresponding JSON structure looks like this:
+struct lsTextDocumentIdentifier {
+ /**
+ * The text document's URI.
+ */
+ lsDocumentUri uri;
+ MAKE_SWAP_METHOD(lsTextDocumentIdentifier, uri)
+};
+MAKE_REFLECT_STRUCT(lsTextDocumentIdentifier, uri) \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentItem.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentItem.h
new file mode 100644
index 0000000000..4d9b4ccc9f
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentItem.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+#include <string>
+#include <vector>
+#include "lsDocumentUri.h"
+
+//An item to transfer a text document from the client to the server.
+struct lsTextDocumentItem {
+ // The text document's URI.
+ lsDocumentUri uri;
+
+ // The text document's language identifier.
+ std::string languageId;
+
+ // The version number of this document (it will strictly increase after each
+ // change, including undo/redo).
+ int version = 0;
+
+ // The content of the opened text document.
+ std::string text;
+
+ MAKE_SWAP_METHOD(lsTextDocumentItem, uri, languageId, version, text)
+};
+
+MAKE_REFLECT_STRUCT(lsTextDocumentItem, uri, languageId, version, text) \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentPositionParams.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentPositionParams.h
new file mode 100644
index 0000000000..52d291351e
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextDocumentPositionParams.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/message.h"
+
+#include "lsTextDocumentIdentifier.h"
+#include "lsPosition.h"
+
+/**
+ * A parameter literal used in requests to pass a text document and a position inside that document.
+ */
+struct lsTextDocumentPositionParams {
+ // The text document.
+ lsTextDocumentIdentifier textDocument;
+
+ // The position inside the text document.
+ lsPosition position;
+
+ /**
+ * Legacy property to support protocol version 1.0 requests.
+ */
+ boost::optional<lsDocumentUri> uri;
+
+ MAKE_SWAP_METHOD(lsTextDocumentPositionParams, textDocument, position, uri);
+
+};
+MAKE_REFLECT_STRUCT(lsTextDocumentPositionParams, textDocument, position, uri);
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextEdit.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextEdit.h
new file mode 100644
index 0000000000..8785e0dcbc
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsTextEdit.h
@@ -0,0 +1,87 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+
+
+
+#include <string>
+#include "lsRange.h"
+
+
+//Since 3.16.0 there is also the concept of an annotated text edit which supports to add an annotation to a text edit.
+//The annotation can add information describing the change to the text edit.
+/**
+ * Additional information that describes document changes.
+ *
+ * @since 3.16.0
+ */
+struct lsChangeAnnotation
+{
+ /**
+ * A human-readable string describing the actual change. The string
+ * is rendered prominent in the user interface.
+ */
+ std::string label;
+
+ /**
+ * A flag which indicates that user confirmation is needed
+ * before applying the change.
+ */
+ boost::optional<bool> needsConfirmation;
+
+ /**
+ * A human-readable string which is rendered less prominent in
+ * the user interface.
+ */
+ boost::optional < std::string > description;
+ MAKE_REFLECT_STRUCT(lsChangeAnnotation, label, needsConfirmation, description)
+};
+MAKE_REFLECT_STRUCT(lsChangeAnnotation, label, needsConfirmation, description)
+
+
+//Usually clients provide options to group the changes along the annotations they are associated with.
+//To support this in the protocol an edit or resource operation refers to a change annotation
+//using an identifier and not the change annotation literal directly.This allows servers to use
+//the identical annotation across multiple edits or resource operations which then allows clients
+//to group the operations under that change annotation.The actual change annotations together with
+//their identifers are managed by the workspace edit via the new property changeAnnotations.
+
+
+
+/**
+ * An identifier referring to a change annotation managed by a workspace
+ * edit.
+ *
+ * @since 3.16.0.
+ */
+using lsChangeAnnotationIdentifier = std::string;
+/**
+ * A special text edit with an additional change annotation.
+ *
+ * @since 3.16.0.
+ */
+
+
+//A textual edit applicable to a text document.
+struct lsTextEdit {
+ // The range of the text document to be manipulated. To insert
+ // text into a document create a range where start === end.
+ lsRange range;
+
+ // The string to be inserted. For delete operations use an
+ // empty string.
+ std::string newText;
+
+ /**
+ * The actual annotation identifier.
+ */
+ boost::optional<lsChangeAnnotationIdentifier> annotationId;
+
+
+ bool operator==(const lsTextEdit& that);
+ std::string ToString() const;
+ MAKE_SWAP_METHOD(lsTextEdit, range, newText, annotationId)
+};
+MAKE_REFLECT_STRUCT(lsTextEdit, range, newText, annotationId)
+
+using lsAnnotatedTextEdit = lsTextEdit;
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsVersionedTextDocumentIdentifier.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsVersionedTextDocumentIdentifier.h
new file mode 100644
index 0000000000..8a858053b1
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsVersionedTextDocumentIdentifier.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+
+#include "LibLsp/JsonRpc/message.h"
+#include "LibLsp/lsp/lsDocumentUri.h"
+#include "LibLsp/lsp/lsTextDocumentIdentifier.h"
+
+struct lsVersionedTextDocumentIdentifier
+{
+ lsDocumentUri uri;
+ // The version number of this document. number | null
+ boost::optional<int> version;
+
+ lsTextDocumentIdentifier AsTextDocumentIdentifier() const;
+
+ MAKE_SWAP_METHOD(lsVersionedTextDocumentIdentifier, uri, version)
+};
+MAKE_REFLECT_STRUCT(lsVersionedTextDocumentIdentifier, uri, version)
+
+/**
+ * The version number of this document. If an optional versioned text document
+ * identifier is sent from the server to the client and the file is not
+ * open in the editor (the server has not received an open notification
+ * before) the server can send `null` to indicate that the version is
+ * known and the content on disk is the master (as specified with document
+ * content ownership).
+ *
+ * The version number of a document will increase after each change,
+ * including undo/redo. The number doesn't need to be consecutive.
+ */
+using lsOptionalVersionedTextDocumentIdentifier = lsVersionedTextDocumentIdentifier; \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsWorkspaceEdit.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsWorkspaceEdit.h
new file mode 100644
index 0000000000..c7fb73930a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsWorkspaceEdit.h
@@ -0,0 +1,57 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/serializer.h"
+#include <vector>
+#include "lsTextDocumentEdit.h"
+#include "LibLsp/lsp/ResourceOperation.h"
+#include "lsAny.h"
+
+//A workspace edit represents changes to many resources managed in the workspace.
+//The edit should either provide changes or documentChanges.
+//If the client can handle versioned document edits and if documentChanges are present, the latter are preferred over changes.
+
+//Since version 3.13.0 a workspace edit can contain resource operations(create, delete or rename files and folders) as well.
+//If resource operations are present clients need to execute the operations in the order in which they are provided.
+//So a workspace edit for example can consist of the following two changes : (1) create file a.txt and (2) a text document edit which insert text into file a.
+//txt.An invalid sequence(e.g. (1) delete file a.txt and (2) insert text into file a.txt) will cause failure of the operation.
+//How the client recovers from the failure is described by the client capability : workspace.workspaceEdit.failureHandling
+
+
+
+struct lsChangeAnnotations
+{
+ lsChangeAnnotation id;
+ MAKE_SWAP_METHOD(lsChangeAnnotations, id)
+};
+MAKE_REFLECT_STRUCT(lsChangeAnnotations, id)
+struct lsWorkspaceEdit {
+ // Holds changes to existing resources.
+ // changes ? : { [uri:string]: TextEdit[]; };
+ // std::unordered_map<lsDocumentUri, std::vector<lsTextEdit>> changes;
+
+ // An array of `TextDocumentEdit`s to express changes to specific a specific
+ // version of a text document. Whether a client supports versioned document
+ // edits is expressed via `WorkspaceClientCapabilites.versionedWorkspaceEdit`.
+ //
+ boost::optional< std::map<std::string, std::vector<lsTextEdit> > > changes;
+ typedef std::pair < boost::optional<lsTextDocumentEdit>, boost::optional<lsp::Any> > Either;
+
+ boost::optional < std::vector< Either > > documentChanges;
+ /**
+ * A map of change annotations that can be referenced in
+ * `AnnotatedTextEdit`s or create, rename and delete file / folder
+ * operations.
+ *
+ * Whether clients honor this property depends on the client capability
+ * `workspace.changeAnnotationSupport`.
+ *
+ * @since 3.16.0
+ */
+ boost::optional< lsChangeAnnotations > changeAnnotations;
+
+ MAKE_SWAP_METHOD(lsWorkspaceEdit, changes, documentChanges, changeAnnotations)
+};
+MAKE_REFLECT_STRUCT(lsWorkspaceEdit, changes, documentChanges, changeAnnotations)
+
+extern void Reflect(Reader& visitor, lsWorkspaceEdit::Either& value);
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsp.cpp b/graphics/asymptote/LspCpp/LibLsp/lsp/lsp.cpp
new file mode 100644
index 0000000000..81bf34ba3a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsp.cpp
@@ -0,0 +1,1087 @@
+
+
+#include "lru_cache.h"
+
+
+#include <rapidjson/writer.h>
+
+
+#include <stdio.h>
+#include <iostream>
+#include "location_type.h"
+#include "out_list.h"
+#include "lsTextDocumentIdentifier.h"
+#include "lsVersionedTextDocumentIdentifier.h"
+#include "lsResponseError.h"
+#include "lsPosition.h"
+#include "lsTextEdit.h"
+#include "lsMarkedString.h"
+#include "lsWorkspaceEdit.h"
+#include "textDocument/code_action.h"
+#include "textDocument/document_symbol.h"
+#include "extention/jdtls/codeActionResult.h"
+
+#include "textDocument/selectionRange.h"
+#include "AbsolutePath.h"
+
+#ifdef _WIN32
+#include <Windows.h>
+#else
+#include <climits>
+#include <cstdlib>
+#endif
+
+#include "Directory.h"
+#include "lsFormattingOptions.h"
+#include "LibLsp/JsonRpc/json.h"
+#include "language/language.h"
+#include "network/uri/uri_builder.hpp"
+#include "lsp_completion.h"
+#include "utils.h"
+#include "client/registerCapability.h"
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_io.hpp>
+#include <boost/uuid/uuid_generators.hpp>
+// namespace
+
+
+
+lsTextDocumentIdentifier
+lsVersionedTextDocumentIdentifier::AsTextDocumentIdentifier() const {
+ lsTextDocumentIdentifier result;
+ result.uri = uri;
+ return result;
+}
+
+
+lsPosition::lsPosition() {}
+lsPosition::lsPosition(int line, int character)
+ : line(line), character(character) {}
+
+bool lsPosition::operator==(const lsPosition& other) const {
+ return line == other.line && character == other.character;
+}
+
+bool lsPosition::operator<(const lsPosition& other) const {
+ return line != other.line ? line < other.line : character < other.character;
+}
+
+std::string lsPosition::ToString() const {
+ return std::to_string(line) + ":" + std::to_string(character);
+}
+const lsPosition lsPosition::kZeroPosition = lsPosition();
+
+lsRange::lsRange() {}
+lsRange::lsRange(lsPosition start, lsPosition end) : start(start), end(end) {}
+
+bool lsRange::operator==(const lsRange& o) const {
+ return start == o.start && end == o.end;
+}
+
+bool lsRange::operator<(const lsRange& o) const {
+ return !(start == o.start) ? start < o.start : end < o.end;
+}
+
+std::string lsRange::ToString() const
+{
+ std::stringstream ss;
+ ss << "start:" << start.ToString() << std::endl;
+ ss << "end" << end.ToString() << std::endl;
+ return ss.str();
+}
+
+lsLocation::lsLocation() {}
+lsLocation::lsLocation(lsDocumentUri uri, lsRange range)
+ : uri(uri), range(range) {}
+
+bool lsLocation::operator==(const lsLocation& o) const {
+ return uri == o.uri && range == o.range;
+}
+
+bool lsLocation::operator<(const lsLocation& o) const {
+ return std::make_tuple(uri.raw_uri_, range) <
+ std::make_tuple(o.uri.raw_uri_, o.range);
+}
+
+bool lsTextEdit::operator==(const lsTextEdit& that) {
+ return range == that.range && newText == that.newText;
+}
+
+std::string lsTextEdit::ToString() const
+{
+ std::stringstream ss;
+ ss << "Range:" << range.ToString() << std::endl;
+ ss << "newText:" << newText << std::endl;
+ return ss.str();
+}
+
+void Reflect(Writer& visitor, lsMarkedString& value) {
+ // If there is a language, emit a `{language:string, value:string}` object. If
+ // not, emit a string.
+ if (value.language) {
+ REFLECT_MEMBER_START();
+ REFLECT_MEMBER(language);
+ REFLECT_MEMBER(value);
+ REFLECT_MEMBER_END();
+ } else {
+ Reflect(visitor, value.value);
+ }
+}
+
+void Reflect(Reader& visitor, lsMarkedString& value)
+{
+ REFLECT_MEMBER_START();
+ REFLECT_MEMBER(language);
+ REFLECT_MEMBER(value);
+ REFLECT_MEMBER_END();
+}
+
+ void Reflect(Reader& visitor, LocationListEither::Either& value)
+{
+ if(!visitor.IsArray())
+ {
+ throw std::invalid_argument("Rsp_LocationListEither::Either& value is not array");
+ }
+ auto data = ((JsonReader&)visitor).m_->GetArray();
+ if (data.Size() && data[0].HasMember("originSelectionRange"))
+ {
+ Reflect(visitor, value.second);
+ }
+ else {
+ Reflect(visitor, value.first);
+ }
+
+}
+
+ void Reflect(Writer& visitor, LocationListEither::Either& value)
+{
+ if (value.first)
+ {
+ Reflect(visitor, value.first.value());
+ }
+ else if (value.second)
+ {
+ Reflect(visitor, value.second.value());
+ }
+}
+
+
+void Reflect(Reader& visitor, TextDocumentCodeAction::Either& value)
+{
+
+
+ if(visitor.HasMember("command"))
+ {
+ if(visitor["command"]->IsString())
+ {
+ Reflect(visitor, value.first);
+ }
+ else
+ {
+ Reflect(visitor, value.second);
+ }
+ }
+ else
+ {
+ if (visitor.HasMember("diagnostics") || visitor.HasMember("edit"))
+ {
+ Reflect(visitor, value.second);
+ }
+ else
+ {
+ Reflect(visitor, value.first);
+ }
+ }
+
+}
+
+
+void Reflect(Reader& visitor, lsWorkspaceEdit::Either& value)
+{
+
+
+ if(visitor.HasMember("textDocument"))
+ {
+ Reflect(visitor, value.first);
+ }
+ else
+ {
+ Reflect(visitor, value.second);
+ }
+}
+ResourceOperation* GetResourceOperation(lsp::Any& lspAny)
+{
+ rapidjson::Document document;
+ auto& data = lspAny.Data();
+ document.Parse(data.c_str(), data.length());
+ if (document.HasParseError()) {
+ // ��ʾ
+ return nullptr;
+ }
+ auto find = document.FindMember("kind");
+
+ JsonReader visitor{ &document };
+ try
+ {
+ if (find->value == "create")
+ {
+ auto ptr = std::make_unique<lsCreateFile>();
+ auto temp = ptr.get();
+ Reflect(visitor, *temp);
+ return ptr.release();
+ }
+ else if (find->value == "rename")
+ {
+ auto ptr = std::make_unique<lsRenameFile>();
+ auto temp = ptr.get();
+ Reflect(visitor, *temp);
+ return ptr.release();
+ }
+ else if (find->value == "delete")
+ {
+
+ auto ptr = std::make_unique<lsDeleteFile>();
+ auto temp = ptr.get();
+ Reflect(visitor, *temp);
+ return ptr.release();
+ }
+ }
+ catch (std::exception&)
+ {
+
+ }
+ return nullptr;
+}
+
+ void Reflect(Writer& visitor, ResourceOperation* value)
+{
+
+ if(!value)
+ {
+ throw std::invalid_argument("ResourceOperation value is nullptr");
+ }
+ if (value->kind == "create")
+ {
+ auto temp = (lsCreateFile*)value;
+ Reflect(visitor, *temp);
+ }
+ else if (value->kind == "rename")
+ {
+ auto temp = (lsRenameFile*)value;
+ Reflect(visitor, *temp);
+ }
+ else if (value->kind == "delete")
+ {
+
+ auto temp = (lsDeleteFile*)value;
+ Reflect(visitor, *temp);
+ }
+
+}
+
+int lsp::Any::GuessType()
+{
+ if (!data.empty())
+ {
+ if (data == "null")
+ {
+ jsonType = rapidjson::kNullType;
+ }
+ else if (data == "true")
+ {
+ jsonType = rapidjson::kTrueType;
+ }
+ else if(data == "false")
+ {
+ jsonType = rapidjson::kFalseType;
+ }
+ else if (data[0] == '{')
+ {
+ jsonType = rapidjson::kObjectType;
+ }
+ else if (data[0] == '[')
+ {
+ if (data.size() >= 2 && data[1] == '{')
+ jsonType = rapidjson::kStringType;
+ else
+ jsonType = rapidjson::kArrayType;
+ }
+ else if (data[0] == '"')
+ {
+ jsonType = rapidjson::kStringType;
+ }
+ else
+ {
+ jsonType = rapidjson::kNumberType;
+ }
+ }
+ else
+ {
+ if (jsonType != kUnKnown)
+ return jsonType;
+ jsonType = rapidjson::kNullType;
+ }
+ return jsonType;
+}
+
+int lsp::Any::GetType()
+{
+ if (jsonType == Type::kUnKnown)
+ {
+ if (data.empty())
+ {
+ jsonType = rapidjson::kNullType;
+ return jsonType;
+ }
+ rapidjson::Document document;
+ document.Parse(data.c_str(), data.length());
+ if (document.HasParseError())
+ {
+ // ��ʾ
+ return jsonType;
+ }
+ jsonType = document.GetType();
+ }
+ return jsonType;
+}
+
+void lsp::Any::Set(std::unique_ptr<LspMessage> value)
+{
+ if (value)
+ {
+ jsonType = rapidjson::Type::kObjectType;
+ data = value->ToJson();
+ }
+ else
+ {
+ assert(false);
+ }
+}
+
+void lsp::Any::SetJsonString(std::string&& _data, Type _type)
+{
+ jsonType = _type;
+ data.swap(_data);
+ GetType();
+}
+
+void lsp::Any::SetJsonString(const std::string& _data, Type _type)
+{
+ jsonType = _type;
+ data = (_data);
+ GetType();
+}
+
+void lsp::Any::swap(Any& arg) noexcept
+{
+ data.swap(arg.data);
+ const int temp = jsonType;
+ jsonType = arg.jsonType;
+ arg.jsonType = temp;
+}
+
+class JsonReaderForAny : public JsonReader
+{
+public:
+ JsonReaderForAny()
+ : JsonReader(&document)
+ {
+ }
+ rapidjson::Document document;
+};
+
+bool lsp::Any::GetForMapHelper(std::string& value)
+{
+ return Get(value);
+}
+
+bool lsp::Any::GetForMapHelper(boost::optional<std::string>& value)
+{
+ return Get(value);
+}
+
+std::unique_ptr<Reader> lsp::Any::GetReader()
+{
+ auto reader = new JsonReaderForAny();
+ std::unique_ptr<Reader> ret(reader);
+ reader->document.Parse(data.c_str(), data.length());
+ if (reader->document.HasParseError())
+ {
+ return {};
+ }
+ if (jsonType == kUnKnown)
+ {
+ jsonType = reader->document.GetType();
+ }
+ return (ret);
+}
+
+class JsonWriterForAny : public JsonWriter
+{
+public:
+ rapidjson::StringBuffer output;
+ rapidjson::Writer<rapidjson::StringBuffer> writer;
+ JsonWriterForAny():JsonWriter(&writer), writer(output)
+ {
+
+ }
+};
+
+std::unique_ptr<Writer> lsp::Any::GetWriter() const
+{
+ return std::make_unique<JsonWriterForAny>();
+}
+
+void lsp::Any::SetData(std::unique_ptr<Writer>& writer)
+{
+ auto _temp = static_cast<JsonWriterForAny*>(writer.get());
+ data = _temp->output.GetString();
+ GuessType();
+}
+
+namespace
+{
+#if 0
+ rapidjson::Type convert(lsp::Any::Type type)
+ {
+ switch (type)
+ {
+ case lsp::Any::Type::kNullType:
+ return rapidjson::Type::kNullType;
+ case lsp::Any::Type::kFalseType:
+ return rapidjson::Type::kFalseType;
+ case lsp::Any::Type::kTrueType:
+ return rapidjson::Type::kTrueType;
+ case lsp::Any::Type::kObjectType:
+ return rapidjson::Type::kObjectType;
+ case lsp::Any::Type::kArrayType:
+ return rapidjson::Type::kArrayType;
+ case lsp::Any::Type::kStringType:
+ return rapidjson::Type::kStringType;
+ case lsp::Any::Type::kNumberType:
+ return rapidjson::Type::kNumberType;
+ default:
+ return rapidjson::Type::kNullType;
+ }
+ }
+#endif
+ lsp::Any::Type convert(rapidjson::Type type)
+ {
+ switch (type)
+ {
+ case rapidjson::Type::kNullType:
+ return lsp::Any::Type::kNullType;
+ case rapidjson::Type::kFalseType:
+ return lsp::Any::Type::kFalseType;
+ case rapidjson::Type::kTrueType:
+ return lsp::Any::Type::kTrueType;
+ case rapidjson::Type::kObjectType:
+ return lsp::Any::Type::kObjectType;
+ case rapidjson::Type::kArrayType:
+ return lsp::Any::Type::kArrayType;
+ case rapidjson::Type::kStringType:
+ return lsp::Any::Type::kStringType;
+ case rapidjson::Type::kNumberType:
+ return lsp::Any::Type::kNumberType;
+ default:
+ return lsp::Any::Type::kNullType;
+ }
+ }
+}
+
+void Reflect(Reader& visitor, lsp::Any& value)
+{
+
+ //if (visitor.IsNull()) {
+ // visitor.GetNull();
+ // value.SetJsonString("", rapidjson::Type::kNullType);
+ // return;
+ //}else
+ //{
+ //
+ //}
+ JsonReader& json_reader = reinterpret_cast<JsonReader&>(visitor);
+ value.SetJsonString(visitor.ToString(), convert(json_reader.m_->GetType()));
+}
+ void Reflect(Writer& visitor, lsp::Any& value)
+ {
+ JsonWriter& json_writer = reinterpret_cast<JsonWriter&>(visitor);
+ json_writer.m_->RawValue( value.Data().data(),value.Data().size(),static_cast<rapidjson::Type>(value.GetType()));
+
+ }
+ void Reflect(Reader& visitor, lsFormattingOptions::KeyData& value)
+{
+ if (visitor.IsBool())
+ {
+ Reflect(visitor, value._boolean);
+ }
+ else if (visitor.IsInt() || visitor.IsInt64() || visitor.IsUint64())
+ {
+ Reflect(visitor, value._integer);
+ }
+ else if(visitor.IsString())
+ {
+ Reflect(visitor, value._string);
+ }
+}
+ void Reflect(Writer& visitor, lsFormattingOptions::KeyData& value)
+{
+ if (value._boolean.has_value())
+ {
+ Reflect(visitor, value._boolean);
+ }
+ else if (value._integer.has_value())
+ {
+ Reflect(visitor, value._integer);
+ }
+ else if (value._string.has_value())
+ {
+ Reflect(visitor, value._string);
+ }
+}
+
+lsCreateFile::lsCreateFile()
+{
+ kind = "create";
+}
+
+lsDeleteFile::lsDeleteFile()
+{
+ kind = "delete";
+}
+
+lsRenameFile::lsRenameFile()
+{
+ kind = "rename";
+}
+
+
+void Reflect(Reader& visitor, boost::optional< SelectionRange* >& value)
+{
+ if (visitor.IsNull()) {
+ visitor.GetNull();
+ return;
+ }
+
+ SelectionRange* entry_value = nullptr;
+
+
+ std::unique_ptr<SelectionRange> ptr = std::make_unique<SelectionRange>();
+ SelectionRange* temp = ptr.get();
+ Reflect(visitor, *temp);
+
+ entry_value = ptr.release();
+ value = (entry_value);
+
+}
+void Reflect(Writer& visitor, SelectionRange* value)
+{
+
+ if (!value)
+ {
+ throw std::invalid_argument("ResourceOperation value is nullptr");
+ }
+
+ Reflect(visitor, *value);
+
+
+}
+
+ std::string make_file_scheme_uri(const std::string& absolute_path)
+{
+ network::uri_builder builder;
+ builder.scheme("file");
+ builder.host("");
+ builder.path(absolute_path);
+ return builder.uri().string();
+ //// lsDocumentUri uri;
+ //// uri.SetPath(absolute_path);
+ /// return uri.raw_uri_;
+}
+
+// static
+AbsolutePath AbsolutePath::BuildDoNotUse(const std::string& path) {
+ AbsolutePath p;
+ p.path = std::string(path);
+ return p;
+}
+
+
+AbsolutePath::AbsolutePath() {}
+
+
+
+AbsolutePath::operator std::string() const {
+ return path;
+}
+
+bool AbsolutePath::operator==(const AbsolutePath& rhs) const {
+ return path == rhs.path;
+}
+
+bool AbsolutePath::operator!=(const AbsolutePath& rhs) const {
+ return path != rhs.path;
+}
+
+bool AbsolutePath::operator<(const AbsolutePath& rhs) const
+{
+ return path < rhs.path;
+}
+
+bool AbsolutePath::operator>(const AbsolutePath& rhs) const
+{
+ return path > rhs.path;
+}
+
+void Reflect(Reader& visitor, AbsolutePath& value) {
+ value.path = visitor.GetString();
+}
+void Reflect(Writer& visitor, AbsolutePath& value) {
+ visitor.String(value.path.c_str(), value.path.length());
+}
+
+std::ostream& operator<<(std::ostream& out, const AbsolutePath& path) {
+ out << path.path;
+ return out;
+}
+
+lsDocumentUri lsDocumentUri::FromPath(const AbsolutePath& path) {
+ lsDocumentUri result;
+ result.SetPath(path);
+ return result;
+}
+//void lsDocumentUri::SetPath(const AbsolutePath& path)
+//{
+// raw_uri_ = make_file_scheme_uri(path.path);
+//}
+//
+void lsDocumentUri::SetPath(const AbsolutePath& path) {
+ // file:///c%3A/Users/jacob/Desktop/superindex/indexer/full_tests
+ raw_uri_ = path;
+
+ size_t index = raw_uri_.find(":");
+ if (index == 1) { // widows drive letters must always be 1 char
+ raw_uri_.replace(raw_uri_.begin() + index, raw_uri_.begin() + index + 1,
+ "%3A");
+ }
+
+ // subset of reserved characters from the URI standard
+ // http://www.ecma-international.org/ecma-262/6.0/#sec-uri-syntax-and-semantics
+ std::string t;
+ t.reserve(8 + raw_uri_.size());
+
+ // TODO: proper fix
+#if defined(_WIN32)
+ t += "file:///";
+#else
+ t += "file://";
+#endif
+
+ // clang-format off
+ for (char c : raw_uri_)
+ switch (c) {
+ case ' ': t += "%20"; break;
+ case '#': t += "%23"; break;
+ case '$': t += "%24"; break;
+ case '&': t += "%26"; break;
+ case '(': t += "%28"; break;
+ case ')': t += "%29"; break;
+ case '+': t += "%2B"; break;
+ case ',': t += "%2C"; break;
+ case ';': t += "%3B"; break;
+ case '?': t += "%3F"; break;
+ case '@': t += "%40"; break;
+ default: t += c; break;
+ }
+ // clang-format on
+ raw_uri_ = std::move(t);
+}
+
+std::string lsDocumentUri::GetRawPath() const {
+
+
+ if (raw_uri_.compare(0, 8, "file:///"))
+ return raw_uri_;
+
+
+ std::string ret;
+#if defined(_WIN32)
+ size_t i = 8;
+#else
+ size_t i = 7;
+#endif
+ auto from_hex = [](unsigned char c) {
+ return c - '0' < 10 ? c - '0' : (c | 32) - 'a' + 10;
+ };
+ for (; i < raw_uri_.size(); i++) {
+ if (i + 3 <= raw_uri_.size() && raw_uri_[i] == '%') {
+ ret.push_back(from_hex(raw_uri_[i + 1]) * 16 + from_hex(raw_uri_[i + 2]));
+ i += 2;
+ }
+ else
+ ret.push_back(raw_uri_[i] == '\\' ? '/' : raw_uri_[i]);
+ }
+ return ret;
+}
+
+lsDocumentUri::lsDocumentUri() {}
+
+
+lsDocumentUri::lsDocumentUri(const AbsolutePath& path)
+{
+ SetPath(path);
+}
+
+lsDocumentUri::lsDocumentUri(const lsDocumentUri& other): raw_uri_(other.raw_uri_)
+{
+}
+
+bool lsDocumentUri::operator==(const lsDocumentUri& other) const {
+ return raw_uri_ == other.raw_uri_;
+}
+
+bool lsDocumentUri::operator==(const std::string& other) const
+{
+ return raw_uri_ == other;
+}
+
+
+AbsolutePath lsDocumentUri::GetAbsolutePath() const {
+
+
+ if (raw_uri_.find("file://") != std::string::npos){
+ try
+ {
+ return lsp::NormalizePath(GetRawPath(), false /*ensure_exists*/, false);
+ }
+ catch (std::exception&)
+ {
+ return AbsolutePath("", false);
+ }
+ }
+
+ return AbsolutePath(raw_uri_,false);
+
+}
+
+AbsolutePath::AbsolutePath(const std::string& path, bool validate)
+ : path(path) {
+ // TODO: enable validation after fixing tests.
+ if (validate && !lsp::IsAbsolutePath(path)) {
+ qualify = false;
+ auto temp = lsp::NormalizePath(path,false);
+ if(!temp.path.empty())
+ {
+ this->path = temp.path;
+ }
+ }
+}
+
+void Reflect(Writer& visitor, lsDocumentUri& value) {
+ Reflect(visitor, value.raw_uri_);
+}
+void Reflect(Reader& visitor, lsDocumentUri& value) {
+ Reflect(visitor, value.raw_uri_);
+ // Only record the path when we deserialize a URI, since it most likely came
+ // from the client.
+
+}
+
+ std::string ProgressReport::ToString() const
+{
+ std::string info;
+ info += "id:" + id + "\n";
+ info += "task:" + task + "\n";
+ info += "subTask:" + subTask + "\n";
+ info += "status:" + status + "\n";
+ {
+ std::stringstream ss;
+ ss << "totalWork:" << totalWork << std::endl;
+ info += ss.str();
+ }
+ {
+ std::stringstream ss;
+ ss << "workDone:" << workDone << std::endl;
+ info += ss.str();
+ }
+
+ {
+ std::stringstream ss;
+ ss << "complete:" << complete << std::endl;
+ info += ss.str();
+ }
+
+ return info;
+}
+
+std::string EventNotification::ToString() const
+{
+ std::string info;
+ if (ClasspathUpdated == eventType)
+ {
+ info += "eventType:ClasspathUpdated\n";
+ }
+ else if (ProjectsImported == eventType)
+ {
+ info += "eventType:ProjectsImported\n";
+ }
+ else
+ {
+ std::ostringstream oss;
+ oss << std::hex << eventType << std::endl;
+
+ info += "eventType:";
+ info += oss.str();
+ }
+ info += "data:" + data.Data() + "\n";
+ return info;
+}
+
+std::string lsp::ToString(lsCompletionItemKind _kind)
+{
+ switch (_kind) {
+ case lsCompletionItemKind::Text:
+ return "Text";
+ case lsCompletionItemKind::Method:
+ return "Method";
+ case lsCompletionItemKind::Function:
+ return "";
+ case lsCompletionItemKind::Constructor:
+ return "Function";
+ case lsCompletionItemKind::Field:
+ return "Field";
+ case lsCompletionItemKind::Variable:
+ return "";
+ case lsCompletionItemKind::Class:
+ return "Variable";
+ case lsCompletionItemKind::Interface:
+ return "Interface";
+ case lsCompletionItemKind::Module:
+ return "Module";
+ case lsCompletionItemKind::Property:
+ return "Property";
+ case lsCompletionItemKind::Unit:
+ return "Unit";
+ case lsCompletionItemKind::Value:
+ return "Value";
+ case lsCompletionItemKind::Enum:
+ return "Enum";
+ case lsCompletionItemKind::Keyword:
+ return "Keyword";
+ case lsCompletionItemKind::Snippet:
+ return "Snippet";
+ case lsCompletionItemKind::Color:
+ return "Color";
+ case lsCompletionItemKind::File:
+ return "File";
+ case lsCompletionItemKind::Reference:
+ return "Reference";
+ case lsCompletionItemKind::Folder:
+ return "Folder";
+ case lsCompletionItemKind::EnumMember:
+ return "EnumMember";
+ case lsCompletionItemKind::Constant:
+ return "Constant";
+ case lsCompletionItemKind::Struct:
+ return "Struct";
+ case lsCompletionItemKind::Event:
+ return "Event";
+ case lsCompletionItemKind::Operator:
+ return "Operator";
+ case lsCompletionItemKind::TypeParameter:
+ return "TypeParameter";
+ default:
+ return "Unknown";
+ }
+}
+
+std::string lsp::ToString(lsInsertTextFormat _kind)
+{
+ if (_kind == lsInsertTextFormat::PlainText)
+ {
+ return "PlainText";
+ }
+ else if (_kind == lsInsertTextFormat::Snippet)
+ {
+ return "Snippet";
+ }else
+ {
+ return "Unknown";
+ }
+}
+
+const std::string& lsCompletionItem::InsertedContent() const
+{
+ if (textEdit)
+ return textEdit->newText;
+ if (insertText.has_value() && !insertText->empty())
+ return insertText.value();
+ return label;
+}
+
+std::string lsCompletionItem::DisplayText()
+{
+
+ if (detail)
+ {
+
+ return label + " in " + detail.value();
+ }
+ return label;
+}
+
+std::string lsCompletionItem::ToString()
+ {
+ std::stringstream info;
+ info << "label : " << label << std::endl;
+ if(kind)
+ info << "kind : " << lsp::ToString(kind.value()) << std::endl;
+ else
+ info << "kind : no exist." << std::endl;
+
+ if (detail)
+ info << "detail : " << detail.value() << std::endl;
+ else
+ info << "detail : no exist." << std::endl;
+
+ if (documentation)
+ {
+ info << "documentation : " << std::endl;
+ if(documentation.value().first)
+ {
+ info << documentation.value().first.value();
+ }
+ else if(documentation.value().second)
+ {
+ info << documentation.value().second.value().value;
+ }
+ }
+ else
+ info << "documentation : no exist." << std::endl;
+
+ if (deprecated)
+ info << "deprecated : " << deprecated.value() << std::endl;
+ else
+ info << "deprecated : no exist." << std::endl;
+
+ if (preselect)
+ info << "preselect : " << preselect.value() << std::endl;
+ else
+ info << "preselect : no exist." << std::endl;
+
+ if (sortText)
+ info << "sortText : " << sortText.value() << std::endl;
+ else
+ info << "sortText : no exist." << std::endl;
+
+ if (filterText)
+ info << "filterText : " << filterText.value() << std::endl;
+ else
+ info << "filterText : no exist." << std::endl;
+
+
+ if (insertText)
+ info << "insertText : " << insertText.value() << std::endl;
+ else
+ info << "insertText : no exist." << std::endl;
+
+
+ if (insertTextFormat)
+ info << "insertText : " << lsp::ToString(insertTextFormat.value()) << std::endl;
+ else
+ info << "insertTextFormat : no exist." << std::endl;
+
+ if (textEdit)
+ info << "textEdit : " << textEdit.value().ToString() << std::endl;
+ else
+ info << "textEdit : no exist." << std::endl;
+
+
+
+ return info.str();
+
+ }
+namespace JDT
+{
+ namespace CodeActionKind {
+
+
+ /**
+ * Base kind for quickfix actions: 'quickfix'
+ */
+ const char* QuickFix = "quickfix";
+
+ /**
+ * Base kind for refactoring actions: 'refactor'
+ */
+ const char* Refactor = "refactor";
+
+ /**
+ * Base kind for refactoring extraction actions: 'refactor.extract'
+ *
+ * Example extract actions:
+ *
+ * - Extract method - Extract function - Extract variable - Extract interface
+ * from class - ...
+ */
+ const char* RefactorExtract = "refactor.extract";
+
+ /**
+ * Base kind for refactoring inline actions: 'refactor.inline'
+ *
+ * Example inline actions:
+ *
+ * - Inline function - Inline variable - Inline constant - ...
+ */
+ const char* RefactorInline = "refactor.inline";
+
+ /**
+ * Base kind for refactoring rewrite actions: 'refactor.rewrite'
+ *
+ * Example rewrite actions:
+ *
+ * - Convert JavaScript function to class - Add or remove parameter -
+ * Encapsulate field - Make method static - Move method to base class - ...
+ */
+ const char* RefactorRewrite = "refactor.rewrite";
+
+ /**
+ * Base kind for source actions: `source`
+ *
+ * Source code actions apply to the entire file.
+ */
+ const char* Source = "source";
+
+ /**
+ * Base kind for an organize imports source action: `source.organizeImports`
+ */
+ const char* SourceOrganizeImports = "source.organizeImports";
+
+ const char* COMMAND_ID_APPLY_EDIT = "java.apply.workspaceEdit";
+
+ };
+
+
+}
+Directory::Directory(const AbsolutePath& path) : path(path.path) {
+ lsp::EnsureEndsInSlash(this->path);
+}
+
+bool Directory::operator==(const Directory& rhs) const {
+ return path == rhs.path;
+}
+
+bool Directory::operator!=(const Directory& rhs) const {
+ return path != rhs.path;
+}
+
+
+
+ Registration Registration::Create(const std::string& method)
+{
+ Registration reg;
+ reg.method = method;
+ const boost::uuids::uuid a_uuid = boost::uuids::random_generator()();
+ reg.id = to_string(a_uuid);
+ return reg;
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsp_code_action.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsp_code_action.h
new file mode 100644
index 0000000000..37acc6ca61
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsp_code_action.h
@@ -0,0 +1,64 @@
+#pragma once
+
+
+#include "location_type.h"
+#include "lsDocumentUri.h"
+#include "lsTextEdit.h"
+#include "lsPosition.h"
+
+// codeAction
+struct CommandArgs {
+ lsDocumentUri textDocumentUri;
+ std::vector<lsTextEdit> edits;
+};
+MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(CommandArgs, textDocumentUri, edits);
+inline void Reflect(Reader& visitor, CommandArgs& value) {
+ int i = 0;
+ visitor.IterArray([&](Reader& visitor) {
+ switch (i++) {
+ case 0:
+ Reflect(visitor, value.textDocumentUri);
+ break;
+ case 1:
+ Reflect(visitor, value.edits);
+ break;
+
+ }
+ });
+}
+
+// codeLens
+struct lsCodeLensUserData {};
+MAKE_REFLECT_EMPTY_STRUCT(lsCodeLensUserData);
+
+struct lsCodeLensCommandArguments {
+ lsDocumentUri uri;
+ lsPosition position;
+ std::vector<lsLocation> locations;
+};
+
+// FIXME Don't use array in vscode-cquery
+inline void Reflect(Writer& visitor, lsCodeLensCommandArguments& value) {
+ visitor.StartArray(3);
+ Reflect(visitor, value.uri);
+ Reflect(visitor, value.position);
+ Reflect(visitor, value.locations);
+ visitor.EndArray();
+}
+
+inline void Reflect(Reader& visitor, lsCodeLensCommandArguments& value) {
+ int i = 0;
+ visitor.IterArray([&](Reader& visitor) {
+ switch (i++) {
+ case 0:
+ Reflect(visitor, value.uri);
+ break;
+ case 1:
+ Reflect(visitor, value.position);
+ break;
+ case 2:
+ Reflect(visitor, value.locations);
+ break;
+ }
+ });
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsp_completion.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsp_completion.h
new file mode 100644
index 0000000000..250699a44a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsp_completion.h
@@ -0,0 +1,224 @@
+#pragma once
+#include "lsTextEdit.h"
+#include "lsMarkedString.h"
+#include "lsCommand.h"
+
+
+// The kind of a completion entry.
+enum class lsCompletionItemKind {
+ Text = 1,
+ Method = 2,
+ Function = 3,
+ Constructor = 4,
+ Field = 5,
+ Variable = 6,
+ Class = 7,
+ Interface = 8,
+ Module = 9,
+ Property = 10,
+ Unit = 11,
+ Value = 12,
+ Enum = 13,
+ Keyword = 14,
+ Snippet = 15,
+ Color = 16,
+ File = 17,
+ Reference = 18,
+ Folder = 19,
+ EnumMember = 20,
+ Constant = 21,
+ Struct = 22,
+ Event = 23,
+ Operator = 24,
+ TypeParameter = 25,
+};
+MAKE_REFLECT_TYPE_PROXY(lsCompletionItemKind);
+
+
+
+// Defines whether the insert text in a completion item should be interpreted as
+// plain text or a snippet.
+enum class lsInsertTextFormat {
+ // The primary text to be inserted is treated as a plain string.
+ PlainText = 1,
+
+ // The primary text to be inserted is treated as a snippet.
+ //
+ // A snippet can define tab stops and placeholders with `$1`, `$2`
+ // and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+ // the end of the snippet. Placeholders with equal identifiers are linked,
+ // that is typing in one will update others too.
+ //
+ // See also:
+ // https://github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/snippet/common/snippet.md
+ Snippet = 2
+};
+MAKE_REFLECT_TYPE_PROXY(lsInsertTextFormat);
+
+namespace lsp
+{
+ std::string ToString(lsCompletionItemKind);
+ std::string ToString(lsInsertTextFormat);
+}
+/**
+ * The Completion request is sent from the client to the server to compute completion items at a given cursor position.
+ * Completion items are presented in the IntelliSense user class. If computing complete completion items is expensive
+ * servers can additional provide a handler for the resolve completion item request. This request is send when a
+ * completion item is selected in the user class.
+ */
+struct lsCompletionItem {
+
+ // The label of this completion item. By default
+ // also the text that is inserted when selecting
+ // this completion.
+ std::string label;
+
+ // The kind of this completion item. Based of the kind
+ // an icon is chosen by the editor.
+ boost::optional<lsCompletionItemKind> kind ;
+
+ // A human-readable string with additional information
+ // about this item, like type or symbol information.
+ boost::optional < std::string > detail;
+
+ // A human-readable string that represents a doc-comment.
+ boost::optional< std::pair<boost::optional< std::string> , boost::optional<MarkupContent> > > documentation;
+
+
+ /**
+ * Indicates if this item is deprecated.
+ */
+ boost::optional< bool >deprecated;
+
+
+ /**
+ * Select this item when showing.
+ *
+ * *Note* that only one completion item can be selected and that the
+ * tool / client decides which item that is. The rule is that the *first
+ * item of those that match best is selected.
+ */
+ boost::optional< bool > preselect;
+
+
+ // Internal information to order candidates.
+ int relevance = 0;
+
+ // A string that shoud be used when comparing this item
+ // with other items. When `falsy` the label is used.
+ boost::optional< std::string > sortText;
+
+ // A string that should be used when filtering a set of
+ // completion items. When `falsy` the label is used.
+ boost::optional<std::string> filterText;
+
+ // A string that should be inserted a document when selecting
+ // this completion. When `falsy` the label is used.
+ boost::optional<std::string> insertText;
+
+ // The format of the insert text. The format applies to both the `insertText`
+ // property and the `newText` property of a provided `textEdit`.
+ boost::optional< lsInsertTextFormat> insertTextFormat ;
+
+ // An edit which is applied to a document when selecting this completion. When
+ // an edit is provided the value of `insertText` is ignored.
+ //
+ // *Note:* The range of the edit must be a single line range and it must
+ // contain the position at which completion has been requested.
+ boost::optional<lsTextEdit> textEdit;
+
+ // An boost::optional array of additional text edits that are applied when
+ // selecting this completion. Edits must not overlap with the main edit
+ // nor with themselves.
+ // std::vector<TextEdit> additionalTextEdits;
+
+ // An boost::optional command that is executed *after* inserting this completion.
+ // *Note* that additional modifications to the current document should be
+ // described with the additionalTextEdits-property. Command command;
+
+ // An data entry field that is preserved on a completion item between
+ // a completion and a completion resolve request.
+ // data ? : any
+
+ // Use this helper to figure out what content the completion item will insert
+ // into the document, as it could live in either |textEdit|, |insertText|, or
+ // |label|.
+ const std::string& InsertedContent() const;
+
+ std::string DisplayText();
+ /**
+ * An boost::optional array of additional text edits that are applied when
+ * selecting this completion. Edits must not overlap (including the same insert position)
+ * with the main edit nor with themselves.
+ *
+ * Additional text edits should be used to change text unrelated to the current cursor position
+ * (for example adding an import statement at the top of the file if the completion item will
+ * insert an unqualified type).
+ */
+ boost::optional<std::vector<lsTextEdit> >additionalTextEdits;
+
+ /**
+* An boost::optional set of characters that when pressed while this completion is active will accept it first and
+* then type that character. *Note* that all commit characters should have `length=1` and that superfluous
+* characters will be ignored.
+*/
+ boost::optional< std::vector<std::string> > commitCharacters;
+
+ /**
+* An boost::optional command that is executed *after* inserting this completion. *Note* that
+* additional modifications to the current document should be described with the
+* additionalTextEdits-property.
+*/
+ boost::optional<lsCommandWithAny> command;
+
+ /**
+* An data entry field that is preserved on a completion item between a completion and a completion resolve request.
+*/
+ boost::optional<lsp::Any> data;
+ std::string ToString();
+ MAKE_SWAP_METHOD(lsCompletionItem,
+ label,
+ kind,
+ detail,
+ documentation,
+ sortText,
+ insertText,
+ filterText,
+ insertTextFormat,
+ textEdit,
+ deprecated, preselect, additionalTextEdits, commitCharacters,
+ command, data);
+
+};
+
+
+
+MAKE_REFLECT_STRUCT(lsCompletionItem,
+ label,
+ kind,
+ detail,
+ documentation,
+ sortText,
+ insertText,
+ filterText,
+ insertTextFormat,
+ textEdit,
+ deprecated, preselect, additionalTextEdits, commitCharacters,
+ command, data);
+
+
+
+struct CompletionList {
+ // This list it not complete. Further typing should result in recomputing
+ // this list.
+ bool isIncomplete = false;
+ // The completion items.
+ std::vector<lsCompletionItem> items;
+
+ void swap(CompletionList& arg) noexcept
+ {
+ items.swap(arg.items);
+ std::swap(isIncomplete, arg.isIncomplete);
+ }
+};
+MAKE_REFLECT_STRUCT(CompletionList, isIncomplete, items); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsp_diagnostic.cpp b/graphics/asymptote/LspCpp/LibLsp/lsp/lsp_diagnostic.cpp
new file mode 100644
index 0000000000..c323706dc0
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsp_diagnostic.cpp
@@ -0,0 +1,74 @@
+#include "lsp_diagnostic.h"
+bool lsDiagnostic::operator==(const lsDiagnostic& rhs) const {
+ // Just check the important fields.
+ return range == rhs.range && message == rhs.message;
+}
+bool lsDiagnostic::operator!=(const lsDiagnostic& rhs) const {
+ return !(*this == rhs);
+}
+
+std::string lsResponseError::ToString()
+{
+ std::string info = "code:";
+ switch (code)
+ {
+ case lsErrorCodes::ParseError:
+ info += "ParseError\n";
+ break;
+ case lsErrorCodes::InvalidRequest:
+ info += "InvalidRequest\n";
+ break;
+ case lsErrorCodes::MethodNotFound:
+ info += "MethodNotFound\n";
+ break;
+ case lsErrorCodes::InvalidParams:
+ info += "InvalidParams\n";
+ break;
+ case lsErrorCodes::InternalError:
+ info += "InternalError\n";
+ break;
+ case lsErrorCodes::serverErrorStart:
+ info += "serverErrorStart\n";
+ break;
+ case lsErrorCodes::serverErrorEnd:
+ info += "serverErrorEnd\n";
+ break;
+ case lsErrorCodes::ServerNotInitialized:
+ info += "ServerNotInitialized\n";
+ break;
+ case lsErrorCodes::UnknownErrorCode:
+ info += "UnknownErrorCode\n";
+ break;
+ // Defined by the protocol.
+ case lsErrorCodes::RequestCancelled:
+ info += "RequestCancelled\n";
+ break;
+ default:
+ {
+ std::stringstream ss;
+ ss << "unknown code:" << (int32_t)code << std::endl;
+ info += ss.str();
+ }
+ break;
+ }
+ info += "message:" + message;
+ info += "\n";
+
+ if(data.has_value())
+ {
+
+ info += "data:" + data.value().Data();
+ info += "\n";
+ }
+ return info;
+}
+
+void lsResponseError::Write(Writer& visitor) {
+ auto& value = *this;
+ int code2 = static_cast<int>(this->code);
+
+ visitor.StartObject();
+ REFLECT_MEMBER2("code", code2);
+ REFLECT_MEMBER(message);
+ visitor.EndObject();
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/lsp_diagnostic.h b/graphics/asymptote/LspCpp/LibLsp/lsp/lsp_diagnostic.h
new file mode 100644
index 0000000000..d1b1d1ba78
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/lsp_diagnostic.h
@@ -0,0 +1,151 @@
+#pragma once
+#include "lsRange.h"
+#include "lsTextEdit.h"
+#include "lsDocumentUri.h"
+
+#include "lsResponseError.h"
+#include "location_type.h"
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+enum class lsDiagnosticSeverity {
+ // Reports an error.
+ Error = 1,
+ // Reports a warning.
+ Warning = 2,
+ // Reports an information.
+ Information = 3,
+ // Reports a hint.
+ Hint = 4
+};
+MAKE_REFLECT_TYPE_PROXY(lsDiagnosticSeverity);
+
+/**
+ * The diagnostic tags.
+ *
+ * @since 3.15.0
+ */
+enum class DiagnosticTag :uint8_t {
+
+ /**
+ * Unused or unnecessary code.
+ *
+ * Clients are allowed to render diagnostics with this tag faded out instead of having
+ * an error squiggle.
+ */
+ Unnecessary=(1),
+
+ /**
+ * Deprecated or obsolete code.
+ *
+ * Clients are allowed to rendered diagnostics with this tag strike through.
+ */
+ Deprecated=(2),
+};
+MAKE_REFLECT_TYPE_PROXY(DiagnosticTag);
+
+
+
+/**
+ * Represents a related message and source code location for a diagnostic. This should be
+ * used to point to code locations that cause or related to a diagnostics, e.g when duplicating
+ * a symbol in a scope.
+ *
+ * Since 3.7.0
+ */
+
+struct DiagnosticRelatedInformation {
+ /**
+ * The location of this related diagnostic information.
+ */
+
+ lsLocation location;
+
+ /**
+ * The message of this related diagnostic information.
+ */
+
+ std::string message;
+
+ MAKE_SWAP_METHOD(DiagnosticRelatedInformation, location, message)
+};
+MAKE_REFLECT_STRUCT(DiagnosticRelatedInformation, location, message)
+/**
+ * Structure to capture a description for an error code.
+ *
+ * @since 3.16.0
+ */
+struct DiagnosticCodeDescription {
+ /**
+ * An URI to open with more information about the diagnostic error.
+ */
+ std::string href;
+ MAKE_SWAP_METHOD(DiagnosticCodeDescription, href)
+};
+MAKE_REFLECT_STRUCT(DiagnosticCodeDescription, href)
+
+//Represents a diagnostic, such as a compiler error or warning.Diagnostic objects are only valid in the scope of a resource.
+struct lsDiagnostic {
+ // The range at which the message applies.
+ lsRange range;
+
+ // The diagnostic's severity. Can be omitted. If omitted it is up to the
+ // client to interpret diagnostics as error, warning, info or hint.
+ boost::optional<lsDiagnosticSeverity> severity;
+
+ // The diagnostic's code. Can be omitted.
+ boost::optional< std::pair<boost::optional<std::string>, boost::optional<int>> > code;
+
+ boost::optional<DiagnosticCodeDescription> codeDescription;
+ // A human-readable string describing the source of this
+ // diagnostic, e.g. 'typescript' or 'super lint'.
+ boost::optional < std::string >source ;
+
+ // The diagnostic's message.
+ std::string message;
+
+ // Non-serialized set of fixits.
+ std::vector<lsTextEdit> fixits_;
+
+ /**
+ * Additional metadata about the diagnostic.
+ *
+ * @since 3.15.0
+ */
+ boost::optional<std::vector<DiagnosticTag>> tags;
+
+
+ /**
+ * An array of related diagnostic information, e.g. when symbol-names within a scope collide
+ * all definitions can be marked via this property.
+ *
+ * Since 3.7.0
+ */
+ boost::optional<std::vector<DiagnosticRelatedInformation>> relatedInformation;
+
+ /**
+ * A data entry field that is preserved between a
+ * `textDocument/publishDiagnostics` notification and
+ * `textDocument/codeAction` request.
+ *
+ * @since 3.16.0
+ */
+ boost::optional<lsp::Any> data;
+ bool operator==(const lsDiagnostic& rhs) const;
+ bool operator!=(const lsDiagnostic& rhs) const;
+
+ MAKE_SWAP_METHOD(lsDiagnostic, range, severity, code, codeDescription, source, message, tags, data)
+};
+MAKE_REFLECT_STRUCT(lsDiagnostic, range, severity, code, codeDescription, source, message, tags, data)
+
+
+
+struct Rsp_Error : ResponseError<lsResponseError, Rsp_Error> {
+
+ MAKE_SWAP_METHOD(Rsp_Error, jsonrpc, id, error)
+};
+MAKE_REFLECT_STRUCT(Rsp_Error, jsonrpc, id, error)
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/method_type.h b/graphics/asymptote/LspCpp/LibLsp/lsp/method_type.h
new file mode 100644
index 0000000000..dcbb4a851a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/method_type.h
@@ -0,0 +1,7 @@
+#pragma once
+#include <string>
+
+using MethodType = const char* const;
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/out_list.h b/graphics/asymptote/LspCpp/LibLsp/lsp/out_list.h
new file mode 100644
index 0000000000..36c4aa78ba
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/out_list.h
@@ -0,0 +1,22 @@
+#pragma once
+
+
+#include "location_type.h"
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+
+
+//DEFINE_RESPONCE_TYPE(Rsp_FindLinkLocationList, std::vector<LinkLocation>);
+//DEFINE_RESPONCE_TYPE(Rsp_LocationList, std::vector<lsLocation>);
+
+
+namespace LocationListEither{
+
+ typedef std::pair< boost::optional<std::vector<lsLocation>> , boost::optional<std::vector<LocationLink> > > Either;
+
+};
+extern void Reflect(Reader& visitor, LocationListEither::Either& value);
+//DEFINE_RESPONCE_TYPE(Rsp_LocationListEither, LocationListEither::Either);
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/symbol.h b/graphics/asymptote/LspCpp/LibLsp/lsp/symbol.h
new file mode 100644
index 0000000000..57298b8d7f
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/symbol.h
@@ -0,0 +1,164 @@
+#pragma once
+#include "LibLsp/lsp/location_type.h"
+
+
+enum class lsSymbolKind : uint8_t {
+ Unknown = 0,
+
+ File = 1,
+ Module = 2,
+ Namespace = 3,
+ Package = 4,
+ Class = 5,
+ Method = 6,
+ Property = 7,
+ Field = 8,
+ Constructor = 9,
+ Enum = 10,
+ Interface = 11,
+ Function = 12,
+ Variable = 13,
+ Constant = 14,
+ String = 15,
+ Number = 16,
+ Boolean = 17,
+ Array = 18,
+ Object = 19,
+ Key = 20,
+ Null = 21,
+ EnumMember = 22,
+ Struct = 23,
+ Event = 24,
+ Operator = 25,
+
+ // For C++, this is interpreted as "template parameter" (including
+ // non-type template parameters).
+ TypeParameter = 26,
+
+ // cquery extensions
+ // See also https://github.com/Microsoft/language-server-protocol/issues/344
+ // for new SymbolKind clang/Index/IndexSymbol.h clang::index::SymbolKind
+ TypeAlias = 252,
+ Parameter = 253,
+ StaticMethod = 254,
+ Macro = 255,
+};
+MAKE_REFLECT_TYPE_PROXY(lsSymbolKind);
+
+typedef lsSymbolKind SymbolKind;
+
+// A document highlight kind.
+enum class lsDocumentHighlightKind {
+ // A textual occurrence.
+ Text = 1,
+ // Read-access of a symbol, like reading a variable.
+ Read = 2,
+ // Write-access of a symbol, like writing to a variable.
+ Write = 3
+};
+MAKE_REFLECT_TYPE_PROXY(lsDocumentHighlightKind);
+
+// A document highlight is a range inside a text document which deserves
+// special attention. Usually a document highlight is visualized by changing
+// the background color of its range.
+struct lsDocumentHighlight {
+ // The range this highlight applies to.
+ lsRange range;
+
+ // The highlight kind, default is DocumentHighlightKind.Text.
+ boost::optional<lsDocumentHighlightKind> kind ;
+
+ MAKE_SWAP_METHOD(lsDocumentHighlight, range, kind)
+};
+MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind);
+
+struct lsSymbolInformation {
+
+/**
+ * The name of this symbol.
+ */
+ std::string name;
+ /**
+ * The kind of this symbol.
+ */
+ lsSymbolKind kind;
+ /**
+* Indicates if this symbol is deprecated.
+*/
+ boost::optional<bool> deprecated;
+ /**
+ * The location of this symbol. The location's range is used by a tool
+ * to reveal the location in the editor. If the symbol is selected in the
+ * tool the range's start information is used to position the cursor. So
+ * the range usually spans more then the actual symbol's name and does
+ * normally include things like visibility modifiers.
+ *
+ * The range doesn't have to denote a node range in the sense of a abstract
+ * syntax tree. It can therefore not be used to re-construct a hierarchy of
+ * the symbols.
+ */
+ lsLocation location;
+ /**
+ * The name of the symbol containing this symbol. This information is for
+ * user interface purposes (e.g. to render a qualifier in the user interface
+ * if necessary). It can't be used to re-infer a hierarchy for the document
+ * symbols.
+ */
+ boost::optional<std::string> containerName;
+
+
+ MAKE_SWAP_METHOD(lsSymbolInformation, name, kind, deprecated, location, containerName);
+};
+MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, deprecated, location, containerName);
+
+
+struct lsDocumentSymbol {
+ /**
+ * The name of this symbol.
+ */
+
+ std::string name;
+
+ /**
+ * The kind of this symbol.
+ */
+
+ lsSymbolKind kind = lsSymbolKind::Unknown;
+
+ /**
+ * The range enclosing this symbol not including leading/trailing whitespace but everything else
+ * like comments. This information is typically used to determine if the clients cursor is
+ * inside the symbol to reveal in the symbol in the UI.
+ */
+
+ lsRange range;
+
+ /**
+ * The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
+ * Must be contained by the `range`.
+ */
+
+ lsRange selectionRange;
+
+ /**
+ * More detail for this symbol, e.g the signature of a function. If not provided the
+ * name is used.
+ */
+ boost::optional< std::string > detail;
+
+ /**
+ * Indicates if this symbol is deprecated.
+ */
+ boost::optional< bool > deprecated;
+
+ /**
+ * Children of this symbol, e.g. properties of a class.
+ */
+ boost::optional < std::vector<lsDocumentSymbol> > children;
+
+ //internal use
+ int flags=0;
+
+ MAKE_SWAP_METHOD(lsDocumentSymbol, name, kind, range, selectionRange, detail, deprecated, children, flags);
+};
+MAKE_REFLECT_STRUCT(lsDocumentSymbol, name, kind, range, selectionRange, detail, deprecated, children, flags); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/SemanticTokens.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/SemanticTokens.h
new file mode 100644
index 0000000000..612d186f6f
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/SemanticTokens.h
@@ -0,0 +1,267 @@
+#pragma once
+
+#include "LibLsp/lsp/lsTextDocumentIdentifier.h"
+#include "LibLsp/lsp/lsVersionedTextDocumentIdentifier.h"
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+enum class HighlightingKind_clangD {
+ Variable = 0,
+ LocalVariable,
+ Parameter,
+ Function,
+ Method,
+ StaticMethod,
+ Field,
+ StaticField,
+ Class,
+ Interface,
+ Enum,
+ EnumConstant,
+ Typedef,
+ Type,
+ Unknown,
+ Namespace,
+ TemplateParameter,
+ Concept,
+ Primitive,
+ Macro,
+
+ // This one is different from the other kinds as it's a line style
+ // rather than a token style.
+ InactiveCode,
+
+ LastKind = InactiveCode
+};
+std::string toSemanticTokenType(HighlightingKind_clangD kind);
+
+enum class HighlightingModifier_clangD {
+ Declaration,
+ Deprecated,
+ Deduced,
+ Readonly,
+ Static,
+ Abstract,
+ DependentName,
+ DefaultLibrary,
+
+ FunctionScope,
+ ClassScope,
+ FileScope,
+ GlobalScope,
+
+ LastModifier = GlobalScope
+};
+std::string toSemanticTokenModifier(HighlightingModifier_clangD modifier);
+
+enum SemanticTokenType {
+ ls_namespace=0,// 'namespace',
+ /**
+ * Represents a generic type. Acts as a fallback for types which
+ * can't be mapped to a specific type like class or enum.
+ */
+ ls_type,// 'type',
+ ls_class,// 'class',
+ ls_enum,// 'enum',
+ ls_interface,// 'interface',
+ ls_struct,// 'struct',
+ ls_typeParameter,// 'typeParameter',
+ ls_parameter,// 'parameter',
+ ls_variable,// 'variable',
+ ls_property,// 'property',
+ ls_enumMember,// 'enumMember',
+ ls_event,// 'event',
+ ls_function,// 'function',
+ ls_method,// 'method',
+ ls_macro,// 'macro',
+ ls_keyword,// 'keyword',
+ ls_modifier,// 'modifier',
+ ls_comment,// 'comment',
+ ls_string,// 'string',
+ ls_number,// 'number',
+ ls_regexp,// 'regexp',
+ ls_operator,// 'operator'
+ lastKind = ls_operator
+};
+std::string to_string(SemanticTokenType);
+unsigned toSemanticTokenType(std::vector<SemanticTokenType>& modifiers);
+
+enum TokenType_JDT {
+ PACKAGE_JDT=0,
+ CLASS_JDT,
+ INTERFACE_JDT,
+ ENUM_JDT,
+ ENUM_MEMBER_JDT,
+ TYPE_JDT,
+ TYPE_PARAMETER_JDT,
+ ANNOTATION_JDT,
+ ANNOTATION_MEMBER_JDT,
+ METHOD_JDT,
+ PROPERTY_JDT,
+ VARIABLE_JDT,
+ PARAMETER_JDT
+};
+std::string to_string(TokenType_JDT);
+
+enum SemanticTokenModifier {
+ ls_declaration=0,// 'declaration',
+ ls_definition,// 'definition',
+ ls_readonly,// 'readonly',
+ ls_static,// 'static',
+ ls_deprecated,// 'deprecated',
+ ls_abstract,// 'abstract',
+ ls_async,// 'async',
+ ls_modification,// 'modification',
+ ls_documentation,// 'documentation',
+ ls_defaultLibrary,// 'defaultLibrary'
+ LastModifier = ls_defaultLibrary
+};
+std::string to_string(SemanticTokenModifier);
+unsigned toSemanticTokenModifiers(std::vector<SemanticTokenModifier>&);
+/// Specifies a single semantic token in the document.
+/// This struct is not part of LSP, which just encodes lists of tokens as
+/// arrays of numbers directly.
+struct SemanticToken {
+ /// token line number, relative to the previous token
+ unsigned deltaLine = 0;
+ /// token start character, relative to the previous token
+ /// (relative to 0 or the previous token's start if they are on the same line)
+ unsigned deltaStart = 0;
+ /// the length of the token. A token cannot be multiline
+ unsigned length = 0;
+ /// will be looked up in `SemanticTokensLegend.tokenTypes`
+ unsigned tokenType = 0;
+ /// each set bit will be looked up in `SemanticTokensLegend.tokenModifiers`
+ unsigned tokenModifiers = 0;
+};
+bool operator==(const SemanticToken&, const SemanticToken&);
+struct SemanticTokens{
+
+ /**
+ * Tokens in a file are represented as an array of integers. The position of each token is expressed relative to
+ * the token before it, because most tokens remain stable relative to each other when edits are made in a file.
+ *
+ * ---
+ * In short, each token takes 5 integers to represent, so a specific token `i` in the file consists of the following array indices:
+ * - at index `5*i` - `deltaLine`: token line number, relative to the previous token
+ * - at index `5*i+1` - `deltaStart`: token start character, relative to the previous token (relative to 0 or the previous token's start if they are on the same line)
+ * - at index `5*i+2` - `length`: the length of the token. A token cannot be multiline.
+ * - at index `5*i+3` - `tokenType`: will be looked up in `SemanticTokensLegend.tokenTypes`. We currently ask that `tokenType` < 65536.
+ * - at index `5*i+4` - `tokenModifiers`: each set bit will be looked up in `SemanticTokensLegend.tokenModifiers`
+ *
+ * ---
+ * ### How to encode tokens
+ *
+ * Here is an example for encoding a file with 3 tokens in a uint32 array:
+ * ```
+ * { line: 2, startChar: 5, length: 3, tokenType: "property", tokenModifiers: ["private", "static"] },
+ * { line: 2, startChar: 10, length: 4, tokenType: "type", tokenModifiers: [] },
+ * { line: 5, startChar: 2, length: 7, tokenType: "class", tokenModifiers: [] }
+ * ```
+ *
+ * 1. First of all, a legend must be devised. This legend must be provided up-front and capture all possible token types.
+ * For this example, we will choose the following legend which must be passed in when registering the provider:
+ * ```
+ * tokenTypes: ['property', 'type', 'class'],
+ * tokenModifiers: ['private', 'static']
+ * ```
+ *
+ * 2. The first transformation step is to encode `tokenType` and `tokenModifiers` as integers using the legend. Token types are looked
+ * up by index, so a `tokenType` value of `1` means `tokenTypes[1]`. Multiple token modifiers can be set by using bit flags,
+ * so a `tokenModifier` value of `3` is first viewed as binary `0b00000011`, which means `[tokenModifiers[0], tokenModifiers[1]]` because
+ * bits 0 and 1 are set. Using this legend, the tokens now are:
+ * ```
+ * { line: 2, startChar: 5, length: 3, tokenType: 0, tokenModifiers: 3 },
+ * { line: 2, startChar: 10, length: 4, tokenType: 1, tokenModifiers: 0 },
+ * { line: 5, startChar: 2, length: 7, tokenType: 2, tokenModifiers: 0 }
+ * ```
+ *
+ * 3. The next step is to represent each token relative to the previous token in the file. In this case, the second token
+ * is on the same line as the first token, so the `startChar` of the second token is made relative to the `startChar`
+ * of the first token, so it will be `10 - 5`. The third token is on a different line than the second token, so the
+ * `startChar` of the third token will not be altered:
+ * ```
+ * { deltaLine: 2, deltaStartChar: 5, length: 3, tokenType: 0, tokenModifiers: 3 },
+ * { deltaLine: 0, deltaStartChar: 5, length: 4, tokenType: 1, tokenModifiers: 0 },
+ * { deltaLine: 3, deltaStartChar: 2, length: 7, tokenType: 2, tokenModifiers: 0 }
+ * ```
+ *
+ * 4. Finally, the last step is to inline each of the 5 fields for a token in a single array, which is a memory friendly representation:
+ * ```
+ * // 1st token, 2nd token, 3rd token
+ * [ 2,5,3,0,3, 0,5,4,1,0, 3,2,7,2,0 ]
+ * ```
+ */
+ std::vector<int32_t> data;
+ static std::vector<int32_t> encodeTokens(std::vector<SemanticToken>& tokens);
+
+ /**
+ * An optional result id. If provided and clients support delta updating
+ * the client will include the result id in the next semantic token request.
+ * A server can then instead of computing all semantic tokens again simply
+ * send a delta.
+ */
+ boost::optional<std::string> resultId;
+ MAKE_SWAP_METHOD(SemanticTokens, data, resultId)
+};
+MAKE_REFLECT_STRUCT(SemanticTokens, data, resultId)
+
+/// Body of textDocument/semanticTokens/full request.
+struct SemanticTokensParams {
+ /// The text document.
+ lsTextDocumentIdentifier textDocument;
+ MAKE_REFLECT_STRUCT(SemanticTokensParams, textDocument)
+};
+MAKE_REFLECT_STRUCT(SemanticTokensParams, textDocument)
+
+
+/// Body of textDocument/semanticTokens/full/delta request.
+/// Requests the changes in semantic tokens since a previous response.
+struct SemanticTokensDeltaParams {
+ /// The text document.
+ lsTextDocumentIdentifier textDocument;
+ /**
+ * The result id of a previous response. The result Id can either point to
+ * a full response or a delta response depending on what was received last.
+ */
+ std::string previousResultId;
+
+ MAKE_REFLECT_STRUCT(SemanticTokensDeltaParams, textDocument, previousResultId)
+};
+MAKE_REFLECT_STRUCT(SemanticTokensDeltaParams, textDocument, previousResultId)
+
+/// Describes a a replacement of a contiguous range of semanticTokens.
+struct SemanticTokensEdit {
+ // LSP specifies `start` and `deleteCount` which are relative to the array
+ // encoding of the previous tokens.
+ // We use token counts instead, and translate when serializing this struct.
+ unsigned startToken = 0;
+ unsigned deleteTokens = 0;
+ std::vector<int32_t> tokens; // encoded as a flat integer array
+
+ MAKE_REFLECT_STRUCT(SemanticTokensEdit, startToken, deleteTokens, tokens)
+};
+MAKE_REFLECT_STRUCT(SemanticTokensEdit, startToken, deleteTokens, tokens)
+
+
+/// This models LSP SemanticTokensDelta | SemanticTokens, which is the result of
+/// textDocument/semanticTokens/full/delta.
+struct SemanticTokensOrDelta {
+ boost::optional<std::string > resultId;
+ /// Set if we computed edits relative to a previous set of tokens.
+ boost::optional< std::vector<SemanticTokensEdit> > edits;
+ /// Set if we computed a fresh set of tokens.
+ /// Set if we computed edits relative to a previous set of tokens.
+ boost::optional<std::vector<int32_t>> tokens; // encoded as integer array
+ MAKE_REFLECT_STRUCT(SemanticTokensOrDelta, resultId, edits, tokens)
+};
+MAKE_REFLECT_STRUCT(SemanticTokensOrDelta, resultId, edits, tokens)
+
+
+struct SemanticTokensLegend {
+ std::vector<std::string> tokenTypes;
+ std::vector<std::string> tokenModifiers;
+ MAKE_REFLECT_STRUCT(SemanticTokensLegend, tokenTypes, tokenModifiers)
+};
+MAKE_REFLECT_STRUCT(SemanticTokensLegend, tokenTypes, tokenModifiers)
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_semanticTokens_full, SemanticTokensParams,boost::optional<SemanticTokens >,"textDocument/semanticTokens/full")
+DEFINE_REQUEST_RESPONSE_TYPE(td_semanticTokens_full_delta, SemanticTokensDeltaParams, boost::optional<SemanticTokensOrDelta >, "textDocument/semanticTokens/full/delta") \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/callHierarchy.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/callHierarchy.h
new file mode 100644
index 0000000000..a005c182e1
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/callHierarchy.h
@@ -0,0 +1,121 @@
+#pragma once
+
+#include "LibLsp/lsp/lsAny.h"
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include "LibLsp/lsp/symbol.h"
+#include "LibLsp/lsp/lsTextDocumentPositionParams.h"
+#include "LibLsp/lsp/lsRange.h"
+
+enum class SymbolTag { Deprecated = 1 };
+MAKE_REFLECT_TYPE_PROXY(SymbolTag)
+
+struct CallHierarchyPrepareParams
+{
+ lsTextDocumentIdentifier textDocument;
+ lsPosition position;
+
+ MAKE_SWAP_METHOD(CallHierarchyPrepareParams,
+ textDocument,
+ position)
+};
+MAKE_REFLECT_STRUCT(CallHierarchyPrepareParams,
+ textDocument,
+ position)
+
+
+
+ /// Represents programming constructs like functions or constructors
+ /// in the context of call hierarchy.
+struct CallHierarchyItem {
+ /// The name of this item.
+ std::string name;
+
+ /// The kind of this item.
+ SymbolKind kind;
+
+ /// Tags for this item.
+ boost::optional<std::vector<SymbolTag>> tags;
+
+ /// More detaill for this item, e.g. the signature of a function.
+ boost::optional<std::string> detail;
+
+ /// The resource identifier of this item.
+ lsDocumentUri uri;
+
+ /**
+ * The range enclosing this symbol not including leading/trailing whitespace
+ * but everything else, e.g. comments and code.
+ */
+ lsRange range;
+
+ /**
+ * The range that should be selected and revealed when this symbol is being
+ * picked, e.g. the name of a function. Must be contained by the
+ * [`range`](#CallHierarchyItem.range).
+ */
+ lsRange selectionRange;
+
+ /**
+ * A data entry field that is preserved between a call hierarchy prepare and
+ * incoming calls or outgoing calls requests.
+ */
+ boost::optional<lsp::Any> data;
+ MAKE_SWAP_METHOD(CallHierarchyItem, name, kind, tags, detail, uri, range, selectionRange, data)
+};
+MAKE_REFLECT_STRUCT(CallHierarchyItem, name, kind, tags, detail, uri, range, selectionRange, data)
+
+
+
+/// The parameter of a `callHierarchy/incomingCalls` request.
+struct CallHierarchyIncomingCallsParams {
+ CallHierarchyItem item;
+ MAKE_SWAP_METHOD(CallHierarchyIncomingCallsParams,item)
+};
+MAKE_REFLECT_STRUCT(CallHierarchyIncomingCallsParams, item)
+
+
+/// Represents an incoming call, e.g. a caller of a method or constructor.
+struct CallHierarchyIncomingCall {
+ /// The item that makes the call.
+ CallHierarchyItem from;
+
+ /// The range at which the calls appear.
+ /// This is relative to the caller denoted by `From`.
+ std::vector<lsRange> fromRanges;
+ MAKE_SWAP_METHOD(CallHierarchyIncomingCall, from, fromRanges)
+};
+MAKE_REFLECT_STRUCT(CallHierarchyIncomingCall, from, fromRanges)
+
+
+
+
+/// The parameter of a `callHierarchy/outgoingCalls` request.
+struct CallHierarchyOutgoingCallsParams {
+ CallHierarchyItem item;
+ MAKE_SWAP_METHOD(CallHierarchyOutgoingCallsParams, item)
+};
+MAKE_REFLECT_STRUCT(CallHierarchyOutgoingCallsParams, item)
+
+/// Represents an outgoing call, e.g. calling a getter from a method or
+/// a method from a constructor etc.
+struct CallHierarchyOutgoingCall {
+ /// The item that is called.
+ CallHierarchyItem to;
+
+ /// The range at which this item is called.
+ /// This is the range relative to the caller, and not `To`.
+ std::vector<lsRange> fromRanges;
+ MAKE_SWAP_METHOD(CallHierarchyOutgoingCall, to, fromRanges)
+};
+MAKE_REFLECT_STRUCT(CallHierarchyOutgoingCall, to, fromRanges)
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_prepareCallHierarchy, CallHierarchyPrepareParams,
+ boost::optional<std::vector<CallHierarchyItem>>, "textDocument/prepareCallHierarchy")
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_incomingCalls, CallHierarchyIncomingCallsParams,
+ boost::optional<std::vector<CallHierarchyIncomingCall>>, "callHierarchy/incomingCalls")
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_outgoingCalls, CallHierarchyOutgoingCallsParams,
+ boost::optional<std::vector<CallHierarchyOutgoingCall>>, "callHierarchy/CallHierarchyOutgoingCall") \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/code_action.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/code_action.h
new file mode 100644
index 0000000000..419fdfbc9b
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/code_action.h
@@ -0,0 +1,37 @@
+#pragma once
+#include "LibLsp/lsp/method_type.h"
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include "LibLsp/lsp/lsTextDocumentIdentifier.h"
+#include "LibLsp/lsp/CodeActionParams.h"
+
+namespace QuickAssistProcessor {
+
+ extern const char* SPLIT_JOIN_VARIABLE_DECLARATION_ID;//$NON-NLS-1$
+ extern const char* CONVERT_FOR_LOOP_ID;// ;// "org.eclipse.jdt.ls.correction.convertForLoop.assist"; //$NON-NLS-1$
+ extern const char* ASSIGN_TO_LOCAL_ID ;// "org.eclipse.jdt.ls.correction.assignToLocal.assist"; //$NON-NLS-1$
+ extern const char* ASSIGN_TO_FIELD_ID ;// "org.eclipse.jdt.ls.correction.assignToField.assist"; //$NON-NLS-1$
+ extern const char* ASSIGN_PARAM_TO_FIELD_ID ;// "org.eclipse.jdt.ls.correction.assignParamToField.assist"; //$NON-NLS-1$
+ extern const char* ASSIGN_ALL_PARAMS_TO_NEW_FIELDS_ID ;// "org.eclipse.jdt.ls.correction.assignAllParamsToNewFields.assist"; //$NON-NLS-1$
+ extern const char* ADD_BLOCK_ID ;// "org.eclipse.jdt.ls.correction.addBlock.assist"; //$NON-NLS-1$
+ extern const char* EXTRACT_LOCAL_ID ;// "org.eclipse.jdt.ls.correction.extractLocal.assist"; //$NON-NLS-1$
+ extern const char* EXTRACT_LOCAL_NOT_REPLACE_ID ;// "org.eclipse.jdt.ls.correction.extractLocalNotReplaceOccurrences.assist"; //$NON-NLS-1$
+ extern const char* EXTRACT_CONSTANT_ID ;// "org.eclipse.jdt.ls.correction.extractConstant.assist"; //$NON-NLS-1$
+ extern const char* INLINE_LOCAL_ID ;// "org.eclipse.jdt.ls.correction.inlineLocal.assist"; //$NON-NLS-1$
+ extern const char* CONVERT_LOCAL_TO_FIELD_ID ;// "org.eclipse.jdt.ls.correction.convertLocalToField.assist"; //$NON-NLS-1$
+ extern const char* CONVERT_ANONYMOUS_TO_LOCAL_ID ;// "org.eclipse.jdt.ls.correction.convertAnonymousToLocal.assist"; //$NON-NLS-1$
+ extern const char* CONVERT_TO_STRING_BUFFER_ID ;// "org.eclipse.jdt.ls.correction.convertToStringBuffer.assist"; //$NON-NLS-1$
+ extern const char* CONVERT_TO_MESSAGE_FORMAT_ID ;// "org.eclipse.jdt.ls.correction.convertToMessageFormat.assist"; //$NON-NLS-1$;
+ extern const char* EXTRACT_METHOD_INPLACE_ID ;// "org.eclipse.jdt.ls.correction.extractMethodInplace.assist"; //$NON-NLS-1$;
+
+ extern const char* CONVERT_ANONYMOUS_CLASS_TO_NESTED_COMMAND ;// "convertAnonymousClassToNestedCommand";
+};
+/**
+ * The code action request is sent from the client to the server to compute
+ * commands for a given text document and range. These commands are
+ * typically code fixes to either fix problems or to beautify/refactor code.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ */
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_codeAction, lsCodeActionParams, std::vector<lsCommandWithAny>, "textDocument/codeAction");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/code_lens.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/code_lens.h
new file mode 100644
index 0000000000..7fd5ae0cf9
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/code_lens.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+struct lsDocumentCodeLensParams {
+
+/**
+ * The document to request code lens for.
+ */
+ lsTextDocumentIdentifier textDocument;
+
+ MAKE_SWAP_METHOD(lsDocumentCodeLensParams, textDocument);
+};
+MAKE_REFLECT_STRUCT(lsDocumentCodeLensParams, textDocument);
+
+
+
+
+struct lsCodeLens {
+ // The range in which this code lens is valid. Should only span a single line.
+ lsRange range;
+ // The command this code lens represents.
+ boost::optional<lsCommandWithAny> command;
+ // A data entry field that is preserved on a code lens item between
+ // a code lens and a code lens resolve request.
+ boost::optional< lsp::Any> data;
+
+ MAKE_SWAP_METHOD(lsCodeLens, range, command, data)
+};
+MAKE_REFLECT_STRUCT(lsCodeLens, range, command, data)
+
+
+
+/**
+ * The code lens request is sent from the client to the server to compute
+ * code lenses for a given text document.
+ *
+ * Registration Options: CodeLensRegistrationOptions
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_codeLens, lsDocumentCodeLensParams, std::vector<lsCodeLens>, "textDocument/codeLens")
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/colorPresentation.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/colorPresentation.h
new file mode 100644
index 0000000000..22574e3e19
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/colorPresentation.h
@@ -0,0 +1,63 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/lsTextDocumentIdentifier.h"
+#include "LibLsp/lsp/lsRange.h"
+#include "documentColor.h"
+#include "LibLsp/lsp/lsTextEdit.h"
+
+
+struct ColorPresentationParams {
+
+ /**
+ * The text document.
+ */
+ lsTextDocumentIdentifier textDocument;
+
+ /**
+ * The range in the document where this color appers.
+ */
+
+ lsRange range;
+
+ /**
+ * The actual color value for this color range.
+ */
+
+ TextDocument::Color color;
+ MAKE_SWAP_METHOD(ColorPresentationParams, textDocument, range, color)
+};
+MAKE_REFLECT_STRUCT(ColorPresentationParams, textDocument, range, color)
+
+
+struct ColorPresentation {
+ /**
+ * The label of this color presentation. It will be shown on the color
+ * picker header. By default this is also the text that is inserted when selecting
+ * this color presentation.
+ */
+
+ std::string label;
+
+ /**
+ * An edit which is applied to a document when selecting
+ * this presentation for the color. When `null` the label is used.
+ */
+ lsTextEdit textEdit;
+
+ /**
+ * An optional array of additional text edits that are applied when
+ * selecting this color presentation. Edits must not overlap with the main edit nor with themselves.
+ */
+ std::vector<lsTextEdit> additionalTextEdits;
+ MAKE_SWAP_METHOD(ColorPresentation, label, textEdit, additionalTextEdits)
+};
+MAKE_REFLECT_STRUCT(ColorPresentation, label, textEdit, additionalTextEdits)
+
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_colorPresentation,
+ ColorPresentationParams, std::vector<ColorPresentation>, "textDocument/colorPresentation") \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/completion.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/completion.h
new file mode 100644
index 0000000000..883c5cfe3a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/completion.h
@@ -0,0 +1,82 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include <regex>
+#include "LibLsp/lsp/lsp_completion.h"
+#include "LibLsp/lsp/lsTextDocumentPositionParams.h"
+
+
+// How a completion was triggered
+enum class lsCompletionTriggerKind {
+ // Completion was triggered by typing an identifier (24x7 code
+ // complete), manual invocation (e.g Ctrl+Space) or via API.
+ Invoked = 1,
+
+ // Completion was triggered by a trigger character specified by
+ // the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
+ TriggerCharacter = 2
+};
+MAKE_REFLECT_TYPE_PROXY(lsCompletionTriggerKind);
+
+
+// Contains additional information about the context in which a completion
+// request is triggered.
+struct lsCompletionContext {
+ // How the completion was triggered.
+ lsCompletionTriggerKind triggerKind = lsCompletionTriggerKind::Invoked;
+
+ // The trigger character (a single character) that has trigger code complete.
+ // Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
+ boost::optional<std::string> triggerCharacter;
+
+ MAKE_SWAP_METHOD(lsCompletionContext, triggerKind, triggerCharacter);
+};
+MAKE_REFLECT_STRUCT(lsCompletionContext, triggerKind, triggerCharacter);
+
+struct lsCompletionParams : lsTextDocumentPositionParams {
+ // The completion context. This is only available it the client specifies to
+ // send this using
+ // `ClientCapabilities.textDocument.completion.contextSupport === true`
+ boost::optional<lsCompletionContext> context;
+
+ MAKE_SWAP_METHOD(lsCompletionParams, textDocument, position, context);
+
+};
+MAKE_REFLECT_STRUCT(lsCompletionParams, textDocument, position, context);
+
+
+
+
+
+
+
+
+
+namespace TextDocumentComplete{
+
+ typedef std::pair< boost::optional<std::vector<lsCompletionItem>>, boost::optional<CompletionList> > Either;
+
+};
+extern void Reflect(Reader& visitor, TextDocumentComplete::Either& value);
+
+/**
+ * The Completion request is sent from the client to the server to compute
+ * completion items at a given cursor position. Completion items are
+ * presented in the IntelliSense user interface. If computing complete
+ * completion items is expensive servers can additional provide a handler
+ * for the resolve completion item request. This request is sent when a
+ * completion item is selected in the user interface.
+ *
+ * Registration Options: CompletionRegistrationOptions
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_completion, lsCompletionParams, CompletionList , "textDocument/completion")
+
+
+
+
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/declaration_definition.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/declaration_definition.h
new file mode 100644
index 0000000000..aa20fce046
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/declaration_definition.h
@@ -0,0 +1,29 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/lsTextDocumentPositionParams.h"
+#include "LibLsp/lsp/out_list.h"
+
+
+/**
+ * The go to declaration request is sent from the client to the server to resolve
+ * the declaration location of a symbol at a given text document position.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ *
+ * Since version 3.14.0
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_declaration, lsTextDocumentPositionParams, LocationListEither::Either, "textDocument/declaration");
+
+/**
+ * The goto definition request is sent from the client to the server to resolve
+ * the definition location of a symbol at a given text document position.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_definition, lsTextDocumentPositionParams, LocationListEither::Either, "textDocument/definition");
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/didRenameFiles.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/didRenameFiles.h
new file mode 100644
index 0000000000..e8a6235a00
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/didRenameFiles.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include <string>
+#include "LibLsp/lsp/CodeActionParams.h"
+#include "LibLsp/lsp/lsWorkspaceEdit.h"
+
+
+class FileRenameEvent {
+public:
+ std::string oldUri;
+ std::string newUri;
+
+ FileRenameEvent() {
+ }
+
+ FileRenameEvent(std::string oldUri, std::string newUri) {
+ this->oldUri = oldUri;
+ this->newUri = newUri;
+ }
+ MAKE_SWAP_METHOD(FileRenameEvent, oldUri, newUri);
+};
+MAKE_REFLECT_STRUCT(FileRenameEvent, oldUri, newUri);
+
+class FileRenameParams {
+public:
+ std::vector <FileRenameEvent> files;
+
+ FileRenameParams() {
+ }
+
+ FileRenameParams(std::vector<FileRenameEvent>& files) {
+ this->files = files;
+ }
+ MAKE_SWAP_METHOD(FileRenameParams, files);
+};
+MAKE_REFLECT_STRUCT(FileRenameParams, files);
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_didRenameFiles, FileRenameParams, boost::optional<lsWorkspaceEdit>, "java/didRenameFiles");
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_willRenameFiles, FileRenameParams, boost::optional<lsWorkspaceEdit>, "java/willRenameFiles");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_change.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_change.h
new file mode 100644
index 0000000000..0887bf6602
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_change.h
@@ -0,0 +1,51 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/lsVersionedTextDocumentIdentifier.h"
+#include "LibLsp/lsp/lsRange.h"
+#include "LibLsp/lsp/lsDocumentUri.h"
+struct lsTextDocumentContentChangeEvent {
+ // The range of the document that changed.
+ boost::optional<lsRange> range;
+ // The length of the range that got replaced.
+ boost::optional<int> rangeLength;
+ // The new text of the range/document.
+ std::string text;
+
+ MAKE_SWAP_METHOD(lsTextDocumentContentChangeEvent, range, rangeLength, text);
+};
+MAKE_REFLECT_STRUCT(lsTextDocumentContentChangeEvent, range, rangeLength, text);
+
+
+struct lsTextDocumentDidChangeParams {
+ lsVersionedTextDocumentIdentifier textDocument;
+ std::vector<lsTextDocumentContentChangeEvent> contentChanges;
+
+ /**
+ * Legacy property to support protocol version 1.0 requests.
+ */
+
+ boost::optional<lsDocumentUri> uri;
+
+ void swap(lsTextDocumentDidChangeParams& arg) noexcept
+ {
+ uri.swap(arg.uri);
+ contentChanges.swap(arg.contentChanges);
+ textDocument.swap(arg.textDocument);
+ }
+};
+MAKE_REFLECT_STRUCT(lsTextDocumentDidChangeParams,
+ textDocument,
+ contentChanges, uri);
+
+/**
+ * The document change notification is sent from the client to the server to
+ * signal changes to a text document.
+ *
+ * Registration Options: TextDocumentChangeRegistrationOptions
+ */
+DEFINE_NOTIFICATION_TYPE(Notify_TextDocumentDidChange, lsTextDocumentDidChangeParams, "textDocument/didChange");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_close.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_close.h
new file mode 100644
index 0000000000..e2eaa2cfcd
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_close.h
@@ -0,0 +1,33 @@
+#pragma once
+
+
+
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+
+
+
+
+namespace TextDocumentDidClose {
+
+ struct Params {
+ lsTextDocumentIdentifier textDocument;
+ void swap(Params& arg) noexcept
+ {
+ textDocument.swap(arg.textDocument);
+ }
+
+ };
+
+};
+
+MAKE_REFLECT_STRUCT(TextDocumentDidClose::Params, textDocument);
+
+/**
+ * The document close notification is sent from the client to the server
+ * when the document got closed in the client. The document's truth now
+ * exists where the document's uri points to (e.g. if the document's uri is
+ * a file uri the truth now exists on disk).
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ */
+DEFINE_NOTIFICATION_TYPE(Notify_TextDocumentDidClose, TextDocumentDidClose::Params, "textDocument/didClose");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_open.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_open.h
new file mode 100644
index 0000000000..7be7a735d6
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_open.h
@@ -0,0 +1,39 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+
+#include "LibLsp/lsp/lsTextDocumentItem.h"
+
+// Open, view, change, close file
+namespace TextDocumentDidOpen {
+
+ struct Params {
+ lsTextDocumentItem textDocument;
+
+
+
+ /**
+ * Legacy property to support protocol version 1.0 requests.
+ */
+ boost::optional<std::string> text;
+
+ MAKE_SWAP_METHOD(TextDocumentDidOpen::Params, textDocument, text);
+
+ };
+
+}
+MAKE_REFLECT_STRUCT(TextDocumentDidOpen::Params, textDocument, text);
+
+/**
+ * The document open notification is sent from the client to the server to
+ * signal newly opened text documents. The document's truth is now managed
+ * by the client and the server must not try to read the document's truth
+ * using the document's uri.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ */;
+
+
+DEFINE_NOTIFICATION_TYPE(Notify_TextDocumentDidOpen, TextDocumentDidOpen::Params, "textDocument/didOpen");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_save.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_save.h
new file mode 100644
index 0000000000..1ce386c415
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/did_save.h
@@ -0,0 +1,31 @@
+#pragma once
+
+
+
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+
+
+namespace TextDocumentDidSave {
+
+ struct Params {
+ // The document that was saved.
+ lsTextDocumentIdentifier textDocument;
+
+ // Optional the content when saved. Depends on the includeText value
+ // when the save notifcation was requested.
+ boost::optional<std::string> text;
+
+ MAKE_SWAP_METHOD(TextDocumentDidSave::Params, textDocument, text);
+ };
+
+};
+MAKE_REFLECT_STRUCT(TextDocumentDidSave::Params, textDocument, text);
+
+/**
+ * The document save notification is sent from the client to the server when
+ * the document for saved in the client.
+ *
+ * Registration Options: TextDocumentSaveRegistrationOptions
+ */
+DEFINE_NOTIFICATION_TYPE(Notify_TextDocumentDidSave, TextDocumentDidSave::Params, "textDocument/didSave");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/documentColor.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/documentColor.h
new file mode 100644
index 0000000000..23a6d08d87
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/documentColor.h
@@ -0,0 +1,73 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/lsTextDocumentIdentifier.h"
+#include "LibLsp/lsp/lsRange.h"
+#include <vector>
+struct DocumentColorParams {
+ /**
+ * The text document.
+ */
+
+ lsTextDocumentIdentifier textDocument;
+ MAKE_SWAP_METHOD(DocumentColorParams, textDocument);
+};
+MAKE_REFLECT_STRUCT(DocumentColorParams, textDocument);
+
+/**
+ * The document color request is sent from the client to the server to list all color references found in a given text
+ * document. Along with the range, a color value in RGB is returned.
+ *
+ * Clients can use the result to decorate color references in an editor. For example:
+ * - Color boxes showing the actual color next to the reference
+ * - Show a color picker when a color reference is edited
+ *
+ * Since version 3.6.0
+ */
+
+namespace TextDocument {
+ struct Color {
+ /**
+ * The red component of this color in the range [0-1].
+ */
+ double red = 0;
+
+ /**
+ * The green component of this color in the range [0-1].
+ */
+ double green = 0;
+
+ /**
+ * The blue component of this color in the range [0-1].
+ */
+ double blue = 0;
+
+ /**
+ * The alpha component of this color in the range [0-1].
+ */
+ double alpha = 0;
+ MAKE_SWAP_METHOD(TextDocument::Color, red, green, blue, alpha)
+ };
+}
+MAKE_REFLECT_STRUCT(TextDocument::Color, red, green, blue, alpha)
+
+
+struct ColorInformation {
+ /**
+ * The range in the document where this color appers.
+ */
+
+ lsRange range;
+
+ /**
+ * The actual color value for this color range.
+ */
+
+ TextDocument::Color color;
+ MAKE_SWAP_METHOD(ColorInformation, range, color)
+};
+MAKE_REFLECT_STRUCT(ColorInformation,range,color)
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_documentColor, DocumentColorParams,std::vector<ColorInformation>, "textDocument/documentColor"); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/document_link.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/document_link.h
new file mode 100644
index 0000000000..536a625c4c
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/document_link.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+
+namespace TextDocumentDocumentLink {
+
+ struct Params {
+ // The document to provide document links for.
+ lsTextDocumentIdentifier textDocument;
+ MAKE_SWAP_METHOD(Params, textDocument)
+ };
+
+};
+MAKE_REFLECT_STRUCT(TextDocumentDocumentLink::Params, textDocument);
+
+
+
+
+// A document link is a range in a text document that links to an internal or
+// external resource, like another text document or a web site.
+struct lsDocumentLink {
+ // The range this link applies to.
+ lsRange range;
+ // The uri this link points to. If missing a resolve request is sent later.
+ boost::optional<lsDocumentUri> target;
+
+ boost::optional<lsp::Any> data;
+
+ MAKE_SWAP_METHOD(lsDocumentLink, range, target, data)
+
+};
+MAKE_REFLECT_STRUCT(lsDocumentLink, range, target,data);
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_links, TextDocumentDocumentLink::Params, lsDocumentLink, "textDocument/documentLink");
+
+
+/**
+ * The document link resolve request is sent from the client to the server to resolve the target of a given document link.
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_linkResolve, std::vector<lsDocumentLink>, lsDocumentLink, "documentLink/resolve");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/document_symbol.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/document_symbol.h
new file mode 100644
index 0000000000..8aa6e8b00e
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/document_symbol.h
@@ -0,0 +1,55 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/symbol.h"
+#include "LibLsp/lsp/lsTextDocumentIdentifier.h"
+ /**
+ * The document symbol request is sent from the client to the server to list all symbols found in a given text document.
+ */
+struct lsDocumentSymbolParams {
+ lsTextDocumentIdentifier textDocument;
+ MAKE_SWAP_METHOD(lsDocumentSymbolParams, textDocument)
+};
+MAKE_REFLECT_STRUCT(lsDocumentSymbolParams, textDocument);
+
+
+
+struct TextDocumentDocumentSymbol{
+ typedef std::pair< boost::optional<lsSymbolInformation> , boost::optional<lsDocumentSymbol> > Either;
+};
+void Reflect(Reader& visitor, TextDocumentDocumentSymbol::Either& value);
+
+
+
+/**
+ * The document symbol request is sent from the client to the server to list all
+ * symbols found in a given text document.
+ *
+ * Registration Options: {@link TextDocumentRegistrationOptions}
+ *
+ * <p>
+ * <b>Caveat</b>: although the return type allows mixing the
+ * {@link DocumentSymbol} and {@link SymbolInformation} instances into a list do
+ * not do it because the clients cannot accept a heterogeneous list. A list of
+ * {@code DocumentSymbol} instances is only a valid return value if the
+ * {@link DocumentSymbolCapabilities#getHierarchicalDocumentSymbolSupport()
+ * textDocument.documentSymbol.hierarchicalDocumentSymbolSupport} is
+ * {@code true}. More details on this difference between the LSP and the LSP4J
+ * can be found <a href="https://github.com/eclipse/lsp4j/issues/252">here</a>.
+ * </p>
+ */
+
+//DEFINE_REQUEST_RESPONSE_TYPE(td_symbol,
+// lsDocumentSymbolParams,
+// std::vector<TextDocumentDocumentSymbol::Either> );
+//
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_symbol,
+ lsDocumentSymbolParams,
+ std::vector< lsDocumentSymbol >,"textDocument/documentSymbol" );
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/foldingRange.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/foldingRange.h
new file mode 100644
index 0000000000..27977a4517
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/foldingRange.h
@@ -0,0 +1,62 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "document_symbol.h"
+#include "LibLsp/lsp/lsTextDocumentIdentifier.h"
+
+
+struct FoldingRangeRequestParams {
+ /**
+ * The text document.
+ */
+
+ lsTextDocumentIdentifier textDocument;
+ MAKE_SWAP_METHOD(FoldingRangeRequestParams, textDocument)
+};
+MAKE_REFLECT_STRUCT(FoldingRangeRequestParams, textDocument)
+
+
+struct FoldingRange {
+ /**
+ * The zero-based line number from where the folded range starts.
+ */
+ int startLine;
+
+ /**
+ * The zero-based line number where the folded range ends.
+ */
+ int endLine;
+
+ /**
+ * The zero-based character offset from where the folded range starts. If not defined, defaults
+ * to the length of the start line.
+ */
+ int startCharacter;
+
+ /**
+ * The zero-based character offset before the folded range ends. If not defined, defaults to the
+ * length of the end line.
+ */
+ int endCharacter;
+
+ /**
+ * Describes the kind of the folding range such as `comment' or 'region'. The kind
+ * is used to categorize folding ranges and used by commands like 'Fold all comments'. See
+ * FoldingRangeKind for an enumeration of standardized kinds.
+ */
+ std::string kind;
+
+ MAKE_SWAP_METHOD(FoldingRange, startLine, endLine, startCharacter, endCharacter, kind)
+};
+MAKE_REFLECT_STRUCT(FoldingRange,startLine,endLine,startCharacter,endCharacter,kind)
+
+
+/**
+ * The folding range request is sent from the client to the server to return all folding
+ * ranges found in a given text document.
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_foldingRange, FoldingRangeRequestParams, std::vector<FoldingRange>, "textDocument/foldingRange");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/formatting.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/formatting.h
new file mode 100644
index 0000000000..ad54e24bf9
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/formatting.h
@@ -0,0 +1,32 @@
+#pragma once
+#include "LibLsp/lsp/lsFormattingOptions.h"
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+
+namespace TextDocumentFormatting {
+
+ struct Params {
+ /**
+ * The document to format.
+ */
+ lsTextDocumentIdentifier textDocument;
+ /**
+ * The format options.
+ */
+ lsFormattingOptions options;
+ MAKE_SWAP_METHOD(Params, textDocument, options);
+ };
+
+};
+MAKE_REFLECT_STRUCT(TextDocumentFormatting::Params, textDocument, options);
+/**
+ * The document formatting request is sent from the client to the server to
+ * format a whole document.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_formatting, TextDocumentFormatting::Params,
+ std::vector<lsTextEdit>, "textDocument/formatting");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/highlight.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/highlight.h
new file mode 100644
index 0000000000..332baf69e1
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/highlight.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include "LibLsp/lsp/lsTextDocumentPositionParams.h"
+#include "document_symbol.h"
+
+/**
+ * The references request is sent from the client to the server to resolve
+ * project-wide references for the symbol denoted by the given text document
+ * position.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ */
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_highlight, lsTextDocumentPositionParams,
+ std::vector<lsDocumentHighlight>, "textDocument/documentHighlight");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/hover.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/hover.h
new file mode 100644
index 0000000000..5302316c6f
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/hover.h
@@ -0,0 +1,55 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/lsMarkedString.h"
+#include "LibLsp/lsp/lsTextDocumentPositionParams.h"
+#include "LibLsp/lsp/lsRange.h"
+/**
+ * The hover request is sent from the client to the server to request hover
+ * information at a given text document position.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ */
+
+namespace TextDocumentHover
+{
+ typedef boost::optional< std::vector< std::pair<boost::optional<std::string>, boost::optional<lsMarkedString>> > > Left;
+ typedef std::pair< Left, boost::optional<MarkupContent> > Either;
+ struct Result {
+ /**
+ * The hover's content as markdown
+ */
+ Either contents;
+
+ /**
+ * An boost::optional range
+ */
+ boost::optional<lsRange> range;
+
+ MAKE_SWAP_METHOD(Result, contents, range)
+ };
+}
+MAKE_REFLECT_STRUCT(TextDocumentHover::Result, contents, range);
+
+extern void Reflect(Reader& visitor, std::pair<boost::optional<std::string>, boost::optional<lsMarkedString>>& value);
+extern void Reflect(Reader& visitor, TextDocumentHover::Either& value);
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_hover, lsTextDocumentPositionParams, TextDocumentHover::Result, "textDocument/hover")
+
+//struct Rsp_TextDocumentHover : ResponseMessage< TextDocumentHover::Result, Rsp_TextDocumentHover> {
+//
+//};
+//MAKE_REFLECT_STRUCT(Rsp_TextDocumentHover,
+// jsonrpc,
+// id,
+// result);
+
+//MAKE_REFLECT_STRUCT_OPTIONALS_MANDATORY(Rsp_TextDocumentHover,
+// jsonrpc,
+// id,
+// result);
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/implementation.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/implementation.h
new file mode 100644
index 0000000000..0d7851cb81
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/implementation.h
@@ -0,0 +1,16 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/lsp/out_list.h"
+
+
+/**
+ * The goto implementation request is sent from the client to the server to resolve
+ * the implementation location of a symbol at a given text document position.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ *
+ * Since version 3.6.0
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_implementation, lsTextDocumentPositionParams, LocationListEither::Either, "textDocument/implementation"); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/linkedEditingRange.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/linkedEditingRange.h
new file mode 100644
index 0000000000..e4055d359f
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/linkedEditingRange.h
@@ -0,0 +1,51 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include "LibLsp/lsp/lsAny.h"
+#include "LibLsp/lsp/symbol.h"
+#include "LibLsp/lsp/lsTextDocumentPositionParams.h"
+#include "LibLsp/lsp/lsRange.h"
+
+
+
+struct LinkedEditingRangeParams
+{
+ lsTextDocumentIdentifier textDocument;
+ lsPosition position;
+
+ MAKE_SWAP_METHOD(LinkedEditingRangeParams,
+ textDocument,
+ position)
+};
+MAKE_REFLECT_STRUCT(LinkedEditingRangeParams,
+ textDocument,
+ position)
+
+
+struct LinkedEditingRanges
+{
+ /**
+ * A list of ranges that can be renamed together. The ranges must have
+ * identical length and contain identical text content. The ranges cannot overlap.
+ */
+ std::vector<lsRange> ranges;
+
+ /**
+ * An optional word pattern (regular expression) that describes valid contents for
+ * the given ranges. If no pattern is provided, the client configuration's word
+ * pattern will be used.
+ */
+
+ boost::optional<std::string> wordPattern;
+ MAKE_SWAP_METHOD(LinkedEditingRanges,
+ ranges,
+ wordPattern)
+};
+
+MAKE_REFLECT_STRUCT(LinkedEditingRanges,
+ ranges,
+ wordPattern)
+DEFINE_REQUEST_RESPONSE_TYPE(td_linkedEditingRange, LinkedEditingRangeParams,
+ boost::optional<std::vector<LinkedEditingRanges >>,"textDocument/linkedEditingRange") \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/onTypeFormatting.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/onTypeFormatting.h
new file mode 100644
index 0000000000..df14ea5d3d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/onTypeFormatting.h
@@ -0,0 +1,44 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/lsFormattingOptions.h"
+#include "LibLsp/lsp/lsTextDocumentIdentifier.h"
+#include "LibLsp/lsp/lsRange.h"
+#include "LibLsp/lsp/lsTextEdit.h"
+
+
+struct lsDocumentOnTypeFormattingParams
+{
+ lsTextDocumentIdentifier textDocument;
+ lsFormattingOptions options;
+
+ lsPosition position;
+
+ /**
+ * The character that has been typed.
+ */
+
+ std::string ch;
+
+ MAKE_SWAP_METHOD(lsDocumentOnTypeFormattingParams,
+ textDocument,
+ position,
+ options, ch);
+};
+MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingParams,
+ textDocument,
+ position,
+ options,ch);
+
+/**
+ * The document range formatting request is sent from the client to the
+ * server to format a given range in a document.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_onTypeFormatting,
+ lsDocumentOnTypeFormattingParams, std::vector<lsTextEdit>, "textDocument/onTypeFormatting");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/prepareRename.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/prepareRename.h
new file mode 100644
index 0000000000..8c653d9864
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/prepareRename.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/lsWorkspaceEdit.h"
+#include "LibLsp/lsp/lsTextDocumentPositionParams.h"
+
+/**
+ * The rename request is sent from the client to the server to do a
+ * workspace wide rename of a symbol.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ */
+struct PrepareRenameResult{
+ /**
+ * The range of the string to rename
+ */
+
+ lsRange range;
+
+/**
+ * A placeholder text of the string content to be renamed.
+ */
+
+ std::string placeholder;
+
+ MAKE_SWAP_METHOD(PrepareRenameResult, range, placeholder)
+
+};
+MAKE_REFLECT_STRUCT(PrepareRenameResult,range,placeholder)
+
+
+
+typedef std::pair< boost::optional< lsRange>, boost::optional<PrepareRenameResult>> TextDocumentPrepareRenameResult;
+extern void Reflect(Reader& visitor, TextDocumentPrepareRenameResult& value);
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_prepareRename,
+ lsTextDocumentPositionParams, TextDocumentPrepareRenameResult, "textDocument/prepareRename"); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/publishDiagnostics.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/publishDiagnostics.h
new file mode 100644
index 0000000000..bf28104bbb
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/publishDiagnostics.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+#include "LibLsp/lsp/lsp_diagnostic.h"
+
+// Diagnostics
+namespace TextDocumentPublishDiagnostics{
+ struct Params {
+ // The URI for which diagnostic information is reported.
+ lsDocumentUri uri;
+
+ // An array of diagnostic information items.
+ std::vector<lsDiagnostic> diagnostics;
+ MAKE_SWAP_METHOD(Params,uri,diagnostics);
+ };
+
+
+};
+MAKE_REFLECT_STRUCT(TextDocumentPublishDiagnostics::Params,
+ uri,
+ diagnostics);
+
+/**
+ * Diagnostics notifications are sent from the server to the client to
+ * signal results of validation runs.
+ */
+DEFINE_NOTIFICATION_TYPE(Notify_TextDocumentPublishDiagnostics, TextDocumentPublishDiagnostics::Params, "textDocument/publishDiagnostics");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/range_formatting.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/range_formatting.h
new file mode 100644
index 0000000000..b2fe750af1
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/range_formatting.h
@@ -0,0 +1,35 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/lsFormattingOptions.h"
+
+
+struct lsTextDocumentRangeFormattingParams {
+ lsTextDocumentIdentifier textDocument;
+ lsRange range;
+ lsFormattingOptions options;
+
+ MAKE_SWAP_METHOD(lsTextDocumentRangeFormattingParams,
+ textDocument,
+ range,
+ options)
+};
+MAKE_REFLECT_STRUCT(lsTextDocumentRangeFormattingParams,
+ textDocument,
+ range,
+ options);
+
+/**
+ * The document range formatting request is sent from the client to the
+ * server to format a given range in a document.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_rangeFormatting, lsTextDocumentRangeFormattingParams, std::vector<lsTextEdit>,
+ "textDocument/rangeFormatting");
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/references.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/references.h
new file mode 100644
index 0000000000..2376912756
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/references.h
@@ -0,0 +1,48 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/symbol.h"
+
+
+namespace TextDocumentReferences {
+
+ struct lsReferenceContext {
+ // Include the declaration of the current symbol.
+ boost::optional<bool> includeDeclaration;
+ MAKE_REFLECT_STRUCT(lsReferenceContext,
+ includeDeclaration)
+ };
+ struct Params {
+ lsTextDocumentIdentifier textDocument;
+ lsPosition position;
+ lsReferenceContext context;
+ MAKE_SWAP_METHOD(Params,
+ textDocument,
+ position,
+ context)
+
+ };
+
+};
+MAKE_REFLECT_STRUCT(TextDocumentReferences::lsReferenceContext,
+ includeDeclaration);
+MAKE_REFLECT_STRUCT(TextDocumentReferences::Params,
+ textDocument,
+ position,
+ context);
+
+
+
+
+/**
+ * The references request is sent from the client to the server to resolve
+ * project-wide references for the symbol denoted by the given text document
+ * position.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_references, TextDocumentReferences::Params,
+ std::vector<lsLocation>, "textDocument/references");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/rename.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/rename.h
new file mode 100644
index 0000000000..35895f0f4f
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/rename.h
@@ -0,0 +1,41 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/lsWorkspaceEdit.h"
+#include "LibLsp/lsp/lsTextDocumentIdentifier.h"
+
+namespace TextDocumentRename {
+
+ struct Params {
+ // The document to format.
+ lsTextDocumentIdentifier textDocument;
+
+ // The position at which this request was sent.
+ lsPosition position;
+
+ // The new name of the symbol. If the given name is not valid the
+ // request must return a [ResponseError](#ResponseError) with an
+ // appropriate message set.
+ std::string newName;
+ MAKE_SWAP_METHOD(Params,
+ textDocument,
+ position,
+ newName);
+ };
+
+};
+MAKE_REFLECT_STRUCT(TextDocumentRename::Params,
+ textDocument,
+ position,
+ newName);
+/**
+ * The rename request is sent from the client to the server to do a
+ * workspace wide rename of a symbol.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_rename, TextDocumentRename::Params, lsWorkspaceEdit, "textDocument/rename");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveCodeLens.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveCodeLens.h
new file mode 100644
index 0000000000..0723985160
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveCodeLens.h
@@ -0,0 +1,10 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "code_lens.h"
+
+DEFINE_REQUEST_RESPONSE_TYPE(codeLens_resolve, lsCodeLens, lsCodeLens, "codeLens/resolve")
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveCompletionItem.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveCompletionItem.h
new file mode 100644
index 0000000000..f5576894ed
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveCompletionItem.h
@@ -0,0 +1,21 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include <regex>
+#include "LibLsp/lsp/lsp_completion.h"
+#include "LibLsp/lsp/lsTextDocumentPositionParams.h"
+#include "completion.h"
+
+/**
+ * The request is sent from the client to the server to resolve additional
+ * information for a given completion item.
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(completionItem_resolve, lsCompletionItem, lsCompletionItem, "completionItem/resolve");
+
+
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveTypeHierarchy.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveTypeHierarchy.h
new file mode 100644
index 0000000000..eab5f838fc
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/resolveTypeHierarchy.h
@@ -0,0 +1,31 @@
+#pragma once
+
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/symbol.h"
+#include "typeHierarchy.h"
+
+struct ResolveTypeHierarchyItemParams {
+ /**
+ * The hierarchy item to resolve.
+ */
+
+ TypeHierarchyItem item;
+
+ /**
+ * The number of hierarchy levels to resolve. {@code 0} indicates no hierarchy level.
+ */
+ boost::optional<int> resolve;
+
+ /**
+ * The direction of the type hierarchy resolution.
+ */
+
+ TypeHierarchyDirection direction;
+ MAKE_SWAP_METHOD(ResolveTypeHierarchyItemParams, item, resolve, direction)
+};
+MAKE_REFLECT_STRUCT(ResolveTypeHierarchyItemParams,item,resolve,direction)
+DEFINE_REQUEST_RESPONSE_TYPE(typeHierarchy_resolve, ResolveTypeHierarchyItemParams, TypeHierarchyItem, "typeHierarchy/resolve")
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/selectionRange.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/selectionRange.h
new file mode 100644
index 0000000000..47590e4152
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/selectionRange.h
@@ -0,0 +1,52 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/lsPosition.h"
+#include "LibLsp/lsp/lsTextDocumentIdentifier.h"
+
+struct SelectionRangeParams {
+ /**
+ * The text document.
+ */
+
+ lsTextDocumentIdentifier textDocument;
+
+ /**
+ * The positions inside the text document.
+ */
+
+ std::vector<lsPosition> positions;
+
+ MAKE_SWAP_METHOD(SelectionRangeParams, textDocument, positions)
+
+};
+MAKE_REFLECT_STRUCT(SelectionRangeParams, textDocument, positions)
+
+struct SelectionRange {
+ /**
+ * The [range](#Range) of this selection range.
+ */
+
+ lsRange range;
+
+ /**
+ * The parent selection range containing this range. Therefore `parent.range` must contain `this.range`.
+ */
+ boost::optional<SelectionRange*> parent;
+ MAKE_SWAP_METHOD(SelectionRange, range, parent)
+};
+
+extern void Reflect(Reader& visitor, boost::optional<SelectionRange*>& value);
+extern void Reflect(Writer& visitor, SelectionRange* value);
+
+MAKE_REFLECT_STRUCT(SelectionRange,range,parent)
+/**
+ * The {@code textDocument/selectionRange} request is sent from the client to the server to return
+ * suggested selection ranges at an array of given positions. A selection range is a range around
+ * the cursor position which the user might be interested in selecting.
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_selectionRange, SelectionRangeParams, std::vector<SelectionRange>, "textDocument/selectionRange");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/semanticHighlighting.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/semanticHighlighting.h
new file mode 100644
index 0000000000..32bc86f5fb
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/semanticHighlighting.h
@@ -0,0 +1,66 @@
+#pragma once
+#include "LibLsp/lsp/lsDocumentUri.h"
+#include "LibLsp/lsp/lsVersionedTextDocumentIdentifier.h"
+
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+/**
+ * Represents a semantic highlighting information that has to be applied on a specific line of the text document.
+ */
+
+struct SemanticHighlightingInformation {
+ /**
+ * The zero-based line position in the text document.
+ */
+ int line = 0;
+
+ /**
+ * A base64 encoded string representing every single highlighted ranges in the line with its start position, length
+ * and the "lookup table" index of of the semantic highlighting <a href="https://manual.macromates.com/en/language_grammars">
+ * TextMate scopes</a>. If the {@code tokens} is empty or not defined, then no highlighted positions are available for the line.
+ */
+ std::string tokens;
+
+ MAKE_SWAP_METHOD(SemanticHighlightingInformation, line, tokens)
+};
+
+MAKE_REFLECT_STRUCT(SemanticHighlightingInformation, line, tokens);
+
+/**
+ * Parameters for the semantic highlighting (server-side) push notification.
+ */
+
+struct SemanticHighlightingParams {
+ /**
+ * The text document that has to be decorated with the semantic highlighting information.
+ */
+
+ lsVersionedTextDocumentIdentifier textDocument;
+
+ /**
+ * An array of semantic highlighting information.
+ */
+
+ std::vector<SemanticHighlightingInformation> lines;
+
+ MAKE_SWAP_METHOD(SemanticHighlightingParams, textDocument, lines)
+
+};
+MAKE_REFLECT_STRUCT(SemanticHighlightingParams, textDocument, lines);
+/**
+ * The {@code textDocument/semanticHighlighting} notification is pushed from the server to the client
+ * to inform the client about additional semantic highlighting information that has to be applied
+ * on the text document. It is the server's responsibility to decide which lines are included in
+ * the highlighting information. In other words, the server is capable of sending only a delta
+ * information. For instance, after opening the text document ({@code DidOpenTextDocumentNotification})
+ * the server sends the semantic highlighting information for the entire document, but if the server
+ * receives a {@code DidChangeTextDocumentNotification}, it pushes the information only about
+ * the affected lines in the document.
+ *
+ * <p>
+ * <b>Note:</b> the <a href=
+ * "https://github.com/Microsoft/vscode-languageserver-node/pull/367">{@code textDocument/semanticHighlighting}
+ * language feature</a> is not yet part of the official LSP specification.
+ */
+DEFINE_NOTIFICATION_TYPE(Notify_semanticHighlighting, SemanticHighlightingParams, "textDocument/semanticHighlighting"); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/signature_help.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/signature_help.h
new file mode 100644
index 0000000000..2a83645901
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/signature_help.h
@@ -0,0 +1,92 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include "LibLsp/lsp/lsMarkedString.h"
+#include "LibLsp/lsp/lsTextDocumentPositionParams.h"
+
+extern void Reflect(Reader& visitor,
+ std::pair<boost::optional<std::string>, boost::optional<MarkupContent>>& value);
+
+
+
+// Represents a parameter of a callable-signature. A parameter can
+// have a label and a doc-comment.
+struct lsParameterInformation {
+ // The label of this parameter. Will be shown in
+ // the UI.
+ std::string label;
+
+ // The human-readable doc-comment of this parameter. Will be shown
+ // in the UI but can be omitted.
+ boost::optional< std::pair< boost::optional<std::string> , boost::optional <MarkupContent> > > documentation;
+
+ MAKE_SWAP_METHOD(lsParameterInformation, label, documentation)
+};
+MAKE_REFLECT_STRUCT(lsParameterInformation, label, documentation);
+
+// Represents the signature of something callable. A signature
+// can have a label, like a function-name, a doc-comment, and
+// a set of parameters.
+struct lsSignatureInformation {
+ // The label of this signature. Will be shown in
+ // the UI.
+ std::string label;
+
+ // The human-readable doc-comment of this signature. Will be shown
+ // in the UI but can be omitted.
+ boost::optional< std::pair< boost::optional<std::string>, boost::optional <MarkupContent> > > documentation;
+
+ // The parameters of this signature.
+ std::vector<lsParameterInformation> parameters;
+
+ MAKE_SWAP_METHOD(lsSignatureInformation, label, documentation, parameters)
+};
+MAKE_REFLECT_STRUCT(lsSignatureInformation, label, documentation, parameters);
+
+// Signature help represents the signature of something
+// callable. There can be multiple signature but only one
+// active and only one active parameter.
+struct lsSignatureHelp {
+ // One or more signatures.
+ std::vector<lsSignatureInformation> signatures;
+
+ // The active signature. If omitted or the value lies outside the
+ // range of `signatures` the value defaults to zero or is ignored if
+ // `signatures.length === 0`. Whenever possible implementors should
+ // make an active decision about the active signature and shouldn't
+ // rely on a default value.
+ // In future version of the protocol this property might become
+ // mandantory to better express this.
+ boost::optional<int> activeSignature;
+
+ // The active parameter of the active signature. If omitted or the value
+ // lies outside the range of `signatures[activeSignature].parameters`
+ // defaults to 0 if the active signature has parameters. If
+ // the active signature has no parameters it is ignored.
+ // In future version of the protocol this property might become
+ // mandantory to better express the active parameter if the
+ // active signature does have any.
+ boost::optional<int> activeParameter;
+
+
+ MAKE_SWAP_METHOD(lsSignatureHelp,
+ signatures,
+ activeSignature,
+ activeParameter)
+};
+MAKE_REFLECT_STRUCT(lsSignatureHelp,
+ signatures,
+ activeSignature,
+ activeParameter);
+
+
+
+/**
+ * The signature help request is sent from the client to the server to
+ * request signature information at a given cursor position.
+ *
+ * Registration Options: SignatureHelpRegistrationOptions
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_signatureHelp, lsTextDocumentPositionParams, lsSignatureHelp, "textDocument/signatureHelp"); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/textDocument.cpp b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/textDocument.cpp
new file mode 100644
index 0000000000..32f647436d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/textDocument.cpp
@@ -0,0 +1,349 @@
+#include "completion.h"
+#include "document_symbol.h"
+#include "LibLsp/lsp/lsMarkedString.h"
+#include "hover.h"
+#include "prepareRename.h"
+#include <LibLsp/lsp/textDocument/typeHierarchy.h>
+
+#include "semanticHighlighting.h"
+#include "SemanticTokens.h"
+#include "LibLsp/JsonRpc/json.h"
+
+
+constexpr unsigned SemanticTokenEncodingSize = 5;
+
+std::string to_string(SemanticTokenType _type)
+{
+ switch (_type) {
+
+ case ls_namespace: return "namespace";
+ /**
+ * Represents a generic type. Acts as a fallback for types which
+ * can"t be mapped to a specific type like class or enum.
+ */
+ case ls_type: return "type";
+ case ls_class: return "class";
+ case ls_enum: return "enum";
+ case ls_interface: return "interface";
+ case ls_struct: return "struct";
+ case ls_typeParameter: return "typeParameter";
+ case ls_parameter: return "parameter";
+ case ls_variable: return "variable";
+ case ls_property: return "property";
+ case ls_enumMember: return "enumMember";
+ case ls_event: return "event";
+ case ls_function: return "function";
+ case ls_method: return "method";
+ case ls_macro: return "macro";
+ case ls_keyword: return "keyword";
+ case ls_modifier: return "modifier";
+ case ls_comment: return "comment";
+ case ls_string: return "string";
+ case ls_number: return "number";
+ case ls_regexp: return "regexp";
+ case ls_operator: return "operator";
+ default:
+ return "unknown";
+ }
+}
+
+unsigned toSemanticTokenType(std::vector<SemanticTokenType>& modifiers)
+{
+ unsigned encode_type = 0;
+ for (auto bit : modifiers) {
+ encode_type = encode_type | (0b00000001 << bit);
+ }
+ return encode_type;
+}
+
+std::string to_string(TokenType_JDT _type)
+{
+ switch (_type)
+ {
+ case PACKAGE_JDT:return "namespace";
+ case CLASS_JDT:return "class";
+ case INTERFACE_JDT:return "interface";
+ case ENUM_JDT:return "enum";
+ case ENUM_MEMBER_JDT:return "enumMember";
+ case TYPE_JDT:return "type";
+ case TYPE_PARAMETER_JDT:return "typeParameter";
+ case ANNOTATION_JDT:return "annotation";
+ case ANNOTATION_MEMBER_JDT:return "annotationMember";
+ case METHOD_JDT:return "function";
+ case PROPERTY_JDT:return "property";
+ case VARIABLE_JDT:return "variable";
+ case PARAMETER_JDT:return "parameter";
+ }
+ return "unknown";
+}
+
+std::string to_string(SemanticTokenModifier modifier)
+{
+ switch (modifier) {
+ case ls_declaration: return "declaration";
+ case ls_definition: return "definition";
+ case ls_readonly: return "readonly";
+ case ls_static: return "static";
+ case ls_deprecated: return "deprecated";
+ case ls_abstract: return "abstract";
+ case ls_async: return "async";
+ case ls_modification: return "modification";
+ case ls_documentation: return "documentation";
+ case ls_defaultLibrary: return "defaultLibrary";
+ default:
+ return "unknown";
+ }
+}
+
+unsigned toSemanticTokenModifiers(std::vector<SemanticTokenModifier>& modifiers)
+{
+ unsigned encodedModifiers = 0;
+ for (auto bit : modifiers) {
+ encodedModifiers = encodedModifiers | (0b00000001 << bit);
+ }
+ return encodedModifiers;
+}
+
+
+std::string toSemanticTokenType(HighlightingKind_clangD kind) {
+ switch (kind) {
+ case HighlightingKind_clangD::Variable:
+ case HighlightingKind_clangD::LocalVariable:
+ case HighlightingKind_clangD::StaticField:
+ return "variable";
+ case HighlightingKind_clangD::Parameter:
+ return "parameter";
+ case HighlightingKind_clangD::Function:
+ return "function";
+ case HighlightingKind_clangD::Method:
+ return "method";
+ case HighlightingKind_clangD::StaticMethod:
+ // FIXME: better method with static modifier?
+ return "function";
+ case HighlightingKind_clangD::Field:
+ return "property";
+ case HighlightingKind_clangD::Class:
+ return "class";
+ case HighlightingKind_clangD::Interface:
+ return "interface";
+ case HighlightingKind_clangD::Enum:
+ return "enum";
+ case HighlightingKind_clangD::EnumConstant:
+ return "enumMember";
+ case HighlightingKind_clangD::Typedef:
+ case HighlightingKind_clangD::Type:
+ return "type";
+ case HighlightingKind_clangD::Unknown:
+ return "unknown"; // nonstandard
+ case HighlightingKind_clangD::Namespace:
+ return "namespace";
+ case HighlightingKind_clangD::TemplateParameter:
+ return "typeParameter";
+ case HighlightingKind_clangD::Concept:
+ return "concept"; // nonstandard
+ case HighlightingKind_clangD::Primitive:
+ return "type";
+ case HighlightingKind_clangD::Macro:
+ return "macro";
+ case HighlightingKind_clangD::InactiveCode:
+ return "comment";
+ }
+ return ("unhandled HighlightingKind_clangD");
+}
+
+std::string toSemanticTokenModifier(HighlightingModifier_clangD modifier) {
+ switch (modifier) {
+ case HighlightingModifier_clangD::Declaration:
+ return "declaration";
+ case HighlightingModifier_clangD::Deprecated:
+ return "deprecated";
+ case HighlightingModifier_clangD::Readonly:
+ return "readonly";
+ case HighlightingModifier_clangD::Static:
+ return "static";
+ case HighlightingModifier_clangD::Deduced:
+ return "deduced"; // nonstandard
+ case HighlightingModifier_clangD::Abstract:
+ return "abstract";
+ case HighlightingModifier_clangD::DependentName:
+ return "dependentName"; // nonstandard
+ case HighlightingModifier_clangD::DefaultLibrary:
+ return "defaultLibrary";
+ case HighlightingModifier_clangD::FunctionScope:
+ return "functionScope"; // nonstandard
+ case HighlightingModifier_clangD::ClassScope:
+ return "classScope"; // nonstandard
+ case HighlightingModifier_clangD::FileScope:
+ return "fileScope"; // nonstandard
+ case HighlightingModifier_clangD::GlobalScope:
+ return "globalScope"; // nonstandard
+ }
+ return ("unhandled HighlightingModifier_clangD");
+}
+
+
+
+bool operator==(const SemanticToken& l, const SemanticToken& r) {
+ return std::tie(l.deltaLine, l.deltaStart, l.length, l.tokenType,
+ l.tokenModifiers) == std::tie(r.deltaLine, r.deltaStart,
+ r.length, r.tokenType,
+ r.tokenModifiers);
+}
+
+std::vector<int32_t> SemanticTokens::encodeTokens(std::vector<SemanticToken>& tokens)
+{
+ std::vector<int32_t> result;
+ result.reserve(SemanticTokenEncodingSize * tokens.size());
+ for (const auto& tok : tokens)
+ {
+ result.push_back(tok.deltaLine);
+ result.push_back(tok.deltaStart);
+ result.push_back(tok.length);
+ result.push_back(tok.tokenType);
+ result.push_back(tok.tokenModifiers);
+ }
+ assert(result.size() == SemanticTokenEncodingSize * tokens.size());
+ return result;
+}
+
+void Reflect(Reader& visitor, TextDocumentComplete::Either& value)
+{
+ if(visitor.IsArray())
+ {
+ Reflect(visitor, value.first);
+ }
+ else
+ {
+
+ Reflect(visitor, value.second);
+ }
+
+}
+void Reflect(Reader& visitor, TextDocumentDocumentSymbol::Either& value)
+{
+ if (visitor.HasMember("location"))
+ {
+ Reflect(visitor, value.first);
+ }
+ else
+ {
+ Reflect(visitor, value.second);
+ }
+}
+
+void Reflect(Reader& visitor, std::pair<boost::optional<std::string>, boost::optional<lsMarkedString>>& value)
+{
+
+ if (!visitor.IsString())
+ {
+ Reflect(visitor, value.second);
+ }
+ else
+ {
+ Reflect(visitor, value.first);
+ }
+}
+
+void Reflect(Reader& visitor, std::pair<boost::optional<std::string>, boost::optional<MarkupContent>>& value)
+{
+ if (!visitor.IsString())
+ {
+ Reflect(visitor, value.second);
+ }
+ else
+ {
+ Reflect(visitor, value.first);
+ }
+}
+ void Reflect(Reader& visitor, TextDocumentHover::Either& value)
+{
+ JsonReader& reader = dynamic_cast<JsonReader&>(visitor);
+ if (reader.IsArray())
+ {
+ Reflect(visitor, value.first);
+ }
+ else if(reader.m_->IsObject())
+ {
+ Reflect(visitor, value.second);
+ }
+}
+
+ void Reflect(Reader& visitor, TextDocumentPrepareRenameResult& value)
+{
+ if (visitor.HasMember("placeholder"))
+ {
+ Reflect(visitor, value.second);
+ }
+ else
+ {
+ Reflect(visitor, value.first);
+ }
+}
+
+ namespace
+ RefactorProposalUtility
+ {
+ const char* APPLY_REFACTORING_COMMAND_ID = "java.action.applyRefactoringCommand";
+ const char* EXTRACT_VARIABLE_ALL_OCCURRENCE_COMMAND = "extractVariableAllOccurrence";
+ const char* EXTRACT_VARIABLE_COMMAND = "extractVariable";
+ const char* EXTRACT_CONSTANT_COMMAND = "extractConstant";
+ const char* EXTRACT_METHOD_COMMAND = "extractMethod";
+ const char* EXTRACT_FIELD_COMMAND = "extractField";
+ const char* CONVERT_VARIABLE_TO_FIELD_COMMAND = "convertVariableToField";
+ const char* MOVE_FILE_COMMAND = "moveFile";
+ const char* MOVE_INSTANCE_METHOD_COMMAND = "moveInstanceMethod";
+ const char* MOVE_STATIC_MEMBER_COMMAND = "moveStaticMember";
+ const char* MOVE_TYPE_COMMAND = "moveType";
+ };
+ namespace QuickAssistProcessor {
+
+ const char* SPLIT_JOIN_VARIABLE_DECLARATION_ID = "org.eclipse.jdt.ls.correction.splitJoinVariableDeclaration.assist"; //$NON-NLS-1$
+ const char* CONVERT_FOR_LOOP_ID = "org.eclipse.jdt.ls.correction.convertForLoop.assist"; //$NON-NLS-1$
+ const char* ASSIGN_TO_LOCAL_ID = "org.eclipse.jdt.ls.correction.assignToLocal.assist"; //$NON-NLS-1$
+ const char* ASSIGN_TO_FIELD_ID = "org.eclipse.jdt.ls.correction.assignToField.assist"; //$NON-NLS-1$
+ const char* ASSIGN_PARAM_TO_FIELD_ID = "org.eclipse.jdt.ls.correction.assignParamToField.assist"; //$NON-NLS-1$
+ const char* ASSIGN_ALL_PARAMS_TO_NEW_FIELDS_ID = "org.eclipse.jdt.ls.correction.assignAllParamsToNewFields.assist"; //$NON-NLS-1$
+ const char* ADD_BLOCK_ID = "org.eclipse.jdt.ls.correction.addBlock.assist"; //$NON-NLS-1$
+ const char* EXTRACT_LOCAL_ID = "org.eclipse.jdt.ls.correction.extractLocal.assist"; //$NON-NLS-1$
+ const char* EXTRACT_LOCAL_NOT_REPLACE_ID = "org.eclipse.jdt.ls.correction.extractLocalNotReplaceOccurrences.assist"; //$NON-NLS-1$
+ const char* EXTRACT_CONSTANT_ID = "org.eclipse.jdt.ls.correction.extractConstant.assist"; //$NON-NLS-1$
+ const char* INLINE_LOCAL_ID = "org.eclipse.jdt.ls.correction.inlineLocal.assist"; //$NON-NLS-1$
+ const char* CONVERT_LOCAL_TO_FIELD_ID = "org.eclipse.jdt.ls.correction.convertLocalToField.assist"; //$NON-NLS-1$
+ const char* CONVERT_ANONYMOUS_TO_LOCAL_ID = "org.eclipse.jdt.ls.correction.convertAnonymousToLocal.assist"; //$NON-NLS-1$
+ const char* CONVERT_TO_STRING_BUFFER_ID = "org.eclipse.jdt.ls.correction.convertToStringBuffer.assist"; //$NON-NLS-1$
+ const char* CONVERT_TO_MESSAGE_FORMAT_ID = "org.eclipse.jdt.ls.correction.convertToMessageFormat.assist"; //$NON-NLS-1$;
+ const char* EXTRACT_METHOD_INPLACE_ID = "org.eclipse.jdt.ls.correction.extractMethodInplace.assist"; //$NON-NLS-1$;
+
+ const char* CONVERT_ANONYMOUS_CLASS_TO_NESTED_COMMAND = "convertAnonymousClassToNestedCommand";
+ };
+
+ void Reflect(Reader& reader, TypeHierarchyDirection& value) {
+ if (!reader.IsString())
+ {
+ value = TypeHierarchyDirection::Both;
+ return;
+ }
+ std::string v = reader.GetString();
+ if (v == "Children")
+ value = TypeHierarchyDirection::Both;
+ else if (v == "Parents")
+ value = TypeHierarchyDirection::Parents;
+ else if (v == "Both")
+ value = TypeHierarchyDirection::Both;
+ }
+
+
+ void Reflect(Writer& writer, TypeHierarchyDirection& value) {
+ switch (value)
+ {
+ case TypeHierarchyDirection::Children:
+ writer.String("Children");
+ break;
+ case TypeHierarchyDirection::Parents:
+ writer.String("Parents");
+ break;
+ case TypeHierarchyDirection::Both:
+ writer.String("Both");
+ break;
+ }
+ }
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/typeHierarchy.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/typeHierarchy.h
new file mode 100644
index 0000000000..b554d751f3
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/typeHierarchy.h
@@ -0,0 +1,133 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+#include "LibLsp/lsp/lsTextDocumentPositionParams.h"
+#include "LibLsp/lsp/symbol.h"
+#include "LibLsp/lsp/lsAny.h"
+/**
+ * The {@code textDocument/typeHierarchy} request is sent from the client to the
+ * server to retrieve a {@link TypeHierarchyItem type hierarchy item} based on
+ * the {@link TypeHierarchyParams cursor position in the text document}. This
+ * request would also allow to specify if the item should be resolved and
+ * whether sub- or supertypes are to be resolved. If no type hierarchy item can
+ * be found under the given text document position, resolves to {@code null}.
+ *
+ * <p>
+ * <b>Note:</b> the <a href=
+ * "https://github.com/Microsoft/vscode-languageserver-node/pull/426">{@code textDocument/typeHierarchy}
+ * language feature</a> is not yet part of the official LSP specification.
+ */
+enum class TypeHierarchyDirection : uint32_t{
+
+ /**
+ * Flag for retrieving/resolving the subtypes. Value: {@code 0}.
+ */
+ Children = 0,
+
+ /**
+ * Flag to use when retrieving/resolving the supertypes. Value: {@code 1}.
+ */
+ Parents =1,
+
+ /**
+ * Flag for resolving both the super- and subtypes. Value: {@code 2}.
+ */
+ Both=2
+};
+void Reflect(Reader& reader, TypeHierarchyDirection& value);
+
+
+void Reflect(Writer& writer, TypeHierarchyDirection& value);
+
+struct TypeHierarchyParams :public lsTextDocumentPositionParams
+{
+ boost::optional<int> resolve;
+ boost::optional<TypeHierarchyDirection> direction ;
+
+ MAKE_SWAP_METHOD(TypeHierarchyParams, textDocument, position, resolve, direction)
+};
+MAKE_REFLECT_STRUCT(TypeHierarchyParams, textDocument, position, resolve, direction);
+
+
+
+
+
+/**
+ * Representation of an item that carries type information (such as class, interface, enumeration, etc) with additional parentage details.
+ */
+
+struct TypeHierarchyItem {
+ /**
+ * The human readable name of the hierarchy item.
+ */
+
+ std::string name;
+
+ /**
+ * Optional detail for the hierarchy item. It can be, for instance, the signature of a function or method.
+ */
+ boost::optional<std::string>
+ detail;
+
+ /**
+ * The kind of the hierarchy item. For instance, class or interface.
+ */
+
+ SymbolKind kind;
+
+ /**
+ * {@code true} if the hierarchy item is deprecated. Otherwise, {@code false}. It is {@code false} by default.
+ */
+
+ boost::optional<bool> deprecated;
+
+ /**
+ * The URI of the text document where this type hierarchy item belongs to.
+ */
+
+ lsDocumentUri uri;
+
+ /**
+ * The range enclosing this type hierarchy item not including leading/trailing whitespace but everything else
+ * like comments. This information is typically used to determine if the clients cursor is inside the type
+ * hierarchy item to reveal in the symbol in the UI.
+ *
+ * @see TypeHierarchyItem#selectionRange
+ */
+
+ lsRange range;
+
+ /**
+ * The range that should be selected and revealed when this type hierarchy item is being picked, e.g the name of a function.
+ * Must be contained by the the {@link TypeHierarchyItem#getRange range}.
+ *
+ * @see TypeHierarchyItem#range
+ */
+
+ lsRange selectionRange;
+
+ /**
+ * If this type hierarchy item is resolved, it contains the direct parents. Could be empty if the item does not have any
+ * direct parents. If not defined, the parents have not been resolved yet.
+ */
+ boost::optional< std::vector<TypeHierarchyItem> > parents;
+
+ /**
+ * If this type hierarchy item is resolved, it contains the direct children of the current item.
+ * Could be empty if the item does not have any descendants. If not defined, the children have not been resolved.
+ */
+ boost::optional< std::vector<TypeHierarchyItem> > children;
+
+ /**
+ * An boost::optional data field can be used to identify a type hierarchy item in a resolve request.
+ */
+ boost::optional<lsp::Any> data;
+
+ MAKE_SWAP_METHOD(TypeHierarchyItem, name, detail, kind, deprecated, uri, range, selectionRange, parents, children, data)
+};
+MAKE_REFLECT_STRUCT(TypeHierarchyItem, name, detail, kind, deprecated, uri, range, selectionRange, parents, children, data);
+
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(td_typeHierarchy, TypeHierarchyParams, TypeHierarchyItem, "textDocument/typeHierarchy"); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/type_definition.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/type_definition.h
new file mode 100644
index 0000000000..38ced43b42
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/type_definition.h
@@ -0,0 +1,16 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/lsp/out_list.h"
+
+/**
+ * The goto type definition request is sent from the client to the server to resolve
+ * the type definition location of a symbol at a given text document position.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ *
+ * Since version 3.6.0
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_typeDefinition,
+ lsTextDocumentPositionParams, LocationListEither::Either, "textDocument/typeDefinition"); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/willSave.h b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/willSave.h
new file mode 100644
index 0000000000..84aa0badaa
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/textDocument/willSave.h
@@ -0,0 +1,71 @@
+#pragma once
+
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/lsTextDocumentIdentifier.h"
+
+namespace WillSaveTextDocumentParams {
+
+ /**
+ * Represents reasons why a text document is saved.
+ */
+ enum class TextDocumentSaveReason {
+
+ /**
+ * Manually triggered, e.g. by the user pressing save, by starting debugging,
+ * or by an API call.
+ */
+ Manual=(1),
+
+ /**
+ * Automatic after a delay.
+ */
+ AfterDelay=(2),
+
+ /**
+ * When the editor lost focus.
+ */
+ FocusOut=(3)
+ };
+
+ struct Params {
+ /**
+ * The document that will be saved.
+ */
+ lsTextDocumentIdentifier textDocument;
+
+ /*
+ * A reason why a text document is saved.
+ */
+
+ boost::optional<TextDocumentSaveReason> reason;
+
+ MAKE_SWAP_METHOD(Params, textDocument, reason);
+ };
+
+};
+MAKE_REFLECT_TYPE_PROXY(WillSaveTextDocumentParams::TextDocumentSaveReason);
+
+MAKE_REFLECT_STRUCT(WillSaveTextDocumentParams::Params, textDocument, reason);
+
+/**
+ * The document save notification is sent from the client to the server when
+ * the document for saved in the client.
+ *
+ * Registration Options: TextDocumentSaveRegistrationOptions
+ */
+DEFINE_NOTIFICATION_TYPE(td_willSave, WillSaveTextDocumentParams::Params, "textDocument/willSave");
+
+/**
+ * The document will save request is sent from the client to the server before the document is actually saved.
+ * The request can return an array of TextEdits which will be applied to the text document before it is saved.
+ * Please note that clients might drop results if computing the text edits took too long or if a server constantly fails on this request.
+ * This is done to keep the save fast and reliable.
+ *
+ * Registration Options: TextDocumentRegistrationOptions
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(td_willSaveWaitUntil,
+ WillSaveTextDocumentParams::Params, std::vector<lsTextEdit>, "textDocument/willSaveWaitUntil");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/utils.cpp b/graphics/asymptote/LspCpp/LibLsp/lsp/utils.cpp
new file mode 100644
index 0000000000..532f4bf6d7
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/utils.cpp
@@ -0,0 +1,602 @@
+#include "utils.h"
+
+#include <algorithm>
+#include <cassert>
+#include <cctype>
+#include <cstring>
+#include <fstream>
+#include <functional>
+
+#include <queue>
+#include <sstream>
+#include <string>
+#include <unordered_map>
+#include <sys/stat.h>
+
+#include "lsPosition.h"
+#include "utf8.h"
+#ifdef _WIN32
+#include <Windows.h>
+#endif
+
+
+// DEFAULT_RESOURCE_DIRECTORY is passed with quotes for non-MSVC compilers, ie,
+// foo vs "foo".
+#if defined(_MSC_VER)
+#define _STRINGIFY(x) #x
+#define ENSURE_STRING_MACRO_ARGUMENT(x) _STRINGIFY(x)
+#else
+#define ENSURE_STRING_MACRO_ARGUMENT(x) x
+#endif
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <boost/algorithm/string.hpp>
+namespace lsp
+{
+
+
+// See http://stackoverflow.com/a/2072890
+bool EndsWith(std::string value, std::string ending) {
+ if (ending.size() > value.size())
+ return false;
+ return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
+}
+
+bool StartsWith(std::string value, std::string start) {
+ if (start.size() > value.size())
+ return false;
+ return std::equal(start.begin(), start.end(), value.begin());
+}
+
+bool AnyStartsWith(const std::vector<std::string>& values,
+ const std::string& start) {
+ return std::any_of(
+ std::begin(values), std::end(values),
+ [&start](const std::string& value) { return StartsWith(value, start); });
+}
+
+bool StartsWithAny(const std::string& value,
+ const std::vector<std::string>& startings) {
+ return std::any_of(std::begin(startings), std::end(startings),
+ [&value](const std::string& starting) {
+ return StartsWith(value, starting);
+ });
+}
+
+bool EndsWithAny(const std::string& value,
+ const std::vector<std::string>& endings) {
+ return std::any_of(
+ std::begin(endings), std::end(endings),
+ [&value](const std::string& ending) { return EndsWith(value, ending); });
+}
+
+bool FindAnyPartial(const std::string& value,
+ const std::vector<std::string>& values) {
+ return std::any_of(std::begin(values), std::end(values),
+ [&value](const std::string& v) {
+ return value.find(v) != std::string::npos;
+ });
+}
+
+std::string GetDirName(std::string path) {
+
+ ReplaceAll(path, "\\", "/");
+ if (path.size() && path.back() == '/')
+ path.pop_back();
+ size_t last_slash = path.find_last_of('/');
+ if (last_slash == std::string::npos)
+ return "./";
+ return path.substr(0, last_slash + 1);
+}
+
+std::string GetBaseName(const std::string& path) {
+ size_t last_slash = path.find_last_of('/');
+ if (last_slash != std::string::npos && (last_slash + 1) < path.size())
+ return path.substr(last_slash + 1);
+ return path;
+}
+
+std::string StripFileType(const std::string& path) {
+ size_t last_period = path.find_last_of('.');
+ if (last_period != std::string::npos)
+ return path.substr(0, last_period);
+ return path;
+}
+
+// See http://stackoverflow.com/a/29752943
+std::string ReplaceAll(const std::string& source,
+ const std::string& from,
+ const std::string& to) {
+ std::string result;
+ result.reserve(source.length()); // avoids a few memory allocations
+
+ std::string::size_type last_pos = 0;
+ std::string::size_type find_pos;
+
+ while (std::string::npos != (find_pos = source.find(from, last_pos))) {
+ result.append(source, last_pos, find_pos - last_pos);
+ result += to;
+ last_pos = find_pos + from.length();
+ }
+
+ // Care for the rest after last occurrence
+ result += source.substr(last_pos);
+
+ return result;
+}
+
+std::vector<std::string> SplitString(const std::string& str,
+ const std::string& delimiter) {
+ // http://stackoverflow.com/a/13172514
+ std::vector<std::string> strings;
+
+ std::string::size_type pos = 0;
+ std::string::size_type prev = 0;
+ while ((pos = str.find(delimiter, prev)) != std::string::npos) {
+ strings.emplace_back(str.substr(prev, pos - prev));
+ prev = pos + 1;
+ }
+
+ // To get the last substring (or only, if delimiter is not found)
+ strings.emplace_back(str.substr(prev));
+
+ return strings;
+}
+
+void EnsureEndsInSlash(std::string& path) {
+ if (path.empty() || path[path.size() - 1] != '/')
+ path += '/';
+}
+
+std::string EscapeFileName(std::string path) {
+ if (path.size() && path.back() == '/')
+ path.pop_back();
+ std::replace(path.begin(), path.end(), '\\', '@');
+ std::replace(path.begin(), path.end(), '/', '@');
+ std::replace(path.begin(), path.end(), ':', '@');
+ return path;
+}
+
+// http://stackoverflow.com/a/6089413
+std::istream& SafeGetline(std::istream& is, std::string& t) {
+ t.clear();
+
+ // The characters in the stream are read one-by-one using a std::streambuf.
+ // That is faster than reading them one-by-one using the std::istream. Code
+ // that uses streambuf this way must be guarded by a sentry object. The sentry
+ // object performs various tasks, such as thread synchronization and updating
+ // the stream state.
+
+ std::istream::sentry se(is, true);
+ std::streambuf* sb = is.rdbuf();
+
+ for (;;) {
+ int c = sb->sbumpc();
+ if (c == EOF) {
+ // Also handle the case when the last line has no line ending
+ if (t.empty())
+ is.setstate(std::ios::eofbit);
+ return is;
+ }
+
+ t += (char)c;
+
+ if (c == '\n')
+ return is;
+ }
+}
+
+bool FileExists(const std::string& filename) {
+ std::ifstream cache(filename);
+ return cache.is_open();
+}
+
+boost::optional<std::string> ReadContent(const AbsolutePath& filename) {
+
+ std::ifstream cache;
+ cache.open(filename.path);
+
+ try {
+ return std::string(std::istreambuf_iterator<char>(cache),
+ std::istreambuf_iterator<char>());
+ } catch (std::ios_base::failure&) {
+ return {};
+ }
+}
+
+std::vector<std::string> ReadLinesWithEnding(const AbsolutePath& filename) {
+ std::vector<std::string> result;
+
+ std::ifstream input(filename.path);
+ for (std::string line; SafeGetline(input, line);)
+ result.emplace_back(line);
+
+ return result;
+}
+
+bool WriteToFile(const std::string& filename, const std::string& content) {
+ std::ofstream file(filename,
+ std::ios::out | std::ios::trunc | std::ios::binary);
+ if (!file.good()) {
+
+ return false;
+ }
+
+ file << content;
+ return true;
+}
+
+
+std::string FormatMicroseconds(long long microseconds) {
+ long long milliseconds = microseconds / 1000;
+ long long remaining = microseconds - milliseconds;
+
+ // Only show two digits after the dot.
+ while (remaining >= 100)
+ remaining /= 10;
+
+ return std::to_string(milliseconds) + "." + std::to_string(remaining) + "ms";
+}
+
+
+
+std::string UpdateToRnNewlines(std::string output) {
+ size_t idx = 0;
+ while (true) {
+ idx = output.find('\n', idx);
+
+ // No more matches.
+ if (idx == std::string::npos)
+ break;
+
+ // Skip an existing "\r\n" match.
+ if (idx > 0 && output[idx - 1] == '\r') {
+ ++idx;
+ continue;
+ }
+
+ // Replace "\n" with "\r|n".
+ output.replace(output.begin() + idx, output.begin() + idx + 1, "\r\n");
+ }
+
+ return output;
+}
+
+
+
+bool IsAbsolutePath(const std::string& path) {
+ return IsUnixAbsolutePath(path) || IsWindowsAbsolutePath(path);
+}
+
+bool IsUnixAbsolutePath(const std::string& path) {
+ return !path.empty() && path[0] == '/';
+}
+
+bool IsWindowsAbsolutePath(const std::string& path) {
+ auto is_drive_letter = [](char c) {
+ return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
+ };
+
+ return path.size() > 3 && path[1] == ':' &&
+ (path[2] == '/' || path[2] == '\\') && is_drive_letter(path[0]);
+}
+
+bool IsDirectory(const std::string& path) {
+ struct stat path_stat;
+
+ if (stat(path.c_str(), &path_stat) != 0) {
+ perror("cannot access path");
+ return false;
+ }
+
+ return path_stat.st_mode & S_IFDIR;
+}
+
+
+std::string ws2s(std::wstring const& wstr) {
+
+ std::string narrow;
+ utf8::utf32to8(wstr.begin(), wstr.end(), std::back_inserter(narrow));
+ return narrow;
+}
+std::wstring s2ws(const std::string& str) {
+ std::wstring wide;
+ utf8::utf8to32(str.begin(), str.end(), std::back_inserter(wide));
+ return wide;
+}
+
+
+#ifdef _WIN32
+
+#else
+// Returns the canonicalized absolute pathname, without expanding symbolic
+// links. This is a variant of realpath(2), C++ rewrite of
+// https://github.com/freebsd/freebsd/blob/master/lib/libc/stdlib/realpath.c
+AbsolutePath RealPathNotExpandSymlink(std::string path,
+ bool ensure_exists) {
+ if (path.empty()) {
+ errno = EINVAL;
+ return {};
+ }
+ if (path[0] == '\0') {
+ errno = ENOENT;
+ return {};
+ }
+
+ // Do not use PATH_MAX because it is tricky on Linux.
+ // See https://eklitzke.org/path-max-is-tricky
+ char tmp[1024];
+ std::string resolved;
+ size_t i = 0;
+ struct stat sb;
+ if (path[0] == '/') {
+ resolved = "/";
+ i = 1;
+ }
+ else {
+ if (!getcwd(tmp, sizeof tmp) && ensure_exists)
+ return {};
+ resolved = tmp;
+ }
+
+ while (i < path.size()) {
+ auto j = path.find('/', i);
+ if (j == std::string::npos)
+ j = path.size();
+ auto next_token = path.substr(i, j - i);
+ i = j + 1;
+ if (resolved.back() != '/')
+ resolved += '/';
+ if (next_token.empty() || next_token == ".") {
+ // Handle consequential slashes and "."
+ continue;
+ }
+ else if (next_token == "..") {
+ // Strip the last path component except when it is single "/"
+ if (resolved.size() > 1)
+ resolved.resize(resolved.rfind('/', resolved.size() - 2) + 1);
+ continue;
+ }
+ // Append the next path component.
+ // Here we differ from realpath(3), we use stat(2) instead of
+ // lstat(2) because we do not want to resolve symlinks.
+ resolved += next_token;
+ if (stat(resolved.c_str(), &sb) != 0 && ensure_exists)
+ return {};
+ if (!S_ISDIR(sb.st_mode) && j < path.size() && ensure_exists) {
+ errno = ENOTDIR;
+ return {};
+ }
+ }
+
+ // Remove trailing slash except when a single "/".
+ if (resolved.size() > 1 && resolved.back() == '/')
+ resolved.pop_back();
+ return AbsolutePath(resolved, true /*validate*/);
+}
+#endif
+
+
+AbsolutePath NormalizePath(const std::string& path0,
+ bool ensure_exists ,
+ bool force_lower_on_windows) {
+#ifdef _WIN32
+
+ std::wstring path = lsp::s2ws(path0);
+
+ wchar_t buffer[MAX_PATH] = (L"");
+
+ // Normalize the path name, ie, resolve `..`.
+ unsigned long len = GetFullPathNameW(path.c_str(), MAX_PATH, buffer, nullptr);
+ if (!len)
+ return {};
+ path = std::wstring(buffer, len);
+
+ // Get the actual casing of the path, ie, if the file on disk is `C:\FooBar`
+ // and this function is called with `c:\fooBar` this will return `c:\FooBar`.
+ // (drive casing is lowercase).
+ if (ensure_exists) {
+ len = GetLongPathNameW(path.c_str(), buffer, MAX_PATH);
+ if (!len)
+ return {};
+ path = std::wstring(buffer, len);
+ }
+
+ // Empty paths have no meaning.
+ if (path.empty())
+ return {};
+
+ // We may need to normalize the drive name to upper-case; at the moment
+ // vscode sends lower-case path names.
+ /*
+ path[0] = toupper(path[0]);
+ */
+ // Make the path all lower-case, since windows is case-insensitive.
+ if (force_lower_on_windows) {
+ for (size_t i = 0; i < path.size(); ++i)
+ path[i] = (wchar_t)tolower(path[i]);
+ }
+
+ // cquery assumes forward-slashes.
+ std::replace(path.begin(), path.end(), '\\', '/');
+
+
+ return AbsolutePath(lsp::ws2s(path), false /*validate*/);
+#else
+
+ return RealPathNotExpandSymlink(path0, ensure_exists);
+
+#endif
+
+
+}
+
+// VSCode (UTF-16) disagrees with Emacs lsp-mode (UTF-8) on how to represent
+// text documents.
+// We use a UTF-8 iterator to approximate UTF-16 in the specification (weird).
+// This is good enough and fails only for UTF-16 surrogate pairs.
+int GetOffsetForPosition(lsPosition position, const std::string& content) {
+ size_t i = 0;
+ // Iterate lines until we have found the correct line.
+ while (position.line > 0 && i < content.size()) {
+ if (content[i] == '\n')
+ position.line--;
+ i++;
+ }
+ // Iterate characters on the target line.
+ while (position.character > 0 && i < content.size()) {
+ if (uint8_t(content[i++]) >= 128) {
+ // Skip 0b10xxxxxx
+ while (i < content.size() && uint8_t(content[i]) >= 128 &&
+ uint8_t(content[i]) < 192)
+ i++;
+ }
+ position.character--;
+ }
+ return int(i);
+}
+
+
+lsPosition GetPositionForOffset(size_t offset,const std::string& content) {
+ lsPosition result;
+ for (size_t i = 0; i < offset && i < content.length(); ++i) {
+ if (content[i] == '\n') {
+ result.line++;
+ result.character = 0;
+ }
+ else {
+ result.character++;
+ }
+ }
+ return result;
+}
+
+lsPosition CharPos(const std::string& search,
+ char character,
+ int character_offset) {
+ lsPosition result;
+ size_t index = 0;
+ while (index < search.size()) {
+ char c = search[index];
+ if (c == character)
+ break;
+ if (c == '\n') {
+ result.line += 1;
+ result.character = 0;
+ }
+ else {
+ result.character += 1;
+ }
+ ++index;
+ }
+ assert(index < search.size());
+ result.character += character_offset;
+ return result;
+}
+
+void scanDirsUseRecursive(const std::wstring& rootPath, std::vector<std::wstring>& ret)
+{
+ namespace fs = boost::filesystem;
+ fs::path fullpath(rootPath);
+ if (!fs::exists(fullpath)) { return; }
+ fs::recursive_directory_iterator end_iter;
+ for (fs::recursive_directory_iterator iter(fullpath); iter != end_iter; iter++) {
+ try {
+ if (fs::is_directory(*iter)) {
+ ret.push_back(iter->path().wstring());
+ }
+ }
+ catch (const std::exception& ex) {
+ continue;
+ }
+ }
+}
+
+void scanDirsNoRecursive(const std::wstring& rootPath, std::vector<std::wstring>& ret)
+{
+ namespace fs = boost::filesystem;
+ boost::filesystem::path myPath(rootPath);
+ if (!fs::exists(rootPath)) { return; }
+ boost::filesystem::directory_iterator endIter;
+ for (boost::filesystem::directory_iterator iter(myPath); iter != endIter; iter++) {
+ if (boost::filesystem::is_directory(*iter)) {
+ ret.push_back(iter->path().wstring());
+ }
+ }
+}
+
+void scanFilesUseRecursive(
+ const std::wstring& rootPath,
+ std::vector<std::wstring>& ret,
+ std::wstring suf) {
+ namespace fs = boost::filesystem;
+ boost::to_lower(suf);
+
+ fs::path fullpath(rootPath);
+ if (!fs::exists(fullpath)) { return; }
+ fs::recursive_directory_iterator end_iter;
+ for (fs::recursive_directory_iterator iter(fullpath); iter != end_iter; iter++) {
+ try {
+ if (!fs::is_directory(*iter) && fs::is_regular_file(*iter)) {
+ auto temp_path = iter->path().wstring();
+ auto size = suf.size();
+ if (!size)
+ {
+ ret.push_back(std::move(temp_path));
+ }
+ else
+ {
+
+ if (temp_path.size() < size) continue;
+ auto suf_temp = temp_path.substr(temp_path.size() - size);
+ boost::to_lower(suf_temp);
+ if (suf_temp == suf)
+ {
+ ret.push_back(std::move(temp_path));
+ }
+ }
+ }
+ }
+ catch (const std::exception&) {
+ continue;
+ }
+ }
+}
+
+void scanFileNamesUseRecursive(const std::wstring& rootPath, std::vector<std::wstring>& ret,
+ std::wstring strSuf)
+{
+ scanFilesUseRecursive(rootPath, ret, strSuf);
+ std::vector<std::wstring> names;
+ for (auto& it : ret)
+ {
+ if (it.size() >= rootPath.size())
+ {
+ names.push_back(it.substr(rootPath.size()));
+ }
+ }
+ ret.swap(names);
+}
+
+void scanFileNamesUseRecursive(const std::string& rootPath, std::vector<std::string>& ret, std::string strSuf)
+{
+ std::vector<std::wstring> out;
+ scanFileNamesUseRecursive(s2ws(rootPath), out, s2ws(strSuf));
+ for (auto& it : out)
+ {
+ ret.push_back(ws2s(it));
+ }
+}
+
+void scanFilesUseRecursive(const std::string& rootPath, std::vector<std::string>& ret, std::string strSuf)
+{
+ std::vector<std::wstring> out;
+ scanFilesUseRecursive(s2ws(rootPath), out, s2ws(strSuf));
+ for (auto& it : out)
+ {
+ ret.push_back(ws2s(it));
+ }
+}
+
+
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/utils.h b/graphics/asymptote/LspCpp/LibLsp/lsp/utils.h
new file mode 100644
index 0000000000..796b5d2569
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/utils.h
@@ -0,0 +1,141 @@
+#pragma once
+#include <algorithm>
+#include <codecvt>
+#include <functional>
+#include <iterator>
+#include <locale>
+#include <memory>
+#include <string>
+#include <vector>
+#include <boost/optional/optional.hpp>
+#include <LibLsp/lsp/AbsolutePath.h>
+
+#include "lsPosition.h"
+
+
+namespace lsp
+{
+
+
+// Returns true if |value| starts/ends with |start| or |ending|.
+bool StartsWith(std::string value, std::string start);
+bool EndsWith(std::string value, std::string ending);
+bool AnyStartsWith(const std::vector<std::string>& values,
+ const std::string& start);
+bool StartsWithAny(const std::string& value,
+ const std::vector<std::string>& startings);
+bool EndsWithAny(const std::string& value,
+ const std::vector<std::string>& endings);
+bool FindAnyPartial(const std::string& value,
+ const std::vector<std::string>& values);
+// Returns the dirname of |path|, i.e. "foo/bar.cc" => "foo/", "foo" => "./",
+// "/foo" => "/". The result always ends in '/'.
+std::string GetDirName(std::string path);
+// Returns the basename of |path|, ie, "foo/bar.cc" => "bar.cc".
+std::string GetBaseName(const std::string& path);
+// Returns |path| without the filetype, ie, "foo/bar.cc" => "foo/bar".
+std::string StripFileType(const std::string& path);
+
+std::string ReplaceAll(const std::string& source,
+ const std::string& from,
+ const std::string& to);
+
+std::vector<std::string> SplitString(const std::string& str,
+ const std::string& delimiter);
+
+template <typename TValues, typename TMap>
+std::string StringJoinMap(const TValues& values,
+ const TMap& map,
+ const std::string& sep = ", ") {
+ std::string result;
+ bool first = true;
+ for (auto& entry : values) {
+ if (!first)
+ result += sep;
+ first = false;
+ result += map(entry);
+ }
+ return result;
+}
+
+template <typename TValues>
+std::string StringJoin(const TValues& values, const std::string& sep = ", ") {
+ return StringJoinMap(values, [](const std::string& entry) { return entry; },
+ sep);
+}
+
+template <typename TCollection, typename TValue>
+bool ContainsValue(const TCollection& collection, const TValue& value) {
+ return std::find(std::begin(collection), std::end(collection), value) !=
+ std::end(collection);
+}
+
+
+// Ensures that |path| ends in a slash.
+void EnsureEndsInSlash(std::string& path);
+
+// Converts a file path to one that can be used as filename.
+// e.g. foo/bar.c => foo_bar.c
+std::string EscapeFileName(std::string path);
+
+// FIXME: Move ReadContent into ICacheManager?
+bool FileExists(const std::string& filename);
+boost::optional<std::string> ReadContent(const AbsolutePath& filename);
+std::vector<std::string> ReadLinesWithEnding(const AbsolutePath& filename);
+
+bool WriteToFile(const std::string& filename, const std::string& content);
+
+
+template <typename T, typename Fn>
+void RemoveIf(std::vector<T>* vec, Fn predicate) {
+ vec->erase(std::remove_if(vec->begin(), vec->end(), predicate), vec->end());
+}
+
+std::string FormatMicroseconds(long long microseconds);
+
+// Makes sure all newlines in |output| are in \r\n format.
+std::string UpdateToRnNewlines(std::string output);
+
+// Utility methods to check if |path| is absolute.
+bool IsAbsolutePath(const std::string& path);
+bool IsUnixAbsolutePath(const std::string& path);
+bool IsWindowsAbsolutePath(const std::string& path);
+
+bool IsDirectory(const std::string& path);
+
+// string <-> wstring conversion (UTF-16), e.g. for use with Window's wide APIs.
+ std::string ws2s(std::wstring const& wstr);
+ std::wstring s2ws(std::string const& str);
+
+AbsolutePath NormalizePath(const std::string& path,
+ bool ensure_exists = true,
+ bool force_lower_on_windows = true);
+
+
+int GetOffsetForPosition(lsPosition position, const std::string& content);
+
+// Finds the position for an |offset| in |content|.
+lsPosition GetPositionForOffset(int offset, const std::string& content);
+
+// Utility method to find a position for the given character.
+lsPosition CharPos(const std::string& search,
+ char character,
+ int character_offset = 0);
+
+
+ void scanDirsNoRecursive(const std::wstring& rootPath, std::vector<std::wstring>& ret);
+
+ void scanFilesUseRecursive(const std::wstring& rootPath, std::vector<std::wstring>& ret,
+ std::wstring strSuf = L"");
+
+ void scanFileNamesUseRecursive(const std::wstring& rootPath, std::vector<std::wstring>& ret,
+ std::wstring strSuf = L"");
+ void scanFileNamesUseRecursive(const std::string& rootPath, std::vector<std::string>& ret,
+ std::string strSuf = "");
+
+ void scanFilesUseRecursive(const std::string& rootPath, std::vector<std::string>& ret,
+ std::string strSuf = "");
+
+ void scanDirsUseRecursive(const std::wstring& rootPath, std::vector<std::wstring>& ret);
+
+}
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/windows/MessageNotify.h b/graphics/asymptote/LspCpp/LibLsp/lsp/windows/MessageNotify.h
new file mode 100644
index 0000000000..8499304f55
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/windows/MessageNotify.h
@@ -0,0 +1,83 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+// Show a message to the user.
+enum class lsMessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 };
+MAKE_REFLECT_TYPE_PROXY(lsMessageType)
+struct MessageParams {
+/**
+ * The message type.
+ */
+
+ lsMessageType type = lsMessageType::Error;
+
+/**
+ * The actual message.
+ */
+ std::string message;
+
+ void swap(MessageParams& arg) noexcept {
+ lsMessageType temp = type;
+ type = arg.type;
+ arg.type = temp;
+ message.swap(arg.message);
+ }
+};
+MAKE_REFLECT_STRUCT(MessageParams, type, message)
+
+ /**
+ * The log message notification is send from the server to the client to ask
+ * the client to log a particular message.
+ */
+DEFINE_NOTIFICATION_TYPE(Notify_LogMessage, MessageParams, "window/logMessage")
+
+
+/**
+ * The show message notification is sent from a server to a client to ask
+ * the client to display a particular message in the user interface.
+ */
+DEFINE_NOTIFICATION_TYPE(Notify_ShowMessage, MessageParams, "window/showMessage")
+
+
+
+/**
+ * The show message request is sent from a server to a client to ask the client to display a particular message in the
+ * user class. In addition to the show message notification the request allows to pass actions and to wait for an
+ * answer from the client.
+ */
+struct MessageActionItem {
+ /**
+ * A short title like 'Retry', 'Open Log' etc.
+ */
+
+ std::string title;
+ MAKE_SWAP_METHOD(MessageActionItem, title)
+};
+MAKE_REFLECT_STRUCT(MessageActionItem, title);
+
+
+struct ShowMessageRequestParams :public MessageParams {
+ /**
+ * The message action items to present.
+ */
+ std::vector<MessageActionItem> actions;
+
+ MAKE_SWAP_METHOD(ShowMessageRequestParams, type, message, actions)
+
+};
+MAKE_REFLECT_STRUCT(ShowMessageRequestParams, type, message, actions)
+
+/**
+* The show message request is sent from a server to a client to ask the
+* client to display a particular message in the user interface. In addition
+* to the show message notification the request allows to pass actions and
+* to wait for an answer from the client.
+*/
+
+DEFINE_REQUEST_RESPONSE_TYPE(WindowShowMessage, ShowMessageRequestParams, MessageActionItem, "window/showMessage")
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/working_files.cpp b/graphics/asymptote/LspCpp/LibLsp/lsp/working_files.cpp
new file mode 100644
index 0000000000..370a038274
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/working_files.cpp
@@ -0,0 +1,186 @@
+#include "working_files.h"
+#include <algorithm>
+#include <climits>
+#include <numeric>
+#include "utils.h"
+#include <memory>
+#include "LibLsp/lsp/AbsolutePath.h"
+using namespace lsp;
+struct WorkingFilesData
+{
+ std::map<AbsolutePath, std::shared_ptr<WorkingFile> > files;
+ std::mutex files_mutex; // Protects |d_ptr->files|.
+};
+
+WorkingFile::WorkingFile(WorkingFiles& _parent, const AbsolutePath& filename,
+ const std::string& buffer_content)
+ : filename(filename), directory(filename), parent(_parent), counter(0), buffer_content(buffer_content)
+{
+ directory = Directory(GetDirName(filename.path));
+}
+
+WorkingFile::WorkingFile(WorkingFiles& _parent, const AbsolutePath& filename,
+ std::string&& buffer_content)
+ : filename(filename), directory(filename), parent(_parent), counter(0), buffer_content(buffer_content)
+{
+ directory = Directory(GetDirName(filename.path));
+}
+
+WorkingFiles::WorkingFiles():d_ptr(new WorkingFilesData())
+{
+}
+
+WorkingFiles::~WorkingFiles()
+{
+ delete d_ptr;
+
+}
+
+
+
+void WorkingFiles::CloseFilesInDirectory(const std::vector<Directory>& directories)
+{
+ std::lock_guard<std::mutex> lock(d_ptr->files_mutex);
+ std::vector<AbsolutePath> files_to_be_delete;
+
+ for(auto& it : d_ptr->files)
+ {
+ for (auto& dir : directories)
+ {
+ if (it.second->directory == dir) {
+ files_to_be_delete.emplace_back(it.first);
+ }
+ }
+ }
+
+ for(auto& it : files_to_be_delete)
+ {
+ d_ptr->files.erase(it);
+ }
+}
+
+
+
+
+std::shared_ptr<WorkingFile> WorkingFiles::GetFileByFilename(const AbsolutePath& filename) {
+ std::lock_guard<std::mutex> lock(d_ptr->files_mutex);
+ return GetFileByFilenameNoLock(filename);
+}
+
+std::shared_ptr<WorkingFile> WorkingFiles::GetFileByFilenameNoLock(
+ const AbsolutePath& filename) {
+ const auto findIt = d_ptr->files.find(filename);
+ if ( findIt != d_ptr->files.end())
+ {
+ return findIt->second;
+ }
+ return nullptr;
+}
+
+
+
+std::shared_ptr<WorkingFile> WorkingFiles::OnOpen( lsTextDocumentItem& open) {
+ std::lock_guard<std::mutex> lock(d_ptr->files_mutex);
+
+ AbsolutePath filename = open.uri.GetAbsolutePath();
+
+ // The file may already be open.
+ if (auto file = GetFileByFilenameNoLock(filename)) {
+ file->version = open.version;
+ file->buffer_content.swap(open.text);
+
+ return file;
+ }
+
+ const auto& it = d_ptr->files.insert({ filename,std::make_shared<WorkingFile>(*this,filename, std::move(open.text)) });
+ return it.first->second;
+}
+
+
+std::shared_ptr<WorkingFile> WorkingFiles::OnChange(const lsTextDocumentDidChangeParams& change) {
+ std::lock_guard<std::mutex> lock(d_ptr->files_mutex);
+
+ AbsolutePath filename = change.textDocument.uri.GetAbsolutePath();
+ auto file = GetFileByFilenameNoLock(filename);
+ if (!file) {
+ return {};
+ }
+
+ if (change.textDocument.version)
+ file->version = *change.textDocument.version;
+ file->counter.fetch_add(1, std::memory_order_relaxed);
+ for (const lsTextDocumentContentChangeEvent& diff : change.contentChanges) {
+ // Per the spec replace everything if the rangeLength and range are not set.
+ // See https://github.com/Microsoft/language-server-protocol/issues/9.
+ if (!diff.range) {
+ file->buffer_content = diff.text;
+
+ } else {
+ int start_offset =
+ GetOffsetForPosition(diff.range->start, file->buffer_content);
+ // Ignore TextDocumentContentChangeEvent.rangeLength which causes trouble
+ // when UTF-16 surrogate pairs are used.
+ int end_offset =
+ GetOffsetForPosition(diff.range->end, file->buffer_content);
+ file->buffer_content.replace(file->buffer_content.begin() + start_offset,
+ file->buffer_content.begin() + end_offset,
+ diff.text);
+
+ }
+ }
+ return file;
+}
+
+bool WorkingFiles::OnClose(const lsTextDocumentIdentifier& close) {
+ std::lock_guard<std::mutex> lock(d_ptr->files_mutex);
+
+ AbsolutePath filename = close.uri.GetAbsolutePath();
+ const auto findIt = d_ptr->files.find(filename);
+ if( findIt != d_ptr->files.end())
+ {
+ d_ptr->files.erase(findIt);
+ return true;
+ }
+ return false;
+}
+
+std::shared_ptr<WorkingFile> WorkingFiles::OnSave(const lsTextDocumentIdentifier& _save)
+{
+ std::lock_guard<std::mutex> lock(d_ptr->files_mutex);
+
+ AbsolutePath filename = _save.uri.GetAbsolutePath();
+ const auto findIt = d_ptr->files.find(filename);
+ if (findIt != d_ptr->files.end())
+ {
+ std::shared_ptr<WorkingFile>& file = findIt->second;
+ lsp::WriteToFile(file->filename, file->GetContentNoLock());
+ return findIt->second;
+ }
+ return {};
+
+}
+
+bool WorkingFiles::GetFileBufferContent(std::shared_ptr<WorkingFile>&file, std::string& out)
+{
+ std::lock_guard<std::mutex> lock(d_ptr->files_mutex);
+ if (file)
+ {
+ out = file->buffer_content;
+ return true;
+ }
+ return false;
+}
+bool WorkingFiles::GetFileBufferContent(std::shared_ptr<WorkingFile>& file, std::wstring& out)
+{
+ std::lock_guard<std::mutex> lock(d_ptr->files_mutex);
+ if (file)
+ {
+ out = lsp::s2ws(file->buffer_content);
+ return true;
+ }
+ return false;
+}
+void WorkingFiles::Clear() {
+ std::lock_guard<std::mutex> lock(d_ptr->files_mutex);
+ d_ptr->files.clear();
+} \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/working_files.h b/graphics/asymptote/LspCpp/LibLsp/lsp/working_files.h
new file mode 100644
index 0000000000..e305fee8d0
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/working_files.h
@@ -0,0 +1,72 @@
+#pragma once
+
+#include "LibLsp/lsp/lsp_diagnostic.h"
+#include "LibLsp/lsp/AbsolutePath.h"
+#include "LibLsp/lsp/textDocument/did_change.h"
+#include "LibLsp/lsp/textDocument/did_close.h"
+#include "LibLsp/lsp/textDocument/did_open.h"
+#include <mutex>
+#include <string>
+#include <memory>
+#include "Directory.h"
+
+struct WorkingFiles;
+struct WorkingFilesData;
+struct WorkingFile {
+
+ int version = 0;
+ AbsolutePath filename;
+ Directory directory;
+ WorkingFiles& parent;
+ std::atomic<long long> counter;
+ WorkingFile(WorkingFiles& ,const AbsolutePath& filename, const std::string& buffer_content);
+ WorkingFile(WorkingFiles&, const AbsolutePath& filename, std::string&& buffer_content);
+ const std::string& GetContentNoLock() const
+ {
+ return buffer_content;
+ }
+protected:
+ friend struct WorkingFiles;
+ std::string buffer_content;
+};
+
+struct WorkingFiles {
+
+ WorkingFiles();
+ ~WorkingFiles();
+
+ void CloseFilesInDirectory(const std::vector<Directory>&);
+ std::shared_ptr<WorkingFile> OnOpen(lsTextDocumentItem& open);
+ std::shared_ptr<WorkingFile> OnChange(const lsTextDocumentDidChangeParams& change);
+ bool OnClose(const lsTextDocumentIdentifier& close);
+ std::shared_ptr<WorkingFile> OnSave(const lsTextDocumentIdentifier& _save);
+
+ bool GetFileBufferContent(const AbsolutePath& filename, std::wstring& out)
+ {
+ auto file = GetFileByFilename(filename);
+ if(!file)
+ return false;
+ return GetFileBufferContent(file, out);
+ }
+ bool GetFileBufferContent(const AbsolutePath& filename,std::string& out)
+ {
+ auto file = GetFileByFilename(filename);
+ if (!file)
+ return false;
+ return GetFileBufferContent(file, out);
+ }
+ bool GetFileBufferContent(std::shared_ptr<WorkingFile>&, std::string& out);
+ bool GetFileBufferContent(std::shared_ptr<WorkingFile>&, std::wstring& out);
+
+
+ // Find the file with the given filename.
+ std::shared_ptr<WorkingFile> GetFileByFilename(const AbsolutePath& filename);
+
+ void Clear();
+private:
+ std::shared_ptr<WorkingFile> GetFileByFilenameNoLock(const AbsolutePath& filename);
+
+ WorkingFilesData* d_ptr;
+
+
+};
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/applyEdit.h b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/applyEdit.h
new file mode 100644
index 0000000000..7e2d8bee0a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/applyEdit.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/lsDocumentUri.h"
+#include "LibLsp/lsp/lsWorkspaceEdit.h"
+
+struct ApplyWorkspaceEditParams
+{
+ /**
+ * The edits to apply.
+ */
+
+ lsWorkspaceEdit edit;
+
+ /**
+ * An optional label of the workspace edit. This label is
+ * presented in the user interface for example on an undo
+ * stack to undo the workspace edit.
+ */
+ std::string label;
+
+ MAKE_SWAP_METHOD(ApplyWorkspaceEditParams, edit, label)
+};
+/**
+ * The workspace/applyEdit request is sent from the server to the client to modify resource on the client side.
+ */
+MAKE_REFLECT_STRUCT(ApplyWorkspaceEditParams, edit, label);
+
+
+
+struct ApplyWorkspaceEditResponse
+{
+ bool applied;
+ boost::optional<std::string> failureReason;
+ MAKE_SWAP_METHOD(ApplyWorkspaceEditResponse, applied, failureReason)
+};
+MAKE_REFLECT_STRUCT(ApplyWorkspaceEditResponse, applied, failureReason);
+
+
+DEFINE_REQUEST_RESPONSE_TYPE(WorkspaceApply, ApplyWorkspaceEditParams, ApplyWorkspaceEditResponse, "workspace/applyEdit");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/configuration.h b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/configuration.h
new file mode 100644
index 0000000000..f7709aa607
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/configuration.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/lsDocumentUri.h"
+
+
+struct ConfigurationItem {
+ /**
+ * The scope to get the configuration section for.
+ */
+ lsDocumentUri scopeUri;
+
+ /**
+ * The configuration section asked for.
+ */
+ std::string section;
+ MAKE_SWAP_METHOD(ConfigurationItem, scopeUri, section);
+};
+MAKE_REFLECT_STRUCT(ConfigurationItem, scopeUri, section);
+struct ConfigurationParams
+{
+ std::vector<ConfigurationItem> items;
+ MAKE_SWAP_METHOD(ConfigurationParams, items)
+};
+
+MAKE_REFLECT_STRUCT(ConfigurationParams, items);
+
+/**
+ * The workspace/configuration request is sent from the server to the client to fetch
+ * configuration settings from the client. The request can fetch n configuration settings
+ * in one roundtrip. The order of the returned configuration settings correspond to the
+ * order of the passed ConfigurationItems (e.g. the first item in the response is the
+ * result for the first configuration item in the params).
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(WorkspaceConfiguration, ConfigurationParams,std::vector<lsp::Any>, "workspace/configuration"); \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/didChangeWorkspaceFolders.h b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/didChangeWorkspaceFolders.h
new file mode 100644
index 0000000000..78f000f30d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/didChangeWorkspaceFolders.h
@@ -0,0 +1,48 @@
+#pragma once
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+#include "LibLsp/lsp/workspace/workspaceFolders.h"
+/**
+ * The workspace folder change event.
+ */
+struct WorkspaceFoldersChangeEvent {
+ /**
+ * The array of added workspace folders
+ */
+
+ std::vector<WorkspaceFolder> added;
+
+ /**
+ * The array of the removed workspace folders
+ */
+
+ std::vector <WorkspaceFolder> removed;
+ MAKE_SWAP_METHOD(WorkspaceFoldersChangeEvent, added, removed);
+
+};
+MAKE_REFLECT_STRUCT(WorkspaceFoldersChangeEvent, added, removed);
+
+struct DidChangeWorkspaceFoldersParams {
+ /**
+ * The actual workspace folder change event.
+ */
+
+ WorkspaceFoldersChangeEvent event;
+
+ MAKE_SWAP_METHOD(DidChangeWorkspaceFoldersParams, event);
+};
+MAKE_REFLECT_STRUCT(DidChangeWorkspaceFoldersParams, event);
+
+
+/**
+ * The workspace/didChangeWorkspaceFolders notification is sent from the client
+ * to the server to inform the server about workspace folder configuration changes.
+ * The notification is sent by default if both ServerCapabilities/workspaceFolders
+ * and ClientCapabilities/workspace/workspaceFolders are true; or if the server has
+ * registered to receive this notification it first.
+ */
+DEFINE_NOTIFICATION_TYPE(Notify_WorkspaceDidChangeWorkspaceFolders,
+ DidChangeWorkspaceFoldersParams, "workspace/didChangeWorkspaceFolders");
+
+
+
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/did_change_configuration.h b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/did_change_configuration.h
new file mode 100644
index 0000000000..8f8acceea4
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/did_change_configuration.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+
+
+#include "workspaceFolders.h"
+
+
+
+
+struct lsDidChangeConfigurationParams {
+ /**
+ * The actual changed settings.
+ */
+ lsp::Any settings;
+ MAKE_SWAP_METHOD(lsDidChangeConfigurationParams, settings);
+};
+
+MAKE_REFLECT_STRUCT(lsDidChangeConfigurationParams, settings);
+
+/**
+ * A notification sent from the client to the server to signal the change of
+ * configuration settings.
+ */
+DEFINE_NOTIFICATION_TYPE(Notify_WorkspaceDidChangeConfiguration, lsDidChangeConfigurationParams, "workspace/didChangeConfiguration");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/did_change_watched_files.h b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/did_change_watched_files.h
new file mode 100644
index 0000000000..c14a7e0eda
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/did_change_watched_files.h
@@ -0,0 +1,46 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+#include "LibLsp/lsp/lsDocumentUri.h"
+enum class lsFileChangeType {
+ Created = 1,
+ Changed = 2,
+ Deleted = 3,
+};
+
+#ifdef _WIN32
+MAKE_REFLECT_TYPE_PROXY(lsFileChangeType);
+#else
+//#pragma clang diagnostic push
+//#pragma clang diagnostic ignored "-Wunused-function"
+MAKE_REFLECT_TYPE_PROXY(lsFileChangeType);
+//#pragma clang diagnostic pop
+#endif
+
+
+/**
+ * An event describing a file change.
+ */
+struct lsFileEvent {
+ lsDocumentUri uri;
+ lsFileChangeType type;
+
+ MAKE_SWAP_METHOD(lsFileEvent, uri, type)
+};
+MAKE_REFLECT_STRUCT(lsFileEvent, uri, type);
+
+struct lsDidChangeWatchedFilesParams {
+ std::vector<lsFileEvent> changes;
+ MAKE_SWAP_METHOD(lsDidChangeWatchedFilesParams, changes);
+};
+MAKE_REFLECT_STRUCT(lsDidChangeWatchedFilesParams, changes);
+
+ /**
+ * The workspace/didChangeWorkspaceFolders notification is sent from the client
+ * to the server to inform the server about workspace folder configuration changes.
+ * The notification is sent by default if both ServerCapabilities/workspaceFolders
+ * and ClientCapabilities/workspace/workspaceFolders are true; or if the server has
+ * registered to receive this notification it first.
+ */
+
+DEFINE_NOTIFICATION_TYPE(Notify_WorkspaceDidChangeWatchedFiles, lsDidChangeWatchedFilesParams, "workspace/didChangeWatchedFiles");
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/execute_command.h b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/execute_command.h
new file mode 100644
index 0000000000..c656ee5ef7
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/execute_command.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "LibLsp/lsp/ExecuteCommandParams.h"
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/JsonRpc/NotificationInMessage.h"
+
+
+
+/**
+ * The workspace/executeCommand request is sent from the client to the
+ * server to trigger command execution on the server. In most cases the
+ * server creates a WorkspaceEdit structure and applies the changes to the
+ * workspace using the request workspace/applyEdit which is sent from the
+ * server to the client.
+ *
+ * Registration Options: ExecuteCommandRegistrationOptions
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(wp_executeCommand, ExecuteCommandParams, lsp::Any, "workspace/executeCommand");
+
+
+DEFINE_NOTIFICATION_TYPE(Notify_sendNotification, ExecuteCommandParams, "workspace/notify") \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/symbol.h b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/symbol.h
new file mode 100644
index 0000000000..129fb5e822
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/symbol.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "LibLsp/lsp/symbol.h"
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+/**
+ * The workspace symbol request is sent from the client to the server to
+ * list project-wide symbols matching the query string.
+ *
+ * Registration Options: void
+ */
+
+DEFINE_REQUEST_RESPONSE_TYPE(wp_symbol, WorkspaceSymbolParams, std::vector<lsSymbolInformation>, "workspace/symbol");
+
diff --git a/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/workspaceFolders.h b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/workspaceFolders.h
new file mode 100644
index 0000000000..7cedcfa5f4
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LibLsp/lsp/workspace/workspaceFolders.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "LibLsp/JsonRpc/RequestInMessage.h"
+#include "LibLsp/JsonRpc/lsResponseMessage.h"
+
+#include "LibLsp/lsp/lsDocumentUri.h"
+struct WorkspaceFolder {
+ /**
+ * The associated URI for this workspace folder.
+ */
+
+ lsDocumentUri uri;
+
+ /**
+ * The name of the workspace folder. Defaults to the uri's basename.
+ */
+ std::string name;
+
+ MAKE_SWAP_METHOD(WorkspaceFolder, uri, name)
+};
+MAKE_REFLECT_STRUCT(WorkspaceFolder, uri, name);
+
+
+/**
+ * The workspace/workspaceFolders request is sent from the server to the client
+ * to fetch the current open list of workspace folders.
+ *
+ * @return null in the response if only a single file is open in the tool,
+ * an empty array if a workspace is open but no folders are configured,
+ * the workspace folders otherwise.
+ */
+DEFINE_REQUEST_RESPONSE_TYPE(WorkspaceFolders,
+ boost::optional<JsonNull>, boost::optional<std::vector< WorkspaceFolder>>, "workspace/workspaceFolders");
+
diff --git a/graphics/asymptote/LspCpp/LspCpp.filters b/graphics/asymptote/LspCpp/LspCpp.filters
new file mode 100644
index 0000000000..795e500f14
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LspCpp.filters
@@ -0,0 +1,465 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="源文件">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="头文件">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
+ </Filter>
+ <Filter Include="资源文件">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ <Filter Include="JsonRpc">
+ <UniqueIdentifier>{16f3c0fa-d78b-48de-ad07-3faced48badc}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp">
+ <UniqueIdentifier>{0b7b623e-2177-4c50-9364-51bad4e3a96d}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\workspace">
+ <UniqueIdentifier>{05d4a0be-21a5-4e0e-92eb-f3246dc60fb0}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\textDocument">
+ <UniqueIdentifier>{555e2484-f11d-466e-b41c-263b68eda142}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\windows">
+ <UniqueIdentifier>{80aef1a6-c03b-4b19-ac86-7ec9f89dcf34}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\general">
+ <UniqueIdentifier>{db50dfa7-d3d1-45db-9c35-6274c624de32}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\JavaExtentions">
+ <UniqueIdentifier>{3fe59184-4ce8-42c3-95f8-c4af6bfef674}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\client">
+ <UniqueIdentifier>{9f073965-fffb-414e-acc3-0b61c54a2404}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="LspCpp.cpp">
+ <Filter>源文件</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\StreamMessageProducer.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\MessageJsonHandler.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\Endpoint.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\serializer.cc">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\message.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\threaded_queue.cc">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\RemoteEndPoint.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\AbsolutePath.cc">
+ <Filter>lsp</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\lsp.cc">
+ <Filter>lsp</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\lsp_diagnostic.cc">
+ <Filter>lsp</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\method_type.cc">
+ <Filter>lsp</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\ProtocolJsonHandler.cpp">
+ <Filter>lsp</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\utils.cc">
+ <Filter>lsp</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\general\initialize.cpp">
+ <Filter>lsp\general</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\textDocument\textDocument.cpp">
+ <Filter>lsp\textDocument</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="LibLsp\JsonRpc\MessageIssue.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\MessageProducer.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\StreamMessageProducer.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\MessageJsonHandler.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\Endpoint.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\maybe.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\serializer.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\child_process_service.hpp">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\threaded_queue.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\RemoteEndPoint.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\cancellation.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\message.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\AbsolutePath.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\config.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\hash_utils.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\location_type.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lru_cache.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsCommand.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsDocumentUri.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsFormattingOptions.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsMarkedString.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsp_code_action.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsp_completion.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsp_diagnostic.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsPosition.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsRange.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsResponseError.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsTextDocumentEdit.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsTextDocumentIdentifier.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsTextDocumentItem.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsTextDocumentPositionParams.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsTextEdit.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsVersionedTextDocumentIdentifier.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsWorkspaceEdit.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\method_type.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\out_list.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\ProtocolJsonHandler.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\ProtocolLocalEndPoint.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\symbol.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\utils.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\exit.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\initialize.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\initialized.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\shutdown.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\callHierarchy.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\code_action.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\code_lens.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\completion.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\did_change.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\did_close.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\did_open.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\did_save.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\document_link.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\document_symbol.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\formatting.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\highlight.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\hover.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\implementation.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\range_formatting.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\references.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\rename.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\signature_help.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\type_definition.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\typeHierarchy.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\did_change_configuration.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\did_change_watched_files.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\execute_command.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\symbol.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\ResourceOperation.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsCodeAction.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\WorkspaceSymbolParams.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\searchSymbols.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\getRefactorEdit.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\buildWorkspace.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\codeActionResult.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\executeCommand.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\workspaceFolders.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\applyEdit.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\configuration.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\semanticHighlighting.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\client\unregisterCapability.h">
+ <Filter>lsp\client</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\client\registerCapability.h">
+ <Filter>lsp\client</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\publishDiagnostics.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\windows\Message.h">
+ <Filter>lsp\windows</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\didChangeWorkspaceFolders.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\resolveCompletionItem.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\declaration_definition.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsAny.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\classFileContents.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\projectConfigurationUpdate.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\listOverridableMethods.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\addOverridableMethods.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\OverridableMethod.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\checkHashCodeEqualsStatus.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\CodeActionParams.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\generateHashCodeEquals.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\organizeImports.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\checkToStringStatus.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\generateToString.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\resolveUnimplementedAccessors.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\generateAccessors.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\checkConstructorsStatus.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\generateConstructors.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\checkDelegateMethodsStatus.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\generateDelegateMethods.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\getMoveDestinations.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\Move.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\JavaExtentions\findLinks.h">
+ <Filter>lsp\JavaExtentions</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\InitializeParams.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\lsServerCapabilities.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\lsClientCapabilities.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\lsWorkspaceClientCapabilites.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\lsTextDocumentClientCapabilities.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\ExecuteCommandParams.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\resolveCodeLens.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\onTypeFormatting.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\willSave.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\documentColor.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\colorPresentation.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\foldingRange.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\prepareRename.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\resolveTypeHierarchy.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\selectionRange.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LspCpp.user b/graphics/asymptote/LspCpp/LspCpp.user
new file mode 100644
index 0000000000..88a550947e
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LspCpp.user
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup />
+</Project> \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LspCpp.vcxproj b/graphics/asymptote/LspCpp/LspCpp.vcxproj
new file mode 100644
index 0000000000..e363e2a027
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LspCpp.vcxproj
@@ -0,0 +1,668 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="STDIO_CLIENT_EXAMPLE|Win32">
+ <Configuration>STDIO_CLIENT_EXAMPLE</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="STDIO_CLIENT_EXAMPLE|x64">
+ <Configuration>STDIO_CLIENT_EXAMPLE</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="STDIO_SERVER_EXAMPLE|Win32">
+ <Configuration>STDIO_SERVER_EXAMPLE</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="STDIO_SERVER_EXAMPLE|x64">
+ <Configuration>STDIO_SERVER_EXAMPLE</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="TCP_SERVER_EXAMPLE|Win32">
+ <Configuration>TCP_SERVER_EXAMPLE</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="TCP_SERVER_EXAMPLE|x64">
+ <Configuration>TCP_SERVER_EXAMPLE</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="WEBSOCKET_SERVER_EXAMPLE|Win32">
+ <Configuration>WEBSOCKET_SERVER_EXAMPLE</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="WEBSOCKET_SERVER_EXAMPLE|x64">
+ <Configuration>WEBSOCKET_SERVER_EXAMPLE</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{F45A78DC-E57C-4AF6-8719-29833E3BFE07}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>LspCpp</RootNamespace>
+ <WindowsTargetPlatformVersion>7.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141_xp</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='TCP_SERVER_EXAMPLE|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141_xp</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_SERVER_EXAMPLE|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141_xp</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_CLIENT_EXAMPLE|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141_xp</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='WEBSOCKET_SERVER_EXAMPLE|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141_xp</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141_xp</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='TCP_SERVER_EXAMPLE|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_SERVER_EXAMPLE|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_CLIENT_EXAMPLE|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='WEBSOCKET_SERVER_EXAMPLE|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='TCP_SERVER_EXAMPLE|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_SERVER_EXAMPLE|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_CLIENT_EXAMPLE|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='WEBSOCKET_SERVER_EXAMPLE|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='TCP_SERVER_EXAMPLE|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_SERVER_EXAMPLE|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_CLIENT_EXAMPLE|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='WEBSOCKET_SERVER_EXAMPLE|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <IncludePath>.\third_party\rapidjson\include;.\third_party\utfcpp\source;.\;.\third_party\threadpool;$(IncludePath)</IncludePath>
+ <OutDir>..\Our_lib_V3</OutDir>
+ <TargetName>LspCppMDD</TargetName>
+ <TargetExt>.lib</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='TCP_SERVER_EXAMPLE|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <IncludePath>.\third_party\rapidjson\include;.\third_party\utfcpp\source;.\;.\third_party\threadpool;$(IncludePath)</IncludePath>
+ <TargetName>TCP_SERVER_EXAMPLE</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_SERVER_EXAMPLE|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <IncludePath>.\third_party\rapidjson\include;.\third_party\utfcpp\source;.\;.\third_party\threadpool;$(IncludePath)</IncludePath>
+ <TargetName>STDIO_SERVER_EXAMPLE</TargetName>
+ <OutDir>.\bin</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_CLIENT_EXAMPLE|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <IncludePath>.\third_party\rapidjson\include;.\third_party\utfcpp\source;.\;.\third_party\threadpool;$(IncludePath)</IncludePath>
+ <TargetName>STDIO_CLIENT_EXAMPLE</TargetName>
+ <OutDir>.\bin</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='WEBSOCKET_SERVER_EXAMPLE|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <IncludePath>.\third_party\rapidjson\include;.\third_party\utfcpp\source;.\;.\third_party\threadpool;$(IncludePath)</IncludePath>
+ <TargetName>WEBSOCKET_SERVER_EXAMPLE</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='TCP_SERVER_EXAMPLE|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_SERVER_EXAMPLE|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_CLIENT_EXAMPLE|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='WEBSOCKET_SERVER_EXAMPLE|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>..\Our_lib_V3</OutDir>
+ <TargetName>LspCppMD</TargetName>
+ <IncludePath>.\third_party\rapidjson\include;.\third_party\utfcpp\source;.\;.\third_party\threadpool;$(IncludePath)</IncludePath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>false</SDLCheck>
+ <PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>false</ConformanceMode>
+ <LanguageStandard>stdcpp14</LanguageStandard>
+ <AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='TCP_SERVER_EXAMPLE|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>false</SDLCheck>
+ <PreprocessorDefinitions>WIN32;_DEBUG;TCP_SERVER_EXAMPLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>false</ConformanceMode>
+ <LanguageStandard>stdcpp14</LanguageStandard>
+ <AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_SERVER_EXAMPLE|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>false</SDLCheck>
+ <PreprocessorDefinitions>WIN32;_DEBUG;STDIO_SERVER_EXAMPLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>false</ConformanceMode>
+ <LanguageStandard>stdcpp14</LanguageStandard>
+ <AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_CLIENT_EXAMPLE|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>false</SDLCheck>
+ <PreprocessorDefinitions>WIN32;_DEBUG;STDIO_CLIENT_EXAMPLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>false</ConformanceMode>
+ <LanguageStandard>stdcpp14</LanguageStandard>
+ <AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='WEBSOCKET_SERVER_EXAMPLE|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>false</SDLCheck>
+ <PreprocessorDefinitions>WIN32;_DEBUG;WEBSOCKET_SERVER_EXAMPLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>false</ConformanceMode>
+ <LanguageStandard>stdcpp14</LanguageStandard>
+ <AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='TCP_SERVER_EXAMPLE|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_SERVER_EXAMPLE|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='STDIO_CLIENT_EXAMPLE|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='WEBSOCKET_SERVER_EXAMPLE|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>false</ConformanceMode>
+ <AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
+ <LanguageStandard>stdcpp14</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="example\StdIOClientExample.cpp" />
+ <ClCompile Include="example\StdIOServerExample.cpp" />
+ <ClCompile Include="example\TcpServerExample.cpp" />
+ <ClCompile Include="example\WebsocketExample.cpp" />
+ <ClCompile Include="LibLsp\JsonRpc\Context.cpp" />
+ <ClCompile Include="LibLsp\JsonRpc\serializer.cpp" />
+ <ClCompile Include="LibLsp\JsonRpc\TcpServer.cpp" />
+ <ClCompile Include="LibLsp\JsonRpc\threaded_queue.cpp" />
+ <ClCompile Include="LibLsp\JsonRpc\WebSocketServer.cpp" />
+ <ClCompile Include="LibLsp\JsonRpc\RemoteEndPoint.cpp" />
+ <ClCompile Include="LibLsp\JsonRpc\GCThreadContext.cpp" />
+ <ClCompile Include="LibLsp\JsonRpc\Endpoint.cpp" />
+ <ClCompile Include="LibLsp\JsonRpc\message.cpp" />
+ <ClCompile Include="LibLsp\JsonRpc\MessageJsonHandler.cpp" />
+ <ClCompile Include="LibLsp\JsonRpc\StreamMessageProducer.cpp" />
+ <ClCompile Include="LibLsp\lsp\extention\sct\sct.cpp" />
+ <ClCompile Include="LibLsp\lsp\general\initialize.cpp" />
+ <ClCompile Include="LibLsp\lsp\lsp.cpp" />
+ <ClCompile Include="LibLsp\lsp\lsp_diagnostic.cpp" />
+ <ClCompile Include="LibLsp\lsp\Markup\Markup.cpp" />
+ <ClCompile Include="LibLsp\lsp\ParentProcessWatcher.cpp" />
+ <ClCompile Include="LibLsp\lsp\ProtocolJsonHandler.cpp" />
+ <ClCompile Include="LibLsp\lsp\textDocument\textDocument.cpp" />
+ <ClCompile Include="LibLsp\lsp\utils.cpp" />
+ <ClCompile Include="LibLsp\lsp\working_files.cpp" />
+ <ClCompile Include="network\uri\detail\uri_advance_parts.cpp" />
+ <ClCompile Include="network\uri\detail\uri_normalize.cpp" />
+ <ClCompile Include="network\uri\detail\uri_parse.cpp" />
+ <ClCompile Include="network\uri\detail\uri_parse_authority.cpp" />
+ <ClCompile Include="network\uri\detail\uri_resolve.cpp" />
+ <ClCompile Include="network\uri\uri.cpp" />
+ <ClCompile Include="network\uri\uri_builder.cpp" />
+ <ClCompile Include="network\uri\uri_errors.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="LibLsp\JsonRpc\Cancellation.h" />
+ <ClInclude Include="LibLsp\JsonRpc\Condition.h" />
+ <ClInclude Include="LibLsp\JsonRpc\Context.h" />
+ <ClInclude Include="LibLsp\JsonRpc\json.h" />
+ <ClInclude Include="LibLsp\JsonRpc\lsRequestId.h" />
+ <ClInclude Include="LibLsp\JsonRpc\lsResponseMessage.h" />
+ <ClInclude Include="LibLsp\JsonRpc\message.h" />
+ <ClInclude Include="LibLsp\JsonRpc\NotificationInMessage.h" />
+ <ClInclude Include="LibLsp\JsonRpc\RemoteEndPoint.h" />
+ <ClInclude Include="LibLsp\JsonRpc\GCThreadContext.h" />
+ <ClInclude Include="LibLsp\JsonRpc\Endpoint.h" />
+ <ClInclude Include="LibLsp\JsonRpc\MessageIssue.h" />
+ <ClInclude Include="LibLsp\JsonRpc\MessageJsonHandler.h" />
+ <ClInclude Include="LibLsp\JsonRpc\MessageProducer.h" />
+ <ClInclude Include="LibLsp\JsonRpc\RequestInMessage.h" />
+ <ClInclude Include="LibLsp\JsonRpc\ScopeExit.h" />
+ <ClInclude Include="LibLsp\JsonRpc\serializer.h" />
+ <ClInclude Include="LibLsp\JsonRpc\stream.h" />
+ <ClInclude Include="LibLsp\JsonRpc\StreamMessageProducer.h" />
+ <ClInclude Include="LibLsp\JsonRpc\TcpServer.h" />
+ <ClInclude Include="LibLsp\JsonRpc\threaded_queue.h" />
+ <ClInclude Include="LibLsp\JsonRpc\traits.h" />
+ <ClInclude Include="LibLsp\JsonRpc\WebSocketServer.h" />
+ <ClInclude Include="LibLsp\lsp\AbsolutePath.h" />
+ <ClInclude Include="LibLsp\lsp\ClientPreferences.h" />
+ <ClInclude Include="LibLsp\lsp\client\registerCapability.h" />
+ <ClInclude Include="LibLsp\lsp\client\unregisterCapability.h" />
+ <ClInclude Include="LibLsp\lsp\CodeActionParams.h" />
+ <ClInclude Include="LibLsp\lsp\Directory.h" />
+ <ClInclude Include="LibLsp\lsp\ExecuteCommandParams.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\addOverridableMethods.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\buildWorkspace.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\checkConstructorsStatus.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\checkDelegateMethodsStatus.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\checkHashCodeEqualsStatus.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\checkToStringStatus.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\classFileContents.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\codeActionResult.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\executeCommand.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\findLinks.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\generateAccessors.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\generateConstructors.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\generateDelegateMethods.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\generateHashCodeEquals.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\generateToString.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\getMoveDestinations.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\getRefactorEdit.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\listOverridableMethods.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\Move.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\organizeImports.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\OverridableMethod.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\projectConfigurationUpdate.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\resolveUnimplementedAccessors.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\searchSymbols.h" />
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\WorkspaceSymbolParams.h" />
+ <ClInclude Include="LibLsp\lsp\extention\sct\protocol.h" />
+ <ClInclude Include="LibLsp\lsp\extention\sct\sct.h" />
+ <ClInclude Include="LibLsp\lsp\extention\sct\SCTConfig.h" />
+ <ClInclude Include="LibLsp\lsp\extention\sonarlint\protocol.h" />
+ <ClInclude Include="LibLsp\lsp\general\exit.h" />
+ <ClInclude Include="LibLsp\lsp\general\initialize.h" />
+ <ClInclude Include="LibLsp\lsp\general\initialized.h" />
+ <ClInclude Include="LibLsp\lsp\general\InitializeParams.h" />
+ <ClInclude Include="LibLsp\lsp\general\lsClientCapabilities.h" />
+ <ClInclude Include="LibLsp\lsp\general\lsServerCapabilities.h" />
+ <ClInclude Include="LibLsp\lsp\general\lsTextDocumentClientCapabilities.h" />
+ <ClInclude Include="LibLsp\lsp\general\lsWorkspaceClientCapabilites.h" />
+ <ClInclude Include="LibLsp\lsp\general\progress.h" />
+ <ClInclude Include="LibLsp\lsp\general\shutdown.h" />
+ <ClInclude Include="LibLsp\lsp\IProgressMonitor.h" />
+ <ClInclude Include="LibLsp\lsp\language\language.h" />
+ <ClInclude Include="LibLsp\lsp\location_type.h" />
+ <ClInclude Include="LibLsp\lsp\lru_cache.h" />
+ <ClInclude Include="LibLsp\lsp\lsAny.h" />
+ <ClInclude Include="LibLsp\lsp\lsCodeAction.h" />
+ <ClInclude Include="LibLsp\lsp\lsCommand.h" />
+ <ClInclude Include="LibLsp\lsp\lsDocumentUri.h" />
+ <ClInclude Include="LibLsp\lsp\lsFormattingOptions.h" />
+ <ClInclude Include="LibLsp\lsp\lsMarkedString.h" />
+ <ClInclude Include="LibLsp\lsp\lsPosition.h" />
+ <ClInclude Include="LibLsp\lsp\lsp_code_action.h" />
+ <ClInclude Include="LibLsp\lsp\lsp_completion.h" />
+ <ClInclude Include="LibLsp\lsp\lsp_diagnostic.h" />
+ <ClInclude Include="LibLsp\lsp\lsRange.h" />
+ <ClInclude Include="LibLsp\lsp\lsResponseError.h" />
+ <ClInclude Include="LibLsp\lsp\lsTextDocumentEdit.h" />
+ <ClInclude Include="LibLsp\lsp\lsTextDocumentIdentifier.h" />
+ <ClInclude Include="LibLsp\lsp\lsTextDocumentItem.h" />
+ <ClInclude Include="LibLsp\lsp\lsTextDocumentPositionParams.h" />
+ <ClInclude Include="LibLsp\lsp\lsTextEdit.h" />
+ <ClInclude Include="LibLsp\lsp\lsVersionedTextDocumentIdentifier.h" />
+ <ClInclude Include="LibLsp\lsp\lsWorkspaceEdit.h" />
+ <ClInclude Include="LibLsp\lsp\Markup\Markup.h" />
+ <ClInclude Include="LibLsp\lsp\Markup\string_ref.h" />
+ <ClInclude Include="LibLsp\lsp\method_type.h" />
+ <ClInclude Include="LibLsp\lsp\out_list.h" />
+ <ClInclude Include="LibLsp\lsp\ParentProcessWatcher.h" />
+ <ClInclude Include="LibLsp\lsp\ProcessIoService.h" />
+ <ClInclude Include="LibLsp\lsp\ProtocolJsonHandler.h" />
+ <ClInclude Include="LibLsp\lsp\ResourceOperation.h" />
+ <ClInclude Include="LibLsp\lsp\SimpleTimer.h" />
+ <ClInclude Include="LibLsp\lsp\symbol.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\callHierarchy.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\code_action.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\code_lens.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\colorPresentation.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\completion.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\declaration_definition.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\didRenameFiles.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\did_change.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\did_close.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\did_open.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\did_save.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\documentColor.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\document_link.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\document_symbol.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\foldingRange.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\formatting.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\highlight.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\hover.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\implementation.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\linkedEditingRange.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\onTypeFormatting.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\prepareRename.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\publishDiagnostics.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\range_formatting.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\references.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\rename.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\resolveCodeLens.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\resolveCompletionItem.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\resolveTypeHierarchy.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\selectionRange.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\semanticHighlighting.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\SemanticTokens.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\signature_help.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\typeHierarchy.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\type_definition.h" />
+ <ClInclude Include="LibLsp\lsp\textDocument\willSave.h" />
+ <ClInclude Include="LibLsp\lsp\utils.h" />
+ <ClInclude Include="LibLsp\lsp\windows\MessageNotify.h" />
+ <ClInclude Include="LibLsp\lsp\working_files.h" />
+ <ClInclude Include="LibLsp\lsp\workspace\applyEdit.h" />
+ <ClInclude Include="LibLsp\lsp\workspace\configuration.h" />
+ <ClInclude Include="LibLsp\lsp\workspace\didChangeWorkspaceFolders.h" />
+ <ClInclude Include="LibLsp\lsp\workspace\did_change_configuration.h" />
+ <ClInclude Include="LibLsp\lsp\workspace\did_change_watched_files.h" />
+ <ClInclude Include="LibLsp\lsp\workspace\execute_command.h" />
+ <ClInclude Include="LibLsp\lsp\workspace\symbol.h" />
+ <ClInclude Include="LibLsp\lsp\workspace\workspaceFolders.h" />
+ <ClInclude Include="network\optional.hpp" />
+ <ClInclude Include="network\string_view.hpp" />
+ <ClInclude Include="network\uri.hpp" />
+ <ClInclude Include="network\uri\config.hpp" />
+ <ClInclude Include="network\uri\detail\algorithm.hpp" />
+ <ClInclude Include="network\uri\detail\decode.hpp" />
+ <ClInclude Include="network\uri\detail\encode.hpp" />
+ <ClInclude Include="network\uri\detail\grammar.hpp" />
+ <ClInclude Include="network\uri\detail\translate.hpp" />
+ <ClInclude Include="network\uri\detail\uri_advance_parts.hpp" />
+ <ClInclude Include="network\uri\detail\uri_normalize.hpp" />
+ <ClInclude Include="network\uri\detail\uri_parse.hpp" />
+ <ClInclude Include="network\uri\detail\uri_parse_authority.hpp" />
+ <ClInclude Include="network\uri\detail\uri_parts.hpp" />
+ <ClInclude Include="network\uri\detail\uri_percent_encode.hpp" />
+ <ClInclude Include="network\uri\detail\uri_resolve.hpp" />
+ <ClInclude Include="network\uri\uri.hpp" />
+ <ClInclude Include="network\uri\uri_builder.hpp" />
+ <ClInclude Include="network\uri\uri_errors.hpp" />
+ <ClInclude Include="network\uri\uri_io.hpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ <Import Project="packages\tencent.rapidjson.1.1.1\build\tencent.rapidjson.targets" Condition="Exists('packages\tencent.rapidjson.1.1.1\build\tencent.rapidjson.targets')" />
+ <Import Project="..\packages\boost.1.76.0.0\build\boost.targets" Condition="Exists('..\packages\boost.1.76.0.0\build\boost.targets')" />
+ <Import Project="..\packages\boost_chrono-vc141.1.76.0.0\build\boost_chrono-vc141.targets" Condition="Exists('..\packages\boost_chrono-vc141.1.76.0.0\build\boost_chrono-vc141.targets')" />
+ <Import Project="..\packages\boost_context-vc141.1.76.0.0\build\boost_context-vc141.targets" Condition="Exists('..\packages\boost_context-vc141.1.76.0.0\build\boost_context-vc141.targets')" />
+ <Import Project="..\packages\boost_coroutine-vc141.1.76.0.0\build\boost_coroutine-vc141.targets" Condition="Exists('..\packages\boost_coroutine-vc141.1.76.0.0\build\boost_coroutine-vc141.targets')" />
+ <Import Project="..\packages\boost_date_time-vc141.1.76.0.0\build\boost_date_time-vc141.targets" Condition="Exists('..\packages\boost_date_time-vc141.1.76.0.0\build\boost_date_time-vc141.targets')" />
+ <Import Project="..\packages\boost_filesystem-vc141.1.76.0.0\build\boost_filesystem-vc141.targets" Condition="Exists('..\packages\boost_filesystem-vc141.1.76.0.0\build\boost_filesystem-vc141.targets')" />
+ <Import Project="..\packages\boost_program_options-vc141.1.76.0.0\build\boost_program_options-vc141.targets" Condition="Exists('..\packages\boost_program_options-vc141.1.76.0.0\build\boost_program_options-vc141.targets')" />
+ <Import Project="..\packages\boost_regex-vc141.1.76.0.0\build\boost_regex-vc141.targets" Condition="Exists('..\packages\boost_regex-vc141.1.76.0.0\build\boost_regex-vc141.targets')" />
+ <Import Project="..\packages\boost_system-vc140.1.76.0.0\build\boost_system-vc140.targets" Condition="Exists('..\packages\boost_system-vc140.1.76.0.0\build\boost_system-vc140.targets')" />
+ <Import Project="..\packages\boost_thread-vc141.1.76.0.0\build\boost_thread-vc141.targets" Condition="Exists('..\packages\boost_thread-vc141.1.76.0.0\build\boost_thread-vc141.targets')" />
+ </ImportGroup>
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('..\packages\boost.1.76.0.0\build\boost.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost.1.76.0.0\build\boost.targets'))" />
+ <Error Condition="!Exists('..\packages\boost_chrono-vc141.1.76.0.0\build\boost_chrono-vc141.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_chrono-vc141.1.76.0.0\build\boost_chrono-vc141.targets'))" />
+ <Error Condition="!Exists('..\packages\boost_context-vc141.1.76.0.0\build\boost_context-vc141.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_context-vc141.1.76.0.0\build\boost_context-vc141.targets'))" />
+ <Error Condition="!Exists('..\packages\boost_coroutine-vc141.1.76.0.0\build\boost_coroutine-vc141.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_coroutine-vc141.1.76.0.0\build\boost_coroutine-vc141.targets'))" />
+ <Error Condition="!Exists('..\packages\boost_date_time-vc141.1.76.0.0\build\boost_date_time-vc141.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_date_time-vc141.1.76.0.0\build\boost_date_time-vc141.targets'))" />
+ <Error Condition="!Exists('..\packages\boost_filesystem-vc141.1.76.0.0\build\boost_filesystem-vc141.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_filesystem-vc141.1.76.0.0\build\boost_filesystem-vc141.targets'))" />
+ <Error Condition="!Exists('..\packages\boost_program_options-vc141.1.76.0.0\build\boost_program_options-vc141.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_program_options-vc141.1.76.0.0\build\boost_program_options-vc141.targets'))" />
+ <Error Condition="!Exists('..\packages\boost_regex-vc141.1.76.0.0\build\boost_regex-vc141.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_regex-vc141.1.76.0.0\build\boost_regex-vc141.targets'))" />
+ <Error Condition="!Exists('..\packages\boost_system-vc140.1.76.0.0\build\boost_system-vc140.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_system-vc140.1.76.0.0\build\boost_system-vc140.targets'))" />
+ <Error Condition="!Exists('..\packages\boost_thread-vc141.1.76.0.0\build\boost_thread-vc141.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_thread-vc141.1.76.0.0\build\boost_thread-vc141.targets'))" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LspCpp.vcxproj.filters b/graphics/asymptote/LspCpp/LspCpp.vcxproj.filters
new file mode 100644
index 0000000000..6402988303
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LspCpp.vcxproj.filters
@@ -0,0 +1,669 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="LibLsp\JsonRpc\StreamMessageProducer.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\MessageJsonHandler.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\Endpoint.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\message.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\RemoteEndPoint.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\ProtocolJsonHandler.cpp">
+ <Filter>lsp</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\general\initialize.cpp">
+ <Filter>lsp\general</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\textDocument\textDocument.cpp">
+ <Filter>lsp\textDocument</Filter>
+ </ClCompile>
+ <ClCompile Include="network\uri\detail\uri_advance_parts.cpp">
+ <Filter>network\uri\detail</Filter>
+ </ClCompile>
+ <ClCompile Include="network\uri\detail\uri_normalize.cpp">
+ <Filter>network\uri\detail</Filter>
+ </ClCompile>
+ <ClCompile Include="network\uri\detail\uri_parse.cpp">
+ <Filter>network\uri\detail</Filter>
+ </ClCompile>
+ <ClCompile Include="network\uri\detail\uri_parse_authority.cpp">
+ <Filter>network\uri\detail</Filter>
+ </ClCompile>
+ <ClCompile Include="network\uri\detail\uri_resolve.cpp">
+ <Filter>network\uri\detail</Filter>
+ </ClCompile>
+ <ClCompile Include="network\uri\uri.cpp">
+ <Filter>network\uri</Filter>
+ </ClCompile>
+ <ClCompile Include="network\uri\uri_builder.cpp">
+ <Filter>network\uri</Filter>
+ </ClCompile>
+ <ClCompile Include="network\uri\uri_errors.cpp">
+ <Filter>network\uri</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\TcpServer.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\WebSocketServer.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="example\StdIOClientExample.cpp">
+ <Filter>example</Filter>
+ </ClCompile>
+ <ClCompile Include="example\StdIOServerExample.cpp">
+ <Filter>example</Filter>
+ </ClCompile>
+ <ClCompile Include="example\TcpServerExample.cpp">
+ <Filter>example</Filter>
+ </ClCompile>
+ <ClCompile Include="example\WebsocketExample.cpp">
+ <Filter>example</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\extention\sct\sct.cpp">
+ <Filter>lsp\extention\sct</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\serializer.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\threaded_queue.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\lsp.cpp">
+ <Filter>lsp</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\lsp_diagnostic.cpp">
+ <Filter>lsp</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\utils.cpp">
+ <Filter>lsp</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\working_files.cpp">
+ <Filter>lsp</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\ParentProcessWatcher.cpp">
+ <Filter>lsp</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\Context.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\lsp\Markup\Markup.cpp">
+ <Filter>lsp\markdown</Filter>
+ </ClCompile>
+ <ClCompile Include="LibLsp\JsonRpc\GCThreadContext.cpp">
+ <Filter>JsonRpc</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="LibLsp\JsonRpc\MessageIssue.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\MessageProducer.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\StreamMessageProducer.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\MessageJsonHandler.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\Endpoint.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\serializer.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\RemoteEndPoint.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\Cancellation.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\message.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\location_type.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lru_cache.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsCommand.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsDocumentUri.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsFormattingOptions.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsMarkedString.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsp_code_action.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsp_completion.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsp_diagnostic.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsPosition.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsRange.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsResponseError.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsTextDocumentEdit.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsTextDocumentIdentifier.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsTextDocumentItem.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsTextDocumentPositionParams.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsTextEdit.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsVersionedTextDocumentIdentifier.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsWorkspaceEdit.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\method_type.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\out_list.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\ProtocolJsonHandler.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\symbol.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\exit.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\initialize.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\initialized.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\callHierarchy.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\code_action.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\code_lens.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\completion.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\did_change.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\did_close.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\did_open.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\did_save.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\document_link.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\document_symbol.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\formatting.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\highlight.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\hover.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\implementation.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\range_formatting.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\references.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\rename.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\signature_help.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\type_definition.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\typeHierarchy.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\did_change_configuration.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\did_change_watched_files.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\execute_command.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\symbol.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\ResourceOperation.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsCodeAction.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\workspaceFolders.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\applyEdit.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\configuration.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\semanticHighlighting.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\publishDiagnostics.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\workspace\didChangeWorkspaceFolders.h">
+ <Filter>lsp\workspace</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\resolveCompletionItem.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\declaration_definition.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\lsAny.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\CodeActionParams.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\InitializeParams.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\lsServerCapabilities.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\lsClientCapabilities.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\lsWorkspaceClientCapabilites.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\lsTextDocumentClientCapabilities.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\ExecuteCommandParams.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\resolveCodeLens.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\onTypeFormatting.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\willSave.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\documentColor.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\colorPresentation.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\foldingRange.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\prepareRename.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\resolveTypeHierarchy.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\selectionRange.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\threaded_queue.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\Condition.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\lsRequestId.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\RequestInMessage.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\NotificationInMessage.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\lsResponseMessage.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\windows\MessageNotify.h">
+ <Filter>lsp\windows</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\AbsolutePath.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\json.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\shutdown.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="network\optional.hpp">
+ <Filter>network</Filter>
+ </ClInclude>
+ <ClInclude Include="network\string_view.hpp">
+ <Filter>network</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri.hpp">
+ <Filter>network</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\detail\algorithm.hpp">
+ <Filter>network\uri\detail</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\detail\decode.hpp">
+ <Filter>network\uri\detail</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\detail\encode.hpp">
+ <Filter>network\uri\detail</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\detail\grammar.hpp">
+ <Filter>network\uri\detail</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\detail\translate.hpp">
+ <Filter>network\uri\detail</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\detail\uri_advance_parts.hpp">
+ <Filter>network\uri\detail</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\detail\uri_normalize.hpp">
+ <Filter>network\uri\detail</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\detail\uri_parse.hpp">
+ <Filter>network\uri\detail</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\detail\uri_parse_authority.hpp">
+ <Filter>network\uri\detail</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\detail\uri_parts.hpp">
+ <Filter>network\uri\detail</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\detail\uri_percent_encode.hpp">
+ <Filter>network\uri\detail</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\detail\uri_resolve.hpp">
+ <Filter>network\uri\detail</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\config.hpp">
+ <Filter>network\uri</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\uri.hpp">
+ <Filter>network\uri</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\uri_builder.hpp">
+ <Filter>network\uri</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\uri_errors.hpp">
+ <Filter>network\uri</Filter>
+ </ClInclude>
+ <ClInclude Include="network\uri\uri_io.hpp">
+ <Filter>network\uri</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\language\language.h">
+ <Filter>lsp\language</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\client\registerCapability.h">
+ <Filter>lsp\client</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\client\unregisterCapability.h">
+ <Filter>lsp\client</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\TcpServer.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\didRenameFiles.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\stream.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\WebSocketServer.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\addOverridableMethods.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\buildWorkspace.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\checkConstructorsStatus.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\checkDelegateMethodsStatus.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\checkHashCodeEqualsStatus.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\checkToStringStatus.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\classFileContents.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\codeActionResult.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\executeCommand.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\findLinks.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\generateAccessors.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\generateConstructors.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\generateDelegateMethods.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\generateHashCodeEquals.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\generateToString.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\getMoveDestinations.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\getRefactorEdit.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\listOverridableMethods.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\Move.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\organizeImports.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\OverridableMethod.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\projectConfigurationUpdate.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\resolveUnimplementedAccessors.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\searchSymbols.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\jdtls\WorkspaceSymbolParams.h">
+ <Filter>lsp\extention\jdtls</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\sct\sct.h">
+ <Filter>lsp\extention\sct</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\sct\SCTConfig.h">
+ <Filter>lsp\extention\sct</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\sct\protocol.h">
+ <Filter>lsp\extention\sct</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\extention\sonarlint\protocol.h">
+ <Filter>lsp\extention\sonarlint</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\utils.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\working_files.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\Directory.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\SimpleTimer.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\general\progress.h">
+ <Filter>lsp\general</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\ParentProcessWatcher.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\ProcessIoService.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\Context.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\ScopeExit.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\SemanticTokens.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\textDocument\linkedEditingRange.h">
+ <Filter>lsp\textDocument</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\IProgressMonitor.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\Markup\Markup.h">
+ <Filter>lsp\markdown</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\Markup\string_ref.h">
+ <Filter>lsp\markdown</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\traits.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\JsonRpc\GCThreadContext.h">
+ <Filter>JsonRpc</Filter>
+ </ClInclude>
+ <ClInclude Include="LibLsp\lsp\ClientPreferences.h">
+ <Filter>lsp</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="JsonRpc">
+ <UniqueIdentifier>{1da4afb3-155d-423f-96b0-1b8da9acc00a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp">
+ <UniqueIdentifier>{e7d76738-44b8-4a69-a1c4-2faa28c9a4e4}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\workspace">
+ <UniqueIdentifier>{b79907e9-c622-4c4a-ba4a-856d5a924cb3}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\textDocument">
+ <UniqueIdentifier>{b5ab5370-6e7b-4a19-b08a-0d60880be5c2}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\windows">
+ <UniqueIdentifier>{24b7fc1b-1430-4833-afc1-7215028d56b3}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\general">
+ <UniqueIdentifier>{09427494-f677-443b-b1f9-20cf6e6976f5}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="network">
+ <UniqueIdentifier>{43293649-591a-46e4-ae6d-93de432e5202}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="network\uri">
+ <UniqueIdentifier>{8e1c4f26-61b7-45f3-9fca-8a709d53e924}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="network\uri\detail">
+ <UniqueIdentifier>{fca88b35-e5ec-4b6c-8e48-e7ddb54f6c5f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\language">
+ <UniqueIdentifier>{c2661f3d-8e6b-4e9c-9f8f-7b1c533198a9}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\client">
+ <UniqueIdentifier>{7dc366bb-0edc-4d01-b61b-b9a25911ab44}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="example">
+ <UniqueIdentifier>{50042bb3-ac58-43e1-8cbe-0af2d1c58599}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\extention">
+ <UniqueIdentifier>{0091cb64-52d3-4c82-a25a-0a9b976182fe}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\extention\sct">
+ <UniqueIdentifier>{9a310695-9678-42c9-9085-412e178574d4}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\extention\jdtls">
+ <UniqueIdentifier>{b2e6e5b5-343f-4098-8105-4f054b3e9b38}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\extention\sonarlint">
+ <UniqueIdentifier>{11198774-b392-4339-b654-17aee0eeaa21}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="lsp\markdown">
+ <UniqueIdentifier>{4ce2a4b8-aa8d-462b-a6c9-c11b56e3bb2d}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/LspCpp.vcxproj.user b/graphics/asymptote/LspCpp/LspCpp.vcxproj.user
new file mode 100644
index 0000000000..88a550947e
--- /dev/null
+++ b/graphics/asymptote/LspCpp/LspCpp.vcxproj.user
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup />
+</Project> \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/Makefile b/graphics/asymptote/LspCpp/Makefile
new file mode 100644
index 0000000000..72d5c3fedf
--- /dev/null
+++ b/graphics/asymptote/LspCpp/Makefile
@@ -0,0 +1,40 @@
+CXX=g++
+
+CFLAGS = -Wall -fPIE
+INCLUDES=-I. -ILibLsp/lsp/extention/jdtls/ -ILibLsp/JsonRpc/ -ILibLsp/JsonRpc/lsp/extention/jdtls \
+ -Ithird_party/threadpool -Ithird_party/utfcpp/source -Ithird_party/rapidjson/include
+CXXFLAGS = -std=c++14
+OPTFLAGS = -O3
+
+ALL_CXXFLAGS = $(CFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(OPTFLAGS)
+
+NETWORKS_DETAIL = $(addprefix detail/, uri_advance_parts.o \
+ uri_normalize.o uri_parse.o uri_parse_authority.o uri_resolve.o)
+NETWORK_FILES = $(addprefix uri/, uri.o uri_builder.o uri_errors.o $(NETWORKS_DETAIL))
+LSP_FILES = extention/sct/sct.o general/initialize.o lsp.o lsp_diagnostic.o \
+ ProtocolJsonHandler.o textDocument/textDocument.o Markup/Markup.o ParentProcessWatcher.o \
+ utils.o working_files.o
+JSONRPC_FILES = TcpServer.o threaded_queue.o WebSocketServer.o RemoteEndPoint.o \
+ Endpoint.o message.o MessageJsonHandler.o serializer.o StreamMessageProducer.o \
+ Context.o GCThreadContext.o
+
+OFILES = $(addprefix ./network/,$(NETWORK_FILES)) \
+ $(addprefix ./LibLsp/lsp/, $(LSP_FILES)) \
+ $(addprefix ./LibLsp/JsonRpc/, $(JSONRPC_FILES))
+
+HEADERS = $(shell find ./LibLsp ./network -regex ".*\.\(h\|hpp\)")
+
+default: liblspcpp.a headers.tar.gz
+
+liblspcpp.a: $(OFILES)
+ ar -r $@ $^
+
+headers.tar.gz: $(HEADERS) macro_map.h
+ tar -czf $@ $^
+
+%.o: %.cpp
+ $(CXX) $(ALL_CXXFLAGS) $< -c -o $@
+
+clean:
+ find ./ -name *.o | xargs rm -rf
+ rm -rf *.a *.tar.gz
diff --git a/graphics/asymptote/LspCpp/README.md b/graphics/asymptote/LspCpp/README.md
new file mode 100644
index 0000000000..4c279f7f4a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/README.md
@@ -0,0 +1,48 @@
+# LspCpp
+
+## Dependencies
+`LspCpp` depends on the boost and rapidjson,utfcpp,and threadpool
+
+## Build
+
+### Linux
+ 1. Install boost
+ ```shell
+ $ sudo apt-get install libboost-dev
+ ```
+ 2. [Restore the submodules][4].
+ ```shell
+ $ git submodule init
+ $ git submodule update
+ ```
+ 3. Build it.
+ ```shell
+ $ make
+ ```
+### Windows
+ 1. Open project with Vistual Studio.
+ 2. [Restore packages][3] with Vistual Studio.
+ 3. [Restore the submodules][4].
+ ```shell
+ git submodule init
+ git submodule update
+ ```
+ 4. Build it with Vistual Studio.
+
+## Reference
+ Some code from :[cquery][1]
+
+## Projects using LspCpp:
+* [JCIDE](https://www.javacardos.com/tools)
+* [LPG-language-server](https://github.com/kuafuwang/LPG-language-server)
+## License
+ MIT
+
+## Example:
+[It's here](https://github.com/kuafuwang/LspCpp/tree/master/example)
+
+
+[1]: https://github.com/cquery-project/cquery "cquery:"
+[2]: https://www.javacardos.com/tools "JcKit:"
+[3]: https://docs.microsoft.com/en-us/nuget/consume-packages/package-restore "Package Restore"
+[4]: https://git-scm.com/book/en/v2/Git-Tools-Submodules "Git-Tools-Submodules"
diff --git a/graphics/asymptote/LspCpp/example/StdIOClientExample.cpp b/graphics/asymptote/LspCpp/example/StdIOClientExample.cpp
new file mode 100644
index 0000000000..1c73626a45
--- /dev/null
+++ b/graphics/asymptote/LspCpp/example/StdIOClientExample.cpp
@@ -0,0 +1,221 @@
+
+#include "LibLsp/lsp/ProcessIoService.h"
+#ifdef STDIO_CLIENT_EXAMPLE
+
+#include <boost/program_options.hpp>
+#include "LibLsp/lsp/general/exit.h"
+#include "LibLsp/lsp/textDocument/declaration_definition.h"
+
+#include "LibLsp/lsp/textDocument/signature_help.h"
+#include "LibLsp/lsp/general/initialize.h"
+#include "LibLsp/lsp/ProtocolJsonHandler.h"
+#include "LibLsp/lsp/textDocument/typeHierarchy.h"
+#include "LibLsp/lsp/AbsolutePath.h"
+#include "LibLsp/lsp/textDocument/resolveCompletionItem.h"
+#include <network/uri.hpp>
+#include "LibLsp/JsonRpc/Endpoint.h"
+#include "LibLsp/JsonRpc/stream.h"
+#include "LibLsp/JsonRpc/TcpServer.h"
+#include "LibLsp/lsp/textDocument/document_symbol.h"
+#include "LibLsp/lsp/workspace/execute_command.h"
+#include <boost/process.hpp>
+#include <boost/process/windows.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/asio.hpp>
+#include <iostream>
+
+
+using namespace boost::asio::ip;
+using namespace std;
+class DummyLog :public lsp::Log
+{
+public:
+
+ void log(Level level, std::wstring&& msg)
+ {
+
+ std::wcerr << msg << std::endl;
+ };
+ void log(Level level, const std::wstring& msg)
+ {
+ std::wcerr << msg << std::endl;
+ };
+ void log(Level level, std::string&& msg)
+ {
+ std::cerr << msg << std::endl;
+ };
+ void log(Level level, const std::string& msg)
+ {
+ std::cerr << msg << std::endl;
+ };
+};
+
+struct boost_process_ipstream : lsp::base_istream< boost::process::ipstream >
+{
+ explicit boost_process_ipstream(boost::process::ipstream& _t)
+ : base_istream<boost::process::ipstream>(_t)
+ {
+ }
+
+ std::string what() override
+ {
+ return {};
+ }
+ void clear() override
+ {
+
+ }
+};
+struct boost_process_opstream : lsp::base_ostream< boost::process::opstream >
+{
+ explicit boost_process_opstream(boost::process::opstream& _t)
+ : lsp::base_ostream<boost::process::opstream>(_t)
+ {
+ }
+
+ std::string what() override
+ {
+ return {};
+ }
+ void clear() override
+ {
+
+ }
+};
+class Client
+{
+public:
+ Client(std::string& execPath,const std::vector<std::string>& args)
+ :point(protocol_json_handler, endpoint, _log)
+ {
+ std::error_code ec;
+ namespace bp = boost::process;
+ c = std::make_shared<bp::child>(asio_io.getIOService(), execPath,
+ bp::args = args,
+ ec,
+ bp::windows::show_normal,
+ bp::std_out > read_from_service,
+ bp::std_in < write_to_service,
+ bp::on_exit([&](int exit_code, const std::error_code& ec_in){
+
+ }));
+ if (ec)
+ {
+ // fail
+ _log.log(lsp::Log::Level::SEVERE, "Start server failed.");
+ }
+ else {
+ //success
+ point.startProcessingMessages(read_from_service_proxy, write_to_service_proxy);
+ }
+ }
+ ~Client()
+ {
+ point.Stop();
+ ::Sleep(1000);
+
+ }
+
+ lsp::ProcessIoService asio_io;
+ std::shared_ptr < lsp::ProtocolJsonHandler > protocol_json_handler = std::make_shared< lsp::ProtocolJsonHandler>();
+ DummyLog _log;
+
+ std::shared_ptr<GenericEndpoint> endpoint = std::make_shared<GenericEndpoint>(_log);
+
+ boost::process::opstream write_to_service;
+ boost::process::ipstream read_from_service;
+
+ std::shared_ptr<lsp::ostream> write_to_service_proxy = std::make_shared<boost_process_opstream>(write_to_service);
+ std::shared_ptr<lsp::istream> read_from_service_proxy = std::make_shared< boost_process_ipstream >(read_from_service);
+
+ std::shared_ptr<boost::process::child> c;
+ RemoteEndPoint point;
+};
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::program_options;
+ options_description desc("Allowed options");
+ desc.add_options()
+ ("help,h", "produce help message")
+ ("execPath", value<string>(), "LSP server's path");
+
+
+
+ variables_map vm;
+ try {
+ store(parse_command_line(argc, argv, desc), vm);
+ }
+ catch (std::exception& e) {
+ std::cout << "Undefined input.Reason:" << e.what() << std::endl;
+ return 0;
+ }
+ notify(vm);
+
+
+ if (vm.count("help"))
+ {
+ cout << desc << endl;
+ return 1;
+ }
+ string execPath;
+ if (vm.count("execPath"))
+ {
+ execPath = vm["execPath"].as<string>();
+ }
+ else
+ {
+ execPath = "STDIO_SERVER_EXAMPLE.exe";
+ }
+
+ Client client(execPath, {});
+ {
+ td_initialize::request req;
+ auto rsp = client.point.waitResponse(req);
+ if (rsp)
+ {
+ std::cerr << rsp->ToJson() << std::endl;
+ }
+ else
+ {
+ std::cerr << "get initialze response time out" << std::endl;
+ }
+ }
+ {
+ td_definition::request req;
+ auto future_rsp = client.point.send(req);
+ auto state = future_rsp.wait_for(std::chrono::seconds(4));
+ if (std::future_status::timeout == state)
+ {
+ std::cerr << "get textDocument/definition response time out" << std::endl;
+ return 0;
+ }
+ auto rsp = future_rsp.get();
+ if (rsp.is_error)
+ {
+ std::cerr << "get textDocument/definition response error" << std::endl;
+
+ }
+ else
+ {
+ std::cerr << rsp.response.ToJson() << std::endl;
+ }
+ }
+ {
+ td_initialize::request req;
+ auto rsp = client.point.waitResponse(req);
+ if (rsp)
+ {
+ std::cerr << rsp->ToJson() << std::endl;
+ }
+ else
+ {
+ std::cerr << "get initialze response time out" << std::endl;
+ }
+ }
+ Notify_Exit::notify notify;
+ client.point.send(notify);
+ return 0;
+}
+#endif
+
diff --git a/graphics/asymptote/LspCpp/example/StdIOServerExample.cpp b/graphics/asymptote/LspCpp/example/StdIOServerExample.cpp
new file mode 100644
index 0000000000..60b0d04db0
--- /dev/null
+++ b/graphics/asymptote/LspCpp/example/StdIOServerExample.cpp
@@ -0,0 +1,162 @@
+#include "LibLsp/JsonRpc/Condition.h"
+#ifdef STDIO_SERVER_EXAMPLE
+
+#include "LibLsp/lsp/general/exit.h"
+#include "LibLsp/lsp/textDocument/declaration_definition.h"
+#include <boost/program_options.hpp>
+#include "LibLsp/lsp/textDocument/signature_help.h"
+#include "LibLsp/lsp/general/initialize.h"
+#include "LibLsp/lsp/ProtocolJsonHandler.h"
+#include "LibLsp/lsp/textDocument/typeHierarchy.h"
+#include "LibLsp/lsp/AbsolutePath.h"
+#include "LibLsp/lsp/textDocument/resolveCompletionItem.h"
+#include <network/uri.hpp>
+
+
+#include "LibLsp/JsonRpc/Endpoint.h"
+#include "LibLsp/JsonRpc/stream.h"
+#include "LibLsp/JsonRpc/TcpServer.h"
+#include "LibLsp/lsp/textDocument/document_symbol.h"
+#include "LibLsp/lsp/workspace/execute_command.h"
+#include <boost/process.hpp>
+#include <boost/process/windows.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/asio.hpp>
+#include <iostream>
+using namespace boost::asio::ip;
+using namespace std;
+class DummyLog :public lsp::Log
+{
+public:
+
+ void log(Level level, std::wstring&& msg)
+ {
+
+ std::wcerr << msg << std::endl;
+ };
+ void log(Level level, const std::wstring& msg)
+ {
+ std::wcerr << msg << std::endl;
+ };
+ void log(Level level, std::string&& msg)
+ {
+ std::cerr << msg << std::endl;
+ };
+ void log(Level level, const std::string& msg)
+ {
+ std::cerr << msg << std::endl;
+ };
+};
+
+
+class StdIOServer
+{
+public:
+
+ StdIOServer() : remote_end_point_(protocol_json_handler, endpoint, _log)
+ {
+ remote_end_point_.registerHandler([&](const td_initialize::request& req)
+ {
+ td_initialize::response rsp;
+ rsp.id = req.id;
+ CodeLensOptions code_lens_options;
+ code_lens_options.resolveProvider = true;
+ rsp.result.capabilities.codeLensProvider = code_lens_options;
+ return rsp;
+ });
+
+ remote_end_point_.registerHandler([&](Notify_Exit::notify& notify)
+ {
+ remote_end_point_.Stop();
+ esc_event.notify(std::make_unique<bool>(true));
+ });
+ remote_end_point_.registerHandler([&](const td_definition::request& req,
+ const CancelMonitor& monitor)
+ {
+ td_definition::response rsp;
+ rsp.result.first = std::vector<lsLocation>();
+ if (monitor && monitor())
+ {
+ _log.info("textDocument/definition request had been cancel.");
+ }
+ return rsp;
+ });
+
+ remote_end_point_.startProcessingMessages(input, output);
+ }
+ ~StdIOServer()
+ {
+
+ }
+
+ struct ostream : lsp::base_ostream<std::ostream>
+ {
+ explicit ostream(std::ostream& _t)
+ : base_ostream<std::ostream>(_t)
+ {
+
+ }
+
+ std::string what() override
+ {
+ return {};
+ }
+ };
+ struct istream :lsp::base_istream<std::istream>
+ {
+ explicit istream(std::istream& _t)
+ : base_istream<std::istream>(_t)
+ {
+ }
+
+ std::string what() override
+ {
+ return {};
+ }
+ };
+ std::shared_ptr < lsp::ProtocolJsonHandler > protocol_json_handler = std::make_shared < lsp::ProtocolJsonHandler >();
+ DummyLog _log;
+
+ std::shared_ptr<ostream> output = std::make_shared<ostream>(std::cout);
+ std::shared_ptr<istream> input = std::make_shared<istream>(std::cin);
+
+ std::shared_ptr < GenericEndpoint > endpoint = std::make_shared<GenericEndpoint>(_log);
+ RemoteEndPoint remote_end_point_;
+ Condition<bool> esc_event;
+};
+
+
+
+
+int main(int argc, char* argv[])
+{
+ using namespace boost::program_options;
+ options_description desc("Allowed options");
+ desc.add_options()
+ ("help,h", "produce help message");
+
+
+
+ variables_map vm;
+ try {
+ store(parse_command_line(argc, argv, desc), vm);
+ }
+ catch (std::exception& e) {
+ std::cout << "Undefined input.Reason:" << e.what() << std::endl;
+ return 0;
+ }
+ notify(vm);
+
+
+ if (vm.count("help"))
+ {
+ cout << desc << endl;
+ return 1;
+ }
+ StdIOServer server;
+ server.esc_event.wait();
+
+ return 0;
+}
+#endif
+
diff --git a/graphics/asymptote/LspCpp/example/TcpServerExample.cpp b/graphics/asymptote/LspCpp/example/TcpServerExample.cpp
new file mode 100644
index 0000000000..1b717aeca4
--- /dev/null
+++ b/graphics/asymptote/LspCpp/example/TcpServerExample.cpp
@@ -0,0 +1,200 @@
+#ifdef TCP_SERVER_EXAMPLE
+
+#include "LibLsp/lsp/general/exit.h"
+#include "LibLsp/lsp/textDocument/declaration_definition.h"
+#include "LibLsp/lsp/textDocument/signature_help.h"
+#include "LibLsp/lsp/general/initialize.h"
+#include "LibLsp/lsp/ProtocolJsonHandler.h"
+#include "LibLsp/lsp/textDocument/typeHierarchy.h"
+#include "LibLsp/lsp/AbsolutePath.h"
+#include "LibLsp/lsp/textDocument/resolveCompletionItem.h"
+#include <network/uri.hpp>
+
+
+#include "LibLsp/JsonRpc/Endpoint.h"
+#include "LibLsp/JsonRpc/stream.h"
+#include "LibLsp/JsonRpc/TcpServer.h"
+#include "LibLsp/lsp/textDocument/document_symbol.h"
+#include "LibLsp/lsp/workspace/execute_command.h"
+
+#include <boost/filesystem.hpp>
+#include <boost/asio.hpp>
+#include <iostream>
+using namespace boost::asio::ip;
+using namespace std;
+class DummyLog :public lsp::Log
+{
+public:
+
+ void log(Level level, std::wstring&& msg)
+ {
+ std::wcout << msg << std::endl;
+ };
+ void log(Level level, const std::wstring& msg)
+ {
+ std::wcout << msg << std::endl;
+ };
+ void log(Level level, std::string&& msg)
+ {
+ std::cout << msg << std::endl;
+ };
+ void log(Level level, const std::string& msg)
+ {
+ std::cout << msg << std::endl;
+ };
+};
+
+std::string _address = "127.0.0.1";
+std::string _port = "9333";
+
+class Server
+{
+public:
+
+
+ Server():server(_address,_port,protocol_json_handler, endpoint, _log)
+ {
+ server.point.registerHandler(
+ [&](const td_initialize::request& req)
+ ->lsp::ResponseOrError< td_initialize::response >{
+
+ td_initialize::response rsp;
+ CodeLensOptions code_lens_options;
+ code_lens_options.resolveProvider = true;
+ rsp.result.capabilities.codeLensProvider = code_lens_options;
+
+ return rsp;
+ });
+ server.point.registerHandler([&](const td_definition::request& req
+ ,const CancelMonitor& monitor)
+ {
+ td_definition::response rsp;
+ rsp.result.first= std::vector<lsLocation>();
+ std::this_thread::sleep_for(std::chrono::seconds(8));
+ if(monitor && monitor())
+ {
+ _log.info("textDocument/definition request had been cancel.");
+ }
+ return rsp;
+ });
+
+ server.point.registerHandler([=](Notify_Exit::notify& notify)
+ {
+ std::cout << notify.ToJson() << std::endl;
+ });
+ std::thread([&]()
+ {
+ server.run();
+ }).detach();
+ }
+ ~Server()
+ {
+ server.stop();
+ }
+ std::shared_ptr < lsp::ProtocolJsonHandler > protocol_json_handler = std::make_shared < lsp::ProtocolJsonHandler >();
+ DummyLog _log;
+
+ std::shared_ptr < GenericEndpoint > endpoint = std::make_shared<GenericEndpoint>(_log);
+ lsp::TcpServer server;
+
+};
+
+class Client
+{
+public:
+ struct iostream :public lsp::base_iostream<tcp::iostream>
+ {
+ explicit iostream(boost::asio::basic_socket_iostream<tcp>& _t)
+ : base_iostream<boost::asio::basic_socket_iostream<tcp>>(_t)
+ {
+ }
+
+ std::string what() override
+ {
+ auto msg = _impl.error().message();
+ return msg;
+ }
+
+ };
+ Client() :remote_end_point_(protocol_json_handler, endpoint, _log)
+ {
+ tcp::endpoint end_point( address::from_string(_address), 9333);
+
+ socket_ = std::make_shared<tcp::iostream>();
+ socket_->connect(end_point);
+ if (!socket_)
+ {
+ string temp = "Unable to connect: " + socket_->error().message();
+ std::cout << temp << std::endl;
+ }
+
+ vector<string> args;
+ socket_proxy = std::make_shared<iostream>(*socket_.get());
+
+ remote_end_point_.startProcessingMessages(socket_proxy, socket_proxy);
+ }
+ ~Client()
+ {
+ remote_end_point_.Stop();
+ ::Sleep(1000);
+ socket_->close();
+ }
+
+ std::shared_ptr < lsp::ProtocolJsonHandler > protocol_json_handler = std::make_shared< lsp::ProtocolJsonHandler>();
+ DummyLog _log;
+
+ std::shared_ptr<GenericEndpoint> endpoint = std::make_shared<GenericEndpoint>(_log);
+
+ std::shared_ptr < iostream> socket_proxy;
+ std::shared_ptr<tcp::iostream> socket_;
+ RemoteEndPoint remote_end_point_;
+};
+
+int main()
+{
+
+ Server server;
+ Client client;
+
+ {
+ td_initialize::request req;
+ auto rsp = client.remote_end_point_.waitResponse(req);
+ if (rsp)
+ {
+ std::cout << rsp->response.ToJson() << std::endl;
+ }
+ else
+ {
+ std::cout << "get initialze response time out" << std::endl;
+ }
+ }
+ {
+ td_definition::request req;
+ auto future_rsp = client.remote_end_point_.send(req);
+ Notify_Cancellation::notify cancel_notify;
+ cancel_notify.params.id = req.id;
+ client.remote_end_point_.send(cancel_notify);
+
+ auto state = future_rsp.wait_for(std::chrono::seconds(16));
+ if (std::future_status::timeout == state)
+ {
+ std::cout << "get textDocument/definition response time out" << std::endl;
+ return 0;
+ }
+ auto rsp = future_rsp.get();
+ if (rsp.is_error)
+ {
+ std::cout << "get textDocument/definition response error" << std::endl;
+
+ }
+ else
+ {
+ std::cout << rsp.response.ToJson() << std::endl;
+ }
+ }
+ Notify_Exit::notify notify;
+ client.remote_end_point_.send(notify);
+ return 0;
+}
+#endif
+
diff --git a/graphics/asymptote/LspCpp/example/WebsocketExample.cpp b/graphics/asymptote/LspCpp/example/WebsocketExample.cpp
new file mode 100644
index 0000000000..e82f0a96f9
--- /dev/null
+++ b/graphics/asymptote/LspCpp/example/WebsocketExample.cpp
@@ -0,0 +1,297 @@
+#ifdef WEBSOCKET_SERVER_EXAMPLE
+
+#include "LibLsp/JsonRpc/WebSocketServer.h"
+#include "LibLsp/lsp/textDocument/signature_help.h"
+#include "LibLsp/lsp/general/initialize.h"
+#include "LibLsp/lsp/ProtocolJsonHandler.h"
+#include "LibLsp/lsp/textDocument/typeHierarchy.h"
+#include "LibLsp/lsp/AbsolutePath.h"
+#include "LibLsp/lsp/textDocument/resolveCompletionItem.h"
+#include <network/uri.hpp>
+
+
+#include "LibLsp/JsonRpc/Endpoint.h"
+#include "LibLsp/JsonRpc/stream.h"
+#include "LibLsp/JsonRpc/TcpServer.h"
+#include "LibLsp/lsp/textDocument/document_symbol.h"
+#include "LibLsp/lsp/workspace/execute_command.h"
+
+#include <boost/filesystem.hpp>
+#include <boost/asio.hpp>
+#include <iostream>
+#include <boost/beast/core.hpp>
+#include <boost/beast/websocket.hpp>
+#include <boost/asio/dispatch.hpp>
+#include <boost/asio/strand.hpp>
+#include <algorithm>
+#include <cstdlib>
+#include <functional>
+#include <iostream>
+#include <memory>
+#include <string>
+#include <thread>
+#include <vector>
+
+#include <boost/beast/version.hpp>
+#include <boost/beast/websocket.hpp>
+#include <boost/asio/dispatch.hpp>
+#include "LibLsp/JsonRpc/Endpoint.h"
+#include "LibLsp/JsonRpc/RemoteEndPoint.h"
+#include "LibLsp/JsonRpc/stream.h"
+#include "LibLsp/lsp/ProtocolJsonHandler.h"
+
+namespace beast = boost::beast; // from <boost/beast.hpp>
+namespace http = beast::http; // from <boost/beast/http.hpp>
+namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
+namespace net = boost::asio; // from <boost/asio.hpp>
+using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
+
+//------------------------------------------------------------------------------
+
+std::string _address = "127.0.0.1";
+std::string _port = "9333";
+
+
+
+
+using namespace std;
+class DummyLog :public lsp::Log
+{
+public:
+
+ void log(Level level, std::wstring&& msg)
+ {
+ std::wcout << msg << std::endl;
+ };
+ void log(Level level, const std::wstring& msg)
+ {
+ std::wcout << msg << std::endl;
+ };
+ void log(Level level, std::string&& msg)
+ {
+ std::cout << msg << std::endl;
+ };
+ void log(Level level, const std::string& msg)
+ {
+ std::cout << msg << std::endl;
+ };
+};
+
+
+
+// Sends a WebSocket message and prints the response
+class Client : public std::enable_shared_from_this<Client>
+{
+ net::io_context ioc;
+ tcp::resolver resolver_;
+ websocket::stream<beast::tcp_stream> ws_;
+ beast::flat_buffer buffer_;
+ std::string host_;
+ std::string user_agent_;
+ std::shared_ptr < lsp::ProtocolJsonHandler > protocol_json_handler = std::make_shared< lsp::ProtocolJsonHandler>();
+ DummyLog _log;
+
+ std::shared_ptr<GenericEndpoint> endpoint = std::make_shared<GenericEndpoint>(_log);
+
+ std::shared_ptr<lsp::websocket_stream_wrapper> proxy_;
+public:
+ RemoteEndPoint point;
+
+public:
+ // Resolver and socket require an io_context
+ explicit
+ Client()
+ : resolver_(net::make_strand(ioc))
+ , ws_(net::make_strand(ioc)),point(protocol_json_handler, endpoint, _log)
+ {
+ proxy_ = std::make_shared<lsp::websocket_stream_wrapper>(ws_);
+
+ }
+
+ // Start the asynchronous operation
+ void
+ run(
+ char const* host,
+ char const* port, char const* user_agent)
+ {
+ // Save these for later
+ host_ = host;
+ user_agent_ = user_agent;
+ // Look up the domain name
+ resolver_.async_resolve(
+ host,
+ port,
+ beast::bind_front_handler(
+ &Client::on_resolve,
+ shared_from_this()));
+ std::thread([&]
+ {
+ ioc.run();
+ }).detach();
+ while (!point.IsWorking())
+ {
+ ::Sleep(50);
+ }
+ }
+
+ void
+ on_resolve(
+ beast::error_code ec,
+ tcp::resolver::results_type results)
+ {
+ if (ec)
+ return;
+
+ // Set the timeout for the operation
+ beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30));
+
+ // Make the connection on the IP address we get from a lookup
+ beast::get_lowest_layer(ws_).async_connect(
+ results,
+ beast::bind_front_handler(
+ &Client::on_connect,
+ shared_from_this()));
+ }
+
+ void
+ on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type)
+ {
+ if (ec)
+ return;
+
+ // Turn off the timeout on the tcp_stream, because
+ // the websocket stream has its own timeout system.
+ beast::get_lowest_layer(ws_).expires_never();
+
+ // Set suggested timeout settings for the websocket
+ ws_.set_option(
+ websocket::stream_base::timeout::suggested(
+ beast::role_type::client));
+
+ // Set a decorator to change the User-Agent of the handshake
+ ws_.set_option(websocket::stream_base::decorator(
+ [=](websocket::request_type& req)
+ {
+ req.set(http::field::user_agent,
+ user_agent_.c_str());
+ }));
+
+ // Perform the websocket handshake
+ ws_.async_handshake(host_, "/",
+ beast::bind_front_handler(
+ &Client::on_handshake,
+ shared_from_this()));
+ }
+
+ void
+ on_handshake(beast::error_code ec)
+ {
+ if (ec)
+ return;
+
+ // Send the message
+
+
+ point.startProcessingMessages(proxy_, proxy_);
+ // Read a message into our buffer
+ ws_.async_read(
+ buffer_,
+ beast::bind_front_handler(
+ &Client::on_read,
+ shared_from_this()));
+ }
+
+
+ void
+ on_read(
+ beast::error_code ec,
+ std::size_t bytes_transferred)
+ {
+ boost::ignore_unused(bytes_transferred);
+
+ if (ec)
+ return;
+
+ char* data = reinterpret_cast<char*>(buffer_.data().data());
+ std::vector<char> elements(data, data + bytes_transferred);
+ buffer_.clear();
+ proxy_->on_request.EnqueueAll(std::move(elements), false);
+
+ ws_.async_read(
+ buffer_,
+ beast::bind_front_handler(
+ &Client::on_read,
+ shared_from_this()));
+ }
+
+ void
+ on_close(beast::error_code ec)
+ {
+ if (ec)
+ return;
+
+ // If we get here then the connection is closed gracefully
+
+ // The make_printable() function helps print a ConstBufferSequence
+ std::cout << beast::make_printable(buffer_.data()) << std::endl;
+ }
+};
+
+class Server
+{
+public:
+ Server(const std::string& user_agent) : server(user_agent,_address, _port, protocol_json_handler, endpoint, _log)
+ {
+ server.point.registerHandler(
+ [&](const td_initialize::request& req)
+ {
+ td_initialize::response rsp;
+ CodeLensOptions code_lens_options;
+ code_lens_options.resolveProvider = true;
+ rsp.result.capabilities.codeLensProvider = code_lens_options;
+ return rsp;
+ });
+ std::thread([&]()
+ {
+ server.run();
+ }).detach();
+ }
+ ~Server()
+ {
+ server.stop();
+ }
+ std::shared_ptr < lsp::ProtocolJsonHandler > protocol_json_handler = std::make_shared < lsp::ProtocolJsonHandler >();
+ DummyLog _log;
+
+ std::shared_ptr < GenericEndpoint > endpoint = std::make_shared<GenericEndpoint>(_log);
+ lsp::WebSocketServer server;
+
+};
+
+int main()
+{
+ std::string user_agent = std::string(BOOST_BEAST_VERSION_STRING) +" websocket-server-async";
+ Server server(user_agent);
+
+ auto client = std::make_shared<Client>();
+ user_agent = std::string(BOOST_BEAST_VERSION_STRING) + " websocket-client-async";
+ client->run(_address.c_str(), _port.c_str(), user_agent.c_str());
+
+ td_initialize::request req;
+
+ auto rsp = client->point.waitResponse(req);
+ if (rsp)
+ {
+ std::cout << rsp->ToJson() << std::endl;
+ }
+ return 0;
+}
+
+
+
+
+
+#endif
+
+
+
diff --git a/graphics/asymptote/LspCpp/macro_map.h b/graphics/asymptote/LspCpp/macro_map.h
new file mode 100644
index 0000000000..f09ba5b1a7
--- /dev/null
+++ b/graphics/asymptote/LspCpp/macro_map.h
@@ -0,0 +1,134 @@
+/*
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+// Taken from https://github.com/cbeck88/visit_struct.
+//
+// Usage
+//
+// #define PRINT_DOUBLE(x) printf(#x " = %d\n", x);
+//
+// MACRO_MAP(PRINT_DOUBLE, 1, 2, 3)
+// #define PRINT_DOUBLES(...) MACRO_MAP(PRINT_DOUBLE, __VA_ARGS__)
+
+#pragma once
+
+static constexpr const int max_visitable_members = 69;
+
+#define VISIT_STRUCT_EXPAND(x) x
+#define VISIT_STRUCT_PP_ARG_N( \
+ _1, _2, _3, _4, _5, _6, _7, _8, _9, _10,\
+ _11, _12, _13, _14, _15, _16, _17, _18, _19, _20,\
+ _21, _22, _23, _24, _25, _26, _27, _28, _29, _30,\
+ _31, _32, _33, _34, _35, _36, _37, _38, _39, _40,\
+ _41, _42, _43, _44, _45, _46, _47, _48, _49, _50,\
+ _51, _52, _53, _54, _55, _56, _57, _58, _59, _60,\
+ _61, _62, _63, _64, _65, _66, _67, _68, _69, N, ...) N
+#define VISIT_STRUCT_PP_NARG(...) VISIT_STRUCT_EXPAND(VISIT_STRUCT_PP_ARG_N(__VA_ARGS__, \
+ 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, \
+ 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \
+ 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \
+ 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \
+ 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
+ 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
+ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
+
+/* need extra level to force extra eval */
+#define VISIT_STRUCT_CONCAT_(a,b) a ## b
+#define VISIT_STRUCT_CONCAT(a,b) VISIT_STRUCT_CONCAT_(a,b)
+
+#define VISIT_STRUCT_APPLYF0(f)
+#define VISIT_STRUCT_APPLYF1(f,_1) f(_1)
+#define VISIT_STRUCT_APPLYF2(f,_1,_2) f(_1) f(_2)
+#define VISIT_STRUCT_APPLYF3(f,_1,_2,_3) f(_1) f(_2) f(_3)
+#define VISIT_STRUCT_APPLYF4(f,_1,_2,_3,_4) f(_1) f(_2) f(_3) f(_4)
+#define VISIT_STRUCT_APPLYF5(f,_1,_2,_3,_4,_5) f(_1) f(_2) f(_3) f(_4) f(_5)
+#define VISIT_STRUCT_APPLYF6(f,_1,_2,_3,_4,_5,_6) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6)
+#define VISIT_STRUCT_APPLYF7(f,_1,_2,_3,_4,_5,_6,_7) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7)
+#define VISIT_STRUCT_APPLYF8(f,_1,_2,_3,_4,_5,_6,_7,_8) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8)
+#define VISIT_STRUCT_APPLYF9(f,_1,_2,_3,_4,_5,_6,_7,_8,_9) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9)
+#define VISIT_STRUCT_APPLYF10(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10)
+#define VISIT_STRUCT_APPLYF11(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11)
+#define VISIT_STRUCT_APPLYF12(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12)
+#define VISIT_STRUCT_APPLYF13(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13)
+#define VISIT_STRUCT_APPLYF14(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14)
+#define VISIT_STRUCT_APPLYF15(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15)
+#define VISIT_STRUCT_APPLYF16(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16)
+#define VISIT_STRUCT_APPLYF17(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17)
+#define VISIT_STRUCT_APPLYF18(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18)
+#define VISIT_STRUCT_APPLYF19(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19)
+#define VISIT_STRUCT_APPLYF20(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20)
+#define VISIT_STRUCT_APPLYF21(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21)
+#define VISIT_STRUCT_APPLYF22(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22)
+#define VISIT_STRUCT_APPLYF23(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23)
+#define VISIT_STRUCT_APPLYF24(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24)
+#define VISIT_STRUCT_APPLYF25(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25)
+#define VISIT_STRUCT_APPLYF26(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26)
+#define VISIT_STRUCT_APPLYF27(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27)
+#define VISIT_STRUCT_APPLYF28(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28)
+#define VISIT_STRUCT_APPLYF29(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29)
+#define VISIT_STRUCT_APPLYF30(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30)
+#define VISIT_STRUCT_APPLYF31(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31)
+#define VISIT_STRUCT_APPLYF32(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32)
+#define VISIT_STRUCT_APPLYF33(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33)
+#define VISIT_STRUCT_APPLYF34(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34)
+#define VISIT_STRUCT_APPLYF35(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35)
+#define VISIT_STRUCT_APPLYF36(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36)
+#define VISIT_STRUCT_APPLYF37(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37)
+#define VISIT_STRUCT_APPLYF38(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38)
+#define VISIT_STRUCT_APPLYF39(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39)
+#define VISIT_STRUCT_APPLYF40(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40)
+#define VISIT_STRUCT_APPLYF41(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41)
+#define VISIT_STRUCT_APPLYF42(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42)
+#define VISIT_STRUCT_APPLYF43(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43)
+#define VISIT_STRUCT_APPLYF44(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44)
+#define VISIT_STRUCT_APPLYF45(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45)
+#define VISIT_STRUCT_APPLYF46(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46)
+#define VISIT_STRUCT_APPLYF47(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47)
+#define VISIT_STRUCT_APPLYF48(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48)
+#define VISIT_STRUCT_APPLYF49(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49)
+#define VISIT_STRUCT_APPLYF50(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50)
+#define VISIT_STRUCT_APPLYF51(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51)
+#define VISIT_STRUCT_APPLYF52(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52)
+#define VISIT_STRUCT_APPLYF53(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53)
+#define VISIT_STRUCT_APPLYF54(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54)
+#define VISIT_STRUCT_APPLYF55(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55)
+#define VISIT_STRUCT_APPLYF56(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56)
+#define VISIT_STRUCT_APPLYF57(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57)
+#define VISIT_STRUCT_APPLYF58(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58)
+#define VISIT_STRUCT_APPLYF59(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59)
+#define VISIT_STRUCT_APPLYF60(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60)
+#define VISIT_STRUCT_APPLYF61(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61)
+#define VISIT_STRUCT_APPLYF62(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62)
+#define VISIT_STRUCT_APPLYF63(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) f(_63)
+#define VISIT_STRUCT_APPLYF64(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) f(_63) f(_64)
+#define VISIT_STRUCT_APPLYF65(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64,_65) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) f(_63) f(_64) f(_65)
+#define VISIT_STRUCT_APPLYF66(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64,_65,_66) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) f(_63) f(_64) f(_65) f(_66)
+#define VISIT_STRUCT_APPLYF67(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64,_65,_66,_67) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) f(_63) f(_64) f(_65) f(_66) f(_67)
+#define VISIT_STRUCT_APPLYF68(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64,_65,_66,_67,_68) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) f(_63) f(_64) f(_65) f(_66) f(_67) f(_68)
+#define VISIT_STRUCT_APPLYF69(f,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64,_65,_66,_67,_68,_69) f(_1) f(_2) f(_3) f(_4) f(_5) f(_6) f(_7) f(_8) f(_9) f(_10) f(_11) f(_12) f(_13) f(_14) f(_15) f(_16) f(_17) f(_18) f(_19) f(_20) f(_21) f(_22) f(_23) f(_24) f(_25) f(_26) f(_27) f(_28) f(_29) f(_30) f(_31) f(_32) f(_33) f(_34) f(_35) f(_36) f(_37) f(_38) f(_39) f(_40) f(_41) f(_42) f(_43) f(_44) f(_45) f(_46) f(_47) f(_48) f(_49) f(_50) f(_51) f(_52) f(_53) f(_54) f(_55) f(_56) f(_57) f(_58) f(_59) f(_60) f(_61) f(_62) f(_63) f(_64) f(_65) f(_66) f(_67) f(_68) f(_69)
+
+#define VISIT_STRUCT_APPLY_F_(M, ...) VISIT_STRUCT_EXPAND(M(__VA_ARGS__))
+#define MACRO_MAP(f, ...) VISIT_STRUCT_EXPAND(VISIT_STRUCT_APPLY_F_(VISIT_STRUCT_CONCAT(VISIT_STRUCT_APPLYF, VISIT_STRUCT_PP_NARG(__VA_ARGS__)), f, __VA_ARGS__))
diff --git a/graphics/asymptote/LspCpp/network/optional.hpp b/graphics/asymptote/LspCpp/network/optional.hpp
new file mode 100644
index 0000000000..43b1cf1fd8
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/optional.hpp
@@ -0,0 +1,711 @@
+// Copyright 2016 Glyn Matthews.
+// Copyright (C) 2011 - 2012 Andrzej Krzemienski.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/**
+ * \file
+ * \brief Contains an implementation of C++17 optional (n3793).
+ *
+ * \sa https://github.com/akrzemi1/Optional
+ * \sa http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3848.html
+ */
+
+#ifndef NETWORK_OPTIONAL_INC
+#define NETWORK_OPTIONAL_INC
+
+#include <stdexcept>
+#include <type_traits>
+#include <utility>
+#include <memory>
+#include <algorithm>
+
+#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
+#ifdef NDEBUG
+#define NETWORK_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR)
+#else
+#define NETWORK_ASSERTED_EXPRESSION(CHECK, EXPR) \
+ ((CHECK) ? (EXPR) : (fail(#CHECK, __FILE__, __LINE__), (EXPR)))
+inline void fail(const char*, const char*, unsigned) {}
+#endif // NDEBUG
+#endif // !defined(DOXYGEN_SHOULD_SKIP_THIS)
+
+namespace network {
+/**
+ * \ingroup optional
+ * \class nullopt_t optional.hpp network/uri.hpp
+ * \brief Disengaged state indicator.
+ * \sa optional
+ */
+struct nullopt_t {
+#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
+ struct init {};
+ constexpr nullopt_t(init) {}
+#endif // !defined(DOXYGEN_SHOULD_SKIP_THIS)
+};
+
+/**
+ * \ingroup optional
+ * \brief Used to indicate a *disengaged* state for optional objects.
+ */
+constexpr nullopt_t nullopt{nullopt_t::init{}};
+
+/**
+ * \ingroup optional
+ * \class bad_optional_access optional.hpp network/uri.hpp
+ * \brief Exception thrown when the value member function is called when the
+ * optional object is disengaged.
+ */
+class bad_optional_access : public std::logic_error {
+ public:
+
+ /**
+ * \brief Constructor.
+ * \param what_arg The error message.
+ */
+ explicit bad_optional_access(const std::string& what_arg)
+ : std::logic_error(what_arg) {}
+
+ /**
+ * \brief Constructor.
+ * \param what_arg The error message.
+ */
+ explicit bad_optional_access(const char* what_arg)
+ : std::logic_error(what_arg) {}
+};
+
+#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
+namespace details {
+struct dummy_t {};
+
+template <class T>
+union trivially_destructible_optional_storage {
+ static_assert(std::is_trivially_destructible<T>::value, "");
+
+ dummy_t dummy_;
+ T value_;
+
+ constexpr trivially_destructible_optional_storage() : dummy_{} {}
+
+ constexpr trivially_destructible_optional_storage(const T& v) : value_{v} {}
+
+ ~trivially_destructible_optional_storage() = default;
+};
+
+template <class T>
+union optional_storage {
+ dummy_t dummy_;
+ T value_;
+
+ constexpr optional_storage() : dummy_{} {}
+
+ constexpr optional_storage(const T& v) : value_{v} {}
+
+ ~optional_storage() {}
+};
+
+template <class T>
+class trivially_destructible_optional_base {
+public:
+ typedef T value_type;
+
+ constexpr trivially_destructible_optional_base() noexcept
+ : init_(false),
+ storage_{} {}
+
+ constexpr trivially_destructible_optional_base(const T& v)
+ : init_(true), storage_{v} {}
+
+ constexpr trivially_destructible_optional_base(T&& v)
+ : init_(true), storage_{std::move(v)} {}
+
+ ~trivially_destructible_optional_base() = default;
+
+protected:
+
+ bool init_;
+ optional_storage<T> storage_;
+};
+
+template <class T>
+class optional_base {
+public:
+ typedef T value_type;
+
+ constexpr optional_base() noexcept
+ : init_(false),
+ storage_{} {}
+
+ constexpr optional_base(const T& v)
+ : init_(true), storage_{v} {}
+
+ constexpr optional_base(T&& v)
+ : init_(true), storage_{std::move(v)} {}
+
+ ~optional_base() {
+ if (init_) {
+ storage_.value_.T::~T();
+ }
+ }
+
+protected:
+
+ bool init_;
+ optional_storage<T> storage_;
+};
+} // namespace details
+#endif // !defined(DOXYGEN_SHOULD_SKIP_THIS)
+
+/**
+ * \ingroup optional
+ * \class optional optional.hpp network/uri.hpp
+ * \brief An implementation of C++17 optional (n3793)
+ */
+#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
+template <class T>
+using optional_base = typename std::conditional<
+ std::is_trivially_destructible<T>::value,
+ details::trivially_destructible_optional_base<T>,
+ details::optional_base<T>>::type;
+#endif // !defined(DOXYGEN_SHOULD_SKIP_THIS)
+
+template <class T>
+#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
+class optional : optional_base<T> {
+#else
+class optional {
+#endif // !defined(DOXYGEN_SHOULD_SKIP_THIS)
+ typedef optional_base<T> base_type;
+
+ public:
+ /**
+ * \brief Optional value type.
+ */
+ typedef T value_type;
+
+ /**
+ * \brief Constructor.
+ * \post *disengaged*.
+ */
+ constexpr optional() : optional_base<T>() {}
+
+ /**
+ * \brief Constructor.
+ * \post *disengaged*.
+ */
+ constexpr optional(nullopt_t) noexcept : optional_base<T>() {}
+
+ /**
+ * \brief Copy constructor.
+ * \param other The other optional object.
+ */
+ optional(const optional& other) {
+ if (other) {
+ ::new(static_cast<void*>(ptr())) T(*other);
+ base_type::init_ = true;
+ }
+ }
+
+ /**
+ * \brief Move constructor.
+ * \param other The other optional object.
+ */
+ optional(optional&& other) noexcept {
+ if (other) {
+ ::new(static_cast<void*>(ptr())) T(std::move(other.storage_.value_));
+ base_type::init_ = true;
+ }
+ }
+
+ /**
+ * \brief Constructor.
+ * \param value The value with which to initialize the optional object.
+ * \post *engaged*
+ */
+ constexpr optional(const T& value) : optional_base<T>(value) {}
+
+ /**
+ * \brief Constructor.
+ * \param value The value with which to initialize the optional object.
+ * \post *engaged*
+ */
+ constexpr optional(T&& value) : optional_base<T>(std::move(value)) {}
+
+ /**
+ * \brief Assignment operator.
+ * \post *disengaged*.
+ * \returns \c *this.
+ */
+ optional& operator=(nullopt_t) noexcept {
+ if (base_type::init_) {
+ ptr()->T::~T();
+ }
+ base_type::init_ = false;
+ return *this;
+ }
+
+ /**
+ * \brief Copy assignment operator.
+ * \param other The other optional object.
+ * \returns \c *this.
+ */
+ optional& operator=(const optional& other) {
+ if (bool(*this) && !other) {
+ ptr()->T::~T();
+ base_type::init_ = false;
+ }
+ else if (!(*this) && bool(other)) {
+ ::new(static_cast<void*>(ptr())) T(*other);
+ base_type::init_ = true;
+ }
+ else if (bool(*this) && bool(other)) {
+ base_type::storage_.value_ = *other;
+ }
+ return *this;
+ }
+
+ /**
+ * \brief Move assignment operator.
+ * \param other The other optional object.
+ * \returns \c *this.
+ */
+ optional& operator=(optional&& other) noexcept {
+ if (bool(*this) && !other) {
+ ptr()->T::~T();
+ base_type::init_ = false;
+ }
+ else if (!(*this) && bool(other)) {
+ ::new(static_cast<void*>(ptr())) T(std::move(*other));
+ base_type::init_ = true;
+ }
+ else if (bool(*this) && bool(other)) {
+ base_type::storage_.value_ = std::move(*other);
+ }
+ return *this;
+ }
+
+ /**
+ * \brief Destructor.
+ */
+ ~optional() = default;
+
+ /**
+ * \brief Swap function.
+ * \param other The other optional object.
+ */
+ void swap(optional& other) noexcept {
+ if (bool(*this) && !other) {
+ ::new(static_cast<void*>(other.ptr())) T(std::move(**this));
+ ptr()->T::~T();
+ std::swap(base_type::init_, other.base_type::init_);
+ }
+ else if (!(*this) && bool(other)) {
+ ::new(static_cast<void*>(ptr())) T(std::move(*other));
+ other.ptr()->T::~T();
+ std::swap(base_type::init_, other.init_);
+ }
+ else if (bool(*this) && bool(other)) {
+ std::swap(**this, *other);
+ }
+ }
+
+ /**
+ * \brief Observer.
+ * \pre *engaged*
+ * \returns The underlying optional value.
+ */
+ constexpr T const* operator->() const {
+ return NETWORK_ASSERTED_EXPRESSION(bool(*this), ptr());
+ }
+
+ /**
+ * \brief Observer.
+ * \pre *engaged*
+ * \returns The underlying optional value.
+ */
+ T* operator->() {
+ return NETWORK_ASSERTED_EXPRESSION(bool(*this), ptr());
+ }
+
+ /**
+ * \brief Observer.
+ * \pre *engaged*
+ * \returns The underlying optional value.
+ */
+ constexpr T const& operator*() const {
+ return NETWORK_ASSERTED_EXPRESSION(bool(*this), base_type::storage_.value_);
+ }
+
+ /**
+ * \brief Observer.
+ * \pre *engaged*
+ * \returns The underlying optional value.
+ */
+ T& operator*() {
+ return NETWORK_ASSERTED_EXPRESSION(bool(*this), base_type::storage_.value_);
+ }
+
+ /**
+ * \brief Operator bool overloads.
+ * \returns \c true if the optional is *engaged*, \c false if it is *disengaged*.
+ */
+ constexpr explicit operator bool() const noexcept { return base_type::init_; }
+
+ /**
+ * \returns The underlying optional value, if \c bool(*this).
+ * \throws A bad_optional_access if \c !*this.
+ */
+ constexpr T const& value() const {
+ return *this ? base_type::storage_.value_
+ : (throw bad_optional_access("Uninitialized optional value"),
+ base_type::storage_.value_);
+ }
+ /**
+ * \returns The underlying optional value, if \c bool(*this).
+ * \throws A bad_optional_access if \c !*this.
+ */
+ T& value() {
+ return *this ? base_type::storage_.value_
+ : (throw bad_optional_access("Uninitialized optional value"),
+ base_type::storage_.value_);
+ }
+
+ /**
+ * \returns <tt>bool(*this) ? **this : static_cast<T>(std::forward<U>(v))</tt>.
+ * \pre \c <tt>std::is_copy_constructible<T>::value</tt> is \c true and <tt>std::is_convertible<U&&, T>::value</tt> is \c true.
+ */
+ template <class U>
+ T value_or(U&& other) const & {
+ static_assert(std::is_copy_constructible<value_type>::value, "Must be copy constructible.");
+ static_assert(std::is_convertible<U, value_type>::value, "U must be convertible to T.");
+ return bool(*this) ? **this : static_cast<T>(std::forward<U>(other));
+ }
+
+ /**
+ * \returns <tt>bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v))</tt>.
+ * \pre <tt>std::is_move_constructible<T>::value</tt> is \c true and <tt>std::is_convertible<U&&, T>::value</tt> is \c true.
+ */
+ template <class U>
+ T value_or(U&& other) && {
+ static_assert(std::is_copy_constructible<value_type>::value, "Must be copy constructible.");
+ static_assert(std::is_convertible<U, value_type>::value, "U must be convertible to T.");
+ return bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(other));
+ }
+
+ private:
+
+ T* ptr() {
+ return std::addressof(base_type::storage_.value_);
+ }
+
+};
+
+/**
+ * \brief Equality operator.
+ */
+template <class T>
+bool operator==(const optional<T>& lhs, const optional<T>& rhs) {
+ if (bool(lhs) != bool(rhs)) {
+ return false;
+ } else if (!bool(lhs)) {
+ return true;
+ } else {
+ return *lhs == *rhs;
+ }
+}
+
+/**
+ * \brief Inequality operator.
+ */
+template <class T>
+bool operator!=(const optional<T>& lhs, const optional<T>& rhs) {
+ return !(lhs == rhs);
+}
+
+/**
+ * \brief Comparison operator.
+ */
+template <class T>
+bool operator<(const optional<T>& lhs, const optional<T>& rhs) {
+ if (!rhs) {
+ return false;
+ } else if (!lhs) {
+ return true;
+ } else {
+ return *lhs < *rhs;
+ }
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>rhs < lhs</tt>.
+ */
+template <class T>
+bool operator>(const optional<T>& lhs, const optional<T>& rhs) {
+ return rhs < lhs;
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>!(rhs < lhs)</tt>.
+ */
+template <class T>
+bool operator<=(const optional<T>& lhs, const optional<T>& rhs) {
+ return !(rhs < lhs);
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>!(rhs > lhs)</tt>.
+ */
+template <class T>
+bool operator>=(const optional<T>& lhs, const optional<T>& rhs) {
+ return !(lhs < rhs);
+}
+
+/**
+ * \brief Equality operator.
+ * \returns \c !x.
+ */
+template <class T>
+bool operator==(const optional<T>& x, nullopt_t) noexcept {
+ return !x;
+}
+
+/**
+ * \brief Equality operator.
+ * \returns \c !x.
+ */
+template <class T>
+bool operator==(nullopt_t, const optional<T>& x) noexcept {
+ return !x;
+}
+
+/**
+ * \brief Inequality operator.
+ * \returns \c bool(x).
+ */
+template <class T>
+bool operator!=(const optional<T>& x, nullopt_t) noexcept {
+ return bool(x);
+}
+
+/**
+ * \brief Inequality operator.
+ * \returns \c bool(x).
+ */
+template <class T>
+bool operator!=(nullopt_t, const optional<T>& x) noexcept {
+ return bool(x);
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns \c false.
+ */
+template <class T>
+bool operator<(const optional<T>& x, nullopt_t) noexcept {
+ return false;
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns \c bool(x).
+ */
+template <class T>
+bool operator<(nullopt_t, const optional<T>& x) noexcept {
+ return bool(x);
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns \c !x.
+ */
+template <class T>
+bool operator<=(const optional<T>& x, nullopt_t) noexcept {
+ return !x;
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns \c true.
+ */
+template <class T>
+bool operator<=(nullopt_t, const optional<T>& x) noexcept {
+ return true;
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns \c bool(x).
+ */
+template <class T>
+bool operator>(const optional<T>& x, nullopt_t) noexcept {
+ return bool(x);
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns \c false.
+ */
+template <class T>
+bool operator>(nullopt_t, const optional<T>& x) noexcept {
+ return false;
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns \c true.
+ */
+template <class T>
+bool operator>=(const optional<T>& x, nullopt_t) noexcept {
+ return true;
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns \c !x.
+ */
+template <class T>
+bool operator>=(nullopt_t, const optional<T>& x) noexcept {
+ return !x;
+}
+
+/**
+ * \brief Equality operator.
+ * \returns <tt>bool(x) ? *x == v : false</tt>.
+ */
+template <class T>
+bool operator==(const optional<T>& x, const T& v) {
+ return bool(x) ? *x == v : false;
+}
+
+/**
+ * \brief Equality operator.
+ * \returns <tt>bool(x) ? v == *x : false</tt>.
+ */
+template <class T>
+bool operator==(const T& v, const optional<T>& x) {
+ return bool(x) ? v == *x : false;
+}
+
+/**
+ * \brief Inequality operator.
+ * \returns <tt>bool(x) ? !(*x == v) : true</tt>.
+ */
+template <class T>
+bool operator!=(const optional<T>& x, const T& v) {
+ return bool(x) ? !(*x == v) : true;
+}
+
+/**
+ * \brief Inequality operator.
+ * \returns <tt>bool(x) ? !(v == *x) : true</tt>.
+ */
+template <class T>
+bool operator!=(const T& v, const optional<T>& x) {
+ return bool(x) ? !(v == *x) : true;
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>bool(x) ? *x < v : true</tt>.
+ */
+template <class T>
+bool operator<(const optional<T>& x, const T& v) {
+ return bool(x) ? *x < v : true;
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>bool(x) ? v < *x : false</tt>.
+ */
+template <class T>
+bool operator<(const T& v, const optional<T>& x) {
+ return bool(x) ? v < *x : false;
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>bool(x) ? *x < v : true</tt>.
+ */
+template <class T>
+bool operator>(const optional<T>& x, const T& v) {
+ return bool(x) ? *x < v : true;
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>bool(x) ? v < *x : false</tt>.
+ */
+template <class T>
+bool operator>(const T& v, const optional<T>& x) {
+ return bool(x) ? v < *x : false;
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>!(x < v)</tt>.
+ */
+template <class T>
+bool operator>=(const optional<T>& x, const T& v) {
+ return !(x < v);
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>!(v < x)</tt>.
+ */
+template <class T>
+bool operator>=(const T& v, const optional<T>& x) {
+ return !(v < x);
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>!(x > v)</tt>.
+ */
+template <class T>
+bool operator<=(const optional<T>& x, const T& v) {
+ return !(x > v);
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>!(v > x)</tt>.
+ */
+template <class T>
+bool operator<=(const T& v, const optional<T>& x) {
+ return !(v > x);
+}
+
+/**
+ * \ingroup optional
+ * \brief Swap function.
+ * \param lhs The first optional object.
+ * \param rhs The second optional object.
+ *
+ * Calls:
+ * \code{.cpp}
+ * lhs.swap(rhs);
+ * \endcode
+ */
+template <class T>
+inline void swap(optional<T>& lhs,
+ optional<T>& rhs) noexcept(noexcept(lhs.swap(rhs))) {
+ return lhs.swap(rhs);
+}
+
+/**
+ * \ingroup optional
+ * \brief A helper function to contruct an optional object.
+ * \returns <tt>optional<typename std::decay<T>::type>(std::forward(value))</tt>.
+ */
+template <class T>
+inline constexpr optional<typename std::decay<T>::type> make_optional(T&& value) {
+ return optional<typename std::decay<T>::type>(std::forward(value));
+}
+} // namespace network
+
+#endif // NETWORK_OPTIONAL_INC
diff --git a/graphics/asymptote/LspCpp/network/string_view.hpp b/graphics/asymptote/LspCpp/network/string_view.hpp
new file mode 100644
index 0000000000..df54e7aa35
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/string_view.hpp
@@ -0,0 +1,273 @@
+// Copyright 2016 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_STRING_VIEW_INC
+#define NETWORK_STRING_VIEW_INC
+
+/**
+ * \file
+ * \brief Contains an implementation of C++17 string_view (n3921).
+ */
+
+#include <string>
+#include <iterator>
+#include <cassert>
+#include <stdexcept>
+#include <algorithm>
+
+namespace network {
+/**
+ * \class basic_string_view string_view.hpp network/uri/string_view.hpp
+ * \brief An implementation of C++17 string_view (n3921)
+ */
+template <class charT, class traits = std::char_traits<charT>>
+class basic_string_view {
+ public:
+ typedef traits traits_type;
+ typedef charT value_type;
+ typedef charT* pointer;
+ typedef const charT* const_pointer;
+ typedef charT& reference;
+ typedef const charT& const_reference;
+ typedef const charT* const_iterator;
+ typedef const_iterator iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef const_reverse_iterator reverse_iterator;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ static constexpr size_type npos = size_type(-1);
+
+ /**
+ * \brief Constructor.
+ */
+ constexpr basic_string_view() noexcept : data_(nullptr), size_(0) {}
+
+ /**
+ * \brief Copy constructor.
+ */
+ constexpr basic_string_view(const basic_string_view&) noexcept = default;
+
+ /**
+ * \brief Assignment operator.
+ */
+ basic_string_view& operator=(const basic_string_view&) noexcept = default;
+
+ /**
+ * \brief Constructor.
+ */
+ template <class Allocator>
+ basic_string_view(
+ const std::basic_string<charT, traits, Allocator>& str) noexcept
+ : data_(str.data()),
+ size_(str.size()) {}
+
+ /**
+ * \brief Constructor.
+ */
+ constexpr basic_string_view(const charT* str)
+ : data_(str), size_(traits::length(str)) {}
+
+ /**
+ * \brief Constructor.
+ */
+ constexpr basic_string_view(const charT* str, size_type len)
+ : data_(str), size_(len) {}
+
+ constexpr const_iterator begin() const noexcept { return data_; }
+
+ constexpr const_iterator end() const noexcept { return data_ + size_; }
+
+ constexpr const_iterator cbegin() const noexcept { return begin(); }
+
+ constexpr const_iterator cend() const noexcept { return end(); }
+
+ 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 rbegin(); }
+
+ const_reverse_iterator crend() const noexcept { return rend(); }
+
+ constexpr size_type size() const noexcept { return size_; }
+
+ constexpr size_type length() const noexcept { return size_; }
+
+ constexpr size_type max_size() const noexcept { return size_; }
+
+ constexpr bool empty() const noexcept { return size_ == 0; }
+
+ constexpr const_reference operator[](size_type pos) const {
+ return data_[pos];
+ }
+
+ const_reference at(size_type pos) const {
+ if (pos >= size_) {
+ throw std::out_of_range("Index out of range.");
+ }
+ return data_[pos];
+ }
+
+ const_reference front() const { return *begin(); }
+
+ const_reference back() const {
+ auto last = (end()) - 1;
+ return *last;
+ }
+
+ constexpr const_pointer data() const noexcept { return data_; }
+
+ void clear() noexcept {
+ data_ = nullptr;
+ size_ = 0;
+ }
+
+ void remove_prefix(size_type n) {
+ data_ += n;
+ size_ -= n;
+ }
+
+ void remove_suffix(size_type n) { size_ -= n; }
+
+ void swap(basic_string_view& s) noexcept {
+ std::swap(data_, s.data_);
+ std::swap(size_, s.size_);
+ }
+
+ template <class Allocator>
+ explicit operator std::basic_string<charT, traits, Allocator>() const {
+ return to_string<charT, traits, Allocator>();
+ }
+
+ template <class Allocator = std::allocator<charT>>
+ std::basic_string<charT, traits, Allocator> to_string(
+ const Allocator& a = Allocator()) const {
+ return std::basic_string<charT, traits, Allocator>(begin(), end(), a);
+ }
+
+ size_type copy(charT* s, size_type n, size_type pos = 0) const {
+ size_type rlen = std::min(n, size() - pos);
+ std::copy_n(begin() + pos, rlen, s);
+ return rlen;
+ }
+
+ constexpr basic_string_view substr(size_type pos = 0,
+ size_type n = npos) const {
+ return basic_string_view(data() + pos, std::min(n, size() - pos));
+ }
+
+ constexpr int compare(basic_string_view s) const noexcept {
+ return size() == s.size()
+ ? traits::compare(data(), s.data(), size())
+ : (size() < s.size()
+ ? (traits::compare(data(), s.data(), size()) > 0 ? 1 : -1)
+ : (traits::compare(data(), s.data(), size()) < 0 ? -1
+ : 1));
+ }
+
+ constexpr int compare(size_type pos1, size_type n1,
+ basic_string_view s) const {
+ return substr(pos1, n1).compare(s);
+ }
+
+ constexpr int compare(size_type pos1, size_type n1, basic_string_view s,
+ size_type pos2, size_type n2) const {
+ return substr(pos1, n1).compare(s.substr(pos2, n2));
+ }
+
+ constexpr int compare(const charT* s) const {
+ return compare(basic_string_view(s));
+ }
+
+ constexpr int compare(size_type pos1, size_type n1, const charT* s) const {
+ return substr(pos1, n1).compare(basic_string_view(s));
+ }
+
+ constexpr int compare(size_type pos1, size_type n1, const charT* s,
+ size_type n2) const {
+ return substr(pos1, n1).compare(basic_string_view(s, n2));
+ }
+
+ private:
+ const_pointer data_;
+ size_type size_;
+};
+
+/**
+ * \brief Equality operator.
+ * \returns <tt>lhs.compare(rhs) == 0</tt>.
+ */
+template <class charT, class traits>
+constexpr bool operator==(basic_string_view<charT, traits> lhs,
+ basic_string_view<charT, traits> rhs) noexcept {
+ return lhs.compare(rhs) == 0;
+}
+
+/**
+ * \brief Inequality operator.
+ * \returns <tt>!(lhs == rhs)</tt>.
+ */
+template <class charT, class traits>
+constexpr bool operator!=(basic_string_view<charT, traits> lhs,
+ basic_string_view<charT, traits> rhs) noexcept {
+ return !(lhs == rhs);
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>lhs.compare(rhs) < 0</tt>.
+ */
+template <class charT, class traits>
+constexpr bool operator<(basic_string_view<charT, traits> lhs,
+ basic_string_view<charT, traits> rhs) noexcept {
+ return lhs.compare(rhs) < 0;
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>rhs < lhs</tt>.
+ */
+template <class charT, class traits>
+constexpr bool operator>(basic_string_view<charT, traits> lhs,
+ basic_string_view<charT, traits> rhs) noexcept {
+ return rhs < lhs;
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>!(lhs > rhs)</tt>.
+ */
+template <class charT, class traits>
+constexpr bool operator<=(basic_string_view<charT, traits> lhs,
+ basic_string_view<charT, traits> rhs) noexcept {
+ return !(lhs > rhs);
+}
+
+/**
+ * \brief Comparison operator.
+ * \returns <tt>!(lhs < rhs)</tt>.
+ */
+template <class charT, class traits>
+constexpr bool operator>=(basic_string_view<charT, traits> lhs,
+ basic_string_view<charT, traits> rhs) noexcept {
+ return !(lhs < rhs);
+}
+
+/**
+ * \brief Output stream operator.
+ */
+template <class charT, class traits>
+std::basic_ostream<charT, traits>& operator<<(
+ std::basic_ostream<charT, traits>& os,
+ basic_string_view<charT, traits> str) {
+ return os << str.to_string();
+}
+
+typedef basic_string_view<char> string_view;
+} // namespace network
+
+#endif // NETWORK_STRING_VIEW_INC
diff --git a/graphics/asymptote/LspCpp/network/uri.hpp b/graphics/asymptote/LspCpp/network/uri.hpp
new file mode 100644
index 0000000000..f3d86e09ec
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri.hpp
@@ -0,0 +1,38 @@
+// Copyright (c) Glyn Matthews 2012-2016.
+// Copyright 2012 Dean Michael Berris <dberris@google.com>
+// Copyright 2012 Google, Inc.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_URI_HPP
+#define NETWORK_URI_HPP
+
+/**
+ * \defgroup uri URI
+ *
+ * This module contains a class encapsulating a URI, a URI builder and
+ * percent encoding and decoding functions.
+ *
+ * \defgroup optional Optional
+ *
+ * This module contains a utility to represent optional values.
+ *
+ * \defgroup string String
+ *
+ * This module contains a class for a non-owning reference to a string.
+ *
+ * \namespace network
+ *
+ * The \c network namespace contains all the classes and functions for
+ * the URI in this library.
+ *
+ * \file
+ * \brief Contains the uri, uri_builder classes and functions
+ * for percent encoding and decoding.
+ */
+
+#include <network/uri/uri.hpp>
+#include <network/uri/uri_io.hpp>
+
+#endif // NETWORK_URI_HPP
diff --git a/graphics/asymptote/LspCpp/network/uri/config.hpp b/graphics/asymptote/LspCpp/network/uri/config.hpp
new file mode 100644
index 0000000000..39c3b58c28
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/config.hpp
@@ -0,0 +1,20 @@
+// Copyright (c) Glyn Matthews 2012-2016.
+// Copyright 2012 Dean Michael Berris <dberris@google.com>
+// Copyright 2012 Google, Inc.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/**
+ * \file
+ * \brief Contains macros to configure compiler or platform-specific workarounds.
+ */
+
+#ifndef NETWORK_URI_CONFIG_INC
+#define NETWORK_URI_CONFIG_INC
+
+#ifdef _MSC_VER
+#define NETWORK_URI_MSVC _MSC_VER
+#endif // _MSC_VER
+
+#endif // NETWORK_URI_CONFIG_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/algorithm.hpp b/graphics/asymptote/LspCpp/network/uri/detail/algorithm.hpp
new file mode 100644
index 0000000000..2358af9a04
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/algorithm.hpp
@@ -0,0 +1,73 @@
+// Copyright 2016 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_DETAIL_RANGE_INC
+#define NETWORK_DETAIL_RANGE_INC
+
+#include <algorithm>
+#include <iterator>
+#include <utility>
+#include <string>
+#include <cctype>
+#include <locale>
+
+namespace network {
+namespace detail {
+template <class Rng, class Pred>
+inline void for_each(Rng& rng, Pred&& pred) {
+ std::for_each(std::begin(rng), std::end(rng), pred);
+}
+
+template <class Rng, class Iter, class Pred>
+inline void transform(Rng& rng, Iter out, Pred&& pred) {
+ std::transform(std::begin(rng), std::end(rng), out, pred);
+}
+
+template <class Rng>
+inline typename Rng::difference_type distance(Rng& rng) {
+ return std::distance(std::begin(rng), std::end(rng));
+}
+
+template <class Rng1, class Rng2>
+inline bool equal(const Rng1& rng1, const Rng2& rng2) {
+ return std::equal(std::begin(rng1), std::end(rng1), std::begin(rng2));
+}
+
+template <class Rng, class Pred>
+inline void remove_erase_if(Rng& rng, Pred&& pred) {
+ auto first = std::begin(rng), last = std::end(rng);
+ auto it = std::remove_if(first, last, pred);
+ rng.erase(it, last);
+}
+
+inline std::string trim_front(const std::string& str) {
+ auto first = std::begin(str), last = std::end(str);
+ auto it = std::find_if(first, last, [](char ch) {
+ return !std::isspace(ch, std::locale());
+ });
+ return std::string(it, last);
+}
+
+inline std::string trim_back(const std::string& str) {
+ using reverse_iterator = std::reverse_iterator<std::string::const_iterator>;
+
+ auto first = reverse_iterator(std::end(str)),
+ last = reverse_iterator(std::begin(str));
+ auto it = std::find_if(first, last, [](char ch) {
+ return !std::isspace(ch, std::locale());
+ });
+ std::string result(it, last);
+ std::reverse(std::begin(result), std::end(result));
+ return result;
+}
+
+inline
+std::string trim_copy(const std::string &str) {
+ return trim_back(trim_front(str));
+}
+} // namespace detail
+} // namespace network
+
+#endif // NETWORK_DETAIL_RANGE_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/decode.hpp b/graphics/asymptote/LspCpp/network/uri/detail/decode.hpp
new file mode 100644
index 0000000000..9d0aaaa1b5
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/decode.hpp
@@ -0,0 +1,78 @@
+// Copyright (c) Glyn Matthews 2011-2016.
+// Copyright 2012 Dean Michael Berris <dberris@google.com>
+// Copyright 2012 Google, Inc.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_URI_DECODE_INC
+#define NETWORK_URI_DECODE_INC
+
+#include <network/uri/uri_errors.hpp>
+#include <iterator>
+#include <cassert>
+
+namespace network {
+namespace detail {
+template <typename CharT>
+CharT letter_to_hex(CharT in) {
+ if ((in >= '0') && (in <= '9')) {
+ return in - '0';
+ }
+
+ if ((in >= 'a') && (in <= 'f')) {
+ return in + 10 - 'a';
+ }
+
+ if ((in >= 'A') && (in <= 'F')) {
+ return in + 10 - 'A';
+ }
+
+ throw percent_decoding_error(uri_error::non_hex_input);
+}
+
+template <class InputIterator, class charT>
+InputIterator decode_char(InputIterator it, charT *out) {
+ assert(*it == '%');
+ ++it;
+ auto h0 = *it;
+ auto v0 = detail::letter_to_hex(h0);
+ ++it;
+ auto h1 = *it;
+ auto v1 = detail::letter_to_hex(h1);
+ ++it;
+ *out = static_cast<charT>((0x10 * v0) + v1);
+ return it;
+}
+
+template <class InputIterator, class OutputIterator>
+OutputIterator decode(InputIterator in_begin, InputIterator in_end,
+ OutputIterator out_begin) {
+ auto it = in_begin;
+ auto out = out_begin;
+ while (it != in_end) {
+ if (*it == '%') {
+ if (std::distance(it, in_end) < 3) {
+ throw percent_decoding_error(uri_error::not_enough_input);
+ }
+ char c = '\0';
+ it = decode_char(it, &c);
+ *out = c;
+ ++out;
+ } else {
+ *out++ = *it++;
+ }
+ }
+ return out;
+}
+
+template <class String>
+String decode(const String &source) {
+ String unencoded;
+ decode(std::begin(source), std::end(source), std::back_inserter(unencoded));
+ return unencoded;
+}
+} // namespace detail
+} // namespace network
+
+#endif // NETWORK_URI_DECODE_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/encode.hpp b/graphics/asymptote/LspCpp/network/uri/detail/encode.hpp
new file mode 100644
index 0000000000..be1dec9fd1
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/encode.hpp
@@ -0,0 +1,169 @@
+// Copyright (c) Glyn Matthews 2011-2016.
+// Copyright 2012 Dean Michael Berris <dberris@google.com>
+// Copyright 2012 Google, Inc.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_URI_ENCODE_INC
+#define NETWORK_URI_ENCODE_INC
+
+#include <network/uri/uri_errors.hpp>
+#include <iterator>
+#include <cstring>
+#include <cassert>
+#include <algorithm>
+
+namespace network {
+namespace detail {
+template <typename CharT>
+inline CharT hex_to_letter(CharT in) {
+ if ((in >= 0) && (in < 10)) {
+ return in + '0';
+ }
+
+ if ((in >= 10) && (in < 16)) {
+ return in - 10 + 'A';
+ }
+
+ return in;
+}
+
+template <class charT, class OutputIterator>
+void percent_encode(charT in, OutputIterator &out) {
+ out++ = '%';
+ out++ = hex_to_letter((in >> 4) & 0x0f);
+ out++ = hex_to_letter(in & 0x0f);
+}
+
+template <class charT>
+bool is_unreserved(charT in) {
+ return ((in >= 'a') && (in <= 'z')) ||
+ ((in >= 'A') && (in <= 'Z')) ||
+ ((in >= '0') && (in <= '9')) ||
+ (in == '-') ||
+ (in == '.') ||
+ (in == '_') ||
+ (in == '~');
+}
+
+template <class charT, class OutputIterator>
+void encode_char(charT in, OutputIterator &out, const char *ignore = "") {
+ if (is_unreserved(in)) {
+ out++ = in;
+ } else {
+ auto first = ignore, last = ignore + std::strlen(ignore);
+ if (std::find(first, last, in) != last) {
+ out++ = in;
+ } else {
+ percent_encode(in, out);
+ }
+ }
+}
+
+template <typename InputIterator, typename OutputIterator>
+OutputIterator encode_user_info(InputIterator first, InputIterator last,
+ OutputIterator out) {
+ auto it = first;
+ while (it != last) {
+ detail::encode_char(*it, out, ":");
+ ++it;
+ }
+ return out;
+}
+
+template <typename InputIterator, typename OutputIterator>
+OutputIterator encode_host(InputIterator first, InputIterator last,
+ OutputIterator out) {
+ auto it = first;
+ while (it != last) {
+ detail::encode_char(*it, out, "[:]");
+ ++it;
+ }
+ return out;
+}
+
+template <typename InputIterator, typename OutputIterator>
+OutputIterator encode_port(InputIterator first, InputIterator last,
+ OutputIterator out) {
+ auto it = first;
+ while (it != last) {
+ detail::encode_char(*it, out);
+ ++it;
+ }
+ return out;
+}
+
+template <typename InputIterator, typename OutputIterator>
+OutputIterator encode_path(InputIterator first, InputIterator last,
+ OutputIterator out) {
+ auto it = first;
+ while (it != last) {
+ detail::encode_char(*it, out, "/.@%;=");
+ ++it;
+ }
+ return out;
+}
+
+template <typename InputIterator, typename OutputIterator>
+OutputIterator encode_query_component(InputIterator first, InputIterator last,
+ OutputIterator out) {
+ auto it = first;
+ while (it != last) {
+ detail::encode_char(*it, out, "/?");
+ ++it;
+ }
+ return out;
+}
+
+template <typename InputIterator, typename OutputIterator>
+OutputIterator encode_fragment(InputIterator first, InputIterator last,
+ OutputIterator out) {
+ auto it = first;
+ while (it != last) {
+ detail::encode_char(*it, out, "/.@&l;=%");
+ ++it;
+ }
+ return out;
+}
+
+template <class String>
+String encode_user_info(const String &user_info) {
+ String encoded;
+ encode_user_info(std::begin(user_info), std::end(user_info),
+ std::back_inserter(encoded));
+ return encoded;
+}
+
+template <class String>
+String encode_host(const String &host) {
+ String encoded;
+ encode_host(std::begin(host), std::end(host), std::back_inserter(encoded));
+ return encoded;
+}
+
+template <class String>
+String encode_port(const String &port) {
+ String encoded;
+ encode_port(std::begin(port), std::end(port), std::back_inserter(encoded));
+ return encoded;
+}
+
+template <class String>
+String encode_path(const String &path) {
+ String encoded;
+ encode_path(std::begin(path), std::end(path), std::back_inserter(encoded));
+ return encoded;
+}
+
+template <class String>
+String encode_fragment(const String &fragment) {
+ String encoded;
+ encode_fragment(std::begin(fragment), std::end(fragment),
+ std::back_inserter(encoded));
+ return encoded;
+}
+} // namespace detail
+} // namespace network
+
+#endif // NETWORK_URI_ENCODE_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/grammar.hpp b/graphics/asymptote/LspCpp/network/uri/detail/grammar.hpp
new file mode 100644
index 0000000000..7e4a9fe3b8
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/grammar.hpp
@@ -0,0 +1,130 @@
+// Copyright 2016 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_DETAIL_URI_GRAMMAR_INC
+#define NETWORK_DETAIL_URI_GRAMMAR_INC
+
+#include <network/string_view.hpp>
+#include <cstdlib>
+#include <locale>
+#include <cstring>
+#include <string>
+
+namespace network {
+namespace detail {
+inline bool isalnum(string_view::const_iterator &it,
+ string_view::const_iterator last) {
+ if (it != last) {
+ if (std::isalnum(*it, std::locale::classic())) {
+ ++it;
+ return true;
+ }
+ }
+ return false;
+}
+
+inline bool isdigit(string_view::const_iterator &it,
+ string_view::const_iterator last) {
+ if (it != last) {
+ if (std::isdigit(*it, std::locale::classic())) {
+ ++it;
+ return true;
+ }
+ }
+ return false;
+}
+
+inline bool is_in(string_view::const_iterator &it,
+ string_view::const_iterator last, const char *chars) {
+ if (it != last) {
+ auto length = std::strlen(chars);
+ for (std::size_t i = 0; i < length; ++i) {
+ if (*it == chars[i]) {
+ ++it;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+inline bool is_sub_delim(string_view::const_iterator &it,
+ string_view::const_iterator last) {
+ return is_in(it, last, "!$&'()*+,;=");
+}
+
+inline bool is_ucschar(string_view::const_iterator &it,
+ string_view::const_iterator last) {
+ if (it == last) {
+ return false;
+ }
+
+
+
+ return false;
+}
+
+inline bool is_private(string_view::const_iterator &it,
+ string_view::const_iterator last) {
+ return false;
+}
+
+inline bool is_unreserved(string_view::const_iterator &it,
+ string_view::const_iterator last) {
+ return isalnum(it, last) || is_in(it, last, "-._~");
+}
+
+inline bool is_pct_encoded(string_view::const_iterator &it,
+ string_view::const_iterator last) {
+ if (it == last) {
+ return false;
+ }
+
+ string_view::const_iterator it_copy = it;
+
+ if (*it_copy == '%') {
+ ++it_copy;
+ if (it_copy == last) {
+ return false;
+ }
+ }
+
+ if (std::isxdigit(*it_copy, std::locale::classic())) {
+ ++it_copy;
+ if (it_copy == last) {
+ return false;
+ }
+ }
+
+ if (std::isxdigit(*it_copy, std::locale::classic())) {
+ ++it_copy;
+ it = it_copy;
+ return true;
+ }
+
+ return false;
+}
+
+inline bool is_pchar(string_view::const_iterator &it,
+ string_view::const_iterator last) {
+ return
+ is_unreserved(it, last) ||
+ is_pct_encoded(it, last) ||
+ is_sub_delim(it, last) ||
+ is_in(it, last, ":@") ||
+ is_ucschar(it, last)
+ ;
+}
+
+inline bool is_valid_port(string_view::const_iterator it) {
+ const char* port_first = &(*it);
+ char* port_last = 0;
+ unsigned long value = std::strtoul(port_first, &port_last, 10);
+ return (value < std::numeric_limits<unsigned short>::max());
+}
+} // namespace detail
+} // namespace network
+
+#endif // NETWORK_DETAIL_URI_GRAMMAR_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/translate.hpp b/graphics/asymptote/LspCpp/network/uri/detail/translate.hpp
new file mode 100644
index 0000000000..7566c258e1
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/translate.hpp
@@ -0,0 +1,89 @@
+// Copyright (c) Glyn Matthews 2012-2016.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_URI_DETAIL_TRANSLATE_INC
+#define NETWORK_URI_DETAIL_TRANSLATE_INC
+
+#include <string>
+
+namespace network {
+namespace detail {
+template <typename Source>
+struct translate_impl;
+
+template <>
+struct translate_impl<std::string> {
+ std::string operator()(const std::string &source) const { return source; }
+};
+
+template <int N>
+struct translate_impl<char[N]> {
+ std::string operator()(const char *source) const { return source; }
+};
+
+template <>
+struct translate_impl<char *> {
+ std::string operator()(const char *source) const { return source; }
+};
+
+template <>
+struct translate_impl<const char *> {
+ std::string operator()(const char *source) const { return source; }
+};
+
+template <int N>
+struct translate_impl<const char[N]> {
+ std::string operator()(const char *source) const { return source; }
+};
+
+template <>
+struct translate_impl<std::wstring> {
+ std::string operator()(const std::wstring &source) const {
+ return std::string(std::begin(source), std::end(source));
+ }
+};
+
+template <int N>
+struct translate_impl<const wchar_t[N]> {
+ std::string operator()(const wchar_t *source) const {
+ translate_impl<std::wstring> impl;
+ return impl(source);
+ }
+};
+
+template <int N>
+struct translate_impl<wchar_t[N]> {
+ std::string operator()(const wchar_t *source) const {
+ translate_impl<std::wstring> impl;
+ return impl(source);
+ }
+};
+
+template <>
+struct translate_impl<wchar_t *> {
+ std::string operator()(const wchar_t *source) const {
+ translate_impl<std::wstring> impl;
+ return impl(source);
+ }
+};
+
+template <>
+struct translate_impl<const wchar_t *> {
+ std::string operator()(const wchar_t *source) const {
+ translate_impl<std::wstring> impl;
+ return impl(source);
+ }
+};
+
+template <typename Source>
+inline std::string translate(const Source &source) {
+ translate_impl<Source> impl;
+ return impl(source);
+}
+
+} // namespace detail
+} // namespace network
+
+#endif // NETWORK_URI_DETAIL_TRANSLATE_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/uri_advance_parts.cpp b/graphics/asymptote/LspCpp/network/uri/detail/uri_advance_parts.cpp
new file mode 100644
index 0000000000..6eec782c82
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/uri_advance_parts.cpp
@@ -0,0 +1,76 @@
+// Copyright 2016-2017 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "uri_advance_parts.hpp"
+#include <iterator>
+#include <utility>
+#include <limits>
+
+namespace network {
+namespace detail {
+namespace {
+template <class Iterator>
+uri_part copy_part(Iterator first, Iterator last,
+ string_view::const_iterator &it) {
+ auto part_first = it;
+ std::advance(it, std::distance(first, last));
+ return detail::uri_part(part_first, it);
+}
+} // namespace
+
+uri_part copy_part(const std::string &uri, string_view::const_iterator &it) {
+ return copy_part(std::begin(uri), std::end(uri), it);
+}
+
+void advance_parts(string_view uri_view, uri_parts &parts,
+ const uri_parts &existing_parts) {
+ auto first = std::begin(uri_view);
+
+ auto it = first;
+ if (auto scheme = existing_parts.scheme) {
+ parts.scheme = copy_part(std::begin(*scheme), std::end(*scheme), it);
+
+ // ignore : for all URIs
+ if (*it == ':') {
+ ++it;
+ }
+
+ // ignore // for hierarchical URIs
+ if (existing_parts.hier_part.host) {
+ std::advance(it, 2);
+ }
+ }
+
+ if (auto user_info = existing_parts.hier_part.user_info) {
+ parts.hier_part.user_info =
+ copy_part(std::begin(*user_info), std::end(*user_info), it);
+ ++it; // ignore @
+ }
+
+ if (auto host = existing_parts.hier_part.host) {
+ parts.hier_part.host = copy_part(std::begin(*host), std::end(*host), it);
+ }
+
+ if (auto port = existing_parts.hier_part.port) {
+ ++it; // ignore :
+ parts.hier_part.port = copy_part(std::begin(*port), std::end(*port), it);
+ }
+
+ if (auto path = existing_parts.hier_part.path) {
+ parts.hier_part.path = copy_part(std::begin(*path), std::end(*path), it);
+ }
+
+ if (auto query = existing_parts.query) {
+ ++it; // ignore ?
+ parts.query = copy_part(std::begin(*query), std::end(*query), it);
+ }
+
+ if (auto fragment = existing_parts.fragment) {
+ ++it; // ignore #
+ parts.fragment = copy_part(std::begin(*fragment), std::end(*fragment), it);
+ }
+}
+} // namespace detail
+} // namespace network
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/uri_advance_parts.hpp b/graphics/asymptote/LspCpp/network/uri/detail/uri_advance_parts.hpp
new file mode 100644
index 0000000000..4d9fd76768
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/uri_advance_parts.hpp
@@ -0,0 +1,21 @@
+// Copyright 2013-2016 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_DETAIL_URI_ADVANCE_INC
+#define NETWORK_DETAIL_URI_ADVANCE_INC
+
+#include <network/uri/detail/uri_parts.hpp>
+
+namespace network {
+namespace detail {
+uri_part copy_part(const std::string &part,
+ string_view::const_iterator &it);
+
+void advance_parts(string_view uri_view, uri_parts &parts,
+ const uri_parts &existing_parts);
+} // namespace detail
+} // namespace network
+
+#endif // NETWORK_DETAIL_URI_ADVANCE_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/uri_normalize.cpp b/graphics/asymptote/LspCpp/network/uri/detail/uri_normalize.cpp
new file mode 100644
index 0000000000..1c6ca1484b
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/uri_normalize.cpp
@@ -0,0 +1,87 @@
+// Copyright 2013-2016 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iterator>
+#include <vector>
+#include <algorithm>
+
+#ifdef NETWORK_URI_EXTERNAL_BOOST
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/join.hpp>
+namespace boost = boost;
+#else // NETWORK_URI_EXTERNAL_BOOST
+#include "boost/algorithm/string/split.hpp"
+#include "boost/algorithm/string/join.hpp"
+#endif // NETWORK_URI_EXTERNAL_BOOST
+
+#include "uri_normalize.hpp"
+#include "uri_percent_encode.hpp"
+#include "algorithm.hpp"
+
+namespace network {
+namespace detail {
+std::string normalize_path_segments(string_view path) {
+ std::string result;
+
+ if (!path.empty()) {
+ std::vector<std::string> path_segments;
+ boost::split(path_segments, path, [](char ch) {
+ return ch == '/';
+ });
+
+ bool last_segment_is_slash = path_segments.back().empty();
+ std::vector<std::string> normalized_segments;
+ for (const auto &segment : path_segments) {
+ if (segment.empty() || (segment == ".")) {
+ continue;
+ }
+ else if (segment == "..") {
+ if (normalized_segments.empty()) {
+ throw uri_builder_error();
+ }
+ normalized_segments.pop_back();
+ }
+ else {
+ normalized_segments.push_back(segment);
+ }
+ }
+
+ for (const auto &segment : normalized_segments) {
+ result += "/" + segment;
+ }
+
+ if (last_segment_is_slash) {
+ result += "/";
+ }
+ }
+
+ if (result.empty()) {
+ result = "/";
+ }
+
+ return result;
+}
+
+std::string normalize_path(string_view path, uri_comparison_level level) {
+ auto result = path.to_string();
+
+ if (uri_comparison_level::syntax_based == level) {
+ // case normalization
+ detail::for_each(result, percent_encoded_to_upper<std::string>());
+
+ // % encoding normalization
+ result.erase(
+ detail::decode_encoded_unreserved_chars(std::begin(result),
+ std::end(result)),
+ std::end(result));
+
+ // % path segment normalization
+ result = normalize_path_segments(result);
+ }
+
+ return result;
+}
+} // namespace detail
+} // namespace network
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/uri_normalize.hpp b/graphics/asymptote/LspCpp/network/uri/detail/uri_normalize.hpp
new file mode 100644
index 0000000000..3c2e03b11d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/uri_normalize.hpp
@@ -0,0 +1,20 @@
+// Copyright 2013-2016 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_DETAIL_NORMALIZE_INC
+#define NETWORK_DETAIL_NORMALIZE_INC
+
+#include <network/uri/uri.hpp>
+#include <network/string_view.hpp>
+
+namespace network {
+namespace detail {
+std::string normalize_path_segments(string_view path);
+
+std::string normalize_path(string_view path, uri_comparison_level level);
+} // namespace detail
+} // namespace network
+
+#endif // NETWORK_DETAIL_NORMALIZE_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/uri_parse.cpp b/graphics/asymptote/LspCpp/network/uri/detail/uri_parse.cpp
new file mode 100644
index 0000000000..46dd1b0f26
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/uri_parse.cpp
@@ -0,0 +1,424 @@
+// Copyright 2016-2017 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "uri_parse.hpp"
+#include <iterator>
+#include <limits>
+#include "grammar.hpp"
+#include <network/uri/detail/uri_parts.hpp>
+
+namespace network {
+namespace detail {
+namespace {
+enum class uri_state {
+ scheme,
+ hier_part,
+ query,
+ fragment
+};
+
+enum class hier_part_state {
+ first_slash,
+ second_slash,
+ authority,
+ host,
+ host_ipv6,
+ port,
+ path
+};
+
+bool validate_scheme(string_view::const_iterator &it,
+ string_view::const_iterator last) {
+ if (it == last) {
+ return false;
+ }
+
+ // The first character must be a letter
+ if (!std::isalpha(*it, std::locale("C"))) {
+ return false;
+ }
+ ++it;
+
+ while (it != last) {
+ if (*it == ':') {
+ break;
+ }
+ else if (!isalnum(it, last) && !is_in(it, last, "+-.")) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool validate_user_info(string_view::const_iterator it,
+ string_view::const_iterator last) {
+ while (it != last) {
+ if (!is_unreserved(it, last) &&
+ !is_pct_encoded(it, last) &&
+ !is_sub_delim(it, last) &&
+ !is_in(it, last, ":")) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool set_host_and_port(string_view::const_iterator first,
+ string_view::const_iterator last,
+ string_view::const_iterator last_colon,
+ uri_parts &parts) {
+ if (first >= last_colon) {
+ parts.hier_part.host = uri_part(first, last);
+ }
+ else {
+ auto port_start = last_colon;
+ ++port_start;
+ parts.hier_part.host = uri_part(first, last_colon);
+ if (!is_valid_port(port_start)) {
+ return false;
+ }
+ parts.hier_part.port = uri_part(port_start, last);
+ }
+ return true;
+}
+
+bool validate_fragment(string_view::const_iterator &it,
+ string_view::const_iterator last) {
+ while (it != last) {
+ if (!is_pchar(it, last) && !is_in(it, last, "?/")) {
+ return false;
+ }
+ }
+ return true;
+}
+} // namespace
+
+bool parse(string_view::const_iterator &it, string_view::const_iterator last,
+ uri_parts &parts) {
+ auto state = uri_state::scheme;
+
+ auto first = it;
+
+ if (it == last) {
+ return false;
+ }
+
+ if (validate_scheme(it, last)) {
+ parts.scheme = uri_part(first, it);
+ // move past the scheme delimiter
+ ++it;
+ state = uri_state::hier_part;
+ }
+ else {
+ return false;
+ }
+
+ // Hierarchical part
+ auto hp_state = hier_part_state::first_slash;
+ // this is used by the user_info/port
+ auto last_colon = first;
+ while (it != last) {
+ if (hp_state == hier_part_state::first_slash) {
+ if (*it == '/') {
+ hp_state = hier_part_state::second_slash;
+ // set the first iterator in case the second slash is not forthcoming
+ first = it;
+ ++it;
+ continue;
+ }
+ else {
+ hp_state = hier_part_state::path;
+ first = it;
+ }
+ }
+ else if (hp_state == hier_part_state::second_slash) {
+ if (*it == '/') {
+ hp_state = hier_part_state::authority;
+ ++it;
+ first = it;
+ continue;
+ }
+ else {
+ // it's a valid URI, and this is the beginning of the path
+ hp_state = hier_part_state::path;
+ }
+ }
+ else if (hp_state == hier_part_state::authority) {
+ if (is_in(first, last, "@:")) {
+ return false;
+ }
+
+ // reset the last colon
+ if (first == it) {
+ last_colon = first;
+ }
+
+ if (*it == '@') {
+ if (!validate_user_info(first, it)) {
+ return false;
+ }
+ parts.hier_part.user_info = uri_part(first, it);
+ hp_state = hier_part_state::host;
+ ++it;
+ first = it;
+
+ if (*first == '[') {
+ // this is an IPv6 address
+ hp_state = hier_part_state::host_ipv6;
+ }
+
+ continue;
+ }
+ else if (*it == '[') {
+ // this is an IPv6 address
+ hp_state = hier_part_state::host_ipv6;
+ first = it;
+ continue;
+ }
+ else if (*it == ':') {
+ last_colon = it;
+ }
+ else if (*it == '/') {
+ // we skipped right past the host and port, and are at the path.
+ if (!set_host_and_port(first, it, last_colon, parts)) {
+ return false;
+ }
+ hp_state = hier_part_state::path;
+ first = it;
+ continue;
+ }
+ else if (*it == '?') {
+ // the path is empty, but valid, and the next part is the query
+ if (!set_host_and_port(first, it, last_colon, parts)) {
+ return false;
+ }
+ parts.hier_part.path = uri_part(it, it);
+ state = uri_state::query;
+ ++it;
+ first = it;
+ break;
+ }
+ else if (*it == '#') {
+ // the path is empty, but valid, and the next part is the fragment
+ if (!set_host_and_port(first, it, last_colon, parts)) {
+ return false;
+ }
+ parts.hier_part.path = uri_part(it, it);
+ state = uri_state::fragment;
+ ++it;
+ first = it;
+ break;
+ }
+ }
+ else if (hp_state == hier_part_state::host) {
+ if (*first == ':') {
+ return false;
+ }
+
+ if (*it == ':') {
+ parts.hier_part.host = uri_part(first, it);
+ hp_state = hier_part_state::port;
+ ++it;
+ first = it;
+ continue;
+ }
+ else if (*it == '/') {
+ parts.hier_part.host = uri_part(first, it);
+ hp_state = hier_part_state::path;
+ first = it;
+ continue;
+ }
+ else if (*it == '?') {
+ // the path is empty, but valid, and the next part is the query
+ parts.hier_part.host = uri_part(first, it);
+ parts.hier_part.path = uri_part(it, it);
+ state = uri_state::query;
+ ++it;
+ first = it;
+ break;
+ }
+ else if (*it == '#') {
+ // the path is empty, but valid, and the next part is the fragment
+ parts.hier_part.host = uri_part(first, it);
+ parts.hier_part.path = uri_part(it, it);
+ state = uri_state::fragment;
+ ++it;
+ first = it;
+ break;
+ }
+ }
+ else if (hp_state == hier_part_state::host_ipv6) {
+ if (*first != '[') {
+ return false;
+ }
+
+ if (*it == ']') {
+ ++it;
+ // Then test if the next part is a host, part, or the end of the file
+ if (it == last) {
+ break;
+ }
+ else if (*it == ':') {
+ parts.hier_part.host = uri_part(first, it);
+ hp_state = hier_part_state::port;
+ ++it;
+ first = it;
+ }
+ else if (*it == '/') {
+ parts.hier_part.host = uri_part(first, it);
+ hp_state = hier_part_state::path;
+ first = it;
+ }
+ else if (*it == '?') {
+ parts.hier_part.host = uri_part(first, it);
+ parts.hier_part.path = uri_part(it, it);
+ state = uri_state::query;
+ ++it;
+ first = it;
+ break;
+ }
+ else if (*it == '#') {
+ parts.hier_part.host = uri_part(first, it);
+ parts.hier_part.path = uri_part(it, it);
+ state = uri_state::fragment;
+ ++it;
+ first = it;
+ break;
+ }
+ continue;
+ }
+ }
+ else if (hp_state == hier_part_state::port) {
+ if (*first == '/') {
+ // the port is empty, but valid
+ if (!is_valid_port(first)) {
+ return false;
+ }
+ parts.hier_part.port = uri_part(first, it);
+
+ // the port isn't set, but the path is
+ hp_state = hier_part_state::path;
+ continue;
+ }
+
+ if (*it == '/') {
+ if (!is_valid_port(first)) {
+ return false;
+ }
+ parts.hier_part.port = uri_part(first, it);
+ hp_state = hier_part_state::path;
+ first = it;
+ continue;
+ }
+ else if (!isdigit(it, last)) {
+ return false;
+ }
+ continue;
+ }
+ else if (hp_state == hier_part_state::path) {
+ if (*it == '?') {
+ parts.hier_part.path = uri_part(first, it);
+ // move past the query delimiter
+ ++it;
+ first = it;
+ state = uri_state::query;
+ break;
+ }
+ else if (*it == '#') {
+ parts.hier_part.path = uri_part(first, it);
+ // move past the fragment delimiter
+ ++it;
+ first = it;
+ state = uri_state::fragment;
+ break;
+ }
+
+ if (!is_pchar(it, last) && !is_in(it, last, "/")) {
+ return false;
+ }
+ else {
+ continue;
+ }
+ }
+
+ ++it;
+ }
+
+ if (state == uri_state::query) {
+ while (it != last) {
+ if (!is_pchar(it, last) && !is_in(it, last, "?/")) {
+ // If this is a fragment, keep going
+ if (*it == '#') {
+ parts.query = uri_part(first, it);
+ // move past the fragment delimiter
+ ++it;
+ first = it;
+ state = uri_state::fragment;
+ break;
+ }
+ else {
+ return false;
+ }
+ }
+ }
+ }
+
+ if (state == uri_state::fragment) {
+ if (!validate_fragment(it, last)) {
+ return false;
+ }
+ }
+
+ // we're done!
+ if (state == uri_state::hier_part) {
+ if (hp_state == hier_part_state::authority) {
+ if (first == last) {
+ return false;
+ }
+
+ if (!set_host_and_port(first, last, last_colon, parts)) {
+ return false;
+ }
+ parts.hier_part.path = uri_part(last, last);
+ }
+ else if (hp_state == hier_part_state::host) {
+ if (first == last) {
+ return false;
+ }
+
+ if (!set_host_and_port(first, last, last_colon, parts)) {
+ return false;
+ }
+ parts.hier_part.path = uri_part(last, last);
+ }
+ else if (hp_state == hier_part_state::host_ipv6) {
+ if (!set_host_and_port(first, last, last_colon, parts)) {
+ return false;
+ }
+ parts.hier_part.path = uri_part(last, last);
+ }
+ else if (hp_state == hier_part_state::port) {
+ if (!is_valid_port(first)) {
+ return false;
+ }
+ parts.hier_part.port = uri_part(first, last);
+ parts.hier_part.path = uri_part(last, last);
+ }
+ else if (hp_state == hier_part_state::path) {
+ parts.hier_part.path = uri_part(first, last);
+ }
+ }
+ else if (state == uri_state::query) {
+ parts.query = uri_part(first, last);
+ }
+ else if (state == uri_state::fragment) {
+ parts.fragment = uri_part(first, last);
+ }
+
+ return true;
+}
+} // namespace detail
+} // namespace network
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/uri_parse.hpp b/graphics/asymptote/LspCpp/network/uri/detail/uri_parse.hpp
new file mode 100644
index 0000000000..73835c3656
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/uri_parse.hpp
@@ -0,0 +1,19 @@
+// Copyright 2013-2016 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_DETAIL_URI_PARSE_INC
+#define NETWORK_DETAIL_URI_PARSE_INC
+
+#include <network/string_view.hpp>
+
+namespace network {
+namespace detail {
+struct uri_parts;
+
+bool parse(string_view::const_iterator &first, string_view::const_iterator last, uri_parts &parts);
+} // namespace detail
+} // namespace network
+
+#endif // NETWORK_DETAIL_URI_PARSE_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/uri_parse_authority.cpp b/graphics/asymptote/LspCpp/network/uri/detail/uri_parse_authority.cpp
new file mode 100644
index 0000000000..0db307f1f6
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/uri_parse_authority.cpp
@@ -0,0 +1,130 @@
+// Copyright 2016 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "uri_parse_authority.hpp"
+#include <cstdlib>
+#include <iterator>
+#include <limits>
+#include "grammar.hpp"
+
+namespace network {
+namespace detail {
+namespace {
+enum class authority_state {
+ user_info,
+ host,
+ host_ipv6,
+ port
+};
+} // namespace
+
+bool parse_authority(string_view::const_iterator &it,
+ string_view::const_iterator last,
+ optional<uri_part> &user_info,
+ optional<uri_part> &host,
+ optional<uri_part> &port) {
+ auto first = it;
+
+ auto state = authority_state::user_info;
+ while (it != last) {
+ if (state == authority_state::user_info) {
+ if (is_in(first, last, "@:")) {
+ return false;
+ }
+
+ if (*it == '@') {
+ user_info = uri_part(first, it);
+ state = authority_state::host;
+ ++it;
+ first = it;
+ continue;
+ }
+ else if (*it == '[') {
+ // this is an IPv6 address
+ state = authority_state::host_ipv6;
+ first = it;
+ continue;
+ }
+ else if (*it == ':') {
+ // this is actually the host, and the next part is expected to be the port
+ host = uri_part(first, it);
+ state = authority_state::port;
+ ++it;
+ first = it;
+ continue;
+ }
+ }
+ else if (state == authority_state::host) {
+ if (*first == ':') {
+ return false;
+ }
+
+ if (*it == ':') {
+ host = uri_part(first, it);
+ state = authority_state::port;
+ ++it;
+ first = it;
+ continue;
+ }
+ }
+ else if (state == authority_state::host_ipv6) {
+ if (*first != '[') {
+ return false;
+ }
+
+ if (*it == ']') {
+ host = uri_part(first, it);
+ ++it;
+ // Then test if the next part is a host, part, or the end of the file
+ if (it == last) {
+ break;
+ }
+ else if (*it == ':') {
+ host = uri_part(first, it);
+ state = authority_state::port;
+ ++it;
+ first = it;
+ }
+ }
+ }
+ else if (state == authority_state::port) {
+ if (*first == '/') {
+ // the port is empty, but valid
+ port = uri_part(first, it);
+ if (!is_valid_port(std::begin(*port))) {
+ return false;
+ }
+
+ continue;
+ }
+
+ if (!isdigit(it, last)) {
+ return false;
+ }
+ }
+
+ ++it;
+ }
+
+ if (state == authority_state::user_info) {
+ host = uri_part(first, last);
+ }
+ else if (state == authority_state::host) {
+ host = uri_part(first, last);
+ }
+ else if (state == authority_state::host_ipv6) {
+ host = uri_part(first, last);
+ }
+ else if (state == authority_state::port) {
+ port = uri_part(first, last);
+ if (!is_valid_port(std::begin(*port))) {
+ return false;
+ }
+ }
+
+ return true;
+}
+} // namespace detail
+} // namespace network
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/uri_parse_authority.hpp b/graphics/asymptote/LspCpp/network/uri/detail/uri_parse_authority.hpp
new file mode 100644
index 0000000000..cb37104258
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/uri_parse_authority.hpp
@@ -0,0 +1,21 @@
+// Copyright 2013-2016 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_DETAIL_URI_PARSE_AUTHORITY_INC
+#define NETWORK_DETAIL_URI_PARSE_AUTHORITY_INC
+
+#include <network/uri/detail/uri_parts.hpp>
+
+namespace network {
+namespace detail {
+bool parse_authority(string_view::const_iterator &first,
+ string_view::const_iterator last,
+ optional<uri_part> &user_info,
+ optional<uri_part> &host,
+ optional<uri_part> &port);
+} // namespace detail
+} // namespace network
+
+#endif // NETWORK_DETAIL_URI_PARSE_AUTHORITY_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/uri_parts.hpp b/graphics/asymptote/LspCpp/network/uri/detail/uri_parts.hpp
new file mode 100644
index 0000000000..17a69687fe
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/uri_parts.hpp
@@ -0,0 +1,88 @@
+// Copyright 2016 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_DETAIL_URI_PARTS_INC
+#define NETWORK_DETAIL_URI_PARTS_INC
+
+#include <string>
+#include <utility>
+#include <iterator>
+#include <network/optional.hpp>
+#include <network/string_view.hpp>
+
+namespace network {
+namespace detail {
+class uri_part {
+ public:
+ typedef string_view::value_type value_type;
+ typedef string_view::iterator iterator;
+ typedef string_view::const_iterator const_iterator;
+ typedef string_view::const_pointer const_pointer;
+ typedef string_view::size_type size_type;
+ typedef string_view::difference_type difference_type;
+
+ uri_part() noexcept = default;
+
+ uri_part(const_iterator first, const_iterator last) noexcept
+ : first(first), last(last) {}
+
+ const_iterator begin() const noexcept { return first; }
+
+ const_iterator end() const noexcept { return last; }
+
+ bool empty() const noexcept { return first == last; }
+
+ std::string to_string() const { return std::string(first, last); }
+
+ const_pointer ptr() const noexcept {
+ assert(first != last);
+ return first;
+ }
+
+ difference_type length() const noexcept {
+ return last - first;
+ }
+
+ string_view to_string_view() const noexcept { return string_view(ptr(), length()); }
+
+ private:
+ const_iterator first, last;
+};
+
+struct hierarchical_part {
+ hierarchical_part() = default;
+
+ optional<uri_part> user_info;
+ optional<uri_part> host;
+ optional<uri_part> port;
+ optional<uri_part> path;
+
+ void clear() {
+ user_info = nullopt;
+ host = nullopt;
+ port = nullopt;
+ path = nullopt;
+ }
+};
+
+struct uri_parts {
+ uri_parts() = default;
+
+ optional<uri_part> scheme;
+ hierarchical_part hier_part;
+ optional<uri_part> query;
+ optional<uri_part> fragment;
+
+ void clear() {
+ scheme = nullopt;
+ hier_part.clear();
+ query = nullopt;
+ fragment = nullopt;
+ }
+};
+} // namespace detail
+} // namespace network
+
+#endif // NETWORK_DETAIL_URI_PARTS_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/uri_percent_encode.hpp b/graphics/asymptote/LspCpp/network/uri/detail/uri_percent_encode.hpp
new file mode 100644
index 0000000000..ab5134db9c
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/uri_percent_encode.hpp
@@ -0,0 +1,80 @@
+// Copyright 2013-2016 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_DETAIL_URI_PERCENT_ENCODE_INC
+#define NETWORK_DETAIL_URI_PERCENT_ENCODE_INC
+
+#include <string>
+#include <vector>
+#include <locale>
+#include <network/optional.hpp>
+#include <network/uri/detail/decode.hpp>
+
+namespace network {
+namespace detail {
+
+inline optional<char> percent_encode(std::string::const_iterator it) {
+ try {
+ char output = '\0';
+ detail::decode_char(it, &output);
+ return output;
+ } catch (percent_decoding_error &) {
+ return optional<char>();
+ }
+}
+
+template <class String>
+struct percent_encoded_to_upper {
+ percent_encoded_to_upper() : count(0) {}
+
+ void operator()(typename String::value_type &c) {
+ if (c == '%') {
+ count = 2;
+ } else if (count > 0) {
+ c = std::toupper(c, std::locale());
+ --count;
+ }
+ }
+
+ unsigned count;
+};
+
+template <class Iter>
+Iter decode_encoded_unreserved_chars(Iter first, Iter last) {
+
+ // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
+
+ const auto is_unreserved = [](char c)
+ {
+ return std::isalnum(c, std::locale())
+ || '-' == c
+ || '.' == c
+ || '_' == c
+ || '~' == c;
+ };
+
+ auto it = first, it2 = first;
+ while (it != last) {
+ if (*it == '%') {
+ const auto sfirst = it;
+ const auto opt_char = percent_encode(sfirst);
+ if (opt_char && is_unreserved(*opt_char)) {
+ *it2 = *opt_char;
+ ++it; ++it;
+ } else {
+ *it2 = *it;
+ }
+ }
+ else {
+ *it2 = *it;
+ }
+ ++it; ++it2;
+ }
+ return it2;
+}
+} // namespace detail
+} // namespace network
+
+#endif // NETWORK_DETAIL_URI_PERCENT_ENCODE_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/uri_resolve.cpp b/graphics/asymptote/LspCpp/network/uri/detail/uri_resolve.cpp
new file mode 100644
index 0000000000..ca66405123
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/uri_resolve.cpp
@@ -0,0 +1,91 @@
+// Copyright 2013-2016 Glyn Matthews.
+// Copyright 2013 Hannes Kamecke.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include "uri_resolve.hpp"
+#include <algorithm>
+
+#ifdef NETWORK_URI_EXTERNAL_BOOST
+#include <boost/algorithm/string/find.hpp>
+#include <boost/algorithm/string/erase.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+namespace boost = boost;
+#else // NETWORK_URI_EXTERNAL_BOOST
+#include "boost/algorithm/string/find.hpp"
+#include "boost/algorithm/string/erase.hpp"
+#include "boost/algorithm/string/replace.hpp"
+#include "boost/algorithm/string/predicate.hpp"
+#endif // NETWORK_URI_EXTERNAL_BOOST
+
+namespace network {
+namespace detail {
+// remove_dot_segments
+inline
+void remove_last_segment(std::string& path) {
+ while (!path.empty()) {
+ if (path.back() == '/') {
+ path.pop_back();
+ break;
+ }
+ path.pop_back();
+ }
+}
+
+// implementation of http://tools.ietf.org/html/rfc3986#section-5.2.4
+static
+std::string remove_dot_segments(std::string input) {
+ std::string result;
+
+ while (!input.empty()) {
+ if (boost::starts_with(input, "../")) {
+ boost::erase_head(input, 3);
+ } else if (boost::starts_with(input, "./")) {
+ boost::erase_head(input, 2);
+ } else if (boost::starts_with(input, "/./")) {
+ boost::replace_head(input, 3, "/");
+ } else if (input == "/.") {
+ boost::replace_head(input, 2, "/");
+ } else if (boost::starts_with(input, "/../")) {
+ boost::erase_head(input, 3);
+ remove_last_segment(result);
+ } else if (boost::starts_with(input, "/..")) {
+ boost::replace_head(input, 3, "/");
+ remove_last_segment(result);
+ } else if (boost::algorithm::all(input, [](char ch) { return ch == '.'; })) {
+ input.clear();
+ }
+ else {
+ int n = (input.front() == '/')? 1 : 0;
+ auto slash = boost::find_nth(input, "/", n);
+ result.append(std::begin(input), std::begin(slash));
+ input.erase(std::begin(input), std::begin(slash));
+ }
+ }
+ return result;
+}
+
+std::string remove_dot_segments(string_view path) {
+ return remove_dot_segments(path.to_string());
+}
+
+// implementation of http://tools.ietf.org/html/rfc3986#section-5.2.3
+std::string merge_paths(const uri& base, const uri& reference) {
+ std::string result;
+
+ if (!base.has_path() || base.path().empty()) {
+ result = "/";
+ } else {
+ const auto& base_path = base.path();
+ auto last_slash = boost::find_last(base_path, "/");
+ result.append(std::begin(base_path), std::end(last_slash));
+ }
+ if (reference.has_path()) {
+ result.append(reference.path().to_string());
+ }
+ return remove_dot_segments(string_view(result));
+}
+} // namespace detail
+} // namespace network
diff --git a/graphics/asymptote/LspCpp/network/uri/detail/uri_resolve.hpp b/graphics/asymptote/LspCpp/network/uri/detail/uri_resolve.hpp
new file mode 100644
index 0000000000..898c6d5423
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/detail/uri_resolve.hpp
@@ -0,0 +1,22 @@
+// Copyright 2013-2016 Glyn Matthews.
+// Copyright 2013 Hannes Kamecke.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_DETAIL_RESOLVE_INC
+#define NETWORK_DETAIL_RESOLVE_INC
+
+#include <network/uri/uri.hpp>
+
+namespace network {
+namespace detail {
+// implementation of http://tools.ietf.org/html/rfc3986#section-5.2.4
+std::string remove_dot_segments(string_view input);
+
+// implementation of http://tools.ietf.org/html/rfc3986#section-5.2.3
+std::string merge_paths(const uri &base, const uri &reference);
+} // namespace detail
+} // namespace network
+
+#endif // NETWORK_DETAIL_RESOLVE_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/uri.cpp b/graphics/asymptote/LspCpp/network/uri/uri.cpp
new file mode 100644
index 0000000000..ee9aee45f1
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/uri.cpp
@@ -0,0 +1,701 @@
+// Copyright 2012-2017 Glyn Matthews.
+// Copyright 2012 Google, Inc.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <cassert>
+#include <locale>
+#include <algorithm>
+#include <functional>
+#include "network/uri/uri.hpp"
+#include "detail/uri_parse.hpp"
+#include "detail/uri_advance_parts.hpp"
+#include "detail/uri_percent_encode.hpp"
+#include "detail/uri_normalize.hpp"
+#include "detail/uri_resolve.hpp"
+#include "detail/algorithm.hpp"
+
+namespace network {
+namespace {
+// With the parser, we use string_views, which are mutable. However,
+// there are times (e.g. during normalization), when we want a part
+// to be mutable. This function returns a pair of
+// std::string::iterators in the same range as the URI part.
+//
+inline std::pair<std::string::iterator, std::string::iterator> mutable_part(
+ std::string &str, detail::uri_part part) {
+ auto view = string_view(str);
+
+ auto first_index = std::distance(std::begin(view), std::begin(part));
+ auto first = std::begin(str);
+ std::advance(first, first_index);
+
+ auto last_index = std::distance(std::begin(view), std::end(part));
+ auto last = std::begin(str);
+ std::advance(last, last_index);
+
+ return std::make_pair(first, last);
+}
+
+// This is a convenience function that converts a part of a
+// std::string to a string_view.
+inline string_view to_string_view(const std::string &uri,
+ detail::uri_part part) {
+ if (!part.empty()) {
+ const char *c_str = uri.c_str();
+ const char *part_begin = &(*(std::begin(part)));
+ std::advance(c_str, std::distance(c_str, part_begin));
+ return string_view(c_str, std::distance(std::begin(part), std::end(part)));
+ }
+ return string_view();
+}
+
+inline optional<std::string> make_arg(optional<string_view> view) {
+ if (view) {
+ return view->to_string();
+ }
+ return nullopt;
+}
+
+template <class T>
+inline void ignore(T) {}
+} // namespace
+
+void uri::initialize(optional<string_type> scheme,
+ optional<string_type> user_info,
+ optional<string_type> host, optional<string_type> port,
+ optional<string_type> path, optional<string_type> query,
+ optional<string_type> fragment) {
+ if (scheme) {
+ uri_.append(*scheme);
+ }
+
+ if (user_info || host || port) {
+ if (scheme) {
+ uri_.append("://");
+ }
+
+ if (user_info) {
+ uri_.append(*user_info);
+ uri_.append("@");
+ }
+
+ if (host) {
+ uri_.append(*host);
+ } else {
+ throw uri_builder_error();
+ }
+
+ if (port) {
+ uri_.append(":");
+ uri_.append(*port);
+ }
+ } else {
+ if (scheme) {
+ if (path || query || fragment) {
+ uri_.append(":");
+ } else {
+ throw uri_builder_error();
+ }
+ }
+ }
+
+ if (path) {
+ // if the URI is not opaque and the path is not already prefixed
+ // with a '/', add one.
+ if (host && (!path->empty() && path->front() != '/')) {
+ path = "/" + *path;
+ }
+ uri_.append(*path);
+ }
+
+ if (query) {
+ uri_.append("?");
+ uri_.append(*query);
+ }
+
+ if (fragment) {
+ uri_.append("#");
+ uri_.append(*fragment);
+ }
+
+ uri_view_ = string_view(uri_);
+
+ auto it = std::begin(uri_view_);
+ if (scheme) {
+ uri_parts_.scheme = detail::copy_part(*scheme, it);
+ // ignore : and ://
+ if (*it == ':') {
+ ++it;
+ }
+ if (*it == '/' && *(it + 1) == '/') {
+ it += 2;
+ }
+ }
+
+ if (user_info) {
+ uri_parts_.hier_part.user_info = detail::copy_part(*user_info, it);
+ ++it; // ignore @
+ }
+
+ if (host) {
+ uri_parts_.hier_part.host = detail::copy_part(*host, it);
+ }
+
+ if (port) {
+ ++it; // ignore :
+ uri_parts_.hier_part.port = detail::copy_part(*port, it);
+ }
+
+ if (path) {
+ uri_parts_.hier_part.path = detail::copy_part(*path, it);
+ }
+
+ if (query) {
+ ++it; // ignore ?
+ uri_parts_.query = detail::copy_part(*query, it);
+ }
+
+ if (fragment) {
+ ++it; // ignore #
+ uri_parts_.fragment = detail::copy_part(*fragment, it);
+ }
+}
+
+uri::uri() : uri_view_(uri_) {}
+
+uri::uri(const uri &other) : uri_(other.uri_), uri_view_(uri_) {
+ detail::advance_parts(uri_view_, uri_parts_, other.uri_parts_);
+}
+
+uri::uri(const uri_builder &builder) {
+ initialize(builder.scheme_, builder.user_info_, builder.host_, builder.port_,
+ builder.path_, builder.query_, builder.fragment_);
+}
+
+uri::uri(uri &&other) noexcept : uri_(std::move(other.uri_)),
+ uri_view_(uri_),
+ uri_parts_(std::move(other.uri_parts_)) {
+ detail::advance_parts(uri_view_, uri_parts_, other.uri_parts_);
+ other.uri_.clear();
+ other.uri_view_ = string_view(other.uri_);
+ other.uri_parts_ = detail::uri_parts();
+}
+
+uri::~uri() {}
+
+uri &uri::operator=(uri other) {
+ other.swap(*this);
+ return *this;
+}
+
+void uri::swap(uri &other) noexcept {
+ uri_.swap(other.uri_);
+ uri_view_ = uri_;
+ other.uri_view_ = other.uri_;
+
+ const auto this_parts = uri_parts_;
+ uri_parts_.clear();
+ detail::advance_parts(uri_view_, uri_parts_, other.uri_parts_);
+ other.uri_parts_.clear();
+ detail::advance_parts(other.uri_view_, other.uri_parts_, this_parts);
+}
+
+uri::const_iterator uri::begin() const noexcept { return uri_view_.begin(); }
+
+uri::const_iterator uri::end() const noexcept { return uri_view_.end(); }
+
+bool uri::has_scheme() const noexcept {
+ return static_cast<bool>(uri_parts_.scheme);
+}
+
+uri::string_view uri::scheme() const noexcept {
+ return has_scheme() ? to_string_view(uri_, *uri_parts_.scheme)
+ : string_view{};
+}
+
+bool uri::has_user_info() const noexcept {
+ return static_cast<bool>(uri_parts_.hier_part.user_info);
+}
+
+uri::string_view uri::user_info() const noexcept {
+ return has_user_info()
+ ? to_string_view(uri_, *uri_parts_.hier_part.user_info)
+ : string_view{};
+}
+
+bool uri::has_host() const noexcept {
+ return static_cast<bool>(uri_parts_.hier_part.host);
+}
+
+uri::string_view uri::host() const noexcept {
+ return has_host() ? to_string_view(uri_, *uri_parts_.hier_part.host)
+ : string_view{};
+}
+
+bool uri::has_port() const noexcept {
+ return static_cast<bool>(uri_parts_.hier_part.port);
+}
+
+uri::string_view uri::port() const noexcept {
+ return has_port() ? to_string_view(uri_, *uri_parts_.hier_part.port)
+ : string_view{};
+}
+
+bool uri::has_path() const noexcept {
+ return static_cast<bool>(uri_parts_.hier_part.path);
+}
+
+uri::string_view uri::path() const noexcept {
+ return has_path() ? to_string_view(uri_, *uri_parts_.hier_part.path)
+ : string_view{};
+}
+
+bool uri::has_query() const noexcept {
+ return static_cast<bool>(uri_parts_.query);
+}
+
+uri::string_view uri::query() const noexcept {
+ return has_query() ? to_string_view(uri_, *uri_parts_.query) : string_view{};
+}
+
+uri::query_iterator::query_iterator() : query_{}, kvp_{} {}
+
+uri::query_iterator::query_iterator(optional<detail::uri_part> query)
+ : query_(query)
+ , kvp_{} {
+ if (query_ && query_->empty()) {
+ query_ = nullopt;
+ }
+ else {
+ assign_kvp();
+ }
+}
+
+uri::query_iterator::query_iterator(const query_iterator &other)
+ : query_(other.query_)
+ , kvp_(other.kvp_) {}
+
+uri::query_iterator &uri::query_iterator::operator = (const query_iterator &other) {
+ auto tmp(other);
+ swap(tmp);
+ return *this;
+}
+
+uri::query_iterator::reference uri::query_iterator::operator ++ () noexcept {
+ increment();
+ return kvp_;
+}
+
+uri::query_iterator::value_type uri::query_iterator::operator ++ (int) noexcept {
+ auto original = kvp_;
+ increment();
+ return original;
+}
+
+uri::query_iterator::reference uri::query_iterator::operator * () const noexcept {
+ return kvp_;
+}
+
+uri::query_iterator::pointer uri::query_iterator::operator -> () const noexcept {
+ return std::addressof(kvp_);
+}
+
+bool uri::query_iterator::operator==(const query_iterator &other) const noexcept {
+ if (!query_ && !other.query_) {
+ return true;
+ }
+ else if (query_ && other.query_) {
+ // since we're comparing substrings, the address of the first
+ // element in each iterator must be the same
+ return std::addressof(kvp_.first) == std::addressof(other.kvp_.first);
+ }
+ return false;
+}
+
+void uri::query_iterator::swap(query_iterator &other) noexcept {
+ std::swap(query_, other.query_);
+ std::swap(kvp_, other.kvp_);
+}
+
+void uri::query_iterator::advance_to_next_kvp() noexcept {
+ auto first = std::begin(*query_), last = std::end(*query_);
+
+ auto sep_it = std::find_if(
+ first, last, [](char c) -> bool { return c == '&' || c == ';'; });
+
+ if (sep_it != last) {
+ ++sep_it; // skip next separator
+ }
+
+ // reassign query to the next element
+ query_ = detail::uri_part(sep_it, last);
+}
+
+void uri::query_iterator::assign_kvp() noexcept {
+ auto first = std::begin(*query_), last = std::end(*query_);
+
+ auto sep_it = std::find_if(
+ first, last, [](char c) -> bool { return c == '&' || c == ';'; });
+ auto eq_it =
+ std::find_if(first, sep_it, [](char c) -> bool { return c == '='; });
+
+ kvp_.first = string_view(std::addressof(*first), std::distance(first, eq_it));
+ if (eq_it != sep_it) {
+ ++eq_it; // skip '=' symbol
+ }
+ kvp_.second = string_view(std::addressof(*eq_it), std::distance(eq_it, sep_it));
+}
+
+void uri::query_iterator::increment() noexcept {
+ assert(query_);
+
+ if (!query_->empty()) {
+ advance_to_next_kvp();
+ assign_kvp();
+ }
+
+ if (query_->empty()) {
+ query_ = nullopt;
+ }
+}
+
+uri::query_iterator uri::query_begin() const noexcept {
+ return has_query()? uri::query_iterator{uri_parts_.query} : uri::query_iterator{};
+}
+
+uri::query_iterator uri::query_end() const noexcept {
+ return uri::query_iterator{};
+}
+
+bool uri::has_fragment() const noexcept {
+ return static_cast<bool>(uri_parts_.fragment);
+}
+
+uri::string_view uri::fragment() const noexcept {
+ return has_fragment() ? to_string_view(uri_, *uri_parts_.fragment)
+ : string_view{};
+}
+
+bool uri::has_authority() const noexcept {
+ return has_host();
+}
+
+uri::string_view uri::authority() const noexcept {
+ if (!has_host()) {
+ return string_view{};
+ }
+
+ auto host = this->host();
+
+ auto user_info = string_view{};
+ if (has_user_info()) {
+ user_info = this->user_info();
+ }
+
+ auto port = string_view{};
+ if (has_port()) {
+ port = this->port();
+ }
+
+ auto first = std::begin(host), last = std::end(host);
+ if (has_user_info() && !user_info.empty()) {
+ first = std::begin(user_info);
+ }
+ else if (host.empty() && has_port() && !port.empty()) {
+ first = std::begin(port);
+ --first; // include ':' before port
+ }
+
+ if (host.empty()) {
+ if (has_port() && !port.empty()) {
+ last = std::end(port);
+ }
+ else if (has_user_info() && !user_info.empty()) {
+ last = std::end(user_info);
+ ++last; // include '@'
+ }
+ }
+ else if (has_port()) {
+ if (port.empty()) {
+ ++last; // include ':' after host
+ }
+ else {
+ last = std::end(port);
+ }
+ }
+
+ return string_view(first, std::distance(first, last));
+}
+
+std::string uri::string() const { return uri_; }
+
+std::wstring uri::wstring() const {
+ return std::wstring(std::begin(*this), std::end(*this));
+}
+
+std::u16string uri::u16string() const {
+ return std::u16string(std::begin(*this), std::end(*this));
+}
+
+std::u32string uri::u32string() const {
+ return std::u32string(std::begin(*this), std::end(*this));
+}
+
+uri::string_view uri::view() const noexcept {
+ return uri_view_;
+}
+
+bool uri::empty() const noexcept { return uri_.empty(); }
+
+bool uri::is_absolute() const noexcept { return has_scheme(); }
+
+bool uri::is_opaque() const noexcept {
+ return (is_absolute() && !has_authority());
+}
+
+uri uri::normalize(uri_comparison_level level) const {
+ string_type normalized(uri_);
+ string_view normalized_view(normalized);
+ detail::uri_parts parts;
+ detail::advance_parts(normalized_view, parts, uri_parts_);
+
+ if (uri_comparison_level::syntax_based == level) {
+ // All alphabetic characters in the scheme and host are
+ // lower-case...
+ if (parts.scheme) {
+ std::string::iterator first, last;
+ std::tie(first, last) = mutable_part(normalized, *parts.scheme);
+ std::transform(first, last, first,
+ [](char ch) { return std::tolower(ch, std::locale()); });
+ }
+
+ // if (parts.hier_part.host) {
+ // std::string::iterator first, last;
+ // std::tie(first, last) = mutable_part(normalized, *parts.hier_part.host);
+ // std::transform(first, last, first,
+ // [](char ch) { return std::tolower(ch, std::locale()); });
+ // }
+
+ // ...except when used in percent encoding
+ detail::for_each(normalized, detail::percent_encoded_to_upper<std::string>());
+
+ // parts are invalidated here
+ // there's got to be a better way of doing this that doesn't
+ // mean parsing again (twice!)
+ normalized.erase(detail::decode_encoded_unreserved_chars(
+ std::begin(normalized), std::end(normalized)),
+ std::end(normalized));
+ normalized_view = string_view(normalized);
+
+ // need to parse the parts again as the underlying string has changed
+ const_iterator it = std::begin(normalized_view), last = std::end(normalized_view);
+ bool is_valid = detail::parse(it, last, parts);
+ ignore(is_valid);
+ assert(is_valid);
+
+ if (parts.hier_part.path) {
+ uri::string_type path = detail::normalize_path_segments(
+ to_string_view(normalized, *parts.hier_part.path));
+
+ // put the normalized path back into the uri
+ optional<string_type> query, fragment;
+ if (parts.query) {
+ query = parts.query->to_string();
+ }
+
+ if (parts.fragment) {
+ fragment = parts.fragment->to_string();
+ }
+
+ auto path_begin = std::begin(normalized);
+ auto path_range = mutable_part(normalized, *parts.hier_part.path);
+ std::advance(path_begin, std::distance(path_begin, path_range.first));
+ normalized.erase(path_begin, std::end(normalized));
+ normalized.append(path);
+
+ if (query) {
+ normalized.append("?");
+ normalized.append(*query);
+ }
+
+ if (fragment) {
+ normalized.append("#");
+ normalized.append(*fragment);
+ }
+ }
+ }
+
+ return uri(normalized);
+}
+
+uri uri::make_relative(const uri &other) const {
+ if (is_opaque() || other.is_opaque()) {
+ return other;
+ }
+
+ if ((!has_scheme() || !other.has_scheme()) ||
+ !detail::equal(scheme(), other.scheme())) {
+ return other;
+ }
+
+ if ((!has_authority() || !other.has_authority()) ||
+ !detail::equal(authority(), other.authority())) {
+ return other;
+ }
+
+ if (!has_path() || !other.has_path()) {
+ return other;
+ }
+
+ auto path =
+ detail::normalize_path(this->path(), uri_comparison_level::syntax_based);
+ auto other_path = detail::normalize_path(other.path(),
+ uri_comparison_level::syntax_based);
+
+ optional<string_type> query, fragment;
+ if (other.has_query()) {
+ query = other.query().to_string();
+ }
+
+ if (other.has_fragment()) {
+ fragment = other.fragment().to_string();
+ }
+
+ network::uri result;
+ result.initialize(optional<string_type>(), optional<string_type>(),
+ optional<string_type>(), optional<string_type>(),
+ other_path, query, fragment);
+ return result;
+}
+
+uri uri::resolve(const uri &base) const {
+ // This implementation uses the psuedo-code given in
+ // http://tools.ietf.org/html/rfc3986#section-5.2.2
+
+ if (is_absolute() && !is_opaque()) {
+ // throw an exception ?
+ return *this;
+ }
+
+ if (is_opaque()) {
+ // throw an exception ?
+ return *this;
+ }
+
+ optional<uri::string_type> user_info, host, port, path, query, fragment;
+
+ if (has_authority()) {
+ // g -> http://g
+ if (has_user_info()) {
+ user_info = make_arg(this->user_info());
+ }
+
+ if (has_host()) {
+ host = make_arg(this->host());
+ }
+
+ if (has_port()) {
+ port = make_arg(this->port());
+ }
+
+ if (has_path()) {
+ path = detail::remove_dot_segments(this->path());
+ }
+
+ if (has_query()) {
+ query = make_arg(this->query());
+ }
+ } else {
+ if (!has_path() || this->path().empty()) {
+ if (base.has_path()) {
+ path = make_arg(base.path());
+ }
+
+ if (has_query()) {
+ query = make_arg(this->query());
+ } else if (base.has_query()) {
+ query = make_arg(base.query());
+ }
+ } else {
+ if (this->path().front() == '/') {
+ path = detail::remove_dot_segments(this->path());
+ } else {
+ path = detail::merge_paths(base, *this);
+ }
+
+ if (has_query()) {
+ query = make_arg(this->query());
+ }
+ }
+
+ if (base.has_user_info()) {
+ user_info = make_arg(base.user_info());
+ }
+
+ if (base.has_host()) {
+ host = make_arg(base.host());
+ }
+
+ if (base.has_port()) {
+ port = make_arg(base.port());
+ }
+ }
+
+ if (has_fragment()) {
+ fragment = make_arg(this->fragment());
+ }
+
+ network::uri result;
+ result.initialize(make_arg(base.scheme()), std::move(user_info),
+ std::move(host), std::move(port), std::move(path),
+ std::move(query), std::move(fragment));
+ return result;
+}
+
+int uri::compare(const uri &other, uri_comparison_level level) const noexcept {
+ // if both URIs are empty, then we should define them as equal
+ // even though they're still invalid.
+ if (empty() && other.empty()) {
+ return 0;
+ }
+
+ if (empty()) {
+ return -1;
+ }
+
+ if (other.empty()) {
+ return 1;
+ }
+
+ return normalize(level).uri_.compare(other.normalize(level).uri_);
+}
+
+bool uri::initialize(const string_type &uri) {
+ uri_ = detail::trim_copy(uri);
+ if (!uri_.empty()) {
+ uri_view_ = string_view(uri_);
+ const_iterator it = std::begin(uri_view_), last = std::end(uri_view_);
+ bool is_valid = detail::parse(it, last, uri_parts_);
+ return is_valid;
+ }
+ return true;
+}
+
+void swap(uri &lhs, uri &rhs) noexcept { lhs.swap(rhs); }
+
+bool operator==(const uri &lhs, const uri &rhs) noexcept {
+ return lhs.view() == rhs.view();
+}
+
+bool operator==(const uri &lhs, const char *rhs) noexcept {
+ return lhs.view() == string_view{rhs};
+}
+
+bool operator<(const uri &lhs, const uri &rhs) noexcept {
+ return lhs.view() < rhs.view();
+}
+
+} // namespace network
diff --git a/graphics/asymptote/LspCpp/network/uri/uri.hpp b/graphics/asymptote/LspCpp/network/uri/uri.hpp
new file mode 100644
index 0000000000..429e2caeff
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/uri.hpp
@@ -0,0 +1,758 @@
+// Copyright 2009-2010 Jeroen Habraken.
+// Copyright 2009-2017 Dean Michael Berris, Glyn Matthews.
+// Copyright 2012 Google, Inc.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_URI_INC
+#define NETWORK_URI_INC
+
+/**
+ * \file
+ * \brief Contains the uri class.
+ */
+
+#include <iterator>
+#include <algorithm>
+#include <functional>
+#include <memory>
+#include <string>
+#include <cstdlib>
+#include <network/string_view.hpp>
+#include <network/optional.hpp>
+#include <network/uri/config.hpp>
+#include <network/uri/uri_errors.hpp>
+#include <network/uri/detail/uri_parts.hpp>
+#include <network/uri/detail/encode.hpp>
+#include <network/uri/detail/decode.hpp>
+#include <network/uri/detail/translate.hpp>
+
+#ifdef NETWORK_URI_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4251 4231 4660)
+#endif
+
+namespace network {
+/**
+ * \enum uri_comparison_level
+ * \brief Defines the steps on the URI comparison ladder.
+ */
+enum class uri_comparison_level {
+ string_comparison,
+ syntax_based,
+ scheme_based,
+};
+
+/**
+ * \ingroup uri
+ * \class uri_builder network/uri/uri_builder.hpp network/uri.hpp
+ * \brief A class that allows complex uri objects to be constructed.
+ * \sa uri
+ */
+class uri_builder;
+
+/**
+ * \ingroup uri
+ * \class uri network/uri/uri.hpp network/uri.hpp
+ * \brief A class that parses a URI (Uniform Resource Identifier)
+ * into its component parts.
+ *
+ * This class conforms to a URI as defined by RFC 3986, RFC 3987 and
+ * RFC 2732, including scoped IDs. It provides member functions for
+ * normalizing, comparing and resolving URIs.
+ *
+ * A URI has the syntax:
+ *
+ * \code
+ * [scheme:][user_info@][host][:port][path][?query][#fragment]
+ * \endcode
+ *
+ * Example:
+ *
+ * \code
+ * network::uri instance("http://cpp-netlib.org/");
+ * assert(instance.is_absolute());
+ * assert(!instance.is_opaque());
+ * assert(instance.scheme());
+ * assert("http" == *instance.scheme());
+ * assert(instance.host());
+ * assert("cpp-netlib.org" == *instance.host());
+ * assert(instance.path());
+ * assert("/" == *instance.path());
+ * \endcode
+ */
+class uri {
+#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
+ friend class uri_builder;
+#endif // !defined(DOXYGEN_SHOULD_SKIP_THIS)
+
+ public:
+ /**
+ * \brief The URI string_type.
+ */
+ typedef std::string string_type;
+
+ /**
+ * \brief A reference to the underlying string_type parts.
+ */
+ typedef network::string_view string_view;
+
+ /**
+ * \brief The char traits.
+ */
+ typedef string_view::traits_type traits_type;
+
+ /**
+ * \brief The URI const_iterator type.
+ */
+ typedef string_view::const_iterator const_iterator;
+
+ /**
+ * \brief The URI iterator type.
+ */
+ typedef const_iterator iterator;
+
+ /**
+ * \brief The URI value_type.
+ */
+ typedef std::iterator_traits<iterator>::value_type value_type;
+
+ /**
+ *
+ */
+ class query_iterator {
+ public:
+ using value_type = std::pair<string_view, string_view>;
+ using difference_type = std::ptrdiff_t;
+ using pointer = const value_type *;
+ using reference = const value_type &;
+ using iterator_category = std::forward_iterator_tag;
+
+ query_iterator();
+ explicit query_iterator(optional<detail::uri_part>);
+ query_iterator(const query_iterator &);
+ query_iterator &operator=(const query_iterator &);
+ reference operator++() noexcept;
+ value_type operator++(int) noexcept;
+ reference operator*() const noexcept;
+ pointer operator->() const noexcept;
+ bool operator==(const query_iterator &) const noexcept;
+ inline bool operator!=(const query_iterator &other) const noexcept {
+ return !(*this == other);
+ }
+
+ private:
+ void swap(query_iterator &) noexcept;
+ void advance_to_next_kvp() noexcept;
+ void assign_kvp() noexcept;
+ void increment() noexcept;
+
+ optional<detail::uri_part> query_;
+ value_type kvp_;
+ };
+
+ /**
+ * \brief Default constructor.
+ */
+ uri();
+
+ /**
+ * \brief Constructor.
+ * \param first The first element in a string sequence.
+ * \param last The end + 1th element in a string sequence.
+ * \throws uri_syntax_error if the sequence is not a valid URI.
+ * \throws std::bad_alloc If the underlying string cannot be allocated.
+ */
+ template <class InputIter>
+ uri(InputIter first, InputIter last) {
+ if (!initialize(string_type(first, last))) {
+ throw uri_syntax_error();
+ }
+ }
+
+#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
+ template <class InputIter>
+ explicit uri(InputIter first, InputIter last, std::error_code &ec) {
+ if (!initialize(string_type(first, last))) {
+ ec = make_error_code(uri_error::invalid_syntax);
+ }
+ }
+#endif // !defined(DOXYGEN_SHOULD_SKIP_THIS)
+
+ /**
+ * \brief Constructor.
+ * \param source A source string that is to be parsed as a URI.
+ * \throws uri_syntax_error if the source is not a valid URI.
+ * \throws std::bad_alloc If the underlying string cannot be allocated.
+ */
+ template <class Source>
+ explicit uri(const Source &source) {
+ if (!initialize(detail::translate(source))) {
+ throw uri_syntax_error();
+ }
+ }
+
+#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
+ template <class Source>
+ explicit uri(const Source &source, std::error_code &ec) {
+ if (!initialize(detail::translate(source))) {
+ ec = make_error_code(uri_error::invalid_syntax);
+ }
+ }
+#endif // !defined(DOXYGEN_SHOULD_SKIP_THIS)
+
+#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
+ explicit uri(const uri_builder &builder);
+#endif // !defined(DOXYGEN_SHOULD_SKIP_THIS)
+
+ /**
+ * \brief Copy constructor.
+ * \throws std::bad_alloc If the underlying string cannot be allocated.
+ */
+ uri(const uri &other);
+
+ /**
+ * \brief Move constructor.
+ */
+ uri(uri &&other) noexcept;
+
+ /**
+ * \brief Destructor.
+ */
+ ~uri();
+
+ /**
+ * \brief Assignment operator.
+ * \throws std::bad_alloc If the underlying string cannot be allocated.
+ */
+ uri &operator=(uri other);
+
+ /**
+ * \brief Swaps one uri object with another.
+ * \param other The other uri object.
+ */
+ void swap(uri &other) noexcept;
+
+ /**
+ * \brief Returns an iterator at the first element in the
+ * underlying sequence.
+ * \return An iterator starting at the first element.
+ */
+ const_iterator begin() const noexcept;
+
+ /**
+ * \brief Returns an iterator at the end + 1th element in the
+ * underlying sequence.
+ * \return An iterator starting at the end + 1th element.
+ */
+ const_iterator end() const noexcept;
+
+ /**
+ * \brief Tests whether this URI has a scheme component.
+ * \return \c true if the URI has a scheme, \c false otherwise.
+ */
+ bool has_scheme() const noexcept;
+
+ /**
+ * \brief Returns the URI scheme.
+ * \return The scheme.
+ * \pre has_scheme()
+ */
+ string_view scheme() const noexcept;
+
+ /**
+ * \brief Tests whether this URI has a user info component.
+ * \return \c true if the URI has a user info, \c false otherwise.
+ */
+ bool has_user_info() const noexcept;
+
+ /**
+ * \brief Returns the URI user info.
+ * \return The user info.
+ * \pre has_user_info()
+ */
+ string_view user_info() const noexcept;
+
+ /**
+ * \brief Tests whether this URI has a host component.
+ * \return \c true if the URI has a host, \c false otherwise.
+ */
+ bool has_host() const noexcept;
+
+ /**
+ * \brief Returns the URI host.
+ * \return The host.
+ * \pre has_host()
+ */
+ string_view host() const noexcept;
+
+ /**
+ * \brief Tests whether this URI has a port component.
+ * \return \c true if the URI has a port, \c false otherwise.
+ */
+ bool has_port() const noexcept;
+
+ /**
+ * \brief Returns the URI port.
+ * \return The port.
+ * \pre has_port()
+ */
+ string_view port() const noexcept;
+
+ /**
+ * \brief Returns the URI port as an integer.
+ * \return The port number.
+ * \pre has_port()
+ */
+ template <typename intT>
+ intT port(typename std::is_integral<intT>::type * = 0) const {
+ assert(has_port());
+ auto p = port();
+ const char *port_first = std::addressof(*p.begin());
+ char *port_last = 0;
+ return static_cast<intT>(std::strtoul(port_first, &port_last, 10));
+ }
+
+ /**
+ * \brief Tests whether this URI has a path component.
+ * \return \c true if the URI has a path, \c false otherwise.
+ */
+ bool has_path() const noexcept;
+
+ /**
+ * \brief Returns the URI path.
+ * \return The path.
+ * \pre has_path()
+ */
+ string_view path() const noexcept;
+
+ /**
+ * \brief Tests whether this URI has a query component.
+ * \return \c true if the URI has a query, \c false otherwise.
+ */
+ bool has_query() const noexcept;
+
+ /**
+ * \brief Returns the URI query.
+ * \return The query.
+ * \pre has_query()
+ */
+ string_view query() const noexcept;
+
+ /**
+ * \brief Returns an iterator to the first key-value pair in the query
+ * component.
+ *
+ * \return query_iterator.
+ */
+ query_iterator query_begin() const noexcept;
+
+ /**
+ * \brief Returns an iterator to the last key-value pair in the query
+ * component.
+ *
+ * \return query_iterator.
+ */
+ query_iterator query_end() const noexcept;
+
+ /**
+ * \brief Tests whether this URI has a fragment component.
+ * \return \c true if the URI has a fragment, \c false otherwise.
+ */
+ bool has_fragment() const noexcept;
+
+ /**
+ * \brief Returns the URI fragment.
+ * \return The fragment.
+ * \pre has_fragment()
+ */
+ string_view fragment() const noexcept;
+
+ /**
+ * \brief Tests whether this URI has a valid authority.
+ * \return \c true if the URI has an authority, \c false otherwise.
+ */
+ bool has_authority() const noexcept;
+
+ /**
+ * \brief Returns the URI authority.
+ * \return The authority.
+ */
+ string_view authority() const noexcept;
+
+ /**
+ * \brief Returns the URI as a std::basic_string object.
+ * \return A URI string.
+ */
+ template <class charT, class traits = std::char_traits<charT>,
+ class Allocator = std::allocator<charT> >
+ std::basic_string<charT, traits, Allocator> to_string(
+ const Allocator &alloc = Allocator()) const {
+ return std::basic_string<charT, traits, Allocator>(begin(), end());
+ }
+
+ /**
+ * \brief Returns the URI as a std::string object.
+ * \returns A URI string.
+ */
+ std::string string() const;
+
+ /**
+ * \brief Returns the URI as a std::wstring object.
+ * \returns A URI string.
+ */
+ std::wstring wstring() const;
+
+ /**
+ * \brief Returns the URI as a std::u16string object.
+ * \returns A URI string.
+ */
+ std::u16string u16string() const;
+
+ /**
+ * \brief Returns the URI as a std::u32string object.
+ * \returns A URI string.
+ */
+ std::u32string u32string() const;
+
+ /**
+ * \brief Returns the URI as a string_view object.
+ * \returns A URI string view.
+ */
+ string_view view() const noexcept;
+
+ /**
+ * \brief Checks if the uri object is empty, i.e. it has no parts.
+ * \returns \c true if there are no parts, \c false otherwise.
+ */
+ bool empty() const noexcept;
+
+ /**
+ * \brief Checks if the uri is absolute, i.e. it has a scheme.
+ * \returns \c true if it is absolute, \c false if it is relative.
+ */
+ bool is_absolute() const noexcept;
+
+ /**
+ * \brief Checks if the uri is opaque, i.e. if it doesn't have an
+ * authority.
+ * \returns \c true if it is opaque, \c false if it is hierarchical.
+ */
+ bool is_opaque() const noexcept;
+
+ /**
+ * \brief Normalizes a uri object at a given level in the
+ * comparison ladder.
+ * \param level The comparison level.
+ * \returns A normalized uri.
+ * \post compare(normalize(uri, level), level) == 0
+ * \throws std::bad_alloc
+ */
+ uri normalize(uri_comparison_level level) const;
+
+ /**
+ * \brief Returns a relative reference against the base URI.
+ * \param base The base URI.
+ * \returns A relative reference of this URI against the base.
+ * \throws std::bad_alloc
+ */
+ uri make_relative(const uri &base) const;
+
+ /**
+ * \brief Resolves a relative reference against the given URI.
+ * \param base The base URI to resolve against.
+ * \returns An absolute URI.
+ * \throws std::bad_alloc
+ */
+ uri resolve(const uri &base) const;
+
+ /**
+ * \brief Compares this URI against another, corresponding to the
+ * level in the comparison ladder.
+ * \param other The other URI.
+ * \param level The level in the comparison ladder.
+ * \returns \c 0 if the URIs are considered equal, \c -1 if this is
+ * less than other and and 1 if this is greater than
+ * other.
+ */
+ int compare(const uri &other, uri_comparison_level level) const noexcept;
+
+ /**
+ * \brief Encodes a sequence according to the rules for encoding a
+ * user info part.
+ * \param first The iterator at first element in the input
+ * sequence.
+ * \param last The iterator at end + 1th element in the input
+ * sequence.
+ * \param out The iterator at the first element in the output
+ * sequence.
+ * \returns The iterator at the end + 1th in the output sequence.
+ */
+ template <typename InputIter, typename OutputIter>
+ static OutputIter encode_user_info(InputIter first, InputIter last,
+ OutputIter out) {
+ return detail::encode_user_info(first, last, out);
+ }
+
+ /**
+ * \brief Encodes a sequence according to the rules for encoding a
+ * host part.
+ * \param first The iterator at first element in the input
+ * sequence.
+ * \param last The iterator at end + 1th element in the input
+ * sequence.
+ * \param out The iterator at the first element in the output
+ * sequence.
+ * \returns The iterator at the end + 1th in the output sequence.
+ */
+ template <typename InputIter, typename OutputIter>
+ static OutputIter encode_host(InputIter first, InputIter last,
+ OutputIter out) {
+ return detail::encode_host(first, last, out);
+ }
+
+ /**
+ * \brief Encodes a sequence according to the rules for encoding a
+ * port part.
+ * \param first The iterator at first element in the input
+ * sequence.
+ * \param last The iterator at end + 1th element in the input
+ * sequence.
+ * \param out The iterator at the first element in the output
+ * sequence.
+ * \returns The iterator at the end + 1th in the output sequence.
+ */
+ template <typename InputIter, typename OutputIter>
+ static OutputIter encode_port(InputIter first, InputIter last,
+ OutputIter out) {
+ return detail::encode_port(first, last, out);
+ }
+
+ /**
+ * \brief Encodes a sequence according to the rules for encoding a
+ * path part.
+ * \param first The iterator at first element in the input
+ * sequence.
+ * \param last The iterator at end + 1th element in the input
+ * sequence.
+ * \param out The iterator at the first element in the output
+ * sequence.
+ * \returns The iterator at the end + 1th in the output sequence.
+ */
+ template <typename InputIter, typename OutputIter>
+ static OutputIter encode_path(InputIter first, InputIter last,
+ OutputIter out) {
+ return detail::encode_path(first, last, out);
+ }
+
+ /**
+ * \deprecated Avoid using this function
+ * \brief Equivalent to \c encode_query_component
+ * \param first The iterator at first element in the input
+ * sequence.
+ * \param last The iterator at end + 1th element in the input
+ * sequence.
+ * \param out The iterator at the first element in the output
+ * sequence.
+ * \returns The iterator at the end + 1th in the output sequence.
+ * \sa encode_query_commponent
+ * \sa encode_query_key_value_pair
+ */
+ template <typename InputIter, typename OutputIter>
+ static OutputIter encode_query(InputIter first, InputIter last,
+ OutputIter out) {
+ return encode_query_component(first, last, out);
+ }
+
+ /**
+ * \brief Encodes a sequence according to the rules for encoding a
+ * query component, including the '=' character.
+ * \param first The iterator at first element in the input
+ * sequence.
+ * \param last The iterator at end + 1th element in the input
+ * sequence.
+ * \param out The iterator at the first element in the output
+ * sequence.
+ * \returns The iterator at the end + 1th in the output sequence.
+ */
+ template <typename InputIter, typename OutputIter>
+ static OutputIter encode_query_component(
+ InputIter first, InputIter last, OutputIter out) {
+ return detail::encode_query_component(first, last, out);
+ }
+
+ /**
+ * \brief Encodes a sequence according to the rules for encoding a
+ * query key value pair.
+ * \param key_first The iterator at first element in the input
+ * sequence.
+ * \param key_last The iterator at end + 1th element in the input
+ * sequence.
+ * \param out The iterator at the first element in the output
+ * sequence.
+ * \returns The iterator at the end + 1th in the output sequence.
+ */
+ template <typename InputIter, typename OutputIter>
+ static OutputIter encode_query_key_value_pair(
+ InputIter key_first, InputIter key_last,
+ InputIter value_first, InputIter value_last,
+ OutputIter out) {
+ out = detail::encode_query_component(key_first, key_last, out);
+ out++ = '=';
+ return detail::encode_query_component(value_first, value_last, out);
+ }
+
+ /**
+ * \brief Encodes a sequence according to the rules for encoding a
+ * fragment part.
+ * \param first The iterator at first element in the input
+ * sequence.
+ * \param last The iterator at end + 1th element in the input
+ * sequence.
+ * \param out The iterator at the first element in the output
+ * sequence.
+ * \returns The iterator at the end + 1th in the output sequence.
+ */
+ template <typename InputIter, typename OutputIter>
+ static OutputIter encode_fragment(InputIter first, InputIter last,
+ OutputIter out) {
+ return detail::encode_fragment(first, last, out);
+ }
+
+ /**
+ * \brief Decodes a sequence according to the percent decoding
+ * rules.
+ * \param first The iterator at first element in the input
+ * sequence.
+ * \param last The iterator at end + 1th element in the input
+ * sequence.
+ * \param out The iterator at the first element in the output
+ * sequence.
+ * \returns The iterator at the end + 1th in the output sequence.
+ */
+ template <typename InputIter, typename OutputIter>
+ static OutputIter decode(InputIter first, InputIter last, OutputIter out) {
+ return detail::decode(first, last, out);
+ }
+
+ private:
+ bool initialize(const string_type &uri);
+
+ void initialize(optional<string_type> scheme, optional<string_type> user_info,
+ optional<string_type> host, optional<string_type> port,
+ optional<string_type> path, optional<string_type> query,
+ optional<string_type> fragment);
+
+ string_type uri_;
+ string_view uri_view_;
+ detail::uri_parts uri_parts_;
+};
+
+
+/**
+ * \brief \c uri factory function.
+ * \param first The first element in a string sequence.
+ * \param last The end + 1th element in a string sequence.
+ * \param ec Error code set if the sequence is not a valid URI.
+ */
+template <class InputIter>
+inline uri make_uri(InputIter first, InputIter last, std::error_code &ec) {
+ return uri(first, last, ec);
+}
+
+/**
+ * \brief \c uri factory function.
+ * \param source A source string that is to be parsed as a URI.
+ * \param ec Error code set if the source is not a valid URI.
+ */
+template <class Source>
+inline uri make_uri(const Source &source, std::error_code &ec) {
+ return uri(source, ec);
+}
+
+/**
+ * \brief Swaps one uri object with another.
+ */
+void swap(uri &lhs, uri &rhs) noexcept;
+
+/**
+* \brief Equality operator for the \c uri.
+*/
+bool operator==(const uri &lhs, const uri &rhs) noexcept;
+
+/**
+ * \brief Equality operator for the \c uri.
+ */
+bool operator==(const uri &lhs, const char *rhs) noexcept;
+
+/**
+ * \brief Equality operator for the \c uri.
+ */
+inline bool operator==(const char *lhs, const uri &rhs) noexcept {
+ return rhs == lhs;
+}
+
+/**
+ * \brief Inequality operator for the \c uri.
+ */
+inline bool operator!=(const uri &lhs, const uri &rhs) noexcept {
+ return !(lhs == rhs);
+}
+
+/**
+ * \brief Less-than operator for the \c uri.
+ */
+bool operator<(const uri &lhs, const uri &rhs) noexcept;
+
+/**
+ * \brief Greater-than operator for the \c uri.
+ */
+inline bool operator>(const uri &lhs, const uri &rhs) noexcept {
+ return rhs < lhs;
+}
+
+/**
+ * \brief Less-than-or-equal-to operator for the \c uri.
+ */
+inline bool operator<=(const uri &lhs, const uri &rhs) noexcept {
+ return !(rhs < lhs);
+}
+
+/**
+ * \brief Greater-than-or-equal-to operator for the \c uri.
+ */
+inline bool operator>=(const uri &lhs, const uri &rhs) noexcept {
+ return !(lhs < rhs);
+}
+} // namespace network
+
+#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
+namespace std {
+template <>
+struct is_error_code_enum<network::uri_error> : public true_type {};
+} // namespace std
+
+namespace std {
+template <>
+struct hash<network::uri> {
+ std::size_t operator()(const network::uri &uri_) const {
+ std::size_t seed = 0;
+ std::for_each(std::begin(uri_), std::end(uri_),
+ [&seed](network::uri::value_type v) {
+ std::hash<network::uri::value_type> hasher;
+ seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+ });
+ return seed;
+ }
+};
+} // namespace std
+#endif // !defined(DOXYGEN_SHOULD_SKIP_THIS)
+
+#ifdef NETWORK_URI_MSVC
+#pragma warning(pop)
+#endif
+
+#include <network/uri/uri_builder.hpp>
+
+#endif // NETWORK_URI_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/uri_builder.cpp b/graphics/asymptote/LspCpp/network/uri/uri_builder.cpp
new file mode 100644
index 0000000000..c8d767ab47
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/uri_builder.cpp
@@ -0,0 +1,152 @@
+// Copyright (c) Glyn Matthews 2012-2016.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <locale>
+#include "network/uri/uri_builder.hpp"
+#include "detail/uri_normalize.hpp"
+#include "detail/uri_parse_authority.hpp"
+#include "detail/algorithm.hpp"
+
+namespace network {
+uri_builder::uri_builder(const network::uri &base_uri) {
+ if (base_uri.has_scheme()) {
+ scheme_ = base_uri.scheme().to_string();
+ }
+
+ if (base_uri.has_user_info()) {
+ user_info_ = base_uri.user_info().to_string();
+ }
+
+ if (base_uri.has_host()) {
+ host_ = base_uri.host().to_string();
+ }
+
+ if (base_uri.has_port()) {
+ port_ = base_uri.port().to_string();
+ }
+
+ if (base_uri.has_path()) {
+ path_ = base_uri.path().to_string();
+ }
+
+ if (base_uri.has_query()) {
+ query_ = base_uri.query().to_string();
+ }
+
+ if (base_uri.has_fragment()) {
+ fragment_ = base_uri.fragment().to_string();
+ }
+}
+
+uri_builder::~uri_builder() noexcept {}
+
+network::uri uri_builder::uri() const { return network::uri(*this); }
+
+void uri_builder::set_scheme(string_type &&scheme) {
+ // validate scheme is valid and normalize
+ scheme_ = scheme;
+ detail::transform(*scheme_, std::begin(*scheme_),
+ [] (char ch) { return std::tolower(ch, std::locale()); });
+}
+
+void uri_builder::set_user_info(string_type &&user_info) {
+ user_info_ = string_type();
+ network::uri::encode_user_info(std::begin(user_info), std::end(user_info),
+ std::back_inserter(*user_info_));
+}
+
+uri_builder &uri_builder::clear_user_info() {
+ user_info_ = network::nullopt;
+ return *this;
+}
+
+void uri_builder::set_host(string_type &&host) {
+ host_ = string_type();
+ network::uri::encode_host(std::begin(host), std::end(host),
+ std::back_inserter(*host_));
+ detail::transform(*host_, std::begin(*host_),
+ [](char ch) { return std::tolower(ch, std::locale()); });
+}
+
+void uri_builder::set_port(string_type &&port) {
+ port_ = string_type();
+ network::uri::encode_port(std::begin(port), std::end(port),
+ std::back_inserter(*port_));
+}
+
+uri_builder &uri_builder::clear_port() {
+ port_ = network::nullopt;
+ return *this;
+}
+
+void uri_builder::set_authority(string_type &&authority) {
+ optional<detail::uri_part> user_info, host, port;
+ uri::string_view view(authority);
+ uri::const_iterator it = std::begin(view), last = std::end(view);
+ detail::parse_authority(it, last, user_info, host, port);
+
+ if (user_info) {
+ set_user_info(user_info->to_string());
+ }
+
+ if (host) {
+ set_host(host->to_string());
+ }
+
+ if (port) {
+ set_port(port->to_string());
+ }
+}
+
+void uri_builder::set_path(string_type &&path) {
+ path_ = string_type();
+ network::uri::encode_path(std::begin(path), std::end(path),
+ std::back_inserter(*path_));
+}
+
+uri_builder &uri_builder::clear_path() {
+ path_ = network::nullopt;
+ return *this;
+}
+
+void uri_builder::append_query_component(string_type &&name) {
+ if (!query_) {
+ query_ = string_type();
+ }
+ else {
+ query_->append("&");
+ }
+ network::uri::encode_query_component(
+ std::begin(name), std::end(name), std::back_inserter(*query_));
+}
+
+void uri_builder::append_query_key_value_pair(string_type &&key, string_type &&value) {
+ if (!query_) {
+ query_ = string_type();
+ } else {
+ query_->push_back('&');
+ }
+ network::uri::encode_query_key_value_pair(
+ std::begin(key), std::end(key),
+ std::begin(value), std::end(value),
+ std::back_inserter(*query_));
+}
+
+uri_builder &uri_builder::clear_query() {
+ query_ = network::nullopt;
+ return *this;
+}
+
+void uri_builder::set_fragment(string_type &&fragment) {
+ fragment_ = string_type();
+ network::uri::encode_fragment(std::begin(fragment), std::end(fragment),
+ std::back_inserter(*fragment_));
+}
+
+uri_builder &uri_builder::clear_fragment() {
+ fragment_ = network::nullopt;
+ return *this;
+}
+} // namespace network
diff --git a/graphics/asymptote/LspCpp/network/uri/uri_builder.hpp b/graphics/asymptote/LspCpp/network/uri/uri_builder.hpp
new file mode 100644
index 0000000000..6c6d487b7d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/uri_builder.hpp
@@ -0,0 +1,277 @@
+// Copyright (c) Glyn Matthews 2012-2016.
+// Copyright 2012 Dean Michael Berris <dberris@google.com>
+// Copyright 2012 Google, Inc.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/**
+ * \file
+ * \brief Contains the definition of the uri_builder.
+ */
+
+#ifndef NETWORK_URI_BUILDER_INC
+#define NETWORK_URI_BUILDER_INC
+
+#include <cstdint>
+#include <utility>
+#include <type_traits>
+#include <network/uri/uri.hpp>
+
+#ifdef NETWORK_URI_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4251 4231 4660)
+#endif
+
+namespace network {
+#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
+namespace detail {
+
+template <class T>
+struct host_converter {
+ uri::string_type operator()(const T &host) const {
+ return detail::translate(host);
+ }
+};
+
+template <class T, class Enable = void>
+struct port_converter {
+ uri::string_type operator()(const T &port) const {
+ return detail::translate(port);
+ }
+};
+
+template <class T>
+struct port_converter<T, typename std::enable_if<std::is_integral<
+ typename std::decay<T>::type>::value>::type> {
+ uri::string_type operator()(std::uint16_t port) const {
+ return std::to_string(port);
+ }
+};
+
+template <class T>
+struct path_converter {
+ uri::string_type operator()(const T &path) const {
+ return detail::translate(path);
+ }
+};
+} // namespace detail
+#endif // !defined(DOXYGEN_SHOULD_SKIP_THIS)
+
+/**
+ * \ingroup uri
+ * \class uri_builder network/uri/uri_builder.hpp network/uri.hpp
+ * \brief A class that allows complex uri objects to be constructed.
+ * \sa uri
+ */
+class uri_builder {
+#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
+ friend class uri;
+#endif // !defined(DOXYGEN_SHOULD_SKIP_THIS)
+
+ uri_builder(const uri_builder &) = delete;
+ uri_builder &operator=(const uri_builder &) = delete;
+
+ public:
+ /**
+ * \brief The uri_builder string_type.
+ */
+ using string_type = network::uri::string_type;
+
+ /**
+ * \brief Constructor.
+ */
+ uri_builder() = default;
+
+ /**
+ * \brief Constructor.
+ * \param base A URI that is the base on which a new URI is built.
+ */
+ explicit uri_builder(const uri &base);
+
+ /**
+ * \brief Destructor.
+ */
+ ~uri_builder() noexcept;
+
+ /**
+ * \brief Adds a new scheme to the uri_builder.
+ * \param scheme The scheme.
+ * \returns \c *this
+ */
+ template <typename Source>
+ uri_builder &scheme(const Source &scheme) {
+ set_scheme(detail::translate(scheme));
+ return *this;
+ }
+
+ /**
+ * \brief Adds a new user info to the uri_builder.
+ * \param user_info The user info.
+ * \returns \c *this
+ */
+ template <typename Source>
+ uri_builder &user_info(const Source &user_info) {
+ set_user_info(detail::translate(user_info));
+ return *this;
+ }
+
+ /**
+ * \brief Clears the URI user_info part.
+ * \returns \c *this
+ */
+ uri_builder &clear_user_info();
+
+ /**
+ * \brief Adds a new host to the uri_builder.
+ * \param host The host.
+ * \returns \c *this
+ */
+ template <typename Source>
+ uri_builder &host(const Source &host) {
+ detail::host_converter<Source> convert;
+ set_host(convert(host));
+ return *this;
+ }
+
+ /**
+ * \brief Adds a new port to the uri_builder.
+ * \param port The port.
+ * \returns \c *this
+ */
+ template <typename Source>
+ uri_builder &port(const Source &port) {
+ detail::port_converter<Source> convert;
+ set_port(convert(port));
+ return *this;
+ }
+
+ /**
+ * \brief Clears the URI port part.
+ * \returns \c *this
+ */
+ uri_builder &clear_port();
+
+ /**
+ * \brief Adds a new authority to the uri_builder.
+ * \param authority The authority.
+ * \returns \c *this
+ */
+ template <typename Source>
+ uri_builder &authority(const Source &authority) {
+ set_authority(detail::translate(authority));
+ return *this;
+ }
+
+ /**
+ * \brief Adds a new path to the uri_builder.
+ * \param path The path.
+ * \returns \c *this
+ */
+ template <typename Source>
+ uri_builder &path(const Source &path) {
+ detail::path_converter<Source> convert;
+ set_path(convert(path));
+ return *this;
+ }
+
+ /**
+ * \brief Clears the URI path part.
+ * \returns \c *this
+ */
+ uri_builder &clear_path();
+
+ /**
+ * \deprecated Use append_query_component
+ * \warning This function's behaviour has changed and percent encoding
+ * of the '=' character is not ignored.
+ * \brief Adds a new query to the uri_builder.
+ * \param query The query.
+ * \returns \c *this
+ * \sa append_query_parameter
+ */
+ template <typename Source>
+ uri_builder &append_query(const Source &query) {
+ return append_query_component(query);
+ }
+
+ /**
+ * \brief Appends a new query component to the uri_builder. The
+ * '=' symbol is percent encoded.
+ * \param component The query component.
+ * \returns \c *this
+ * \sa append_query_key_value_pair
+ */
+ template <typename Source>
+ uri_builder &append_query_component(const Source &component) {
+ append_query_component(detail::translate(component));
+ return *this;
+ }
+
+ /**
+ * \brief Adds a new query key/value pair to the uri_builder.
+ * \param key The query parameter key.
+ * \param value The query parameter value.
+ * \returns \c *this
+ */
+ template <typename Key, typename Value>
+ uri_builder &append_query_key_value_pair(const Key &key, const Value &value) {
+ append_query_key_value_pair(detail::translate(key),
+ detail::translate(value));
+ return *this;
+ }
+
+ /**
+ * \brief Clears the URI query part.
+ * \returns \c *this
+ */
+ uri_builder &clear_query();
+
+ /**
+ * \brief Adds a new fragment to the uri_builder.
+ * \param fragment The fragment.
+ * \returns \c *this
+ */
+ template <typename Source>
+ uri_builder &fragment(const Source &fragment) {
+ set_fragment(detail::translate(fragment));
+ return *this;
+ }
+
+ /**
+ * \brief Clears the URI fragment part.
+ * \returns \c *this
+ */
+ uri_builder &clear_fragment();
+
+ /**
+ * \brief Builds a new uri object.
+ * \returns A valid uri object.
+ * \throws uri_builder_error if the uri_builder is unable to build
+ * a valid URI.
+ * \throws std::bad_alloc If the underlying string cannot be
+ * allocated.
+ */
+ network::uri uri() const;
+
+ private:
+ void set_scheme(string_type &&scheme);
+ void set_user_info(string_type &&user_info);
+ void set_host(string_type &&host);
+ void set_port(string_type &&port);
+ void set_authority(string_type &&authority);
+ void set_path(string_type &&path);
+ void append_query_component(string_type &&name);
+ void append_query_key_value_pair(string_type &&key, string_type &&value);
+ void set_fragment(string_type &&fragment);
+
+ optional<string_type> scheme_, user_info_, host_, port_, path_, query_,
+ fragment_;
+};
+} // namespace network
+
+#ifdef NETWORK_URI_MSVC
+#pragma warning(pop)
+#endif
+
+#endif // NETWORK_URI_BUILDER_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/uri_errors.cpp b/graphics/asymptote/LspCpp/network/uri/uri_errors.cpp
new file mode 100644
index 0000000000..b718cff586
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/uri_errors.cpp
@@ -0,0 +1,72 @@
+// Copyright 2013-2016 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <string>
+#include <network/uri/uri_errors.hpp>
+
+namespace network {
+
+ class uri_category_impl : public std::error_category {
+
+ public:
+
+ uri_category_impl() = default;
+
+ virtual ~uri_category_impl() noexcept;
+
+ virtual const char *name() const noexcept;
+
+ virtual std::string message(int ev) const;
+
+ };
+
+ uri_category_impl::~uri_category_impl() noexcept {}
+
+ const char *uri_category_impl::name() const noexcept {
+ static const char name[] = "uri_error";
+ return name;
+ }
+
+ std::string uri_category_impl::message(int ev) const {
+ switch (uri_error(ev)) {
+ case uri_error::invalid_syntax:
+ return "Unable to parse URI string.";
+ case uri_error::not_enough_input:
+ return "Percent decoding: Not enough input.";
+ case uri_error::non_hex_input:
+ return "Percent decoding: Non-hex input.";
+ case uri_error::conversion_failed:
+ return "Percent decoding: Conversion failed.";
+ default:
+ break;
+ }
+ return "Unknown URI error.";
+ }
+
+ const std::error_category &uri_category() {
+ static uri_category_impl uri_category;
+ return uri_category;
+ }
+
+ std::error_code make_error_code(uri_error e) {
+ return std::error_code(static_cast<int>(e), uri_category());
+ }
+
+ uri_syntax_error::uri_syntax_error()
+ : std::system_error(make_error_code(uri_error::invalid_syntax)) {}
+
+ uri_syntax_error::~uri_syntax_error() noexcept {}
+
+ uri_builder_error::uri_builder_error()
+ : std::system_error(make_error_code(uri_error::invalid_uri)) {}
+
+ uri_builder_error::~uri_builder_error() noexcept {}
+
+ percent_decoding_error::percent_decoding_error(uri_error error)
+ : std::system_error(make_error_code(error)) {}
+
+ percent_decoding_error::~percent_decoding_error() noexcept {}
+
+} // namespace network
diff --git a/graphics/asymptote/LspCpp/network/uri/uri_errors.hpp b/graphics/asymptote/LspCpp/network/uri/uri_errors.hpp
new file mode 100644
index 0000000000..a192533dfd
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/uri_errors.hpp
@@ -0,0 +1,122 @@
+// Copyright 2013-2016 Glyn Matthews.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NETWORK_URI_ERRORS_INC
+#define NETWORK_URI_ERRORS_INC
+
+/**
+ * \file
+ * \brief Contains functions and exceptions for URI error handling.
+ */
+
+#include <system_error>
+#include <network/uri/config.hpp>
+
+#ifdef NETWORK_URI_MSVC
+# pragma warning(push)
+# pragma warning(disable : 4251 4231 4660)
+ // Disable C4275 too because it's "essentially noise and can be silenced"
+ // according to Stephen T. Lavavej at Microsoft. See:
+ // https://connect.microsoft.com/VisualStudio/feedback/details/696593/vc-10-vs-2010-basic-string-exports.
+# pragma warning(disable : 4275)
+#endif
+
+namespace network {
+
+#if !defined(DOXYGEN_SHOULD_SKIP_THIS)
+ enum class uri_error {
+
+ // parser errors
+ invalid_syntax = 1,
+
+ // builder errors
+ invalid_uri,
+ invalid_scheme,
+ invalid_user_info,
+ invalid_host,
+ invalid_port,
+ invalid_path,
+ invalid_query,
+ invalid_fragment,
+
+ // encoding errors
+ not_enough_input,
+ non_hex_input,
+ conversion_failed,
+ };
+
+ const std::error_category &uri_category();
+
+ std::error_code make_error_code(uri_error e);
+#endif // !defined(DOXYGEN_SHOULD_SKIP_THIS)
+
+ /**
+ * \class uri_syntax_error uri.hpp network/uri.hpp
+ * \brief An exception thrown by the \c uri constructor when a URI
+ * cannot be parsed.
+ */
+ class uri_syntax_error : public std::system_error {
+
+ public:
+
+ /**
+ * \brief Constructor.
+ */
+ uri_syntax_error();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~uri_syntax_error() noexcept;
+
+ };
+
+ /**
+ * \class uri_builder_error uri.hpp network/uri.hpp
+ * \brief An exception thrown when the \c uri_builder cannot build a
+ * valid URI.
+ */
+ class uri_builder_error : public std::system_error {
+
+ public:
+
+ /**
+ * \brief Constructor.
+ */
+ uri_builder_error();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~uri_builder_error() noexcept;
+
+ };
+
+ /**
+ * \class percent_decoding_error uri.hpp network/uri.hpp
+ * \brief An exception thrown when during percent decoding.
+ */
+ class percent_decoding_error : public std::system_error {
+
+ public:
+
+ /**
+ * \brief Constructor.
+ */
+ explicit percent_decoding_error(uri_error error);
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~percent_decoding_error() noexcept;
+
+ };
+} // namespace network
+
+#ifdef NETWORK_URI_MSVC
+#pragma warning(pop)
+#endif
+
+#endif // NETWORK_URI_ERRORS_INC
diff --git a/graphics/asymptote/LspCpp/network/uri/uri_io.hpp b/graphics/asymptote/LspCpp/network/uri/uri_io.hpp
new file mode 100644
index 0000000000..cb9b243f43
--- /dev/null
+++ b/graphics/asymptote/LspCpp/network/uri/uri_io.hpp
@@ -0,0 +1,62 @@
+// Copyright (c) Glyn Matthews 2011-2016
+// Copyright 2012 Dean Michael Berris <dberris@google.com>
+// Copyright 2012 Google, Inc.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/**
+ * \file
+ * \brief Defines stream overloads for the uri class.
+ */
+
+#ifndef NETWORK_URI_URI_IO_INC
+#define NETWORK_URI_URI_IO_INC
+
+#include <network/uri/config.hpp>
+#include <network/uri/uri.hpp>
+#include <iosfwd>
+
+namespace network {
+#if !defined(NETWORK_URI_MSVC)
+template <typename CharT, class CharTraits = std::char_traits<CharT> >
+std::basic_ostream<CharT, CharTraits> &operator<<(
+ std::basic_ostream<CharT, CharTraits> &os, const uri &uri_) {
+ return os << uri_.to_string<CharT, CharTraits>();
+}
+
+template <typename CharT, class CharTraits = std::char_traits<CharT> >
+std::basic_istream<CharT, CharTraits> &operator>>(
+ std::basic_istream<CharT, CharTraits> &is, uri &uri_) {
+ std::basic_string<CharT, CharTraits> uri_string;
+ is >> uri_string;
+ uri_ = uri(uri_string);
+ return is;
+}
+#else
+inline std::ostream &operator<<(std::ostream &os, const uri &uri_) {
+ return os << uri_.string();
+}
+
+inline std::wostream &operator<<(std::wostream &os, const uri &uri_) {
+ return os << uri_.wstring();
+}
+
+inline std::istream &operator>>(std::istream &is, uri &uri_) {
+ std::string uri_string;
+ is >> uri_string;
+ uri_ = uri(uri_string);
+ return is;
+}
+
+inline std::wistream &operator>>(std::wistream &is, uri &uri_) {
+ std::wstring uri_string;
+ is >> uri_string;
+ uri_ = uri(uri_string);
+ return is;
+}
+#endif // !defined(NETWORK_URI_MSVC)
+
+} // namespace network
+
+#endif // NETWORK_URI_URI_IO_INC
diff --git a/graphics/asymptote/LspCpp/packages.config b/graphics/asymptote/LspCpp/packages.config
new file mode 100644
index 0000000000..f4caf6a09e
--- /dev/null
+++ b/graphics/asymptote/LspCpp/packages.config
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="boost" version="1.76.0.0" targetFramework="native" />
+ <package id="boost_chrono-vc141" version="1.76.0.0" targetFramework="native" />
+ <package id="boost_context-vc141" version="1.76.0.0" targetFramework="native" />
+ <package id="boost_coroutine-vc141" version="1.76.0.0" targetFramework="native" />
+ <package id="boost_date_time-vc141" version="1.76.0.0" targetFramework="native" />
+ <package id="boost_filesystem-vc141" version="1.76.0.0" targetFramework="native" />
+ <package id="boost_program_options-vc141" version="1.76.0.0" targetFramework="native" />
+ <package id="boost_regex-vc141" version="1.76.0.0" targetFramework="native" />
+ <package id="boost_system-vc140" version="1.76.0.0" targetFramework="native" />
+ <package id="boost_thread-vc141" version="1.76.0.0" targetFramework="native" />
+ <package id="tencent.rapidjson" version="1.1.1" targetFramework="native" />
+</packages> \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/CHANGE_LOG b/graphics/asymptote/LspCpp/third_party/threadpool/CHANGE_LOG
new file mode 100644
index 0000000000..635fbcfde5
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/CHANGE_LOG
@@ -0,0 +1,88 @@
+Change Log
+
+0.2.5
+ - Made threadpool compatible to boost::thread 1.37
+ - Fixed hang problem in shutdown method (Thanks to Sohail Somani)
+ - Adapted repository layout to boost (Thanks to Alex Ott)
+
+0.2.4 (Stable)
+ - Made threadpool compatible to boost::thread 1.35.x code base
+ - Fixed compiler warning in scope_guard.hpp
+
+0.2.3 (Development)
+ - Implemented workaround for Sun C++ Pro compiler bug in pool_core
+ - Removed subtask implementation (there was no demand for this feature)
+ - Improved shutdown policies
+
+0.2.2 (Development)
+ - Refactored SizePolicy and added SizePolicyController
+ - Moved policies into separate files
+ - Fixed some compiler problems (GCC)
+ - Implemented size_controller handling
+ - Implemented two size policies: static_size and fixed_size
+ - Refactored worker_thread handling, moved policies from pool_core to pool
+ - Specialized schedule function for usage with futures
+ - Added compile test project
+ - Improved constness in pool core class
+ - Fixed timed wait
+ - Implemented futures (in progress)
+ - Added result_type to all functors
+
+0.2.1 (Development)
+ - Pool base class (thread_pool) has now reference semantics
+ - Large refactorings: Removed scoped_pool, reimplemented worker (now worker_thread)
+ - Fixed odd resize behaviour. Now resize changes the number of threads immediately
+ - Apply pimpl idiom on pool core class (to make the ugly scoped_pool class needless)
+ - Introduced scheduling policies
+ - Switched to policy-based design (PBD), inspired by Scott Meyers C++ workshop
+ - Cosmetic code change: Replaced keyword 'class' with 'typename' in template definitions
+ - Revised tutorials
+ - New requirements: tasks functions should not and schedulers shall not throw exceptions
+
+
+0.2.0 (Development)
+ - Moved threadpool into the boost namespace: boost::threadpool
+ - Used keyword volatile to indicate thread-safe member functions
+ - Used volatile on primitve types were appropriate
+ - Moved worker to detail directory
+ - Fixed thread deletion
+ - Extended wait functionality (waiting for idle threads was implemented)
+ - Renamed 'join()' to 'wait()' as 'join' indicates the termination of thread. That was not the case in pool::join.
+ - Changed internal container of lifo and fifo schedulers to improve efficiency.
+ - Improved code reference documentation (source code browser)
+ - Renamed thread_func into task_func
+ - Added += operator to scoped_pool to ease scheduling of tasks
+ - Refactored file structures and class names
+ - Added a new task concept (named subtask) which allows the combination of sequential and parallel execution
+ - Added new task adaptor for looped or timed tasks: looped_task_func
+ - Introduced function clear() which can be used to remove all tasks from the pool and schedulers
+ - New function pool::active() which returns the number of active tasks
+
+0.1.8 (Development)
+ - Fixed some compile errors which were reported by gcc
+ - Wrote tutorial "Prioritized Tasks"
+
+0.1.7 (Development)
+ - Added Visual Studio 2005 project files for tutorial and examples
+
+0.1.6 (Development)
+ - Replaced task adaptor 'task' with boost::bind
+ - Workers are unregistered from thread_group when they are terminated
+ - Working on example boost::iostreams packet_filter
+
+0.1.5 (Development)
+ - Finished threadpool reference
+ - Class pool_adaptor was replaced by smart_pool
+ - Minor pool improvements
+ - First tutorial page online
+
+0.1.4 (Development)
+ - Created the pool's homepage: http://threadpool.sourceforge.net
+ - Improved documentation
+ - Added build scripts
+
+0.1.3 (Development)
+ - First public release
+ - Added mergesort example
+ - Added tutorial
+ - Implementation of threadpool core and related classes \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/COPYING b/graphics/asymptote/LspCpp/third_party/threadpool/COPYING
new file mode 100644
index 0000000000..06bdc4605a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/COPYING
@@ -0,0 +1,5 @@
+Copyright (c) 2005-2007 Philipp Henkel
+
+Use, modification, and distribution are subject to the
+Boost Software License, Version 1.0. (See accompanying file
+LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/Jamfile.v2 b/graphics/asymptote/LspCpp/third_party/threadpool/Jamfile.v2
new file mode 100644
index 0000000000..56c8549755
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/Jamfile.v2
@@ -0,0 +1,13 @@
+use-project /boost
+ : $(BOOST_ROOT)
+ ;
+
+project threadpool
+ : requirements <include>.&&$(BOOST_ROOT)
+ # disable auto-linking for all targets here,
+ # primarily because it caused troubles with V2
+ <define>BOOST_ALL_NO_LIB=1
+ : usage-requirements <include>.&&$(BOOST_ROOT)
+ : build-dir bin.v2
+ ;
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/Jamrules b/graphics/asymptote/LspCpp/third_party/threadpool/Jamrules
new file mode 100644
index 0000000000..8571a1461c
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/Jamrules
@@ -0,0 +1 @@
+project boost : $(BOOST_ROOT) ;
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/LICENSE_1_0.txt b/graphics/asymptote/LspCpp/third_party/threadpool/LICENSE_1_0.txt
new file mode 100644
index 0000000000..36b7cd93cd
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/LICENSE_1_0.txt
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/Makefile b/graphics/asymptote/LspCpp/third_party/threadpool/Makefile
new file mode 100644
index 0000000000..9acf23b272
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/Makefile
@@ -0,0 +1,32 @@
+export RELEASE_MANAGER=philipphenkel
+export RELEASE_VERSION=0_2_5
+
+doc: clean
+ make --directory=./libs/threadpool/doc --print-directory doc
+
+release_doc:
+ make --directory=./libs/threadpool/doc --print-directory release_doc
+
+release_src: clean fetch_clean_src
+ mv clean_src threadpool-$(RELEASE_VERSION)-src
+ zip -r9 threadpool-$(RELEASE_VERSION)-src.zip threadpool-$(RELEASE_VERSION)-src
+ rm -rf threadpool-$(RELEASE_VERSION)-src
+
+deploy_website:
+ make --directory=./libs/threadpool/doc --print-directory deploy_sf
+
+clean:
+ rm -rf clean_src
+ rm -rf threadpool-$(RELEASE_VERSION)-src.zip
+ rm -rf threadpool-$(RELEASE_VERSION)-doc.zip
+ make --directory=./libs/threadpool/doc --print-directory clean
+
+fetch_clean_src:
+ rm -rf clean_src
+ mkdir clean_src
+# cvs -d:pserver:anonymous@threadpool.cvs.sourceforge.net:/cvsroot/threadpool login
+ cd clean_src; cvs -z3 -d:pserver:anonymous@threadpool.cvs.sourceforge.net:/cvsroot/threadpool export -r RELEASE_$(RELEASE_VERSION) threadpool
+# cd clean_src; cvs -z3 -d:ext:$(RELEASE_MANAGER)@cvs.sourceforge.net:/cvsroot/threadpool export -r RELEASE_$(RELEASE_VERSION) threadpool
+
+
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/README b/graphics/asymptote/LspCpp/third_party/threadpool/README
new file mode 100644
index 0000000000..c6f1a83d81
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/README
@@ -0,0 +1,10 @@
+threadpool
+
+Copyright (c) 2005-2007 Philipp Henkel
+
+threadpool is a cross-platform C++ thread pool library and released under the Boost Software License.
+
+See doc/index.html for information on:
+ - API documentation and a tutorial
+ - External dependencies
+ - Using threadpool
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/TODO b/graphics/asymptote/LspCpp/third_party/threadpool/TODO
new file mode 100644
index 0000000000..1c5e6e26d6
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/TODO
@@ -0,0 +1,36 @@
+threadpool to-do items
+======================
+
+Documentation
+--------------------------------------------
+- Source code documentation
+- Design rationale
+- Tutorial
+- Finish Quickstart Tutorial/Example
+
+Functionality
+--------------------------------------------
+- Implement a size policy which dynamically
+ increase/decrease the pool's size:
+ - init with min/max threads
+ - auto increase
+ - auto decrease (using timed cleanup tasks)
+- Add some kind of deadline scheduler
+- Add futures to pool
+
+
+Examples
+--------------------------------------------
+- Buffering Client Requests: Handle 'bursty' client traffic
+ Some applications need more buffering than is provided by OS I/O subsystem
+
+ Working on 'active' buffer for boost::iostreams
+ buffer_filter which provides a dynamic amount of buffer objects.
+ buffer_filter uses a threadpool with one thread which provides the buffers to
+ consumer. (TODO Philipp)
+
+ 2nd implemention step:
+ Flexbile configuration: Buffer capacities can be configured according to
+ - maximum number of requests
+ - maximum number of bytes
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool.hpp b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool.hpp
new file mode 100644
index 0000000000..7d9ee48010
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool.hpp
@@ -0,0 +1,28 @@
+/*! \file
+* \brief Main include.
+*
+* This is the only file you have to include in order to use the
+* complete threadpool library.
+*
+* Copyright (c) 2005-2007 Philipp Henkel
+*
+* Use, modification, and distribution are subject to the
+* Boost Software License, Version 1.0. (See accompanying file
+* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+#ifndef THREADPOOL_HPP_INCLUDED
+#define THREADPOOL_HPP_INCLUDED
+
+#include "./threadpool/future.hpp"
+#include "./threadpool/pool.hpp"
+
+#include "./threadpool/pool_adaptors.hpp"
+#include "./threadpool/task_adaptors.hpp"
+
+
+#endif // THREADPOOL_HPP_INCLUDED
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/future.hpp b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/future.hpp
new file mode 100644
index 0000000000..4e4b35bebe
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/future.hpp
@@ -0,0 +1,215 @@
+/*! \file
+* \brief TODO.
+*
+* TODO.
+*
+* Copyright (c) 2005-2007 Philipp Henkel
+*
+* Use, modification, and distribution are subject to the
+* Boost Software License, Version 1.0. (See accompanying file
+* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+
+#ifndef THREADPOOL_DETAIL_FUTURE_IMPL_HPP_INCLUDED
+#define THREADPOOL_DETAIL_FUTURE_IMPL_HPP_INCLUDED
+
+
+#include "locking_ptr.hpp"
+
+#include <boost/smart_ptr.hpp>
+#include <boost/optional.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/xtime.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+
+namespace boost { namespace threadpool { namespace detail
+{
+
+template<class Result>
+class future_impl
+{
+public:
+ typedef Result const & result_type; //!< Indicates the functor's result type.
+
+ typedef Result future_result_type; //!< Indicates the future's result type.
+ typedef future_impl<future_result_type> future_type;
+
+private:
+ volatile bool m_ready;
+ volatile future_result_type m_result;
+
+ mutable mutex m_monitor;
+ mutable condition m_condition_ready;
+
+ volatile bool m_is_cancelled;
+ volatile bool m_executing;
+
+public:
+
+
+public:
+
+ future_impl()
+ : m_ready(false)
+ , m_is_cancelled(false)
+ {
+ }
+
+ bool ready() const volatile
+ {
+ return m_ready;
+ }
+
+ void wait() const volatile
+ {
+ const future_type* self = const_cast<const future_type*>(this);
+ mutex::scoped_lock lock(self->m_monitor);
+
+ while(!m_ready)
+ {
+ self->m_condition_ready.wait(lock);
+ }
+ }
+
+
+ bool timed_wait(boost::xtime const & timestamp) const
+ {
+ const future_type* self = const_cast<const future_type*>(this);
+ mutex::scoped_lock lock(self->m_monitor);
+
+ while(!m_ready)
+ {
+ if(!self->m_condition_ready.timed_wait(lock, timestamp)) return false;
+ }
+
+ return true;
+ }
+
+
+ result_type operator()() const volatile
+ {
+ wait();
+/*
+ if( throw_exception_ != 0 )
+ {
+ throw_exception_( this );
+ }
+*/
+
+ return *(const_cast<const future_result_type*>(&m_result));
+ }
+
+
+ void set_value(future_result_type const & r) volatile
+ {
+ locking_ptr<future_type, mutex> lockedThis(*this, m_monitor);
+ if(!m_ready && !m_is_cancelled)
+ {
+ lockedThis->m_result = r;
+ lockedThis->m_ready = true;
+ lockedThis->m_condition_ready.notify_all();
+ }
+ }
+/*
+ template<class E> void set_exception() // throw()
+ {
+ m_impl->template set_exception<E>();
+ }
+
+ template<class E> void set_exception( char const * what ) // throw()
+ {
+ m_impl->template set_exception<E>( what );
+ }
+ */
+
+
+ bool cancel() volatile
+ {
+ if(!m_ready || m_executing)
+ {
+ m_is_cancelled = true;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ bool is_cancelled() const volatile
+ {
+ return m_is_cancelled;
+ }
+
+
+ void set_execution_status(bool executing) volatile
+ {
+ m_executing = executing;
+ }
+};
+
+
+template<
+ template <typename> class Future,
+ typename Function
+>
+class future_impl_task_func
+{
+
+public:
+ typedef void result_type; //!< Indicates the functor's result type.
+
+ typedef Function function_type; //!< Indicates the function's type.
+ typedef typename result_of<function_type()>::type future_result_type; //!< Indicates the future's result type.
+ typedef Future<future_result_type> future_type; //!< Indicates the future's type.
+
+ // The task is required to be a nullary function.
+ BOOST_STATIC_ASSERT(function_traits<function_type()>::arity == 0);
+
+ // The task function's result type is required not to be void.
+ BOOST_STATIC_ASSERT(!is_void<future_result_type>::value);
+
+private:
+ function_type m_function;
+ shared_ptr<future_type> m_future;
+
+public:
+ future_impl_task_func(function_type const & function, shared_ptr<future_type> const & future)
+ : m_function(function)
+ , m_future(future)
+ {
+ }
+
+ void operator()()
+ {
+ if(m_function)
+ {
+ m_future->set_execution_status(true);
+ if(!m_future->is_cancelled())
+ {
+ // TODO future exeception handling
+ m_future->set_value(m_function());
+ }
+ m_future->set_execution_status(false); // TODO consider exceptions
+ }
+ }
+
+};
+
+
+
+
+
+} } } // namespace boost::threadpool::detail
+
+#endif // THREADPOOL_DETAIL_FUTURE_IMPL_HPP_INCLUDED
+
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/locking_ptr.hpp b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/locking_ptr.hpp
new file mode 100644
index 0000000000..57ba560b5a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/locking_ptr.hpp
@@ -0,0 +1,85 @@
+/*! \file
+* \brief The locking_ptr is smart pointer with a scoped locking mechanism.
+*
+* The class is a wrapper for a volatile pointer. It enables synchronized access to the
+* internal pointer by locking the passed mutex.
+* locking_ptr is based on Andrei Alexandrescu's LockingPtr. For more information
+* see article "volatile - Multithreaded Programmer's Best Friend" by A. Alexandrescu.
+*
+*
+* Copyright (c) 2005-2007 Philipp Henkel
+*
+* Use, modification, and distribution are subject to the
+* Boost Software License, Version 1.0. (See accompanying file
+* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+
+#ifndef THREADPOOL_DETAIL_LOCKING_PTR_HPP_INCLUDED
+#define THREADPOOL_DETAIL_LOCKING_PTR_HPP_INCLUDED
+
+#include <boost/utility.hpp>
+#include <boost/thread/mutex.hpp>
+
+
+namespace boost { namespace threadpool { namespace detail
+{
+
+/*! \brief Smart pointer with a scoped locking mechanism.
+ *
+ * This class is a wrapper for a volatile pointer. It enables synchronized access to the
+ * internal pointer by locking the passed mutex.
+ */
+ template <typename T, typename Mutex>
+ class locking_ptr
+ : private noncopyable
+ {
+ T* m_obj; //!< The instance pointer.
+ Mutex & m_mutex; //!< Mutex is used for scoped locking.
+
+ public:
+ /// Constructor.
+ locking_ptr(volatile T& obj, const volatile Mutex& mtx)
+ : m_obj(const_cast<T*>(&obj))
+ , m_mutex(*const_cast<Mutex*>(&mtx))
+ {
+ // Lock mutex
+ m_mutex.lock();
+ }
+
+
+ /// Destructor.
+ ~locking_ptr()
+ {
+ // Unlock mutex
+ m_mutex.unlock();
+ }
+
+
+ /*! Returns a reference to the stored instance.
+ * \return The instance's reference.
+ */
+ T& operator*() const
+ {
+ return *m_obj;
+ }
+
+
+ /*! Returns a pointer to the stored instance.
+ * \return The instance's pointer.
+ */
+ T* operator->() const
+ {
+ return m_obj;
+ }
+ };
+
+
+} } } // namespace boost::threadpool::detail
+
+
+#endif // THREADPOOL_DETAIL_LOCKING_PTR_HPP_INCLUDED
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/pool_core.hpp b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/pool_core.hpp
new file mode 100644
index 0000000000..a81df87763
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/pool_core.hpp
@@ -0,0 +1,453 @@
+/*! \file
+* \brief Thread pool core.
+*
+* This file contains the threadpool's core class: pool<Task, SchedulingPolicy>.
+*
+* Thread pools are a mechanism for asynchronous and parallel processing
+* within the same process. The pool class provides a convenient way
+* for dispatching asynchronous tasks as functions objects. The scheduling
+* of these tasks can be easily controlled by using customized schedulers.
+*
+* Copyright (c) 2005-2007 Philipp Henkel
+*
+* Use, modification, and distribution are subject to the
+* Boost Software License, Version 1.0. (See accompanying file
+* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+
+#ifndef THREADPOOL_POOL_CORE_HPP_INCLUDED
+#define THREADPOOL_POOL_CORE_HPP_INCLUDED
+
+
+
+
+#include "locking_ptr.hpp"
+#include "worker_thread.hpp"
+
+#include "../task_adaptors.hpp"
+
+#include <boost/thread.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/smart_ptr.hpp>
+#include <boost/bind.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+
+#include <vector>
+
+
+/// The namespace threadpool contains a thread pool and related utility classes.
+namespace boost { namespace threadpool { namespace detail
+{
+
+ /*! \brief Thread pool.
+ *
+ * Thread pools are a mechanism for asynchronous and parallel processing
+ * within the same process. The pool class provides a convenient way
+ * for dispatching asynchronous tasks as functions objects. The scheduling
+ * of these tasks can be easily controlled by using customized schedulers.
+ * A task must not throw an exception.
+ *
+ * A pool_impl is DefaultConstructible and NonCopyable.
+ *
+ * \param Task A function object which implements the operator 'void operator() (void) const'. The operator () is called by the pool to execute the task. Exceptions are ignored.
+ * \param Scheduler A task container which determines how tasks are scheduled. It is guaranteed that this container is accessed only by one thread at a time. The scheduler shall not throw exceptions.
+ *
+ * \remarks The pool class is thread-safe.
+ *
+ * \see Tasks: task_func, prio_task_func
+ * \see Scheduling policies: fifo_scheduler, lifo_scheduler, prio_scheduler
+ */
+ template <
+ typename Task,
+
+ template <typename> class SchedulingPolicy,
+ template <typename> class SizePolicy,
+ template <typename> class SizePolicyController,
+ template <typename> class ShutdownPolicy
+ >
+ class pool_core
+ : public enable_shared_from_this< pool_core<Task, SchedulingPolicy, SizePolicy, SizePolicyController, ShutdownPolicy > >
+ , private noncopyable
+ {
+
+ public: // Type definitions
+ typedef Task task_type; //!< Indicates the task's type.
+ typedef SchedulingPolicy<task_type> scheduler_type; //!< Indicates the scheduler's type.
+ typedef pool_core<Task,
+ SchedulingPolicy,
+ SizePolicy,
+ SizePolicyController,
+ ShutdownPolicy > pool_type; //!< Indicates the thread pool's type.
+ typedef SizePolicy<pool_type> size_policy_type; //!< Indicates the sizer's type.
+ //typedef typename size_policy_type::size_controller size_controller_type;
+
+ typedef SizePolicyController<pool_type> size_controller_type;
+
+// typedef SizePolicy<pool_type>::size_controller size_controller_type;
+ typedef ShutdownPolicy<pool_type> shutdown_policy_type;//!< Indicates the shutdown policy's type.
+
+ typedef worker_thread<pool_type> worker_type;
+
+ // The task is required to be a nullary function.
+ BOOST_STATIC_ASSERT(function_traits<task_type()>::arity == 0);
+
+ // The task function's result type is required to be void.
+ BOOST_STATIC_ASSERT(is_void<typename result_of<task_type()>::type >::value);
+
+
+ private: // Friends
+ friend class worker_thread<pool_type>;
+
+#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x580) // Tested with CC: Sun C++ 5.8 Patch 121018-08 2006/12/06
+ friend class SizePolicy;
+ friend class ShutdownPolicy;
+#else
+ friend class SizePolicy<pool_type>;
+ friend class ShutdownPolicy<pool_type>;
+#endif
+
+ private: // The following members may be accessed by _multiple_ threads at the same time:
+ volatile size_t m_worker_count;
+ volatile size_t m_target_worker_count;
+ volatile size_t m_active_worker_count;
+
+
+
+ private: // The following members are accessed only by _one_ thread at the same time:
+ scheduler_type m_scheduler;
+ scoped_ptr<size_policy_type> m_size_policy; // is never null
+
+ bool m_terminate_all_workers; // Indicates if termination of all workers was triggered.
+ std::vector<shared_ptr<worker_type> > m_terminated_workers; // List of workers which are terminated but not fully destructed.
+
+ private: // The following members are implemented thread-safe:
+ mutable recursive_mutex m_monitor;
+ mutable condition m_worker_idle_or_terminated_event; // A worker is idle or was terminated.
+ mutable condition m_task_or_terminate_workers_event; // Task is available OR total worker count should be reduced.
+
+ public:
+ /// Constructor.
+ pool_core()
+ : m_worker_count(0)
+ , m_target_worker_count(0)
+ , m_active_worker_count(0)
+ , m_terminate_all_workers(false)
+ {
+ pool_type volatile & self_ref = *this;
+ m_size_policy.reset(new size_policy_type(self_ref));
+
+ m_scheduler.clear();
+ }
+
+
+ /// Destructor.
+ ~pool_core()
+ {
+ }
+
+ /*! Gets the size controller which manages the number of threads in the pool.
+ * \return The size controller.
+ * \see SizePolicy
+ */
+ size_controller_type size_controller()
+ {
+ return size_controller_type(*m_size_policy, this->shared_from_this());
+ }
+
+ /*! Gets the number of threads in the pool.
+ * \return The number of threads.
+ */
+ size_t size() const volatile
+ {
+ return m_worker_count;
+ }
+
+// TODO is only called once
+ void shutdown()
+ {
+ ShutdownPolicy<pool_type>::shutdown(*this);
+ }
+
+ /*! Schedules a task for asynchronous execution. The task will be executed once only.
+ * \param task The task function object. It should not throw execeptions.
+ * \return true, if the task could be scheduled and false otherwise.
+ */
+ bool schedule(task_type const & task) volatile
+ {
+ locking_ptr<pool_type, recursive_mutex> lockedThis(*this, m_monitor);
+
+ if(lockedThis->m_scheduler.push(task))
+ {
+ lockedThis->m_task_or_terminate_workers_event.notify_one();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ /*! Returns the number of tasks which are currently executed.
+ * \return The number of active tasks.
+ */
+ size_t active() const volatile
+ {
+ return m_active_worker_count;
+ }
+
+
+ /*! Returns the number of tasks which are ready for execution.
+ * \return The number of pending tasks.
+ */
+ size_t pending() const volatile
+ {
+ locking_ptr<const pool_type, recursive_mutex> lockedThis(*this, m_monitor);
+ return lockedThis->m_scheduler.size();
+ }
+
+
+ /*! Removes all pending tasks from the pool's scheduler.
+ */
+ void clear() volatile
+ {
+ locking_ptr<pool_type, recursive_mutex> lockedThis(*this, m_monitor);
+ lockedThis->m_scheduler.clear();
+ }
+
+
+ /*! Indicates that there are no tasks pending.
+ * \return true if there are no tasks ready for execution.
+ * \remarks This function is more efficient that the check 'pending() == 0'.
+ */
+ bool empty() const volatile
+ {
+ locking_ptr<const pool_type, recursive_mutex> lockedThis(*this, m_monitor);
+ return lockedThis->m_scheduler.empty();
+ }
+
+
+ /*! The current thread of execution is blocked until the sum of all active
+ * and pending tasks is equal or less than a given threshold.
+ * \param task_threshold The maximum number of tasks in pool and scheduler.
+ */
+ void wait(size_t const task_threshold = 0) const volatile
+ {
+ const pool_type* self = const_cast<const pool_type*>(this);
+ recursive_mutex::scoped_lock lock(self->m_monitor);
+
+ if(0 == task_threshold)
+ {
+ while(0 != self->m_active_worker_count || !self->m_scheduler.empty())
+ {
+ self->m_worker_idle_or_terminated_event.wait(lock);
+ }
+ }
+ else
+ {
+ while(task_threshold < self->m_active_worker_count + self->m_scheduler.size())
+ {
+ self->m_worker_idle_or_terminated_event.wait(lock);
+ }
+ }
+ }
+
+ /*! The current thread of execution is blocked until the timestamp is met
+ * or the sum of all active and pending tasks is equal or less
+ * than a given threshold.
+ * \param timestamp The time when function returns at the latest.
+ * \param task_threshold The maximum number of tasks in pool and scheduler.
+ * \return true if the task sum is equal or less than the threshold, false otherwise.
+ */
+ bool wait(xtime const & timestamp, size_t const task_threshold = 0) const volatile
+ {
+ const pool_type* self = const_cast<const pool_type*>(this);
+ recursive_mutex::scoped_lock lock(self->m_monitor);
+
+ if(0 == task_threshold)
+ {
+ while(0 != self->m_active_worker_count || !self->m_scheduler.empty())
+ {
+ if(!self->m_worker_idle_or_terminated_event.timed_wait(lock, timestamp)) return false;
+ }
+ }
+ else
+ {
+ while(task_threshold < self->m_active_worker_count + self->m_scheduler.size())
+ {
+ if(!self->m_worker_idle_or_terminated_event.timed_wait(lock, timestamp)) return false;
+ }
+ }
+
+ return true;
+ }
+
+
+ private:
+
+
+ void terminate_all_workers(bool const wait) volatile
+ {
+ pool_type* self = const_cast<pool_type*>(this);
+ recursive_mutex::scoped_lock lock(self->m_monitor);
+
+ self->m_terminate_all_workers = true;
+
+ m_target_worker_count = 0;
+ self->m_task_or_terminate_workers_event.notify_all();
+
+ if(wait)
+ {
+ while(m_active_worker_count > 0)
+ {
+ self->m_worker_idle_or_terminated_event.wait(lock);
+ }
+
+ for(typename std::vector<shared_ptr<worker_type> >::iterator it = self->m_terminated_workers.begin();
+ it != self->m_terminated_workers.end();
+ ++it)
+ {
+ (*it)->join();
+ }
+ self->m_terminated_workers.clear();
+ }
+ }
+
+
+ /*! Changes the number of worker threads in the pool. The resizing
+ * is handled by the SizePolicy.
+ * \param threads The new number of worker threads.
+ * \return true, if pool will be resized and false if not.
+ */
+ bool resize(size_t const worker_count) volatile
+ {
+ locking_ptr<pool_type, recursive_mutex> lockedThis(*this, m_monitor);
+
+ if(!m_terminate_all_workers)
+ {
+ m_target_worker_count = worker_count;
+ }
+ else
+ {
+ return false;
+ }
+
+
+ if(m_worker_count <= m_target_worker_count)
+ { // increase worker count
+ while(m_worker_count < m_target_worker_count)
+ {
+ try
+ {
+ worker_thread<pool_type>::create_and_attach(lockedThis->shared_from_this());
+ m_worker_count++;
+ m_active_worker_count++;
+ }
+ catch(thread_resource_error&)
+ {
+ return false;
+ }
+ }
+ }
+ else
+ { // decrease worker count
+ lockedThis->m_task_or_terminate_workers_event.notify_all(); // TODO: Optimize number of notified workers
+ }
+
+ return true;
+ }
+
+
+ // worker died with unhandled exception
+ void worker_died_unexpectedly(shared_ptr<worker_type> worker) volatile
+ {
+ locking_ptr<pool_type, recursive_mutex> lockedThis(*this, m_monitor);
+
+ m_worker_count--;
+ m_active_worker_count--;
+ lockedThis->m_worker_idle_or_terminated_event.notify_all();
+
+ if(m_terminate_all_workers)
+ {
+ lockedThis->m_terminated_workers.push_back(worker);
+ }
+ else
+ {
+ lockedThis->m_size_policy->worker_died_unexpectedly(m_worker_count);
+ }
+ }
+
+ void worker_destructed(shared_ptr<worker_type> worker) volatile
+ {
+ locking_ptr<pool_type, recursive_mutex> lockedThis(*this, m_monitor);
+ m_worker_count--;
+ m_active_worker_count--;
+ lockedThis->m_worker_idle_or_terminated_event.notify_all();
+
+ if(m_terminate_all_workers)
+ {
+ lockedThis->m_terminated_workers.push_back(worker);
+ }
+ }
+
+
+ bool execute_task() volatile
+ {
+ function0<void> task;
+
+ { // fetch task
+ pool_type* lockedThis = const_cast<pool_type*>(this);
+ recursive_mutex::scoped_lock lock(lockedThis->m_monitor);
+
+ // decrease number of threads if necessary
+ if(m_worker_count > m_target_worker_count)
+ {
+ return false; // terminate worker
+ }
+
+
+ // wait for tasks
+ while(lockedThis->m_scheduler.empty())
+ {
+ // decrease number of workers if necessary
+ if(m_worker_count > m_target_worker_count)
+ {
+ return false; // terminate worker
+ }
+ else
+ {
+ m_active_worker_count--;
+ lockedThis->m_worker_idle_or_terminated_event.notify_all();
+ lockedThis->m_task_or_terminate_workers_event.wait(lock);
+ m_active_worker_count++;
+ }
+ }
+
+ task = lockedThis->m_scheduler.top();
+ lockedThis->m_scheduler.pop();
+ }
+
+ // call task function
+ if(task)
+ {
+ task();
+ }
+
+ //guard->disable();
+ return true;
+ }
+ };
+
+
+
+
+} } } // namespace boost::threadpool::detail
+
+#endif // THREADPOOL_POOL_CORE_HPP_INCLUDED
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/scope_guard.hpp b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/scope_guard.hpp
new file mode 100644
index 0000000000..68634654ba
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/scope_guard.hpp
@@ -0,0 +1,65 @@
+/*! \file
+* \brief TODO.
+*
+* TODO.
+*
+* Copyright (c) 2005-2007 Philipp Henkel
+*
+* Use, modification, and distribution are subject to the
+* Boost Software License, Version 1.0. (See accompanying file
+* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+
+#ifndef THREADPOOL_DETAIL_SCOPE_GUARD_HPP_INCLUDED
+#define THREADPOOL_DETAIL_SCOPE_GUARD_HPP_INCLUDED
+
+
+
+#include <boost/function.hpp>
+
+
+namespace boost { namespace threadpool { namespace detail
+{
+
+// TODO documentation
+class scope_guard
+: private boost::noncopyable
+{
+ function0<void> const m_function;
+ bool m_is_active;
+
+public:
+ scope_guard(function0<void> const & call_on_exit)
+ : m_function(call_on_exit)
+ , m_is_active(true)
+ {
+ }
+
+ ~scope_guard()
+ {
+ if(m_is_active && m_function)
+ {
+ m_function();
+ }
+ }
+
+ void disable()
+ {
+ m_is_active = false;
+ }
+};
+
+
+
+
+
+
+} } } // namespace boost::threadpool::detail
+
+#endif // THREADPOOL_DETAIL_SCOPE_GUARD_HPP_INCLUDED
+
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/worker_thread.hpp b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/worker_thread.hpp
new file mode 100644
index 0000000000..d33467a527
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/detail/worker_thread.hpp
@@ -0,0 +1,115 @@
+/*! \file
+* \brief Thread pool worker.
+*
+* The worker thread instance is attached to a pool
+* and executes tasks of this pool.
+*
+* Copyright (c) 2005-2007 Philipp Henkel
+*
+* Use, modification, and distribution are subject to the
+* Boost Software License, Version 1.0. (See accompanying file
+* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+#ifndef THREADPOOL_DETAIL_WORKER_THREAD_HPP_INCLUDED
+#define THREADPOOL_DETAIL_WORKER_THREAD_HPP_INCLUDED
+
+
+#include "scope_guard.hpp"
+
+#include <boost/smart_ptr.hpp>
+#include <boost/thread.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/bind.hpp>
+
+
+namespace boost { namespace threadpool { namespace detail
+{
+
+ /*! \brief Thread pool worker.
+ *
+ * A worker_thread represents a thread of execution. The worker is attached to a
+ * thread pool and processes tasks of that pool. The lifetime of the worker and its
+ * internal boost::thread is managed automatically.
+ *
+ * This class is a helper class and cannot be constructed or accessed directly.
+ *
+ * \see pool_core
+ */
+ template <typename Pool>
+ class worker_thread
+ : public enable_shared_from_this< worker_thread<Pool> >
+ , private noncopyable
+ {
+ public:
+ typedef Pool pool_type; //!< Indicates the pool's type.
+
+ private:
+ shared_ptr<pool_type> m_pool; //!< Pointer to the pool which created the worker.
+ shared_ptr<boost::thread> m_thread; //!< Pointer to the thread which executes the run loop.
+
+
+ /*! Constructs a new worker.
+ * \param pool Pointer to it's parent pool.
+ * \see function create_and_attach
+ */
+ worker_thread(shared_ptr<pool_type> const & pool)
+ : m_pool(pool)
+ {
+ assert(pool);
+ }
+
+
+ /*! Notifies that an exception occurred in the run loop.
+ */
+ void died_unexpectedly()
+ {
+ m_pool->worker_died_unexpectedly(this->shared_from_this());
+ }
+
+
+ public:
+ /*! Executes pool's tasks sequentially.
+ */
+ void run()
+ {
+ scope_guard notify_exception(bind(&worker_thread::died_unexpectedly, this));
+
+ while(m_pool->execute_task()) {}
+
+ notify_exception.disable();
+ m_pool->worker_destructed(this->shared_from_this());
+ }
+
+
+ /*! Joins the worker's thread.
+ */
+ void join()
+ {
+ m_thread->join();
+ }
+
+
+ /*! Constructs a new worker thread and attaches it to the pool.
+ * \param pool Pointer to the pool.
+ */
+ static void create_and_attach(shared_ptr<pool_type> const & pool)
+ {
+ shared_ptr<worker_thread> worker(new worker_thread(pool));
+ if(worker)
+ {
+ worker->m_thread.reset(new boost::thread(bind(&worker_thread::run, worker)));
+ }
+ }
+
+ };
+
+
+} } } // namespace boost::threadpool::detail
+
+#endif // THREADPOOL_DETAIL_WORKER_THREAD_HPP_INCLUDED
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/future.hpp b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/future.hpp
new file mode 100644
index 0000000000..f4a6e12244
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/future.hpp
@@ -0,0 +1,144 @@
+/*! \file
+* \brief TODO.
+*
+* TODO.
+*
+* Copyright (c) 2005-2007 Philipp Henkel
+*
+* Use, modification, and distribution are subject to the
+* Boost Software License, Version 1.0. (See accompanying file
+* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+#ifndef THREADPOOL_FUTURE_HPP_INCLUDED
+#define THREADPOOL_FUTURE_HPP_INCLUDED
+
+
+
+#include "./detail/future.hpp"
+#include <boost/utility/enable_if.hpp>
+
+//#include "pool.hpp"
+//#include <boost/utility.hpp>
+
+//#include <boost/thread/mutex.hpp>
+
+
+namespace boost { namespace threadpool
+{
+
+ /*! \brief Experimental. Do not use in production code. TODO.
+ *
+ * TODO Future
+ *
+ * \see TODO
+ *
+ */
+
+
+template<class Result>
+class future
+{
+private:
+ shared_ptr<detail::future_impl<Result> > m_impl;
+
+public:
+ typedef Result const & result_type; //!< Indicates the functor's result type.
+ typedef Result future_result_type; //!< Indicates the future's result type.
+
+
+public:
+
+ future()
+ : m_impl(new detail::future_impl<future_result_type>()) // TODO remove this
+ {
+ }
+
+ // only for internal usage
+ future(shared_ptr<detail::future_impl<Result> > const & impl)
+ : m_impl(impl)
+ {
+ }
+
+ bool ready() const
+ {
+ return m_impl->ready();
+ }
+
+ void wait() const
+ {
+ m_impl->wait();
+ }
+
+ bool timed_wait(boost::xtime const & timestamp) const
+ {
+ return m_impl->timed_wait(timestamp);
+ }
+
+ result_type operator()() // throw( thread::cancelation_exception, ... )
+ {
+ return (*m_impl)();
+ }
+
+ result_type get() // throw( thread::cancelation_exception, ... )
+ {
+ return (*m_impl)();
+ }
+
+ bool cancel()
+ {
+ return m_impl->cancel();
+ }
+
+ bool is_cancelled() const
+ {
+ return m_impl->is_cancelled();
+ }
+};
+
+
+
+
+
+template<class Pool, class Function>
+typename disable_if <
+ is_void< typename result_of< Function() >::type >,
+ future< typename result_of< Function() >::type >
+>::type
+schedule(Pool& pool, const Function& task)
+{
+ typedef typename result_of< Function() >::type future_result_type;
+
+ // create future impl and future
+ shared_ptr<detail::future_impl<future_result_type> > impl(new detail::future_impl<future_result_type>);
+ future <future_result_type> res(impl);
+
+ // schedule future impl
+ pool.schedule(detail::future_impl_task_func<detail::future_impl, Function>(task, impl));
+
+ // return future
+ return res;
+
+/*
+ TODO
+ if(pool->schedule(bind(&Future::run, future)))
+ {
+ return future;
+ }
+ else
+ {
+ // construct empty future
+ return error_future;
+ }
+ */
+}
+
+
+
+} } // namespace boost::threadpool
+
+#endif // THREADPOOL_FUTURE_HPP_INCLUDED
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/pool.hpp b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/pool.hpp
new file mode 100644
index 0000000000..a4b6676ea9
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/pool.hpp
@@ -0,0 +1,232 @@
+/*! \file
+* \brief Thread pool core.
+*
+* This file contains the threadpool's core class: pool<Task, SchedulingPolicy>.
+*
+* Thread pools are a mechanism for asynchronous and parallel processing
+* within the same process. The pool class provides a convenient way
+* for dispatching asynchronous tasks as functions objects. The scheduling
+* of these tasks can be easily controlled by using customized schedulers.
+*
+* Copyright (c) 2005-2007 Philipp Henkel
+*
+* Use, modification, and distribution are subject to the
+* Boost Software License, Version 1.0. (See accompanying file
+* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+
+#ifndef THREADPOOL_POOL_HPP_INCLUDED
+#define THREADPOOL_POOL_HPP_INCLUDED
+
+#include <boost/ref.hpp>
+
+#include "./detail/pool_core.hpp"
+
+#include "task_adaptors.hpp"
+
+#include "./detail/locking_ptr.hpp"
+
+#include "scheduling_policies.hpp"
+#include "size_policies.hpp"
+#include "shutdown_policies.hpp"
+
+
+
+/// The namespace threadpool contains a thread pool and related utility classes.
+namespace boost { namespace threadpool
+{
+
+
+
+ /*! \brief Thread pool.
+ *
+ * Thread pools are a mechanism for asynchronous and parallel processing
+ * within the same process. The pool class provides a convenient way
+ * for dispatching asynchronous tasks as functions objects. The scheduling
+ * of these tasks can be easily controlled by using customized schedulers.
+ * A task must not throw an exception.
+ *
+ * A pool is DefaultConstructible, CopyConstructible and Assignable.
+ * It has reference semantics; all copies of the same pool are equivalent and interchangeable.
+ * All operations on a pool except assignment are strongly thread safe or sequentially consistent;
+ * that is, the behavior of concurrent calls is as if the calls have been issued sequentially in an unspecified order.
+ *
+ * \param Task A function object which implements the operator 'void operator() (void) const'. The operator () is called by the pool to execute the task. Exceptions are ignored.
+ * \param SchedulingPolicy A task container which determines how tasks are scheduled. It is guaranteed that this container is accessed only by one thread at a time. The scheduler shall not throw exceptions.
+ *
+ * \remarks The pool class is thread-safe.
+ *
+ * \see Tasks: task_func, prio_task_func
+ * \see Scheduling policies: fifo_scheduler, lifo_scheduler, prio_scheduler
+ */
+ template <
+ typename Task = task_func,
+ template <typename> class SchedulingPolicy = fifo_scheduler,
+ template <typename> class SizePolicy = static_size,
+ template <typename> class SizePolicyController = resize_controller,
+ template <typename> class ShutdownPolicy = wait_for_all_tasks
+ >
+ class thread_pool
+ {
+ typedef detail::pool_core<Task,
+ SchedulingPolicy,
+ SizePolicy,
+ SizePolicyController,
+ ShutdownPolicy> pool_core_type;
+ shared_ptr<pool_core_type> m_core; // pimpl idiom
+ shared_ptr<void> m_shutdown_controller; // If the last pool holding a pointer to the core is deleted the controller shuts the pool down.
+
+ public: // Type definitions
+ typedef Task task_type; //!< Indicates the task's type.
+ typedef SchedulingPolicy<task_type> scheduler_type; //!< Indicates the scheduler's type.
+ /* typedef thread_pool<Task,
+ SchedulingPolicy,
+ SizePolicy,
+ ShutdownPolicy > pool_type; //!< Indicates the thread pool's type.
+ */
+ typedef SizePolicy<pool_core_type> size_policy_type;
+ typedef SizePolicyController<pool_core_type> size_controller_type;
+
+
+ public:
+ /*! Constructor.
+ * \param initial_threads The pool is immediately resized to set the specified number of threads. The pool's actual number threads depends on the SizePolicy.
+ */
+ thread_pool(size_t initial_threads = 0)
+ : m_core(new pool_core_type)
+ , m_shutdown_controller(static_cast<void*>(0), bind(&pool_core_type::shutdown, m_core))
+ {
+ size_policy_type::init(*m_core, initial_threads);
+ }
+
+
+ /*! Gets the size controller which manages the number of threads in the pool.
+ * \return The size controller.
+ * \see SizePolicy
+ */
+ size_controller_type size_controller()
+ {
+ return m_core->size_controller();
+ }
+
+
+ /*! Gets the number of threads in the pool.
+ * \return The number of threads.
+ */
+ size_t size() const
+ {
+ return m_core->size();
+ }
+
+
+ /*! Schedules a task for asynchronous execution. The task will be executed once only.
+ * \param task The task function object. It should not throw execeptions.
+ * \return true, if the task could be scheduled and false otherwise.
+ */
+ bool schedule(task_type const & task)
+ {
+ return m_core->schedule(task);
+ }
+
+
+ /*! Returns the number of tasks which are currently executed.
+ * \return The number of active tasks.
+ */
+ size_t active() const
+ {
+ return m_core->active();
+ }
+
+
+ /*! Returns the number of tasks which are ready for execution.
+ * \return The number of pending tasks.
+ */
+ size_t pending() const
+ {
+ return m_core->pending();
+ }
+
+
+ /*! Removes all pending tasks from the pool's scheduler.
+ */
+ void clear()
+ {
+ m_core->clear();
+ }
+
+
+ /*! Indicates that there are no tasks pending.
+ * \return true if there are no tasks ready for execution.
+ * \remarks This function is more efficient that the check 'pending() == 0'.
+ */
+ bool empty() const
+ {
+ return m_core->empty();
+ }
+
+
+ /*! The current thread of execution is blocked until the sum of all active
+ * and pending tasks is equal or less than a given threshold.
+ * \param task_threshold The maximum number of tasks in pool and scheduler.
+ */
+ void wait(size_t task_threshold = 0) const
+ {
+ m_core->wait(task_threshold);
+ }
+
+
+ /*! The current thread of execution is blocked until the timestamp is met
+ * or the sum of all active and pending tasks is equal or less
+ * than a given threshold.
+ * \param timestamp The time when function returns at the latest.
+ * \param task_threshold The maximum number of tasks in pool and scheduler.
+ * \return true if the task sum is equal or less than the threshold, false otherwise.
+ */
+ bool wait(xtime const & timestamp, size_t task_threshold = 0) const
+ {
+ return m_core->wait(timestamp, task_threshold);
+ }
+ };
+
+
+
+ /*! \brief Fifo pool.
+ *
+ * The pool's tasks are fifo scheduled task_func functors.
+ *
+ */
+ typedef thread_pool<task_func, fifo_scheduler, static_size, resize_controller, wait_for_all_tasks> fifo_pool;
+
+
+ /*! \brief Lifo pool.
+ *
+ * The pool's tasks are lifo scheduled task_func functors.
+ *
+ */
+ typedef thread_pool<task_func, lifo_scheduler, static_size, resize_controller, wait_for_all_tasks> lifo_pool;
+
+
+ /*! \brief Pool for prioritized task.
+ *
+ * The pool's tasks are prioritized prio_task_func functors.
+ *
+ */
+ typedef thread_pool<prio_task_func, prio_scheduler, static_size, resize_controller, wait_for_all_tasks> prio_pool;
+
+
+ /*! \brief A standard pool.
+ *
+ * The pool's tasks are fifo scheduled task_func functors.
+ *
+ */
+ typedef fifo_pool pool;
+
+
+
+} } // namespace boost::threadpool
+
+#endif // THREADPOOL_POOL_HPP_INCLUDED
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/pool_adaptors.hpp b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/pool_adaptors.hpp
new file mode 100644
index 0000000000..6cde152d2a
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/pool_adaptors.hpp
@@ -0,0 +1,70 @@
+/*! \file
+* \brief Pool adaptors.
+*
+* This file contains an easy-to-use adaptor similar to a smart
+* pointer for the pool class.
+*
+* Copyright (c) 2005-2007 Philipp Henkel
+*
+* Use, modification, and distribution are subject to the
+* Boost Software License, Version 1.0. (See accompanying file
+* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+
+#ifndef THREADPOOL_POOL_ADAPTORS_HPP_INCLUDED
+#define THREADPOOL_POOL_ADAPTORS_HPP_INCLUDED
+
+#include <boost/smart_ptr.hpp>
+
+
+namespace boost { namespace threadpool
+{
+
+
+// TODO convenience scheduling function
+ /*! Schedules a Runnable for asynchronous execution. A Runnable is an arbitrary class with a run()
+ * member function. This a convenience shorthand for pool->schedule(bind(&Runnable::run, task_object)).
+ * \param
+ * \param obj The Runnable object. The member function run() will be exectued and should not throw execeptions.
+ * \return true, if the task could be scheduled and false otherwise.
+ */
+ template<typename Pool, typename Runnable>
+ bool schedule(Pool& pool, shared_ptr<Runnable> const & obj)
+ {
+ return pool->schedule(bind(&Runnable::run, obj));
+ }
+
+ /*! Schedules a task for asynchronous execution. The task will be executed once only.
+ * \param task The task function object.
+ */
+ template<typename Pool>
+ typename enable_if <
+ is_void< typename result_of< typename Pool::task_type() >::type >,
+ bool
+ >::type
+ schedule(Pool& pool, typename Pool::task_type const & task)
+ {
+ return pool.schedule(task);
+ }
+
+
+ template<typename Pool>
+ typename enable_if <
+ is_void< typename result_of< typename Pool::task_type() >::type >,
+ bool
+ >::type
+ schedule(shared_ptr<Pool> const pool, typename Pool::task_type const & task)
+ {
+ return pool->schedule(task);
+ }
+
+
+} } // namespace boost::threadpool
+
+#endif // THREADPOOL_POOL_ADAPTORS_HPP_INCLUDED
+
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/scheduling_policies.hpp b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/scheduling_policies.hpp
new file mode 100644
index 0000000000..2d6c7c1bae
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/scheduling_policies.hpp
@@ -0,0 +1,262 @@
+/*! \file
+* \brief Task scheduling policies.
+*
+* This file contains some fundamental scheduling policies for the pool class.
+* A scheduling policy is realized by a task container which controls the access to
+* the tasks. Fundamentally the container determines the order the tasks are processed
+* by the thread pool.
+* The task containers need not to be thread-safe because they are used by the pool
+* in thread-safe way.
+*
+* Copyright (c) 2005-2007 Philipp Henkel
+*
+* Use, modification, and distribution are subject to the
+* Boost Software License, Version 1.0. (See accompanying file
+* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+
+#ifndef THREADPOOL_SCHEDULING_POLICIES_HPP_INCLUDED
+#define THREADPOOL_SCHEDULING_POLICIES_HPP_INCLUDED
+
+
+#include <queue>
+#include <deque>
+
+#include "task_adaptors.hpp"
+
+namespace boost { namespace threadpool
+{
+
+ /*! \brief SchedulingPolicy which implements FIFO ordering.
+ *
+ * This container implements a FIFO scheduling policy.
+ * The first task to be added to the scheduler will be the first to be removed.
+ * The processing proceeds sequentially in the same order.
+ * FIFO stands for "first in, first out".
+ *
+ * \param Task A function object which implements the operator()(void).
+ *
+ */
+ template <typename Task = task_func>
+ class fifo_scheduler
+ {
+ public:
+ typedef Task task_type; //!< Indicates the scheduler's task type.
+
+ protected:
+ std::deque<task_type> m_container; //!< Internal task container.
+
+
+ public:
+ /*! Adds a new task to the scheduler.
+ * \param task The task object.
+ * \return true, if the task could be scheduled and false otherwise.
+ */
+ bool push(task_type const & task)
+ {
+ m_container.push_back(task);
+ return true;
+ }
+
+ /*! Removes the task which should be executed next.
+ */
+ void pop()
+ {
+ m_container.pop_front();
+ }
+
+ /*! Gets the task which should be executed next.
+ * \return The task object to be executed.
+ */
+ task_type const & top() const
+ {
+ return m_container.front();
+ }
+
+ /*! Gets the current number of tasks in the scheduler.
+ * \return The number of tasks.
+ * \remarks Prefer empty() to size() == 0 to check if the scheduler is empty.
+ */
+ size_t size() const
+ {
+ return m_container.size();
+ }
+
+ /*! Checks if the scheduler is empty.
+ * \return true if the scheduler contains no tasks, false otherwise.
+ * \remarks Is more efficient than size() == 0.
+ */
+ bool empty() const
+ {
+ return m_container.empty();
+ }
+
+ /*! Removes all tasks from the scheduler.
+ */
+ void clear()
+ {
+ m_container.clear();
+ }
+ };
+
+
+
+ /*! \brief SchedulingPolicy which implements LIFO ordering.
+ *
+ * This container implements a LIFO scheduling policy.
+ * The last task to be added to the scheduler will be the first to be removed.
+ * LIFO stands for "last in, first out".
+ *
+ * \param Task A function object which implements the operator()(void).
+ *
+ */
+ template <typename Task = task_func>
+ class lifo_scheduler
+ {
+ public:
+ typedef Task task_type; //!< Indicates the scheduler's task type.
+
+ protected:
+ std::deque<task_type> m_container; //!< Internal task container.
+
+ public:
+ /*! Adds a new task to the scheduler.
+ * \param task The task object.
+ * \return true, if the task could be scheduled and false otherwise.
+ */
+ bool push(task_type const & task)
+ {
+ m_container.push_front(task);
+ return true;
+ }
+
+ /*! Removes the task which should be executed next.
+ */
+ void pop()
+ {
+ m_container.pop_front();
+ }
+
+ /*! Gets the task which should be executed next.
+ * \return The task object to be executed.
+ */
+ task_type const & top() const
+ {
+ return m_container.front();
+ }
+
+ /*! Gets the current number of tasks in the scheduler.
+ * \return The number of tasks.
+ * \remarks Prefer empty() to size() == 0 to check if the scheduler is empty.
+ */
+ size_t size() const
+ {
+ return m_container.size();
+ }
+
+ /*! Checks if the scheduler is empty.
+ * \return true if the scheduler contains no tasks, false otherwise.
+ * \remarks Is more efficient than size() == 0.
+ */
+ bool empty() const
+ {
+ return m_container.empty();
+ }
+
+ /*! Removes all tasks from the scheduler.
+ */
+ void clear()
+ {
+ m_container.clear();
+ }
+
+ };
+
+
+
+ /*! \brief SchedulingPolicy which implements prioritized ordering.
+ *
+ * This container implements a scheduling policy based on task priorities.
+ * The task with highest priority will be the first to be removed.
+ * It must be possible to compare two tasks using operator<.
+ *
+ * \param Task A function object which implements the operator() and operator<. operator< must be a partial ordering.
+ *
+ * \see prio_thread_func
+ *
+ */
+ template <typename Task = prio_task_func>
+ class prio_scheduler
+ {
+ public:
+ typedef Task task_type; //!< Indicates the scheduler's task type.
+
+ protected:
+ std::priority_queue<task_type> m_container; //!< Internal task container.
+
+
+ public:
+ /*! Adds a new task to the scheduler.
+ * \param task The task object.
+ * \return true, if the task could be scheduled and false otherwise.
+ */
+ bool push(task_type const & task)
+ {
+ m_container.push(task);
+ return true;
+ }
+
+ /*! Removes the task which should be executed next.
+ */
+ void pop()
+ {
+ m_container.pop();
+ }
+
+ /*! Gets the task which should be executed next.
+ * \return The task object to be executed.
+ */
+ task_type const & top() const
+ {
+ return m_container.top();
+ }
+
+ /*! Gets the current number of tasks in the scheduler.
+ * \return The number of tasks.
+ * \remarks Prefer empty() to size() == 0 to check if the scheduler is empty.
+ */
+ size_t size() const
+ {
+ return m_container.size();
+ }
+
+ /*! Checks if the scheduler is empty.
+ * \return true if the scheduler contains no tasks, false otherwise.
+ * \remarks Is more efficient than size() == 0.
+ */
+ bool empty() const
+ {
+ return m_container.empty();
+ }
+
+ /*! Removes all tasks from the scheduler.
+ */
+ void clear()
+ {
+ while(!m_container.empty())
+ {
+ m_container.pop();
+ }
+ }
+ };
+
+
+} } // namespace boost::threadpool
+
+
+#endif // THREADPOOL_SCHEDULING_POLICIES_HPP_INCLUDED
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/shutdown_policies.hpp b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/shutdown_policies.hpp
new file mode 100644
index 0000000000..047a6eb516
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/shutdown_policies.hpp
@@ -0,0 +1,83 @@
+/*! \file
+* \brief Shutdown policies.
+*
+* This file contains shutdown policies for thread_pool.
+* A shutdown policy controls the pool's behavior from the time
+* when the pool is not referenced any longer.
+*
+* Copyright (c) 2005-2007 Philipp Henkel
+*
+* Use, modification, and distribution are subject to the
+* Boost Software License, Version 1.0. (See accompanying file
+* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+
+#ifndef THREADPOOL_SHUTDOWN_POLICIES_HPP_INCLUDED
+#define THREADPOOL_SHUTDOWN_POLICIES_HPP_INCLUDED
+
+
+
+/// The namespace threadpool contains a thread pool and related utility classes.
+namespace boost { namespace threadpool
+{
+
+
+/*! \brief ShutdownPolicy which waits for the completion of all tasks
+ * and the worker termination afterwards.
+ *
+ * \param Pool The pool's core type.
+ */
+ template<typename Pool>
+ class wait_for_all_tasks
+ {
+ public:
+ static void shutdown(Pool& pool)
+ {
+ pool.wait();
+ pool.terminate_all_workers(true);
+ }
+ };
+
+
+ /*! \brief ShutdownPolicy which waits for the completion of all active tasks
+ * and the worker termination afterwards.
+ *
+ * \param Pool The pool's core type.
+ */
+ template<typename Pool>
+ class wait_for_active_tasks
+ {
+ public:
+ static void shutdown(Pool& pool)
+ {
+ pool.clear();
+ pool.wait();
+ pool.terminate_all_workers(true);
+ }
+ };
+
+
+ /*! \brief ShutdownPolicy which does not wait for any tasks or worker termination.
+ *
+ * This policy does not wait for any tasks. Nevertheless all active tasks will be processed completely.
+ *
+ * \param Pool The pool's core type.
+ */
+ template<typename Pool>
+ class immediately
+ {
+ public:
+ static void shutdown(Pool& pool)
+ {
+ pool.clear();
+ pool.terminate_all_workers(false);
+ }
+ };
+
+} } // namespace boost::threadpool
+
+#endif // THREADPOOL_SHUTDOWN_POLICIES_HPP_INCLUDED
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/size_policies.hpp b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/size_policies.hpp
new file mode 100644
index 0000000000..e3c08038db
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/size_policies.hpp
@@ -0,0 +1,99 @@
+/*! \file
+* \brief Size policies.
+*
+* This file contains size policies for thread_pool. A size
+* policy controls the number of worker threads in the pool.
+*
+* Copyright (c) 2005-2007 Philipp Henkel
+*
+* Use, modification, and distribution are subject to the
+* Boost Software License, Version 1.0. (See accompanying file
+* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+
+#ifndef THREADPOOL_SIZE_POLICIES_HPP_INCLUDED
+#define THREADPOOL_SIZE_POLICIES_HPP_INCLUDED
+
+
+
+/// The namespace threadpool contains a thread pool and related utility classes.
+namespace boost { namespace threadpool
+{
+
+ /*! \brief SizePolicyController which provides no functionality.
+ *
+ * \param Pool The pool's core type.
+ */
+ template<typename Pool>
+ struct empty_controller
+ {
+ empty_controller(typename Pool::size_policy_type&, shared_ptr<Pool>) {}
+ };
+
+
+ /*! \brief SizePolicyController which allows resizing.
+ *
+ * \param Pool The pool's core type.
+ */
+ template< typename Pool >
+ class resize_controller
+ {
+ typedef typename Pool::size_policy_type size_policy_type;
+ reference_wrapper<size_policy_type> m_policy;
+ shared_ptr<Pool> m_pool; //!< to make sure that the pool is alive (the policy pointer is valid) as long as the controller exists
+
+ public:
+ resize_controller(size_policy_type& policy, shared_ptr<Pool> pool)
+ : m_policy(policy)
+ , m_pool(pool)
+ {
+ }
+
+ bool resize(size_t worker_count)
+ {
+ return m_policy.get().resize(worker_count);
+ }
+ };
+
+
+ /*! \brief SizePolicy which preserves the thread count.
+ *
+ * \param Pool The pool's core type.
+ */
+ template<typename Pool>
+ class static_size
+ {
+ reference_wrapper<Pool volatile> m_pool;
+
+ public:
+ static void init(Pool& pool, size_t const worker_count)
+ {
+ pool.resize(worker_count);
+ }
+
+ static_size(Pool volatile & pool)
+ : m_pool(pool)
+ {}
+
+ bool resize(size_t const worker_count)
+ {
+ return m_pool.get().resize(worker_count);
+ }
+
+ void worker_died_unexpectedly(size_t const new_worker_count)
+ {
+ m_pool.get().resize(new_worker_count + 1);
+ }
+
+ // TODO this functions are not called yet
+ void task_scheduled() {}
+ void task_finished() {}
+ };
+
+} } // namespace boost::threadpool
+
+#endif // THREADPOOL_SIZE_POLICIES_HPP_INCLUDED
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/task_adaptors.hpp b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/task_adaptors.hpp
new file mode 100644
index 0000000000..6b874e3358
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/boost/threadpool/task_adaptors.hpp
@@ -0,0 +1,168 @@
+/*! \file
+* \brief Task adaptors.
+*
+* This file contains adaptors for task function objects.
+*
+* Copyright (c) 2005-2007 Philipp Henkel
+*
+* Use, modification, and distribution are subject to the
+* Boost Software License, Version 1.0. (See accompanying file
+* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+
+#ifndef THREADPOOL_TASK_ADAPTERS_HPP_INCLUDED
+#define THREADPOOL_TASK_ADAPTERS_HPP_INCLUDED
+
+
+#include <boost/smart_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/thread.hpp>
+
+
+namespace boost { namespace threadpool
+{
+
+ /*! \brief Standard task function object.
+ *
+ * This function object wraps a nullary function which returns void.
+ * The wrapped function is invoked by calling the operator ().
+ *
+ * \see boost function library
+ *
+ */
+ typedef function0<void> task_func;
+
+
+
+
+ /*! \brief Prioritized task function object.
+ *
+ * This function object wraps a task_func object and binds a priority to it.
+ * prio_task_funcs can be compared using the operator < which realises a partial ordering.
+ * The wrapped task function is invoked by calling the operator ().
+ *
+ * \see prio_scheduler
+ *
+ */
+ class prio_task_func
+ {
+ private:
+ unsigned int m_priority; //!< The priority of the task's function.
+ task_func m_function; //!< The task's function.
+
+ public:
+ typedef void result_type; //!< Indicates the functor's result type.
+
+ public:
+ /*! Constructor.
+ * \param priority The priority of the task.
+ * \param function The task's function object.
+ */
+ prio_task_func(unsigned int const priority, task_func const & function)
+ : m_priority(priority)
+ , m_function(function)
+ {
+ }
+
+ /*! Executes the task function.
+ */
+ void operator() (void) const
+ {
+ if(m_function)
+ {
+ m_function();
+ }
+ }
+
+ /*! Comparison operator which realises a partial ordering based on priorities.
+ * \param rhs The object to compare with.
+ * \return true if the priority of *this is less than right hand side's priority, false otherwise.
+ */
+ bool operator< (const prio_task_func& rhs) const
+ {
+ return m_priority < rhs.m_priority;
+ }
+
+ }; // prio_task_func
+
+
+
+
+
+
+
+
+ /*! \brief Looped task function object.
+ *
+ * This function object wraps a boolean thread function object.
+ * The wrapped task function is invoked by calling the operator () and it is executed in regular
+ * time intervals until false is returned. The interval length may be zero.
+ * Please note that a pool's thread is engaged as long as the task is looped.
+ *
+ */
+ class looped_task_func
+ {
+ private:
+ function0<bool> m_function; //!< The task's function.
+ unsigned int m_break_s; //!< Duration of breaks in seconds.
+ unsigned int m_break_ns; //!< Duration of breaks in nano seconds.
+
+ public:
+ typedef void result_type; //!< Indicates the functor's result type.
+
+ public:
+ /*! Constructor.
+ * \param function The task's function object which is looped until false is returned.
+ * \param interval The minimum break time in milli seconds before the first execution of the task function and between the following ones.
+ */
+ looped_task_func(function0<bool> const & function, unsigned int const interval = 0)
+ : m_function(function)
+ {
+ m_break_s = interval / 1000;
+ m_break_ns = (interval - m_break_s * 1000) * 1000 * 1000;
+ }
+
+ /*! Executes the task function.
+ */
+ void operator() (void) const
+ {
+ if(m_function)
+ {
+ if(m_break_s > 0 || m_break_ns > 0)
+ { // Sleep some time before first execution
+ xtime xt;
+ xtime_get(&xt, TIME_UTC);
+ xt.nsec += m_break_ns;
+ xt.sec += m_break_s;
+ thread::sleep(xt);
+ }
+
+ while(m_function())
+ {
+ if(m_break_s > 0 || m_break_ns > 0)
+ {
+ xtime xt;
+ xtime_get(&xt, TIME_UTC);
+ xt.nsec += m_break_ns;
+ xt.sec += m_break_s;
+ thread::sleep(xt);
+ }
+ else
+ {
+ thread::yield(); // Be fair to other threads
+ }
+ }
+ }
+ }
+
+ }; // looped_task_func
+
+
+} } // namespace boost::threadpool
+
+#endif // THREADPOOL_TASK_ADAPTERS_HPP_INCLUDED
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/Makefile b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/Makefile
new file mode 100644
index 0000000000..578ff7e0ba
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/Makefile
@@ -0,0 +1,36 @@
+DOXYGEN=doxygen
+
+doc: clean copy_footer generate_doc
+
+copy_footer:
+ cp footer/*.htm .
+
+copy_footer_sf:
+ cp footer_sf/*.htm .
+
+generate_doc:
+ $(DOXYGEN) overview.dox
+ $(DOXYGEN) reference.dox
+ $(DOXYGEN) tutorial.dox
+ $(DOXYGEN) examples.dox
+ $(DOXYGEN) design.dox
+
+clean:
+ rm -rf ../../../doc
+ rm -rf ../../../threadpool-$(RELEASE_VERSION)-doc
+ rm -rf ../../../threadpool-$(RELEASE_VERSION)-doc.zip
+
+release_doc: clean doc
+ cd ../../..; mv doc threadpool-$(RELEASE_VERSION)-doc
+ cd ../../..; zip -r9 threadpool-$(RELEASE_VERSION)-doc.zip threadpool-$(RELEASE_VERSION)-doc
+ cd ../../..; mv threadpool-$(RELEASE_VERSION)-doc doc
+
+doc_sf: clean copy_footer_sf generate_doc
+
+deploy_sf: doc_sf
+ scp -vr ../../../doc/* $(RELEASE_MANAGER)@shell.sourceforge.net:/home/groups/t/th/threadpool/htdocs
+
+
+
+
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design.dox b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design.dox
new file mode 100644
index 0000000000..06b287c7e4
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design.dox
@@ -0,0 +1,145 @@
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = "threadpool"
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY = ../../../doc/design
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = NO
+REPEAT_BRIEF = NO
+ALWAYS_DETAILED_SEC = YES
+INLINE_INHERITED_MEMB = YES
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = /../../include/
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = YES
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = YES
+DETAILS_AT_TOP = YES
+INHERIT_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 2
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = NO
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = YES
+HIDE_UNDOC_CLASSES = YES
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = NO
+INLINE_INFO = NO
+SORT_MEMBER_DOCS = NO
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = NO
+GENERATE_TESTLIST = NO
+GENERATE_BUGLIST = NO
+GENERATE_DEPRECATEDLIST= NO
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = NO
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = design.txt
+FILE_PATTERNS =
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = YES
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 1
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = .
+HTML_FILE_EXTENSION = .html
+HTML_HEADER = design_header.htm
+HTML_FOOTER = common_footer.htm
+HTML_STYLESHEET = threadpool.css
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = YES
+ENUM_VALUES_PER_LINE = 1
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design.txt b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design.txt
new file mode 100644
index 0000000000..05cf85e8ac
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design.txt
@@ -0,0 +1,35 @@
+/*! \page intro TODO5
+
+
+A thread pool manages a homogeneous pool of worker threads. In general worker threads are created once and are used to
+process a sequence of tasks. The re-use of threads reduces the thread creation and teardown overhead. The resource
+consumption is limited as the number of threads can be restricted. This leads to an improved system stability.
+
+Thread-per-task
+
+TODO5
+
+light-weight, no administration/management thread, synchronized scheduler, e.g. queue
+
+
+ */
+
+
+/*! \page pattern Thread Pool Pattern
+
+
+In the thread pool pattern in programming, a number of N threads are created to perform a number of M tasks, usually organized in a queue. Typically, N << M. As soon as a thread completes its task, it will request the next task from the queue until all tasks have been completed. The thread can then terminate, or sleep until there are new tasks available.
+
+The number of threads used (N) is a parameter that can be tuned to provide the best performance.
+
+The advantage of using a Thread Pool over creating a new thread for each task, is that thread creation and destruction overhead is negated, which may result in better performance and better system stability.
+
+<BR>
+<B>From <A HREF="http://en.wikipedia.org/wiki/Thread_pool_pattern"> Wikipedia </A>, the free encyclopedia.</B>
+
+
+
+ */
+
+
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design_header.htm b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design_header.htm
new file mode 100644
index 0000000000..006ce09490
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/design_header.htm
@@ -0,0 +1,38 @@
+<HTML>
+ <HEAD>
+ <TITLE>threadpool Documentation</TITLE>
+ <LINK HREF="threadpool.css" REL="stylesheet" TYPE="text/css">
+ </HEAD>
+ <BODY BGCOLOR="#FFFFFF">
+
+ <DIV CLASS="qindex">
+ <TABLE BORDER="0" WIDTH="100%">
+ <TR>
+
+ <TD ALIGN="LEFT">
+ <B>$projectname</B>
+ </TD>
+ <TD ALIGN="RIGHT">
+ <A CLASS="qindex" HREF="../index.html">Overview</A> |
+ <A CLASS="qindex" HREF="../reference/annotated.html">Reference</A> |
+ <A CLASS="qindex" HREF="../tutorial/intro.html">Tutorial</A> |
+ <A CLASS="qindex" HREF="../examples/intro.html">Examples</A> |
+ <A CLASS="qindex" HREF="../design/intro.html">Design</A>
+ </TD>
+
+ </TR>
+ </TABLE>
+ </DIV>
+ <DIV CLASS="qindex">
+ <TABLE BORDER="0" WIDTH="100%">
+ <TR>
+ <TD ALIGN="LEFT">
+ <B>Design</B>
+ </TD>
+ <TD ALIGN="RIGHT">
+ <A CLASS="qindex" HREF="intro.html">TODO5</A> |
+ <A CLASS="qindex" HREF="pattern.html">Thread Pool Pattern</A>
+ </TD>
+ </TR>
+ </TABLE>
+ </DIV>
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples.dox b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples.dox
new file mode 100644
index 0000000000..128a4089ad
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples.dox
@@ -0,0 +1,145 @@
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = "threadpool"
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY = ../../../doc/examples
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = NO
+REPEAT_BRIEF = NO
+ALWAYS_DETAILED_SEC = YES
+INLINE_INHERITED_MEMB = YES
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = /../../include
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = YES
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = YES
+DETAILS_AT_TOP = YES
+INHERIT_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 2
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = NO
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = YES
+HIDE_UNDOC_CLASSES = YES
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = NO
+INLINE_INFO = NO
+SORT_MEMBER_DOCS = NO
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = NO
+GENERATE_TESTLIST = NO
+GENERATE_BUGLIST = NO
+GENERATE_DEPRECATEDLIST= NO
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = NO
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = examples.txt
+FILE_PATTERNS =
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = YES
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 1
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = .
+HTML_FILE_EXTENSION = .html
+HTML_HEADER = examples_header.htm
+HTML_FOOTER = common_footer.htm
+HTML_STYLESHEET = threadpool.css
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = YES
+ENUM_VALUES_PER_LINE = 1
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples.txt b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples.txt
new file mode 100644
index 0000000000..fbb29f4d33
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples.txt
@@ -0,0 +1,14 @@
+
+/*! \page intro TODO3
+
+See src/examples/mergesort/mergesort.cpp
+<BR>
+
+ */
+
+
+/*! \page pattern TODO4
+TODO4
+
+ */
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples_header.htm b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples_header.htm
new file mode 100644
index 0000000000..d35512cf52
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/examples_header.htm
@@ -0,0 +1,38 @@
+<HTML>
+ <HEAD>
+ <TITLE>threadpool Documentation</TITLE>
+ <LINK HREF="threadpool.css" REL="stylesheet" TYPE="text/css">
+ </HEAD>
+ <BODY BGCOLOR="#FFFFFF">
+
+ <DIV CLASS="qindex">
+ <TABLE BORDER="0" WIDTH="100%">
+ <TR>
+
+ <TD ALIGN="LEFT">
+ <B>$projectname</B>
+ </TD>
+ <TD ALIGN="RIGHT">
+ <A CLASS="qindex" HREF="../index.html">Overview</A> |
+ <A CLASS="qindex" HREF="../reference/annotated.html">Reference</A> |
+ <A CLASS="qindex" HREF="../tutorial/intro.html">Tutorial</A> |
+ <A CLASS="qindex" HREF="../examples/intro.html">Examples</A> |
+ <A CLASS="qindex" HREF="../design/intro.html">Design</A>
+ </TD>
+
+ </TR>
+ </TABLE>
+ </DIV>
+ <DIV CLASS="qindex">
+ <TABLE BORDER="0" WIDTH="100%">
+ <TR>
+ <TD ALIGN="LEFT">
+ <B>Examples</B>
+ </TD>
+ <TD ALIGN="RIGHT">
+ <A CLASS="qindex" HREF="intro.html">TODO3</A> |
+ <A CLASS="qindex" HREF="pattern.html">TODO4</A>
+ </TD>
+ </TR>
+ </TABLE>
+ </DIV>
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer/common_footer.htm b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer/common_footer.htm
new file mode 100644
index 0000000000..1debd97adf
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer/common_footer.htm
@@ -0,0 +1,17 @@
+ <BR>
+ <DIV CLASS="qindex">
+ <TABLE BORDER="0" WIDTH="100%">
+ <TR>
+ <TD CLASS="tiny" ALIGN="LEFT">Copyright &copy 2005-2008 Philipp Henkel</TD>
+ <TD ALIGN="RIGHT">
+ <A CLASS="qindex" HREF="../index.html">Overview</A> |
+ <A CLASS="qindex" HREF="../reference/annotated.html">Reference</A> |
+ <A CLASS="qindex" HREF="../tutorial/intro.html">Tutorial</A> |
+ <A CLASS="qindex" HREF="../examples/intro.html">Examples</A> |
+ <A CLASS="qindex" HREF="../design/intro.html">Design</A>
+ </TD>
+ </TR>
+ </TABLE>
+ </DIV>
+ </BODY>
+</HTML>
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer/overview_footer.htm b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer/overview_footer.htm
new file mode 100644
index 0000000000..75ef22b181
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer/overview_footer.htm
@@ -0,0 +1,17 @@
+ <BR>
+ <DIV CLASS="qindex">
+ <TABLE BORDER="0" WIDTH="100%">
+ <TR>
+ <TD CLASS="tiny" ALIGN="LEFT">Copyright &copy 2005-2008 Philipp Henkel</TD>
+ <TD ALIGN="RIGHT">
+ <A CLASS="qindex" HREF="index.html">Overview</A> |
+ <A CLASS="qindex" HREF="reference/annotated.html">Reference</A> |
+ <A CLASS="qindex" HREF="tutorial/intro.html">Tutorial</A> |
+ <A CLASS="qindex" HREF="examples/intro.html">Examples</A> |
+ <A CLASS="qindex" HREF="design/intro.html">Design</A>
+ </TD>
+ </TR>
+ </TABLE>
+ </DIV>
+ </BODY>
+</HTML>
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer_sf/common_footer.htm b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer_sf/common_footer.htm
new file mode 100644
index 0000000000..7c177c9f33
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer_sf/common_footer.htm
@@ -0,0 +1,30 @@
+ <BR>
+ <DIV CLASS="qindex">
+ <TABLE BORDER="0" WIDTH="100%">
+ <TR>
+ <TD CLASS="tiny" ALIGN="LEFT">Copyright &copy 2005-2008 Philipp Henkel</TD>
+ <TD ALIGN="RIGHT">
+ <A CLASS="qindex" HREF="../index.html">Overview</A> |
+ <A CLASS="qindex" HREF="../reference/annotated.html">Reference</A> |
+ <A CLASS="qindex" HREF="../tutorial/intro.html">Tutorial</A> |
+ <A CLASS="qindex" HREF="../examples/intro.html">Examples</A> |
+ <A CLASS="qindex" HREF="../design/intro.html">Design</A>
+ </TD>
+ </TR>
+ </TABLE>
+ </DIV>
+
+ <P align="right" valign="top">
+ Hosted by
+ <A HREF="http://sourceforge.net">
+ <IMG src="http://sflogo.sourceforge.net/sflogo.php?group_id=158064&type=2"
+ width="125"
+ height="37"
+ border="0"
+ align="top"
+ alt="SourceForge.net Logo"/>
+ </A>
+ </P>
+
+ </BODY>
+</HTML>
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer_sf/overview_footer.htm b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer_sf/overview_footer.htm
new file mode 100644
index 0000000000..4a6f80c53b
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/footer_sf/overview_footer.htm
@@ -0,0 +1,29 @@
+ <BR>
+ <DIV CLASS="qindex">
+ <TABLE BORDER="0" WIDTH="100%">
+ <TR>
+ <TD CLASS="tiny" ALIGN="LEFT">Copyright &copy 2005-2008 Philipp Henkel</TD>
+ <TD ALIGN="RIGHT">
+ <A CLASS="qindex" HREF="index.html">Overview</A> |
+ <A CLASS="qindex" HREF="reference/annotated.html">Reference</A> |
+ <A CLASS="qindex" HREF="tutorial/intro.html">Tutorial</A> |
+ <A CLASS="qindex" HREF="examples/intro.html">Examples</A> |
+ <A CLASS="qindex" HREF="design/intro.html">Design</A>
+ </TD>
+ </TR>
+ </TABLE>
+ </DIV>
+
+ <P align="right" valign="top">
+ Hosted by
+ <A HREF="http://sourceforge.net">
+ <IMG src="http://sflogo.sourceforge.net/sflogo.php?group_id=158064&type=2"
+ width="125"
+ height="37"
+ border="0"
+ align="top"
+ alt="SourceForge.net Logo"/>
+ </A>
+ </P>
+ </BODY>
+</HTML>
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/index.html b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/index.html
new file mode 100644
index 0000000000..f36e87310d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/index.html
@@ -0,0 +1,9 @@
+<HTML>
+ <HEAD>
+ <TITLE>threadpool Documentation</TITLE>
+ <meta http-equiv="refresh" content="2;url=overview/index.html">
+ </HEAD>
+ <BODY BGCOLOR="#FFFFFF">
+
+ </BODY>
+</HTML>
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview.dox b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview.dox
new file mode 100644
index 0000000000..3021c3972d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview.dox
@@ -0,0 +1,145 @@
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = "threadpool"
+PROJECT_NUMBER = 0.2.5
+OUTPUT_DIRECTORY = ../../../doc
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = NO
+REPEAT_BRIEF = NO
+ALWAYS_DETAILED_SEC = YES
+INLINE_INHERITED_MEMB = YES
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = /../../../boost/threadpool
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = YES
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = YES
+DETAILS_AT_TOP = YES
+INHERIT_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 2
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = NO
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = YES
+HIDE_UNDOC_CLASSES = YES
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = NO
+INLINE_INFO = NO
+SORT_MEMBER_DOCS = NO
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = NO
+GENERATE_TESTLIST = NO
+GENERATE_BUGLIST = NO
+GENERATE_DEPRECATEDLIST= NO
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = NO
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = overview.txt
+FILE_PATTERNS =
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH = ../../..
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = YES
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 1
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = .
+HTML_FILE_EXTENSION = .html
+HTML_HEADER = overview_header.htm
+HTML_FOOTER = overview_footer.htm
+HTML_STYLESHEET = threadpool.css
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = YES
+ENUM_VALUES_PER_LINE = 1
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview.txt b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview.txt
new file mode 100644
index 0000000000..3a995fffb9
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview.txt
@@ -0,0 +1,205 @@
+/*! \mainpage threadpool
+
+
+\section intro_sec threadpool
+threadpool is a cross-platform C++ thread pool library. In general terms thread pools
+are an efficient mechanism for asynchronous task processing within the same process.
+They realise the <A HREF="design/pattern.html"> thread pool pattern</A>.
+
+A thread pool manages a group of threads in order to process a large number of tasks.
+Since multiple threads can be executed in parallel this approach may be very efficient regarding the overall program performance on many computer systems. By restricting the number of threads and by reusing them resources are saved
+and additionally the system stability is increased.
+
+The threadpool library provides a convenient way for dispatching asynchronous tasks. Pools can be customized, managed dynamically and easily integrated into your software.
+
+
+\section dev_status_sec Development Status & Future Work
+The threadpool core classes are completed and the implemenation can be considered ready for production code. The library is used by several commercial server applications and can handle high workload without problems. I'm currently working on helper and service classes which make the
+usage of the pool more comfortable. A small tutorial introduces the thread pool and
+more example code will be added in the future. The documentation is far away from being finished.
+<BR>
+<BR><A HREF="http://threadpool.cvs.sourceforge.net/threadpool/threadpool">Browse CVS Repository</A>
+<BR>
+
+<P>
+Features
+- Policy-based thread pool implementation<BR>
+- Scheduling policies: fifo, lifo and priority<BR>
+- Size policies: static_size<BR>
+- Size policy controller: empty_controller, resize_controller<BR>
+- Shutdown policies: wait_for_all_tasks, wait_for_active_tasks, immediately<BR>
+- Smooth integration into STL and boost<BR>
+</P>
+
+<P>
+Future Work
+- More policies: deadline_scheduler, ...<BR>
+- Possibility of limiting the number of pending tasks<BR>
+- Futures (handles to results of scheduled functions)<BR>
+- More examples to illustrate the usage of the library<BR>
+- Provide Unit tests<BR>
+</P>
+
+
+
+
+\section down_sec Download Section
+<P>
+threadpool 0.2.5 (Development Snapshot)
+- <A HREF="http://prdownloads.sourceforge.net/threadpool/threadpool-0_2_5-src.zip?download">threadpool-0_2_5-src.zip</A><BR>
+- <A HREF="http://prdownloads.sourceforge.net/threadpool/threadpool-0_2_5-doc.zip?download">threadpool-0_2_5-doc.zip</A><BR>
+</P>
+
+For more information on the revisions see \ref changelog.
+
+
+\section platforms_sec Supported Platforms
+threadpool is highly portable. It runs on any platform on which Boost threads are available: Linux, Windows, Mac OS 9/X, Solaris, etc.
+
+
+\section boost_sec Boost Libraries
+Boost is a collection of high-quality C++ libraries and works on almost any
+modern operating system, including UNIX and Windows variants.
+In fact threadpool is only a small extension to the portable Boost source libraries.
+It incorporates the thread pool concept by using the thread library from William Kempf.
+For more information on this excellent library visit <A HREF="http://www.boost.org">Boost.org</A>.
+
+
+\section installation_sec Installing & Using threadpool
+threadpool consists only of header files, and so there is no need to build the library itself
+before using it in your own applications. You simply need to add the
+following directories to your compiler include path:<BR>
+ - threadpool's include directory<BR>
+ - the boost directory (e.g. the one called boost_1_37_0)<BR>
+
+Furthermore you have to compile boost's thread library and link against it (libboost_thread-*.lib under Windows).
+
+
+
+\section license_sec Software License
+threadpool is released under the \ref license "Boost Software License".
+This license encourages both commercial and non-commercial use.
+
+
+\section acknowledgments_sec Acknowledgments
+This library was written by Philipp Henkel.
+<P>
+I appreciate your suggestions, and would love to know if you
+use threadpool. Hopefully you will enjoy it and find it useful.
+Please post questions, comments, bugs, or contact me at:
+
+</P>
+
+threadpool@googlemail.com<BR>
+or<BR>
+<A HREF="http://www.sourceforge.net/projects/threadpool">www.sourceforge.net/projects/threadpool</A>
+<BR>
+<BR>
+*/
+
+
+
+/*! \page license Software License
+
+\verbinclude LICENSE_1_0.txt
+
+*/
+
+
+
+ /*! \page changelog Change Log
+
+ <B>0.2.5 (Stable)</B>
+ - Made threadpool compatible to boost::thread 1.37
+ - Fixed hang problem in shutdown method (Thanks to Sohail Somani)
+ - Adapted repository layout to boost (Thanks to Alex Ott)
+
+<B>0.2.4 (Stable)</B>
+ - Made threadpool compatible to boost::thread 1.35.x code base
+ - Fixed compiler warning in scope_guard.hpp
+
+<B>0.2.4 (Stable)</B>
+ - Made threadpool compatible to boost::thread 1.35.x code base
+ - Fixed compiler warning in scope_guard.hpp
+
+<B>0.2.3 (Development)</B>
+ - Implemented workaround for Sun C++ Pro compiler bug in pool_core
+ - Removed subtask implementation (there was no demand for this feature)
+ - Improved shutdown policies
+
+<B>0.2.2 (Development)</B>
+ - Refactored SizePolicy and added SizePolicyController
+ - Moved policies into separate files
+ - Fixed some compiler problems (GCC)
+ - Implemented size_controller handling
+ - Implemented two size policies: static_size and fixed_size
+ - Refactored worker_thread handling, moved policies from pool_core to pool
+ - Specialized schedule function for usage with futures
+ - Added compile test project
+ - Improved constness in pool core class
+ - Fixed timed wait
+ - Implemented futures (in progress)
+ - Added result_type to all functors
+
+<B>0.2.1 (Development)</B>
+ - Pool base class (thread_pool) has now reference semantics.
+ - Large refactorings: Removed scoped_pool, reimplemented worker (now worker_thread)
+ - Fixed odd resize behaviour. Now resize changes the number of threads immediately.
+ - Apply pimpl idiom on pool core class (to make the ugly scoped_pool class needless)
+ - Introduced scheduling policies
+ - Switched to policy-based design (PBD), inspired by Scott Meyers C++ workshop
+ - Cosmetic code change: Replaced keyword 'class' with 'typename' in template definitions
+ - Revised tutorials
+ - New requirements: tasks functions should not and schedulers shall not throw exceptions
+
+<B>0.2.0 (Development)</B>
+ - Moved threadpool into the boost namespace: boost::threadpool
+ - Used keyword volatile to indicate thread-safe member functions
+ - Used volatile on primitve types were appropriate
+ - Moved worker to detail directory
+ - Fixed thread deletion
+ - Extended wait functionality (waiting for idle threads was implemented)
+ - Renamed 'join()' to 'wait()' as 'join' indicates the termination of thread. That was not the case in pool::join.
+ - Changed internal container of lifo and fifo schedulers to improve efficiency.
+ - Improved code reference documentation (source code browser)
+ - Renamed thread_func into task_func
+ - Added += operator to scoped_pool to ease scheduling of tasks
+ - Refactored file structures and class names
+ - Added a new task concept (named subtask) which allows the combination of sequential and parallel execution
+ - Added new task adaptor for looped or timed tasks: looped_task_func
+ - Introduced function clear() which can be used to remove all tasks from the pool and schedulers
+ - New function pool::active() which returns the number of active tasks
+
+<B>0.1.8 (Development)</B>
+ - Fixed some compile errors which were reported by gcc
+ - Wrote tutorial "Prioritized Tasks"
+
+<B>0.1.7 (Development)</B>
+ - Added Visual Studio 2005 project files for tutorial and examples
+
+<B>0.1.6 (Development)</B>
+ - Replaced task adaptor 'task' with boost::bind
+ - Workers are unregistered from thread_group when they are terminated
+ - Working on example boost::iostreams packet_filter
+
+<B>0.1.5 (Development)</B>
+ - Finished threadpool reference
+ - Class pool_adaptor was replaced by smart_pool
+ - Minor pool improvements
+ - First tutorial page online
+
+<B>0.1.4 (Development)</B>
+ - Created the pool's homepage: http://threadpool.sourceforge.net
+ - Improved documentation
+ - Added build scripts
+
+<B>0.1.3 (Development)</B>
+ - First public release
+ - Added mergesort example
+ - Added tutorial
+ - Implementation of threadpool core and related classes
+
+ */
+
+
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview_header.htm b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview_header.htm
new file mode 100644
index 0000000000..dc6e9f6c18
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/overview_header.htm
@@ -0,0 +1,36 @@
+<HTML>
+ <HEAD>
+ <TITLE>threadpool Documentation</TITLE>
+ <LINK HREF="threadpool.css" REL="stylesheet" TYPE="text/css">
+ </HEAD>
+ <BODY BGCOLOR="#FFFFFF">
+ <DIV CLASS="qindex">
+ <TABLE BORDER="0" WIDTH="100%">
+ <TR>
+ <TD ALIGN="LEFT">
+ <B>$projectname</B>
+ </TD>
+ <TD ALIGN="RIGHT">
+ <A CLASS="qindex" HREF="index.html">Overview</A> |
+ <A CLASS="qindex" HREF="reference/annotated.html">Reference</A> |
+ <A CLASS="qindex" HREF="tutorial/intro.html">Tutorial</A> |
+ <A CLASS="qindex" HREF="examples/intro.html">Examples</A> |
+ <A CLASS="qindex" HREF="design/intro.html">Design</A>
+ </TD>
+ </TR>
+ </TABLE>
+ </DIV>
+ <DIV CLASS="qindex">
+ <TABLE BORDER="0" WIDTH="100%">
+ <TR>
+ <TD ALIGN="LEFT">
+ <B>Overview</B>
+ </TD>
+ <TD ALIGN="RIGHT">
+ <A CLASS="qindex" HREF="index.html">Main Page</A> |
+ <A CLASS="qindex" HREF="changelog.html">Change Log</A> |
+ <A CLASS="qindex" HREF="license.html">Software License</A>
+ </TD>
+ </TR>
+ </TABLE>
+ </DIV>
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/reference.dox b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/reference.dox
new file mode 100644
index 0000000000..d0fb398834
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/reference.dox
@@ -0,0 +1,220 @@
+# Doxyfile 1.4.2
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = "threadpool"
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY = ../../../doc/reference
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = NO
+REPEAT_BRIEF = YES
+ALWAYS_DETAILED_SEC = YES
+INLINE_INHERITED_MEMB = YES
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = /../../../boost/threadpool
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = YES
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = YES
+DETAILS_AT_TOP = YES
+INHERIT_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 2
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+SUBGROUPING = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = NO
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = YES
+HIDE_UNDOC_CLASSES = YES
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = NO
+INLINE_INFO = NO
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = YES
+SORT_BY_SCOPE_NAME = YES
+GENERATE_TODOLIST = NO
+GENERATE_TESTLIST = NO
+GENERATE_BUGLIST = NO
+GENERATE_DEPRECATEDLIST= NO
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = NO
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = ../../../boost ../../../boost/threadpool
+FILE_PATTERNS = *.hpp
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH = /../examples
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = YES
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = YES
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+VERBATIM_HEADERS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 1
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = .
+HTML_FILE_EXTENSION = .html
+HTML_HEADER = reference_header.htm
+HTML_FOOTER = common_footer.htm
+HTML_STYLESHEET = threadpool.css
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = YES
+ENUM_VALUES_PER_LINE = 1
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4wide
+EXTRA_PACKAGES =
+LATEX_HEADER =
+PDF_HYPERLINKS = NO
+USE_PDFLATEX = NO
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+EXPAND_ONLY_PREDEF = YES
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = NO
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = YES
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = NO
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+TEMPLATE_RELATIONS = YES
+INCLUDE_GRAPH = NO
+INCLUDED_BY_GRAPH = NO
+CALL_GRAPH = NO
+GRAPHICAL_HIERARCHY = NO
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 1024
+MAX_DOT_GRAPH_HEIGHT = 1024
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = NO
+DOT_CLEANUP = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/reference_header.htm b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/reference_header.htm
new file mode 100644
index 0000000000..40fd7423aa
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/reference_header.htm
@@ -0,0 +1,40 @@
+<HTML>
+ <HEAD>
+ <TITLE>threadpool Documentation</TITLE>
+ <LINK HREF="threadpool.css" REL="stylesheet" TYPE="text/css">
+ </HEAD>
+ <BODY BGCOLOR="#FFFFFF">
+
+ <DIV CLASS="qindex">
+ <TABLE BORDER="0" WIDTH="100%">
+ <TR>
+
+ <TD ALIGN="LEFT">
+ <B>$projectname</B>
+ </TD>
+ <TD ALIGN="RIGHT">
+ <A CLASS="qindex" HREF="../index.html">Overview</A> |
+ <A CLASS="qindex" HREF="../reference/annotated.html">Reference</A> |
+ <A CLASS="qindex" HREF="../tutorial/intro.html">Tutorial</A> |
+ <A CLASS="qindex" HREF="../examples/intro.html">Examples</A> |
+ <A CLASS="qindex" HREF="../design/intro.html">Design</A>
+ </TD>
+
+ </TR>
+ </TABLE>
+ </DIV>
+ <DIV CLASS="qindex">
+ <TABLE BORDER="0" WIDTH="100%">
+ <TR>
+ <TD ALIGN="LEFT">
+ <B>Reference</B>
+ </TD>
+ <TD ALIGN="RIGHT">
+ <A CLASS="qindex" HREF="annotated.html">Class List</A> |
+ <A CLASS="qindex" HREF="functions.html">Member Functions</A> |
+ <A CLASS="qindex" HREF="namespacemembers.html">Typedefs</A> |
+ <A CLASS="qindex" HREF="files.html">File List</A>
+ </TD>
+ </TR>
+ </TABLE>
+ </DIV>
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/threadpool.css b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/threadpool.css
new file mode 100644
index 0000000000..8593700905
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/threadpool.css
@@ -0,0 +1,331 @@
+BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+ font-family: Geneva, Arial, Helvetica, sans-serif;
+}
+BODY,TD {
+ font-size: 90%;
+}
+H1 {
+ text-align: center;
+ font-size: 160%;
+}
+H2 {
+ font-size: 120%;
+}
+H3 {
+ font-size: 100%;
+}
+CAPTION { font-weight: bold }
+DIV.sidebar {
+ width: 210px;
+ background-color: #e8eef2;
+ border: 1px solid #84b0c7;
+ text-align: center;
+ margin: 2px;
+ margin-bottom: 20px;
+ padding: 2px;
+ line-height: 140%;
+}
+DIV.sidebar TABLE TR TD {
+ font-size: 80%;
+}
+DIV.sidebar UL {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+DIV.qindex {
+ width: 100%;
+ background-color: #e8eef2;
+ border: 1px solid #84b0c7;
+ text-align: center;
+ margin: 2px;
+ padding: 2px;
+ line-height: 140%;
+}
+DIV.nav {
+ width: 100%;
+ background-color: #e8eef2;
+ border: 1px solid #84b0c7;
+ text-align: center;
+ margin: 2px;
+ padding: 2px;
+ line-height: 140%;
+}
+DIV.navtab {
+ background-color: #e8eef2;
+ border: 1px solid #84b0c7;
+ text-align: center;
+ margin: 2px;
+ margin-right: 15px;
+ padding: 2px;
+}
+TD.navtab {
+ font-size: 70%;
+}
+A.qindex {
+ text-decoration: none;
+ font-weight: bold;
+ color: #1A419D;
+}
+A.qindex:visited {
+ text-decoration: none;
+ font-weight: bold;
+ color: #1A419D
+}
+A.qindex:hover {
+ text-decoration: none;
+ background-color: #ddddff;
+}
+A.qindexHL {
+ text-decoration: none;
+ font-weight: bold;
+ background-color: #6666cc;
+ color: #ffffff;
+ border: 1px double #9295C2;
+}
+A.qindexHL:hover {
+ text-decoration: none;
+ background-color: #6666cc;
+ color: #ffffff;
+}
+A.anchor {
+ text-decoration: none;
+ color: #000000;
+}
+A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }
+A.el { text-decoration: none; font-weight: bold }
+A.elRef { text-decoration: none; font-weight: bold }
+A.code:link { text-decoration: none; font-weight: normal; color: #0000FF}
+A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}
+A.codeRef:link { text-decoration: none; font-weight: normal; color: #0000FF}
+A.codeRef:visited { text-decoration: none; font-weight: normal; color: #0000FF}
+A:hover { text-decoration: none; background-color: #f2f2ff }
+DL.el { margin-left: -1cm }
+.fragment {
+ font-family: Fixed, monospace;
+ font-size: 95%;
+}
+PRE.fragment {
+ border: 1px solid #CCCCCC;
+ background-color: #f5f5f5;
+ margin-top: 4px;
+ margin-bottom: 4px;
+ margin-left: 2px;
+ margin-right: 8px;
+ padding-left: 6px;
+ padding-right: 6px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
+TD.md { background-color: #F4F4FB; font-weight: bold; }
+TD.mdPrefix {
+ background-color: #F4F4FB;
+ color: #606060;
+ font-size: 80%;
+}
+TD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; }
+TD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; }
+DIV.groupHeader {
+ margin-left: 16px;
+ margin-top: 12px;
+ margin-bottom: 6px;
+ font-weight: bold;
+}
+DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }
+BODY {
+ background: white;
+ color: black;
+ margin-right: 20px;
+ margin-left: 20px;
+}
+TD.indexkey {
+ background-color: #e8eef2;
+ font-weight: bold;
+ padding-right : 10px;
+ padding-top : 2px;
+ padding-left : 10px;
+ padding-bottom : 2px;
+ margin-left : 0px;
+ margin-right : 0px;
+ margin-top : 2px;
+ margin-bottom : 2px;
+ border: 1px solid #CCCCCC;
+}
+TD.indexvalue {
+ background-color: #e8eef2;
+ font-style: italic;
+ padding-right : 10px;
+ padding-top : 2px;
+ padding-left : 10px;
+ padding-bottom : 2px;
+ margin-left : 0px;
+ margin-right : 0px;
+ margin-top : 2px;
+ margin-bottom : 2px;
+ border: 1px solid #CCCCCC;
+}
+TR.memlist {
+ background-color: #f0f0f0;
+}
+P.formulaDsp { text-align: center; }
+IMG.formulaDsp { }
+IMG.formulaInl { vertical-align: middle; }
+SPAN.keyword { color: #008000 }
+SPAN.keywordtype { color: #604020 }
+SPAN.keywordflow { color: #e08000 }
+SPAN.comment { color: #800000 }
+SPAN.preprocessor { color: #806020 }
+SPAN.stringliteral { color: #002080 }
+SPAN.charliteral { color: #008080 }
+.mdTable {
+ border: 1px solid #868686;
+ background-color: #F4F4FB;
+}
+.mdRow {
+ padding: 8px 10px;
+}
+.mdescLeft {
+ padding: 0px 8px 4px 8px;
+ font-size: 80%;
+ font-style: italic;
+ background-color: #FAFAFA;
+ border-top: 1px none #E0E0E0;
+ border-right: 1px none #E0E0E0;
+ border-bottom: 1px none #E0E0E0;
+ border-left: 1px none #E0E0E0;
+ margin: 0px;
+}
+.mdescRight {
+ padding: 0px 8px 4px 8px;
+ font-size: 80%;
+ font-style: italic;
+ background-color: #FAFAFA;
+ border-top: 1px none #E0E0E0;
+ border-right: 1px none #E0E0E0;
+ border-bottom: 1px none #E0E0E0;
+ border-left: 1px none #E0E0E0;
+ margin: 0px;
+}
+.memItemLeft {
+ padding: 1px 0px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-top-style: solid;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ background-color: #FAFAFA;
+ font-size: 80%;
+}
+.memItemRight {
+ padding: 1px 8px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-top-style: solid;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ background-color: #FAFAFA;
+ font-size: 80%;
+}
+.memTemplItemLeft {
+ padding: 1px 0px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-top-style: none;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ background-color: #FAFAFA;
+ font-size: 80%;
+}
+.memTemplItemRight {
+ padding: 1px 8px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-top-style: none;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ background-color: #FAFAFA;
+ font-size: 80%;
+}
+.memTemplParams {
+ padding: 1px 0px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-top-style: solid;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ color: #606060;
+ background-color: #FAFAFA;
+ font-size: 80%;
+}
+.search { color: #003399;
+ font-weight: bold;
+}
+FORM.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+INPUT.search { font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #e8eef2;
+}
+TD.tiny { font-size: 75%;
+}
+a {
+ color: #1A41A8;
+}
+a:visited {
+ color: #2A3798;
+}
+.dirtab { padding: 4px;
+ border-collapse: collapse;
+ border: 1px solid #84b0c7;
+}
+TH.dirtab { background: #e8eef2;
+ font-weight: bold;
+}
+HR { height: 1px;
+ border: none;
+ border-top: 1px solid black;
+}
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial.dox b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial.dox
new file mode 100644
index 0000000000..66a39edf23
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial.dox
@@ -0,0 +1,145 @@
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = "threadpool"
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY = ../../../doc/tutorial
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+USE_WINDOWS_ENCODING = NO
+BRIEF_MEMBER_DESC = NO
+REPEAT_BRIEF = NO
+ALWAYS_DETAILED_SEC = YES
+INLINE_INHERITED_MEMB = YES
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH = /../../include/
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = YES
+JAVADOC_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = YES
+DETAILS_AT_TOP = YES
+INHERIT_DOCS = YES
+DISTRIBUTE_GROUP_DOC = NO
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 2
+ALIASES =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = NO
+EXTRACT_LOCAL_METHODS = NO
+HIDE_UNDOC_MEMBERS = YES
+HIDE_UNDOC_CLASSES = YES
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = NO
+INLINE_INFO = NO
+SORT_MEMBER_DOCS = NO
+SORT_BRIEF_DOCS = NO
+SORT_BY_SCOPE_NAME = NO
+GENERATE_TODOLIST = NO
+GENERATE_TESTLIST = NO
+GENERATE_BUGLIST = NO
+GENERATE_DEPRECATEDLIST= NO
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = NO
+SHOW_DIRECTORIES = NO
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = tutorial.txt
+FILE_PATTERNS =
+RECURSIVE = NO
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = YES
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = NO
+COLS_IN_ALPHA_INDEX = 1
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = .
+HTML_FILE_EXTENSION = .html
+HTML_HEADER = tutorial_header.htm
+HTML_FOOTER = common_footer.htm
+HTML_STYLESHEET = threadpool.css
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = YES
+ENUM_VALUES_PER_LINE = 1
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial.txt b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial.txt
new file mode 100644
index 0000000000..e89c96d9af
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial.txt
@@ -0,0 +1,207 @@
+/*! \page intro Quick Start
+
+This tutorial introduces the threadpool library by discussing an easy to understand source listing:
+
+\code
+01
+02 #include "threadpool.hpp"
+03
+04 using namespace boost::threadpool;
+05
+06 // Some example tasks
+07 void first_task()
+08 {
+09 ...
+10 }
+11
+13 void second_task()
+14 {
+15 ...
+16 }
+17
+19 void third_task()
+20 {
+21 ...
+22 }
+23
+24 void execute_with_threadpool()
+25 {
+26 // Create a thread pool.
+27 pool tp(2);
+28
+29 // Add some tasks to the pool.
+30 tp.schedule(&first_task);
+31 tp.schedule(&second_task);
+32 tp.schedule(&third_task);
+33
+34 // Leave this function and wait until all tasks are finished.
+35 }
+36
+\endcode
+
+We start by including the necessary header files. The complete threadpool functionality can be used by simply including
+the "threadpool.hpp" header file at line 2.
+
+The three functions first_task(), second_task and third_task() are placeholders
+for tasks that should be executed by our pool.
+
+The thread pool is created at line 27. The argument indicates the number of initial threads.
+The new pool contains two threads that is two tasks can be processed in parallel. The pool's threads
+are sleeping until tasks are added.
+By default it uses a Fifo scheduling strategy.
+Fifo is an abbreviation of "first in, first out"
+and means in this case that the first task which is added is the
+first that will be executed. Generally this is the expected default behaviour
+since the tasks are executed in the order they are added to the pool.
+
+In line 30 to 32 the task functions are scheduled asynchronously using the pool's schedule function.
+A task is registered and it will be executed as soon as one of the pool's threads is idle.
+It is very important to understand that the task is only scheduled for execution.
+Schedule returns immediately and there are no guarantees about when the tasks are executed and how long
+the processing will take. As they are added to a fifo pool with two threads the following is true:
+- the execution of first_task begins first
+- second_task is started after first_task
+- third_task is begun at last
+- a maximum of two tasks may are processed in parallel
+- each scheduled task will be executed once only
+
+
+The pool reference tp is created in the scope of the function execute_with_threadpool(). When this
+function returns at line 35 tp goes out of scope and the pool will be destructed. As the default ShutdownPolicy
+is wait_for_all_tasks it is ensured that all tasks are processed before the pool is destroyed.
+
+\code
+101
+102 ...
+103 execute_with_threadpool(); // execute first_task, second_task and third_task
+104 // When this line is reached all tasks are finished and the pool is destructed.
+105
+\endcode
+
+The small code example clarifies the issue. When the function leaves the pool is shut down
+and waits for the tasks. That means the current thread of execution is blocked
+at the end of the execute_with_threadpool as long as
+the processing of tasks is in progress.
+
+<BR>
+*/
+
+
+/*! \page prioritized Prioritized Tasks
+
+TODO This tutorial is out dated.
+
+It's easy to prioritize asynchronous tasks by using the task adaptor prio_task_func.
+The following source listing illustrates how to setup the pool and add the tasks:
+
+\code
+01
+02 #include "threadpool.hpp"
+03
+04 using namespace boost::threadpool;
+05
+06 // Some example tasks
+07 void normal_task()
+08 {
+09 ...
+10 }
+11
+13 void important_task()
+14 {
+15 ...
+16 }
+17
+18 void execute_prioritized()
+19 {
+20 // Create prioritized thread pool container without any threads.
+21 scoped_pool<prio_pool, 0> tp;
+22
+23 // Add some tasks to the pool.
+24 tp += prio_task_func(5, &normal_task);
+25 tp += prio_task_func(100, &important_task);
+26 tp += prio_task_func(7, &normal_task);
+27
+28 // Add the some threads to the pool. This will start the execution of the tasks.
+29 tp->resize(2);
+30
+31 // The tasks are processed according to their priority: important_task(100), nonrelevant_task(7), nonrelevant_task(5).
+32
+33 tp->wait();
+34
+35 // Now all tasks are finished and the pool will be destroyed safely when tp goes out of scope.
+36 }
+37
+\endcode
+
+Like in the first tutorial we start including the main header file and defining some tasks.
+
+At line 21 a prioritized thread pool is created. That means that the pool's tasks are arranged
+according to their priority before they get executed. Therefore the tasks themselves have to realize a partial ordering based
+on operator<.
+
+The adaptor prio_thread_func satisfies our requirements regarding the order and is just a small wrapper object for
+the task functions. In line 24 to 26 some prioritized tasks are scheduled. This time the pool's schedule function is used and like smart pool's += operator
+this function returns immediately.
+
+At line 29 the first thread is added to the pool and the execution of important_task begins. As we have only one thread
+the tasks are processed sequentially.
+
+Finally wait() is called to ensure that all tasks are finished before our example function returns
+and the pool is destroyed. This is very important since the behavior is undefined if pool's lifetime ends while tasks are executed.
+
+*/
+
+
+/*! \page task_adaptor Arbitrary Task Functions
+
+TODO This tutorial is out dated.
+
+
+\section member_task Member Task Functions
+
+using namespace boost::threadpool;
+
+TODO <BR>
+boost::bind(member_function, shared_ptr)
+26 tp->schedule(boost::bind(task_with_parameter, 42));
+12 // Second example task
+13 void task_with_parameter(int value)
+14 {
+15 ...
+16 }
+
+\section member_task Functions With Arguments
+
+*/
+
+
+/*! \page instantiation Advanced Instantiation
+
+TODO This tutorial is out dated.
+
+TODO <BR>
+Pool instantiation
+\code
+
+ boost::shared_ptr<fifo_pool> tp = fifo_pool::create_pool(5);
+
+ print(" Add tasks ...\n");
+ tp->schedule(&task_1);
+ tp->schedule(&task_2);
+ tp->schedule(&task_3);
+
+ tp->schedule(looped_task_func(&looped_task, 1500));
+
+ print(" Wait until all tasks are finished ...\n");
+ tp->wait();
+ print(" Tasks finished!\n");
+
+\endcode
+
+
+\code
+ typedef threadpool::pool<boost::function0<void>, threadpool::fifo_scheduler<boost::function0<void> > > pool_type;
+ boost::shared_ptr< pool_type > tp = pool_type::create_pool(5);
+\endcode
+
+*/ \ No newline at end of file
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial_header.htm b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial_header.htm
new file mode 100644
index 0000000000..b087ec0f9f
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/doc/tutorial_header.htm
@@ -0,0 +1,40 @@
+<HTML>
+ <HEAD>
+ <TITLE>threadpool Documentation</TITLE>
+ <LINK HREF="threadpool.css" REL="stylesheet" TYPE="text/css">
+ </HEAD>
+ <BODY BGCOLOR="#FFFFFF">
+
+ <DIV CLASS="qindex">
+ <TABLE BORDER="0" WIDTH="100%">
+ <TR>
+
+ <TD ALIGN="LEFT">
+ <B>$projectname</B>
+ </TD>
+ <TD ALIGN="RIGHT">
+ <A CLASS="qindex" HREF="../index.html">Overview</A> |
+ <A CLASS="qindex" HREF="../reference/annotated.html">Reference</A> |
+ <A CLASS="qindex" HREF="../tutorial/intro.html">Tutorial</A> |
+ <A CLASS="qindex" HREF="../examples/intro.html">Examples</A> |
+ <A CLASS="qindex" HREF="../design/intro.html">Design</A>
+ </TD>
+
+ </TR>
+ </TABLE>
+ </DIV>
+ <DIV CLASS="qindex">
+ <TABLE BORDER="0" WIDTH="100%">
+ <TR>
+ <TD ALIGN="LEFT">
+ <B>Tutorial</B>
+ </TD>
+ <TD ALIGN="RIGHT">
+ <A CLASS="qindex" HREF="intro.html">Quick Start</A> |
+ <A CLASS="qindex" HREF="prioritized.html">Prioritized Tasks</A> |
+ <A CLASS="qindex" HREF="task_adaptor.html">Arbitrary Task Functions</A> |
+ <A CLASS="qindex" HREF="instantiation.html">Advanced Pool Instantiation</A>
+ </TD>
+ </TR>
+ </TABLE>
+ </DIV>
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/example/mergesort/Jamfile.v2 b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/example/mergesort/Jamfile.v2
new file mode 100644
index 0000000000..8ff7fe2dbb
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/example/mergesort/Jamfile.v2
@@ -0,0 +1,11 @@
+
+project
+ : requirements
+ <include>../../../..
+ <library>/boost/thread//boost_thread
+ <define>BOOST_ALL_NO_LIB=1
+ <threading>multi
+ <link>static
+ ;
+
+exe mergesort : mergesort.cpp ;
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/example/mergesort/mergesort.cpp b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/example/mergesort/mergesort.cpp
new file mode 100644
index 0000000000..338153453b
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/example/mergesort/mergesort.cpp
@@ -0,0 +1,200 @@
+/*! \file
+ * \brief Mergesort example.
+ *
+ * This example shows how to use the threadpool library.
+ *
+ * Copyright (c) 2005-2006 Philipp Henkel
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * http://threadpool.sourceforge.net
+ *
+ */
+
+
+#include <boost/threadpool.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/smart_ptr.hpp>
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+
+
+
+using namespace std;
+using namespace boost::threadpool;
+
+//
+// Helpers
+boost::mutex m_io_monitor;
+
+void print(string text)
+{
+ boost::mutex::scoped_lock lock(m_io_monitor);
+ cout << text;
+}
+
+template<class T>
+string to_string(const T& value)
+{
+ ostringstream ost;
+ ost << value;
+ ost.flush();
+ return ost.str();
+}
+
+unsigned long get_ms_diff(boost::xtime& start, boost::xtime& end)
+{
+ boost::xtime::xtime_sec_t start_ms = start.sec * 1000 + start.nsec/1000000;
+ boost::xtime::xtime_sec_t end_ms = end.sec * 1000 + end.nsec/1000000;
+ return static_cast<unsigned long>(end_ms - start_ms);
+}
+
+class image
+{
+public:
+ image() : m_content(0) {}
+ image(int content) : m_content(content) {}
+
+ image(const image& src)
+ {
+ m_content = src.m_content;
+ }
+
+ bool operator<(const image& l) const
+ {
+ { // simulate time needed for image comparision
+ boost::xtime xt;
+ boost::xtime_get(&xt, boost::TIME_UTC);
+ int duration = 1+(m_content % 4);
+ xt.nsec += 250 * 1000 * duration;
+ boost::thread::sleep(xt);
+ print(".");
+ }
+ return m_content < l.m_content;
+ }
+
+protected:
+ int m_content; // represents image data in this example
+};
+
+
+template<class T>
+class merge_job
+{
+public:
+ merge_job(boost::shared_array<T> data, unsigned int position, unsigned int length)
+ : m_data(data)
+ , m_position(position)
+ , m_length(length)
+ {
+ print("merge job created : " + to_string(m_position) +", "+ to_string(m_length) +"\n");
+ }
+
+ void run()
+ {
+ print("merge job running : " + to_string(m_position) +", "+ to_string(m_length) +"\n");
+
+ T* begin = m_data.get();
+ std::advance(begin, m_position);
+
+ T* mid = m_data.get();
+ std::advance(mid, m_position + m_length/2);
+
+ T* end = m_data.get();
+ std::advance(end, m_position + m_length);
+
+ std::inplace_merge(begin, mid, end);
+
+ print("\nmerge job finished: " + to_string(m_position) +", "+ to_string(m_length) +"\n");
+ }
+
+protected:
+ boost::shared_array<T> m_data;
+ unsigned int m_position;
+ unsigned int m_length;
+};
+
+
+
+
+//
+// A demonstration of the thread_pool class
+int main (int argc, char * const argv[])
+{
+ print("MAIN: construct thread pool\n");
+
+
+
+ boost::xtime start;
+ boost::xtime_get(&start, boost::TIME_UTC);
+
+ int exponent = 7;
+ int data_len = 1 << exponent; // = pow(2, exponent)
+
+ print("MAIN: sort array with "+ to_string(data_len) + " elements.\n");
+
+ boost::shared_array<image> data(new image[data_len]);
+
+ // fill array with arbitrary values (not sorted ascendingly)
+ for(int i = 0; i < data_len; i++)
+ {
+ data[i] = image((data_len - i - 1) % 23);
+ }
+
+
+ /***************************/
+ /* Standard implementation */
+ /***************************/
+
+ pool tp;
+ tp.size_controller().resize(5);
+
+// merge data array
+ for(int step = 1; step <= exponent; step++)
+ {
+ print("\nMAIN: merge step "+ to_string(step)+"\n");
+
+ // divide array into partitions
+ int partition_size = 1 << step;
+ for(int partition = 0; partition < data_len/partition_size; partition++)
+ {
+ // sort partition
+ boost::shared_ptr<merge_job<image> > job(new merge_job<image>(data, partition*partition_size, partition_size));
+ //tp->schedule(prio_task_func(5, boost::bind(&merge_job<image>::run, job)));
+ schedule(tp, boost::bind(&merge_job<image>::run, job));
+ // schedule(tp, job);
+ }
+ tp.wait(); // wait until all partitions are sorted
+ }
+
+ boost::xtime end;
+ boost::xtime_get(&end, boost::TIME_UTC);
+
+ print("\nMAIN: duration " + to_string(get_ms_diff(start, end)) + " ms \n");
+
+ print("\nMAIN: check if array is sorted... \n");
+
+ // check if array is sorted ascendingly
+ bool ascending = true;
+ for(int i = 0; i < data_len-1; i++)
+ {
+ if(data[i+1] < data[i])
+ {
+ ascending = false;
+ }
+ }
+
+ if(ascending)
+ {
+ print("\nMAIN: array is sorted\n");
+ }
+ else
+ {
+ print("\nMAIN: array is NOT sorted!\n");
+ }
+
+ return 0;
+}
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/Jamfile.v2 b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/Jamfile.v2
new file mode 100644
index 0000000000..85b2bcb0fd
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/Jamfile.v2
@@ -0,0 +1,11 @@
+
+project
+ : requirements
+ <include>../../..
+ <library>/boost/thread//boost_thread
+ <define>BOOST_ALL_NO_LIB=1
+ <threading>multi
+ <link>static
+ ;
+
+exe quickstart : quickstart.cpp ;
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/README b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/README
new file mode 100644
index 0000000000..4f97ce51d7
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/README
@@ -0,0 +1,7 @@
+Supposing the boost directory is in /usr/local/lib, it is also worth to mention that they need to
+set LD_LIBRARY_PATH as follows:
+export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):/usr/local/lib
+
+Please adapt threadpool.makefile to your system.
+
+Special thanks to Rudy Prabowo who contributed this example to help linux users.
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/quickstart.cpp b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/quickstart.cpp
new file mode 100644
index 0000000000..858573a0a8
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/quickstart/quickstart.cpp
@@ -0,0 +1,50 @@
+/*! \file
+ * \brief Quick start example.
+ *
+ * This is a very simple example which can be used to configure the threadpool environment on your system.
+ *
+ * Copyright (c) 2005-2006 Philipp Henkel
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * http://threadpool.sourceforge.net
+ *
+ */
+
+#include <iostream>
+
+#include <boost/threadpool.hpp>
+
+using namespace std;
+using namespace boost::threadpool;
+
+// Some example tasks
+void first_task()
+{
+ cout << "first task is running\n" ;
+}
+
+void second_task()
+{
+ cout << "second task is running\n" ;
+}
+
+int main(int argc,char *argv[])
+{
+ // Create fifo thread pool container with two threads.
+ pool tp(2);
+
+ // Add some tasks to the pool.
+ tp.schedule(&first_task);
+ tp.schedule(&second_task);
+
+ // Wait until all tasks are finished.
+ tp.wait();
+
+ // Now all tasks are finished!
+ return(0);
+}
+
+
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/test/compile_all/Jamfile.v2 b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/test/compile_all/Jamfile.v2
new file mode 100644
index 0000000000..e14c124a8d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/test/compile_all/Jamfile.v2
@@ -0,0 +1,11 @@
+
+project
+ : requirements
+ <include>../../../..
+ <library>/boost/thread//boost_thread
+ <define>BOOST_ALL_NO_LIB=1
+ <threading>multi
+ <link>static
+ ;
+
+exe compile_all : compile_all.cpp ;
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/test/compile_all/compile_all.cpp b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/test/compile_all/compile_all.cpp
new file mode 100644
index 0000000000..1c349d4406
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/test/compile_all/compile_all.cpp
@@ -0,0 +1,149 @@
+/*! \file
+* \brief threadpool tutorial.
+*
+* This file contains a tutorial for the threadpool library.
+*
+* Copyright (c) 2005-2006 Philipp Henkel
+*
+* Distributed under the Boost Software License, Version 1.0. (See
+* accompanying file LICENSE_1_0.txt or copy at
+* http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+
+
+
+#include <iostream>
+#include <sstream>
+#include <boost/thread/mutex.hpp>
+#include <boost/bind.hpp>
+
+#include <boost/threadpool.hpp>
+
+using namespace std;
+using namespace boost::threadpool;
+
+
+//
+// Helpers
+boost::mutex m_io_monitor;
+
+void print(string text)
+{
+ boost::mutex::scoped_lock lock(m_io_monitor);
+ cout << text;
+}
+
+template<typename T>
+string to_string(T const & value)
+{
+ ostringstream ost;
+ ost << value;
+ ost.flush();
+ return ost.str();
+}
+
+
+
+//
+// An example task functions
+void task_1()
+{
+ print(" task_1()\n");
+}
+
+void task_2()
+{
+ print(" task_2()\n");
+}
+
+void task_3()
+{
+ print(" task_3()\n");
+}
+
+int task_4()
+{
+ print(" task_4()\n");
+ return 4;
+}
+
+void task_with_parameter(int value)
+{
+ print(" task_with_parameter(" + to_string(value) + ")\n");
+}
+
+int loops = 0;
+bool looped_task()
+{
+ print(" looped_task()\n");
+ return ++loops < 5;
+}
+
+
+int task_int()
+{
+ print(" task_int()\n");
+ return 23;
+}
+
+
+void fifo_pool_test()
+{
+ pool tp;
+
+ tp.schedule(&task_1);
+ tp.schedule(boost::bind(task_with_parameter, 4));
+
+ if(!tp.empty())
+ {
+ tp.clear(); // remove all tasks -> no output in this test
+ }
+
+ size_t active_threads = tp.active();
+ size_t pending_threads = tp.pending();
+ size_t total_threads = tp.size();
+
+ size_t dummy = active_threads + pending_threads + total_threads;
+ dummy++;
+
+ tp.size_controller().resize(5);
+ tp.wait();
+}
+
+void lifo_pool_test()
+{
+ lifo_pool tp;
+ tp.size_controller().resize(0);
+ schedule(tp, &task_1);
+ tp.size_controller().resize(10);
+ tp.wait();
+}
+
+void prio_pool_test()
+{
+ prio_pool tp(2);
+ schedule(tp, prio_task_func(1, &task_1));
+ schedule(tp, prio_task_func(10,&task_2));
+}
+
+
+void future_test()
+{
+ fifo_pool tp(5);
+ future<int> fut = schedule(tp, &task_4);
+ int res = fut();
+}
+
+
+int main (int , char * const [])
+{
+ fifo_pool_test();
+ lifo_pool_test();
+ prio_pool_test();
+ future_test();
+ return 0;
+}
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/tutorial/Jamfile.v2 b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/tutorial/Jamfile.v2
new file mode 100644
index 0000000000..5b9d02b459
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/tutorial/Jamfile.v2
@@ -0,0 +1,11 @@
+
+project
+ : requirements
+ <include>../../..
+ <library>/boost/thread//boost_thread
+ <define>BOOST_ALL_NO_LIB=1
+ <threading>multi
+ <link>static
+ ;
+
+exe tutorial : tutorial.cpp ;
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/tutorial/tutorial.cpp b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/tutorial/tutorial.cpp
new file mode 100644
index 0000000000..4cc688509e
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/libs/threadpool/tutorial/tutorial.cpp
@@ -0,0 +1,263 @@
+/*! \file
+* \brief threadpool tutorial.
+*
+* This file contains a tutorial for the threadpool library.
+*
+* Copyright (c) 2005-2007 Philipp Henkel
+*
+* Distributed under the Boost Software License, Version 1.0. (See
+* accompanying file LICENSE_1_0.txt or copy at
+* http://www.boost.org/LICENSE_1_0.txt)
+*
+* http://threadpool.sourceforge.net
+*
+*/
+
+//#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+
+#include <iostream>
+#include <sstream>
+#include <boost/thread/mutex.hpp>
+#include <boost/bind.hpp>
+#include <boost/threadpool.hpp>
+
+using namespace std;
+using namespace boost::threadpool;
+
+//
+// Helpers
+boost::mutex m_io_monitor;
+
+void print(string text)
+{
+ boost::mutex::scoped_lock lock(m_io_monitor);
+ cout << text;
+}
+
+template<typename T>
+string to_string(T const & value)
+{
+ ostringstream ost;
+ ost << value;
+ ost.flush();
+ return ost.str();
+}
+
+
+
+//
+// An example task functions
+void task_1()
+{
+ print(" task_1()\n");
+ throw 5;
+}
+
+void task_2()
+{
+ print(" task_2()\n");
+ throw 5;
+}
+
+void task_3()
+{
+ print(" task_3()\n");
+}
+
+void task_with_parameter(int value)
+{
+ print(" task_with_parameter(" + to_string(value) + ")\n");
+}
+
+int loops = 0;
+bool looped_task()
+{
+ print(" looped_task()\n");
+ return ++loops < 5;
+}
+
+
+int task_int_23()
+{
+ print(" task_int_23()\n");
+ return 23;
+}
+
+int task_int_1()
+{
+ print(" task_int_1()\n");
+ return 1;
+}
+
+
+class CTest
+{
+ pool m_pool;
+public:
+ CTest()
+ : m_pool(pool(1000))
+ {
+ }
+};
+
+
+//
+// A demonstration of the thread_pool class
+int main (int , char * const [])
+{
+ print("\nWelcome to the threadpool tutorial!\n");
+
+ print("\n**************************************\n");
+ print("Section 1: Quick Start\n");
+
+ //void func()
+ {
+ print(" Create a new thread pool\n");
+ pool tp(2); // tp is handle to the pool
+
+ // Add tasks
+ tp.schedule(&task_1);
+ tp.schedule(&task_2);
+ tp.schedule(&task_3);
+ tp.schedule(boost::bind(task_with_parameter, 4));
+
+ // The pool handle tp is allocated on stack and will
+ // be destructed if it gets out of scope. Before the
+ // pool is destroyed it waits for its tasks.
+ // That means the current thread of execution is
+ // blocked at the end of the function
+ // (until all tasks are processed).
+ // while (&tp){int i = 3; ++i;}
+ }
+
+ { // Section Futures
+ print("\n**************************************\n");
+ print("Section 1: Futures\n");
+
+ //typedef thread_pool<task_func, fifo_scheduler, static_size, empty_controller, wait_for_all_tasks> test_pool;
+
+ pool tp;
+
+// tp.resize(0);
+ tp.pending();
+// tp.clear();
+ boost::xtime t;
+ tp.wait(t);
+ bool test = tp.empty();
+ if(test)
+ {
+ test = false;
+ }
+
+ tp.size_controller().resize(2);
+
+ //test_pool::size_controller_type controller = tp.size_controller();
+// controller.resize(5);
+
+ schedule(tp, &task_int_1);
+ future<int> res = schedule(tp, &task_int_23);
+ future<int> res2 = schedule(tp, &task_int_1);
+
+ res.wait();
+ int value = res.get() + res2.get();
+
+ res.cancel();
+ res.is_cancelled();
+value ++;
+
+//thread_pool<boost::function0<int>, fifo_scheduler> test2332;
+
+//TODO runnable comile test
+ }
+
+
+
+ { // Section 2
+ print("\n**************************************\n");
+ print("Section 2: Controlling scheduling\n");
+
+ // Create a lifo_pool: last task in, first task out
+ lifo_pool tp(0);
+
+ print(" Add tasks (using the pool's schedule function)\n");
+ schedule(tp, &task_1);
+ schedule(tp, &task_2);
+ schedule(tp, &task_3);
+
+ // tp.wait(); This would be a deadlock as there are no threads which process the tasks.
+
+ print(" Add some threads ...\n");
+ tp.size_controller().resize(5);
+
+ print(" Wait until all tasks are finished ...\n");
+ tp.wait();
+ print(" Tasks finished!\n");
+ }
+
+
+
+ { // Section 3:
+ print("\n**************************************\n");
+ print("Section 3: Prioritized Tasks\n");
+
+ prio_pool tp(0);
+
+
+ print(" Add prioritized tasks ...\n");
+ schedule(tp, prio_task_func(1, &task_1));
+ schedule(tp, prio_task_func(10,&task_2));
+ schedule(tp, prio_task_func(5,&task_3));
+
+ // Tasks are ordered according to their priority: task_2, task_4, task_3, task_1
+
+ print(" Thread added\n");
+ tp.size_controller().resize(10);
+
+ print(" Wait until all tasks are finished ...\n");
+ tp.wait();
+ print(" Tasks finished!\n");
+ }
+
+
+/* */
+ { // Section 5:
+ print("\n**************************************\n");
+ print("Section 5: Advanced thread pool instantiation\n");
+ // Create the pool directly
+/*
+TODO
+boost::shared_ptr<fifo_pool> tp = fifo_pool::create_pool(5);
+
+ print(" Add tasks ...\n");
+ tp->schedule(&task_1);
+ tp->schedule(&task_2);
+ tp->schedule(&task_3);
+ tp->schedule(looped_task_func(&looped_task, 1500));
+
+ print(" Wait until all tasks are finished ...\n");
+ tp->wait();
+*/
+
+ print(" Tasks finished!\n");
+
+ }
+
+
+ print("\n**************************************\n");
+ print("Tutorial finished!\n");
+
+
+
+ { // Section Compile Tests
+ print("\n**************************************\n");
+ print("Section Compile Tests\n");
+
+
+ fifo_pool tp;
+ tp.size_controller().resize(0);
+ tp.empty();
+ }
+
+ return 0;
+}
diff --git a/graphics/asymptote/LspCpp/third_party/threadpool/project-root.jam b/graphics/asymptote/LspCpp/third_party/threadpool/project-root.jam
new file mode 100644
index 0000000000..e94f7232e0
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/threadpool/project-root.jam
@@ -0,0 +1,2 @@
+import os ;
+path-constant BOOST_ROOT : [ os.environ BOOST_ROOT ] ;
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/CMakeLists.txt b/graphics/asymptote/LspCpp/third_party/utfcpp/CMakeLists.txt
new file mode 100644
index 0000000000..f1a2e1f1e9
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/CMakeLists.txt
@@ -0,0 +1,42 @@
+cmake_minimum_required (VERSION 3.0.2)
+project (utf8cpp VERSION 3.2 LANGUAGES CXX)
+
+if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
+ set(IS_ROOT_PROJECT ON)
+else()
+ set(IS_ROOT_PROJECT OFF)
+endif()
+
+option(UTF8_TESTS "Enable tests for UTF8-CPP" ${IS_ROOT_PROJECT})
+option(UTF8_INSTALL "Enable installation for UTF8-CPP" ${IS_ROOT_PROJECT})
+option(UTF8_SAMPLES "Enable building samples for UTF8-CPP" ${IS_ROOT_PROJECT})
+
+add_library(utf8cpp INTERFACE)
+target_include_directories(utf8cpp INTERFACE
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/source>"
+ $<INSTALL_INTERFACE:include/utf8cpp>
+)
+add_library(utf8::cpp ALIAS utf8cpp)
+
+if(UTF8_INSTALL)
+ if(MSVC)
+ set(DEF_INSTALL_CMAKE_DIR CMake)
+ else()
+ include(GNUInstallDirs) # define CMAKE_INSTALL_*
+ set(DEF_INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/utf8cpp)
+ endif()
+
+ install(DIRECTORY source/ DESTINATION include/utf8cpp)
+ install(TARGETS utf8cpp EXPORT utf8cppConfig)
+ install(EXPORT utf8cppConfig DESTINATION ${DEF_INSTALL_CMAKE_DIR})
+endif()
+
+if(UTF8_SAMPLES)
+ add_executable(docsample ${PROJECT_SOURCE_DIR}/samples/docsample.cpp)
+ target_link_libraries(docsample PRIVATE utf8::cpp)
+endif()
+
+if(UTF8_TESTS)
+ enable_testing()
+ add_subdirectory(tests)
+endif()
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/LICENSE b/graphics/asymptote/LspCpp/third_party/utfcpp/LICENSE
new file mode 100644
index 0000000000..36b7cd93cd
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/LICENSE
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/README.md b/graphics/asymptote/LspCpp/third_party/utfcpp/README.md
new file mode 100644
index 0000000000..a519cdb963
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/README.md
@@ -0,0 +1,1503 @@
+# UTF8-CPP: UTF-8 with C++ in a Portable Way
+
+
+## Introduction
+
+C++ developers miss an easy and portable way of handling Unicode encoded strings. The original C++ Standard (known as C++98 or C++03) is Unicode agnostic. C++11 provides some support for Unicode on core language and library level: u8, u, and U character and string literals, char16_t and char32_t character types, u16string and u32string library classes, and codecvt support for conversions between Unicode encoding forms. In the meantime, developers use third party libraries like ICU, OS specific capabilities, or simply roll out their own solutions.
+
+In order to easily handle UTF-8 encoded Unicode strings, I came up with a small, C++98 compatible generic library. For anybody used to work with STL algorithms and iterators, it should be easy and natural to use. The code is freely available for any purpose - check out the [license](./LICENSE). The library has been used a lot in the past ten years both in commercial and open-source projects and is considered feature-complete now. If you run into bugs or performance issues, please let me know and I'll do my best to address them.
+
+The purpose of this article is not to offer an introduction to Unicode in general, and UTF-8 in particular. If you are not familiar with Unicode, be sure to check out [Unicode Home Page](http://www.unicode.org/) or some other source of information for Unicode. Also, it is not my aim to advocate the use of UTF-8 encoded strings in C++ programs; if you want to handle UTF-8 encoded strings from C++, I am sure you have good reasons for it.
+
+## Examples of use
+
+### Introductionary Sample
+
+To illustrate the use of the library, let's start with a small but complete program that opens a file containing UTF-8 encoded text, reads it line by line, checks each line for invalid UTF-8 byte sequences, and converts it to UTF-16 encoding and back to UTF-8:
+
+```cpp
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+#include "utf8.h"
+using namespace std;
+int main(int argc, char** argv)
+{
+ if (argc != 2) {
+ cout << "\nUsage: docsample filename\n";
+ return 0;
+ }
+ const char* test_file_path = argv[1];
+ // Open the test file (must be UTF-8 encoded)
+ ifstream fs8(test_file_path);
+ if (!fs8.is_open()) {
+ cout << "Could not open " << test_file_path << endl;
+ return 0;
+ }
+
+ unsigned line_count = 1;
+ string line;
+ // Play with all the lines in the file
+ while (getline(fs8, line)) {
+ // check for invalid utf-8 (for a simple yes/no check, there is also utf8::is_valid function)
+#if __cplusplus >= 201103L // C++ 11 or later
+ auto end_it = utf8::find_invalid(line.begin(), line.end());
+#else
+ string::iterator end_it = utf8::find_invalid(line.begin(), line.end());
+#endif // C++ 11
+ if (end_it != line.end()) {
+ cout << "Invalid UTF-8 encoding detected at line " << line_count << "\n";
+ cout << "This part is fine: " << string(line.begin(), end_it) << "\n";
+ }
+ // Get the line length (at least for the valid part)
+ int length = utf8::distance(line.begin(), end_it);
+ cout << "Length of line " << line_count << " is " << length << "\n";
+
+ // Convert it to utf-16
+#if __cplusplus >= 201103L // C++ 11 or later
+ u16string utf16line = utf8::utf8to16(line);
+#else
+ vector<unsigned short> utf16line;
+ utf8::utf8to16(line.begin(), end_it, back_inserter(utf16line));
+#endif // C++ 11
+ // And back to utf-8;
+#if __cplusplus >= 201103L // C++ 11 or later
+ string utf8line = utf8::utf16to8(utf16line);
+#else
+ string utf8line;
+ utf8::utf16to8(utf16line.begin(), utf16line.end(), back_inserter(utf8line));
+#endif // C++ 11
+ // Confirm that the conversion went OK:
+ if (utf8line != string(line.begin(), end_it))
+ cout << "Error in UTF-16 conversion at line: " << line_count << "\n";
+
+ line_count++;
+ }
+
+ return 0;
+}
+```
+
+In the previous code sample, for each line we performed a detection of invalid UTF-8 sequences with `find_invalid`; the number of characters (more precisely - the number of Unicode code points, including the end of line and even BOM if there is one) in each line was determined with a use of `utf8::distance`; finally, we have converted each line to UTF-16 encoding with `utf8to16` and back to UTF-8 with `utf16to8`.
+
+Note a different pattern of usage for old compilers. For instance, this is how we convert
+a UTF-8 encoded string to a UTF-16 encoded one with a pre - C++11 compiler:
+```cpp
+ vector<unsigned short> utf16line;
+ utf8::utf8to16(line.begin(), end_it, back_inserter(utf16line));
+```
+
+With a more modern compiler, the same operation would look like:
+```cpp
+ u16string utf16line = utf8::utf8to16(line);
+```
+If `__cplusplus` macro points to a C++ 11 or later, the library exposes API that takes into
+account C++ standard Unicode strings and move semantics. With an older compiler, it is still
+possible to use the same functionality, just in a little less convenient way
+
+In case you do not trust the `__cplusplus` macro or, for instance, do not want to include
+the C++ 11 helper functions even with a modern compiler, define `UTF_CPP_CPLUSPLUS` macro
+before including `utf8.h` and assign it a value for the standard you want to use - the values are the same as for the `__cplusplus` macro. This can be also useful with compilers that are conservative in setting the `__cplusplus` macro even if they have a good support for a recent standard edition - Microsoft's Visual C++ is one example.
+
+### Checking if a file contains valid UTF-8 text
+
+Here is a function that checks whether the content of a file is valid UTF-8 encoded text without reading the content into the memory:
+
+```cpp
+bool valid_utf8_file(const char* file_name)
+{
+ ifstream ifs(file_name);
+ if (!ifs)
+ return false; // even better, throw here
+
+ istreambuf_iterator<char> it(ifs.rdbuf());
+ istreambuf_iterator<char> eos;
+
+ return utf8::is_valid(it, eos);
+}
+```
+
+Because the function `utf8::is_valid()` works with input iterators, we were able to pass an `istreambuf_iterator` to `it` and read the content of the file directly without loading it to the memory first.
+
+Note that other functions that take input iterator arguments can be used in a similar way. For instance, to read the content of a UTF-8 encoded text file and convert the text to UTF-16, just do something like:
+
+```cpp
+ utf8::utf8to16(it, eos, back_inserter(u16string));
+```
+
+### Ensure that a string contains valid UTF-8 text
+
+If we have some text that "probably" contains UTF-8 encoded text and we want to replace any invalid UTF-8 sequence with a replacement character, something like the following function may be used:
+
+```cpp
+void fix_utf8_string(std::string& str)
+{
+ std::string temp;
+ utf8::replace_invalid(str.begin(), str.end(), back_inserter(temp));
+ str = temp;
+}
+```
+
+The function will replace any invalid UTF-8 sequence with a Unicode replacement character. There is an overloaded function that enables the caller to supply their own replacement character.
+
+
+## Points of interest
+
+#### Design goals and decisions
+
+The library was designed to be:
+
+1. Generic: for better or worse, there are many C++ string classes out there, and the library should work with as many of them as possible.
+2. Portable: the library should be portable both accross different platforms and compilers. The only non-portable code is a small section that declares unsigned integers of different sizes: three typedefs. They can be changed by the users of the library if they don't match their platform. The default setting should work for Windows (both 32 and 64 bit), and most 32 bit and 64 bit Unix derivatives. Support for post C++03 language features is included for modern compilers at API level only, so the library should work even with pretty old compilers.
+3. Lightweight: follow the "pay only for what you use" guideline.
+4. Unintrusive: avoid forcing any particular design or even programming style on the user. This is a library, not a framework.
+
+#### Alternatives
+
+In case you want to look into other means of working with UTF-8 strings from C++, here is the list of solutions I am aware of:
+
+1. [ICU Library](http://icu.sourceforge.net/). It is very powerful, complete, feature-rich, mature, and widely used. Also big, intrusive, non-generic, and doesn't play well with the Standard Library. I definitelly recommend looking at ICU even if you don't plan to use it.
+2. C++11 language and library features. Still far from complete, and not easy to use.
+3. [Glib::ustring](http://www.gtkmm.org/gtkmm2/docs/tutorial/html/ch03s04.html). A class specifically made to work with UTF-8 strings, and also feel like `std::string`. If you prefer to have yet another string class in your code, it may be worth a look. Be aware of the licensing issues, though.
+4. Platform dependent solutions: Windows and POSIX have functions to convert strings from one encoding to another. That is only a subset of what my library offers, but if that is all you need it may be good enough.
+
+
+## Reference
+
+### Functions From utf8 Namespace
+
+#### utf8::append
+
+Available in version 3.0 and later. Requires a C++ 11 compliant compiler.
+
+Encodes a 32 bit code point as a UTF-8 sequence of octets and appends the sequence to a UTF-8 string.
+
+```cpp
+void append(char32_t cp, std::string& s);
+```
+
+`cp`: a code point to append to the string.
+`s`: a utf-8 encoded string to append the code point to.
+
+Example of use:
+
+```cpp
+std::string u;
+append(0x0448, u);
+assert (u[0] == char(0xd1) && u[1] == char(0x88) && u.length() == 2);
+```
+
+In case of an invalid code point, a `utf8::invalid_code_point` exception is thrown.
+
+
+#### utf8::append
+
+Available in version 1.0 and later.
+
+Encodes a 32 bit code point as a UTF-8 sequence of octets and appends the sequence to a UTF-8 string.
+
+```cpp
+template <typename octet_iterator>
+octet_iterator append(uint32_t cp, octet_iterator result);
+```
+
+`octet_iterator`: an output iterator.
+`cp`: a 32 bit integer representing a code point to append to the sequence.
+`result`: an output iterator to the place in the sequence where to append the code point.
+Return value: an iterator pointing to the place after the newly appended sequence.
+
+Example of use:
+
+```cpp
+unsigned char u[5] = {0,0,0,0,0};
+unsigned char* end = append(0x0448, u);
+assert (u[0] == 0xd1 && u[1] == 0x88 && u[2] == 0 && u[3] == 0 && u[4] == 0);
+```
+
+Note that `append` does not allocate any memory - it is the burden of the caller to make sure there is enough memory allocated for the operation. To make things more interesting, `append` can add anywhere between 1 and 4 octets to the sequence. In practice, you would most often want to use `std::back_inserter` to ensure that the necessary memory is allocated.
+
+In case of an invalid code point, a `utf8::invalid_code_point` exception is thrown.
+
+#### utf8::next
+
+Available in version 1.0 and later.
+
+Given the iterator to the beginning of the UTF-8 sequence, it returns the code point and moves the iterator to the next position.
+
+```cpp
+template <typename octet_iterator>
+uint32_t next(octet_iterator& it, octet_iterator end);
+```
+
+`octet_iterator`: an input iterator.
+`it`: a reference to an iterator pointing to the beginning of an UTF-8 encoded code point. After the function returns, it is incremented to point to the beginning of the next code point.
+`end`: end of the UTF-8 sequence to be processed. If `it` gets equal to `end` during the extraction of a code point, an `utf8::not_enough_room` exception is thrown.
+Return value: the 32 bit representation of the processed UTF-8 code point.
+
+Example of use:
+
+```cpp
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+char* w = twochars;
+int cp = next(w, twochars + 6);
+assert (cp == 0x65e5);
+assert (w == twochars + 3);
+```
+
+This function is typically used to iterate through a UTF-8 encoded string.
+
+In case of an invalid UTF-8 seqence, a `utf8::invalid_utf8` exception is thrown.
+
+#### utf8::peek_next
+
+Available in version 2.1 and later.
+
+Given the iterator to the beginning of the UTF-8 sequence, it returns the code point for the following sequence without changing the value of the iterator.
+
+```cpp
+template <typename octet_iterator>
+uint32_t peek_next(octet_iterator it, octet_iterator end);
+```
+
+
+`octet_iterator`: an input iterator.
+`it`: an iterator pointing to the beginning of an UTF-8 encoded code point.
+`end`: end of the UTF-8 sequence to be processed. If `it` gets equal to `end` during the extraction of a code point, an `utf8::not_enough_room` exception is thrown.
+Return value: the 32 bit representation of the processed UTF-8 code point.
+
+Example of use:
+
+```cpp
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+char* w = twochars;
+int cp = peek_next(w, twochars + 6);
+assert (cp == 0x65e5);
+assert (w == twochars);
+```
+
+In case of an invalid UTF-8 seqence, a `utf8::invalid_utf8` exception is thrown.
+
+#### utf8::prior
+
+Available in version 1.02 and later.
+
+Given a reference to an iterator pointing to an octet in a UTF-8 sequence, it decreases the iterator until it hits the beginning of the previous UTF-8 encoded code point and returns the 32 bits representation of the code point.
+
+```cpp
+template <typename octet_iterator>
+uint32_t prior(octet_iterator& it, octet_iterator start);
+```
+
+`octet_iterator`: a bidirectional iterator.
+`it`: a reference pointing to an octet within a UTF-8 encoded string. After the function returns, it is decremented to point to the beginning of the previous code point.
+`start`: an iterator to the beginning of the sequence where the search for the beginning of a code point is performed. It is a safety measure to prevent passing the beginning of the string in the search for a UTF-8 lead octet.
+ Return value: the 32 bit representation of the previous code point.
+
+Example of use:
+
+```cpp
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+unsigned char* w = twochars + 3;
+int cp = prior (w, twochars);
+assert (cp == 0x65e5);
+assert (w == twochars);
+```
+
+This function has two purposes: one is two iterate backwards through a UTF-8 encoded string. Note that it is usually a better idea to iterate forward instead, since `utf8::next` is faster. The second purpose is to find a beginning of a UTF-8 sequence if we have a random position within a string. Note that in that case `utf8::prior` may not detect an invalid UTF-8 sequence in some scenarios: for instance if there are superfluous trail octets, it will just skip them.
+
+`it` will typically point to the beginning of a code point, and `start` will point to the beginning of the string to ensure we don't go backwards too far. `it` is decreased until it points to a lead UTF-8 octet, and then the UTF-8 sequence beginning with that octet is decoded to a 32 bit representation and returned.
+
+In case `start` is reached before a UTF-8 lead octet is hit, or if an invalid UTF-8 sequence is started by the lead octet, an `invalid_utf8` exception is thrown.
+
+In case `start` equals `it`, a `not_enough_room` exception is thrown.
+
+#### utf8::advance
+Available in version 1.0 and later.
+
+Advances an iterator by the specified number of code points within an UTF-8 sequence.
+
+```cpp
+template <typename octet_iterator, typename distance_type>
+void advance (octet_iterator& it, distance_type n, octet_iterator end);
+```
+
+`octet_iterator`: an input iterator.
+`distance_type`: an integral type convertible to `octet_iterator`'s difference type.
+`it`: a reference to an iterator pointing to the beginning of an UTF-8 encoded code point. After the function returns, it is incremented to point to the nth following code point.
+`n`: number of code points `it` should be advanced. A negative value means decrement.
+`end`: limit of the UTF-8 sequence to be processed. If `n` is positive and `it` gets equal to `end` during the extraction of a code point, an `utf8::not_enough_room` exception is thrown. If `n` is negative and `it` reaches `end` while `it` points t a trail byte of a UTF-8 sequence, a `utf8::invalid_code_point` exception is thrown.
+
+Example of use:
+
+```cpp
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+unsigned char* w = twochars;
+advance (w, 2, twochars + 6);
+assert (w == twochars + 5);
+advance (w, -2, twochars);
+assert (w == twochars);
+```
+
+In case of an invalid code point, a `utf8::invalid_code_point` exception is thrown.
+
+#### utf8::distance
+
+Available in version 1.0 and later.
+
+Given the iterators to two UTF-8 encoded code points in a seqence, returns the number of code points between them.
+
+```cpp
+template <typename octet_iterator>
+typename std::iterator_traits<octet_iterator>::difference_type distance (octet_iterator first, octet_iterator last);
+```
+
+`octet_iterator`: an input iterator.
+`first`: an iterator to a beginning of a UTF-8 encoded code point.
+`last`: an iterator to a "post-end" of the last UTF-8 encoded code point in the sequence we are trying to determine the length. It can be the beginning of a new code point, or not.
+ Return value the distance between the iterators, in code points.
+
+Example of use:
+
+```cpp
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+size_t dist = utf8::distance(twochars, twochars + 5);
+assert (dist == 2);
+```
+
+This function is used to find the length (in code points) of a UTF-8 encoded string. The reason it is called _distance_, rather than, say, _length_ is mainly because developers are used that _length_ is an O(1) function. Computing the length of an UTF-8 string is a linear operation, and it looked better to model it after `std::distance` algorithm.
+
+In case of an invalid UTF-8 seqence, a `utf8::invalid_utf8` exception is thrown. If `last` does not point to the past-of-end of a UTF-8 seqence, a `utf8::not_enough_room` exception is thrown.
+
+#### utf8::utf16to8
+
+Available in version 3.0 and later. Requires a C++ 11 compliant compiler.
+
+Converts a UTF-16 encoded string to UTF-8.
+
+```cpp
+std::string utf16to8(const std::u16string& s);
+```
+
+`s`: a UTF-16 encoded string.
+Return value: A UTF-8 encoded string.
+
+Example of use:
+
+```cpp
+ u16string utf16string = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e};
+ string u = utf16to8(utf16string);
+ assert (u.size() == 10);
+```
+
+In case of invalid UTF-16 sequence, a `utf8::invalid_utf16` exception is thrown.
+
+#### utf8::utf16to8
+
+Available in version 3.2 and later. Requires a C++ 17 compliant compiler.
+
+Converts a UTF-16 encoded string to UTF-8.
+
+```cpp
+std::string utf16to8(std::u16string_view s);
+```
+
+`s`: a UTF-16 encoded string.
+Return value: A UTF-8 encoded string.
+
+Example of use:
+
+```cpp
+ u16string utf16string = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e};
+ u16string_view utf16stringview(u16string);
+ string u = utf16to8(utf16string);
+ assert (u.size() == 10);
+```
+
+In case of invalid UTF-16 sequence, a `utf8::invalid_utf16` exception is thrown.
+
+
+#### utf8::utf16to8
+
+Available in version 1.0 and later.
+
+Converts a UTF-16 encoded string to UTF-8.
+
+```cpp
+template <typename u16bit_iterator, typename octet_iterator>
+octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result);
+```
+
+`u16bit_iterator`: an input iterator.
+`octet_iterator`: an output iterator.
+`start`: an iterator pointing to the beginning of the UTF-16 encoded string to convert.
+`end`: an iterator pointing to pass-the-end of the UTF-16 encoded string to convert.
+`result`: an output iterator to the place in the UTF-8 string where to append the result of conversion.
+Return value: An iterator pointing to the place after the appended UTF-8 string.
+
+Example of use:
+
+```cpp
+unsigned short utf16string[] = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e};
+vector<unsigned char> utf8result;
+utf16to8(utf16string, utf16string + 5, back_inserter(utf8result));
+assert (utf8result.size() == 10);
+```
+
+In case of invalid UTF-16 sequence, a `utf8::invalid_utf16` exception is thrown.
+
+#### utf8::utf8to16
+
+Available in version 3.0 and later. Requires a C++ 11 compliant compiler.
+
+Converts an UTF-8 encoded string to UTF-16.
+
+```cpp
+std::u16string utf8to16(const std::string& s);
+```
+
+`s`: an UTF-8 encoded string to convert.
+Return value: A UTF-16 encoded string
+
+Example of use:
+
+```cpp
+string utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e";
+u16string utf16result = utf8to16(utf8_with_surrogates);
+assert (utf16result.length() == 4);
+assert (utf16result[2] == 0xd834);
+assert (utf16result[3] == 0xdd1e);
+```
+
+In case of an invalid UTF-8 seqence, a `utf8::invalid_utf8` exception is thrown.
+
+#### utf8::utf8to16
+
+Available in version 3.2 and later. Requires a C++ 17 compliant compiler.
+
+Converts an UTF-8 encoded string to UTF-16.
+
+```cpp
+std::u16string utf8to16(std::string_view s);
+```
+
+`s`: an UTF-8 encoded string to convert.
+Return value: A UTF-16 encoded string
+
+Example of use:
+
+```cpp
+string_view utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e";
+u16string utf16result = utf8to16(utf8_with_surrogates);
+assert (utf16result.length() == 4);
+assert (utf16result[2] == 0xd834);
+assert (utf16result[3] == 0xdd1e);
+```
+
+In case of an invalid UTF-8 seqence, a `utf8::invalid_utf8` exception is thrown.
+
+
+#### utf8::utf8to16
+
+Available in version 1.0 and later.
+
+Converts an UTF-8 encoded string to UTF-16
+
+```cpp
+template <typename u16bit_iterator, typename octet_iterator>
+u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result);
+```
+
+`octet_iterator`: an input iterator.
+`u16bit_iterator`: an output iterator.
+`start`: an iterator pointing to the beginning of the UTF-8 encoded string to convert. < br /> `end`: an iterator pointing to pass-the-end of the UTF-8 encoded string to convert.
+`result`: an output iterator to the place in the UTF-16 string where to append the result of conversion.
+Return value: An iterator pointing to the place after the appended UTF-16 string.
+
+Example of use:
+
+```cpp
+char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e";
+vector <unsigned short> utf16result;
+utf8to16(utf8_with_surrogates, utf8_with_surrogates + 9, back_inserter(utf16result));
+assert (utf16result.size() == 4);
+assert (utf16result[2] == 0xd834);
+assert (utf16result[3] == 0xdd1e);
+```
+
+In case of an invalid UTF-8 seqence, a `utf8::invalid_utf8` exception is thrown. If `end` does not point to the past-of-end of a UTF-8 seqence, a `utf8::not_enough_room` exception is thrown.
+
+#### utf8::utf32to8
+
+Available in version 3.0 and later. Requires a C++ 11 compliant compiler.
+
+Converts a UTF-32 encoded string to UTF-8.
+
+```cpp
+std::string utf32to8(const std::u32string& s);
+```
+
+`s`: a UTF-32 encoded string.
+Return value: a UTF-8 encoded string.
+
+Example of use:
+
+```cpp
+u32string utf32string = {0x448, 0x65E5, 0x10346};
+string utf8result = utf32to8(utf32string);
+assert (utf8result.size() == 9);
+```
+
+In case of invalid UTF-32 string, a `utf8::invalid_code_point` exception is thrown.
+
+#### utf8::utf32to8
+
+Available in version 3.2 and later. Requires a C++ 17 compliant compiler.
+
+Converts a UTF-32 encoded string to UTF-8.
+
+```cpp
+std::string utf32to8(std::u32string_view s);
+```
+
+`s`: a UTF-32 encoded string.
+Return value: a UTF-8 encoded string.
+
+Example of use:
+
+```cpp
+u32string utf32string = {0x448, 0x65E5, 0x10346};
+u32string_view utf32stringview(utf32string);
+string utf8result = utf32to8(utf32stringview);
+assert (utf8result.size() == 9);
+```
+
+In case of invalid UTF-32 string, a `utf8::invalid_code_point` exception is thrown.
+
+
+#### utf8::utf32to8
+
+Available in version 1.0 and later.
+
+Converts a UTF-32 encoded string to UTF-8.
+
+```cpp
+template <typename octet_iterator, typename u32bit_iterator>
+octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result);
+```
+
+`octet_iterator`: an output iterator.
+`u32bit_iterator`: an input iterator.
+`start`: an iterator pointing to the beginning of the UTF-32 encoded string to convert.
+`end`: an iterator pointing to pass-the-end of the UTF-32 encoded string to convert.
+`result`: an output iterator to the place in the UTF-8 string where to append the result of conversion.
+Return value: An iterator pointing to the place after the appended UTF-8 string.
+
+Example of use:
+
+```cpp
+int utf32string[] = {0x448, 0x65E5, 0x10346, 0};
+vector<unsigned char> utf8result;
+utf32to8(utf32string, utf32string + 3, back_inserter(utf8result));
+assert (utf8result.size() == 9);
+```
+
+In case of invalid UTF-32 string, a `utf8::invalid_code_point` exception is thrown.
+
+#### utf8::utf8to32
+
+Available in version 3.0 and later. Requires a C++ 11 compliant compiler.
+
+Converts a UTF-8 encoded string to UTF-32.
+
+```cpp
+std::u32string utf8to32(const std::string& s);
+```
+
+`s`: a UTF-8 encoded string.
+Return value: a UTF-32 encoded string.
+
+Example of use:
+
+```cpp
+const char* twochars = "\xe6\x97\xa5\xd1\x88";
+u32string utf32result = utf8to32(twochars);
+assert (utf32result.size() == 2);
+```
+
+In case of an invalid UTF-8 seqence, a `utf8::invalid_utf8` exception is thrown.
+
+#### utf8::utf8to32
+
+Available in version 3.2 and later. Requires a C++ 17 compliant compiler.
+
+Converts a UTF-8 encoded string to UTF-32.
+
+```cpp
+std::u32string utf8to32(std::string_view s);
+```
+
+`s`: a UTF-8 encoded string.
+Return value: a UTF-32 encoded string.
+
+Example of use:
+
+```cpp
+string_view twochars = "\xe6\x97\xa5\xd1\x88";
+u32string utf32result = utf8to32(twochars);
+assert (utf32result.size() == 2);
+```
+
+In case of an invalid UTF-8 seqence, a `utf8::invalid_utf8` exception is thrown.
+
+
+#### utf8::utf8to32
+
+Available in version 1.0 and later.
+
+Converts a UTF-8 encoded string to UTF-32.
+
+```cpp
+template <typename octet_iterator, typename u32bit_iterator>
+u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result);
+```
+
+`octet_iterator`: an input iterator.
+`u32bit_iterator`: an output iterator.
+`start`: an iterator pointing to the beginning of the UTF-8 encoded string to convert.
+`end`: an iterator pointing to pass-the-end of the UTF-8 encoded string to convert.
+`result`: an output iterator to the place in the UTF-32 string where to append the result of conversion.
+Return value: An iterator pointing to the place after the appended UTF-32 string.
+
+Example of use:
+
+```cpp
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+vector<int> utf32result;
+utf8to32(twochars, twochars + 5, back_inserter(utf32result));
+assert (utf32result.size() == 2);
+```
+
+In case of an invalid UTF-8 seqence, a `utf8::invalid_utf8` exception is thrown. If `end` does not point to the past-of-end of a UTF-8 seqence, a `utf8::not_enough_room` exception is thrown.
+
+#### utf8::find_invalid
+
+Available in version 3.0 and later. Requires a C++ 11 compliant compiler.
+
+Detects an invalid sequence within a UTF-8 string.
+
+```cpp
+std::size_t find_invalid(const std::string& s);
+```
+
+`s`: a UTF-8 encoded string.
+Return value: the index of the first invalid octet in the UTF-8 string. In case none were found, equals `std::string::npos`.
+
+Example of use:
+
+```cpp
+string utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa";
+auto invalid = find_invalid(utf_invalid);
+assert (invalid == 5);
+```
+
+This function is typically used to make sure a UTF-8 string is valid before processing it with other functions. It is especially important to call it if before doing any of the _unchecked_ operations on it.
+
+#### utf8::find_invalid
+
+Available in version 3.2 and later. Requires a C++ 17 compliant compiler.
+
+Detects an invalid sequence within a UTF-8 string.
+
+```cpp
+std::size_t find_invalid(std::string_view s);
+```
+
+`s`: a UTF-8 encoded string.
+Return value: the index of the first invalid octet in the UTF-8 string. In case none were found, equals `std::string_view::npos`.
+
+Example of use:
+
+```cpp
+string_view utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa";
+auto invalid = find_invalid(utf_invalid);
+assert (invalid == 5);
+```
+
+This function is typically used to make sure a UTF-8 string is valid before processing it with other functions. It is especially important to call it if before doing any of the _unchecked_ operations on it.
+
+
+#### utf8::find_invalid
+
+Available in version 1.0 and later.
+
+Detects an invalid sequence within a UTF-8 string.
+
+```cpp
+template <typename octet_iterator>
+octet_iterator find_invalid(octet_iterator start, octet_iterator end);
+```
+
+`octet_iterator`: an input iterator.
+`start`: an iterator pointing to the beginning of the UTF-8 string to test for validity.
+`end`: an iterator pointing to pass-the-end of the UTF-8 string to test for validity.
+Return value: an iterator pointing to the first invalid octet in the UTF-8 string. In case none were found, equals `end`.
+
+Example of use:
+
+```cpp
+char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa";
+char* invalid = find_invalid(utf_invalid, utf_invalid + 6);
+assert (invalid == utf_invalid + 5);
+```
+
+This function is typically used to make sure a UTF-8 string is valid before processing it with other functions. It is especially important to call it if before doing any of the _unchecked_ operations on it.
+
+#### utf8::is_valid
+
+Available in version 3.0 and later. Requires a C++ 11 compliant compiler.
+
+Checks whether a string object contains valid UTF-8 encoded text.
+
+```cpp
+bool is_valid(const std::string& s);
+```
+
+`s`: a UTF-8 encoded string.
+Return value: `true` if the string contains valid UTF-8 encoded text; `false` if not.
+
+Example of use:
+
+```cpp
+char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa";
+bool bvalid = is_valid(utf_invalid);
+assert (bvalid == false);
+```
+
+You may want to use `is_valid` to make sure that a string contains valid UTF-8 text without the need to know where it fails if it is not valid.
+
+#### utf8::is_valid
+
+Available in version 3.2 and later. Requires a C++ 17 compliant compiler.
+
+Checks whether a string object contains valid UTF-8 encoded text.
+
+```cpp
+bool is_valid(std::string_view s);
+```
+
+`s`: a UTF-8 encoded string.
+Return value: `true` if the string contains valid UTF-8 encoded text; `false` if not.
+
+Example of use:
+
+```cpp
+string_view utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa";
+bool bvalid = is_valid(utf_invalid);
+assert (bvalid == false);
+```
+
+You may want to use `is_valid` to make sure that a string contains valid UTF-8 text without the need to know where it fails if it is not valid.
+
+
+#### utf8::is_valid
+
+Available in version 1.0 and later.
+
+Checks whether a sequence of octets is a valid UTF-8 string.
+
+```cpp
+template <typename octet_iterator>
+bool is_valid(octet_iterator start, octet_iterator end);
+```
+
+`octet_iterator`: an input iterator.
+`start`: an iterator pointing to the beginning of the UTF-8 string to test for validity.
+`end`: an iterator pointing to pass-the-end of the UTF-8 string to test for validity.
+Return value: `true` if the sequence is a valid UTF-8 string; `false` if not.
+
+Example of use:
+
+```cpp
+char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa";
+bool bvalid = is_valid(utf_invalid, utf_invalid + 6);
+assert (bvalid == false);
+```
+
+`is_valid` is a shorthand for `find_invalid(start, end) == end;`. You may want to use it to make sure that a byte seqence is a valid UTF-8 string without the need to know where it fails if it is not valid.
+
+#### utf8::replace_invalid
+
+Available in version 3.0 and later. Requires a C++ 11 compliant compiler.
+
+Replaces all invalid UTF-8 sequences within a string with a replacement marker.
+
+```cpp
+std::string replace_invalid(const std::string& s, char32_t replacement);
+std::string replace_invalid(const std::string& s);
+```
+
+`s`: a UTF-8 encoded string.
+`replacement`: A Unicode code point for the replacement marker. The version without this parameter assumes the value `0xfffd`
+Return value: A UTF-8 encoded string with replaced invalid sequences.
+
+Example of use:
+
+```cpp
+string invalid_sequence = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z";
+string replace_invalid_result = replace_invalid(invalid_sequence, '?');
+bvalid = is_valid(replace_invalid_result);
+assert (bvalid);
+const string fixed_invalid_sequence = "a????z";
+assert (fixed_invalid_sequence == replace_invalid_result);
+```
+
+#### utf8::replace_invalid
+
+Available in version 3.2 and later. Requires a C++ 17 compliant compiler.
+
+Replaces all invalid UTF-8 sequences within a string with a replacement marker.
+
+```cpp
+std::string replace_invalid(std::string_view s, char32_t replacement);
+std::string replace_invalid(std::string_view s);
+```
+
+`s`: a UTF-8 encoded string.
+`replacement`: A Unicode code point for the replacement marker. The version without this parameter assumes the value `0xfffd`
+Return value: A UTF-8 encoded string with replaced invalid sequences.
+
+Example of use:
+
+```cpp
+string_view invalid_sequence = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z";
+string replace_invalid_result = replace_invalid(invalid_sequence, '?');
+bool bvalid = is_valid(replace_invalid_result);
+assert (bvalid);
+const string fixed_invalid_sequence = "a????z";
+assert(fixed_invalid_sequence, replace_invalid_result);
+```
+
+
+#### utf8::replace_invalid
+
+Available in version 2.0 and later.
+
+Replaces all invalid UTF-8 sequences within a string with a replacement marker.
+
+```cpp
+template <typename octet_iterator, typename output_iterator>
+output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement);
+template <typename octet_iterator, typename output_iterator>
+output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out);
+```
+
+`octet_iterator`: an input iterator.
+`output_iterator`: an output iterator.
+`start`: an iterator pointing to the beginning of the UTF-8 string to look for invalid UTF-8 sequences.
+`end`: an iterator pointing to pass-the-end of the UTF-8 string to look for invalid UTF-8 sequences.
+`out`: An output iterator to the range where the result of replacement is stored.
+`replacement`: A Unicode code point for the replacement marker. The version without this parameter assumes the value `0xfffd`
+Return value: An iterator pointing to the place after the UTF-8 string with replaced invalid sequences.
+
+Example of use:
+
+```cpp
+char invalid_sequence[] = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z";
+vector<char> replace_invalid_result;
+replace_invalid (invalid_sequence, invalid_sequence + sizeof(invalid_sequence), back_inserter(replace_invalid_result), '?');
+bvalid = is_valid(replace_invalid_result.begin(), replace_invalid_result.end());
+assert (bvalid);
+char* fixed_invalid_sequence = "a????z";
+assert (std::equal(replace_invalid_result.begin(), replace_invalid_result.end(), fixed_invalid_sequence));
+```
+
+`replace_invalid` does not perform in-place replacement of invalid sequences. Rather, it produces a copy of the original string with the invalid sequences replaced with a replacement marker. Therefore, `out` must not be in the `[start, end]` range.
+
+#### utf8::starts_with_bom
+
+Available in version 3.0 and later. Requires a C++ 11 compliant compiler.
+
+Checks whether a string starts with a UTF-8 byte order mark (BOM)
+
+```cpp
+bool starts_with_bom(const std::string& s);
+```
+
+`s`: a UTF-8 encoded string.
+Return value: `true` if the string starts with a UTF-8 byte order mark; `false` if not.
+
+Example of use:
+
+```cpp
+string byte_order_mark = {char(0xef), char(0xbb), char(0xbf)};
+bool bbom = starts_with_bom(byte_order_mark);
+assert (bbom == true);
+string threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+bool no_bbom = starts_with_bom(threechars);
+assert (no_bbom == false);
+ ```
+
+The typical use of this function is to check the first three bytes of a file. If they form the UTF-8 BOM, we want to skip them before processing the actual UTF-8 encoded text.
+
+
+#### utf8::starts_with_bom
+
+Available in version 3.2 and later. Requires a C++ 17 compliant compiler.
+
+Checks whether a string starts with a UTF-8 byte order mark (BOM)
+
+```cpp
+bool starts_with_bom(std::string_view s);
+```
+
+`s`: a UTF-8 encoded string.
+Return value: `true` if the string starts with a UTF-8 byte order mark; `false` if not.
+
+Example of use:
+
+```cpp
+string byte_order_mark = {char(0xef), char(0xbb), char(0xbf)};
+string_view byte_order_mark_view(byte_order_mark);
+bool bbom = starts_with_bom(byte_order_mark_view);
+assert (bbom);
+string_view threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+bool no_bbom = starts_with_bom(threechars);
+assert (!no_bbom);
+ ```
+
+The typical use of this function is to check the first three bytes of a file. If they form the UTF-8 BOM, we want to skip them before processing the actual UTF-8 encoded text.
+
+
+#### utf8::starts_with_bom
+
+Available in version 2.3 and later.
+
+Checks whether an octet sequence starts with a UTF-8 byte order mark (BOM)
+
+```cpp
+template <typename octet_iterator>
+bool starts_with_bom (octet_iterator it, octet_iterator end);
+```
+
+`octet_iterator`: an input iterator.
+`it`: beginning of the octet sequence to check
+`end`: pass-end of the sequence to check
+Return value: `true` if the sequence starts with a UTF-8 byte order mark; `false` if not.
+
+Example of use:
+
+```cpp
+unsigned char byte_order_mark[] = {0xef, 0xbb, 0xbf};
+bool bbom = starts_with_bom(byte_order_mark, byte_order_mark + sizeof(byte_order_mark));
+assert (bbom == true);
+```
+
+The typical use of this function is to check the first three bytes of a file. If they form the UTF-8 BOM, we want to skip them before processing the actual UTF-8 encoded text.
+
+### Types From utf8 Namespace
+
+#### utf8::exception
+
+Available in version 2.3 and later.
+
+Base class for the exceptions thrown by UTF CPP library functions.
+
+```cpp
+class exception : public std::exception {};
+```
+
+Example of use:
+
+```cpp
+try {
+ code_that_uses_utf_cpp_library();
+}
+catch(const utf8::exception& utfcpp_ex) {
+ cerr << utfcpp_ex.what();
+}
+```
+
+#### utf8::invalid_code_point
+
+Available in version 1.0 and later.
+
+Thrown by UTF8 CPP functions such as `advance` and `next` if an UTF-8 sequence represents and invalid code point.
+
+```cpp
+class invalid_code_point : public exception {
+public:
+ uint32_t code_point() const;
+};
+```
+
+Member function `code_point()` can be used to determine the invalid code point that caused the exception to be thrown.
+
+#### utf8::invalid_utf8
+
+Available in version 1.0 and later.
+
+Thrown by UTF8 CPP functions such as `next` and `prior` if an invalid UTF-8 sequence is detected during decoding.
+
+```cpp
+class invalid_utf8 : public exception {
+public:
+ uint8_t utf8_octet() const;
+};
+```
+
+Member function `utf8_octet()` can be used to determine the beginning of the byte sequence that caused the exception to be thrown.
+
+#### utf8::invalid_utf16
+
+Available in version 1.0 and later.
+
+Thrown by UTF8 CPP function `utf16to8` if an invalid UTF-16 sequence is detected during decoding.
+
+```cpp
+class invalid_utf16 : public exception {
+public:
+ uint16_t utf16_word() const;
+};
+```
+
+Member function `utf16_word()` can be used to determine the UTF-16 code unit that caused the exception to be thrown.
+
+#### utf8::not_enough_room
+
+Available in version 1.0 and later.
+
+Thrown by UTF8 CPP functions such as `next` if the end of the decoded UTF-8 sequence was reached before the code point was decoded.
+
+```cpp
+class not_enough_room : public exception {};
+```
+
+#### utf8::iterator
+
+Available in version 2.0 and later.
+
+Adapts the underlying octet iterator to iterate over the sequence of code points, rather than raw octets.
+
+```cpp
+template <typename octet_iterator>
+class iterator;
+```
+
+##### Member functions
+
+`iterator();` the deafult constructor; the underlying octet_iterator is constructed with its default constructor.
+
+`explicit iterator (const octet_iterator& octet_it, const octet_iterator& range_start, const octet_iterator& range_end);` a constructor that initializes the underlying octet_iterator with octet_it and sets the range in which the iterator is considered valid.
+
+`octet_iterator base () const;` returns the underlying octet_iterator.
+
+`uint32_t operator * () const;` decodes the utf-8 sequence the underlying octet_iterator is pointing to and returns the code point.
+
+`bool operator == (const iterator& rhs) const;` returns `true` if the two underlaying iterators are equal.
+
+`bool operator != (const iterator& rhs) const;` returns `true` if the two underlaying iterators are not equal.
+
+`iterator& operator ++ ();` the prefix increment - moves the iterator to the next UTF-8 encoded code point.
+
+`iterator operator ++ (int);` the postfix increment - moves the iterator to the next UTF-8 encoded code point and returns the current one.
+
+`iterator& operator -- ();` the prefix decrement - moves the iterator to the previous UTF-8 encoded code point.
+
+`iterator operator -- (int);` the postfix decrement - moves the iterator to the previous UTF-8 encoded code point and returns the current one.
+
+Example of use:
+
+```cpp
+char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+utf8::iterator<char*> it(threechars, threechars, threechars + 9);
+utf8::iterator<char*> it2 = it;
+assert (it2 == it);
+assert (*it == 0x10346);
+assert (*(++it) == 0x65e5);
+assert ((*it++) == 0x65e5);
+assert (*it == 0x0448);
+assert (it != it2);
+utf8::iterator<char*> endit (threechars + 9, threechars, threechars + 9);
+assert (++it == endit);
+assert (*(--it) == 0x0448);
+assert ((*it--) == 0x0448);
+assert (*it == 0x65e5);
+assert (--it == utf8::iterator<char*>(threechars, threechars, threechars + 9));
+assert (*it == 0x10346);
+```
+
+The purpose of `utf8::iterator` adapter is to enable easy iteration as well as the use of STL algorithms with UTF-8 encoded strings. Increment and decrement operators are implemented in terms of `utf8::next()` and `utf8::prior()` functions.
+
+Note that `utf8::iterator` adapter is a checked iterator. It operates on the range specified in the constructor; any attempt to go out of that range will result in an exception. Even the comparison operators require both iterator object to be constructed against the same range - otherwise an exception is thrown. Typically, the range will be determined by sequence container functions `begin` and `end`, i.e.:
+
+```cpp
+std::string s = "example";
+utf8::iterator i (s.begin(), s.begin(), s.end());
+```
+
+### Functions From utf8::unchecked Namespace
+
+#### utf8::unchecked::append
+
+Available in version 1.0 and later.
+
+Encodes a 32 bit code point as a UTF-8 sequence of octets and appends the sequence to a UTF-8 string.
+
+```cpp
+template <typename octet_iterator>
+octet_iterator append(uint32_t cp, octet_iterator result);
+```
+
+`cp`: A 32 bit integer representing a code point to append to the sequence.
+`result`: An output iterator to the place in the sequence where to append the code point.
+Return value: An iterator pointing to the place after the newly appended sequence.
+
+Example of use:
+
+```cpp
+unsigned char u[5] = {0,0,0,0,0};
+unsigned char* end = unchecked::append(0x0448, u);
+assert (u[0] == 0xd1 && u[1] == 0x88 && u[2] == 0 && u[3] == 0 && u[4] == 0);
+```
+
+This is a faster but less safe version of `utf8::append`. It does not check for validity of the supplied code point, and may produce an invalid UTF-8 sequence.
+
+#### utf8::unchecked::next
+
+Available in version 1.0 and later.
+
+Given the iterator to the beginning of a UTF-8 sequence, it returns the code point and moves the iterator to the next position.
+
+```cpp
+template <typename octet_iterator>
+uint32_t next(octet_iterator& it);
+```
+
+`it`: a reference to an iterator pointing to the beginning of an UTF-8 encoded code point. After the function returns, it is incremented to point to the beginning of the next code point.
+ Return value: the 32 bit representation of the processed UTF-8 code point.
+
+Example of use:
+
+```cpp
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+char* w = twochars;
+int cp = unchecked::next(w);
+assert (cp == 0x65e5);
+assert (w == twochars + 3);
+```
+
+This is a faster but less safe version of `utf8::next`. It does not check for validity of the supplied UTF-8 sequence.
+
+#### utf8::unchecked::peek_next
+
+Available in version 2.1 and later.
+
+Given the iterator to the beginning of a UTF-8 sequence, it returns the code point.
+
+```cpp
+template <typename octet_iterator>
+uint32_t peek_next(octet_iterator it);
+```
+
+`it`: an iterator pointing to the beginning of an UTF-8 encoded code point.
+Return value: the 32 bit representation of the processed UTF-8 code point.
+
+Example of use:
+
+```cpp
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+char* w = twochars;
+int cp = unchecked::peek_next(w);
+assert (cp == 0x65e5);
+assert (w == twochars);
+```
+
+This is a faster but less safe version of `utf8::peek_next`. It does not check for validity of the supplied UTF-8 sequence.
+
+#### utf8::unchecked::prior
+
+Available in version 1.02 and later.
+
+Given a reference to an iterator pointing to an octet in a UTF-8 seqence, it decreases the iterator until it hits the beginning of the previous UTF-8 encoded code point and returns the 32 bits representation of the code point.
+
+```cpp
+template <typename octet_iterator>
+uint32_t prior(octet_iterator& it);
+```
+
+`it`: a reference pointing to an octet within a UTF-8 encoded string. After the function returns, it is decremented to point to the beginning of the previous code point.
+ Return value: the 32 bit representation of the previous code point.
+
+Example of use:
+
+```cpp
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+char* w = twochars + 3;
+int cp = unchecked::prior (w);
+assert (cp == 0x65e5);
+assert (w == twochars);
+```
+
+This is a faster but less safe version of `utf8::prior`. It does not check for validity of the supplied UTF-8 sequence and offers no boundary checking.
+
+#### utf8::unchecked::advance
+
+Available in version 1.0 and later.
+
+Advances an iterator by the specified number of code points within an UTF-8 sequence.
+
+```cpp
+template <typename octet_iterator, typename distance_type>
+void advance (octet_iterator& it, distance_type n);
+```
+
+`it`: a reference to an iterator pointing to the beginning of an UTF-8 encoded code point. After the function returns, it is incremented to point to the nth following code point.
+`n`: number of code points `it` should be advanced. A negative value means decrement.
+
+Example of use:
+
+```cpp
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+char* w = twochars;
+unchecked::advance (w, 2);
+assert (w == twochars + 5);
+```
+
+This is a faster but less safe version of `utf8::advance`. It does not check for validity of the supplied UTF-8 sequence and offers no boundary checking.
+
+#### utf8::unchecked::distance
+
+Available in version 1.0 and later.
+
+Given the iterators to two UTF-8 encoded code points in a seqence, returns the number of code points between them.
+
+```cpp
+template <typename octet_iterator>
+typename std::iterator_traits<octet_iterator>::difference_type distance (octet_iterator first, octet_iterator last);
+```
+
+`first`: an iterator to a beginning of a UTF-8 encoded code point.
+`last`: an iterator to a "post-end" of the last UTF-8 encoded code point in the sequence we are trying to determine the length. It can be the beginning of a new code point, or not.
+Return value: the distance between the iterators, in code points.
+
+Example of use:
+
+```cpp
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+size_t dist = utf8::unchecked::distance(twochars, twochars + 5);
+assert (dist == 2);
+```
+
+This is a faster but less safe version of `utf8::distance`. It does not check for validity of the supplied UTF-8 sequence.
+
+#### utf8::unchecked::utf16to8
+
+Available in version 1.0 and later.
+
+Converts a UTF-16 encoded string to UTF-8.
+
+```cpp
+template <typename u16bit_iterator, typename octet_iterator>
+octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result);
+```
+
+`start`: an iterator pointing to the beginning of the UTF-16 encoded string to convert.
+`end`: an iterator pointing to pass-the-end of the UTF-16 encoded string to convert.
+`result`: an output iterator to the place in the UTF-8 string where to append the result of conversion.
+Return value: An iterator pointing to the place after the appended UTF-8 string.
+
+Example of use:
+
+```cpp
+unsigned short utf16string[] = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e};
+vector<unsigned char> utf8result;
+unchecked::utf16to8(utf16string, utf16string + 5, back_inserter(utf8result));
+assert (utf8result.size() == 10);
+```
+
+This is a faster but less safe version of `utf8::utf16to8`. It does not check for validity of the supplied UTF-16 sequence.
+
+#### utf8::unchecked::utf8to16
+
+Available in version 1.0 and later.
+
+Converts an UTF-8 encoded string to UTF-16
+
+```cpp
+template <typename u16bit_iterator, typename octet_iterator>
+u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result);
+```
+
+`start`: an iterator pointing to the beginning of the UTF-8 encoded string to convert. < br /> `end`: an iterator pointing to pass-the-end of the UTF-8 encoded string to convert.
+`result`: an output iterator to the place in the UTF-16 string where to append the result of conversion.
+Return value: An iterator pointing to the place after the appended UTF-16 string.
+
+Example of use:
+
+```cpp
+char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e";
+vector <unsigned short> utf16result;
+unchecked::utf8to16(utf8_with_surrogates, utf8_with_surrogates + 9, back_inserter(utf16result));
+assert (utf16result.size() == 4);
+assert (utf16result[2] == 0xd834);
+assert (utf16result[3] == 0xdd1e);
+```
+
+This is a faster but less safe version of `utf8::utf8to16`. It does not check for validity of the supplied UTF-8 sequence.
+
+#### utf8::unchecked::utf32to8
+
+Available in version 1.0 and later.
+
+Converts a UTF-32 encoded string to UTF-8.
+
+```cpp
+template <typename octet_iterator, typename u32bit_iterator>
+octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result);
+```
+
+`start`: an iterator pointing to the beginning of the UTF-32 encoded string to convert.
+`end`: an iterator pointing to pass-the-end of the UTF-32 encoded string to convert.
+`result`: an output iterator to the place in the UTF-8 string where to append the result of conversion.
+Return value: An iterator pointing to the place after the appended UTF-8 string.
+
+Example of use:
+
+```cpp
+int utf32string[] = {0x448, 0x65e5, 0x10346, 0};
+vector<unsigned char> utf8result;
+utf32to8(utf32string, utf32string + 3, back_inserter(utf8result));
+assert (utf8result.size() == 9);
+```
+
+This is a faster but less safe version of `utf8::utf32to8`. It does not check for validity of the supplied UTF-32 sequence.
+
+#### utf8::unchecked::utf8to32
+
+Available in version 1.0 and later.
+
+Converts a UTF-8 encoded string to UTF-32.
+
+```cpp
+template <typename octet_iterator, typename u32bit_iterator>
+u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result);
+```
+
+`start`: an iterator pointing to the beginning of the UTF-8 encoded string to convert.
+`end`: an iterator pointing to pass-the-end of the UTF-8 encoded string to convert.
+`result`: an output iterator to the place in the UTF-32 string where to append the result of conversion.
+Return value: An iterator pointing to the place after the appended UTF-32 string.
+
+Example of use:
+
+```cpp
+char* twochars = "\xe6\x97\xa5\xd1\x88";
+vector<int> utf32result;
+unchecked::utf8to32(twochars, twochars + 5, back_inserter(utf32result));
+assert (utf32result.size() == 2);
+```
+
+This is a faster but less safe version of `utf8::utf8to32`. It does not check for validity of the supplied UTF-8 sequence.
+
+#### utf8::unchecked::replace_invalid
+
+Available in version 3.1 and later.
+
+Replaces all invalid UTF-8 sequences within a string with a replacement marker.
+
+```cpp
+template <typename octet_iterator, typename output_iterator>
+output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement);
+template <typename octet_iterator, typename output_iterator>
+output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out);
+```
+
+`octet_iterator`: an input iterator.
+`output_iterator`: an output iterator.
+`start`: an iterator pointing to the beginning of the UTF-8 string to look for invalid UTF-8 sequences.
+`end`: an iterator pointing to pass-the-end of the UTF-8 string to look for invalid UTF-8 sequences.
+`out`: An output iterator to the range where the result of replacement is stored.
+`replacement`: A Unicode code point for the replacement marker. The version without this parameter assumes the value `0xfffd`
+Return value: An iterator pointing to the place after the UTF-8 string with replaced invalid sequences.
+
+Example of use:
+
+```cpp
+char invalid_sequence[] = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z";
+vector<char> replace_invalid_result;
+unchecked::replace_invalid (invalid_sequence, invalid_sequence + sizeof(invalid_sequence), back_inserter(replace_invalid_result), '?');
+bvalid = utf8::is_valid(replace_invalid_result.begin(), replace_invalid_result.end());
+assert (bvalid);
+char* fixed_invalid_sequence = "a????z";
+assert (std::equal(replace_invalid_result.begin(), replace_invalid_result.end(), fixed_invalid_sequence));
+```
+
+`replace_invalid` does not perform in-place replacement of invalid sequences. Rather, it produces a copy of the original string with the invalid sequences replaced with a replacement marker. Therefore, `out` must not be in the `[start, end]` range.
+
+Unlike `utf8::replace_invalid`, this function does not verify validity of the replacement marker.
+
+### Types From utf8::unchecked Namespace
+
+#### utf8::iterator
+
+Available in version 2.0 and later.
+
+Adapts the underlying octet iterator to iterate over the sequence of code points, rather than raw octets.
+
+```cpp
+template <typename octet_iterator>
+class iterator;
+```
+
+##### Member functions
+
+`iterator();` the deafult constructor; the underlying octet_iterator is constructed with its default constructor.
+
+`explicit iterator (const octet_iterator& octet_it);` a constructor that initializes the underlying octet_iterator with `octet_it`.
+
+`octet_iterator base () const;` returns the underlying octet_iterator.
+
+`uint32_t operator * () const;` decodes the utf-8 sequence the underlying octet_iterator is pointing to and returns the code point.
+
+`bool operator == (const iterator& rhs) const;` returns `true` if the two underlaying iterators are equal.
+
+`bool operator != (const iterator& rhs) const;` returns `true` if the two underlaying iterators are not equal.
+
+`iterator& operator ++ ();` the prefix increment - moves the iterator to the next UTF-8 encoded code point.
+
+`iterator operator ++ (int);` the postfix increment - moves the iterator to the next UTF-8 encoded code point and returns the current one.
+
+`iterator& operator -- ();` the prefix decrement - moves the iterator to the previous UTF-8 encoded code point.
+
+`iterator operator -- (int);` the postfix decrement - moves the iterator to the previous UTF-8 encoded code point and returns the current one.
+
+Example of use:
+
+```cpp
+char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+utf8::unchecked::iterator<char*> un_it(threechars);
+utf8::unchecked::iterator<char*> un_it2 = un_it;
+assert (un_it2 == un_it);
+assert (*un_it == 0x10346);
+assert (*(++un_it) == 0x65e5);
+assert ((*un_it++) == 0x65e5);
+assert (*un_it == 0x0448);
+assert (un_it != un_it2);
+utf8::::unchecked::iterator<char*> un_endit (threechars + 9);
+assert (++un_it == un_endit);
+assert (*(--un_it) == 0x0448);
+assert ((*un_it--) == 0x0448);
+assert (*un_it == 0x65e5);
+assert (--un_it == utf8::unchecked::iterator<char*>(threechars));
+assert (*un_it == 0x10346);
+```
+
+This is an unchecked version of `utf8::iterator`. It is faster in many cases, but offers no validity or range checks.
+
+## Links
+
+1. [The Unicode Consortium](http://www.unicode.org/).
+2. [ICU Library](http://icu.sourceforge.net/).
+3. [UTF-8 at Wikipedia](http://en.wikipedia.org/wiki/UTF-8)
+4. [UTF-8 and Unicode FAQ for Unix/Linux](http://www.cl.cam.ac.uk/~mgk25/unicode.html)
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/samples/docsample.cpp b/graphics/asymptote/LspCpp/third_party/utfcpp/samples/docsample.cpp
new file mode 100644
index 0000000000..6533887253
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/samples/docsample.cpp
@@ -0,0 +1,64 @@
+#include "../source/utf8.h"
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+
+using namespace std;
+
+int main(int argc, char** argv)
+{
+ if (argc != 2) {
+ cout << "\nUsage: docsample filename\n";
+ return 0;
+ }
+ const char* test_file_path = argv[1];
+ // Open the test file (must be UTF-8 encoded)
+ ifstream fs8(test_file_path);
+ if (!fs8.is_open()) {
+ cout << "Could not open " << test_file_path << endl;
+ return 0;
+ }
+
+ unsigned line_count = 1;
+ string line;
+ // Play with all the lines in the file
+ while (getline(fs8, line)) {
+ // check for invalid utf-8 (for a simple yes/no check, there is also utf8::is_valid function)
+#if __cplusplus >= 201103L // C++ 11 or later
+ auto end_it = utf8::find_invalid(line.begin(), line.end());
+#else
+ string::iterator end_it = utf8::find_invalid(line.begin(), line.end());
+#endif // C++ 11
+ if (end_it != line.end()) {
+ cout << "Invalid UTF-8 encoding detected at line " << line_count << "\n";
+ cout << "This part is fine: " << string(line.begin(), end_it) << "\n";
+ }
+ // Get the line length (at least for the valid part)
+ ptrdiff_t length = utf8::distance(line.begin(), end_it);
+ cout << "Length of line " << line_count << " is " << length << "\n";
+
+ // Convert it to utf-16
+#if __cplusplus >= 201103L // C++ 11 or later
+ u16string utf16line = utf8::utf8to16(line);
+#else
+ vector<unsigned short> utf16line;
+ utf8::utf8to16(line.begin(), end_it, back_inserter(utf16line));
+#endif // C++ 11
+ // And back to utf-8;
+#if __cplusplus >= 201103L // C++ 11 or later
+ string utf8line = utf8::utf16to8(utf16line);
+#else
+ string utf8line;
+ utf8::utf16to8(utf16line.begin(), utf16line.end(), back_inserter(utf8line));
+#endif // C++ 11
+ // Confirm that the conversion went OK:
+ if (utf8line != string(line.begin(), end_it))
+ cout << "Error in UTF-16 conversion at line: " << line_count << "\n";
+
+ line_count++;
+ }
+
+ return 0;
+}
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8.h b/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8.h
new file mode 100644
index 0000000000..82b13f59f9
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8.h
@@ -0,0 +1,34 @@
+// Copyright 2006 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
+#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
+
+#include "utf8/checked.h"
+#include "utf8/unchecked.h"
+
+#endif // header guard
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/checked.h b/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/checked.h
new file mode 100644
index 0000000000..993b7f7c5f
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/checked.h
@@ -0,0 +1,335 @@
+// Copyright 2006-2016 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+
+#include "core.h"
+#include <stdexcept>
+
+namespace utf8
+{
+ // Base for the exceptions that may be thrown from the library
+ class exception : public ::std::exception {
+ };
+
+ // Exceptions that may be thrown from the library functions.
+ class invalid_code_point : public exception {
+ uint32_t cp;
+ public:
+ invalid_code_point(uint32_t codepoint) : cp(codepoint) {}
+ virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid code point"; }
+ uint32_t code_point() const {return cp;}
+ };
+
+ class invalid_utf8 : public exception {
+ uint8_t u8;
+ public:
+ invalid_utf8 (uint8_t u) : u8(u) {}
+ virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid UTF-8"; }
+ uint8_t utf8_octet() const {return u8;}
+ };
+
+ class invalid_utf16 : public exception {
+ uint16_t u16;
+ public:
+ invalid_utf16 (uint16_t u) : u16(u) {}
+ virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid UTF-16"; }
+ uint16_t utf16_word() const {return u16;}
+ };
+
+ class not_enough_room : public exception {
+ public:
+ virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Not enough space"; }
+ };
+
+ /// The library API - functions intended to be called by the users
+
+ template <typename octet_iterator>
+ octet_iterator append(uint32_t cp, octet_iterator result)
+ {
+ if (!utf8::internal::is_code_point_valid(cp))
+ throw invalid_code_point(cp);
+
+ if (cp < 0x80) // one octet
+ *(result++) = static_cast<uint8_t>(cp);
+ else if (cp < 0x800) { // two octets
+ *(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ else if (cp < 0x10000) { // three octets
+ *(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
+ *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ else { // four octets
+ *(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
+ *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ return result;
+ }
+
+ template <typename octet_iterator, typename output_iterator>
+ output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
+ {
+ while (start != end) {
+ octet_iterator sequence_start = start;
+ internal::utf_error err_code = utf8::internal::validate_next(start, end);
+ switch (err_code) {
+ case internal::UTF8_OK :
+ for (octet_iterator it = sequence_start; it != start; ++it)
+ *out++ = *it;
+ break;
+ case internal::NOT_ENOUGH_ROOM:
+ out = utf8::append (replacement, out);
+ start = end;
+ break;
+ case internal::INVALID_LEAD:
+ out = utf8::append (replacement, out);
+ ++start;
+ break;
+ case internal::INCOMPLETE_SEQUENCE:
+ case internal::OVERLONG_SEQUENCE:
+ case internal::INVALID_CODE_POINT:
+ out = utf8::append (replacement, out);
+ ++start;
+ // just one replacement mark for the sequence
+ while (start != end && utf8::internal::is_trail(*start))
+ ++start;
+ break;
+ }
+ }
+ return out;
+ }
+
+ template <typename octet_iterator, typename output_iterator>
+ inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
+ {
+ static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
+ return utf8::replace_invalid(start, end, out, replacement_marker);
+ }
+
+ template <typename octet_iterator>
+ uint32_t next(octet_iterator& it, octet_iterator end)
+ {
+ uint32_t cp = 0;
+ internal::utf_error err_code = utf8::internal::validate_next(it, end, cp);
+ switch (err_code) {
+ case internal::UTF8_OK :
+ break;
+ case internal::NOT_ENOUGH_ROOM :
+ throw not_enough_room();
+ case internal::INVALID_LEAD :
+ case internal::INCOMPLETE_SEQUENCE :
+ case internal::OVERLONG_SEQUENCE :
+ throw invalid_utf8(*it);
+ case internal::INVALID_CODE_POINT :
+ throw invalid_code_point(cp);
+ }
+ return cp;
+ }
+
+ template <typename octet_iterator>
+ uint32_t peek_next(octet_iterator it, octet_iterator end)
+ {
+ return utf8::next(it, end);
+ }
+
+ template <typename octet_iterator>
+ uint32_t prior(octet_iterator& it, octet_iterator start)
+ {
+ // can't do much if it == start
+ if (it == start)
+ throw not_enough_room();
+
+ octet_iterator end = it;
+ // Go back until we hit either a lead octet or start
+ while (utf8::internal::is_trail(*(--it)))
+ if (it == start)
+ throw invalid_utf8(*it); // error - no lead byte in the sequence
+ return utf8::peek_next(it, end);
+ }
+
+ template <typename octet_iterator, typename distance_type>
+ void advance (octet_iterator& it, distance_type n, octet_iterator end)
+ {
+ const distance_type zero(0);
+ if (n < zero) {
+ // backward
+ for (distance_type i = n; i < zero; ++i)
+ utf8::prior(it, end);
+ } else {
+ // forward
+ for (distance_type i = zero; i < n; ++i)
+ utf8::next(it, end);
+ }
+ }
+
+ template <typename octet_iterator>
+ typename std::iterator_traits<octet_iterator>::difference_type
+ distance (octet_iterator first, octet_iterator last)
+ {
+ typename std::iterator_traits<octet_iterator>::difference_type dist;
+ for (dist = 0; first < last; ++dist)
+ utf8::next(first, last);
+ return dist;
+ }
+
+ template <typename u16bit_iterator, typename octet_iterator>
+ octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
+ {
+ while (start != end) {
+ uint32_t cp = utf8::internal::mask16(*start++);
+ // Take care of surrogate pairs first
+ if (utf8::internal::is_lead_surrogate(cp)) {
+ if (start != end) {
+ uint32_t trail_surrogate = utf8::internal::mask16(*start++);
+ if (utf8::internal::is_trail_surrogate(trail_surrogate))
+ cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
+ else
+ throw invalid_utf16(static_cast<uint16_t>(trail_surrogate));
+ }
+ else
+ throw invalid_utf16(static_cast<uint16_t>(cp));
+
+ }
+ // Lone trail surrogate
+ else if (utf8::internal::is_trail_surrogate(cp))
+ throw invalid_utf16(static_cast<uint16_t>(cp));
+
+ result = utf8::append(cp, result);
+ }
+ return result;
+ }
+
+ template <typename u16bit_iterator, typename octet_iterator>
+ u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
+ {
+ while (start < end) {
+ uint32_t cp = utf8::next(start, end);
+ if (cp > 0xffff) { //make a surrogate pair
+ *result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
+ *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
+ }
+ else
+ *result++ = static_cast<uint16_t>(cp);
+ }
+ return result;
+ }
+
+ template <typename octet_iterator, typename u32bit_iterator>
+ octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
+ {
+ while (start != end)
+ result = utf8::append(*(start++), result);
+
+ return result;
+ }
+
+ template <typename octet_iterator, typename u32bit_iterator>
+ u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
+ {
+ while (start < end)
+ (*result++) = utf8::next(start, end);
+
+ return result;
+ }
+
+ // The iterator class
+ template <typename octet_iterator>
+ class iterator {
+ octet_iterator it;
+ octet_iterator range_start;
+ octet_iterator range_end;
+ public:
+ typedef uint32_t value_type;
+ typedef uint32_t* pointer;
+ typedef uint32_t& reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::bidirectional_iterator_tag iterator_category;
+ iterator () {}
+ explicit iterator (const octet_iterator& octet_it,
+ const octet_iterator& rangestart,
+ const octet_iterator& rangeend) :
+ it(octet_it), range_start(rangestart), range_end(rangeend)
+ {
+ if (it < range_start || it > range_end)
+ throw std::out_of_range("Invalid utf-8 iterator position");
+ }
+ // the default "big three" are OK
+ octet_iterator base () const { return it; }
+ uint32_t operator * () const
+ {
+ octet_iterator temp = it;
+ return utf8::next(temp, range_end);
+ }
+ bool operator == (const iterator& rhs) const
+ {
+ if (range_start != rhs.range_start || range_end != rhs.range_end)
+ throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
+ return (it == rhs.it);
+ }
+ bool operator != (const iterator& rhs) const
+ {
+ return !(operator == (rhs));
+ }
+ iterator& operator ++ ()
+ {
+ utf8::next(it, range_end);
+ return *this;
+ }
+ iterator operator ++ (int)
+ {
+ iterator temp = *this;
+ utf8::next(it, range_end);
+ return temp;
+ }
+ iterator& operator -- ()
+ {
+ utf8::prior(it, range_start);
+ return *this;
+ }
+ iterator operator -- (int)
+ {
+ iterator temp = *this;
+ utf8::prior(it, range_start);
+ return temp;
+ }
+ }; // class iterator
+
+} // namespace utf8
+
+#if UTF_CPP_CPLUSPLUS >= 201703L // C++ 17 or later
+#include "cpp17.h"
+#elif UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later
+#include "cpp11.h"
+#endif // C++ 11 or later
+
+#endif //header guard
+
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/core.h b/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/core.h
new file mode 100644
index 0000000000..de6199f2a3
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/core.h
@@ -0,0 +1,338 @@
+// Copyright 2006 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+
+#include <iterator>
+
+// Determine the C++ standard version.
+// If the user defines UTF_CPP_CPLUSPLUS, use that.
+// Otherwise, trust the unreliable predefined macro __cplusplus
+
+#if !defined UTF_CPP_CPLUSPLUS
+ #define UTF_CPP_CPLUSPLUS __cplusplus
+#endif
+
+#if UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later
+ #define UTF_CPP_OVERRIDE override
+ #define UTF_CPP_NOEXCEPT noexcept
+#else // C++ 98/03
+ #define UTF_CPP_OVERRIDE
+ #define UTF_CPP_NOEXCEPT throw()
+#endif // C++ 11 or later
+
+
+namespace utf8
+{
+ // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers
+ // You may need to change them to match your system.
+ // These typedefs have the same names as ones from cstdint, or boost/cstdint
+ typedef unsigned char uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+
+// Helper code - not intended to be directly called by the library users. May be changed at any time
+namespace internal
+{
+ // Unicode constants
+ // Leading (high) surrogates: 0xd800 - 0xdbff
+ // Trailing (low) surrogates: 0xdc00 - 0xdfff
+ const uint16_t LEAD_SURROGATE_MIN = 0xd800u;
+ const uint16_t LEAD_SURROGATE_MAX = 0xdbffu;
+ const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;
+ const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;
+ const uint16_t LEAD_OFFSET = 0xd7c0u; // LEAD_SURROGATE_MIN - (0x10000 >> 10)
+ const uint32_t SURROGATE_OFFSET = 0xfca02400u; // 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN
+
+ // Maximum valid value for a Unicode code point
+ const uint32_t CODE_POINT_MAX = 0x0010ffffu;
+
+ template<typename octet_type>
+ inline uint8_t mask8(octet_type oc)
+ {
+ return static_cast<uint8_t>(0xff & oc);
+ }
+ template<typename u16_type>
+ inline uint16_t mask16(u16_type oc)
+ {
+ return static_cast<uint16_t>(0xffff & oc);
+ }
+ template<typename octet_type>
+ inline bool is_trail(octet_type oc)
+ {
+ return ((utf8::internal::mask8(oc) >> 6) == 0x2);
+ }
+
+ template <typename u16>
+ inline bool is_lead_surrogate(u16 cp)
+ {
+ return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);
+ }
+
+ template <typename u16>
+ inline bool is_trail_surrogate(u16 cp)
+ {
+ return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
+ }
+
+ template <typename u16>
+ inline bool is_surrogate(u16 cp)
+ {
+ return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
+ }
+
+ template <typename u32>
+ inline bool is_code_point_valid(u32 cp)
+ {
+ return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp));
+ }
+
+ template <typename octet_iterator>
+ inline typename std::iterator_traits<octet_iterator>::difference_type
+ sequence_length(octet_iterator lead_it)
+ {
+ uint8_t lead = utf8::internal::mask8(*lead_it);
+ if (lead < 0x80)
+ return 1;
+ else if ((lead >> 5) == 0x6)
+ return 2;
+ else if ((lead >> 4) == 0xe)
+ return 3;
+ else if ((lead >> 3) == 0x1e)
+ return 4;
+ else
+ return 0;
+ }
+
+ template <typename octet_difference_type>
+ inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)
+ {
+ if (cp < 0x80) {
+ if (length != 1)
+ return true;
+ }
+ else if (cp < 0x800) {
+ if (length != 2)
+ return true;
+ }
+ else if (cp < 0x10000) {
+ if (length != 3)
+ return true;
+ }
+
+ return false;
+ }
+
+ enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};
+
+ /// Helper for get_sequence_x
+ template <typename octet_iterator>
+ utf_error increase_safely(octet_iterator& it, octet_iterator end)
+ {
+ if (++it == end)
+ return NOT_ENOUGH_ROOM;
+
+ if (!utf8::internal::is_trail(*it))
+ return INCOMPLETE_SEQUENCE;
+
+ return UTF8_OK;
+ }
+
+ #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;}
+
+ /// get_sequence_x functions decode utf-8 sequences of the length x
+ template <typename octet_iterator>
+ utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ if (it == end)
+ return NOT_ENOUGH_ROOM;
+
+ code_point = utf8::internal::mask8(*it);
+
+ return UTF8_OK;
+ }
+
+ template <typename octet_iterator>
+ utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ if (it == end)
+ return NOT_ENOUGH_ROOM;
+
+ code_point = utf8::internal::mask8(*it);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f);
+
+ return UTF8_OK;
+ }
+
+ template <typename octet_iterator>
+ utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ if (it == end)
+ return NOT_ENOUGH_ROOM;
+
+ code_point = utf8::internal::mask8(*it);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point += (*it) & 0x3f;
+
+ return UTF8_OK;
+ }
+
+ template <typename octet_iterator>
+ utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ if (it == end)
+ return NOT_ENOUGH_ROOM;
+
+ code_point = utf8::internal::mask8(*it);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point += (utf8::internal::mask8(*it) << 6) & 0xfff;
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point += (*it) & 0x3f;
+
+ return UTF8_OK;
+ }
+
+ #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR
+
+ template <typename octet_iterator>
+ utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ if (it == end)
+ return NOT_ENOUGH_ROOM;
+
+ // Save the original value of it so we can go back in case of failure
+ // Of course, it does not make much sense with i.e. stream iterators
+ octet_iterator original_it = it;
+
+ uint32_t cp = 0;
+ // Determine the sequence length based on the lead octet
+ typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type;
+ const octet_difference_type length = utf8::internal::sequence_length(it);
+
+ // Get trail octets and calculate the code point
+ utf_error err = UTF8_OK;
+ switch (length) {
+ case 0:
+ return INVALID_LEAD;
+ case 1:
+ err = utf8::internal::get_sequence_1(it, end, cp);
+ break;
+ case 2:
+ err = utf8::internal::get_sequence_2(it, end, cp);
+ break;
+ case 3:
+ err = utf8::internal::get_sequence_3(it, end, cp);
+ break;
+ case 4:
+ err = utf8::internal::get_sequence_4(it, end, cp);
+ break;
+ }
+
+ if (err == UTF8_OK) {
+ // Decoding succeeded. Now, security checks...
+ if (utf8::internal::is_code_point_valid(cp)) {
+ if (!utf8::internal::is_overlong_sequence(cp, length)){
+ // Passed! Return here.
+ code_point = cp;
+ ++it;
+ return UTF8_OK;
+ }
+ else
+ err = OVERLONG_SEQUENCE;
+ }
+ else
+ err = INVALID_CODE_POINT;
+ }
+
+ // Failure branch - restore the original value of the iterator
+ it = original_it;
+ return err;
+ }
+
+ template <typename octet_iterator>
+ inline utf_error validate_next(octet_iterator& it, octet_iterator end) {
+ uint32_t ignored;
+ return utf8::internal::validate_next(it, end, ignored);
+ }
+
+} // namespace internal
+
+ /// The library API - functions intended to be called by the users
+
+ // Byte order mark
+ const uint8_t bom[] = {0xef, 0xbb, 0xbf};
+
+ template <typename octet_iterator>
+ octet_iterator find_invalid(octet_iterator start, octet_iterator end)
+ {
+ octet_iterator result = start;
+ while (result != end) {
+ utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end);
+ if (err_code != internal::UTF8_OK)
+ return result;
+ }
+ return result;
+ }
+
+ template <typename octet_iterator>
+ inline bool is_valid(octet_iterator start, octet_iterator end)
+ {
+ return (utf8::find_invalid(start, end) == end);
+ }
+
+ template <typename octet_iterator>
+ inline bool starts_with_bom (octet_iterator it, octet_iterator end)
+ {
+ return (
+ ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) &&
+ ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) &&
+ ((it != end) && (utf8::internal::mask8(*it)) == bom[2])
+ );
+ }
+} // namespace utf8
+
+#endif // header guard
+
+
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/cpp11.h b/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/cpp11.h
new file mode 100644
index 0000000000..d93961b04f
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/cpp11.h
@@ -0,0 +1,103 @@
+// Copyright 2018 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_a184c22c_d012_11e8_a8d5_f2801f1b9fd1
+#define UTF8_FOR_CPP_a184c22c_d012_11e8_a8d5_f2801f1b9fd1
+
+#include "checked.h"
+#include <string>
+
+namespace utf8
+{
+
+ inline void append(char32_t cp, std::string& s)
+ {
+ append(uint32_t(cp), std::back_inserter(s));
+ }
+
+ inline std::string utf16to8(const std::u16string& s)
+ {
+ std::string result;
+ utf16to8(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline std::u16string utf8to16(const std::string& s)
+ {
+ std::u16string result;
+ utf8to16(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline std::string utf32to8(const std::u32string& s)
+ {
+ std::string result;
+ utf32to8(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline std::u32string utf8to32(const std::string& s)
+ {
+ std::u32string result;
+ utf8to32(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline std::size_t find_invalid(const std::string& s)
+ {
+ std::string::const_iterator invalid = find_invalid(s.begin(), s.end());
+ return (invalid == s.end()) ? std::string::npos : (invalid - s.begin());
+ }
+
+ inline bool is_valid(const std::string& s)
+ {
+ return is_valid(s.begin(), s.end());
+ }
+
+ inline std::string replace_invalid(const std::string& s, char32_t replacement)
+ {
+ std::string result;
+ replace_invalid(s.begin(), s.end(), std::back_inserter(result), replacement);
+ return result;
+ }
+
+ inline std::string replace_invalid(const std::string& s)
+ {
+ std::string result;
+ replace_invalid(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline bool starts_with_bom(const std::string& s)
+ {
+ return starts_with_bom(s.begin(), s.end());
+ }
+
+} // namespace utf8
+
+#endif // header guard
+
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/cpp17.h b/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/cpp17.h
new file mode 100644
index 0000000000..7bfa869942
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/cpp17.h
@@ -0,0 +1,103 @@
+// Copyright 2018 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_7e906c01_03a3_4daf_b420_ea7ea952b3c9
+#define UTF8_FOR_CPP_7e906c01_03a3_4daf_b420_ea7ea952b3c9
+
+#include "checked.h"
+#include <string>
+
+namespace utf8
+{
+
+ inline void append(char32_t cp, std::string& s)
+ {
+ append(uint32_t(cp), std::back_inserter(s));
+ }
+
+ inline std::string utf16to8(std::u16string_view s)
+ {
+ std::string result;
+ utf16to8(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline std::u16string utf8to16(std::string_view s)
+ {
+ std::u16string result;
+ utf8to16(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline std::string utf32to8(std::u32string_view s)
+ {
+ std::string result;
+ utf32to8(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline std::u32string utf8to32(std::string_view s)
+ {
+ std::u32string result;
+ utf8to32(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline std::size_t find_invalid(std::string_view s)
+ {
+ std::string_view::const_iterator invalid = find_invalid(s.begin(), s.end());
+ return (invalid == s.end()) ? std::string_view::npos : (invalid - s.begin());
+ }
+
+ inline bool is_valid(std::string_view s)
+ {
+ return is_valid(s.begin(), s.end());
+ }
+
+ inline std::string replace_invalid(std::string_view s, char32_t replacement)
+ {
+ std::string result;
+ replace_invalid(s.begin(), s.end(), std::back_inserter(result), replacement);
+ return result;
+ }
+
+ inline std::string replace_invalid(std::string_view s)
+ {
+ std::string result;
+ replace_invalid(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline bool starts_with_bom(std::string_view s)
+ {
+ return starts_with_bom(s.begin(), s.end());
+ }
+
+} // namespace utf8
+
+#endif // header guard
+
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/unchecked.h b/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/unchecked.h
new file mode 100644
index 0000000000..0e1b51cc7d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/source/utf8/unchecked.h
@@ -0,0 +1,274 @@
+// Copyright 2006 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+
+#include "core.h"
+
+namespace utf8
+{
+ namespace unchecked
+ {
+ template <typename octet_iterator>
+ octet_iterator append(uint32_t cp, octet_iterator result)
+ {
+ if (cp < 0x80) // one octet
+ *(result++) = static_cast<uint8_t>(cp);
+ else if (cp < 0x800) { // two octets
+ *(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ else if (cp < 0x10000) { // three octets
+ *(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
+ *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ else { // four octets
+ *(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
+ *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80);
+ *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ return result;
+ }
+
+ template <typename octet_iterator, typename output_iterator>
+ output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
+ {
+ while (start != end) {
+ octet_iterator sequence_start = start;
+ internal::utf_error err_code = utf8::internal::validate_next(start, end);
+ switch (err_code) {
+ case internal::UTF8_OK :
+ for (octet_iterator it = sequence_start; it != start; ++it)
+ *out++ = *it;
+ break;
+ case internal::NOT_ENOUGH_ROOM:
+ out = utf8::unchecked::append (replacement, out);
+ start = end;
+ break;
+ case internal::INVALID_LEAD:
+ out = utf8::unchecked::append (replacement, out);
+ ++start;
+ break;
+ case internal::INCOMPLETE_SEQUENCE:
+ case internal::OVERLONG_SEQUENCE:
+ case internal::INVALID_CODE_POINT:
+ out = utf8::unchecked::append (replacement, out);
+ ++start;
+ // just one replacement mark for the sequence
+ while (start != end && utf8::internal::is_trail(*start))
+ ++start;
+ break;
+ }
+ }
+ return out;
+ }
+
+ template <typename octet_iterator, typename output_iterator>
+ inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
+ {
+ static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
+ return utf8::unchecked::replace_invalid(start, end, out, replacement_marker);
+ }
+
+ template <typename octet_iterator>
+ uint32_t next(octet_iterator& it)
+ {
+ uint32_t cp = utf8::internal::mask8(*it);
+ typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);
+ switch (length) {
+ case 1:
+ break;
+ case 2:
+ it++;
+ cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
+ break;
+ case 3:
+ ++it;
+ cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
+ ++it;
+ cp += (*it) & 0x3f;
+ break;
+ case 4:
+ ++it;
+ cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
+ ++it;
+ cp += (utf8::internal::mask8(*it) << 6) & 0xfff;
+ ++it;
+ cp += (*it) & 0x3f;
+ break;
+ }
+ ++it;
+ return cp;
+ }
+
+ template <typename octet_iterator>
+ uint32_t peek_next(octet_iterator it)
+ {
+ return utf8::unchecked::next(it);
+ }
+
+ template <typename octet_iterator>
+ uint32_t prior(octet_iterator& it)
+ {
+ while (utf8::internal::is_trail(*(--it))) ;
+ octet_iterator temp = it;
+ return utf8::unchecked::next(temp);
+ }
+
+ template <typename octet_iterator, typename distance_type>
+ void advance (octet_iterator& it, distance_type n)
+ {
+ const distance_type zero(0);
+ if (n < zero) {
+ // backward
+ for (distance_type i = n; i < zero; ++i)
+ utf8::unchecked::prior(it);
+ } else {
+ // forward
+ for (distance_type i = zero; i < n; ++i)
+ utf8::unchecked::next(it);
+ }
+ }
+
+ template <typename octet_iterator>
+ typename std::iterator_traits<octet_iterator>::difference_type
+ distance (octet_iterator first, octet_iterator last)
+ {
+ typename std::iterator_traits<octet_iterator>::difference_type dist;
+ for (dist = 0; first < last; ++dist)
+ utf8::unchecked::next(first);
+ return dist;
+ }
+
+ template <typename u16bit_iterator, typename octet_iterator>
+ octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
+ {
+ while (start != end) {
+ uint32_t cp = utf8::internal::mask16(*start++);
+ // Take care of surrogate pairs first
+ if (utf8::internal::is_lead_surrogate(cp)) {
+ uint32_t trail_surrogate = utf8::internal::mask16(*start++);
+ cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
+ }
+ result = utf8::unchecked::append(cp, result);
+ }
+ return result;
+ }
+
+ template <typename u16bit_iterator, typename octet_iterator>
+ u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
+ {
+ while (start < end) {
+ uint32_t cp = utf8::unchecked::next(start);
+ if (cp > 0xffff) { //make a surrogate pair
+ *result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
+ *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
+ }
+ else
+ *result++ = static_cast<uint16_t>(cp);
+ }
+ return result;
+ }
+
+ template <typename octet_iterator, typename u32bit_iterator>
+ octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
+ {
+ while (start != end)
+ result = utf8::unchecked::append(*(start++), result);
+
+ return result;
+ }
+
+ template <typename octet_iterator, typename u32bit_iterator>
+ u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
+ {
+ while (start < end)
+ (*result++) = utf8::unchecked::next(start);
+
+ return result;
+ }
+
+ // The iterator class
+ template <typename octet_iterator>
+ class iterator {
+ octet_iterator it;
+ public:
+ typedef uint32_t value_type;
+ typedef uint32_t* pointer;
+ typedef uint32_t& reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::bidirectional_iterator_tag iterator_category;
+ iterator () {}
+ explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
+ // the default "big three" are OK
+ octet_iterator base () const { return it; }
+ uint32_t operator * () const
+ {
+ octet_iterator temp = it;
+ return utf8::unchecked::next(temp);
+ }
+ bool operator == (const iterator& rhs) const
+ {
+ return (it == rhs.it);
+ }
+ bool operator != (const iterator& rhs) const
+ {
+ return !(operator == (rhs));
+ }
+ iterator& operator ++ ()
+ {
+ ::std::advance(it, utf8::internal::sequence_length(it));
+ return *this;
+ }
+ iterator operator ++ (int)
+ {
+ iterator temp = *this;
+ ::std::advance(it, utf8::internal::sequence_length(it));
+ return temp;
+ }
+ iterator& operator -- ()
+ {
+ utf8::unchecked::prior(it);
+ return *this;
+ }
+ iterator operator -- (int)
+ {
+ iterator temp = *this;
+ utf8::unchecked::prior(it);
+ return temp;
+ }
+ }; // class iterator
+
+ } // namespace utf8::unchecked
+} // namespace utf8
+
+
+#endif // header guard
+
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/tests/CMakeLists.txt b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/CMakeLists.txt
new file mode 100644
index 0000000000..4063df7c67
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/CMakeLists.txt
@@ -0,0 +1,47 @@
+add_executable(negative ${PROJECT_SOURCE_DIR}/tests/negative.cpp)
+add_executable(cpp11 ${PROJECT_SOURCE_DIR}/tests/test_cpp11.cpp)
+add_executable(cpp17 ${PROJECT_SOURCE_DIR}/tests/test_cpp17.cpp)
+add_executable(apitests
+ ${PROJECT_SOURCE_DIR}/tests/test_checked_api.cpp
+ ${PROJECT_SOURCE_DIR}/tests/test_unchecked_api.cpp
+ ${PROJECT_SOURCE_DIR}/tests/test_checked_iterator.cpp
+ ${PROJECT_SOURCE_DIR}/tests/test_unchecked_iterator.cpp
+)
+
+add_executable(noexceptionstests
+ ${PROJECT_SOURCE_DIR}/tests/test_unchecked_api.cpp
+ ${PROJECT_SOURCE_DIR}/tests/test_unchecked_iterator.cpp
+)
+
+target_link_libraries(negative PRIVATE utf8::cpp)
+target_link_libraries(cpp11 PRIVATE utf8::cpp)
+target_link_libraries(cpp17 PRIVATE utf8::cpp)
+target_link_libraries(apitests PRIVATE utf8::cpp)
+target_link_libraries(noexceptionstests PRIVATE utf8::cpp)
+
+target_compile_options(noexceptionstests PUBLIC -fno-exceptions)
+
+set_target_properties(negative apitests noexceptionstests
+ PROPERTIES
+ CXX_STANDARD 98
+ CXX_STANDARD_REQUIRED YES
+ CXX_EXTENSIONS NO)
+
+set_target_properties(cpp11
+ PROPERTIES
+ CXX_STANDARD 11
+ CXX_STANDARD_REQUIRED YES
+ CXX_EXTENSIONS NO)
+
+set_target_properties(cpp17
+ PROPERTIES
+ CXX_STANDARD 17
+ CXX_STANDARD_REQUIRED YES
+ CXX_EXTENSIONS NO)
+
+add_test(negative_test negative ${PROJECT_SOURCE_DIR}/tests/test_data/utf8_invalid.txt)
+add_test(cpp11_test cpp11)
+add_test(cpp17_test cpp17)
+add_test(api_test apitests)
+add_test(noexceptions_test noexceptionstests)
+
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/tests/docker/Dockerfile b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/docker/Dockerfile
new file mode 100644
index 0000000000..9df3717a1d
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/docker/Dockerfile
@@ -0,0 +1,5 @@
+FROM debian:buster-slim
+
+RUN apt-get update \
+ && apt-get install -y make g++ cmake git \
+ && rm -rf /var/lib/apt/lists/*
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/tests/negative.cpp b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/negative.cpp
new file mode 100644
index 0000000000..f1bcc993e0
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/negative.cpp
@@ -0,0 +1,59 @@
+#include "utf8.h"
+using namespace utf8;
+
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <algorithm>
+using namespace std;
+
+const unsigned INVALID_LINES[] = { 75, 76, 83, 84, 85, 93, 102, 103, 105, 106, 107, 108, 109, 110, 114, 115, 116, 117, 124, 125, 130, 135, 140, 145, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 169, 175, 176, 177, 207, 208, 209, 210, 211, 220, 221, 222, 223, 224, 232, 233, 234, 235, 236, 247, 248, 249, 250, 251, 252, 253, 257, 258, 259, 260, 261, 262, 263, 264};
+const unsigned* INVALID_LINES_END = INVALID_LINES + sizeof(INVALID_LINES)/sizeof(unsigned);
+
+int main(int argc, char** argv)
+{
+ string test_file_path;
+ if (argc == 2)
+ test_file_path = argv[1];
+ else {
+ cout << "Wrong number of arguments" << endl;
+ return 1;
+ }
+ // Open the test file
+ ifstream fs8(test_file_path.c_str());
+ if (!fs8.is_open()) {
+ cout << "Could not open " << test_file_path << endl;
+ return 1;
+ }
+
+ // Read it line by line
+ unsigned int line_count = 0;
+ char byte;
+ while (!fs8.eof()) {
+ string line;
+ while ((byte = static_cast<char>(fs8.get())) != '\n' && !fs8.eof())
+ line.push_back(byte);
+
+ line_count++;
+ bool expected_valid = (find(INVALID_LINES, INVALID_LINES_END, line_count) == INVALID_LINES_END);
+ // Print out lines that contain unexpected invalid UTF-8
+ if (!is_valid(line.begin(), line.end())) {
+ if (expected_valid) {
+ cout << "Unexpected invalid utf-8 at line " << line_count << '\n';
+ return 1;
+ }
+
+ // try fixing it:
+ string fixed_line;
+ replace_invalid(line.begin(), line.end(), back_inserter(fixed_line));
+ if (!is_valid(fixed_line.begin(), fixed_line.end())) {
+ cout << "replace_invalid() resulted in an invalid utf-8 at line " << line_count << '\n';
+ return 1;
+ }
+ }
+ else if (!expected_valid) {
+ cout << "Invalid utf-8 NOT detected at line " << line_count << '\n';
+ return 1;
+ }
+ }
+}
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_checked_api.cpp b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_checked_api.cpp
new file mode 100644
index 0000000000..b57e1bc894
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_checked_api.cpp
@@ -0,0 +1,189 @@
+#define F_TEST_NO_MAIN
+#include "../extern/ftest/ftest.h"
+#include "utf8.h"
+
+#include <string>
+#include <vector>
+using namespace utf8;
+using namespace std;
+
+
+TEST(CheckedAPITests, test_append)
+{
+ unsigned char u[5] = {0,0,0,0,0};
+ append(0x0448, u);
+ EXPECT_EQ (u[0], 0xd1);
+ EXPECT_EQ (u[1], 0x88);
+ EXPECT_EQ (u[2], 0);
+ EXPECT_EQ (u[3], 0);
+ EXPECT_EQ (u[4], 0);
+
+ append(0x65e5, u);
+ EXPECT_EQ (u[0], 0xe6);
+ EXPECT_EQ (u[1], 0x97);
+ EXPECT_EQ (u[2], 0xa5);
+ EXPECT_EQ (u[3], 0);
+ EXPECT_EQ (u[4], 0);
+
+ append(0x3044, u);
+ EXPECT_EQ (u[0], 0xe3);
+ EXPECT_EQ (u[1], 0x81);
+ EXPECT_EQ (u[2], 0x84);
+ EXPECT_EQ (u[3], 0);
+ EXPECT_EQ (u[4], 0);
+
+ append(0x10346, u);
+ EXPECT_EQ (u[0], 0xf0);
+ EXPECT_EQ (u[1], 0x90);
+ EXPECT_EQ (u[2], 0x8d);
+ EXPECT_EQ (u[3], 0x86);
+ EXPECT_EQ (u[4], 0);
+}
+
+TEST(CheckedAPITests, test_next)
+{
+ const char* twochars = "\xe6\x97\xa5\xd1\x88";
+ const char* w = twochars;
+ int cp = next(w, twochars + 6);
+ EXPECT_EQ (cp, 0x65e5);
+ EXPECT_EQ (w, twochars + 3);
+
+ const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+ w = threechars;
+
+ cp = next(w, threechars + 9);
+ EXPECT_EQ (cp, 0x10346);
+ EXPECT_EQ (w, threechars + 4);
+
+ cp = next(w, threechars + 9);
+ EXPECT_EQ (cp, 0x65e5);
+ EXPECT_EQ (w, threechars + 7);
+
+ cp = next(w, threechars + 9);
+ EXPECT_EQ (cp, 0x0448);
+ EXPECT_EQ (w, threechars + 9);
+}
+
+TEST(CheckedAPITests, test_peek_next)
+{
+ const char* const cw = "\xe6\x97\xa5\xd1\x88";
+ int cp = peek_next(cw, cw + 6);
+ EXPECT_EQ (cp, 0x65e5);
+}
+
+TEST(CheckedAPITests, test_prior)
+{
+ const char* twochars = "\xe6\x97\xa5\xd1\x88";
+ const char* w = twochars + 3;
+ int cp = prior (w, twochars);
+ EXPECT_EQ (cp, 0x65e5);
+ EXPECT_EQ (w, twochars);
+
+ const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+ w = threechars + 9;
+ cp = prior(w, threechars);
+ EXPECT_EQ (cp, 0x0448);
+ EXPECT_EQ (w, threechars + 7);
+ cp = prior(w, threechars);
+ EXPECT_EQ (cp, 0x65e5);
+ EXPECT_EQ (w, threechars + 4);
+ cp = prior(w, threechars);
+ EXPECT_EQ (cp, 0x10346);
+ EXPECT_EQ (w, threechars);
+}
+
+TEST(CheckedAPITests, test_advance)
+{
+ const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+ const char* w = threechars;
+ advance(w, 2, threechars + 9);
+ EXPECT_EQ(w, threechars + 7);
+ advance(w, -2, threechars);
+ EXPECT_EQ(w, threechars);
+ advance(w, 3, threechars + 9);
+ EXPECT_EQ(w, threechars + 9);
+ advance(w, -2, threechars);
+ EXPECT_EQ(w, threechars + 4);
+ advance(w, -1, threechars);
+ EXPECT_EQ(w, threechars);
+}
+
+TEST(CheckedAPITests, test_distance)
+{
+ const char* twochars = "\xe6\x97\xa5\xd1\x88";
+ size_t dist = utf8::distance(twochars, twochars + 5);
+ EXPECT_EQ (dist, 2);
+}
+
+TEST(CheckedAPITests, test_utf32to8)
+{
+ int utf32string[] = {0x448, 0x65E5, 0x10346, 0};
+ string utf8result;
+ utf32to8(utf32string, utf32string + 3, back_inserter(utf8result));
+ EXPECT_EQ (utf8result.size(), 9);
+}
+
+TEST(CheckedAPITests, test_utf8to32)
+{
+ const char* twochars = "\xe6\x97\xa5\xd1\x88";
+ vector<int> utf32result;
+ utf8to32(twochars, twochars + 5, back_inserter(utf32result));
+ EXPECT_EQ (utf32result.size(), 2);
+}
+
+TEST(CheckedAPITests, test_utf16to8)
+{
+ unsigned short utf16string[] = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e};
+ string utf8result;
+ utf16to8(utf16string, utf16string + 5, back_inserter(utf8result));
+ EXPECT_EQ (utf8result.size(), 10);
+}
+
+TEST(CheckedAPITests, test_utf8to16)
+{
+ char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e";
+ vector <unsigned short> utf16result;
+ utf8to16(utf8_with_surrogates, utf8_with_surrogates + 9, back_inserter(utf16result));
+ EXPECT_EQ (utf16result.size(), 4);
+ EXPECT_EQ (utf16result[2], 0xd834);
+ EXPECT_EQ (utf16result[3], 0xdd1e);
+}
+
+TEST(CheckedAPITests, test_replace_invalid)
+{
+ char invalid_sequence[] = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z";
+ vector<char> replace_invalid_result;
+ replace_invalid (invalid_sequence, invalid_sequence + sizeof(invalid_sequence), std::back_inserter(replace_invalid_result), '?');
+ bool bvalid = is_valid(replace_invalid_result.begin(), replace_invalid_result.end());
+ EXPECT_TRUE (bvalid);
+ const char fixed_invalid_sequence[] = "a????z";
+ EXPECT_EQ (sizeof(fixed_invalid_sequence), replace_invalid_result.size());
+ EXPECT_TRUE (std::equal(replace_invalid_result.begin(), replace_invalid_result.begin() + sizeof(fixed_invalid_sequence), fixed_invalid_sequence));
+}
+
+TEST(CheckedAPITests, test_find_invalid)
+{
+ char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa";
+ char* invalid = find_invalid(utf_invalid, utf_invalid + 6);
+ EXPECT_EQ (invalid, utf_invalid + 5);
+}
+
+TEST(CheckedAPITests, test_is_valid)
+{
+ char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa";
+ bool bvalid = is_valid(utf_invalid, utf_invalid + 6);
+ EXPECT_FALSE (bvalid);
+ char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e";
+ bvalid = is_valid(utf8_with_surrogates, utf8_with_surrogates + 9);
+ EXPECT_TRUE (bvalid);
+}
+
+TEST(CheckedAPITests, test_starts_with_bom)
+{
+ unsigned char byte_order_mark[] = {0xef, 0xbb, 0xbf};
+ bool bbom = starts_with_bom(byte_order_mark, byte_order_mark + sizeof(byte_order_mark));
+ EXPECT_TRUE (bbom);
+ const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+ bool no_bbom = starts_with_bom(threechars, threechars + sizeof(threechars));
+ EXPECT_FALSE (no_bbom);
+}
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_checked_iterator.cpp b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_checked_iterator.cpp
new file mode 100644
index 0000000000..3f9bfe96a2
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_checked_iterator.cpp
@@ -0,0 +1,32 @@
+#define F_TEST_NO_MAIN
+#include "../extern/ftest/ftest.h"
+#include "utf8.h"
+
+using namespace utf8;
+
+
+TEST(CheckedIteratrTests, test_increment)
+{
+ const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+ utf8::iterator<const char*> it(threechars, threechars, threechars + 9);
+ utf8::iterator<const char*> it2 = it;
+ EXPECT_EQ (it2, it);
+ EXPECT_EQ (*it, 0x10346);
+ EXPECT_EQ (*(++it), 0x65e5);
+ EXPECT_EQ ((*it++), 0x65e5);
+ EXPECT_EQ (*it, 0x0448);
+ EXPECT_NE (it, it2);
+ utf8::iterator<const char*> endit (threechars + 9, threechars, threechars + 9);
+ EXPECT_EQ (++it, endit);
+}
+
+TEST(CheckedIteratrTests, test_decrement)
+{
+ const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+ utf8::iterator<const char*> it(threechars+9, threechars, threechars + 9);
+ EXPECT_EQ (*(--it), 0x0448);
+ EXPECT_EQ ((*it--), 0x0448);
+ EXPECT_EQ (*it, 0x65e5);
+ EXPECT_EQ (--it, utf8::iterator<const char*>(threechars, threechars, threechars + 9));
+ EXPECT_EQ (*it, 0x10346);
+}
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_cpp11.cpp b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_cpp11.cpp
new file mode 100644
index 0000000000..ee4ddd8fd6
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_cpp11.cpp
@@ -0,0 +1,109 @@
+#include "../extern/ftest/ftest.h"
+#include "utf8.h"
+#include <string>
+using namespace utf8;
+using namespace std;
+
+#if __cplusplus >= 201103L // C++ 11 or later
+
+TEST(CPP11APITests, test_append)
+{
+ string u;
+ append(0x0448, u);
+ EXPECT_EQ (u[0], char(0xd1));
+ EXPECT_EQ (u[1], char(0x88));
+ EXPECT_EQ (u.length(), 2);
+
+ u.clear();
+ append(0x65e5, u);
+ EXPECT_EQ (u[0], char(0xe6));
+ EXPECT_EQ (u[1], char(0x97));
+ EXPECT_EQ (u[2], char(0xa5));
+ EXPECT_EQ (u.length(), 3);
+
+ u.clear();
+ append(0x3044, u);
+ EXPECT_EQ (u[0], char(0xe3));
+ EXPECT_EQ (u[1], char(0x81));
+ EXPECT_EQ (u[2], char(0x84));
+ EXPECT_EQ (u.length(), 3);
+
+ u.clear();
+ append(0x10346, u);
+ EXPECT_EQ (u[0], char(0xf0));
+ EXPECT_EQ (u[1], char(0x90));
+ EXPECT_EQ (u[2], char(0x8d));
+ EXPECT_EQ (u[3], char(0x86));
+ EXPECT_EQ (u.length(), 4);
+}
+
+TEST(CPP11APITests, test_utf16to8)
+{
+ u16string utf16string = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e};
+ string u = utf16to8(utf16string);
+ EXPECT_EQ (u.size(), 10);
+}
+
+TEST(CPP11APITests, test_utf8to16)
+{
+ string utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e";
+ u16string utf16result = utf8to16(utf8_with_surrogates);
+ EXPECT_EQ (utf16result.size(), 4);
+ EXPECT_EQ (utf16result[2], 0xd834);
+ EXPECT_EQ (utf16result[3], 0xdd1e);
+ // Just to make sure it compiles with string literals
+ utf8to16(u8"simple");
+ utf8to16("simple");
+}
+
+TEST(CPP11APITests, test_utf32to8)
+{
+ u32string utf32string = {0x448, 0x65E5, 0x10346};
+ string utf8result = utf32to8(utf32string);
+ EXPECT_EQ (utf8result.size(), 9);
+}
+
+TEST(CPP11APITests, test_utf8to32)
+{
+ const char* twochars = "\xe6\x97\xa5\xd1\x88";
+ u32string utf32result = utf8to32(twochars);
+ EXPECT_EQ (utf32result.size(), 2);
+}
+
+TEST(CPP11APITests, test_find_invalid)
+{
+ string utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa";
+ auto invalid = find_invalid(utf_invalid);
+ EXPECT_EQ (invalid, 5);
+}
+
+TEST(CPP11APITests, test_is_valid)
+{
+ string utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa";
+ bool bvalid = is_valid(utf_invalid);
+ EXPECT_FALSE (bvalid);
+ string utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e";
+ bvalid = is_valid(utf8_with_surrogates);
+ EXPECT_TRUE (bvalid);
+}
+
+TEST(CPP11APITests, test_replace_invalid)
+{
+ string invalid_sequence = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z";
+ string replace_invalid_result = replace_invalid(invalid_sequence, '?');
+ bool bvalid = is_valid(replace_invalid_result);
+ EXPECT_TRUE (bvalid);
+ const string fixed_invalid_sequence = "a????z";
+ EXPECT_EQ(fixed_invalid_sequence, replace_invalid_result);
+}
+
+TEST(CPP11APITests, test_starts_with_bom)
+{
+ string byte_order_mark = {char(0xef), char(0xbb), char(0xbf)};
+ bool bbom = starts_with_bom(byte_order_mark);
+ EXPECT_TRUE (bbom);
+ string threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+ bool no_bbom = starts_with_bom(threechars);
+ EXPECT_FALSE (no_bbom);
+}
+#endif // C++ 11 or later
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_cpp17.cpp b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_cpp17.cpp
new file mode 100644
index 0000000000..4b87816b1c
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_cpp17.cpp
@@ -0,0 +1,88 @@
+#include "../extern/ftest/ftest.h"
+#include "utf8.h"
+#include <string>
+using namespace utf8;
+using namespace std;
+
+#if __cplusplus >= 201703L // C++ 17 or later
+
+
+TEST(CPP17APITests, test_utf16to8)
+{
+ u16string utf16string = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e};
+ u16string_view utf16stringview(u16string);
+ string u = utf16to8(utf16string);
+ EXPECT_EQ (u.size(), 10);
+}
+
+TEST(CPP17APITests, test_utf8to16)
+{
+ string_view utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e";
+ u16string utf16result = utf8to16(utf8_with_surrogates);
+ EXPECT_EQ (utf16result.size(), 4);
+ EXPECT_EQ (utf16result[2], 0xd834);
+ EXPECT_EQ (utf16result[3], 0xdd1e);
+}
+
+TEST(CPP17APITests, test_utf32to8)
+{
+ u32string utf32string = {0x448, 0x65E5, 0x10346};
+ u32string_view utf32stringview(utf32string);
+ string utf8result = utf32to8(utf32stringview);
+ EXPECT_EQ (utf8result.size(), 9);
+}
+
+TEST(CPP17APITests, test_utf8to32)
+{
+ string_view twochars = "\xe6\x97\xa5\xd1\x88";
+ u32string utf32result = utf8to32(twochars);
+ EXPECT_EQ (utf32result.size(), 2);
+}
+
+TEST(CPP17APITests, test_find_invalid)
+{
+ string_view utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa";
+ auto invalid = find_invalid(utf_invalid);
+ EXPECT_EQ (invalid, 5);
+}
+
+TEST(CPP17APITests, test_is_valid)
+{
+ string_view utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa";
+ bool bvalid = is_valid(utf_invalid);
+ EXPECT_FALSE (bvalid);
+ string_view utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e";
+ bvalid = is_valid(utf8_with_surrogates);
+ EXPECT_TRUE (bvalid);
+}
+
+TEST(CPP17APITests, test_replace_invalid)
+{
+ string_view invalid_sequence = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z";
+ string replace_invalid_result = replace_invalid(invalid_sequence, '?');
+ bool bvalid = is_valid(replace_invalid_result);
+ EXPECT_TRUE (bvalid);
+ const string fixed_invalid_sequence = "a????z";
+ EXPECT_EQ(fixed_invalid_sequence, replace_invalid_result);
+}
+
+TEST(CPP17APITests, test_starts_with_bom)
+{
+ string byte_order_mark = {char(0xef), char(0xbb), char(0xbf)};
+ string_view byte_order_mark_view(byte_order_mark);
+ bool bbom = starts_with_bom(byte_order_mark_view);
+ EXPECT_TRUE (bbom);
+ string_view threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+ bool no_bbom = starts_with_bom(threechars);
+ EXPECT_FALSE (no_bbom);
+}
+
+TEST(CPP17APITests, string_class_and_literals)
+{
+ const char* twochars = u8"ab";
+ EXPECT_TRUE (is_valid(twochars));
+ const string two_chars_string(twochars);
+ EXPECT_TRUE (is_valid(two_chars_string));
+}
+
+#endif // C++ 11 or later
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_data/utf8_invalid.txt b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_data/utf8_invalid.txt
new file mode 100644
index 0000000000..ae83159328
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_data/utf8_invalid.txt
Binary files differ
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_unchecked_api.cpp b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_unchecked_api.cpp
new file mode 100644
index 0000000000..c400ada0d2
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_unchecked_api.cpp
@@ -0,0 +1,161 @@
+#include "../extern/ftest/ftest.h"
+#include "utf8/unchecked.h"
+
+#include <string>
+#include <vector>
+using namespace utf8::unchecked;
+using namespace std;
+
+TEST(UnCheckedAPITests, test_append)
+{
+ unsigned char u[5] = {0,0,0,0,0};
+ append(0x0448, u);
+ EXPECT_EQ (u[0], 0xd1);
+ EXPECT_EQ (u[1], 0x88);
+ EXPECT_EQ (u[2], 0);
+ EXPECT_EQ (u[3], 0);
+ EXPECT_EQ (u[4], 0);
+
+ append(0x65e5, u);
+ EXPECT_EQ (u[0], 0xe6);
+ EXPECT_EQ (u[1], 0x97);
+ EXPECT_EQ (u[2], 0xa5);
+ EXPECT_EQ (u[3], 0);
+ EXPECT_EQ (u[4], 0);
+
+ append(0x3044, u);
+ EXPECT_EQ (u[0], 0xe3);
+ EXPECT_EQ (u[1], 0x81);
+ EXPECT_EQ (u[2], 0x84);
+ EXPECT_EQ (u[3], 0);
+ EXPECT_EQ (u[4], 0);
+
+ append(0x10346, u);
+ EXPECT_EQ (u[0], 0xf0);
+ EXPECT_EQ (u[1], 0x90);
+ EXPECT_EQ (u[2], 0x8d);
+ EXPECT_EQ (u[3], 0x86);
+ EXPECT_EQ (u[4], 0);
+}
+
+TEST(UnCheckedAPITests, test_next)
+{
+ const char* twochars = "\xe6\x97\xa5\xd1\x88";
+ const char* w = twochars;
+ int cp = utf8::unchecked::next(w);
+ EXPECT_EQ (cp, 0x65e5);
+ EXPECT_EQ (w, twochars + 3);
+
+ const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+ w = threechars;
+
+ cp = utf8::unchecked::next(w);
+ EXPECT_EQ (cp, 0x10346);
+ EXPECT_EQ (w, threechars + 4);
+
+ cp = utf8::unchecked::next(w);
+ EXPECT_EQ (cp, 0x65e5);
+ EXPECT_EQ (w, threechars + 7);
+
+ cp = utf8::unchecked::next(w);
+ EXPECT_EQ (cp, 0x0448);
+ EXPECT_EQ (w, threechars + 9);
+}
+
+TEST(UnCheckedAPITests, test_peek_next)
+{
+ const char* const cw = "\xe6\x97\xa5\xd1\x88";
+ int cp = peek_next(cw);
+ EXPECT_EQ (cp, 0x65e5);
+}
+
+TEST(UnCheckedAPITests, test_prior)
+{
+ const char* twochars = "\xe6\x97\xa5\xd1\x88";
+ const char* w = twochars + 3;
+ int cp = prior (w);
+ EXPECT_EQ (cp, 0x65e5);
+ EXPECT_EQ (w, twochars);
+
+ const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+ w = threechars + 9;
+ cp = prior(w);
+ EXPECT_EQ (cp, 0x0448);
+ EXPECT_EQ (w, threechars + 7);
+ cp = prior(w);
+ EXPECT_EQ (cp, 0x65e5);
+ EXPECT_EQ (w, threechars + 4);
+ cp = prior(w);
+ EXPECT_EQ (cp, 0x10346);
+ EXPECT_EQ (w, threechars);
+}
+
+TEST(UnCheckedAPITests, test_advance)
+{
+ const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+ const char* w = threechars;
+ utf8::unchecked::advance(w, 2);
+ EXPECT_EQ(w, threechars + 7);
+ utf8::unchecked::advance(w, -2);
+ EXPECT_EQ(w, threechars);
+ utf8::unchecked::advance(w, 3);
+ EXPECT_EQ(w, threechars + 9);
+ utf8::unchecked::advance(w, -2);
+ EXPECT_EQ(w, threechars + 4);
+ utf8::unchecked::advance(w, -1);
+ EXPECT_EQ(w, threechars);
+}
+
+TEST(UnCheckedAPITests, test_distance)
+{
+ const char* twochars = "\xe6\x97\xa5\xd1\x88";
+ size_t dist = utf8::unchecked::distance(twochars, twochars + 5);
+ EXPECT_EQ (dist, 2);
+}
+
+TEST(UnCheckedAPITests, test_utf32to8)
+{
+ int utf32string[] = {0x448, 0x65E5, 0x10346, 0};
+ string utf8result;
+ utf32to8(utf32string, utf32string + 3, back_inserter(utf8result));
+ EXPECT_EQ (utf8result.size(), 9);
+}
+
+TEST(UnCheckedAPITests, test_utf8to32)
+{
+ const char* twochars = "\xe6\x97\xa5\xd1\x88";
+ vector<int> utf32result;
+ utf8to32(twochars, twochars + 5, back_inserter(utf32result));
+ EXPECT_EQ (utf32result.size(), 2);
+}
+
+TEST(UnCheckedAPITests, test_utf16to8)
+{
+ unsigned short utf16string[] = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e};
+ string utf8result;
+ utf16to8(utf16string, utf16string + 5, back_inserter(utf8result));
+ EXPECT_EQ (utf8result.size(), 10);
+}
+
+TEST(UnCheckedAPITests, test_utf8to16)
+{
+ char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e";
+ vector <unsigned short> utf16result;
+ utf8to16(utf8_with_surrogates, utf8_with_surrogates + 9, back_inserter(utf16result));
+ EXPECT_EQ (utf16result.size(), 4);
+ EXPECT_EQ (utf16result[2], 0xd834);
+ EXPECT_EQ (utf16result[3], 0xdd1e);
+}
+
+TEST(UnCheckedAPITests, test_replace_invalid)
+{
+ char invalid_sequence[] = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z";
+ vector<char> replace_invalid_result;
+ replace_invalid (invalid_sequence, invalid_sequence + sizeof(invalid_sequence), std::back_inserter(replace_invalid_result), '?');
+ bool bvalid = utf8::is_valid(replace_invalid_result.begin(), replace_invalid_result.end());
+ EXPECT_TRUE (bvalid);
+ const char fixed_invalid_sequence[] = "a????z";
+ EXPECT_EQ (sizeof(fixed_invalid_sequence), replace_invalid_result.size());
+ EXPECT_TRUE (std::equal(replace_invalid_result.begin(), replace_invalid_result.begin() + sizeof(fixed_invalid_sequence), fixed_invalid_sequence));
+}
+
diff --git a/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_unchecked_iterator.cpp b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_unchecked_iterator.cpp
new file mode 100644
index 0000000000..68943bf94c
--- /dev/null
+++ b/graphics/asymptote/LspCpp/third_party/utfcpp/tests/test_unchecked_iterator.cpp
@@ -0,0 +1,34 @@
+#define F_TEST_NO_MAIN
+#include "../extern/ftest/ftest.h"
+
+#include "utf8/unchecked.h"
+
+using namespace utf8::unchecked;
+
+
+TEST(UnCheckedIteratrTests, test_increment)
+{
+ const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+ utf8::unchecked::iterator<const char*> it(threechars);
+ utf8::unchecked::iterator<const char*> it2 = it;
+ EXPECT_EQ (it2, it);
+ EXPECT_EQ (*it, 0x10346);
+ EXPECT_EQ (*(++it), 0x65e5);
+ EXPECT_EQ ((*it++), 0x65e5);
+ EXPECT_EQ (*it, 0x0448);
+ EXPECT_NE (it, it2);
+ utf8::unchecked::iterator<const char*> endit (threechars + 9);
+ EXPECT_EQ (++it, endit);
+}
+
+TEST(UnCheckedIteratrTests, test_decrement)
+{
+ const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
+ utf8::unchecked::iterator<const char*> it(threechars+9);
+ EXPECT_EQ (*(--it), 0x0448);
+ EXPECT_EQ ((*it--), 0x0448);
+ EXPECT_EQ (*it, 0x65e5);
+ EXPECT_EQ (--it, utf8::unchecked::iterator<const char*>(threechars));
+ EXPECT_EQ (*it, 0x10346);
+
+}
diff --git a/graphics/asymptote/Makefile.in b/graphics/asymptote/Makefile.in
index a6705f9536..467b4ccb0b 100644
--- a/graphics/asymptote/Makefile.in
+++ b/graphics/asymptote/Makefile.in
@@ -11,11 +11,15 @@ GCOPTIONS = @GCOPTIONS@
GCLIB = @GCLIB@
GCPPLIB = @GCPPLIB@
GCLIBS = $(GCPPLIB) $(GCLIB)
-LFLAGS = @LDFLAGS@
-LIBS = $(LFLAGS) @PTHREAD_LIBS@ @GLEW@ @LIBS@ $(GCLIBS)
+LFLAGS = @LDFLAGS@ -LLspCpp
+LIBS = $(LFLAGS) @PTHREAD_LIBS@ @GLEW@ @LIBS@ $(GCLIBS) @LSPLIBS@
DOSLIBS = $(subst -lncurses, -ltermcap, $(LIBS)) -lwolfssl -lgdi32 -lwinmm -s -static
-PERL = perl
+PERL ?= perl
+PYTHON ?= python3
+BISON ?= bison
+PYRCC ?= pyrcc5
+PYUIC ?= pyuic5
# Libraries needed to make asymptote.so.
# We have to remove OpenGL, threading, GC, etc from this.
@@ -44,32 +48,41 @@ COREFILES = $(CAMP) $(SYMBOL_FILES) env genv stm dec errormsg \
fftw++asy simpson coder coenv impdatum \
@getopt@ locate parser program application varinit fundec refaccess \
envcompleter process constructor array Delaunay predicates \
- $(PRC) glrender tr shaders jsfile
+ $(PRC) glrender tr shaders jsfile v3dfile tinyexr EXRFiles GLTextures \
+ lspserv symbolmaps
FILES = $(COREFILES) main
SYMBOLSH = opsymbols.h allsymbols.h $(SYMBOL_FILES:=.symbols.h)
UIFILES = $(wildcard GUI/windows/*.ui)
PYFILES = $(wildcard GUI/pyUIClass/*.py) GUI/icons_rc.py
+
+GENERATEDENUMS=v3dtypes v3dheadertypes
+ASYGENERATEDENUMS=$(addprefix base/,$(GENERATEDENUMS:=.asy))
+PYGENERATEDENUMS=$(GENERATEDENUMS:=.py)
+
DIST = camp.tab.h camp.tab.cc lex.yy.cc runtime.cc keywords.cc \
asy-keywords.el $(RUNTIME_FILES:=.cc) $(RUNTIME_FILES:=.h) asy.list \
- $(SYMBOLSH) $(PYFILES)
+ $(SYMBOLSH) $(PYFILES) $(GENERATEDENUMS:=.h) $(ASYGENERATEDENUMS)
+
NAME = asy
XNAME = x$(NAME)
CLEAN = camp.output base/version.asy doc/version.texi \
- GUI/xasyVersion.py $(XNAME) doc/asy-latex.pdf $(SYMBOLSH)
+ GUI/xasyVersion.py GUI/icons_rc.py $(XNAME) doc/asy-latex.pdf \
+ $(SYMBOLSH)
EXTRA = asy-mode.el asy-init.el asy.vim asy_filetype.vim asy-kate.sh \
asymptote.py reload.js nopapersize.ps
EXEXTRA = piicon.png 100d.pdb1 *.views *.dat *.bib
DOCEXTRA = *.asy *.csv *.dat latexusage.tex externalprc.tex pixel.pdf
KEYWORDS = base $(ASYMPTOTE_SITEDIR)
-LATEXFILES = asymptote.sty asycolors.sty ocg.sty latexmkrc
+LATEXFILES = asymptote.sty asycolors.sty latexmkrc
CONTEXTFILES = colo-asy.tex
ASY = ./asy -dir base -config "" -render=0
-DEFS = @DEFS@ @OPTIONS@ @PTHREAD_CFLAGS@ -DFFTWPP_SINGLE_THREAD
+DEFS = @DEFS@ @OPTIONS@ @PTHREAD_CFLAGS@ -DFFTWPP_SINGLE_THREAD -Wall
CFLAGS = @CFLAGS@
-OPTS = $(DEFS) @CPPFLAGS@ @CXXFLAGS@ $(CFLAGS)
+OPTS = $(DEFS) @CPPFLAGS@ @CXXFLAGS@ $(CFLAGS) -ILspCpp -ILspCpp/LibLsp/JsonRpc
+
GLEWOPTS = $(DEFS) @CPPFLAGS@ $(CFLAGS) -DGLEW_NO_GLU -DGLEW_BUILD -O1 -fPIC
# Options for compiling the object files for the shared library.
@@ -78,12 +91,9 @@ GLEWOPTS = $(DEFS) @CPPFLAGS@ $(CFLAGS) -DGLEW_NO_GLU -DGLEW_BUILD -O1 -fPIC
# shared library.
SHAREDOPTS = $(filter-out -DUSEGC, $(OPTS)) -fPIC -DFOR_SHARED
-CXX = @CXX@ -Wall
-CC = @CC@ -Wall
-MAKEDEPEND = $(OPTS) -O0 -M -DDEPEND
-BISON ?= bison
-PYRCC ?= pyrcc5
-PYUIC ?= pyuic5
+CXX = @CXX@
+CC = @CC@
+MAKEDEPEND = $(OPTS) -O0 -M -MG -DDEPEND
LEX = @LEX@
prefix = @prefix@
@@ -115,7 +125,7 @@ endif
export prefix docdir exampledir mandir infodir INSTALL MAKE DESTDIR TEXI2DVI
-asy: version glew.o
+asy: version glew.o @LSPLIB@
if test -n "$(MSDOS)"; then \
$(CXX) $(OPTS) -o $(NAME) $(FILES:=.o) revision.o asy.o $(DOSLIBS); \
else \
@@ -123,7 +133,7 @@ asy: version glew.o
$(CXX) $(OPTS) -o $(NAME) $(FILES:=.o) revision.o $(LIBS); \
fi
-version: $(GCLIB) $(FILES:=.o) $(notdir $(UIFILES:.ui=.py)) GUI/icons_rc.py
+version: $(GCLIB) $(FILES:=.o) $(notdir $(UIFILES:.ui=.py)) GUI/icons_rc.py $(ASYGENERATEDENUMS) $(PYGENERATEDENUMS)
if test ! -s revision.cc || test "$(revision)" != "$(last)"; then \
echo $(REVISION)\"$(revision)\"\; > revision.cc; \
echo const char *AsyGLVersion=\"$(ASYGLVERSION)\"\; >> revision.cc; \
@@ -149,6 +159,9 @@ version: $(GCLIB) $(FILES:=.o) $(notdir $(UIFILES:.ui=.py)) GUI/icons_rc.py
asymptote.so: $(COREFILES:=.pic.o) glew.o
$(CXX) $(OPTS) -shared -o asymptote.so revision.o $(COREFILES:=.pic.o) $(SHAREDLIBS)
+liblspcpp.a:
+ cd LspCpp && $(MAKE) CPPFLAGS="@OPTIONS@"
+
all: asy sty man faq asy-keywords.el
$(GCLIB): $(GC).tar.gz
@@ -324,6 +337,7 @@ uninstall-docdir:
clean: FORCE
-rm -f asy asymptote.so *.pic.o *.o *.d *mon.out $(CLEAN)
+ cd LspCpp && $(MAKE) clean
gc-clean: FORCE clean
-if test -d $(GC); then \
@@ -361,9 +375,9 @@ glew.o: glew.c GL/glew.h GL/glew.c config.h
$(CC) -I. $(GLEWOPTS) -o glew.o -c glew.c
.SUFFIXES: .c .cc .o .d .ui .py
-%.o: %.cc
+%.o: %.cc $(GENERATEDENUMS:=.h)
$(CXX) $(OPTS) -o $@ -c $<
-%.d: %.cc
+%.d: %.cc $(GENERATEDENUMS:=.h) $(GCLIB)
@echo Creating $@; \
rm -f $@; \
${CXX} $(MAKEDEPEND) $(MDOPTS) $< > $@.$$$$ 2>/dev/null && \
@@ -383,6 +397,17 @@ glew.o: glew.c GL/glew.h GL/glew.c config.h
%.pic.o: %.cc
$(CXX) $(SHAREDOPTS) -o $@ -c $<
+# Generate V3D headers
+
+%.h: %.csv generate_enums.py $(GENERATEDENUMS:=.csv)
+ $(PYTHON) generate_enums.py -language cxx -o $@ -i $< -name $(notdir $*) -xopt namespace=camp
+
+base/%.asy: %.csv generate_enums.py $(GENERATEDENUMS:=.csv)
+ $(PYTHON) generate_enums.py -language asy -o $@ -i $< -name $(notdir $*)
+
+%.py: %.csv generate_enums.py $(GENERATEDENUMS:=.csv)
+ $(PYTHON) generate_enums.py -language python -o $@ -i $< -name $(notdir $*)
+
ifeq (,$(findstring clean,${MAKECMDGOALS}))
-include $(FILES:=.d)
endif
diff --git a/graphics/asymptote/README b/graphics/asymptote/README
index 2c5895bd85..693b14efaa 100644
--- a/graphics/asymptote/README
+++ b/graphics/asymptote/README
@@ -49,7 +49,7 @@ noted below.
========================================================================
-Source code for the x86_64 and i386 3.0.4 cygwin1.dll libraries is
+Source code for the x86_64 and i386 3.3.3 cygwin1.dll libraries is
available under the GPL license:
https://cygwin.com/snapshots/
diff --git a/graphics/asymptote/ReleaseNotes b/graphics/asymptote/ReleaseNotes
index 19620b64d5..fb0f2b579c 100644
--- a/graphics/asymptote/ReleaseNotes
+++ b/graphics/asymptote/ReleaseNotes
@@ -1,3 +1,29 @@
+Release Notes for Version 2.72
+
+WebGL2 is enabled by default only for examples that use image-based lighting.
+Multiple output formats in threaded interactive mode are now handled correctly.
+CPU partial sum indexing is used in the 3D transparency shader if the compute
+shader fails to compile.
+
+Release Notes for Version 2.71
+
+Support for the portable compressed 3D vector file format V3D was added.
+The default value of settings.prc was changed to false.
+Efficient order-independent transparency was implemented for modern OpenGL
+platforms and the OSMesa offscreen rendering engine (with no interactive
+transparency support for Mac OS X and WebGL). The WebGL library now uses
+WebGL2 if available. Image-based lighting was implemented.
+Many bug fixes and improvements were made to Xasy, allowing objects drawn
+with the graphical editor to be saved to and restored from a .xasy file, as
+well as being exportable to an .asy file. A function was added to graph a
+parametric function with control points determined by the specified
+derivative. The recommended PostScript viewer for MSWindows is now Sumatra PDF.
+The workflow for generating transparent PDFs and PNGs was fixed.
+Emacs lasy-mode was patched to work with Emacs >= 23. Support for the Language
+Server Protocol was added. Compilation with COMPACT=0 is supported again.
+All threads now return the same error code. A remote command-line interface to
+http://asymptote.ualberta.ca is now available.
+
Release Notes for Version 2.70
A stack overflow was fixed. Under MSWindows, problems with SVG generation and
diff --git a/graphics/asymptote/_config.yml b/graphics/asymptote/_config.yml
new file mode 100644
index 0000000000..c4192631f2
--- /dev/null
+++ b/graphics/asymptote/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-cayman \ No newline at end of file
diff --git a/graphics/asymptote/abs3doutfile.h b/graphics/asymptote/abs3doutfile.h
new file mode 100644
index 0000000000..2871320952
--- /dev/null
+++ b/graphics/asymptote/abs3doutfile.h
@@ -0,0 +1,75 @@
+#ifndef ABS3DOUTFILE_H
+#define ABS3DOUTFILE_H
+
+#include "common.h"
+#include "triple.h"
+#include "prcfile.h"
+#include "material.h"
+
+namespace camp
+{
+
+inline bool distinct(const uint32_t *I, const uint32_t *J)
+{
+ return I[0] != J[0] || I[1] != J[1] || I[2] != J[2];
+}
+
+class abs3Doutfile : public gc {
+protected:
+ bool singleprecision;
+public:
+ abs3Doutfile(bool singleprecision=false) : singleprecision(singleprecision) {}
+ virtual ~abs3Doutfile() = default;
+
+ virtual void close()=0;
+
+ virtual void addPatch(triple const* controls, triple const& Min, triple const& Max, prc::RGBAColour const* c) = 0;
+
+ virtual void addStraightPatch(
+ triple const* controls, triple const& Min, triple const& Max, prc::RGBAColour const* c) = 0;
+
+ virtual void addBezierTriangle(
+ triple const* controls, triple const& Min, triple const& Max, prc::RGBAColour const* c) = 0;
+
+ virtual void addStraightBezierTriangle(
+ triple const* controls, triple const& Min, triple const& Max, prc::RGBAColour const* c) = 0;
+
+ virtual void addMaterial(Material const& mat) = 0;
+
+ virtual void addSphere(triple const& center, double radius) = 0;
+
+ virtual void addHemisphere(triple const& center, double radius, double const& polar, double const& azimuth) = 0;
+
+ virtual void addCylinder(triple const& center, double radius, double height,
+ double const& polar, const double& azimuth,
+ bool core) = 0;
+
+ virtual void addDisk(triple const& center, double radius,
+ double const& polar, const double& azimuth) = 0;
+
+ virtual void addTube(const triple* g, double width,
+ const triple& Min, const triple& Max, bool core) = 0;
+
+ virtual void addTriangles(size_t nP, const triple* P, size_t nN,
+ const triple* N, size_t nC, const prc::RGBAColour* C,
+ size_t nI, const uint32_t (* PI)[3],
+ const uint32_t (* NI)[3], const uint32_t (* CI)[3],
+ const triple& Min, const triple& Max) = 0;
+
+ virtual void addCurve(const triple& z0, const triple& c0,
+ const triple& c1, const triple& z1,
+ const triple& Min, const triple& Max) = 0;
+
+ virtual void addCurve(const triple& z0, const triple& z1,
+ const triple& Min, const triple& Max) = 0;
+
+ virtual void addPixel(const triple& z0, double width,
+ const triple& Min, const triple& Max) = 0;
+
+ virtual void precision(int digits) = 0;
+
+};
+
+}
+
+#endif
diff --git a/graphics/asymptote/absyn.cc b/graphics/asymptote/absyn.cc
index 8ff3148dc2..0144977813 100644
--- a/graphics/asymptote/absyn.cc
+++ b/graphics/asymptote/absyn.cc
@@ -22,7 +22,8 @@ void prettyindent(ostream &out, Int indent)
{
for (Int i = 0; i < indent; i++) out << " ";
}
-void prettyname(ostream &out, string name, Int indent) {
+void prettyname(ostream &out, string name, Int indent, position pos) {
+ pos.print(out);
prettyindent(out,indent);
out << name << "\n";
}
diff --git a/graphics/asymptote/absyn.h b/graphics/asymptote/absyn.h
index c8b85009ec..a25d463c64 100644
--- a/graphics/asymptote/absyn.h
+++ b/graphics/asymptote/absyn.h
@@ -10,6 +10,7 @@
#define ABSYN_H
#include "common.h"
+#include "symbolmaps.h"
#include "errormsg.h" // For position
// Forward declaration for markPos.
@@ -37,13 +38,14 @@ public:
}
virtual void prettyprint(ostream &out, Int indent) = 0;
+ virtual void createSymMap(AsymptoteLsp::SymbolContext* symContext) {}
private: // Non-copyable
void operator=(const absyn&);
absyn(const absyn&);
};
void prettyindent(ostream &out, Int indent);
-void prettyname(ostream &out, string name, Int indent);
+void prettyname(ostream &out, string name, Int indent, position pos);
class name;
class ty;
diff --git a/graphics/asymptote/asy-keywords.el b/graphics/asymptote/asy-keywords.el
index a24374785b..bd6d7ff4a3 100644
--- a/graphics/asymptote/asy-keywords.el
+++ b/graphics/asymptote/asy-keywords.el
@@ -2,7 +2,7 @@
;; This file is automatically generated by asy-list.pl.
;; Changes will be overwritten.
;;
-(defvar asy-keywords-version "2.70")
+(defvar asy-keywords-version "2.72")
(defvar asy-keyword-name '(
and controls tension atleast curl if else while for do return break continue struct typedef new access import unravel from include quote static public private restricted this explicit true false null cycle newframe operator ))
@@ -11,7 +11,7 @@ and controls tension atleast curl if else while for do return break continue str
Braid FitResult Label Legend Solution TreeNode abscissa arc arrowhead binarytree binarytreeNode block bool bool3 bounds bqe circle conic coord coordsys cputime ellipse evaluatedpoint file filltype frame grid3 guide horner hsv hyperbola int inversion key light line linefit marginT marker mass node object pair parabola patch path path3 pen picture point position positionedvector projection rational real revolution scaleT scientific segment side simplex slice solution splitface string surface tensionSpecifier ticklocate ticksgridT tickvalues transform transformation tree triangle trilinear triple vector vertex void ))
(defvar asy-function-name '(
-AND Arc ArcArrow ArcArrows Arrow Arrows AtA Automatic AvantGarde B03 B13 B23 B33 BBox BWRainbow BWRainbow2 Bar Bars BeginArcArrow BeginArrow BeginBar BeginDotMargin BeginMargin BeginPenMargin Blank Bookman Bottom BottomTop Bounds Break Broken BrokenLog CLZ CTZ Ceil Circle CircleBarIntervalMarker Cos Courier CrossIntervalMarker DOSendl DOSnewl DefaultFormat DefaultLogFormat Degrees Dir DotMargin DotMargins Dotted Draw Drawline Embed EndArcArrow EndArrow EndBar EndDotMargin EndMargin EndPenMargin Fill FillDraw Finite Floor Format Full Gaussian Gaussrand Gaussrandpair Gradient Grayscale Helvetica Hermite HookHead InOutTicks InTicks Jn Label Landscape Left LeftRight LeftTicks Legend Linear Log LogFormat Margin Margins Mark MidArcArrow MidArrow NOT NewCenturySchoolBook NoBox NoMargin NoModifier NoTicks NoTicks3 NoZero NoZeroFormat None OR OmitFormat OmitTick OmitTickInterval OmitTickIntervals OutTicks Ox Oy Palatino PaletteTicks Pen PenMargin PenMargins Pentype Portrait RGB RadialShade RadialShadeDraw Rainbow Range Relative Right RightTicks Rotate Round SQR Scale ScaleX ScaleY ScaleZ Seascape Shift Sin Slant Spline StickIntervalMarker Straight Symbol Tan TeXify Ticks Ticks3 TildeIntervalMarker TimesRoman Top TrueMargin UnFill UpsideDown Wheel X XEquals XOR XY XYEquals XYZero XYgrid XZEquals XZZero XZero XZgrid Y YEquals YXgrid YZ YZEquals YZZero YZero YZgrid Yn Z ZX ZXgrid ZYgrid ZapfChancery ZapfDingbats _begingroup3 _cputime _draw _eval _findroot _image _labelpath _projection _shipout _strokepath _texpath aCos aSin aTan abort abs abs2 accel acos acosh acot acsc activatequote add addArrow addMargins addSaveFunction addpenarc addpenline addseg adjust alias align all altitude angabscissa angle angledegrees angpoint animate annotate anticomplementary antipedal apply approximate arc arcarrowsize arccircle arcdir arcfromcenter arcfromfocus arclength arcnodesnumber arcpoint arcsubtended arcsubtendedcenter arctime arctopath array arrow arrow2 arrowbase arrowbasepoints arrowsize ascii asec asin asinh ask assert asy asycode asydir asyfigure asyfilecode asyinclude asywrite atan atan2 atanh atbreakpoint atexit attach attract atupdate autoformat autoscale autoscale3 axes axes3 axialshade axis axiscoverage azimuth babel background bangles bar barmarksize barsize basealign baseline bbox beep begin beginclip begingroup beginpoint between bevel bezier bezierP bezierPP bezierPPP bezulate bibliography bibliographystyle binarytree binarytreeNode binomial bins bisector bisectorpoint bispline bispline0 bitreverse blend blockconnector box bqe brace breakpoint breakpoints brick buildRestoreDefaults buildRestoreThunk buildcycle bulletcolor byte calculateScaling canonical canonicalcartesiansystem cartesiansystem case1 case2 case3 cbrt cd ceil center centerToFocus centroid cevian change2 changecoordsys checkSegment check_fpt_zero checkconditionlength checker checkincreasing checklengths checkposition checkpt checkptincube checktriangle choose circle circlebarframe circlemarkradius circlenodesnumber circumcenter circumcircle clamped clear clip clipdraw close cmyk code colatitude collect collinear color colorless colors colorspace comma compassmark complement complementary concat concurrent cone conic conicnodesnumber conictype conj connect containmentTree contains contour contour3 controlSpecifier convert coordinates coordsys copy copyPairOrTriple cos cosh cot countIntersections cputime crop cropcode cross crossframe crosshatch crossmarksize csc cubicroots curabscissa curlSpecifier curpoint currentarrow currentexitfunction currentmomarrow currentpolarconicroutine curve cut cutafter cutbefore cyclic cylinder deactivatequote debugger deconstruct defaultdir defaultformat defaultpen defined degenerate degrees delete deletepreamble determinant diagonal diamond diffdiv dir dirSpecifier dirtime display distance divisors do_overpaint dot dotframe dotsize downcase draw drawAll drawCylinder drawDisk drawDoubleLine drawFermion drawGhost drawGluon drawMomArrow drawPhoton drawScalar drawSphere drawTube drawVertex drawVertexBox drawVertexBoxO drawVertexBoxX drawVertexO drawVertexOX drawVertexTriangle drawVertexTriangleO drawVertexX drawarrow drawarrow2 drawbeziertriangle drawline drawpixel drawstrokepath drawtick duplicate elle ellipse ellipsenodesnumber embed embed3 embedplayer empty enclose end endclip endgroup endgroup3 endl endpoint endpoints eof eol equation equations erase erasestep erf erfc error errorbar errorbars eval excenter excircle exit exitfunction exp expfactors expi expm1 exradius extend extension extouch fabs factorial fermat fft fhorner figure file filecode fill filldraw filloutside fillrule filltype find findall findroot finite finiteDifferenceJacobian firstcut firstframe fit fit2 fixedscaling floor flush fmdefaults fmod focusToCenter font fontcommand fontsize foot format frac frequency fromCenter fromFocus fspline functionshade gamma gcd generate_random_backtrace generateticks gergonne getc getint getpair getreal getstring gettriple gluon gouraudshade graph graphic graphicscale gray grestore grid grid3 gsave halfbox hatch hdiffdiv hermite hex histogram history hline hprojection hsv hyperbola hyperbolanodesnumber hyperlink hypot identity image implicitsurface incenter incentral incircle increasing incrementposition indexedfigure initdefaults initialized input inradius insert inside insphere integrate interactive interior interp interpolate intersect intersection intersectionpoint intersectionpoints intersections intouch inverse inversion invisible is3D isDuplicate isnan isogonal isogonalconjugate isometry isotomic isotomicconjugate isparabola italic item jobname key kurtosis kurtosisexcess label labelaxis labelmargin labelpath labels labeltick labelx labelx3 labely labely3 labelz labelz3 lastcut latex latitude latticeshade layer layout lcm ldexp leastsquares legend legenditem length lexorder lift light limits line linear linecap lineinversion linejoin linemargin lineskip linetype linewidth link list lm_enorm lm_evaluate_default lm_lmdif lm_lmpar lm_minimize lm_print_default lm_print_quiet lm_qrfac lm_qrsolv locale locate locatefile location log log10 log1p logaxiscoverage longitude lookup make3dgrid makeMappingArray makeNode makecircle makedraw makepen maketriangle map mapArray mapTemplate margin markangle markangleradius markanglespace markarc marker markinterval marknodes markrightangle markthin markuniform mass masscenter massformat math max max3 maxAfterTransform maxbezier maxbound maxcoords maxlength maxratio maxtimes mean medial median midpoint min min3 minAfterTransform minbezier minbound minipage minratio mintimes miterlimit mktemp momArrowPath momarrowsize monotonic multifigure nGrad nativeformat natural newl newpage newslide newton newtree nextframe nextnormal nextpage nib nodabscissa node none norm normalout normalvideo notaknot nowarn numberpage nurb object offset onpath opacity opposite orient orientation origin orthic orthocentercenter outdirectory outformat outline outname outprefix output overloadedMessage overwrite pack pad pairs palette parabola parabolanodesnumber parallel parallelogram partialsum patchwithnormals path path3 pathbetween pathinface pattern pause pdf pedal periodic perp perpendicular perpendicularmark phantom phi1 phi2 phi3 phi4 photon piecewisestraight point polar polarconicroutine polargraph polygon popcount postcontrol postscript pow10 ppoint prc prc0 prconly precision precontrol prepend printBytecode print_random_addresses progress project projection projecttospan projecttospan_findcoeffs purge pwhermite quadpatches quadrant quadraticroots quantize quarticroots quotient radialshade radians radicalcenter radicalline radius rand randompath rationalidentity rd readline realmult realquarticroots rectangle rectangular rectify reflect relabscissa relative relativedistance reldir relpoint reltime remainder remark removeDuplicates rename render replace report resetdefaultpen restore restoredefaults reverse reversevideo rf rfind rgb rgba rgbint rms rotate rotateO rotation round roundbox roundedpath roundrectangle samecoordsys sameside sample save savedefaults saveline scale scale3 scaleO scaleT scaleless scientific search searchtree sec secondaryX secondaryY seconds section sector seek seekeof segment segmentlimits sequence setpens sgn sgnd sharpangle sharpdegrees shift shiftless shipout shipout3 show simeq simplex simplexInit simplexPhase1 simplexPhase2 simplexTableau simplexWrite simpson sin sinh size size3 skewness skip slant sleep slice slope slopefield solve solveBVP sort sourceline sphere split sqrt square srand standardizecoordsys stdev step stickframe stickmarksize stickmarkspace stop straight straightness string stripdirectory stripextension stripfile stripsuffix strokepath subdivide subitem subpath substr sum surface symmedial symmedian system tab tableau tan tangent tangential tangents tanh tell tensionSpecifier tensorshade tex texcolor texify texpath texpreamble texreset texshipout texsize texstring textpath thick thin tick tickMax tickMax3 tickMin tickMin3 ticklabelshift ticklocate tildeframe tildemarksize tile tiling time times title titlepage topbox toplocation transform transformation transpose trembleFuzz triangle triangleAbc triangleabc triangletoquads trianglewithnormals triangulate tricoef tridiagonal trilinear trim truepoint tube type uncycle unfill uniform unique unit unitrand unitsize unityroot unstraighten upcase updatefunction uperiodic upscale uptodate usepackage usersetting usetypescript usleep value variance variancebiased vbox vector vectorfield verbatim view vline vperiodic vprojection warn warning windingnumber write xasyKEY xaxis xaxis3 xaxis3At xaxisAt xequals xlimits xmap xpart xscale xscaleO xtick xtick3 xtrans yaxis yaxis3 yaxis3At yaxisAt yequals ylimits ypart yscale yscaleO ytick ytick3 ytrans zaxis3 zaxis3At zero zlimits zpart ztick ztick3 ztrans ))
+AND Align Arc ArcArrow ArcArrows Arrow Arrows AtA Automatic AvantGarde B03 B13 B23 B33 BBox BWRainbow BWRainbow2 Bar Bars BeginArcArrow BeginArrow BeginBar BeginDotMargin BeginMargin BeginPenMargin Blank Bookman Bottom BottomTop Bounds Break Broken BrokenLog CLZ CTZ Ceil Circle CircleBarIntervalMarker Cos Courier CrossIntervalMarker DOSendl DOSnewl DefaultFormat DefaultLogFormat Degrees Dir DotMargin DotMargins Dotted Draw Drawline Embed EndArcArrow EndArrow EndBar EndDotMargin EndMargin EndPenMargin Fill FillDraw Finite Floor Format Full Gaussian Gaussrand Gaussrandpair Gradient Grayscale Helvetica Hermite HookHead InOutTicks InTicks Jn Label Landscape Left LeftRight LeftTicks Legend Linear Log LogFormat Margin Margins Mark MidArcArrow MidArrow NOT NewCenturySchoolBook NoBox NoMargin NoModifier NoTicks NoTicks3 NoZero NoZeroFormat None OR OmitFormat OmitTick OmitTickInterval OmitTickIntervals OutTicks Ox Oy Palatino PaletteTicks Pen PenMargin PenMargins Pentype Portrait RGB RadialShade RadialShadeDraw Rainbow Range Relative Right RightTicks Rotate Round SQR Scale ScaleX ScaleY ScaleZ Seascape Shift Sin Slant Spline StickIntervalMarker Straight Symbol Tan TeXify Ticks Ticks3 TildeIntervalMarker TimesRoman Top TrueMargin UnFill UpsideDown Wheel X XEquals XOR XY XYEquals XYZero XYgrid XZEquals XZZero XZero XZgrid Y YEquals YXgrid YZ YZEquals YZZero YZero YZgrid Yn Z ZX ZXgrid ZYgrid ZapfChancery ZapfDingbats _begingroup3 _cputime _draw _eval _findroot _image _labelpath _projection _shipout _strokepath _texpath aCos aSin aTan abort abs abs2 accel acos acosh acot acsc activatequote add addArrow addMargins addSaveFunction addpenarc addpenline addseg adjust alias align all altitude angabscissa angle angledegrees angpoint animate annotate anticomplementary antipedal apply approximate arc arcarrowsize arccircle arcdir arcfromcenter arcfromfocus arclength arcnodesnumber arcpoint arcsubtended arcsubtendedcenter arctime arctopath array arrow arrow2 arrowbase arrowbasepoints arrowsize ascii asec asin asinh ask assert asy asycode asydir asyfigure asyfilecode asyinclude asywrite atan atan2 atanh atbreakpoint atexit attach attract atupdate autoformat autoscale autoscale3 axes axes3 axialshade axis axiscoverage azimuth babel background bangles bar barmarksize barsize basealign baseline bbox beep begin beginclip begingroup beginpoint between bevel bezier bezierP bezierPP bezierPPP bezulate bibliography bibliographystyle binarytree binarytreeNode binomial bins bisector bisectorpoint bispline bispline0 bitreverse blend blockconnector box bqe brace breakpoint breakpoints brick buildRestoreDefaults buildRestoreThunk buildcycle bulletcolor byte byteinv calculateScaling canonical canonicalcartesiansystem cartesiansystem case1 case2 case3 cbrt cd ceil center centerToFocus centroid cevian change2 changecoordsys checkSegment check_fpt_zero checkconditionlength checker checkincreasing checklengths checkposition checkpt checkptincube checktriangle choose circle circlebarframe circlemarkradius circlenodesnumber circumcenter circumcircle clamped clear clip clipdraw close cmyk code colatitude collect collinear color colorless colors colorspace comma compassmark complement complementary concat concurrent cone conic conicnodesnumber conictype conj connect containmentTree contains contour contour3 controlSpecifier convert coordinates coordsys copy copyPairOrTriple cos cosh cot countIntersections cputime crop cropcode cross crossframe crosshatch crossmarksize csc cubicroots curabscissa curlSpecifier curpoint currentarrow currentexitfunction currentmomarrow currentpolarconicroutine curve cut cutafter cutbefore cyclic cylinder deactivatequote debugger deconstruct defaultdir defaultformat defaultpen defined degenerate degrees delete deletepreamble determinant diagonal diamond diffdiv dir dirSpecifier dirtime display distance divisors do_overpaint dot dotframe dotsize downcase draw drawAll drawCylinder drawDisk drawDoubleLine drawFermion drawGhost drawGluon drawMomArrow drawPhoton drawScalar drawSphere drawTube drawVertex drawVertexBox drawVertexBoxO drawVertexBoxX drawVertexO drawVertexOX drawVertexTriangle drawVertexTriangleO drawVertexX drawarrow drawarrow2 drawbeziertriangle drawline drawpixel drawstrokepath drawtick duplicate elle ellipse ellipsenodesnumber embed embed3 embedplayer empty enclose end endclip endgroup endgroup3 endl endpoint endpoints eof eol equation equations erase erasestep erf erfc error errorbar errorbars eval excenter excircle exit exitfunction exp expfactors expi expm1 exradius extend extension extouch fabs factorial fermat fft fhorner figure file filecode fill filldraw filloutside fillrule filltype find findall findroot finite finiteDifferenceJacobian firstcut firstframe fit fit2 fixedscaling floor flush fmdefaults fmod focusToCenter font fontcommand fontsize foot format frac frequency fromCenter fromFocus fspline functionshade gamma gcd generate_random_backtrace generateticks gergonne getc getint getpair getreal getstring gettriple gluon gouraudshade graph graphic graphicscale graphwithderiv gray grestore grid grid3 gsave halfbox hatch hdiffdiv hermite hex histogram history hline hprojection hsv hyperbola hyperbolanodesnumber hyperlink hypot identity image implicitsurface importv3d incenter incentral incircle increasing incrementposition indexedfigure initdefaults initialized input inradius insert inside insphere integrate interactive interior interp interpolate intersect intersection intersectionpoint intersectionpoints intersections intouch inverse inversion invisible is3D isDuplicate isnan isogonal isogonalconjugate isometry isotomic isotomicconjugate isparabola italic item jobname key kurtosis kurtosisexcess label labelaxis labelmargin labelpath labels labeltick labelx labelx3 labely labely3 labelz labelz3 lastcut latex latitude latticeshade layer layout lcm ldexp leastsquares legend legenditem length lexorder lift light limits line linear linecap lineinversion linejoin linemargin lineskip linetype linewidth link list lm_enorm lm_evaluate_default lm_lmdif lm_lmpar lm_minimize lm_print_default lm_print_quiet lm_qrfac lm_qrsolv locale locate locatefile location log log10 log1p logaxiscoverage longitude lookup make3dgrid makeMappingArray makeNode makecircle makedraw makepen maketriangle map mapArray mapTemplate margin markangle markangleradius markanglespace markarc marker markinterval marknodes markrightangle markthin markuniform mass masscenter massformat math max max3 maxAfterTransform maxbezier maxbound maxcoords maxlength maxratio maxtimes mean medial median midpoint min min3 minAfterTransform minbezier minbound minipage minratio mintimes miterlimit mktemp momArrowPath momarrowsize monotonic multifigure nGrad nativeformat natural newl newpage newslide newton newtree nextframe nextnormal nextpage nib nodabscissa node none norm normalout normalvideo notaknot nowarn numberpage nurb object offset onpath opacity opposite orient orientation origin orthic orthocentercenter outdirectory outformat outline outname outprefix output overloadedMessage overwrite pack pad pairs palette parabola parabolanodesnumber parallel parallelogram partialsum patchwithnormals path path3 pathbetween pathinface pattern pause pdf pedal periodic perp perpendicular perpendicularmark phantom phi1 phi2 phi3 phi4 photon piecewisestraight point polar polarconicroutine polargraph polygon popcount postcontrol postscript pow10 ppoint prc prc0 prconly precision precontrol prepend primitive printBytecode print_random_addresses progress project projection projecttospan projecttospan_findcoeffs purge pwhermite quadpatches quadrant quadraticroots quantize quarticroots quotient radialshade radians radicalcenter radicalline radius rand randompath rationalidentity rd readline realmult realquarticroots rectangle rectangular rectify reflect relabscissa relative relativedistance reldir relpoint reltime remainder remark removeDuplicates rename render replace report resetdefaultpen restore restoredefaults reverse reversevideo rf rfind rgb rgba rgbint rms rotate rotateO rotation round roundbox roundedpath roundrectangle samecoordsys sameside sample save savedefaults saveline scale scale3 scaleO scaleT scaleless scientific search searchtree sec secondaryX secondaryY seconds section sector seek seekeof segment segmentlimits sequence setpens sgn sgnd sharpangle sharpdegrees shift shiftless shipout shipout3 show simeq simplex simplexInit simplexPhase1 simplexPhase2 simplexTableau simplexWrite simpson sin sinh size size3 skewness skip slant sleep slice slope slopefield solve solveBVP sort sourceline sphere split sqrt square srand standardizecoordsys stdev step stickframe stickmarksize stickmarkspace stop straight straightness string stripdirectory stripextension stripfile stripsuffix strokepath subdivide subitem subpath substr sum surface symmedial symmedian system tab tableau tan tangent tangential tangents tanh tell tensionSpecifier tensorshade tex texcolor texify texpath texpreamble texreset texshipout texsize texstring textpath thick thin tick tickMax tickMax3 tickMin tickMin3 ticklabelshift ticklocate tildeframe tildemarksize tile tiling time times title titlepage topbox transform transformation transpose trembleFuzz triangle triangleAbc triangleabc triangletoquads trianglewithnormals triangulate tricoef tridiagonal trilinear trim truepoint tube type uncycle unfill uniform unique unit unitrand unitsize unityroot unstraighten upcase updatefunction uperiodic upscale uptodate usepackage usersetting usetypescript usleep value variance variancebiased vbox vector vectorfield verbatim view vline vperiodic vprojection warn warning windingnumber write xasyKEY xaxis xaxis3 xaxis3At xaxisAt xequals xlimits xmap xpart xscale xscaleO xtick xtick3 xtrans yaxis yaxis3 yaxis3At yaxisAt yequals ylimits ypart yscale yscaleO ytick ytick3 ytrans zaxis3 zaxis3At zero zlimits zpart ztick ztick3 ztrans ))
(defvar asy-variable-name '(
-Accent AliceBlue Align Allow AntiqueWhite Apricot Aqua Aquamarine Aspect Azure BeginPoint Beige Bisque Bittersweet Black BlanchedAlmond Blue BlueGreen BlueViolet Blues Both BrBG Break BrickRed Brown BuGn BuPu BurlyWood BurntOrange CCW CMRmap CW CadetBlue CarnationPink Center Centered Cerulean Chartreuse Chocolate Coeff Coral CornflowerBlue Cornsilk Crimson Crop Cyan Dandelion Dark2 DarkBlue DarkCyan DarkGoldenrod DarkGray DarkGreen DarkKhaki DarkMagenta DarkOliveGreen DarkOrange DarkOrchid DarkRed DarkSalmon DarkSeaGreen DarkSlateBlue DarkSlateGray DarkTurquoise DarkViolet DeepPink DeepSkyBlue DefaultHead DimGray DodgerBlue Dotted Down Draw E ENE EPS ESE E_Euler E_PC E_RK2 E_RK3BS Emerald EndPoint Euler Fill FillDraw FireBrick FloralWhite ForestGreen Fuchsia Gainsboro GhostWhite GnBu Gold Goldenrod Gray Green GreenYellow Greens Greys Honeydew HookHead Horizontal HotPink I IgnoreAspect IndianRed Indigo Infinity Ivory JOIN_IN JOIN_OUT JungleGreen Khaki LM_DWARF LM_MACHEP LM_SQRT_DWARF LM_SQRT_GIANT LM_USERTOL Label Lavender LavenderBlush LawnGreen Left LeftJustified LeftSide LemonChiffon LightBlue LightCoral LightCyan LightGoldenrodYellow LightGreen LightGrey LightPink LightSalmon LightSeaGreen LightSkyBlue LightSlateGray LightSteelBlue LightYellow Lime LimeGreen Linear Linen Log Logarithmic Magenta Mahogany Mark MarkFill MarkPath Maroon Max MediumAquamarine MediumBlue MediumOrchid MediumPurple MediumSeaGreen MediumSlateBlue MediumSpringGreen MediumTurquoise MediumVioletRed Melon MidPoint MidnightBlue Min MintCream MistyRose Moccasin Move MoveQuiet Mulberry N NE NNE NNW NULL_VERTEX NW NavajoWhite Navy NavyBlue NoAlign NoCrop NoFill NoSide OldLace Olive OliveDrab OliveGreen OrRd Orange OrangeRed Oranges Orchid Ox Oy PC PRGn Paired PaleGoldenrod PaleGreen PaleTurquoise PaleVioletRed PapayaWhip Pastel1 Pastel2 Peach PeachPuff Periwinkle Peru PiYG PineGreen Pink Plum PowderBlue ProcessBlue PuBu PuBuGn PuOr PuRd Purple Purples RELEASE RK2 RK3 RK3BS RK4 RK5 RK5DP RK5F RawSienna RdBu RdGy RdPu RdYlBu RdYlGn Red RedOrange RedViolet Reds Rhodamine Right RightJustified RightSide RosyBrown RoyalBlue RoyalPurple RubineRed S SE SSE SSW SW SaddleBrown Salmon SandyBrown SeaGreen Seashell Sepia Set1 Set2 Set3 Sienna Silver SimpleHead SkyBlue SlateBlue SlateGray Snow Spectral SpringGreen SteelBlue Suppress SuppressQuiet Tan TeXHead Teal TealBlue Thistle Ticksize Tomato Turquoise UnFill Up VERSION Value Vertical Violet VioletRed W WNW WSW Wheat White WhiteSmoke WildStrawberry XHIGH XLOW XYAlign YAlign YHIGH YLOW Yellow YellowGreen YellowOrange YlGn YlGnBu YlOrBr YlOrRd ZHIGH ZLOW _outpipe aboveequationskip addpenarc addpenline align allowstepping angularsystem animationdelay appendsuffix arcarrowangle arcarrowfactor arrow2sizelimit arrowangle arrowbarb arrowdir arrowfactor arrowhookfactor arrowlength arrowsizelimit arrowtexfactor authorpen autumn axis axiscoverage axislabelfactor background backgroundcolor backgroundpen barfactor barmarksizefactor basealign baselinetemplate bernstein beveljoin bigvertexpen bigvertexsize binary black blue bm bone bottom bp bracedefaultratio braceinnerangle bracemidangle braceouterangle brg brown bullet bwr byfoci byvertices camerafactor chartreuse circlemarkradiusfactor circlenodesnumberfactor circleprecision circlescale cividis cm codefile codepen codeskip colorPen coloredNodes coloredSegments conditionlength conicnodesfactor cool coolwarm copper count cputimeformat crossmarksizefactor currentcoordsys currentlight currentpatterns currentpen currentpicture currentposition currentprojection curvilinearsystem cuttings cyan darkblue darkbrown darkcyan darkgray darkgreen darkgrey darkmagenta darkolive darkred dashdotted dashed datepen dateskip debuggerlines debugging deepblue deepcyan deepgray deepgreen deepgrey deepmagenta deepred deepyellow default defaultControl defaultS defaultbackpen defaultcoordsys defaultexcursion defaultfilename defaultformat defaultmassformat defaultpen defaultseparator differentlengths dot dotfactor dotfilltype dotframe dotted doublelinepen doublelinespacing down duplicateFuzz ellipsenodesnumberfactor eps epsgeo epsilon evenodd expansionfactor extendcap fermionpen figureborder figuremattpen file3 firstnode firststep foregroundcolor fuchsia fuzz gapfactor ghostpen gist_earth gist_ncar gist_stern gluonamplitude gluonpen gluonratio gray green grey hatchepsilon havepagenumber heavyblue heavycyan heavygray heavygreen heavygrey heavymagenta heavyred hline hot hsv hwratio hyperbolanodesnumberfactor identity identity4 ignore implicitshipout inch inches includegraphicscommand inf inferno infinity institutionpen intMax intMin invert invisible itempen itemskip itemstep jet labelmargin landscape lastnode left legendhskip legendlinelength legendmargin legendmarkersize legendmaxrelativewidth legendvskip lightblue lightcyan lightgray lightgreen lightgrey lightmagenta lightolive lightred lightyellow linemargin lm_infmsg lm_shortmsg longdashdotted longdashed magenta magma magneticRadius mantissaBits markangleradius markangleradiusfactor markanglespace markanglespacefactor maxrefinements mediumblue mediumcyan mediumgray mediumgreen mediumgrey mediummagenta mediumred mediumyellow middle minDistDefault minblockheight minblockwidth mincirclediameter minipagemargin minipagewidth minvertexangle miterjoin mm momarrowfactor momarrowlength momarrowmargin momarrowoffset momarrowpen monoPen morepoints nCircle nan newbulletcolor ngraph nil nipy_spectral nmesh nobasealign nodeMarginDefault nodesystem nomarker nopoint noprimary nullpath nullpen numarray ocgindex oldbulletcolor olive orange origin overpaint page pageheight pagemargin pagenumberalign pagenumberpen pagenumberposition pagewidth paleblue palecyan palegray palegreen palegrey palemagenta palered paleyellow parabolanodesnumberfactor perpfactor phi photonamplitude photonpen photonratio pi pink plain plain_bounds plain_scaling plasma plus preamblenodes pt purple r3 r4a r4b randMax realDigits realEpsilon realMax realMin red relativesystem reverse right roundcap roundjoin royalblue salmon saveFunctions scalarpen seismic sequencereal settings signedtrailingzero simplex solid spinner spring springgreen sqrtEpsilon squarecap squarepen startposition stdin stdout stepfactor stepfraction steppagenumberpen stepping stickframe stickmarksizefactor stickmarkspacefactor summer swap tab10 tab20 tab20b tab20c textpen ticksize tildeframe tildemarksizefactor tinv titlealign titlepagepen titlepageposition titlepen titleskip top trailingzero treeLevelStep treeMinNodeWidth treeNodeStep trembleAngle trembleFrequency trembleRandom tubegranularity twilight twilight_shifted undefined unitcircle unitsquare up urlpen urlskip version vertexpen vertexsize viewportmargin viewportsize viridis vline white winter wistia wye yellow ylabelwidth zeroTransform zerotickfuzz zerowinding ))
+Accent AliceBlue Align Allow AntiqueWhite Apricot Aqua Aquamarine Aspect Azure BeginPoint Beige Bisque Bittersweet Black BlanchedAlmond Blue BlueGreen BlueViolet Blues Both BrBG Break BrickRed Brown BuGn BuPu BurlyWood BurntOrange CCW CMRmap CW CadetBlue CarnationPink Center Centered Cerulean Chartreuse Chocolate Coeff Coral CornflowerBlue Cornsilk Crimson Crop Cyan Dandelion Dark2 DarkBlue DarkCyan DarkGoldenrod DarkGray DarkGreen DarkKhaki DarkMagenta DarkOliveGreen DarkOrange DarkOrchid DarkRed DarkSalmon DarkSeaGreen DarkSlateBlue DarkSlateGray DarkTurquoise DarkViolet DeepPink DeepSkyBlue DefaultHead DimGray DodgerBlue Dotted Down Draw E ENE EPS ESE E_Euler E_PC E_RK2 E_RK3BS Emerald EndPoint Euler Fill FillDraw FireBrick FloralWhite ForestGreen Fuchsia Gainsboro GhostWhite GnBu Gold Goldenrod Gray Green GreenYellow Greens Greys Honeydew HookHead Horizontal HotPink I IgnoreAspect IndianRed Indigo Infinity Ivory JOIN_IN JOIN_OUT JungleGreen Khaki LM_DWARF LM_MACHEP LM_SQRT_DWARF LM_SQRT_GIANT LM_USERTOL Label Lavender LavenderBlush LawnGreen Left LeftJustified LeftSide LemonChiffon LightBlue LightCoral LightCyan LightGoldenrodYellow LightGreen LightGrey LightPink LightSalmon LightSeaGreen LightSkyBlue LightSlateGray LightSteelBlue LightYellow Lime LimeGreen Linear Linen Log Logarithmic Magenta Mahogany Mark MarkFill MarkFillable MarkPath Maroon Max MediumAquamarine MediumBlue MediumOrchid MediumPurple MediumSeaGreen MediumSlateBlue MediumSpringGreen MediumTurquoise MediumVioletRed Melon MidPoint MidnightBlue Min MintCream MistyRose Moccasin Move MoveQuiet Mulberry N NE NNE NNW NULL_VERTEX NW NavajoWhite Navy NavyBlue NoAlign NoCrop NoFill NoSide OldLace Olive OliveDrab OliveGreen OrRd Orange OrangeRed Oranges Orchid Ox Oy PC PRGn Paired PaleGoldenrod PaleGreen PaleTurquoise PaleVioletRed PapayaWhip Pastel1 Pastel2 Peach PeachPuff Periwinkle Peru PiYG PineGreen Pink Plum PowderBlue ProcessBlue PuBu PuBuGn PuOr PuRd Purple Purples RELEASE RK2 RK3 RK3BS RK4 RK5 RK5DP RK5F RawSienna RdBu RdGy RdPu RdYlBu RdYlGn Red RedOrange RedViolet Reds Rhodamine Right RightJustified RightSide RosyBrown RoyalBlue RoyalPurple RubineRed S SE SSE SSW SW SaddleBrown Salmon SandyBrown SeaGreen Seashell Sepia Set1 Set2 Set3 Sienna Silver SimpleHead SkyBlue SlateBlue SlateGray Snow Spectral SpringGreen SteelBlue Suppress SuppressQuiet Tan TeXHead Teal TealBlue Thistle Ticksize Tomato Turquoise UnFill Up VERSION Value Vertical Violet VioletRed W WNW WSW Wheat White WhiteSmoke WildStrawberry XHIGH XLOW XYAlign YAlign YHIGH YLOW Yellow YellowGreen YellowOrange YlGn YlGnBu YlOrBr YlOrRd ZHIGH ZLOW _outpipe aboveequationskip addpenarc addpenline align allowstepping angularsystem animationdelay appendsuffix arcarrowangle arcarrowfactor arrow2sizelimit arrowangle arrowbarb arrowdir arrowfactor arrowhookfactor arrowlength arrowsizelimit arrowtexfactor authorpen autumn axis axiscoverage axislabelfactor background backgroundcolor backgroundpen barfactor barmarksizefactor basealign baselinetemplate bernstein beveljoin bigvertexpen bigvertexsize binary black blue bm bone bottom bp bracedefaultratio braceinnerangle bracemidangle braceouterangle brg brown bullet bwr byfoci byvertices camerafactor chartreuse circlemarkradiusfactor circlenodesnumberfactor circleprecision circlescale cividis cm codefile codepen codeskip colorPen coloredNodes coloredSegments conditionlength conicnodesfactor cool coolwarm copper count cputimeformat crossmarksizefactor currentcoordsys currentlight currentpatterns currentpen currentpicture currentposition currentprojection curvilinearsystem cuttings cyan darkblue darkbrown darkcyan darkgray darkgreen darkgrey darkmagenta darkolive darkred dashdotted dashed datepen dateskip debuggerlines debugging deepblue deepcyan deepgray deepgreen deepgrey deepmagenta deepred deepyellow default defaultControl defaultS defaultbackpen defaultcoordsys defaultexcursion defaultfilename defaultformat defaultmassformat defaultpen defaultseparator diamond differentlengths dot dotfactor dotfilltype dotframe dotted doublelinepen doublelinespacing down duplicateFuzz ellipsenodesnumberfactor eps epsgeo epsilon evenodd expansionfactor extendcap fermionpen figureborder figuremattpen file3 firstnode firststep foregroundcolor fuchsia fuzz gapfactor ghostpen gist_earth gist_ncar gist_stern gluonamplitude gluonpen gluonratio gray green grey hatchepsilon havepagenumber heavyblue heavycyan heavygray heavygreen heavygrey heavymagenta heavyred hline hot hsv hwratio hyperbolanodesnumberfactor identity identity4 ignore implicitshipout inch inches includegraphicscommand inf inferno infinity institutionpen intMax intMin invert invisible itempen itemskip itemstep jet labelmargin landscape lastnode left legendhskip legendlinelength legendmargin legendmarkersize legendmaxrelativewidth legendvskip lightblue lightcyan lightgray lightgreen lightgrey lightmagenta lightolive lightred lightyellow linemargin lm_infmsg lm_shortmsg longdashdotted longdashed magenta magma magneticRadius mantissaBits markangleradius markangleradiusfactor markanglespace markanglespacefactor maxrefinements mediumblue mediumcyan mediumgray mediumgreen mediumgrey mediummagenta mediumred mediumyellow middle minDistDefault minblockheight minblockwidth mincirclediameter minipagemargin minipagewidth minvertexangle miterjoin mm momarrowfactor momarrowlength momarrowmargin momarrowoffset momarrowpen monoPen morepoints nCircle nan newbulletcolor ngraph nil nipy_spectral nmesh nobasealign nodeMarginDefault nodesystem nomarker nopoint noprimary nullpath nullpen numarray ocgindex oldbulletcolor olive orange origin overpaint page pageheight pagemargin pagenumberalign pagenumberpen pagenumberposition pagewidth paleblue palecyan palegray palegreen palegrey palemagenta palered paleyellow parabolanodesnumberfactor perpfactor phi photonamplitude photonpen photonratio pi pink plain plain_bounds plain_scaling plasma plus preamblenodes pt purple r3 r4a r4b randMax realDigits realEpsilon realMax realMin red relativesystem reverse right roundcap roundjoin royalblue salmon saveFunctions scalarpen seismic sequencereal settings signedtrailingzero simplex solid spinner spring springgreen sqrtEpsilon squarecap squarepen startposition stdin stdout stepfactor stepfraction steppagenumberpen stepping stickframe stickmarksizefactor stickmarkspacefactor summer swap tab10 tab20 tab20b tab20c textpen ticksize tildeframe tildemarksizefactor tinv titlealign titlepagepen titlepageposition titlepen titleskip top trailingzero treeLevelStep treeMinNodeWidth treeNodeStep trembleAngle trembleFrequency trembleRandom tubegranularity twilight twilight_shifted undefined unitcircle unitsquare up urlpen urlskip v3dheadertypes v3dtypes version vertexpen vertexsize viewportmargin viewportsize viridis vline white winter wistia wye yellow ylabelwidth zeroTransform zerotickfuzz zerowinding ))
diff --git a/graphics/asymptote/asy.list b/graphics/asymptote/asy.list
index 6bd03077e5..02bcd37db3 100644
--- a/graphics/asymptote/asy.list
+++ b/graphics/asymptote/asy.list
@@ -68,8 +68,8 @@ path3 subpath(path3 p, real a, real b);
bool isnan(real x);
string jobname(string name);
void print_random_addresses(int n=<default>);
-void attach(picture dest=<default>, frame src, pair position, pair align, bool group=<default>, filltype filltype=<default>, bool above=<default>);
void attach(picture dest=<default>, frame src, pair position=<default>, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+void attach(picture dest=<default>, frame src, pair position, pair align, bool group=<default>, filltype filltype=<default>, bool above=<default>);
real[] quadraticroots(real a, real b, real c);
pair[] quadraticroots(explicit pair a, explicit pair b, explicit pair c);
pen darkcyan;
@@ -106,8 +106,8 @@ void atupdate(void f());
void atupdate()();
void unfill(frame f, path[] g, bool copy=<default>);
void unfill(picture pic=<default>, path[] g, bool copy=<default>);
-bool Bar(picture, path, pen, marginT(path, pen))(real size=<default>);
bool Bar(picture, path, pen, marginT(path, pen));
+bool Bar(picture, path, pen, marginT(path, pen))(real size=<default>);
bool eol(file f);
pen zerowinding;
void atbreakpoint(string f(string, int, int, code));
@@ -144,10 +144,11 @@ real fmod(real x, real y);
real offset(pen p);
pen rgb(pen p);
pen rgb(real r, real g, real b);
+pen rgb(real[] a);
pen rgb(string s);
real inch;
-bool ArcArrow(picture, path, pen, marginT(path, pen));
bool ArcArrow(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, position position=<default>);
+bool ArcArrow(picture, path, pen, marginT(path, pen));
bool ArcArrows(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>);
bool ArcArrows(picture, path, pen, marginT(path, pen));
pen currentpen;
@@ -245,9 +246,9 @@ pair min(frame f);
pair min(explicit path p);
pair min(path[] p);
triple min(path3 p);
+pair min(picture pic, bool user=<default>);
real min(... real[] a);
real min(real m, scaling s, coord[] c);
-pair min(picture pic, bool user=<default>);
real min(real m, scaling s, coord[] c);
int min(... int[] a);
filltype RadialShade(pen penc, pen penr);
@@ -255,31 +256,31 @@ int search(int[] a, int key);
int search(real[] a, real key);
int search(string[] a, string key);
int search(void()()[] a, void key()(), bool less(void()(), void()()));
+int search(Label[] a, Label key, bool less(Label, Label));
int search(real[] a, real key, bool less(real, real));
int search(guide[] a, guide key, bool less(guide, guide));
-int search(object[] a, object key, bool less(object, object));
-int search(pair[] a, pair key, bool less(pair, pair));
-int search(coord[] a, coord key, bool less(coord, coord));
int search(Legend[] a, Legend key, bool less(Legend, Legend));
-int search(Label[] a, Label key, bool less(Label, Label));
+int search(pair[] a, pair key, bool less(pair, pair));
int search(frame[] a, frame key, bool less(frame, frame));
int search(coord[] a, coord key, bool less(coord, coord));
+int search(coord[] a, coord key, bool less(coord, coord));
int search(int[] a, int key, bool less(int, int));
int search(bool3[] a, bool3 key, bool less(bool3, bool3));
+int search(marker[] a, marker key, bool less(marker, marker));
int search(string[] a, string key, bool less(string, string));
int search(path[] a, path key, bool less(path, path));
int search(pen[] a, pen key, bool less(pen, pen));
+int search(picture[] a, picture key, bool less(picture, picture));
int search(bool[] a, bool key, bool less(bool, bool));
int search(triple[] a, triple key, bool less(triple, triple));
-int search(marker[] a, marker key, bool less(marker, marker));
-int search(picture[] a, picture key, bool less(picture, picture));
+int search(object[] a, object key, bool less(object, object));
filltype RadialShadeDraw(real xmargin=<default>, real ymargin=<default>, pen penc, pen penr, pen drawpen=<default>);
real sin(real x);
real[] sin(real[] a);
pair sin(explicit pair z);
pen deepcyan;
void restoredefaults();
-path[] plus;
+path plus;
pair expi(real angle);
triple expi(real polar, real azimuth);
void endclip(frame f);
@@ -347,19 +348,19 @@ pair max(frame f);
pair max(explicit path p);
pair max(path[] p);
triple max(path3 p);
-pair max(picture pic, bool user=<default>);
+real max(real M, scaling s, coord[] c);
real max(real M, scaling s, coord[] c);
int max(... int[] a);
+pair max(picture pic, bool user=<default>);
real max(... real[] a);
-real max(real M, scaling s, coord[] c);
-Label Label(Label L, pair position, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
Label Label(string s, string size=<default>, explicit position position, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
Label Label(Label L, explicit position position, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
Label Label(explicit pair position, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
-Label Label;
Label Label(string s=<default>, string size=<default>, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
+Label Label;
Label Label(string s, string size=<default>, pair position, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
Label Label(Label L, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
+Label Label(Label L, pair position, align align=<default>, pen p=<default>, transform embed(transform)=<default>, filltype filltype=<default>);
string font(pen p=<default>);
pen font(string name, string options=<default>);
pen font(string encoding, string family, string series, string shape);
@@ -404,10 +405,10 @@ void label(picture pic=<default>, Label L, explicit path g, align align=<default
real fabs(real x);
real[] fabs(real[] a);
bool labels(frame f);
+light light(explicit light light);
light light(pen diffuse=<default>, pen specular=<default>, pen background=<default>, real x, real y, real z);
light light(pen diffuse=<default>, pen specular=<default>, pen background=<default>, real specularfactor=<default> ... triple[] position);
light light(pen[] diffuse, pen[] specular=<default>, pen background=<default>, real specularfactor=<default>, triple[] position);
-light light(explicit light light);
real remainder(real x, real y);
int byte(real x);
real camerafactor;
@@ -432,10 +433,10 @@ real erf(real x);
void saveline(string name, string value, bool store=<default>);
pen fuchsia;
filltype filltype(int type=<default>, pen fillpen=<default>, pen drawpen=<default>, void fill2(frame f, path[] g, pen fillpen));
-pen Bookman(string series=<default>, string shape=<default>);
+path box(pair a, pair b);
path box(frame dest, frame src=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
path box(frame f, Label L, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
-path box(pair a, pair b);
+pen Bookman(string series=<default>, string shape=<default>);
frame[] fit(string prefix=<default>, picture[] pictures, string format=<default>, bool view=<default>, string options=<default>, string script=<default>, projection P=<default>);
void seekeof(file f);
path unitcircle;
@@ -528,9 +529,10 @@ bool[] copy(bool[] a, int depth=<default>);
real[][] copy(real[][] a, int depth=<default>);
pen[] copy(pen[] a, int depth=<default>);
coord[] copy(coord[] a, int depth=<default>);
+coord[] copy(coord[] a, int depth=<default>);
object[] copy(object[] a, int depth=<default>);
marker[] copy(marker[] a, int depth=<default>);
-picture[] copy(picture[] a, int depth=<default>);
+Legend[] copy(Legend[] a, int depth=<default>);
pen[][] copy(pen[][] a, int depth=<default>);
path[] copy(path[] a, int depth=<default>);
string[] copy(string[] a, int depth=<default>);
@@ -540,9 +542,8 @@ string[][] copy(string[][] a, int depth=<default>);
frame[] copy(frame[] a, int depth=<default>);
pair[] copy(pair[] a, int depth=<default>);
bool3[] copy(bool3[] a, int depth=<default>);
-coord[] copy(coord[] a, int depth=<default>);
-Legend[] copy(Legend[] a, int depth=<default>);
Label[] copy(Label[] a, int depth=<default>);
+picture[] copy(picture[] a, int depth=<default>);
pair[][] copy(pair[][] a, int depth=<default>);
real[] abs(pair[] a);
real[] abs(triple[] a);
@@ -578,25 +579,25 @@ int[] map(int f(real), real[] a);
bool3[] map(bool3 f(bool3), bool3[] a);
frame[] map(frame f(frame), frame[] a);
coord[] map(coord f(coord), coord[] a);
+coord[] map(coord f(coord), coord[] a);
pen[][] map(pen[] f(pen[]), pen[][] a);
triple[] map(triple f(triple), triple[] a);
pen[] map(pen f(pen), pen[] a);
-coord[] map(coord f(coord), coord[] a);
-Legend[] map(Legend f(Legend), Legend[] a);
-Label[] map(Label f(Label), Label[] a);
pair[] map(pair f(pair), pair[] a);
-object[] map(object f(object), object[] a);
+Legend[] map(Legend f(Legend), Legend[] a);
string[] map(string f(string), string[] a);
+Label[] map(Label f(Label), Label[] a);
void()()[] map(void f()()(void()()), void()()[] a);
pair[][] map(pair[] f(pair[]), pair[][] a);
real[] map(real f(real), real[] a);
-marker[] map(marker f(marker), marker[] a);
-picture[] map(picture f(picture), picture[] a);
+object[] map(object f(object), object[] a);
int[] map(int f(int), int[] a);
string[][] map(string[] f(string[]), string[][] a);
+picture[] map(picture f(picture), picture[] a);
bool[] map(bool f(bool), bool[] a);
path[] map(path f(path), path[] a);
real[][] map(real[] f(real[]), real[][] a);
+marker[] map(marker f(marker), marker[] a);
guide[] map(guide f(guide), guide[] a);
path unstraighten(path p);
path3 unstraighten(path3 p);
@@ -609,16 +610,17 @@ int rfind(string s, string t, int pos=<default>);
pair minratio(frame f);
pair minratio(triple[][] p, pair b);
pair minratio(path3 g);
-string toplocation();
int[] sequence(int n);
pen[][] sequence(pen[] f(int), int n);
coord[] sequence(coord f(int), int n);
+coord[] sequence(coord f(int), int n);
object[] sequence(object f(int), int n);
marker[] sequence(marker f(int), int n);
-picture[] sequence(picture f(int), int n);
+Legend[] sequence(Legend f(int), int n);
int[] sequence(int f(int), int n);
string[][] sequence(string[] f(int), int n);
pair[] sequence(pair f(int), int n);
+int[] sequence(int n, int m, int skip);
guide[] sequence(guide f(int), int n);
pen[] sequence(pen f(int), int n);
void()()[] sequence(void f()()(int), int n);
@@ -626,9 +628,8 @@ bool[] sequence(bool f(int), int n);
string[] sequence(string f(int), int n);
pair[][] sequence(pair[] f(int), int n);
bool3[] sequence(bool3 f(int), int n);
-coord[] sequence(coord f(int), int n);
-Legend[] sequence(Legend f(int), int n);
Label[] sequence(Label f(int), int n);
+picture[] sequence(picture f(int), int n);
real[][] sequence(real[] f(int), int n);
real[] sequence(real f(int), int n);
int[] sequence(int n, int m);
@@ -705,23 +706,23 @@ slice cut(path p, path knife, int n);
bool is3D(frame f);
bool is3D(string format=<default>);
void add(frame dest, frame src);
+void add(picture pic=<default>, void d(frame f, transform t), bool exact=<default>);
+void add(frame dest, frame src, filltype filltype, bool above=<default>);
+void add(frame dest, frame src, bool group, filltype filltype=<default>, bool above=<default>);
+void add(picture pic=<default>, void d(picture, real[][]), bool exact=<default>);
+void add(frame dest, frame src, pair position, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+void add(picture dest=<default>, frame src, pair position=<default>, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+void add(picture src, pair position, bool group=<default>, filltype filltype=<default>, bool above=<default>);
+void add(picture pic=<default>, Label L);
+void add(frame f, transform t=<default>, Label L);
void add(picture dest=<default>, frame src, pair position, pair align, bool group=<default>, filltype filltype=<default>, bool above=<default>);
void add(frame dest, frame src, pair position, pair align, bool group=<default>, filltype filltype=<default>, bool above=<default>);
void add(picture src, bool group=<default>, filltype filltype=<default>, bool above=<default>);
-void add(picture pic=<default>, void d(frame f, transform t), bool exact=<default>);
void add(picture pic=<default>, void d(frame f, real[][] t, picture pic, projection P), bool exact=<default>);
-void add(picture pic=<default>, void d(picture, real[][]), bool exact=<default>);
-void add(picture pic=<default>, Label L);
+void add(picture pic=<default>, void d(picture, transform), bool exact=<default>);
void add(picture dest, picture src, bool group=<default>, filltype filltype=<default>, bool above=<default>);
void add(picture dest, picture src, pair position, bool group=<default>, filltype filltype=<default>, bool above=<default>);
void add(picture dest=<default>, object F, pair position=<default>, bool group=<default>, filltype filltype=<default>, bool above=<default>);
-void add(frame dest, frame src, filltype filltype, bool above=<default>);
-void add(frame dest, frame src, bool group, filltype filltype=<default>, bool above=<default>);
-void add(frame dest, frame src, pair position, bool group=<default>, filltype filltype=<default>, bool above=<default>);
-void add(picture dest=<default>, frame src, pair position=<default>, bool group=<default>, filltype filltype=<default>, bool above=<default>);
-void add(picture pic=<default>, void d(picture, transform), bool exact=<default>);
-void add(frame f, transform t=<default>, Label L);
-void add(picture src, pair position, bool group=<default>, filltype filltype=<default>, bool above=<default>);
plain plain;
void purge(int divisor=<default>);
int Round(real x);
@@ -729,8 +730,8 @@ real sqrt(real x);
real[] sqrt(real[] a);
pair sqrt(explicit pair z);
string[] spinner;
-real[] times(path p, real x);
-real[] times(path p, explicit pair z);
+real[] times(path p, real x, real fuzz=<default>);
+real[] times(path p, explicit pair z, real fuzz=<default>);
void drawbeziertriangle(frame f, triple[][] p, triple center, bool straight, pen[] p, real opacity, real shininess, real metallic, real fresnel0, pen[] colors, int interaction, int digits, bool primitive=<default>);
void Draw(picture pic=<default>, path g, pen p=<default>);
filltype Draw;
@@ -741,18 +742,17 @@ plain_scaling plain_scaling;
string file(string s);
plain_bounds plain_bounds;
string outprefix(string prefix=<default>);
-object object(Label L, path e(frame dest, frame src=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>), real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
-object object(frame f);
object object(Label L);
+object object(frame f);
+object object(Label L, path e(frame dest, frame src=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>), real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
file stdin;
void()()[] array(int n, void value()(), int depth=<default>);
bool[] array(int n, bool value, int depth=<default>);
string[] array(int n, string value, int depth=<default>);
pair[][] array(int n, pair[] value, int depth=<default>);
bool3[] array(int n, bool3 value, int depth=<default>);
-coord[] array(int n, coord value, int depth=<default>);
-Legend[] array(int n, Legend value, int depth=<default>);
Label[] array(int n, Label value, int depth=<default>);
+picture[] array(int n, picture value, int depth=<default>);
real[][] array(int n, real[] value, int depth=<default>);
real[] array(int n, real value, int depth=<default>);
triple[] array(int n, triple value, int depth=<default>);
@@ -760,9 +760,10 @@ path[] array(int n, path value, int depth=<default>);
frame[] array(int n, frame value, int depth=<default>);
pen[][] array(int n, pen[] value, int depth=<default>);
coord[] array(int n, coord value, int depth=<default>);
+coord[] array(int n, coord value, int depth=<default>);
object[] array(int n, object value, int depth=<default>);
marker[] array(int n, marker value, int depth=<default>);
-picture[] array(int n, picture value, int depth=<default>);
+Legend[] array(int n, Legend value, int depth=<default>);
int[] array(int n, int value, int depth=<default>);
string[][] array(int n, string[] value, int depth=<default>);
pair[] array(int n, pair value, int depth=<default>);
@@ -808,20 +809,20 @@ pen palemagenta;
void draw(frame f, triple[][] p, triple center, bool straight, pen[] p, real opacity, real shininess, real metallic, real fresnel0, pen[] colors, int interaction, int digits, bool primitive=<default>);
void draw(frame f, triple[] p, real[] knot, real[] weights=<default>, pen p);
void draw(frame f, triple[][] p, real[] uknot, real[] vknot, real[][] weights=<default>, pen[] p, real opacity, real shininess, real metallic, real fresnel0, pen[] colors);
-void draw(frame f, triple[] v, int[][] vi, triple[] n, int[][] ni, pen[] p, real opacity, real shininess, real metallic, real fresnel0, pen[] c=<default>, int[][] ci=<default>);
+void draw(frame f, triple[] v, int[][] vi, triple center=<default>, triple[] n, int[][] ni, pen[] p, real opacity, real shininess, real metallic, real fresnel0, pen[] c=<default>, int[][] ci=<default>, int interaction);
void draw(picture pic=<default>, path[] g, pen fillrule=<default>, pen[] p);
-object draw(picture pic=<default>, Label L, path e(frame dest, frame src=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>), pair position, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
+object draw(picture pic=<default>, Label L, path e(frame dest, frame src=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>), real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
void draw(frame f, explicit path[] g, pen p=<default>);
-void draw(picture pic=<default>, guide[] g, pen p=<default>, Label legend=<default>, marker marker=<default>);
-void draw(pair origin, picture pic=<default>, guide[] g, pen p=<default>, Label legend=<default>, marker marker=<default>);
+void draw(frame f, path g, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen)));
void draw(picture pic=<default>, explicit path[] g, pen p=<default>, Label legend=<default>, marker marker=<default>);
void draw(pair origin, picture pic=<default>, explicit path[] g, pen p=<default>, Label legend=<default>, marker marker=<default>);
-object draw(picture pic=<default>, Label L, path e(frame dest, frame src=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>), real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
-void draw(frame f, guide[] g, pen p=<default>);
-void draw(frame f, path g, pen p=<default>);
+object draw(picture pic=<default>, Label L, path e(frame dest, frame src=<default>, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>), pair position, real xmargin=<default>, real ymargin=<default>, pen p=<default>, filltype filltype=<default>, bool above=<default>);
void draw(picture pic=<default>, Label L=<default>, path g, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool bar(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, Label legend=<default>, marker marker=<default>);
void draw(pair origin, picture pic=<default>, Label L=<default>, path g, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, bool bar(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, Label legend=<default>, marker marker=<default>);
-void draw(frame f, path g, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen)));
+void draw(frame f, guide[] g, pen p=<default>);
+void draw(frame f, path g, pen p=<default>);
+void draw(picture pic=<default>, guide[] g, pen p=<default>, Label legend=<default>, marker marker=<default>);
+void draw(pair origin, picture pic=<default>, guide[] g, pen p=<default>, Label legend=<default>, marker marker=<default>);
int mantissaBits;
real identity(real x);
real[] identity(real[] a);
@@ -835,6 +836,7 @@ string pattern(pen p);
transform invert;
transform inverse(transform t);
real[][] inverse(real[][] a);
+int[] MarkFillable;
pair unit(pair z);
triple unit(triple v);
triple min3(frame f);
@@ -884,11 +886,11 @@ void write(file file=<default>, string s=<default>, guide x, void suffix(file)=<
void write(file file=<default>, string s=<default>, pen x, void suffix(file)=<default> ... pen[]);
void write(file file, string s=<default>, explicit guide[] x, void suffix(file)=<default>);
void write(string s=<default>, cputime c, string format=<default>, void suffix(file)=<default>);
+void write(pairOrTriple a);
void write(string s=<default>, explicit path[] x, void suffix(file)=<default>);
void write(file file, void suffix(file)=<default>);
void write(file file=<default>, string s=<default>, pen[] p);
void write(void suffix(file)=<default>);
-void write(pairOrTriple a);
void write(file file, string s=<default>, explicit path[] x, void suffix(file)=<default>);
void write(file file=<default>, align align, void suffix(file)=<default>);
void write(file file, string s=<default>, cputime c, string format=<default>, void suffix(file)=<default>);
@@ -947,22 +949,22 @@ pen dotted;
string blend(pen p);
arrowhead HookHead;
arrowhead HookHead(real dir=<default>, real barb=<default>);
-marker[] concat(... marker[][]);
-picture[] concat(... picture[][]);
+object[] concat(... object[][]);
real[] concat(... real[][]);
+Label[] concat(... Label[][]);
pair[] concat(... pair[][]);
-object[] concat(... object[][]);
-pen[] concat(... pen[][]);
-coord[] concat(... coord[][]);
Legend[] concat(... Legend[][]);
-Label[] concat(... Label[][]);
+pen[] concat(... pen[][]);
path[] concat(... path[][]);
coord[] concat(... coord[][]);
+coord[] concat(... coord[][]);
int[] concat(... int[][]);
void()()[] concat(... void()()[][]);
bool3[] concat(... bool3[][]);
string[] concat(... string[][]);
+marker[] concat(... marker[][]);
triple[] concat(... triple[][]);
+picture[] concat(... picture[][]);
frame[] concat(... frame[][]);
guide[] concat(... guide[][]);
bool[] concat(... bool[][]);
@@ -972,69 +974,69 @@ real[] log1p(real[] a);
real infinity;
bool alias(pair[][] a, pair[][] b);
bool alias(guide[] a, guide[] b);
-bool alias(marginT a, marginT b);
+bool alias(filltype a, filltype b);
bool alias(coord[] a, coord[] b);
-bool alias(light a, light b);
-bool alias(align a, align b);
-bool alias(processtime a, processtime b);
+bool alias(coord[] a, coord[] b);
+bool alias(coords3 a, coords3 b);
+bool alias(marker a, marker b);
bool alias(pair[] a, pair[] b);
bool alias(scaling a, scaling b);
-bool alias(coord a, coord b);
-bool alias(coords3 a, coords3 b);
-bool alias(Legend a, Legend b);
-bool alias(Label a, Label b);
+bool alias(scaling a, scaling b);
+bool alias(ScaleT a, ScaleT b);
+bool alias(side a, side b);
+bool alias(arrowhead a, arrowhead b);
+bool alias(picture[] a, picture[] b);
bool alias(int[] a, int[] b);
bool alias(string[][] a, string[][] b);
bool alias(slice a, slice b);
-bool alias(freezableBounds a, freezableBounds b);
-bool alias(transformation a, transformation b);
-bool alias(picture a, picture b);
-bool alias(object[] a, object[] b);
-bool alias(marker a, marker b);
+bool alias(simplex a, simplex b);
+bool alias(projection a, projection b);
+bool alias(pairOrTriple a, pairOrTriple b);
+bool alias(object a, object b);
+bool alias(Legend[] a, Legend[] b);
bool alias(real[][] a, real[][] b);
bool alias(bool3 a, bool3 b);
bool alias(bool3[] a, bool3[] b);
+bool alias(bounds a, bounds b);
bool alias(scaleT a, scaleT b);
-bool alias(autoscaleT a, autoscaleT b);
-bool alias(side a, side b);
+bool alias(processtime a, processtime b);
bool alias(cputime a, cputime b);
bool alias(string[] a, string[] b);
bool alias(frame[] a, frame[] b);
bool alias(coords2 a, coords2 b);
-bool alias(scaling a, scaling b);
-bool alias(node a, node b);
-bool alias(object a, object b);
-bool alias(marker[] a, marker[] b);
-bool alias(picture[] a, picture[] b);
+bool alias(coords2 a, coords2 b);
+bool alias(Legend a, Legend b);
+bool alias(position a, position b);
+bool alias(object[] a, object[] b);
bool alias(bool[] a, bool[] b);
bool alias(void()()[] a, void()()[] b);
bool alias(pen[][] a, pen[][] b);
-bool alias(filltype a, filltype b);
-bool alias(simplex a, simplex b);
-bool alias(coord[] a, coord[] b);
-bool alias(projection a, projection b);
-bool alias(Legend[] a, Legend[] b);
-bool alias(Label[] a, Label[] b);
-bool alias(arrowhead a, arrowhead b);
+bool alias(marginT a, marginT b);
+bool alias(light a, light b);
+bool alias(picture a, picture b);
bool alias(path[] a, path[] b);
bool alias(triple[] a, triple[] b);
bool alias(coord a, coord b);
-bool alias(bounds a, bounds b);
-bool alias(ScaleT a, ScaleT b);
-bool alias(position a, position b);
+bool alias(coord a, coord b);
+bool alias(autoscaleT a, autoscaleT b);
+bool alias(align a, align b);
+bool alias(marker[] a, marker[] b);
bool alias(real[] a, real[] b);
bool alias(pen[] a, pen[] b);
bool alias(hsv a, hsv b);
-bool alias(coords2 a, coords2 b);
-bool alias(pairOrTriple a, pairOrTriple b);
+bool alias(freezableBounds a, freezableBounds b);
+bool alias(transformation a, transformation b);
+bool alias(node a, node b);
+bool alias(Label a, Label b);
+bool alias(Label[] a, Label[] b);
real pi;
int getint(string name=<default>, int default=<default>, string prompt=<default>, bool store=<default>);
int bitreverse(int a, int bits);
bool IgnoreAspect;
void postscript(frame f, string s);
void postscript(frame f, string s, pair min, pair max);
-void postscript(picture pic=<default>, string s, pair min, pair max);
void postscript(picture pic=<default>, string s);
+void postscript(picture pic=<default>, string s, pair min, pair max);
transform slant(real s);
void breakpoint(code s=<default>);
void breakpoints();
@@ -1047,6 +1049,7 @@ real gamma(real x);
real pow10(real x);
real[] pow10(real[] a);
real[][] AtA(real[][] a);
+real byteinv(int x);
real bp;
int[] sort(int[] a);
int[][] sort(int[][] a);
@@ -1055,9 +1058,10 @@ real[][] sort(real[][] a);
string[] sort(string[] a);
string[][] sort(string[][] a);
coord[] sort(coord[] a, bool less(coord, coord), bool stable=<default>);
+coord[] sort(coord[] a, bool less(coord, coord), bool stable=<default>);
object[] sort(object[] a, bool less(object, object), bool stable=<default>);
marker[] sort(marker[] a, bool less(marker, marker), bool stable=<default>);
-picture[] sort(picture[] a, bool less(picture, picture), bool stable=<default>);
+Legend[] sort(Legend[] a, bool less(Legend, Legend), bool stable=<default>);
path[] sort(path[] a, bool less(path, path), bool stable=<default>);
pen[][] sort(pen[][] a, bool less(pen[], pen[]), bool stable=<default>);
pair[][] sort(pair[][] a, bool less(pair[], pair[]), bool stable=<default>);
@@ -1066,9 +1070,8 @@ bool[] sort(bool[] a, bool less(bool, bool), bool stable=<default>);
void()()[] sort(void()()[] a, bool less(void()(), void()()), bool stable=<default>);
frame[] sort(frame[] a, bool less(frame, frame), bool stable=<default>);
bool3[] sort(bool3[] a, bool less(bool3, bool3), bool stable=<default>);
-coord[] sort(coord[] a, bool less(coord, coord), bool stable=<default>);
-Legend[] sort(Legend[] a, bool less(Legend, Legend), bool stable=<default>);
Label[] sort(Label[] a, bool less(Label, Label), bool stable=<default>);
+picture[] sort(picture[] a, bool less(picture, picture), bool stable=<default>);
int[] sort(int[] a, bool less(int, int), bool stable=<default>);
string[][] sort(string[][] a, bool less(string[], string[]), bool stable=<default>);
real[] sort(real[] a, bool less(real, real), bool stable=<default>);
@@ -1086,11 +1089,11 @@ void latticeshade(picture pic=<default>, path[] g, bool stroke=<default>, pen fi
pair[] pairs(real[] x, real[] y);
void eval(code s, bool embedded=<default>);
void eval(string s, bool embedded=<default>);
-bool Arrow(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, position position=<default>);
bool Arrow(picture, path, pen, marginT(path, pen));
+bool Arrow(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, position position=<default>);
void drawTube(frame f, triple[] g, real width, pen[] p, real opacity, real shininess, real metallic, real fresnel0, triple min, triple max, bool core=<default>);
-bool Arrows(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>);
bool Arrows(picture, path, pen, marginT(path, pen));
+bool Arrows(picture, path, pen, marginT(path, pen))(arrowhead arrowhead=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>);
int tell(file f);
pen Yellow;
pair up;
@@ -1116,9 +1119,9 @@ pen[] mean(pen[][] palette, real opacity(real[])=<default>);
string mktemp(string s);
void sleep(int seconds);
void drawstrokepath(picture pic=<default>, path g, pen strokepen, pen p=<default>);
+void unitsize(picture pic=<default>, real x, real y=<default>, real z=<default>);
void arrow(picture pic=<default>, Label L=<default>, pair b, pair dir, real length=<default>, align align=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>);
picture arrow(arrowhead arrowhead=<default>, path g, pen p=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, position position=<default>, bool forwards=<default>, marginT margin(path, pen)=<default>, bool center=<default>);
-void unitsize(picture pic=<default>, real x, real y=<default>, real z=<default>);
picture arrow2(arrowhead arrowhead=<default>, path g, pen p=<default>, real size=<default>, real angle=<default>, filltype filltype=<default>, marginT margin(path, pen)=<default>);
path unitsquare;
real arrowdir;
@@ -1197,6 +1200,7 @@ pair project(triple v, real[][] t);
bool prc(string format=<default>);
projection projection(triple camera, triple up=<default>, triple target=<default>, triple normal=<default>, real zoom=<default>, real angle=<default>, pair viewportshift=<default>, bool showtarget=<default>, bool autoadjust=<default>, bool center=<default>, transformation projector(triple camera, triple up, triple target));
void endl(file file);
+path diamond;
marginT TrueMargin(path, pen)(real begin, real end=<default>);
pair bezier(pair a, pair b, pair c, pair d, real t);
triple bezier(triple a, triple b, triple c, triple d, real t);
@@ -1292,10 +1296,10 @@ triple[] operator +(triple[] a);
pen operator +(pen a, pen b);
transform operator +(transform a, transform b);
pen operator +(pen p, real w);
+marginT operator +(path, pen)(marginT ma(path, pen), marginT mb(path, pen));
pen[] operator +(pen a, pen[] b);
pen operator +(real w, pen p);
string operator +(... string[] a);
-marginT operator +(path, pen)(marginT ma(path, pen), marginT mb(path, pen));
pen[] operator +(pen[] a, pen b);
int operator -(int a, int b);
int[] operator -(int a, int[] b);
@@ -1329,6 +1333,7 @@ triple[][] operator -(triple[][] a, triple[][] b);
triple operator -(triple a);
triple[] operator -(triple[] a);
triple[][] operator -(triple[][] a);
+bool primitive();
int operator *(int a, int b);
int[] operator *(int a, int[] b);
int[] operator *(int[] a, int b);
@@ -1368,15 +1373,15 @@ triple operator *(real[][] t, triple v);
triple operator *(real x, triple v);
triple operator *(triple v, real x);
path3 operator *(real[][] t, path3 g);
-side operator *(real x, side s);
-Label operator *(real[][] t, Label L);
picture operator *(transform t, picture orig);
object operator *(transform t, explicit object F);
-path[] operator *(transform t, explicit path[] p);
Label operator *(transform t, Label L);
+path[] operator *(transform t, explicit path[] p);
pair[] operator *(transform t, pair[] z);
-bounds operator *(transform t, bounds b);
picture operator *(real[][] t, picture orig);
+bounds operator *(transform t, bounds b);
+side operator *(real x, side s);
+Label operator *(real[][] t, Label L);
bool operator init();
int operator init();
real operator init();
@@ -1390,38 +1395,38 @@ path3 operator init();
pen operator init();
frame operator init();
file operator init();
+filltype operator init();
+coords3 operator init();
+marker operator init();
marginT operator init();
light operator init();
-align operator init();
-processtime operator init();
-filltype operator init();
+picture operator init();
+slice operator init();
simplex operator init();
projection operator init();
-arrowhead operator init();
-slice operator init();
-transformation operator init();
-picture operator init();
-marker operator init();
+pairOrTriple operator init();
+object operator init();
hsv operator init();
+transformation operator init();
+node operator init();
+Label operator init();
coords2 operator init();
-pairOrTriple operator init();
coords2 operator init();
+Legend operator init();
+position operator init();
scaling operator init();
-node operator init();
-object operator init();
scaling operator init();
+ScaleT operator init();
+side operator init();
+arrowhead operator init();
coord operator init();
-coords3 operator init();
-Legend operator init();
-Label operator init();
coord operator init();
-bounds operator init();
-ScaleT operator init();
-position operator init();
+autoscaleT operator init();
+align operator init();
bool3 operator init();
+bounds operator init();
scaleT operator init();
-autoscaleT operator init();
-side operator init();
+processtime operator init();
cputime operator init();
real operator cast(int);
pair operator cast(int);
@@ -1464,33 +1469,33 @@ string[][][] operator cast(file);
guide operator cast(cycleToken tok);
guide operator cast(curlSpecifier spec);
guide operator cast(tensionSpecifier t);
-align operator cast(side side);
guide[] operator cast(path[] g);
-frame operator cast(object F);
-hsv operator cast(pen p);
-bool3[] operator cast(bool[] b);
-position operator cast(pair x);
-object operator cast(Label L);
-Label operator cast(object F);
pair operator cast(position P);
+hsv operator cast(pen p);
object operator cast(frame f);
+bool3[] operator cast(bool[] b);
+align operator cast(pair dir);
guide[] operator cast(pair[] z);
+align operator cast(triple dir);
path[] operator cast(guide[] g);
bool operator cast(bool3 b);
-align operator cast(pair dir);
path[] operator cast(guide g);
+align operator cast(side side);
+position operator cast(int x);
+object operator cast(string s);
path[] operator cast(pair[] z);
-align operator cast(triple dir);
path[] operator cast(path p);
bool[] operator cast(bool3[] b);
-bool3 operator cast(bool b);
-position operator cast(int x);
-object operator cast(string s);
+position operator cast(real x);
+Label operator cast(string s);
+object operator cast(Label L);
+Label operator cast(object F);
pair operator cast(pairOrTriple a);
triple operator cast(pairOrTriple a);
+frame operator cast(object F);
+bool3 operator cast(bool b);
pen operator cast(hsv hsv);
-position operator cast(real x);
-Label operator cast(string s);
+position operator cast(pair x);
pen deepred;
bool error(file f);
string operator ecast(int);
@@ -1595,41 +1600,41 @@ bool operator ==(file a, file b);
bool operator ==(path a, path b);
bool operator ==(path3 a, path3 b);
bool operator ==(bool3 a, bool3 b);
+bool operator ==(bounds a, bounds b);
bool operator ==(scaleT a, scaleT b);
-bool operator ==(autoscaleT a, autoscaleT b);
-bool operator ==(side a, side b);
+bool operator ==(processtime a, processtime b);
bool operator ==(cputime a, cputime b);
bool operator ==(coords2 a, coords2 b);
-bool operator ==(scaling a, scaling b);
-bool operator ==(node a, node b);
-bool operator ==(object a, object b);
-bool operator ==(filltype a, filltype b);
-bool operator ==(simplex a, simplex b);
-bool operator ==(projection a, projection b);
-bool operator ==(arrowhead a, arrowhead b);
-bool operator ==(coord a, coord b);
-bool operator ==(bounds a, bounds b);
-bool operator ==(ScaleT a, ScaleT b);
-bool operator ==(position a, position b);
-bool operator ==(hsv a, hsv b);
bool operator ==(coords2 a, coords2 b);
-bool operator ==(pairOrTriple a, pairOrTriple b);
-bool operator ==(bool3 a, bool b);
+bool operator ==(Legend a, Legend b);
+bool operator ==(position a, position b);
bool operator ==(marginT a, marginT b);
bool operator ==(light a, light b);
-bool operator ==(align a, align b);
-bool operator ==(processtime a, processtime b);
-bool operator ==(scaling a, scaling b);
+bool operator ==(picture a, picture b);
bool operator ==(coord a, coord b);
-bool operator ==(coords3 a, coords3 b);
-bool operator ==(Legend a, Legend b);
-bool operator ==(Label a, Label b);
-bool operator ==(bool a, bool3 b);
-bool operator ==(slice a, slice b);
+bool operator ==(coord a, coord b);
+bool operator ==(autoscaleT a, autoscaleT b);
+bool operator ==(align a, align b);
+bool operator ==(hsv a, hsv b);
bool operator ==(freezableBounds a, freezableBounds b);
bool operator ==(transformation a, transformation b);
-bool operator ==(picture a, picture b);
+bool operator ==(node a, node b);
+bool operator ==(Label a, Label b);
+bool operator ==(bool3 a, bool b);
+bool operator ==(filltype a, filltype b);
+bool operator ==(coords3 a, coords3 b);
bool operator ==(marker a, marker b);
+bool operator ==(scaling a, scaling b);
+bool operator ==(scaling a, scaling b);
+bool operator ==(ScaleT a, ScaleT b);
+bool operator ==(side a, side b);
+bool operator ==(arrowhead a, arrowhead b);
+bool operator ==(bool a, bool3 b);
+bool operator ==(slice a, slice b);
+bool operator ==(simplex a, simplex b);
+bool operator ==(projection a, projection b);
+bool operator ==(pairOrTriple a, pairOrTriple b);
+bool operator ==(object a, object b);
bool operator !=(bool a, bool b);
bool[] operator !=(bool a, bool[] b);
bool[] operator !=(bool[] a, bool b);
@@ -1667,41 +1672,41 @@ bool operator !=(file a, file b);
bool operator !=(path a, path b);
bool operator !=(path3 a, path3 b);
bool operator !=(bool3 a, bool3 b);
+bool operator !=(bounds a, bounds b);
bool operator !=(scaleT a, scaleT b);
-bool operator !=(autoscaleT a, autoscaleT b);
-bool operator !=(side a, side b);
+bool operator !=(processtime a, processtime b);
bool operator !=(cputime a, cputime b);
bool operator !=(coords2 a, coords2 b);
-bool operator !=(scaling a, scaling b);
-bool operator !=(node a, node b);
-bool operator !=(object a, object b);
-bool operator !=(filltype a, filltype b);
-bool operator !=(simplex a, simplex b);
-bool operator !=(projection a, projection b);
-bool operator !=(arrowhead a, arrowhead b);
-bool operator !=(coord a, coord b);
-bool operator !=(bounds a, bounds b);
-bool operator !=(ScaleT a, ScaleT b);
-bool operator !=(position a, position b);
-bool operator !=(hsv a, hsv b);
bool operator !=(coords2 a, coords2 b);
-bool operator !=(pairOrTriple a, pairOrTriple b);
-bool operator !=(bool3 a, bool b);
+bool operator !=(Legend a, Legend b);
+bool operator !=(position a, position b);
bool operator !=(marginT a, marginT b);
bool operator !=(light a, light b);
-bool operator !=(align a, align b);
-bool operator !=(processtime a, processtime b);
-bool operator !=(scaling a, scaling b);
+bool operator !=(picture a, picture b);
bool operator !=(coord a, coord b);
-bool operator !=(coords3 a, coords3 b);
-bool operator !=(Legend a, Legend b);
-bool operator !=(Label a, Label b);
-bool operator !=(bool a, bool3 b);
-bool operator !=(slice a, slice b);
+bool operator !=(coord a, coord b);
+bool operator !=(autoscaleT a, autoscaleT b);
+bool operator !=(align a, align b);
+bool operator !=(hsv a, hsv b);
bool operator !=(freezableBounds a, freezableBounds b);
bool operator !=(transformation a, transformation b);
-bool operator !=(picture a, picture b);
+bool operator !=(node a, node b);
+bool operator !=(Label a, Label b);
+bool operator !=(bool3 a, bool b);
+bool operator !=(filltype a, filltype b);
+bool operator !=(coords3 a, coords3 b);
bool operator !=(marker a, marker b);
+bool operator !=(scaling a, scaling b);
+bool operator !=(scaling a, scaling b);
+bool operator !=(ScaleT a, ScaleT b);
+bool operator !=(side a, side b);
+bool operator !=(arrowhead a, arrowhead b);
+bool operator !=(bool a, bool3 b);
+bool operator !=(slice a, slice b);
+bool operator !=(simplex a, simplex b);
+bool operator !=(projection a, projection b);
+bool operator !=(pairOrTriple a, pairOrTriple b);
+bool operator !=(object a, object b);
bool operator <(int a, int b);
bool[] operator <(int a, int[] b);
bool[] operator <(int[] a, int b);
@@ -1848,7 +1853,6 @@ real dot(real[] a, real[] b);
pair dot(pair[] a, pair[] b);
real dot(explicit pair z, explicit pair w);
real dot(triple u, triple v);
-void dot(picture pic=<default>, Label[] L=<default>, explicit path g, align align=<default>, string format=<default>, pen p=<default>, filltype filltype=<default>);
marker dot(pen p=<default>, filltype filltype=<default>);
void dot(picture pic=<default>, pair z, pen p=<default>, filltype filltype=<default>);
void dot(frame f, pair z, pen p=<default>, filltype filltype=<default>);
@@ -1857,6 +1861,7 @@ void dot(picture pic=<default>, Label[] L=<default>, pair[] z, align align=<defa
void dot(picture pic=<default>, path[] g, pen p=<default>, filltype filltype=<default>);
marker dot;
void dot(picture pic=<default>, Label L, pair z, align align=<default>, string format=<default>, pen p=<default>, filltype filltype=<default>);
+void dot(picture pic=<default>, Label[] L=<default>, explicit path g, align align=<default>, string format=<default>, pen p=<default>, filltype filltype=<default>);
void list(string s, bool imports=<default>);
pair NNW;
string phantom(string s);
@@ -1965,16 +1970,16 @@ real braceinnerangle;
real braceouterangle;
void tex(frame f, string s);
void tex(frame f, string s, pair min, pair max);
-void tex(picture pic=<default>, string s, pair min, pair max);
void tex(picture pic=<default>, string s);
+void tex(picture pic=<default>, string s, pair min, pair max);
real bracedefaultratio;
bool prconly(string format=<default>);
pen Black;
triple size3(frame f);
void size3(picture pic=<default>, real x, real y=<default>, real z=<default>, bool keepAspect=<default>);
bool eof(file f);
-frame dotframe(pen p=<default>, filltype filltype=<default>);
frame dotframe;
+frame dotframe(pen p=<default>, filltype filltype=<default>);
real realMax;
pair NE;
real realMin;
@@ -1989,7 +1994,6 @@ pair[][] fft(pair[][] a, int sign=<default>);
pair[][][] fft(pair[][][] a, int sign=<default>);
pair SE;
pen nobasealign;
-sCAD operator init();
real animationdelay;
animation operator init();
frame NoBox(frame f);
@@ -2036,6 +2040,7 @@ bsp operator init();
picture operator cast(face f);
face operator cast(path3 p);
void add(picture pic=<default>, face[] faces, projection P=<default>);
+sCAD operator init();
list_data Set2;
list_data YlOrBr;
list_data YlGn;
@@ -2108,6 +2113,15 @@ list_data Paired;
seg_data jet;
seg_data summer;
list_data RdYlBu;
+surface surface(vertex[][] g);
+weighted operator init();
+bucket operator init();
+vertex operator init();
+object operator init();
+vertex[][] contour3(triple[][][] v, real[][][] f, real[][][] midpoint=<default>, projection P=<default>);
+vertex[][] contour3(real[][][] f, real[][][] midpoint=<default>, triple a, triple b, projection P=<default>);
+vertex[][] contour3(real f(real, real, real), triple a, triple b, int nx=<default>, int ny=<default>, int nz=<default>, projection P=<default>);
+real eps;
segment case1(pair p0, pair p1, int edge);
void draw(picture pic=<default>, Label[] L=<default>, guide[][] g, pen[] p);
void draw(picture pic=<default>, Label[] L=<default>, guide[][] g, pen p=<default>);
@@ -2127,15 +2141,6 @@ guide[][] contour(picture pic=<default>, real f(real, real), pair a, pair b, rea
guide[][] contour(picture pic=<default>, real f(pair), pair a, pair b, real[] c, int nx=<default>, int ny=<default>, guide join(... guide[])=<default>);
guide[][] contour(picture pic=<default>, pair[] z, real[] f, real[] c, guide join(... guide[])=<default>);
real eps;
-surface surface(vertex[][] g);
-weighted operator init();
-bucket operator init();
-vertex operator init();
-object operator init();
-vertex[][] contour3(triple[][][] v, real[][][] f, real[][][] midpoint=<default>, projection P=<default>);
-vertex[][] contour3(real[][][] f, real[][][] midpoint=<default>, triple a, triple b, projection P=<default>);
-vertex[][] contour3(real f(real, real, real), triple a, triple b, int nx=<default>, int ny=<default>, int nz=<default>, projection P=<default>);
-real eps;
void draw(TreeNode root, pair pos);
real treeNodeStep;
void drawAll(TreeNode node, frame f);
@@ -2561,8 +2566,8 @@ line complementary(explicit line l);
line[] complementary(explicit segment s);
arc complementary(arc a);
point ppoint(arc a, real x);
-bool between(point M, point O, point N);
path fromFocus(conic co, real angle1, real angle2, int n, bool direction);
+bool between(point M, point O, point N);
bool sameside(point M, point N, point O);
bool sameside(point M, point P, line l);
point[] sameside(point M, line l1, line l2);
@@ -2584,6 +2589,9 @@ circle circle(segment s);
circle circle(point A, point B, point C);
circle circle(triangle t);
circle circle(inversion i);
+segment segment(point A, point B);
+segment segment(line l);
+segment segment(explicit side side);
point angpoint(conic co, real angle);
point angpoint(explicit circle c, real x);
point angpoint(explicit ellipse el, real x, path polarconicroutine(conic co, real angle1, real angle2, int n, bool direction)=<default>);
@@ -2800,9 +2808,6 @@ real degrees(vector v, coordsys R=<default>, bool warn=<default>);
real degrees(line l, coordsys R=<default>);
real degrees(line l1, line l2);
real degrees(arc a);
-segment segment(point A, point B);
-segment segment(line l);
-segment segment(explicit side side);
real linemargin;
real linemargin();
line Oy(coordsys R=<default>);
@@ -2885,10 +2890,10 @@ triangle tangential(triangle t);
triangle pedal(triangle t, point M);
line pedal(side side, point M);
string massformat(string format=<default>, string s, mass M);
+int relativesystem;
triangle cevian(triangle t, point P);
point cevian(side side, point P);
line cevian(vertex V, point P);
-int relativesystem;
void drawline(picture pic=<default>, triangle t, pen p=<default>);
void addMargins(picture pic=<default>, real lmargin=<default>, real bmargin=<default>, real rmargin=<default>, real tmargin=<default>, bool rigid=<default>, bool allObject=<default>);
triangle medial(triangle t);
@@ -2909,6 +2914,127 @@ abscissa curabscissa(ellipse el, point M);
abscissa curabscissa(parabola p, point M);
abscissa curabscissa(conic co, point M);
abscissa curabscissa(arc a, point M);
+locateT operator init();
+void Straight(flatguide3)(... void(flatguide3)[]);
+void graph(flatguide3)(triple F(real), real, real, int)(void join(flatguide3)(... void(flatguide3)[]));
+void(flatguide3)[] graph(triple F(real), real, real, int)(void join(flatguide3)(... void(flatguide3)[]), bool3 cond(real));
+void graph(flatguide3)(picture pic=<default>, real x(real), real y(real), real z(real), real a, real b, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void(flatguide3)[] graph(picture pic=<default>, real x(real), real y(real), real z(real), real a, real b, int n=<default>, bool3 cond(real), void join(flatguide3)(... void(flatguide3)[])=<default>);
+void graph(flatguide3)(picture pic=<default>, triple v(real), real a, real b, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void(flatguide3)[] graph(picture pic=<default>, triple v(real), real a, real b, int n=<default>, bool3 cond(real), void join(flatguide3)(... void(flatguide3)[])=<default>);
+void graph(flatguide3)(picture pic=<default>, triple[] v, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void(flatguide3)[] graph(picture pic=<default>, triple[] v, bool3[] cond, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void graph(flatguide3)(picture pic=<default>, real[] x, real[] y, real[] z, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void(flatguide3)[] graph(picture pic=<default>, real[] x, real[] y, real[] z, bool3[] cond, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void graph(flatguide3)(triple F(path, real), path p, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void graph(flatguide3)(triple F(pair), path p, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void graph(flatguide3)(picture pic=<default>, real f(pair), path p, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void graph(flatguide3)(real f(pair), path p, int n=<default>, real T(pair), void join(flatguide3)(... void(flatguide3)[])=<default>);
+void(flatguide3)[][] lift(real f(real x, real y), guide[][] g, void join(flatguide3)(... void(flatguide3)[])=<default>);
+void(flatguide3)[][] lift(real f(pair z), guide[][] g, void join(flatguide3)(... void(flatguide3)[])=<default>);
+triple polar(real r, real theta, real phi);
+void polargraph(flatguide3)(real r(real, real), real theta(real), real phi(real), int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
+bool uperiodic(real[][] a);
+bool uperiodic(triple[][] a);
+bool vperiodic(real[][] a);
+bool vperiodic(triple[][] a);
+void OutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void OutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks, real[] ticks=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void OutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>);
+void axis(picture pic=<default>, Label L=<default>, path3 g, path3 g2=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>), ticklocate locate, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, int[] divisor=<default>, bool above=<default>, bool opposite=<default>);
+void Bounds(picture, axisT)(int type=<default>, int type2=<default>, triple align=<default>, bool extend=<default>);
+void Bounds(picture, axisT);
+void xaxis3At(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>, bool opposite=<default>, bool opposite2=<default>, bool primary=<default>);
+void yaxis3At(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>, bool opposite=<default>, bool opposite2=<default>, bool primary=<default>);
+void zaxis3At(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real zmin=<default>, real zmax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>, bool opposite=<default>, bool opposite2=<default>, bool primary=<default>);
+void xaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>);
+void yaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>);
+void zaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real zmin=<default>, real zmax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>);
+void XZZero(picture, axisT)(triple align=<default>, bool extend=<default>);
+void XZZero(picture, axisT);
+void YZZero(picture, axisT)(triple align=<default>, bool extend=<default>);
+void YZZero(picture, axisT);
+surface surface(picture pic=<default>, triple[][] f, bool[][] cond=<default>);
+surface surface(picture pic=<default>, real[][] f, real[] x, real[] y, real[] xsplinetype(real[], real[])=<default>, real[] ysplinetype(real[], real[])=<default>, bool[][] cond=<default>);
+surface surface(picture pic=<default>, real[][] f, pair a, pair b, real[] xsplinetype(real[], real[]), real[] ysplinetype(real[], real[])=<default>, bool[][] cond=<default>);
+surface surface(picture pic=<default>, real[][] f, pair a, pair b, bool[][] cond=<default>);
+surface surface(picture pic=<default>, triple f(pair z), pair a, pair b, int nu=<default>, int nv=<default>, bool cond(pair z)=<default>);
+surface surface(picture pic=<default>, triple f(pair z), real[] u, real[] v, real[](real[], real[])[] usplinetype, real[](real[], real[])[] vsplinetype=<default>, bool cond(pair z)=<default>);
+surface surface(picture pic=<default>, triple f(pair z), pair a, pair b, int nu=<default>, int nv=<default>, real[](real[], real[])[] usplinetype, real[](real[], real[])[] vsplinetype=<default>, bool cond(pair z)=<default>);
+surface surface(picture pic=<default>, real f(pair z), pair a, pair b, int nx=<default>, int ny=<default>, bool cond(pair z)=<default>);
+surface surface(picture pic=<default>, real f(pair z), pair a, pair b, int nx=<default>, int ny=<default>, real[] xsplinetype(real[], real[]), real[] ysplinetype(real[], real[])=<default>, bool cond(pair z)=<default>);
+void XYEquals(picture, axisT)(real x, real y, triple align=<default>, bool extend=<default>);
+triple Dir(real)(triple dir);
+void draw(picture pic=<default>, Label[] L=<default>, void(flatguide3)[][] g, pen[] p, light light=<default>, string name=<default>, render render=<default>, interaction interaction=<default>);
+void draw(picture pic=<default>, Label[] L=<default>, void(flatguide3)[][] g, pen p=<default>, light light=<default>, string name=<default>, render render=<default>, interaction interaction=<default>);
+void Ticks3(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(int sign, Label F=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks=<default>, real[] ticks=<default>, int N=<default>, bool begin=<default>, bool end=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void Ticks3(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(int sign, Label F=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+real maxlength(triple f(pair z), pair a, pair b, int nu, int nv);
+void drawtick(picture pic, real[][] T, path3 g, path3 g2, ticklocate locate, real val, real Size, int sign, pen p, bool extend);
+triple tickMin3(picture pic);
+triple tickMax3(picture pic);
+triple Scale(picture pic=<default>, triple v);
+triple[][] Scale(picture pic=<default>, triple[][] P);
+real ScaleX(picture pic=<default>, real x);
+real ScaleY(picture pic=<default>, real y);
+real ScaleZ(picture pic=<default>, real z);
+real[][] ScaleZ(picture pic=<default>, real[][] P);
+picture vectorfield(path3 vector(pair v), triple f(pair z), pair a, pair b, int nu=<default>, int nv=<default>, bool truesize=<default>, real maxlength=<default>, bool cond(pair z)=<default>, pen p=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, string name=<default>, render render=<default>);
+path3 Circle(triple c, real r, triple normal=<default>, int n=<default>);
+void InTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void InTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks, real[] ticks=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void InTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>);
+void Spline(flatguide3)(... void(flatguide3)[]);
+void InOutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void InOutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks, real[] ticks=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
+void InOutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>);
+void axes3(picture pic=<default>, Label xlabel=<default>, Label ylabel=<default>, Label zlabel=<default>, bool extend=<default>, triple min=<default>, triple max=<default>, pen p=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>);
+void label(picture pic, Label L, triple v, real x, align align, string format, pen p);
+void labelx(picture pic=<default>, Label L=<default>, triple v, align align=<default>, string format=<default>, pen p=<default>);
+void labelx3(picture pic=<default>, Label L=<default>, real x, align align=<default>, string format=<default>, pen p=<default>);
+void labeltick(picture pic, real[][] T, path3 g, ticklocate locate, real val, int sign, real Size, string ticklabel(real), Label F, real norm=<default>);
+void labelaxis(picture pic, real[][] T, Label L, path3 g, ticklocate locate=<default>, int sign=<default>, bool ticklabels=<default>);
+void labely(picture pic=<default>, Label L=<default>, triple v, align align=<default>, string format=<default>, pen p=<default>);
+void labely3(picture pic=<default>, Label L=<default>, real y, align align=<default>, string format=<default>, pen p=<default>);
+void labelz(picture pic=<default>, Label L=<default>, triple v, align align=<default>, string format=<default>, pen p=<default>);
+void labelz3(picture pic=<default>, Label L=<default>, real z, align align=<default>, string format=<default>, pen p=<default>);
+void autoscale3(picture pic=<default>, void axis(picture, axisT));
+void xtick(picture pic=<default>, triple v, triple dir=<default>, real size=<default>, pen p=<default>);
+void xtick(picture pic=<default>, Label L, triple v, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+void xtick3(picture pic=<default>, real x, triple dir=<default>, real size=<default>, pen p=<default>);
+void xtick3(picture pic=<default>, Label L, real x, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+void ytick(picture pic=<default>, triple v, triple dir=<default>, real size=<default>, pen p=<default>);
+void ytick(picture pic=<default>, Label L, triple v, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+void ytick3(picture pic=<default>, real y, triple dir=<default>, real size=<default>, pen p=<default>);
+void ytick3(picture pic=<default>, Label L, real y, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+void ztick(picture pic=<default>, triple v, triple dir=<default>, real size=<default>, pen p=<default>);
+void ztick(picture pic=<default>, Label L, triple v, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+void ztick3(picture pic=<default>, real z, triple dir=<default>, real size=<default>, pen p=<default>);
+void ztick3(picture pic=<default>, Label L, real z, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
+triple defaultdir(triple X, triple Y, triple Z, bool opposite=<default>, projection P);
+real xtrans(real[][] t, real x);
+real ytrans(real[][] t, real y);
+real ztrans(real[][] t, real z);
+ticklocate ticklocate(real a, real b, autoscaleT S=<default>, real tickmin=<default>, real tickmax=<default>, real time(real)=<default>, triple dir(real));
+triple ticklabelshift(triple align, pen p=<default>);
+path3 Arc(triple c, triple v1, triple v2, triple normal=<default>, bool direction=<default>, int n=<default>);
+path3 Arc(triple c, real r, real theta1, real phi1, real theta2, real phi2, triple normal=<default>, bool direction, int n=<default>);
+path3 Arc(triple c, real r, real theta1, real phi1, real theta2, real phi2, triple normal=<default>, int n=<default>);
+void limits(picture pic=<default>, triple min, triple max);
+void XZEquals(picture, axisT)(real x, real z, triple align=<default>, bool extend=<default>);
+void YZEquals(picture, axisT)(real y, real z, triple align=<default>, bool extend=<default>);
+void XYZero(picture, axisT)(triple align=<default>, bool extend=<default>);
+void XYZero(picture, axisT);
+void zlimits(picture pic=<default>, real min=<default>, real max=<default>, bool crop=<default>);
+void tick(picture pic=<default>, triple v, triple dir, real size=<default>, pen p=<default>);
+void tick(picture pic=<default>, Label L, real value, triple v, triple dir, string format=<default>, real size=<default>, pen p=<default>);
+surface bispline(real[][] z, real[][] p, real[][] q, real[][] r, real[] x, real[] y, bool[][] cond=<default>);
+real[][][] bispline(real[][] f, real[] x, real[] y, real[] xsplinetype(real[], real[])=<default>, real[] ysplinetype(real[], real[])=<default>, bool[][] cond=<default>);
+real[][][] bispline0(real[][] z, real[][] p, real[][] q, real[][] r, real[] x, real[] y, bool[][] cond=<default>);
+path3[] segment(triple[] v, bool[] cond, void join(flatguide3)(... void(flatguide3)[])=<default>);
+real[] uniform(real T(real x), real Tinv(real x), real a, real b, int n);
+void NoTicks3(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)();
+void NoTicks3(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>);
string DefaultFormat(real);
string DefaultLogFormat(real)(int base);
string DefaultLogFormat(real);
@@ -2924,6 +3050,7 @@ guide graph(picture pic=<default>, pair[] z, guide join(... guide[])=<default>);
guide[] graph(picture pic=<default>, pair[] z, bool3[] cond, guide join(... guide[])=<default>);
guide graph(picture pic=<default>, real[] x, real[] y, guide join(... guide[])=<default>);
guide[] graph(picture pic=<default>, real[] x, real[] y, bool3[] cond, guide join(... guide[])=<default>);
+guide graphwithderiv(pair f(real), pair fprime(real), real a, real b, int n=<default>);
scientific scientific(real x);
void Left(picture, axisT)(bool extend=<default>);
void Left(picture, axisT);
@@ -2960,11 +3087,11 @@ void labelx(picture pic=<default>, Label L, string format=<default>, explicit pe
path Arc(pair c, real r, real angle1, real angle2, bool direction, int n=<default>);
path Arc(pair c, real r, real angle1, real angle2, int n=<default>);
path Arc(pair c, explicit pair z1, explicit pair z2, bool direction=<default>, int n=<default>);
+pair labeltick(frame d, transform T, path g, ticklocate locate, real val, pair side, int sign, real Size, string ticklabel(real), Label F, real norm=<default>);
+void labelaxis(frame f, transform T, Label L, path g, ticklocate locate=<default>, int sign=<default>, bool ticklabels=<default>);
void labely(picture pic=<default>, Label L=<default>, explicit pair z, align align=<default>, string format=<default>, pen p=<default>);
void labely(picture pic=<default>, Label L=<default>, real y, align align=<default>, string format=<default>, pen p=<default>);
void labely(picture pic=<default>, Label L, string format=<default>, explicit pen p=<default>);
-pair labeltick(frame d, transform T, path g, ticklocate locate, real val, pair side, int sign, real Size, string ticklabel(real), Label F, real norm=<default>);
-void labelaxis(frame f, transform T, Label L, path g, ticklocate locate=<default>, int sign=<default>, bool ticklabels=<default>);
void xtick(picture pic=<default>, explicit pair z, pair dir=<default>, real size=<default>, pen p=<default>);
void xtick(picture pic=<default>, real x, pair dir=<default>, real size=<default>, pen p=<default>);
void xtick(picture pic=<default>, Label L, explicit pair z, pair dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
@@ -2975,16 +3102,16 @@ void ytick(picture pic=<default>, Label L, explicit pair z, pair dir=<default>,
void ytick(picture pic=<default>, Label L, real y, pair dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
picture secondaryX(picture primary=<default>, void f(picture));
picture secondaryY(picture primary=<default>, void f(picture));
-tickvalues OmitTickIntervals(tickvalues)(real[] a, real[] b);
-tickvalues OmitTickInterval(tickvalues)(real a, real b);
-tickvalues OmitTick(tickvalues)(... real[] x);
Label Break;
tickvalues Break(tickvalues)(real, real);
scaleT Linear;
scaleT Linear(bool automin=<default>, bool automax=<default>, real s=<default>, real intercept=<default>);
pair tickMin(picture pic);
pair tickMax(picture pic);
+tickvalues OmitTickIntervals(tickvalues)(real[] a, real[] b);
string autoformat(string format=<default>, real norm ... real[] a);
+tickvalues OmitTickInterval(tickvalues)(real a, real b);
+tickvalues OmitTick(tickvalues)(... real[] x);
real linear(real)(real S(real x)=<default>, real Min, real Max);
pair polar(real r, real theta);
string Format(real)(string s=<default>);
@@ -2993,8 +3120,6 @@ guide polargraph(picture pic=<default>, real[] r, real[] theta, guide join(... g
void LeftTicks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
void LeftTicks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks, real[] ticks=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
void LeftTicks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>);
-tickvalues NoZero(tickvalues);
-string NoZeroFormat(real);
guide Hermite(... guide[])(real[] splinetype(real[], real[]));
guide Hermite(... guide[]);
path Circle(pair c, real r, int n=<default>);
@@ -3012,16 +3137,14 @@ void yequals(picture pic=<default>, Label L=<default>, real y, bool extend=<defa
pair Scale(picture pic=<default>, pair z);
real ScaleX(picture pic=<default>, real x);
real ScaleY(picture pic=<default>, real y);
-void xaxisAt(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool opposite=<default>);
-void yaxisAt(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool opposite=<default>);
-void xaxis(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>);
tickvalues generateticks(int sign, Label F=<default>, string ticklabel(real)=<default>, int N, int n=<default>, real Step=<default>, real step=<default>, real Size=<default>, real size=<default>, transform T, pair side, path g, real limit, pen p, ticklocate locate, int[] divisor, bool opposite);
-void yaxis(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool autorotate=<default>);
+path[] segment(pair[] z, bool[] cond, guide join(... guide[])=<default>);
void checkconditionlength(int x, int y);
real xtrans(transform t, real x);
void Top(picture, axisT)(bool extend=<default>);
void Top(picture, axisT);
real ytrans(transform t, real y);
+string NoZeroFormat(real);
void scale(picture pic=<default>, scaleT x, scaleT y=<default>, scaleT z=<default>);
void scale(picture pic=<default>, bool xautoscale=<default>, bool yautoscale=<default>, bool zautoscale=<default>);
int[] divisors(int a, int b);
@@ -3031,10 +3154,14 @@ ticklocate operator init();
locateT operator init();
tickvalues operator init();
axisT operator init();
+tickvalues NoZero(tickvalues);
int Both;
void axes(picture pic=<default>, Label xlabel=<default>, Label ylabel=<default>, bool extend=<default>, pair min=<default>, pair max=<default>, pen p=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>);
string signedtrailingzero;
-path[] segment(pair[] z, bool[] cond, guide join(... guide[])=<default>);
+void xaxisAt(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool opposite=<default>);
+void yaxisAt(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool opposite=<default>);
+void xaxis(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>);
+void yaxis(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(frame, transform, Label, pair, path, path, pen, bool(picture, path, pen, marginT(path, pen)), marginT(path, pen), ticklocate, int[], bool opposite=<default>)=<default>, bool arrow(picture, path, pen, marginT(path, pen))=<default>, marginT margin(path, pen)=<default>, bool above=<default>, bool autorotate=<default>);
ticklocate ticklocate(real a, real b, autoscaleT S=<default>, real tickmin=<default>, real tickmax=<default>, real time(real)=<default>, pair dir(real)=<default>);
pair ticklabelshift(pair align, pen p=<default>);
pair zero(real);
@@ -3068,127 +3195,6 @@ void autoscale(picture pic=<default>, void axis(picture, axisT));
guide Spline(... guide[]);
void LeftRight(picture, axisT)(bool extend=<default>);
void LeftRight(picture, axisT);
-path3[] segment(triple[] v, bool[] cond, void join(flatguide3)(... void(flatguide3)[])=<default>);
-locateT operator init();
-void Straight(flatguide3)(... void(flatguide3)[]);
-void graph(flatguide3)(triple F(real), real, real, int)(void join(flatguide3)(... void(flatguide3)[]));
-void(flatguide3)[] graph(triple F(real), real, real, int)(void join(flatguide3)(... void(flatguide3)[]), bool3 cond(real));
-void graph(flatguide3)(picture pic=<default>, real x(real), real y(real), real z(real), real a, real b, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
-void(flatguide3)[] graph(picture pic=<default>, real x(real), real y(real), real z(real), real a, real b, int n=<default>, bool3 cond(real), void join(flatguide3)(... void(flatguide3)[])=<default>);
-void graph(flatguide3)(picture pic=<default>, triple v(real), real a, real b, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
-void(flatguide3)[] graph(picture pic=<default>, triple v(real), real a, real b, int n=<default>, bool3 cond(real), void join(flatguide3)(... void(flatguide3)[])=<default>);
-void graph(flatguide3)(picture pic=<default>, triple[] v, void join(flatguide3)(... void(flatguide3)[])=<default>);
-void(flatguide3)[] graph(picture pic=<default>, triple[] v, bool3[] cond, void join(flatguide3)(... void(flatguide3)[])=<default>);
-void graph(flatguide3)(picture pic=<default>, real[] x, real[] y, real[] z, void join(flatguide3)(... void(flatguide3)[])=<default>);
-void(flatguide3)[] graph(picture pic=<default>, real[] x, real[] y, real[] z, bool3[] cond, void join(flatguide3)(... void(flatguide3)[])=<default>);
-void graph(flatguide3)(triple F(path, real), path p, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
-void graph(flatguide3)(triple F(pair), path p, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
-void graph(flatguide3)(picture pic=<default>, real f(pair), path p, int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
-void graph(flatguide3)(real f(pair), path p, int n=<default>, real T(pair), void join(flatguide3)(... void(flatguide3)[])=<default>);
-void(flatguide3)[][] lift(real f(real x, real y), guide[][] g, void join(flatguide3)(... void(flatguide3)[])=<default>);
-void(flatguide3)[][] lift(real f(pair z), guide[][] g, void join(flatguide3)(... void(flatguide3)[])=<default>);
-triple polar(real r, real theta, real phi);
-void polargraph(flatguide3)(real r(real, real), real theta(real), real phi(real), int n=<default>, void join(flatguide3)(... void(flatguide3)[])=<default>);
-bool uperiodic(real[][] a);
-bool uperiodic(triple[][] a);
-bool vperiodic(real[][] a);
-bool vperiodic(triple[][] a);
-void OutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
-void OutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks, real[] ticks=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
-void OutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>);
-void axis(picture pic=<default>, Label L=<default>, path3 g, path3 g2=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>), ticklocate locate, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, int[] divisor=<default>, bool above=<default>, bool opposite=<default>);
-void Bounds(picture, axisT)(int type=<default>, int type2=<default>, triple align=<default>, bool extend=<default>);
-void Bounds(picture, axisT);
-void XZZero(picture, axisT)(triple align=<default>, bool extend=<default>);
-void XZZero(picture, axisT);
-void YZZero(picture, axisT)(triple align=<default>, bool extend=<default>);
-void YZZero(picture, axisT);
-void xaxis3At(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>, bool opposite=<default>, bool opposite2=<default>, bool primary=<default>);
-void yaxis3At(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>, bool opposite=<default>, bool opposite2=<default>, bool primary=<default>);
-void zaxis3At(picture pic=<default>, Label L=<default>, void axis(picture, axisT), real zmin=<default>, real zmax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>, bool opposite=<default>, bool opposite2=<default>, bool primary=<default>);
-void xaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real xmin=<default>, real xmax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>);
-void yaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real ymin=<default>, real ymax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>);
-void zaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, real zmin=<default>, real zmax=<default>, pen p=<default>, void ticks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, bool above=<default>);
-surface surface(picture pic=<default>, triple[][] f, bool[][] cond=<default>);
-surface surface(picture pic=<default>, real[][] f, real[] x, real[] y, real[] xsplinetype(real[], real[])=<default>, real[] ysplinetype(real[], real[])=<default>, bool[][] cond=<default>);
-surface surface(picture pic=<default>, real[][] f, pair a, pair b, real[] xsplinetype(real[], real[]), real[] ysplinetype(real[], real[])=<default>, bool[][] cond=<default>);
-surface surface(picture pic=<default>, real[][] f, pair a, pair b, bool[][] cond=<default>);
-surface surface(picture pic=<default>, triple f(pair z), pair a, pair b, int nu=<default>, int nv=<default>, bool cond(pair z)=<default>);
-surface surface(picture pic=<default>, triple f(pair z), real[] u, real[] v, real[](real[], real[])[] usplinetype, real[](real[], real[])[] vsplinetype=<default>, bool cond(pair z)=<default>);
-surface surface(picture pic=<default>, triple f(pair z), pair a, pair b, int nu=<default>, int nv=<default>, real[](real[], real[])[] usplinetype, real[](real[], real[])[] vsplinetype=<default>, bool cond(pair z)=<default>);
-surface surface(picture pic=<default>, real f(pair z), pair a, pair b, int nx=<default>, int ny=<default>, bool cond(pair z)=<default>);
-surface surface(picture pic=<default>, real f(pair z), pair a, pair b, int nx=<default>, int ny=<default>, real[] xsplinetype(real[], real[]), real[] ysplinetype(real[], real[])=<default>, bool cond(pair z)=<default>);
-void XYEquals(picture, axisT)(real x, real y, triple align=<default>, bool extend=<default>);
-triple Dir(real)(triple dir);
-void draw(picture pic=<default>, Label[] L=<default>, void(flatguide3)[][] g, pen[] p, light light=<default>, string name=<default>, render render=<default>, interaction interaction=<default>);
-void draw(picture pic=<default>, Label[] L=<default>, void(flatguide3)[][] g, pen p=<default>, light light=<default>, string name=<default>, render render=<default>, interaction interaction=<default>);
-void Ticks3(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(int sign, Label F=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks=<default>, real[] ticks=<default>, int N=<default>, bool begin=<default>, bool end=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
-void Ticks3(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(int sign, Label F=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
-real maxlength(triple f(pair z), pair a, pair b, int nu, int nv);
-void drawtick(picture pic, real[][] T, path3 g, path3 g2, ticklocate locate, real val, real Size, int sign, pen p, bool extend);
-triple tickMin3(picture pic);
-triple tickMax3(picture pic);
-triple Scale(picture pic=<default>, triple v);
-triple[][] Scale(picture pic=<default>, triple[][] P);
-real ScaleX(picture pic=<default>, real x);
-real ScaleY(picture pic=<default>, real y);
-real ScaleZ(picture pic=<default>, real z);
-real[][] ScaleZ(picture pic=<default>, real[][] P);
-picture vectorfield(path3 vector(pair v), triple f(pair z), pair a, pair b, int nu=<default>, int nv=<default>, bool truesize=<default>, real maxlength=<default>, bool cond(pair z)=<default>, pen p=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>, string name=<default>, render render=<default>);
-path3 Circle(triple c, real r, triple normal=<default>, int n=<default>);
-void InTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
-void InTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks, real[] ticks=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
-void InTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>);
-void Spline(flatguide3)(... void(flatguide3)[]);
-void InOutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, tickvalues modify(tickvalues)=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
-void InOutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)(Label format=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, real[] Ticks, real[] ticks=<default>, real Size=<default>, real size=<default>, bool extend=<default>, pen pTick=<default>, pen ptick=<default>);
-void InOutTicks(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>);
-void axes3(picture pic=<default>, Label xlabel=<default>, Label ylabel=<default>, Label zlabel=<default>, bool extend=<default>, triple min=<default>, triple max=<default>, pen p=<default>, bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, marginT3 margin(path3, pen)=<default>);
-void label(picture pic, Label L, triple v, real x, align align, string format, pen p);
-void labelx(picture pic=<default>, Label L=<default>, triple v, align align=<default>, string format=<default>, pen p=<default>);
-void labely(picture pic=<default>, Label L=<default>, triple v, align align=<default>, string format=<default>, pen p=<default>);
-void labeltick(picture pic, real[][] T, path3 g, ticklocate locate, real val, int sign, real Size, string ticklabel(real), Label F, real norm=<default>);
-void labelaxis(picture pic, real[][] T, Label L, path3 g, ticklocate locate=<default>, int sign=<default>, bool ticklabels=<default>);
-void labelx3(picture pic=<default>, Label L=<default>, real x, align align=<default>, string format=<default>, pen p=<default>);
-void labely3(picture pic=<default>, Label L=<default>, real y, align align=<default>, string format=<default>, pen p=<default>);
-void labelz(picture pic=<default>, Label L=<default>, triple v, align align=<default>, string format=<default>, pen p=<default>);
-void labelz3(picture pic=<default>, Label L=<default>, real z, align align=<default>, string format=<default>, pen p=<default>);
-void autoscale3(picture pic=<default>, void axis(picture, axisT));
-void xtick(picture pic=<default>, triple v, triple dir=<default>, real size=<default>, pen p=<default>);
-void xtick(picture pic=<default>, Label L, triple v, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
-void ytick(picture pic=<default>, triple v, triple dir=<default>, real size=<default>, pen p=<default>);
-void ytick(picture pic=<default>, Label L, triple v, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
-void xtick3(picture pic=<default>, real x, triple dir=<default>, real size=<default>, pen p=<default>);
-void xtick3(picture pic=<default>, Label L, real x, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
-void ytick3(picture pic=<default>, real y, triple dir=<default>, real size=<default>, pen p=<default>);
-void ytick3(picture pic=<default>, Label L, real y, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
-void ztick(picture pic=<default>, triple v, triple dir=<default>, real size=<default>, pen p=<default>);
-void ztick(picture pic=<default>, Label L, triple v, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
-void ztick3(picture pic=<default>, real z, triple dir=<default>, real size=<default>, pen p=<default>);
-void ztick3(picture pic=<default>, Label L, real z, triple dir=<default>, string format=<default>, real size=<default>, pen p=<default>);
-triple defaultdir(triple X, triple Y, triple Z, bool opposite=<default>, projection P);
-real xtrans(real[][] t, real x);
-real ytrans(real[][] t, real y);
-real ztrans(real[][] t, real z);
-ticklocate ticklocate(real a, real b, autoscaleT S=<default>, real tickmin=<default>, real tickmax=<default>, real time(real)=<default>, triple dir(real));
-triple ticklabelshift(triple align, pen p=<default>);
-path3 Arc(triple c, triple v1, triple v2, triple normal=<default>, bool direction=<default>, int n=<default>);
-path3 Arc(triple c, real r, real theta1, real phi1, real theta2, real phi2, triple normal=<default>, bool direction, int n=<default>);
-path3 Arc(triple c, real r, real theta1, real phi1, real theta2, real phi2, triple normal=<default>, int n=<default>);
-void limits(picture pic=<default>, triple min, triple max);
-void XZEquals(picture, axisT)(real x, real z, triple align=<default>, bool extend=<default>);
-void YZEquals(picture, axisT)(real y, real z, triple align=<default>, bool extend=<default>);
-void XYZero(picture, axisT)(triple align=<default>, bool extend=<default>);
-void XYZero(picture, axisT);
-void zlimits(picture pic=<default>, real min=<default>, real max=<default>, bool crop=<default>);
-void tick(picture pic=<default>, triple v, triple dir, real size=<default>, pen p=<default>);
-void tick(picture pic=<default>, Label L, real value, triple v, triple dir, string format=<default>, real size=<default>, pen p=<default>);
-surface bispline(real[][] z, real[][] p, real[][] q, real[][] r, real[] x, real[] y, bool[][] cond=<default>);
-real[][][] bispline(real[][] f, real[] x, real[] y, real[] xsplinetype(real[], real[])=<default>, real[] ysplinetype(real[], real[])=<default>, bool[][] cond=<default>);
-real[][][] bispline0(real[][] z, real[][] p, real[][] q, real[][] r, real[] x, real[] y, bool[][] cond=<default>);
-real[] uniform(real T(real x), real Tinv(real x), real a, real b, int n);
-void NoTicks3(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>)();
-void NoTicks3(picture, real[][], Label, path3, path3, pen, bool(picture, path3, material, marginT3(path3, pen), light, light), marginT3(path3, pen), ticklocate, int[], bool opposite=<default>, bool primary=<default>);
bool Crop;
int ngraph;
real epsilon;
@@ -3223,9 +3229,9 @@ grid3(picture pic)[][] operator cast(grid3 gridroutine(picture pic));
triple X(picture pic);
triple Y(picture pic);
triple Z(picture pic);
+position middle;
grid3(picture pic)[] XYXgrid(position pos=<default>);
grid3(picture pic)[] XYXgrid;
-position middle;
grid3(picture pic)[] XY_XZgrid(position posa=<default>, position posb=<default>);
grid3(picture pic)[] XY_XZgrid;
grid3(picture pic)[] ZX_ZYgrid(position posa=<default>, position posb=<default>);
@@ -3238,10 +3244,10 @@ void grid3(picture pic=<default>, grid3(picture pic)[][] gridroutine=<default>,
void grid3(picture pic=<default>, grid3(picture pic)[][] gridroutine, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, pen[] pGrid, pen[] pgrid, bool above=<default>);
ticksgridT OutTicks()(Label F=<default>, string ticklabel(real)=<default>, bool beginlabel=<default>, bool endlabel=<default>, int N=<default>, int n=<default>, real Step=<default>, real step=<default>, bool begin=<default>, bool end=<default>, real Size=<default>, real size=<default>, pen pTick=<default>, pen ptick=<default>, grid3(picture pic)[][] gridroutine, pen pGrid=<default>, pen pgrid=<default>);
triple YZ(picture pic);
-triple ZX(picture pic);
void xaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, pen p=<default>, ticksgridT ticks(), bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, bool above=<default>);
void yaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, pen p=<default>, ticksgridT ticks(), bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, bool above=<default>);
void zaxis3(picture pic=<default>, Label L=<default>, void axis(picture, axisT)=<default>, pen p=<default>, ticksgridT ticks(), bool arrow(picture, path3, material, marginT3(path3, pen), light, light)=<default>, bool above=<default>);
+triple ZX(picture pic);
grid3(picture pic)[] ZXZgrid(position pos=<default>);
grid3(picture pic)[] ZXZgrid;
position top;
@@ -3263,26 +3269,26 @@ grid3(picture pic)[] ZYZgrid(position pos=<default>);
grid3(picture pic)[] ZYZgrid;
grid3 XZgrid(picture pic)(position pos=<default>);
grid3 XZgrid(picture pic);
-grid3 YZgrid(picture pic)(position pos=<default>);
-grid3 YZgrid(picture pic);
grid3(picture pic)[] YZYgrid(position pos=<default>);
grid3(picture pic)[] YZYgrid;
+grid3 YZgrid(picture pic)(position pos=<default>);
+grid3 YZgrid(picture pic);
real fspline(real)(real[] x, real[] y, real[] splinetype(real[], real[])=<default>);
real pwhermite(real)(real[] x, real[] y, real[] dy);
horner diffdiv(real[] x, real[] y);
horner hdiffdiv(real[] x, real[] y, real[] dy);
horner operator init();
real fhorner(real)(horner sh);
-void labelpath(frame f, Label L, path g, string justify=<default>, pen p=<default>);
-void labelpath(picture pic=<default>, Label L, path g, string justify=<default>, pen p=<default>);
-string LeftJustified;
-string Centered;
-string RightJustified;
surface labelpath(string s, path3 p, real angle=<default>, triple optional=<default>);
triple[] firstframe(path3 p, triple optional=<default>);
triple[] nextframe(path3 p, real reltimestart, triple[] start, real reltimeend, int subdiv=<default>);
real eps;
triple nextnormal(triple p, triple q);
+void labelpath(frame f, Label L, path g, string justify=<default>, pen p=<default>);
+void labelpath(picture pic=<default>, Label L, path g, string justify=<default>, pen p=<default>);
+string LeftJustified;
+string Centered;
+string RightJustified;
string[] lm_infmsg;
void lm_qrfac(int m, int n, real[] a, bool pivot, int[] ipvt, real[] rdiag, real[] acnorm, real[] wa);
void lm_qrsolv(int n, real[] r, int ldr, int[] ipvt, real[] diag, real[] qtb, real[] x, real[] sdiag, real[] wa);
@@ -3372,24 +3378,24 @@ bool polygon(path p);
pair unityroot(int n, int k=<default>);
real acot(real x);
pair[][] fft(pair[][] a, int sign=<default>);
-real slope(path g, real x, int n=<default>);
-real slope(path g, explicit pair z, int n=<default>);
+real slope(path g, real x, int n=<default>, real fuzz=<default>);
+real slope(path g, explicit pair z, int n=<default>, real fuzz=<default>);
+int[][] segmentlimits(bool[] b);
+int[][] segment(bool[] b);
picture grid(int Nx, int Ny, pen p=<default>);
rootfinder_settings operator init();
real frac(real x);
real asec(real x);
-int[][] segmentlimits(bool[] b);
-int[][] segment(bool[] b);
-real time(path g, real x, int n=<default>);
-real time(path g, explicit pair z, int n=<default>);
+real time(path g, real x, int n=<default>, real fuzz=<default>);
+real time(path g, explicit pair z, int n=<default>, real fuzz=<default>);
real[] leastsquares(real[][] A, real[] b, bool warn=<default>);
bool increasing(real[] a, bool strict=<default>);
real[] zero(int n);
real[][] zero(int n, int m);
real findroot(real f(real), real a, real b, real tolerance=<default>, real fa=<default>, real fb=<default>);
real acsc(real x);
-real value(path g, real x, int n=<default>);
-real value(path g, explicit pair z, int n=<default>);
+real value(path g, real x, int n=<default>, real fuzz=<default>);
+real value(path g, explicit pair z, int n=<default>, real fuzz=<default>);
real csc(real x);
pair log(explicit pair z);
void drawline(picture pic=<default>, pair P, pair Q, pen p=<default>);
@@ -3545,8 +3551,8 @@ void asyfilecode(bool center=<default>, string s, string options=<default>, stri
bool itemstep;
real itemskip;
void remark(bool center=<default>, string s, pair align=<default>, pen p=<default>, real indent=<default>, bool minipage=<default>, real skip=<default>, filltype filltype=<default>, bool step=<default>);
-void filecode(bool center=<default>, string s, pen p=<default>, real indent=<default>, real skip=<default>, filltype filltype=<default>);
void usersetting();
+void filecode(bool center=<default>, string s, pen p=<default>, real indent=<default>, real skip=<default>, filltype filltype=<default>);
bool landscape;
real codeskip;
void newslide(bool stepping=<default>);
@@ -3557,8 +3563,8 @@ void vbox(string s, pen p=<default>);
void asycode(bool center=<default>, string s, string options=<default>, string caption=<default>, string preamble=<default>, pair align=<default>, pen p=<default>, pen figuremattpen=<default>, real indent=<default>, real skip=<default>, filltype filltype=<default>, bool newslide=<default>);
void exitfunction();
bool havepagenumber;
-void item(string s, pen p=<default>, bool step=<default>);
real pageheight;
+void item(string s, pen p=<default>, bool step=<default>);
real pagewidth;
picture background;
void background();
@@ -3569,15 +3575,15 @@ pen titlepen;
real titleskip;
pair dateskip;
pair titlealign;
-pen authorpen;
pen titlepagepen;
void titlepage(string title, string author, string institution=<default>, string date=<default>, string url=<default>, bool newslide=<default>);
+pen authorpen;
pair titlepageposition;
pen codepen;
void erasestep(int erasenode);
-string cropcode(string s);
bool checkposition();
void setpens(pen red=<default>, pen blue=<default>, pen steppen=<default>);
+string cropcode(string s);
void code(bool center=<default>, string s, pen p=<default>, real indent=<default>, real skip=<default>, filltype filltype=<default>);
transform tinv;
pair urlskip;
@@ -3689,9 +3695,9 @@ int[] frequency(real[] data, real a, real b, int n);
int[][] frequency(real[] x, real[] y, real[] xbins, real[] ybins);
int[][] frequency(real[] x, real[] y, pair a, pair b, int nx, int ny=<default>);
int[][] frequency(pair[] z, pair a, pair b, int nx, int ny=<default>);
+real mean(real[] A);
void histogram(picture pic=<default>, real[] bins, real[] count, real low=<default>, pen fillpen=<default>, pen drawpen=<default>, bool bars=<default>, Label legend=<default>, real markersize=<default>);
void histogram(picture pic=<default>, real[] data, real a, real b, int n, bool normalize=<default>, real low=<default>, pen fillpen=<default>, pen drawpen=<default>, bool bars=<default>, Label legend=<default>, real markersize=<default>);
-real mean(real[] A);
int bins(real[] data, int max=<default>);
path topbox(pair a, pair b);
path halfbox(pair a, pair b);
@@ -3702,8 +3708,8 @@ real variancebiased(real[] A);
real Gaussian(real x, real sigma);
real Gaussian(real x);
pair Gaussrandpair();
-real Gaussrand();
linefit operator init();
+real Gaussrand();
real skewness(real[] A);
linefit leastsquares(real[] x, real[] y);
real kurtosis(real[] A);
@@ -3819,6 +3825,16 @@ coloredpath operator init();
coloredpath operator cast(path p);
coloredpath operator cast(guide p);
real degrees(rmf a, rmf b);
+void importv3d(string name);
+triangleGroup operator init();
+pixel operator init();
+CameraInformation operator init();
+v3dfile operator init();
+real[][] Align(real polar, real azimuth);
+v3dheadertypes v3dheadertypes;
+v3dheadertypes operator init();
+v3dtypes v3dtypes;
+v3dtypes operator init();
string VERSION;
pen Orchid;
pen Indigo;
@@ -3826,28 +3842,28 @@ pen Beige;
pen SlateBlue;
pen SlateGray;
pen Magenta;
+pen DarkOliveGreen;
+pen DarkOrange;
pen CadetBlue;
pen DeepPink;
-pen LavenderBlush;
-pen Wheat;
pen SpringGreen;
+pen Silver;
pen MidnightBlue;
-pen PeachPuff;
pen Olive;
pen OliveDrab;
pen Salmon;
-pen Lime;
-pen SteelBlue;
pen Chocolate;
+pen Linen;
+pen SandyBrown;
pen Cyan;
pen Gainsboro;
pen Ivory;
pen PapayaWhip;
pen Red;
pen Pink;
+pen DeepSkyBlue;
pen MintCream;
pen DarkTurquoise;
-pen LemonChiffon;
pen Gray;
pen MediumBlue;
pen MediumOrchid;
@@ -3859,11 +3875,11 @@ pen MediumSpringGreen;
pen MediumTurquoise;
pen MediumVioletRed;
pen Plum;
-pen Aqua;
pen Blue;
pen Gold;
pen BlueViolet;
pen Goldenrod;
+pen Cornsilk;
pen ForestGreen;
pen Chartreuse;
pen NavajoWhite;
@@ -3871,70 +3887,71 @@ pen Tan;
pen DarkMagenta;
pen AntiqueWhite;
pen PaleTurquoise;
-pen Aquamarine;
pen IndianRed;
+pen Seashell;
+pen Aquamarine;
pen Crimson;
pen Azure;
-pen LawnGreen;
-pen Lavender;
pen Brown;
+pen LawnGreen;
pen BurlyWood;
pen Moccasin;
+pen Lavender;
pen DarkBlue;
+pen GhostWhite;
pen Peru;
pen White;
pen Purple;
pen WhiteSmoke;
-pen Sienna;
pen DimGray;
pen Orange;
pen OrangeRed;
pen Fuchsia;
-pen Honeydew;
pen Bisque;
+pen Honeydew;
pen RosyBrown;
pen Black;
+pen LavenderBlush;
pen Khaki;
+pen Wheat;
pen FireBrick;
-pen DarkOliveGreen;
-pen DarkOrange;
+pen PeachPuff;
pen Snow;
pen Maroon;
pen YellowGreen;
+pen Lime;
pen LimeGreen;
-pen Silver;
+pen SteelBlue;
pen OldLace;
pen Green;
pen GreenYellow;
pen DarkCyan;
pen FloralWhite;
pen DarkRed;
-pen SandyBrown;
+pen LemonChiffon;
pen BlanchedAlmond;
pen PowderBlue;
pen DarkGray;
pen DarkGreen;
-pen DeepSkyBlue;
pen DarkGoldenrod;
+pen Aqua;
pen SkyBlue;
pen SeaGreen;
pen DarkViolet;
pen Teal;
-pen Violet;
pen AliceBlue;
+pen Violet;
pen HotPink;
pen DodgerBlue;
pen SaddleBrown;
pen Tomato;
pen DarkKhaki;
-pen Cornsilk;
pen Thistle;
pen LightBlue;
pen LightCoral;
pen Yellow;
pen LightCyan;
pen PaleGreen;
-pen Linen;
pen LightGoldenrodYellow;
pen LightGreen;
pen LightGrey;
@@ -3942,10 +3959,10 @@ pen PaleGoldenrod;
pen LightPink;
pen LightSalmon;
pen LightSeaGreen;
-pen Navy;
pen LightSkyBlue;
+pen Navy;
+pen Sienna;
pen PaleVioletRed;
-pen Seashell;
pen DarkOrchid;
pen CornflowerBlue;
pen LightSlateGray;
@@ -3954,7 +3971,6 @@ pen rgbint(int r, int g, int b);
pen LightYellow;
pen Coral;
pen MistyRose;
-pen GhostWhite;
pen DarkSalmon;
pen DarkSeaGreen;
pen RoyalBlue;
diff --git a/graphics/asymptote/asymptote.spec b/graphics/asymptote/asymptote.spec
index a6c12915d5..63ef30356d 100644
--- a/graphics/asymptote/asymptote.spec
+++ b/graphics/asymptote/asymptote.spec
@@ -3,7 +3,7 @@
%global __python %{__python3}
Name: asymptote
-Version: 2.70
+Version: 2.72
Release: 1%{?dist}
Summary: Descriptive vector graphics language
@@ -25,6 +25,7 @@ BuildRequires: dvisvgm >= 2.9.1
BuildRequires: texinfo >= 4.7
BuildRequires: ImageMagick
BuildRequires: libtirpc-devel
+BuildRequires: libboost-devel
Requires: tetex-latex
Requires: freeglut-devel >= 3.0.0
@@ -33,7 +34,7 @@ Requires(postun): /usr/bin/texhash /sbin/install-info
%description
Asymptote is a powerful descriptive vector graphics language for technical
-drawings, inspired by MetaPost but with an improved C++-like syntax.
+drawing, inspired by MetaPost but with an improved C++-like syntax.
Asymptote provides for figures the same high-quality level of typesetting
that LaTeX does for scientific text.
@@ -43,7 +44,7 @@ that LaTeX does for scientific text.
%build
-CFLAGS="`echo $RPM_OPT_FLAGS | sed s/-O2/-O3/`" \
+CFLAGS="`echo $RPM_OPT_FLAGS | sed s/-O2/-O3/` -fno-lto" \
%configure --with-latex=%{_texmf}/tex/latex --with-context=%{_texmf}/tex/context/third
make %{?_smp_mflags}
diff --git a/graphics/asymptote/base/asy-mode.el b/graphics/asymptote/base/asy-mode.el
index ec3a3746d7..9f6eda793c 100644
--- a/graphics/asymptote/base/asy-mode.el
+++ b/graphics/asymptote/base/asy-mode.el
@@ -110,7 +110,7 @@ Some variables can be customized: M-x customize-group <RET> asymptote <RET>."
(require 'font-lock)
(require 'cc-mode)
-(require 'cl) ;; Common Lisp extensions for Emacs
+(require 'cl-lib) ;; Common Lisp extensions for Emacs
(require 'compile)
(require 'wid-edit)
@@ -637,6 +637,9 @@ Fields are defined as 'field1: field2.field3:field4' . Field=0 <-> all fields"
(if (locate-library "two-mode-mode")
(progn
+;; patch two-mode-mode.el for Emacs >= 23.
+ (defun make-local-hook (func))
+
(defvar lasy-fontify-asy-p nil
"Variable to communicate with `font-lock-unfontify-region'.
Internal use, don't set in any fashion.")
@@ -682,7 +685,8 @@ the current mode."
(setq lasy-fontify-asy-p (eq func 'asy-mode))
(funcall func)
(hack-local-variables)
- (two-mode-mode-setup)
+;; avoid infinite loop in two-mode-mode
+;; (two-mode-mode-setup)
(if two-mode-switch-hook
(run-hooks 'two-mode-switch-hook))
(if (eq font-lock-mode t)
diff --git a/graphics/asymptote/base/graph.asy b/graphics/asymptote/base/graph.asy
index 46a5d7d064..1d4dfc1bfd 100644
--- a/graphics/asymptote/base/graph.asy
+++ b/graphics/asymptote/base/graph.asy
@@ -2090,6 +2090,29 @@ guide polargraph(picture pic=currentpicture, real[] r, real[] theta,
},0,0,n-1);
}
+// Graph a parametric function with the control points specified to match the
+// derivative.
+guide graphwithderiv(pair f(real), pair fprime(real), real a, real b,
+ int n=ngraph # 10) {
+ guide toreturn;
+ real segmentlen = (b - a) / n;
+ pair[] points = new pair[n+1];
+ pair[] derivs = new pair[n+1];
+ real derivfactor = segmentlen / 3;
+ for (int i = 0; i <= n; ++i) {
+ real t = interp(a, b, i/n);
+ points[i] = f(t);
+ derivs[i] = fprime(t) * derivfactor;
+ }
+
+ toreturn = points[0];
+ for (int i = 1; i <= n; ++i) {
+ toreturn = toreturn .. controls (points[i-1] + derivs[i-1])
+ and (points[i] - derivs[i]) .. points[i];
+ }
+ return toreturn;
+}
+
void errorbar(picture pic, pair z, pair dp, pair dm, pen p=currentpen,
real size=0)
{
diff --git a/graphics/asymptote/base/math.asy b/graphics/asymptote/base/math.asy
index 3dde1b9dd4..d0ce523340 100644
--- a/graphics/asymptote/base/math.asy
+++ b/graphics/asymptote/base/math.asy
@@ -325,45 +325,45 @@ real interpolate(real[] x, real[] y, real x0)
private string nopoint="point not found";
// Return the nth intersection time of path g with the vertical line through x.
-real time(path g, real x, int n=0)
+real time(path g, real x, int n=0, real fuzz=-1)
{
- real[] t=times(g,x);
+ real[] t=times(g,x,fuzz);
if(t.length <= n) abort(nopoint);
return t[n];
}
// Return the nth intersection time of path g with the horizontal line through
// (0,z.y).
-real time(path g, explicit pair z, int n=0)
+real time(path g, explicit pair z, int n=0, real fuzz=-1)
{
- real[] t=times(g,z);
+ real[] t=times(g,z,fuzz);
if(t.length <= n) abort(nopoint);
return t[n];
}
// Return the nth y value of g at x.
-real value(path g, real x, int n=0)
+real value(path g, real x, int n=0, real fuzz=-1)
{
- return point(g,time(g,x,n)).y;
+ return point(g,time(g,x,n,fuzz)).y;
}
// Return the nth x value of g at y=z.y.
-real value(path g, explicit pair z, int n=0)
+real value(path g, explicit pair z, int n=0, real fuzz=-1)
{
- return point(g,time(g,(0,z.y),n)).x;
+ return point(g,time(g,(0,z.y),n,fuzz)).x;
}
// Return the nth slope of g at x.
-real slope(path g, real x, int n=0)
+real slope(path g, real x, int n=0, real fuzz=-1)
{
- pair a=dir(g,time(g,x,n));
+ pair a=dir(g,time(g,x,n,fuzz));
return a.y/a.x;
}
// Return the nth slope of g at y=z.y.
-real slope(path g, explicit pair z, int n=0)
+real slope(path g, explicit pair z, int n=0, real fuzz=-1)
{
- pair a=dir(g,time(g,(0,z.y),n));
+ pair a=dir(g,time(g,(0,z.y),n,fuzz));
return a.y/a.x;
}
diff --git a/graphics/asymptote/base/plain.asy b/graphics/asymptote/base/plain.asy
index 365aad02c7..cac6aa0722 100644
--- a/graphics/asymptote/base/plain.asy
+++ b/graphics/asymptote/base/plain.asy
@@ -150,7 +150,13 @@ void initdefaults()
// Return the sequence n,...,m
int[] sequence(int n, int m)
{
- return sequence(new int(int x){return x;},m-n+1)+n;
+ return n+sequence(m-n+1);
+}
+
+// Return the sequence n,...,m skipping by skip
+int[] sequence(int n, int m, int skip)
+{
+ return n+skip*sequence((m-n)#skip+1);
}
int[] reverse(int n) {return sequence(new int(int x){return n-1-x;},n);}
diff --git a/graphics/asymptote/base/plain_boxes.asy b/graphics/asymptote/base/plain_boxes.asy
index 50501a4089..9576caff55 100644
--- a/graphics/asymptote/base/plain_boxes.asy
+++ b/graphics/asymptote/base/plain_boxes.asy
@@ -28,7 +28,7 @@ path roundbox(frame dest, frame src=dest, real xmargin=0, real ymargin=xmargin,
(dw,b)--(a-dw,b){right}..{down}
(a,b-dw)--(a,dw){down}..{left}
(a-dw,0)--(dw,0){left}..{up}cycle);
-
+
frame F;
if(above == false) {
filltype.fill(F,g,p);
@@ -81,7 +81,7 @@ typedef path envelope(frame dest, frame src=dest, real xmargin=0,
filltype filltype=NoFill, bool above=true);
object object(Label L, envelope e, real xmargin=0, real ymargin=xmargin,
- pen p=currentpen, filltype filltype=NoFill, bool above=true)
+ pen p=currentpen, filltype filltype=NoFill, bool above=true)
{
object F;
F.L=L.copy();
@@ -93,9 +93,9 @@ object object(Label L, envelope e, real xmargin=0, real ymargin=xmargin,
return F;
}
-object draw(picture pic=currentpicture, Label L, envelope e,
+object draw(picture pic=currentpicture, Label L, envelope e,
real xmargin=0, real ymargin=xmargin, pen p=currentpen,
- filltype filltype=NoFill, bool above=true)
+ filltype filltype=NoFill, bool above=true)
{
object F=object(L,e,xmargin,ymargin,p,filltype,above);
pic.add(new void (frame f, transform t) {
@@ -115,7 +115,7 @@ object draw(picture pic=currentpicture, Label L, envelope e, pair position,
return draw(pic,Label(L,position),e,xmargin,ymargin,p,filltype,above);
}
-pair point(object F, pair dir, transform t=identity())
+pair point(object F, pair dir, transform t=identity())
{
pair m=min(F.g);
pair M=max(F.g);
diff --git a/graphics/asymptote/base/plain_constants.asy b/graphics/asymptote/base/plain_constants.asy
index 136b354021..6cca1406cf 100644
--- a/graphics/asymptote/base/plain_constants.asy
+++ b/graphics/asymptote/base/plain_constants.asy
@@ -31,9 +31,9 @@ restricted pair WSW=unit(W+SW);
restricted pair SSW=unit(S+SW);
restricted pair SSE=unit(S+SE);
restricted pair ESE=unit(E+SE);
-
+
restricted real sqrtEpsilon=sqrt(realEpsilon);
-restricted pair Align=sqrtEpsilon*NE;
+restricted pair Align=sqrtEpsilon*NE;
restricted int mantissaBits=ceil(-log(realEpsilon)/log(2))+1;
restricted transform identity;
@@ -108,7 +108,7 @@ void write(file file, string s="", bool3 b, suffix suffix=none)
else write("default",suffix);
}
-void write(string s="", bool3 b, suffix suffix=endl)
+void write(string s="", bool3 b, suffix suffix=endl)
{
write(stdout,s,b,suffix);
}
@@ -128,32 +128,32 @@ bool3 operator cast(bool b)
return B;
}
-bool operator == (bool3 a, bool3 b)
+bool operator == (bool3 a, bool3 b)
{
return a.set == b.set && (!a.set || (a.value == b.value));
}
-bool operator != (bool3 a, bool3 b)
+bool operator != (bool3 a, bool3 b)
{
return a.set != b.set || (a.set && (a.value != b.value));
}
-bool operator == (bool3 a, bool b)
+bool operator == (bool3 a, bool b)
{
return a.set && a.value == b;
}
-bool operator != (bool3 a, bool b)
+bool operator != (bool3 a, bool b)
{
return !a.set || a.value != b;
}
-bool operator == (bool a, bool3 b)
+bool operator == (bool a, bool3 b)
{
return b.set && b.value == a;
}
-bool operator != (bool a, bool3 b)
+bool operator != (bool a, bool3 b)
{
return !b.set || b.value != a;
}
diff --git a/graphics/asymptote/base/plain_filldraw.asy b/graphics/asymptote/base/plain_filldraw.asy
index 026f2cee6c..eaf1257169 100644
--- a/graphics/asymptote/base/plain_filldraw.asy
+++ b/graphics/asymptote/base/plain_filldraw.asy
@@ -3,7 +3,7 @@ void makedraw(frame f, path g, pen p, int depth=mantissaBits)
{
if(depth == 0) return;
--depth;
-
+
path n=nib(p);
for(int i=0; i < size(g); ++i)
fill(f,shift(point(g,i))*n,p);
@@ -88,7 +88,7 @@ void filloutside(frame f, path[] g, pen p=currentpen, bool copy=true)
fill(f,complement(f,g),p+evenodd,copy);
}
-struct filltype
+struct filltype
{
typedef void fill2(frame f, path[] g, pen fillpen);
fill2 fill2;
@@ -101,7 +101,7 @@ struct filltype
static int Draw=3;
static int NoFill=4;
static int UnFill=5;
-
+
void operator init(int type=0, pen fillpen=nullpen, pen drawpen=nullpen,
fill2 fill2) {
this.type=type;
@@ -112,7 +112,7 @@ struct filltype
void fill(frame f, path[] g, pen p) {fill2(f,g,p);}
}
-path[] margin(path[] g, real xmargin, real ymargin)
+path[] margin(path[] g, real xmargin, real ymargin)
{
if(xmargin != 0 || ymargin != 0) {
pair M=max(g);
@@ -123,7 +123,7 @@ path[] margin(path[] g, real xmargin, real ymargin)
real yfactor=height > 0 ? (height+2ymargin)/height : 1;
g=scale(xfactor,yfactor)*g;
g=shift(0.5*(M+m)-0.5*(max(g)+min(g)))*g;
- }
+ }
return g;
}
@@ -174,7 +174,7 @@ filltype UnFill(real xmargin=0, real ymargin=xmargin)
});
}
-filltype FillDraw=FillDraw(), Fill=Fill(), Draw=Draw(), UnFill=UnFill();
+filltype FillDraw=FillDraw(), Fill=Fill(), Draw=Draw(), UnFill=UnFill();
// Fill varying radially from penc at the center of the bounding box to
// penr at the edge.
diff --git a/graphics/asymptote/base/plain_margins.asy b/graphics/asymptote/base/plain_margins.asy
index fbd0163050..c03b3a2b52 100644
--- a/graphics/asymptote/base/plain_margins.asy
+++ b/graphics/asymptote/base/plain_margins.asy
@@ -27,7 +27,7 @@ margin operator +(margin ma, margin mb)
}
margin NoMargin()
-{
+{
return new marginT(path g, pen) {
marginT margin;
margin.begin=margin.end=0;
@@ -35,9 +35,9 @@ margin NoMargin()
return margin;
};
}
-
+
margin Margin(real begin, real end=begin)
-{
+{
return new marginT(path g, pen p) {
marginT margin;
real factor=labelmargin(p);
@@ -47,9 +47,9 @@ margin Margin(real begin, real end=begin)
return margin;
};
}
-
+
margin PenMargin(real begin, real end=begin)
-{
+{
return new marginT(path g, pen p) {
marginT margin;
real factor=linewidth(p);
@@ -59,9 +59,9 @@ margin PenMargin(real begin, real end=begin)
return margin;
};
}
-
+
margin DotMargin(real begin, real end=begin)
-{
+{
return new marginT(path g, pen p) {
marginT margin;
real margindot(real x) {return x > 0 ? dotfactor*x : x;}
@@ -72,9 +72,9 @@ margin DotMargin(real begin, real end=begin)
return margin;
};
}
-
+
margin TrueMargin(real begin, real end=begin)
-{
+{
return new marginT(path g, pen p) {
marginT margin;
margin.begin=begin;
@@ -83,7 +83,7 @@ margin TrueMargin(real begin, real end=begin)
return margin;
};
}
-
+
margin NoMargin=NoMargin(),
BeginMargin=Margin(1,0),
Margin=Margin(0,1),
diff --git a/graphics/asymptote/base/plain_markers.asy b/graphics/asymptote/base/plain_markers.asy
index 250e1701eb..c6109d4e6c 100644
--- a/graphics/asymptote/base/plain_markers.asy
+++ b/graphics/asymptote/base/plain_markers.asy
@@ -5,7 +5,7 @@ real legendmargin=10;
real legendmaxrelativewidth=1;
// Return a unit polygon with n sides.
-path polygon(int n)
+path polygon(int n)
{
guide g;
for(int i=0; i < n; ++i) g=g--expi(2pi*(i+0.5)/n-0.5*pi);
@@ -14,7 +14,7 @@ path polygon(int n)
// Return a unit n-point cyclic cross, with optional inner radius r and
// end rounding.
-path cross(int n, bool round=true, real r=0)
+path cross(int n, bool round=true, real r=0)
{
assert(n > 1);
real r=min(r,1);
@@ -41,7 +41,8 @@ path cross(int n, bool round=true, real r=0)
return g--cycle;
}
-path[] plus=(-1,0)--(1,0)^^(0,-1)--(0,1);
+path plus=rotate(45)*cross(4);
+path diamond=rotate(45)*polygon(4);
typedef void markroutine(picture pic=currentpicture, frame f, path g);
@@ -98,9 +99,9 @@ struct marker {
markroutine(pic,f,g);
};
}
-
+
marker marker(frame f=newframe, markroutine markroutine=marknodes,
- bool above=true)
+ bool above=true)
{
marker m=new marker;
m.f=f;
@@ -147,15 +148,18 @@ real circlescale=0.85;
path[] MarkPath={scale(circlescale)*unitcircle,
polygon(3),polygon(4),polygon(5),invert*polygon(3),
- cross(4),cross(6)};
+ cross(4),cross(6),diamond,plus};
+
+int[] MarkFillable={0,1,2,3,4,7};
marker[] Mark=sequence(new marker(int i) {return marker(MarkPath[i]);},
MarkPath.length);
-marker[] MarkFill=sequence(new marker(int i) {return marker(MarkPath[i],Fill);},
- MarkPath.length-2);
+marker[] MarkFill=sequence(new marker(int i) {
+ return marker(MarkPath[MarkFillable[i]],Fill);
+ },MarkFillable.length);
-marker Mark(int n)
+marker Mark(int n)
{
n=n % (Mark.length+MarkFill.length);
if(n < Mark.length) return Mark[n];
@@ -194,7 +198,7 @@ picture legend(Legend[] Legend, int perline=1, real linelength,
if(Legend.length == 0)
return inset;
- // Check for legend entries with lines:
+ // Check for legend entries with lines:
bool bLineEntriesAvailable=false;
for(int i=0; i < Legend.length; ++i) {
if(Legend[i].p != invisible) {
@@ -231,8 +235,8 @@ picture legend(Legend[] Legend, int perline=1, real linelength,
totalwidth += size(pic).x;
}
}
- // Does everything fit into one line?
- if(((perline < 1) || (perline >= Legend.length)) &&
+ // Does everything fit into one line?
+ if(((perline < 1) || (perline >= Legend.length)) &&
(maxwidth >= totalwidth+(totalwidth/Legend.length)*
(Legend.length-1)*(hskip-1))) {
// One-line legend
@@ -285,7 +289,7 @@ frame legend(picture pic=currentpicture, int perline=1,
real xmargin=legendmargin, real ymargin=xmargin,
real linelength=legendlinelength,
real hskip=legendhskip, real vskip=legendvskip,
- real maxwidth=perline == 0 ?
+ real maxwidth=perline == 0 ?
legendmaxrelativewidth*size(pic).x : 0, real maxheight=0,
bool hstretch=false, bool vstretch=false, pen p=currentpen)
{
@@ -312,7 +316,7 @@ void dot(frame f, pair z, pen p=currentpen, filltype filltype=dotfilltype)
if(filltype == Fill)
draw(f,z,dotsize(p)+p);
else {
- real s=0.5*(dotsize(p)-linewidth(p));
+ real s=0.5*(dotsize(p)-linewidth(p));
if(s <= 0) return;
path g=shift(z)*scale(s)*unitcircle;
begingroup(f);
@@ -398,4 +402,4 @@ marker dot(pen p=currentpen, filltype filltype=dotfilltype)
}
marker dot=dot();
-
+
diff --git a/graphics/asymptote/base/plain_paths.asy b/graphics/asymptote/base/plain_paths.asy
index 8bb5250db5..49d2f4ac0b 100644
--- a/graphics/asymptote/base/plain_paths.asy
+++ b/graphics/asymptote/base/plain_paths.asy
@@ -51,32 +51,32 @@ path[] operator cast(guide g)
return new path[] {(path) g};
}
-path[] operator ^^ (path p, path q)
+path[] operator ^^ (path p, path q)
{
return new path[] {p,q};
}
-path[] operator ^^ (path p, explicit path[] q)
+path[] operator ^^ (path p, explicit path[] q)
{
return concat(new path[] {p},q);
}
-path[] operator ^^ (explicit path[] p, path q)
+path[] operator ^^ (explicit path[] p, path q)
{
return concat(p,new path[] {q});
}
-path[] operator ^^ (explicit path[] p, explicit path[] q)
+path[] operator ^^ (explicit path[] p, explicit path[] q)
{
return concat(p,q);
}
-path[] operator * (transform t, explicit path[] p)
+path[] operator * (transform t, explicit path[] p)
{
return sequence(new path(int i) {return t*p[i];},p.length);
}
-pair[] operator * (transform t, pair[] z)
+pair[] operator * (transform t, pair[] z)
{
return sequence(new pair(int i) {return t*z[i];},z.length);
}
@@ -93,7 +93,7 @@ void write(file file, string s="", explicit path[] x, suffix suffix=none)
write(file,suffix);
}
-void write(string s="", explicit path[] x, suffix suffix=endl)
+void write(string s="", explicit path[] x, suffix suffix=endl)
{
write(stdout,s,x,suffix);
}
@@ -110,7 +110,7 @@ void write(file file, string s="", explicit guide[] x, suffix suffix=none)
write(file,suffix);
}
-void write(string s="", explicit guide[] x, suffix suffix=endl)
+void write(string s="", explicit guide[] x, suffix suffix=endl)
{
write(stdout,s,x,suffix);
}
@@ -156,8 +156,8 @@ pair[] intersectionpoints(explicit path[] p, explicit path[] q, real fuzz=-1)
struct slice {
path before,after;
}
-
-slice cut(path p, path knife, int n)
+
+slice cut(path p, path knife, int n)
{
slice s;
real[][] T=intersections(p,knife);
@@ -169,7 +169,7 @@ slice cut(path p, path knife, int n)
return s;
}
-slice firstcut(path p, path knife)
+slice firstcut(path p, path knife)
{
return cut(p,knife,0);
}
@@ -331,16 +331,16 @@ pair inside(path p, pen fillrule=currentpen)
}
// Return all intersection times of path g with the vertical line through (x,0).
-real[] times(path p, real x)
+real[] times(path p, real x, real fuzz=-1)
{
- return intersections(p,(x,0),(x,1));
+ return intersections(p,(x,0),(x,1),fuzz);
}
// Return all intersection times of path g with the horizontal line through
// (0,z.y).
-real[] times(path p, explicit pair z)
+real[] times(path p, explicit pair z, real fuzz=-1)
{
- return intersections(p,(0,z.y),(1,z.y));
+ return intersections(p,(0,z.y),(1,z.y),fuzz);
}
path randompath(int n, bool cumulate=true, interpolate join=operator ..)
@@ -349,7 +349,7 @@ path randompath(int n, bool cumulate=true, interpolate join=operator ..)
pair w;
for(int i=0; i <= n; ++i) {
pair z=(unitrand()-0.5,unitrand()-0.5);
- if(cumulate) w += z;
+ if(cumulate) w += z;
else w=z;
g=join(g,w);
}
diff --git a/graphics/asymptote/base/plain_pens.asy b/graphics/asymptote/base/plain_pens.asy
index b846569658..2e3a4449a3 100644
--- a/graphics/asymptote/base/plain_pens.asy
+++ b/graphics/asymptote/base/plain_pens.asy
@@ -8,7 +8,7 @@ pen longdashed=linetype(new real[] {24,8});
pen dashdotted=linetype(new real[] {8,8,0,8});
pen longdashdotted=linetype(new real[] {24,8,0,8});
-pen linetype(string pattern, real offset=0, bool scale=true, bool adjust=true)
+pen linetype(string pattern, real offset=0, bool scale=true, bool adjust=true)
{
return linetype((real[]) split(pattern),offset,scale,adjust);
}
@@ -151,7 +151,7 @@ pen[] monoPen={solid,dashed,dotted,longdashed,dashdotted,
longdashdotted};
monoPen.cyclic=true;
-pen Pen(int n)
+pen Pen(int n)
{
return (settings.gray || settings.bw) ? monoPen[n] : colorPen[n];
}
@@ -161,12 +161,12 @@ pen Pentype(int n)
return (settings.gray || settings.bw) ? monoPen[n] : monoPen[n]+colorPen[n];
}
-real dotsize(pen p=currentpen)
+real dotsize(pen p=currentpen)
{
return dotfactor*linewidth(p);
}
-pen fontsize(real size)
+pen fontsize(real size)
{
return fontsize(size,1.2*size);
}
@@ -189,7 +189,7 @@ void usetypescript(string s, string encoding="")
texpreamble(s);
}
-pen font(string name, string options="")
+pen font(string name, string options="")
{
// Work around misalignment in ConTeXt switchtobodyfont if font is not found.
return fontcommand(settings.tex == "context" ?
@@ -199,7 +199,7 @@ pen font(string name, string options="")
"\font\ASYfont="+name+"\ASYfont");
}
-pen font(string name, real size, string options="")
+pen font(string name, real size, string options="")
{
string s=(string) (size/pt)+"pt";
if(settings.tex == "context")
@@ -207,7 +207,7 @@ pen font(string name, real size, string options="")
return fontsize(size)+font(name+" at "+s);
}
-pen font(string encoding, string family, string series, string shape)
+pen font(string encoding, string family, string series, string shape)
{
return fontcommand("\usefont{"+encoding+"}{"+family+"}{"+series+"}{"+shape+
"}");
@@ -316,16 +316,21 @@ real[] rgba(pen p)
return a;
}
+pen rgb(real[] a)
+{
+ return rgb(a[0],a[1],a[2]);
+}
+
pen rgba(real[] a)
{
return rgb(a[0],a[1],a[2])+opacity(a[3]);
}
// Return a pen corresponding to a given 6-character RGB hexadecimal string.
-pen rgb(string s)
+pen rgb(string s)
{
int offset=substr(s,0,1) == '#' ? 1 : 0;
- real value(string s, int i) {return hex(substr(s,2i+offset,2))/255;}
+ real value(string s, int i) {return byteinv(hex(substr(s,2i+offset,2)));}
return rgb(value(s,0),value(s,1),value(s,2));
}
diff --git a/graphics/asymptote/base/plain_picture.asy b/graphics/asymptote/base/plain_picture.asy
index c0c189ee69..13619e80ab 100644
--- a/graphics/asymptote/base/plain_picture.asy
+++ b/graphics/asymptote/base/plain_picture.asy
@@ -59,10 +59,10 @@ struct coords3 {
}
}
}
-
+
// scaleT and Legend <<<
typedef real scalefcn(real x);
-
+
struct scaleT {
scalefcn T,Tinv;
bool logarithmic;
@@ -86,7 +86,7 @@ scaleT operator init()
scaleT S=scaleT(identity,identity);
return S;
}
-
+
typedef void boundRoutine();
struct autoscaleT {
@@ -97,11 +97,11 @@ struct autoscaleT {
bool automin=false, automax=false;
bool automin() {return automin && scale.automin;}
bool automax() {return automax && scale.automax;}
-
+
real T(real x) {return postscale.T(scale.T(x));}
scalefcn T() {return scale.logarithmic ? postscale.T : T;}
real Tinv(real x) {return scale.Tinv(postscale.Tinv(x));}
-
+
autoscaleT copy() {
autoscaleT dest=new autoscaleT;
dest.scale=scale.copy();
@@ -120,7 +120,7 @@ struct ScaleT {
autoscaleT x;
autoscaleT y;
autoscaleT z;
-
+
ScaleT copy() {
ScaleT dest=new ScaleT;
dest.set=set;
@@ -240,15 +240,15 @@ struct picture { // <<<1
return b;
}
}
-
+
bounds bounds;
bounds3 bounds3;
-
+
// Other Fields <<<2
// Transform to be applied to this picture.
transform T;
transform3 T3;
-
+
// The internal representation of the 3D user bounds.
private pairOrTriple umin, umax;
private bool usetx, usety, usetz;
@@ -267,14 +267,14 @@ struct picture { // <<<1
// Fixed unitsizes in the x y, and z directions; zero means use
// xsize, ysize, and zsize.
real xunitsize=0, yunitsize=0, zunitsize=0;
-
+
// If true, the x and y directions must be scaled by the same amount.
bool keepAspect=true;
// A fixed scaling transform.
bool fixed;
transform fixedscaling;
-
+
// Init and erase <<<2
void init() {
umin.init();
@@ -283,7 +283,7 @@ struct picture { // <<<1
T3=identity(4);
}
init();
-
+
// Erase the current picture, retaining bounds.
void clear() {
nodes.delete();
@@ -300,7 +300,7 @@ struct picture { // <<<1
scale=new ScaleT;
init();
}
-
+
// Empty <<<2
bool empty2() {
return nodes.length == 0;
@@ -313,7 +313,7 @@ struct picture { // <<<1
bool empty() {
return empty2() && empty3();
}
-
+
// User min/max <<<2
pair userMin2() {return bounds.userMin(); }
pair userMax2() {return bounds.userMax(); }
@@ -373,27 +373,27 @@ struct picture { // <<<1
umin.x=x;
usetx=true;
}
-
+
void userMiny3(real y) {
umin.y=y;
usety=true;
}
-
+
void userMinz3(real z) {
umin.z=z;
usetz=true;
}
-
+
void userMaxx3(real x) {
umax.x=x;
usetx=true;
}
-
+
void userMaxy3(real y) {
umax.y=y;
usety=true;
}
-
+
void userMaxz3(real z) {
umax.z=z;
usetz=true;
@@ -409,7 +409,7 @@ struct picture { // <<<1
void userMaxy(real y) { userMaxy2(y); userMaxy3(y); }
void userMinz(real z) = userMinz3;
void userMaxz(real z) = userMaxz3;
-
+
void userCorners3(triple c000, triple c001, triple c010, triple c011,
triple c100, triple c101, triple c110, triple c111) {
umin.x = min(c000.x,c001.x,c010.x,c011.x,c100.x,c101.x,c110.x,c111.x);
@@ -419,7 +419,7 @@ struct picture { // <<<1
umax.y = max(c000.y,c001.y,c010.y,c011.y,c100.y,c101.y,c110.y,c111.y);
umax.z = max(c000.z,c001.z,c010.z,c011.z,c100.z,c101.z,c110.z,c111.z);
}
-
+
// Cache the current user-space bounding box x coodinates
void userBoxX3(real min, real max, binop m=min, binop M=max) {
if (usetx) {
@@ -462,7 +462,7 @@ struct picture { // <<<1
userBoxY3(min.y,max.y);
userBoxZ3(min.z,max.z);
}
-
+
// Add drawer <<<2
void add(drawerBound d, bool exact=false, bool above=true) {
uptodate=false;
@@ -472,7 +472,7 @@ struct picture { // <<<1
else
nodes.insert(0,node(d));
}
-
+
// Faster implementation of most common case.
void addExactAbove(drawerBound d) {
uptodate=false;
@@ -518,13 +518,13 @@ struct picture { // <<<1
bounds.addPoint(user,truesize);
//userBox(user,user);
}
-
+
// Add a point to the sizing, accounting also for the size of the pen.
void addPoint(pair user, pair truesize=0, pen p) {
addPoint(user,truesize+min(p));
addPoint(user,truesize+max(p));
}
-
+
void addPoint(triple user, triple truesize=(0,0,0)) {
bounds3.point.push(user,truesize);
userBox3(user,user);
@@ -618,7 +618,7 @@ struct picture { // <<<1
}
void append(coords3 point, coords3 min, coords3 max, transform3 t,
- bounds3 bounds)
+ bounds3 bounds)
{
// Add the coord info to this picture.
if(t == identity4) {
@@ -638,7 +638,7 @@ struct picture { // <<<1
point.push(t,bounds.max,bounds.max,bounds.max);
}
}
-
+
// Scaling and Fit <<<2
// Returns the transform for turning user-space pairs into true-space pairs.
transform scaling(real xsize, real ysize, bool keepAspect=true,
@@ -660,9 +660,9 @@ struct picture { // <<<1
return identity(4);
coords3 Coords;
-
+
append(Coords,Coords,Coords,T3,bounds3);
-
+
real sx;
if(xunitsize == 0) {
if(xsize != 0) sx=calculateScaling("x",Coords.x,xsize,warn);
@@ -709,7 +709,7 @@ struct picture { // <<<1
triple m, triple M) {
frame f;
for(node3 n : nodes3) {
- xasyKEY(n.key);
+ xasyKEY(nodes3[0].key);
n.d(f,t,T0,pic,P,m,M);
}
return f;
@@ -757,7 +757,7 @@ struct picture { // <<<1
frame f=fit(fixedscaling);
pair d=size(f);
static real epsilon=100*realEpsilon;
- if(d.x > xsize*(1+epsilon))
+ if(d.x > xsize*(1+epsilon))
warning("xlimit","frame exceeds xlimit: "+(string) d.x+" > "+
(string) xsize);
if(d.y > ysize*(1+epsilon))
@@ -765,7 +765,7 @@ struct picture { // <<<1
(string) ysize);
return f;
}
-
+
// Calculate additional scaling required if only an approximate picture
// size estimate is available.
transform scale(frame f, real xsize=this.xsize, real ysize=this.ysize,
@@ -836,24 +836,24 @@ struct picture { // <<<1
bool keepAspect=this.keepAspect, bool warn=true) {
return min(calculateTransform(xsize,ysize,keepAspect,warn));
}
-
+
pair max(real xsize=this.xsize, real ysize=this.ysize,
bool keepAspect=this.keepAspect, bool warn=true) {
return max(calculateTransform(xsize,ysize,keepAspect,warn));
}
-
+
triple min3(real xsize=this.xsize3, real ysize=this.ysize3,
real zsize=this.zsize3, bool keepAspect=this.keepAspect,
bool warn=true, projection P) {
return min(calculateTransform3(xsize,ysize,zsize,keepAspect,warn,P));
}
-
+
triple max3(real xsize=this.xsize3, real ysize=this.ysize3,
real zsize=this.zsize3, bool keepAspect=this.keepAspect,
bool warn=true, projection P) {
return max(calculateTransform3(xsize,ysize,zsize,keepAspect,warn,P));
}
-
+
// More Fitting <<<2
// Returns the 2D picture fit to the requested size.
frame fit2(real xsize=this.xsize, real ysize=this.ysize,
@@ -880,7 +880,7 @@ struct picture { // <<<1
fitter(prefix,this,format,xsize,ysize,keepAspect,view,options,script,
light,P);
}
-
+
// Fit a 3D picture.
frame fit3(projection P=currentprojection) {
if(settings.render == 0) return fit(P);
@@ -895,7 +895,7 @@ struct picture { // <<<1
// In case only an approximate picture size estimate is available, return the
// fitted frame slightly scaled (including labels and true size distances)
- // so that it precisely meets the given size specification.
+ // so that it precisely meets the given size specification.
frame scale(real xsize=this.xsize, real ysize=this.ysize,
bool keepAspect=this.keepAspect) {
frame f=fit(xsize,ysize,keepAspect);
@@ -905,7 +905,7 @@ struct picture { // <<<1
}
// Copying <<<2
-
+
// Copies enough information to yield the same userMin/userMax.
void userCopy2(picture pic) {
userMinx2(pic.userMin2().x);
@@ -921,12 +921,12 @@ struct picture { // <<<1
usety=pic.usety;
usetz=pic.usetz;
}
-
+
void userCopy(picture pic) {
userCopy2(pic);
userCopy3(pic);
}
-
+
// Copies the drawing information, but not the sizing information into a new
// picture. Fitting this picture will not scale as the original picture would.
picture drawcopy() {
@@ -954,14 +954,14 @@ struct picture { // <<<1
dest.uptodate=uptodate;
dest.bounds=bounds.copy();
dest.bounds3=bounds3.copy();
-
+
dest.xsize=xsize; dest.ysize=ysize;
dest.xsize3=xsize; dest.ysize3=ysize3; dest.zsize3=zsize3;
dest.keepAspect=keepAspect;
dest.xunitsize=xunitsize; dest.yunitsize=yunitsize;
dest.zunitsize=zunitsize;
dest.fixed=fixed; dest.fixedscaling=fixedscaling;
-
+
return dest;
}
@@ -984,7 +984,7 @@ struct picture { // <<<1
dest.uptodate=uptodate;
dest.bounds=bounds.transformed(t);
dest.bounds3=bounds3.copy();
-
+
dest.bounds.exact=false;
dest.xsize=xsize; dest.ysize=ysize;
@@ -993,7 +993,7 @@ struct picture { // <<<1
dest.xunitsize=xunitsize; dest.yunitsize=yunitsize;
dest.zunitsize=zunitsize;
dest.fixed=fixed; dest.fixedscaling=fixedscaling;
-
+
return dest;
}
@@ -1007,7 +1007,7 @@ struct picture { // <<<1
// objects added to it that should not be included in this picture.
if(src == this) abort("cannot add picture to itself");
-
+
uptodate=false;
picture srcCopy=src.drawcopy();
@@ -1018,7 +1018,7 @@ struct picture { // <<<1
add(f,srcCopy.fit(t,T*srcCopy.T,m,M),group,filltype,above);
}));
}
-
+
if(srcCopy.nodes3.length > 0) {
nodes3.push(node3(new void(frame f, transform3 t, transform3 T3,
picture pic, projection P, triple m, triple M)
@@ -1026,13 +1026,13 @@ struct picture { // <<<1
add(f,srcCopy.fit3(t,T3*srcCopy.T3,pic,P,m,M),group,above);
}));
}
-
+
legend.append(src.legend);
-
+
if(src.usetx) userBoxX3(src.umin.x,src.umax.x);
if(src.usety) userBoxY3(src.umin.y,src.umax.y);
if(src.usetz) userBoxZ3(src.umin.z,src.umax.z);
-
+
bounds.append(srcCopy.T, src.bounds);
//append(bounds.point,bounds.min,bounds.max,srcCopy.T,src.bounds);
append(bounds3.point,bounds3.min,bounds3.max,srcCopy.T3,src.bounds3);
@@ -1087,7 +1087,7 @@ void size3(picture pic=currentpicture, real x, real y=x, real z=y,
pic.size3(x,y,z,keepAspect);
}
-void unitsize(picture pic=currentpicture, real x, real y=x, real z=y)
+void unitsize(picture pic=currentpicture, real x, real y=x, real z=y)
{
pic.unitsize(x,y,z);
}
@@ -1113,14 +1113,14 @@ pair min(picture pic, bool user=false)
pair z=pic.min(t);
return user ? inverse(t)*z : z;
}
-
+
pair max(picture pic, bool user=false)
{
transform t=pic.calculateTransform();
pair z=pic.max(t);
return user ? inverse(t)*z : z;
}
-
+
pair size(picture pic, bool user=false)
{
transform t=pic.calculateTransform();
@@ -1132,7 +1132,7 @@ pair size(picture pic, bool user=false)
}
// Frame Alignment <<<
-pair rectify(pair dir)
+pair rectify(pair dir)
{
real scale=max(abs(dir.x),abs(dir.y));
if(scale != 0) dir *= 0.5/scale;
@@ -1161,13 +1161,13 @@ path[] align(path[] g, transform t=identity(), pair position,
}
// Returns a transform for aligning frame f in the direction align
-transform shift(frame f, pair align)
+transform shift(frame f, pair align)
{
return shift(align-point(f,-align));
}
// Returns a copy of frame f aligned in the direction align
-frame align(frame f, pair align)
+frame align(frame f, pair align)
{
return shift(f,align)*f;
}
@@ -1448,7 +1448,7 @@ void clip(picture pic=currentpicture, path[] g, bool stroke=false,
}
void beginclip(picture pic=currentpicture, path[] g, bool stroke=false,
- pen fillrule=currentpen, bool copy=true)
+ pen fillrule=currentpen, bool copy=true)
{
if(copy)
g=copy(g);
@@ -1505,7 +1505,7 @@ void filloutside(picture pic=currentpicture, path[] g, pen p=currentpen,
pic.addPath(g);
}
-// Use a fixed scaling to map user coordinates in box(min,max) to the
+// Use a fixed scaling to map user coordinates in box(min,max) to the
// desired picture size.
transform fixedscaling(picture pic=currentpicture, pair min, pair max,
pen p=nullpen, bool warn=false)
@@ -1671,7 +1671,7 @@ void begin(picture pic=currentpicture, string name, string id="",
void end(picture pic=currentpicture)
{
if(!latex() || !pdf()) return;
- tex(pic,"\end{ocg}");
+ tex(pic,"\end{ocg}%");
layer(pic);
}
diff --git a/graphics/asymptote/base/plain_prethree.asy b/graphics/asymptote/base/plain_prethree.asy
index 968ae2943a..8866396255 100644
--- a/graphics/asymptote/base/plain_prethree.asy
+++ b/graphics/asymptote/base/plain_prethree.asy
@@ -76,7 +76,7 @@ struct projection {
bool center=false; // Center target within bounding volume?
int ninterpolate; // Used for projecting nurbs to 2D Bezier curves.
bool bboxonly=true; // Typeset label bounding box only.
-
+
transformation T;
void calculate() {
@@ -137,8 +137,8 @@ struct projection {
(M.x,m.y,m.z),(M.x,m.y,M.z),(M.x,M.y,m.z),M};
return max(abs(c-target));
}
-
-
+
+
// This is redefined here to make projection as self-contained as possible.
static private real sqrtEpsilon = sqrt(realEpsilon);
@@ -161,7 +161,7 @@ projection currentprojection;
struct light {
real[][] diffuse;
- real[][] specular;
+ real[][] specular; // For PRC only
pen background=nullpen; // Background color of the 3D canvas.
real specularfactor;
triple[] position; // Only directional lights are currently implemented.
@@ -169,14 +169,14 @@ struct light {
transform3 T=identity(4); // Transform to apply to normal vectors.
bool on() {return position.length > 0;}
-
+
void operator init(pen[] diffuse,
pen[] specular=diffuse, pen background=nullpen,
real specularfactor=1,
triple[] position) {
int n=diffuse.length;
assert(specular.length == n && position.length == n);
-
+
this.diffuse=new real[n][];
this.specular=new real[n][];
this.background=background;
@@ -213,4 +213,3 @@ struct light {
}
light currentlight;
-
diff --git a/graphics/asymptote/base/plain_scaling.asy b/graphics/asymptote/base/plain_scaling.asy
index 5bed3338e9..4c6beae655 100644
--- a/graphics/asymptote/base/plain_scaling.asy
+++ b/graphics/asymptote/base/plain_scaling.asy
@@ -19,7 +19,7 @@ struct coord {
coord copy() {
return build(user, truesize);
}
-
+
void clip(real min, real max) {
user=min(max(user,min),max);
truesize=0;
@@ -47,7 +47,7 @@ coord[] maxcoords(coord[] in, bool operator <= (coord,coord))
coord[] c;
int n=in.length;
-
+
if(n == 0)
return c;
@@ -151,15 +151,15 @@ struct coords2 {
}
}
void xclip(real min, real max) {
- for(int i=0; i < x.length; ++i)
+ for(int i=0; i < x.length; ++i)
x[i].clip(min,max);
}
void yclip(real min, real max) {
- for(int i=0; i < y.length; ++i)
+ for(int i=0; i < y.length; ++i)
y[i].clip(min,max);
}
}
-
+
// The scaling in one dimension: x --> a*x + b
struct scaling {
real a,b;
@@ -211,7 +211,7 @@ real calculateScaling(string dir, coord[] m, coord[] M, real size,
// (a*user + b) + truesize >= 0:
A.push(new real[] {c.user,1,-1});
b.push(-c.truesize);
- }
+ }
void addMaxCoord(coord c) {
// (a*user + b) + truesize <= size:
A.push(new real[] {-c.user,-1,1});
@@ -239,12 +239,12 @@ real calculateScaling(string dir, coord[] m, coord[] M, real size,
if(coord.user != 0) return false;
return true;
}
-
+
if((userzero(m) && userzero(M)) || size >= infinity) return 1;
-
+
warning("cannotfit","cannot fit picture to "+dir+"size "+(string) size
+"...enlarging...");
-
+
return calculateScaling(dir,m,M,expansionfactor*size,warn);
}
}
diff --git a/graphics/asymptote/base/plain_shipout.asy b/graphics/asymptote/base/plain_shipout.asy
index 388a03a557..fcc7f8e28a 100644
--- a/graphics/asymptote/base/plain_shipout.asy
+++ b/graphics/asymptote/base/plain_shipout.asy
@@ -11,7 +11,7 @@ string outprefix(string prefix=defaultfilename) {
return stripextension(prefix != "" ? prefix : outname());
}
-string outformat(string format="")
+string outformat(string format="")
{
if(format == "") format=settings.outformat;
if(format == "") format=nativeformat();
@@ -32,6 +32,10 @@ object embed3(string, frame, string, string, string, light, projection);
string Embed(string name, string text="", string options="", real width=0,
real height=0);
+bool primitive() { // Encode primitive objects
+ return settings.outformat == "html" || settings.outformat=="v3d";
+}
+
bool prconly(string format="")
{
return outformat(format) == "prc";
@@ -39,7 +43,7 @@ bool prconly(string format="")
bool prc0(string format="")
{
- return settings.prc && (outformat(format) == "pdf" || prconly() || settings.inlineimage );
+ return settings.outformat == "prc" || (settings.prc && (outformat(format) == "pdf" || prconly() || settings.inlineimage ));
}
bool prc(string format="") {
@@ -62,6 +66,14 @@ frame enclose(string prefix=defaultfilename, object F, string format="")
void deconstruct(picture pic=currentpicture)
{
+ if(currentpicture.nodes3.length > 0) {
+ if(currentpicture.xsize3 == 0 &&
+ currentpicture.ysize3 == 0 &&
+ currentpicture.zsize3 == 0)
+ currentpicture.size3(hypot(currentpicture.xsize,currentpicture.ysize));
+ currentpicture.size(0);
+ }
+
frame f;
transform t=pic.calculateTransform();
if(currentpicture.fitter == null)
@@ -95,7 +107,7 @@ void shipout(string prefix=defaultfilename, frame f,
}
return;
}
-
+
// Applications like LaTeX cannot handle large PostScript coordinates.
pair m=min(f);
int limit=2000;
diff --git a/graphics/asymptote/base/plain_strings.asy b/graphics/asymptote/base/plain_strings.asy
index a515861493..2e291f102f 100644
--- a/graphics/asymptote/base/plain_strings.asy
+++ b/graphics/asymptote/base/plain_strings.asy
@@ -49,13 +49,13 @@ triple gettriple(string name="", triple default=(0,0,0), string prompt="",
// returns a string with all occurrences of string 'before' in string 's'
// changed to string 'after'.
-string replace(string s, string before, string after)
+string replace(string s, string before, string after)
{
return replace(s,new string[][] {{before,after}});
}
// Like texify but don't convert embedded TeX commands: \${}
-string TeXify(string s)
+string TeXify(string s)
{
static string[][] t={{"&","\&"},{"%","\%"},{"_","\_"},{"#","\#"},{"<","$<$"},
{">","$>$"},{"|","$|$"},{"^","$\hat{\ }$"},
@@ -68,7 +68,7 @@ private string[][] trans1={{'\\',"\backslash "},
private string[][] trans2={{"\backslash ","$\backslash$"}};
// Convert string to TeX
-string texify(string s)
+string texify(string s)
{
return TeXify(replace(replace(s,trans1),trans2));
}
@@ -93,7 +93,7 @@ string[] split(string s, string delimiter="")
prune=true;
delimiter=" ";
}
-
+
string[] S;
int last=0;
int i;
@@ -130,7 +130,7 @@ string operator +(...string[] a)
return S;
}
-int system(string s)
+int system(string s)
{
return system(split(s));
}
@@ -161,8 +161,8 @@ string italic(string s)
return s != "" ? "{\it "+s+"}" : s;
}
-string baseline(string s, string template="\strut")
-{
+string baseline(string s, string template="\strut")
+{
return s != "" && settings.tex != "none" ? "\vphantom{"+template+"}"+s : s;
}
@@ -171,7 +171,7 @@ string math(string s)
return s != "" ? "$"+s+"$" : s;
}
-private void notimplemented(string text)
+private void notimplemented(string text)
{
abort(text+" is not implemented for the '"+settings.tex+"' TeX engine");
}
@@ -217,7 +217,7 @@ void usepackage(string s, string options="")
texpreamble(usepackage+"{"+s+"}");
}
-void pause(string w="Hit enter to continue")
+void pause(string w="Hit enter to continue")
{
write(w);
w=stdin;
diff --git a/graphics/asymptote/base/pstoedit.asy b/graphics/asymptote/base/pstoedit.asy
index 7baccd3ed6..8bd67e0911 100644
--- a/graphics/asymptote/base/pstoedit.asy
+++ b/graphics/asymptote/base/pstoedit.asy
@@ -15,4 +15,4 @@ void grestore(picture pic=currentpicture)
grestore(f);
},true);
}
-
+
diff --git a/graphics/asymptote/base/rational.asy b/graphics/asymptote/base/rational.asy
index a120c14123..aac3d5be9b 100644
--- a/graphics/asymptote/base/rational.asy
+++ b/graphics/asymptote/base/rational.asy
@@ -11,7 +11,7 @@ int gcd(int m, int n)
int r=m % n;
m=n;
n=r;
- }
+ }
return m;
}
diff --git a/graphics/asymptote/base/roundedpath.asy b/graphics/asymptote/base/roundedpath.asy
index 1a426f91dc..0029447327 100644
--- a/graphics/asymptote/base/roundedpath.asy
+++ b/graphics/asymptote/base/roundedpath.asy
@@ -1,7 +1,7 @@
// a function to round sharp edges of open and cyclic paths
// written by stefan knorr
-path roundedpath(path A, real R, real S = 1)
+path roundedpath(path A, real R, real S = 1)
// create rounded path from path A with radius R and scale S = 1
{
path RoundPath; // returned path
@@ -9,20 +9,20 @@ path roundedpath(path A, real R, real S = 1)
path LocalCirc; // local edge circle for intersection
real LocalTime; // local intersectiontime between . and ..
pair LocalPair; // local point to be added to 'RoundPath'
-
- int len=length(A); // length of given path 'A'
+
+ int len=length(A); // length of given path 'A'
bool PathClosed=cyclic(A); // true, if given path 'A' is cyclic
// initialisation: define first Point of 'RoundPath' as
if (PathClosed) // ? is 'A' cyclic
- RoundPath=scale(S)*point(point(A,0)--point(A,1), 0.5); // centerpoint of first straight subpath of 'A'
+ RoundPath=scale(S)*point(point(A,0)--point(A,1), 0.5); // centerpoint of first straight subpath of 'A'
else
RoundPath=scale(S)*point(A,0); // first point of 'A'
- // doing everything between start and end
- // create round paths subpath by subpath for every i-th edge
+ // doing everything between start and end
+ // create round paths subpath by subpath for every i-th edge
for(int i=1; i < len; ++i)
- {
+ {
// straight subpath towards i-th edge
LocalPath=point(A,i-1)---point(A,i);
// circle with radius 'R' around i-th edge
@@ -36,23 +36,23 @@ path roundedpath(path A, real R, real S = 1)
// add straight subpath towards i-th curvature to 'RoundPath'
RoundPath=RoundPath--scale(S)*LocalPair;
}
-
+
// straight subpath from i-th edge to (i+1)-th edge
LocalPath=point(A,i)---point(A,i+1);
// calculate intersection-time between straight subpath and circle
real[] t=intersect(LocalPath, LocalCirc);
if(t.length > 0) {
LocalTime=t[0];
- // define intersectionpoint between both paths
+ // define intersectionpoint between both paths
LocalPair=point(subpath(LocalPath, 0, LocalTime), 1);
// add curvature near i-th edge to 'RoundPath'
RoundPath=RoundPath..scale(S)*LocalPair;
}
- }
+ }
- // final steps to have a correct termination
+ // final steps to have a correct termination
if(PathClosed) { // Is 'A' cyclic?
- // straight subpath towards 0-th edge
+ // straight subpath towards 0-th edge
LocalPath=point(A,len-1)---point(A,0);
// circle with radius 'R' around 0-th edge
LocalCirc=circle(point(A,0),R);
@@ -65,15 +65,15 @@ path roundedpath(path A, real R, real S = 1)
// add straight subpath towards 0-th curvature to 'RoundPath'
RoundPath=RoundPath--scale(S)*LocalPair;
}
-
-
+
+
// straight subpath from 0-th edge to 1st edge
LocalPath=point(A,0)---point(A,1);
// calculate intersection-time between straight subpath and circle
real[] t=intersect(LocalPath, LocalCirc);
if(t.length > 0) {
LocalTime=t[0];
- // define intersectionpoint between both paths
+ // define intersectionpoint between both paths
LocalPair=point(subpath(LocalPath, 0, LocalTime), 1);
// add curvature near 0-th edge to 'RoundPath' and close path
RoundPath=RoundPath..scale(S)*LocalPair--cycle;
diff --git a/graphics/asymptote/base/shaders/blend.glsl b/graphics/asymptote/base/shaders/blend.glsl
new file mode 100644
index 0000000000..f3bd26c393
--- /dev/null
+++ b/graphics/asymptote/base/shaders/blend.glsl
@@ -0,0 +1,84 @@
+struct Fragment
+{
+ vec4 color;
+ float depth;
+};
+
+layout(binding=1, std430) buffer offsetBuffer {
+ uint offset[];
+};
+
+layout(binding=2, std430) buffer countBuffer {
+ uint count[];
+};
+
+layout(binding=3, std430) buffer fragmentBuffer {
+ Fragment fragment[];
+};
+
+out vec4 outColor;
+
+uniform uint width;
+uniform vec4 background;
+
+vec4 blend(vec4 outColor, vec4 color)
+{
+ return mix(outColor,color,color.a);
+}
+
+void main()
+{
+ uint headIndex=uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x);
+ uint size=count[headIndex];
+ if(size == 0u) {
+#ifdef GPUINDEXING
+ offset[headIndex]=0u;
+#endif
+ discard;
+ }
+ uint listIndex=offset[headIndex];
+ const uint maxSize=16u;
+
+ // Sort the fragments with respect to descending depth
+ if(size < maxSize) {
+ Fragment sortedList[maxSize];
+
+ sortedList[0]=fragment[listIndex];
+ for(uint i=1u; i < size; i++) {
+ Fragment temp=fragment[listIndex+i];
+ float depth=temp.depth;
+ uint j=i;
+ Fragment f;
+ while(f=sortedList[j-1u], j > 0u && depth > f.depth) {
+ sortedList[j]=f;
+ j--;
+ }
+ sortedList[j]=temp;
+ }
+
+ outColor=background;
+ for(uint i=0u; i < size; i++)
+ outColor=blend(outColor,sortedList[i].color);
+ } else {
+ for(uint i=1u; i < size; i++) {
+ Fragment temp=fragment[listIndex+i];
+ float depth=temp.depth;
+ uint j=i;
+ Fragment f;
+ while(f=fragment[listIndex+j-1u], j > 0u && depth > f.depth) {
+ fragment[listIndex+j]=f;
+ j--;
+ }
+ fragment[listIndex+j]=temp;
+ }
+
+ outColor=background;
+ uint stop=listIndex+size;
+ for(uint i=listIndex; i < stop; i++)
+ outColor=blend(outColor,fragment[i].color);
+ }
+ count[headIndex]=0u;
+#ifdef GPUINDEXING
+ offset[headIndex]=0u;
+#endif
+}
diff --git a/graphics/asymptote/base/shaders/count.glsl b/graphics/asymptote/base/shaders/count.glsl
new file mode 100644
index 0000000000..dae4e51f1b
--- /dev/null
+++ b/graphics/asymptote/base/shaders/count.glsl
@@ -0,0 +1,11 @@
+layout(binding=2, std430) buffer countBuffer {
+ uint count[];
+};
+
+uniform uint width;
+
+void main()
+{
+ atomicAdd(count[uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x)],1u);
+ discard;
+}
diff --git a/graphics/asymptote/base/shaders/count0.glsl b/graphics/asymptote/base/shaders/count0.glsl
new file mode 100644
index 0000000000..9bcb6d222e
--- /dev/null
+++ b/graphics/asymptote/base/shaders/count0.glsl
@@ -0,0 +1,11 @@
+layout(binding=2, std430) buffer countBuffer {
+ uint count[];
+};
+
+uniform uint width;
+
+void main()
+{
+ count[uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x)]=0u;
+ discard;
+}
diff --git a/graphics/asymptote/base/shaders/fragment.glsl b/graphics/asymptote/base/shaders/fragment.glsl
index 057acbc744..423ec679b2 100644
--- a/graphics/asymptote/base/shaders/fragment.glsl
+++ b/graphics/asymptote/base/shaders/fragment.glsl
@@ -10,25 +10,13 @@ struct Light
vec3 color;
};
-uniform int nlights;
+uniform uint nlights;
uniform Light lights[max(Nlights,1)];
uniform MaterialBuffer {
Material Materials[Nmaterials];
};
-#ifdef NORMAL
-#ifndef ORTHOGRAPHIC
-in vec3 ViewPosition;
-#endif
-in vec3 Normal;
-vec3 normal;
-#endif
-
-#ifdef COLOR
-in vec4 Color;
-#endif
-
flat in int materialIndex;
out vec4 outColor;
@@ -38,41 +26,94 @@ vec3 Specular; // Specular tint for nonmetals
float Metallic; // Metallic/Nonmetals parameter
float Fresnel0; // Fresnel at zero for nonmetals
float Roughness2; // roughness squared, for smoothing
+float Roughness;
-#ifdef ENABLE_TEXTURE
-uniform sampler2D environmentMap;
-const float PI=acos(-1.0);
-const float twopi=2*PI;
-const float halfpi=PI/2;
+#ifdef HAVE_SSBO
+struct Fragment
+{
+ vec4 color;
+ float depth;
+};
+
+layout(binding=1, std430) buffer offsetBuffer {
+ uint offset[];
+};
+
+layout(binding=2, std430) buffer countBuffer {
+ uint count[];
+};
+
+layout(binding=3, std430) buffer fragmentBuffer {
+ Fragment fragment[];
+};
+
+uniform uint width;
+#endif
+
+#ifdef NORMAL
+
+#ifndef ORTHOGRAPHIC
+in vec3 ViewPosition;
+#endif
+in vec3 Normal;
+vec3 normal;
-const int numSamples=7;
+#ifdef USE_IBL
+uniform sampler2D reflBRDFSampler;
+uniform sampler2D diffuseSampler;
+uniform sampler3D reflImgSampler;
+
+const float pi=acos(-1.0);
+const float piInv=1.0/pi;
+const float twopi=2.0*pi;
+const float twopiInv=1.0/twopi;
// (x,y,z) -> (r,theta,phi);
-// theta -> [0,\pi]: colatitude
-// phi -> [0, 2\pi]: longitude
+// theta -> [0,pi]: colatitude
+// phi -> [-pi,pi]: longitude
vec3 cart2sphere(vec3 cart)
{
- float x=cart.z;
- float y=cart.x;
+ float x=cart.x;
+ float y=cart.z;
float z=cart.y;
float r=length(cart);
+ float theta=r > 0.0 ? acos(z/r) : 0.0;
float phi=atan(y,x);
- float theta=acos(z/r);
- return vec3(r,phi,theta);
+ return vec3(r,theta,phi);
}
vec2 normalizedAngle(vec3 cartVec)
{
vec3 sphericalVec=cart2sphere(cartVec);
- sphericalVec.y=sphericalVec.y/(2*PI)-0.25;
- sphericalVec.z=sphericalVec.z/PI;
- return sphericalVec.yz;
+ sphericalVec.y=sphericalVec.y*piInv;
+ sphericalVec.z=0.75-sphericalVec.z*twopiInv;
+
+ return sphericalVec.zy;
}
-#endif
-#ifdef NORMAL
+vec3 IBLColor(vec3 viewDir)
+{
+ //
+ // based on the split sum formula approximation
+ // L(v)=\int_\Omega L(l)f(l,v) \cos \theta_l
+ // which, by the split sum approiximation (assuming independence+GGX distrubition),
+ // roughly equals (within a margin of error)
+ // [\int_\Omega L(l)] * [\int_\Omega f(l,v) \cos \theta_l].
+ // the first term is the reflectance irradiance integral
+
+ vec3 IBLDiffuse=Diffuse*texture(diffuseSampler,normalizedAngle(normal)).rgb;
+ vec3 reflectVec=normalize(reflect(-viewDir,normal));
+ vec2 reflCoord=normalizedAngle(reflectVec);
+ vec3 IBLRefl=texture(reflImgSampler,vec3(reflCoord,Roughness)).rgb;
+ vec2 IBLbrdf=texture(reflBRDFSampler,vec2(dot(normal,viewDir),Roughness)).rg;
+ float specularMultiplier=Fresnel0*IBLbrdf.x+IBLbrdf.y;
+ vec3 dielectric=IBLDiffuse+specularMultiplier*IBLRefl;
+ vec3 metal=Diffuse*IBLRefl;
+ return mix(dielectric,metal,Metallic);
+}
+#else
// h is the halfway vector between normal and light direction
// GGX Trowbridge-Reitz Approximation
float NDF_TRG(vec3 h)
@@ -122,18 +163,24 @@ vec3 BRDF(vec3 viewDirection, vec3 lightDirection)
vec3 dielectric=mix(lambertian,rawReflectance*Specular,F);
vec3 metal=rawReflectance*Diffuse;
-
+
return mix(dielectric,metal,Metallic);
}
#endif
+#endif
+
+#ifdef COLOR
+in vec4 Color;
+#endif
+
void main()
{
vec4 diffuse;
vec4 emissive;
Material m;
-#ifdef TRANSPARENT
+#ifdef GENERAL
m=Materials[abs(materialIndex)-1];
emissive=m.emissive;
if(materialIndex >= 0)
@@ -150,18 +197,18 @@ void main()
#ifdef COLOR
diffuse=Color;
#if Nlights == 0
- emissive += Color;
+ emissive += Color;
#endif
-#else
- diffuse=m.diffuse;
+#else
+ diffuse=m.diffuse;
#endif
#endif
-
+
#if defined(NORMAL) && Nlights > 0
Specular=m.specular.rgb;
vec4 parameters=m.parameters;
- Roughness2=1.0-parameters[0];
- Roughness2=Roughness2*Roughness2;
+ Roughness=1.0-parameters[0];
+ Roughness2=Roughness*Roughness;
Metallic=parameters[1];
Fresnel0=parameters[2];
Diffuse=diffuse.rgb;
@@ -178,50 +225,34 @@ void main()
#else
vec3 viewDir=-normalize(ViewPosition);
#endif
+ vec3 color;
+#ifdef USE_IBL
+ color=IBLColor(viewDir);
+#else
// For a finite point light, the rendering equation simplifies.
- vec3 color=emissive.rgb;
- for(int i=0; i < nlights; ++i) {
+ color=emissive.rgb;
+ for(uint i=0u; i < nlights; ++i) {
Light Li=lights[i];
vec3 L=Li.direction;
float cosTheta=max(dot(normal,L),0.0); // $\omega_i \cdot n$ term
vec3 radiance=cosTheta*Li.color;
color += BRDF(viewDir,L)*radiance;
}
-
-#if defined(ENABLE_TEXTURE) && !defined(COLOR)
- // Experimental environment radiance using Riemann sums;
- // can also do importance sampling.
- vec3 envRadiance=vec3(0.0,0.0,0.0);
-
- vec3 normalPerp=vec3(-normal.y,normal.x,0.0);
- if(length(normalPerp) == 0.0)
- normalPerp=vec3(1.0,0.0,0.0);
-
- // we now have a normal basis;
- normalPerp=normalize(normalPerp);
- vec3 normalPerp2=normalize(cross(normal,normalPerp));
-
- const float step=1.0/numSamples;
- const float phistep=twopi*step;
- const float thetastep=halfpi*step;
- for (int iphi=0; iphi < numSamples; ++iphi) {
- float phi=iphi*phistep;
- for (int itheta=0; itheta < numSamples; ++itheta) {
- float theta=itheta*thetastep;
-
- vec3 azimuth=cos(phi)*normalPerp+sin(phi)*normalPerp2;
- vec3 L=sin(theta)*azimuth+cos(theta)*normal;
-
- vec3 rawRadiance=texture(environmentMap,normalizedAngle(L)).rgb;
- vec3 surfRefl=BRDF(Z,L);
- envRadiance += surfRefl*rawRadiance*sin(2.0*theta);
- }
- }
- envRadiance *= halfpi*step*step;
- color += envRadiance.rgb;
#endif
outColor=vec4(color,diffuse.a);
-#else
+#else
outColor=emissive;
-#endif
+#endif
+
+#ifdef HAVE_SSBO
+ uint headIndex=uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x);
+ uint listIndex=offset[headIndex]+atomicAdd(count[headIndex],1u);
+ fragment[listIndex].color=outColor;
+ fragment[listIndex].depth=gl_FragCoord.z;
+#ifdef TRANSPARENT
+#ifndef WIREFRAME
+ discard;
+#endif
+#endif
+#endif
}
diff --git a/graphics/asymptote/base/shaders/offset.glsl b/graphics/asymptote/base/shaders/offset.glsl
new file mode 100644
index 0000000000..5fe24e7558
--- /dev/null
+++ b/graphics/asymptote/base/shaders/offset.glsl
@@ -0,0 +1,11 @@
+layout(binding=1, std430) buffer offsetBuffer {
+ uint offset[];
+};
+
+uniform uint width;
+
+void main()
+{
+ atomicAdd(offset[uint(gl_FragCoord.y)*width+uint(gl_FragCoord.x)+1u],1u);
+ discard;
+}
diff --git a/graphics/asymptote/base/shaders/partialsum.glsl b/graphics/asymptote/base/shaders/partialsum.glsl
new file mode 100644
index 0000000000..0506965c23
--- /dev/null
+++ b/graphics/asymptote/base/shaders/partialsum.glsl
@@ -0,0 +1,54 @@
+layout(local_size_x=PROCESSORS) in;
+
+uniform uint elements;
+uniform uint steps;
+
+layout(binding=0, std430) buffer sumBuffer
+{
+ uint sum[];
+};
+
+layout(binding=1, std430) buffer offsetBuffer
+{
+ uint offset[];
+};
+
+shared uint sharedData[PROCESSORS];
+
+uint ceilquotient(uint a, uint b)
+{
+ return (a+b-1u)/b;
+}
+
+void main(void)
+{
+ uint id=gl_LocalInvocationID.x;
+ sharedData[id]=sum[id];
+
+ barrier();
+
+ uint index=id << 1u;
+ sharedData[index+1u] += sharedData[index];
+ barrier();
+ uint step;
+ for(step=1u; step < steps-1u; step++) {
+ uint mask=(1u << step)-1u;
+ uint index=((id >> step) << (step+1u))+mask;
+ uint windex=index+(id&mask)+1u;
+ sharedData[windex] += sharedData[index];
+ barrier();
+ }
+ uint mask=(1u << step)-1u;
+ index=((id >> step) << steps)+mask;
+ uint windex=index+(id&mask)+1u;
+ if(windex < PROCESSORS)
+ sharedData[windex] += sharedData[index];
+ barrier();
+
+ uint m=ceilquotient(elements,PROCESSORS);
+
+ if(id+1u < PROCESSORS)
+ offset[m*(id+1u)] += sharedData[id];
+ else
+ sum[0]=sharedData[id]; // Store fragment size in sum[0]
+}
diff --git a/graphics/asymptote/base/shaders/postsum.glsl b/graphics/asymptote/base/shaders/postsum.glsl
new file mode 100644
index 0000000000..9a2afaf845
--- /dev/null
+++ b/graphics/asymptote/base/shaders/postsum.glsl
@@ -0,0 +1,30 @@
+layout(local_size_x=1) in;
+
+uniform uint elements;
+
+layout(binding=1, std430) buffer offsetBuffer
+{
+ uint offset[];
+};
+
+uint ceilquotient(uint a, uint b)
+{
+ return (a+b-1u)/b;
+}
+
+void main(void)
+{
+ uint id=gl_GlobalInvocationID.x;
+
+ uint m=ceilquotient(elements,gl_NumWorkGroups.x);
+ uint row=m*id;
+ uint col=min(m,elements-row);
+ uint stop=row+col-1u;
+
+ uint curr=offset[row];
+ for(uint i=row; i < stop; ++i) {
+ uint next=offset[i+1u];
+ curr += next;
+ offset[i+1u]=curr;
+ }
+}
diff --git a/graphics/asymptote/base/shaders/presum.glsl b/graphics/asymptote/base/shaders/presum.glsl
new file mode 100644
index 0000000000..0bcb02c91d
--- /dev/null
+++ b/graphics/asymptote/base/shaders/presum.glsl
@@ -0,0 +1,34 @@
+layout(local_size_x=1) in;
+
+uniform uint elements;
+
+layout(binding=0, std430) buffer sumBuffer
+{
+ uint sum[];
+};
+
+layout(binding=1, std430) buffer offsetBuffer
+{
+ uint offset[];
+};
+
+uint ceilquotient(uint a, uint b)
+{
+ return (a+b-1u)/b;
+}
+
+void main(void)
+{
+ uint id=gl_GlobalInvocationID.x;
+
+ uint m=ceilquotient(elements,gl_NumWorkGroups.x);
+ uint row=m*id;
+ uint col=min(m,elements-row);
+ uint stop=row+col;
+
+ uint Sum=offset[row];
+ for(uint i=row+1u; i < stop; ++i)
+ Sum += offset[i];
+
+ sum[id]=Sum;
+}
diff --git a/graphics/asymptote/base/shaders/screen.glsl b/graphics/asymptote/base/shaders/screen.glsl
new file mode 100644
index 0000000000..9e8611a727
--- /dev/null
+++ b/graphics/asymptote/base/shaders/screen.glsl
@@ -0,0 +1,5 @@
+void main()
+{
+ vec2 vertices[3]=vec2[3](vec2(-1,-1),vec2(3,-1),vec2(-1, 3));
+ gl_Position = vec4(vertices[gl_VertexID],0,1);
+}
diff --git a/graphics/asymptote/base/shaders/vertex.glsl b/graphics/asymptote/base/shaders/vertex.glsl
index 4b2a54b989..42623ccef6 100644
--- a/graphics/asymptote/base/shaders/vertex.glsl
+++ b/graphics/asymptote/base/shaders/vertex.glsl
@@ -1,16 +1,22 @@
in vec3 position;
-uniform mat3 normMat;
-
#ifdef NORMAL
+
#ifndef ORTHOGRAPHIC
+uniform mat4 viewMat;
out vec3 ViewPosition;
#endif
+
+uniform mat3 normMat;
in vec3 normal;
out vec3 Normal;
+
#endif
+#ifdef MATERIAL
in int material;
+flat out int materialIndex;
+#endif
#ifdef COLOR
in vec4 color;
@@ -22,9 +28,6 @@ in float width;
#endif
uniform mat4 projViewMat;
-uniform mat4 viewMat;
-
-flat out int materialIndex;
void main()
{
@@ -45,5 +48,7 @@ void main()
gl_PointSize=width;
#endif
+#ifdef MATERIAL
materialIndex=material;
+#endif
}
diff --git a/graphics/asymptote/base/simplex.asy b/graphics/asymptote/base/simplex.asy
index e6d0410b23..3bc74635db 100644
--- a/graphics/asymptote/base/simplex.asy
+++ b/graphics/asymptote/base/simplex.asy
@@ -219,7 +219,7 @@ struct simplex {
basicValues();
iterate(E,n+k,Bindices);
-
+
if(abs(Em[0]) > EpsilonA) {
case=INFEASIBLE;
return;
@@ -249,7 +249,7 @@ struct simplex {
for(int i=0; i < m; ++i) {
int k=Bindices[i];
if(k > n) continue;
- Bindices[ip]=k;
+ Bindices[ip]=k;
cB[ip]=c[k-1];
real[] Dip=D[ip];
real[] Ei=E[i];
@@ -319,7 +319,7 @@ struct simplex {
ai[j]=Ai[j];
}
}
-
+
int k=0;
bool phase1=false;
diff --git a/graphics/asymptote/base/slide.asy b/graphics/asymptote/base/slide.asy
index 9d26c68065..a695953768 100644
--- a/graphics/asymptote/base/slide.asy
+++ b/graphics/asymptote/base/slide.asy
@@ -32,7 +32,7 @@ real minipagemargin=1inch;
real minipagewidth=pagewidth-2minipagemargin;
transform tinv=inverse(fixedscaling((-1,-1),(1,1),currentpen));
-
+
pen itempen=fontsize(24pt);
pen codepen=fontsize(20pt);
pen titlepagepen=fontsize(36pt);
@@ -55,7 +55,7 @@ real titleskip=0.5;
string oldbulletcolor;
string newbulletcolor="red";
string bullet="{\bulletcolor\textbullet}";
-
+
pair pagenumberposition=S+E;
pair pagenumberalign=4NW;
pen pagenumberpen=fontsize(12);
@@ -90,7 +90,7 @@ bool empty()
return currentpicture.nodes.length <= preamblenodes;
}
-void background()
+void background()
{
if(!background.empty()) {
add(background);
@@ -197,7 +197,7 @@ void nextpage(pen p=pagenumberpen)
firststep=true;
}
-void newslide(bool stepping=true)
+void newslide(bool stepping=true)
{
allowstepping=stepping;
nextpage();
@@ -264,11 +264,11 @@ void outline(string s="Outline", pair position=N, pair align=titlealign,
void remark(bool center=false, string s, pair align=0, pen p=itempen,
real indent=0, bool minipage=true, real skip=itemskip,
- filltype filltype=NoFill, bool step=false)
+ filltype filltype=NoFill, bool step=false)
{
checkposition();
if(minipage) s=minipage(s,minipagewidth);
-
+
pair offset;
if(center) {
if(align == 0) align=S;
@@ -277,12 +277,12 @@ void remark(bool center=false, string s, pair align=0, pen p=itempen,
if(align == 0) align=SE;
offset=currentposition;
}
-
+
frame f;
label(f,s,(indent,0),align,p,filltype);
pair m=tinv*min(f);
pair M=tinv*min(f);
-
+
if(abs(offset.x+M.x) > 1)
warning("slidetoowide","slide too wide on page "+(string) page+':\n'+
(string) s);
@@ -399,7 +399,7 @@ void display(string s, string caption="", pair align=S, pen p=itempen,
display(new string[] {s},caption,align,p,figuremattpen, final);
}
-void figure(string[] s, string options="", real margin=0,
+void figure(string[] s, string options="", real margin=0,
string[] captions=new string[], string caption="",
pair align=S, pen p=itempen, pen figuremattpen=figuremattpen,
bool final=true)
@@ -435,7 +435,7 @@ void multifigure(string[] slist, string options="", string caption="",
firststep=false;
}
-void indexedfigure(string prefix, int first, int last,
+void indexedfigure(string prefix, int first, int last,
string options="", string caption="",
pair align=S, pen p=itempen, pen figuremattpen=figuremattpen,
bool step=itemstep)
@@ -473,7 +473,7 @@ string cropcode(string s)
void code(bool center=false, string s, pen p=codepen,
real indent=0, real skip=codeskip,
- filltype filltype=NoFill)
+ filltype filltype=NoFill)
{
remark(center,"{\tt "+verbatim(cropcode(s))+"}",p,indent,skip,filltype);
}
@@ -569,7 +569,7 @@ void bibliographystyle(string name)
texpreamble("\bibliographystyle{"+name+"}");
}
-void bibliography(string name)
+void bibliography(string name)
{
numberpage();
havepagenumber=false;
diff --git a/graphics/asymptote/base/slopefield.asy b/graphics/asymptote/base/slopefield.asy
index e87e2cd36f..c36ee4d9d0 100644
--- a/graphics/asymptote/base/slopefield.asy
+++ b/graphics/asymptote/base/slopefield.asy
@@ -16,7 +16,7 @@ picture slopefield(real f(real,real), pair a, pair b,
pair cp=(x,a.y+j*dy);
real slope=f(cp.x,cp.y);
real mp=step/sqrt(1+slope^2);
- draw(pic,(cp.x-mp,cp.y-mp*slope)--(cp.x+mp,cp.y+mp*slope),p,arrow);
+ draw(pic,(cp.x-mp,cp.y-mp*slope)--(cp.x+mp,cp.y+mp*slope),p,arrow);
}
}
return pic;
@@ -29,12 +29,12 @@ picture slopefield(real f(real), pair a, pair b,
return slopefield(new real(real x, real y) {return f(x);},a,b,nx,ny,p,arrow);
}
-path curve(pair c, real f(real,real), pair a, pair b)
+path curve(pair c, real f(real,real), pair a, pair b)
{
- real step=stepfraction*(b.x-a.x);
+ real step=stepfraction*(b.x-a.x);
real halfstep=0.5*step;
real sixthstep=step/6;
-
+
path follow(real sign) {
pair cp=c;
guide g=cp;
diff --git a/graphics/asymptote/base/smoothcontour3.asy b/graphics/asymptote/base/smoothcontour3.asy
index be6f900a4d..c39d0a3f3d 100644
--- a/graphics/asymptote/base/smoothcontour3.asy
+++ b/graphics/asymptote/base/smoothcontour3.asy
@@ -1,11 +1,11 @@
// Copyright 2015 Charles Staats III
-//
+//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
-//
+//
// http://www.apache.org/licenses/LICENSE-2.0
-//
+//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -72,7 +72,7 @@ patch patchwithnormals(path3 external, triple[] u0normals, triple[] u1normals,
assert(u1normals.length == 3);
assert(v0normals.length == 3);
assert(v1normals.length == 3);
-
+
triple[][] controlpoints = new triple[4][4];
controlpoints[0][0] = point(external,0);
controlpoints[1][0] = postcontrol(external,0);
@@ -217,7 +217,7 @@ patch patchwithnormals(path3 external, triple[] u0normals, triple[] u1normals,
+ "on bezier patch. Using coons patch.");
return patch(external);
}
-
+
for (int i = 1; i <= 2; ++i) {
for (int j = 1; j <= 2; ++j) {
int position = 3 * (2 * (i-1) + (j-1));
@@ -268,7 +268,7 @@ patch trianglewithnormals(path3 external, triple n1,
tangent = dir(external, 2.5);
n3 -= dot(n3,tangent)*tangent;
n3 = unit(n3);
-
+
real wild = 2 * wildnessweight;
real[][] matrix = { {n1.x, n1.y, n1.z},
{n2.x, n2.y, n2.z},
@@ -591,7 +591,7 @@ triple projecttospan(triple toproject, triple v1, triple v2,
path3 pathbetween(path3 edgecycle, int vertex1, int vertex2) {
triple point1 = point(edgecycle, vertex1);
triple point2 = point(edgecycle, vertex2);
-
+
triple v1 = -dir(edgecycle, vertex1, sign=-1);
triple v2 = dir(edgecycle, vertex1, sign= 1);
triple direction1 = projecttospan(unit(point2-point1), v1, v2);
@@ -802,7 +802,7 @@ patch[] triangletoquads(path3 external, real f(triple), triple grad(triple),
return new patch[] {patchwithnormals(quad0, grad),
patchwithnormals(quad1, grad),
- patchwithnormals(quad2, grad)};
+ patchwithnormals(quad2, grad)};
}
// Attempts to fill the path external (which should by a cyclic path consisting of
@@ -837,7 +837,7 @@ patch[] maketriangle(path3 external, real f(triple),
return new patch[] {beziertriangle};
if (!allowsubdivide) return new patch[0];
-
+
positionedvector m1 = positionedvector(m1, n1);
positionedvector m2 = positionedvector(m2, n2);
positionedvector m3 = positionedvector(m3, n3);
@@ -855,7 +855,7 @@ patch[] maketriangle(path3 external, real f(triple),
triangles.append(maketriangle(subpath(external, 0.5, 1.5) & reverse(p12) & cycle,
f, grad=grad, allowsubdivide=false));
if (triangles.length < 3) return new patch[0];
-
+
triangles.append(maketriangle(subpath(external, 1.5, 2.5) & reverse(p23) & cycle,
f, grad=grad, allowsubdivide=false));
if (triangles.length < 4) return new patch[0];
@@ -913,7 +913,7 @@ patch[] quadpatches(path3 edgecycle, positionedvector[] corners,
// The tolerance for considering two points "essentially identical."
static real tolerance = 2.5 * rootfinder_settings.roottolerance;
-
+
// If there are two neighboring vertices that are essentially identical,
// unify them into one.
for (int i = 0; i < corners.length; ++i) {
@@ -948,7 +948,7 @@ patch[] quadpatches(path3 edgecycle, positionedvector[] corners,
return null;
}
}
-
+
if (length(edgecycle) == 3) {
patch[] toreturn = usetriangles ? maketriangle(edgecycle, f, grad)
: triangletoquads(edgecycle, f, grad, a, b);
@@ -961,12 +961,12 @@ patch[] quadpatches(path3 edgecycle, positionedvector[] corners,
int[] bisectorindices;
path3 middleguide = bisector(edgecycle, bisectorindices);
-
+
triple testpoint = point(middleguide, 0.5);
if (!checkpt(testpoint, f, grad, a, b)) {
return null;
}
-
+
patch[] toreturn = null;
path3 firstpatch = subpath(edgecycle, bisectorindices[0], bisectorindices[1])
& reverse(middleguide) & cycle;
@@ -1328,7 +1328,7 @@ struct gridwithzeros {
}
return null;
}
-
+
currentface = XLOW;
nextface = YHIGH;
pushifnonnull(zdirzeros[0][1][0]);
@@ -1393,12 +1393,12 @@ struct gridwithzeros {
if (!checkpt(testpoint, f, grad, corners[0][0][0], corners[1][1][1])) {
return subdividecube();
}
-
+
edgecycle = edgecycle & currentpath;
}
edgecycle = edgecycle & cycle;
-
+
{ // Ensure the outward normals are pointing in the same direction as the gradient.
triple tangentin = patchcorners[0].position - precontrol(edgecycle, 0);
triple tangentout = postcontrol(edgecycle, 0) - patchcorners[0].position;
@@ -1482,7 +1482,7 @@ struct gridwithzeros {
if (k >= nz) reportactive[ZHIGH] = true;
}
}
-
+
for (int i = 0; i < nx+1; ++i) {
for (int j = 0; j < ny+1; ++j) {
for (int k = 0; k < nz+1; ++k) {
@@ -1532,7 +1532,7 @@ struct gridwithzeros {
};
}
-// The external interface of this whole module. Accepts exactly one
+// The external interface of this whole module. Accepts exactly one
// function (throws an error if two or zero functions are specified).
// The function should be differentiable. (Whatever you do, do not
// pass in an indicator function!) Ideally, the zero locus of the
diff --git a/graphics/asymptote/base/solids.asy b/graphics/asymptote/base/solids.asy
index 72110d6f7a..035a00d2fc 100644
--- a/graphics/asymptote/base/solids.asy
+++ b/graphics/asymptote/base/solids.asy
@@ -5,11 +5,11 @@ pen defaultbackpen=linetype(new real[] {4,4},4,scale=false);
// A solid geometry package.
// Try to find a bounding tangent line between two paths.
-real[] tangent(path p, path q, bool side)
+real[] tangent(path p, path q, bool side)
{
static real fuzz=1.0e-5;
- if((cyclic(p) && inside(p,point(q,0)) ||
+ if((cyclic(p) && inside(p,point(q,0)) ||
cyclic(q) && inside(q,point(p,0))) &&
intersect(p,q,fuzz).length == 0) return new real[];
@@ -28,14 +28,14 @@ real[] tangent(path p, path q, bool side)
return new real[];
}
-path line(path p, path q, real[] t)
+path line(path p, path q, real[] t)
{
return point(p,t[0])--point(q,t[1]);
}
// Return the projection of a generalized cylinder of height h constructed
// from area base in the XY plane and aligned with axis.
-path[] cylinder(path3 base, real h, triple axis=Z, projection P)
+path[] cylinder(path3 base, real h, triple axis=Z, projection P)
{
base=rotate(-colatitude(axis),cross(axis,Z))*base;
path3 top=shift(h*axis)*base;
@@ -71,7 +71,7 @@ struct revolution {
triple m;
static real epsilon=10*sqrtEpsilon;
-
+
void operator init(triple c=O, path3 g, triple axis=Z, real angle1=0,
real angle2=360) {
this.c=c;
@@ -82,12 +82,12 @@ struct revolution {
M=max(g);
m=min(g);
}
-
+
revolution copy() {
return revolution(c,g,axis,angle1,angle2);
}
-
+
triple vertex(int i, real j) {
triple v=point(g,i);
triple center=c+dot(v-c,axis)*axis;
@@ -114,7 +114,7 @@ struct revolution {
path3 p=Arc(center,v1,v2,axis,n);
return (angle2-angle1) % 360 == 0 ? p&cycle : p;
}
-
+
// add transverse slice to skeleton s;
void transverse(skeleton s, real t, int n=nslice, projection P) {
skeleton.curve s=s.transverse;
@@ -196,7 +196,7 @@ struct revolution {
int M=(m == 0) ? N : m;
real factor=m == 1 ? 0 : 1/(m-1);
int n=nslice;
-
+
real tfirst=-1;
real tlast;
for(int i=0; i < M; ++i) {
@@ -238,7 +238,7 @@ struct revolution {
G=sfirst.transverse.back[0]..G;
}
}
-
+
skeleton slast;
transverse(slast,tlast,n,P);
if(dot(delta,axis) == 0 || (tlast >= L-epsilon && sign > 0)) {
@@ -287,7 +287,7 @@ struct revolution {
path3 p1=subpath(p,0,t);
path3 p2=subpath(p,t,length(p));
if(length(p1) > 0 &&
- (length(p2) == 0 ||
+ (length(p2) == 0 ||
abs(midpoint(p1)-P.camera) <= abs(midpoint(p2)-P.camera))) {
s.longitudinal.front.push(p1);
s.longitudinal.back.push(p2);
@@ -300,7 +300,7 @@ struct revolution {
push(t1);
push(t2);
}
-
+
skeleton skeleton(int m=0, int n=nslice, projection P) {
skeleton s;
transverse(s,m,n,P);
diff --git a/graphics/asymptote/base/stats.asy b/graphics/asymptote/base/stats.asy
index be9efdfa42..6183fc18df 100644
--- a/graphics/asymptote/base/stats.asy
+++ b/graphics/asymptote/base/stats.asy
@@ -287,6 +287,6 @@ linefit leastsquares(real[] x, real[] y)
real s=sqrt(arg/(n-2));
L.dm=s*sqrt(1/sxx);
L.db=s*sqrt(1+sx^2/sxx)/n;
- }
+ }
return L;
}
diff --git a/graphics/asymptote/base/syzygy.asy b/graphics/asymptote/base/syzygy.asy
index 93889b252e..3cef2b3a75 100644
--- a/graphics/asymptote/base/syzygy.asy
+++ b/graphics/asymptote/base/syzygy.asy
@@ -78,7 +78,7 @@ bp.draw=new guide[] (picture pic, guide[] ins) {
return new guide[] {(centre+offset*NW){NW}..z[0]+h*N,
ins[0]..centre{NE}..z[1]+h*N};
};
-
+
Component bm=new Component;
bm.in=2; bm.out=2;
bm.connections=new int[] {1,0};
@@ -99,7 +99,7 @@ bm.draw=new guide[] (picture pic, guide[] ins) {
return new guide[] {ins[1]..centre{NW}..z[0]+h*N,
(centre+offset*NE){NE}..z[1]+h*N};
};
-
+
Component phi=new Component;
phi.in=2; phi.out=1;
phi.connections=new int[] {0,0};
@@ -442,7 +442,7 @@ struct Braid { // {{{1
p.place + p.c.in <= place ? 0 : // The string doesn't touch it.
place-p.place+2;*/
}
-
+
int[] pullbackWindow(int step, int w_place, int w_size) {
int[] a={1};
for (int place=0; place<n; ++place)
@@ -735,7 +735,7 @@ struct Syzygy { // {{{1
bool showall=false;
bool number=false; // Number the diagrams when drawn.
- string lsym, codename;
+ string lsym, codename;
bool watched=false;
bool uptodate=true;
diff --git a/graphics/asymptote/base/three.asy b/graphics/asymptote/base/three.asy
index 5fc0d2f109..fbca4b3960 100644
--- a/graphics/asymptote/base/three.asy
+++ b/graphics/asymptote/base/three.asy
@@ -1,8 +1,5 @@
private import math;
-if(settings.xasy)
- settings.render=0;
-
if(prc0()) {
if(!latex()) settings.prc=false;
else {
@@ -11,8 +8,9 @@ if(prc0()) {
}
}
-// Useful lossy compression values.
+// Useful lossy PRC compression values.
restricted real Zero=0;
+restricted real Single=0.000001;
restricted real Low=0.0001;
restricted real Medium=0.001;
restricted real High=0.01;
@@ -20,6 +18,27 @@ restricted real High=0.01;
restricted int PRCsphere=0; // Renders slowly but produces smaller PRC files.
restricted int NURBSsphere=1; // Renders fast but produces larger PRC files.
+struct interaction
+{
+ int type;
+ triple center; // position to rotate billboard objects about
+ bool targetsize;
+ static interaction defaultinteraction;
+
+ void operator init(interaction interaction=defaultinteraction,
+ int type=interaction.type,
+ triple center=interaction.center, bool targetsize=interaction.targetsize) {
+ this.type=type;
+ this.center=center;
+ this.targetsize=targetsize;
+ }
+}
+
+interaction.defaultinteraction=new interaction;
+
+restricted interaction Embedded=interaction();
+restricted interaction Billboard=interaction(1);
+
struct render
{
// PRC parameters:
@@ -41,19 +60,22 @@ struct render
bool partnames; // assign part name indices to compound objects
bool defaultnames; // assign default names to unnamed objects
+ interaction interaction; // billboard interaction mode
static render defaultrender;
-
- void operator init(real compression=defaultrender.compression,
- real granularity=defaultrender.granularity,
- bool closed=defaultrender.closed,
- bool tessellate=defaultrender.tessellate,
- bool3 merge=defaultrender.merge,
- int sphere=defaultrender.sphere,
- real margin=defaultrender.margin,
- bool labelfill=defaultrender.labelfill,
- bool partnames=defaultrender.partnames,
- bool defaultnames=defaultrender.defaultnames)
+
+ void operator init(render render=defaultrender,
+ real compression=render.compression,
+ real granularity=render.granularity,
+ bool closed=render.closed,
+ bool tessellate=render.tessellate,
+ bool3 merge=render.merge,
+ int sphere=render.sphere,
+ real margin=render.margin,
+ bool labelfill=render.labelfill,
+ bool partnames=render.partnames,
+ bool defaultnames=render.defaultnames,
+ interaction interaction=render.interaction)
{
this.compression=compression;
this.granularity=granularity;
@@ -65,6 +87,7 @@ struct render
this.labelfill=labelfill;
this.partnames=partnames;
this.defaultnames=defaultnames;
+ this.interaction=interaction;
}
}
@@ -81,6 +104,7 @@ defaultrender.sphere=NURBSsphere;
defaultrender.labelfill=true;
defaultrender.partnames=false;
defaultrender.defaultnames=true;
+defaultrender.interaction=Embedded;
real defaultshininess=0.7;
real defaultmetallic=0.0;
@@ -95,7 +119,7 @@ string defaultembed3Doptions="3Dmenu";
string defaultembed3Dscript;
real defaulteyetoview=63mm/1000mm;
-string partname(int i, render render=defaultrender)
+string partname(int i, render render=defaultrender)
{
return render.partnames ? string(i+1) : "";
}
@@ -158,8 +182,8 @@ transform3 scale(triple v, real s)
v=unit(v);
s -= 1;
return new real[][] {
- {1+s*v.x^2, s*v.x*v.y, s*v.x*v.z, 0},
- {s*v.x*v.y, 1+s*v.y^2, s*v.y*v.z, 0},
+ {1+s*v.x^2, s*v.x*v.y, s*v.x*v.z, 0},
+ {s*v.x*v.y, 1+s*v.y^2, s*v.y*v.z, 0},
{s*v.x*v.z, s*v.y*v.z, 1+s*v.z^2, 0},
{0, 0, 0, 1}};
}
@@ -248,7 +272,7 @@ transform3 look(triple eye, triple up=Z, triple target=O)
}
// Return a matrix to do perspective distortion based on a triple v.
-transform3 distort(triple v)
+transform3 distort(triple v)
{
transform3 t=identity(4);
real d=length(v);
@@ -410,7 +434,7 @@ projection TopView=orthographic(Z,up=Y,showtarget=true);
currentprojection=perspective(5,4,2);
-projection projection()
+projection projection()
{
projection P;
real[] a=_projection();
@@ -467,8 +491,8 @@ struct control {
}
control nocontrol;
-
-control operator * (transform3 t, control c)
+
+control operator * (transform3 t, control c)
{
control C;
C.post=t*c.post;
@@ -485,7 +509,7 @@ void write(file file, control c)
write(file," and ");
write(file,c.pre);
}
-
+
struct Tension {
real out,in;
bool atLeast;
@@ -510,7 +534,7 @@ Tension operator init()
Tension noTension;
noTension.active=false;
-
+
void write(file file, Tension t)
{
write(file,"..tension ");
@@ -519,7 +543,7 @@ void write(file file, Tension t)
write(file," and ");
write(file,t.in);
}
-
+
struct dir {
triple dir;
real gamma=1; // endpoint curl
@@ -561,8 +585,8 @@ void write(file file, dir d)
write(file,"{curl "); write(file,d.gamma); write(file,"}");
}
}
-
-dir operator * (transform3 t, dir d)
+
+dir operator * (transform3 t, dir d)
{
dir D=d.copy();
D.init(unit(shiftless(t)*d.dir));
@@ -596,11 +620,11 @@ struct flatguide3 {
bool cyclic() {int n=cyclic.length; return n > 0 ? cyclic[n-1] : false;}
bool precyclic() {int i=find(cyclic); return i >= 0 && i < cyclic.length-1;}
-
+
int size() {
return cyclic() ? nodes.length-1 : nodes.length;
}
-
+
void node(triple v, bool b=false) {
nodes.push(v);
control.push(nocontrol);
@@ -650,7 +674,7 @@ struct flatguide3 {
if(nodes.length > 0)
node(nodes[0],true);
}
-
+
// Return true if outgoing direction at node i is known.
bool solved(int i) {
return out[i].active() || control[i].active;
@@ -705,13 +729,13 @@ guide3 operator cast(cycleToken) {
};
}
-guide3 operator controls(triple post, triple pre)
+guide3 operator controls(triple post, triple pre)
{
return new void(flatguide3 f) {
f.control(post,pre);
};
};
-
+
guide3 operator controls(triple v)
{
return operator controls(v,v);
@@ -743,7 +767,7 @@ guide3 operator spec(triple v, int side)
abort("invalid direction specifier");
};
}
-
+
guide3 operator -- (... guide3[] g)
{
return new void(flatguide3 f) {
@@ -805,13 +829,13 @@ real asin1(real x)
{
return asin(min(max(x,-1),1));
}
-
+
// A version of acos that tolerates numerical imprecision
real acos1(real x)
{
return acos(min(max(x,-1),1));
}
-
+
struct Controls {
triple c0,c1;
@@ -840,7 +864,7 @@ private triple cross(triple d0, triple d1, triple reference)
triple normal=cross(d0,d1);
return normal == O ? reference : normal;
}
-
+
private triple dir(real theta, triple d0, triple d1, triple reference)
{
triple normal=cross(d0,d1,reference);
@@ -860,7 +884,7 @@ private real angle(triple d0, triple d1, triple reference)
// beta[i] is the tension for segment i, and in[i] is the incoming
// direction for segment i (where segment i begins at node i).
-real[] theta(triple[] v, real[] alpha, real[] beta,
+real[] theta(triple[] v, real[] alpha, real[] beta,
triple dir0, triple dirn, real g0, real gn, triple reference)
{
real[] a,b,c,f,l,psi;
@@ -905,7 +929,7 @@ real[] theta(triple[] v, real[] alpha, real[] beta,
f[n]=angle(v[n]-v[n-1],dirn,reference);
}
}
-
+
for(int i=i0; i < n; ++i) {
real in=beta[i-1]^2*l[i-1];
real A=in/alpha[i-1];
@@ -917,14 +941,14 @@ real[] theta(triple[] v, real[] alpha, real[] beta,
c[i]=C;
f[i]=-B*psi[i-1]-C*psi[i];
}
-
+
return tridiagonal(a,b,c,f);
}
triple reference(triple[] v, int n, triple d0, triple d1)
{
triple[] V=sequence(new triple(int i) {
- return cross(v[i+1]-v[i],v[i+2]-v[i+1]);
+ return cross(v[i+1]-v[i],v[i+2]-v[i+1]);
},n-1);
if(n > 0) {
V.push(cross(d0,v[1]-v[0]));
@@ -952,18 +976,18 @@ triple reference(triple[] v, int n, triple d0, triple d1)
}
// Fill in missing directions for n cyclic nodes.
-void aim(flatguide3 g, int N)
+void aim(flatguide3 g, int N)
{
bool cyclic=true;
int start=0, end=0;
-
+
// If the cycle contains one or more direction specifiers, break the loop.
for(int k=0; k < N; ++k)
if(g.solved(k)) {cyclic=false; end=k; break;}
for(int k=N-1; k >= 0; --k)
if(g.solved(k)) {cyclic=false; start=k; break;}
while(start < N && g.control[start].active) ++start;
-
+
int n=N-(start-end);
if(n <= 1 || (cyclic && n <= 2)) return;
@@ -993,7 +1017,7 @@ void aim(flatguide3 g, int N)
v.cyclic=true;
theta.cyclic=true;
-
+
for(int k=1; k < (cyclic ? n+1 : n); ++k) {
triple w=dir(theta[k],v[k]-v[k-1],v[k+1]-v[k],reference);
g.in[(start+k-1) % N].init(w);
@@ -1008,7 +1032,7 @@ void aim(flatguide3 g, int N)
}
// Fill in missing directions for the sequence of nodes i...n.
-void aim(flatguide3 g, int i, int n)
+void aim(flatguide3 g, int i, int n)
{
int j=n-i;
if(j > 1 || g.out[i].dir != O || g.in[i].dir != O) {
@@ -1021,7 +1045,7 @@ void aim(flatguide3 g, int i, int n)
beta[k]=g.Tension[i+k].in;
}
v[j]=g.nodes[n];
-
+
triple d0=g.out[i].dir;
triple d1=g.in[n-1].dir;
@@ -1029,7 +1053,7 @@ void aim(flatguide3 g, int i, int n)
real[] theta=theta(v,alpha,beta,d0,d1,g.out[i].gamma,g.in[n-1].gamma,
reference);
-
+
for(int k=1; k < j; ++k) {
triple w=dir(theta[k],v[k]-v[k-1],v[k+1]-v[k],reference);
g.in[i+k-1].init(w);
@@ -1175,7 +1199,7 @@ path path(path3 p, pair P(triple)=xypart)
for(int i=1; i < n; ++i)
g=straight(p,i-1) ? g--P(point(p,i)) :
g..controls P(postcontrol(p,i-1)) and P(precontrol(p,i))..P(point(p,i));
-
+
if(straight(p,n-1))
return cyclic(p) ? g--cycle : g--P(point(p,n));
@@ -1241,16 +1265,16 @@ path3 solve(flatguide3 g)
for(int i=0; i < n; ++i) {
if(g.nodes[i] == g.nodes[i+1] && !g.control[i].active)
g.control[i]=control(g.nodes[i],g.nodes[i],straight=true);
- }
-
+ }
+
// Fill in empty direction specifiers inherited from explicit control points.
for(int i=0; i < n; ++i) {
if(g.control[i].active) {
g.out[i].init(g.control[i].post-g.nodes[i]);
g.in[i].init(g.nodes[i+1]-g.control[i].pre);
}
- }
-
+ }
+
// Propagate directions across nodes.
for(int i=0; i < n; ++i) {
int next=g.cyclic[i+1] ? 0 : i+1;
@@ -1260,8 +1284,8 @@ path3 solve(flatguide3 g)
g.out[next].default(g.in[i]);
g.out[i+1].default(g.in[i]);
}
- }
-
+ }
+
// Compute missing 3D directions.
// First, resolve cycles
int i=find(g.cyclic);
@@ -1278,7 +1302,7 @@ path3 solve(flatguide3 g)
}
}
}
-
+
// Next, resolve sequences.
int i=0;
int start=0;
@@ -1288,13 +1312,13 @@ path3 solve(flatguide3 g)
if(i > n) break;
// Look for the end of the sequence.
while(i < n && !g.solved(i)) ++i;
-
+
while(start < i && g.control[start].active) ++start;
-
- if(start < i)
+
+ if(start < i)
aim(g,start,i);
}
-
+
// Compute missing 3D control points.
for(int i=0; i < n; ++i) {
int next=g.cyclic[i+1] ? 0 : i+1;
@@ -1344,7 +1368,7 @@ path3 solve(flatguide3 g)
straight[n-1]=false;
}
}
-
+
return path3(pre,point,post,straight,cyclic);
}
@@ -1385,7 +1409,7 @@ path project(path3 p, projection P=currentprojection,
int last=length(p);
if(last < 0) return g;
-
+
transform3 t=P.t;
if(ninterpolate == 1 || piecewisestraight(p)) {
@@ -1401,7 +1425,7 @@ path project(path3 p, projection P=currentprojection,
}
}
} else return nurb(p,P);
-
+
if(cyclic(p))
g=straight(p,last-1) ? g--cycle :
g..controls project(postcontrol(p,last-1),t) and
@@ -1418,11 +1442,11 @@ path[] project(explicit path3[] g, projection P=currentprojection)
{
return sequence(new path(int i) {return project(g[i],P);},g.length);
}
-
+
guide3 operator cast(path3 p)
{
int last=length(p);
-
+
bool cyclic=cyclic(p);
int stop=cyclic ? last-1 : last;
return new void(flatguide3 f) {
@@ -1456,7 +1480,7 @@ triple normal(path3 p)
real fuzz=sqrtEpsilon*abs(max(p)-min(p));
real absnormal;
real theta;
-
+
bool Cross(triple a, triple b) {
if(abs(a) >= fuzz && abs(b) >= fuzz) {
triple n=cross(unit(a),unit(b));
@@ -1478,7 +1502,7 @@ triple normal(path3 p)
}
return false;
}
-
+
int L=length(p);
if(L <= 0) return O;
@@ -1505,7 +1529,7 @@ triple normal(triple[] p)
real fuzz=sqrtEpsilon*abs(maxbound(p)-minbound(p));
real absnormal;
real theta;
-
+
bool Cross(triple a, triple b) {
if(abs(a) >= fuzz && abs(b) >= fuzz) {
triple n=cross(unit(a),unit(b));
@@ -1526,7 +1550,7 @@ triple normal(triple[] p)
}
return false;
}
-
+
if(p.length <= 0) return O;
triple zi=p[0];
@@ -1642,7 +1666,7 @@ Label project(Label L, triple u, triple v, triple O=O,
projection P=currentprojection) {
Label L=L.copy();
L.position=project(O,P.t);
- L.transform(transform(u,v,O,P));
+ L.transform(transform(u,v,O,P));
return L;
}
@@ -1674,7 +1698,7 @@ void write(file file, string s="", explicit guide3[] x, suffix suffix=none)
write(file,s,(path3[]) x,suffix);
}
-void write(string s="", explicit guide3[] x, suffix suffix=endl)
+void write(string s="", explicit guide3[] x, suffix suffix=endl)
{
write(stdout,s,(path3[]) x,suffix);
}
@@ -1850,7 +1874,7 @@ real relative(Label L, path3 g)
}
// return the linear transformation that maps X,Y,Z to u,v,w.
-transform3 transform3(triple u, triple v, triple w=cross(u,v))
+transform3 transform3(triple u, triple v, triple w=cross(u,v))
{
return new real[][] {
{u.x,v.x,w.x,0},
@@ -1915,37 +1939,37 @@ path3[] operator cast(guide3 g)
return new path3[] {(path3) g};
}
-path3[] operator ^^ (path3 p, path3 q)
+path3[] operator ^^ (path3 p, path3 q)
{
return new path3[] {p,q};
}
-path3[] operator ^^ (path3 p, explicit path3[] q)
+path3[] operator ^^ (path3 p, explicit path3[] q)
{
return concat(new path3[] {p},q);
}
-path3[] operator ^^ (explicit path3[] p, path3 q)
+path3[] operator ^^ (explicit path3[] p, path3 q)
{
return concat(p,new path3[] {q});
}
-path3[] operator ^^ (explicit path3[] p, explicit path3[] q)
+path3[] operator ^^ (explicit path3[] p, explicit path3[] q)
{
return concat(p,q);
}
-path3[] operator * (transform3 t, explicit path3[] p)
+path3[] operator * (transform3 t, explicit path3[] p)
{
return sequence(new path3(int i) {return t*p[i];},p.length);
}
-triple[] operator * (transform3 t, triple[] v)
+triple[] operator * (transform3 t, triple[] v)
{
return sequence(new triple(int i) {return t*v[i];},v.length);
}
-triple[][] operator * (transform3 t, triple[][] v)
+triple[][] operator * (transform3 t, triple[][] v)
{
triple[][] V=new triple[v.length][];
for(int i=0; i < v.length; ++i) {
@@ -1979,7 +2003,7 @@ path3 randompath3(int n, bool cumulate=true, interpolate3 join=operator ..)
triple w;
for(int i=0; i <= n; ++i) {
triple z=(unitrand()-0.5,unitrand()-0.5,unitrand()-0.5);
- if(cumulate) w += z;
+ if(cumulate) w += z;
else w=z;
g=join(g,w);
}
@@ -2040,15 +2064,15 @@ path3 arc(triple c, triple v1, triple v2, triple normal=O, bool direction=CCW)
v1=Tinv*v1;
v2=Tinv*v2;
}
-
+
string invalidnormal="invalid normal vector";
real fuzz=sqrtEpsilon;
if(abs(v1.z) > fuzz || abs(v2.z) > fuzz)
abort(invalidnormal);
-
+
real[] t1=intersect(unitcircle3,O--2*(v1.x,v1.y,0));
real[] t2=intersect(unitcircle3,O--2*(v2.x,v2.y,0));
-
+
if(t1.length == 0 || t2.length == 0)
abort(invalidnormal);
@@ -2102,21 +2126,19 @@ void draw(frame f, path3 g, material p=currentpen, light light=nolight,
string name="", render render=defaultrender,
projection P=currentprojection);
-void begingroup3(frame f, string name="", render render=defaultrender,
- triple center=O, int interaction=0)
+void begingroup3(frame f, string name="", render render=defaultrender)
{
_begingroup3(f,name,render.compression,render.granularity,render.closed,
render.tessellate,render.merge == false,
- render.merge == true,center,interaction);
+ render.merge == true,render.interaction.center,render.interaction.type);
}
void begingroup3(picture pic=currentpicture, string name="",
- render render=defaultrender,
- triple center=O, int interaction=0)
+ render render=defaultrender)
{
pic.add(new void(frame f, transform3, picture pic, projection) {
if(is3D())
- begingroup3(f,name,render,center,interaction);
+ begingroup3(f,name,render);
if(pic != null)
begingroup(pic);
},true);
@@ -2141,7 +2163,7 @@ void addPath(picture pic, path3 g, pen p)
include three_surface;
include three_margins;
-pair min(path3 p, projection P)
+pair min(path3 p, projection P)
{
path3 q=P.T.modelview*p;
if(P.infinity)
@@ -2149,7 +2171,7 @@ pair min(path3 p, projection P)
return maxratio(q)/P.T.projection[3][2];
}
-pair max(path3 p, projection P)
+pair max(path3 p, projection P)
{
path3 q=P.T.modelview*p;
if(P.infinity)
@@ -2157,7 +2179,7 @@ pair max(path3 p, projection P)
return minratio(q)/P.T.projection[3][2];
}
-pair min(frame f, projection P)
+pair min(frame f, projection P)
{
frame g=P.T.modelview*f;
if(P.infinity)
@@ -2165,7 +2187,7 @@ pair min(frame f, projection P)
return maxratio(g)/P.T.projection[3][2];
}
-pair max(frame f, projection P)
+pair max(frame f, projection P)
{
frame g=P.T.modelview*f;
if(P.infinity)
@@ -2210,7 +2232,7 @@ draw=new void(frame f, path3 g, material p=currentpen,
void drawthick(path3 g) {
if(settings.thick && width > 0) {
bool prc=prc();
- bool webgl=settings.outformat == "html";
+ bool primitive=primitive();
real linecap=linecap(q);
real r=0.5*width;
bool open=!cyclic(g);
@@ -2256,7 +2278,7 @@ draw=new void(frame f, path3 g, material p=currentpen,
}
}
// Draw central core for better small-scale rendering.
- if((!prc || piecewisestraight(g)) && !webgl && opacity(q) == 1)
+ if((!prc || piecewisestraight(g)) && !primitive && opacity(q) == 1)
_draw(f,c,p,light);
}
for(surface s : T.s)
@@ -2319,7 +2341,7 @@ void draw(picture pic=currentpicture, explicit path3[] g,
include three_arrows;
-void draw(picture pic=currentpicture, Label L="", path3 g,
+void draw(picture pic=currentpicture, Label L="", path3 g,
align align=NoAlign, material p=currentpen, arrowbar3 arrow,
arrowbar3 bar=None, margin3 margin=NoMargin3, light light=nolight,
light arrowheadlight=currentlight, string name="",
@@ -2409,12 +2431,12 @@ triple min3(picture pic, projection P=currentprojection)
{
return pic.min3(P);
}
-
+
triple max3(picture pic, projection P=currentprojection)
{
return pic.max3(P);
}
-
+
triple size3(picture pic, bool user=false, projection P=currentprojection)
{
transform3 t=pic.calculateTransform3(P);
@@ -2635,7 +2657,7 @@ struct scene
transform3 T=identity4;
picture pic2;
bool keepAspect=true;
-
+
void operator init(frame f, real width, real height,
projection P=currentprojection) {
this.f=f;
@@ -2644,14 +2666,14 @@ struct scene
this.width=width;
this.height=height;
}
-
+
void operator init(picture pic, real xsize=pic.xsize, real ysize=pic.ysize,
bool keepAspect=pic.keepAspect, bool is3D=true,
projection P=currentprojection) {
real xsize3=pic.xsize3, ysize3=pic.ysize3, zsize3=pic.zsize3;
bool warn=true;
this.keepAspect=keepAspect;
-
+
if(xsize3 == 0 && ysize3 == 0 && zsize3 == 0) {
xsize3=ysize3=zsize3=max(xsize,ysize);
warn=false;
@@ -2787,6 +2809,7 @@ object embed(string prefix=outprefix(), string label=prefix,
triple orthoshift;
modelview=P.T.modelview;
transform3 inv;
+ bool prc=prc(format);
if(P.absolute) {
Q=modelview*P;
inv=inverse(modelview);
@@ -2798,12 +2821,13 @@ object embed(string prefix=outprefix(), string label=prefix,
if(Q.t[2][3] == -1) // PRC can't handle oblique projections
Q=orthographic(P.camera,P.up,P.target,P.zoom,P.viewportshift,
- P.showtarget,P.center);
+ P.showtarget,P.center);
+
if(P.infinity) {
triple m=min3(S.f);
triple M=max3(S.f);
triple lambda=M-m;
- if(S.keepAspect) {
+ if(S.keepAspect || prc) {
S.viewportmargin=viewportmargin((lambda.x,lambda.y));
S.width=ceil(lambda.x+2*S.viewportmargin.x);
S.height=ceil(lambda.y+2*S.viewportmargin.y);
@@ -2821,7 +2845,7 @@ object embed(string prefix=outprefix(), string label=prefix,
inv=inverse(modelview);
Q.angle=P.angle;
if(settings.verbose > 0) {
- if(S.adjusted)
+ if(S.adjusted)
write("adjusting camera to ",tinv*inv*P.camera);
target=inv*P.target;
}
@@ -2835,7 +2859,6 @@ object embed(string prefix=outprefix(), string label=prefix,
light Light=modelview*light;
if(prefix == "") prefix=outprefix();
- bool prc=prc(format);
bool preview=settings.render > 0 && !prconly();
if(prc) {
// The media9.sty package cannot handle spaces or dots in filenames.
@@ -2868,12 +2891,12 @@ object embed(string prefix=outprefix(), string label=prefix,
if(P.infinity) {
triple margin=(S.viewportmargin.x,S.viewportmargin.y,0);
- M += margin;
+ M += margin;
m -= margin;
} else if(M.z >= 0) abort("camera too close");
- if(settings.outformat == "html")
- format="html";
+ if(primitive())
+ format=settings.outformat;
shipout3(prefix,f,preview ? nativeformat() : format,
S.width-defaultrender.margin,S.height-defaultrender.margin,
@@ -2893,7 +2916,7 @@ object embed(string prefix=outprefix(), string label=prefix,
transform T=S.pic2.scaling(S.width,S.height);
_shipout(image,S.pic2.fit(T),newframe,nativeformat(),false,false);
}
-
+
image += "."+nativeformat();
if(!settings.inlinetex) file3.push(image);
image=graphic(image,"hiresbb");
@@ -2924,7 +2947,7 @@ shift");
if(P.infinity) {
triple lambda=max3(S.f)-min3(S.f);
pair margin=viewportmargin((lambda.x,lambda.y));
- viewplanesize=(max(lambda.x+2*margin.x,lambda.y+2*margin.y))/(Q.zoom);
+ viewplanesize=(max(lambda.x+2*margin.x,lambda.y+2*margin.y))/Q.zoom;
transform3 t=inv*shift(-orthoshift);
Q=t*Q;
S.f=t*S.f;
@@ -2948,7 +2971,7 @@ object embed(string prefix=outprefix(), string label=prefix,
{
bool is3D=is3D(format);
scene S=scene(pic,xsize,ysize,keepAspect,is3D,P);
- if(is3D)
+ if(is3D && !(settings.xasy && format == ""))
return embed(prefix,label,text,S,format,view,options,script,light);
else {
object F;
@@ -3017,7 +3040,9 @@ currentpicture.fitter=new frame(string prefix, picture pic, string format,
return embed(prefix=prefix,pic,format,xsize,ysize,keepAspect,view,
options,script,light,P);
},prefix,format,view,light);
- if(is3D(format) || empty3) add(f,pic.fit2(xsize,ysize,keepAspect));
+
+ if(is3D(format) || empty3)
+ add(f,pic.fit2(xsize,ysize,keepAspect));
return f;
};
@@ -3056,7 +3081,7 @@ void addViews(picture dest, picture src, projection[][] views=SixViewsUS,
frame[][] F=array(views.length,new frame[]);
pair[][] M=array(views.length,new pair[]);
pair[][] m=array(views.length,new pair[]);
-
+
for(int i=0; i < views.length; ++i) {
projection[] viewsi=views[i];
frame[] Fi=F[i];
@@ -3076,17 +3101,17 @@ void addViews(picture dest, picture src, projection[][] views=SixViewsUS,
}
}
}
-
+
real[] my=new real[views.length];
real[] My=new real[views.length];
-
+
int Nj=0;
for(int i=0; i < views.length; ++i) {
my[i]=minbound(m[i]).y;
My[i]=maxbound(M[i]).y;
Nj=max(Nj,views[i].length);
}
-
+
real[] mx=array(Nj,infinity);
real[] Mx=array(Nj,-infinity);
for(int i=0; i < views.length; ++i) {
@@ -3179,10 +3204,10 @@ frame[] fit3(string prefix="", picture[] pictures, picture all,
frame f=embedder(prefix,out[i],format,S.width,S.height,view,options,
script,light,S.P);
if(!settings.loop) out[i]=f;
- }
+ }
if(!settings.loop) break;
}
-
+
settings.animating=false;
settings.interrupt=false;
settings.reverse=reverse;
diff --git a/graphics/asymptote/base/three_arrows.asy b/graphics/asymptote/base/three_arrows.asy
index b0369e6bea..35f6bc4cea 100644
--- a/graphics/asymptote/base/three_arrows.asy
+++ b/graphics/asymptote/base/three_arrows.asy
@@ -37,7 +37,7 @@ triple bend(triple p, path3 g, real scale)
return bend(g,arctime(g,arclength(g)+p.z-scale))*(p.x,p.y,0);
}
-void bend(surface s, path3 g, real L)
+void bend(surface s, path3 g, real L)
{
for(patch p : s.s) {
for(int i=0; i < 4; ++i) {
@@ -140,7 +140,7 @@ DefaultHead3.head=new surface(path3 g, position position=EndPoint,
path3 r=subpath(g,position,0);
path3 s=subpath(r,arctime(r,size),0);
- int n=length(s);
+ int n=length(s);
bool straight1=n == 1 && straight(g,0);
real aspect=Tan(angle);
real width=size*aspect;
@@ -186,7 +186,7 @@ arrowhead3 HookHead3(real dir=arrowdir, real barb=arrowbarb)
filltype filltype=null, bool forwards=true,
projection P=currentprojection) {
if(size == 0) size=a.size(p);
-
+
bool relative=position.relative;
real position=position.position.x;
if(relative) position=reltime(g,position);
@@ -198,7 +198,7 @@ arrowhead3 HookHead3(real dir=arrowdir, real barb=arrowbarb)
YZplane);
surface head=surface(O,reverse(approach(subpath(H,1,0),7,1.5))&
approach(subpath(H,1,2),4,2),Z);
-
+
if(straight1) {
triple v=point(s,0);
triple u=point(s,1)-v;
@@ -324,7 +324,7 @@ private real position(position position, real size, path3 g, bool center)
position *= arclength(g);
if(center) position += 0.5*size;
position=arctime(g,position);
- } else if(center)
+ } else if(center)
position=arctime(g,arclength(subpath(g,0,position))+0.5*size);
return position;
}
@@ -450,7 +450,7 @@ picture arrow2(arrowhead3 arrowhead=DefaultHead3,
path3 g, material p=currentpen, material arrowheadpen=p,
real size=0, real angle=arrowangle, filltype filltype=null,
margin3 margin=NoMargin3, light light=nolight,
- light arrowheadlight=currentlight)
+ light arrowheadlight=currentlight)
{
pen q=(pen) p;
if(size == 0) size=arrowhead.size(q);
@@ -539,7 +539,7 @@ void bar(picture pic, triple a, triple d, triple perp=O,
pic.addPoint(a,v-M);
pic.addPoint(a,v+M);
}
-
+
picture bar(triple a, triple dir, triple perp=O, material p=currentpen)
{
picture pic;
@@ -620,11 +620,11 @@ arrowbar3 BeginArcArrow3(arrowhead3 arrowhead=DefaultHead3,
material arrowheadpen=nullpen)
{
return new bool(picture pic, path3 g, material p, margin3 margin,
- light light, light arrowheadlight) {
+ light light, light arrowheadlight) {
real size=size == 0 ? arrowhead.arcsize((pen) p) : size;
add(pic,arrowhead,size,angle,filltype,position,arrowheadpen,g,p,
forwards=false,margin,light,arrowheadlight);
- return false;
+ return false;
};
}
@@ -685,7 +685,7 @@ arrowbar3 BeginBar3(real size=0, triple dir=O)
};
}
-arrowbar3 Bar3(real size=0, triple dir=O)
+arrowbar3 Bar3(real size=0, triple dir=O)
{
return new bool(picture pic, path3 g, material p, margin3 margin, light light,
light) {
@@ -696,9 +696,9 @@ arrowbar3 Bar3(real size=0, triple dir=O)
};
}
-arrowbar3 EndBar3(real size=0, triple dir=O)=Bar3;
+arrowbar3 EndBar3(real size=0, triple dir=O)=Bar3;
-arrowbar3 Bars3(real size=0, triple dir=O)
+arrowbar3 Bars3(real size=0, triple dir=O)
{
return new bool(picture pic, path3 g, material p, margin3 margin, light light,
light) {
diff --git a/graphics/asymptote/base/three_light.asy b/graphics/asymptote/base/three_light.asy
index 46b0fef7d0..f17a4324c9 100644
--- a/graphics/asymptote/base/three_light.asy
+++ b/graphics/asymptote/base/three_light.asy
@@ -1,7 +1,7 @@
struct material {
pen[] p; // diffusepen,emissivepen,specularpen
real opacity;
- real shininess;
+ real shininess;
real metallic;
real fresnel0; // Reflectance rate at a perfect normal angle.
@@ -34,7 +34,7 @@ struct material {
void specular(pen q) {p[2]=q;}
}
-material operator init()
+material operator init()
{
return material();
}
@@ -57,7 +57,7 @@ void write(string s="", material x, suffix suffix=endl)
{
write(stdout,s,x,suffix);
}
-
+
bool operator == (material m, material n)
{
return all(m.p == n.p) && m.opacity == n.opacity &&
diff --git a/graphics/asymptote/base/three_margins.asy b/graphics/asymptote/base/three_margins.asy
index b6f286ee4f..a488029573 100644
--- a/graphics/asymptote/base/three_margins.asy
+++ b/graphics/asymptote/base/three_margins.asy
@@ -27,7 +27,7 @@ margin3 operator +(margin3 ma, margin3 mb)
}
margin3 NoMargin3()
-{
+{
return new marginT3(path3 g, pen) {
marginT3 margin;
margin.begin=margin.end=0;
@@ -35,9 +35,9 @@ margin3 NoMargin3()
return margin;
};
}
-
+
margin3 Margin3(real begin, real end)
-{
+{
return new marginT3(path3 g, pen p) {
marginT3 margin;
real factor=labelmargin(p);
@@ -48,9 +48,9 @@ margin3 Margin3(real begin, real end)
return margin;
};
}
-
+
margin3 PenMargin3(real begin, real end)
-{
+{
return new marginT3(path3 g, pen p) {
marginT3 margin;
real factor=linewidth(p);
@@ -60,9 +60,9 @@ margin3 PenMargin3(real begin, real end)
return margin;
};
}
-
+
margin3 DotMargin3(real begin, real end)
-{
+{
return new marginT3(path3 g, pen p) {
marginT3 margin;
real margindot(real x) {return x > 0 ? dotfactor*x : x;}
@@ -73,9 +73,9 @@ margin3 DotMargin3(real begin, real end)
return margin;
};
}
-
+
margin3 TrueMargin3(real begin, real end)
-{
+{
return new marginT3(path3 g, pen p) {
marginT3 margin;
margin.begin=begin;
@@ -84,7 +84,7 @@ margin3 TrueMargin3(real begin, real end)
return margin;
};
}
-
+
margin3 NoMargin3=NoMargin3(),
BeginMargin3=Margin3(1,0),
Margin3=Margin3(0,1),
diff --git a/graphics/asymptote/base/three_surface.asy b/graphics/asymptote/base/three_surface.asy
index 77bdc6a998..e993c8d713 100644
--- a/graphics/asymptote/base/three_surface.asy
+++ b/graphics/asymptote/base/three_surface.asy
@@ -34,7 +34,7 @@ struct patch {
}
path3 externaltriangular() {
- return
+ return
P[0][0]..controls P[1][0] and P[2][0]..
P[3][0]..controls P[3][1] and P[3][2]..
P[3][3]..controls P[2][2] and P[1][1]..cycle;
@@ -91,7 +91,7 @@ struct patch {
new triple[] {Bv(1,v),z1},new bool[] {straight,false},false);
}
- triple point(real u, real v) {
+ triple point(real u, real v) {
return bezier(Bu(0,u),Bu(1,u),Bu(2,u),Bu(3,u),v);
}
@@ -237,7 +237,7 @@ struct patch {
color(normal11(),nocolors ? m : colors[2],light),
color(normal01(),nocolors ? m : colors[3],light)};
}
-
+
pen[] colorstriangular(material m, light light=currentlight) {
bool nocolors=colors.length == 0;
if(planar) {
@@ -250,7 +250,7 @@ struct patch {
color(normal10(),nocolors ? m : colors[1],light),
color(normal01(),nocolors ? m : colors[2],light)};
}
-
+
triple min3,max3;
bool havemin3,havemax3;
@@ -332,7 +332,7 @@ struct patch {
void operator init(patch s) {
operator init(s.P,s.colors,s.straight,s.planar,s.triangular);
}
-
+
// A constructor for a cyclic path3 of length 3 with a specified
// internal point, corner normals, and pens (rendered as a Bezier triangle).
void operator init(path3 external, triple internal, pen[] colors=new pen[],
@@ -406,51 +406,65 @@ struct patch {
};
}
- // A constructor for a convex quadrilateral.
+ // A constructor for a triangle or convex quadrilateral.
void operator init(triple[] external, triple[] internal=new triple[],
pen[] colors=new pen[], bool3 planar=default) {
init();
- if(internal.length == 0 && planar == default)
- this.planar=normal(external) != O;
- else this.planar=planar;
+ straight=true;
if(colors.length != 0)
this.colors=copy(colors);
- if(internal.length == 0) {
- internal=new triple[4];
+ if(external.length == 3) {
+ P=new triple[][] {
+ {external[0]},
+ {interp(external[0],external[1],1/3),
+ interp(external[2],external[0],2/3)},
+ {interp(external[0],external[1],2/3),sum(external)/3,
+ interp(external[2],external[0],1/3)},
+ {external[1],interp(external[1],external[2],1/3),
+ interp(external[1],external[2],2/3),external[2]}
+ };
+ planar=true;
+ triangular=true;
+ } else {
+ if(internal.length == 0 && planar == default)
+ this.planar=normal(external) != O;
+ else this.planar=planar;
+
+ if(internal.length == 0) {
+ internal=new triple[4];
+ for(int j=0; j < 4; ++j)
+ internal[j]=nineth*(4*external[j]+2*external[(j+1)%4]+
+ external[(j+2)%4]+2*external[(j+3)%4]);
+ }
+
+ triple delta[]=new triple[4];
for(int j=0; j < 4; ++j)
- internal[j]=nineth*(4*external[j]+2*external[(j+1)%4]+
- external[(j+2)%4]+2*external[(j+3)%4]);
+ delta[j]=(external[(j+1)% 4]-external[j])/3;
+
+ P=new triple[][] {
+ {external[0],external[0]-delta[3],external[3]+delta[3],external[3]},
+ {external[0]+delta[0],internal[0],internal[3],external[3]-delta[2]},
+ {external[1]-delta[0],internal[1],internal[2],external[2]+delta[2]},
+ {external[1],external[1]+delta[1],external[2]-delta[1],external[2]}
+ };
}
-
- straight=true;
-
- triple delta[]=new triple[4];
- for(int j=0; j < 4; ++j)
- delta[j]=(external[(j+1)% 4]-external[j])/3;
-
- P=new triple[][] {
- {external[0],external[0]-delta[3],external[3]+delta[3],external[3]},
- {external[0]+delta[0],internal[0],internal[3],external[3]-delta[2]},
- {external[1]-delta[0],internal[1],internal[2],external[2]+delta[2]},
- {external[1],external[1]+delta[1],external[2]-delta[1],external[2]}
- };
}
}
patch operator * (transform3 t, patch s)
-{
+{
patch S;
S.P=new triple[s.P.length][];
- for(int i=0; i < s.P.length; ++i) {
+ for(int i=0; i < s.P.length; ++i) {
triple[] si=s.P[i];
triple[] Si=S.P[i];
for(int j=0; j < si.length; ++j)
- Si[j]=t*si[j];
+ Si[j]=t*si[j];
}
-
+
S.colors=copy(s.colors);
S.planar=s.planar;
S.straight=s.straight;
@@ -458,8 +472,8 @@ patch operator * (transform3 t, patch s)
S.init();
return S;
}
-
-patch reverse(patch s)
+
+patch reverse(patch s)
{
assert(!s.triangular);
patch S;
@@ -505,7 +519,7 @@ pair[][] coons(path p)
p=p--cycle--cycle;
else if(L == 3)
p=p--cycle;
-
+
pair[] internal=new pair[4];
for(int j=0; j < 4; ++j) {
internal[j]=nineth*(-4*point(p,j)
@@ -533,12 +547,12 @@ path[] regularize(path p, bool checkboundary=true)
s.append(regularize(g,checkboundary));
return s;
}
-
+
bool straight=piecewisestraight(p);
if(L <= 3 && straight) {
return new path[] {p};
}
-
+
// Split p along the angle bisector at t.
bool split(path p, real t) {
pair dir=dir(p,t);
@@ -574,7 +588,7 @@ path[] regularize(path p, bool checkboundary=true)
if(straight)
return new path[] {p};
-
+
pair[][] P=coons(p);
// Check for degeneracy.
@@ -585,12 +599,12 @@ path[] regularize(path p, bool checkboundary=true)
for(int j=0; j < 4; ++j)
U[i][j]=P[i+1][j]-P[i][j];
}
-
+
for(int i=0; i < 4; ++i) {
for(int j=0; j < 3; ++j)
V[i][j]=P[i][j+1]-P[i][j];
}
-
+
int[] choose2={1,2,1};
int[] choose3={1,3,3,1};
@@ -670,7 +684,7 @@ path[] regularize(path p, bool checkboundary=true)
c[3] += w*(conj(P[0][j]-P[1][j])*P[0][i]).y; // u=0
}
}
-
+
pair BuP(int j, real u) {
return bezierP(P[0][j],P[1][j],P[2][j],P[3][j],u);
}
@@ -709,7 +723,7 @@ path[] regularize(path p, bool checkboundary=true)
// Split at the worst boundary degeneracy.
if(M < 0 && split(p,cut)) return s;
}
-
+
// Split arbitrarily to resolve any remaining (internal) degeneracy.
checkboundary=false;
for(int i=0; i < L; ++i)
@@ -730,7 +744,7 @@ struct surface {
int index[][];// Position of patch corresponding to major U,V parameter in s.
bool vcyclic;
transform3 T=identity4;
-
+
drawfcn draw;
bool PRCprimitive=true; // True unless no PRC primitive is available.
@@ -790,7 +804,7 @@ struct surface {
int V=floor(v);
int index=index.length == 0 ? U+V : index[U][V];
return s[index].point(u-U,v-V);
- }
+ }
triple normal(real u, real v) {
int U=floor(u);
@@ -798,25 +812,25 @@ struct surface {
int index=index.length == 0 ? U+V : index[U][V];
return s[index].normal(u-U,v-V);
}
-
- void ucyclic(bool f)
+
+ void ucyclic(bool f)
{
index.cyclic=f;
}
-
- void vcyclic(bool f)
+
+ void vcyclic(bool f)
{
for(int[] i : index)
i.cyclic=f;
vcyclic=f;
}
-
- bool ucyclic()
+
+ bool ucyclic()
{
return index.cyclic;
}
-
- bool vcyclic()
+
+ bool vcyclic()
{
return vcyclic;
}
@@ -830,7 +844,7 @@ struct surface {
g=g&s[i].uequals(u-U);
return vcyclic() ? g&cycle : g;
}
-
+
path3 vequals(real v) {
if(index.length == 0) return nullpath3;
int V=floor(v);
@@ -839,7 +853,7 @@ struct surface {
g=g&s[i[V]].vequals(v-V);
return ucyclic() ? g&cycle : g;
}
-
+
// A constructor for a possibly nonconvex simple cyclic path in a given
// plane.
void operator init(path p, triple plane(pair)=XYplane) {
@@ -880,12 +894,12 @@ struct surface {
return;
}
}
-
+
if(L <= 4 || internal.length > 0) {
s.push(patch(external,internal,colors,planar));
return;
}
-
+
// Path is not planar; split into patches.
real factor=1/L;
pen[] p;
@@ -968,7 +982,7 @@ struct surface {
typedef pen colorfcn(int i, real j);
bool defaultcolors=(colorfcn) color == null;
-
+
for(int i=0; i < L; ++i) {
path3 h=subpath(g,i,i+1);
path3 r=reverse(h);
@@ -985,7 +999,7 @@ struct surface {
}
test(maxtimes(H));
test(mintimes(H));
-
+
perp=unit(perp);
triple normal=unit(cross(axis,perp));
triple dir(real j) {return Cos(j)*normal-Sin(j)*perp;}
@@ -1023,7 +1037,7 @@ struct surface {
}
surface operator * (transform3 t, surface s)
-{
+{
surface S;
S.s=new patch[s.s.length];
for(int i=0; i < s.s.length; ++i)
@@ -1033,7 +1047,7 @@ surface operator * (transform3 t, surface s)
S.T=t*s.T;
S.draw=s.draw;
S.PRCprimitive=s.PRCprimitive;
-
+
return S;
}
@@ -1048,7 +1062,7 @@ triple min(surface s)
bound=s.s[i].min(bound);
return bound;
}
-
+
triple max(surface s)
{
if(s.s.length == 0)
@@ -1068,7 +1082,7 @@ pair min(surface s, projection P)
bound=s.s[i].min(P,bound);
return bound;
}
-
+
pair max(surface s, projection P)
{
if(s.s.length == 0)
@@ -1153,13 +1167,13 @@ triple[][][][] split(triple[][] P, real u=0.5, real v=0.5)
triple[] P1=P[1];
triple[] P2=P[2];
triple[] P3=P[3];
-
+
// slice horizontally
triple[] c0=split(P0[0],P0[1],P0[2],P0[3],v);
triple[] c1=split(P1[0],P1[1],P1[2],P1[3],v);
triple[] c2=split(P2[0],P2[1],P2[2],P2[3],v);
triple[] c3=split(P3[0],P3[1],P3[2],P3[3],v);
-
+
// bottom patch
triple[] c4=split(P0[0],P1[0],P2[0],P3[0],u);
triple[] c5=split(c0[0],c1[0],c2[0],c3[0],u);
@@ -1242,7 +1256,7 @@ triple[][] subpatchbegin(triple[][] P, real u, real v)
{c4[2],c5[2],c6[2],c7[2]}};
}
-triple[][] subpatch(triple[][] P, pair a, pair b)
+triple[][] subpatch(triple[][] P, pair a, pair b)
{
return subpatchend(subpatchbegin(P,b.x,b.y),a.x/b.x,a.y/b.y);
}
@@ -1294,7 +1308,7 @@ real[][] intersections(path3 p, surface s, real fuzz=-1)
static real Fuzz=1000*realEpsilon;
real fuzz=max(10*fuzz,Fuzz*max(abs(min(s)),abs(max(s))));
-
+
// Remove intrapatch duplicate points.
for(int i=0; i < T.length; ++i) {
triple v=point(p,T[i][0]);
@@ -1331,7 +1345,7 @@ bool overlap(triple[][] p, triple[][] q, real fuzz=-1)
if(fuzz == -1)
fuzz=1000*realEpsilon*max(abs(pmin),abs(pmax),abs(qmin),abs(qmax));
-
+
return
pmax.x+fuzz >= qmin.x &&
pmax.y+fuzz >= qmin.y &&
@@ -1346,19 +1360,6 @@ triple point(patch s, real u, real v)
return s.point(u,v);
}
-struct interaction
-{
- int type;
- bool targetsize;
- void operator init(int type, bool targetsize=false) {
- this.type=type;
- this.targetsize=targetsize;
- }
-}
-
-restricted interaction Embedded=interaction(0);
-restricted interaction Billboard=interaction(1);
-
interaction LabelInteraction()
{
return settings.autobillboard ? Billboard : Embedded;
@@ -1369,8 +1370,8 @@ material material(material m, light light, bool colors=false)
return light.on() || invisible((pen) m) ? m : emissive(m,colors);
}
-void draw3D(frame f, patch s, triple center=O, material m,
- light light=currentlight, interaction interaction=Embedded,
+void draw3D(frame f, patch s, material m,
+ light light=currentlight, render render=defaultrender,
bool primitive=false)
{
bool straight=s.straight && s.planar;
@@ -1381,13 +1382,15 @@ void draw3D(frame f, patch s, triple center=O, material m,
if(s.colors.length > 0) {
if(prc() && light.on())
straight=false; // PRC vertex colors (for quads only) ignore lighting
+ m=material(m);
m.diffuse(mean(s.colors));
}
m=material(m,light,s.colors.length > 0);
-
- (s.triangular ? drawbeziertriangle : draw)
- (f,s.P,center,straight,m.p,m.opacity,m.shininess,
- m.metallic,m.fresnel0,s.colors,interaction.type,digits,primitive);
+
+ (s.triangular ? drawbeziertriangle : draw)
+ (f,s.P,render.interaction.center,straight,m.p,m.opacity,m.shininess,
+ m.metallic,m.fresnel0,s.colors,render.interaction.type,digits,
+ primitive);
}
void _draw(frame f, path3 g, triple center=O, material m,
@@ -1417,7 +1420,7 @@ int computeNormals(triple[] v, int[][] vi, triple[] n, int[][] ni)
// Draw triangles on a frame.
void draw(frame f, triple[] v, int[][] vi,
triple[] n={}, int[][] ni={}, material m=currentpen, pen[] p={},
- int[][] pi={}, light light=currentlight)
+ int[][] pi={}, light light=currentlight, render render=defaultrender)
{
bool normals=n.length > 0;
if(!normals) {
@@ -1427,13 +1430,15 @@ void draw(frame f, triple[] v, int[][] vi,
if(p.length > 0)
m=mean(p);
m=material(m,light);
- draw(f,v,vi,n,ni,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,p,pi);
+ draw(f,v,vi,render.interaction.center,n,ni,
+ m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,p,pi,
+ render.interaction.type);
}
-
+
// Draw triangles on a picture.
void draw(picture pic=currentpicture, triple[] v, int[][] vi,
triple[] n={}, int[][] ni={}, material m=currentpen, pen[] p={},
- int[][] pi={}, light light=currentlight)
+ int[][] pi={}, light light=currentlight, render render=defaultrender)
{
bool prc=prc();
bool normals=n.length > 0;
@@ -1448,7 +1453,9 @@ void draw(picture pic=currentpicture, triple[] v, int[][] vi,
triple[] n=t*n;
if(is3D()) {
- draw(f,v,vi,n,ni,m,p,pi,light);
+ render Render=render(render,interaction(render.interaction,
+ t*render.interaction.center));
+ draw(f,v,vi,n,ni,m,p,pi,light,Render);
if(pic != null) {
for(int[] vii : vi)
for(int viij : vii)
@@ -1487,7 +1494,7 @@ void draw(picture pic=currentpicture, triple[] v, int[][] vi,
}
}
}
- }
+ }
},true);
for(int[] vii : vi)
@@ -1502,7 +1509,7 @@ void tensorshade(transform t=identity(), frame f, patch s,
if(s.triangular) {
p=s.colorstriangular(m,light);
p.push(p[0]);
- s=tensor(s);
+ s=tensor(s);
} else p=s.colors(m,light);
path g=t*project(s.external(),P,1);
pair[] internal=t*project(s.internal(),P);
@@ -1529,11 +1536,12 @@ void draw(transform t=identity(), frame f, surface s, int nu=1, int nv=1,
bool is3D=is3D();
if(is3D) {
bool prc=prc();
- if(s.draw != null && (settings.outformat == "html" ||
- (prc && s.PRCprimitive))) {
+ if(s.draw != null && (primitive() || (prc && s.PRCprimitive))) {
+ bool noprerender=settings.prerender == 0;
for(int k=0; k < s.s.length; ++k)
- draw3D(f,s.s[k],surfacepen[k],light,primitive=true);
- s.draw(f,s.T,surfacepen,light,render);
+ draw3D(f,s.s[k],surfacepen[k],light,render,primitive=noprerender);
+ if(noprerender)
+ s.draw(f,s.T,surfacepen,light,render);
} else {
bool group=name != "" || render.defaultnames;
if(group)
@@ -1557,7 +1565,7 @@ void draw(transform t=identity(), frame f, surface s, int nu=1, int nv=1,
for(int p=depth.length-1; p >= 0; --p) {
real[] a=depth[p];
int k=round(a[1]);
- draw3D(f,s.s[k],surfacepen[k],light);
+ draw3D(f,s.s[k],surfacepen[k],light,render);
}
if(group)
@@ -1646,8 +1654,11 @@ void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1,
pic.add(new void(frame f, transform3 t, picture pic, projection P) {
surface S=t*s;
- if(is3D())
- draw(f,S,nu,nv,surfacepen,meshpen,light,meshlight,name,render);
+ if(is3D()) {
+ render Render=render(render,interaction(render.interaction,
+ t*render.interaction.center));
+ draw(f,S,nu,nv,surfacepen,meshpen,light,meshlight,name,Render);
+ }
if(pic != null) {
pic.add(new void(frame f, transform T) {
draw(T,f,S,nu,nv,surfacepen,meshpen,light,meshlight,P);
@@ -1724,7 +1735,7 @@ surface extrude(explicit path[] p, triple axis=Z)
return s;
}
-triple rectify(triple dir)
+triple rectify(triple dir)
{
real scale=max(abs(dir.x),abs(dir.y),abs(dir.z));
if(scale != 0) dir *= 0.5/scale;
@@ -1832,16 +1843,17 @@ void label(frame f, Label L, triple position, align align=NoAlign,
transform3 positioning=
shift(L.align.is3D ? position+L.align.dir3*labelmargin(L.p) : position);
frame f1,f2,f3;
- begingroup3(f1,name,render);
- if(L.defaulttransform3)
- begingroup3(f3,render,position,interaction.type);
- else {
- begingroup3(f2,render,position,interaction.type);
- begingroup3(f3,render,position);
- }
+ render Render=render(render,interaction(interaction,position));
+ begingroup3(f1,name,render);
+ if(L.defaulttransform3)
+ begingroup3(f3,Render);
+ else {
+ begingroup3(f2,Render);
+ begingroup3(f3,Render);
+ }
for(patch S : s.s) {
S=centering*S;
- draw3D(f3,S,position,L.p,light,interaction);
+ draw3D(f3,S,L.p,light,Render);
// Fill subdivision cracks
if(prc && render.labelfill && opacity(L.p) == 1 && !lighton)
_draw(f3,S.external(),position,L.p,light,interaction);
@@ -1861,7 +1873,7 @@ void label(frame f, Label L, triple position, align align=NoAlign,
for(patch S : surface(L,position).s) {
triple V=L.align.is3D ? position+L.align.dir3*labelmargin(L.p) :
position;
- draw3D(f,S,V,L.p,light,interaction);
+ draw3D(f,S,L.p,light,render(interaction(interaction,center=V)));
// Fill subdivision cracks
if(prc && render.labelfill && opacity(L.p) == 1 && !lighton)
_draw(f,S.external(),V,L.p,light,interaction);
@@ -1894,7 +1906,7 @@ void label(picture pic=currentpicture, Label L, triple position,
L.align(align);
L.p(p);
L.position(0);
-
+
pic.add(new void(frame f, transform3 t, picture pic2, projection P) {
// Handle relative projected 3D alignments.
bool prc=prc();
@@ -1903,7 +1915,7 @@ void label(picture pic=currentpicture, Label L, triple position,
if(!align.is3D && L.align.relative && L.align.dir3 != O &&
determinant(P.t) != 0)
L.align(L.align.dir*unit(project(v+L.align.dir3,P.t)-project(v,P.t)));
-
+
if(interaction.targetsize && settings.render != 0)
L.T=L.T*scale(abs(P.camera-v)/abs(P.vector()));
transform3 T=transform3(P);
@@ -1922,15 +1934,16 @@ void label(picture pic=currentpicture, Label L, triple position,
shift(L.align.is3D ? v+L.align.dir3*labelmargin(L.p) : v);
frame f1,f2,f3;
begingroup3(f1,name,render);
+ render Render=render(render,interaction(interaction,v));
if(L.defaulttransform3)
- begingroup3(f3,render,v,interaction.type);
+ begingroup3(f3,Render);
else {
- begingroup3(f2,render,v,interaction.type);
- begingroup3(f3,render,v);
+ begingroup3(f2,Render);
+ begingroup3(f3,Render);
}
for(patch S : s.s) {
S=centering*S;
- draw3D(f3,S,v,L.p,light,interaction);
+ draw3D(f3,S,L.p,light,Render);
// Fill subdivision cracks
if(prc && render.labelfill && opacity(L.p) == 1 && !lighton)
_draw(f3,S.external(),v,L.p,light,interaction);
@@ -1950,7 +1963,8 @@ void label(picture pic=currentpicture, Label L, triple position,
begingroup3(f,name,render);
for(patch S : surface(L,v,bbox=P.bboxonly).s) {
triple V=L.align.is3D ? v+L.align.dir3*labelmargin(L.p) : v;
- draw3D(f,S,V,L.p,light,interaction);
+ render Render=render(render,interaction(interaction,V));
+ draw3D(f,S,L.p,light,Render);
// Fill subdivision cracks
if(prc && render.labelfill && opacity(L.p) == 1 && !lighton)
_draw(f,S.external(),V,L.p,light,interaction);
@@ -1958,7 +1972,7 @@ void label(picture pic=currentpicture, Label L, triple position,
endgroup3(f);
}
}
-
+
if(pic2 != null) {
pen p=color(L.T3*Z,L.p,light,shiftless(P.T.modelview));
if(L.defaulttransform3) {
@@ -1975,11 +1989,11 @@ void label(picture pic=currentpicture, Label L, triple position,
fill(f,T*project(S.external(),P,1),p);
});
}
-
+
},!L.defaulttransform3);
Label L=L.copy();
-
+
if(interaction.targetsize && settings.render != 0)
L.T=L.T*scale(abs(currentprojection.camera-position)/
abs(currentprojection.vector()));
@@ -2008,7 +2022,7 @@ void label(picture pic=currentpicture, Label L, path3 g, align align=NoAlign,
a.init(-I*(position <= sqrtEpsilon ? S :
position >= length(g)-sqrtEpsilon ? N : E),relative=true);
a.dir3=dir(g,position); // Pass 3D direction via unused field.
- L.align(a);
+ L.align(a);
}
label(pic,L,point(g,position),light,name,interaction);
}
@@ -2063,7 +2077,7 @@ surface surface(Label L, surface s, real uoffset, real voffset,
for(path g : regularize(p)) {
path3 b;
bool extrude=height > 0;
- if(bottom || extrude)
+ if(bottom || extrude)
b=transpath(g,0);
if(bottom) s.s.push(patch(b));
if(top || extrude) {
@@ -2390,7 +2404,7 @@ pair maxbound(triple[][] A, projection P)
return b;
}
-triple[][] operator / (triple[][] a, real[][] b)
+triple[][] operator / (triple[][] a, real[][] b)
{
triple[][] A=new triple[a.length][];
for(int i=0; i < a.length; ++i) {
diff --git a/graphics/asymptote/base/three_tube.asy b/graphics/asymptote/base/three_tube.asy
index 60085a7d51..5c22f4d29b 100644
--- a/graphics/asymptote/base/three_tube.asy
+++ b/graphics/asymptote/base/three_tube.asy
@@ -100,6 +100,17 @@ rmf[] rmf(triple z0, triple c0, triple c1, triple z1, real[] t, triple perp=O)
return R;
}
+
+drawfcn drawTube(triple[] g, real w, triple min, triple max) {
+ return new void(frame f, transform3 t=identity4, material[] m,
+ light light=currentlight, render render=defaultrender)
+ {
+ material m=material(m[0],light);
+ drawTube(f,t*g,w,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,
+ t*min,t*max,m.opacity == 1);
+ };
+}
+
surface tube(triple z0, triple c0, triple c1, triple z1, real w)
{
surface s;
@@ -125,13 +136,7 @@ surface tube(triple z0, triple c0, triple c1, triple z1, real w)
f(t3);
s.PRCprimitive=false;
- s.draw=new void(frame f, transform3 t=identity4, material[] m,
- light light=currentlight, render render=defaultrender)
- {
- material m=material(m[0],light);
- drawTube(f,t*g,w,m.p,m.opacity,m.shininess,m.metallic,m.fresnel0,
- t*min(s),t*max(s),m.opacity == 1);
- };
+ s.draw=drawTube(g,w,min(s),max(s));
return s;
}
@@ -153,7 +158,7 @@ struct tube
void Null(transform3) {}
void Null(transform3, bool) {}
-
+
surface[] render(path3 g, real r) {
triple z0=point(g,0);
triple c0=postcontrol(g,0);
@@ -174,7 +179,7 @@ struct tube
pair a0=threshold(z0,c0,c1);
pair a1=threshold(z1,c1,c0);
real rL=r*arclength(z0,c0,c1,z1)*tubethreshold;
- if((a0.x >= norm && rL*a0.y^2 > a0.x^8) ||
+ if((a0.x >= norm && rL*a0.y^2 > a0.x^8) ||
(a1.x >= norm && rL*a1.y^2 > a1.x^8)) {
triple m0=0.5*(z0+c0);
triple m1=0.5*(c0+c1);
@@ -214,7 +219,7 @@ struct tube
s.append(render(subpath(p,i,i+1),r));
}
}
-
+
transform3 t=scale3(r);
bool cyclic=cyclic(p);
int begin=0;
diff --git a/graphics/asymptote/base/trembling.asy b/graphics/asymptote/base/trembling.asy
index f9f0d6a747..6f696945af 100644
--- a/graphics/asymptote/base/trembling.asy
+++ b/graphics/asymptote/base/trembling.asy
@@ -17,14 +17,14 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-// COMMENTARY:
+// COMMENTARY:
-// THANKS:
+// THANKS:
-// BUGS:
+// BUGS:
// magnetic points are experimental...
-// CODE:
+// CODE:
real magneticRadius=1; // unit is bp in postscript coordinates.
real trembleFuzz(){return min(1e-3,magneticRadius/10);}
@@ -34,7 +34,7 @@ real trembleAngle=4, trembleFrequency=0.5, trembleRandom=2;
struct tremble
{
static real test=5;
-
+
real angle,frequency,random,fuzz;
pair[] single(pair[] P)
@@ -141,7 +141,7 @@ struct tremble
this.random=random;
this.fuzz=fuzz;
}
-
+
path deform(path g...pair[] magneticPoints) {
/* Return g as it was handwriting.
The postcontrols and precontrols of the nodes of g will be rotated
diff --git a/graphics/asymptote/base/v3d.asy b/graphics/asymptote/base/v3d.asy
new file mode 100644
index 0000000000..0405a5d5bc
--- /dev/null
+++ b/graphics/asymptote/base/v3d.asy
@@ -0,0 +1,643 @@
+// Supakorn "Jamie" Rassameemasuang <jamievlin@outlook.com> and
+// John C. Bowman
+
+import three;
+import v3dtypes;
+import v3dheadertypes;
+
+struct triangleGroup
+{
+ triple[] positions;
+ triple[] normals;
+ pen[] colors;
+
+ int[][] positionIndices;
+ int[][] normalIndices;
+ int[][] colorIndices;
+}
+
+struct pixel
+{
+ triple point;
+ real width;
+}
+
+struct CameraInformation
+{
+ int canvasWidth;
+ int canvasHeight;
+ bool absolute;
+
+ triple b;
+ triple B;
+ bool orthographic;
+ real angle;
+ real Zoom0;
+ pair viewportMargin;
+
+ light light;
+
+ void setCameraInfo()
+ {
+ size(canvasWidth,canvasHeight);
+ triple center=0.5*(b.z+B.z)*Z;
+
+ if(orthographic)
+ currentprojection=orthographic(Z,target=center);
+ else
+ currentprojection=perspective(Z,Y,target=center,Zoom0,degrees(angle),autoadjust=false);
+ light.specular=light.diffuse;
+ currentlight=light;
+ }
+}
+
+transform3 Align(real polar, real azimuth)
+{
+ return align(dir(degrees(polar),degrees(azimuth)));
+}
+
+struct v3dfile
+{
+ file xdrfile;
+ int version;
+ bool hasCameraInfo=false;
+ CameraInformation info;
+ bool singleprecision=false;
+
+ triple[] centers;
+ material[] materials;
+
+ surface[][][] surfaces;
+ path3[][][] paths3;
+ triangleGroup[][][] triangles;
+ pixel[][] pixels;
+
+ void initSurface(int center, int material) {
+ if(!surfaces.initialized(center))
+ surfaces[center]=new surface[][];
+ if(!surfaces[center].initialized(material))
+ surfaces[center][material]=new surface[] {new surface};
+ }
+
+ void initPath3(int center, int material) {
+ if(!paths3.initialized(center))
+ paths3[center]=new path3[][];
+ if(!paths3[center].initialized(material))
+ paths3[center][material]=new path3[];
+ }
+
+ void initTriangleGroup(int center, int material) {
+ if (!triangles.initialized(center))
+ triangles[center]=new triangleGroup[][];
+ if(!triangles[center].initialized(material))
+ triangles[center][material]=new triangleGroup[];
+ }
+
+ void initPixel(int material) {
+ if(!pixels.initialized(material))
+ pixels[material]=new pixel[];
+ }
+
+ void surface(int center, int material, patch p) {
+ initSurface(center,material);
+ surfaces[center][material][0].s.push(p);
+ }
+
+ void primitive(int center, int material, surface s) {
+ initSurface(center,material);
+ surfaces[center][material].push(s);
+ }
+
+ void path3(int center, int material, path3 p) {
+ initPath3(center,material);
+ paths3[center][material].push(p);
+ }
+
+ void triangleGroup(int center, int material, triangleGroup g) {
+ initTriangleGroup(center,material);
+ triangles[center][material].push(g);
+ }
+
+ void pixel(int material, pixel P) {
+ initPixel(material);
+ pixels[material].push(P);
+ }
+
+ void operator init(string name)
+ {
+ xdrfile=input(name, mode="xdrgz");
+ version=xdrfile;
+
+ int doubleprecision=xdrfile;
+ singleprecision=doubleprecision == 0;
+ xdrfile.singlereal(singleprecision);
+ }
+
+ int getType()
+ {
+ return xdrfile;
+ }
+
+ void setCameraInfo()
+ {
+ if(hasCameraInfo)
+ info.setCameraInfo();
+ }
+
+ pen[] readColorData(int size=4, bool alpha=true)
+ {
+ xdrfile.singlereal(true);
+
+ xdrfile.dimension(alpha ? 4 : 3);
+ pen[] newPen=new pen[size];
+ for (int i=0; i < size; ++i)
+ {
+ newPen[i]=alpha ? rgba(xdrfile) : rgb((real[]) xdrfile);
+ }
+
+ xdrfile.singlereal(singleprecision);
+
+ return newPen;
+ }
+
+ CameraInformation processHeader()
+ {
+ CameraInformation ci;
+
+ int entryCount=xdrfile;
+ for (int i=0;i<entryCount;++i)
+ {
+ int headerKey=xdrfile;
+ int headerSz=xdrfile;
+
+ if (headerKey == v3dheadertypes.canvasWidth)
+ {
+ ci.canvasWidth=xdrfile;
+ }
+ else if (headerKey == v3dheadertypes.canvasHeight)
+ {
+ ci.canvasHeight=xdrfile;
+ }
+ else if (headerKey == v3dheadertypes.absolute)
+ {
+ int val=xdrfile;
+ ci.absolute=(val != 0);
+ }
+ else if (headerKey == v3dheadertypes.minBound)
+ {
+ ci.b=xdrfile;
+ }
+ else if (headerKey == v3dheadertypes.maxBound)
+ {
+ ci.B=xdrfile;
+ }
+ else if (headerKey == v3dheadertypes.orthographic)
+ {
+ int val=xdrfile;
+ ci.orthographic=(val != 0);
+ }
+ else if (headerKey == v3dheadertypes.angleOfView)
+ {
+ ci.angle=xdrfile;
+ }
+ else if (headerKey == v3dheadertypes.initialZoom)
+ {
+ ci.Zoom0=xdrfile;
+ }
+ else if (headerKey==v3dheadertypes.viewportMargin)
+ {
+ ci.viewportMargin=xdrfile;
+ }
+ else if (headerKey==v3dheadertypes.background)
+ {
+ ci.light.background=readColorData(1)[0];
+ }
+ else if (headerKey==v3dheadertypes.light)
+ {
+ triple position=xdrfile;
+ ci.light.position.push(position);
+ ci.light.diffuse.push(rgba(readColorData(1,false)[0]));
+ }
+ else
+ {
+ xdrfile.dimension(headerSz);
+ int[] _dmp=xdrfile;
+ }
+ }
+ return ci;
+ }
+
+ material readMaterial() {
+ xdrfile.dimension(4);
+ xdrfile.singlereal(true);
+
+ pen diffusePen=rgba(xdrfile);
+ pen emissivePen=rgba(xdrfile);
+ pen specularPen=rgba(xdrfile);
+
+ xdrfile.dimension(3);
+ real[] params=xdrfile;
+ real shininess=params[0];
+ real metallic=params[1];
+ real F0=params[2];
+
+ xdrfile.singlereal(singleprecision);
+
+ return material(diffusePen,emissivePen,specularPen,1,shininess,
+ metallic,F0);
+ }
+
+ triple[][] readRawPatchData() {
+ triple[][] val;
+ xdrfile.dimension(4,4);
+ val=xdrfile;
+ return val;
+ }
+
+ triple[][] readRawTriangleData() {
+ triple[][] val;
+
+ for(int i=0; i < 4; ++i) {
+ xdrfile.dimension(i+1);
+ triple[] v=xdrfile;
+ val.push(v);
+ }
+ return val;
+ }
+
+ void readBezierPatch() {
+ triple[][] val=readRawPatchData();
+ int center=xdrfile;
+ int material=xdrfile;
+ surface(center,material,patch(val));
+ }
+
+ void readBezierTriangle() {
+ triple[][] val=readRawTriangleData();
+ int center=xdrfile;
+ int material=xdrfile;
+ surface(center,material,patch(val,triangular=true));
+ }
+
+ triple[] readCenters() {
+ int centerCount=xdrfile;
+ xdrfile.dimension(centerCount);
+ triple[] centersFetched;
+ if (centerCount>0)
+ centersFetched=xdrfile;
+ return centersFetched;
+ }
+
+ void readBezierPatchColor() {
+ triple[][] val=readRawPatchData();
+ int center=xdrfile;
+ int material=xdrfile;
+ pen[] colors=readColorData(4);
+ surface(center,material,patch(val,colors=colors));
+ }
+
+ void readBezierTriangleColor() {
+ triple[][] val=readRawTriangleData();
+ int center=xdrfile;
+ int material=xdrfile;
+ pen[] colors=readColorData(3);
+ surface(center,material,patch(val,triangular=true,colors=colors));
+ }
+
+ void readSphere() {
+ triple origin=xdrfile;
+ real radius=xdrfile;
+
+ int center=xdrfile;
+ int material=xdrfile;
+
+ surface s=shift(origin)*scale3(radius)*unitsphere;
+ s.draw=unitsphere.draw;
+ primitive(center,material,s);
+ }
+
+ void readHemisphere() {
+ triple origin=xdrfile;
+ real radius=xdrfile;
+
+ int center=xdrfile;
+ int material=xdrfile;
+
+ real polar=xdrfile;
+ real azimuth=xdrfile;
+
+ surface s=shift(origin)*Align(polar,azimuth)*scale3(radius)*unithemisphere;
+ s.draw=unithemisphere.draw;
+ primitive(center,material,s);
+ }
+
+ void readDisk() {
+ triple origin=xdrfile;
+ real radius=xdrfile;
+
+ int center=xdrfile;
+ int material=xdrfile;
+
+ real polar=xdrfile;
+ real azimuth=xdrfile;
+
+ surface s=shift(origin)*Align(polar,azimuth)*scale3(radius)*unitdisk;
+ s.draw=unitdisk.draw;
+ primitive(center,material,s);
+ }
+
+ void readPolygon(int n)
+ {
+ xdrfile.dimension(n);
+ triple[] val=xdrfile;
+
+ int center=xdrfile;
+ int material=xdrfile;
+ surface(center,material,patch(val));
+ }
+
+ void readPolygonColor(int n)
+ {
+ xdrfile.dimension(n);
+ triple[] val=xdrfile;
+
+ int center=xdrfile;
+ int material=xdrfile;
+
+ pen[] colors=readColorData(n);
+ surface(center,material,patch(val,colors=colors));
+ }
+
+ void readCylinder() {
+ triple origin=xdrfile;
+ real radius=xdrfile;
+ real height=xdrfile;
+
+ int center=xdrfile;
+ int material=xdrfile;
+
+ real polar=xdrfile;
+ real azimuth=xdrfile;
+
+ int core=xdrfile;
+
+ transform3 T=shift(origin)*Align(polar,azimuth)*
+ scale(radius,radius,height);
+ if(core != 0)
+ path3(center,material,T*(O--Z));
+
+ surface s=T*unitcylinder;
+ s.draw=unitcylinder.draw;
+ primitive(center,material,s);
+ }
+
+ void readTube() {
+ xdrfile.dimension(4);
+ triple[] g=xdrfile;
+
+ real width=xdrfile;
+ int center=xdrfile;
+ int material=xdrfile;
+
+ int core=xdrfile;
+
+ if(core != 0)
+ path3(center,material,g[0]..controls g[1] and g[2]..g[3]);
+
+ surface s=tube(g[0],g[1],g[2],g[3],width);
+ s.draw=drawTube(g,width,info.b,info.B);
+ primitive(center,material,s);
+ }
+
+ void readCurve() {
+ xdrfile.dimension(4);
+ triple[] points=xdrfile;
+
+ int center=xdrfile;
+ int material=xdrfile;
+
+ path3(center,material,
+ points[0]..controls points[1] and points[2]..points[3]);
+ }
+
+ void readLine() {
+ xdrfile.dimension(2);
+ triple[] points=xdrfile;
+
+ int center=xdrfile;
+ int material=xdrfile;
+
+ path3(center,material,points[0]--points[1]);
+ }
+
+ void readTriangles() {
+ triangleGroup g;
+
+ int nI=xdrfile;
+
+ int nP=xdrfile;
+ xdrfile.dimension(nP);
+ g.positions=xdrfile;
+
+ int nN=xdrfile;
+ xdrfile.dimension(nN);
+ g.normals=xdrfile;
+
+ int explicitNI=xdrfile;
+
+ int nC=xdrfile;
+ int explicitCI;
+ if (nC > 0) {
+ g.colors=readColorData(nC);
+ explicitCI=xdrfile;
+ }
+
+ g.positionIndices=new int[nI][3];
+ g.normalIndices=new int[nI][3];
+ int[][] colorIndices;
+ if (nC > 0)
+ g.colorIndices=new int[nI][3];
+
+ for (int i=0; i < nI; ++i) {
+ xdrfile.dimension(3);
+ g.positionIndices[i]=xdrfile;
+ if(explicitNI != 0)
+ g.normalIndices[i]=xdrfile;
+ else
+ g.normalIndices[i]=g.positionIndices[i];
+ if(nC > 0) {
+ if(explicitCI != 0)
+ g.colorIndices[i]=xdrfile;
+ else
+ g.colorIndices[i]=g.positionIndices[i];
+ } else
+ g.colorIndices[i]=g.positionIndices[i];
+ }
+ int center=xdrfile;
+ int material=xdrfile;
+ triangleGroup(center,material,g);
+ }
+
+ void readPixel() {
+ pixel P;
+ P.point=xdrfile;
+ P.width=xdrfile;
+ int material=xdrfile;
+ pixel(material,P);
+ }
+
+ void process()
+ {
+ static bool processed;
+ if(processed) return;
+
+ while (!eof(xdrfile))
+ {
+ int ty=getType();
+ if(ty == v3dtypes.header)
+ {
+ hasCameraInfo=true;
+ info=processHeader();
+ }
+ else if(ty == v3dtypes.material)
+ {
+ materials.push(readMaterial());
+ }
+ else if(ty == v3dtypes.bezierPatch)
+ {
+ readBezierPatch();
+ }
+ else if(ty == v3dtypes.bezierTriangle)
+ {
+ readBezierTriangle();
+ }
+ else if(ty == v3dtypes.bezierPatchColor)
+ {
+ readBezierPatchColor();
+ }
+ else if(ty == v3dtypes.bezierTriangleColor)
+ {
+ readBezierTriangleColor();
+ }
+ else if(ty == v3dtypes.quad)
+ {
+ readPolygon(4);
+ }
+ else if(ty == v3dtypes.quadColor)
+ {
+ readPolygonColor(4);
+ }
+ else if(ty == v3dtypes.triangle)
+ {
+ readPolygon(3);
+ }
+ else if(ty == v3dtypes.triangleColor)
+ {
+ readPolygonColor(3);
+ }
+ else if(ty == v3dtypes.sphere)
+ {
+ readSphere();
+ }
+ else if(ty == v3dtypes.halfSphere)
+ {
+ readHemisphere();
+ }
+ else if(ty == v3dtypes.cylinder)
+ {
+ readCylinder();
+ }
+ else if(ty == v3dtypes.tube)
+ {
+ readTube();
+ }
+ else if(ty == v3dtypes.disk)
+ {
+ readDisk();
+ }
+ else if(ty == v3dtypes.curve)
+ {
+ readCurve();
+ }
+ else if(ty == v3dtypes.line)
+ {
+ readLine();
+ }
+ else if(ty == v3dtypes.triangles)
+ {
+ readTriangles();
+ }
+ else if(ty == v3dtypes.centers)
+ {
+ centers=readCenters();
+ }
+ else if(ty == v3dtypes.pixel)
+ {
+ readPixel();
+ }
+ else
+ {
+ // abort("Unknown type:"+string(ty));
+ }
+ }
+ processed=true;
+ }
+}
+
+void importv3d(string name)
+{
+ if(name == stripextension(name)) name += ".v3d";
+ v3dfile xf=v3dfile(name);
+ xf.process();
+ xf.setCameraInfo();
+
+ for(int c=0; c < xf.surfaces.length; ++c) {
+ triple center=c > 0 ? xf.centers[c-1] : O;
+ render r=render(interaction(c == 0 ? Embedded : Billboard,center=center));
+ surface[][] S=xf.surfaces[c];
+ for(int m=0; m < S.length; ++m)
+ if(S.initialized(m))
+ draw(S[m],xf.materials[m],r);
+ }
+
+ for(int c=0; c < xf.paths3.length; ++c) {
+ triple center=c > 0 ? xf.centers[c-1] : O;
+ render r=render(interaction(c == 0 ? Embedded : Billboard,center=center));
+ path3[][] G=xf.paths3[c];
+ for(int m=0; m < G.length; ++m)
+ if(G.initialized(m)) {
+ material material=xf.materials[m];
+ material.p[0] += thin();
+ draw(G[m],material,r);
+ }
+ }
+
+ for(int c=0;c < xf.triangles.length; ++c) {
+ triple center=c > 0 ? xf.centers[c-1] : O;
+ render r=render(interaction(c == 0 ? Embedded : Billboard,center=center));
+ triangleGroup[][] groups=xf.triangles[c];
+ for(int m=0; m < groups.length; ++m) {
+ if(groups.initialized(m)) {
+ material material=xf.materials[m];
+ triangleGroup[] triangleGroups=groups[m];
+ for(triangleGroup g : triangleGroups) {
+ if(g.colors.length > 0)
+ draw(g.positions,g.positionIndices,g.normals,g.normalIndices,
+ g.colors,g.colorIndices,r);
+ else
+ draw(g.positions,g.positionIndices,g.normals,g.normalIndices,
+ material,r);
+ }
+ }
+ }
+ }
+
+ for(int m=0; m < xf.pixels.length; ++m) {
+ if(xf.pixels.initialized(m)) {
+ material material=xf.materials[m];
+ pixel[] pixels=xf.pixels[m];
+ for(pixel P : pixels)
+ pixel(P.point,material.p[0],P.width);
+ }
+ }
+}
diff --git a/graphics/asymptote/base/v3dheadertypes.asy b/graphics/asymptote/base/v3dheadertypes.asy
new file mode 100644
index 0000000000..765d678080
--- /dev/null
+++ b/graphics/asymptote/base/v3dheadertypes.asy
@@ -0,0 +1,66 @@
+// Enum class for v3dheadertypes
+// AUTO-GENERATED from v3dheadertypes.csv
+// Generated at 2021-12-27 12:46:04.747922
+
+struct v3dheadertypes
+{
+ int canvasWidth=1;
+// UINT Canvas width
+
+ int canvasHeight=2;
+// UINT Canvas height
+
+ int absolute=3;
+// BOOL true: absolute size; false: scale to canvas
+
+ int minBound=4;
+// TRIPLE Scene minimum bounding box corners
+
+ int maxBound=5;
+// TRIPLE Scene maximum bounding box corners
+
+ int orthographic=6;
+// BOOL true: orthographic; false: perspective
+
+ int angleOfView=7;
+// REAL Field of view angle
+
+ int initialZoom=8;
+// REAL Initial zoom
+
+ int viewportShift=9;
+// PAIR Viewport shift (for perspective projection)
+
+ int viewportMargin=10;
+// PAIR Margin around viewport
+
+ int light=11;
+// RGB Direction and color of each point light source
+
+ int background=12;
+// RGBA Background color
+
+ int zoomFactor=13;
+// REAL Zoom base factor
+
+ int zoomPinchFactor=14;
+// REAL Zoom pinch factor
+
+ int zoomPinchCap=15;
+// REAL Zoom pinch limit
+
+ int zoomStep=16;
+// REAL Zoom power step
+
+ int shiftHoldDistance=17;
+// REAL Shift-mode maximum hold distance (pixels)
+
+ int shiftWaitTime=18;
+// REAL Shift-mode hold time (milliseconds)
+
+ int vibrateTime=19;
+// REAL Shift-mode vibrate time (milliseconds)
+
+};
+
+v3dheadertypes v3dheadertypes;// End of File
diff --git a/graphics/asymptote/base/v3dtypes.asy b/graphics/asymptote/base/v3dtypes.asy
new file mode 100644
index 0000000000..b5f19cd5cd
--- /dev/null
+++ b/graphics/asymptote/base/v3dtypes.asy
@@ -0,0 +1,34 @@
+// Enum class for v3dtypes
+// AUTO-GENERATED from v3dtypes.csv
+// Generated at 2021-12-27 12:46:04.684643
+
+struct v3dtypes
+{
+ int material=1;
+ int transform=2;
+ int element=3;
+ int centers=4;
+ int header=5;
+ int line=64;
+ int triangle=65;
+ int quad=66;
+ int curve=128;
+ int bezierTriangle=129;
+ int bezierPatch=130;
+ int lineColor=192;
+ int triangleColor=193;
+ int quadColor=194;
+ int curveColor=256;
+ int bezierTriangleColor=257;
+ int bezierPatchColor=258;
+ int triangles=512;
+ int disk=1024;
+ int cylinder=1025;
+ int tube=1026;
+ int sphere=1027;
+ int halfSphere=1028;
+ int animation=2048;
+ int pixel=4096;
+};
+
+v3dtypes v3dtypes;// End of File
diff --git a/graphics/asymptote/base/webgl/asygl.js b/graphics/asymptote/base/webgl/asygl.js
index db8810f260..8e02dcfbda 100644
--- a/graphics/asymptote/base/webgl/asygl.js
+++ b/graphics/asymptote/base/webgl/asygl.js
@@ -1,6 +1,6 @@
/*@license
AsyGL: Render Bezier patches and triangles via subdivision with WebGL.
- Copyright 2019-2020: John C. Bowman and Supakorn "Jamie" Rassameemasmuang
+ Copyright 2019-2021: John C. Bowman and Supakorn "Jamie" Rassameemasmuang
University of Alberta
This program is free software; you can redistribute it and/or modify
@@ -36,4 +36,4 @@ AUTHORS OR COPYRIGHT HOLDERS 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.*/
-let vertex="\nattribute vec3 position;\n#ifdef WIDTH\nattribute float width;\n#endif\n#ifdef NORMAL\nattribute vec3 normal;\n#endif\nattribute float materialIndex;\n#ifdef COLOR\nattribute vec4 color;\n#endif\n\nuniform mat3 normMat;\nuniform mat4 viewMat;\nuniform mat4 projViewMat;\n\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\nvarying vec3 ViewPosition;\n#endif\nvarying vec3 Normal;\n#endif\nvarying vec4 diffuse;\nvarying vec3 specular;\nvarying float roughness,metallic,fresnel0;\nvarying vec4 emissive;\n\nstruct Material {\n vec4 diffuse,emissive,specular;\n vec4 parameters;\n};\n\nuniform Material Materials[Nmaterials];\n\nvoid main(void)\n{\n vec4 v=vec4(position,1.0);\n gl_Position=projViewMat*v;\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\n ViewPosition=(viewMat*v).xyz;\n#endif \n Normal=normalize(normal*normMat);\n \n Material m;\n#ifdef TRANSPARENT\n m=Materials[int(abs(materialIndex))-1];\n emissive=m.emissive;\n if(materialIndex >= 0.0) {\n diffuse=m.diffuse;\n } else {\n diffuse=color;\n#if nlights == 0\n emissive += color;\n#endif\n }\n#else\n m=Materials[int(materialIndex)];\n emissive=m.emissive;\n#ifdef COLOR\n diffuse=color;\n#if nlights == 0\n emissive += color;\n#endif\n#else\n diffuse=m.diffuse;\n#endif\n#endif\n specular=m.specular.rgb;\n vec4 parameters=m.parameters;\n roughness=1.0-parameters[0];\n metallic=parameters[1];\n fresnel0=parameters[2];\n#else\n emissive=Materials[int(materialIndex)].emissive;\n#endif\n#ifdef WIDTH\n gl_PointSize=width;\n#endif\n}\n",fragment="\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\nvarying vec3 ViewPosition;\n#endif\nvarying vec3 Normal;\nvarying vec4 diffuse;\nvarying vec3 specular;\nvarying float roughness,metallic,fresnel0;\n\nfloat Roughness2;\nvec3 normal;\n\nstruct Light {\n vec3 direction;\n vec3 color;\n};\n\nuniform Light Lights[Nlights];\n\nfloat NDF_TRG(vec3 h)\n{\n float ndoth=max(dot(normal,h),0.0);\n float alpha2=Roughness2*Roughness2;\n float denom=ndoth*ndoth*(alpha2-1.0)+1.0;\n return denom != 0.0 ? alpha2/(denom*denom) : 0.0;\n}\n \nfloat GGX_Geom(vec3 v)\n{\n float ndotv=max(dot(v,normal),0.0);\n float ap=1.0+Roughness2;\n float k=0.125*ap*ap;\n return ndotv/((ndotv*(1.0-k))+k);\n}\n \nfloat Geom(vec3 v, vec3 l)\n{\n return GGX_Geom(v)*GGX_Geom(l);\n}\n \nfloat Fresnel(vec3 h, vec3 v, float fresnel0)\n{\n float a=1.0-max(dot(h,v),0.0);\n float b=a*a;\n return fresnel0+(1.0-fresnel0)*b*b*a;\n}\n \n// physical based shading using UE4 model.\nvec3 BRDF(vec3 viewDirection, vec3 lightDirection)\n{\n vec3 lambertian=diffuse.rgb;\n vec3 h=normalize(lightDirection+viewDirection);\n \n float omegain=max(dot(viewDirection,normal),0.0);\n float omegali=max(dot(lightDirection,normal),0.0);\n \n float D=NDF_TRG(h);\n float G=Geom(viewDirection,lightDirection);\n float F=Fresnel(h,viewDirection,fresnel0);\n \n float denom=4.0*omegain*omegali;\n float rawReflectance=denom > 0.0 ? (D*G)/denom : 0.0;\n \n vec3 dielectric=mix(lambertian,rawReflectance*specular,F);\n vec3 metal=rawReflectance*diffuse.rgb;\n \n return mix(dielectric,metal,metallic);\n}\n#endif\nvarying vec4 emissive;\n \nvoid main(void)\n{\n#if defined(NORMAL) && nlights > 0\n normal=normalize(Normal);\n normal=gl_FrontFacing ? normal : -normal;\n#ifdef ORTHOGRAPHIC\n vec3 viewDir=vec3(0.0,0.0,1.0);\n#else\n vec3 viewDir=-normalize(ViewPosition);\n#endif\n Roughness2=roughness*roughness;\n vec3 color=emissive.rgb;\n for(int i=0; i < nlights; ++i) {\n Light Li=Lights[i];\n vec3 L=Li.direction;\n float cosTheta=max(dot(normal,L),0.0);\n vec3 radiance=cosTheta*Li.color;\n color += BRDF(viewDir,L)*radiance;\n }\n gl_FragColor=vec4(color,diffuse.a);\n#else\n gl_FragColor=emissive;\n#endif\n}\n";!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var i=e();for(var a in i)("object"==typeof exports?exports:t)[a]=i[a]}}("undefined"!=typeof self?self:this,(function(){return function(t){var e={};function i(a){if(e[a])return e[a].exports;var r=e[a]={i:a,l:!1,exports:{}};return t[a].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=t,i.c=e,i.d=function(t,e,a){i.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:a})},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=1)}([function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.setMatrixArrayType=function(t){e.ARRAY_TYPE=t},e.toRadian=function(t){return t*r},e.equals=function(t,e){return Math.abs(t-e)<=a*Math.max(1,Math.abs(t),Math.abs(e))};var a=e.EPSILON=1e-6;e.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,e.RANDOM=Math.random;var r=Math.PI/180},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.mat4=e.mat3=void 0;var a=n(i(2)),r=n(i(3));function n(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e.default=t,e}e.mat3=a,e.mat4=r},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.create=function(){var t=new a.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat4=function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[4],t[4]=e[5],t[5]=e[6],t[6]=e[8],t[7]=e[9],t[8]=e[10],t},e.invert=function(t,e){var i=e[0],a=e[1],r=e[2],n=e[3],s=e[4],o=e[5],h=e[6],l=e[7],c=e[8],d=c*s-o*l,m=-c*n+o*h,f=l*n-s*h,u=i*d+a*m+r*f;if(!u)return null;return u=1/u,t[0]=d*u,t[1]=(-c*a+r*l)*u,t[2]=(o*a-r*s)*u,t[3]=m*u,t[4]=(c*i-r*h)*u,t[5]=(-o*i+r*n)*u,t[6]=f*u,t[7]=(-l*i+a*h)*u,t[8]=(s*i-a*n)*u,t};var a=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e.default=t,e}(i(0))},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.create=function(){var t=new a.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.invert=function(t,e){var i=e[0],a=e[1],r=e[2],n=e[3],s=e[4],o=e[5],h=e[6],l=e[7],c=e[8],d=e[9],m=e[10],f=e[11],u=e[12],p=e[13],v=e[14],g=e[15],x=i*o-a*s,w=i*h-r*s,M=i*l-n*s,b=a*h-r*o,S=a*l-n*o,P=r*l-n*h,A=c*p-d*u,y=c*v-m*u,T=c*g-f*u,R=d*v-m*p,D=d*g-f*p,I=m*g-f*v,z=x*I-w*D+M*R+b*T-S*y+P*A;if(!z)return null;return z=1/z,t[0]=(o*I-h*D+l*R)*z,t[1]=(r*D-a*I-n*R)*z,t[2]=(p*P-v*S+g*b)*z,t[3]=(m*S-d*P-f*b)*z,t[4]=(h*T-s*I-l*y)*z,t[5]=(i*I-r*T+n*y)*z,t[6]=(v*M-u*P-g*w)*z,t[7]=(c*P-m*M+f*w)*z,t[8]=(s*D-o*T+l*A)*z,t[9]=(a*T-i*D-n*A)*z,t[10]=(u*S-p*M+g*x)*z,t[11]=(d*M-c*S-f*x)*z,t[12]=(o*y-s*R-h*A)*z,t[13]=(i*R-a*y+r*A)*z,t[14]=(p*w-u*b-v*x)*z,t[15]=(c*b-d*w+m*x)*z,t},e.multiply=r,e.translate=function(t,e,i){var a=i[0],r=i[1],n=i[2],s=void 0,o=void 0,h=void 0,l=void 0,c=void 0,d=void 0,m=void 0,f=void 0,u=void 0,p=void 0,v=void 0,g=void 0;e===t?(t[12]=e[0]*a+e[4]*r+e[8]*n+e[12],t[13]=e[1]*a+e[5]*r+e[9]*n+e[13],t[14]=e[2]*a+e[6]*r+e[10]*n+e[14],t[15]=e[3]*a+e[7]*r+e[11]*n+e[15]):(s=e[0],o=e[1],h=e[2],l=e[3],c=e[4],d=e[5],m=e[6],f=e[7],u=e[8],p=e[9],v=e[10],g=e[11],t[0]=s,t[1]=o,t[2]=h,t[3]=l,t[4]=c,t[5]=d,t[6]=m,t[7]=f,t[8]=u,t[9]=p,t[10]=v,t[11]=g,t[12]=s*a+c*r+u*n+e[12],t[13]=o*a+d*r+p*n+e[13],t[14]=h*a+m*r+v*n+e[14],t[15]=l*a+f*r+g*n+e[15]);return t},e.rotate=function(t,e,i,r){var n,s,o,h,l,c,d,m,f,u,p,v,g,x,w,M,b,S,P,A,y,T,R,D,I=r[0],z=r[1],L=r[2],N=Math.sqrt(I*I+z*z+L*L);if(Math.abs(N)<a.EPSILON)return null;I*=N=1/N,z*=N,L*=N,n=Math.sin(i),s=Math.cos(i),o=1-s,h=e[0],l=e[1],c=e[2],d=e[3],m=e[4],f=e[5],u=e[6],p=e[7],v=e[8],g=e[9],x=e[10],w=e[11],M=I*I*o+s,b=z*I*o+L*n,S=L*I*o-z*n,P=I*z*o-L*n,A=z*z*o+s,y=L*z*o+I*n,T=I*L*o+z*n,R=z*L*o-I*n,D=L*L*o+s,t[0]=h*M+m*b+v*S,t[1]=l*M+f*b+g*S,t[2]=c*M+u*b+x*S,t[3]=d*M+p*b+w*S,t[4]=h*P+m*A+v*y,t[5]=l*P+f*A+g*y,t[6]=c*P+u*A+x*y,t[7]=d*P+p*A+w*y,t[8]=h*T+m*R+v*D,t[9]=l*T+f*R+g*D,t[10]=c*T+u*R+x*D,t[11]=d*T+p*R+w*D,e!==t&&(t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15]);return t},e.fromTranslation=function(t,e){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=e[0],t[13]=e[1],t[14]=e[2],t[15]=1,t},e.fromRotation=function(t,e,i){var r,n,s,o=i[0],h=i[1],l=i[2],c=Math.sqrt(o*o+h*h+l*l);if(Math.abs(c)<a.EPSILON)return null;return o*=c=1/c,h*=c,l*=c,r=Math.sin(e),n=Math.cos(e),s=1-n,t[0]=o*o*s+n,t[1]=h*o*s+l*r,t[2]=l*o*s-h*r,t[3]=0,t[4]=o*h*s-l*r,t[5]=h*h*s+n,t[6]=l*h*s+o*r,t[7]=0,t[8]=o*l*s+h*r,t[9]=h*l*s-o*r,t[10]=l*l*s+n,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.frustum=function(t,e,i,a,r,n,s){var o=1/(i-e),h=1/(r-a),l=1/(n-s);return t[0]=2*n*o,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*n*h,t[6]=0,t[7]=0,t[8]=(i+e)*o,t[9]=(r+a)*h,t[10]=(s+n)*l,t[11]=-1,t[12]=0,t[13]=0,t[14]=s*n*2*l,t[15]=0,t},e.ortho=function(t,e,i,a,r,n,s){var o=1/(e-i),h=1/(a-r),l=1/(n-s);return t[0]=-2*o,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*h,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*l,t[11]=0,t[12]=(e+i)*o,t[13]=(r+a)*h,t[14]=(s+n)*l,t[15]=1,t};var a=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e.default=t,e}(i(0));function r(t,e,i){var a=e[0],r=e[1],n=e[2],s=e[3],o=e[4],h=e[5],l=e[6],c=e[7],d=e[8],m=e[9],f=e[10],u=e[11],p=e[12],v=e[13],g=e[14],x=e[15],w=i[0],M=i[1],b=i[2],S=i[3];return t[0]=w*a+M*o+b*d+S*p,t[1]=w*r+M*h+b*m+S*v,t[2]=w*n+M*l+b*f+S*g,t[3]=w*s+M*c+b*u+S*x,w=i[4],M=i[5],b=i[6],S=i[7],t[4]=w*a+M*o+b*d+S*p,t[5]=w*r+M*h+b*m+S*v,t[6]=w*n+M*l+b*f+S*g,t[7]=w*s+M*c+b*u+S*x,w=i[8],M=i[9],b=i[10],S=i[11],t[8]=w*a+M*o+b*d+S*p,t[9]=w*r+M*h+b*m+S*v,t[10]=w*n+M*l+b*f+S*g,t[11]=w*s+M*c+b*u+S*x,w=i[12],M=i[13],b=i[14],S=i[15],t[12]=w*a+M*o+b*d+S*p,t[13]=w*r+M*h+b*m+S*v,t[14]=w*n+M*l+b*f+S*g,t[15]=w*s+M*c+b*u+S*x,t}}])}));let canvasWidth,canvasHeight,canvasWidth0,canvasHeight0,b,B,angle,Zoom0,zoom0,viewportmargin,zoomFactor,zoomPinchFactor,zoomPinchCap,zoomStep,shiftHoldDistance,shiftWaitTime,vibrateTime,embedded,canvas,gl,alpha,offscreen,context,maxMaterials,halfCanvasWidth,halfCanvasHeight,Zoom,maxViewportWidth,maxViewportHeight,P=[],Materials=[],Lights=[],Centers=[],Background=[1,1,1,1],absolute=!1,viewportshift=[0,0],nlights=0,Nmaterials=2,materials=[],pixel=.75,zoomRemeshFactor=1.5,FillFactor=.1;const windowTrim=10;let lastZoom,H,zmin,zmax,size2,ArcballFactor,third=1/3,rotMat=mat4.create(),projMat=mat4.create(),viewMat=mat4.create(),projViewMat=mat4.create(),normMat=mat3.create(),viewMat3=mat3.create(),cjMatInv=mat4.create(),T=mat4.create(),center={x:0,y:0,z:0},shift={x:0,y:0},viewParam={xmin:0,xmax:0,ymin:0,ymax:0,zmin:0,zmax:0},remesh=!0,wireframe=0,mouseDownOrTouchActive=!1,lastMouseX=null,lastMouseY=null,touchID=null,Positions=[],Normals=[],Colors=[],Indices=[];class Material{constructor(t,e,i,a,r,n){this.diffuse=t,this.emissive=e,this.specular=i,this.shininess=a,this.metallic=r,this.fresnel0=n}setUniform(t,e){let i=i=>gl.getUniformLocation(t,"Materials["+e+"]."+i);gl.uniform4fv(i("diffuse"),new Float32Array(this.diffuse)),gl.uniform4fv(i("emissive"),new Float32Array(this.emissive)),gl.uniform4fv(i("specular"),new Float32Array(this.specular)),gl.uniform4f(i("parameters"),this.shininess,this.metallic,this.fresnel0,0)}}let indexExt,TRIANGLES,material0Data,material1Data,materialData,colorData,transparentData,triangleData,materialIndex,enumPointLight=1,enumDirectionalLight=2;class Light{constructor(t,e){this.direction=t,this.color=e}setUniform(t,e){let i=i=>gl.getUniformLocation(t,"Lights["+e+"]."+i);gl.uniform3fv(i("direction"),new Float32Array(this.direction)),gl.uniform3fv(i("color"),new Float32Array(this.color))}}function initShaders(){let t=gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS);maxMaterials=Math.floor((t-14)/4),Nmaterials=Math.min(Math.max(Nmaterials,Materials.length),maxMaterials),pixelShader=initShader(["WIDTH"]),materialShader=initShader(["NORMAL"]),colorShader=initShader(["NORMAL","COLOR"]),transparentShader=initShader(["NORMAL","COLOR","TRANSPARENT"])}function deleteShaders(){gl.deleteProgram(transparentShader),gl.deleteProgram(colorShader),gl.deleteProgram(materialShader),gl.deleteProgram(pixelShader)}function noGL(){gl||alert("Could not initialize WebGL")}function saveAttributes(){let t=window.top.document.asygl[alpha];t.gl=gl,t.nlights=Lights.length,t.Nmaterials=Nmaterials,t.maxMaterials=maxMaterials,t.pixelShader=pixelShader,t.materialShader=materialShader,t.colorShader=colorShader,t.transparentShader=transparentShader}function restoreAttributes(){let t=window.top.document.asygl[alpha];gl=t.gl,nlights=t.nlights,Nmaterials=t.Nmaterials,maxMaterials=t.maxMaterials,pixelShader=t.pixelShader,materialShader=t.materialShader,colorShader=t.colorShader,transparentShader=t.transparentShader}function initGL(){if(alpha=Background[3]<1,embedded){let t=window.top.document;null==t.asygl&&(t.asygl=Array(2)),context=canvas.getContext("2d"),offscreen=t.offscreen,offscreen||(offscreen=t.createElement("canvas"),t.offscreen=offscreen),t.asygl[alpha]&&t.asygl[alpha].gl?(restoreAttributes(),(Lights.length!=nlights||Math.min(Materials.length,maxMaterials)>Nmaterials)&&(initShaders(),saveAttributes())):(gl=offscreen.getContext("webgl",{alpha:alpha}),gl||noGL(),initShaders(),t.asygl[alpha]={},saveAttributes())}else gl=canvas.getContext("webgl",{alpha:alpha}),gl||noGL(),initShaders();indexExt=gl.getExtension("OES_element_index_uint"),TRIANGLES=gl.TRIANGLES,material0Data=new vertexBuffer(gl.POINTS),material1Data=new vertexBuffer(gl.LINES),materialData=new vertexBuffer,colorData=new vertexBuffer,transparentData=new vertexBuffer,triangleData=new vertexBuffer}function getShader(t,e,i,a=[]){let r=`#version 100\n#ifdef GL_FRAGMENT_PRECISION_HIGH\n precision highp float;\n#else\n precision mediump float;\n#endif\n #define nlights ${0==wireframe?Lights.length:0}\n\n const int Nlights=${Math.max(Lights.length,1)};\n\n #define Nmaterials ${Nmaterials}\n`;orthographic&&(r+="#define ORTHOGRAPHIC\n"),a.forEach(t=>r+="#define "+t+"\n");let n=t.createShader(i);return t.shaderSource(n,r+e),t.compileShader(n),t.getShaderParameter(n,t.COMPILE_STATUS)?n:(alert(t.getShaderInfoLog(n)),null)}function registerBuffer(t,e,i,a=gl.ARRAY_BUFFER){return t.length>0&&(0==e&&(e=gl.createBuffer(),i=!0),gl.bindBuffer(a,e),i&&gl.bufferData(a,t,gl.STATIC_DRAW)),e}function drawBuffer(t,e,i=t.indices){if(0==t.indices.length)return;let a=e!=pixelShader;setUniforms(t,e);let r=remesh||t.partial||!t.rendered;t.verticesBuffer=registerBuffer(new Float32Array(t.vertices),t.verticesBuffer,r),gl.vertexAttribPointer(positionAttribute,3,gl.FLOAT,!1,a?24:16,0),a&&Lights.length>0?gl.vertexAttribPointer(normalAttribute,3,gl.FLOAT,!1,24,12):pixel&&gl.vertexAttribPointer(widthAttribute,1,gl.FLOAT,!1,16,12),t.materialsBuffer=registerBuffer(new Int16Array(t.materialIndices),t.materialsBuffer,r),gl.vertexAttribPointer(materialAttribute,1,gl.SHORT,!1,2,0),e!=colorShader&&e!=transparentShader||(t.colorsBuffer=registerBuffer(new Uint8Array(t.colors),t.colorsBuffer,r),gl.vertexAttribPointer(colorAttribute,4,gl.UNSIGNED_BYTE,!0,0,0)),t.indicesBuffer=registerBuffer(indexExt?new Uint32Array(i):new Uint16Array(i),t.indicesBuffer,r,gl.ELEMENT_ARRAY_BUFFER),t.rendered=!0,gl.drawElements(a?wireframe?gl.LINES:t.type:gl.POINTS,i.length,indexExt?gl.UNSIGNED_INT:gl.UNSIGNED_SHORT,0)}class vertexBuffer{constructor(t){this.type=t||TRIANGLES,this.verticesBuffer=0,this.materialsBuffer=0,this.colorsBuffer=0,this.indicesBuffer=0,this.rendered=!1,this.partial=!1,this.clear()}clear(){this.vertices=[],this.materialIndices=[],this.colors=[],this.indices=[],this.nvertices=0,this.materials=[],this.materialTable=[]}vertex(t,e){return this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.materialIndices.push(materialIndex),this.nvertices++}Vertex(t,e,i=[0,0,0,0]){return this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.materialIndices.push(materialIndex),this.colors.push(i[0]),this.colors.push(i[1]),this.colors.push(i[2]),this.colors.push(i[3]),this.nvertices++}vertex0(t,e){return this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.vertices.push(e),this.materialIndices.push(materialIndex),this.nvertices++}iVertex(t,e,i,a=[0,0,0,0]){let r=6*t;this.vertices[r]=e[0],this.vertices[r+1]=e[1],this.vertices[r+2]=e[2],this.vertices[r+3]=i[0],this.vertices[r+4]=i[1],this.vertices[r+5]=i[2],this.materialIndices[t]=materialIndex;let n=4*t;this.colors[n]=a[0],this.colors[n+1]=a[1],this.colors[n+2]=a[2],this.colors[n+3]=a[3],this.indices.push(t)}append(t){append(this.vertices,t.vertices),append(this.materialIndices,t.materialIndices),append(this.colors,t.colors),appendOffset(this.indices,t.indices,this.nvertices),this.nvertices+=t.nvertices}}function append(t,e){let i=t.length,a=e.length;t.length+=a;for(let r=0;r<a;++r)t[i+r]=e[r]}function appendOffset(t,e,i){let a=t.length,r=e.length;t.length+=e.length;for(let n=0;n<r;++n)t[a+n]=e[n]+i}class Geometry{constructor(){this.data=new vertexBuffer,this.Onscreen=!1,this.m=[]}offscreen(t){let e=projViewMat,i=t[0],a=i[0],r=i[1],n=i[2],s=1/(e[3]*a+e[7]*r+e[11]*n+e[15]);this.x=this.X=(e[0]*a+e[4]*r+e[8]*n+e[12])*s,this.y=this.Y=(e[1]*a+e[5]*r+e[9]*n+e[13])*s;for(let i=1,a=t.length;i<a;++i){let a=t[i],r=a[0],n=a[1],s=a[2],o=1/(e[3]*r+e[7]*n+e[11]*s+e[15]),h=(e[0]*r+e[4]*n+e[8]*s+e[12])*o,l=(e[1]*r+e[5]*n+e[9]*s+e[13])*o;h<this.x?this.x=h:h>this.X&&(this.X=h),l<this.y?this.y=l:l>this.Y&&(this.Y=l)}return(this.X<-1.01||this.x>1.01||this.Y<-1.01||this.y>1.01)&&(this.Onscreen=!1,!0)}T(t){let e=this.c[0],i=this.c[1],a=this.c[2],r=t[0]-e,n=t[1]-i,s=t[2]-a;return[r*normMat[0]+n*normMat[3]+s*normMat[6]+e,r*normMat[1]+n*normMat[4]+s*normMat[7]+i,r*normMat[2]+n*normMat[5]+s*normMat[8]+a]}Tcorners(t,e){return[this.T(t),this.T([t[0],t[1],e[2]]),this.T([t[0],e[1],t[2]]),this.T([t[0],e[1],e[2]]),this.T([e[0],t[1],t[2]]),this.T([e[0],t[1],e[2]]),this.T([e[0],e[1],t[2]]),this.T(e)]}setMaterial(t,e){null==t.materialTable[this.MaterialIndex]&&(t.materials.length>=Nmaterials&&(t.partial=!0,e()),t.materialTable[this.MaterialIndex]=t.materials.length,t.materials.push(Materials[this.MaterialIndex])),materialIndex=t.materialTable[this.MaterialIndex]}render(){let t;if(this.setMaterialIndex(),0==this.CenterIndex?t=corners(this.Min,this.Max):(this.c=Centers[this.CenterIndex-1],t=this.Tcorners(this.Min,this.Max)),this.offscreen(t))return this.data.clear(),void this.notRendered();let e,i=this.controlpoints;if(0==this.CenterIndex){if(!remesh&&this.Onscreen)return void this.append();e=i}else{let t=i.length;e=Array(t);for(let a=0;a<t;++a)e[a]=this.T(i[a])}let a=orthographic?1:this.Min[2]/B[2],r=pixel*Math.hypot(a*(viewParam.xmax-viewParam.xmin),a*(viewParam.ymax-viewParam.ymin))/size2;this.res2=r*r,this.Epsilon=FillFactor*r,this.data.clear(),this.notRendered(),this.Onscreen=!0,this.process(e)}}class BezierPatch extends Geometry{constructor(t,e,i,a,r,n){super(),this.controlpoints=t,this.Min=a,this.Max=r,this.color=n,this.CenterIndex=e;let s=t.length;if(n){let t=n[0][3]+n[1][3]+n[2][3];this.transparent=16==s||4==s?t+n[3][3]<1020:t<765}else this.transparent=Materials[i].diffuse[3]<1;this.MaterialIndex=i,this.vertex=this.transparent?this.data.Vertex.bind(this.data):this.data.vertex.bind(this.data),this.L2norm(this.controlpoints)}setMaterialIndex(){this.transparent?this.setMaterial(transparentData,drawTransparent):this.color?this.setMaterial(colorData,drawColor):this.setMaterial(materialData,drawMaterial)}L2norm(t){let e=t[0];this.epsilon=0;let i=t.length;for(let a=1;a<i;++a)this.epsilon=Math.max(this.epsilon,abs2([t[a][0]-e[0],t[a][1]-e[1],t[a][2]-e[2]]));this.epsilon*=Number.EPSILON}processTriangle(t){let e=t[0],i=t[1],a=t[2],r=unit(cross([i[0]-e[0],i[1]-e[1],i[2]-e[2]],[a[0]-e[0],a[1]-e[1],a[2]-e[2]]));if(!this.offscreen([e,i,a])){let t,n,s;this.color?(t=this.data.Vertex(e,r,this.color[0]),n=this.data.Vertex(i,r,this.color[1]),s=this.data.Vertex(a,r,this.color[2])):(t=this.vertex(e,r),n=this.vertex(i,r),s=this.vertex(a,r)),0==wireframe?(this.data.indices.push(t),this.data.indices.push(n),this.data.indices.push(s)):(this.data.indices.push(t),this.data.indices.push(n),this.data.indices.push(n),this.data.indices.push(s),this.data.indices.push(s),this.data.indices.push(t)),this.append()}}processQuad(t){let e=t[0],i=t[1],a=t[2],r=t[3],n=cross([i[0]-e[0],i[1]-e[1],i[2]-e[2]],[a[0]-i[0],a[1]-i[1],a[2]-i[2]]),s=cross([a[0]-r[0],a[1]-r[1],a[2]-r[2]],[r[0]-e[0],r[1]-e[1],r[2]-e[2]]),o=unit([n[0]+s[0],n[1]+s[1],n[2]+s[2]]);if(!this.offscreen([e,i,a,r])){let t,n,s,h;this.color?(t=this.data.Vertex(e,o,this.color[0]),n=this.data.Vertex(i,o,this.color[1]),s=this.data.Vertex(a,o,this.color[2]),h=this.data.Vertex(r,o,this.color[3])):(t=this.vertex(e,o),n=this.vertex(i,o),s=this.vertex(a,o),h=this.vertex(r,o)),0==wireframe?(this.data.indices.push(t),this.data.indices.push(n),this.data.indices.push(s),this.data.indices.push(t),this.data.indices.push(s),this.data.indices.push(h)):(this.data.indices.push(t),this.data.indices.push(n),this.data.indices.push(n),this.data.indices.push(s),this.data.indices.push(s),this.data.indices.push(h),this.data.indices.push(h),this.data.indices.push(t)),this.append()}}curve(t,e,i,a,r){new BezierCurve([t[e],t[i],t[a],t[r]],0,materialIndex,this.Min,this.Max).render()}process(t){if(this.transparent&&1!=wireframe&&(materialIndex=this.color?-1-materialIndex:1+materialIndex),10==t.length)return this.process3(t);if(3==t.length)return this.processTriangle(t);if(4==t.length)return this.processQuad(t);if(1==wireframe)return this.curve(t,0,4,8,12),this.curve(t,12,13,14,15),this.curve(t,15,11,7,3),void this.curve(t,3,2,1,0);let e=t[0],i=t[3],a=t[12],r=t[15],n=this.normal(i,t[2],t[1],e,t[4],t[8],a);abs2(n)<this.epsilon&&(n=this.normal(i,t[2],t[1],e,t[13],t[14],r),abs2(n)<this.epsilon&&(n=this.normal(r,t[11],t[7],i,t[4],t[8],a)));let s=this.normal(e,t[4],t[8],a,t[13],t[14],r);abs2(s)<this.epsilon&&(s=this.normal(e,t[4],t[8],a,t[11],t[7],i),abs2(s)<this.epsilon&&(s=this.normal(i,t[2],t[1],e,t[13],t[14],r)));let o=this.normal(a,t[13],t[14],r,t[11],t[7],i);abs2(o)<this.epsilon&&(o=this.normal(a,t[13],t[14],r,t[2],t[1],e),abs2(o)<this.epsilon&&(o=this.normal(e,t[4],t[8],a,t[11],t[7],i)));let h=this.normal(r,t[11],t[7],i,t[2],t[1],e);if(abs2(h)<this.epsilon&&(h=this.normal(r,t[11],t[7],i,t[4],t[8],a),abs2(h)<this.epsilon&&(h=this.normal(a,t[13],t[14],r,t[2],t[1],e))),this.color){let l=this.color[0],c=this.color[1],d=this.color[2],m=this.color[3],f=this.data.Vertex(e,n,l),u=this.data.Vertex(a,s,c),p=this.data.Vertex(r,o,d),v=this.data.Vertex(i,h,m);this.Render(t,f,u,p,v,e,a,r,i,!1,!1,!1,!1,l,c,d,m)}else{let l=this.vertex(e,n),c=this.vertex(a,s),d=this.vertex(r,o),m=this.vertex(i,h);this.Render(t,l,c,d,m,e,a,r,i,!1,!1,!1,!1)}this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):this.color?colorData.append(this.data):materialData.append(this.data)}notRendered(){this.transparent?transparentData.rendered=!1:this.color?colorData.rendered=!1:materialData.rendered=!1}Render(t,e,i,a,r,n,s,o,h,l,c,d,m,f,u,p,v){let g=this.Distance(t);if(g[0]<this.res2&&g[1]<this.res2)this.offscreen([n,s,o])||(0==wireframe?(this.data.indices.push(e),this.data.indices.push(i),this.data.indices.push(a)):(this.data.indices.push(e),this.data.indices.push(i),this.data.indices.push(i),this.data.indices.push(a))),this.offscreen([n,o,h])||(0==wireframe?(this.data.indices.push(e),this.data.indices.push(a),this.data.indices.push(r)):(this.data.indices.push(a),this.data.indices.push(r),this.data.indices.push(r),this.data.indices.push(e)));else{if(this.offscreen(t))return;let x=t[0],w=t[3],M=t[12],b=t[15];if(g[0]<this.res2){let g=new Split3(x,t[1],t[2],w),S=new Split3(t[4],t[5],t[6],t[7]),P=new Split3(t[8],t[9],t[10],t[11]),A=new Split3(M,t[13],t[14],b),y=[x,g.m0,g.m3,g.m5,t[4],S.m0,S.m3,S.m5,t[8],P.m0,P.m3,P.m5,M,A.m0,A.m3,A.m5],T=[g.m5,g.m4,g.m2,w,S.m5,S.m4,S.m2,t[7],P.m5,P.m4,P.m2,t[11],A.m5,A.m4,A.m2,b],R=this.normal(y[12],y[13],y[14],y[15],y[11],y[7],y[3]);abs2(R)<=this.epsilon&&(R=this.normal(y[12],y[13],y[14],y[15],y[2],y[1],y[0]),abs2(R)<=this.epsilon&&(R=this.normal(y[0],y[4],y[8],y[12],y[11],y[7],y[3])));let D=this.normal(T[3],T[2],T[1],T[0],T[4],T[8],T[12]);abs2(D)<=this.epsilon&&(D=this.normal(T[3],T[2],T[1],T[0],T[13],T[14],T[15]),abs2(D)<=this.epsilon&&(D=this.normal(T[15],T[11],T[7],T[3],T[4],T[8],T[12])));let I=this.Epsilon,z=[.5*(s[0]+o[0]),.5*(s[1]+o[1]),.5*(s[2]+o[2])];if(!c)if(c=Straightness(M,t[13],t[14],b)<this.res2){let t=unit(this.differential(T[12],T[8],T[4],T[0]));z=[z[0]-I*t[0],z[1]-I*t[1],z[2]-I*t[2]]}else z=y[15];let L=[.5*(h[0]+n[0]),.5*(h[1]+n[1]),.5*(h[2]+n[2])];if(!m)if(m=Straightness(x,t[1],t[2],w)<this.res2){let t=unit(this.differential(y[3],y[7],y[11],y[15]));L=[L[0]-I*t[0],L[1]-I*t[1],L[2]-I*t[2]]}else L=T[0];if(f){let t=Array(4),g=Array(4);for(let e=0;e<4;++e)t[e]=.5*(u[e]+p[e]),g[e]=.5*(v[e]+f[e]);let x=this.data.Vertex(z,R,t),w=this.data.Vertex(L,D,g);this.Render(y,e,i,x,w,n,s,z,L,l,c,!1,m,f,u,t,g),this.Render(T,w,x,a,r,L,z,o,h,!1,c,d,m,g,t,p,v)}else{let t=this.vertex(z,R),f=this.vertex(L,D);this.Render(y,e,i,t,f,n,s,z,L,l,c,!1,m),this.Render(T,f,t,a,r,L,z,o,h,!1,c,d,m)}return}if(g[1]<this.res2){let g=new Split3(x,t[4],t[8],M),S=new Split3(t[1],t[5],t[9],t[13]),P=new Split3(t[2],t[6],t[10],t[14]),A=new Split3(w,t[7],t[11],b),y=[x,t[1],t[2],w,g.m0,S.m0,P.m0,A.m0,g.m3,S.m3,P.m3,A.m3,g.m5,S.m5,P.m5,A.m5],T=[g.m5,S.m5,P.m5,A.m5,g.m4,S.m4,P.m4,A.m4,g.m2,S.m2,P.m2,A.m2,M,t[13],t[14],b],R=this.normal(y[0],y[4],y[8],y[12],y[13],y[14],y[15]);abs2(R)<=this.epsilon&&(R=this.normal(y[0],y[4],y[8],y[12],y[11],y[7],y[3]),abs2(R)<=this.epsilon&&(R=this.normal(y[3],y[2],y[1],y[0],y[13],y[14],y[15])));let D=this.normal(T[15],T[11],T[7],T[3],T[2],T[1],T[0]);abs2(D)<=this.epsilon&&(D=this.normal(T[15],T[11],T[7],T[3],T[4],T[8],T[12]),abs2(D)<=this.epsilon&&(D=this.normal(T[12],T[13],T[14],T[15],T[2],T[1],T[0])));let I=this.Epsilon,z=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[2]+s[2])];if(!l)if(l=Straightness(x,t[4],t[8],M)<this.res2){let t=unit(this.differential(T[0],T[1],T[2],T[3]));z=[z[0]-I*t[0],z[1]-I*t[1],z[2]-I*t[2]]}else z=y[12];let L=[.5*(o[0]+h[0]),.5*(o[1]+h[1]),.5*(o[2]+h[2])];if(!d)if(d=Straightness(b,t[11],t[7],w)<this.res2){let t=unit(this.differential(y[15],y[14],y[13],y[12]));L=[L[0]-I*t[0],L[1]-I*t[1],L[2]-I*t[2]]}else L=T[3];if(f){let t=Array(4),g=Array(4);for(let e=0;e<4;++e)t[e]=.5*(f[e]+u[e]),g[e]=.5*(p[e]+v[e]);let x=this.data.Vertex(z,R,t),w=this.data.Vertex(L,D,g);this.Render(y,e,x,w,r,n,z,L,h,l,!1,d,m,f,t,g,v),this.Render(T,x,i,a,w,z,s,o,L,l,c,d,!1,t,u,p,g)}else{let t=this.vertex(z,R),f=this.vertex(L,D);this.Render(y,e,t,f,r,n,z,L,h,l,!1,d,m),this.Render(T,t,i,a,f,z,s,o,L,l,c,d,!1)}return}let S=new Split3(x,t[1],t[2],w),P=new Split3(t[4],t[5],t[6],t[7]),A=new Split3(t[8],t[9],t[10],t[11]),y=new Split3(M,t[13],t[14],b),T=new Split3(x,t[4],t[8],M),R=new Split3(S.m0,P.m0,A.m0,y.m0),D=new Split3(S.m3,P.m3,A.m3,y.m3),I=new Split3(S.m5,P.m5,A.m5,y.m5),z=new Split3(S.m4,P.m4,A.m4,y.m4),L=new Split3(S.m2,P.m2,A.m2,y.m2),N=new Split3(w,t[7],t[11],b),E=[x,S.m0,S.m3,S.m5,T.m0,R.m0,D.m0,I.m0,T.m3,R.m3,D.m3,I.m3,T.m5,R.m5,D.m5,I.m5],O=[T.m5,R.m5,D.m5,I.m5,T.m4,R.m4,D.m4,I.m4,T.m2,R.m2,D.m2,I.m2,M,y.m0,y.m3,y.m5],V=[I.m5,z.m5,L.m5,N.m5,I.m4,z.m4,L.m4,N.m4,I.m2,z.m2,L.m2,N.m2,y.m5,y.m4,y.m2,b],C=[S.m5,S.m4,S.m2,w,I.m0,z.m0,L.m0,N.m0,I.m3,z.m3,L.m3,N.m3,I.m5,z.m5,L.m5,N.m5],B=E[15],H=this.normal(E[0],E[4],E[8],E[12],E[13],E[14],E[15]);abs2(H)<this.epsilon&&(H=this.normal(E[0],E[4],E[8],E[12],E[11],E[7],E[3]),abs2(H)<this.epsilon&&(H=this.normal(E[3],E[2],E[1],E[0],E[13],E[14],E[15])));let _=this.normal(O[12],O[13],O[14],O[15],O[11],O[7],O[3]);abs2(_)<this.epsilon&&(_=this.normal(O[12],O[13],O[14],O[15],O[2],O[1],O[0]),abs2(_)<this.epsilon&&(_=this.normal(O[0],O[4],O[8],O[12],O[11],O[7],O[3])));let F=this.normal(V[15],V[11],V[7],V[3],V[2],V[1],V[0]);abs2(F)<this.epsilon&&(F=this.normal(V[15],V[11],V[7],V[3],V[4],V[8],V[12]),abs2(F)<this.epsilon&&(F=this.normal(V[12],V[13],V[14],V[15],V[2],V[1],V[0])));let G=this.normal(C[3],C[2],C[1],C[0],C[4],C[8],C[12]);abs2(G)<this.epsilon&&(G=this.normal(C[3],C[2],C[1],C[0],C[13],C[14],C[15]),abs2(G)<this.epsilon&&(G=this.normal(C[15],C[11],C[7],C[3],C[4],C[8],C[12])));let W=this.normal(V[3],V[2],V[1],B,V[4],V[8],V[12]),U=this.Epsilon,Z=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[2]+s[2])];if(!l)if(l=Straightness(x,t[4],t[8],M)<this.res2){let t=unit(this.differential(O[0],O[1],O[2],O[3]));Z=[Z[0]-U*t[0],Z[1]-U*t[1],Z[2]-U*t[2]]}else Z=E[12];let j=[.5*(s[0]+o[0]),.5*(s[1]+o[1]),.5*(s[2]+o[2])];if(!c)if(c=Straightness(M,t[13],t[14],b)<this.res2){let t=unit(this.differential(V[12],V[8],V[4],V[0]));j=[j[0]-U*t[0],j[1]-U*t[1],j[2]-U*t[2]]}else j=O[15];let k=[.5*(o[0]+h[0]),.5*(o[1]+h[1]),.5*(o[2]+h[2])];if(!d)if(d=Straightness(b,t[11],t[7],w)<this.res2){let t=unit(this.differential(C[15],C[14],C[13],C[12]));k=[k[0]-U*t[0],k[1]-U*t[1],k[2]-U*t[2]]}else k=V[3];let Y=[.5*(h[0]+n[0]),.5*(h[1]+n[1]),.5*(h[2]+n[2])];if(!m)if(m=Straightness(x,t[1],t[2],w)<this.res2){let t=unit(this.differential(E[3],E[7],E[11],E[15]));Y=[Y[0]-U*t[0],Y[1]-U*t[1],Y[2]-U*t[2]]}else Y=C[0];if(f){let t=Array(4),g=Array(4),x=Array(4),w=Array(4),M=Array(4);for(let e=0;e<4;++e)t[e]=.5*(f[e]+u[e]),g[e]=.5*(u[e]+p[e]),x[e]=.5*(p[e]+v[e]),w[e]=.5*(v[e]+f[e]),M[e]=.5*(t[e]+x[e]);let b=this.data.Vertex(Z,H,t),S=this.data.Vertex(j,_,g),P=this.data.Vertex(k,F,x),A=this.data.Vertex(Y,G,w),y=this.data.Vertex(B,W,M);this.Render(E,e,b,y,A,n,Z,B,Y,l,!1,!1,m,f,t,M,w),this.Render(O,b,i,S,y,Z,s,j,B,l,c,!1,!1,t,u,g,M),this.Render(V,y,S,a,P,B,j,o,k,!1,c,d,!1,M,g,p,x),this.Render(C,A,y,P,r,Y,B,k,h,!1,!1,d,m,w,M,x,v)}else{let t=this.vertex(Z,H),f=this.vertex(j,_),u=this.vertex(k,F),p=this.vertex(Y,G),v=this.vertex(B,W);this.Render(E,e,t,v,p,n,Z,B,Y,l,!1,!1,m),this.Render(O,t,i,f,v,Z,s,j,B,l,c,!1,!1),this.Render(V,v,f,a,u,B,j,o,k,!1,c,d,!1),this.Render(C,p,v,u,r,Y,B,k,h,!1,!1,d,m)}}}process3(t){if(1==wireframe)return this.curve(t,0,1,3,6),this.curve(t,6,7,8,9),void this.curve(t,9,5,2,0);let e=t[0],i=t[6],a=t[9],r=this.normal(a,t[5],t[2],e,t[1],t[3],i),n=this.normal(e,t[1],t[3],i,t[7],t[8],a),s=this.normal(i,t[7],t[8],a,t[5],t[2],e);if(this.color){let o=this.color[0],h=this.color[1],l=this.color[2],c=this.data.Vertex(e,r,o),d=this.data.Vertex(i,n,h),m=this.data.Vertex(a,s,l);this.Render3(t,c,d,m,e,i,a,!1,!1,!1,o,h,l)}else{let o=this.vertex(e,r),h=this.vertex(i,n),l=this.vertex(a,s);this.Render3(t,o,h,l,e,i,a,!1,!1,!1)}this.data.indices.length>0&&this.append()}Render3(t,e,i,a,r,n,s,o,h,l,c,d,m){if(this.Distance3(t)<this.res2)this.offscreen([r,n,s])||(0==wireframe?(this.data.indices.push(e),this.data.indices.push(i),this.data.indices.push(a)):(this.data.indices.push(e),this.data.indices.push(i),this.data.indices.push(i),this.data.indices.push(a),this.data.indices.push(a),this.data.indices.push(e)));else{if(this.offscreen(t))return;let f=t[0],u=t[1],p=t[2],v=t[3],g=t[4],x=t[5],w=t[6],M=t[7],b=t[8],S=t[9],P=[.5*(S[0]+x[0]),.5*(S[1]+x[1]),.5*(S[2]+x[2])],A=[.5*(S[0]+b[0]),.5*(S[1]+b[1]),.5*(S[2]+b[2])],y=[.5*(x[0]+p[0]),.5*(x[1]+p[1]),.5*(x[2]+p[2])],T=[.5*(b[0]+g[0]),.5*(b[1]+g[1]),.5*(b[2]+g[2])],R=[.5*(b[0]+M[0]),.5*(b[1]+M[1]),.5*(b[2]+M[2])],D=[.5*(p[0]+g[0]),.5*(p[1]+g[1]),.5*(p[2]+g[2])],I=[.5*(p[0]+f[0]),.5*(p[1]+f[1]),.5*(p[2]+f[2])],z=[.5*(g[0]+v[0]),.5*(g[1]+v[1]),.5*(g[2]+v[2])],L=[.5*(M[0]+w[0]),.5*(M[1]+w[1]),.5*(M[2]+w[2])],N=[.5*(f[0]+u[0]),.5*(f[1]+u[1]),.5*(f[2]+u[2])],E=[.5*(u[0]+v[0]),.5*(u[1]+v[1]),.5*(u[2]+v[2])],O=[.5*(v[0]+w[0]),.5*(v[1]+w[1]),.5*(v[2]+w[2])],V=[.5*(P[0]+y[0]),.5*(P[1]+y[1]),.5*(P[2]+y[2])],C=[.5*(A[0]+R[0]),.5*(A[1]+R[1]),.5*(A[2]+R[2])],B=[.5*(y[0]+I[0]),.5*(y[1]+I[1]),.5*(y[2]+I[2])],H=[.5*T[0]+.25*(g[0]+u[0]),.5*T[1]+.25*(g[1]+u[1]),.5*T[2]+.25*(g[2]+u[2])],_=[.5*(R[0]+L[0]),.5*(R[1]+L[1]),.5*(R[2]+L[2])],F=[.5*D[0]+.25*(g[0]+M[0]),.5*D[1]+.25*(g[1]+M[1]),.5*D[2]+.25*(g[2]+M[2])],G=[.25*(x[0]+g[0])+.5*z[0],.25*(x[1]+g[1])+.5*z[1],.25*(x[2]+g[2])+.5*z[2]],W=[.5*(N[0]+E[0]),.5*(N[1]+E[1]),.5*(N[2]+E[2])],U=[.5*(E[0]+O[0]),.5*(E[1]+O[1]),.5*(E[2]+O[2])],Z=[.5*(F[0]+W[0]),.5*(F[1]+W[1]),.5*(F[2]+W[2])],j=[.5*(F[0]+U[0]),.5*(F[1]+U[1]),.5*(F[2]+U[2])],k=[.5*(W[0]+U[0]),.5*(W[1]+U[1]),.5*(W[2]+U[2])],Y=[.5*(G[0]+_[0]),.5*(G[1]+_[1]),.5*(G[2]+_[2])],X=[.5*(C[0]+G[0]),.5*(C[1]+G[1]),.5*(C[2]+G[2])],q=[.5*(C[0]+_[0]),.5*(C[1]+_[1]),.5*(C[2]+_[2])],K=[.5*(V[0]+H[0]),.5*(V[1]+H[1]),.5*(V[2]+H[2])],$=[.5*(B[0]+H[0]),.5*(B[1]+H[1]),.5*(B[2]+H[2])],Q=[.5*(V[0]+B[0]),.5*(V[1]+B[1]),.5*(V[2]+B[2])],J=[f,N,I,W,[.5*(D[0]+N[0]),.5*(D[1]+N[1]),.5*(D[2]+N[2])],B,k,Z,$,Q],tt=[k,U,j,O,[.5*(z[0]+L[0]),.5*(z[1]+L[1]),.5*(z[2]+L[2])],Y,w,L,_,q],et=[Q,K,V,X,[.5*(P[0]+T[0]),.5*(P[1]+T[1]),.5*(P[2]+T[2])],P,q,C,A,S],it=[q,X,Y,K,[.25*(y[0]+R[0]+E[0]+g[0]),.25*(y[1]+R[1]+E[1]+g[1]),.25*(y[2]+R[2]+E[2]+g[2])],j,Q,$,Z,k],at=this.normal(k,j,Y,q,X,K,Q),rt=this.normal(q,X,K,Q,$,Z,k),nt=this.normal(Q,$,Z,k,j,Y,q),st=this.Epsilon,ot=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[2]+s[2])];if(!o)if(o=Straightness(w,M,b,S)<this.res2){let t=unit(this.sumdifferential(it[0],it[2],it[5],it[9],it[1],it[3],it[6]));ot=[ot[0]-st*t[0],ot[1]-st*t[1],ot[2]-st*t[2]]}else ot=q;let ht=[.5*(s[0]+r[0]),.5*(s[1]+r[1]),.5*(s[2]+r[2])];if(!h)if(h=Straightness(f,p,x,S)<this.res2){let t=unit(this.sumdifferential(it[6],it[3],it[1],it[0],it[7],it[8],it[9]));ht=[ht[0]-st*t[0],ht[1]-st*t[1],ht[2]-st*t[2]]}else ht=Q;let lt=[.5*(r[0]+n[0]),.5*(r[1]+n[1]),.5*(r[2]+n[2])];if(!l)if(l=Straightness(f,u,v,w)<this.res2){let t=unit(this.sumdifferential(it[9],it[8],it[7],it[6],it[5],it[2],it[0]));lt=[lt[0]-st*t[0],lt[1]-st*t[1],lt[2]-st*t[2]]}else lt=k;if(c){let t=Array(4),f=Array(4),u=Array(4);for(let e=0;e<4;++e)t[e]=.5*(d[e]+m[e]),f[e]=.5*(m[e]+c[e]),u[e]=.5*(c[e]+d[e]);let p=this.data.Vertex(ot,at,t),v=this.data.Vertex(ht,rt,f),g=this.data.Vertex(lt,nt,u);this.Render3(J,e,g,v,r,lt,ht,!1,h,l,c,u,f),this.Render3(tt,g,i,p,lt,n,ot,o,!1,l,u,d,t),this.Render3(et,v,p,a,ht,ot,s,o,h,!1,f,t,m),this.Render3(it,p,v,g,ot,ht,lt,!1,!1,!1,t,f,u)}else{let t=this.vertex(ot,at),c=this.vertex(ht,rt),d=this.vertex(lt,nt);this.Render3(J,e,d,c,r,lt,ht,!1,h,l),this.Render3(tt,d,i,t,lt,n,ot,o,!1,l),this.Render3(et,c,t,a,ht,ot,s,o,h,!1),this.Render3(it,t,c,d,ot,ht,lt,!1,!1,!1)}}}Distance(t){let e=t[0],i=t[3],a=t[12],r=t[15],n=Flatness(e,a,i,r);n=Math.max(Straightness(e,t[4],t[8],a)),n=Math.max(n,Straightness(t[1],t[5],t[9],t[13])),n=Math.max(n,Straightness(i,t[7],t[11],r)),n=Math.max(n,Straightness(t[2],t[6],t[10],t[14]));let s=Flatness(e,i,a,r);return s=Math.max(s,Straightness(e,t[1],t[2],i)),s=Math.max(s,Straightness(t[4],t[5],t[6],t[7])),s=Math.max(s,Straightness(t[8],t[9],t[10],t[11])),s=Math.max(s,Straightness(a,t[13],t[14],r)),[n,s]}Distance3(t){let e=t[0],i=t[4],a=t[6],r=t[9],n=abs2([(e[0]+a[0]+r[0])*third-i[0],(e[1]+a[1]+r[1])*third-i[1],(e[2]+a[2]+r[2])*third-i[2]]);return n=Math.max(n,Straightness(e,t[1],t[3],a)),n=Math.max(n,Straightness(e,t[2],t[5],r)),Math.max(n,Straightness(a,t[7],t[8],r))}differential(t,e,i,a){let r=[3*(e[0]-t[0]),3*(e[1]-t[1]),3*(e[2]-t[2])];return abs2(r)>this.epsilon?r:(r=bezierPP(t,e,i),abs2(r)>this.epsilon?r:bezierPPP(t,e,i,a))}sumdifferential(t,e,i,a,r,n,s){let o=this.differential(t,e,i,a),h=this.differential(t,r,n,s);return[o[0]+h[0],o[1]+h[1],o[2]+h[2]]}normal(t,e,i,a,r,n,s){let o=3*(r[0]-a[0]),h=3*(r[1]-a[1]),l=3*(r[2]-a[2]),c=3*(i[0]-a[0]),d=3*(i[1]-a[1]),m=3*(i[2]-a[2]),f=[h*m-l*d,l*c-o*m,o*d-h*c];if(abs2(f)>this.epsilon)return f;let u=[c,d,m],p=[o,h,l],v=bezierPP(a,i,e),g=bezierPP(a,r,n),x=cross(g,u),w=cross(p,v);if(f=[x[0]+w[0],x[1]+w[1],x[2]+w[2]],abs2(f)>this.epsilon)return f;let M=bezierPPP(a,i,e,t),b=bezierPPP(a,r,n,s);x=cross(p,M),w=cross(b,u);let S=cross(g,v);return f=[x[0]+w[0]+S[0],x[1]+w[1]+S[1],x[2]+w[2]+S[2]],abs2(f)>this.epsilon?f:(x=cross(b,v),w=cross(g,M),f=[x[0]+w[0],x[1]+w[1],x[2]+w[2]],abs2(f)>this.epsilon?f:cross(b,M))}}class BezierCurve extends Geometry{constructor(t,e,i,a,r){super(),this.controlpoints=t,this.Min=a,this.Max=r,this.CenterIndex=e,this.MaterialIndex=i}setMaterialIndex(){this.setMaterial(material1Data,drawMaterial1)}processLine(t){let e=t[0],i=t[1];if(!this.offscreen([e,i])){let t=[0,0,1];this.data.indices.push(this.data.vertex(e,t)),this.data.indices.push(this.data.vertex(i,t)),this.append()}}process(t){if(2==t.length)return this.processLine(t);let e=t[0],i=t[1],a=t[2],r=t[3],n=this.normal(bezierP(e,i),bezierPP(e,i,a)),s=this.normal(bezierP(a,r),bezierPP(r,a,i)),o=this.data.vertex(e,n),h=this.data.vertex(r,s);this.Render(t,o,h),this.data.indices.length>0&&this.append()}append(){material1Data.append(this.data)}notRendered(){material1Data.rendered=!1}Render(t,e,i){let a=t[0],r=t[1],n=t[2],s=t[3];if(Straightness(a,r,n,s)<this.res2)this.offscreen([a,s])||(this.data.indices.push(e),this.data.indices.push(i));else{if(this.offscreen(t))return;let o=[.5*(a[0]+r[0]),.5*(a[1]+r[1]),.5*(a[2]+r[2])],h=[.5*(r[0]+n[0]),.5*(r[1]+n[1]),.5*(r[2]+n[2])],l=[.5*(n[0]+s[0]),.5*(n[1]+s[1]),.5*(n[2]+s[2])],c=[.5*(o[0]+h[0]),.5*(o[1]+h[1]),.5*(o[2]+h[2])],d=[.5*(h[0]+l[0]),.5*(h[1]+l[1]),.5*(h[2]+l[2])],m=[.5*(c[0]+d[0]),.5*(c[1]+d[1]),.5*(c[2]+d[2])],f=[a,o,c,m],u=[m,d,l,s],p=this.normal(bezierPh(a,r,n,s),bezierPPh(a,r,n,s)),v=this.data.vertex(m,p);this.Render(f,e,v),this.Render(u,v,i)}}normal(t,e){let i=dot(t,t),a=dot(t,e);return[i*e[0]-a*t[0],i*e[1]-a*t[1],i*e[2]-a*t[2]]}}class Pixel extends Geometry{constructor(t,e,i,a,r){super(),this.controlpoint=t,this.width=e,this.CenterIndex=0,this.MaterialIndex=i,this.Min=a,this.Max=r}setMaterialIndex(){this.setMaterial(material0Data,drawMaterial0)}process(t){this.data.indices.push(this.data.vertex0(this.controlpoint,this.width)),this.append()}append(){material0Data.append(this.data)}notRendered(){material0Data.rendered=!1}}class Triangles extends Geometry{constructor(t,e,i){super(),this.CenterIndex=0,this.MaterialIndex=t,this.Min=e,this.Max=i,this.Positions=Positions,this.Normals=Normals,this.Colors=Colors,this.Indices=Indices,Positions=[],Normals=[],Colors=[],Indices=[],this.transparent=Materials[t].diffuse[3]<1}setMaterialIndex(){this.transparent?this.setMaterial(transparentData,drawTransparent):this.setMaterial(triangleData,drawTriangle)}process(t){materialIndex=this.Colors.length>0?-1-materialIndex:1+materialIndex;for(let t=0,e=this.Indices.length;t<e;++t){let e=this.Indices[t],i=e[0],a=this.Positions[i[0]],r=this.Positions[i[1]],n=this.Positions[i[2]];if(!this.offscreen([a,r,n])){let t=e.length>1?e[1]:i;if(t&&0!=t.length||(t=i),this.Colors.length>0){let s=e.length>2?e[2]:i;s&&0!=s.length||(s=i);let o=this.Colors[s[0]],h=this.Colors[s[1]],l=this.Colors[s[2]];this.transparent|=o[3]+h[3]+l[3]<765,0==wireframe?(this.data.iVertex(i[0],a,this.Normals[t[0]],o),this.data.iVertex(i[1],r,this.Normals[t[1]],h),this.data.iVertex(i[2],n,this.Normals[t[2]],l)):(this.data.iVertex(i[0],a,this.Normals[t[0]],o),this.data.iVertex(i[1],r,this.Normals[t[1]],h),this.data.iVertex(i[1],r,this.Normals[t[1]],h),this.data.iVertex(i[2],n,this.Normals[t[2]],l),this.data.iVertex(i[2],n,this.Normals[t[2]],l),this.data.iVertex(i[0],a,this.Normals[t[0]],o))}else 0==wireframe?(this.data.iVertex(i[0],a,this.Normals[t[0]]),this.data.iVertex(i[1],r,this.Normals[t[1]]),this.data.iVertex(i[2],n,this.Normals[t[2]])):(this.data.iVertex(i[0],a,this.Normals[t[0]]),this.data.iVertex(i[1],r,this.Normals[t[1]]),this.data.iVertex(i[1],r,this.Normals[t[1]]),this.data.iVertex(i[2],n,this.Normals[t[2]]),this.data.iVertex(i[2],n,this.Normals[t[2]]),this.data.iVertex(i[0],a,this.Normals[t[0]]))}}this.data.nvertices=this.Positions.length,this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):triangleData.append(this.data)}notRendered(){this.transparent?transparentData.rendered=!1:triangleData.rendered=!1}}function redraw(){initProjection(),setProjection(),remesh=!0,draw()}function home(){mat4.identity(rotMat),redraw()}let positionAttribute=0,normalAttribute=1,materialAttribute=2,colorAttribute=3,widthAttribute=4;function initShader(t=[]){let e=getShader(gl,vertex,gl.VERTEX_SHADER,t),i=getShader(gl,fragment,gl.FRAGMENT_SHADER,t),a=gl.createProgram();return gl.attachShader(a,e),gl.attachShader(a,i),gl.bindAttribLocation(a,positionAttribute,"position"),gl.bindAttribLocation(a,normalAttribute,"normal"),gl.bindAttribLocation(a,materialAttribute,"materialIndex"),gl.bindAttribLocation(a,colorAttribute,"color"),gl.bindAttribLocation(a,widthAttribute,"width"),gl.linkProgram(a),gl.getProgramParameter(a,gl.LINK_STATUS)||alert("Could not initialize shaders"),a}class Split3{constructor(t,e,i,a){this.m0=[.5*(t[0]+e[0]),.5*(t[1]+e[1]),.5*(t[2]+e[2])];let r=.5*(e[0]+i[0]),n=.5*(e[1]+i[1]),s=.5*(e[2]+i[2]);this.m2=[.5*(i[0]+a[0]),.5*(i[1]+a[1]),.5*(i[2]+a[2])],this.m3=[.5*(this.m0[0]+r),.5*(this.m0[1]+n),.5*(this.m0[2]+s)],this.m4=[.5*(r+this.m2[0]),.5*(n+this.m2[1]),.5*(s+this.m2[2])],this.m5=[.5*(this.m3[0]+this.m4[0]),.5*(this.m3[1]+this.m4[1]),.5*(this.m3[2]+this.m4[2])]}}function unit(t){let e=1/(Math.sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2])||1);return[t[0]*e,t[1]*e,t[2]*e]}function abs2(t){return t[0]*t[0]+t[1]*t[1]+t[2]*t[2]}function dot(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function cross(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function bezierP(t,e){return[e[0]-t[0],e[1]-t[1],e[2]-t[2]]}function bezierPP(t,e,i){return[3*(t[0]+i[0])-6*e[0],3*(t[1]+i[1])-6*e[1],3*(t[2]+i[2])-6*e[2]]}function bezierPPP(t,e,i,a){return[a[0]-t[0]+3*(e[0]-i[0]),a[1]-t[1]+3*(e[1]-i[1]),a[2]-t[2]+3*(e[2]-i[2])]}function bezierPh(t,e,i,a){return[i[0]+a[0]-t[0]-e[0],i[1]+a[1]-t[1]-e[1],i[2]+a[2]-t[2]-e[2]]}function bezierPPh(t,e,i,a){return[3*t[0]-5*e[0]+i[0]+a[0],3*t[1]-5*e[1]+i[1]+a[1],3*t[2]-5*e[2]+i[2]+a[2]]}function Straightness(t,e,i,a){let r=[third*(a[0]-t[0]),third*(a[1]-t[1]),third*(a[2]-t[2])];return Math.max(abs2([e[0]-r[0]-t[0],e[1]-r[1]-t[1],e[2]-r[2]-t[2]]),abs2([a[0]-r[0]-i[0],a[1]-r[1]-i[1],a[2]-r[2]-i[2]]))}function Flatness(t,e,i,a){let r=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],n=[a[0]-i[0],a[1]-i[1],a[2]-i[2]];return Math.max(abs2(cross(r,unit(n))),abs2(cross(n,unit(r))))/9}function corners(t,e){return[t,[t[0],t[1],e[2]],[t[0],e[1],t[2]],[t[0],e[1],e[2]],[e[0],t[1],t[2]],[e[0],t[1],e[2]],[e[0],e[1],t[2]],e]}function minbound(t){return[Math.min(t[0][0],t[1][0],t[2][0],t[3][0],t[4][0],t[5][0],t[6][0],t[7][0]),Math.min(t[0][1],t[1][1],t[2][1],t[3][1],t[4][1],t[5][1],t[6][1],t[7][1]),Math.min(t[0][2],t[1][2],t[2][2],t[3][2],t[4][2],t[5][2],t[6][2],t[7][2])]}function maxbound(t){return[Math.max(t[0][0],t[1][0],t[2][0],t[3][0],t[4][0],t[5][0],t[6][0],t[7][0]),Math.max(t[0][1],t[1][1],t[2][1],t[3][1],t[4][1],t[5][1],t[6][1],t[7][1]),Math.max(t[0][2],t[1][2],t[2][2],t[3][2],t[4][2],t[5][2],t[6][2],t[7][2])]}function COBTarget(t,e){mat4.fromTranslation(T,[center.x,center.y,center.z]),mat4.invert(cjMatInv,T),mat4.multiply(t,e,cjMatInv),mat4.multiply(t,T,t)}function setUniforms(t,e){let i=e==pixelShader;gl.useProgram(e),gl.enableVertexAttribArray(positionAttribute),i&&gl.enableVertexAttribArray(widthAttribute);let a=!i&&Lights.length>0;if(a&&gl.enableVertexAttribArray(normalAttribute),gl.enableVertexAttribArray(materialAttribute),e.projViewMatUniform=gl.getUniformLocation(e,"projViewMat"),e.viewMatUniform=gl.getUniformLocation(e,"viewMat"),e.normMatUniform=gl.getUniformLocation(e,"normMat"),e!=colorShader&&e!=transparentShader||gl.enableVertexAttribArray(colorAttribute),a)for(let t=0;t<Lights.length;++t)Lights[t].setUniform(e,t);for(let i=0;i<t.materials.length;++i)t.materials[i].setUniform(e,i);gl.uniformMatrix4fv(e.projViewMatUniform,!1,projViewMat),gl.uniformMatrix4fv(e.viewMatUniform,!1,viewMat),gl.uniformMatrix3fv(e.normMatUniform,!1,normMat)}function handleMouseDown(t){zoomEnabled||enableZoom(),mouseDownOrTouchActive=!0,lastMouseX=t.clientX,lastMouseY=t.clientY}let pinchStart,touchStartTime,pinch=!1;function pinchDistance(t){return Math.hypot(t[0].pageX-t[1].pageX,t[0].pageY-t[1].pageY)}function handleTouchStart(t){t.preventDefault(),zoomEnabled||enableZoom();let e=t.targetTouches;swipe=rotate=pinch=!1,zooming||(1!=e.length||mouseDownOrTouchActive||(touchStartTime=(new Date).getTime(),touchId=e[0].identifier,lastMouseX=e[0].pageX,lastMouseY=e[0].pageY),2!=e.length||mouseDownOrTouchActive||(touchId=e[0].identifier,pinchStart=pinchDistance(e),pinch=!0))}function handleMouseUpOrTouchEnd(t){mouseDownOrTouchActive=!1}function rotateScene(t,e,i,a,r){if(t==i&&e==a)return;let[n,s]=arcball([t,-e],[i,-a]);mat4.fromRotation(T,2*r*ArcballFactor*n/Zoom,s),mat4.multiply(rotMat,T,rotMat)}function shiftScene(t,e,i,a){let r=1/Zoom;shift.x+=(i-t)*r*halfCanvasWidth,shift.y-=(a-e)*r*halfCanvasHeight}function panScene(t,e,i,a){orthographic?shiftScene(t,e,i,a):(center.x+=(i-t)*(viewParam.xmax-viewParam.xmin),center.y-=(a-e)*(viewParam.ymax-viewParam.ymin))}function updateViewMatrix(){COBTarget(viewMat,rotMat),mat4.translate(viewMat,viewMat,[center.x,center.y,0]),mat3.fromMat4(viewMat3,viewMat),mat3.invert(normMat,viewMat3),mat4.multiply(projViewMat,projMat,viewMat)}function capzoom(){let t=Math.sqrt(Number.MAX_VALUE),e=1/t;Zoom<=e&&(Zoom=e),Zoom>=t&&(Zoom=t),(zoomRemeshFactor*Zoom<lastZoom||Zoom>zoomRemeshFactor*lastZoom)&&(remesh=!0,lastZoom=Zoom)}function zoomImage(t){let e=zoomStep*halfCanvasHeight*t;const i=Math.log(.1*Number.MAX_VALUE)/Math.log(zoomFactor);Math.abs(e)<i&&(Zoom*=zoomFactor**e,capzoom())}function normMouse(t){let e=t[0],i=t[1],a=Math.hypot(e,i);return a>1&&(denom=1/a,e*=denom,i*=denom),[e,i,Math.sqrt(Math.max(1-i*i-e*e,0))]}function arcball(t,e){let i=normMouse(t),a=normMouse(e),r=dot(i,a);return[r>1?0:r<-1?pi:Math.acos(r),unit(cross(i,a))]}function zoomScene(t,e,i,a){zoomImage(e-a)}const DRAGMODE_ROTATE=1,DRAGMODE_SHIFT=2,DRAGMODE_ZOOM=3,DRAGMODE_PAN=4;function processDrag(t,e,i,a=1){let r;switch(i){case 1:r=rotateScene;break;case 2:r=shiftScene;break;case 3:r=zoomScene;break;case 4:r=panScene;break;default:r=(t,e,i,a)=>{}}r((lastMouseX-halfCanvasWidth)/halfCanvasWidth,(lastMouseY-halfCanvasHeight)/halfCanvasHeight,(t-halfCanvasWidth)/halfCanvasWidth,(e-halfCanvasHeight)/halfCanvasHeight,a),lastMouseX=t,lastMouseY=e,setProjection(),draw()}let zoomEnabled=0;function enableZoom(){zoomEnabled=1,canvas.addEventListener("wheel",handleMouseWheel,!1)}function disableZoom(){zoomEnabled=0,canvas.removeEventListener("wheel",handleMouseWheel,!1)}function handleKey(t){if(zoomEnabled||enableZoom(),embedded&&zoomEnabled&&27==t.keyCode)return void disableZoom();let e=[];switch(t.key){case"x":e=[1,0,0];break;case"y":e=[0,1,0];break;case"z":e=[0,0,1];break;case"h":home();break;case"m":++wireframe,3==wireframe&&(wireframe=0),2!=wireframe&&(embedded||deleteShaders(),initShaders()),remesh=!0,draw();break;case"+":case"=":case">":expand();break;case"-":case"_":case"<":shrink()}e.length>0&&(mat4.rotate(rotMat,rotMat,.1,e),updateViewMatrix(),draw())}function setZoom(){capzoom(),setProjection(),draw()}function handleMouseWheel(t){t.preventDefault(),t.deltaY<0?Zoom*=zoomFactor:Zoom/=zoomFactor,setZoom()}function handleMouseMove(t){if(!mouseDownOrTouchActive)return;let e,i=t.clientX,a=t.clientY;e=t.getModifierState("Control")?2:t.getModifierState("Shift")?3:t.getModifierState("Alt")?4:1,processDrag(i,a,e)}let zooming=!1,swipe=!1,rotate=!1;function handleTouchMove(t){if(t.preventDefault(),zooming)return;let e=t.targetTouches;if(!pinch&&1==e.length&&touchId==e[0].identifier){let t=e[0].pageX,i=e[0].pageY,a=t-lastMouseX,r=i-lastMouseY,n=a*a+r*r<=shiftHoldDistance*shiftHoldDistance;if(n&&!swipe&&!rotate&&(new Date).getTime()-touchStartTime>shiftWaitTime&&(navigator.vibrate&&window.navigator.vibrate(vibrateTime),swipe=!0),swipe)processDrag(t,i,2);else if(!n){rotate=!0,processDrag(e[0].pageX,e[0].pageY,1,.5)}}if(pinch&&!swipe&&2==e.length&&touchId==e[0].identifier){let t=pinchDistance(e),i=t-pinchStart;zooming=!0,i*=zoomPinchFactor,i>zoomPinchCap&&(i=zoomPinchCap),i<-zoomPinchCap&&(i=-zoomPinchCap),zoomImage(i/size2),pinchStart=t,swipe=rotate=zooming=!1,setProjection(),draw()}}let pixelShader,materialShader,colorShader,transparentShader,zbuffer=[];function transformVertices(t){let e=viewMat[2],i=viewMat[6],a=viewMat[10];zbuffer.length=t.length;for(let r=0;r<t.length;++r){let n=6*r;zbuffer[r]=e*t[n]+i*t[n+1]+a*t[n+2]}}function drawMaterial0(){drawBuffer(material0Data,pixelShader),material0Data.clear()}function drawMaterial1(){drawBuffer(material1Data,materialShader),material1Data.clear()}function drawMaterial(){drawBuffer(materialData,materialShader),materialData.clear()}function drawColor(){drawBuffer(colorData,colorShader),colorData.clear()}function drawTriangle(){drawBuffer(triangleData,transparentShader),triangleData.rendered=!1,triangleData.clear()}function drawTransparent(){let t=transparentData.indices;if(wireframe>0)return drawBuffer(transparentData,transparentShader,t),void transparentData.clear();if(t.length>0){transformVertices(transparentData.vertices);let e=t.length/3,i=Array(e).fill().map((t,e)=>e);i.sort((function(e,i){let a=3*e;Ia=t[a],Ib=t[a+1],Ic=t[a+2];let r=3*i;return IA=t[r],IB=t[r+1],IC=t[r+2],zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic]<zbuffer[IA]+zbuffer[IB]+zbuffer[IC]?-1:1}));let a=Array(t.length);for(let r=0;r<e;++r){let e=3*i[r];a[3*r]=t[e],a[3*r+1]=t[e+1],a[3*r+2]=t[e+2]}gl.depthMask(!1),drawBuffer(transparentData,transparentShader,a),transparentData.rendered=!1,gl.depthMask(!0)}transparentData.clear()}function drawBuffers(){drawMaterial0(),drawMaterial1(),drawMaterial(),drawColor(),drawTriangle(),drawTransparent()}function draw(){embedded&&(offscreen.width=canvasWidth,offscreen.height=canvasHeight,setViewport()),gl.clearColor(Background[0],Background[1],Background[2],Background[3]),gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);for(let t=0;t<P.length;++t)P[t].render();drawBuffers(),embedded&&(context.clearRect(0,0,canvasWidth,canvasHeight),context.drawImage(offscreen,0,0)),0==wireframe&&(remesh=!1)}function setDimensions(t,e,i,a){let r=t/e,n=1/Zoom,s=(i/t+viewportshift[0])*Zoom,o=(a/e+viewportshift[1])*Zoom;if(orthographic){let t=B[0]-b[0],e=B[1]-b[1];if(t<e*r){let t=.5*e*r*n,i=2*t*s,a=e*n*o;viewParam.xmin=-t-i,viewParam.xmax=t-i,viewParam.ymin=b[1]*n-a,viewParam.ymax=B[1]*n-a}else{let e=.5*t/(r*Zoom),i=t*n*s,a=2*e*o;viewParam.xmin=b[0]*n-i,viewParam.xmax=B[0]*n-i,viewParam.ymin=-e-a,viewParam.ymax=e-a}}else{let t=H*n,e=t*r,i=2*e*s,a=2*t*o;viewParam.xmin=-e-i,viewParam.xmax=e-i,viewParam.ymin=-t-a,viewParam.ymax=t-a}}function setProjection(){setDimensions(canvasWidth,canvasHeight,shift.x,shift.y),(orthographic?mat4.ortho:mat4.frustum)(projMat,viewParam.xmin,viewParam.xmax,viewParam.ymin,viewParam.ymax,-viewParam.zmax,-viewParam.zmin),updateViewMatrix()}function initProjection(){H=-Math.tan(.5*angle)*B[2],center.x=center.y=0,center.z=.5*(b[2]+B[2]),lastZoom=Zoom=zoom0,viewParam.zmin=b[2],viewParam.zmax=B[2],shift.x=shift.y=0}function setViewport(){gl.viewportWidth=canvasWidth,gl.viewportHeight=canvasHeight,gl.viewport(.5*(canvas.width-canvasWidth),.5*(canvas.height-canvasHeight),canvasWidth,canvasHeight),gl.scissor(0,0,canvas.width,canvas.height)}function setCanvas(){embedded&&(canvas.width=offscreen.width=canvasWidth,canvas.height=offscreen.height=canvasHeight),size2=Math.hypot(canvasWidth,canvasHeight),halfCanvasWidth=.5*canvas.width,halfCanvasHeight=.5*canvas.height,ArcballFactor=1+8*Math.hypot(viewportmargin[0],viewportmargin[1])/size2}function setsize(t,e){t>maxViewportWidth&&(t=maxViewportWidth),e>maxViewportHeight&&(e=maxViewportHeight),shift.x*=t/canvasWidth,shift.y*=e/canvasHeight,canvasWidth=t,canvasHeight=e,setCanvas(),setViewport(),setProjection(),remesh=!0}function resize(){if(zoom0=Zoom0,absolute&&!embedded)canvasWidth=canvasWidth0*window.devicePixelRatio,canvasHeight=canvasHeight0*window.devicePixelRatio;else{let t=canvasWidth0/canvasHeight0;canvasWidth=Math.max(window.innerWidth-10,10),canvasHeight=Math.max(window.innerHeight-10,10),!orthographic&&canvasWidth<canvasHeight*t&&(zoom0*=canvasWidth/(canvasHeight*t))}canvas.width=canvasWidth,canvas.height=canvasHeight;window.innerWidth,window.innerHeight;viewportshift[0]/=zoom0,viewportshift[1]/=zoom0,setsize(canvasWidth,canvasHeight),redraw()}function expand(){Zoom*=zoomFactor,setZoom()}function shrink(){Zoom/=zoomFactor,setZoom()}class Align{constructor(t,e){if(this.center=t,e){let t=e[0],i=e[1];this.ct=Math.cos(t),this.st=Math.sin(t),this.cp=Math.cos(i),this.sp=Math.sin(i)}}T0(t){return[t[0]+this.center[0],t[1]+this.center[1],t[2]+this.center[2]]}T(t){let e=t[0],i=t[1],a=t[2],r=e*this.ct+a*this.st;return[r*this.cp-i*this.sp+this.center[0],r*this.sp+i*this.cp+this.center[1],-e*this.st+a*this.ct+this.center[2]]}}function Tcorners(t,e,i){let a=[t(e),t([e[0],e[1],i[2]]),t([e[0],i[1],e[2]]),t([e[0],i[1],i[2]]),t([i[0],e[1],e[2]]),t([i[0],e[1],i[2]]),t([i[0],i[1],e[2]]),t(i)];return[minbound(a),maxbound(a)]}function sphere(t,e,i,r,n){let s,o,h,l,c,d,m=.524670512339254,f=.595936986722291,u=.954967051233925,p=.0820155480083437,v=.996685028842544,g=.0549670512339254,x=.998880711874577,w=.0405017186586849,M=[[[1,0,0],[1,0,m],[f,0,u],[p,0,v],[1,a,0],[1,a,m],[f,a*f,u],[p,a*p,v],[a,1,0],[a,1,m],[a*f,f,u],[a*p,p,v],[0,1,0],[0,1,m],[0,f,u],[0,p,v]],[[p,0,v],[p,a*p,v],[g,0,x],[a*p,p,v],[w,w,1],[.05*a,0,1],[0,p,v],[0,g,x],[0,.05*a,1],[0,0,1]]],b=new Align(t,n);function S(t){let e=Array(t.length);for(let i=0;i<t.length;++i){let a=t[i];e[i]=c([s*a[0],o*a[1],h*a[2]])}return e}n?(l=1,d=0,c=b.T.bind(b)):(l=-1,d=-e,c=b.T0.bind(b));let A=Tcorners(c,[-e,-e,d],[e,e,e]),y=A[0],T=A[1];for(let t=-1;t<=1;t+=2){s=t*e;for(let t=-1;t<=1;t+=2){o=t*e;for(let t=l;t<=1;t+=2){h=t*e;for(let t=0;t<2;++t)P.push(new BezierPatch(S(M[t]),i,r,y,T))}}}}let a=4/3*(Math.sqrt(2)-1);function disk(t,e,i,r,n){let s=1-2*a/3,o=[[1,0,0],[1,-a,0],[a,-1,0],[0,-1,0],[1,a,0],[s,0,0],[0,-s,0],[-a,-1,0],[a,1,0],[0,s,0],[-s,0,0],[-1,-a,0],[0,1,0],[-a,1,0],[-1,a,0],[-1,0,0]],h=new Align(t,n);let l=Tcorners(h.T.bind(h),[-e,-e,0],[e,e,0]);P.push(new BezierPatch(function(t){let i=Array(t.length);for(let a=0;a<t.length;++a){let r=t[a];i[a]=h.T([e*r[0],e*r[1],0])}return i}(o),i,r,l[0],l[1]))}function cylinder(t,e,i,r,n,s,o){let h,l,c=[[1,0,0],[1,0,1/3],[1,0,2/3],[1,0,1],[1,a,0],[1,a,1/3],[1,a,2/3],[1,a,1],[a,1,0],[a,1,1/3],[a,1,2/3],[a,1,1],[0,1,0],[0,1,1/3],[0,1,2/3],[0,1,1]],d=new Align(t,s);function m(t){let e=Array(t.length);for(let a=0;a<t.length;++a){let r=t[a];e[a]=d.T([h*r[0],l*r[1],i*r[2]])}return e}let f=Tcorners(d.T.bind(d),[-e,-e,0],[e,e,i]),u=f[0],p=f[1];for(let t=-1;t<=1;t+=2){h=t*e;for(let t=-1;t<=1;t+=2)l=t*e,P.push(new BezierPatch(m(c),r,n,u,p))}if(o){let e=d.T([0,0,i]);P.push(new BezierCurve([t,e],r,n,t,e))}}function rmf(t,e,i,a,r){class n{constructor(t,e,i){this.p=t,this.r=e,this.t=i,this.s=cross(i,e)}}let s=Number.EPSILON*Math.max(abs2(t),abs2(e),abs2(i),abs2(a));function o(r){if(1==r){let r=[a[0]-i[0],a[1]-i[1],a[2]-i[2]];return abs2(r)>s?unit(r):(r=[2*i[0]-e[0]-a[0],2*i[1]-e[1]-a[1],2*i[2]-e[2]-a[2]],abs2(r)>s?unit(r):[a[0]-t[0]+3*(e[0]-i[0]),a[1]-t[1]+3*(e[1]-i[1]),a[2]-t[2]+3*(e[2]-i[2])])}let n=[a[0]-t[0]+3*(e[0]-i[0]),a[1]-t[1]+3*(e[1]-i[1]),a[2]-t[2]+3*(e[2]-i[2])],o=[2*(t[0]+i[0])-4*e[0],2*(t[1]+i[1])-4*e[1],2*(t[2]+i[2])-4*e[2]],h=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],l=r*r,c=[n[0]*l+o[0]*r+h[0],n[1]*l+o[1]*r+h[1],n[2]*l+o[2]*r+h[2]];return abs2(c)>s?unit(c):(l=2*r,c=[n[0]*l+o[0],n[1]*l+o[1],n[2]*l+o[2]],abs2(c)>s?unit(c):unit(n))}let h=Array(r.length),l=[e[0]-t[0],e[1]-t[1],e[2]-t[2]];abs2(l)<s&&(l=[t[0]-2*e[0]+i[0],t[1]-2*e[1]+i[1],t[2]-2*e[2]+i[2]],abs2(l)<s&&(l=[a[0]-t[0]+3*(e[0]-i[0]),a[1]-t[1]+3*(e[1]-i[1]),a[2]-t[2]+3*(e[2]-i[2])])),l=unit(l);let c=function(t){let e=cross(t,[0,1,0]),i=Number.EPSILON*abs2(t);return abs2(e)>i?unit(e):(e=cross(t,[0,0,1]),abs2(e)>i?unit(e):[1,0,0])}(l);h[0]=new n(t,c,l);for(let s=1;s<r.length;++s){let l=h[s-1],c=r[s],d=1-c,m=d*d,f=m*d,u=3*c;m*=u,d*=u*c;let p=c*c*c,v=[f*t[0]+m*e[0]+d*i[0]+p*a[0],f*t[1]+m*e[1]+d*i[1]+p*a[1],f*t[2]+m*e[2]+d*i[2]+p*a[2]],g=[v[0]-l.p[0],v[1]-l.p[1],v[2]-l.p[2]];if(0!=g[0]||0!=g[1]||0!=g[2]){let t=l.r,e=unit(g),i=l.t,a=dot(e,i),r=[i[0]-2*a*e[0],i[1]-2*a*e[1],i[2]-2*a*e[2]];i=o(c);let d=2*dot(e,t),m=[t[0]-d*e[0],t[1]-d*e[1],t[2]-d*e[2]],f=unit([i[0]-r[0],i[1]-r[1],i[2]-r[2]]),u=2*dot(f,m);m=[m[0]-u*f[0],m[1]-u*f[1],m[2]-u*f[2]],h[s]=new n(v,unit(m),unit(i))}else h[s]=h[s-1]}return h}function tube(t,e,i,r,n,s,o){let h=rmf(t[0],t[1],t[2],t[3],[0,1/3,2/3,1]),l=a*e,c=[[e,0],[e,l],[l,e],[0,e]];function d(e,a,o,l){let d=Array(16);for(let i=0;i<4;++i){let r=h[i],n=r.r[0],s=r.s[0],m=n*e+s*a,f=n*o+s*l;n=r.r[1],s=r.s[1];let u=n*e+s*a,p=n*o+s*l;n=r.r[2],s=r.s[2];let v=n*e+s*a,g=n*o+s*l,x=t[i],w=x[0];w1=x[1],w2=x[2];for(let t=0;t<4;++t){let e=c[t],a=e[0],r=e[1];d[4*i+t]=[m*a+f*r+w,u*a+p*r+w1,v*a+g*r+w2]}}P.push(new BezierPatch(d,i,r,n,s))}d(1,0,0,1),d(0,-1,1,0),d(-1,0,0,-1),d(0,1,-1,0),o&&P.push(new BezierCurve(t,i,r,n,s))}function webGLStart(){canvas=document.getElementById("Asymptote"),embedded=window.top.document!=document,initGL(),gl.enable(gl.BLEND),gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA),gl.enable(gl.DEPTH_TEST),gl.enable(gl.SCISSOR_TEST),canvas.onmousedown=handleMouseDown,document.onmouseup=handleMouseUpOrTouchEnd,document.onmousemove=handleMouseMove,canvas.onkeydown=handleKey,embedded||enableZoom(),canvas.addEventListener("touchstart",handleTouchStart,!1),canvas.addEventListener("touchend",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchcancel",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchleave",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchmove",handleTouchMove,!1),document.addEventListener("keydown",handleKey,!1),canvasWidth0=canvasWidth,canvasHeight0=canvasHeight,mat4.identity(rotMat),0!=window.innerWidth&&0!=window.innerHeight&&resize(),window.addEventListener("resize",resize,!1)}
+let vertex="\n#ifdef WEBGL2\n#define IN in\n#define OUT out\n#else\n#define IN attribute\n#define OUT varying\n#endif\n\nIN vec3 position;\n#ifdef WIDTH\nIN float width;\n#endif\n#ifdef NORMAL\nIN vec3 normal;\n#endif\n\nIN float materialIndex;\n\n#ifdef WEBGL2\nflat out int MaterialIndex;\n#ifdef COLOR\nOUT vec4 Color;\n#endif\n\n#else\nOUT vec4 diffuse;\nOUT vec3 specular;\nOUT float roughness,metallic,fresnel0;\nOUT vec4 emissive;\n\nstruct Material {\n vec4 diffuse,emissive,specular;\n vec4 parameters;\n};\n\nuniform Material Materials[Nmaterials];\n#endif\n\n#ifdef COLOR\nIN vec4 color;\n#endif\n\nuniform mat3 normMat;\nuniform mat4 viewMat;\nuniform mat4 projViewMat;\n\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\nOUT vec3 ViewPosition;\n#endif\nOUT vec3 Normal;\n#endif\n\nvoid main(void)\n{\n vec4 v=vec4(position,1.0);\n gl_Position=projViewMat*v;\n\n#ifdef NORMAL\n#ifndef ORTHOGRAPHIC\n ViewPosition=(viewMat*v).xyz;\n#endif\n Normal=normalize(normal*normMat);\n#endif\n\n#ifdef WEBGL2\n MaterialIndex=int(materialIndex);\n#ifdef COLOR\n Color=color;\n#endif\n#else\n#ifdef NORMAL\n Material m;\n#ifdef TRANSPARENT\n m=Materials[int(abs(materialIndex))-1];\n emissive=m.emissive;\n if(materialIndex >= 0.0)\n diffuse=m.diffuse;\n else {\n diffuse=color;\n#if nlights == 0\n emissive += color;\n#endif\n }\n#else\n m=Materials[int(materialIndex)];\n emissive=m.emissive;\n#ifdef COLOR\n diffuse=color;\n#if nlights == 0\n emissive += color;\n#endif\n#else\n diffuse=m.diffuse;\n#endif // COLOR\n#endif // TRANSPARENT\n specular=m.specular.rgb;\n vec4 parameters=m.parameters;\n roughness=1.0-parameters[0];\n metallic=parameters[1];\n fresnel0=parameters[2];\n#else\n emissive=Materials[int(materialIndex)].emissive;\n#endif // NORMAL\n#endif // WEBGL2\n\n#ifdef WIDTH\n gl_PointSize=width;\n#endif\n}\n",fragment="\n#ifdef WEBGL2\n#define IN in\nout vec4 outValue;\n#define OUTVALUE outValue\n#else\n#define IN varying\n#define OUTVALUE gl_FragColor\n#endif\n\n#ifdef WEBGL2\nflat in int MaterialIndex;\n\nstruct Material {\n vec4 diffuse,emissive,specular;\n vec4 parameters;\n};\n\nuniform Material Materials[Nmaterials];\n\nvec4 diffuse;\nvec3 specular;\nfloat roughness,metallic,fresnel0;\nvec4 emissive;\n\n#ifdef COLOR\nin vec4 Color;\n#endif\n\n#else\nIN vec4 diffuse;\nIN vec3 specular;\nIN float roughness,metallic,fresnel0;\nIN vec4 emissive;\n#endif\n\n#ifdef NORMAL\n\n#ifndef ORTHOGRAPHIC\nIN vec3 ViewPosition;\n#endif\nIN vec3 Normal;\n\nvec3 normal;\n\nstruct Light {\n vec3 direction;\n vec3 color;\n};\n\nuniform Light Lights[Nlights];\n\n#ifdef USE_IBL\nuniform sampler2D reflBRDFSampler;\nuniform sampler2D diffuseSampler;\nuniform sampler2D reflImgSampler;\n\nconst float pi=acos(-1.0);\nconst float piInv=1.0/pi;\nconst float twopi=2.0*pi;\nconst float twopiInv=1.0/twopi;\n\n// (x,y,z) -> (r,theta,phi);\n// theta -> [0,pi]: colatitude\n// phi -> [-pi,pi]: longitude\nvec3 cart2sphere(vec3 cart)\n{\n float x=cart.x;\n float y=cart.z;\n float z=cart.y;\n\n float r=length(cart);\n float theta=r > 0.0 ? acos(z/r) : 0.0;\n float phi=atan(y,x);\n\n return vec3(r,theta,phi);\n}\n\nvec2 normalizedAngle(vec3 cartVec)\n{\n vec3 sphericalVec=cart2sphere(cartVec);\n sphericalVec.y=sphericalVec.y*piInv;\n sphericalVec.z=0.75-sphericalVec.z*twopiInv;\n return sphericalVec.zy;\n}\n\nvec3 IBLColor(vec3 viewDir)\n{\n vec3 IBLDiffuse=diffuse.rgb*texture(diffuseSampler,normalizedAngle(normal)).rgb;\n vec3 reflectVec=normalize(reflect(-viewDir,normal));\n vec2 reflCoord=normalizedAngle(reflectVec);\n vec3 IBLRefl=textureLod(reflImgSampler,reflCoord,roughness*ROUGHNESS_STEP_COUNT).rgb;\n vec2 IBLbrdf=texture(reflBRDFSampler,vec2(dot(normal,viewDir),roughness)).rg;\n float specularMultiplier=fresnel0*IBLbrdf.x+IBLbrdf.y;\n vec3 dielectric=IBLDiffuse+specularMultiplier*IBLRefl;\n vec3 metal=diffuse.rgb*IBLRefl;\n return mix(dielectric,metal,metallic);\n}\n#else\nfloat Roughness2;\nfloat NDF_TRG(vec3 h)\n{\n float ndoth=max(dot(normal,h),0.0);\n float alpha2=Roughness2*Roughness2;\n float denom=ndoth*ndoth*(alpha2-1.0)+1.0;\n return denom != 0.0 ? alpha2/(denom*denom) : 0.0;\n}\n\nfloat GGX_Geom(vec3 v)\n{\n float ndotv=max(dot(v,normal),0.0);\n float ap=1.0+Roughness2;\n float k=0.125*ap*ap;\n return ndotv/((ndotv*(1.0-k))+k);\n}\n\nfloat Geom(vec3 v, vec3 l)\n{\n return GGX_Geom(v)*GGX_Geom(l);\n}\n\nfloat Fresnel(vec3 h, vec3 v, float fresnel0)\n{\n float a=1.0-max(dot(h,v),0.0);\n float b=a*a;\n return fresnel0+(1.0-fresnel0)*b*b*a;\n}\n\n// physical based shading using UE4 model.\nvec3 BRDF(vec3 viewDirection, vec3 lightDirection)\n{\n vec3 lambertian=diffuse.rgb;\n vec3 h=normalize(lightDirection+viewDirection);\n\n float omegain=max(dot(viewDirection,normal),0.0);\n float omegaln=max(dot(lightDirection,normal),0.0);\n\n float D=NDF_TRG(h);\n float G=Geom(viewDirection,lightDirection);\n float F=Fresnel(h,viewDirection,fresnel0);\n\n float denom=4.0*omegain*omegaln;\n float rawReflectance=denom > 0.0 ? (D*G)/denom : 0.0;\n\n vec3 dielectric=mix(lambertian,rawReflectance*specular,F);\n vec3 metal=rawReflectance*diffuse.rgb;\n\n return mix(dielectric,metal,metallic);\n}\n#endif\n\n#endif\n\nvoid main(void)\n{\n#ifdef WEBGL2\n#ifdef NORMAL\n Material m;\n#ifdef TRANSPARENT\n m=Materials[abs(MaterialIndex)-1];\n emissive=m.emissive;\n if(MaterialIndex >= 0)\n diffuse=m.diffuse;\n else {\n diffuse=Color;\n#if nlights == 0\n emissive += Color;\n#endif\n }\n#else\n m=Materials[MaterialIndex];\n emissive=m.emissive;\n#ifdef COLOR\n diffuse=Color;\n#if nlights == 0\n emissive += Color;\n#endif\n#else\n diffuse=m.diffuse;\n#endif // COLOR\n#endif // TRANSPARENT\n specular=m.specular.rgb;\n vec4 parameters=m.parameters;\n roughness=1.0-parameters[0];\n metallic=parameters[1];\n fresnel0=parameters[2];\n#else\n emissive=Materials[MaterialIndex].emissive;\n#endif // NORMAL\n#endif // WEBGL2\n\n#if defined(NORMAL) && nlights > 0\n normal=normalize(Normal);\n normal=gl_FrontFacing ? normal : -normal;\n#ifdef ORTHOGRAPHIC\n vec3 viewDir=vec3(0.0,0.0,1.0);\n#else\n vec3 viewDir=-normalize(ViewPosition);\n#endif\n\nvec3 color;\n#ifdef USE_IBL\n color=IBLColor(viewDir);\n#else\n Roughness2=roughness*roughness;\n color=emissive.rgb;\n for(int i=0; i < nlights; ++i) {\n Light Li=Lights[i];\n vec3 L=Li.direction;\n float cosTheta=max(dot(normal,L),0.0);\n vec3 radiance=cosTheta*Li.color;\n color += BRDF(viewDir,L)*radiance;\n }\n#endif\n OUTVALUE=vec4(color,diffuse.a);\n#else\n OUTVALUE=emissive;\n#endif\n}\n";!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var i=t();for(var a in i)("object"==typeof exports?exports:e)[a]=i[a]}}("undefined"!=typeof self?self:this,(function(){return function(e){var t={};function i(a){if(t[a])return t[a].exports;var n=t[a]={i:a,l:!1,exports:{}};return e[a].call(n.exports,n,n.exports,i),n.l=!0,n.exports}return i.m=e,i.c=t,i.d=function(e,t,a){i.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:a})},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=1)}([function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.setMatrixArrayType=function(e){t.ARRAY_TYPE=e},t.toRadian=function(e){return e*n},t.equals=function(e,t){return Math.abs(e-t)<=a*Math.max(1,Math.abs(e),Math.abs(t))};var a=t.EPSILON=1e-6;t.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,t.RANDOM=Math.random;var n=Math.PI/180},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.mat4=t.mat3=void 0;var a=r(i(2)),n=r(i(3));function r(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}t.mat3=a,t.mat4=n},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.create=function(){var e=new a.ARRAY_TYPE(9);return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=1,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e},t.fromMat4=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e},t.invert=function(e,t){var i=t[0],a=t[1],n=t[2],r=t[3],s=t[4],o=t[5],l=t[6],h=t[7],c=t[8],d=c*s-o*h,m=-c*r+o*l,f=h*r-s*l,u=i*d+a*m+n*f;if(!u)return null;return u=1/u,e[0]=d*u,e[1]=(-c*a+n*h)*u,e[2]=(o*a-n*s)*u,e[3]=m*u,e[4]=(c*i-n*l)*u,e[5]=(-o*i+n*r)*u,e[6]=f*u,e[7]=(-h*i+a*l)*u,e[8]=(s*i-a*r)*u,e};var a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}(i(0))},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.create=function(){var e=new a.ARRAY_TYPE(16);return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.identity=function(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.invert=function(e,t){var i=t[0],a=t[1],n=t[2],r=t[3],s=t[4],o=t[5],l=t[6],h=t[7],c=t[8],d=t[9],m=t[10],f=t[11],u=t[12],p=t[13],g=t[14],v=t[15],x=i*o-a*s,w=i*l-n*s,M=i*h-r*s,b=a*l-n*o,T=a*h-r*o,S=n*h-r*l,R=c*p-d*u,I=c*g-m*u,A=c*v-f*u,E=d*g-m*p,P=d*v-f*p,L=m*v-f*g,D=x*L-w*P+M*E+b*A-T*I+S*R;if(!D)return null;return D=1/D,e[0]=(o*L-l*P+h*E)*D,e[1]=(n*P-a*L-r*E)*D,e[2]=(p*S-g*T+v*b)*D,e[3]=(m*T-d*S-f*b)*D,e[4]=(l*A-s*L-h*I)*D,e[5]=(i*L-n*A+r*I)*D,e[6]=(g*M-u*S-v*w)*D,e[7]=(c*S-m*M+f*w)*D,e[8]=(s*P-o*A+h*R)*D,e[9]=(a*A-i*P-r*R)*D,e[10]=(u*T-p*M+v*x)*D,e[11]=(d*M-c*T-f*x)*D,e[12]=(o*I-s*E-l*R)*D,e[13]=(i*E-a*I+n*R)*D,e[14]=(p*w-u*b-g*x)*D,e[15]=(c*b-d*w+m*x)*D,e},t.multiply=n,t.translate=function(e,t,i){var a=i[0],n=i[1],r=i[2],s=void 0,o=void 0,l=void 0,h=void 0,c=void 0,d=void 0,m=void 0,f=void 0,u=void 0,p=void 0,g=void 0,v=void 0;t===e?(e[12]=t[0]*a+t[4]*n+t[8]*r+t[12],e[13]=t[1]*a+t[5]*n+t[9]*r+t[13],e[14]=t[2]*a+t[6]*n+t[10]*r+t[14],e[15]=t[3]*a+t[7]*n+t[11]*r+t[15]):(s=t[0],o=t[1],l=t[2],h=t[3],c=t[4],d=t[5],m=t[6],f=t[7],u=t[8],p=t[9],g=t[10],v=t[11],e[0]=s,e[1]=o,e[2]=l,e[3]=h,e[4]=c,e[5]=d,e[6]=m,e[7]=f,e[8]=u,e[9]=p,e[10]=g,e[11]=v,e[12]=s*a+c*n+u*r+t[12],e[13]=o*a+d*n+p*r+t[13],e[14]=l*a+m*n+g*r+t[14],e[15]=h*a+f*n+v*r+t[15]);return e},t.rotate=function(e,t,i,n){var r,s,o,l,h,c,d,m,f,u,p,g,v,x,w,M,b,T,S,R,I,A,E,P,L=n[0],D=n[1],y=n[2],O=Math.sqrt(L*L+D*D+y*y);if(Math.abs(O)<a.EPSILON)return null;L*=O=1/O,D*=O,y*=O,r=Math.sin(i),s=Math.cos(i),o=1-s,l=t[0],h=t[1],c=t[2],d=t[3],m=t[4],f=t[5],u=t[6],p=t[7],g=t[8],v=t[9],x=t[10],w=t[11],M=L*L*o+s,b=D*L*o+y*r,T=y*L*o-D*r,S=L*D*o-y*r,R=D*D*o+s,I=y*D*o+L*r,A=L*y*o+D*r,E=D*y*o-L*r,P=y*y*o+s,e[0]=l*M+m*b+g*T,e[1]=h*M+f*b+v*T,e[2]=c*M+u*b+x*T,e[3]=d*M+p*b+w*T,e[4]=l*S+m*R+g*I,e[5]=h*S+f*R+v*I,e[6]=c*S+u*R+x*I,e[7]=d*S+p*R+w*I,e[8]=l*A+m*E+g*P,e[9]=h*A+f*E+v*P,e[10]=c*A+u*E+x*P,e[11]=d*A+p*E+w*P,t!==e&&(e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]);return e},t.fromTranslation=function(e,t){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=t[0],e[13]=t[1],e[14]=t[2],e[15]=1,e},t.fromRotation=function(e,t,i){var n,r,s,o=i[0],l=i[1],h=i[2],c=Math.sqrt(o*o+l*l+h*h);if(Math.abs(c)<a.EPSILON)return null;return o*=c=1/c,l*=c,h*=c,n=Math.sin(t),r=Math.cos(t),s=1-r,e[0]=o*o*s+r,e[1]=l*o*s+h*n,e[2]=h*o*s-l*n,e[3]=0,e[4]=o*l*s-h*n,e[5]=l*l*s+r,e[6]=h*l*s+o*n,e[7]=0,e[8]=o*h*s+l*n,e[9]=l*h*s-o*n,e[10]=h*h*s+r,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.frustum=function(e,t,i,a,n,r,s){var o=1/(i-t),l=1/(n-a),h=1/(r-s);return e[0]=2*r*o,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=2*r*l,e[6]=0,e[7]=0,e[8]=(i+t)*o,e[9]=(n+a)*l,e[10]=(s+r)*h,e[11]=-1,e[12]=0,e[13]=0,e[14]=s*r*2*h,e[15]=0,e},t.ortho=function(e,t,i,a,n,r,s){var o=1/(t-i),l=1/(a-n),h=1/(r-s);return e[0]=-2*o,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=-2*l,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=2*h,e[11]=0,e[12]=(t+i)*o,e[13]=(n+a)*l,e[14]=(s+r)*h,e[15]=1,e};var a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}(i(0));function n(e,t,i){var a=t[0],n=t[1],r=t[2],s=t[3],o=t[4],l=t[5],h=t[6],c=t[7],d=t[8],m=t[9],f=t[10],u=t[11],p=t[12],g=t[13],v=t[14],x=t[15],w=i[0],M=i[1],b=i[2],T=i[3];return e[0]=w*a+M*o+b*d+T*p,e[1]=w*n+M*l+b*m+T*g,e[2]=w*r+M*h+b*f+T*v,e[3]=w*s+M*c+b*u+T*x,w=i[4],M=i[5],b=i[6],T=i[7],e[4]=w*a+M*o+b*d+T*p,e[5]=w*n+M*l+b*m+T*g,e[6]=w*r+M*h+b*f+T*v,e[7]=w*s+M*c+b*u+T*x,w=i[8],M=i[9],b=i[10],T=i[11],e[8]=w*a+M*o+b*d+T*p,e[9]=w*n+M*l+b*m+T*g,e[10]=w*r+M*h+b*f+T*v,e[11]=w*s+M*c+b*u+T*x,w=i[12],M=i[13],b=i[14],T=i[15],e[12]=w*a+M*o+b*d+T*p,e[13]=w*n+M*l+b*m+T*g,e[14]=w*r+M*h+b*f+T*v,e[15]=w*s+M*c+b*u+T*x,e}}])}));let canvasWidth,canvasHeight,imageURL,image,minBound,maxBound,orthographic,angleOfView,initialZoom,viewportMargin,zoomFactor,zoomPinchFactor,zoomPinchCap,zoomStep,shiftHoldDistance,shiftWaitTime,vibrateTime,canvasWidth0,canvasHeight0,zoom0,embedded,canvas,gl,alpha,offscreen2,context,maxMaterials,halfCanvasWidth,halfCanvasHeight,P=[],Materials=[],Lights=[],Centers=[],Background=[1,1,1,1],absolute=!1,ibl=!1,viewportShift=[0,0],webgl2=!1,nlights=0,Nmaterials=2,materials=[];const pixelResolution=.75,zoomRemeshFactor=1.5,FillFactor=.1,windowTrim=10,third=1/3;let Zoom,lastZoom,maxViewportWidth,maxViewportHeight,H,zmin,zmax,size2,ArcballFactor,rotMat=mat4.create(),projMat=mat4.create(),viewMat=mat4.create(),projViewMat=mat4.create(),normMat=mat3.create(),viewMat3=mat3.create(),cjMatInv=mat4.create(),T=mat4.create(),center={x:0,y:0,z:0},shift={x:0,y:0},viewParam={xmin:0,xmax:0,ymin:0,ymax:0,zmin:0,zmax:0},remesh=!0,wireframe=0,mouseDownOrTouchActive=!1,lastMouseX=null,lastMouseY=null,touchID=null,Positions=[],Normals=[],Colors=[],Indices=[],IBLReflMap=null,IBLDiffuseMap=null,IBLbdrfMap=null;function IBLReady(){return null!==IBLReflMap&&null!==IBLDiffuseMap&&null!==IBLbdrfMap}function SetIBL(){embedded||deleteShaders(),initShaders(ibl)}let roughnessStepCount=8;class Material{constructor(e,t,i,a,n,r){this.diffuse=e,this.emissive=t,this.specular=i,this.shininess=a,this.metallic=n,this.fresnel0=r}setUniform(e,t){let i=i=>gl.getUniformLocation(e,"Materials["+t+"]."+i);gl.uniform4fv(i("diffuse"),new Float32Array(this.diffuse)),gl.uniform4fv(i("emissive"),new Float32Array(this.emissive)),gl.uniform4fv(i("specular"),new Float32Array(this.specular)),gl.uniform4f(i("parameters"),this.shininess,this.metallic,this.fresnel0,0)}}let indexExt,TRIANGLES,material0Data,material1Data,materialData,colorData,transparentData,triangleData,materialIndex,enumPointLight=1,enumDirectionalLight=2;class Light{constructor(e,t){this.direction=e,this.color=t}setUniform(e,t){let i=i=>gl.getUniformLocation(e,"Lights["+t+"]."+i);gl.uniform3fv(i("direction"),new Float32Array(this.direction)),gl.uniform3fv(i("color"),new Float32Array(this.color))}}function initShaders(e=!1){let t=gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS);maxMaterials=Math.floor((t-14)/4),Nmaterials=Math.min(Math.max(Nmaterials,Materials.length),maxMaterials),pixelOpt=["WIDTH"],materialOpt=["NORMAL"],colorOpt=["NORMAL","COLOR"],transparentOpt=["NORMAL","COLOR","TRANSPARENT"],e&&(materialOpt.push("USE_IBL"),transparentOpt.push("USE_IBL")),pixelShader=initShader(pixelOpt),materialShader=initShader(materialOpt),colorShader=initShader(colorOpt),transparentShader=initShader(transparentOpt)}function deleteShaders(){gl.deleteProgram(transparentShader),gl.deleteProgram(colorShader),gl.deleteProgram(materialShader),gl.deleteProgram(pixelShader)}function saveAttributes(){let e=window.top.document.asygl2[alpha];e.gl=gl,e.nlights=Lights.length,e.Nmaterials=Nmaterials,e.maxMaterials=maxMaterials,e.pixelShader=pixelShader,e.materialShader=materialShader,e.colorShader=colorShader,e.transparentShader=transparentShader}function restoreAttributes(){let e=window.top.document.asygl2[alpha];gl=e.gl,nlights=e.nlights,Nmaterials=e.Nmaterials,maxMaterials=e.maxMaterials,pixelShader=e.pixelShader,materialShader=e.materialShader,colorShader=e.colorShader,transparentShader=e.transparentShader}function webGL(e,t){let i;return ibl&&(webgl2=!0),webgl2&&(i=e.getContext("webgl2",{alpha:t})),i||(webgl2=!1,ibl=!1,i=e.getContext("webgl",{alpha:t})),i||alert("Could not initialize WebGL"),i}function initGL(){if(alpha=Background[3]<1,embedded){let e=window.top.document;null==e.asygl2&&(e.asygl2=Array(2)),context=canvas.getContext("2d"),offscreen2=e.offscreen2,offscreen2||(offscreen2=e.createElement("canvas"),e.offscreen2=offscreen2),e.asygl2[alpha]&&e.asygl2[alpha].gl?(restoreAttributes(),(Lights.length!=nlights||Math.min(Materials.length,maxMaterials)>Nmaterials)&&(initShaders(),saveAttributes())):(gl=webGL(offscreen2,alpha),initShaders(),e.asygl2[alpha]={},saveAttributes())}else gl=webGL(canvas,alpha),initShaders();indexExt=gl.getExtension("OES_element_index_uint"),TRIANGLES=gl.TRIANGLES,material0Data=new vertexBuffer(gl.POINTS),material1Data=new vertexBuffer(gl.LINES),materialData=new vertexBuffer,colorData=new vertexBuffer,transparentData=new vertexBuffer,triangleData=new vertexBuffer}function getShader(e,t,i,a=[]){let n=webgl2?"300 es":"100",r=Array(...a),s=[["nlights",0==wireframe?Lights.length:0],["Nmaterials",Nmaterials]],o=[["int","Nlights",Math.max(Lights.length,1)]];webgl2&&r.push("WEBGL2"),ibl&&s.push(["ROUGHNESS_STEP_COUNT",roughnessStepCount.toFixed(2)]),orthographic&&r.push("ORTHOGRAPHIC"),macros_str=s.map(e=>`#define ${e[0]} ${e[1]}`).join("\n"),define_str=r.map(e=>"#define "+e).join("\n"),const_str=o.map(e=>`const ${e[0]} ${e[1]}=${e[2]};`).join("\n"),ext_str=[].map(e=>`#extension ${e}: enable`).join("\n"),shaderSrc=`#version ${n}\n${ext_str}\n${define_str}\n${const_str}\n${macros_str}\n\n\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n \n${t}\n `;let l=e.createShader(i);return e.shaderSource(l,shaderSrc),e.compileShader(l),e.getShaderParameter(l,e.COMPILE_STATUS)?l:(alert(e.getShaderInfoLog(l)),null)}function registerBuffer(e,t,i,a=gl.ARRAY_BUFFER){return e.length>0&&(0==t&&(t=gl.createBuffer(),i=!0),gl.bindBuffer(a,t),i&&gl.bufferData(a,e,gl.STATIC_DRAW)),t}function drawBuffer(e,t,i=e.indices){if(0==e.indices.length)return;let a=t!=pixelShader;setUniforms(e,t),null!=IBLDiffuseMap&&(gl.activeTexture(gl.TEXTURE0),gl.bindTexture(gl.TEXTURE_2D,IBLbdrfMap),gl.uniform1i(gl.getUniformLocation(t,"reflBRDFSampler"),0),gl.activeTexture(gl.TEXTURE1),gl.bindTexture(gl.TEXTURE_2D,IBLDiffuseMap),gl.uniform1i(gl.getUniformLocation(t,"diffuseSampler"),1),gl.activeTexture(gl.TEXTURE2),gl.bindTexture(gl.TEXTURE_2D,IBLReflMap),gl.uniform1i(gl.getUniformLocation(t,"reflImgSampler"),2));let n=remesh||e.partial||!e.rendered;e.verticesBuffer=registerBuffer(new Float32Array(e.vertices),e.verticesBuffer,n),gl.vertexAttribPointer(positionAttribute,3,gl.FLOAT,!1,a?24:16,0),a?Lights.length>0&&gl.vertexAttribPointer(normalAttribute,3,gl.FLOAT,!1,24,12):gl.vertexAttribPointer(widthAttribute,1,gl.FLOAT,!1,16,12),e.materialsBuffer=registerBuffer(new Int16Array(e.materialIndices),e.materialsBuffer,n),gl.vertexAttribPointer(materialAttribute,1,gl.SHORT,!1,2,0),t!=colorShader&&t!=transparentShader||(e.colorsBuffer=registerBuffer(new Uint8Array(e.colors),e.colorsBuffer,n),gl.vertexAttribPointer(colorAttribute,4,gl.UNSIGNED_BYTE,!0,0,0)),e.indicesBuffer=registerBuffer(indexExt?new Uint32Array(i):new Uint16Array(i),e.indicesBuffer,n,gl.ELEMENT_ARRAY_BUFFER),e.rendered=!0,gl.drawElements(a?wireframe?gl.LINES:e.type:gl.POINTS,i.length,indexExt?gl.UNSIGNED_INT:gl.UNSIGNED_SHORT,0)}class vertexBuffer{constructor(e){this.type=e||TRIANGLES,this.verticesBuffer=0,this.materialsBuffer=0,this.colorsBuffer=0,this.indicesBuffer=0,this.rendered=!1,this.partial=!1,this.clear()}clear(){this.vertices=[],this.materialIndices=[],this.colors=[],this.indices=[],this.nvertices=0,this.materials=[],this.materialTable=[]}vertex(e,t){return this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.materialIndices.push(materialIndex),this.nvertices++}Vertex(e,t,i=[0,0,0,0]){return this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.vertices.push(t[0]),this.vertices.push(t[1]),this.vertices.push(t[2]),this.materialIndices.push(materialIndex),this.colors.push(i[0]),this.colors.push(i[1]),this.colors.push(i[2]),this.colors.push(i[3]),this.nvertices++}vertex0(e,t){return this.vertices.push(e[0]),this.vertices.push(e[1]),this.vertices.push(e[2]),this.vertices.push(t),this.materialIndices.push(materialIndex),this.nvertices++}iVertex(e,t,i,a=[0,0,0,0]){let n=6*e;this.vertices[n]=t[0],this.vertices[n+1]=t[1],this.vertices[n+2]=t[2],this.vertices[n+3]=i[0],this.vertices[n+4]=i[1],this.vertices[n+5]=i[2],this.materialIndices[e]=materialIndex;let r=4*e;this.colors[r]=a[0],this.colors[r+1]=a[1],this.colors[r+2]=a[2],this.colors[r+3]=a[3],this.indices.push(e)}append(e){append(this.vertices,e.vertices),append(this.materialIndices,e.materialIndices),append(this.colors,e.colors),appendOffset(this.indices,e.indices,this.nvertices),this.nvertices+=e.nvertices}}function append(e,t){let i=e.length,a=t.length;e.length+=a;for(let n=0;n<a;++n)e[i+n]=t[n]}function appendOffset(e,t,i){let a=e.length,n=t.length;e.length+=t.length;for(let r=0;r<n;++r)e[a+r]=t[r]+i}class Geometry{constructor(){this.data=new vertexBuffer,this.Onscreen=!1,this.m=[]}offscreen(e){let t=projViewMat,i=e[0],a=i[0],n=i[1],r=i[2],s=1/(t[3]*a+t[7]*n+t[11]*r+t[15]);this.x=this.X=(t[0]*a+t[4]*n+t[8]*r+t[12])*s,this.y=this.Y=(t[1]*a+t[5]*n+t[9]*r+t[13])*s;for(let i=1,a=e.length;i<a;++i){let a=e[i],n=a[0],r=a[1],s=a[2],o=1/(t[3]*n+t[7]*r+t[11]*s+t[15]),l=(t[0]*n+t[4]*r+t[8]*s+t[12])*o,h=(t[1]*n+t[5]*r+t[9]*s+t[13])*o;l<this.x?this.x=l:l>this.X&&(this.X=l),h<this.y?this.y=h:h>this.Y&&(this.Y=h)}return(this.X<-1.01||this.x>1.01||this.Y<-1.01||this.y>1.01)&&(this.Onscreen=!1,!0)}T(e){let t=this.c[0],i=this.c[1],a=this.c[2],n=e[0]-t,r=e[1]-i,s=e[2]-a;return[n*normMat[0]+r*normMat[3]+s*normMat[6]+t,n*normMat[1]+r*normMat[4]+s*normMat[7]+i,n*normMat[2]+r*normMat[5]+s*normMat[8]+a]}Tcorners(e,t){return[this.T(e),this.T([e[0],e[1],t[2]]),this.T([e[0],t[1],e[2]]),this.T([e[0],t[1],t[2]]),this.T([t[0],e[1],e[2]]),this.T([t[0],e[1],t[2]]),this.T([t[0],t[1],e[2]]),this.T(t)]}setMaterial(e,t){null==e.materialTable[this.MaterialIndex]&&(e.materials.length>=Nmaterials&&(e.partial=!0,t()),e.materialTable[this.MaterialIndex]=e.materials.length,e.materials.push(Materials[this.MaterialIndex])),materialIndex=e.materialTable[this.MaterialIndex]}render(){let e;if(this.setMaterialIndex(),0==this.CenterIndex?e=corners(this.Min,this.Max):(this.c=Centers[this.CenterIndex-1],e=this.Tcorners(this.Min,this.Max)),this.offscreen(e))return this.data.clear(),void this.notRendered();let t,i=this.controlpoints;if(0==this.CenterIndex){if(!remesh&&this.Onscreen)return void this.append();t=i}else{let e=i.length;t=Array(e);for(let a=0;a<e;++a)t[a]=this.T(i[a])}let a=orthographic?1:this.Min[2]/maxBound[2],n=.75*Math.hypot(a*(viewParam.xmax-viewParam.xmin),a*(viewParam.ymax-viewParam.ymin))/size2;this.res2=n*n,this.Epsilon=.1*n,this.data.clear(),this.notRendered(),this.Onscreen=!0,this.process(t)}}class BezierPatch extends Geometry{constructor(e,t,i,a,n,r){super(),this.controlpoints=e,this.CenterIndex=t,this.MaterialIndex=i,this.Min=a,this.Max=n,this.color=r;let s=e.length;if(r){let e=r[0][3]+r[1][3]+r[2][3];this.transparent=16==s||4==s?e+r[3][3]<1020:e<765}else this.transparent=Materials[i].diffuse[3]<1;this.vertex=this.transparent?this.data.Vertex.bind(this.data):this.data.vertex.bind(this.data),this.L2norm(this.controlpoints)}setMaterialIndex(){this.transparent?this.setMaterial(transparentData,drawTransparent):this.color?this.setMaterial(colorData,drawColor):this.setMaterial(materialData,drawMaterial)}L2norm(e){let t=e[0];this.epsilon=0;let i=e.length;for(let a=1;a<i;++a)this.epsilon=Math.max(this.epsilon,abs2([e[a][0]-t[0],e[a][1]-t[1],e[a][2]-t[2]]));this.epsilon*=Number.EPSILON}processTriangle(e){let t=e[0],i=e[1],a=e[2],n=unit(cross([i[0]-t[0],i[1]-t[1],i[2]-t[2]],[a[0]-t[0],a[1]-t[1],a[2]-t[2]]));if(!this.offscreen([t,i,a])){let e,r,s;this.color?(e=this.data.Vertex(t,n,this.color[0]),r=this.data.Vertex(i,n,this.color[1]),s=this.data.Vertex(a,n,this.color[2])):(e=this.vertex(t,n),r=this.vertex(i,n),s=this.vertex(a,n)),0==wireframe?(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(s)):(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(r),this.data.indices.push(s),this.data.indices.push(s),this.data.indices.push(e)),this.append()}}processQuad(e){let t=e[0],i=e[1],a=e[2],n=e[3],r=cross([i[0]-t[0],i[1]-t[1],i[2]-t[2]],[a[0]-i[0],a[1]-i[1],a[2]-i[2]]),s=cross([a[0]-n[0],a[1]-n[1],a[2]-n[2]],[n[0]-t[0],n[1]-t[1],n[2]-t[2]]),o=unit([r[0]+s[0],r[1]+s[1],r[2]+s[2]]);if(!this.offscreen([t,i,a,n])){let e,r,s,l;this.color?(e=this.data.Vertex(t,o,this.color[0]),r=this.data.Vertex(i,o,this.color[1]),s=this.data.Vertex(a,o,this.color[2]),l=this.data.Vertex(n,o,this.color[3])):(e=this.vertex(t,o),r=this.vertex(i,o),s=this.vertex(a,o),l=this.vertex(n,o)),0==wireframe?(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(s),this.data.indices.push(e),this.data.indices.push(s),this.data.indices.push(l)):(this.data.indices.push(e),this.data.indices.push(r),this.data.indices.push(r),this.data.indices.push(s),this.data.indices.push(s),this.data.indices.push(l),this.data.indices.push(l),this.data.indices.push(e)),this.append()}}curve(e,t,i,a,n){new BezierCurve([e[t],e[i],e[a],e[n]],0,materialIndex,this.Min,this.Max).render()}process(e){if(this.transparent&&1!=wireframe&&(materialIndex=this.color?-1-materialIndex:1+materialIndex),10==e.length)return this.process3(e);if(3==e.length)return this.processTriangle(e);if(4==e.length)return this.processQuad(e);if(1==wireframe)return this.curve(e,0,4,8,12),this.curve(e,12,13,14,15),this.curve(e,15,11,7,3),void this.curve(e,3,2,1,0);let t=e[0],i=e[3],a=e[12],n=e[15],r=this.normal(i,e[2],e[1],t,e[4],e[8],a);abs2(r)<this.epsilon&&(r=this.normal(i,e[2],e[1],t,e[13],e[14],n),abs2(r)<this.epsilon&&(r=this.normal(n,e[11],e[7],i,e[4],e[8],a)));let s=this.normal(t,e[4],e[8],a,e[13],e[14],n);abs2(s)<this.epsilon&&(s=this.normal(t,e[4],e[8],a,e[11],e[7],i),abs2(s)<this.epsilon&&(s=this.normal(i,e[2],e[1],t,e[13],e[14],n)));let o=this.normal(a,e[13],e[14],n,e[11],e[7],i);abs2(o)<this.epsilon&&(o=this.normal(a,e[13],e[14],n,e[2],e[1],t),abs2(o)<this.epsilon&&(o=this.normal(t,e[4],e[8],a,e[11],e[7],i)));let l=this.normal(n,e[11],e[7],i,e[2],e[1],t);if(abs2(l)<this.epsilon&&(l=this.normal(n,e[11],e[7],i,e[4],e[8],a),abs2(l)<this.epsilon&&(l=this.normal(a,e[13],e[14],n,e[2],e[1],t))),this.color){let h=this.color[0],c=this.color[1],d=this.color[2],m=this.color[3],f=this.data.Vertex(t,r,h),u=this.data.Vertex(a,s,c),p=this.data.Vertex(n,o,d),g=this.data.Vertex(i,l,m);this.Render(e,f,u,p,g,t,a,n,i,!1,!1,!1,!1,h,c,d,m)}else{let h=this.vertex(t,r),c=this.vertex(a,s),d=this.vertex(n,o),m=this.vertex(i,l);this.Render(e,h,c,d,m,t,a,n,i,!1,!1,!1,!1)}this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):this.color?colorData.append(this.data):materialData.append(this.data)}notRendered(){this.transparent?transparentData.rendered=!1:this.color?colorData.rendered=!1:materialData.rendered=!1}Render(e,t,i,a,n,r,s,o,l,h,c,d,m,f,u,p,g){let v=this.Distance(e);if(v[0]<this.res2&&v[1]<this.res2)this.offscreen([r,s,o])||(0==wireframe?(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(a)):(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(i),this.data.indices.push(a))),this.offscreen([r,o,l])||(0==wireframe?(this.data.indices.push(t),this.data.indices.push(a),this.data.indices.push(n)):(this.data.indices.push(a),this.data.indices.push(n),this.data.indices.push(n),this.data.indices.push(t)));else{if(this.offscreen(e))return;let x=e[0],w=e[3],M=e[12],b=e[15];if(v[0]<this.res2){let v=new Split3(x,e[1],e[2],w),T=new Split3(e[4],e[5],e[6],e[7]),S=new Split3(e[8],e[9],e[10],e[11]),R=new Split3(M,e[13],e[14],b),I=[x,v.m0,v.m3,v.m5,e[4],T.m0,T.m3,T.m5,e[8],S.m0,S.m3,S.m5,M,R.m0,R.m3,R.m5],A=[v.m5,v.m4,v.m2,w,T.m5,T.m4,T.m2,e[7],S.m5,S.m4,S.m2,e[11],R.m5,R.m4,R.m2,b],E=this.normal(I[12],I[13],I[14],I[15],I[11],I[7],I[3]);abs2(E)<=this.epsilon&&(E=this.normal(I[12],I[13],I[14],I[15],I[2],I[1],I[0]),abs2(E)<=this.epsilon&&(E=this.normal(I[0],I[4],I[8],I[12],I[11],I[7],I[3])));let P=this.normal(A[3],A[2],A[1],A[0],A[4],A[8],A[12]);abs2(P)<=this.epsilon&&(P=this.normal(A[3],A[2],A[1],A[0],A[13],A[14],A[15]),abs2(P)<=this.epsilon&&(P=this.normal(A[15],A[11],A[7],A[3],A[4],A[8],A[12])));let L=this.Epsilon,D=[.5*(s[0]+o[0]),.5*(s[1]+o[1]),.5*(s[2]+o[2])];if(!c)if(c=Straightness(M,e[13],e[14],b)<this.res2){let e=unit(this.differential(A[12],A[8],A[4],A[0]));D=[D[0]-L*e[0],D[1]-L*e[1],D[2]-L*e[2]]}else D=I[15];let y=[.5*(l[0]+r[0]),.5*(l[1]+r[1]),.5*(l[2]+r[2])];if(!m)if(m=Straightness(x,e[1],e[2],w)<this.res2){let e=unit(this.differential(I[3],I[7],I[11],I[15]));y=[y[0]-L*e[0],y[1]-L*e[1],y[2]-L*e[2]]}else y=A[0];if(f){let e=Array(4),v=Array(4);for(let t=0;t<4;++t)e[t]=.5*(u[t]+p[t]),v[t]=.5*(g[t]+f[t]);let x=this.data.Vertex(D,E,e),w=this.data.Vertex(y,P,v);this.Render(I,t,i,x,w,r,s,D,y,h,c,!1,m,f,u,e,v),this.Render(A,w,x,a,n,y,D,o,l,!1,c,d,m,v,e,p,g)}else{let e=this.vertex(D,E),f=this.vertex(y,P);this.Render(I,t,i,e,f,r,s,D,y,h,c,!1,m),this.Render(A,f,e,a,n,y,D,o,l,!1,c,d,m)}return}if(v[1]<this.res2){let v=new Split3(x,e[4],e[8],M),T=new Split3(e[1],e[5],e[9],e[13]),S=new Split3(e[2],e[6],e[10],e[14]),R=new Split3(w,e[7],e[11],b),I=[x,e[1],e[2],w,v.m0,T.m0,S.m0,R.m0,v.m3,T.m3,S.m3,R.m3,v.m5,T.m5,S.m5,R.m5],A=[v.m5,T.m5,S.m5,R.m5,v.m4,T.m4,S.m4,R.m4,v.m2,T.m2,S.m2,R.m2,M,e[13],e[14],b],E=this.normal(I[0],I[4],I[8],I[12],I[13],I[14],I[15]);abs2(E)<=this.epsilon&&(E=this.normal(I[0],I[4],I[8],I[12],I[11],I[7],I[3]),abs2(E)<=this.epsilon&&(E=this.normal(I[3],I[2],I[1],I[0],I[13],I[14],I[15])));let P=this.normal(A[15],A[11],A[7],A[3],A[2],A[1],A[0]);abs2(P)<=this.epsilon&&(P=this.normal(A[15],A[11],A[7],A[3],A[4],A[8],A[12]),abs2(P)<=this.epsilon&&(P=this.normal(A[12],A[13],A[14],A[15],A[2],A[1],A[0])));let L=this.Epsilon,D=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])];if(!h)if(h=Straightness(x,e[4],e[8],M)<this.res2){let e=unit(this.differential(A[0],A[1],A[2],A[3]));D=[D[0]-L*e[0],D[1]-L*e[1],D[2]-L*e[2]]}else D=I[12];let y=[.5*(o[0]+l[0]),.5*(o[1]+l[1]),.5*(o[2]+l[2])];if(!d)if(d=Straightness(b,e[11],e[7],w)<this.res2){let e=unit(this.differential(I[15],I[14],I[13],I[12]));y=[y[0]-L*e[0],y[1]-L*e[1],y[2]-L*e[2]]}else y=A[3];if(f){let e=Array(4),v=Array(4);for(let t=0;t<4;++t)e[t]=.5*(f[t]+u[t]),v[t]=.5*(p[t]+g[t]);let x=this.data.Vertex(D,E,e),w=this.data.Vertex(y,P,v);this.Render(I,t,x,w,n,r,D,y,l,h,!1,d,m,f,e,v,g),this.Render(A,x,i,a,w,D,s,o,y,h,c,d,!1,e,u,p,v)}else{let e=this.vertex(D,E),f=this.vertex(y,P);this.Render(I,t,e,f,n,r,D,y,l,h,!1,d,m),this.Render(A,e,i,a,f,D,s,o,y,h,c,d,!1)}return}let T=new Split3(x,e[1],e[2],w),S=new Split3(e[4],e[5],e[6],e[7]),R=new Split3(e[8],e[9],e[10],e[11]),I=new Split3(M,e[13],e[14],b),A=new Split3(x,e[4],e[8],M),E=new Split3(T.m0,S.m0,R.m0,I.m0),P=new Split3(T.m3,S.m3,R.m3,I.m3),L=new Split3(T.m5,S.m5,R.m5,I.m5),D=new Split3(T.m4,S.m4,R.m4,I.m4),y=new Split3(T.m2,S.m2,R.m2,I.m2),O=new Split3(w,e[7],e[11],b),B=[x,T.m0,T.m3,T.m5,A.m0,E.m0,P.m0,L.m0,A.m3,E.m3,P.m3,L.m3,A.m5,E.m5,P.m5,L.m5],N=[A.m5,E.m5,P.m5,L.m5,A.m4,E.m4,P.m4,L.m4,A.m2,E.m2,P.m2,L.m2,M,I.m0,I.m3,I.m5],z=[L.m5,D.m5,y.m5,O.m5,L.m4,D.m4,y.m4,O.m4,L.m2,D.m2,y.m2,O.m2,I.m5,I.m4,I.m2,b],_=[T.m5,T.m4,T.m2,w,L.m0,D.m0,y.m0,O.m0,L.m3,D.m3,y.m3,O.m3,L.m5,D.m5,y.m5,O.m5],C=B[15],V=this.normal(B[0],B[4],B[8],B[12],B[13],B[14],B[15]);abs2(V)<this.epsilon&&(V=this.normal(B[0],B[4],B[8],B[12],B[11],B[7],B[3]),abs2(V)<this.epsilon&&(V=this.normal(B[3],B[2],B[1],B[0],B[13],B[14],B[15])));let U=this.normal(N[12],N[13],N[14],N[15],N[11],N[7],N[3]);abs2(U)<this.epsilon&&(U=this.normal(N[12],N[13],N[14],N[15],N[2],N[1],N[0]),abs2(U)<this.epsilon&&(U=this.normal(N[0],N[4],N[8],N[12],N[11],N[7],N[3])));let H=this.normal(z[15],z[11],z[7],z[3],z[2],z[1],z[0]);abs2(H)<this.epsilon&&(H=this.normal(z[15],z[11],z[7],z[3],z[4],z[8],z[12]),abs2(H)<this.epsilon&&(H=this.normal(z[12],z[13],z[14],z[15],z[2],z[1],z[0])));let F=this.normal(_[3],_[2],_[1],_[0],_[4],_[8],_[12]);abs2(F)<this.epsilon&&(F=this.normal(_[3],_[2],_[1],_[0],_[13],_[14],_[15]),abs2(F)<this.epsilon&&(F=this.normal(_[15],_[11],_[7],_[3],_[4],_[8],_[12])));let G=this.normal(z[3],z[2],z[1],C,z[4],z[8],z[12]),X=this.Epsilon,W=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])];if(!h)if(h=Straightness(x,e[4],e[8],M)<this.res2){let e=unit(this.differential(N[0],N[1],N[2],N[3]));W=[W[0]-X*e[0],W[1]-X*e[1],W[2]-X*e[2]]}else W=B[12];let j=[.5*(s[0]+o[0]),.5*(s[1]+o[1]),.5*(s[2]+o[2])];if(!c)if(c=Straightness(M,e[13],e[14],b)<this.res2){let e=unit(this.differential(z[12],z[8],z[4],z[0]));j=[j[0]-X*e[0],j[1]-X*e[1],j[2]-X*e[2]]}else j=N[15];let Z=[.5*(o[0]+l[0]),.5*(o[1]+l[1]),.5*(o[2]+l[2])];if(!d)if(d=Straightness(b,e[11],e[7],w)<this.res2){let e=unit(this.differential(_[15],_[14],_[13],_[12]));Z=[Z[0]-X*e[0],Z[1]-X*e[1],Z[2]-X*e[2]]}else Z=z[3];let k=[.5*(l[0]+r[0]),.5*(l[1]+r[1]),.5*(l[2]+r[2])];if(!m)if(m=Straightness(x,e[1],e[2],w)<this.res2){let e=unit(this.differential(B[3],B[7],B[11],B[15]));k=[k[0]-X*e[0],k[1]-X*e[1],k[2]-X*e[2]]}else k=_[0];if(f){let e=Array(4),v=Array(4),x=Array(4),w=Array(4),M=Array(4);for(let t=0;t<4;++t)e[t]=.5*(f[t]+u[t]),v[t]=.5*(u[t]+p[t]),x[t]=.5*(p[t]+g[t]),w[t]=.5*(g[t]+f[t]),M[t]=.5*(e[t]+x[t]);let b=this.data.Vertex(W,V,e),T=this.data.Vertex(j,U,v),S=this.data.Vertex(Z,H,x),R=this.data.Vertex(k,F,w),I=this.data.Vertex(C,G,M);this.Render(B,t,b,I,R,r,W,C,k,h,!1,!1,m,f,e,M,w),this.Render(N,b,i,T,I,W,s,j,C,h,c,!1,!1,e,u,v,M),this.Render(z,I,T,a,S,C,j,o,Z,!1,c,d,!1,M,v,p,x),this.Render(_,R,I,S,n,k,C,Z,l,!1,!1,d,m,w,M,x,g)}else{let e=this.vertex(W,V),f=this.vertex(j,U),u=this.vertex(Z,H),p=this.vertex(k,F),g=this.vertex(C,G);this.Render(B,t,e,g,p,r,W,C,k,h,!1,!1,m),this.Render(N,e,i,f,g,W,s,j,C,h,c,!1,!1),this.Render(z,g,f,a,u,C,j,o,Z,!1,c,d,!1),this.Render(_,p,g,u,n,k,C,Z,l,!1,!1,d,m)}}}process3(e){if(1==wireframe)return this.curve(e,0,1,3,6),this.curve(e,6,7,8,9),void this.curve(e,9,5,2,0);let t=e[0],i=e[6],a=e[9],n=this.normal(a,e[5],e[2],t,e[1],e[3],i),r=this.normal(t,e[1],e[3],i,e[7],e[8],a),s=this.normal(i,e[7],e[8],a,e[5],e[2],t);if(this.color){let o=this.color[0],l=this.color[1],h=this.color[2],c=this.data.Vertex(t,n,o),d=this.data.Vertex(i,r,l),m=this.data.Vertex(a,s,h);this.Render3(e,c,d,m,t,i,a,!1,!1,!1,o,l,h)}else{let o=this.vertex(t,n),l=this.vertex(i,r),h=this.vertex(a,s);this.Render3(e,o,l,h,t,i,a,!1,!1,!1)}this.data.indices.length>0&&this.append()}Render3(e,t,i,a,n,r,s,o,l,h,c,d,m){if(this.Distance3(e)<this.res2)this.offscreen([n,r,s])||(0==wireframe?(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(a)):(this.data.indices.push(t),this.data.indices.push(i),this.data.indices.push(i),this.data.indices.push(a),this.data.indices.push(a),this.data.indices.push(t)));else{if(this.offscreen(e))return;let f=e[0],u=e[1],p=e[2],g=e[3],v=e[4],x=e[5],w=e[6],M=e[7],b=e[8],T=e[9],S=[.5*(T[0]+x[0]),.5*(T[1]+x[1]),.5*(T[2]+x[2])],R=[.5*(T[0]+b[0]),.5*(T[1]+b[1]),.5*(T[2]+b[2])],I=[.5*(x[0]+p[0]),.5*(x[1]+p[1]),.5*(x[2]+p[2])],A=[.5*(b[0]+v[0]),.5*(b[1]+v[1]),.5*(b[2]+v[2])],E=[.5*(b[0]+M[0]),.5*(b[1]+M[1]),.5*(b[2]+M[2])],P=[.5*(p[0]+v[0]),.5*(p[1]+v[1]),.5*(p[2]+v[2])],L=[.5*(p[0]+f[0]),.5*(p[1]+f[1]),.5*(p[2]+f[2])],D=[.5*(v[0]+g[0]),.5*(v[1]+g[1]),.5*(v[2]+g[2])],y=[.5*(M[0]+w[0]),.5*(M[1]+w[1]),.5*(M[2]+w[2])],O=[.5*(f[0]+u[0]),.5*(f[1]+u[1]),.5*(f[2]+u[2])],B=[.5*(u[0]+g[0]),.5*(u[1]+g[1]),.5*(u[2]+g[2])],N=[.5*(g[0]+w[0]),.5*(g[1]+w[1]),.5*(g[2]+w[2])],z=[.5*(S[0]+I[0]),.5*(S[1]+I[1]),.5*(S[2]+I[2])],_=[.5*(R[0]+E[0]),.5*(R[1]+E[1]),.5*(R[2]+E[2])],C=[.5*(I[0]+L[0]),.5*(I[1]+L[1]),.5*(I[2]+L[2])],V=[.5*A[0]+.25*(v[0]+u[0]),.5*A[1]+.25*(v[1]+u[1]),.5*A[2]+.25*(v[2]+u[2])],U=[.5*(E[0]+y[0]),.5*(E[1]+y[1]),.5*(E[2]+y[2])],H=[.5*P[0]+.25*(v[0]+M[0]),.5*P[1]+.25*(v[1]+M[1]),.5*P[2]+.25*(v[2]+M[2])],F=[.25*(x[0]+v[0])+.5*D[0],.25*(x[1]+v[1])+.5*D[1],.25*(x[2]+v[2])+.5*D[2]],G=[.5*(O[0]+B[0]),.5*(O[1]+B[1]),.5*(O[2]+B[2])],X=[.5*(B[0]+N[0]),.5*(B[1]+N[1]),.5*(B[2]+N[2])],W=[.5*(H[0]+G[0]),.5*(H[1]+G[1]),.5*(H[2]+G[2])],j=[.5*(H[0]+X[0]),.5*(H[1]+X[1]),.5*(H[2]+X[2])],Z=[.5*(G[0]+X[0]),.5*(G[1]+X[1]),.5*(G[2]+X[2])],k=[.5*(F[0]+U[0]),.5*(F[1]+U[1]),.5*(F[2]+U[2])],Y=[.5*(_[0]+F[0]),.5*(_[1]+F[1]),.5*(_[2]+F[2])],q=[.5*(_[0]+U[0]),.5*(_[1]+U[1]),.5*(_[2]+U[2])],$=[.5*(z[0]+V[0]),.5*(z[1]+V[1]),.5*(z[2]+V[2])],K=[.5*(C[0]+V[0]),.5*(C[1]+V[1]),.5*(C[2]+V[2])],Q=[.5*(z[0]+C[0]),.5*(z[1]+C[1]),.5*(z[2]+C[2])],J=[f,O,L,G,[.5*(P[0]+O[0]),.5*(P[1]+O[1]),.5*(P[2]+O[2])],C,Z,W,K,Q],ee=[Z,X,j,N,[.5*(D[0]+y[0]),.5*(D[1]+y[1]),.5*(D[2]+y[2])],k,w,y,U,q],te=[Q,$,z,Y,[.5*(S[0]+A[0]),.5*(S[1]+A[1]),.5*(S[2]+A[2])],S,q,_,R,T],ie=[q,Y,k,$,[.25*(I[0]+E[0]+B[0]+v[0]),.25*(I[1]+E[1]+B[1]+v[1]),.25*(I[2]+E[2]+B[2]+v[2])],j,Q,K,W,Z],ae=this.normal(Z,j,k,q,Y,$,Q),ne=this.normal(q,Y,$,Q,K,W,Z),re=this.normal(Q,K,W,Z,j,k,q),se=this.Epsilon,oe=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])];if(!o)if(o=Straightness(w,M,b,T)<this.res2){let e=unit(this.sumdifferential(ie[0],ie[2],ie[5],ie[9],ie[1],ie[3],ie[6]));oe=[oe[0]-se*e[0],oe[1]-se*e[1],oe[2]-se*e[2]]}else oe=q;let le=[.5*(s[0]+n[0]),.5*(s[1]+n[1]),.5*(s[2]+n[2])];if(!l)if(l=Straightness(f,p,x,T)<this.res2){let e=unit(this.sumdifferential(ie[6],ie[3],ie[1],ie[0],ie[7],ie[8],ie[9]));le=[le[0]-se*e[0],le[1]-se*e[1],le[2]-se*e[2]]}else le=Q;let he=[.5*(n[0]+r[0]),.5*(n[1]+r[1]),.5*(n[2]+r[2])];if(!h)if(h=Straightness(f,u,g,w)<this.res2){let e=unit(this.sumdifferential(ie[9],ie[8],ie[7],ie[6],ie[5],ie[2],ie[0]));he=[he[0]-se*e[0],he[1]-se*e[1],he[2]-se*e[2]]}else he=Z;if(c){let e=Array(4),f=Array(4),u=Array(4);for(let t=0;t<4;++t)e[t]=.5*(d[t]+m[t]),f[t]=.5*(m[t]+c[t]),u[t]=.5*(c[t]+d[t]);let p=this.data.Vertex(oe,ae,e),g=this.data.Vertex(le,ne,f),v=this.data.Vertex(he,re,u);this.Render3(J,t,v,g,n,he,le,!1,l,h,c,u,f),this.Render3(ee,v,i,p,he,r,oe,o,!1,h,u,d,e),this.Render3(te,g,p,a,le,oe,s,o,l,!1,f,e,m),this.Render3(ie,p,g,v,oe,le,he,!1,!1,!1,e,f,u)}else{let e=this.vertex(oe,ae),c=this.vertex(le,ne),d=this.vertex(he,re);this.Render3(J,t,d,c,n,he,le,!1,l,h),this.Render3(ee,d,i,e,he,r,oe,o,!1,h),this.Render3(te,c,e,a,le,oe,s,o,l,!1),this.Render3(ie,e,c,d,oe,le,he,!1,!1,!1)}}}Distance(e){let t=e[0],i=e[3],a=e[12],n=e[15],r=Flatness(t,a,i,n);r=Math.max(Straightness(t,e[4],e[8],a)),r=Math.max(r,Straightness(e[1],e[5],e[9],e[13])),r=Math.max(r,Straightness(i,e[7],e[11],n)),r=Math.max(r,Straightness(e[2],e[6],e[10],e[14]));let s=Flatness(t,i,a,n);return s=Math.max(s,Straightness(t,e[1],e[2],i)),s=Math.max(s,Straightness(e[4],e[5],e[6],e[7])),s=Math.max(s,Straightness(e[8],e[9],e[10],e[11])),s=Math.max(s,Straightness(a,e[13],e[14],n)),[r,s]}Distance3(e){let t=e[0],i=e[4],a=e[6],n=e[9],r=abs2([(t[0]+a[0]+n[0])*(1/3)-i[0],(t[1]+a[1]+n[1])*(1/3)-i[1],(t[2]+a[2]+n[2])*(1/3)-i[2]]);return r=Math.max(r,Straightness(t,e[1],e[3],a)),r=Math.max(r,Straightness(t,e[2],e[5],n)),Math.max(r,Straightness(a,e[7],e[8],n))}differential(e,t,i,a){let n=[3*(t[0]-e[0]),3*(t[1]-e[1]),3*(t[2]-e[2])];return abs2(n)>this.epsilon?n:(n=bezierPP(e,t,i),abs2(n)>this.epsilon?n:bezierPPP(e,t,i,a))}sumdifferential(e,t,i,a,n,r,s){let o=this.differential(e,t,i,a),l=this.differential(e,n,r,s);return[o[0]+l[0],o[1]+l[1],o[2]+l[2]]}normal(e,t,i,a,n,r,s){let o=3*(n[0]-a[0]),l=3*(n[1]-a[1]),h=3*(n[2]-a[2]),c=3*(i[0]-a[0]),d=3*(i[1]-a[1]),m=3*(i[2]-a[2]),f=[l*m-h*d,h*c-o*m,o*d-l*c];if(abs2(f)>this.epsilon)return f;let u=[c,d,m],p=[o,l,h],g=bezierPP(a,i,t),v=bezierPP(a,n,r),x=cross(v,u),w=cross(p,g);if(f=[x[0]+w[0],x[1]+w[1],x[2]+w[2]],abs2(f)>this.epsilon)return f;let M=bezierPPP(a,i,t,e),b=bezierPPP(a,n,r,s);x=cross(p,M),w=cross(b,u);let T=cross(v,g);return f=[x[0]+w[0]+T[0],x[1]+w[1]+T[1],x[2]+w[2]+T[2]],abs2(f)>this.epsilon?f:(x=cross(b,g),w=cross(v,M),f=[x[0]+w[0],x[1]+w[1],x[2]+w[2]],abs2(f)>this.epsilon?f:cross(b,M))}}class BezierCurve extends Geometry{constructor(e,t,i,a,n){super(),this.controlpoints=e,this.CenterIndex=t,this.MaterialIndex=i,this.Min=a,this.Max=n}setMaterialIndex(){this.setMaterial(material1Data,drawMaterial1)}processLine(e){let t=e[0],i=e[1];if(!this.offscreen([t,i])){let e=[0,0,1];this.data.indices.push(this.data.vertex(t,e)),this.data.indices.push(this.data.vertex(i,e)),this.append()}}process(e){if(2==e.length)return this.processLine(e);let t=e[0],i=e[1],a=e[2],n=e[3],r=this.normal(bezierP(t,i),bezierPP(t,i,a)),s=this.normal(bezierP(a,n),bezierPP(n,a,i)),o=this.data.vertex(t,r),l=this.data.vertex(n,s);this.Render(e,o,l),this.data.indices.length>0&&this.append()}append(){material1Data.append(this.data)}notRendered(){material1Data.rendered=!1}Render(e,t,i){let a=e[0],n=e[1],r=e[2],s=e[3];if(Straightness(a,n,r,s)<this.res2)this.offscreen([a,s])||(this.data.indices.push(t),this.data.indices.push(i));else{if(this.offscreen(e))return;let o=[.5*(a[0]+n[0]),.5*(a[1]+n[1]),.5*(a[2]+n[2])],l=[.5*(n[0]+r[0]),.5*(n[1]+r[1]),.5*(n[2]+r[2])],h=[.5*(r[0]+s[0]),.5*(r[1]+s[1]),.5*(r[2]+s[2])],c=[.5*(o[0]+l[0]),.5*(o[1]+l[1]),.5*(o[2]+l[2])],d=[.5*(l[0]+h[0]),.5*(l[1]+h[1]),.5*(l[2]+h[2])],m=[.5*(c[0]+d[0]),.5*(c[1]+d[1]),.5*(c[2]+d[2])],f=[a,o,c,m],u=[m,d,h,s],p=this.normal(bezierPh(a,n,r,s),bezierPPh(a,n,r,s)),g=this.data.vertex(m,p);this.Render(f,t,g),this.Render(u,g,i)}}normal(e,t){let i=dot(e,e),a=dot(e,t);return[i*t[0]-a*e[0],i*t[1]-a*e[1],i*t[2]-a*e[2]]}}class Pixel extends Geometry{constructor(e,t,i,a,n){super(),this.controlpoint=e,this.width=t,this.CenterIndex=0,this.MaterialIndex=i,this.Min=a,this.Max=n}setMaterialIndex(){this.setMaterial(material0Data,drawMaterial0)}process(e){this.data.indices.push(this.data.vertex0(this.controlpoint,this.width)),this.append()}append(){material0Data.append(this.data)}notRendered(){material0Data.rendered=!1}}class Triangles extends Geometry{constructor(e,t,i,a){super(),this.CenterIndex=e,this.MaterialIndex=t,this.Min=i,this.Max=a,this.controlpoints=Positions,this.Normals=Normals,this.Colors=Colors,this.Indices=Indices,Positions=[],Normals=[],Colors=[],Indices=[],this.transparent=Materials[this.MaterialIndex].diffuse[3]<1}setMaterialIndex(){this.transparent?this.setMaterial(transparentData,drawTransparent):this.setMaterial(triangleData,drawTriangle)}process(e){this.data.vertices=new Array(6*e.length),materialIndex=this.Colors.length>0?-1-materialIndex:1+materialIndex;for(let t=0,i=this.Indices.length;t<i;++t){let i=this.Indices[t],a=i[0],n=e[a[0]],r=e[a[1]],s=e[a[2]];if(!this.offscreen([n,r,s])){let e=i.length>1?i[1]:a;if(e&&0!=e.length||(e=a),this.Colors.length>0){let t=i.length>2?i[2]:a;t&&0!=t.length||(t=a);let o=this.Colors[t[0]],l=this.Colors[t[1]],h=this.Colors[t[2]];this.transparent|=o[3]+l[3]+h[3]<765,0==wireframe?(this.data.iVertex(a[0],n,this.Normals[e[0]],o),this.data.iVertex(a[1],r,this.Normals[e[1]],l),this.data.iVertex(a[2],s,this.Normals[e[2]],h)):(this.data.iVertex(a[0],n,this.Normals[e[0]],o),this.data.iVertex(a[1],r,this.Normals[e[1]],l),this.data.iVertex(a[1],r,this.Normals[e[1]],l),this.data.iVertex(a[2],s,this.Normals[e[2]],h),this.data.iVertex(a[2],s,this.Normals[e[2]],h),this.data.iVertex(a[0],n,this.Normals[e[0]],o))}else 0==wireframe?(this.data.iVertex(a[0],n,this.Normals[e[0]]),this.data.iVertex(a[1],r,this.Normals[e[1]]),this.data.iVertex(a[2],s,this.Normals[e[2]])):(this.data.iVertex(a[0],n,this.Normals[e[0]]),this.data.iVertex(a[1],r,this.Normals[e[1]]),this.data.iVertex(a[1],r,this.Normals[e[1]]),this.data.iVertex(a[2],s,this.Normals[e[2]]),this.data.iVertex(a[2],s,this.Normals[e[2]]),this.data.iVertex(a[0],n,this.Normals[e[0]]))}}this.data.nvertices=e.length,this.data.indices.length>0&&this.append()}append(){this.transparent?transparentData.append(this.data):triangleData.append(this.data)}notRendered(){this.transparent?transparentData.rendered=!1:triangleData.rendered=!1}}function redrawScene(){initProjection(),setProjection(),remesh=!0,drawScene()}function home(){mat4.identity(rotMat),redrawScene()}let positionAttribute=0,normalAttribute=1,materialAttribute=2,colorAttribute=3,widthAttribute=4;function initShader(e=[]){let t=getShader(gl,vertex,gl.VERTEX_SHADER,e),i=getShader(gl,fragment,gl.FRAGMENT_SHADER,e),a=gl.createProgram();return gl.attachShader(a,t),gl.attachShader(a,i),gl.bindAttribLocation(a,positionAttribute,"position"),gl.bindAttribLocation(a,normalAttribute,"normal"),gl.bindAttribLocation(a,materialAttribute,"materialIndex"),gl.bindAttribLocation(a,colorAttribute,"color"),gl.bindAttribLocation(a,widthAttribute,"width"),gl.linkProgram(a),gl.getProgramParameter(a,gl.LINK_STATUS)||alert("Could not initialize shaders"),a}class Split3{constructor(e,t,i,a){this.m0=[.5*(e[0]+t[0]),.5*(e[1]+t[1]),.5*(e[2]+t[2])];let n=.5*(t[0]+i[0]),r=.5*(t[1]+i[1]),s=.5*(t[2]+i[2]);this.m2=[.5*(i[0]+a[0]),.5*(i[1]+a[1]),.5*(i[2]+a[2])],this.m3=[.5*(this.m0[0]+n),.5*(this.m0[1]+r),.5*(this.m0[2]+s)],this.m4=[.5*(n+this.m2[0]),.5*(r+this.m2[1]),.5*(s+this.m2[2])],this.m5=[.5*(this.m3[0]+this.m4[0]),.5*(this.m3[1]+this.m4[1]),.5*(this.m3[2]+this.m4[2])]}}function unit(e){let t=1/(Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2])||1);return[e[0]*t,e[1]*t,e[2]*t]}function abs2(e){return e[0]*e[0]+e[1]*e[1]+e[2]*e[2]}function dot(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function cross(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}function bezierP(e,t){return[t[0]-e[0],t[1]-e[1],t[2]-e[2]]}function bezierPP(e,t,i){return[3*(e[0]+i[0])-6*t[0],3*(e[1]+i[1])-6*t[1],3*(e[2]+i[2])-6*t[2]]}function bezierPPP(e,t,i,a){return[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])]}function bezierPh(e,t,i,a){return[i[0]+a[0]-e[0]-t[0],i[1]+a[1]-e[1]-t[1],i[2]+a[2]-e[2]-t[2]]}function bezierPPh(e,t,i,a){return[3*e[0]-5*t[0]+i[0]+a[0],3*e[1]-5*t[1]+i[1]+a[1],3*e[2]-5*t[2]+i[2]+a[2]]}function Straightness(e,t,i,a){let n=[1/3*(a[0]-e[0]),1/3*(a[1]-e[1]),1/3*(a[2]-e[2])];return Math.max(abs2([t[0]-n[0]-e[0],t[1]-n[1]-e[1],t[2]-n[2]-e[2]]),abs2([a[0]-n[0]-i[0],a[1]-n[1]-i[1],a[2]-n[2]-i[2]]))}function Flatness(e,t,i,a){let n=[t[0]-e[0],t[1]-e[1],t[2]-e[2]],r=[a[0]-i[0],a[1]-i[1],a[2]-i[2]];return Math.max(abs2(cross(n,unit(r))),abs2(cross(r,unit(n))))/9}function corners(e,t){return[e,[e[0],e[1],t[2]],[e[0],t[1],e[2]],[e[0],t[1],t[2]],[t[0],e[1],e[2]],[t[0],e[1],t[2]],[t[0],t[1],e[2]],t]}function minbound(e){return[Math.min(e[0][0],e[1][0],e[2][0],e[3][0],e[4][0],e[5][0],e[6][0],e[7][0]),Math.min(e[0][1],e[1][1],e[2][1],e[3][1],e[4][1],e[5][1],e[6][1],e[7][1]),Math.min(e[0][2],e[1][2],e[2][2],e[3][2],e[4][2],e[5][2],e[6][2],e[7][2])]}function maxbound(e){return[Math.max(e[0][0],e[1][0],e[2][0],e[3][0],e[4][0],e[5][0],e[6][0],e[7][0]),Math.max(e[0][1],e[1][1],e[2][1],e[3][1],e[4][1],e[5][1],e[6][1],e[7][1]),Math.max(e[0][2],e[1][2],e[2][2],e[3][2],e[4][2],e[5][2],e[6][2],e[7][2])]}function COBTarget(e,t){mat4.fromTranslation(T,[center.x,center.y,center.z]),mat4.invert(cjMatInv,T),mat4.multiply(e,t,cjMatInv),mat4.multiply(e,T,e)}function setUniforms(e,t){let i=t==pixelShader;gl.useProgram(t),gl.enableVertexAttribArray(positionAttribute),i&&gl.enableVertexAttribArray(widthAttribute);let a=!i&&Lights.length>0;if(a&&gl.enableVertexAttribArray(normalAttribute),gl.enableVertexAttribArray(materialAttribute),t.projViewMatUniform=gl.getUniformLocation(t,"projViewMat"),t.viewMatUniform=gl.getUniformLocation(t,"viewMat"),t.normMatUniform=gl.getUniformLocation(t,"normMat"),t!=colorShader&&t!=transparentShader||gl.enableVertexAttribArray(colorAttribute),a)for(let e=0;e<Lights.length;++e)Lights[e].setUniform(t,e);for(let i=0;i<e.materials.length;++i)e.materials[i].setUniform(t,i);gl.uniformMatrix4fv(t.projViewMatUniform,!1,projViewMat),gl.uniformMatrix4fv(t.viewMatUniform,!1,viewMat),gl.uniformMatrix3fv(t.normMatUniform,!1,normMat)}function handleMouseDown(e){zoomEnabled||enableZoom(),mouseDownOrTouchActive=!0,lastMouseX=e.clientX,lastMouseY=e.clientY}let pinchStart,touchStartTime,pinch=!1;function pinchDistance(e){return Math.hypot(e[0].pageX-e[1].pageX,e[0].pageY-e[1].pageY)}function handleTouchStart(e){e.preventDefault(),zoomEnabled||enableZoom();let t=e.targetTouches;swipe=rotate=pinch=!1,zooming||(1!=t.length||mouseDownOrTouchActive||(touchStartTime=(new Date).getTime(),touchId=t[0].identifier,lastMouseX=t[0].pageX,lastMouseY=t[0].pageY),2!=t.length||mouseDownOrTouchActive||(touchId=t[0].identifier,pinchStart=pinchDistance(t),pinch=!0))}function handleMouseUpOrTouchEnd(e){mouseDownOrTouchActive=!1}function rotateScene(e,t,i,a,n){if(e==i&&t==a)return;let[r,s]=arcball([e,-t],[i,-a]);mat4.fromRotation(T,2*n*ArcballFactor*r/Zoom,s),mat4.multiply(rotMat,T,rotMat)}function shiftScene(e,t,i,a){let n=1/Zoom;shift.x+=(i-e)*n*halfCanvasWidth,shift.y-=(a-t)*n*halfCanvasHeight}function panScene(e,t,i,a){orthographic?shiftScene(e,t,i,a):(center.x+=(i-e)*(viewParam.xmax-viewParam.xmin),center.y-=(a-t)*(viewParam.ymax-viewParam.ymin))}function updateViewMatrix(){COBTarget(viewMat,rotMat),mat4.translate(viewMat,viewMat,[center.x,center.y,0]),mat3.fromMat4(viewMat3,viewMat),mat3.invert(normMat,viewMat3),mat4.multiply(projViewMat,projMat,viewMat)}function capzoom(){let e=Math.sqrt(Number.MAX_VALUE),t=1/e;Zoom<=t&&(Zoom=t),Zoom>=e&&(Zoom=e),(1.5*Zoom<lastZoom||Zoom>1.5*lastZoom)&&(remesh=!0,lastZoom=Zoom)}function zoomImage(e){let t=zoomStep*halfCanvasHeight*e;const i=Math.log(.1*Number.MAX_VALUE)/Math.log(zoomFactor);Math.abs(t)<i&&(Zoom*=zoomFactor**t,capzoom())}function normMouse(e){let t=e[0],i=e[1],a=Math.hypot(t,i);return a>1&&(denom=1/a,t*=denom,i*=denom),[t,i,Math.sqrt(Math.max(1-i*i-t*t,0))]}function arcball(e,t){let i=normMouse(e),a=normMouse(t),n=dot(i,a);return[n>1?0:n<-1?pi:Math.acos(n),unit(cross(i,a))]}function zoomScene(e,t,i,a){zoomImage(t-a)}const DRAGMODE_ROTATE=1,DRAGMODE_SHIFT=2,DRAGMODE_ZOOM=3,DRAGMODE_PAN=4;function processDrag(e,t,i,a=1){let n;switch(i){case 1:n=rotateScene;break;case 2:n=shiftScene;break;case 3:n=zoomScene;break;case 4:n=panScene;break;default:n=(e,t,i,a)=>{}}n((lastMouseX-halfCanvasWidth)/halfCanvasWidth,(lastMouseY-halfCanvasHeight)/halfCanvasHeight,(e-halfCanvasWidth)/halfCanvasWidth,(t-halfCanvasHeight)/halfCanvasHeight,a),lastMouseX=e,lastMouseY=t,setProjection(),drawScene()}let zoomEnabled=0;function enableZoom(){zoomEnabled=1,canvas.addEventListener("wheel",handleMouseWheel,!1)}function disableZoom(){zoomEnabled=0,canvas.removeEventListener("wheel",handleMouseWheel,!1)}function handleKey(e){if(zoomEnabled||enableZoom(),embedded&&zoomEnabled&&27==e.keyCode)return void disableZoom();let t=[];switch(e.key){case"x":t=[1,0,0];break;case"y":t=[0,1,0];break;case"z":t=[0,0,1];break;case"h":home();break;case"m":++wireframe,3==wireframe&&(wireframe=0),2!=wireframe&&(embedded||deleteShaders(),initShaders(ibl)),remesh=!0,drawScene();break;case"+":case"=":case">":expand();break;case"-":case"_":case"<":shrink()}t.length>0&&(mat4.rotate(rotMat,rotMat,.1,t),updateViewMatrix(),drawScene())}function setZoom(){capzoom(),setProjection(),drawScene()}function handleMouseWheel(e){e.preventDefault(),e.deltaY<0?Zoom*=zoomFactor:Zoom/=zoomFactor,setZoom()}function handleMouseMove(e){if(!mouseDownOrTouchActive)return;let t,i=e.clientX,a=e.clientY;t=e.getModifierState("Control")?2:e.getModifierState("Shift")?3:e.getModifierState("Alt")?4:1,processDrag(i,a,t)}let zooming=!1,swipe=!1,rotate=!1;function handleTouchMove(e){if(e.preventDefault(),zooming)return;let t=e.targetTouches;if(!pinch&&1==t.length&&touchId==t[0].identifier){let e=t[0].pageX,i=t[0].pageY,a=e-lastMouseX,n=i-lastMouseY,r=a*a+n*n<=shiftHoldDistance*shiftHoldDistance;if(r&&!swipe&&!rotate&&(new Date).getTime()-touchStartTime>shiftWaitTime&&(navigator.vibrate&&window.navigator.vibrate(vibrateTime),swipe=!0),swipe)processDrag(e,i,2);else if(!r){rotate=!0,processDrag(t[0].pageX,t[0].pageY,1,.5)}}if(pinch&&!swipe&&2==t.length&&touchId==t[0].identifier){let e=pinchDistance(t),i=e-pinchStart;zooming=!0,i*=zoomPinchFactor,i>zoomPinchCap&&(i=zoomPinchCap),i<-zoomPinchCap&&(i=-zoomPinchCap),zoomImage(i/size2),pinchStart=e,swipe=rotate=zooming=!1,setProjection(),drawScene()}}let pixelShader,materialShader,colorShader,transparentShader,zbuffer=[];function transformVertices(e){let t=viewMat[2],i=viewMat[6],a=viewMat[10];zbuffer.length=e.length;for(let n=0;n<e.length;++n){let r=6*n;zbuffer[n]=t*e[r]+i*e[r+1]+a*e[r+2]}}function drawMaterial0(){drawBuffer(material0Data,pixelShader),material0Data.clear()}function drawMaterial1(){drawBuffer(material1Data,materialShader),material1Data.clear()}function drawMaterial(){drawBuffer(materialData,materialShader),materialData.clear()}function drawColor(){drawBuffer(colorData,colorShader),colorData.clear()}function drawTriangle(){drawBuffer(triangleData,transparentShader),triangleData.rendered=!1,triangleData.clear()}function drawTransparent(){let e=transparentData.indices;if(wireframe>0)return drawBuffer(transparentData,transparentShader,e),void transparentData.clear();if(e.length>0){transformVertices(transparentData.vertices);let t=e.length/3,i=Array(t).fill().map((e,t)=>t);i.sort((function(t,i){let a=3*t;Ia=e[a],Ib=e[a+1],Ic=e[a+2];let n=3*i;return IA=e[n],IB=e[n+1],IC=e[n+2],zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic]<zbuffer[IA]+zbuffer[IB]+zbuffer[IC]?-1:1}));let a=Array(e.length);for(let n=0;n<t;++n){let t=3*i[n];a[3*n]=e[t],a[3*n+1]=e[t+1],a[3*n+2]=e[t+2]}gl.depthMask(!1),drawBuffer(transparentData,transparentShader,a),transparentData.rendered=!1,gl.depthMask(!0)}transparentData.clear()}function drawBuffers(){drawMaterial0(),drawMaterial1(),drawMaterial(),drawColor(),drawTriangle(),drawTransparent(),requestAnimationFrame(drawBuffers)}function drawScene(){embedded&&(offscreen2.width=canvasWidth,offscreen2.height=canvasHeight,setViewport()),gl.clearColor(Background[0],Background[1],Background[2],Background[3]),gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);for(let e=0;e<P.length;++e)P[e].render();drawBuffers(),embedded&&(context.clearRect(0,0,canvasWidth,canvasHeight),context.drawImage(offscreen2,0,0)),0==wireframe&&(remesh=!1)}function setDimensions(e,t,i,a){let n=e/t,r=1/Zoom,s=(i/e+viewportShift[0])*Zoom,o=(a/t+viewportShift[1])*Zoom;if(orthographic){let e=maxBound[0]-minBound[0],t=maxBound[1]-minBound[1];if(e<t*n){let e=.5*t*n*r,i=2*e*s,a=t*r*o;viewParam.xmin=-e-i,viewParam.xmax=e-i,viewParam.ymin=minBound[1]*r-a,viewParam.ymax=maxBound[1]*r-a}else{let t=.5*e/(n*Zoom),i=e*r*s,a=2*t*o;viewParam.xmin=minBound[0]*r-i,viewParam.xmax=maxBound[0]*r-i,viewParam.ymin=-t-a,viewParam.ymax=t-a}}else{let e=H*r,t=e*n,i=2*t*s,a=2*e*o;viewParam.xmin=-t-i,viewParam.xmax=t-i,viewParam.ymin=-e-a,viewParam.ymax=e-a}}function setProjection(){setDimensions(canvasWidth,canvasHeight,shift.x,shift.y),(orthographic?mat4.ortho:mat4.frustum)(projMat,viewParam.xmin,viewParam.xmax,viewParam.ymin,viewParam.ymax,-viewParam.zmax,-viewParam.zmin),updateViewMatrix()}function initProjection(){H=-Math.tan(.5*angleOfView)*maxBound[2],center.x=center.y=0,center.z=.5*(minBound[2]+maxBound[2]),lastZoom=Zoom=zoom0,viewParam.zmin=minBound[2],viewParam.zmax=maxBound[2],shift.x=shift.y=0}function setViewport(){gl.viewportWidth=canvasWidth,gl.viewportHeight=canvasHeight,gl.viewport(.5*(canvas.width-canvasWidth),.5*(canvas.height-canvasHeight),canvasWidth,canvasHeight),gl.scissor(0,0,canvas.width,canvas.height)}function setCanvas(){embedded&&(canvas.width=offscreen2.width=canvasWidth,canvas.height=offscreen2.height=canvasHeight),size2=Math.hypot(canvasWidth,canvasHeight),halfCanvasWidth=.5*canvas.width,halfCanvasHeight=.5*canvas.height,ArcballFactor=1+8*Math.hypot(viewportMargin[0],viewportMargin[1])/size2}function setsize(e,t){e>maxViewportWidth&&(e=maxViewportWidth),t>maxViewportHeight&&(t=maxViewportHeight),shift.x*=e/canvasWidth,shift.y*=t/canvasHeight,canvasWidth=e,canvasHeight=t,setCanvas(),setViewport(),setProjection(),remesh=!0}function resize(){if(zoom0=initialZoom,absolute&&!embedded)canvasWidth=canvasWidth0*window.devicePixelRatio,canvasHeight=canvasHeight0*window.devicePixelRatio;else{let e=canvasWidth0/canvasHeight0;canvasWidth=Math.max(window.innerWidth-10,10),canvasHeight=Math.max(window.innerHeight-10,10),!orthographic&&canvasWidth<canvasHeight*e&&(zoom0*=canvasWidth/(canvasHeight*e))}canvas.width=canvasWidth,canvas.height=canvasHeight;window.innerWidth,window.innerHeight;viewportShift[0]/=zoom0,viewportShift[1]/=zoom0,setsize(canvasWidth,canvasHeight),redrawScene()}function expand(){Zoom*=zoomFactor,setZoom()}function shrink(){Zoom/=zoomFactor,setZoom()}class Align{constructor(e,t){if(this.center=e,t){let e=t[0],i=t[1];this.ct=Math.cos(e),this.st=Math.sin(e),this.cp=Math.cos(i),this.sp=Math.sin(i)}}T0(e){return[e[0]+this.center[0],e[1]+this.center[1],e[2]+this.center[2]]}T(e){let t=e[0],i=e[1],a=e[2],n=t*this.ct+a*this.st;return[n*this.cp-i*this.sp+this.center[0],n*this.sp+i*this.cp+this.center[1],-t*this.st+a*this.ct+this.center[2]]}}function Tcorners(e,t,i){let a=[e(t),e([t[0],t[1],i[2]]),e([t[0],i[1],t[2]]),e([t[0],i[1],i[2]]),e([i[0],t[1],t[2]]),e([i[0],t[1],i[2]]),e([i[0],i[1],t[2]]),e(i)];return[minbound(a),maxbound(a)]}function material(e,t,i,a,n,r){Materials.push(new Material(e,t,i,a,n,r))}function patch(e,t,i,a,n,r){P.push(new BezierPatch(e,t,i,a,n,r))}function curve(e,t,i,a,n){P.push(new BezierCurve(e,t,i,a,n))}function pixel(e,t,i,a,n){P.push(new Pixel(e,t,i,a,n))}function triangles(e,t,i,a){P.push(new Triangles(e,t,i,a))}function sphere(e,t,i,n,r){let s,o,l,h,c,d,m=.524670512339254,f=.595936986722291,u=.954967051233925,p=.0820155480083437,g=.996685028842544,v=.0549670512339254,x=.998880711874577,w=.0405017186586849,M=[[[1,0,0],[1,0,m],[f,0,u],[p,0,g],[1,a,0],[1,a,m],[f,a*f,u],[p,a*p,g],[a,1,0],[a,1,m],[a*f,f,u],[a*p,p,g],[0,1,0],[0,1,m],[0,f,u],[0,p,g]],[[p,0,g],[p,a*p,g],[v,0,x],[a*p,p,g],[w,w,1],[.05*a,0,1],[0,p,g],[0,v,x],[0,.05*a,1],[0,0,1]]],b=new Align(e,r);function T(e){let t=Array(e.length);for(let i=0;i<e.length;++i){let a=e[i];t[i]=c([s*a[0],o*a[1],l*a[2]])}return t}r?(h=1,d=0,c=b.T.bind(b)):(h=-1,d=-t,c=b.T0.bind(b));let S=Tcorners(c,[-t,-t,d],[t,t,t]),R=S[0],I=S[1];for(let e=-1;e<=1;e+=2){s=e*t;for(let e=-1;e<=1;e+=2){o=e*t;for(let e=h;e<=1;e+=2){l=e*t;for(let e=0;e<2;++e)P.push(new BezierPatch(T(M[e]),i,n,R,I))}}}}let a=4/3*(Math.sqrt(2)-1);function disk(e,t,i,n,r){let s=1-2*a/3,o=[[1,0,0],[1,-a,0],[a,-1,0],[0,-1,0],[1,a,0],[s,0,0],[0,-s,0],[-a,-1,0],[a,1,0],[0,s,0],[-s,0,0],[-1,-a,0],[0,1,0],[-a,1,0],[-1,a,0],[-1,0,0]],l=new Align(e,r);let h=Tcorners(l.T.bind(l),[-t,-t,0],[t,t,0]);P.push(new BezierPatch(function(e){let i=Array(e.length);for(let a=0;a<e.length;++a){let n=e[a];i[a]=l.T([t*n[0],t*n[1],0])}return i}(o),i,n,h[0],h[1]))}function cylinder(e,t,i,n,r,s,o){let l,h,c=[[1,0,0],[1,0,1/3],[1,0,2/3],[1,0,1],[1,a,0],[1,a,1/3],[1,a,2/3],[1,a,1],[a,1,0],[a,1,1/3],[a,1,2/3],[a,1,1],[0,1,0],[0,1,1/3],[0,1,2/3],[0,1,1]],d=new Align(e,s);function m(e){let t=Array(e.length);for(let a=0;a<e.length;++a){let n=e[a];t[a]=d.T([l*n[0],h*n[1],i*n[2]])}return t}let f=Tcorners(d.T.bind(d),[-t,-t,0],[t,t,i]),u=f[0],p=f[1];for(let e=-1;e<=1;e+=2){l=e*t;for(let e=-1;e<=1;e+=2)h=e*t,P.push(new BezierPatch(m(c),n,r,u,p))}if(o){let t=d.T([0,0,i]);P.push(new BezierCurve([e,t],n,r,e,t))}}function rmf(e,t,i,a,n){class r{constructor(e,t,i){this.p=e,this.r=t,this.t=i,this.s=cross(i,t)}}let s=Number.EPSILON*Math.max(abs2(e),abs2(t),abs2(i),abs2(a));function o(n){if(1==n){let n=[a[0]-i[0],a[1]-i[1],a[2]-i[2]];return abs2(n)>s?unit(n):(n=[2*i[0]-t[0]-a[0],2*i[1]-t[1]-a[1],2*i[2]-t[2]-a[2]],abs2(n)>s?unit(n):[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])])}let r=[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])],o=[2*(e[0]+i[0])-4*t[0],2*(e[1]+i[1])-4*t[1],2*(e[2]+i[2])-4*t[2]],l=[t[0]-e[0],t[1]-e[1],t[2]-e[2]],h=n*n,c=[r[0]*h+o[0]*n+l[0],r[1]*h+o[1]*n+l[1],r[2]*h+o[2]*n+l[2]];return abs2(c)>s?unit(c):(h=2*n,c=[r[0]*h+o[0],r[1]*h+o[1],r[2]*h+o[2]],abs2(c)>s?unit(c):unit(r))}let l=Array(n.length),h=[t[0]-e[0],t[1]-e[1],t[2]-e[2]];abs2(h)<s&&(h=[e[0]-2*t[0]+i[0],e[1]-2*t[1]+i[1],e[2]-2*t[2]+i[2]],abs2(h)<s&&(h=[a[0]-e[0]+3*(t[0]-i[0]),a[1]-e[1]+3*(t[1]-i[1]),a[2]-e[2]+3*(t[2]-i[2])])),h=unit(h);let c=function(e){let t=cross(e,[0,1,0]),i=Number.EPSILON*abs2(e);return abs2(t)>i?unit(t):(t=cross(e,[0,0,1]),abs2(t)>i?unit(t):[1,0,0])}(h);l[0]=new r(e,c,h);for(let s=1;s<n.length;++s){let h=l[s-1],c=n[s],d=1-c,m=d*d,f=m*d,u=3*c;m*=u,d*=u*c;let p=c*c*c,g=[f*e[0]+m*t[0]+d*i[0]+p*a[0],f*e[1]+m*t[1]+d*i[1]+p*a[1],f*e[2]+m*t[2]+d*i[2]+p*a[2]],v=[g[0]-h.p[0],g[1]-h.p[1],g[2]-h.p[2]];if(0!=v[0]||0!=v[1]||0!=v[2]){let e=h.r,t=unit(v),i=h.t,a=dot(t,i),n=[i[0]-2*a*t[0],i[1]-2*a*t[1],i[2]-2*a*t[2]];i=o(c);let d=2*dot(t,e),m=[e[0]-d*t[0],e[1]-d*t[1],e[2]-d*t[2]],f=unit([i[0]-n[0],i[1]-n[1],i[2]-n[2]]),u=2*dot(f,m);m=[m[0]-u*f[0],m[1]-u*f[1],m[2]-u*f[2]],l[s]=new r(g,unit(m),unit(i))}else l[s]=l[s-1]}return l}function tube(e,t,i,n,r,s,o){let l=rmf(e[0],e[1],e[2],e[3],[0,1/3,2/3,1]),h=a*t,c=[[t,0],[t,h],[h,t],[0,t]];function d(t,a,o,h){let d=Array(16);for(let i=0;i<4;++i){let n=l[i],r=n.r[0],s=n.s[0],m=r*t+s*a,f=r*o+s*h;r=n.r[1],s=n.s[1];let u=r*t+s*a,p=r*o+s*h;r=n.r[2],s=n.s[2];let g=r*t+s*a,v=r*o+s*h,x=e[i],w=x[0];w1=x[1],w2=x[2];for(let e=0;e<4;++e){let t=c[e],a=t[0],n=t[1];d[4*i+e]=[m*a+f*n+w,u*a+p*n+w1,g*a+v*n+w2]}}P.push(new BezierPatch(d,i,n,r,s))}d(1,0,0,1),d(0,-1,1,0),d(-1,0,0,-1),d(0,1,-1,0),o&&P.push(new BezierCurve(e,i,n,r,s))}async function getReq(e){return(await fetch(e)).arrayBuffer()}function rgb(e){return e.getBytes().filter((e,t)=>t%4!=3)}function createTexture(e,t,i=gl.RGB16F){let a=e.width(),n=e.height(),r=gl.createTexture();return gl.activeTexture(gl.TEXTURE0+t),gl.bindTexture(gl.TEXTURE_2D,r),gl.pixelStorei(gl.UNPACK_ALIGNMENT,1),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR),gl.texImage2D(gl.TEXTURE_2D,0,i,a,n,0,gl.RGB,gl.FLOAT,rgb(e)),r}async function initIBL(){let e=imageURL+image+"/";function t(e){return new Promise(t=>setTimeout(t,e))}for(;!Module.EXRLoader;)await t(0);promises=[getReq(imageURL+"refl.exr").then(e=>{let t=new Module.EXRLoader(e);IBLbdrfMap=createTexture(t,0)}),getReq(e+"diffuse.exr").then(e=>{let t=new Module.EXRLoader(e);IBLDiffuseMap=createTexture(t,1)})],refl_promise=[],refl_promise.push(getReq(e+"refl0.exr"));for(let t=1;t<=roughnessStepCount;++t)refl_promise.push(getReq(e+"refl"+t+"w.exr"));finished_promise=Promise.all(refl_promise).then(e=>{let t=gl.createTexture();gl.activeTexture(gl.TEXTURE0+2),gl.pixelStorei(gl.UNPACK_ALIGNMENT,1),gl.bindTexture(gl.TEXTURE_2D,t),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAX_LEVEL,e.length-1),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR_MIPMAP_LINEAR),gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR),gl.texParameterf(gl.TEXTURE_2D,gl.TEXTURE_MIN_LOD,0),gl.texParameterf(gl.TEXTURE_2D,gl.TEXTURE_MAX_LOD,roughnessStepCount);for(let t=0;t<e.length;++t){let i=new Module.EXRLoader(e[t]);gl.texImage2D(gl.TEXTURE_2D,t,gl.RGB16F,i.width(),i.height(),0,gl.RGB,gl.FLOAT,rgb(i))}IBLReflMap=t}),promises.push(finished_promise),await Promise.all(promises)}function webGLStart(){canvas=document.getElementById("Asymptote"),embedded=window.top.document!=document,initGL(),gl.enable(gl.BLEND),gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA),gl.enable(gl.DEPTH_TEST),gl.enable(gl.SCISSOR_TEST),canvas.onmousedown=handleMouseDown,document.onmouseup=handleMouseUpOrTouchEnd,document.onmousemove=handleMouseMove,canvas.onkeydown=handleKey,embedded||enableZoom(),canvas.addEventListener("touchstart",handleTouchStart,!1),canvas.addEventListener("touchend",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchcancel",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchleave",handleMouseUpOrTouchEnd,!1),canvas.addEventListener("touchmove",handleTouchMove,!1),document.addEventListener("keydown",handleKey,!1),canvasWidth0=canvasWidth,canvasHeight0=canvasHeight,mat4.identity(rotMat),0!=window.innerWidth&&0!=window.innerHeight&&resize(),window.addEventListener("resize",resize,!1),ibl&&initIBL().then(SetIBL).then(redrawScene)}
diff --git a/graphics/asymptote/base/x11colors.asy b/graphics/asymptote/base/x11colors.asy
index 77e0401f06..eb65e5346f 100644
--- a/graphics/asymptote/base/x11colors.asy
+++ b/graphics/asymptote/base/x11colors.asy
@@ -1,4 +1,4 @@
-pen rgbint(int r, int g, int b)
+pen rgbint(int r, int g, int b)
{
return rgb(r/255,g/255,b/255);
}
diff --git a/graphics/asymptote/bbox.h b/graphics/asymptote/bbox.h
index 3edbe45d7e..f68bd4022f 100644
--- a/graphics/asymptote/bbox.h
+++ b/graphics/asymptote/bbox.h
@@ -174,11 +174,13 @@ struct bbox {
*this=bbox();
}
- void shift(const pair& p) {
- left += p.getx();
- right += p.getx();
- bottom += p.gety();
- top += p.gety();
+ bbox shift(const pair& p) const {
+ bbox b=*this;
+ b.left += p.getx();
+ b.right += p.getx();
+ b.bottom += p.gety();
+ b.top += p.gety();
+ return b;
}
pair Min() const {
@@ -233,8 +235,7 @@ inline bbox svgbbox(const bbox& B, pair shift=pair(0,0))
b.top += offset;
b.bottom += offset;
}
- b.shift(pair(1.99*settings::cm,1.9*settings::cm)+shift);
- return b;
+ return b.shift(pair(1.99*settings::cm,1.9*settings::cm)+shift);
}
} // namespace camp
diff --git a/graphics/asymptote/beziercurve.h b/graphics/asymptote/beziercurve.h
index 833da4db27..8e3576c458 100644
--- a/graphics/asymptote/beziercurve.h
+++ b/graphics/asymptote/beziercurve.h
@@ -49,7 +49,7 @@ struct BezierCurve
data.clear();
notRendered();
Onscreen=true;
- init(pixel*ratio);
+ init(pixelResolution*ratio);
render(g,straight);
}
diff --git a/graphics/asymptote/bezierpatch.cc b/graphics/asymptote/bezierpatch.cc
index 314ac94809..c2cc059c4b 100644
--- a/graphics/asymptote/bezierpatch.cc
+++ b/graphics/asymptote/bezierpatch.cc
@@ -13,260 +13,13 @@ namespace camp {
using ::orient2d;
using ::orient3d;
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
int MaterialIndex;
-
-//std::vector<GLuint>& I=transparentData.Indices;
-//std::vector<VertexData>& V=transparentData.Vertices;
bool colors;
-std::vector<GLfloat> zbuffer;
-std::vector<GLfloat> xbuffer;
-std::vector<GLfloat> ybuffer;
-
-//std::vector<GLfloat> xmin,ymin,zmin;
-//std::vector<GLfloat> xmax,ymax,zmax;
-std::vector<GLfloat> zsum;
-
-inline double min(double a, double b, double c)
-{
- return min(min(a,b),c);
-}
-
-inline double max(double a, double b, double c)
-{
- return max(max(a,b),c);
-}
-
-struct iz {
- unsigned i;
- double z;
- iz() {}
- void minimum(unsigned i, const std::vector<GLuint>& I) {
- this->i=i;
- unsigned i3=3*i;
- z=min(zbuffer[I[i3]],zbuffer[I[i3+1]],zbuffer[I[i3+2]]);
- }
-};
-
-std::vector<iz> IZ;
-
const double FillFactor=0.1;
-inline int sgn1(double x)
-{
- return x >= 0.0 ? 1 : -1;
-}
-
-inline int sgn(double x)
-{
- return (x > 0.0 ? 1 : (x < 0.0 ? -1 : 0));
-}
-
-bool sameside(const double *a, const double *b, int s0, const double *A,
- const double *B, const double *C)
-{
- if(sgn(orient2d(a,b,A)) == s0) return true;
- if(sgn(orient2d(a,b,B)) == s0) return true;
- if(sgn(orient2d(a,b,C)) == s0) return true;
- return false;
-}
-
-// returns true iff 2D triangles abc and ABC intersect
-bool intersect2D(const double *a, const double *b, const double *c,
- const double *A, const double *B, const double *C)
-{
- int s0=sgn(orient2d(a,b,c)); // Optimize away
- int S0=sgn(orient2d(A,B,C)); // Optimize away
- return
- sameside(a,b,s0,A,B,C) &&
- sameside(b,c,s0,A,B,C) &&
- sameside(c,a,s0,A,B,C) &&
- sameside(A,B,S0,a,b,c) &&
- sameside(B,C,S0,a,b,c) &&
- sameside(C,A,S0,a,b,c);
-}
-
-// returns true iff triangle abc is pierced by line segment AB.
-bool pierce(const double *a, const double *b, const double *c, const double *A, const double *B)
-{
- int sa=sgn(orient3d(A,b,c,B));
- int sb=sgn(orient3d(A,c,a,B));
- int sc=sgn(orient3d(A,a,b,B));
- return sa == sb && sb == sc;
-}
-
-// returns true iff triangle abc is pierced by an edge of triangle ABC
-bool intersect0(const double *a, const double *b, const double *c,
- const double *A, const double *B, const double *C,
- int sA, int sB, int sC)
-{
- if(sA != sB) {
- if(pierce(a,b,c,A,B)) return true;
- if(sC != sA) {
- if(pierce(a,b,c,C,A)) return true;
- } else {
- if(pierce(a,b,c,B,C)) return true;
- }
- } else {
- if(pierce(a,b,c,B,C)) return true;
- if(pierce(a,b,c,C,A)) return true;
- }
- return false;
-}
-
-// returns true iff triangle abc intersects triangle ABC
-bool intersect3D(const double *a, const double *b, const double *c,
- const double *A, const double *B, const double *C)
-{
- int sA=sgn(orient3d(a,b,c,A));
- int sB=sgn(orient3d(a,b,c,B));
- int sC=sgn(orient3d(a,b,c,C));
- if(sA == sB && sB == sC) return false;
-
- int sa=sgn(orient3d(A,B,C,a));
- int sb=sgn(orient3d(A,B,C,b));
- int sc=sgn(orient3d(A,B,C,c));
- if(sa == sb && sb == sc) return false;
-
- return intersect0(a,b,c,A,B,C,sA,sB,sC) || intersect0(A,B,C,a,b,c,sa,sb,sc);
-}
-
-// Return the intersection time of the extension of the line segment PQ
-// with the plane perpendicular to n and passing through Z.
-inline double intersect(const double *P, const double *Q, const double *n,
- const double *Z)
-{
- double d=n[0]*Z[0]+n[1]*Z[1]+n[2]*Z[2];
- double denom=n[0]*(Q[0]-P[0])+n[1]*(Q[1]-P[1])+n[2]*(Q[2]-P[2]);
- return denom == 0 ? DBL_MAX : (d-n[0]*P[0]-n[1]*P[1]-n[2]*P[2])/denom;
-}
-
-inline triple interp(const double *a, const double *b, double t)
-{
- return triple(a[0]+t*(b[0]-a[0]),a[1]+t*(b[1]-a[1]),a[2]+t*(b[2]-a[2]));
-}
-
-inline void interp(GLfloat *dest,
- const GLfloat *a, const GLfloat *b, double t)
-{
- double onemt=1.0-t;
- for(size_t i=0; i < 4; ++i)
- dest[i]=onemt*a[i]+t*b[i];
-}
-
-inline triple interp(const triple& a, const triple& b, double t)
-{
- return a+(b-a)*t;
-}
-
-unsigned n;
-unsigned int count;
-
-// Sort nonintersecting triangles by depth.
-int compare(const void *p, const void *P)
-{
- unsigned Ia=((GLuint *) p)[0];
- unsigned Ib=((GLuint *) p)[1];
- unsigned Ic=((GLuint *) p)[2];
-
- unsigned IA=((GLuint *) P)[0];
- unsigned IB=((GLuint *) P)[1];
- unsigned IC=((GLuint *) P)[2];
-
- return zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic] <
- zbuffer[IA]+zbuffer[IB]+zbuffer[IC] ? -1 : 1;
-
- /*
- double a[]={xbuffer[Ia],ybuffer[Ia],zbuffer[Ia]};
- double b[]={xbuffer[Ib],ybuffer[Ib],zbuffer[Ib]};
- double c[]={xbuffer[Ic],ybuffer[Ic],zbuffer[Ic]};
-
- double A[]={xbuffer[IA],ybuffer[IA],zbuffer[IA]};
- double B[]={xbuffer[IB],ybuffer[IB],zbuffer[IB]};
- double C[]={xbuffer[IC],ybuffer[IC],zbuffer[IC]};
-
- double viewpoint[]={0,0,100000};
-
- double sa=-orient3d(A,B,C,a);
- double sb=-orient3d(A,B,C,b);
- double sc=-orient3d(A,B,C,c);
- double s=min(sa,sb,sc);
- double S=max(sa,sb,sc);
- double eps=1000;
-
- if(s < -eps && S > eps) { //swap
- double sA=-orient3d(a,b,c,A);
- double sB=-orient3d(a,b,c,B);
- double sC=-orient3d(a,b,c,C);
- double s=min(sA,sB,sC);
- double S=max(sA,sB,sC);
- if(S < -s) S=s;
- int sz=sgn1(orient3d(a,b,c,viewpoint));
- if(S < -eps) return -sz;
- if(S > eps) return sz;
- }
- if(S < -s) S=s;
- int sz=sgn1(orient3d(A,B,C,viewpoint));
- if(S < -eps) return sz;
- if(S > eps) return -sz;
- return a[2]+b[2]+c[2] < A[2]+B[2]+C[2] ? -1 : 1;
- */
-}
-
-#if 0
-void split(unsigned i3, GLuint ia, GLuint ib, GLuint ic,
- double *a, double *b, double *c, double *N, double *A) {
- double td=intersect(a,b,N,A);
- double te=intersect(a,c,N,A);
-
- triple d=interp(a,b,td);
- triple e=interp(a,c,te);
-
- GLuint Ia=tstride*ia;
- GLuint Ib=tstride*ib;
- GLuint Ic=tstride*ic;
-
- triple na=triple(V[Ia+3],V[Ia+4],V[Ia+5]);
- triple nb=triple(V[Ib+3],V[Ib+4],V[Ib+5]);
- triple nc=triple(V[Ic+3],V[Ic+4],V[Ic+5]);
-
- triple nd=interp(na,nb,td);
- triple ne=interp(na,nc,te);
-
- GLuint id,ie;
-
- if(colors) {
- GLfloat *ca=&V[Ia+6];
- GLfloat *cb=&V[Ib+6];
- GLfloat *cc=&V[Ic+6];
-
- GLfloat cd[4],ce[4];
- interp(cd,ca,cb,td);
- interp(ce,ca,cc,te);
-
- id=data.Vertex(d,nd,cd);
- ie=data.Vertex(e,ne,ce);
- } else {
- id=data.Vertex(d,nd);
- ie=data.Vertex(e,ne);
- }
-
- I[i3]=ia;
- I[i3+1]=id;
- I[i3+2]=ie;
-
- I.push_back(id);
- I.push_back(ib);
- I.push_back(ie);
-
- I.push_back(ie);
- I.push_back(ib);
- I.push_back(ic);
-}
-#endif
-
void BezierPatch::init(double res)
{
res2=res*res;
@@ -979,11 +732,12 @@ void BezierTriangle::render(const triple *p,
}
}
+#ifndef HAVE_SSBO
+std::vector<GLfloat> zbuffer;
+
void transform(const std::vector<VertexData>& b)
{
unsigned n=b.size();
-// xbuffer.resize(n);
-// ybuffer.resize(n);
zbuffer.resize(n);
double Tz0=gl::dView[2];
@@ -995,65 +749,30 @@ void transform(const std::vector<VertexData>& b)
}
}
-#if 0
-// precompute min and max bounds of each triangle
-void bounds(const std::vector<GLuint>& I)
+// Sort nonintersecting triangles by depth.
+int compare(const void *p, const void *P)
{
- unsigned n=I.size()/3;
-/*
- xmin.resize(n);
- xmax.resize(n);
- ymin.resize(n);
- ymax.resize(n);
-*/
-
- zmin.resize(n);
- zmax.resize(n);
-
- for(unsigned i=0; i < n; ++i) {
- unsigned i3=3*i;
- unsigned Ia=I[i3];
- unsigned Ib=I[i3+1];
- unsigned Ic=I[i3+2];
-
-
- /*
- double xa=xbuffer[Ia];
- double xb=xbuffer[Ib];
- double xc=xbuffer[Ic];
-
- double ya=ybuffer[Ia];
- double yb=ybuffer[Ib];
- double yc=ybuffer[Ic];
- */
-
- double za=zbuffer[Ia];
- double zb=zbuffer[Ib];
- double zc=zbuffer[Ic];
-
- /*
- xmin[i]=min(xa,xb,xc);
- xmax[i]=max(xa,xb,xc);
+ unsigned Ia=((GLuint *) p)[0];
+ unsigned Ib=((GLuint *) p)[1];
+ unsigned Ic=((GLuint *) p)[2];
- ymin[i]=min(ya,yb,yc);
- ymax[i]=max(ya,yb,yc);
- */
+ unsigned IA=((GLuint *) P)[0];
+ unsigned IB=((GLuint *) P)[1];
+ unsigned IC=((GLuint *) P)[2];
- zmin[i]=min(za,zb,zc);
- zmax[i]=max(za,zb,zc);
- }
+ return zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic] <
+ zbuffer[IA]+zbuffer[IB]+zbuffer[IC] ? -1 : 1;
}
-#endif
void sortTriangles()
{
if(!transparentData.indices.empty()) {
transform(transparentData.Vertices);
-// bounds(tIndices);
qsort(&transparentData.indices[0],transparentData.indices.size()/3,
3*sizeof(GLuint),compare);
}
}
+#endif
void Triangles::queue(size_t nP, const triple* P, size_t nN, const triple* N,
size_t nC, const prc::RGBAColour* C, size_t nI,
diff --git a/graphics/asymptote/bezierpatch.h b/graphics/asymptote/bezierpatch.h
index b4159fe3ac..54ad4b8dab 100644
--- a/graphics/asymptote/bezierpatch.h
+++ b/graphics/asymptote/bezierpatch.h
@@ -12,12 +12,11 @@
namespace camp {
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
struct BezierPatch
{
vertexBuffer data;
-
bool transparent;
bool color;
double epsilon;
@@ -31,6 +30,12 @@ struct BezierPatch
void init(double res);
+ void init(double res, GLfloat *colors) {
+ transparent=false;
+ color=colors;
+ init(res);
+ }
+
triple normal(triple left3, triple left2, triple left1, triple middle,
triple right1, triple right2, triple right3) {
triple lp=3.0*(left1-middle);
@@ -159,7 +164,7 @@ struct BezierPatch
transparent=Transparent;
color=colors;
notRendered();
- init(pixel*ratio);
+ init(pixelResolution*ratio);
render(g,straight,colors);
}
diff --git a/graphics/asymptote/binaries/i386-windows/README b/graphics/asymptote/binaries/i386-windows/README
index 2c5895bd85..693b14efaa 100644
--- a/graphics/asymptote/binaries/i386-windows/README
+++ b/graphics/asymptote/binaries/i386-windows/README
@@ -49,7 +49,7 @@ noted below.
========================================================================
-Source code for the x86_64 and i386 3.0.4 cygwin1.dll libraries is
+Source code for the x86_64 and i386 3.3.3 cygwin1.dll libraries is
available under the GPL license:
https://cygwin.com/snapshots/
diff --git a/graphics/asymptote/binaries/i386-windows/cygwin1.dll b/graphics/asymptote/binaries/i386-windows/cygwin1.dll
index b609c0425e..1a4f38221e 100755
--- a/graphics/asymptote/binaries/i386-windows/cygwin1.dll
+++ b/graphics/asymptote/binaries/i386-windows/cygwin1.dll
Binary files differ
diff --git a/graphics/asymptote/binaries/x86_64-windows/README b/graphics/asymptote/binaries/x86_64-windows/README
index 2c5895bd85..693b14efaa 100644
--- a/graphics/asymptote/binaries/x86_64-windows/README
+++ b/graphics/asymptote/binaries/x86_64-windows/README
@@ -49,7 +49,7 @@ noted below.
========================================================================
-Source code for the x86_64 and i386 3.0.4 cygwin1.dll libraries is
+Source code for the x86_64 and i386 3.3.3 cygwin1.dll libraries is
available under the GPL license:
https://cygwin.com/snapshots/
diff --git a/graphics/asymptote/binaries/x86_64-windows/cygwin1.dll b/graphics/asymptote/binaries/x86_64-windows/cygwin1.dll
index 85e3847f02..350a74bad9 100644
--- a/graphics/asymptote/binaries/x86_64-windows/cygwin1.dll
+++ b/graphics/asymptote/binaries/x86_64-windows/cygwin1.dll
Binary files differ
diff --git a/graphics/asymptote/build-scripts/HOWTO-MSWindows b/graphics/asymptote/build-scripts/HOWTO-MSWindows
index 9a39e4b174..9b6972cbef 100644
--- a/graphics/asymptote/build-scripts/HOWTO-MSWindows
+++ b/graphics/asymptote/build-scripts/HOWTO-MSWindows
@@ -29,9 +29,10 @@ make install
tirpc-devel:
./configure --prefix=/usr --disable-gssapi
make install
+rm -rf /usr/include/rpc
ln -s /usr/include/tirpc/rpc /usr/include/rpc
-ln -s /usr/include/tirpc/netconfig.h /usr/include/netconfig.h
-ln -s /usr/lib/libtirpc.a /usr/lib/librpc.a
+ln -sf /usr/include/tirpc/netconfig.h /usr/include/netconfig.h
+ln -sf /usr/lib/libtirpc.a /usr/lib/librpc.a
termcap-1.3.1:
./configure --prefix=/usr
diff --git a/graphics/asymptote/build-scripts/build-asymptote b/graphics/asymptote/build-scripts/build-asymptote
index 9bbc66b36c..91c41d2bb5 100755
--- a/graphics/asymptote/build-scripts/build-asymptote
+++ b/graphics/asymptote/build-scripts/build-asymptote
@@ -3,8 +3,8 @@
HOME=~bowman
SHARED=$HOME/shared/asy
-GCVERSION=8.0.4
-ATOMICVERSION=7.6.10
+GCVERSION=8.2.0
+ATOMICVERSION=7.6.12
GC=gc-$GCVERSION
MAKEFLAGS=-j8
@@ -20,7 +20,7 @@ git clone http://github.com/vectorgraphics/asymptote
cd asymptote
git log > ChangeLog
VERSIONgit=`grep AC_INIT configure.ac | cut -s -d[ -f3 | cut -s -d] -f1`
-VERSION=${VERSIONgit/git/}
+VERSION=${VERSIONgit/git/}$1
cat configure.ac | sed -e "s/$VERSIONgit/$VERSION/" > configure.ac_
mv configure.ac_ configure.ac
cat $ASYMPTOTE/asymptote.spec | sed -e "s|Version:.*|Version: $VERSION|" > asymptote.spec
diff --git a/graphics/asymptote/build-scripts/build-asymptote.dos b/graphics/asymptote/build-scripts/build-asymptote.dos
index 5bb6777cc2..23edfcf835 100755
--- a/graphics/asymptote/build-scripts/build-asymptote.dos
+++ b/graphics/asymptote/build-scripts/build-asymptote.dos
@@ -23,7 +23,9 @@ cd ~/
rm -rf asymptote-$VERSION
mkdir -p CTAN
rm -rf CTAN/asymptote-$VERSION
-tar -zxf $SHARED/asymptote-$VERSION.src.tgz -C CTAN
+cd CTAN
+tar -vzxf $SHARED/asymptote-$VERSION.src.tgz | grep "/\." | xargs rm -rf
+cd ..
tar -zxf $SHARED/asymptote-$VERSION.src.tgz
mkdir -p CTAN/asymptote-$VERSION/binaries/$BINDIR/texlive
cd asymptote-$VERSION
@@ -31,7 +33,7 @@ fi
BUILD=build-$VERSION
ln -sf ../gc-$GC.tar.gz .
ln -sf ../gc-$GC .
-make -n MSDOS=1 >& /dev/null || ./configure OSTYPE=msdos --enable-gc=$GC --with-latex=/usr/local/share --with-context=/usr/local/share
+make -n MSDOS=1 >& /dev/null || ./configure OSTYPE=msdos --enable-gc=$GC --disable-lsp --with-latex=/usr/local/share --with-context=/usr/local/share
rm -rf $BUILD
mkdir -p $BUILD
cp -a $HOME/dll/cygwin/*.dll $BUILD
diff --git a/graphics/asymptote/camp.tab.cc b/graphics/asymptote/camp.tab.cc
index 2ced391e89..dbe17c9a03 100644
--- a/graphics/asymptote/camp.tab.cc
+++ b/graphics/asymptote/camp.tab.cc
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.5. */
+/* A Bison parser, made by GNU Bison 3.7.4. */
/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
+ Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -33,6 +34,10 @@
/* C LALR(1) parser skeleton written by Richard Stallman, by
simplifying the original so-called "semantic" parser. */
+/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+ especially those whose name start with YY_ or yy_. They are
+ private implementation details that can be changed or removed. */
+
/* All symbols defined below should begin with yy or YY, to avoid
infringing on user name space. This should be done even for local
variables, as they might otherwise be expanded by user macros.
@@ -40,11 +45,11 @@
define necessary library symbols; they are noted "INFRINGES ON
USER NAME SPACE" below. */
-/* Identify Bison output. */
-#define YYBISON 1
+/* Identify Bison output, and Bison version. */
+#define YYBISON 30704
-/* Bison version. */
-#define YYBISON_VERSION "3.0.5"
+/* Bison version string. */
+#define YYBISON_VERSION "3.7.4"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -61,8 +66,8 @@
-/* Copy the first part of user declarations. */
-#line 1 "camp.y" /* yacc.c:339 */
+/* First part of user prologue. */
+#line 1 "camp.y"
/*****
* camp.y
@@ -121,196 +126,239 @@ using namespace absyntax;
using sym::symbol;
using mem::string;
-#line 125 "camp.tab.c" /* yacc.c:339 */
+#line 130 "camp.tab.c"
+# ifndef YY_CAST
+# ifdef __cplusplus
+# define YY_CAST(Type, Val) static_cast<Type> (Val)
+# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)
+# else
+# define YY_CAST(Type, Val) ((Type) (Val))
+# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
+# endif
+# endif
# ifndef YY_NULLPTR
-# if defined __cplusplus && 201103L <= __cplusplus
-# define YY_NULLPTR nullptr
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
# else
-# define YY_NULLPTR 0
+# define YY_NULLPTR ((void*)0)
# endif
# endif
-/* Enabling verbose error messages. */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* In a future release of Bison, this section will be replaced
- by #include "camp.tab.h". */
-#ifndef YY_YY_CAMP_TAB_H_INCLUDED
-# define YY_YY_CAMP_TAB_H_INCLUDED
-/* Debug traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 1
-#endif
-#if YYDEBUG
-extern int yydebug;
-#endif
-
-/* Token type. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- enum yytokentype
- {
- ID = 258,
- SELFOP = 259,
- DOTS = 260,
- COLONS = 261,
- DASHES = 262,
- INCR = 263,
- LONGDASH = 264,
- CONTROLS = 265,
- TENSION = 266,
- ATLEAST = 267,
- CURL = 268,
- COR = 269,
- CAND = 270,
- BAR = 271,
- AMPERSAND = 272,
- EQ = 273,
- NEQ = 274,
- LT = 275,
- LE = 276,
- GT = 277,
- GE = 278,
- CARETS = 279,
- OPERATOR = 280,
- LOOSE = 281,
- ASSIGN = 282,
- DIRTAG = 283,
- JOIN_PREC = 284,
- AND = 285,
- ELLIPSIS = 286,
- ACCESS = 287,
- UNRAVEL = 288,
- IMPORT = 289,
- INCLUDE = 290,
- FROM = 291,
- QUOTE = 292,
- STRUCT = 293,
- TYPEDEF = 294,
- NEW = 295,
- IF = 296,
- ELSE = 297,
- WHILE = 298,
- DO = 299,
- FOR = 300,
- BREAK = 301,
- CONTINUE = 302,
- RETURN_ = 303,
- THIS = 304,
- EXPLICIT = 305,
- GARBAGE = 306,
- LIT = 307,
- STRING = 308,
- PERM = 309,
- MODIFIER = 310,
- UNARY = 311,
- EXP_IN_PARENS_RULE = 312
- };
-#endif
-
-/* Value type. */
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
-union YYSTYPE
+#include "camp.tab.h"
+/* Symbol kind. */
+enum yysymbol_kind_t
{
-#line 60 "camp.y" /* yacc.c:355 */
-
- position pos;
- bool boo;
- struct {
- position pos;
- sym::symbol sym;
- } ps;
- absyntax::name *n;
- absyntax::varinit *vi;
- absyntax::arrayinit *ai;
- absyntax::exp *e;
- absyntax::stringExp *stre;
- absyntax::specExp *se;
- absyntax::joinExp *j;
- absyntax::explist *elist;
- absyntax::argument arg;
- absyntax::arglist *alist;
- absyntax::slice *slice;
- absyntax::dimensions *dim;
- absyntax::ty *t;
- absyntax::decid *di;
- absyntax::decidlist *dil;
- absyntax::decidstart *dis;
- absyntax::runnable *run;
- struct {
- position pos;
- trans::permission val;
- } perm;
- struct {
- position pos;
- trans::modifier val;
- } mod;
- absyntax::modifierList *ml;
- //absyntax::program *prog;
- absyntax::vardec *vd;
- //absyntax::vardecs *vds;
- absyntax::dec *d;
- absyntax::idpair *ip;
- absyntax::idpairlist *ipl;
- absyntax::stm *s;
- absyntax::block *b;
- absyntax::stmExpList *sel;
- //absyntax::funheader *fh;
- absyntax::formal *fl;
- absyntax::formals *fls;
-
-#line 270 "camp.tab.c" /* yacc.c:355 */
+ YYSYMBOL_YYEMPTY = -2,
+ YYSYMBOL_YYEOF = 0, /* "end of file" */
+ YYSYMBOL_YYerror = 1, /* error */
+ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */
+ YYSYMBOL_ID = 3, /* ID */
+ YYSYMBOL_SELFOP = 4, /* SELFOP */
+ YYSYMBOL_DOTS = 5, /* DOTS */
+ YYSYMBOL_COLONS = 6, /* COLONS */
+ YYSYMBOL_DASHES = 7, /* DASHES */
+ YYSYMBOL_INCR = 8, /* INCR */
+ YYSYMBOL_LONGDASH = 9, /* LONGDASH */
+ YYSYMBOL_CONTROLS = 10, /* CONTROLS */
+ YYSYMBOL_TENSION = 11, /* TENSION */
+ YYSYMBOL_ATLEAST = 12, /* ATLEAST */
+ YYSYMBOL_CURL = 13, /* CURL */
+ YYSYMBOL_COR = 14, /* COR */
+ YYSYMBOL_CAND = 15, /* CAND */
+ YYSYMBOL_BAR = 16, /* BAR */
+ YYSYMBOL_AMPERSAND = 17, /* AMPERSAND */
+ YYSYMBOL_EQ = 18, /* EQ */
+ YYSYMBOL_NEQ = 19, /* NEQ */
+ YYSYMBOL_LT = 20, /* LT */
+ YYSYMBOL_LE = 21, /* LE */
+ YYSYMBOL_GT = 22, /* GT */
+ YYSYMBOL_GE = 23, /* GE */
+ YYSYMBOL_CARETS = 24, /* CARETS */
+ YYSYMBOL_25_ = 25, /* '+' */
+ YYSYMBOL_26_ = 26, /* '-' */
+ YYSYMBOL_27_ = 27, /* '*' */
+ YYSYMBOL_28_ = 28, /* '/' */
+ YYSYMBOL_29_ = 29, /* '%' */
+ YYSYMBOL_30_ = 30, /* '#' */
+ YYSYMBOL_31_ = 31, /* '^' */
+ YYSYMBOL_OPERATOR = 32, /* OPERATOR */
+ YYSYMBOL_LOOSE = 33, /* LOOSE */
+ YYSYMBOL_ASSIGN = 34, /* ASSIGN */
+ YYSYMBOL_35_ = 35, /* '?' */
+ YYSYMBOL_36_ = 36, /* ':' */
+ YYSYMBOL_DIRTAG = 37, /* DIRTAG */
+ YYSYMBOL_JOIN_PREC = 38, /* JOIN_PREC */
+ YYSYMBOL_AND = 39, /* AND */
+ YYSYMBOL_40_ = 40, /* '{' */
+ YYSYMBOL_41_ = 41, /* '}' */
+ YYSYMBOL_42_ = 42, /* '(' */
+ YYSYMBOL_43_ = 43, /* ')' */
+ YYSYMBOL_44_ = 44, /* '.' */
+ YYSYMBOL_45_ = 45, /* ',' */
+ YYSYMBOL_46_ = 46, /* '[' */
+ YYSYMBOL_47_ = 47, /* ']' */
+ YYSYMBOL_48_ = 48, /* ';' */
+ YYSYMBOL_ELLIPSIS = 49, /* ELLIPSIS */
+ YYSYMBOL_ACCESS = 50, /* ACCESS */
+ YYSYMBOL_UNRAVEL = 51, /* UNRAVEL */
+ YYSYMBOL_IMPORT = 52, /* IMPORT */
+ YYSYMBOL_INCLUDE = 53, /* INCLUDE */
+ YYSYMBOL_FROM = 54, /* FROM */
+ YYSYMBOL_QUOTE = 55, /* QUOTE */
+ YYSYMBOL_STRUCT = 56, /* STRUCT */
+ YYSYMBOL_TYPEDEF = 57, /* TYPEDEF */
+ YYSYMBOL_NEW = 58, /* NEW */
+ YYSYMBOL_IF = 59, /* IF */
+ YYSYMBOL_ELSE = 60, /* ELSE */
+ YYSYMBOL_WHILE = 61, /* WHILE */
+ YYSYMBOL_DO = 62, /* DO */
+ YYSYMBOL_FOR = 63, /* FOR */
+ YYSYMBOL_BREAK = 64, /* BREAK */
+ YYSYMBOL_CONTINUE = 65, /* CONTINUE */
+ YYSYMBOL_RETURN_ = 66, /* RETURN_ */
+ YYSYMBOL_THIS = 67, /* THIS */
+ YYSYMBOL_EXPLICIT = 68, /* EXPLICIT */
+ YYSYMBOL_GARBAGE = 69, /* GARBAGE */
+ YYSYMBOL_LIT = 70, /* LIT */
+ YYSYMBOL_STRING = 71, /* STRING */
+ YYSYMBOL_PERM = 72, /* PERM */
+ YYSYMBOL_MODIFIER = 73, /* MODIFIER */
+ YYSYMBOL_UNARY = 74, /* UNARY */
+ YYSYMBOL_EXP_IN_PARENS_RULE = 75, /* EXP_IN_PARENS_RULE */
+ YYSYMBOL_YYACCEPT = 76, /* $accept */
+ YYSYMBOL_file = 77, /* file */
+ YYSYMBOL_fileblock = 78, /* fileblock */
+ YYSYMBOL_bareblock = 79, /* bareblock */
+ YYSYMBOL_name = 80, /* name */
+ YYSYMBOL_runnable = 81, /* runnable */
+ YYSYMBOL_modifiers = 82, /* modifiers */
+ YYSYMBOL_dec = 83, /* dec */
+ YYSYMBOL_idpair = 84, /* idpair */
+ YYSYMBOL_idpairlist = 85, /* idpairlist */
+ YYSYMBOL_strid = 86, /* strid */
+ YYSYMBOL_stridpair = 87, /* stridpair */
+ YYSYMBOL_stridpairlist = 88, /* stridpairlist */
+ YYSYMBOL_vardec = 89, /* vardec */
+ YYSYMBOL_barevardec = 90, /* barevardec */
+ YYSYMBOL_type = 91, /* type */
+ YYSYMBOL_celltype = 92, /* celltype */
+ YYSYMBOL_dims = 93, /* dims */
+ YYSYMBOL_dimexps = 94, /* dimexps */
+ YYSYMBOL_decidlist = 95, /* decidlist */
+ YYSYMBOL_decid = 96, /* decid */
+ YYSYMBOL_decidstart = 97, /* decidstart */
+ YYSYMBOL_varinit = 98, /* varinit */
+ YYSYMBOL_block = 99, /* block */
+ YYSYMBOL_arrayinit = 100, /* arrayinit */
+ YYSYMBOL_basearrayinit = 101, /* basearrayinit */
+ YYSYMBOL_varinits = 102, /* varinits */
+ YYSYMBOL_formals = 103, /* formals */
+ YYSYMBOL_explicitornot = 104, /* explicitornot */
+ YYSYMBOL_formal = 105, /* formal */
+ YYSYMBOL_fundec = 106, /* fundec */
+ YYSYMBOL_typedec = 107, /* typedec */
+ YYSYMBOL_slice = 108, /* slice */
+ YYSYMBOL_value = 109, /* value */
+ YYSYMBOL_argument = 110, /* argument */
+ YYSYMBOL_arglist = 111, /* arglist */
+ YYSYMBOL_tuple = 112, /* tuple */
+ YYSYMBOL_exp = 113, /* exp */
+ YYSYMBOL_join = 114, /* join */
+ YYSYMBOL_dir = 115, /* dir */
+ YYSYMBOL_basicjoin = 116, /* basicjoin */
+ YYSYMBOL_tension = 117, /* tension */
+ YYSYMBOL_controls = 118, /* controls */
+ YYSYMBOL_stm = 119, /* stm */
+ YYSYMBOL_stmexp = 120, /* stmexp */
+ YYSYMBOL_blockstm = 121, /* blockstm */
+ YYSYMBOL_forinit = 122, /* forinit */
+ YYSYMBOL_fortest = 123, /* fortest */
+ YYSYMBOL_forupdate = 124, /* forupdate */
+ YYSYMBOL_stmexplist = 125 /* stmexplist */
};
+typedef enum yysymbol_kind_t yysymbol_kind_t;
-typedef union YYSTYPE YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define YYSTYPE_IS_DECLARED 1
-#endif
-extern YYSTYPE yylval;
-int yyparse (void);
+#ifdef short
+# undef short
+#endif
-#endif /* !YY_YY_CAMP_TAB_H_INCLUDED */
+/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
+ <limits.h> and (if available) <stdint.h> are included
+ so that the code can choose integer types of a good width. */
-/* Copy the second part of user declarations. */
+#ifndef __PTRDIFF_MAX__
+# include <limits.h> /* INFRINGES ON USER NAME SPACE */
+# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+# include <stdint.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_STDINT_H
+# endif
+#endif
-#line 287 "camp.tab.c" /* yacc.c:358 */
+/* Narrow types that promote to a signed type and that can represent a
+ signed or unsigned integer of at least N bits. In tables they can
+ save space and decrease cache pressure. Promoting to a signed type
+ helps avoid bugs in integer arithmetic. */
-#ifdef short
-# undef short
+#ifdef __INT_LEAST8_MAX__
+typedef __INT_LEAST8_TYPE__ yytype_int8;
+#elif defined YY_STDINT_H
+typedef int_least8_t yytype_int8;
+#else
+typedef signed char yytype_int8;
#endif
-#ifdef YYTYPE_UINT8
-typedef YYTYPE_UINT8 yytype_uint8;
+#ifdef __INT_LEAST16_MAX__
+typedef __INT_LEAST16_TYPE__ yytype_int16;
+#elif defined YY_STDINT_H
+typedef int_least16_t yytype_int16;
#else
-typedef unsigned char yytype_uint8;
+typedef short yytype_int16;
#endif
-#ifdef YYTYPE_INT8
-typedef YYTYPE_INT8 yytype_int8;
+#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST8_TYPE__ yytype_uint8;
+#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
+ && UINT_LEAST8_MAX <= INT_MAX)
+typedef uint_least8_t yytype_uint8;
+#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
+typedef unsigned char yytype_uint8;
#else
-typedef signed char yytype_int8;
+typedef short yytype_uint8;
#endif
-#ifdef YYTYPE_UINT16
-typedef YYTYPE_UINT16 yytype_uint16;
+#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST16_TYPE__ yytype_uint16;
+#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
+ && UINT_LEAST16_MAX <= INT_MAX)
+typedef uint_least16_t yytype_uint16;
+#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
+typedef unsigned short yytype_uint16;
#else
-typedef unsigned short int yytype_uint16;
+typedef int yytype_uint16;
#endif
-#ifdef YYTYPE_INT16
-typedef YYTYPE_INT16 yytype_int16;
-#else
-typedef short int yytype_int16;
+#ifndef YYPTRDIFF_T
+# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
+# define YYPTRDIFF_T __PTRDIFF_TYPE__
+# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
+# elif defined PTRDIFF_MAX
+# ifndef ptrdiff_t
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# endif
+# define YYPTRDIFF_T ptrdiff_t
+# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
+# else
+# define YYPTRDIFF_T long
+# define YYPTRDIFF_MAXIMUM LONG_MAX
+# endif
#endif
#ifndef YYSIZE_T
@@ -318,15 +366,28 @@ typedef short int yytype_int16;
# define YYSIZE_T __SIZE_TYPE__
# elif defined size_t
# define YYSIZE_T size_t
-# elif ! defined YYSIZE_T
+# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
# define YYSIZE_T size_t
# else
-# define YYSIZE_T unsigned int
+# define YYSIZE_T unsigned
# endif
#endif
-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+#define YYSIZE_MAXIMUM \
+ YY_CAST (YYPTRDIFF_T, \
+ (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \
+ ? YYPTRDIFF_MAXIMUM \
+ : YY_CAST (YYSIZE_T, -1)))
+
+#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
+
+
+/* Stored state numbers (used for stacks). */
+typedef yytype_int16 yy_state_t;
+
+/* State numbers in computations. */
+typedef int yy_state_fast_t;
#ifndef YY_
# if defined YYENABLE_NLS && YYENABLE_NLS
@@ -340,30 +401,20 @@ typedef short int yytype_int16;
# endif
#endif
-#ifndef YY_ATTRIBUTE
-# if (defined __GNUC__ \
- && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
- || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
-# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
-# else
-# define YY_ATTRIBUTE(Spec) /* empty */
-# endif
-#endif
#ifndef YY_ATTRIBUTE_PURE
-# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
+# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
+# else
+# define YY_ATTRIBUTE_PURE
+# endif
#endif
#ifndef YY_ATTRIBUTE_UNUSED
-# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
-#endif
-
-#if !defined _Noreturn \
- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-# define _Noreturn __declspec (noreturn)
+# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
# else
-# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
+# define YY_ATTRIBUTE_UNUSED
# endif
#endif
@@ -374,13 +425,13 @@ typedef short int yytype_int16;
# define YYUSE(E) /* empty */
#endif
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
- _Pragma ("GCC diagnostic push") \
- _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop")
#else
# define YY_INITIAL_VALUE(Value) Value
@@ -393,8 +444,22 @@ typedef short int yytype_int16;
# define YY_INITIAL_VALUE(Value) /* Nothing. */
#endif
+#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
+# define YY_IGNORE_USELESS_CAST_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
+# define YY_IGNORE_USELESS_CAST_END \
+ _Pragma ("GCC diagnostic pop")
+#endif
+#ifndef YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_END
+#endif
+
+
+#define YY_ASSERT(E) ((void) (0 && (E)))
-#if ! defined yyoverflow || YYERROR_VERBOSE
+#if !defined yyoverflow
/* The parser invokes alloca or malloc; define the necessary symbols. */
@@ -459,8 +524,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# endif
-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-
+#endif /* !defined yyoverflow */
#if (! defined yyoverflow \
&& (! defined __cplusplus \
@@ -469,17 +533,17 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
/* A type that is properly aligned for any stack member. */
union yyalloc
{
- yytype_int16 yyss_alloc;
+ yy_state_t yyss_alloc;
YYSTYPE yyvs_alloc;
};
/* The size of the maximum gap between one aligned stack and the next. */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
/* The size of an array large to enough to hold all stacks, each with
N elements. */
# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
# define YYCOPY_NEEDED 1
@@ -492,11 +556,11 @@ union yyalloc
# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
do \
{ \
- YYSIZE_T yynewbytes; \
+ YYPTRDIFF_T yynewbytes; \
YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
Stack = &yyptr->Stack_alloc; \
- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
- yyptr += yynewbytes / sizeof (*yyptr); \
+ yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / YYSIZEOF (*yyptr); \
} \
while (0)
@@ -508,12 +572,12 @@ union yyalloc
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(Dst, Src, Count) \
- __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+ __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))
# else
# define YYCOPY(Dst, Src, Count) \
do \
{ \
- YYSIZE_T yyi; \
+ YYPTRDIFF_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(Dst)[yyi] = (Src)[yyi]; \
} \
@@ -536,17 +600,20 @@ union yyalloc
/* YYNSTATES -- Number of states. */
#define YYNSTATES 376
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
- by yylex, with out-of-bounds checking. */
-#define YYUNDEFTOK 2
+/* YYMAXUTOK -- Last valid token kind. */
#define YYMAXUTOK 312
-#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, with out-of-bounds checking. */
+#define YYTRANSLATE(YYX) \
+ (0 <= (YYX) && (YYX) <= YYMAXUTOK \
+ ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \
+ : YYSYMBOL_YYUNDEF)
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
- as returned by yylex, without out-of-bounds checking. */
-static const yytype_uint8 yytranslate[] =
+ as returned by yylex. */
+static const yytype_int8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -584,7 +651,7 @@ static const yytype_uint8 yytranslate[] =
#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
-static const yytype_uint16 yyrline[] =
+static const yytype_int16 yyrline[] =
{
0, 191, 191, 195, 196, 201, 202, 207, 208, 209,
214, 215, 216, 218, 223, 224, 225, 227, 232, 233,
@@ -610,19 +677,26 @@ static const yytype_uint16 yyrline[] =
};
#endif
-#if YYDEBUG || YYERROR_VERBOSE || 0
+/** Accessing symbol of state STATE. */
+#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State])
+
+#if YYDEBUG || 0
+/* The user-facing name of the symbol whose (internal) number is
+ YYSYMBOL. No bounds checking. */
+static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
+
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
- "$end", "error", "$undefined", "ID", "SELFOP", "DOTS", "COLONS",
- "DASHES", "INCR", "LONGDASH", "CONTROLS", "TENSION", "ATLEAST", "CURL",
- "COR", "CAND", "BAR", "AMPERSAND", "EQ", "NEQ", "LT", "LE", "GT", "GE",
- "CARETS", "'+'", "'-'", "'*'", "'/'", "'%'", "'#'", "'^'", "OPERATOR",
- "LOOSE", "ASSIGN", "'?'", "':'", "DIRTAG", "JOIN_PREC", "AND", "'{'",
- "'}'", "'('", "')'", "'.'", "','", "'['", "']'", "';'", "ELLIPSIS",
- "ACCESS", "UNRAVEL", "IMPORT", "INCLUDE", "FROM", "QUOTE", "STRUCT",
- "TYPEDEF", "NEW", "IF", "ELSE", "WHILE", "DO", "FOR", "BREAK",
+ "\"end of file\"", "error", "\"invalid token\"", "ID", "SELFOP", "DOTS",
+ "COLONS", "DASHES", "INCR", "LONGDASH", "CONTROLS", "TENSION", "ATLEAST",
+ "CURL", "COR", "CAND", "BAR", "AMPERSAND", "EQ", "NEQ", "LT", "LE", "GT",
+ "GE", "CARETS", "'+'", "'-'", "'*'", "'/'", "'%'", "'#'", "'^'",
+ "OPERATOR", "LOOSE", "ASSIGN", "'?'", "':'", "DIRTAG", "JOIN_PREC",
+ "AND", "'{'", "'}'", "'('", "')'", "'.'", "','", "'['", "']'", "';'",
+ "ELLIPSIS", "ACCESS", "UNRAVEL", "IMPORT", "INCLUDE", "FROM", "QUOTE",
+ "STRUCT", "TYPEDEF", "NEW", "IF", "ELSE", "WHILE", "DO", "FOR", "BREAK",
"CONTINUE", "RETURN_", "THIS", "EXPLICIT", "GARBAGE", "LIT", "STRING",
"PERM", "MODIFIER", "UNARY", "EXP_IN_PARENS_RULE", "$accept", "file",
"fileblock", "bareblock", "name", "runnable", "modifiers", "dec",
@@ -634,12 +708,18 @@ static const char *const yytname[] =
"basicjoin", "tension", "controls", "stm", "stmexp", "blockstm",
"forinit", "fortest", "forupdate", "stmexplist", YY_NULLPTR
};
+
+static const char *
+yysymbol_name (yysymbol_kind_t yysymbol)
+{
+ return yytname[yysymbol];
+}
#endif
-# ifdef YYPRINT
+#ifdef YYPRINT
/* YYTOKNUM[NUM] -- (External) token number corresponding to the
(internal) symbol number NUM (which must be that of a token). */
-static const yytype_uint16 yytoknum[] =
+static const yytype_int16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
@@ -650,16 +730,16 @@ static const yytype_uint16 yytoknum[] =
297, 298, 299, 300, 301, 302, 303, 304, 305, 306,
307, 308, 309, 310, 311, 312
};
-# endif
+#endif
-#define YYPACT_NINF -285
+#define YYPACT_NINF (-285)
-#define yypact_value_is_default(Yystate) \
- (!!((Yystate) == (-285)))
+#define yypact_value_is_default(Yyn) \
+ ((Yyn) == YYPACT_NINF)
-#define YYTABLE_NINF -45
+#define YYTABLE_NINF (-45)
-#define yytable_value_is_error(Yytable_value) \
+#define yytable_value_is_error(Yyn) \
0
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
@@ -1180,7 +1260,7 @@ static const yytype_int16 yycheck[] =
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
-static const yytype_uint8 yystos[] =
+static const yytype_int8 yystos[] =
{
0, 77, 78, 0, 3, 7, 8, 25, 26, 29,
32, 40, 42, 48, 50, 51, 52, 53, 54, 55,
@@ -1223,7 +1303,7 @@ static const yytype_uint8 yystos[] =
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const yytype_uint8 yyr1[] =
+static const yytype_int8 yyr1[] =
{
0, 76, 77, 78, 78, 79, 79, 80, 80, 80,
81, 81, 81, 81, 82, 82, 82, 82, 83, 83,
@@ -1249,7 +1329,7 @@ static const yytype_uint8 yyr1[] =
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
-static const yytype_uint8 yyr2[] =
+static const yytype_int8 yyr2[] =
{
0, 2, 1, 0, 2, 0, 2, 1, 3, 1,
1, 1, 2, 2, 1, 1, 2, 2, 1, 1,
@@ -1275,10 +1355,10 @@ static const yytype_uint8 yyr2[] =
};
+enum { YYENOMEM = -2 };
+
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
-#define YYEMPTY (-2)
-#define YYEOF 0
#define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab
@@ -1287,27 +1367,26 @@ static const yytype_uint8 yyr2[] =
#define YYRECOVERING() (!!yyerrstatus)
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- YYPOPSTACK (yylen); \
- yystate = *yyssp; \
- goto yybackup; \
- } \
- else \
- { \
- yyerror (YY_("syntax error: cannot back up")); \
- YYERROR; \
- } \
-while (0)
-
-/* Error token number */
-#define YYTERROR 1
-#define YYERRCODE 256
-
+#define YYBACKUP(Token, Value) \
+ do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+ while (0)
+
+/* Backward compatibility with an undocumented macro.
+ Use YYerror or YYUNDEF. */
+#define YYERRCODE YYUNDEF
/* Enable debugging if requested. */
@@ -1325,54 +1404,58 @@ do { \
} while (0)
/* This macro is provided for backward compatibility. */
-#ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-#endif
+# ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
do { \
if (yydebug) \
{ \
YYFPRINTF (stderr, "%s ", Title); \
yy_symbol_print (stderr, \
- Type, Value); \
+ Kind, Value); \
YYFPRINTF (stderr, "\n"); \
} \
} while (0)
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT. |
-`----------------------------------------*/
+/*-----------------------------------.
+| Print this symbol's value on YYO. |
+`-----------------------------------*/
static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+yy_symbol_value_print (FILE *yyo,
+ yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
{
- FILE *yyo = yyoutput;
- YYUSE (yyo);
+ FILE *yyoutput = yyo;
+ YYUSE (yyoutput);
if (!yyvaluep)
return;
# ifdef YYPRINT
- if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+ if (yykind < YYNTOKENS)
+ YYPRINT (yyo, yytoknum[yykind], *yyvaluep);
# endif
- YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YYUSE (yykind);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
}
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
+/*---------------------------.
+| Print this symbol on YYO. |
+`---------------------------*/
static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+yy_symbol_print (FILE *yyo,
+ yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
{
- YYFPRINTF (yyoutput, "%s %s (",
- yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+ YYFPRINTF (yyo, "%s %s (",
+ yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));
- yy_symbol_value_print (yyoutput, yytype, yyvaluep);
- YYFPRINTF (yyoutput, ")");
+ yy_symbol_value_print (yyo, yykind, yyvaluep);
+ YYFPRINTF (yyo, ")");
}
/*------------------------------------------------------------------.
@@ -1381,7 +1464,7 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
`------------------------------------------------------------------*/
static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)
{
YYFPRINTF (stderr, "Stack now");
for (; yybottom <= yytop; yybottom++)
@@ -1404,21 +1487,21 @@ do { \
`------------------------------------------------*/
static void
-yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
+yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp,
+ int yyrule)
{
- unsigned long int yylno = yyrline[yyrule];
+ int yylno = yyrline[yyrule];
int yynrhs = yyr2[yyrule];
int yyi;
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
yyrule - 1, yylno);
/* The symbols being reduced. */
for (yyi = 0; yyi < yynrhs; yyi++)
{
YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr,
- yystos[yyssp[yyi + 1 - yynrhs]],
- &(yyvsp[(yyi + 1) - (yynrhs)])
- );
+ YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
+ &yyvsp[(yyi + 1) - (yynrhs)]);
YYFPRINTF (stderr, "\n");
}
}
@@ -1433,8 +1516,8 @@ do { \
multiple parsers can coexist. */
int yydebug;
#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YYDPRINTF(Args) ((void) 0)
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
# define YY_STACK_PRINT(Bottom, Top)
# define YY_REDUCE_PRINT(Rule)
#endif /* !YYDEBUG */
@@ -1457,250 +1540,30 @@ int yydebug;
#endif
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-# if defined __GLIBC__ && defined _STRING_H
-# define yystrlen strlen
-# else
-/* Return the length of YYSTR. */
-static YYSIZE_T
-yystrlen (const char *yystr)
-{
- YYSIZE_T yylen;
- for (yylen = 0; yystr[yylen]; yylen++)
- continue;
- return yylen;
-}
-# endif
-# endif
-
-# ifndef yystpcpy
-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-# define yystpcpy stpcpy
-# else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
- YYDEST. */
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-{
- char *yyd = yydest;
- const char *yys = yysrc;
-
- while ((*yyd++ = *yys++) != '\0')
- continue;
-
- return yyd - 1;
-}
-# endif
-# endif
-
-# ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
- quotes and backslashes, so that it's suitable for yyerror. The
- heuristic is that double-quoting is unnecessary unless the string
- contains an apostrophe, a comma, or backslash (other than
- backslash-backslash). YYSTR is taken from yytname. If YYRES is
- null, do not copy; instead, return the length of what the result
- would have been. */
-static YYSIZE_T
-yytnamerr (char *yyres, const char *yystr)
-{
- if (*yystr == '"')
- {
- YYSIZE_T yyn = 0;
- char const *yyp = yystr;
-
- for (;;)
- switch (*++yyp)
- {
- case '\'':
- case ',':
- goto do_not_strip_quotes;
-
- case '\\':
- if (*++yyp != '\\')
- goto do_not_strip_quotes;
- /* Fall through. */
- default:
- if (yyres)
- yyres[yyn] = *yyp;
- yyn++;
- break;
-
- case '"':
- if (yyres)
- yyres[yyn] = '\0';
- return yyn;
- }
- do_not_strip_quotes: ;
- }
-
- if (! yyres)
- return yystrlen (yystr);
- return yystpcpy (yyres, yystr) - yyres;
-}
-# endif
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
- about the unexpected token YYTOKEN for the state stack whose top is
- YYSSP.
-
- Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
- not large enough to hold the message. In that case, also set
- *YYMSG_ALLOC to the required number of bytes. Return 2 if the
- required number of bytes is too large to store. */
-static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
- yytype_int16 *yyssp, int yytoken)
-{
- YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
- YYSIZE_T yysize = yysize0;
- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
- /* Internationalized format string. */
- const char *yyformat = YY_NULLPTR;
- /* Arguments of yyformat. */
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- /* Number of reported tokens (one for the "unexpected", one per
- "expected"). */
- int yycount = 0;
-
- /* There are many possibilities here to consider:
- - If this state is a consistent state with a default action, then
- the only way this function was invoked is if the default action
- is an error action. In that case, don't check for expected
- tokens because there are none.
- - The only way there can be no lookahead present (in yychar) is if
- this state is a consistent state with a default action. Thus,
- detecting the absence of a lookahead is sufficient to determine
- that there is no unexpected or expected token to report. In that
- case, just report a simple "syntax error".
- - Don't assume there isn't a lookahead just because this state is a
- consistent state with a default action. There might have been a
- previous inconsistent state, consistent state with a non-default
- action, or user semantic action that manipulated yychar.
- - Of course, the expected token list depends on states to have
- correct lookahead information, and it depends on the parser not
- to perform extra reductions after fetching a lookahead from the
- scanner and before detecting a syntax error. Thus, state merging
- (from LALR or IELR) and default reductions corrupt the expected
- token list. However, the list is correct for canonical LR with
- one exception: it will still contain any token that will not be
- accepted due to an error action in a later state.
- */
- if (yytoken != YYEMPTY)
- {
- int yyn = yypact[*yyssp];
- yyarg[yycount++] = yytname[yytoken];
- if (!yypact_value_is_default (yyn))
- {
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. In other words, skip the first -YYN actions for
- this state because they are default actions. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yyx;
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
- && !yytable_value_is_error (yytable[yyx + yyn]))
- {
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- {
- YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
- if (! (yysize <= yysize1
- && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
- }
- }
- }
- }
-
- switch (yycount)
- {
-# define YYCASE_(N, S) \
- case N: \
- yyformat = S; \
- break
- default: /* Avoid compiler warnings. */
- YYCASE_(0, YY_("syntax error"));
- YYCASE_(1, YY_("syntax error, unexpected %s"));
- YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
- YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
- YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
- YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
- }
- {
- YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
- return 2;
- yysize = yysize1;
- }
-
- if (*yymsg_alloc < yysize)
- {
- *yymsg_alloc = 2 * yysize;
- if (! (yysize <= *yymsg_alloc
- && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
- *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
- return 1;
- }
-
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- {
- char *yyp = *yymsg;
- int yyi = 0;
- while ((*yyp = *yyformat) != '\0')
- if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyformat += 2;
- }
- else
- {
- yyp++;
- yyformat++;
- }
- }
- return 0;
-}
-#endif /* YYERROR_VERBOSE */
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
`-----------------------------------------------*/
static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+yydestruct (const char *yymsg,
+ yysymbol_kind_t yykind, YYSTYPE *yyvaluep)
{
YYUSE (yyvaluep);
if (!yymsg)
yymsg = "Deleting";
- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+ YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
- YYUSE (yytype);
+ YYUSE (yykind);
YY_IGNORE_MAYBE_UNINITIALIZED_END
}
-
-
-/* The lookahead symbol. */
+/* Lookahead token kind. */
int yychar;
/* The semantic value of the lookahead symbol. */
@@ -1709,6 +1572,8 @@ YYSTYPE yylval;
int yynerrs;
+
+
/*----------.
| yyparse. |
`----------*/
@@ -1716,43 +1581,36 @@ int yynerrs;
int
yyparse (void)
{
- int yystate;
+ yy_state_fast_t yystate = 0;
/* Number of tokens to shift before error messages enabled. */
- int yyerrstatus;
+ int yyerrstatus = 0;
- /* The stacks and their tools:
- 'yyss': related to states.
- 'yyvs': related to semantic values.
-
- Refer to the stacks through separate pointers, to allow yyoverflow
+ /* Refer to the stacks through separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
- /* The state stack. */
- yytype_int16 yyssa[YYINITDEPTH];
- yytype_int16 *yyss;
- yytype_int16 *yyssp;
+ /* Their size. */
+ YYPTRDIFF_T yystacksize = YYINITDEPTH;
- /* The semantic value stack. */
- YYSTYPE yyvsa[YYINITDEPTH];
- YYSTYPE *yyvs;
- YYSTYPE *yyvsp;
+ /* The state stack: array, bottom, top. */
+ yy_state_t yyssa[YYINITDEPTH];
+ yy_state_t *yyss = yyssa;
+ yy_state_t *yyssp = yyss;
- YYSIZE_T yystacksize;
+ /* The semantic value stack: array, bottom, top. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp = yyvs;
int yyn;
+ /* The return value of yyparse. */
int yyresult;
- /* Lookahead token as an internal (translated) token number. */
- int yytoken = 0;
+ /* Lookahead symbol kind. */
+ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
-#if YYERROR_VERBOSE
- /* Buffer for error messages, and its allocated size. */
- char yymsgbuf[128];
- char *yymsg = yymsgbuf;
- YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
+
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
@@ -1760,58 +1618,60 @@ yyparse (void)
Keep to zero when no symbol should be popped. */
int yylen = 0;
- yyssp = yyss = yyssa;
- yyvsp = yyvs = yyvsa;
- yystacksize = YYINITDEPTH;
-
YYDPRINTF ((stderr, "Starting parse\n"));
- yystate = 0;
- yyerrstatus = 0;
- yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
goto yysetstate;
+
/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate. |
+| yynewstate -- push a new state, which is found in yystate. |
`------------------------------------------------------------*/
- yynewstate:
+yynewstate:
/* In all cases, when you get here, the value and location stacks
have just been pushed. So pushing a state here evens the stacks. */
yyssp++;
- yysetstate:
- *yyssp = yystate;
+
+/*--------------------------------------------------------------------.
+| yysetstate -- set current state (the top of the stack) to yystate. |
+`--------------------------------------------------------------------*/
+yysetstate:
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
+ YY_IGNORE_USELESS_CAST_BEGIN
+ *yyssp = YY_CAST (yy_state_t, yystate);
+ YY_IGNORE_USELESS_CAST_END
+ YY_STACK_PRINT (yyss, yyssp);
if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+#else
{
/* Get the current used size of the three stacks, in elements. */
- YYSIZE_T yysize = yyssp - yyss + 1;
+ YYPTRDIFF_T yysize = yyssp - yyss + 1;
-#ifdef yyoverflow
+# if defined yyoverflow
{
/* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
memory. */
+ yy_state_t *yyss1 = yyss;
YYSTYPE *yyvs1 = yyvs;
- yytype_int16 *yyss1 = yyss;
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. This used to be a
conditional around just the two extra args, but that might
be undefined if yyoverflow is a macro. */
yyoverflow (YY_("memory exhausted"),
- &yyss1, yysize * sizeof (*yyssp),
- &yyvs1, yysize * sizeof (*yyvsp),
+ &yyss1, yysize * YYSIZEOF (*yyssp),
+ &yyvs1, yysize * YYSIZEOF (*yyvsp),
&yystacksize);
-
yyss = yyss1;
yyvs = yyvs1;
}
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
- goto yyexhaustedlab;
-# else
+# else /* defined YYSTACK_RELOCATE */
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
goto yyexhaustedlab;
@@ -1820,9 +1680,10 @@ yyparse (void)
yystacksize = YYMAXDEPTH;
{
- yytype_int16 *yyss1 = yyss;
+ yy_state_t *yyss1 = yyss;
union yyalloc *yyptr =
- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ YY_CAST (union yyalloc *,
+ YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
if (! yyptr)
goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss_alloc, yyss);
@@ -1832,30 +1693,30 @@ yyparse (void)
YYSTACK_FREE (yyss1);
}
# endif
-#endif /* no yyoverflow */
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
- YYDPRINTF ((stderr, "Stack size increased to %lu\n",
- (unsigned long int) yystacksize));
+ YY_IGNORE_USELESS_CAST_BEGIN
+ YYDPRINTF ((stderr, "Stack size increased to %ld\n",
+ YY_CAST (long, yystacksize)));
+ YY_IGNORE_USELESS_CAST_END
if (yyss + yystacksize - 1 <= yyssp)
YYABORT;
}
-
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
if (yystate == YYFINAL)
YYACCEPT;
goto yybackup;
+
/*-----------.
| yybackup. |
`-----------*/
yybackup:
-
/* Do appropriate processing given the current state. Read a
lookahead token if we need one and don't already have one. */
@@ -1866,18 +1727,29 @@ yybackup:
/* Not known => get a lookahead token if don't already have one. */
- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */
if (yychar == YYEMPTY)
{
- YYDPRINTF ((stderr, "Reading a token: "));
+ YYDPRINTF ((stderr, "Reading a token\n"));
yychar = yylex ();
}
if (yychar <= YYEOF)
{
- yychar = yytoken = YYEOF;
+ yychar = YYEOF;
+ yytoken = YYSYMBOL_YYEOF;
YYDPRINTF ((stderr, "Now at end of input.\n"));
}
+ else if (yychar == YYerror)
+ {
+ /* The scanner already issued an error message, process directly
+ to error recovery. But do not keep the error token as
+ lookahead, it is too special and may lead us to an endless
+ loop in error recovery. */
+ yychar = YYUNDEF;
+ yytoken = YYSYMBOL_YYerror;
+ goto yyerrlab1;
+ }
else
{
yytoken = YYTRANSLATE (yychar);
@@ -1905,15 +1777,13 @@ yybackup:
/* Shift the lookahead token. */
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-
- /* Discard the shifted token. */
- yychar = YYEMPTY;
-
yystate = yyn;
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
goto yynewstate;
@@ -1928,7 +1798,7 @@ yydefault:
/*-----------------------------.
-| yyreduce -- Do a reduction. |
+| yyreduce -- do a reduction. |
`-----------------------------*/
yyreduce:
/* yyn is the number of a rule to reduce with. */
@@ -1948,1233 +1818,1234 @@ yyreduce:
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
- case 2:
-#line 191 "camp.y" /* yacc.c:1648 */
- { absyntax::root = (yyvsp[0].b); }
-#line 1955 "camp.tab.c" /* yacc.c:1648 */
+ case 2: /* file: fileblock */
+#line 191 "camp.y"
+ { absyntax::root = (yyvsp[0].b); }
+#line 1825 "camp.tab.c"
break;
- case 3:
-#line 195 "camp.y" /* yacc.c:1648 */
- { (yyval.b) = new file(lexerPos(), false); }
-#line 1961 "camp.tab.c" /* yacc.c:1648 */
+ case 3: /* fileblock: %empty */
+#line 195 "camp.y"
+ { (yyval.b) = new file(lexerPos(), false); }
+#line 1831 "camp.tab.c"
break;
- case 4:
-#line 197 "camp.y" /* yacc.c:1648 */
- { (yyval.b) = (yyvsp[-1].b); (yyval.b)->add((yyvsp[0].run)); }
-#line 1967 "camp.tab.c" /* yacc.c:1648 */
+ case 4: /* fileblock: fileblock runnable */
+#line 197 "camp.y"
+ { (yyval.b) = (yyvsp[-1].b); (yyval.b)->add((yyvsp[0].run)); }
+#line 1837 "camp.tab.c"
break;
- case 5:
-#line 201 "camp.y" /* yacc.c:1648 */
- { (yyval.b) = new block(lexerPos(), true); }
-#line 1973 "camp.tab.c" /* yacc.c:1648 */
+ case 5: /* bareblock: %empty */
+#line 201 "camp.y"
+ { (yyval.b) = new block(lexerPos(), true); }
+#line 1843 "camp.tab.c"
break;
- case 6:
-#line 203 "camp.y" /* yacc.c:1648 */
- { (yyval.b) = (yyvsp[-1].b); (yyval.b)->add((yyvsp[0].run)); }
-#line 1979 "camp.tab.c" /* yacc.c:1648 */
+ case 6: /* bareblock: bareblock runnable */
+#line 203 "camp.y"
+ { (yyval.b) = (yyvsp[-1].b); (yyval.b)->add((yyvsp[0].run)); }
+#line 1849 "camp.tab.c"
break;
- case 7:
-#line 207 "camp.y" /* yacc.c:1648 */
- { (yyval.n) = new simpleName((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
-#line 1985 "camp.tab.c" /* yacc.c:1648 */
+ case 7: /* name: ID */
+#line 207 "camp.y"
+ { (yyval.n) = new simpleName((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
+#line 1855 "camp.tab.c"
break;
- case 8:
-#line 208 "camp.y" /* yacc.c:1648 */
- { (yyval.n) = new qualifiedName((yyvsp[-1].pos), (yyvsp[-2].n), (yyvsp[0].ps).sym); }
-#line 1991 "camp.tab.c" /* yacc.c:1648 */
+ case 8: /* name: name '.' ID */
+#line 208 "camp.y"
+ { (yyval.n) = new qualifiedName((yyvsp[-1].pos), (yyvsp[-2].n), (yyvsp[0].ps).sym); }
+#line 1861 "camp.tab.c"
break;
- case 9:
-#line 209 "camp.y" /* yacc.c:1648 */
- { (yyval.n) = new simpleName((yyvsp[0].ps).pos,
+ case 9: /* name: '%' */
+#line 209 "camp.y"
+ { (yyval.n) = new simpleName((yyvsp[0].ps).pos,
symbol::trans("operator answer")); }
-#line 1998 "camp.tab.c" /* yacc.c:1648 */
+#line 1868 "camp.tab.c"
break;
- case 10:
-#line 214 "camp.y" /* yacc.c:1648 */
- { (yyval.run) = (yyvsp[0].d); }
-#line 2004 "camp.tab.c" /* yacc.c:1648 */
+ case 10: /* runnable: dec */
+#line 214 "camp.y"
+ { (yyval.run) = (yyvsp[0].d); }
+#line 1874 "camp.tab.c"
break;
- case 11:
-#line 215 "camp.y" /* yacc.c:1648 */
- { (yyval.run) = (yyvsp[0].s); }
-#line 2010 "camp.tab.c" /* yacc.c:1648 */
+ case 11: /* runnable: stm */
+#line 215 "camp.y"
+ { (yyval.run) = (yyvsp[0].s); }
+#line 1880 "camp.tab.c"
break;
- case 12:
-#line 217 "camp.y" /* yacc.c:1648 */
- { (yyval.run) = new modifiedRunnable((yyvsp[-1].ml)->getPos(), (yyvsp[-1].ml), (yyvsp[0].d)); }
-#line 2016 "camp.tab.c" /* yacc.c:1648 */
+ case 12: /* runnable: modifiers dec */
+#line 217 "camp.y"
+ { (yyval.run) = new modifiedRunnable((yyvsp[-1].ml)->getPos(), (yyvsp[-1].ml), (yyvsp[0].d)); }
+#line 1886 "camp.tab.c"
break;
- case 13:
-#line 219 "camp.y" /* yacc.c:1648 */
- { (yyval.run) = new modifiedRunnable((yyvsp[-1].ml)->getPos(), (yyvsp[-1].ml), (yyvsp[0].s)); }
-#line 2022 "camp.tab.c" /* yacc.c:1648 */
+ case 13: /* runnable: modifiers stm */
+#line 219 "camp.y"
+ { (yyval.run) = new modifiedRunnable((yyvsp[-1].ml)->getPos(), (yyvsp[-1].ml), (yyvsp[0].s)); }
+#line 1892 "camp.tab.c"
break;
- case 14:
-#line 223 "camp.y" /* yacc.c:1648 */
- { (yyval.ml) = new modifierList((yyvsp[0].mod).pos); (yyval.ml)->add((yyvsp[0].mod).val); }
-#line 2028 "camp.tab.c" /* yacc.c:1648 */
+ case 14: /* modifiers: MODIFIER */
+#line 223 "camp.y"
+ { (yyval.ml) = new modifierList((yyvsp[0].mod).pos); (yyval.ml)->add((yyvsp[0].mod).val); }
+#line 1898 "camp.tab.c"
break;
- case 15:
-#line 224 "camp.y" /* yacc.c:1648 */
- { (yyval.ml) = new modifierList((yyvsp[0].perm).pos); (yyval.ml)->add((yyvsp[0].perm).val); }
-#line 2034 "camp.tab.c" /* yacc.c:1648 */
+ case 15: /* modifiers: PERM */
+#line 224 "camp.y"
+ { (yyval.ml) = new modifierList((yyvsp[0].perm).pos); (yyval.ml)->add((yyvsp[0].perm).val); }
+#line 1904 "camp.tab.c"
break;
- case 16:
-#line 226 "camp.y" /* yacc.c:1648 */
- { (yyval.ml) = (yyvsp[-1].ml); (yyval.ml)->add((yyvsp[0].mod).val); }
-#line 2040 "camp.tab.c" /* yacc.c:1648 */
+ case 16: /* modifiers: modifiers MODIFIER */
+#line 226 "camp.y"
+ { (yyval.ml) = (yyvsp[-1].ml); (yyval.ml)->add((yyvsp[0].mod).val); }
+#line 1910 "camp.tab.c"
break;
- case 17:
-#line 228 "camp.y" /* yacc.c:1648 */
- { (yyval.ml) = (yyvsp[-1].ml); (yyval.ml)->add((yyvsp[0].perm).val); }
-#line 2046 "camp.tab.c" /* yacc.c:1648 */
+ case 17: /* modifiers: modifiers PERM */
+#line 228 "camp.y"
+ { (yyval.ml) = (yyvsp[-1].ml); (yyval.ml)->add((yyvsp[0].perm).val); }
+#line 1916 "camp.tab.c"
break;
- case 18:
-#line 232 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = (yyvsp[0].vd); }
-#line 2052 "camp.tab.c" /* yacc.c:1648 */
+ case 18: /* dec: vardec */
+#line 232 "camp.y"
+ { (yyval.d) = (yyvsp[0].vd); }
+#line 1922 "camp.tab.c"
break;
- case 19:
-#line 233 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = (yyvsp[0].d); }
-#line 2058 "camp.tab.c" /* yacc.c:1648 */
+ case 19: /* dec: fundec */
+#line 233 "camp.y"
+ { (yyval.d) = (yyvsp[0].d); }
+#line 1928 "camp.tab.c"
break;
- case 20:
-#line 234 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = (yyvsp[0].d); }
-#line 2064 "camp.tab.c" /* yacc.c:1648 */
+ case 20: /* dec: typedec */
+#line 234 "camp.y"
+ { (yyval.d) = (yyvsp[0].d); }
+#line 1934 "camp.tab.c"
break;
- case 21:
-#line 236 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = new accessdec((yyvsp[-2].pos), (yyvsp[-1].ipl)); }
-#line 2070 "camp.tab.c" /* yacc.c:1648 */
+ case 21: /* dec: ACCESS stridpairlist ';' */
+#line 236 "camp.y"
+ { (yyval.d) = new accessdec((yyvsp[-2].pos), (yyvsp[-1].ipl)); }
+#line 1940 "camp.tab.c"
break;
- case 22:
-#line 238 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = new unraveldec((yyvsp[-4].pos), (yyvsp[-3].n), (yyvsp[-1].ipl)); }
-#line 2076 "camp.tab.c" /* yacc.c:1648 */
+ case 22: /* dec: FROM name UNRAVEL idpairlist ';' */
+#line 238 "camp.y"
+ { (yyval.d) = new unraveldec((yyvsp[-4].pos), (yyvsp[-3].n), (yyvsp[-1].ipl)); }
+#line 1946 "camp.tab.c"
break;
- case 23:
-#line 240 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = new unraveldec((yyvsp[-4].pos), (yyvsp[-3].n), WILDCARD); }
-#line 2082 "camp.tab.c" /* yacc.c:1648 */
+ case 23: /* dec: FROM name UNRAVEL '*' ';' */
+#line 240 "camp.y"
+ { (yyval.d) = new unraveldec((yyvsp[-4].pos), (yyvsp[-3].n), WILDCARD); }
+#line 1952 "camp.tab.c"
break;
- case 24:
-#line 241 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = new unraveldec((yyvsp[-2].pos), (yyvsp[-1].n), WILDCARD); }
-#line 2088 "camp.tab.c" /* yacc.c:1648 */
+ case 24: /* dec: UNRAVEL name ';' */
+#line 241 "camp.y"
+ { (yyval.d) = new unraveldec((yyvsp[-2].pos), (yyvsp[-1].n), WILDCARD); }
+#line 1958 "camp.tab.c"
break;
- case 25:
-#line 243 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = new fromaccessdec((yyvsp[-4].pos), (yyvsp[-3].ps).sym, (yyvsp[-1].ipl)); }
-#line 2094 "camp.tab.c" /* yacc.c:1648 */
+ case 25: /* dec: FROM strid ACCESS idpairlist ';' */
+#line 243 "camp.y"
+ { (yyval.d) = new fromaccessdec((yyvsp[-4].pos), (yyvsp[-3].ps).sym, (yyvsp[-1].ipl)); }
+#line 1964 "camp.tab.c"
break;
- case 26:
-#line 245 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = new fromaccessdec((yyvsp[-4].pos), (yyvsp[-3].ps).sym, WILDCARD); }
-#line 2100 "camp.tab.c" /* yacc.c:1648 */
+ case 26: /* dec: FROM strid ACCESS '*' ';' */
+#line 245 "camp.y"
+ { (yyval.d) = new fromaccessdec((yyvsp[-4].pos), (yyvsp[-3].ps).sym, WILDCARD); }
+#line 1970 "camp.tab.c"
break;
- case 27:
-#line 247 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = new importdec((yyvsp[-2].pos), (yyvsp[-1].ip)); }
-#line 2106 "camp.tab.c" /* yacc.c:1648 */
+ case 27: /* dec: IMPORT stridpair ';' */
+#line 247 "camp.y"
+ { (yyval.d) = new importdec((yyvsp[-2].pos), (yyvsp[-1].ip)); }
+#line 1976 "camp.tab.c"
break;
- case 28:
-#line 248 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = new includedec((yyvsp[-2].pos), (yyvsp[-1].ps).sym); }
-#line 2112 "camp.tab.c" /* yacc.c:1648 */
+ case 28: /* dec: INCLUDE ID ';' */
+#line 248 "camp.y"
+ { (yyval.d) = new includedec((yyvsp[-2].pos), (yyvsp[-1].ps).sym); }
+#line 1982 "camp.tab.c"
break;
- case 29:
-#line 250 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = new includedec((yyvsp[-2].pos), (yyvsp[-1].stre)->getString()); }
-#line 2118 "camp.tab.c" /* yacc.c:1648 */
+ case 29: /* dec: INCLUDE STRING ';' */
+#line 250 "camp.y"
+ { (yyval.d) = new includedec((yyvsp[-2].pos), (yyvsp[-1].stre)->getString()); }
+#line 1988 "camp.tab.c"
break;
- case 30:
-#line 254 "camp.y" /* yacc.c:1648 */
- { (yyval.ip) = new idpair((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
-#line 2124 "camp.tab.c" /* yacc.c:1648 */
+ case 30: /* idpair: ID */
+#line 254 "camp.y"
+ { (yyval.ip) = new idpair((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
+#line 1994 "camp.tab.c"
break;
- case 31:
-#line 256 "camp.y" /* yacc.c:1648 */
- { (yyval.ip) = new idpair((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym, (yyvsp[-1].ps).sym , (yyvsp[0].ps).sym); }
-#line 2130 "camp.tab.c" /* yacc.c:1648 */
+ case 31: /* idpair: ID ID ID */
+#line 256 "camp.y"
+ { (yyval.ip) = new idpair((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym, (yyvsp[-1].ps).sym , (yyvsp[0].ps).sym); }
+#line 2000 "camp.tab.c"
break;
- case 32:
-#line 260 "camp.y" /* yacc.c:1648 */
- { (yyval.ipl) = new idpairlist(); (yyval.ipl)->add((yyvsp[0].ip)); }
-#line 2136 "camp.tab.c" /* yacc.c:1648 */
+ case 32: /* idpairlist: idpair */
+#line 260 "camp.y"
+ { (yyval.ipl) = new idpairlist(); (yyval.ipl)->add((yyvsp[0].ip)); }
+#line 2006 "camp.tab.c"
break;
- case 33:
-#line 262 "camp.y" /* yacc.c:1648 */
- { (yyval.ipl) = (yyvsp[-2].ipl); (yyval.ipl)->add((yyvsp[0].ip)); }
-#line 2142 "camp.tab.c" /* yacc.c:1648 */
+ case 33: /* idpairlist: idpairlist ',' idpair */
+#line 262 "camp.y"
+ { (yyval.ipl) = (yyvsp[-2].ipl); (yyval.ipl)->add((yyvsp[0].ip)); }
+#line 2012 "camp.tab.c"
break;
- case 34:
-#line 266 "camp.y" /* yacc.c:1648 */
- { (yyval.ps) = (yyvsp[0].ps); }
-#line 2148 "camp.tab.c" /* yacc.c:1648 */
+ case 34: /* strid: ID */
+#line 266 "camp.y"
+ { (yyval.ps) = (yyvsp[0].ps); }
+#line 2018 "camp.tab.c"
break;
- case 35:
-#line 267 "camp.y" /* yacc.c:1648 */
- { (yyval.ps).pos = (yyvsp[0].stre)->getPos();
+ case 35: /* strid: STRING */
+#line 267 "camp.y"
+ { (yyval.ps).pos = (yyvsp[0].stre)->getPos();
(yyval.ps).sym = symbol::literalTrans((yyvsp[0].stre)->getString()); }
-#line 2155 "camp.tab.c" /* yacc.c:1648 */
+#line 2025 "camp.tab.c"
break;
- case 36:
-#line 272 "camp.y" /* yacc.c:1648 */
- { (yyval.ip) = new idpair((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
-#line 2161 "camp.tab.c" /* yacc.c:1648 */
+ case 36: /* stridpair: ID */
+#line 272 "camp.y"
+ { (yyval.ip) = new idpair((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
+#line 2031 "camp.tab.c"
break;
- case 37:
-#line 274 "camp.y" /* yacc.c:1648 */
- { (yyval.ip) = new idpair((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym, (yyvsp[-1].ps).sym , (yyvsp[0].ps).sym); }
-#line 2167 "camp.tab.c" /* yacc.c:1648 */
+ case 37: /* stridpair: strid ID ID */
+#line 274 "camp.y"
+ { (yyval.ip) = new idpair((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym, (yyvsp[-1].ps).sym , (yyvsp[0].ps).sym); }
+#line 2037 "camp.tab.c"
break;
- case 38:
-#line 278 "camp.y" /* yacc.c:1648 */
- { (yyval.ipl) = new idpairlist(); (yyval.ipl)->add((yyvsp[0].ip)); }
-#line 2173 "camp.tab.c" /* yacc.c:1648 */
+ case 38: /* stridpairlist: stridpair */
+#line 278 "camp.y"
+ { (yyval.ipl) = new idpairlist(); (yyval.ipl)->add((yyvsp[0].ip)); }
+#line 2043 "camp.tab.c"
break;
- case 39:
-#line 280 "camp.y" /* yacc.c:1648 */
- { (yyval.ipl) = (yyvsp[-2].ipl); (yyval.ipl)->add((yyvsp[0].ip)); }
-#line 2179 "camp.tab.c" /* yacc.c:1648 */
+ case 39: /* stridpairlist: stridpairlist ',' stridpair */
+#line 280 "camp.y"
+ { (yyval.ipl) = (yyvsp[-2].ipl); (yyval.ipl)->add((yyvsp[0].ip)); }
+#line 2049 "camp.tab.c"
break;
- case 40:
-#line 284 "camp.y" /* yacc.c:1648 */
- { (yyval.vd) = (yyvsp[-1].vd); }
-#line 2185 "camp.tab.c" /* yacc.c:1648 */
+ case 40: /* vardec: barevardec ';' */
+#line 284 "camp.y"
+ { (yyval.vd) = (yyvsp[-1].vd); }
+#line 2055 "camp.tab.c"
break;
- case 41:
-#line 288 "camp.y" /* yacc.c:1648 */
- { (yyval.vd) = new vardec((yyvsp[-1].t)->getPos(), (yyvsp[-1].t), (yyvsp[0].dil)); }
-#line 2191 "camp.tab.c" /* yacc.c:1648 */
+ case 41: /* barevardec: type decidlist */
+#line 288 "camp.y"
+ { (yyval.vd) = new vardec((yyvsp[-1].t)->getPos(), (yyvsp[-1].t), (yyvsp[0].dil)); }
+#line 2061 "camp.tab.c"
break;
- case 42:
-#line 292 "camp.y" /* yacc.c:1648 */
- { (yyval.t) = (yyvsp[0].t); }
-#line 2197 "camp.tab.c" /* yacc.c:1648 */
+ case 42: /* type: celltype */
+#line 292 "camp.y"
+ { (yyval.t) = (yyvsp[0].t); }
+#line 2067 "camp.tab.c"
break;
- case 43:
-#line 293 "camp.y" /* yacc.c:1648 */
- { (yyval.t) = new arrayTy((yyvsp[-1].n), (yyvsp[0].dim)); }
-#line 2203 "camp.tab.c" /* yacc.c:1648 */
+ case 43: /* type: name dims */
+#line 293 "camp.y"
+ { (yyval.t) = new arrayTy((yyvsp[-1].n), (yyvsp[0].dim)); }
+#line 2073 "camp.tab.c"
break;
- case 44:
-#line 297 "camp.y" /* yacc.c:1648 */
- { (yyval.t) = new nameTy((yyvsp[0].n)); }
-#line 2209 "camp.tab.c" /* yacc.c:1648 */
+ case 44: /* celltype: name */
+#line 297 "camp.y"
+ { (yyval.t) = new nameTy((yyvsp[0].n)); }
+#line 2079 "camp.tab.c"
break;
- case 45:
-#line 301 "camp.y" /* yacc.c:1648 */
- { (yyval.dim) = new dimensions((yyvsp[-1].pos)); }
-#line 2215 "camp.tab.c" /* yacc.c:1648 */
+ case 45: /* dims: '[' ']' */
+#line 301 "camp.y"
+ { (yyval.dim) = new dimensions((yyvsp[-1].pos)); }
+#line 2085 "camp.tab.c"
break;
- case 46:
-#line 302 "camp.y" /* yacc.c:1648 */
- { (yyval.dim) = (yyvsp[-2].dim); (yyval.dim)->increase(); }
-#line 2221 "camp.tab.c" /* yacc.c:1648 */
+ case 46: /* dims: dims '[' ']' */
+#line 302 "camp.y"
+ { (yyval.dim) = (yyvsp[-2].dim); (yyval.dim)->increase(); }
+#line 2091 "camp.tab.c"
break;
- case 47:
-#line 306 "camp.y" /* yacc.c:1648 */
- { (yyval.elist) = new explist((yyvsp[-2].pos)); (yyval.elist)->add((yyvsp[-1].e)); }
-#line 2227 "camp.tab.c" /* yacc.c:1648 */
+ case 47: /* dimexps: '[' exp ']' */
+#line 306 "camp.y"
+ { (yyval.elist) = new explist((yyvsp[-2].pos)); (yyval.elist)->add((yyvsp[-1].e)); }
+#line 2097 "camp.tab.c"
break;
- case 48:
-#line 308 "camp.y" /* yacc.c:1648 */
- { (yyval.elist) = (yyvsp[-3].elist); (yyval.elist)->add((yyvsp[-1].e)); }
-#line 2233 "camp.tab.c" /* yacc.c:1648 */
+ case 48: /* dimexps: dimexps '[' exp ']' */
+#line 308 "camp.y"
+ { (yyval.elist) = (yyvsp[-3].elist); (yyval.elist)->add((yyvsp[-1].e)); }
+#line 2103 "camp.tab.c"
break;
- case 49:
-#line 312 "camp.y" /* yacc.c:1648 */
- { (yyval.dil) = new decidlist((yyvsp[0].di)->getPos()); (yyval.dil)->add((yyvsp[0].di)); }
-#line 2239 "camp.tab.c" /* yacc.c:1648 */
+ case 49: /* decidlist: decid */
+#line 312 "camp.y"
+ { (yyval.dil) = new decidlist((yyvsp[0].di)->getPos()); (yyval.dil)->add((yyvsp[0].di)); }
+#line 2109 "camp.tab.c"
break;
- case 50:
-#line 314 "camp.y" /* yacc.c:1648 */
- { (yyval.dil) = (yyvsp[-2].dil); (yyval.dil)->add((yyvsp[0].di)); }
-#line 2245 "camp.tab.c" /* yacc.c:1648 */
+ case 50: /* decidlist: decidlist ',' decid */
+#line 314 "camp.y"
+ { (yyval.dil) = (yyvsp[-2].dil); (yyval.dil)->add((yyvsp[0].di)); }
+#line 2115 "camp.tab.c"
break;
- case 51:
-#line 318 "camp.y" /* yacc.c:1648 */
- { (yyval.di) = new decid((yyvsp[0].dis)->getPos(), (yyvsp[0].dis)); }
-#line 2251 "camp.tab.c" /* yacc.c:1648 */
+ case 51: /* decid: decidstart */
+#line 318 "camp.y"
+ { (yyval.di) = new decid((yyvsp[0].dis)->getPos(), (yyvsp[0].dis)); }
+#line 2121 "camp.tab.c"
break;
- case 52:
-#line 320 "camp.y" /* yacc.c:1648 */
- { (yyval.di) = new decid((yyvsp[-2].dis)->getPos(), (yyvsp[-2].dis), (yyvsp[0].vi)); }
-#line 2257 "camp.tab.c" /* yacc.c:1648 */
+ case 52: /* decid: decidstart ASSIGN varinit */
+#line 320 "camp.y"
+ { (yyval.di) = new decid((yyvsp[-2].dis)->getPos(), (yyvsp[-2].dis), (yyvsp[0].vi)); }
+#line 2127 "camp.tab.c"
break;
- case 53:
-#line 324 "camp.y" /* yacc.c:1648 */
- { (yyval.dis) = new decidstart((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
-#line 2263 "camp.tab.c" /* yacc.c:1648 */
+ case 53: /* decidstart: ID */
+#line 324 "camp.y"
+ { (yyval.dis) = new decidstart((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
+#line 2133 "camp.tab.c"
break;
- case 54:
-#line 325 "camp.y" /* yacc.c:1648 */
- { (yyval.dis) = new decidstart((yyvsp[-1].ps).pos, (yyvsp[-1].ps).sym, (yyvsp[0].dim)); }
-#line 2269 "camp.tab.c" /* yacc.c:1648 */
+ case 54: /* decidstart: ID dims */
+#line 325 "camp.y"
+ { (yyval.dis) = new decidstart((yyvsp[-1].ps).pos, (yyvsp[-1].ps).sym, (yyvsp[0].dim)); }
+#line 2139 "camp.tab.c"
break;
- case 55:
-#line 326 "camp.y" /* yacc.c:1648 */
- { (yyval.dis) = new fundecidstart((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym, 0,
+ case 55: /* decidstart: ID '(' ')' */
+#line 326 "camp.y"
+ { (yyval.dis) = new fundecidstart((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym, 0,
new formals((yyvsp[-1].pos))); }
-#line 2276 "camp.tab.c" /* yacc.c:1648 */
+#line 2146 "camp.tab.c"
break;
- case 56:
-#line 329 "camp.y" /* yacc.c:1648 */
- { (yyval.dis) = new fundecidstart((yyvsp[-3].ps).pos, (yyvsp[-3].ps).sym, 0, (yyvsp[-1].fls)); }
-#line 2282 "camp.tab.c" /* yacc.c:1648 */
+ case 56: /* decidstart: ID '(' formals ')' */
+#line 329 "camp.y"
+ { (yyval.dis) = new fundecidstart((yyvsp[-3].ps).pos, (yyvsp[-3].ps).sym, 0, (yyvsp[-1].fls)); }
+#line 2152 "camp.tab.c"
break;
- case 57:
-#line 333 "camp.y" /* yacc.c:1648 */
- { (yyval.vi) = (yyvsp[0].e); }
-#line 2288 "camp.tab.c" /* yacc.c:1648 */
+ case 57: /* varinit: exp */
+#line 333 "camp.y"
+ { (yyval.vi) = (yyvsp[0].e); }
+#line 2158 "camp.tab.c"
break;
- case 58:
-#line 334 "camp.y" /* yacc.c:1648 */
- { (yyval.vi) = (yyvsp[0].ai); }
-#line 2294 "camp.tab.c" /* yacc.c:1648 */
+ case 58: /* varinit: arrayinit */
+#line 334 "camp.y"
+ { (yyval.vi) = (yyvsp[0].ai); }
+#line 2164 "camp.tab.c"
break;
- case 59:
-#line 339 "camp.y" /* yacc.c:1648 */
- { (yyval.b) = (yyvsp[-1].b); }
-#line 2300 "camp.tab.c" /* yacc.c:1648 */
+ case 59: /* block: '{' bareblock '}' */
+#line 339 "camp.y"
+ { (yyval.b) = (yyvsp[-1].b); }
+#line 2170 "camp.tab.c"
break;
- case 60:
-#line 343 "camp.y" /* yacc.c:1648 */
- { (yyval.ai) = new arrayinit((yyvsp[-1].pos)); }
-#line 2306 "camp.tab.c" /* yacc.c:1648 */
+ case 60: /* arrayinit: '{' '}' */
+#line 343 "camp.y"
+ { (yyval.ai) = new arrayinit((yyvsp[-1].pos)); }
+#line 2176 "camp.tab.c"
break;
- case 61:
-#line 345 "camp.y" /* yacc.c:1648 */
- { (yyval.ai) = new arrayinit((yyvsp[-3].pos)); (yyval.ai)->addRest((yyvsp[-1].vi)); }
-#line 2312 "camp.tab.c" /* yacc.c:1648 */
+ case 61: /* arrayinit: '{' ELLIPSIS varinit '}' */
+#line 345 "camp.y"
+ { (yyval.ai) = new arrayinit((yyvsp[-3].pos)); (yyval.ai)->addRest((yyvsp[-1].vi)); }
+#line 2182 "camp.tab.c"
break;
- case 62:
-#line 347 "camp.y" /* yacc.c:1648 */
- { (yyval.ai) = (yyvsp[-1].ai); }
-#line 2318 "camp.tab.c" /* yacc.c:1648 */
+ case 62: /* arrayinit: '{' basearrayinit '}' */
+#line 347 "camp.y"
+ { (yyval.ai) = (yyvsp[-1].ai); }
+#line 2188 "camp.tab.c"
break;
- case 63:
-#line 349 "camp.y" /* yacc.c:1648 */
- { (yyval.ai) = (yyvsp[-3].ai); (yyval.ai)->addRest((yyvsp[-1].vi)); }
-#line 2324 "camp.tab.c" /* yacc.c:1648 */
+ case 63: /* arrayinit: '{' basearrayinit ELLIPSIS varinit '}' */
+#line 349 "camp.y"
+ { (yyval.ai) = (yyvsp[-3].ai); (yyval.ai)->addRest((yyvsp[-1].vi)); }
+#line 2194 "camp.tab.c"
break;
- case 64:
-#line 353 "camp.y" /* yacc.c:1648 */
- { (yyval.ai) = new arrayinit((yyvsp[0].pos)); }
-#line 2330 "camp.tab.c" /* yacc.c:1648 */
+ case 64: /* basearrayinit: ',' */
+#line 353 "camp.y"
+ { (yyval.ai) = new arrayinit((yyvsp[0].pos)); }
+#line 2200 "camp.tab.c"
break;
- case 65:
-#line 354 "camp.y" /* yacc.c:1648 */
- { (yyval.ai) = (yyvsp[0].ai); }
-#line 2336 "camp.tab.c" /* yacc.c:1648 */
+ case 65: /* basearrayinit: varinits */
+#line 354 "camp.y"
+ { (yyval.ai) = (yyvsp[0].ai); }
+#line 2206 "camp.tab.c"
break;
- case 66:
-#line 355 "camp.y" /* yacc.c:1648 */
- { (yyval.ai) = (yyvsp[-1].ai); }
-#line 2342 "camp.tab.c" /* yacc.c:1648 */
+ case 66: /* basearrayinit: varinits ',' */
+#line 355 "camp.y"
+ { (yyval.ai) = (yyvsp[-1].ai); }
+#line 2212 "camp.tab.c"
break;
- case 67:
-#line 359 "camp.y" /* yacc.c:1648 */
- { (yyval.ai) = new arrayinit((yyvsp[0].vi)->getPos());
+ case 67: /* varinits: varinit */
+#line 359 "camp.y"
+ { (yyval.ai) = new arrayinit((yyvsp[0].vi)->getPos());
(yyval.ai)->add((yyvsp[0].vi));}
-#line 2349 "camp.tab.c" /* yacc.c:1648 */
+#line 2219 "camp.tab.c"
break;
- case 68:
-#line 362 "camp.y" /* yacc.c:1648 */
- { (yyval.ai) = (yyvsp[-2].ai); (yyval.ai)->add((yyvsp[0].vi)); }
-#line 2355 "camp.tab.c" /* yacc.c:1648 */
+ case 68: /* varinits: varinits ',' varinit */
+#line 362 "camp.y"
+ { (yyval.ai) = (yyvsp[-2].ai); (yyval.ai)->add((yyvsp[0].vi)); }
+#line 2225 "camp.tab.c"
break;
- case 69:
-#line 366 "camp.y" /* yacc.c:1648 */
- { (yyval.fls) = new formals((yyvsp[0].fl)->getPos()); (yyval.fls)->add((yyvsp[0].fl)); }
-#line 2361 "camp.tab.c" /* yacc.c:1648 */
+ case 69: /* formals: formal */
+#line 366 "camp.y"
+ { (yyval.fls) = new formals((yyvsp[0].fl)->getPos()); (yyval.fls)->add((yyvsp[0].fl)); }
+#line 2231 "camp.tab.c"
break;
- case 70:
-#line 367 "camp.y" /* yacc.c:1648 */
- { (yyval.fls) = new formals((yyvsp[-1].pos)); (yyval.fls)->addRest((yyvsp[0].fl)); }
-#line 2367 "camp.tab.c" /* yacc.c:1648 */
+ case 70: /* formals: ELLIPSIS formal */
+#line 367 "camp.y"
+ { (yyval.fls) = new formals((yyvsp[-1].pos)); (yyval.fls)->addRest((yyvsp[0].fl)); }
+#line 2237 "camp.tab.c"
break;
- case 71:
-#line 369 "camp.y" /* yacc.c:1648 */
- { (yyval.fls) = (yyvsp[-2].fls); (yyval.fls)->add((yyvsp[0].fl)); }
-#line 2373 "camp.tab.c" /* yacc.c:1648 */
+ case 71: /* formals: formals ',' formal */
+#line 369 "camp.y"
+ { (yyval.fls) = (yyvsp[-2].fls); (yyval.fls)->add((yyvsp[0].fl)); }
+#line 2243 "camp.tab.c"
break;
- case 72:
-#line 371 "camp.y" /* yacc.c:1648 */
- { (yyval.fls) = (yyvsp[-2].fls); (yyval.fls)->addRest((yyvsp[0].fl)); }
-#line 2379 "camp.tab.c" /* yacc.c:1648 */
+ case 72: /* formals: formals ELLIPSIS formal */
+#line 371 "camp.y"
+ { (yyval.fls) = (yyvsp[-2].fls); (yyval.fls)->addRest((yyvsp[0].fl)); }
+#line 2249 "camp.tab.c"
break;
- case 73:
-#line 375 "camp.y" /* yacc.c:1648 */
- { (yyval.boo) = true; }
-#line 2385 "camp.tab.c" /* yacc.c:1648 */
+ case 73: /* explicitornot: EXPLICIT */
+#line 375 "camp.y"
+ { (yyval.boo) = true; }
+#line 2255 "camp.tab.c"
break;
- case 74:
-#line 376 "camp.y" /* yacc.c:1648 */
- { (yyval.boo) = false; }
-#line 2391 "camp.tab.c" /* yacc.c:1648 */
+ case 74: /* explicitornot: %empty */
+#line 376 "camp.y"
+ { (yyval.boo) = false; }
+#line 2261 "camp.tab.c"
break;
- case 75:
-#line 381 "camp.y" /* yacc.c:1648 */
- { (yyval.fl) = new formal((yyvsp[0].t)->getPos(), (yyvsp[0].t), 0, 0, (yyvsp[-1].boo), 0); }
-#line 2397 "camp.tab.c" /* yacc.c:1648 */
+ case 75: /* formal: explicitornot type */
+#line 381 "camp.y"
+ { (yyval.fl) = new formal((yyvsp[0].t)->getPos(), (yyvsp[0].t), 0, 0, (yyvsp[-1].boo), 0); }
+#line 2267 "camp.tab.c"
break;
- case 76:
-#line 383 "camp.y" /* yacc.c:1648 */
- { (yyval.fl) = new formal((yyvsp[-1].t)->getPos(), (yyvsp[-1].t), (yyvsp[0].dis), 0, (yyvsp[-2].boo), 0); }
-#line 2403 "camp.tab.c" /* yacc.c:1648 */
+ case 76: /* formal: explicitornot type decidstart */
+#line 383 "camp.y"
+ { (yyval.fl) = new formal((yyvsp[-1].t)->getPos(), (yyvsp[-1].t), (yyvsp[0].dis), 0, (yyvsp[-2].boo), 0); }
+#line 2273 "camp.tab.c"
break;
- case 77:
-#line 385 "camp.y" /* yacc.c:1648 */
- { (yyval.fl) = new formal((yyvsp[-3].t)->getPos(), (yyvsp[-3].t), (yyvsp[-2].dis), (yyvsp[0].vi), (yyvsp[-4].boo), 0); }
-#line 2409 "camp.tab.c" /* yacc.c:1648 */
+ case 77: /* formal: explicitornot type decidstart ASSIGN varinit */
+#line 385 "camp.y"
+ { (yyval.fl) = new formal((yyvsp[-3].t)->getPos(), (yyvsp[-3].t), (yyvsp[-2].dis), (yyvsp[0].vi), (yyvsp[-4].boo), 0); }
+#line 2279 "camp.tab.c"
break;
- case 78:
-#line 388 "camp.y" /* yacc.c:1648 */
- { bool k = checkKeyword((yyvsp[-1].ps).pos, (yyvsp[-1].ps).sym);
+ case 78: /* formal: explicitornot type ID decidstart */
+#line 388 "camp.y"
+ { bool k = checkKeyword((yyvsp[-1].ps).pos, (yyvsp[-1].ps).sym);
(yyval.fl) = new formal((yyvsp[-2].t)->getPos(), (yyvsp[-2].t), (yyvsp[0].dis), 0, (yyvsp[-3].boo), k); }
-#line 2416 "camp.tab.c" /* yacc.c:1648 */
+#line 2286 "camp.tab.c"
break;
- case 79:
-#line 391 "camp.y" /* yacc.c:1648 */
- { bool k = checkKeyword((yyvsp[-3].ps).pos, (yyvsp[-3].ps).sym);
+ case 79: /* formal: explicitornot type ID decidstart ASSIGN varinit */
+#line 391 "camp.y"
+ { bool k = checkKeyword((yyvsp[-3].ps).pos, (yyvsp[-3].ps).sym);
(yyval.fl) = new formal((yyvsp[-4].t)->getPos(), (yyvsp[-4].t), (yyvsp[-2].dis), (yyvsp[0].vi), (yyvsp[-5].boo), k); }
-#line 2423 "camp.tab.c" /* yacc.c:1648 */
+#line 2293 "camp.tab.c"
break;
- case 80:
-#line 397 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = new fundec((yyvsp[-2].pos), (yyvsp[-4].t), (yyvsp[-3].ps).sym, new formals((yyvsp[-2].pos)), (yyvsp[0].s)); }
-#line 2429 "camp.tab.c" /* yacc.c:1648 */
+ case 80: /* fundec: type ID '(' ')' blockstm */
+#line 397 "camp.y"
+ { (yyval.d) = new fundec((yyvsp[-2].pos), (yyvsp[-4].t), (yyvsp[-3].ps).sym, new formals((yyvsp[-2].pos)), (yyvsp[0].s)); }
+#line 2299 "camp.tab.c"
break;
- case 81:
-#line 399 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = new fundec((yyvsp[-3].pos), (yyvsp[-5].t), (yyvsp[-4].ps).sym, (yyvsp[-2].fls), (yyvsp[0].s)); }
-#line 2435 "camp.tab.c" /* yacc.c:1648 */
+ case 81: /* fundec: type ID '(' formals ')' blockstm */
+#line 399 "camp.y"
+ { (yyval.d) = new fundec((yyvsp[-3].pos), (yyvsp[-5].t), (yyvsp[-4].ps).sym, (yyvsp[-2].fls), (yyvsp[0].s)); }
+#line 2305 "camp.tab.c"
break;
- case 82:
-#line 403 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = new recorddec((yyvsp[-2].pos), (yyvsp[-1].ps).sym, (yyvsp[0].b)); }
-#line 2441 "camp.tab.c" /* yacc.c:1648 */
+ case 82: /* typedec: STRUCT ID block */
+#line 403 "camp.y"
+ { (yyval.d) = new recorddec((yyvsp[-2].pos), (yyvsp[-1].ps).sym, (yyvsp[0].b)); }
+#line 2311 "camp.tab.c"
break;
- case 83:
-#line 404 "camp.y" /* yacc.c:1648 */
- { (yyval.d) = new typedec((yyvsp[-1].pos), (yyvsp[0].vd)); }
-#line 2447 "camp.tab.c" /* yacc.c:1648 */
+ case 83: /* typedec: TYPEDEF vardec */
+#line 404 "camp.y"
+ { (yyval.d) = new typedec((yyvsp[-1].pos), (yyvsp[0].vd)); }
+#line 2317 "camp.tab.c"
break;
- case 84:
-#line 408 "camp.y" /* yacc.c:1648 */
- { (yyval.slice) = new slice((yyvsp[0].pos), 0, 0); }
-#line 2453 "camp.tab.c" /* yacc.c:1648 */
+ case 84: /* slice: ':' */
+#line 408 "camp.y"
+ { (yyval.slice) = new slice((yyvsp[0].pos), 0, 0); }
+#line 2323 "camp.tab.c"
break;
- case 85:
-#line 409 "camp.y" /* yacc.c:1648 */
- { (yyval.slice) = new slice((yyvsp[0].pos), (yyvsp[-1].e), 0); }
-#line 2459 "camp.tab.c" /* yacc.c:1648 */
+ case 85: /* slice: exp ':' */
+#line 409 "camp.y"
+ { (yyval.slice) = new slice((yyvsp[0].pos), (yyvsp[-1].e), 0); }
+#line 2329 "camp.tab.c"
break;
- case 86:
-#line 410 "camp.y" /* yacc.c:1648 */
- { (yyval.slice) = new slice((yyvsp[-1].pos), 0, (yyvsp[0].e)); }
-#line 2465 "camp.tab.c" /* yacc.c:1648 */
+ case 86: /* slice: ':' exp */
+#line 410 "camp.y"
+ { (yyval.slice) = new slice((yyvsp[-1].pos), 0, (yyvsp[0].e)); }
+#line 2335 "camp.tab.c"
break;
- case 87:
-#line 411 "camp.y" /* yacc.c:1648 */
- { (yyval.slice) = new slice((yyvsp[-1].pos), (yyvsp[-2].e), (yyvsp[0].e)); }
-#line 2471 "camp.tab.c" /* yacc.c:1648 */
+ case 87: /* slice: exp ':' exp */
+#line 411 "camp.y"
+ { (yyval.slice) = new slice((yyvsp[-1].pos), (yyvsp[-2].e), (yyvsp[0].e)); }
+#line 2341 "camp.tab.c"
break;
- case 88:
-#line 415 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new fieldExp((yyvsp[-1].pos), (yyvsp[-2].e), (yyvsp[0].ps).sym); }
-#line 2477 "camp.tab.c" /* yacc.c:1648 */
+ case 88: /* value: value '.' ID */
+#line 415 "camp.y"
+ { (yyval.e) = new fieldExp((yyvsp[-1].pos), (yyvsp[-2].e), (yyvsp[0].ps).sym); }
+#line 2347 "camp.tab.c"
break;
- case 89:
-#line 416 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new subscriptExp((yyvsp[-2].pos),
+ case 89: /* value: name '[' exp ']' */
+#line 416 "camp.y"
+ { (yyval.e) = new subscriptExp((yyvsp[-2].pos),
new nameExp((yyvsp[-3].n)->getPos(), (yyvsp[-3].n)), (yyvsp[-1].e)); }
-#line 2484 "camp.tab.c" /* yacc.c:1648 */
+#line 2354 "camp.tab.c"
break;
- case 90:
-#line 418 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new subscriptExp((yyvsp[-2].pos), (yyvsp[-3].e), (yyvsp[-1].e)); }
-#line 2490 "camp.tab.c" /* yacc.c:1648 */
+ case 90: /* value: value '[' exp ']' */
+#line 418 "camp.y"
+ { (yyval.e) = new subscriptExp((yyvsp[-2].pos), (yyvsp[-3].e), (yyvsp[-1].e)); }
+#line 2360 "camp.tab.c"
break;
- case 91:
-#line 419 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new sliceExp((yyvsp[-2].pos),
+ case 91: /* value: name '[' slice ']' */
+#line 419 "camp.y"
+ { (yyval.e) = new sliceExp((yyvsp[-2].pos),
new nameExp((yyvsp[-3].n)->getPos(), (yyvsp[-3].n)), (yyvsp[-1].slice)); }
-#line 2497 "camp.tab.c" /* yacc.c:1648 */
+#line 2367 "camp.tab.c"
break;
- case 92:
-#line 421 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new sliceExp((yyvsp[-2].pos), (yyvsp[-3].e), (yyvsp[-1].slice)); }
-#line 2503 "camp.tab.c" /* yacc.c:1648 */
+ case 92: /* value: value '[' slice ']' */
+#line 421 "camp.y"
+ { (yyval.e) = new sliceExp((yyvsp[-2].pos), (yyvsp[-3].e), (yyvsp[-1].slice)); }
+#line 2373 "camp.tab.c"
break;
- case 93:
-#line 422 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new callExp((yyvsp[-1].pos),
+ case 93: /* value: name '(' ')' */
+#line 422 "camp.y"
+ { (yyval.e) = new callExp((yyvsp[-1].pos),
new nameExp((yyvsp[-2].n)->getPos(), (yyvsp[-2].n)),
new arglist()); }
-#line 2511 "camp.tab.c" /* yacc.c:1648 */
+#line 2381 "camp.tab.c"
break;
- case 94:
-#line 426 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new callExp((yyvsp[-2].pos),
+ case 94: /* value: name '(' arglist ')' */
+#line 426 "camp.y"
+ { (yyval.e) = new callExp((yyvsp[-2].pos),
new nameExp((yyvsp[-3].n)->getPos(), (yyvsp[-3].n)),
(yyvsp[-1].alist)); }
-#line 2519 "camp.tab.c" /* yacc.c:1648 */
+#line 2389 "camp.tab.c"
break;
- case 95:
-#line 429 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new callExp((yyvsp[-1].pos), (yyvsp[-2].e), new arglist()); }
-#line 2525 "camp.tab.c" /* yacc.c:1648 */
+ case 95: /* value: value '(' ')' */
+#line 429 "camp.y"
+ { (yyval.e) = new callExp((yyvsp[-1].pos), (yyvsp[-2].e), new arglist()); }
+#line 2395 "camp.tab.c"
break;
- case 96:
-#line 431 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new callExp((yyvsp[-2].pos), (yyvsp[-3].e), (yyvsp[-1].alist)); }
-#line 2531 "camp.tab.c" /* yacc.c:1648 */
+ case 96: /* value: value '(' arglist ')' */
+#line 431 "camp.y"
+ { (yyval.e) = new callExp((yyvsp[-2].pos), (yyvsp[-3].e), (yyvsp[-1].alist)); }
+#line 2401 "camp.tab.c"
break;
- case 97:
-#line 433 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = (yyvsp[-1].e); }
-#line 2537 "camp.tab.c" /* yacc.c:1648 */
+ case 97: /* value: '(' exp ')' */
+#line 433 "camp.y"
+ { (yyval.e) = (yyvsp[-1].e); }
+#line 2407 "camp.tab.c"
break;
- case 98:
-#line 435 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new nameExp((yyvsp[-1].n)->getPos(), (yyvsp[-1].n)); }
-#line 2543 "camp.tab.c" /* yacc.c:1648 */
+ case 98: /* value: '(' name ')' */
+#line 435 "camp.y"
+ { (yyval.e) = new nameExp((yyvsp[-1].n)->getPos(), (yyvsp[-1].n)); }
+#line 2413 "camp.tab.c"
break;
- case 99:
-#line 436 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new thisExp((yyvsp[0].pos)); }
-#line 2549 "camp.tab.c" /* yacc.c:1648 */
+ case 99: /* value: THIS */
+#line 436 "camp.y"
+ { (yyval.e) = new thisExp((yyvsp[0].pos)); }
+#line 2419 "camp.tab.c"
break;
- case 100:
-#line 440 "camp.y" /* yacc.c:1648 */
- { (yyval.arg).name = symbol::nullsym; (yyval.arg).val=(yyvsp[0].e); }
-#line 2555 "camp.tab.c" /* yacc.c:1648 */
+ case 100: /* argument: exp */
+#line 440 "camp.y"
+ { (yyval.arg).name = symbol::nullsym; (yyval.arg).val=(yyvsp[0].e); }
+#line 2425 "camp.tab.c"
break;
- case 101:
-#line 441 "camp.y" /* yacc.c:1648 */
- { (yyval.arg).name = (yyvsp[-2].ps).sym; (yyval.arg).val=(yyvsp[0].e); }
-#line 2561 "camp.tab.c" /* yacc.c:1648 */
+ case 101: /* argument: ID ASSIGN exp */
+#line 441 "camp.y"
+ { (yyval.arg).name = (yyvsp[-2].ps).sym; (yyval.arg).val=(yyvsp[0].e); }
+#line 2431 "camp.tab.c"
break;
- case 102:
-#line 445 "camp.y" /* yacc.c:1648 */
- { (yyval.alist) = new arglist(); (yyval.alist)->add((yyvsp[0].arg)); }
-#line 2567 "camp.tab.c" /* yacc.c:1648 */
+ case 102: /* arglist: argument */
+#line 445 "camp.y"
+ { (yyval.alist) = new arglist(); (yyval.alist)->add((yyvsp[0].arg)); }
+#line 2437 "camp.tab.c"
break;
- case 103:
-#line 447 "camp.y" /* yacc.c:1648 */
- { (yyval.alist) = new arglist(); (yyval.alist)->addRest((yyvsp[0].arg)); }
-#line 2573 "camp.tab.c" /* yacc.c:1648 */
+ case 103: /* arglist: ELLIPSIS argument */
+#line 447 "camp.y"
+ { (yyval.alist) = new arglist(); (yyval.alist)->addRest((yyvsp[0].arg)); }
+#line 2443 "camp.tab.c"
break;
- case 104:
-#line 449 "camp.y" /* yacc.c:1648 */
- { (yyval.alist) = (yyvsp[-2].alist); (yyval.alist)->add((yyvsp[0].arg)); }
-#line 2579 "camp.tab.c" /* yacc.c:1648 */
+ case 104: /* arglist: arglist ',' argument */
+#line 449 "camp.y"
+ { (yyval.alist) = (yyvsp[-2].alist); (yyval.alist)->add((yyvsp[0].arg)); }
+#line 2449 "camp.tab.c"
break;
- case 105:
-#line 451 "camp.y" /* yacc.c:1648 */
- { (yyval.alist) = (yyvsp[-2].alist); (yyval.alist)->addRest((yyvsp[0].arg)); }
-#line 2585 "camp.tab.c" /* yacc.c:1648 */
+ case 105: /* arglist: arglist ELLIPSIS argument */
+#line 451 "camp.y"
+ { (yyval.alist) = (yyvsp[-2].alist); (yyval.alist)->addRest((yyvsp[0].arg)); }
+#line 2455 "camp.tab.c"
break;
- case 106:
-#line 456 "camp.y" /* yacc.c:1648 */
- { (yyval.alist) = new arglist(); (yyval.alist)->add((yyvsp[-2].e)); (yyval.alist)->add((yyvsp[0].e)); }
-#line 2591 "camp.tab.c" /* yacc.c:1648 */
+ case 106: /* tuple: exp ',' exp */
+#line 456 "camp.y"
+ { (yyval.alist) = new arglist(); (yyval.alist)->add((yyvsp[-2].e)); (yyval.alist)->add((yyvsp[0].e)); }
+#line 2461 "camp.tab.c"
break;
- case 107:
-#line 457 "camp.y" /* yacc.c:1648 */
- { (yyval.alist) = (yyvsp[-2].alist); (yyval.alist)->add((yyvsp[0].e)); }
-#line 2597 "camp.tab.c" /* yacc.c:1648 */
+ case 107: /* tuple: tuple ',' exp */
+#line 457 "camp.y"
+ { (yyval.alist) = (yyvsp[-2].alist); (yyval.alist)->add((yyvsp[0].e)); }
+#line 2467 "camp.tab.c"
break;
- case 108:
-#line 461 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new nameExp((yyvsp[0].n)->getPos(), (yyvsp[0].n)); }
-#line 2603 "camp.tab.c" /* yacc.c:1648 */
+ case 108: /* exp: name */
+#line 461 "camp.y"
+ { (yyval.e) = new nameExp((yyvsp[0].n)->getPos(), (yyvsp[0].n)); }
+#line 2473 "camp.tab.c"
break;
- case 109:
-#line 462 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = (yyvsp[0].e); }
-#line 2609 "camp.tab.c" /* yacc.c:1648 */
+ case 109: /* exp: value */
+#line 462 "camp.y"
+ { (yyval.e) = (yyvsp[0].e); }
+#line 2479 "camp.tab.c"
break;
- case 110:
-#line 463 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = (yyvsp[0].e); }
-#line 2615 "camp.tab.c" /* yacc.c:1648 */
+ case 110: /* exp: LIT */
+#line 463 "camp.y"
+ { (yyval.e) = (yyvsp[0].e); }
+#line 2485 "camp.tab.c"
break;
- case 111:
-#line 464 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = (yyvsp[0].stre); }
-#line 2621 "camp.tab.c" /* yacc.c:1648 */
+ case 111: /* exp: STRING */
+#line 464 "camp.y"
+ { (yyval.e) = (yyvsp[0].stre); }
+#line 2491 "camp.tab.c"
break;
- case 112:
-#line 466 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new scaleExp((yyvsp[-1].e)->getPos(), (yyvsp[-1].e), (yyvsp[0].e)); }
-#line 2627 "camp.tab.c" /* yacc.c:1648 */
+ case 112: /* exp: LIT exp */
+#line 466 "camp.y"
+ { (yyval.e) = new scaleExp((yyvsp[-1].e)->getPos(), (yyvsp[-1].e), (yyvsp[0].e)); }
+#line 2497 "camp.tab.c"
break;
- case 113:
-#line 468 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new castExp((yyvsp[-2].n)->getPos(), new nameTy((yyvsp[-2].n)), (yyvsp[0].e)); }
-#line 2633 "camp.tab.c" /* yacc.c:1648 */
+ case 113: /* exp: '(' name ')' exp */
+#line 468 "camp.y"
+ { (yyval.e) = new castExp((yyvsp[-2].n)->getPos(), new nameTy((yyvsp[-2].n)), (yyvsp[0].e)); }
+#line 2503 "camp.tab.c"
break;
- case 114:
-#line 470 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new castExp((yyvsp[-3].n)->getPos(), new arrayTy((yyvsp[-3].n), (yyvsp[-2].dim)), (yyvsp[0].e)); }
-#line 2639 "camp.tab.c" /* yacc.c:1648 */
+ case 114: /* exp: '(' name dims ')' exp */
+#line 470 "camp.y"
+ { (yyval.e) = new castExp((yyvsp[-3].n)->getPos(), new arrayTy((yyvsp[-3].n), (yyvsp[-2].dim)), (yyvsp[0].e)); }
+#line 2509 "camp.tab.c"
break;
- case 115:
-#line 472 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new unaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym); }
-#line 2645 "camp.tab.c" /* yacc.c:1648 */
+ case 115: /* exp: '+' exp */
+#line 472 "camp.y"
+ { (yyval.e) = new unaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym); }
+#line 2515 "camp.tab.c"
break;
- case 116:
-#line 474 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new unaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym); }
-#line 2651 "camp.tab.c" /* yacc.c:1648 */
+ case 116: /* exp: '-' exp */
+#line 474 "camp.y"
+ { (yyval.e) = new unaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym); }
+#line 2521 "camp.tab.c"
break;
- case 117:
-#line 475 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new unaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym); }
-#line 2657 "camp.tab.c" /* yacc.c:1648 */
+ case 117: /* exp: OPERATOR exp */
+#line 475 "camp.y"
+ { (yyval.e) = new unaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym); }
+#line 2527 "camp.tab.c"
break;
- case 118:
-#line 476 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2663 "camp.tab.c" /* yacc.c:1648 */
+ case 118: /* exp: exp '+' exp */
+#line 476 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2533 "camp.tab.c"
break;
- case 119:
-#line 477 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2669 "camp.tab.c" /* yacc.c:1648 */
+ case 119: /* exp: exp '-' exp */
+#line 477 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2539 "camp.tab.c"
break;
- case 120:
-#line 478 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2675 "camp.tab.c" /* yacc.c:1648 */
+ case 120: /* exp: exp '*' exp */
+#line 478 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2545 "camp.tab.c"
break;
- case 121:
-#line 479 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2681 "camp.tab.c" /* yacc.c:1648 */
+ case 121: /* exp: exp '/' exp */
+#line 479 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2551 "camp.tab.c"
break;
- case 122:
-#line 480 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2687 "camp.tab.c" /* yacc.c:1648 */
+ case 122: /* exp: exp '%' exp */
+#line 480 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2557 "camp.tab.c"
break;
- case 123:
-#line 481 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2693 "camp.tab.c" /* yacc.c:1648 */
+ case 123: /* exp: exp '#' exp */
+#line 481 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2563 "camp.tab.c"
break;
- case 124:
-#line 482 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2699 "camp.tab.c" /* yacc.c:1648 */
+ case 124: /* exp: exp '^' exp */
+#line 482 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2569 "camp.tab.c"
break;
- case 125:
-#line 483 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2705 "camp.tab.c" /* yacc.c:1648 */
+ case 125: /* exp: exp LT exp */
+#line 483 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2575 "camp.tab.c"
break;
- case 126:
-#line 484 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2711 "camp.tab.c" /* yacc.c:1648 */
+ case 126: /* exp: exp LE exp */
+#line 484 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2581 "camp.tab.c"
break;
- case 127:
-#line 485 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2717 "camp.tab.c" /* yacc.c:1648 */
+ case 127: /* exp: exp GT exp */
+#line 485 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2587 "camp.tab.c"
break;
- case 128:
-#line 486 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2723 "camp.tab.c" /* yacc.c:1648 */
+ case 128: /* exp: exp GE exp */
+#line 486 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2593 "camp.tab.c"
break;
- case 129:
-#line 487 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new equalityExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2729 "camp.tab.c" /* yacc.c:1648 */
+ case 129: /* exp: exp EQ exp */
+#line 487 "camp.y"
+ { (yyval.e) = new equalityExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2599 "camp.tab.c"
break;
- case 130:
-#line 488 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new equalityExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2735 "camp.tab.c" /* yacc.c:1648 */
+ case 130: /* exp: exp NEQ exp */
+#line 488 "camp.y"
+ { (yyval.e) = new equalityExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2605 "camp.tab.c"
break;
- case 131:
-#line 489 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new andExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2741 "camp.tab.c" /* yacc.c:1648 */
+ case 131: /* exp: exp CAND exp */
+#line 489 "camp.y"
+ { (yyval.e) = new andExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2611 "camp.tab.c"
break;
- case 132:
-#line 490 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new orExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2747 "camp.tab.c" /* yacc.c:1648 */
+ case 132: /* exp: exp COR exp */
+#line 490 "camp.y"
+ { (yyval.e) = new orExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2617 "camp.tab.c"
break;
- case 133:
-#line 491 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2753 "camp.tab.c" /* yacc.c:1648 */
+ case 133: /* exp: exp CARETS exp */
+#line 491 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2623 "camp.tab.c"
break;
- case 134:
-#line 492 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2759 "camp.tab.c" /* yacc.c:1648 */
+ case 134: /* exp: exp AMPERSAND exp */
+#line 492 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2629 "camp.tab.c"
break;
- case 135:
-#line 493 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2765 "camp.tab.c" /* yacc.c:1648 */
+ case 135: /* exp: exp BAR exp */
+#line 493 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2635 "camp.tab.c"
break;
- case 136:
-#line 494 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2771 "camp.tab.c" /* yacc.c:1648 */
+ case 136: /* exp: exp OPERATOR exp */
+#line 494 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2641 "camp.tab.c"
break;
- case 137:
-#line 495 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2777 "camp.tab.c" /* yacc.c:1648 */
+ case 137: /* exp: exp INCR exp */
+#line 495 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2647 "camp.tab.c"
break;
- case 138:
-#line 497 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new newRecordExp((yyvsp[-1].pos), (yyvsp[0].t)); }
-#line 2783 "camp.tab.c" /* yacc.c:1648 */
+ case 138: /* exp: NEW celltype */
+#line 497 "camp.y"
+ { (yyval.e) = new newRecordExp((yyvsp[-1].pos), (yyvsp[0].t)); }
+#line 2653 "camp.tab.c"
break;
- case 139:
-#line 499 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new newArrayExp((yyvsp[-2].pos), (yyvsp[-1].t), (yyvsp[0].elist), 0, 0); }
-#line 2789 "camp.tab.c" /* yacc.c:1648 */
+ case 139: /* exp: NEW celltype dimexps */
+#line 499 "camp.y"
+ { (yyval.e) = new newArrayExp((yyvsp[-2].pos), (yyvsp[-1].t), (yyvsp[0].elist), 0, 0); }
+#line 2659 "camp.tab.c"
break;
- case 140:
-#line 501 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new newArrayExp((yyvsp[-3].pos), (yyvsp[-2].t), (yyvsp[-1].elist), (yyvsp[0].dim), 0); }
-#line 2795 "camp.tab.c" /* yacc.c:1648 */
+ case 140: /* exp: NEW celltype dimexps dims */
+#line 501 "camp.y"
+ { (yyval.e) = new newArrayExp((yyvsp[-3].pos), (yyvsp[-2].t), (yyvsp[-1].elist), (yyvsp[0].dim), 0); }
+#line 2665 "camp.tab.c"
break;
- case 141:
-#line 503 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new newArrayExp((yyvsp[-2].pos), (yyvsp[-1].t), 0, (yyvsp[0].dim), 0); }
-#line 2801 "camp.tab.c" /* yacc.c:1648 */
+ case 141: /* exp: NEW celltype dims */
+#line 503 "camp.y"
+ { (yyval.e) = new newArrayExp((yyvsp[-2].pos), (yyvsp[-1].t), 0, (yyvsp[0].dim), 0); }
+#line 2671 "camp.tab.c"
break;
- case 142:
-#line 505 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new newArrayExp((yyvsp[-3].pos), (yyvsp[-2].t), 0, (yyvsp[-1].dim), (yyvsp[0].ai)); }
-#line 2807 "camp.tab.c" /* yacc.c:1648 */
+ case 142: /* exp: NEW celltype dims arrayinit */
+#line 505 "camp.y"
+ { (yyval.e) = new newArrayExp((yyvsp[-3].pos), (yyvsp[-2].t), 0, (yyvsp[-1].dim), (yyvsp[0].ai)); }
+#line 2677 "camp.tab.c"
break;
- case 143:
-#line 507 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new newFunctionExp((yyvsp[-4].pos), (yyvsp[-3].t), new formals((yyvsp[-2].pos)), (yyvsp[0].s)); }
-#line 2813 "camp.tab.c" /* yacc.c:1648 */
+ case 143: /* exp: NEW celltype '(' ')' blockstm */
+#line 507 "camp.y"
+ { (yyval.e) = new newFunctionExp((yyvsp[-4].pos), (yyvsp[-3].t), new formals((yyvsp[-2].pos)), (yyvsp[0].s)); }
+#line 2683 "camp.tab.c"
break;
- case 144:
-#line 509 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new newFunctionExp((yyvsp[-5].pos),
+ case 144: /* exp: NEW celltype dims '(' ')' blockstm */
+#line 509 "camp.y"
+ { (yyval.e) = new newFunctionExp((yyvsp[-5].pos),
new arrayTy((yyvsp[-4].t)->getPos(), (yyvsp[-4].t), (yyvsp[-3].dim)),
new formals((yyvsp[-2].pos)),
(yyvsp[0].s)); }
-#line 2822 "camp.tab.c" /* yacc.c:1648 */
+#line 2692 "camp.tab.c"
break;
- case 145:
-#line 514 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new newFunctionExp((yyvsp[-5].pos), (yyvsp[-4].t), (yyvsp[-2].fls), (yyvsp[0].s)); }
-#line 2828 "camp.tab.c" /* yacc.c:1648 */
+ case 145: /* exp: NEW celltype '(' formals ')' blockstm */
+#line 514 "camp.y"
+ { (yyval.e) = new newFunctionExp((yyvsp[-5].pos), (yyvsp[-4].t), (yyvsp[-2].fls), (yyvsp[0].s)); }
+#line 2698 "camp.tab.c"
break;
- case 146:
-#line 516 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new newFunctionExp((yyvsp[-6].pos),
+ case 146: /* exp: NEW celltype dims '(' formals ')' blockstm */
+#line 516 "camp.y"
+ { (yyval.e) = new newFunctionExp((yyvsp[-6].pos),
new arrayTy((yyvsp[-5].t)->getPos(), (yyvsp[-5].t), (yyvsp[-4].dim)),
(yyvsp[-2].fls),
(yyvsp[0].s)); }
-#line 2837 "camp.tab.c" /* yacc.c:1648 */
+#line 2707 "camp.tab.c"
break;
- case 147:
-#line 521 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new conditionalExp((yyvsp[-3].pos), (yyvsp[-4].e), (yyvsp[-2].e), (yyvsp[0].e)); }
-#line 2843 "camp.tab.c" /* yacc.c:1648 */
+ case 147: /* exp: exp '?' exp ':' exp */
+#line 521 "camp.y"
+ { (yyval.e) = new conditionalExp((yyvsp[-3].pos), (yyvsp[-4].e), (yyvsp[-2].e), (yyvsp[0].e)); }
+#line 2713 "camp.tab.c"
break;
- case 148:
-#line 522 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new assignExp((yyvsp[-1].pos), (yyvsp[-2].e), (yyvsp[0].e)); }
-#line 2849 "camp.tab.c" /* yacc.c:1648 */
+ case 148: /* exp: exp ASSIGN exp */
+#line 522 "camp.y"
+ { (yyval.e) = new assignExp((yyvsp[-1].pos), (yyvsp[-2].e), (yyvsp[0].e)); }
+#line 2719 "camp.tab.c"
break;
- case 149:
-#line 523 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new callExp((yyvsp[-2].pos), new nameExp((yyvsp[-2].pos), SYM_TUPLE), (yyvsp[-1].alist)); }
-#line 2855 "camp.tab.c" /* yacc.c:1648 */
+ case 149: /* exp: '(' tuple ')' */
+#line 523 "camp.y"
+ { (yyval.e) = new callExp((yyvsp[-2].pos), new nameExp((yyvsp[-2].pos), SYM_TUPLE), (yyvsp[-1].alist)); }
+#line 2725 "camp.tab.c"
break;
- case 150:
-#line 525 "camp.y" /* yacc.c:1648 */
- { (yyvsp[-1].j)->pushFront((yyvsp[-2].e)); (yyvsp[-1].j)->pushBack((yyvsp[0].e)); (yyval.e) = (yyvsp[-1].j); }
-#line 2861 "camp.tab.c" /* yacc.c:1648 */
+ case 150: /* exp: exp join exp */
+#line 525 "camp.y"
+ { (yyvsp[-1].j)->pushFront((yyvsp[-2].e)); (yyvsp[-1].j)->pushBack((yyvsp[0].e)); (yyval.e) = (yyvsp[-1].j); }
+#line 2731 "camp.tab.c"
break;
- case 151:
-#line 527 "camp.y" /* yacc.c:1648 */
- { (yyvsp[0].se)->setSide(camp::OUT);
+ case 151: /* exp: exp dir */
+#line 527 "camp.y"
+ { (yyvsp[0].se)->setSide(camp::OUT);
joinExp *jexp =
new joinExp((yyvsp[0].se)->getPos(), SYM_DOTS);
(yyval.e)=jexp;
jexp->pushBack((yyvsp[-1].e)); jexp->pushBack((yyvsp[0].se)); }
-#line 2871 "camp.tab.c" /* yacc.c:1648 */
+#line 2741 "camp.tab.c"
break;
- case 152:
-#line 533 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new prefixExp((yyvsp[-1].ps).pos, (yyvsp[0].e), SYM_PLUS); }
-#line 2877 "camp.tab.c" /* yacc.c:1648 */
+ case 152: /* exp: INCR exp */
+#line 533 "camp.y"
+ { (yyval.e) = new prefixExp((yyvsp[-1].ps).pos, (yyvsp[0].e), SYM_PLUS); }
+#line 2747 "camp.tab.c"
break;
- case 153:
-#line 535 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new prefixExp((yyvsp[-1].ps).pos, (yyvsp[0].e), SYM_MINUS); }
-#line 2883 "camp.tab.c" /* yacc.c:1648 */
+ case 153: /* exp: DASHES exp */
+#line 535 "camp.y"
+ { (yyval.e) = new prefixExp((yyvsp[-1].ps).pos, (yyvsp[0].e), SYM_MINUS); }
+#line 2753 "camp.tab.c"
break;
- case 154:
-#line 538 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new postfixExp((yyvsp[0].ps).pos, (yyvsp[-1].e), SYM_PLUS); }
-#line 2889 "camp.tab.c" /* yacc.c:1648 */
+ case 154: /* exp: exp INCR */
+#line 538 "camp.y"
+ { (yyval.e) = new postfixExp((yyvsp[0].ps).pos, (yyvsp[-1].e), SYM_PLUS); }
+#line 2759 "camp.tab.c"
break;
- case 155:
-#line 539 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new selfExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
-#line 2895 "camp.tab.c" /* yacc.c:1648 */
+ case 155: /* exp: exp SELFOP exp */
+#line 539 "camp.y"
+ { (yyval.e) = new selfExp((yyvsp[-1].ps).pos, (yyvsp[-2].e), (yyvsp[-1].ps).sym, (yyvsp[0].e)); }
+#line 2765 "camp.tab.c"
break;
- case 156:
-#line 541 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new quoteExp((yyvsp[-3].pos), (yyvsp[-1].b)); }
-#line 2901 "camp.tab.c" /* yacc.c:1648 */
+ case 156: /* exp: QUOTE '{' fileblock '}' */
+#line 541 "camp.y"
+ { (yyval.e) = new quoteExp((yyvsp[-3].pos), (yyvsp[-1].b)); }
+#line 2771 "camp.tab.c"
break;
- case 157:
-#line 547 "camp.y" /* yacc.c:1648 */
- { (yyval.j) = new joinExp((yyvsp[0].ps).pos,(yyvsp[0].ps).sym); }
-#line 2907 "camp.tab.c" /* yacc.c:1648 */
+ case 157: /* join: DASHES */
+#line 547 "camp.y"
+ { (yyval.j) = new joinExp((yyvsp[0].ps).pos,(yyvsp[0].ps).sym); }
+#line 2777 "camp.tab.c"
break;
- case 158:
-#line 549 "camp.y" /* yacc.c:1648 */
- { (yyval.j) = (yyvsp[0].j); }
-#line 2913 "camp.tab.c" /* yacc.c:1648 */
+ case 158: /* join: basicjoin */
+#line 549 "camp.y"
+ { (yyval.j) = (yyvsp[0].j); }
+#line 2783 "camp.tab.c"
break;
- case 159:
-#line 551 "camp.y" /* yacc.c:1648 */
- { (yyvsp[-1].se)->setSide(camp::OUT);
+ case 159: /* join: dir basicjoin */
+#line 551 "camp.y"
+ { (yyvsp[-1].se)->setSide(camp::OUT);
(yyval.j) = (yyvsp[0].j); (yyval.j)->pushFront((yyvsp[-1].se)); }
-#line 2920 "camp.tab.c" /* yacc.c:1648 */
+#line 2790 "camp.tab.c"
break;
- case 160:
-#line 554 "camp.y" /* yacc.c:1648 */
- { (yyvsp[0].se)->setSide(camp::IN);
+ case 160: /* join: basicjoin dir */
+#line 554 "camp.y"
+ { (yyvsp[0].se)->setSide(camp::IN);
(yyval.j) = (yyvsp[-1].j); (yyval.j)->pushBack((yyvsp[0].se)); }
-#line 2927 "camp.tab.c" /* yacc.c:1648 */
+#line 2797 "camp.tab.c"
break;
- case 161:
-#line 557 "camp.y" /* yacc.c:1648 */
- { (yyvsp[-2].se)->setSide(camp::OUT); (yyvsp[0].se)->setSide(camp::IN);
+ case 161: /* join: dir basicjoin dir */
+#line 557 "camp.y"
+ { (yyvsp[-2].se)->setSide(camp::OUT); (yyvsp[0].se)->setSide(camp::IN);
(yyval.j) = (yyvsp[-1].j); (yyval.j)->pushFront((yyvsp[-2].se)); (yyval.j)->pushBack((yyvsp[0].se)); }
-#line 2934 "camp.tab.c" /* yacc.c:1648 */
+#line 2804 "camp.tab.c"
break;
- case 162:
-#line 562 "camp.y" /* yacc.c:1648 */
- { (yyval.se) = new specExp((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym, (yyvsp[-1].e)); }
-#line 2940 "camp.tab.c" /* yacc.c:1648 */
+ case 162: /* dir: '{' CURL exp '}' */
+#line 562 "camp.y"
+ { (yyval.se) = new specExp((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym, (yyvsp[-1].e)); }
+#line 2810 "camp.tab.c"
break;
- case 163:
-#line 563 "camp.y" /* yacc.c:1648 */
- { (yyval.se) = new specExp((yyvsp[-2].pos), symbol::opTrans("spec"), (yyvsp[-1].e)); }
-#line 2946 "camp.tab.c" /* yacc.c:1648 */
+ case 163: /* dir: '{' exp '}' */
+#line 563 "camp.y"
+ { (yyval.se) = new specExp((yyvsp[-2].pos), symbol::opTrans("spec"), (yyvsp[-1].e)); }
+#line 2816 "camp.tab.c"
break;
- case 164:
-#line 565 "camp.y" /* yacc.c:1648 */
- { (yyval.se) = new specExp((yyvsp[-4].pos), symbol::opTrans("spec"),
+ case 164: /* dir: '{' exp ',' exp '}' */
+#line 565 "camp.y"
+ { (yyval.se) = new specExp((yyvsp[-4].pos), symbol::opTrans("spec"),
new pairExp((yyvsp[-2].pos), (yyvsp[-3].e), (yyvsp[-1].e))); }
-#line 2953 "camp.tab.c" /* yacc.c:1648 */
+#line 2823 "camp.tab.c"
break;
- case 165:
-#line 568 "camp.y" /* yacc.c:1648 */
- { (yyval.se) = new specExp((yyvsp[-6].pos), symbol::opTrans("spec"),
+ case 165: /* dir: '{' exp ',' exp ',' exp '}' */
+#line 568 "camp.y"
+ { (yyval.se) = new specExp((yyvsp[-6].pos), symbol::opTrans("spec"),
new tripleExp((yyvsp[-4].pos), (yyvsp[-5].e), (yyvsp[-3].e), (yyvsp[-1].e))); }
-#line 2960 "camp.tab.c" /* yacc.c:1648 */
+#line 2830 "camp.tab.c"
break;
- case 166:
-#line 573 "camp.y" /* yacc.c:1648 */
- { (yyval.j) = new joinExp((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
-#line 2966 "camp.tab.c" /* yacc.c:1648 */
+ case 166: /* basicjoin: DOTS */
+#line 573 "camp.y"
+ { (yyval.j) = new joinExp((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
+#line 2836 "camp.tab.c"
break;
- case 167:
-#line 575 "camp.y" /* yacc.c:1648 */
- { (yyval.j) = new joinExp((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym); (yyval.j)->pushBack((yyvsp[-1].e)); }
-#line 2972 "camp.tab.c" /* yacc.c:1648 */
+ case 167: /* basicjoin: DOTS tension DOTS */
+#line 575 "camp.y"
+ { (yyval.j) = new joinExp((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym); (yyval.j)->pushBack((yyvsp[-1].e)); }
+#line 2842 "camp.tab.c"
break;
- case 168:
-#line 577 "camp.y" /* yacc.c:1648 */
- { (yyval.j) = new joinExp((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym); (yyval.j)->pushBack((yyvsp[-1].e)); }
-#line 2978 "camp.tab.c" /* yacc.c:1648 */
+ case 168: /* basicjoin: DOTS controls DOTS */
+#line 577 "camp.y"
+ { (yyval.j) = new joinExp((yyvsp[-2].ps).pos, (yyvsp[-2].ps).sym); (yyval.j)->pushBack((yyvsp[-1].e)); }
+#line 2848 "camp.tab.c"
break;
- case 169:
-#line 578 "camp.y" /* yacc.c:1648 */
- { (yyval.j) = new joinExp((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
-#line 2984 "camp.tab.c" /* yacc.c:1648 */
+ case 169: /* basicjoin: COLONS */
+#line 578 "camp.y"
+ { (yyval.j) = new joinExp((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
+#line 2854 "camp.tab.c"
break;
- case 170:
-#line 579 "camp.y" /* yacc.c:1648 */
- { (yyval.j) = new joinExp((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
-#line 2990 "camp.tab.c" /* yacc.c:1648 */
+ case 170: /* basicjoin: LONGDASH */
+#line 579 "camp.y"
+ { (yyval.j) = new joinExp((yyvsp[0].ps).pos, (yyvsp[0].ps).sym); }
+#line 2860 "camp.tab.c"
break;
- case 171:
-#line 583 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym,
+ case 171: /* tension: TENSION exp */
+#line 583 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym,
new booleanExp((yyvsp[-1].ps).pos, false)); }
-#line 2997 "camp.tab.c" /* yacc.c:1648 */
+#line 2867 "camp.tab.c"
break;
- case 172:
-#line 586 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new ternaryExp((yyvsp[-3].ps).pos, (yyvsp[-2].e), (yyvsp[-3].ps).sym, (yyvsp[0].e),
+ case 172: /* tension: TENSION exp AND exp */
+#line 586 "camp.y"
+ { (yyval.e) = new ternaryExp((yyvsp[-3].ps).pos, (yyvsp[-2].e), (yyvsp[-3].ps).sym, (yyvsp[0].e),
new booleanExp((yyvsp[-3].ps).pos, false)); }
-#line 3004 "camp.tab.c" /* yacc.c:1648 */
+#line 2874 "camp.tab.c"
break;
- case 173:
-#line 589 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-2].ps).pos, (yyvsp[0].e), (yyvsp[-2].ps).sym,
+ case 173: /* tension: TENSION ATLEAST exp */
+#line 589 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-2].ps).pos, (yyvsp[0].e), (yyvsp[-2].ps).sym,
new booleanExp((yyvsp[-1].ps).pos, true)); }
-#line 3011 "camp.tab.c" /* yacc.c:1648 */
+#line 2881 "camp.tab.c"
break;
- case 174:
-#line 592 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new ternaryExp((yyvsp[-4].ps).pos, (yyvsp[-2].e), (yyvsp[-4].ps).sym, (yyvsp[0].e),
+ case 174: /* tension: TENSION ATLEAST exp AND exp */
+#line 592 "camp.y"
+ { (yyval.e) = new ternaryExp((yyvsp[-4].ps).pos, (yyvsp[-2].e), (yyvsp[-4].ps).sym, (yyvsp[0].e),
new booleanExp((yyvsp[-3].ps).pos, true)); }
-#line 3018 "camp.tab.c" /* yacc.c:1648 */
+#line 2888 "camp.tab.c"
break;
- case 175:
-#line 597 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new unaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym); }
-#line 3024 "camp.tab.c" /* yacc.c:1648 */
+ case 175: /* controls: CONTROLS exp */
+#line 597 "camp.y"
+ { (yyval.e) = new unaryExp((yyvsp[-1].ps).pos, (yyvsp[0].e), (yyvsp[-1].ps).sym); }
+#line 2894 "camp.tab.c"
break;
- case 176:
-#line 599 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = new binaryExp((yyvsp[-3].ps).pos, (yyvsp[-2].e), (yyvsp[-3].ps).sym, (yyvsp[0].e)); }
-#line 3030 "camp.tab.c" /* yacc.c:1648 */
+ case 176: /* controls: CONTROLS exp AND exp */
+#line 599 "camp.y"
+ { (yyval.e) = new binaryExp((yyvsp[-3].ps).pos, (yyvsp[-2].e), (yyvsp[-3].ps).sym, (yyvsp[0].e)); }
+#line 2900 "camp.tab.c"
break;
- case 177:
-#line 603 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = new emptyStm((yyvsp[0].pos)); }
-#line 3036 "camp.tab.c" /* yacc.c:1648 */
+ case 177: /* stm: ';' */
+#line 603 "camp.y"
+ { (yyval.s) = new emptyStm((yyvsp[0].pos)); }
+#line 2906 "camp.tab.c"
break;
- case 178:
-#line 604 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = (yyvsp[0].s); }
-#line 3042 "camp.tab.c" /* yacc.c:1648 */
+ case 178: /* stm: blockstm */
+#line 604 "camp.y"
+ { (yyval.s) = (yyvsp[0].s); }
+#line 2912 "camp.tab.c"
break;
- case 179:
-#line 605 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = (yyvsp[-1].s); }
-#line 3048 "camp.tab.c" /* yacc.c:1648 */
+ case 179: /* stm: stmexp ';' */
+#line 605 "camp.y"
+ { (yyval.s) = (yyvsp[-1].s); }
+#line 2918 "camp.tab.c"
break;
- case 180:
-#line 607 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = new ifStm((yyvsp[-4].pos), (yyvsp[-2].e), (yyvsp[0].s)); }
-#line 3054 "camp.tab.c" /* yacc.c:1648 */
+ case 180: /* stm: IF '(' exp ')' stm */
+#line 607 "camp.y"
+ { (yyval.s) = new ifStm((yyvsp[-4].pos), (yyvsp[-2].e), (yyvsp[0].s)); }
+#line 2924 "camp.tab.c"
break;
- case 181:
-#line 609 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = new ifStm((yyvsp[-6].pos), (yyvsp[-4].e), (yyvsp[-2].s), (yyvsp[0].s)); }
-#line 3060 "camp.tab.c" /* yacc.c:1648 */
+ case 181: /* stm: IF '(' exp ')' stm ELSE stm */
+#line 609 "camp.y"
+ { (yyval.s) = new ifStm((yyvsp[-6].pos), (yyvsp[-4].e), (yyvsp[-2].s), (yyvsp[0].s)); }
+#line 2930 "camp.tab.c"
break;
- case 182:
-#line 611 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = new whileStm((yyvsp[-4].pos), (yyvsp[-2].e), (yyvsp[0].s)); }
-#line 3066 "camp.tab.c" /* yacc.c:1648 */
+ case 182: /* stm: WHILE '(' exp ')' stm */
+#line 611 "camp.y"
+ { (yyval.s) = new whileStm((yyvsp[-4].pos), (yyvsp[-2].e), (yyvsp[0].s)); }
+#line 2936 "camp.tab.c"
break;
- case 183:
-#line 613 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = new doStm((yyvsp[-6].pos), (yyvsp[-5].s), (yyvsp[-2].e)); }
-#line 3072 "camp.tab.c" /* yacc.c:1648 */
+ case 183: /* stm: DO stm WHILE '(' exp ')' ';' */
+#line 613 "camp.y"
+ { (yyval.s) = new doStm((yyvsp[-6].pos), (yyvsp[-5].s), (yyvsp[-2].e)); }
+#line 2942 "camp.tab.c"
break;
- case 184:
-#line 615 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = new forStm((yyvsp[-8].pos), (yyvsp[-6].run), (yyvsp[-4].e), (yyvsp[-2].sel), (yyvsp[0].s)); }
-#line 3078 "camp.tab.c" /* yacc.c:1648 */
+ case 184: /* stm: FOR '(' forinit ';' fortest ';' forupdate ')' stm */
+#line 615 "camp.y"
+ { (yyval.s) = new forStm((yyvsp[-8].pos), (yyvsp[-6].run), (yyvsp[-4].e), (yyvsp[-2].sel), (yyvsp[0].s)); }
+#line 2948 "camp.tab.c"
break;
- case 185:
-#line 617 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = new extendedForStm((yyvsp[-7].pos), (yyvsp[-5].t), (yyvsp[-4].ps).sym, (yyvsp[-2].e), (yyvsp[0].s)); }
-#line 3084 "camp.tab.c" /* yacc.c:1648 */
+ case 185: /* stm: FOR '(' type ID ':' exp ')' stm */
+#line 617 "camp.y"
+ { (yyval.s) = new extendedForStm((yyvsp[-7].pos), (yyvsp[-5].t), (yyvsp[-4].ps).sym, (yyvsp[-2].e), (yyvsp[0].s)); }
+#line 2954 "camp.tab.c"
break;
- case 186:
-#line 618 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = new breakStm((yyvsp[-1].pos)); }
-#line 3090 "camp.tab.c" /* yacc.c:1648 */
+ case 186: /* stm: BREAK ';' */
+#line 618 "camp.y"
+ { (yyval.s) = new breakStm((yyvsp[-1].pos)); }
+#line 2960 "camp.tab.c"
break;
- case 187:
-#line 619 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = new continueStm((yyvsp[-1].pos)); }
-#line 3096 "camp.tab.c" /* yacc.c:1648 */
+ case 187: /* stm: CONTINUE ';' */
+#line 619 "camp.y"
+ { (yyval.s) = new continueStm((yyvsp[-1].pos)); }
+#line 2966 "camp.tab.c"
break;
- case 188:
-#line 620 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = new returnStm((yyvsp[-1].pos)); }
-#line 3102 "camp.tab.c" /* yacc.c:1648 */
+ case 188: /* stm: RETURN_ ';' */
+#line 620 "camp.y"
+ { (yyval.s) = new returnStm((yyvsp[-1].pos)); }
+#line 2972 "camp.tab.c"
break;
- case 189:
-#line 621 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = new returnStm((yyvsp[-2].pos), (yyvsp[-1].e)); }
-#line 3108 "camp.tab.c" /* yacc.c:1648 */
+ case 189: /* stm: RETURN_ exp ';' */
+#line 621 "camp.y"
+ { (yyval.s) = new returnStm((yyvsp[-2].pos), (yyvsp[-1].e)); }
+#line 2978 "camp.tab.c"
break;
- case 190:
-#line 625 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = new expStm((yyvsp[0].e)->getPos(), (yyvsp[0].e)); }
-#line 3114 "camp.tab.c" /* yacc.c:1648 */
+ case 190: /* stmexp: exp */
+#line 625 "camp.y"
+ { (yyval.s) = new expStm((yyvsp[0].e)->getPos(), (yyvsp[0].e)); }
+#line 2984 "camp.tab.c"
break;
- case 191:
-#line 629 "camp.y" /* yacc.c:1648 */
- { (yyval.s) = new blockStm((yyvsp[0].b)->getPos(), (yyvsp[0].b)); }
-#line 3120 "camp.tab.c" /* yacc.c:1648 */
+ case 191: /* blockstm: block */
+#line 629 "camp.y"
+ { (yyval.s) = new blockStm((yyvsp[0].b)->getPos(), (yyvsp[0].b)); }
+#line 2990 "camp.tab.c"
break;
- case 192:
-#line 633 "camp.y" /* yacc.c:1648 */
- { (yyval.run) = 0; }
-#line 3126 "camp.tab.c" /* yacc.c:1648 */
+ case 192: /* forinit: %empty */
+#line 633 "camp.y"
+ { (yyval.run) = 0; }
+#line 2996 "camp.tab.c"
break;
- case 193:
-#line 634 "camp.y" /* yacc.c:1648 */
- { (yyval.run) = (yyvsp[0].sel); }
-#line 3132 "camp.tab.c" /* yacc.c:1648 */
+ case 193: /* forinit: stmexplist */
+#line 634 "camp.y"
+ { (yyval.run) = (yyvsp[0].sel); }
+#line 3002 "camp.tab.c"
break;
- case 194:
-#line 635 "camp.y" /* yacc.c:1648 */
- { (yyval.run) = (yyvsp[0].vd); }
-#line 3138 "camp.tab.c" /* yacc.c:1648 */
+ case 194: /* forinit: barevardec */
+#line 635 "camp.y"
+ { (yyval.run) = (yyvsp[0].vd); }
+#line 3008 "camp.tab.c"
break;
- case 195:
-#line 639 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = 0; }
-#line 3144 "camp.tab.c" /* yacc.c:1648 */
+ case 195: /* fortest: %empty */
+#line 639 "camp.y"
+ { (yyval.e) = 0; }
+#line 3014 "camp.tab.c"
break;
- case 196:
-#line 640 "camp.y" /* yacc.c:1648 */
- { (yyval.e) = (yyvsp[0].e); }
-#line 3150 "camp.tab.c" /* yacc.c:1648 */
+ case 196: /* fortest: exp */
+#line 640 "camp.y"
+ { (yyval.e) = (yyvsp[0].e); }
+#line 3020 "camp.tab.c"
break;
- case 197:
-#line 644 "camp.y" /* yacc.c:1648 */
- { (yyval.sel) = 0; }
-#line 3156 "camp.tab.c" /* yacc.c:1648 */
+ case 197: /* forupdate: %empty */
+#line 644 "camp.y"
+ { (yyval.sel) = 0; }
+#line 3026 "camp.tab.c"
break;
- case 198:
-#line 645 "camp.y" /* yacc.c:1648 */
- { (yyval.sel) = (yyvsp[0].sel); }
-#line 3162 "camp.tab.c" /* yacc.c:1648 */
+ case 198: /* forupdate: stmexplist */
+#line 645 "camp.y"
+ { (yyval.sel) = (yyvsp[0].sel); }
+#line 3032 "camp.tab.c"
break;
- case 199:
-#line 649 "camp.y" /* yacc.c:1648 */
- { (yyval.sel) = new stmExpList((yyvsp[0].s)->getPos()); (yyval.sel)->add((yyvsp[0].s)); }
-#line 3168 "camp.tab.c" /* yacc.c:1648 */
+ case 199: /* stmexplist: stmexp */
+#line 649 "camp.y"
+ { (yyval.sel) = new stmExpList((yyvsp[0].s)->getPos()); (yyval.sel)->add((yyvsp[0].s)); }
+#line 3038 "camp.tab.c"
break;
- case 200:
-#line 651 "camp.y" /* yacc.c:1648 */
- { (yyval.sel) = (yyvsp[-2].sel); (yyval.sel)->add((yyvsp[0].s)); }
-#line 3174 "camp.tab.c" /* yacc.c:1648 */
+ case 200: /* stmexplist: stmexplist ',' stmexp */
+#line 651 "camp.y"
+ { (yyval.sel) = (yyvsp[-2].sel); (yyval.sel)->add((yyvsp[0].s)); }
+#line 3044 "camp.tab.c"
break;
-#line 3178 "camp.tab.c" /* yacc.c:1648 */
+#line 3048 "camp.tab.c"
+
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -3188,25 +3059,23 @@ yyreduce:
case of YYERROR or YYBACKUP, subsequent parser actions might lead
to an incorrect destructor call or verbose syntax error message
before the lookahead is translated. */
- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+ YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
YYPOPSTACK (yylen);
yylen = 0;
- YY_STACK_PRINT (yyss, yyssp);
*++yyvsp = yyval;
/* Now 'shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTOKENS];
+ {
+ const int yylhs = yyr1[yyn] - YYNTOKENS;
+ const int yyi = yypgoto[yylhs] + *yyssp;
+ yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+ ? yytable[yyi]
+ : yydefgoto[yylhs]);
+ }
goto yynewstate;
@@ -3217,50 +3086,14 @@ yyreduce:
yyerrlab:
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
- yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
+ yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar);
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
++yynerrs;
-#if ! YYERROR_VERBOSE
yyerror (YY_("syntax error"));
-#else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
- yyssp, yytoken)
- {
- char const *yymsgp = YY_("syntax error");
- int yysyntax_error_status;
- yysyntax_error_status = YYSYNTAX_ERROR;
- if (yysyntax_error_status == 0)
- yymsgp = yymsg;
- else if (yysyntax_error_status == 1)
- {
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
- if (!yymsg)
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- yysyntax_error_status = 2;
- }
- else
- {
- yysyntax_error_status = YYSYNTAX_ERROR;
- yymsgp = yymsg;
- }
- }
- yyerror (yymsgp);
- if (yysyntax_error_status == 2)
- goto yyexhaustedlab;
- }
-# undef YYSYNTAX_ERROR
-#endif
}
-
-
if (yyerrstatus == 3)
{
/* If just tried and failed to reuse lookahead token after an
@@ -3289,12 +3122,10 @@ yyerrlab:
| yyerrorlab -- error raised explicitly by YYERROR. |
`---------------------------------------------------*/
yyerrorlab:
-
- /* Pacify compilers like GCC when the user code never invokes
- YYERROR and the label yyerrorlab therefore never appears in user
- code. */
- if (/*CONSTCOND*/ 0)
- goto yyerrorlab;
+ /* Pacify compilers when the user code never invokes YYERROR and the
+ label yyerrorlab therefore never appears in user code. */
+ if (0)
+ YYERROR;
/* Do not reclaim the symbols of the rule whose action triggered
this YYERROR. */
@@ -3311,13 +3142,14 @@ yyerrorlab:
yyerrlab1:
yyerrstatus = 3; /* Each real token shifted decrements this. */
+ /* Pop stack until we find a state that shifts the error token. */
for (;;)
{
yyn = yypact[yystate];
if (!yypact_value_is_default (yyn))
{
- yyn += YYTERROR;
- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ yyn += YYSYMBOL_YYerror;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
{
yyn = yytable[yyn];
if (0 < yyn)
@@ -3331,7 +3163,7 @@ yyerrlab1:
yydestruct ("Error: popping",
- yystos[yystate], yyvsp);
+ YY_ACCESSING_SYMBOL (yystate), yyvsp);
YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
@@ -3343,7 +3175,7 @@ yyerrlab1:
/* Shift the error token. */
- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+ YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp);
yystate = yyn;
goto yynewstate;
@@ -3356,6 +3188,7 @@ yyacceptlab:
yyresult = 0;
goto yyreturn;
+
/*-----------------------------------.
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
@@ -3363,16 +3196,21 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
-#if !defined yyoverflow || YYERROR_VERBOSE
+
+#if !defined yyoverflow
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
yyexhaustedlab:
yyerror (YY_("memory exhausted"));
yyresult = 2;
- /* Fall through. */
+ goto yyreturn;
#endif
+
+/*-------------------------------------------------------.
+| yyreturn -- parsing is finished, clean up and return. |
+`-------------------------------------------------------*/
yyreturn:
if (yychar != YYEMPTY)
{
@@ -3389,16 +3227,14 @@ yyreturn:
while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp);
+ YY_ACCESSING_SYMBOL (+*yyssp), yyvsp);
YYPOPSTACK (1);
}
#ifndef yyoverflow
if (yyss != yyssa)
YYSTACK_FREE (yyss);
#endif
-#if YYERROR_VERBOSE
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
-#endif
+
return yyresult;
}
+
diff --git a/graphics/asymptote/camp.tab.h b/graphics/asymptote/camp.tab.h
index b3ffe25774..a0ab8a0dc7 100644
--- a/graphics/asymptote/camp.tab.h
+++ b/graphics/asymptote/camp.tab.h
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.5. */
+/* A Bison parser, made by GNU Bison 3.7.4. */
/* Bison interface for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
+ Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,6 +31,10 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
+/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+ especially those whose name start with YY_ or yy_. They are
+ private implementation details that can be changed or removed. */
+
#ifndef YY_YY_CAMP_TAB_H_INCLUDED
# define YY_YY_CAMP_TAB_H_INCLUDED
/* Debug traces. */
@@ -40,75 +45,79 @@
extern int yydebug;
#endif
-/* Token type. */
+/* Token kinds. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
- ID = 258,
- SELFOP = 259,
- DOTS = 260,
- COLONS = 261,
- DASHES = 262,
- INCR = 263,
- LONGDASH = 264,
- CONTROLS = 265,
- TENSION = 266,
- ATLEAST = 267,
- CURL = 268,
- COR = 269,
- CAND = 270,
- BAR = 271,
- AMPERSAND = 272,
- EQ = 273,
- NEQ = 274,
- LT = 275,
- LE = 276,
- GT = 277,
- GE = 278,
- CARETS = 279,
- OPERATOR = 280,
- LOOSE = 281,
- ASSIGN = 282,
- DIRTAG = 283,
- JOIN_PREC = 284,
- AND = 285,
- ELLIPSIS = 286,
- ACCESS = 287,
- UNRAVEL = 288,
- IMPORT = 289,
- INCLUDE = 290,
- FROM = 291,
- QUOTE = 292,
- STRUCT = 293,
- TYPEDEF = 294,
- NEW = 295,
- IF = 296,
- ELSE = 297,
- WHILE = 298,
- DO = 299,
- FOR = 300,
- BREAK = 301,
- CONTINUE = 302,
- RETURN_ = 303,
- THIS = 304,
- EXPLICIT = 305,
- GARBAGE = 306,
- LIT = 307,
- STRING = 308,
- PERM = 309,
- MODIFIER = 310,
- UNARY = 311,
- EXP_IN_PARENS_RULE = 312
+ YYEMPTY = -2,
+ YYEOF = 0, /* "end of file" */
+ YYerror = 256, /* error */
+ YYUNDEF = 257, /* "invalid token" */
+ ID = 258, /* ID */
+ SELFOP = 259, /* SELFOP */
+ DOTS = 260, /* DOTS */
+ COLONS = 261, /* COLONS */
+ DASHES = 262, /* DASHES */
+ INCR = 263, /* INCR */
+ LONGDASH = 264, /* LONGDASH */
+ CONTROLS = 265, /* CONTROLS */
+ TENSION = 266, /* TENSION */
+ ATLEAST = 267, /* ATLEAST */
+ CURL = 268, /* CURL */
+ COR = 269, /* COR */
+ CAND = 270, /* CAND */
+ BAR = 271, /* BAR */
+ AMPERSAND = 272, /* AMPERSAND */
+ EQ = 273, /* EQ */
+ NEQ = 274, /* NEQ */
+ LT = 275, /* LT */
+ LE = 276, /* LE */
+ GT = 277, /* GT */
+ GE = 278, /* GE */
+ CARETS = 279, /* CARETS */
+ OPERATOR = 280, /* OPERATOR */
+ LOOSE = 281, /* LOOSE */
+ ASSIGN = 282, /* ASSIGN */
+ DIRTAG = 283, /* DIRTAG */
+ JOIN_PREC = 284, /* JOIN_PREC */
+ AND = 285, /* AND */
+ ELLIPSIS = 286, /* ELLIPSIS */
+ ACCESS = 287, /* ACCESS */
+ UNRAVEL = 288, /* UNRAVEL */
+ IMPORT = 289, /* IMPORT */
+ INCLUDE = 290, /* INCLUDE */
+ FROM = 291, /* FROM */
+ QUOTE = 292, /* QUOTE */
+ STRUCT = 293, /* STRUCT */
+ TYPEDEF = 294, /* TYPEDEF */
+ NEW = 295, /* NEW */
+ IF = 296, /* IF */
+ ELSE = 297, /* ELSE */
+ WHILE = 298, /* WHILE */
+ DO = 299, /* DO */
+ FOR = 300, /* FOR */
+ BREAK = 301, /* BREAK */
+ CONTINUE = 302, /* CONTINUE */
+ RETURN_ = 303, /* RETURN_ */
+ THIS = 304, /* THIS */
+ EXPLICIT = 305, /* EXPLICIT */
+ GARBAGE = 306, /* GARBAGE */
+ LIT = 307, /* LIT */
+ STRING = 308, /* STRING */
+ PERM = 309, /* PERM */
+ MODIFIER = 310, /* MODIFIER */
+ UNARY = 311, /* UNARY */
+ EXP_IN_PARENS_RULE = 312 /* EXP_IN_PARENS_RULE */
};
+ typedef enum yytokentype yytoken_kind_t;
#endif
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
union YYSTYPE
{
-#line 60 "camp.y" /* yacc.c:1910 */
+#line 60 "camp.y"
position pos;
bool boo;
@@ -155,9 +164,9 @@ union YYSTYPE
absyntax::formal *fl;
absyntax::formals *fls;
-#line 159 "camp.tab.h" /* yacc.c:1910 */
-};
+#line 168 "camp.tab.h"
+};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
diff --git a/graphics/asymptote/camperror.cc b/graphics/asymptote/camperror.cc
index 8b36310a47..f124e85d78 100644
--- a/graphics/asymptote/camperror.cc
+++ b/graphics/asymptote/camperror.cc
@@ -42,7 +42,7 @@ void reportFatal(const string& desc)
em.statusError();
try {
throw quit();
- } catch(handled_error) {
+ } catch(handled_error const&) {
}
}
diff --git a/graphics/asymptote/common.h b/graphics/asymptote/common.h
index 80dfef8ac3..50f397c7e3 100644
--- a/graphics/asymptote/common.h
+++ b/graphics/asymptote/common.h
@@ -10,12 +10,27 @@
#undef NDEBUG
#include <iostream>
+#include <memory>
#include <climits>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#ifdef HAVE_LSP
+#include <boost/optional.hpp>
+#include <boost/none.hpp>
+using boost::optional;
+using boost::make_optional;
+#else
+#include "optional.hpp"
+#define boost nonstd
+using nonstd::optional;
+using nonstd::nullopt;
+#endif
+
+using std::make_pair;
+
#if !defined(FOR_SHARED) && \
((defined(HAVE_LIBGL) && defined(HAVE_LIBGLUT) && defined(HAVE_LIBGLM)) || \
defined(HAVE_LIBOSMESA))
@@ -88,6 +103,10 @@ using mem::istringstream;
using mem::ostringstream;
using mem::stringbuf;
+using std::shared_ptr;
+using std::unique_ptr;
+using std::make_shared;
+
static const struct ws_t {} ws={};
// Portable way of skipping whitespace
diff --git a/graphics/asymptote/config.h.in b/graphics/asymptote/config.h.in
index c6b6c524e7..52c23ede51 100644
--- a/graphics/asymptote/config.h.in
+++ b/graphics/asymptote/config.h.in
@@ -9,6 +9,9 @@
/* System directory for global .asy files */
#undef ASYMPTOTE_SYSDIR
+/* Define to 1 if you have GLSL compute shaders. */
+#undef HAVE_COMPUTE_SHADER
+
/* Define to 1 if you have the <curses.h> header file. */
#undef HAVE_CURSES_H
@@ -105,6 +108,9 @@
/* Define to 1 if the system has the type `long long'. */
#undef HAVE_LONG_LONG
+/* Define to 1 if you have Language server protocol. */
+#undef HAVE_LSP
+
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
@@ -135,6 +141,9 @@
/* Define to 1 if you have a working <tirpc/rpc/rpc.h> header. */
#undef HAVE_RPC_RPC_H
+/* Define to 1 if you have GLSL shader storage buffer objects. */
+#undef HAVE_SSBO
+
/* Define to 1 if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
@@ -214,9 +223,6 @@
your system. */
#undef PTHREAD_CREATE_JOINABLE
-/* Define as the return type of signal handlers (`int' or `void'). */
-#undef RETSIGTYPE
-
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
diff --git a/graphics/asymptote/configure b/graphics/asymptote/configure
index 903b9a9ed1..1473361be0 100755
--- a/graphics/asymptote/configure
+++ b/graphics/asymptote/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Asymptote 2.70.
+# Generated by GNU Autoconf 2.69 for Asymptote 2.72.
#
# Report bugs to <https://sourceforge.net/projects/asymptote>.
#
@@ -580,8 +580,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='Asymptote'
PACKAGE_TARNAME='asymptote'
-PACKAGE_VERSION='2.70'
-PACKAGE_STRING='Asymptote 2.70'
+PACKAGE_VERSION='2.72'
+PACKAGE_STRING='Asymptote 2.72'
PACKAGE_BUGREPORT='https://sourceforge.net/projects/asymptote'
PACKAGE_URL=''
@@ -631,6 +631,8 @@ ax_pthread_config
GLEW
OPTIONS
INCL
+LSPLIBS
+LSPLIB
GCPPLIB
GCLIB
GCOPTIONS
@@ -694,6 +696,7 @@ infodir
docdir
oldincludedir
includedir
+runstatedir
localstatedir
sharedstatedir
sysconfdir
@@ -716,6 +719,7 @@ SHELL'
ac_subst_files=''
ac_user_opts='
enable_option_checking
+enable_lsp
with_latex
with_context
with_docdir
@@ -786,6 +790,7 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1038,6 +1043,15 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
+ -runstatedir | --runstatedir | --runstatedi | --runstated \
+ | --runstate | --runstat | --runsta | --runst | --runs \
+ | --run | --ru | --r)
+ ac_prev=runstatedir ;;
+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+ | --run=* | --ru=* | --r=*)
+ runstatedir=$ac_optarg ;;
+
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1175,7 +1189,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
+ libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@@ -1288,7 +1302,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures Asymptote 2.70 to adapt to many kinds of systems.
+\`configure' configures Asymptote 2.72 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1328,6 +1342,7 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@@ -1353,7 +1368,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of Asymptote 2.70:";;
+ short | recursive ) echo "Configuration of Asymptote 2.72:";;
esac
cat <<\_ACEOF
@@ -1361,6 +1376,7 @@ Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-lsp[=yes] enable Language Server Protocol
--enable-texlive-build automatically determine sysdir from kpsewhich
--enable-gc[=system] enable system Boehm garbage collector
[=VERSION] enable local VERSION of Boehm garbage collector
@@ -1470,7 +1486,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-Asymptote configure 2.70
+Asymptote configure 2.72
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2056,7 +2072,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by Asymptote $as_me 2.70, which was
+It was created by Asymptote $as_me 2.72, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2513,10 +2529,6 @@ VERSION=$PACKAGE_VERSION
-test "$CXXFLAGS" || CXXFLAGS="-std=c++11"
-
-test "$CFLAGS" || CFLAGS="-g -O3"
-
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -4035,6 +4047,24 @@ test "$Datadir" = '${datarootdir}' && Datadir=$datarootdir
test "$Datadir" = '${prefix}/share' && Datadir=$prefix/share
+# Check whether --enable-lsp was given.
+if test "${enable_lsp+set}" = set; then :
+ enableval=$enable_lsp;
+fi
+
+if test "x$enable_lsp" != "xno"; then
+cxxstd="c++14"
+else
+cxxstd="c++11"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: *** Language Server Protocol disabled by configure flag ***" >&5
+$as_echo "$as_me: *** Language Server Protocol disabled by configure flag ***" >&6;}
+fi
+
+test "$CXXFLAGS" || CXXFLAGS="-std=$cxxstd"
+echo Compiling with $CXXFLAGS
+
+test "$CFLAGS" || CFLAGS="-g -O3"
+
# Check whether --with-latex was given.
if test "${with_latex+set}" = set; then :
@@ -5867,10 +5897,10 @@ fi
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-ASYGLVERSION=1.00
+ASYGLVERSION=1.01
-GCVERSION=8.0.4
-ATOMICVERSION=7.6.10
+GCVERSION=8.2.0
+ATOMICVERSION=7.6.12
GCFILE=gc-$GCVERSION
ac_cv_use_gc="system"
@@ -6060,6 +6090,8 @@ fi
+
+
# Checks for libraries.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing lgamma" >&5
$as_echo_n "checking for library containing lgamma... " >&6; }
@@ -6722,6 +6754,100 @@ else
$as_echo "$as_me: *** libcurl support disabled by configure flag: will compile without optional URL support. ***" >&6;}
fi
+LSPLIBS=
+LSPLIB=
+if test "x$enable_lsp" != "xno"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for opendir in -lboost_filesystem" >&5
+$as_echo_n "checking for opendir in -lboost_filesystem... " >&6; }
+if ${ac_cv_lib_boost_filesystem_opendir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lboost_filesystem $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_boost_filesystem_opendir=yes
+else
+ ac_cv_lib_boost_filesystem_opendir=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_boost_filesystem_opendir" >&5
+$as_echo "$ac_cv_lib_boost_filesystem_opendir" >&6; }
+if test "x$ac_cv_lib_boost_filesystem_opendir" = xyes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_attr_getdetachstate in -lboost_thread" >&5
+$as_echo_n "checking for pthread_attr_getdetachstate in -lboost_thread... " >&6; }
+if ${ac_cv_lib_boost_thread_pthread_attr_getdetachstate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lboost_thread $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_attr_getdetachstate ();
+int
+main ()
+{
+return pthread_attr_getdetachstate ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_lib_boost_thread_pthread_attr_getdetachstate=yes
+else
+ ac_cv_lib_boost_thread_pthread_attr_getdetachstate=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_boost_thread_pthread_attr_getdetachstate" >&5
+$as_echo "$ac_cv_lib_boost_thread_pthread_attr_getdetachstate" >&6; }
+if test "x$ac_cv_lib_boost_thread_pthread_attr_getdetachstate" = xyes; then :
+
+$as_echo "#define HAVE_LSP 1" >>confdefs.h
+
+ LSPLIBS="-llspcpp -lboost_filesystem -lboost_thread "
+ LSPLIB=liblspcpp.a
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find libboost_thread: will compile without optional Language Server Protocol. ***" >&5
+$as_echo "$as_me: *** Could not find libboost_thread: will compile without optional Language Server Protocol. ***" >&6;}
+fi
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Could not find libboost_filesystem: will compile without optional Language Server Protocol. ***" >&5
+$as_echo "$as_me: *** Could not find libboost_filesystem: will compile without optional Language Server Protocol. ***" >&6;}
+fi
+
+fi
+
# Check whether --enable-readline was given.
if test "${enable_readline+set}" = set; then :
enableval=$enable_readline;
@@ -7734,6 +7860,50 @@ if test "${enable_gl+set}" = set; then :
fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <GL/gl.h>
+ #if !defined(GL_VERSION_4_3) && !defined(GL_ARB_shader_storage_buffer_object)
+ #error
+ #endif
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_SSBO 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <GL/gl.h>
+ #if !defined(GL_VERSION_4_3) && !defined(GL_ARB_compute_shader)
+ #error
+ #endif
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_COMPUTE_SHADER 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
# Check whether --enable-offscreen was given.
if test "${enable_offscreen+set}" = set; then :
enableval=$enable_offscreen;
@@ -8381,39 +8551,6 @@ _ACEOF
;;
esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
-$as_echo_n "checking return type of signal handlers... " >&6; }
-if ${ac_cv_type_signal+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <sys/types.h>
-#include <signal.h>
-
-int
-main ()
-{
-return *(signal (0, 0)) (0) == 1;
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
- ac_cv_type_signal=int
-else
- ac_cv_type_signal=void
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5
-$as_echo "$ac_cv_type_signal" >&6; }
-
-cat >>confdefs.h <<_ACEOF
-#define RETSIGTYPE $ac_cv_type_signal
-_ACEOF
-
-
@@ -9327,7 +9464,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by Asymptote $as_me 2.70, which was
+This file was extended by Asymptote $as_me 2.72, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -9389,7 +9526,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-Asymptote config.status 2.70
+Asymptote config.status 2.72
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/graphics/asymptote/configure.ac b/graphics/asymptote/configure.ac
index c866ce498d..e3d0f175ff 100644
--- a/graphics/asymptote/configure.ac
+++ b/graphics/asymptote/configure.ac
@@ -3,15 +3,11 @@
# this file.
AC_PREREQ(2)
-AC_INIT([Asymptote],[2.70],[https://sourceforge.net/projects/asymptote])
+AC_INIT([Asymptote],[2.72],[https://sourceforge.net/projects/asymptote])
VERSION=$PACKAGE_VERSION
AC_SUBST(VERSION)
m4_include([ax_pthread.m4])
-test "$CXXFLAGS" || CXXFLAGS="-std=c++11"
-
-test "$CFLAGS" || CFLAGS="-g -O3"
-
AC_C_BIGENDIAN
AC_CANONICAL_HOST
@@ -21,6 +17,20 @@ test "$Datadir" = '${datarootdir}' && Datadir=$datarootdir
test "$Datadir" = '${prefix}/share' && Datadir=$prefix/share
AC_SUBST(Datadir)
+AC_ARG_ENABLE(lsp,
+[AS_HELP_STRING(--enable-lsp[[[=yes]]],enable Language Server Protocol)])
+if test "x$enable_lsp" != "xno"; then
+cxxstd="c++14"
+else
+cxxstd="c++11"
+AC_MSG_NOTICE([*** Language Server Protocol disabled by configure flag ***])
+fi
+
+test "$CXXFLAGS" || CXXFLAGS="-std=$cxxstd"
+echo Compiling with $CXXFLAGS
+
+test "$CFLAGS" || CFLAGS="-g -O3"
+
AC_ARG_WITH(latex,
[AS_HELP_STRING(--with-latex=PATH,
specify path to LaTeX installation)],
@@ -99,7 +109,7 @@ AC_CONFIG_SRCDIR([absyn.cc])
AC_LANG([C++])
# Checks for programs.
-AC_PROG_LEX
+AC_PROG_LEX(noyywrap)
AC_PROG_CXX
AC_PROG_INSTALL
AC_PROG_CC
@@ -138,10 +148,10 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
DEFINE([<unordered_map>])),
[AC_CHECK_HEADER(ext/hash_map,,OPTIONS=$OPTIONS"-DNOHASH ")])])
-ASYGLVERSION=1.00
+ASYGLVERSION=1.01
-GCVERSION=8.0.4
-ATOMICVERSION=7.6.10
+GCVERSION=8.2.0
+ATOMICVERSION=7.6.12
GCFILE=gc-$GCVERSION
ac_cv_use_gc="system"
@@ -245,6 +255,8 @@ AC_SUBST(ATOMICVERSION)
AC_SUBST(GCOPTIONS)
AC_SUBST(GCLIB)
AC_SUBST(GCPPLIB)
+AC_SUBST(LSPLIB)
+AC_SUBST(LSPLIBS)
AC_SUBST(INCL)
AC_SUBST(OPTIONS)
AC_SUBST(GLEW)
@@ -274,6 +286,18 @@ else
AC_MSG_NOTICE([*** libcurl support disabled by configure flag: will compile without optional URL support. ***])
fi
+LSPLIBS=
+LSPLIB=
+if test "x$enable_lsp" != "xno"; then
+ AC_CHECK_LIB([boost_filesystem],[opendir],
+ [AC_CHECK_LIB([boost_thread],[pthread_attr_getdetachstate],
+ [AC_DEFINE(HAVE_LSP,1,DEFINE([Language server protocol]))
+ LSPLIBS="-llspcpp -lboost_filesystem -lboost_thread "
+ LSPLIB=liblspcpp.a],
+ AC_MSG_NOTICE([*** Could not find libboost_thread: will compile without optional Language Server Protocol. ***]))],
+ AC_MSG_NOTICE([*** Could not find libboost_filesystem: will compile without optional Language Server Protocol. ***]))
+fi
+
AC_ARG_ENABLE(readline,
[AS_HELP_STRING(--enable-readline[[[=yes]]],enable GNU Readline Library)])
@@ -376,6 +400,22 @@ fi
AC_ARG_ENABLE(gl,
[AS_HELP_STRING(--enable-gl[[[=yes]]],enable OpenGL Library)])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+ [#include <GL/gl.h>]
+ [#if !defined(GL_VERSION_4_3) && !defined(GL_ARB_shader_storage_buffer_object)]
+ [#error]
+ [#endif ]
+ )],
+ AC_DEFINE(HAVE_SSBO,1,DEFINE([GLSL shader storage buffer objects])))
+
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+ [#include <GL/gl.h>]
+ [#if !defined(GL_VERSION_4_3) && !defined(GL_ARB_compute_shader)]
+ [#error]
+ [#endif ]
+ )],
+ AC_DEFINE(HAVE_COMPUTE_SHADER,1,DEFINE([GLSL compute shaders])))
+
AC_ARG_ENABLE(offscreen,
[AS_HELP_STRING(--enable-offscreen[[[=no]]],use OSMesa library to implement offscreen rendering)])
@@ -447,7 +487,6 @@ AC_CHECK_TYPES([long long])
AC_CHECK_TYPES([long])
AC_C_CONST
AC_C_INLINE
-AC_TYPE_SIGNAL
AC_DEFUN([ac_FUNC_STRPTIME], [
AC_CHECK_FUNCS(strptime)
diff --git a/graphics/asymptote/constructor.cc b/graphics/asymptote/constructor.cc
index 68e9b803d5..b7ab7e1478 100644
--- a/graphics/asymptote/constructor.cc
+++ b/graphics/asymptote/constructor.cc
@@ -76,7 +76,7 @@ void transConstructorBody(position pos, coenv &e, record *r, varEntry *init)
v->encode(READ, pos, e.c);
// Call the 'operator init' field of the object.
- init->encode(CALL, pos, e.c, v->getLevel());
+ init->encode(action::CALL, pos, e.c, v->getLevel());
// Push the object again.
v->encode(READ, pos, e.c);
diff --git a/graphics/asymptote/cudareflect/EXRFiles.cc b/graphics/asymptote/cudareflect/EXRFiles.cc
new file mode 100644
index 0000000000..3d9060f79d
--- /dev/null
+++ b/graphics/asymptote/cudareflect/EXRFiles.cc
@@ -0,0 +1,104 @@
+#include "EXRFiles.h"
+
+EXRFile::EXRFile(std::string const& input)
+{
+ char const* err = nullptr;
+ if (LoadEXR(&flt, &width, &height, input.c_str(), &err) != TINYEXR_SUCCESS)
+ {
+ if (err)
+ {
+ std::cerr << "TinyEXR ERROR: " << err << std::endl;
+ FreeEXRErrorMessage(err);
+ exit(1);
+ }
+ }
+}
+
+OEXRFile::OEXRFile(std::vector<float3> const& dat, int width, int height, int compressionType) :
+ width(std::move(width)), height(std::move(height)),
+ compressionType(compressionType), infos(3)
+{
+ for (float3 const& col : dat)
+ {
+ r.push_back(col.x);
+ g.push_back(col.y);
+ b.push_back(col.z);
+ //a.push_back(col.w);
+ }
+
+ for (int i = 0; i < 3; ++i)
+ {
+ pixelType.push_back(TINYEXR_PIXELTYPE_FLOAT);
+ reqPixelType.push_back(TINYEXR_PIXELTYPE_FLOAT);
+ }
+
+ initChannelInfo();
+ initHeader();
+}
+
+OEXRFile::OEXRFile(std::vector<float2> const& dat, int width, int height, int compressionType) :
+ width(std::move(width)), height(std::move(height)),
+ compressionType(compressionType), infos(3)
+{
+ for (float2 const& col : dat)
+ {
+ r.push_back(col.x);
+ g.push_back(col.y);
+ b.push_back(0);
+ //a.push_back(col.w);
+ }
+
+ for (int i = 0; i < 3; ++i)
+ {
+ pixelType.push_back(TINYEXR_PIXELTYPE_FLOAT);
+ reqPixelType.push_back(TINYEXR_PIXELTYPE_FLOAT);
+ }
+
+ initChannelInfo();
+ initHeader();
+}
+
+void OEXRFile::initChannelInfo()
+{
+ infos.resize(4);
+ // strcpy(infos[0].name, "A");
+ strcpy(infos[0].name, "B");
+ strcpy(infos[1].name, "G");
+ strcpy(infos[2].name, "R");
+
+ for (auto& info : infos)
+ {
+ info.name[1] = '\0';
+ }
+}
+
+void OEXRFile::initHeader()
+{
+ InitEXRHeader(&hd);
+ hd.num_channels = 3;
+ hd.channels = infos.data();
+ hd.pixel_types = pixelType.data();
+ hd.requested_pixel_types = reqPixelType.data();
+ hd.compression_type = compressionType;
+}
+
+void OEXRFile::write(std::string const& filename)
+{
+ EXRImage im;
+ InitEXRImage(&im);
+ im.num_channels = 3;
+ im.width = width;
+ im.height = height;
+
+ std::array<float*, 3> arr{ b.data(), g.data(), r.data() };
+
+ im.images = reinterpret_cast<unsigned char**>(arr.data());
+
+ char const* err = nullptr;
+ if (SaveEXRImageToFile(&im, &hd, filename.c_str(), &err) != TINYEXR_SUCCESS)
+ {
+ std::cerr << "TinyEXR ERROR: " << err << std::endl;
+ FreeEXRErrorMessage(err);
+ exit(1);
+ }
+}
diff --git a/graphics/asymptote/cudareflect/EXRFiles.h b/graphics/asymptote/cudareflect/EXRFiles.h
new file mode 100644
index 0000000000..75a69cb6ab
--- /dev/null
+++ b/graphics/asymptote/cudareflect/EXRFiles.h
@@ -0,0 +1,71 @@
+#pragma once
+
+#include "common.h"
+#include <cuda_runtime.h>
+
+class EXRFile
+{
+public:
+ EXRFile(std::string const& input);
+
+ float const* getData() const
+ {
+ return flt;
+ }
+
+ ~EXRFile()
+ {
+ free(flt);
+ }
+
+ int getWidth() const
+ {
+ return width;
+ }
+
+ int getHeight() const
+ {
+ return height;
+ }
+
+ float4 getPixel4(size_t const& x, size_t const& y)
+ {
+ size_t base = 4 * (y * width + x);
+ return make_float4(flt[base], flt[base + 1], flt[base + 2], flt[base + 3]);
+ }
+
+ float3 getPixel3(size_t const& x, size_t const& y)
+ {
+ size_t base = 4 * (y * width + x);
+ return make_float3(flt[base], flt[base + 1], flt[base + 2]);
+ }
+
+private:
+ int width, height;
+ float* flt;
+};
+
+class OEXRFile
+{
+public:
+ OEXRFile(std::vector<float3> const& dat, int width, int height, int compressionType=TINYEXR_COMPRESSIONTYPE_PIZ);
+ OEXRFile(std::vector<float2> const& dat, int width, int height, int compressionType=TINYEXR_COMPRESSIONTYPE_PIZ);
+ void write(std::string const& filename);
+ ~OEXRFile() = default;
+
+protected:
+ void initChannelInfo();
+ void initHeader();
+private:
+ int width, height;
+ int compressionType;
+
+ std::vector<EXRChannelInfo> infos;
+ EXRHeader hd;
+
+ std::vector<int> pixelType;
+ std::vector<int> reqPixelType;
+
+ std::vector<float> r, g, b, a;
+
+}; \ No newline at end of file
diff --git a/graphics/asymptote/cudareflect/IrradianceGenerator.sln b/graphics/asymptote/cudareflect/IrradianceGenerator.sln
new file mode 100644
index 0000000000..eee523873a
--- /dev/null
+++ b/graphics/asymptote/cudareflect/IrradianceGenerator.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31613.86
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IrradianceGenerator", "IrradianceGenerator.vcxproj", "{0043AE31-F6A1-47CB-8A80-1DA6E2C049DF}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0043AE31-F6A1-47CB-8A80-1DA6E2C049DF}.Debug|x64.ActiveCfg = Debug|x64
+ {0043AE31-F6A1-47CB-8A80-1DA6E2C049DF}.Debug|x64.Build.0 = Debug|x64
+ {0043AE31-F6A1-47CB-8A80-1DA6E2C049DF}.Release|x64.ActiveCfg = Release|x64
+ {0043AE31-F6A1-47CB-8A80-1DA6E2C049DF}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {849A0D9E-0CAB-48D8-954B-D97F29D1C539}
+ EndGlobalSection
+EndGlobal
diff --git a/graphics/asymptote/cudareflect/IrradianceGenerator.vcxproj b/graphics/asymptote/cudareflect/IrradianceGenerator.vcxproj
new file mode 100644
index 0000000000..08c8855e0e
--- /dev/null
+++ b/graphics/asymptote/cudareflect/IrradianceGenerator.vcxproj
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <CudaCompile Include="kernel.cu" />
+ <CudaCompile Include="ReflectanceMapper.cu" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="EXRFiles.cc" />
+ <ClCompile Include="main.cc" />
+ <ClCompile Include="tinyexr.cc" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="common.h" />
+ <ClInclude Include="EXRFiles.h" />
+ <ClInclude Include="helper.cuh" />
+ <ClInclude Include="include\tinyexr\tinyexr.h">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DeploymentContent>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DeploymentContent>
+ </ClInclude>
+ <ClInclude Include="kernel.h" />
+ <ClInclude Include="ReflectanceMapper.cuh" />
+ <ClInclude Include="simpson.cuh" />
+ <ClInclude Include="utils.cuh" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include=".gitignore" />
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{0043AE31-F6A1-47CB-8A80-1DA6E2C049DF}</ProjectGuid>
+ <RootNamespace>IrradianceGenerator</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ <Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA 11.4.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <PreprocessorDefinitions>DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>cudart_static.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <CudaCompile>
+ <TargetMachinePlatform>64</TargetMachinePlatform>
+ <CudaRuntime>Shared</CudaRuntime>
+ <GenerateRelocatableDeviceCode>false</GenerateRelocatableDeviceCode>
+ </CudaCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ <PreprocessorDefinitions>DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>cudart_static.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <CudaCompile>
+ <TargetMachinePlatform>64</TargetMachinePlatform>
+ <GPUDebugInfo>true</GPUDebugInfo>
+ <CudaRuntime>Shared</CudaRuntime>
+ <GenerateRelocatableDeviceCode>false</GenerateRelocatableDeviceCode>
+ </CudaCompile>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ <Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA 11.4.targets" />
+ </ImportGroup>
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ </Target>
+</Project> \ No newline at end of file
diff --git a/graphics/asymptote/cudareflect/Makefile b/graphics/asymptote/cudareflect/Makefile
new file mode 100644
index 0000000000..ebb7833ffd
--- /dev/null
+++ b/graphics/asymptote/cudareflect/Makefile
@@ -0,0 +1,26 @@
+# Makefile.
+
+CFLAGS = -O3 -g -Wall
+CXX = g++
+NVCC = nvcc
+INCL=-I/usr/local/cuda/include
+NVCCFLAGS = -O3 -Xcudafe --diag_suppress=esa_on_defaulted_function_ignored
+
+FILES = main tinyexr EXRFiles
+CUDA_FILES = kernel ReflectanceMapper
+CUDA_LIBS = -lcudart -lz
+
+all: $(FILES:=.o) $(CUDA_FILES:=.o)
+ $(NVCC) $(NVCCFLAGS) -o reflect $(FILES:=.o) $(CUDA_FILES:=.o) $(CUDA_LIBS)
+
+tinyexr.o: tinyexr/tinyexr.h
+
+.SUFFIXES: .c .cc .cu .o .d
+.cc.o:
+ $(CXX) $(CFLAGS) $(INCL) -o $@ -c $<
+
+.cu.o:
+ $(NVCC) $(NVCCFLAGS) -o $@ -c $<
+
+clean:
+ rm -f *.o *.d reflect
diff --git a/graphics/asymptote/cudareflect/ReflectanceMapper.cu b/graphics/asymptote/cudareflect/ReflectanceMapper.cu
new file mode 100644
index 0000000000..e14ae74b25
--- /dev/null
+++ b/graphics/asymptote/cudareflect/ReflectanceMapper.cu
@@ -0,0 +1,272 @@
+#include "ReflectanceMapper.cuh"
+
+#include "helper.cuh"
+#include "utils.cuh"
+
+#include <cuda.h>
+#include <device_launch_parameters.h>
+
+#define GLM_FORCE_CUDA
+#include <glm/glm.hpp>
+
+__device__
+inline float swap_bits(uint32_t const& x, uint32_t const& mask_1, unsigned int const& shft)
+{
+ return ((x & mask_1) << shft) | ((x & (~mask_1)) >> shft);
+}
+
+__device__ constexpr float recvbit = 2.32830643654e-10; // 1/2^32.
+__device__ constexpr int REFL_NUM_SAMPLES = 1 << 15;
+
+__device__
+float van_der_corput_bitshift(uint32_t bits)
+{
+ bits = swap_bits(bits, 0x55555555, 1);
+ bits = swap_bits(bits, 0x33333333, 2);
+ bits = swap_bits(bits, 0x0F0F0F0F, 4);
+ bits = swap_bits(bits, 0x00FF00FF, 8);
+ bits = swap_bits(bits, 0x0000FFFF, 16);
+
+ return static_cast<float>(bits) * recvbit;
+}
+
+__device__
+glm::vec2 hamersely(uint32_t i, uint32_t N)
+{
+ return glm::vec2(static_cast<float>(i) / N, van_der_corput_bitshift(i));
+}
+
+__device__
+glm::vec3 importance_sampl_GGX(glm::vec2 sample, glm::vec3 normal, float roughness)
+{
+ float a = roughness * roughness;
+
+ float phi = TAU * sample.x;
+ float cosTheta = sqrtf((1.0f - sample.y) / (1.f + (a * a - 1.f) * sample.y)); // GGX Sample, inverse sampling?
+ // TODO: Understand the derivation behind this cosTheta. It has something to do with GGX distribution, but how?
+ float sinTheta = sqrtf(1.0f - cosTheta * cosTheta);
+
+ glm::vec3 vec = from_sphcoord(phi, cosTheta, sinTheta);
+ glm::vec3 N1(cosTheta * __cosf(phi), cosTheta * __sinf(phi), -1 * sinTheta);
+ glm::vec3 N2(-1 * __sinf(phi), __cosf(phi), 0);
+
+ glm::mat3 normalBasis(N1, N2, normal);
+ return normalBasis * vec;
+}
+
+
+#pragma region mapReflectance
+__global__
+void map_reflectance(cudaTextureObject_t tObj,
+ int width, int height, float roughness,
+ float3* out, int outWidth, int outHeight)
+{
+ int idx = blockIdx.x * blockDim.x + threadIdx.x;
+ int idx_y = blockIdx.y * blockDim.y + threadIdx.y;
+ glm::vec3 result(0.0f);
+
+ if (idx < outWidth && idx_y < outHeight)
+ {
+ int access_idx = to_idx(outWidth, idx, idx_y);
+
+ float target_phi = TAU * ((idx + 0.5f) / outWidth);
+ float target_theta = PI * ((idx_y + 0.5f) / outHeight);
+ glm::vec3 N = from_sphcoord(target_phi, target_theta);
+
+ float total_weight = 0.0f;
+ for (int i = 0; i < REFL_NUM_SAMPLES; ++i)
+ {
+ glm::vec2 sample = hamersely(i, REFL_NUM_SAMPLES);
+ glm::vec3 half_vec = importance_sampl_GGX(sample, N, roughness);
+
+ // use the structure of rhombus to calculate lightvec
+ glm::vec3 scaled_half = 2.0f * glm::dot(half_vec, N) * half_vec;
+ glm::vec3 lightvec = glm::normalize(scaled_half - N);
+
+ float ndotl = glm::dot(N, lightvec);
+ glm::vec2 sphcoord = to_sphcoord(lightvec);
+ float4 frag = tex2D<float4>(tObj,
+ sphcoord.x * PI_RECR * width / 2,
+ sphcoord.y * PI_RECR * height);
+
+ glm::vec3 frag3(frag.x, frag.y, frag.z);
+
+ if (ndotl > 0.0)
+ {
+ // epic games said it gives better results, otherwise weight can be set to 1.
+#ifndef SET_WEIGHT_ONE
+ float weight = ndotl;
+#else
+ float weight = 1.0f;
+#endif
+ result += (frag3 * weight); // weighting by n@l, technically not required,
+ total_weight += weight;
+ }
+
+ }
+ if (total_weight > 0.0f)
+ {
+ result = result / total_weight;
+ out[access_idx] = make_float3(result.x, result.y, result.z);
+ }
+ else
+ out[access_idx] = make_float3(0, 0, 0);
+
+ }
+}
+
+const size_t blkSz = 8;
+void map_reflectance_ker(
+ float4* in, float3* out, size_t width, size_t height, float roughness,
+ size_t outWidth, size_t outHeight)
+{
+ float4* d_ptr;
+ size_t pitch;
+ cudaErrorCheck(cudaMallocPitch(
+ &d_ptr, &pitch, width * sizeof(float4), height));
+ cudaErrorCheck(cudaMemcpy2D(d_ptr, pitch, in,
+ width * sizeof(float4), width * sizeof(float4),
+ height, cudaMemcpyHostToDevice));
+
+ cudaResourceDesc cRD;
+ memset(&cRD, 0, sizeof(cudaResourceDesc));
+ cRD.resType = cudaResourceTypePitch2D;
+ cRD.res.pitch2D.devPtr = d_ptr;
+ cRD.res.pitch2D.width = width;
+ cRD.res.pitch2D.height = height;
+ cRD.res.pitch2D.desc = cudaCreateChannelDesc<float4>();
+ cRD.res.pitch2D.pitchInBytes = pitch;
+
+ cudaTextureDesc texDesc;
+ memset(&texDesc, 0, sizeof(texDesc));
+ texDesc.filterMode = cudaFilterModeLinear;
+ texDesc.sRGB = 0;
+ texDesc.readMode = cudaReadModeElementType;
+
+ cudaTextureObject_t t_obj;
+ cudaErrorCheck(cudaCreateTextureObject(
+ &t_obj, &cRD, &texDesc, nullptr));
+
+ // out source
+ float3* d_out = nullptr;
+ cudaErrorCheck(cudaMalloc(
+ (void**)&d_out, static_cast<size_t>(sizeof(float3) * outWidth * outHeight)));
+ dim3 blockSz((outWidth / blkSz) + 1, (outHeight / blkSz) + 1);
+ dim3 kerSz(blkSz, blkSz);
+ map_reflectance KERNEL_ARGS(blockSz, kerSz) (t_obj, width, height, roughness, d_out, outWidth, outHeight);
+
+ cudaErrorCheck(cudaMemcpy(
+ out, d_out, sizeof(float3) * outWidth * outHeight, cudaMemcpyDeviceToHost));
+
+ cudaErrorCheck(cudaDestroyTextureObject(t_obj));
+ cudaErrorCheck(cudaFree(d_ptr));
+}
+
+
+#pragma endregion
+
+__device__
+float norm_dist(float const& roughness, float3 const& half_vec)
+{
+ float alpha = roughness * roughness;
+ float ndoth = half_vec.z; // assume N=(0,0,1)
+ float denom_base = (ndoth * ndoth) * (alpha * alpha - 1) + 1;
+ return (alpha * alpha) / (denom_base * denom_base * PI);
+}
+
+__device__
+float G_component(float const& k, float const& ndotv)
+{
+ float denom = (ndotv * (1 - k)) + k;
+ return 1 / denom;
+}
+
+__device__
+float GFn(float const& roughness, float const& ndotl, float const& ndotv)
+{
+ float a = roughness * roughness;
+ float k = a * a * 0.5;
+ return G_component(k, ndotl) * G_component(k, ndotv);
+}
+
+__device__
+float clamp(float const& x)
+{
+ return fminf(fmaxf(x, 0.0f), 1.0f);
+}
+
+// by symmetry, assume phi_v=0.
+// porting of python code to CUDA
+
+__device__ constexpr int LUT_INTEGRATE_SAMPLES = 8192;
+__device__ constexpr float INTEGRATE_LUT_SCALE = 1.0f / LUT_INTEGRATE_SAMPLES;
+
+__device__
+float2 get_integrate_value(float const& roughness, float const& cos_theta)
+{
+ glm::vec2 value(0.0f);
+ glm::vec3 upZ(0, 0, 1.0f);
+ float num_samples = 0.0f;
+
+ float cos_theta_v = clamp(cos_theta);
+ float sin_theta_v = sqrtf(1 - cos_theta_v * cos_theta_v);
+ glm::vec3 view_vec(sin_theta_v, 0, cos_theta_v);
+
+ for (int i=0; i< LUT_INTEGRATE_SAMPLES; ++i)
+ {
+ glm::vec2 sample_coord = hamersely(i, LUT_INTEGRATE_SAMPLES);
+ glm::vec3 half_vec = importance_sampl_GGX(sample_coord, upZ, roughness);
+
+ glm::vec3 scaled_half = 2.0f * glm::dot(half_vec, view_vec) * half_vec;
+ glm::vec3 lightvec = glm::normalize(scaled_half - view_vec);
+
+ float ldotn = clamp(lightvec.z);
+ float vdoth = clamp(glm::dot(half_vec, view_vec));
+ float ndoth = clamp(half_vec.z);
+
+ if (ldotn > 0.0f)
+ {
+ float base_val = (GFn(roughness, ldotn, cos_theta_v) * cos_theta_v * ldotn);
+ float base_f = powf(1.0f - vdoth, 5.0f);
+
+ value.x += base_val * (1 - base_f);
+ value.y += base_val * base_f;
+ num_samples += 1.0f;
+ }
+ }
+ value = value * INTEGRATE_LUT_SCALE;
+
+ return make_float2(value.x, value.y);
+}
+
+__global__
+void generate_brdf_integrate(int width, int height, float2* out)
+{
+ int idx = blockIdx.x * blockDim.x + threadIdx.x;
+ int idx_y = blockIdx.y * blockDim.y + threadIdx.y;
+ if (idx < width && idx_y < height)
+ {
+ int access_idx = to_idx(width, idx, idx_y);
+ float cosv = (idx + 1.0f) / width;
+ float roughness = (idx_y + 1.0f) / height;
+
+ out[access_idx] = get_integrate_value(roughness, cosv);
+ }
+}
+
+void generate_brdf_integrate_lut_ker(int width, int height, float2* out)
+{
+ float2* d_out;
+ cudaErrorCheck(cudaMalloc(
+ (void**)&d_out, static_cast<size_t>(width * height * sizeof(float2))));
+
+
+ dim3 blockSz((width / blkSz) + 1, (height / blkSz) + 1);
+ dim3 kerSz(blkSz, blkSz);
+ generate_brdf_integrate KERNEL_ARGS(blockSz, kerSz) (width, height, d_out);
+
+ cudaErrorCheck(cudaMemcpy(
+ out, d_out, width * height * sizeof(float2), cudaMemcpyDeviceToHost));
+ cudaErrorCheck(cudaFree(d_out));
+
+}
diff --git a/graphics/asymptote/cudareflect/ReflectanceMapper.cuh b/graphics/asymptote/cudareflect/ReflectanceMapper.cuh
new file mode 100644
index 0000000000..3643bf782a
--- /dev/null
+++ b/graphics/asymptote/cudareflect/ReflectanceMapper.cuh
@@ -0,0 +1,16 @@
+#pragma once
+
+#ifndef __INTELLISENSE__
+#ifndef KERNEL_ARGS
+#define KERNEL_ARGS(blk,thrdsz) <<<blk,thrdsz>>>
+#endif
+#else
+#define KERNEL_ARGS(blk,thrdsz)
+#define __CUDACC__
+#include <device_functions.h>
+#endif
+
+#include <cuda_runtime.h>
+
+void map_reflectance_ker(float4* in, float3* out, size_t width, size_t height, float roughness, size_t outWidth, size_t outHeight);
+void generate_brdf_integrate_lut_ker(int width, int height, float2* out);
diff --git a/graphics/asymptote/cudareflect/common.h b/graphics/asymptote/cudareflect/common.h
new file mode 100644
index 0000000000..9758e7ac40
--- /dev/null
+++ b/graphics/asymptote/cudareflect/common.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <iostream>
+#include <iomanip>
+#include <vector>
+#include <memory>
+#include <array>
+#include <cstring>
+#include <cmath>
+#include <functional>
+#include <sstream>
+
+#define TINYEXR_USE_THREAD 1
+#include "tinyexr/tinyexr.h" \ No newline at end of file
diff --git a/graphics/asymptote/cudareflect/helper.cuh b/graphics/asymptote/cudareflect/helper.cuh
new file mode 100644
index 0000000000..87d1bb6aeb
--- /dev/null
+++ b/graphics/asymptote/cudareflect/helper.cuh
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <iostream>
+#include <cuda.h>
+#include <cuda_runtime.h>
+
+inline void check_error()
+{
+#ifdef DEBUG
+ cudaError_t __err = cudaGetLastError();
+ if (__err != cudaSuccess)
+ {
+ std::cerr << "Fata CUDA Error. Msg: " << cudaGetErrorString(__err) << std::endl;
+ }
+ else
+ {
+ std::cerr << "CUDA Operation success" << std::endl;
+ }
+#endif
+}
+
+inline void cudaErrorCheck(cudaError err)
+{
+ if (err != cudaSuccess)
+ {
+ std::cerr << "ERROR: " << cudaGetErrorString(err) << std::endl;
+ exit(1);
+ }
+}
+
+template<typename T>
+T* cudaDupe(T* in, size_t sz)
+{
+ T* out = nullptr;
+ cudaErrorCheck(cudaMalloc((void**)&out, sizeof(T) * sz));
+ cudaErrorCheck(cudaMemcpy(out, in, sizeof(T) * sz, cudaMemcpyHostToDevice));
+ return out;
+}
+
+__device__
+inline int to_idx(int width, int x, int y)
+{
+ return y * width + x;
+}
diff --git a/graphics/asymptote/cudareflect/kernel.cu b/graphics/asymptote/cudareflect/kernel.cu
new file mode 100644
index 0000000000..9104ed3b64
--- /dev/null
+++ b/graphics/asymptote/cudareflect/kernel.cu
@@ -0,0 +1,148 @@
+/**
+* @file kernel.cu
+* @author Supakorn "Jamie" Rassameemasmuang <jamievlin@outlook.com>
+* CUDA Kernel for computing irradiance by solid angle integration
+
+* Partially based on:
+* https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf
+*/
+
+#include "kernel.h"
+#include "helper.cuh"
+#include "utils.cuh"
+
+#include "simpson.cuh"
+
+#include <cuda.h>
+#include <texture_indirect_functions.h>
+#include <device_launch_parameters.h>
+
+#define GLM_FORCE_CUDA
+#include <glm/glm.hpp>
+
+#include <functional>
+
+class IntegrateSampler
+{
+public:
+ __device__
+ IntegrateSampler(
+ cudaTextureObject_t tObjin,
+ glm::mat3 normalOrthBasis,
+ size_t const& inWidth, size_t const& inHeight) :
+ normalOrthBasis(normalOrthBasis), width(inWidth), height(inHeight),
+ tObj(tObjin)
+
+ {
+ }
+
+ __device__ ~IntegrateSampler() {}
+
+ __device__
+ glm::vec3 integrand(float const& sampled_phi, float const& sampled_theta)
+ {
+ // vec3 is the world space coordinate
+ glm::vec2 sphcoord = to_sphcoord(angleToBasis(normalOrthBasis, sampled_phi, sampled_theta));
+ float4 frag = tex2D<float4>(tObj,
+ sphcoord.x * PI_RECR * 0.5*width,
+ sphcoord.y * PI_RECR * height);
+
+ return glm::vec3(frag.x, frag.y, frag.z);
+ }
+
+ __device__
+ glm::vec3 inner(float const& sampled_theta)
+ {
+ return simpson(
+ [this, &sampled_theta](float const& phi) {return this->integrand(phi,sampled_theta); },
+ 0, TAU, acc)*0.5f*__sinf(2 * sampled_theta);
+ }
+
+ __device__
+ glm::vec3 integrate()
+ {
+ return PI_RECR * simpson(
+ [this](float const& theta) {return this->inner(theta); },
+ 0, HALFPI, acc);
+ }
+
+private:
+ glm::mat3 normalOrthBasis;
+ size_t width, height;
+ cudaTextureObject_t tObj;
+};
+
+
+
+__global__
+void irradiate(cudaTextureObject_t tObjin, float3* out, size_t width, size_t height)
+{
+ int idx = blockIdx.x * blockDim.x + threadIdx.x;
+ int idx_y = blockIdx.y * blockDim.y + threadIdx.y;
+
+
+ if (idx < width && idx_y < height)
+ {
+ int access_idx = to_idx(width, idx, idx_y);
+
+ float target_phi = TAU * ((idx + 0.5f) / width);
+ float target_theta = PI * ((idx_y + 0.5f) / height);
+
+ const glm::vec3 N = from_sphcoord(target_phi, target_theta);
+ const glm::vec3 N1(
+ __cosf(target_theta) * __cosf(target_phi),
+ __cosf(target_theta) * __sinf(target_phi),
+ -1*__sinf(target_theta));
+ const glm::vec3 N2(-1 * __sinf(target_phi), __cosf(target_phi), 0);
+
+ glm::mat3 normalBasisMat(N1,N2,N);
+
+ IntegrateSampler integrator(tObjin, normalBasisMat, width, height);
+ glm::vec3 out_val = integrator.integrate();
+ out[access_idx] = make_float3(out_val.x, out_val.y, out_val.z);
+ }
+}
+
+const size_t blkSz = 8;
+void irradiate_ker(float4* in, float3* out, size_t width, size_t height)
+{
+ float4* d_ptr;
+ size_t pitch;
+ cudaErrorCheck(cudaMallocPitch(
+ &d_ptr, &pitch, width * sizeof(float4), height));
+ cudaErrorCheck(cudaMemcpy2D(d_ptr, pitch, in,
+ width * sizeof(float4), width*sizeof(float4),
+ height, cudaMemcpyHostToDevice));
+
+ cudaResourceDesc cRD;
+ memset(&cRD, 0, sizeof(cudaResourceDesc));
+ cRD.resType = cudaResourceTypePitch2D;
+ cRD.res.pitch2D.devPtr = d_ptr;
+ cRD.res.pitch2D.width = width;
+ cRD.res.pitch2D.height = height;
+ cRD.res.pitch2D.desc = cudaCreateChannelDesc<float4>();
+ cRD.res.pitch2D.pitchInBytes = pitch;
+
+ cudaTextureDesc texDesc;
+ memset(&texDesc, 0, sizeof(texDesc));
+ texDesc.filterMode = cudaFilterModeLinear;
+ texDesc.sRGB = 0;
+ texDesc.readMode = cudaReadModeElementType;
+
+ cudaTextureObject_t t_obj;
+ cudaErrorCheck(cudaCreateTextureObject(
+ &t_obj, &cRD, &texDesc, nullptr));
+
+ // out source
+ float3* d_out;
+ cudaErrorCheck(cudaMalloc(
+ (void**)&d_out, static_cast<size_t>(sizeof(float3) * width * height)));
+ dim3 blockSz((width / blkSz) + 1, (height / blkSz) + 1);
+ dim3 kerSz(blkSz, blkSz);
+ irradiate KERNEL_ARGS(blockSz, kerSz) (t_obj, d_out, width, height);
+
+ cudaErrorCheck(cudaMemcpy(
+ out, d_out, sizeof(float3) * width * height, cudaMemcpyDeviceToHost));
+ cudaErrorCheck(cudaDestroyTextureObject(t_obj));
+ cudaFree(d_ptr);
+}
diff --git a/graphics/asymptote/cudareflect/kernel.h b/graphics/asymptote/cudareflect/kernel.h
new file mode 100644
index 0000000000..1a1587dfc6
--- /dev/null
+++ b/graphics/asymptote/cudareflect/kernel.h
@@ -0,0 +1,18 @@
+/**
+* @file kernel.h
+* @author Supakorn "Jamie" Rassameemasmuang <jamievlin@outlook.com>
+* CUDA Kernel Header for computing irradiance by solid angle integration
+*/
+#pragma once
+
+#ifndef __INTELLISENSE__
+#ifndef KERNEL_ARGS
+#define KERNEL_ARGS(blk,thrdsz) <<<blk,thrdsz>>>
+#endif
+#else
+#define KERNEL_ARGS(blk,thrdsz)
+#define __CUDACC__
+#endif
+
+#include <cuda_runtime.h>
+void irradiate_ker(float4* in, float3* out, size_t width, size_t height);
diff --git a/graphics/asymptote/cudareflect/main.cc b/graphics/asymptote/cudareflect/main.cc
new file mode 100644
index 0000000000..2450b5dd84
--- /dev/null
+++ b/graphics/asymptote/cudareflect/main.cc
@@ -0,0 +1,305 @@
+/**
+ * @file main.cpp
+ * @author Supakorn "Jamie" Rassameemasmuang <jamievlin@outlook.com>
+ * Program for loading image and writing the irradiated image.
+ */
+
+#include "common.h"
+#include <fstream>
+
+#ifdef _WIN32
+// use vcpkg getopt package for this
+#undef _UNICODE
+#include <getopt.h>
+#include <Windows.h>
+#else
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#endif
+
+#include "kernel.h"
+#include "ReflectanceMapper.cuh"
+#include "EXRFiles.h"
+
+size_t const MIN_WIDTH = 2;
+size_t const MIN_HEIGHT = 2;
+
+
+struct Args
+{
+ char mode = 'a';
+ bool webgl = false;
+ char const* file_in = nullptr;
+ char const* directory = nullptr;
+
+ size_t count;
+
+ bool validate()
+ {
+ if (mode == 0)
+ return false;
+
+ if ((mode == 'a' || mode == 'b' || mode == 'i' || mode == 'r') && !file_in)
+ {
+ return false;
+ }
+
+ return true;
+ }
+};
+
+void usage()
+{
+ std::cerr << "reflect [-a|-i|-r|-b] inputEXRFile [-d outputDirectory]" <<
+ std::endl;
+ std::cerr << "Options: " << std::endl;
+ std::cerr << "-h\t\t help" << std::endl;
+ std::cerr << "-d\t\t output directory" << std::endl;
+ std::cerr << "-a\t\t generate irradiance and reflectance images (default)"
+ << std::endl;
+ std::cerr << "-i\t\t generate irradiance image diffuse.exr" << std::endl;
+ std::cerr << "-r\t\t generate reflectance images reflN.exr" << std::endl;
+ std::cerr << "-b\t\t generate brdf image refl.exr (independent of image)"
+ << std::endl;
+}
+
+Args parseArgs(int argc, char* argv[])
+{
+ Args arg;
+ int c;
+ while ((c = getopt(argc, argv, "abd:hir")) != -1)
+ {
+ switch (c)
+ {
+ case 'a':
+ arg.mode = 'a';
+ break;
+ case 'i':
+ arg.mode = 'i';
+ break;
+ case 'r':
+ arg.mode = 'r';
+ break;
+ case 'b':
+ arg.mode = 'b';
+ break;
+/*
+ case 'c':
+ {
+ std::stringstream ss;
+ ss << optarg;
+ ss >> arg.count;
+ }
+ break;
+*/
+ case 'd':
+ arg.directory = optarg;
+ break;
+ case 'h':
+ usage();
+ exit(0);
+ break;
+ default:
+ usage();
+ exit(1);
+ }
+ }
+
+ arg.file_in = argv[optind];
+
+ if (!arg.validate())
+ {
+ usage();
+ exit(1);
+ }
+ return arg;
+}
+
+struct image_t
+{
+ float4* im;
+ int width, height;
+
+ int sz() const { return width * height; }
+
+ image_t(float4* im, int width, int height) :
+ im(im), width(std::move(width)), height(std::move(height)) {}
+};
+
+void irradiate_im(image_t& im, std::string const& prefix)
+{
+ std::vector<float3> out_proc(im.sz());
+ std::stringstream out_name;
+ out_name << prefix;
+ std::cout << "Irradiating image..." << std::endl;
+ irradiate_ker(im.im, out_proc.data(), im.width, im.height);
+ out_name << "diffuse.exr";
+
+ std::string out_name_str(std::move(out_name).str());
+ OEXRFile ox(out_proc, im.width, im.height);
+
+ std::cout << "copying data back" << std::endl;
+ std::cout << "writing to: " << out_name_str << std::endl;
+ ox.write(out_name_str);
+}
+
+std::string generate_refl_file(std::string const& prefix, int const& i, std::string const suffix="")
+{
+ std::stringstream out_name;
+ out_name << prefix << "refl" << i << suffix << ".exr";
+ return out_name.str();
+}
+
+void map_refl_im(image_t& im, std::string const& prefix, float const& step, int const& i, std::pair<size_t, size_t> const& outSize, bool halve=false)
+{
+ float roughness = step * i;
+ auto [outWidth, outHeight] = outSize;
+ std::vector<float3> out_proc(outWidth * outHeight);
+
+ std::string out_name_str = generate_refl_file(prefix, i,
+ halve ? "w" : "");
+ std::cout << "Mapping reflectance map..." << std::endl;
+ map_reflectance_ker(im.im, out_proc.data(), im.width, im.height, roughness, outWidth, outHeight);
+ OEXRFile ox(out_proc, outWidth, outHeight);
+ std::cout << "copying data back" << std::endl;
+ std::cout << "writing to: " << out_name_str << std::endl;
+ ox.write(out_name_str);
+}
+
+std::string const INVALID_FILE_ATTRIB = "Intermediate directories do not exist";
+
+void make_dir(std::string const& directory)
+{
+ // different implementation for windows vs linux
+#ifdef _WIN32
+ DWORD ret = CreateDirectoryA(directory.c_str(), nullptr);
+ if (ret == 0 && GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ std::cerr << INVALID_FILE_ATTRIB << std::endl;
+ exit(1);
+ }
+#else
+ struct stat st;
+ if (stat(directory.c_str(), &st) == -1)
+ {
+ mkdir(directory.c_str(), 0755);
+ }
+#endif
+}
+
+void copy_file(std::string const& in, std::string const& out)
+{
+ std::ifstream ifs(in, std::ios::binary);
+ std::ofstream ofs(out, std::ios::binary);
+
+ ofs << ifs.rdbuf();
+
+}
+
+void generate_brdf_refl(
+ int res, std::string const& outdir, std::string const& outname="refl.exr")
+{
+ std::vector<float2> out_proc(res * res);
+ std::string finalName = outdir + "/" + outname;
+ std::cout << "generating Fresnel/Roughness/cos_v data" << std::endl;
+ std::cout << "writing to " << finalName << std::endl;
+ generate_brdf_integrate_lut_ker(res, res, out_proc.data());
+ OEXRFile ox(out_proc, res, res);
+ ox.write(finalName);
+}
+
+inline float length(float3 v)
+{
+ return sqrt(v.x*v.x+v.y*v.y+v.z*v.z);
+}
+
+int main(int argc, char* argv[])
+{
+ Args args = parseArgs(argc, argv);
+ std::vector<float4> im_proc;
+ int width = 0;
+ int height = 0;
+
+ std::cout << "Loading file " << args.file_in << std::endl;
+ EXRFile im(args.file_in);
+ width = im.getWidth();
+ height = im.getHeight();
+ std::vector<float3> out_proc;
+ std::cout << "Image dimensions: " << width << "x" << height << std::endl;
+ for (int i = 0; i < height; ++i)
+ {
+ for (int j = 0; j < width; ++j)
+ {
+ // index is i*height+j <-> (i,j)
+ float3 frag3=im.getPixel3(j, i);
+ // Clamp oversaturated values.
+ float norm=0.02*length(frag3);
+ if(norm > 1.0) {
+ frag3.x /= norm;
+ frag3.y /= norm;
+ frag3.z /= norm;
+ }
+ out_proc.emplace_back(frag3);
+ im_proc.emplace_back(make_float4(frag3.x,frag3.y,frag3.z,1.0f));
+ }
+ // std::cout << "pushed row " << i << " into array" << std::endl;
+ }
+ std::cout << "finished converting to float3" << std::endl;
+
+ std::stringstream outss;
+ if (args.directory)
+ {
+ make_dir(args.directory);
+ }
+ else
+ {
+ args.directory = ".";
+ }
+
+ outss << args.directory << "/";
+
+ if(args.mode != 'b') {
+ std::ofstream readme(outss.str()+"README");
+ readme << "The image files in this directory were generated from " << args.file_in << std::endl;
+ readme.close();
+ }
+
+ std::string outprefix(outss.str());
+
+ image_t imt(im_proc.data(), width, height);
+
+ if (args.mode == 'b')
+ {
+ generate_brdf_refl(200, ".");
+ }
+ if (args.mode == 'i' || args.mode == 'a')
+ {
+ irradiate_im(imt, outprefix);
+ }
+ if (args.mode == 'r' || args.mode == 'a')
+ {
+ OEXRFile ox(out_proc, width, height);
+ std::string out_name_str = generate_refl_file(outprefix, 0);
+ std::cout << "writing to: " << out_name_str << std::endl;
+ ox.write(out_name_str);
+
+ for(size_t halve=0; halve < 2; ++halve) {
+ size_t count=halve ? 8 : 10;
+ float step = 1.0f / count;
+
+ unsigned int out_width = width;
+ unsigned int out_height = height;
+
+ for (size_t i = 1; i <= count; ++i)
+ {
+ if (halve && out_width >= MIN_WIDTH && out_height >= MIN_HEIGHT)
+ {
+ out_width = out_width >> 1;
+ out_height = out_height >> 1; // halve
+ }
+ map_refl_im(imt, outprefix, step, i, std::pair<size_t,size_t>(out_width, out_height), halve);
+ }
+ }
+ }
+}
diff --git a/graphics/asymptote/cudareflect/simpson.cuh b/graphics/asymptote/cudareflect/simpson.cuh
new file mode 100644
index 0000000000..99fe8b7aad
--- /dev/null
+++ b/graphics/asymptote/cudareflect/simpson.cuh
@@ -0,0 +1,103 @@
+/*
+* John C. Bowman and Supakorn "Jamie" Rassameemasmuang <jamievlin@outlook.com>
+* University of Alberta
+* CUDA Adaptive Simpson integration
+*/
+
+#include <cuda.h>
+
+#include "utils.cuh"
+
+// Compute a numerical approximation to an integral via adaptive Simpson's Rule
+// This routine ignores underflow.
+
+__device__ constexpr float sixth=1.0/6.0;
+__device__ constexpr int depth=10;
+__device__ constexpr int acc = 1.0/256;
+
+template<typename T>
+struct TABLE {
+ bool left; // left interval?
+ float dat;
+ T psum, f1t, f2t, f3t, estr;
+};
+
+template<typename T=glm::vec3, typename TUtil=Vec3Utility, typename Tf>
+__device__ inline T
+simpson(Tf f, // Function to be integrated.
+ float a, float b, // Lower, upper limits of integration.
+ float acc) // Desired relative accuracy of integral.
+ // Try to make |error| <= acc*abs(integral).
+{
+ T integral,diff,area,estl,estr,est,fv0,fv1,fv2,fv3,fv4;
+ float dx;
+ TABLE<T> table[depth],*p,*pstop;
+
+ p=table;
+ pstop=table+depth-1;
+ p->left=true;
+ p->psum=TUtil::init();
+ float alpha=a;
+ float da=b-a;
+ fv0=f(alpha);
+ fv2=f(alpha+0.5f*da);
+ fv4=f(alpha+da);
+ float wt=sixth*da;
+ est=wt*(fv0+4.0f*fv2+fv4);
+ area=est;
+ float acc2=acc*acc;
+
+ // Have estimate est of integral on (alpha, alpha+da).
+ // Bisect and compute estimates on left and right half intervals.
+ // integral is the best value for the integral.
+
+ for(;;) {
+ dx=0.5f*da;
+ float arg=alpha+0.5f*dx;
+ fv1=f(arg);
+ fv3=f(arg+dx);
+ wt=sixth*dx;
+ estl=wt*(fv0+4.0f*fv1+fv2);
+ estr=wt*(fv2+4.0f*fv3+fv4);
+ integral=estl+estr;
+ diff=est-integral;
+ area -= diff;
+
+ if(p >= pstop || (TUtil::abs2(diff) <= acc2*TUtil::abs2(area))) {
+ // Accept approximate integral.
+ // If it was a right interval, add results to finish at this level.
+ // If it was a left interval, process right interval.
+
+ for(;;) {
+ if(p->left == false) { // process right-half interval
+ alpha += da;
+ p->left=true;
+ p->psum=integral;
+ fv0=p->f1t;
+ fv2=p->f2t;
+ fv4=p->f3t;
+ da=p->dat;
+ est=p->estr;
+ break;
+ }
+ integral += p->psum;
+ if(--p <= table) return integral;
+ }
+
+ } else {
+ // Raise level and store information for processing right-half interval.
+ ++p;
+ da=dx;
+ est=estl;
+ p->left=false;
+ p->f1t=fv2;
+ p->f2t=fv3;
+ p->f3t=fv4;
+ p->dat=dx;
+ p->estr=estr;
+ fv4=fv2;
+ fv2=fv1;
+ }
+ }
+}
+
diff --git a/graphics/asymptote/cudareflect/tinyexr.cc b/graphics/asymptote/cudareflect/tinyexr.cc
new file mode 100644
index 0000000000..37d45de42d
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr.cc
@@ -0,0 +1,15 @@
+/**
+* @file tinyexr.cc
+* @brief An implementation object file for tinyexr mandated by the repository.
+*
+* On Windows, use vcpkg to install zlib instead of nuget. On Linux, this should work naturally
+*/
+
+#include <zlib.h>
+
+#define TINYEXR_IMPLEMENTATION
+#define TINYEXR_USE_MINIZ 0
+#define TINYEXR_USE_THREAD 1
+#define TINYEXR_USE_PIZ 1
+
+#include "tinyexr/tinyexr.h" \ No newline at end of file
diff --git a/graphics/asymptote/cudareflect/tinyexr/CMakeLists.txt b/graphics/asymptote/cudareflect/tinyexr/CMakeLists.txt
new file mode 100644
index 0000000000..6d03e7e193
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/CMakeLists.txt
@@ -0,0 +1,74 @@
+# this cmake file is for compile tests.
+# Not usable for your cmake app.
+cmake_minimum_required(VERSION 3.5)
+
+set(BUILD_TARGET "tinyexr")
+set(SAMPLE_TARGET "test_tinyexr")
+
+project(${BUILD_TARGET} CXX)
+
+# options
+option(TINYEXR_BUILD_SAMPLE "Build a sample" ON)
+option(TINYEXR_USE_MINIZ "Use miniz" ON)
+
+# cmake modules
+list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
+list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/sanitizers)
+find_package(Sanitizers) # Address sanitizer (-DSANITIZE_ADDRESS=ON)
+
+# Require strict C++11 mode(e.g. `-std=c++11`)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
+
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+set(TINYEXR_SOURCES
+ ${PROJECT_SOURCE_DIR}/tinyexr.cc
+ )
+
+if(TINYEXR_USE_MINIZ)
+ enable_language(C)
+ add_library(miniz STATIC deps/miniz/miniz.c)
+ target_include_directories(miniz PUBLIC deps/miniz)
+ set_target_properties(miniz PROPERTIES FOLDER "deps")
+ list(APPEND TINYEXR_EXT_LIBRARIES miniz)
+endif()
+
+add_library(${BUILD_TARGET} ${TINYEXR_SOURCES} ${TINYEXR_DEP_SOURCES})
+add_sanitizers(${BUILD_TARGET})
+
+target_include_directories(${BUILD_TARGET} PRIVATE ${PROJECT_SOURCE_DIR})
+target_link_libraries(${BUILD_TARGET} ${TINYEXR_EXT_LIBRARIES} ${CMAKE_DL_LIBS})
+
+# Increase warning level for clang.
+IF (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ set_source_files_properties(${TINYEXR_SOURCES} PROPERTIES COMPILE_FLAGS "-Weverything -Werror -Wno-padded -Wno-c++98-compat-pedantic -Wno-documentation -Wno-unused-member-function")
+ENDIF ()
+
+if (TINYEXR_BUILD_SAMPLE)
+
+ set(TINYEXR_SAMPLE_SOURCES
+ ${PROJECT_SOURCE_DIR}/test_tinyexr.cc
+ )
+
+ add_executable(${SAMPLE_TARGET} ${TINYEXR_SAMPLE_SOURCES})
+ target_link_libraries(${SAMPLE_TARGET} ${TINYEXR_EXT_LIBRARIES})
+ add_sanitizers(${SAMPLE_TARGET})
+ if (WIN32)
+ target_compile_definitions(${SAMPLE_TARGET} PUBLIC UNICODE)
+ target_compile_definitions(${SAMPLE_TARGET} PUBLIC _UNICODE)
+
+ # Set ${SAMPLE_TARGET} as a startup project for VS IDE
+ set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT ${SAMPLE_TARGET})
+
+ # For easier debugging in VS IDE(cmake 3.8.0 or later required) Set working
+ # directory to ${BUILD_TARGET} git repo root.
+ if(CMAKE_VERSION VERSION_GREATER 3.8.0)
+ set_target_properties(${SAMPLE_TARGET}
+ PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY
+ "${CMAKE_CURRENT_SOURCE_DIR}")
+ endif()
+ endif(WIN32)
+
+endif (TINYEXR_BUILD_SAMPLE)
diff --git a/graphics/asymptote/cudareflect/tinyexr/Makefile b/graphics/asymptote/cudareflect/tinyexr/Makefile
new file mode 100644
index 0000000000..8e54d7ede2
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/Makefile
@@ -0,0 +1,25 @@
+#CXX ?= clang++
+#CXXFLAGS ?= -fsanitize=address -Werror -Wall -Wextra -g -O0 -DTINYEXR_USE_MINIZ=0 -DTINYEXR_USE_PIZ=0
+#LDFLAGS ?= -lz
+
+# ZFP
+#CXXFLAGS += -DTINYEXR_USE_ZFP=1 -I./deps/ZFP/inc
+#LDFLAGS += -L./deps/ZFP/lib -lzfp
+
+CFLAGS += -I./deps/miniz
+CXXFLAGS += -I./deps/miniz
+
+.PHONY: test clean
+
+all: miniz.o
+ $(CXX) $(CXXFLAGS) -o test_tinyexr test_tinyexr.cc miniz.o $(LDFLAGS)
+
+miniz.o:
+ $(CC) $(CFLAGS) -c ./deps/miniz/miniz.c
+
+test:
+ ./test_tinyexr asakusa.exr
+
+clean:
+ rm -rf test_tinyexr miniz.o
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/Makefile.gcc-mingw b/graphics/asymptote/cudareflect/tinyexr/Makefile.gcc-mingw
new file mode 100644
index 0000000000..44e86ed244
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/Makefile.gcc-mingw
@@ -0,0 +1,18 @@
+#CXX ?= clang++
+#CXXFLAGS ?= -fsanitize=address -Werror -Wall -Wextra -g -O0 -DTINYEXR_USE_MINIZ=0 -DTINYEXR_USE_PIZ=0
+#LDFLAGS ?= -lz
+
+CXX=x86_64-w64-mingw32-g++
+
+# ZFP
+#CXXFLAGS += -DTINYEXR_USE_ZFP=1 -I./deps/ZFP/inc
+#LDFLAGS += -L./deps/ZFP/lib -lzfp
+
+all:
+ $(CC) $(CFLAGS) -c ./deps/miniz/miniz.c
+ $(CXX) $(CXXFLAGS) -I./deps/miniz -o test_tinyexr test_tinyexr.cc miniz.o $(LDFLAGS)
+
+test:
+ ./test_tinyexr asakusa.exr
+
+.PHONY: test
diff --git a/graphics/asymptote/cudareflect/tinyexr/Makefile.gcc-mingw-msys b/graphics/asymptote/cudareflect/tinyexr/Makefile.gcc-mingw-msys
new file mode 100644
index 0000000000..28af0e89ae
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/Makefile.gcc-mingw-msys
@@ -0,0 +1,16 @@
+#CXX ?= clang++
+#CXXFLAGS ?= -fsanitize=address -Werror -Wall -Wextra -g -O0 -DTINYEXR_USE_MINIZ=0 -DTINYEXR_USE_PIZ=0
+#LDFLAGS ?= -lz
+
+CXX=g++
+# -municode is not yet implemented
+CXXFLAGS=-DUNICODE -D_UNICODE -mwindows
+
+all:
+ $(CC) $(CFLAGS) -I./deps/miniz ./deps/miniz.c
+ $(CXX) $(CXXFLAGS) -I./deps/miniz -o test_tinyexr test_tinyexr.cc miniz.o $(LDFLAGS)
+
+test:
+ ./test_tinyexr asakusa.exr
+
+.PHONY: test
diff --git a/graphics/asymptote/cudareflect/tinyexr/Makefile.llvm-mingw b/graphics/asymptote/cudareflect/tinyexr/Makefile.llvm-mingw
new file mode 100644
index 0000000000..aff5444e1e
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/Makefile.llvm-mingw
@@ -0,0 +1,25 @@
+#CXX ?= clang++
+#CXXFLAGS ?= -fsanitize=address -Werror -Wall -Wextra -g -O0 -DTINYEXR_USE_MINIZ=0 -DTINYEXR_USE_PIZ=0
+#LDFLAGS ?= -lz
+
+CC=clang
+CXX=clang++
+
+# ZFP
+#CXXFLAGS += -DTINYEXR_USE_ZFP=1 -I./deps/ZFP/inc
+#LDFLAGS += -L./deps/ZFP/lib -lzfp
+
+CXXFLAGS += -DTINYEXR_USE_MINIZ=1 -I./deps/miniz
+CFLAGS += -DTINYEXR_USE_MINIZ=1 -I./deps/miniz
+
+# miniz
+miniz.o:
+ $(CC) $(CFLAGS) -c ./deps/miniz.c
+#
+all: miniz.o
+ $(CXX) $(CXXFLAGS) -o test_tinyexr test_tinyexr.cc miniz.o $(LDFLAGS)
+
+test:
+ ./test_tinyexr asakusa.exr
+
+.PHONY: test
diff --git a/graphics/asymptote/cudareflect/tinyexr/README.md b/graphics/asymptote/cudareflect/tinyexr/README.md
new file mode 100644
index 0000000000..92c766a76f
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/README.md
@@ -0,0 +1,568 @@
+# Tiny OpenEXR image library.
+
+[![Total alerts](https://img.shields.io/lgtm/alerts/g/syoyo/tinyexr.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/syoyo/tinyexr/alerts/)
+
+![Example](https://github.com/syoyo/tinyexr/blob/master/asakusa.png?raw=true)
+
+[![AppVeyor build status](https://ci.appveyor.com/api/projects/status/k07ftfe4ph057qau/branch/master?svg=true)](https://ci.appveyor.com/project/syoyo/tinyexr/branch/master)
+
+[![Travis build Status](https://travis-ci.org/syoyo/tinyexr.svg)](https://travis-ci.org/syoyo/tinyexr)
+
+[![Coverity Scan Build Status](https://scan.coverity.com/projects/5827/badge.svg)](https://scan.coverity.com/projects/5827)
+
+`tinyexr` is a small, single header-only library to load and save OpenEXR (.exr) images.
+`tinyexr` is written in portable C++ (no library dependency except for STL), thus `tinyexr` is good to embed into your application.
+To use `tinyexr`, simply copy `tinyexr.h`, `miniz.c` and `miniz.h`(for zlib. You can use system-installed zlib instead of miniz. Controlled with `TINYEXR_USE_MINIZ` compile flag) into your project.
+
+# Features
+
+Current status of `tinyexr` is:
+
+- OpenEXR v1 image
+ - [x] Scanline format
+ - [x] Tiled format
+ - [x] Tile format with no LoD (load).
+ - [x] Tile format with LoD (load).
+ - [x] Tile format with no LoD (save).
+ - [x] Tile format with LoD (save).
+ - [x] Custom attributes
+- OpenEXR v2 image
+ - [ ] Multipart format
+ - [x] Load multi-part image
+ - [x] Save multi-part image
+ - [ ] Load multi-part deep image
+ - [ ] Save multi-part deep image
+- OpenEXR v2 deep image
+ - [x] Loading scanline + ZIPS + HALF or FLOAT pixel type.
+- Compression
+ - [x] NONE
+ - [x] RLE
+ - [x] ZIP
+ - [x] ZIPS
+ - [x] PIZ
+ - [x] ZFP (tinyexr extension)
+ - [ ] B44?
+ - [ ] B44A?
+ - [ ] PIX24?
+- Line order.
+ - [x] Increasing, decreasing (load)
+ - [ ] Random?
+ - [x] Increasing (save)
+ - [ ] decreasing (save)
+- Pixel format (UINT, FLOAT).
+ - [x] UINT, FLOAT (load)
+ - [x] UINT, FLOAT (deep load)
+ - [x] UINT, FLOAT (save)
+ - [ ] UINT, FLOAT (deep save)
+- Support for big endian machine.
+ - [x] Loading scanline image
+ - [x] Saving scanline image
+ - [x] Loading multi-part channel EXR (not tested)
+ - [x] Saving multi-part channel EXR (not tested)
+ - [ ] Loading deep image
+ - [ ] Saving deep image
+- Optimization
+ - [x] C++11 thread loading
+ - [ ] C++11 thread saving
+ - [ ] ISPC?
+ - [x] OpenMP multi-threading in EXR loading.
+ - [x] OpenMP multi-threading in EXR saving.
+ - [ ] OpenMP multi-threading in deep image loading.
+ - [ ] OpenMP multi-threading in deep image saving.
+* C interface.
+ * You can easily write language bindings (e.g. golang)
+
+# Supported platform
+
+* [x] x86-64
+ * [x] Windows 7 or later
+ * [x] Linux(posix) system
+ * [x] macOS
+* [x] AARCH64
+ * [x] aarch64 linux(e.g. Raspberry Pi)
+ * [x] Android
+ * [x] iOS
+ * [x] macOS
+* [ ] RISC-V(Should work)
+* [x] Big endian machine(not maintained, but should work)
+ * SPARC, PowerPC, ...
+* [x] WebAssembly(JavaScript)
+ * Loader only(See ![js](experimental/js/))
+* [x] Python binding
+ * Loader only https://pypi.org/project/pytinyexr/
+
+# Requirements
+
+* C++ compiler(C++11 recommended. C++03 may work)
+
+# Use case
+
+## New TinyEXR (v0.9.5+)
+
+* Godot. Multi-platform 2D and 3D game engine https://godotengine.org/
+* Filament. PBR engine(used in a converter tool). https://github.com/google/filament
+* PyEXR. Loading OpenEXR (.exr) images using Python. https://github.com/ialhashim/PyEXR
+* The-Forge. The Forge Cross-Platform Rendering Framework PC, Linux, Ray Tracing, macOS / iOS, Android, XBOX, PS4 https://github.com/ConfettiFX/The-Forge
+* Your project here!
+
+## Older TinyEXR (v0.9.0)
+
+* mallie https://github.com/lighttransport/mallie
+* Cinder 0.9.0 https://libcinder.org/notes/v0.9.0
+* Piccante (develop branch) http://piccantelib.net/
+* Your project here!
+
+## Examples
+
+* [examples/deepview/](examples/deepview) Deep image view
+* [examples/rgbe2exr/](examples/rgbe2exr) .hdr to EXR converter
+* [examples/exr2rgbe/](examples/exr2rgbe) EXR to .hdr converter
+* [examples/ldr2exr/](examples/exr2rgbe) LDR to EXR converter
+* [examples/exr2ldr/](examples/exr2ldr) EXR to LDR converter
+* [examples/exr2fptiff/](examples/exr2fptiff) EXR to 32bit floating point TIFF converter
+ * for 32bit floating point TIFF to EXR convert, see https://github.com/syoyo/tinydngloader/tree/master/examples/fptiff2exr
+* [examples/cube2longlat/](examples/cube2longlat) Cubemap to longlat (equirectangler) converter
+
+## Experimental
+
+* [experimental/js/](experimental/js) JavaScript port using Emscripten
+
+## Usage
+
+NOTE: **API is still subject to change**. See the source code for details.
+
+Include `tinyexr.h` with `TINYEXR_IMPLEMENTATION` flag (do this only for **one** .cc file).
+
+```cpp
+//Please include your own zlib-compatible API header before
+//including `tinyexr.h` when you disable `TINYEXR_USE_MINIZ`
+//#define TINYEXR_USE_MINIZ 0
+//#include "zlib.h"
+#define TINYEXR_IMPLEMENTATION
+#include "tinyexr.h"
+```
+
+### Compile flags
+
+* `TINYEXR_USE_MINIZ` Use miniz (default = 1). Please include `zlib.h` header before `tinyexr.h` if you disable miniz support(e.g. use system's zlib).
+* `TINYEXR_USE_PIZ` Enable PIZ compression support (default = 1)
+* `TINYEXR_USE_ZFP` Enable ZFP compression supoort (TinyEXR extension, default = 0)
+* `TINYEXR_USE_THREAD` Enable threaded loading using C++11 thread (Requires C++11 compiler, default = 0)
+* `TINYEXR_USE_OPENMP` Enable OpenMP threading support (default = 1 if `_OPENMP` is defined)
+ * Use `TINYEXR_USE_OPENMP=0` to force disable OpenMP code path even if OpenMP is available/enabled in the compiler.
+
+### Quickly reading RGB(A) EXR file.
+
+```cpp
+ const char* input = "asakusa.exr";
+ float* out; // width * height * RGBA
+ int width;
+ int height;
+ const char* err = NULL; // or nullptr in C++11
+
+ int ret = LoadEXR(&out, &width, &height, input, &err);
+
+ if (ret != TINYEXR_SUCCESS) {
+ if (err) {
+ fprintf(stderr, "ERR : %s\n", err);
+ FreeEXRErrorMessage(err); // release memory of error message.
+ }
+ } else {
+ ...
+ free(out); // release memory of image data
+ }
+
+```
+
+### Reading layered RGB(A) EXR file.
+
+If you want to read EXR image with layer info (channel has a name with delimiter `.`), please use `LoadEXRWithLayer` API.
+
+You need to know layer name in advance (e.g. through `EXRLayers` API).
+
+```cpp
+ const char* input = ...;
+ const char* layer_name = "diffuse"; // or use EXRLayers to get list of layer names in .exr
+ float* out; // width * height * RGBA
+ int width;
+ int height;
+ const char* err = NULL; // or nullptr in C++11
+
+ // will read `diffuse.R`, `diffuse.G`, `diffuse.B`, (`diffuse.A`) channels
+ int ret = LoadEXRWithLayer(&out, &width, &height, input, layer_name, &err);
+
+ if (ret != TINYEXR_SUCCESS) {
+ if (err) {
+ fprintf(stderr, "ERR : %s\n", err);
+ FreeEXRErrorMessage(err); // release memory of error message.
+ }
+ } else {
+ ...
+ free(out); // release memory of image data
+ }
+
+```
+
+### Loading Singlepart EXR from a file.
+
+Scanline and tiled format are supported.
+
+```cpp
+ // 1. Read EXR version.
+ EXRVersion exr_version;
+
+ int ret = ParseEXRVersionFromFile(&exr_version, argv[1]);
+ if (ret != 0) {
+ fprintf(stderr, "Invalid EXR file: %s\n", argv[1]);
+ return -1;
+ }
+
+ if (exr_version.multipart) {
+ // must be multipart flag is false.
+ return -1;
+ }
+
+ // 2. Read EXR header
+ EXRHeader exr_header;
+ InitEXRHeader(&exr_header);
+
+ const char* err = NULL; // or `nullptr` in C++11 or later.
+ ret = ParseEXRHeaderFromFile(&exr_header, &exr_version, argv[1], &err);
+ if (ret != 0) {
+ fprintf(stderr, "Parse EXR err: %s\n", err);
+ FreeEXRErrorMessage(err); // free's buffer for an error message
+ return ret;
+ }
+
+ // // Read HALF channel as FLOAT.
+ // for (int i = 0; i < exr_header.num_channels; i++) {
+ // if (exr_header.pixel_types[i] == TINYEXR_PIXELTYPE_HALF) {
+ // exr_header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
+ // }
+ // }
+
+ EXRImage exr_image;
+ InitEXRImage(&exr_image);
+
+ ret = LoadEXRImageFromFile(&exr_image, &exr_header, argv[1], &err);
+ if (ret != 0) {
+ fprintf(stderr, "Load EXR err: %s\n", err);
+ FreeEXRHeader(&exr_header);
+ FreeEXRErrorMessage(err); // free's buffer for an error message
+ return ret;
+ }
+
+ // 3. Access image data
+ // `exr_image.images` will be filled when EXR is scanline format.
+ // `exr_image.tiled` will be filled when EXR is tiled format.
+
+ // 4. Free image data
+ FreeEXRImage(&exr_image);
+ FreeEXRHeader(&exr_header);
+```
+
+### Loading Multipart EXR from a file.
+
+Scanline and tiled format are supported.
+
+```cpp
+ // 1. Read EXR version.
+ EXRVersion exr_version;
+
+ int ret = ParseEXRVersionFromFile(&exr_version, argv[1]);
+ if (ret != 0) {
+ fprintf(stderr, "Invalid EXR file: %s\n", argv[1]);
+ return -1;
+ }
+
+ if (!exr_version.multipart) {
+ // must be multipart flag is true.
+ return -1;
+ }
+
+ // 2. Read EXR headers in the EXR.
+ EXRHeader **exr_headers; // list of EXRHeader pointers.
+ int num_exr_headers;
+ const char *err = NULL; // or nullptr in C++11 or later
+
+ // Memory for EXRHeader is allocated inside of ParseEXRMultipartHeaderFromFile,
+ ret = ParseEXRMultipartHeaderFromFile(&exr_headers, &num_exr_headers, &exr_version, argv[1], &err);
+ if (ret != 0) {
+ fprintf(stderr, "Parse EXR err: %s\n", err);
+ FreeEXRErrorMessage(err); // free's buffer for an error message
+ return ret;
+ }
+
+ printf("num parts = %d\n", num_exr_headers);
+
+
+ // 3. Load images.
+
+ // Prepare array of EXRImage.
+ std::vector<EXRImage> images(num_exr_headers);
+ for (int i =0; i < num_exr_headers; i++) {
+ InitEXRImage(&images[i]);
+ }
+
+ ret = LoadEXRMultipartImageFromFile(&images.at(0), const_cast<const EXRHeader**>(exr_headers), num_exr_headers, argv[1], &err);
+ if (ret != 0) {
+ fprintf(stderr, "Parse EXR err: %s\n", err);
+ FreeEXRErrorMessage(err); // free's buffer for an error message
+ return ret;
+ }
+
+ printf("Loaded %d part images\n", num_exr_headers);
+
+ // 4. Access image data
+ // `exr_image.images` will be filled when EXR is scanline format.
+ // `exr_image.tiled` will be filled when EXR is tiled format.
+
+ // 5. Free images
+ for (int i =0; i < num_exr_headers; i++) {
+ FreeEXRImage(&images.at(i));
+ }
+
+ // 6. Free headers.
+ for (int i =0; i < num_exr_headers; i++) {
+ FreeEXRHeader(exr_headers[i]);
+ free(exr_headers[i]);
+ }
+ free(exr_headers);
+```
+
+
+Saving Scanline EXR file.
+
+```cpp
+ // See `examples/rgbe2exr/` for more details.
+ bool SaveEXR(const float* rgb, int width, int height, const char* outfilename) {
+
+ EXRHeader header;
+ InitEXRHeader(&header);
+
+ EXRImage image;
+ InitEXRImage(&image);
+
+ image.num_channels = 3;
+
+ std::vector<float> images[3];
+ images[0].resize(width * height);
+ images[1].resize(width * height);
+ images[2].resize(width * height);
+
+ // Split RGBRGBRGB... into R, G and B layer
+ for (int i = 0; i < width * height; i++) {
+ images[0][i] = rgb[3*i+0];
+ images[1][i] = rgb[3*i+1];
+ images[2][i] = rgb[3*i+2];
+ }
+
+ float* image_ptr[3];
+ image_ptr[0] = &(images[2].at(0)); // B
+ image_ptr[1] = &(images[1].at(0)); // G
+ image_ptr[2] = &(images[0].at(0)); // R
+
+ image.images = (unsigned char**)image_ptr;
+ image.width = width;
+ image.height = height;
+
+ header.num_channels = 3;
+ header.channels = (EXRChannelInfo *)malloc(sizeof(EXRChannelInfo) * header.num_channels);
+ // Must be (A)BGR order, since most of EXR viewers expect this channel order.
+ strncpy(header.channels[0].name, "B", 255); header.channels[0].name[strlen("B")] = '\0';
+ strncpy(header.channels[1].name, "G", 255); header.channels[1].name[strlen("G")] = '\0';
+ strncpy(header.channels[2].name, "R", 255); header.channels[2].name[strlen("R")] = '\0';
+
+ header.pixel_types = (int *)malloc(sizeof(int) * header.num_channels);
+ header.requested_pixel_types = (int *)malloc(sizeof(int) * header.num_channels);
+ for (int i = 0; i < header.num_channels; i++) {
+ header.pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image
+ header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_HALF; // pixel type of output image to be stored in .EXR
+ }
+
+ const char* err = NULL; // or nullptr in C++11 or later.
+ int ret = SaveEXRImageToFile(&image, &header, outfilename, &err);
+ if (ret != TINYEXR_SUCCESS) {
+ fprintf(stderr, "Save EXR err: %s\n", err);
+ FreeEXRErrorMessage(err); // free's buffer for an error message
+ return ret;
+ }
+ printf("Saved exr file. [ %s ] \n", outfilename);
+
+ free(rgb);
+
+ free(header.channels);
+ free(header.pixel_types);
+ free(header.requested_pixel_types);
+
+ }
+```
+
+
+Reading deep image EXR file.
+See `example/deepview` for actual usage.
+
+```cpp
+ const char* input = "deepimage.exr";
+ const char* err = NULL; // or nullptr
+ DeepImage deepImage;
+
+ int ret = LoadDeepEXR(&deepImage, input, &err);
+
+ // access to each sample in the deep pixel.
+ for (int y = 0; y < deepImage.height; y++) {
+ int sampleNum = deepImage.offset_table[y][deepImage.width-1];
+ for (int x = 0; x < deepImage.width-1; x++) {
+ int s_start = deepImage.offset_table[y][x];
+ int s_end = deepImage.offset_table[y][x+1];
+ if (s_start >= sampleNum) {
+ continue;
+ }
+ s_end = (s_end < sampleNum) ? s_end : sampleNum;
+ for (int s = s_start; s < s_end; s++) {
+ float val = deepImage.image[depthChan][y][s];
+ ...
+ }
+ }
+ }
+
+```
+
+### deepview
+
+`examples/deepview` is simple deep image viewer in OpenGL.
+
+![DeepViewExample](https://github.com/syoyo/tinyexr/blob/master/examples/deepview/deepview_screencast.gif?raw=true)
+
+## TinyEXR extension
+
+### ZFP
+
+#### NOTE
+
+TinyEXR adds ZFP compression as an experimemtal support (Linux and MacOSX only).
+
+ZFP only supports FLOAT format pixel, and its image width and height must be the multiple of 4, since ZFP compresses pixels with 4x4 pixel block.
+
+#### Setup
+
+Checkout zfp repo as an submodule.
+
+ $ git submodule update --init
+
+#### Build
+
+Then build ZFP
+
+ $ cd deps/ZFP
+ $ mkdir -p lib # Create `lib` directory if not exist
+ $ make
+
+Set `1` to `TINYEXT_USE_ZFP` define in `tinyexr.h`
+
+Build your app with linking `deps/ZFP/lib/libzfp.a`
+
+#### ZFP attribute
+
+For ZFP EXR image, the following attribute must exist in its EXR image.
+
+* `zfpCompressionType` (uchar).
+ * 0 = fixed rate compression
+ * 1 = precision based variable rate compression
+ * 2 = accuracy based variable rate compression
+
+And the one of following attributes must exist in EXR, depending on the `zfpCompressionType` value.
+
+* `zfpCompressionRate` (double)
+ * Specifies compression rate for fixed rate compression.
+* `zfpCompressionPrecision` (int32)
+ * Specifies the number of bits for precision based variable rate compression.
+* `zfpCompressionTolerance` (double)
+ * Specifies the tolerance value for accuracy based variable rate compression.
+
+#### Note on ZFP compression.
+
+At least ZFP code itself works well on big endian machine.
+
+## Unit tests
+
+See `test/unit` directory.
+
+## TODO
+
+Contribution is welcome!
+
+- [ ] Compression
+ - [ ] B44?
+ - [ ] B44A?
+ - [ ] PIX24?
+- [ ] Custom attributes
+ - [x] Normal image (EXR 1.x)
+ - [ ] Deep image (EXR 2.x)
+- [ ] JavaScript library (experimental, using Emscripten)
+ - [x] LoadEXRFromMemory
+ - [ ] SaveMultiChannelEXR
+ - [ ] Deep image save/load
+- [ ] Write from/to memory buffer.
+ - [ ] Deep image save/load
+- [ ] Tile format.
+ - [x] Tile format with no LoD (load).
+ - [ ] Tile format with LoD (load).
+ - [ ] Tile format with no LoD (save).
+ - [ ] Tile format with LoD (save).
+- [ ] Support for custom compression type.
+ - [x] zfp compression (Not in OpenEXR spec, though)
+ - [ ] zstd?
+- [x] Multi-channel.
+- [ ] Multi-part (EXR2.0)
+ - [x] Load multi-part image
+ - [ ] Load multi-part deep image
+- [ ] Line order.
+ - [x] Increasing, decreasing (load)
+ - [ ] Random?
+ - [ ] Increasing, decreasing (save)
+- [ ] Pixel format (UINT, FLOAT).
+ - [x] UINT, FLOAT (load)
+ - [x] UINT, FLOAT (deep load)
+ - [x] UINT, FLOAT (save)
+ - [ ] UINT, FLOAT (deep save)
+- [ ] Support for big endian machine.
+ - [ ] Loading multi-part channel EXR
+ - [ ] Saving multi-part channel EXR
+ - [ ] Loading deep image
+ - [ ] Saving deep image
+- [ ] Optimization
+ - [ ] ISPC?
+ - [x] OpenMP multi-threading in EXR loading.
+ - [x] OpenMP multi-threading in EXR saving.
+ - [ ] OpenMP multi-threading in deep image loading.
+ - [ ] OpenMP multi-threading in deep image saving.
+
+## Python bindings
+
+`pytinyexr` is available: https://pypi.org/project/pytinyexr/ (loading only as of 0.9.1)
+
+## Similar or related projects
+
+* miniexr: https://github.com/aras-p/miniexr (Write OpenEXR)
+* stb_image_resize.h: https://github.com/nothings/stb (Good for HDR image resizing)
+
+## License
+
+3-clause BSD
+
+`tinyexr` uses miniz, which is developed by Rich Geldreich <richgel99@gmail.com>, and licensed under public domain.
+
+`tinyexr` tools uses stb, which is licensed under public domain: https://github.com/nothings/stb
+`tinyexr` uses some code from OpenEXR, which is licensed under 3-clause BSD license.
+
+## Author(s)
+
+Syoyo Fujita (syoyo@lighttransport.com)
+
+## Contributor(s)
+
+* Matt Ebb (http://mattebb.com): deep image example. Thanks!
+* Matt Pharr (http://pharr.org/matt/): Testing tinyexr with OpenEXR(IlmImf). Thanks!
+* Andrew Bell (https://github.com/andrewfb) & Richard Eakin (https://github.com/richardeakin): Improving TinyEXR API. Thanks!
+* Mike Wong (https://github.com/mwkm): ZIPS compression support in loading. Thanks!
diff --git a/graphics/asymptote/cudareflect/tinyexr/appveyor.yml b/graphics/asymptote/cudareflect/tinyexr/appveyor.yml
new file mode 100644
index 0000000000..c63267fe8b
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/appveyor.yml
@@ -0,0 +1,13 @@
+version: 0.9.{build}
+
+platform: x64
+configuration: Release
+
+before_build:
+ - echo running cmake...
+ - cd test
+ - cmake -G "Visual Studio 12 Win64" -Bbuild -H..
+
+build:
+ parallel: true
+ project: C:\projects\tinyexr\test\build\tinyexr.sln
diff --git a/graphics/asymptote/cudareflect/tinyexr/asakusa.exr b/graphics/asymptote/cudareflect/tinyexr/asakusa.exr
new file mode 100644
index 0000000000..ae7f38ad34
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/asakusa.exr
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/asakusa.png b/graphics/asymptote/cudareflect/tinyexr/asakusa.png
new file mode 100644
index 0000000000..7183d5f01c
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/asakusa.png
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindASan.cmake b/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindASan.cmake
new file mode 100644
index 0000000000..98ea7cb311
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindASan.cmake
@@ -0,0 +1,59 @@
+# The MIT License (MIT)
+#
+# Copyright (c)
+# 2013 Matthew Arsenault
+# 2015-2016 RWTH Aachen University, Federal Republic of Germany
+#
+# 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
+# AUTHORS OR COPYRIGHT HOLDERS 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.
+
+option(SANITIZE_ADDRESS "Enable AddressSanitizer for sanitized targets." Off)
+
+set(FLAG_CANDIDATES
+ # Clang 3.2+ use this version. The no-omit-frame-pointer option is optional.
+ "-g -fsanitize=address -fno-omit-frame-pointer"
+ "-g -fsanitize=address"
+
+ # Older deprecated flag for ASan
+ "-g -faddress-sanitizer"
+)
+
+
+if (SANITIZE_ADDRESS AND (SANITIZE_THREAD OR SANITIZE_MEMORY))
+ message(FATAL_ERROR "AddressSanitizer is not compatible with "
+ "ThreadSanitizer or MemorySanitizer.")
+endif ()
+
+
+include(sanitize-helpers)
+
+if (SANITIZE_ADDRESS)
+ sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "AddressSanitizer"
+ "ASan")
+
+ find_program(ASan_WRAPPER "asan-wrapper" PATHS ${CMAKE_MODULE_PATH})
+ mark_as_advanced(ASan_WRAPPER)
+endif ()
+
+function (add_sanitize_address TARGET)
+ if (NOT SANITIZE_ADDRESS)
+ return()
+ endif ()
+
+ sanitizer_add_flags(${TARGET} "AddressSanitizer" "ASan")
+endfunction ()
diff --git a/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindMSan.cmake b/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindMSan.cmake
new file mode 100644
index 0000000000..22d0050e97
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindMSan.cmake
@@ -0,0 +1,57 @@
+# The MIT License (MIT)
+#
+# Copyright (c)
+# 2013 Matthew Arsenault
+# 2015-2016 RWTH Aachen University, Federal Republic of Germany
+#
+# 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
+# AUTHORS OR COPYRIGHT HOLDERS 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.
+
+option(SANITIZE_MEMORY "Enable MemorySanitizer for sanitized targets." Off)
+
+set(FLAG_CANDIDATES
+ "-g -fsanitize=memory"
+)
+
+
+include(sanitize-helpers)
+
+if (SANITIZE_MEMORY)
+ if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
+ message(WARNING "MemorySanitizer disabled for target ${TARGET} because "
+ "MemorySanitizer is supported for Linux systems only.")
+ set(SANITIZE_MEMORY Off CACHE BOOL
+ "Enable MemorySanitizer for sanitized targets." FORCE)
+ elseif (NOT ${CMAKE_SIZEOF_VOID_P} EQUAL 8)
+ message(WARNING "MemorySanitizer disabled for target ${TARGET} because "
+ "MemorySanitizer is supported for 64bit systems only.")
+ set(SANITIZE_MEMORY Off CACHE BOOL
+ "Enable MemorySanitizer for sanitized targets." FORCE)
+ else ()
+ sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "MemorySanitizer"
+ "MSan")
+ endif ()
+endif ()
+
+function (add_sanitize_memory TARGET)
+ if (NOT SANITIZE_MEMORY)
+ return()
+ endif ()
+
+ sanitizer_add_flags(${TARGET} "MemorySanitizer" "MSan")
+endfunction ()
diff --git a/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindSanitizers.cmake b/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindSanitizers.cmake
new file mode 100644
index 0000000000..101bab8439
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindSanitizers.cmake
@@ -0,0 +1,94 @@
+# The MIT License (MIT)
+#
+# Copyright (c)
+# 2013 Matthew Arsenault
+# 2015-2016 RWTH Aachen University, Federal Republic of Germany
+#
+# 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
+# AUTHORS OR COPYRIGHT HOLDERS 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.
+
+# If any of the used compiler is a GNU compiler, add a second option to static
+# link against the sanitizers.
+option(SANITIZE_LINK_STATIC "Try to link static against sanitizers." Off)
+
+
+
+
+set(FIND_QUIETLY_FLAG "")
+if (DEFINED Sanitizers_FIND_QUIETLY)
+ set(FIND_QUIETLY_FLAG "QUIET")
+endif ()
+
+find_package(ASan ${FIND_QUIETLY_FLAG})
+find_package(TSan ${FIND_QUIETLY_FLAG})
+find_package(MSan ${FIND_QUIETLY_FLAG})
+find_package(UBSan ${FIND_QUIETLY_FLAG})
+
+
+
+
+function(sanitizer_add_blacklist_file FILE)
+ if(NOT IS_ABSOLUTE ${FILE})
+ set(FILE "${CMAKE_CURRENT_SOURCE_DIR}/${FILE}")
+ endif()
+ get_filename_component(FILE "${FILE}" REALPATH)
+
+ sanitizer_check_compiler_flags("-fsanitize-blacklist=${FILE}"
+ "SanitizerBlacklist" "SanBlist")
+endfunction()
+
+function(add_sanitizers ...)
+ # If no sanitizer is enabled, return immediately.
+ if (NOT (SANITIZE_ADDRESS OR SANITIZE_MEMORY OR SANITIZE_THREAD OR
+ SANITIZE_UNDEFINED))
+ return()
+ endif ()
+
+ foreach (TARGET ${ARGV})
+ # Check if this target will be compiled by exactly one compiler. Other-
+ # wise sanitizers can't be used and a warning should be printed once.
+ get_target_property(TARGET_TYPE ${TARGET} TYPE)
+ if (TARGET_TYPE STREQUAL "INTERFACE_LIBRARY")
+ message(WARNING "Can't use any sanitizers for target ${TARGET}, "
+ "because it is an interface library and cannot be "
+ "compiled directly.")
+ return()
+ endif ()
+ sanitizer_target_compilers(${TARGET} TARGET_COMPILER)
+ list(LENGTH TARGET_COMPILER NUM_COMPILERS)
+ if (NUM_COMPILERS GREATER 1)
+ message(WARNING "Can't use any sanitizers for target ${TARGET}, "
+ "because it will be compiled by incompatible compilers. "
+ "Target will be compiled without sanitizers.")
+ return()
+
+ # If the target is compiled by no or no known compiler, give a warning.
+ elseif (NUM_COMPILERS EQUAL 0)
+ message(WARNING "Sanitizers for target ${TARGET} may not be"
+ " usable, because it uses no or an unknown compiler. "
+ "This is a false warning for targets using only "
+ "object lib(s) as input.")
+ endif ()
+
+ # Add sanitizers for target.
+ add_sanitize_address(${TARGET})
+ add_sanitize_thread(${TARGET})
+ add_sanitize_memory(${TARGET})
+ add_sanitize_undefined(${TARGET})
+ endforeach ()
+endfunction(add_sanitizers)
diff --git a/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindTSan.cmake b/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindTSan.cmake
new file mode 100644
index 0000000000..3cba3c03b6
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindTSan.cmake
@@ -0,0 +1,65 @@
+# The MIT License (MIT)
+#
+# Copyright (c)
+# 2013 Matthew Arsenault
+# 2015-2016 RWTH Aachen University, Federal Republic of Germany
+#
+# 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
+# AUTHORS OR COPYRIGHT HOLDERS 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.
+
+option(SANITIZE_THREAD "Enable ThreadSanitizer for sanitized targets." Off)
+
+set(FLAG_CANDIDATES
+ "-g -fsanitize=thread"
+)
+
+
+# ThreadSanitizer is not compatible with MemorySanitizer.
+if (SANITIZE_THREAD AND SANITIZE_MEMORY)
+ message(FATAL_ERROR "ThreadSanitizer is not compatible with "
+ "MemorySanitizer.")
+endif ()
+
+
+include(sanitize-helpers)
+
+if (SANITIZE_THREAD)
+ if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND
+ NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
+ message(WARNING "ThreadSanitizer disabled for target ${TARGET} because "
+ "ThreadSanitizer is supported for Linux systems and macOS only.")
+ set(SANITIZE_THREAD Off CACHE BOOL
+ "Enable ThreadSanitizer for sanitized targets." FORCE)
+ elseif (NOT ${CMAKE_SIZEOF_VOID_P} EQUAL 8)
+ message(WARNING "ThreadSanitizer disabled for target ${TARGET} because "
+ "ThreadSanitizer is supported for 64bit systems only.")
+ set(SANITIZE_THREAD Off CACHE BOOL
+ "Enable ThreadSanitizer for sanitized targets." FORCE)
+ else ()
+ sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "ThreadSanitizer"
+ "TSan")
+ endif ()
+endif ()
+
+function (add_sanitize_thread TARGET)
+ if (NOT SANITIZE_THREAD)
+ return()
+ endif ()
+
+ sanitizer_add_flags(${TARGET} "ThreadSanitizer" "TSan")
+endfunction ()
diff --git a/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindUBSan.cmake b/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindUBSan.cmake
new file mode 100644
index 0000000000..ae103f7172
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/FindUBSan.cmake
@@ -0,0 +1,46 @@
+# The MIT License (MIT)
+#
+# Copyright (c)
+# 2013 Matthew Arsenault
+# 2015-2016 RWTH Aachen University, Federal Republic of Germany
+#
+# 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
+# AUTHORS OR COPYRIGHT HOLDERS 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.
+
+option(SANITIZE_UNDEFINED
+ "Enable UndefinedBehaviorSanitizer for sanitized targets." Off)
+
+set(FLAG_CANDIDATES
+ "-g -fsanitize=undefined"
+)
+
+
+include(sanitize-helpers)
+
+if (SANITIZE_UNDEFINED)
+ sanitizer_check_compiler_flags("${FLAG_CANDIDATES}"
+ "UndefinedBehaviorSanitizer" "UBSan")
+endif ()
+
+function (add_sanitize_undefined TARGET)
+ if (NOT SANITIZE_UNDEFINED)
+ return()
+ endif ()
+
+ sanitizer_add_flags(${TARGET} "UndefinedBehaviorSanitizer" "UBSan")
+endfunction ()
diff --git a/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/asan-wrapper b/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/asan-wrapper
new file mode 100644
index 0000000000..5d54103372
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/asan-wrapper
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+# The MIT License (MIT)
+#
+# Copyright (c)
+# 2013 Matthew Arsenault
+# 2015-2016 RWTH Aachen University, Federal Republic of Germany
+#
+# 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
+# AUTHORS OR COPYRIGHT HOLDERS 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.
+
+# This script is a wrapper for AddressSanitizer. In some special cases you need
+# to preload AddressSanitizer to avoid error messages - e.g. if you're
+# preloading another library to your application. At the moment this script will
+# only do something, if we're running on a Linux platform. OSX might not be
+# affected.
+
+
+# Exit immediately, if platform is not Linux.
+if [ "$(uname)" != "Linux" ]
+then
+ exec $@
+fi
+
+
+# Get the used libasan of the application ($1). If a libasan was found, it will
+# be prepended to LD_PRELOAD.
+libasan=$(ldd $1 | grep libasan | sed "s/^[[:space:]]//" | cut -d' ' -f1)
+if [ -n "$libasan" ]
+then
+ if [ -n "$LD_PRELOAD" ]
+ then
+ export LD_PRELOAD="$libasan:$LD_PRELOAD"
+ else
+ export LD_PRELOAD="$libasan"
+ fi
+fi
+
+# Execute the application.
+exec $@
diff --git a/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/sanitize-helpers.cmake b/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/sanitize-helpers.cmake
new file mode 100644
index 0000000000..3649b07423
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/cmake/sanitizers/sanitize-helpers.cmake
@@ -0,0 +1,177 @@
+# The MIT License (MIT)
+#
+# Copyright (c)
+# 2013 Matthew Arsenault
+# 2015-2016 RWTH Aachen University, Federal Republic of Germany
+#
+# 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
+# AUTHORS OR COPYRIGHT HOLDERS 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.
+
+# Helper function to get the language of a source file.
+function (sanitizer_lang_of_source FILE RETURN_VAR)
+ get_filename_component(LONGEST_EXT "${FILE}" EXT)
+ # If extension is empty return. This can happen for extensionless headers
+ if("${LONGEST_EXT}" STREQUAL "")
+ set(${RETURN_VAR} "" PARENT_SCOPE)
+ return()
+ endif()
+ # Get shortest extension as some files can have dot in their names
+ string(REGEX REPLACE "^.*(\\.[^.]+)$" "\\1" FILE_EXT ${LONGEST_EXT})
+ string(TOLOWER "${FILE_EXT}" FILE_EXT)
+ string(SUBSTRING "${FILE_EXT}" 1 -1 FILE_EXT)
+
+ get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
+ foreach (LANG ${ENABLED_LANGUAGES})
+ list(FIND CMAKE_${LANG}_SOURCE_FILE_EXTENSIONS "${FILE_EXT}" TEMP)
+ if (NOT ${TEMP} EQUAL -1)
+ set(${RETURN_VAR} "${LANG}" PARENT_SCOPE)
+ return()
+ endif ()
+ endforeach()
+
+ set(${RETURN_VAR} "" PARENT_SCOPE)
+endfunction ()
+
+
+# Helper function to get compilers used by a target.
+function (sanitizer_target_compilers TARGET RETURN_VAR)
+ # Check if all sources for target use the same compiler. If a target uses
+ # e.g. C and Fortran mixed and uses different compilers (e.g. clang and
+ # gfortran) this can trigger huge problems, because different compilers may
+ # use different implementations for sanitizers.
+ set(BUFFER "")
+ get_target_property(TSOURCES ${TARGET} SOURCES)
+ foreach (FILE ${TSOURCES})
+ # If expression was found, FILE is a generator-expression for an object
+ # library. Object libraries will be ignored.
+ string(REGEX MATCH "TARGET_OBJECTS:([^ >]+)" _file ${FILE})
+ if ("${_file}" STREQUAL "")
+ sanitizer_lang_of_source(${FILE} LANG)
+ if (LANG)
+ list(APPEND BUFFER ${CMAKE_${LANG}_COMPILER_ID})
+ endif ()
+ endif ()
+ endforeach ()
+
+ list(REMOVE_DUPLICATES BUFFER)
+ set(${RETURN_VAR} "${BUFFER}" PARENT_SCOPE)
+endfunction ()
+
+
+# Helper function to check compiler flags for language compiler.
+function (sanitizer_check_compiler_flag FLAG LANG VARIABLE)
+ if (${LANG} STREQUAL "C")
+ include(CheckCCompilerFlag)
+ check_c_compiler_flag("${FLAG}" ${VARIABLE})
+
+ elseif (${LANG} STREQUAL "CXX")
+ include(CheckCXXCompilerFlag)
+ check_cxx_compiler_flag("${FLAG}" ${VARIABLE})
+
+ elseif (${LANG} STREQUAL "Fortran")
+ # CheckFortranCompilerFlag was introduced in CMake 3.x. To be compatible
+ # with older Cmake versions, we will check if this module is present
+ # before we use it. Otherwise we will define Fortran coverage support as
+ # not available.
+ include(CheckFortranCompilerFlag OPTIONAL RESULT_VARIABLE INCLUDED)
+ if (INCLUDED)
+ check_fortran_compiler_flag("${FLAG}" ${VARIABLE})
+ elseif (NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VARIABLE}")
+ message(STATUS "Performing Test ${VARIABLE}"
+ " - Failed (Check not supported)")
+ endif ()
+ endif()
+endfunction ()
+
+
+# Helper function to test compiler flags.
+function (sanitizer_check_compiler_flags FLAG_CANDIDATES NAME PREFIX)
+ set(CMAKE_REQUIRED_QUIET ${${PREFIX}_FIND_QUIETLY})
+
+ get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
+ foreach (LANG ${ENABLED_LANGUAGES})
+ # Sanitizer flags are not dependend on language, but the used compiler.
+ # So instead of searching flags foreach language, search flags foreach
+ # compiler used.
+ set(COMPILER ${CMAKE_${LANG}_COMPILER_ID})
+ if (NOT DEFINED ${PREFIX}_${COMPILER}_FLAGS)
+ foreach (FLAG ${FLAG_CANDIDATES})
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Try ${COMPILER} ${NAME} flag = [${FLAG}]")
+ endif()
+
+ set(CMAKE_REQUIRED_FLAGS "${FLAG}")
+ unset(${PREFIX}_FLAG_DETECTED CACHE)
+ sanitizer_check_compiler_flag("${FLAG}" ${LANG}
+ ${PREFIX}_FLAG_DETECTED)
+
+ if (${PREFIX}_FLAG_DETECTED)
+ # If compiler is a GNU compiler, search for static flag, if
+ # SANITIZE_LINK_STATIC is enabled.
+ if (SANITIZE_LINK_STATIC AND (${COMPILER} STREQUAL "GNU"))
+ string(TOLOWER ${PREFIX} PREFIX_lower)
+ sanitizer_check_compiler_flag(
+ "-static-lib${PREFIX_lower}" ${LANG}
+ ${PREFIX}_STATIC_FLAG_DETECTED)
+
+ if (${PREFIX}_STATIC_FLAG_DETECTED)
+ set(FLAG "-static-lib${PREFIX_lower} ${FLAG}")
+ endif ()
+ endif ()
+
+ set(${PREFIX}_${COMPILER}_FLAGS "${FLAG}" CACHE STRING
+ "${NAME} flags for ${COMPILER} compiler.")
+ mark_as_advanced(${PREFIX}_${COMPILER}_FLAGS)
+ break()
+ endif ()
+ endforeach ()
+
+ if (NOT ${PREFIX}_FLAG_DETECTED)
+ set(${PREFIX}_${COMPILER}_FLAGS "" CACHE STRING
+ "${NAME} flags for ${COMPILER} compiler.")
+ mark_as_advanced(${PREFIX}_${COMPILER}_FLAGS)
+
+ message(WARNING "${NAME} is not available for ${COMPILER} "
+ "compiler. Targets using this compiler will be "
+ "compiled without ${NAME}.")
+ endif ()
+ endif ()
+ endforeach ()
+endfunction ()
+
+
+# Helper to assign sanitizer flags for TARGET.
+function (sanitizer_add_flags TARGET NAME PREFIX)
+ # Get list of compilers used by target and check, if sanitizer is available
+ # for this target. Other compiler checks like check for conflicting
+ # compilers will be done in add_sanitizers function.
+ sanitizer_target_compilers(${TARGET} TARGET_COMPILER)
+ list(LENGTH TARGET_COMPILER NUM_COMPILERS)
+ if ("${${PREFIX}_${TARGET_COMPILER}_FLAGS}" STREQUAL "")
+ return()
+ endif()
+
+ # Set compile- and link-flags for target.
+ set_property(TARGET ${TARGET} APPEND_STRING
+ PROPERTY COMPILE_FLAGS " ${${PREFIX}_${TARGET_COMPILER}_FLAGS}")
+ set_property(TARGET ${TARGET} APPEND_STRING
+ PROPERTY COMPILE_FLAGS " ${SanBlist_${TARGET_COMPILER}_FLAGS}")
+ set_property(TARGET ${TARGET} APPEND_STRING
+ PROPERTY LINK_FLAGS " ${${PREFIX}_${TARGET_COMPILER}_FLAGS}")
+endfunction ()
diff --git a/graphics/asymptote/cudareflect/tinyexr/config-msvc.py b/graphics/asymptote/cudareflect/tinyexr/config-msvc.py
new file mode 100644
index 0000000000..1b3a48c876
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/config-msvc.py
@@ -0,0 +1,78 @@
+exe = "test_tinyexr.exe"
+
+# "gnu" or "msvc" are provided as predefined toolchain
+toolchain = "msvc"
+
+# optional
+link_pool_depth = 1
+
+# optional
+builddir = {
+ "gnu" : "build"
+ , "msvc" : "build"
+ , "clang" : "build"
+ }
+
+# required
+includes = {
+ "gnu" : [ "-I." ]
+ , "msvc" : [ "/I." ]
+ , "clang" : [ "-I." ]
+ }
+
+# required
+defines = {
+ "gnu" : [ "-DEXAMPLE=1" ]
+ , "msvc" : [ "/DEXAMPLE=1" ]
+ , "clang" : [ "-DEXAMPLE=1" ]
+ }
+
+# required
+cflags = {
+ "gnu" : [ "-O2", "-g" ]
+ , "msvc" : [ "/O2" ]
+ , "clang" : [ "-O2", "-g" ]
+ }
+
+# required
+cxxflags = {
+ "gnu" : [ "-O2", "-g" ]
+ , "msvc" : [ "/O2", "/W4" ]
+ , "clang" : [ "-O2", "-g", "-fsanitize=address" ]
+ }
+
+# required
+ldflags = {
+ "gnu" : [ ]
+ , "msvc" : [ ]
+ , "clang" : [ "-fsanitize=address" ]
+ }
+
+# optionsl
+cxx_files = [ "test_tinyexr.cc" ]
+c_files = [ ]
+
+# You can register your own toolchain through register_toolchain function
+def register_toolchain(ninja):
+ pass
+
+ #ninja.rule('clangcxx', description='CXX $out',
+ # command='$clangcxx -MMD -MF $out.d $clangdefines $clangincludes $clangcxxflags -c $in -o $out',
+ # depfile='$out.d', deps='gcc')
+ #ninja.rule('clangcc', description='CC $out',
+ # command='$clangcc -MMD -MF $out.d $clangdefines $clangincludes $clangcflags -c $in -o $out',
+ # depfile='$out.d', deps='gcc')
+ #ninja.rule('clanglink', description='LINK $out', pool='link_pool',
+ # command='$clangld $clangldflags -o $out $in $libs')
+ #ninja.rule('clangar', description='AR $out', pool='link_pool',
+ # command='$clangar rsc $out $in')
+ #ninja.rule('clangstamp', description='STAMP $out', command='touch $out')
+ #ninja.newline()
+
+ #ninja.variable('clangcxx', 'clang++')
+ #ninja.variable('clangcc', 'clang')
+ #ninja.variable('clangld', 'clang++')
+ #ninja.variable('clangar', 'ar')
+ #ninja.newline()
+
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/deps/miniz/ChangeLog.md b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/ChangeLog.md
new file mode 100644
index 0000000000..4ae15a8cdf
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/ChangeLog.md
@@ -0,0 +1,196 @@
+## Changelog
+
+### 2.2.0
+
+ - Fix examples with amalgamation
+ - Modified cmake script to support shared library mode and find_package
+ - Fix for misleading doc comment on `mz_zip_reader_init_cfile` function
+ - Add include location tolerance and stop forcing `_GNU_SOURCE`
+ - Fix: mz_zip_reader_locate_file_v2 returns an mz_bool
+ - Fix large file system checks
+ - Add #elif to enable an external mz_crc32() to be linked in
+ - Write with dynamic size (size of file/data to be added not known before adding)
+ - Added uncompress2 for zlib compatibility
+ - Add support for building as a Meson subproject
+ - Added OSSFuzz support; Integrate with CIFuzz
+ - Add pkg-config file
+ - Fixed use-of-uninitialized value msan error when copying dist bytes with no output bytes written.
+ - mz_zip_validate_file(): fix memory leak on errors
+ - Fixed MSAN use-of-uninitialized in tinfl_decompress when invalid dist is decoded. In this instance dist was 31 which s_dist_base translates as 0
+ - Add flag to set (compressed) size in local file header
+ - avoid use of uninitialized value in tdefl_record_literal
+
+### 2.1.0
+
+ - More instances of memcpy instead of cast and use memcpy per default
+ - Remove inline for c90 support
+ - New function to read files via callback functions when adding them
+ - Fix out of bounds read while reading Zip64 extended information
+ - guard memcpy when n == 0 because buffer may be NULL
+ - Implement inflateReset() function
+ - Move comp/decomp alloc/free prototypes under guarding #ifndef MZ_NO_MALLOC
+ - Fix large file support under Windows
+ - Don't warn if _LARGEFILE64_SOURCE is not defined to 1
+ - Fixes for MSVC warnings
+ - Remove check that path of file added to archive contains ':' or '\'
+ - Add !defined check on MINIZ_USE_ALIGNED_LOADS_AND_STORES
+
+### 2.0.8
+
+ - Remove unimplemented functions (mz_zip_locate_file and mz_zip_locate_file_v2)
+ - Add license, changelog, readme and example files to release zip
+ - Fix heap overflow to user buffer in tinfl_status tinfl_decompress
+ - Fix corrupt archive if uncompressed file smaller than 4 byte and the file is added by mz_zip_writer_add_mem*
+
+### 2.0.7
+
+ - Removed need in C++ compiler in cmake build
+ - Fixed a lot of uninitialized value errors found with Valgrind by memsetting m_dict to 0 in tdefl_init
+ - Fix resource leak in mz_zip_reader_init_file_v2
+ - Fix assert with mz_zip_writer_add_mem* w/MZ_DEFAULT_COMPRESSION
+ - cmake build: install library and headers
+ - Remove _LARGEFILE64_SOURCE requirement from apple defines for large files
+
+### 2.0.6
+
+ - Improve MZ_ZIP_FLAG_WRITE_ZIP64 documentation
+ - Remove check for cur_archive_file_ofs > UINT_MAX because cur_archive_file_ofs is not used after this point
+ - Add cmake debug configuration
+ - Fix PNG height when creating png files
+ - Add "iterative" file extraction method based on mz_zip_reader_extract_to_callback.
+ - Option to use memcpy for unaligned data access
+ - Define processor/arch macros as zero if not set to one
+
+### 2.0.4/2.0.5
+
+ - Fix compilation with the various omission compile definitions
+
+### 2.0.3
+
+- Fix GCC/clang compile warnings
+- Added callback for periodic flushes (for ZIP file streaming)
+- Use UTF-8 for file names in ZIP files per default
+
+### 2.0.2
+
+- Fix source backwards compatibility with 1.x
+- Fix a ZIP bit not being set correctly
+
+### 2.0.1
+
+- Added some tests
+- Added CI
+- Make source code ANSI C compatible
+
+### 2.0.0 beta
+
+- Matthew Sitton merged miniz 1.x to Rich Geldreich's vogl ZIP64 changes. Miniz is now licensed as MIT since the vogl code base is MIT licensed
+- Miniz is now split into several files
+- Miniz does now not seek backwards when creating ZIP files. That is the ZIP files can be streamed
+- Miniz automatically switches to the ZIP64 format when the created ZIP files goes over ZIP file limits
+- Similar to [SQLite](https://www.sqlite.org/amalgamation.html) the Miniz source code is amalgamated into one miniz.c/miniz.h pair in a build step (amalgamate.sh). Please use miniz.c/miniz.h in your projects
+- Miniz 2 is only source back-compatible with miniz 1.x. It breaks binary compatibility because structures changed
+
+### v1.16 BETA Oct 19, 2013
+
+Still testing, this release is downloadable from [here](http://www.tenacioussoftware.com/miniz_v116_beta_r1.7z). Two key inflator-only robustness and streaming related changes. Also merged in tdefl_compressor_alloc(), tdefl_compressor_free() helpers to make script bindings easier for rustyzip. I would greatly appreciate any help with testing or any feedback.
+
+The inflator in raw (non-zlib) mode is now usable on gzip or similar streams that have a bunch of bytes following the raw deflate data (problem discovered by rustyzip author williamw520). This version should never read beyond the last byte of the raw deflate data independent of how many bytes you pass into the input buffer.
+
+The inflator now has a new failure status TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS (-4). Previously, if the inflator was starved of bytes and could not make progress (because the input buffer was empty and the caller did not set the TINFL_FLAG_HAS_MORE_INPUT flag - say on truncated or corrupted compressed data stream) it would append all 0's to the input and try to soldier on. This is scary behavior if the caller didn't know when to stop accepting output (because it didn't know how much uncompressed data was expected, or didn't enforce a sane maximum). v1.16 will instead return TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS immediately if it needs 1 or more bytes to make progress, the input buf is empty, and the caller has indicated that no more input is available. This is a "soft" failure, so you can call the inflator again with more input and it will try to continue, or you can give up and fail. This could be very useful in network streaming scenarios.
+
+- The inflator coroutine func. is subtle and complex so I'm being cautious about this release. I would greatly appreciate any help with testing or any feedback.
+ I feel good about these changes, and they've been through several hours of automated testing, but they will probably not fix anything for the majority of prev. users so I'm
+ going to mark this release as beta for a few weeks and continue testing it at work/home on various things.
+- The inflator in raw (non-zlib) mode is now usable on gzip or similar data streams that have a bunch of bytes following the raw deflate data (problem discovered by rustyzip author williamw520).
+ This version should *never* read beyond the last byte of the raw deflate data independent of how many bytes you pass into the input buffer. This issue was caused by the various Huffman bitbuffer lookahead optimizations, and
+ would not be an issue if the caller knew and enforced the precise size of the raw compressed data *or* if the compressed data was in zlib format (i.e. always followed by the byte aligned zlib adler32).
+ So in other words, you can now call the inflator on deflate streams that are followed by arbitrary amounts of data and it's guaranteed that decompression will stop exactly on the last byte.
+- The inflator now has a new failure status: TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS (-4). Previously, if the inflator was starved of bytes and could not make progress (because the input buffer was empty and the
+ caller did not set the TINFL_FLAG_HAS_MORE_INPUT flag - say on truncated or corrupted compressed data stream) it would append all 0's to the input and try to soldier on.
+ This is scary, because in the worst case, I believe it was possible for the prev. inflator to start outputting large amounts of literal data. If the caller didn't know when to stop accepting output
+ (because it didn't know how much uncompressed data was expected, or didn't enforce a sane maximum) it could continue forever. v1.16 cannot fall into this failure mode, instead it'll return
+ TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS immediately if it needs 1 or more bytes to make progress, the input buf is empty, and the caller has indicated that no more input is available. This is a "soft"
+ failure, so you can call the inflator again with more input and it will try to continue, or you can give up and fail. This could be very useful in network streaming scenarios.
+- Added documentation to all the tinfl return status codes, fixed miniz_tester so it accepts double minus params for Linux, tweaked example1.c, added a simple "follower bytes" test to miniz_tester.cpp.
+### v1.15 r4 STABLE - Oct 13, 2013
+
+Merged over a few very minor bug fixes that I fixed in the zip64 branch. This is downloadable from [here](http://code.google.com/p/miniz/downloads/list) and also in SVN head (as of 10/19/13).
+
+
+### v1.15 - Oct. 13, 2013
+
+Interim bugfix release while I work on the next major release with zip64 and streaming compression/decompression support. Fixed the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com), which could cause the locate files func to not find files when this flag was specified. Also fixed a bug in mz_zip_reader_extract_to_mem_no_alloc() with user provided read buffers (thanks kymoon). I also merged lots of compiler fixes from various github repo branches and Google Code issue reports. I finally added cmake support (only tested under for Linux so far), compiled and tested with clang v3.3 and gcc 4.6 (under Linux), added defl_write_image_to_png_file_in_memory_ex() (supports Y flipping for OpenGL use, real-time compression), added a new PNG example (example6.c - Mandelbrot), and I added 64-bit file I/O support (stat64(), etc.) for glibc.
+
+- Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com) which could cause locate files to not find files. This bug
+ would only have occured in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place()
+ (which used this flag). If you can't switch to v1.15 but want to fix this bug, just remove the uses of this flag from both helper funcs (and of course don't use the flag).
+- Bugfix in mz_zip_reader_extract_to_mem_no_alloc() from kymoon when pUser_read_buf is not NULL and compressed size is > uncompressed size
+- Fixing mz_zip_reader_extract_*() funcs so they don't try to extract compressed data from directory entries, to account for weird zipfiles which contain zero-size compressed data on dir entries.
+ Hopefully this fix won't cause any issues on weird zip archives, because it assumes the low 16-bits of zip external attributes are DOS attributes (which I believe they always are in practice).
+- Fixing mz_zip_reader_is_file_a_directory() so it doesn't check the internal attributes, just the filename and external attributes
+- mz_zip_reader_init_file() - missing MZ_FCLOSE() call if the seek failed
+- Added cmake support for Linux builds which builds all the examples, tested with clang v3.3 and gcc v4.6.
+- Clang fix for tdefl_write_image_to_png_file_in_memory() from toffaletti
+- Merged MZ_FORCEINLINE fix from hdeanclark
+- Fix <time.h> include before config #ifdef, thanks emil.brink
+- Added tdefl_write_image_to_png_file_in_memory_ex(): supports Y flipping (super useful for OpenGL apps), and explicit control over the compression level (so you can
+ set it to 1 for real-time compression).
+- Merged in some compiler fixes from paulharris's github repro.
+- Retested this build under Windows (VS 2010, including static analysis), tcc 0.9.26, gcc v4.6 and clang v3.3.
+- Added example6.c, which dumps an image of the mandelbrot set to a PNG file.
+- Modified example2 to help test the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY flag more.
+- In r3: Bugfix to mz_zip_writer_add_file() found during merge: Fix possible src file fclose() leak if alignment bytes+local header file write faiiled
+- In r4: Minor bugfix to mz_zip_writer_add_from_zip_reader(): Was pushing the wrong central dir header offset, appears harmless in this release, but it became a problem in the zip64 branch
+
+### v1.14 - May 20, 2012
+
+(SVN Only) Minor tweaks to get miniz.c compiling with the Tiny C Compiler, added #ifndef MINIZ_NO_TIME guards around utime.h includes. Adding mz_free() function, so the caller can free heap blocks returned by miniz using whatever heap functions it has been configured to use, MSVC specific fixes to use "safe" variants of several functions (localtime_s, fopen_s, freopen_s).
+
+MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, #include <time.h> (thanks fermtect).
+
+Compiler specific fixes, some from fermtect. I upgraded to TDM GCC 4.6.1 and now static __forceinline is giving it fits, so I'm changing all usage of __forceinline to MZ_FORCEINLINE and forcing gcc to use __attribute__((__always_inline__)) (and MSVC to use __forceinline). Also various fixes from fermtect for MinGW32: added #include , 64-bit ftell/fseek fixes.
+
+### v1.13 - May 19, 2012
+
+From jason@cornsyrup.org and kelwert@mtu.edu - Most importantly, fixed mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bits. Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files. Other stuff:
+
+Eliminated a bunch of warnings when compiling with GCC 32-bit/64. Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly "Use of the comma-operator in a tested expression.." analysis warning, which I purposely use to work around a MSVC compiler warning).
+
+Created 32-bit and 64-bit Codeblocks projects/workspace. Built and tested Linux executables. The codeblocks workspace is compatible with Linux+Win32/x64. Added miniz_tester solution/project, which is a useful little app derived from LZHAM's tester app that I use as part of the regression test. Ran miniz.c and tinfl.c through another series of regression testing on ~500,000 files and archives. Modified example5.c so it purposely disables a bunch of high-level functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the MINIZ_NO_STDIO bug report.)
+
+Fix ftell() usage in a few of the examples so they exit with an error on files which are too large (a limitation of the examples, not miniz itself). Fix fail logic handling in mz_zip_add_mem_to_archive_file_in_place() so it always calls mz_zip_writer_finalize_archive() and mz_zip_writer_end(), even if the file add fails.
+
+- From jason@cornsyrup.org and kelwert@mtu.edu - Fix mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit.
+- Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files.
+- Eliminated a bunch of warnings when compiling with GCC 32-bit/64.
+- Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly
+"Use of the comma-operator in a tested expression.." analysis warning, which I purposely use to work around a MSVC compiler warning).
+- Created 32-bit and 64-bit Codeblocks projects/workspace. Built and tested Linux executables. The codeblocks workspace is compatible with Linux+Win32/x64.
+- Added miniz_tester solution/project, which is a useful little app derived from LZHAM's tester app that I use as part of the regression test.
+- Ran miniz.c and tinfl.c through another series of regression testing on ~500,000 files and archives.
+- Modified example5.c so it purposely disables a bunch of high-level functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the MINIZ_NO_STDIO bug report.)
+- Fix ftell() usage in examples so they exit with an error on files which are too large (a limitation of the examples, not miniz itself).
+
+### v1.12 - 4/12/12
+
+More comments, added low-level example5.c, fixed a couple minor level_and_flags issues in the archive API's.
+level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson <bruced@valvesoftware.com> for the feedback/bug report.
+
+### v1.11 - 5/28/11
+
+Added statement from unlicense.org
+
+### v1.10 - 5/27/11
+
+- Substantial compressor optimizations:
+- Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86).
+- Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types.
+- Refactored the compression code for better readability and maintainability.
+- Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large drop in throughput on some files).
+
+### v1.09 - 5/15/11
+
+Initial stable release.
+
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/deps/miniz/LICENSE b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/LICENSE
new file mode 100644
index 0000000000..b6ff45a30f
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/LICENSE
@@ -0,0 +1,22 @@
+Copyright 2013-2014 RAD Game Tools and Valve Software
+Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
+
+All Rights Reserved.
+
+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
+AUTHORS OR COPYRIGHT HOLDERS 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.
diff --git a/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example1.c b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example1.c
new file mode 100644
index 0000000000..d6e33faaa6
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example1.c
@@ -0,0 +1,105 @@
+// example1.c - Demonstrates miniz.c's compress() and uncompress() functions (same as zlib's).
+// Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c.
+#include <stdio.h>
+#include "miniz.h"
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint;
+
+// The string to compress.
+static const char *s_pStr = "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
+ "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
+ "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
+ "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
+ "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
+ "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
+ "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson.";
+
+int main(int argc, char *argv[])
+{
+ uint step = 0;
+ int cmp_status;
+ uLong src_len = (uLong)strlen(s_pStr);
+ uLong cmp_len = compressBound(src_len);
+ uLong uncomp_len = src_len;
+ uint8 *pCmp, *pUncomp;
+ uint total_succeeded = 0;
+ (void)argc, (void)argv;
+
+ printf("miniz.c version: %s\n", MZ_VERSION);
+
+ do
+ {
+ // Allocate buffers to hold compressed and uncompressed data.
+ pCmp = (mz_uint8 *)malloc((size_t)cmp_len);
+ pUncomp = (mz_uint8 *)malloc((size_t)src_len);
+ if ((!pCmp) || (!pUncomp))
+ {
+ printf("Out of memory!\n");
+ return EXIT_FAILURE;
+ }
+
+ // Compress the string.
+ cmp_status = compress(pCmp, &cmp_len, (const unsigned char *)s_pStr, src_len);
+ if (cmp_status != Z_OK)
+ {
+ printf("compress() failed!\n");
+ free(pCmp);
+ free(pUncomp);
+ return EXIT_FAILURE;
+ }
+
+ printf("Compressed from %u to %u bytes\n", (mz_uint32)src_len, (mz_uint32)cmp_len);
+
+ if (step)
+ {
+ // Purposely corrupt the compressed data if fuzzy testing (this is a very crude fuzzy test).
+ uint n = 1 + (rand() % 3);
+ while (n--)
+ {
+ uint i = rand() % cmp_len;
+ pCmp[i] ^= (rand() & 0xFF);
+ }
+ }
+
+ // Decompress.
+ cmp_status = uncompress(pUncomp, &uncomp_len, pCmp, cmp_len);
+ total_succeeded += (cmp_status == Z_OK);
+
+ if (step)
+ {
+ printf("Simple fuzzy test: step %u total_succeeded: %u\n", step, total_succeeded);
+ }
+ else
+ {
+ if (cmp_status != Z_OK)
+ {
+ printf("uncompress failed!\n");
+ free(pCmp);
+ free(pUncomp);
+ return EXIT_FAILURE;
+ }
+
+ printf("Decompressed from %u to %u bytes\n", (mz_uint32)cmp_len, (mz_uint32)uncomp_len);
+
+ // Ensure uncompress() returned the expected data.
+ if ((uncomp_len != src_len) || (memcmp(pUncomp, s_pStr, (size_t)src_len)))
+ {
+ printf("Decompression failed!\n");
+ free(pCmp);
+ free(pUncomp);
+ return EXIT_FAILURE;
+ }
+ }
+
+ free(pCmp);
+ free(pUncomp);
+
+ step++;
+
+ // Keep on fuzzy testing if there's a non-empty command line.
+ } while (argc >= 2);
+
+ printf("Success.\n");
+ return EXIT_SUCCESS;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example2.c b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example2.c
new file mode 100644
index 0000000000..03d2409583
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example2.c
@@ -0,0 +1,164 @@
+// example2.c - Simple demonstration of miniz.c's ZIP archive API's.
+// Note this test deletes the test archive file "__mz_example2_test__.zip" in the current directory, then creates a new one with test data.
+// Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c.
+
+#if defined(__GNUC__)
+ // Ensure we get the 64-bit variants of the CRT's file I/O calls
+ #ifndef _FILE_OFFSET_BITS
+ #define _FILE_OFFSET_BITS 64
+ #endif
+ #ifndef _LARGEFILE64_SOURCE
+ #define _LARGEFILE64_SOURCE 1
+ #endif
+#endif
+
+#include <stdio.h>
+#include "miniz.h"
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint;
+
+// The string to compress.
+static const char *s_pTest_str =
+ "MISSION CONTROL I wouldn't worry too much about the computer. First of all, there is still a chance that he is right, despite your tests, and" \
+ "if it should happen again, we suggest eliminating this possibility by allowing the unit to remain in place and seeing whether or not it" \
+ "actually fails. If the computer should turn out to be wrong, the situation is still not alarming. The type of obsessional error he may be" \
+ "guilty of is not unknown among the latest generation of HAL 9000 computers. It has almost always revolved around a single detail, such as" \
+ "the one you have described, and it has never interfered with the integrity or reliability of the computer's performance in other areas." \
+ "No one is certain of the cause of this kind of malfunctioning. It may be over-programming, but it could also be any number of reasons. In any" \
+ "event, it is somewhat analogous to human neurotic behavior. Does this answer your query? Zero-five-three-Zero, MC, transmission concluded.";
+
+static const char *s_pComment = "This is a comment";
+
+int main(int argc, char *argv[])
+{
+ int i, sort_iter;
+ mz_bool status;
+ size_t uncomp_size;
+ mz_zip_archive zip_archive;
+ void *p;
+ const int N = 50;
+ char data[2048];
+ char archive_filename[64];
+ static const char *s_Test_archive_filename = "__mz_example2_test__.zip";
+
+ assert((strlen(s_pTest_str) + 64) < sizeof(data));
+
+ printf("miniz.c version: %s\n", MZ_VERSION);
+
+ (void)argc, (void)argv;
+
+ // Delete the test archive, so it doesn't keep growing as we run this test
+ remove(s_Test_archive_filename);
+
+ // Append a bunch of text files to the test archive
+ for (i = (N - 1); i >= 0; --i)
+ {
+ sprintf(archive_filename, "%u.txt", i);
+ sprintf(data, "%u %s %u", (N - 1) - i, s_pTest_str, i);
+
+ // Add a new file to the archive. Note this is an IN-PLACE operation, so if it fails your archive is probably hosed (its central directory may not be complete) but it should be recoverable using zip -F or -FF. So use caution with this guy.
+ // A more robust way to add a file to an archive would be to read it into memory, perform the operation, then write a new archive out to a temp file and then delete/rename the files.
+ // Or, write a new archive to disk to a temp file, then delete/rename the files. For this test this API is fine.
+ status = mz_zip_add_mem_to_archive_file_in_place(s_Test_archive_filename, archive_filename, data, strlen(data) + 1, s_pComment, (uint16)strlen(s_pComment), MZ_BEST_COMPRESSION);
+ if (!status)
+ {
+ printf("mz_zip_add_mem_to_archive_file_in_place failed!\n");
+ return EXIT_FAILURE;
+ }
+ }
+
+ // Add a directory entry for testing
+ status = mz_zip_add_mem_to_archive_file_in_place(s_Test_archive_filename, "directory/", NULL, 0, "no comment", (uint16)strlen("no comment"), MZ_BEST_COMPRESSION);
+ if (!status)
+ {
+ printf("mz_zip_add_mem_to_archive_file_in_place failed!\n");
+ return EXIT_FAILURE;
+ }
+
+ // Now try to open the archive.
+ memset(&zip_archive, 0, sizeof(zip_archive));
+
+ status = mz_zip_reader_init_file(&zip_archive, s_Test_archive_filename, 0);
+ if (!status)
+ {
+ printf("mz_zip_reader_init_file() failed!\n");
+ return EXIT_FAILURE;
+ }
+
+ // Get and print information about each file in the archive.
+ for (i = 0; i < (int)mz_zip_reader_get_num_files(&zip_archive); i++)
+ {
+ mz_zip_archive_file_stat file_stat;
+ if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat))
+ {
+ printf("mz_zip_reader_file_stat() failed!\n");
+ mz_zip_reader_end(&zip_archive);
+ return EXIT_FAILURE;
+ }
+
+ printf("Filename: \"%s\", Comment: \"%s\", Uncompressed size: %u, Compressed size: %u, Is Dir: %u\n", file_stat.m_filename, file_stat.m_comment, (uint)file_stat.m_uncomp_size, (uint)file_stat.m_comp_size, mz_zip_reader_is_file_a_directory(&zip_archive, i));
+
+ if (!strcmp(file_stat.m_filename, "directory/"))
+ {
+ if (!mz_zip_reader_is_file_a_directory(&zip_archive, i))
+ {
+ printf("mz_zip_reader_is_file_a_directory() didn't return the expected results!\n");
+ mz_zip_reader_end(&zip_archive);
+ return EXIT_FAILURE;
+ }
+ }
+ }
+
+ // Close the archive, freeing any resources it was using
+ mz_zip_reader_end(&zip_archive);
+
+ // Now verify the compressed data
+ for (sort_iter = 0; sort_iter < 2; sort_iter++)
+ {
+ memset(&zip_archive, 0, sizeof(zip_archive));
+ status = mz_zip_reader_init_file(&zip_archive, s_Test_archive_filename, sort_iter ? MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY : 0);
+ if (!status)
+ {
+ printf("mz_zip_reader_init_file() failed!\n");
+ return EXIT_FAILURE;
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ sprintf(archive_filename, "%u.txt", i);
+ sprintf(data, "%u %s %u", (N - 1) - i, s_pTest_str, i);
+
+ // Try to extract all the files to the heap.
+ p = mz_zip_reader_extract_file_to_heap(&zip_archive, archive_filename, &uncomp_size, 0);
+ if (!p)
+ {
+ printf("mz_zip_reader_extract_file_to_heap() failed!\n");
+ mz_zip_reader_end(&zip_archive);
+ return EXIT_FAILURE;
+ }
+
+ // Make sure the extraction really succeeded.
+ if ((uncomp_size != (strlen(data) + 1)) || (memcmp(p, data, strlen(data))))
+ {
+ printf("mz_zip_reader_extract_file_to_heap() failed to extract the proper data\n");
+ mz_free(p);
+ mz_zip_reader_end(&zip_archive);
+ return EXIT_FAILURE;
+ }
+
+ printf("Successfully extracted file \"%s\", size %u\n", archive_filename, (uint)uncomp_size);
+ printf("File data: \"%s\"\n", (const char *)p);
+
+ // We're done.
+ mz_free(p);
+ }
+
+ // Close the archive, freeing any resources it was using
+ mz_zip_reader_end(&zip_archive);
+ }
+
+ printf("Success.\n");
+ return EXIT_SUCCESS;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example3.c b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example3.c
new file mode 100644
index 0000000000..a97ba8420f
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example3.c
@@ -0,0 +1,269 @@
+// example3.c - Demonstrates how to use miniz.c's deflate() and inflate() functions for simple file compression.
+// Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c.
+// For simplicity, this example is limited to files smaller than 4GB, but this is not a limitation of miniz.c.
+#include <stdio.h>
+#include <limits.h>
+#include "miniz.h"
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint;
+
+#define my_max(a,b) (((a) > (b)) ? (a) : (b))
+#define my_min(a,b) (((a) < (b)) ? (a) : (b))
+
+#define BUF_SIZE (1024 * 1024)
+static uint8 s_inbuf[BUF_SIZE];
+static uint8 s_outbuf[BUF_SIZE];
+
+int main(int argc, char *argv[])
+{
+ const char *pMode;
+ FILE *pInfile, *pOutfile;
+ uint infile_size;
+ int level = Z_BEST_COMPRESSION;
+ z_stream stream;
+ int p = 1;
+ const char *pSrc_filename;
+ const char *pDst_filename;
+ long file_loc;
+
+ printf("miniz.c version: %s\n", MZ_VERSION);
+
+ if (argc < 4)
+ {
+ printf("Usage: example3 [options] [mode:c or d] infile outfile\n");
+ printf("\nModes:\n");
+ printf("c - Compresses file infile to a zlib stream in file outfile\n");
+ printf("d - Decompress zlib stream in file infile to file outfile\n");
+ printf("\nOptions:\n");
+ printf("-l[0-10] - Compression level, higher values are slower.\n");
+ return EXIT_FAILURE;
+ }
+
+ while ((p < argc) && (argv[p][0] == '-'))
+ {
+ switch (argv[p][1])
+ {
+ case 'l':
+ {
+ level = atoi(&argv[1][2]);
+ if ((level < 0) || (level > 10))
+ {
+ printf("Invalid level!\n");
+ return EXIT_FAILURE;
+ }
+ break;
+ }
+ default:
+ {
+ printf("Invalid option: %s\n", argv[p]);
+ return EXIT_FAILURE;
+ }
+ }
+ p++;
+ }
+
+ if ((argc - p) < 3)
+ {
+ printf("Must specify mode, input filename, and output filename after options!\n");
+ return EXIT_FAILURE;
+ }
+ else if ((argc - p) > 3)
+ {
+ printf("Too many filenames!\n");
+ return EXIT_FAILURE;
+ }
+
+ pMode = argv[p++];
+ if (!strchr("cCdD", pMode[0]))
+ {
+ printf("Invalid mode!\n");
+ return EXIT_FAILURE;
+ }
+
+ pSrc_filename = argv[p++];
+ pDst_filename = argv[p++];
+
+ printf("Mode: %c, Level: %u\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename);
+
+ // Open input file.
+ pInfile = fopen(pSrc_filename, "rb");
+ if (!pInfile)
+ {
+ printf("Failed opening input file!\n");
+ return EXIT_FAILURE;
+ }
+
+ // Determine input file's size.
+ fseek(pInfile, 0, SEEK_END);
+ file_loc = ftell(pInfile);
+ fseek(pInfile, 0, SEEK_SET);
+
+ if ((file_loc < 0) || (file_loc > INT_MAX))
+ {
+ // This is not a limitation of miniz or tinfl, but this example.
+ printf("File is too large to be processed by this example.\n");
+ return EXIT_FAILURE;
+ }
+
+ infile_size = (uint)file_loc;
+
+ // Open output file.
+ pOutfile = fopen(pDst_filename, "wb");
+ if (!pOutfile)
+ {
+ printf("Failed opening output file!\n");
+ return EXIT_FAILURE;
+ }
+
+ printf("Input file size: %u\n", infile_size);
+
+ // Init the z_stream
+ memset(&stream, 0, sizeof(stream));
+ stream.next_in = s_inbuf;
+ stream.avail_in = 0;
+ stream.next_out = s_outbuf;
+ stream.avail_out = BUF_SIZE;
+
+ if ((pMode[0] == 'c') || (pMode[0] == 'C'))
+ {
+ // Compression.
+ uint infile_remaining = infile_size;
+
+ if (deflateInit(&stream, level) != Z_OK)
+ {
+ printf("deflateInit() failed!\n");
+ return EXIT_FAILURE;
+ }
+
+ for ( ; ; )
+ {
+ int status;
+ if (!stream.avail_in)
+ {
+ // Input buffer is empty, so read more bytes from input file.
+ uint n = my_min(BUF_SIZE, infile_remaining);
+
+ if (fread(s_inbuf, 1, n, pInfile) != n)
+ {
+ printf("Failed reading from input file!\n");
+ return EXIT_FAILURE;
+ }
+
+ stream.next_in = s_inbuf;
+ stream.avail_in = n;
+
+ infile_remaining -= n;
+ //printf("Input bytes remaining: %u\n", infile_remaining);
+ }
+
+ status = deflate(&stream, infile_remaining ? Z_NO_FLUSH : Z_FINISH);
+
+ if ((status == Z_STREAM_END) || (!stream.avail_out))
+ {
+ // Output buffer is full, or compression is done, so write buffer to output file.
+ uint n = BUF_SIZE - stream.avail_out;
+ if (fwrite(s_outbuf, 1, n, pOutfile) != n)
+ {
+ printf("Failed writing to output file!\n");
+ return EXIT_FAILURE;
+ }
+ stream.next_out = s_outbuf;
+ stream.avail_out = BUF_SIZE;
+ }
+
+ if (status == Z_STREAM_END)
+ break;
+ else if (status != Z_OK)
+ {
+ printf("deflate() failed with status %i!\n", status);
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (deflateEnd(&stream) != Z_OK)
+ {
+ printf("deflateEnd() failed!\n");
+ return EXIT_FAILURE;
+ }
+ }
+ else if ((pMode[0] == 'd') || (pMode[0] == 'D'))
+ {
+ // Decompression.
+ uint infile_remaining = infile_size;
+
+ if (inflateInit(&stream))
+ {
+ printf("inflateInit() failed!\n");
+ return EXIT_FAILURE;
+ }
+
+ for ( ; ; )
+ {
+ int status;
+ if (!stream.avail_in)
+ {
+ // Input buffer is empty, so read more bytes from input file.
+ uint n = my_min(BUF_SIZE, infile_remaining);
+
+ if (fread(s_inbuf, 1, n, pInfile) != n)
+ {
+ printf("Failed reading from input file!\n");
+ return EXIT_FAILURE;
+ }
+
+ stream.next_in = s_inbuf;
+ stream.avail_in = n;
+
+ infile_remaining -= n;
+ }
+
+ status = inflate(&stream, Z_SYNC_FLUSH);
+
+ if ((status == Z_STREAM_END) || (!stream.avail_out))
+ {
+ // Output buffer is full, or decompression is done, so write buffer to output file.
+ uint n = BUF_SIZE - stream.avail_out;
+ if (fwrite(s_outbuf, 1, n, pOutfile) != n)
+ {
+ printf("Failed writing to output file!\n");
+ return EXIT_FAILURE;
+ }
+ stream.next_out = s_outbuf;
+ stream.avail_out = BUF_SIZE;
+ }
+
+ if (status == Z_STREAM_END)
+ break;
+ else if (status != Z_OK)
+ {
+ printf("inflate() failed with status %i!\n", status);
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (inflateEnd(&stream) != Z_OK)
+ {
+ printf("inflateEnd() failed!\n");
+ return EXIT_FAILURE;
+ }
+ }
+ else
+ {
+ printf("Invalid mode!\n");
+ return EXIT_FAILURE;
+ }
+
+ fclose(pInfile);
+ if (EOF == fclose(pOutfile))
+ {
+ printf("Failed writing to output file!\n");
+ return EXIT_FAILURE;
+ }
+
+ printf("Total input bytes: %u\n", (mz_uint32)stream.total_in);
+ printf("Total output bytes: %u\n", (mz_uint32)stream.total_out);
+ printf("Success.\n");
+ return EXIT_SUCCESS;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example4.c b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example4.c
new file mode 100644
index 0000000000..3f2d7cf1ed
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example4.c
@@ -0,0 +1,102 @@
+// example4.c - Uses tinfl.c to decompress a zlib stream in memory to an output file
+// Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c.
+#include "miniz.h"
+#include <stdio.h>
+#include <limits.h>
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint;
+
+#define my_max(a,b) (((a) > (b)) ? (a) : (b))
+#define my_min(a,b) (((a) < (b)) ? (a) : (b))
+
+static int tinfl_put_buf_func(const void* pBuf, int len, void *pUser)
+{
+ return len == (int)fwrite(pBuf, 1, len, (FILE*)pUser);
+}
+
+int main(int argc, char *argv[])
+{
+ int status;
+ FILE *pInfile, *pOutfile;
+ uint infile_size, outfile_size;
+ size_t in_buf_size;
+ uint8 *pCmp_data;
+ long file_loc;
+
+ if (argc != 3)
+ {
+ printf("Usage: example4 infile outfile\n");
+ printf("Decompresses zlib stream in file infile to file outfile.\n");
+ printf("Input file must be able to fit entirely in memory.\n");
+ printf("example3 can be used to create compressed zlib streams.\n");
+ return EXIT_FAILURE;
+ }
+
+ // Open input file.
+ pInfile = fopen(argv[1], "rb");
+ if (!pInfile)
+ {
+ printf("Failed opening input file!\n");
+ return EXIT_FAILURE;
+ }
+
+ // Determine input file's size.
+ fseek(pInfile, 0, SEEK_END);
+ file_loc = ftell(pInfile);
+ fseek(pInfile, 0, SEEK_SET);
+
+ if ((file_loc < 0) || (file_loc > INT_MAX))
+ {
+ // This is not a limitation of miniz or tinfl, but this example.
+ printf("File is too large to be processed by this example.\n");
+ return EXIT_FAILURE;
+ }
+
+ infile_size = (uint)file_loc;
+
+ pCmp_data = (uint8 *)malloc(infile_size);
+ if (!pCmp_data)
+ {
+ printf("Out of memory!\n");
+ return EXIT_FAILURE;
+ }
+ if (fread(pCmp_data, 1, infile_size, pInfile) != infile_size)
+ {
+ printf("Failed reading input file!\n");
+ return EXIT_FAILURE;
+ }
+
+ // Open output file.
+ pOutfile = fopen(argv[2], "wb");
+ if (!pOutfile)
+ {
+ printf("Failed opening output file!\n");
+ return EXIT_FAILURE;
+ }
+
+ printf("Input file size: %u\n", infile_size);
+
+ in_buf_size = infile_size;
+ status = tinfl_decompress_mem_to_callback(pCmp_data, &in_buf_size, tinfl_put_buf_func, pOutfile, TINFL_FLAG_PARSE_ZLIB_HEADER);
+ if (!status)
+ {
+ printf("tinfl_decompress_mem_to_callback() failed with status %i!\n", status);
+ return EXIT_FAILURE;
+ }
+
+ outfile_size = ftell(pOutfile);
+
+ fclose(pInfile);
+ if (EOF == fclose(pOutfile))
+ {
+ printf("Failed writing to output file!\n");
+ return EXIT_FAILURE;
+ }
+
+ printf("Total input bytes: %u\n", (uint)in_buf_size);
+ printf("Total output bytes: %u\n", outfile_size);
+ printf("Success.\n");
+ return EXIT_SUCCESS;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example5.c b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example5.c
new file mode 100644
index 0000000000..a190357b3d
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example5.c
@@ -0,0 +1,327 @@
+// example5.c - Demonstrates how to use miniz.c's low-level tdefl_compress() and tinfl_inflate() API's for simple file to file compression/decompression.
+// The low-level API's are the fastest, make no use of dynamic memory allocation, and are the most flexible functions exposed by miniz.c.
+// Public domain, April 11 2012, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c.
+// For simplicity, this example is limited to files smaller than 4GB, but this is not a limitation of miniz.c.
+
+// Purposely disable a whole bunch of stuff this low-level example doesn't use.
+#define MINIZ_NO_STDIO
+#define MINIZ_NO_ARCHIVE_APIS
+#define MINIZ_NO_TIME
+#define MINIZ_NO_ZLIB_APIS
+#define MINIZ_NO_MALLOC
+#include "miniz.h"
+
+// Now include stdio.h because this test uses fopen(), etc. (but we still don't want miniz.c's stdio stuff, for testing).
+#include <stdio.h>
+#include <limits.h>
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint;
+
+#define my_max(a,b) (((a) > (b)) ? (a) : (b))
+#define my_min(a,b) (((a) < (b)) ? (a) : (b))
+
+// IN_BUF_SIZE is the size of the file read buffer.
+// IN_BUF_SIZE must be >= 1
+#define IN_BUF_SIZE (1024*512)
+static uint8 s_inbuf[IN_BUF_SIZE];
+
+// COMP_OUT_BUF_SIZE is the size of the output buffer used during compression.
+// COMP_OUT_BUF_SIZE must be >= 1 and <= OUT_BUF_SIZE
+#define COMP_OUT_BUF_SIZE (1024*512)
+
+// OUT_BUF_SIZE is the size of the output buffer used during decompression.
+// OUT_BUF_SIZE must be a power of 2 >= TINFL_LZ_DICT_SIZE (because the low-level decompressor not only writes, but reads from the output buffer as it decompresses)
+//#define OUT_BUF_SIZE (TINFL_LZ_DICT_SIZE)
+#define OUT_BUF_SIZE (1024*512)
+static uint8 s_outbuf[OUT_BUF_SIZE];
+
+// tdefl_compressor contains all the state needed by the low-level compressor so it's a pretty big struct (~300k).
+// This example makes it a global vs. putting it on the stack, of course in real-world usage you'll probably malloc() or new it.
+tdefl_compressor g_deflator;
+
+int main(int argc, char *argv[])
+{
+ const char *pMode;
+ FILE *pInfile, *pOutfile;
+ uint infile_size;
+ int level = 9;
+ int p = 1;
+ const char *pSrc_filename;
+ const char *pDst_filename;
+ const void *next_in = s_inbuf;
+ size_t avail_in = 0;
+ void *next_out = s_outbuf;
+ size_t avail_out = OUT_BUF_SIZE;
+ size_t total_in = 0, total_out = 0;
+ long file_loc;
+
+ assert(COMP_OUT_BUF_SIZE <= OUT_BUF_SIZE);
+
+ printf("miniz.c example5 (demonstrates tinfl/tdefl)\n");
+
+ if (argc < 4)
+ {
+ printf("File to file compression/decompression using the low-level tinfl/tdefl API's.\n");
+ printf("Usage: example5 [options] [mode:c or d] infile outfile\n");
+ printf("\nModes:\n");
+ printf("c - Compresses file infile to a zlib stream in file outfile\n");
+ printf("d - Decompress zlib stream in file infile to file outfile\n");
+ printf("\nOptions:\n");
+ printf("-l[0-10] - Compression level, higher values are slower, 0 is none.\n");
+ return EXIT_FAILURE;
+ }
+
+ while ((p < argc) && (argv[p][0] == '-'))
+ {
+ switch (argv[p][1])
+ {
+ case 'l':
+ {
+ level = atoi(&argv[1][2]);
+ if ((level < 0) || (level > 10))
+ {
+ printf("Invalid level!\n");
+ return EXIT_FAILURE;
+ }
+ break;
+ }
+ default:
+ {
+ printf("Invalid option: %s\n", argv[p]);
+ return EXIT_FAILURE;
+ }
+ }
+ p++;
+ }
+
+ if ((argc - p) < 3)
+ {
+ printf("Must specify mode, input filename, and output filename after options!\n");
+ return EXIT_FAILURE;
+ }
+ else if ((argc - p) > 3)
+ {
+ printf("Too many filenames!\n");
+ return EXIT_FAILURE;
+ }
+
+ pMode = argv[p++];
+ if (!strchr("cCdD", pMode[0]))
+ {
+ printf("Invalid mode!\n");
+ return EXIT_FAILURE;
+ }
+
+ pSrc_filename = argv[p++];
+ pDst_filename = argv[p++];
+
+ printf("Mode: %c, Level: %u\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename);
+
+ // Open input file.
+ pInfile = fopen(pSrc_filename, "rb");
+ if (!pInfile)
+ {
+ printf("Failed opening input file!\n");
+ return EXIT_FAILURE;
+ }
+
+ // Determine input file's size.
+ fseek(pInfile, 0, SEEK_END);
+ file_loc = ftell(pInfile);
+ fseek(pInfile, 0, SEEK_SET);
+
+ if ((file_loc < 0) || (file_loc > INT_MAX))
+ {
+ // This is not a limitation of miniz or tinfl, but this example.
+ printf("File is too large to be processed by this example.\n");
+ return EXIT_FAILURE;
+ }
+
+ infile_size = (uint)file_loc;
+
+ // Open output file.
+ pOutfile = fopen(pDst_filename, "wb");
+ if (!pOutfile)
+ {
+ printf("Failed opening output file!\n");
+ return EXIT_FAILURE;
+ }
+
+ printf("Input file size: %u\n", infile_size);
+
+ if ((pMode[0] == 'c') || (pMode[0] == 'C'))
+ {
+ // The number of dictionary probes to use at each compression level (0-10). 0=implies fastest/minimal possible probing.
+ static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
+
+ tdefl_status status;
+ uint infile_remaining = infile_size;
+
+ // create tdefl() compatible flags (we have to compose the low-level flags ourselves, or use tdefl_create_comp_flags_from_zip_params() but that means MINIZ_NO_ZLIB_APIS can't be defined).
+ mz_uint comp_flags = TDEFL_WRITE_ZLIB_HEADER | s_tdefl_num_probes[MZ_MIN(10, level)] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
+ if (!level)
+ comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
+
+ // Initialize the low-level compressor.
+ status = tdefl_init(&g_deflator, NULL, NULL, comp_flags);
+ if (status != TDEFL_STATUS_OKAY)
+ {
+ printf("tdefl_init() failed!\n");
+ return EXIT_FAILURE;
+ }
+
+ avail_out = COMP_OUT_BUF_SIZE;
+
+ // Compression.
+ for ( ; ; )
+ {
+ size_t in_bytes, out_bytes;
+
+ if (!avail_in)
+ {
+ // Input buffer is empty, so read more bytes from input file.
+ uint n = my_min(IN_BUF_SIZE, infile_remaining);
+
+ if (fread(s_inbuf, 1, n, pInfile) != n)
+ {
+ printf("Failed reading from input file!\n");
+ return EXIT_FAILURE;
+ }
+
+ next_in = s_inbuf;
+ avail_in = n;
+
+ infile_remaining -= n;
+ //printf("Input bytes remaining: %u\n", infile_remaining);
+ }
+
+ in_bytes = avail_in;
+ out_bytes = avail_out;
+ // Compress as much of the input as possible (or all of it) to the output buffer.
+ status = tdefl_compress(&g_deflator, next_in, &in_bytes, next_out, &out_bytes, infile_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH);
+
+ next_in = (const char *)next_in + in_bytes;
+ avail_in -= in_bytes;
+ total_in += in_bytes;
+
+ next_out = (char *)next_out + out_bytes;
+ avail_out -= out_bytes;
+ total_out += out_bytes;
+
+ if ((status != TDEFL_STATUS_OKAY) || (!avail_out))
+ {
+ // Output buffer is full, or compression is done or failed, so write buffer to output file.
+ uint n = COMP_OUT_BUF_SIZE - (uint)avail_out;
+ if (fwrite(s_outbuf, 1, n, pOutfile) != n)
+ {
+ printf("Failed writing to output file!\n");
+ return EXIT_FAILURE;
+ }
+ next_out = s_outbuf;
+ avail_out = COMP_OUT_BUF_SIZE;
+ }
+
+ if (status == TDEFL_STATUS_DONE)
+ {
+ // Compression completed successfully.
+ break;
+ }
+ else if (status != TDEFL_STATUS_OKAY)
+ {
+ // Compression somehow failed.
+ printf("tdefl_compress() failed with status %i!\n", status);
+ return EXIT_FAILURE;
+ }
+ }
+ }
+ else if ((pMode[0] == 'd') || (pMode[0] == 'D'))
+ {
+ // Decompression.
+ uint infile_remaining = infile_size;
+
+ tinfl_decompressor inflator;
+ tinfl_init(&inflator);
+
+ for ( ; ; )
+ {
+ size_t in_bytes, out_bytes;
+ tinfl_status status;
+ if (!avail_in)
+ {
+ // Input buffer is empty, so read more bytes from input file.
+ uint n = my_min(IN_BUF_SIZE, infile_remaining);
+
+ if (fread(s_inbuf, 1, n, pInfile) != n)
+ {
+ printf("Failed reading from input file!\n");
+ return EXIT_FAILURE;
+ }
+
+ next_in = s_inbuf;
+ avail_in = n;
+
+ infile_remaining -= n;
+ }
+
+ in_bytes = avail_in;
+ out_bytes = avail_out;
+ status = tinfl_decompress(&inflator, (const mz_uint8 *)next_in, &in_bytes, s_outbuf, (mz_uint8 *)next_out, &out_bytes, (infile_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0) | TINFL_FLAG_PARSE_ZLIB_HEADER);
+
+ avail_in -= in_bytes;
+ next_in = (const mz_uint8 *)next_in + in_bytes;
+ total_in += in_bytes;
+
+ avail_out -= out_bytes;
+ next_out = (mz_uint8 *)next_out + out_bytes;
+ total_out += out_bytes;
+
+ if ((status <= TINFL_STATUS_DONE) || (!avail_out))
+ {
+ // Output buffer is full, or decompression is done, so write buffer to output file.
+ uint n = OUT_BUF_SIZE - (uint)avail_out;
+ if (fwrite(s_outbuf, 1, n, pOutfile) != n)
+ {
+ printf("Failed writing to output file!\n");
+ return EXIT_FAILURE;
+ }
+ next_out = s_outbuf;
+ avail_out = OUT_BUF_SIZE;
+ }
+
+ // If status is <= TINFL_STATUS_DONE then either decompression is done or something went wrong.
+ if (status <= TINFL_STATUS_DONE)
+ {
+ if (status == TINFL_STATUS_DONE)
+ {
+ // Decompression completed successfully.
+ break;
+ }
+ else
+ {
+ // Decompression failed.
+ printf("tinfl_decompress() failed with status %i!\n", status);
+ return EXIT_FAILURE;
+ }
+ }
+ }
+ }
+ else
+ {
+ printf("Invalid mode!\n");
+ return EXIT_FAILURE;
+ }
+
+ fclose(pInfile);
+ if (EOF == fclose(pOutfile))
+ {
+ printf("Failed writing to output file!\n");
+ return EXIT_FAILURE;
+ }
+
+ printf("Total input bytes: %u\n", (mz_uint32)total_in);
+ printf("Total output bytes: %u\n", (mz_uint32)total_out);
+ printf("Success.\n");
+ return EXIT_SUCCESS;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example6.c b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example6.c
new file mode 100644
index 0000000000..abbb64fe3c
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/examples/example6.c
@@ -0,0 +1,162 @@
+// example6.c - Demonstrates how to miniz's PNG writer func
+// Public domain, April 11 2012, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c.
+// Mandlebrot set code from http://rosettacode.org/wiki/Mandelbrot_set#C
+// Must link this example against libm on Linux.
+
+// Purposely disable a whole bunch of stuff this low-level example doesn't use.
+#define MINIZ_NO_STDIO
+#define MINIZ_NO_TIME
+#define MINIZ_NO_ZLIB_APIS
+#include "miniz.h"
+
+// Now include stdio.h because this test uses fopen(), etc. (but we still don't want miniz.c's stdio stuff, for testing).
+#include <stdio.h>
+#include <limits.h>
+#include <math.h>
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint;
+
+typedef struct
+{
+ uint8 r, g, b;
+} rgb_t;
+
+static void hsv_to_rgb(int hue, int min, int max, rgb_t *p)
+{
+ const int invert = 0;
+ const int saturation = 1;
+ const int color_rotate = 0;
+
+ if (min == max) max = min + 1;
+ if (invert) hue = max - (hue - min);
+ if (!saturation) {
+ p->r = p->g = p->b = 255 * (max - hue) / (max - min);
+ return;
+ }
+ double h = fmod(color_rotate + 1e-4 + 4.0 * (hue - min) / (max - min), 6);
+ double c = 255.0f * saturation;
+ double X = c * (1 - fabs(fmod(h, 2) - 1));
+
+ p->r = p->g = p->b = 0;
+
+ switch((int)h) {
+ case 0: p->r = c; p->g = X; return;
+ case 1: p->r = X; p->g = c; return;
+ case 2: p->g = c; p->b = X; return;
+ case 3: p->g = X; p->b = c; return;
+ case 4: p->r = X; p->b = c; return;
+ default:p->r = c; p->b = X;
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ (void)argc, (void)argv;
+
+ // Image resolution
+ const int iXmax = 4096;
+ const int iYmax = 4096;
+
+ // Output filename
+ static const char *pFilename = "mandelbrot.png";
+
+ int iX, iY;
+ const double CxMin = -2.5;
+ const double CxMax = 1.5;
+ const double CyMin = -2.0;
+ const double CyMax = 2.0;
+
+ double PixelWidth = (CxMax - CxMin) / iXmax;
+ double PixelHeight = (CyMax - CyMin) / iYmax;
+
+ // Z=Zx+Zy*i ; Z0 = 0
+ double Zx, Zy;
+ double Zx2, Zy2; // Zx2=Zx*Zx; Zy2=Zy*Zy
+
+ int Iteration;
+ const int IterationMax = 200;
+
+ // bail-out value , radius of circle
+ const double EscapeRadius = 2;
+ double ER2=EscapeRadius * EscapeRadius;
+
+ uint8 *pImage = (uint8 *)malloc(iXmax * 3 * iYmax);
+
+ // world ( double) coordinate = parameter plane
+ double Cx,Cy;
+
+ int MinIter = 9999, MaxIter = 0;
+
+ for(iY = 0; iY < iYmax; iY++)
+ {
+ Cy = CyMin + iY * PixelHeight;
+ if (fabs(Cy) < PixelHeight/2)
+ Cy = 0.0; // Main antenna
+
+ for(iX = 0; iX < iXmax; iX++)
+ {
+ uint8 *color = pImage + (iX * 3) + (iY * iXmax * 3);
+
+ Cx = CxMin + iX * PixelWidth;
+
+ // initial value of orbit = critical point Z= 0
+ Zx = 0.0;
+ Zy = 0.0;
+ Zx2 = Zx * Zx;
+ Zy2 = Zy * Zy;
+
+ for (Iteration=0;Iteration<IterationMax && ((Zx2+Zy2)<ER2);Iteration++)
+ {
+ Zy = 2 * Zx * Zy + Cy;
+ Zx =Zx2 - Zy2 + Cx;
+ Zx2 = Zx * Zx;
+ Zy2 = Zy * Zy;
+ };
+
+ color[0] = (uint8)Iteration;
+ color[1] = (uint8)Iteration >> 8;
+ color[2] = 0;
+
+ if (Iteration < MinIter)
+ MinIter = Iteration;
+ if (Iteration > MaxIter)
+ MaxIter = Iteration;
+ }
+ }
+
+ for(iY = 0; iY < iYmax; iY++)
+ {
+ for(iX = 0; iX < iXmax; iX++)
+ {
+ uint8 *color = (uint8 *)(pImage + (iX * 3) + (iY * iXmax * 3));
+
+ uint Iterations = color[0] | (color[1] << 8U);
+
+ hsv_to_rgb(Iterations, MinIter, MaxIter, (rgb_t *)color);
+ }
+ }
+
+ // Now write the PNG image.
+ {
+ size_t png_data_size = 0;
+ void *pPNG_data = tdefl_write_image_to_png_file_in_memory_ex(pImage, iXmax, iYmax, 3, &png_data_size, 6, MZ_FALSE);
+ if (!pPNG_data)
+ fprintf(stderr, "tdefl_write_image_to_png_file_in_memory_ex() failed!\n");
+ else
+ {
+ FILE *pFile = fopen(pFilename, "wb");
+ fwrite(pPNG_data, 1, png_data_size, pFile);
+ fclose(pFile);
+ printf("Wrote %s\n", pFilename);
+ }
+
+ // mz_free() is by default just an alias to free() internally, but if you've overridden miniz's allocation funcs you'll probably need to call mz_free().
+ mz_free(pPNG_data);
+ }
+
+ free(pImage);
+
+ return EXIT_SUCCESS;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/deps/miniz/miniz.c b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/miniz.c
new file mode 100644
index 0000000000..87bdedb188
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/miniz.c
@@ -0,0 +1,7733 @@
+#include "miniz.h"
+/**************************************************************************
+ *
+ * Copyright 2013-2014 RAD Game Tools and Valve Software
+ * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
+ * All Rights Reserved.
+ *
+ * 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
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ **************************************************************************/
+
+
+
+typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1];
+typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1];
+typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1];
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ------------------- zlib-style API's */
+
+mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
+{
+ mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16);
+ size_t block_len = buf_len % 5552;
+ if (!ptr)
+ return MZ_ADLER32_INIT;
+ while (buf_len)
+ {
+ for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
+ {
+ s1 += ptr[0], s2 += s1;
+ s1 += ptr[1], s2 += s1;
+ s1 += ptr[2], s2 += s1;
+ s1 += ptr[3], s2 += s1;
+ s1 += ptr[4], s2 += s1;
+ s1 += ptr[5], s2 += s1;
+ s1 += ptr[6], s2 += s1;
+ s1 += ptr[7], s2 += s1;
+ }
+ for (; i < block_len; ++i)
+ s1 += *ptr++, s2 += s1;
+ s1 %= 65521U, s2 %= 65521U;
+ buf_len -= block_len;
+ block_len = 5552;
+ }
+ return (s2 << 16) + s1;
+}
+
+/* Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/ */
+#if 0
+ mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
+ {
+ static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
+ 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
+ mz_uint32 crcu32 = (mz_uint32)crc;
+ if (!ptr)
+ return MZ_CRC32_INIT;
+ crcu32 = ~crcu32;
+ while (buf_len--)
+ {
+ mz_uint8 b = *ptr++;
+ crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
+ crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
+ }
+ return ~crcu32;
+ }
+#elif defined(USE_EXTERNAL_MZCRC)
+/* If USE_EXTERNAL_CRC is defined, an external module will export the
+ * mz_crc32() symbol for us to use, e.g. an SSE-accelerated version.
+ * Depending on the impl, it may be necessary to ~ the input/output crc values.
+ */
+mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len);
+#else
+/* Faster, but larger CPU cache footprint.
+ */
+mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
+{
+ static const mz_uint32 s_crc_table[256] =
+ {
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
+ 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
+ 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
+ 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
+ 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
+ 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC,
+ 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
+ 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
+ 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB,
+ 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA,
+ 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE,
+ 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
+ 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409,
+ 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
+ 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739,
+ 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268,
+ 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0,
+ 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8,
+ 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
+ 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
+ 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
+ 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE,
+ 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
+ 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6,
+ 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D,
+ 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
+ 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
+ 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+ };
+
+ mz_uint32 crc32 = (mz_uint32)crc ^ 0xFFFFFFFF;
+ const mz_uint8 *pByte_buf = (const mz_uint8 *)ptr;
+
+ while (buf_len >= 4)
+ {
+ crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
+ crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[1]) & 0xFF];
+ crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[2]) & 0xFF];
+ crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[3]) & 0xFF];
+ pByte_buf += 4;
+ buf_len -= 4;
+ }
+
+ while (buf_len)
+ {
+ crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
+ ++pByte_buf;
+ --buf_len;
+ }
+
+ return ~crc32;
+}
+#endif
+
+void mz_free(void *p)
+{
+ MZ_FREE(p);
+}
+
+MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size)
+{
+ (void)opaque, (void)items, (void)size;
+ return MZ_MALLOC(items * size);
+}
+MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address)
+{
+ (void)opaque, (void)address;
+ MZ_FREE(address);
+}
+MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
+{
+ (void)opaque, (void)address, (void)items, (void)size;
+ return MZ_REALLOC(address, items * size);
+}
+
+const char *mz_version(void)
+{
+ return MZ_VERSION;
+}
+
+#ifndef MINIZ_NO_ZLIB_APIS
+
+int mz_deflateInit(mz_streamp pStream, int level)
+{
+ return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY);
+}
+
+int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
+{
+ tdefl_compressor *pComp;
+ mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
+
+ if (!pStream)
+ return MZ_STREAM_ERROR;
+ if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)))
+ return MZ_PARAM_ERROR;
+
+ pStream->data_type = 0;
+ pStream->adler = MZ_ADLER32_INIT;
+ pStream->msg = NULL;
+ pStream->reserved = 0;
+ pStream->total_in = 0;
+ pStream->total_out = 0;
+ if (!pStream->zalloc)
+ pStream->zalloc = miniz_def_alloc_func;
+ if (!pStream->zfree)
+ pStream->zfree = miniz_def_free_func;
+
+ pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
+ if (!pComp)
+ return MZ_MEM_ERROR;
+
+ pStream->state = (struct mz_internal_state *)pComp;
+
+ if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
+ {
+ mz_deflateEnd(pStream);
+ return MZ_PARAM_ERROR;
+ }
+
+ return MZ_OK;
+}
+
+int mz_deflateReset(mz_streamp pStream)
+{
+ if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree))
+ return MZ_STREAM_ERROR;
+ pStream->total_in = pStream->total_out = 0;
+ tdefl_init((tdefl_compressor *)pStream->state, NULL, NULL, ((tdefl_compressor *)pStream->state)->m_flags);
+ return MZ_OK;
+}
+
+int mz_deflate(mz_streamp pStream, int flush)
+{
+ size_t in_bytes, out_bytes;
+ mz_ulong orig_total_in, orig_total_out;
+ int mz_status = MZ_OK;
+
+ if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out))
+ return MZ_STREAM_ERROR;
+ if (!pStream->avail_out)
+ return MZ_BUF_ERROR;
+
+ if (flush == MZ_PARTIAL_FLUSH)
+ flush = MZ_SYNC_FLUSH;
+
+ if (((tdefl_compressor *)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
+ return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
+
+ orig_total_in = pStream->total_in;
+ orig_total_out = pStream->total_out;
+ for (;;)
+ {
+ tdefl_status defl_status;
+ in_bytes = pStream->avail_in;
+ out_bytes = pStream->avail_out;
+
+ defl_status = tdefl_compress((tdefl_compressor *)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
+ pStream->next_in += (mz_uint)in_bytes;
+ pStream->avail_in -= (mz_uint)in_bytes;
+ pStream->total_in += (mz_uint)in_bytes;
+ pStream->adler = tdefl_get_adler32((tdefl_compressor *)pStream->state);
+
+ pStream->next_out += (mz_uint)out_bytes;
+ pStream->avail_out -= (mz_uint)out_bytes;
+ pStream->total_out += (mz_uint)out_bytes;
+
+ if (defl_status < 0)
+ {
+ mz_status = MZ_STREAM_ERROR;
+ break;
+ }
+ else if (defl_status == TDEFL_STATUS_DONE)
+ {
+ mz_status = MZ_STREAM_END;
+ break;
+ }
+ else if (!pStream->avail_out)
+ break;
+ else if ((!pStream->avail_in) && (flush != MZ_FINISH))
+ {
+ if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
+ break;
+ return MZ_BUF_ERROR; /* Can't make forward progress without some input.
+ */
+ }
+ }
+ return mz_status;
+}
+
+int mz_deflateEnd(mz_streamp pStream)
+{
+ if (!pStream)
+ return MZ_STREAM_ERROR;
+ if (pStream->state)
+ {
+ pStream->zfree(pStream->opaque, pStream->state);
+ pStream->state = NULL;
+ }
+ return MZ_OK;
+}
+
+mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len)
+{
+ (void)pStream;
+ /* This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.) */
+ return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
+}
+
+int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
+{
+ int status;
+ mz_stream stream;
+ memset(&stream, 0, sizeof(stream));
+
+ /* In case mz_ulong is 64-bits (argh I hate longs). */
+ if ((source_len | *pDest_len) > 0xFFFFFFFFU)
+ return MZ_PARAM_ERROR;
+
+ stream.next_in = pSource;
+ stream.avail_in = (mz_uint32)source_len;
+ stream.next_out = pDest;
+ stream.avail_out = (mz_uint32)*pDest_len;
+
+ status = mz_deflateInit(&stream, level);
+ if (status != MZ_OK)
+ return status;
+
+ status = mz_deflate(&stream, MZ_FINISH);
+ if (status != MZ_STREAM_END)
+ {
+ mz_deflateEnd(&stream);
+ return (status == MZ_OK) ? MZ_BUF_ERROR : status;
+ }
+
+ *pDest_len = stream.total_out;
+ return mz_deflateEnd(&stream);
+}
+
+int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
+{
+ return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
+}
+
+mz_ulong mz_compressBound(mz_ulong source_len)
+{
+ return mz_deflateBound(NULL, source_len);
+}
+
+typedef struct
+{
+ tinfl_decompressor m_decomp;
+ mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed;
+ int m_window_bits;
+ mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
+ tinfl_status m_last_status;
+} inflate_state;
+
+int mz_inflateInit2(mz_streamp pStream, int window_bits)
+{
+ inflate_state *pDecomp;
+ if (!pStream)
+ return MZ_STREAM_ERROR;
+ if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))
+ return MZ_PARAM_ERROR;
+
+ pStream->data_type = 0;
+ pStream->adler = 0;
+ pStream->msg = NULL;
+ pStream->total_in = 0;
+ pStream->total_out = 0;
+ pStream->reserved = 0;
+ if (!pStream->zalloc)
+ pStream->zalloc = miniz_def_alloc_func;
+ if (!pStream->zfree)
+ pStream->zfree = miniz_def_free_func;
+
+ pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
+ if (!pDecomp)
+ return MZ_MEM_ERROR;
+
+ pStream->state = (struct mz_internal_state *)pDecomp;
+
+ tinfl_init(&pDecomp->m_decomp);
+ pDecomp->m_dict_ofs = 0;
+ pDecomp->m_dict_avail = 0;
+ pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
+ pDecomp->m_first_call = 1;
+ pDecomp->m_has_flushed = 0;
+ pDecomp->m_window_bits = window_bits;
+
+ return MZ_OK;
+}
+
+int mz_inflateInit(mz_streamp pStream)
+{
+ return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
+}
+
+int mz_inflateReset(mz_streamp pStream)
+{
+ inflate_state *pDecomp;
+ if (!pStream)
+ return MZ_STREAM_ERROR;
+
+ pStream->data_type = 0;
+ pStream->adler = 0;
+ pStream->msg = NULL;
+ pStream->total_in = 0;
+ pStream->total_out = 0;
+ pStream->reserved = 0;
+
+ pDecomp = (inflate_state *)pStream->state;
+
+ tinfl_init(&pDecomp->m_decomp);
+ pDecomp->m_dict_ofs = 0;
+ pDecomp->m_dict_avail = 0;
+ pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
+ pDecomp->m_first_call = 1;
+ pDecomp->m_has_flushed = 0;
+ /* pDecomp->m_window_bits = window_bits */;
+
+ return MZ_OK;
+}
+
+int mz_inflate(mz_streamp pStream, int flush)
+{
+ inflate_state *pState;
+ mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
+ size_t in_bytes, out_bytes, orig_avail_in;
+ tinfl_status status;
+
+ if ((!pStream) || (!pStream->state))
+ return MZ_STREAM_ERROR;
+ if (flush == MZ_PARTIAL_FLUSH)
+ flush = MZ_SYNC_FLUSH;
+ if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH))
+ return MZ_STREAM_ERROR;
+
+ pState = (inflate_state *)pStream->state;
+ if (pState->m_window_bits > 0)
+ decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
+ orig_avail_in = pStream->avail_in;
+
+ first_call = pState->m_first_call;
+ pState->m_first_call = 0;
+ if (pState->m_last_status < 0)
+ return MZ_DATA_ERROR;
+
+ if (pState->m_has_flushed && (flush != MZ_FINISH))
+ return MZ_STREAM_ERROR;
+ pState->m_has_flushed |= (flush == MZ_FINISH);
+
+ if ((flush == MZ_FINISH) && (first_call))
+ {
+ /* MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. */
+ decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
+ in_bytes = pStream->avail_in;
+ out_bytes = pStream->avail_out;
+ status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
+ pState->m_last_status = status;
+ pStream->next_in += (mz_uint)in_bytes;
+ pStream->avail_in -= (mz_uint)in_bytes;
+ pStream->total_in += (mz_uint)in_bytes;
+ pStream->adler = tinfl_get_adler32(&pState->m_decomp);
+ pStream->next_out += (mz_uint)out_bytes;
+ pStream->avail_out -= (mz_uint)out_bytes;
+ pStream->total_out += (mz_uint)out_bytes;
+
+ if (status < 0)
+ return MZ_DATA_ERROR;
+ else if (status != TINFL_STATUS_DONE)
+ {
+ pState->m_last_status = TINFL_STATUS_FAILED;
+ return MZ_BUF_ERROR;
+ }
+ return MZ_STREAM_END;
+ }
+ /* flush != MZ_FINISH then we must assume there's more input. */
+ if (flush != MZ_FINISH)
+ decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
+
+ if (pState->m_dict_avail)
+ {
+ n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
+ memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
+ pStream->next_out += n;
+ pStream->avail_out -= n;
+ pStream->total_out += n;
+ pState->m_dict_avail -= n;
+ pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
+ return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
+ }
+
+ for (;;)
+ {
+ in_bytes = pStream->avail_in;
+ out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
+
+ status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags);
+ pState->m_last_status = status;
+
+ pStream->next_in += (mz_uint)in_bytes;
+ pStream->avail_in -= (mz_uint)in_bytes;
+ pStream->total_in += (mz_uint)in_bytes;
+ pStream->adler = tinfl_get_adler32(&pState->m_decomp);
+
+ pState->m_dict_avail = (mz_uint)out_bytes;
+
+ n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
+ memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
+ pStream->next_out += n;
+ pStream->avail_out -= n;
+ pStream->total_out += n;
+ pState->m_dict_avail -= n;
+ pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
+
+ if (status < 0)
+ return MZ_DATA_ERROR; /* Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). */
+ else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
+ return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. */
+ else if (flush == MZ_FINISH)
+ {
+ /* The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. */
+ if (status == TINFL_STATUS_DONE)
+ return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
+ /* status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. */
+ else if (!pStream->avail_out)
+ return MZ_BUF_ERROR;
+ }
+ else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
+ break;
+ }
+
+ return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
+}
+
+int mz_inflateEnd(mz_streamp pStream)
+{
+ if (!pStream)
+ return MZ_STREAM_ERROR;
+ if (pStream->state)
+ {
+ pStream->zfree(pStream->opaque, pStream->state);
+ pStream->state = NULL;
+ }
+ return MZ_OK;
+}
+int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong *pSource_len)
+{
+ mz_stream stream;
+ int status;
+ memset(&stream, 0, sizeof(stream));
+
+ /* In case mz_ulong is 64-bits (argh I hate longs). */
+ if ((*pSource_len | *pDest_len) > 0xFFFFFFFFU)
+ return MZ_PARAM_ERROR;
+
+ stream.next_in = pSource;
+ stream.avail_in = (mz_uint32)*pSource_len;
+ stream.next_out = pDest;
+ stream.avail_out = (mz_uint32)*pDest_len;
+
+ status = mz_inflateInit(&stream);
+ if (status != MZ_OK)
+ return status;
+
+ status = mz_inflate(&stream, MZ_FINISH);
+ *pSource_len = *pSource_len - stream.avail_in;
+ if (status != MZ_STREAM_END)
+ {
+ mz_inflateEnd(&stream);
+ return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
+ }
+ *pDest_len = stream.total_out;
+
+ return mz_inflateEnd(&stream);
+}
+
+int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
+{
+ return mz_uncompress2(pDest, pDest_len, pSource, &source_len);
+}
+
+const char *mz_error(int err)
+{
+ static struct
+ {
+ int m_err;
+ const char *m_pDesc;
+ } s_error_descs[] =
+ {
+ { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" }
+ };
+ mz_uint i;
+ for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i)
+ if (s_error_descs[i].m_err == err)
+ return s_error_descs[i].m_pDesc;
+ return NULL;
+}
+
+#endif /*MINIZ_NO_ZLIB_APIS */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ This is free and unencumbered software released into the public domain.
+
+ Anyone is free to copy, modify, publish, use, compile, sell, or
+ distribute this software, either in source code form or as a compiled
+ binary, for any purpose, commercial or non-commercial, and by any
+ means.
+
+ In jurisdictions that recognize copyright laws, the author or authors
+ of this software dedicate any and all copyright interest in the
+ software to the public domain. We make this dedication for the benefit
+ of the public at large and to the detriment of our heirs and
+ successors. We intend this dedication to be an overt act of
+ relinquishment in perpetuity of all present and future rights to this
+ software under copyright law.
+
+ 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 AUTHORS 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.
+
+ For more information, please refer to <http://unlicense.org/>
+*/
+/**************************************************************************
+ *
+ * Copyright 2013-2014 RAD Game Tools and Valve Software
+ * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
+ * All Rights Reserved.
+ *
+ * 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
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ **************************************************************************/
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ------------------- Low-level Compression (independent from all decompression API's) */
+
+/* Purposely making these tables static for faster init and thread safety. */
+static const mz_uint16 s_tdefl_len_sym[256] =
+ {
+ 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272,
+ 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, 276, 276, 276, 276,
+ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
+ 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280,
+ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281,
+ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282,
+ 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 285
+ };
+
+static const mz_uint8 s_tdefl_len_extra[256] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0
+ };
+
+static const mz_uint8 s_tdefl_small_dist_sym[512] =
+ {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17
+ };
+
+static const mz_uint8 s_tdefl_small_dist_extra[512] =
+ {
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7
+ };
+
+static const mz_uint8 s_tdefl_large_dist_sym[128] =
+ {
+ 0, 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+ };
+
+static const mz_uint8 s_tdefl_large_dist_extra[128] =
+ {
+ 0, 0, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13
+ };
+
+/* Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values. */
+typedef struct
+{
+ mz_uint16 m_key, m_sym_index;
+} tdefl_sym_freq;
+static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq *pSyms0, tdefl_sym_freq *pSyms1)
+{
+ mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2];
+ tdefl_sym_freq *pCur_syms = pSyms0, *pNew_syms = pSyms1;
+ MZ_CLEAR_OBJ(hist);
+ for (i = 0; i < num_syms; i++)
+ {
+ mz_uint freq = pSyms0[i].m_key;
+ hist[freq & 0xFF]++;
+ hist[256 + ((freq >> 8) & 0xFF)]++;
+ }
+ while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256]))
+ total_passes--;
+ for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8)
+ {
+ const mz_uint32 *pHist = &hist[pass << 8];
+ mz_uint offsets[256], cur_ofs = 0;
+ for (i = 0; i < 256; i++)
+ {
+ offsets[i] = cur_ofs;
+ cur_ofs += pHist[i];
+ }
+ for (i = 0; i < num_syms; i++)
+ pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i];
+ {
+ tdefl_sym_freq *t = pCur_syms;
+ pCur_syms = pNew_syms;
+ pNew_syms = t;
+ }
+ }
+ return pCur_syms;
+}
+
+/* tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. */
+static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n)
+{
+ int root, leaf, next, avbl, used, dpth;
+ if (n == 0)
+ return;
+ else if (n == 1)
+ {
+ A[0].m_key = 1;
+ return;
+ }
+ A[0].m_key += A[1].m_key;
+ root = 0;
+ leaf = 2;
+ for (next = 1; next < n - 1; next++)
+ {
+ if (leaf >= n || A[root].m_key < A[leaf].m_key)
+ {
+ A[next].m_key = A[root].m_key;
+ A[root++].m_key = (mz_uint16)next;
+ }
+ else
+ A[next].m_key = A[leaf++].m_key;
+ if (leaf >= n || (root < next && A[root].m_key < A[leaf].m_key))
+ {
+ A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key);
+ A[root++].m_key = (mz_uint16)next;
+ }
+ else
+ A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key);
+ }
+ A[n - 2].m_key = 0;
+ for (next = n - 3; next >= 0; next--)
+ A[next].m_key = A[A[next].m_key].m_key + 1;
+ avbl = 1;
+ used = dpth = 0;
+ root = n - 2;
+ next = n - 1;
+ while (avbl > 0)
+ {
+ while (root >= 0 && (int)A[root].m_key == dpth)
+ {
+ used++;
+ root--;
+ }
+ while (avbl > used)
+ {
+ A[next--].m_key = (mz_uint16)(dpth);
+ avbl--;
+ }
+ avbl = 2 * used;
+ dpth++;
+ used = 0;
+ }
+}
+
+/* Limits canonical Huffman code table's max code size. */
+enum
+{
+ TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32
+};
+static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size)
+{
+ int i;
+ mz_uint32 total = 0;
+ if (code_list_len <= 1)
+ return;
+ for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++)
+ pNum_codes[max_code_size] += pNum_codes[i];
+ for (i = max_code_size; i > 0; i--)
+ total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
+ while (total != (1UL << max_code_size))
+ {
+ pNum_codes[max_code_size]--;
+ for (i = max_code_size - 1; i > 0; i--)
+ if (pNum_codes[i])
+ {
+ pNum_codes[i]--;
+ pNum_codes[i + 1] += 2;
+ break;
+ }
+ total--;
+ }
+}
+
+static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table)
+{
+ int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE];
+ mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1];
+ MZ_CLEAR_OBJ(num_codes);
+ if (static_table)
+ {
+ for (i = 0; i < table_len; i++)
+ num_codes[d->m_huff_code_sizes[table_num][i]]++;
+ }
+ else
+ {
+ tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms;
+ int num_used_syms = 0;
+ const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
+ for (i = 0; i < table_len; i++)
+ if (pSym_count[i])
+ {
+ syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i];
+ syms0[num_used_syms++].m_sym_index = (mz_uint16)i;
+ }
+
+ pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1);
+ tdefl_calculate_minimum_redundancy(pSyms, num_used_syms);
+
+ for (i = 0; i < num_used_syms; i++)
+ num_codes[pSyms[i].m_key]++;
+
+ tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit);
+
+ MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]);
+ MZ_CLEAR_OBJ(d->m_huff_codes[table_num]);
+ for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
+ for (l = num_codes[i]; l > 0; l--)
+ d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
+ }
+
+ next_code[1] = 0;
+ for (j = 0, i = 2; i <= code_size_limit; i++)
+ next_code[i] = j = ((j + num_codes[i - 1]) << 1);
+
+ for (i = 0; i < table_len; i++)
+ {
+ mz_uint rev_code = 0, code, code_size;
+ if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0)
+ continue;
+ code = next_code[code_size]++;
+ for (l = code_size; l > 0; l--, code >>= 1)
+ rev_code = (rev_code << 1) | (code & 1);
+ d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
+ }
+}
+
+#define TDEFL_PUT_BITS(b, l) \
+ do \
+ { \
+ mz_uint bits = b; \
+ mz_uint len = l; \
+ MZ_ASSERT(bits <= ((1U << len) - 1U)); \
+ d->m_bit_buffer |= (bits << d->m_bits_in); \
+ d->m_bits_in += len; \
+ while (d->m_bits_in >= 8) \
+ { \
+ if (d->m_pOutput_buf < d->m_pOutput_buf_end) \
+ *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
+ d->m_bit_buffer >>= 8; \
+ d->m_bits_in -= 8; \
+ } \
+ } \
+ MZ_MACRO_END
+
+#define TDEFL_RLE_PREV_CODE_SIZE() \
+ { \
+ if (rle_repeat_count) \
+ { \
+ if (rle_repeat_count < 3) \
+ { \
+ d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
+ while (rle_repeat_count--) \
+ packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
+ } \
+ else \
+ { \
+ d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); \
+ packed_code_sizes[num_packed_code_sizes++] = 16; \
+ packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \
+ } \
+ rle_repeat_count = 0; \
+ } \
+ }
+
+#define TDEFL_RLE_ZERO_CODE_SIZE() \
+ { \
+ if (rle_z_count) \
+ { \
+ if (rle_z_count < 3) \
+ { \
+ d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); \
+ while (rle_z_count--) \
+ packed_code_sizes[num_packed_code_sizes++] = 0; \
+ } \
+ else if (rle_z_count <= 10) \
+ { \
+ d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); \
+ packed_code_sizes[num_packed_code_sizes++] = 17; \
+ packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \
+ } \
+ else \
+ { \
+ d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); \
+ packed_code_sizes[num_packed_code_sizes++] = 18; \
+ packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \
+ } \
+ rle_z_count = 0; \
+ } \
+ }
+
+static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
+
+static void tdefl_start_dynamic_block(tdefl_compressor *d)
+{
+ int num_lit_codes, num_dist_codes, num_bit_lengths;
+ mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index;
+ mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF;
+
+ d->m_huff_count[0][256] = 1;
+
+ tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE);
+ tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE);
+
+ for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--)
+ if (d->m_huff_code_sizes[0][num_lit_codes - 1])
+ break;
+ for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--)
+ if (d->m_huff_code_sizes[1][num_dist_codes - 1])
+ break;
+
+ memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
+ memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes);
+ total_code_sizes_to_pack = num_lit_codes + num_dist_codes;
+ num_packed_code_sizes = 0;
+ rle_z_count = 0;
+ rle_repeat_count = 0;
+
+ memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
+ for (i = 0; i < total_code_sizes_to_pack; i++)
+ {
+ mz_uint8 code_size = code_sizes_to_pack[i];
+ if (!code_size)
+ {
+ TDEFL_RLE_PREV_CODE_SIZE();
+ if (++rle_z_count == 138)
+ {
+ TDEFL_RLE_ZERO_CODE_SIZE();
+ }
+ }
+ else
+ {
+ TDEFL_RLE_ZERO_CODE_SIZE();
+ if (code_size != prev_code_size)
+ {
+ TDEFL_RLE_PREV_CODE_SIZE();
+ d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1);
+ packed_code_sizes[num_packed_code_sizes++] = code_size;
+ }
+ else if (++rle_repeat_count == 6)
+ {
+ TDEFL_RLE_PREV_CODE_SIZE();
+ }
+ }
+ prev_code_size = code_size;
+ }
+ if (rle_repeat_count)
+ {
+ TDEFL_RLE_PREV_CODE_SIZE();
+ }
+ else
+ {
+ TDEFL_RLE_ZERO_CODE_SIZE();
+ }
+
+ tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE);
+
+ TDEFL_PUT_BITS(2, 2);
+
+ TDEFL_PUT_BITS(num_lit_codes - 257, 5);
+ TDEFL_PUT_BITS(num_dist_codes - 1, 5);
+
+ for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--)
+ if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]])
+ break;
+ num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1));
+ TDEFL_PUT_BITS(num_bit_lengths - 4, 4);
+ for (i = 0; (int)i < num_bit_lengths; i++)
+ TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3);
+
+ for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes;)
+ {
+ mz_uint code = packed_code_sizes[packed_code_sizes_index++];
+ MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2);
+ TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
+ if (code >= 16)
+ TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]);
+ }
+}
+
+static void tdefl_start_static_block(tdefl_compressor *d)
+{
+ mz_uint i;
+ mz_uint8 *p = &d->m_huff_code_sizes[0][0];
+
+ for (i = 0; i <= 143; ++i)
+ *p++ = 8;
+ for (; i <= 255; ++i)
+ *p++ = 9;
+ for (; i <= 279; ++i)
+ *p++ = 7;
+ for (; i <= 287; ++i)
+ *p++ = 8;
+
+ memset(d->m_huff_code_sizes[1], 5, 32);
+
+ tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
+ tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE);
+
+ TDEFL_PUT_BITS(1, 2);
+}
+
+static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
+static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
+{
+ mz_uint flags;
+ mz_uint8 *pLZ_codes;
+ mz_uint8 *pOutput_buf = d->m_pOutput_buf;
+ mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
+ mz_uint64 bit_buffer = d->m_bit_buffer;
+ mz_uint bits_in = d->m_bits_in;
+
+#define TDEFL_PUT_BITS_FAST(b, l) \
+ { \
+ bit_buffer |= (((mz_uint64)(b)) << bits_in); \
+ bits_in += (l); \
+ }
+
+ flags = 1;
+ for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1)
+ {
+ if (flags == 1)
+ flags = *pLZ_codes++ | 0x100;
+
+ if (flags & 1)
+ {
+ mz_uint s0, s1, n0, n1, sym, num_extra_bits;
+ mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1);
+ pLZ_codes += 3;
+
+ MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
+ TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
+
+ /* This sequence coaxes MSVC into using cmov's vs. jmp's. */
+ s0 = s_tdefl_small_dist_sym[match_dist & 511];
+ n0 = s_tdefl_small_dist_extra[match_dist & 511];
+ s1 = s_tdefl_large_dist_sym[match_dist >> 8];
+ n1 = s_tdefl_large_dist_extra[match_dist >> 8];
+ sym = (match_dist < 512) ? s0 : s1;
+ num_extra_bits = (match_dist < 512) ? n0 : n1;
+
+ MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
+ TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
+ }
+ else
+ {
+ mz_uint lit = *pLZ_codes++;
+ MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
+
+ if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
+ {
+ flags >>= 1;
+ lit = *pLZ_codes++;
+ MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
+
+ if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
+ {
+ flags >>= 1;
+ lit = *pLZ_codes++;
+ MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
+ }
+ }
+ }
+
+ if (pOutput_buf >= d->m_pOutput_buf_end)
+ return MZ_FALSE;
+
+ *(mz_uint64 *)pOutput_buf = bit_buffer;
+ pOutput_buf += (bits_in >> 3);
+ bit_buffer >>= (bits_in & ~7);
+ bits_in &= 7;
+ }
+
+#undef TDEFL_PUT_BITS_FAST
+
+ d->m_pOutput_buf = pOutput_buf;
+ d->m_bits_in = 0;
+ d->m_bit_buffer = 0;
+
+ while (bits_in)
+ {
+ mz_uint32 n = MZ_MIN(bits_in, 16);
+ TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n);
+ bit_buffer >>= n;
+ bits_in -= n;
+ }
+
+ TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
+
+ return (d->m_pOutput_buf < d->m_pOutput_buf_end);
+}
+#else
+static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
+{
+ mz_uint flags;
+ mz_uint8 *pLZ_codes;
+
+ flags = 1;
+ for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1)
+ {
+ if (flags == 1)
+ flags = *pLZ_codes++ | 0x100;
+ if (flags & 1)
+ {
+ mz_uint sym, num_extra_bits;
+ mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8));
+ pLZ_codes += 3;
+
+ MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
+ TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
+ TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
+
+ if (match_dist < 512)
+ {
+ sym = s_tdefl_small_dist_sym[match_dist];
+ num_extra_bits = s_tdefl_small_dist_extra[match_dist];
+ }
+ else
+ {
+ sym = s_tdefl_large_dist_sym[match_dist >> 8];
+ num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8];
+ }
+ MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
+ TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
+ TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
+ }
+ else
+ {
+ mz_uint lit = *pLZ_codes++;
+ MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
+ TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
+ }
+ }
+
+ TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
+
+ return (d->m_pOutput_buf < d->m_pOutput_buf_end);
+}
+#endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS */
+
+static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block)
+{
+ if (static_block)
+ tdefl_start_static_block(d);
+ else
+ tdefl_start_dynamic_block(d);
+ return tdefl_compress_lz_codes(d);
+}
+
+static int tdefl_flush_block(tdefl_compressor *d, int flush)
+{
+ mz_uint saved_bit_buf, saved_bits_in;
+ mz_uint8 *pSaved_output_buf;
+ mz_bool comp_block_succeeded = MZ_FALSE;
+ int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size;
+ mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf;
+
+ d->m_pOutput_buf = pOutput_buf_start;
+ d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16;
+
+ MZ_ASSERT(!d->m_output_flush_remaining);
+ d->m_output_flush_ofs = 0;
+ d->m_output_flush_remaining = 0;
+
+ *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
+ d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);
+
+ if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index))
+ {
+ TDEFL_PUT_BITS(0x78, 8);
+ TDEFL_PUT_BITS(0x01, 8);
+ }
+
+ TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
+
+ pSaved_output_buf = d->m_pOutput_buf;
+ saved_bit_buf = d->m_bit_buffer;
+ saved_bits_in = d->m_bits_in;
+
+ if (!use_raw_block)
+ comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48));
+
+ /* If the block gets expanded, forget the current contents of the output buffer and send a raw block instead. */
+ if (((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) &&
+ ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size))
+ {
+ mz_uint i;
+ d->m_pOutput_buf = pSaved_output_buf;
+ d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
+ TDEFL_PUT_BITS(0, 2);
+ if (d->m_bits_in)
+ {
+ TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
+ }
+ for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF)
+ {
+ TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
+ }
+ for (i = 0; i < d->m_total_lz_bytes; ++i)
+ {
+ TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8);
+ }
+ }
+ /* Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes. */
+ else if (!comp_block_succeeded)
+ {
+ d->m_pOutput_buf = pSaved_output_buf;
+ d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
+ tdefl_compress_block(d, MZ_TRUE);
+ }
+
+ if (flush)
+ {
+ if (flush == TDEFL_FINISH)
+ {
+ if (d->m_bits_in)
+ {
+ TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
+ }
+ if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER)
+ {
+ mz_uint i, a = d->m_adler32;
+ for (i = 0; i < 4; i++)
+ {
+ TDEFL_PUT_BITS((a >> 24) & 0xFF, 8);
+ a <<= 8;
+ }
+ }
+ }
+ else
+ {
+ mz_uint i, z = 0;
+ TDEFL_PUT_BITS(0, 3);
+ if (d->m_bits_in)
+ {
+ TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
+ }
+ for (i = 2; i; --i, z ^= 0xFFFF)
+ {
+ TDEFL_PUT_BITS(z & 0xFFFF, 16);
+ }
+ }
+ }
+
+ MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end);
+
+ memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
+ memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
+
+ d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
+ d->m_pLZ_flags = d->m_lz_code_buf;
+ d->m_num_flags_left = 8;
+ d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes;
+ d->m_total_lz_bytes = 0;
+ d->m_block_index++;
+
+ if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0)
+ {
+ if (d->m_pPut_buf_func)
+ {
+ *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
+ if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
+ return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED);
+ }
+ else if (pOutput_buf_start == d->m_output_buf)
+ {
+ int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
+ memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy);
+ d->m_out_buf_ofs += bytes_to_copy;
+ if ((n -= bytes_to_copy) != 0)
+ {
+ d->m_output_flush_ofs = bytes_to_copy;
+ d->m_output_flush_remaining = n;
+ }
+ }
+ else
+ {
+ d->m_out_buf_ofs += n;
+ }
+ }
+
+ return d->m_output_flush_remaining;
+}
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
+#ifdef MINIZ_UNALIGNED_USE_MEMCPY
+static mz_uint16 TDEFL_READ_UNALIGNED_WORD(const mz_uint8* p)
+{
+ mz_uint16 ret;
+ memcpy(&ret, p, sizeof(mz_uint16));
+ return ret;
+}
+static mz_uint16 TDEFL_READ_UNALIGNED_WORD2(const mz_uint16* p)
+{
+ mz_uint16 ret;
+ memcpy(&ret, p, sizeof(mz_uint16));
+ return ret;
+}
+#else
+#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p)
+#define TDEFL_READ_UNALIGNED_WORD2(p) *(const mz_uint16 *)(p)
+#endif
+static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
+{
+ mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
+ mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
+ const mz_uint16 *s = (const mz_uint16 *)(d->m_dict + pos), *p, *q;
+ mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD2(s);
+ MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
+ if (max_match_len <= match_len)
+ return;
+ for (;;)
+ {
+ for (;;)
+ {
+ if (--num_probes_left == 0)
+ return;
+#define TDEFL_PROBE \
+ next_probe_pos = d->m_next[probe_pos]; \
+ if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
+ return; \
+ probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
+ if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) \
+ break;
+ TDEFL_PROBE;
+ TDEFL_PROBE;
+ TDEFL_PROBE;
+ }
+ if (!dist)
+ break;
+ q = (const mz_uint16 *)(d->m_dict + probe_pos);
+ if (TDEFL_READ_UNALIGNED_WORD2(q) != s01)
+ continue;
+ p = s;
+ probe_len = 32;
+ do
+ {
+ } while ((TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) &&
+ (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (--probe_len > 0));
+ if (!probe_len)
+ {
+ *pMatch_dist = dist;
+ *pMatch_len = MZ_MIN(max_match_len, (mz_uint)TDEFL_MAX_MATCH_LEN);
+ break;
+ }
+ else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q)) > match_len)
+ {
+ *pMatch_dist = dist;
+ if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len)
+ break;
+ c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
+ }
+ }
+}
+#else
+static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
+{
+ mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
+ mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
+ const mz_uint8 *s = d->m_dict + pos, *p, *q;
+ mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
+ MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
+ if (max_match_len <= match_len)
+ return;
+ for (;;)
+ {
+ for (;;)
+ {
+ if (--num_probes_left == 0)
+ return;
+#define TDEFL_PROBE \
+ next_probe_pos = d->m_next[probe_pos]; \
+ if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
+ return; \
+ probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
+ if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) \
+ break;
+ TDEFL_PROBE;
+ TDEFL_PROBE;
+ TDEFL_PROBE;
+ }
+ if (!dist)
+ break;
+ p = s;
+ q = d->m_dict + probe_pos;
+ for (probe_len = 0; probe_len < max_match_len; probe_len++)
+ if (*p++ != *q++)
+ break;
+ if (probe_len > match_len)
+ {
+ *pMatch_dist = dist;
+ if ((*pMatch_len = match_len = probe_len) == max_match_len)
+ return;
+ c0 = d->m_dict[pos + match_len];
+ c1 = d->m_dict[pos + match_len - 1];
+ }
+ }
+}
+#endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES */
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
+#ifdef MINIZ_UNALIGNED_USE_MEMCPY
+static mz_uint32 TDEFL_READ_UNALIGNED_WORD32(const mz_uint8* p)
+{
+ mz_uint32 ret;
+ memcpy(&ret, p, sizeof(mz_uint32));
+ return ret;
+}
+#else
+#define TDEFL_READ_UNALIGNED_WORD32(p) *(const mz_uint32 *)(p)
+#endif
+static mz_bool tdefl_compress_fast(tdefl_compressor *d)
+{
+ /* Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio. */
+ mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left;
+ mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
+ mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
+
+ while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size)))
+ {
+ const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096;
+ mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
+ mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size);
+ d->m_src_buf_left -= num_bytes_to_process;
+ lookahead_size += num_bytes_to_process;
+
+ while (num_bytes_to_process)
+ {
+ mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process);
+ memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
+ if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
+ memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
+ d->m_pSrc += n;
+ dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK;
+ num_bytes_to_process -= n;
+ }
+
+ dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size);
+ if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE))
+ break;
+
+ while (lookahead_size >= 4)
+ {
+ mz_uint cur_match_dist, cur_match_len = 1;
+ mz_uint8 *pCur_dict = d->m_dict + cur_pos;
+ mz_uint first_trigram = TDEFL_READ_UNALIGNED_WORD32(pCur_dict) & 0xFFFFFF;
+ mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK;
+ mz_uint probe_pos = d->m_hash[hash];
+ d->m_hash[hash] = (mz_uint16)lookahead_pos;
+
+ if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((TDEFL_READ_UNALIGNED_WORD32(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram))
+ {
+ const mz_uint16 *p = (const mz_uint16 *)pCur_dict;
+ const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos);
+ mz_uint32 probe_len = 32;
+ do
+ {
+ } while ((TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) &&
+ (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (--probe_len > 0));
+ cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q);
+ if (!probe_len)
+ cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0;
+
+ if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U)))
+ {
+ cur_match_len = 1;
+ *pLZ_code_buf++ = (mz_uint8)first_trigram;
+ *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
+ d->m_huff_count[0][(mz_uint8)first_trigram]++;
+ }
+ else
+ {
+ mz_uint32 s0, s1;
+ cur_match_len = MZ_MIN(cur_match_len, lookahead_size);
+
+ MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE));
+
+ cur_match_dist--;
+
+ pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
+#ifdef MINIZ_UNALIGNED_USE_MEMCPY
+ memcpy(&pLZ_code_buf[1], &cur_match_dist, sizeof(cur_match_dist));
+#else
+ *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
+#endif
+ pLZ_code_buf += 3;
+ *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);
+
+ s0 = s_tdefl_small_dist_sym[cur_match_dist & 511];
+ s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8];
+ d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++;
+
+ d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++;
+ }
+ }
+ else
+ {
+ *pLZ_code_buf++ = (mz_uint8)first_trigram;
+ *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
+ d->m_huff_count[0][(mz_uint8)first_trigram]++;
+ }
+
+ if (--num_flags_left == 0)
+ {
+ num_flags_left = 8;
+ pLZ_flags = pLZ_code_buf++;
+ }
+
+ total_lz_bytes += cur_match_len;
+ lookahead_pos += cur_match_len;
+ dict_size = MZ_MIN(dict_size + cur_match_len, (mz_uint)TDEFL_LZ_DICT_SIZE);
+ cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK;
+ MZ_ASSERT(lookahead_size >= cur_match_len);
+ lookahead_size -= cur_match_len;
+
+ if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
+ {
+ int n;
+ d->m_lookahead_pos = lookahead_pos;
+ d->m_lookahead_size = lookahead_size;
+ d->m_dict_size = dict_size;
+ d->m_total_lz_bytes = total_lz_bytes;
+ d->m_pLZ_code_buf = pLZ_code_buf;
+ d->m_pLZ_flags = pLZ_flags;
+ d->m_num_flags_left = num_flags_left;
+ if ((n = tdefl_flush_block(d, 0)) != 0)
+ return (n < 0) ? MZ_FALSE : MZ_TRUE;
+ total_lz_bytes = d->m_total_lz_bytes;
+ pLZ_code_buf = d->m_pLZ_code_buf;
+ pLZ_flags = d->m_pLZ_flags;
+ num_flags_left = d->m_num_flags_left;
+ }
+ }
+
+ while (lookahead_size)
+ {
+ mz_uint8 lit = d->m_dict[cur_pos];
+
+ total_lz_bytes++;
+ *pLZ_code_buf++ = lit;
+ *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
+ if (--num_flags_left == 0)
+ {
+ num_flags_left = 8;
+ pLZ_flags = pLZ_code_buf++;
+ }
+
+ d->m_huff_count[0][lit]++;
+
+ lookahead_pos++;
+ dict_size = MZ_MIN(dict_size + 1, (mz_uint)TDEFL_LZ_DICT_SIZE);
+ cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
+ lookahead_size--;
+
+ if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
+ {
+ int n;
+ d->m_lookahead_pos = lookahead_pos;
+ d->m_lookahead_size = lookahead_size;
+ d->m_dict_size = dict_size;
+ d->m_total_lz_bytes = total_lz_bytes;
+ d->m_pLZ_code_buf = pLZ_code_buf;
+ d->m_pLZ_flags = pLZ_flags;
+ d->m_num_flags_left = num_flags_left;
+ if ((n = tdefl_flush_block(d, 0)) != 0)
+ return (n < 0) ? MZ_FALSE : MZ_TRUE;
+ total_lz_bytes = d->m_total_lz_bytes;
+ pLZ_code_buf = d->m_pLZ_code_buf;
+ pLZ_flags = d->m_pLZ_flags;
+ num_flags_left = d->m_num_flags_left;
+ }
+ }
+ }
+
+ d->m_lookahead_pos = lookahead_pos;
+ d->m_lookahead_size = lookahead_size;
+ d->m_dict_size = dict_size;
+ d->m_total_lz_bytes = total_lz_bytes;
+ d->m_pLZ_code_buf = pLZ_code_buf;
+ d->m_pLZ_flags = pLZ_flags;
+ d->m_num_flags_left = num_flags_left;
+ return MZ_TRUE;
+}
+#endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */
+
+static MZ_FORCEINLINE void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit)
+{
+ d->m_total_lz_bytes++;
+ *d->m_pLZ_code_buf++ = lit;
+ *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1);
+ if (--d->m_num_flags_left == 0)
+ {
+ d->m_num_flags_left = 8;
+ d->m_pLZ_flags = d->m_pLZ_code_buf++;
+ }
+ d->m_huff_count[0][lit]++;
+}
+
+static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist)
+{
+ mz_uint32 s0, s1;
+
+ MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE));
+
+ d->m_total_lz_bytes += match_len;
+
+ d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN);
+
+ match_dist -= 1;
+ d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF);
+ d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8);
+ d->m_pLZ_code_buf += 3;
+
+ *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80);
+ if (--d->m_num_flags_left == 0)
+ {
+ d->m_num_flags_left = 8;
+ d->m_pLZ_flags = d->m_pLZ_code_buf++;
+ }
+
+ s0 = s_tdefl_small_dist_sym[match_dist & 511];
+ s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
+ d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
+ d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
+}
+
+static mz_bool tdefl_compress_normal(tdefl_compressor *d)
+{
+ const mz_uint8 *pSrc = d->m_pSrc;
+ size_t src_buf_left = d->m_src_buf_left;
+ tdefl_flush flush = d->m_flush;
+
+ while ((src_buf_left) || ((flush) && (d->m_lookahead_size)))
+ {
+ mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos;
+ /* Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN. */
+ if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1))
+ {
+ mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2;
+ mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK];
+ mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size);
+ const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process;
+ src_buf_left -= num_bytes_to_process;
+ d->m_lookahead_size += num_bytes_to_process;
+ while (pSrc != pSrc_end)
+ {
+ mz_uint8 c = *pSrc++;
+ d->m_dict[dst_pos] = c;
+ if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
+ d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
+ hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
+ d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
+ d->m_hash[hash] = (mz_uint16)(ins_pos);
+ dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
+ ins_pos++;
+ }
+ }
+ else
+ {
+ while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
+ {
+ mz_uint8 c = *pSrc++;
+ mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
+ src_buf_left--;
+ d->m_dict[dst_pos] = c;
+ if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
+ d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
+ if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN)
+ {
+ mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2;
+ mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
+ d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
+ d->m_hash[hash] = (mz_uint16)(ins_pos);
+ }
+ }
+ }
+ d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size);
+ if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
+ break;
+
+ /* Simple lazy/greedy parsing state machine. */
+ len_to_move = 1;
+ cur_match_dist = 0;
+ cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1);
+ cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
+ if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS))
+ {
+ if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))
+ {
+ mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK];
+ cur_match_len = 0;
+ while (cur_match_len < d->m_lookahead_size)
+ {
+ if (d->m_dict[cur_pos + cur_match_len] != c)
+ break;
+ cur_match_len++;
+ }
+ if (cur_match_len < TDEFL_MIN_MATCH_LEN)
+ cur_match_len = 0;
+ else
+ cur_match_dist = 1;
+ }
+ }
+ else
+ {
+ tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len);
+ }
+ if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5)))
+ {
+ cur_match_dist = cur_match_len = 0;
+ }
+ if (d->m_saved_match_len)
+ {
+ if (cur_match_len > d->m_saved_match_len)
+ {
+ tdefl_record_literal(d, (mz_uint8)d->m_saved_lit);
+ if (cur_match_len >= 128)
+ {
+ tdefl_record_match(d, cur_match_len, cur_match_dist);
+ d->m_saved_match_len = 0;
+ len_to_move = cur_match_len;
+ }
+ else
+ {
+ d->m_saved_lit = d->m_dict[cur_pos];
+ d->m_saved_match_dist = cur_match_dist;
+ d->m_saved_match_len = cur_match_len;
+ }
+ }
+ else
+ {
+ tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist);
+ len_to_move = d->m_saved_match_len - 1;
+ d->m_saved_match_len = 0;
+ }
+ }
+ else if (!cur_match_dist)
+ tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]);
+ else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128))
+ {
+ tdefl_record_match(d, cur_match_len, cur_match_dist);
+ len_to_move = cur_match_len;
+ }
+ else
+ {
+ d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)];
+ d->m_saved_match_dist = cur_match_dist;
+ d->m_saved_match_len = cur_match_len;
+ }
+ /* Move the lookahead forward by len_to_move bytes. */
+ d->m_lookahead_pos += len_to_move;
+ MZ_ASSERT(d->m_lookahead_size >= len_to_move);
+ d->m_lookahead_size -= len_to_move;
+ d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, (mz_uint)TDEFL_LZ_DICT_SIZE);
+ /* Check if it's time to flush the current LZ codes to the internal output buffer. */
+ if ((d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) ||
+ ((d->m_total_lz_bytes > 31 * 1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))))
+ {
+ int n;
+ d->m_pSrc = pSrc;
+ d->m_src_buf_left = src_buf_left;
+ if ((n = tdefl_flush_block(d, 0)) != 0)
+ return (n < 0) ? MZ_FALSE : MZ_TRUE;
+ }
+ }
+
+ d->m_pSrc = pSrc;
+ d->m_src_buf_left = src_buf_left;
+ return MZ_TRUE;
+}
+
+static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d)
+{
+ if (d->m_pIn_buf_size)
+ {
+ *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
+ }
+
+ if (d->m_pOut_buf_size)
+ {
+ size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining);
+ memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n);
+ d->m_output_flush_ofs += (mz_uint)n;
+ d->m_output_flush_remaining -= (mz_uint)n;
+ d->m_out_buf_ofs += n;
+
+ *d->m_pOut_buf_size = d->m_out_buf_ofs;
+ }
+
+ return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY;
+}
+
+tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush)
+{
+ if (!d)
+ {
+ if (pIn_buf_size)
+ *pIn_buf_size = 0;
+ if (pOut_buf_size)
+ *pOut_buf_size = 0;
+ return TDEFL_STATUS_BAD_PARAM;
+ }
+
+ d->m_pIn_buf = pIn_buf;
+ d->m_pIn_buf_size = pIn_buf_size;
+ d->m_pOut_buf = pOut_buf;
+ d->m_pOut_buf_size = pOut_buf_size;
+ d->m_pSrc = (const mz_uint8 *)(pIn_buf);
+ d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0;
+ d->m_out_buf_ofs = 0;
+ d->m_flush = flush;
+
+ if (((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) ||
+ (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf))
+ {
+ if (pIn_buf_size)
+ *pIn_buf_size = 0;
+ if (pOut_buf_size)
+ *pOut_buf_size = 0;
+ return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM);
+ }
+ d->m_wants_to_finish |= (flush == TDEFL_FINISH);
+
+ if ((d->m_output_flush_remaining) || (d->m_finished))
+ return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
+ if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) &&
+ ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) &&
+ ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0))
+ {
+ if (!tdefl_compress_fast(d))
+ return d->m_prev_return_status;
+ }
+ else
+#endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */
+ {
+ if (!tdefl_compress_normal(d))
+ return d->m_prev_return_status;
+ }
+
+ if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf))
+ d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf);
+
+ if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining))
+ {
+ if (tdefl_flush_block(d, flush) < 0)
+ return d->m_prev_return_status;
+ d->m_finished = (flush == TDEFL_FINISH);
+ if (flush == TDEFL_FULL_FLUSH)
+ {
+ MZ_CLEAR_OBJ(d->m_hash);
+ MZ_CLEAR_OBJ(d->m_next);
+ d->m_dict_size = 0;
+ }
+ }
+
+ return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
+}
+
+tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush)
+{
+ MZ_ASSERT(d->m_pPut_buf_func);
+ return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush);
+}
+
+tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
+{
+ d->m_pPut_buf_func = pPut_buf_func;
+ d->m_pPut_buf_user = pPut_buf_user;
+ d->m_flags = (mz_uint)(flags);
+ d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3;
+ d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
+ d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
+ if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG))
+ MZ_CLEAR_OBJ(d->m_hash);
+ d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0;
+ d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0;
+ d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
+ d->m_pLZ_flags = d->m_lz_code_buf;
+ *d->m_pLZ_flags = 0;
+ d->m_num_flags_left = 8;
+ d->m_pOutput_buf = d->m_output_buf;
+ d->m_pOutput_buf_end = d->m_output_buf;
+ d->m_prev_return_status = TDEFL_STATUS_OKAY;
+ d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0;
+ d->m_adler32 = 1;
+ d->m_pIn_buf = NULL;
+ d->m_pOut_buf = NULL;
+ d->m_pIn_buf_size = NULL;
+ d->m_pOut_buf_size = NULL;
+ d->m_flush = TDEFL_NO_FLUSH;
+ d->m_pSrc = NULL;
+ d->m_src_buf_left = 0;
+ d->m_out_buf_ofs = 0;
+ if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG))
+ MZ_CLEAR_OBJ(d->m_dict);
+ memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
+ memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
+ return TDEFL_STATUS_OKAY;
+}
+
+tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d)
+{
+ return d->m_prev_return_status;
+}
+
+mz_uint32 tdefl_get_adler32(tdefl_compressor *d)
+{
+ return d->m_adler32;
+}
+
+mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
+{
+ tdefl_compressor *pComp;
+ mz_bool succeeded;
+ if (((buf_len) && (!pBuf)) || (!pPut_buf_func))
+ return MZ_FALSE;
+ pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
+ if (!pComp)
+ return MZ_FALSE;
+ succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY);
+ succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE);
+ MZ_FREE(pComp);
+ return succeeded;
+}
+
+typedef struct
+{
+ size_t m_size, m_capacity;
+ mz_uint8 *m_pBuf;
+ mz_bool m_expandable;
+} tdefl_output_buffer;
+
+static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser)
+{
+ tdefl_output_buffer *p = (tdefl_output_buffer *)pUser;
+ size_t new_size = p->m_size + len;
+ if (new_size > p->m_capacity)
+ {
+ size_t new_capacity = p->m_capacity;
+ mz_uint8 *pNew_buf;
+ if (!p->m_expandable)
+ return MZ_FALSE;
+ do
+ {
+ new_capacity = MZ_MAX(128U, new_capacity << 1U);
+ } while (new_size > new_capacity);
+ pNew_buf = (mz_uint8 *)MZ_REALLOC(p->m_pBuf, new_capacity);
+ if (!pNew_buf)
+ return MZ_FALSE;
+ p->m_pBuf = pNew_buf;
+ p->m_capacity = new_capacity;
+ }
+ memcpy((mz_uint8 *)p->m_pBuf + p->m_size, pBuf, len);
+ p->m_size = new_size;
+ return MZ_TRUE;
+}
+
+void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
+{
+ tdefl_output_buffer out_buf;
+ MZ_CLEAR_OBJ(out_buf);
+ if (!pOut_len)
+ return MZ_FALSE;
+ else
+ *pOut_len = 0;
+ out_buf.m_expandable = MZ_TRUE;
+ if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
+ return NULL;
+ *pOut_len = out_buf.m_size;
+ return out_buf.m_pBuf;
+}
+
+size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
+{
+ tdefl_output_buffer out_buf;
+ MZ_CLEAR_OBJ(out_buf);
+ if (!pOut_buf)
+ return 0;
+ out_buf.m_pBuf = (mz_uint8 *)pOut_buf;
+ out_buf.m_capacity = out_buf_len;
+ if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
+ return 0;
+ return out_buf.m_size;
+}
+
+static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
+
+/* level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files). */
+mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy)
+{
+ mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
+ if (window_bits > 0)
+ comp_flags |= TDEFL_WRITE_ZLIB_HEADER;
+
+ if (!level)
+ comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
+ else if (strategy == MZ_FILTERED)
+ comp_flags |= TDEFL_FILTER_MATCHES;
+ else if (strategy == MZ_HUFFMAN_ONLY)
+ comp_flags &= ~TDEFL_MAX_PROBES_MASK;
+ else if (strategy == MZ_FIXED)
+ comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS;
+ else if (strategy == MZ_RLE)
+ comp_flags |= TDEFL_RLE_MATCHES;
+
+ return comp_flags;
+}
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4204) /* nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal) */
+#endif
+
+/* Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at
+ http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/.
+ This is actually a modification of Alex's original code so PNG files generated by this function pass pngcheck. */
+void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip)
+{
+ /* Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was defined. */
+ static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
+ tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
+ tdefl_output_buffer out_buf;
+ int i, bpl = w * num_chans, y, z;
+ mz_uint32 c;
+ *pLen_out = 0;
+ if (!pComp)
+ return NULL;
+ MZ_CLEAR_OBJ(out_buf);
+ out_buf.m_expandable = MZ_TRUE;
+ out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl) * h);
+ if (NULL == (out_buf.m_pBuf = (mz_uint8 *)MZ_MALLOC(out_buf.m_capacity)))
+ {
+ MZ_FREE(pComp);
+ return NULL;
+ }
+ /* write dummy header */
+ for (z = 41; z; --z)
+ tdefl_output_buffer_putter(&z, 1, &out_buf);
+ /* compress image data */
+ tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER);
+ for (y = 0; y < h; ++y)
+ {
+ tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH);
+ tdefl_compress_buffer(pComp, (mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH);
+ }
+ if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE)
+ {
+ MZ_FREE(pComp);
+ MZ_FREE(out_buf.m_pBuf);
+ return NULL;
+ }
+ /* write real header */
+ *pLen_out = out_buf.m_size - 41;
+ {
+ static const mz_uint8 chans[] = { 0x00, 0x00, 0x04, 0x02, 0x06 };
+ mz_uint8 pnghdr[41] = { 0x89, 0x50, 0x4e, 0x47, 0x0d,
+ 0x0a, 0x1a, 0x0a, 0x00, 0x00,
+ 0x00, 0x0d, 0x49, 0x48, 0x44,
+ 0x52, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x49, 0x44, 0x41,
+ 0x54 };
+ pnghdr[18] = (mz_uint8)(w >> 8);
+ pnghdr[19] = (mz_uint8)w;
+ pnghdr[22] = (mz_uint8)(h >> 8);
+ pnghdr[23] = (mz_uint8)h;
+ pnghdr[25] = chans[num_chans];
+ pnghdr[33] = (mz_uint8)(*pLen_out >> 24);
+ pnghdr[34] = (mz_uint8)(*pLen_out >> 16);
+ pnghdr[35] = (mz_uint8)(*pLen_out >> 8);
+ pnghdr[36] = (mz_uint8)*pLen_out;
+ c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17);
+ for (i = 0; i < 4; ++i, c <<= 8)
+ ((mz_uint8 *)(pnghdr + 29))[i] = (mz_uint8)(c >> 24);
+ memcpy(out_buf.m_pBuf, pnghdr, 41);
+ }
+ /* write footer (IDAT CRC-32, followed by IEND chunk) */
+ if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf))
+ {
+ *pLen_out = 0;
+ MZ_FREE(pComp);
+ MZ_FREE(out_buf.m_pBuf);
+ return NULL;
+ }
+ c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4, *pLen_out + 4);
+ for (i = 0; i < 4; ++i, c <<= 8)
+ (out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24);
+ /* compute final size of file, grab compressed data buffer and return */
+ *pLen_out += 57;
+ MZ_FREE(pComp);
+ return out_buf.m_pBuf;
+}
+void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out)
+{
+ /* Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out) */
+ return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE);
+}
+
+#ifndef MINIZ_NO_MALLOC
+/* Allocate the tdefl_compressor and tinfl_decompressor structures in C so that */
+/* non-C language bindings to tdefL_ and tinfl_ API don't need to worry about */
+/* structure size and allocation mechanism. */
+tdefl_compressor *tdefl_compressor_alloc()
+{
+ return (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
+}
+
+void tdefl_compressor_free(tdefl_compressor *pComp)
+{
+ MZ_FREE(pComp);
+}
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+ /**************************************************************************
+ *
+ * Copyright 2013-2014 RAD Game Tools and Valve Software
+ * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
+ * All Rights Reserved.
+ *
+ * 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
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ **************************************************************************/
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ------------------- Low-level Decompression (completely independent from all compression API's) */
+
+#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
+#define TINFL_MEMSET(p, c, l) memset(p, c, l)
+
+#define TINFL_CR_BEGIN \
+ switch (r->m_state) \
+ { \
+ case 0:
+#define TINFL_CR_RETURN(state_index, result) \
+ do \
+ { \
+ status = result; \
+ r->m_state = state_index; \
+ goto common_exit; \
+ case state_index:; \
+ } \
+ MZ_MACRO_END
+#define TINFL_CR_RETURN_FOREVER(state_index, result) \
+ do \
+ { \
+ for (;;) \
+ { \
+ TINFL_CR_RETURN(state_index, result); \
+ } \
+ } \
+ MZ_MACRO_END
+#define TINFL_CR_FINISH }
+
+#define TINFL_GET_BYTE(state_index, c) \
+ do \
+ { \
+ while (pIn_buf_cur >= pIn_buf_end) \
+ { \
+ TINFL_CR_RETURN(state_index, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \
+ } \
+ c = *pIn_buf_cur++; \
+ } \
+ MZ_MACRO_END
+
+#define TINFL_NEED_BITS(state_index, n) \
+ do \
+ { \
+ mz_uint c; \
+ TINFL_GET_BYTE(state_index, c); \
+ bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
+ num_bits += 8; \
+ } while (num_bits < (mz_uint)(n))
+#define TINFL_SKIP_BITS(state_index, n) \
+ do \
+ { \
+ if (num_bits < (mz_uint)(n)) \
+ { \
+ TINFL_NEED_BITS(state_index, n); \
+ } \
+ bit_buf >>= (n); \
+ num_bits -= (n); \
+ } \
+ MZ_MACRO_END
+#define TINFL_GET_BITS(state_index, b, n) \
+ do \
+ { \
+ if (num_bits < (mz_uint)(n)) \
+ { \
+ TINFL_NEED_BITS(state_index, n); \
+ } \
+ b = bit_buf & ((1 << (n)) - 1); \
+ bit_buf >>= (n); \
+ num_bits -= (n); \
+ } \
+ MZ_MACRO_END
+
+/* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. */
+/* It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a */
+/* Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the */
+/* bit buffer contains >=15 bits (deflate's max. Huffman code size). */
+#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
+ do \
+ { \
+ temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
+ if (temp >= 0) \
+ { \
+ code_len = temp >> 9; \
+ if ((code_len) && (num_bits >= code_len)) \
+ break; \
+ } \
+ else if (num_bits > TINFL_FAST_LOOKUP_BITS) \
+ { \
+ code_len = TINFL_FAST_LOOKUP_BITS; \
+ do \
+ { \
+ temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
+ } while ((temp < 0) && (num_bits >= (code_len + 1))); \
+ if (temp >= 0) \
+ break; \
+ } \
+ TINFL_GET_BYTE(state_index, c); \
+ bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
+ num_bits += 8; \
+ } while (num_bits < 15);
+
+/* TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read */
+/* beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully */
+/* decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. */
+/* The slow path is only executed at the very end of the input buffer. */
+/* v1.16: The original macro handled the case at the very end of the passed-in input buffer, but we also need to handle the case where the user passes in 1+zillion bytes */
+/* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */
+#define TINFL_HUFF_DECODE(state_index, sym, pHuff) \
+ do \
+ { \
+ int temp; \
+ mz_uint code_len, c; \
+ if (num_bits < 15) \
+ { \
+ if ((pIn_buf_end - pIn_buf_cur) < 2) \
+ { \
+ TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
+ } \
+ else \
+ { \
+ bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \
+ pIn_buf_cur += 2; \
+ num_bits += 16; \
+ } \
+ } \
+ if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
+ code_len = temp >> 9, temp &= 511; \
+ else \
+ { \
+ code_len = TINFL_FAST_LOOKUP_BITS; \
+ do \
+ { \
+ temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
+ } while (temp < 0); \
+ } \
+ sym = temp; \
+ bit_buf >>= code_len; \
+ num_bits -= code_len; \
+ } \
+ MZ_MACRO_END
+
+tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags)
+{
+ static const int s_length_base[31] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 };
+ static const int s_length_extra[31] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 };
+ static const int s_dist_base[32] = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 };
+ static const int s_dist_extra[32] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 };
+ static const mz_uint8 s_length_dezigzag[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
+ static const int s_min_table_sizes[3] = { 257, 1, 4 };
+
+ tinfl_status status = TINFL_STATUS_FAILED;
+ mz_uint32 num_bits, dist, counter, num_extra;
+ tinfl_bit_buf_t bit_buf;
+ const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
+ mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
+ size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start;
+
+ /* Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). */
+ if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start))
+ {
+ *pIn_buf_size = *pOut_buf_size = 0;
+ return TINFL_STATUS_BAD_PARAM;
+ }
+
+ num_bits = r->m_num_bits;
+ bit_buf = r->m_bit_buf;
+ dist = r->m_dist;
+ counter = r->m_counter;
+ num_extra = r->m_num_extra;
+ dist_from_out_buf_start = r->m_dist_from_out_buf_start;
+ TINFL_CR_BEGIN
+
+ bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0;
+ r->m_z_adler32 = r->m_check_adler32 = 1;
+ if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
+ {
+ TINFL_GET_BYTE(1, r->m_zhdr0);
+ TINFL_GET_BYTE(2, r->m_zhdr1);
+ counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
+ if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
+ counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
+ if (counter)
+ {
+ TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED);
+ }
+ }
+
+ do
+ {
+ TINFL_GET_BITS(3, r->m_final, 3);
+ r->m_type = r->m_final >> 1;
+ if (r->m_type == 0)
+ {
+ TINFL_SKIP_BITS(5, num_bits & 7);
+ for (counter = 0; counter < 4; ++counter)
+ {
+ if (num_bits)
+ TINFL_GET_BITS(6, r->m_raw_header[counter], 8);
+ else
+ TINFL_GET_BYTE(7, r->m_raw_header[counter]);
+ }
+ if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8))))
+ {
+ TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED);
+ }
+ while ((counter) && (num_bits))
+ {
+ TINFL_GET_BITS(51, dist, 8);
+ while (pOut_buf_cur >= pOut_buf_end)
+ {
+ TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT);
+ }
+ *pOut_buf_cur++ = (mz_uint8)dist;
+ counter--;
+ }
+ while (counter)
+ {
+ size_t n;
+ while (pOut_buf_cur >= pOut_buf_end)
+ {
+ TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT);
+ }
+ while (pIn_buf_cur >= pIn_buf_end)
+ {
+ TINFL_CR_RETURN(38, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS);
+ }
+ n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
+ TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n);
+ pIn_buf_cur += n;
+ pOut_buf_cur += n;
+ counter -= (mz_uint)n;
+ }
+ }
+ else if (r->m_type == 3)
+ {
+ TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
+ }
+ else
+ {
+ if (r->m_type == 1)
+ {
+ mz_uint8 *p = r->m_tables[0].m_code_size;
+ mz_uint i;
+ r->m_table_sizes[0] = 288;
+ r->m_table_sizes[1] = 32;
+ TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
+ for (i = 0; i <= 143; ++i)
+ *p++ = 8;
+ for (; i <= 255; ++i)
+ *p++ = 9;
+ for (; i <= 279; ++i)
+ *p++ = 7;
+ for (; i <= 287; ++i)
+ *p++ = 8;
+ }
+ else
+ {
+ for (counter = 0; counter < 3; counter++)
+ {
+ TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]);
+ r->m_table_sizes[counter] += s_min_table_sizes[counter];
+ }
+ MZ_CLEAR_OBJ(r->m_tables[2].m_code_size);
+ for (counter = 0; counter < r->m_table_sizes[2]; counter++)
+ {
+ mz_uint s;
+ TINFL_GET_BITS(14, s, 3);
+ r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s;
+ }
+ r->m_table_sizes[2] = 19;
+ }
+ for (; (int)r->m_type >= 0; r->m_type--)
+ {
+ int tree_next, tree_cur;
+ tinfl_huff_table *pTable;
+ mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16];
+ pTable = &r->m_tables[r->m_type];
+ MZ_CLEAR_OBJ(total_syms);
+ MZ_CLEAR_OBJ(pTable->m_look_up);
+ MZ_CLEAR_OBJ(pTable->m_tree);
+ for (i = 0; i < r->m_table_sizes[r->m_type]; ++i)
+ total_syms[pTable->m_code_size[i]]++;
+ used_syms = 0, total = 0;
+ next_code[0] = next_code[1] = 0;
+ for (i = 1; i <= 15; ++i)
+ {
+ used_syms += total_syms[i];
+ next_code[i + 1] = (total = ((total + total_syms[i]) << 1));
+ }
+ if ((65536 != total) && (used_syms > 1))
+ {
+ TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
+ }
+ for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
+ {
+ mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index];
+ if (!code_size)
+ continue;
+ cur_code = next_code[code_size]++;
+ for (l = code_size; l > 0; l--, cur_code >>= 1)
+ rev_code = (rev_code << 1) | (cur_code & 1);
+ if (code_size <= TINFL_FAST_LOOKUP_BITS)
+ {
+ mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
+ while (rev_code < TINFL_FAST_LOOKUP_SIZE)
+ {
+ pTable->m_look_up[rev_code] = k;
+ rev_code += (1 << code_size);
+ }
+ continue;
+ }
+ if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)]))
+ {
+ pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next;
+ tree_cur = tree_next;
+ tree_next -= 2;
+ }
+ rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
+ for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
+ {
+ tree_cur -= ((rev_code >>= 1) & 1);
+ if (!pTable->m_tree[-tree_cur - 1])
+ {
+ pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next;
+ tree_cur = tree_next;
+ tree_next -= 2;
+ }
+ else
+ tree_cur = pTable->m_tree[-tree_cur - 1];
+ }
+ tree_cur -= ((rev_code >>= 1) & 1);
+ pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
+ }
+ if (r->m_type == 2)
+ {
+ for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);)
+ {
+ mz_uint s;
+ TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]);
+ if (dist < 16)
+ {
+ r->m_len_codes[counter++] = (mz_uint8)dist;
+ continue;
+ }
+ if ((dist == 16) && (!counter))
+ {
+ TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
+ }
+ num_extra = "\02\03\07"[dist - 16];
+ TINFL_GET_BITS(18, s, num_extra);
+ s += "\03\03\013"[dist - 16];
+ TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s);
+ counter += s;
+ }
+ if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
+ {
+ TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
+ }
+ TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]);
+ TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
+ }
+ }
+ for (;;)
+ {
+ mz_uint8 *pSrc;
+ for (;;)
+ {
+ if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
+ {
+ TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
+ if (counter >= 256)
+ break;
+ while (pOut_buf_cur >= pOut_buf_end)
+ {
+ TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT);
+ }
+ *pOut_buf_cur++ = (mz_uint8)counter;
+ }
+ else
+ {
+ int sym2;
+ mz_uint code_len;
+#if TINFL_USE_64BIT_BITBUF
+ if (num_bits < 30)
+ {
+ bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits);
+ pIn_buf_cur += 4;
+ num_bits += 32;
+ }
+#else
+ if (num_bits < 15)
+ {
+ bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
+ pIn_buf_cur += 2;
+ num_bits += 16;
+ }
+#endif
+ if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
+ code_len = sym2 >> 9;
+ else
+ {
+ code_len = TINFL_FAST_LOOKUP_BITS;
+ do
+ {
+ sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
+ } while (sym2 < 0);
+ }
+ counter = sym2;
+ bit_buf >>= code_len;
+ num_bits -= code_len;
+ if (counter & 256)
+ break;
+
+#if !TINFL_USE_64BIT_BITBUF
+ if (num_bits < 15)
+ {
+ bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
+ pIn_buf_cur += 2;
+ num_bits += 16;
+ }
+#endif
+ if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
+ code_len = sym2 >> 9;
+ else
+ {
+ code_len = TINFL_FAST_LOOKUP_BITS;
+ do
+ {
+ sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
+ } while (sym2 < 0);
+ }
+ bit_buf >>= code_len;
+ num_bits -= code_len;
+
+ pOut_buf_cur[0] = (mz_uint8)counter;
+ if (sym2 & 256)
+ {
+ pOut_buf_cur++;
+ counter = sym2;
+ break;
+ }
+ pOut_buf_cur[1] = (mz_uint8)sym2;
+ pOut_buf_cur += 2;
+ }
+ }
+ if ((counter &= 511) == 256)
+ break;
+
+ num_extra = s_length_extra[counter - 257];
+ counter = s_length_base[counter - 257];
+ if (num_extra)
+ {
+ mz_uint extra_bits;
+ TINFL_GET_BITS(25, extra_bits, num_extra);
+ counter += extra_bits;
+ }
+
+ TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
+ num_extra = s_dist_extra[dist];
+ dist = s_dist_base[dist];
+ if (num_extra)
+ {
+ mz_uint extra_bits;
+ TINFL_GET_BITS(27, extra_bits, num_extra);
+ dist += extra_bits;
+ }
+
+ dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
+ if ((dist == 0 || dist > dist_from_out_buf_start || dist_from_out_buf_start == 0) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
+ {
+ TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
+ }
+
+ pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
+
+ if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
+ {
+ while (counter--)
+ {
+ while (pOut_buf_cur >= pOut_buf_end)
+ {
+ TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT);
+ }
+ *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
+ }
+ continue;
+ }
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
+ else if ((counter >= 9) && (counter <= dist))
+ {
+ const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
+ do
+ {
+#ifdef MINIZ_UNALIGNED_USE_MEMCPY
+ memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32)*2);
+#else
+ ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
+ ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
+#endif
+ pOut_buf_cur += 8;
+ } while ((pSrc += 8) < pSrc_end);
+ if ((counter &= 7) < 3)
+ {
+ if (counter)
+ {
+ pOut_buf_cur[0] = pSrc[0];
+ if (counter > 1)
+ pOut_buf_cur[1] = pSrc[1];
+ pOut_buf_cur += counter;
+ }
+ continue;
+ }
+ }
+#endif
+ while(counter>2)
+ {
+ pOut_buf_cur[0] = pSrc[0];
+ pOut_buf_cur[1] = pSrc[1];
+ pOut_buf_cur[2] = pSrc[2];
+ pOut_buf_cur += 3;
+ pSrc += 3;
+ counter -= 3;
+ }
+ if (counter > 0)
+ {
+ pOut_buf_cur[0] = pSrc[0];
+ if (counter > 1)
+ pOut_buf_cur[1] = pSrc[1];
+ pOut_buf_cur += counter;
+ }
+ }
+ }
+ } while (!(r->m_final & 1));
+
+ /* Ensure byte alignment and put back any bytes from the bitbuf if we've looked ahead too far on gzip, or other Deflate streams followed by arbitrary data. */
+ /* I'm being super conservative here. A number of simplifications can be made to the byte alignment part, and the Adler32 check shouldn't ever need to worry about reading from the bitbuf now. */
+ TINFL_SKIP_BITS(32, num_bits & 7);
+ while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
+ {
+ --pIn_buf_cur;
+ num_bits -= 8;
+ }
+ bit_buf &= (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1);
+ MZ_ASSERT(!num_bits); /* if this assert fires then we've read beyond the end of non-deflate/zlib streams with following data (such as gzip streams). */
+
+ if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
+ {
+ for (counter = 0; counter < 4; ++counter)
+ {
+ mz_uint s;
+ if (num_bits)
+ TINFL_GET_BITS(41, s, 8);
+ else
+ TINFL_GET_BYTE(42, s);
+ r->m_z_adler32 = (r->m_z_adler32 << 8) | s;
+ }
+ }
+ TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
+
+ TINFL_CR_FINISH
+
+common_exit:
+ /* As long as we aren't telling the caller that we NEED more input to make forward progress: */
+ /* Put back any bytes from the bitbuf in case we've looked ahead too far on gzip, or other Deflate streams followed by arbitrary data. */
+ /* We need to be very careful here to NOT push back any bytes we definitely know we need to make forward progress, though, or we'll lock the caller up into an inf loop. */
+ if ((status != TINFL_STATUS_NEEDS_MORE_INPUT) && (status != TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS))
+ {
+ while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
+ {
+ --pIn_buf_cur;
+ num_bits -= 8;
+ }
+ }
+ r->m_num_bits = num_bits;
+ r->m_bit_buf = bit_buf & (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1);
+ r->m_dist = dist;
+ r->m_counter = counter;
+ r->m_num_extra = num_extra;
+ r->m_dist_from_out_buf_start = dist_from_out_buf_start;
+ *pIn_buf_size = pIn_buf_cur - pIn_buf_next;
+ *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
+ if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
+ {
+ const mz_uint8 *ptr = pOut_buf_next;
+ size_t buf_len = *pOut_buf_size;
+ mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16;
+ size_t block_len = buf_len % 5552;
+ while (buf_len)
+ {
+ for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
+ {
+ s1 += ptr[0], s2 += s1;
+ s1 += ptr[1], s2 += s1;
+ s1 += ptr[2], s2 += s1;
+ s1 += ptr[3], s2 += s1;
+ s1 += ptr[4], s2 += s1;
+ s1 += ptr[5], s2 += s1;
+ s1 += ptr[6], s2 += s1;
+ s1 += ptr[7], s2 += s1;
+ }
+ for (; i < block_len; ++i)
+ s1 += *ptr++, s2 += s1;
+ s1 %= 65521U, s2 %= 65521U;
+ buf_len -= block_len;
+ block_len = 5552;
+ }
+ r->m_check_adler32 = (s2 << 16) + s1;
+ if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32))
+ status = TINFL_STATUS_ADLER32_MISMATCH;
+ }
+ return status;
+}
+
+/* Higher level helper functions. */
+void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
+{
+ tinfl_decompressor decomp;
+ void *pBuf = NULL, *pNew_buf;
+ size_t src_buf_ofs = 0, out_buf_capacity = 0;
+ *pOut_len = 0;
+ tinfl_init(&decomp);
+ for (;;)
+ {
+ size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
+ tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8 *)pBuf, pBuf ? (mz_uint8 *)pBuf + *pOut_len : NULL, &dst_buf_size,
+ (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
+ if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
+ {
+ MZ_FREE(pBuf);
+ *pOut_len = 0;
+ return NULL;
+ }
+ src_buf_ofs += src_buf_size;
+ *pOut_len += dst_buf_size;
+ if (status == TINFL_STATUS_DONE)
+ break;
+ new_out_buf_capacity = out_buf_capacity * 2;
+ if (new_out_buf_capacity < 128)
+ new_out_buf_capacity = 128;
+ pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
+ if (!pNew_buf)
+ {
+ MZ_FREE(pBuf);
+ *pOut_len = 0;
+ return NULL;
+ }
+ pBuf = pNew_buf;
+ out_buf_capacity = new_out_buf_capacity;
+ }
+ return pBuf;
+}
+
+size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
+{
+ tinfl_decompressor decomp;
+ tinfl_status status;
+ tinfl_init(&decomp);
+ status = tinfl_decompress(&decomp, (const mz_uint8 *)pSrc_buf, &src_buf_len, (mz_uint8 *)pOut_buf, (mz_uint8 *)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
+ return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
+}
+
+int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
+{
+ int result = 0;
+ tinfl_decompressor decomp;
+ mz_uint8 *pDict = (mz_uint8 *)MZ_MALLOC(TINFL_LZ_DICT_SIZE);
+ size_t in_buf_ofs = 0, dict_ofs = 0;
+ if (!pDict)
+ return TINFL_STATUS_FAILED;
+ tinfl_init(&decomp);
+ for (;;)
+ {
+ size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
+ tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
+ (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
+ in_buf_ofs += in_buf_size;
+ if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
+ break;
+ if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
+ {
+ result = (status == TINFL_STATUS_DONE);
+ break;
+ }
+ dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
+ }
+ MZ_FREE(pDict);
+ *pIn_buf_size = in_buf_ofs;
+ return result;
+}
+
+#ifndef MINIZ_NO_MALLOC
+tinfl_decompressor *tinfl_decompressor_alloc()
+{
+ tinfl_decompressor *pDecomp = (tinfl_decompressor *)MZ_MALLOC(sizeof(tinfl_decompressor));
+ if (pDecomp)
+ tinfl_init(pDecomp);
+ return pDecomp;
+}
+
+void tinfl_decompressor_free(tinfl_decompressor *pDecomp)
+{
+ MZ_FREE(pDecomp);
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+ /**************************************************************************
+ *
+ * Copyright 2013-2014 RAD Game Tools and Valve Software
+ * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
+ * Copyright 2016 Martin Raiber
+ * All Rights Reserved.
+ *
+ * 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
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ **************************************************************************/
+
+
+#ifndef MINIZ_NO_ARCHIVE_APIS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ------------------- .ZIP archive reading */
+
+#ifdef MINIZ_NO_STDIO
+#define MZ_FILE void *
+#else
+#include <sys/stat.h>
+
+#if defined(_MSC_VER) || defined(__MINGW64__)
+static FILE *mz_fopen(const char *pFilename, const char *pMode)
+{
+ FILE *pFile = NULL;
+ fopen_s(&pFile, pFilename, pMode);
+ return pFile;
+}
+static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
+{
+ FILE *pFile = NULL;
+ if (freopen_s(&pFile, pPath, pMode, pStream))
+ return NULL;
+ return pFile;
+}
+#ifndef MINIZ_NO_TIME
+#include <sys/utime.h>
+#endif
+#define MZ_FOPEN mz_fopen
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 _ftelli64
+#define MZ_FSEEK64 _fseeki64
+#define MZ_FILE_STAT_STRUCT _stat64
+#define MZ_FILE_STAT _stat64
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN mz_freopen
+#define MZ_DELETE_FILE remove
+#elif defined(__MINGW32__)
+#ifndef MINIZ_NO_TIME
+#include <sys/utime.h>
+#endif
+#define MZ_FOPEN(f, m) fopen(f, m)
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 ftello64
+#define MZ_FSEEK64 fseeko64
+#define MZ_FILE_STAT_STRUCT _stat
+#define MZ_FILE_STAT _stat
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
+#define MZ_DELETE_FILE remove
+#elif defined(__TINYC__)
+#ifndef MINIZ_NO_TIME
+#include <sys/utime.h>
+#endif
+#define MZ_FOPEN(f, m) fopen(f, m)
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 ftell
+#define MZ_FSEEK64 fseek
+#define MZ_FILE_STAT_STRUCT stat
+#define MZ_FILE_STAT stat
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
+#define MZ_DELETE_FILE remove
+#elif defined(__USE_LARGEFILE64) /* gcc, clang */
+#ifndef MINIZ_NO_TIME
+#include <utime.h>
+#endif
+#define MZ_FOPEN(f, m) fopen64(f, m)
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 ftello64
+#define MZ_FSEEK64 fseeko64
+#define MZ_FILE_STAT_STRUCT stat64
+#define MZ_FILE_STAT stat64
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
+#define MZ_DELETE_FILE remove
+#elif defined(__APPLE__)
+#ifndef MINIZ_NO_TIME
+#include <utime.h>
+#endif
+#define MZ_FOPEN(f, m) fopen(f, m)
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 ftello
+#define MZ_FSEEK64 fseeko
+#define MZ_FILE_STAT_STRUCT stat
+#define MZ_FILE_STAT stat
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN(p, m, s) freopen(p, m, s)
+#define MZ_DELETE_FILE remove
+
+#else
+#pragma message("Using fopen, ftello, fseeko, stat() etc. path for file I/O - this path may not support large files.")
+#ifndef MINIZ_NO_TIME
+#include <utime.h>
+#endif
+#define MZ_FOPEN(f, m) fopen(f, m)
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#ifdef __STRICT_ANSI__
+#define MZ_FTELL64 ftell
+#define MZ_FSEEK64 fseek
+#else
+#define MZ_FTELL64 ftello
+#define MZ_FSEEK64 fseeko
+#endif
+#define MZ_FILE_STAT_STRUCT stat
+#define MZ_FILE_STAT stat
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
+#define MZ_DELETE_FILE remove
+#endif /* #ifdef _MSC_VER */
+#endif /* #ifdef MINIZ_NO_STDIO */
+
+#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
+
+/* Various ZIP archive enums. To completely avoid cross platform compiler alignment and platform endian issues, miniz.c doesn't use structs for any of this stuff. */
+enum
+{
+ /* ZIP archive identifiers and record sizes */
+ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50,
+ MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50,
+ MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50,
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30,
+ MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46,
+ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22,
+
+ /* ZIP64 archive identifier and record sizes */
+ MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06064b50,
+ MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG = 0x07064b50,
+ MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE = 56,
+ MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE = 20,
+ MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID = 0x0001,
+ MZ_ZIP_DATA_DESCRIPTOR_ID = 0x08074b50,
+ MZ_ZIP_DATA_DESCRIPTER_SIZE64 = 24,
+ MZ_ZIP_DATA_DESCRIPTER_SIZE32 = 16,
+
+ /* Central directory header record offsets */
+ MZ_ZIP_CDH_SIG_OFS = 0,
+ MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4,
+ MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6,
+ MZ_ZIP_CDH_BIT_FLAG_OFS = 8,
+ MZ_ZIP_CDH_METHOD_OFS = 10,
+ MZ_ZIP_CDH_FILE_TIME_OFS = 12,
+ MZ_ZIP_CDH_FILE_DATE_OFS = 14,
+ MZ_ZIP_CDH_CRC32_OFS = 16,
+ MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20,
+ MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24,
+ MZ_ZIP_CDH_FILENAME_LEN_OFS = 28,
+ MZ_ZIP_CDH_EXTRA_LEN_OFS = 30,
+ MZ_ZIP_CDH_COMMENT_LEN_OFS = 32,
+ MZ_ZIP_CDH_DISK_START_OFS = 34,
+ MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36,
+ MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38,
+ MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42,
+
+ /* Local directory header offsets */
+ MZ_ZIP_LDH_SIG_OFS = 0,
+ MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4,
+ MZ_ZIP_LDH_BIT_FLAG_OFS = 6,
+ MZ_ZIP_LDH_METHOD_OFS = 8,
+ MZ_ZIP_LDH_FILE_TIME_OFS = 10,
+ MZ_ZIP_LDH_FILE_DATE_OFS = 12,
+ MZ_ZIP_LDH_CRC32_OFS = 14,
+ MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18,
+ MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22,
+ MZ_ZIP_LDH_FILENAME_LEN_OFS = 26,
+ MZ_ZIP_LDH_EXTRA_LEN_OFS = 28,
+ MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR = 1 << 3,
+
+ /* End of central directory offsets */
+ MZ_ZIP_ECDH_SIG_OFS = 0,
+ MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4,
+ MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6,
+ MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8,
+ MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10,
+ MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12,
+ MZ_ZIP_ECDH_CDIR_OFS_OFS = 16,
+ MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20,
+
+ /* ZIP64 End of central directory locator offsets */
+ MZ_ZIP64_ECDL_SIG_OFS = 0, /* 4 bytes */
+ MZ_ZIP64_ECDL_NUM_DISK_CDIR_OFS = 4, /* 4 bytes */
+ MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS = 8, /* 8 bytes */
+ MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS = 16, /* 4 bytes */
+
+ /* ZIP64 End of central directory header offsets */
+ MZ_ZIP64_ECDH_SIG_OFS = 0, /* 4 bytes */
+ MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS = 4, /* 8 bytes */
+ MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS = 12, /* 2 bytes */
+ MZ_ZIP64_ECDH_VERSION_NEEDED_OFS = 14, /* 2 bytes */
+ MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS = 16, /* 4 bytes */
+ MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS = 20, /* 4 bytes */
+ MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 24, /* 8 bytes */
+ MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS = 32, /* 8 bytes */
+ MZ_ZIP64_ECDH_CDIR_SIZE_OFS = 40, /* 8 bytes */
+ MZ_ZIP64_ECDH_CDIR_OFS_OFS = 48, /* 8 bytes */
+ MZ_ZIP_VERSION_MADE_BY_DOS_FILESYSTEM_ID = 0,
+ MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG = 0x10,
+ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED = 1,
+ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG = 32,
+ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION = 64,
+ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED = 8192,
+ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 = 1 << 11
+};
+
+typedef struct
+{
+ void *m_p;
+ size_t m_size, m_capacity;
+ mz_uint m_element_size;
+} mz_zip_array;
+
+struct mz_zip_internal_state_tag
+{
+ mz_zip_array m_central_dir;
+ mz_zip_array m_central_dir_offsets;
+ mz_zip_array m_sorted_central_dir_offsets;
+
+ /* The flags passed in when the archive is initially opened. */
+ uint32_t m_init_flags;
+
+ /* MZ_TRUE if the archive has a zip64 end of central directory headers, etc. */
+ mz_bool m_zip64;
+
+ /* MZ_TRUE if we found zip64 extended info in the central directory (m_zip64 will also be slammed to true too, even if we didn't find a zip64 end of central dir header, etc.) */
+ mz_bool m_zip64_has_extended_info_fields;
+
+ /* These fields are used by the file, FILE, memory, and memory/heap read/write helpers. */
+ MZ_FILE *m_pFile;
+ mz_uint64 m_file_archive_start_ofs;
+
+ void *m_pMem;
+ size_t m_mem_size;
+ size_t m_mem_capacity;
+};
+
+#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size
+
+#if defined(DEBUG) || defined(_DEBUG)
+static MZ_FORCEINLINE mz_uint mz_zip_array_range_check(const mz_zip_array *pArray, mz_uint index)
+{
+ MZ_ASSERT(index < pArray->m_size);
+ return index;
+}
+#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[mz_zip_array_range_check(array_ptr, index)]
+#else
+#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index]
+#endif
+
+static MZ_FORCEINLINE void mz_zip_array_init(mz_zip_array *pArray, mz_uint32 element_size)
+{
+ memset(pArray, 0, sizeof(mz_zip_array));
+ pArray->m_element_size = element_size;
+}
+
+static MZ_FORCEINLINE void mz_zip_array_clear(mz_zip_archive *pZip, mz_zip_array *pArray)
+{
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p);
+ memset(pArray, 0, sizeof(mz_zip_array));
+}
+
+static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing)
+{
+ void *pNew_p;
+ size_t new_capacity = min_new_capacity;
+ MZ_ASSERT(pArray->m_element_size);
+ if (pArray->m_capacity >= min_new_capacity)
+ return MZ_TRUE;
+ if (growing)
+ {
+ new_capacity = MZ_MAX(1, pArray->m_capacity);
+ while (new_capacity < min_new_capacity)
+ new_capacity *= 2;
+ }
+ if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity)))
+ return MZ_FALSE;
+ pArray->m_p = pNew_p;
+ pArray->m_capacity = new_capacity;
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_capacity, mz_uint growing)
+{
+ if (new_capacity > pArray->m_capacity)
+ {
+ if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing))
+ return MZ_FALSE;
+ }
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing)
+{
+ if (new_size > pArray->m_capacity)
+ {
+ if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing))
+ return MZ_FALSE;
+ }
+ pArray->m_size = new_size;
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip, mz_zip_array *pArray, size_t n)
+{
+ return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE);
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, mz_zip_array *pArray, const void *pElements, size_t n)
+{
+ size_t orig_size = pArray->m_size;
+ if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE))
+ return MZ_FALSE;
+ if (n > 0)
+ memcpy((mz_uint8 *)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size);
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_TIME
+static MZ_TIME_T mz_zip_dos_to_time_t(int dos_time, int dos_date)
+{
+ struct tm tm;
+ memset(&tm, 0, sizeof(tm));
+ tm.tm_isdst = -1;
+ tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900;
+ tm.tm_mon = ((dos_date >> 5) & 15) - 1;
+ tm.tm_mday = dos_date & 31;
+ tm.tm_hour = (dos_time >> 11) & 31;
+ tm.tm_min = (dos_time >> 5) & 63;
+ tm.tm_sec = (dos_time << 1) & 62;
+ return mktime(&tm);
+}
+
+#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
+static void mz_zip_time_t_to_dos_time(MZ_TIME_T time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
+{
+#ifdef _MSC_VER
+ struct tm tm_struct;
+ struct tm *tm = &tm_struct;
+ errno_t err = localtime_s(tm, &time);
+ if (err)
+ {
+ *pDOS_date = 0;
+ *pDOS_time = 0;
+ return;
+ }
+#else
+ struct tm *tm = localtime(&time);
+#endif /* #ifdef _MSC_VER */
+
+ *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1));
+ *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday);
+}
+#endif /* MINIZ_NO_ARCHIVE_WRITING_APIS */
+
+#ifndef MINIZ_NO_STDIO
+#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
+static mz_bool mz_zip_get_file_modified_time(const char *pFilename, MZ_TIME_T *pTime)
+{
+ struct MZ_FILE_STAT_STRUCT file_stat;
+
+ /* On Linux with x86 glibc, this call will fail on large files (I think >= 0x80000000 bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh. */
+ if (MZ_FILE_STAT(pFilename, &file_stat) != 0)
+ return MZ_FALSE;
+
+ *pTime = file_stat.st_mtime;
+
+ return MZ_TRUE;
+}
+#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS*/
+
+static mz_bool mz_zip_set_file_times(const char *pFilename, MZ_TIME_T access_time, MZ_TIME_T modified_time)
+{
+ struct utimbuf t;
+
+ memset(&t, 0, sizeof(t));
+ t.actime = access_time;
+ t.modtime = modified_time;
+
+ return !utime(pFilename, &t);
+}
+#endif /* #ifndef MINIZ_NO_STDIO */
+#endif /* #ifndef MINIZ_NO_TIME */
+
+static MZ_FORCEINLINE mz_bool mz_zip_set_error(mz_zip_archive *pZip, mz_zip_error err_num)
+{
+ if (pZip)
+ pZip->m_last_error = err_num;
+ return MZ_FALSE;
+}
+
+static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint flags)
+{
+ (void)flags;
+ if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ if (!pZip->m_pAlloc)
+ pZip->m_pAlloc = miniz_def_alloc_func;
+ if (!pZip->m_pFree)
+ pZip->m_pFree = miniz_def_free_func;
+ if (!pZip->m_pRealloc)
+ pZip->m_pRealloc = miniz_def_realloc_func;
+
+ pZip->m_archive_size = 0;
+ pZip->m_central_directory_file_ofs = 0;
+ pZip->m_total_files = 0;
+ pZip->m_last_error = MZ_ZIP_NO_ERROR;
+
+ if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+
+ memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32));
+ pZip->m_pState->m_init_flags = flags;
+ pZip->m_pState->m_zip64 = MZ_FALSE;
+ pZip->m_pState->m_zip64_has_extended_info_fields = MZ_FALSE;
+
+ pZip->m_zip_mode = MZ_ZIP_MODE_READING;
+
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_reader_filename_less(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, mz_uint r_index)
+{
+ const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
+ const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index));
+ mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS), r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ mz_uint8 l = 0, r = 0;
+ pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
+ pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
+ pE = pL + MZ_MIN(l_len, r_len);
+ while (pL < pE)
+ {
+ if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
+ break;
+ pL++;
+ pR++;
+ }
+ return (pL == pE) ? (l_len < r_len) : (l < r);
+}
+
+#define MZ_SWAP_UINT32(a, b) \
+ do \
+ { \
+ mz_uint32 t = a; \
+ a = b; \
+ b = t; \
+ } \
+ MZ_MACRO_END
+
+/* Heap sort of lowercased filenames, used to help accelerate plain central directory searches by mz_zip_reader_locate_file(). (Could also use qsort(), but it could allocate memory.) */
+static void mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip)
+{
+ mz_zip_internal_state *pState = pZip->m_pState;
+ const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
+ const mz_zip_array *pCentral_dir = &pState->m_central_dir;
+ mz_uint32 *pIndices;
+ mz_uint32 start, end;
+ const mz_uint32 size = pZip->m_total_files;
+
+ if (size <= 1U)
+ return;
+
+ pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
+
+ start = (size - 2U) >> 1U;
+ for (;;)
+ {
+ mz_uint64 child, root = start;
+ for (;;)
+ {
+ if ((child = (root << 1U) + 1U) >= size)
+ break;
+ child += (((child + 1U) < size) && (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U])));
+ if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
+ break;
+ MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
+ root = child;
+ }
+ if (!start)
+ break;
+ start--;
+ }
+
+ end = size - 1;
+ while (end > 0)
+ {
+ mz_uint64 child, root = 0;
+ MZ_SWAP_UINT32(pIndices[end], pIndices[0]);
+ for (;;)
+ {
+ if ((child = (root << 1U) + 1U) >= end)
+ break;
+ child += (((child + 1U) < end) && mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U]));
+ if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
+ break;
+ MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
+ root = child;
+ }
+ end--;
+ }
+}
+
+static mz_bool mz_zip_reader_locate_header_sig(mz_zip_archive *pZip, mz_uint32 record_sig, mz_uint32 record_size, mz_int64 *pOfs)
+{
+ mz_int64 cur_file_ofs;
+ mz_uint32 buf_u32[4096 / sizeof(mz_uint32)];
+ mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
+
+ /* Basic sanity checks - reject files which are too small */
+ if (pZip->m_archive_size < record_size)
+ return MZ_FALSE;
+
+ /* Find the record by scanning the file from the end towards the beginning. */
+ cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0);
+ for (;;)
+ {
+ int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
+
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
+ return MZ_FALSE;
+
+ for (i = n - 4; i >= 0; --i)
+ {
+ mz_uint s = MZ_READ_LE32(pBuf + i);
+ if (s == record_sig)
+ {
+ if ((pZip->m_archive_size - (cur_file_ofs + i)) >= record_size)
+ break;
+ }
+ }
+
+ if (i >= 0)
+ {
+ cur_file_ofs += i;
+ break;
+ }
+
+ /* Give up if we've searched the entire file, or we've gone back "too far" (~64kb) */
+ if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (MZ_UINT16_MAX + record_size)))
+ return MZ_FALSE;
+
+ cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
+ }
+
+ *pOfs = cur_file_ofs;
+ return MZ_TRUE;
+}
+
+static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flags)
+{
+ mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0, cdir_disk_index = 0;
+ mz_uint64 cdir_ofs = 0;
+ mz_int64 cur_file_ofs = 0;
+ const mz_uint8 *p;
+
+ mz_uint32 buf_u32[4096 / sizeof(mz_uint32)];
+ mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
+ mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0);
+ mz_uint32 zip64_end_of_central_dir_locator_u32[(MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
+ mz_uint8 *pZip64_locator = (mz_uint8 *)zip64_end_of_central_dir_locator_u32;
+
+ mz_uint32 zip64_end_of_central_dir_header_u32[(MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
+ mz_uint8 *pZip64_end_of_central_dir = (mz_uint8 *)zip64_end_of_central_dir_header_u32;
+
+ mz_uint64 zip64_end_of_central_dir_ofs = 0;
+
+ /* Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there. */
+ if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
+ return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
+
+ if (!mz_zip_reader_locate_header_sig(pZip, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE, &cur_file_ofs))
+ return mz_zip_set_error(pZip, MZ_ZIP_FAILED_FINDING_CENTRAL_DIR);
+
+ /* Read and verify the end of central directory record. */
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+
+ if (MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG)
+ return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
+
+ if (cur_file_ofs >= (MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE))
+ {
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE, pZip64_locator, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE)
+ {
+ if (MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG)
+ {
+ zip64_end_of_central_dir_ofs = MZ_READ_LE64(pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS);
+ if (zip64_end_of_central_dir_ofs > (pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE))
+ return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
+
+ if (pZip->m_pRead(pZip->m_pIO_opaque, zip64_end_of_central_dir_ofs, pZip64_end_of_central_dir, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
+ {
+ if (MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG)
+ {
+ pZip->m_pState->m_zip64 = MZ_TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS);
+ cdir_entries_on_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS);
+ num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS);
+ cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS);
+ cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS);
+ cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);
+
+ if (pZip->m_pState->m_zip64)
+ {
+ mz_uint32 zip64_total_num_of_disks = MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS);
+ mz_uint64 zip64_cdir_total_entries = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS);
+ mz_uint64 zip64_cdir_total_entries_on_this_disk = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS);
+ mz_uint64 zip64_size_of_end_of_central_dir_record = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS);
+ mz_uint64 zip64_size_of_central_directory = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_SIZE_OFS);
+
+ if (zip64_size_of_end_of_central_dir_record < (MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - 12))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ if (zip64_total_num_of_disks != 1U)
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
+
+ /* Check for miniz's practical limits */
+ if (zip64_cdir_total_entries > MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
+
+ pZip->m_total_files = (mz_uint32)zip64_cdir_total_entries;
+
+ if (zip64_cdir_total_entries_on_this_disk > MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
+
+ cdir_entries_on_this_disk = (mz_uint32)zip64_cdir_total_entries_on_this_disk;
+
+ /* Check for miniz's current practical limits (sorry, this should be enough for millions of files) */
+ if (zip64_size_of_central_directory > MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
+
+ cdir_size = (mz_uint32)zip64_size_of_central_directory;
+
+ num_this_disk = MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS);
+
+ cdir_disk_index = MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS);
+
+ cdir_ofs = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_OFS_OFS);
+ }
+
+ if (pZip->m_total_files != cdir_entries_on_this_disk)
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
+
+ if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1)))
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
+
+ if (cdir_size < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ pZip->m_central_directory_file_ofs = cdir_ofs;
+
+ if (pZip->m_total_files)
+ {
+ mz_uint i, n;
+ /* Read the entire central directory into a heap block, and allocate another heap block to hold the unsorted central dir file record offsets, and possibly another to hold the sorted indices. */
+ if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) ||
+ (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, pZip->m_total_files, MZ_FALSE)))
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+
+ if (sort_central_dir)
+ {
+ if (!mz_zip_array_resize(pZip, &pZip->m_pState->m_sorted_central_dir_offsets, pZip->m_total_files, MZ_FALSE))
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+
+ /* Now create an index into the central directory file records, do some basic sanity checking on each record */
+ p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p;
+ for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i)
+ {
+ mz_uint total_header_size, disk_index, bit_flags, filename_size, ext_data_size;
+ mz_uint64 comp_size, decomp_size, local_header_ofs;
+
+ if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, i) = (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p);
+
+ if (sort_central_dir)
+ MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, mz_uint32, i) = i;
+
+ comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
+ decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
+ local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
+ filename_size = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ ext_data_size = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS);
+
+ if ((!pZip->m_pState->m_zip64_has_extended_info_fields) &&
+ (ext_data_size) &&
+ (MZ_MAX(MZ_MAX(comp_size, decomp_size), local_header_ofs) == MZ_UINT32_MAX))
+ {
+ /* Attempt to find zip64 extended information field in the entry's extra data */
+ mz_uint32 extra_size_remaining = ext_data_size;
+
+ if (extra_size_remaining)
+ {
+ const mz_uint8 *pExtra_data;
+ void* buf = NULL;
+
+ if (MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + ext_data_size > n)
+ {
+ buf = MZ_MALLOC(ext_data_size);
+ if(buf==NULL)
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size, buf, ext_data_size) != ext_data_size)
+ {
+ MZ_FREE(buf);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+ }
+
+ pExtra_data = (mz_uint8*)buf;
+ }
+ else
+ {
+ pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size;
+ }
+
+ do
+ {
+ mz_uint32 field_id;
+ mz_uint32 field_data_size;
+
+ if (extra_size_remaining < (sizeof(mz_uint16) * 2))
+ {
+ MZ_FREE(buf);
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+ }
+
+ field_id = MZ_READ_LE16(pExtra_data);
+ field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
+
+ if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining)
+ {
+ MZ_FREE(buf);
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+ }
+
+ if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
+ {
+ /* Ok, the archive didn't have any zip64 headers but it uses a zip64 extended information field so mark it as zip64 anyway (this can occur with infozip's zip util when it reads compresses files from stdin). */
+ pZip->m_pState->m_zip64 = MZ_TRUE;
+ pZip->m_pState->m_zip64_has_extended_info_fields = MZ_TRUE;
+ break;
+ }
+
+ pExtra_data += sizeof(mz_uint16) * 2 + field_data_size;
+ extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size;
+ } while (extra_size_remaining);
+
+ MZ_FREE(buf);
+ }
+ }
+
+ /* I've seen archives that aren't marked as zip64 that uses zip64 ext data, argh */
+ if ((comp_size != MZ_UINT32_MAX) && (decomp_size != MZ_UINT32_MAX))
+ {
+ if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+ }
+
+ disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS);
+ if ((disk_index == MZ_UINT16_MAX) || ((disk_index != num_this_disk) && (disk_index != 1)))
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
+
+ if (comp_size != MZ_UINT32_MAX)
+ {
+ if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+ }
+
+ bit_flags = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
+ if (bit_flags & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED)
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
+
+ if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) > n)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ n -= total_header_size;
+ p += total_header_size;
+ }
+ }
+
+ if (sort_central_dir)
+ mz_zip_reader_sort_central_dir_offsets_by_filename(pZip);
+
+ return MZ_TRUE;
+}
+
+void mz_zip_zero_struct(mz_zip_archive *pZip)
+{
+ if (pZip)
+ MZ_CLEAR_OBJ(*pZip);
+}
+
+static mz_bool mz_zip_reader_end_internal(mz_zip_archive *pZip, mz_bool set_last_error)
+{
+ mz_bool status = MZ_TRUE;
+
+ if (!pZip)
+ return MZ_FALSE;
+
+ if ((!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
+ {
+ if (set_last_error)
+ pZip->m_last_error = MZ_ZIP_INVALID_PARAMETER;
+
+ return MZ_FALSE;
+ }
+
+ if (pZip->m_pState)
+ {
+ mz_zip_internal_state *pState = pZip->m_pState;
+ pZip->m_pState = NULL;
+
+ mz_zip_array_clear(pZip, &pState->m_central_dir);
+ mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
+ mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
+
+#ifndef MINIZ_NO_STDIO
+ if (pState->m_pFile)
+ {
+ if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
+ {
+ if (MZ_FCLOSE(pState->m_pFile) == EOF)
+ {
+ if (set_last_error)
+ pZip->m_last_error = MZ_ZIP_FILE_CLOSE_FAILED;
+ status = MZ_FALSE;
+ }
+ }
+ pState->m_pFile = NULL;
+ }
+#endif /* #ifndef MINIZ_NO_STDIO */
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
+ }
+ pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
+
+ return status;
+}
+
+mz_bool mz_zip_reader_end(mz_zip_archive *pZip)
+{
+ return mz_zip_reader_end_internal(pZip, MZ_TRUE);
+}
+mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags)
+{
+ if ((!pZip) || (!pZip->m_pRead))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ if (!mz_zip_reader_init_internal(pZip, flags))
+ return MZ_FALSE;
+
+ pZip->m_zip_type = MZ_ZIP_TYPE_USER;
+ pZip->m_archive_size = size;
+
+ if (!mz_zip_reader_read_central_dir(pZip, flags))
+ {
+ mz_zip_reader_end_internal(pZip, MZ_FALSE);
+ return MZ_FALSE;
+ }
+
+ return MZ_TRUE;
+}
+
+static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
+{
+ mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
+ size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n);
+ memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s);
+ return s;
+}
+
+mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags)
+{
+ if (!pMem)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ if (size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
+ return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
+
+ if (!mz_zip_reader_init_internal(pZip, flags))
+ return MZ_FALSE;
+
+ pZip->m_zip_type = MZ_ZIP_TYPE_MEMORY;
+ pZip->m_archive_size = size;
+ pZip->m_pRead = mz_zip_mem_read_func;
+ pZip->m_pIO_opaque = pZip;
+ pZip->m_pNeeds_keepalive = NULL;
+
+#ifdef __cplusplus
+ pZip->m_pState->m_pMem = const_cast<void *>(pMem);
+#else
+ pZip->m_pState->m_pMem = (void *)pMem;
+#endif
+
+ pZip->m_pState->m_mem_size = size;
+
+ if (!mz_zip_reader_read_central_dir(pZip, flags))
+ {
+ mz_zip_reader_end_internal(pZip, MZ_FALSE);
+ return MZ_FALSE;
+ }
+
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_STDIO
+static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
+{
+ mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
+ mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
+
+ file_ofs += pZip->m_pState->m_file_archive_start_ofs;
+
+ if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
+ return 0;
+
+ return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile);
+}
+
+mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags)
+{
+ return mz_zip_reader_init_file_v2(pZip, pFilename, flags, 0, 0);
+}
+
+mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size)
+{
+ mz_uint64 file_size;
+ MZ_FILE *pFile;
+
+ if ((!pZip) || (!pFilename) || ((archive_size) && (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ pFile = MZ_FOPEN(pFilename, "rb");
+ if (!pFile)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
+
+ file_size = archive_size;
+ if (!file_size)
+ {
+ if (MZ_FSEEK64(pFile, 0, SEEK_END))
+ {
+ MZ_FCLOSE(pFile);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED);
+ }
+
+ file_size = MZ_FTELL64(pFile);
+ }
+
+ /* TODO: Better sanity check archive_size and the # of actual remaining bytes */
+
+ if (file_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
+ {
+ MZ_FCLOSE(pFile);
+ return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
+ }
+
+ if (!mz_zip_reader_init_internal(pZip, flags))
+ {
+ MZ_FCLOSE(pFile);
+ return MZ_FALSE;
+ }
+
+ pZip->m_zip_type = MZ_ZIP_TYPE_FILE;
+ pZip->m_pRead = mz_zip_file_read_func;
+ pZip->m_pIO_opaque = pZip;
+ pZip->m_pState->m_pFile = pFile;
+ pZip->m_archive_size = file_size;
+ pZip->m_pState->m_file_archive_start_ofs = file_start_ofs;
+
+ if (!mz_zip_reader_read_central_dir(pZip, flags))
+ {
+ mz_zip_reader_end_internal(pZip, MZ_FALSE);
+ return MZ_FALSE;
+ }
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags)
+{
+ mz_uint64 cur_file_ofs;
+
+ if ((!pZip) || (!pFile))
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
+
+ cur_file_ofs = MZ_FTELL64(pFile);
+
+ if (!archive_size)
+ {
+ if (MZ_FSEEK64(pFile, 0, SEEK_END))
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED);
+
+ archive_size = MZ_FTELL64(pFile) - cur_file_ofs;
+
+ if (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
+ return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
+ }
+
+ if (!mz_zip_reader_init_internal(pZip, flags))
+ return MZ_FALSE;
+
+ pZip->m_zip_type = MZ_ZIP_TYPE_CFILE;
+ pZip->m_pRead = mz_zip_file_read_func;
+
+ pZip->m_pIO_opaque = pZip;
+ pZip->m_pState->m_pFile = pFile;
+ pZip->m_archive_size = archive_size;
+ pZip->m_pState->m_file_archive_start_ofs = cur_file_ofs;
+
+ if (!mz_zip_reader_read_central_dir(pZip, flags))
+ {
+ mz_zip_reader_end_internal(pZip, MZ_FALSE);
+ return MZ_FALSE;
+ }
+
+ return MZ_TRUE;
+}
+
+#endif /* #ifndef MINIZ_NO_STDIO */
+
+static MZ_FORCEINLINE const mz_uint8 *mz_zip_get_cdh(mz_zip_archive *pZip, mz_uint file_index)
+{
+ if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files))
+ return NULL;
+ return &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index));
+}
+
+mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index)
+{
+ mz_uint m_bit_flag;
+ const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
+ if (!p)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+ return MZ_FALSE;
+ }
+
+ m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
+ return (m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION)) != 0;
+}
+
+mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index)
+{
+ mz_uint bit_flag;
+ mz_uint method;
+
+ const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
+ if (!p)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+ return MZ_FALSE;
+ }
+
+ method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
+ bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
+
+ if ((method != 0) && (method != MZ_DEFLATED))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
+ return MZ_FALSE;
+ }
+
+ if (bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
+ return MZ_FALSE;
+ }
+
+ if (bit_flag & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);
+ return MZ_FALSE;
+ }
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index)
+{
+ mz_uint filename_len, attribute_mapping_id, external_attr;
+ const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
+ if (!p)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+ return MZ_FALSE;
+ }
+
+ filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ if (filename_len)
+ {
+ if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/')
+ return MZ_TRUE;
+ }
+
+ /* Bugfix: This code was also checking if the internal attribute was non-zero, which wasn't correct. */
+ /* Most/all zip writers (hopefully) set DOS file/directory attributes in the low 16-bits, so check for the DOS directory flag and ignore the source OS ID in the created by field. */
+ /* FIXME: Remove this check? Is it necessary - we already check the filename. */
+ attribute_mapping_id = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS) >> 8;
+ (void)attribute_mapping_id;
+
+ external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
+ if ((external_attr & MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG) != 0)
+ {
+ return MZ_TRUE;
+ }
+
+ return MZ_FALSE;
+}
+
+static mz_bool mz_zip_file_stat_internal(mz_zip_archive *pZip, mz_uint file_index, const mz_uint8 *pCentral_dir_header, mz_zip_archive_file_stat *pStat, mz_bool *pFound_zip64_extra_data)
+{
+ mz_uint n;
+ const mz_uint8 *p = pCentral_dir_header;
+
+ if (pFound_zip64_extra_data)
+ *pFound_zip64_extra_data = MZ_FALSE;
+
+ if ((!p) || (!pStat))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ /* Extract fields from the central directory record. */
+ pStat->m_file_index = file_index;
+ pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index);
+ pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS);
+ pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS);
+ pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
+ pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
+#ifndef MINIZ_NO_TIME
+ pStat->m_time = mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS), MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS));
+#endif
+ pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS);
+ pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
+ pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
+ pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS);
+ pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
+ pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
+
+ /* Copy as much of the filename and comment as possible. */
+ n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1);
+ memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
+ pStat->m_filename[n] = '\0';
+
+ n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS);
+ n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1);
+ pStat->m_comment_size = n;
+ memcpy(pStat->m_comment, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), n);
+ pStat->m_comment[n] = '\0';
+
+ /* Set some flags for convienance */
+ pStat->m_is_directory = mz_zip_reader_is_file_a_directory(pZip, file_index);
+ pStat->m_is_encrypted = mz_zip_reader_is_file_encrypted(pZip, file_index);
+ pStat->m_is_supported = mz_zip_reader_is_file_supported(pZip, file_index);
+
+ /* See if we need to read any zip64 extended information fields. */
+ /* Confusingly, these zip64 fields can be present even on non-zip64 archives (Debian zip on a huge files from stdin piped to stdout creates them). */
+ if (MZ_MAX(MZ_MAX(pStat->m_comp_size, pStat->m_uncomp_size), pStat->m_local_header_ofs) == MZ_UINT32_MAX)
+ {
+ /* Attempt to find zip64 extended information field in the entry's extra data */
+ mz_uint32 extra_size_remaining = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS);
+
+ if (extra_size_remaining)
+ {
+ const mz_uint8 *pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+
+ do
+ {
+ mz_uint32 field_id;
+ mz_uint32 field_data_size;
+
+ if (extra_size_remaining < (sizeof(mz_uint16) * 2))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ field_id = MZ_READ_LE16(pExtra_data);
+ field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
+
+ if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
+ {
+ const mz_uint8 *pField_data = pExtra_data + sizeof(mz_uint16) * 2;
+ mz_uint32 field_data_remaining = field_data_size;
+
+ if (pFound_zip64_extra_data)
+ *pFound_zip64_extra_data = MZ_TRUE;
+
+ if (pStat->m_uncomp_size == MZ_UINT32_MAX)
+ {
+ if (field_data_remaining < sizeof(mz_uint64))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ pStat->m_uncomp_size = MZ_READ_LE64(pField_data);
+ pField_data += sizeof(mz_uint64);
+ field_data_remaining -= sizeof(mz_uint64);
+ }
+
+ if (pStat->m_comp_size == MZ_UINT32_MAX)
+ {
+ if (field_data_remaining < sizeof(mz_uint64))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ pStat->m_comp_size = MZ_READ_LE64(pField_data);
+ pField_data += sizeof(mz_uint64);
+ field_data_remaining -= sizeof(mz_uint64);
+ }
+
+ if (pStat->m_local_header_ofs == MZ_UINT32_MAX)
+ {
+ if (field_data_remaining < sizeof(mz_uint64))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ pStat->m_local_header_ofs = MZ_READ_LE64(pField_data);
+ pField_data += sizeof(mz_uint64);
+ field_data_remaining -= sizeof(mz_uint64);
+ }
+
+ break;
+ }
+
+ pExtra_data += sizeof(mz_uint16) * 2 + field_data_size;
+ extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size;
+ } while (extra_size_remaining);
+ }
+ }
+
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags)
+{
+ mz_uint i;
+ if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE)
+ return 0 == memcmp(pA, pB, len);
+ for (i = 0; i < len; ++i)
+ if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i]))
+ return MZ_FALSE;
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE int mz_zip_filename_compare(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, const char *pR, mz_uint r_len)
+{
+ const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
+ mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ mz_uint8 l = 0, r = 0;
+ pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
+ pE = pL + MZ_MIN(l_len, r_len);
+ while (pL < pE)
+ {
+ if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
+ break;
+ pL++;
+ pR++;
+ }
+ return (pL == pE) ? (int)(l_len - r_len) : (l - r);
+}
+
+static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename, mz_uint32 *pIndex)
+{
+ mz_zip_internal_state *pState = pZip->m_pState;
+ const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
+ const mz_zip_array *pCentral_dir = &pState->m_central_dir;
+ mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
+ const uint32_t size = pZip->m_total_files;
+ const mz_uint filename_len = (mz_uint)strlen(pFilename);
+
+ if (pIndex)
+ *pIndex = 0;
+
+ if (size)
+ {
+ /* yes I could use uint32_t's, but then we would have to add some special case checks in the loop, argh, and */
+ /* honestly the major expense here on 32-bit CPU's will still be the filename compare */
+ mz_int64 l = 0, h = (mz_int64)size - 1;
+
+ while (l <= h)
+ {
+ mz_int64 m = l + ((h - l) >> 1);
+ uint32_t file_index = pIndices[(uint32_t)m];
+
+ int comp = mz_zip_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len);
+ if (!comp)
+ {
+ if (pIndex)
+ *pIndex = file_index;
+ return MZ_TRUE;
+ }
+ else if (comp < 0)
+ l = m + 1;
+ else
+ h = m - 1;
+ }
+ }
+
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND);
+}
+
+int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags)
+{
+ mz_uint32 index;
+ if (!mz_zip_reader_locate_file_v2(pZip, pName, pComment, flags, &index))
+ return -1;
+ else
+ return (int)index;
+}
+
+mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *pIndex)
+{
+ mz_uint file_index;
+ size_t name_len, comment_len;
+
+ if (pIndex)
+ *pIndex = 0;
+
+ if ((!pZip) || (!pZip->m_pState) || (!pName))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ /* See if we can use a binary search */
+ if (((pZip->m_pState->m_init_flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0) &&
+ (pZip->m_zip_mode == MZ_ZIP_MODE_READING) &&
+ ((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size))
+ {
+ return mz_zip_locate_file_binary_search(pZip, pName, pIndex);
+ }
+
+ /* Locate the entry by scanning the entire central directory */
+ name_len = strlen(pName);
+ if (name_len > MZ_UINT16_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ comment_len = pComment ? strlen(pComment) : 0;
+ if (comment_len > MZ_UINT16_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ for (file_index = 0; file_index < pZip->m_total_files; file_index++)
+ {
+ const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index));
+ mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ const char *pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
+ if (filename_len < name_len)
+ continue;
+ if (comment_len)
+ {
+ mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), file_comment_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS);
+ const char *pFile_comment = pFilename + filename_len + file_extra_len;
+ if ((file_comment_len != comment_len) || (!mz_zip_string_equal(pComment, pFile_comment, file_comment_len, flags)))
+ continue;
+ }
+ if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len))
+ {
+ int ofs = filename_len - 1;
+ do
+ {
+ if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || (pFilename[ofs] == ':'))
+ break;
+ } while (--ofs >= 0);
+ ofs++;
+ pFilename += ofs;
+ filename_len -= ofs;
+ }
+ if ((filename_len == name_len) && (mz_zip_string_equal(pName, pFilename, filename_len, flags)))
+ {
+ if (pIndex)
+ *pIndex = file_index;
+ return MZ_TRUE;
+ }
+ }
+
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND);
+}
+
+mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size)
+{
+ int status = TINFL_STATUS_DONE;
+ mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
+ mz_zip_archive_file_stat file_stat;
+ void *pRead_buf;
+ mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
+ mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
+ tinfl_decompressor inflator;
+
+ if ((!pZip) || (!pZip->m_pState) || ((buf_size) && (!pBuf)) || ((user_read_buf_size) && (!pUser_read_buf)) || (!pZip->m_pRead))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
+ return MZ_FALSE;
+
+ /* A directory or zero length file */
+ if ((file_stat.m_is_directory) || (!file_stat.m_comp_size))
+ return MZ_TRUE;
+
+ /* Encryption and patch files are not supported. */
+ if (file_stat.m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG))
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
+
+ /* This function only supports decompressing stored and deflate. */
+ if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
+
+ /* Ensure supplied output buffer is large enough. */
+ needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
+ if (buf_size < needed_size)
+ return mz_zip_set_error(pZip, MZ_ZIP_BUF_TOO_SMALL);
+
+ /* Read and parse the local directory entry. */
+ cur_file_ofs = file_stat.m_local_header_ofs;
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+
+ if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
+ if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
+ {
+ /* The file is stored or the caller has requested the compressed data. */
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (size_t)needed_size) != needed_size)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+
+#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
+ if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) == 0)
+ {
+ if (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
+ return mz_zip_set_error(pZip, MZ_ZIP_CRC_CHECK_FAILED);
+ }
+#endif
+
+ return MZ_TRUE;
+ }
+
+ /* Decompress the file either directly from memory or from a file input buffer. */
+ tinfl_init(&inflator);
+
+ if (pZip->m_pState->m_pMem)
+ {
+ /* Read directly from the archive in memory. */
+ pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
+ read_buf_size = read_buf_avail = file_stat.m_comp_size;
+ comp_remaining = 0;
+ }
+ else if (pUser_read_buf)
+ {
+ /* Use a user provided read buffer. */
+ if (!user_read_buf_size)
+ return MZ_FALSE;
+ pRead_buf = (mz_uint8 *)pUser_read_buf;
+ read_buf_size = user_read_buf_size;
+ read_buf_avail = 0;
+ comp_remaining = file_stat.m_comp_size;
+ }
+ else
+ {
+ /* Temporarily allocate a read buffer. */
+ read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
+ if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
+ return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
+
+ if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+
+ read_buf_avail = 0;
+ comp_remaining = file_stat.m_comp_size;
+ }
+
+ do
+ {
+ /* The size_t cast here should be OK because we've verified that the output buffer is >= file_stat.m_uncomp_size above */
+ size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs);
+ if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
+ {
+ read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
+ {
+ status = TINFL_STATUS_FAILED;
+ mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED);
+ break;
+ }
+ cur_file_ofs += read_buf_avail;
+ comp_remaining -= read_buf_avail;
+ read_buf_ofs = 0;
+ }
+ in_buf_size = (size_t)read_buf_avail;
+ status = tinfl_decompress(&inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0));
+ read_buf_avail -= in_buf_size;
+ read_buf_ofs += in_buf_size;
+ out_buf_ofs += out_buf_size;
+ } while (status == TINFL_STATUS_NEEDS_MORE_INPUT);
+
+ if (status == TINFL_STATUS_DONE)
+ {
+ /* Make sure the entire file was decompressed, and check its CRC. */
+ if (out_buf_ofs != file_stat.m_uncomp_size)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE);
+ status = TINFL_STATUS_FAILED;
+ }
+#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
+ else if (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_CRC_CHECK_FAILED);
+ status = TINFL_STATUS_FAILED;
+ }
+#endif
+ }
+
+ if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf))
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+
+ return status == TINFL_STATUS_DONE;
+}
+
+mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size)
+{
+ mz_uint32 file_index;
+ if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
+ return MZ_FALSE;
+ return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size);
+}
+
+mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags)
+{
+ return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, NULL, 0);
+}
+
+mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags)
+{
+ return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, buf_size, flags, NULL, 0);
+}
+
+void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags)
+{
+ mz_uint64 comp_size, uncomp_size, alloc_size;
+ const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
+ void *pBuf;
+
+ if (pSize)
+ *pSize = 0;
+
+ if (!p)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
+ uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
+
+ alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
+ if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ return NULL;
+ }
+
+ if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, flags))
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return NULL;
+ }
+
+ if (pSize)
+ *pSize = (size_t)alloc_size;
+ return pBuf;
+}
+
+void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags)
+{
+ mz_uint32 file_index;
+ if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
+ {
+ if (pSize)
+ *pSize = 0;
+ return MZ_FALSE;
+ }
+ return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags);
+}
+
+mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags)
+{
+ int status = TINFL_STATUS_DONE;
+#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
+ mz_uint file_crc32 = MZ_CRC32_INIT;
+#endif
+ mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs;
+ mz_zip_archive_file_stat file_stat;
+ void *pRead_buf = NULL;
+ void *pWrite_buf = NULL;
+ mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
+ mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
+
+ if ((!pZip) || (!pZip->m_pState) || (!pCallback) || (!pZip->m_pRead))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
+ return MZ_FALSE;
+
+ /* A directory or zero length file */
+ if ((file_stat.m_is_directory) || (!file_stat.m_comp_size))
+ return MZ_TRUE;
+
+ /* Encryption and patch files are not supported. */
+ if (file_stat.m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG))
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
+
+ /* This function only supports decompressing stored and deflate. */
+ if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
+
+ /* Read and do some minimal validation of the local directory entry (this doesn't crack the zip64 stuff, which we already have from the central dir) */
+ cur_file_ofs = file_stat.m_local_header_ofs;
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+
+ if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
+ if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ /* Decompress the file either directly from memory or from a file input buffer. */
+ if (pZip->m_pState->m_pMem)
+ {
+ pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
+ read_buf_size = read_buf_avail = file_stat.m_comp_size;
+ comp_remaining = 0;
+ }
+ else
+ {
+ read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
+ if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+
+ read_buf_avail = 0;
+ comp_remaining = file_stat.m_comp_size;
+ }
+
+ if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
+ {
+ /* The file is stored or the caller has requested the compressed data. */
+ if (pZip->m_pState->m_pMem)
+ {
+ if (((sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > MZ_UINT32_MAX))
+ return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
+
+ if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED);
+ status = TINFL_STATUS_FAILED;
+ }
+ else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
+ {
+#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
+ file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size);
+#endif
+ }
+
+ cur_file_ofs += file_stat.m_comp_size;
+ out_buf_ofs += file_stat.m_comp_size;
+ comp_remaining = 0;
+ }
+ else
+ {
+ while (comp_remaining)
+ {
+ read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+
+#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
+ if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
+ {
+ file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail);
+ }
+#endif
+
+ if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED);
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+
+ cur_file_ofs += read_buf_avail;
+ out_buf_ofs += read_buf_avail;
+ comp_remaining -= read_buf_avail;
+ }
+ }
+ }
+ else
+ {
+ tinfl_decompressor inflator;
+ tinfl_init(&inflator);
+
+ if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ status = TINFL_STATUS_FAILED;
+ }
+ else
+ {
+ do
+ {
+ mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
+ size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
+ if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
+ {
+ read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+ cur_file_ofs += read_buf_avail;
+ comp_remaining -= read_buf_avail;
+ read_buf_ofs = 0;
+ }
+
+ in_buf_size = (size_t)read_buf_avail;
+ status = tinfl_decompress(&inflator, (const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
+ read_buf_avail -= in_buf_size;
+ read_buf_ofs += in_buf_size;
+
+ if (out_buf_size)
+ {
+ if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED);
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+
+#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
+ file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
+#endif
+ if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED);
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+ }
+ } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT));
+ }
+ }
+
+ if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
+ {
+ /* Make sure the entire file was decompressed, and check its CRC. */
+ if (out_buf_ofs != file_stat.m_uncomp_size)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE);
+ status = TINFL_STATUS_FAILED;
+ }
+#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
+ else if (file_crc32 != file_stat.m_crc32)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED);
+ status = TINFL_STATUS_FAILED;
+ }
+#endif
+ }
+
+ if (!pZip->m_pState->m_pMem)
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+
+ if (pWrite_buf)
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf);
+
+ return status == TINFL_STATUS_DONE;
+}
+
+mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags)
+{
+ mz_uint32 file_index;
+ if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
+ return MZ_FALSE;
+
+ return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, flags);
+}
+
+mz_zip_reader_extract_iter_state* mz_zip_reader_extract_iter_new(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags)
+{
+ mz_zip_reader_extract_iter_state *pState;
+ mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
+ mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
+
+ /* Argument sanity check */
+ if ((!pZip) || (!pZip->m_pState))
+ return NULL;
+
+ /* Allocate an iterator status structure */
+ pState = (mz_zip_reader_extract_iter_state*)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_reader_extract_iter_state));
+ if (!pState)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ return NULL;
+ }
+
+ /* Fetch file details */
+ if (!mz_zip_reader_file_stat(pZip, file_index, &pState->file_stat))
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
+ return NULL;
+ }
+
+ /* Encryption and patch files are not supported. */
+ if (pState->file_stat.m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
+ return NULL;
+ }
+
+ /* This function only supports decompressing stored and deflate. */
+ if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (pState->file_stat.m_method != 0) && (pState->file_stat.m_method != MZ_DEFLATED))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
+ return NULL;
+ }
+
+ /* Init state - save args */
+ pState->pZip = pZip;
+ pState->flags = flags;
+
+ /* Init state - reset variables to defaults */
+ pState->status = TINFL_STATUS_DONE;
+#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
+ pState->file_crc32 = MZ_CRC32_INIT;
+#endif
+ pState->read_buf_ofs = 0;
+ pState->out_buf_ofs = 0;
+ pState->pRead_buf = NULL;
+ pState->pWrite_buf = NULL;
+ pState->out_blk_remain = 0;
+
+ /* Read and parse the local directory entry. */
+ pState->cur_file_ofs = pState->file_stat.m_local_header_ofs;
+ if (pZip->m_pRead(pZip->m_pIO_opaque, pState->cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
+ return NULL;
+ }
+
+ if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
+ return NULL;
+ }
+
+ pState->cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
+ if ((pState->cur_file_ofs + pState->file_stat.m_comp_size) > pZip->m_archive_size)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
+ return NULL;
+ }
+
+ /* Decompress the file either directly from memory or from a file input buffer. */
+ if (pZip->m_pState->m_pMem)
+ {
+ pState->pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + pState->cur_file_ofs;
+ pState->read_buf_size = pState->read_buf_avail = pState->file_stat.m_comp_size;
+ pState->comp_remaining = pState->file_stat.m_comp_size;
+ }
+ else
+ {
+ if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method)))
+ {
+ /* Decompression required, therefore intermediate read buffer required */
+ pState->read_buf_size = MZ_MIN(pState->file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
+ if (NULL == (pState->pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)pState->read_buf_size)))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
+ return NULL;
+ }
+ }
+ else
+ {
+ /* Decompression not required - we will be reading directly into user buffer, no temp buf required */
+ pState->read_buf_size = 0;
+ }
+ pState->read_buf_avail = 0;
+ pState->comp_remaining = pState->file_stat.m_comp_size;
+ }
+
+ if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method)))
+ {
+ /* Decompression required, init decompressor */
+ tinfl_init( &pState->inflator );
+
+ /* Allocate write buffer */
+ if (NULL == (pState->pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ if (pState->pRead_buf)
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState->pRead_buf);
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
+ return NULL;
+ }
+ }
+
+ return pState;
+}
+
+mz_zip_reader_extract_iter_state* mz_zip_reader_extract_file_iter_new(mz_zip_archive *pZip, const char *pFilename, mz_uint flags)
+{
+ mz_uint32 file_index;
+
+ /* Locate file index by name */
+ if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
+ return NULL;
+
+ /* Construct iterator */
+ return mz_zip_reader_extract_iter_new(pZip, file_index, flags);
+}
+
+size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state* pState, void* pvBuf, size_t buf_size)
+{
+ size_t copied_to_caller = 0;
+
+ /* Argument sanity check */
+ if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState) || (!pvBuf))
+ return 0;
+
+ if ((pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method))
+ {
+ /* The file is stored or the caller has requested the compressed data, calc amount to return. */
+ copied_to_caller = (size_t)MZ_MIN( buf_size, pState->comp_remaining );
+
+ /* Zip is in memory....or requires reading from a file? */
+ if (pState->pZip->m_pState->m_pMem)
+ {
+ /* Copy data to caller's buffer */
+ memcpy( pvBuf, pState->pRead_buf, copied_to_caller );
+ pState->pRead_buf = ((mz_uint8*)pState->pRead_buf) + copied_to_caller;
+ }
+ else
+ {
+ /* Read directly into caller's buffer */
+ if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, pState->cur_file_ofs, pvBuf, copied_to_caller) != copied_to_caller)
+ {
+ /* Failed to read all that was asked for, flag failure and alert user */
+ mz_zip_set_error(pState->pZip, MZ_ZIP_FILE_READ_FAILED);
+ pState->status = TINFL_STATUS_FAILED;
+ copied_to_caller = 0;
+ }
+ }
+
+#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
+ /* Compute CRC if not returning compressed data only */
+ if (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
+ pState->file_crc32 = (mz_uint32)mz_crc32(pState->file_crc32, (const mz_uint8 *)pvBuf, copied_to_caller);
+#endif
+
+ /* Advance offsets, dec counters */
+ pState->cur_file_ofs += copied_to_caller;
+ pState->out_buf_ofs += copied_to_caller;
+ pState->comp_remaining -= copied_to_caller;
+ }
+ else
+ {
+ do
+ {
+ /* Calc ptr to write buffer - given current output pos and block size */
+ mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pState->pWrite_buf + (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
+
+ /* Calc max output size - given current output pos and block size */
+ size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
+
+ if (!pState->out_blk_remain)
+ {
+ /* Read more data from file if none available (and reading from file) */
+ if ((!pState->read_buf_avail) && (!pState->pZip->m_pState->m_pMem))
+ {
+ /* Calc read size */
+ pState->read_buf_avail = MZ_MIN(pState->read_buf_size, pState->comp_remaining);
+ if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, pState->cur_file_ofs, pState->pRead_buf, (size_t)pState->read_buf_avail) != pState->read_buf_avail)
+ {
+ mz_zip_set_error(pState->pZip, MZ_ZIP_FILE_READ_FAILED);
+ pState->status = TINFL_STATUS_FAILED;
+ break;
+ }
+
+ /* Advance offsets, dec counters */
+ pState->cur_file_ofs += pState->read_buf_avail;
+ pState->comp_remaining -= pState->read_buf_avail;
+ pState->read_buf_ofs = 0;
+ }
+
+ /* Perform decompression */
+ in_buf_size = (size_t)pState->read_buf_avail;
+ pState->status = tinfl_decompress(&pState->inflator, (const mz_uint8 *)pState->pRead_buf + pState->read_buf_ofs, &in_buf_size, (mz_uint8 *)pState->pWrite_buf, pWrite_buf_cur, &out_buf_size, pState->comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
+ pState->read_buf_avail -= in_buf_size;
+ pState->read_buf_ofs += in_buf_size;
+
+ /* Update current output block size remaining */
+ pState->out_blk_remain = out_buf_size;
+ }
+
+ if (pState->out_blk_remain)
+ {
+ /* Calc amount to return. */
+ size_t to_copy = MZ_MIN( (buf_size - copied_to_caller), pState->out_blk_remain );
+
+ /* Copy data to caller's buffer */
+ memcpy( (uint8_t*)pvBuf + copied_to_caller, pWrite_buf_cur, to_copy );
+
+#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
+ /* Perform CRC */
+ pState->file_crc32 = (mz_uint32)mz_crc32(pState->file_crc32, pWrite_buf_cur, to_copy);
+#endif
+
+ /* Decrement data consumed from block */
+ pState->out_blk_remain -= to_copy;
+
+ /* Inc output offset, while performing sanity check */
+ if ((pState->out_buf_ofs += to_copy) > pState->file_stat.m_uncomp_size)
+ {
+ mz_zip_set_error(pState->pZip, MZ_ZIP_DECOMPRESSION_FAILED);
+ pState->status = TINFL_STATUS_FAILED;
+ break;
+ }
+
+ /* Increment counter of data copied to caller */
+ copied_to_caller += to_copy;
+ }
+ } while ( (copied_to_caller < buf_size) && ((pState->status == TINFL_STATUS_NEEDS_MORE_INPUT) || (pState->status == TINFL_STATUS_HAS_MORE_OUTPUT)) );
+ }
+
+ /* Return how many bytes were copied into user buffer */
+ return copied_to_caller;
+}
+
+mz_bool mz_zip_reader_extract_iter_free(mz_zip_reader_extract_iter_state* pState)
+{
+ int status;
+
+ /* Argument sanity check */
+ if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState))
+ return MZ_FALSE;
+
+ /* Was decompression completed and requested? */
+ if ((pState->status == TINFL_STATUS_DONE) && (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
+ {
+ /* Make sure the entire file was decompressed, and check its CRC. */
+ if (pState->out_buf_ofs != pState->file_stat.m_uncomp_size)
+ {
+ mz_zip_set_error(pState->pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE);
+ pState->status = TINFL_STATUS_FAILED;
+ }
+#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
+ else if (pState->file_crc32 != pState->file_stat.m_crc32)
+ {
+ mz_zip_set_error(pState->pZip, MZ_ZIP_DECOMPRESSION_FAILED);
+ pState->status = TINFL_STATUS_FAILED;
+ }
+#endif
+ }
+
+ /* Free buffers */
+ if (!pState->pZip->m_pState->m_pMem)
+ pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pRead_buf);
+ if (pState->pWrite_buf)
+ pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pWrite_buf);
+
+ /* Save status */
+ status = pState->status;
+
+ /* Free context */
+ pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState);
+
+ return status == TINFL_STATUS_DONE;
+}
+
+#ifndef MINIZ_NO_STDIO
+static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n)
+{
+ (void)ofs;
+
+ return MZ_FWRITE(pBuf, 1, n, (MZ_FILE *)pOpaque);
+}
+
+mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags)
+{
+ mz_bool status;
+ mz_zip_archive_file_stat file_stat;
+ MZ_FILE *pFile;
+
+ if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
+ return MZ_FALSE;
+
+ if ((file_stat.m_is_directory) || (!file_stat.m_is_supported))
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);
+
+ pFile = MZ_FOPEN(pDst_filename, "wb");
+ if (!pFile)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
+
+ status = mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags);
+
+ if (MZ_FCLOSE(pFile) == EOF)
+ {
+ if (status)
+ mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED);
+
+ status = MZ_FALSE;
+ }
+
+#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO)
+ if (status)
+ mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time);
+#endif
+
+ return status;
+}
+
+mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags)
+{
+ mz_uint32 file_index;
+ if (!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags, &file_index))
+ return MZ_FALSE;
+
+ return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags);
+}
+
+mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *pFile, mz_uint flags)
+{
+ mz_zip_archive_file_stat file_stat;
+
+ if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
+ return MZ_FALSE;
+
+ if ((file_stat.m_is_directory) || (!file_stat.m_is_supported))
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);
+
+ return mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags);
+}
+
+mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags)
+{
+ mz_uint32 file_index;
+ if (!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags, &file_index))
+ return MZ_FALSE;
+
+ return mz_zip_reader_extract_to_cfile(pZip, file_index, pFile, flags);
+}
+#endif /* #ifndef MINIZ_NO_STDIO */
+
+static size_t mz_zip_compute_crc32_callback(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
+{
+ mz_uint32 *p = (mz_uint32 *)pOpaque;
+ (void)file_ofs;
+ *p = (mz_uint32)mz_crc32(*p, (const mz_uint8 *)pBuf, n);
+ return n;
+}
+
+mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags)
+{
+ mz_zip_archive_file_stat file_stat;
+ mz_zip_internal_state *pState;
+ const mz_uint8 *pCentral_dir_header;
+ mz_bool found_zip64_ext_data_in_cdir = MZ_FALSE;
+ mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE;
+ mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
+ mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
+ mz_uint64 local_header_ofs = 0;
+ mz_uint32 local_header_filename_len, local_header_extra_len, local_header_crc32;
+ mz_uint64 local_header_comp_size, local_header_uncomp_size;
+ mz_uint32 uncomp_crc32 = MZ_CRC32_INIT;
+ mz_bool has_data_descriptor;
+ mz_uint32 local_header_bit_flags;
+
+ mz_zip_array file_data_array;
+ mz_zip_array_init(&file_data_array, 1);
+
+ if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ if (file_index > pZip->m_total_files)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ pState = pZip->m_pState;
+
+ pCentral_dir_header = mz_zip_get_cdh(pZip, file_index);
+
+ if (!mz_zip_file_stat_internal(pZip, file_index, pCentral_dir_header, &file_stat, &found_zip64_ext_data_in_cdir))
+ return MZ_FALSE;
+
+ /* A directory or zero length file */
+ if ((file_stat.m_is_directory) || (!file_stat.m_uncomp_size))
+ return MZ_TRUE;
+
+ /* Encryption and patch files are not supported. */
+ if (file_stat.m_is_encrypted)
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
+
+ /* This function only supports stored and deflate. */
+ if ((file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
+
+ if (!file_stat.m_is_supported)
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);
+
+ /* Read and parse the local directory entry. */
+ local_header_ofs = file_stat.m_local_header_ofs;
+ if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+
+ if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ local_header_filename_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS);
+ local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
+ local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS);
+ local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS);
+ local_header_crc32 = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_CRC32_OFS);
+ local_header_bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
+ has_data_descriptor = (local_header_bit_flags & 8) != 0;
+
+ if (local_header_filename_len != strlen(file_stat.m_filename))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ if ((local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size) > pZip->m_archive_size)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ if (!mz_zip_array_resize(pZip, &file_data_array, MZ_MAX(local_header_filename_len, local_header_extra_len), MZ_FALSE))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ goto handle_failure;
+ }
+
+ if (local_header_filename_len)
+ {
+ if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE, file_data_array.m_p, local_header_filename_len) != local_header_filename_len)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+ goto handle_failure;
+ }
+
+ /* I've seen 1 archive that had the same pathname, but used backslashes in the local dir and forward slashes in the central dir. Do we care about this? For now, this case will fail validation. */
+ if (memcmp(file_stat.m_filename, file_data_array.m_p, local_header_filename_len) != 0)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
+ goto handle_failure;
+ }
+ }
+
+ if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
+ {
+ mz_uint32 extra_size_remaining = local_header_extra_len;
+ const mz_uint8 *pExtra_data = (const mz_uint8 *)file_data_array.m_p;
+
+ if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len, file_data_array.m_p, local_header_extra_len) != local_header_extra_len)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+ goto handle_failure;
+ }
+
+ do
+ {
+ mz_uint32 field_id, field_data_size, field_total_size;
+
+ if (extra_size_remaining < (sizeof(mz_uint16) * 2))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+ goto handle_failure;
+ }
+
+ field_id = MZ_READ_LE16(pExtra_data);
+ field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
+ field_total_size = field_data_size + sizeof(mz_uint16) * 2;
+
+ if (field_total_size > extra_size_remaining)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+ goto handle_failure;
+ }
+
+ if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
+ {
+ const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32);
+
+ if (field_data_size < sizeof(mz_uint64) * 2)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+ goto handle_failure;
+ }
+
+ local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data);
+ local_header_comp_size = MZ_READ_LE64(pSrc_field_data + sizeof(mz_uint64));
+
+ found_zip64_ext_data_in_ldir = MZ_TRUE;
+ break;
+ }
+
+ pExtra_data += field_total_size;
+ extra_size_remaining -= field_total_size;
+ } while (extra_size_remaining);
+ }
+
+ /* TODO: parse local header extra data when local_header_comp_size is 0xFFFFFFFF! (big_descriptor.zip) */
+ /* I've seen zips in the wild with the data descriptor bit set, but proper local header values and bogus data descriptors */
+ if ((has_data_descriptor) && (!local_header_comp_size) && (!local_header_crc32))
+ {
+ mz_uint8 descriptor_buf[32];
+ mz_bool has_id;
+ const mz_uint8 *pSrc;
+ mz_uint32 file_crc32;
+ mz_uint64 comp_size = 0, uncomp_size = 0;
+
+ mz_uint32 num_descriptor_uint32s = ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) ? 6 : 4;
+
+ if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size, descriptor_buf, sizeof(mz_uint32) * num_descriptor_uint32s) != (sizeof(mz_uint32) * num_descriptor_uint32s))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+ goto handle_failure;
+ }
+
+ has_id = (MZ_READ_LE32(descriptor_buf) == MZ_ZIP_DATA_DESCRIPTOR_ID);
+ pSrc = has_id ? (descriptor_buf + sizeof(mz_uint32)) : descriptor_buf;
+
+ file_crc32 = MZ_READ_LE32(pSrc);
+
+ if ((pState->m_zip64) || (found_zip64_ext_data_in_ldir))
+ {
+ comp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32));
+ uncomp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32) + sizeof(mz_uint64));
+ }
+ else
+ {
+ comp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32));
+ uncomp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32) + sizeof(mz_uint32));
+ }
+
+ if ((file_crc32 != file_stat.m_crc32) || (comp_size != file_stat.m_comp_size) || (uncomp_size != file_stat.m_uncomp_size))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
+ goto handle_failure;
+ }
+ }
+ else
+ {
+ if ((local_header_crc32 != file_stat.m_crc32) || (local_header_comp_size != file_stat.m_comp_size) || (local_header_uncomp_size != file_stat.m_uncomp_size))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
+ goto handle_failure;
+ }
+ }
+
+ mz_zip_array_clear(pZip, &file_data_array);
+
+ if ((flags & MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY) == 0)
+ {
+ if (!mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_compute_crc32_callback, &uncomp_crc32, 0))
+ return MZ_FALSE;
+
+ /* 1 more check to be sure, although the extract checks too. */
+ if (uncomp_crc32 != file_stat.m_crc32)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
+ return MZ_FALSE;
+ }
+ }
+
+ return MZ_TRUE;
+
+handle_failure:
+ mz_zip_array_clear(pZip, &file_data_array);
+ return MZ_FALSE;
+}
+
+mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags)
+{
+ mz_zip_internal_state *pState;
+ uint32_t i;
+
+ if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ pState = pZip->m_pState;
+
+ /* Basic sanity checks */
+ if (!pState->m_zip64)
+ {
+ if (pZip->m_total_files > MZ_UINT16_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
+
+ if (pZip->m_archive_size > MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
+ }
+ else
+ {
+ if (pZip->m_total_files >= MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
+
+ if (pState->m_central_dir.m_size >= MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
+ }
+
+ for (i = 0; i < pZip->m_total_files; i++)
+ {
+ if (MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG & flags)
+ {
+ mz_uint32 found_index;
+ mz_zip_archive_file_stat stat;
+
+ if (!mz_zip_reader_file_stat(pZip, i, &stat))
+ return MZ_FALSE;
+
+ if (!mz_zip_reader_locate_file_v2(pZip, stat.m_filename, NULL, 0, &found_index))
+ return MZ_FALSE;
+
+ /* This check can fail if there are duplicate filenames in the archive (which we don't check for when writing - that's up to the user) */
+ if (found_index != i)
+ return mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
+ }
+
+ if (!mz_zip_validate_file(pZip, i, flags))
+ return MZ_FALSE;
+ }
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr)
+{
+ mz_bool success = MZ_TRUE;
+ mz_zip_archive zip;
+ mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
+
+ if ((!pMem) || (!size))
+ {
+ if (pErr)
+ *pErr = MZ_ZIP_INVALID_PARAMETER;
+ return MZ_FALSE;
+ }
+
+ mz_zip_zero_struct(&zip);
+
+ if (!mz_zip_reader_init_mem(&zip, pMem, size, flags))
+ {
+ if (pErr)
+ *pErr = zip.m_last_error;
+ return MZ_FALSE;
+ }
+
+ if (!mz_zip_validate_archive(&zip, flags))
+ {
+ actual_err = zip.m_last_error;
+ success = MZ_FALSE;
+ }
+
+ if (!mz_zip_reader_end_internal(&zip, success))
+ {
+ if (!actual_err)
+ actual_err = zip.m_last_error;
+ success = MZ_FALSE;
+ }
+
+ if (pErr)
+ *pErr = actual_err;
+
+ return success;
+}
+
+#ifndef MINIZ_NO_STDIO
+mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr)
+{
+ mz_bool success = MZ_TRUE;
+ mz_zip_archive zip;
+ mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
+
+ if (!pFilename)
+ {
+ if (pErr)
+ *pErr = MZ_ZIP_INVALID_PARAMETER;
+ return MZ_FALSE;
+ }
+
+ mz_zip_zero_struct(&zip);
+
+ if (!mz_zip_reader_init_file_v2(&zip, pFilename, flags, 0, 0))
+ {
+ if (pErr)
+ *pErr = zip.m_last_error;
+ return MZ_FALSE;
+ }
+
+ if (!mz_zip_validate_archive(&zip, flags))
+ {
+ actual_err = zip.m_last_error;
+ success = MZ_FALSE;
+ }
+
+ if (!mz_zip_reader_end_internal(&zip, success))
+ {
+ if (!actual_err)
+ actual_err = zip.m_last_error;
+ success = MZ_FALSE;
+ }
+
+ if (pErr)
+ *pErr = actual_err;
+
+ return success;
+}
+#endif /* #ifndef MINIZ_NO_STDIO */
+
+/* ------------------- .ZIP archive writing */
+
+#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
+
+static MZ_FORCEINLINE void mz_write_le16(mz_uint8 *p, mz_uint16 v)
+{
+ p[0] = (mz_uint8)v;
+ p[1] = (mz_uint8)(v >> 8);
+}
+static MZ_FORCEINLINE void mz_write_le32(mz_uint8 *p, mz_uint32 v)
+{
+ p[0] = (mz_uint8)v;
+ p[1] = (mz_uint8)(v >> 8);
+ p[2] = (mz_uint8)(v >> 16);
+ p[3] = (mz_uint8)(v >> 24);
+}
+static MZ_FORCEINLINE void mz_write_le64(mz_uint8 *p, mz_uint64 v)
+{
+ mz_write_le32(p, (mz_uint32)v);
+ mz_write_le32(p + sizeof(mz_uint32), (mz_uint32)(v >> 32));
+}
+
+#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v))
+#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v))
+#define MZ_WRITE_LE64(p, v) mz_write_le64((mz_uint8 *)(p), (mz_uint64)(v))
+
+static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
+{
+ mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
+ mz_zip_internal_state *pState = pZip->m_pState;
+ mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size);
+
+ if (!n)
+ return 0;
+
+ /* An allocation this big is likely to just fail on 32-bit systems, so don't even go there. */
+ if ((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE);
+ return 0;
+ }
+
+ if (new_size > pState->m_mem_capacity)
+ {
+ void *pNew_block;
+ size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity);
+
+ while (new_capacity < new_size)
+ new_capacity *= 2;
+
+ if (NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity)))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ return 0;
+ }
+
+ pState->m_pMem = pNew_block;
+ pState->m_mem_capacity = new_capacity;
+ }
+ memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n);
+ pState->m_mem_size = (size_t)new_size;
+ return n;
+}
+
+static mz_bool mz_zip_writer_end_internal(mz_zip_archive *pZip, mz_bool set_last_error)
+{
+ mz_zip_internal_state *pState;
+ mz_bool status = MZ_TRUE;
+
+ if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) && (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)))
+ {
+ if (set_last_error)
+ mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+ return MZ_FALSE;
+ }
+
+ pState = pZip->m_pState;
+ pZip->m_pState = NULL;
+ mz_zip_array_clear(pZip, &pState->m_central_dir);
+ mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
+ mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
+
+#ifndef MINIZ_NO_STDIO
+ if (pState->m_pFile)
+ {
+ if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
+ {
+ if (MZ_FCLOSE(pState->m_pFile) == EOF)
+ {
+ if (set_last_error)
+ mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED);
+ status = MZ_FALSE;
+ }
+ }
+
+ pState->m_pFile = NULL;
+ }
+#endif /* #ifndef MINIZ_NO_STDIO */
+
+ if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem))
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem);
+ pState->m_pMem = NULL;
+ }
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
+ pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
+ return status;
+}
+
+mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags)
+{
+ mz_bool zip64 = (flags & MZ_ZIP_FLAG_WRITE_ZIP64) != 0;
+
+ if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
+ {
+ if (!pZip->m_pRead)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+ }
+
+ if (pZip->m_file_offset_alignment)
+ {
+ /* Ensure user specified file offset alignment is a power of 2. */
+ if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+ }
+
+ if (!pZip->m_pAlloc)
+ pZip->m_pAlloc = miniz_def_alloc_func;
+ if (!pZip->m_pFree)
+ pZip->m_pFree = miniz_def_free_func;
+ if (!pZip->m_pRealloc)
+ pZip->m_pRealloc = miniz_def_realloc_func;
+
+ pZip->m_archive_size = existing_size;
+ pZip->m_central_directory_file_ofs = 0;
+ pZip->m_total_files = 0;
+
+ if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+
+ memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
+
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32));
+
+ pZip->m_pState->m_zip64 = zip64;
+ pZip->m_pState->m_zip64_has_extended_info_fields = zip64;
+
+ pZip->m_zip_type = MZ_ZIP_TYPE_USER;
+ pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size)
+{
+ return mz_zip_writer_init_v2(pZip, existing_size, 0);
+}
+
+mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags)
+{
+ pZip->m_pWrite = mz_zip_heap_write_func;
+ pZip->m_pNeeds_keepalive = NULL;
+
+ if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
+ pZip->m_pRead = mz_zip_mem_read_func;
+
+ pZip->m_pIO_opaque = pZip;
+
+ if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags))
+ return MZ_FALSE;
+
+ pZip->m_zip_type = MZ_ZIP_TYPE_HEAP;
+
+ if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, size_to_reserve_at_beginning)))
+ {
+ if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size)))
+ {
+ mz_zip_writer_end_internal(pZip, MZ_FALSE);
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+ pZip->m_pState->m_mem_capacity = initial_allocation_size;
+ }
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size)
+{
+ return mz_zip_writer_init_heap_v2(pZip, size_to_reserve_at_beginning, initial_allocation_size, 0);
+}
+
+#ifndef MINIZ_NO_STDIO
+static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
+{
+ mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
+ mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
+
+ file_ofs += pZip->m_pState->m_file_archive_start_ofs;
+
+ if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED);
+ return 0;
+ }
+
+ return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile);
+}
+
+mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning)
+{
+ return mz_zip_writer_init_file_v2(pZip, pFilename, size_to_reserve_at_beginning, 0);
+}
+
+mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags)
+{
+ MZ_FILE *pFile;
+
+ pZip->m_pWrite = mz_zip_file_write_func;
+ pZip->m_pNeeds_keepalive = NULL;
+
+ if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
+ pZip->m_pRead = mz_zip_file_read_func;
+
+ pZip->m_pIO_opaque = pZip;
+
+ if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags))
+ return MZ_FALSE;
+
+ if (NULL == (pFile = MZ_FOPEN(pFilename, (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) ? "w+b" : "wb")))
+ {
+ mz_zip_writer_end(pZip);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
+ }
+
+ pZip->m_pState->m_pFile = pFile;
+ pZip->m_zip_type = MZ_ZIP_TYPE_FILE;
+
+ if (size_to_reserve_at_beginning)
+ {
+ mz_uint64 cur_ofs = 0;
+ char buf[4096];
+
+ MZ_CLEAR_OBJ(buf);
+
+ do
+ {
+ size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning);
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n)
+ {
+ mz_zip_writer_end(pZip);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+ }
+ cur_ofs += n;
+ size_to_reserve_at_beginning -= n;
+ } while (size_to_reserve_at_beginning);
+ }
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags)
+{
+ pZip->m_pWrite = mz_zip_file_write_func;
+ pZip->m_pNeeds_keepalive = NULL;
+
+ if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
+ pZip->m_pRead = mz_zip_file_read_func;
+
+ pZip->m_pIO_opaque = pZip;
+
+ if (!mz_zip_writer_init_v2(pZip, 0, flags))
+ return MZ_FALSE;
+
+ pZip->m_pState->m_pFile = pFile;
+ pZip->m_pState->m_file_archive_start_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
+ pZip->m_zip_type = MZ_ZIP_TYPE_CFILE;
+
+ return MZ_TRUE;
+}
+#endif /* #ifndef MINIZ_NO_STDIO */
+
+mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags)
+{
+ mz_zip_internal_state *pState;
+
+ if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ if (flags & MZ_ZIP_FLAG_WRITE_ZIP64)
+ {
+ /* We don't support converting a non-zip64 file to zip64 - this seems like more trouble than it's worth. (What about the existing 32-bit data descriptors that could follow the compressed data?) */
+ if (!pZip->m_pState->m_zip64)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+ }
+
+ /* No sense in trying to write to an archive that's already at the support max size */
+ if (pZip->m_pState->m_zip64)
+ {
+ if (pZip->m_total_files == MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
+ }
+ else
+ {
+ if (pZip->m_total_files == MZ_UINT16_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
+
+ if ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE);
+ }
+
+ pState = pZip->m_pState;
+
+ if (pState->m_pFile)
+ {
+#ifdef MINIZ_NO_STDIO
+ (void)pFilename;
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+#else
+ if (pZip->m_pIO_opaque != pZip)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
+ {
+ if (!pFilename)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ /* Archive is being read from stdio and was originally opened only for reading. Try to reopen as writable. */
+ if (NULL == (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile)))
+ {
+ /* The mz_zip_archive is now in a bogus state because pState->m_pFile is NULL, so just close it. */
+ mz_zip_reader_end_internal(pZip, MZ_FALSE);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
+ }
+ }
+
+ pZip->m_pWrite = mz_zip_file_write_func;
+ pZip->m_pNeeds_keepalive = NULL;
+#endif /* #ifdef MINIZ_NO_STDIO */
+ }
+ else if (pState->m_pMem)
+ {
+ /* Archive lives in a memory block. Assume it's from the heap that we can resize using the realloc callback. */
+ if (pZip->m_pIO_opaque != pZip)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ pState->m_mem_capacity = pState->m_mem_size;
+ pZip->m_pWrite = mz_zip_heap_write_func;
+ pZip->m_pNeeds_keepalive = NULL;
+ }
+ /* Archive is being read via a user provided read function - make sure the user has specified a write function too. */
+ else if (!pZip->m_pWrite)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ /* Start writing new files at the archive's current central directory location. */
+ /* TODO: We could add a flag that lets the user start writing immediately AFTER the existing central dir - this would be safer. */
+ pZip->m_archive_size = pZip->m_central_directory_file_ofs;
+ pZip->m_central_directory_file_ofs = 0;
+
+ /* Clear the sorted central dir offsets, they aren't useful or maintained now. */
+ /* Even though we're now in write mode, files can still be extracted and verified, but file locates will be slow. */
+ /* TODO: We could easily maintain the sorted central directory offsets. */
+ mz_zip_array_clear(pZip, &pZip->m_pState->m_sorted_central_dir_offsets);
+
+ pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename)
+{
+ return mz_zip_writer_init_from_reader_v2(pZip, pFilename, 0);
+}
+
+/* TODO: pArchive_name is a terrible name here! */
+mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags)
+{
+ return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0);
+}
+
+typedef struct
+{
+ mz_zip_archive *m_pZip;
+ mz_uint64 m_cur_archive_file_ofs;
+ mz_uint64 m_comp_size;
+} mz_zip_writer_add_state;
+
+static mz_bool mz_zip_writer_add_put_buf_callback(const void *pBuf, int len, void *pUser)
+{
+ mz_zip_writer_add_state *pState = (mz_zip_writer_add_state *)pUser;
+ if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len)
+ return MZ_FALSE;
+
+ pState->m_cur_archive_file_ofs += len;
+ pState->m_comp_size += len;
+ return MZ_TRUE;
+}
+
+#define MZ_ZIP64_MAX_LOCAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 2)
+#define MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 3)
+static mz_uint32 mz_zip_writer_create_zip64_extra_data(mz_uint8 *pBuf, mz_uint64 *pUncomp_size, mz_uint64 *pComp_size, mz_uint64 *pLocal_header_ofs)
+{
+ mz_uint8 *pDst = pBuf;
+ mz_uint32 field_size = 0;
+
+ MZ_WRITE_LE16(pDst + 0, MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID);
+ MZ_WRITE_LE16(pDst + 2, 0);
+ pDst += sizeof(mz_uint16) * 2;
+
+ if (pUncomp_size)
+ {
+ MZ_WRITE_LE64(pDst, *pUncomp_size);
+ pDst += sizeof(mz_uint64);
+ field_size += sizeof(mz_uint64);
+ }
+
+ if (pComp_size)
+ {
+ MZ_WRITE_LE64(pDst, *pComp_size);
+ pDst += sizeof(mz_uint64);
+ field_size += sizeof(mz_uint64);
+ }
+
+ if (pLocal_header_ofs)
+ {
+ MZ_WRITE_LE64(pDst, *pLocal_header_ofs);
+ pDst += sizeof(mz_uint64);
+ field_size += sizeof(mz_uint64);
+ }
+
+ MZ_WRITE_LE16(pBuf + 2, field_size);
+
+ return (mz_uint32)(pDst - pBuf);
+}
+
+static mz_bool mz_zip_writer_create_local_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date)
+{
+ (void)pZip;
+ memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, MZ_MIN(comp_size, MZ_UINT32_MAX));
+ MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, MZ_MIN(uncomp_size, MZ_UINT32_MAX));
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size);
+ return MZ_TRUE;
+}
+
+static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst,
+ mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size,
+ mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32,
+ mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date,
+ mz_uint64 local_header_ofs, mz_uint32 ext_attributes)
+{
+ (void)pZip;
+ memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, MZ_MIN(comp_size, MZ_UINT32_MAX));
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, MZ_MIN(uncomp_size, MZ_UINT32_MAX));
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, MZ_MIN(local_header_ofs, MZ_UINT32_MAX));
+ return MZ_TRUE;
+}
+
+static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size,
+ const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size,
+ mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32,
+ mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date,
+ mz_uint64 local_header_ofs, mz_uint32 ext_attributes,
+ const char *user_extra_data, mz_uint user_extra_data_len)
+{
+ mz_zip_internal_state *pState = pZip->m_pState;
+ mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size;
+ size_t orig_central_dir_size = pState->m_central_dir.m_size;
+ mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
+
+ if (!pZip->m_pState->m_zip64)
+ {
+ if (local_header_ofs > 0xFFFFFFFF)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE);
+ }
+
+ /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */
+ if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + user_extra_data_len + comment_size) >= MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
+
+ if (!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, (mz_uint16)(extra_size + user_extra_data_len), comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes))
+ return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
+
+ if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) ||
+ (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) ||
+ (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) ||
+ (!mz_zip_array_push_back(pZip, &pState->m_central_dir, user_extra_data, user_extra_data_len)) ||
+ (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) ||
+ (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &central_dir_ofs, 1)))
+ {
+ /* Try to resize the central directory array back into its original state. */
+ mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+
+ return MZ_TRUE;
+}
+
+static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name)
+{
+ /* Basic ZIP archive filename validity checks: Valid filenames cannot start with a forward slash, cannot contain a drive letter, and cannot use DOS-style backward slashes. */
+ if (*pArchive_name == '/')
+ return MZ_FALSE;
+
+ /* Making sure the name does not contain drive letters or DOS style backward slashes is the responsibility of the program using miniz*/
+
+ return MZ_TRUE;
+}
+
+static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip)
+{
+ mz_uint32 n;
+ if (!pZip->m_file_offset_alignment)
+ return 0;
+ n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
+ return (mz_uint)((pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1));
+}
+
+static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_file_ofs, mz_uint32 n)
+{
+ char buf[4096];
+ memset(buf, 0, MZ_MIN(sizeof(buf), n));
+ while (n)
+ {
+ mz_uint32 s = MZ_MIN(sizeof(buf), n);
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ cur_file_ofs += s;
+ n -= s;
+ }
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
+ mz_uint64 uncomp_size, mz_uint32 uncomp_crc32)
+{
+ return mz_zip_writer_add_mem_ex_v2(pZip, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, uncomp_size, uncomp_crc32, NULL, NULL, 0, NULL, 0);
+}
+
+mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size,
+ mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified,
+ const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len)
+{
+ mz_uint16 method = 0, dos_time = 0, dos_date = 0;
+ mz_uint level, ext_attributes = 0, num_alignment_padding_bytes;
+ mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0;
+ size_t archive_name_size;
+ mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
+ tdefl_compressor *pComp = NULL;
+ mz_bool store_data_uncompressed;
+ mz_zip_internal_state *pState;
+ mz_uint8 *pExtra_data = NULL;
+ mz_uint32 extra_size = 0;
+ mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE];
+ mz_uint16 bit_flags = 0;
+
+ if ((int)level_and_flags < 0)
+ level_and_flags = MZ_DEFAULT_LEVEL;
+
+ if (uncomp_size || (buf_size && !(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
+ bit_flags |= MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR;
+
+ if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
+ bit_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8;
+
+ level = level_and_flags & 0xF;
+ store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA));
+
+ if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ pState = pZip->m_pState;
+
+ if (pState->m_zip64)
+ {
+ if (pZip->m_total_files == MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
+ }
+ else
+ {
+ if (pZip->m_total_files == MZ_UINT16_MAX)
+ {
+ pState->m_zip64 = MZ_TRUE;
+ /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */
+ }
+ if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF))
+ {
+ pState->m_zip64 = MZ_TRUE;
+ /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
+ }
+ }
+
+ if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ if (!mz_zip_writer_validate_archive_name(pArchive_name))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);
+
+#ifndef MINIZ_NO_TIME
+ if (last_modified != NULL)
+ {
+ mz_zip_time_t_to_dos_time(*last_modified, &dos_time, &dos_date);
+ }
+ else
+ {
+ MZ_TIME_T cur_time;
+ time(&cur_time);
+ mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date);
+ }
+#endif /* #ifndef MINIZ_NO_TIME */
+
+ if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
+ {
+ uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size);
+ uncomp_size = buf_size;
+ if (uncomp_size <= 3)
+ {
+ level = 0;
+ store_data_uncompressed = MZ_TRUE;
+ }
+ }
+
+ archive_name_size = strlen(pArchive_name);
+ if (archive_name_size > MZ_UINT16_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);
+
+ num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
+
+ /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */
+ if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE + comment_size) >= MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
+
+ if (!pState->m_zip64)
+ {
+ /* Bail early if the archive would obviously become too large */
+ if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size
+ + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len +
+ pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len
+ + MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF)
+ {
+ pState->m_zip64 = MZ_TRUE;
+ /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
+ }
+ }
+
+ if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/'))
+ {
+ /* Set DOS Subdirectory attribute bit. */
+ ext_attributes |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG;
+
+ /* Subdirectories cannot contain data. */
+ if ((buf_size) || (uncomp_size))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+ }
+
+ /* Try to do any allocations before writing to the archive, so if an allocation fails the file remains unmodified. (A good idea if we're doing an in-place modification.) */
+ if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + (pState->m_zip64 ? MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE : 0))) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1)))
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+
+ if ((!store_data_uncompressed) && (buf_size))
+ {
+ if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor))))
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+
+ if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes))
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ return MZ_FALSE;
+ }
+
+ local_dir_header_ofs += num_alignment_padding_bytes;
+ if (pZip->m_file_offset_alignment)
+ {
+ MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
+ }
+ cur_archive_file_ofs += num_alignment_padding_bytes;
+
+ MZ_CLEAR_OBJ(local_dir_header);
+
+ if (!store_data_uncompressed || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
+ {
+ method = MZ_DEFLATED;
+ }
+
+ if (pState->m_zip64)
+ {
+ if (uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX)
+ {
+ pExtra_data = extra_data;
+ extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
+ (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
+ }
+
+ if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len), 0, 0, 0, method, bit_flags, dos_time, dos_date))
+ return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ cur_archive_file_ofs += sizeof(local_dir_header);
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+ }
+ cur_archive_file_ofs += archive_name_size;
+
+ if (pExtra_data != NULL)
+ {
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ cur_archive_file_ofs += extra_size;
+ }
+ }
+ else
+ {
+ if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX))
+ return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
+ if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)user_extra_data_len, 0, 0, 0, method, bit_flags, dos_time, dos_date))
+ return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ cur_archive_file_ofs += sizeof(local_dir_header);
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+ }
+ cur_archive_file_ofs += archive_name_size;
+ }
+
+ if (user_extra_data_len > 0)
+ {
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ cur_archive_file_ofs += user_extra_data_len;
+ }
+
+ if (store_data_uncompressed)
+ {
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+ }
+
+ cur_archive_file_ofs += buf_size;
+ comp_size = buf_size;
+ }
+ else if (buf_size)
+ {
+ mz_zip_writer_add_state state;
+
+ state.m_pZip = pZip;
+ state.m_cur_archive_file_ofs = cur_archive_file_ofs;
+ state.m_comp_size = 0;
+
+ if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) ||
+ (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE))
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ return mz_zip_set_error(pZip, MZ_ZIP_COMPRESSION_FAILED);
+ }
+
+ comp_size = state.m_comp_size;
+ cur_archive_file_ofs = state.m_cur_archive_file_ofs;
+ }
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ pComp = NULL;
+
+ if (uncomp_size)
+ {
+ mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64];
+ mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32;
+
+ MZ_ASSERT(bit_flags & MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR);
+
+ MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID);
+ MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32);
+ if (pExtra_data == NULL)
+ {
+ if (comp_size > MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
+
+ MZ_WRITE_LE32(local_dir_footer + 8, comp_size);
+ MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size);
+ }
+ else
+ {
+ MZ_WRITE_LE64(local_dir_footer + 8, comp_size);
+ MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size);
+ local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64;
+ }
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size)
+ return MZ_FALSE;
+
+ cur_archive_file_ofs += local_dir_footer_size;
+ }
+
+ if (pExtra_data != NULL)
+ {
+ extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
+ (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
+ }
+
+ if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, (mz_uint16)extra_size, pComment,
+ comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes,
+ user_extra_data_central, user_extra_data_central_len))
+ return MZ_FALSE;
+
+ pZip->m_total_files++;
+ pZip->m_archive_size = cur_archive_file_ofs;
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
+ const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len)
+{
+ mz_uint16 gen_flags = (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) ? 0 : MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR;
+ mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
+ mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0;
+ mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0;
+ size_t archive_name_size;
+ mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
+ mz_uint8 *pExtra_data = NULL;
+ mz_uint32 extra_size = 0;
+ mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE];
+ mz_zip_internal_state *pState;
+ mz_uint64 file_ofs = 0, cur_archive_header_file_ofs;
+
+ if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
+ gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8;
+
+ if ((int)level_and_flags < 0)
+ level_and_flags = MZ_DEFAULT_LEVEL;
+ level = level_and_flags & 0xF;
+
+ /* Sanity checks */
+ if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ pState = pZip->m_pState;
+
+ if ((!pState->m_zip64) && (max_size > MZ_UINT32_MAX))
+ {
+ /* Source file is too large for non-zip64 */
+ /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
+ pState->m_zip64 = MZ_TRUE;
+ }
+
+ /* We could support this, but why? */
+ if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ if (!mz_zip_writer_validate_archive_name(pArchive_name))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);
+
+ if (pState->m_zip64)
+ {
+ if (pZip->m_total_files == MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
+ }
+ else
+ {
+ if (pZip->m_total_files == MZ_UINT16_MAX)
+ {
+ pState->m_zip64 = MZ_TRUE;
+ /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */
+ }
+ }
+
+ archive_name_size = strlen(pArchive_name);
+ if (archive_name_size > MZ_UINT16_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);
+
+ num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
+
+ /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */
+ if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE + comment_size) >= MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
+
+ if (!pState->m_zip64)
+ {
+ /* Bail early if the archive would obviously become too large */
+ if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE
+ + archive_name_size + comment_size + user_extra_data_len + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024
+ + MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > 0xFFFFFFFF)
+ {
+ pState->m_zip64 = MZ_TRUE;
+ /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
+ }
+ }
+
+#ifndef MINIZ_NO_TIME
+ if (pFile_time)
+ {
+ mz_zip_time_t_to_dos_time(*pFile_time, &dos_time, &dos_date);
+ }
+#endif
+
+ if (max_size <= 3)
+ level = 0;
+
+ if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes))
+ {
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+ }
+
+ cur_archive_file_ofs += num_alignment_padding_bytes;
+ local_dir_header_ofs = cur_archive_file_ofs;
+
+ if (pZip->m_file_offset_alignment)
+ {
+ MZ_ASSERT((cur_archive_file_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
+ }
+
+ if (max_size && level)
+ {
+ method = MZ_DEFLATED;
+ }
+
+ MZ_CLEAR_OBJ(local_dir_header);
+ if (pState->m_zip64)
+ {
+ if (max_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX)
+ {
+ pExtra_data = extra_data;
+ if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE)
+ extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
+ (max_size >= MZ_UINT32_MAX) ? &comp_size : NULL,
+ (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
+ else
+ extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, NULL,
+ NULL,
+ (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
+ }
+
+ if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len), 0, 0, 0, method, gen_flags, dos_time, dos_date))
+ return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ cur_archive_file_ofs += sizeof(local_dir_header);
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
+ {
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+ }
+
+ cur_archive_file_ofs += archive_name_size;
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ cur_archive_file_ofs += extra_size;
+ }
+ else
+ {
+ if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX))
+ return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
+ if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)user_extra_data_len, 0, 0, 0, method, gen_flags, dos_time, dos_date))
+ return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ cur_archive_file_ofs += sizeof(local_dir_header);
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
+ {
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+ }
+
+ cur_archive_file_ofs += archive_name_size;
+ }
+
+ if (user_extra_data_len > 0)
+ {
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ cur_archive_file_ofs += user_extra_data_len;
+ }
+
+ if (max_size)
+ {
+ void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE);
+ if (!pRead_buf)
+ {
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+
+ if (!level)
+ {
+ while (1)
+ {
+ size_t n = read_callback(callback_opaque, file_ofs, pRead_buf, MZ_ZIP_MAX_IO_BUF_SIZE);
+ if (n == 0)
+ break;
+
+ if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size))
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+ }
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+ }
+ file_ofs += n;
+ uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
+ cur_archive_file_ofs += n;
+ }
+ uncomp_size = file_ofs;
+ comp_size = uncomp_size;
+ }
+ else
+ {
+ mz_bool result = MZ_FALSE;
+ mz_zip_writer_add_state state;
+ tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor));
+ if (!pComp)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+
+ state.m_pZip = pZip;
+ state.m_cur_archive_file_ofs = cur_archive_file_ofs;
+ state.m_comp_size = 0;
+
+ if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
+ }
+
+ for (;;)
+ {
+ tdefl_status status;
+ tdefl_flush flush = TDEFL_NO_FLUSH;
+
+ size_t n = read_callback(callback_opaque, file_ofs, pRead_buf, MZ_ZIP_MAX_IO_BUF_SIZE);
+ if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size))
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+ break;
+ }
+
+ file_ofs += n;
+ uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
+
+ if (pZip->m_pNeeds_keepalive != NULL && pZip->m_pNeeds_keepalive(pZip->m_pIO_opaque))
+ flush = TDEFL_FULL_FLUSH;
+
+ if (n == 0)
+ flush = TDEFL_FINISH;
+
+ status = tdefl_compress_buffer(pComp, pRead_buf, n, flush);
+ if (status == TDEFL_STATUS_DONE)
+ {
+ result = MZ_TRUE;
+ break;
+ }
+ else if (status != TDEFL_STATUS_OKAY)
+ {
+ mz_zip_set_error(pZip, MZ_ZIP_COMPRESSION_FAILED);
+ break;
+ }
+ }
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+
+ if (!result)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ return MZ_FALSE;
+ }
+
+ uncomp_size = file_ofs;
+ comp_size = state.m_comp_size;
+ cur_archive_file_ofs = state.m_cur_archive_file_ofs;
+ }
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ }
+
+ if (!(level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE))
+ {
+ mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64];
+ mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32;
+
+ MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID);
+ MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32);
+ if (pExtra_data == NULL)
+ {
+ if (comp_size > MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
+
+ MZ_WRITE_LE32(local_dir_footer + 8, comp_size);
+ MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size);
+ }
+ else
+ {
+ MZ_WRITE_LE64(local_dir_footer + 8, comp_size);
+ MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size);
+ local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64;
+ }
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size)
+ return MZ_FALSE;
+
+ cur_archive_file_ofs += local_dir_footer_size;
+ }
+
+ if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE)
+ {
+ if (pExtra_data != NULL)
+ {
+ extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
+ (max_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
+ }
+
+ if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header,
+ (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len),
+ (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : uncomp_size,
+ (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : comp_size,
+ uncomp_crc32, method, gen_flags, dos_time, dos_date))
+ return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
+
+ cur_archive_header_file_ofs = local_dir_header_ofs;
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ if (pExtra_data != NULL)
+ {
+ cur_archive_header_file_ofs += sizeof(local_dir_header);
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
+ {
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+ }
+
+ cur_archive_header_file_ofs += archive_name_size;
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, extra_data, extra_size) != extra_size)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ cur_archive_header_file_ofs += extra_size;
+ }
+ }
+
+ if (pExtra_data != NULL)
+ {
+ extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
+ (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
+ }
+
+ if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, (mz_uint16)extra_size, pComment, comment_size,
+ uncomp_size, comp_size, uncomp_crc32, method, gen_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes,
+ user_extra_data_central, user_extra_data_central_len))
+ return MZ_FALSE;
+
+ pZip->m_total_files++;
+ pZip->m_archive_size = cur_archive_file_ofs;
+
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_STDIO
+
+static size_t mz_file_read_func_stdio(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
+{
+ MZ_FILE *pSrc_file = (MZ_FILE *)pOpaque;
+ mz_int64 cur_ofs = MZ_FTELL64(pSrc_file);
+
+ if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pSrc_file, (mz_int64)file_ofs, SEEK_SET))))
+ return 0;
+
+ return MZ_FREAD(pBuf, 1, n, pSrc_file);
+}
+
+mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
+ const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len)
+{
+ return mz_zip_writer_add_read_buf_callback(pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, max_size, pFile_time, pComment, comment_size, level_and_flags,
+ user_extra_data, user_extra_data_len, user_extra_data_central, user_extra_data_central_len);
+}
+
+mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
+{
+ MZ_FILE *pSrc_file = NULL;
+ mz_uint64 uncomp_size = 0;
+ MZ_TIME_T file_modified_time;
+ MZ_TIME_T *pFile_time = NULL;
+ mz_bool status;
+
+ memset(&file_modified_time, 0, sizeof(file_modified_time));
+
+#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO)
+ pFile_time = &file_modified_time;
+ if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time))
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_STAT_FAILED);
+#endif
+
+ pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
+ if (!pSrc_file)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
+
+ MZ_FSEEK64(pSrc_file, 0, SEEK_END);
+ uncomp_size = MZ_FTELL64(pSrc_file);
+ MZ_FSEEK64(pSrc_file, 0, SEEK_SET);
+
+ status = mz_zip_writer_add_cfile(pZip, pArchive_name, pSrc_file, uncomp_size, pFile_time, pComment, comment_size, level_and_flags, NULL, 0, NULL, 0);
+
+ MZ_FCLOSE(pSrc_file);
+
+ return status;
+}
+#endif /* #ifndef MINIZ_NO_STDIO */
+
+static mz_bool mz_zip_writer_update_zip64_extension_block(mz_zip_array *pNew_ext, mz_zip_archive *pZip, const mz_uint8 *pExt, uint32_t ext_len, mz_uint64 *pComp_size, mz_uint64 *pUncomp_size, mz_uint64 *pLocal_header_ofs, mz_uint32 *pDisk_start)
+{
+ /* + 64 should be enough for any new zip64 data */
+ if (!mz_zip_array_reserve(pZip, pNew_ext, ext_len + 64, MZ_FALSE))
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+
+ mz_zip_array_resize(pZip, pNew_ext, 0, MZ_FALSE);
+
+ if ((pUncomp_size) || (pComp_size) || (pLocal_header_ofs) || (pDisk_start))
+ {
+ mz_uint8 new_ext_block[64];
+ mz_uint8 *pDst = new_ext_block;
+ mz_write_le16(pDst, MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID);
+ mz_write_le16(pDst + sizeof(mz_uint16), 0);
+ pDst += sizeof(mz_uint16) * 2;
+
+ if (pUncomp_size)
+ {
+ mz_write_le64(pDst, *pUncomp_size);
+ pDst += sizeof(mz_uint64);
+ }
+
+ if (pComp_size)
+ {
+ mz_write_le64(pDst, *pComp_size);
+ pDst += sizeof(mz_uint64);
+ }
+
+ if (pLocal_header_ofs)
+ {
+ mz_write_le64(pDst, *pLocal_header_ofs);
+ pDst += sizeof(mz_uint64);
+ }
+
+ if (pDisk_start)
+ {
+ mz_write_le32(pDst, *pDisk_start);
+ pDst += sizeof(mz_uint32);
+ }
+
+ mz_write_le16(new_ext_block + sizeof(mz_uint16), (mz_uint16)((pDst - new_ext_block) - sizeof(mz_uint16) * 2));
+
+ if (!mz_zip_array_push_back(pZip, pNew_ext, new_ext_block, pDst - new_ext_block))
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+
+ if ((pExt) && (ext_len))
+ {
+ mz_uint32 extra_size_remaining = ext_len;
+ const mz_uint8 *pExtra_data = pExt;
+
+ do
+ {
+ mz_uint32 field_id, field_data_size, field_total_size;
+
+ if (extra_size_remaining < (sizeof(mz_uint16) * 2))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ field_id = MZ_READ_LE16(pExtra_data);
+ field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
+ field_total_size = field_data_size + sizeof(mz_uint16) * 2;
+
+ if (field_total_size > extra_size_remaining)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ if (field_id != MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
+ {
+ if (!mz_zip_array_push_back(pZip, pNew_ext, pExtra_data, field_total_size))
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+
+ pExtra_data += field_total_size;
+ extra_size_remaining -= field_total_size;
+ } while (extra_size_remaining);
+ }
+
+ return MZ_TRUE;
+}
+
+/* TODO: This func is now pretty freakin complex due to zip64, split it up? */
+mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index)
+{
+ mz_uint n, bit_flags, num_alignment_padding_bytes, src_central_dir_following_data_size;
+ mz_uint64 src_archive_bytes_remaining, local_dir_header_ofs;
+ mz_uint64 cur_src_file_ofs, cur_dst_file_ofs;
+ mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
+ mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
+ mz_uint8 new_central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
+ size_t orig_central_dir_size;
+ mz_zip_internal_state *pState;
+ void *pBuf;
+ const mz_uint8 *pSrc_central_header;
+ mz_zip_archive_file_stat src_file_stat;
+ mz_uint32 src_filename_len, src_comment_len, src_ext_len;
+ mz_uint32 local_header_filename_size, local_header_extra_len;
+ mz_uint64 local_header_comp_size, local_header_uncomp_size;
+ mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE;
+
+ /* Sanity checks */
+ if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pSource_zip->m_pRead))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ pState = pZip->m_pState;
+
+ /* Don't support copying files from zip64 archives to non-zip64, even though in some cases this is possible */
+ if ((pSource_zip->m_pState->m_zip64) && (!pZip->m_pState->m_zip64))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ /* Get pointer to the source central dir header and crack it */
+ if (NULL == (pSrc_central_header = mz_zip_get_cdh(pSource_zip, src_file_index)))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ if (MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_SIG_OFS) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ src_filename_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ src_comment_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS);
+ src_ext_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS);
+ src_central_dir_following_data_size = src_filename_len + src_ext_len + src_comment_len;
+
+ /* TODO: We don't support central dir's >= MZ_UINT32_MAX bytes right now (+32 fudge factor in case we need to add more extra data) */
+ if ((pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_central_dir_following_data_size + 32) >= MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
+
+ num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
+
+ if (!pState->m_zip64)
+ {
+ if (pZip->m_total_files == MZ_UINT16_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
+ }
+ else
+ {
+ /* TODO: Our zip64 support still has some 32-bit limits that may not be worth fixing. */
+ if (pZip->m_total_files == MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
+ }
+
+ if (!mz_zip_file_stat_internal(pSource_zip, src_file_index, pSrc_central_header, &src_file_stat, NULL))
+ return MZ_FALSE;
+
+ cur_src_file_ofs = src_file_stat.m_local_header_ofs;
+ cur_dst_file_ofs = pZip->m_archive_size;
+
+ /* Read the source archive's local dir header */
+ if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+
+ if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+
+ cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
+
+ /* Compute the total size we need to copy (filename+extra data+compressed data) */
+ local_header_filename_size = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS);
+ local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
+ local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS);
+ local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS);
+ src_archive_bytes_remaining = local_header_filename_size + local_header_extra_len + src_file_stat.m_comp_size;
+
+ /* Try to find a zip64 extended information field */
+ if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
+ {
+ mz_zip_array file_data_array;
+ const mz_uint8 *pExtra_data;
+ mz_uint32 extra_size_remaining = local_header_extra_len;
+
+ mz_zip_array_init(&file_data_array, 1);
+ if (!mz_zip_array_resize(pZip, &file_data_array, local_header_extra_len, MZ_FALSE))
+ {
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+
+ if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, src_file_stat.m_local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_size, file_data_array.m_p, local_header_extra_len) != local_header_extra_len)
+ {
+ mz_zip_array_clear(pZip, &file_data_array);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+ }
+
+ pExtra_data = (const mz_uint8 *)file_data_array.m_p;
+
+ do
+ {
+ mz_uint32 field_id, field_data_size, field_total_size;
+
+ if (extra_size_remaining < (sizeof(mz_uint16) * 2))
+ {
+ mz_zip_array_clear(pZip, &file_data_array);
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+ }
+
+ field_id = MZ_READ_LE16(pExtra_data);
+ field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
+ field_total_size = field_data_size + sizeof(mz_uint16) * 2;
+
+ if (field_total_size > extra_size_remaining)
+ {
+ mz_zip_array_clear(pZip, &file_data_array);
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+ }
+
+ if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
+ {
+ const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32);
+
+ if (field_data_size < sizeof(mz_uint64) * 2)
+ {
+ mz_zip_array_clear(pZip, &file_data_array);
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
+ }
+
+ local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data);
+ local_header_comp_size = MZ_READ_LE64(pSrc_field_data + sizeof(mz_uint64)); /* may be 0 if there's a descriptor */
+
+ found_zip64_ext_data_in_ldir = MZ_TRUE;
+ break;
+ }
+
+ pExtra_data += field_total_size;
+ extra_size_remaining -= field_total_size;
+ } while (extra_size_remaining);
+
+ mz_zip_array_clear(pZip, &file_data_array);
+ }
+
+ if (!pState->m_zip64)
+ {
+ /* Try to detect if the new archive will most likely wind up too big and bail early (+(sizeof(mz_uint32) * 4) is for the optional descriptor which could be present, +64 is a fudge factor). */
+ /* We also check when the archive is finalized so this doesn't need to be perfect. */
+ mz_uint64 approx_new_archive_size = cur_dst_file_ofs + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + src_archive_bytes_remaining + (sizeof(mz_uint32) * 4) +
+ pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_central_dir_following_data_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 64;
+
+ if (approx_new_archive_size >= MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
+ }
+
+ /* Write dest archive padding */
+ if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, num_alignment_padding_bytes))
+ return MZ_FALSE;
+
+ cur_dst_file_ofs += num_alignment_padding_bytes;
+
+ local_dir_header_ofs = cur_dst_file_ofs;
+ if (pZip->m_file_offset_alignment)
+ {
+ MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
+ }
+
+ /* The original zip's local header+ext block doesn't change, even with zip64, so we can just copy it over to the dest zip */
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
+
+ /* Copy over the source archive bytes to the dest archive, also ensure we have enough buf space to handle optional data descriptor */
+ if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)MZ_MAX(32U, MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, src_archive_bytes_remaining)))))
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+
+ while (src_archive_bytes_remaining)
+ {
+ n = (mz_uint)MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, src_archive_bytes_remaining);
+ if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+ }
+ cur_src_file_ofs += n;
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+ }
+ cur_dst_file_ofs += n;
+
+ src_archive_bytes_remaining -= n;
+ }
+
+ /* Now deal with the optional data descriptor */
+ bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
+ if (bit_flags & 8)
+ {
+ /* Copy data descriptor */
+ if ((pSource_zip->m_pState->m_zip64) || (found_zip64_ext_data_in_ldir))
+ {
+ /* src is zip64, dest must be zip64 */
+
+ /* name uint32_t's */
+ /* id 1 (optional in zip64?) */
+ /* crc 1 */
+ /* comp_size 2 */
+ /* uncomp_size 2 */
+ if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, (sizeof(mz_uint32) * 6)) != (sizeof(mz_uint32) * 6))
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+ }
+
+ n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID) ? 6 : 5);
+ }
+ else
+ {
+ /* src is NOT zip64 */
+ mz_bool has_id;
+
+ if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
+ }
+
+ has_id = (MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID);
+
+ if (pZip->m_pState->m_zip64)
+ {
+ /* dest is zip64, so upgrade the data descriptor */
+ const mz_uint32 *pSrc_descriptor = (const mz_uint32 *)((const mz_uint8 *)pBuf + (has_id ? sizeof(mz_uint32) : 0));
+ const mz_uint32 src_crc32 = pSrc_descriptor[0];
+ const mz_uint64 src_comp_size = pSrc_descriptor[1];
+ const mz_uint64 src_uncomp_size = pSrc_descriptor[2];
+
+ mz_write_le32((mz_uint8 *)pBuf, MZ_ZIP_DATA_DESCRIPTOR_ID);
+ mz_write_le32((mz_uint8 *)pBuf + sizeof(mz_uint32) * 1, src_crc32);
+ mz_write_le64((mz_uint8 *)pBuf + sizeof(mz_uint32) * 2, src_comp_size);
+ mz_write_le64((mz_uint8 *)pBuf + sizeof(mz_uint32) * 4, src_uncomp_size);
+
+ n = sizeof(mz_uint32) * 6;
+ }
+ else
+ {
+ /* dest is NOT zip64, just copy it as-is */
+ n = sizeof(mz_uint32) * (has_id ? 4 : 3);
+ }
+ }
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
+ {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+ }
+
+ cur_src_file_ofs += n;
+ cur_dst_file_ofs += n;
+ }
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+
+ /* Finally, add the new central dir header */
+ orig_central_dir_size = pState->m_central_dir.m_size;
+
+ memcpy(new_central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
+
+ if (pState->m_zip64)
+ {
+ /* This is the painful part: We need to write a new central dir header + ext block with updated zip64 fields, and ensure the old fields (if any) are not included. */
+ const mz_uint8 *pSrc_ext = pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_filename_len;
+ mz_zip_array new_ext_block;
+
+ mz_zip_array_init(&new_ext_block, sizeof(mz_uint8));
+
+ MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, MZ_UINT32_MAX);
+ MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, MZ_UINT32_MAX);
+ MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, MZ_UINT32_MAX);
+
+ if (!mz_zip_writer_update_zip64_extension_block(&new_ext_block, pZip, pSrc_ext, src_ext_len, &src_file_stat.m_comp_size, &src_file_stat.m_uncomp_size, &local_dir_header_ofs, NULL))
+ {
+ mz_zip_array_clear(pZip, &new_ext_block);
+ return MZ_FALSE;
+ }
+
+ MZ_WRITE_LE16(new_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS, new_ext_block.m_size);
+
+ if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
+ {
+ mz_zip_array_clear(pZip, &new_ext_block);
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+
+ if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, src_filename_len))
+ {
+ mz_zip_array_clear(pZip, &new_ext_block);
+ mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+
+ if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_ext_block.m_p, new_ext_block.m_size))
+ {
+ mz_zip_array_clear(pZip, &new_ext_block);
+ mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+
+ if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_filename_len + src_ext_len, src_comment_len))
+ {
+ mz_zip_array_clear(pZip, &new_ext_block);
+ mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+
+ mz_zip_array_clear(pZip, &new_ext_block);
+ }
+ else
+ {
+ /* sanity checks */
+ if (cur_dst_file_ofs > MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
+
+ if (local_dir_header_ofs >= MZ_UINT32_MAX)
+ return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
+
+ MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_dir_header_ofs);
+
+ if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+
+ if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, src_central_dir_following_data_size))
+ {
+ mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+ }
+
+ /* This shouldn't trigger unless we screwed up during the initial sanity checks */
+ if (pState->m_central_dir.m_size >= MZ_UINT32_MAX)
+ {
+ /* TODO: Support central dirs >= 32-bits in size */
+ mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
+ return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
+ }
+
+ n = (mz_uint32)orig_central_dir_size;
+ if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1))
+ {
+ mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
+ return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
+ }
+
+ pZip->m_total_files++;
+ pZip->m_archive_size = cur_dst_file_ofs;
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip)
+{
+ mz_zip_internal_state *pState;
+ mz_uint64 central_dir_ofs, central_dir_size;
+ mz_uint8 hdr[256];
+
+ if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ pState = pZip->m_pState;
+
+ if (pState->m_zip64)
+ {
+ if ((pZip->m_total_files > MZ_UINT32_MAX) || (pState->m_central_dir.m_size >= MZ_UINT32_MAX))
+ return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
+ }
+ else
+ {
+ if ((pZip->m_total_files > MZ_UINT16_MAX) || ((pZip->m_archive_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX))
+ return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
+ }
+
+ central_dir_ofs = 0;
+ central_dir_size = 0;
+ if (pZip->m_total_files)
+ {
+ /* Write central directory */
+ central_dir_ofs = pZip->m_archive_size;
+ central_dir_size = pState->m_central_dir.m_size;
+ pZip->m_central_directory_file_ofs = central_dir_ofs;
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs, pState->m_central_dir.m_p, (size_t)central_dir_size) != central_dir_size)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ pZip->m_archive_size += central_dir_size;
+ }
+
+ if (pState->m_zip64)
+ {
+ /* Write zip64 end of central directory header */
+ mz_uint64 rel_ofs_to_zip64_ecdr = pZip->m_archive_size;
+
+ MZ_CLEAR_OBJ(hdr);
+ MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDH_SIG_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG);
+ MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - sizeof(mz_uint32) - sizeof(mz_uint64));
+ MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS, 0x031E); /* TODO: always Unix */
+ MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_NEEDED_OFS, 0x002D);
+ MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, pZip->m_total_files);
+ MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS, pZip->m_total_files);
+ MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_SIZE_OFS, central_dir_size);
+ MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_OFS_OFS, central_dir_ofs);
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE;
+
+ /* Write zip64 end of central directory locator */
+ MZ_CLEAR_OBJ(hdr);
+ MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_SIG_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG);
+ MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS, rel_ofs_to_zip64_ecdr);
+ MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS, 1);
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) != MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+ pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE;
+ }
+
+ /* Write end of central directory record */
+ MZ_CLEAR_OBJ(hdr);
+ MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG);
+ MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files));
+ MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files));
+ MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, MZ_MIN(MZ_UINT32_MAX, central_dir_size));
+ MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, MZ_MIN(MZ_UINT32_MAX, central_dir_ofs));
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
+
+#ifndef MINIZ_NO_STDIO
+ if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF))
+ return mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED);
+#endif /* #ifndef MINIZ_NO_STDIO */
+
+ pZip->m_archive_size += MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE;
+
+ pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED;
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize)
+{
+ if ((!ppBuf) || (!pSize))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ *ppBuf = NULL;
+ *pSize = 0;
+
+ if ((!pZip) || (!pZip->m_pState))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ if (pZip->m_pWrite != mz_zip_heap_write_func)
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ if (!mz_zip_writer_finalize_archive(pZip))
+ return MZ_FALSE;
+
+ *ppBuf = pZip->m_pState->m_pMem;
+ *pSize = pZip->m_pState->m_mem_size;
+ pZip->m_pState->m_pMem = NULL;
+ pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0;
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_end(mz_zip_archive *pZip)
+{
+ return mz_zip_writer_end_internal(pZip, MZ_TRUE);
+}
+
+#ifndef MINIZ_NO_STDIO
+mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
+{
+ return mz_zip_add_mem_to_archive_file_in_place_v2(pZip_filename, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, NULL);
+}
+
+mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr)
+{
+ mz_bool status, created_new_archive = MZ_FALSE;
+ mz_zip_archive zip_archive;
+ struct MZ_FILE_STAT_STRUCT file_stat;
+ mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
+
+ mz_zip_zero_struct(&zip_archive);
+ if ((int)level_and_flags < 0)
+ level_and_flags = MZ_DEFAULT_LEVEL;
+
+ if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION))
+ {
+ if (pErr)
+ *pErr = MZ_ZIP_INVALID_PARAMETER;
+ return MZ_FALSE;
+ }
+
+ if (!mz_zip_writer_validate_archive_name(pArchive_name))
+ {
+ if (pErr)
+ *pErr = MZ_ZIP_INVALID_FILENAME;
+ return MZ_FALSE;
+ }
+
+ /* Important: The regular non-64 bit version of stat() can fail here if the file is very large, which could cause the archive to be overwritten. */
+ /* So be sure to compile with _LARGEFILE64_SOURCE 1 */
+ if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0)
+ {
+ /* Create a new archive. */
+ if (!mz_zip_writer_init_file_v2(&zip_archive, pZip_filename, 0, level_and_flags))
+ {
+ if (pErr)
+ *pErr = zip_archive.m_last_error;
+ return MZ_FALSE;
+ }
+
+ created_new_archive = MZ_TRUE;
+ }
+ else
+ {
+ /* Append to an existing archive. */
+ if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0))
+ {
+ if (pErr)
+ *pErr = zip_archive.m_last_error;
+ return MZ_FALSE;
+ }
+
+ if (!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename, level_and_flags))
+ {
+ if (pErr)
+ *pErr = zip_archive.m_last_error;
+
+ mz_zip_reader_end_internal(&zip_archive, MZ_FALSE);
+
+ return MZ_FALSE;
+ }
+ }
+
+ status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0);
+ actual_err = zip_archive.m_last_error;
+
+ /* Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.) */
+ if (!mz_zip_writer_finalize_archive(&zip_archive))
+ {
+ if (!actual_err)
+ actual_err = zip_archive.m_last_error;
+
+ status = MZ_FALSE;
+ }
+
+ if (!mz_zip_writer_end_internal(&zip_archive, status))
+ {
+ if (!actual_err)
+ actual_err = zip_archive.m_last_error;
+
+ status = MZ_FALSE;
+ }
+
+ if ((!status) && (created_new_archive))
+ {
+ /* It's a new archive and something went wrong, so just delete it. */
+ int ignoredStatus = MZ_DELETE_FILE(pZip_filename);
+ (void)ignoredStatus;
+ }
+
+ if (pErr)
+ *pErr = actual_err;
+
+ return status;
+}
+
+void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr)
+{
+ mz_uint32 file_index;
+ mz_zip_archive zip_archive;
+ void *p = NULL;
+
+ if (pSize)
+ *pSize = 0;
+
+ if ((!pZip_filename) || (!pArchive_name))
+ {
+ if (pErr)
+ *pErr = MZ_ZIP_INVALID_PARAMETER;
+
+ return NULL;
+ }
+
+ mz_zip_zero_struct(&zip_archive);
+ if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0))
+ {
+ if (pErr)
+ *pErr = zip_archive.m_last_error;
+
+ return NULL;
+ }
+
+ if (mz_zip_reader_locate_file_v2(&zip_archive, pArchive_name, pComment, flags, &file_index))
+ {
+ p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags);
+ }
+
+ mz_zip_reader_end_internal(&zip_archive, p != NULL);
+
+ if (pErr)
+ *pErr = zip_archive.m_last_error;
+
+ return p;
+}
+
+void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags)
+{
+ return mz_zip_extract_archive_file_to_heap_v2(pZip_filename, pArchive_name, NULL, pSize, flags, NULL);
+}
+
+#endif /* #ifndef MINIZ_NO_STDIO */
+
+#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */
+
+/* ------------------- Misc utils */
+
+mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip)
+{
+ return pZip ? pZip->m_zip_mode : MZ_ZIP_MODE_INVALID;
+}
+
+mz_zip_type mz_zip_get_type(mz_zip_archive *pZip)
+{
+ return pZip ? pZip->m_zip_type : MZ_ZIP_TYPE_INVALID;
+}
+
+mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num)
+{
+ mz_zip_error prev_err;
+
+ if (!pZip)
+ return MZ_ZIP_INVALID_PARAMETER;
+
+ prev_err = pZip->m_last_error;
+
+ pZip->m_last_error = err_num;
+ return prev_err;
+}
+
+mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip)
+{
+ if (!pZip)
+ return MZ_ZIP_INVALID_PARAMETER;
+
+ return pZip->m_last_error;
+}
+
+mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip)
+{
+ return mz_zip_set_last_error(pZip, MZ_ZIP_NO_ERROR);
+}
+
+mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip)
+{
+ mz_zip_error prev_err;
+
+ if (!pZip)
+ return MZ_ZIP_INVALID_PARAMETER;
+
+ prev_err = pZip->m_last_error;
+
+ pZip->m_last_error = MZ_ZIP_NO_ERROR;
+ return prev_err;
+}
+
+const char *mz_zip_get_error_string(mz_zip_error mz_err)
+{
+ switch (mz_err)
+ {
+ case MZ_ZIP_NO_ERROR:
+ return "no error";
+ case MZ_ZIP_UNDEFINED_ERROR:
+ return "undefined error";
+ case MZ_ZIP_TOO_MANY_FILES:
+ return "too many files";
+ case MZ_ZIP_FILE_TOO_LARGE:
+ return "file too large";
+ case MZ_ZIP_UNSUPPORTED_METHOD:
+ return "unsupported method";
+ case MZ_ZIP_UNSUPPORTED_ENCRYPTION:
+ return "unsupported encryption";
+ case MZ_ZIP_UNSUPPORTED_FEATURE:
+ return "unsupported feature";
+ case MZ_ZIP_FAILED_FINDING_CENTRAL_DIR:
+ return "failed finding central directory";
+ case MZ_ZIP_NOT_AN_ARCHIVE:
+ return "not a ZIP archive";
+ case MZ_ZIP_INVALID_HEADER_OR_CORRUPTED:
+ return "invalid header or archive is corrupted";
+ case MZ_ZIP_UNSUPPORTED_MULTIDISK:
+ return "unsupported multidisk archive";
+ case MZ_ZIP_DECOMPRESSION_FAILED:
+ return "decompression failed or archive is corrupted";
+ case MZ_ZIP_COMPRESSION_FAILED:
+ return "compression failed";
+ case MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE:
+ return "unexpected decompressed size";
+ case MZ_ZIP_CRC_CHECK_FAILED:
+ return "CRC-32 check failed";
+ case MZ_ZIP_UNSUPPORTED_CDIR_SIZE:
+ return "unsupported central directory size";
+ case MZ_ZIP_ALLOC_FAILED:
+ return "allocation failed";
+ case MZ_ZIP_FILE_OPEN_FAILED:
+ return "file open failed";
+ case MZ_ZIP_FILE_CREATE_FAILED:
+ return "file create failed";
+ case MZ_ZIP_FILE_WRITE_FAILED:
+ return "file write failed";
+ case MZ_ZIP_FILE_READ_FAILED:
+ return "file read failed";
+ case MZ_ZIP_FILE_CLOSE_FAILED:
+ return "file close failed";
+ case MZ_ZIP_FILE_SEEK_FAILED:
+ return "file seek failed";
+ case MZ_ZIP_FILE_STAT_FAILED:
+ return "file stat failed";
+ case MZ_ZIP_INVALID_PARAMETER:
+ return "invalid parameter";
+ case MZ_ZIP_INVALID_FILENAME:
+ return "invalid filename";
+ case MZ_ZIP_BUF_TOO_SMALL:
+ return "buffer too small";
+ case MZ_ZIP_INTERNAL_ERROR:
+ return "internal error";
+ case MZ_ZIP_FILE_NOT_FOUND:
+ return "file not found";
+ case MZ_ZIP_ARCHIVE_TOO_LARGE:
+ return "archive is too large";
+ case MZ_ZIP_VALIDATION_FAILED:
+ return "validation failed";
+ case MZ_ZIP_WRITE_CALLBACK_FAILED:
+ return "write calledback failed";
+ default:
+ break;
+ }
+
+ return "unknown error";
+}
+
+/* Note: Just because the archive is not zip64 doesn't necessarily mean it doesn't have Zip64 extended information extra field, argh. */
+mz_bool mz_zip_is_zip64(mz_zip_archive *pZip)
+{
+ if ((!pZip) || (!pZip->m_pState))
+ return MZ_FALSE;
+
+ return pZip->m_pState->m_zip64;
+}
+
+size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip)
+{
+ if ((!pZip) || (!pZip->m_pState))
+ return 0;
+
+ return pZip->m_pState->m_central_dir.m_size;
+}
+
+mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip)
+{
+ return pZip ? pZip->m_total_files : 0;
+}
+
+mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip)
+{
+ if (!pZip)
+ return 0;
+ return pZip->m_archive_size;
+}
+
+mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip)
+{
+ if ((!pZip) || (!pZip->m_pState))
+ return 0;
+ return pZip->m_pState->m_file_archive_start_ofs;
+}
+
+MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip)
+{
+ if ((!pZip) || (!pZip->m_pState))
+ return 0;
+ return pZip->m_pState->m_pFile;
+}
+
+size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n)
+{
+ if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pZip->m_pRead))
+ return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+
+ return pZip->m_pRead(pZip->m_pIO_opaque, file_ofs, pBuf, n);
+}
+
+mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size)
+{
+ mz_uint n;
+ const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
+ if (!p)
+ {
+ if (filename_buf_size)
+ pFilename[0] = '\0';
+ mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
+ return 0;
+ }
+ n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ if (filename_buf_size)
+ {
+ n = MZ_MIN(n, filename_buf_size - 1);
+ memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
+ pFilename[n] = '\0';
+ }
+ return n + 1;
+}
+
+mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat)
+{
+ return mz_zip_file_stat_internal(pZip, file_index, mz_zip_get_cdh(pZip, file_index), pStat, NULL);
+}
+
+mz_bool mz_zip_end(mz_zip_archive *pZip)
+{
+ if (!pZip)
+ return MZ_FALSE;
+
+ if (pZip->m_zip_mode == MZ_ZIP_MODE_READING)
+ return mz_zip_reader_end(pZip);
+#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
+ else if ((pZip->m_zip_mode == MZ_ZIP_MODE_WRITING) || (pZip->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED))
+ return mz_zip_writer_end(pZip);
+#endif
+
+ return MZ_FALSE;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*#ifndef MINIZ_NO_ARCHIVE_APIS*/
diff --git a/graphics/asymptote/cudareflect/tinyexr/deps/miniz/miniz.h b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/miniz.h
new file mode 100644
index 0000000000..6cc398c920
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/miniz.h
@@ -0,0 +1,1350 @@
+#define MINIZ_EXPORT
+/* miniz.c 2.2.0 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
+ See "unlicense" statement at the end of this file.
+ Rich Geldreich <richgel99@gmail.com>, last updated Oct. 13, 2013
+ Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
+
+ Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define
+ MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros).
+
+ * Low-level Deflate/Inflate implementation notes:
+
+ Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or
+ greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses
+ approximately as well as zlib.
+
+ Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function
+ coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory
+ block large enough to hold the entire file.
+
+ The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation.
+
+ * zlib-style API notes:
+
+ miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in
+ zlib replacement in many apps:
+ The z_stream struct, optional memory allocation callbacks
+ deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound
+ inflateInit/inflateInit2/inflate/inflateReset/inflateEnd
+ compress, compress2, compressBound, uncompress
+ CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines.
+ Supports raw deflate streams or standard zlib streams with adler-32 checking.
+
+ Limitations:
+ The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries.
+ I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but
+ there are no guarantees that miniz.c pulls this off perfectly.
+
+ * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by
+ Alex Evans. Supports 1-4 bytes/pixel images.
+
+ * ZIP archive API notes:
+
+ The ZIP archive API's where designed with simplicity and efficiency in mind, with just enough abstraction to
+ get the job done with minimal fuss. There are simple API's to retrieve file information, read files from
+ existing archives, create new archives, append new files to existing archives, or clone archive data from
+ one archive to another. It supports archives located in memory or the heap, on disk (using stdio.h),
+ or you can specify custom file read/write callbacks.
+
+ - Archive reading: Just call this function to read a single file from a disk archive:
+
+ void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name,
+ size_t *pSize, mz_uint zip_flags);
+
+ For more complex cases, use the "mz_zip_reader" functions. Upon opening an archive, the entire central
+ directory is located and read as-is into memory, and subsequent file access only occurs when reading individual files.
+
+ - Archives file scanning: The simple way is to use this function to scan a loaded archive for a specific file:
+
+ int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
+
+ The locate operation can optionally check file comments too, which (as one example) can be used to identify
+ multiple versions of the same file in an archive. This function uses a simple linear search through the central
+ directory, so it's not very fast.
+
+ Alternately, you can iterate through all the files in an archive (using mz_zip_reader_get_num_files()) and
+ retrieve detailed info on each file by calling mz_zip_reader_file_stat().
+
+ - Archive creation: Use the "mz_zip_writer" functions. The ZIP writer immediately writes compressed file data
+ to disk and builds an exact image of the central directory in memory. The central directory image is written
+ all at once at the end of the archive file when the archive is finalized.
+
+ The archive writer can optionally align each file's local header and file data to any power of 2 alignment,
+ which can be useful when the archive will be read from optical media. Also, the writer supports placing
+ arbitrary data blobs at the very beginning of ZIP archives. Archives written using either feature are still
+ readable by any ZIP tool.
+
+ - Archive appending: The simple way to add a single file to an archive is to call this function:
+
+ mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name,
+ const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
+
+ The archive will be created if it doesn't already exist, otherwise it'll be appended to.
+ Note the appending is done in-place and is not an atomic operation, so if something goes wrong
+ during the operation it's possible the archive could be left without a central directory (although the local
+ file headers and file data will be fine, so the archive will be recoverable).
+
+ For more complex archive modification scenarios:
+ 1. The safest way is to use a mz_zip_reader to read the existing archive, cloning only those bits you want to
+ preserve into a new archive using using the mz_zip_writer_add_from_zip_reader() function (which compiles the
+ compressed file data as-is). When you're done, delete the old archive and rename the newly written archive, and
+ you're done. This is safe but requires a bunch of temporary disk space or heap memory.
+
+ 2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using mz_zip_writer_init_from_reader(),
+ append new files as needed, then finalize the archive which will write an updated central directory to the
+ original archive. (This is basically what mz_zip_add_mem_to_archive_file_in_place() does.) There's a
+ possibility that the archive's central directory could be lost with this method if anything goes wrong, though.
+
+ - ZIP archive support limitations:
+ No spanning support. Extraction functions can only handle unencrypted, stored or deflated files.
+ Requires streams capable of seeking.
+
+ * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the
+ below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it.
+
+ * Important: For best perf. be sure to customize the below macros for your target platform:
+ #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
+ #define MINIZ_LITTLE_ENDIAN 1
+ #define MINIZ_HAS_64BIT_REGISTERS 1
+
+ * On platforms using glibc, Be sure to "#define _LARGEFILE64_SOURCE 1" before including miniz.c to ensure miniz
+ uses the 64-bit variants: fopen64(), stat64(), etc. Otherwise you won't be able to process large files
+ (i.e. 32-bit stat() fails for me on files > 0x7FFFFFFF bytes).
+*/
+#pragma once
+
+
+
+/* Defines to completely disable specific portions of miniz.c:
+ If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. */
+
+/* Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. */
+/*#define MINIZ_NO_STDIO */
+
+/* If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or */
+/* get/set file times, and the C run-time funcs that get/set times won't be called. */
+/* The current downside is the times written to your archives will be from 1979. */
+/*#define MINIZ_NO_TIME */
+
+/* Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. */
+/*#define MINIZ_NO_ARCHIVE_APIS */
+
+/* Define MINIZ_NO_ARCHIVE_WRITING_APIS to disable all writing related ZIP archive API's. */
+/*#define MINIZ_NO_ARCHIVE_WRITING_APIS */
+
+/* Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's. */
+/*#define MINIZ_NO_ZLIB_APIS */
+
+/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib. */
+/*#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES */
+
+/* Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc.
+ Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc
+ callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user
+ functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. */
+/*#define MINIZ_NO_MALLOC */
+
+#if defined(__TINYC__) && (defined(__linux) || defined(__linux__))
+/* TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux */
+#define MINIZ_NO_TIME
+#endif
+
+#include <stddef.h>
+
+#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS)
+#include <time.h>
+#endif
+
+#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__)
+/* MINIZ_X86_OR_X64_CPU is only used to help set the below macros. */
+#define MINIZ_X86_OR_X64_CPU 1
+#else
+#define MINIZ_X86_OR_X64_CPU 0
+#endif
+
+#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
+/* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */
+#define MINIZ_LITTLE_ENDIAN 1
+#else
+#define MINIZ_LITTLE_ENDIAN 0
+#endif
+
+/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES only if not set */
+#if !defined(MINIZ_USE_UNALIGNED_LOADS_AND_STORES)
+#if MINIZ_X86_OR_X64_CPU
+/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. */
+#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
+#define MINIZ_UNALIGNED_USE_MEMCPY
+#else
+#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
+#endif
+#endif
+
+#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__)
+/* Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions). */
+#define MINIZ_HAS_64BIT_REGISTERS 1
+#else
+#define MINIZ_HAS_64BIT_REGISTERS 0
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ------------------- zlib-style API Definitions. */
+
+/* For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits! */
+typedef unsigned long mz_ulong;
+
+/* mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap. */
+MINIZ_EXPORT void mz_free(void *p);
+
+#define MZ_ADLER32_INIT (1)
+/* mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL. */
+MINIZ_EXPORT mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
+
+#define MZ_CRC32_INIT (0)
+/* mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. */
+MINIZ_EXPORT mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
+
+/* Compression strategies. */
+enum
+{
+ MZ_DEFAULT_STRATEGY = 0,
+ MZ_FILTERED = 1,
+ MZ_HUFFMAN_ONLY = 2,
+ MZ_RLE = 3,
+ MZ_FIXED = 4
+};
+
+/* Method */
+#define MZ_DEFLATED 8
+
+/* Heap allocation callbacks.
+Note that mz_alloc_func parameter types purposely differ from zlib's: items/size is size_t, not unsigned long. */
+typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
+typedef void (*mz_free_func)(void *opaque, void *address);
+typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
+
+/* Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. */
+enum
+{
+ MZ_NO_COMPRESSION = 0,
+ MZ_BEST_SPEED = 1,
+ MZ_BEST_COMPRESSION = 9,
+ MZ_UBER_COMPRESSION = 10,
+ MZ_DEFAULT_LEVEL = 6,
+ MZ_DEFAULT_COMPRESSION = -1
+};
+
+#define MZ_VERSION "10.2.0"
+#define MZ_VERNUM 0xA100
+#define MZ_VER_MAJOR 10
+#define MZ_VER_MINOR 2
+#define MZ_VER_REVISION 0
+#define MZ_VER_SUBREVISION 0
+
+#ifndef MINIZ_NO_ZLIB_APIS
+
+/* Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs). */
+enum
+{
+ MZ_NO_FLUSH = 0,
+ MZ_PARTIAL_FLUSH = 1,
+ MZ_SYNC_FLUSH = 2,
+ MZ_FULL_FLUSH = 3,
+ MZ_FINISH = 4,
+ MZ_BLOCK = 5
+};
+
+/* Return status codes. MZ_PARAM_ERROR is non-standard. */
+enum
+{
+ MZ_OK = 0,
+ MZ_STREAM_END = 1,
+ MZ_NEED_DICT = 2,
+ MZ_ERRNO = -1,
+ MZ_STREAM_ERROR = -2,
+ MZ_DATA_ERROR = -3,
+ MZ_MEM_ERROR = -4,
+ MZ_BUF_ERROR = -5,
+ MZ_VERSION_ERROR = -6,
+ MZ_PARAM_ERROR = -10000
+};
+
+/* Window bits */
+#define MZ_DEFAULT_WINDOW_BITS 15
+
+struct mz_internal_state;
+
+/* Compression/decompression stream struct. */
+typedef struct mz_stream_s
+{
+ const unsigned char *next_in; /* pointer to next byte to read */
+ unsigned int avail_in; /* number of bytes available at next_in */
+ mz_ulong total_in; /* total number of bytes consumed so far */
+
+ unsigned char *next_out; /* pointer to next byte to write */
+ unsigned int avail_out; /* number of bytes that can be written to next_out */
+ mz_ulong total_out; /* total number of bytes produced so far */
+
+ char *msg; /* error msg (unused) */
+ struct mz_internal_state *state; /* internal state, allocated by zalloc/zfree */
+
+ mz_alloc_func zalloc; /* optional heap allocation function (defaults to malloc) */
+ mz_free_func zfree; /* optional heap free function (defaults to free) */
+ void *opaque; /* heap alloc function user pointer */
+
+ int data_type; /* data_type (unused) */
+ mz_ulong adler; /* adler32 of the source or uncompressed data */
+ mz_ulong reserved; /* not used */
+} mz_stream;
+
+typedef mz_stream *mz_streamp;
+
+/* Returns the version string of miniz.c. */
+MINIZ_EXPORT const char *mz_version(void);
+
+/* mz_deflateInit() initializes a compressor with default options: */
+/* Parameters: */
+/* pStream must point to an initialized mz_stream struct. */
+/* level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION]. */
+/* level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio. */
+/* (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.) */
+/* Return values: */
+/* MZ_OK on success. */
+/* MZ_STREAM_ERROR if the stream is bogus. */
+/* MZ_PARAM_ERROR if the input parameters are bogus. */
+/* MZ_MEM_ERROR on out of memory. */
+MINIZ_EXPORT int mz_deflateInit(mz_streamp pStream, int level);
+
+/* mz_deflateInit2() is like mz_deflate(), except with more control: */
+/* Additional parameters: */
+/* method must be MZ_DEFLATED */
+/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer) */
+/* mem_level must be between [1, 9] (it's checked but ignored by miniz.c) */
+MINIZ_EXPORT int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy);
+
+/* Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). */
+MINIZ_EXPORT int mz_deflateReset(mz_streamp pStream);
+
+/* mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. */
+/* Parameters: */
+/* pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. */
+/* flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH. */
+/* Return values: */
+/* MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full). */
+/* MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore. */
+/* MZ_STREAM_ERROR if the stream is bogus. */
+/* MZ_PARAM_ERROR if one of the parameters is invalid. */
+/* MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.) */
+MINIZ_EXPORT int mz_deflate(mz_streamp pStream, int flush);
+
+/* mz_deflateEnd() deinitializes a compressor: */
+/* Return values: */
+/* MZ_OK on success. */
+/* MZ_STREAM_ERROR if the stream is bogus. */
+MINIZ_EXPORT int mz_deflateEnd(mz_streamp pStream);
+
+/* mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH. */
+MINIZ_EXPORT mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
+
+/* Single-call compression functions mz_compress() and mz_compress2(): */
+/* Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure. */
+MINIZ_EXPORT int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
+MINIZ_EXPORT int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
+
+/* mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). */
+MINIZ_EXPORT mz_ulong mz_compressBound(mz_ulong source_len);
+
+/* Initializes a decompressor. */
+MINIZ_EXPORT int mz_inflateInit(mz_streamp pStream);
+
+/* mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer: */
+/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate). */
+MINIZ_EXPORT int mz_inflateInit2(mz_streamp pStream, int window_bits);
+
+/* Quickly resets a compressor without having to reallocate anything. Same as calling mz_inflateEnd() followed by mz_inflateInit()/mz_inflateInit2(). */
+MINIZ_EXPORT int mz_inflateReset(mz_streamp pStream);
+
+/* Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible. */
+/* Parameters: */
+/* pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. */
+/* flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH. */
+/* On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster). */
+/* MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data. */
+/* Return values: */
+/* MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full. */
+/* MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified. */
+/* MZ_STREAM_ERROR if the stream is bogus. */
+/* MZ_DATA_ERROR if the deflate stream is invalid. */
+/* MZ_PARAM_ERROR if one of the parameters is invalid. */
+/* MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again */
+/* with more input data, or with more room in the output buffer (except when using single call decompression, described above). */
+MINIZ_EXPORT int mz_inflate(mz_streamp pStream, int flush);
+
+/* Deinitializes a decompressor. */
+MINIZ_EXPORT int mz_inflateEnd(mz_streamp pStream);
+
+/* Single-call decompression. */
+/* Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. */
+MINIZ_EXPORT int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
+MINIZ_EXPORT int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong *pSource_len);
+
+/* Returns a string description of the specified error code, or NULL if the error code is invalid. */
+MINIZ_EXPORT const char *mz_error(int err);
+
+/* Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports. */
+/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. */
+#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
+typedef unsigned char Byte;
+typedef unsigned int uInt;
+typedef mz_ulong uLong;
+typedef Byte Bytef;
+typedef uInt uIntf;
+typedef char charf;
+typedef int intf;
+typedef void *voidpf;
+typedef uLong uLongf;
+typedef void *voidp;
+typedef void *const voidpc;
+#define Z_NULL 0
+#define Z_NO_FLUSH MZ_NO_FLUSH
+#define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH
+#define Z_SYNC_FLUSH MZ_SYNC_FLUSH
+#define Z_FULL_FLUSH MZ_FULL_FLUSH
+#define Z_FINISH MZ_FINISH
+#define Z_BLOCK MZ_BLOCK
+#define Z_OK MZ_OK
+#define Z_STREAM_END MZ_STREAM_END
+#define Z_NEED_DICT MZ_NEED_DICT
+#define Z_ERRNO MZ_ERRNO
+#define Z_STREAM_ERROR MZ_STREAM_ERROR
+#define Z_DATA_ERROR MZ_DATA_ERROR
+#define Z_MEM_ERROR MZ_MEM_ERROR
+#define Z_BUF_ERROR MZ_BUF_ERROR
+#define Z_VERSION_ERROR MZ_VERSION_ERROR
+#define Z_PARAM_ERROR MZ_PARAM_ERROR
+#define Z_NO_COMPRESSION MZ_NO_COMPRESSION
+#define Z_BEST_SPEED MZ_BEST_SPEED
+#define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION
+#define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
+#define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY
+#define Z_FILTERED MZ_FILTERED
+#define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY
+#define Z_RLE MZ_RLE
+#define Z_FIXED MZ_FIXED
+#define Z_DEFLATED MZ_DEFLATED
+#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
+#define alloc_func mz_alloc_func
+#define free_func mz_free_func
+#define internal_state mz_internal_state
+#define z_stream mz_stream
+#define deflateInit mz_deflateInit
+#define deflateInit2 mz_deflateInit2
+#define deflateReset mz_deflateReset
+#define deflate mz_deflate
+#define deflateEnd mz_deflateEnd
+#define deflateBound mz_deflateBound
+#define compress mz_compress
+#define compress2 mz_compress2
+#define compressBound mz_compressBound
+#define inflateInit mz_inflateInit
+#define inflateInit2 mz_inflateInit2
+#define inflateReset mz_inflateReset
+#define inflate mz_inflate
+#define inflateEnd mz_inflateEnd
+#define uncompress mz_uncompress
+#define uncompress2 mz_uncompress2
+#define crc32 mz_crc32
+#define adler32 mz_adler32
+#define MAX_WBITS 15
+#define MAX_MEM_LEVEL 9
+#define zError mz_error
+#define ZLIB_VERSION MZ_VERSION
+#define ZLIB_VERNUM MZ_VERNUM
+#define ZLIB_VER_MAJOR MZ_VER_MAJOR
+#define ZLIB_VER_MINOR MZ_VER_MINOR
+#define ZLIB_VER_REVISION MZ_VER_REVISION
+#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
+#define zlibVersion mz_version
+#define zlib_version mz_version()
+#endif /* #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES */
+
+#endif /* MINIZ_NO_ZLIB_APIS */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+
+#pragma once
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+
+/* ------------------- Types and macros */
+typedef unsigned char mz_uint8;
+typedef signed short mz_int16;
+typedef unsigned short mz_uint16;
+typedef unsigned int mz_uint32;
+typedef unsigned int mz_uint;
+typedef int64_t mz_int64;
+typedef uint64_t mz_uint64;
+typedef int mz_bool;
+
+#define MZ_FALSE (0)
+#define MZ_TRUE (1)
+
+/* Works around MSVC's spammy "warning C4127: conditional expression is constant" message. */
+#ifdef _MSC_VER
+#define MZ_MACRO_END while (0, 0)
+#else
+#define MZ_MACRO_END while (0)
+#endif
+
+#ifdef MINIZ_NO_STDIO
+#define MZ_FILE void *
+#else
+#include <stdio.h>
+#define MZ_FILE FILE
+#endif /* #ifdef MINIZ_NO_STDIO */
+
+#ifdef MINIZ_NO_TIME
+typedef struct mz_dummy_time_t_tag
+{
+ int m_dummy;
+} mz_dummy_time_t;
+#define MZ_TIME_T mz_dummy_time_t
+#else
+#define MZ_TIME_T time_t
+#endif
+
+#define MZ_ASSERT(x) assert(x)
+
+#ifdef MINIZ_NO_MALLOC
+#define MZ_MALLOC(x) NULL
+#define MZ_FREE(x) (void)x, ((void)0)
+#define MZ_REALLOC(p, x) NULL
+#else
+#define MZ_MALLOC(x) malloc(x)
+#define MZ_FREE(x) free(x)
+#define MZ_REALLOC(p, x) realloc(p, x)
+#endif
+
+#define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b))
+#define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
+#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
+#define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
+#else
+#define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
+#define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
+#endif
+
+#define MZ_READ_LE64(p) (((mz_uint64)MZ_READ_LE32(p)) | (((mz_uint64)MZ_READ_LE32((const mz_uint8 *)(p) + sizeof(mz_uint32))) << 32U))
+
+#ifdef _MSC_VER
+#define MZ_FORCEINLINE __forceinline
+#elif defined(__GNUC__)
+#define MZ_FORCEINLINE __inline__ __attribute__((__always_inline__))
+#else
+#define MZ_FORCEINLINE inline
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size);
+extern MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address);
+extern MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size);
+
+#define MZ_UINT16_MAX (0xFFFFU)
+#define MZ_UINT32_MAX (0xFFFFFFFFU)
+
+#ifdef __cplusplus
+}
+#endif
+ #pragma once
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* ------------------- Low-level Compression API Definitions */
+
+/* Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently). */
+#define TDEFL_LESS_MEMORY 0
+
+/* tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search): */
+/* TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression). */
+enum
+{
+ TDEFL_HUFFMAN_ONLY = 0,
+ TDEFL_DEFAULT_MAX_PROBES = 128,
+ TDEFL_MAX_PROBES_MASK = 0xFFF
+};
+
+/* TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data. */
+/* TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers). */
+/* TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing. */
+/* TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory). */
+/* TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1) */
+/* TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled. */
+/* TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables. */
+/* TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks. */
+/* The low 12 bits are reserved to control the max # of hash probes per dictionary lookup (see TDEFL_MAX_PROBES_MASK). */
+enum
+{
+ TDEFL_WRITE_ZLIB_HEADER = 0x01000,
+ TDEFL_COMPUTE_ADLER32 = 0x02000,
+ TDEFL_GREEDY_PARSING_FLAG = 0x04000,
+ TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000,
+ TDEFL_RLE_MATCHES = 0x10000,
+ TDEFL_FILTER_MATCHES = 0x20000,
+ TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000,
+ TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000
+};
+
+/* High level compression functions: */
+/* tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc(). */
+/* On entry: */
+/* pSrc_buf, src_buf_len: Pointer and size of source block to compress. */
+/* flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression. */
+/* On return: */
+/* Function returns a pointer to the compressed data, or NULL on failure. */
+/* *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data. */
+/* The caller must free() the returned block when it's no longer needed. */
+MINIZ_EXPORT void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
+
+/* tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory. */
+/* Returns 0 on failure. */
+MINIZ_EXPORT size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
+
+/* Compresses an image to a compressed PNG file in memory. */
+/* On entry: */
+/* pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4. */
+/* The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory. */
+/* level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL */
+/* If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps). */
+/* On return: */
+/* Function returns a pointer to the compressed data, or NULL on failure. */
+/* *pLen_out will be set to the size of the PNG image file. */
+/* The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. */
+MINIZ_EXPORT void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip);
+MINIZ_EXPORT void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out);
+
+/* Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. */
+typedef mz_bool (*tdefl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);
+
+/* tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally. */
+MINIZ_EXPORT mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
+
+enum
+{
+ TDEFL_MAX_HUFF_TABLES = 3,
+ TDEFL_MAX_HUFF_SYMBOLS_0 = 288,
+ TDEFL_MAX_HUFF_SYMBOLS_1 = 32,
+ TDEFL_MAX_HUFF_SYMBOLS_2 = 19,
+ TDEFL_LZ_DICT_SIZE = 32768,
+ TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1,
+ TDEFL_MIN_MATCH_LEN = 3,
+ TDEFL_MAX_MATCH_LEN = 258
+};
+
+/* TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes). */
+#if TDEFL_LESS_MEMORY
+enum
+{
+ TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024,
+ TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10,
+ TDEFL_MAX_HUFF_SYMBOLS = 288,
+ TDEFL_LZ_HASH_BITS = 12,
+ TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
+ TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3,
+ TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS
+};
+#else
+enum
+{
+ TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024,
+ TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10,
+ TDEFL_MAX_HUFF_SYMBOLS = 288,
+ TDEFL_LZ_HASH_BITS = 15,
+ TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
+ TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3,
+ TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS
+};
+#endif
+
+/* The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. */
+typedef enum {
+ TDEFL_STATUS_BAD_PARAM = -2,
+ TDEFL_STATUS_PUT_BUF_FAILED = -1,
+ TDEFL_STATUS_OKAY = 0,
+ TDEFL_STATUS_DONE = 1
+} tdefl_status;
+
+/* Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums */
+typedef enum {
+ TDEFL_NO_FLUSH = 0,
+ TDEFL_SYNC_FLUSH = 2,
+ TDEFL_FULL_FLUSH = 3,
+ TDEFL_FINISH = 4
+} tdefl_flush;
+
+/* tdefl's compression state structure. */
+typedef struct
+{
+ tdefl_put_buf_func_ptr m_pPut_buf_func;
+ void *m_pPut_buf_user;
+ mz_uint m_flags, m_max_probes[2];
+ int m_greedy_parsing;
+ mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size;
+ mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end;
+ mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer;
+ mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish;
+ tdefl_status m_prev_return_status;
+ const void *m_pIn_buf;
+ void *m_pOut_buf;
+ size_t *m_pIn_buf_size, *m_pOut_buf_size;
+ tdefl_flush m_flush;
+ const mz_uint8 *m_pSrc;
+ size_t m_src_buf_left, m_out_buf_ofs;
+ mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1];
+ mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
+ mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
+ mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
+ mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE];
+ mz_uint16 m_next[TDEFL_LZ_DICT_SIZE];
+ mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE];
+ mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE];
+} tdefl_compressor;
+
+/* Initializes the compressor. */
+/* There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory. */
+/* pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression. */
+/* If pBut_buf_func is NULL the user should always call the tdefl_compress() API. */
+/* flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.) */
+MINIZ_EXPORT tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
+
+/* Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible. */
+MINIZ_EXPORT tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush);
+
+/* tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr. */
+/* tdefl_compress_buffer() always consumes the entire input buffer. */
+MINIZ_EXPORT tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);
+
+MINIZ_EXPORT tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d);
+MINIZ_EXPORT mz_uint32 tdefl_get_adler32(tdefl_compressor *d);
+
+/* Create tdefl_compress() flags given zlib-style compression parameters. */
+/* level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files) */
+/* window_bits may be -15 (raw deflate) or 15 (zlib) */
+/* strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED */
+MINIZ_EXPORT mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
+
+#ifndef MINIZ_NO_MALLOC
+/* Allocate the tdefl_compressor structure in C so that */
+/* non-C language bindings to tdefl_ API don't need to worry about */
+/* structure size and allocation mechanism. */
+MINIZ_EXPORT tdefl_compressor *tdefl_compressor_alloc(void);
+MINIZ_EXPORT void tdefl_compressor_free(tdefl_compressor *pComp);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+ #pragma once
+
+/* ------------------- Low-level Decompression API Definitions */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* Decompression flags used by tinfl_decompress(). */
+/* TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream. */
+/* TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input. */
+/* TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB). */
+/* TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes. */
+enum
+{
+ TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
+ TINFL_FLAG_HAS_MORE_INPUT = 2,
+ TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
+ TINFL_FLAG_COMPUTE_ADLER32 = 8
+};
+
+/* High level decompression functions: */
+/* tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc(). */
+/* On entry: */
+/* pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress. */
+/* On return: */
+/* Function returns a pointer to the decompressed data, or NULL on failure. */
+/* *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. */
+/* The caller must call mz_free() on the returned block when it's no longer needed. */
+MINIZ_EXPORT void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
+
+/* tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. */
+/* Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. */
+#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
+MINIZ_EXPORT size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
+
+/* tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer. */
+/* Returns 1 on success or 0 on failure. */
+typedef int (*tinfl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);
+MINIZ_EXPORT int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
+
+struct tinfl_decompressor_tag;
+typedef struct tinfl_decompressor_tag tinfl_decompressor;
+
+#ifndef MINIZ_NO_MALLOC
+/* Allocate the tinfl_decompressor structure in C so that */
+/* non-C language bindings to tinfl_ API don't need to worry about */
+/* structure size and allocation mechanism. */
+MINIZ_EXPORT tinfl_decompressor *tinfl_decompressor_alloc(void);
+MINIZ_EXPORT void tinfl_decompressor_free(tinfl_decompressor *pDecomp);
+#endif
+
+/* Max size of LZ dictionary. */
+#define TINFL_LZ_DICT_SIZE 32768
+
+/* Return status. */
+typedef enum {
+ /* This flags indicates the inflator needs 1 or more input bytes to make forward progress, but the caller is indicating that no more are available. The compressed data */
+ /* is probably corrupted. If you call the inflator again with more bytes it'll try to continue processing the input but this is a BAD sign (either the data is corrupted or you called it incorrectly). */
+ /* If you call it again with no input you'll just get TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS again. */
+ TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS = -4,
+
+ /* This flag indicates that one or more of the input parameters was obviously bogus. (You can try calling it again, but if you get this error the calling code is wrong.) */
+ TINFL_STATUS_BAD_PARAM = -3,
+
+ /* This flags indicate the inflator is finished but the adler32 check of the uncompressed data didn't match. If you call it again it'll return TINFL_STATUS_DONE. */
+ TINFL_STATUS_ADLER32_MISMATCH = -2,
+
+ /* This flags indicate the inflator has somehow failed (bad code, corrupted input, etc.). If you call it again without resetting via tinfl_init() it it'll just keep on returning the same status failure code. */
+ TINFL_STATUS_FAILED = -1,
+
+ /* Any status code less than TINFL_STATUS_DONE must indicate a failure. */
+
+ /* This flag indicates the inflator has returned every byte of uncompressed data that it can, has consumed every byte that it needed, has successfully reached the end of the deflate stream, and */
+ /* if zlib headers and adler32 checking enabled that it has successfully checked the uncompressed data's adler32. If you call it again you'll just get TINFL_STATUS_DONE over and over again. */
+ TINFL_STATUS_DONE = 0,
+
+ /* This flag indicates the inflator MUST have more input data (even 1 byte) before it can make any more forward progress, or you need to clear the TINFL_FLAG_HAS_MORE_INPUT */
+ /* flag on the next call if you don't have any more source data. If the source data was somehow corrupted it's also possible (but unlikely) for the inflator to keep on demanding input to */
+ /* proceed, so be sure to properly set the TINFL_FLAG_HAS_MORE_INPUT flag. */
+ TINFL_STATUS_NEEDS_MORE_INPUT = 1,
+
+ /* This flag indicates the inflator definitely has 1 or more bytes of uncompressed data available, but it cannot write this data into the output buffer. */
+ /* Note if the source compressed data was corrupted it's possible for the inflator to return a lot of uncompressed data to the caller. I've been assuming you know how much uncompressed data to expect */
+ /* (either exact or worst case) and will stop calling the inflator and fail after receiving too much. In pure streaming scenarios where you have no idea how many bytes to expect this may not be possible */
+ /* so I may need to add some code to address this. */
+ TINFL_STATUS_HAS_MORE_OUTPUT = 2
+} tinfl_status;
+
+/* Initializes the decompressor to its initial state. */
+#define tinfl_init(r) \
+ do \
+ { \
+ (r)->m_state = 0; \
+ } \
+ MZ_MACRO_END
+#define tinfl_get_adler32(r) (r)->m_check_adler32
+
+/* Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. */
+/* This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. */
+MINIZ_EXPORT tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags);
+
+/* Internal/private bits follow. */
+enum
+{
+ TINFL_MAX_HUFF_TABLES = 3,
+ TINFL_MAX_HUFF_SYMBOLS_0 = 288,
+ TINFL_MAX_HUFF_SYMBOLS_1 = 32,
+ TINFL_MAX_HUFF_SYMBOLS_2 = 19,
+ TINFL_FAST_LOOKUP_BITS = 10,
+ TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
+};
+
+typedef struct
+{
+ mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
+ mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
+} tinfl_huff_table;
+
+#if MINIZ_HAS_64BIT_REGISTERS
+#define TINFL_USE_64BIT_BITBUF 1
+#else
+#define TINFL_USE_64BIT_BITBUF 0
+#endif
+
+#if TINFL_USE_64BIT_BITBUF
+typedef mz_uint64 tinfl_bit_buf_t;
+#define TINFL_BITBUF_SIZE (64)
+#else
+typedef mz_uint32 tinfl_bit_buf_t;
+#define TINFL_BITBUF_SIZE (32)
+#endif
+
+struct tinfl_decompressor_tag
+{
+ mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
+ tinfl_bit_buf_t m_bit_buf;
+ size_t m_dist_from_out_buf_start;
+ tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
+ mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma once
+
+
+/* ------------------- ZIP archive reading/writing */
+
+#ifndef MINIZ_NO_ARCHIVE_APIS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum
+{
+ /* Note: These enums can be reduced as needed to save memory or stack space - they are pretty conservative. */
+ MZ_ZIP_MAX_IO_BUF_SIZE = 64 * 1024,
+ MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 512,
+ MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 512
+};
+
+typedef struct
+{
+ /* Central directory file index. */
+ mz_uint32 m_file_index;
+
+ /* Byte offset of this entry in the archive's central directory. Note we currently only support up to UINT_MAX or less bytes in the central dir. */
+ mz_uint64 m_central_dir_ofs;
+
+ /* These fields are copied directly from the zip's central dir. */
+ mz_uint16 m_version_made_by;
+ mz_uint16 m_version_needed;
+ mz_uint16 m_bit_flag;
+ mz_uint16 m_method;
+
+#ifndef MINIZ_NO_TIME
+ MZ_TIME_T m_time;
+#endif
+
+ /* CRC-32 of uncompressed data. */
+ mz_uint32 m_crc32;
+
+ /* File's compressed size. */
+ mz_uint64 m_comp_size;
+
+ /* File's uncompressed size. Note, I've seen some old archives where directory entries had 512 bytes for their uncompressed sizes, but when you try to unpack them you actually get 0 bytes. */
+ mz_uint64 m_uncomp_size;
+
+ /* Zip internal and external file attributes. */
+ mz_uint16 m_internal_attr;
+ mz_uint32 m_external_attr;
+
+ /* Entry's local header file offset in bytes. */
+ mz_uint64 m_local_header_ofs;
+
+ /* Size of comment in bytes. */
+ mz_uint32 m_comment_size;
+
+ /* MZ_TRUE if the entry appears to be a directory. */
+ mz_bool m_is_directory;
+
+ /* MZ_TRUE if the entry uses encryption/strong encryption (which miniz_zip doesn't support) */
+ mz_bool m_is_encrypted;
+
+ /* MZ_TRUE if the file is not encrypted, a patch file, and if it uses a compression method we support. */
+ mz_bool m_is_supported;
+
+ /* Filename. If string ends in '/' it's a subdirectory entry. */
+ /* Guaranteed to be zero terminated, may be truncated to fit. */
+ char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE];
+
+ /* Comment field. */
+ /* Guaranteed to be zero terminated, may be truncated to fit. */
+ char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];
+
+} mz_zip_archive_file_stat;
+
+typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n);
+typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n);
+typedef mz_bool (*mz_file_needs_keepalive)(void *pOpaque);
+
+struct mz_zip_internal_state_tag;
+typedef struct mz_zip_internal_state_tag mz_zip_internal_state;
+
+typedef enum {
+ MZ_ZIP_MODE_INVALID = 0,
+ MZ_ZIP_MODE_READING = 1,
+ MZ_ZIP_MODE_WRITING = 2,
+ MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
+} mz_zip_mode;
+
+typedef enum {
+ MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
+ MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
+ MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
+ MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800,
+ MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG = 0x1000, /* if enabled, mz_zip_reader_locate_file() will be called on each file as its validated to ensure the func finds the file in the central dir (intended for testing) */
+ MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY = 0x2000, /* validate the local headers, but don't decompress the entire file and check the crc32 */
+ MZ_ZIP_FLAG_WRITE_ZIP64 = 0x4000, /* always use the zip64 file format, instead of the original zip file format with automatic switch to zip64. Use as flags parameter with mz_zip_writer_init*_v2 */
+ MZ_ZIP_FLAG_WRITE_ALLOW_READING = 0x8000,
+ MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000,
+ /*After adding a compressed file, seek back
+ to local file header and set the correct sizes*/
+ MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE = 0x20000
+} mz_zip_flags;
+
+typedef enum {
+ MZ_ZIP_TYPE_INVALID = 0,
+ MZ_ZIP_TYPE_USER,
+ MZ_ZIP_TYPE_MEMORY,
+ MZ_ZIP_TYPE_HEAP,
+ MZ_ZIP_TYPE_FILE,
+ MZ_ZIP_TYPE_CFILE,
+ MZ_ZIP_TOTAL_TYPES
+} mz_zip_type;
+
+/* miniz error codes. Be sure to update mz_zip_get_error_string() if you add or modify this enum. */
+typedef enum {
+ MZ_ZIP_NO_ERROR = 0,
+ MZ_ZIP_UNDEFINED_ERROR,
+ MZ_ZIP_TOO_MANY_FILES,
+ MZ_ZIP_FILE_TOO_LARGE,
+ MZ_ZIP_UNSUPPORTED_METHOD,
+ MZ_ZIP_UNSUPPORTED_ENCRYPTION,
+ MZ_ZIP_UNSUPPORTED_FEATURE,
+ MZ_ZIP_FAILED_FINDING_CENTRAL_DIR,
+ MZ_ZIP_NOT_AN_ARCHIVE,
+ MZ_ZIP_INVALID_HEADER_OR_CORRUPTED,
+ MZ_ZIP_UNSUPPORTED_MULTIDISK,
+ MZ_ZIP_DECOMPRESSION_FAILED,
+ MZ_ZIP_COMPRESSION_FAILED,
+ MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE,
+ MZ_ZIP_CRC_CHECK_FAILED,
+ MZ_ZIP_UNSUPPORTED_CDIR_SIZE,
+ MZ_ZIP_ALLOC_FAILED,
+ MZ_ZIP_FILE_OPEN_FAILED,
+ MZ_ZIP_FILE_CREATE_FAILED,
+ MZ_ZIP_FILE_WRITE_FAILED,
+ MZ_ZIP_FILE_READ_FAILED,
+ MZ_ZIP_FILE_CLOSE_FAILED,
+ MZ_ZIP_FILE_SEEK_FAILED,
+ MZ_ZIP_FILE_STAT_FAILED,
+ MZ_ZIP_INVALID_PARAMETER,
+ MZ_ZIP_INVALID_FILENAME,
+ MZ_ZIP_BUF_TOO_SMALL,
+ MZ_ZIP_INTERNAL_ERROR,
+ MZ_ZIP_FILE_NOT_FOUND,
+ MZ_ZIP_ARCHIVE_TOO_LARGE,
+ MZ_ZIP_VALIDATION_FAILED,
+ MZ_ZIP_WRITE_CALLBACK_FAILED,
+ MZ_ZIP_TOTAL_ERRORS
+} mz_zip_error;
+
+typedef struct
+{
+ mz_uint64 m_archive_size;
+ mz_uint64 m_central_directory_file_ofs;
+
+ /* We only support up to UINT32_MAX files in zip64 mode. */
+ mz_uint32 m_total_files;
+ mz_zip_mode m_zip_mode;
+ mz_zip_type m_zip_type;
+ mz_zip_error m_last_error;
+
+ mz_uint64 m_file_offset_alignment;
+
+ mz_alloc_func m_pAlloc;
+ mz_free_func m_pFree;
+ mz_realloc_func m_pRealloc;
+ void *m_pAlloc_opaque;
+
+ mz_file_read_func m_pRead;
+ mz_file_write_func m_pWrite;
+ mz_file_needs_keepalive m_pNeeds_keepalive;
+ void *m_pIO_opaque;
+
+ mz_zip_internal_state *m_pState;
+
+} mz_zip_archive;
+
+typedef struct
+{
+ mz_zip_archive *pZip;
+ mz_uint flags;
+
+ int status;
+#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
+ mz_uint file_crc32;
+#endif
+ mz_uint64 read_buf_size, read_buf_ofs, read_buf_avail, comp_remaining, out_buf_ofs, cur_file_ofs;
+ mz_zip_archive_file_stat file_stat;
+ void *pRead_buf;
+ void *pWrite_buf;
+
+ size_t out_blk_remain;
+
+ tinfl_decompressor inflator;
+
+} mz_zip_reader_extract_iter_state;
+
+/* -------- ZIP reading */
+
+/* Inits a ZIP archive reader. */
+/* These functions read and validate the archive's central directory. */
+MINIZ_EXPORT mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags);
+
+MINIZ_EXPORT mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags);
+
+#ifndef MINIZ_NO_STDIO
+/* Read a archive from a disk file. */
+/* file_start_ofs is the file offset where the archive actually begins, or 0. */
+/* actual_archive_size is the true total size of the archive, which may be smaller than the file's actual size on disk. If zero the entire file is treated as the archive. */
+MINIZ_EXPORT mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags);
+MINIZ_EXPORT mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size);
+
+/* Read an archive from an already opened FILE, beginning at the current file position. */
+/* The archive is assumed to be archive_size bytes long. If archive_size is 0, then the entire rest of the file is assumed to contain the archive. */
+/* The FILE will NOT be closed when mz_zip_reader_end() is called. */
+MINIZ_EXPORT mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags);
+#endif
+
+/* Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used. */
+MINIZ_EXPORT mz_bool mz_zip_reader_end(mz_zip_archive *pZip);
+
+/* -------- ZIP reading or writing */
+
+/* Clears a mz_zip_archive struct to all zeros. */
+/* Important: This must be done before passing the struct to any mz_zip functions. */
+MINIZ_EXPORT void mz_zip_zero_struct(mz_zip_archive *pZip);
+
+MINIZ_EXPORT mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip);
+MINIZ_EXPORT mz_zip_type mz_zip_get_type(mz_zip_archive *pZip);
+
+/* Returns the total number of files in the archive. */
+MINIZ_EXPORT mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip);
+
+MINIZ_EXPORT mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip);
+MINIZ_EXPORT mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip);
+MINIZ_EXPORT MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip);
+
+/* Reads n bytes of raw archive data, starting at file offset file_ofs, to pBuf. */
+MINIZ_EXPORT size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n);
+
+/* All mz_zip funcs set the m_last_error field in the mz_zip_archive struct. These functions retrieve/manipulate this field. */
+/* Note that the m_last_error functionality is not thread safe. */
+MINIZ_EXPORT mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num);
+MINIZ_EXPORT mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip);
+MINIZ_EXPORT mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip);
+MINIZ_EXPORT mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip);
+MINIZ_EXPORT const char *mz_zip_get_error_string(mz_zip_error mz_err);
+
+/* MZ_TRUE if the archive file entry is a directory entry. */
+MINIZ_EXPORT mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index);
+
+/* MZ_TRUE if the file is encrypted/strong encrypted. */
+MINIZ_EXPORT mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index);
+
+/* MZ_TRUE if the compression method is supported, and the file is not encrypted, and the file is not a compressed patch file. */
+MINIZ_EXPORT mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index);
+
+/* Retrieves the filename of an archive file entry. */
+/* Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename. */
+MINIZ_EXPORT mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size);
+
+/* Attempts to locates a file in the archive's central directory. */
+/* Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH */
+/* Returns -1 if the file cannot be found. */
+MINIZ_EXPORT int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
+MINIZ_EXPORT mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *file_index);
+
+/* Returns detailed information about an archive file entry. */
+MINIZ_EXPORT mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat);
+
+/* MZ_TRUE if the file is in zip64 format. */
+/* A file is considered zip64 if it contained a zip64 end of central directory marker, or if it contained any zip64 extended file information fields in the central directory. */
+MINIZ_EXPORT mz_bool mz_zip_is_zip64(mz_zip_archive *pZip);
+
+/* Returns the total central directory size in bytes. */
+/* The current max supported size is <= MZ_UINT32_MAX. */
+MINIZ_EXPORT size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip);
+
+/* Extracts a archive file to a memory buffer using no memory allocation. */
+/* There must be at least enough room on the stack to store the inflator's state (~34KB or so). */
+MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
+MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
+
+/* Extracts a archive file to a memory buffer. */
+MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags);
+MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags);
+
+/* Extracts a archive file to a dynamically allocated heap buffer. */
+/* The memory will be allocated via the mz_zip_archive's alloc/realloc functions. */
+/* Returns NULL and sets the last error on failure. */
+MINIZ_EXPORT void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags);
+MINIZ_EXPORT void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags);
+
+/* Extracts a archive file using a callback function to output the file's data. */
+MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
+MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
+
+/* Extract a file iteratively */
+MINIZ_EXPORT mz_zip_reader_extract_iter_state* mz_zip_reader_extract_iter_new(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
+MINIZ_EXPORT mz_zip_reader_extract_iter_state* mz_zip_reader_extract_file_iter_new(mz_zip_archive *pZip, const char *pFilename, mz_uint flags);
+MINIZ_EXPORT size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state* pState, void* pvBuf, size_t buf_size);
+MINIZ_EXPORT mz_bool mz_zip_reader_extract_iter_free(mz_zip_reader_extract_iter_state* pState);
+
+#ifndef MINIZ_NO_STDIO
+/* Extracts a archive file to a disk file and sets its last accessed and modified times. */
+/* This function only extracts files, not archive directory records. */
+MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags);
+MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags);
+
+/* Extracts a archive file starting at the current position in the destination FILE stream. */
+MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *File, mz_uint flags);
+MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags);
+#endif
+
+#if 0
+/* TODO */
+ typedef void *mz_zip_streaming_extract_state_ptr;
+ mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
+ uint64_t mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
+ uint64_t mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
+ mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, uint64_t new_ofs);
+ size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size);
+ mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
+#endif
+
+/* This function compares the archive's local headers, the optional local zip64 extended information block, and the optional descriptor following the compressed data vs. the data in the central directory. */
+/* It also validates that each file can be successfully uncompressed unless the MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY is specified. */
+MINIZ_EXPORT mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
+
+/* Validates an entire archive by calling mz_zip_validate_file() on each file. */
+MINIZ_EXPORT mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags);
+
+/* Misc utils/helpers, valid for ZIP reading or writing */
+MINIZ_EXPORT mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr);
+MINIZ_EXPORT mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr);
+
+/* Universal end function - calls either mz_zip_reader_end() or mz_zip_writer_end(). */
+MINIZ_EXPORT mz_bool mz_zip_end(mz_zip_archive *pZip);
+
+/* -------- ZIP writing */
+
+#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
+
+/* Inits a ZIP archive writer. */
+/*Set pZip->m_pWrite (and pZip->m_pIO_opaque) before calling mz_zip_writer_init or mz_zip_writer_init_v2*/
+/*The output is streamable, i.e. file_ofs in mz_file_write_func always increases only by n*/
+MINIZ_EXPORT mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size);
+MINIZ_EXPORT mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags);
+
+MINIZ_EXPORT mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size);
+MINIZ_EXPORT mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags);
+
+#ifndef MINIZ_NO_STDIO
+MINIZ_EXPORT mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning);
+MINIZ_EXPORT mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags);
+MINIZ_EXPORT mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags);
+#endif
+
+/* Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive. */
+/* For archives opened using mz_zip_reader_init_file, pFilename must be the archive's filename so it can be reopened for writing. If the file can't be reopened, mz_zip_reader_end() will be called. */
+/* For archives opened using mz_zip_reader_init_mem, the memory block must be growable using the realloc callback (which defaults to realloc unless you've overridden it). */
+/* Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL. */
+/* Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before */
+/* the archive is finalized the file's central directory will be hosed. */
+MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename);
+MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags);
+
+/* Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive. */
+/* To add a directory entry, call this method with an archive name ending in a forwardslash with an empty buffer. */
+/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
+MINIZ_EXPORT mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags);
+
+/* Like mz_zip_writer_add_mem(), except you can specify a file comment field, and optionally supply the function with already compressed data. */
+/* uncomp_size/uncomp_crc32 are only used if the MZ_ZIP_FLAG_COMPRESSED_DATA flag is specified. */
+MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
+ mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);
+
+MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
+ mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
+ const char *user_extra_data_central, mz_uint user_extra_data_central_len);
+
+/* Adds the contents of a file to an archive. This function also records the disk file's modified time into the archive. */
+/* File data is supplied via a read callback function. User mz_zip_writer_add_(c)file to add a file directly.*/
+MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 max_size,
+ const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
+ const char *user_extra_data_central, mz_uint user_extra_data_central_len);
+
+
+#ifndef MINIZ_NO_STDIO
+/* Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. */
+/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
+MINIZ_EXPORT mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
+
+/* Like mz_zip_writer_add_file(), except the file data is read from the specified FILE stream. */
+MINIZ_EXPORT mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size,
+ const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
+ const char *user_extra_data_central, mz_uint user_extra_data_central_len);
+#endif
+
+/* Adds a file to an archive by fully cloning the data from another archive. */
+/* This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data (it may add or modify the zip64 local header extra data field), and the optional descriptor following the compressed data. */
+MINIZ_EXPORT mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index);
+
+/* Finalizes the archive by writing the central directory records followed by the end of central directory record. */
+/* After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end(). */
+/* An archive must be manually finalized by calling this function for it to be valid. */
+MINIZ_EXPORT mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip);
+
+/* Finalizes a heap archive, returning a poiner to the heap block and its size. */
+/* The heap block will be allocated using the mz_zip_archive's alloc/realloc callbacks. */
+MINIZ_EXPORT mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize);
+
+/* Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used. */
+/* Note for the archive to be valid, it *must* have been finalized before ending (this function will not do it for you). */
+MINIZ_EXPORT mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
+
+/* -------- Misc. high-level helper functions: */
+
+/* mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive. */
+/* Note this is NOT a fully safe operation. If it crashes or dies in some way your archive can be left in a screwed up state (without a central directory). */
+/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
+/* TODO: Perhaps add an option to leave the existing central dir in place in case the add dies? We could then truncate the file (so the old central dir would be at the end) if something goes wrong. */
+MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
+MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr);
+
+/* Reads a single file from an archive into a heap block. */
+/* If pComment is not NULL, only the file with the specified comment will be extracted. */
+/* Returns NULL on failure. */
+MINIZ_EXPORT void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags);
+MINIZ_EXPORT void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr);
+
+#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MINIZ_NO_ARCHIVE_APIS */
diff --git a/graphics/asymptote/cudareflect/tinyexr/deps/miniz/readme.md b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/readme.md
new file mode 100644
index 0000000000..3f8fd73247
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/deps/miniz/readme.md
@@ -0,0 +1,34 @@
+## Miniz
+
+Miniz is a lossless, high performance data compression library in a single source file that implements the zlib (RFC 1950) and Deflate (RFC 1951) compressed data format specification standards. It supports the most commonly used functions exported by the zlib library, but is a completely independent implementation so zlib's licensing requirements do not apply. Miniz also contains simple to use functions for writing .PNG format image files and reading/writing/appending .ZIP format archives. Miniz's compression speed has been tuned to be comparable to zlib's, and it also has a specialized real-time compressor function designed to compare well against fastlz/minilzo.
+
+## Usage
+
+Please use the files from the [releases page](https://github.com/richgel999/miniz/releases) in your projects. Do not use the git checkout directly! The different source and header files are [amalgamated](https://www.sqlite.org/amalgamation.html) into one `miniz.c`/`miniz.h` pair in a build step (`amalgamate.sh`). Include `miniz.c` and `miniz.h` in your project to use Miniz.
+
+## Features
+
+* MIT licensed
+* A portable, single source and header file library written in plain C. Tested with GCC, clang and Visual Studio.
+* Easily tuned and trimmed down by defines
+* A drop-in replacement for zlib's most used API's (tested in several open source projects that use zlib, such as libpng and libzip).
+* Fills a single threaded performance vs. compression ratio gap between several popular real-time compressors and zlib. For example, at level 1, miniz.c compresses around 5-9% better than minilzo, but is approx. 35% slower. At levels 2-9, miniz.c is designed to compare favorably against zlib's ratio and speed. See the miniz performance comparison page for example timings.
+* Not a block based compressor: miniz.c fully supports stream based processing using a coroutine-style implementation. The zlib-style API functions can be called a single byte at a time if that's all you've got.
+* Easy to use. The low-level compressor (tdefl) and decompressor (tinfl) have simple state structs which can be saved/restored as needed with simple memcpy's. The low-level codec API's don't use the heap in any way.
+* Entire inflater (including optional zlib header parsing and Adler-32 checking) is implemented in a single function as a coroutine, which is separately available in a small (~550 line) source file: miniz_tinfl.c
+* A fairly complete (but totally optional) set of .ZIP archive manipulation and extraction API's. The archive functionality is intended to solve common problems encountered in embedded, mobile, or game development situations. (The archive API's are purposely just powerful enough to write an entire archiver given a bit of additional higher-level logic.)
+
+## Known Problems
+
+* No support for encrypted archives. Not sure how useful this stuff is in practice.
+* Minimal documentation. The assumption is that the user is already familiar with the basic zlib API. I need to write an API wiki - for now I've tried to place key comments before each enum/API, and I've included 6 examples that demonstrate how to use the module's major features.
+
+## Special Thanks
+
+Thanks to Alex Evans for the PNG writer function. Also, thanks to Paul Holden and Thorsten Scheuermann for feedback and testing, Matt Pritchard for all his encouragement, and Sean Barrett's various public domain libraries for inspiration (and encouraging me to write miniz.c in C, which was much more enjoyable and less painful than I thought it would be considering I've been programming in C++ for so long).
+
+Thanks to Bruce Dawson for reporting a problem with the level_and_flags archive API parameter (which is fixed in v1.12) and general feedback, and Janez Zemva for indirectly encouraging me into writing more examples.
+
+## Patents
+
+I was recently asked if miniz avoids patent issues. miniz purposely uses the same core algorithms as the ones used by zlib. The compressor uses vanilla hash chaining as described [here](https://datatracker.ietf.org/doc/html/rfc1951#section-4). Also see the [gzip FAQ](https://web.archive.org/web/20160308045258/http://www.gzip.org/#faq11). In my opinion, if miniz falls prey to a patent attack then zlib/gzip are likely to be at serious risk too.
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/common/cxxopts.hpp b/graphics/asymptote/cudareflect/tinyexr/examples/common/cxxopts.hpp
new file mode 100644
index 0000000000..6a6a85f035
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/common/cxxopts.hpp
@@ -0,0 +1,1988 @@
+/*
+
+Copyright (c) 2014, 2015, 2016, 2017 Jarryd Beck
+
+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
+AUTHORS OR COPYRIGHT HOLDERS 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.
+
+*/
+
+#ifndef CXXOPTS_HPP_INCLUDED
+#define CXXOPTS_HPP_INCLUDED
+
+#include <cstring>
+#include <cctype>
+#include <exception>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <regex>
+#include <sstream>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+namespace cxxopts
+{
+ static constexpr struct {
+ uint8_t major, minor, patch;
+ } version = {2, 1, 0};
+}
+
+//when we ask cxxopts to use Unicode, help strings are processed using ICU,
+//which results in the correct lengths being computed for strings when they
+//are formatted for the help output
+//it is necessary to make sure that <unicode/unistr.h> can be found by the
+//compiler, and that icu-uc is linked in to the binary.
+
+#ifdef CXXOPTS_USE_UNICODE
+#include <unicode/unistr.h>
+
+namespace cxxopts
+{
+ typedef icu::UnicodeString String;
+
+ inline
+ String
+ toLocalString(std::string s)
+ {
+ return icu::UnicodeString::fromUTF8(std::move(s));
+ }
+
+ class UnicodeStringIterator : public
+ std::iterator<std::forward_iterator_tag, int32_t>
+ {
+ public:
+
+ UnicodeStringIterator(const icu::UnicodeString* string, int32_t pos)
+ : s(string)
+ , i(pos)
+ {
+ }
+
+ value_type
+ operator*() const
+ {
+ return s->char32At(i);
+ }
+
+ bool
+ operator==(const UnicodeStringIterator& rhs) const
+ {
+ return s == rhs.s && i == rhs.i;
+ }
+
+ bool
+ operator!=(const UnicodeStringIterator& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
+ UnicodeStringIterator&
+ operator++()
+ {
+ ++i;
+ return *this;
+ }
+
+ UnicodeStringIterator
+ operator+(int32_t v)
+ {
+ return UnicodeStringIterator(s, i + v);
+ }
+
+ private:
+ const icu::UnicodeString* s;
+ int32_t i;
+ };
+
+ inline
+ String&
+ stringAppend(String&s, String a)
+ {
+ return s.append(std::move(a));
+ }
+
+ inline
+ String&
+ stringAppend(String& s, int n, UChar32 c)
+ {
+ for (int i = 0; i != n; ++i)
+ {
+ s.append(c);
+ }
+
+ return s;
+ }
+
+ template <typename Iterator>
+ String&
+ stringAppend(String& s, Iterator begin, Iterator end)
+ {
+ while (begin != end)
+ {
+ s.append(*begin);
+ ++begin;
+ }
+
+ return s;
+ }
+
+ inline
+ size_t
+ stringLength(const String& s)
+ {
+ return s.length();
+ }
+
+ inline
+ std::string
+ toUTF8String(const String& s)
+ {
+ std::string result;
+ s.toUTF8String(result);
+
+ return result;
+ }
+
+ inline
+ bool
+ empty(const String& s)
+ {
+ return s.isEmpty();
+ }
+}
+
+namespace std
+{
+ inline
+ cxxopts::UnicodeStringIterator
+ begin(const icu::UnicodeString& s)
+ {
+ return cxxopts::UnicodeStringIterator(&s, 0);
+ }
+
+ inline
+ cxxopts::UnicodeStringIterator
+ end(const icu::UnicodeString& s)
+ {
+ return cxxopts::UnicodeStringIterator(&s, s.length());
+ }
+}
+
+//ifdef CXXOPTS_USE_UNICODE
+#else
+
+namespace cxxopts
+{
+ typedef std::string String;
+
+ template <typename T>
+ T
+ toLocalString(T&& t)
+ {
+ return t;
+ }
+
+ inline
+ size_t
+ stringLength(const String& s)
+ {
+ return s.length();
+ }
+
+ inline
+ String&
+ stringAppend(String&s, String a)
+ {
+ return s.append(std::move(a));
+ }
+
+ inline
+ String&
+ stringAppend(String& s, size_t n, char c)
+ {
+ return s.append(n, c);
+ }
+
+ template <typename Iterator>
+ String&
+ stringAppend(String& s, Iterator begin, Iterator end)
+ {
+ return s.append(begin, end);
+ }
+
+ template <typename T>
+ std::string
+ toUTF8String(T&& t)
+ {
+ return std::forward<T>(t);
+ }
+
+ inline
+ bool
+ empty(const std::string& s)
+ {
+ return s.empty();
+ }
+}
+
+//ifdef CXXOPTS_USE_UNICODE
+#endif
+
+namespace cxxopts
+{
+ namespace
+ {
+#ifdef _WIN32
+ const std::string LQUOTE("\'");
+ const std::string RQUOTE("\'");
+#else
+ const std::string LQUOTE("‘");
+ const std::string RQUOTE("’");
+#endif
+ }
+
+ class Value : public std::enable_shared_from_this<Value>
+ {
+ public:
+
+ virtual ~Value() = default;
+
+ virtual
+ std::shared_ptr<Value>
+ clone() const = 0;
+
+ virtual void
+ parse(const std::string& text) const = 0;
+
+ virtual void
+ parse() const = 0;
+
+ virtual bool
+ has_default() const = 0;
+
+ virtual bool
+ is_container() const = 0;
+
+ virtual bool
+ has_implicit() const = 0;
+
+ virtual std::string
+ get_default_value() const = 0;
+
+ virtual std::string
+ get_implicit_value() const = 0;
+
+ virtual std::shared_ptr<Value>
+ default_value(const std::string& value) = 0;
+
+ virtual std::shared_ptr<Value>
+ implicit_value(const std::string& value) = 0;
+
+ virtual bool
+ is_boolean() const = 0;
+ };
+
+ class OptionException : public std::exception
+ {
+ public:
+ OptionException(const std::string& message)
+ : m_message(message)
+ {
+ }
+
+ virtual const char*
+ what() const noexcept
+ {
+ return m_message.c_str();
+ }
+
+ private:
+ std::string m_message;
+ };
+
+ class OptionSpecException : public OptionException
+ {
+ public:
+
+ OptionSpecException(const std::string& message)
+ : OptionException(message)
+ {
+ }
+ };
+
+ class OptionParseException : public OptionException
+ {
+ public:
+ OptionParseException(const std::string& message)
+ : OptionException(message)
+ {
+ }
+ };
+
+ class option_exists_error : public OptionSpecException
+ {
+ public:
+ option_exists_error(const std::string& option)
+ : OptionSpecException(u8"Option " + LQUOTE + option + RQUOTE + u8" already exists")
+ {
+ }
+ };
+
+ class invalid_option_format_error : public OptionSpecException
+ {
+ public:
+ invalid_option_format_error(const std::string& format)
+ : OptionSpecException(u8"Invalid option format " + LQUOTE + format + RQUOTE)
+ {
+ }
+ };
+
+ class option_not_exists_exception : public OptionParseException
+ {
+ public:
+ option_not_exists_exception(const std::string& option)
+ : OptionParseException(u8"Option " + LQUOTE + option + RQUOTE + u8" does not exist")
+ {
+ }
+ };
+
+ class missing_argument_exception : public OptionParseException
+ {
+ public:
+ missing_argument_exception(const std::string& option)
+ : OptionParseException(
+ u8"Option " + LQUOTE + option + RQUOTE + u8" is missing an argument"
+ )
+ {
+ }
+ };
+
+ class option_requires_argument_exception : public OptionParseException
+ {
+ public:
+ option_requires_argument_exception(const std::string& option)
+ : OptionParseException(
+ u8"Option " + LQUOTE + option + RQUOTE + u8" requires an argument"
+ )
+ {
+ }
+ };
+
+ class option_not_has_argument_exception : public OptionParseException
+ {
+ public:
+ option_not_has_argument_exception
+ (
+ const std::string& option,
+ const std::string& arg
+ )
+ : OptionParseException(
+ u8"Option " + LQUOTE + option + RQUOTE +
+ u8" does not take an argument, but argument " +
+ LQUOTE + arg + RQUOTE + " given"
+ )
+ {
+ }
+ };
+
+ class option_not_present_exception : public OptionParseException
+ {
+ public:
+ option_not_present_exception(const std::string& option)
+ : OptionParseException(u8"Option " + LQUOTE + option + RQUOTE + u8" not present")
+ {
+ }
+ };
+
+ class argument_incorrect_type : public OptionParseException
+ {
+ public:
+ argument_incorrect_type
+ (
+ const std::string& arg
+ )
+ : OptionParseException(
+ u8"Argument " + LQUOTE + arg + RQUOTE + u8" failed to parse"
+ )
+ {
+ }
+ };
+
+ class option_required_exception : public OptionParseException
+ {
+ public:
+ option_required_exception(const std::string& option)
+ : OptionParseException(
+ u8"Option " + LQUOTE + option + RQUOTE + u8" is required but not present"
+ )
+ {
+ }
+ };
+
+ namespace values
+ {
+ namespace
+ {
+ std::basic_regex<char> integer_pattern
+ ("(-)?(0x)?([1-9a-zA-Z][0-9a-zA-Z]*)|((0x)?0)");
+ std::basic_regex<char> truthy_pattern
+ ("(t|T)(rue)?");
+ std::basic_regex<char> falsy_pattern
+ ("((f|F)(alse)?)?");
+ }
+
+ namespace detail
+ {
+ template <typename T, bool B>
+ struct SignedCheck;
+
+ template <typename T>
+ struct SignedCheck<T, true>
+ {
+ template <typename U>
+ void
+ operator()(bool negative, U u, const std::string& text)
+ {
+ if (negative)
+ {
+ if (u > static_cast<U>(-std::numeric_limits<T>::min()))
+ {
+ throw argument_incorrect_type(text);
+ }
+ }
+ else
+ {
+ if (u > static_cast<U>(std::numeric_limits<T>::max()))
+ {
+ throw argument_incorrect_type(text);
+ }
+ }
+ }
+ };
+
+ template <typename T>
+ struct SignedCheck<T, false>
+ {
+ template <typename U>
+ void
+ operator()(bool, U, const std::string&) {}
+ };
+
+ template <typename T, typename U>
+ void
+ check_signed_range(bool negative, U value, const std::string& text)
+ {
+ SignedCheck<T, std::numeric_limits<T>::is_signed>()(negative, value, text);
+ }
+ }
+
+ template <typename R, typename T>
+ R
+ checked_negate(T&& t, const std::string&, std::true_type)
+ {
+ // if we got to here, then `t` is a positive number that fits into
+ // `R`. So to avoid MSVC C4146, we first cast it to `R`.
+ // See https://github.com/jarro2783/cxxopts/issues/62 for more details.
+ return -static_cast<R>(t);
+ }
+
+ template <typename R, typename T>
+ T
+ checked_negate(T&&, const std::string& text, std::false_type)
+ {
+ throw argument_incorrect_type(text);
+ }
+
+ template <typename T>
+ void
+ integer_parser(const std::string& text, T& value)
+ {
+ std::smatch match;
+ std::regex_match(text, match, integer_pattern);
+
+ if (match.length() == 0)
+ {
+ throw argument_incorrect_type(text);
+ }
+
+ if (match.length(4) > 0)
+ {
+ value = 0;
+ return;
+ }
+
+ using US = typename std::make_unsigned<T>::type;
+
+ constexpr auto umax = std::numeric_limits<US>::max();
+ constexpr bool is_signed = std::numeric_limits<T>::is_signed;
+ const bool negative = match.length(1) > 0;
+ const uint8_t base = match.length(2) > 0 ? 16 : 10;
+
+ auto value_match = match[3];
+
+ US result = 0;
+
+ for (auto iter = value_match.first; iter != value_match.second; ++iter)
+ {
+ size_t digit = 0;
+
+ if (*iter >= '0' && *iter <= '9')
+ {
+ digit = *iter - '0';
+ }
+ else if (base == 16 && *iter >= 'a' && *iter <= 'f')
+ {
+ digit = *iter - 'a' + 10;
+ }
+ else if (base == 16 && *iter >= 'A' && *iter <= 'F')
+ {
+ digit = *iter - 'A' + 10;
+ }
+ else
+ {
+ throw argument_incorrect_type(text);
+ }
+
+ if (umax - digit < result * base)
+ {
+ throw argument_incorrect_type(text);
+ }
+
+ result = result * base + digit;
+ }
+
+ detail::check_signed_range<T>(negative, result, text);
+
+ if (negative)
+ {
+ value = checked_negate<T>(result,
+ text,
+ std::integral_constant<bool, is_signed>());
+ }
+ else
+ {
+ value = result;
+ }
+ }
+
+ template <typename T>
+ void stringstream_parser(const std::string& text, T& value)
+ {
+ std::stringstream in(text);
+ in >> value;
+ if (!in) {
+ throw argument_incorrect_type(text);
+ }
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, uint8_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, int8_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, uint16_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, int16_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, uint32_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, int32_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, uint64_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, int64_t& value)
+ {
+ integer_parser(text, value);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, bool& value)
+ {
+ std::smatch result;
+ std::regex_match(text, result, truthy_pattern);
+
+ if (!result.empty())
+ {
+ value = true;
+ return;
+ }
+
+ std::regex_match(text, result, falsy_pattern);
+ if (!result.empty())
+ {
+ value = false;
+ return;
+ }
+
+ throw argument_incorrect_type(text);
+ }
+
+ inline
+ void
+ parse_value(const std::string& text, std::string& value)
+ {
+ value = text;
+ }
+
+ // The fallback parser. It uses the stringstream parser to parse all types
+ // that have not been overloaded explicitly. It has to be placed in the
+ // source code before all other more specialized templates.
+ template <typename T>
+ void
+ parse_value(const std::string& text, T& value) {
+ stringstream_parser(text, value);
+ }
+
+ template <typename T>
+ void
+ parse_value(const std::string& text, std::vector<T>& value)
+ {
+ T v;
+ parse_value(text, v);
+ value.push_back(v);
+ }
+
+ template <typename T>
+ struct type_is_container
+ {
+ static constexpr bool value = false;
+ };
+
+ template <typename T>
+ struct type_is_container<std::vector<T>>
+ {
+ static constexpr bool value = true;
+ };
+
+ template <typename T>
+ class abstract_value : public Value
+ {
+ using Self = abstract_value<T>;
+
+ public:
+ abstract_value()
+ : m_result(std::make_shared<T>())
+ , m_store(m_result.get())
+ {
+ }
+
+ abstract_value(T* t)
+ : m_store(t)
+ {
+ }
+
+ virtual ~abstract_value() = default;
+
+ abstract_value(const abstract_value& rhs)
+ {
+ if (rhs.m_result)
+ {
+ m_result = std::make_shared<T>();
+ m_store = m_result.get();
+ }
+ else
+ {
+ m_store = rhs.m_store;
+ }
+
+ m_default = rhs.m_default;
+ m_implicit = rhs.m_implicit;
+ m_default_value = rhs.m_default_value;
+ m_implicit_value = rhs.m_implicit_value;
+ }
+
+ void
+ parse(const std::string& text) const
+ {
+ parse_value(text, *m_store);
+ }
+
+ bool
+ is_container() const
+ {
+ return type_is_container<T>::value;
+ }
+
+ void
+ parse() const
+ {
+ parse_value(m_default_value, *m_store);
+ }
+
+ bool
+ has_default() const
+ {
+ return m_default;
+ }
+
+ bool
+ has_implicit() const
+ {
+ return m_implicit;
+ }
+
+ std::shared_ptr<Value>
+ default_value(const std::string& value)
+ {
+ m_default = true;
+ m_default_value = value;
+ return shared_from_this();
+ }
+
+ std::shared_ptr<Value>
+ implicit_value(const std::string& value)
+ {
+ m_implicit = true;
+ m_implicit_value = value;
+ return shared_from_this();
+ }
+
+ std::string
+ get_default_value() const
+ {
+ return m_default_value;
+ }
+
+ std::string
+ get_implicit_value() const
+ {
+ return m_implicit_value;
+ }
+
+ bool
+ is_boolean() const
+ {
+ return std::is_same<T, bool>::value;
+ }
+
+ const T&
+ get() const
+ {
+ if (m_store == nullptr)
+ {
+ return *m_result;
+ }
+ else
+ {
+ return *m_store;
+ }
+ }
+
+ protected:
+ std::shared_ptr<T> m_result;
+ T* m_store;
+
+ bool m_default = false;
+ bool m_implicit = false;
+
+ std::string m_default_value;
+ std::string m_implicit_value;
+ };
+
+ template <typename T>
+ class standard_value : public abstract_value<T>
+ {
+ public:
+ using abstract_value<T>::abstract_value;
+
+ std::shared_ptr<Value>
+ clone() const
+ {
+ return std::make_shared<standard_value<T>>(*this);
+ }
+ };
+
+ template <>
+ class standard_value<bool> : public abstract_value<bool>
+ {
+ public:
+ ~standard_value() = default;
+
+ standard_value()
+ {
+ set_implicit();
+ }
+
+ standard_value(bool* b)
+ : abstract_value(b)
+ {
+ set_implicit();
+ }
+
+ std::shared_ptr<Value>
+ clone() const
+ {
+ return std::make_shared<standard_value<bool>>(*this);
+ }
+
+ private:
+
+ void
+ set_implicit()
+ {
+ m_implicit = true;
+ m_implicit_value = "true";
+ }
+ };
+ }
+
+ template <typename T>
+ std::shared_ptr<Value>
+ value()
+ {
+ return std::make_shared<values::standard_value<T>>();
+ }
+
+ template <typename T>
+ std::shared_ptr<Value>
+ value(T& t)
+ {
+ return std::make_shared<values::standard_value<T>>(&t);
+ }
+
+ class OptionAdder;
+
+ class OptionDetails
+ {
+ public:
+ OptionDetails
+ (
+ const std::string& short_,
+ const std::string& long_,
+ const String& desc,
+ std::shared_ptr<const Value> val
+ )
+ : m_short(short_)
+ , m_long(long_)
+ , m_desc(desc)
+ , m_value(val)
+ , m_count(0)
+ {
+ }
+
+ OptionDetails(const OptionDetails& rhs)
+ : m_desc(rhs.m_desc)
+ , m_count(rhs.m_count)
+ {
+ m_value = rhs.m_value->clone();
+ }
+
+ OptionDetails(OptionDetails&& rhs) = default;
+
+ const String&
+ description() const
+ {
+ return m_desc;
+ }
+
+ const Value& value() const {
+ return *m_value;
+ }
+
+ std::shared_ptr<Value>
+ make_storage() const
+ {
+ return m_value->clone();
+ }
+
+ const std::string&
+ short_name() const
+ {
+ return m_short;
+ }
+
+ const std::string&
+ long_name() const
+ {
+ return m_long;
+ }
+
+ private:
+ std::string m_short;
+ std::string m_long;
+ String m_desc;
+ std::shared_ptr<const Value> m_value;
+ int m_count;
+ };
+
+ struct HelpOptionDetails
+ {
+ std::string s;
+ std::string l;
+ String desc;
+ bool has_default;
+ std::string default_value;
+ bool has_implicit;
+ std::string implicit_value;
+ std::string arg_help;
+ bool is_container;
+ bool is_boolean;
+ };
+
+ struct HelpGroupDetails
+ {
+ std::string name;
+ std::string description;
+ std::vector<HelpOptionDetails> options;
+ };
+
+ class OptionValue
+ {
+ public:
+ void
+ parse
+ (
+ std::shared_ptr<const OptionDetails> details,
+ const std::string& text
+ )
+ {
+ ensure_value(details);
+ ++m_count;
+ m_value->parse(text);
+ }
+
+ void
+ parse_default(std::shared_ptr<const OptionDetails> details)
+ {
+ ensure_value(details);
+ m_value->parse();
+ m_count++;
+ }
+
+ size_t
+ count() const
+ {
+ return m_count;
+ }
+
+ template <typename T>
+ const T&
+ as() const
+ {
+#ifdef CXXOPTS_NO_RTTI
+ return static_cast<const values::standard_value<T>&>(*m_value).get();
+#else
+ return dynamic_cast<const values::standard_value<T>&>(*m_value).get();
+#endif
+ }
+
+ private:
+ void
+ ensure_value(std::shared_ptr<const OptionDetails> details)
+ {
+ if (m_value == nullptr)
+ {
+ m_value = details->make_storage();
+ }
+ }
+
+ std::shared_ptr<Value> m_value;
+ size_t m_count = 0;
+ };
+
+ class KeyValue
+ {
+ public:
+ KeyValue(std::string key_, std::string value_)
+ : m_key(std::move(key_))
+ , m_value(std::move(value_))
+ {
+ }
+
+ const
+ std::string&
+ key() const
+ {
+ return m_key;
+ }
+
+ const std::string
+ value() const
+ {
+ return m_value;
+ }
+
+ template <typename T>
+ T
+ as() const
+ {
+ T result;
+ values::parse_value(m_value, result);
+ return result;
+ }
+
+ private:
+ std::string m_key;
+ std::string m_value;
+ };
+
+ class ParseResult
+ {
+ public:
+
+ ParseResult(
+ const std::unordered_map<std::string, std::shared_ptr<OptionDetails>>&,
+ std::vector<std::string>,
+ int&, char**&);
+
+ size_t
+ count(const std::string& o) const
+ {
+ auto iter = m_options.find(o);
+ if (iter == m_options.end())
+ {
+ return 0;
+ }
+
+ auto riter = m_results.find(iter->second);
+
+ return riter->second.count();
+ }
+
+ const OptionValue&
+ operator[](const std::string& option) const
+ {
+ auto iter = m_options.find(option);
+
+ if (iter == m_options.end())
+ {
+ throw option_not_present_exception(option);
+ }
+
+ auto riter = m_results.find(iter->second);
+
+ return riter->second;
+ }
+
+ const std::vector<KeyValue>&
+ arguments() const
+ {
+ return m_sequential;
+ }
+
+ private:
+
+ OptionValue&
+ get_option(std::shared_ptr<OptionDetails>);
+
+ void
+ parse(int& argc, char**& argv);
+
+ void
+ add_to_option(const std::string& option, const std::string& arg);
+
+ bool
+ consume_positional(std::string a);
+
+ void
+ parse_option
+ (
+ std::shared_ptr<OptionDetails> value,
+ const std::string& name,
+ const std::string& arg = ""
+ );
+
+ void
+ parse_default(std::shared_ptr<OptionDetails> details);
+
+ void
+ checked_parse_arg
+ (
+ int argc,
+ char* argv[],
+ int& current,
+ std::shared_ptr<OptionDetails> value,
+ const std::string& name
+ );
+
+ const std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
+ &m_options;
+ std::vector<std::string> m_positional;
+ std::vector<std::string>::iterator m_next_positional;
+ std::unordered_set<std::string> m_positional_set;
+ std::unordered_map<std::shared_ptr<OptionDetails>, OptionValue> m_results;
+
+ std::vector<KeyValue> m_sequential;
+ };
+
+ class Options
+ {
+ public:
+
+ Options(std::string program, std::string help_string = "")
+ : m_program(std::move(program))
+ , m_help_string(toLocalString(std::move(help_string)))
+ , m_custom_help("[OPTION...]")
+ , m_positional_help("positional parameters")
+ , m_show_positional(false)
+ , m_next_positional(m_positional.end())
+ {
+ }
+
+ Options&
+ positional_help(std::string help_text)
+ {
+ m_positional_help = std::move(help_text);
+ return *this;
+ }
+
+ Options&
+ custom_help(std::string help_text)
+ {
+ m_custom_help = std::move(help_text);
+ return *this;
+ }
+
+ Options&
+ show_positional_help()
+ {
+ m_show_positional = true;
+ return *this;
+ }
+
+ ParseResult
+ parse(int& argc, char**& argv);
+
+ OptionAdder
+ add_options(std::string group = "");
+
+ void
+ add_option
+ (
+ const std::string& group,
+ const std::string& s,
+ const std::string& l,
+ std::string desc,
+ std::shared_ptr<const Value> value,
+ std::string arg_help
+ );
+
+ //parse positional arguments into the given option
+ void
+ parse_positional(std::string option);
+
+ void
+ parse_positional(std::vector<std::string> options);
+
+ void
+ parse_positional(std::initializer_list<std::string> options);
+
+ std::string
+ help(const std::vector<std::string>& groups = {""}) const;
+
+ const std::vector<std::string>
+ groups() const;
+
+ const HelpGroupDetails&
+ group_help(const std::string& group) const;
+
+ private:
+
+ void
+ add_one_option
+ (
+ const std::string& option,
+ std::shared_ptr<OptionDetails> details
+ );
+
+ String
+ help_one_group(const std::string& group) const;
+
+ void
+ generate_group_help
+ (
+ String& result,
+ const std::vector<std::string>& groups
+ ) const;
+
+ void
+ generate_all_groups_help(String& result) const;
+
+ std::string m_program;
+ String m_help_string;
+ std::string m_custom_help;
+ std::string m_positional_help;
+ bool m_show_positional;
+
+ std::unordered_map<std::string, std::shared_ptr<OptionDetails>> m_options;
+ std::vector<std::string> m_positional;
+ std::vector<std::string>::iterator m_next_positional;
+ std::unordered_set<std::string> m_positional_set;
+
+ //mapping from groups to help options
+ std::map<std::string, HelpGroupDetails> m_help;
+ };
+
+ class OptionAdder
+ {
+ public:
+
+ OptionAdder(Options& options, std::string group)
+ : m_options(options), m_group(std::move(group))
+ {
+ }
+
+ OptionAdder&
+ operator()
+ (
+ const std::string& opts,
+ const std::string& desc,
+ std::shared_ptr<const Value> value
+ = ::cxxopts::value<bool>(),
+ std::string arg_help = ""
+ );
+
+ private:
+ Options& m_options;
+ std::string m_group;
+ };
+
+ namespace
+ {
+ constexpr int OPTION_LONGEST = 30;
+ constexpr int OPTION_DESC_GAP = 2;
+
+ std::basic_regex<char> option_matcher
+ ("--([[:alnum:]][-_[:alnum:]]+)(=(.*))?|-([[:alnum:]]+)");
+
+ std::basic_regex<char> option_specifier
+ ("(([[:alnum:]]),)?[ ]*([[:alnum:]][-_[:alnum:]]*)?");
+
+ String
+ format_option
+ (
+ const HelpOptionDetails& o
+ )
+ {
+ auto& s = o.s;
+ auto& l = o.l;
+
+ String result = " ";
+
+ if (s.size() > 0)
+ {
+ result += "-" + toLocalString(s) + ",";
+ }
+ else
+ {
+ result += " ";
+ }
+
+ if (l.size() > 0)
+ {
+ result += " --" + toLocalString(l);
+ }
+
+ auto arg = o.arg_help.size() > 0 ? toLocalString(o.arg_help) : "arg";
+
+ if (!o.is_boolean)
+ {
+ if (o.has_implicit)
+ {
+ result += " [=" + arg + "(=" + toLocalString(o.implicit_value) + ")]";
+ }
+ else
+ {
+ result += " " + arg;
+ }
+ }
+
+ return result;
+ }
+
+ String
+ format_description
+ (
+ const HelpOptionDetails& o,
+ size_t start,
+ size_t width
+ )
+ {
+ auto desc = o.desc;
+
+ if (o.has_default)
+ {
+ desc += toLocalString(" (default: " + o.default_value + ")");
+ }
+
+ String result;
+
+ auto current = std::begin(desc);
+ auto startLine = current;
+ auto lastSpace = current;
+
+ auto size = size_t{};
+
+ while (current != std::end(desc))
+ {
+ if (*current == ' ')
+ {
+ lastSpace = current;
+ }
+
+ if (size > width)
+ {
+ if (lastSpace == startLine)
+ {
+ stringAppend(result, startLine, current + 1);
+ stringAppend(result, "\n");
+ stringAppend(result, start, ' ');
+ startLine = current + 1;
+ lastSpace = startLine;
+ }
+ else
+ {
+ stringAppend(result, startLine, lastSpace);
+ stringAppend(result, "\n");
+ stringAppend(result, start, ' ');
+ startLine = lastSpace + 1;
+ }
+ size = 0;
+ }
+ else
+ {
+ ++size;
+ }
+
+ ++current;
+ }
+
+ //append whatever is left
+ stringAppend(result, startLine, current);
+
+ return result;
+ }
+ }
+
+inline
+ParseResult::ParseResult
+(
+ const std::unordered_map<std::string, std::shared_ptr<OptionDetails>>& options,
+ std::vector<std::string> positional,
+ int& argc, char**& argv
+)
+: m_options(options)
+, m_positional(std::move(positional))
+, m_next_positional(m_positional.begin())
+{
+ parse(argc, argv);
+}
+
+inline
+OptionAdder
+Options::add_options(std::string group)
+{
+ return OptionAdder(*this, std::move(group));
+}
+
+inline
+OptionAdder&
+OptionAdder::operator()
+(
+ const std::string& opts,
+ const std::string& desc,
+ std::shared_ptr<const Value> value,
+ std::string arg_help
+)
+{
+ std::match_results<const char*> result;
+ std::regex_match(opts.c_str(), result, option_specifier);
+
+ if (result.empty())
+ {
+ throw invalid_option_format_error(opts);
+ }
+
+ const auto& short_match = result[2];
+ const auto& long_match = result[3];
+
+ if (!short_match.length() && !long_match.length())
+ {
+ throw invalid_option_format_error(opts);
+ } else if (long_match.length() == 1 && short_match.length())
+ {
+ throw invalid_option_format_error(opts);
+ }
+
+ auto option_names = []
+ (
+ const std::sub_match<const char*>& short_,
+ const std::sub_match<const char*>& long_
+ )
+ {
+ if (long_.length() == 1)
+ {
+ return std::make_tuple(long_.str(), short_.str());
+ }
+ else
+ {
+ return std::make_tuple(short_.str(), long_.str());
+ }
+ }(short_match, long_match);
+
+ m_options.add_option
+ (
+ m_group,
+ std::get<0>(option_names),
+ std::get<1>(option_names),
+ desc,
+ value,
+ std::move(arg_help)
+ );
+
+ return *this;
+}
+
+inline
+void
+ParseResult::parse_default(std::shared_ptr<OptionDetails> details)
+{
+ m_results[details].parse_default(details);
+}
+
+inline
+void
+ParseResult::parse_option
+(
+ std::shared_ptr<OptionDetails> value,
+ const std::string& /*name*/,
+ const std::string& arg
+)
+{
+ auto& result = m_results[value];
+ result.parse(value, arg);
+
+ m_sequential.emplace_back(value->long_name(), arg);
+}
+
+inline
+void
+ParseResult::checked_parse_arg
+(
+ int argc,
+ char* argv[],
+ int& current,
+ std::shared_ptr<OptionDetails> value,
+ const std::string& name
+)
+{
+ if (current + 1 >= argc)
+ {
+ if (value->value().has_implicit())
+ {
+ parse_option(value, name, value->value().get_implicit_value());
+ }
+ else
+ {
+ throw missing_argument_exception(name);
+ }
+ }
+ else
+ {
+ if (value->value().has_implicit())
+ {
+ parse_option(value, name, value->value().get_implicit_value());
+ }
+ else
+ {
+ parse_option(value, name, argv[current + 1]);
+ ++current;
+ }
+ }
+}
+
+inline
+void
+ParseResult::add_to_option(const std::string& option, const std::string& arg)
+{
+ auto iter = m_options.find(option);
+
+ if (iter == m_options.end())
+ {
+ throw option_not_exists_exception(option);
+ }
+
+ parse_option(iter->second, option, arg);
+}
+
+inline
+bool
+ParseResult::consume_positional(std::string a)
+{
+ while (m_next_positional != m_positional.end())
+ {
+ auto iter = m_options.find(*m_next_positional);
+ if (iter != m_options.end())
+ {
+ auto& result = m_results[iter->second];
+ if (!iter->second->value().is_container())
+ {
+ if (result.count() == 0)
+ {
+ add_to_option(*m_next_positional, a);
+ ++m_next_positional;
+ return true;
+ }
+ else
+ {
+ ++m_next_positional;
+ continue;
+ }
+ }
+ else
+ {
+ add_to_option(*m_next_positional, a);
+ return true;
+ }
+ }
+ ++m_next_positional;
+ }
+
+ return false;
+}
+
+inline
+void
+Options::parse_positional(std::string option)
+{
+ parse_positional(std::vector<std::string>{std::move(option)});
+}
+
+inline
+void
+Options::parse_positional(std::vector<std::string> options)
+{
+ m_positional = std::move(options);
+ m_next_positional = m_positional.begin();
+
+ m_positional_set.insert(m_positional.begin(), m_positional.end());
+}
+
+inline
+void
+Options::parse_positional(std::initializer_list<std::string> options)
+{
+ parse_positional(std::vector<std::string>(std::move(options)));
+}
+
+inline
+ParseResult
+Options::parse(int& argc, char**& argv)
+{
+ ParseResult result(m_options, m_positional, argc, argv);
+ return result;
+}
+
+inline
+void
+ParseResult::parse(int& argc, char**& argv)
+{
+ int current = 1;
+
+ int nextKeep = 1;
+
+ bool consume_remaining = false;
+
+ while (current != argc)
+ {
+ if (strcmp(argv[current], "--") == 0)
+ {
+ consume_remaining = true;
+ ++current;
+ break;
+ }
+
+ std::match_results<const char*> result;
+ std::regex_match(argv[current], result, option_matcher);
+
+ if (result.empty())
+ {
+ //not a flag
+
+ //if true is returned here then it was consumed, otherwise it is
+ //ignored
+ if (consume_positional(argv[current]))
+ {
+ }
+ else
+ {
+ argv[nextKeep] = argv[current];
+ ++nextKeep;
+ }
+ //if we return from here then it was parsed successfully, so continue
+ }
+ else
+ {
+ //short or long option?
+ if (result[4].length() != 0)
+ {
+ const std::string& s = result[4];
+
+ for (std::size_t i = 0; i != s.size(); ++i)
+ {
+ std::string name(1, s[i]);
+ auto iter = m_options.find(name);
+
+ if (iter == m_options.end())
+ {
+ throw option_not_exists_exception(name);
+ }
+
+ auto value = iter->second;
+
+ if (i + 1 == s.size())
+ {
+ //it must be the last argument
+ checked_parse_arg(argc, argv, current, value, name);
+ }
+ else if (value->value().has_implicit())
+ {
+ parse_option(value, name, value->value().get_implicit_value());
+ }
+ else
+ {
+ //error
+ throw option_requires_argument_exception(name);
+ }
+ }
+ }
+ else if (result[1].length() != 0)
+ {
+ const std::string& name = result[1];
+
+ auto iter = m_options.find(name);
+
+ if (iter == m_options.end())
+ {
+ throw option_not_exists_exception(name);
+ }
+
+ auto opt = iter->second;
+
+ //equals provided for long option?
+ if (result[2].length() != 0)
+ {
+ //parse the option given
+
+ parse_option(opt, name, result[3]);
+ }
+ else
+ {
+ //parse the next argument
+ checked_parse_arg(argc, argv, current, opt, name);
+ }
+ }
+
+ }
+
+ ++current;
+ }
+
+ for (auto& opt : m_options)
+ {
+ auto& detail = opt.second;
+ auto& value = detail->value();
+
+ auto& store = m_results[detail];
+
+ if(!store.count() && value.has_default()){
+ parse_default(detail);
+ }
+ }
+
+ if (consume_remaining)
+ {
+ while (current < argc)
+ {
+ if (!consume_positional(argv[current])) {
+ break;
+ }
+ ++current;
+ }
+
+ //adjust argv for any that couldn't be swallowed
+ while (current != argc) {
+ argv[nextKeep] = argv[current];
+ ++nextKeep;
+ ++current;
+ }
+ }
+
+ argc = nextKeep;
+
+}
+
+inline
+void
+Options::add_option
+(
+ const std::string& group,
+ const std::string& s,
+ const std::string& l,
+ std::string desc,
+ std::shared_ptr<const Value> value,
+ std::string arg_help
+)
+{
+ auto stringDesc = toLocalString(std::move(desc));
+ auto option = std::make_shared<OptionDetails>(s, l, stringDesc, value);
+
+ if (s.size() > 0)
+ {
+ add_one_option(s, option);
+ }
+
+ if (l.size() > 0)
+ {
+ add_one_option(l, option);
+ }
+
+ //add the help details
+ auto& options = m_help[group];
+
+ options.options.emplace_back(HelpOptionDetails{s, l, stringDesc,
+ value->has_default(), value->get_default_value(),
+ value->has_implicit(), value->get_implicit_value(),
+ std::move(arg_help),
+ value->is_container(),
+ value->is_boolean()});
+}
+
+inline
+void
+Options::add_one_option
+(
+ const std::string& option,
+ std::shared_ptr<OptionDetails> details
+)
+{
+ auto in = m_options.emplace(option, details);
+
+ if (!in.second)
+ {
+ throw option_exists_error(option);
+ }
+}
+
+inline
+String
+Options::help_one_group(const std::string& g) const
+{
+ typedef std::vector<std::pair<String, String>> OptionHelp;
+
+ auto group = m_help.find(g);
+ if (group == m_help.end())
+ {
+ return "";
+ }
+
+ OptionHelp format;
+
+ size_t longest = 0;
+
+ String result;
+
+ if (!g.empty())
+ {
+ result += toLocalString(" " + g + " options:\n");
+ }
+
+ for (const auto& o : group->second.options)
+ {
+ if (o.is_container &&
+ m_positional_set.find(o.l) != m_positional_set.end() &&
+ !m_show_positional)
+ {
+ continue;
+ }
+
+ auto s = format_option(o);
+ longest = std::max(longest, stringLength(s));
+ format.push_back(std::make_pair(s, String()));
+ }
+
+ longest = std::min(longest, static_cast<size_t>(OPTION_LONGEST));
+
+ //widest allowed description
+ auto allowed = size_t{76} - longest - OPTION_DESC_GAP;
+
+ auto fiter = format.begin();
+ for (const auto& o : group->second.options)
+ {
+ if (o.is_container &&
+ m_positional_set.find(o.l) != m_positional_set.end() &&
+ !m_show_positional)
+ {
+ continue;
+ }
+
+ auto d = format_description(o, longest + OPTION_DESC_GAP, allowed);
+
+ result += fiter->first;
+ if (stringLength(fiter->first) > longest)
+ {
+ result += '\n';
+ result += toLocalString(std::string(longest + OPTION_DESC_GAP, ' '));
+ }
+ else
+ {
+ result += toLocalString(std::string(longest + OPTION_DESC_GAP -
+ stringLength(fiter->first),
+ ' '));
+ }
+ result += d;
+ result += '\n';
+
+ ++fiter;
+ }
+
+ return result;
+}
+
+inline
+void
+Options::generate_group_help
+(
+ String& result,
+ const std::vector<std::string>& print_groups
+) const
+{
+ for (size_t i = 0; i != print_groups.size(); ++i)
+ {
+ const String& group_help_text = help_one_group(print_groups[i]);
+ if (empty(group_help_text))
+ {
+ continue;
+ }
+ result += group_help_text;
+ if (i < print_groups.size() - 1)
+ {
+ result += '\n';
+ }
+ }
+}
+
+inline
+void
+Options::generate_all_groups_help(String& result) const
+{
+ std::vector<std::string> all_groups;
+ all_groups.reserve(m_help.size());
+
+ for (auto& group : m_help)
+ {
+ all_groups.push_back(group.first);
+ }
+
+ generate_group_help(result, all_groups);
+}
+
+inline
+std::string
+Options::help(const std::vector<std::string>& help_groups) const
+{
+ String result = m_help_string + "\nUsage:\n " +
+ toLocalString(m_program) + " " + toLocalString(m_custom_help);
+
+ if (m_positional.size() > 0 && m_positional_help.size() > 0) {
+ result += " " + toLocalString(m_positional_help);
+ }
+
+ result += "\n\n";
+
+ if (help_groups.size() == 0)
+ {
+ generate_all_groups_help(result);
+ }
+ else
+ {
+ generate_group_help(result, help_groups);
+ }
+
+ return toUTF8String(result);
+}
+
+inline
+const std::vector<std::string>
+Options::groups() const
+{
+ std::vector<std::string> g;
+
+ std::transform(
+ m_help.begin(),
+ m_help.end(),
+ std::back_inserter(g),
+ [] (const std::map<std::string, HelpGroupDetails>::value_type& pair)
+ {
+ return pair.first;
+ }
+ );
+
+ return g;
+}
+
+inline
+const HelpGroupDetails&
+Options::group_help(const std::string& group) const
+{
+ return m_help.at(group);
+}
+
+}
+
+#endif //CXXOPTS_HPP_INCLUDED
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image.h b/graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image.h
new file mode 100644
index 0000000000..d9c21bc813
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image.h
@@ -0,0 +1,7462 @@
+/* stb_image - v2.19 - public domain image loader - http://nothings.org/stb
+ no warranty implied; use at your own risk
+
+ Do this:
+ #define STB_IMAGE_IMPLEMENTATION
+ before you include this file in *one* C or C++ file to create the implementation.
+
+ // i.e. it should look like this:
+ #include ...
+ #include ...
+ #include ...
+ #define STB_IMAGE_IMPLEMENTATION
+ #include "stb_image.h"
+
+ You can #define STBI_ASSERT(x) before the #include to avoid using assert.h.
+ And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free
+
+
+ QUICK NOTES:
+ Primarily of interest to game developers and other people who can
+ avoid problematic images and only need the trivial interface
+
+ JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib)
+ PNG 1/2/4/8/16-bit-per-channel
+
+ TGA (not sure what subset, if a subset)
+ BMP non-1bpp, non-RLE
+ PSD (composited view only, no extra channels, 8/16 bit-per-channel)
+
+ GIF (*comp always reports as 4-channel)
+ HDR (radiance rgbE format)
+ PIC (Softimage PIC)
+ PNM (PPM and PGM binary only)
+
+ Animated GIF still needs a proper API, but here's one way to do it:
+ http://gist.github.com/urraka/685d9a6340b26b830d49
+
+ - decode from memory or through FILE (define STBI_NO_STDIO to remove code)
+ - decode from arbitrary I/O callbacks
+ - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON)
+
+ Full documentation under "DOCUMENTATION" below.
+
+
+LICENSE
+
+ See end of file for license information.
+
+RECENT REVISION HISTORY:
+
+ 2.19 (2018-02-11) fix warning
+ 2.18 (2018-01-30) fix warnings
+ 2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings
+ 2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes
+ 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC
+ 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
+ 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes
+ 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
+ 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
+ RGB-format JPEG; remove white matting in PSD;
+ allocate large structures on the stack;
+ correct channel count for PNG & BMP
+ 2.10 (2016-01-22) avoid warning introduced in 2.09
+ 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
+
+ See end of file for full revision history.
+
+
+ ============================ Contributors =========================
+
+ Image formats Extensions, features
+ Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info)
+ Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info)
+ Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG)
+ Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks)
+ Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG)
+ Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip)
+ Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD)
+ github:urraka (animated gif) Junggon Kim (PNM comments)
+ Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA)
+ socks-the-fox (16-bit PNG)
+ Jeremy Sawicki (handle all ImageNet JPGs)
+ Optimizations & bugfixes Mikhail Morozov (1-bit BMP)
+ Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query)
+ Arseny Kapoulkine
+ John-Mark Allen
+
+ Bug & warning fixes
+ Marc LeBlanc David Woo Guillaume George Martins Mozeiko
+ Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan
+ Dave Moore Roy Eltham Hayaki Saito Nathan Reed
+ Won Chun Luke Graham Johan Duparc Nick Verigakis
+ the Horde3D community Thomas Ruf Ronny Chevalier github:rlyeh
+ Janez Zemva John Bartholomew Michal Cichon github:romigrou
+ Jonathan Blow Ken Hamada Tero Hanninen github:svdijk
+ Laurent Gomila Cort Stratton Sergio Gonzalez github:snagar
+ Aruelien Pocheville Thibault Reuille Cass Everitt github:Zelex
+ Ryamond Barbiero Paul Du Bois Engin Manap github:grim210
+ Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw
+ Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus
+ Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo
+ Christian Floisand Kevin Schmidt github:darealshinji
+ Blazej Dariusz Roszkowski github:Michaelangel007
+*/
+
+#ifndef STBI_INCLUDE_STB_IMAGE_H
+#define STBI_INCLUDE_STB_IMAGE_H
+
+// DOCUMENTATION
+//
+// Limitations:
+// - no 12-bit-per-channel JPEG
+// - no JPEGs with arithmetic coding
+// - GIF always returns *comp=4
+//
+// Basic usage (see HDR discussion below for HDR usage):
+// int x,y,n;
+// unsigned char *data = stbi_load(filename, &x, &y, &n, 0);
+// // ... process data if not NULL ...
+// // ... x = width, y = height, n = # 8-bit components per pixel ...
+// // ... replace '0' with '1'..'4' to force that many components per pixel
+// // ... but 'n' will always be the number that it would have been if you said 0
+// stbi_image_free(data)
+//
+// Standard parameters:
+// int *x -- outputs image width in pixels
+// int *y -- outputs image height in pixels
+// int *channels_in_file -- outputs # of image components in image file
+// int desired_channels -- if non-zero, # of image components requested in result
+//
+// The return value from an image loader is an 'unsigned char *' which points
+// to the pixel data, or NULL on an allocation failure or if the image is
+// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels,
+// with each pixel consisting of N interleaved 8-bit components; the first
+// pixel pointed to is top-left-most in the image. There is no padding between
+// image scanlines or between pixels, regardless of format. The number of
+// components N is 'desired_channels' if desired_channels is non-zero, or
+// *channels_in_file otherwise. If desired_channels is non-zero,
+// *channels_in_file has the number of components that _would_ have been
+// output otherwise. E.g. if you set desired_channels to 4, you will always
+// get RGBA output, but you can check *channels_in_file to see if it's trivially
+// opaque because e.g. there were only 3 channels in the source image.
+//
+// An output image with N components has the following components interleaved
+// in this order in each pixel:
+//
+// N=#comp components
+// 1 grey
+// 2 grey, alpha
+// 3 red, green, blue
+// 4 red, green, blue, alpha
+//
+// If image loading fails for any reason, the return value will be NULL,
+// and *x, *y, *channels_in_file will be unchanged. The function
+// stbi_failure_reason() can be queried for an extremely brief, end-user
+// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS
+// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly
+// more user-friendly ones.
+//
+// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized.
+//
+// ===========================================================================
+//
+// Philosophy
+//
+// stb libraries are designed with the following priorities:
+//
+// 1. easy to use
+// 2. easy to maintain
+// 3. good performance
+//
+// Sometimes I let "good performance" creep up in priority over "easy to maintain",
+// and for best performance I may provide less-easy-to-use APIs that give higher
+// performance, in addition to the easy to use ones. Nevertheless, it's important
+// to keep in mind that from the standpoint of you, a client of this library,
+// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all.
+//
+// Some secondary priorities arise directly from the first two, some of which
+// make more explicit reasons why performance can't be emphasized.
+//
+// - Portable ("ease of use")
+// - Small source code footprint ("easy to maintain")
+// - No dependencies ("ease of use")
+//
+// ===========================================================================
+//
+// I/O callbacks
+//
+// I/O callbacks allow you to read from arbitrary sources, like packaged
+// files or some other source. Data read from callbacks are processed
+// through a small internal buffer (currently 128 bytes) to try to reduce
+// overhead.
+//
+// The three functions you must define are "read" (reads some bytes of data),
+// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end).
+//
+// ===========================================================================
+//
+// SIMD support
+//
+// The JPEG decoder will try to automatically use SIMD kernels on x86 when
+// supported by the compiler. For ARM Neon support, you must explicitly
+// request it.
+//
+// (The old do-it-yourself SIMD API is no longer supported in the current
+// code.)
+//
+// On x86, SSE2 will automatically be used when available based on a run-time
+// test; if not, the generic C versions are used as a fall-back. On ARM targets,
+// the typical path is to have separate builds for NEON and non-NEON devices
+// (at least this is true for iOS and Android). Therefore, the NEON support is
+// toggled by a build flag: define STBI_NEON to get NEON loops.
+//
+// If for some reason you do not want to use any of SIMD code, or if
+// you have issues compiling it, you can disable it entirely by
+// defining STBI_NO_SIMD.
+//
+// ===========================================================================
+//
+// HDR image support (disable by defining STBI_NO_HDR)
+//
+// stb_image now supports loading HDR images in general, and currently
+// the Radiance .HDR file format, although the support is provided
+// generically. You can still load any file through the existing interface;
+// if you attempt to load an HDR file, it will be automatically remapped to
+// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
+// both of these constants can be reconfigured through this interface:
+//
+// stbi_hdr_to_ldr_gamma(2.2f);
+// stbi_hdr_to_ldr_scale(1.0f);
+//
+// (note, do not use _inverse_ constants; stbi_image will invert them
+// appropriately).
+//
+// Additionally, there is a new, parallel interface for loading files as
+// (linear) floats to preserve the full dynamic range:
+//
+// float *data = stbi_loadf(filename, &x, &y, &n, 0);
+//
+// If you load LDR images through this interface, those images will
+// be promoted to floating point values, run through the inverse of
+// constants corresponding to the above:
+//
+// stbi_ldr_to_hdr_scale(1.0f);
+// stbi_ldr_to_hdr_gamma(2.2f);
+//
+// Finally, given a filename (or an open file or memory block--see header
+// file for details) containing image data, you can query for the "most
+// appropriate" interface to use (that is, whether the image is HDR or
+// not), using:
+//
+// stbi_is_hdr(char *filename);
+//
+// ===========================================================================
+//
+// iPhone PNG support:
+//
+// By default we convert iphone-formatted PNGs back to RGB, even though
+// they are internally encoded differently. You can disable this conversion
+// by by calling stbi_convert_iphone_png_to_rgb(0), in which case
+// you will always just get the native iphone "format" through (which
+// is BGR stored in RGB).
+//
+// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per
+// pixel to remove any premultiplied alpha *only* if the image file explicitly
+// says there's premultiplied data (currently only happens in iPhone images,
+// and only if iPhone convert-to-rgb processing is on).
+//
+// ===========================================================================
+//
+// ADDITIONAL CONFIGURATION
+//
+// - You can suppress implementation of any of the decoders to reduce
+// your code footprint by #defining one or more of the following
+// symbols before creating the implementation.
+//
+// STBI_NO_JPEG
+// STBI_NO_PNG
+// STBI_NO_BMP
+// STBI_NO_PSD
+// STBI_NO_TGA
+// STBI_NO_GIF
+// STBI_NO_HDR
+// STBI_NO_PIC
+// STBI_NO_PNM (.ppm and .pgm)
+//
+// - You can request *only* certain decoders and suppress all other ones
+// (this will be more forward-compatible, as addition of new decoders
+// doesn't require you to disable them explicitly):
+//
+// STBI_ONLY_JPEG
+// STBI_ONLY_PNG
+// STBI_ONLY_BMP
+// STBI_ONLY_PSD
+// STBI_ONLY_TGA
+// STBI_ONLY_GIF
+// STBI_ONLY_HDR
+// STBI_ONLY_PIC
+// STBI_ONLY_PNM (.ppm and .pgm)
+//
+// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
+// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
+//
+
+
+#ifndef STBI_NO_STDIO
+#include <stdio.h>
+#endif // STBI_NO_STDIO
+
+#define STBI_VERSION 1
+
+enum
+{
+ STBI_default = 0, // only used for desired_channels
+
+ STBI_grey = 1,
+ STBI_grey_alpha = 2,
+ STBI_rgb = 3,
+ STBI_rgb_alpha = 4
+};
+
+typedef unsigned char stbi_uc;
+typedef unsigned short stbi_us;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef STB_IMAGE_STATIC
+#define STBIDEF static
+#else
+#define STBIDEF extern
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// PRIMARY API - works on images of any type
+//
+
+//
+// load image by filename, open file, or memory buffer
+//
+
+typedef struct
+{
+ int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read
+ void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative
+ int (*eof) (void *user); // returns nonzero if we are at end of file/data
+} stbi_io_callbacks;
+
+////////////////////////////////////
+//
+// 8-bits-per-channel interface
+//
+
+STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels);
+STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels);
+#ifndef STBI_NO_GIF
+STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
+#endif
+
+
+#ifndef STBI_NO_STDIO
+STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
+STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
+// for stbi_load_from_file, file pointer is left pointing immediately after image
+#endif
+
+////////////////////////////////////
+//
+// 16-bits-per-channel interface
+//
+
+STBIDEF stbi_us *stbi_load_16_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels);
+STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels);
+
+#ifndef STBI_NO_STDIO
+STBIDEF stbi_us *stbi_load_16 (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
+STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
+#endif
+
+////////////////////////////////////
+//
+// float-per-channel interface
+//
+#ifndef STBI_NO_LINEAR
+ STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels);
+ STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels);
+
+ #ifndef STBI_NO_STDIO
+ STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels);
+ STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels);
+ #endif
+#endif
+
+#ifndef STBI_NO_HDR
+ STBIDEF void stbi_hdr_to_ldr_gamma(float gamma);
+ STBIDEF void stbi_hdr_to_ldr_scale(float scale);
+#endif // STBI_NO_HDR
+
+#ifndef STBI_NO_LINEAR
+ STBIDEF void stbi_ldr_to_hdr_gamma(float gamma);
+ STBIDEF void stbi_ldr_to_hdr_scale(float scale);
+#endif // STBI_NO_LINEAR
+
+// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR
+STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user);
+STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len);
+#ifndef STBI_NO_STDIO
+STBIDEF int stbi_is_hdr (char const *filename);
+STBIDEF int stbi_is_hdr_from_file(FILE *f);
+#endif // STBI_NO_STDIO
+
+
+// get a VERY brief reason for failure
+// NOT THREADSAFE
+STBIDEF const char *stbi_failure_reason (void);
+
+// free the loaded image -- this is just free()
+STBIDEF void stbi_image_free (void *retval_from_stbi_load);
+
+// get image dimensions & components without fully decoding
+STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp);
+STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp);
+STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len);
+STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user);
+
+#ifndef STBI_NO_STDIO
+STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp);
+STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp);
+STBIDEF int stbi_is_16_bit (char const *filename);
+STBIDEF int stbi_is_16_bit_from_file(FILE *f);
+#endif
+
+
+
+// for image formats that explicitly notate that they have premultiplied alpha,
+// we just return the colors as stored in the file. set this flag to force
+// unpremultiplication. results are undefined if the unpremultiply overflow.
+STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply);
+
+// indicate whether we should process iphone images back to canonical format,
+// or just pass them through "as-is"
+STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert);
+
+// flip the image vertically, so the first pixel in the output array is the bottom left
+STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip);
+
+// ZLIB client - used by PNG, available for other purposes
+
+STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen);
+STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header);
+STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen);
+STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
+
+STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen);
+STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+//
+//
+//// end header file /////////////////////////////////////////////////////
+#endif // STBI_INCLUDE_STB_IMAGE_H
+
+#ifdef STB_IMAGE_IMPLEMENTATION
+
+#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \
+ || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \
+ || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \
+ || defined(STBI_ONLY_ZLIB)
+ #ifndef STBI_ONLY_JPEG
+ #define STBI_NO_JPEG
+ #endif
+ #ifndef STBI_ONLY_PNG
+ #define STBI_NO_PNG
+ #endif
+ #ifndef STBI_ONLY_BMP
+ #define STBI_NO_BMP
+ #endif
+ #ifndef STBI_ONLY_PSD
+ #define STBI_NO_PSD
+ #endif
+ #ifndef STBI_ONLY_TGA
+ #define STBI_NO_TGA
+ #endif
+ #ifndef STBI_ONLY_GIF
+ #define STBI_NO_GIF
+ #endif
+ #ifndef STBI_ONLY_HDR
+ #define STBI_NO_HDR
+ #endif
+ #ifndef STBI_ONLY_PIC
+ #define STBI_NO_PIC
+ #endif
+ #ifndef STBI_ONLY_PNM
+ #define STBI_NO_PNM
+ #endif
+#endif
+
+#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB)
+#define STBI_NO_ZLIB
+#endif
+
+
+#include <stdarg.h>
+#include <stddef.h> // ptrdiff_t on osx
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
+#include <math.h> // ldexp, pow
+#endif
+
+#ifndef STBI_NO_STDIO
+#include <stdio.h>
+#endif
+
+#ifndef STBI_ASSERT
+#include <assert.h>
+#define STBI_ASSERT(x) assert(x)
+#endif
+
+
+#ifndef _MSC_VER
+ #ifdef __cplusplus
+ #define stbi_inline inline
+ #else
+ #define stbi_inline
+ #endif
+#else
+ #define stbi_inline __forceinline
+#endif
+
+
+#ifdef _MSC_VER
+typedef unsigned short stbi__uint16;
+typedef signed short stbi__int16;
+typedef unsigned int stbi__uint32;
+typedef signed int stbi__int32;
+#else
+#include <stdint.h>
+typedef uint16_t stbi__uint16;
+typedef int16_t stbi__int16;
+typedef uint32_t stbi__uint32;
+typedef int32_t stbi__int32;
+#endif
+
+// should produce compiler error if size is wrong
+typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
+
+#ifdef _MSC_VER
+#define STBI_NOTUSED(v) (void)(v)
+#else
+#define STBI_NOTUSED(v) (void)sizeof(v)
+#endif
+
+#ifdef _MSC_VER
+#define STBI_HAS_LROTL
+#endif
+
+#ifdef STBI_HAS_LROTL
+ #define stbi_lrot(x,y) _lrotl(x,y)
+#else
+ #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y))))
+#endif
+
+#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED))
+// ok
+#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED)
+// ok
+#else
+#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)."
+#endif
+
+#ifndef STBI_MALLOC
+#define STBI_MALLOC(sz) malloc(sz)
+#define STBI_REALLOC(p,newsz) realloc(p,newsz)
+#define STBI_FREE(p) free(p)
+#endif
+
+#ifndef STBI_REALLOC_SIZED
+#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz)
+#endif
+
+// x86/x64 detection
+#if defined(__x86_64__) || defined(_M_X64)
+#define STBI__X64_TARGET
+#elif defined(__i386) || defined(_M_IX86)
+#define STBI__X86_TARGET
+#endif
+
+#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
+// gcc doesn't support sse2 intrinsics unless you compile with -msse2,
+// which in turn means it gets to use SSE2 everywhere. This is unfortunate,
+// but previous attempts to provide the SSE2 functions with runtime
+// detection caused numerous issues. The way architecture extensions are
+// exposed in GCC/Clang is, sadly, not really suited for one-file libs.
+// New behavior: if compiled with -msse2, we use SSE2 without any
+// detection; if not, we don't use it at all.
+#define STBI_NO_SIMD
+#endif
+
+#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD)
+// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET
+//
+// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the
+// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant.
+// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not
+// simultaneously enabling "-mstackrealign".
+//
+// See https://github.com/nothings/stb/issues/81 for more information.
+//
+// So default to no SSE2 on 32-bit MinGW. If you've read this far and added
+// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2.
+#define STBI_NO_SIMD
+#endif
+
+#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET))
+#define STBI_SSE2
+#include <emmintrin.h>
+
+#ifdef _MSC_VER
+
+#if _MSC_VER >= 1400 // not VC6
+#include <intrin.h> // __cpuid
+static int stbi__cpuid3(void)
+{
+ int info[4];
+ __cpuid(info,1);
+ return info[3];
+}
+#else
+static int stbi__cpuid3(void)
+{
+ int res;
+ __asm {
+ mov eax,1
+ cpuid
+ mov res,edx
+ }
+ return res;
+}
+#endif
+
+#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name
+
+static int stbi__sse2_available(void)
+{
+ int info3 = stbi__cpuid3();
+ return ((info3 >> 26) & 1) != 0;
+}
+#else // assume GCC-style if not VC++
+#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
+
+static int stbi__sse2_available(void)
+{
+ // If we're even attempting to compile this on GCC/Clang, that means
+ // -msse2 is on, which means the compiler is allowed to use SSE2
+ // instructions at will, and so are we.
+ return 1;
+}
+#endif
+#endif
+
+// ARM NEON
+#if defined(STBI_NO_SIMD) && defined(STBI_NEON)
+#undef STBI_NEON
+#endif
+
+#ifdef STBI_NEON
+#include <arm_neon.h>
+// assume GCC or Clang on ARM targets
+#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
+#endif
+
+#ifndef STBI_SIMD_ALIGN
+#define STBI_SIMD_ALIGN(type, name) type name
+#endif
+
+///////////////////////////////////////////////
+//
+// stbi__context struct and start_xxx functions
+
+// stbi__context structure is our basic context used by all images, so it
+// contains all the IO context, plus some basic image information
+typedef struct
+{
+ stbi__uint32 img_x, img_y;
+ int img_n, img_out_n;
+
+ stbi_io_callbacks io;
+ void *io_user_data;
+
+ int read_from_callbacks;
+ int buflen;
+ stbi_uc buffer_start[128];
+
+ stbi_uc *img_buffer, *img_buffer_end;
+ stbi_uc *img_buffer_original, *img_buffer_original_end;
+} stbi__context;
+
+
+static void stbi__refill_buffer(stbi__context *s);
+
+// initialize a memory-decode context
+static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len)
+{
+ s->io.read = NULL;
+ s->read_from_callbacks = 0;
+ s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer;
+ s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len;
+}
+
+// initialize a callback-based context
+static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user)
+{
+ s->io = *c;
+ s->io_user_data = user;
+ s->buflen = sizeof(s->buffer_start);
+ s->read_from_callbacks = 1;
+ s->img_buffer_original = s->buffer_start;
+ stbi__refill_buffer(s);
+ s->img_buffer_original_end = s->img_buffer_end;
+}
+
+#ifndef STBI_NO_STDIO
+
+static int stbi__stdio_read(void *user, char *data, int size)
+{
+ return (int) fread(data,1,size,(FILE*) user);
+}
+
+static void stbi__stdio_skip(void *user, int n)
+{
+ fseek((FILE*) user, n, SEEK_CUR);
+}
+
+static int stbi__stdio_eof(void *user)
+{
+ return feof((FILE*) user);
+}
+
+static stbi_io_callbacks stbi__stdio_callbacks =
+{
+ stbi__stdio_read,
+ stbi__stdio_skip,
+ stbi__stdio_eof,
+};
+
+static void stbi__start_file(stbi__context *s, FILE *f)
+{
+ stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f);
+}
+
+//static void stop_file(stbi__context *s) { }
+
+#endif // !STBI_NO_STDIO
+
+static void stbi__rewind(stbi__context *s)
+{
+ // conceptually rewind SHOULD rewind to the beginning of the stream,
+ // but we just rewind to the beginning of the initial buffer, because
+ // we only use it after doing 'test', which only ever looks at at most 92 bytes
+ s->img_buffer = s->img_buffer_original;
+ s->img_buffer_end = s->img_buffer_original_end;
+}
+
+enum
+{
+ STBI_ORDER_RGB,
+ STBI_ORDER_BGR
+};
+
+typedef struct
+{
+ int bits_per_channel;
+ int num_channels;
+ int channel_order;
+} stbi__result_info;
+
+#ifndef STBI_NO_JPEG
+static int stbi__jpeg_test(stbi__context *s);
+static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp);
+#endif
+
+#ifndef STBI_NO_PNG
+static int stbi__png_test(stbi__context *s);
+static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp);
+static int stbi__png_is16(stbi__context *s);
+#endif
+
+#ifndef STBI_NO_BMP
+static int stbi__bmp_test(stbi__context *s);
+static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp);
+#endif
+
+#ifndef STBI_NO_TGA
+static int stbi__tga_test(stbi__context *s);
+static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp);
+#endif
+
+#ifndef STBI_NO_PSD
+static int stbi__psd_test(stbi__context *s);
+static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc);
+static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp);
+static int stbi__psd_is16(stbi__context *s);
+#endif
+
+#ifndef STBI_NO_HDR
+static int stbi__hdr_test(stbi__context *s);
+static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp);
+#endif
+
+#ifndef STBI_NO_PIC
+static int stbi__pic_test(stbi__context *s);
+static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp);
+#endif
+
+#ifndef STBI_NO_GIF
+static int stbi__gif_test(stbi__context *s);
+static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp);
+static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp);
+#endif
+
+#ifndef STBI_NO_PNM
+static int stbi__pnm_test(stbi__context *s);
+static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri);
+static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp);
+#endif
+
+// this is not threadsafe
+static const char *stbi__g_failure_reason;
+
+STBIDEF const char *stbi_failure_reason(void)
+{
+ return stbi__g_failure_reason;
+}
+
+static int stbi__err(const char *str)
+{
+ stbi__g_failure_reason = str;
+ return 0;
+}
+
+static void *stbi__malloc(size_t size)
+{
+ return STBI_MALLOC(size);
+}
+
+// stb_image uses ints pervasively, including for offset calculations.
+// therefore the largest decoded image size we can support with the
+// current code, even on 64-bit targets, is INT_MAX. this is not a
+// significant limitation for the intended use case.
+//
+// we do, however, need to make sure our size calculations don't
+// overflow. hence a few helper functions for size calculations that
+// multiply integers together, making sure that they're non-negative
+// and no overflow occurs.
+
+// return 1 if the sum is valid, 0 on overflow.
+// negative terms are considered invalid.
+static int stbi__addsizes_valid(int a, int b)
+{
+ if (b < 0) return 0;
+ // now 0 <= b <= INT_MAX, hence also
+ // 0 <= INT_MAX - b <= INTMAX.
+ // And "a + b <= INT_MAX" (which might overflow) is the
+ // same as a <= INT_MAX - b (no overflow)
+ return a <= INT_MAX - b;
+}
+
+// returns 1 if the product is valid, 0 on overflow.
+// negative factors are considered invalid.
+static int stbi__mul2sizes_valid(int a, int b)
+{
+ if (a < 0 || b < 0) return 0;
+ if (b == 0) return 1; // mul-by-0 is always safe
+ // portable way to check for no overflows in a*b
+ return a <= INT_MAX/b;
+}
+
+// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow
+static int stbi__mad2sizes_valid(int a, int b, int add)
+{
+ return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add);
+}
+
+// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow
+static int stbi__mad3sizes_valid(int a, int b, int c, int add)
+{
+ return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) &&
+ stbi__addsizes_valid(a*b*c, add);
+}
+
+// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow
+#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
+static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add)
+{
+ return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) &&
+ stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add);
+}
+#endif
+
+// mallocs with size overflow checking
+static void *stbi__malloc_mad2(int a, int b, int add)
+{
+ if (!stbi__mad2sizes_valid(a, b, add)) return NULL;
+ return stbi__malloc(a*b + add);
+}
+
+static void *stbi__malloc_mad3(int a, int b, int c, int add)
+{
+ if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL;
+ return stbi__malloc(a*b*c + add);
+}
+
+#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
+static void *stbi__malloc_mad4(int a, int b, int c, int d, int add)
+{
+ if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL;
+ return stbi__malloc(a*b*c*d + add);
+}
+#endif
+
+// stbi__err - error
+// stbi__errpf - error returning pointer to float
+// stbi__errpuc - error returning pointer to unsigned char
+
+#ifdef STBI_NO_FAILURE_STRINGS
+ #define stbi__err(x,y) 0
+#elif defined(STBI_FAILURE_USERMSG)
+ #define stbi__err(x,y) stbi__err(y)
+#else
+ #define stbi__err(x,y) stbi__err(x)
+#endif
+
+#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL))
+#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL))
+
+STBIDEF void stbi_image_free(void *retval_from_stbi_load)
+{
+ STBI_FREE(retval_from_stbi_load);
+}
+
+#ifndef STBI_NO_LINEAR
+static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp);
+#endif
+
+#ifndef STBI_NO_HDR
+static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp);
+#endif
+
+static int stbi__vertically_flip_on_load = 0;
+
+STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip)
+{
+ stbi__vertically_flip_on_load = flag_true_if_should_flip;
+}
+
+static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
+{
+ memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields
+ ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed
+ ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order
+ ri->num_channels = 0;
+
+ #ifndef STBI_NO_JPEG
+ if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri);
+ #endif
+ #ifndef STBI_NO_PNG
+ if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri);
+ #endif
+ #ifndef STBI_NO_BMP
+ if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp, ri);
+ #endif
+ #ifndef STBI_NO_GIF
+ if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp, ri);
+ #endif
+ #ifndef STBI_NO_PSD
+ if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc);
+ #endif
+ #ifndef STBI_NO_PIC
+ if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri);
+ #endif
+ #ifndef STBI_NO_PNM
+ if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri);
+ #endif
+
+ #ifndef STBI_NO_HDR
+ if (stbi__hdr_test(s)) {
+ float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri);
+ return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp);
+ }
+ #endif
+
+ #ifndef STBI_NO_TGA
+ // test tga last because it's a crappy test!
+ if (stbi__tga_test(s))
+ return stbi__tga_load(s,x,y,comp,req_comp, ri);
+ #endif
+
+ return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt");
+}
+
+static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels)
+{
+ int i;
+ int img_len = w * h * channels;
+ stbi_uc *reduced;
+
+ reduced = (stbi_uc *) stbi__malloc(img_len);
+ if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory");
+
+ for (i = 0; i < img_len; ++i)
+ reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling
+
+ STBI_FREE(orig);
+ return reduced;
+}
+
+static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels)
+{
+ int i;
+ int img_len = w * h * channels;
+ stbi__uint16 *enlarged;
+
+ enlarged = (stbi__uint16 *) stbi__malloc(img_len*2);
+ if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
+
+ for (i = 0; i < img_len; ++i)
+ enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff
+
+ STBI_FREE(orig);
+ return enlarged;
+}
+
+static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel)
+{
+ int row;
+ size_t bytes_per_row = (size_t)w * bytes_per_pixel;
+ stbi_uc temp[2048];
+ stbi_uc *bytes = (stbi_uc *)image;
+
+ for (row = 0; row < (h>>1); row++) {
+ stbi_uc *row0 = bytes + row*bytes_per_row;
+ stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row;
+ // swap row0 with row1
+ size_t bytes_left = bytes_per_row;
+ while (bytes_left) {
+ size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp);
+ memcpy(temp, row0, bytes_copy);
+ memcpy(row0, row1, bytes_copy);
+ memcpy(row1, temp, bytes_copy);
+ row0 += bytes_copy;
+ row1 += bytes_copy;
+ bytes_left -= bytes_copy;
+ }
+ }
+}
+
+static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel)
+{
+ int slice;
+ int slice_size = w * h * bytes_per_pixel;
+
+ stbi_uc *bytes = (stbi_uc *)image;
+ for (slice = 0; slice < z; ++slice) {
+ stbi__vertical_flip(bytes, w, h, bytes_per_pixel);
+ bytes += slice_size;
+ }
+}
+
+static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
+{
+ stbi__result_info ri;
+ void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8);
+
+ if (result == NULL)
+ return NULL;
+
+ if (ri.bits_per_channel != 8) {
+ STBI_ASSERT(ri.bits_per_channel == 16);
+ result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
+ ri.bits_per_channel = 8;
+ }
+
+ // @TODO: move stbi__convert_format to here
+
+ if (stbi__vertically_flip_on_load) {
+ int channels = req_comp ? req_comp : *comp;
+ stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc));
+ }
+
+ return (unsigned char *) result;
+}
+
+static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp)
+{
+ stbi__result_info ri;
+ void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16);
+
+ if (result == NULL)
+ return NULL;
+
+ if (ri.bits_per_channel != 16) {
+ STBI_ASSERT(ri.bits_per_channel == 8);
+ result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
+ ri.bits_per_channel = 16;
+ }
+
+ // @TODO: move stbi__convert_format16 to here
+ // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision
+
+ if (stbi__vertically_flip_on_load) {
+ int channels = req_comp ? req_comp : *comp;
+ stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16));
+ }
+
+ return (stbi__uint16 *) result;
+}
+
+#if !defined(STBI_NO_HDR) || !defined(STBI_NO_LINEAR)
+static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
+{
+ if (stbi__vertically_flip_on_load && result != NULL) {
+ int channels = req_comp ? req_comp : *comp;
+ stbi__vertical_flip(result, *x, *y, channels * sizeof(float));
+ }
+}
+#endif
+
+#ifndef STBI_NO_STDIO
+
+static FILE *stbi__fopen(char const *filename, char const *mode)
+{
+ FILE *f;
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ if (0 != fopen_s(&f, filename, mode))
+ f=0;
+#else
+ f = fopen(filename, mode);
+#endif
+ return f;
+}
+
+
+STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp)
+{
+ FILE *f = stbi__fopen(filename, "rb");
+ unsigned char *result;
+ if (!f) return stbi__errpuc("can't fopen", "Unable to open file");
+ result = stbi_load_from_file(f,x,y,comp,req_comp);
+ fclose(f);
+ return result;
+}
+
+STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp)
+{
+ unsigned char *result;
+ stbi__context s;
+ stbi__start_file(&s,f);
+ result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
+ if (result) {
+ // need to 'unget' all the characters in the IO buffer
+ fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
+ }
+ return result;
+}
+
+STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp)
+{
+ stbi__uint16 *result;
+ stbi__context s;
+ stbi__start_file(&s,f);
+ result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp);
+ if (result) {
+ // need to 'unget' all the characters in the IO buffer
+ fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
+ }
+ return result;
+}
+
+STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp)
+{
+ FILE *f = stbi__fopen(filename, "rb");
+ stbi__uint16 *result;
+ if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file");
+ result = stbi_load_from_file_16(f,x,y,comp,req_comp);
+ fclose(f);
+ return result;
+}
+
+
+#endif //!STBI_NO_STDIO
+
+STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels)
+{
+ stbi__context s;
+ stbi__start_mem(&s,buffer,len);
+ return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels);
+}
+
+STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels)
+{
+ stbi__context s;
+ stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user);
+ return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels);
+}
+
+STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
+{
+ stbi__context s;
+ stbi__start_mem(&s,buffer,len);
+ return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
+}
+
+STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
+{
+ stbi__context s;
+ stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
+ return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp);
+}
+
+#ifndef STBI_NO_GIF
+STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
+{
+ unsigned char *result;
+ stbi__context s;
+ stbi__start_mem(&s,buffer,len);
+
+ result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp);
+ if (stbi__vertically_flip_on_load) {
+ stbi__vertical_flip_slices( result, *x, *y, *z, *comp );
+ }
+
+ return result;
+}
+#endif
+
+#ifndef STBI_NO_LINEAR
+static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
+{
+ unsigned char *data;
+ #ifndef STBI_NO_HDR
+ if (stbi__hdr_test(s)) {
+ stbi__result_info ri;
+ float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri);
+ if (hdr_data)
+ stbi__float_postprocess(hdr_data,x,y,comp,req_comp);
+ return hdr_data;
+ }
+ #endif
+ data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp);
+ if (data)
+ return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp);
+ return stbi__errpf("unknown image type", "Image not of any known type, or corrupt");
+}
+
+STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
+{
+ stbi__context s;
+ stbi__start_mem(&s,buffer,len);
+ return stbi__loadf_main(&s,x,y,comp,req_comp);
+}
+
+STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
+{
+ stbi__context s;
+ stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
+ return stbi__loadf_main(&s,x,y,comp,req_comp);
+}
+
+#ifndef STBI_NO_STDIO
+STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp)
+{
+ float *result;
+ FILE *f = stbi__fopen(filename, "rb");
+ if (!f) return stbi__errpf("can't fopen", "Unable to open file");
+ result = stbi_loadf_from_file(f,x,y,comp,req_comp);
+ fclose(f);
+ return result;
+}
+
+STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp)
+{
+ stbi__context s;
+ stbi__start_file(&s,f);
+ return stbi__loadf_main(&s,x,y,comp,req_comp);
+}
+#endif // !STBI_NO_STDIO
+
+#endif // !STBI_NO_LINEAR
+
+// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is
+// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always
+// reports false!
+
+STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len)
+{
+ #ifndef STBI_NO_HDR
+ stbi__context s;
+ stbi__start_mem(&s,buffer,len);
+ return stbi__hdr_test(&s);
+ #else
+ STBI_NOTUSED(buffer);
+ STBI_NOTUSED(len);
+ return 0;
+ #endif
+}
+
+#ifndef STBI_NO_STDIO
+STBIDEF int stbi_is_hdr (char const *filename)
+{
+ FILE *f = stbi__fopen(filename, "rb");
+ int result=0;
+ if (f) {
+ result = stbi_is_hdr_from_file(f);
+ fclose(f);
+ }
+ return result;
+}
+
+STBIDEF int stbi_is_hdr_from_file(FILE *f)
+{
+ #ifndef STBI_NO_HDR
+ long pos = ftell(f);
+ int res;
+ stbi__context s;
+ stbi__start_file(&s,f);
+ res = stbi__hdr_test(&s);
+ fseek(f, pos, SEEK_SET);
+ return res;
+ #else
+ STBI_NOTUSED(f);
+ return 0;
+ #endif
+}
+#endif // !STBI_NO_STDIO
+
+STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user)
+{
+ #ifndef STBI_NO_HDR
+ stbi__context s;
+ stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
+ return stbi__hdr_test(&s);
+ #else
+ STBI_NOTUSED(clbk);
+ STBI_NOTUSED(user);
+ return 0;
+ #endif
+}
+
+#ifndef STBI_NO_LINEAR
+static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f;
+
+STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; }
+STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; }
+#endif
+
+static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f;
+
+STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; }
+STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; }
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Common code used by all image loaders
+//
+
+enum
+{
+ STBI__SCAN_load=0,
+ STBI__SCAN_type,
+ STBI__SCAN_header
+};
+
+static void stbi__refill_buffer(stbi__context *s)
+{
+ int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen);
+ if (n == 0) {
+ // at end of file, treat same as if from memory, but need to handle case
+ // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file
+ s->read_from_callbacks = 0;
+ s->img_buffer = s->buffer_start;
+ s->img_buffer_end = s->buffer_start+1;
+ *s->img_buffer = 0;
+ } else {
+ s->img_buffer = s->buffer_start;
+ s->img_buffer_end = s->buffer_start + n;
+ }
+}
+
+stbi_inline static stbi_uc stbi__get8(stbi__context *s)
+{
+ if (s->img_buffer < s->img_buffer_end)
+ return *s->img_buffer++;
+ if (s->read_from_callbacks) {
+ stbi__refill_buffer(s);
+ return *s->img_buffer++;
+ }
+ return 0;
+}
+
+stbi_inline static int stbi__at_eof(stbi__context *s)
+{
+ if (s->io.read) {
+ if (!(s->io.eof)(s->io_user_data)) return 0;
+ // if feof() is true, check if buffer = end
+ // special case: we've only got the special 0 character at the end
+ if (s->read_from_callbacks == 0) return 1;
+ }
+
+ return s->img_buffer >= s->img_buffer_end;
+}
+
+static void stbi__skip(stbi__context *s, int n)
+{
+ if (n < 0) {
+ s->img_buffer = s->img_buffer_end;
+ return;
+ }
+ if (s->io.read) {
+ int blen = (int) (s->img_buffer_end - s->img_buffer);
+ if (blen < n) {
+ s->img_buffer = s->img_buffer_end;
+ (s->io.skip)(s->io_user_data, n - blen);
+ return;
+ }
+ }
+ s->img_buffer += n;
+}
+
+static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n)
+{
+ if (s->io.read) {
+ int blen = (int) (s->img_buffer_end - s->img_buffer);
+ if (blen < n) {
+ int res, count;
+
+ memcpy(buffer, s->img_buffer, blen);
+
+ count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen);
+ res = (count == (n-blen));
+ s->img_buffer = s->img_buffer_end;
+ return res;
+ }
+ }
+
+ if (s->img_buffer+n <= s->img_buffer_end) {
+ memcpy(buffer, s->img_buffer, n);
+ s->img_buffer += n;
+ return 1;
+ } else
+ return 0;
+}
+
+static int stbi__get16be(stbi__context *s)
+{
+ int z = stbi__get8(s);
+ return (z << 8) + stbi__get8(s);
+}
+
+static stbi__uint32 stbi__get32be(stbi__context *s)
+{
+ stbi__uint32 z = stbi__get16be(s);
+ return (z << 16) + stbi__get16be(s);
+}
+
+#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF)
+// nothing
+#else
+static int stbi__get16le(stbi__context *s)
+{
+ int z = stbi__get8(s);
+ return z + (stbi__get8(s) << 8);
+}
+#endif
+
+#ifndef STBI_NO_BMP
+static stbi__uint32 stbi__get32le(stbi__context *s)
+{
+ stbi__uint32 z = stbi__get16le(s);
+ return z + (stbi__get16le(s) << 16);
+}
+#endif
+
+#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// generic converter from built-in img_n to req_comp
+// individual types do this automatically as much as possible (e.g. jpeg
+// does all cases internally since it needs to colorspace convert anyway,
+// and it never has alpha, so very few cases ). png can automatically
+// interleave an alpha=255 channel, but falls back to this for other cases
+//
+// assume data buffer is malloced, so malloc a new one and free that one
+// only failure mode is malloc failing
+
+static stbi_uc stbi__compute_y(int r, int g, int b)
+{
+ return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8);
+}
+
+static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y)
+{
+ int i,j;
+ unsigned char *good;
+
+ if (req_comp == img_n) return data;
+ STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
+
+ good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0);
+ if (good == NULL) {
+ STBI_FREE(data);
+ return stbi__errpuc("outofmem", "Out of memory");
+ }
+
+ for (j=0; j < (int) y; ++j) {
+ unsigned char *src = data + j * x * img_n ;
+ unsigned char *dest = good + j * x * req_comp;
+
+ #define STBI__COMBO(a,b) ((a)*8+(b))
+ #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b)
+ // convert source image with img_n components to one with req_comp components;
+ // avoid switch per pixel, so use switch per scanline and massive macros
+ switch (STBI__COMBO(img_n, req_comp)) {
+ STBI__CASE(1,2) { dest[0]=src[0], dest[1]=255; } break;
+ STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
+ STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; } break;
+ STBI__CASE(2,1) { dest[0]=src[0]; } break;
+ STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
+ STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break;
+ STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; } break;
+ STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
+ STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; } break;
+ STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
+ STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; } break;
+ STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break;
+ default: STBI_ASSERT(0);
+ }
+ #undef STBI__CASE
+ }
+
+ STBI_FREE(data);
+ return good;
+}
+
+static stbi__uint16 stbi__compute_y_16(int r, int g, int b)
+{
+ return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8);
+}
+
+static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y)
+{
+ int i,j;
+ stbi__uint16 *good;
+
+ if (req_comp == img_n) return data;
+ STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
+
+ good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2);
+ if (good == NULL) {
+ STBI_FREE(data);
+ return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory");
+ }
+
+ for (j=0; j < (int) y; ++j) {
+ stbi__uint16 *src = data + j * x * img_n ;
+ stbi__uint16 *dest = good + j * x * req_comp;
+
+ #define STBI__COMBO(a,b) ((a)*8+(b))
+ #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b)
+ // convert source image with img_n components to one with req_comp components;
+ // avoid switch per pixel, so use switch per scanline and massive macros
+ switch (STBI__COMBO(img_n, req_comp)) {
+ STBI__CASE(1,2) { dest[0]=src[0], dest[1]=0xffff; } break;
+ STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
+ STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=0xffff; } break;
+ STBI__CASE(2,1) { dest[0]=src[0]; } break;
+ STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break;
+ STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break;
+ STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=0xffff; } break;
+ STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
+ STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = 0xffff; } break;
+ STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
+ STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = src[3]; } break;
+ STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break;
+ default: STBI_ASSERT(0);
+ }
+ #undef STBI__CASE
+ }
+
+ STBI_FREE(data);
+ return good;
+}
+
+#ifndef STBI_NO_LINEAR
+static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
+{
+ int i,k,n;
+ float *output;
+ if (!data) return NULL;
+ output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0);
+ if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); }
+ // compute number of non-alpha components
+ if (comp & 1) n = comp; else n = comp-1;
+ for (i=0; i < x*y; ++i) {
+ for (k=0; k < n; ++k) {
+ output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale);
+ }
+ if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f;
+ }
+ STBI_FREE(data);
+ return output;
+}
+#endif
+
+#ifndef STBI_NO_HDR
+#define stbi__float2int(x) ((int) (x))
+static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp)
+{
+ int i,k,n;
+ stbi_uc *output;
+ if (!data) return NULL;
+ output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0);
+ if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); }
+ // compute number of non-alpha components
+ if (comp & 1) n = comp; else n = comp-1;
+ for (i=0; i < x*y; ++i) {
+ for (k=0; k < n; ++k) {
+ float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f;
+ if (z < 0) z = 0;
+ if (z > 255) z = 255;
+ output[i*comp + k] = (stbi_uc) stbi__float2int(z);
+ }
+ if (k < comp) {
+ float z = data[i*comp+k] * 255 + 0.5f;
+ if (z < 0) z = 0;
+ if (z > 255) z = 255;
+ output[i*comp + k] = (stbi_uc) stbi__float2int(z);
+ }
+ }
+ STBI_FREE(data);
+ return output;
+}
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// "baseline" JPEG/JFIF decoder
+//
+// simple implementation
+// - doesn't support delayed output of y-dimension
+// - simple interface (only one output format: 8-bit interleaved RGB)
+// - doesn't try to recover corrupt jpegs
+// - doesn't allow partial loading, loading multiple at once
+// - still fast on x86 (copying globals into locals doesn't help x86)
+// - allocates lots of intermediate memory (full size of all components)
+// - non-interleaved case requires this anyway
+// - allows good upsampling (see next)
+// high-quality
+// - upsampled channels are bilinearly interpolated, even across blocks
+// - quality integer IDCT derived from IJG's 'slow'
+// performance
+// - fast huffman; reasonable integer IDCT
+// - some SIMD kernels for common paths on targets with SSE2/NEON
+// - uses a lot of intermediate memory, could cache poorly
+
+#ifndef STBI_NO_JPEG
+
+// huffman decoding acceleration
+#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache
+
+typedef struct
+{
+ stbi_uc fast[1 << FAST_BITS];
+ // weirdly, repacking this into AoS is a 10% speed loss, instead of a win
+ stbi__uint16 code[256];
+ stbi_uc values[256];
+ stbi_uc size[257];
+ unsigned int maxcode[18];
+ int delta[17]; // old 'firstsymbol' - old 'firstcode'
+} stbi__huffman;
+
+typedef struct
+{
+ stbi__context *s;
+ stbi__huffman huff_dc[4];
+ stbi__huffman huff_ac[4];
+ stbi__uint16 dequant[4][64];
+ stbi__int16 fast_ac[4][1 << FAST_BITS];
+
+// sizes for components, interleaved MCUs
+ int img_h_max, img_v_max;
+ int img_mcu_x, img_mcu_y;
+ int img_mcu_w, img_mcu_h;
+
+// definition of jpeg image component
+ struct
+ {
+ int id;
+ int h,v;
+ int tq;
+ int hd,ha;
+ int dc_pred;
+
+ int x,y,w2,h2;
+ stbi_uc *data;
+ void *raw_data, *raw_coeff;
+ stbi_uc *linebuf;
+ short *coeff; // progressive only
+ int coeff_w, coeff_h; // number of 8x8 coefficient blocks
+ } img_comp[4];
+
+ stbi__uint32 code_buffer; // jpeg entropy-coded buffer
+ int code_bits; // number of valid bits
+ unsigned char marker; // marker seen while filling entropy buffer
+ int nomore; // flag if we saw a marker so must stop
+
+ int progressive;
+ int spec_start;
+ int spec_end;
+ int succ_high;
+ int succ_low;
+ int eob_run;
+ int jfif;
+ int app14_color_transform; // Adobe APP14 tag
+ int rgb;
+
+ int scan_n, order[4];
+ int restart_interval, todo;
+
+// kernels
+ void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]);
+ void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step);
+ stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs);
+} stbi__jpeg;
+
+static int stbi__build_huffman(stbi__huffman *h, int *count)
+{
+ int i,j,k=0;
+ unsigned int code;
+ // build size list for each symbol (from JPEG spec)
+ for (i=0; i < 16; ++i)
+ for (j=0; j < count[i]; ++j)
+ h->size[k++] = (stbi_uc) (i+1);
+ h->size[k] = 0;
+
+ // compute actual symbols (from jpeg spec)
+ code = 0;
+ k = 0;
+ for(j=1; j <= 16; ++j) {
+ // compute delta to add to code to compute symbol id
+ h->delta[j] = k - code;
+ if (h->size[k] == j) {
+ while (h->size[k] == j)
+ h->code[k++] = (stbi__uint16) (code++);
+ if (code-1 >= (1u << j)) return stbi__err("bad code lengths","Corrupt JPEG");
+ }
+ // compute largest code + 1 for this size, preshifted as needed later
+ h->maxcode[j] = code << (16-j);
+ code <<= 1;
+ }
+ h->maxcode[j] = 0xffffffff;
+
+ // build non-spec acceleration table; 255 is flag for not-accelerated
+ memset(h->fast, 255, 1 << FAST_BITS);
+ for (i=0; i < k; ++i) {
+ int s = h->size[i];
+ if (s <= FAST_BITS) {
+ int c = h->code[i] << (FAST_BITS-s);
+ int m = 1 << (FAST_BITS-s);
+ for (j=0; j < m; ++j) {
+ h->fast[c+j] = (stbi_uc) i;
+ }
+ }
+ }
+ return 1;
+}
+
+// build a table that decodes both magnitude and value of small ACs in
+// one go.
+static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h)
+{
+ int i;
+ for (i=0; i < (1 << FAST_BITS); ++i) {
+ stbi_uc fast = h->fast[i];
+ fast_ac[i] = 0;
+ if (fast < 255) {
+ int rs = h->values[fast];
+ int run = (rs >> 4) & 15;
+ int magbits = rs & 15;
+ int len = h->size[fast];
+
+ if (magbits && len + magbits <= FAST_BITS) {
+ // magnitude code followed by receive_extend code
+ int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits);
+ int m = 1 << (magbits - 1);
+ if (k < m) k += (~0U << magbits) + 1;
+ // if the result is small enough, we can fit it in fast_ac table
+ if (k >= -128 && k <= 127)
+ fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits));
+ }
+ }
+ }
+}
+
+static void stbi__grow_buffer_unsafe(stbi__jpeg *j)
+{
+ do {
+ unsigned int b = j->nomore ? 0 : stbi__get8(j->s);
+ if (b == 0xff) {
+ int c = stbi__get8(j->s);
+ while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes
+ if (c != 0) {
+ j->marker = (unsigned char) c;
+ j->nomore = 1;
+ return;
+ }
+ }
+ j->code_buffer |= b << (24 - j->code_bits);
+ j->code_bits += 8;
+ } while (j->code_bits <= 24);
+}
+
+// (1 << n) - 1
+static const stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535};
+
+// decode a jpeg huffman value from the bitstream
+stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h)
+{
+ unsigned int temp;
+ int c,k;
+
+ if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
+
+ // look at the top FAST_BITS and determine what symbol ID it is,
+ // if the code is <= FAST_BITS
+ c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1);
+ k = h->fast[c];
+ if (k < 255) {
+ int s = h->size[k];
+ if (s > j->code_bits)
+ return -1;
+ j->code_buffer <<= s;
+ j->code_bits -= s;
+ return h->values[k];
+ }
+
+ // naive test is to shift the code_buffer down so k bits are
+ // valid, then test against maxcode. To speed this up, we've
+ // preshifted maxcode left so that it has (16-k) 0s at the
+ // end; in other words, regardless of the number of bits, it
+ // wants to be compared against something shifted to have 16;
+ // that way we don't need to shift inside the loop.
+ temp = j->code_buffer >> 16;
+ for (k=FAST_BITS+1 ; ; ++k)
+ if (temp < h->maxcode[k])
+ break;
+ if (k == 17) {
+ // error! code not found
+ j->code_bits -= 16;
+ return -1;
+ }
+
+ if (k > j->code_bits)
+ return -1;
+
+ // convert the huffman code to the symbol id
+ c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k];
+ STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]);
+
+ // convert the id to a symbol
+ j->code_bits -= k;
+ j->code_buffer <<= k;
+ return h->values[c];
+}
+
+// bias[n] = (-1<<n) + 1
+static const int stbi__jbias[16] = {0,-1,-3,-7,-15,-31,-63,-127,-255,-511,-1023,-2047,-4095,-8191,-16383,-32767};
+
+// combined JPEG 'receive' and JPEG 'extend', since baseline
+// always extends everything it receives.
+stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
+{
+ unsigned int k;
+ int sgn;
+ if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
+
+ sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
+ k = stbi_lrot(j->code_buffer, n);
+ STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask)));
+ j->code_buffer = k & ~stbi__bmask[n];
+ k &= stbi__bmask[n];
+ j->code_bits -= n;
+ return k + (stbi__jbias[n] & ~sgn);
+}
+
+// get some unsigned bits
+stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n)
+{
+ unsigned int k;
+ if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
+ k = stbi_lrot(j->code_buffer, n);
+ j->code_buffer = k & ~stbi__bmask[n];
+ k &= stbi__bmask[n];
+ j->code_bits -= n;
+ return k;
+}
+
+stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j)
+{
+ unsigned int k;
+ if (j->code_bits < 1) stbi__grow_buffer_unsafe(j);
+ k = j->code_buffer;
+ j->code_buffer <<= 1;
+ --j->code_bits;
+ return k & 0x80000000;
+}
+
+// given a value that's at position X in the zigzag stream,
+// where does it appear in the 8x8 matrix coded as row-major?
+static const stbi_uc stbi__jpeg_dezigzag[64+15] =
+{
+ 0, 1, 8, 16, 9, 2, 3, 10,
+ 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63,
+ // let corrupt input sample past end
+ 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63
+};
+
+// decode one 64-entry block--
+static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant)
+{
+ int diff,dc,k;
+ int t;
+
+ if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
+ t = stbi__jpeg_huff_decode(j, hdc);
+ if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG");
+
+ // 0 all the ac values now so we can do it 32-bits at a time
+ memset(data,0,64*sizeof(data[0]));
+
+ diff = t ? stbi__extend_receive(j, t) : 0;
+ dc = j->img_comp[b].dc_pred + diff;
+ j->img_comp[b].dc_pred = dc;
+ data[0] = (short) (dc * dequant[0]);
+
+ // decode AC components, see JPEG spec
+ k = 1;
+ do {
+ unsigned int zig;
+ int c,r,s;
+ if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
+ c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1);
+ r = fac[c];
+ if (r) { // fast-AC path
+ k += (r >> 4) & 15; // run
+ s = r & 15; // combined length
+ j->code_buffer <<= s;
+ j->code_bits -= s;
+ // decode into unzigzag'd location
+ zig = stbi__jpeg_dezigzag[k++];
+ data[zig] = (short) ((r >> 8) * dequant[zig]);
+ } else {
+ int rs = stbi__jpeg_huff_decode(j, hac);
+ if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG");
+ s = rs & 15;
+ r = rs >> 4;
+ if (s == 0) {
+ if (rs != 0xf0) break; // end block
+ k += 16;
+ } else {
+ k += r;
+ // decode into unzigzag'd location
+ zig = stbi__jpeg_dezigzag[k++];
+ data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]);
+ }
+ }
+ } while (k < 64);
+ return 1;
+}
+
+static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b)
+{
+ int diff,dc;
+ int t;
+ if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
+
+ if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
+
+ if (j->succ_high == 0) {
+ // first scan for DC coefficient, must be first
+ memset(data,0,64*sizeof(data[0])); // 0 all the ac values now
+ t = stbi__jpeg_huff_decode(j, hdc);
+ diff = t ? stbi__extend_receive(j, t) : 0;
+
+ dc = j->img_comp[b].dc_pred + diff;
+ j->img_comp[b].dc_pred = dc;
+ data[0] = (short) (dc << j->succ_low);
+ } else {
+ // refinement scan for DC coefficient
+ if (stbi__jpeg_get_bit(j))
+ data[0] += (short) (1 << j->succ_low);
+ }
+ return 1;
+}
+
+// @OPTIMIZE: store non-zigzagged during the decode passes,
+// and only de-zigzag when dequantizing
+static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac)
+{
+ int k;
+ if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
+
+ if (j->succ_high == 0) {
+ int shift = j->succ_low;
+
+ if (j->eob_run) {
+ --j->eob_run;
+ return 1;
+ }
+
+ k = j->spec_start;
+ do {
+ unsigned int zig;
+ int c,r,s;
+ if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
+ c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1);
+ r = fac[c];
+ if (r) { // fast-AC path
+ k += (r >> 4) & 15; // run
+ s = r & 15; // combined length
+ j->code_buffer <<= s;
+ j->code_bits -= s;
+ zig = stbi__jpeg_dezigzag[k++];
+ data[zig] = (short) ((r >> 8) << shift);
+ } else {
+ int rs = stbi__jpeg_huff_decode(j, hac);
+ if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG");
+ s = rs & 15;
+ r = rs >> 4;
+ if (s == 0) {
+ if (r < 15) {
+ j->eob_run = (1 << r);
+ if (r)
+ j->eob_run += stbi__jpeg_get_bits(j, r);
+ --j->eob_run;
+ break;
+ }
+ k += 16;
+ } else {
+ k += r;
+ zig = stbi__jpeg_dezigzag[k++];
+ data[zig] = (short) (stbi__extend_receive(j,s) << shift);
+ }
+ }
+ } while (k <= j->spec_end);
+ } else {
+ // refinement scan for these AC coefficients
+
+ short bit = (short) (1 << j->succ_low);
+
+ if (j->eob_run) {
+ --j->eob_run;
+ for (k = j->spec_start; k <= j->spec_end; ++k) {
+ short *p = &data[stbi__jpeg_dezigzag[k]];
+ if (*p != 0)
+ if (stbi__jpeg_get_bit(j))
+ if ((*p & bit)==0) {
+ if (*p > 0)
+ *p += bit;
+ else
+ *p -= bit;
+ }
+ }
+ } else {
+ k = j->spec_start;
+ do {
+ int r,s;
+ int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh
+ if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG");
+ s = rs & 15;
+ r = rs >> 4;
+ if (s == 0) {
+ if (r < 15) {
+ j->eob_run = (1 << r) - 1;
+ if (r)
+ j->eob_run += stbi__jpeg_get_bits(j, r);
+ r = 64; // force end of block
+ } else {
+ // r=15 s=0 should write 16 0s, so we just do
+ // a run of 15 0s and then write s (which is 0),
+ // so we don't have to do anything special here
+ }
+ } else {
+ if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG");
+ // sign bit
+ if (stbi__jpeg_get_bit(j))
+ s = bit;
+ else
+ s = -bit;
+ }
+
+ // advance by r
+ while (k <= j->spec_end) {
+ short *p = &data[stbi__jpeg_dezigzag[k++]];
+ if (*p != 0) {
+ if (stbi__jpeg_get_bit(j))
+ if ((*p & bit)==0) {
+ if (*p > 0)
+ *p += bit;
+ else
+ *p -= bit;
+ }
+ } else {
+ if (r == 0) {
+ *p = (short) s;
+ break;
+ }
+ --r;
+ }
+ }
+ } while (k <= j->spec_end);
+ }
+ }
+ return 1;
+}
+
+// take a -128..127 value and stbi__clamp it and convert to 0..255
+stbi_inline static stbi_uc stbi__clamp(int x)
+{
+ // trick to use a single test to catch both cases
+ if ((unsigned int) x > 255) {
+ if (x < 0) return 0;
+ if (x > 255) return 255;
+ }
+ return (stbi_uc) x;
+}
+
+#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5)))
+#define stbi__fsh(x) ((x) * 4096)
+
+// derived from jidctint -- DCT_ISLOW
+#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \
+ int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \
+ p2 = s2; \
+ p3 = s6; \
+ p1 = (p2+p3) * stbi__f2f(0.5411961f); \
+ t2 = p1 + p3*stbi__f2f(-1.847759065f); \
+ t3 = p1 + p2*stbi__f2f( 0.765366865f); \
+ p2 = s0; \
+ p3 = s4; \
+ t0 = stbi__fsh(p2+p3); \
+ t1 = stbi__fsh(p2-p3); \
+ x0 = t0+t3; \
+ x3 = t0-t3; \
+ x1 = t1+t2; \
+ x2 = t1-t2; \
+ t0 = s7; \
+ t1 = s5; \
+ t2 = s3; \
+ t3 = s1; \
+ p3 = t0+t2; \
+ p4 = t1+t3; \
+ p1 = t0+t3; \
+ p2 = t1+t2; \
+ p5 = (p3+p4)*stbi__f2f( 1.175875602f); \
+ t0 = t0*stbi__f2f( 0.298631336f); \
+ t1 = t1*stbi__f2f( 2.053119869f); \
+ t2 = t2*stbi__f2f( 3.072711026f); \
+ t3 = t3*stbi__f2f( 1.501321110f); \
+ p1 = p5 + p1*stbi__f2f(-0.899976223f); \
+ p2 = p5 + p2*stbi__f2f(-2.562915447f); \
+ p3 = p3*stbi__f2f(-1.961570560f); \
+ p4 = p4*stbi__f2f(-0.390180644f); \
+ t3 += p1+p4; \
+ t2 += p2+p3; \
+ t1 += p2+p4; \
+ t0 += p1+p3;
+
+static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64])
+{
+ int i,val[64],*v=val;
+ stbi_uc *o;
+ short *d = data;
+
+ // columns
+ for (i=0; i < 8; ++i,++d, ++v) {
+ // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing
+ if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0
+ && d[40]==0 && d[48]==0 && d[56]==0) {
+ // no shortcut 0 seconds
+ // (1|2|3|4|5|6|7)==0 0 seconds
+ // all separate -0.047 seconds
+ // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds
+ int dcterm = d[0]*4;
+ v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm;
+ } else {
+ STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56])
+ // constants scaled things up by 1<<12; let's bring them back
+ // down, but keep 2 extra bits of precision
+ x0 += 512; x1 += 512; x2 += 512; x3 += 512;
+ v[ 0] = (x0+t3) >> 10;
+ v[56] = (x0-t3) >> 10;
+ v[ 8] = (x1+t2) >> 10;
+ v[48] = (x1-t2) >> 10;
+ v[16] = (x2+t1) >> 10;
+ v[40] = (x2-t1) >> 10;
+ v[24] = (x3+t0) >> 10;
+ v[32] = (x3-t0) >> 10;
+ }
+ }
+
+ for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) {
+ // no fast case since the first 1D IDCT spread components out
+ STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7])
+ // constants scaled things up by 1<<12, plus we had 1<<2 from first
+ // loop, plus horizontal and vertical each scale by sqrt(8) so together
+ // we've got an extra 1<<3, so 1<<17 total we need to remove.
+ // so we want to round that, which means adding 0.5 * 1<<17,
+ // aka 65536. Also, we'll end up with -128 to 127 that we want
+ // to encode as 0..255 by adding 128, so we'll add that before the shift
+ x0 += 65536 + (128<<17);
+ x1 += 65536 + (128<<17);
+ x2 += 65536 + (128<<17);
+ x3 += 65536 + (128<<17);
+ // tried computing the shifts into temps, or'ing the temps to see
+ // if any were out of range, but that was slower
+ o[0] = stbi__clamp((x0+t3) >> 17);
+ o[7] = stbi__clamp((x0-t3) >> 17);
+ o[1] = stbi__clamp((x1+t2) >> 17);
+ o[6] = stbi__clamp((x1-t2) >> 17);
+ o[2] = stbi__clamp((x2+t1) >> 17);
+ o[5] = stbi__clamp((x2-t1) >> 17);
+ o[3] = stbi__clamp((x3+t0) >> 17);
+ o[4] = stbi__clamp((x3-t0) >> 17);
+ }
+}
+
+#ifdef STBI_SSE2
+// sse2 integer IDCT. not the fastest possible implementation but it
+// produces bit-identical results to the generic C version so it's
+// fully "transparent".
+static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
+{
+ // This is constructed to match our regular (generic) integer IDCT exactly.
+ __m128i row0, row1, row2, row3, row4, row5, row6, row7;
+ __m128i tmp;
+
+ // dot product constant: even elems=x, odd elems=y
+ #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y))
+
+ // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit)
+ // out(1) = c1[even]*x + c1[odd]*y
+ #define dct_rot(out0,out1, x,y,c0,c1) \
+ __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \
+ __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \
+ __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \
+ __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \
+ __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \
+ __m128i out1##_h = _mm_madd_epi16(c0##hi, c1)
+
+ // out = in << 12 (in 16-bit, out 32-bit)
+ #define dct_widen(out, in) \
+ __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \
+ __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4)
+
+ // wide add
+ #define dct_wadd(out, a, b) \
+ __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \
+ __m128i out##_h = _mm_add_epi32(a##_h, b##_h)
+
+ // wide sub
+ #define dct_wsub(out, a, b) \
+ __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \
+ __m128i out##_h = _mm_sub_epi32(a##_h, b##_h)
+
+ // butterfly a/b, add bias, then shift by "s" and pack
+ #define dct_bfly32o(out0, out1, a,b,bias,s) \
+ { \
+ __m128i abiased_l = _mm_add_epi32(a##_l, bias); \
+ __m128i abiased_h = _mm_add_epi32(a##_h, bias); \
+ dct_wadd(sum, abiased, b); \
+ dct_wsub(dif, abiased, b); \
+ out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \
+ out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \
+ }
+
+ // 8-bit interleave step (for transposes)
+ #define dct_interleave8(a, b) \
+ tmp = a; \
+ a = _mm_unpacklo_epi8(a, b); \
+ b = _mm_unpackhi_epi8(tmp, b)
+
+ // 16-bit interleave step (for transposes)
+ #define dct_interleave16(a, b) \
+ tmp = a; \
+ a = _mm_unpacklo_epi16(a, b); \
+ b = _mm_unpackhi_epi16(tmp, b)
+
+ #define dct_pass(bias,shift) \
+ { \
+ /* even part */ \
+ dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \
+ __m128i sum04 = _mm_add_epi16(row0, row4); \
+ __m128i dif04 = _mm_sub_epi16(row0, row4); \
+ dct_widen(t0e, sum04); \
+ dct_widen(t1e, dif04); \
+ dct_wadd(x0, t0e, t3e); \
+ dct_wsub(x3, t0e, t3e); \
+ dct_wadd(x1, t1e, t2e); \
+ dct_wsub(x2, t1e, t2e); \
+ /* odd part */ \
+ dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \
+ dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \
+ __m128i sum17 = _mm_add_epi16(row1, row7); \
+ __m128i sum35 = _mm_add_epi16(row3, row5); \
+ dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \
+ dct_wadd(x4, y0o, y4o); \
+ dct_wadd(x5, y1o, y5o); \
+ dct_wadd(x6, y2o, y5o); \
+ dct_wadd(x7, y3o, y4o); \
+ dct_bfly32o(row0,row7, x0,x7,bias,shift); \
+ dct_bfly32o(row1,row6, x1,x6,bias,shift); \
+ dct_bfly32o(row2,row5, x2,x5,bias,shift); \
+ dct_bfly32o(row3,row4, x3,x4,bias,shift); \
+ }
+
+ __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f));
+ __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f));
+ __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f));
+ __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f));
+ __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f));
+ __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f));
+ __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f));
+ __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f));
+
+ // rounding biases in column/row passes, see stbi__idct_block for explanation.
+ __m128i bias_0 = _mm_set1_epi32(512);
+ __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17));
+
+ // load
+ row0 = _mm_load_si128((const __m128i *) (data + 0*8));
+ row1 = _mm_load_si128((const __m128i *) (data + 1*8));
+ row2 = _mm_load_si128((const __m128i *) (data + 2*8));
+ row3 = _mm_load_si128((const __m128i *) (data + 3*8));
+ row4 = _mm_load_si128((const __m128i *) (data + 4*8));
+ row5 = _mm_load_si128((const __m128i *) (data + 5*8));
+ row6 = _mm_load_si128((const __m128i *) (data + 6*8));
+ row7 = _mm_load_si128((const __m128i *) (data + 7*8));
+
+ // column pass
+ dct_pass(bias_0, 10);
+
+ {
+ // 16bit 8x8 transpose pass 1
+ dct_interleave16(row0, row4);
+ dct_interleave16(row1, row5);
+ dct_interleave16(row2, row6);
+ dct_interleave16(row3, row7);
+
+ // transpose pass 2
+ dct_interleave16(row0, row2);
+ dct_interleave16(row1, row3);
+ dct_interleave16(row4, row6);
+ dct_interleave16(row5, row7);
+
+ // transpose pass 3
+ dct_interleave16(row0, row1);
+ dct_interleave16(row2, row3);
+ dct_interleave16(row4, row5);
+ dct_interleave16(row6, row7);
+ }
+
+ // row pass
+ dct_pass(bias_1, 17);
+
+ {
+ // pack
+ __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7
+ __m128i p1 = _mm_packus_epi16(row2, row3);
+ __m128i p2 = _mm_packus_epi16(row4, row5);
+ __m128i p3 = _mm_packus_epi16(row6, row7);
+
+ // 8bit 8x8 transpose pass 1
+ dct_interleave8(p0, p2); // a0e0a1e1...
+ dct_interleave8(p1, p3); // c0g0c1g1...
+
+ // transpose pass 2
+ dct_interleave8(p0, p1); // a0c0e0g0...
+ dct_interleave8(p2, p3); // b0d0f0h0...
+
+ // transpose pass 3
+ dct_interleave8(p0, p2); // a0b0c0d0...
+ dct_interleave8(p1, p3); // a4b4c4d4...
+
+ // store
+ _mm_storel_epi64((__m128i *) out, p0); out += out_stride;
+ _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride;
+ _mm_storel_epi64((__m128i *) out, p2); out += out_stride;
+ _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride;
+ _mm_storel_epi64((__m128i *) out, p1); out += out_stride;
+ _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride;
+ _mm_storel_epi64((__m128i *) out, p3); out += out_stride;
+ _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e));
+ }
+
+#undef dct_const
+#undef dct_rot
+#undef dct_widen
+#undef dct_wadd
+#undef dct_wsub
+#undef dct_bfly32o
+#undef dct_interleave8
+#undef dct_interleave16
+#undef dct_pass
+}
+
+#endif // STBI_SSE2
+
+#ifdef STBI_NEON
+
+// NEON integer IDCT. should produce bit-identical
+// results to the generic C version.
+static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
+{
+ int16x8_t row0, row1, row2, row3, row4, row5, row6, row7;
+
+ int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f));
+ int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f));
+ int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f));
+ int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f));
+ int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f));
+ int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f));
+ int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f));
+ int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f));
+ int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f));
+ int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f));
+ int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f));
+ int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f));
+
+#define dct_long_mul(out, inq, coeff) \
+ int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \
+ int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff)
+
+#define dct_long_mac(out, acc, inq, coeff) \
+ int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \
+ int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff)
+
+#define dct_widen(out, inq) \
+ int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \
+ int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12)
+
+// wide add
+#define dct_wadd(out, a, b) \
+ int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \
+ int32x4_t out##_h = vaddq_s32(a##_h, b##_h)
+
+// wide sub
+#define dct_wsub(out, a, b) \
+ int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \
+ int32x4_t out##_h = vsubq_s32(a##_h, b##_h)
+
+// butterfly a/b, then shift using "shiftop" by "s" and pack
+#define dct_bfly32o(out0,out1, a,b,shiftop,s) \
+ { \
+ dct_wadd(sum, a, b); \
+ dct_wsub(dif, a, b); \
+ out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \
+ out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \
+ }
+
+#define dct_pass(shiftop, shift) \
+ { \
+ /* even part */ \
+ int16x8_t sum26 = vaddq_s16(row2, row6); \
+ dct_long_mul(p1e, sum26, rot0_0); \
+ dct_long_mac(t2e, p1e, row6, rot0_1); \
+ dct_long_mac(t3e, p1e, row2, rot0_2); \
+ int16x8_t sum04 = vaddq_s16(row0, row4); \
+ int16x8_t dif04 = vsubq_s16(row0, row4); \
+ dct_widen(t0e, sum04); \
+ dct_widen(t1e, dif04); \
+ dct_wadd(x0, t0e, t3e); \
+ dct_wsub(x3, t0e, t3e); \
+ dct_wadd(x1, t1e, t2e); \
+ dct_wsub(x2, t1e, t2e); \
+ /* odd part */ \
+ int16x8_t sum15 = vaddq_s16(row1, row5); \
+ int16x8_t sum17 = vaddq_s16(row1, row7); \
+ int16x8_t sum35 = vaddq_s16(row3, row5); \
+ int16x8_t sum37 = vaddq_s16(row3, row7); \
+ int16x8_t sumodd = vaddq_s16(sum17, sum35); \
+ dct_long_mul(p5o, sumodd, rot1_0); \
+ dct_long_mac(p1o, p5o, sum17, rot1_1); \
+ dct_long_mac(p2o, p5o, sum35, rot1_2); \
+ dct_long_mul(p3o, sum37, rot2_0); \
+ dct_long_mul(p4o, sum15, rot2_1); \
+ dct_wadd(sump13o, p1o, p3o); \
+ dct_wadd(sump24o, p2o, p4o); \
+ dct_wadd(sump23o, p2o, p3o); \
+ dct_wadd(sump14o, p1o, p4o); \
+ dct_long_mac(x4, sump13o, row7, rot3_0); \
+ dct_long_mac(x5, sump24o, row5, rot3_1); \
+ dct_long_mac(x6, sump23o, row3, rot3_2); \
+ dct_long_mac(x7, sump14o, row1, rot3_3); \
+ dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \
+ dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \
+ dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \
+ dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \
+ }
+
+ // load
+ row0 = vld1q_s16(data + 0*8);
+ row1 = vld1q_s16(data + 1*8);
+ row2 = vld1q_s16(data + 2*8);
+ row3 = vld1q_s16(data + 3*8);
+ row4 = vld1q_s16(data + 4*8);
+ row5 = vld1q_s16(data + 5*8);
+ row6 = vld1q_s16(data + 6*8);
+ row7 = vld1q_s16(data + 7*8);
+
+ // add DC bias
+ row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0));
+
+ // column pass
+ dct_pass(vrshrn_n_s32, 10);
+
+ // 16bit 8x8 transpose
+ {
+// these three map to a single VTRN.16, VTRN.32, and VSWP, respectively.
+// whether compilers actually get this is another story, sadly.
+#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; }
+#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); }
+#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); }
+
+ // pass 1
+ dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6
+ dct_trn16(row2, row3);
+ dct_trn16(row4, row5);
+ dct_trn16(row6, row7);
+
+ // pass 2
+ dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4
+ dct_trn32(row1, row3);
+ dct_trn32(row4, row6);
+ dct_trn32(row5, row7);
+
+ // pass 3
+ dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0
+ dct_trn64(row1, row5);
+ dct_trn64(row2, row6);
+ dct_trn64(row3, row7);
+
+#undef dct_trn16
+#undef dct_trn32
+#undef dct_trn64
+ }
+
+ // row pass
+ // vrshrn_n_s32 only supports shifts up to 16, we need
+ // 17. so do a non-rounding shift of 16 first then follow
+ // up with a rounding shift by 1.
+ dct_pass(vshrn_n_s32, 16);
+
+ {
+ // pack and round
+ uint8x8_t p0 = vqrshrun_n_s16(row0, 1);
+ uint8x8_t p1 = vqrshrun_n_s16(row1, 1);
+ uint8x8_t p2 = vqrshrun_n_s16(row2, 1);
+ uint8x8_t p3 = vqrshrun_n_s16(row3, 1);
+ uint8x8_t p4 = vqrshrun_n_s16(row4, 1);
+ uint8x8_t p5 = vqrshrun_n_s16(row5, 1);
+ uint8x8_t p6 = vqrshrun_n_s16(row6, 1);
+ uint8x8_t p7 = vqrshrun_n_s16(row7, 1);
+
+ // again, these can translate into one instruction, but often don't.
+#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; }
+#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); }
+#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); }
+
+ // sadly can't use interleaved stores here since we only write
+ // 8 bytes to each scan line!
+
+ // 8x8 8-bit transpose pass 1
+ dct_trn8_8(p0, p1);
+ dct_trn8_8(p2, p3);
+ dct_trn8_8(p4, p5);
+ dct_trn8_8(p6, p7);
+
+ // pass 2
+ dct_trn8_16(p0, p2);
+ dct_trn8_16(p1, p3);
+ dct_trn8_16(p4, p6);
+ dct_trn8_16(p5, p7);
+
+ // pass 3
+ dct_trn8_32(p0, p4);
+ dct_trn8_32(p1, p5);
+ dct_trn8_32(p2, p6);
+ dct_trn8_32(p3, p7);
+
+ // store
+ vst1_u8(out, p0); out += out_stride;
+ vst1_u8(out, p1); out += out_stride;
+ vst1_u8(out, p2); out += out_stride;
+ vst1_u8(out, p3); out += out_stride;
+ vst1_u8(out, p4); out += out_stride;
+ vst1_u8(out, p5); out += out_stride;
+ vst1_u8(out, p6); out += out_stride;
+ vst1_u8(out, p7);
+
+#undef dct_trn8_8
+#undef dct_trn8_16
+#undef dct_trn8_32
+ }
+
+#undef dct_long_mul
+#undef dct_long_mac
+#undef dct_widen
+#undef dct_wadd
+#undef dct_wsub
+#undef dct_bfly32o
+#undef dct_pass
+}
+
+#endif // STBI_NEON
+
+#define STBI__MARKER_none 0xff
+// if there's a pending marker from the entropy stream, return that
+// otherwise, fetch from the stream and get a marker. if there's no
+// marker, return 0xff, which is never a valid marker value
+static stbi_uc stbi__get_marker(stbi__jpeg *j)
+{
+ stbi_uc x;
+ if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; }
+ x = stbi__get8(j->s);
+ if (x != 0xff) return STBI__MARKER_none;
+ while (x == 0xff)
+ x = stbi__get8(j->s); // consume repeated 0xff fill bytes
+ return x;
+}
+
+// in each scan, we'll have scan_n components, and the order
+// of the components is specified by order[]
+#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7)
+
+// after a restart interval, stbi__jpeg_reset the entropy decoder and
+// the dc prediction
+static void stbi__jpeg_reset(stbi__jpeg *j)
+{
+ j->code_bits = 0;
+ j->code_buffer = 0;
+ j->nomore = 0;
+ j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0;
+ j->marker = STBI__MARKER_none;
+ j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff;
+ j->eob_run = 0;
+ // no more than 1<<31 MCUs if no restart_interal? that's plenty safe,
+ // since we don't even allow 1<<30 pixels
+}
+
+static int stbi__parse_entropy_coded_data(stbi__jpeg *z)
+{
+ stbi__jpeg_reset(z);
+ if (!z->progressive) {
+ if (z->scan_n == 1) {
+ int i,j;
+ STBI_SIMD_ALIGN(short, data[64]);
+ int n = z->order[0];
+ // non-interleaved data, we just need to process one block at a time,
+ // in trivial scanline order
+ // number of blocks to do just depends on how many actual "pixels" this
+ // component has, independent of interleaved MCU blocking and such
+ int w = (z->img_comp[n].x+7) >> 3;
+ int h = (z->img_comp[n].y+7) >> 3;
+ for (j=0; j < h; ++j) {
+ for (i=0; i < w; ++i) {
+ int ha = z->img_comp[n].ha;
+ if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0;
+ z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data);
+ // every data block is an MCU, so countdown the restart interval
+ if (--z->todo <= 0) {
+ if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
+ // if it's NOT a restart, then just bail, so we get corrupt data
+ // rather than no data
+ if (!STBI__RESTART(z->marker)) return 1;
+ stbi__jpeg_reset(z);
+ }
+ }
+ }
+ return 1;
+ } else { // interleaved
+ int i,j,k,x,y;
+ STBI_SIMD_ALIGN(short, data[64]);
+ for (j=0; j < z->img_mcu_y; ++j) {
+ for (i=0; i < z->img_mcu_x; ++i) {
+ // scan an interleaved mcu... process scan_n components in order
+ for (k=0; k < z->scan_n; ++k) {
+ int n = z->order[k];
+ // scan out an mcu's worth of this component; that's just determined
+ // by the basic H and V specified for the component
+ for (y=0; y < z->img_comp[n].v; ++y) {
+ for (x=0; x < z->img_comp[n].h; ++x) {
+ int x2 = (i*z->img_comp[n].h + x)*8;
+ int y2 = (j*z->img_comp[n].v + y)*8;
+ int ha = z->img_comp[n].ha;
+ if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0;
+ z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data);
+ }
+ }
+ }
+ // after all interleaved components, that's an interleaved MCU,
+ // so now count down the restart interval
+ if (--z->todo <= 0) {
+ if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
+ if (!STBI__RESTART(z->marker)) return 1;
+ stbi__jpeg_reset(z);
+ }
+ }
+ }
+ return 1;
+ }
+ } else {
+ if (z->scan_n == 1) {
+ int i,j;
+ int n = z->order[0];
+ // non-interleaved data, we just need to process one block at a time,
+ // in trivial scanline order
+ // number of blocks to do just depends on how many actual "pixels" this
+ // component has, independent of interleaved MCU blocking and such
+ int w = (z->img_comp[n].x+7) >> 3;
+ int h = (z->img_comp[n].y+7) >> 3;
+ for (j=0; j < h; ++j) {
+ for (i=0; i < w; ++i) {
+ short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w);
+ if (z->spec_start == 0) {
+ if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n))
+ return 0;
+ } else {
+ int ha = z->img_comp[n].ha;
+ if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha]))
+ return 0;
+ }
+ // every data block is an MCU, so countdown the restart interval
+ if (--z->todo <= 0) {
+ if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
+ if (!STBI__RESTART(z->marker)) return 1;
+ stbi__jpeg_reset(z);
+ }
+ }
+ }
+ return 1;
+ } else { // interleaved
+ int i,j,k,x,y;
+ for (j=0; j < z->img_mcu_y; ++j) {
+ for (i=0; i < z->img_mcu_x; ++i) {
+ // scan an interleaved mcu... process scan_n components in order
+ for (k=0; k < z->scan_n; ++k) {
+ int n = z->order[k];
+ // scan out an mcu's worth of this component; that's just determined
+ // by the basic H and V specified for the component
+ for (y=0; y < z->img_comp[n].v; ++y) {
+ for (x=0; x < z->img_comp[n].h; ++x) {
+ int x2 = (i*z->img_comp[n].h + x);
+ int y2 = (j*z->img_comp[n].v + y);
+ short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w);
+ if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n))
+ return 0;
+ }
+ }
+ }
+ // after all interleaved components, that's an interleaved MCU,
+ // so now count down the restart interval
+ if (--z->todo <= 0) {
+ if (z->code_bits < 24) stbi__grow_buffer_unsafe(z);
+ if (!STBI__RESTART(z->marker)) return 1;
+ stbi__jpeg_reset(z);
+ }
+ }
+ }
+ return 1;
+ }
+ }
+}
+
+static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant)
+{
+ int i;
+ for (i=0; i < 64; ++i)
+ data[i] *= dequant[i];
+}
+
+static void stbi__jpeg_finish(stbi__jpeg *z)
+{
+ if (z->progressive) {
+ // dequantize and idct the data
+ int i,j,n;
+ for (n=0; n < z->s->img_n; ++n) {
+ int w = (z->img_comp[n].x+7) >> 3;
+ int h = (z->img_comp[n].y+7) >> 3;
+ for (j=0; j < h; ++j) {
+ for (i=0; i < w; ++i) {
+ short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w);
+ stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]);
+ z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data);
+ }
+ }
+ }
+ }
+}
+
+static int stbi__process_marker(stbi__jpeg *z, int m)
+{
+ int L;
+ switch (m) {
+ case STBI__MARKER_none: // no marker found
+ return stbi__err("expected marker","Corrupt JPEG");
+
+ case 0xDD: // DRI - specify restart interval
+ if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG");
+ z->restart_interval = stbi__get16be(z->s);
+ return 1;
+
+ case 0xDB: // DQT - define quantization table
+ L = stbi__get16be(z->s)-2;
+ while (L > 0) {
+ int q = stbi__get8(z->s);
+ int p = q >> 4, sixteen = (p != 0);
+ int t = q & 15,i;
+ if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG");
+ if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG");
+
+ for (i=0; i < 64; ++i)
+ z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s));
+ L -= (sixteen ? 129 : 65);
+ }
+ return L==0;
+
+ case 0xC4: // DHT - define huffman table
+ L = stbi__get16be(z->s)-2;
+ while (L > 0) {
+ stbi_uc *v;
+ int sizes[16],i,n=0;
+ int q = stbi__get8(z->s);
+ int tc = q >> 4;
+ int th = q & 15;
+ if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG");
+ for (i=0; i < 16; ++i) {
+ sizes[i] = stbi__get8(z->s);
+ n += sizes[i];
+ }
+ L -= 17;
+ if (tc == 0) {
+ if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0;
+ v = z->huff_dc[th].values;
+ } else {
+ if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0;
+ v = z->huff_ac[th].values;
+ }
+ for (i=0; i < n; ++i)
+ v[i] = stbi__get8(z->s);
+ if (tc != 0)
+ stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th);
+ L -= n;
+ }
+ return L==0;
+ }
+
+ // check for comment block or APP blocks
+ if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) {
+ L = stbi__get16be(z->s);
+ if (L < 2) {
+ if (m == 0xFE)
+ return stbi__err("bad COM len","Corrupt JPEG");
+ else
+ return stbi__err("bad APP len","Corrupt JPEG");
+ }
+ L -= 2;
+
+ if (m == 0xE0 && L >= 5) { // JFIF APP0 segment
+ static const unsigned char tag[5] = {'J','F','I','F','\0'};
+ int ok = 1;
+ int i;
+ for (i=0; i < 5; ++i)
+ if (stbi__get8(z->s) != tag[i])
+ ok = 0;
+ L -= 5;
+ if (ok)
+ z->jfif = 1;
+ } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment
+ static const unsigned char tag[6] = {'A','d','o','b','e','\0'};
+ int ok = 1;
+ int i;
+ for (i=0; i < 6; ++i)
+ if (stbi__get8(z->s) != tag[i])
+ ok = 0;
+ L -= 6;
+ if (ok) {
+ stbi__get8(z->s); // version
+ stbi__get16be(z->s); // flags0
+ stbi__get16be(z->s); // flags1
+ z->app14_color_transform = stbi__get8(z->s); // color transform
+ L -= 6;
+ }
+ }
+
+ stbi__skip(z->s, L);
+ return 1;
+ }
+
+ return stbi__err("unknown marker","Corrupt JPEG");
+}
+
+// after we see SOS
+static int stbi__process_scan_header(stbi__jpeg *z)
+{
+ int i;
+ int Ls = stbi__get16be(z->s);
+ z->scan_n = stbi__get8(z->s);
+ if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG");
+ if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG");
+ for (i=0; i < z->scan_n; ++i) {
+ int id = stbi__get8(z->s), which;
+ int q = stbi__get8(z->s);
+ for (which = 0; which < z->s->img_n; ++which)
+ if (z->img_comp[which].id == id)
+ break;
+ if (which == z->s->img_n) return 0; // no match
+ z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG");
+ z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG");
+ z->order[i] = which;
+ }
+
+ {
+ int aa;
+ z->spec_start = stbi__get8(z->s);
+ z->spec_end = stbi__get8(z->s); // should be 63, but might be 0
+ aa = stbi__get8(z->s);
+ z->succ_high = (aa >> 4);
+ z->succ_low = (aa & 15);
+ if (z->progressive) {
+ if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13)
+ return stbi__err("bad SOS", "Corrupt JPEG");
+ } else {
+ if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG");
+ if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG");
+ z->spec_end = 63;
+ }
+ }
+
+ return 1;
+}
+
+static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why)
+{
+ int i;
+ for (i=0; i < ncomp; ++i) {
+ if (z->img_comp[i].raw_data) {
+ STBI_FREE(z->img_comp[i].raw_data);
+ z->img_comp[i].raw_data = NULL;
+ z->img_comp[i].data = NULL;
+ }
+ if (z->img_comp[i].raw_coeff) {
+ STBI_FREE(z->img_comp[i].raw_coeff);
+ z->img_comp[i].raw_coeff = 0;
+ z->img_comp[i].coeff = 0;
+ }
+ if (z->img_comp[i].linebuf) {
+ STBI_FREE(z->img_comp[i].linebuf);
+ z->img_comp[i].linebuf = NULL;
+ }
+ }
+ return why;
+}
+
+static int stbi__process_frame_header(stbi__jpeg *z, int scan)
+{
+ stbi__context *s = z->s;
+ int Lf,p,i,q, h_max=1,v_max=1,c;
+ Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG
+ p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline
+ s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
+ s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
+ c = stbi__get8(s);
+ if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG");
+ s->img_n = c;
+ for (i=0; i < c; ++i) {
+ z->img_comp[i].data = NULL;
+ z->img_comp[i].linebuf = NULL;
+ }
+
+ if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG");
+
+ z->rgb = 0;
+ for (i=0; i < s->img_n; ++i) {
+ static const unsigned char rgb[3] = { 'R', 'G', 'B' };
+ z->img_comp[i].id = stbi__get8(s);
+ if (s->img_n == 3 && z->img_comp[i].id == rgb[i])
+ ++z->rgb;
+ q = stbi__get8(s);
+ z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG");
+ z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG");
+ z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG");
+ }
+
+ if (scan != STBI__SCAN_load) return 1;
+
+ if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode");
+
+ for (i=0; i < s->img_n; ++i) {
+ if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h;
+ if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v;
+ }
+
+ // compute interleaved mcu info
+ z->img_h_max = h_max;
+ z->img_v_max = v_max;
+ z->img_mcu_w = h_max * 8;
+ z->img_mcu_h = v_max * 8;
+ // these sizes can't be more than 17 bits
+ z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w;
+ z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h;
+
+ for (i=0; i < s->img_n; ++i) {
+ // number of effective pixels (e.g. for non-interleaved MCU)
+ z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max;
+ z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max;
+ // to simplify generation, we'll allocate enough memory to decode
+ // the bogus oversized data from using interleaved MCUs and their
+ // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't
+ // discard the extra data until colorspace conversion
+ //
+ // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier)
+ // so these muls can't overflow with 32-bit ints (which we require)
+ z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8;
+ z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8;
+ z->img_comp[i].coeff = 0;
+ z->img_comp[i].raw_coeff = 0;
+ z->img_comp[i].linebuf = NULL;
+ z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15);
+ if (z->img_comp[i].raw_data == NULL)
+ return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory"));
+ // align blocks for idct using mmx/sse
+ z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15);
+ if (z->progressive) {
+ // w2, h2 are multiples of 8 (see above)
+ z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8;
+ z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8;
+ z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15);
+ if (z->img_comp[i].raw_coeff == NULL)
+ return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory"));
+ z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15);
+ }
+ }
+
+ return 1;
+}
+
+// use comparisons since in some cases we handle more than one case (e.g. SOF)
+#define stbi__DNL(x) ((x) == 0xdc)
+#define stbi__SOI(x) ((x) == 0xd8)
+#define stbi__EOI(x) ((x) == 0xd9)
+#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2)
+#define stbi__SOS(x) ((x) == 0xda)
+
+#define stbi__SOF_progressive(x) ((x) == 0xc2)
+
+static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
+{
+ int m;
+ z->jfif = 0;
+ z->app14_color_transform = -1; // valid values are 0,1,2
+ z->marker = STBI__MARKER_none; // initialize cached marker to empty
+ m = stbi__get_marker(z);
+ if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG");
+ if (scan == STBI__SCAN_type) return 1;
+ m = stbi__get_marker(z);
+ while (!stbi__SOF(m)) {
+ if (!stbi__process_marker(z,m)) return 0;
+ m = stbi__get_marker(z);
+ while (m == STBI__MARKER_none) {
+ // some files have extra padding after their blocks, so ok, we'll scan
+ if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG");
+ m = stbi__get_marker(z);
+ }
+ }
+ z->progressive = stbi__SOF_progressive(m);
+ if (!stbi__process_frame_header(z, scan)) return 0;
+ return 1;
+}
+
+// decode image to YCbCr format
+static int stbi__decode_jpeg_image(stbi__jpeg *j)
+{
+ int m;
+ for (m = 0; m < 4; m++) {
+ j->img_comp[m].raw_data = NULL;
+ j->img_comp[m].raw_coeff = NULL;
+ }
+ j->restart_interval = 0;
+ if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0;
+ m = stbi__get_marker(j);
+ while (!stbi__EOI(m)) {
+ if (stbi__SOS(m)) {
+ if (!stbi__process_scan_header(j)) return 0;
+ if (!stbi__parse_entropy_coded_data(j)) return 0;
+ if (j->marker == STBI__MARKER_none ) {
+ // handle 0s at the end of image data from IP Kamera 9060
+ while (!stbi__at_eof(j->s)) {
+ int x = stbi__get8(j->s);
+ if (x == 255) {
+ j->marker = stbi__get8(j->s);
+ break;
+ }
+ }
+ // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0
+ }
+ } else if (stbi__DNL(m)) {
+ int Ld = stbi__get16be(j->s);
+ stbi__uint32 NL = stbi__get16be(j->s);
+ if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG");
+ if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG");
+ } else {
+ if (!stbi__process_marker(j, m)) return 0;
+ }
+ m = stbi__get_marker(j);
+ }
+ if (j->progressive)
+ stbi__jpeg_finish(j);
+ return 1;
+}
+
+// static jfif-centered resampling (across block boundaries)
+
+typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1,
+ int w, int hs);
+
+#define stbi__div4(x) ((stbi_uc) ((x) >> 2))
+
+static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
+{
+ STBI_NOTUSED(out);
+ STBI_NOTUSED(in_far);
+ STBI_NOTUSED(w);
+ STBI_NOTUSED(hs);
+ return in_near;
+}
+
+static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
+{
+ // need to generate two samples vertically for every one in input
+ int i;
+ STBI_NOTUSED(hs);
+ for (i=0; i < w; ++i)
+ out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2);
+ return out;
+}
+
+static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
+{
+ // need to generate two samples horizontally for every one in input
+ int i;
+ stbi_uc *input = in_near;
+
+ if (w == 1) {
+ // if only one sample, can't do any interpolation
+ out[0] = out[1] = input[0];
+ return out;
+ }
+
+ out[0] = input[0];
+ out[1] = stbi__div4(input[0]*3 + input[1] + 2);
+ for (i=1; i < w-1; ++i) {
+ int n = 3*input[i]+2;
+ out[i*2+0] = stbi__div4(n+input[i-1]);
+ out[i*2+1] = stbi__div4(n+input[i+1]);
+ }
+ out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2);
+ out[i*2+1] = input[w-1];
+
+ STBI_NOTUSED(in_far);
+ STBI_NOTUSED(hs);
+
+ return out;
+}
+
+#define stbi__div16(x) ((stbi_uc) ((x) >> 4))
+
+static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
+{
+ // need to generate 2x2 samples for every one in input
+ int i,t0,t1;
+ if (w == 1) {
+ out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2);
+ return out;
+ }
+
+ t1 = 3*in_near[0] + in_far[0];
+ out[0] = stbi__div4(t1+2);
+ for (i=1; i < w; ++i) {
+ t0 = t1;
+ t1 = 3*in_near[i]+in_far[i];
+ out[i*2-1] = stbi__div16(3*t0 + t1 + 8);
+ out[i*2 ] = stbi__div16(3*t1 + t0 + 8);
+ }
+ out[w*2-1] = stbi__div4(t1+2);
+
+ STBI_NOTUSED(hs);
+
+ return out;
+}
+
+#if defined(STBI_SSE2) || defined(STBI_NEON)
+static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
+{
+ // need to generate 2x2 samples for every one in input
+ int i=0,t0,t1;
+
+ if (w == 1) {
+ out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2);
+ return out;
+ }
+
+ t1 = 3*in_near[0] + in_far[0];
+ // process groups of 8 pixels for as long as we can.
+ // note we can't handle the last pixel in a row in this loop
+ // because we need to handle the filter boundary conditions.
+ for (; i < ((w-1) & ~7); i += 8) {
+#if defined(STBI_SSE2)
+ // load and perform the vertical filtering pass
+ // this uses 3*x + y = 4*x + (y - x)
+ __m128i zero = _mm_setzero_si128();
+ __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i));
+ __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i));
+ __m128i farw = _mm_unpacklo_epi8(farb, zero);
+ __m128i nearw = _mm_unpacklo_epi8(nearb, zero);
+ __m128i diff = _mm_sub_epi16(farw, nearw);
+ __m128i nears = _mm_slli_epi16(nearw, 2);
+ __m128i curr = _mm_add_epi16(nears, diff); // current row
+
+ // horizontal filter works the same based on shifted vers of current
+ // row. "prev" is current row shifted right by 1 pixel; we need to
+ // insert the previous pixel value (from t1).
+ // "next" is current row shifted left by 1 pixel, with first pixel
+ // of next block of 8 pixels added in.
+ __m128i prv0 = _mm_slli_si128(curr, 2);
+ __m128i nxt0 = _mm_srli_si128(curr, 2);
+ __m128i prev = _mm_insert_epi16(prv0, t1, 0);
+ __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7);
+
+ // horizontal filter, polyphase implementation since it's convenient:
+ // even pixels = 3*cur + prev = cur*4 + (prev - cur)
+ // odd pixels = 3*cur + next = cur*4 + (next - cur)
+ // note the shared term.
+ __m128i bias = _mm_set1_epi16(8);
+ __m128i curs = _mm_slli_epi16(curr, 2);
+ __m128i prvd = _mm_sub_epi16(prev, curr);
+ __m128i nxtd = _mm_sub_epi16(next, curr);
+ __m128i curb = _mm_add_epi16(curs, bias);
+ __m128i even = _mm_add_epi16(prvd, curb);
+ __m128i odd = _mm_add_epi16(nxtd, curb);
+
+ // interleave even and odd pixels, then undo scaling.
+ __m128i int0 = _mm_unpacklo_epi16(even, odd);
+ __m128i int1 = _mm_unpackhi_epi16(even, odd);
+ __m128i de0 = _mm_srli_epi16(int0, 4);
+ __m128i de1 = _mm_srli_epi16(int1, 4);
+
+ // pack and write output
+ __m128i outv = _mm_packus_epi16(de0, de1);
+ _mm_storeu_si128((__m128i *) (out + i*2), outv);
+#elif defined(STBI_NEON)
+ // load and perform the vertical filtering pass
+ // this uses 3*x + y = 4*x + (y - x)
+ uint8x8_t farb = vld1_u8(in_far + i);
+ uint8x8_t nearb = vld1_u8(in_near + i);
+ int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb));
+ int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2));
+ int16x8_t curr = vaddq_s16(nears, diff); // current row
+
+ // horizontal filter works the same based on shifted vers of current
+ // row. "prev" is current row shifted right by 1 pixel; we need to
+ // insert the previous pixel value (from t1).
+ // "next" is current row shifted left by 1 pixel, with first pixel
+ // of next block of 8 pixels added in.
+ int16x8_t prv0 = vextq_s16(curr, curr, 7);
+ int16x8_t nxt0 = vextq_s16(curr, curr, 1);
+ int16x8_t prev = vsetq_lane_s16(t1, prv0, 0);
+ int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7);
+
+ // horizontal filter, polyphase implementation since it's convenient:
+ // even pixels = 3*cur + prev = cur*4 + (prev - cur)
+ // odd pixels = 3*cur + next = cur*4 + (next - cur)
+ // note the shared term.
+ int16x8_t curs = vshlq_n_s16(curr, 2);
+ int16x8_t prvd = vsubq_s16(prev, curr);
+ int16x8_t nxtd = vsubq_s16(next, curr);
+ int16x8_t even = vaddq_s16(curs, prvd);
+ int16x8_t odd = vaddq_s16(curs, nxtd);
+
+ // undo scaling and round, then store with even/odd phases interleaved
+ uint8x8x2_t o;
+ o.val[0] = vqrshrun_n_s16(even, 4);
+ o.val[1] = vqrshrun_n_s16(odd, 4);
+ vst2_u8(out + i*2, o);
+#endif
+
+ // "previous" value for next iter
+ t1 = 3*in_near[i+7] + in_far[i+7];
+ }
+
+ t0 = t1;
+ t1 = 3*in_near[i] + in_far[i];
+ out[i*2] = stbi__div16(3*t1 + t0 + 8);
+
+ for (++i; i < w; ++i) {
+ t0 = t1;
+ t1 = 3*in_near[i]+in_far[i];
+ out[i*2-1] = stbi__div16(3*t0 + t1 + 8);
+ out[i*2 ] = stbi__div16(3*t1 + t0 + 8);
+ }
+ out[w*2-1] = stbi__div4(t1+2);
+
+ STBI_NOTUSED(hs);
+
+ return out;
+}
+#endif
+
+static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
+{
+ // resample with nearest-neighbor
+ int i,j;
+ STBI_NOTUSED(in_far);
+ for (i=0; i < w; ++i)
+ for (j=0; j < hs; ++j)
+ out[i*hs+j] = in_near[i];
+ return out;
+}
+
+// this is a reduced-precision calculation of YCbCr-to-RGB introduced
+// to make sure the code produces the same results in both SIMD and scalar
+#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8)
+static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step)
+{
+ int i;
+ for (i=0; i < count; ++i) {
+ int y_fixed = (y[i] << 20) + (1<<19); // rounding
+ int r,g,b;
+ int cr = pcr[i] - 128;
+ int cb = pcb[i] - 128;
+ r = y_fixed + cr* stbi__float2fixed(1.40200f);
+ g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
+ b = y_fixed + cb* stbi__float2fixed(1.77200f);
+ r >>= 20;
+ g >>= 20;
+ b >>= 20;
+ if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; }
+ if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; }
+ if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; }
+ out[0] = (stbi_uc)r;
+ out[1] = (stbi_uc)g;
+ out[2] = (stbi_uc)b;
+ out[3] = 255;
+ out += step;
+ }
+}
+
+#if defined(STBI_SSE2) || defined(STBI_NEON)
+static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step)
+{
+ int i = 0;
+
+#ifdef STBI_SSE2
+ // step == 3 is pretty ugly on the final interleave, and i'm not convinced
+ // it's useful in practice (you wouldn't use it for textures, for example).
+ // so just accelerate step == 4 case.
+ if (step == 4) {
+ // this is a fairly straightforward implementation and not super-optimized.
+ __m128i signflip = _mm_set1_epi8(-0x80);
+ __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f));
+ __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f));
+ __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f));
+ __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f));
+ __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128);
+ __m128i xw = _mm_set1_epi16(255); // alpha channel
+
+ for (; i+7 < count; i += 8) {
+ // load
+ __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i));
+ __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i));
+ __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i));
+ __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128
+ __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128
+
+ // unpack to short (and left-shift cr, cb by 8)
+ __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes);
+ __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased);
+ __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased);
+
+ // color transform
+ __m128i yws = _mm_srli_epi16(yw, 4);
+ __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw);
+ __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw);
+ __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1);
+ __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1);
+ __m128i rws = _mm_add_epi16(cr0, yws);
+ __m128i gwt = _mm_add_epi16(cb0, yws);
+ __m128i bws = _mm_add_epi16(yws, cb1);
+ __m128i gws = _mm_add_epi16(gwt, cr1);
+
+ // descale
+ __m128i rw = _mm_srai_epi16(rws, 4);
+ __m128i bw = _mm_srai_epi16(bws, 4);
+ __m128i gw = _mm_srai_epi16(gws, 4);
+
+ // back to byte, set up for transpose
+ __m128i brb = _mm_packus_epi16(rw, bw);
+ __m128i gxb = _mm_packus_epi16(gw, xw);
+
+ // transpose to interleave channels
+ __m128i t0 = _mm_unpacklo_epi8(brb, gxb);
+ __m128i t1 = _mm_unpackhi_epi8(brb, gxb);
+ __m128i o0 = _mm_unpacklo_epi16(t0, t1);
+ __m128i o1 = _mm_unpackhi_epi16(t0, t1);
+
+ // store
+ _mm_storeu_si128((__m128i *) (out + 0), o0);
+ _mm_storeu_si128((__m128i *) (out + 16), o1);
+ out += 32;
+ }
+ }
+#endif
+
+#ifdef STBI_NEON
+ // in this version, step=3 support would be easy to add. but is there demand?
+ if (step == 4) {
+ // this is a fairly straightforward implementation and not super-optimized.
+ uint8x8_t signflip = vdup_n_u8(0x80);
+ int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f));
+ int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f));
+ int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f));
+ int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f));
+
+ for (; i+7 < count; i += 8) {
+ // load
+ uint8x8_t y_bytes = vld1_u8(y + i);
+ uint8x8_t cr_bytes = vld1_u8(pcr + i);
+ uint8x8_t cb_bytes = vld1_u8(pcb + i);
+ int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip));
+ int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip));
+
+ // expand to s16
+ int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4));
+ int16x8_t crw = vshll_n_s8(cr_biased, 7);
+ int16x8_t cbw = vshll_n_s8(cb_biased, 7);
+
+ // color transform
+ int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0);
+ int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0);
+ int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1);
+ int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1);
+ int16x8_t rws = vaddq_s16(yws, cr0);
+ int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1);
+ int16x8_t bws = vaddq_s16(yws, cb1);
+
+ // undo scaling, round, convert to byte
+ uint8x8x4_t o;
+ o.val[0] = vqrshrun_n_s16(rws, 4);
+ o.val[1] = vqrshrun_n_s16(gws, 4);
+ o.val[2] = vqrshrun_n_s16(bws, 4);
+ o.val[3] = vdup_n_u8(255);
+
+ // store, interleaving r/g/b/a
+ vst4_u8(out, o);
+ out += 8*4;
+ }
+ }
+#endif
+
+ for (; i < count; ++i) {
+ int y_fixed = (y[i] << 20) + (1<<19); // rounding
+ int r,g,b;
+ int cr = pcr[i] - 128;
+ int cb = pcb[i] - 128;
+ r = y_fixed + cr* stbi__float2fixed(1.40200f);
+ g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
+ b = y_fixed + cb* stbi__float2fixed(1.77200f);
+ r >>= 20;
+ g >>= 20;
+ b >>= 20;
+ if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; }
+ if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; }
+ if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; }
+ out[0] = (stbi_uc)r;
+ out[1] = (stbi_uc)g;
+ out[2] = (stbi_uc)b;
+ out[3] = 255;
+ out += step;
+ }
+}
+#endif
+
+// set up the kernels
+static void stbi__setup_jpeg(stbi__jpeg *j)
+{
+ j->idct_block_kernel = stbi__idct_block;
+ j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row;
+ j->resample_row_hv_2_kernel = stbi__resample_row_hv_2;
+
+#ifdef STBI_SSE2
+ if (stbi__sse2_available()) {
+ j->idct_block_kernel = stbi__idct_simd;
+ j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
+ j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
+ }
+#endif
+
+#ifdef STBI_NEON
+ j->idct_block_kernel = stbi__idct_simd;
+ j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
+ j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
+#endif
+}
+
+// clean up the temporary component buffers
+static void stbi__cleanup_jpeg(stbi__jpeg *j)
+{
+ stbi__free_jpeg_components(j, j->s->img_n, 0);
+}
+
+typedef struct
+{
+ resample_row_func resample;
+ stbi_uc *line0,*line1;
+ int hs,vs; // expansion factor in each axis
+ int w_lores; // horizontal pixels pre-expansion
+ int ystep; // how far through vertical expansion we are
+ int ypos; // which pre-expansion row we're on
+} stbi__resample;
+
+// fast 0..255 * 0..255 => 0..255 rounded multiplication
+static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y)
+{
+ unsigned int t = x*y + 128;
+ return (stbi_uc) ((t + (t >>8)) >> 8);
+}
+
+static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp)
+{
+ int n, decode_n, is_rgb;
+ z->s->img_n = 0; // make stbi__cleanup_jpeg safe
+
+ // validate req_comp
+ if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
+
+ // load a jpeg image from whichever source, but leave in YCbCr format
+ if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; }
+
+ // determine actual number of components to generate
+ n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1;
+
+ is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif));
+
+ if (z->s->img_n == 3 && n < 3 && !is_rgb)
+ decode_n = 1;
+ else
+ decode_n = z->s->img_n;
+
+ // resample and color-convert
+ {
+ int k;
+ unsigned int i,j;
+ stbi_uc *output;
+ stbi_uc *coutput[4];
+
+ stbi__resample res_comp[4];
+
+ for (k=0; k < decode_n; ++k) {
+ stbi__resample *r = &res_comp[k];
+
+ // allocate line buffer big enough for upsampling off the edges
+ // with upsample factor of 4
+ z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3);
+ if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); }
+
+ r->hs = z->img_h_max / z->img_comp[k].h;
+ r->vs = z->img_v_max / z->img_comp[k].v;
+ r->ystep = r->vs >> 1;
+ r->w_lores = (z->s->img_x + r->hs-1) / r->hs;
+ r->ypos = 0;
+ r->line0 = r->line1 = z->img_comp[k].data;
+
+ if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1;
+ else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2;
+ else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2;
+ else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel;
+ else r->resample = stbi__resample_row_generic;
+ }
+
+ // can't error after this so, this is safe
+ output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1);
+ if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); }
+
+ // now go ahead and resample
+ for (j=0; j < z->s->img_y; ++j) {
+ stbi_uc *out = output + n * z->s->img_x * j;
+ for (k=0; k < decode_n; ++k) {
+ stbi__resample *r = &res_comp[k];
+ int y_bot = r->ystep >= (r->vs >> 1);
+ coutput[k] = r->resample(z->img_comp[k].linebuf,
+ y_bot ? r->line1 : r->line0,
+ y_bot ? r->line0 : r->line1,
+ r->w_lores, r->hs);
+ if (++r->ystep >= r->vs) {
+ r->ystep = 0;
+ r->line0 = r->line1;
+ if (++r->ypos < z->img_comp[k].y)
+ r->line1 += z->img_comp[k].w2;
+ }
+ }
+ if (n >= 3) {
+ stbi_uc *y = coutput[0];
+ if (z->s->img_n == 3) {
+ if (is_rgb) {
+ for (i=0; i < z->s->img_x; ++i) {
+ out[0] = y[i];
+ out[1] = coutput[1][i];
+ out[2] = coutput[2][i];
+ out[3] = 255;
+ out += n;
+ }
+ } else {
+ z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
+ }
+ } else if (z->s->img_n == 4) {
+ if (z->app14_color_transform == 0) { // CMYK
+ for (i=0; i < z->s->img_x; ++i) {
+ stbi_uc m = coutput[3][i];
+ out[0] = stbi__blinn_8x8(coutput[0][i], m);
+ out[1] = stbi__blinn_8x8(coutput[1][i], m);
+ out[2] = stbi__blinn_8x8(coutput[2][i], m);
+ out[3] = 255;
+ out += n;
+ }
+ } else if (z->app14_color_transform == 2) { // YCCK
+ z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
+ for (i=0; i < z->s->img_x; ++i) {
+ stbi_uc m = coutput[3][i];
+ out[0] = stbi__blinn_8x8(255 - out[0], m);
+ out[1] = stbi__blinn_8x8(255 - out[1], m);
+ out[2] = stbi__blinn_8x8(255 - out[2], m);
+ out += n;
+ }
+ } else { // YCbCr + alpha? Ignore the fourth channel for now
+ z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
+ }
+ } else
+ for (i=0; i < z->s->img_x; ++i) {
+ out[0] = out[1] = out[2] = y[i];
+ out[3] = 255; // not used if n==3
+ out += n;
+ }
+ } else {
+ if (is_rgb) {
+ if (n == 1)
+ for (i=0; i < z->s->img_x; ++i)
+ *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
+ else {
+ for (i=0; i < z->s->img_x; ++i, out += 2) {
+ out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
+ out[1] = 255;
+ }
+ }
+ } else if (z->s->img_n == 4 && z->app14_color_transform == 0) {
+ for (i=0; i < z->s->img_x; ++i) {
+ stbi_uc m = coutput[3][i];
+ stbi_uc r = stbi__blinn_8x8(coutput[0][i], m);
+ stbi_uc g = stbi__blinn_8x8(coutput[1][i], m);
+ stbi_uc b = stbi__blinn_8x8(coutput[2][i], m);
+ out[0] = stbi__compute_y(r, g, b);
+ out[1] = 255;
+ out += n;
+ }
+ } else if (z->s->img_n == 4 && z->app14_color_transform == 2) {
+ for (i=0; i < z->s->img_x; ++i) {
+ out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]);
+ out[1] = 255;
+ out += n;
+ }
+ } else {
+ stbi_uc *y = coutput[0];
+ if (n == 1)
+ for (i=0; i < z->s->img_x; ++i) out[i] = y[i];
+ else
+ for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255;
+ }
+ }
+ }
+ stbi__cleanup_jpeg(z);
+ *out_x = z->s->img_x;
+ *out_y = z->s->img_y;
+ if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output
+ return output;
+ }
+}
+
+static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
+{
+ unsigned char* result;
+ stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
+ STBI_NOTUSED(ri);
+ j->s = s;
+ stbi__setup_jpeg(j);
+ result = load_jpeg_image(j, x,y,comp,req_comp);
+ STBI_FREE(j);
+ return result;
+}
+
+static int stbi__jpeg_test(stbi__context *s)
+{
+ int r;
+ stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg));
+ j->s = s;
+ stbi__setup_jpeg(j);
+ r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
+ stbi__rewind(s);
+ STBI_FREE(j);
+ return r;
+}
+
+static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp)
+{
+ if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) {
+ stbi__rewind( j->s );
+ return 0;
+ }
+ if (x) *x = j->s->img_x;
+ if (y) *y = j->s->img_y;
+ if (comp) *comp = j->s->img_n >= 3 ? 3 : 1;
+ return 1;
+}
+
+static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
+{
+ int result;
+ stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
+ j->s = s;
+ result = stbi__jpeg_info_raw(j, x, y, comp);
+ STBI_FREE(j);
+ return result;
+}
+#endif
+
+// public domain zlib decode v0.2 Sean Barrett 2006-11-18
+// simple implementation
+// - all input must be provided in an upfront buffer
+// - all output is written to a single output buffer (can malloc/realloc)
+// performance
+// - fast huffman
+
+#ifndef STBI_NO_ZLIB
+
+// fast-way is faster to check than jpeg huffman, but slow way is slower
+#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables
+#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1)
+
+// zlib-style huffman encoding
+// (jpegs packs from left, zlib from right, so can't share code)
+typedef struct
+{
+ stbi__uint16 fast[1 << STBI__ZFAST_BITS];
+ stbi__uint16 firstcode[16];
+ int maxcode[17];
+ stbi__uint16 firstsymbol[16];
+ stbi_uc size[288];
+ stbi__uint16 value[288];
+} stbi__zhuffman;
+
+stbi_inline static int stbi__bitreverse16(int n)
+{
+ n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1);
+ n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2);
+ n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4);
+ n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8);
+ return n;
+}
+
+stbi_inline static int stbi__bit_reverse(int v, int bits)
+{
+ STBI_ASSERT(bits <= 16);
+ // to bit reverse n bits, reverse 16 and shift
+ // e.g. 11 bits, bit reverse and shift away 5
+ return stbi__bitreverse16(v) >> (16-bits);
+}
+
+static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num)
+{
+ int i,k=0;
+ int code, next_code[16], sizes[17];
+
+ // DEFLATE spec for generating codes
+ memset(sizes, 0, sizeof(sizes));
+ memset(z->fast, 0, sizeof(z->fast));
+ for (i=0; i < num; ++i)
+ ++sizes[sizelist[i]];
+ sizes[0] = 0;
+ for (i=1; i < 16; ++i)
+ if (sizes[i] > (1 << i))
+ return stbi__err("bad sizes", "Corrupt PNG");
+ code = 0;
+ for (i=1; i < 16; ++i) {
+ next_code[i] = code;
+ z->firstcode[i] = (stbi__uint16) code;
+ z->firstsymbol[i] = (stbi__uint16) k;
+ code = (code + sizes[i]);
+ if (sizes[i])
+ if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG");
+ z->maxcode[i] = code << (16-i); // preshift for inner loop
+ code <<= 1;
+ k += sizes[i];
+ }
+ z->maxcode[16] = 0x10000; // sentinel
+ for (i=0; i < num; ++i) {
+ int s = sizelist[i];
+ if (s) {
+ int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s];
+ stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i);
+ z->size [c] = (stbi_uc ) s;
+ z->value[c] = (stbi__uint16) i;
+ if (s <= STBI__ZFAST_BITS) {
+ int j = stbi__bit_reverse(next_code[s],s);
+ while (j < (1 << STBI__ZFAST_BITS)) {
+ z->fast[j] = fastv;
+ j += (1 << s);
+ }
+ }
+ ++next_code[s];
+ }
+ }
+ return 1;
+}
+
+// zlib-from-memory implementation for PNG reading
+// because PNG allows splitting the zlib stream arbitrarily,
+// and it's annoying structurally to have PNG call ZLIB call PNG,
+// we require PNG read all the IDATs and combine them into a single
+// memory buffer
+
+typedef struct
+{
+ stbi_uc *zbuffer, *zbuffer_end;
+ int num_bits;
+ stbi__uint32 code_buffer;
+
+ char *zout;
+ char *zout_start;
+ char *zout_end;
+ int z_expandable;
+
+ stbi__zhuffman z_length, z_distance;
+} stbi__zbuf;
+
+stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z)
+{
+ if (z->zbuffer >= z->zbuffer_end) return 0;
+ return *z->zbuffer++;
+}
+
+static void stbi__fill_bits(stbi__zbuf *z)
+{
+ do {
+ STBI_ASSERT(z->code_buffer < (1U << z->num_bits));
+ z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits;
+ z->num_bits += 8;
+ } while (z->num_bits <= 24);
+}
+
+stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n)
+{
+ unsigned int k;
+ if (z->num_bits < n) stbi__fill_bits(z);
+ k = z->code_buffer & ((1 << n) - 1);
+ z->code_buffer >>= n;
+ z->num_bits -= n;
+ return k;
+}
+
+static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
+{
+ int b,s,k;
+ // not resolved by fast table, so compute it the slow way
+ // use jpeg approach, which requires MSbits at top
+ k = stbi__bit_reverse(a->code_buffer, 16);
+ for (s=STBI__ZFAST_BITS+1; ; ++s)
+ if (k < z->maxcode[s])
+ break;
+ if (s == 16) return -1; // invalid code!
+ // code size is s, so:
+ b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
+ STBI_ASSERT(z->size[b] == s);
+ a->code_buffer >>= s;
+ a->num_bits -= s;
+ return z->value[b];
+}
+
+stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
+{
+ int b,s;
+ if (a->num_bits < 16) stbi__fill_bits(a);
+ b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
+ if (b) {
+ s = b >> 9;
+ a->code_buffer >>= s;
+ a->num_bits -= s;
+ return b & 511;
+ }
+ return stbi__zhuffman_decode_slowpath(a, z);
+}
+
+static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes
+{
+ char *q;
+ int cur, limit, old_limit;
+ z->zout = zout;
+ if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG");
+ cur = (int) (z->zout - z->zout_start);
+ limit = old_limit = (int) (z->zout_end - z->zout_start);
+ while (cur + n > limit)
+ limit *= 2;
+ q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
+ STBI_NOTUSED(old_limit);
+ if (q == NULL) return stbi__err("outofmem", "Out of memory");
+ z->zout_start = q;
+ z->zout = q + cur;
+ z->zout_end = q + limit;
+ return 1;
+}
+
+static const int stbi__zlength_base[31] = {
+ 3,4,5,6,7,8,9,10,11,13,
+ 15,17,19,23,27,31,35,43,51,59,
+ 67,83,99,115,131,163,195,227,258,0,0 };
+
+static const int stbi__zlength_extra[31]=
+{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 };
+
+static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,
+257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0};
+
+static const int stbi__zdist_extra[32] =
+{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+static int stbi__parse_huffman_block(stbi__zbuf *a)
+{
+ char *zout = a->zout;
+ for(;;) {
+ int z = stbi__zhuffman_decode(a, &a->z_length);
+ if (z < 256) {
+ if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes
+ if (zout >= a->zout_end) {
+ if (!stbi__zexpand(a, zout, 1)) return 0;
+ zout = a->zout;
+ }
+ *zout++ = (char) z;
+ } else {
+ stbi_uc *p;
+ int len,dist;
+ if (z == 256) {
+ a->zout = zout;
+ return 1;
+ }
+ z -= 257;
+ len = stbi__zlength_base[z];
+ if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]);
+ z = stbi__zhuffman_decode(a, &a->z_distance);
+ if (z < 0) return stbi__err("bad huffman code","Corrupt PNG");
+ dist = stbi__zdist_base[z];
+ if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]);
+ if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG");
+ if (zout + len > a->zout_end) {
+ if (!stbi__zexpand(a, zout, len)) return 0;
+ zout = a->zout;
+ }
+ p = (stbi_uc *) (zout - dist);
+ if (dist == 1) { // run of one byte; common in images.
+ stbi_uc v = *p;
+ if (len) { do *zout++ = v; while (--len); }
+ } else {
+ if (len) { do *zout++ = *p++; while (--len); }
+ }
+ }
+ }
+}
+
+static int stbi__compute_huffman_codes(stbi__zbuf *a)
+{
+ static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
+ stbi__zhuffman z_codelength;
+ stbi_uc lencodes[286+32+137];//padding for maximum single op
+ stbi_uc codelength_sizes[19];
+ int i,n;
+
+ int hlit = stbi__zreceive(a,5) + 257;
+ int hdist = stbi__zreceive(a,5) + 1;
+ int hclen = stbi__zreceive(a,4) + 4;
+ int ntot = hlit + hdist;
+
+ memset(codelength_sizes, 0, sizeof(codelength_sizes));
+ for (i=0; i < hclen; ++i) {
+ int s = stbi__zreceive(a,3);
+ codelength_sizes[length_dezigzag[i]] = (stbi_uc) s;
+ }
+ if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0;
+
+ n = 0;
+ while (n < ntot) {
+ int c = stbi__zhuffman_decode(a, &z_codelength);
+ if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG");
+ if (c < 16)
+ lencodes[n++] = (stbi_uc) c;
+ else {
+ stbi_uc fill = 0;
+ if (c == 16) {
+ c = stbi__zreceive(a,2)+3;
+ if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG");
+ fill = lencodes[n-1];
+ } else if (c == 17)
+ c = stbi__zreceive(a,3)+3;
+ else {
+ STBI_ASSERT(c == 18);
+ c = stbi__zreceive(a,7)+11;
+ }
+ if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG");
+ memset(lencodes+n, fill, c);
+ n += c;
+ }
+ }
+ if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG");
+ if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0;
+ if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0;
+ return 1;
+}
+
+static int stbi__parse_uncompressed_block(stbi__zbuf *a)
+{
+ stbi_uc header[4];
+ int len,nlen,k;
+ if (a->num_bits & 7)
+ stbi__zreceive(a, a->num_bits & 7); // discard
+ // drain the bit-packed data into header
+ k = 0;
+ while (a->num_bits > 0) {
+ header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check
+ a->code_buffer >>= 8;
+ a->num_bits -= 8;
+ }
+ STBI_ASSERT(a->num_bits == 0);
+ // now fill header the normal way
+ while (k < 4)
+ header[k++] = stbi__zget8(a);
+ len = header[1] * 256 + header[0];
+ nlen = header[3] * 256 + header[2];
+ if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG");
+ if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG");
+ if (a->zout + len > a->zout_end)
+ if (!stbi__zexpand(a, a->zout, len)) return 0;
+ memcpy(a->zout, a->zbuffer, len);
+ a->zbuffer += len;
+ a->zout += len;
+ return 1;
+}
+
+static int stbi__parse_zlib_header(stbi__zbuf *a)
+{
+ int cmf = stbi__zget8(a);
+ int cm = cmf & 15;
+ /* int cinfo = cmf >> 4; */
+ int flg = stbi__zget8(a);
+ if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
+ if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png
+ if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png
+ // window = 1 << (8 + cinfo)... but who cares, we fully buffer output
+ return 1;
+}
+
+static const stbi_uc stbi__zdefault_length[288] =
+{
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8
+};
+static const stbi_uc stbi__zdefault_distance[32] =
+{
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
+};
+/*
+Init algorithm:
+{
+ int i; // use <= to match clearly with spec
+ for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8;
+ for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9;
+ for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7;
+ for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8;
+
+ for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5;
+}
+*/
+
+static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
+{
+ int final, type;
+ if (parse_header)
+ if (!stbi__parse_zlib_header(a)) return 0;
+ a->num_bits = 0;
+ a->code_buffer = 0;
+ do {
+ final = stbi__zreceive(a,1);
+ type = stbi__zreceive(a,2);
+ if (type == 0) {
+ if (!stbi__parse_uncompressed_block(a)) return 0;
+ } else if (type == 3) {
+ return 0;
+ } else {
+ if (type == 1) {
+ // use fixed code lengths
+ if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0;
+ if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0;
+ } else {
+ if (!stbi__compute_huffman_codes(a)) return 0;
+ }
+ if (!stbi__parse_huffman_block(a)) return 0;
+ }
+ } while (!final);
+ return 1;
+}
+
+static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header)
+{
+ a->zout_start = obuf;
+ a->zout = obuf;
+ a->zout_end = obuf + olen;
+ a->z_expandable = exp;
+
+ return stbi__parse_zlib(a, parse_header);
+}
+
+STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen)
+{
+ stbi__zbuf a;
+ char *p = (char *) stbi__malloc(initial_size);
+ if (p == NULL) return NULL;
+ a.zbuffer = (stbi_uc *) buffer;
+ a.zbuffer_end = (stbi_uc *) buffer + len;
+ if (stbi__do_zlib(&a, p, initial_size, 1, 1)) {
+ if (outlen) *outlen = (int) (a.zout - a.zout_start);
+ return a.zout_start;
+ } else {
+ STBI_FREE(a.zout_start);
+ return NULL;
+ }
+}
+
+STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen)
+{
+ return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen);
+}
+
+STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header)
+{
+ stbi__zbuf a;
+ char *p = (char *) stbi__malloc(initial_size);
+ if (p == NULL) return NULL;
+ a.zbuffer = (stbi_uc *) buffer;
+ a.zbuffer_end = (stbi_uc *) buffer + len;
+ if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) {
+ if (outlen) *outlen = (int) (a.zout - a.zout_start);
+ return a.zout_start;
+ } else {
+ STBI_FREE(a.zout_start);
+ return NULL;
+ }
+}
+
+STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen)
+{
+ stbi__zbuf a;
+ a.zbuffer = (stbi_uc *) ibuffer;
+ a.zbuffer_end = (stbi_uc *) ibuffer + ilen;
+ if (stbi__do_zlib(&a, obuffer, olen, 0, 1))
+ return (int) (a.zout - a.zout_start);
+ else
+ return -1;
+}
+
+STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen)
+{
+ stbi__zbuf a;
+ char *p = (char *) stbi__malloc(16384);
+ if (p == NULL) return NULL;
+ a.zbuffer = (stbi_uc *) buffer;
+ a.zbuffer_end = (stbi_uc *) buffer+len;
+ if (stbi__do_zlib(&a, p, 16384, 1, 0)) {
+ if (outlen) *outlen = (int) (a.zout - a.zout_start);
+ return a.zout_start;
+ } else {
+ STBI_FREE(a.zout_start);
+ return NULL;
+ }
+}
+
+STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen)
+{
+ stbi__zbuf a;
+ a.zbuffer = (stbi_uc *) ibuffer;
+ a.zbuffer_end = (stbi_uc *) ibuffer + ilen;
+ if (stbi__do_zlib(&a, obuffer, olen, 0, 0))
+ return (int) (a.zout - a.zout_start);
+ else
+ return -1;
+}
+#endif
+
+// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18
+// simple implementation
+// - only 8-bit samples
+// - no CRC checking
+// - allocates lots of intermediate memory
+// - avoids problem of streaming data between subsystems
+// - avoids explicit window management
+// performance
+// - uses stb_zlib, a PD zlib implementation with fast huffman decoding
+
+#ifndef STBI_NO_PNG
+typedef struct
+{
+ stbi__uint32 length;
+ stbi__uint32 type;
+} stbi__pngchunk;
+
+static stbi__pngchunk stbi__get_chunk_header(stbi__context *s)
+{
+ stbi__pngchunk c;
+ c.length = stbi__get32be(s);
+ c.type = stbi__get32be(s);
+ return c;
+}
+
+static int stbi__check_png_header(stbi__context *s)
+{
+ static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 };
+ int i;
+ for (i=0; i < 8; ++i)
+ if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG");
+ return 1;
+}
+
+typedef struct
+{
+ stbi__context *s;
+ stbi_uc *idata, *expanded, *out;
+ int depth;
+} stbi__png;
+
+
+enum {
+ STBI__F_none=0,
+ STBI__F_sub=1,
+ STBI__F_up=2,
+ STBI__F_avg=3,
+ STBI__F_paeth=4,
+ // synthetic filters used for first scanline to avoid needing a dummy row of 0s
+ STBI__F_avg_first,
+ STBI__F_paeth_first
+};
+
+static stbi_uc first_row_filter[5] =
+{
+ STBI__F_none,
+ STBI__F_sub,
+ STBI__F_none,
+ STBI__F_avg_first,
+ STBI__F_paeth_first
+};
+
+static int stbi__paeth(int a, int b, int c)
+{
+ int p = a + b - c;
+ int pa = abs(p-a);
+ int pb = abs(p-b);
+ int pc = abs(p-c);
+ if (pa <= pb && pa <= pc) return a;
+ if (pb <= pc) return b;
+ return c;
+}
+
+static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 };
+
+// create the png data from post-deflated data
+static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color)
+{
+ int bytes = (depth == 16? 2 : 1);
+ stbi__context *s = a->s;
+ stbi__uint32 i,j,stride = x*out_n*bytes;
+ stbi__uint32 img_len, img_width_bytes;
+ int k;
+ int img_n = s->img_n; // copy it into a local for later
+
+ int output_bytes = out_n*bytes;
+ int filter_bytes = img_n*bytes;
+ int width = x;
+
+ STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1);
+ a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into
+ if (!a->out) return stbi__err("outofmem", "Out of memory");
+
+ if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG");
+ img_width_bytes = (((img_n * x * depth) + 7) >> 3);
+ img_len = (img_width_bytes + 1) * y;
+
+ // we used to check for exact match between raw_len and img_len on non-interlaced PNGs,
+ // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros),
+ // so just check for raw_len < img_len always.
+ if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG");
+
+ for (j=0; j < y; ++j) {
+ stbi_uc *cur = a->out + stride*j;
+ stbi_uc *prior;
+ int filter = *raw++;
+
+ if (filter > 4)
+ return stbi__err("invalid filter","Corrupt PNG");
+
+ if (depth < 8) {
+ STBI_ASSERT(img_width_bytes <= x);
+ cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
+ filter_bytes = 1;
+ width = img_width_bytes;
+ }
+ prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above
+
+ // if first row, use special filter that doesn't sample previous row
+ if (j == 0) filter = first_row_filter[filter];
+
+ // handle first byte explicitly
+ for (k=0; k < filter_bytes; ++k) {
+ switch (filter) {
+ case STBI__F_none : cur[k] = raw[k]; break;
+ case STBI__F_sub : cur[k] = raw[k]; break;
+ case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
+ case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break;
+ case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break;
+ case STBI__F_avg_first : cur[k] = raw[k]; break;
+ case STBI__F_paeth_first: cur[k] = raw[k]; break;
+ }
+ }
+
+ if (depth == 8) {
+ if (img_n != out_n)
+ cur[img_n] = 255; // first pixel
+ raw += img_n;
+ cur += out_n;
+ prior += out_n;
+ } else if (depth == 16) {
+ if (img_n != out_n) {
+ cur[filter_bytes] = 255; // first pixel top byte
+ cur[filter_bytes+1] = 255; // first pixel bottom byte
+ }
+ raw += filter_bytes;
+ cur += output_bytes;
+ prior += output_bytes;
+ } else {
+ raw += 1;
+ cur += 1;
+ prior += 1;
+ }
+
+ // this is a little gross, so that we don't switch per-pixel or per-component
+ if (depth < 8 || img_n == out_n) {
+ int nk = (width - 1)*filter_bytes;
+ #define STBI__CASE(f) \
+ case f: \
+ for (k=0; k < nk; ++k)
+ switch (filter) {
+ // "none" filter turns into a memcpy here; make that explicit.
+ case STBI__F_none: memcpy(cur, raw, nk); break;
+ STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break;
+ STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
+ STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break;
+ STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break;
+ STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break;
+ STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break;
+ }
+ #undef STBI__CASE
+ raw += nk;
+ } else {
+ STBI_ASSERT(img_n+1 == out_n);
+ #define STBI__CASE(f) \
+ case f: \
+ for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \
+ for (k=0; k < filter_bytes; ++k)
+ switch (filter) {
+ STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break;
+ STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break;
+ STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break;
+ STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break;
+ STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break;
+ STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break;
+ STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break;
+ }
+ #undef STBI__CASE
+
+ // the loop above sets the high byte of the pixels' alpha, but for
+ // 16 bit png files we also need the low byte set. we'll do that here.
+ if (depth == 16) {
+ cur = a->out + stride*j; // start at the beginning of the row again
+ for (i=0; i < x; ++i,cur+=output_bytes) {
+ cur[filter_bytes+1] = 255;
+ }
+ }
+ }
+ }
+
+ // we make a separate pass to expand bits to pixels; for performance,
+ // this could run two scanlines behind the above code, so it won't
+ // intefere with filtering but will still be in the cache.
+ if (depth < 8) {
+ for (j=0; j < y; ++j) {
+ stbi_uc *cur = a->out + stride*j;
+ stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes;
+ // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit
+ // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop
+ stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range
+
+ // note that the final byte might overshoot and write more data than desired.
+ // we can allocate enough data that this never writes out of memory, but it
+ // could also overwrite the next scanline. can it overwrite non-empty data
+ // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel.
+ // so we need to explicitly clamp the final ones
+
+ if (depth == 4) {
+ for (k=x*img_n; k >= 2; k-=2, ++in) {
+ *cur++ = scale * ((*in >> 4) );
+ *cur++ = scale * ((*in ) & 0x0f);
+ }
+ if (k > 0) *cur++ = scale * ((*in >> 4) );
+ } else if (depth == 2) {
+ for (k=x*img_n; k >= 4; k-=4, ++in) {
+ *cur++ = scale * ((*in >> 6) );
+ *cur++ = scale * ((*in >> 4) & 0x03);
+ *cur++ = scale * ((*in >> 2) & 0x03);
+ *cur++ = scale * ((*in ) & 0x03);
+ }
+ if (k > 0) *cur++ = scale * ((*in >> 6) );
+ if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03);
+ if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03);
+ } else if (depth == 1) {
+ for (k=x*img_n; k >= 8; k-=8, ++in) {
+ *cur++ = scale * ((*in >> 7) );
+ *cur++ = scale * ((*in >> 6) & 0x01);
+ *cur++ = scale * ((*in >> 5) & 0x01);
+ *cur++ = scale * ((*in >> 4) & 0x01);
+ *cur++ = scale * ((*in >> 3) & 0x01);
+ *cur++ = scale * ((*in >> 2) & 0x01);
+ *cur++ = scale * ((*in >> 1) & 0x01);
+ *cur++ = scale * ((*in ) & 0x01);
+ }
+ if (k > 0) *cur++ = scale * ((*in >> 7) );
+ if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01);
+ if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01);
+ if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01);
+ if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01);
+ if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01);
+ if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01);
+ }
+ if (img_n != out_n) {
+ int q;
+ // insert alpha = 255
+ cur = a->out + stride*j;
+ if (img_n == 1) {
+ for (q=x-1; q >= 0; --q) {
+ cur[q*2+1] = 255;
+ cur[q*2+0] = cur[q];
+ }
+ } else {
+ STBI_ASSERT(img_n == 3);
+ for (q=x-1; q >= 0; --q) {
+ cur[q*4+3] = 255;
+ cur[q*4+2] = cur[q*3+2];
+ cur[q*4+1] = cur[q*3+1];
+ cur[q*4+0] = cur[q*3+0];
+ }
+ }
+ }
+ }
+ } else if (depth == 16) {
+ // force the image data from big-endian to platform-native.
+ // this is done in a separate pass due to the decoding relying
+ // on the data being untouched, but could probably be done
+ // per-line during decode if care is taken.
+ stbi_uc *cur = a->out;
+ stbi__uint16 *cur16 = (stbi__uint16*)cur;
+
+ for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) {
+ *cur16 = (cur[0] << 8) | cur[1];
+ }
+ }
+
+ return 1;
+}
+
+static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced)
+{
+ int bytes = (depth == 16 ? 2 : 1);
+ int out_bytes = out_n * bytes;
+ stbi_uc *final;
+ int p;
+ if (!interlaced)
+ return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color);
+
+ // de-interlacing
+ final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0);
+ for (p=0; p < 7; ++p) {
+ int xorig[] = { 0,4,0,2,0,1,0 };
+ int yorig[] = { 0,0,4,0,2,0,1 };
+ int xspc[] = { 8,8,4,4,2,2,1 };
+ int yspc[] = { 8,8,8,4,4,2,2 };
+ int i,j,x,y;
+ // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1
+ x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p];
+ y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p];
+ if (x && y) {
+ stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y;
+ if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) {
+ STBI_FREE(final);
+ return 0;
+ }
+ for (j=0; j < y; ++j) {
+ for (i=0; i < x; ++i) {
+ int out_y = j*yspc[p]+yorig[p];
+ int out_x = i*xspc[p]+xorig[p];
+ memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes,
+ a->out + (j*x+i)*out_bytes, out_bytes);
+ }
+ }
+ STBI_FREE(a->out);
+ image_data += img_len;
+ image_data_len -= img_len;
+ }
+ }
+ a->out = final;
+
+ return 1;
+}
+
+static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n)
+{
+ stbi__context *s = z->s;
+ stbi__uint32 i, pixel_count = s->img_x * s->img_y;
+ stbi_uc *p = z->out;
+
+ // compute color-based transparency, assuming we've
+ // already got 255 as the alpha value in the output
+ STBI_ASSERT(out_n == 2 || out_n == 4);
+
+ if (out_n == 2) {
+ for (i=0; i < pixel_count; ++i) {
+ p[1] = (p[0] == tc[0] ? 0 : 255);
+ p += 2;
+ }
+ } else {
+ for (i=0; i < pixel_count; ++i) {
+ if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2])
+ p[3] = 0;
+ p += 4;
+ }
+ }
+ return 1;
+}
+
+static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n)
+{
+ stbi__context *s = z->s;
+ stbi__uint32 i, pixel_count = s->img_x * s->img_y;
+ stbi__uint16 *p = (stbi__uint16*) z->out;
+
+ // compute color-based transparency, assuming we've
+ // already got 65535 as the alpha value in the output
+ STBI_ASSERT(out_n == 2 || out_n == 4);
+
+ if (out_n == 2) {
+ for (i = 0; i < pixel_count; ++i) {
+ p[1] = (p[0] == tc[0] ? 0 : 65535);
+ p += 2;
+ }
+ } else {
+ for (i = 0; i < pixel_count; ++i) {
+ if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2])
+ p[3] = 0;
+ p += 4;
+ }
+ }
+ return 1;
+}
+
+static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n)
+{
+ stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y;
+ stbi_uc *p, *temp_out, *orig = a->out;
+
+ p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0);
+ if (p == NULL) return stbi__err("outofmem", "Out of memory");
+
+ // between here and free(out) below, exitting would leak
+ temp_out = p;
+
+ if (pal_img_n == 3) {
+ for (i=0; i < pixel_count; ++i) {
+ int n = orig[i]*4;
+ p[0] = palette[n ];
+ p[1] = palette[n+1];
+ p[2] = palette[n+2];
+ p += 3;
+ }
+ } else {
+ for (i=0; i < pixel_count; ++i) {
+ int n = orig[i]*4;
+ p[0] = palette[n ];
+ p[1] = palette[n+1];
+ p[2] = palette[n+2];
+ p[3] = palette[n+3];
+ p += 4;
+ }
+ }
+ STBI_FREE(a->out);
+ a->out = temp_out;
+
+ STBI_NOTUSED(len);
+
+ return 1;
+}
+
+static int stbi__unpremultiply_on_load = 0;
+static int stbi__de_iphone_flag = 0;
+
+STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply)
+{
+ stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply;
+}
+
+STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert)
+{
+ stbi__de_iphone_flag = flag_true_if_should_convert;
+}
+
+static void stbi__de_iphone(stbi__png *z)
+{
+ stbi__context *s = z->s;
+ stbi__uint32 i, pixel_count = s->img_x * s->img_y;
+ stbi_uc *p = z->out;
+
+ if (s->img_out_n == 3) { // convert bgr to rgb
+ for (i=0; i < pixel_count; ++i) {
+ stbi_uc t = p[0];
+ p[0] = p[2];
+ p[2] = t;
+ p += 3;
+ }
+ } else {
+ STBI_ASSERT(s->img_out_n == 4);
+ if (stbi__unpremultiply_on_load) {
+ // convert bgr to rgb and unpremultiply
+ for (i=0; i < pixel_count; ++i) {
+ stbi_uc a = p[3];
+ stbi_uc t = p[0];
+ if (a) {
+ stbi_uc half = a / 2;
+ p[0] = (p[2] * 255 + half) / a;
+ p[1] = (p[1] * 255 + half) / a;
+ p[2] = ( t * 255 + half) / a;
+ } else {
+ p[0] = p[2];
+ p[2] = t;
+ }
+ p += 4;
+ }
+ } else {
+ // convert bgr to rgb
+ for (i=0; i < pixel_count; ++i) {
+ stbi_uc t = p[0];
+ p[0] = p[2];
+ p[2] = t;
+ p += 4;
+ }
+ }
+ }
+}
+
+#define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d))
+
+static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
+{
+ stbi_uc palette[1024], pal_img_n=0;
+ stbi_uc has_trans=0, tc[3];
+ stbi__uint16 tc16[3];
+ stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
+ int first=1,k,interlace=0, color=0, is_iphone=0;
+ stbi__context *s = z->s;
+
+ z->expanded = NULL;
+ z->idata = NULL;
+ z->out = NULL;
+
+ if (!stbi__check_png_header(s)) return 0;
+
+ if (scan == STBI__SCAN_type) return 1;
+
+ for (;;) {
+ stbi__pngchunk c = stbi__get_chunk_header(s);
+ switch (c.type) {
+ case STBI__PNG_TYPE('C','g','B','I'):
+ is_iphone = 1;
+ stbi__skip(s, c.length);
+ break;
+ case STBI__PNG_TYPE('I','H','D','R'): {
+ int comp,filter;
+ if (!first) return stbi__err("multiple IHDR","Corrupt PNG");
+ first = 0;
+ if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
+ s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
+ s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
+ z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
+ color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
+ if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
+ if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG");
+ comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG");
+ filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG");
+ interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG");
+ if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG");
+ if (!pal_img_n) {
+ s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0);
+ if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode");
+ if (scan == STBI__SCAN_header) return 1;
+ } else {
+ // if paletted, then pal_n is our final components, and
+ // img_n is # components to decompress/filter.
+ s->img_n = 1;
+ if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG");
+ // if SCAN_header, have to scan to see if we have a tRNS
+ }
+ break;
+ }
+
+ case STBI__PNG_TYPE('P','L','T','E'): {
+ if (first) return stbi__err("first not IHDR", "Corrupt PNG");
+ if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG");
+ pal_len = c.length / 3;
+ if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG");
+ for (i=0; i < pal_len; ++i) {
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ }
+ break;
+ }
+
+ case STBI__PNG_TYPE('t','R','N','S'): {
+ if (first) return stbi__err("first not IHDR", "Corrupt PNG");
+ if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG");
+ if (pal_img_n) {
+ if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; }
+ if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG");
+ if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG");
+ pal_img_n = 4;
+ for (i=0; i < c.length; ++i)
+ palette[i*4+3] = stbi__get8(s);
+ } else {
+ if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG");
+ if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
+ has_trans = 1;
+ if (z->depth == 16) {
+ for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
+ } else {
+ for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
+ }
+ }
+ break;
+ }
+
+ case STBI__PNG_TYPE('I','D','A','T'): {
+ if (first) return stbi__err("first not IHDR", "Corrupt PNG");
+ if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG");
+ if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; }
+ if ((int)(ioff + c.length) < (int)ioff) return 0;
+ if (ioff + c.length > idata_limit) {
+ stbi__uint32 idata_limit_old = idata_limit;
+ stbi_uc *p;
+ if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
+ while (ioff + c.length > idata_limit)
+ idata_limit *= 2;
+ STBI_NOTUSED(idata_limit_old);
+ p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory");
+ z->idata = p;
+ }
+ if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG");
+ ioff += c.length;
+ break;
+ }
+
+ case STBI__PNG_TYPE('I','E','N','D'): {
+ stbi__uint32 raw_len, bpl;
+ if (first) return stbi__err("first not IHDR", "Corrupt PNG");
+ if (scan != STBI__SCAN_load) return 1;
+ if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG");
+ // initial guess for decoded data size to avoid unnecessary reallocs
+ bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component
+ raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */;
+ z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone);
+ if (z->expanded == NULL) return 0; // zlib should set error
+ STBI_FREE(z->idata); z->idata = NULL;
+ if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans)
+ s->img_out_n = s->img_n+1;
+ else
+ s->img_out_n = s->img_n;
+ if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0;
+ if (has_trans) {
+ if (z->depth == 16) {
+ if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0;
+ } else {
+ if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0;
+ }
+ }
+ if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2)
+ stbi__de_iphone(z);
+ if (pal_img_n) {
+ // pal_img_n == 3 or 4
+ s->img_n = pal_img_n; // record the actual colors we had
+ s->img_out_n = pal_img_n;
+ if (req_comp >= 3) s->img_out_n = req_comp;
+ if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n))
+ return 0;
+ } else if (has_trans) {
+ // non-paletted image with tRNS -> source image has (constant) alpha
+ ++s->img_n;
+ }
+ STBI_FREE(z->expanded); z->expanded = NULL;
+ return 1;
+ }
+
+ default:
+ // if critical, fail
+ if (first) return stbi__err("first not IHDR", "Corrupt PNG");
+ if ((c.type & (1 << 29)) == 0) {
+ #ifndef STBI_NO_FAILURE_STRINGS
+ // not threadsafe
+ static char invalid_chunk[] = "XXXX PNG chunk not known";
+ invalid_chunk[0] = STBI__BYTECAST(c.type >> 24);
+ invalid_chunk[1] = STBI__BYTECAST(c.type >> 16);
+ invalid_chunk[2] = STBI__BYTECAST(c.type >> 8);
+ invalid_chunk[3] = STBI__BYTECAST(c.type >> 0);
+ #endif
+ return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type");
+ }
+ stbi__skip(s, c.length);
+ break;
+ }
+ // end of PNG chunk, read and skip CRC
+ stbi__get32be(s);
+ }
+}
+
+static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri)
+{
+ void *result=NULL;
+ if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
+ if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
+ if (p->depth < 8)
+ ri->bits_per_channel = 8;
+ else
+ ri->bits_per_channel = p->depth;
+ result = p->out;
+ p->out = NULL;
+ if (req_comp && req_comp != p->s->img_out_n) {
+ if (ri->bits_per_channel == 8)
+ result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y);
+ else
+ result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y);
+ p->s->img_out_n = req_comp;
+ if (result == NULL) return result;
+ }
+ *x = p->s->img_x;
+ *y = p->s->img_y;
+ if (n) *n = p->s->img_n;
+ }
+ STBI_FREE(p->out); p->out = NULL;
+ STBI_FREE(p->expanded); p->expanded = NULL;
+ STBI_FREE(p->idata); p->idata = NULL;
+
+ return result;
+}
+
+static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
+{
+ stbi__png p;
+ p.s = s;
+ return stbi__do_png(&p, x,y,comp,req_comp, ri);
+}
+
+static int stbi__png_test(stbi__context *s)
+{
+ int r;
+ r = stbi__check_png_header(s);
+ stbi__rewind(s);
+ return r;
+}
+
+static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp)
+{
+ if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) {
+ stbi__rewind( p->s );
+ return 0;
+ }
+ if (x) *x = p->s->img_x;
+ if (y) *y = p->s->img_y;
+ if (comp) *comp = p->s->img_n;
+ return 1;
+}
+
+static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp)
+{
+ stbi__png p;
+ p.s = s;
+ return stbi__png_info_raw(&p, x, y, comp);
+}
+
+static int stbi__png_is16(stbi__context *s)
+{
+ stbi__png p;
+ p.s = s;
+ if (!stbi__png_info_raw(&p, NULL, NULL, NULL))
+ return 0;
+ if (p.depth != 16) {
+ stbi__rewind(p.s);
+ return 0;
+ }
+ return 1;
+}
+#endif
+
+// Microsoft/Windows BMP image
+
+#ifndef STBI_NO_BMP
+static int stbi__bmp_test_raw(stbi__context *s)
+{
+ int r;
+ int sz;
+ if (stbi__get8(s) != 'B') return 0;
+ if (stbi__get8(s) != 'M') return 0;
+ stbi__get32le(s); // discard filesize
+ stbi__get16le(s); // discard reserved
+ stbi__get16le(s); // discard reserved
+ stbi__get32le(s); // discard data offset
+ sz = stbi__get32le(s);
+ r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124);
+ return r;
+}
+
+static int stbi__bmp_test(stbi__context *s)
+{
+ int r = stbi__bmp_test_raw(s);
+ stbi__rewind(s);
+ return r;
+}
+
+
+// returns 0..31 for the highest set bit
+static int stbi__high_bit(unsigned int z)
+{
+ int n=0;
+ if (z == 0) return -1;
+ if (z >= 0x10000) n += 16, z >>= 16;
+ if (z >= 0x00100) n += 8, z >>= 8;
+ if (z >= 0x00010) n += 4, z >>= 4;
+ if (z >= 0x00004) n += 2, z >>= 2;
+ if (z >= 0x00002) n += 1, z >>= 1;
+ return n;
+}
+
+static int stbi__bitcount(unsigned int a)
+{
+ a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2
+ a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4
+ a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits
+ a = (a + (a >> 8)); // max 16 per 8 bits
+ a = (a + (a >> 16)); // max 32 per 8 bits
+ return a & 0xff;
+}
+
+// extract an arbitrarily-aligned N-bit value (N=bits)
+// from v, and then make it 8-bits long and fractionally
+// extend it to full full range.
+static int stbi__shiftsigned(int v, int shift, int bits)
+{
+ static unsigned int mul_table[9] = {
+ 0,
+ 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/,
+ 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/,
+ };
+ static unsigned int shift_table[9] = {
+ 0, 0,0,1,0,2,4,6,0,
+ };
+ if (shift < 0)
+ v <<= -shift;
+ else
+ v >>= shift;
+ STBI_ASSERT(v >= 0 && v < 256);
+ v >>= (8-bits);
+ STBI_ASSERT(bits >= 0 && bits <= 8);
+ return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits];
+}
+
+typedef struct
+{
+ int bpp, offset, hsz;
+ unsigned int mr,mg,mb,ma, all_a;
+} stbi__bmp_data;
+
+static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
+{
+ int hsz;
+ if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP");
+ stbi__get32le(s); // discard filesize
+ stbi__get16le(s); // discard reserved
+ stbi__get16le(s); // discard reserved
+ info->offset = stbi__get32le(s);
+ info->hsz = hsz = stbi__get32le(s);
+ info->mr = info->mg = info->mb = info->ma = 0;
+
+ if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
+ if (hsz == 12) {
+ s->img_x = stbi__get16le(s);
+ s->img_y = stbi__get16le(s);
+ } else {
+ s->img_x = stbi__get32le(s);
+ s->img_y = stbi__get32le(s);
+ }
+ if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP");
+ info->bpp = stbi__get16le(s);
+ if (hsz != 12) {
+ int compress = stbi__get32le(s);
+ if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE");
+ stbi__get32le(s); // discard sizeof
+ stbi__get32le(s); // discard hres
+ stbi__get32le(s); // discard vres
+ stbi__get32le(s); // discard colorsused
+ stbi__get32le(s); // discard max important
+ if (hsz == 40 || hsz == 56) {
+ if (hsz == 56) {
+ stbi__get32le(s);
+ stbi__get32le(s);
+ stbi__get32le(s);
+ stbi__get32le(s);
+ }
+ if (info->bpp == 16 || info->bpp == 32) {
+ if (compress == 0) {
+ if (info->bpp == 32) {
+ info->mr = 0xffu << 16;
+ info->mg = 0xffu << 8;
+ info->mb = 0xffu << 0;
+ info->ma = 0xffu << 24;
+ info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
+ } else {
+ info->mr = 31u << 10;
+ info->mg = 31u << 5;
+ info->mb = 31u << 0;
+ }
+ } else if (compress == 3) {
+ info->mr = stbi__get32le(s);
+ info->mg = stbi__get32le(s);
+ info->mb = stbi__get32le(s);
+ // not documented, but generated by photoshop and handled by mspaint
+ if (info->mr == info->mg && info->mg == info->mb) {
+ // ?!?!?
+ return stbi__errpuc("bad BMP", "bad BMP");
+ }
+ } else
+ return stbi__errpuc("bad BMP", "bad BMP");
+ }
+ } else {
+ int i;
+ if (hsz != 108 && hsz != 124)
+ return stbi__errpuc("bad BMP", "bad BMP");
+ info->mr = stbi__get32le(s);
+ info->mg = stbi__get32le(s);
+ info->mb = stbi__get32le(s);
+ info->ma = stbi__get32le(s);
+ stbi__get32le(s); // discard color space
+ for (i=0; i < 12; ++i)
+ stbi__get32le(s); // discard color space parameters
+ if (hsz == 124) {
+ stbi__get32le(s); // discard rendering intent
+ stbi__get32le(s); // discard offset of profile data
+ stbi__get32le(s); // discard size of profile data
+ stbi__get32le(s); // discard reserved
+ }
+ }
+ }
+ return (void *) 1;
+}
+
+
+static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
+{
+ stbi_uc *out;
+ unsigned int mr=0,mg=0,mb=0,ma=0, all_a;
+ stbi_uc pal[256][4];
+ int psize=0,i,j,width;
+ int flip_vertically, pad, target;
+ stbi__bmp_data info;
+ STBI_NOTUSED(ri);
+
+ info.all_a = 255;
+ if (stbi__bmp_parse_header(s, &info) == NULL)
+ return NULL; // error code already set
+
+ flip_vertically = ((int) s->img_y) > 0;
+ s->img_y = abs((int) s->img_y);
+
+ mr = info.mr;
+ mg = info.mg;
+ mb = info.mb;
+ ma = info.ma;
+ all_a = info.all_a;
+
+ if (info.hsz == 12) {
+ if (info.bpp < 24)
+ psize = (info.offset - 14 - 24) / 3;
+ } else {
+ if (info.bpp < 16)
+ psize = (info.offset - 14 - info.hsz) >> 2;
+ }
+
+ s->img_n = ma ? 4 : 3;
+ if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
+ target = req_comp;
+ else
+ target = s->img_n; // if they want monochrome, we'll post-convert
+
+ // sanity-check size
+ if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0))
+ return stbi__errpuc("too large", "Corrupt BMP");
+
+ out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0);
+ if (!out) return stbi__errpuc("outofmem", "Out of memory");
+ if (info.bpp < 16) {
+ int z=0;
+ if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); }
+ for (i=0; i < psize; ++i) {
+ pal[i][2] = stbi__get8(s);
+ pal[i][1] = stbi__get8(s);
+ pal[i][0] = stbi__get8(s);
+ if (info.hsz != 12) stbi__get8(s);
+ pal[i][3] = 255;
+ }
+ stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4));
+ if (info.bpp == 1) width = (s->img_x + 7) >> 3;
+ else if (info.bpp == 4) width = (s->img_x + 1) >> 1;
+ else if (info.bpp == 8) width = s->img_x;
+ else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); }
+ pad = (-width)&3;
+ if (info.bpp == 1) {
+ for (j=0; j < (int) s->img_y; ++j) {
+ int bit_offset = 7, v = stbi__get8(s);
+ for (i=0; i < (int) s->img_x; ++i) {
+ int color = (v>>bit_offset)&0x1;
+ out[z++] = pal[color][0];
+ out[z++] = pal[color][1];
+ out[z++] = pal[color][2];
+ if((--bit_offset) < 0) {
+ bit_offset = 7;
+ v = stbi__get8(s);
+ }
+ }
+ stbi__skip(s, pad);
+ }
+ } else {
+ for (j=0; j < (int) s->img_y; ++j) {
+ for (i=0; i < (int) s->img_x; i += 2) {
+ int v=stbi__get8(s),v2=0;
+ if (info.bpp == 4) {
+ v2 = v & 15;
+ v >>= 4;
+ }
+ out[z++] = pal[v][0];
+ out[z++] = pal[v][1];
+ out[z++] = pal[v][2];
+ if (target == 4) out[z++] = 255;
+ if (i+1 == (int) s->img_x) break;
+ v = (info.bpp == 8) ? stbi__get8(s) : v2;
+ out[z++] = pal[v][0];
+ out[z++] = pal[v][1];
+ out[z++] = pal[v][2];
+ if (target == 4) out[z++] = 255;
+ }
+ stbi__skip(s, pad);
+ }
+ }
+ } else {
+ int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0;
+ int z = 0;
+ int easy=0;
+ stbi__skip(s, info.offset - 14 - info.hsz);
+ if (info.bpp == 24) width = 3 * s->img_x;
+ else if (info.bpp == 16) width = 2*s->img_x;
+ else /* bpp = 32 and pad = 0 */ width=0;
+ pad = (-width) & 3;
+ if (info.bpp == 24) {
+ easy = 1;
+ } else if (info.bpp == 32) {
+ if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000)
+ easy = 2;
+ }
+ if (!easy) {
+ if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); }
+ // right shift amt to put high bit in position #7
+ rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr);
+ gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg);
+ bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb);
+ ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma);
+ }
+ for (j=0; j < (int) s->img_y; ++j) {
+ if (easy) {
+ for (i=0; i < (int) s->img_x; ++i) {
+ unsigned char a;
+ out[z+2] = stbi__get8(s);
+ out[z+1] = stbi__get8(s);
+ out[z+0] = stbi__get8(s);
+ z += 3;
+ a = (easy == 2 ? stbi__get8(s) : 255);
+ all_a |= a;
+ if (target == 4) out[z++] = a;
+ }
+ } else {
+ int bpp = info.bpp;
+ for (i=0; i < (int) s->img_x; ++i) {
+ stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s));
+ unsigned int a;
+ out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount));
+ out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount));
+ out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount));
+ a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255);
+ all_a |= a;
+ if (target == 4) out[z++] = STBI__BYTECAST(a);
+ }
+ }
+ stbi__skip(s, pad);
+ }
+ }
+
+ // if alpha channel is all 0s, replace with all 255s
+ if (target == 4 && all_a == 0)
+ for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4)
+ out[i] = 255;
+
+ if (flip_vertically) {
+ stbi_uc t;
+ for (j=0; j < (int) s->img_y>>1; ++j) {
+ stbi_uc *p1 = out + j *s->img_x*target;
+ stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target;
+ for (i=0; i < (int) s->img_x*target; ++i) {
+ t = p1[i], p1[i] = p2[i], p2[i] = t;
+ }
+ }
+ }
+
+ if (req_comp && req_comp != target) {
+ out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y);
+ if (out == NULL) return out; // stbi__convert_format frees input on failure
+ }
+
+ *x = s->img_x;
+ *y = s->img_y;
+ if (comp) *comp = s->img_n;
+ return out;
+}
+#endif
+
+// Targa Truevision - TGA
+// by Jonathan Dummer
+#ifndef STBI_NO_TGA
+// returns STBI_rgb or whatever, 0 on error
+static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16)
+{
+ // only RGB or RGBA (incl. 16bit) or grey allowed
+ if (is_rgb16) *is_rgb16 = 0;
+ switch(bits_per_pixel) {
+ case 8: return STBI_grey;
+ case 16: if(is_grey) return STBI_grey_alpha;
+ // fallthrough
+ case 15: if(is_rgb16) *is_rgb16 = 1;
+ return STBI_rgb;
+ case 24: // fallthrough
+ case 32: return bits_per_pixel/8;
+ default: return 0;
+ }
+}
+
+static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
+{
+ int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp;
+ int sz, tga_colormap_type;
+ stbi__get8(s); // discard Offset
+ tga_colormap_type = stbi__get8(s); // colormap type
+ if( tga_colormap_type > 1 ) {
+ stbi__rewind(s);
+ return 0; // only RGB or indexed allowed
+ }
+ tga_image_type = stbi__get8(s); // image type
+ if ( tga_colormap_type == 1 ) { // colormapped (paletted) image
+ if (tga_image_type != 1 && tga_image_type != 9) {
+ stbi__rewind(s);
+ return 0;
+ }
+ stbi__skip(s,4); // skip index of first colormap entry and number of entries
+ sz = stbi__get8(s); // check bits per palette color entry
+ if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) {
+ stbi__rewind(s);
+ return 0;
+ }
+ stbi__skip(s,4); // skip image x and y origin
+ tga_colormap_bpp = sz;
+ } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE
+ if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) {
+ stbi__rewind(s);
+ return 0; // only RGB or grey allowed, +/- RLE
+ }
+ stbi__skip(s,9); // skip colormap specification and image x/y origin
+ tga_colormap_bpp = 0;
+ }
+ tga_w = stbi__get16le(s);
+ if( tga_w < 1 ) {
+ stbi__rewind(s);
+ return 0; // test width
+ }
+ tga_h = stbi__get16le(s);
+ if( tga_h < 1 ) {
+ stbi__rewind(s);
+ return 0; // test height
+ }
+ tga_bits_per_pixel = stbi__get8(s); // bits per pixel
+ stbi__get8(s); // ignore alpha bits
+ if (tga_colormap_bpp != 0) {
+ if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) {
+ // when using a colormap, tga_bits_per_pixel is the size of the indexes
+ // I don't think anything but 8 or 16bit indexes makes sense
+ stbi__rewind(s);
+ return 0;
+ }
+ tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL);
+ } else {
+ tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL);
+ }
+ if(!tga_comp) {
+ stbi__rewind(s);
+ return 0;
+ }
+ if (x) *x = tga_w;
+ if (y) *y = tga_h;
+ if (comp) *comp = tga_comp;
+ return 1; // seems to have passed everything
+}
+
+static int stbi__tga_test(stbi__context *s)
+{
+ int res = 0;
+ int sz, tga_color_type;
+ stbi__get8(s); // discard Offset
+ tga_color_type = stbi__get8(s); // color type
+ if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed
+ sz = stbi__get8(s); // image type
+ if ( tga_color_type == 1 ) { // colormapped (paletted) image
+ if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9
+ stbi__skip(s,4); // skip index of first colormap entry and number of entries
+ sz = stbi__get8(s); // check bits per palette color entry
+ if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
+ stbi__skip(s,4); // skip image x and y origin
+ } else { // "normal" image w/o colormap
+ if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE
+ stbi__skip(s,9); // skip colormap specification and image x/y origin
+ }
+ if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width
+ if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height
+ sz = stbi__get8(s); // bits per pixel
+ if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index
+ if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
+
+ res = 1; // if we got this far, everything's good and we can return 1 instead of 0
+
+errorEnd:
+ stbi__rewind(s);
+ return res;
+}
+
+// read 16bit value and convert to 24bit RGB
+static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out)
+{
+ stbi__uint16 px = (stbi__uint16)stbi__get16le(s);
+ stbi__uint16 fiveBitMask = 31;
+ // we have 3 channels with 5bits each
+ int r = (px >> 10) & fiveBitMask;
+ int g = (px >> 5) & fiveBitMask;
+ int b = px & fiveBitMask;
+ // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later
+ out[0] = (stbi_uc)((r * 255)/31);
+ out[1] = (stbi_uc)((g * 255)/31);
+ out[2] = (stbi_uc)((b * 255)/31);
+
+ // some people claim that the most significant bit might be used for alpha
+ // (possibly if an alpha-bit is set in the "image descriptor byte")
+ // but that only made 16bit test images completely translucent..
+ // so let's treat all 15 and 16bit TGAs as RGB with no alpha.
+}
+
+static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
+{
+ // read in the TGA header stuff
+ int tga_offset = stbi__get8(s);
+ int tga_indexed = stbi__get8(s);
+ int tga_image_type = stbi__get8(s);
+ int tga_is_RLE = 0;
+ int tga_palette_start = stbi__get16le(s);
+ int tga_palette_len = stbi__get16le(s);
+ int tga_palette_bits = stbi__get8(s);
+ int tga_x_origin = stbi__get16le(s);
+ int tga_y_origin = stbi__get16le(s);
+ int tga_width = stbi__get16le(s);
+ int tga_height = stbi__get16le(s);
+ int tga_bits_per_pixel = stbi__get8(s);
+ int tga_comp, tga_rgb16=0;
+ int tga_inverted = stbi__get8(s);
+ // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?)
+ // image data
+ unsigned char *tga_data;
+ unsigned char *tga_palette = NULL;
+ int i, j;
+ unsigned char raw_data[4] = {0};
+ int RLE_count = 0;
+ int RLE_repeating = 0;
+ int read_next_pixel = 1;
+ STBI_NOTUSED(ri);
+
+ // do a tiny bit of precessing
+ if ( tga_image_type >= 8 )
+ {
+ tga_image_type -= 8;
+ tga_is_RLE = 1;
+ }
+ tga_inverted = 1 - ((tga_inverted >> 5) & 1);
+
+ // If I'm paletted, then I'll use the number of bits from the palette
+ if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16);
+ else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16);
+
+ if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency
+ return stbi__errpuc("bad format", "Can't find out TGA pixelformat");
+
+ // tga info
+ *x = tga_width;
+ *y = tga_height;
+ if (comp) *comp = tga_comp;
+
+ if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0))
+ return stbi__errpuc("too large", "Corrupt TGA");
+
+ tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0);
+ if (!tga_data) return stbi__errpuc("outofmem", "Out of memory");
+
+ // skip to the data's starting position (offset usually = 0)
+ stbi__skip(s, tga_offset );
+
+ if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) {
+ for (i=0; i < tga_height; ++i) {
+ int row = tga_inverted ? tga_height -i - 1 : i;
+ stbi_uc *tga_row = tga_data + row*tga_width*tga_comp;
+ stbi__getn(s, tga_row, tga_width * tga_comp);
+ }
+ } else {
+ // do I need to load a palette?
+ if ( tga_indexed)
+ {
+ // any data to skip? (offset usually = 0)
+ stbi__skip(s, tga_palette_start );
+ // load the palette
+ tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0);
+ if (!tga_palette) {
+ STBI_FREE(tga_data);
+ return stbi__errpuc("outofmem", "Out of memory");
+ }
+ if (tga_rgb16) {
+ stbi_uc *pal_entry = tga_palette;
+ STBI_ASSERT(tga_comp == STBI_rgb);
+ for (i=0; i < tga_palette_len; ++i) {
+ stbi__tga_read_rgb16(s, pal_entry);
+ pal_entry += tga_comp;
+ }
+ } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) {
+ STBI_FREE(tga_data);
+ STBI_FREE(tga_palette);
+ return stbi__errpuc("bad palette", "Corrupt TGA");
+ }
+ }
+ // load the data
+ for (i=0; i < tga_width * tga_height; ++i)
+ {
+ // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk?
+ if ( tga_is_RLE )
+ {
+ if ( RLE_count == 0 )
+ {
+ // yep, get the next byte as a RLE command
+ int RLE_cmd = stbi__get8(s);
+ RLE_count = 1 + (RLE_cmd & 127);
+ RLE_repeating = RLE_cmd >> 7;
+ read_next_pixel = 1;
+ } else if ( !RLE_repeating )
+ {
+ read_next_pixel = 1;
+ }
+ } else
+ {
+ read_next_pixel = 1;
+ }
+ // OK, if I need to read a pixel, do it now
+ if ( read_next_pixel )
+ {
+ // load however much data we did have
+ if ( tga_indexed )
+ {
+ // read in index, then perform the lookup
+ int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s);
+ if ( pal_idx >= tga_palette_len ) {
+ // invalid index
+ pal_idx = 0;
+ }
+ pal_idx *= tga_comp;
+ for (j = 0; j < tga_comp; ++j) {
+ raw_data[j] = tga_palette[pal_idx+j];
+ }
+ } else if(tga_rgb16) {
+ STBI_ASSERT(tga_comp == STBI_rgb);
+ stbi__tga_read_rgb16(s, raw_data);
+ } else {
+ // read in the data raw
+ for (j = 0; j < tga_comp; ++j) {
+ raw_data[j] = stbi__get8(s);
+ }
+ }
+ // clear the reading flag for the next pixel
+ read_next_pixel = 0;
+ } // end of reading a pixel
+
+ // copy data
+ for (j = 0; j < tga_comp; ++j)
+ tga_data[i*tga_comp+j] = raw_data[j];
+
+ // in case we're in RLE mode, keep counting down
+ --RLE_count;
+ }
+ // do I need to invert the image?
+ if ( tga_inverted )
+ {
+ for (j = 0; j*2 < tga_height; ++j)
+ {
+ int index1 = j * tga_width * tga_comp;
+ int index2 = (tga_height - 1 - j) * tga_width * tga_comp;
+ for (i = tga_width * tga_comp; i > 0; --i)
+ {
+ unsigned char temp = tga_data[index1];
+ tga_data[index1] = tga_data[index2];
+ tga_data[index2] = temp;
+ ++index1;
+ ++index2;
+ }
+ }
+ }
+ // clear my palette, if I had one
+ if ( tga_palette != NULL )
+ {
+ STBI_FREE( tga_palette );
+ }
+ }
+
+ // swap RGB - if the source data was RGB16, it already is in the right order
+ if (tga_comp >= 3 && !tga_rgb16)
+ {
+ unsigned char* tga_pixel = tga_data;
+ for (i=0; i < tga_width * tga_height; ++i)
+ {
+ unsigned char temp = tga_pixel[0];
+ tga_pixel[0] = tga_pixel[2];
+ tga_pixel[2] = temp;
+ tga_pixel += tga_comp;
+ }
+ }
+
+ // convert to target component count
+ if (req_comp && req_comp != tga_comp)
+ tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height);
+
+ // the things I do to get rid of an error message, and yet keep
+ // Microsoft's C compilers happy... [8^(
+ tga_palette_start = tga_palette_len = tga_palette_bits =
+ tga_x_origin = tga_y_origin = 0;
+ // OK, done
+ return tga_data;
+}
+#endif
+
+// *************************************************************************************************
+// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB
+
+#ifndef STBI_NO_PSD
+static int stbi__psd_test(stbi__context *s)
+{
+ int r = (stbi__get32be(s) == 0x38425053);
+ stbi__rewind(s);
+ return r;
+}
+
+static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount)
+{
+ int count, nleft, len;
+
+ count = 0;
+ while ((nleft = pixelCount - count) > 0) {
+ len = stbi__get8(s);
+ if (len == 128) {
+ // No-op.
+ } else if (len < 128) {
+ // Copy next len+1 bytes literally.
+ len++;
+ if (len > nleft) return 0; // corrupt data
+ count += len;
+ while (len) {
+ *p = stbi__get8(s);
+ p += 4;
+ len--;
+ }
+ } else if (len > 128) {
+ stbi_uc val;
+ // Next -len+1 bytes in the dest are replicated from next source byte.
+ // (Interpret len as a negative 8-bit int.)
+ len = 257 - len;
+ if (len > nleft) return 0; // corrupt data
+ val = stbi__get8(s);
+ count += len;
+ while (len) {
+ *p = val;
+ p += 4;
+ len--;
+ }
+ }
+ }
+
+ return 1;
+}
+
+static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc)
+{
+ int pixelCount;
+ int channelCount, compression;
+ int channel, i;
+ int bitdepth;
+ int w,h;
+ stbi_uc *out;
+ STBI_NOTUSED(ri);
+
+ // Check identifier
+ if (stbi__get32be(s) != 0x38425053) // "8BPS"
+ return stbi__errpuc("not PSD", "Corrupt PSD image");
+
+ // Check file type version.
+ if (stbi__get16be(s) != 1)
+ return stbi__errpuc("wrong version", "Unsupported version of PSD image");
+
+ // Skip 6 reserved bytes.
+ stbi__skip(s, 6 );
+
+ // Read the number of channels (R, G, B, A, etc).
+ channelCount = stbi__get16be(s);
+ if (channelCount < 0 || channelCount > 16)
+ return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image");
+
+ // Read the rows and columns of the image.
+ h = stbi__get32be(s);
+ w = stbi__get32be(s);
+
+ // Make sure the depth is 8 bits.
+ bitdepth = stbi__get16be(s);
+ if (bitdepth != 8 && bitdepth != 16)
+ return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit");
+
+ // Make sure the color mode is RGB.
+ // Valid options are:
+ // 0: Bitmap
+ // 1: Grayscale
+ // 2: Indexed color
+ // 3: RGB color
+ // 4: CMYK color
+ // 7: Multichannel
+ // 8: Duotone
+ // 9: Lab color
+ if (stbi__get16be(s) != 3)
+ return stbi__errpuc("wrong color format", "PSD is not in RGB color format");
+
+ // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.)
+ stbi__skip(s,stbi__get32be(s) );
+
+ // Skip the image resources. (resolution, pen tool paths, etc)
+ stbi__skip(s, stbi__get32be(s) );
+
+ // Skip the reserved data.
+ stbi__skip(s, stbi__get32be(s) );
+
+ // Find out if the data is compressed.
+ // Known values:
+ // 0: no compression
+ // 1: RLE compressed
+ compression = stbi__get16be(s);
+ if (compression > 1)
+ return stbi__errpuc("bad compression", "PSD has an unknown compression format");
+
+ // Check size
+ if (!stbi__mad3sizes_valid(4, w, h, 0))
+ return stbi__errpuc("too large", "Corrupt PSD");
+
+ // Create the destination image.
+
+ if (!compression && bitdepth == 16 && bpc == 16) {
+ out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0);
+ ri->bits_per_channel = 16;
+ } else
+ out = (stbi_uc *) stbi__malloc(4 * w*h);
+
+ if (!out) return stbi__errpuc("outofmem", "Out of memory");
+ pixelCount = w*h;
+
+ // Initialize the data to zero.
+ //memset( out, 0, pixelCount * 4 );
+
+ // Finally, the image data.
+ if (compression) {
+ // RLE as used by .PSD and .TIFF
+ // Loop until you get the number of unpacked bytes you are expecting:
+ // Read the next source byte into n.
+ // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally.
+ // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times.
+ // Else if n is 128, noop.
+ // Endloop
+
+ // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data,
+ // which we're going to just skip.
+ stbi__skip(s, h * channelCount * 2 );
+
+ // Read the RLE data by channel.
+ for (channel = 0; channel < 4; channel++) {
+ stbi_uc *p;
+
+ p = out+channel;
+ if (channel >= channelCount) {
+ // Fill this channel with default data.
+ for (i = 0; i < pixelCount; i++, p += 4)
+ *p = (channel == 3 ? 255 : 0);
+ } else {
+ // Read the RLE data.
+ if (!stbi__psd_decode_rle(s, p, pixelCount)) {
+ STBI_FREE(out);
+ return stbi__errpuc("corrupt", "bad RLE data");
+ }
+ }
+ }
+
+ } else {
+ // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...)
+ // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image.
+
+ // Read the data by channel.
+ for (channel = 0; channel < 4; channel++) {
+ if (channel >= channelCount) {
+ // Fill this channel with default data.
+ if (bitdepth == 16 && bpc == 16) {
+ stbi__uint16 *q = ((stbi__uint16 *) out) + channel;
+ stbi__uint16 val = channel == 3 ? 65535 : 0;
+ for (i = 0; i < pixelCount; i++, q += 4)
+ *q = val;
+ } else {
+ stbi_uc *p = out+channel;
+ stbi_uc val = channel == 3 ? 255 : 0;
+ for (i = 0; i < pixelCount; i++, p += 4)
+ *p = val;
+ }
+ } else {
+ if (ri->bits_per_channel == 16) { // output bpc
+ stbi__uint16 *q = ((stbi__uint16 *) out) + channel;
+ for (i = 0; i < pixelCount; i++, q += 4)
+ *q = (stbi__uint16) stbi__get16be(s);
+ } else {
+ stbi_uc *p = out+channel;
+ if (bitdepth == 16) { // input bpc
+ for (i = 0; i < pixelCount; i++, p += 4)
+ *p = (stbi_uc) (stbi__get16be(s) >> 8);
+ } else {
+ for (i = 0; i < pixelCount; i++, p += 4)
+ *p = stbi__get8(s);
+ }
+ }
+ }
+ }
+ }
+
+ // remove weird white matte from PSD
+ if (channelCount >= 4) {
+ if (ri->bits_per_channel == 16) {
+ for (i=0; i < w*h; ++i) {
+ stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i;
+ if (pixel[3] != 0 && pixel[3] != 65535) {
+ float a = pixel[3] / 65535.0f;
+ float ra = 1.0f / a;
+ float inv_a = 65535.0f * (1 - ra);
+ pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a);
+ pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a);
+ pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a);
+ }
+ }
+ } else {
+ for (i=0; i < w*h; ++i) {
+ unsigned char *pixel = out + 4*i;
+ if (pixel[3] != 0 && pixel[3] != 255) {
+ float a = pixel[3] / 255.0f;
+ float ra = 1.0f / a;
+ float inv_a = 255.0f * (1 - ra);
+ pixel[0] = (unsigned char) (pixel[0]*ra + inv_a);
+ pixel[1] = (unsigned char) (pixel[1]*ra + inv_a);
+ pixel[2] = (unsigned char) (pixel[2]*ra + inv_a);
+ }
+ }
+ }
+ }
+
+ // convert to desired output format
+ if (req_comp && req_comp != 4) {
+ if (ri->bits_per_channel == 16)
+ out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h);
+ else
+ out = stbi__convert_format(out, 4, req_comp, w, h);
+ if (out == NULL) return out; // stbi__convert_format frees input on failure
+ }
+
+ if (comp) *comp = 4;
+ *y = h;
+ *x = w;
+
+ return out;
+}
+#endif
+
+// *************************************************************************************************
+// Softimage PIC loader
+// by Tom Seddon
+//
+// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format
+// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/
+
+#ifndef STBI_NO_PIC
+static int stbi__pic_is4(stbi__context *s,const char *str)
+{
+ int i;
+ for (i=0; i<4; ++i)
+ if (stbi__get8(s) != (stbi_uc)str[i])
+ return 0;
+
+ return 1;
+}
+
+static int stbi__pic_test_core(stbi__context *s)
+{
+ int i;
+
+ if (!stbi__pic_is4(s,"\x53\x80\xF6\x34"))
+ return 0;
+
+ for(i=0;i<84;++i)
+ stbi__get8(s);
+
+ if (!stbi__pic_is4(s,"PICT"))
+ return 0;
+
+ return 1;
+}
+
+typedef struct
+{
+ stbi_uc size,type,channel;
+} stbi__pic_packet;
+
+static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest)
+{
+ int mask=0x80, i;
+
+ for (i=0; i<4; ++i, mask>>=1) {
+ if (channel & mask) {
+ if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short");
+ dest[i]=stbi__get8(s);
+ }
+ }
+
+ return dest;
+}
+
+static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src)
+{
+ int mask=0x80,i;
+
+ for (i=0;i<4; ++i, mask>>=1)
+ if (channel&mask)
+ dest[i]=src[i];
+}
+
+static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result)
+{
+ int act_comp=0,num_packets=0,y,chained;
+ stbi__pic_packet packets[10];
+
+ // this will (should...) cater for even some bizarre stuff like having data
+ // for the same channel in multiple packets.
+ do {
+ stbi__pic_packet *packet;
+
+ if (num_packets==sizeof(packets)/sizeof(packets[0]))
+ return stbi__errpuc("bad format","too many packets");
+
+ packet = &packets[num_packets++];
+
+ chained = stbi__get8(s);
+ packet->size = stbi__get8(s);
+ packet->type = stbi__get8(s);
+ packet->channel = stbi__get8(s);
+
+ act_comp |= packet->channel;
+
+ if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (reading packets)");
+ if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp");
+ } while (chained);
+
+ *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel?
+
+ for(y=0; y<height; ++y) {
+ int packet_idx;
+
+ for(packet_idx=0; packet_idx < num_packets; ++packet_idx) {
+ stbi__pic_packet *packet = &packets[packet_idx];
+ stbi_uc *dest = result+y*width*4;
+
+ switch (packet->type) {
+ default:
+ return stbi__errpuc("bad format","packet has bad compression type");
+
+ case 0: {//uncompressed
+ int x;
+
+ for(x=0;x<width;++x, dest+=4)
+ if (!stbi__readval(s,packet->channel,dest))
+ return 0;
+ break;
+ }
+
+ case 1://Pure RLE
+ {
+ int left=width, i;
+
+ while (left>0) {
+ stbi_uc count,value[4];
+
+ count=stbi__get8(s);
+ if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)");
+
+ if (count > left)
+ count = (stbi_uc) left;
+
+ if (!stbi__readval(s,packet->channel,value)) return 0;
+
+ for(i=0; i<count; ++i,dest+=4)
+ stbi__copyval(packet->channel,dest,value);
+ left -= count;
+ }
+ }
+ break;
+
+ case 2: {//Mixed RLE
+ int left=width;
+ while (left>0) {
+ int count = stbi__get8(s), i;
+ if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)");
+
+ if (count >= 128) { // Repeated
+ stbi_uc value[4];
+
+ if (count==128)
+ count = stbi__get16be(s);
+ else
+ count -= 127;
+ if (count > left)
+ return stbi__errpuc("bad file","scanline overrun");
+
+ if (!stbi__readval(s,packet->channel,value))
+ return 0;
+
+ for(i=0;i<count;++i, dest += 4)
+ stbi__copyval(packet->channel,dest,value);
+ } else { // Raw
+ ++count;
+ if (count>left) return stbi__errpuc("bad file","scanline overrun");
+
+ for(i=0;i<count;++i, dest+=4)
+ if (!stbi__readval(s,packet->channel,dest))
+ return 0;
+ }
+ left-=count;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri)
+{
+ stbi_uc *result;
+ int i, x,y, internal_comp;
+ STBI_NOTUSED(ri);
+
+ if (!comp) comp = &internal_comp;
+
+ for (i=0; i<92; ++i)
+ stbi__get8(s);
+
+ x = stbi__get16be(s);
+ y = stbi__get16be(s);
+ if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)");
+ if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode");
+
+ stbi__get32be(s); //skip `ratio'
+ stbi__get16be(s); //skip `fields'
+ stbi__get16be(s); //skip `pad'
+
+ // intermediate buffer is RGBA
+ result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0);
+ memset(result, 0xff, x*y*4);
+
+ if (!stbi__pic_load_core(s,x,y,comp, result)) {
+ STBI_FREE(result);
+ result=0;
+ }
+ *px = x;
+ *py = y;
+ if (req_comp == 0) req_comp = *comp;
+ result=stbi__convert_format(result,4,req_comp,x,y);
+
+ return result;
+}
+
+static int stbi__pic_test(stbi__context *s)
+{
+ int r = stbi__pic_test_core(s);
+ stbi__rewind(s);
+ return r;
+}
+#endif
+
+// *************************************************************************************************
+// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb
+
+#ifndef STBI_NO_GIF
+typedef struct
+{
+ stbi__int16 prefix;
+ stbi_uc first;
+ stbi_uc suffix;
+} stbi__gif_lzw;
+
+typedef struct
+{
+ int w,h;
+ stbi_uc *out; // output buffer (always 4 components)
+ stbi_uc *background; // The current "background" as far as a gif is concerned
+ stbi_uc *history;
+ int flags, bgindex, ratio, transparent, eflags;
+ stbi_uc pal[256][4];
+ stbi_uc lpal[256][4];
+ stbi__gif_lzw codes[8192];
+ stbi_uc *color_table;
+ int parse, step;
+ int lflags;
+ int start_x, start_y;
+ int max_x, max_y;
+ int cur_x, cur_y;
+ int line_size;
+ int delay;
+} stbi__gif;
+
+static int stbi__gif_test_raw(stbi__context *s)
+{
+ int sz;
+ if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0;
+ sz = stbi__get8(s);
+ if (sz != '9' && sz != '7') return 0;
+ if (stbi__get8(s) != 'a') return 0;
+ return 1;
+}
+
+static int stbi__gif_test(stbi__context *s)
+{
+ int r = stbi__gif_test_raw(s);
+ stbi__rewind(s);
+ return r;
+}
+
+static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp)
+{
+ int i;
+ for (i=0; i < num_entries; ++i) {
+ pal[i][2] = stbi__get8(s);
+ pal[i][1] = stbi__get8(s);
+ pal[i][0] = stbi__get8(s);
+ pal[i][3] = transp == i ? 0 : 255;
+ }
+}
+
+static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info)
+{
+ stbi_uc version;
+ if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8')
+ return stbi__err("not GIF", "Corrupt GIF");
+
+ version = stbi__get8(s);
+ if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF");
+ if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF");
+
+ stbi__g_failure_reason = "";
+ g->w = stbi__get16le(s);
+ g->h = stbi__get16le(s);
+ g->flags = stbi__get8(s);
+ g->bgindex = stbi__get8(s);
+ g->ratio = stbi__get8(s);
+ g->transparent = -1;
+
+ if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments
+
+ if (is_info) return 1;
+
+ if (g->flags & 0x80)
+ stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1);
+
+ return 1;
+}
+
+static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp)
+{
+ stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
+ if (!stbi__gif_header(s, g, comp, 1)) {
+ STBI_FREE(g);
+ stbi__rewind( s );
+ return 0;
+ }
+ if (x) *x = g->w;
+ if (y) *y = g->h;
+ STBI_FREE(g);
+ return 1;
+}
+
+static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code)
+{
+ stbi_uc *p, *c;
+ int idx;
+
+ // recurse to decode the prefixes, since the linked-list is backwards,
+ // and working backwards through an interleaved image would be nasty
+ if (g->codes[code].prefix >= 0)
+ stbi__out_gif_code(g, g->codes[code].prefix);
+
+ if (g->cur_y >= g->max_y) return;
+
+ idx = g->cur_x + g->cur_y;
+ p = &g->out[idx];
+ g->history[idx / 4] = 1;
+
+ c = &g->color_table[g->codes[code].suffix * 4];
+ if (c[3] > 128) { // don't render transparent pixels;
+ p[0] = c[2];
+ p[1] = c[1];
+ p[2] = c[0];
+ p[3] = c[3];
+ }
+ g->cur_x += 4;
+
+ if (g->cur_x >= g->max_x) {
+ g->cur_x = g->start_x;
+ g->cur_y += g->step;
+
+ while (g->cur_y >= g->max_y && g->parse > 0) {
+ g->step = (1 << g->parse) * g->line_size;
+ g->cur_y = g->start_y + (g->step >> 1);
+ --g->parse;
+ }
+ }
+}
+
+static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
+{
+ stbi_uc lzw_cs;
+ stbi__int32 len, init_code;
+ stbi__uint32 first;
+ stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear;
+ stbi__gif_lzw *p;
+
+ lzw_cs = stbi__get8(s);
+ if (lzw_cs > 12) return NULL;
+ clear = 1 << lzw_cs;
+ first = 1;
+ codesize = lzw_cs + 1;
+ codemask = (1 << codesize) - 1;
+ bits = 0;
+ valid_bits = 0;
+ for (init_code = 0; init_code < clear; init_code++) {
+ g->codes[init_code].prefix = -1;
+ g->codes[init_code].first = (stbi_uc) init_code;
+ g->codes[init_code].suffix = (stbi_uc) init_code;
+ }
+
+ // support no starting clear code
+ avail = clear+2;
+ oldcode = -1;
+
+ len = 0;
+ for(;;) {
+ if (valid_bits < codesize) {
+ if (len == 0) {
+ len = stbi__get8(s); // start new block
+ if (len == 0)
+ return g->out;
+ }
+ --len;
+ bits |= (stbi__int32) stbi__get8(s) << valid_bits;
+ valid_bits += 8;
+ } else {
+ stbi__int32 code = bits & codemask;
+ bits >>= codesize;
+ valid_bits -= codesize;
+ // @OPTIMIZE: is there some way we can accelerate the non-clear path?
+ if (code == clear) { // clear code
+ codesize = lzw_cs + 1;
+ codemask = (1 << codesize) - 1;
+ avail = clear + 2;
+ oldcode = -1;
+ first = 0;
+ } else if (code == clear + 1) { // end of stream code
+ stbi__skip(s, len);
+ while ((len = stbi__get8(s)) > 0)
+ stbi__skip(s,len);
+ return g->out;
+ } else if (code <= avail) {
+ if (first) {
+ return stbi__errpuc("no clear code", "Corrupt GIF");
+ }
+
+ if (oldcode >= 0) {
+ p = &g->codes[avail++];
+ if (avail > 8192) {
+ return stbi__errpuc("too many codes", "Corrupt GIF");
+ }
+
+ p->prefix = (stbi__int16) oldcode;
+ p->first = g->codes[oldcode].first;
+ p->suffix = (code == avail) ? p->first : g->codes[code].first;
+ } else if (code == avail)
+ return stbi__errpuc("illegal code in raster", "Corrupt GIF");
+
+ stbi__out_gif_code(g, (stbi__uint16) code);
+
+ if ((avail & codemask) == 0 && avail <= 0x0FFF) {
+ codesize++;
+ codemask = (1 << codesize) - 1;
+ }
+
+ oldcode = code;
+ } else {
+ return stbi__errpuc("illegal code in raster", "Corrupt GIF");
+ }
+ }
+ }
+}
+
+// this function is designed to support animated gifs, although stb_image doesn't support it
+// two back is the image from two frames ago, used for a very specific disposal format
+static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back)
+{
+ int dispose;
+ int first_frame;
+ int pi;
+ int pcount;
+
+ // on first frame, any non-written pixels get the background colour (non-transparent)
+ first_frame = 0;
+ if (g->out == 0) {
+ if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
+ g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
+ g->background = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
+ g->history = (stbi_uc *) stbi__malloc(g->w * g->h);
+ if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory");
+
+ // image is treated as "tranparent" at the start - ie, nothing overwrites the current background;
+ // background colour is only used for pixels that are not rendered first frame, after that "background"
+ // color refers to teh color that was there the previous frame.
+ memset( g->out, 0x00, 4 * g->w * g->h );
+ memset( g->background, 0x00, 4 * g->w * g->h ); // state of the background (starts transparent)
+ memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame
+ first_frame = 1;
+ } else {
+ // second frame - how do we dispoase of the previous one?
+ dispose = (g->eflags & 0x1C) >> 2;
+ pcount = g->w * g->h;
+
+ if ((dispose == 3) && (two_back == 0)) {
+ dispose = 2; // if I don't have an image to revert back to, default to the old background
+ }
+
+ if (dispose == 3) { // use previous graphic
+ for (pi = 0; pi < pcount; ++pi) {
+ if (g->history[pi]) {
+ memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 );
+ }
+ }
+ } else if (dispose == 2) {
+ // restore what was changed last frame to background before that frame;
+ for (pi = 0; pi < pcount; ++pi) {
+ if (g->history[pi]) {
+ memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 );
+ }
+ }
+ } else {
+ // This is a non-disposal case eithe way, so just
+ // leave the pixels as is, and they will become the new background
+ // 1: do not dispose
+ // 0: not specified.
+ }
+
+ // background is what out is after the undoing of the previou frame;
+ memcpy( g->background, g->out, 4 * g->w * g->h );
+ }
+
+ // clear my history;
+ memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame
+
+ for (;;) {
+ int tag = stbi__get8(s);
+ switch (tag) {
+ case 0x2C: /* Image Descriptor */
+ {
+ stbi__int32 x, y, w, h;
+ stbi_uc *o;
+
+ x = stbi__get16le(s);
+ y = stbi__get16le(s);
+ w = stbi__get16le(s);
+ h = stbi__get16le(s);
+ if (((x + w) > (g->w)) || ((y + h) > (g->h)))
+ return stbi__errpuc("bad Image Descriptor", "Corrupt GIF");
+
+ g->line_size = g->w * 4;
+ g->start_x = x * 4;
+ g->start_y = y * g->line_size;
+ g->max_x = g->start_x + w * 4;
+ g->max_y = g->start_y + h * g->line_size;
+ g->cur_x = g->start_x;
+ g->cur_y = g->start_y;
+
+ g->lflags = stbi__get8(s);
+
+ if (g->lflags & 0x40) {
+ g->step = 8 * g->line_size; // first interlaced spacing
+ g->parse = 3;
+ } else {
+ g->step = g->line_size;
+ g->parse = 0;
+ }
+
+ if (g->lflags & 0x80) {
+ stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1);
+ g->color_table = (stbi_uc *) g->lpal;
+ } else if (g->flags & 0x80) {
+ g->color_table = (stbi_uc *) g->pal;
+ } else
+ return stbi__errpuc("missing color table", "Corrupt GIF");
+
+ o = stbi__process_gif_raster(s, g);
+ if (o == NULL) return NULL;
+
+ // if this was the first frame,
+ pcount = g->w * g->h;
+ if (first_frame && (g->bgindex > 0)) {
+ // if first frame, any pixel not drawn to gets the background color
+ for (pi = 0; pi < pcount; ++pi) {
+ if (g->history[pi] == 0) {
+ g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be;
+ memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 );
+ }
+ }
+ }
+
+ return o;
+ }
+
+ case 0x21: // Comment Extension.
+ {
+ int len;
+ int ext = stbi__get8(s);
+ if (ext == 0xF9) { // Graphic Control Extension.
+ len = stbi__get8(s);
+ if (len == 4) {
+ g->eflags = stbi__get8(s);
+ g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths.
+
+ // unset old transparent
+ if (g->transparent >= 0) {
+ g->pal[g->transparent][3] = 255;
+ }
+ if (g->eflags & 0x01) {
+ g->transparent = stbi__get8(s);
+ if (g->transparent >= 0) {
+ g->pal[g->transparent][3] = 0;
+ }
+ } else {
+ // don't need transparent
+ stbi__skip(s, 1);
+ g->transparent = -1;
+ }
+ } else {
+ stbi__skip(s, len);
+ break;
+ }
+ }
+ while ((len = stbi__get8(s)) != 0) {
+ stbi__skip(s, len);
+ }
+ break;
+ }
+
+ case 0x3B: // gif stream termination code
+ return (stbi_uc *) s; // using '1' causes warning on some compilers
+
+ default:
+ return stbi__errpuc("unknown code", "Corrupt GIF");
+ }
+ }
+}
+
+static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp)
+{
+ if (stbi__gif_test(s)) {
+ int layers = 0;
+ stbi_uc *u = 0;
+ stbi_uc *out = 0;
+ stbi_uc *two_back = 0;
+ stbi__gif g;
+ int stride;
+ memset(&g, 0, sizeof(g));
+ if (delays) {
+ *delays = 0;
+ }
+
+ do {
+ u = stbi__gif_load_next(s, &g, comp, req_comp, two_back);
+ if (u == (stbi_uc *) s) u = 0; // end of animated gif marker
+
+ if (u) {
+ *x = g.w;
+ *y = g.h;
+ ++layers;
+ stride = g.w * g.h * 4;
+
+ if (out) {
+ out = (stbi_uc*) STBI_REALLOC( out, layers * stride );
+ if (delays) {
+ *delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers );
+ }
+ } else {
+ out = (stbi_uc*)stbi__malloc( layers * stride );
+ if (delays) {
+ *delays = (int*) stbi__malloc( layers * sizeof(int) );
+ }
+ }
+ memcpy( out + ((layers - 1) * stride), u, stride );
+ if (layers >= 2) {
+ two_back = out - 2 * stride;
+ }
+
+ if (delays) {
+ (*delays)[layers - 1U] = g.delay;
+ }
+ }
+ } while (u != 0);
+
+ // free temp buffer;
+ STBI_FREE(g.out);
+ STBI_FREE(g.history);
+ STBI_FREE(g.background);
+
+ // do the final conversion after loading everything;
+ if (req_comp && req_comp != 4)
+ out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h);
+
+ *z = layers;
+ return out;
+ } else {
+ return stbi__errpuc("not GIF", "Image was not as a gif type.");
+ }
+}
+
+static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
+{
+ stbi_uc *u = 0;
+ stbi__gif g;
+ memset(&g, 0, sizeof(g));
+
+ u = stbi__gif_load_next(s, &g, comp, req_comp, 0);
+ if (u == (stbi_uc *) s) u = 0; // end of animated gif marker
+ if (u) {
+ *x = g.w;
+ *y = g.h;
+
+ // moved conversion to after successful load so that the same
+ // can be done for multiple frames.
+ if (req_comp && req_comp != 4)
+ u = stbi__convert_format(u, 4, req_comp, g.w, g.h);
+ }
+
+ // free buffers needed for multiple frame loading;
+ STBI_FREE(g.history);
+ STBI_FREE(g.background);
+
+ return u;
+}
+
+static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp)
+{
+ return stbi__gif_info_raw(s,x,y,comp);
+}
+#endif
+
+// *************************************************************************************************
+// Radiance RGBE HDR loader
+// originally by Nicolas Schulz
+#ifndef STBI_NO_HDR
+static int stbi__hdr_test_core(stbi__context *s, const char *signature)
+{
+ int i;
+ for (i=0; signature[i]; ++i)
+ if (stbi__get8(s) != signature[i])
+ return 0;
+ stbi__rewind(s);
+ return 1;
+}
+
+static int stbi__hdr_test(stbi__context* s)
+{
+ int r = stbi__hdr_test_core(s, "#?RADIANCE\n");
+ stbi__rewind(s);
+ if(!r) {
+ r = stbi__hdr_test_core(s, "#?RGBE\n");
+ stbi__rewind(s);
+ }
+ return r;
+}
+
+#define STBI__HDR_BUFLEN 1024
+static char *stbi__hdr_gettoken(stbi__context *z, char *buffer)
+{
+ int len=0;
+ char c = '\0';
+
+ c = (char) stbi__get8(z);
+
+ while (!stbi__at_eof(z) && c != '\n') {
+ buffer[len++] = c;
+ if (len == STBI__HDR_BUFLEN-1) {
+ // flush to end of line
+ while (!stbi__at_eof(z) && stbi__get8(z) != '\n')
+ ;
+ break;
+ }
+ c = (char) stbi__get8(z);
+ }
+
+ buffer[len] = 0;
+ return buffer;
+}
+
+static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp)
+{
+ if ( input[3] != 0 ) {
+ float f1;
+ // Exponent
+ f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8));
+ if (req_comp <= 2)
+ output[0] = (input[0] + input[1] + input[2]) * f1 / 3;
+ else {
+ output[0] = input[0] * f1;
+ output[1] = input[1] * f1;
+ output[2] = input[2] * f1;
+ }
+ if (req_comp == 2) output[1] = 1;
+ if (req_comp == 4) output[3] = 1;
+ } else {
+ switch (req_comp) {
+ case 4: output[3] = 1; /* fallthrough */
+ case 3: output[0] = output[1] = output[2] = 0;
+ break;
+ case 2: output[1] = 1; /* fallthrough */
+ case 1: output[0] = 0;
+ break;
+ }
+ }
+}
+
+static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
+{
+ char buffer[STBI__HDR_BUFLEN];
+ char *token;
+ int valid = 0;
+ int width, height;
+ stbi_uc *scanline;
+ float *hdr_data;
+ int len;
+ unsigned char count, value;
+ int i, j, k, c1,c2, z;
+ const char *headerToken;
+ STBI_NOTUSED(ri);
+
+ // Check identifier
+ headerToken = stbi__hdr_gettoken(s,buffer);
+ if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0)
+ return stbi__errpf("not HDR", "Corrupt HDR image");
+
+ // Parse header
+ for(;;) {
+ token = stbi__hdr_gettoken(s,buffer);
+ if (token[0] == 0) break;
+ if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1;
+ }
+
+ if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format");
+
+ // Parse width and height
+ // can't use sscanf() if we're not using stdio!
+ token = stbi__hdr_gettoken(s,buffer);
+ if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format");
+ token += 3;
+ height = (int) strtol(token, &token, 10);
+ while (*token == ' ') ++token;
+ if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format");
+ token += 3;
+ width = (int) strtol(token, NULL, 10);
+
+ *x = width;
+ *y = height;
+
+ if (comp) *comp = 3;
+ if (req_comp == 0) req_comp = 3;
+
+ if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0))
+ return stbi__errpf("too large", "HDR image is too large");
+
+ // Read data
+ hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0);
+ if (!hdr_data)
+ return stbi__errpf("outofmem", "Out of memory");
+
+ // Load image data
+ // image data is stored as some number of sca
+ if ( width < 8 || width >= 32768) {
+ // Read flat data
+ for (j=0; j < height; ++j) {
+ for (i=0; i < width; ++i) {
+ stbi_uc rgbe[4];
+ main_decode_loop:
+ stbi__getn(s, rgbe, 4);
+ stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp);
+ }
+ }
+ } else {
+ // Read RLE-encoded data
+ scanline = NULL;
+
+ for (j = 0; j < height; ++j) {
+ c1 = stbi__get8(s);
+ c2 = stbi__get8(s);
+ len = stbi__get8(s);
+ if (c1 != 2 || c2 != 2 || (len & 0x80)) {
+ // not run-length encoded, so we have to actually use THIS data as a decoded
+ // pixel (note this can't be a valid pixel--one of RGB must be >= 128)
+ stbi_uc rgbe[4];
+ rgbe[0] = (stbi_uc) c1;
+ rgbe[1] = (stbi_uc) c2;
+ rgbe[2] = (stbi_uc) len;
+ rgbe[3] = (stbi_uc) stbi__get8(s);
+ stbi__hdr_convert(hdr_data, rgbe, req_comp);
+ i = 1;
+ j = 0;
+ STBI_FREE(scanline);
+ goto main_decode_loop; // yes, this makes no sense
+ }
+ len <<= 8;
+ len |= stbi__get8(s);
+ if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); }
+ if (scanline == NULL) {
+ scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0);
+ if (!scanline) {
+ STBI_FREE(hdr_data);
+ return stbi__errpf("outofmem", "Out of memory");
+ }
+ }
+
+ for (k = 0; k < 4; ++k) {
+ int nleft;
+ i = 0;
+ while ((nleft = width - i) > 0) {
+ count = stbi__get8(s);
+ if (count > 128) {
+ // Run
+ value = stbi__get8(s);
+ count -= 128;
+ if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
+ for (z = 0; z < count; ++z)
+ scanline[i++ * 4 + k] = value;
+ } else {
+ // Dump
+ if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
+ for (z = 0; z < count; ++z)
+ scanline[i++ * 4 + k] = stbi__get8(s);
+ }
+ }
+ }
+ for (i=0; i < width; ++i)
+ stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp);
+ }
+ if (scanline)
+ STBI_FREE(scanline);
+ }
+
+ return hdr_data;
+}
+
+static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
+{
+ char buffer[STBI__HDR_BUFLEN];
+ char *token;
+ int valid = 0;
+ int dummy;
+
+ if (!x) x = &dummy;
+ if (!y) y = &dummy;
+ if (!comp) comp = &dummy;
+
+ if (stbi__hdr_test(s) == 0) {
+ stbi__rewind( s );
+ return 0;
+ }
+
+ for(;;) {
+ token = stbi__hdr_gettoken(s,buffer);
+ if (token[0] == 0) break;
+ if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1;
+ }
+
+ if (!valid) {
+ stbi__rewind( s );
+ return 0;
+ }
+ token = stbi__hdr_gettoken(s,buffer);
+ if (strncmp(token, "-Y ", 3)) {
+ stbi__rewind( s );
+ return 0;
+ }
+ token += 3;
+ *y = (int) strtol(token, &token, 10);
+ while (*token == ' ') ++token;
+ if (strncmp(token, "+X ", 3)) {
+ stbi__rewind( s );
+ return 0;
+ }
+ token += 3;
+ *x = (int) strtol(token, NULL, 10);
+ *comp = 3;
+ return 1;
+}
+#endif // STBI_NO_HDR
+
+#ifndef STBI_NO_BMP
+static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
+{
+ void *p;
+ stbi__bmp_data info;
+
+ info.all_a = 255;
+ p = stbi__bmp_parse_header(s, &info);
+ stbi__rewind( s );
+ if (p == NULL)
+ return 0;
+ if (x) *x = s->img_x;
+ if (y) *y = s->img_y;
+ if (comp) *comp = info.ma ? 4 : 3;
+ return 1;
+}
+#endif
+
+#ifndef STBI_NO_PSD
+static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
+{
+ int channelCount, dummy, depth;
+ if (!x) x = &dummy;
+ if (!y) y = &dummy;
+ if (!comp) comp = &dummy;
+ if (stbi__get32be(s) != 0x38425053) {
+ stbi__rewind( s );
+ return 0;
+ }
+ if (stbi__get16be(s) != 1) {
+ stbi__rewind( s );
+ return 0;
+ }
+ stbi__skip(s, 6);
+ channelCount = stbi__get16be(s);
+ if (channelCount < 0 || channelCount > 16) {
+ stbi__rewind( s );
+ return 0;
+ }
+ *y = stbi__get32be(s);
+ *x = stbi__get32be(s);
+ depth = stbi__get16be(s);
+ if (depth != 8 && depth != 16) {
+ stbi__rewind( s );
+ return 0;
+ }
+ if (stbi__get16be(s) != 3) {
+ stbi__rewind( s );
+ return 0;
+ }
+ *comp = 4;
+ return 1;
+}
+
+static int stbi__psd_is16(stbi__context *s)
+{
+ int channelCount, depth;
+ if (stbi__get32be(s) != 0x38425053) {
+ stbi__rewind( s );
+ return 0;
+ }
+ if (stbi__get16be(s) != 1) {
+ stbi__rewind( s );
+ return 0;
+ }
+ stbi__skip(s, 6);
+ channelCount = stbi__get16be(s);
+ if (channelCount < 0 || channelCount > 16) {
+ stbi__rewind( s );
+ return 0;
+ }
+ (void) stbi__get32be(s);
+ (void) stbi__get32be(s);
+ depth = stbi__get16be(s);
+ if (depth != 16) {
+ stbi__rewind( s );
+ return 0;
+ }
+ return 1;
+}
+#endif
+
+#ifndef STBI_NO_PIC
+static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
+{
+ int act_comp=0,num_packets=0,chained,dummy;
+ stbi__pic_packet packets[10];
+
+ if (!x) x = &dummy;
+ if (!y) y = &dummy;
+ if (!comp) comp = &dummy;
+
+ if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) {
+ stbi__rewind(s);
+ return 0;
+ }
+
+ stbi__skip(s, 88);
+
+ *x = stbi__get16be(s);
+ *y = stbi__get16be(s);
+ if (stbi__at_eof(s)) {
+ stbi__rewind( s);
+ return 0;
+ }
+ if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) {
+ stbi__rewind( s );
+ return 0;
+ }
+
+ stbi__skip(s, 8);
+
+ do {
+ stbi__pic_packet *packet;
+
+ if (num_packets==sizeof(packets)/sizeof(packets[0]))
+ return 0;
+
+ packet = &packets[num_packets++];
+ chained = stbi__get8(s);
+ packet->size = stbi__get8(s);
+ packet->type = stbi__get8(s);
+ packet->channel = stbi__get8(s);
+ act_comp |= packet->channel;
+
+ if (stbi__at_eof(s)) {
+ stbi__rewind( s );
+ return 0;
+ }
+ if (packet->size != 8) {
+ stbi__rewind( s );
+ return 0;
+ }
+ } while (chained);
+
+ *comp = (act_comp & 0x10 ? 4 : 3);
+
+ return 1;
+}
+#endif
+
+// *************************************************************************************************
+// Portable Gray Map and Portable Pixel Map loader
+// by Ken Miller
+//
+// PGM: http://netpbm.sourceforge.net/doc/pgm.html
+// PPM: http://netpbm.sourceforge.net/doc/ppm.html
+//
+// Known limitations:
+// Does not support comments in the header section
+// Does not support ASCII image data (formats P2 and P3)
+// Does not support 16-bit-per-channel
+
+#ifndef STBI_NO_PNM
+
+static int stbi__pnm_test(stbi__context *s)
+{
+ char p, t;
+ p = (char) stbi__get8(s);
+ t = (char) stbi__get8(s);
+ if (p != 'P' || (t != '5' && t != '6')) {
+ stbi__rewind( s );
+ return 0;
+ }
+ return 1;
+}
+
+static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri)
+{
+ stbi_uc *out;
+ STBI_NOTUSED(ri);
+
+ if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n))
+ return 0;
+
+ *x = s->img_x;
+ *y = s->img_y;
+ if (comp) *comp = s->img_n;
+
+ if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0))
+ return stbi__errpuc("too large", "PNM too large");
+
+ out = (stbi_uc *) stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0);
+ if (!out) return stbi__errpuc("outofmem", "Out of memory");
+ stbi__getn(s, out, s->img_n * s->img_x * s->img_y);
+
+ if (req_comp && req_comp != s->img_n) {
+ out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
+ if (out == NULL) return out; // stbi__convert_format frees input on failure
+ }
+ return out;
+}
+
+static int stbi__pnm_isspace(char c)
+{
+ return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r';
+}
+
+static void stbi__pnm_skip_whitespace(stbi__context *s, char *c)
+{
+ for (;;) {
+ while (!stbi__at_eof(s) && stbi__pnm_isspace(*c))
+ *c = (char) stbi__get8(s);
+
+ if (stbi__at_eof(s) || *c != '#')
+ break;
+
+ while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' )
+ *c = (char) stbi__get8(s);
+ }
+}
+
+static int stbi__pnm_isdigit(char c)
+{
+ return c >= '0' && c <= '9';
+}
+
+static int stbi__pnm_getinteger(stbi__context *s, char *c)
+{
+ int value = 0;
+
+ while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) {
+ value = value*10 + (*c - '0');
+ *c = (char) stbi__get8(s);
+ }
+
+ return value;
+}
+
+static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
+{
+ int maxv, dummy;
+ char c, p, t;
+
+ if (!x) x = &dummy;
+ if (!y) y = &dummy;
+ if (!comp) comp = &dummy;
+
+ stbi__rewind(s);
+
+ // Get identifier
+ p = (char) stbi__get8(s);
+ t = (char) stbi__get8(s);
+ if (p != 'P' || (t != '5' && t != '6')) {
+ stbi__rewind(s);
+ return 0;
+ }
+
+ *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm
+
+ c = (char) stbi__get8(s);
+ stbi__pnm_skip_whitespace(s, &c);
+
+ *x = stbi__pnm_getinteger(s, &c); // read width
+ stbi__pnm_skip_whitespace(s, &c);
+
+ *y = stbi__pnm_getinteger(s, &c); // read height
+ stbi__pnm_skip_whitespace(s, &c);
+
+ maxv = stbi__pnm_getinteger(s, &c); // read max value
+
+ if (maxv > 255)
+ return stbi__err("max value > 255", "PPM image not 8-bit");
+ else
+ return 1;
+}
+#endif
+
+static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp)
+{
+ #ifndef STBI_NO_JPEG
+ if (stbi__jpeg_info(s, x, y, comp)) return 1;
+ #endif
+
+ #ifndef STBI_NO_PNG
+ if (stbi__png_info(s, x, y, comp)) return 1;
+ #endif
+
+ #ifndef STBI_NO_GIF
+ if (stbi__gif_info(s, x, y, comp)) return 1;
+ #endif
+
+ #ifndef STBI_NO_BMP
+ if (stbi__bmp_info(s, x, y, comp)) return 1;
+ #endif
+
+ #ifndef STBI_NO_PSD
+ if (stbi__psd_info(s, x, y, comp)) return 1;
+ #endif
+
+ #ifndef STBI_NO_PIC
+ if (stbi__pic_info(s, x, y, comp)) return 1;
+ #endif
+
+ #ifndef STBI_NO_PNM
+ if (stbi__pnm_info(s, x, y, comp)) return 1;
+ #endif
+
+ #ifndef STBI_NO_HDR
+ if (stbi__hdr_info(s, x, y, comp)) return 1;
+ #endif
+
+ // test tga last because it's a crappy test!
+ #ifndef STBI_NO_TGA
+ if (stbi__tga_info(s, x, y, comp))
+ return 1;
+ #endif
+ return stbi__err("unknown image type", "Image not of any known type, or corrupt");
+}
+
+static int stbi__is_16_main(stbi__context *s)
+{
+ #ifndef STBI_NO_PNG
+ if (stbi__png_is16(s)) return 1;
+ #endif
+
+ #ifndef STBI_NO_PSD
+ if (stbi__psd_is16(s)) return 1;
+ #endif
+
+ return 0;
+}
+
+#ifndef STBI_NO_STDIO
+STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp)
+{
+ FILE *f = stbi__fopen(filename, "rb");
+ int result;
+ if (!f) return stbi__err("can't fopen", "Unable to open file");
+ result = stbi_info_from_file(f, x, y, comp);
+ fclose(f);
+ return result;
+}
+
+STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp)
+{
+ int r;
+ stbi__context s;
+ long pos = ftell(f);
+ stbi__start_file(&s, f);
+ r = stbi__info_main(&s,x,y,comp);
+ fseek(f,pos,SEEK_SET);
+ return r;
+}
+
+STBIDEF int stbi_is_16_bit(char const *filename)
+{
+ FILE *f = stbi__fopen(filename, "rb");
+ int result;
+ if (!f) return stbi__err("can't fopen", "Unable to open file");
+ result = stbi_is_16_bit_from_file(f);
+ fclose(f);
+ return result;
+}
+
+STBIDEF int stbi_is_16_bit_from_file(FILE *f)
+{
+ int r;
+ stbi__context s;
+ long pos = ftell(f);
+ stbi__start_file(&s, f);
+ r = stbi__is_16_main(&s);
+ fseek(f,pos,SEEK_SET);
+ return r;
+}
+#endif // !STBI_NO_STDIO
+
+STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp)
+{
+ stbi__context s;
+ stbi__start_mem(&s,buffer,len);
+ return stbi__info_main(&s,x,y,comp);
+}
+
+STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp)
+{
+ stbi__context s;
+ stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user);
+ return stbi__info_main(&s,x,y,comp);
+}
+
+STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len)
+{
+ stbi__context s;
+ stbi__start_mem(&s,buffer,len);
+ return stbi__is_16_main(&s);
+}
+
+STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user)
+{
+ stbi__context s;
+ stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user);
+ return stbi__is_16_main(&s);
+}
+
+#endif // STB_IMAGE_IMPLEMENTATION
+
+/*
+ revision history:
+ 2.19 (2018-02-11) fix warning
+ 2.18 (2018-01-30) fix warnings
+ 2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug
+ 1-bit BMP
+ *_is_16_bit api
+ avoid warnings
+ 2.16 (2017-07-23) all functions have 16-bit variants;
+ STBI_NO_STDIO works again;
+ compilation fixes;
+ fix rounding in unpremultiply;
+ optimize vertical flip;
+ disable raw_len validation;
+ documentation fixes
+ 2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode;
+ warning fixes; disable run-time SSE detection on gcc;
+ uniform handling of optional "return" values;
+ thread-safe initialization of zlib tables
+ 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
+ 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now
+ 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
+ 2.11 (2016-04-02) allocate large structures on the stack
+ remove white matting for transparent PSD
+ fix reported channel count for PNG & BMP
+ re-enable SSE2 in non-gcc 64-bit
+ support RGB-formatted JPEG
+ read 16-bit PNGs (only as 8-bit)
+ 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED
+ 2.09 (2016-01-16) allow comments in PNM files
+ 16-bit-per-pixel TGA (not bit-per-component)
+ info() for TGA could break due to .hdr handling
+ info() for BMP to shares code instead of sloppy parse
+ can use STBI_REALLOC_SIZED if allocator doesn't support realloc
+ code cleanup
+ 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
+ 2.07 (2015-09-13) fix compiler warnings
+ partial animated GIF support
+ limited 16-bpc PSD support
+ #ifdef unused functions
+ bug with < 92 byte PIC,PNM,HDR,TGA
+ 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value
+ 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning
+ 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit
+ 2.03 (2015-04-12) extra corruption checking (mmozeiko)
+ stbi_set_flip_vertically_on_load (nguillemot)
+ fix NEON support; fix mingw support
+ 2.02 (2015-01-19) fix incorrect assert, fix warning
+ 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2
+ 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG
+ 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg)
+ progressive JPEG (stb)
+ PGM/PPM support (Ken Miller)
+ STBI_MALLOC,STBI_REALLOC,STBI_FREE
+ GIF bugfix -- seemingly never worked
+ STBI_NO_*, STBI_ONLY_*
+ 1.48 (2014-12-14) fix incorrectly-named assert()
+ 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb)
+ optimize PNG (ryg)
+ fix bug in interlaced PNG with user-specified channel count (stb)
+ 1.46 (2014-08-26)
+ fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG
+ 1.45 (2014-08-16)
+ fix MSVC-ARM internal compiler error by wrapping malloc
+ 1.44 (2014-08-07)
+ various warning fixes from Ronny Chevalier
+ 1.43 (2014-07-15)
+ fix MSVC-only compiler problem in code changed in 1.42
+ 1.42 (2014-07-09)
+ don't define _CRT_SECURE_NO_WARNINGS (affects user code)
+ fixes to stbi__cleanup_jpeg path
+ added STBI_ASSERT to avoid requiring assert.h
+ 1.41 (2014-06-25)
+ fix search&replace from 1.36 that messed up comments/error messages
+ 1.40 (2014-06-22)
+ fix gcc struct-initialization warning
+ 1.39 (2014-06-15)
+ fix to TGA optimization when req_comp != number of components in TGA;
+ fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite)
+ add support for BMP version 5 (more ignored fields)
+ 1.38 (2014-06-06)
+ suppress MSVC warnings on integer casts truncating values
+ fix accidental rename of 'skip' field of I/O
+ 1.37 (2014-06-04)
+ remove duplicate typedef
+ 1.36 (2014-06-03)
+ convert to header file single-file library
+ if de-iphone isn't set, load iphone images color-swapped instead of returning NULL
+ 1.35 (2014-05-27)
+ various warnings
+ fix broken STBI_SIMD path
+ fix bug where stbi_load_from_file no longer left file pointer in correct place
+ fix broken non-easy path for 32-bit BMP (possibly never used)
+ TGA optimization by Arseny Kapoulkine
+ 1.34 (unknown)
+ use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case
+ 1.33 (2011-07-14)
+ make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements
+ 1.32 (2011-07-13)
+ support for "info" function for all supported filetypes (SpartanJ)
+ 1.31 (2011-06-20)
+ a few more leak fixes, bug in PNG handling (SpartanJ)
+ 1.30 (2011-06-11)
+ added ability to load files via callbacks to accomidate custom input streams (Ben Wenger)
+ removed deprecated format-specific test/load functions
+ removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway
+ error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha)
+ fix inefficiency in decoding 32-bit BMP (David Woo)
+ 1.29 (2010-08-16)
+ various warning fixes from Aurelien Pocheville
+ 1.28 (2010-08-01)
+ fix bug in GIF palette transparency (SpartanJ)
+ 1.27 (2010-08-01)
+ cast-to-stbi_uc to fix warnings
+ 1.26 (2010-07-24)
+ fix bug in file buffering for PNG reported by SpartanJ
+ 1.25 (2010-07-17)
+ refix trans_data warning (Won Chun)
+ 1.24 (2010-07-12)
+ perf improvements reading from files on platforms with lock-heavy fgetc()
+ minor perf improvements for jpeg
+ deprecated type-specific functions so we'll get feedback if they're needed
+ attempt to fix trans_data warning (Won Chun)
+ 1.23 fixed bug in iPhone support
+ 1.22 (2010-07-10)
+ removed image *writing* support
+ stbi_info support from Jetro Lauha
+ GIF support from Jean-Marc Lienher
+ iPhone PNG-extensions from James Brown
+ warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva)
+ 1.21 fix use of 'stbi_uc' in header (reported by jon blow)
+ 1.20 added support for Softimage PIC, by Tom Seddon
+ 1.19 bug in interlaced PNG corruption check (found by ryg)
+ 1.18 (2008-08-02)
+ fix a threading bug (local mutable static)
+ 1.17 support interlaced PNG
+ 1.16 major bugfix - stbi__convert_format converted one too many pixels
+ 1.15 initialize some fields for thread safety
+ 1.14 fix threadsafe conversion bug
+ header-file-only version (#define STBI_HEADER_FILE_ONLY before including)
+ 1.13 threadsafe
+ 1.12 const qualifiers in the API
+ 1.11 Support installable IDCT, colorspace conversion routines
+ 1.10 Fixes for 64-bit (don't use "unsigned long")
+ optimized upsampling by Fabian "ryg" Giesen
+ 1.09 Fix format-conversion for PSD code (bad global variables!)
+ 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz
+ 1.07 attempt to fix C++ warning/errors again
+ 1.06 attempt to fix C++ warning/errors again
+ 1.05 fix TGA loading to return correct *comp and use good luminance calc
+ 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free
+ 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR
+ 1.02 support for (subset of) HDR files, float interface for preferred access to them
+ 1.01 fix bug: possible bug in handling right-side up bmps... not sure
+ fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all
+ 1.00 interface to zlib that skips zlib header
+ 0.99 correct handling of alpha in palette
+ 0.98 TGA loader by lonesock; dynamically add loaders (untested)
+ 0.97 jpeg errors on too large a file; also catch another malloc failure
+ 0.96 fix detection of invalid v value - particleman@mollyrocket forum
+ 0.95 during header scan, seek to markers in case of padding
+ 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same
+ 0.93 handle jpegtran output; verbose errors
+ 0.92 read 4,8,16,24,32-bit BMP files of several formats
+ 0.91 output 24-bit Windows 3.0 BMP files
+ 0.90 fix a few more warnings; bump version number to approach 1.0
+ 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd
+ 0.60 fix compiling as c++
+ 0.59 fix warnings: merge Dave Moore's -Wall fixes
+ 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian
+ 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available
+ 0.56 fix bug: zlib uncompressed mode len vs. nlen
+ 0.55 fix bug: restart_interval not initialized to 0
+ 0.54 allow NULL for 'int *comp'
+ 0.53 fix bug in png 3->4; speedup png decoding
+ 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments
+ 0.51 obey req_comp requests, 1-component jpegs return as 1-component,
+ on 'test' only check type, not whether we support this variant
+ 0.50 (2006-11-19)
+ first released version
+*/
+
+
+/*
+------------------------------------------------------------------------------
+This software is available under 2 licenses -- choose whichever you prefer.
+------------------------------------------------------------------------------
+ALTERNATIVE A - MIT License
+Copyright (c) 2017 Sean Barrett
+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
+AUTHORS OR COPYRIGHT HOLDERS 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.
+------------------------------------------------------------------------------
+ALTERNATIVE B - Public Domain (www.unlicense.org)
+This is free and unencumbered software released into the public domain.
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
+software, either in source code form or as a compiled binary, for any purpose,
+commercial or non-commercial, and by any means.
+In jurisdictions that recognize copyright laws, the author or authors of this
+software dedicate any and all copyright interest in the software to the public
+domain. We make this dedication for the benefit of the public at large and to
+the detriment of our heirs and successors. We intend this dedication to be an
+overt act of relinquishment in perpetuity of all present and future rights to
+this software under copyright law.
+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
+AUTHORS 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.
+------------------------------------------------------------------------------
+*/
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image_resize.h b/graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image_resize.h
new file mode 100644
index 0000000000..bcca92c2dc
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image_resize.h
@@ -0,0 +1,2585 @@
+/* stb_image_resize - v0.90 - public domain image resizing
+ by Jorge L Rodriguez (@VinoBS) - 2014
+ http://github.com/nothings/stb
+
+ Written with emphasis on usability, portability, and efficiency. (No
+ SIMD or threads, so it be easily outperformed by libs that use those.)
+ Only scaling and translation is supported, no rotations or shears.
+ Easy API downsamples w/Mitchell filter, upsamples w/cubic interpolation.
+
+ COMPILING & LINKING
+ In one C/C++ file that #includes this file, do this:
+ #define STB_IMAGE_RESIZE_IMPLEMENTATION
+ before the #include. That will create the implementation in that file.
+
+ QUICKSTART
+ stbir_resize_uint8( input_pixels , in_w , in_h , 0,
+ output_pixels, out_w, out_h, 0, num_channels)
+ stbir_resize_float(...)
+ stbir_resize_uint8_srgb( input_pixels , in_w , in_h , 0,
+ output_pixels, out_w, out_h, 0,
+ num_channels , alpha_chan , 0)
+ stbir_resize_uint8_srgb_edgemode(
+ input_pixels , in_w , in_h , 0,
+ output_pixels, out_w, out_h, 0,
+ num_channels , alpha_chan , 0, STBIR_EDGE_CLAMP)
+ // WRAP/REFLECT/ZERO
+
+ FULL API
+ See the "header file" section of the source for API documentation.
+
+ ADDITIONAL DOCUMENTATION
+
+ SRGB & FLOATING POINT REPRESENTATION
+ The sRGB functions presume IEEE floating point. If you do not have
+ IEEE floating point, define STBIR_NON_IEEE_FLOAT. This will use
+ a slower implementation.
+
+ MEMORY ALLOCATION
+ The resize functions here perform a single memory allocation using
+ malloc. To control the memory allocation, before the #include that
+ triggers the implementation, do:
+
+ #define STBIR_MALLOC(size,context) ...
+ #define STBIR_FREE(ptr,context) ...
+
+ Each resize function makes exactly one call to malloc/free, so to use
+ temp memory, store the temp memory in the context and return that.
+
+ ASSERT
+ Define STBIR_ASSERT(boolval) to override assert() and not use assert.h
+
+ OPTIMIZATION
+ Define STBIR_SATURATE_INT to compute clamp values in-range using
+ integer operations instead of float operations. This may be faster
+ on some platforms.
+
+ DEFAULT FILTERS
+ For functions which don't provide explicit control over what filters
+ to use, you can change the compile-time defaults with
+
+ #define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_something
+ #define STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_something
+
+ See stbir_filter in the header-file section for the list of filters.
+
+ NEW FILTERS
+ A number of 1D filter kernels are used. For a list of
+ supported filters see the stbir_filter enum. To add a new filter,
+ write a filter function and add it to stbir__filter_info_table.
+
+ PROGRESS
+ For interactive use with slow resize operations, you can install
+ a progress-report callback:
+
+ #define STBIR_PROGRESS_REPORT(val) some_func(val)
+
+ The parameter val is a float which goes from 0 to 1 as progress is made.
+
+ For example:
+
+ static void my_progress_report(float progress);
+ #define STBIR_PROGRESS_REPORT(val) my_progress_report(val)
+
+ #define STB_IMAGE_RESIZE_IMPLEMENTATION
+ #include "stb_image_resize.h"
+
+ static void my_progress_report(float progress)
+ {
+ printf("Progress: %f%%\n", progress*100);
+ }
+
+ MAX CHANNELS
+ If your image has more than 64 channels, define STBIR_MAX_CHANNELS
+ to the max you'll have.
+
+ ALPHA CHANNEL
+ Most of the resizing functions provide the ability to control how
+ the alpha channel of an image is processed. The important things
+ to know about this:
+
+ 1. The best mathematically-behaved version of alpha to use is
+ called "premultiplied alpha", in which the other color channels
+ have had the alpha value multiplied in. If you use premultiplied
+ alpha, linear filtering (such as image resampling done by this
+ library, or performed in texture units on GPUs) does the "right
+ thing". While premultiplied alpha is standard in the movie CGI
+ industry, it is still uncommon in the videogame/real-time world.
+
+ If you linearly filter non-premultiplied alpha, strange effects
+ occur. (For example, the average of 1% opaque bright green
+ and 99% opaque black produces 50% transparent dark green when
+ non-premultiplied, whereas premultiplied it produces 50%
+ transparent near-black. The former introduces green energy
+ that doesn't exist in the source image.)
+
+ 2. Artists should not edit premultiplied-alpha images; artists
+ want non-premultiplied alpha images. Thus, art tools generally output
+ non-premultiplied alpha images.
+
+ 3. You will get best results in most cases by converting images
+ to premultiplied alpha before processing them mathematically.
+
+ 4. If you pass the flag STBIR_FLAG_ALPHA_PREMULTIPLIED, the
+ resizer does not do anything special for the alpha channel;
+ it is resampled identically to other channels. This produces
+ the correct results for premultiplied-alpha images, but produces
+ less-than-ideal results for non-premultiplied-alpha images.
+
+ 5. If you do not pass the flag STBIR_FLAG_ALPHA_PREMULTIPLIED,
+ then the resizer weights the contribution of input pixels
+ based on their alpha values, or, equivalently, it multiplies
+ the alpha value into the color channels, resamples, then divides
+ by the resultant alpha value. Input pixels which have alpha=0 do
+ not contribute at all to output pixels unless _all_ of the input
+ pixels affecting that output pixel have alpha=0, in which case
+ the result for that pixel is the same as it would be without
+ STBIR_FLAG_ALPHA_PREMULTIPLIED. However, this is only true for
+ input images in integer formats. For input images in float format,
+ input pixels with alpha=0 have no effect, and output pixels
+ which have alpha=0 will be 0 in all channels. (For float images,
+ you can manually achieve the same result by adding a tiny epsilon
+ value to the alpha channel of every image, and then subtracting
+ or clamping it at the end.)
+
+ 6. You can suppress the behavior described in #5 and make
+ all-0-alpha pixels have 0 in all channels by #defining
+ STBIR_NO_ALPHA_EPSILON.
+
+ 7. You can separately control whether the alpha channel is
+ interpreted as linear or affected by the colorspace. By default
+ it is linear; you almost never want to apply the colorspace.
+ (For example, graphics hardware does not apply sRGB conversion
+ to the alpha channel.)
+
+ ADDITIONAL CONTRIBUTORS
+ Sean Barrett: API design, optimizations
+
+ REVISIONS
+ 0.90 (2014-09-17) first released version
+
+ LICENSE
+ This software is in the public domain. Where that dedication is not
+ recognized, you are granted a perpetual, irrevocable license to copy
+ and modify this file as you see fit.
+
+ TODO
+ Don't decode all of the image data when only processing a partial tile
+ Don't use full-width decode buffers when only processing a partial tile
+ When processing wide images, break processing into tiles so data fits in L1 cache
+ Installable filters?
+ Resize that respects alpha test coverage
+ (Reference code: FloatImage::alphaTestCoverage and FloatImage::scaleAlphaToCoverage:
+ https://code.google.com/p/nvidia-texture-tools/source/browse/trunk/src/nvimage/FloatImage.cpp )
+*/
+
+#ifndef STBIR_INCLUDE_STB_IMAGE_RESIZE_H
+#define STBIR_INCLUDE_STB_IMAGE_RESIZE_H
+
+#ifdef _MSC_VER
+typedef unsigned char stbir_uint8;
+typedef unsigned short stbir_uint16;
+typedef unsigned int stbir_uint32;
+#else
+#include <stdint.h>
+typedef uint8_t stbir_uint8;
+typedef uint16_t stbir_uint16;
+typedef uint32_t stbir_uint32;
+#endif
+
+#ifdef STB_IMAGE_RESIZE_STATIC
+#define STBIRDEF static
+#else
+#ifdef __cplusplus
+#define STBIRDEF extern "C"
+#else
+#define STBIRDEF extern
+#endif
+#endif
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Easy-to-use API:
+//
+// * "input pixels" points to an array of image data with 'num_channels' channels (e.g. RGB=3, RGBA=4)
+// * input_w is input image width (x-axis), input_h is input image height (y-axis)
+// * stride is the offset between successive rows of image data in memory, in bytes. you can
+// specify 0 to mean packed continuously in memory
+// * alpha channel is treated identically to other channels.
+// * colorspace is linear or sRGB as specified by function name
+// * returned result is 1 for success or 0 in case of an error.
+// #define STBIR_ASSERT() to trigger an assert on parameter validation errors.
+// * Memory required grows approximately linearly with input and output size, but with
+// discontinuities at input_w == output_w and input_h == output_h.
+// * These functions use a "default" resampling filter defined at compile time. To change the filter,
+// you can change the compile-time defaults by #defining STBIR_DEFAULT_FILTER_UPSAMPLE
+// and STBIR_DEFAULT_FILTER_DOWNSAMPLE, or you can use the medium-complexity API.
+
+STBIRDEF int stbir_resize_uint8( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ int num_channels);
+
+STBIRDEF int stbir_resize_float( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ float *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ int num_channels);
+
+
+// The following functions interpret image data as gamma-corrected sRGB.
+// Specify STBIR_ALPHA_CHANNEL_NONE if you have no alpha channel,
+// or otherwise provide the index of the alpha channel. Flags value
+// of 0 will probably do the right thing if you're not sure what
+// the flags mean.
+
+#define STBIR_ALPHA_CHANNEL_NONE -1
+
+// Set this flag if your texture has premultiplied alpha. Otherwise, stbir will
+// use alpha-weighted resampling (effectively premultiplying, resampling,
+// then unpremultiplying).
+#define STBIR_FLAG_ALPHA_PREMULTIPLIED (1 << 0)
+// The specified alpha channel should be handled as gamma-corrected value even
+// when doing sRGB operations.
+#define STBIR_FLAG_ALPHA_USES_COLORSPACE (1 << 1)
+
+STBIRDEF int stbir_resize_uint8_srgb(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ int num_channels, int alpha_channel, int flags);
+
+
+typedef enum
+{
+ STBIR_EDGE_CLAMP = 1,
+ STBIR_EDGE_REFLECT = 2,
+ STBIR_EDGE_WRAP = 3,
+ STBIR_EDGE_ZERO = 4,
+} stbir_edge;
+
+// This function adds the ability to specify how requests to sample off the edge of the image are handled.
+STBIRDEF int stbir_resize_uint8_srgb_edgemode(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ int num_channels, int alpha_channel, int flags,
+ stbir_edge edge_wrap_mode);
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Medium-complexity API
+//
+// This extends the easy-to-use API as follows:
+//
+// * Alpha-channel can be processed separately
+// * If alpha_channel is not STBIR_ALPHA_CHANNEL_NONE
+// * Alpha channel will not be gamma corrected (unless flags&STBIR_FLAG_GAMMA_CORRECT)
+// * Filters will be weighted by alpha channel (unless flags&STBIR_FLAG_ALPHA_PREMULTIPLIED)
+// * Filter can be selected explicitly
+// * uint16 image type
+// * sRGB colorspace available for all types
+// * context parameter for passing to STBIR_MALLOC
+
+typedef enum
+{
+ STBIR_FILTER_DEFAULT = 0, // use same filter type that easy-to-use API chooses
+ STBIR_FILTER_BOX = 1, // A trapezoid w/1-pixel wide ramps, same result as box for integer scale ratios
+ STBIR_FILTER_TRIANGLE = 2, // On upsampling, produces same results as bilinear texture filtering
+ STBIR_FILTER_CUBICBSPLINE = 3, // The cubic b-spline (aka Mitchell-Netrevalli with B=1,C=0), gaussian-esque
+ STBIR_FILTER_CATMULLROM = 4, // An interpolating cubic spline
+ STBIR_FILTER_MITCHELL = 5, // Mitchell-Netrevalli filter with B=1/3, C=1/3
+} stbir_filter;
+
+typedef enum
+{
+ STBIR_COLORSPACE_LINEAR,
+ STBIR_COLORSPACE_SRGB,
+
+ STBIR_MAX_COLORSPACES,
+} stbir_colorspace;
+
+// The following functions are all identical except for the type of the image data
+
+STBIRDEF int stbir_resize_uint8_generic( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ int num_channels, int alpha_channel, int flags,
+ stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space,
+ void *alloc_context);
+
+STBIRDEF int stbir_resize_uint16_generic(const stbir_uint16 *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ stbir_uint16 *output_pixels , int output_w, int output_h, int output_stride_in_bytes,
+ int num_channels, int alpha_channel, int flags,
+ stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space,
+ void *alloc_context);
+
+STBIRDEF int stbir_resize_float_generic( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ float *output_pixels , int output_w, int output_h, int output_stride_in_bytes,
+ int num_channels, int alpha_channel, int flags,
+ stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space,
+ void *alloc_context);
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Full-complexity API
+//
+// This extends the medium API as follows:
+//
+// * uint32 image type
+// * not typesafe
+// * separate filter types for each axis
+// * separate edge modes for each axis
+// * can specify scale explicitly for subpixel correctness
+// * can specify image source tile using texture coordinates
+
+typedef enum
+{
+ STBIR_TYPE_UINT8 ,
+ STBIR_TYPE_UINT16,
+ STBIR_TYPE_UINT32,
+ STBIR_TYPE_FLOAT ,
+
+ STBIR_MAX_TYPES
+} stbir_datatype;
+
+STBIRDEF int stbir_resize( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ void *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ stbir_datatype datatype,
+ int num_channels, int alpha_channel, int flags,
+ stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical,
+ stbir_filter filter_horizontal, stbir_filter filter_vertical,
+ stbir_colorspace space, void *alloc_context);
+
+STBIRDEF int stbir_resize_subpixel(const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ void *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ stbir_datatype datatype,
+ int num_channels, int alpha_channel, int flags,
+ stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical,
+ stbir_filter filter_horizontal, stbir_filter filter_vertical,
+ stbir_colorspace space, void *alloc_context,
+ float x_scale, float y_scale,
+ float x_offset, float y_offset);
+
+STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ void *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ stbir_datatype datatype,
+ int num_channels, int alpha_channel, int flags,
+ stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical,
+ stbir_filter filter_horizontal, stbir_filter filter_vertical,
+ stbir_colorspace space, void *alloc_context,
+ float s0, float t0, float s1, float t1);
+// (s0, t0) & (s1, t1) are the top-left and bottom right corner (uv addressing style: [0, 1]x[0, 1]) of a region of the input image to use.
+
+//
+//
+//// end header file /////////////////////////////////////////////////////
+#endif // STBIR_INCLUDE_STB_IMAGE_RESIZE_H
+
+
+
+
+
+#ifdef STB_IMAGE_RESIZE_IMPLEMENTATION
+
+#ifndef STBIR_ASSERT
+#include <assert.h>
+#define STBIR_ASSERT(x) assert(x)
+#endif
+
+#ifdef STBIR_DEBUG
+#define STBIR__DEBUG_ASSERT STBIR_ASSERT
+#else
+#define STBIR__DEBUG_ASSERT
+#endif
+
+// If you hit this it means I haven't done it yet.
+#define STBIR__UNIMPLEMENTED(x) STBIR_ASSERT(!(x))
+
+// For memset
+#include <string.h>
+
+#include <math.h>
+
+#ifndef STBIR_MALLOC
+#include <stdlib.h>
+#define STBIR_MALLOC(size,c) malloc(size)
+#define STBIR_FREE(ptr,c) free(ptr)
+#endif
+
+#ifndef _MSC_VER
+#ifdef __cplusplus
+#define stbir__inline inline
+#else
+#define stbir__inline
+#endif
+#else
+#define stbir__inline __forceinline
+#endif
+
+
+// should produce compiler error if size is wrong
+typedef unsigned char stbir__validate_uint32[sizeof(stbir_uint32) == 4 ? 1 : -1];
+
+#ifdef _MSC_VER
+#define STBIR__NOTUSED(v) (void)(v)
+#else
+#define STBIR__NOTUSED(v) (void)sizeof(v)
+#endif
+
+#define STBIR__ARRAY_SIZE(a) (sizeof((a))/sizeof((a)[0]))
+
+#ifndef STBIR_DEFAULT_FILTER_UPSAMPLE
+#define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_CATMULLROM
+#endif
+
+#ifndef STBIR_DEFAULT_FILTER_DOWNSAMPLE
+#define STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_MITCHELL
+#endif
+
+#ifndef STBIR_PROGRESS_REPORT
+#define STBIR_PROGRESS_REPORT(float_0_to_1)
+#endif
+
+#ifndef STBIR_MAX_CHANNELS
+#define STBIR_MAX_CHANNELS 64
+#endif
+
+#if STBIR_MAX_CHANNELS > 65536
+#error "Too many channels; STBIR_MAX_CHANNELS must be no more than 65536."
+// because we store the indices in 16-bit variables
+#endif
+
+// This value is added to alpha just before premultiplication to avoid
+// zeroing out color values. It is equivalent to 2^-80. If you don't want
+// that behavior (it may interfere if you have floating point images with
+// very small alpha values) then you can define STBIR_NO_ALPHA_EPSILON to
+// disable it.
+#ifndef STBIR_ALPHA_EPSILON
+#define STBIR_ALPHA_EPSILON ((float)1 / (1 << 20) / (1 << 20) / (1 << 20) / (1 << 20))
+#endif
+
+
+
+#ifdef _MSC_VER
+#define STBIR__UNUSED_PARAM(v) (void)(v)
+#else
+#define STBIR__UNUSED_PARAM(v) (void)sizeof(v)
+#endif
+
+// must match stbir_datatype
+static unsigned char stbir__type_size[] = {
+ 1, // STBIR_TYPE_UINT8
+ 2, // STBIR_TYPE_UINT16
+ 4, // STBIR_TYPE_UINT32
+ 4, // STBIR_TYPE_FLOAT
+};
+
+// Kernel function centered at 0
+typedef float (stbir__kernel_fn)(float x, float scale);
+typedef float (stbir__support_fn)(float scale);
+
+typedef struct
+{
+ stbir__kernel_fn* kernel;
+ stbir__support_fn* support;
+} stbir__filter_info;
+
+// When upsampling, the contributors are which source pixels contribute.
+// When downsampling, the contributors are which destination pixels are contributed to.
+typedef struct
+{
+ int n0; // First contributing pixel
+ int n1; // Last contributing pixel
+} stbir__contributors;
+
+typedef struct
+{
+ const void* input_data;
+ int input_w;
+ int input_h;
+ int input_stride_bytes;
+
+ void* output_data;
+ int output_w;
+ int output_h;
+ int output_stride_bytes;
+
+ float s0, t0, s1, t1;
+
+ float horizontal_shift; // Units: output pixels
+ float vertical_shift; // Units: output pixels
+ float horizontal_scale;
+ float vertical_scale;
+
+ int channels;
+ int alpha_channel;
+ stbir_uint32 flags;
+ stbir_datatype type;
+ stbir_filter horizontal_filter;
+ stbir_filter vertical_filter;
+ stbir_edge edge_horizontal;
+ stbir_edge edge_vertical;
+ stbir_colorspace colorspace;
+
+ stbir__contributors* horizontal_contributors;
+ float* horizontal_coefficients;
+
+ stbir__contributors* vertical_contributors;
+ float* vertical_coefficients;
+
+ int decode_buffer_pixels;
+ float* decode_buffer;
+
+ float* horizontal_buffer;
+
+ // cache these because ceil/floor are inexplicably showing up in profile
+ int horizontal_coefficient_width;
+ int vertical_coefficient_width;
+ int horizontal_filter_pixel_width;
+ int vertical_filter_pixel_width;
+ int horizontal_filter_pixel_margin;
+ int vertical_filter_pixel_margin;
+ int horizontal_num_contributors;
+ int vertical_num_contributors;
+
+ int ring_buffer_length_bytes; // The length of an individual entry in the ring buffer. The total number of ring buffers is stbir__get_filter_pixel_width(filter)
+ int ring_buffer_first_scanline;
+ int ring_buffer_last_scanline;
+ int ring_buffer_begin_index;
+ float* ring_buffer;
+
+ float* encode_buffer; // A temporary buffer to store floats so we don't lose precision while we do multiply-adds.
+
+ int horizontal_contributors_size;
+ int horizontal_coefficients_size;
+ int vertical_contributors_size;
+ int vertical_coefficients_size;
+ int decode_buffer_size;
+ int horizontal_buffer_size;
+ int ring_buffer_size;
+ int encode_buffer_size;
+} stbir__info;
+
+static stbir__inline int stbir__min(int a, int b)
+{
+ return a < b ? a : b;
+}
+
+static stbir__inline int stbir__max(int a, int b)
+{
+ return a > b ? a : b;
+}
+
+static stbir__inline float stbir__saturate(float x)
+{
+ if (x < 0)
+ return 0;
+
+ if (x > 1)
+ return 1;
+
+ return x;
+}
+
+#ifdef STBIR_SATURATE_INT
+static stbir__inline stbir_uint8 stbir__saturate8(int x)
+{
+ if ((unsigned int) x <= 255)
+ return x;
+
+ if (x < 0)
+ return 0;
+
+ return 255;
+}
+
+static stbir__inline stbir_uint16 stbir__saturate16(int x)
+{
+ if ((unsigned int) x <= 65535)
+ return x;
+
+ if (x < 0)
+ return 0;
+
+ return 65535;
+}
+#endif
+
+static float stbir__srgb_uchar_to_linear_float[256] = {
+ 0.000000f, 0.000304f, 0.000607f, 0.000911f, 0.001214f, 0.001518f, 0.001821f, 0.002125f, 0.002428f, 0.002732f, 0.003035f,
+ 0.003347f, 0.003677f, 0.004025f, 0.004391f, 0.004777f, 0.005182f, 0.005605f, 0.006049f, 0.006512f, 0.006995f, 0.007499f,
+ 0.008023f, 0.008568f, 0.009134f, 0.009721f, 0.010330f, 0.010960f, 0.011612f, 0.012286f, 0.012983f, 0.013702f, 0.014444f,
+ 0.015209f, 0.015996f, 0.016807f, 0.017642f, 0.018500f, 0.019382f, 0.020289f, 0.021219f, 0.022174f, 0.023153f, 0.024158f,
+ 0.025187f, 0.026241f, 0.027321f, 0.028426f, 0.029557f, 0.030713f, 0.031896f, 0.033105f, 0.034340f, 0.035601f, 0.036889f,
+ 0.038204f, 0.039546f, 0.040915f, 0.042311f, 0.043735f, 0.045186f, 0.046665f, 0.048172f, 0.049707f, 0.051269f, 0.052861f,
+ 0.054480f, 0.056128f, 0.057805f, 0.059511f, 0.061246f, 0.063010f, 0.064803f, 0.066626f, 0.068478f, 0.070360f, 0.072272f,
+ 0.074214f, 0.076185f, 0.078187f, 0.080220f, 0.082283f, 0.084376f, 0.086500f, 0.088656f, 0.090842f, 0.093059f, 0.095307f,
+ 0.097587f, 0.099899f, 0.102242f, 0.104616f, 0.107023f, 0.109462f, 0.111932f, 0.114435f, 0.116971f, 0.119538f, 0.122139f,
+ 0.124772f, 0.127438f, 0.130136f, 0.132868f, 0.135633f, 0.138432f, 0.141263f, 0.144128f, 0.147027f, 0.149960f, 0.152926f,
+ 0.155926f, 0.158961f, 0.162029f, 0.165132f, 0.168269f, 0.171441f, 0.174647f, 0.177888f, 0.181164f, 0.184475f, 0.187821f,
+ 0.191202f, 0.194618f, 0.198069f, 0.201556f, 0.205079f, 0.208637f, 0.212231f, 0.215861f, 0.219526f, 0.223228f, 0.226966f,
+ 0.230740f, 0.234551f, 0.238398f, 0.242281f, 0.246201f, 0.250158f, 0.254152f, 0.258183f, 0.262251f, 0.266356f, 0.270498f,
+ 0.274677f, 0.278894f, 0.283149f, 0.287441f, 0.291771f, 0.296138f, 0.300544f, 0.304987f, 0.309469f, 0.313989f, 0.318547f,
+ 0.323143f, 0.327778f, 0.332452f, 0.337164f, 0.341914f, 0.346704f, 0.351533f, 0.356400f, 0.361307f, 0.366253f, 0.371238f,
+ 0.376262f, 0.381326f, 0.386430f, 0.391573f, 0.396755f, 0.401978f, 0.407240f, 0.412543f, 0.417885f, 0.423268f, 0.428691f,
+ 0.434154f, 0.439657f, 0.445201f, 0.450786f, 0.456411f, 0.462077f, 0.467784f, 0.473532f, 0.479320f, 0.485150f, 0.491021f,
+ 0.496933f, 0.502887f, 0.508881f, 0.514918f, 0.520996f, 0.527115f, 0.533276f, 0.539480f, 0.545725f, 0.552011f, 0.558340f,
+ 0.564712f, 0.571125f, 0.577581f, 0.584078f, 0.590619f, 0.597202f, 0.603827f, 0.610496f, 0.617207f, 0.623960f, 0.630757f,
+ 0.637597f, 0.644480f, 0.651406f, 0.658375f, 0.665387f, 0.672443f, 0.679543f, 0.686685f, 0.693872f, 0.701102f, 0.708376f,
+ 0.715694f, 0.723055f, 0.730461f, 0.737911f, 0.745404f, 0.752942f, 0.760525f, 0.768151f, 0.775822f, 0.783538f, 0.791298f,
+ 0.799103f, 0.806952f, 0.814847f, 0.822786f, 0.830770f, 0.838799f, 0.846873f, 0.854993f, 0.863157f, 0.871367f, 0.879622f,
+ 0.887923f, 0.896269f, 0.904661f, 0.913099f, 0.921582f, 0.930111f, 0.938686f, 0.947307f, 0.955974f, 0.964686f, 0.973445f,
+ 0.982251f, 0.991102f, 1.0f
+};
+
+static float stbir__srgb_to_linear(float f)
+{
+ if (f <= 0.04045f)
+ return f / 12.92f;
+ else
+ return (float)pow((f + 0.055f) / 1.055f, 2.4f);
+}
+
+static float stbir__linear_to_srgb(float f)
+{
+ if (f <= 0.0031308f)
+ return f * 12.92f;
+ else
+ return 1.055f * (float)pow(f, 1 / 2.4f) - 0.055f;
+}
+
+#ifndef STBIR_NON_IEEE_FLOAT
+// From https://gist.github.com/rygorous/2203834
+
+typedef union
+{
+ stbir_uint32 u;
+ float f;
+} stbir__FP32;
+
+static const stbir_uint32 fp32_to_srgb8_tab4[104] = {
+ 0x0073000d, 0x007a000d, 0x0080000d, 0x0087000d, 0x008d000d, 0x0094000d, 0x009a000d, 0x00a1000d,
+ 0x00a7001a, 0x00b4001a, 0x00c1001a, 0x00ce001a, 0x00da001a, 0x00e7001a, 0x00f4001a, 0x0101001a,
+ 0x010e0033, 0x01280033, 0x01410033, 0x015b0033, 0x01750033, 0x018f0033, 0x01a80033, 0x01c20033,
+ 0x01dc0067, 0x020f0067, 0x02430067, 0x02760067, 0x02aa0067, 0x02dd0067, 0x03110067, 0x03440067,
+ 0x037800ce, 0x03df00ce, 0x044600ce, 0x04ad00ce, 0x051400ce, 0x057b00c5, 0x05dd00bc, 0x063b00b5,
+ 0x06970158, 0x07420142, 0x07e30130, 0x087b0120, 0x090b0112, 0x09940106, 0x0a1700fc, 0x0a9500f2,
+ 0x0b0f01cb, 0x0bf401ae, 0x0ccb0195, 0x0d950180, 0x0e56016e, 0x0f0d015e, 0x0fbc0150, 0x10630143,
+ 0x11070264, 0x1238023e, 0x1357021d, 0x14660201, 0x156601e9, 0x165a01d3, 0x174401c0, 0x182401af,
+ 0x18fe0331, 0x1a9602fe, 0x1c1502d2, 0x1d7e02ad, 0x1ed4028d, 0x201a0270, 0x21520256, 0x227d0240,
+ 0x239f0443, 0x25c003fe, 0x27bf03c4, 0x29a10392, 0x2b6a0367, 0x2d1d0341, 0x2ebe031f, 0x304d0300,
+ 0x31d105b0, 0x34a80555, 0x37520507, 0x39d504c5, 0x3c37048b, 0x3e7c0458, 0x40a8042a, 0x42bd0401,
+ 0x44c20798, 0x488e071e, 0x4c1c06b6, 0x4f76065d, 0x52a50610, 0x55ac05cc, 0x5892058f, 0x5b590559,
+ 0x5e0c0a23, 0x631c0980, 0x67db08f6, 0x6c55087f, 0x70940818, 0x74a007bd, 0x787d076c, 0x7c330723,
+};
+
+static stbir_uint8 stbir__linear_to_srgb_uchar(float in)
+{
+ static const stbir__FP32 almostone = { 0x3f7fffff }; // 1-eps
+ static const stbir__FP32 minval = { (127-13) << 23 };
+ stbir_uint32 tab,bias,scale,t;
+ stbir__FP32 f;
+
+ // Clamp to [2^(-13), 1-eps]; these two values map to 0 and 1, respectively.
+ // The tests are carefully written so that NaNs map to 0, same as in the reference
+ // implementation.
+ if (!(in > minval.f)) // written this way to catch NaNs
+ in = minval.f;
+ if (in > almostone.f)
+ in = almostone.f;
+
+ // Do the table lookup and unpack bias, scale
+ f.f = in;
+ tab = fp32_to_srgb8_tab4[(f.u - minval.u) >> 20];
+ bias = (tab >> 16) << 9;
+ scale = tab & 0xffff;
+
+ // Grab next-highest mantissa bits and perform linear interpolation
+ t = (f.u >> 12) & 0xff;
+ return (unsigned char) ((bias + scale*t) >> 16);
+}
+
+#else
+// sRGB transition values, scaled by 1<<28
+static int stbir__srgb_offset_to_linear_scaled[256] =
+{
+ 0, 40738, 122216, 203693, 285170, 366648, 448125, 529603,
+ 611080, 692557, 774035, 855852, 942009, 1033024, 1128971, 1229926,
+ 1335959, 1447142, 1563542, 1685229, 1812268, 1944725, 2082664, 2226148,
+ 2375238, 2529996, 2690481, 2856753, 3028870, 3206888, 3390865, 3580856,
+ 3776916, 3979100, 4187460, 4402049, 4622919, 4850123, 5083710, 5323731,
+ 5570236, 5823273, 6082892, 6349140, 6622065, 6901714, 7188133, 7481369,
+ 7781466, 8088471, 8402427, 8723380, 9051372, 9386448, 9728650, 10078021,
+ 10434603, 10798439, 11169569, 11548036, 11933879, 12327139, 12727857, 13136073,
+ 13551826, 13975156, 14406100, 14844697, 15290987, 15745007, 16206795, 16676389,
+ 17153826, 17639142, 18132374, 18633560, 19142734, 19659934, 20185196, 20718552,
+ 21260042, 21809696, 22367554, 22933648, 23508010, 24090680, 24681686, 25281066,
+ 25888850, 26505076, 27129772, 27762974, 28404716, 29055026, 29713942, 30381490,
+ 31057708, 31742624, 32436272, 33138682, 33849884, 34569912, 35298800, 36036568,
+ 36783260, 37538896, 38303512, 39077136, 39859796, 40651528, 41452360, 42262316,
+ 43081432, 43909732, 44747252, 45594016, 46450052, 47315392, 48190064, 49074096,
+ 49967516, 50870356, 51782636, 52704392, 53635648, 54576432, 55526772, 56486700,
+ 57456236, 58435408, 59424248, 60422780, 61431036, 62449032, 63476804, 64514376,
+ 65561776, 66619028, 67686160, 68763192, 69850160, 70947088, 72053992, 73170912,
+ 74297864, 75434880, 76581976, 77739184, 78906536, 80084040, 81271736, 82469648,
+ 83677792, 84896192, 86124888, 87363888, 88613232, 89872928, 91143016, 92423512,
+ 93714432, 95015816, 96327688, 97650056, 98982952, 100326408, 101680440, 103045072,
+ 104420320, 105806224, 107202800, 108610064, 110028048, 111456776, 112896264, 114346544,
+ 115807632, 117279552, 118762328, 120255976, 121760536, 123276016, 124802440, 126339832,
+ 127888216, 129447616, 131018048, 132599544, 134192112, 135795792, 137410592, 139036528,
+ 140673648, 142321952, 143981456, 145652208, 147334208, 149027488, 150732064, 152447968,
+ 154175200, 155913792, 157663776, 159425168, 161197984, 162982240, 164777968, 166585184,
+ 168403904, 170234160, 172075968, 173929344, 175794320, 177670896, 179559120, 181458992,
+ 183370528, 185293776, 187228736, 189175424, 191133888, 193104112, 195086128, 197079968,
+ 199085648, 201103184, 203132592, 205173888, 207227120, 209292272, 211369392, 213458480,
+ 215559568, 217672656, 219797792, 221934976, 224084240, 226245600, 228419056, 230604656,
+ 232802400, 235012320, 237234432, 239468736, 241715280, 243974080, 246245120, 248528464,
+ 250824112, 253132064, 255452368, 257785040, 260130080, 262487520, 264857376, 267239664,
+};
+
+static stbir_uint8 stbir__linear_to_srgb_uchar(float f)
+{
+ int x = (int) (f * (1 << 28)); // has headroom so you don't need to clamp
+ int v = 0;
+ int i;
+
+ // Refine the guess with a short binary search.
+ i = v + 128; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i;
+ i = v + 64; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i;
+ i = v + 32; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i;
+ i = v + 16; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i;
+ i = v + 8; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i;
+ i = v + 4; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i;
+ i = v + 2; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i;
+ i = v + 1; if (x >= stbir__srgb_offset_to_linear_scaled[i]) v = i;
+
+ return (stbir_uint8) v;
+}
+#endif
+
+static float stbir__filter_trapezoid(float x, float scale)
+{
+ float halfscale = scale / 2;
+ float t = 0.5f + halfscale;
+ STBIR__DEBUG_ASSERT(scale <= 1);
+
+ x = (float)fabs(x);
+
+ if (x >= t)
+ return 0;
+ else
+ {
+ float r = 0.5f - halfscale;
+ if (x <= r)
+ return 1;
+ else
+ return (t - x) / scale;
+ }
+}
+
+static float stbir__support_trapezoid(float scale)
+{
+ STBIR__DEBUG_ASSERT(scale <= 1);
+ return 0.5f + scale / 2;
+}
+
+static float stbir__filter_triangle(float x, float s)
+{
+ STBIR__UNUSED_PARAM(s);
+
+ x = (float)fabs(x);
+
+ if (x <= 1.0f)
+ return 1 - x;
+ else
+ return 0;
+}
+
+static float stbir__filter_cubic(float x, float s)
+{
+ STBIR__UNUSED_PARAM(s);
+
+ x = (float)fabs(x);
+
+ if (x < 1.0f)
+ return (4 + x*x*(3*x - 6))/6;
+ else if (x < 2.0f)
+ return (8 + x*(-12 + x*(6 - x)))/6;
+
+ return (0.0f);
+}
+
+static float stbir__filter_catmullrom(float x, float s)
+{
+ STBIR__UNUSED_PARAM(s);
+
+ x = (float)fabs(x);
+
+ if (x < 1.0f)
+ return 1 - x*x*(2.5f - 1.5f*x);
+ else if (x < 2.0f)
+ return 2 - x*(4 + x*(0.5f*x - 2.5f));
+
+ return (0.0f);
+}
+
+static float stbir__filter_mitchell(float x, float s)
+{
+ STBIR__UNUSED_PARAM(s);
+
+ x = (float)fabs(x);
+
+ if (x < 1.0f)
+ return (16 + x*x*(21 * x - 36))/18;
+ else if (x < 2.0f)
+ return (32 + x*(-60 + x*(36 - 7*x)))/18;
+
+ return (0.0f);
+}
+
+static float stbir__support_zero(float s)
+{
+ STBIR__UNUSED_PARAM(s);
+ return 0;
+}
+
+static float stbir__support_one(float s)
+{
+ STBIR__UNUSED_PARAM(s);
+ return 1;
+}
+
+static float stbir__support_two(float s)
+{
+ STBIR__UNUSED_PARAM(s);
+ return 2;
+}
+
+static stbir__filter_info stbir__filter_info_table[] = {
+ { NULL, stbir__support_zero },
+ { stbir__filter_trapezoid, stbir__support_trapezoid },
+ { stbir__filter_triangle, stbir__support_one },
+ { stbir__filter_cubic, stbir__support_two },
+ { stbir__filter_catmullrom, stbir__support_two },
+ { stbir__filter_mitchell, stbir__support_two },
+};
+
+stbir__inline static int stbir__use_upsampling(float ratio)
+{
+ return ratio > 1;
+}
+
+stbir__inline static int stbir__use_width_upsampling(stbir__info* stbir_info)
+{
+ return stbir__use_upsampling(stbir_info->horizontal_scale);
+}
+
+stbir__inline static int stbir__use_height_upsampling(stbir__info* stbir_info)
+{
+ return stbir__use_upsampling(stbir_info->vertical_scale);
+}
+
+// This is the maximum number of input samples that can affect an output sample
+// with the given filter
+static int stbir__get_filter_pixel_width(stbir_filter filter, float scale)
+{
+ STBIR_ASSERT(filter != 0);
+ STBIR_ASSERT(filter < STBIR__ARRAY_SIZE(stbir__filter_info_table));
+
+ if (stbir__use_upsampling(scale))
+ return (int)ceil(stbir__filter_info_table[filter].support(1/scale) * 2);
+ else
+ return (int)ceil(stbir__filter_info_table[filter].support(scale) * 2 / scale);
+}
+
+// This is how much to expand buffers to account for filters seeking outside
+// the image boundaries.
+static int stbir__get_filter_pixel_margin(stbir_filter filter, float scale)
+{
+ return stbir__get_filter_pixel_width(filter, scale) / 2;
+}
+
+static int stbir__get_coefficient_width(stbir_filter filter, float scale)
+{
+ if (stbir__use_upsampling(scale))
+ return (int)ceil(stbir__filter_info_table[filter].support(1 / scale) * 2);
+ else
+ return (int)ceil(stbir__filter_info_table[filter].support(scale) * 2);
+}
+
+static int stbir__get_contributors(float scale, stbir_filter filter, int input_size, int output_size)
+{
+ if (stbir__use_upsampling(scale))
+ return output_size;
+ else
+ return (input_size + stbir__get_filter_pixel_margin(filter, scale) * 2);
+}
+
+static int stbir__get_total_horizontal_coefficients(stbir__info* info)
+{
+ return info->horizontal_num_contributors
+ * stbir__get_coefficient_width (info->horizontal_filter, info->horizontal_scale);
+}
+
+static int stbir__get_total_vertical_coefficients(stbir__info* info)
+{
+ return info->vertical_num_contributors
+ * stbir__get_coefficient_width (info->vertical_filter, info->vertical_scale);
+}
+
+static stbir__contributors* stbir__get_contributor(stbir__contributors* contributors, int n)
+{
+ return &contributors[n];
+}
+
+// For perf reasons this code is duplicated in stbir__resample_horizontal_upsample/downsample,
+// if you change it here change it there too.
+static float* stbir__get_coefficient(float* coefficients, stbir_filter filter, float scale, int n, int c)
+{
+ int width = stbir__get_coefficient_width(filter, scale);
+ return &coefficients[width*n + c];
+}
+
+static int stbir__edge_wrap_slow(stbir_edge edge, int n, int max)
+{
+ switch (edge)
+ {
+ case STBIR_EDGE_ZERO:
+ return 0; // we'll decode the wrong pixel here, and then overwrite with 0s later
+
+ case STBIR_EDGE_CLAMP:
+ if (n < 0)
+ return 0;
+
+ if (n >= max)
+ return max - 1;
+
+ return n; // NOTREACHED
+
+ case STBIR_EDGE_REFLECT:
+ {
+ if (n < 0)
+ {
+ if (n < max)
+ return -n;
+ else
+ return max - 1;
+ }
+
+ if (n >= max)
+ {
+ int max2 = max * 2;
+ if (n >= max2)
+ return 0;
+ else
+ return max2 - n - 1;
+ }
+
+ return n; // NOTREACHED
+ }
+
+ case STBIR_EDGE_WRAP:
+ if (n >= 0)
+ return (n % max);
+ else
+ {
+ int m = (-n) % max;
+
+ if (m != 0)
+ m = max - m;
+
+ return (m);
+ }
+ return n; // NOTREACHED
+
+ default:
+ STBIR__UNIMPLEMENTED("Unimplemented edge type");
+ return 0;
+ }
+}
+
+stbir__inline static int stbir__edge_wrap(stbir_edge edge, int n, int max)
+{
+ // avoid per-pixel switch
+ if (n >= 0 && n < max)
+ return n;
+ return stbir__edge_wrap_slow(edge, n, max);
+}
+
+// What input pixels contribute to this output pixel?
+static void stbir__calculate_sample_range_upsample(int n, float out_filter_radius, float scale_ratio, float out_shift, int* in_first_pixel, int* in_last_pixel, float* in_center_of_out)
+{
+ float out_pixel_center = (float)n + 0.5f;
+ float out_pixel_influence_lowerbound = out_pixel_center - out_filter_radius;
+ float out_pixel_influence_upperbound = out_pixel_center + out_filter_radius;
+
+ float in_pixel_influence_lowerbound = (out_pixel_influence_lowerbound + out_shift) / scale_ratio;
+ float in_pixel_influence_upperbound = (out_pixel_influence_upperbound + out_shift) / scale_ratio;
+
+ *in_center_of_out = (out_pixel_center + out_shift) / scale_ratio;
+ *in_first_pixel = (int)(floor(in_pixel_influence_lowerbound + 0.5));
+ *in_last_pixel = (int)(floor(in_pixel_influence_upperbound - 0.5));
+}
+
+// What output pixels does this input pixel contribute to?
+static void stbir__calculate_sample_range_downsample(int n, float in_pixels_radius, float scale_ratio, float out_shift, int* out_first_pixel, int* out_last_pixel, float* out_center_of_in)
+{
+ float in_pixel_center = (float)n + 0.5f;
+ float in_pixel_influence_lowerbound = in_pixel_center - in_pixels_radius;
+ float in_pixel_influence_upperbound = in_pixel_center + in_pixels_radius;
+
+ float out_pixel_influence_lowerbound = in_pixel_influence_lowerbound * scale_ratio - out_shift;
+ float out_pixel_influence_upperbound = in_pixel_influence_upperbound * scale_ratio - out_shift;
+
+ *out_center_of_in = in_pixel_center * scale_ratio - out_shift;
+ *out_first_pixel = (int)(floor(out_pixel_influence_lowerbound + 0.5));
+ *out_last_pixel = (int)(floor(out_pixel_influence_upperbound - 0.5));
+}
+
+static void stbir__calculate_coefficients_upsample(stbir__info* stbir_info, stbir_filter filter, float scale, int in_first_pixel, int in_last_pixel, float in_center_of_out, stbir__contributors* contributor, float* coefficient_group)
+{
+ int i;
+ float total_filter = 0;
+ float filter_scale;
+
+ STBIR__DEBUG_ASSERT(in_last_pixel - in_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support(1/scale) * 2)); // Taken directly from stbir__get_coefficient_width() which we can't call because we don't know if we're horizontal or vertical.
+
+ contributor->n0 = in_first_pixel;
+ contributor->n1 = in_last_pixel;
+
+ STBIR__DEBUG_ASSERT(contributor->n1 >= contributor->n0);
+
+ for (i = 0; i <= in_last_pixel - in_first_pixel; i++)
+ {
+ float in_pixel_center = (float)(i + in_first_pixel) + 0.5f;
+ coefficient_group[i] = stbir__filter_info_table[filter].kernel(in_center_of_out - in_pixel_center, 1 / scale);
+
+ // If the coefficient is zero, skip it. (Don't do the <0 check here, we want the influence of those outside pixels.)
+ if (i == 0 && !coefficient_group[i])
+ {
+ contributor->n0 = ++in_first_pixel;
+ i--;
+ continue;
+ }
+
+ total_filter += coefficient_group[i];
+ }
+
+ STBIR__DEBUG_ASSERT(stbir__filter_info_table[filter].kernel((float)(in_last_pixel + 1) + 0.5f - in_center_of_out, 1/scale) == 0);
+
+ STBIR__DEBUG_ASSERT(total_filter > 0.9);
+ STBIR__DEBUG_ASSERT(total_filter < 1.1f); // Make sure it's not way off.
+
+ // Make sure the sum of all coefficients is 1.
+ filter_scale = 1 / total_filter;
+
+ for (i = 0; i <= in_last_pixel - in_first_pixel; i++)
+ coefficient_group[i] *= filter_scale;
+
+ for (i = in_last_pixel - in_first_pixel; i >= 0; i--)
+ {
+ if (coefficient_group[i])
+ break;
+
+ // This line has no weight. We can skip it.
+ contributor->n1 = contributor->n0 + i - 1;
+ }
+}
+
+static void stbir__calculate_coefficients_downsample(stbir__info* stbir_info, stbir_filter filter, float scale_ratio, int out_first_pixel, int out_last_pixel, float out_center_of_in, stbir__contributors* contributor, float* coefficient_group)
+{
+ int i;
+
+ STBIR__DEBUG_ASSERT(out_last_pixel - out_first_pixel <= (int)ceil(stbir__filter_info_table[filter].support(scale_ratio) * 2)); // Taken directly from stbir__get_coefficient_width() which we can't call because we don't know if we're horizontal or vertical.
+
+ contributor->n0 = out_first_pixel;
+ contributor->n1 = out_last_pixel;
+
+ STBIR__DEBUG_ASSERT(contributor->n1 >= contributor->n0);
+
+ for (i = 0; i <= out_last_pixel - out_first_pixel; i++)
+ {
+ float out_pixel_center = (float)(i + out_first_pixel) + 0.5f;
+ float x = out_pixel_center - out_center_of_in;
+ coefficient_group[i] = stbir__filter_info_table[filter].kernel(x, scale_ratio) * scale_ratio;
+ }
+
+ STBIR__DEBUG_ASSERT(stbir__filter_info_table[filter].kernel((float)(out_last_pixel + 1) + 0.5f - out_center_of_in, scale_ratio) == 0);
+
+ for (i = out_last_pixel - out_first_pixel; i >= 0; i--)
+ {
+ if (coefficient_group[i])
+ break;
+
+ // This line has no weight. We can skip it.
+ contributor->n1 = contributor->n0 + i - 1;
+ }
+}
+
+static void stbir__normalize_downsample_coefficients(stbir__info* stbir_info, stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size)
+{
+ int num_contributors = stbir__get_contributors(scale_ratio, filter, input_size, output_size);
+ int num_coefficients = stbir__get_coefficient_width(filter, scale_ratio);
+ int i, j;
+ int skip;
+
+ for (i = 0; i < output_size; i++)
+ {
+ float scale;
+ float total = 0;
+
+ for (j = 0; j < num_contributors; j++)
+ {
+ if (i >= contributors[j].n0 && i <= contributors[j].n1)
+ {
+ float coefficient = *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i - contributors[j].n0);
+ total += coefficient;
+ }
+ else if (i < contributors[j].n0)
+ break;
+ }
+
+ STBIR__DEBUG_ASSERT(total > 0.9f);
+ STBIR__DEBUG_ASSERT(total < 1.1f);
+
+ scale = 1 / total;
+
+ for (j = 0; j < num_contributors; j++)
+ {
+ if (i >= contributors[j].n0 && i <= contributors[j].n1)
+ *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i - contributors[j].n0) *= scale;
+ else if (i < contributors[j].n0)
+ break;
+ }
+ }
+
+ // Optimize: Skip zero coefficients and contributions outside of image bounds.
+ // Do this after normalizing because normalization depends on the n0/n1 values.
+ for (j = 0; j < num_contributors; j++)
+ {
+ int range, max, width;
+
+ skip = 0;
+ while (*stbir__get_coefficient(coefficients, filter, scale_ratio, j, skip) == 0)
+ skip++;
+
+ contributors[j].n0 += skip;
+
+ while (contributors[j].n0 < 0)
+ {
+ contributors[j].n0++;
+ skip++;
+ }
+
+ range = contributors[j].n1 - contributors[j].n0 + 1;
+ max = stbir__min(num_coefficients, range);
+
+ width = stbir__get_coefficient_width(filter, scale_ratio);
+ for (i = 0; i < max; i++)
+ {
+ if (i + skip >= width)
+ break;
+
+ *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i) = *stbir__get_coefficient(coefficients, filter, scale_ratio, j, i + skip);
+ }
+
+ continue;
+ }
+
+ // Using min to avoid writing into invalid pixels.
+ for (i = 0; i < num_contributors; i++)
+ contributors[i].n1 = stbir__min(contributors[i].n1, output_size - 1);
+}
+
+// Each scan line uses the same kernel values so we should calculate the kernel
+// values once and then we can use them for every scan line.
+static void stbir__calculate_filters(stbir__info* stbir_info, stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size)
+{
+ int n;
+ int total_contributors = stbir__get_contributors(scale_ratio, filter, input_size, output_size);
+
+ if (stbir__use_upsampling(scale_ratio))
+ {
+ float out_pixels_radius = stbir__filter_info_table[filter].support(1 / scale_ratio) * scale_ratio;
+
+ // Looping through out pixels
+ for (n = 0; n < total_contributors; n++)
+ {
+ float in_center_of_out; // Center of the current out pixel in the in pixel space
+ int in_first_pixel, in_last_pixel;
+
+ stbir__calculate_sample_range_upsample(n, out_pixels_radius, scale_ratio, shift, &in_first_pixel, &in_last_pixel, &in_center_of_out);
+
+ stbir__calculate_coefficients_upsample(stbir_info, filter, scale_ratio, in_first_pixel, in_last_pixel, in_center_of_out, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0));
+ }
+ }
+ else
+ {
+ float in_pixels_radius = stbir__filter_info_table[filter].support(scale_ratio) / scale_ratio;
+
+ // Looping through in pixels
+ for (n = 0; n < total_contributors; n++)
+ {
+ float out_center_of_in; // Center of the current out pixel in the in pixel space
+ int out_first_pixel, out_last_pixel;
+ int n_adjusted = n - stbir__get_filter_pixel_margin(filter, scale_ratio);
+
+ stbir__calculate_sample_range_downsample(n_adjusted, in_pixels_radius, scale_ratio, shift, &out_first_pixel, &out_last_pixel, &out_center_of_in);
+
+ stbir__calculate_coefficients_downsample(stbir_info, filter, scale_ratio, out_first_pixel, out_last_pixel, out_center_of_in, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0));
+ }
+
+ stbir__normalize_downsample_coefficients(stbir_info, contributors, coefficients, filter, scale_ratio, shift, input_size, output_size);
+ }
+}
+
+static float* stbir__get_decode_buffer(stbir__info* stbir_info)
+{
+ // The 0 index of the decode buffer starts after the margin. This makes
+ // it okay to use negative indexes on the decode buffer.
+ return &stbir_info->decode_buffer[stbir_info->horizontal_filter_pixel_margin * stbir_info->channels];
+}
+
+#define STBIR__DECODE(type, colorspace) ((type) * (STBIR_MAX_COLORSPACES) + (colorspace))
+
+static void stbir__decode_scanline(stbir__info* stbir_info, int n)
+{
+ int c;
+ int channels = stbir_info->channels;
+ int alpha_channel = stbir_info->alpha_channel;
+ int type = stbir_info->type;
+ int colorspace = stbir_info->colorspace;
+ int input_w = stbir_info->input_w;
+ int input_stride_bytes = stbir_info->input_stride_bytes;
+ float* decode_buffer = stbir__get_decode_buffer(stbir_info);
+ stbir_edge edge_horizontal = stbir_info->edge_horizontal;
+ stbir_edge edge_vertical = stbir_info->edge_vertical;
+ int in_buffer_row_offset = stbir__edge_wrap(edge_vertical, n, stbir_info->input_h) * input_stride_bytes;
+ const void* input_data = (char *) stbir_info->input_data + in_buffer_row_offset;
+ int max_x = input_w + stbir_info->horizontal_filter_pixel_margin;
+ int decode = STBIR__DECODE(type, colorspace);
+
+ int x = -stbir_info->horizontal_filter_pixel_margin;
+
+ // special handling for STBIR_EDGE_ZERO because it needs to return an item that doesn't appear in the input,
+ // and we want to avoid paying overhead on every pixel if not STBIR_EDGE_ZERO
+ if (edge_vertical == STBIR_EDGE_ZERO && (n < 0 || n >= stbir_info->input_h))
+ {
+ for (; x < max_x; x++)
+ for (c = 0; c < channels; c++)
+ decode_buffer[x*channels + c] = 0;
+ return;
+ }
+
+ switch (decode)
+ {
+ case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_LINEAR):
+ for (; x < max_x; x++)
+ {
+ int decode_pixel_index = x * channels;
+ int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
+ for (c = 0; c < channels; c++)
+ decode_buffer[decode_pixel_index + c] = ((float)((const unsigned char*)input_data)[input_pixel_index + c]) / 255;
+ }
+ break;
+
+ case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_SRGB):
+ for (; x < max_x; x++)
+ {
+ int decode_pixel_index = x * channels;
+ int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
+ for (c = 0; c < channels; c++)
+ decode_buffer[decode_pixel_index + c] = stbir__srgb_uchar_to_linear_float[((const unsigned char*)input_data)[input_pixel_index + c]];
+
+ if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
+ decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned char*)input_data)[input_pixel_index + alpha_channel]) / 255;
+ }
+ break;
+
+ case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_LINEAR):
+ for (; x < max_x; x++)
+ {
+ int decode_pixel_index = x * channels;
+ int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
+ for (c = 0; c < channels; c++)
+ decode_buffer[decode_pixel_index + c] = ((float)((const unsigned short*)input_data)[input_pixel_index + c]) / 65535;
+ }
+ break;
+
+ case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_SRGB):
+ for (; x < max_x; x++)
+ {
+ int decode_pixel_index = x * channels;
+ int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
+ for (c = 0; c < channels; c++)
+ decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear(((float)((const unsigned short*)input_data)[input_pixel_index + c]) / 65535);
+
+ if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
+ decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned short*)input_data)[input_pixel_index + alpha_channel]) / 65535;
+ }
+ break;
+
+ case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_LINEAR):
+ for (; x < max_x; x++)
+ {
+ int decode_pixel_index = x * channels;
+ int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
+ for (c = 0; c < channels; c++)
+ decode_buffer[decode_pixel_index + c] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / 4294967295);
+ }
+ break;
+
+ case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_SRGB):
+ for (; x < max_x; x++)
+ {
+ int decode_pixel_index = x * channels;
+ int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
+ for (c = 0; c < channels; c++)
+ decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear((float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / 4294967295));
+
+ if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
+ decode_buffer[decode_pixel_index + alpha_channel] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + alpha_channel]) / 4294967295);
+ }
+ break;
+
+ case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_LINEAR):
+ for (; x < max_x; x++)
+ {
+ int decode_pixel_index = x * channels;
+ int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
+ for (c = 0; c < channels; c++)
+ decode_buffer[decode_pixel_index + c] = ((const float*)input_data)[input_pixel_index + c];
+ }
+ break;
+
+ case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_SRGB):
+ for (; x < max_x; x++)
+ {
+ int decode_pixel_index = x * channels;
+ int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
+ for (c = 0; c < channels; c++)
+ decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear(((const float*)input_data)[input_pixel_index + c]);
+
+ if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
+ decode_buffer[decode_pixel_index + alpha_channel] = ((const float*)input_data)[input_pixel_index + alpha_channel];
+ }
+
+ break;
+
+ default:
+ STBIR__UNIMPLEMENTED("Unknown type/colorspace/channels combination.");
+ break;
+ }
+
+ if (!(stbir_info->flags & STBIR_FLAG_ALPHA_PREMULTIPLIED))
+ {
+ for (x = -stbir_info->horizontal_filter_pixel_margin; x < max_x; x++)
+ {
+ int decode_pixel_index = x * channels;
+
+ // If the alpha value is 0 it will clobber the color values. Make sure it's not.
+ float alpha = decode_buffer[decode_pixel_index + alpha_channel];
+#ifndef STBIR_NO_ALPHA_EPSILON
+ if (stbir_info->type != STBIR_TYPE_FLOAT) {
+ alpha += STBIR_ALPHA_EPSILON;
+ decode_buffer[decode_pixel_index + alpha_channel] = alpha;
+ }
+#endif
+ for (c = 0; c < channels; c++)
+ {
+ if (c == alpha_channel)
+ continue;
+
+ decode_buffer[decode_pixel_index + c] *= alpha;
+ }
+ }
+ }
+
+ if (edge_horizontal == STBIR_EDGE_ZERO)
+ {
+ for (x = -stbir_info->horizontal_filter_pixel_margin; x < 0; x++)
+ {
+ for (c = 0; c < channels; c++)
+ decode_buffer[x*channels + c] = 0;
+ }
+ for (x = input_w; x < max_x; x++)
+ {
+ for (c = 0; c < channels; c++)
+ decode_buffer[x*channels + c] = 0;
+ }
+ }
+}
+
+static float* stbir__get_ring_buffer_entry(float* ring_buffer, int index, int ring_buffer_length)
+{
+ return &ring_buffer[index * ring_buffer_length];
+}
+
+static float* stbir__add_empty_ring_buffer_entry(stbir__info* stbir_info, int n)
+{
+ int ring_buffer_index;
+ float* ring_buffer;
+
+ if (stbir_info->ring_buffer_begin_index < 0)
+ {
+ ring_buffer_index = stbir_info->ring_buffer_begin_index = 0;
+ stbir_info->ring_buffer_first_scanline = n;
+ }
+ else
+ {
+ ring_buffer_index = (stbir_info->ring_buffer_begin_index + (stbir_info->ring_buffer_last_scanline - stbir_info->ring_buffer_first_scanline) + 1) % stbir_info->vertical_filter_pixel_width;
+ STBIR__DEBUG_ASSERT(ring_buffer_index != stbir_info->ring_buffer_begin_index);
+ }
+
+ ring_buffer = stbir__get_ring_buffer_entry(stbir_info->ring_buffer, ring_buffer_index, stbir_info->ring_buffer_length_bytes / sizeof(float));
+ memset(ring_buffer, 0, stbir_info->ring_buffer_length_bytes);
+
+ stbir_info->ring_buffer_last_scanline = n;
+
+ return ring_buffer;
+}
+
+
+static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n, float* output_buffer)
+{
+ int x, k;
+ int output_w = stbir_info->output_w;
+ int kernel_pixel_width = stbir_info->horizontal_filter_pixel_width;
+ int channels = stbir_info->channels;
+ float* decode_buffer = stbir__get_decode_buffer(stbir_info);
+ stbir__contributors* horizontal_contributors = stbir_info->horizontal_contributors;
+ float* horizontal_coefficients = stbir_info->horizontal_coefficients;
+ int coefficient_width = stbir_info->horizontal_coefficient_width;
+
+ for (x = 0; x < output_w; x++)
+ {
+ int n0 = horizontal_contributors[x].n0;
+ int n1 = horizontal_contributors[x].n1;
+
+ int out_pixel_index = x * channels;
+ int coefficient_group = coefficient_width * x;
+ int coefficient_counter = 0;
+
+ STBIR__DEBUG_ASSERT(n1 >= n0);
+ STBIR__DEBUG_ASSERT(n0 >= -stbir_info->horizontal_filter_pixel_margin);
+ STBIR__DEBUG_ASSERT(n1 >= -stbir_info->horizontal_filter_pixel_margin);
+ STBIR__DEBUG_ASSERT(n0 < stbir_info->input_w + stbir_info->horizontal_filter_pixel_margin);
+ STBIR__DEBUG_ASSERT(n1 < stbir_info->input_w + stbir_info->horizontal_filter_pixel_margin);
+
+ switch (channels) {
+ case 1:
+ for (k = n0; k <= n1; k++)
+ {
+ int in_pixel_index = k * 1;
+ float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
+ STBIR__DEBUG_ASSERT(coefficient != 0);
+ output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
+ }
+ break;
+ case 2:
+ for (k = n0; k <= n1; k++)
+ {
+ int in_pixel_index = k * 2;
+ float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
+ STBIR__DEBUG_ASSERT(coefficient != 0);
+ output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
+ output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
+ }
+ break;
+ case 3:
+ for (k = n0; k <= n1; k++)
+ {
+ int in_pixel_index = k * 3;
+ float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
+ STBIR__DEBUG_ASSERT(coefficient != 0);
+ output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
+ output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
+ output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient;
+ }
+ break;
+ case 4:
+ for (k = n0; k <= n1; k++)
+ {
+ int in_pixel_index = k * 4;
+ float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
+ STBIR__DEBUG_ASSERT(coefficient != 0);
+ output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
+ output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
+ output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient;
+ output_buffer[out_pixel_index + 3] += decode_buffer[in_pixel_index + 3] * coefficient;
+ }
+ break;
+ default:
+ for (k = n0; k <= n1; k++)
+ {
+ int in_pixel_index = k * channels;
+ float coefficient = horizontal_coefficients[coefficient_group + coefficient_counter++];
+ int c;
+ STBIR__DEBUG_ASSERT(coefficient != 0);
+ for (c = 0; c < channels; c++)
+ output_buffer[out_pixel_index + c] += decode_buffer[in_pixel_index + c] * coefficient;
+ }
+ break;
+ }
+ }
+}
+
+static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, int n, float* output_buffer)
+{
+ int x, k;
+ int input_w = stbir_info->input_w;
+ int output_w = stbir_info->output_w;
+ int kernel_pixel_width = stbir_info->horizontal_filter_pixel_width;
+ int channels = stbir_info->channels;
+ float* decode_buffer = stbir__get_decode_buffer(stbir_info);
+ stbir__contributors* horizontal_contributors = stbir_info->horizontal_contributors;
+ float* horizontal_coefficients = stbir_info->horizontal_coefficients;
+ int coefficient_width = stbir_info->horizontal_coefficient_width;
+ int filter_pixel_margin = stbir_info->horizontal_filter_pixel_margin;
+ int max_x = input_w + filter_pixel_margin * 2;
+
+ STBIR__DEBUG_ASSERT(!stbir__use_width_upsampling(stbir_info));
+
+ switch (channels) {
+ case 1:
+ for (x = 0; x < max_x; x++)
+ {
+ int n0 = horizontal_contributors[x].n0;
+ int n1 = horizontal_contributors[x].n1;
+
+ int in_x = x - filter_pixel_margin;
+ int in_pixel_index = in_x * 1;
+ int max_n = n1;
+ int coefficient_group = coefficient_width * x;
+
+ for (k = n0; k <= max_n; k++)
+ {
+ int out_pixel_index = k * 1;
+ float coefficient = horizontal_coefficients[coefficient_group + k - n0];
+ STBIR__DEBUG_ASSERT(coefficient != 0);
+ output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
+ }
+ }
+ break;
+
+ case 2:
+ for (x = 0; x < max_x; x++)
+ {
+ int n0 = horizontal_contributors[x].n0;
+ int n1 = horizontal_contributors[x].n1;
+
+ int in_x = x - filter_pixel_margin;
+ int in_pixel_index = in_x * 2;
+ int max_n = n1;
+ int coefficient_group = coefficient_width * x;
+
+ for (k = n0; k <= max_n; k++)
+ {
+ int out_pixel_index = k * 2;
+ float coefficient = horizontal_coefficients[coefficient_group + k - n0];
+ STBIR__DEBUG_ASSERT(coefficient != 0);
+ output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
+ output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
+ }
+ }
+ break;
+
+ case 3:
+ for (x = 0; x < max_x; x++)
+ {
+ int n0 = horizontal_contributors[x].n0;
+ int n1 = horizontal_contributors[x].n1;
+
+ int in_x = x - filter_pixel_margin;
+ int in_pixel_index = in_x * 3;
+ int max_n = n1;
+ int coefficient_group = coefficient_width * x;
+
+ for (k = n0; k <= max_n; k++)
+ {
+ int out_pixel_index = k * 3;
+ float coefficient = horizontal_coefficients[coefficient_group + k - n0];
+ STBIR__DEBUG_ASSERT(coefficient != 0);
+ output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
+ output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
+ output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient;
+ }
+ }
+ break;
+
+ case 4:
+ for (x = 0; x < max_x; x++)
+ {
+ int n0 = horizontal_contributors[x].n0;
+ int n1 = horizontal_contributors[x].n1;
+
+ int in_x = x - filter_pixel_margin;
+ int in_pixel_index = in_x * 4;
+ int max_n = n1;
+ int coefficient_group = coefficient_width * x;
+
+ for (k = n0; k <= max_n; k++)
+ {
+ int out_pixel_index = k * 4;
+ float coefficient = horizontal_coefficients[coefficient_group + k - n0];
+ STBIR__DEBUG_ASSERT(coefficient != 0);
+ output_buffer[out_pixel_index + 0] += decode_buffer[in_pixel_index + 0] * coefficient;
+ output_buffer[out_pixel_index + 1] += decode_buffer[in_pixel_index + 1] * coefficient;
+ output_buffer[out_pixel_index + 2] += decode_buffer[in_pixel_index + 2] * coefficient;
+ output_buffer[out_pixel_index + 3] += decode_buffer[in_pixel_index + 3] * coefficient;
+ }
+ }
+ break;
+
+ default:
+ for (x = 0; x < max_x; x++)
+ {
+ int n0 = horizontal_contributors[x].n0;
+ int n1 = horizontal_contributors[x].n1;
+
+ int in_x = x - filter_pixel_margin;
+ int in_pixel_index = in_x * channels;
+ int max_n = n1;
+ int coefficient_group = coefficient_width * x;
+
+ for (k = n0; k <= max_n; k++)
+ {
+ int c;
+ int out_pixel_index = k * channels;
+ float coefficient = horizontal_coefficients[coefficient_group + k - n0];
+ STBIR__DEBUG_ASSERT(coefficient != 0);
+ for (c = 0; c < channels; c++)
+ output_buffer[out_pixel_index + c] += decode_buffer[in_pixel_index + c] * coefficient;
+ }
+ }
+ break;
+ }
+}
+
+static void stbir__decode_and_resample_upsample(stbir__info* stbir_info, int n)
+{
+ // Decode the nth scanline from the source image into the decode buffer.
+ stbir__decode_scanline(stbir_info, n);
+
+ // Now resample it into the ring buffer.
+ if (stbir__use_width_upsampling(stbir_info))
+ stbir__resample_horizontal_upsample(stbir_info, n, stbir__add_empty_ring_buffer_entry(stbir_info, n));
+ else
+ stbir__resample_horizontal_downsample(stbir_info, n, stbir__add_empty_ring_buffer_entry(stbir_info, n));
+
+ // Now it's sitting in the ring buffer ready to be used as source for the vertical sampling.
+}
+
+static void stbir__decode_and_resample_downsample(stbir__info* stbir_info, int n)
+{
+ // Decode the nth scanline from the source image into the decode buffer.
+ stbir__decode_scanline(stbir_info, n);
+
+ memset(stbir_info->horizontal_buffer, 0, stbir_info->output_w * stbir_info->channels * sizeof(float));
+
+ // Now resample it into the horizontal buffer.
+ if (stbir__use_width_upsampling(stbir_info))
+ stbir__resample_horizontal_upsample(stbir_info, n, stbir_info->horizontal_buffer);
+ else
+ stbir__resample_horizontal_downsample(stbir_info, n, stbir_info->horizontal_buffer);
+
+ // Now it's sitting in the horizontal buffer ready to be distributed into the ring buffers.
+}
+
+// Get the specified scan line from the ring buffer.
+static float* stbir__get_ring_buffer_scanline(int get_scanline, float* ring_buffer, int begin_index, int first_scanline, int ring_buffer_size, int ring_buffer_length)
+{
+ int ring_buffer_index = (begin_index + (get_scanline - first_scanline)) % ring_buffer_size;
+ return stbir__get_ring_buffer_entry(ring_buffer, ring_buffer_index, ring_buffer_length);
+}
+
+
+static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void *output_buffer, float *encode_buffer, int channels, int alpha_channel, int decode)
+{
+ int x;
+ int n;
+ int num_nonalpha;
+ stbir_uint16 nonalpha[STBIR_MAX_CHANNELS];
+
+ if (!(stbir_info->flags&STBIR_FLAG_ALPHA_PREMULTIPLIED))
+ {
+ for (x=0; x < num_pixels; ++x)
+ {
+ int pixel_index = x*channels;
+
+ float alpha = encode_buffer[pixel_index + alpha_channel];
+ float reciprocal_alpha = alpha ? 1.0f / alpha : 0;
+
+ // unrolling this produced a 1% slowdown upscaling a large RGBA linear-space image on my machine - stb
+ for (n = 0; n < channels; n++)
+ if (n != alpha_channel)
+ encode_buffer[pixel_index + n] *= reciprocal_alpha;
+
+ // We added in a small epsilon to prevent the color channel from being deleted with zero alpha.
+ // Because we only add it for integer types, it will automatically be discarded on integer
+ // conversion, so we don't need to subtract it back out (which would be problematic for
+ // numeric precision reasons).
+ }
+ }
+
+ // build a table of all channels that need colorspace correction, so
+ // we don't perform colorspace correction on channels that don't need it.
+ for (x=0, num_nonalpha=0; x < channels; ++x)
+ if (x != alpha_channel || (stbir_info->flags & STBIR_FLAG_ALPHA_USES_COLORSPACE))
+ nonalpha[num_nonalpha++] = x;
+
+ #define STBIR__ROUND_INT(f) ((int) ((f)+0.5))
+ #define STBIR__ROUND_UINT(f) ((stbir_uint32) ((f)+0.5))
+
+ #ifdef STBIR__SATURATE_INT
+ #define STBIR__ENCODE_LINEAR8(f) stbir__saturate8 (STBIR__ROUND_INT((f) * 255 ))
+ #define STBIR__ENCODE_LINEAR16(f) stbir__saturate16(STBIR__ROUND_INT((f) * 65535))
+ #else
+ #define STBIR__ENCODE_LINEAR8(f) (unsigned char ) STBIR__ROUND_INT(stbir__saturate(f) * 255 )
+ #define STBIR__ENCODE_LINEAR16(f) (unsigned short) STBIR__ROUND_INT(stbir__saturate(f) * 65535)
+ #endif
+
+ switch (decode)
+ {
+ case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_LINEAR):
+ for (x=0; x < num_pixels; ++x)
+ {
+ int pixel_index = x*channels;
+
+ for (n = 0; n < channels; n++)
+ {
+ int index = pixel_index + n;
+ ((unsigned char*)output_buffer)[index] = STBIR__ENCODE_LINEAR8(encode_buffer[index]);
+ }
+ }
+ break;
+
+ case STBIR__DECODE(STBIR_TYPE_UINT8, STBIR_COLORSPACE_SRGB):
+ for (x=0; x < num_pixels; ++x)
+ {
+ int pixel_index = x*channels;
+
+ for (n = 0; n < num_nonalpha; n++)
+ {
+ int index = pixel_index + nonalpha[n];
+ ((unsigned char*)output_buffer)[index] = stbir__linear_to_srgb_uchar(encode_buffer[index]);
+ }
+
+ if (!(stbir_info->flags & STBIR_FLAG_ALPHA_USES_COLORSPACE))
+ ((unsigned char *)output_buffer)[pixel_index + alpha_channel] = STBIR__ENCODE_LINEAR8(encode_buffer[pixel_index+alpha_channel]);
+ }
+ break;
+
+ case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_LINEAR):
+ for (x=0; x < num_pixels; ++x)
+ {
+ int pixel_index = x*channels;
+
+ for (n = 0; n < channels; n++)
+ {
+ int index = pixel_index + n;
+ ((unsigned short*)output_buffer)[index] = STBIR__ENCODE_LINEAR16(encode_buffer[index]);
+ }
+ }
+ break;
+
+ case STBIR__DECODE(STBIR_TYPE_UINT16, STBIR_COLORSPACE_SRGB):
+ for (x=0; x < num_pixels; ++x)
+ {
+ int pixel_index = x*channels;
+
+ for (n = 0; n < num_nonalpha; n++)
+ {
+ int index = pixel_index + nonalpha[n];
+ ((unsigned short*)output_buffer)[index] = (unsigned short)STBIR__ROUND_INT(stbir__linear_to_srgb(stbir__saturate(encode_buffer[index])) * 65535);
+ }
+
+ if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
+ ((unsigned short*)output_buffer)[pixel_index + alpha_channel] = STBIR__ENCODE_LINEAR16(encode_buffer[pixel_index + alpha_channel]);
+ }
+
+ break;
+
+ case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_LINEAR):
+ for (x=0; x < num_pixels; ++x)
+ {
+ int pixel_index = x*channels;
+
+ for (n = 0; n < channels; n++)
+ {
+ int index = pixel_index + n;
+ ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__saturate(encode_buffer[index])) * 4294967295);
+ }
+ }
+ break;
+
+ case STBIR__DECODE(STBIR_TYPE_UINT32, STBIR_COLORSPACE_SRGB):
+ for (x=0; x < num_pixels; ++x)
+ {
+ int pixel_index = x*channels;
+
+ for (n = 0; n < num_nonalpha; n++)
+ {
+ int index = pixel_index + nonalpha[n];
+ ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__linear_to_srgb(stbir__saturate(encode_buffer[index]))) * 4294967295);
+ }
+
+ if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
+ ((unsigned int*)output_buffer)[pixel_index + alpha_channel] = (unsigned int)STBIR__ROUND_INT(((double)stbir__saturate(encode_buffer[pixel_index + alpha_channel])) * 4294967295);
+ }
+ break;
+
+ case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_LINEAR):
+ for (x=0; x < num_pixels; ++x)
+ {
+ int pixel_index = x*channels;
+
+ for (n = 0; n < channels; n++)
+ {
+ int index = pixel_index + n;
+ ((float*)output_buffer)[index] = encode_buffer[index];
+ }
+ }
+ break;
+
+ case STBIR__DECODE(STBIR_TYPE_FLOAT, STBIR_COLORSPACE_SRGB):
+ for (x=0; x < num_pixels; ++x)
+ {
+ int pixel_index = x*channels;
+
+ for (n = 0; n < num_nonalpha; n++)
+ {
+ int index = pixel_index + nonalpha[n];
+ ((float*)output_buffer)[index] = stbir__linear_to_srgb(encode_buffer[index]);
+ }
+
+ if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
+ ((float*)output_buffer)[pixel_index + alpha_channel] = encode_buffer[pixel_index + alpha_channel];
+ }
+ break;
+
+ default:
+ STBIR__UNIMPLEMENTED("Unknown type/colorspace/channels combination.");
+ break;
+ }
+}
+
+static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, int in_first_scanline, int in_last_scanline, float in_center_of_out)
+{
+ int x, k;
+ int output_w = stbir_info->output_w;
+ stbir__contributors* vertical_contributors = stbir_info->vertical_contributors;
+ float* vertical_coefficients = stbir_info->vertical_coefficients;
+ int channels = stbir_info->channels;
+ int alpha_channel = stbir_info->alpha_channel;
+ int type = stbir_info->type;
+ int colorspace = stbir_info->colorspace;
+ int kernel_pixel_width = stbir_info->vertical_filter_pixel_width;
+ void* output_data = stbir_info->output_data;
+ float* encode_buffer = stbir_info->encode_buffer;
+ int decode = STBIR__DECODE(type, colorspace);
+ int coefficient_width = stbir_info->vertical_coefficient_width;
+ int coefficient_counter;
+ int contributor = n;
+
+ float* ring_buffer = stbir_info->ring_buffer;
+ int ring_buffer_begin_index = stbir_info->ring_buffer_begin_index;
+ int ring_buffer_first_scanline = stbir_info->ring_buffer_first_scanline;
+ int ring_buffer_last_scanline = stbir_info->ring_buffer_last_scanline;
+ int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float);
+
+ int n0,n1, output_row_start;
+ int coefficient_group = coefficient_width * contributor;
+
+ n0 = vertical_contributors[contributor].n0;
+ n1 = vertical_contributors[contributor].n1;
+
+ output_row_start = n * stbir_info->output_stride_bytes;
+
+ STBIR__DEBUG_ASSERT(stbir__use_height_upsampling(stbir_info));
+
+ memset(encode_buffer, 0, output_w * sizeof(float) * channels);
+
+ // I tried reblocking this for better cache usage of encode_buffer
+ // (using x_outer, k, x_inner), but it lost speed. -- stb
+
+ coefficient_counter = 0;
+ switch (channels) {
+ case 1:
+ for (k = n0; k <= n1; k++)
+ {
+ int coefficient_index = coefficient_counter++;
+ float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
+ float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
+ for (x = 0; x < output_w; ++x)
+ {
+ int in_pixel_index = x * 1;
+ encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient;
+ }
+ }
+ break;
+ case 2:
+ for (k = n0; k <= n1; k++)
+ {
+ int coefficient_index = coefficient_counter++;
+ float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
+ float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
+ for (x = 0; x < output_w; ++x)
+ {
+ int in_pixel_index = x * 2;
+ encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient;
+ encode_buffer[in_pixel_index + 1] += ring_buffer_entry[in_pixel_index + 1] * coefficient;
+ }
+ }
+ break;
+ case 3:
+ for (k = n0; k <= n1; k++)
+ {
+ int coefficient_index = coefficient_counter++;
+ float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
+ float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
+ for (x = 0; x < output_w; ++x)
+ {
+ int in_pixel_index = x * 3;
+ encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient;
+ encode_buffer[in_pixel_index + 1] += ring_buffer_entry[in_pixel_index + 1] * coefficient;
+ encode_buffer[in_pixel_index + 2] += ring_buffer_entry[in_pixel_index + 2] * coefficient;
+ }
+ }
+ break;
+ case 4:
+ for (k = n0; k <= n1; k++)
+ {
+ int coefficient_index = coefficient_counter++;
+ float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
+ float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
+ for (x = 0; x < output_w; ++x)
+ {
+ int in_pixel_index = x * 4;
+ encode_buffer[in_pixel_index + 0] += ring_buffer_entry[in_pixel_index + 0] * coefficient;
+ encode_buffer[in_pixel_index + 1] += ring_buffer_entry[in_pixel_index + 1] * coefficient;
+ encode_buffer[in_pixel_index + 2] += ring_buffer_entry[in_pixel_index + 2] * coefficient;
+ encode_buffer[in_pixel_index + 3] += ring_buffer_entry[in_pixel_index + 3] * coefficient;
+ }
+ }
+ break;
+ default:
+ for (k = n0; k <= n1; k++)
+ {
+ int coefficient_index = coefficient_counter++;
+ float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
+ float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
+ for (x = 0; x < output_w; ++x)
+ {
+ int in_pixel_index = x * channels;
+ int c;
+ for (c = 0; c < channels; c++)
+ encode_buffer[in_pixel_index + c] += ring_buffer_entry[in_pixel_index + c] * coefficient;
+ }
+ }
+ break;
+ }
+ stbir__encode_scanline(stbir_info, output_w, (char *) output_data + output_row_start, encode_buffer, channels, alpha_channel, decode);
+}
+
+static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n, int in_first_scanline, int in_last_scanline, float in_center_of_out)
+{
+ int x, k;
+ int output_w = stbir_info->output_w;
+ int output_h = stbir_info->output_h;
+ stbir__contributors* vertical_contributors = stbir_info->vertical_contributors;
+ float* vertical_coefficients = stbir_info->vertical_coefficients;
+ int channels = stbir_info->channels;
+ int kernel_pixel_width = stbir_info->vertical_filter_pixel_width;
+ void* output_data = stbir_info->output_data;
+ float* horizontal_buffer = stbir_info->horizontal_buffer;
+ int coefficient_width = stbir_info->vertical_coefficient_width;
+ int contributor = n + stbir_info->vertical_filter_pixel_margin;
+
+ float* ring_buffer = stbir_info->ring_buffer;
+ int ring_buffer_begin_index = stbir_info->ring_buffer_begin_index;
+ int ring_buffer_first_scanline = stbir_info->ring_buffer_first_scanline;
+ int ring_buffer_last_scanline = stbir_info->ring_buffer_last_scanline;
+ int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float);
+ int n0,n1;
+
+ n0 = vertical_contributors[contributor].n0;
+ n1 = vertical_contributors[contributor].n1;
+
+ STBIR__DEBUG_ASSERT(!stbir__use_height_upsampling(stbir_info));
+
+ for (k = n0; k <= n1; k++)
+ {
+ int coefficient_index = k - n0;
+ int coefficient_group = coefficient_width * contributor;
+ float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
+
+ float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
+
+ switch (channels) {
+ case 1:
+ for (x = 0; x < output_w; x++)
+ {
+ int in_pixel_index = x * 1;
+ ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient;
+ }
+ break;
+ case 2:
+ for (x = 0; x < output_w; x++)
+ {
+ int in_pixel_index = x * 2;
+ ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient;
+ ring_buffer_entry[in_pixel_index + 1] += horizontal_buffer[in_pixel_index + 1] * coefficient;
+ }
+ break;
+ case 3:
+ for (x = 0; x < output_w; x++)
+ {
+ int in_pixel_index = x * 3;
+ ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient;
+ ring_buffer_entry[in_pixel_index + 1] += horizontal_buffer[in_pixel_index + 1] * coefficient;
+ ring_buffer_entry[in_pixel_index + 2] += horizontal_buffer[in_pixel_index + 2] * coefficient;
+ }
+ break;
+ case 4:
+ for (x = 0; x < output_w; x++)
+ {
+ int in_pixel_index = x * 4;
+ ring_buffer_entry[in_pixel_index + 0] += horizontal_buffer[in_pixel_index + 0] * coefficient;
+ ring_buffer_entry[in_pixel_index + 1] += horizontal_buffer[in_pixel_index + 1] * coefficient;
+ ring_buffer_entry[in_pixel_index + 2] += horizontal_buffer[in_pixel_index + 2] * coefficient;
+ ring_buffer_entry[in_pixel_index + 3] += horizontal_buffer[in_pixel_index + 3] * coefficient;
+ }
+ break;
+ default:
+ for (x = 0; x < output_w; x++)
+ {
+ int in_pixel_index = x * channels;
+
+ int c;
+ for (c = 0; c < channels; c++)
+ ring_buffer_entry[in_pixel_index + c] += horizontal_buffer[in_pixel_index + c] * coefficient;
+ }
+ break;
+ }
+ }
+}
+
+static void stbir__buffer_loop_upsample(stbir__info* stbir_info)
+{
+ int y;
+ float scale_ratio = stbir_info->vertical_scale;
+ float out_scanlines_radius = stbir__filter_info_table[stbir_info->vertical_filter].support(1/scale_ratio) * scale_ratio;
+
+ STBIR__DEBUG_ASSERT(stbir__use_height_upsampling(stbir_info));
+
+ for (y = 0; y < stbir_info->output_h; y++)
+ {
+ float in_center_of_out = 0; // Center of the current out scanline in the in scanline space
+ int in_first_scanline = 0, in_last_scanline = 0;
+
+ stbir__calculate_sample_range_upsample(y, out_scanlines_radius, scale_ratio, stbir_info->vertical_shift, &in_first_scanline, &in_last_scanline, &in_center_of_out);
+
+ STBIR__DEBUG_ASSERT(in_last_scanline - in_first_scanline <= stbir_info->vertical_filter_pixel_width);
+
+ if (stbir_info->ring_buffer_begin_index >= 0)
+ {
+ // Get rid of whatever we don't need anymore.
+ while (in_first_scanline > stbir_info->ring_buffer_first_scanline)
+ {
+ if (stbir_info->ring_buffer_first_scanline == stbir_info->ring_buffer_last_scanline)
+ {
+ // We just popped the last scanline off the ring buffer.
+ // Reset it to the empty state.
+ stbir_info->ring_buffer_begin_index = -1;
+ stbir_info->ring_buffer_first_scanline = 0;
+ stbir_info->ring_buffer_last_scanline = 0;
+ break;
+ }
+ else
+ {
+ stbir_info->ring_buffer_first_scanline++;
+ stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->vertical_filter_pixel_width;
+ }
+ }
+ }
+
+ // Load in new ones.
+ if (stbir_info->ring_buffer_begin_index < 0)
+ stbir__decode_and_resample_upsample(stbir_info, in_first_scanline);
+
+ while (in_last_scanline > stbir_info->ring_buffer_last_scanline)
+ stbir__decode_and_resample_upsample(stbir_info, stbir_info->ring_buffer_last_scanline + 1);
+
+ // Now all buffers should be ready to write a row of vertical sampling.
+ stbir__resample_vertical_upsample(stbir_info, y, in_first_scanline, in_last_scanline, in_center_of_out);
+
+ STBIR_PROGRESS_REPORT((float)y / stbir_info->output_h);
+ }
+}
+
+static void stbir__empty_ring_buffer(stbir__info* stbir_info, int first_necessary_scanline)
+{
+ int output_stride_bytes = stbir_info->output_stride_bytes;
+ int channels = stbir_info->channels;
+ int alpha_channel = stbir_info->alpha_channel;
+ int type = stbir_info->type;
+ int colorspace = stbir_info->colorspace;
+ int output_w = stbir_info->output_w;
+ void* output_data = stbir_info->output_data;
+ int decode = STBIR__DECODE(type, colorspace);
+
+ float* ring_buffer = stbir_info->ring_buffer;
+ int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float);
+
+ if (stbir_info->ring_buffer_begin_index >= 0)
+ {
+ // Get rid of whatever we don't need anymore.
+ while (first_necessary_scanline > stbir_info->ring_buffer_first_scanline)
+ {
+ if (stbir_info->ring_buffer_first_scanline >= 0 && stbir_info->ring_buffer_first_scanline < stbir_info->output_h)
+ {
+ int output_row_start = stbir_info->ring_buffer_first_scanline * output_stride_bytes;
+ float* ring_buffer_entry = stbir__get_ring_buffer_entry(ring_buffer, stbir_info->ring_buffer_begin_index, ring_buffer_length);
+ stbir__encode_scanline(stbir_info, output_w, (char *) output_data + output_row_start, ring_buffer_entry, channels, alpha_channel, decode);
+ STBIR_PROGRESS_REPORT((float)stbir_info->ring_buffer_first_scanline / stbir_info->output_h);
+ }
+
+ if (stbir_info->ring_buffer_first_scanline == stbir_info->ring_buffer_last_scanline)
+ {
+ // We just popped the last scanline off the ring buffer.
+ // Reset it to the empty state.
+ stbir_info->ring_buffer_begin_index = -1;
+ stbir_info->ring_buffer_first_scanline = 0;
+ stbir_info->ring_buffer_last_scanline = 0;
+ break;
+ }
+ else
+ {
+ stbir_info->ring_buffer_first_scanline++;
+ stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->vertical_filter_pixel_width;
+ }
+ }
+ }
+}
+
+static void stbir__buffer_loop_downsample(stbir__info* stbir_info)
+{
+ int y;
+ float scale_ratio = stbir_info->vertical_scale;
+ int output_h = stbir_info->output_h;
+ float in_pixels_radius = stbir__filter_info_table[stbir_info->vertical_filter].support(scale_ratio) / scale_ratio;
+ int pixel_margin = stbir_info->vertical_filter_pixel_margin;
+ int max_y = stbir_info->input_h + pixel_margin;
+
+ STBIR__DEBUG_ASSERT(!stbir__use_height_upsampling(stbir_info));
+
+ for (y = -pixel_margin; y < max_y; y++)
+ {
+ float out_center_of_in; // Center of the current out scanline in the in scanline space
+ int out_first_scanline, out_last_scanline;
+
+ stbir__calculate_sample_range_downsample(y, in_pixels_radius, scale_ratio, stbir_info->vertical_shift, &out_first_scanline, &out_last_scanline, &out_center_of_in);
+
+ STBIR__DEBUG_ASSERT(out_last_scanline - out_first_scanline <= stbir_info->vertical_filter_pixel_width);
+
+ if (out_last_scanline < 0 || out_first_scanline >= output_h)
+ continue;
+
+ stbir__empty_ring_buffer(stbir_info, out_first_scanline);
+
+ stbir__decode_and_resample_downsample(stbir_info, y);
+
+ // Load in new ones.
+ if (stbir_info->ring_buffer_begin_index < 0)
+ stbir__add_empty_ring_buffer_entry(stbir_info, out_first_scanline);
+
+ while (out_last_scanline > stbir_info->ring_buffer_last_scanline)
+ stbir__add_empty_ring_buffer_entry(stbir_info, stbir_info->ring_buffer_last_scanline + 1);
+
+ // Now the horizontal buffer is ready to write to all ring buffer rows.
+ stbir__resample_vertical_downsample(stbir_info, y, out_first_scanline, out_last_scanline, out_center_of_in);
+ }
+
+ stbir__empty_ring_buffer(stbir_info, stbir_info->output_h);
+}
+
+static void stbir__setup(stbir__info *info, int input_w, int input_h, int output_w, int output_h, int channels)
+{
+ info->input_w = input_w;
+ info->input_h = input_h;
+ info->output_w = output_w;
+ info->output_h = output_h;
+ info->channels = channels;
+}
+
+static void stbir__calculate_transform(stbir__info *info, float s0, float t0, float s1, float t1, float *transform)
+{
+ info->s0 = s0;
+ info->t0 = t0;
+ info->s1 = s1;
+ info->t1 = t1;
+
+ if (transform)
+ {
+ info->horizontal_scale = transform[0];
+ info->vertical_scale = transform[1];
+ info->horizontal_shift = transform[2];
+ info->vertical_shift = transform[3];
+ }
+ else
+ {
+ info->horizontal_scale = ((float)info->output_w / info->input_w) / (s1 - s0);
+ info->vertical_scale = ((float)info->output_h / info->input_h) / (t1 - t0);
+
+ info->horizontal_shift = s0 * info->input_w / (s1 - s0);
+ info->vertical_shift = t0 * info->input_h / (t1 - t0);
+ }
+}
+
+static void stbir__choose_filter(stbir__info *info, stbir_filter h_filter, stbir_filter v_filter)
+{
+ if (h_filter == 0)
+ h_filter = stbir__use_upsampling(info->horizontal_scale) ? STBIR_DEFAULT_FILTER_UPSAMPLE : STBIR_DEFAULT_FILTER_DOWNSAMPLE;
+ if (v_filter == 0)
+ v_filter = stbir__use_upsampling(info->vertical_scale) ? STBIR_DEFAULT_FILTER_UPSAMPLE : STBIR_DEFAULT_FILTER_DOWNSAMPLE;
+ info->horizontal_filter = h_filter;
+ info->vertical_filter = v_filter;
+}
+
+static stbir_uint32 stbir__calculate_memory(stbir__info *info)
+{
+ int pixel_margin = stbir__get_filter_pixel_margin(info->horizontal_filter, info->horizontal_scale);
+ int filter_height = stbir__get_filter_pixel_width(info->vertical_filter, info->vertical_scale);
+
+ info->horizontal_num_contributors = stbir__get_contributors(info->horizontal_scale, info->horizontal_filter, info->input_w, info->output_w);
+ info->vertical_num_contributors = stbir__get_contributors(info->vertical_scale , info->vertical_filter , info->input_h, info->output_h);
+
+ info->horizontal_contributors_size = info->horizontal_num_contributors * sizeof(stbir__contributors);
+ info->horizontal_coefficients_size = stbir__get_total_horizontal_coefficients(info) * sizeof(float);
+ info->vertical_contributors_size = info->vertical_num_contributors * sizeof(stbir__contributors);
+ info->vertical_coefficients_size = stbir__get_total_vertical_coefficients(info) * sizeof(float);
+ info->decode_buffer_size = (info->input_w + pixel_margin * 2) * info->channels * sizeof(float);
+ info->horizontal_buffer_size = info->output_w * info->channels * sizeof(float);
+ info->ring_buffer_size = info->output_w * info->channels * filter_height * sizeof(float);
+ info->encode_buffer_size = info->output_w * info->channels * sizeof(float);
+
+ STBIR_ASSERT(info->horizontal_filter != 0);
+ STBIR_ASSERT(info->horizontal_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); // this now happens too late
+ STBIR_ASSERT(info->vertical_filter != 0);
+ STBIR_ASSERT(info->vertical_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table)); // this now happens too late
+
+ if (stbir__use_height_upsampling(info))
+ // The horizontal buffer is for when we're downsampling the height and we
+ // can't output the result of sampling the decode buffer directly into the
+ // ring buffers.
+ info->horizontal_buffer_size = 0;
+ else
+ // The encode buffer is to retain precision in the height upsampling method
+ // and isn't used when height downsampling.
+ info->encode_buffer_size = 0;
+
+ return info->horizontal_contributors_size + info->horizontal_coefficients_size
+ + info->vertical_contributors_size + info->vertical_coefficients_size
+ + info->decode_buffer_size + info->horizontal_buffer_size
+ + info->ring_buffer_size + info->encode_buffer_size;
+}
+
+static int stbir__resize_allocated(stbir__info *info,
+ const void* input_data, int input_stride_in_bytes,
+ void* output_data, int output_stride_in_bytes,
+ int alpha_channel, stbir_uint32 flags, stbir_datatype type,
+ stbir_edge edge_horizontal, stbir_edge edge_vertical, stbir_colorspace colorspace,
+ void* tempmem, size_t tempmem_size_in_bytes)
+{
+ size_t memory_required = stbir__calculate_memory(info);
+
+ int width_stride_input = input_stride_in_bytes ? input_stride_in_bytes : info->channels * info->input_w * stbir__type_size[type];
+ int width_stride_output = output_stride_in_bytes ? output_stride_in_bytes : info->channels * info->output_w * stbir__type_size[type];
+
+#ifdef STBIR_DEBUG_OVERWRITE_TEST
+#define OVERWRITE_ARRAY_SIZE 8
+ unsigned char overwrite_output_before_pre[OVERWRITE_ARRAY_SIZE];
+ unsigned char overwrite_tempmem_before_pre[OVERWRITE_ARRAY_SIZE];
+ unsigned char overwrite_output_after_pre[OVERWRITE_ARRAY_SIZE];
+ unsigned char overwrite_tempmem_after_pre[OVERWRITE_ARRAY_SIZE];
+
+ size_t begin_forbidden = width_stride_output * (info->output_h - 1) + info->output_w * info->channels * stbir__type_size[type];
+ memcpy(overwrite_output_before_pre, &((unsigned char*)output_data)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE);
+ memcpy(overwrite_output_after_pre, &((unsigned char*)output_data)[begin_forbidden], OVERWRITE_ARRAY_SIZE);
+ memcpy(overwrite_tempmem_before_pre, &((unsigned char*)tempmem)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE);
+ memcpy(overwrite_tempmem_after_pre, &((unsigned char*)tempmem)[tempmem_size_in_bytes], OVERWRITE_ARRAY_SIZE);
+#endif
+
+ STBIR_ASSERT(info->channels >= 0);
+ STBIR_ASSERT(info->channels <= STBIR_MAX_CHANNELS);
+
+ if (info->channels < 0 || info->channels > STBIR_MAX_CHANNELS)
+ return 0;
+
+ STBIR_ASSERT(info->horizontal_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table));
+ STBIR_ASSERT(info->vertical_filter < STBIR__ARRAY_SIZE(stbir__filter_info_table));
+
+ if (info->horizontal_filter >= STBIR__ARRAY_SIZE(stbir__filter_info_table))
+ return 0;
+ if (info->vertical_filter >= STBIR__ARRAY_SIZE(stbir__filter_info_table))
+ return 0;
+
+ if (alpha_channel < 0)
+ flags |= STBIR_FLAG_ALPHA_USES_COLORSPACE | STBIR_FLAG_ALPHA_PREMULTIPLIED;
+
+ if (!(flags&STBIR_FLAG_ALPHA_USES_COLORSPACE) || !(flags&STBIR_FLAG_ALPHA_PREMULTIPLIED))
+ STBIR_ASSERT(alpha_channel >= 0 && alpha_channel < info->channels);
+
+ if (alpha_channel >= info->channels)
+ return 0;
+
+ STBIR_ASSERT(tempmem);
+
+ if (!tempmem)
+ return 0;
+
+ STBIR_ASSERT(tempmem_size_in_bytes >= memory_required);
+
+ if (tempmem_size_in_bytes < memory_required)
+ return 0;
+
+ memset(tempmem, 0, tempmem_size_in_bytes);
+
+ info->input_data = input_data;
+ info->input_stride_bytes = width_stride_input;
+
+ info->output_data = output_data;
+ info->output_stride_bytes = width_stride_output;
+
+ info->alpha_channel = alpha_channel;
+ info->flags = flags;
+ info->type = type;
+ info->edge_horizontal = edge_horizontal;
+ info->edge_vertical = edge_vertical;
+ info->colorspace = colorspace;
+
+ info->horizontal_coefficient_width = stbir__get_coefficient_width (info->horizontal_filter, info->horizontal_scale);
+ info->vertical_coefficient_width = stbir__get_coefficient_width (info->vertical_filter , info->vertical_scale );
+ info->horizontal_filter_pixel_width = stbir__get_filter_pixel_width (info->horizontal_filter, info->horizontal_scale);
+ info->vertical_filter_pixel_width = stbir__get_filter_pixel_width (info->vertical_filter , info->vertical_scale );
+ info->horizontal_filter_pixel_margin = stbir__get_filter_pixel_margin(info->horizontal_filter, info->horizontal_scale);
+ info->vertical_filter_pixel_margin = stbir__get_filter_pixel_margin(info->vertical_filter , info->vertical_scale );
+
+ info->ring_buffer_length_bytes = info->output_w * info->channels * sizeof(float);
+ info->decode_buffer_pixels = info->input_w + info->horizontal_filter_pixel_margin * 2;
+
+#define STBIR__NEXT_MEMPTR(current, newtype) (newtype*)(((unsigned char*)current) + current##_size)
+
+ info->horizontal_contributors = (stbir__contributors *) tempmem;
+ info->horizontal_coefficients = STBIR__NEXT_MEMPTR(info->horizontal_contributors, float);
+ info->vertical_contributors = STBIR__NEXT_MEMPTR(info->horizontal_coefficients, stbir__contributors);
+ info->vertical_coefficients = STBIR__NEXT_MEMPTR(info->vertical_contributors, float);
+ info->decode_buffer = STBIR__NEXT_MEMPTR(info->vertical_coefficients, float);
+
+ if (stbir__use_height_upsampling(info))
+ {
+ info->horizontal_buffer = NULL;
+ info->ring_buffer = STBIR__NEXT_MEMPTR(info->decode_buffer, float);
+ info->encode_buffer = STBIR__NEXT_MEMPTR(info->ring_buffer, float);
+
+ STBIR__DEBUG_ASSERT((size_t)STBIR__NEXT_MEMPTR(info->encode_buffer, unsigned char) == (size_t)tempmem + tempmem_size_in_bytes);
+ }
+ else
+ {
+ info->horizontal_buffer = STBIR__NEXT_MEMPTR(info->decode_buffer, float);
+ info->ring_buffer = STBIR__NEXT_MEMPTR(info->horizontal_buffer, float);
+ info->encode_buffer = NULL;
+
+ STBIR__DEBUG_ASSERT((size_t)STBIR__NEXT_MEMPTR(info->ring_buffer, unsigned char) == (size_t)tempmem + tempmem_size_in_bytes);
+ }
+
+#undef STBIR__NEXT_MEMPTR
+
+ // This signals that the ring buffer is empty
+ info->ring_buffer_begin_index = -1;
+
+ stbir__calculate_filters(info, info->horizontal_contributors, info->horizontal_coefficients, info->horizontal_filter, info->horizontal_scale, info->horizontal_shift, info->input_w, info->output_w);
+ stbir__calculate_filters(info, info->vertical_contributors, info->vertical_coefficients, info->vertical_filter, info->vertical_scale, info->vertical_shift, info->input_h, info->output_h);
+
+ STBIR_PROGRESS_REPORT(0);
+
+ if (stbir__use_height_upsampling(info))
+ stbir__buffer_loop_upsample(info);
+ else
+ stbir__buffer_loop_downsample(info);
+
+ STBIR_PROGRESS_REPORT(1);
+
+#ifdef STBIR_DEBUG_OVERWRITE_TEST
+ STBIR__DEBUG_ASSERT(memcmp(overwrite_output_before_pre, &((unsigned char*)output_data)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE) == 0);
+ STBIR__DEBUG_ASSERT(memcmp(overwrite_output_after_pre, &((unsigned char*)output_data)[begin_forbidden], OVERWRITE_ARRAY_SIZE) == 0);
+ STBIR__DEBUG_ASSERT(memcmp(overwrite_tempmem_before_pre, &((unsigned char*)tempmem)[-OVERWRITE_ARRAY_SIZE], OVERWRITE_ARRAY_SIZE) == 0);
+ STBIR__DEBUG_ASSERT(memcmp(overwrite_tempmem_after_pre, &((unsigned char*)tempmem)[tempmem_size_in_bytes], OVERWRITE_ARRAY_SIZE) == 0);
+#endif
+
+ return 1;
+}
+
+
+static int stbir__resize_arbitrary(
+ void *alloc_context,
+ const void* input_data, int input_w, int input_h, int input_stride_in_bytes,
+ void* output_data, int output_w, int output_h, int output_stride_in_bytes,
+ float s0, float t0, float s1, float t1, float *transform,
+ int channels, int alpha_channel, stbir_uint32 flags, stbir_datatype type,
+ stbir_filter h_filter, stbir_filter v_filter,
+ stbir_edge edge_horizontal, stbir_edge edge_vertical, stbir_colorspace colorspace)
+{
+ stbir__info info;
+ int result;
+ size_t memory_required;
+ void* extra_memory;
+
+ stbir__setup(&info, input_w, input_h, output_w, output_h, channels);
+ stbir__calculate_transform(&info, s0,t0,s1,t1,transform);
+ stbir__choose_filter(&info, h_filter, v_filter);
+ memory_required = stbir__calculate_memory(&info);
+ extra_memory = STBIR_MALLOC(memory_required, alloc_context);
+
+ if (!extra_memory)
+ return 0;
+
+ result = stbir__resize_allocated(&info, input_data, input_stride_in_bytes,
+ output_data, output_stride_in_bytes,
+ alpha_channel, flags, type,
+ edge_horizontal, edge_vertical,
+ colorspace, extra_memory, memory_required);
+
+ STBIR_FREE(extra_memory, alloc_context);
+
+ return result;
+}
+
+STBIRDEF int stbir_resize_uint8( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ int num_channels)
+{
+ return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes,
+ output_pixels, output_w, output_h, output_stride_in_bytes,
+ 0,0,1,1,NULL,num_channels,-1,0, STBIR_TYPE_UINT8, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT,
+ STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_COLORSPACE_LINEAR);
+}
+
+STBIRDEF int stbir_resize_float( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ float *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ int num_channels)
+{
+ return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes,
+ output_pixels, output_w, output_h, output_stride_in_bytes,
+ 0,0,1,1,NULL,num_channels,-1,0, STBIR_TYPE_FLOAT, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT,
+ STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_COLORSPACE_LINEAR);
+}
+
+STBIRDEF int stbir_resize_uint8_srgb(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ int num_channels, int alpha_channel, int flags)
+{
+ return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes,
+ output_pixels, output_w, output_h, output_stride_in_bytes,
+ 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT8, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT,
+ STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP, STBIR_COLORSPACE_SRGB);
+}
+
+STBIRDEF int stbir_resize_uint8_srgb_edgemode(const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ int num_channels, int alpha_channel, int flags,
+ stbir_edge edge_wrap_mode)
+{
+ return stbir__resize_arbitrary(NULL, input_pixels, input_w, input_h, input_stride_in_bytes,
+ output_pixels, output_w, output_h, output_stride_in_bytes,
+ 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT8, STBIR_FILTER_DEFAULT, STBIR_FILTER_DEFAULT,
+ edge_wrap_mode, edge_wrap_mode, STBIR_COLORSPACE_SRGB);
+}
+
+STBIRDEF int stbir_resize_uint8_generic( const unsigned char *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ unsigned char *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ int num_channels, int alpha_channel, int flags,
+ stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space,
+ void *alloc_context)
+{
+ return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes,
+ output_pixels, output_w, output_h, output_stride_in_bytes,
+ 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT8, filter, filter,
+ edge_wrap_mode, edge_wrap_mode, space);
+}
+
+STBIRDEF int stbir_resize_uint16_generic(const stbir_uint16 *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ stbir_uint16 *output_pixels , int output_w, int output_h, int output_stride_in_bytes,
+ int num_channels, int alpha_channel, int flags,
+ stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space,
+ void *alloc_context)
+{
+ return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes,
+ output_pixels, output_w, output_h, output_stride_in_bytes,
+ 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_UINT16, filter, filter,
+ edge_wrap_mode, edge_wrap_mode, space);
+}
+
+
+STBIRDEF int stbir_resize_float_generic( const float *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ float *output_pixels , int output_w, int output_h, int output_stride_in_bytes,
+ int num_channels, int alpha_channel, int flags,
+ stbir_edge edge_wrap_mode, stbir_filter filter, stbir_colorspace space,
+ void *alloc_context)
+{
+ return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes,
+ output_pixels, output_w, output_h, output_stride_in_bytes,
+ 0,0,1,1,NULL,num_channels,alpha_channel,flags, STBIR_TYPE_FLOAT, filter, filter,
+ edge_wrap_mode, edge_wrap_mode, space);
+}
+
+
+STBIRDEF int stbir_resize( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ void *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ stbir_datatype datatype,
+ int num_channels, int alpha_channel, int flags,
+ stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical,
+ stbir_filter filter_horizontal, stbir_filter filter_vertical,
+ stbir_colorspace space, void *alloc_context)
+{
+ return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes,
+ output_pixels, output_w, output_h, output_stride_in_bytes,
+ 0,0,1,1,NULL,num_channels,alpha_channel,flags, datatype, filter_horizontal, filter_vertical,
+ edge_mode_horizontal, edge_mode_vertical, space);
+}
+
+
+STBIRDEF int stbir_resize_subpixel(const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ void *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ stbir_datatype datatype,
+ int num_channels, int alpha_channel, int flags,
+ stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical,
+ stbir_filter filter_horizontal, stbir_filter filter_vertical,
+ stbir_colorspace space, void *alloc_context,
+ float x_scale, float y_scale,
+ float x_offset, float y_offset)
+{
+ float transform[4];
+ transform[0] = x_scale;
+ transform[1] = y_scale;
+ transform[2] = x_offset;
+ transform[3] = y_offset;
+ return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes,
+ output_pixels, output_w, output_h, output_stride_in_bytes,
+ 0,0,1,1,transform,num_channels,alpha_channel,flags, datatype, filter_horizontal, filter_vertical,
+ edge_mode_horizontal, edge_mode_vertical, space);
+}
+
+STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int input_h , int input_stride_in_bytes,
+ void *output_pixels, int output_w, int output_h, int output_stride_in_bytes,
+ stbir_datatype datatype,
+ int num_channels, int alpha_channel, int flags,
+ stbir_edge edge_mode_horizontal, stbir_edge edge_mode_vertical,
+ stbir_filter filter_horizontal, stbir_filter filter_vertical,
+ stbir_colorspace space, void *alloc_context,
+ float s0, float t0, float s1, float t1)
+{
+ return stbir__resize_arbitrary(alloc_context, input_pixels, input_w, input_h, input_stride_in_bytes,
+ output_pixels, output_w, output_h, output_stride_in_bytes,
+ s0,t0,s1,t1,NULL,num_channels,alpha_channel,flags, datatype, filter_horizontal, filter_vertical,
+ edge_mode_horizontal, edge_mode_vertical, space);
+}
+
+#endif // STB_IMAGE_RESIZE_IMPLEMENTATION
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image_write.h b/graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image_write.h
new file mode 100644
index 0000000000..4319c0de1d
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/common/stb_image_write.h
@@ -0,0 +1,1048 @@
+/* stb_image_write - v1.02 - public domain - http://nothings.org/stb/stb_image_write.h
+ writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010-2015
+ no warranty implied; use at your own risk
+
+ Before #including,
+
+ #define STB_IMAGE_WRITE_IMPLEMENTATION
+
+ in the file that you want to have the implementation.
+
+ Will probably not work correctly with strict-aliasing optimizations.
+
+ABOUT:
+
+ This header file is a library for writing images to C stdio. It could be
+ adapted to write to memory or a general streaming interface; let me know.
+
+ The PNG output is not optimal; it is 20-50% larger than the file
+ written by a decent optimizing implementation. This library is designed
+ for source code compactness and simplicity, not optimal image file size
+ or run-time performance.
+
+BUILDING:
+
+ You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h.
+ You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace
+ malloc,realloc,free.
+ You can define STBIW_MEMMOVE() to replace memmove()
+
+USAGE:
+
+ There are four functions, one for each image file format:
+
+ int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
+ int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
+ int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
+ int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
+
+ There are also four equivalent functions that use an arbitrary write function. You are
+ expected to open/close your file-equivalent before and after calling these:
+
+ int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes);
+ int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
+ int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
+ int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
+
+ where the callback is:
+ void stbi_write_func(void *context, void *data, int size);
+
+ You can define STBI_WRITE_NO_STDIO to disable the file variant of these
+ functions, so the library will not use stdio.h at all. However, this will
+ also disable HDR writing, because it requires stdio for formatted output.
+
+ Each function returns 0 on failure and non-0 on success.
+
+ The functions create an image file defined by the parameters. The image
+ is a rectangle of pixels stored from left-to-right, top-to-bottom.
+ Each pixel contains 'comp' channels of data stored interleaved with 8-bits
+ per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is
+ monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall.
+ The *data pointer points to the first byte of the top-left-most pixel.
+ For PNG, "stride_in_bytes" is the distance in bytes from the first byte of
+ a row of pixels to the first byte of the next row of pixels.
+
+ PNG creates output files with the same number of components as the input.
+ The BMP format expands Y to RGB in the file format and does not
+ output alpha.
+
+ PNG supports writing rectangles of data even when the bytes storing rows of
+ data are not consecutive in memory (e.g. sub-rectangles of a larger image),
+ by supplying the stride between the beginning of adjacent rows. The other
+ formats do not. (Thus you cannot write a native-format BMP through the BMP
+ writer, both because it is in BGR order and because it may have padding
+ at the end of the line.)
+
+ HDR expects linear float data. Since the format is always 32-bit rgb(e)
+ data, alpha (if provided) is discarded, and for monochrome data it is
+ replicated across all three channels.
+
+ TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed
+ data, set the global variable 'stbi_write_tga_with_rle' to 0.
+
+CREDITS:
+
+ PNG/BMP/TGA
+ Sean Barrett
+ HDR
+ Baldur Karlsson
+ TGA monochrome:
+ Jean-Sebastien Guay
+ misc enhancements:
+ Tim Kelsey
+ TGA RLE
+ Alan Hickman
+ initial file IO callback implementation
+ Emmanuel Julien
+ bugfixes:
+ github:Chribba
+ Guillaume Chereau
+ github:jry2
+ github:romigrou
+ Sergio Gonzalez
+ Jonas Karlsson
+ Filip Wasil
+ Thatcher Ulrich
+
+LICENSE
+
+This software is dual-licensed to the public domain and under the following
+license: you are granted a perpetual, irrevocable license to copy, modify,
+publish, and distribute this file as you see fit.
+
+*/
+
+#ifndef INCLUDE_STB_IMAGE_WRITE_H
+#define INCLUDE_STB_IMAGE_WRITE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef STB_IMAGE_WRITE_STATIC
+#define STBIWDEF static
+#else
+#define STBIWDEF extern
+extern int stbi_write_tga_with_rle;
+#endif
+
+#ifndef STBI_WRITE_NO_STDIO
+STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
+STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
+STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
+STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
+#endif
+
+typedef void stbi_write_func(void *context, void *data, int size);
+
+STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes);
+STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
+STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data);
+STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif//INCLUDE_STB_IMAGE_WRITE_H
+
+#ifdef STB_IMAGE_WRITE_IMPLEMENTATION
+
+#ifdef _WIN32
+ #ifndef _CRT_SECURE_NO_WARNINGS
+ #define _CRT_SECURE_NO_WARNINGS
+ #endif
+ #ifndef _CRT_NONSTDC_NO_DEPRECATE
+ #define _CRT_NONSTDC_NO_DEPRECATE
+ #endif
+#endif
+
+#ifndef STBI_WRITE_NO_STDIO
+#include <stdio.h>
+#endif // STBI_WRITE_NO_STDIO
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED))
+// ok
+#elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED)
+// ok
+#else
+#error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)."
+#endif
+
+#ifndef STBIW_MALLOC
+#define STBIW_MALLOC(sz) malloc(sz)
+#define STBIW_REALLOC(p,newsz) realloc(p,newsz)
+#define STBIW_FREE(p) free(p)
+#endif
+
+#ifndef STBIW_REALLOC_SIZED
+#define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz)
+#endif
+
+
+#ifndef STBIW_MEMMOVE
+#define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz)
+#endif
+
+
+#ifndef STBIW_ASSERT
+#include <assert.h>
+#define STBIW_ASSERT(x) assert(x)
+#endif
+
+#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
+
+typedef struct
+{
+ stbi_write_func *func;
+ void *context;
+} stbi__write_context;
+
+// initialize a callback-based context
+static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context)
+{
+ s->func = c;
+ s->context = context;
+}
+
+#ifndef STBI_WRITE_NO_STDIO
+
+static void stbi__stdio_write(void *context, void *data, int size)
+{
+ fwrite(data,1,size,(FILE*) context);
+}
+
+static int stbi__start_write_file(stbi__write_context *s, const char *filename)
+{
+ FILE *f = fopen(filename, "wb");
+ stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f);
+ return f != NULL;
+}
+
+static void stbi__end_write_file(stbi__write_context *s)
+{
+ fclose((FILE *)s->context);
+}
+
+#endif // !STBI_WRITE_NO_STDIO
+
+typedef unsigned int stbiw_uint32;
+typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
+
+#ifdef STB_IMAGE_WRITE_STATIC
+static int stbi_write_tga_with_rle = 1;
+#else
+int stbi_write_tga_with_rle = 1;
+#endif
+
+static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v)
+{
+ while (*fmt) {
+ switch (*fmt++) {
+ case ' ': break;
+ case '1': { unsigned char x = STBIW_UCHAR(va_arg(v, int));
+ s->func(s->context,&x,1);
+ break; }
+ case '2': { int x = va_arg(v,int);
+ unsigned char b[2];
+ b[0] = STBIW_UCHAR(x);
+ b[1] = STBIW_UCHAR(x>>8);
+ s->func(s->context,b,2);
+ break; }
+ case '4': { stbiw_uint32 x = va_arg(v,int);
+ unsigned char b[4];
+ b[0]=STBIW_UCHAR(x);
+ b[1]=STBIW_UCHAR(x>>8);
+ b[2]=STBIW_UCHAR(x>>16);
+ b[3]=STBIW_UCHAR(x>>24);
+ s->func(s->context,b,4);
+ break; }
+ default:
+ STBIW_ASSERT(0);
+ return;
+ }
+ }
+}
+
+static void stbiw__writef(stbi__write_context *s, const char *fmt, ...)
+{
+ va_list v;
+ va_start(v, fmt);
+ stbiw__writefv(s, fmt, v);
+ va_end(v);
+}
+
+static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
+{
+ unsigned char arr[3];
+ arr[0] = a, arr[1] = b, arr[2] = c;
+ s->func(s->context, arr, 3);
+}
+
+static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d)
+{
+ unsigned char bg[3] = { 255, 0, 255}, px[3];
+ int k;
+
+ if (write_alpha < 0)
+ s->func(s->context, &d[comp - 1], 1);
+
+ switch (comp) {
+ case 1:
+ s->func(s->context,d,1);
+ break;
+ case 2:
+ if (expand_mono)
+ stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp
+ else
+ s->func(s->context, d, 1); // monochrome TGA
+ break;
+ case 4:
+ if (!write_alpha) {
+ // composite against pink background
+ for (k = 0; k < 3; ++k)
+ px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255;
+ stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]);
+ break;
+ }
+ /* FALLTHROUGH */
+ case 3:
+ stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]);
+ break;
+ }
+ if (write_alpha > 0)
+ s->func(s->context, &d[comp - 1], 1);
+}
+
+static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono)
+{
+ stbiw_uint32 zero = 0;
+ int i,j, j_end;
+
+ if (y <= 0)
+ return;
+
+ if (vdir < 0)
+ j_end = -1, j = y-1;
+ else
+ j_end = y, j = 0;
+
+ for (; j != j_end; j += vdir) {
+ for (i=0; i < x; ++i) {
+ unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
+ stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d);
+ }
+ s->func(s->context, &zero, scanline_pad);
+ }
+}
+
+static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...)
+{
+ if (y < 0 || x < 0) {
+ return 0;
+ } else {
+ va_list v;
+ va_start(v, fmt);
+ stbiw__writefv(s, fmt, v);
+ va_end(v);
+ stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono);
+ return 1;
+ }
+}
+
+static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data)
+{
+ int pad = (-x*3) & 3;
+ return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad,
+ "11 4 22 4" "4 44 22 444444",
+ 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
+ 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
+}
+
+STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
+{
+ stbi__write_context s;
+ stbi__start_write_callbacks(&s, func, context);
+ return stbi_write_bmp_core(&s, x, y, comp, data);
+}
+
+#ifndef STBI_WRITE_NO_STDIO
+STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
+{
+ stbi__write_context s;
+ if (stbi__start_write_file(&s,filename)) {
+ int r = stbi_write_bmp_core(&s, x, y, comp, data);
+ stbi__end_write_file(&s);
+ return r;
+ } else
+ return 0;
+}
+#endif //!STBI_WRITE_NO_STDIO
+
+static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data)
+{
+ int has_alpha = (comp == 2 || comp == 4);
+ int colorbytes = has_alpha ? comp-1 : comp;
+ int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3
+
+ if (y < 0 || x < 0)
+ return 0;
+
+ if (!stbi_write_tga_with_rle) {
+ return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *) data, has_alpha, 0,
+ "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8);
+ } else {
+ int i,j,k;
+
+ stbiw__writef(s, "111 221 2222 11", 0,0,format+8, 0,0,0, 0,0,x,y, (colorbytes + has_alpha) * 8, has_alpha * 8);
+
+ for (j = y - 1; j >= 0; --j) {
+ unsigned char *row = (unsigned char *) data + j * x * comp;
+ int len;
+
+ for (i = 0; i < x; i += len) {
+ unsigned char *begin = row + i * comp;
+ int diff = 1;
+ len = 1;
+
+ if (i < x - 1) {
+ ++len;
+ diff = memcmp(begin, row + (i + 1) * comp, comp);
+ if (diff) {
+ const unsigned char *prev = begin;
+ for (k = i + 2; k < x && len < 128; ++k) {
+ if (memcmp(prev, row + k * comp, comp)) {
+ prev += comp;
+ ++len;
+ } else {
+ --len;
+ break;
+ }
+ }
+ } else {
+ for (k = i + 2; k < x && len < 128; ++k) {
+ if (!memcmp(begin, row + k * comp, comp)) {
+ ++len;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ if (diff) {
+ unsigned char header = STBIW_UCHAR(len - 1);
+ s->func(s->context, &header, 1);
+ for (k = 0; k < len; ++k) {
+ stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp);
+ }
+ } else {
+ unsigned char header = STBIW_UCHAR(len - 129);
+ s->func(s->context, &header, 1);
+ stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin);
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
+{
+ stbi__write_context s;
+ stbi__start_write_callbacks(&s, func, context);
+ return stbi_write_tga_core(&s, x, y, comp, (void *) data);
+}
+
+#ifndef STBI_WRITE_NO_STDIO
+int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
+{
+ stbi__write_context s;
+ if (stbi__start_write_file(&s,filename)) {
+ int r = stbi_write_tga_core(&s, x, y, comp, (void *) data);
+ stbi__end_write_file(&s);
+ return r;
+ } else
+ return 0;
+}
+#endif
+
+// *************************************************************************************************
+// Radiance RGBE HDR writer
+// by Baldur Karlsson
+#ifndef STBI_WRITE_NO_STDIO
+
+#define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
+
+void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
+{
+ int exponent;
+ float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
+
+ if (maxcomp < 1e-32f) {
+ rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
+ } else {
+ float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp;
+
+ rgbe[0] = (unsigned char)(linear[0] * normalize);
+ rgbe[1] = (unsigned char)(linear[1] * normalize);
+ rgbe[2] = (unsigned char)(linear[2] * normalize);
+ rgbe[3] = (unsigned char)(exponent + 128);
+ }
+}
+
+void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
+{
+ unsigned char lengthbyte = STBIW_UCHAR(length+128);
+ STBIW_ASSERT(length+128 <= 255);
+ s->func(s->context, &lengthbyte, 1);
+ s->func(s->context, &databyte, 1);
+}
+
+void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
+{
+ unsigned char lengthbyte = STBIW_UCHAR(length);
+ STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
+ s->func(s->context, &lengthbyte, 1);
+ s->func(s->context, data, length);
+}
+
+void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
+{
+ unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
+ unsigned char rgbe[4];
+ float linear[3];
+ int x;
+
+ scanlineheader[2] = (width&0xff00)>>8;
+ scanlineheader[3] = (width&0x00ff);
+
+ /* skip RLE for images too small or large */
+ if (width < 8 || width >= 32768) {
+ for (x=0; x < width; x++) {
+ switch (ncomp) {
+ case 4: /* fallthrough */
+ case 3: linear[2] = scanline[x*ncomp + 2];
+ linear[1] = scanline[x*ncomp + 1];
+ linear[0] = scanline[x*ncomp + 0];
+ break;
+ default:
+ linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
+ break;
+ }
+ stbiw__linear_to_rgbe(rgbe, linear);
+ s->func(s->context, rgbe, 4);
+ }
+ } else {
+ int c,r;
+ /* encode into scratch buffer */
+ for (x=0; x < width; x++) {
+ switch(ncomp) {
+ case 4: /* fallthrough */
+ case 3: linear[2] = scanline[x*ncomp + 2];
+ linear[1] = scanline[x*ncomp + 1];
+ linear[0] = scanline[x*ncomp + 0];
+ break;
+ default:
+ linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0];
+ break;
+ }
+ stbiw__linear_to_rgbe(rgbe, linear);
+ scratch[x + width*0] = rgbe[0];
+ scratch[x + width*1] = rgbe[1];
+ scratch[x + width*2] = rgbe[2];
+ scratch[x + width*3] = rgbe[3];
+ }
+
+ s->func(s->context, scanlineheader, 4);
+
+ /* RLE each component separately */
+ for (c=0; c < 4; c++) {
+ unsigned char *comp = &scratch[width*c];
+
+ x = 0;
+ while (x < width) {
+ // find first run
+ r = x;
+ while (r+2 < width) {
+ if (comp[r] == comp[r+1] && comp[r] == comp[r+2])
+ break;
+ ++r;
+ }
+ if (r+2 >= width)
+ r = width;
+ // dump up to first run
+ while (x < r) {
+ int len = r-x;
+ if (len > 128) len = 128;
+ stbiw__write_dump_data(s, len, &comp[x]);
+ x += len;
+ }
+ // if there's a run, output it
+ if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd
+ // find next byte after run
+ while (r < width && comp[r] == comp[x])
+ ++r;
+ // output run up to r
+ while (x < r) {
+ int len = r-x;
+ if (len > 127) len = 127;
+ stbiw__write_run_data(s, len, comp[x]);
+ x += len;
+ }
+ }
+ }
+ }
+ }
+}
+
+static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data)
+{
+ if (y <= 0 || x <= 0 || data == NULL)
+ return 0;
+ else {
+ // Each component is stored separately. Allocate scratch space for full output scanline.
+ unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4);
+ int i, len;
+ char buffer[128];
+ char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
+ s->func(s->context, header, sizeof(header)-1);
+
+ len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
+ s->func(s->context, buffer, len);
+
+ for(i=0; i < y; i++)
+ stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*i*x);
+ STBIW_FREE(scratch);
+ return 1;
+ }
+}
+
+int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data)
+{
+ stbi__write_context s;
+ stbi__start_write_callbacks(&s, func, context);
+ return stbi_write_hdr_core(&s, x, y, comp, (float *) data);
+}
+
+int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
+{
+ stbi__write_context s;
+ if (stbi__start_write_file(&s,filename)) {
+ int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data);
+ stbi__end_write_file(&s);
+ return r;
+ } else
+ return 0;
+}
+#endif // STBI_WRITE_NO_STDIO
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// PNG writer
+//
+
+// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
+#define stbiw__sbraw(a) ((int *) (a) - 2)
+#define stbiw__sbm(a) stbiw__sbraw(a)[0]
+#define stbiw__sbn(a) stbiw__sbraw(a)[1]
+
+#define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a))
+#define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0)
+#define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a)))
+
+#define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v))
+#define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0)
+#define stbiw__sbfree(a) ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0)
+
+static void *stbiw__sbgrowf(void **arr, int increment, int itemsize)
+{
+ int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1;
+ void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2);
+ STBIW_ASSERT(p);
+ if (p) {
+ if (!*arr) ((int *) p)[1] = 0;
+ *arr = (void *) ((int *) p + 2);
+ stbiw__sbm(*arr) = m;
+ }
+ return *arr;
+}
+
+static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
+{
+ while (*bitcount >= 8) {
+ stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer));
+ *bitbuffer >>= 8;
+ *bitcount -= 8;
+ }
+ return data;
+}
+
+static int stbiw__zlib_bitrev(int code, int codebits)
+{
+ int res=0;
+ while (codebits--) {
+ res = (res << 1) | (code & 1);
+ code >>= 1;
+ }
+ return res;
+}
+
+static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit)
+{
+ int i;
+ for (i=0; i < limit && i < 258; ++i)
+ if (a[i] != b[i]) break;
+ return i;
+}
+
+static unsigned int stbiw__zhash(unsigned char *data)
+{
+ stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
+ hash ^= hash << 3;
+ hash += hash >> 5;
+ hash ^= hash << 4;
+ hash += hash >> 17;
+ hash ^= hash << 25;
+ hash += hash >> 6;
+ return hash;
+}
+
+#define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount))
+#define stbiw__zlib_add(code,codebits) \
+ (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush())
+#define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c)
+// default huffman tables
+#define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8)
+#define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9)
+#define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7)
+#define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8)
+#define stbiw__zlib_huff(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : (n) <= 255 ? stbiw__zlib_huff2(n) : (n) <= 279 ? stbiw__zlib_huff3(n) : stbiw__zlib_huff4(n))
+#define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n))
+
+#define stbiw__ZHASH 16384
+
+unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
+{
+ static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 };
+ static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 };
+ static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 };
+ static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 };
+ unsigned int bitbuf=0;
+ int i,j, bitcount=0;
+ unsigned char *out = NULL;
+ unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**));
+ if (quality < 5) quality = 5;
+
+ stbiw__sbpush(out, 0x78); // DEFLATE 32K window
+ stbiw__sbpush(out, 0x5e); // FLEVEL = 1
+ stbiw__zlib_add(1,1); // BFINAL = 1
+ stbiw__zlib_add(1,2); // BTYPE = 1 -- fixed huffman
+
+ for (i=0; i < stbiw__ZHASH; ++i)
+ hash_table[i] = NULL;
+
+ i=0;
+ while (i < data_len-3) {
+ // hash next 3 bytes of data to be compressed
+ int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3;
+ unsigned char *bestloc = 0;
+ unsigned char **hlist = hash_table[h];
+ int n = stbiw__sbcount(hlist);
+ for (j=0; j < n; ++j) {
+ if (hlist[j]-data > i-32768) { // if entry lies within window
+ int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
+ if (d >= best) best=d,bestloc=hlist[j];
+ }
+ }
+ // when hash table entry is too long, delete half the entries
+ if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) {
+ STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
+ stbiw__sbn(hash_table[h]) = quality;
+ }
+ stbiw__sbpush(hash_table[h],data+i);
+
+ if (bestloc) {
+ // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
+ h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1);
+ hlist = hash_table[h];
+ n = stbiw__sbcount(hlist);
+ for (j=0; j < n; ++j) {
+ if (hlist[j]-data > i-32767) {
+ int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1);
+ if (e > best) { // if next match is better, bail on current match
+ bestloc = NULL;
+ break;
+ }
+ }
+ }
+ }
+
+ if (bestloc) {
+ int d = (int) (data+i - bestloc); // distance back
+ STBIW_ASSERT(d <= 32767 && best <= 258);
+ for (j=0; best > lengthc[j+1]-1; ++j);
+ stbiw__zlib_huff(j+257);
+ if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]);
+ for (j=0; d > distc[j+1]-1; ++j);
+ stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5);
+ if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]);
+ i += best;
+ } else {
+ stbiw__zlib_huffb(data[i]);
+ ++i;
+ }
+ }
+ // write out final bytes
+ for (;i < data_len; ++i)
+ stbiw__zlib_huffb(data[i]);
+ stbiw__zlib_huff(256); // end of block
+ // pad with 0 bits to byte boundary
+ while (bitcount)
+ stbiw__zlib_add(0,1);
+
+ for (i=0; i < stbiw__ZHASH; ++i)
+ (void) stbiw__sbfree(hash_table[i]);
+ STBIW_FREE(hash_table);
+
+ {
+ // compute adler32 on input
+ unsigned int s1=1, s2=0;
+ int blocklen = (int) (data_len % 5552);
+ j=0;
+ while (j < data_len) {
+ for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
+ s1 %= 65521, s2 %= 65521;
+ j += blocklen;
+ blocklen = 5552;
+ }
+ stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8));
+ stbiw__sbpush(out, STBIW_UCHAR(s2));
+ stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8));
+ stbiw__sbpush(out, STBIW_UCHAR(s1));
+ }
+ *out_len = stbiw__sbn(out);
+ // make returned pointer freeable
+ STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len);
+ return (unsigned char *) stbiw__sbraw(out);
+}
+
+static unsigned int stbiw__crc32(unsigned char *buffer, int len)
+{
+ static unsigned int crc_table[256] =
+ {
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+ 0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+ };
+
+ unsigned int crc = ~0u;
+ int i;
+ for (i=0; i < len; ++i)
+ crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
+ return ~crc;
+}
+
+#define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4)
+#define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
+#define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3])
+
+static void stbiw__wpcrc(unsigned char **data, int len)
+{
+ unsigned int crc = stbiw__crc32(*data - len - 4, len+4);
+ stbiw__wp32(*data, crc);
+}
+
+static unsigned char stbiw__paeth(int a, int b, int c)
+{
+ int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
+ if (pa <= pb && pa <= pc) return STBIW_UCHAR(a);
+ if (pb <= pc) return STBIW_UCHAR(b);
+ return STBIW_UCHAR(c);
+}
+
+unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
+{
+ int ctype[5] = { -1, 0, 4, 2, 6 };
+ unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
+ unsigned char *out,*o, *filt, *zlib;
+ signed char *line_buffer;
+ int i,j,k,p,zlen;
+
+ if (stride_bytes == 0)
+ stride_bytes = x * n;
+
+ filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0;
+ line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; }
+ for (j=0; j < y; ++j) {
+ static int mapping[] = { 0,1,2,3,4 };
+ static int firstmap[] = { 0,1,0,5,6 };
+ int *mymap = j ? mapping : firstmap;
+ int best = 0, bestval = 0x7fffffff;
+ for (p=0; p < 2; ++p) {
+ for (k= p?best:0; k < 5; ++k) {
+ int type = mymap[k],est=0;
+ unsigned char *z = pixels + stride_bytes*j;
+ for (i=0; i < n; ++i)
+ switch (type) {
+ case 0: line_buffer[i] = z[i]; break;
+ case 1: line_buffer[i] = z[i]; break;
+ case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
+ case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
+ case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break;
+ case 5: line_buffer[i] = z[i]; break;
+ case 6: line_buffer[i] = z[i]; break;
+ }
+ for (i=n; i < x*n; ++i) {
+ switch (type) {
+ case 0: line_buffer[i] = z[i]; break;
+ case 1: line_buffer[i] = z[i] - z[i-n]; break;
+ case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
+ case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
+ case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
+ case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
+ case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
+ }
+ }
+ if (p) break;
+ for (i=0; i < x*n; ++i)
+ est += abs((signed char) line_buffer[i]);
+ if (est < bestval) { bestval = est; best = k; }
+ }
+ }
+ // when we get here, best contains the filter type, and line_buffer contains the data
+ filt[j*(x*n+1)] = (unsigned char) best;
+ STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n);
+ }
+ STBIW_FREE(line_buffer);
+ zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory
+ STBIW_FREE(filt);
+ if (!zlib) return 0;
+
+ // each tag requires 12 bytes of overhead
+ out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12);
+ if (!out) return 0;
+ *out_len = 8 + 12+13 + 12+zlen + 12;
+
+ o=out;
+ STBIW_MEMMOVE(o,sig,8); o+= 8;
+ stbiw__wp32(o, 13); // header length
+ stbiw__wptag(o, "IHDR");
+ stbiw__wp32(o, x);
+ stbiw__wp32(o, y);
+ *o++ = 8;
+ *o++ = STBIW_UCHAR(ctype[n]);
+ *o++ = 0;
+ *o++ = 0;
+ *o++ = 0;
+ stbiw__wpcrc(&o,13);
+
+ stbiw__wp32(o, zlen);
+ stbiw__wptag(o, "IDAT");
+ STBIW_MEMMOVE(o, zlib, zlen);
+ o += zlen;
+ STBIW_FREE(zlib);
+ stbiw__wpcrc(&o, zlen);
+
+ stbiw__wp32(o,0);
+ stbiw__wptag(o, "IEND");
+ stbiw__wpcrc(&o,0);
+
+ STBIW_ASSERT(o == out + *out_len);
+
+ return out;
+}
+
+#ifndef STBI_WRITE_NO_STDIO
+STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)
+{
+ FILE *f;
+ int len;
+ unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
+ if (png == NULL) return 0;
+ f = fopen(filename, "wb");
+ if (!f) { STBIW_FREE(png); return 0; }
+ fwrite(png, 1, len, f);
+ fclose(f);
+ STBIW_FREE(png);
+ return 1;
+}
+#endif
+
+STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes)
+{
+ int len;
+ unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
+ if (png == NULL) return 0;
+ func(context, png, len);
+ STBIW_FREE(png);
+ return 1;
+}
+
+#endif // STB_IMAGE_WRITE_IMPLEMENTATION
+
+/* Revision history
+ 1.02 (2016-04-02)
+ avoid allocating large structures on the stack
+ 1.01 (2016-01-16)
+ STBIW_REALLOC_SIZED: support allocators with no realloc support
+ avoid race-condition in crc initialization
+ minor compile issues
+ 1.00 (2015-09-14)
+ installable file IO function
+ 0.99 (2015-09-13)
+ warning fixes; TGA rle support
+ 0.98 (2015-04-08)
+ added STBIW_MALLOC, STBIW_ASSERT etc
+ 0.97 (2015-01-18)
+ fixed HDR asserts, rewrote HDR rle logic
+ 0.96 (2015-01-17)
+ add HDR output
+ fix monochrome BMP
+ 0.95 (2014-08-17)
+ add monochrome TGA output
+ 0.94 (2014-05-31)
+ rename private functions to avoid conflicts with stb_image.h
+ 0.93 (2014-05-27)
+ warning fixes
+ 0.92 (2010-08-01)
+ casts to unsigned char to fix warnings
+ 0.91 (2010-07-17)
+ first public release
+ 0.90 first internal release
+*/
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/Makefile b/graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/Makefile
new file mode 100644
index 0000000000..6868dd9ac6
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/Makefile
@@ -0,0 +1,28 @@
+INC_DIR = -I../../ -I../common -I ../../deps/miniz
+
+INCLUDES := ../../tinyexr.h
+OBJS := miniz.o tinyexr.o cube2longlat.o
+
+CFLAGS := -fsanitize=address -O2
+CXXFLAGS := $(CFLAGS) -std=c++11
+LDFLAGS := -fsanitize=address
+
+TARGET=cube2longlat
+
+all: $(TARGET)
+
+$(TARGET): $(OBJS)
+ $(CXX) -o $(TARGET) $(LDFLAGS) $(OBJS)
+
+miniz.o: ../../deps/miniz/miniz.c
+ $(CC) $(CFLAGS) -c $(INC_DIR) $<
+
+tinyexr.o: ../../tinyexr.cc
+ $(CXX) $(CXXFLAGS) -c $(INC_DIR) $<
+
+cube2longlat.o: cube2longlat.cc
+ $(CXX) $(CXXFLAGS) -c $(INC_DIR) $<
+
+.PHONY: clean
+clean:
+ rm -rf $(TARGET) $(OBJS)
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/README.md b/graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/README.md
new file mode 100644
index 0000000000..06a9e3c0ac
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/README.md
@@ -0,0 +1,46 @@
+# Simple HDR cubemap to longlat(longitude latitude. or known as equirectangular) converter.
+
+## Requirements
+
+* C++11 compiler
+
+## Coordinate definition.
+
+* Y-up
+* Right-handed
+* Center is -z
+
+## Usage
+
+Assume cubemap image is given by 6 images(6 faces).
+
+```
+$ ./cube2longlat px.exr nx.exr py.exr ny.exr pz.exr nz.exr 512 longlat.exr (phi_offset)
+```
+
+Optional `phi_offset` is used to add offset(by angle) to phi to rotate X and Z faces.
+
+
+## Supported input image format
+
+* [ ] RGBM(Filament's RGBM encoding. Multiplier is 16, and gamma corrected) Implemented but not tested.
+* [x] EXR
+
+## Supported output image format
+
+* [ ] RGBM(Filament's RGBM encoding. Multiplier is 16, and gamma corrected) Implemented but not tested.
+* [x] EXR
+* [x] RGBE
+
+## Note
+
+When you create cubemap using Filament's cmgen https://github.com/google/filament/tree/master/tools/cmgen , its generated cubemap images are mirrored by X direction.
+Use `--mirror` when invoking `cmgen` if required.
+
+## TODO
+
+* Single cubemap image(cross layout)
+* Better antialiasing
+* theta offset
+* Mirroring.
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/cube2longlat.cc b/graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/cube2longlat.cc
new file mode 100644
index 0000000000..5a389c18cf
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/cube2longlat/cube2longlat.cc
@@ -0,0 +1,470 @@
+#include "tinyexr.h"
+
+#define STB_IMAGE_IMPLEMENTATION
+#include "stb_image.h"
+
+#define STB_IMAGE_WRITE_IMPLEMENTATION
+#include "stb_image_write.h"
+
+#include <array>
+#include <cmath>
+#include <iostream>
+#include <string>
+#include <vector>
+
+// From Filament.
+static inline void RGBMtoLinear(const float rgbm[4], float linear[3]) {
+ linear[0] = rgbm[0] * rgbm[3] * 16.0f;
+ linear[1] = rgbm[1] * rgbm[3] * 16.0f;
+ linear[2] = rgbm[2] * rgbm[3] * 16.0f;
+
+ // Gamma to linear space
+ linear[0] = linear[0] * linear[0];
+ linear[1] = linear[1] * linear[1];
+ linear[2] = linear[2] * linear[2];
+}
+
+static inline void LinearToRGBM(const float linear[3], float rgbm[4]) {
+ rgbm[0] = linear[0];
+ rgbm[1] = linear[1];
+ rgbm[2] = linear[2];
+ rgbm[3] = 1.0f;
+
+ // Linear to gamma space
+ rgbm[0] = rgbm[0] * rgbm[0];
+ rgbm[1] = rgbm[1] * rgbm[1];
+ rgbm[2] = rgbm[2] * rgbm[2];
+
+ // Set the range
+ rgbm[0] /= 16.0f;
+ rgbm[1] /= 16.0f;
+ rgbm[2] /= 16.0f;
+
+ float maxComponent =
+ std::max(std::max(rgbm[0], rgbm[1]), std::max(rgbm[2], 1e-6f));
+ // Don't let M go below 1 in the [0..16] range
+ rgbm[3] = std::max(1.0f / 16.0f, std::min(maxComponent, 1.0f));
+ rgbm[3] = std::ceil(rgbm[3] * 255.0f) / 255.0f;
+
+ // saturate([0.0, 1.0])
+ rgbm[0] = std::max(0.0f, std::min(1.0f, rgbm[0] / rgbm[3]));
+ rgbm[1] = std::max(0.0f, std::min(1.0f, rgbm[1] / rgbm[3]));
+ rgbm[2] = std::max(0.0f, std::min(1.0f, rgbm[2] / rgbm[3]));
+}
+
+static std::string GetFileExtension(const std::string& filename) {
+ if (filename.find_last_of(".") != std::string::npos)
+ return filename.substr(filename.find_last_of(".") + 1);
+ return "";
+}
+
+struct Image {
+ int width;
+ int height;
+ std::vector<float> data;
+};
+
+static bool LoadCubemaps(const std::array<std::string, 6> face_filenames,
+ std::array<Image, 6>* output) {
+ for (size_t i = 0; i < 6; i++) {
+ std::string ext = GetFileExtension(face_filenames[i]);
+
+ Image image;
+
+ if ((ext.compare("exr") == 0) || (ext.compare("EXR") == 0)) {
+ int width, height;
+ float* rgba;
+ const char* err;
+
+ int ret =
+ LoadEXR(&rgba, &width, &height, face_filenames[i].c_str(), &err);
+ if (ret != 0) {
+ if (err) {
+ std::cerr << "EXR load error: " << err << std::endl;
+ } else {
+ std::cerr << "EXR load error: code " << ret << std::endl;
+ }
+ return false;
+ }
+
+ image.width = width;
+ image.height = height;
+ image.data.resize(width * height * 3);
+
+ // RGBA -> RGB
+ for (size_t j = 0; j < size_t(width * height); j++) {
+ image.data[3 * j + 0] = rgba[4 * j + 0];
+ image.data[3 * j + 1] = rgba[4 * j + 1];
+ image.data[3 * j + 2] = rgba[4 * j + 2];
+ }
+
+ free(rgba);
+
+ (*output)[i] = std::move(image);
+
+ } else if ((ext.compare("rgbm") == 0) || (ext.compare("RGBM") == 0)) {
+ int width, height;
+ int n;
+
+ unsigned char* data = stbi_load(face_filenames[i].c_str(), &width,
+ &height, &n, STBI_default);
+
+ if (!data) {
+ std::cerr << "Failed to load file: " << face_filenames[i] << std::endl;
+ return false;
+ }
+
+ if ((n != 4)) {
+ std::cerr << "Not a RGBM encoded image: " << face_filenames[i]
+ << std::endl;
+ return false;
+ }
+
+ image.width = width;
+ image.height = height;
+ image.data.resize(size_t(width * height));
+
+ for (size_t i = 0; i < size_t(width * height); i++) {
+ float rgbm[4];
+ // [0, 1.0]
+ rgbm[0] = data[4 * i + 0] / 255.0f;
+ rgbm[1] = data[4 * i + 1] / 255.0f;
+ rgbm[2] = data[4 * i + 2] / 255.0f;
+ rgbm[3] = data[4 * i + 3] / 255.0f;
+
+ float linear[3];
+ RGBMtoLinear(rgbm, linear);
+
+ image.data[3 * i + 0] = linear[0];
+ image.data[3 * i + 1] = linear[1];
+ image.data[3 * i + 2] = linear[2];
+ }
+
+ (*output)[i] = std::move(image);
+
+ } else {
+ std::cerr << "Unknown file extension : " << ext << std::endl;
+ return false;
+ }
+ std::cout << "Loaded " << face_filenames[i] << std::endl;
+ }
+
+ return true;
+}
+
+void convert_xyz_to_cube_uv(float x, float y, float z, int* index, float* u,
+ float* v) {
+ float absX = fabs(x);
+ float absY = fabs(y);
+ float absZ = fabs(z);
+
+ int isXPositive = x > 0.0f ? 1 : 0;
+ int isYPositive = y > 0.0f ? 1 : 0;
+ int isZPositive = z > 0.0f ? 1 : 0;
+
+ float maxAxis, uc, vc;
+
+ // POSITIVE X
+ if (isXPositive && absX >= absY && absX >= absZ) {
+ // u (0 to 1) goes from +z to -z
+ // v (0 to 1) goes from -y to +y
+ maxAxis = absX;
+ uc = -z;
+ vc = y;
+ *index = 0;
+ }
+ // NEGATIVE X
+ if (!isXPositive && absX >= absY && absX >= absZ) {
+ // u (0 to 1) goes from -z to +z
+ // v (0 to 1) goes from -y to +y
+ maxAxis = absX;
+ uc = z;
+ vc = y;
+ *index = 1;
+ }
+ // POSITIVE Y
+ if (isYPositive && absY >= absX && absY >= absZ) {
+ // u (0 to 1) goes from -x to +x
+ // v (0 to 1) goes from +z to -z
+ maxAxis = absY;
+ uc = x;
+ vc = -z;
+ *index = 2;
+ }
+ // NEGATIVE Y
+ if (!isYPositive && absY >= absX && absY >= absZ) {
+ // u (0 to 1) goes from -x to +x
+ // v (0 to 1) goes from -z to +z
+ maxAxis = absY;
+ uc = x;
+ vc = z;
+ *index = 3;
+ }
+ // POSITIVE Z
+ if (isZPositive && (absZ >= absX) && (absZ >= absY)) {
+ // u (0 to 1) goes from -x to +x
+ // v (0 to 1) goes from -y to +y
+ maxAxis = absZ;
+ uc = x;
+ vc = y;
+ *index = 4;
+ }
+ // NEGATIVE Z
+ if (!isZPositive && (absZ >= absX) && (absZ >= absY)) {
+ // u (0 to 1) goes from +x to -x
+ // v (0 to 1) goes from -y to +y
+ maxAxis = absZ;
+ uc = -x;
+ vc = y;
+ *index = 5;
+ }
+
+ // Convert range from -1 to 1 to 0 to 1
+ *u = 0.5f * (uc / maxAxis + 1.0f);
+ *v = 0.5f * (vc / maxAxis + 1.0f);
+}
+
+//
+// Simple bilinear texture filtering.
+//
+static void SampleTexture(float* rgba, float u, float v, int width, int height,
+ int channels, const float* texels) {
+ float sx = std::floor(u);
+ float sy = std::floor(v);
+
+ // Wrap mode = repeat
+ float uu = u - sx;
+ float vv = v - sy;
+
+ // clamp
+ uu = std::max(uu, 0.0f);
+ uu = std::min(uu, 1.0f);
+ vv = std::max(vv, 0.0f);
+ vv = std::min(vv, 1.0f);
+
+ float px = (width - 1) * uu;
+ float py = (height - 1) * vv;
+
+ int x0 = std::max(0, std::min((int)px, (width - 1)));
+ int y0 = std::max(0, std::min((int)py, (height - 1)));
+ int x1 = std::max(0, std::min((x0 + 1), (width - 1)));
+ int y1 = std::max(0, std::min((y0 + 1), (height - 1)));
+
+ float dx = px - (float)x0;
+ float dy = py - (float)y0;
+
+ float w[4];
+
+ w[0] = (1.0f - dx) * (1.0 - dy);
+ w[1] = (1.0f - dx) * (dy);
+ w[2] = (dx) * (1.0 - dy);
+ w[3] = (dx) * (dy);
+
+ int i00 = channels * (y0 * width + x0);
+ int i01 = channels * (y0 * width + x1);
+ int i10 = channels * (y1 * width + x0);
+ int i11 = channels * (y1 * width + x1);
+
+ for (int i = 0; i < channels; i++) {
+ rgba[i] = w[0] * texels[i00 + i] + w[1] * texels[i10 + i] +
+ w[2] * texels[i01 + i] + w[3] * texels[i11 + i];
+ }
+}
+
+static void SampleCubemap(const std::array<Image, 6>& cubemap_faces,
+ const float n[3], float col[3]) {
+ int face;
+ float u, v;
+ convert_xyz_to_cube_uv(n[0], n[1], n[2], &face, &u, &v);
+
+ v = 1.0f - v;
+
+ // std::cout << "face = " << face << std::endl;
+
+ // TODO(syoyo): Do we better consider seams on the cubemap face border?
+ const Image& tex = cubemap_faces[face];
+
+ // std::cout << "n = " << n[0] << ", " << n[1] << ", " << n[2] << ", uv = " <<
+ // u << ", " << v << std::endl;
+
+ SampleTexture(col, u, v, tex.width, tex.height, /* RGB */ 3, tex.data.data());
+
+// col[0] = u;
+// col[1] = v;
+// col[2] = 0.0f;
+#if 0
+ if (face == 0) {
+ col[0] = 1.0f;
+ col[1] = 0.0f;
+ col[2] = 0.0f;
+ } else if (face == 1) {
+ col[0] = 0.0f;
+ col[1] = 1.0f;
+ col[2] = 0.0f;
+ } else if (face == 2) {
+ col[0] = 0.0f;
+ col[1] = 0.0f;
+ col[2] = 1.0f;
+ } else if (face == 3) {
+ col[0] = 1.0f;
+ col[1] = 0.0f;
+ col[2] = 1.0f;
+ } else if (face == 4) {
+ col[0] = 0.0f;
+ col[1] = 1.0f;
+ col[2] = 1.0f;
+ } else if (face == 5) {
+ col[0] = 1.0f;
+ col[1] = 1.0f;
+ col[2] = 1.0f;
+ }
+#endif
+}
+
+static void CubemapToLonglat(const std::array<Image, 6>& cubemap_faces,
+ const float phi_offset, /* in angle */
+ const int width, Image* longlat) {
+ int height = width / 2;
+
+ longlat->width = width;
+ longlat->height = height;
+ longlat->data.resize(size_t(width * height * 3)); // RGB
+
+ const float kPI = 3.141592f;
+
+ for (size_t y = 0; y < size_t(height); y++) {
+ float theta = ((y + 0.5f) / float(height)) * kPI; // [0, pi]
+ for (size_t x = 0; x < size_t(width); x++) {
+ float phi = ((x + 0.5f) / float(width)) * 2.0f * kPI; // [0, 2 pi]
+
+ phi += (phi_offset) * kPI / 180.0f;
+
+ float n[3];
+
+ // Y-up
+ n[0] = std::sin(theta) * std::cos(phi);
+ n[1] = std::cos(theta);
+ n[2] = -std::sin(theta) * std::sin(phi);
+
+ float col[3];
+ SampleCubemap(cubemap_faces, n, col);
+
+ longlat->data[3 * size_t(y * width + x) + 0] = col[0];
+ longlat->data[3 * size_t(y * width + x) + 1] = col[1];
+ longlat->data[3 * size_t(y * width + x) + 2] = col[2];
+ }
+ }
+}
+
+static unsigned char ftouc(const float f) {
+ int i(f * 255.0f);
+ i = std::max(0, std::min(255, i));
+ return static_cast<unsigned char>(i);
+}
+
+int main(int argc, char** argv) {
+ float phi_offset = 0.0f;
+
+ if (argc < 9) {
+ printf(
+ "Usage: cube2longlat px.exr nx.exr py.exr ny.exr pz.exr nz.exr "
+ "output_width output.exr\n");
+ exit(-1);
+ }
+
+ std::array<std::string, 6> face_filenames;
+
+ face_filenames[0] = argv[1];
+ face_filenames[1] = argv[2];
+ face_filenames[2] = argv[3];
+ face_filenames[3] = argv[4];
+ face_filenames[4] = argv[5];
+ face_filenames[5] = argv[6];
+
+ int output_width = atoi(argv[7]);
+
+ std::string output_filename = argv[8];
+
+ if (argc > 9) {
+ phi_offset = atof(argv[9]);
+ }
+
+ std::array<Image, 6> cubemaps;
+
+ if (!LoadCubemaps(face_filenames, &cubemaps)) {
+ std::cerr << "Failed to load cubemap faces." << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ Image longlat;
+
+ CubemapToLonglat(cubemaps, phi_offset, output_width, &longlat);
+
+ {
+ std::string ext = GetFileExtension(output_filename);
+ if ((ext.compare("exr") == 0) || (ext.compare("EXR") == 0)) {
+ const char *err;
+ int ret = SaveEXR(longlat.data.data(), longlat.width, longlat.height,
+ /* RGB */ 3, /* fp16 */ 0, output_filename.c_str(), &err);
+ if (ret != TINYEXR_SUCCESS) {
+ if (err) {
+ std::cout << "Failed to save image as EXR. msg = " << err << ", code = " << ret << std::endl;
+ FreeEXRErrorMessage(err);
+ } else {
+ std::cout << "Failed to save image as EXR. code = " << ret << std::endl;
+ }
+ return EXIT_FAILURE;
+ }
+ } else if ((ext.compare("rgbm") == 0) || (ext.compare("RGBM") == 0)) {
+ std::vector<unsigned char> rgbm_image;
+
+ for (size_t j = 0; j < size_t(longlat.width * longlat.height); j++) {
+ float linear[3];
+ linear[0] = longlat.data[3 * j + 0];
+ linear[1] = longlat.data[3 * j + 1];
+ linear[2] = longlat.data[3 * j + 2];
+
+ float rgbm[4];
+
+ LinearToRGBM(linear, rgbm);
+
+ rgbm_image[4 * j + 0] = ftouc(rgbm[0]);
+ rgbm_image[4 * j + 1] = ftouc(rgbm[1]);
+ rgbm_image[4 * j + 2] = ftouc(rgbm[2]);
+ rgbm_image[4 * j + 3] = ftouc(rgbm[2]);
+ }
+
+ // Save as PNG.
+ int ret =
+ stbi_write_png(output_filename.c_str(), longlat.width, longlat.height,
+ 4, rgbm_image.data(), longlat.width * 4);
+
+ if (ret == 0) {
+ std::cerr << "Failed to save image as RGBM file : " << output_filename
+ << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ } else {
+ if ((ext.compare("hdr") == 0) || (ext.compare("HDR") == 0)) {
+ // ok
+ } else {
+ std::cout << "Unknown file extension. Interpret it as RGBE format : "
+ << ext << std::endl;
+ }
+
+ int ret = stbi_write_hdr(output_filename.c_str(), longlat.width,
+ longlat.height, 3, longlat.data.data());
+
+ if (ret == 0) {
+ std::cerr << "Failed to save image as HDR file : " << output_filename
+ << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+ }
+
+ std::cout << "Write " << output_filename << std::endl;
+
+ return 0;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/deepview/Makefile b/graphics/asymptote/cudareflect/tinyexr/examples/deepview/Makefile
new file mode 100644
index 0000000000..b3dafd7877
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/deepview/Makefile
@@ -0,0 +1,2 @@
+all:
+ g++ -I ../../deps/miniz -o deepview -g -O2 main.cc trackball.cc ../../tinyexr.cc ../../deps/miniz/miniz.c -framework OpenGL -framework GLUT
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/deepview/deepview_screencast.gif b/graphics/asymptote/cudareflect/tinyexr/examples/deepview/deepview_screencast.gif
new file mode 100644
index 0000000000..6a9560efbf
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/deepview/deepview_screencast.gif
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/deepview/main.cc b/graphics/asymptote/cudareflect/tinyexr/examples/deepview/main.cc
new file mode 100644
index 0000000000..4c996d5b81
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/deepview/main.cc
@@ -0,0 +1,277 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <float.h>
+#include <string.h>
+#include <string.h>
+
+#ifdef __APPLE__
+#include <GLUT/glut.h>
+#else
+#include <GL/glut.h>
+#endif
+
+#include "../../tinyexr.h"
+#include "trackball.h"
+
+static int mouse_x, mouse_y;
+static int mouse_m_pressed;
+static int mouse_r_pressed;
+static int mouse_moving;
+static int width = 512, height = 512;
+static float view_org[3], view_tgt[3];
+static float curr_quat[4], prev_quat[4];
+static float color_scale = 1.0f;
+
+DeepImage gDeepImage;
+
+//
+// --
+//
+
+static void reshape(int w, int h) {
+ glViewport(0, 0, w, h);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(5.0, (float)w / (float)h, 0.1f, 1000.0f);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ width = w;
+ height = h;
+}
+
+static void draw_samples() {
+ glPointSize(1.0f);
+ glColor3f(1.0f, 1.0f, 1.0f);
+
+ glBegin(GL_POINTS);
+
+ // find depth channel.
+ // @todo { Do this only once. }
+ int depthChan = 0;
+ int rChan = -1;
+ int raChan = -1;
+ int gChan = -1;
+ int gaChan = -1;
+ int bChan = -1;
+ int baChan = -1;
+
+ for (int c = 0; c < gDeepImage.num_channels; c++) {
+ if (strcmp("Z", gDeepImage.channel_names[c]) == 0) {
+ depthChan = c;
+ } else if (strcmp("R", gDeepImage.channel_names[c]) == 0) {
+ rChan = c;
+ } else if (strcmp("RA", gDeepImage.channel_names[c]) == 0) {
+ raChan = c;
+ } else if (strcmp("G", gDeepImage.channel_names[c]) == 0) {
+ gChan = c;
+ } else if (strcmp("GA", gDeepImage.channel_names[c]) == 0) {
+ gaChan = c;
+ } else if (strcmp("B", gDeepImage.channel_names[c]) == 0) {
+ bChan = c;
+ } else if (strcmp("BA", gDeepImage.channel_names[c]) == 0) {
+ baChan = c;
+ }
+ }
+
+ for (int y = 0; y < gDeepImage.height; y++) {
+ float py = 2.0f * ((gDeepImage.height - y - 1) / (float)gDeepImage.height) -
+ 1.0f; // upside down?
+ int sampleNum = gDeepImage.offset_table[y][gDeepImage.width - 1];
+
+ int s_start = 0; // First pixel data starts at 0
+ for (int x = 0; x < gDeepImage.width; x++) {
+ float px = 2.0f * (x / (float)gDeepImage.width) - 1.0f;
+ int s_end = gDeepImage.offset_table[y][x];
+ if (s_start >= sampleNum || s_end >= sampleNum) {
+ continue;
+ }
+ for (int s = s_start; s < s_end; s++) {
+ float pz = -gDeepImage.image[depthChan][y][s];
+
+ float red = 1.0f;
+ float green = 1.0f;
+ float blue = 1.0f;
+ float red_alpha = 1.0f;
+ float green_alpha = 1.0f;
+ float blue_alpha = 1.0f;
+ if (rChan >= 0) {
+ red = gDeepImage.image[rChan][y][s];
+ }
+ if (raChan >= 0) {
+ red_alpha = gDeepImage.image[raChan][y][s];
+ }
+ if (gChan >= 0) {
+ green = gDeepImage.image[gChan][y][s];
+ }
+ if (gaChan >= 0) {
+ green_alpha = gDeepImage.image[gaChan][y][s];
+ }
+ if (bChan >= 0) {
+ blue = gDeepImage.image[bChan][y][s];
+ }
+ if (baChan >= 0) {
+ blue_alpha = gDeepImage.image[baChan][y][s];
+ }
+ // unmultiply and apply scaling
+ red *= color_scale / red_alpha;
+ green *= color_scale / green_alpha;
+ blue *= color_scale / blue_alpha;
+ glColor3f(red, green, blue);
+ glVertex3f(px, py, pz);
+ }
+
+ s_start = s_end;
+ }
+ }
+
+ glEnd();
+}
+
+static void display() {
+ GLfloat mat[4][4];
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ // camera & rotate
+ gluLookAt(view_org[0], view_org[1], view_org[2], view_tgt[0], view_tgt[1],
+ view_tgt[2], 0.0, 1.0, 0.0);
+
+ build_rotmatrix(mat, curr_quat);
+ glMultMatrixf(&mat[0][0]);
+
+ draw_samples();
+
+ // glBegin(GL_POLYGON);
+ // glTexCoord2f(0 , 0); glVertex2f(-0.9 , -0.9);
+ // glTexCoord2f(0 , 1); glVertex2f(-0.9 , 0.9);
+ // glTexCoord2f(1 , 1); glVertex2f(0.9 , 0.9);
+ // glTexCoord2f(1 , 0); glVertex2f(0.9 , -0.9);
+ // glEnd();
+
+ glutSwapBuffers();
+}
+
+static void keyboard(unsigned char key, int x, int y) {
+ switch (key) {
+ case 'q':
+ case 27:
+ exit(0);
+ break;
+ case 'c':
+ color_scale += 1.0f;
+ break;
+ case 'x':
+ color_scale -= 1.0f;
+ if (color_scale < 1.0f)
+ color_scale = 1.0f;
+ break;
+ default:
+ break;
+ }
+
+ glutPostRedisplay();
+}
+
+static void mouse(int button, int state, int x, int y) {
+ int mod = glutGetModifiers();
+
+ if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
+ if (mod == GLUT_ACTIVE_SHIFT) {
+ mouse_m_pressed = 1;
+ } else if (mod == GLUT_ACTIVE_CTRL) {
+ mouse_r_pressed = 1;
+ } else {
+ trackball(prev_quat, 0, 0, 0, 0);
+ }
+ mouse_moving = 1;
+ mouse_x = x;
+ mouse_y = y;
+ } else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
+ mouse_m_pressed = 0;
+ mouse_r_pressed = 0;
+ mouse_moving = 0;
+ }
+}
+
+static void motion(int x, int y) {
+ float w = 1.0;
+ float mw = 0.1;
+
+ if (mouse_moving) {
+ if (mouse_r_pressed) {
+ view_org[2] += mw * (mouse_y - y);
+ view_tgt[2] += mw * (mouse_y - y);
+ } else if (mouse_m_pressed) {
+ view_org[0] += mw * (mouse_x - x);
+ view_org[1] -= mw * (mouse_y - y);
+ view_tgt[0] += mw * (mouse_x - x);
+ view_tgt[1] -= mw * (mouse_y - y);
+ } else {
+ trackball(prev_quat, w * (2.0 * mouse_x - width) / width,
+ w * (height - 2.0 * mouse_y) / height,
+ w * (2.0 * x - width) / width, w * (height - 2.0 * y) / height);
+ add_quats(prev_quat, curr_quat, curr_quat);
+ }
+
+ mouse_x = x;
+ mouse_y = y;
+ }
+
+ glutPostRedisplay();
+}
+
+static void init() {
+ trackball(curr_quat, 0, 0, 0, 0);
+
+ view_org[0] = 0.0f;
+ view_org[1] = 0.0f;
+ view_org[2] = 3.0f;
+
+ view_tgt[0] = 0.0f;
+ view_tgt[1] = 0.0f;
+ view_tgt[2] = 0.0f;
+}
+
+int main(int argc, char **argv) {
+ const char *input = "input.exr";
+
+ if (argc < 2) {
+ printf("Usage: deepview <input.exr>\n");
+ exit(1);
+ }
+
+ input = argv[1];
+ const char *err;
+ int ret = LoadDeepEXR(&gDeepImage, input, &err);
+ if (ret != 0) {
+ if (err) {
+ fprintf(stderr, "ERR: %s\n", err);
+ }
+ exit(-1);
+ }
+
+ glutInit(&argc, argv);
+ glutInitWindowSize(512, 512);
+ glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
+
+ init();
+
+ glutCreateWindow("deepimage viewer");
+
+ glutReshapeFunc(reshape);
+ glutDisplayFunc(display);
+ glutKeyboardFunc(keyboard);
+ glutMouseFunc(mouse);
+ glutMotionFunc(motion);
+ glutMainLoop();
+
+ return 0;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/deepview/trackball.cc b/graphics/asymptote/cudareflect/tinyexr/examples/deepview/trackball.cc
new file mode 100644
index 0000000000..f23d3db30b
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/deepview/trackball.cc
@@ -0,0 +1,324 @@
+/*
+ * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States. Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ * Trackball code:
+ *
+ * Implementation of a virtual trackball.
+ * Implemented by Gavin Bell, lots of ideas from Thant Tessman and
+ * the August '88 issue of Siggraph's "Computer Graphics," pp. 121-129.
+ *
+ * Vector manip code:
+ *
+ * Original code from:
+ * David M. Ciemiewicz, Mark Grossman, Henry Moreton, and Paul Haeberli
+ *
+ * Much mucking with by:
+ * Gavin Bell
+ */
+#include <math.h>
+#include "trackball.h"
+
+/*
+ * This size should really be based on the distance from the center of
+ * rotation to the point on the object underneath the mouse. That
+ * point would then track the mouse as closely as possible. This is a
+ * simple example, though, so that is left as an Exercise for the
+ * Programmer.
+ */
+#define TRACKBALLSIZE (0.8)
+
+/*
+ * Local function prototypes (not defined in trackball.h)
+ */
+static float tb_project_to_sphere(float, float, float);
+static void normalize_quat(float [4]);
+
+void
+vzero(float *v)
+{
+ v[0] = 0.0;
+ v[1] = 0.0;
+ v[2] = 0.0;
+}
+
+void
+vset(float *v, float x, float y, float z)
+{
+ v[0] = x;
+ v[1] = y;
+ v[2] = z;
+}
+
+void
+vsub(const float *src1, const float *src2, float *dst)
+{
+ dst[0] = src1[0] - src2[0];
+ dst[1] = src1[1] - src2[1];
+ dst[2] = src1[2] - src2[2];
+}
+
+void
+vcopy(const float *v1, float *v2)
+{
+ register int i;
+ for (i = 0 ; i < 3 ; i++)
+ v2[i] = v1[i];
+}
+
+void
+vcross(const float *v1, const float *v2, float *cross)
+{
+ float temp[3];
+
+ temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]);
+ temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]);
+ temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]);
+ vcopy(temp, cross);
+}
+
+float
+vlength(const float *v)
+{
+ return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+}
+
+void
+vscale(float *v, float div)
+{
+ v[0] *= div;
+ v[1] *= div;
+ v[2] *= div;
+}
+
+void
+vnormal(float *v)
+{
+ vscale(v,1.0/vlength(v));
+}
+
+float
+vdot(const float *v1, const float *v2)
+{
+ return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
+}
+
+void
+vadd(const float *src1, const float *src2, float *dst)
+{
+ dst[0] = src1[0] + src2[0];
+ dst[1] = src1[1] + src2[1];
+ dst[2] = src1[2] + src2[2];
+}
+
+/*
+ * Ok, simulate a track-ball. Project the points onto the virtual
+ * trackball, then figure out the axis of rotation, which is the cross
+ * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
+ * Note: This is a deformed trackball-- is a trackball in the center,
+ * but is deformed into a hyperbolic sheet of rotation away from the
+ * center. This particular function was chosen after trying out
+ * several variations.
+ *
+ * It is assumed that the arguments to this routine are in the range
+ * (-1.0 ... 1.0)
+ */
+void
+trackball(float q[4], float p1x, float p1y, float p2x, float p2y)
+{
+ float a[3]; /* Axis of rotation */
+ float phi; /* how much to rotate about axis */
+ float p1[3], p2[3], d[3];
+ float t;
+
+ if (p1x == p2x && p1y == p2y) {
+ /* Zero rotation */
+ vzero(q);
+ q[3] = 1.0;
+ return;
+ }
+
+ /*
+ * First, figure out z-coordinates for projection of P1 and P2 to
+ * deformed sphere
+ */
+ vset(p1,p1x,p1y,tb_project_to_sphere(TRACKBALLSIZE,p1x,p1y));
+ vset(p2,p2x,p2y,tb_project_to_sphere(TRACKBALLSIZE,p2x,p2y));
+
+ /*
+ * Now, we want the cross product of P1 and P2
+ */
+ vcross(p2,p1,a);
+
+ /*
+ * Figure out how much to rotate around that axis.
+ */
+ vsub(p1,p2,d);
+ t = vlength(d) / (2.0*TRACKBALLSIZE);
+
+ /*
+ * Avoid problems with out-of-control values...
+ */
+ if (t > 1.0) t = 1.0;
+ if (t < -1.0) t = -1.0;
+ phi = 2.0 * asin(t);
+
+ axis_to_quat(a,phi,q);
+}
+
+/*
+ * Given an axis and angle, compute quaternion.
+ */
+void
+axis_to_quat(float a[3], float phi, float q[4])
+{
+ vnormal(a);
+ vcopy(a,q);
+ vscale(q,sin(phi/2.0));
+ q[3] = cos(phi/2.0);
+}
+
+/*
+ * Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
+ * if we are away from the center of the sphere.
+ */
+static float
+tb_project_to_sphere(float r, float x, float y)
+{
+ float d, t, z;
+
+ d = sqrt(x*x + y*y);
+ if (d < r * 0.70710678118654752440) { /* Inside sphere */
+ z = sqrt(r*r - d*d);
+ } else { /* On hyperbola */
+ t = r / 1.41421356237309504880;
+ z = t*t / d;
+ }
+ return z;
+}
+
+/*
+ * Given two rotations, e1 and e2, expressed as quaternion rotations,
+ * figure out the equivalent single rotation and stuff it into dest.
+ *
+ * This routine also normalizes the result every RENORMCOUNT times it is
+ * called, to keep error from creeping in.
+ *
+ * NOTE: This routine is written so that q1 or q2 may be the same
+ * as dest (or each other).
+ */
+
+#define RENORMCOUNT 97
+
+void
+add_quats(float q1[4], float q2[4], float dest[4])
+{
+ static int count=0;
+ float t1[4], t2[4], t3[4];
+ float tf[4];
+
+ vcopy(q1,t1);
+ vscale(t1,q2[3]);
+
+ vcopy(q2,t2);
+ vscale(t2,q1[3]);
+
+ vcross(q2,q1,t3);
+ vadd(t1,t2,tf);
+ vadd(t3,tf,tf);
+ tf[3] = q1[3] * q2[3] - vdot(q1,q2);
+
+ dest[0] = tf[0];
+ dest[1] = tf[1];
+ dest[2] = tf[2];
+ dest[3] = tf[3];
+
+ if (++count > RENORMCOUNT) {
+ count = 0;
+ normalize_quat(dest);
+ }
+}
+
+/*
+ * Quaternions always obey: a^2 + b^2 + c^2 + d^2 = 1.0
+ * If they don't add up to 1.0, dividing by their magnitued will
+ * renormalize them.
+ *
+ * Note: See the following for more information on quaternions:
+ *
+ * - Shoemake, K., Animating rotation with quaternion curves, Computer
+ * Graphics 19, No 3 (Proc. SIGGRAPH'85), 245-254, 1985.
+ * - Pletinckx, D., Quaternion calculus as a basic tool in computer
+ * graphics, The Visual Computer 5, 2-13, 1989.
+ */
+static void
+normalize_quat(float q[4])
+{
+ int i;
+ float mag;
+
+ mag = (q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
+ for (i = 0; i < 4; i++) q[i] /= mag;
+}
+
+/*
+ * Build a rotation matrix, given a quaternion rotation.
+ *
+ */
+void
+build_rotmatrix(float m[4][4], float q[4])
+{
+ m[0][0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]);
+ m[0][1] = 2.0 * (q[0] * q[1] - q[2] * q[3]);
+ m[0][2] = 2.0 * (q[2] * q[0] + q[1] * q[3]);
+ m[0][3] = 0.0;
+
+ m[1][0] = 2.0 * (q[0] * q[1] + q[2] * q[3]);
+ m[1][1]= 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]);
+ m[1][2] = 2.0 * (q[1] * q[2] - q[0] * q[3]);
+ m[1][3] = 0.0;
+
+ m[2][0] = 2.0 * (q[2] * q[0] - q[1] * q[3]);
+ m[2][1] = 2.0 * (q[1] * q[2] + q[0] * q[3]);
+ m[2][2] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]);
+ m[2][3] = 0.0;
+
+ m[3][0] = 0.0;
+ m[3][1] = 0.0;
+ m[3][2] = 0.0;
+ m[3][3] = 1.0;
+}
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/deepview/trackball.h b/graphics/asymptote/cudareflect/tinyexr/examples/deepview/trackball.h
new file mode 100644
index 0000000000..68a83d1609
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/deepview/trackball.h
@@ -0,0 +1,81 @@
+/*
+ * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
+ * ALL RIGHTS RESERVED
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation, and that
+ * the name of Silicon Graphics, Inc. not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.
+ *
+ * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
+ * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
+ * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
+ * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
+ * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
+ * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
+ * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
+ * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * US Government Users Restricted Rights
+ * Use, duplication, or disclosure by the Government is subject to
+ * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
+ * (c)(1)(ii) of the Rights in Technical Data and Computer Software
+ * clause at DFARS 252.227-7013 and/or in similar or successor
+ * clauses in the FAR or the DOD or NASA FAR Supplement.
+ * Unpublished-- rights reserved under the copyright laws of the
+ * United States. Contractor/manufacturer is Silicon Graphics,
+ * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
+ *
+ * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
+ */
+/*
+ * trackball.h
+ * A virtual trackball implementation
+ * Written by Gavin Bell for Silicon Graphics, November 1988.
+ */
+
+/*
+ * Pass the x and y coordinates of the last and current positions of
+ * the mouse, scaled so they are from (-1.0 ... 1.0).
+ *
+ * The resulting rotation is returned as a quaternion rotation in the
+ * first paramater.
+ */
+void
+trackball(float q[4], float p1x, float p1y, float p2x, float p2y);
+
+void
+negate_quat(float *q, float *qn);
+
+/*
+ * Given two quaternions, add them together to get a third quaternion.
+ * Adding quaternions to get a compound rotation is analagous to adding
+ * translations to get a compound translation. When incrementally
+ * adding rotations, the first argument here should be the new
+ * rotation, the second and third the total rotation (which will be
+ * over-written with the resulting new total rotation).
+ */
+void
+add_quats(float *q1, float *q2, float *dest);
+
+/*
+ * A useful function, builds a rotation matrix in Matrix based on
+ * given quaternion.
+ */
+void
+build_rotmatrix(float m[4][4], float q[4]);
+
+/*
+ * This function computes a quaternion based on an axis (defined by
+ * the given vector) and an angle about which to rotate. The angle is
+ * expressed in radians. The result is put into the third argument.
+ */
+void
+axis_to_quat(float a[3], float phi, float q[4]);
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/Makefile b/graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/Makefile
new file mode 100644
index 0000000000..68789d2009
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/Makefile
@@ -0,0 +1,32 @@
+
+CXX=clang++
+CC=clang
+
+CFLAGS = -fsanitize=address -Weverything -Wno-padded -g -O2 -I../../ -I../../deps/miniz
+CXXFLAGS = -std=c++11 -Wno-c++98-compat -Wno-variadic-macros $(CFLAGS)
+LDFLAGS = -fsanitize=address
+
+# ZFP
+#CXXFLAGS += -DTINYEXR_USE_ZFP=1 -I/home/syoyo/work/zfp/include
+#LDFLAGS += -L/home/syoyo/work/zfp/build/lib -lzfp
+
+
+all: exr2fptiff
+
+exr2fptiff: exr2fptiff.o tinyexr.o miniz.o
+ $(CXX) -o $@ $^ $(LDFLAGS)
+
+exr2fptiff.o: exr2fptiff.cc tiny_dng_writer.h
+ $(CXX) $(CXXFLAGS) -c -o $@ $<
+
+tinyexr.o: ../../tinyexr.cc
+ $(CXX) $(CXXFLAGS) -c -o $@ $<
+
+miniz.o: ../../deps/miniz/miniz.c
+ $(CC) $(CFLAGS) -c $(INC_DIR) $<
+
+.PHONY: clean
+
+
+clean:
+ rm -rf tinyexr.o exr2fptiff.o
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/README.md b/graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/README.md
new file mode 100644
index 0000000000..3c3a2390dd
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/README.md
@@ -0,0 +1,7 @@
+# exr2fptiff
+
+OpenEXR to 32bit float TIFF converter.
+
+## Limitation
+
+Input EXR image must be grayscale, RGB or RGBA.
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/exr2fptiff.cc b/graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/exr2fptiff.cc
new file mode 100644
index 0000000000..fd101bb6a0
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/exr2fptiff.cc
@@ -0,0 +1,199 @@
+#include <cstdio>
+#include <cstdlib>
+#include <vector>
+
+#include "tinyexr.h"
+
+#define TINY_DNG_WRITER_IMPLEMENTATION
+#include "tiny_dng_writer.h"
+
+static bool Create32bitFpTiff(
+ const float *data, // [width x height x in_channels]
+ const size_t width,
+ const size_t height,
+ const size_t in_channels,
+ const size_t channels,
+ tinydngwriter::DNGImage *dng_image) {
+
+ if (in_channels < 1) return false;
+
+ unsigned int image_width = uint32_t(width);
+ unsigned int image_height = uint32_t(height);
+
+ //dng_image->SetSubfileType(false, false, false);
+ dng_image->SetImageWidth(image_width);
+ dng_image->SetImageLength(image_height);
+ dng_image->SetRowsPerStrip(image_height);
+ dng_image->SetSamplesPerPixel(uint16_t(channels));
+ std::vector<uint16_t> bps(channels);
+ for (size_t i = 0; i < bps.size(); i++) {
+ bps[i] = 32;
+ }
+ dng_image->SetBitsPerSample(static_cast<unsigned int>(channels), bps.data());
+ dng_image->SetPlanarConfig(tinydngwriter::PLANARCONFIG_CONTIG);
+ dng_image->SetCompression(tinydngwriter::COMPRESSION_NONE);
+ if (channels == 1) {
+ dng_image->SetPhotometric(
+ tinydngwriter::PHOTOMETRIC_BLACK_IS_ZERO); // grayscale
+ } else {
+ dng_image->SetPhotometric(
+ tinydngwriter::PHOTOMETRIC_RGB);
+ }
+ dng_image->SetXResolution(1.0);
+ dng_image->SetYResolution(1.0);
+ dng_image->SetResolutionUnit(tinydngwriter::RESUNIT_NONE);
+
+ std::vector<uint16_t> formats(channels);
+ for (size_t i = 0; i < formats.size(); i++) {
+ formats[i] = tinydngwriter::SAMPLEFORMAT_IEEEFP;
+ }
+ dng_image->SetSampleFormat(static_cast<unsigned int>(channels), formats.data());
+
+ std::vector<float> buf;
+ buf.resize(size_t(channels) * image_width * image_height);
+
+ for (size_t i = 0; i < image_width * image_height; i++) {
+ size_t in_c = 0;
+ for (size_t c = 0; c < channels; c++) {
+ buf[channels * i + c] = data[in_channels * i + in_c];
+ in_c++;
+ in_c = std::min(in_c, in_channels - 1);
+ }
+ }
+
+ //size_t max_dump_pixels = 4096;
+ //for (size_t i = 0; i < std::min(max_dump_pixels, buf.size()); i++) {
+ // std::cout << "val[" << i << "] = " << buf[i] << "\n";
+ //}
+ //std::cout << "last = " << buf.at(image_width * image_height * channels - 1) << "\n";
+
+ // We must retain pointer address of `buf` until calling DNGWriter::WriteToFile
+ dng_image->SetImageData(reinterpret_cast<unsigned char *>(buf.data()),
+ buf.size() * sizeof(float));
+
+
+ if (!dng_image->Error().empty()) {
+ std::cout << "Err: " << dng_image->Error() << "\n";
+
+ return false;
+ }
+
+ return true;
+}
+
+int main(int argc, char** argv)
+{
+ if (argc < 3) {
+ printf("Usage: exr2fptiff input.exr output.tiff\n");
+ exit(-1);
+ }
+
+ std::string input_filename = argv[1];
+ std::string output_filename = argv[2];
+
+
+ // Get # of layers
+ size_t num_layers{0};
+ {
+
+ EXRVersion exr_version;
+ {
+ int ret = ParseEXRVersionFromFile(&exr_version, input_filename.c_str());
+ if (ret != 0) {
+ std::cerr << "Invalid EXR file: " << input_filename << "\n";
+ return EXIT_FAILURE;
+ }
+
+ if (exr_version.multipart) {
+ std::cerr << "Multipart EXR file is not supported in this example.\n";
+ return EXIT_FAILURE;
+ }
+ }
+
+ EXRHeader exr_header;
+ InitEXRHeader(&exr_header);
+
+ const char* err = nullptr;
+ int ret = ParseEXRHeaderFromFile(&exr_header, &exr_version, argv[1], &err);
+ if (ret != TINYEXR_SUCCESS) {
+ if (err) {
+ std::cerr << "Parse EXR error: " << err << "\n";
+ FreeEXRErrorMessage(err); // free's buffer for an error message
+ } else {
+ std::cerr << "Parse EXR error.\n";
+ }
+ return EXIT_FAILURE;
+ }
+
+ num_layers = size_t(exr_header.num_channels);
+ if (num_layers == 0) {
+ std::cerr << "no layers found\n";
+ return EXIT_FAILURE;
+ }
+
+ if (num_layers > 4) {
+ std::cerr << "This program supports up to 4(e.g. RGBA) layers.\n";
+ return EXIT_FAILURE;
+ }
+
+ FreeEXRHeader(&exr_header);
+ }
+
+ std::cout << "# of channels = " << num_layers << "\n";
+
+ // Use legacy but easy-to-use API to read image.
+ float *rgba{nullptr};
+ int width;
+ int height;
+ {
+ const char *err;
+ int ret = LoadEXR(&rgba, &width, &height, input_filename.c_str(), &err);
+
+ if (ret != TINYEXR_SUCCESS) {
+ if (err) {
+ std::cerr << "Load EXR error: " << err << "\n";
+ FreeEXRErrorMessage(err); // free's buffer for an error message
+ } else {
+ std::cerr << "Load EXR error.\n";
+ }
+ return EXIT_FAILURE;
+ }
+
+ }
+
+ bool big_endian = false;
+
+ tinydngwriter::DNGImage tiff;
+ tiff.SetBigEndian(big_endian);
+
+ bool ret = Create32bitFpTiff(rgba, size_t(width), size_t(height), /* in_channels */4, size_t(num_layers), &tiff);
+ if (!ret) {
+ std::cerr << "Failed to create floating point tiff data\n";
+ return EXIT_FAILURE;
+ }
+
+ // 4. Free image data
+ free(rgba);
+
+ tinydngwriter::DNGWriter dng_writer(big_endian);
+ ret = dng_writer.AddImage(&tiff);
+ if (!ret) {
+ std::cerr << "Failed to add TIFF image to TIFF writer.\n";
+ return EXIT_FAILURE;
+ }
+
+ // 5. write tiff
+ std::string err;
+ ret = dng_writer.WriteToFile(output_filename.c_str(), &err);
+
+ if (!err.empty()) {
+ std::cerr << err;
+ }
+
+ if (!ret) {
+ return EXIT_FAILURE;
+ }
+
+
+ return EXIT_SUCCESS;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/tiny_dng_writer.h b/graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/tiny_dng_writer.h
new file mode 100644
index 0000000000..6156821f3c
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exr2fptiff/tiny_dng_writer.h
@@ -0,0 +1,1356 @@
+//
+// TinyDNGWriter, single header only DNG writer in C++11.
+//
+
+/*
+The MIT License (MIT)
+
+Copyright (c) 2016 - 2020 Syoyo Fujita.
+
+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
+AUTHORS OR COPYRIGHT HOLDERS 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.
+*/
+
+#ifndef TINY_DNG_WRITER_H_
+#define TINY_DNG_WRITER_H_
+
+#include <sstream>
+#include <vector>
+
+namespace tinydngwriter {
+
+typedef enum {
+ TIFFTAG_SUB_FILETYPE = 254,
+ TIFFTAG_IMAGE_WIDTH = 256,
+ TIFFTAG_IMAGE_LENGTH = 257,
+ TIFFTAG_BITS_PER_SAMPLE = 258,
+ TIFFTAG_COMPRESSION = 259,
+ TIFFTAG_PHOTOMETRIC = 262,
+ TIFFTAG_IMAGEDESCRIPTION = 270,
+ TIFFTAG_STRIP_OFFSET = 273,
+ TIFFTAG_SAMPLES_PER_PIXEL = 277,
+ TIFFTAG_ROWS_PER_STRIP = 278,
+ TIFFTAG_STRIP_BYTE_COUNTS = 279,
+ TIFFTAG_PLANAR_CONFIG = 284,
+ TIFFTAG_ORIENTATION = 274,
+
+ TIFFTAG_XRESOLUTION = 282, // rational
+ TIFFTAG_YRESOLUTION = 283, // rational
+ TIFFTAG_RESOLUTION_UNIT = 296,
+
+ TIFFTAG_SAMPLEFORMAT = 339,
+
+ // DNG extension
+ TIFFTAG_CFA_REPEAT_PATTERN_DIM = 33421,
+ TIFFTAG_CFA_PATTERN = 33422,
+
+ TIFFTAG_DNG_VERSION = 50706,
+ TIFFTAG_DNG_BACKWARD_VERSION = 50707,
+ TIFFTAG_CHRROMA_BLUR_RADIUS = 50703,
+ TIFFTAG_BLACK_LEVEL = 50714,
+ TIFFTAG_WHITE_LEVEL = 50717,
+ TIFFTAG_COLOR_MATRIX1 = 50721,
+ TIFFTAG_COLOR_MATRIX2 = 50722,
+ TIFFTAG_EXTRA_CAMERA_PROFILES = 50933,
+ TIFFTAG_PROFILE_NAME = 50936,
+ TIFFTAG_AS_SHOT_PROFILE_NAME = 50934,
+ TIFFTAG_DEFAULT_BLACK_RENDER = 51110,
+ TIFFTAG_ACTIVE_AREA = 50829,
+ TIFFTAG_FORWARD_MATRIX1 = 50964,
+ TIFFTAG_FORWARD_MATRIX2 = 50965
+} Tag;
+
+// SUBFILETYPE(bit field)
+static const int FILETYPE_REDUCEDIMAGE = 1;
+static const int FILETYPE_PAGE = 2;
+static const int FILETYPE_MASK = 4;
+
+// PLANARCONFIG
+static const int PLANARCONFIG_CONTIG = 1;
+static const int PLANARCONFIG_SEPARATE = 2;
+
+// COMPRESSION
+// TODO(syoyo) more compressin types.
+static const int COMPRESSION_NONE = 1;
+
+// ORIENTATION
+static const int ORIENTATION_TOPLEFT = 1;
+static const int ORIENTATION_TOPRIGHT = 2;
+static const int ORIENTATION_BOTRIGHT = 3;
+static const int ORIENTATION_BOTLEFT = 4;
+static const int ORIENTATION_LEFTTOP = 5;
+static const int ORIENTATION_RIGHTTOP = 6;
+static const int ORIENTATION_RIGHTBOT = 7;
+static const int ORIENTATION_LEFTBOT = 8;
+
+// RESOLUTIONUNIT
+static const int RESUNIT_NONE = 1;
+static const int RESUNIT_INCH = 2;
+static const int RESUNIT_CENTIMETER = 2;
+
+// PHOTOMETRIC
+// TODO(syoyo): more photometric types.
+static const int PHOTOMETRIC_WHITE_IS_ZERO = 0; // For bilevel and grayscale
+static const int PHOTOMETRIC_BLACK_IS_ZERO = 1; // For bilevel and grayscale
+static const int PHOTOMETRIC_RGB = 2; // Default
+static const int PHOTOMETRIC_CFA = 32893; // DNG ext
+static const int PHOTOMETRIC_LINEARRAW = 34892; // DNG ext
+
+// Sample format
+static const int SAMPLEFORMAT_UINT = 1; // Default
+static const int SAMPLEFORMAT_INT = 2;
+static const int SAMPLEFORMAT_IEEEFP = 3; // floating point
+
+struct IFDTag {
+ unsigned short tag;
+ unsigned short type;
+ unsigned int count;
+ unsigned int offset_or_value;
+};
+// 12 bytes.
+
+class DNGImage {
+ public:
+ DNGImage();
+ ~DNGImage() {}
+
+ ///
+ /// Optional: Explicitly specify endian.
+ /// Must be called before calling other Set methods.
+ ///
+ void SetBigEndian(bool big_endian);
+
+ ///
+ /// Default = 0
+ ///
+ bool SetSubfileType(bool reduced_image = false, bool page = false,
+ bool mask = false);
+
+ bool SetImageWidth(unsigned int value);
+ bool SetImageLength(unsigned int value);
+ bool SetRowsPerStrip(unsigned int value);
+ bool SetSamplesPerPixel(unsigned short value);
+ // Set bits for each samples
+ bool SetBitsPerSample(const unsigned int num_samples,
+ const unsigned short *values);
+ bool SetPhotometric(unsigned short value);
+ bool SetPlanarConfig(unsigned short value);
+ bool SetOrientation(unsigned short value);
+ bool SetCompression(unsigned short value);
+ bool SetSampleFormat(const unsigned int num_samples,
+ const unsigned short *values);
+ bool SetXResolution(double value);
+ bool SetYResolution(double value);
+ bool SetResolutionUnit(const unsigned short value);
+
+ bool SetImageDescription(const std::string &ascii);
+
+ bool SetActiveArea(const unsigned int values[4]);
+
+ bool SetChromaBlurRadius(double value);
+
+ /// Specify black level per sample.
+ bool SetBlackLevelRational(unsigned int num_samples, const double *values);
+
+ /// Specify white level per sample.
+ bool SetWhiteLevelRational(unsigned int num_samples, const double *values);
+
+ /// Set image data
+ bool SetImageData(const unsigned char *data, const size_t data_len);
+
+ /// Set custom field
+ bool SetCustomFieldLong(const unsigned short tag, const int value);
+ bool SetCustomFieldULong(const unsigned short tag, const unsigned int value);
+
+ size_t GetDataSize() const { return data_os_.str().length(); }
+
+ size_t GetStripOffset() const { return data_strip_offset_; }
+ size_t GetStripBytes() const { return data_strip_bytes_; }
+
+ /// Write aux IFD data and strip image data to stream
+ bool WriteDataToStream(std::ostream *ofs, std::string *err) const;
+
+ ///
+ /// Write IFD to stream.
+ ///
+ /// @param[in] data_base_offset : Byte offset to data
+ /// @param[in] strip_offset : Byte offset to image strip data
+ ///
+ /// TODO(syoyo): Support multiple strips
+ ///
+ bool WriteIFDToStream(const unsigned int data_base_offset,
+ const unsigned int strip_offset, std::ostream *ofs,
+ std::string *err) const;
+
+ std::string Error() const { return err_; }
+
+ private:
+ std::ostringstream data_os_;
+ bool swap_endian_;
+ bool dng_big_endian_;
+ unsigned short num_fields_;
+ unsigned int samples_per_pixels_;
+ unsigned short bits_per_sample_;
+
+ // TODO(syoyo): Support multiple strips
+ size_t data_strip_offset_{0};
+ size_t data_strip_bytes_{0};
+
+ std::string err_; // Error message
+
+ std::vector<IFDTag> ifd_tags_;
+};
+
+class DNGWriter {
+ public:
+ // TODO(syoyo): Use same endian setting with DNGImage.
+ DNGWriter(bool big_endian);
+ ~DNGWriter() {}
+
+ ///
+ /// Add DNGImage.
+ /// It just retains the pointer of the image, thus
+ /// application must not free resources until `WriteToFile` has been called.
+ ///
+ bool AddImage(const DNGImage *image) {
+ images_.push_back(image);
+
+ return true;
+ }
+
+ /// Write DNG to a file.
+ /// Return error string to `err` when Write() returns false.
+ /// Returns true upon success.
+ bool WriteToFile(const char *filename, std::string *err) const;
+
+ private:
+ bool swap_endian_;
+ bool dng_big_endian_; // Endianness of DNG file.
+
+ std::vector<const DNGImage *> images_;
+};
+
+} // namespace tinydngwriter
+
+#endif // TINY_DNG_WRITER_H_
+
+#ifdef TINY_DNG_WRITER_IMPLEMENTATION
+
+//
+// TIFF format resources.
+//
+// http://c0de517e.blogspot.jp/2013/07/tiny-hdr-writer.html
+// http://paulbourke.net/dataformats/tiff/ and
+// http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf
+//
+
+#include <algorithm>
+#include <cassert>
+#include <cfloat>
+#include <cmath>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
+namespace tinydngwriter {
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#if __has_warning("-Wzero-as-null-pointer-constant")
+#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
+#endif
+#endif
+
+//
+// TinyDNGWriter stores IFD table in the end of file so that offset to
+// image data can be easily computed.
+//
+// +----------------------+
+// | header |
+// +----------------------+
+// | |
+// | image & meta 0 |
+// | |
+// +----------------------+
+// | |
+// | image & meta 1 |
+// | |
+// +----------------------+
+// ...
+// +----------------------+
+// | |
+// | image & meta N |
+// | |
+// +----------------------+
+// | |
+// | IFD 0 |
+// | |
+// +----------------------+
+// | |
+// | IFD 1 |
+// | |
+// +----------------------+
+// ...
+// +----------------------+
+// | |
+// | IFD 2 |
+// | |
+// +----------------------+
+//
+
+// From tiff.h
+typedef enum {
+ TIFF_NOTYPE = 0, /* placeholder */
+ TIFF_BYTE = 1, /* 8-bit unsigned integer */
+ TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */
+ TIFF_SHORT = 3, /* 16-bit unsigned integer */
+ TIFF_LONG = 4, /* 32-bit unsigned integer */
+ TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */
+ TIFF_SBYTE = 6, /* !8-bit signed integer */
+ TIFF_UNDEFINED = 7, /* !8-bit untyped data */
+ TIFF_SSHORT = 8, /* !16-bit signed integer */
+ TIFF_SLONG = 9, /* !32-bit signed integer */
+ TIFF_SRATIONAL = 10, /* !64-bit signed fraction */
+ TIFF_FLOAT = 11, /* !32-bit IEEE floating point */
+ TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */
+ TIFF_IFD = 13, /* %32-bit unsigned integer (offset) */
+ TIFF_LONG8 = 16, /* BigTIFF 64-bit unsigned integer */
+ TIFF_SLONG8 = 17, /* BigTIFF 64-bit signed integer */
+ TIFF_IFD8 = 18 /* BigTIFF 64-bit unsigned integer (offset) */
+} DataType;
+
+const static int kHeaderSize = 8; // TIFF header size.
+
+// floating point to integer rational value conversion
+// https://stackoverflow.com/questions/51142275/exact-value-of-a-floating-point-number-as-a-rational
+//
+// Return error flag
+static int DoubleToRational(double x, double *numerator, double *denominator) {
+ if (!std::isfinite(x)) {
+ *numerator = *denominator = 0.0;
+ if (x > 0.0) *numerator = 1.0;
+ if (x < 0.0) *numerator = -1.0;
+ return 1;
+ }
+
+ // TIFF Rational use two uint32's, so reduce the bits
+ int bdigits = FLT_MANT_DIG;
+ int expo;
+ *denominator = 1.0;
+ *numerator = std::frexp(x, &expo) * std::pow(2.0, bdigits);
+ expo -= bdigits;
+ if (expo > 0) {
+ *numerator *= std::pow(2.0, expo);
+ } else if (expo < 0) {
+ expo = -expo;
+ if (expo >= FLT_MAX_EXP - 1) {
+ *numerator /= std::pow(2.0, expo - (FLT_MAX_EXP - 1));
+ *denominator *= std::pow(2.0, FLT_MAX_EXP - 1);
+ return fabs(*numerator) < 1.0;
+ } else {
+ *denominator *= std::pow(2.0, expo);
+ }
+ }
+
+ while ((std::fabs(*numerator) > 0.0) &&
+ (std::fabs(std::fmod(*numerator, 2)) <
+ std::numeric_limits<double>::epsilon()) &&
+ (std::fabs(std::fmod(*denominator, 2)) <
+ std::numeric_limits<double>::epsilon())) {
+ *numerator /= 2.0;
+ *denominator /= 2.0;
+ }
+ return 0;
+}
+
+static inline bool IsBigEndian() {
+ unsigned int i = 0x01020304;
+ char c[4];
+ memcpy(c, &i, 4);
+ return (c[0] == 1);
+}
+
+static void swap2(unsigned short *val) {
+ unsigned short tmp = *val;
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[1];
+ dst[1] = src[0];
+}
+
+static void swap4(unsigned int *val) {
+ unsigned int tmp = *val;
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[3];
+ dst[1] = src[2];
+ dst[2] = src[1];
+ dst[3] = src[0];
+}
+
+static void swap8(uint64_t *val) {
+ uint64_t tmp = *val;
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[7];
+ dst[1] = src[6];
+ dst[2] = src[5];
+ dst[3] = src[4];
+ dst[4] = src[3];
+ dst[5] = src[2];
+ dst[6] = src[1];
+ dst[7] = src[0];
+}
+
+static void Write1(const unsigned char c, std::ostringstream *out) {
+ unsigned char value = c;
+ out->write(reinterpret_cast<const char *>(&value), 1);
+}
+
+static void Write2(const unsigned short c, std::ostringstream *out,
+ const bool swap_endian) {
+ unsigned short value = c;
+ if (swap_endian) {
+ swap2(&value);
+ }
+
+ out->write(reinterpret_cast<const char *>(&value), 2);
+}
+
+static void Write4(const unsigned int c, std::ostringstream *out,
+ const bool swap_endian) {
+ unsigned int value = c;
+ if (swap_endian) {
+ swap4(&value);
+ }
+
+ out->write(reinterpret_cast<const char *>(&value), 4);
+}
+
+static bool WriteTIFFTag(const unsigned short tag, const unsigned short type,
+ const unsigned int count, const unsigned char *data,
+ std::vector<IFDTag> *tags_out,
+ std::ostringstream *data_out) {
+ assert(sizeof(IFDTag) ==
+ 12); // FIXME(syoyo): Use static_assert for C++11 compiler
+
+ IFDTag ifd;
+ ifd.tag = tag;
+ ifd.type = type;
+ ifd.count = count;
+
+ size_t typesize_table[] = {1, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4};
+
+ size_t len = count * (typesize_table[(type) < 14 ? (type) : 0]);
+ if (len > 4) {
+ assert(data_out);
+ if (!data_out) {
+ return false;
+ }
+
+ // Store offset value.
+
+ unsigned int offset =
+ static_cast<unsigned int>(data_out->tellp()) + kHeaderSize;
+ ifd.offset_or_value = offset;
+
+ data_out->write(reinterpret_cast<const char *>(data),
+ static_cast<std::streamsize>(len));
+
+ } else {
+ ifd.offset_or_value = 0;
+
+ // less than 4 bytes = store data itself.
+ if (len == 1) {
+ unsigned char value = *(data);
+ memcpy(&(ifd.offset_or_value), &value, sizeof(unsigned char));
+ } else if (len == 2) {
+ unsigned short value = *(reinterpret_cast<const unsigned short *>(data));
+ memcpy(&(ifd.offset_or_value), &value, sizeof(unsigned short));
+ } else if (len == 4) {
+ unsigned int value = *(reinterpret_cast<const unsigned int *>(data));
+ ifd.offset_or_value = value;
+ } else {
+ assert(0);
+ }
+ }
+
+ tags_out->push_back(ifd);
+
+ return true;
+}
+
+static bool WriteTIFFVersionHeader(std::ostringstream *out, bool big_endian) {
+ // TODO(syoyo): Support BigTIFF?
+
+ // 4d 4d = Big endian. 49 49 = Little endian.
+ if (big_endian) {
+ Write1(0x4d, out);
+ Write1(0x4d, out);
+ Write1(0x0, out);
+ Write1(0x2a, out); // Tiff version ID
+ } else {
+ Write1(0x49, out);
+ Write1(0x49, out);
+ Write1(0x2a, out); // Tiff version ID
+ Write1(0x0, out);
+ }
+
+ return true;
+}
+
+DNGImage::DNGImage()
+ : dng_big_endian_(true),
+ num_fields_(0),
+ samples_per_pixels_(0),
+ bits_per_sample_(0),
+ data_strip_offset_{0},
+ data_strip_bytes_{0} {
+ swap_endian_ = (IsBigEndian() != dng_big_endian_);
+}
+
+void DNGImage::SetBigEndian(bool big_endian) {
+ dng_big_endian_ = big_endian;
+ swap_endian_ = (IsBigEndian() != dng_big_endian_);
+}
+
+bool DNGImage::SetSubfileType(bool reduced_image, bool page, bool mask) {
+ unsigned int count = 1;
+
+ unsigned int bits = 0;
+ if (reduced_image) {
+ bits |= FILETYPE_REDUCEDIMAGE;
+ }
+ if (page) {
+ bits |= FILETYPE_PAGE;
+ }
+ if (mask) {
+ bits |= FILETYPE_MASK;
+ }
+
+ bool ret = WriteTIFFTag(
+ static_cast<unsigned short>(TIFFTAG_SUB_FILETYPE), TIFF_LONG, count,
+ reinterpret_cast<const unsigned char *>(&bits), &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetImageWidth(const unsigned int width) {
+ unsigned int count = 1;
+
+ unsigned int data = width;
+ bool ret = WriteTIFFTag(
+ static_cast<unsigned short>(TIFFTAG_IMAGE_WIDTH), TIFF_LONG, count,
+ reinterpret_cast<const unsigned char *>(&data), &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetImageLength(const unsigned int length) {
+ unsigned int count = 1;
+
+ const unsigned int data = length;
+ bool ret = WriteTIFFTag(
+ static_cast<unsigned short>(TIFFTAG_IMAGE_LENGTH), TIFF_LONG, count,
+ reinterpret_cast<const unsigned char *>(&data), &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetRowsPerStrip(const unsigned int rows) {
+ if (rows == 0) {
+ return false;
+ }
+
+ unsigned int count = 1;
+
+ const unsigned int data = rows;
+ bool ret = WriteTIFFTag(
+ static_cast<unsigned short>(TIFFTAG_ROWS_PER_STRIP), TIFF_LONG, count,
+ reinterpret_cast<const unsigned char *>(&data), &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetSamplesPerPixel(const unsigned short value) {
+ if (value > 4) {
+ return false;
+ }
+
+ unsigned int count = 1;
+
+ const unsigned short data = value;
+ bool ret = WriteTIFFTag(
+ static_cast<unsigned short>(TIFFTAG_SAMPLES_PER_PIXEL), TIFF_SHORT, count,
+ reinterpret_cast<const unsigned char *>(&data), &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ samples_per_pixels_ = value; // Store SPP for later use.
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetBitsPerSample(const unsigned int num_samples,
+ const unsigned short *values) {
+ // `SetSamplesPerPixel()` must be called in advance and SPP shoud be equal to
+ // `num_samples`.
+ if ((num_samples > 0) && (num_samples == samples_per_pixels_)) {
+ // OK
+ } else {
+ err_ += "SetSamplesPerPixel() must be called before SetBitsPerSample().\n";
+ return false;
+ }
+
+ unsigned short bps = values[0];
+
+ std::vector<unsigned short> vs(num_samples);
+ for (size_t i = 0; i < vs.size(); i++) {
+ // FIXME(syoyo): Currently bps must be same for all samples
+ if (bps != values[i]) {
+ err_ += "BitsPerSample must be same among samples at the moment.\n";
+ return false;
+ }
+
+ vs[i] = values[i];
+
+ // TODO(syoyo): Swap values when writing IFD tag, not here.
+ if (swap_endian_) {
+ swap2(&vs[i]);
+ }
+ }
+
+ unsigned int count = num_samples;
+
+ bool ret = WriteTIFFTag(static_cast<unsigned short>(TIFFTAG_BITS_PER_SAMPLE),
+ TIFF_SHORT, count,
+ reinterpret_cast<const unsigned char *>(vs.data()),
+ &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ // Store BPS for later use.
+ bits_per_sample_ = bps;
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetPhotometric(const unsigned short value) {
+ if ((value == PHOTOMETRIC_LINEARRAW) || (value == PHOTOMETRIC_RGB) ||
+ (value == PHOTOMETRIC_WHITE_IS_ZERO) ||
+ (value == PHOTOMETRIC_BLACK_IS_ZERO)) {
+ // OK
+ } else {
+ return false;
+ }
+
+ unsigned int count = 1;
+
+ const unsigned short data = value;
+ bool ret = WriteTIFFTag(
+ static_cast<unsigned short>(TIFFTAG_PHOTOMETRIC), TIFF_SHORT, count,
+ reinterpret_cast<const unsigned char *>(&data), &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetPlanarConfig(const unsigned short value) {
+ unsigned int count = 1;
+
+ if ((value == PLANARCONFIG_CONTIG) || (value == PLANARCONFIG_SEPARATE)) {
+ // OK
+ } else {
+ return false;
+ }
+
+ const unsigned short data = value;
+ bool ret = WriteTIFFTag(
+ static_cast<unsigned short>(TIFFTAG_PLANAR_CONFIG), TIFF_SHORT, count,
+ reinterpret_cast<const unsigned char *>(&data), &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetCompression(const unsigned short value) {
+ unsigned int count = 1;
+
+ if ((value == COMPRESSION_NONE)) {
+ // OK
+ } else {
+ return false;
+ }
+
+ const unsigned short data = value;
+ bool ret = WriteTIFFTag(
+ static_cast<unsigned short>(TIFFTAG_COMPRESSION), TIFF_SHORT, count,
+ reinterpret_cast<const unsigned char *>(&data), &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetSampleFormat(const unsigned int num_samples,
+ const unsigned short *values) {
+ // `SetSamplesPerPixel()` must be called in advance
+ if ((num_samples > 0) && (num_samples == samples_per_pixels_)) {
+ // OK
+ } else {
+ err_ += "SetSamplesPerPixel() must be called before SetSampleFormat().\n";
+ return false;
+ }
+
+ unsigned short format = values[0];
+
+ std::vector<unsigned short> vs(num_samples);
+ for (size_t i = 0; i < vs.size(); i++) {
+ // FIXME(syoyo): Currently format must be same for all samples
+ if (format != values[i]) {
+ err_ += "SampleFormat must be same among samples at the moment.\n";
+ return false;
+ }
+
+ if ((format == SAMPLEFORMAT_UINT) || (format == SAMPLEFORMAT_INT) ||
+ (format == SAMPLEFORMAT_IEEEFP)) {
+ // OK
+ } else {
+ err_ += "Invalid format value specified for SetSampleFormat().\n";
+ return false;
+ }
+
+ vs[i] = values[i];
+
+ // TODO(syoyo): Swap values when writing IFD tag, not here.
+ if (swap_endian_) {
+ swap2(&vs[i]);
+ }
+ }
+
+ unsigned int count = num_samples;
+
+ bool ret = WriteTIFFTag(static_cast<unsigned short>(TIFFTAG_SAMPLEFORMAT),
+ TIFF_SHORT, count,
+ reinterpret_cast<const unsigned char *>(vs.data()),
+ &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetOrientation(const unsigned short value) {
+ unsigned int count = 1;
+
+ if ((value == ORIENTATION_TOPLEFT) || (value == ORIENTATION_TOPRIGHT) ||
+ (value == ORIENTATION_BOTRIGHT) || (value == ORIENTATION_BOTLEFT) ||
+ (value == ORIENTATION_LEFTTOP) || (value == ORIENTATION_RIGHTTOP) ||
+ (value == ORIENTATION_RIGHTBOT) || (value == ORIENTATION_LEFTBOT)) {
+ // OK
+ } else {
+ return false;
+ }
+
+ const unsigned int data = value;
+ bool ret = WriteTIFFTag(
+ static_cast<unsigned short>(TIFFTAG_ORIENTATION), TIFF_SHORT, count,
+ reinterpret_cast<const unsigned char *>(&data), &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetBlackLevelRational(unsigned int num_samples,
+ const double *values) {
+ // `SetSamplesPerPixel()` must be called in advance and SPP shoud be equal to
+ // `num_samples`.
+ if ((num_samples > 0) && (num_samples == samples_per_pixels_)) {
+ // OK
+ } else {
+ return false;
+ }
+
+ std::vector<unsigned int> vs(num_samples * 2);
+ for (size_t i = 0; i < vs.size(); i++) {
+ double numerator, denominator;
+ if (DoubleToRational(values[i], &numerator, &denominator) != 0) {
+ // Couldn't represent fp value as integer rational value.
+ return false;
+ }
+
+ vs[2 * i + 0] = static_cast<unsigned int>(numerator);
+ vs[2 * i + 1] = static_cast<unsigned int>(denominator);
+
+ // TODO(syoyo): Swap rational value(8 bytes) when writing IFD tag, not here.
+ if (swap_endian_) {
+ swap4(&vs[2 * i + 0]);
+ swap4(&vs[2 * i + 1]);
+ }
+ }
+
+ unsigned int count = num_samples;
+
+ bool ret = WriteTIFFTag(static_cast<unsigned short>(TIFFTAG_BLACK_LEVEL),
+ TIFF_RATIONAL, count,
+ reinterpret_cast<const unsigned char *>(vs.data()),
+ &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetWhiteLevelRational(unsigned int num_samples,
+ const double *values) {
+ // `SetSamplesPerPixel()` must be called in advance and SPP shoud be equal to
+ // `num_samples`.
+ if ((num_samples > 0) && (num_samples == samples_per_pixels_)) {
+ // OK
+ } else {
+ return false;
+ }
+
+ std::vector<unsigned int> vs(num_samples * 2);
+ for (size_t i = 0; i < vs.size(); i++) {
+ double numerator, denominator;
+ if (DoubleToRational(values[i], &numerator, &denominator) != 0) {
+ // Couldn't represent fp value as integer rational value.
+ return false;
+ }
+
+ vs[2 * i + 0] = static_cast<unsigned int>(numerator);
+ vs[2 * i + 1] = static_cast<unsigned int>(denominator);
+
+ // TODO(syoyo): Swap rational value(8 bytes) when writing IFD tag, not here.
+ if (swap_endian_) {
+ swap4(&vs[2 * i + 0]);
+ swap4(&vs[2 * i + 1]);
+ }
+ }
+
+ unsigned int count = num_samples;
+
+ bool ret = WriteTIFFTag(static_cast<unsigned short>(TIFFTAG_WHITE_LEVEL),
+ TIFF_RATIONAL, count,
+ reinterpret_cast<const unsigned char *>(vs.data()),
+ &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetXResolution(const double value) {
+ double numerator, denominator;
+ if (DoubleToRational(value, &numerator, &denominator) != 0) {
+ // Couldn't represent fp value as integer rational value.
+ return false;
+ }
+
+ unsigned int data[2];
+ data[0] = static_cast<unsigned int>(numerator);
+ data[1] = static_cast<unsigned int>(denominator);
+
+ // TODO(syoyo): Swap rational value(8 bytes) when writing IFD tag, not here.
+ if (swap_endian_) {
+ swap4(&data[0]);
+ swap4(&data[1]);
+ }
+
+ bool ret = WriteTIFFTag(
+ static_cast<unsigned short>(TIFFTAG_XRESOLUTION), TIFF_RATIONAL, 1,
+ reinterpret_cast<const unsigned char *>(data), &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetYResolution(const double value) {
+ double numerator, denominator;
+ if (DoubleToRational(value, &numerator, &denominator) != 0) {
+ // Couldn't represent fp value as integer rational value.
+ return false;
+ }
+
+ unsigned int data[2];
+ data[0] = static_cast<unsigned int>(numerator);
+ data[1] = static_cast<unsigned int>(denominator);
+
+ // TODO(syoyo): Swap rational value(8 bytes) when writing IFD tag, not here.
+ if (swap_endian_) {
+ swap4(&data[0]);
+ swap4(&data[1]);
+ }
+
+ bool ret = WriteTIFFTag(
+ static_cast<unsigned short>(TIFFTAG_YRESOLUTION), TIFF_RATIONAL, 1,
+ reinterpret_cast<const unsigned char *>(data), &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetResolutionUnit(const unsigned short value) {
+ unsigned int count = 1;
+
+ if ((value == RESUNIT_NONE) || (value == RESUNIT_INCH) ||
+ (value == RESUNIT_CENTIMETER)) {
+ // OK
+ } else {
+ return false;
+ }
+
+ const unsigned short data = value;
+ bool ret = WriteTIFFTag(
+ static_cast<unsigned short>(TIFFTAG_RESOLUTION_UNIT), TIFF_SHORT, count,
+ reinterpret_cast<const unsigned char *>(&data), &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetImageDescription(const std::string &ascii) {
+ unsigned int count =
+ static_cast<unsigned int>(ascii.length() + 1); // +1 for '\0'
+
+ if (count < 2) {
+ // empty string
+ return false;
+ }
+
+ if (count > (1024 * 1024)) {
+ // too large
+ return false;
+ }
+
+ bool ret = WriteTIFFTag(static_cast<unsigned short>(TIFFTAG_IMAGEDESCRIPTION),
+ TIFF_ASCII, count,
+ reinterpret_cast<const unsigned char *>(ascii.data()),
+ &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetActiveArea(const unsigned int values[4]) {
+ unsigned int count = 4;
+
+ const unsigned int *data = values;
+ bool ret = WriteTIFFTag(
+ static_cast<unsigned short>(TIFFTAG_ACTIVE_AREA), TIFF_LONG, count,
+ reinterpret_cast<const unsigned char *>(data), &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetImageData(const unsigned char *data, const size_t data_len) {
+ if ((data == NULL) || (data_len < 1)) {
+ return false;
+ }
+
+ data_strip_offset_ = size_t(data_os_.tellp());
+ data_strip_bytes_ = data_len;
+
+ data_os_.write(reinterpret_cast<const char *>(data),
+ static_cast<std::streamsize>(data_len));
+
+ // NOTE: STRIP_OFFSET tag will be written at `WriteIFDToStream()`.
+
+ {
+ unsigned int count = 1;
+ unsigned int bytes = static_cast<unsigned int>(data_len);
+
+ bool ret = WriteTIFFTag(
+ static_cast<unsigned short>(TIFFTAG_STRIP_BYTE_COUNTS), TIFF_LONG,
+ count, reinterpret_cast<const unsigned char *>(&bytes), &ifd_tags_,
+ NULL);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ }
+
+ return true;
+}
+
+bool DNGImage::SetCustomFieldLong(const unsigned short tag, const int value) {
+ unsigned int count = 1;
+
+ // TODO(syoyo): Check if `tag` value does not conflict with existing TIFF tag
+ // value.
+
+ bool ret = WriteTIFFTag(tag, TIFF_SLONG, count,
+ reinterpret_cast<const unsigned char *>(&value),
+ &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+bool DNGImage::SetCustomFieldULong(const unsigned short tag,
+ const unsigned int value) {
+ unsigned int count = 1;
+
+ // TODO(syoyo): Check if `tag` value does not conflict with existing TIFF tag
+ // value.
+
+ bool ret = WriteTIFFTag(tag, TIFF_LONG, count,
+ reinterpret_cast<const unsigned char *>(&value),
+ &ifd_tags_, &data_os_);
+
+ if (!ret) {
+ return false;
+ }
+
+ num_fields_++;
+ return true;
+}
+
+static bool IFDComparator(const IFDTag &a, const IFDTag &b) {
+ return (a.tag < b.tag);
+}
+
+bool DNGImage::WriteDataToStream(std::ostream *ofs, std::string *err) const {
+ if ((data_os_.str().length() == 0)) {
+ if (err) {
+ (*err) += "Empty IFD data and image data.\n";
+ }
+ return false;
+ }
+
+ if ((bits_per_sample_ == 0) || (samples_per_pixels_ == 0)) {
+ if (err) {
+ (*err) += "Both BitsPerSample and SamplesPerPixels must be set.\n";
+ }
+ return false;
+ }
+
+ std::vector<uint8_t> data(data_os_.str().length());
+ memcpy(data.data(), data_os_.str().data(), data.size());
+
+ if (data_strip_bytes_ == 0) {
+ // May ok?.
+ } else {
+ // FIXME(syoyo): Assume all channels use sample bps
+
+ // We may need to swap endian for pixel data.
+ if (swap_endian_) {
+ if (bits_per_sample_ == 16) {
+ size_t n = data_strip_bytes_ / sizeof(uint16_t);
+ uint16_t *ptr =
+ reinterpret_cast<uint16_t *>(data.data() + data_strip_offset_);
+
+ for (size_t i = 0; i < n; i++) {
+ swap2(&ptr[i]);
+ }
+
+ } else if (bits_per_sample_ == 32) {
+ size_t n = data_strip_bytes_ / sizeof(uint32_t);
+ uint32_t *ptr =
+ reinterpret_cast<uint32_t *>(data.data() + data_strip_offset_);
+
+ for (size_t i = 0; i < n; i++) {
+ swap4(&ptr[i]);
+ }
+
+ } else if (bits_per_sample_ == 64) {
+ size_t n = data_strip_bytes_ / sizeof(uint64_t);
+ uint64_t *ptr =
+ reinterpret_cast<uint64_t *>(data.data() + data_strip_offset_);
+
+ for (size_t i = 0; i < n; i++) {
+ swap8(&ptr[i]);
+ }
+ }
+ }
+ }
+
+ ofs->write(reinterpret_cast<const char *>(data.data()),
+ static_cast<std::streamsize>(data.size()));
+
+ return true;
+}
+
+bool DNGImage::WriteIFDToStream(const unsigned int data_base_offset,
+ const unsigned int strip_offset,
+ std::ostream *ofs, std::string *err) const {
+ if ((num_fields_ == 0) || (ifd_tags_.size() < 1)) {
+ if (err) {
+ (*err) += "No TIFF Tags.\n";
+ }
+ return false;
+ }
+
+ // add STRIP_OFFSET tag and sort IFD tags.
+ std::vector<IFDTag> tags = ifd_tags_;
+ {
+ // For STRIP_OFFSET we need the actual offset value to data(image),
+ // thus write STRIP_OFFSET here.
+ unsigned int offset = strip_offset + kHeaderSize;
+ IFDTag ifd;
+ ifd.tag = TIFFTAG_STRIP_OFFSET;
+ ifd.type = TIFF_LONG;
+ ifd.count = 1;
+ ifd.offset_or_value = offset;
+ tags.push_back(ifd);
+ }
+
+ // TIFF expects IFD tags are sorted.
+ std::sort(tags.begin(), tags.end(), IFDComparator);
+
+ std::ostringstream ifd_os;
+
+ unsigned short num_fields = static_cast<unsigned short>(tags.size());
+
+ Write2(num_fields, &ifd_os, swap_endian_);
+
+ {
+ size_t typesize_table[] = {1, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4};
+
+ for (size_t i = 0; i < tags.size(); i++) {
+ const IFDTag &ifd = tags[i];
+ Write2(ifd.tag, &ifd_os, swap_endian_);
+ Write2(ifd.type, &ifd_os, swap_endian_);
+ Write4(ifd.count, &ifd_os, swap_endian_);
+
+ size_t len =
+ ifd.count * (typesize_table[(ifd.type) < 14 ? (ifd.type) : 0]);
+ if (len > 4) {
+ // Store offset value.
+ unsigned int ifd_offt = ifd.offset_or_value + data_base_offset;
+ Write4(ifd_offt, &ifd_os, swap_endian_);
+ } else {
+ // less than 4 bytes = store data itself.
+
+ if (len == 1) {
+ const unsigned char value =
+ *(reinterpret_cast<const unsigned char *>(&ifd.offset_or_value));
+ Write1(value, &ifd_os);
+ unsigned char pad = 0;
+ Write1(pad, &ifd_os);
+ Write1(pad, &ifd_os);
+ Write1(pad, &ifd_os);
+ } else if (len == 2) {
+ const unsigned short value =
+ *(reinterpret_cast<const unsigned short *>(&ifd.offset_or_value));
+ Write2(value, &ifd_os, swap_endian_);
+ const unsigned short pad = 0;
+ Write2(pad, &ifd_os, swap_endian_);
+ } else if (len == 4) {
+ const unsigned int value =
+ *(reinterpret_cast<const unsigned int *>(&ifd.offset_or_value));
+ Write4(value, &ifd_os, swap_endian_);
+ } else {
+ assert(0);
+ }
+ }
+ }
+
+ ofs->write(ifd_os.str().c_str(),
+ static_cast<std::streamsize>(ifd_os.str().length()));
+ }
+
+ return true;
+}
+
+// -------------------------------------------
+
+DNGWriter::DNGWriter(bool big_endian) : dng_big_endian_(big_endian) {
+ swap_endian_ = (IsBigEndian() != dng_big_endian_);
+}
+
+bool DNGWriter::WriteToFile(const char *filename, std::string *err) const {
+ std::ofstream ofs(filename, std::ostream::binary);
+
+ if (!ofs) {
+ if (err) {
+ (*err) = "Failed to open file.\n";
+ }
+
+ return false;
+ }
+
+ std::ostringstream header;
+ bool ret = WriteTIFFVersionHeader(&header, dng_big_endian_);
+ if (!ret) {
+ return false;
+ }
+
+ if (images_.size() == 0) {
+ if (err) {
+ (*err) = "No image added for writing.\n";
+ }
+
+ return false;
+ }
+
+ // 1. Compute offset and data size(exclude TIFF header bytes)
+ size_t data_len = 0;
+ size_t strip_offset = 0;
+ std::vector<size_t> data_offset_table;
+ std::vector<size_t> strip_offset_table;
+ for (size_t i = 0; i < images_.size(); i++) {
+ strip_offset = data_len + images_[i]->GetStripOffset();
+ data_offset_table.push_back(data_len);
+ strip_offset_table.push_back(strip_offset);
+ data_len += images_[i]->GetDataSize();
+ }
+
+ // 2. Write offset to ifd table.
+ const unsigned int ifd_offset =
+ kHeaderSize + static_cast<unsigned int>(data_len);
+ Write4(ifd_offset, &header, swap_endian_);
+
+ assert(header.str().length() == 8);
+
+ // std::cout << "ifd_offset " << ifd_offset << std::endl;
+ // std::cout << "data_len " << data_os_.str().length() << std::endl;
+ // std::cout << "ifd_len " << ifd_os_.str().length() << std::endl;
+ // std::cout << "swap endian " << swap_endian_ << std::endl;
+
+ // 3. Write header
+ ofs.write(header.str().c_str(),
+ static_cast<std::streamsize>(header.str().length()));
+
+ // 4. Write image and meta data
+ // TODO(syoyo): Write IFD first, then image/meta data
+ for (size_t i = 0; i < images_.size(); i++) {
+ bool ok = images_[i]->WriteDataToStream(&ofs, err);
+ if (!ok) {
+ return false;
+ }
+ }
+
+ // 5. Write IFD entries;
+ for (size_t i = 0; i < images_.size(); i++) {
+ bool ok = images_[i]->WriteIFDToStream(
+ static_cast<unsigned int>(data_offset_table[i]),
+ static_cast<unsigned int>(strip_offset_table[i]), &ofs, err);
+ if (!ok) {
+ return false;
+ }
+
+ unsigned int next_ifd_offset =
+ static_cast<unsigned int>(ofs.tellp()) + sizeof(unsigned int);
+
+ if (i == (images_.size() - 1)) {
+ // Write zero as IFD offset(= end of data)
+ next_ifd_offset = 0;
+ }
+
+ if (swap_endian_) {
+ swap4(&next_ifd_offset);
+ }
+
+ ofs.write(reinterpret_cast<const char *>(&next_ifd_offset), 4);
+ }
+
+ return true;
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+} // namespace tinydngwriter
+
+#endif // TINY_DNG_WRITER_IMPLEMENTATION
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exr2ldr/Makefile b/graphics/asymptote/cudareflect/tinyexr/examples/exr2ldr/Makefile
new file mode 100644
index 0000000000..532212ee4a
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exr2ldr/Makefile
@@ -0,0 +1,3 @@
+all:
+ clang -g -O2 -c -I../../deps/miniz ../../deps/miniz/miniz.c
+ clang++ -g -fsanitize=address -O2 -o exr2ldr -I../common -I../../ -I../../deps/miniz exr2ldr.cc ../../tinyexr.cc miniz.o
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exr2ldr/exr2ldr.cc b/graphics/asymptote/cudareflect/tinyexr/examples/exr2ldr/exr2ldr.cc
new file mode 100644
index 0000000000..a401211cb5
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exr2ldr/exr2ldr.cc
@@ -0,0 +1,111 @@
+#include <cstdio>
+#include <cstdlib>
+#include <vector>
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+#endif
+
+#define STB_IMAGE_RESIZE_IMPLEMENTATION
+#include "stb_image_resize.h"
+
+#define STB_IMAGE_WRITE_IMPLEMENTATION
+#include "stb_image_write.h"
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include "tinyexr.h"
+
+inline unsigned char ftouc(float f, float gamma)
+{
+ int i = static_cast<int>(255.0f * powf(f, 1.0f / gamma));
+ if (i > 255) i = 255;
+ if (i < 0) i = 0;
+
+ return static_cast<unsigned char>(i);
+}
+
+bool SaveImage(const char* filename, const float* rgba, float scale, float gamma, int width, int height, bool ignore_alpha) {
+
+ std::vector<unsigned char> dst(width * height * 4);
+
+ // alpha channel is also affected by `scale` parameter.
+ if(ignore_alpha) {
+ for (size_t i = 0; i < width * height; i++) {
+ dst[i * 4 + 0] = ftouc(rgba[i * 4 + 0] * scale, gamma);
+ dst[i * 4 + 1] = ftouc(rgba[i * 4 + 1] * scale, gamma);
+ dst[i * 4 + 2] = ftouc(rgba[i * 4 + 2] * scale, gamma);
+ dst[i * 4 + 3] = 255;
+ }
+ } else {
+ for (size_t i = 0; i < width * height * 4; i++) {
+ dst[i] = ftouc(rgba[i] * scale, gamma);
+ }
+ }
+
+ int ret = stbi_write_png(filename, width, height, 4, static_cast<const void*>(dst.data()), width * 4);
+
+ return (ret > 0);
+}
+
+int main(int argc, char** argv)
+{
+ if (argc < 3) {
+ printf("Usage: exr2ldr input.exr output.png (scale) (resize_factor) (gammavalue) (-i or --ignore-alpha).\n");
+ printf(" Pixel value [0.0, 1.0] in EXR is mapped to [0, 255] for LDR image.\n");
+ printf(" You can adjust pixel value by `scale`(default = 1.0).\n");
+ printf(" Resize image using `resize_factor`(default = 1.0). 2 = create half size image, 4 = 1/4 image, and so on\n");
+ printf(" gammmavalue will be used for gamma correction when saving png image(default = 2.2).\n");
+ printf(" Ignore alpha value of input using -i or --ignore-alpha flag, and alpha of output is set to 255.\n");
+ exit(-1);
+ }
+
+ float scale = 1.0f;
+ if (argc > 3) {
+ scale = atof(argv[3]);
+ }
+
+ float resize_factor = 1.0f;
+ if (argc > 4) {
+ resize_factor = atof(argv[4]);
+ }
+
+ float gamma = 2.2f;
+ if (argc > 5) {
+ gamma = atof(argv[5]);
+ }
+
+ bool ignore_alpha = false;
+ if (argc > 6 && (strcmp(argv[6], "-i") == 0 || strcmp(argv[6], "--ignore-alpha") == 0)) {
+ ignore_alpha = true;
+ }
+
+ int width, height;
+ float* rgba;
+ const char* err;
+
+ {
+ int ret = LoadEXR(&rgba, &width, &height, argv[1], &err);
+ if (ret != 0) {
+ printf("err: %s\n", err);
+ return -1;
+ }
+ }
+
+ int dst_width = width / resize_factor;
+ int dst_height = height / resize_factor;
+ printf("dst = %d, %d\n", dst_width, dst_height);
+
+ std::vector<float> buf(dst_width * dst_height * 4);
+ int ret = stbir_resize_float(rgba, width, height, width*4*sizeof(float), &buf.at(0), dst_width, dst_height,dst_width*4*sizeof(float), 4);
+ assert(ret != 0);
+
+ bool ok = SaveImage(argv[2], &buf.at(0), scale, gamma, dst_width, dst_height, ignore_alpha);
+
+ free(rgba);
+
+ return (ok ? 0 : -1);
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exr2rgbe/Makefile b/graphics/asymptote/cudareflect/tinyexr/examples/exr2rgbe/Makefile
new file mode 100644
index 0000000000..f0356eb491
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exr2rgbe/Makefile
@@ -0,0 +1,3 @@
+all:
+ gcc -O2 -c -I../../deps/miniz ../../deps/miniz/miniz.c
+ g++ -O2 -o exr2rgbe -I../common -I../../ -I../../deps/miniz exr2rgbe.cc ../../tinyexr.cc miniz.o
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exr2rgbe/exr2rgbe.cc b/graphics/asymptote/cudareflect/tinyexr/examples/exr2rgbe/exr2rgbe.cc
new file mode 100644
index 0000000000..2631590488
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exr2rgbe/exr2rgbe.cc
@@ -0,0 +1,38 @@
+#include <cstdio>
+#include <cstdlib>
+#include <vector>
+
+#define STB_IMAGE_WRITE_IMPLEMENTATION
+#include "stb_image_write.h"
+
+#include "tinyexr.h"
+
+int main(int argc, char** argv)
+{
+ if (argc < 3) {
+ printf("Usage: exr2rgbe input.exr output.hdr\n");
+ exit(-1);
+ }
+
+ int width, height;
+ float* rgba;
+ const char* err;
+
+ {
+ int ret = LoadEXR(&rgba, &width, &height, argv[1], &err);
+ if (ret != 0) {
+ printf("err: %s\n", err);
+ return -1;
+ }
+ }
+
+ {
+ int ret = stbi_write_hdr(argv[2], width, height, 4, rgba);
+
+ if (ret == 0) {
+ return -1; // fail
+ }
+ }
+
+ return 0;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/Makefile b/graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/Makefile
new file mode 100644
index 0000000000..c2e740ce0d
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/Makefile
@@ -0,0 +1,3 @@
+all:
+ gcc -O2 -c -I../../deps/miniz ../../deps/miniz/miniz.c
+ g++ -std=c++11 -O2 -o exrfilter -I../common -I../../ -I ../../deps/miniz exrfilter.cc ../../tinyexr.cc miniz.o
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/README.md b/graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/README.md
new file mode 100644
index 0000000000..8317ac1bad
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/README.md
@@ -0,0 +1,5 @@
+Simple EXR filtering program.
+
+Currently implemented are
+
+- Clip min/max intensity(RGB)
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/exrfilter.cc b/graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/exrfilter.cc
new file mode 100644
index 0000000000..b766c1d622
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrfilter/exrfilter.cc
@@ -0,0 +1,150 @@
+#include <cstdio>
+#include <cstdlib>
+#include <vector>
+
+#include "tinyexr.h"
+
+#include "cxxopts.hpp"
+
+int main(int argc, char** argv)
+{
+
+ float min_value = -std::numeric_limits<float>::max();
+ float max_value = std::numeric_limits<float>::max();
+
+ float rgb_min[3] = {min_value, min_value, min_value};
+ float rgb_max[3] = {max_value, max_value, max_value};
+
+ cxxopts::Options options("normalmap", "help");
+ options.show_positional_help();
+
+ options.add_options()
+ ("max", "Max intensity(apply all RGB channels)", cxxopts::value<float>())
+ ("rmax", "Max Red intensity", cxxopts::value<float>())
+ ("gmax", "Max Green intensity", cxxopts::value<float>())
+ ("bmax", "Max Blue intensity", cxxopts::value<float>())
+ ("min", "Min intensity(apply all RGB channels)", cxxopts::value<float>())
+ ("rmin", "Min Red intensity", cxxopts::value<float>())
+ ("gmin", "Min Green intensity", cxxopts::value<float>())
+ ("bmin", "Min Blue intensity", cxxopts::value<float>())
+ ("i,input", "Input filename", cxxopts::value<std::string>())
+ ("o,output", "Output filename", cxxopts::value<std::string>())
+ ("help", "Print help")
+ ;
+
+ auto result = options.parse(argc, argv);
+
+ if (result.count("help")) {
+ std::cout << options.help() << std::endl;
+ }
+
+ if (result.count("input") == 0) {
+ std::cerr << "input filename missing" << std::endl;
+ std::cout << options.help() << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ if (result.count("output") == 0) {
+ std::cerr << "output filename missing" << std::endl;
+ std::cout << options.help() << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ std::string input_filename = result["input"].as<std::string>();
+ std::string output_filename = result["output"].as<std::string>();
+
+
+ if (result.count("max")) {
+ rgb_max[0] = result["max"].as<float>();
+ rgb_max[1] = result["max"].as<float>();
+ rgb_max[2] = result["max"].as<float>();
+ }
+ if (result.count("rmax")) {
+ rgb_max[0] = result["rmax"].as<float>();
+ }
+ if (result.count("gmax")) {
+ rgb_max[1] = result["gmax"].as<float>();
+ }
+ if (result.count("bmax")) {
+ rgb_max[2] = result["bmax"].as<float>();
+ }
+
+ if (result.count("min")) {
+ rgb_min[0] = result["min"].as<float>();
+ rgb_min[1] = result["min"].as<float>();
+ rgb_min[2] = result["min"].as<float>();
+ }
+ if (result.count("rmin")) {
+ rgb_min[0] = result["rmin"].as<float>();
+ }
+ if (result.count("gmin")) {
+ rgb_min[1] = result["gmin"].as<float>();
+ }
+ if (result.count("bmin")) {
+ rgb_min[2] = result["bmin"].as<float>();
+ }
+
+ float *rgba = nullptr;
+ int width, height;
+ const char *err = nullptr;
+ {
+ int ret = LoadEXR(&rgba, &width, &height, input_filename.c_str(), &err);
+ if (TINYEXR_SUCCESS != ret) {
+ std::cerr << "Failed to load EXR file [" << input_filename << "] code = " << ret << std::endl;
+ if (err) {
+ std::cerr << err << std::endl;
+ FreeEXRErrorMessage(err);
+ }
+
+ return EXIT_FAILURE;
+ }
+ }
+
+ // clip pixel values.
+ // ignore alpha channel for now.
+ std::vector<float> rgb;
+ rgb.resize(width * height * 3);
+
+ float v_max[3] = {
+ -std::numeric_limits<float>::max(),
+ -std::numeric_limits<float>::max(),
+ -std::numeric_limits<float>::max()};
+ float v_min[3] = {
+ std::numeric_limits<float>::max(),
+ std::numeric_limits<float>::max(),
+ std::numeric_limits<float>::max()};
+
+ {
+ for (size_t i = 0; i < width * height; i++) {
+ rgb[3 * i + 0] = std::max(rgb_min[0], std::min(rgb_max[0], rgba[4 * i + 0]));
+ rgb[3 * i + 1] = std::max(rgb_min[1], std::min(rgb_max[1], rgba[4 * i + 1]));
+ rgb[3 * i + 2] = std::max(rgb_min[2], std::min(rgb_max[2], rgba[4 * i + 2]));
+
+ v_max[0] = std::max(rgb[3 * i + 0], v_max[0]);
+ v_max[1] = std::max(rgb[3 * i + 1], v_max[1]);
+ v_max[2] = std::max(rgb[3 * i + 2], v_max[2]);
+
+ v_min[0] = std::min(rgb[3 * i + 0], v_min[0]);
+ v_min[1] = std::min(rgb[3 * i + 1], v_min[1]);
+ v_min[2] = std::min(rgb[3 * i + 2], v_min[2]);
+
+ }
+ }
+
+ std::cout << "v min = " << v_min[0] << ", " << v_min[1] << ", " << v_min[2] << std::endl;
+ std::cout << "v max = " << v_max[0] << ", " << v_max[1] << ", " << v_max[2] << std::endl;
+
+ {
+ int ret = SaveEXR(rgb.data(), width, height, /* component */3, /* fp16 */0, output_filename.c_str(), &err);
+ if (TINYEXR_SUCCESS != ret) {
+ if (err) {
+ std::cerr << err << std::endl;
+ FreeEXRErrorMessage(err);
+ }
+ std::cerr << "Failed to save EXR file [" << input_filename << "] code = " << ret << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/DroidSans.ttf b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/DroidSans.ttf
new file mode 100644
index 0000000000..767c63ad00
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/DroidSans.ttf
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/CommonWindowInterface.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/CommonWindowInterface.h
new file mode 100644
index 0000000000..346fdac72a
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/CommonWindowInterface.h
@@ -0,0 +1,130 @@
+#ifndef B3G_WINDOW_INTERFACE_H
+#define B3G_WINDOW_INTERFACE_H
+
+
+typedef void (*b3WheelCallback)(float deltax, float deltay);
+typedef void (*b3ResizeCallback)( float width, float height);
+typedef void (*b3MouseMoveCallback)( float x, float y);
+typedef void (*b3MouseButtonCallback)(int button, int state, float x, float y);
+typedef void (*b3KeyboardCallback)(int keycode, int state);
+typedef void (*b3RenderCallback) ();
+
+enum {
+ B3G_ESCAPE = 27,
+ B3G_F1 = 0xff00,
+ B3G_F2,
+ B3G_F3,
+ B3G_F4,
+ B3G_F5,
+ B3G_F6,
+ B3G_F7,
+ B3G_F8,
+ B3G_F9,
+ B3G_F10,
+ B3G_F11,
+ B3G_F12,
+ B3G_F13,
+ B3G_F14,
+ B3G_F15,
+ B3G_LEFT_ARROW,
+ B3G_RIGHT_ARROW,
+ B3G_UP_ARROW,
+ B3G_DOWN_ARROW,
+ B3G_PAGE_UP,
+ B3G_PAGE_DOWN,
+ B3G_END,
+ B3G_HOME,
+ B3G_INSERT,
+ B3G_DELETE,
+ B3G_BACKSPACE,
+ B3G_SHIFT,
+ B3G_CONTROL,
+ B3G_ALT,
+ B3G_RETURN
+};
+
+struct b3gWindowConstructionInfo
+{
+ int m_width;
+ int m_height;
+ bool m_fullscreen;
+ int m_colorBitsPerPixel;
+ void* m_windowHandle;
+ const char* m_title;
+ int m_openglVersion;
+
+
+ b3gWindowConstructionInfo(int width=1024, int height=768)
+ :m_width(width),
+ m_height(height),
+ m_fullscreen(false),
+ m_colorBitsPerPixel(32),
+ m_windowHandle(0),
+ m_title("title"),
+ m_openglVersion(3)
+ {
+ }
+};
+
+
+class CommonWindowInterface
+{
+ public:
+
+ virtual ~CommonWindowInterface()
+ {
+ }
+
+ virtual void createDefaultWindow(int width, int height, const char* title)
+ {
+ b3gWindowConstructionInfo ci(width,height);
+ ci.m_title = title;
+ createWindow(ci);
+ }
+
+ virtual void createWindow(const b3gWindowConstructionInfo& ci)=0;
+
+ virtual void closeWindow()=0;
+
+ virtual void runMainLoop()=0;
+ virtual float getTimeInSeconds()=0;
+
+ virtual bool requestedExit() const = 0;
+ virtual void setRequestExit() = 0;
+
+ virtual void startRendering()=0;
+
+ virtual void endRendering()=0;
+
+ virtual bool isModifierKeyPressed(int key) = 0;
+
+ virtual void setMouseMoveCallback(b3MouseMoveCallback mouseCallback)=0;
+ virtual b3MouseMoveCallback getMouseMoveCallback()=0;
+
+ virtual void setMouseButtonCallback(b3MouseButtonCallback mouseCallback)=0;
+ virtual b3MouseButtonCallback getMouseButtonCallback()=0;
+
+ virtual void setResizeCallback(b3ResizeCallback resizeCallback)=0;
+ virtual b3ResizeCallback getResizeCallback()=0;
+
+ virtual void setWheelCallback(b3WheelCallback wheelCallback)=0;
+ virtual b3WheelCallback getWheelCallback()=0;
+
+ virtual void setKeyboardCallback( b3KeyboardCallback keyboardCallback)=0;
+ virtual b3KeyboardCallback getKeyboardCallback()=0;
+
+ virtual void setRenderCallback( b3RenderCallback renderCallback) = 0;
+
+ virtual void setWindowTitle(const char* title)=0;
+
+ virtual float getRetinaScale() const =0;
+ virtual void setAllowRetina(bool allow) =0;
+
+ virtual int getWidth() const = 0;
+ virtual int getHeight() const = 0;
+
+ virtual int fileOpenDialog(char* fileName, int maxFileNameLength) = 0;
+
+};
+
+#endif //B3G_WINDOW_INTERFACE_H \ No newline at end of file
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/MacOpenGLWindow.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/MacOpenGLWindow.h
new file mode 100644
index 0000000000..0d61f67567
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/MacOpenGLWindow.h
@@ -0,0 +1,118 @@
+#ifndef MAC_OPENGL_WINDOW_H
+#define MAC_OPENGL_WINDOW_H
+
+#include "CommonWindowInterface.h"
+
+#define b3gDefaultOpenGLWindow MacOpenGLWindow
+
+class MacOpenGLWindow : public CommonWindowInterface
+{
+ struct MacOpenGLWindowInternalData* m_internalData;
+ float m_mouseX;
+ float m_mouseY;
+ int m_modifierFlags;
+
+ b3MouseButtonCallback m_mouseButtonCallback;
+ b3MouseMoveCallback m_mouseMoveCallback;
+ b3WheelCallback m_wheelCallback;
+ b3KeyboardCallback m_keyboardCallback;
+ b3RenderCallback m_renderCallback;
+
+ float m_retinaScaleFactor;
+ bool m_allowRetina;
+
+public:
+
+ MacOpenGLWindow();
+ virtual ~MacOpenGLWindow();
+
+ void init(int width, int height, const char* windowTitle);
+
+ void closeWindow();
+
+ void startRendering();
+
+ void endRendering();//swap buffers
+
+ virtual bool requestedExit() const;
+
+ virtual void setRequestExit();
+
+ void getMouseCoordinates(int& x, int& y);
+
+ void runMainLoop();
+
+ virtual bool isModifierKeyPressed(int key);
+
+ void setMouseButtonCallback(b3MouseButtonCallback mouseCallback)
+ {
+ m_mouseButtonCallback = mouseCallback;
+ }
+
+ void setMouseMoveCallback(b3MouseMoveCallback mouseCallback)
+ {
+ m_mouseMoveCallback = mouseCallback;
+ }
+
+ void setResizeCallback(b3ResizeCallback resizeCallback);
+
+
+ void setKeyboardCallback( b3KeyboardCallback keyboardCallback)
+ {
+ m_keyboardCallback = keyboardCallback;
+ }
+
+ virtual b3MouseMoveCallback getMouseMoveCallback()
+ {
+ return m_mouseMoveCallback;
+ }
+ virtual b3MouseButtonCallback getMouseButtonCallback()
+ {
+ return m_mouseButtonCallback;
+ }
+ virtual b3ResizeCallback getResizeCallback();
+
+ virtual b3WheelCallback getWheelCallback()
+ {
+ return m_wheelCallback;
+ }
+
+ b3KeyboardCallback getKeyboardCallback()
+ {
+ return m_keyboardCallback;
+ }
+
+ void setWheelCallback (b3WheelCallback wheelCallback)
+ {
+ m_wheelCallback = wheelCallback;
+ }
+
+ float getRetinaScale() const
+ {
+ return m_retinaScaleFactor;
+ }
+ virtual void setAllowRetina(bool allow)
+ {
+ m_allowRetina = allow;
+ }
+
+ virtual void createWindow(const b3gWindowConstructionInfo& ci);
+
+ virtual float getTimeInSeconds();
+
+
+ virtual int getWidth() const;
+ virtual int getHeight() const;
+
+
+ virtual void setRenderCallback( b3RenderCallback renderCallback);
+
+ virtual void setWindowTitle(const char* title);
+
+ int fileOpenDialog(char* filename, int maxNameLength);
+
+};
+
+
+#endif
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/MacOpenGLWindow.mm b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/MacOpenGLWindow.mm
new file mode 100644
index 0000000000..8cab041af3
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/MacOpenGLWindow.mm
@@ -0,0 +1,1169 @@
+#include "MacOpenGLWindow.h"
+
+#define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
+#import <Cocoa/Cocoa.h>
+#include "OpenGLInclude.h"
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+
+
+enum
+{
+ MY_MAC_ALTKEY=1,
+ MY_MAC_SHIFTKEY=2,
+ MY_MAC_CONTROL_KEY=4
+};
+
+/* report GL errors, if any, to stderr */
+static void checkError(const char *functionName)
+{
+ GLenum error;
+ while (( error = glGetError() ) != GL_NO_ERROR)
+ {
+ fprintf (stderr, "GL error 0x%X detected in %s\n", error, functionName);
+ }
+}
+
+void dumpInfo(void)
+{
+ printf ("Vendor: %s\n", glGetString (GL_VENDOR));
+ printf ("Renderer: %s\n", glGetString (GL_RENDERER));
+ printf ("Version: %s\n", glGetString (GL_VERSION));
+ printf ("GLSL: %s\n", glGetString (GL_SHADING_LANGUAGE_VERSION));
+ checkError ("dumpInfo");
+}
+
+
+
+
+// -------------------- View ------------------------
+
+@interface TestView : NSView
+{
+ NSOpenGLContext* m_context;
+ int m_lastWidth;
+ int m_lastHeight;
+ bool m_requestClose;
+ b3ResizeCallback m_resizeCallback;
+
+}
+-(void)drawRect:(NSRect)rect;
+-(void) MakeContext:(int) openglVersion;
+-(void) MakeCurrent;
+-(float) GetWindowWidth;
+-(float) GetWindowHeight;
+-(BOOL) GetRequestClose;
+- (BOOL)windowShouldClose:(id)sender;
+-(void) setResizeCallback:(b3ResizeCallback) callback;
+-(b3ResizeCallback) getResizeCallback;
+-(NSOpenGLContext*) getContext;
+@end
+
+float loop;
+
+#define Pi 3.1415
+
+@implementation TestView
+
+- (BOOL)windowShouldClose:(id)sender
+{
+ m_requestClose = true;
+ return false;
+}
+-(BOOL) GetRequestClose
+{
+ return m_requestClose;
+}
+-(float) GetWindowWidth
+{
+ return m_lastWidth;
+}
+-(float) GetWindowHeight
+{
+ return m_lastHeight;
+}
+
+-(b3ResizeCallback) getResizeCallback
+{
+ return m_resizeCallback;
+}
+
+-(NSOpenGLContext*) getContext
+{
+ return m_context;
+}
+-(void)setResizeCallback:(b3ResizeCallback)callback
+{
+ m_resizeCallback = callback;
+}
+-(void)drawRect:(NSRect)rect
+{
+ if (([self frame].size.width != m_lastWidth) || ([self frame].size.height != m_lastHeight))
+ {
+ m_lastWidth = [self frame].size.width;
+ m_lastHeight = [self frame].size.height;
+
+ // Only needed on resize:
+ [m_context clearDrawable];
+
+// reshape([self frame].size.width, [self frame].size.height);
+ float width = [self frame].size.width;
+ float height = [self frame].size.height;
+
+
+ // Get view dimensions in pixels
+ // glViewport(0,0,10,10);
+
+ if (m_resizeCallback)
+ {
+ (*m_resizeCallback)(width,height);
+ }
+ #ifndef NO_OPENGL3
+ NSRect backingBounds = [self convertRectToBacking:[self bounds]];
+ GLsizei backingPixelWidth = (GLsizei)(backingBounds.size.width),
+ backingPixelHeight = (GLsizei)(backingBounds.size.height);
+
+ // Set viewport
+ glViewport(0, 0, backingPixelWidth, backingPixelHeight);
+ #else
+ glViewport(0,0,(GLsizei)width,(GLsizei)height);
+#endif
+ }
+
+ [m_context setView: self];
+ [m_context makeCurrentContext];
+
+ // Draw
+ //display();
+
+ [m_context flushBuffer];
+ [NSOpenGLContext clearCurrentContext];
+
+ loop = loop + 0.1;
+}
+
+-(void) MakeContext :(int) openglVersion
+{
+ // NSWindow *w;
+ NSOpenGLPixelFormat *fmt;
+
+ m_requestClose = false;
+
+
+
+#ifndef NO_OPENGL3
+ if (openglVersion==3)
+ {
+ NSOpenGLPixelFormatAttribute attrs[] =
+ {
+ NSOpenGLPFAOpenGLProfile,
+ NSOpenGLProfileVersion3_2Core,
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFADepthSize, 32,
+ NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)8,
+ (NSOpenGLPixelFormatAttribute)0
+ };
+
+ // Init GL context
+ fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: (NSOpenGLPixelFormatAttribute*)attrs];
+ } else
+#endif
+ {
+ NSOpenGLPixelFormatAttribute attrs[] =
+ {
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFADepthSize, 32,
+ NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)8,
+ (NSOpenGLPixelFormatAttribute)0
+ };
+ // Init GL context
+ fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: (NSOpenGLPixelFormatAttribute*)attrs];
+
+ }
+ m_context = [[NSOpenGLContext alloc] initWithFormat: fmt shareContext: nil];
+ [fmt release];
+ [m_context makeCurrentContext];
+
+ checkError("makeCurrentContext");
+}
+
+-(void) MakeCurrent
+{
+ [m_context makeCurrentContext];
+}
+-(void)windowWillClose:(NSNotification *)note
+{
+ [[NSApplication sharedApplication] terminate:self];
+}
+@end
+
+struct MacOpenGLWindowInternalData
+{
+ MacOpenGLWindowInternalData()
+ {
+ m_myApp = 0;
+ m_myview = 0;
+ m_pool = 0;
+ m_window = 0;
+ m_width = -1;
+ m_height = -1;
+ m_exitRequested = false;
+ }
+ NSApplication* m_myApp;
+ TestView* m_myview;
+ NSAutoreleasePool* m_pool;
+ NSWindow* m_window;
+ int m_width;
+ int m_height;
+ bool m_exitRequested;
+
+};
+
+MacOpenGLWindow::MacOpenGLWindow()
+:m_internalData(0),
+m_mouseX(0),
+m_mouseY(0),
+m_modifierFlags(0),
+m_mouseMoveCallback(0),
+m_mouseButtonCallback(0),
+m_wheelCallback(0),
+m_keyboardCallback(0),
+m_retinaScaleFactor(1),
+m_allowRetina(true)
+{
+}
+
+MacOpenGLWindow::~MacOpenGLWindow()
+{
+ if (m_internalData)
+ closeWindow();
+}
+
+
+bool MacOpenGLWindow::isModifierKeyPressed(int key)
+{
+ bool isPressed = false;
+
+ switch (key)
+ {
+ case B3G_ALT:
+ {
+ isPressed = ((m_modifierFlags & MY_MAC_ALTKEY)!=0);
+ break;
+ };
+ case B3G_SHIFT:
+ {
+ isPressed = ((m_modifierFlags & MY_MAC_SHIFTKEY)!=0);
+ break;
+ };
+ case B3G_CONTROL:
+ {
+ isPressed = ((m_modifierFlags & MY_MAC_CONTROL_KEY )!=0);
+ break;
+ };
+
+ default:
+ {
+ }
+ };
+ return isPressed;
+}
+
+float MacOpenGLWindow::getTimeInSeconds()
+{
+ return 0.f;
+}
+
+
+void MacOpenGLWindow::setRenderCallback( b3RenderCallback renderCallback)
+{
+ m_renderCallback = renderCallback;
+}
+
+void MacOpenGLWindow::setWindowTitle(const char* windowTitle)
+{
+ [m_internalData->m_window setTitle:[NSString stringWithCString:windowTitle encoding:NSISOLatin1StringEncoding]] ;
+}
+
+void MacOpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci)
+{
+ if (m_internalData)
+ closeWindow();
+
+ int width = ci.m_width;
+ int height = ci.m_height;
+ const char* windowTitle = ci.m_title;
+
+
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ m_internalData = new MacOpenGLWindowInternalData;
+ m_internalData->m_width = width;
+ m_internalData->m_height = height;
+
+ m_internalData->m_pool = [NSAutoreleasePool new];
+ m_internalData->m_myApp = [NSApplication sharedApplication];
+ //myApp = [MyApp sharedApplication];
+ //home();
+
+ [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
+
+ id menubar = [[NSMenu new] autorelease];
+ id appMenuItem = [[NSMenuItem new] autorelease];
+ [menubar addItem:appMenuItem];
+ [NSApp setMainMenu:menubar];
+
+ id appMenu = [[NSMenu new] autorelease];
+ id appName = [[NSProcessInfo processInfo] processName];
+ id quitTitle = [@"Quit " stringByAppendingString:appName];
+ id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:quitTitle
+ action:@selector(terminate:) keyEquivalent:@"q"] autorelease];
+
+ [appMenu addItem:quitMenuItem];
+ [appMenuItem setSubmenu:appMenu];
+
+ NSMenuItem *fileMenuItem = [[NSMenuItem new] autorelease];
+ NSMenu *fileMenu = [[NSMenu alloc] initWithTitle:@"File"];
+ [fileMenuItem setSubmenu: fileMenu]; // was setMenu:
+
+ NSMenuItem *newMenu = [[NSMenuItem alloc] initWithTitle:@"New" action:NULL keyEquivalent:@""];
+ NSMenuItem *openMenu = [[NSMenuItem alloc] initWithTitle:@"Open" action:NULL keyEquivalent:@""];
+ NSMenuItem *saveMenu = [[NSMenuItem alloc] initWithTitle:@"Save" action:NULL keyEquivalent:@""];
+
+ [fileMenu addItem: newMenu];
+ [fileMenu addItem: openMenu];
+ [fileMenu addItem: saveMenu];
+ [menubar addItem: fileMenuItem];
+
+
+ // add Edit menu
+ NSMenuItem *editMenuItem = [[NSMenuItem new] autorelease];
+ NSMenu *menu = [[NSMenu allocWithZone:[NSMenu menuZone]]initWithTitle:@"Edit"];
+ [editMenuItem setSubmenu: menu];
+
+ NSMenuItem *copyItem = [[NSMenuItem allocWithZone:[NSMenu menuZone]]initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"];
+
+ [menu addItem:copyItem];
+ [menubar addItem:editMenuItem];
+
+ // [mainMenu setSubmenu:menu forItem:menuItem];
+
+
+ //NSMenuItem *fileMenuItem = [[NSMenuItem alloc] initWithTitle: @"File"];
+ /*[fileMenuItem setSubmenu: fileMenu]; // was setMenu:
+ [fileMenuItem release];
+ */
+
+ /*NSMenu *newMenu;
+ NSMenuItem *newItem;
+
+ // Add the submenu
+ newItem = [[NSMenuItem allocWithZone:[NSMenu menuZone]]
+ initWithTitle:@"Flashy" action:NULL keyEquivalent:@""];
+ newMenu = [[NSMenu allocWithZone:[NSMenu menuZone]]
+ initWithTitle:@"Flashy"];
+ [newItem setSubmenu:newMenu];
+ [newMenu release];
+ [[NSApp mainMenu] addItem:newItem];
+ [newItem release];
+ */
+
+ NSRect frame = NSMakeRect(0., 0., width, height);
+
+ m_internalData->m_window = [NSWindow alloc];
+ [m_internalData->m_window initWithContentRect:frame
+ styleMask:NSTitledWindowMask |NSResizableWindowMask| NSClosableWindowMask | NSMiniaturizableWindowMask
+ backing:NSBackingStoreBuffered
+ defer:false];
+
+
+ [m_internalData->m_window setTitle:[NSString stringWithCString:windowTitle encoding:NSISOLatin1StringEncoding]] ;
+
+ m_internalData->m_myview = [TestView alloc];
+
+ [m_internalData->m_myview setResizeCallback:0];
+ ///ci.m_resizeCallback];
+
+ [m_internalData->m_myview initWithFrame: frame];
+
+ // OpenGL init!
+ [m_internalData->m_myview MakeContext : ci.m_openglVersion];
+
+ // https://developer.apple.com/library/mac/#documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/CapturingScreenContents/CapturingScreenContents.html#//apple_ref/doc/uid/TP40012302-CH10-SW1
+ //support HighResolutionOSX for Retina Macbook
+ if (ci.m_openglVersion>=3)
+ {
+ if (m_allowRetina)
+ {
+ [m_internalData->m_myview setWantsBestResolutionOpenGLSurface:YES];
+ }
+ }
+ NSSize sz;
+ sz.width = 1;
+ sz.height = 1;
+
+ // float newBackingScaleFactor = [m_internalData->m_window backingScaleFactor];
+
+ dumpInfo();
+
+
+
+
+ [m_internalData->m_window setContentView: m_internalData->m_myview];
+
+
+
+ [m_internalData->m_window setDelegate:(id) m_internalData->m_myview];
+
+ [m_internalData->m_window makeKeyAndOrderFront: nil];
+
+ [m_internalData->m_myview MakeCurrent];
+ m_internalData->m_width = m_internalData->m_myview.GetWindowWidth;
+ m_internalData->m_height = m_internalData->m_myview.GetWindowHeight;
+
+
+ [NSApp activateIgnoringOtherApps:YES];
+
+
+//[m_internalData->m_window setLevel:NSMainMenuWindowLevel];
+
+// [NSEvent addGlobalMonitorForEventsMatchingMask:NSMouseMovedMask];
+
+// [NSEvent addGlobalMonitorForEventsMatchingMask:NSMouseMovedMask handler:^(NSEvent *event)
+ // {
+ //[window setFrameOrigin:[NSEvent mouseLocation]];
+ // NSPoint eventLocation = [m_internalData->m_window mouseLocationOutsideOfEventStream];
+
+ // NSPoint eventLocation = [event locationInWindow];
+ //NSPoint center = [m_internalData->m_myview convertPoint:eventLocation fromView:nil];
+ // m_mouseX = center.x;
+ // m_mouseY = [m_internalData->m_myview GetWindowHeight] - center.y;
+
+
+ // printf("mouse coord = %f, %f\n",m_mouseX,m_mouseY);
+ // if (m_mouseMoveCallback)
+ // (*m_mouseMoveCallback)(m_mouseX,m_mouseY);
+
+ // }];
+
+ //see http://stackoverflow.com/questions/8238473/cant-get-nsmousemoved-events-from-nexteventmatchingmask-with-an-nsopenglview
+/* ProcessSerialNumber psn;
+ GetCurrentProcess(&psn);
+ TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+ SetFrontProcess(&psn);
+ */
+#ifndef NO_OPENGL3
+ m_retinaScaleFactor = [m_internalData->m_myview convertSizeToBacking:sz].width;
+#else
+ m_retinaScaleFactor=1.f;
+#endif
+
+ [m_internalData->m_myApp finishLaunching];
+ [pool release];
+
+}
+
+void MacOpenGLWindow::runMainLoop()
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ // FILE* dump = fopen ("/Users/erwincoumans/yes.txt","wb");
+ // fclose(dump);
+
+
+
+
+ [pool release];
+
+}
+
+void MacOpenGLWindow::closeWindow()
+{
+
+ delete m_internalData;
+ m_internalData = 0;
+
+}
+extern float m_azi;
+extern float m_ele;
+extern float m_cameraDistance;
+
+
+ /*
+ * Summary:
+ * Virtual keycodes
+ *
+ * Discussion:
+ * These constants are the virtual keycodes defined originally in
+ * Inside Mac Volume V, pg. V-191. They identify physical keys on a
+ * keyboard. Those constants with "ANSI" in the name are labeled
+ * according to the key position on an ANSI-standard US keyboard.
+ * For example, kVK_ANSI_A indicates the virtual keycode for the key
+ * with the letter 'A' in the US keyboard layout. Other keyboard
+ * layouts may have the 'A' key label on a different physical key;
+ * in this case, pressing 'A' will generate a different virtual
+ * keycode.
+ */
+enum {
+ kVK_ANSI_A = 0x00,
+ kVK_ANSI_S = 0x01,
+ kVK_ANSI_D = 0x02,
+ kVK_ANSI_F = 0x03,
+ kVK_ANSI_H = 0x04,
+ kVK_ANSI_G = 0x05,
+ kVK_ANSI_Z = 0x06,
+ kVK_ANSI_X = 0x07,
+ kVK_ANSI_C = 0x08,
+ kVK_ANSI_V = 0x09,
+ kVK_ANSI_B = 0x0B,
+ kVK_ANSI_Q = 0x0C,
+ kVK_ANSI_W = 0x0D,
+ kVK_ANSI_E = 0x0E,
+ kVK_ANSI_R = 0x0F,
+ kVK_ANSI_Y = 0x10,
+ kVK_ANSI_T = 0x11,
+ kVK_ANSI_1 = 0x12,
+ kVK_ANSI_2 = 0x13,
+ kVK_ANSI_3 = 0x14,
+ kVK_ANSI_4 = 0x15,
+ kVK_ANSI_6 = 0x16,
+ kVK_ANSI_5 = 0x17,
+ kVK_ANSI_Equal = 0x18,
+ kVK_ANSI_9 = 0x19,
+ kVK_ANSI_7 = 0x1A,
+ kVK_ANSI_Minus = 0x1B,
+ kVK_ANSI_8 = 0x1C,
+ kVK_ANSI_0 = 0x1D,
+ kVK_ANSI_RightBracket = 0x1E,
+ kVK_ANSI_O = 0x1F,
+ kVK_ANSI_U = 0x20,
+ kVK_ANSI_LeftBracket = 0x21,
+ kVK_ANSI_I = 0x22,
+ kVK_ANSI_P = 0x23,
+ kVK_ANSI_L = 0x25,
+ kVK_ANSI_J = 0x26,
+ kVK_ANSI_Quote = 0x27,
+ kVK_ANSI_K = 0x28,
+ kVK_ANSI_Semicolon = 0x29,
+ kVK_ANSI_Backslash = 0x2A,
+ kVK_ANSI_Comma = 0x2B,
+ kVK_ANSI_Slash = 0x2C,
+ kVK_ANSI_N = 0x2D,
+ kVK_ANSI_M = 0x2E,
+ kVK_ANSI_Period = 0x2F,
+ kVK_ANSI_Grave = 0x32,
+ kVK_ANSI_KeypadDecimal = 0x41,
+ kVK_ANSI_KeypadMultiply = 0x43,
+ kVK_ANSI_KeypadPlus = 0x45,
+ kVK_ANSI_KeypadClear = 0x47,
+ kVK_ANSI_KeypadDivide = 0x4B,
+ kVK_ANSI_KeypadEnter = 0x4C,
+ kVK_ANSI_KeypadMinus = 0x4E,
+ kVK_ANSI_KeypadEquals = 0x51,
+ kVK_ANSI_Keypad0 = 0x52,
+ kVK_ANSI_Keypad1 = 0x53,
+ kVK_ANSI_Keypad2 = 0x54,
+ kVK_ANSI_Keypad3 = 0x55,
+ kVK_ANSI_Keypad4 = 0x56,
+ kVK_ANSI_Keypad5 = 0x57,
+ kVK_ANSI_Keypad6 = 0x58,
+ kVK_ANSI_Keypad7 = 0x59,
+ kVK_ANSI_Keypad8 = 0x5B,
+ kVK_ANSI_Keypad9 = 0x5C
+};
+
+/* keycodes for keys that are independent of keyboard layout*/
+enum {
+ kVK_Return = 0x24,
+ kVK_Tab = 0x30,
+ kVK_Space = 0x31,
+ kVK_Delete = 0x33,
+ kVK_Escape = 0x35,
+ kVK_Command = 0x37,
+ kVK_Shift = 0x38,
+ kVK_CapsLock = 0x39,
+ kVK_Option = 0x3A,
+ kVK_Control = 0x3B,
+ kVK_RightShift = 0x3C,
+ kVK_RightOption = 0x3D,
+ kVK_RightControl = 0x3E,
+ kVK_Function = 0x3F,
+ kVK_F17 = 0x40,
+ kVK_VolumeUp = 0x48,
+ kVK_VolumeDown = 0x49,
+ kVK_Mute = 0x4A,
+ kVK_F18 = 0x4F,
+ kVK_F19 = 0x50,
+ kVK_F20 = 0x5A,
+ kVK_F5 = 0x60,
+ kVK_F6 = 0x61,
+ kVK_F7 = 0x62,
+ kVK_F3 = 0x63,
+ kVK_F8 = 0x64,
+ kVK_F9 = 0x65,
+ kVK_F11 = 0x67,
+ kVK_F13 = 0x69,
+ kVK_F16 = 0x6A,
+ kVK_F14 = 0x6B,
+ kVK_F10 = 0x6D,
+ kVK_F12 = 0x6F,
+ kVK_F15 = 0x71,
+ kVK_Help = 0x72,
+ kVK_Home = 0x73,
+ kVK_PageUp = 0x74,
+ kVK_ForwardDelete = 0x75,
+ kVK_F4 = 0x76,
+ kVK_End = 0x77,
+ kVK_F2 = 0x78,
+ kVK_PageDown = 0x79,
+ kVK_F1 = 0x7A,
+ kVK_LeftArrow = 0x7B,
+ kVK_RightArrow = 0x7C,
+ kVK_DownArrow = 0x7D,
+ kVK_UpArrow = 0x7E
+};
+
+/* ISO keyboards only*/
+enum {
+ kVK_ISO_Section = 0x0A
+};
+
+/* JIS keyboards only*/
+enum {
+ kVK_JIS_Yen = 0x5D,
+ kVK_JIS_Underscore = 0x5E,
+ kVK_JIS_KeypadComma = 0x5F,
+ kVK_JIS_Eisu = 0x66,
+ kVK_JIS_Kana = 0x68
+};
+
+int getAsciiCodeFromVirtualKeycode(int virtualKeyCode)
+{
+ int keycode = 0xffffffff;
+
+ switch (virtualKeyCode)
+ {
+
+ case kVK_ANSI_A : {keycode = 'a'; break;}
+ case kVK_ANSI_B : {keycode = 'b'; break;}
+ case kVK_ANSI_C : {keycode = 'c'; break;}
+ case kVK_ANSI_D : {keycode = 'd';break;}
+ case kVK_ANSI_E : {keycode = 'e'; break;}
+ case kVK_ANSI_F : {keycode = 'f'; break;}
+ case kVK_ANSI_G : {keycode = 'g'; break;}
+ case kVK_ANSI_H : {keycode = 'h'; break;}
+ case kVK_ANSI_I : {keycode = 'i'; break;}
+ case kVK_ANSI_J : {keycode = 'j'; break;}
+ case kVK_ANSI_K : {keycode = 'k'; break;}
+ case kVK_ANSI_L : {keycode = 'l'; break;}
+ case kVK_ANSI_M : {keycode = 'm'; break;}
+ case kVK_ANSI_N : {keycode = 'n'; break;}
+ case kVK_ANSI_O : {keycode = 'o'; break;}
+ case kVK_ANSI_P : {keycode = 'p'; break;}
+ case kVK_ANSI_Q : {keycode = 'q'; break;}
+ case kVK_ANSI_R : {keycode = 'r'; break;}
+ case kVK_ANSI_S : {keycode = 's';break;}
+ case kVK_ANSI_T : {keycode = 't'; break;}
+ case kVK_ANSI_U : {keycode = 'u'; break;}
+ case kVK_ANSI_V : {keycode = 'v'; break;}
+ case kVK_ANSI_W : {keycode = 'w'; break;}
+ case kVK_ANSI_X : {keycode = 'x'; break;}
+ case kVK_ANSI_Y : {keycode = 'y'; break;}
+ case kVK_ANSI_Z : {keycode = 'z'; break;}
+
+ case kVK_ANSI_1 : {keycode = '1'; break;}
+ case kVK_ANSI_2 : {keycode = '2'; break;}
+ case kVK_ANSI_3 : {keycode = '3'; break;}
+ case kVK_ANSI_4 : {keycode = '4'; break;}
+ case kVK_ANSI_5 : {keycode = '5'; break;}
+ case kVK_ANSI_6 : {keycode = '6'; break;}
+ case kVK_ANSI_7 : {keycode = '7'; break;}
+ case kVK_ANSI_8 : {keycode = '8'; break;}
+ case kVK_ANSI_9 : {keycode = '9'; break;}
+ case kVK_ANSI_0 : {keycode = '0'; break;}
+ case kVK_ANSI_Equal : {keycode = '='; break;}
+ case kVK_ANSI_Minus : {keycode = '-'; break;}
+
+ case kVK_Tab: {keycode = 9; break;}
+ case kVK_Space: {keycode=' '; break;}
+ case kVK_Escape: {keycode=27; break;}
+ case kVK_Delete: {keycode=8; break;}
+ case kVK_ForwardDelete: {keycode=B3G_INSERT; break;}
+
+
+ case kVK_F1: {keycode = B3G_F1; break;}
+ case kVK_F2: {keycode = B3G_F2; break;}
+ case kVK_F3: {keycode = B3G_F3; break;}
+ case kVK_F4: {keycode = B3G_F4; break;}
+ case kVK_F5: {keycode = B3G_F5; break;}
+ case kVK_F6: {keycode = B3G_F6; break;}
+ case kVK_F7: {keycode = B3G_F7; break;}
+ case kVK_F8: {keycode = B3G_F8; break;}
+ case kVK_F9: {keycode = B3G_F9; break;}
+ case kVK_F10: {keycode = B3G_F10; break;}
+ case kVK_F11: {keycode = B3G_F11; break;}
+ case kVK_F12: {keycode = B3G_F12; break;}
+ case kVK_F13: {keycode = B3G_F13; break;}
+ case kVK_F14: {keycode = B3G_F14; break;}
+ case kVK_F15: {keycode = B3G_F15; break;}
+
+ case kVK_LeftArrow: {keycode = B3G_LEFT_ARROW;break;}
+ case kVK_RightArrow: {keycode = B3G_RIGHT_ARROW;break;}
+ case kVK_UpArrow: {keycode = B3G_UP_ARROW;break;}
+ case kVK_DownArrow: {keycode = B3G_DOWN_ARROW;break;}
+
+ case kVK_PageUp :{keycode = B3G_PAGE_UP;break;}
+ case kVK_PageDown :{keycode = B3G_PAGE_DOWN;break;}
+ case kVK_End :{keycode = B3G_END;break;}
+ case kVK_Home :{keycode = B3G_HOME;break;}
+ case kVK_Control: {keycode = B3G_CONTROL;break;}
+ case kVK_Option: {keycode = B3G_ALT;break;}
+
+ case kVK_ANSI_RightBracket : {keycode = ']'; break;}
+ case kVK_ANSI_LeftBracket : {keycode = '['; break;}
+ case kVK_ANSI_Quote : {keycode = '\''; break;}
+ case kVK_ANSI_Semicolon : {keycode = ';'; break;}
+ case kVK_ANSI_Backslash : {keycode = '\\'; break;}
+ case kVK_ANSI_Comma : {keycode = ','; break;}
+ case kVK_ANSI_Slash : {keycode = '/'; break;}
+ case kVK_ANSI_Period : {keycode = '.'; break;}
+ case kVK_ANSI_Grave : {keycode = '`'; break;}
+ case kVK_ANSI_KeypadDecimal : {keycode = '.'; break;}
+ case kVK_ANSI_KeypadMultiply : {keycode = '*'; break;}
+ case kVK_ANSI_KeypadPlus : {keycode = '+'; break;}
+ case kVK_ANSI_KeypadClear : {keycode = '?'; break;}
+ case kVK_ANSI_KeypadDivide : {keycode = '/'; break;}
+ case kVK_ANSI_KeypadEnter : {keycode = B3G_RETURN; break;}
+ case kVK_ANSI_KeypadMinus : {keycode = '-'; break;}
+ case kVK_ANSI_KeypadEquals : {keycode = '='; break;}
+ case kVK_ANSI_Keypad0 : {keycode = '0'; break;}
+ case kVK_ANSI_Keypad1 : {keycode = '1'; break;}
+ case kVK_ANSI_Keypad2 : {keycode = '2'; break;}
+ case kVK_ANSI_Keypad3 : {keycode = '3'; break;}
+ case kVK_ANSI_Keypad4 : {keycode = '4'; break;}
+ case kVK_ANSI_Keypad5 : {keycode = '5'; break;}
+ case kVK_ANSI_Keypad6 : {keycode = '6'; break;}
+ case kVK_ANSI_Keypad7 : {keycode = '7'; break;}
+ case kVK_ANSI_Keypad8 : {keycode = '8'; break;}
+ case kVK_ANSI_Keypad9 : {keycode = '9'; break;}
+ case kVK_Return:
+ {
+ keycode = B3G_RETURN; break;
+ }
+
+ default:
+ {
+
+ printf("unknown keycode\n");
+ }
+ }
+ return keycode;
+}
+
+
+void MacOpenGLWindow::startRendering()
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+
+ GLint err = glGetError();
+ assert(err==GL_NO_ERROR);
+
+
+ NSEvent *event = nil;
+ bool handledEvent = false;
+
+ do
+ {
+ [pool release];
+ pool = [[NSAutoreleasePool alloc] init];
+ event = [m_internalData->m_myApp
+ nextEventMatchingMask:NSAnyEventMask
+ untilDate:[NSDate distantPast]
+ inMode:NSDefaultRunLoopMode
+ // inMode:NSEventTrackingRunLoopMode
+ dequeue:YES];
+
+ //NSShiftKeyMask = 1 << 17,
+ //NSControlKeyMask
+
+ if ([event type] == NSFlagsChanged)
+ {
+ int modifiers = [event modifierFlags];
+ if (m_keyboardCallback)
+ {
+ if ((modifiers & NSShiftKeyMask))
+ {
+ m_keyboardCallback(B3G_SHIFT,1);
+ m_modifierFlags |= MY_MAC_SHIFTKEY;
+ }else
+ {
+ if (m_modifierFlags& MY_MAC_SHIFTKEY)
+ {
+ m_keyboardCallback(B3G_SHIFT,0);
+ m_modifierFlags &= ~MY_MAC_SHIFTKEY;
+ }
+ }
+ if (modifiers & NSControlKeyMask)
+ {
+ m_keyboardCallback(B3G_CONTROL,1);
+ m_modifierFlags |= MY_MAC_CONTROL_KEY;
+ } else
+ {
+ if (m_modifierFlags&MY_MAC_CONTROL_KEY)
+ {
+ m_keyboardCallback(B3G_CONTROL,0);
+ m_modifierFlags &= ~MY_MAC_CONTROL_KEY;
+ }
+ }
+ if (modifiers & NSAlternateKeyMask)
+ {
+ m_keyboardCallback(B3G_ALT,1);
+ m_modifierFlags |= MY_MAC_ALTKEY;
+ } else
+ {
+ if (m_modifierFlags&MY_MAC_ALTKEY)
+ {
+ m_keyboardCallback(B3G_ALT,0);
+ m_modifierFlags &= ~MY_MAC_ALTKEY;
+
+ }
+ }
+ //handle NSCommandKeyMask
+
+ }
+ }
+ if ([event type] == NSKeyUp)
+ {
+ handledEvent = true;
+
+ uint32 virtualKeycode = [event keyCode];
+
+ int keycode = getAsciiCodeFromVirtualKeycode(virtualKeycode);
+ // printf("keycode = %d\n", keycode);
+
+ if (m_keyboardCallback)
+ {
+ int state = 0;
+ m_keyboardCallback(keycode,state);
+ }
+ }
+ if ([event type] == NSKeyDown)
+ {
+ handledEvent = true;
+
+ if (![event isARepeat])
+ {
+ uint32 virtualKeycode = [event keyCode];
+
+ int keycode = getAsciiCodeFromVirtualKeycode(virtualKeycode);
+ //printf("keycode = %d\n", keycode);
+
+ if (m_keyboardCallback)
+ {
+ int state = 1;
+ m_keyboardCallback(keycode,state);
+ }
+ }
+ }
+
+
+ if (([event type]== NSRightMouseDown) || ([ event type]==NSLeftMouseDown)||([event type]==NSOtherMouseDown))
+ {
+ // printf("right mouse!");
+ // float mouseX,mouseY;
+
+ NSPoint eventLocation = [event locationInWindow];
+ NSPoint center = [m_internalData->m_myview convertPoint:eventLocation fromView:nil];
+ m_mouseX = center.x;
+ m_mouseY = [m_internalData->m_myview GetWindowHeight] - center.y;
+ int button=0;
+ switch ([event type])
+ {
+ case NSLeftMouseDown:
+ {
+ button=0;
+ break;
+ }
+ case NSOtherMouseDown:
+ {
+ button=1;
+ break;
+ }
+ case NSRightMouseDown:
+ {
+ button=2;
+ break;
+ }
+ default:
+ {
+
+ }
+ };
+ // printf("mouse coord = %f, %f\n",mouseX,mouseY);
+ if (m_mouseButtonCallback)
+ {
+ //handledEvent = true;
+ (*m_mouseButtonCallback)(button,1,m_mouseX,m_mouseY);
+ }
+ }
+
+
+ if (([event type]== NSRightMouseUp) || ([ event type]==NSLeftMouseUp)||([event type]==NSOtherMouseUp))
+ {
+ // printf("right mouse!");
+ // float mouseX,mouseY;
+
+ NSPoint eventLocation = [event locationInWindow];
+ NSPoint center = [m_internalData->m_myview convertPoint:eventLocation fromView:nil];
+ m_mouseX = center.x;
+ m_mouseY = [m_internalData->m_myview GetWindowHeight] - center.y;
+
+ int button=0;
+ switch ([event type])
+ {
+ case NSLeftMouseUp:
+ {
+ button=0;
+ break;
+ }
+ case NSOtherMouseUp:
+ {
+ button=1;
+ break;
+ }
+ case NSRightMouseUp:
+ {
+ button=2;
+ break;
+ }
+ default:
+ {
+
+ }
+ };
+
+ // printf("mouse coord = %f, %f\n",mouseX,mouseY);
+ if (m_mouseButtonCallback)
+ (*m_mouseButtonCallback)(button,0,m_mouseX,m_mouseY);
+
+ }
+
+
+ if ([event type] == NSMouseMoved)
+ {
+
+
+ // http://stackoverflow.com/questions/4630509/how-to-find-if-the-mouse-is-over-a-view
+ NSPoint globalLocation = [ NSEvent mouseLocation ];
+ NSPoint windowLocation = [ [m_internalData->m_myview window] convertScreenToBase:globalLocation ];
+ NSPoint viewLocation = [ m_internalData->m_myview convertPoint:windowLocation fromView: nil ];
+
+ //NSPoint eventLocation = [NSEvent mouseLocation]; //[event locationInWindow];
+ //NSPoint center = [m_internalData->m_myview convertPoint:eventLocation fromView:nil];
+ NSPoint center = viewLocation;
+ m_mouseX = center.x;
+ m_mouseY = [m_internalData->m_myview GetWindowHeight] - center.y;
+
+ //printf("mouse coord = %f, %f\n",m_mouseX,m_mouseY);
+ if (m_mouseMoveCallback)
+ {
+ //handledEvent = true;
+ (*m_mouseMoveCallback)(m_mouseX,m_mouseY);
+ }
+ }
+
+ if (([event type] == NSLeftMouseDragged) || ([event type] == NSRightMouseDragged) || ([event type] == NSOtherMouseDragged))
+ {
+ int dx1, dy1;
+ CGGetLastMouseDelta (&dx1, &dy1);
+
+ NSPoint eventLocation = [event locationInWindow];
+ NSPoint center = [m_internalData->m_myview convertPoint:eventLocation fromView:nil];
+ m_mouseX = center.x;
+ m_mouseY = [m_internalData->m_myview GetWindowHeight] - center.y;
+
+ if (m_mouseMoveCallback)
+ {
+ //handledEvent = true;
+ (*m_mouseMoveCallback)(m_mouseX,m_mouseY);
+ }
+
+ // printf("mouse coord = %f, %f\n",m_mouseX,m_mouseY);
+ }
+
+ if ([event type] == NSScrollWheel)
+ {
+ float dy, dx;
+ dy = [ event deltaY ];
+ dx = [ event deltaX ];
+
+ if (m_wheelCallback)
+ {
+ handledEvent = true;
+ (*m_wheelCallback)(dx,dy);
+ }
+ // m_cameraDistance -= dy*0.1;
+ // m_azi -= dx*0.1;
+
+ }
+
+ if (!handledEvent)
+ [m_internalData->m_myApp sendEvent:event];
+
+ [m_internalData->m_myApp updateWindows];
+ } while (event);
+
+ err = glGetError();
+ assert(err==GL_NO_ERROR);
+
+ [m_internalData->m_myview MakeCurrent];
+ err = glGetError();
+ assert(err==GL_NO_ERROR);
+
+
+ // glClearColor(1,1,1,1);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //clear buffers
+
+ err = glGetError();
+ assert(err==GL_NO_ERROR);
+
+ //glCullFace(GL_BACK);
+ //glFrontFace(GL_CCW);
+ glEnable(GL_DEPTH_TEST);
+ err = glGetError();
+ assert(err==GL_NO_ERROR);
+
+ float aspect;
+ //b3Vector3 extents;
+
+ if (m_internalData->m_width > m_internalData->m_height)
+ {
+ aspect = (float)m_internalData->m_width / (float)m_internalData->m_height;
+ //extents.setValue(aspect * 1.0f, 1.0f,0);
+ } else
+ {
+ aspect = (float)m_internalData->m_height / (float)m_internalData->m_width;
+ //extents.setValue(1.0f, aspect*1.f,0);
+ }
+
+ err = glGetError();
+ assert(err==GL_NO_ERROR);
+ [pool release];
+
+}
+
+void MacOpenGLWindow::endRendering()
+{
+ [m_internalData->m_myview MakeCurrent];
+//#ifndef NO_OPENGL3
+// glSwapAPPLE();
+//#else
+ [[m_internalData->m_myview getContext] flushBuffer];
+// #endif
+
+}
+
+bool MacOpenGLWindow::requestedExit() const
+{
+ bool closeme = m_internalData->m_myview.GetRequestClose;
+ return m_internalData->m_exitRequested || closeme;
+}
+
+void MacOpenGLWindow::setRequestExit()
+{
+ m_internalData->m_exitRequested = true;
+}
+
+#include <string.h>
+int MacOpenGLWindow::fileOpenDialog(char* filename, int maxNameLength)
+{
+ //save/restore the OpenGL context, NSOpenPanel can mess it up
+ //http://stackoverflow.com/questions/13987148/nsopenpanel-breaks-my-sdl-opengl-app
+
+ NSOpenGLContext *foo = [NSOpenGLContext currentContext];
+ // get the url of a .txt file
+ NSOpenPanel * zOpenPanel = [NSOpenPanel openPanel];
+ NSArray * zAryOfExtensions = [NSArray arrayWithObjects:@"urdf",@"bullet",@"obj",@"sdf",nil];
+ [zOpenPanel setAllowedFileTypes:zAryOfExtensions];
+ NSInteger zIntResult = [zOpenPanel runModal];
+
+ [foo makeCurrentContext];
+
+ if (zIntResult == NSFileHandlingPanelCancelButton) {
+ NSLog(@"readUsingOpenPanel cancelled");
+ return 0;
+ }
+ NSURL *zUrl = [zOpenPanel URL];
+ if (zUrl)
+ {
+ //without the file://
+ NSString *myString = [zUrl absoluteString];
+ int slen = [myString length];
+ if (slen < maxNameLength)
+ {
+ const char *cfilename=[myString UTF8String];
+ //expect file:// at start of URL
+ const char* p = strstr(cfilename, "file://");
+ if (p==cfilename)
+ {
+ int actualLen = strlen(cfilename)-7;
+ memcpy(filename, cfilename+7,actualLen);
+ filename[actualLen]=0;
+ return actualLen;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+
+void MacOpenGLWindow::getMouseCoordinates(int& x, int& y)
+{
+
+ NSPoint pt = [m_internalData->m_window mouseLocationOutsideOfEventStream];
+ m_mouseX = pt.x;
+ m_mouseY = pt.y;
+
+ x = m_mouseX;
+ //our convention is x,y is upper left hand side
+ y = [m_internalData->m_myview GetWindowHeight]-m_mouseY;
+
+
+}
+
+int MacOpenGLWindow::getWidth() const
+{
+ if (m_internalData && m_internalData->m_myview && m_internalData->m_myview.GetWindowWidth)
+ return m_internalData->m_myview.GetWindowWidth;
+ return 0;
+}
+
+int MacOpenGLWindow::getHeight() const
+{
+ if (m_internalData && m_internalData->m_myview && m_internalData->m_myview.GetWindowHeight)
+ return m_internalData->m_myview.GetWindowHeight;
+ return 0;
+}
+
+
+void MacOpenGLWindow::setResizeCallback(b3ResizeCallback resizeCallback)
+{
+ [m_internalData->m_myview setResizeCallback:resizeCallback];
+ if (resizeCallback)
+ {
+ (resizeCallback)(m_internalData->m_width,m_internalData->m_height);
+ }
+}
+
+b3ResizeCallback MacOpenGLWindow::getResizeCallback()
+{
+ return [m_internalData->m_myview getResizeCallback];
+}
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/OpenGL2Include.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/OpenGL2Include.h
new file mode 100644
index 0000000000..34caaaf07e
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/OpenGL2Include.h
@@ -0,0 +1,59 @@
+/*
+Copyright (c) 2012 Advanced Micro Devices, Inc.
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+//Originally written by Erwin Coumans
+
+
+#ifndef __OPENGL_INCLUDE_H
+#define __OPENGL_INCLUDE_H
+
+
+//think different
+#if defined(__APPLE__) && !defined (VMDMESA)
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+#else
+
+#ifdef GLEW_STATIC
+#include "CustomGL/glew.h"
+#else
+#include <GL/glew.h>
+#endif//GLEW_STATIC
+
+#ifdef _WINDOWS
+#include <windows.h>
+//#include <GL/gl.h>
+//#include <GL/glu.h>
+#else
+//#include <GL/gl.h>
+//#include <GL/glu.h>
+#endif //_WINDOWS
+#endif //APPLE
+
+//disable glGetError
+//#undef glGetError
+//#define glGetError MyGetError
+//
+//GLenum inline MyGetError()
+//{
+// return 0;
+//}
+
+///on Linux only glDrawElementsInstancedARB is defined?!?
+//#ifdef __linux
+//#define glDrawElementsInstanced glDrawElementsInstancedARB
+//
+//#endif //__linux
+
+#endif //__OPENGL_INCLUDE_H
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/OpenGLInclude.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/OpenGLInclude.h
new file mode 100644
index 0000000000..19219a188f
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/OpenGLInclude.h
@@ -0,0 +1,66 @@
+/*
+Copyright (c) 2012 Advanced Micro Devices, Inc.
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+//Originally written by Erwin Coumans
+
+
+#ifndef __OPENGL_INCLUDE_H
+#define __OPENGL_INCLUDE_H
+
+
+//think different
+#if defined(__APPLE__) && !defined (VMDMESA)
+#include <OpenGL/OpenGL.h>
+//#include <OpenGL/gl.h>
+//#include <OpenGL/glu.h>
+//#import <Cocoa/Cocoa.h>
+#if defined (USE_OPENGL2) || defined (NO_OPENGL3)
+#include <OpenGL/gl.h>
+#else
+#include <OpenGL/gl3.h>
+#endif
+#else
+
+#ifdef GLEW_STATIC
+#include "CustomGL/glew.h"
+#else
+#include <GL/glew.h>
+#endif //GLEW_STATIC
+
+#ifdef _WINDOWS
+#include <windows.h>
+//#include <GL/gl.h>
+//#include <GL/glu.h>
+#else
+//#include <GL/gl.h>
+//#include <GL/glu.h>
+#endif //_WINDOWS
+#endif //APPLE
+
+//disable glGetError
+//#undef glGetError
+//#define glGetError MyGetError
+//
+//GLenum inline MyGetError()
+//{
+// return 0;
+//}
+
+///on Linux only glDrawElementsInstancedARB is defined?!?
+//#ifdef __linux
+//#define glDrawElementsInstanced glDrawElementsInstancedARB
+//
+//#endif //__linux
+
+#endif //__OPENGL_INCLUDE_H
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32InternalWindowData.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32InternalWindowData.h
new file mode 100644
index 0000000000..a512bc7630
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32InternalWindowData.h
@@ -0,0 +1,68 @@
+
+#ifndef WIN32_INTERNAL_WINDOW_DATA_H
+#define WIN32_INTERNAL_WINDOW_DATA_H
+
+#include <windows.h>
+
+
+struct InternalData2
+{
+ HWND m_hWnd;;
+ int m_fullWindowWidth;//includes borders etc
+ int m_fullWindowHeight;
+
+ int m_openglViewportWidth;//just the 3d viewport/client area
+ int m_openglViewportHeight;
+
+ HDC m_hDC;
+ HGLRC m_hRC;
+ bool m_OpenGLInitialized;
+ int m_oldScreenWidth;
+ int m_oldHeight;
+ int m_oldBitsPerPel;
+ bool m_quit;
+ int m_mouseLButton;
+ int m_mouseRButton;
+ int m_mouseMButton;
+ int m_mouseXpos;
+ int m_mouseYpos;
+
+ int m_internalKeyModifierFlags;
+
+ b3WheelCallback m_wheelCallback;
+ b3MouseMoveCallback m_mouseMoveCallback;
+ b3MouseButtonCallback m_mouseButtonCallback;
+ b3ResizeCallback m_resizeCallback;
+ b3KeyboardCallback m_keyboardCallback;
+
+
+
+ InternalData2()
+ {
+ m_hWnd = 0;
+ m_mouseLButton=0;
+ m_mouseRButton=0;
+ m_mouseMButton=0;
+ m_internalKeyModifierFlags = 0;
+ m_fullWindowWidth = 0;
+ m_fullWindowHeight= 0;
+ m_openglViewportHeight=0;
+ m_openglViewportWidth=0;
+ m_hDC = 0;
+ m_hRC = 0;
+ m_OpenGLInitialized = false;
+ m_oldScreenWidth = 0;
+ m_oldHeight = 0;
+ m_oldBitsPerPel = 0;
+ m_quit = false;
+
+ m_keyboardCallback = 0;
+ m_mouseMoveCallback = 0;
+ m_mouseButtonCallback = 0;
+ m_resizeCallback = 0;
+ m_wheelCallback = 0;
+
+ }
+};
+
+#endif //WIN32_INTERNAL_WINDOW_DATA_H \ No newline at end of file
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32OpenGLWindow.cpp b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32OpenGLWindow.cpp
new file mode 100644
index 0000000000..0e076b92c2
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32OpenGLWindow.cpp
@@ -0,0 +1,200 @@
+#ifdef _WIN32
+/*
+Copyright (c) 2012 Advanced Micro Devices, Inc.
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+//Originally written by Erwin Coumans
+
+
+#include "Win32OpenGLWindow.h"
+
+#include "OpenGLInclude.h"
+
+//#include "Bullet3Common/b3Vector3.h"
+
+#include "Win32InternalWindowData.h"
+#include <stdio.h>
+
+static void printGLString(const char *name, GLenum s) {
+ const char *v = (const char *) glGetString(s);
+ printf("%s = %s\n",name, v);
+}
+
+bool sOpenGLVerbose = true;
+
+void Win32OpenGLWindow::enableOpenGL()
+{
+
+ PIXELFORMATDESCRIPTOR pfd;
+ int format;
+
+ // get the device context (DC)
+ m_data->m_hDC = GetDC( m_data->m_hWnd );
+
+ // set the pixel format for the DC
+ ZeroMemory( &pfd, sizeof( pfd ) );
+ pfd.nSize = sizeof( pfd );
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = 32;
+ pfd.cRedBits = 8;
+ pfd.cGreenBits = 8;
+ pfd.cBlueBits = 8;
+ pfd.cAlphaBits = 8;
+
+ pfd.cDepthBits = 24;
+ pfd.cStencilBits = 8;//1;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+ format = ChoosePixelFormat( m_data->m_hDC, &pfd );
+ SetPixelFormat( m_data->m_hDC, format, &pfd );
+
+ // create and enable the render context (RC)
+ m_data->m_hRC = wglCreateContext( m_data->m_hDC );
+ wglMakeCurrent( m_data->m_hDC, m_data->m_hRC );
+
+ if (sOpenGLVerbose)
+ {
+ printGLString("Version", GL_VERSION);
+ printGLString("Vendor", GL_VENDOR);
+ printGLString("Renderer", GL_RENDERER);
+ }
+ //printGLString("Extensions", GL_EXTENSIONS);
+
+}
+
+
+
+void Win32OpenGLWindow::disableOpenGL()
+{
+ wglMakeCurrent( NULL, NULL );
+ wglDeleteContext( m_data->m_hRC );
+// ReleaseDC( m_data->m_hWnd, m_data->m_hDC );
+
+}
+
+
+
+
+
+void Win32OpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci)
+{
+ Win32Window::createWindow(ci);
+
+ //VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this);
+ enableOpenGL();
+
+}
+
+
+
+
+Win32OpenGLWindow::Win32OpenGLWindow()
+{
+
+
+}
+
+Win32OpenGLWindow::~Win32OpenGLWindow()
+{
+
+}
+
+
+void Win32OpenGLWindow::closeWindow()
+{
+ disableOpenGL();
+
+ Win32Window::closeWindow();
+}
+
+
+
+void Win32OpenGLWindow::startRendering()
+{
+ pumpMessage();
+ //don't clear all 3 buffers because some AMD drivers are buggy
+ //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+
+ //glCullFace(GL_BACK);
+ //glFrontFace(GL_CCW);
+ glEnable(GL_DEPTH_TEST);
+
+}
+
+
+void Win32OpenGLWindow::renderAllObjects()
+{
+}
+
+void Win32OpenGLWindow::endRendering()
+ {
+ SwapBuffers( m_data->m_hDC );
+
+}
+
+int Win32OpenGLWindow::fileOpenDialog(char* fileName, int maxFileNameLength)
+{
+ //wchar_t wideChars[1024];
+
+ OPENFILENAME ofn ;
+ ZeroMemory( &ofn , sizeof( ofn));
+ ofn.lStructSize = sizeof ( ofn );
+ ofn.hwndOwner = NULL ;
+
+#ifdef UNICODE
+ WCHAR bla[1024];
+ ofn.lpstrFile = bla;
+ ofn.lpstrFile[0] = '\0';
+ ofn.nMaxFile = 1023;
+ ofn.lpstrFilter = L"All Files\0*.*\0URDF\0*.urdf\0.bullet\0*.bullet\0";
+#else
+ ofn.lpstrFile = fileName;
+ ofn.lpstrFile[0] = '\0';
+ ofn.nMaxFile = 1023;
+ //ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
+ ofn.lpstrFilter = "All Files\0*.*\0URDF\0*.urdf\0.bullet\0*.bullet\0";
+
+#endif
+
+ ofn.nFilterIndex =1;
+ ofn.lpstrFileTitle = NULL ;
+ ofn.nMaxFileTitle = 0 ;
+ ofn.lpstrInitialDir=NULL ;
+ ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ;
+ GetOpenFileName( &ofn );
+ return strlen(fileName);
+
+
+ //return 0;
+}
+
+int Win32OpenGLWindow::getWidth() const
+{
+ if (m_data)
+ return m_data->m_openglViewportWidth;
+ return 0;
+}
+
+int Win32OpenGLWindow::getHeight() const
+{
+ if (m_data)
+ return m_data->m_openglViewportHeight;
+ return 0;
+}
+
+
+#endif
+
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32OpenGLWindow.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32OpenGLWindow.h
new file mode 100644
index 0000000000..901ce6518b
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32OpenGLWindow.h
@@ -0,0 +1,64 @@
+/*
+Copyright (c) 2012 Advanced Micro Devices, Inc.
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+//Originally written by Erwin Coumans
+
+
+#ifndef _WIN32_OPENGL_RENDER_MANAGER_H
+#define _WIN32_OPENGL_RENDER_MANAGER_H
+
+
+
+#include "Win32Window.h"
+
+#define b3gDefaultOpenGLWindow Win32OpenGLWindow
+
+class Win32OpenGLWindow : public Win32Window
+{
+ bool m_OpenGLInitialized;
+
+ protected:
+
+
+ void enableOpenGL();
+
+ void disableOpenGL();
+
+public:
+
+ Win32OpenGLWindow();
+
+ virtual ~Win32OpenGLWindow();
+
+ virtual void createWindow(const b3gWindowConstructionInfo& ci);
+
+ virtual void closeWindow();
+
+ virtual void startRendering();
+
+ virtual void renderAllObjects();
+
+ virtual void endRendering();
+
+ virtual float getRetinaScale() const {return 1.f;}
+ virtual void setAllowRetina(bool /*allowRetina*/) {};
+
+ virtual int getWidth() const;
+ virtual int getHeight() const;
+
+ virtual int fileOpenDialog(char* fileName, int maxFileNameLength);
+};
+
+
+
+#endif //_WIN32_OPENGL_RENDER_MANAGER_H
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32Window.cpp b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32Window.cpp
new file mode 100644
index 0000000000..029a098f2c
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32Window.cpp
@@ -0,0 +1,810 @@
+#ifdef _WIN32
+/*
+Copyright (c) 2012 Advanced Micro Devices, Inc.
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+//Originally written by Erwin Coumans
+
+
+#include "Win32Window.h"
+
+#include "OpenGLInclude.h"
+
+#include <wchar.h>
+static InternalData2* sData = 0;
+
+#include "Win32InternalWindowData.h"
+
+
+enum
+{
+ INTERNAL_SHIFT_MODIFIER=1,
+ INTERNAL_ALT_MODIFIER=2,
+ INTERNAL_CONTROL_MODIFIER=4,
+};
+
+void Win32Window::pumpMessage()
+{
+ MSG msg;
+ // check for messages
+ //'if' instead of 'while' can make mainloop smoother.
+ //@todo: use separate threads for input and rendering
+ while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
+ {
+
+ // handle or dispatch messages
+ if ( msg.message == WM_QUIT )
+ {
+ m_data->m_quit = TRUE;
+ }
+ else
+ {
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ }
+
+// gDemoApplication->displayCallback();
+
+
+ };
+}
+
+int getSpecialKeyFromVirtualKeycode(int virtualKeyCode)
+{
+ int keycode = -1;
+ if (virtualKeyCode >= 'A' && virtualKeyCode <= 'Z')
+ {
+ return virtualKeyCode+32;//todo: fix the ascii A vs a input
+ }
+
+ switch (virtualKeyCode)
+ {
+ case VK_RETURN: {keycode = B3G_RETURN; break; };
+ case VK_F1: {keycode = B3G_F1; break;}
+ case VK_F2: {keycode = B3G_F2; break;}
+ case VK_F3: {keycode = B3G_F3; break;}
+ case VK_F4: {keycode = B3G_F4; break;}
+ case VK_F5: {keycode = B3G_F5; break;}
+ case VK_F6: {keycode = B3G_F6; break;}
+ case VK_F7: {keycode = B3G_F7; break;}
+ case VK_F8: {keycode = B3G_F8; break;}
+ case VK_F9: {keycode = B3G_F9; break;}
+ case VK_F10: {keycode= B3G_F10; break;}
+
+ //case VK_SPACE: {keycode= ' '; break;}
+
+ case VK_NEXT: {keycode= B3G_PAGE_DOWN; break;}
+ case VK_PRIOR: {keycode= B3G_PAGE_UP; break;}
+
+ case VK_INSERT: {keycode= B3G_INSERT; break;}
+ case VK_BACK: {keycode= B3G_BACKSPACE; break;}
+ case VK_DELETE: {keycode= B3G_DELETE; break;}
+
+ case VK_END:{keycode= B3G_END; break;}
+ case VK_HOME:{keycode= B3G_HOME; break;}
+ case VK_LEFT:{keycode= B3G_LEFT_ARROW; break;}
+ case VK_UP:{keycode= B3G_UP_ARROW; break;}
+ case VK_RIGHT:{keycode= B3G_RIGHT_ARROW; break;}
+ case VK_DOWN:{keycode= B3G_DOWN_ARROW; break;}
+ case VK_SHIFT:{keycode=B3G_SHIFT;break;}
+ case VK_MENU:{keycode=B3G_ALT;break;}
+ case VK_CONTROL:{keycode=B3G_CONTROL;break;}
+ default:
+ {
+ //keycode = MapVirtualKey( virtualKeyCode, MAPVK_VK_TO_CHAR ) & 0x0000FFFF;
+ }
+ };
+
+ return keycode;
+}
+
+
+int getAsciiCodeFromVirtualKeycode(int virtualKeyCode)
+{
+ int keycode = 0xffffffff;
+
+ if (virtualKeyCode >= 'a' && virtualKeyCode <= 'z')
+ {
+ return virtualKeyCode;
+ }
+
+ if (virtualKeyCode >= 'A' && virtualKeyCode <= 'Z')
+ {
+ return virtualKeyCode+32;//todo: fix the ascii A vs a input
+ }
+
+ return keycode;
+}
+
+bool Win32Window::isModifierKeyPressed(int key)
+{
+ bool isPressed = false;
+
+ switch (key)
+ {
+ case B3G_ALT:
+ {
+ isPressed = ((sData->m_internalKeyModifierFlags&INTERNAL_ALT_MODIFIER)!=0);
+ break;
+ };
+ case B3G_SHIFT:
+ {
+ isPressed = ((sData->m_internalKeyModifierFlags&INTERNAL_SHIFT_MODIFIER)!=0);
+ break;
+ };
+ case B3G_CONTROL:
+ {
+ isPressed = ((sData->m_internalKeyModifierFlags&INTERNAL_CONTROL_MODIFIER)!=0);
+ break;
+ };
+
+ default:
+ {
+ }
+ };
+ return isPressed;//m_internalKeyModifierFlags
+}
+
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ //printf("msg = %d\n", message);
+ switch (message)
+ {
+
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ BeginPaint(hWnd, &ps);
+ EndPaint(hWnd, &ps);
+ }
+ return 1;
+
+ case WM_ERASEBKGND:
+ return 1;
+
+ case WM_CLOSE:
+ if (sData)
+ sData->m_quit = true;
+ //PostQuitMessage(0);
+ return 1;
+
+ case WM_DESTROY:
+ if (sData)
+ sData->m_quit = true;
+ //PostQuitMessage(0);
+ return 1;
+
+ case WM_SYSKEYUP:
+ case WM_KEYUP:
+ {
+
+ int keycode = getSpecialKeyFromVirtualKeycode(wParam);
+ switch (keycode)
+ {
+ case B3G_ALT:
+ {
+ sData->m_internalKeyModifierFlags&=~INTERNAL_ALT_MODIFIER;
+ break;
+ };
+ case B3G_SHIFT:
+ {
+ sData->m_internalKeyModifierFlags &= ~INTERNAL_SHIFT_MODIFIER;
+ break;
+ };
+ case B3G_CONTROL:
+ {
+ sData->m_internalKeyModifierFlags &=~INTERNAL_CONTROL_MODIFIER;
+ break;
+ };
+ }
+
+ if (keycode>=0 && sData && sData->m_keyboardCallback )
+ {
+ int state=0;
+ (*sData->m_keyboardCallback)(keycode,state);
+ }
+ return 0;
+ }
+ case WM_CHAR:
+ {
+ //skip 'enter' key, it is processed in WM_KEYUP/WM_KEYDOWN
+ int keycode = getAsciiCodeFromVirtualKeycode(wParam);
+ if (keycode < 0)
+ {
+ if (sData && sData->m_keyboardCallback && ((HIWORD(lParam) & KF_REPEAT) == 0))
+ {
+ int state = 1;
+ (*sData->m_keyboardCallback)(wParam, state);
+ }
+ }
+ return 0;
+ }
+ case WM_SYSKEYDOWN:
+ case WM_KEYDOWN:
+ {
+ int keycode = getSpecialKeyFromVirtualKeycode(wParam);
+ switch (keycode)
+ {
+ case B3G_ALT:
+ {
+ sData->m_internalKeyModifierFlags|=INTERNAL_ALT_MODIFIER;
+ break;
+ };
+ case B3G_SHIFT:
+ {
+ sData->m_internalKeyModifierFlags |= INTERNAL_SHIFT_MODIFIER;
+ break;
+ };
+ case B3G_CONTROL:
+ {
+ sData->m_internalKeyModifierFlags |=INTERNAL_CONTROL_MODIFIER;
+ break;
+ };
+ }
+ if (keycode>=0 && sData && sData->m_keyboardCallback)// && ((HIWORD(lParam) & KF_REPEAT) == 0))
+ {
+ int state = 1;
+ (*sData->m_keyboardCallback)(keycode,state);
+ return 1;
+ }
+ return 0;
+ }
+
+ case WM_MBUTTONUP:
+ {
+ int xPos = LOWORD(lParam);
+ int yPos = HIWORD(lParam);
+ if (sData)
+ {
+ sData->m_mouseMButton=0;
+ sData->m_mouseXpos = xPos;
+ sData->m_mouseYpos = yPos;
+ if (sData && sData->m_mouseButtonCallback)
+ (*sData->m_mouseButtonCallback)(1,0,xPos,yPos);
+ }
+ break;
+ }
+ case WM_MBUTTONDOWN:
+ {
+ int xPos = LOWORD(lParam);
+ int yPos = HIWORD(lParam);
+ if (sData)
+ {
+ sData->m_mouseMButton=1;
+ sData->m_mouseXpos = xPos;
+ sData->m_mouseYpos = yPos;
+ if (sData && sData->m_mouseButtonCallback)
+ (*sData->m_mouseButtonCallback)(1,1,xPos,yPos);
+ }
+ break;
+ }
+
+ case WM_LBUTTONUP:
+ {
+ int xPos = LOWORD(lParam);
+ int yPos = HIWORD(lParam);
+ if (sData)
+ {
+ sData->m_mouseLButton=0;
+ sData->m_mouseXpos = xPos;
+ sData->m_mouseYpos = yPos;
+
+ if (sData && sData->m_mouseButtonCallback)
+ (*sData->m_mouseButtonCallback)(0,0,xPos,yPos);
+
+ }
+ // gDemoApplication->mouseFunc(0,1,xPos,yPos);
+ break;
+ }
+ case WM_LBUTTONDOWN:
+ {
+ int xPos = LOWORD(lParam);
+ int yPos = HIWORD(lParam);
+ if (sData)
+ {
+ sData->m_mouseLButton=1;
+ sData->m_mouseXpos = xPos;
+ sData->m_mouseYpos = yPos;
+
+ if (sData && sData->m_mouseButtonCallback)
+ (*sData->m_mouseButtonCallback)(0,1,xPos,yPos);
+ }
+ break;
+ }
+
+ case 0x020e://WM_MOUSEWHEEL_LEFT_RIGHT
+ {
+
+ int zDelta = (short)HIWORD(wParam);
+ int xPos = LOWORD(lParam);
+ int yPos = HIWORD(lParam);
+ //m_cameraDistance -= zDelta*0.01;
+ if (sData && sData->m_wheelCallback)
+ (*sData->m_wheelCallback)(-float(zDelta)*0.05f,0);
+ return 1;
+ break;
+ }
+ case 0x020A://WM_MOUSEWHEEL:
+ {
+
+ int zDelta = (short)HIWORD(wParam);
+ int xPos = LOWORD(lParam);
+ int yPos = HIWORD(lParam);
+ //m_cameraDistance -= zDelta*0.01;
+ if (sData && sData->m_wheelCallback)
+ (*sData->m_wheelCallback)(0,float(zDelta)*0.05f);
+ return 1;
+ break;
+ }
+
+ case WM_MOUSEMOVE:
+ {
+ int xPos = LOWORD(lParam);
+ int yPos = HIWORD(lParam);
+ sData->m_mouseXpos = xPos;
+ sData->m_mouseYpos = yPos;
+
+ if (sData && sData->m_mouseMoveCallback)
+ (*sData->m_mouseMoveCallback)(xPos,yPos);
+
+ break;
+ }
+ case WM_RBUTTONUP:
+ {
+ int xPos = LOWORD(lParam);
+ int yPos = HIWORD(lParam);
+ sData->m_mouseRButton = 1;
+
+ if (sData && sData->m_mouseButtonCallback)
+ (*sData->m_mouseButtonCallback)(2,0,sData->m_mouseXpos,sData->m_mouseYpos);
+
+ //gDemoApplication->mouseFunc(2,1,xPos,yPos);
+ break;
+ }
+ case WM_RBUTTONDOWN:
+ {
+ int xPos = LOWORD(lParam);
+ int yPos = HIWORD(lParam);
+ sData->m_mouseRButton = 0;
+ if (sData && sData->m_mouseButtonCallback)
+ (*sData->m_mouseButtonCallback)(2,1,sData->m_mouseXpos,sData->m_mouseYpos);
+
+ break;
+ }
+ case WM_QUIT:
+ {
+ return 0;
+ break;
+ }
+ case WM_SIZE: // Size Action Has Taken Place
+
+ RECT clientRect;
+ GetClientRect(hWnd,&clientRect);
+
+ switch (wParam) // Evaluate Size Action
+ {
+
+ case SIZE_MINIMIZED: // Was Window Minimized?
+ return 0; // Return
+
+ case SIZE_MAXIMIZED: // Was Window Maximized?
+ case SIZE_RESTORED: // Was Window Restored?
+ RECT wr;
+ GetWindowRect(hWnd,&wr);
+
+ sData->m_fullWindowWidth = wr.right-wr.left;
+ sData->m_fullWindowHeight = wr.bottom-wr.top;//LOWORD (lParam) HIWORD (lParam);
+ sData->m_openglViewportWidth = clientRect.right;
+ sData->m_openglViewportHeight = clientRect.bottom;
+ glViewport(0, 0, sData->m_openglViewportWidth, sData->m_openglViewportHeight);
+
+ if (sData->m_resizeCallback)
+ (*sData->m_resizeCallback)(sData->m_openglViewportWidth,sData->m_openglViewportHeight);
+ //if (sOpenGLInitialized)
+ //{
+ // //gDemoApplication->reshape(sWidth,sHeight);
+ //}
+ return 0; // Return
+ }
+ break;
+
+ default:{
+
+
+ }
+ };
+
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+
+
+void Win32Window::setWindowTitle(const char* titleChar)
+{
+
+ wchar_t windowTitle[1024];
+ swprintf(windowTitle, 1024, L"%hs", titleChar);
+
+ DWORD dwResult;
+
+#ifdef _WIN64
+ SetWindowTextW(m_data->m_hWnd, windowTitle);
+#else
+ SendMessageTimeoutW(m_data->m_hWnd, WM_SETTEXT, 0,
+ reinterpret_cast<LPARAM>(windowTitle),
+ SMTO_ABORTIFHUNG, 2000, &dwResult);
+#endif
+}
+
+void Win32Window::createWindow(const b3gWindowConstructionInfo& ci)
+{
+ int oglViewportWidth = ci.m_width;
+ int oglViewportHeight = ci.m_height;
+ bool fullscreen = ci.m_fullscreen;
+ int colorBitsPerPixel = ci.m_colorBitsPerPixel;
+ void* windowHandle = ci.m_windowHandle;
+
+ // get handle to exe file
+ HINSTANCE hInstance = GetModuleHandle(0);
+
+
+ // create the window if we need to and we do not use the null device
+ if (!windowHandle)
+ {
+#ifdef UNICODE
+ const wchar_t * ClassName = L"DeviceWin32";
+ const wchar_t* emptyString= L"";
+#else
+ const char* ClassName = "DeviceWin32";
+ const char* emptyString = "";
+#endif
+ // Register Class
+ WNDCLASSEX wcex;
+ wcex.cbSize = sizeof(WNDCLASSEX);
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = WndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hInstance;
+ wcex.hIcon = LoadIcon( NULL, IDI_APPLICATION ); //(HICON)LoadImage(hInstance, "bullet_ico.ico", IMAGE_ICON, 0,0, LR_LOADTRANSPARENT);//LR_LOADFROMFILE);
+ wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ wcex.lpszMenuName = 0;
+ wcex.lpszClassName = ClassName;
+ wcex.hIconSm = 0;
+
+ // if there is an icon, load it
+// wcex.hIcon = (HICON)LoadImage(hInstance, "bullet.ico", IMAGE_ICON, 0,0, LR_LOADFROMFILE);
+
+ RegisterClassEx(&wcex);
+
+ // calculate client size
+
+ RECT clientSize;
+ clientSize.top = 0;
+ clientSize.left = 0;
+ clientSize.right = oglViewportWidth;
+ clientSize.bottom = oglViewportHeight;
+
+ DWORD style = WS_POPUP;
+
+ if (!fullscreen)
+ style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX;
+
+ AdjustWindowRect(&clientSize, style, false);
+
+ m_data->m_fullWindowWidth = clientSize.right - clientSize.left;
+ m_data->m_fullWindowHeight = clientSize.bottom - clientSize.top;
+
+ int windowLeft = (GetSystemMetrics(SM_CXSCREEN) - m_data->m_fullWindowWidth) / 2;
+ int windowTop = (GetSystemMetrics(SM_CYSCREEN) - m_data->m_fullWindowHeight) / 2;
+
+ if (fullscreen)
+ {
+ windowLeft = 0;
+ windowTop = 0;
+ }
+
+ // create window
+
+ m_data->m_hWnd = CreateWindow( ClassName, emptyString, style, windowLeft, windowTop,
+ m_data->m_fullWindowWidth, m_data->m_fullWindowHeight,NULL, NULL, hInstance, NULL);
+
+
+ RECT clientRect;
+ GetClientRect(m_data->m_hWnd,&clientRect);
+
+
+
+ ShowWindow(m_data->m_hWnd, SW_SHOW);
+ UpdateWindow(m_data->m_hWnd);
+
+ MoveWindow(m_data->m_hWnd, windowLeft, windowTop, m_data->m_fullWindowWidth, m_data->m_fullWindowHeight, TRUE);
+
+ GetClientRect(m_data->m_hWnd,&clientRect);
+ int w = clientRect.right-clientRect.left;
+ int h = clientRect.bottom-clientRect.top;
+// printf("actual client OpenGL viewport width / height = %d, %d\n",w,h);
+ m_data->m_openglViewportHeight = h;
+ m_data->m_openglViewportWidth = w;
+
+ }
+ else if (windowHandle)
+ {
+ // attach external window
+ m_data->m_hWnd = static_cast<HWND>(windowHandle);
+ RECT r;
+ GetWindowRect(m_data->m_hWnd, &r);
+ m_data->m_fullWindowWidth = r.right - r.left;
+ m_data->m_fullWindowHeight= r.bottom - r.top;
+
+
+ //sFullScreen = false;
+ //sExternalWindow = true;
+ }
+
+
+ if (fullscreen)
+ {
+ DEVMODE dm;
+ memset(&dm, 0, sizeof(dm));
+ dm.dmSize = sizeof(dm);
+ // use default values from current setting
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
+ m_data->m_oldScreenWidth = dm.dmPelsWidth;
+ m_data->m_oldHeight = dm.dmPelsHeight;
+ m_data->m_oldBitsPerPel = dm.dmBitsPerPel;
+
+ dm.dmPelsWidth = oglViewportWidth;
+ dm.dmPelsHeight = oglViewportHeight;
+ if (colorBitsPerPixel)
+ {
+ dm.dmBitsPerPel = colorBitsPerPixel;
+ }
+ dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
+
+ LONG res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
+ if (res != DISP_CHANGE_SUCCESSFUL)
+ { // try again without forcing display frequency
+ dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+ res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
+ }
+
+ }
+
+
+}
+
+
+void Win32Window::switchFullScreen(bool fullscreen,int width,int height,int colorBitsPerPixel)
+{
+
+ LONG res;
+ DEVMODE dm;
+ memset(&dm, 0, sizeof(dm));
+ dm.dmSize = sizeof(dm);
+ // use default values from current setting
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
+
+ dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
+
+ if (fullscreen && !m_data->m_oldScreenWidth)
+ {
+ m_data->m_oldScreenWidth = dm.dmPelsWidth;
+ m_data->m_oldHeight = dm.dmPelsHeight;
+ m_data->m_oldBitsPerPel = dm.dmBitsPerPel;
+
+ if (width && height)
+ {
+ dm.dmPelsWidth = width;
+ dm.dmPelsHeight = height;
+ } else
+ {
+ dm.dmPelsWidth = m_data->m_fullWindowWidth;
+ dm.dmPelsHeight = m_data->m_fullWindowHeight;
+ }
+ if (colorBitsPerPixel)
+ {
+ dm.dmBitsPerPel = colorBitsPerPixel;
+ }
+ } else
+ {
+ if (m_data->m_oldScreenWidth)
+ {
+ dm.dmPelsWidth = m_data->m_oldScreenWidth;
+ dm.dmPelsHeight= m_data->m_oldHeight;
+ dm.dmBitsPerPel = m_data->m_oldBitsPerPel;
+ }
+ }
+
+ if (fullscreen)
+ {
+
+ res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
+ if (!res)
+ {
+ dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+ res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
+ }
+
+ DWORD style = WS_POPUP;
+ SetWindowLong(m_data->m_hWnd, GWL_STYLE, style);
+
+ MoveWindow(m_data->m_hWnd, 0, 0, m_data->m_fullWindowWidth, m_data->m_fullWindowHeight, TRUE);
+
+ SetWindowPos(m_data->m_hWnd, NULL,0,0, (int)width, (int)height,
+ SWP_FRAMECHANGED |SWP_SHOWWINDOW);//|SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOOWNERZORDER | SWP_NOREPOSITION | SWP_NOZORDER);
+
+
+ } else
+ {
+ res = ChangeDisplaySettings(&dm, 0);
+
+ DWORD style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX;
+ SetWindowLong(m_data->m_hWnd, GWL_STYLE, style);
+
+ SetWindowPos(m_data->m_hWnd, NULL,0,0, (int)width, (int)height,
+ SWP_FRAMECHANGED |SWP_SHOWWINDOW);
+ //|SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOOWNERZORDER | SWP_NOREPOSITION | SWP_NOZORDER);
+
+ }
+
+
+}
+
+
+
+Win32Window::Win32Window()
+{
+ m_data = new InternalData2();
+ sData = m_data;
+
+}
+
+Win32Window::~Win32Window()
+{
+ setKeyboardCallback(0);
+ setMouseMoveCallback(0);
+ setMouseButtonCallback(0);
+ setWheelCallback(0);
+ setResizeCallback(0);
+
+ sData = 0;
+ delete m_data;
+
+}
+
+void Win32Window::setRenderCallback( b3RenderCallback renderCallback)
+{
+
+}
+
+void Win32Window::closeWindow()
+{
+ setKeyboardCallback(0);
+ setMouseMoveCallback(0);
+ setMouseButtonCallback(0);
+ setWheelCallback(0);
+ setResizeCallback(0);
+ setRenderCallback(0);
+
+
+ DestroyWindow(this->m_data->m_hWnd);
+}
+
+void Win32Window::getMouseCoordinates(int& x, int& y)
+{
+ x = m_data->m_mouseXpos;
+ y = m_data->m_mouseYpos;
+
+}
+
+void Win32Window::runMainLoop()
+{
+
+}
+
+
+void Win32Window::startRendering()
+{
+ pumpMessage();
+
+// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //clear buffers
+
+ //glCullFace(GL_BACK);
+ //glFrontFace(GL_CCW);
+ // glEnable(GL_DEPTH_TEST);
+
+
+
+}
+
+
+void Win32Window::renderAllObjects()
+{
+}
+
+void Win32Window::endRendering()
+{
+ SwapBuffers( m_data->m_hDC );
+}
+
+float Win32Window::getTimeInSeconds()
+{
+ return 0.f;
+}
+
+void Win32Window::setDebugMessage(int x,int y,const char* message)
+{
+}
+
+void Win32Window::setRequestExit()
+{
+ m_data->m_quit = true;
+}
+bool Win32Window::requestedExit() const
+{
+ return m_data->m_quit;
+}
+
+void Win32Window::setWheelCallback(b3WheelCallback wheelCallback)
+{
+ m_data->m_wheelCallback = wheelCallback;
+}
+
+void Win32Window::setMouseMoveCallback(b3MouseMoveCallback mouseCallback)
+{
+ m_data->m_mouseMoveCallback = mouseCallback;
+}
+
+void Win32Window::setMouseButtonCallback(b3MouseButtonCallback mouseCallback)
+{
+ m_data->m_mouseButtonCallback = mouseCallback;
+}
+
+void Win32Window::setResizeCallback(b3ResizeCallback resizeCallback)
+{
+ m_data->m_resizeCallback = resizeCallback;
+ if (m_data->m_resizeCallback)
+ (*m_data->m_resizeCallback)(m_data->m_openglViewportWidth,m_data->m_openglViewportHeight);
+}
+
+void Win32Window::setKeyboardCallback( b3KeyboardCallback keyboardCallback)
+{
+ m_data->m_keyboardCallback = keyboardCallback;
+
+}
+
+b3KeyboardCallback Win32Window::getKeyboardCallback()
+{
+ return m_data->m_keyboardCallback;
+}
+
+b3MouseMoveCallback Win32Window::getMouseMoveCallback()
+{
+ return m_data->m_mouseMoveCallback;
+}
+b3MouseButtonCallback Win32Window::getMouseButtonCallback()
+{
+ return m_data->m_mouseButtonCallback;
+}
+b3ResizeCallback Win32Window::getResizeCallback()
+{
+ return m_data->m_resizeCallback;
+}
+b3WheelCallback Win32Window::getWheelCallback()
+{
+ return m_data->m_wheelCallback;
+}
+#endif
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32Window.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32Window.h
new file mode 100644
index 0000000000..d10e65d6ec
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/Win32Window.h
@@ -0,0 +1,86 @@
+/*
+Copyright (c) 2012 Advanced Micro Devices, Inc.
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+//Originally written by Erwin Coumans
+
+
+#ifndef _WIN32_WINDOW_H
+#define _WIN32_WINDOW_H
+
+
+
+struct InternalData2;
+
+#include "CommonWindowInterface.h"
+
+class Win32Window : public CommonWindowInterface
+{
+ protected:
+
+ struct InternalData2* m_data;
+
+
+ void pumpMessage();
+
+
+
+public:
+
+ Win32Window();
+
+ virtual ~Win32Window();
+
+ virtual void createWindow(const b3gWindowConstructionInfo& ci);
+
+ virtual void switchFullScreen(bool fullscreen,int width=0,int height=0,int colorBitsPerPixel=0);
+
+ virtual void closeWindow();
+
+ virtual void runMainLoop();
+
+ virtual void startRendering();
+
+ virtual void renderAllObjects();
+
+ virtual void endRendering();
+
+ virtual float getTimeInSeconds();
+
+ virtual void setDebugMessage(int x,int y,const char* message);
+
+ virtual bool requestedExit() const;
+
+ virtual void setRequestExit();
+
+ virtual void getMouseCoordinates(int& x, int& y);
+
+ virtual void setMouseMoveCallback(b3MouseMoveCallback mouseCallback);
+ virtual void setMouseButtonCallback(b3MouseButtonCallback mouseCallback);
+ virtual void setResizeCallback(b3ResizeCallback resizeCallback);
+ virtual void setWheelCallback(b3WheelCallback wheelCallback);
+ virtual void setKeyboardCallback( b3KeyboardCallback keyboardCallback);
+
+ virtual b3MouseMoveCallback getMouseMoveCallback();
+ virtual b3MouseButtonCallback getMouseButtonCallback();
+ virtual b3ResizeCallback getResizeCallback();
+ virtual b3WheelCallback getWheelCallback();
+ virtual b3KeyboardCallback getKeyboardCallback();
+
+ virtual void setRenderCallback( b3RenderCallback renderCallback);
+
+ virtual void setWindowTitle(const char* title);
+
+ virtual bool isModifierKeyPressed(int key);
+};
+
+#endif //_WIN32_WINDOW_H
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.cpp b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.cpp
new file mode 100644
index 0000000000..68aa22720b
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.cpp
@@ -0,0 +1,1118 @@
+#include "X11OpenGLWindow.h"
+#include "OpenGLInclude.h"
+
+#include<stdio.h>
+#include<stdlib.h>
+#ifdef GLEW_STATIC
+#include "CustomGL/glew.h"
+#else
+#include <GL/glew.h>
+#endif//GLEW_STATIC
+
+#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+#include "CustomGL/glxew.h"
+#else
+#include<GL/glx.h>
+#endif // GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+#include <assert.h>
+
+//#define DYNAMIC_LOAD_X11_FUNCTIONS
+#ifdef DYNAMIC_LOAD_X11_FUNCTIONS
+#include <dlfcn.h>
+#endif //DYNAMIC_LOAD_X11_FUNCTIONS
+
+//#include<X11/X.h>
+//#include<X11/Xlib.h>
+//#include<GL/gl.h>
+
+//defined in GL/glxew.h
+//#include<GL/glu.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <pthread.h>
+
+GLint att[] = { GLX_RGBA,
+GLX_DEPTH_SIZE, 24,
+GLX_RED_SIZE , 8,
+GLX_GREEN_SIZE , 8,
+GLX_BLUE_SIZE , 8,
+GLX_ALPHA_SIZE , 8,
+GLX_STENCIL_SIZE , 8,
+GLX_DOUBLEBUFFER,
+None };
+/*
+ static int att[] =
+ {
+ GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None
+
+ GLX_X_RENDERABLE , True,
+ GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
+ GLX_RENDER_TYPE , GLX_RGBA_BIT,
+ GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR,
+ GLX_RED_SIZE , 8,
+ GLX_GREEN_SIZE , 8,
+ GLX_BLUE_SIZE , 8,
+ GLX_ALPHA_SIZE , 8,
+ GLX_DEPTH_SIZE , 24,
+ GLX_STENCIL_SIZE , 8,
+ GLX_DOUBLEBUFFER , True,
+ None
+ };
+*/
+static bool forceOpenGL3 = true;
+
+
+
+#ifdef DYNAMIC_LOAD_X11_FUNCTIONS
+
+///our X11 function typedefs
+
+typedef int (*PFNXFREE)(void*);
+typedef XErrorHandler (* PFNXSETERRORHANDLER) (XErrorHandler);
+typedef int (* PFNXSYNC) (Display* a,Bool b);
+typedef Display* (* PFNXOPENDISPLAY) (_Xconst char* a);
+typedef Colormap (*PFNXCREATECOLORMAP) (Display* a,Window b,Visual* c,int d);
+typedef Window (*PFNXCREATEWINDOW) (Display* a,Window b,int c,int d,unsigned int e,unsigned int f,unsigned int g,int h,unsigned int i,Visual* j,unsigned long k,XSetWindowAttributes* l);
+typedef int (*PFNXMAPWINDOW) (Display*, Window);
+typedef int (*PFNXSTORENAME) (Display* a,Window b,_Xconst char* c);
+typedef int (*PFNXCLOSEDISPLAY) (Display* a);
+typedef int (*PFNXDESTROYWINDOW) (Display* a,Window b);
+typedef int (*PFNXRAISEWINDOW) (Display* a, Window b);
+
+#if NeedWidePrototypes
+ typedef KeySym* (*PFNXGETKEYBOARDMAPPING) (Display*,unsigned int,int,int*);
+ typedef KeySym (*PFNXKEYCODETOKEYSYM) (Display* a,unsigned int b,int c);
+#else
+ typedef KeySym* (*PFNXGETKEYBOARDMAPPING) (Display*,KeyCode,int,int*);
+ typedef KeySym (*PFNXKEYCODETOKEYSYM) (Display* a,KeyCode b,int c);
+#endif
+typedef void (*PFNXCONVERTCASE) (KeySym /* sym */,KeySym * /* lower */,KeySym * /* upper */);
+typedef int (*PFNXPENDING) (Display* a);
+typedef int (*PFNXNEXTEVENT) (Display* a,XEvent* b);
+typedef int (*PFNXEVENTSQUEUED) (Display* a,int b);
+typedef int (*PFNXPEEKEVENT) (Display* a,XEvent* b);
+typedef KeySym (*PFNXLOOKUPKEYSYM) (XKeyEvent* a,int b);
+typedef Status (*PFNXGETWINDOWATTRIBUTES) (Display* a,Window b,XWindowAttributes* c);
+
+#define X11_LIBRARY "libX11.so.6"
+
+#define MyXSync m_data->m_x11_XSync
+#define MyXGetKeyboardMapping m_data->m_x11_XGetKeyboardMapping
+#define MyXSetErrorHandler m_data->m_x11_XSetErrorHandler
+#define MyXOpenDisplay m_data->m_x11_XOpenDisplay
+#define MyXCreateColormap m_data->m_x11_XCreateColormap
+#define MyXCreateWindow m_data->m_x11_XCreateWindow
+#define MyXMapWindow m_data->m_x11_XMapWindow
+#define MyXStoreName m_data->m_x11_XStoreName
+#define MyXDestroyWindow m_data->m_x11_XDestroyWindow
+#define MyXRaiseWindow m_data->m_x11_XRaiseWindow
+#define MyXCloseDisplay m_data->m_x11_XCloseDisplay
+#define MyXKeycodeToKeysym m_data->m_x11_XKeycodeToKeysym
+#define MyXConvertCase m_data->m_x11_XConvertCase
+#define MyXPending m_data->m_x11_XPending
+#define MyXNextEvent m_data->m_x11_XNextEvent
+#define MyXEventsQueued m_data->m_x11_XEventsQueued
+#define MyXPeekEvent m_data->m_x11_XPeekEvent
+#define MyXNextEvent m_data->m_x11_XNextEvent
+#define MyXGetWindowAttributes m_data->m_x11_XGetWindowAttributes
+#define MyXStoreName m_data->m_x11_XStoreName
+#define MyXFree m_data->m_x11_XFree
+#define MyXMapWindow m_data->m_x11_XMapWindow
+#define MyXStoreName m_data->m_x11_XStoreName
+#define MyXLookupKeysym m_data->m_x11_XLookupKeysym
+
+#else
+#define MyXSync XSync
+#define MyXGetKeyboardMapping XGetKeyboardMapping
+#define MyXSetErrorHandler XSetErrorHandler
+#define MyXOpenDisplay XOpenDisplay
+#define MyXCreateColormap XCreateColormap
+#define MyXCreateWindow XCreateWindow
+#define MyXMapWindow XMapWindow
+#define MyXStoreName XStoreName
+#define MyXDestroyWindow XDestroyWindow
+#define MyXRaiseWindow XRaiseWindow
+#define MyXCloseDisplay XCloseDisplay
+#define MyXKeycodeToKeysym XKeycodeToKeysym
+#define MyXConvertCase XConvertCase
+#define MyXPending XPending
+#define MyXNextEvent XNextEvent
+#define MyXEventsQueued XEventsQueued
+#define MyXPeekEvent XPeekEvent
+#define MyXNextEvent XNextEvent
+#define MyXGetWindowAttributes XGetWindowAttributes
+#define MyXStoreName XStoreName
+#define MyXFree XFree
+#define MyXMapWindow XMapWindow
+#define MyXStoreName XStoreName
+#define MyXLookupKeysym XLookupKeysym
+
+#endif//DYNAMIC_LOAD_X11_FUNCTIONS
+
+enum
+{
+ MY_X11_ALT_KEY = 1,
+ MY_X11_SHIFT_KEY = 2,
+ MY_X11_CONTROL_KEY = 4
+};
+
+struct InternalData2
+{
+ Display* m_dpy;
+ Window m_root;
+ XVisualInfo* m_vi;
+ Colormap m_cmap;
+ XSetWindowAttributes m_swa;
+ Window m_win;
+ GLXContext m_glc;
+ XWindowAttributes m_gwa;
+ XEvent m_xev;
+ GLXFBConfig m_bestFbc;
+ int m_modifierFlags;
+ int m_glWidth;
+ int m_glHeight;
+
+#ifdef DYNAMIC_LOAD_X11_FUNCTIONS
+ //dynamically load stuff
+ void* m_x11_library;
+ PFNXFREE m_x11_XFree;
+ PFNXSETERRORHANDLER m_x11_XSetErrorHandler;
+ PFNXSYNC m_x11_XSync;
+ PFNXOPENDISPLAY m_x11_XOpenDisplay;
+ PFNXCREATECOLORMAP m_x11_XCreateColormap;
+ PFNXCREATEWINDOW m_x11_XCreateWindow;
+ PFNXMAPWINDOW m_x11_XMapWindow;
+ PFNXSTORENAME m_x11_XStoreName;
+ PFNXCLOSEDISPLAY m_x11_XCloseDisplay;
+ PFNXDESTROYWINDOW m_x11_XDestroyWindow;
+ PFNXRAISEWINDOW m_x11_XRaiseWindow;
+ PFNXKEYCODETOKEYSYM m_x11_XKeycodeToKeysym;
+ PFNXGETKEYBOARDMAPPING m_x11_XGetKeyboardMapping;
+ PFNXCONVERTCASE m_x11_XConvertCase;
+ PFNXPENDING m_x11_XPending;
+ PFNXNEXTEVENT m_x11_XNextEvent;
+ PFNXEVENTSQUEUED m_x11_XEventsQueued;
+ PFNXPEEKEVENT m_x11_XPeekEvent;
+ PFNXLOOKUPKEYSYM m_x11_XLookupKeysym;
+ PFNXGETWINDOWATTRIBUTES m_x11_XGetWindowAttributes;
+#endif //DYNAMIC_LOAD_X11_FUNCTIONS
+
+ b3WheelCallback m_wheelCallback;
+ b3MouseMoveCallback m_mouseMoveCallback;
+ b3MouseButtonCallback m_mouseButtonCallback;
+ b3ResizeCallback m_resizeCallback;
+ b3KeyboardCallback m_keyboardCallback;
+
+ InternalData2()
+ :m_dpy(0),
+ m_vi(0),
+ m_modifierFlags(0),
+ m_glWidth(-1),
+ m_glHeight(-1),
+ m_wheelCallback(0),
+ m_mouseMoveCallback(0),
+ m_mouseButtonCallback(0),
+ m_resizeCallback(0),
+ m_keyboardCallback(0)
+ {
+#ifdef DYNAMIC_LOAD_X11_FUNCTIONS
+ m_x11_library = dlopen(X11_LIBRARY, RTLD_LOCAL | RTLD_NOW);
+ if (!m_x11_library)
+ {
+ printf("Error opening X11 library %s\n", X11_LIBRARY);
+ exit(0);
+ }
+
+ bool missingFunc = false;
+
+ missingFunc = ((m_x11_XFree = (PFNXFREE) dlsym(m_x11_library, "XFree"))==NULL) | missingFunc;
+ assert(!missingFunc);
+ if (missingFunc) { printf("Error: missing func XFree in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XSetErrorHandler = (PFNXSETERRORHANDLER) dlsym(m_x11_library,"XSetErrorHandler"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XSetErrorHandler in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XSetErrorHandler = (PFNXSETERRORHANDLER) dlsym(m_x11_library,"XSetErrorHandler"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XSetErrorHandler in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XSync = (PFNXSYNC) dlsym(m_x11_library,"XSync"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XSync in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XOpenDisplay = (PFNXOPENDISPLAY) dlsym(m_x11_library,"XOpenDisplay"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XOpenDisplay in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XCreateColormap = (PFNXCREATECOLORMAP) dlsym(m_x11_library,"XCreateColormap"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XCreateColormap in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XCreateWindow = (PFNXCREATEWINDOW) dlsym(m_x11_library,"XCreateWindow"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XCreateWindow in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XMapWindow = (PFNXMAPWINDOW) dlsym(m_x11_library,"XMapWindow"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XMapWindow in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XStoreName = (PFNXSTORENAME) dlsym(m_x11_library,"XStoreName"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XStoreName in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XCloseDisplay = (PFNXCLOSEDISPLAY) dlsym(m_x11_library,"XCloseDisplay"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XCloseDisplay in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XDestroyWindow = (PFNXDESTROYWINDOW) dlsym(m_x11_library,"XDestroyWindow"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XDestroyWindow in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XRaiseWindow = (PFNXRAISEWINDOW) dlsym(m_x11_library,"XRaiseWindow"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XRaiseWindow in %s, exiting!\n", X11_LIBRARY); exit(0);}
+
+ missingFunc = ((m_x11_XGetKeyboardMapping = (PFNXGETKEYBOARDMAPPING) dlsym(m_x11_library,"XGetKeyboardMapping"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XGetKeyboardMapping in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XKeycodeToKeysym = (PFNXKEYCODETOKEYSYM) dlsym(m_x11_library,"XKeycodeToKeysym"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XKeycodeToKeysym in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XConvertCase = (PFNXCONVERTCASE) dlsym(m_x11_library,"XConvertCase"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XConvertCase in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XPending = (PFNXPENDING) dlsym(m_x11_library,"XPending"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XPending in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XNextEvent = (PFNXNEXTEVENT) dlsym(m_x11_library,"XNextEvent"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XNextEvent in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XEventsQueued = (PFNXEVENTSQUEUED) dlsym(m_x11_library,"XEventsQueued"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XEventsQueued in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XPeekEvent = (PFNXPEEKEVENT) dlsym(m_x11_library,"XPeekEvent"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XPeekEvent in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XLookupKeysym = (PFNXLOOKUPKEYSYM) dlsym(m_x11_library,"XLookupKeysym"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XLookupKeysym in %s, exiting!\n", X11_LIBRARY); exit(0);}
+ missingFunc = ((m_x11_XGetWindowAttributes = (PFNXGETWINDOWATTRIBUTES) dlsym(m_x11_library,"XGetWindowAttributes"))==NULL) | missingFunc;
+ if (missingFunc) { printf("Error: missing func XGetWindowAttributes in %s, exiting!\n", X11_LIBRARY); exit(0);}
+
+ if (missingFunc)
+ {
+ printf("Error: a missing func in %s, exiting!\n", X11_LIBRARY);
+ exit(0);
+ } else
+ {
+ printf("X11 functions dynamically loaded using dlopen/dlsym OK!\n");
+ }
+#endif //DYNAMIC_LOAD_X11_FUNCTIONS
+ }
+};
+
+#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
+typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
+
+// Helper to check for extension string presence. Adapted from:
+// http://www.opengl.org/resources/features/OGLextensions/
+static bool isExtensionSupported(const char *extList, const char *extension)
+{
+ const char *start;
+ const char *where, *terminator;
+
+ /* Extension names should not have spaces. */
+ where = strchr(extension, ' ');
+ if (where || *extension == '\0')
+ return false;
+
+ /* It takes a bit of care to be fool-proof about parsing the
+ OpenGL extensions string. Don't be fooled by sub-strings,
+ etc. */
+ for (start=extList;;) {
+ where = strstr(start, extension);
+
+ if (!where)
+ break;
+
+ terminator = where + strlen(extension);
+
+ if ( where == start || *(where - 1) == ' ' )
+ if ( *terminator == ' ' || *terminator == '\0' )
+ return true;
+
+ start = terminator;
+ }
+
+ return false;
+}
+
+static bool ctxErrorOccurred = false;
+static int ctxErrorHandler( Display *dpy, XErrorEvent *ev )
+{
+ ctxErrorOccurred = true;
+ return 0;
+}
+
+
+
+
+X11OpenGLWindow::X11OpenGLWindow()
+:m_OpenGLInitialized(false),
+m_requestedExit(false)
+{
+ m_data = new InternalData2;
+}
+
+X11OpenGLWindow::~X11OpenGLWindow()
+{
+ if (m_OpenGLInitialized)
+ {
+ disableOpenGL();
+ }
+
+ delete m_data;
+}
+
+
+
+void X11OpenGLWindow::enableOpenGL()
+{
+
+
+ if (forceOpenGL3)
+ {
+ // Get the default screen's GLX extension list
+ const char *glxExts = glXQueryExtensionsString( m_data->m_dpy,
+ DefaultScreen( m_data->m_dpy ) );
+
+ // NOTE: It is not necessary to create or make current to a context before
+ // calling glXGetProcAddressARB, unless we dynamically load OpenGL/GLX/X11
+
+ glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
+ glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
+ glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
+
+ GLXContext ctx = 0;
+
+ // Install an X error handler so the application won't exit if GL 3.0
+ // context allocation fails.
+ //
+ // Note this error handler is global. All display connections in all threads
+ // of a process use the same error handler, so be sure to guard against other
+ // threads issuing X commands while this code is running.
+ ctxErrorOccurred = false;
+ int (*oldHandler)(Display*, XErrorEvent*) =
+ MyXSetErrorHandler(&ctxErrorHandler);
+
+ // Check for the GLX_ARB_create_context extension string and the function.
+ // If either is not present, use GLX 1.3 context creation method.
+ if ( !isExtensionSupported( glxExts, "GLX_ARB_create_context" ) ||
+ !glXCreateContextAttribsARB )
+ {
+ printf( "glXCreateContextAttribsARB() not found"
+ " ... using old-style GLX context\n" );
+ ctx = glXCreateNewContext( m_data->m_dpy, m_data->m_bestFbc, GLX_RGBA_TYPE, 0, True );
+ }
+
+ // If it does, try to get a GL 3.0 context!
+ else
+ {
+ int context_attribs[] = {
+ GLX_CONTEXT_MAJOR_VERSION_ARB ,3,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 2,
+ GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
+ GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,None
+ };
+/*
+ int context_attribs[] =
+ {
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 2,
+
+ //GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+ None
+ };
+*/
+ printf( "Creating context\n" );
+ ctx = glXCreateContextAttribsARB( m_data->m_dpy, m_data->m_bestFbc, 0,
+ True, context_attribs );
+
+ // Sync to ensure any errors generated are processed.
+ MyXSync( m_data->m_dpy, False );
+ if ( !ctxErrorOccurred && ctx )
+ printf( "Created GL 3.0 context\n" );
+ else
+ {
+ // Couldn't create GL 3.0 context. Fall back to old-style 2.x context.
+ // When a context version below 3.0 is requested, implementations will
+ // return the newest context version compatible with OpenGL versions less
+ // than version 3.0.
+ // GLX_CONTEXT_MAJOR_VERSION_ARB = 1
+ context_attribs[1] = 1;
+ // GLX_CONTEXT_MINOR_VERSION_ARB = 0
+ context_attribs[3] = 0;
+
+ ctxErrorOccurred = false;
+
+ printf( "Failed to create GL 3.0 context"
+ " ... using old-style GLX context\n" );
+ ctx = glXCreateContextAttribsARB( m_data->m_dpy, m_data->m_bestFbc, 0,
+ True, context_attribs );
+ }
+ }
+
+ // Sync to ensure any errors generated are processed.
+ MyXSync( m_data->m_dpy, False );
+
+ // Restore the original error handler
+ MyXSetErrorHandler( oldHandler );
+
+ if ( ctxErrorOccurred || !ctx )
+ {
+ printf( "Failed to create an OpenGL context\n" );
+ exit(1);
+ }
+
+ // Verifying that context is a direct context
+ if ( ! glXIsDirect ( m_data->m_dpy, ctx ) )
+ {
+ printf( "Indirect GLX rendering context obtained\n" );
+ }
+ else
+ {
+ printf( "Direct GLX rendering context obtained\n" );
+ }
+
+ printf( "Making context current\n" );
+ glXMakeCurrent( m_data->m_dpy, m_data->m_win, ctx );
+ m_data->m_glc = ctx;
+
+ } else
+ {
+ m_data->m_glc = glXCreateContext(m_data->m_dpy, m_data->m_vi, NULL, GL_TRUE);
+ glXMakeCurrent(m_data->m_dpy, m_data->m_win, m_data->m_glc);
+ }
+
+#ifdef GLEW_INIT_OPENGL11_FUNCTIONS
+{
+ GLboolean res = glewOpenGL11Init();
+ if (res==0)
+ {
+ printf("glewOpenGL11Init OK!\n");
+ } else
+ {
+ printf("ERROR: glewOpenGL11Init failed, exiting!\n");
+ exit(0);
+ }
+}
+
+#endif //GLEW_INIT_OPENGL11_FUNCTIONS
+
+ const GLubyte* ven = glGetString(GL_VENDOR);
+ printf("GL_VENDOR=%s\n", ven);
+
+ const GLubyte* ren = glGetString(GL_RENDERER);
+ printf("GL_RENDERER=%s\n",ren);
+ const GLubyte* ver = glGetString(GL_VERSION);
+ printf("GL_VERSION=%s\n", ver);
+ const GLubyte* sl = glGetString(GL_SHADING_LANGUAGE_VERSION);
+ printf("GL_SHADING_LANGUAGE_VERSION=%s\n", sl);
+
+//Access pthreads as a workaround for a bug in Linux/Ubuntu
+//See https://bugs.launchpad.net/ubuntu/+source/nvidia-graphics-drivers-319/+bug/1248642
+
+ int i=pthread_getconcurrency();
+ printf("pthread_getconcurrency()=%d\n",i);
+
+// const GLubyte* ext = glGetString(GL_EXTENSIONS);
+// printf("GL_EXTENSIONS=%s\n", ext);
+}
+
+void X11OpenGLWindow::disableOpenGL()
+{
+ glXMakeCurrent(m_data->m_dpy, None, NULL);
+ glXDestroyContext(m_data->m_dpy, m_data->m_glc);
+}
+
+
+void X11OpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci)
+{
+
+ m_data->m_dpy = MyXOpenDisplay(NULL);
+
+ if(m_data->m_dpy == NULL) {
+ printf("\n\tcannot connect to X server\n\n");
+ exit(0);
+ }
+
+ m_data->m_root = DefaultRootWindow(m_data->m_dpy);
+
+
+#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+GLboolean res = glewXInit();
+if (res==0)
+{
+ printf("glewXInit OK\n");
+} else
+{
+ printf("glewXInit failed, exit\n");
+ exit(0);
+}
+#endif //GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+
+
+ if (ci.m_openglVersion < 3)
+ {
+ forceOpenGL3 = false;
+ }
+
+ if (forceOpenGL3)
+ {
+ int glxMinor, glxMajor;
+ if (!glXQueryVersion(m_data->m_dpy,&glxMajor,&glxMinor) || (((glxMajor==1)&&(glxMinor<3)) || (glxMajor<1)))
+ {
+ printf("Invalid GLX version: major %d, minor %d\n",glxMajor,glxMinor);
+ exit(0);
+ }
+
+ static int visual_attribs[] =
+ {
+ GLX_X_RENDERABLE , True,
+ GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
+ GLX_RENDER_TYPE , GLX_RGBA_BIT,
+ GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR,
+ GLX_RED_SIZE , 8,
+ GLX_GREEN_SIZE , 8,
+ GLX_BLUE_SIZE , 8,
+ GLX_ALPHA_SIZE , 8,
+ GLX_DEPTH_SIZE , 24,
+ GLX_STENCIL_SIZE , 8,
+ GLX_DOUBLEBUFFER , True,
+ None
+ };
+ int fbcount;
+ GLXFBConfig* fbc = glXChooseFBConfig(m_data->m_dpy, DefaultScreen(m_data->m_dpy), visual_attribs, &fbcount);
+ if (!fbc)
+ {
+ printf( "Failed to retrieve a framebuffer config\n" );
+ exit(1);
+ }
+///don't use highest samples, it is really slow on some NVIDIA Quadro cards
+#ifdef USE_HIGHEST_SAMPLES
+ int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;
+
+ int i;
+ for (i=0; i<fbcount; ++i)
+ {
+ XVisualInfo *vi = glXGetVisualFromFBConfig( m_data->m_dpy, fbc[i] );
+ if ( vi )
+ {
+ int samp_buf, samples;
+ glXGetFBConfigAttrib( m_data->m_dpy, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf );
+ glXGetFBConfigAttrib( m_data->m_dpy, fbc[i], GLX_SAMPLES , &samples );
+
+ //printf( " Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
+ // " SAMPLES = %d\n",
+ // i, vi -> visualid, samp_buf, samples );
+
+ if ( best_fbc < 0 || (samp_buf && (samples > best_num_samp)) )
+ best_fbc = i, best_num_samp = samples;
+ if ( worst_fbc < 0 || (!samp_buf || (samples < worst_num_samp)) )
+ worst_fbc = i, worst_num_samp = samples;
+ }
+ MyXFree( vi );
+ }
+
+ m_data->m_bestFbc = fbc[ best_fbc ];
+#else
+ m_data->m_bestFbc = *fbc;
+#endif
+ // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
+ MyXFree( fbc );
+
+ m_data->m_vi = glXGetVisualFromFBConfig( m_data->m_dpy, m_data->m_bestFbc );
+
+
+ m_data->m_swa.colormap = m_data->m_cmap = MyXCreateColormap( m_data->m_dpy,
+ RootWindow( m_data->m_dpy, m_data->m_vi->screen ),
+ m_data->m_vi->visual, AllocNone );
+ m_data->m_swa.background_pixmap = None ;
+ m_data->m_swa.border_pixel = 0;
+ m_data->m_swa.event_mask = ExposureMask | KeyReleaseMask | KeyPressMask |ButtonPressMask | ButtonReleaseMask |PointerMotionMask|StructureNotifyMask;
+;
+ m_data->m_root = RootWindow( m_data->m_dpy, m_data->m_vi->screen );
+
+ m_data->m_win = MyXCreateWindow( m_data->m_dpy, m_data->m_root,
+ 0, 0, ci.m_width, ci.m_height, 0, m_data->m_vi->depth, InputOutput,
+ m_data->m_vi->visual,
+ CWBorderPixel|CWColormap|CWEventMask, &m_data->m_swa );
+
+ //m_data->m_win = m_data->m_x11_XCreateWindow(m_data->m_dpy, m_data->m_root, 0, 0, ci.m_width, ci.m_height, 0, m_data->m_vi->depth, InputOutput, m_data->m_vi->visual, CWColormap | CWEventMask, &m_data->m_swa);
+
+
+ if (!m_data->m_win)
+ {
+ printf("Cannot create window\n");
+ exit(0);
+ }
+
+ MyXMapWindow(m_data->m_dpy, m_data->m_win);
+ MyXStoreName(m_data->m_dpy, m_data->m_win, "OpenGL3 Window");
+
+
+ } else
+ {
+ m_data->m_vi = glXChooseVisual(m_data->m_dpy, 0, att);
+
+ printf("4\n");
+
+ if(m_data->m_vi == NULL) {
+ printf("\n\tno appropriate visual found\n\n");
+ exit(0);
+ }
+ else {
+ printf("\n\tvisual %p selected\n", (void *)m_data->m_vi->visualid); /* %p creates hexadecimal output like in glxinfo */
+ }
+
+
+ m_data->m_cmap = MyXCreateColormap(m_data->m_dpy, m_data->m_root, m_data->m_vi->visual, AllocNone);
+ m_data->m_swa.colormap = m_data->m_cmap;
+ m_data->m_swa.event_mask = ExposureMask | KeyReleaseMask | KeyPressMask |ButtonPressMask | ButtonReleaseMask |PointerMotionMask|StructureNotifyMask;
+ m_data->m_win = MyXCreateWindow(m_data->m_dpy, m_data->m_root, 0, 0, ci.m_width, ci.m_height, 0, m_data->m_vi->depth, InputOutput, m_data->m_vi->visual, CWColormap | CWEventMask, &m_data->m_swa);
+
+ MyXMapWindow(m_data->m_dpy, m_data->m_win);
+
+ MyXStoreName(m_data->m_dpy, m_data->m_win, "OpenGL2 Window");
+
+
+ }
+
+ enableOpenGL();
+}
+
+void X11OpenGLWindow::closeWindow()
+{
+ disableOpenGL();
+
+ MyXDestroyWindow(m_data->m_dpy, m_data->m_win);
+ MyXCloseDisplay(m_data->m_dpy);
+}
+
+int X11OpenGLWindow::getAsciiCodeFromVirtualKeycode(int keycode)
+{
+ int result = 0;
+
+ KeySym key, key_lc, key_uc;
+
+ int keysyms_per_keycode_return;
+ KeySym *keysym = MyXGetKeyboardMapping(m_data->m_dpy,
+ keycode,
+ 1,
+ &keysyms_per_keycode_return);
+
+ key = keysym[0];
+
+
+ //key = MyXKeycodeToKeysym( m_data->m_dpy, keycode, 0 );
+
+ switch( key )
+ {
+ case XK_Escape: return B3G_ESCAPE;
+ case XK_Return: return B3G_RETURN;
+
+ case XK_Control_L:
+ case XK_Control_R: {
+ return B3G_CONTROL;
+ }
+ case XK_Left: return B3G_LEFT_ARROW;
+ case XK_Right: return B3G_RIGHT_ARROW;
+ case XK_Up: return B3G_UP_ARROW;
+ case XK_Down: return B3G_DOWN_ARROW;
+
+ case XK_Alt_L:
+ case XK_Alt_R:
+ {
+ return B3G_ALT;
+ }
+ case XK_Shift_L:
+ case XK_Shift_R: return B3G_SHIFT;
+ case XK_F1: return B3G_F1;
+ case XK_F2: return B3G_F2;
+ case XK_F3: return B3G_F3;
+ case XK_F4: return B3G_F4;
+ case XK_F5: return B3G_F5;
+ case XK_F6: return B3G_F6;
+ case XK_F7: return B3G_F7;
+ case XK_F8: return B3G_F8;
+ case XK_F9: return B3G_F9;
+ case XK_F10: return B3G_F10;
+ case XK_F11: return B3G_F11;
+ case XK_F12: return B3G_F12;
+ case XK_F13: return B3G_F13;
+ case XK_F14: return B3G_F14;
+ case XK_F15: return B3G_F15;
+ default:
+ // Make lowercase
+ MyXConvertCase( key, &key_lc, &key_uc );
+ key = key_lc;
+ // Valid ISO 8859-1 character?
+ if( (key >= 32 && key <= 126) ||(key >= 160 && key <= 255) )
+ {
+ return (int) key;
+ }
+ result = -1;
+ }
+
+ MyXFree(keysym);
+
+ return result;
+}
+
+bool X11OpenGLWindow::isModifierKeyPressed(int key)
+{
+ bool isPressed = false;
+
+ switch (key)
+ {
+ case B3G_ALT:
+ {
+ isPressed = ((m_data->m_modifierFlags & MY_X11_ALT_KEY)!=0);
+ break;
+ };
+ case B3G_SHIFT:
+ {
+ isPressed = ((m_data->m_modifierFlags & MY_X11_SHIFT_KEY)!=0);
+ break;
+ };
+ case B3G_CONTROL:
+ {
+ isPressed = ((m_data->m_modifierFlags & MY_X11_CONTROL_KEY )!=0);
+ break;
+ };
+
+ default:
+ {
+ }
+ };
+ return isPressed;
+}
+
+void X11OpenGLWindow::pumpMessage()
+{
+
+ int buttonState = 1;
+
+ // Process all pending events
+ while( MyXPending( m_data->m_dpy ) )
+ {
+ MyXNextEvent(m_data->m_dpy, &m_data->m_xev);
+ // printf("#");
+ // fflush(stdout);
+ switch( m_data->m_xev.type )
+ {
+ case KeyPress:
+ {
+ int keycode = getAsciiCodeFromVirtualKeycode(m_data->m_xev.xkey.keycode);
+ switch (keycode)
+ {
+ case B3G_ALT:
+ m_data->m_modifierFlags |= MY_X11_ALT_KEY;
+ break;
+ case B3G_SHIFT:
+ m_data->m_modifierFlags |= MY_X11_SHIFT_KEY;
+ break;
+ case B3G_CONTROL:
+ m_data->m_modifierFlags |= MY_X11_CONTROL_KEY;
+ break;
+ default:
+ {}
+ };
+ if (m_data->m_keyboardCallback)
+ {
+
+ int state = 1;
+ (*m_data->m_keyboardCallback)(keycode,state);
+ // printf("keycode %d",keycode);
+ // fflush(stdout);
+
+ }
+ break;
+ }
+
+ case KeyRelease:
+ {
+ // fflush(stdout);
+ int keycode = getAsciiCodeFromVirtualKeycode( m_data->m_xev.xkey.keycode);
+ switch (keycode)
+ {
+ case B3G_ALT:
+ m_data->m_modifierFlags &= ~MY_X11_ALT_KEY;
+ break;
+ case B3G_SHIFT:
+ m_data->m_modifierFlags &= ~MY_X11_SHIFT_KEY;
+ break;
+ case B3G_CONTROL:
+ m_data->m_modifierFlags &= ~MY_X11_CONTROL_KEY;
+ break;
+ default:
+ {}
+ };
+
+ if (m_data->m_keyboardCallback)
+ {
+#if 0
+ unsigned short is_retriggered = 0;
+///filter out keyboard repeat
+//see http://stackoverflow.com/questions/2100654/ignore-auto-repeat-in-x11-applications
+ if (MyXEventsQueued(m_data->m_dpy, QueuedAfterReading))
+ {
+ XEvent nev;
+ MyXPeekEvent(m_data->m_dpy, &nev);
+
+ if (nev.type == KeyPress && nev.xkey.time == m_data->m_xev.xkey.time &&
+ nev.xkey.keycode == m_data->m_xev.xkey.keycode)
+ {
+ fprintf (stdout, "key #%ld was retriggered.\n",
+ (long) MyXLookupKeysym(&nev.xkey, 0));
+
+ // delete retriggered KeyPress event
+ MyXNextEvent(m_data->m_dpy, & m_data->m_xev);
+ is_retriggered = 1;
+ }
+ }
+#endif
+ int state = 0;
+ (*m_data->m_keyboardCallback)(keycode,state);
+ }
+
+ break;
+ }
+
+ case ButtonRelease:
+ buttonState = 0;
+ //continue with ButtonPress code
+ case ButtonPress:
+ {
+// printf("!");
+// fflush(stdout);
+
+ int button=-1;
+
+ switch (m_data->m_xev.xbutton.button)
+ {
+ case Button1:
+ {
+ button=0;
+ break;
+ }
+ case Button2:
+ {
+ button=1;
+ break;
+ }
+ case Button3:
+ {
+ button=2;
+ break;
+ }
+ case Button4:
+ {
+ if (m_data->m_wheelCallback)
+ {
+ (*m_data->m_wheelCallback)(0,10);
+ }
+ break;
+ }
+ case Button5:
+ {
+ if (m_data->m_wheelCallback)
+ {
+ (*m_data->m_wheelCallback)(0,-10);
+ }
+ break;
+ }
+ }
+ int xpos = m_data->m_xev.xmotion.x;
+ int ypos = m_data->m_xev.xmotion.y;
+
+ if (button>=0 && m_data->m_mouseButtonCallback)
+ {
+// printf("xpos = %d, ypos = %d\n",xpos,ypos);
+
+ (*m_data->m_mouseButtonCallback)(button,buttonState,xpos,ypos);
+ }
+ break;
+ }
+ case MotionNotify:
+ {
+// printf("!");
+// fflush(0);
+ if (m_data->m_mouseMoveCallback)
+ {
+ int xpos = m_data->m_xev.xmotion.x;
+ int ypos = m_data->m_xev.xmotion.y;
+ (*m_data->m_mouseMoveCallback)(xpos,ypos);
+ }
+ break;
+ }
+ case ConfigureNotify:
+ {
+ // printf("@");
+ // fflush(0);
+ m_data->m_glWidth = m_data->m_xev.xconfigure.width;
+ m_data->m_glHeight = m_data->m_xev.xconfigure.height;
+
+ if (m_data->m_resizeCallback)
+ {
+ (*m_data->m_resizeCallback)(m_data->m_xev.xconfigure.width,m_data->m_xev.xconfigure.height);
+ }
+ break;
+ }
+ case ClientMessage:
+ {
+ // printf("?");
+ // fflush(stdout);
+ break;
+ }
+ case Expose:
+ {
+ break;
+ }
+ case DestroyNotify:
+ {
+ break;
+ }
+ default:
+ {
+ //XRRUpdateConfiguration( &event );
+ }
+ };
+ }
+}
+
+
+
+void X11OpenGLWindow::startRendering()
+{
+ pumpMessage();
+
+ MyXGetWindowAttributes(m_data->m_dpy, m_data->m_win, &m_data->m_gwa);
+ glViewport(0, 0, m_data->m_gwa.width, m_data->m_gwa.height);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //clear buffers
+
+ //glCullFace(GL_BACK);
+ //glFrontFace(GL_CCW);
+ glEnable(GL_DEPTH_TEST);
+}
+
+void X11OpenGLWindow::renderAllObjects()
+{
+
+}
+
+void X11OpenGLWindow::endRendering()
+{
+ glXSwapBuffers(m_data->m_dpy, m_data->m_win);
+}
+
+void X11OpenGLWindow::runMainLoop()
+{
+
+}
+
+float X11OpenGLWindow::getTimeInSeconds()
+{
+ return 0.f;
+}
+
+bool X11OpenGLWindow::requestedExit() const
+{
+ return m_requestedExit;
+}
+
+void X11OpenGLWindow::setRequestExit()
+{
+ m_requestedExit=true;
+}
+
+void X11OpenGLWindow::setRenderCallback( b3RenderCallback renderCallback)
+{
+
+}
+
+void X11OpenGLWindow::setWindowTitle(const char* title)
+{
+ MyXStoreName(m_data->m_dpy, m_data->m_win, title);
+}
+
+
+void X11OpenGLWindow::setWheelCallback(b3WheelCallback wheelCallback)
+{
+ m_data->m_wheelCallback = wheelCallback;
+}
+
+void X11OpenGLWindow::setMouseMoveCallback(b3MouseMoveCallback mouseCallback)
+{
+ m_data->m_mouseMoveCallback = mouseCallback;
+}
+
+void X11OpenGLWindow::setMouseButtonCallback(b3MouseButtonCallback mouseCallback)
+{
+ m_data->m_mouseButtonCallback = mouseCallback;
+}
+
+void X11OpenGLWindow::setResizeCallback(b3ResizeCallback resizeCallback)
+{
+ if (resizeCallback && m_data->m_glWidth>0 && m_data->m_glHeight > 0)
+ {
+ resizeCallback(m_data->m_glWidth, m_data->m_glHeight);
+ }
+ m_data->m_resizeCallback = resizeCallback;
+}
+
+void X11OpenGLWindow::setKeyboardCallback( b3KeyboardCallback keyboardCallback)
+{
+ m_data->m_keyboardCallback = keyboardCallback;
+
+}
+
+b3MouseMoveCallback X11OpenGLWindow::getMouseMoveCallback()
+{
+ return m_data->m_mouseMoveCallback;
+}
+b3MouseButtonCallback X11OpenGLWindow::getMouseButtonCallback()
+{
+ return m_data->m_mouseButtonCallback;
+}
+b3ResizeCallback X11OpenGLWindow::getResizeCallback()
+{
+ return m_data->m_resizeCallback;
+}
+b3WheelCallback X11OpenGLWindow::getWheelCallback()
+{
+ return m_data->m_wheelCallback;
+}
+
+
+b3KeyboardCallback X11OpenGLWindow::getKeyboardCallback()
+{
+ return m_data->m_keyboardCallback;
+}
+
+int X11OpenGLWindow::getWidth() const
+{
+ if (m_data)
+ return m_data->m_glWidth;
+ return 0;
+}
+int X11OpenGLWindow::getHeight() const
+{
+ if (m_data)
+ return m_data->m_glHeight;
+ return 0;
+}
+
+
+#include <stdio.h>
+
+int X11OpenGLWindow::fileOpenDialog(char* filename, int maxNameLength)
+{
+ int len = 0;
+ FILE * output = popen("zenity --file-selection --file-filter=\"*.urdf\" --file-filter=\"*.sdf\" --file-filter=\"*.obj\" --file-filter=\"*.*\"","r");
+ if (output)
+ {
+ while( fgets(filename, maxNameLength-1, output) != NULL )
+ {
+ len=strlen(filename);
+ if (len>0)
+ {
+ filename[len-1]=0;
+ printf("file open (length=%d) = %s\n", len,filename);
+ }
+ }
+ pclose(output);
+ } else
+ {
+ printf("Error: fileOpenDialog no popen output, perhaps install zenity?\n");
+ }
+ MyXRaiseWindow(m_data->m_dpy, m_data->m_win);
+ return len;
+
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.h
new file mode 100644
index 0000000000..3d8eac1fcc
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/OpenGLWindow/X11OpenGLWindow.h
@@ -0,0 +1,78 @@
+#ifndef X11_OPENGL_WINDOW_H
+#define X11_OPENGL_WINDOW_H
+
+#define b3gDefaultOpenGLWindow X11OpenGLWindow
+
+#include "CommonWindowInterface.h"
+
+class X11OpenGLWindow : public CommonWindowInterface
+{
+
+ struct InternalData2* m_data;
+ bool m_OpenGLInitialized;
+ bool m_requestedExit;
+
+protected:
+
+ void enableOpenGL();
+
+ void disableOpenGL();
+
+ void pumpMessage();
+
+ int getAsciiCodeFromVirtualKeycode(int orgCode);
+
+public:
+
+ X11OpenGLWindow();
+
+ virtual ~X11OpenGLWindow();
+
+ virtual void createWindow(const b3gWindowConstructionInfo& ci);
+
+ virtual void closeWindow();
+
+ virtual void startRendering();
+
+ virtual void renderAllObjects();
+
+ virtual void endRendering();
+
+ virtual float getRetinaScale() const {return 1.f;}
+ virtual void setAllowRetina(bool /*allowRetina*/) {};
+
+ virtual void runMainLoop();
+ virtual float getTimeInSeconds();
+
+ virtual bool requestedExit() const;
+ virtual void setRequestExit() ;
+
+ virtual bool isModifierKeyPressed(int key);
+
+ virtual void setMouseMoveCallback(b3MouseMoveCallback mouseCallback);
+ virtual void setMouseButtonCallback(b3MouseButtonCallback mouseCallback);
+ virtual void setResizeCallback(b3ResizeCallback resizeCallback);
+ virtual void setWheelCallback(b3WheelCallback wheelCallback);
+ virtual void setKeyboardCallback( b3KeyboardCallback keyboardCallback);
+
+ virtual b3MouseMoveCallback getMouseMoveCallback();
+ virtual b3MouseButtonCallback getMouseButtonCallback();
+ virtual b3ResizeCallback getResizeCallback();
+ virtual b3WheelCallback getWheelCallback();
+ virtual b3KeyboardCallback getKeyboardCallback();
+
+ virtual void setRenderCallback( b3RenderCallback renderCallback);
+
+ virtual void setWindowTitle(const char* title);
+
+ virtual int getWidth() const;
+
+ virtual int getHeight() const;
+
+ int fileOpenDialog(char* filename, int maxNameLength);
+};
+
+
+
+#endif
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/README.md b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/README.md
new file mode 100644
index 0000000000..4e5947a212
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/README.md
@@ -0,0 +1,56 @@
+# exrview
+
+![ScreenShot](screenshots/exrview.png)
+
+Simple cross-platform OpenEXR viewer using TinyEXR, bullet3's windows library and nukler UI library.
+Currently only EXR image with RGB channels can be displayed.
+
+## Requirements
+
+* premake5
+* Visual Studio 2015(2013 will work)
+* OpenGL 2.x
+* GTK+3(optional and Linux only. Used for file dialog support on Linux)
+
+## Build on Windows
+
+ $ premake5 vs2015
+
+## Build on Linux
+
+ $ premake5 gmake
+
+If you want nativefiledialog support(File dialog UI), Install GTK+3 then,
+
+ $ premake5 --with-gtk3nfd gmake
+
+## Build on Mac
+
+ $ premake5 gmake
+
+## Usage
+
+ $ ./bin/native/Release/exrview input.exr
+
+## TODO
+
+* [ ] Retina resolution
+* [ ] Display arbitrary channel EXR
+* [ ] Zoom and pan image
+* [ ] Tone mapping
+
+## Third party licenses
+
+`OpenGLWindow` and `CommonInterfaces` is grabbed from bullet3, which is licensed under zlib lince.
+
+https://github.com/bulletphysics/bullet://github.com/bulletphysics/bullet3
+
+`ThirdPartyLibs/Glew/` is licensed under licensed under the Modified BSD License, the Mesa 3-D License (MIT) and the Khronos License (MIT).
+
+http://glew.sourceforge.net/
+
+nuklear is licensed under MIT.
+
+https://github.com/vurtun/nuklear
+
+See `ThirdPartyLibs/nativefiledialog/LICENSE` for nativefiledialog license.
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/glew.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/glew.h
new file mode 100644
index 0000000000..f33e7d458e
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/glew.h
@@ -0,0 +1,19093 @@
+/*
+** The OpenGL Extension Wrangler Library
+** Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org>
+** Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org>
+** Copyright (C) 2002, Lev Povalahev
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** * The name of the author may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+** THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define GLEW_NO_GLU
+//#define GLEW_INIT_OPENGL11_FUNCTIONS 1
+//#define GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS 1
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.0
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * 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
+ * BRIAN PAUL 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.
+ */
+
+/*
+** Copyright (c) 2007 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are 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 Materials.
+**
+** THE MATERIALS ARE 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 AUTHORS OR COPYRIGHT HOLDERS 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
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#ifndef __glew_h__
+#define __glew_h__
+#define __GLEW_H__
+
+#if defined(__gl_h_) || defined(__GL_H__) || defined(__X_GL_H)
+#error gl.h included before glew.h
+#endif
+#if defined(__gl2_h_)
+#error gl2.h included before glew.h
+#endif
+#if defined(__gltypes_h_)
+#error gltypes.h included before glew.h
+#endif
+#if defined(__REGAL_H__)
+#error Regal.h included before glew.h
+#endif
+#if defined(__glext_h_) || defined(__GLEXT_H_)
+#error glext.h included before glew.h
+#endif
+#if defined(__gl_ATI_h_)
+#error glATI.h included before glew.h
+#endif
+
+#define __gl_h_
+#define __gl2_h_
+#define __GL_H__
+#define __gltypes_h_
+#define __REGAL_H__
+#define __X_GL_H
+#define __glext_h_
+#define __GLEXT_H_
+#define __gl_ATI_h_
+
+#if defined(_WIN32)
+
+/*
+ * GLEW does not include <windows.h> to avoid name space pollution.
+ * GL needs GLAPI and GLAPIENTRY, GLU needs APIENTRY, CALLBACK, and wchar_t
+ * defined properly.
+ */
+/* <windef.h> */
+#ifndef APIENTRY
+#define GLEW_APIENTRY_DEFINED
+# if defined(__MINGW32__) || defined(__CYGWIN__)
+# define APIENTRY __stdcall
+# elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__)
+# define APIENTRY __stdcall
+# else
+# define APIENTRY
+# endif
+#endif
+#ifndef GLAPI
+# if defined(__MINGW32__) || defined(__CYGWIN__)
+# define GLAPI extern
+# endif
+#endif
+/* <winnt.h> */
+#ifndef CALLBACK
+#define GLEW_CALLBACK_DEFINED
+# if defined(__MINGW32__) || defined(__CYGWIN__)
+# define CALLBACK __attribute__ ((__stdcall__))
+# elif (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS)
+# define CALLBACK __stdcall
+# else
+# define CALLBACK
+# endif
+#endif
+/* <wingdi.h> and <winnt.h> */
+#ifndef WINGDIAPI
+#define GLEW_WINGDIAPI_DEFINED
+#define WINGDIAPI __declspec(dllimport)
+#endif
+/* <ctype.h> */
+#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(_WCHAR_T_DEFINED)
+typedef unsigned short wchar_t;
+# define _WCHAR_T_DEFINED
+#endif
+/* <stddef.h> */
+#if !defined(_W64)
+# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && defined(_MSC_VER) && _MSC_VER >= 1300
+# define _W64 __w64
+# else
+# define _W64
+# endif
+#endif
+#if !defined(_PTRDIFF_T_DEFINED) && !defined(_PTRDIFF_T_) && !defined(__MINGW64__)
+# ifdef _WIN64
+typedef __int64 ptrdiff_t;
+# else
+typedef _W64 int ptrdiff_t;
+# endif
+# define _PTRDIFF_T_DEFINED
+# define _PTRDIFF_T_
+#endif
+
+#ifndef GLAPI
+# if defined(__MINGW32__) || defined(__CYGWIN__)
+# define GLAPI extern
+# else
+# define GLAPI WINGDIAPI
+# endif
+#endif
+
+#ifndef GLAPIENTRY
+#define GLAPIENTRY APIENTRY
+#endif
+
+#ifndef GLEWAPIENTRY
+#define GLEWAPIENTRY APIENTRY
+#endif
+
+/*
+ * GLEW_STATIC is defined for static library.
+ * GLEW_BUILD is defined for building the DLL library.
+ */
+
+#ifdef GLEW_STATIC
+# define GLEWAPI extern
+#else
+# ifdef GLEW_BUILD
+# define GLEWAPI extern __declspec(dllexport)
+# else
+# define GLEWAPI extern __declspec(dllimport)
+# endif
+#endif
+
+#else /* _UNIX */
+
+/*
+ * Needed for ptrdiff_t in turn needed by VBO. This is defined by ISO
+ * C. On my system, this amounts to _3 lines_ of included code, all of
+ * them pretty much harmless. If you know of a way of detecting 32 vs
+ * 64 _targets_ at compile time you are free to replace this with
+ * something that's portable. For now, _this_ is the portable solution.
+ * (mem, 2004-01-04)
+ */
+
+#include <stddef.h>
+
+/* SGI MIPSPro doesn't like stdint.h in C++ mode */
+/* ID: 3376260 Solaris 9 has inttypes.h, but not stdint.h */
+
+#if (defined(__sgi) || defined(__sun)) && !defined(__GNUC__)
+#include <inttypes.h>
+#else
+#include <stdint.h>
+#endif
+
+#define GLEW_APIENTRY_DEFINED
+#define APIENTRY
+
+/*
+ * GLEW_STATIC is defined for static library.
+ */
+
+#ifdef GLEW_STATIC
+# define GLEWAPI extern
+#else
+# if defined(__GNUC__) && __GNUC__>=4
+# define GLEWAPI extern __attribute__ ((visibility("default")))
+# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+# define GLEWAPI extern __global
+# else
+# define GLEWAPI extern
+# endif
+#endif
+
+/* <glu.h> */
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+#ifndef GLAPIENTRY
+#define GLAPIENTRY
+#endif
+
+#ifndef GLEWAPIENTRY
+#define GLEWAPIENTRY
+#endif
+
+#endif /* _WIN32 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ----------------------------- GL_VERSION_1_1 ---------------------------- */
+
+#ifndef GL_VERSION_1_1
+#define GL_VERSION_1_1 1
+
+typedef unsigned int GLenum;
+typedef unsigned int GLbitfield;
+typedef unsigned int GLuint;
+typedef int GLint;
+typedef int GLsizei;
+typedef unsigned char GLboolean;
+typedef signed char GLbyte;
+typedef short GLshort;
+typedef unsigned char GLubyte;
+typedef unsigned short GLushort;
+typedef unsigned long GLulong;
+typedef float GLfloat;
+typedef float GLclampf;
+typedef double GLdouble;
+typedef double GLclampd;
+typedef void GLvoid;
+#if defined(_MSC_VER) && _MSC_VER < 1400
+typedef __int64 GLint64EXT;
+typedef unsigned __int64 GLuint64EXT;
+#elif defined(_MSC_VER) || defined(__BORLANDC__)
+typedef signed long long GLint64EXT;
+typedef unsigned long long GLuint64EXT;
+#else
+# if defined(__MINGW32__) || defined(__CYGWIN__)
+#include <inttypes.h>
+# endif
+typedef int64_t GLint64EXT;
+typedef uint64_t GLuint64EXT;
+#endif
+typedef GLint64EXT GLint64;
+typedef GLuint64EXT GLuint64;
+typedef struct __GLsync *GLsync;
+
+typedef char GLchar;
+
+#define GL_ZERO 0
+#define GL_FALSE 0
+#define GL_LOGIC_OP 0x0BF1
+#define GL_NONE 0
+#define GL_TEXTURE_COMPONENTS 0x1003
+#define GL_NO_ERROR 0
+#define GL_POINTS 0x0000
+#define GL_CURRENT_BIT 0x00000001
+#define GL_TRUE 1
+#define GL_ONE 1
+#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001
+#define GL_LINES 0x0001
+#define GL_LINE_LOOP 0x0002
+#define GL_POINT_BIT 0x00000002
+#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002
+#define GL_LINE_STRIP 0x0003
+#define GL_LINE_BIT 0x00000004
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_FAN 0x0006
+#define GL_QUADS 0x0007
+#define GL_QUAD_STRIP 0x0008
+#define GL_POLYGON_BIT 0x00000008
+#define GL_POLYGON 0x0009
+#define GL_POLYGON_STIPPLE_BIT 0x00000010
+#define GL_PIXEL_MODE_BIT 0x00000020
+#define GL_LIGHTING_BIT 0x00000040
+#define GL_FOG_BIT 0x00000080
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_ACCUM 0x0100
+#define GL_LOAD 0x0101
+#define GL_RETURN 0x0102
+#define GL_MULT 0x0103
+#define GL_ADD 0x0104
+#define GL_NEVER 0x0200
+#define GL_ACCUM_BUFFER_BIT 0x00000200
+#define GL_LESS 0x0201
+#define GL_EQUAL 0x0202
+#define GL_LEQUAL 0x0203
+#define GL_GREATER 0x0204
+#define GL_NOTEQUAL 0x0205
+#define GL_GEQUAL 0x0206
+#define GL_ALWAYS 0x0207
+#define GL_SRC_COLOR 0x0300
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_SRC_ALPHA 0x0302
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_DST_ALPHA 0x0304
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#define GL_DST_COLOR 0x0306
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_FRONT_LEFT 0x0400
+#define GL_FRONT_RIGHT 0x0401
+#define GL_BACK_LEFT 0x0402
+#define GL_BACK_RIGHT 0x0403
+#define GL_FRONT 0x0404
+#define GL_BACK 0x0405
+#define GL_LEFT 0x0406
+#define GL_RIGHT 0x0407
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_AUX0 0x0409
+#define GL_AUX1 0x040A
+#define GL_AUX2 0x040B
+#define GL_AUX3 0x040C
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVALID_OPERATION 0x0502
+#define GL_STACK_OVERFLOW 0x0503
+#define GL_STACK_UNDERFLOW 0x0504
+#define GL_OUT_OF_MEMORY 0x0505
+#define GL_2D 0x0600
+#define GL_3D 0x0601
+#define GL_3D_COLOR 0x0602
+#define GL_3D_COLOR_TEXTURE 0x0603
+#define GL_4D_COLOR_TEXTURE 0x0604
+#define GL_PASS_THROUGH_TOKEN 0x0700
+#define GL_POINT_TOKEN 0x0701
+#define GL_LINE_TOKEN 0x0702
+#define GL_POLYGON_TOKEN 0x0703
+#define GL_BITMAP_TOKEN 0x0704
+#define GL_DRAW_PIXEL_TOKEN 0x0705
+#define GL_COPY_PIXEL_TOKEN 0x0706
+#define GL_LINE_RESET_TOKEN 0x0707
+#define GL_EXP 0x0800
+#define GL_VIEWPORT_BIT 0x00000800
+#define GL_EXP2 0x0801
+#define GL_CW 0x0900
+#define GL_CCW 0x0901
+#define GL_COEFF 0x0A00
+#define GL_ORDER 0x0A01
+#define GL_DOMAIN 0x0A02
+#define GL_CURRENT_COLOR 0x0B00
+#define GL_CURRENT_INDEX 0x0B01
+#define GL_CURRENT_NORMAL 0x0B02
+#define GL_CURRENT_TEXTURE_COORDS 0x0B03
+#define GL_CURRENT_RASTER_COLOR 0x0B04
+#define GL_CURRENT_RASTER_INDEX 0x0B05
+#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06
+#define GL_CURRENT_RASTER_POSITION 0x0B07
+#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08
+#define GL_CURRENT_RASTER_DISTANCE 0x0B09
+#define GL_POINT_SMOOTH 0x0B10
+#define GL_POINT_SIZE 0x0B11
+#define GL_POINT_SIZE_RANGE 0x0B12
+#define GL_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_LINE_SMOOTH 0x0B20
+#define GL_LINE_WIDTH 0x0B21
+#define GL_LINE_WIDTH_RANGE 0x0B22
+#define GL_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_LINE_STIPPLE 0x0B24
+#define GL_LINE_STIPPLE_PATTERN 0x0B25
+#define GL_LINE_STIPPLE_REPEAT 0x0B26
+#define GL_LIST_MODE 0x0B30
+#define GL_MAX_LIST_NESTING 0x0B31
+#define GL_LIST_BASE 0x0B32
+#define GL_LIST_INDEX 0x0B33
+#define GL_POLYGON_MODE 0x0B40
+#define GL_POLYGON_SMOOTH 0x0B41
+#define GL_POLYGON_STIPPLE 0x0B42
+#define GL_EDGE_FLAG 0x0B43
+#define GL_CULL_FACE 0x0B44
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_FRONT_FACE 0x0B46
+#define GL_LIGHTING 0x0B50
+#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
+#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52
+#define GL_LIGHT_MODEL_AMBIENT 0x0B53
+#define GL_SHADE_MODEL 0x0B54
+#define GL_COLOR_MATERIAL_FACE 0x0B55
+#define GL_COLOR_MATERIAL_PARAMETER 0x0B56
+#define GL_COLOR_MATERIAL 0x0B57
+#define GL_FOG 0x0B60
+#define GL_FOG_INDEX 0x0B61
+#define GL_FOG_DENSITY 0x0B62
+#define GL_FOG_START 0x0B63
+#define GL_FOG_END 0x0B64
+#define GL_FOG_MODE 0x0B65
+#define GL_FOG_COLOR 0x0B66
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_TEST 0x0B71
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_ACCUM_CLEAR_VALUE 0x0B80
+#define GL_STENCIL_TEST 0x0B90
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_MATRIX_MODE 0x0BA0
+#define GL_NORMALIZE 0x0BA1
+#define GL_VIEWPORT 0x0BA2
+#define GL_MODELVIEW_STACK_DEPTH 0x0BA3
+#define GL_PROJECTION_STACK_DEPTH 0x0BA4
+#define GL_TEXTURE_STACK_DEPTH 0x0BA5
+#define GL_MODELVIEW_MATRIX 0x0BA6
+#define GL_PROJECTION_MATRIX 0x0BA7
+#define GL_TEXTURE_MATRIX 0x0BA8
+#define GL_ATTRIB_STACK_DEPTH 0x0BB0
+#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1
+#define GL_ALPHA_TEST 0x0BC0
+#define GL_ALPHA_TEST_FUNC 0x0BC1
+#define GL_ALPHA_TEST_REF 0x0BC2
+#define GL_DITHER 0x0BD0
+#define GL_BLEND_DST 0x0BE0
+#define GL_BLEND_SRC 0x0BE1
+#define GL_BLEND 0x0BE2
+#define GL_LOGIC_OP_MODE 0x0BF0
+#define GL_INDEX_LOGIC_OP 0x0BF1
+#define GL_COLOR_LOGIC_OP 0x0BF2
+#define GL_AUX_BUFFERS 0x0C00
+#define GL_DRAW_BUFFER 0x0C01
+#define GL_READ_BUFFER 0x0C02
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_INDEX_CLEAR_VALUE 0x0C20
+#define GL_INDEX_WRITEMASK 0x0C21
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_INDEX_MODE 0x0C30
+#define GL_RGBA_MODE 0x0C31
+#define GL_DOUBLEBUFFER 0x0C32
+#define GL_STEREO 0x0C33
+#define GL_RENDER_MODE 0x0C40
+#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50
+#define GL_POINT_SMOOTH_HINT 0x0C51
+#define GL_LINE_SMOOTH_HINT 0x0C52
+#define GL_POLYGON_SMOOTH_HINT 0x0C53
+#define GL_FOG_HINT 0x0C54
+#define GL_TEXTURE_GEN_S 0x0C60
+#define GL_TEXTURE_GEN_T 0x0C61
+#define GL_TEXTURE_GEN_R 0x0C62
+#define GL_TEXTURE_GEN_Q 0x0C63
+#define GL_PIXEL_MAP_I_TO_I 0x0C70
+#define GL_PIXEL_MAP_S_TO_S 0x0C71
+#define GL_PIXEL_MAP_I_TO_R 0x0C72
+#define GL_PIXEL_MAP_I_TO_G 0x0C73
+#define GL_PIXEL_MAP_I_TO_B 0x0C74
+#define GL_PIXEL_MAP_I_TO_A 0x0C75
+#define GL_PIXEL_MAP_R_TO_R 0x0C76
+#define GL_PIXEL_MAP_G_TO_G 0x0C77
+#define GL_PIXEL_MAP_B_TO_B 0x0C78
+#define GL_PIXEL_MAP_A_TO_A 0x0C79
+#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0
+#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1
+#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2
+#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3
+#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4
+#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5
+#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6
+#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7
+#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8
+#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9
+#define GL_UNPACK_SWAP_BYTES 0x0CF0
+#define GL_UNPACK_LSB_FIRST 0x0CF1
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_PACK_SWAP_BYTES 0x0D00
+#define GL_PACK_LSB_FIRST 0x0D01
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_MAP_COLOR 0x0D10
+#define GL_MAP_STENCIL 0x0D11
+#define GL_INDEX_SHIFT 0x0D12
+#define GL_INDEX_OFFSET 0x0D13
+#define GL_RED_SCALE 0x0D14
+#define GL_RED_BIAS 0x0D15
+#define GL_ZOOM_X 0x0D16
+#define GL_ZOOM_Y 0x0D17
+#define GL_GREEN_SCALE 0x0D18
+#define GL_GREEN_BIAS 0x0D19
+#define GL_BLUE_SCALE 0x0D1A
+#define GL_BLUE_BIAS 0x0D1B
+#define GL_ALPHA_SCALE 0x0D1C
+#define GL_ALPHA_BIAS 0x0D1D
+#define GL_DEPTH_SCALE 0x0D1E
+#define GL_DEPTH_BIAS 0x0D1F
+#define GL_MAX_EVAL_ORDER 0x0D30
+#define GL_MAX_LIGHTS 0x0D31
+#define GL_MAX_CLIP_PLANES 0x0D32
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_PIXEL_MAP_TABLE 0x0D34
+#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35
+#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36
+#define GL_MAX_NAME_STACK_DEPTH 0x0D37
+#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38
+#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_INDEX_BITS 0x0D51
+#define GL_RED_BITS 0x0D52
+#define GL_GREEN_BITS 0x0D53
+#define GL_BLUE_BITS 0x0D54
+#define GL_ALPHA_BITS 0x0D55
+#define GL_DEPTH_BITS 0x0D56
+#define GL_STENCIL_BITS 0x0D57
+#define GL_ACCUM_RED_BITS 0x0D58
+#define GL_ACCUM_GREEN_BITS 0x0D59
+#define GL_ACCUM_BLUE_BITS 0x0D5A
+#define GL_ACCUM_ALPHA_BITS 0x0D5B
+#define GL_NAME_STACK_DEPTH 0x0D70
+#define GL_AUTO_NORMAL 0x0D80
+#define GL_MAP1_COLOR_4 0x0D90
+#define GL_MAP1_INDEX 0x0D91
+#define GL_MAP1_NORMAL 0x0D92
+#define GL_MAP1_TEXTURE_COORD_1 0x0D93
+#define GL_MAP1_TEXTURE_COORD_2 0x0D94
+#define GL_MAP1_TEXTURE_COORD_3 0x0D95
+#define GL_MAP1_TEXTURE_COORD_4 0x0D96
+#define GL_MAP1_VERTEX_3 0x0D97
+#define GL_MAP1_VERTEX_4 0x0D98
+#define GL_MAP2_COLOR_4 0x0DB0
+#define GL_MAP2_INDEX 0x0DB1
+#define GL_MAP2_NORMAL 0x0DB2
+#define GL_MAP2_TEXTURE_COORD_1 0x0DB3
+#define GL_MAP2_TEXTURE_COORD_2 0x0DB4
+#define GL_MAP2_TEXTURE_COORD_3 0x0DB5
+#define GL_MAP2_TEXTURE_COORD_4 0x0DB6
+#define GL_MAP2_VERTEX_3 0x0DB7
+#define GL_MAP2_VERTEX_4 0x0DB8
+#define GL_MAP1_GRID_DOMAIN 0x0DD0
+#define GL_MAP1_GRID_SEGMENTS 0x0DD1
+#define GL_MAP2_GRID_DOMAIN 0x0DD2
+#define GL_MAP2_GRID_SEGMENTS 0x0DD3
+#define GL_TEXTURE_1D 0x0DE0
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0
+#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1
+#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2
+#define GL_SELECTION_BUFFER_POINTER 0x0DF3
+#define GL_SELECTION_BUFFER_SIZE 0x0DF4
+#define GL_TEXTURE_WIDTH 0x1000
+#define GL_TRANSFORM_BIT 0x00001000
+#define GL_TEXTURE_HEIGHT 0x1001
+#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
+#define GL_TEXTURE_BORDER_COLOR 0x1004
+#define GL_TEXTURE_BORDER 0x1005
+#define GL_DONT_CARE 0x1100
+#define GL_FASTEST 0x1101
+#define GL_NICEST 0x1102
+#define GL_AMBIENT 0x1200
+#define GL_DIFFUSE 0x1201
+#define GL_SPECULAR 0x1202
+#define GL_POSITION 0x1203
+#define GL_SPOT_DIRECTION 0x1204
+#define GL_SPOT_EXPONENT 0x1205
+#define GL_SPOT_CUTOFF 0x1206
+#define GL_CONSTANT_ATTENUATION 0x1207
+#define GL_LINEAR_ATTENUATION 0x1208
+#define GL_QUADRATIC_ATTENUATION 0x1209
+#define GL_COMPILE 0x1300
+#define GL_COMPILE_AND_EXECUTE 0x1301
+#define GL_BYTE 0x1400
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_SHORT 0x1402
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_INT 0x1404
+#define GL_UNSIGNED_INT 0x1405
+#define GL_FLOAT 0x1406
+#define GL_2_BYTES 0x1407
+#define GL_3_BYTES 0x1408
+#define GL_4_BYTES 0x1409
+#define GL_DOUBLE 0x140A
+#define GL_CLEAR 0x1500
+#define GL_AND 0x1501
+#define GL_AND_REVERSE 0x1502
+#define GL_COPY 0x1503
+#define GL_AND_INVERTED 0x1504
+#define GL_NOOP 0x1505
+#define GL_XOR 0x1506
+#define GL_OR 0x1507
+#define GL_NOR 0x1508
+#define GL_EQUIV 0x1509
+#define GL_INVERT 0x150A
+#define GL_OR_REVERSE 0x150B
+#define GL_COPY_INVERTED 0x150C
+#define GL_OR_INVERTED 0x150D
+#define GL_NAND 0x150E
+#define GL_SET 0x150F
+#define GL_EMISSION 0x1600
+#define GL_SHININESS 0x1601
+#define GL_AMBIENT_AND_DIFFUSE 0x1602
+#define GL_COLOR_INDEXES 0x1603
+#define GL_MODELVIEW 0x1700
+#define GL_PROJECTION 0x1701
+#define GL_TEXTURE 0x1702
+#define GL_COLOR 0x1800
+#define GL_DEPTH 0x1801
+#define GL_STENCIL 0x1802
+#define GL_COLOR_INDEX 0x1900
+#define GL_STENCIL_INDEX 0x1901
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_RED 0x1903
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_ALPHA 0x1906
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+#define GL_BITMAP 0x1A00
+#define GL_POINT 0x1B00
+#define GL_LINE 0x1B01
+#define GL_FILL 0x1B02
+#define GL_RENDER 0x1C00
+#define GL_FEEDBACK 0x1C01
+#define GL_SELECT 0x1C02
+#define GL_FLAT 0x1D00
+#define GL_SMOOTH 0x1D01
+#define GL_KEEP 0x1E00
+#define GL_REPLACE 0x1E01
+#define GL_INCR 0x1E02
+#define GL_DECR 0x1E03
+#define GL_VENDOR 0x1F00
+#define GL_RENDERER 0x1F01
+#define GL_VERSION 0x1F02
+#define GL_EXTENSIONS 0x1F03
+#define GL_S 0x2000
+#define GL_ENABLE_BIT 0x00002000
+#define GL_T 0x2001
+#define GL_R 0x2002
+#define GL_Q 0x2003
+#define GL_MODULATE 0x2100
+#define GL_DECAL 0x2101
+#define GL_TEXTURE_ENV_MODE 0x2200
+#define GL_TEXTURE_ENV_COLOR 0x2201
+#define GL_TEXTURE_ENV 0x2300
+#define GL_EYE_LINEAR 0x2400
+#define GL_OBJECT_LINEAR 0x2401
+#define GL_SPHERE_MAP 0x2402
+#define GL_TEXTURE_GEN_MODE 0x2500
+#define GL_OBJECT_PLANE 0x2501
+#define GL_EYE_PLANE 0x2502
+#define GL_NEAREST 0x2600
+#define GL_LINEAR 0x2601
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_CLAMP 0x2900
+#define GL_REPEAT 0x2901
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_OFFSET_POINT 0x2A01
+#define GL_POLYGON_OFFSET_LINE 0x2A02
+#define GL_R3_G3_B2 0x2A10
+#define GL_V2F 0x2A20
+#define GL_V3F 0x2A21
+#define GL_C4UB_V2F 0x2A22
+#define GL_C4UB_V3F 0x2A23
+#define GL_C3F_V3F 0x2A24
+#define GL_N3F_V3F 0x2A25
+#define GL_C4F_N3F_V3F 0x2A26
+#define GL_T2F_V3F 0x2A27
+#define GL_T4F_V4F 0x2A28
+#define GL_T2F_C4UB_V3F 0x2A29
+#define GL_T2F_C3F_V3F 0x2A2A
+#define GL_T2F_N3F_V3F 0x2A2B
+#define GL_T2F_C4F_N3F_V3F 0x2A2C
+#define GL_T4F_C4F_N3F_V4F 0x2A2D
+#define GL_CLIP_PLANE0 0x3000
+#define GL_CLIP_PLANE1 0x3001
+#define GL_CLIP_PLANE2 0x3002
+#define GL_CLIP_PLANE3 0x3003
+#define GL_CLIP_PLANE4 0x3004
+#define GL_CLIP_PLANE5 0x3005
+#define GL_LIGHT0 0x4000
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_LIGHT1 0x4001
+#define GL_LIGHT2 0x4002
+#define GL_LIGHT3 0x4003
+#define GL_LIGHT4 0x4004
+#define GL_LIGHT5 0x4005
+#define GL_LIGHT6 0x4006
+#define GL_LIGHT7 0x4007
+#define GL_HINT_BIT 0x00008000
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_ALPHA4 0x803B
+#define GL_ALPHA8 0x803C
+#define GL_ALPHA12 0x803D
+#define GL_ALPHA16 0x803E
+#define GL_LUMINANCE4 0x803F
+#define GL_LUMINANCE8 0x8040
+#define GL_LUMINANCE12 0x8041
+#define GL_LUMINANCE16 0x8042
+#define GL_LUMINANCE4_ALPHA4 0x8043
+#define GL_LUMINANCE6_ALPHA2 0x8044
+#define GL_LUMINANCE8_ALPHA8 0x8045
+#define GL_LUMINANCE12_ALPHA4 0x8046
+#define GL_LUMINANCE12_ALPHA12 0x8047
+#define GL_LUMINANCE16_ALPHA16 0x8048
+#define GL_INTENSITY 0x8049
+#define GL_INTENSITY4 0x804A
+#define GL_INTENSITY8 0x804B
+#define GL_INTENSITY12 0x804C
+#define GL_INTENSITY16 0x804D
+#define GL_RGB4 0x804F
+#define GL_RGB5 0x8050
+#define GL_RGB8 0x8051
+#define GL_RGB10 0x8052
+#define GL_RGB12 0x8053
+#define GL_RGB16 0x8054
+#define GL_RGBA2 0x8055
+#define GL_RGBA4 0x8056
+#define GL_RGB5_A1 0x8057
+#define GL_RGBA8 0x8058
+#define GL_RGB10_A2 0x8059
+#define GL_RGBA12 0x805A
+#define GL_RGBA16 0x805B
+#define GL_TEXTURE_RED_SIZE 0x805C
+#define GL_TEXTURE_GREEN_SIZE 0x805D
+#define GL_TEXTURE_BLUE_SIZE 0x805E
+#define GL_TEXTURE_ALPHA_SIZE 0x805F
+#define GL_TEXTURE_LUMINANCE_SIZE 0x8060
+#define GL_TEXTURE_INTENSITY_SIZE 0x8061
+#define GL_PROXY_TEXTURE_1D 0x8063
+#define GL_PROXY_TEXTURE_2D 0x8064
+#define GL_TEXTURE_PRIORITY 0x8066
+#define GL_TEXTURE_RESIDENT 0x8067
+#define GL_TEXTURE_BINDING_1D 0x8068
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_VERTEX_ARRAY 0x8074
+#define GL_NORMAL_ARRAY 0x8075
+#define GL_COLOR_ARRAY 0x8076
+#define GL_INDEX_ARRAY 0x8077
+#define GL_TEXTURE_COORD_ARRAY 0x8078
+#define GL_EDGE_FLAG_ARRAY 0x8079
+#define GL_VERTEX_ARRAY_SIZE 0x807A
+#define GL_VERTEX_ARRAY_TYPE 0x807B
+#define GL_VERTEX_ARRAY_STRIDE 0x807C
+#define GL_NORMAL_ARRAY_TYPE 0x807E
+#define GL_NORMAL_ARRAY_STRIDE 0x807F
+#define GL_COLOR_ARRAY_SIZE 0x8081
+#define GL_COLOR_ARRAY_TYPE 0x8082
+#define GL_COLOR_ARRAY_STRIDE 0x8083
+#define GL_INDEX_ARRAY_TYPE 0x8085
+#define GL_INDEX_ARRAY_STRIDE 0x8086
+#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A
+#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C
+#define GL_VERTEX_ARRAY_POINTER 0x808E
+#define GL_NORMAL_ARRAY_POINTER 0x808F
+#define GL_COLOR_ARRAY_POINTER 0x8090
+#define GL_INDEX_ARRAY_POINTER 0x8091
+#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092
+#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093
+#define GL_COLOR_INDEX1_EXT 0x80E2
+#define GL_COLOR_INDEX2_EXT 0x80E3
+#define GL_COLOR_INDEX4_EXT 0x80E4
+#define GL_COLOR_INDEX8_EXT 0x80E5
+#define GL_COLOR_INDEX12_EXT 0x80E6
+#define GL_COLOR_INDEX16_EXT 0x80E7
+#define GL_EVAL_BIT 0x00010000
+#define GL_LIST_BIT 0x00020000
+#define GL_TEXTURE_BIT 0x00040000
+#define GL_SCISSOR_BIT 0x00080000
+#define GL_ALL_ATTRIB_BITS 0x000fffff
+#define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff
+
+#ifdef GLEW_INIT_OPENGL11_FUNCTIONS
+
+typedef void (GLAPIENTRY * PFNGLACCUMPROC) (GLenum op, GLfloat value);
+typedef void (GLAPIENTRY * PFNGLALPHAFUNCPROC) (GLenum func, GLclampf ref);
+typedef GLboolean (GLAPIENTRY * PFNGLARETEXTURESRESIDENTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences);
+typedef void (GLAPIENTRY * PFNGLARRAYELEMENTPROC) (GLint i);
+typedef void (GLAPIENTRY * PFNGLBEGINPROC) (GLenum mode);
+typedef void (GLAPIENTRY * PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
+typedef void (GLAPIENTRY * PFNGLBITMAPPROC) (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor);
+typedef void (GLAPIENTRY * PFNGLCALLLISTPROC) (GLuint list);
+typedef void (GLAPIENTRY * PFNGLCALLLISTSPROC) (GLsizei n, GLenum type, const GLvoid *lists);
+typedef void (GLAPIENTRY * PFNGLCLEARPROC) (GLbitfield mask);
+typedef void (GLAPIENTRY * PFNGLCLEARACCUMPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GLAPIENTRY * PFNGLCLEARCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+typedef void (GLAPIENTRY * PFNGLCLEARDEPTHPROC) (GLclampd depth);
+typedef void (GLAPIENTRY * PFNGLCLEARINDEXPROC) (GLfloat c);
+typedef void (GLAPIENTRY * PFNGLCLEARSTENCILPROC) (GLint s);
+typedef void (GLAPIENTRY * PFNGLCLIPPLANEPROC) (GLenum plane, const GLdouble *equation);
+typedef void (GLAPIENTRY * PFNGLCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (GLAPIENTRY * PFNGLCOLOR3BVPROC) (const GLbyte *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (GLAPIENTRY * PFNGLCOLOR3DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (GLAPIENTRY * PFNGLCOLOR3FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR3IPROC) (GLint red, GLint green, GLint blue);
+typedef void (GLAPIENTRY * PFNGLCOLOR3IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (GLAPIENTRY * PFNGLCOLOR3SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (GLAPIENTRY * PFNGLCOLOR3UBVPROC) (const GLubyte *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (GLAPIENTRY * PFNGLCOLOR3UIVPROC) (const GLuint *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (GLAPIENTRY * PFNGLCOLOR3USVPROC) (const GLushort *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4BPROC) (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha);
+typedef void (GLAPIENTRY * PFNGLCOLOR4BVPROC) (const GLbyte *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4DPROC) (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha);
+typedef void (GLAPIENTRY * PFNGLCOLOR4DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4FPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GLAPIENTRY * PFNGLCOLOR4FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4IPROC) (GLint red, GLint green, GLint blue, GLint alpha);
+typedef void (GLAPIENTRY * PFNGLCOLOR4IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4SPROC) (GLshort red, GLshort green, GLshort blue, GLshort alpha);
+typedef void (GLAPIENTRY * PFNGLCOLOR4SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4UBPROC) (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+typedef void (GLAPIENTRY * PFNGLCOLOR4UBVPROC) (const GLubyte *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4UIPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha);
+typedef void (GLAPIENTRY * PFNGLCOLOR4UIVPROC) (const GLuint *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4USPROC) (GLushort red, GLushort green, GLushort blue, GLushort alpha);
+typedef void (GLAPIENTRY * PFNGLCOLOR4USVPROC) (const GLushort *v);
+typedef void (GLAPIENTRY * PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+typedef void (GLAPIENTRY * PFNGLCOLORMATERIALPROC) (GLenum face, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLCOPYPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLCULLFACEPROC) (GLenum mode);
+typedef void (GLAPIENTRY * PFNGLDELETELISTSPROC) (GLuint list, GLsizei range);
+typedef void (GLAPIENTRY * PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
+typedef void (GLAPIENTRY * PFNGLDEPTHFUNCPROC) (GLenum func);
+typedef void (GLAPIENTRY * PFNGLDEPTHMASKPROC) (GLboolean flag);
+typedef void (GLAPIENTRY * PFNGLDEPTHRANGEPROC) (GLclampd zNear, GLclampd zFar);
+typedef void (GLAPIENTRY * PFNGLDISABLEPROC) (GLenum cap);
+typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEPROC) (GLenum array);
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (GLAPIENTRY * PFNGLDRAWBUFFERPROC) (GLenum mode);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
+typedef void (GLAPIENTRY * PFNGLDRAWPIXELSPROC) (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLEDGEFLAGPROC) (GLboolean flag);
+typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTERPROC) (GLsizei stride, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLEDGEFLAGVPROC) (const GLboolean *flag);
+typedef void (GLAPIENTRY * PFNGLENABLEPROC) (GLenum cap);
+typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEPROC) (GLenum array);
+typedef void (GLAPIENTRY * PFNGLENDPROC) (void);
+typedef void (GLAPIENTRY * PFNGLENDLISTPROC) (void);
+typedef void (GLAPIENTRY * PFNGLEVALCOORD1DPROC) (GLdouble u);
+typedef void (GLAPIENTRY * PFNGLEVALCOORD1DVPROC) (const GLdouble *u);
+typedef void (GLAPIENTRY * PFNGLEVALCOORD1FPROC) (GLfloat u);
+typedef void (GLAPIENTRY * PFNGLEVALCOORD1FVPROC) (const GLfloat *u);
+typedef void (GLAPIENTRY * PFNGLEVALCOORD2DPROC) (GLdouble u, GLdouble v);
+typedef void (GLAPIENTRY * PFNGLEVALCOORD2DVPROC) (const GLdouble *u);
+typedef void (GLAPIENTRY * PFNGLEVALCOORD2FPROC) (GLfloat u, GLfloat v);
+typedef void (GLAPIENTRY * PFNGLEVALCOORD2FVPROC) (const GLfloat *u);
+typedef void (GLAPIENTRY * PFNGLEVALMESH1PROC) (GLenum mode, GLint i1, GLint i2);
+typedef void (GLAPIENTRY * PFNGLEVALMESH2PROC) (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2);
+typedef void (GLAPIENTRY * PFNGLEVALPOINT1PROC) (GLint i);
+typedef void (GLAPIENTRY * PFNGLEVALPOINT2PROC) (GLint i, GLint j);
+typedef void (GLAPIENTRY * PFNGLFEEDBACKBUFFERPROC) (GLsizei size, GLenum type, GLfloat *buffer);
+typedef void (GLAPIENTRY * PFNGLFINISHPROC) (void);
+typedef void (GLAPIENTRY * PFNGLFLUSHPROC) (void);
+typedef void (GLAPIENTRY * PFNGLFOGFPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLFOGFVPROC) (GLenum pname, const GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLFOGIPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLFOGIVPROC) (GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLFRONTFACEPROC) (GLenum mode);
+typedef void (GLAPIENTRY * PFNGLFRUSTUMPROC) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+typedef GLuint (GLAPIENTRY * PFNGLGENLISTSPROC) (GLsizei range);
+typedef void (GLAPIENTRY * PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
+typedef void (GLAPIENTRY * PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *params);
+typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEPROC) (GLenum plane, GLdouble *equation);
+typedef void (GLAPIENTRY * PFNGLGETDOUBLEVPROC) (GLenum pname, GLdouble *params);
+typedef GLenum (GLAPIENTRY * PFNGLGETERRORPROC) (void);
+typedef void (GLAPIENTRY * PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERVPROC) (GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETLIGHTFVPROC) (GLenum light, GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETLIGHTIVPROC) (GLenum light, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETMAPDVPROC) (GLenum target, GLenum query, GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLGETMAPFVPROC) (GLenum target, GLenum query, GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLGETMAPIVPROC) (GLenum target, GLenum query, GLint *v);
+typedef void (GLAPIENTRY * PFNGLGETMATERIALFVPROC) (GLenum face, GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETMATERIALIVPROC) (GLenum face, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETPIXELMAPFVPROC) (GLenum map, GLfloat *values);
+typedef void (GLAPIENTRY * PFNGLGETPIXELMAPUIVPROC) (GLenum map, GLuint *values);
+typedef void (GLAPIENTRY * PFNGLGETPIXELMAPUSVPROC) (GLenum map, GLushort *values);
+typedef void (GLAPIENTRY * PFNGLGETPOINTERVPROC) (GLenum pname, GLvoid* *params);
+typedef void (GLAPIENTRY * PFNGLGETPOLYGONSTIPPLEPROC) (GLubyte *mask);
+typedef GLubyte* (GLAPIENTRY * PFNGLGETSTRINGPROC) (GLenum s);
+typedef void (GLAPIENTRY * PFNGLGETTEXENVFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETTEXENVIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETTEXGENDVPROC) (GLenum coord, GLenum pname, GLdouble *params);
+typedef void (GLAPIENTRY * PFNGLGETTEXGENFVPROC) (GLenum coord, GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETTEXGENIVPROC) (GLenum coord, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLGETTEXLEVELPARAMETERFVPROC) (GLenum target, GLint level, GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETTEXLEVELPARAMETERIVPROC) (GLenum target, GLint level, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLHINTPROC) (GLenum target, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLINDEXMASKPROC) (GLuint mask);
+typedef void (GLAPIENTRY * PFNGLINDEXPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLINDEXDPROC) (GLdouble c);
+typedef void (GLAPIENTRY * PFNGLINDEXDVPROC) (const GLdouble *c);
+typedef void (GLAPIENTRY * PFNGLINDEXFPROC) (GLfloat c);
+typedef void (GLAPIENTRY * PFNGLINDEXFVPROC) (const GLfloat *c);
+typedef void (GLAPIENTRY * PFNGLINDEXIPROC) (GLint c);
+typedef void (GLAPIENTRY * PFNGLINDEXIVPROC) (const GLint *c);
+typedef void (GLAPIENTRY * PFNGLINDEXSPROC) (GLshort c);
+typedef void (GLAPIENTRY * PFNGLINDEXSVPROC) (const GLshort *c);
+typedef void (GLAPIENTRY * PFNGLINDEXUBPROC) (GLubyte c);
+typedef void (GLAPIENTRY * PFNGLINDEXUBVPROC) (const GLubyte *c);
+typedef void (GLAPIENTRY * PFNGLINITNAMESPROC) (void);
+typedef void (GLAPIENTRY * PFNGLINTERLEAVEDARRAYSPROC) (GLenum format, GLsizei stride, const GLvoid *pointer);
+typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDPROC) (GLenum cap);
+typedef GLboolean (GLAPIENTRY * PFNGLISLISTPROC) (GLuint list);
+typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREPROC) (GLuint texture);
+typedef void (GLAPIENTRY * PFNGLLIGHTMODELFPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLLIGHTMODELFVPROC) (GLenum pname, const GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLLIGHTMODELIPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLLIGHTMODELIVPROC) (GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLLIGHTFPROC) (GLenum light, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLLIGHTFVPROC) (GLenum light, GLenum pname, const GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLLIGHTIPROC) (GLenum light, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLLIGHTIVPROC) (GLenum light, GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLLINESTIPPLEPROC) (GLint factor, GLushort pattern);
+typedef void (GLAPIENTRY * PFNGLLINEWIDTHPROC) (GLfloat width);
+typedef void (GLAPIENTRY * PFNGLLISTBASEPROC) (GLuint base);
+typedef void (GLAPIENTRY * PFNGLLOADIDENTITYPROC) (void);
+typedef void (GLAPIENTRY * PFNGLLOADMATRIXDPROC) (const GLdouble *m);
+typedef void (GLAPIENTRY * PFNGLLOADMATRIXFPROC) (const GLfloat *m);
+typedef void (GLAPIENTRY * PFNGLLOADNAMEPROC) (GLuint name);
+typedef void (GLAPIENTRY * PFNGLLOGICOPPROC) (GLenum opcode);
+typedef void (GLAPIENTRY * PFNGLMAP1DPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+typedef void (GLAPIENTRY * PFNGLMAP1FPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+typedef void (GLAPIENTRY * PFNGLMAP2DPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+typedef void (GLAPIENTRY * PFNGLMAP2FPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+typedef void (GLAPIENTRY * PFNGLMAPGRID1DPROC) (GLint un, GLdouble u1, GLdouble u2);
+typedef void (GLAPIENTRY * PFNGLMAPGRID1FPROC) (GLint un, GLfloat u1, GLfloat u2);
+typedef void (GLAPIENTRY * PFNGLMAPGRID2DPROC) (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2);
+typedef void (GLAPIENTRY * PFNGLMAPGRID2FPROC) (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2);
+typedef void (GLAPIENTRY * PFNGLMATERIALFPROC) (GLenum face, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLMATERIALFVPROC) (GLenum face, GLenum pname, const GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLMATERIALIPROC) (GLenum face, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLMATERIALIVPROC) (GLenum face, GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLMATRIXMODEPROC) (GLenum mode);
+typedef void (GLAPIENTRY * PFNGLMULTMATRIXDPROC) (const GLdouble *m);
+typedef void (GLAPIENTRY * PFNGLMULTMATRIXFPROC) (const GLfloat *m);
+typedef void (GLAPIENTRY * PFNGLNEWLISTPROC) (GLuint list, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLNORMAL3BPROC) (GLbyte nx, GLbyte ny, GLbyte nz);
+typedef void (GLAPIENTRY * PFNGLNORMAL3BVPROC) (const GLbyte *v);
+typedef void (GLAPIENTRY * PFNGLNORMAL3DPROC) (GLdouble nx, GLdouble ny, GLdouble nz);
+typedef void (GLAPIENTRY * PFNGLNORMAL3DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLNORMAL3FPROC) (GLfloat nx, GLfloat ny, GLfloat nz);
+typedef void (GLAPIENTRY * PFNGLNORMAL3FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLNORMAL3IPROC) (GLint nx, GLint ny, GLint nz);
+typedef void (GLAPIENTRY * PFNGLNORMAL3IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLNORMAL3SPROC) (GLshort nx, GLshort ny, GLshort nz);
+typedef void (GLAPIENTRY * PFNGLNORMAL3SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLNORMALPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLORTHOPROC) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+typedef void (GLAPIENTRY * PFNGLPASSTHROUGHPROC) (GLfloat token);
+typedef void (GLAPIENTRY * PFNGLPIXELMAPFVPROC) (GLenum map, GLsizei mapsize, const GLfloat *values);
+typedef void (GLAPIENTRY * PFNGLPIXELMAPUIVPROC) (GLenum map, GLsizei mapsize, const GLuint *values);
+typedef void (GLAPIENTRY * PFNGLPIXELMAPUSVPROC) (GLenum map, GLsizei mapsize, const GLushort *values);
+typedef void (GLAPIENTRY * PFNGLPIXELSTOREFPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFERFPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFERIPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLPIXELZOOMPROC) (GLfloat xfactor, GLfloat yfactor);
+typedef void (GLAPIENTRY * PFNGLPOINTSIZEPROC) (GLfloat size);
+typedef void (GLAPIENTRY * PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units);
+typedef void (GLAPIENTRY * PFNGLPOLYGONSTIPPLEPROC) (const GLubyte *mask);
+typedef void (GLAPIENTRY * PFNGLPOPATTRIBPROC) (void);
+typedef void (GLAPIENTRY * PFNGLPOPCLIENTATTRIBPROC) (void);
+typedef void (GLAPIENTRY * PFNGLPOPMATRIXPROC) (void);
+typedef void (GLAPIENTRY * PFNGLPOPNAMEPROC) (void);
+typedef void (GLAPIENTRY * PFNGLPRIORITIZETEXTURESPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities);
+typedef void (GLAPIENTRY * PFNGLPUSHATTRIBPROC) (GLbitfield mask);
+typedef void (GLAPIENTRY * PFNGLPUSHCLIENTATTRIBPROC) (GLbitfield mask);
+typedef void (GLAPIENTRY * PFNGLPUSHMATRIXPROC) (void);
+typedef void (GLAPIENTRY * PFNGLPUSHNAMEPROC) (GLuint name);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS2DPROC) (GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS2DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS2FPROC) (GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS2FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS2IPROC) (GLint x, GLint y);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS2IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS2SPROC) (GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS2SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS3DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS3FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS3IPROC) (GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS3IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS3SPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS3SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS4DPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS4DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS4FPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS4FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS4IPROC) (GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS4IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS4SPROC) (GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (GLAPIENTRY * PFNGLRASTERPOS4SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLREADBUFFERPROC) (GLenum mode);
+typedef void (GLAPIENTRY * PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLRECTDPROC) (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
+typedef void (GLAPIENTRY * PFNGLRECTDVPROC) (const GLdouble *v1, const GLdouble *v2);
+typedef void (GLAPIENTRY * PFNGLRECTFPROC) (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
+typedef void (GLAPIENTRY * PFNGLRECTFVPROC) (const GLfloat *v1, const GLfloat *v2);
+typedef void (GLAPIENTRY * PFNGLRECTIPROC) (GLint x1, GLint y1, GLint x2, GLint y2);
+typedef void (GLAPIENTRY * PFNGLRECTIVPROC) (const GLint *v1, const GLint *v2);
+typedef void (GLAPIENTRY * PFNGLRECTSPROC) (GLshort x1, GLshort y1, GLshort x2, GLshort y2);
+typedef void (GLAPIENTRY * PFNGLRECTSVPROC) (const GLshort *v1, const GLshort *v2);
+typedef GLint (GLAPIENTRY * PFNGLRENDERMODEPROC) (GLenum mode);
+typedef void (GLAPIENTRY * PFNGLROTATEDPROC) (GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLROTATEFPROC) (GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLSCALEDPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLSCALEFPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLSELECTBUFFERPROC) (GLsizei size, GLuint *buffer);
+typedef void (GLAPIENTRY * PFNGLSHADEMODELPROC) (GLenum mode);
+typedef void (GLAPIENTRY * PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask);
+typedef void (GLAPIENTRY * PFNGLSTENCILMASKPROC) (GLuint mask);
+typedef void (GLAPIENTRY * PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD1DPROC) (GLdouble s);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD1DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD1FPROC) (GLfloat s);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD1FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD1IPROC) (GLint s);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD1IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD1SPROC) (GLshort s);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD1SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2DPROC) (GLdouble s, GLdouble t);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FPROC) (GLfloat s, GLfloat t);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2IPROC) (GLint s, GLint t);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2SPROC) (GLshort s, GLshort t);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD3DPROC) (GLdouble s, GLdouble t, GLdouble r);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD3DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD3FPROC) (GLfloat s, GLfloat t, GLfloat r);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD3FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD3IPROC) (GLint s, GLint t, GLint r);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD3IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD3SPROC) (GLshort s, GLshort t, GLshort r);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD3SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4DPROC) (GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4FPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4IPROC) (GLint s, GLint t, GLint r, GLint q);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4SPROC) (GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLTEXENVFPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLTEXENVFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLTEXENVIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLTEXENVIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLTEXGENDPROC) (GLenum coord, GLenum pname, GLdouble param);
+typedef void (GLAPIENTRY * PFNGLTEXGENDVPROC) (GLenum coord, GLenum pname, const GLdouble *params);
+typedef void (GLAPIENTRY * PFNGLTEXGENFPROC) (GLenum coord, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLTEXGENFVPROC) (GLenum coord, GLenum pname, const GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLTEXGENIPROC) (GLenum coord, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLTEXGENIVPROC) (GLenum coord, GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE1DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLTRANSLATEDPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLTRANSLATEFPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLVERTEX2DPROC) (GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLVERTEX2DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLVERTEX2FPROC) (GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLVERTEX2FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLVERTEX2IPROC) (GLint x, GLint y);
+typedef void (GLAPIENTRY * PFNGLVERTEX2IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEX2SPROC) (GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLVERTEX2SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLVERTEX3DPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLVERTEX3DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLVERTEX3FPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLVERTEX3FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLVERTEX3IPROC) (GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLVERTEX3IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEX3SPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLVERTEX3SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLVERTEX4DPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLVERTEX4DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLVERTEX4FPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLVERTEX4FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLVERTEX4IPROC) (GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLVERTEX4IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEX4SPROC) (GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (GLAPIENTRY * PFNGLVERTEX4SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+
+#define glAccum GLEW_GET_FUN(__glewAccum)
+#define glAlphaFunc GLEW_GET_FUN(__glewAlphaFunc)
+#define glAreTexturesResident GLEW_GET_FUN(__glewAreTexturesResident)
+#define glArrayElement GLEW_GET_FUN(__glewArrayElement)
+#define glBegin GLEW_GET_FUN(__glewBegin)
+#define glBindTexture GLEW_GET_FUN(__glewBindTexture)
+#define glBitmap GLEW_GET_FUN(__glewBitmap)
+#define glBlendFunc GLEW_GET_FUN(__glewBlendFunc)
+#define glCallList GLEW_GET_FUN(__glewCallList)
+#define glCallLists GLEW_GET_FUN(__glewCallLists)
+#define glClear GLEW_GET_FUN(__glewClear)
+#define glClearAccum GLEW_GET_FUN(__glewClearAccum)
+#define glClearColor GLEW_GET_FUN(__glewClearColor)
+#define glClearDepth GLEW_GET_FUN(__glewClearDepth)
+#define glClearIndex GLEW_GET_FUN(__glewClearIndex)
+#define glClearStencil GLEW_GET_FUN(__glewClearStencil)
+#define glClipPlane GLEW_GET_FUN(__glewClipPlane)
+#define glColor3b GLEW_GET_FUN(__glewColor3b)
+#define glColor3bv GLEW_GET_FUN(__glewColor3bv)
+#define glColor3d GLEW_GET_FUN(__glewColor3d)
+#define glColor3dv GLEW_GET_FUN(__glewColor3dv)
+#define glColor3f GLEW_GET_FUN(__glewColor3f)
+#define glColor3fv GLEW_GET_FUN(__glewColor3fv)
+#define glColor3i GLEW_GET_FUN(__glewColor3i)
+#define glColor3iv GLEW_GET_FUN(__glewColor3iv)
+#define glColor3s GLEW_GET_FUN(__glewColor3s)
+#define glColor3sv GLEW_GET_FUN(__glewColor3sv)
+#define glColor3ub GLEW_GET_FUN(__glewColor3ub)
+#define glColor3ubv GLEW_GET_FUN(__glewColor3ubv)
+#define glColor3ui GLEW_GET_FUN(__glewColor3ui)
+#define glColor3uiv GLEW_GET_FUN(__glewColor3uiv)
+#define glColor3us GLEW_GET_FUN(__glewColor3us)
+#define glColor3usv GLEW_GET_FUN(__glewColor3usv)
+#define glColor4b GLEW_GET_FUN(__glewColor4b)
+#define glColor4bv GLEW_GET_FUN(__glewColor4bv)
+#define glColor4d GLEW_GET_FUN(__glewColor4d)
+#define glColor4dv GLEW_GET_FUN(__glewColor4dv)
+#define glColor4f GLEW_GET_FUN(__glewColor4f)
+#define glColor4fv GLEW_GET_FUN(__glewColor4fv)
+#define glColor4i GLEW_GET_FUN(__glewColor4i)
+#define glColor4iv GLEW_GET_FUN(__glewColor4iv)
+#define glColor4s GLEW_GET_FUN(__glewColor4s)
+#define glColor4sv GLEW_GET_FUN(__glewColor4sv)
+#define glColor4ub GLEW_GET_FUN(__glewColor4ub)
+#define glColor4ubv GLEW_GET_FUN(__glewColor4ubv)
+#define glColor4ui GLEW_GET_FUN(__glewColor4ui)
+#define glColor4uiv GLEW_GET_FUN(__glewColor4uiv)
+#define glColor4us GLEW_GET_FUN(__glewColor4us)
+#define glColor4usv GLEW_GET_FUN(__glewColor4usv)
+#define glColorMask GLEW_GET_FUN(__glewColorMask)
+#define glColorMaterial GLEW_GET_FUN(__glewColorMaterial)
+#define glColorPointer GLEW_GET_FUN(__glewColorPointer)
+#define glCopyPixels GLEW_GET_FUN(__glewCopyPixels)
+#define glCopyTexImage1D GLEW_GET_FUN(__glewCopyTexImage1D)
+#define glCopyTexImage2D GLEW_GET_FUN(__glewCopyTexImage2D)
+#define glCopyTexSubImage1D GLEW_GET_FUN(__glewCopyTexSubImage1D)
+#define glCopyTexSubImage2D GLEW_GET_FUN(__glewCopyTexSubImage2D)
+#define glCullFace GLEW_GET_FUN(__glewCullFace)
+#define glDeleteLists GLEW_GET_FUN(__glewDeleteLists)
+#define glDeleteTextures GLEW_GET_FUN(__glewDeleteTextures)
+#define glDepthFunc GLEW_GET_FUN(__glewDepthFunc)
+#define glDepthMask GLEW_GET_FUN(__glewDepthMask)
+#define glDepthRange GLEW_GET_FUN(__glewDepthRange)
+#define glDisable GLEW_GET_FUN(__glewDisable)
+#define glDisableClientState GLEW_GET_FUN(__glewDisableClientState)
+#define glDrawArrays GLEW_GET_FUN(__glewDrawArrays)
+#define glDrawBuffer GLEW_GET_FUN(__glewDrawBuffer)
+#define glDrawElements GLEW_GET_FUN(__glewDrawElements)
+#define glDrawPixels GLEW_GET_FUN(__glewDrawPixels)
+#define glEdgeFlag GLEW_GET_FUN(__glewEdgeFlag)
+#define glEdgeFlagPointer GLEW_GET_FUN(__glewEdgeFlagPointer)
+#define glEdgeFlagv GLEW_GET_FUN(__glewEdgeFlagv)
+#define glEnable GLEW_GET_FUN(__glewEnable)
+#define glEnableClientState GLEW_GET_FUN(__glewEnableClientState)
+#define glEnd GLEW_GET_FUN(__glewEnd)
+#define glEndList GLEW_GET_FUN(__glewEndList)
+#define glEvalCoord1d GLEW_GET_FUN(__glewEvalCoord1d)
+#define glEvalCoord1dv GLEW_GET_FUN(__glewEvalCoord1dv)
+#define glEvalCoord1f GLEW_GET_FUN(__glewEvalCoord1f)
+#define glEvalCoord1fv GLEW_GET_FUN(__glewEvalCoord1fv)
+#define glEvalCoord2d GLEW_GET_FUN(__glewEvalCoord2d)
+#define glEvalCoord2dv GLEW_GET_FUN(__glewEvalCoord2dv)
+#define glEvalCoord2f GLEW_GET_FUN(__glewEvalCoord2f)
+#define glEvalCoord2fv GLEW_GET_FUN(__glewEvalCoord2fv)
+#define glEvalMesh1 GLEW_GET_FUN(__glewEvalMesh1)
+#define glEvalMesh2 GLEW_GET_FUN(__glewEvalMesh2)
+#define glEvalPoint1 GLEW_GET_FUN(__glewEvalPoint1)
+#define glEvalPoint2 GLEW_GET_FUN(__glewEvalPoint2)
+#define glFeedbackBuffer GLEW_GET_FUN(__glewFeedbackBuffer)
+#define glFinish GLEW_GET_FUN(__glewFinish)
+#define glFlush GLEW_GET_FUN(__glewFlush)
+#define glFogf GLEW_GET_FUN(__glewFogf)
+#define glFogfv GLEW_GET_FUN(__glewFogfv)
+#define glFogi GLEW_GET_FUN(__glewFogi)
+#define glFogiv GLEW_GET_FUN(__glewFogiv)
+#define glFrontFace GLEW_GET_FUN(__glewFrontFace)
+#define glFrustum GLEW_GET_FUN(__glewFrustum)
+#define glGenLists GLEW_GET_FUN(__glewGenLists)
+#define glGenTextures GLEW_GET_FUN(__glewGenTextures)
+#define glGetBooleanv GLEW_GET_FUN(__glewGetBooleanv)
+#define glGetClipPlane GLEW_GET_FUN(__glewGetClipPlane)
+#define glGetDoublev GLEW_GET_FUN(__glewGetDoublev)
+#define glGetError GLEW_GET_FUN(__glewGetError)
+#define glGetFloatv GLEW_GET_FUN(__glewGetFloatv)
+#define glGetIntegerv GLEW_GET_FUN(__glewGetIntegerv)
+#define glGetLightfv GLEW_GET_FUN(__glewGetLightfv)
+#define glGetLightiv GLEW_GET_FUN(__glewGetLightiv)
+#define glGetMapdv GLEW_GET_FUN(__glewGetMapdv)
+#define glGetMapfv GLEW_GET_FUN(__glewGetMapfv)
+#define glGetMapiv GLEW_GET_FUN(__glewGetMapiv)
+#define glGetMaterialfv GLEW_GET_FUN(__glewGetMaterialfv)
+#define glGetMaterialiv GLEW_GET_FUN(__glewGetMaterialiv)
+#define glGetPixelMapfv GLEW_GET_FUN(__glewGetPixelMapfv)
+#define glGetPixelMapuiv GLEW_GET_FUN(__glewGetPixelMapuiv)
+#define glGetPixelMapusv GLEW_GET_FUN(__glewGetPixelMapusv)
+#define glGetPointerv GLEW_GET_FUN(__glewGetPointerv)
+#define glGetPolygonStipple GLEW_GET_FUN(__glewGetPolygonStipple)
+#define glGetString GLEW_GET_FUN(__glewGetString)
+#define glGetTexEnvfv GLEW_GET_FUN(__glewGetTexEnvfv)
+#define glGetTexEnviv GLEW_GET_FUN(__glewGetTexEnviv)
+#define glGetTexGendv GLEW_GET_FUN(__glewGetTexGendv)
+#define glGetTexGenfv GLEW_GET_FUN(__glewGetTexGenfv)
+#define glGetTexGeniv GLEW_GET_FUN(__glewGetTexGeniv)
+#define glGetTexImage GLEW_GET_FUN(__glewGetTexImage)
+#define glGetTexLevelParameterfv GLEW_GET_FUN(__glewGetTexLevelParameterfv)
+#define glGetTexLevelParameteriv GLEW_GET_FUN(__glewGetTexLevelParameteriv)
+#define glGetTexParameterfv GLEW_GET_FUN(__glewGetTexParameterfv)
+#define glGetTexParameteriv GLEW_GET_FUN(__glewGetTexParameteriv)
+#define glHint GLEW_GET_FUN(__glewHint)
+#define glIndexMask GLEW_GET_FUN(__glewIndexMask)
+#define glIndexPointer GLEW_GET_FUN(__glewIndexPointer)
+#define glIndexd GLEW_GET_FUN(__glewIndexd)
+#define glIndexdv GLEW_GET_FUN(__glewIndexdv)
+#define glIndexf GLEW_GET_FUN(__glewIndexf)
+#define glIndexfv GLEW_GET_FUN(__glewIndexfv)
+#define glIndexi GLEW_GET_FUN(__glewIndexi)
+#define glIndexiv GLEW_GET_FUN(__glewIndexiv)
+#define glIndexs GLEW_GET_FUN(__glewIndexs)
+#define glIndexsv GLEW_GET_FUN(__glewIndexsv)
+#define glIndexub GLEW_GET_FUN(__glewIndexub)
+#define glIndexubv GLEW_GET_FUN(__glewIndexubv)
+#define glInitNames GLEW_GET_FUN(__glewInitNames)
+#define glInterleavedArrays GLEW_GET_FUN(__glewInterleavedArrays)
+#define glIsEnabled GLEW_GET_FUN(__glewIsEnabled)
+#define glIsList GLEW_GET_FUN(__glewIsList)
+#define glIsTexture GLEW_GET_FUN(__glewIsTexture)
+#define glLightModelf GLEW_GET_FUN(__glewLightModelf)
+#define glLightModelfv GLEW_GET_FUN(__glewLightModelfv)
+#define glLightModeli GLEW_GET_FUN(__glewLightModeli)
+#define glLightModeliv GLEW_GET_FUN(__glewLightModeliv)
+#define glLightf GLEW_GET_FUN(__glewLightf)
+#define glLightfv GLEW_GET_FUN(__glewLightfv)
+#define glLighti GLEW_GET_FUN(__glewLighti)
+#define glLightiv GLEW_GET_FUN(__glewLightiv)
+#define glLineStipple GLEW_GET_FUN(__glewLineStipple)
+#define glLineWidth GLEW_GET_FUN(__glewLineWidth)
+#define glListBase GLEW_GET_FUN(__glewListBase)
+#define glLoadIdentity GLEW_GET_FUN(__glewLoadIdentity)
+#define glLoadMatrixd GLEW_GET_FUN(__glewLoadMatrixd)
+#define glLoadMatrixf GLEW_GET_FUN(__glewLoadMatrixf)
+#define glLoadName GLEW_GET_FUN(__glewLoadName)
+#define glLogicOp GLEW_GET_FUN(__glewLogicOp)
+#define glMap1d GLEW_GET_FUN(__glewMap1d)
+#define glMap1f GLEW_GET_FUN(__glewMap1f)
+#define glMap2d GLEW_GET_FUN(__glewMap2d)
+#define glMap2f GLEW_GET_FUN(__glewMap2f)
+#define glMapGrid1d GLEW_GET_FUN(__glewMapGrid1d)
+#define glMapGrid1f GLEW_GET_FUN(__glewMapGrid1f)
+#define glMapGrid2d GLEW_GET_FUN(__glewMapGrid2d)
+#define glMapGrid2f GLEW_GET_FUN(__glewMapGrid2f)
+#define glMaterialf GLEW_GET_FUN(__glewMaterialf)
+#define glMaterialfv GLEW_GET_FUN(__glewMaterialfv)
+#define glMateriali GLEW_GET_FUN(__glewMateriali)
+#define glMaterialiv GLEW_GET_FUN(__glewMaterialiv)
+#define glMatrixMode GLEW_GET_FUN(__glewMatrixMode)
+#define glMultMatrixd GLEW_GET_FUN(__glewMultMatrixd)
+#define glMultMatrixf GLEW_GET_FUN(__glewMultMatrixf)
+#define glNewList GLEW_GET_FUN(__glewNewList)
+#define glNormal3b GLEW_GET_FUN(__glewNormal3b)
+#define glNormal3bv GLEW_GET_FUN(__glewNormal3bv)
+#define glNormal3d GLEW_GET_FUN(__glewNormal3d)
+#define glNormal3dv GLEW_GET_FUN(__glewNormal3dv)
+#define glNormal3f GLEW_GET_FUN(__glewNormal3f)
+#define glNormal3fv GLEW_GET_FUN(__glewNormal3fv)
+#define glNormal3i GLEW_GET_FUN(__glewNormal3i)
+#define glNormal3iv GLEW_GET_FUN(__glewNormal3iv)
+#define glNormal3s GLEW_GET_FUN(__glewNormal3s)
+#define glNormal3sv GLEW_GET_FUN(__glewNormal3sv)
+#define glNormalPointer GLEW_GET_FUN(__glewNormalPointer)
+#define glOrtho GLEW_GET_FUN(__glewOrtho)
+#define glPassThrough GLEW_GET_FUN(__glewPassThrough)
+#define glPixelMapfv GLEW_GET_FUN(__glewPixelMapfv)
+#define glPixelMapuiv GLEW_GET_FUN(__glewPixelMapuiv)
+#define glPixelMapusv GLEW_GET_FUN(__glewPixelMapusv)
+#define glPixelStoref GLEW_GET_FUN(__glewPixelStoref)
+#define glPixelStorei GLEW_GET_FUN(__glewPixelStorei)
+#define glPixelTransferf GLEW_GET_FUN(__glewPixelTransferf)
+#define glPixelTransferi GLEW_GET_FUN(__glewPixelTransferi)
+#define glPixelZoom GLEW_GET_FUN(__glewPixelZoom)
+#define glPointSize GLEW_GET_FUN(__glewPointSize)
+#define glPolygonMode GLEW_GET_FUN(__glewPolygonMode)
+#define glPolygonOffset GLEW_GET_FUN(__glewPolygonOffset)
+#define glPolygonStipple GLEW_GET_FUN(__glewPolygonStipple)
+#define glPopAttrib GLEW_GET_FUN(__glewPopAttrib)
+#define glPopClientAttrib GLEW_GET_FUN(__glewPopClientAttrib)
+#define glPopMatrix GLEW_GET_FUN(__glewPopMatrix)
+#define glPopName GLEW_GET_FUN(__glewPopName)
+#define glPrioritizeTextures GLEW_GET_FUN(__glewPrioritizeTextures)
+#define glPushAttrib GLEW_GET_FUN(__glewPushAttrib)
+#define glPushClientAttrib GLEW_GET_FUN(__glewPushClientAttrib)
+#define glPushMatrix GLEW_GET_FUN(__glewPushMatrix)
+#define glPushName GLEW_GET_FUN(__glewPushName)
+#define glRasterPos2d GLEW_GET_FUN(__glewRasterPos2d)
+#define glRasterPos2dv GLEW_GET_FUN(__glewRasterPos2dv)
+#define glRasterPos2f GLEW_GET_FUN(__glewRasterPos2f)
+#define glRasterPos2fv GLEW_GET_FUN(__glewRasterPos2fv)
+#define glRasterPos2i GLEW_GET_FUN(__glewRasterPos2i)
+#define glRasterPos2iv GLEW_GET_FUN(__glewRasterPos2iv)
+#define glRasterPos2s GLEW_GET_FUN(__glewRasterPos2s)
+#define glRasterPos2sv GLEW_GET_FUN(__glewRasterPos2sv)
+#define glRasterPos3d GLEW_GET_FUN(__glewRasterPos3d)
+#define glRasterPos3dv GLEW_GET_FUN(__glewRasterPos3dv)
+#define glRasterPos3f GLEW_GET_FUN(__glewRasterPos3f)
+#define glRasterPos3fv GLEW_GET_FUN(__glewRasterPos3fv)
+#define glRasterPos3i GLEW_GET_FUN(__glewRasterPos3i)
+#define glRasterPos3iv GLEW_GET_FUN(__glewRasterPos3iv)
+#define glRasterPos3s GLEW_GET_FUN(__glewRasterPos3s)
+#define glRasterPos3sv GLEW_GET_FUN(__glewRasterPos3sv)
+#define glRasterPos4d GLEW_GET_FUN(__glewRasterPos4d)
+#define glRasterPos4dv GLEW_GET_FUN(__glewRasterPos4dv)
+#define glRasterPos4f GLEW_GET_FUN(__glewRasterPos4f)
+#define glRasterPos4fv GLEW_GET_FUN(__glewRasterPos4fv)
+#define glRasterPos4i GLEW_GET_FUN(__glewRasterPos4i)
+#define glRasterPos4iv GLEW_GET_FUN(__glewRasterPos4iv)
+#define glRasterPos4s GLEW_GET_FUN(__glewRasterPos4s)
+#define glRasterPos4sv GLEW_GET_FUN(__glewRasterPos4sv)
+#define glReadBuffer GLEW_GET_FUN(__glewReadBuffer)
+#define glReadPixels GLEW_GET_FUN(__glewReadPixels)
+#define glRectd GLEW_GET_FUN(__glewRectd)
+#define glRectdv GLEW_GET_FUN(__glewRectdv)
+#define glRectf GLEW_GET_FUN(__glewRectf)
+#define glRectfv GLEW_GET_FUN(__glewRectfv)
+#define glRecti GLEW_GET_FUN(__glewRecti)
+#define glRectiv GLEW_GET_FUN(__glewRectiv)
+#define glRects GLEW_GET_FUN(__glewRects)
+#define glRectsv GLEW_GET_FUN(__glewRectsv)
+#define glRenderMode GLEW_GET_FUN(__glewRenderMode)
+#define glRotated GLEW_GET_FUN(__glewRotated)
+#define glRotatef GLEW_GET_FUN(__glewRotatef)
+#define glScaled GLEW_GET_FUN(__glewScaled)
+#define glScalef GLEW_GET_FUN(__glewScalef)
+#define glScissor GLEW_GET_FUN(__glewScissor)
+#define glSelectBuffer GLEW_GET_FUN(__glewSelectBuffer)
+#define glShadeModel GLEW_GET_FUN(__glewShadeModel)
+#define glStencilFunc GLEW_GET_FUN(__glewStencilFunc)
+#define glStencilMask GLEW_GET_FUN(__glewStencilMask)
+#define glStencilOp GLEW_GET_FUN(__glewStencilOp)
+#define glTexCoord1d GLEW_GET_FUN(__glewTexCoord1d)
+#define glTexCoord1dv GLEW_GET_FUN(__glewTexCoord1dv)
+#define glTexCoord1f GLEW_GET_FUN(__glewTexCoord1f)
+#define glTexCoord1fv GLEW_GET_FUN(__glewTexCoord1fv)
+#define glTexCoord1i GLEW_GET_FUN(__glewTexCoord1i)
+#define glTexCoord1iv GLEW_GET_FUN(__glewTexCoord1iv)
+#define glTexCoord1s GLEW_GET_FUN(__glewTexCoord1s)
+#define glTexCoord1sv GLEW_GET_FUN(__glewTexCoord1sv)
+#define glTexCoord2d GLEW_GET_FUN(__glewTexCoord2d)
+#define glTexCoord2dv GLEW_GET_FUN(__glewTexCoord2dv)
+#define glTexCoord2f GLEW_GET_FUN(__glewTexCoord2f)
+#define glTexCoord2fv GLEW_GET_FUN(__glewTexCoord2fv)
+#define glTexCoord2i GLEW_GET_FUN(__glewTexCoord2i)
+#define glTexCoord2iv GLEW_GET_FUN(__glewTexCoord2iv)
+#define glTexCoord2s GLEW_GET_FUN(__glewTexCoord2s)
+#define glTexCoord2sv GLEW_GET_FUN(__glewTexCoord2sv)
+#define glTexCoord3d GLEW_GET_FUN(__glewTexCoord3d)
+#define glTexCoord3dv GLEW_GET_FUN(__glewTexCoord3dv)
+#define glTexCoord3f GLEW_GET_FUN(__glewTexCoord3f)
+#define glTexCoord3fv GLEW_GET_FUN(__glewTexCoord3fv)
+#define glTexCoord3i GLEW_GET_FUN(__glewTexCoord3i)
+#define glTexCoord3iv GLEW_GET_FUN(__glewTexCoord3iv)
+#define glTexCoord3s GLEW_GET_FUN(__glewTexCoord3s)
+#define glTexCoord3sv GLEW_GET_FUN(__glewTexCoord3sv)
+#define glTexCoord4d GLEW_GET_FUN(__glewTexCoord4d)
+#define glTexCoord4dv GLEW_GET_FUN(__glewTexCoord4dv)
+#define glTexCoord4f GLEW_GET_FUN(__glewTexCoord4f)
+#define glTexCoord4fv GLEW_GET_FUN(__glewTexCoord4fv)
+#define glTexCoord4i GLEW_GET_FUN(__glewTexCoord4i)
+#define glTexCoord4iv GLEW_GET_FUN(__glewTexCoord4iv)
+#define glTexCoord4s GLEW_GET_FUN(__glewTexCoord4s)
+#define glTexCoord4sv GLEW_GET_FUN(__glewTexCoord4sv)
+#define glTexCoordPointer GLEW_GET_FUN(__glewTexCoordPointer)
+#define glTexEnvf GLEW_GET_FUN(__glewTexEnvf)
+#define glTexEnvfv GLEW_GET_FUN(__glewTexEnvfv)
+#define glTexEnvi GLEW_GET_FUN(__glewTexEnvi)
+#define glTexEnviv GLEW_GET_FUN(__glewTexEnviv)
+#define glTexGend GLEW_GET_FUN(__glewTexGend)
+#define glTexGendv GLEW_GET_FUN(__glewTexGendv)
+#define glTexGenf GLEW_GET_FUN(__glewTexGenf)
+#define glTexGenfv GLEW_GET_FUN(__glewTexGenfv)
+#define glTexGeni GLEW_GET_FUN(__glewTexGeni)
+#define glTexGeniv GLEW_GET_FUN(__glewTexGeniv)
+#define glTexImage1D GLEW_GET_FUN(__glewTexImage1D)
+#define glTexImage2D GLEW_GET_FUN(__glewTexImage2D)
+#define glTexParameterf GLEW_GET_FUN(__glewTexParameterf)
+#define glTexParameterfv GLEW_GET_FUN(__glewTexParameterfv)
+#define glTexParameteri GLEW_GET_FUN(__glewTexParameteri)
+#define glTexParameteriv GLEW_GET_FUN(__glewTexParameteriv)
+#define glTexSubImage1D GLEW_GET_FUN(__glewTexSubImage1D)
+#define glTexSubImage2D GLEW_GET_FUN(__glewTexSubImage2D)
+#define glTranslated GLEW_GET_FUN(__glewTranslated)
+#define glTranslatef GLEW_GET_FUN(__glewTranslatef)
+#define glVertex2d GLEW_GET_FUN(__glewVertex2d)
+#define glVertex2dv GLEW_GET_FUN(__glewVertex2dv)
+#define glVertex2f GLEW_GET_FUN(__glewVertex2f)
+#define glVertex2fv GLEW_GET_FUN(__glewVertex2fv)
+#define glVertex2i GLEW_GET_FUN(__glewVertex2i)
+#define glVertex2iv GLEW_GET_FUN(__glewVertex2iv)
+#define glVertex2s GLEW_GET_FUN(__glewVertex2s)
+#define glVertex2sv GLEW_GET_FUN(__glewVertex2sv)
+#define glVertex3d GLEW_GET_FUN(__glewVertex3d)
+#define glVertex3dv GLEW_GET_FUN(__glewVertex3dv)
+#define glVertex3f GLEW_GET_FUN(__glewVertex3f)
+#define glVertex3fv GLEW_GET_FUN(__glewVertex3fv)
+#define glVertex3i GLEW_GET_FUN(__glewVertex3i)
+#define glVertex3iv GLEW_GET_FUN(__glewVertex3iv)
+#define glVertex3s GLEW_GET_FUN(__glewVertex3s)
+#define glVertex3sv GLEW_GET_FUN(__glewVertex3sv)
+#define glVertex4d GLEW_GET_FUN(__glewVertex4d)
+#define glVertex4dv GLEW_GET_FUN(__glewVertex4dv)
+#define glVertex4f GLEW_GET_FUN(__glewVertex4f)
+#define glVertex4fv GLEW_GET_FUN(__glewVertex4fv)
+#define glVertex4i GLEW_GET_FUN(__glewVertex4i)
+#define glVertex4iv GLEW_GET_FUN(__glewVertex4iv)
+#define glVertex4s GLEW_GET_FUN(__glewVertex4s)
+#define glVertex4sv GLEW_GET_FUN(__glewVertex4sv)
+#define glVertexPointer GLEW_GET_FUN(__glewVertexPointer)
+#define glViewport GLEW_GET_FUN(__glewViewport)
+
+
+#else //GLEW_INIT_OPENGL11_FUNCTIONS
+
+GLAPI void GLAPIENTRY glAccum (GLenum op, GLfloat value);
+GLAPI void GLAPIENTRY glAlphaFunc (GLenum func, GLclampf ref);
+GLAPI GLboolean GLAPIENTRY glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences);
+GLAPI void GLAPIENTRY glArrayElement (GLint i);
+GLAPI void GLAPIENTRY glBegin (GLenum mode);
+GLAPI void GLAPIENTRY glBindTexture (GLenum target, GLuint texture);
+GLAPI void GLAPIENTRY glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap);
+GLAPI void GLAPIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
+GLAPI void GLAPIENTRY glCallList (GLuint list);
+GLAPI void GLAPIENTRY glCallLists (GLsizei n, GLenum type, const GLvoid *lists);
+GLAPI void GLAPIENTRY glClear (GLbitfield mask);
+GLAPI void GLAPIENTRY glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GLAPI void GLAPIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+GLAPI void GLAPIENTRY glClearDepth (GLclampd depth);
+GLAPI void GLAPIENTRY glClearIndex (GLfloat c);
+GLAPI void GLAPIENTRY glClearStencil (GLint s);
+GLAPI void GLAPIENTRY glClipPlane (GLenum plane, const GLdouble *equation);
+GLAPI void GLAPIENTRY glColor3b (GLbyte red, GLbyte green, GLbyte blue);
+GLAPI void GLAPIENTRY glColor3bv (const GLbyte *v);
+GLAPI void GLAPIENTRY glColor3d (GLdouble red, GLdouble green, GLdouble blue);
+GLAPI void GLAPIENTRY glColor3dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue);
+GLAPI void GLAPIENTRY glColor3fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glColor3i (GLint red, GLint green, GLint blue);
+GLAPI void GLAPIENTRY glColor3iv (const GLint *v);
+GLAPI void GLAPIENTRY glColor3s (GLshort red, GLshort green, GLshort blue);
+GLAPI void GLAPIENTRY glColor3sv (const GLshort *v);
+GLAPI void GLAPIENTRY glColor3ub (GLubyte red, GLubyte green, GLubyte blue);
+GLAPI void GLAPIENTRY glColor3ubv (const GLubyte *v);
+GLAPI void GLAPIENTRY glColor3ui (GLuint red, GLuint green, GLuint blue);
+GLAPI void GLAPIENTRY glColor3uiv (const GLuint *v);
+GLAPI void GLAPIENTRY glColor3us (GLushort red, GLushort green, GLushort blue);
+GLAPI void GLAPIENTRY glColor3usv (const GLushort *v);
+GLAPI void GLAPIENTRY glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha);
+GLAPI void GLAPIENTRY glColor4bv (const GLbyte *v);
+GLAPI void GLAPIENTRY glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha);
+GLAPI void GLAPIENTRY glColor4dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GLAPI void GLAPIENTRY glColor4fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glColor4i (GLint red, GLint green, GLint blue, GLint alpha);
+GLAPI void GLAPIENTRY glColor4iv (const GLint *v);
+GLAPI void GLAPIENTRY glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha);
+GLAPI void GLAPIENTRY glColor4sv (const GLshort *v);
+GLAPI void GLAPIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+GLAPI void GLAPIENTRY glColor4ubv (const GLubyte *v);
+GLAPI void GLAPIENTRY glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha);
+GLAPI void GLAPIENTRY glColor4uiv (const GLuint *v);
+GLAPI void GLAPIENTRY glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha);
+GLAPI void GLAPIENTRY glColor4usv (const GLushort *v);
+GLAPI void GLAPIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+GLAPI void GLAPIENTRY glColorMaterial (GLenum face, GLenum mode);
+GLAPI void GLAPIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void GLAPIENTRY glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
+GLAPI void GLAPIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border);
+GLAPI void GLAPIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GLAPI void GLAPIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+GLAPI void GLAPIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void GLAPIENTRY glCullFace (GLenum mode);
+GLAPI void GLAPIENTRY glDeleteLists (GLuint list, GLsizei range);
+GLAPI void GLAPIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
+GLAPI void GLAPIENTRY glDepthFunc (GLenum func);
+GLAPI void GLAPIENTRY glDepthMask (GLboolean flag);
+GLAPI void GLAPIENTRY glDepthRange (GLclampd zNear, GLclampd zFar);
+GLAPI void GLAPIENTRY glDisable (GLenum cap);
+GLAPI void GLAPIENTRY glDisableClientState (GLenum array);
+GLAPI void GLAPIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
+GLAPI void GLAPIENTRY glDrawBuffer (GLenum mode);
+GLAPI void GLAPIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
+GLAPI void GLAPIENTRY glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void GLAPIENTRY glEdgeFlag (GLboolean flag);
+GLAPI void GLAPIENTRY glEdgeFlagPointer (GLsizei stride, const GLvoid *pointer);
+GLAPI void GLAPIENTRY glEdgeFlagv (const GLboolean *flag);
+GLAPI void GLAPIENTRY glEnable (GLenum cap);
+GLAPI void GLAPIENTRY glEnableClientState (GLenum array);
+GLAPI void GLAPIENTRY glEnd (void);
+GLAPI void GLAPIENTRY glEndList (void);
+GLAPI void GLAPIENTRY glEvalCoord1d (GLdouble u);
+GLAPI void GLAPIENTRY glEvalCoord1dv (const GLdouble *u);
+GLAPI void GLAPIENTRY glEvalCoord1f (GLfloat u);
+GLAPI void GLAPIENTRY glEvalCoord1fv (const GLfloat *u);
+GLAPI void GLAPIENTRY glEvalCoord2d (GLdouble u, GLdouble v);
+GLAPI void GLAPIENTRY glEvalCoord2dv (const GLdouble *u);
+GLAPI void GLAPIENTRY glEvalCoord2f (GLfloat u, GLfloat v);
+GLAPI void GLAPIENTRY glEvalCoord2fv (const GLfloat *u);
+GLAPI void GLAPIENTRY glEvalMesh1 (GLenum mode, GLint i1, GLint i2);
+GLAPI void GLAPIENTRY glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2);
+GLAPI void GLAPIENTRY glEvalPoint1 (GLint i);
+GLAPI void GLAPIENTRY glEvalPoint2 (GLint i, GLint j);
+GLAPI void GLAPIENTRY glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer);
+GLAPI void GLAPIENTRY glFinish (void);
+GLAPI void GLAPIENTRY glFlush (void);
+GLAPI void GLAPIENTRY glFogf (GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glFogfv (GLenum pname, const GLfloat *params);
+GLAPI void GLAPIENTRY glFogi (GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glFogiv (GLenum pname, const GLint *params);
+GLAPI void GLAPIENTRY glFrontFace (GLenum mode);
+GLAPI void GLAPIENTRY glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GLAPI GLuint GLAPIENTRY glGenLists (GLsizei range);
+GLAPI void GLAPIENTRY glGenTextures (GLsizei n, GLuint *textures);
+GLAPI void GLAPIENTRY glGetBooleanv (GLenum pname, GLboolean *params);
+GLAPI void GLAPIENTRY glGetClipPlane (GLenum plane, GLdouble *equation);
+GLAPI void GLAPIENTRY glGetDoublev (GLenum pname, GLdouble *params);
+GLAPI GLenum GLAPIENTRY glGetError (void);
+GLAPI void GLAPIENTRY glGetFloatv (GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetIntegerv (GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetLightiv (GLenum light, GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glGetMapdv (GLenum target, GLenum query, GLdouble *v);
+GLAPI void GLAPIENTRY glGetMapfv (GLenum target, GLenum query, GLfloat *v);
+GLAPI void GLAPIENTRY glGetMapiv (GLenum target, GLenum query, GLint *v);
+GLAPI void GLAPIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetMaterialiv (GLenum face, GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glGetPixelMapfv (GLenum map, GLfloat *values);
+GLAPI void GLAPIENTRY glGetPixelMapuiv (GLenum map, GLuint *values);
+GLAPI void GLAPIENTRY glGetPixelMapusv (GLenum map, GLushort *values);
+GLAPI void GLAPIENTRY glGetPointerv (GLenum pname, GLvoid* *params);
+GLAPI void GLAPIENTRY glGetPolygonStipple (GLubyte *mask);
+GLAPI const GLubyte * GLAPIENTRY glGetString (GLenum name);
+GLAPI void GLAPIENTRY glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetTexEnviv (GLenum target, GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params);
+GLAPI void GLAPIENTRY glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetTexGeniv (GLenum coord, GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+GLAPI void GLAPIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void GLAPIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glHint (GLenum target, GLenum mode);
+GLAPI void GLAPIENTRY glIndexMask (GLuint mask);
+GLAPI void GLAPIENTRY glIndexPointer (GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void GLAPIENTRY glIndexd (GLdouble c);
+GLAPI void GLAPIENTRY glIndexdv (const GLdouble *c);
+GLAPI void GLAPIENTRY glIndexf (GLfloat c);
+GLAPI void GLAPIENTRY glIndexfv (const GLfloat *c);
+GLAPI void GLAPIENTRY glIndexi (GLint c);
+GLAPI void GLAPIENTRY glIndexiv (const GLint *c);
+GLAPI void GLAPIENTRY glIndexs (GLshort c);
+GLAPI void GLAPIENTRY glIndexsv (const GLshort *c);
+GLAPI void GLAPIENTRY glIndexub (GLubyte c);
+GLAPI void GLAPIENTRY glIndexubv (const GLubyte *c);
+GLAPI void GLAPIENTRY glInitNames (void);
+GLAPI void GLAPIENTRY glInterleavedArrays (GLenum format, GLsizei stride, const GLvoid *pointer);
+GLAPI GLboolean GLAPIENTRY glIsEnabled (GLenum cap);
+GLAPI GLboolean GLAPIENTRY glIsList (GLuint list);
+GLAPI GLboolean GLAPIENTRY glIsTexture (GLuint texture);
+GLAPI void GLAPIENTRY glLightModelf (GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glLightModelfv (GLenum pname, const GLfloat *params);
+GLAPI void GLAPIENTRY glLightModeli (GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glLightModeliv (GLenum pname, const GLint *params);
+GLAPI void GLAPIENTRY glLightf (GLenum light, GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params);
+GLAPI void GLAPIENTRY glLighti (GLenum light, GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glLightiv (GLenum light, GLenum pname, const GLint *params);
+GLAPI void GLAPIENTRY glLineStipple (GLint factor, GLushort pattern);
+GLAPI void GLAPIENTRY glLineWidth (GLfloat width);
+GLAPI void GLAPIENTRY glListBase (GLuint base);
+GLAPI void GLAPIENTRY glLoadIdentity (void);
+GLAPI void GLAPIENTRY glLoadMatrixd (const GLdouble *m);
+GLAPI void GLAPIENTRY glLoadMatrixf (const GLfloat *m);
+GLAPI void GLAPIENTRY glLoadName (GLuint name);
+GLAPI void GLAPIENTRY glLogicOp (GLenum opcode);
+GLAPI void GLAPIENTRY glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+GLAPI void GLAPIENTRY glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+GLAPI void GLAPIENTRY glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+GLAPI void GLAPIENTRY glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+GLAPI void GLAPIENTRY glMapGrid1d (GLint un, GLdouble u1, GLdouble u2);
+GLAPI void GLAPIENTRY glMapGrid1f (GLint un, GLfloat u1, GLfloat u2);
+GLAPI void GLAPIENTRY glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2);
+GLAPI void GLAPIENTRY glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2);
+GLAPI void GLAPIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params);
+GLAPI void GLAPIENTRY glMateriali (GLenum face, GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glMaterialiv (GLenum face, GLenum pname, const GLint *params);
+GLAPI void GLAPIENTRY glMatrixMode (GLenum mode);
+GLAPI void GLAPIENTRY glMultMatrixd (const GLdouble *m);
+GLAPI void GLAPIENTRY glMultMatrixf (const GLfloat *m);
+GLAPI void GLAPIENTRY glNewList (GLuint list, GLenum mode);
+GLAPI void GLAPIENTRY glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz);
+GLAPI void GLAPIENTRY glNormal3bv (const GLbyte *v);
+GLAPI void GLAPIENTRY glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz);
+GLAPI void GLAPIENTRY glNormal3dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz);
+GLAPI void GLAPIENTRY glNormal3fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glNormal3i (GLint nx, GLint ny, GLint nz);
+GLAPI void GLAPIENTRY glNormal3iv (const GLint *v);
+GLAPI void GLAPIENTRY glNormal3s (GLshort nx, GLshort ny, GLshort nz);
+GLAPI void GLAPIENTRY glNormal3sv (const GLshort *v);
+GLAPI void GLAPIENTRY glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void GLAPIENTRY glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GLAPI void GLAPIENTRY glPassThrough (GLfloat token);
+GLAPI void GLAPIENTRY glPixelMapfv (GLenum map, GLsizei mapsize, const GLfloat *values);
+GLAPI void GLAPIENTRY glPixelMapuiv (GLenum map, GLsizei mapsize, const GLuint *values);
+GLAPI void GLAPIENTRY glPixelMapusv (GLenum map, GLsizei mapsize, const GLushort *values);
+GLAPI void GLAPIENTRY glPixelStoref (GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glPixelStorei (GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glPixelTransferf (GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glPixelTransferi (GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glPixelZoom (GLfloat xfactor, GLfloat yfactor);
+GLAPI void GLAPIENTRY glPointSize (GLfloat size);
+GLAPI void GLAPIENTRY glPolygonMode (GLenum face, GLenum mode);
+GLAPI void GLAPIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
+GLAPI void GLAPIENTRY glPolygonStipple (const GLubyte *mask);
+GLAPI void GLAPIENTRY glPopAttrib (void);
+GLAPI void GLAPIENTRY glPopClientAttrib (void);
+GLAPI void GLAPIENTRY glPopMatrix (void);
+GLAPI void GLAPIENTRY glPopName (void);
+GLAPI void GLAPIENTRY glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities);
+GLAPI void GLAPIENTRY glPushAttrib (GLbitfield mask);
+GLAPI void GLAPIENTRY glPushClientAttrib (GLbitfield mask);
+GLAPI void GLAPIENTRY glPushMatrix (void);
+GLAPI void GLAPIENTRY glPushName (GLuint name);
+GLAPI void GLAPIENTRY glRasterPos2d (GLdouble x, GLdouble y);
+GLAPI void GLAPIENTRY glRasterPos2dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glRasterPos2f (GLfloat x, GLfloat y);
+GLAPI void GLAPIENTRY glRasterPos2fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glRasterPos2i (GLint x, GLint y);
+GLAPI void GLAPIENTRY glRasterPos2iv (const GLint *v);
+GLAPI void GLAPIENTRY glRasterPos2s (GLshort x, GLshort y);
+GLAPI void GLAPIENTRY glRasterPos2sv (const GLshort *v);
+GLAPI void GLAPIENTRY glRasterPos3d (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void GLAPIENTRY glRasterPos3dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glRasterPos3f (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void GLAPIENTRY glRasterPos3fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glRasterPos3i (GLint x, GLint y, GLint z);
+GLAPI void GLAPIENTRY glRasterPos3iv (const GLint *v);
+GLAPI void GLAPIENTRY glRasterPos3s (GLshort x, GLshort y, GLshort z);
+GLAPI void GLAPIENTRY glRasterPos3sv (const GLshort *v);
+GLAPI void GLAPIENTRY glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void GLAPIENTRY glRasterPos4dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void GLAPIENTRY glRasterPos4fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glRasterPos4i (GLint x, GLint y, GLint z, GLint w);
+GLAPI void GLAPIENTRY glRasterPos4iv (const GLint *v);
+GLAPI void GLAPIENTRY glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void GLAPIENTRY glRasterPos4sv (const GLshort *v);
+GLAPI void GLAPIENTRY glReadBuffer (GLenum mode);
+GLAPI void GLAPIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
+GLAPI void GLAPIENTRY glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
+GLAPI void GLAPIENTRY glRectdv (const GLdouble *v1, const GLdouble *v2);
+GLAPI void GLAPIENTRY glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
+GLAPI void GLAPIENTRY glRectfv (const GLfloat *v1, const GLfloat *v2);
+GLAPI void GLAPIENTRY glRecti (GLint x1, GLint y1, GLint x2, GLint y2);
+GLAPI void GLAPIENTRY glRectiv (const GLint *v1, const GLint *v2);
+GLAPI void GLAPIENTRY glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2);
+GLAPI void GLAPIENTRY glRectsv (const GLshort *v1, const GLshort *v2);
+GLAPI GLint GLAPIENTRY glRenderMode (GLenum mode);
+GLAPI void GLAPIENTRY glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void GLAPIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void GLAPIENTRY glScaled (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void GLAPIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void GLAPIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void GLAPIENTRY glSelectBuffer (GLsizei size, GLuint *buffer);
+GLAPI void GLAPIENTRY glShadeModel (GLenum mode);
+GLAPI void GLAPIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
+GLAPI void GLAPIENTRY glStencilMask (GLuint mask);
+GLAPI void GLAPIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
+GLAPI void GLAPIENTRY glTexCoord1d (GLdouble s);
+GLAPI void GLAPIENTRY glTexCoord1dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glTexCoord1f (GLfloat s);
+GLAPI void GLAPIENTRY glTexCoord1fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glTexCoord1i (GLint s);
+GLAPI void GLAPIENTRY glTexCoord1iv (const GLint *v);
+GLAPI void GLAPIENTRY glTexCoord1s (GLshort s);
+GLAPI void GLAPIENTRY glTexCoord1sv (const GLshort *v);
+GLAPI void GLAPIENTRY glTexCoord2d (GLdouble s, GLdouble t);
+GLAPI void GLAPIENTRY glTexCoord2dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glTexCoord2f (GLfloat s, GLfloat t);
+GLAPI void GLAPIENTRY glTexCoord2fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glTexCoord2i (GLint s, GLint t);
+GLAPI void GLAPIENTRY glTexCoord2iv (const GLint *v);
+GLAPI void GLAPIENTRY glTexCoord2s (GLshort s, GLshort t);
+GLAPI void GLAPIENTRY glTexCoord2sv (const GLshort *v);
+GLAPI void GLAPIENTRY glTexCoord3d (GLdouble s, GLdouble t, GLdouble r);
+GLAPI void GLAPIENTRY glTexCoord3dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glTexCoord3f (GLfloat s, GLfloat t, GLfloat r);
+GLAPI void GLAPIENTRY glTexCoord3fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glTexCoord3i (GLint s, GLint t, GLint r);
+GLAPI void GLAPIENTRY glTexCoord3iv (const GLint *v);
+GLAPI void GLAPIENTRY glTexCoord3s (GLshort s, GLshort t, GLshort r);
+GLAPI void GLAPIENTRY glTexCoord3sv (const GLshort *v);
+GLAPI void GLAPIENTRY glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+GLAPI void GLAPIENTRY glTexCoord4dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+GLAPI void GLAPIENTRY glTexCoord4fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glTexCoord4i (GLint s, GLint t, GLint r, GLint q);
+GLAPI void GLAPIENTRY glTexCoord4iv (const GLint *v);
+GLAPI void GLAPIENTRY glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q);
+GLAPI void GLAPIENTRY glTexCoord4sv (const GLshort *v);
+GLAPI void GLAPIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void GLAPIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void GLAPIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void GLAPIENTRY glTexGend (GLenum coord, GLenum pname, GLdouble param);
+GLAPI void GLAPIENTRY glTexGendv (GLenum coord, GLenum pname, const GLdouble *params);
+GLAPI void GLAPIENTRY glTexGenf (GLenum coord, GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params);
+GLAPI void GLAPIENTRY glTexGeni (GLenum coord, GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glTexGeniv (GLenum coord, GLenum pname, const GLint *params);
+GLAPI void GLAPIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void GLAPIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void GLAPIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
+GLAPI void GLAPIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void GLAPIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
+GLAPI void GLAPIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void GLAPIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void GLAPIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void GLAPIENTRY glTranslated (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void GLAPIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void GLAPIENTRY glVertex2d (GLdouble x, GLdouble y);
+GLAPI void GLAPIENTRY glVertex2dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glVertex2f (GLfloat x, GLfloat y);
+GLAPI void GLAPIENTRY glVertex2fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glVertex2i (GLint x, GLint y);
+GLAPI void GLAPIENTRY glVertex2iv (const GLint *v);
+GLAPI void GLAPIENTRY glVertex2s (GLshort x, GLshort y);
+GLAPI void GLAPIENTRY glVertex2sv (const GLshort *v);
+GLAPI void GLAPIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void GLAPIENTRY glVertex3dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void GLAPIENTRY glVertex3fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glVertex3i (GLint x, GLint y, GLint z);
+GLAPI void GLAPIENTRY glVertex3iv (const GLint *v);
+GLAPI void GLAPIENTRY glVertex3s (GLshort x, GLshort y, GLshort z);
+GLAPI void GLAPIENTRY glVertex3sv (const GLshort *v);
+GLAPI void GLAPIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void GLAPIENTRY glVertex4dv (const GLdouble *v);
+GLAPI void GLAPIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void GLAPIENTRY glVertex4fv (const GLfloat *v);
+GLAPI void GLAPIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w);
+GLAPI void GLAPIENTRY glVertex4iv (const GLint *v);
+GLAPI void GLAPIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void GLAPIENTRY glVertex4sv (const GLshort *v);
+GLAPI void GLAPIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void GLAPIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
+#endif //GLEW_INIT_OPENGL11_FUNCTIONS
+#define GLEW_VERSION_1_1 GLEW_GET_VAR(__GLEW_VERSION_1_1)
+
+#endif /* GL_VERSION_1_1 */
+
+/* ---------------------------------- GLU ---------------------------------- */
+
+#ifndef GLEW_NO_GLU
+/* this is where we can safely include GLU */
+# if defined(__APPLE__) && defined(__MACH__)
+# include <OpenGL/glu.h>
+# else
+# include <GL/glu.h>
+# endif
+#endif
+
+/* ----------------------------- GL_VERSION_1_2 ---------------------------- */
+
+#ifndef GL_VERSION_1_2
+#define GL_VERSION_1_2 1
+
+#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define GL_RESCALE_NORMAL 0x803A
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_PACK_SKIP_IMAGES 0x806B
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_PROXY_TEXTURE_3D 0x8070
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_BGR 0x80E0
+#define GL_BGRA 0x80E1
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
+#define GL_SINGLE_COLOR 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+
+typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+
+#define glCopyTexSubImage3D GLEW_GET_FUN(__glewCopyTexSubImage3D)
+#define glDrawRangeElements GLEW_GET_FUN(__glewDrawRangeElements)
+#define glTexImage3D GLEW_GET_FUN(__glewTexImage3D)
+#define glTexSubImage3D GLEW_GET_FUN(__glewTexSubImage3D)
+
+#define GLEW_VERSION_1_2 GLEW_GET_VAR(__GLEW_VERSION_1_2)
+
+#endif /* GL_VERSION_1_2 */
+
+/* ---------------------------- GL_VERSION_1_2_1 --------------------------- */
+
+#ifndef GL_VERSION_1_2_1
+#define GL_VERSION_1_2_1 1
+
+#define GLEW_VERSION_1_2_1 GLEW_GET_VAR(__GLEW_VERSION_1_2_1)
+
+#endif /* GL_VERSION_1_2_1 */
+
+/* ----------------------------- GL_VERSION_1_3 ---------------------------- */
+
+#ifndef GL_VERSION_1_3
+#define GL_VERSION_1_3 1
+
+#define GL_MULTISAMPLE 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_CLAMP_TO_BORDER 0x812D
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1
+#define GL_MAX_TEXTURE_UNITS 0x84E2
+#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6
+#define GL_SUBTRACT 0x84E7
+#define GL_COMPRESSED_ALPHA 0x84E9
+#define GL_COMPRESSED_LUMINANCE 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
+#define GL_COMPRESSED_INTENSITY 0x84EC
+#define GL_COMPRESSED_RGB 0x84ED
+#define GL_COMPRESSED_RGBA 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
+#define GL_NORMAL_MAP 0x8511
+#define GL_REFLECTION_MAP 0x8512
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_COMBINE 0x8570
+#define GL_COMBINE_RGB 0x8571
+#define GL_COMBINE_ALPHA 0x8572
+#define GL_RGB_SCALE 0x8573
+#define GL_ADD_SIGNED 0x8574
+#define GL_INTERPOLATE 0x8575
+#define GL_CONSTANT 0x8576
+#define GL_PRIMARY_COLOR 0x8577
+#define GL_PREVIOUS 0x8578
+#define GL_SOURCE0_RGB 0x8580
+#define GL_SOURCE1_RGB 0x8581
+#define GL_SOURCE2_RGB 0x8582
+#define GL_SOURCE0_ALPHA 0x8588
+#define GL_SOURCE1_ALPHA 0x8589
+#define GL_SOURCE2_ALPHA 0x858A
+#define GL_OPERAND0_RGB 0x8590
+#define GL_OPERAND1_RGB 0x8591
+#define GL_OPERAND2_RGB 0x8592
+#define GL_OPERAND0_ALPHA 0x8598
+#define GL_OPERAND1_ALPHA 0x8599
+#define GL_OPERAND2_ALPHA 0x859A
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_DOT3_RGB 0x86AE
+#define GL_DOT3_RGBA 0x86AF
+#define GL_MULTISAMPLE_BIT 0x20000000
+
+typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLvoid *img);
+typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble m[16]);
+typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat m[16]);
+typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble m[16]);
+typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat m[16]);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert);
+
+#define glActiveTexture GLEW_GET_FUN(__glewActiveTexture)
+#define glClientActiveTexture GLEW_GET_FUN(__glewClientActiveTexture)
+#define glCompressedTexImage1D GLEW_GET_FUN(__glewCompressedTexImage1D)
+#define glCompressedTexImage2D GLEW_GET_FUN(__glewCompressedTexImage2D)
+#define glCompressedTexImage3D GLEW_GET_FUN(__glewCompressedTexImage3D)
+#define glCompressedTexSubImage1D GLEW_GET_FUN(__glewCompressedTexSubImage1D)
+#define glCompressedTexSubImage2D GLEW_GET_FUN(__glewCompressedTexSubImage2D)
+#define glCompressedTexSubImage3D GLEW_GET_FUN(__glewCompressedTexSubImage3D)
+#define glGetCompressedTexImage GLEW_GET_FUN(__glewGetCompressedTexImage)
+#define glLoadTransposeMatrixd GLEW_GET_FUN(__glewLoadTransposeMatrixd)
+#define glLoadTransposeMatrixf GLEW_GET_FUN(__glewLoadTransposeMatrixf)
+#define glMultTransposeMatrixd GLEW_GET_FUN(__glewMultTransposeMatrixd)
+#define glMultTransposeMatrixf GLEW_GET_FUN(__glewMultTransposeMatrixf)
+#define glMultiTexCoord1d GLEW_GET_FUN(__glewMultiTexCoord1d)
+#define glMultiTexCoord1dv GLEW_GET_FUN(__glewMultiTexCoord1dv)
+#define glMultiTexCoord1f GLEW_GET_FUN(__glewMultiTexCoord1f)
+#define glMultiTexCoord1fv GLEW_GET_FUN(__glewMultiTexCoord1fv)
+#define glMultiTexCoord1i GLEW_GET_FUN(__glewMultiTexCoord1i)
+#define glMultiTexCoord1iv GLEW_GET_FUN(__glewMultiTexCoord1iv)
+#define glMultiTexCoord1s GLEW_GET_FUN(__glewMultiTexCoord1s)
+#define glMultiTexCoord1sv GLEW_GET_FUN(__glewMultiTexCoord1sv)
+#define glMultiTexCoord2d GLEW_GET_FUN(__glewMultiTexCoord2d)
+#define glMultiTexCoord2dv GLEW_GET_FUN(__glewMultiTexCoord2dv)
+#define glMultiTexCoord2f GLEW_GET_FUN(__glewMultiTexCoord2f)
+#define glMultiTexCoord2fv GLEW_GET_FUN(__glewMultiTexCoord2fv)
+#define glMultiTexCoord2i GLEW_GET_FUN(__glewMultiTexCoord2i)
+#define glMultiTexCoord2iv GLEW_GET_FUN(__glewMultiTexCoord2iv)
+#define glMultiTexCoord2s GLEW_GET_FUN(__glewMultiTexCoord2s)
+#define glMultiTexCoord2sv GLEW_GET_FUN(__glewMultiTexCoord2sv)
+#define glMultiTexCoord3d GLEW_GET_FUN(__glewMultiTexCoord3d)
+#define glMultiTexCoord3dv GLEW_GET_FUN(__glewMultiTexCoord3dv)
+#define glMultiTexCoord3f GLEW_GET_FUN(__glewMultiTexCoord3f)
+#define glMultiTexCoord3fv GLEW_GET_FUN(__glewMultiTexCoord3fv)
+#define glMultiTexCoord3i GLEW_GET_FUN(__glewMultiTexCoord3i)
+#define glMultiTexCoord3iv GLEW_GET_FUN(__glewMultiTexCoord3iv)
+#define glMultiTexCoord3s GLEW_GET_FUN(__glewMultiTexCoord3s)
+#define glMultiTexCoord3sv GLEW_GET_FUN(__glewMultiTexCoord3sv)
+#define glMultiTexCoord4d GLEW_GET_FUN(__glewMultiTexCoord4d)
+#define glMultiTexCoord4dv GLEW_GET_FUN(__glewMultiTexCoord4dv)
+#define glMultiTexCoord4f GLEW_GET_FUN(__glewMultiTexCoord4f)
+#define glMultiTexCoord4fv GLEW_GET_FUN(__glewMultiTexCoord4fv)
+#define glMultiTexCoord4i GLEW_GET_FUN(__glewMultiTexCoord4i)
+#define glMultiTexCoord4iv GLEW_GET_FUN(__glewMultiTexCoord4iv)
+#define glMultiTexCoord4s GLEW_GET_FUN(__glewMultiTexCoord4s)
+#define glMultiTexCoord4sv GLEW_GET_FUN(__glewMultiTexCoord4sv)
+#define glSampleCoverage GLEW_GET_FUN(__glewSampleCoverage)
+
+#define GLEW_VERSION_1_3 GLEW_GET_VAR(__GLEW_VERSION_1_3)
+
+#endif /* GL_VERSION_1_3 */
+
+/* ----------------------------- GL_VERSION_1_4 ---------------------------- */
+
+#ifndef GL_VERSION_1_4
+#define GL_VERSION_1_4 1
+
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_POINT_SIZE_MIN 0x8126
+#define GL_POINT_SIZE_MAX 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128
+#define GL_POINT_DISTANCE_ATTENUATION 0x8129
+#define GL_GENERATE_MIPMAP 0x8191
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_DEPTH_COMPONENT32 0x81A7
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_FOG_COORDINATE_SOURCE 0x8450
+#define GL_FOG_COORDINATE 0x8451
+#define GL_FRAGMENT_DEPTH 0x8452
+#define GL_CURRENT_FOG_COORDINATE 0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456
+#define GL_FOG_COORDINATE_ARRAY 0x8457
+#define GL_COLOR_SUM 0x8458
+#define GL_CURRENT_SECONDARY_COLOR 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D
+#define GL_SECONDARY_COLOR_ARRAY 0x845E
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_TEXTURE_FILTER_CONTROL 0x8500
+#define GL_TEXTURE_LOD_BIAS 0x8501
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_DEPTH_TEXTURE_MODE 0x884B
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_COMPARE_R_TO_TEXTURE 0x884E
+
+typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDDPROC) (GLdouble coord);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDDVPROC) (const GLdouble *coord);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDFPROC) (GLfloat coord);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDFVPROC) (const GLfloat *coord);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei drawcount);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVPROC) (const GLdouble *p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVPROC) (const GLfloat *p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IPROC) (GLint x, GLint y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVPROC) (const GLint *p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVPROC) (const GLshort *p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVPROC) (const GLdouble *p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVPROC) (const GLfloat *p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVPROC) (const GLint *p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVPROC) (const GLshort *p);
+
+#define glBlendColor GLEW_GET_FUN(__glewBlendColor)
+#define glBlendEquation GLEW_GET_FUN(__glewBlendEquation)
+#define glBlendFuncSeparate GLEW_GET_FUN(__glewBlendFuncSeparate)
+#define glFogCoordPointer GLEW_GET_FUN(__glewFogCoordPointer)
+#define glFogCoordd GLEW_GET_FUN(__glewFogCoordd)
+#define glFogCoorddv GLEW_GET_FUN(__glewFogCoorddv)
+#define glFogCoordf GLEW_GET_FUN(__glewFogCoordf)
+#define glFogCoordfv GLEW_GET_FUN(__glewFogCoordfv)
+#define glMultiDrawArrays GLEW_GET_FUN(__glewMultiDrawArrays)
+#define glMultiDrawElements GLEW_GET_FUN(__glewMultiDrawElements)
+#define glPointParameterf GLEW_GET_FUN(__glewPointParameterf)
+#define glPointParameterfv GLEW_GET_FUN(__glewPointParameterfv)
+#define glPointParameteri GLEW_GET_FUN(__glewPointParameteri)
+#define glPointParameteriv GLEW_GET_FUN(__glewPointParameteriv)
+#define glSecondaryColor3b GLEW_GET_FUN(__glewSecondaryColor3b)
+#define glSecondaryColor3bv GLEW_GET_FUN(__glewSecondaryColor3bv)
+#define glSecondaryColor3d GLEW_GET_FUN(__glewSecondaryColor3d)
+#define glSecondaryColor3dv GLEW_GET_FUN(__glewSecondaryColor3dv)
+#define glSecondaryColor3f GLEW_GET_FUN(__glewSecondaryColor3f)
+#define glSecondaryColor3fv GLEW_GET_FUN(__glewSecondaryColor3fv)
+#define glSecondaryColor3i GLEW_GET_FUN(__glewSecondaryColor3i)
+#define glSecondaryColor3iv GLEW_GET_FUN(__glewSecondaryColor3iv)
+#define glSecondaryColor3s GLEW_GET_FUN(__glewSecondaryColor3s)
+#define glSecondaryColor3sv GLEW_GET_FUN(__glewSecondaryColor3sv)
+#define glSecondaryColor3ub GLEW_GET_FUN(__glewSecondaryColor3ub)
+#define glSecondaryColor3ubv GLEW_GET_FUN(__glewSecondaryColor3ubv)
+#define glSecondaryColor3ui GLEW_GET_FUN(__glewSecondaryColor3ui)
+#define glSecondaryColor3uiv GLEW_GET_FUN(__glewSecondaryColor3uiv)
+#define glSecondaryColor3us GLEW_GET_FUN(__glewSecondaryColor3us)
+#define glSecondaryColor3usv GLEW_GET_FUN(__glewSecondaryColor3usv)
+#define glSecondaryColorPointer GLEW_GET_FUN(__glewSecondaryColorPointer)
+#define glWindowPos2d GLEW_GET_FUN(__glewWindowPos2d)
+#define glWindowPos2dv GLEW_GET_FUN(__glewWindowPos2dv)
+#define glWindowPos2f GLEW_GET_FUN(__glewWindowPos2f)
+#define glWindowPos2fv GLEW_GET_FUN(__glewWindowPos2fv)
+#define glWindowPos2i GLEW_GET_FUN(__glewWindowPos2i)
+#define glWindowPos2iv GLEW_GET_FUN(__glewWindowPos2iv)
+#define glWindowPos2s GLEW_GET_FUN(__glewWindowPos2s)
+#define glWindowPos2sv GLEW_GET_FUN(__glewWindowPos2sv)
+#define glWindowPos3d GLEW_GET_FUN(__glewWindowPos3d)
+#define glWindowPos3dv GLEW_GET_FUN(__glewWindowPos3dv)
+#define glWindowPos3f GLEW_GET_FUN(__glewWindowPos3f)
+#define glWindowPos3fv GLEW_GET_FUN(__glewWindowPos3fv)
+#define glWindowPos3i GLEW_GET_FUN(__glewWindowPos3i)
+#define glWindowPos3iv GLEW_GET_FUN(__glewWindowPos3iv)
+#define glWindowPos3s GLEW_GET_FUN(__glewWindowPos3s)
+#define glWindowPos3sv GLEW_GET_FUN(__glewWindowPos3sv)
+
+#define GLEW_VERSION_1_4 GLEW_GET_VAR(__GLEW_VERSION_1_4)
+
+#endif /* GL_VERSION_1_4 */
+
+/* ----------------------------- GL_VERSION_1_5 ---------------------------- */
+
+#ifndef GL_VERSION_1_5
+#define GL_VERSION_1_5 1
+
+#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE
+#define GL_FOG_COORD GL_FOG_COORDINATE
+#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY
+#define GL_SRC0_RGB GL_SOURCE0_RGB
+#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER
+#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE
+#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA
+#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE
+#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE
+#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA
+#define GL_SRC1_RGB GL_SOURCE1_RGB
+#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING
+#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA
+#define GL_SRC2_RGB GL_SOURCE2_RGB
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_QUERY_COUNTER_BITS 0x8864
+#define GL_CURRENT_QUERY 0x8865
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_READ_ONLY 0x88B8
+#define GL_WRITE_ONLY 0x88B9
+#define GL_READ_WRITE 0x88BA
+#define GL_BUFFER_ACCESS 0x88BB
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_COPY 0x88E2
+#define GL_STATIC_DRAW 0x88E4
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_COPY 0x88E6
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_SAMPLES_PASSED 0x8914
+
+typedef ptrdiff_t GLintptr;
+typedef ptrdiff_t GLsizeiptr;
+
+typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers);
+typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLENDQUERYPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint* buffers);
+typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid** params);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer);
+typedef GLboolean (GLAPIENTRY * PFNGLISQUERYPROC) (GLuint id);
+typedef GLvoid* (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
+typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERPROC) (GLenum target);
+
+#define glBeginQuery GLEW_GET_FUN(__glewBeginQuery)
+#define glBindBuffer GLEW_GET_FUN(__glewBindBuffer)
+#define glBufferData GLEW_GET_FUN(__glewBufferData)
+#define glBufferSubData GLEW_GET_FUN(__glewBufferSubData)
+#define glDeleteBuffers GLEW_GET_FUN(__glewDeleteBuffers)
+#define glDeleteQueries GLEW_GET_FUN(__glewDeleteQueries)
+#define glEndQuery GLEW_GET_FUN(__glewEndQuery)
+#define glGenBuffers GLEW_GET_FUN(__glewGenBuffers)
+#define glGenQueries GLEW_GET_FUN(__glewGenQueries)
+#define glGetBufferParameteriv GLEW_GET_FUN(__glewGetBufferParameteriv)
+#define glGetBufferPointerv GLEW_GET_FUN(__glewGetBufferPointerv)
+#define glGetBufferSubData GLEW_GET_FUN(__glewGetBufferSubData)
+#define glGetQueryObjectiv GLEW_GET_FUN(__glewGetQueryObjectiv)
+#define glGetQueryObjectuiv GLEW_GET_FUN(__glewGetQueryObjectuiv)
+#define glGetQueryiv GLEW_GET_FUN(__glewGetQueryiv)
+#define glIsBuffer GLEW_GET_FUN(__glewIsBuffer)
+#define glIsQuery GLEW_GET_FUN(__glewIsQuery)
+#define glMapBuffer GLEW_GET_FUN(__glewMapBuffer)
+#define glUnmapBuffer GLEW_GET_FUN(__glewUnmapBuffer)
+
+#define GLEW_VERSION_1_5 GLEW_GET_VAR(__GLEW_VERSION_1_5)
+
+#endif /* GL_VERSION_1_5 */
+
+/* ----------------------------- GL_VERSION_2_0 ---------------------------- */
+
+#ifndef GL_VERSION_2_0
+#define GL_VERSION_2_0 1
+
+#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_POINT_SPRITE 0x8861
+#define GL_COORD_REPLACE 0x8862
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_MAX_TEXTURE_COORDS 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_MAX_VARYING_FLOATS 0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_1D 0x8B5D
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_SAMPLER_1D_SHADOW 0x8B61
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_DELETE_STATUS 0x8B80
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
+#define GL_LOWER_LEFT 0x8CA1
+#define GL_UPPER_LEFT 0x8CA2
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+
+typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum, GLenum);
+typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader);
+typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (void);
+typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type);
+typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program);
+typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader);
+typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint);
+typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum* bufs);
+typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders);
+typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint* param);
+typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
+typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLuint obj, GLsizei maxLength, GLsizei* length, GLchar* source);
+typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint* param);
+typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint, GLenum, GLvoid**);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVPROC) (GLuint, GLenum, GLdouble*);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint, GLenum, GLfloat*);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint, GLenum, GLint*);
+typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program);
+typedef GLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader);
+typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program);
+typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths);
+typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum, GLuint);
+typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program);
+typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer);
+
+#define glAttachShader GLEW_GET_FUN(__glewAttachShader)
+#define glBindAttribLocation GLEW_GET_FUN(__glewBindAttribLocation)
+#define glBlendEquationSeparate GLEW_GET_FUN(__glewBlendEquationSeparate)
+#define glCompileShader GLEW_GET_FUN(__glewCompileShader)
+#define glCreateProgram GLEW_GET_FUN(__glewCreateProgram)
+#define glCreateShader GLEW_GET_FUN(__glewCreateShader)
+#define glDeleteProgram GLEW_GET_FUN(__glewDeleteProgram)
+#define glDeleteShader GLEW_GET_FUN(__glewDeleteShader)
+#define glDetachShader GLEW_GET_FUN(__glewDetachShader)
+#define glDisableVertexAttribArray GLEW_GET_FUN(__glewDisableVertexAttribArray)
+#define glDrawBuffers GLEW_GET_FUN(__glewDrawBuffers)
+#define glEnableVertexAttribArray GLEW_GET_FUN(__glewEnableVertexAttribArray)
+#define glGetActiveAttrib GLEW_GET_FUN(__glewGetActiveAttrib)
+#define glGetActiveUniform GLEW_GET_FUN(__glewGetActiveUniform)
+#define glGetAttachedShaders GLEW_GET_FUN(__glewGetAttachedShaders)
+#define glGetAttribLocation GLEW_GET_FUN(__glewGetAttribLocation)
+#define glGetProgramInfoLog GLEW_GET_FUN(__glewGetProgramInfoLog)
+#define glGetProgramiv GLEW_GET_FUN(__glewGetProgramiv)
+#define glGetShaderInfoLog GLEW_GET_FUN(__glewGetShaderInfoLog)
+#define glGetShaderSource GLEW_GET_FUN(__glewGetShaderSource)
+#define glGetShaderiv GLEW_GET_FUN(__glewGetShaderiv)
+#define glGetUniformLocation GLEW_GET_FUN(__glewGetUniformLocation)
+#define glGetUniformfv GLEW_GET_FUN(__glewGetUniformfv)
+#define glGetUniformiv GLEW_GET_FUN(__glewGetUniformiv)
+#define glGetVertexAttribPointerv GLEW_GET_FUN(__glewGetVertexAttribPointerv)
+#define glGetVertexAttribdv GLEW_GET_FUN(__glewGetVertexAttribdv)
+#define glGetVertexAttribfv GLEW_GET_FUN(__glewGetVertexAttribfv)
+#define glGetVertexAttribiv GLEW_GET_FUN(__glewGetVertexAttribiv)
+#define glIsProgram GLEW_GET_FUN(__glewIsProgram)
+#define glIsShader GLEW_GET_FUN(__glewIsShader)
+#define glLinkProgram GLEW_GET_FUN(__glewLinkProgram)
+#define glShaderSource GLEW_GET_FUN(__glewShaderSource)
+#define glStencilFuncSeparate GLEW_GET_FUN(__glewStencilFuncSeparate)
+#define glStencilMaskSeparate GLEW_GET_FUN(__glewStencilMaskSeparate)
+#define glStencilOpSeparate GLEW_GET_FUN(__glewStencilOpSeparate)
+#define glUniform1f GLEW_GET_FUN(__glewUniform1f)
+#define glUniform1fv GLEW_GET_FUN(__glewUniform1fv)
+#define glUniform1i GLEW_GET_FUN(__glewUniform1i)
+#define glUniform1iv GLEW_GET_FUN(__glewUniform1iv)
+#define glUniform2f GLEW_GET_FUN(__glewUniform2f)
+#define glUniform2fv GLEW_GET_FUN(__glewUniform2fv)
+#define glUniform2i GLEW_GET_FUN(__glewUniform2i)
+#define glUniform2iv GLEW_GET_FUN(__glewUniform2iv)
+#define glUniform3f GLEW_GET_FUN(__glewUniform3f)
+#define glUniform3fv GLEW_GET_FUN(__glewUniform3fv)
+#define glUniform3i GLEW_GET_FUN(__glewUniform3i)
+#define glUniform3iv GLEW_GET_FUN(__glewUniform3iv)
+#define glUniform4f GLEW_GET_FUN(__glewUniform4f)
+#define glUniform4fv GLEW_GET_FUN(__glewUniform4fv)
+#define glUniform4i GLEW_GET_FUN(__glewUniform4i)
+#define glUniform4iv GLEW_GET_FUN(__glewUniform4iv)
+#define glUniformMatrix2fv GLEW_GET_FUN(__glewUniformMatrix2fv)
+#define glUniformMatrix3fv GLEW_GET_FUN(__glewUniformMatrix3fv)
+#define glUniformMatrix4fv GLEW_GET_FUN(__glewUniformMatrix4fv)
+#define glUseProgram GLEW_GET_FUN(__glewUseProgram)
+#define glValidateProgram GLEW_GET_FUN(__glewValidateProgram)
+#define glVertexAttrib1d GLEW_GET_FUN(__glewVertexAttrib1d)
+#define glVertexAttrib1dv GLEW_GET_FUN(__glewVertexAttrib1dv)
+#define glVertexAttrib1f GLEW_GET_FUN(__glewVertexAttrib1f)
+#define glVertexAttrib1fv GLEW_GET_FUN(__glewVertexAttrib1fv)
+#define glVertexAttrib1s GLEW_GET_FUN(__glewVertexAttrib1s)
+#define glVertexAttrib1sv GLEW_GET_FUN(__glewVertexAttrib1sv)
+#define glVertexAttrib2d GLEW_GET_FUN(__glewVertexAttrib2d)
+#define glVertexAttrib2dv GLEW_GET_FUN(__glewVertexAttrib2dv)
+#define glVertexAttrib2f GLEW_GET_FUN(__glewVertexAttrib2f)
+#define glVertexAttrib2fv GLEW_GET_FUN(__glewVertexAttrib2fv)
+#define glVertexAttrib2s GLEW_GET_FUN(__glewVertexAttrib2s)
+#define glVertexAttrib2sv GLEW_GET_FUN(__glewVertexAttrib2sv)
+#define glVertexAttrib3d GLEW_GET_FUN(__glewVertexAttrib3d)
+#define glVertexAttrib3dv GLEW_GET_FUN(__glewVertexAttrib3dv)
+#define glVertexAttrib3f GLEW_GET_FUN(__glewVertexAttrib3f)
+#define glVertexAttrib3fv GLEW_GET_FUN(__glewVertexAttrib3fv)
+#define glVertexAttrib3s GLEW_GET_FUN(__glewVertexAttrib3s)
+#define glVertexAttrib3sv GLEW_GET_FUN(__glewVertexAttrib3sv)
+#define glVertexAttrib4Nbv GLEW_GET_FUN(__glewVertexAttrib4Nbv)
+#define glVertexAttrib4Niv GLEW_GET_FUN(__glewVertexAttrib4Niv)
+#define glVertexAttrib4Nsv GLEW_GET_FUN(__glewVertexAttrib4Nsv)
+#define glVertexAttrib4Nub GLEW_GET_FUN(__glewVertexAttrib4Nub)
+#define glVertexAttrib4Nubv GLEW_GET_FUN(__glewVertexAttrib4Nubv)
+#define glVertexAttrib4Nuiv GLEW_GET_FUN(__glewVertexAttrib4Nuiv)
+#define glVertexAttrib4Nusv GLEW_GET_FUN(__glewVertexAttrib4Nusv)
+#define glVertexAttrib4bv GLEW_GET_FUN(__glewVertexAttrib4bv)
+#define glVertexAttrib4d GLEW_GET_FUN(__glewVertexAttrib4d)
+#define glVertexAttrib4dv GLEW_GET_FUN(__glewVertexAttrib4dv)
+#define glVertexAttrib4f GLEW_GET_FUN(__glewVertexAttrib4f)
+#define glVertexAttrib4fv GLEW_GET_FUN(__glewVertexAttrib4fv)
+#define glVertexAttrib4iv GLEW_GET_FUN(__glewVertexAttrib4iv)
+#define glVertexAttrib4s GLEW_GET_FUN(__glewVertexAttrib4s)
+#define glVertexAttrib4sv GLEW_GET_FUN(__glewVertexAttrib4sv)
+#define glVertexAttrib4ubv GLEW_GET_FUN(__glewVertexAttrib4ubv)
+#define glVertexAttrib4uiv GLEW_GET_FUN(__glewVertexAttrib4uiv)
+#define glVertexAttrib4usv GLEW_GET_FUN(__glewVertexAttrib4usv)
+#define glVertexAttribPointer GLEW_GET_FUN(__glewVertexAttribPointer)
+
+#define GLEW_VERSION_2_0 GLEW_GET_VAR(__GLEW_VERSION_2_0)
+
+#endif /* GL_VERSION_2_0 */
+
+/* ----------------------------- GL_VERSION_2_1 ---------------------------- */
+
+#ifndef GL_VERSION_2_1
+#define GL_VERSION_2_1 1
+
+#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_FLOAT_MAT2x3 0x8B65
+#define GL_FLOAT_MAT2x4 0x8B66
+#define GL_FLOAT_MAT3x2 0x8B67
+#define GL_FLOAT_MAT3x4 0x8B68
+#define GL_FLOAT_MAT4x2 0x8B69
+#define GL_FLOAT_MAT4x3 0x8B6A
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB_ALPHA 0x8C42
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_SLUMINANCE_ALPHA 0x8C44
+#define GL_SLUMINANCE8_ALPHA8 0x8C45
+#define GL_SLUMINANCE 0x8C46
+#define GL_SLUMINANCE8 0x8C47
+#define GL_COMPRESSED_SRGB 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
+#define GL_COMPRESSED_SLUMINANCE 0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B
+
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+
+#define glUniformMatrix2x3fv GLEW_GET_FUN(__glewUniformMatrix2x3fv)
+#define glUniformMatrix2x4fv GLEW_GET_FUN(__glewUniformMatrix2x4fv)
+#define glUniformMatrix3x2fv GLEW_GET_FUN(__glewUniformMatrix3x2fv)
+#define glUniformMatrix3x4fv GLEW_GET_FUN(__glewUniformMatrix3x4fv)
+#define glUniformMatrix4x2fv GLEW_GET_FUN(__glewUniformMatrix4x2fv)
+#define glUniformMatrix4x3fv GLEW_GET_FUN(__glewUniformMatrix4x3fv)
+
+#define GLEW_VERSION_2_1 GLEW_GET_VAR(__GLEW_VERSION_2_1)
+
+#endif /* GL_VERSION_2_1 */
+
+/* ----------------------------- GL_VERSION_3_0 ---------------------------- */
+
+#ifndef GL_VERSION_3_0
+#define GL_VERSION_3_0 1
+
+#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES
+#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5
+#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1
+#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3
+#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB
+#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0
+#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4
+#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2
+#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MINOR_VERSION 0x821C
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_CONTEXT_FLAGS 0x821E
+#define GL_DEPTH_BUFFER 0x8223
+#define GL_STENCIL_BUFFER 0x8224
+#define GL_RGBA32F 0x8814
+#define GL_RGB32F 0x8815
+#define GL_RGBA16F 0x881A
+#define GL_RGB16F 0x881B
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_CLAMP_VERTEX_COLOR 0x891A
+#define GL_CLAMP_FRAGMENT_COLOR 0x891B
+#define GL_CLAMP_READ_COLOR 0x891C
+#define GL_FIXED_ONLY 0x891D
+#define GL_TEXTURE_RED_TYPE 0x8C10
+#define GL_TEXTURE_GREEN_TYPE 0x8C11
+#define GL_TEXTURE_BLUE_TYPE 0x8C12
+#define GL_TEXTURE_ALPHA_TYPE 0x8C13
+#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14
+#define GL_TEXTURE_INTENSITY_TYPE 0x8C15
+#define GL_TEXTURE_DEPTH_TYPE 0x8C16
+#define GL_TEXTURE_1D_ARRAY 0x8C18
+#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B
+#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_RGB9_E5 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_TEXTURE_SHARED_SIZE 0x8C3F
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_PRIMITIVES_GENERATED 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_RGBA32UI 0x8D70
+#define GL_RGB32UI 0x8D71
+#define GL_RGBA16UI 0x8D76
+#define GL_RGB16UI 0x8D77
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGB8UI 0x8D7D
+#define GL_RGBA32I 0x8D82
+#define GL_RGB32I 0x8D83
+#define GL_RGBA16I 0x8D88
+#define GL_RGB16I 0x8D89
+#define GL_RGBA8I 0x8D8E
+#define GL_RGB8I 0x8D8F
+#define GL_RED_INTEGER 0x8D94
+#define GL_GREEN_INTEGER 0x8D95
+#define GL_BLUE_INTEGER 0x8D96
+#define GL_ALPHA_INTEGER 0x8D97
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_BGR_INTEGER 0x8D9A
+#define GL_BGRA_INTEGER 0x8D9B
+#define GL_SAMPLER_1D_ARRAY 0x8DC0
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_INT_SAMPLER_1D 0x8DC9
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_QUERY_WAIT 0x8E13
+#define GL_QUERY_NO_WAIT 0x8E14
+#define GL_QUERY_BY_REGION_WAIT 0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16
+
+typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERPROC) (GLuint, GLenum);
+typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum);
+typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONPROC) (GLuint, GLuint, const GLchar*);
+typedef void (GLAPIENTRY * PFNGLCLAMPCOLORPROC) (GLenum, GLenum);
+typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum, GLint, GLfloat, GLint);
+typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFVPROC) (GLenum, GLint, const GLfloat*);
+typedef void (GLAPIENTRY * PFNGLCLEARBUFFERIVPROC) (GLenum, GLint, const GLint*);
+typedef void (GLAPIENTRY * PFNGLCLEARBUFFERUIVPROC) (GLenum, GLint, const GLuint*);
+typedef void (GLAPIENTRY * PFNGLCOLORMASKIPROC) (GLuint, GLboolean, GLboolean, GLboolean, GLboolean);
+typedef void (GLAPIENTRY * PFNGLDISABLEIPROC) (GLenum, GLuint);
+typedef void (GLAPIENTRY * PFNGLENABLEIPROC) (GLenum, GLuint);
+typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERPROC) (void);
+typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKPROC) (void);
+typedef void (GLAPIENTRY * PFNGLGETBOOLEANI_VPROC) (GLenum, GLuint, GLboolean*);
+typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint, const GLchar*);
+typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC) (GLenum, GLuint);
+typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVPROC) (GLenum, GLenum, GLint*);
+typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVPROC) (GLenum, GLenum, GLuint*);
+typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVPROC) (GLuint, GLint, GLuint*);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVPROC) (GLuint, GLenum, GLint*);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint, GLenum, GLuint*);
+typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIPROC) (GLenum, GLuint);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVPROC) (GLenum, GLenum, const GLint*);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVPROC) (GLenum, GLenum, const GLuint*);
+typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint, GLsizei, const GLchar **, GLenum);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1UIPROC) (GLint, GLuint);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVPROC) (GLint, GLsizei, const GLuint*);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2UIPROC) (GLint, GLuint, GLuint);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVPROC) (GLint, GLsizei, const GLuint*);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3UIPROC) (GLint, GLuint, GLuint, GLuint);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVPROC) (GLint, GLsizei, const GLuint*);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4UIPROC) (GLint, GLuint, GLuint, GLuint, GLuint);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVPROC) (GLint, GLsizei, const GLuint*);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IPROC) (GLuint, GLint);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVPROC) (GLuint, const GLint*);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIPROC) (GLuint, GLuint);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVPROC) (GLuint, const GLuint*);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IPROC) (GLuint, GLint, GLint);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVPROC) (GLuint, const GLint*);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIPROC) (GLuint, GLuint, GLuint);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVPROC) (GLuint, const GLuint*);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IPROC) (GLuint, GLint, GLint, GLint);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVPROC) (GLuint, const GLint*);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIPROC) (GLuint, GLuint, GLuint, GLuint);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVPROC) (GLuint, const GLuint*);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVPROC) (GLuint, const GLbyte*);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IPROC) (GLuint, GLint, GLint, GLint, GLint);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVPROC) (GLuint, const GLint*);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVPROC) (GLuint, const GLshort*);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVPROC) (GLuint, const GLubyte*);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIPROC) (GLuint, GLuint, GLuint, GLuint, GLuint);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVPROC) (GLuint, const GLuint*);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVPROC) (GLuint, const GLushort*);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint, GLint, GLenum, GLsizei, const GLvoid*);
+
+#define glBeginConditionalRender GLEW_GET_FUN(__glewBeginConditionalRender)
+#define glBeginTransformFeedback GLEW_GET_FUN(__glewBeginTransformFeedback)
+#define glBindFragDataLocation GLEW_GET_FUN(__glewBindFragDataLocation)
+#define glClampColor GLEW_GET_FUN(__glewClampColor)
+#define glClearBufferfi GLEW_GET_FUN(__glewClearBufferfi)
+#define glClearBufferfv GLEW_GET_FUN(__glewClearBufferfv)
+#define glClearBufferiv GLEW_GET_FUN(__glewClearBufferiv)
+#define glClearBufferuiv GLEW_GET_FUN(__glewClearBufferuiv)
+#define glColorMaski GLEW_GET_FUN(__glewColorMaski)
+#define glDisablei GLEW_GET_FUN(__glewDisablei)
+#define glEnablei GLEW_GET_FUN(__glewEnablei)
+#define glEndConditionalRender GLEW_GET_FUN(__glewEndConditionalRender)
+#define glEndTransformFeedback GLEW_GET_FUN(__glewEndTransformFeedback)
+#define glGetBooleani_v GLEW_GET_FUN(__glewGetBooleani_v)
+#define glGetFragDataLocation GLEW_GET_FUN(__glewGetFragDataLocation)
+#define glGetStringi GLEW_GET_FUN(__glewGetStringi)
+#define glGetTexParameterIiv GLEW_GET_FUN(__glewGetTexParameterIiv)
+#define glGetTexParameterIuiv GLEW_GET_FUN(__glewGetTexParameterIuiv)
+#define glGetTransformFeedbackVarying GLEW_GET_FUN(__glewGetTransformFeedbackVarying)
+#define glGetUniformuiv GLEW_GET_FUN(__glewGetUniformuiv)
+#define glGetVertexAttribIiv GLEW_GET_FUN(__glewGetVertexAttribIiv)
+#define glGetVertexAttribIuiv GLEW_GET_FUN(__glewGetVertexAttribIuiv)
+#define glIsEnabledi GLEW_GET_FUN(__glewIsEnabledi)
+#define glTexParameterIiv GLEW_GET_FUN(__glewTexParameterIiv)
+#define glTexParameterIuiv GLEW_GET_FUN(__glewTexParameterIuiv)
+#define glTransformFeedbackVaryings GLEW_GET_FUN(__glewTransformFeedbackVaryings)
+#define glUniform1ui GLEW_GET_FUN(__glewUniform1ui)
+#define glUniform1uiv GLEW_GET_FUN(__glewUniform1uiv)
+#define glUniform2ui GLEW_GET_FUN(__glewUniform2ui)
+#define glUniform2uiv GLEW_GET_FUN(__glewUniform2uiv)
+#define glUniform3ui GLEW_GET_FUN(__glewUniform3ui)
+#define glUniform3uiv GLEW_GET_FUN(__glewUniform3uiv)
+#define glUniform4ui GLEW_GET_FUN(__glewUniform4ui)
+#define glUniform4uiv GLEW_GET_FUN(__glewUniform4uiv)
+#define glVertexAttribI1i GLEW_GET_FUN(__glewVertexAttribI1i)
+#define glVertexAttribI1iv GLEW_GET_FUN(__glewVertexAttribI1iv)
+#define glVertexAttribI1ui GLEW_GET_FUN(__glewVertexAttribI1ui)
+#define glVertexAttribI1uiv GLEW_GET_FUN(__glewVertexAttribI1uiv)
+#define glVertexAttribI2i GLEW_GET_FUN(__glewVertexAttribI2i)
+#define glVertexAttribI2iv GLEW_GET_FUN(__glewVertexAttribI2iv)
+#define glVertexAttribI2ui GLEW_GET_FUN(__glewVertexAttribI2ui)
+#define glVertexAttribI2uiv GLEW_GET_FUN(__glewVertexAttribI2uiv)
+#define glVertexAttribI3i GLEW_GET_FUN(__glewVertexAttribI3i)
+#define glVertexAttribI3iv GLEW_GET_FUN(__glewVertexAttribI3iv)
+#define glVertexAttribI3ui GLEW_GET_FUN(__glewVertexAttribI3ui)
+#define glVertexAttribI3uiv GLEW_GET_FUN(__glewVertexAttribI3uiv)
+#define glVertexAttribI4bv GLEW_GET_FUN(__glewVertexAttribI4bv)
+#define glVertexAttribI4i GLEW_GET_FUN(__glewVertexAttribI4i)
+#define glVertexAttribI4iv GLEW_GET_FUN(__glewVertexAttribI4iv)
+#define glVertexAttribI4sv GLEW_GET_FUN(__glewVertexAttribI4sv)
+#define glVertexAttribI4ubv GLEW_GET_FUN(__glewVertexAttribI4ubv)
+#define glVertexAttribI4ui GLEW_GET_FUN(__glewVertexAttribI4ui)
+#define glVertexAttribI4uiv GLEW_GET_FUN(__glewVertexAttribI4uiv)
+#define glVertexAttribI4usv GLEW_GET_FUN(__glewVertexAttribI4usv)
+#define glVertexAttribIPointer GLEW_GET_FUN(__glewVertexAttribIPointer)
+
+#define GLEW_VERSION_3_0 GLEW_GET_VAR(__GLEW_VERSION_3_0)
+
+#endif /* GL_VERSION_3_0 */
+
+/* ----------------------------- GL_VERSION_3_1 ---------------------------- */
+
+#ifndef GL_VERSION_3_1
+#define GL_VERSION_3_1 1
+
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
+#define GL_SAMPLER_2D_RECT 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64
+#define GL_TEXTURE_BUFFER 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E
+#define GL_SAMPLER_BUFFER 0x8DC2
+#define GL_INT_SAMPLER_2D_RECT 0x8DCD
+#define GL_INT_SAMPLER_BUFFER 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
+#define GL_RED_SNORM 0x8F90
+#define GL_RG_SNORM 0x8F91
+#define GL_RGB_SNORM 0x8F92
+#define GL_RGBA_SNORM 0x8F93
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_R16_SNORM 0x8F98
+#define GL_RG16_SNORM 0x8F99
+#define GL_RGB16_SNORM 0x8F9A
+#define GL_RGBA16_SNORM 0x8F9B
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_PRIMITIVE_RESTART 0x8F9D
+#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum, GLint, GLsizei, GLsizei);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum, GLsizei, GLenum, const GLvoid*, GLsizei);
+typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint);
+typedef void (GLAPIENTRY * PFNGLTEXBUFFERPROC) (GLenum, GLenum, GLuint);
+
+#define glDrawArraysInstanced GLEW_GET_FUN(__glewDrawArraysInstanced)
+#define glDrawElementsInstanced GLEW_GET_FUN(__glewDrawElementsInstanced)
+#define glPrimitiveRestartIndex GLEW_GET_FUN(__glewPrimitiveRestartIndex)
+#define glTexBuffer GLEW_GET_FUN(__glewTexBuffer)
+
+#define GLEW_VERSION_3_1 GLEW_GET_VAR(__GLEW_VERSION_3_1)
+
+#endif /* GL_VERSION_3_1 */
+
+/* ----------------------------- GL_VERSION_3_2 ---------------------------- */
+
+#ifndef GL_VERSION_3_2
+#define GL_VERSION_3_2 1
+
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_LINES_ADJACENCY 0x000A
+#define GL_LINE_STRIP_ADJACENCY 0x000B
+#define GL_TRIANGLES_ADJACENCY 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D
+#define GL_PROGRAM_POINT_SIZE 0x8642
+#define GL_GEOMETRY_VERTICES_OUT 0x8916
+#define GL_GEOMETRY_INPUT_TYPE 0x8917
+#define GL_GEOMETRY_OUTPUT_TYPE 0x8918
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define GL_GEOMETRY_SHADER 0x8DD9
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum, GLenum, GLuint, GLint);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum, GLenum, GLint64 *);
+typedef void (GLAPIENTRY * PFNGLGETINTEGER64I_VPROC) (GLenum, GLuint, GLint64 *);
+
+#define glFramebufferTexture GLEW_GET_FUN(__glewFramebufferTexture)
+#define glGetBufferParameteri64v GLEW_GET_FUN(__glewGetBufferParameteri64v)
+#define glGetInteger64i_v GLEW_GET_FUN(__glewGetInteger64i_v)
+
+#define GLEW_VERSION_3_2 GLEW_GET_VAR(__GLEW_VERSION_3_2)
+
+#endif /* GL_VERSION_3_2 */
+
+/* ----------------------------- GL_VERSION_3_3 ---------------------------- */
+
+#ifndef GL_VERSION_3_3
+#define GL_VERSION_3_3 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+#define GL_RGB10_A2UI 0x906F
+
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor);
+
+#define glVertexAttribDivisor GLEW_GET_FUN(__glewVertexAttribDivisor)
+
+#define GLEW_VERSION_3_3 GLEW_GET_VAR(__GLEW_VERSION_3_3)
+
+#endif /* GL_VERSION_3_3 */
+
+/* ----------------------------- GL_VERSION_4_0 ---------------------------- */
+
+#ifndef GL_VERSION_4_0
+#define GL_VERSION_4_0 1
+
+#define GL_SAMPLE_SHADING 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F
+#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGPROC) (GLclampf value);
+
+#define glBlendEquationSeparatei GLEW_GET_FUN(__glewBlendEquationSeparatei)
+#define glBlendEquationi GLEW_GET_FUN(__glewBlendEquationi)
+#define glBlendFuncSeparatei GLEW_GET_FUN(__glewBlendFuncSeparatei)
+#define glBlendFunci GLEW_GET_FUN(__glewBlendFunci)
+#define glMinSampleShading GLEW_GET_FUN(__glewMinSampleShading)
+
+#define GLEW_VERSION_4_0 GLEW_GET_VAR(__GLEW_VERSION_4_0)
+
+#endif /* GL_VERSION_4_0 */
+
+/* ----------------------------- GL_VERSION_4_1 ---------------------------- */
+
+#ifndef GL_VERSION_4_1
+#define GL_VERSION_4_1 1
+
+#define GLEW_VERSION_4_1 GLEW_GET_VAR(__GLEW_VERSION_4_1)
+
+#endif /* GL_VERSION_4_1 */
+
+/* ----------------------------- GL_VERSION_4_2 ---------------------------- */
+
+#ifndef GL_VERSION_4_2
+#define GL_VERSION_4_2 1
+
+#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
+
+#define GLEW_VERSION_4_2 GLEW_GET_VAR(__GLEW_VERSION_4_2)
+
+#endif /* GL_VERSION_4_2 */
+
+/* ----------------------------- GL_VERSION_4_3 ---------------------------- */
+
+#ifndef GL_VERSION_4_3
+#define GL_VERSION_4_3 1
+
+#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9
+#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E
+
+#define GLEW_VERSION_4_3 GLEW_GET_VAR(__GLEW_VERSION_4_3)
+
+#endif /* GL_VERSION_4_3 */
+
+/* ----------------------------- GL_VERSION_4_4 ---------------------------- */
+
+#ifndef GL_VERSION_4_4
+#define GL_VERSION_4_4 1
+
+#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5
+
+#define GLEW_VERSION_4_4 GLEW_GET_VAR(__GLEW_VERSION_4_4)
+
+#endif /* GL_VERSION_4_4 */
+
+/* -------------------------- GL_3DFX_multisample -------------------------- */
+
+#ifndef GL_3DFX_multisample
+#define GL_3DFX_multisample 1
+
+#define GL_MULTISAMPLE_3DFX 0x86B2
+#define GL_SAMPLE_BUFFERS_3DFX 0x86B3
+#define GL_SAMPLES_3DFX 0x86B4
+#define GL_MULTISAMPLE_BIT_3DFX 0x20000000
+
+#define GLEW_3DFX_multisample GLEW_GET_VAR(__GLEW_3DFX_multisample)
+
+#endif /* GL_3DFX_multisample */
+
+/* ---------------------------- GL_3DFX_tbuffer ---------------------------- */
+
+#ifndef GL_3DFX_tbuffer
+#define GL_3DFX_tbuffer 1
+
+typedef void (GLAPIENTRY * PFNGLTBUFFERMASK3DFXPROC) (GLuint mask);
+
+#define glTbufferMask3DFX GLEW_GET_FUN(__glewTbufferMask3DFX)
+
+#define GLEW_3DFX_tbuffer GLEW_GET_VAR(__GLEW_3DFX_tbuffer)
+
+#endif /* GL_3DFX_tbuffer */
+
+/* -------------------- GL_3DFX_texture_compression_FXT1 ------------------- */
+
+#ifndef GL_3DFX_texture_compression_FXT1
+#define GL_3DFX_texture_compression_FXT1 1
+
+#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0
+#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1
+
+#define GLEW_3DFX_texture_compression_FXT1 GLEW_GET_VAR(__GLEW_3DFX_texture_compression_FXT1)
+
+#endif /* GL_3DFX_texture_compression_FXT1 */
+
+/* ----------------------- GL_AMD_blend_minmax_factor ---------------------- */
+
+#ifndef GL_AMD_blend_minmax_factor
+#define GL_AMD_blend_minmax_factor 1
+
+#define GL_FACTOR_MIN_AMD 0x901C
+#define GL_FACTOR_MAX_AMD 0x901D
+
+#define GLEW_AMD_blend_minmax_factor GLEW_GET_VAR(__GLEW_AMD_blend_minmax_factor)
+
+#endif /* GL_AMD_blend_minmax_factor */
+
+/* ----------------------- GL_AMD_conservative_depth ----------------------- */
+
+#ifndef GL_AMD_conservative_depth
+#define GL_AMD_conservative_depth 1
+
+#define GLEW_AMD_conservative_depth GLEW_GET_VAR(__GLEW_AMD_conservative_depth)
+
+#endif /* GL_AMD_conservative_depth */
+
+/* -------------------------- GL_AMD_debug_output -------------------------- */
+
+#ifndef GL_AMD_debug_output
+#define GL_AMD_debug_output 1
+
+#define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145
+#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147
+#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148
+#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149
+#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A
+#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B
+#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C
+#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D
+#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E
+#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F
+#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150
+
+typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id, GLenum category, GLenum severity, GLsizei length, const GLchar* message, GLvoid* userParam);
+
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, GLvoid *userParam);
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled);
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar* buf);
+typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum* categories, GLuint* severities, GLuint* ids, GLsizei* lengths, GLchar* message);
+
+#define glDebugMessageCallbackAMD GLEW_GET_FUN(__glewDebugMessageCallbackAMD)
+#define glDebugMessageEnableAMD GLEW_GET_FUN(__glewDebugMessageEnableAMD)
+#define glDebugMessageInsertAMD GLEW_GET_FUN(__glewDebugMessageInsertAMD)
+#define glGetDebugMessageLogAMD GLEW_GET_FUN(__glewGetDebugMessageLogAMD)
+
+#define GLEW_AMD_debug_output GLEW_GET_VAR(__GLEW_AMD_debug_output)
+
+#endif /* GL_AMD_debug_output */
+
+/* ---------------------- GL_AMD_depth_clamp_separate ---------------------- */
+
+#ifndef GL_AMD_depth_clamp_separate
+#define GL_AMD_depth_clamp_separate 1
+
+#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E
+#define GL_DEPTH_CLAMP_FAR_AMD 0x901F
+
+#define GLEW_AMD_depth_clamp_separate GLEW_GET_VAR(__GLEW_AMD_depth_clamp_separate)
+
+#endif /* GL_AMD_depth_clamp_separate */
+
+/* ----------------------- GL_AMD_draw_buffers_blend ----------------------- */
+
+#ifndef GL_AMD_draw_buffers_blend
+#define GL_AMD_draw_buffers_blend 1
+
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+
+#define glBlendEquationIndexedAMD GLEW_GET_FUN(__glewBlendEquationIndexedAMD)
+#define glBlendEquationSeparateIndexedAMD GLEW_GET_FUN(__glewBlendEquationSeparateIndexedAMD)
+#define glBlendFuncIndexedAMD GLEW_GET_FUN(__glewBlendFuncIndexedAMD)
+#define glBlendFuncSeparateIndexedAMD GLEW_GET_FUN(__glewBlendFuncSeparateIndexedAMD)
+
+#define GLEW_AMD_draw_buffers_blend GLEW_GET_VAR(__GLEW_AMD_draw_buffers_blend)
+
+#endif /* GL_AMD_draw_buffers_blend */
+
+/* ---------------------- GL_AMD_interleaved_elements ---------------------- */
+
+#ifndef GL_AMD_interleaved_elements
+#define GL_AMD_interleaved_elements 1
+
+#define GL_RED 0x1903
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_ALPHA 0x1906
+#define GL_RG8UI 0x8238
+#define GL_RG16UI 0x823A
+#define GL_RGBA8UI 0x8D7C
+#define GL_VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4
+#define GL_VERTEX_ID_SWIZZLE_AMD 0x91A5
+
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPARAMETERIAMDPROC) (GLuint index, GLenum pname, GLint param);
+
+#define glVertexAttribParameteriAMD GLEW_GET_FUN(__glewVertexAttribParameteriAMD)
+
+#define GLEW_AMD_interleaved_elements GLEW_GET_VAR(__GLEW_AMD_interleaved_elements)
+
+#endif /* GL_AMD_interleaved_elements */
+
+/* ----------------------- GL_AMD_multi_draw_indirect ---------------------- */
+
+#ifndef GL_AMD_multi_draw_indirect
+#define GL_AMD_multi_draw_indirect 1
+
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC) (GLenum mode, const GLvoid *indirect, GLsizei primcount, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC) (GLenum mode, GLenum type, const GLvoid *indirect, GLsizei primcount, GLsizei stride);
+
+#define glMultiDrawArraysIndirectAMD GLEW_GET_FUN(__glewMultiDrawArraysIndirectAMD)
+#define glMultiDrawElementsIndirectAMD GLEW_GET_FUN(__glewMultiDrawElementsIndirectAMD)
+
+#define GLEW_AMD_multi_draw_indirect GLEW_GET_VAR(__GLEW_AMD_multi_draw_indirect)
+
+#endif /* GL_AMD_multi_draw_indirect */
+
+/* ------------------------- GL_AMD_name_gen_delete ------------------------ */
+
+#ifndef GL_AMD_name_gen_delete
+#define GL_AMD_name_gen_delete 1
+
+#define GL_DATA_BUFFER_AMD 0x9151
+#define GL_PERFORMANCE_MONITOR_AMD 0x9152
+#define GL_QUERY_OBJECT_AMD 0x9153
+#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154
+#define GL_SAMPLER_OBJECT_AMD 0x9155
+
+typedef void (GLAPIENTRY * PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint* names);
+typedef void (GLAPIENTRY * PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint* names);
+typedef GLboolean (GLAPIENTRY * PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name);
+
+#define glDeleteNamesAMD GLEW_GET_FUN(__glewDeleteNamesAMD)
+#define glGenNamesAMD GLEW_GET_FUN(__glewGenNamesAMD)
+#define glIsNameAMD GLEW_GET_FUN(__glewIsNameAMD)
+
+#define GLEW_AMD_name_gen_delete GLEW_GET_VAR(__GLEW_AMD_name_gen_delete)
+
+#endif /* GL_AMD_name_gen_delete */
+
+/* ----------------------- GL_AMD_performance_monitor ---------------------- */
+
+#ifndef GL_AMD_performance_monitor
+#define GL_AMD_performance_monitor 1
+
+#define GL_COUNTER_TYPE_AMD 0x8BC0
+#define GL_COUNTER_RANGE_AMD 0x8BC1
+#define GL_UNSIGNED_INT64_AMD 0x8BC2
+#define GL_PERCENTAGE_AMD 0x8BC3
+#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4
+#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5
+#define GL_PERFMON_RESULT_AMD 0x8BC6
+
+typedef void (GLAPIENTRY * PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (GLAPIENTRY * PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors);
+typedef void (GLAPIENTRY * PFNGLENDPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (GLAPIENTRY * PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint *bytesWritten);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, GLchar *counterString);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint* numCounters, GLint *maxActiveCounters, GLsizei countersSize, GLuint *counters);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei* length, GLchar *groupString);
+typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint* numGroups, GLsizei groupsSize, GLuint *groups);
+typedef void (GLAPIENTRY * PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* counterList);
+
+#define glBeginPerfMonitorAMD GLEW_GET_FUN(__glewBeginPerfMonitorAMD)
+#define glDeletePerfMonitorsAMD GLEW_GET_FUN(__glewDeletePerfMonitorsAMD)
+#define glEndPerfMonitorAMD GLEW_GET_FUN(__glewEndPerfMonitorAMD)
+#define glGenPerfMonitorsAMD GLEW_GET_FUN(__glewGenPerfMonitorsAMD)
+#define glGetPerfMonitorCounterDataAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterDataAMD)
+#define glGetPerfMonitorCounterInfoAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterInfoAMD)
+#define glGetPerfMonitorCounterStringAMD GLEW_GET_FUN(__glewGetPerfMonitorCounterStringAMD)
+#define glGetPerfMonitorCountersAMD GLEW_GET_FUN(__glewGetPerfMonitorCountersAMD)
+#define glGetPerfMonitorGroupStringAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupStringAMD)
+#define glGetPerfMonitorGroupsAMD GLEW_GET_FUN(__glewGetPerfMonitorGroupsAMD)
+#define glSelectPerfMonitorCountersAMD GLEW_GET_FUN(__glewSelectPerfMonitorCountersAMD)
+
+#define GLEW_AMD_performance_monitor GLEW_GET_VAR(__GLEW_AMD_performance_monitor)
+
+#endif /* GL_AMD_performance_monitor */
+
+/* -------------------------- GL_AMD_pinned_memory ------------------------- */
+
+#ifndef GL_AMD_pinned_memory
+#define GL_AMD_pinned_memory 1
+
+#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160
+
+#define GLEW_AMD_pinned_memory GLEW_GET_VAR(__GLEW_AMD_pinned_memory)
+
+#endif /* GL_AMD_pinned_memory */
+
+/* ----------------------- GL_AMD_query_buffer_object ---------------------- */
+
+#ifndef GL_AMD_query_buffer_object
+#define GL_AMD_query_buffer_object 1
+
+#define GL_QUERY_BUFFER_AMD 0x9192
+#define GL_QUERY_BUFFER_BINDING_AMD 0x9193
+#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194
+
+#define GLEW_AMD_query_buffer_object GLEW_GET_VAR(__GLEW_AMD_query_buffer_object)
+
+#endif /* GL_AMD_query_buffer_object */
+
+/* ------------------------ GL_AMD_sample_positions ------------------------ */
+
+#ifndef GL_AMD_sample_positions
+#define GL_AMD_sample_positions 1
+
+#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F
+
+typedef void (GLAPIENTRY * PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat* val);
+
+#define glSetMultisamplefvAMD GLEW_GET_FUN(__glewSetMultisamplefvAMD)
+
+#define GLEW_AMD_sample_positions GLEW_GET_VAR(__GLEW_AMD_sample_positions)
+
+#endif /* GL_AMD_sample_positions */
+
+/* ------------------ GL_AMD_seamless_cubemap_per_texture ------------------ */
+
+#ifndef GL_AMD_seamless_cubemap_per_texture
+#define GL_AMD_seamless_cubemap_per_texture 1
+
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS_ARB 0x884F
+
+#define GLEW_AMD_seamless_cubemap_per_texture GLEW_GET_VAR(__GLEW_AMD_seamless_cubemap_per_texture)
+
+#endif /* GL_AMD_seamless_cubemap_per_texture */
+
+/* ---------------------- GL_AMD_shader_stencil_export --------------------- */
+
+#ifndef GL_AMD_shader_stencil_export
+#define GL_AMD_shader_stencil_export 1
+
+#define GLEW_AMD_shader_stencil_export GLEW_GET_VAR(__GLEW_AMD_shader_stencil_export)
+
+#endif /* GL_AMD_shader_stencil_export */
+
+/* ---------------------- GL_AMD_shader_trinary_minmax --------------------- */
+
+#ifndef GL_AMD_shader_trinary_minmax
+#define GL_AMD_shader_trinary_minmax 1
+
+#define GLEW_AMD_shader_trinary_minmax GLEW_GET_VAR(__GLEW_AMD_shader_trinary_minmax)
+
+#endif /* GL_AMD_shader_trinary_minmax */
+
+/* ------------------------- GL_AMD_sparse_texture ------------------------- */
+
+#ifndef GL_AMD_sparse_texture
+#define GL_AMD_sparse_texture 1
+
+#define GL_TEXTURE_STORAGE_SPARSE_BIT_AMD 0x00000001
+#define GL_VIRTUAL_PAGE_SIZE_X_AMD 0x9195
+#define GL_VIRTUAL_PAGE_SIZE_Y_AMD 0x9196
+#define GL_VIRTUAL_PAGE_SIZE_Z_AMD 0x9197
+#define GL_MAX_SPARSE_TEXTURE_SIZE_AMD 0x9198
+#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD 0x9199
+#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS 0x919A
+#define GL_MIN_SPARSE_LEVEL_AMD 0x919B
+#define GL_MIN_LOD_WARNING_AMD 0x919C
+
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGESPARSEAMDPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGESPARSEAMDPROC) (GLuint texture, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei layers, GLbitfield flags);
+
+#define glTexStorageSparseAMD GLEW_GET_FUN(__glewTexStorageSparseAMD)
+#define glTextureStorageSparseAMD GLEW_GET_FUN(__glewTextureStorageSparseAMD)
+
+#define GLEW_AMD_sparse_texture GLEW_GET_VAR(__GLEW_AMD_sparse_texture)
+
+#endif /* GL_AMD_sparse_texture */
+
+/* ------------------- GL_AMD_stencil_operation_extended ------------------- */
+
+#ifndef GL_AMD_stencil_operation_extended
+#define GL_AMD_stencil_operation_extended 1
+
+#define GL_SET_AMD 0x874A
+#define GL_REPLACE_VALUE_AMD 0x874B
+#define GL_STENCIL_OP_VALUE_AMD 0x874C
+#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D
+
+typedef void (GLAPIENTRY * PFNGLSTENCILOPVALUEAMDPROC) (GLenum face, GLuint value);
+
+#define glStencilOpValueAMD GLEW_GET_FUN(__glewStencilOpValueAMD)
+
+#define GLEW_AMD_stencil_operation_extended GLEW_GET_VAR(__GLEW_AMD_stencil_operation_extended)
+
+#endif /* GL_AMD_stencil_operation_extended */
+
+/* ------------------------ GL_AMD_texture_texture4 ------------------------ */
+
+#ifndef GL_AMD_texture_texture4
+#define GL_AMD_texture_texture4 1
+
+#define GLEW_AMD_texture_texture4 GLEW_GET_VAR(__GLEW_AMD_texture_texture4)
+
+#endif /* GL_AMD_texture_texture4 */
+
+/* --------------- GL_AMD_transform_feedback3_lines_triangles -------------- */
+
+#ifndef GL_AMD_transform_feedback3_lines_triangles
+#define GL_AMD_transform_feedback3_lines_triangles 1
+
+#define GLEW_AMD_transform_feedback3_lines_triangles GLEW_GET_VAR(__GLEW_AMD_transform_feedback3_lines_triangles)
+
+#endif /* GL_AMD_transform_feedback3_lines_triangles */
+
+/* ----------------------- GL_AMD_vertex_shader_layer ---------------------- */
+
+#ifndef GL_AMD_vertex_shader_layer
+#define GL_AMD_vertex_shader_layer 1
+
+#define GLEW_AMD_vertex_shader_layer GLEW_GET_VAR(__GLEW_AMD_vertex_shader_layer)
+
+#endif /* GL_AMD_vertex_shader_layer */
+
+/* -------------------- GL_AMD_vertex_shader_tessellator ------------------- */
+
+#ifndef GL_AMD_vertex_shader_tessellator
+#define GL_AMD_vertex_shader_tessellator 1
+
+#define GL_SAMPLER_BUFFER_AMD 0x9001
+#define GL_INT_SAMPLER_BUFFER_AMD 0x9002
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003
+#define GL_TESSELLATION_MODE_AMD 0x9004
+#define GL_TESSELLATION_FACTOR_AMD 0x9005
+#define GL_DISCRETE_AMD 0x9006
+#define GL_CONTINUOUS_AMD 0x9007
+
+typedef void (GLAPIENTRY * PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor);
+typedef void (GLAPIENTRY * PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode);
+
+#define glTessellationFactorAMD GLEW_GET_FUN(__glewTessellationFactorAMD)
+#define glTessellationModeAMD GLEW_GET_FUN(__glewTessellationModeAMD)
+
+#define GLEW_AMD_vertex_shader_tessellator GLEW_GET_VAR(__GLEW_AMD_vertex_shader_tessellator)
+
+#endif /* GL_AMD_vertex_shader_tessellator */
+
+/* ------------------ GL_AMD_vertex_shader_viewport_index ------------------ */
+
+#ifndef GL_AMD_vertex_shader_viewport_index
+#define GL_AMD_vertex_shader_viewport_index 1
+
+#define GLEW_AMD_vertex_shader_viewport_index GLEW_GET_VAR(__GLEW_AMD_vertex_shader_viewport_index)
+
+#endif /* GL_AMD_vertex_shader_viewport_index */
+
+/* ------------------------- GL_ANGLE_depth_texture ------------------------ */
+
+#ifndef GL_ANGLE_depth_texture
+#define GL_ANGLE_depth_texture 1
+
+#define GLEW_ANGLE_depth_texture GLEW_GET_VAR(__GLEW_ANGLE_depth_texture)
+
+#endif /* GL_ANGLE_depth_texture */
+
+/* ----------------------- GL_ANGLE_framebuffer_blit ----------------------- */
+
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_ANGLE_framebuffer_blit 1
+
+#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
+
+typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+
+#define glBlitFramebufferANGLE GLEW_GET_FUN(__glewBlitFramebufferANGLE)
+
+#define GLEW_ANGLE_framebuffer_blit GLEW_GET_VAR(__GLEW_ANGLE_framebuffer_blit)
+
+#endif /* GL_ANGLE_framebuffer_blit */
+
+/* -------------------- GL_ANGLE_framebuffer_multisample ------------------- */
+
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_ANGLE_framebuffer_multisample 1
+
+#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
+#define GL_MAX_SAMPLES_ANGLE 0x8D57
+
+typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+
+#define glRenderbufferStorageMultisampleANGLE GLEW_GET_FUN(__glewRenderbufferStorageMultisampleANGLE)
+
+#define GLEW_ANGLE_framebuffer_multisample GLEW_GET_VAR(__GLEW_ANGLE_framebuffer_multisample)
+
+#endif /* GL_ANGLE_framebuffer_multisample */
+
+/* ----------------------- GL_ANGLE_instanced_arrays ----------------------- */
+
+#ifndef GL_ANGLE_instanced_arrays
+#define GL_ANGLE_instanced_arrays 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor);
+
+#define glDrawArraysInstancedANGLE GLEW_GET_FUN(__glewDrawArraysInstancedANGLE)
+#define glDrawElementsInstancedANGLE GLEW_GET_FUN(__glewDrawElementsInstancedANGLE)
+#define glVertexAttribDivisorANGLE GLEW_GET_FUN(__glewVertexAttribDivisorANGLE)
+
+#define GLEW_ANGLE_instanced_arrays GLEW_GET_VAR(__GLEW_ANGLE_instanced_arrays)
+
+#endif /* GL_ANGLE_instanced_arrays */
+
+/* -------------------- GL_ANGLE_pack_reverse_row_order -------------------- */
+
+#ifndef GL_ANGLE_pack_reverse_row_order
+#define GL_ANGLE_pack_reverse_row_order 1
+
+#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4
+
+#define GLEW_ANGLE_pack_reverse_row_order GLEW_GET_VAR(__GLEW_ANGLE_pack_reverse_row_order)
+
+#endif /* GL_ANGLE_pack_reverse_row_order */
+
+/* ------------------------ GL_ANGLE_program_binary ------------------------ */
+
+#ifndef GL_ANGLE_program_binary
+#define GL_ANGLE_program_binary 1
+
+#define GL_PROGRAM_BINARY_ANGLE 0x93A6
+
+#define GLEW_ANGLE_program_binary GLEW_GET_VAR(__GLEW_ANGLE_program_binary)
+
+#endif /* GL_ANGLE_program_binary */
+
+/* ------------------- GL_ANGLE_texture_compression_dxt1 ------------------- */
+
+#ifndef GL_ANGLE_texture_compression_dxt1
+#define GL_ANGLE_texture_compression_dxt1 1
+
+#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3
+
+#define GLEW_ANGLE_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt1)
+
+#endif /* GL_ANGLE_texture_compression_dxt1 */
+
+/* ------------------- GL_ANGLE_texture_compression_dxt3 ------------------- */
+
+#ifndef GL_ANGLE_texture_compression_dxt3
+#define GL_ANGLE_texture_compression_dxt3 1
+
+#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3
+
+#define GLEW_ANGLE_texture_compression_dxt3 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt3)
+
+#endif /* GL_ANGLE_texture_compression_dxt3 */
+
+/* ------------------- GL_ANGLE_texture_compression_dxt5 ------------------- */
+
+#ifndef GL_ANGLE_texture_compression_dxt5
+#define GL_ANGLE_texture_compression_dxt5 1
+
+#define GL_COMPRESSED_RGB_S3TC_DXT1_ANGLE 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_ANGLE 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3
+
+#define GLEW_ANGLE_texture_compression_dxt5 GLEW_GET_VAR(__GLEW_ANGLE_texture_compression_dxt5)
+
+#endif /* GL_ANGLE_texture_compression_dxt5 */
+
+/* ------------------------- GL_ANGLE_texture_usage ------------------------ */
+
+#ifndef GL_ANGLE_texture_usage
+#define GL_ANGLE_texture_usage 1
+
+#define GL_TEXTURE_USAGE_ANGLE 0x93A2
+#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3
+
+#define GLEW_ANGLE_texture_usage GLEW_GET_VAR(__GLEW_ANGLE_texture_usage)
+
+#endif /* GL_ANGLE_texture_usage */
+
+/* -------------------------- GL_ANGLE_timer_query ------------------------- */
+
+#ifndef GL_ANGLE_timer_query
+#define GL_ANGLE_timer_query 1
+
+#define GL_QUERY_COUNTER_BITS_ANGLE 0x8864
+#define GL_CURRENT_QUERY_ANGLE 0x8865
+#define GL_QUERY_RESULT_ANGLE 0x8866
+#define GL_QUERY_RESULT_AVAILABLE_ANGLE 0x8867
+#define GL_TIME_ELAPSED_ANGLE 0x88BF
+#define GL_TIMESTAMP_ANGLE 0x8E28
+
+typedef void (GLAPIENTRY * PFNGLBEGINQUERYANGLEPROC) (GLenum target, GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETEQUERIESANGLEPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLENDQUERYANGLEPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLGENQUERIESANGLEPROC) (GLsizei n, GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VANGLEPROC) (GLuint id, GLenum pname, GLint64* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVANGLEPROC) (GLuint id, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VANGLEPROC) (GLuint id, GLenum pname, GLuint64* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVANGLEPROC) (GLuint id, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYIVANGLEPROC) (GLenum target, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISQUERYANGLEPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERANGLEPROC) (GLuint id, GLenum target);
+
+#define glBeginQueryANGLE GLEW_GET_FUN(__glewBeginQueryANGLE)
+#define glDeleteQueriesANGLE GLEW_GET_FUN(__glewDeleteQueriesANGLE)
+#define glEndQueryANGLE GLEW_GET_FUN(__glewEndQueryANGLE)
+#define glGenQueriesANGLE GLEW_GET_FUN(__glewGenQueriesANGLE)
+#define glGetQueryObjecti64vANGLE GLEW_GET_FUN(__glewGetQueryObjecti64vANGLE)
+#define glGetQueryObjectivANGLE GLEW_GET_FUN(__glewGetQueryObjectivANGLE)
+#define glGetQueryObjectui64vANGLE GLEW_GET_FUN(__glewGetQueryObjectui64vANGLE)
+#define glGetQueryObjectuivANGLE GLEW_GET_FUN(__glewGetQueryObjectuivANGLE)
+#define glGetQueryivANGLE GLEW_GET_FUN(__glewGetQueryivANGLE)
+#define glIsQueryANGLE GLEW_GET_FUN(__glewIsQueryANGLE)
+#define glQueryCounterANGLE GLEW_GET_FUN(__glewQueryCounterANGLE)
+
+#define GLEW_ANGLE_timer_query GLEW_GET_VAR(__GLEW_ANGLE_timer_query)
+
+#endif /* GL_ANGLE_timer_query */
+
+/* ------------------- GL_ANGLE_translated_shader_source ------------------- */
+
+#ifndef GL_ANGLE_translated_shader_source
+#define GL_ANGLE_translated_shader_source 1
+
+#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0
+
+typedef void (GLAPIENTRY * PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+
+#define glGetTranslatedShaderSourceANGLE GLEW_GET_FUN(__glewGetTranslatedShaderSourceANGLE)
+
+#define GLEW_ANGLE_translated_shader_source GLEW_GET_VAR(__GLEW_ANGLE_translated_shader_source)
+
+#endif /* GL_ANGLE_translated_shader_source */
+
+/* ----------------------- GL_APPLE_aux_depth_stencil ---------------------- */
+
+#ifndef GL_APPLE_aux_depth_stencil
+#define GL_APPLE_aux_depth_stencil 1
+
+#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14
+
+#define GLEW_APPLE_aux_depth_stencil GLEW_GET_VAR(__GLEW_APPLE_aux_depth_stencil)
+
+#endif /* GL_APPLE_aux_depth_stencil */
+
+/* ------------------------ GL_APPLE_client_storage ------------------------ */
+
+#ifndef GL_APPLE_client_storage
+#define GL_APPLE_client_storage 1
+
+#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2
+
+#define GLEW_APPLE_client_storage GLEW_GET_VAR(__GLEW_APPLE_client_storage)
+
+#endif /* GL_APPLE_client_storage */
+
+/* ------------------------- GL_APPLE_element_array ------------------------ */
+
+#ifndef GL_APPLE_element_array
+#define GL_APPLE_element_array 1
+
+#define GL_ELEMENT_ARRAY_APPLE 0x8A0C
+#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D
+#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E
+
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count);
+typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint* first, const GLsizei *count, GLsizei primcount);
+
+#define glDrawElementArrayAPPLE GLEW_GET_FUN(__glewDrawElementArrayAPPLE)
+#define glDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewDrawRangeElementArrayAPPLE)
+#define glElementPointerAPPLE GLEW_GET_FUN(__glewElementPointerAPPLE)
+#define glMultiDrawElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawElementArrayAPPLE)
+#define glMultiDrawRangeElementArrayAPPLE GLEW_GET_FUN(__glewMultiDrawRangeElementArrayAPPLE)
+
+#define GLEW_APPLE_element_array GLEW_GET_VAR(__GLEW_APPLE_element_array)
+
+#endif /* GL_APPLE_element_array */
+
+/* ----------------------------- GL_APPLE_fence ---------------------------- */
+
+#ifndef GL_APPLE_fence
+#define GL_APPLE_fence 1
+
+#define GL_DRAW_PIXELS_APPLE 0x8A0A
+#define GL_FENCE_APPLE 0x8A0B
+
+typedef void (GLAPIENTRY * PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint* fences);
+typedef void (GLAPIENTRY * PFNGLFINISHFENCEAPPLEPROC) (GLuint fence);
+typedef void (GLAPIENTRY * PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name);
+typedef void (GLAPIENTRY * PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint* fences);
+typedef GLboolean (GLAPIENTRY * PFNGLISFENCEAPPLEPROC) (GLuint fence);
+typedef void (GLAPIENTRY * PFNGLSETFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (GLAPIENTRY * PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name);
+
+#define glDeleteFencesAPPLE GLEW_GET_FUN(__glewDeleteFencesAPPLE)
+#define glFinishFenceAPPLE GLEW_GET_FUN(__glewFinishFenceAPPLE)
+#define glFinishObjectAPPLE GLEW_GET_FUN(__glewFinishObjectAPPLE)
+#define glGenFencesAPPLE GLEW_GET_FUN(__glewGenFencesAPPLE)
+#define glIsFenceAPPLE GLEW_GET_FUN(__glewIsFenceAPPLE)
+#define glSetFenceAPPLE GLEW_GET_FUN(__glewSetFenceAPPLE)
+#define glTestFenceAPPLE GLEW_GET_FUN(__glewTestFenceAPPLE)
+#define glTestObjectAPPLE GLEW_GET_FUN(__glewTestObjectAPPLE)
+
+#define GLEW_APPLE_fence GLEW_GET_VAR(__GLEW_APPLE_fence)
+
+#endif /* GL_APPLE_fence */
+
+/* ------------------------- GL_APPLE_float_pixels ------------------------- */
+
+#ifndef GL_APPLE_float_pixels
+#define GL_APPLE_float_pixels 1
+
+#define GL_HALF_APPLE 0x140B
+#define GL_RGBA_FLOAT32_APPLE 0x8814
+#define GL_RGB_FLOAT32_APPLE 0x8815
+#define GL_ALPHA_FLOAT32_APPLE 0x8816
+#define GL_INTENSITY_FLOAT32_APPLE 0x8817
+#define GL_LUMINANCE_FLOAT32_APPLE 0x8818
+#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819
+#define GL_RGBA_FLOAT16_APPLE 0x881A
+#define GL_RGB_FLOAT16_APPLE 0x881B
+#define GL_ALPHA_FLOAT16_APPLE 0x881C
+#define GL_INTENSITY_FLOAT16_APPLE 0x881D
+#define GL_LUMINANCE_FLOAT16_APPLE 0x881E
+#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F
+#define GL_COLOR_FLOAT_APPLE 0x8A0F
+
+#define GLEW_APPLE_float_pixels GLEW_GET_VAR(__GLEW_APPLE_float_pixels)
+
+#endif /* GL_APPLE_float_pixels */
+
+/* ---------------------- GL_APPLE_flush_buffer_range ---------------------- */
+
+#ifndef GL_APPLE_flush_buffer_range
+#define GL_APPLE_flush_buffer_range 1
+
+#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12
+#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13
+
+typedef void (GLAPIENTRY * PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size);
+
+#define glBufferParameteriAPPLE GLEW_GET_FUN(__glewBufferParameteriAPPLE)
+#define glFlushMappedBufferRangeAPPLE GLEW_GET_FUN(__glewFlushMappedBufferRangeAPPLE)
+
+#define GLEW_APPLE_flush_buffer_range GLEW_GET_VAR(__GLEW_APPLE_flush_buffer_range)
+
+#endif /* GL_APPLE_flush_buffer_range */
+
+/* ----------------------- GL_APPLE_object_purgeable ----------------------- */
+
+#ifndef GL_APPLE_object_purgeable
+#define GL_APPLE_object_purgeable 1
+
+#define GL_BUFFER_OBJECT_APPLE 0x85B3
+#define GL_RELEASED_APPLE 0x8A19
+#define GL_VOLATILE_APPLE 0x8A1A
+#define GL_RETAINED_APPLE 0x8A1B
+#define GL_UNDEFINED_APPLE 0x8A1C
+#define GL_PURGEABLE_APPLE 0x8A1D
+
+typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint* params);
+typedef GLenum (GLAPIENTRY * PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+typedef GLenum (GLAPIENTRY * PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+
+#define glGetObjectParameterivAPPLE GLEW_GET_FUN(__glewGetObjectParameterivAPPLE)
+#define glObjectPurgeableAPPLE GLEW_GET_FUN(__glewObjectPurgeableAPPLE)
+#define glObjectUnpurgeableAPPLE GLEW_GET_FUN(__glewObjectUnpurgeableAPPLE)
+
+#define GLEW_APPLE_object_purgeable GLEW_GET_VAR(__GLEW_APPLE_object_purgeable)
+
+#endif /* GL_APPLE_object_purgeable */
+
+/* ------------------------- GL_APPLE_pixel_buffer ------------------------- */
+
+#ifndef GL_APPLE_pixel_buffer
+#define GL_APPLE_pixel_buffer 1
+
+#define GL_MIN_PBUFFER_VIEWPORT_DIMS_APPLE 0x8A10
+
+#define GLEW_APPLE_pixel_buffer GLEW_GET_VAR(__GLEW_APPLE_pixel_buffer)
+
+#endif /* GL_APPLE_pixel_buffer */
+
+/* ---------------------------- GL_APPLE_rgb_422 --------------------------- */
+
+#ifndef GL_APPLE_rgb_422
+#define GL_APPLE_rgb_422 1
+
+#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
+#define GL_RGB_422_APPLE 0x8A1F
+
+#define GLEW_APPLE_rgb_422 GLEW_GET_VAR(__GLEW_APPLE_rgb_422)
+
+#endif /* GL_APPLE_rgb_422 */
+
+/* --------------------------- GL_APPLE_row_bytes -------------------------- */
+
+#ifndef GL_APPLE_row_bytes
+#define GL_APPLE_row_bytes 1
+
+#define GL_PACK_ROW_BYTES_APPLE 0x8A15
+#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16
+
+#define GLEW_APPLE_row_bytes GLEW_GET_VAR(__GLEW_APPLE_row_bytes)
+
+#endif /* GL_APPLE_row_bytes */
+
+/* ------------------------ GL_APPLE_specular_vector ----------------------- */
+
+#ifndef GL_APPLE_specular_vector
+#define GL_APPLE_specular_vector 1
+
+#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0
+
+#define GLEW_APPLE_specular_vector GLEW_GET_VAR(__GLEW_APPLE_specular_vector)
+
+#endif /* GL_APPLE_specular_vector */
+
+/* ------------------------- GL_APPLE_texture_range ------------------------ */
+
+#ifndef GL_APPLE_texture_range
+#define GL_APPLE_texture_range 1
+
+#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7
+#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8
+#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
+#define GL_STORAGE_PRIVATE_APPLE 0x85BD
+#define GL_STORAGE_CACHED_APPLE 0x85BE
+#define GL_STORAGE_SHARED_APPLE 0x85BF
+
+typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid **params);
+typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, GLvoid *pointer);
+
+#define glGetTexParameterPointervAPPLE GLEW_GET_FUN(__glewGetTexParameterPointervAPPLE)
+#define glTextureRangeAPPLE GLEW_GET_FUN(__glewTextureRangeAPPLE)
+
+#define GLEW_APPLE_texture_range GLEW_GET_VAR(__GLEW_APPLE_texture_range)
+
+#endif /* GL_APPLE_texture_range */
+
+/* ------------------------ GL_APPLE_transform_hint ------------------------ */
+
+#ifndef GL_APPLE_transform_hint
+#define GL_APPLE_transform_hint 1
+
+#define GL_TRANSFORM_HINT_APPLE 0x85B1
+
+#define GLEW_APPLE_transform_hint GLEW_GET_VAR(__GLEW_APPLE_transform_hint)
+
+#endif /* GL_APPLE_transform_hint */
+
+/* ---------------------- GL_APPLE_vertex_array_object --------------------- */
+
+#ifndef GL_APPLE_vertex_array_object
+#define GL_APPLE_vertex_array_object 1
+
+#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5
+
+typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array);
+typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays);
+typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays);
+typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array);
+
+#define glBindVertexArrayAPPLE GLEW_GET_FUN(__glewBindVertexArrayAPPLE)
+#define glDeleteVertexArraysAPPLE GLEW_GET_FUN(__glewDeleteVertexArraysAPPLE)
+#define glGenVertexArraysAPPLE GLEW_GET_FUN(__glewGenVertexArraysAPPLE)
+#define glIsVertexArrayAPPLE GLEW_GET_FUN(__glewIsVertexArrayAPPLE)
+
+#define GLEW_APPLE_vertex_array_object GLEW_GET_VAR(__GLEW_APPLE_vertex_array_object)
+
+#endif /* GL_APPLE_vertex_array_object */
+
+/* ---------------------- GL_APPLE_vertex_array_range ---------------------- */
+
+#ifndef GL_APPLE_vertex_array_range
+#define GL_APPLE_vertex_array_range 1
+
+#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E
+#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F
+#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE 0x8520
+#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521
+#define GL_STORAGE_CLIENT_APPLE 0x85B4
+#define GL_STORAGE_CACHED_APPLE 0x85BE
+#define GL_STORAGE_SHARED_APPLE 0x85BF
+
+typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer);
+
+#define glFlushVertexArrayRangeAPPLE GLEW_GET_FUN(__glewFlushVertexArrayRangeAPPLE)
+#define glVertexArrayParameteriAPPLE GLEW_GET_FUN(__glewVertexArrayParameteriAPPLE)
+#define glVertexArrayRangeAPPLE GLEW_GET_FUN(__glewVertexArrayRangeAPPLE)
+
+#define GLEW_APPLE_vertex_array_range GLEW_GET_VAR(__GLEW_APPLE_vertex_array_range)
+
+#endif /* GL_APPLE_vertex_array_range */
+
+/* ------------------- GL_APPLE_vertex_program_evaluators ------------------ */
+
+#ifndef GL_APPLE_vertex_program_evaluators
+#define GL_APPLE_vertex_program_evaluators 1
+
+#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00
+#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01
+#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02
+#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03
+#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04
+#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05
+#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06
+#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07
+#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08
+#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09
+
+typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble* points);
+typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat* points);
+typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble* points);
+typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat* points);
+
+#define glDisableVertexAttribAPPLE GLEW_GET_FUN(__glewDisableVertexAttribAPPLE)
+#define glEnableVertexAttribAPPLE GLEW_GET_FUN(__glewEnableVertexAttribAPPLE)
+#define glIsVertexAttribEnabledAPPLE GLEW_GET_FUN(__glewIsVertexAttribEnabledAPPLE)
+#define glMapVertexAttrib1dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1dAPPLE)
+#define glMapVertexAttrib1fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib1fAPPLE)
+#define glMapVertexAttrib2dAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2dAPPLE)
+#define glMapVertexAttrib2fAPPLE GLEW_GET_FUN(__glewMapVertexAttrib2fAPPLE)
+
+#define GLEW_APPLE_vertex_program_evaluators GLEW_GET_VAR(__GLEW_APPLE_vertex_program_evaluators)
+
+#endif /* GL_APPLE_vertex_program_evaluators */
+
+/* --------------------------- GL_APPLE_ycbcr_422 -------------------------- */
+
+#ifndef GL_APPLE_ycbcr_422
+#define GL_APPLE_ycbcr_422 1
+
+#define GL_YCBCR_422_APPLE 0x85B9
+
+#define GLEW_APPLE_ycbcr_422 GLEW_GET_VAR(__GLEW_APPLE_ycbcr_422)
+
+#endif /* GL_APPLE_ycbcr_422 */
+
+/* ------------------------ GL_ARB_ES2_compatibility ----------------------- */
+
+#ifndef GL_ARB_ES2_compatibility
+#define GL_ARB_ES2_compatibility 1
+
+#define GL_FIXED 0x140C
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_RGB565 0x8D62
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_LOW_INT 0x8DF3
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_HIGH_INT 0x8DF5
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+
+typedef int GLfixed;
+
+typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFPROC) (GLclampf d);
+typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f);
+typedef void (GLAPIENTRY * PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint* range, GLint *precision);
+typedef void (GLAPIENTRY * PFNGLRELEASESHADERCOMPILERPROC) (void);
+typedef void (GLAPIENTRY * PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint* shaders, GLenum binaryformat, const GLvoid*binary, GLsizei length);
+
+#define glClearDepthf GLEW_GET_FUN(__glewClearDepthf)
+#define glDepthRangef GLEW_GET_FUN(__glewDepthRangef)
+#define glGetShaderPrecisionFormat GLEW_GET_FUN(__glewGetShaderPrecisionFormat)
+#define glReleaseShaderCompiler GLEW_GET_FUN(__glewReleaseShaderCompiler)
+#define glShaderBinary GLEW_GET_FUN(__glewShaderBinary)
+
+#define GLEW_ARB_ES2_compatibility GLEW_GET_VAR(__GLEW_ARB_ES2_compatibility)
+
+#endif /* GL_ARB_ES2_compatibility */
+
+/* ------------------------ GL_ARB_ES3_compatibility ----------------------- */
+
+#ifndef GL_ARB_ES3_compatibility
+#define GL_ARB_ES3_compatibility 1
+
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+
+#define GLEW_ARB_ES3_compatibility GLEW_GET_VAR(__GLEW_ARB_ES3_compatibility)
+
+#endif /* GL_ARB_ES3_compatibility */
+
+/* ------------------------ GL_ARB_arrays_of_arrays ------------------------ */
+
+#ifndef GL_ARB_arrays_of_arrays
+#define GL_ARB_arrays_of_arrays 1
+
+#define GLEW_ARB_arrays_of_arrays GLEW_GET_VAR(__GLEW_ARB_arrays_of_arrays)
+
+#endif /* GL_ARB_arrays_of_arrays */
+
+/* -------------------------- GL_ARB_base_instance ------------------------- */
+
+#ifndef GL_ARB_base_instance
+#define GL_ARB_base_instance 1
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLuint baseinstance);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance);
+
+#define glDrawArraysInstancedBaseInstance GLEW_GET_FUN(__glewDrawArraysInstancedBaseInstance)
+#define glDrawElementsInstancedBaseInstance GLEW_GET_FUN(__glewDrawElementsInstancedBaseInstance)
+#define glDrawElementsInstancedBaseVertexBaseInstance GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertexBaseInstance)
+
+#define GLEW_ARB_base_instance GLEW_GET_VAR(__GLEW_ARB_base_instance)
+
+#endif /* GL_ARB_base_instance */
+
+/* ------------------------ GL_ARB_bindless_texture ------------------------ */
+
+#ifndef GL_ARB_bindless_texture
+#define GL_ARB_bindless_texture 1
+
+#define GL_UNSIGNED_INT64_ARB 0x140F
+
+typedef GLuint64 (GLAPIENTRY * PFNGLGETIMAGEHANDLEARBPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);
+typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture);
+typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLUI64VARBPROC) (GLuint index, GLenum pname, GLuint64EXT* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle);
+typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLERESIDENTARBPROC) (GLuint64 handle, GLenum access);
+typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLERESIDENTARBPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC) (GLuint program, GLint location, GLuint64 value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* values);
+typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64ARBPROC) (GLint location, GLuint64 value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64VARBPROC) (GLint location, GLsizei count, const GLuint64* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64ARBPROC) (GLuint index, GLuint64EXT x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64VARBPROC) (GLuint index, const GLuint64EXT* v);
+
+#define glGetImageHandleARB GLEW_GET_FUN(__glewGetImageHandleARB)
+#define glGetTextureHandleARB GLEW_GET_FUN(__glewGetTextureHandleARB)
+#define glGetTextureSamplerHandleARB GLEW_GET_FUN(__glewGetTextureSamplerHandleARB)
+#define glGetVertexAttribLui64vARB GLEW_GET_FUN(__glewGetVertexAttribLui64vARB)
+#define glIsImageHandleResidentARB GLEW_GET_FUN(__glewIsImageHandleResidentARB)
+#define glIsTextureHandleResidentARB GLEW_GET_FUN(__glewIsTextureHandleResidentARB)
+#define glMakeImageHandleNonResidentARB GLEW_GET_FUN(__glewMakeImageHandleNonResidentARB)
+#define glMakeImageHandleResidentARB GLEW_GET_FUN(__glewMakeImageHandleResidentARB)
+#define glMakeTextureHandleNonResidentARB GLEW_GET_FUN(__glewMakeTextureHandleNonResidentARB)
+#define glMakeTextureHandleResidentARB GLEW_GET_FUN(__glewMakeTextureHandleResidentARB)
+#define glProgramUniformHandleui64ARB GLEW_GET_FUN(__glewProgramUniformHandleui64ARB)
+#define glProgramUniformHandleui64vARB GLEW_GET_FUN(__glewProgramUniformHandleui64vARB)
+#define glUniformHandleui64ARB GLEW_GET_FUN(__glewUniformHandleui64ARB)
+#define glUniformHandleui64vARB GLEW_GET_FUN(__glewUniformHandleui64vARB)
+#define glVertexAttribL1ui64ARB GLEW_GET_FUN(__glewVertexAttribL1ui64ARB)
+#define glVertexAttribL1ui64vARB GLEW_GET_FUN(__glewVertexAttribL1ui64vARB)
+
+#define GLEW_ARB_bindless_texture GLEW_GET_VAR(__GLEW_ARB_bindless_texture)
+
+#endif /* GL_ARB_bindless_texture */
+
+/* ----------------------- GL_ARB_blend_func_extended ---------------------- */
+
+#ifndef GL_ARB_blend_func_extended
+#define GL_ARB_blend_func_extended 1
+
+#define GL_SRC1_COLOR 0x88F9
+#define GL_ONE_MINUS_SRC1_COLOR 0x88FA
+#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC
+
+typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar * name);
+typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar * name);
+
+#define glBindFragDataLocationIndexed GLEW_GET_FUN(__glewBindFragDataLocationIndexed)
+#define glGetFragDataIndex GLEW_GET_FUN(__glewGetFragDataIndex)
+
+#define GLEW_ARB_blend_func_extended GLEW_GET_VAR(__GLEW_ARB_blend_func_extended)
+
+#endif /* GL_ARB_blend_func_extended */
+
+/* ------------------------- GL_ARB_buffer_storage ------------------------- */
+
+#ifndef GL_ARB_buffer_storage
+#define GL_ARB_buffer_storage 1
+
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_PERSISTENT_BIT 0x00000040
+#define GL_MAP_COHERENT_BIT 0x00000080
+#define GL_DYNAMIC_STORAGE_BIT 0x0100
+#define GL_CLIENT_STORAGE_BIT 0x0200
+#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000
+#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F
+#define GL_BUFFER_STORAGE_FLAGS 0x8220
+
+typedef void (GLAPIENTRY * PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const GLvoid* data, GLbitfield flags);
+typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEEXTPROC) (GLuint buffer, GLsizeiptr size, const GLvoid* data, GLbitfield flags);
+
+#define glBufferStorage GLEW_GET_FUN(__glewBufferStorage)
+#define glNamedBufferStorageEXT GLEW_GET_FUN(__glewNamedBufferStorageEXT)
+
+#define GLEW_ARB_buffer_storage GLEW_GET_VAR(__GLEW_ARB_buffer_storage)
+
+#endif /* GL_ARB_buffer_storage */
+
+/* ---------------------------- GL_ARB_cl_event ---------------------------- */
+
+#ifndef GL_ARB_cl_event
+#define GL_ARB_cl_event 1
+
+#define GL_SYNC_CL_EVENT_ARB 0x8240
+#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241
+
+typedef struct _cl_context *cl_context;
+typedef struct _cl_event *cl_event;
+
+typedef GLsync (GLAPIENTRY * PFNGLCREATESYNCFROMCLEVENTARBPROC) (cl_context context, cl_event event, GLbitfield flags);
+
+#define glCreateSyncFromCLeventARB GLEW_GET_FUN(__glewCreateSyncFromCLeventARB)
+
+#define GLEW_ARB_cl_event GLEW_GET_VAR(__GLEW_ARB_cl_event)
+
+#endif /* GL_ARB_cl_event */
+
+/* ----------------------- GL_ARB_clear_buffer_object ---------------------- */
+
+#ifndef GL_ARB_clear_buffer_object
+#define GL_ARB_clear_buffer_object 1
+
+typedef void (GLAPIENTRY * PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const GLvoid* data);
+typedef void (GLAPIENTRY * PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const GLvoid* data);
+typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const GLvoid* data);
+typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const GLvoid* data);
+
+#define glClearBufferData GLEW_GET_FUN(__glewClearBufferData)
+#define glClearBufferSubData GLEW_GET_FUN(__glewClearBufferSubData)
+#define glClearNamedBufferDataEXT GLEW_GET_FUN(__glewClearNamedBufferDataEXT)
+#define glClearNamedBufferSubDataEXT GLEW_GET_FUN(__glewClearNamedBufferSubDataEXT)
+
+#define GLEW_ARB_clear_buffer_object GLEW_GET_VAR(__GLEW_ARB_clear_buffer_object)
+
+#endif /* GL_ARB_clear_buffer_object */
+
+/* -------------------------- GL_ARB_clear_texture ------------------------- */
+
+#ifndef GL_ARB_clear_texture
+#define GL_ARB_clear_texture 1
+
+#define GL_CLEAR_TEXTURE 0x9365
+
+typedef void (GLAPIENTRY * PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const GLvoid* data);
+typedef void (GLAPIENTRY * PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* data);
+
+#define glClearTexImage GLEW_GET_FUN(__glewClearTexImage)
+#define glClearTexSubImage GLEW_GET_FUN(__glewClearTexSubImage)
+
+#define GLEW_ARB_clear_texture GLEW_GET_VAR(__GLEW_ARB_clear_texture)
+
+#endif /* GL_ARB_clear_texture */
+
+/* ----------------------- GL_ARB_color_buffer_float ----------------------- */
+
+#ifndef GL_ARB_color_buffer_float
+#define GL_ARB_color_buffer_float 1
+
+#define GL_RGBA_FLOAT_MODE_ARB 0x8820
+#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A
+#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B
+#define GL_CLAMP_READ_COLOR_ARB 0x891C
+#define GL_FIXED_ONLY_ARB 0x891D
+
+typedef void (GLAPIENTRY * PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp);
+
+#define glClampColorARB GLEW_GET_FUN(__glewClampColorARB)
+
+#define GLEW_ARB_color_buffer_float GLEW_GET_VAR(__GLEW_ARB_color_buffer_float)
+
+#endif /* GL_ARB_color_buffer_float */
+
+/* -------------------------- GL_ARB_compatibility ------------------------- */
+
+#ifndef GL_ARB_compatibility
+#define GL_ARB_compatibility 1
+
+#define GLEW_ARB_compatibility GLEW_GET_VAR(__GLEW_ARB_compatibility)
+
+#endif /* GL_ARB_compatibility */
+
+/* ---------------- GL_ARB_compressed_texture_pixel_storage ---------------- */
+
+#ifndef GL_ARB_compressed_texture_pixel_storage
+#define GL_ARB_compressed_texture_pixel_storage 1
+
+#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127
+#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128
+#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129
+#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A
+#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B
+#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C
+#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D
+#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E
+
+#define GLEW_ARB_compressed_texture_pixel_storage GLEW_GET_VAR(__GLEW_ARB_compressed_texture_pixel_storage)
+
+#endif /* GL_ARB_compressed_texture_pixel_storage */
+
+/* ------------------------- GL_ARB_compute_shader ------------------------- */
+
+#ifndef GL_ARB_compute_shader
+#define GL_ARB_compute_shader 1
+
+#define GL_COMPUTE_SHADER_BIT 0x00000020
+#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262
+#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263
+#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264
+#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265
+#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266
+#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267
+#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED
+#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE
+#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF
+#define GL_COMPUTE_SHADER 0x91B9
+#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB
+#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC
+#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD
+#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
+#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
+
+typedef void (GLAPIENTRY * PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
+typedef void (GLAPIENTRY * PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect);
+
+#define glDispatchCompute GLEW_GET_FUN(__glewDispatchCompute)
+#define glDispatchComputeIndirect GLEW_GET_FUN(__glewDispatchComputeIndirect)
+
+#define GLEW_ARB_compute_shader GLEW_GET_VAR(__GLEW_ARB_compute_shader)
+
+#endif /* GL_ARB_compute_shader */
+
+/* ------------------- GL_ARB_compute_variable_group_size ------------------ */
+
+#ifndef GL_ARB_compute_variable_group_size
+#define GL_ARB_compute_variable_group_size 1
+
+#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB 0x90EB
+#define GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB 0x91BF
+#define GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB 0x9344
+#define GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB 0x9345
+
+typedef void (GLAPIENTRY * PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z);
+
+#define glDispatchComputeGroupSizeARB GLEW_GET_FUN(__glewDispatchComputeGroupSizeARB)
+
+#define GLEW_ARB_compute_variable_group_size GLEW_GET_VAR(__GLEW_ARB_compute_variable_group_size)
+
+#endif /* GL_ARB_compute_variable_group_size */
+
+/* ----------------------- GL_ARB_conservative_depth ----------------------- */
+
+#ifndef GL_ARB_conservative_depth
+#define GL_ARB_conservative_depth 1
+
+#define GLEW_ARB_conservative_depth GLEW_GET_VAR(__GLEW_ARB_conservative_depth)
+
+#endif /* GL_ARB_conservative_depth */
+
+/* --------------------------- GL_ARB_copy_buffer -------------------------- */
+
+#ifndef GL_ARB_copy_buffer
+#define GL_ARB_copy_buffer 1
+
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+
+typedef void (GLAPIENTRY * PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size);
+
+#define glCopyBufferSubData GLEW_GET_FUN(__glewCopyBufferSubData)
+
+#define GLEW_ARB_copy_buffer GLEW_GET_VAR(__GLEW_ARB_copy_buffer)
+
+#endif /* GL_ARB_copy_buffer */
+
+/* --------------------------- GL_ARB_copy_image --------------------------- */
+
+#ifndef GL_ARB_copy_image
+#define GL_ARB_copy_image 1
+
+typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+
+#define glCopyImageSubData GLEW_GET_FUN(__glewCopyImageSubData)
+
+#define GLEW_ARB_copy_image GLEW_GET_VAR(__GLEW_ARB_copy_image)
+
+#endif /* GL_ARB_copy_image */
+
+/* -------------------------- GL_ARB_debug_output -------------------------- */
+
+#ifndef GL_ARB_debug_output
+#define GL_ARB_debug_output 1
+
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245
+#define GL_DEBUG_SOURCE_API_ARB 0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249
+#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A
+#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B
+#define GL_DEBUG_TYPE_ERROR_ARB 0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250
+#define GL_DEBUG_TYPE_OTHER_ARB 0x8251
+#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145
+#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147
+#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148
+
+typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, GLvoid* userParam);
+
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const GLvoid *userParam);
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled);
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf);
+typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufsize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog);
+
+#define glDebugMessageCallbackARB GLEW_GET_FUN(__glewDebugMessageCallbackARB)
+#define glDebugMessageControlARB GLEW_GET_FUN(__glewDebugMessageControlARB)
+#define glDebugMessageInsertARB GLEW_GET_FUN(__glewDebugMessageInsertARB)
+#define glGetDebugMessageLogARB GLEW_GET_FUN(__glewGetDebugMessageLogARB)
+
+#define GLEW_ARB_debug_output GLEW_GET_VAR(__GLEW_ARB_debug_output)
+
+#endif /* GL_ARB_debug_output */
+
+/* ----------------------- GL_ARB_depth_buffer_float ----------------------- */
+
+#ifndef GL_ARB_depth_buffer_float
+#define GL_ARB_depth_buffer_float 1
+
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+
+#define GLEW_ARB_depth_buffer_float GLEW_GET_VAR(__GLEW_ARB_depth_buffer_float)
+
+#endif /* GL_ARB_depth_buffer_float */
+
+/* --------------------------- GL_ARB_depth_clamp -------------------------- */
+
+#ifndef GL_ARB_depth_clamp
+#define GL_ARB_depth_clamp 1
+
+#define GL_DEPTH_CLAMP 0x864F
+
+#define GLEW_ARB_depth_clamp GLEW_GET_VAR(__GLEW_ARB_depth_clamp)
+
+#endif /* GL_ARB_depth_clamp */
+
+/* -------------------------- GL_ARB_depth_texture ------------------------- */
+
+#ifndef GL_ARB_depth_texture
+#define GL_ARB_depth_texture 1
+
+#define GL_DEPTH_COMPONENT16_ARB 0x81A5
+#define GL_DEPTH_COMPONENT24_ARB 0x81A6
+#define GL_DEPTH_COMPONENT32_ARB 0x81A7
+#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A
+#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B
+
+#define GLEW_ARB_depth_texture GLEW_GET_VAR(__GLEW_ARB_depth_texture)
+
+#endif /* GL_ARB_depth_texture */
+
+/* -------------------------- GL_ARB_draw_buffers -------------------------- */
+
+#ifndef GL_ARB_draw_buffers
+#define GL_ARB_draw_buffers 1
+
+#define GL_MAX_DRAW_BUFFERS_ARB 0x8824
+#define GL_DRAW_BUFFER0_ARB 0x8825
+#define GL_DRAW_BUFFER1_ARB 0x8826
+#define GL_DRAW_BUFFER2_ARB 0x8827
+#define GL_DRAW_BUFFER3_ARB 0x8828
+#define GL_DRAW_BUFFER4_ARB 0x8829
+#define GL_DRAW_BUFFER5_ARB 0x882A
+#define GL_DRAW_BUFFER6_ARB 0x882B
+#define GL_DRAW_BUFFER7_ARB 0x882C
+#define GL_DRAW_BUFFER8_ARB 0x882D
+#define GL_DRAW_BUFFER9_ARB 0x882E
+#define GL_DRAW_BUFFER10_ARB 0x882F
+#define GL_DRAW_BUFFER11_ARB 0x8830
+#define GL_DRAW_BUFFER12_ARB 0x8831
+#define GL_DRAW_BUFFER13_ARB 0x8832
+#define GL_DRAW_BUFFER14_ARB 0x8833
+#define GL_DRAW_BUFFER15_ARB 0x8834
+
+typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum* bufs);
+
+#define glDrawBuffersARB GLEW_GET_FUN(__glewDrawBuffersARB)
+
+#define GLEW_ARB_draw_buffers GLEW_GET_VAR(__GLEW_ARB_draw_buffers)
+
+#endif /* GL_ARB_draw_buffers */
+
+/* ----------------------- GL_ARB_draw_buffers_blend ----------------------- */
+
+#ifndef GL_ARB_draw_buffers_blend
+#define GL_ARB_draw_buffers_blend 1
+
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst);
+
+#define glBlendEquationSeparateiARB GLEW_GET_FUN(__glewBlendEquationSeparateiARB)
+#define glBlendEquationiARB GLEW_GET_FUN(__glewBlendEquationiARB)
+#define glBlendFuncSeparateiARB GLEW_GET_FUN(__glewBlendFuncSeparateiARB)
+#define glBlendFunciARB GLEW_GET_FUN(__glewBlendFunciARB)
+
+#define GLEW_ARB_draw_buffers_blend GLEW_GET_VAR(__GLEW_ARB_draw_buffers_blend)
+
+#endif /* GL_ARB_draw_buffers_blend */
+
+/* -------------------- GL_ARB_draw_elements_base_vertex ------------------- */
+
+#ifndef GL_ARB_draw_elements_base_vertex
+#define GL_ARB_draw_elements_base_vertex 1
+
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex);
+typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei* count, GLenum type, const GLvoid* const *indices, GLsizei primcount, const GLint *basevertex);
+
+#define glDrawElementsBaseVertex GLEW_GET_FUN(__glewDrawElementsBaseVertex)
+#define glDrawElementsInstancedBaseVertex GLEW_GET_FUN(__glewDrawElementsInstancedBaseVertex)
+#define glDrawRangeElementsBaseVertex GLEW_GET_FUN(__glewDrawRangeElementsBaseVertex)
+#define glMultiDrawElementsBaseVertex GLEW_GET_FUN(__glewMultiDrawElementsBaseVertex)
+
+#define GLEW_ARB_draw_elements_base_vertex GLEW_GET_VAR(__GLEW_ARB_draw_elements_base_vertex)
+
+#endif /* GL_ARB_draw_elements_base_vertex */
+
+/* -------------------------- GL_ARB_draw_indirect ------------------------- */
+
+#ifndef GL_ARB_draw_indirect
+#define GL_ARB_draw_indirect 1
+
+#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
+#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const GLvoid *indirect);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const GLvoid *indirect);
+
+#define glDrawArraysIndirect GLEW_GET_FUN(__glewDrawArraysIndirect)
+#define glDrawElementsIndirect GLEW_GET_FUN(__glewDrawElementsIndirect)
+
+#define GLEW_ARB_draw_indirect GLEW_GET_VAR(__GLEW_ARB_draw_indirect)
+
+#endif /* GL_ARB_draw_indirect */
+
+/* ------------------------- GL_ARB_draw_instanced ------------------------- */
+
+#ifndef GL_ARB_draw_instanced
+#define GL_ARB_draw_instanced 1
+
+#define GLEW_ARB_draw_instanced GLEW_GET_VAR(__GLEW_ARB_draw_instanced)
+
+#endif /* GL_ARB_draw_instanced */
+
+/* ------------------------ GL_ARB_enhanced_layouts ------------------------ */
+
+#ifndef GL_ARB_enhanced_layouts
+#define GL_ARB_enhanced_layouts 1
+
+#define GL_LOCATION_COMPONENT 0x934A
+#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B
+#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C
+
+#define GLEW_ARB_enhanced_layouts GLEW_GET_VAR(__GLEW_ARB_enhanced_layouts)
+
+#endif /* GL_ARB_enhanced_layouts */
+
+/* -------------------- GL_ARB_explicit_attrib_location -------------------- */
+
+#ifndef GL_ARB_explicit_attrib_location
+#define GL_ARB_explicit_attrib_location 1
+
+#define GLEW_ARB_explicit_attrib_location GLEW_GET_VAR(__GLEW_ARB_explicit_attrib_location)
+
+#endif /* GL_ARB_explicit_attrib_location */
+
+/* -------------------- GL_ARB_explicit_uniform_location ------------------- */
+
+#ifndef GL_ARB_explicit_uniform_location
+#define GL_ARB_explicit_uniform_location 1
+
+#define GL_MAX_UNIFORM_LOCATIONS 0x826E
+
+#define GLEW_ARB_explicit_uniform_location GLEW_GET_VAR(__GLEW_ARB_explicit_uniform_location)
+
+#endif /* GL_ARB_explicit_uniform_location */
+
+/* ------------------- GL_ARB_fragment_coord_conventions ------------------- */
+
+#ifndef GL_ARB_fragment_coord_conventions
+#define GL_ARB_fragment_coord_conventions 1
+
+#define GLEW_ARB_fragment_coord_conventions GLEW_GET_VAR(__GLEW_ARB_fragment_coord_conventions)
+
+#endif /* GL_ARB_fragment_coord_conventions */
+
+/* --------------------- GL_ARB_fragment_layer_viewport -------------------- */
+
+#ifndef GL_ARB_fragment_layer_viewport
+#define GL_ARB_fragment_layer_viewport 1
+
+#define GLEW_ARB_fragment_layer_viewport GLEW_GET_VAR(__GLEW_ARB_fragment_layer_viewport)
+
+#endif /* GL_ARB_fragment_layer_viewport */
+
+/* ------------------------ GL_ARB_fragment_program ------------------------ */
+
+#ifndef GL_ARB_fragment_program
+#define GL_ARB_fragment_program 1
+
+#define GL_FRAGMENT_PROGRAM_ARB 0x8804
+#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805
+#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806
+#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807
+#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808
+#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809
+#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A
+#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B
+#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C
+#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D
+#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E
+#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F
+#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810
+#define GL_MAX_TEXTURE_COORDS_ARB 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
+
+#define GLEW_ARB_fragment_program GLEW_GET_VAR(__GLEW_ARB_fragment_program)
+
+#endif /* GL_ARB_fragment_program */
+
+/* --------------------- GL_ARB_fragment_program_shadow -------------------- */
+
+#ifndef GL_ARB_fragment_program_shadow
+#define GL_ARB_fragment_program_shadow 1
+
+#define GLEW_ARB_fragment_program_shadow GLEW_GET_VAR(__GLEW_ARB_fragment_program_shadow)
+
+#endif /* GL_ARB_fragment_program_shadow */
+
+/* ------------------------- GL_ARB_fragment_shader ------------------------ */
+
+#ifndef GL_ARB_fragment_shader
+#define GL_ARB_fragment_shader 1
+
+#define GL_FRAGMENT_SHADER_ARB 0x8B30
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B
+
+#define GLEW_ARB_fragment_shader GLEW_GET_VAR(__GLEW_ARB_fragment_shader)
+
+#endif /* GL_ARB_fragment_shader */
+
+/* ------------------- GL_ARB_framebuffer_no_attachments ------------------- */
+
+#ifndef GL_ARB_framebuffer_no_attachments
+#define GL_ARB_framebuffer_no_attachments 1
+
+#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310
+#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312
+#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313
+#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314
+#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315
+#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316
+#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317
+#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param);
+
+#define glFramebufferParameteri GLEW_GET_FUN(__glewFramebufferParameteri)
+#define glGetFramebufferParameteriv GLEW_GET_FUN(__glewGetFramebufferParameteriv)
+#define glGetNamedFramebufferParameterivEXT GLEW_GET_FUN(__glewGetNamedFramebufferParameterivEXT)
+#define glNamedFramebufferParameteriEXT GLEW_GET_FUN(__glewNamedFramebufferParameteriEXT)
+
+#define GLEW_ARB_framebuffer_no_attachments GLEW_GET_VAR(__GLEW_ARB_framebuffer_no_attachments)
+
+#endif /* GL_ARB_framebuffer_no_attachments */
+
+/* ----------------------- GL_ARB_framebuffer_object ----------------------- */
+
+#ifndef GL_ARB_framebuffer_object
+#define GL_ARB_framebuffer_object 1
+
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_INDEX 0x8222
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_TEXTURE_STENCIL_SIZE 0x88F1
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_SRGB 0x8C40
+#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_STENCIL_INDEX1 0x8D46
+#define GL_STENCIL_INDEX4 0x8D47
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_STENCIL_INDEX16 0x8D49
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_MAX_SAMPLES 0x8D57
+
+typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
+typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint* framebuffers);
+typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint* renderbuffers);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer);
+typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers);
+typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers);
+typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);
+typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+
+#define glBindFramebuffer GLEW_GET_FUN(__glewBindFramebuffer)
+#define glBindRenderbuffer GLEW_GET_FUN(__glewBindRenderbuffer)
+#define glBlitFramebuffer GLEW_GET_FUN(__glewBlitFramebuffer)
+#define glCheckFramebufferStatus GLEW_GET_FUN(__glewCheckFramebufferStatus)
+#define glDeleteFramebuffers GLEW_GET_FUN(__glewDeleteFramebuffers)
+#define glDeleteRenderbuffers GLEW_GET_FUN(__glewDeleteRenderbuffers)
+#define glFramebufferRenderbuffer GLEW_GET_FUN(__glewFramebufferRenderbuffer)
+#define glFramebufferTexture1D GLEW_GET_FUN(__glewFramebufferTexture1D)
+#define glFramebufferTexture2D GLEW_GET_FUN(__glewFramebufferTexture2D)
+#define glFramebufferTexture3D GLEW_GET_FUN(__glewFramebufferTexture3D)
+#define glFramebufferTextureLayer GLEW_GET_FUN(__glewFramebufferTextureLayer)
+#define glGenFramebuffers GLEW_GET_FUN(__glewGenFramebuffers)
+#define glGenRenderbuffers GLEW_GET_FUN(__glewGenRenderbuffers)
+#define glGenerateMipmap GLEW_GET_FUN(__glewGenerateMipmap)
+#define glGetFramebufferAttachmentParameteriv GLEW_GET_FUN(__glewGetFramebufferAttachmentParameteriv)
+#define glGetRenderbufferParameteriv GLEW_GET_FUN(__glewGetRenderbufferParameteriv)
+#define glIsFramebuffer GLEW_GET_FUN(__glewIsFramebuffer)
+#define glIsRenderbuffer GLEW_GET_FUN(__glewIsRenderbuffer)
+#define glRenderbufferStorage GLEW_GET_FUN(__glewRenderbufferStorage)
+#define glRenderbufferStorageMultisample GLEW_GET_FUN(__glewRenderbufferStorageMultisample)
+
+#define GLEW_ARB_framebuffer_object GLEW_GET_VAR(__GLEW_ARB_framebuffer_object)
+
+#endif /* GL_ARB_framebuffer_object */
+
+/* ------------------------ GL_ARB_framebuffer_sRGB ------------------------ */
+
+#ifndef GL_ARB_framebuffer_sRGB
+#define GL_ARB_framebuffer_sRGB 1
+
+#define GL_FRAMEBUFFER_SRGB 0x8DB9
+
+#define GLEW_ARB_framebuffer_sRGB GLEW_GET_VAR(__GLEW_ARB_framebuffer_sRGB)
+
+#endif /* GL_ARB_framebuffer_sRGB */
+
+/* ------------------------ GL_ARB_geometry_shader4 ------------------------ */
+
+#ifndef GL_ARB_geometry_shader4
+#define GL_ARB_geometry_shader4 1
+
+#define GL_LINES_ADJACENCY_ARB 0xA
+#define GL_LINE_STRIP_ADJACENCY_ARB 0xB
+#define GL_TRIANGLES_ADJACENCY_ARB 0xC
+#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0xD
+#define GL_PROGRAM_POINT_SIZE_ARB 0x8642
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9
+#define GL_GEOMETRY_SHADER_ARB 0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA
+#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB
+#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value);
+
+#define glFramebufferTextureARB GLEW_GET_FUN(__glewFramebufferTextureARB)
+#define glFramebufferTextureFaceARB GLEW_GET_FUN(__glewFramebufferTextureFaceARB)
+#define glFramebufferTextureLayerARB GLEW_GET_FUN(__glewFramebufferTextureLayerARB)
+#define glProgramParameteriARB GLEW_GET_FUN(__glewProgramParameteriARB)
+
+#define GLEW_ARB_geometry_shader4 GLEW_GET_VAR(__GLEW_ARB_geometry_shader4)
+
+#endif /* GL_ARB_geometry_shader4 */
+
+/* ----------------------- GL_ARB_get_program_binary ----------------------- */
+
+#ifndef GL_ARB_get_program_binary
+#define GL_ARB_get_program_binary 1
+
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum *binaryFormat, GLvoid*binary);
+typedef void (GLAPIENTRY * PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value);
+
+#define glGetProgramBinary GLEW_GET_FUN(__glewGetProgramBinary)
+#define glProgramBinary GLEW_GET_FUN(__glewProgramBinary)
+#define glProgramParameteri GLEW_GET_FUN(__glewProgramParameteri)
+
+#define GLEW_ARB_get_program_binary GLEW_GET_VAR(__GLEW_ARB_get_program_binary)
+
+#endif /* GL_ARB_get_program_binary */
+
+/* --------------------------- GL_ARB_gpu_shader5 -------------------------- */
+
+#ifndef GL_ARB_gpu_shader5
+#define GL_ARB_gpu_shader5 1
+
+#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D
+#define GL_MAX_VERTEX_STREAMS 0x8E71
+
+#define GLEW_ARB_gpu_shader5 GLEW_GET_VAR(__GLEW_ARB_gpu_shader5)
+
+#endif /* GL_ARB_gpu_shader5 */
+
+/* ------------------------- GL_ARB_gpu_shader_fp64 ------------------------ */
+
+#ifndef GL_ARB_gpu_shader_fp64
+#define GL_ARB_gpu_shader_fp64 1
+
+#define GL_DOUBLE_MAT2 0x8F46
+#define GL_DOUBLE_MAT3 0x8F47
+#define GL_DOUBLE_MAT4 0x8F48
+#define GL_DOUBLE_MAT2x3 0x8F49
+#define GL_DOUBLE_MAT2x4 0x8F4A
+#define GL_DOUBLE_MAT3x2 0x8F4B
+#define GL_DOUBLE_MAT3x4 0x8F4C
+#define GL_DOUBLE_MAT4x2 0x8F4D
+#define GL_DOUBLE_MAT4x3 0x8F4E
+#define GL_DOUBLE_VEC2 0x8FFC
+#define GL_DOUBLE_VEC3 0x8FFD
+#define GL_DOUBLE_VEC4 0x8FFE
+
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1DPROC) (GLint location, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+
+#define glGetUniformdv GLEW_GET_FUN(__glewGetUniformdv)
+#define glUniform1d GLEW_GET_FUN(__glewUniform1d)
+#define glUniform1dv GLEW_GET_FUN(__glewUniform1dv)
+#define glUniform2d GLEW_GET_FUN(__glewUniform2d)
+#define glUniform2dv GLEW_GET_FUN(__glewUniform2dv)
+#define glUniform3d GLEW_GET_FUN(__glewUniform3d)
+#define glUniform3dv GLEW_GET_FUN(__glewUniform3dv)
+#define glUniform4d GLEW_GET_FUN(__glewUniform4d)
+#define glUniform4dv GLEW_GET_FUN(__glewUniform4dv)
+#define glUniformMatrix2dv GLEW_GET_FUN(__glewUniformMatrix2dv)
+#define glUniformMatrix2x3dv GLEW_GET_FUN(__glewUniformMatrix2x3dv)
+#define glUniformMatrix2x4dv GLEW_GET_FUN(__glewUniformMatrix2x4dv)
+#define glUniformMatrix3dv GLEW_GET_FUN(__glewUniformMatrix3dv)
+#define glUniformMatrix3x2dv GLEW_GET_FUN(__glewUniformMatrix3x2dv)
+#define glUniformMatrix3x4dv GLEW_GET_FUN(__glewUniformMatrix3x4dv)
+#define glUniformMatrix4dv GLEW_GET_FUN(__glewUniformMatrix4dv)
+#define glUniformMatrix4x2dv GLEW_GET_FUN(__glewUniformMatrix4x2dv)
+#define glUniformMatrix4x3dv GLEW_GET_FUN(__glewUniformMatrix4x3dv)
+
+#define GLEW_ARB_gpu_shader_fp64 GLEW_GET_VAR(__GLEW_ARB_gpu_shader_fp64)
+
+#endif /* GL_ARB_gpu_shader_fp64 */
+
+/* ------------------------ GL_ARB_half_float_pixel ------------------------ */
+
+#ifndef GL_ARB_half_float_pixel
+#define GL_ARB_half_float_pixel 1
+
+#define GL_HALF_FLOAT_ARB 0x140B
+
+#define GLEW_ARB_half_float_pixel GLEW_GET_VAR(__GLEW_ARB_half_float_pixel)
+
+#endif /* GL_ARB_half_float_pixel */
+
+/* ------------------------ GL_ARB_half_float_vertex ----------------------- */
+
+#ifndef GL_ARB_half_float_vertex
+#define GL_ARB_half_float_vertex 1
+
+#define GL_HALF_FLOAT 0x140B
+
+#define GLEW_ARB_half_float_vertex GLEW_GET_VAR(__GLEW_ARB_half_float_vertex)
+
+#endif /* GL_ARB_half_float_vertex */
+
+/* ----------------------------- GL_ARB_imaging ---------------------------- */
+
+#ifndef GL_ARB_imaging
+#define GL_ARB_imaging 1
+
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+#define GL_FUNC_ADD 0x8006
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_BLEND_EQUATION 0x8009
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_CONVOLUTION_1D 0x8010
+#define GL_CONVOLUTION_2D 0x8011
+#define GL_SEPARABLE_2D 0x8012
+#define GL_CONVOLUTION_BORDER_MODE 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS 0x8015
+#define GL_REDUCE 0x8016
+#define GL_CONVOLUTION_FORMAT 0x8017
+#define GL_CONVOLUTION_WIDTH 0x8018
+#define GL_CONVOLUTION_HEIGHT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023
+#define GL_HISTOGRAM 0x8024
+#define GL_PROXY_HISTOGRAM 0x8025
+#define GL_HISTOGRAM_WIDTH 0x8026
+#define GL_HISTOGRAM_FORMAT 0x8027
+#define GL_HISTOGRAM_RED_SIZE 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C
+#define GL_HISTOGRAM_SINK 0x802D
+#define GL_MINMAX 0x802E
+#define GL_MINMAX_FORMAT 0x802F
+#define GL_MINMAX_SINK 0x8030
+#define GL_TABLE_TOO_LARGE 0x8031
+#define GL_COLOR_MATRIX 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB
+#define GL_COLOR_TABLE 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2
+#define GL_PROXY_COLOR_TABLE 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5
+#define GL_COLOR_TABLE_SCALE 0x80D6
+#define GL_COLOR_TABLE_BIAS 0x80D7
+#define GL_COLOR_TABLE_FORMAT 0x80D8
+#define GL_COLOR_TABLE_WIDTH 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF
+#define GL_IGNORE_BORDER 0x8150
+#define GL_CONSTANT_BORDER 0x8151
+#define GL_WRAP_BORDER 0x8152
+#define GL_REPLICATE_BORDER 0x8153
+#define GL_CONVOLUTION_BORDER_COLOR 0x8154
+
+typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum types, GLvoid *values);
+typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (GLAPIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (GLAPIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLRESETMINMAXPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+
+#define glColorSubTable GLEW_GET_FUN(__glewColorSubTable)
+#define glColorTable GLEW_GET_FUN(__glewColorTable)
+#define glColorTableParameterfv GLEW_GET_FUN(__glewColorTableParameterfv)
+#define glColorTableParameteriv GLEW_GET_FUN(__glewColorTableParameteriv)
+#define glConvolutionFilter1D GLEW_GET_FUN(__glewConvolutionFilter1D)
+#define glConvolutionFilter2D GLEW_GET_FUN(__glewConvolutionFilter2D)
+#define glConvolutionParameterf GLEW_GET_FUN(__glewConvolutionParameterf)
+#define glConvolutionParameterfv GLEW_GET_FUN(__glewConvolutionParameterfv)
+#define glConvolutionParameteri GLEW_GET_FUN(__glewConvolutionParameteri)
+#define glConvolutionParameteriv GLEW_GET_FUN(__glewConvolutionParameteriv)
+#define glCopyColorSubTable GLEW_GET_FUN(__glewCopyColorSubTable)
+#define glCopyColorTable GLEW_GET_FUN(__glewCopyColorTable)
+#define glCopyConvolutionFilter1D GLEW_GET_FUN(__glewCopyConvolutionFilter1D)
+#define glCopyConvolutionFilter2D GLEW_GET_FUN(__glewCopyConvolutionFilter2D)
+#define glGetColorTable GLEW_GET_FUN(__glewGetColorTable)
+#define glGetColorTableParameterfv GLEW_GET_FUN(__glewGetColorTableParameterfv)
+#define glGetColorTableParameteriv GLEW_GET_FUN(__glewGetColorTableParameteriv)
+#define glGetConvolutionFilter GLEW_GET_FUN(__glewGetConvolutionFilter)
+#define glGetConvolutionParameterfv GLEW_GET_FUN(__glewGetConvolutionParameterfv)
+#define glGetConvolutionParameteriv GLEW_GET_FUN(__glewGetConvolutionParameteriv)
+#define glGetHistogram GLEW_GET_FUN(__glewGetHistogram)
+#define glGetHistogramParameterfv GLEW_GET_FUN(__glewGetHistogramParameterfv)
+#define glGetHistogramParameteriv GLEW_GET_FUN(__glewGetHistogramParameteriv)
+#define glGetMinmax GLEW_GET_FUN(__glewGetMinmax)
+#define glGetMinmaxParameterfv GLEW_GET_FUN(__glewGetMinmaxParameterfv)
+#define glGetMinmaxParameteriv GLEW_GET_FUN(__glewGetMinmaxParameteriv)
+#define glGetSeparableFilter GLEW_GET_FUN(__glewGetSeparableFilter)
+#define glHistogram GLEW_GET_FUN(__glewHistogram)
+#define glMinmax GLEW_GET_FUN(__glewMinmax)
+#define glResetHistogram GLEW_GET_FUN(__glewResetHistogram)
+#define glResetMinmax GLEW_GET_FUN(__glewResetMinmax)
+#define glSeparableFilter2D GLEW_GET_FUN(__glewSeparableFilter2D)
+
+#define GLEW_ARB_imaging GLEW_GET_VAR(__GLEW_ARB_imaging)
+
+#endif /* GL_ARB_imaging */
+
+/* ----------------------- GL_ARB_indirect_parameters ---------------------- */
+
+#ifndef GL_ARB_indirect_parameters
+#define GL_ARB_indirect_parameters 1
+
+#define GL_PARAMETER_BUFFER_ARB 0x80EE
+#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF
+
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, const GLvoid *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, const GLvoid *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+
+#define glMultiDrawArraysIndirectCountARB GLEW_GET_FUN(__glewMultiDrawArraysIndirectCountARB)
+#define glMultiDrawElementsIndirectCountARB GLEW_GET_FUN(__glewMultiDrawElementsIndirectCountARB)
+
+#define GLEW_ARB_indirect_parameters GLEW_GET_VAR(__GLEW_ARB_indirect_parameters)
+
+#endif /* GL_ARB_indirect_parameters */
+
+/* ------------------------ GL_ARB_instanced_arrays ------------------------ */
+
+#ifndef GL_ARB_instanced_arrays
+#define GL_ARB_instanced_arrays 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor);
+
+#define glDrawArraysInstancedARB GLEW_GET_FUN(__glewDrawArraysInstancedARB)
+#define glDrawElementsInstancedARB GLEW_GET_FUN(__glewDrawElementsInstancedARB)
+#define glVertexAttribDivisorARB GLEW_GET_FUN(__glewVertexAttribDivisorARB)
+
+#define GLEW_ARB_instanced_arrays GLEW_GET_VAR(__GLEW_ARB_instanced_arrays)
+
+#endif /* GL_ARB_instanced_arrays */
+
+/* ---------------------- GL_ARB_internalformat_query ---------------------- */
+
+#ifndef GL_ARB_internalformat_query
+#define GL_ARB_internalformat_query 1
+
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+
+typedef void (GLAPIENTRY * PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
+
+#define glGetInternalformativ GLEW_GET_FUN(__glewGetInternalformativ)
+
+#define GLEW_ARB_internalformat_query GLEW_GET_VAR(__GLEW_ARB_internalformat_query)
+
+#endif /* GL_ARB_internalformat_query */
+
+/* ---------------------- GL_ARB_internalformat_query2 --------------------- */
+
+#ifndef GL_ARB_internalformat_query2
+#define GL_ARB_internalformat_query2 1
+
+#define GL_INTERNALFORMAT_SUPPORTED 0x826F
+#define GL_INTERNALFORMAT_PREFERRED 0x8270
+#define GL_INTERNALFORMAT_RED_SIZE 0x8271
+#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272
+#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273
+#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274
+#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275
+#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276
+#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277
+#define GL_INTERNALFORMAT_RED_TYPE 0x8278
+#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279
+#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A
+#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B
+#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C
+#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D
+#define GL_MAX_WIDTH 0x827E
+#define GL_MAX_HEIGHT 0x827F
+#define GL_MAX_DEPTH 0x8280
+#define GL_MAX_LAYERS 0x8281
+#define GL_MAX_COMBINED_DIMENSIONS 0x8282
+#define GL_COLOR_COMPONENTS 0x8283
+#define GL_DEPTH_COMPONENTS 0x8284
+#define GL_STENCIL_COMPONENTS 0x8285
+#define GL_COLOR_RENDERABLE 0x8286
+#define GL_DEPTH_RENDERABLE 0x8287
+#define GL_STENCIL_RENDERABLE 0x8288
+#define GL_FRAMEBUFFER_RENDERABLE 0x8289
+#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A
+#define GL_FRAMEBUFFER_BLEND 0x828B
+#define GL_READ_PIXELS 0x828C
+#define GL_READ_PIXELS_FORMAT 0x828D
+#define GL_READ_PIXELS_TYPE 0x828E
+#define GL_TEXTURE_IMAGE_FORMAT 0x828F
+#define GL_TEXTURE_IMAGE_TYPE 0x8290
+#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291
+#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292
+#define GL_MIPMAP 0x8293
+#define GL_MANUAL_GENERATE_MIPMAP 0x8294
+#define GL_AUTO_GENERATE_MIPMAP 0x8295
+#define GL_COLOR_ENCODING 0x8296
+#define GL_SRGB_READ 0x8297
+#define GL_SRGB_WRITE 0x8298
+#define GL_SRGB_DECODE_ARB 0x8299
+#define GL_FILTER 0x829A
+#define GL_VERTEX_TEXTURE 0x829B
+#define GL_TESS_CONTROL_TEXTURE 0x829C
+#define GL_TESS_EVALUATION_TEXTURE 0x829D
+#define GL_GEOMETRY_TEXTURE 0x829E
+#define GL_FRAGMENT_TEXTURE 0x829F
+#define GL_COMPUTE_TEXTURE 0x82A0
+#define GL_TEXTURE_SHADOW 0x82A1
+#define GL_TEXTURE_GATHER 0x82A2
+#define GL_TEXTURE_GATHER_SHADOW 0x82A3
+#define GL_SHADER_IMAGE_LOAD 0x82A4
+#define GL_SHADER_IMAGE_STORE 0x82A5
+#define GL_SHADER_IMAGE_ATOMIC 0x82A6
+#define GL_IMAGE_TEXEL_SIZE 0x82A7
+#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8
+#define GL_IMAGE_PIXEL_FORMAT 0x82A9
+#define GL_IMAGE_PIXEL_TYPE 0x82AA
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF
+#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1
+#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2
+#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3
+#define GL_CLEAR_BUFFER 0x82B4
+#define GL_TEXTURE_VIEW 0x82B5
+#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6
+#define GL_FULL_SUPPORT 0x82B7
+#define GL_CAVEAT_SUPPORT 0x82B8
+#define GL_IMAGE_CLASS_4_X_32 0x82B9
+#define GL_IMAGE_CLASS_2_X_32 0x82BA
+#define GL_IMAGE_CLASS_1_X_32 0x82BB
+#define GL_IMAGE_CLASS_4_X_16 0x82BC
+#define GL_IMAGE_CLASS_2_X_16 0x82BD
+#define GL_IMAGE_CLASS_1_X_16 0x82BE
+#define GL_IMAGE_CLASS_4_X_8 0x82BF
+#define GL_IMAGE_CLASS_2_X_8 0x82C0
+#define GL_IMAGE_CLASS_1_X_8 0x82C1
+#define GL_IMAGE_CLASS_11_11_10 0x82C2
+#define GL_IMAGE_CLASS_10_10_10_2 0x82C3
+#define GL_VIEW_CLASS_128_BITS 0x82C4
+#define GL_VIEW_CLASS_96_BITS 0x82C5
+#define GL_VIEW_CLASS_64_BITS 0x82C6
+#define GL_VIEW_CLASS_48_BITS 0x82C7
+#define GL_VIEW_CLASS_32_BITS 0x82C8
+#define GL_VIEW_CLASS_24_BITS 0x82C9
+#define GL_VIEW_CLASS_16_BITS 0x82CA
+#define GL_VIEW_CLASS_8_BITS 0x82CB
+#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC
+#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD
+#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE
+#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF
+#define GL_VIEW_CLASS_RGTC1_RED 0x82D0
+#define GL_VIEW_CLASS_RGTC2_RG 0x82D1
+#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2
+#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3
+
+typedef void (GLAPIENTRY * PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64* params);
+
+#define glGetInternalformati64v GLEW_GET_FUN(__glewGetInternalformati64v)
+
+#define GLEW_ARB_internalformat_query2 GLEW_GET_VAR(__GLEW_ARB_internalformat_query2)
+
+#endif /* GL_ARB_internalformat_query2 */
+
+/* ----------------------- GL_ARB_invalidate_subdata ----------------------- */
+
+#ifndef GL_ARB_invalidate_subdata
+#define GL_ARB_invalidate_subdata 1
+
+typedef void (GLAPIENTRY * PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);
+typedef void (GLAPIENTRY * PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum* attachments);
+typedef void (GLAPIENTRY * PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
+
+#define glInvalidateBufferData GLEW_GET_FUN(__glewInvalidateBufferData)
+#define glInvalidateBufferSubData GLEW_GET_FUN(__glewInvalidateBufferSubData)
+#define glInvalidateFramebuffer GLEW_GET_FUN(__glewInvalidateFramebuffer)
+#define glInvalidateSubFramebuffer GLEW_GET_FUN(__glewInvalidateSubFramebuffer)
+#define glInvalidateTexImage GLEW_GET_FUN(__glewInvalidateTexImage)
+#define glInvalidateTexSubImage GLEW_GET_FUN(__glewInvalidateTexSubImage)
+
+#define GLEW_ARB_invalidate_subdata GLEW_GET_VAR(__GLEW_ARB_invalidate_subdata)
+
+#endif /* GL_ARB_invalidate_subdata */
+
+/* ---------------------- GL_ARB_map_buffer_alignment ---------------------- */
+
+#ifndef GL_ARB_map_buffer_alignment
+#define GL_ARB_map_buffer_alignment 1
+
+#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC
+
+#define GLEW_ARB_map_buffer_alignment GLEW_GET_VAR(__GLEW_ARB_map_buffer_alignment)
+
+#endif /* GL_ARB_map_buffer_alignment */
+
+/* ------------------------ GL_ARB_map_buffer_range ------------------------ */
+
+#ifndef GL_ARB_map_buffer_range
+#define GL_ARB_map_buffer_range 1
+
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+
+typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+typedef GLvoid * (GLAPIENTRY * PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+
+#define glFlushMappedBufferRange GLEW_GET_FUN(__glewFlushMappedBufferRange)
+#define glMapBufferRange GLEW_GET_FUN(__glewMapBufferRange)
+
+#define GLEW_ARB_map_buffer_range GLEW_GET_VAR(__GLEW_ARB_map_buffer_range)
+
+#endif /* GL_ARB_map_buffer_range */
+
+/* ------------------------- GL_ARB_matrix_palette ------------------------- */
+
+#ifndef GL_ARB_matrix_palette
+#define GL_ARB_matrix_palette 1
+
+#define GL_MATRIX_PALETTE_ARB 0x8840
+#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841
+#define GL_MAX_PALETTE_MATRICES_ARB 0x8842
+#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843
+#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844
+#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845
+#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846
+#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847
+#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848
+#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849
+
+typedef void (GLAPIENTRY * PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index);
+typedef void (GLAPIENTRY * PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUBVARBPROC) (GLint size, GLubyte *indices);
+typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUIVARBPROC) (GLint size, GLuint *indices);
+typedef void (GLAPIENTRY * PFNGLMATRIXINDEXUSVARBPROC) (GLint size, GLushort *indices);
+
+#define glCurrentPaletteMatrixARB GLEW_GET_FUN(__glewCurrentPaletteMatrixARB)
+#define glMatrixIndexPointerARB GLEW_GET_FUN(__glewMatrixIndexPointerARB)
+#define glMatrixIndexubvARB GLEW_GET_FUN(__glewMatrixIndexubvARB)
+#define glMatrixIndexuivARB GLEW_GET_FUN(__glewMatrixIndexuivARB)
+#define glMatrixIndexusvARB GLEW_GET_FUN(__glewMatrixIndexusvARB)
+
+#define GLEW_ARB_matrix_palette GLEW_GET_VAR(__GLEW_ARB_matrix_palette)
+
+#endif /* GL_ARB_matrix_palette */
+
+/* --------------------------- GL_ARB_multi_bind --------------------------- */
+
+#ifndef GL_ARB_multi_bind
+#define GL_ARB_multi_bind 1
+
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERSBASEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint* buffers);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERSRANGEPROC) (GLenum target, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizeiptr *sizes);
+typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint* textures);
+typedef void (GLAPIENTRY * PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint* samplers);
+typedef void (GLAPIENTRY * PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint* textures);
+typedef void (GLAPIENTRY * PFNGLBINDVERTEXBUFFERSPROC) (GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizei *strides);
+
+#define glBindBuffersBase GLEW_GET_FUN(__glewBindBuffersBase)
+#define glBindBuffersRange GLEW_GET_FUN(__glewBindBuffersRange)
+#define glBindImageTextures GLEW_GET_FUN(__glewBindImageTextures)
+#define glBindSamplers GLEW_GET_FUN(__glewBindSamplers)
+#define glBindTextures GLEW_GET_FUN(__glewBindTextures)
+#define glBindVertexBuffers GLEW_GET_FUN(__glewBindVertexBuffers)
+
+#define GLEW_ARB_multi_bind GLEW_GET_VAR(__GLEW_ARB_multi_bind)
+
+#endif /* GL_ARB_multi_bind */
+
+/* ----------------------- GL_ARB_multi_draw_indirect ---------------------- */
+
+#ifndef GL_ARB_multi_draw_indirect
+#define GL_ARB_multi_draw_indirect 1
+
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const GLvoid *indirect, GLsizei primcount, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const GLvoid *indirect, GLsizei primcount, GLsizei stride);
+
+#define glMultiDrawArraysIndirect GLEW_GET_FUN(__glewMultiDrawArraysIndirect)
+#define glMultiDrawElementsIndirect GLEW_GET_FUN(__glewMultiDrawElementsIndirect)
+
+#define GLEW_ARB_multi_draw_indirect GLEW_GET_VAR(__GLEW_ARB_multi_draw_indirect)
+
+#endif /* GL_ARB_multi_draw_indirect */
+
+/* --------------------------- GL_ARB_multisample -------------------------- */
+
+#ifndef GL_ARB_multisample
+#define GL_ARB_multisample 1
+
+#define GL_MULTISAMPLE_ARB 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F
+#define GL_SAMPLE_COVERAGE_ARB 0x80A0
+#define GL_SAMPLE_BUFFERS_ARB 0x80A8
+#define GL_SAMPLES_ARB 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB
+#define GL_MULTISAMPLE_BIT_ARB 0x20000000
+
+typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert);
+
+#define glSampleCoverageARB GLEW_GET_FUN(__glewSampleCoverageARB)
+
+#define GLEW_ARB_multisample GLEW_GET_VAR(__GLEW_ARB_multisample)
+
+#endif /* GL_ARB_multisample */
+
+/* -------------------------- GL_ARB_multitexture -------------------------- */
+
+#ifndef GL_ARB_multitexture
+#define GL_ARB_multitexture 1
+
+#define GL_TEXTURE0_ARB 0x84C0
+#define GL_TEXTURE1_ARB 0x84C1
+#define GL_TEXTURE2_ARB 0x84C2
+#define GL_TEXTURE3_ARB 0x84C3
+#define GL_TEXTURE4_ARB 0x84C4
+#define GL_TEXTURE5_ARB 0x84C5
+#define GL_TEXTURE6_ARB 0x84C6
+#define GL_TEXTURE7_ARB 0x84C7
+#define GL_TEXTURE8_ARB 0x84C8
+#define GL_TEXTURE9_ARB 0x84C9
+#define GL_TEXTURE10_ARB 0x84CA
+#define GL_TEXTURE11_ARB 0x84CB
+#define GL_TEXTURE12_ARB 0x84CC
+#define GL_TEXTURE13_ARB 0x84CD
+#define GL_TEXTURE14_ARB 0x84CE
+#define GL_TEXTURE15_ARB 0x84CF
+#define GL_TEXTURE16_ARB 0x84D0
+#define GL_TEXTURE17_ARB 0x84D1
+#define GL_TEXTURE18_ARB 0x84D2
+#define GL_TEXTURE19_ARB 0x84D3
+#define GL_TEXTURE20_ARB 0x84D4
+#define GL_TEXTURE21_ARB 0x84D5
+#define GL_TEXTURE22_ARB 0x84D6
+#define GL_TEXTURE23_ARB 0x84D7
+#define GL_TEXTURE24_ARB 0x84D8
+#define GL_TEXTURE25_ARB 0x84D9
+#define GL_TEXTURE26_ARB 0x84DA
+#define GL_TEXTURE27_ARB 0x84DB
+#define GL_TEXTURE28_ARB 0x84DC
+#define GL_TEXTURE29_ARB 0x84DD
+#define GL_TEXTURE30_ARB 0x84DE
+#define GL_TEXTURE31_ARB 0x84DF
+#define GL_ACTIVE_TEXTURE_ARB 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
+#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
+
+typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v);
+
+#define glActiveTextureARB GLEW_GET_FUN(__glewActiveTextureARB)
+#define glClientActiveTextureARB GLEW_GET_FUN(__glewClientActiveTextureARB)
+#define glMultiTexCoord1dARB GLEW_GET_FUN(__glewMultiTexCoord1dARB)
+#define glMultiTexCoord1dvARB GLEW_GET_FUN(__glewMultiTexCoord1dvARB)
+#define glMultiTexCoord1fARB GLEW_GET_FUN(__glewMultiTexCoord1fARB)
+#define glMultiTexCoord1fvARB GLEW_GET_FUN(__glewMultiTexCoord1fvARB)
+#define glMultiTexCoord1iARB GLEW_GET_FUN(__glewMultiTexCoord1iARB)
+#define glMultiTexCoord1ivARB GLEW_GET_FUN(__glewMultiTexCoord1ivARB)
+#define glMultiTexCoord1sARB GLEW_GET_FUN(__glewMultiTexCoord1sARB)
+#define glMultiTexCoord1svARB GLEW_GET_FUN(__glewMultiTexCoord1svARB)
+#define glMultiTexCoord2dARB GLEW_GET_FUN(__glewMultiTexCoord2dARB)
+#define glMultiTexCoord2dvARB GLEW_GET_FUN(__glewMultiTexCoord2dvARB)
+#define glMultiTexCoord2fARB GLEW_GET_FUN(__glewMultiTexCoord2fARB)
+#define glMultiTexCoord2fvARB GLEW_GET_FUN(__glewMultiTexCoord2fvARB)
+#define glMultiTexCoord2iARB GLEW_GET_FUN(__glewMultiTexCoord2iARB)
+#define glMultiTexCoord2ivARB GLEW_GET_FUN(__glewMultiTexCoord2ivARB)
+#define glMultiTexCoord2sARB GLEW_GET_FUN(__glewMultiTexCoord2sARB)
+#define glMultiTexCoord2svARB GLEW_GET_FUN(__glewMultiTexCoord2svARB)
+#define glMultiTexCoord3dARB GLEW_GET_FUN(__glewMultiTexCoord3dARB)
+#define glMultiTexCoord3dvARB GLEW_GET_FUN(__glewMultiTexCoord3dvARB)
+#define glMultiTexCoord3fARB GLEW_GET_FUN(__glewMultiTexCoord3fARB)
+#define glMultiTexCoord3fvARB GLEW_GET_FUN(__glewMultiTexCoord3fvARB)
+#define glMultiTexCoord3iARB GLEW_GET_FUN(__glewMultiTexCoord3iARB)
+#define glMultiTexCoord3ivARB GLEW_GET_FUN(__glewMultiTexCoord3ivARB)
+#define glMultiTexCoord3sARB GLEW_GET_FUN(__glewMultiTexCoord3sARB)
+#define glMultiTexCoord3svARB GLEW_GET_FUN(__glewMultiTexCoord3svARB)
+#define glMultiTexCoord4dARB GLEW_GET_FUN(__glewMultiTexCoord4dARB)
+#define glMultiTexCoord4dvARB GLEW_GET_FUN(__glewMultiTexCoord4dvARB)
+#define glMultiTexCoord4fARB GLEW_GET_FUN(__glewMultiTexCoord4fARB)
+#define glMultiTexCoord4fvARB GLEW_GET_FUN(__glewMultiTexCoord4fvARB)
+#define glMultiTexCoord4iARB GLEW_GET_FUN(__glewMultiTexCoord4iARB)
+#define glMultiTexCoord4ivARB GLEW_GET_FUN(__glewMultiTexCoord4ivARB)
+#define glMultiTexCoord4sARB GLEW_GET_FUN(__glewMultiTexCoord4sARB)
+#define glMultiTexCoord4svARB GLEW_GET_FUN(__glewMultiTexCoord4svARB)
+
+#define GLEW_ARB_multitexture GLEW_GET_VAR(__GLEW_ARB_multitexture)
+
+#endif /* GL_ARB_multitexture */
+
+/* ------------------------- GL_ARB_occlusion_query ------------------------ */
+
+#ifndef GL_ARB_occlusion_query
+#define GL_ARB_occlusion_query 1
+
+#define GL_QUERY_COUNTER_BITS_ARB 0x8864
+#define GL_CURRENT_QUERY_ARB 0x8865
+#define GL_QUERY_RESULT_ARB 0x8866
+#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
+#define GL_SAMPLES_PASSED_ARB 0x8914
+
+typedef void (GLAPIENTRY * PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLENDQUERYARBPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISQUERYARBPROC) (GLuint id);
+
+#define glBeginQueryARB GLEW_GET_FUN(__glewBeginQueryARB)
+#define glDeleteQueriesARB GLEW_GET_FUN(__glewDeleteQueriesARB)
+#define glEndQueryARB GLEW_GET_FUN(__glewEndQueryARB)
+#define glGenQueriesARB GLEW_GET_FUN(__glewGenQueriesARB)
+#define glGetQueryObjectivARB GLEW_GET_FUN(__glewGetQueryObjectivARB)
+#define glGetQueryObjectuivARB GLEW_GET_FUN(__glewGetQueryObjectuivARB)
+#define glGetQueryivARB GLEW_GET_FUN(__glewGetQueryivARB)
+#define glIsQueryARB GLEW_GET_FUN(__glewIsQueryARB)
+
+#define GLEW_ARB_occlusion_query GLEW_GET_VAR(__GLEW_ARB_occlusion_query)
+
+#endif /* GL_ARB_occlusion_query */
+
+/* ------------------------ GL_ARB_occlusion_query2 ------------------------ */
+
+#ifndef GL_ARB_occlusion_query2
+#define GL_ARB_occlusion_query2 1
+
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+
+#define GLEW_ARB_occlusion_query2 GLEW_GET_VAR(__GLEW_ARB_occlusion_query2)
+
+#endif /* GL_ARB_occlusion_query2 */
+
+/* ----------------------- GL_ARB_pixel_buffer_object ---------------------- */
+
+#ifndef GL_ARB_pixel_buffer_object
+#define GL_ARB_pixel_buffer_object 1
+
+#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
+
+#define GLEW_ARB_pixel_buffer_object GLEW_GET_VAR(__GLEW_ARB_pixel_buffer_object)
+
+#endif /* GL_ARB_pixel_buffer_object */
+
+/* ------------------------ GL_ARB_point_parameters ------------------------ */
+
+#ifndef GL_ARB_point_parameters
+#define GL_ARB_point_parameters 1
+
+#define GL_POINT_SIZE_MIN_ARB 0x8126
+#define GL_POINT_SIZE_MAX_ARB 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128
+#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129
+
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat* params);
+
+#define glPointParameterfARB GLEW_GET_FUN(__glewPointParameterfARB)
+#define glPointParameterfvARB GLEW_GET_FUN(__glewPointParameterfvARB)
+
+#define GLEW_ARB_point_parameters GLEW_GET_VAR(__GLEW_ARB_point_parameters)
+
+#endif /* GL_ARB_point_parameters */
+
+/* -------------------------- GL_ARB_point_sprite -------------------------- */
+
+#ifndef GL_ARB_point_sprite
+#define GL_ARB_point_sprite 1
+
+#define GL_POINT_SPRITE_ARB 0x8861
+#define GL_COORD_REPLACE_ARB 0x8862
+
+#define GLEW_ARB_point_sprite GLEW_GET_VAR(__GLEW_ARB_point_sprite)
+
+#endif /* GL_ARB_point_sprite */
+
+/* --------------------- GL_ARB_program_interface_query -------------------- */
+
+#ifndef GL_ARB_program_interface_query
+#define GL_ARB_program_interface_query 1
+
+#define GL_UNIFORM 0x92E1
+#define GL_UNIFORM_BLOCK 0x92E2
+#define GL_PROGRAM_INPUT 0x92E3
+#define GL_PROGRAM_OUTPUT 0x92E4
+#define GL_BUFFER_VARIABLE 0x92E5
+#define GL_SHADER_STORAGE_BLOCK 0x92E6
+#define GL_IS_PER_PATCH 0x92E7
+#define GL_VERTEX_SUBROUTINE 0x92E8
+#define GL_TESS_CONTROL_SUBROUTINE 0x92E9
+#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA
+#define GL_GEOMETRY_SUBROUTINE 0x92EB
+#define GL_FRAGMENT_SUBROUTINE 0x92EC
+#define GL_COMPUTE_SUBROUTINE 0x92ED
+#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE
+#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF
+#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0
+#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1
+#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2
+#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3
+#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4
+#define GL_ACTIVE_RESOURCES 0x92F5
+#define GL_MAX_NAME_LENGTH 0x92F6
+#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7
+#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8
+#define GL_NAME_LENGTH 0x92F9
+#define GL_TYPE 0x92FA
+#define GL_ARRAY_SIZE 0x92FB
+#define GL_OFFSET 0x92FC
+#define GL_BLOCK_INDEX 0x92FD
+#define GL_ARRAY_STRIDE 0x92FE
+#define GL_MATRIX_STRIDE 0x92FF
+#define GL_IS_ROW_MAJOR 0x9300
+#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301
+#define GL_BUFFER_BINDING 0x9302
+#define GL_BUFFER_DATA_SIZE 0x9303
+#define GL_NUM_ACTIVE_VARIABLES 0x9304
+#define GL_ACTIVE_VARIABLES 0x9305
+#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308
+#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309
+#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A
+#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B
+#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C
+#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D
+#define GL_LOCATION 0x930E
+#define GL_LOCATION_INDEX 0x930F
+
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint* params);
+typedef GLuint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar* name);
+typedef GLint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar* name);
+typedef GLint (GLAPIENTRY * PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar *name);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei *length, GLint *params);
+
+#define glGetProgramInterfaceiv GLEW_GET_FUN(__glewGetProgramInterfaceiv)
+#define glGetProgramResourceIndex GLEW_GET_FUN(__glewGetProgramResourceIndex)
+#define glGetProgramResourceLocation GLEW_GET_FUN(__glewGetProgramResourceLocation)
+#define glGetProgramResourceLocationIndex GLEW_GET_FUN(__glewGetProgramResourceLocationIndex)
+#define glGetProgramResourceName GLEW_GET_FUN(__glewGetProgramResourceName)
+#define glGetProgramResourceiv GLEW_GET_FUN(__glewGetProgramResourceiv)
+
+#define GLEW_ARB_program_interface_query GLEW_GET_VAR(__GLEW_ARB_program_interface_query)
+
+#endif /* GL_ARB_program_interface_query */
+
+/* ------------------------ GL_ARB_provoking_vertex ------------------------ */
+
+#ifndef GL_ARB_provoking_vertex
+#define GL_ARB_provoking_vertex 1
+
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_PROVOKING_VERTEX 0x8E4F
+
+typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXPROC) (GLenum mode);
+
+#define glProvokingVertex GLEW_GET_FUN(__glewProvokingVertex)
+
+#define GLEW_ARB_provoking_vertex GLEW_GET_VAR(__GLEW_ARB_provoking_vertex)
+
+#endif /* GL_ARB_provoking_vertex */
+
+/* ----------------------- GL_ARB_query_buffer_object ---------------------- */
+
+#ifndef GL_ARB_query_buffer_object
+#define GL_ARB_query_buffer_object 1
+
+#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000
+#define GL_QUERY_BUFFER 0x9192
+#define GL_QUERY_BUFFER_BINDING 0x9193
+#define GL_QUERY_RESULT_NO_WAIT 0x9194
+
+#define GLEW_ARB_query_buffer_object GLEW_GET_VAR(__GLEW_ARB_query_buffer_object)
+
+#endif /* GL_ARB_query_buffer_object */
+
+/* ------------------ GL_ARB_robust_buffer_access_behavior ----------------- */
+
+#ifndef GL_ARB_robust_buffer_access_behavior
+#define GL_ARB_robust_buffer_access_behavior 1
+
+#define GLEW_ARB_robust_buffer_access_behavior GLEW_GET_VAR(__GLEW_ARB_robust_buffer_access_behavior)
+
+#endif /* GL_ARB_robust_buffer_access_behavior */
+
+/* --------------------------- GL_ARB_robustness --------------------------- */
+
+#ifndef GL_ARB_robustness
+#define GL_ARB_robustness 1
+
+#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253
+#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
+#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define GL_NO_RESET_NOTIFICATION_ARB 0x8261
+
+typedef GLenum (GLAPIENTRY * PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void);
+typedef void (GLAPIENTRY * PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* table);
+typedef void (GLAPIENTRY * PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, void* img);
+typedef void (GLAPIENTRY * PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* image);
+typedef void (GLAPIENTRY * PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values);
+typedef void (GLAPIENTRY * PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint* v);
+typedef void (GLAPIENTRY * PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values);
+typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat* values);
+typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint* values);
+typedef void (GLAPIENTRY * PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort* values);
+typedef void (GLAPIENTRY * PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte* pattern);
+typedef void (GLAPIENTRY * PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void* row, GLsizei columnBufSize, GLvoid*column, GLvoid*span);
+typedef void (GLAPIENTRY * PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void* img);
+typedef void (GLAPIENTRY * PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void* data);
+
+#define glGetGraphicsResetStatusARB GLEW_GET_FUN(__glewGetGraphicsResetStatusARB)
+#define glGetnColorTableARB GLEW_GET_FUN(__glewGetnColorTableARB)
+#define glGetnCompressedTexImageARB GLEW_GET_FUN(__glewGetnCompressedTexImageARB)
+#define glGetnConvolutionFilterARB GLEW_GET_FUN(__glewGetnConvolutionFilterARB)
+#define glGetnHistogramARB GLEW_GET_FUN(__glewGetnHistogramARB)
+#define glGetnMapdvARB GLEW_GET_FUN(__glewGetnMapdvARB)
+#define glGetnMapfvARB GLEW_GET_FUN(__glewGetnMapfvARB)
+#define glGetnMapivARB GLEW_GET_FUN(__glewGetnMapivARB)
+#define glGetnMinmaxARB GLEW_GET_FUN(__glewGetnMinmaxARB)
+#define glGetnPixelMapfvARB GLEW_GET_FUN(__glewGetnPixelMapfvARB)
+#define glGetnPixelMapuivARB GLEW_GET_FUN(__glewGetnPixelMapuivARB)
+#define glGetnPixelMapusvARB GLEW_GET_FUN(__glewGetnPixelMapusvARB)
+#define glGetnPolygonStippleARB GLEW_GET_FUN(__glewGetnPolygonStippleARB)
+#define glGetnSeparableFilterARB GLEW_GET_FUN(__glewGetnSeparableFilterARB)
+#define glGetnTexImageARB GLEW_GET_FUN(__glewGetnTexImageARB)
+#define glGetnUniformdvARB GLEW_GET_FUN(__glewGetnUniformdvARB)
+#define glGetnUniformfvARB GLEW_GET_FUN(__glewGetnUniformfvARB)
+#define glGetnUniformivARB GLEW_GET_FUN(__glewGetnUniformivARB)
+#define glGetnUniformuivARB GLEW_GET_FUN(__glewGetnUniformuivARB)
+#define glReadnPixelsARB GLEW_GET_FUN(__glewReadnPixelsARB)
+
+#define GLEW_ARB_robustness GLEW_GET_VAR(__GLEW_ARB_robustness)
+
+#endif /* GL_ARB_robustness */
+
+/* ---------------- GL_ARB_robustness_application_isolation ---------------- */
+
+#ifndef GL_ARB_robustness_application_isolation
+#define GL_ARB_robustness_application_isolation 1
+
+#define GLEW_ARB_robustness_application_isolation GLEW_GET_VAR(__GLEW_ARB_robustness_application_isolation)
+
+#endif /* GL_ARB_robustness_application_isolation */
+
+/* ---------------- GL_ARB_robustness_share_group_isolation ---------------- */
+
+#ifndef GL_ARB_robustness_share_group_isolation
+#define GL_ARB_robustness_share_group_isolation 1
+
+#define GLEW_ARB_robustness_share_group_isolation GLEW_GET_VAR(__GLEW_ARB_robustness_share_group_isolation)
+
+#endif /* GL_ARB_robustness_share_group_isolation */
+
+/* ------------------------- GL_ARB_sample_shading ------------------------- */
+
+#ifndef GL_ARB_sample_shading
+#define GL_ARB_sample_shading 1
+
+#define GL_SAMPLE_SHADING_ARB 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37
+
+typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGARBPROC) (GLclampf value);
+
+#define glMinSampleShadingARB GLEW_GET_FUN(__glewMinSampleShadingARB)
+
+#define GLEW_ARB_sample_shading GLEW_GET_VAR(__GLEW_ARB_sample_shading)
+
+#endif /* GL_ARB_sample_shading */
+
+/* ------------------------- GL_ARB_sampler_objects ------------------------ */
+
+#ifndef GL_ARB_sampler_objects
+#define GL_ARB_sampler_objects 1
+
+#define GL_SAMPLER_BINDING 0x8919
+
+typedef void (GLAPIENTRY * PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
+typedef void (GLAPIENTRY * PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint * samplers);
+typedef void (GLAPIENTRY * PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint* samplers);
+typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISSAMPLERPROC) (GLuint sampler);
+typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint* params);
+typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint* params);
+
+#define glBindSampler GLEW_GET_FUN(__glewBindSampler)
+#define glDeleteSamplers GLEW_GET_FUN(__glewDeleteSamplers)
+#define glGenSamplers GLEW_GET_FUN(__glewGenSamplers)
+#define glGetSamplerParameterIiv GLEW_GET_FUN(__glewGetSamplerParameterIiv)
+#define glGetSamplerParameterIuiv GLEW_GET_FUN(__glewGetSamplerParameterIuiv)
+#define glGetSamplerParameterfv GLEW_GET_FUN(__glewGetSamplerParameterfv)
+#define glGetSamplerParameteriv GLEW_GET_FUN(__glewGetSamplerParameteriv)
+#define glIsSampler GLEW_GET_FUN(__glewIsSampler)
+#define glSamplerParameterIiv GLEW_GET_FUN(__glewSamplerParameterIiv)
+#define glSamplerParameterIuiv GLEW_GET_FUN(__glewSamplerParameterIuiv)
+#define glSamplerParameterf GLEW_GET_FUN(__glewSamplerParameterf)
+#define glSamplerParameterfv GLEW_GET_FUN(__glewSamplerParameterfv)
+#define glSamplerParameteri GLEW_GET_FUN(__glewSamplerParameteri)
+#define glSamplerParameteriv GLEW_GET_FUN(__glewSamplerParameteriv)
+
+#define GLEW_ARB_sampler_objects GLEW_GET_VAR(__GLEW_ARB_sampler_objects)
+
+#endif /* GL_ARB_sampler_objects */
+
+/* ------------------------ GL_ARB_seamless_cube_map ----------------------- */
+
+#ifndef GL_ARB_seamless_cube_map
+#define GL_ARB_seamless_cube_map 1
+
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+
+#define GLEW_ARB_seamless_cube_map GLEW_GET_VAR(__GLEW_ARB_seamless_cube_map)
+
+#endif /* GL_ARB_seamless_cube_map */
+
+/* ------------------ GL_ARB_seamless_cubemap_per_texture ------------------ */
+
+#ifndef GL_ARB_seamless_cubemap_per_texture
+#define GL_ARB_seamless_cubemap_per_texture 1
+
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+
+#define GLEW_ARB_seamless_cubemap_per_texture GLEW_GET_VAR(__GLEW_ARB_seamless_cubemap_per_texture)
+
+#endif /* GL_ARB_seamless_cubemap_per_texture */
+
+/* --------------------- GL_ARB_separate_shader_objects -------------------- */
+
+#ifndef GL_ARB_separate_shader_objects
+#define GL_ARB_separate_shader_objects 1
+
+#define GL_VERTEX_SHADER_BIT 0x00000001
+#define GL_FRAGMENT_SHADER_BIT 0x00000002
+#define GL_GEOMETRY_SHADER_BIT 0x00000004
+#define GL_TESS_CONTROL_SHADER_BIT 0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010
+#define GL_PROGRAM_SEPARABLE 0x8258
+#define GL_ACTIVE_PROGRAM 0x8259
+#define GL_PROGRAM_PIPELINE_BINDING 0x825A
+#define GL_ALL_SHADER_BITS 0xFFFFFFFF
+
+typedef void (GLAPIENTRY * PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program);
+typedef void (GLAPIENTRY * PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar ** strings);
+typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint* pipelines);
+typedef void (GLAPIENTRY * PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint* pipelines);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar *infoLog);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat x);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint x);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint x);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint x, GLint y);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint x, GLuint y);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint x, GLuint y, GLuint z);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program);
+typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline);
+
+#define glActiveShaderProgram GLEW_GET_FUN(__glewActiveShaderProgram)
+#define glBindProgramPipeline GLEW_GET_FUN(__glewBindProgramPipeline)
+#define glCreateShaderProgramv GLEW_GET_FUN(__glewCreateShaderProgramv)
+#define glDeleteProgramPipelines GLEW_GET_FUN(__glewDeleteProgramPipelines)
+#define glGenProgramPipelines GLEW_GET_FUN(__glewGenProgramPipelines)
+#define glGetProgramPipelineInfoLog GLEW_GET_FUN(__glewGetProgramPipelineInfoLog)
+#define glGetProgramPipelineiv GLEW_GET_FUN(__glewGetProgramPipelineiv)
+#define glIsProgramPipeline GLEW_GET_FUN(__glewIsProgramPipeline)
+#define glProgramUniform1d GLEW_GET_FUN(__glewProgramUniform1d)
+#define glProgramUniform1dv GLEW_GET_FUN(__glewProgramUniform1dv)
+#define glProgramUniform1f GLEW_GET_FUN(__glewProgramUniform1f)
+#define glProgramUniform1fv GLEW_GET_FUN(__glewProgramUniform1fv)
+#define glProgramUniform1i GLEW_GET_FUN(__glewProgramUniform1i)
+#define glProgramUniform1iv GLEW_GET_FUN(__glewProgramUniform1iv)
+#define glProgramUniform1ui GLEW_GET_FUN(__glewProgramUniform1ui)
+#define glProgramUniform1uiv GLEW_GET_FUN(__glewProgramUniform1uiv)
+#define glProgramUniform2d GLEW_GET_FUN(__glewProgramUniform2d)
+#define glProgramUniform2dv GLEW_GET_FUN(__glewProgramUniform2dv)
+#define glProgramUniform2f GLEW_GET_FUN(__glewProgramUniform2f)
+#define glProgramUniform2fv GLEW_GET_FUN(__glewProgramUniform2fv)
+#define glProgramUniform2i GLEW_GET_FUN(__glewProgramUniform2i)
+#define glProgramUniform2iv GLEW_GET_FUN(__glewProgramUniform2iv)
+#define glProgramUniform2ui GLEW_GET_FUN(__glewProgramUniform2ui)
+#define glProgramUniform2uiv GLEW_GET_FUN(__glewProgramUniform2uiv)
+#define glProgramUniform3d GLEW_GET_FUN(__glewProgramUniform3d)
+#define glProgramUniform3dv GLEW_GET_FUN(__glewProgramUniform3dv)
+#define glProgramUniform3f GLEW_GET_FUN(__glewProgramUniform3f)
+#define glProgramUniform3fv GLEW_GET_FUN(__glewProgramUniform3fv)
+#define glProgramUniform3i GLEW_GET_FUN(__glewProgramUniform3i)
+#define glProgramUniform3iv GLEW_GET_FUN(__glewProgramUniform3iv)
+#define glProgramUniform3ui GLEW_GET_FUN(__glewProgramUniform3ui)
+#define glProgramUniform3uiv GLEW_GET_FUN(__glewProgramUniform3uiv)
+#define glProgramUniform4d GLEW_GET_FUN(__glewProgramUniform4d)
+#define glProgramUniform4dv GLEW_GET_FUN(__glewProgramUniform4dv)
+#define glProgramUniform4f GLEW_GET_FUN(__glewProgramUniform4f)
+#define glProgramUniform4fv GLEW_GET_FUN(__glewProgramUniform4fv)
+#define glProgramUniform4i GLEW_GET_FUN(__glewProgramUniform4i)
+#define glProgramUniform4iv GLEW_GET_FUN(__glewProgramUniform4iv)
+#define glProgramUniform4ui GLEW_GET_FUN(__glewProgramUniform4ui)
+#define glProgramUniform4uiv GLEW_GET_FUN(__glewProgramUniform4uiv)
+#define glProgramUniformMatrix2dv GLEW_GET_FUN(__glewProgramUniformMatrix2dv)
+#define glProgramUniformMatrix2fv GLEW_GET_FUN(__glewProgramUniformMatrix2fv)
+#define glProgramUniformMatrix2x3dv GLEW_GET_FUN(__glewProgramUniformMatrix2x3dv)
+#define glProgramUniformMatrix2x3fv GLEW_GET_FUN(__glewProgramUniformMatrix2x3fv)
+#define glProgramUniformMatrix2x4dv GLEW_GET_FUN(__glewProgramUniformMatrix2x4dv)
+#define glProgramUniformMatrix2x4fv GLEW_GET_FUN(__glewProgramUniformMatrix2x4fv)
+#define glProgramUniformMatrix3dv GLEW_GET_FUN(__glewProgramUniformMatrix3dv)
+#define glProgramUniformMatrix3fv GLEW_GET_FUN(__glewProgramUniformMatrix3fv)
+#define glProgramUniformMatrix3x2dv GLEW_GET_FUN(__glewProgramUniformMatrix3x2dv)
+#define glProgramUniformMatrix3x2fv GLEW_GET_FUN(__glewProgramUniformMatrix3x2fv)
+#define glProgramUniformMatrix3x4dv GLEW_GET_FUN(__glewProgramUniformMatrix3x4dv)
+#define glProgramUniformMatrix3x4fv GLEW_GET_FUN(__glewProgramUniformMatrix3x4fv)
+#define glProgramUniformMatrix4dv GLEW_GET_FUN(__glewProgramUniformMatrix4dv)
+#define glProgramUniformMatrix4fv GLEW_GET_FUN(__glewProgramUniformMatrix4fv)
+#define glProgramUniformMatrix4x2dv GLEW_GET_FUN(__glewProgramUniformMatrix4x2dv)
+#define glProgramUniformMatrix4x2fv GLEW_GET_FUN(__glewProgramUniformMatrix4x2fv)
+#define glProgramUniformMatrix4x3dv GLEW_GET_FUN(__glewProgramUniformMatrix4x3dv)
+#define glProgramUniformMatrix4x3fv GLEW_GET_FUN(__glewProgramUniformMatrix4x3fv)
+#define glUseProgramStages GLEW_GET_FUN(__glewUseProgramStages)
+#define glValidateProgramPipeline GLEW_GET_FUN(__glewValidateProgramPipeline)
+
+#define GLEW_ARB_separate_shader_objects GLEW_GET_VAR(__GLEW_ARB_separate_shader_objects)
+
+#endif /* GL_ARB_separate_shader_objects */
+
+/* --------------------- GL_ARB_shader_atomic_counters --------------------- */
+
+#ifndef GL_ARB_shader_atomic_counters
+#define GL_ARB_shader_atomic_counters 1
+
+#define GL_ATOMIC_COUNTER_BUFFER 0x92C0
+#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1
+#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2
+#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3
+#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB
+#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0
+#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1
+#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6
+#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8
+#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9
+#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA
+#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC
+
+typedef void (GLAPIENTRY * PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint* params);
+
+#define glGetActiveAtomicCounterBufferiv GLEW_GET_FUN(__glewGetActiveAtomicCounterBufferiv)
+
+#define GLEW_ARB_shader_atomic_counters GLEW_GET_VAR(__GLEW_ARB_shader_atomic_counters)
+
+#endif /* GL_ARB_shader_atomic_counters */
+
+/* ----------------------- GL_ARB_shader_bit_encoding ---------------------- */
+
+#ifndef GL_ARB_shader_bit_encoding
+#define GL_ARB_shader_bit_encoding 1
+
+#define GLEW_ARB_shader_bit_encoding GLEW_GET_VAR(__GLEW_ARB_shader_bit_encoding)
+
+#endif /* GL_ARB_shader_bit_encoding */
+
+/* --------------------- GL_ARB_shader_draw_parameters --------------------- */
+
+#ifndef GL_ARB_shader_draw_parameters
+#define GL_ARB_shader_draw_parameters 1
+
+#define GLEW_ARB_shader_draw_parameters GLEW_GET_VAR(__GLEW_ARB_shader_draw_parameters)
+
+#endif /* GL_ARB_shader_draw_parameters */
+
+/* ------------------------ GL_ARB_shader_group_vote ----------------------- */
+
+#ifndef GL_ARB_shader_group_vote
+#define GL_ARB_shader_group_vote 1
+
+#define GLEW_ARB_shader_group_vote GLEW_GET_VAR(__GLEW_ARB_shader_group_vote)
+
+#endif /* GL_ARB_shader_group_vote */
+
+/* --------------------- GL_ARB_shader_image_load_store -------------------- */
+
+#ifndef GL_ARB_shader_image_load_store
+#define GL_ARB_shader_image_load_store 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
+#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
+#define GL_UNIFORM_BARRIER_BIT 0x00000004
+#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#define GL_COMMAND_BARRIER_BIT 0x00000040
+#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
+#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
+#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
+#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
+#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
+#define GL_MAX_IMAGE_UNITS 0x8F38
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39
+#define GL_IMAGE_BINDING_NAME 0x8F3A
+#define GL_IMAGE_BINDING_LEVEL 0x8F3B
+#define GL_IMAGE_BINDING_LAYERED 0x8F3C
+#define GL_IMAGE_BINDING_LAYER 0x8F3D
+#define GL_IMAGE_BINDING_ACCESS 0x8F3E
+#define GL_IMAGE_1D 0x904C
+#define GL_IMAGE_2D 0x904D
+#define GL_IMAGE_3D 0x904E
+#define GL_IMAGE_2D_RECT 0x904F
+#define GL_IMAGE_CUBE 0x9050
+#define GL_IMAGE_BUFFER 0x9051
+#define GL_IMAGE_1D_ARRAY 0x9052
+#define GL_IMAGE_2D_ARRAY 0x9053
+#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054
+#define GL_IMAGE_2D_MULTISAMPLE 0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056
+#define GL_INT_IMAGE_1D 0x9057
+#define GL_INT_IMAGE_2D 0x9058
+#define GL_INT_IMAGE_3D 0x9059
+#define GL_INT_IMAGE_2D_RECT 0x905A
+#define GL_INT_IMAGE_CUBE 0x905B
+#define GL_INT_IMAGE_BUFFER 0x905C
+#define GL_INT_IMAGE_1D_ARRAY 0x905D
+#define GL_INT_IMAGE_2D_ARRAY 0x905E
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F
+#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061
+#define GL_UNSIGNED_INT_IMAGE_1D 0x9062
+#define GL_UNSIGNED_INT_IMAGE_2D 0x9063
+#define GL_UNSIGNED_INT_IMAGE_3D 0x9064
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
+#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C
+#define GL_MAX_IMAGE_SAMPLES 0x906D
+#define GL_IMAGE_BINDING_FORMAT 0x906E
+#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9
+#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD
+#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE
+#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF
+#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
+
+typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+typedef void (GLAPIENTRY * PFNGLMEMORYBARRIERPROC) (GLbitfield barriers);
+
+#define glBindImageTexture GLEW_GET_FUN(__glewBindImageTexture)
+#define glMemoryBarrier GLEW_GET_FUN(__glewMemoryBarrier)
+
+#define GLEW_ARB_shader_image_load_store GLEW_GET_VAR(__GLEW_ARB_shader_image_load_store)
+
+#endif /* GL_ARB_shader_image_load_store */
+
+/* ------------------------ GL_ARB_shader_image_size ----------------------- */
+
+#ifndef GL_ARB_shader_image_size
+#define GL_ARB_shader_image_size 1
+
+#define GLEW_ARB_shader_image_size GLEW_GET_VAR(__GLEW_ARB_shader_image_size)
+
+#endif /* GL_ARB_shader_image_size */
+
+/* ------------------------- GL_ARB_shader_objects ------------------------- */
+
+#ifndef GL_ARB_shader_objects
+#define GL_ARB_shader_objects 1
+
+#define GL_PROGRAM_OBJECT_ARB 0x8B40
+#define GL_SHADER_OBJECT_ARB 0x8B48
+#define GL_OBJECT_TYPE_ARB 0x8B4E
+#define GL_OBJECT_SUBTYPE_ARB 0x8B4F
+#define GL_FLOAT_VEC2_ARB 0x8B50
+#define GL_FLOAT_VEC3_ARB 0x8B51
+#define GL_FLOAT_VEC4_ARB 0x8B52
+#define GL_INT_VEC2_ARB 0x8B53
+#define GL_INT_VEC3_ARB 0x8B54
+#define GL_INT_VEC4_ARB 0x8B55
+#define GL_BOOL_ARB 0x8B56
+#define GL_BOOL_VEC2_ARB 0x8B57
+#define GL_BOOL_VEC3_ARB 0x8B58
+#define GL_BOOL_VEC4_ARB 0x8B59
+#define GL_FLOAT_MAT2_ARB 0x8B5A
+#define GL_FLOAT_MAT3_ARB 0x8B5B
+#define GL_FLOAT_MAT4_ARB 0x8B5C
+#define GL_SAMPLER_1D_ARB 0x8B5D
+#define GL_SAMPLER_2D_ARB 0x8B5E
+#define GL_SAMPLER_3D_ARB 0x8B5F
+#define GL_SAMPLER_CUBE_ARB 0x8B60
+#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61
+#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62
+#define GL_SAMPLER_2D_RECT_ARB 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64
+#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80
+#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81
+#define GL_OBJECT_LINK_STATUS_ARB 0x8B82
+#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83
+#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84
+#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85
+#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86
+#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87
+#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88
+
+typedef char GLcharARB;
+typedef unsigned int GLhandleARB;
+
+typedef void (GLAPIENTRY * PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj);
+typedef void (GLAPIENTRY * PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj);
+typedef GLhandleARB (GLAPIENTRY * PFNGLCREATEPROGRAMOBJECTARBPROC) (void);
+typedef GLhandleARB (GLAPIENTRY * PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType);
+typedef void (GLAPIENTRY * PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj);
+typedef void (GLAPIENTRY * PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name);
+typedef void (GLAPIENTRY * PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei* count, GLhandleARB *obj);
+typedef GLhandleARB (GLAPIENTRY * PFNGLGETHANDLEARBPROC) (GLenum pname);
+typedef void (GLAPIENTRY * PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *infoLog);
+typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei* length, GLcharARB *source);
+typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint* params);
+typedef void (GLAPIENTRY * PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj);
+typedef void (GLAPIENTRY * PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB ** string, const GLint *length);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj);
+typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj);
+
+#define glAttachObjectARB GLEW_GET_FUN(__glewAttachObjectARB)
+#define glCompileShaderARB GLEW_GET_FUN(__glewCompileShaderARB)
+#define glCreateProgramObjectARB GLEW_GET_FUN(__glewCreateProgramObjectARB)
+#define glCreateShaderObjectARB GLEW_GET_FUN(__glewCreateShaderObjectARB)
+#define glDeleteObjectARB GLEW_GET_FUN(__glewDeleteObjectARB)
+#define glDetachObjectARB GLEW_GET_FUN(__glewDetachObjectARB)
+#define glGetActiveUniformARB GLEW_GET_FUN(__glewGetActiveUniformARB)
+#define glGetAttachedObjectsARB GLEW_GET_FUN(__glewGetAttachedObjectsARB)
+#define glGetHandleARB GLEW_GET_FUN(__glewGetHandleARB)
+#define glGetInfoLogARB GLEW_GET_FUN(__glewGetInfoLogARB)
+#define glGetObjectParameterfvARB GLEW_GET_FUN(__glewGetObjectParameterfvARB)
+#define glGetObjectParameterivARB GLEW_GET_FUN(__glewGetObjectParameterivARB)
+#define glGetShaderSourceARB GLEW_GET_FUN(__glewGetShaderSourceARB)
+#define glGetUniformLocationARB GLEW_GET_FUN(__glewGetUniformLocationARB)
+#define glGetUniformfvARB GLEW_GET_FUN(__glewGetUniformfvARB)
+#define glGetUniformivARB GLEW_GET_FUN(__glewGetUniformivARB)
+#define glLinkProgramARB GLEW_GET_FUN(__glewLinkProgramARB)
+#define glShaderSourceARB GLEW_GET_FUN(__glewShaderSourceARB)
+#define glUniform1fARB GLEW_GET_FUN(__glewUniform1fARB)
+#define glUniform1fvARB GLEW_GET_FUN(__glewUniform1fvARB)
+#define glUniform1iARB GLEW_GET_FUN(__glewUniform1iARB)
+#define glUniform1ivARB GLEW_GET_FUN(__glewUniform1ivARB)
+#define glUniform2fARB GLEW_GET_FUN(__glewUniform2fARB)
+#define glUniform2fvARB GLEW_GET_FUN(__glewUniform2fvARB)
+#define glUniform2iARB GLEW_GET_FUN(__glewUniform2iARB)
+#define glUniform2ivARB GLEW_GET_FUN(__glewUniform2ivARB)
+#define glUniform3fARB GLEW_GET_FUN(__glewUniform3fARB)
+#define glUniform3fvARB GLEW_GET_FUN(__glewUniform3fvARB)
+#define glUniform3iARB GLEW_GET_FUN(__glewUniform3iARB)
+#define glUniform3ivARB GLEW_GET_FUN(__glewUniform3ivARB)
+#define glUniform4fARB GLEW_GET_FUN(__glewUniform4fARB)
+#define glUniform4fvARB GLEW_GET_FUN(__glewUniform4fvARB)
+#define glUniform4iARB GLEW_GET_FUN(__glewUniform4iARB)
+#define glUniform4ivARB GLEW_GET_FUN(__glewUniform4ivARB)
+#define glUniformMatrix2fvARB GLEW_GET_FUN(__glewUniformMatrix2fvARB)
+#define glUniformMatrix3fvARB GLEW_GET_FUN(__glewUniformMatrix3fvARB)
+#define glUniformMatrix4fvARB GLEW_GET_FUN(__glewUniformMatrix4fvARB)
+#define glUseProgramObjectARB GLEW_GET_FUN(__glewUseProgramObjectARB)
+#define glValidateProgramARB GLEW_GET_FUN(__glewValidateProgramARB)
+
+#define GLEW_ARB_shader_objects GLEW_GET_VAR(__GLEW_ARB_shader_objects)
+
+#endif /* GL_ARB_shader_objects */
+
+/* ------------------------ GL_ARB_shader_precision ------------------------ */
+
+#ifndef GL_ARB_shader_precision
+#define GL_ARB_shader_precision 1
+
+#define GLEW_ARB_shader_precision GLEW_GET_VAR(__GLEW_ARB_shader_precision)
+
+#endif /* GL_ARB_shader_precision */
+
+/* ---------------------- GL_ARB_shader_stencil_export --------------------- */
+
+#ifndef GL_ARB_shader_stencil_export
+#define GL_ARB_shader_stencil_export 1
+
+#define GLEW_ARB_shader_stencil_export GLEW_GET_VAR(__GLEW_ARB_shader_stencil_export)
+
+#endif /* GL_ARB_shader_stencil_export */
+
+/* ------------------ GL_ARB_shader_storage_buffer_object ------------------ */
+
+#ifndef GL_ARB_shader_storage_buffer_object
+#define GL_ARB_shader_storage_buffer_object 1
+
+#define GL_SHADER_STORAGE_BARRIER_BIT 0x2000
+#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39
+#define GL_SHADER_STORAGE_BUFFER 0x90D2
+#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3
+#define GL_SHADER_STORAGE_BUFFER_START 0x90D4
+#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5
+#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9
+#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA
+#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB
+#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC
+#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD
+#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
+#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF
+
+typedef void (GLAPIENTRY * PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);
+
+#define glShaderStorageBlockBinding GLEW_GET_FUN(__glewShaderStorageBlockBinding)
+
+#define GLEW_ARB_shader_storage_buffer_object GLEW_GET_VAR(__GLEW_ARB_shader_storage_buffer_object)
+
+#endif /* GL_ARB_shader_storage_buffer_object */
+
+/* ------------------------ GL_ARB_shader_subroutine ----------------------- */
+
+#ifndef GL_ARB_shader_subroutine
+#define GL_ARB_shader_subroutine 1
+
+#define GL_ACTIVE_SUBROUTINES 0x8DE5
+#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6
+#define GL_MAX_SUBROUTINES 0x8DE7
+#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47
+#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49
+#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A
+#define GL_COMPATIBLE_SUBROUTINES 0x8E4B
+
+typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, GLchar *name);
+typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, GLchar *name);
+typedef void (GLAPIENTRY * PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint* values);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint* values);
+typedef GLuint (GLAPIENTRY * PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar* name);
+typedef GLint (GLAPIENTRY * PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint* indices);
+
+#define glGetActiveSubroutineName GLEW_GET_FUN(__glewGetActiveSubroutineName)
+#define glGetActiveSubroutineUniformName GLEW_GET_FUN(__glewGetActiveSubroutineUniformName)
+#define glGetActiveSubroutineUniformiv GLEW_GET_FUN(__glewGetActiveSubroutineUniformiv)
+#define glGetProgramStageiv GLEW_GET_FUN(__glewGetProgramStageiv)
+#define glGetSubroutineIndex GLEW_GET_FUN(__glewGetSubroutineIndex)
+#define glGetSubroutineUniformLocation GLEW_GET_FUN(__glewGetSubroutineUniformLocation)
+#define glGetUniformSubroutineuiv GLEW_GET_FUN(__glewGetUniformSubroutineuiv)
+#define glUniformSubroutinesuiv GLEW_GET_FUN(__glewUniformSubroutinesuiv)
+
+#define GLEW_ARB_shader_subroutine GLEW_GET_VAR(__GLEW_ARB_shader_subroutine)
+
+#endif /* GL_ARB_shader_subroutine */
+
+/* ----------------------- GL_ARB_shader_texture_lod ----------------------- */
+
+#ifndef GL_ARB_shader_texture_lod
+#define GL_ARB_shader_texture_lod 1
+
+#define GLEW_ARB_shader_texture_lod GLEW_GET_VAR(__GLEW_ARB_shader_texture_lod)
+
+#endif /* GL_ARB_shader_texture_lod */
+
+/* ---------------------- GL_ARB_shading_language_100 ---------------------- */
+
+#ifndef GL_ARB_shading_language_100
+#define GL_ARB_shading_language_100 1
+
+#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C
+
+#define GLEW_ARB_shading_language_100 GLEW_GET_VAR(__GLEW_ARB_shading_language_100)
+
+#endif /* GL_ARB_shading_language_100 */
+
+/* -------------------- GL_ARB_shading_language_420pack -------------------- */
+
+#ifndef GL_ARB_shading_language_420pack
+#define GL_ARB_shading_language_420pack 1
+
+#define GLEW_ARB_shading_language_420pack GLEW_GET_VAR(__GLEW_ARB_shading_language_420pack)
+
+#endif /* GL_ARB_shading_language_420pack */
+
+/* -------------------- GL_ARB_shading_language_include -------------------- */
+
+#ifndef GL_ARB_shading_language_include
+#define GL_ARB_shading_language_include 1
+
+#define GL_SHADER_INCLUDE_ARB 0x8DAE
+#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9
+#define GL_NAMED_STRING_TYPE_ARB 0x8DEA
+
+typedef void (GLAPIENTRY * PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar* const *path, const GLint *length);
+typedef void (GLAPIENTRY * PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name, GLsizei bufSize, GLint *stringlen, GLchar *string);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar* name, GLenum pname, GLint *params);
+typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar* name);
+typedef void (GLAPIENTRY * PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar* name, GLint stringlen, const GLchar *string);
+
+#define glCompileShaderIncludeARB GLEW_GET_FUN(__glewCompileShaderIncludeARB)
+#define glDeleteNamedStringARB GLEW_GET_FUN(__glewDeleteNamedStringARB)
+#define glGetNamedStringARB GLEW_GET_FUN(__glewGetNamedStringARB)
+#define glGetNamedStringivARB GLEW_GET_FUN(__glewGetNamedStringivARB)
+#define glIsNamedStringARB GLEW_GET_FUN(__glewIsNamedStringARB)
+#define glNamedStringARB GLEW_GET_FUN(__glewNamedStringARB)
+
+#define GLEW_ARB_shading_language_include GLEW_GET_VAR(__GLEW_ARB_shading_language_include)
+
+#endif /* GL_ARB_shading_language_include */
+
+/* -------------------- GL_ARB_shading_language_packing -------------------- */
+
+#ifndef GL_ARB_shading_language_packing
+#define GL_ARB_shading_language_packing 1
+
+#define GLEW_ARB_shading_language_packing GLEW_GET_VAR(__GLEW_ARB_shading_language_packing)
+
+#endif /* GL_ARB_shading_language_packing */
+
+/* ----------------------------- GL_ARB_shadow ----------------------------- */
+
+#ifndef GL_ARB_shadow
+#define GL_ARB_shadow 1
+
+#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C
+#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D
+#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E
+
+#define GLEW_ARB_shadow GLEW_GET_VAR(__GLEW_ARB_shadow)
+
+#endif /* GL_ARB_shadow */
+
+/* ------------------------- GL_ARB_shadow_ambient ------------------------- */
+
+#ifndef GL_ARB_shadow_ambient
+#define GL_ARB_shadow_ambient 1
+
+#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF
+
+#define GLEW_ARB_shadow_ambient GLEW_GET_VAR(__GLEW_ARB_shadow_ambient)
+
+#endif /* GL_ARB_shadow_ambient */
+
+/* ------------------------- GL_ARB_sparse_texture ------------------------- */
+
+#ifndef GL_ARB_sparse_texture
+#define GL_ARB_sparse_texture 1
+
+#define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195
+#define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196
+#define GL_VIRTUAL_PAGE_SIZE_Z_ARB 0x9197
+#define GL_MAX_SPARSE_TEXTURE_SIZE_ARB 0x9198
+#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199
+#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A
+#define GL_TEXTURE_SPARSE_ARB 0x91A6
+#define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7
+#define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8
+#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9
+#define GL_NUM_SPARSE_LEVELS_ARB 0x91AA
+
+typedef void (GLAPIENTRY * PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);
+
+#define glTexPageCommitmentARB GLEW_GET_FUN(__glewTexPageCommitmentARB)
+#define glTexturePageCommitmentEXT GLEW_GET_FUN(__glewTexturePageCommitmentEXT)
+
+#define GLEW_ARB_sparse_texture GLEW_GET_VAR(__GLEW_ARB_sparse_texture)
+
+#endif /* GL_ARB_sparse_texture */
+
+/* ------------------------ GL_ARB_stencil_texturing ----------------------- */
+
+#ifndef GL_ARB_stencil_texturing
+#define GL_ARB_stencil_texturing 1
+
+#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA
+
+#define GLEW_ARB_stencil_texturing GLEW_GET_VAR(__GLEW_ARB_stencil_texturing)
+
+#endif /* GL_ARB_stencil_texturing */
+
+/* ------------------------------ GL_ARB_sync ------------------------------ */
+
+#ifndef GL_ARB_sync
+#define GL_ARB_sync 1
+
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_OBJECT_TYPE 0x9112
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_UNSIGNALED 0x9118
+#define GL_SIGNALED 0x9119
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_WAIT_FAILED 0x911D
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF
+
+typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout);
+typedef void (GLAPIENTRY * PFNGLDELETESYNCPROC) (GLsync GLsync);
+typedef GLsync (GLAPIENTRY * PFNGLFENCESYNCPROC) (GLenum condition,GLbitfield flags);
+typedef void (GLAPIENTRY * PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64* params);
+typedef void (GLAPIENTRY * PFNGLGETSYNCIVPROC) (GLsync GLsync,GLenum pname,GLsizei bufSize,GLsizei* length, GLint *values);
+typedef GLboolean (GLAPIENTRY * PFNGLISSYNCPROC) (GLsync GLsync);
+typedef void (GLAPIENTRY * PFNGLWAITSYNCPROC) (GLsync GLsync,GLbitfield flags,GLuint64 timeout);
+
+#define glClientWaitSync GLEW_GET_FUN(__glewClientWaitSync)
+#define glDeleteSync GLEW_GET_FUN(__glewDeleteSync)
+#define glFenceSync GLEW_GET_FUN(__glewFenceSync)
+#define glGetInteger64v GLEW_GET_FUN(__glewGetInteger64v)
+#define glGetSynciv GLEW_GET_FUN(__glewGetSynciv)
+#define glIsSync GLEW_GET_FUN(__glewIsSync)
+#define glWaitSync GLEW_GET_FUN(__glewWaitSync)
+
+#define GLEW_ARB_sync GLEW_GET_VAR(__GLEW_ARB_sync)
+
+#endif /* GL_ARB_sync */
+
+/* ----------------------- GL_ARB_tessellation_shader ---------------------- */
+
+#ifndef GL_ARB_tessellation_shader
+#define GL_ARB_tessellation_shader 1
+
+#define GL_PATCHES 0xE
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
+#define GL_PATCH_VERTICES 0x8E72
+#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73
+#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74
+#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75
+#define GL_TESS_GEN_MODE 0x8E76
+#define GL_TESS_GEN_SPACING 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER 0x8E78
+#define GL_TESS_GEN_POINT_MODE 0x8E79
+#define GL_ISOLINES 0x8E7A
+#define GL_FRACTIONAL_ODD 0x8E7B
+#define GL_FRACTIONAL_EVEN 0x8E7C
+#define GL_MAX_PATCH_VERTICES 0x8E7D
+#define GL_MAX_TESS_GEN_LEVEL 0x8E7E
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83
+#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86
+#define GL_TESS_EVALUATION_SHADER 0x8E87
+#define GL_TESS_CONTROL_SHADER 0x8E88
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A
+
+typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat* values);
+typedef void (GLAPIENTRY * PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value);
+
+#define glPatchParameterfv GLEW_GET_FUN(__glewPatchParameterfv)
+#define glPatchParameteri GLEW_GET_FUN(__glewPatchParameteri)
+
+#define GLEW_ARB_tessellation_shader GLEW_GET_VAR(__GLEW_ARB_tessellation_shader)
+
+#endif /* GL_ARB_tessellation_shader */
+
+/* ---------------------- GL_ARB_texture_border_clamp ---------------------- */
+
+#ifndef GL_ARB_texture_border_clamp
+#define GL_ARB_texture_border_clamp 1
+
+#define GL_CLAMP_TO_BORDER_ARB 0x812D
+
+#define GLEW_ARB_texture_border_clamp GLEW_GET_VAR(__GLEW_ARB_texture_border_clamp)
+
+#endif /* GL_ARB_texture_border_clamp */
+
+/* ---------------------- GL_ARB_texture_buffer_object --------------------- */
+
+#ifndef GL_ARB_texture_buffer_object
+#define GL_ARB_texture_buffer_object 1
+
+#define GL_TEXTURE_BUFFER_ARB 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E
+
+typedef void (GLAPIENTRY * PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+
+#define glTexBufferARB GLEW_GET_FUN(__glewTexBufferARB)
+
+#define GLEW_ARB_texture_buffer_object GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object)
+
+#endif /* GL_ARB_texture_buffer_object */
+
+/* ------------------- GL_ARB_texture_buffer_object_rgb32 ------------------ */
+
+#ifndef GL_ARB_texture_buffer_object_rgb32
+#define GL_ARB_texture_buffer_object_rgb32 1
+
+#define GLEW_ARB_texture_buffer_object_rgb32 GLEW_GET_VAR(__GLEW_ARB_texture_buffer_object_rgb32)
+
+#endif /* GL_ARB_texture_buffer_object_rgb32 */
+
+/* ---------------------- GL_ARB_texture_buffer_range ---------------------- */
+
+#ifndef GL_ARB_texture_buffer_range
+#define GL_ARB_texture_buffer_range 1
+
+#define GL_TEXTURE_BUFFER_OFFSET 0x919D
+#define GL_TEXTURE_BUFFER_SIZE 0x919E
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F
+
+typedef void (GLAPIENTRY * PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+
+#define glTexBufferRange GLEW_GET_FUN(__glewTexBufferRange)
+#define glTextureBufferRangeEXT GLEW_GET_FUN(__glewTextureBufferRangeEXT)
+
+#define GLEW_ARB_texture_buffer_range GLEW_GET_VAR(__GLEW_ARB_texture_buffer_range)
+
+#endif /* GL_ARB_texture_buffer_range */
+
+/* ----------------------- GL_ARB_texture_compression ---------------------- */
+
+#ifndef GL_ARB_texture_compression
+#define GL_ARB_texture_compression 1
+
+#define GL_COMPRESSED_ALPHA_ARB 0x84E9
+#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
+#define GL_COMPRESSED_INTENSITY_ARB 0x84EC
+#define GL_COMPRESSED_RGB_ARB 0x84ED
+#define GL_COMPRESSED_RGBA_ARB 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0
+#define GL_TEXTURE_COMPRESSED_ARB 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3
+
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLvoid *img);
+
+#define glCompressedTexImage1DARB GLEW_GET_FUN(__glewCompressedTexImage1DARB)
+#define glCompressedTexImage2DARB GLEW_GET_FUN(__glewCompressedTexImage2DARB)
+#define glCompressedTexImage3DARB GLEW_GET_FUN(__glewCompressedTexImage3DARB)
+#define glCompressedTexSubImage1DARB GLEW_GET_FUN(__glewCompressedTexSubImage1DARB)
+#define glCompressedTexSubImage2DARB GLEW_GET_FUN(__glewCompressedTexSubImage2DARB)
+#define glCompressedTexSubImage3DARB GLEW_GET_FUN(__glewCompressedTexSubImage3DARB)
+#define glGetCompressedTexImageARB GLEW_GET_FUN(__glewGetCompressedTexImageARB)
+
+#define GLEW_ARB_texture_compression GLEW_GET_VAR(__GLEW_ARB_texture_compression)
+
+#endif /* GL_ARB_texture_compression */
+
+/* -------------------- GL_ARB_texture_compression_bptc -------------------- */
+
+#ifndef GL_ARB_texture_compression_bptc
+#define GL_ARB_texture_compression_bptc 1
+
+#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
+
+#define GLEW_ARB_texture_compression_bptc GLEW_GET_VAR(__GLEW_ARB_texture_compression_bptc)
+
+#endif /* GL_ARB_texture_compression_bptc */
+
+/* -------------------- GL_ARB_texture_compression_rgtc -------------------- */
+
+#ifndef GL_ARB_texture_compression_rgtc
+#define GL_ARB_texture_compression_rgtc 1
+
+#define GL_COMPRESSED_RED_RGTC1 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
+#define GL_COMPRESSED_RG_RGTC2 0x8DBD
+#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
+
+#define GLEW_ARB_texture_compression_rgtc GLEW_GET_VAR(__GLEW_ARB_texture_compression_rgtc)
+
+#endif /* GL_ARB_texture_compression_rgtc */
+
+/* ------------------------ GL_ARB_texture_cube_map ------------------------ */
+
+#ifndef GL_ARB_texture_cube_map
+#define GL_ARB_texture_cube_map 1
+
+#define GL_NORMAL_MAP_ARB 0x8511
+#define GL_REFLECTION_MAP_ARB 0x8512
+#define GL_TEXTURE_CUBE_MAP_ARB 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C
+
+#define GLEW_ARB_texture_cube_map GLEW_GET_VAR(__GLEW_ARB_texture_cube_map)
+
+#endif /* GL_ARB_texture_cube_map */
+
+/* --------------------- GL_ARB_texture_cube_map_array --------------------- */
+
+#ifndef GL_ARB_texture_cube_map_array
+#define GL_ARB_texture_cube_map_array 1
+
+#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F
+
+#define GLEW_ARB_texture_cube_map_array GLEW_GET_VAR(__GLEW_ARB_texture_cube_map_array)
+
+#endif /* GL_ARB_texture_cube_map_array */
+
+/* ------------------------- GL_ARB_texture_env_add ------------------------ */
+
+#ifndef GL_ARB_texture_env_add
+#define GL_ARB_texture_env_add 1
+
+#define GLEW_ARB_texture_env_add GLEW_GET_VAR(__GLEW_ARB_texture_env_add)
+
+#endif /* GL_ARB_texture_env_add */
+
+/* ----------------------- GL_ARB_texture_env_combine ---------------------- */
+
+#ifndef GL_ARB_texture_env_combine
+#define GL_ARB_texture_env_combine 1
+
+#define GL_SUBTRACT_ARB 0x84E7
+#define GL_COMBINE_ARB 0x8570
+#define GL_COMBINE_RGB_ARB 0x8571
+#define GL_COMBINE_ALPHA_ARB 0x8572
+#define GL_RGB_SCALE_ARB 0x8573
+#define GL_ADD_SIGNED_ARB 0x8574
+#define GL_INTERPOLATE_ARB 0x8575
+#define GL_CONSTANT_ARB 0x8576
+#define GL_PRIMARY_COLOR_ARB 0x8577
+#define GL_PREVIOUS_ARB 0x8578
+#define GL_SOURCE0_RGB_ARB 0x8580
+#define GL_SOURCE1_RGB_ARB 0x8581
+#define GL_SOURCE2_RGB_ARB 0x8582
+#define GL_SOURCE0_ALPHA_ARB 0x8588
+#define GL_SOURCE1_ALPHA_ARB 0x8589
+#define GL_SOURCE2_ALPHA_ARB 0x858A
+#define GL_OPERAND0_RGB_ARB 0x8590
+#define GL_OPERAND1_RGB_ARB 0x8591
+#define GL_OPERAND2_RGB_ARB 0x8592
+#define GL_OPERAND0_ALPHA_ARB 0x8598
+#define GL_OPERAND1_ALPHA_ARB 0x8599
+#define GL_OPERAND2_ALPHA_ARB 0x859A
+
+#define GLEW_ARB_texture_env_combine GLEW_GET_VAR(__GLEW_ARB_texture_env_combine)
+
+#endif /* GL_ARB_texture_env_combine */
+
+/* ---------------------- GL_ARB_texture_env_crossbar ---------------------- */
+
+#ifndef GL_ARB_texture_env_crossbar
+#define GL_ARB_texture_env_crossbar 1
+
+#define GLEW_ARB_texture_env_crossbar GLEW_GET_VAR(__GLEW_ARB_texture_env_crossbar)
+
+#endif /* GL_ARB_texture_env_crossbar */
+
+/* ------------------------ GL_ARB_texture_env_dot3 ------------------------ */
+
+#ifndef GL_ARB_texture_env_dot3
+#define GL_ARB_texture_env_dot3 1
+
+#define GL_DOT3_RGB_ARB 0x86AE
+#define GL_DOT3_RGBA_ARB 0x86AF
+
+#define GLEW_ARB_texture_env_dot3 GLEW_GET_VAR(__GLEW_ARB_texture_env_dot3)
+
+#endif /* GL_ARB_texture_env_dot3 */
+
+/* -------------------------- GL_ARB_texture_float ------------------------- */
+
+#ifndef GL_ARB_texture_float
+#define GL_ARB_texture_float 1
+
+#define GL_RGBA32F_ARB 0x8814
+#define GL_RGB32F_ARB 0x8815
+#define GL_ALPHA32F_ARB 0x8816
+#define GL_INTENSITY32F_ARB 0x8817
+#define GL_LUMINANCE32F_ARB 0x8818
+#define GL_LUMINANCE_ALPHA32F_ARB 0x8819
+#define GL_RGBA16F_ARB 0x881A
+#define GL_RGB16F_ARB 0x881B
+#define GL_ALPHA16F_ARB 0x881C
+#define GL_INTENSITY16F_ARB 0x881D
+#define GL_LUMINANCE16F_ARB 0x881E
+#define GL_LUMINANCE_ALPHA16F_ARB 0x881F
+#define GL_TEXTURE_RED_TYPE_ARB 0x8C10
+#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11
+#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12
+#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13
+#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14
+#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15
+#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16
+#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17
+
+#define GLEW_ARB_texture_float GLEW_GET_VAR(__GLEW_ARB_texture_float)
+
+#endif /* GL_ARB_texture_float */
+
+/* ------------------------- GL_ARB_texture_gather ------------------------- */
+
+#ifndef GL_ARB_texture_gather
+#define GL_ARB_texture_gather 1
+
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB 0x8F9F
+
+#define GLEW_ARB_texture_gather GLEW_GET_VAR(__GLEW_ARB_texture_gather)
+
+#endif /* GL_ARB_texture_gather */
+
+/* ------------------ GL_ARB_texture_mirror_clamp_to_edge ------------------ */
+
+#ifndef GL_ARB_texture_mirror_clamp_to_edge
+#define GL_ARB_texture_mirror_clamp_to_edge 1
+
+#define GL_MIRROR_CLAMP_TO_EDGE 0x8743
+
+#define GLEW_ARB_texture_mirror_clamp_to_edge GLEW_GET_VAR(__GLEW_ARB_texture_mirror_clamp_to_edge)
+
+#endif /* GL_ARB_texture_mirror_clamp_to_edge */
+
+/* --------------------- GL_ARB_texture_mirrored_repeat -------------------- */
+
+#ifndef GL_ARB_texture_mirrored_repeat
+#define GL_ARB_texture_mirrored_repeat 1
+
+#define GL_MIRRORED_REPEAT_ARB 0x8370
+
+#define GLEW_ARB_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_ARB_texture_mirrored_repeat)
+
+#endif /* GL_ARB_texture_mirrored_repeat */
+
+/* ----------------------- GL_ARB_texture_multisample ---------------------- */
+
+#ifndef GL_ARB_texture_multisample
+#define GL_ARB_texture_multisample 1
+
+#define GL_SAMPLE_POSITION 0x8E50
+#define GL_SAMPLE_MASK 0x8E51
+#define GL_SAMPLE_MASK_VALUE 0x8E52
+#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define GL_TEXTURE_SAMPLES 0x9106
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define GL_MAX_INTEGER_SAMPLES 0x9110
+
+typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat* val);
+typedef void (GLAPIENTRY * PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask);
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+
+#define glGetMultisamplefv GLEW_GET_FUN(__glewGetMultisamplefv)
+#define glSampleMaski GLEW_GET_FUN(__glewSampleMaski)
+#define glTexImage2DMultisample GLEW_GET_FUN(__glewTexImage2DMultisample)
+#define glTexImage3DMultisample GLEW_GET_FUN(__glewTexImage3DMultisample)
+
+#define GLEW_ARB_texture_multisample GLEW_GET_VAR(__GLEW_ARB_texture_multisample)
+
+#endif /* GL_ARB_texture_multisample */
+
+/* -------------------- GL_ARB_texture_non_power_of_two -------------------- */
+
+#ifndef GL_ARB_texture_non_power_of_two
+#define GL_ARB_texture_non_power_of_two 1
+
+#define GLEW_ARB_texture_non_power_of_two GLEW_GET_VAR(__GLEW_ARB_texture_non_power_of_two)
+
+#endif /* GL_ARB_texture_non_power_of_two */
+
+/* ---------------------- GL_ARB_texture_query_levels ---------------------- */
+
+#ifndef GL_ARB_texture_query_levels
+#define GL_ARB_texture_query_levels 1
+
+#define GLEW_ARB_texture_query_levels GLEW_GET_VAR(__GLEW_ARB_texture_query_levels)
+
+#endif /* GL_ARB_texture_query_levels */
+
+/* ------------------------ GL_ARB_texture_query_lod ----------------------- */
+
+#ifndef GL_ARB_texture_query_lod
+#define GL_ARB_texture_query_lod 1
+
+#define GLEW_ARB_texture_query_lod GLEW_GET_VAR(__GLEW_ARB_texture_query_lod)
+
+#endif /* GL_ARB_texture_query_lod */
+
+/* ------------------------ GL_ARB_texture_rectangle ----------------------- */
+
+#ifndef GL_ARB_texture_rectangle
+#define GL_ARB_texture_rectangle 1
+
+#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
+#define GL_SAMPLER_2D_RECT_ARB 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64
+
+#define GLEW_ARB_texture_rectangle GLEW_GET_VAR(__GLEW_ARB_texture_rectangle)
+
+#endif /* GL_ARB_texture_rectangle */
+
+/* --------------------------- GL_ARB_texture_rg --------------------------- */
+
+#ifndef GL_ARB_texture_rg
+#define GL_ARB_texture_rg 1
+
+#define GL_COMPRESSED_RED 0x8225
+#define GL_COMPRESSED_RG 0x8226
+#define GL_RG 0x8227
+#define GL_RG_INTEGER 0x8228
+#define GL_R8 0x8229
+#define GL_R16 0x822A
+#define GL_RG8 0x822B
+#define GL_RG16 0x822C
+#define GL_R16F 0x822D
+#define GL_R32F 0x822E
+#define GL_RG16F 0x822F
+#define GL_RG32F 0x8230
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+
+#define GLEW_ARB_texture_rg GLEW_GET_VAR(__GLEW_ARB_texture_rg)
+
+#endif /* GL_ARB_texture_rg */
+
+/* ----------------------- GL_ARB_texture_rgb10_a2ui ----------------------- */
+
+#ifndef GL_ARB_texture_rgb10_a2ui
+#define GL_ARB_texture_rgb10_a2ui 1
+
+#define GL_RGB10_A2UI 0x906F
+
+#define GLEW_ARB_texture_rgb10_a2ui GLEW_GET_VAR(__GLEW_ARB_texture_rgb10_a2ui)
+
+#endif /* GL_ARB_texture_rgb10_a2ui */
+
+/* ------------------------ GL_ARB_texture_stencil8 ------------------------ */
+
+#ifndef GL_ARB_texture_stencil8
+#define GL_ARB_texture_stencil8 1
+
+#define GL_STENCIL_INDEX 0x1901
+#define GL_STENCIL_INDEX8 0x8D48
+
+#define GLEW_ARB_texture_stencil8 GLEW_GET_VAR(__GLEW_ARB_texture_stencil8)
+
+#endif /* GL_ARB_texture_stencil8 */
+
+/* ------------------------- GL_ARB_texture_storage ------------------------ */
+
+#ifndef GL_ARB_texture_storage
+#define GL_ARB_texture_storage 1
+
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+
+#define glTexStorage1D GLEW_GET_FUN(__glewTexStorage1D)
+#define glTexStorage2D GLEW_GET_FUN(__glewTexStorage2D)
+#define glTexStorage3D GLEW_GET_FUN(__glewTexStorage3D)
+#define glTextureStorage1DEXT GLEW_GET_FUN(__glewTextureStorage1DEXT)
+#define glTextureStorage2DEXT GLEW_GET_FUN(__glewTextureStorage2DEXT)
+#define glTextureStorage3DEXT GLEW_GET_FUN(__glewTextureStorage3DEXT)
+
+#define GLEW_ARB_texture_storage GLEW_GET_VAR(__GLEW_ARB_texture_storage)
+
+#endif /* GL_ARB_texture_storage */
+
+/* ------------------- GL_ARB_texture_storage_multisample ------------------ */
+
+#ifndef GL_ARB_texture_storage_multisample
+#define GL_ARB_texture_storage_multisample 1
+
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+
+#define glTexStorage2DMultisample GLEW_GET_FUN(__glewTexStorage2DMultisample)
+#define glTexStorage3DMultisample GLEW_GET_FUN(__glewTexStorage3DMultisample)
+#define glTextureStorage2DMultisampleEXT GLEW_GET_FUN(__glewTextureStorage2DMultisampleEXT)
+#define glTextureStorage3DMultisampleEXT GLEW_GET_FUN(__glewTextureStorage3DMultisampleEXT)
+
+#define GLEW_ARB_texture_storage_multisample GLEW_GET_VAR(__GLEW_ARB_texture_storage_multisample)
+
+#endif /* GL_ARB_texture_storage_multisample */
+
+/* ------------------------- GL_ARB_texture_swizzle ------------------------ */
+
+#ifndef GL_ARB_texture_swizzle
+#define GL_ARB_texture_swizzle 1
+
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+
+#define GLEW_ARB_texture_swizzle GLEW_GET_VAR(__GLEW_ARB_texture_swizzle)
+
+#endif /* GL_ARB_texture_swizzle */
+
+/* -------------------------- GL_ARB_texture_view -------------------------- */
+
+#ifndef GL_ARB_texture_view
+#define GL_ARB_texture_view 1
+
+#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB
+#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC
+#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD
+#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+
+typedef void (GLAPIENTRY * PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+
+#define glTextureView GLEW_GET_FUN(__glewTextureView)
+
+#define GLEW_ARB_texture_view GLEW_GET_VAR(__GLEW_ARB_texture_view)
+
+#endif /* GL_ARB_texture_view */
+
+/* --------------------------- GL_ARB_timer_query -------------------------- */
+
+#ifndef GL_ARB_timer_query
+#define GL_ARB_timer_query 1
+
+#define GL_TIME_ELAPSED 0x88BF
+#define GL_TIMESTAMP 0x8E28
+
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64* params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64* params);
+typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target);
+
+#define glGetQueryObjecti64v GLEW_GET_FUN(__glewGetQueryObjecti64v)
+#define glGetQueryObjectui64v GLEW_GET_FUN(__glewGetQueryObjectui64v)
+#define glQueryCounter GLEW_GET_FUN(__glewQueryCounter)
+
+#define GLEW_ARB_timer_query GLEW_GET_VAR(__GLEW_ARB_timer_query)
+
+#endif /* GL_ARB_timer_query */
+
+/* ----------------------- GL_ARB_transform_feedback2 ---------------------- */
+
+#ifndef GL_ARB_transform_feedback2
+#define GL_ARB_transform_feedback2 1
+
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+
+typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id);
+typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids);
+typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKPROC) (void);
+typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKPROC) (void);
+
+#define glBindTransformFeedback GLEW_GET_FUN(__glewBindTransformFeedback)
+#define glDeleteTransformFeedbacks GLEW_GET_FUN(__glewDeleteTransformFeedbacks)
+#define glDrawTransformFeedback GLEW_GET_FUN(__glewDrawTransformFeedback)
+#define glGenTransformFeedbacks GLEW_GET_FUN(__glewGenTransformFeedbacks)
+#define glIsTransformFeedback GLEW_GET_FUN(__glewIsTransformFeedback)
+#define glPauseTransformFeedback GLEW_GET_FUN(__glewPauseTransformFeedback)
+#define glResumeTransformFeedback GLEW_GET_FUN(__glewResumeTransformFeedback)
+
+#define GLEW_ARB_transform_feedback2 GLEW_GET_VAR(__GLEW_ARB_transform_feedback2)
+
+#endif /* GL_ARB_transform_feedback2 */
+
+/* ----------------------- GL_ARB_transform_feedback3 ---------------------- */
+
+#ifndef GL_ARB_transform_feedback3
+#define GL_ARB_transform_feedback3 1
+
+#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
+#define GL_MAX_VERTEX_STREAMS 0x8E71
+
+typedef void (GLAPIENTRY * PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id);
+typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream);
+typedef void (GLAPIENTRY * PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index);
+typedef void (GLAPIENTRY * PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params);
+
+#define glBeginQueryIndexed GLEW_GET_FUN(__glewBeginQueryIndexed)
+#define glDrawTransformFeedbackStream GLEW_GET_FUN(__glewDrawTransformFeedbackStream)
+#define glEndQueryIndexed GLEW_GET_FUN(__glewEndQueryIndexed)
+#define glGetQueryIndexediv GLEW_GET_FUN(__glewGetQueryIndexediv)
+
+#define GLEW_ARB_transform_feedback3 GLEW_GET_VAR(__GLEW_ARB_transform_feedback3)
+
+#endif /* GL_ARB_transform_feedback3 */
+
+/* ------------------ GL_ARB_transform_feedback_instanced ------------------ */
+
+#ifndef GL_ARB_transform_feedback_instanced
+#define GL_ARB_transform_feedback_instanced 1
+
+typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei primcount);
+
+#define glDrawTransformFeedbackInstanced GLEW_GET_FUN(__glewDrawTransformFeedbackInstanced)
+#define glDrawTransformFeedbackStreamInstanced GLEW_GET_FUN(__glewDrawTransformFeedbackStreamInstanced)
+
+#define GLEW_ARB_transform_feedback_instanced GLEW_GET_VAR(__GLEW_ARB_transform_feedback_instanced)
+
+#endif /* GL_ARB_transform_feedback_instanced */
+
+/* ------------------------ GL_ARB_transpose_matrix ------------------------ */
+
+#ifndef GL_ARB_transpose_matrix
+#define GL_ARB_transpose_matrix 1
+
+#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6
+
+typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]);
+typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]);
+typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (GLdouble m[16]);
+typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (GLfloat m[16]);
+
+#define glLoadTransposeMatrixdARB GLEW_GET_FUN(__glewLoadTransposeMatrixdARB)
+#define glLoadTransposeMatrixfARB GLEW_GET_FUN(__glewLoadTransposeMatrixfARB)
+#define glMultTransposeMatrixdARB GLEW_GET_FUN(__glewMultTransposeMatrixdARB)
+#define glMultTransposeMatrixfARB GLEW_GET_FUN(__glewMultTransposeMatrixfARB)
+
+#define GLEW_ARB_transpose_matrix GLEW_GET_VAR(__GLEW_ARB_transpose_matrix)
+
+#endif /* GL_ARB_transpose_matrix */
+
+/* ---------------------- GL_ARB_uniform_buffer_object --------------------- */
+
+#ifndef GL_ARB_uniform_buffer_object
+#define GL_ARB_uniform_buffer_object 1
+
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_INVALID_INDEX 0xFFFFFFFF
+
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformName);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint* data);
+typedef GLuint (GLAPIENTRY * PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar* uniformBlockName);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar** uniformNames, GLuint* uniformIndices);
+typedef void (GLAPIENTRY * PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+
+#define glBindBufferBase GLEW_GET_FUN(__glewBindBufferBase)
+#define glBindBufferRange GLEW_GET_FUN(__glewBindBufferRange)
+#define glGetActiveUniformBlockName GLEW_GET_FUN(__glewGetActiveUniformBlockName)
+#define glGetActiveUniformBlockiv GLEW_GET_FUN(__glewGetActiveUniformBlockiv)
+#define glGetActiveUniformName GLEW_GET_FUN(__glewGetActiveUniformName)
+#define glGetActiveUniformsiv GLEW_GET_FUN(__glewGetActiveUniformsiv)
+#define glGetIntegeri_v GLEW_GET_FUN(__glewGetIntegeri_v)
+#define glGetUniformBlockIndex GLEW_GET_FUN(__glewGetUniformBlockIndex)
+#define glGetUniformIndices GLEW_GET_FUN(__glewGetUniformIndices)
+#define glUniformBlockBinding GLEW_GET_FUN(__glewUniformBlockBinding)
+
+#define GLEW_ARB_uniform_buffer_object GLEW_GET_VAR(__GLEW_ARB_uniform_buffer_object)
+
+#endif /* GL_ARB_uniform_buffer_object */
+
+/* ------------------------ GL_ARB_vertex_array_bgra ----------------------- */
+
+#ifndef GL_ARB_vertex_array_bgra
+#define GL_ARB_vertex_array_bgra 1
+
+#define GL_BGRA 0x80E1
+
+#define GLEW_ARB_vertex_array_bgra GLEW_GET_VAR(__GLEW_ARB_vertex_array_bgra)
+
+#endif /* GL_ARB_vertex_array_bgra */
+
+/* ----------------------- GL_ARB_vertex_array_object ---------------------- */
+
+#ifndef GL_ARB_vertex_array_object
+#define GL_ARB_vertex_array_object 1
+
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+
+typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array);
+typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint* arrays);
+typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays);
+typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYPROC) (GLuint array);
+
+#define glBindVertexArray GLEW_GET_FUN(__glewBindVertexArray)
+#define glDeleteVertexArrays GLEW_GET_FUN(__glewDeleteVertexArrays)
+#define glGenVertexArrays GLEW_GET_FUN(__glewGenVertexArrays)
+#define glIsVertexArray GLEW_GET_FUN(__glewIsVertexArray)
+
+#define GLEW_ARB_vertex_array_object GLEW_GET_VAR(__GLEW_ARB_vertex_array_object)
+
+#endif /* GL_ARB_vertex_array_object */
+
+/* ----------------------- GL_ARB_vertex_attrib_64bit ---------------------- */
+
+#ifndef GL_ARB_vertex_attrib_64bit
+#define GL_ARB_vertex_attrib_64bit 1
+
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer);
+
+#define glGetVertexAttribLdv GLEW_GET_FUN(__glewGetVertexAttribLdv)
+#define glVertexAttribL1d GLEW_GET_FUN(__glewVertexAttribL1d)
+#define glVertexAttribL1dv GLEW_GET_FUN(__glewVertexAttribL1dv)
+#define glVertexAttribL2d GLEW_GET_FUN(__glewVertexAttribL2d)
+#define glVertexAttribL2dv GLEW_GET_FUN(__glewVertexAttribL2dv)
+#define glVertexAttribL3d GLEW_GET_FUN(__glewVertexAttribL3d)
+#define glVertexAttribL3dv GLEW_GET_FUN(__glewVertexAttribL3dv)
+#define glVertexAttribL4d GLEW_GET_FUN(__glewVertexAttribL4d)
+#define glVertexAttribL4dv GLEW_GET_FUN(__glewVertexAttribL4dv)
+#define glVertexAttribLPointer GLEW_GET_FUN(__glewVertexAttribLPointer)
+
+#define GLEW_ARB_vertex_attrib_64bit GLEW_GET_VAR(__GLEW_ARB_vertex_attrib_64bit)
+
+#endif /* GL_ARB_vertex_attrib_64bit */
+
+/* ---------------------- GL_ARB_vertex_attrib_binding --------------------- */
+
+#ifndef GL_ARB_vertex_attrib_binding
+#define GL_ARB_vertex_attrib_binding 1
+
+#define GL_VERTEX_ATTRIB_BINDING 0x82D4
+#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5
+#define GL_VERTEX_BINDING_DIVISOR 0x82D6
+#define GL_VERTEX_BINDING_OFFSET 0x82D7
+#define GL_VERTEX_BINDING_STRIDE 0x82D8
+#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9
+#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA
+
+typedef void (GLAPIENTRY * PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GLAPIENTRY * PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor);
+
+#define glBindVertexBuffer GLEW_GET_FUN(__glewBindVertexBuffer)
+#define glVertexAttribBinding GLEW_GET_FUN(__glewVertexAttribBinding)
+#define glVertexAttribFormat GLEW_GET_FUN(__glewVertexAttribFormat)
+#define glVertexAttribIFormat GLEW_GET_FUN(__glewVertexAttribIFormat)
+#define glVertexAttribLFormat GLEW_GET_FUN(__glewVertexAttribLFormat)
+#define glVertexBindingDivisor GLEW_GET_FUN(__glewVertexBindingDivisor)
+
+#define GLEW_ARB_vertex_attrib_binding GLEW_GET_VAR(__GLEW_ARB_vertex_attrib_binding)
+
+#endif /* GL_ARB_vertex_attrib_binding */
+
+/* -------------------------- GL_ARB_vertex_blend -------------------------- */
+
+#ifndef GL_ARB_vertex_blend
+#define GL_ARB_vertex_blend 1
+
+#define GL_MODELVIEW0_ARB 0x1700
+#define GL_MODELVIEW1_ARB 0x850A
+#define GL_MAX_VERTEX_UNITS_ARB 0x86A4
+#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5
+#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6
+#define GL_VERTEX_BLEND_ARB 0x86A7
+#define GL_CURRENT_WEIGHT_ARB 0x86A8
+#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9
+#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA
+#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB
+#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC
+#define GL_WEIGHT_ARRAY_ARB 0x86AD
+#define GL_MODELVIEW2_ARB 0x8722
+#define GL_MODELVIEW3_ARB 0x8723
+#define GL_MODELVIEW4_ARB 0x8724
+#define GL_MODELVIEW5_ARB 0x8725
+#define GL_MODELVIEW6_ARB 0x8726
+#define GL_MODELVIEW7_ARB 0x8727
+#define GL_MODELVIEW8_ARB 0x8728
+#define GL_MODELVIEW9_ARB 0x8729
+#define GL_MODELVIEW10_ARB 0x872A
+#define GL_MODELVIEW11_ARB 0x872B
+#define GL_MODELVIEW12_ARB 0x872C
+#define GL_MODELVIEW13_ARB 0x872D
+#define GL_MODELVIEW14_ARB 0x872E
+#define GL_MODELVIEW15_ARB 0x872F
+#define GL_MODELVIEW16_ARB 0x8730
+#define GL_MODELVIEW17_ARB 0x8731
+#define GL_MODELVIEW18_ARB 0x8732
+#define GL_MODELVIEW19_ARB 0x8733
+#define GL_MODELVIEW20_ARB 0x8734
+#define GL_MODELVIEW21_ARB 0x8735
+#define GL_MODELVIEW22_ARB 0x8736
+#define GL_MODELVIEW23_ARB 0x8737
+#define GL_MODELVIEW24_ARB 0x8738
+#define GL_MODELVIEW25_ARB 0x8739
+#define GL_MODELVIEW26_ARB 0x873A
+#define GL_MODELVIEW27_ARB 0x873B
+#define GL_MODELVIEW28_ARB 0x873C
+#define GL_MODELVIEW29_ARB 0x873D
+#define GL_MODELVIEW30_ARB 0x873E
+#define GL_MODELVIEW31_ARB 0x873F
+
+typedef void (GLAPIENTRY * PFNGLVERTEXBLENDARBPROC) (GLint count);
+typedef void (GLAPIENTRY * PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLWEIGHTBVARBPROC) (GLint size, GLbyte *weights);
+typedef void (GLAPIENTRY * PFNGLWEIGHTDVARBPROC) (GLint size, GLdouble *weights);
+typedef void (GLAPIENTRY * PFNGLWEIGHTFVARBPROC) (GLint size, GLfloat *weights);
+typedef void (GLAPIENTRY * PFNGLWEIGHTIVARBPROC) (GLint size, GLint *weights);
+typedef void (GLAPIENTRY * PFNGLWEIGHTSVARBPROC) (GLint size, GLshort *weights);
+typedef void (GLAPIENTRY * PFNGLWEIGHTUBVARBPROC) (GLint size, GLubyte *weights);
+typedef void (GLAPIENTRY * PFNGLWEIGHTUIVARBPROC) (GLint size, GLuint *weights);
+typedef void (GLAPIENTRY * PFNGLWEIGHTUSVARBPROC) (GLint size, GLushort *weights);
+
+#define glVertexBlendARB GLEW_GET_FUN(__glewVertexBlendARB)
+#define glWeightPointerARB GLEW_GET_FUN(__glewWeightPointerARB)
+#define glWeightbvARB GLEW_GET_FUN(__glewWeightbvARB)
+#define glWeightdvARB GLEW_GET_FUN(__glewWeightdvARB)
+#define glWeightfvARB GLEW_GET_FUN(__glewWeightfvARB)
+#define glWeightivARB GLEW_GET_FUN(__glewWeightivARB)
+#define glWeightsvARB GLEW_GET_FUN(__glewWeightsvARB)
+#define glWeightubvARB GLEW_GET_FUN(__glewWeightubvARB)
+#define glWeightuivARB GLEW_GET_FUN(__glewWeightuivARB)
+#define glWeightusvARB GLEW_GET_FUN(__glewWeightusvARB)
+
+#define GLEW_ARB_vertex_blend GLEW_GET_VAR(__GLEW_ARB_vertex_blend)
+
+#endif /* GL_ARB_vertex_blend */
+
+/* ---------------------- GL_ARB_vertex_buffer_object ---------------------- */
+
+#ifndef GL_ARB_vertex_buffer_object
+#define GL_ARB_vertex_buffer_object 1
+
+#define GL_BUFFER_SIZE_ARB 0x8764
+#define GL_BUFFER_USAGE_ARB 0x8765
+#define GL_ARRAY_BUFFER_ARB 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
+#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
+#define GL_READ_ONLY_ARB 0x88B8
+#define GL_WRITE_ONLY_ARB 0x88B9
+#define GL_READ_WRITE_ARB 0x88BA
+#define GL_BUFFER_ACCESS_ARB 0x88BB
+#define GL_BUFFER_MAPPED_ARB 0x88BC
+#define GL_BUFFER_MAP_POINTER_ARB 0x88BD
+#define GL_STREAM_DRAW_ARB 0x88E0
+#define GL_STREAM_READ_ARB 0x88E1
+#define GL_STREAM_COPY_ARB 0x88E2
+#define GL_STATIC_DRAW_ARB 0x88E4
+#define GL_STATIC_READ_ARB 0x88E5
+#define GL_STATIC_COPY_ARB 0x88E6
+#define GL_DYNAMIC_DRAW_ARB 0x88E8
+#define GL_DYNAMIC_READ_ARB 0x88E9
+#define GL_DYNAMIC_COPY_ARB 0x88EA
+
+typedef ptrdiff_t GLintptrARB;
+typedef ptrdiff_t GLsizeiptrARB;
+
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
+typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint* buffers);
+typedef void (GLAPIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint* buffers);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid** params);
+typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data);
+typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERARBPROC) (GLuint buffer);
+typedef GLvoid * (GLAPIENTRY * PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access);
+typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERARBPROC) (GLenum target);
+
+#define glBindBufferARB GLEW_GET_FUN(__glewBindBufferARB)
+#define glBufferDataARB GLEW_GET_FUN(__glewBufferDataARB)
+#define glBufferSubDataARB GLEW_GET_FUN(__glewBufferSubDataARB)
+#define glDeleteBuffersARB GLEW_GET_FUN(__glewDeleteBuffersARB)
+#define glGenBuffersARB GLEW_GET_FUN(__glewGenBuffersARB)
+#define glGetBufferParameterivARB GLEW_GET_FUN(__glewGetBufferParameterivARB)
+#define glGetBufferPointervARB GLEW_GET_FUN(__glewGetBufferPointervARB)
+#define glGetBufferSubDataARB GLEW_GET_FUN(__glewGetBufferSubDataARB)
+#define glIsBufferARB GLEW_GET_FUN(__glewIsBufferARB)
+#define glMapBufferARB GLEW_GET_FUN(__glewMapBufferARB)
+#define glUnmapBufferARB GLEW_GET_FUN(__glewUnmapBufferARB)
+
+#define GLEW_ARB_vertex_buffer_object GLEW_GET_VAR(__GLEW_ARB_vertex_buffer_object)
+
+#endif /* GL_ARB_vertex_buffer_object */
+
+/* ------------------------- GL_ARB_vertex_program ------------------------- */
+
+#ifndef GL_ARB_vertex_program
+#define GL_ARB_vertex_program 1
+
+#define GL_COLOR_SUM_ARB 0x8458
+#define GL_VERTEX_PROGRAM_ARB 0x8620
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625
+#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626
+#define GL_PROGRAM_LENGTH_ARB 0x8627
+#define GL_PROGRAM_STRING_ARB 0x8628
+#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E
+#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F
+#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640
+#define GL_CURRENT_MATRIX_ARB 0x8641
+#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645
+#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B
+#define GL_PROGRAM_BINDING_ARB 0x8677
+#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A
+#define GL_PROGRAM_ERROR_STRING_ARB 0x8874
+#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875
+#define GL_PROGRAM_FORMAT_ARB 0x8876
+#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0
+#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1
+#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2
+#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3
+#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4
+#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5
+#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6
+#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7
+#define GL_PROGRAM_PARAMETERS_ARB 0x88A8
+#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9
+#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA
+#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB
+#define GL_PROGRAM_ATTRIBS_ARB 0x88AC
+#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD
+#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE
+#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF
+#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0
+#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1
+#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2
+#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3
+#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4
+#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5
+#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6
+#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7
+#define GL_MATRIX0_ARB 0x88C0
+#define GL_MATRIX1_ARB 0x88C1
+#define GL_MATRIX2_ARB 0x88C2
+#define GL_MATRIX3_ARB 0x88C3
+#define GL_MATRIX4_ARB 0x88C4
+#define GL_MATRIX5_ARB 0x88C5
+#define GL_MATRIX6_ARB 0x88C6
+#define GL_MATRIX7_ARB 0x88C7
+#define GL_MATRIX8_ARB 0x88C8
+#define GL_MATRIX9_ARB 0x88C9
+#define GL_MATRIX10_ARB 0x88CA
+#define GL_MATRIX11_ARB 0x88CB
+#define GL_MATRIX12_ARB 0x88CC
+#define GL_MATRIX13_ARB 0x88CD
+#define GL_MATRIX14_ARB 0x88CE
+#define GL_MATRIX15_ARB 0x88CF
+#define GL_MATRIX16_ARB 0x88D0
+#define GL_MATRIX17_ARB 0x88D1
+#define GL_MATRIX18_ARB 0x88D2
+#define GL_MATRIX19_ARB 0x88D3
+#define GL_MATRIX20_ARB 0x88D4
+#define GL_MATRIX21_ARB 0x88D5
+#define GL_MATRIX22_ARB 0x88D6
+#define GL_MATRIX23_ARB 0x88D7
+#define GL_MATRIX24_ARB 0x88D8
+#define GL_MATRIX25_ARB 0x88D9
+#define GL_MATRIX26_ARB 0x88DA
+#define GL_MATRIX27_ARB 0x88DB
+#define GL_MATRIX28_ARB 0x88DC
+#define GL_MATRIX29_ARB 0x88DD
+#define GL_MATRIX30_ARB 0x88DE
+#define GL_MATRIX31_ARB 0x88DF
+
+typedef void (GLAPIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program);
+typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint* programs);
+typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
+typedef void (GLAPIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint* programs);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid** pointer);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMARBPROC) (GLuint program);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+
+#define glBindProgramARB GLEW_GET_FUN(__glewBindProgramARB)
+#define glDeleteProgramsARB GLEW_GET_FUN(__glewDeleteProgramsARB)
+#define glDisableVertexAttribArrayARB GLEW_GET_FUN(__glewDisableVertexAttribArrayARB)
+#define glEnableVertexAttribArrayARB GLEW_GET_FUN(__glewEnableVertexAttribArrayARB)
+#define glGenProgramsARB GLEW_GET_FUN(__glewGenProgramsARB)
+#define glGetProgramEnvParameterdvARB GLEW_GET_FUN(__glewGetProgramEnvParameterdvARB)
+#define glGetProgramEnvParameterfvARB GLEW_GET_FUN(__glewGetProgramEnvParameterfvARB)
+#define glGetProgramLocalParameterdvARB GLEW_GET_FUN(__glewGetProgramLocalParameterdvARB)
+#define glGetProgramLocalParameterfvARB GLEW_GET_FUN(__glewGetProgramLocalParameterfvARB)
+#define glGetProgramStringARB GLEW_GET_FUN(__glewGetProgramStringARB)
+#define glGetProgramivARB GLEW_GET_FUN(__glewGetProgramivARB)
+#define glGetVertexAttribPointervARB GLEW_GET_FUN(__glewGetVertexAttribPointervARB)
+#define glGetVertexAttribdvARB GLEW_GET_FUN(__glewGetVertexAttribdvARB)
+#define glGetVertexAttribfvARB GLEW_GET_FUN(__glewGetVertexAttribfvARB)
+#define glGetVertexAttribivARB GLEW_GET_FUN(__glewGetVertexAttribivARB)
+#define glIsProgramARB GLEW_GET_FUN(__glewIsProgramARB)
+#define glProgramEnvParameter4dARB GLEW_GET_FUN(__glewProgramEnvParameter4dARB)
+#define glProgramEnvParameter4dvARB GLEW_GET_FUN(__glewProgramEnvParameter4dvARB)
+#define glProgramEnvParameter4fARB GLEW_GET_FUN(__glewProgramEnvParameter4fARB)
+#define glProgramEnvParameter4fvARB GLEW_GET_FUN(__glewProgramEnvParameter4fvARB)
+#define glProgramLocalParameter4dARB GLEW_GET_FUN(__glewProgramLocalParameter4dARB)
+#define glProgramLocalParameter4dvARB GLEW_GET_FUN(__glewProgramLocalParameter4dvARB)
+#define glProgramLocalParameter4fARB GLEW_GET_FUN(__glewProgramLocalParameter4fARB)
+#define glProgramLocalParameter4fvARB GLEW_GET_FUN(__glewProgramLocalParameter4fvARB)
+#define glProgramStringARB GLEW_GET_FUN(__glewProgramStringARB)
+#define glVertexAttrib1dARB GLEW_GET_FUN(__glewVertexAttrib1dARB)
+#define glVertexAttrib1dvARB GLEW_GET_FUN(__glewVertexAttrib1dvARB)
+#define glVertexAttrib1fARB GLEW_GET_FUN(__glewVertexAttrib1fARB)
+#define glVertexAttrib1fvARB GLEW_GET_FUN(__glewVertexAttrib1fvARB)
+#define glVertexAttrib1sARB GLEW_GET_FUN(__glewVertexAttrib1sARB)
+#define glVertexAttrib1svARB GLEW_GET_FUN(__glewVertexAttrib1svARB)
+#define glVertexAttrib2dARB GLEW_GET_FUN(__glewVertexAttrib2dARB)
+#define glVertexAttrib2dvARB GLEW_GET_FUN(__glewVertexAttrib2dvARB)
+#define glVertexAttrib2fARB GLEW_GET_FUN(__glewVertexAttrib2fARB)
+#define glVertexAttrib2fvARB GLEW_GET_FUN(__glewVertexAttrib2fvARB)
+#define glVertexAttrib2sARB GLEW_GET_FUN(__glewVertexAttrib2sARB)
+#define glVertexAttrib2svARB GLEW_GET_FUN(__glewVertexAttrib2svARB)
+#define glVertexAttrib3dARB GLEW_GET_FUN(__glewVertexAttrib3dARB)
+#define glVertexAttrib3dvARB GLEW_GET_FUN(__glewVertexAttrib3dvARB)
+#define glVertexAttrib3fARB GLEW_GET_FUN(__glewVertexAttrib3fARB)
+#define glVertexAttrib3fvARB GLEW_GET_FUN(__glewVertexAttrib3fvARB)
+#define glVertexAttrib3sARB GLEW_GET_FUN(__glewVertexAttrib3sARB)
+#define glVertexAttrib3svARB GLEW_GET_FUN(__glewVertexAttrib3svARB)
+#define glVertexAttrib4NbvARB GLEW_GET_FUN(__glewVertexAttrib4NbvARB)
+#define glVertexAttrib4NivARB GLEW_GET_FUN(__glewVertexAttrib4NivARB)
+#define glVertexAttrib4NsvARB GLEW_GET_FUN(__glewVertexAttrib4NsvARB)
+#define glVertexAttrib4NubARB GLEW_GET_FUN(__glewVertexAttrib4NubARB)
+#define glVertexAttrib4NubvARB GLEW_GET_FUN(__glewVertexAttrib4NubvARB)
+#define glVertexAttrib4NuivARB GLEW_GET_FUN(__glewVertexAttrib4NuivARB)
+#define glVertexAttrib4NusvARB GLEW_GET_FUN(__glewVertexAttrib4NusvARB)
+#define glVertexAttrib4bvARB GLEW_GET_FUN(__glewVertexAttrib4bvARB)
+#define glVertexAttrib4dARB GLEW_GET_FUN(__glewVertexAttrib4dARB)
+#define glVertexAttrib4dvARB GLEW_GET_FUN(__glewVertexAttrib4dvARB)
+#define glVertexAttrib4fARB GLEW_GET_FUN(__glewVertexAttrib4fARB)
+#define glVertexAttrib4fvARB GLEW_GET_FUN(__glewVertexAttrib4fvARB)
+#define glVertexAttrib4ivARB GLEW_GET_FUN(__glewVertexAttrib4ivARB)
+#define glVertexAttrib4sARB GLEW_GET_FUN(__glewVertexAttrib4sARB)
+#define glVertexAttrib4svARB GLEW_GET_FUN(__glewVertexAttrib4svARB)
+#define glVertexAttrib4ubvARB GLEW_GET_FUN(__glewVertexAttrib4ubvARB)
+#define glVertexAttrib4uivARB GLEW_GET_FUN(__glewVertexAttrib4uivARB)
+#define glVertexAttrib4usvARB GLEW_GET_FUN(__glewVertexAttrib4usvARB)
+#define glVertexAttribPointerARB GLEW_GET_FUN(__glewVertexAttribPointerARB)
+
+#define GLEW_ARB_vertex_program GLEW_GET_VAR(__GLEW_ARB_vertex_program)
+
+#endif /* GL_ARB_vertex_program */
+
+/* -------------------------- GL_ARB_vertex_shader ------------------------- */
+
+#ifndef GL_ARB_vertex_shader
+#define GL_ARB_vertex_shader 1
+
+#define GL_VERTEX_SHADER_ARB 0x8B31
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A
+#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D
+#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89
+#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A
+
+typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB* name);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei* length, GLint *size, GLenum *type, GLcharARB *name);
+typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB* name);
+
+#define glBindAttribLocationARB GLEW_GET_FUN(__glewBindAttribLocationARB)
+#define glGetActiveAttribARB GLEW_GET_FUN(__glewGetActiveAttribARB)
+#define glGetAttribLocationARB GLEW_GET_FUN(__glewGetAttribLocationARB)
+
+#define GLEW_ARB_vertex_shader GLEW_GET_VAR(__GLEW_ARB_vertex_shader)
+
+#endif /* GL_ARB_vertex_shader */
+
+/* ------------------- GL_ARB_vertex_type_10f_11f_11f_rev ------------------ */
+
+#ifndef GL_ARB_vertex_type_10f_11f_11f_rev
+#define GL_ARB_vertex_type_10f_11f_11f_rev 1
+
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+
+#define GLEW_ARB_vertex_type_10f_11f_11f_rev GLEW_GET_VAR(__GLEW_ARB_vertex_type_10f_11f_11f_rev)
+
+#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */
+
+/* ------------------- GL_ARB_vertex_type_2_10_10_10_rev ------------------- */
+
+#ifndef GL_ARB_vertex_type_2_10_10_10_rev
+#define GL_ARB_vertex_type_2_10_10_10_rev 1
+
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_INT_2_10_10_10_REV 0x8D9F
+
+typedef void (GLAPIENTRY * PFNGLCOLORP3UIPROC) (GLenum type, GLuint color);
+typedef void (GLAPIENTRY * PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint* color);
+typedef void (GLAPIENTRY * PFNGLCOLORP4UIPROC) (GLenum type, GLuint color);
+typedef void (GLAPIENTRY * PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint* color);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint* color);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint* coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value);
+typedef void (GLAPIENTRY * PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value);
+typedef void (GLAPIENTRY * PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value);
+typedef void (GLAPIENTRY * PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint* value);
+
+#define glColorP3ui GLEW_GET_FUN(__glewColorP3ui)
+#define glColorP3uiv GLEW_GET_FUN(__glewColorP3uiv)
+#define glColorP4ui GLEW_GET_FUN(__glewColorP4ui)
+#define glColorP4uiv GLEW_GET_FUN(__glewColorP4uiv)
+#define glMultiTexCoordP1ui GLEW_GET_FUN(__glewMultiTexCoordP1ui)
+#define glMultiTexCoordP1uiv GLEW_GET_FUN(__glewMultiTexCoordP1uiv)
+#define glMultiTexCoordP2ui GLEW_GET_FUN(__glewMultiTexCoordP2ui)
+#define glMultiTexCoordP2uiv GLEW_GET_FUN(__glewMultiTexCoordP2uiv)
+#define glMultiTexCoordP3ui GLEW_GET_FUN(__glewMultiTexCoordP3ui)
+#define glMultiTexCoordP3uiv GLEW_GET_FUN(__glewMultiTexCoordP3uiv)
+#define glMultiTexCoordP4ui GLEW_GET_FUN(__glewMultiTexCoordP4ui)
+#define glMultiTexCoordP4uiv GLEW_GET_FUN(__glewMultiTexCoordP4uiv)
+#define glNormalP3ui GLEW_GET_FUN(__glewNormalP3ui)
+#define glNormalP3uiv GLEW_GET_FUN(__glewNormalP3uiv)
+#define glSecondaryColorP3ui GLEW_GET_FUN(__glewSecondaryColorP3ui)
+#define glSecondaryColorP3uiv GLEW_GET_FUN(__glewSecondaryColorP3uiv)
+#define glTexCoordP1ui GLEW_GET_FUN(__glewTexCoordP1ui)
+#define glTexCoordP1uiv GLEW_GET_FUN(__glewTexCoordP1uiv)
+#define glTexCoordP2ui GLEW_GET_FUN(__glewTexCoordP2ui)
+#define glTexCoordP2uiv GLEW_GET_FUN(__glewTexCoordP2uiv)
+#define glTexCoordP3ui GLEW_GET_FUN(__glewTexCoordP3ui)
+#define glTexCoordP3uiv GLEW_GET_FUN(__glewTexCoordP3uiv)
+#define glTexCoordP4ui GLEW_GET_FUN(__glewTexCoordP4ui)
+#define glTexCoordP4uiv GLEW_GET_FUN(__glewTexCoordP4uiv)
+#define glVertexAttribP1ui GLEW_GET_FUN(__glewVertexAttribP1ui)
+#define glVertexAttribP1uiv GLEW_GET_FUN(__glewVertexAttribP1uiv)
+#define glVertexAttribP2ui GLEW_GET_FUN(__glewVertexAttribP2ui)
+#define glVertexAttribP2uiv GLEW_GET_FUN(__glewVertexAttribP2uiv)
+#define glVertexAttribP3ui GLEW_GET_FUN(__glewVertexAttribP3ui)
+#define glVertexAttribP3uiv GLEW_GET_FUN(__glewVertexAttribP3uiv)
+#define glVertexAttribP4ui GLEW_GET_FUN(__glewVertexAttribP4ui)
+#define glVertexAttribP4uiv GLEW_GET_FUN(__glewVertexAttribP4uiv)
+#define glVertexP2ui GLEW_GET_FUN(__glewVertexP2ui)
+#define glVertexP2uiv GLEW_GET_FUN(__glewVertexP2uiv)
+#define glVertexP3ui GLEW_GET_FUN(__glewVertexP3ui)
+#define glVertexP3uiv GLEW_GET_FUN(__glewVertexP3uiv)
+#define glVertexP4ui GLEW_GET_FUN(__glewVertexP4ui)
+#define glVertexP4uiv GLEW_GET_FUN(__glewVertexP4uiv)
+
+#define GLEW_ARB_vertex_type_2_10_10_10_rev GLEW_GET_VAR(__GLEW_ARB_vertex_type_2_10_10_10_rev)
+
+#endif /* GL_ARB_vertex_type_2_10_10_10_rev */
+
+/* ------------------------- GL_ARB_viewport_array ------------------------- */
+
+#ifndef GL_ARB_viewport_array
+#define GL_ARB_viewport_array 1
+
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_VIEWPORT 0x0BA2
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_MAX_VIEWPORTS 0x825B
+#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C
+#define GL_VIEWPORT_BOUNDS_RANGE 0x825D
+#define GL_LAYER_PROVOKING_VERTEX 0x825E
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F
+#define GL_UNDEFINED_VERTEX 0x8260
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_PROVOKING_VERTEX 0x8E4F
+
+typedef void (GLAPIENTRY * PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLclampd * v);
+typedef void (GLAPIENTRY * PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLclampd n, GLclampd f);
+typedef void (GLAPIENTRY * PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble* data);
+typedef void (GLAPIENTRY * PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat* data);
+typedef void (GLAPIENTRY * PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint * v);
+typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint * v);
+typedef void (GLAPIENTRY * PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat * v);
+typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+typedef void (GLAPIENTRY * PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat * v);
+
+#define glDepthRangeArrayv GLEW_GET_FUN(__glewDepthRangeArrayv)
+#define glDepthRangeIndexed GLEW_GET_FUN(__glewDepthRangeIndexed)
+#define glGetDoublei_v GLEW_GET_FUN(__glewGetDoublei_v)
+#define glGetFloati_v GLEW_GET_FUN(__glewGetFloati_v)
+#define glScissorArrayv GLEW_GET_FUN(__glewScissorArrayv)
+#define glScissorIndexed GLEW_GET_FUN(__glewScissorIndexed)
+#define glScissorIndexedv GLEW_GET_FUN(__glewScissorIndexedv)
+#define glViewportArrayv GLEW_GET_FUN(__glewViewportArrayv)
+#define glViewportIndexedf GLEW_GET_FUN(__glewViewportIndexedf)
+#define glViewportIndexedfv GLEW_GET_FUN(__glewViewportIndexedfv)
+
+#define GLEW_ARB_viewport_array GLEW_GET_VAR(__GLEW_ARB_viewport_array)
+
+#endif /* GL_ARB_viewport_array */
+
+/* --------------------------- GL_ARB_window_pos --------------------------- */
+
+#ifndef GL_ARB_window_pos
+#define GL_ARB_window_pos 1
+
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVARBPROC) (const GLdouble* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVARBPROC) (const GLfloat* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVARBPROC) (const GLint* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVARBPROC) (const GLshort* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVARBPROC) (const GLdouble* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVARBPROC) (const GLfloat* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVARBPROC) (const GLint* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVARBPROC) (const GLshort* p);
+
+#define glWindowPos2dARB GLEW_GET_FUN(__glewWindowPos2dARB)
+#define glWindowPos2dvARB GLEW_GET_FUN(__glewWindowPos2dvARB)
+#define glWindowPos2fARB GLEW_GET_FUN(__glewWindowPos2fARB)
+#define glWindowPos2fvARB GLEW_GET_FUN(__glewWindowPos2fvARB)
+#define glWindowPos2iARB GLEW_GET_FUN(__glewWindowPos2iARB)
+#define glWindowPos2ivARB GLEW_GET_FUN(__glewWindowPos2ivARB)
+#define glWindowPos2sARB GLEW_GET_FUN(__glewWindowPos2sARB)
+#define glWindowPos2svARB GLEW_GET_FUN(__glewWindowPos2svARB)
+#define glWindowPos3dARB GLEW_GET_FUN(__glewWindowPos3dARB)
+#define glWindowPos3dvARB GLEW_GET_FUN(__glewWindowPos3dvARB)
+#define glWindowPos3fARB GLEW_GET_FUN(__glewWindowPos3fARB)
+#define glWindowPos3fvARB GLEW_GET_FUN(__glewWindowPos3fvARB)
+#define glWindowPos3iARB GLEW_GET_FUN(__glewWindowPos3iARB)
+#define glWindowPos3ivARB GLEW_GET_FUN(__glewWindowPos3ivARB)
+#define glWindowPos3sARB GLEW_GET_FUN(__glewWindowPos3sARB)
+#define glWindowPos3svARB GLEW_GET_FUN(__glewWindowPos3svARB)
+
+#define GLEW_ARB_window_pos GLEW_GET_VAR(__GLEW_ARB_window_pos)
+
+#endif /* GL_ARB_window_pos */
+
+/* ------------------------- GL_ATIX_point_sprites ------------------------- */
+
+#ifndef GL_ATIX_point_sprites
+#define GL_ATIX_point_sprites 1
+
+#define GL_TEXTURE_POINT_MODE_ATIX 0x60B0
+#define GL_TEXTURE_POINT_ONE_COORD_ATIX 0x60B1
+#define GL_TEXTURE_POINT_SPRITE_ATIX 0x60B2
+#define GL_POINT_SPRITE_CULL_MODE_ATIX 0x60B3
+#define GL_POINT_SPRITE_CULL_CENTER_ATIX 0x60B4
+#define GL_POINT_SPRITE_CULL_CLIP_ATIX 0x60B5
+
+#define GLEW_ATIX_point_sprites GLEW_GET_VAR(__GLEW_ATIX_point_sprites)
+
+#endif /* GL_ATIX_point_sprites */
+
+/* ---------------------- GL_ATIX_texture_env_combine3 --------------------- */
+
+#ifndef GL_ATIX_texture_env_combine3
+#define GL_ATIX_texture_env_combine3 1
+
+#define GL_MODULATE_ADD_ATIX 0x8744
+#define GL_MODULATE_SIGNED_ADD_ATIX 0x8745
+#define GL_MODULATE_SUBTRACT_ATIX 0x8746
+
+#define GLEW_ATIX_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATIX_texture_env_combine3)
+
+#endif /* GL_ATIX_texture_env_combine3 */
+
+/* ----------------------- GL_ATIX_texture_env_route ----------------------- */
+
+#ifndef GL_ATIX_texture_env_route
+#define GL_ATIX_texture_env_route 1
+
+#define GL_SECONDARY_COLOR_ATIX 0x8747
+#define GL_TEXTURE_OUTPUT_RGB_ATIX 0x8748
+#define GL_TEXTURE_OUTPUT_ALPHA_ATIX 0x8749
+
+#define GLEW_ATIX_texture_env_route GLEW_GET_VAR(__GLEW_ATIX_texture_env_route)
+
+#endif /* GL_ATIX_texture_env_route */
+
+/* ---------------- GL_ATIX_vertex_shader_output_point_size ---------------- */
+
+#ifndef GL_ATIX_vertex_shader_output_point_size
+#define GL_ATIX_vertex_shader_output_point_size 1
+
+#define GL_OUTPUT_POINT_SIZE_ATIX 0x610E
+
+#define GLEW_ATIX_vertex_shader_output_point_size GLEW_GET_VAR(__GLEW_ATIX_vertex_shader_output_point_size)
+
+#endif /* GL_ATIX_vertex_shader_output_point_size */
+
+/* -------------------------- GL_ATI_draw_buffers -------------------------- */
+
+#ifndef GL_ATI_draw_buffers
+#define GL_ATI_draw_buffers 1
+
+#define GL_MAX_DRAW_BUFFERS_ATI 0x8824
+#define GL_DRAW_BUFFER0_ATI 0x8825
+#define GL_DRAW_BUFFER1_ATI 0x8826
+#define GL_DRAW_BUFFER2_ATI 0x8827
+#define GL_DRAW_BUFFER3_ATI 0x8828
+#define GL_DRAW_BUFFER4_ATI 0x8829
+#define GL_DRAW_BUFFER5_ATI 0x882A
+#define GL_DRAW_BUFFER6_ATI 0x882B
+#define GL_DRAW_BUFFER7_ATI 0x882C
+#define GL_DRAW_BUFFER8_ATI 0x882D
+#define GL_DRAW_BUFFER9_ATI 0x882E
+#define GL_DRAW_BUFFER10_ATI 0x882F
+#define GL_DRAW_BUFFER11_ATI 0x8830
+#define GL_DRAW_BUFFER12_ATI 0x8831
+#define GL_DRAW_BUFFER13_ATI 0x8832
+#define GL_DRAW_BUFFER14_ATI 0x8833
+#define GL_DRAW_BUFFER15_ATI 0x8834
+
+typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum* bufs);
+
+#define glDrawBuffersATI GLEW_GET_FUN(__glewDrawBuffersATI)
+
+#define GLEW_ATI_draw_buffers GLEW_GET_VAR(__GLEW_ATI_draw_buffers)
+
+#endif /* GL_ATI_draw_buffers */
+
+/* -------------------------- GL_ATI_element_array ------------------------- */
+
+#ifndef GL_ATI_element_array
+#define GL_ATI_element_array 1
+
+#define GL_ELEMENT_ARRAY_ATI 0x8768
+#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769
+#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A
+
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count);
+typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count);
+typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer);
+
+#define glDrawElementArrayATI GLEW_GET_FUN(__glewDrawElementArrayATI)
+#define glDrawRangeElementArrayATI GLEW_GET_FUN(__glewDrawRangeElementArrayATI)
+#define glElementPointerATI GLEW_GET_FUN(__glewElementPointerATI)
+
+#define GLEW_ATI_element_array GLEW_GET_VAR(__GLEW_ATI_element_array)
+
+#endif /* GL_ATI_element_array */
+
+/* ------------------------- GL_ATI_envmap_bumpmap ------------------------- */
+
+#ifndef GL_ATI_envmap_bumpmap
+#define GL_ATI_envmap_bumpmap 1
+
+#define GL_BUMP_ROT_MATRIX_ATI 0x8775
+#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776
+#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777
+#define GL_BUMP_TEX_UNITS_ATI 0x8778
+#define GL_DUDV_ATI 0x8779
+#define GL_DU8DV8_ATI 0x877A
+#define GL_BUMP_ENVMAP_ATI 0x877B
+#define GL_BUMP_TARGET_ATI 0x877C
+
+typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param);
+typedef void (GLAPIENTRY * PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param);
+typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param);
+typedef void (GLAPIENTRY * PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param);
+
+#define glGetTexBumpParameterfvATI GLEW_GET_FUN(__glewGetTexBumpParameterfvATI)
+#define glGetTexBumpParameterivATI GLEW_GET_FUN(__glewGetTexBumpParameterivATI)
+#define glTexBumpParameterfvATI GLEW_GET_FUN(__glewTexBumpParameterfvATI)
+#define glTexBumpParameterivATI GLEW_GET_FUN(__glewTexBumpParameterivATI)
+
+#define GLEW_ATI_envmap_bumpmap GLEW_GET_VAR(__GLEW_ATI_envmap_bumpmap)
+
+#endif /* GL_ATI_envmap_bumpmap */
+
+/* ------------------------- GL_ATI_fragment_shader ------------------------ */
+
+#ifndef GL_ATI_fragment_shader
+#define GL_ATI_fragment_shader 1
+
+#define GL_RED_BIT_ATI 0x00000001
+#define GL_2X_BIT_ATI 0x00000001
+#define GL_4X_BIT_ATI 0x00000002
+#define GL_GREEN_BIT_ATI 0x00000002
+#define GL_COMP_BIT_ATI 0x00000002
+#define GL_BLUE_BIT_ATI 0x00000004
+#define GL_8X_BIT_ATI 0x00000004
+#define GL_NEGATE_BIT_ATI 0x00000004
+#define GL_BIAS_BIT_ATI 0x00000008
+#define GL_HALF_BIT_ATI 0x00000008
+#define GL_QUARTER_BIT_ATI 0x00000010
+#define GL_EIGHTH_BIT_ATI 0x00000020
+#define GL_SATURATE_BIT_ATI 0x00000040
+#define GL_FRAGMENT_SHADER_ATI 0x8920
+#define GL_REG_0_ATI 0x8921
+#define GL_REG_1_ATI 0x8922
+#define GL_REG_2_ATI 0x8923
+#define GL_REG_3_ATI 0x8924
+#define GL_REG_4_ATI 0x8925
+#define GL_REG_5_ATI 0x8926
+#define GL_CON_0_ATI 0x8941
+#define GL_CON_1_ATI 0x8942
+#define GL_CON_2_ATI 0x8943
+#define GL_CON_3_ATI 0x8944
+#define GL_CON_4_ATI 0x8945
+#define GL_CON_5_ATI 0x8946
+#define GL_CON_6_ATI 0x8947
+#define GL_CON_7_ATI 0x8948
+#define GL_MOV_ATI 0x8961
+#define GL_ADD_ATI 0x8963
+#define GL_MUL_ATI 0x8964
+#define GL_SUB_ATI 0x8965
+#define GL_DOT3_ATI 0x8966
+#define GL_DOT4_ATI 0x8967
+#define GL_MAD_ATI 0x8968
+#define GL_LERP_ATI 0x8969
+#define GL_CND_ATI 0x896A
+#define GL_CND0_ATI 0x896B
+#define GL_DOT2_ADD_ATI 0x896C
+#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D
+#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E
+#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F
+#define GL_NUM_PASSES_ATI 0x8970
+#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971
+#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972
+#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973
+#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974
+#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975
+#define GL_SWIZZLE_STR_ATI 0x8976
+#define GL_SWIZZLE_STQ_ATI 0x8977
+#define GL_SWIZZLE_STR_DR_ATI 0x8978
+#define GL_SWIZZLE_STQ_DQ_ATI 0x8979
+#define GL_SWIZZLE_STRQ_ATI 0x897A
+#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B
+
+typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+typedef void (GLAPIENTRY * PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+typedef void (GLAPIENTRY * PFNGLBEGINFRAGMENTSHADERATIPROC) (void);
+typedef void (GLAPIENTRY * PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+typedef void (GLAPIENTRY * PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+typedef void (GLAPIENTRY * PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLENDFRAGMENTSHADERATIPROC) (void);
+typedef GLuint (GLAPIENTRY * PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range);
+typedef void (GLAPIENTRY * PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle);
+typedef void (GLAPIENTRY * PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle);
+typedef void (GLAPIENTRY * PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat* value);
+
+#define glAlphaFragmentOp1ATI GLEW_GET_FUN(__glewAlphaFragmentOp1ATI)
+#define glAlphaFragmentOp2ATI GLEW_GET_FUN(__glewAlphaFragmentOp2ATI)
+#define glAlphaFragmentOp3ATI GLEW_GET_FUN(__glewAlphaFragmentOp3ATI)
+#define glBeginFragmentShaderATI GLEW_GET_FUN(__glewBeginFragmentShaderATI)
+#define glBindFragmentShaderATI GLEW_GET_FUN(__glewBindFragmentShaderATI)
+#define glColorFragmentOp1ATI GLEW_GET_FUN(__glewColorFragmentOp1ATI)
+#define glColorFragmentOp2ATI GLEW_GET_FUN(__glewColorFragmentOp2ATI)
+#define glColorFragmentOp3ATI GLEW_GET_FUN(__glewColorFragmentOp3ATI)
+#define glDeleteFragmentShaderATI GLEW_GET_FUN(__glewDeleteFragmentShaderATI)
+#define glEndFragmentShaderATI GLEW_GET_FUN(__glewEndFragmentShaderATI)
+#define glGenFragmentShadersATI GLEW_GET_FUN(__glewGenFragmentShadersATI)
+#define glPassTexCoordATI GLEW_GET_FUN(__glewPassTexCoordATI)
+#define glSampleMapATI GLEW_GET_FUN(__glewSampleMapATI)
+#define glSetFragmentShaderConstantATI GLEW_GET_FUN(__glewSetFragmentShaderConstantATI)
+
+#define GLEW_ATI_fragment_shader GLEW_GET_VAR(__GLEW_ATI_fragment_shader)
+
+#endif /* GL_ATI_fragment_shader */
+
+/* ------------------------ GL_ATI_map_object_buffer ----------------------- */
+
+#ifndef GL_ATI_map_object_buffer
+#define GL_ATI_map_object_buffer 1
+
+typedef GLvoid * (GLAPIENTRY * PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer);
+
+#define glMapObjectBufferATI GLEW_GET_FUN(__glewMapObjectBufferATI)
+#define glUnmapObjectBufferATI GLEW_GET_FUN(__glewUnmapObjectBufferATI)
+
+#define GLEW_ATI_map_object_buffer GLEW_GET_VAR(__GLEW_ATI_map_object_buffer)
+
+#endif /* GL_ATI_map_object_buffer */
+
+/* ----------------------------- GL_ATI_meminfo ---------------------------- */
+
+#ifndef GL_ATI_meminfo
+#define GL_ATI_meminfo 1
+
+#define GL_VBO_FREE_MEMORY_ATI 0x87FB
+#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
+#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
+
+#define GLEW_ATI_meminfo GLEW_GET_VAR(__GLEW_ATI_meminfo)
+
+#endif /* GL_ATI_meminfo */
+
+/* -------------------------- GL_ATI_pn_triangles -------------------------- */
+
+#ifndef GL_ATI_pn_triangles
+#define GL_ATI_pn_triangles 1
+
+#define GL_PN_TRIANGLES_ATI 0x87F0
+#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1
+#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2
+#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3
+#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4
+#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5
+#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6
+#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
+#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
+
+typedef void (GLAPIENTRY * PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param);
+
+#define glPNTrianglesfATI GLEW_GET_FUN(__glewPNTrianglesfATI)
+#define glPNTrianglesiATI GLEW_GET_FUN(__glewPNTrianglesiATI)
+
+#define GLEW_ATI_pn_triangles GLEW_GET_VAR(__GLEW_ATI_pn_triangles)
+
+#endif /* GL_ATI_pn_triangles */
+
+/* ------------------------ GL_ATI_separate_stencil ------------------------ */
+
+#ifndef GL_ATI_separate_stencil
+#define GL_ATI_separate_stencil 1
+
+#define GL_STENCIL_BACK_FUNC_ATI 0x8800
+#define GL_STENCIL_BACK_FAIL_ATI 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803
+
+typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+
+#define glStencilFuncSeparateATI GLEW_GET_FUN(__glewStencilFuncSeparateATI)
+#define glStencilOpSeparateATI GLEW_GET_FUN(__glewStencilOpSeparateATI)
+
+#define GLEW_ATI_separate_stencil GLEW_GET_VAR(__GLEW_ATI_separate_stencil)
+
+#endif /* GL_ATI_separate_stencil */
+
+/* ----------------------- GL_ATI_shader_texture_lod ----------------------- */
+
+#ifndef GL_ATI_shader_texture_lod
+#define GL_ATI_shader_texture_lod 1
+
+#define GLEW_ATI_shader_texture_lod GLEW_GET_VAR(__GLEW_ATI_shader_texture_lod)
+
+#endif /* GL_ATI_shader_texture_lod */
+
+/* ---------------------- GL_ATI_text_fragment_shader ---------------------- */
+
+#ifndef GL_ATI_text_fragment_shader
+#define GL_ATI_text_fragment_shader 1
+
+#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200
+
+#define GLEW_ATI_text_fragment_shader GLEW_GET_VAR(__GLEW_ATI_text_fragment_shader)
+
+#endif /* GL_ATI_text_fragment_shader */
+
+/* --------------------- GL_ATI_texture_compression_3dc -------------------- */
+
+#ifndef GL_ATI_texture_compression_3dc
+#define GL_ATI_texture_compression_3dc 1
+
+#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837
+
+#define GLEW_ATI_texture_compression_3dc GLEW_GET_VAR(__GLEW_ATI_texture_compression_3dc)
+
+#endif /* GL_ATI_texture_compression_3dc */
+
+/* ---------------------- GL_ATI_texture_env_combine3 ---------------------- */
+
+#ifndef GL_ATI_texture_env_combine3
+#define GL_ATI_texture_env_combine3 1
+
+#define GL_MODULATE_ADD_ATI 0x8744
+#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
+#define GL_MODULATE_SUBTRACT_ATI 0x8746
+
+#define GLEW_ATI_texture_env_combine3 GLEW_GET_VAR(__GLEW_ATI_texture_env_combine3)
+
+#endif /* GL_ATI_texture_env_combine3 */
+
+/* -------------------------- GL_ATI_texture_float ------------------------- */
+
+#ifndef GL_ATI_texture_float
+#define GL_ATI_texture_float 1
+
+#define GL_RGBA_FLOAT32_ATI 0x8814
+#define GL_RGB_FLOAT32_ATI 0x8815
+#define GL_ALPHA_FLOAT32_ATI 0x8816
+#define GL_INTENSITY_FLOAT32_ATI 0x8817
+#define GL_LUMINANCE_FLOAT32_ATI 0x8818
+#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819
+#define GL_RGBA_FLOAT16_ATI 0x881A
+#define GL_RGB_FLOAT16_ATI 0x881B
+#define GL_ALPHA_FLOAT16_ATI 0x881C
+#define GL_INTENSITY_FLOAT16_ATI 0x881D
+#define GL_LUMINANCE_FLOAT16_ATI 0x881E
+#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F
+
+#define GLEW_ATI_texture_float GLEW_GET_VAR(__GLEW_ATI_texture_float)
+
+#endif /* GL_ATI_texture_float */
+
+/* ----------------------- GL_ATI_texture_mirror_once ---------------------- */
+
+#ifndef GL_ATI_texture_mirror_once
+#define GL_ATI_texture_mirror_once 1
+
+#define GL_MIRROR_CLAMP_ATI 0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743
+
+#define GLEW_ATI_texture_mirror_once GLEW_GET_VAR(__GLEW_ATI_texture_mirror_once)
+
+#endif /* GL_ATI_texture_mirror_once */
+
+/* ----------------------- GL_ATI_vertex_array_object ---------------------- */
+
+#ifndef GL_ATI_vertex_array_object
+#define GL_ATI_vertex_array_object 1
+
+#define GL_STATIC_ATI 0x8760
+#define GL_DYNAMIC_ATI 0x8761
+#define GL_PRESERVE_ATI 0x8762
+#define GL_DISCARD_ATI 0x8763
+#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764
+#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765
+#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766
+#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767
+
+typedef void (GLAPIENTRY * PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (GLAPIENTRY * PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef GLuint (GLAPIENTRY * PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage);
+typedef void (GLAPIENTRY * PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve);
+typedef void (GLAPIENTRY * PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+
+#define glArrayObjectATI GLEW_GET_FUN(__glewArrayObjectATI)
+#define glFreeObjectBufferATI GLEW_GET_FUN(__glewFreeObjectBufferATI)
+#define glGetArrayObjectfvATI GLEW_GET_FUN(__glewGetArrayObjectfvATI)
+#define glGetArrayObjectivATI GLEW_GET_FUN(__glewGetArrayObjectivATI)
+#define glGetObjectBufferfvATI GLEW_GET_FUN(__glewGetObjectBufferfvATI)
+#define glGetObjectBufferivATI GLEW_GET_FUN(__glewGetObjectBufferivATI)
+#define glGetVariantArrayObjectfvATI GLEW_GET_FUN(__glewGetVariantArrayObjectfvATI)
+#define glGetVariantArrayObjectivATI GLEW_GET_FUN(__glewGetVariantArrayObjectivATI)
+#define glIsObjectBufferATI GLEW_GET_FUN(__glewIsObjectBufferATI)
+#define glNewObjectBufferATI GLEW_GET_FUN(__glewNewObjectBufferATI)
+#define glUpdateObjectBufferATI GLEW_GET_FUN(__glewUpdateObjectBufferATI)
+#define glVariantArrayObjectATI GLEW_GET_FUN(__glewVariantArrayObjectATI)
+
+#define GLEW_ATI_vertex_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_array_object)
+
+#endif /* GL_ATI_vertex_array_object */
+
+/* ------------------- GL_ATI_vertex_attrib_array_object ------------------- */
+
+#ifndef GL_ATI_vertex_attrib_array_object
+#define GL_ATI_vertex_attrib_array_object 1
+
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset);
+
+#define glGetVertexAttribArrayObjectfvATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectfvATI)
+#define glGetVertexAttribArrayObjectivATI GLEW_GET_FUN(__glewGetVertexAttribArrayObjectivATI)
+#define glVertexAttribArrayObjectATI GLEW_GET_FUN(__glewVertexAttribArrayObjectATI)
+
+#define GLEW_ATI_vertex_attrib_array_object GLEW_GET_VAR(__GLEW_ATI_vertex_attrib_array_object)
+
+#endif /* GL_ATI_vertex_attrib_array_object */
+
+/* ------------------------- GL_ATI_vertex_streams ------------------------- */
+
+#ifndef GL_ATI_vertex_streams
+#define GL_ATI_vertex_streams 1
+
+#define GL_MAX_VERTEX_STREAMS_ATI 0x876B
+#define GL_VERTEX_SOURCE_ATI 0x876C
+#define GL_VERTEX_STREAM0_ATI 0x876D
+#define GL_VERTEX_STREAM1_ATI 0x876E
+#define GL_VERTEX_STREAM2_ATI 0x876F
+#define GL_VERTEX_STREAM3_ATI 0x8770
+#define GL_VERTEX_STREAM4_ATI 0x8771
+#define GL_VERTEX_STREAM5_ATI 0x8772
+#define GL_VERTEX_STREAM6_ATI 0x8773
+#define GL_VERTEX_STREAM7_ATI 0x8774
+
+typedef void (GLAPIENTRY * PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte x, GLbyte y, GLbyte z);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (GLAPIENTRY * PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords);
+
+#define glClientActiveVertexStreamATI GLEW_GET_FUN(__glewClientActiveVertexStreamATI)
+#define glNormalStream3bATI GLEW_GET_FUN(__glewNormalStream3bATI)
+#define glNormalStream3bvATI GLEW_GET_FUN(__glewNormalStream3bvATI)
+#define glNormalStream3dATI GLEW_GET_FUN(__glewNormalStream3dATI)
+#define glNormalStream3dvATI GLEW_GET_FUN(__glewNormalStream3dvATI)
+#define glNormalStream3fATI GLEW_GET_FUN(__glewNormalStream3fATI)
+#define glNormalStream3fvATI GLEW_GET_FUN(__glewNormalStream3fvATI)
+#define glNormalStream3iATI GLEW_GET_FUN(__glewNormalStream3iATI)
+#define glNormalStream3ivATI GLEW_GET_FUN(__glewNormalStream3ivATI)
+#define glNormalStream3sATI GLEW_GET_FUN(__glewNormalStream3sATI)
+#define glNormalStream3svATI GLEW_GET_FUN(__glewNormalStream3svATI)
+#define glVertexBlendEnvfATI GLEW_GET_FUN(__glewVertexBlendEnvfATI)
+#define glVertexBlendEnviATI GLEW_GET_FUN(__glewVertexBlendEnviATI)
+#define glVertexStream1dATI GLEW_GET_FUN(__glewVertexStream1dATI)
+#define glVertexStream1dvATI GLEW_GET_FUN(__glewVertexStream1dvATI)
+#define glVertexStream1fATI GLEW_GET_FUN(__glewVertexStream1fATI)
+#define glVertexStream1fvATI GLEW_GET_FUN(__glewVertexStream1fvATI)
+#define glVertexStream1iATI GLEW_GET_FUN(__glewVertexStream1iATI)
+#define glVertexStream1ivATI GLEW_GET_FUN(__glewVertexStream1ivATI)
+#define glVertexStream1sATI GLEW_GET_FUN(__glewVertexStream1sATI)
+#define glVertexStream1svATI GLEW_GET_FUN(__glewVertexStream1svATI)
+#define glVertexStream2dATI GLEW_GET_FUN(__glewVertexStream2dATI)
+#define glVertexStream2dvATI GLEW_GET_FUN(__glewVertexStream2dvATI)
+#define glVertexStream2fATI GLEW_GET_FUN(__glewVertexStream2fATI)
+#define glVertexStream2fvATI GLEW_GET_FUN(__glewVertexStream2fvATI)
+#define glVertexStream2iATI GLEW_GET_FUN(__glewVertexStream2iATI)
+#define glVertexStream2ivATI GLEW_GET_FUN(__glewVertexStream2ivATI)
+#define glVertexStream2sATI GLEW_GET_FUN(__glewVertexStream2sATI)
+#define glVertexStream2svATI GLEW_GET_FUN(__glewVertexStream2svATI)
+#define glVertexStream3dATI GLEW_GET_FUN(__glewVertexStream3dATI)
+#define glVertexStream3dvATI GLEW_GET_FUN(__glewVertexStream3dvATI)
+#define glVertexStream3fATI GLEW_GET_FUN(__glewVertexStream3fATI)
+#define glVertexStream3fvATI GLEW_GET_FUN(__glewVertexStream3fvATI)
+#define glVertexStream3iATI GLEW_GET_FUN(__glewVertexStream3iATI)
+#define glVertexStream3ivATI GLEW_GET_FUN(__glewVertexStream3ivATI)
+#define glVertexStream3sATI GLEW_GET_FUN(__glewVertexStream3sATI)
+#define glVertexStream3svATI GLEW_GET_FUN(__glewVertexStream3svATI)
+#define glVertexStream4dATI GLEW_GET_FUN(__glewVertexStream4dATI)
+#define glVertexStream4dvATI GLEW_GET_FUN(__glewVertexStream4dvATI)
+#define glVertexStream4fATI GLEW_GET_FUN(__glewVertexStream4fATI)
+#define glVertexStream4fvATI GLEW_GET_FUN(__glewVertexStream4fvATI)
+#define glVertexStream4iATI GLEW_GET_FUN(__glewVertexStream4iATI)
+#define glVertexStream4ivATI GLEW_GET_FUN(__glewVertexStream4ivATI)
+#define glVertexStream4sATI GLEW_GET_FUN(__glewVertexStream4sATI)
+#define glVertexStream4svATI GLEW_GET_FUN(__glewVertexStream4svATI)
+
+#define GLEW_ATI_vertex_streams GLEW_GET_VAR(__GLEW_ATI_vertex_streams)
+
+#endif /* GL_ATI_vertex_streams */
+
+/* --------------------------- GL_EXT_422_pixels --------------------------- */
+
+#ifndef GL_EXT_422_pixels
+#define GL_EXT_422_pixels 1
+
+#define GL_422_EXT 0x80CC
+#define GL_422_REV_EXT 0x80CD
+#define GL_422_AVERAGE_EXT 0x80CE
+#define GL_422_REV_AVERAGE_EXT 0x80CF
+
+#define GLEW_EXT_422_pixels GLEW_GET_VAR(__GLEW_EXT_422_pixels)
+
+#endif /* GL_EXT_422_pixels */
+
+/* ---------------------------- GL_EXT_Cg_shader --------------------------- */
+
+#ifndef GL_EXT_Cg_shader
+#define GL_EXT_Cg_shader 1
+
+#define GL_CG_VERTEX_SHADER_EXT 0x890E
+#define GL_CG_FRAGMENT_SHADER_EXT 0x890F
+
+#define GLEW_EXT_Cg_shader GLEW_GET_VAR(__GLEW_EXT_Cg_shader)
+
+#endif /* GL_EXT_Cg_shader */
+
+/* ------------------------------ GL_EXT_abgr ------------------------------ */
+
+#ifndef GL_EXT_abgr
+#define GL_EXT_abgr 1
+
+#define GL_ABGR_EXT 0x8000
+
+#define GLEW_EXT_abgr GLEW_GET_VAR(__GLEW_EXT_abgr)
+
+#endif /* GL_EXT_abgr */
+
+/* ------------------------------ GL_EXT_bgra ------------------------------ */
+
+#ifndef GL_EXT_bgra
+#define GL_EXT_bgra 1
+
+#define GL_BGR_EXT 0x80E0
+#define GL_BGRA_EXT 0x80E1
+
+#define GLEW_EXT_bgra GLEW_GET_VAR(__GLEW_EXT_bgra)
+
+#endif /* GL_EXT_bgra */
+
+/* ------------------------ GL_EXT_bindable_uniform ------------------------ */
+
+#ifndef GL_EXT_bindable_uniform
+#define GL_EXT_bindable_uniform 1
+
+#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2
+#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3
+#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4
+#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED
+#define GL_UNIFORM_BUFFER_EXT 0x8DEE
+#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF
+
+typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location);
+typedef GLintptr (GLAPIENTRY * PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location);
+typedef void (GLAPIENTRY * PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer);
+
+#define glGetUniformBufferSizeEXT GLEW_GET_FUN(__glewGetUniformBufferSizeEXT)
+#define glGetUniformOffsetEXT GLEW_GET_FUN(__glewGetUniformOffsetEXT)
+#define glUniformBufferEXT GLEW_GET_FUN(__glewUniformBufferEXT)
+
+#define GLEW_EXT_bindable_uniform GLEW_GET_VAR(__GLEW_EXT_bindable_uniform)
+
+#endif /* GL_EXT_bindable_uniform */
+
+/* --------------------------- GL_EXT_blend_color -------------------------- */
+
+#ifndef GL_EXT_blend_color
+#define GL_EXT_blend_color 1
+
+#define GL_CONSTANT_COLOR_EXT 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002
+#define GL_CONSTANT_ALPHA_EXT 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004
+#define GL_BLEND_COLOR_EXT 0x8005
+
+typedef void (GLAPIENTRY * PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+
+#define glBlendColorEXT GLEW_GET_FUN(__glewBlendColorEXT)
+
+#define GLEW_EXT_blend_color GLEW_GET_VAR(__GLEW_EXT_blend_color)
+
+#endif /* GL_EXT_blend_color */
+
+/* --------------------- GL_EXT_blend_equation_separate -------------------- */
+
+#ifndef GL_EXT_blend_equation_separate
+#define GL_EXT_blend_equation_separate 1
+
+#define GL_BLEND_EQUATION_RGB_EXT 0x8009
+#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D
+
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha);
+
+#define glBlendEquationSeparateEXT GLEW_GET_FUN(__glewBlendEquationSeparateEXT)
+
+#define GLEW_EXT_blend_equation_separate GLEW_GET_VAR(__GLEW_EXT_blend_equation_separate)
+
+#endif /* GL_EXT_blend_equation_separate */
+
+/* ----------------------- GL_EXT_blend_func_separate ---------------------- */
+
+#ifndef GL_EXT_blend_func_separate
+#define GL_EXT_blend_func_separate 1
+
+#define GL_BLEND_DST_RGB_EXT 0x80C8
+#define GL_BLEND_SRC_RGB_EXT 0x80C9
+#define GL_BLEND_DST_ALPHA_EXT 0x80CA
+#define GL_BLEND_SRC_ALPHA_EXT 0x80CB
+
+typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+
+#define glBlendFuncSeparateEXT GLEW_GET_FUN(__glewBlendFuncSeparateEXT)
+
+#define GLEW_EXT_blend_func_separate GLEW_GET_VAR(__GLEW_EXT_blend_func_separate)
+
+#endif /* GL_EXT_blend_func_separate */
+
+/* ------------------------- GL_EXT_blend_logic_op ------------------------- */
+
+#ifndef GL_EXT_blend_logic_op
+#define GL_EXT_blend_logic_op 1
+
+#define GLEW_EXT_blend_logic_op GLEW_GET_VAR(__GLEW_EXT_blend_logic_op)
+
+#endif /* GL_EXT_blend_logic_op */
+
+/* -------------------------- GL_EXT_blend_minmax -------------------------- */
+
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+
+#define GL_FUNC_ADD_EXT 0x8006
+#define GL_MIN_EXT 0x8007
+#define GL_MAX_EXT 0x8008
+#define GL_BLEND_EQUATION_EXT 0x8009
+
+typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode);
+
+#define glBlendEquationEXT GLEW_GET_FUN(__glewBlendEquationEXT)
+
+#define GLEW_EXT_blend_minmax GLEW_GET_VAR(__GLEW_EXT_blend_minmax)
+
+#endif /* GL_EXT_blend_minmax */
+
+/* ------------------------- GL_EXT_blend_subtract ------------------------- */
+
+#ifndef GL_EXT_blend_subtract
+#define GL_EXT_blend_subtract 1
+
+#define GL_FUNC_SUBTRACT_EXT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B
+
+#define GLEW_EXT_blend_subtract GLEW_GET_VAR(__GLEW_EXT_blend_subtract)
+
+#endif /* GL_EXT_blend_subtract */
+
+/* ------------------------ GL_EXT_clip_volume_hint ------------------------ */
+
+#ifndef GL_EXT_clip_volume_hint
+#define GL_EXT_clip_volume_hint 1
+
+#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0
+
+#define GLEW_EXT_clip_volume_hint GLEW_GET_VAR(__GLEW_EXT_clip_volume_hint)
+
+#endif /* GL_EXT_clip_volume_hint */
+
+/* ------------------------------ GL_EXT_cmyka ----------------------------- */
+
+#ifndef GL_EXT_cmyka
+#define GL_EXT_cmyka 1
+
+#define GL_CMYK_EXT 0x800C
+#define GL_CMYKA_EXT 0x800D
+#define GL_PACK_CMYK_HINT_EXT 0x800E
+#define GL_UNPACK_CMYK_HINT_EXT 0x800F
+
+#define GLEW_EXT_cmyka GLEW_GET_VAR(__GLEW_EXT_cmyka)
+
+#endif /* GL_EXT_cmyka */
+
+/* ------------------------- GL_EXT_color_subtable ------------------------- */
+
+#ifndef GL_EXT_color_subtable
+#define GL_EXT_color_subtable 1
+
+typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+
+#define glColorSubTableEXT GLEW_GET_FUN(__glewColorSubTableEXT)
+#define glCopyColorSubTableEXT GLEW_GET_FUN(__glewCopyColorSubTableEXT)
+
+#define GLEW_EXT_color_subtable GLEW_GET_VAR(__GLEW_EXT_color_subtable)
+
+#endif /* GL_EXT_color_subtable */
+
+/* ---------------------- GL_EXT_compiled_vertex_array --------------------- */
+
+#ifndef GL_EXT_compiled_vertex_array
+#define GL_EXT_compiled_vertex_array 1
+
+#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8
+#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9
+
+typedef void (GLAPIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
+typedef void (GLAPIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
+
+#define glLockArraysEXT GLEW_GET_FUN(__glewLockArraysEXT)
+#define glUnlockArraysEXT GLEW_GET_FUN(__glewUnlockArraysEXT)
+
+#define GLEW_EXT_compiled_vertex_array GLEW_GET_VAR(__GLEW_EXT_compiled_vertex_array)
+
+#endif /* GL_EXT_compiled_vertex_array */
+
+/* --------------------------- GL_EXT_convolution -------------------------- */
+
+#ifndef GL_EXT_convolution
+#define GL_EXT_convolution 1
+
+#define GL_CONVOLUTION_1D_EXT 0x8010
+#define GL_CONVOLUTION_2D_EXT 0x8011
+#define GL_SEPARABLE_2D_EXT 0x8012
+#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015
+#define GL_REDUCE_EXT 0x8016
+#define GL_CONVOLUTION_FORMAT_EXT 0x8017
+#define GL_CONVOLUTION_WIDTH_EXT 0x8018
+#define GL_CONVOLUTION_HEIGHT_EXT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023
+
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+
+#define glConvolutionFilter1DEXT GLEW_GET_FUN(__glewConvolutionFilter1DEXT)
+#define glConvolutionFilter2DEXT GLEW_GET_FUN(__glewConvolutionFilter2DEXT)
+#define glConvolutionParameterfEXT GLEW_GET_FUN(__glewConvolutionParameterfEXT)
+#define glConvolutionParameterfvEXT GLEW_GET_FUN(__glewConvolutionParameterfvEXT)
+#define glConvolutionParameteriEXT GLEW_GET_FUN(__glewConvolutionParameteriEXT)
+#define glConvolutionParameterivEXT GLEW_GET_FUN(__glewConvolutionParameterivEXT)
+#define glCopyConvolutionFilter1DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter1DEXT)
+#define glCopyConvolutionFilter2DEXT GLEW_GET_FUN(__glewCopyConvolutionFilter2DEXT)
+#define glGetConvolutionFilterEXT GLEW_GET_FUN(__glewGetConvolutionFilterEXT)
+#define glGetConvolutionParameterfvEXT GLEW_GET_FUN(__glewGetConvolutionParameterfvEXT)
+#define glGetConvolutionParameterivEXT GLEW_GET_FUN(__glewGetConvolutionParameterivEXT)
+#define glGetSeparableFilterEXT GLEW_GET_FUN(__glewGetSeparableFilterEXT)
+#define glSeparableFilter2DEXT GLEW_GET_FUN(__glewSeparableFilter2DEXT)
+
+#define GLEW_EXT_convolution GLEW_GET_VAR(__GLEW_EXT_convolution)
+
+#endif /* GL_EXT_convolution */
+
+/* ------------------------ GL_EXT_coordinate_frame ------------------------ */
+
+#ifndef GL_EXT_coordinate_frame
+#define GL_EXT_coordinate_frame 1
+
+#define GL_TANGENT_ARRAY_EXT 0x8439
+#define GL_BINORMAL_ARRAY_EXT 0x843A
+#define GL_CURRENT_TANGENT_EXT 0x843B
+#define GL_CURRENT_BINORMAL_EXT 0x843C
+#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E
+#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F
+#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440
+#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441
+#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442
+#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443
+#define GL_MAP1_TANGENT_EXT 0x8444
+#define GL_MAP2_TANGENT_EXT 0x8445
+#define GL_MAP1_BINORMAL_EXT 0x8446
+#define GL_MAP2_BINORMAL_EXT 0x8447
+
+typedef void (GLAPIENTRY * PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, GLvoid *pointer);
+
+#define glBinormalPointerEXT GLEW_GET_FUN(__glewBinormalPointerEXT)
+#define glTangentPointerEXT GLEW_GET_FUN(__glewTangentPointerEXT)
+
+#define GLEW_EXT_coordinate_frame GLEW_GET_VAR(__GLEW_EXT_coordinate_frame)
+
+#endif /* GL_EXT_coordinate_frame */
+
+/* -------------------------- GL_EXT_copy_texture -------------------------- */
+
+#ifndef GL_EXT_copy_texture
+#define GL_EXT_copy_texture 1
+
+typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+
+#define glCopyTexImage1DEXT GLEW_GET_FUN(__glewCopyTexImage1DEXT)
+#define glCopyTexImage2DEXT GLEW_GET_FUN(__glewCopyTexImage2DEXT)
+#define glCopyTexSubImage1DEXT GLEW_GET_FUN(__glewCopyTexSubImage1DEXT)
+#define glCopyTexSubImage2DEXT GLEW_GET_FUN(__glewCopyTexSubImage2DEXT)
+#define glCopyTexSubImage3DEXT GLEW_GET_FUN(__glewCopyTexSubImage3DEXT)
+
+#define GLEW_EXT_copy_texture GLEW_GET_VAR(__GLEW_EXT_copy_texture)
+
+#endif /* GL_EXT_copy_texture */
+
+/* --------------------------- GL_EXT_cull_vertex -------------------------- */
+
+#ifndef GL_EXT_cull_vertex
+#define GL_EXT_cull_vertex 1
+
+#define GL_CULL_VERTEX_EXT 0x81AA
+#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB
+#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC
+
+typedef void (GLAPIENTRY * PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat* params);
+
+#define glCullParameterdvEXT GLEW_GET_FUN(__glewCullParameterdvEXT)
+#define glCullParameterfvEXT GLEW_GET_FUN(__glewCullParameterfvEXT)
+
+#define GLEW_EXT_cull_vertex GLEW_GET_VAR(__GLEW_EXT_cull_vertex)
+
+#endif /* GL_EXT_cull_vertex */
+
+/* -------------------------- GL_EXT_debug_marker -------------------------- */
+
+#ifndef GL_EXT_debug_marker
+#define GL_EXT_debug_marker 1
+
+typedef void (GLAPIENTRY * PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar* marker);
+typedef void (GLAPIENTRY * PFNGLPOPGROUPMARKEREXTPROC) (void);
+typedef void (GLAPIENTRY * PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar* marker);
+
+#define glInsertEventMarkerEXT GLEW_GET_FUN(__glewInsertEventMarkerEXT)
+#define glPopGroupMarkerEXT GLEW_GET_FUN(__glewPopGroupMarkerEXT)
+#define glPushGroupMarkerEXT GLEW_GET_FUN(__glewPushGroupMarkerEXT)
+
+#define GLEW_EXT_debug_marker GLEW_GET_VAR(__GLEW_EXT_debug_marker)
+
+#endif /* GL_EXT_debug_marker */
+
+/* ------------------------ GL_EXT_depth_bounds_test ----------------------- */
+
+#ifndef GL_EXT_depth_bounds_test
+#define GL_EXT_depth_bounds_test 1
+
+#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890
+#define GL_DEPTH_BOUNDS_EXT 0x8891
+
+typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax);
+
+#define glDepthBoundsEXT GLEW_GET_FUN(__glewDepthBoundsEXT)
+
+#define GLEW_EXT_depth_bounds_test GLEW_GET_VAR(__GLEW_EXT_depth_bounds_test)
+
+#endif /* GL_EXT_depth_bounds_test */
+
+/* ----------------------- GL_EXT_direct_state_access ---------------------- */
+
+#ifndef GL_EXT_direct_state_access
+#define GL_EXT_direct_state_access 1
+
+#define GL_PROGRAM_MATRIX_EXT 0x8E2D
+#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E
+#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F
+
+typedef void (GLAPIENTRY * PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture);
+typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target);
+typedef void (GLAPIENTRY * PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);
+typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index);
+typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index);
+typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array);
+typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEIEXTPROC) (GLenum array, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYATTRIBEXTPROC) (GLuint vaobj, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYEXTPROC) (GLuint vaobj, GLenum array);
+typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target);
+typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target);
+typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLvoid *img);
+typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLvoid *img);
+typedef void (GLAPIENTRY * PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint* param);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void** params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, GLvoid *string);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLvoid** params);
+typedef void (GLAPIENTRY * PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, GLvoid** params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint* param);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINTEGERVEXTPROC) (GLuint vaobj, GLenum pname, GLint* param);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLvoid** param);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYPOINTERVEXTPROC) (GLuint vaobj, GLenum pname, GLvoid** param);
+typedef GLvoid * (GLAPIENTRY * PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access);
+typedef GLvoid * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (GLAPIENTRY * PFNGLMATRIXFRUSTUMEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f);
+typedef void (GLAPIENTRY * PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum matrixMode);
+typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXLOADDEXTPROC) (GLenum matrixMode, const GLdouble* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXLOADFEXTPROC) (GLenum matrixMode, const GLfloat* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum matrixMode, const GLdouble* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum matrixMode, const GLfloat* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXMULTDEXTPROC) (GLenum matrixMode, const GLdouble* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXMULTFEXTPROC) (GLenum matrixMode, const GLfloat* m);
+typedef void (GLAPIENTRY * PFNGLMATRIXORTHOEXTPROC) (GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, GLdouble n, GLdouble f);
+typedef void (GLAPIENTRY * PFNGLMATRIXPOPEXTPROC) (GLenum matrixMode);
+typedef void (GLAPIENTRY * PFNGLMATRIXPUSHEXTPROC) (GLenum matrixMode);
+typedef void (GLAPIENTRY * PFNGLMATRIXROTATEDEXTPROC) (GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLMATRIXROTATEFEXTPROC) (GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLMATRIXSCALEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLMATRIXSCALEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint* params);
+typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat* param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint* param);
+typedef void (GLAPIENTRY * PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage);
+typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face);
+typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint* params);
+typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask);
+typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint* params);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat* param);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint* param);
+typedef void (GLAPIENTRY * PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYINDEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum texunit, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYNORMALOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+
+#define glBindMultiTextureEXT GLEW_GET_FUN(__glewBindMultiTextureEXT)
+#define glCheckNamedFramebufferStatusEXT GLEW_GET_FUN(__glewCheckNamedFramebufferStatusEXT)
+#define glClientAttribDefaultEXT GLEW_GET_FUN(__glewClientAttribDefaultEXT)
+#define glCompressedMultiTexImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage1DEXT)
+#define glCompressedMultiTexImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage2DEXT)
+#define glCompressedMultiTexImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexImage3DEXT)
+#define glCompressedMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage1DEXT)
+#define glCompressedMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage2DEXT)
+#define glCompressedMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCompressedMultiTexSubImage3DEXT)
+#define glCompressedTextureImage1DEXT GLEW_GET_FUN(__glewCompressedTextureImage1DEXT)
+#define glCompressedTextureImage2DEXT GLEW_GET_FUN(__glewCompressedTextureImage2DEXT)
+#define glCompressedTextureImage3DEXT GLEW_GET_FUN(__glewCompressedTextureImage3DEXT)
+#define glCompressedTextureSubImage1DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage1DEXT)
+#define glCompressedTextureSubImage2DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage2DEXT)
+#define glCompressedTextureSubImage3DEXT GLEW_GET_FUN(__glewCompressedTextureSubImage3DEXT)
+#define glCopyMultiTexImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexImage1DEXT)
+#define glCopyMultiTexImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexImage2DEXT)
+#define glCopyMultiTexSubImage1DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage1DEXT)
+#define glCopyMultiTexSubImage2DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage2DEXT)
+#define glCopyMultiTexSubImage3DEXT GLEW_GET_FUN(__glewCopyMultiTexSubImage3DEXT)
+#define glCopyTextureImage1DEXT GLEW_GET_FUN(__glewCopyTextureImage1DEXT)
+#define glCopyTextureImage2DEXT GLEW_GET_FUN(__glewCopyTextureImage2DEXT)
+#define glCopyTextureSubImage1DEXT GLEW_GET_FUN(__glewCopyTextureSubImage1DEXT)
+#define glCopyTextureSubImage2DEXT GLEW_GET_FUN(__glewCopyTextureSubImage2DEXT)
+#define glCopyTextureSubImage3DEXT GLEW_GET_FUN(__glewCopyTextureSubImage3DEXT)
+#define glDisableClientStateIndexedEXT GLEW_GET_FUN(__glewDisableClientStateIndexedEXT)
+#define glDisableClientStateiEXT GLEW_GET_FUN(__glewDisableClientStateiEXT)
+#define glDisableVertexArrayAttribEXT GLEW_GET_FUN(__glewDisableVertexArrayAttribEXT)
+#define glDisableVertexArrayEXT GLEW_GET_FUN(__glewDisableVertexArrayEXT)
+#define glEnableClientStateIndexedEXT GLEW_GET_FUN(__glewEnableClientStateIndexedEXT)
+#define glEnableClientStateiEXT GLEW_GET_FUN(__glewEnableClientStateiEXT)
+#define glEnableVertexArrayAttribEXT GLEW_GET_FUN(__glewEnableVertexArrayAttribEXT)
+#define glEnableVertexArrayEXT GLEW_GET_FUN(__glewEnableVertexArrayEXT)
+#define glFlushMappedNamedBufferRangeEXT GLEW_GET_FUN(__glewFlushMappedNamedBufferRangeEXT)
+#define glFramebufferDrawBufferEXT GLEW_GET_FUN(__glewFramebufferDrawBufferEXT)
+#define glFramebufferDrawBuffersEXT GLEW_GET_FUN(__glewFramebufferDrawBuffersEXT)
+#define glFramebufferReadBufferEXT GLEW_GET_FUN(__glewFramebufferReadBufferEXT)
+#define glGenerateMultiTexMipmapEXT GLEW_GET_FUN(__glewGenerateMultiTexMipmapEXT)
+#define glGenerateTextureMipmapEXT GLEW_GET_FUN(__glewGenerateTextureMipmapEXT)
+#define glGetCompressedMultiTexImageEXT GLEW_GET_FUN(__glewGetCompressedMultiTexImageEXT)
+#define glGetCompressedTextureImageEXT GLEW_GET_FUN(__glewGetCompressedTextureImageEXT)
+#define glGetDoubleIndexedvEXT GLEW_GET_FUN(__glewGetDoubleIndexedvEXT)
+#define glGetDoublei_vEXT GLEW_GET_FUN(__glewGetDoublei_vEXT)
+#define glGetFloatIndexedvEXT GLEW_GET_FUN(__glewGetFloatIndexedvEXT)
+#define glGetFloati_vEXT GLEW_GET_FUN(__glewGetFloati_vEXT)
+#define glGetFramebufferParameterivEXT GLEW_GET_FUN(__glewGetFramebufferParameterivEXT)
+#define glGetMultiTexEnvfvEXT GLEW_GET_FUN(__glewGetMultiTexEnvfvEXT)
+#define glGetMultiTexEnvivEXT GLEW_GET_FUN(__glewGetMultiTexEnvivEXT)
+#define glGetMultiTexGendvEXT GLEW_GET_FUN(__glewGetMultiTexGendvEXT)
+#define glGetMultiTexGenfvEXT GLEW_GET_FUN(__glewGetMultiTexGenfvEXT)
+#define glGetMultiTexGenivEXT GLEW_GET_FUN(__glewGetMultiTexGenivEXT)
+#define glGetMultiTexImageEXT GLEW_GET_FUN(__glewGetMultiTexImageEXT)
+#define glGetMultiTexLevelParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterfvEXT)
+#define glGetMultiTexLevelParameterivEXT GLEW_GET_FUN(__glewGetMultiTexLevelParameterivEXT)
+#define glGetMultiTexParameterIivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIivEXT)
+#define glGetMultiTexParameterIuivEXT GLEW_GET_FUN(__glewGetMultiTexParameterIuivEXT)
+#define glGetMultiTexParameterfvEXT GLEW_GET_FUN(__glewGetMultiTexParameterfvEXT)
+#define glGetMultiTexParameterivEXT GLEW_GET_FUN(__glewGetMultiTexParameterivEXT)
+#define glGetNamedBufferParameterivEXT GLEW_GET_FUN(__glewGetNamedBufferParameterivEXT)
+#define glGetNamedBufferPointervEXT GLEW_GET_FUN(__glewGetNamedBufferPointervEXT)
+#define glGetNamedBufferSubDataEXT GLEW_GET_FUN(__glewGetNamedBufferSubDataEXT)
+#define glGetNamedFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetNamedFramebufferAttachmentParameterivEXT)
+#define glGetNamedProgramLocalParameterIivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIivEXT)
+#define glGetNamedProgramLocalParameterIuivEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterIuivEXT)
+#define glGetNamedProgramLocalParameterdvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterdvEXT)
+#define glGetNamedProgramLocalParameterfvEXT GLEW_GET_FUN(__glewGetNamedProgramLocalParameterfvEXT)
+#define glGetNamedProgramStringEXT GLEW_GET_FUN(__glewGetNamedProgramStringEXT)
+#define glGetNamedProgramivEXT GLEW_GET_FUN(__glewGetNamedProgramivEXT)
+#define glGetNamedRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetNamedRenderbufferParameterivEXT)
+#define glGetPointerIndexedvEXT GLEW_GET_FUN(__glewGetPointerIndexedvEXT)
+#define glGetPointeri_vEXT GLEW_GET_FUN(__glewGetPointeri_vEXT)
+#define glGetTextureImageEXT GLEW_GET_FUN(__glewGetTextureImageEXT)
+#define glGetTextureLevelParameterfvEXT GLEW_GET_FUN(__glewGetTextureLevelParameterfvEXT)
+#define glGetTextureLevelParameterivEXT GLEW_GET_FUN(__glewGetTextureLevelParameterivEXT)
+#define glGetTextureParameterIivEXT GLEW_GET_FUN(__glewGetTextureParameterIivEXT)
+#define glGetTextureParameterIuivEXT GLEW_GET_FUN(__glewGetTextureParameterIuivEXT)
+#define glGetTextureParameterfvEXT GLEW_GET_FUN(__glewGetTextureParameterfvEXT)
+#define glGetTextureParameterivEXT GLEW_GET_FUN(__glewGetTextureParameterivEXT)
+#define glGetVertexArrayIntegeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayIntegeri_vEXT)
+#define glGetVertexArrayIntegervEXT GLEW_GET_FUN(__glewGetVertexArrayIntegervEXT)
+#define glGetVertexArrayPointeri_vEXT GLEW_GET_FUN(__glewGetVertexArrayPointeri_vEXT)
+#define glGetVertexArrayPointervEXT GLEW_GET_FUN(__glewGetVertexArrayPointervEXT)
+#define glMapNamedBufferEXT GLEW_GET_FUN(__glewMapNamedBufferEXT)
+#define glMapNamedBufferRangeEXT GLEW_GET_FUN(__glewMapNamedBufferRangeEXT)
+#define glMatrixFrustumEXT GLEW_GET_FUN(__glewMatrixFrustumEXT)
+#define glMatrixLoadIdentityEXT GLEW_GET_FUN(__glewMatrixLoadIdentityEXT)
+#define glMatrixLoadTransposedEXT GLEW_GET_FUN(__glewMatrixLoadTransposedEXT)
+#define glMatrixLoadTransposefEXT GLEW_GET_FUN(__glewMatrixLoadTransposefEXT)
+#define glMatrixLoaddEXT GLEW_GET_FUN(__glewMatrixLoaddEXT)
+#define glMatrixLoadfEXT GLEW_GET_FUN(__glewMatrixLoadfEXT)
+#define glMatrixMultTransposedEXT GLEW_GET_FUN(__glewMatrixMultTransposedEXT)
+#define glMatrixMultTransposefEXT GLEW_GET_FUN(__glewMatrixMultTransposefEXT)
+#define glMatrixMultdEXT GLEW_GET_FUN(__glewMatrixMultdEXT)
+#define glMatrixMultfEXT GLEW_GET_FUN(__glewMatrixMultfEXT)
+#define glMatrixOrthoEXT GLEW_GET_FUN(__glewMatrixOrthoEXT)
+#define glMatrixPopEXT GLEW_GET_FUN(__glewMatrixPopEXT)
+#define glMatrixPushEXT GLEW_GET_FUN(__glewMatrixPushEXT)
+#define glMatrixRotatedEXT GLEW_GET_FUN(__glewMatrixRotatedEXT)
+#define glMatrixRotatefEXT GLEW_GET_FUN(__glewMatrixRotatefEXT)
+#define glMatrixScaledEXT GLEW_GET_FUN(__glewMatrixScaledEXT)
+#define glMatrixScalefEXT GLEW_GET_FUN(__glewMatrixScalefEXT)
+#define glMatrixTranslatedEXT GLEW_GET_FUN(__glewMatrixTranslatedEXT)
+#define glMatrixTranslatefEXT GLEW_GET_FUN(__glewMatrixTranslatefEXT)
+#define glMultiTexBufferEXT GLEW_GET_FUN(__glewMultiTexBufferEXT)
+#define glMultiTexCoordPointerEXT GLEW_GET_FUN(__glewMultiTexCoordPointerEXT)
+#define glMultiTexEnvfEXT GLEW_GET_FUN(__glewMultiTexEnvfEXT)
+#define glMultiTexEnvfvEXT GLEW_GET_FUN(__glewMultiTexEnvfvEXT)
+#define glMultiTexEnviEXT GLEW_GET_FUN(__glewMultiTexEnviEXT)
+#define glMultiTexEnvivEXT GLEW_GET_FUN(__glewMultiTexEnvivEXT)
+#define glMultiTexGendEXT GLEW_GET_FUN(__glewMultiTexGendEXT)
+#define glMultiTexGendvEXT GLEW_GET_FUN(__glewMultiTexGendvEXT)
+#define glMultiTexGenfEXT GLEW_GET_FUN(__glewMultiTexGenfEXT)
+#define glMultiTexGenfvEXT GLEW_GET_FUN(__glewMultiTexGenfvEXT)
+#define glMultiTexGeniEXT GLEW_GET_FUN(__glewMultiTexGeniEXT)
+#define glMultiTexGenivEXT GLEW_GET_FUN(__glewMultiTexGenivEXT)
+#define glMultiTexImage1DEXT GLEW_GET_FUN(__glewMultiTexImage1DEXT)
+#define glMultiTexImage2DEXT GLEW_GET_FUN(__glewMultiTexImage2DEXT)
+#define glMultiTexImage3DEXT GLEW_GET_FUN(__glewMultiTexImage3DEXT)
+#define glMultiTexParameterIivEXT GLEW_GET_FUN(__glewMultiTexParameterIivEXT)
+#define glMultiTexParameterIuivEXT GLEW_GET_FUN(__glewMultiTexParameterIuivEXT)
+#define glMultiTexParameterfEXT GLEW_GET_FUN(__glewMultiTexParameterfEXT)
+#define glMultiTexParameterfvEXT GLEW_GET_FUN(__glewMultiTexParameterfvEXT)
+#define glMultiTexParameteriEXT GLEW_GET_FUN(__glewMultiTexParameteriEXT)
+#define glMultiTexParameterivEXT GLEW_GET_FUN(__glewMultiTexParameterivEXT)
+#define glMultiTexRenderbufferEXT GLEW_GET_FUN(__glewMultiTexRenderbufferEXT)
+#define glMultiTexSubImage1DEXT GLEW_GET_FUN(__glewMultiTexSubImage1DEXT)
+#define glMultiTexSubImage2DEXT GLEW_GET_FUN(__glewMultiTexSubImage2DEXT)
+#define glMultiTexSubImage3DEXT GLEW_GET_FUN(__glewMultiTexSubImage3DEXT)
+#define glNamedBufferDataEXT GLEW_GET_FUN(__glewNamedBufferDataEXT)
+#define glNamedBufferSubDataEXT GLEW_GET_FUN(__glewNamedBufferSubDataEXT)
+#define glNamedCopyBufferSubDataEXT GLEW_GET_FUN(__glewNamedCopyBufferSubDataEXT)
+#define glNamedFramebufferRenderbufferEXT GLEW_GET_FUN(__glewNamedFramebufferRenderbufferEXT)
+#define glNamedFramebufferTexture1DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture1DEXT)
+#define glNamedFramebufferTexture2DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture2DEXT)
+#define glNamedFramebufferTexture3DEXT GLEW_GET_FUN(__glewNamedFramebufferTexture3DEXT)
+#define glNamedFramebufferTextureEXT GLEW_GET_FUN(__glewNamedFramebufferTextureEXT)
+#define glNamedFramebufferTextureFaceEXT GLEW_GET_FUN(__glewNamedFramebufferTextureFaceEXT)
+#define glNamedFramebufferTextureLayerEXT GLEW_GET_FUN(__glewNamedFramebufferTextureLayerEXT)
+#define glNamedProgramLocalParameter4dEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dEXT)
+#define glNamedProgramLocalParameter4dvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4dvEXT)
+#define glNamedProgramLocalParameter4fEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fEXT)
+#define glNamedProgramLocalParameter4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameter4fvEXT)
+#define glNamedProgramLocalParameterI4iEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4iEXT)
+#define glNamedProgramLocalParameterI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4ivEXT)
+#define glNamedProgramLocalParameterI4uiEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uiEXT)
+#define glNamedProgramLocalParameterI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParameterI4uivEXT)
+#define glNamedProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewNamedProgramLocalParameters4fvEXT)
+#define glNamedProgramLocalParametersI4ivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4ivEXT)
+#define glNamedProgramLocalParametersI4uivEXT GLEW_GET_FUN(__glewNamedProgramLocalParametersI4uivEXT)
+#define glNamedProgramStringEXT GLEW_GET_FUN(__glewNamedProgramStringEXT)
+#define glNamedRenderbufferStorageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageEXT)
+#define glNamedRenderbufferStorageMultisampleCoverageEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleCoverageEXT)
+#define glNamedRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewNamedRenderbufferStorageMultisampleEXT)
+#define glProgramUniform1fEXT GLEW_GET_FUN(__glewProgramUniform1fEXT)
+#define glProgramUniform1fvEXT GLEW_GET_FUN(__glewProgramUniform1fvEXT)
+#define glProgramUniform1iEXT GLEW_GET_FUN(__glewProgramUniform1iEXT)
+#define glProgramUniform1ivEXT GLEW_GET_FUN(__glewProgramUniform1ivEXT)
+#define glProgramUniform1uiEXT GLEW_GET_FUN(__glewProgramUniform1uiEXT)
+#define glProgramUniform1uivEXT GLEW_GET_FUN(__glewProgramUniform1uivEXT)
+#define glProgramUniform2fEXT GLEW_GET_FUN(__glewProgramUniform2fEXT)
+#define glProgramUniform2fvEXT GLEW_GET_FUN(__glewProgramUniform2fvEXT)
+#define glProgramUniform2iEXT GLEW_GET_FUN(__glewProgramUniform2iEXT)
+#define glProgramUniform2ivEXT GLEW_GET_FUN(__glewProgramUniform2ivEXT)
+#define glProgramUniform2uiEXT GLEW_GET_FUN(__glewProgramUniform2uiEXT)
+#define glProgramUniform2uivEXT GLEW_GET_FUN(__glewProgramUniform2uivEXT)
+#define glProgramUniform3fEXT GLEW_GET_FUN(__glewProgramUniform3fEXT)
+#define glProgramUniform3fvEXT GLEW_GET_FUN(__glewProgramUniform3fvEXT)
+#define glProgramUniform3iEXT GLEW_GET_FUN(__glewProgramUniform3iEXT)
+#define glProgramUniform3ivEXT GLEW_GET_FUN(__glewProgramUniform3ivEXT)
+#define glProgramUniform3uiEXT GLEW_GET_FUN(__glewProgramUniform3uiEXT)
+#define glProgramUniform3uivEXT GLEW_GET_FUN(__glewProgramUniform3uivEXT)
+#define glProgramUniform4fEXT GLEW_GET_FUN(__glewProgramUniform4fEXT)
+#define glProgramUniform4fvEXT GLEW_GET_FUN(__glewProgramUniform4fvEXT)
+#define glProgramUniform4iEXT GLEW_GET_FUN(__glewProgramUniform4iEXT)
+#define glProgramUniform4ivEXT GLEW_GET_FUN(__glewProgramUniform4ivEXT)
+#define glProgramUniform4uiEXT GLEW_GET_FUN(__glewProgramUniform4uiEXT)
+#define glProgramUniform4uivEXT GLEW_GET_FUN(__glewProgramUniform4uivEXT)
+#define glProgramUniformMatrix2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2fvEXT)
+#define glProgramUniformMatrix2x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x3fvEXT)
+#define glProgramUniformMatrix2x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix2x4fvEXT)
+#define glProgramUniformMatrix3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3fvEXT)
+#define glProgramUniformMatrix3x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x2fvEXT)
+#define glProgramUniformMatrix3x4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix3x4fvEXT)
+#define glProgramUniformMatrix4fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4fvEXT)
+#define glProgramUniformMatrix4x2fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x2fvEXT)
+#define glProgramUniformMatrix4x3fvEXT GLEW_GET_FUN(__glewProgramUniformMatrix4x3fvEXT)
+#define glPushClientAttribDefaultEXT GLEW_GET_FUN(__glewPushClientAttribDefaultEXT)
+#define glTextureBufferEXT GLEW_GET_FUN(__glewTextureBufferEXT)
+#define glTextureImage1DEXT GLEW_GET_FUN(__glewTextureImage1DEXT)
+#define glTextureImage2DEXT GLEW_GET_FUN(__glewTextureImage2DEXT)
+#define glTextureImage3DEXT GLEW_GET_FUN(__glewTextureImage3DEXT)
+#define glTextureParameterIivEXT GLEW_GET_FUN(__glewTextureParameterIivEXT)
+#define glTextureParameterIuivEXT GLEW_GET_FUN(__glewTextureParameterIuivEXT)
+#define glTextureParameterfEXT GLEW_GET_FUN(__glewTextureParameterfEXT)
+#define glTextureParameterfvEXT GLEW_GET_FUN(__glewTextureParameterfvEXT)
+#define glTextureParameteriEXT GLEW_GET_FUN(__glewTextureParameteriEXT)
+#define glTextureParameterivEXT GLEW_GET_FUN(__glewTextureParameterivEXT)
+#define glTextureRenderbufferEXT GLEW_GET_FUN(__glewTextureRenderbufferEXT)
+#define glTextureSubImage1DEXT GLEW_GET_FUN(__glewTextureSubImage1DEXT)
+#define glTextureSubImage2DEXT GLEW_GET_FUN(__glewTextureSubImage2DEXT)
+#define glTextureSubImage3DEXT GLEW_GET_FUN(__glewTextureSubImage3DEXT)
+#define glUnmapNamedBufferEXT GLEW_GET_FUN(__glewUnmapNamedBufferEXT)
+#define glVertexArrayColorOffsetEXT GLEW_GET_FUN(__glewVertexArrayColorOffsetEXT)
+#define glVertexArrayEdgeFlagOffsetEXT GLEW_GET_FUN(__glewVertexArrayEdgeFlagOffsetEXT)
+#define glVertexArrayFogCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayFogCoordOffsetEXT)
+#define glVertexArrayIndexOffsetEXT GLEW_GET_FUN(__glewVertexArrayIndexOffsetEXT)
+#define glVertexArrayMultiTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayMultiTexCoordOffsetEXT)
+#define glVertexArrayNormalOffsetEXT GLEW_GET_FUN(__glewVertexArrayNormalOffsetEXT)
+#define glVertexArraySecondaryColorOffsetEXT GLEW_GET_FUN(__glewVertexArraySecondaryColorOffsetEXT)
+#define glVertexArrayTexCoordOffsetEXT GLEW_GET_FUN(__glewVertexArrayTexCoordOffsetEXT)
+#define glVertexArrayVertexAttribIOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribIOffsetEXT)
+#define glVertexArrayVertexAttribOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribOffsetEXT)
+#define glVertexArrayVertexOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexOffsetEXT)
+
+#define GLEW_EXT_direct_state_access GLEW_GET_VAR(__GLEW_EXT_direct_state_access)
+
+#endif /* GL_EXT_direct_state_access */
+
+/* -------------------------- GL_EXT_draw_buffers2 ------------------------- */
+
+#ifndef GL_EXT_draw_buffers2
+#define GL_EXT_draw_buffers2 1
+
+typedef void (GLAPIENTRY * PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef void (GLAPIENTRY * PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index);
+typedef void (GLAPIENTRY * PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index);
+typedef void (GLAPIENTRY * PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum value, GLuint index, GLboolean* data);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum value, GLuint index, GLint* data);
+typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index);
+
+#define glColorMaskIndexedEXT GLEW_GET_FUN(__glewColorMaskIndexedEXT)
+#define glDisableIndexedEXT GLEW_GET_FUN(__glewDisableIndexedEXT)
+#define glEnableIndexedEXT GLEW_GET_FUN(__glewEnableIndexedEXT)
+#define glGetBooleanIndexedvEXT GLEW_GET_FUN(__glewGetBooleanIndexedvEXT)
+#define glGetIntegerIndexedvEXT GLEW_GET_FUN(__glewGetIntegerIndexedvEXT)
+#define glIsEnabledIndexedEXT GLEW_GET_FUN(__glewIsEnabledIndexedEXT)
+
+#define GLEW_EXT_draw_buffers2 GLEW_GET_VAR(__GLEW_EXT_draw_buffers2)
+
+#endif /* GL_EXT_draw_buffers2 */
+
+/* ------------------------- GL_EXT_draw_instanced ------------------------- */
+
+#ifndef GL_EXT_draw_instanced
+#define GL_EXT_draw_instanced 1
+
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+
+#define glDrawArraysInstancedEXT GLEW_GET_FUN(__glewDrawArraysInstancedEXT)
+#define glDrawElementsInstancedEXT GLEW_GET_FUN(__glewDrawElementsInstancedEXT)
+
+#define GLEW_EXT_draw_instanced GLEW_GET_VAR(__GLEW_EXT_draw_instanced)
+
+#endif /* GL_EXT_draw_instanced */
+
+/* ----------------------- GL_EXT_draw_range_elements ---------------------- */
+
+#ifndef GL_EXT_draw_range_elements
+#define GL_EXT_draw_range_elements 1
+
+#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8
+#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9
+
+typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+
+#define glDrawRangeElementsEXT GLEW_GET_FUN(__glewDrawRangeElementsEXT)
+
+#define GLEW_EXT_draw_range_elements GLEW_GET_VAR(__GLEW_EXT_draw_range_elements)
+
+#endif /* GL_EXT_draw_range_elements */
+
+/* ---------------------------- GL_EXT_fog_coord --------------------------- */
+
+#ifndef GL_EXT_fog_coord
+#define GL_EXT_fog_coord 1
+
+#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450
+#define GL_FOG_COORDINATE_EXT 0x8451
+#define GL_FRAGMENT_DEPTH_EXT 0x8452
+#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456
+#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457
+
+typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord);
+
+#define glFogCoordPointerEXT GLEW_GET_FUN(__glewFogCoordPointerEXT)
+#define glFogCoorddEXT GLEW_GET_FUN(__glewFogCoorddEXT)
+#define glFogCoorddvEXT GLEW_GET_FUN(__glewFogCoorddvEXT)
+#define glFogCoordfEXT GLEW_GET_FUN(__glewFogCoordfEXT)
+#define glFogCoordfvEXT GLEW_GET_FUN(__glewFogCoordfvEXT)
+
+#define GLEW_EXT_fog_coord GLEW_GET_VAR(__GLEW_EXT_fog_coord)
+
+#endif /* GL_EXT_fog_coord */
+
+/* ------------------------ GL_EXT_fragment_lighting ----------------------- */
+
+#ifndef GL_EXT_fragment_lighting
+#define GL_EXT_fragment_lighting 1
+
+#define GL_FRAGMENT_LIGHTING_EXT 0x8400
+#define GL_FRAGMENT_COLOR_MATERIAL_EXT 0x8401
+#define GL_FRAGMENT_COLOR_MATERIAL_FACE_EXT 0x8402
+#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_EXT 0x8403
+#define GL_MAX_FRAGMENT_LIGHTS_EXT 0x8404
+#define GL_MAX_ACTIVE_LIGHTS_EXT 0x8405
+#define GL_CURRENT_RASTER_NORMAL_EXT 0x8406
+#define GL_LIGHT_ENV_MODE_EXT 0x8407
+#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_EXT 0x8408
+#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_EXT 0x8409
+#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_EXT 0x840A
+#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_EXT 0x840B
+#define GL_FRAGMENT_LIGHT0_EXT 0x840C
+#define GL_FRAGMENT_LIGHT7_EXT 0x8413
+
+typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALEXTPROC) (GLenum face, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFEXTPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVEXTPROC) (GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIEXTPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVEXTPROC) (GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFEXTPROC) (GLenum light, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIEXTPROC) (GLenum light, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFEXTPROC) (GLenum face, GLenum pname, const GLfloat param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIEXTPROC) (GLenum face, GLenum pname, const GLint param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVEXTPROC) (GLenum light, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVEXTPROC) (GLenum light, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVEXTPROC) (GLenum face, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVEXTPROC) (GLenum face, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLLIGHTENVIEXTPROC) (GLenum pname, GLint param);
+
+#define glFragmentColorMaterialEXT GLEW_GET_FUN(__glewFragmentColorMaterialEXT)
+#define glFragmentLightModelfEXT GLEW_GET_FUN(__glewFragmentLightModelfEXT)
+#define glFragmentLightModelfvEXT GLEW_GET_FUN(__glewFragmentLightModelfvEXT)
+#define glFragmentLightModeliEXT GLEW_GET_FUN(__glewFragmentLightModeliEXT)
+#define glFragmentLightModelivEXT GLEW_GET_FUN(__glewFragmentLightModelivEXT)
+#define glFragmentLightfEXT GLEW_GET_FUN(__glewFragmentLightfEXT)
+#define glFragmentLightfvEXT GLEW_GET_FUN(__glewFragmentLightfvEXT)
+#define glFragmentLightiEXT GLEW_GET_FUN(__glewFragmentLightiEXT)
+#define glFragmentLightivEXT GLEW_GET_FUN(__glewFragmentLightivEXT)
+#define glFragmentMaterialfEXT GLEW_GET_FUN(__glewFragmentMaterialfEXT)
+#define glFragmentMaterialfvEXT GLEW_GET_FUN(__glewFragmentMaterialfvEXT)
+#define glFragmentMaterialiEXT GLEW_GET_FUN(__glewFragmentMaterialiEXT)
+#define glFragmentMaterialivEXT GLEW_GET_FUN(__glewFragmentMaterialivEXT)
+#define glGetFragmentLightfvEXT GLEW_GET_FUN(__glewGetFragmentLightfvEXT)
+#define glGetFragmentLightivEXT GLEW_GET_FUN(__glewGetFragmentLightivEXT)
+#define glGetFragmentMaterialfvEXT GLEW_GET_FUN(__glewGetFragmentMaterialfvEXT)
+#define glGetFragmentMaterialivEXT GLEW_GET_FUN(__glewGetFragmentMaterialivEXT)
+#define glLightEnviEXT GLEW_GET_FUN(__glewLightEnviEXT)
+
+#define GLEW_EXT_fragment_lighting GLEW_GET_VAR(__GLEW_EXT_fragment_lighting)
+
+#endif /* GL_EXT_fragment_lighting */
+
+/* ------------------------ GL_EXT_framebuffer_blit ------------------------ */
+
+#ifndef GL_EXT_framebuffer_blit
+#define GL_EXT_framebuffer_blit 1
+
+#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6
+#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
+
+typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+
+#define glBlitFramebufferEXT GLEW_GET_FUN(__glewBlitFramebufferEXT)
+
+#define GLEW_EXT_framebuffer_blit GLEW_GET_VAR(__GLEW_EXT_framebuffer_blit)
+
+#endif /* GL_EXT_framebuffer_blit */
+
+/* --------------------- GL_EXT_framebuffer_multisample -------------------- */
+
+#ifndef GL_EXT_framebuffer_multisample
+#define GL_EXT_framebuffer_multisample 1
+
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT 0x8D57
+
+typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+
+#define glRenderbufferStorageMultisampleEXT GLEW_GET_FUN(__glewRenderbufferStorageMultisampleEXT)
+
+#define GLEW_EXT_framebuffer_multisample GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample)
+
+#endif /* GL_EXT_framebuffer_multisample */
+
+/* --------------- GL_EXT_framebuffer_multisample_blit_scaled -------------- */
+
+#ifndef GL_EXT_framebuffer_multisample_blit_scaled
+#define GL_EXT_framebuffer_multisample_blit_scaled 1
+
+#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA
+#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB
+
+#define GLEW_EXT_framebuffer_multisample_blit_scaled GLEW_GET_VAR(__GLEW_EXT_framebuffer_multisample_blit_scaled)
+
+#endif /* GL_EXT_framebuffer_multisample_blit_scaled */
+
+/* ----------------------- GL_EXT_framebuffer_object ----------------------- */
+
+#ifndef GL_EXT_framebuffer_object
+#define GL_EXT_framebuffer_object 1
+
+#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
+#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
+#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
+#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
+#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
+#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
+#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
+#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
+#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
+#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
+#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
+#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
+#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
+#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
+#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
+#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
+#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
+#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
+#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
+#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
+#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
+#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
+#define GL_DEPTH_ATTACHMENT_EXT 0x8D00
+#define GL_STENCIL_ATTACHMENT_EXT 0x8D20
+#define GL_FRAMEBUFFER_EXT 0x8D40
+#define GL_RENDERBUFFER_EXT 0x8D41
+#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
+#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
+#define GL_STENCIL_INDEX1_EXT 0x8D46
+#define GL_STENCIL_INDEX4_EXT 0x8D47
+#define GL_STENCIL_INDEX8_EXT 0x8D48
+#define GL_STENCIL_INDEX16_EXT 0x8D49
+#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
+
+typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
+typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
+typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint* framebuffers);
+typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint* renderbuffers);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint* framebuffers);
+typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint* renderbuffers);
+typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPEXTPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer);
+typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer);
+typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+
+#define glBindFramebufferEXT GLEW_GET_FUN(__glewBindFramebufferEXT)
+#define glBindRenderbufferEXT GLEW_GET_FUN(__glewBindRenderbufferEXT)
+#define glCheckFramebufferStatusEXT GLEW_GET_FUN(__glewCheckFramebufferStatusEXT)
+#define glDeleteFramebuffersEXT GLEW_GET_FUN(__glewDeleteFramebuffersEXT)
+#define glDeleteRenderbuffersEXT GLEW_GET_FUN(__glewDeleteRenderbuffersEXT)
+#define glFramebufferRenderbufferEXT GLEW_GET_FUN(__glewFramebufferRenderbufferEXT)
+#define glFramebufferTexture1DEXT GLEW_GET_FUN(__glewFramebufferTexture1DEXT)
+#define glFramebufferTexture2DEXT GLEW_GET_FUN(__glewFramebufferTexture2DEXT)
+#define glFramebufferTexture3DEXT GLEW_GET_FUN(__glewFramebufferTexture3DEXT)
+#define glGenFramebuffersEXT GLEW_GET_FUN(__glewGenFramebuffersEXT)
+#define glGenRenderbuffersEXT GLEW_GET_FUN(__glewGenRenderbuffersEXT)
+#define glGenerateMipmapEXT GLEW_GET_FUN(__glewGenerateMipmapEXT)
+#define glGetFramebufferAttachmentParameterivEXT GLEW_GET_FUN(__glewGetFramebufferAttachmentParameterivEXT)
+#define glGetRenderbufferParameterivEXT GLEW_GET_FUN(__glewGetRenderbufferParameterivEXT)
+#define glIsFramebufferEXT GLEW_GET_FUN(__glewIsFramebufferEXT)
+#define glIsRenderbufferEXT GLEW_GET_FUN(__glewIsRenderbufferEXT)
+#define glRenderbufferStorageEXT GLEW_GET_FUN(__glewRenderbufferStorageEXT)
+
+#define GLEW_EXT_framebuffer_object GLEW_GET_VAR(__GLEW_EXT_framebuffer_object)
+
+#endif /* GL_EXT_framebuffer_object */
+
+/* ------------------------ GL_EXT_framebuffer_sRGB ------------------------ */
+
+#ifndef GL_EXT_framebuffer_sRGB
+#define GL_EXT_framebuffer_sRGB 1
+
+#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
+#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA
+
+#define GLEW_EXT_framebuffer_sRGB GLEW_GET_VAR(__GLEW_EXT_framebuffer_sRGB)
+
+#endif /* GL_EXT_framebuffer_sRGB */
+
+/* ------------------------ GL_EXT_geometry_shader4 ------------------------ */
+
+#ifndef GL_EXT_geometry_shader4
+#define GL_EXT_geometry_shader4 1
+
+#define GL_LINES_ADJACENCY_EXT 0xA
+#define GL_LINE_STRIP_ADJACENCY_EXT 0xB
+#define GL_TRIANGLES_ADJACENCY_EXT 0xC
+#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0xD
+#define GL_PROGRAM_POINT_SIZE_EXT 0x8642
+#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9
+#define GL_GEOMETRY_SHADER_EXT 0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA
+#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB
+#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
+
+#define glFramebufferTextureEXT GLEW_GET_FUN(__glewFramebufferTextureEXT)
+#define glFramebufferTextureFaceEXT GLEW_GET_FUN(__glewFramebufferTextureFaceEXT)
+#define glProgramParameteriEXT GLEW_GET_FUN(__glewProgramParameteriEXT)
+
+#define GLEW_EXT_geometry_shader4 GLEW_GET_VAR(__GLEW_EXT_geometry_shader4)
+
+#endif /* GL_EXT_geometry_shader4 */
+
+/* --------------------- GL_EXT_gpu_program_parameters --------------------- */
+
+#ifndef GL_EXT_gpu_program_parameters
+#define GL_EXT_gpu_program_parameters 1
+
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat* params);
+
+#define glProgramEnvParameters4fvEXT GLEW_GET_FUN(__glewProgramEnvParameters4fvEXT)
+#define glProgramLocalParameters4fvEXT GLEW_GET_FUN(__glewProgramLocalParameters4fvEXT)
+
+#define GLEW_EXT_gpu_program_parameters GLEW_GET_VAR(__GLEW_EXT_gpu_program_parameters)
+
+#endif /* GL_EXT_gpu_program_parameters */
+
+/* --------------------------- GL_EXT_gpu_shader4 -------------------------- */
+
+#ifndef GL_EXT_gpu_shader4
+#define GL_EXT_gpu_shader4 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD
+#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0
+#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1
+#define GL_SAMPLER_BUFFER_EXT 0x8DC2
+#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3
+#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5
+#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6
+#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7
+#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8
+#define GL_INT_SAMPLER_1D_EXT 0x8DC9
+#define GL_INT_SAMPLER_2D_EXT 0x8DCA
+#define GL_INT_SAMPLER_3D_EXT 0x8DCB
+#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC
+#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD
+#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE
+#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF
+#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8
+
+typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+
+#define glBindFragDataLocationEXT GLEW_GET_FUN(__glewBindFragDataLocationEXT)
+#define glGetFragDataLocationEXT GLEW_GET_FUN(__glewGetFragDataLocationEXT)
+#define glGetUniformuivEXT GLEW_GET_FUN(__glewGetUniformuivEXT)
+#define glGetVertexAttribIivEXT GLEW_GET_FUN(__glewGetVertexAttribIivEXT)
+#define glGetVertexAttribIuivEXT GLEW_GET_FUN(__glewGetVertexAttribIuivEXT)
+#define glUniform1uiEXT GLEW_GET_FUN(__glewUniform1uiEXT)
+#define glUniform1uivEXT GLEW_GET_FUN(__glewUniform1uivEXT)
+#define glUniform2uiEXT GLEW_GET_FUN(__glewUniform2uiEXT)
+#define glUniform2uivEXT GLEW_GET_FUN(__glewUniform2uivEXT)
+#define glUniform3uiEXT GLEW_GET_FUN(__glewUniform3uiEXT)
+#define glUniform3uivEXT GLEW_GET_FUN(__glewUniform3uivEXT)
+#define glUniform4uiEXT GLEW_GET_FUN(__glewUniform4uiEXT)
+#define glUniform4uivEXT GLEW_GET_FUN(__glewUniform4uivEXT)
+#define glVertexAttribI1iEXT GLEW_GET_FUN(__glewVertexAttribI1iEXT)
+#define glVertexAttribI1ivEXT GLEW_GET_FUN(__glewVertexAttribI1ivEXT)
+#define glVertexAttribI1uiEXT GLEW_GET_FUN(__glewVertexAttribI1uiEXT)
+#define glVertexAttribI1uivEXT GLEW_GET_FUN(__glewVertexAttribI1uivEXT)
+#define glVertexAttribI2iEXT GLEW_GET_FUN(__glewVertexAttribI2iEXT)
+#define glVertexAttribI2ivEXT GLEW_GET_FUN(__glewVertexAttribI2ivEXT)
+#define glVertexAttribI2uiEXT GLEW_GET_FUN(__glewVertexAttribI2uiEXT)
+#define glVertexAttribI2uivEXT GLEW_GET_FUN(__glewVertexAttribI2uivEXT)
+#define glVertexAttribI3iEXT GLEW_GET_FUN(__glewVertexAttribI3iEXT)
+#define glVertexAttribI3ivEXT GLEW_GET_FUN(__glewVertexAttribI3ivEXT)
+#define glVertexAttribI3uiEXT GLEW_GET_FUN(__glewVertexAttribI3uiEXT)
+#define glVertexAttribI3uivEXT GLEW_GET_FUN(__glewVertexAttribI3uivEXT)
+#define glVertexAttribI4bvEXT GLEW_GET_FUN(__glewVertexAttribI4bvEXT)
+#define glVertexAttribI4iEXT GLEW_GET_FUN(__glewVertexAttribI4iEXT)
+#define glVertexAttribI4ivEXT GLEW_GET_FUN(__glewVertexAttribI4ivEXT)
+#define glVertexAttribI4svEXT GLEW_GET_FUN(__glewVertexAttribI4svEXT)
+#define glVertexAttribI4ubvEXT GLEW_GET_FUN(__glewVertexAttribI4ubvEXT)
+#define glVertexAttribI4uiEXT GLEW_GET_FUN(__glewVertexAttribI4uiEXT)
+#define glVertexAttribI4uivEXT GLEW_GET_FUN(__glewVertexAttribI4uivEXT)
+#define glVertexAttribI4usvEXT GLEW_GET_FUN(__glewVertexAttribI4usvEXT)
+#define glVertexAttribIPointerEXT GLEW_GET_FUN(__glewVertexAttribIPointerEXT)
+
+#define GLEW_EXT_gpu_shader4 GLEW_GET_VAR(__GLEW_EXT_gpu_shader4)
+
+#endif /* GL_EXT_gpu_shader4 */
+
+/* ---------------------------- GL_EXT_histogram --------------------------- */
+
+#ifndef GL_EXT_histogram
+#define GL_EXT_histogram 1
+
+#define GL_HISTOGRAM_EXT 0x8024
+#define GL_PROXY_HISTOGRAM_EXT 0x8025
+#define GL_HISTOGRAM_WIDTH_EXT 0x8026
+#define GL_HISTOGRAM_FORMAT_EXT 0x8027
+#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C
+#define GL_HISTOGRAM_SINK_EXT 0x802D
+#define GL_MINMAX_EXT 0x802E
+#define GL_MINMAX_FORMAT_EXT 0x802F
+#define GL_MINMAX_SINK_EXT 0x8030
+
+typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (GLAPIENTRY * PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMEXTPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLRESETMINMAXEXTPROC) (GLenum target);
+
+#define glGetHistogramEXT GLEW_GET_FUN(__glewGetHistogramEXT)
+#define glGetHistogramParameterfvEXT GLEW_GET_FUN(__glewGetHistogramParameterfvEXT)
+#define glGetHistogramParameterivEXT GLEW_GET_FUN(__glewGetHistogramParameterivEXT)
+#define glGetMinmaxEXT GLEW_GET_FUN(__glewGetMinmaxEXT)
+#define glGetMinmaxParameterfvEXT GLEW_GET_FUN(__glewGetMinmaxParameterfvEXT)
+#define glGetMinmaxParameterivEXT GLEW_GET_FUN(__glewGetMinmaxParameterivEXT)
+#define glHistogramEXT GLEW_GET_FUN(__glewHistogramEXT)
+#define glMinmaxEXT GLEW_GET_FUN(__glewMinmaxEXT)
+#define glResetHistogramEXT GLEW_GET_FUN(__glewResetHistogramEXT)
+#define glResetMinmaxEXT GLEW_GET_FUN(__glewResetMinmaxEXT)
+
+#define GLEW_EXT_histogram GLEW_GET_VAR(__GLEW_EXT_histogram)
+
+#endif /* GL_EXT_histogram */
+
+/* ----------------------- GL_EXT_index_array_formats ---------------------- */
+
+#ifndef GL_EXT_index_array_formats
+#define GL_EXT_index_array_formats 1
+
+#define GLEW_EXT_index_array_formats GLEW_GET_VAR(__GLEW_EXT_index_array_formats)
+
+#endif /* GL_EXT_index_array_formats */
+
+/* --------------------------- GL_EXT_index_func --------------------------- */
+
+#ifndef GL_EXT_index_func
+#define GL_EXT_index_func 1
+
+typedef void (GLAPIENTRY * PFNGLINDEXFUNCEXTPROC) (GLenum func, GLfloat ref);
+
+#define glIndexFuncEXT GLEW_GET_FUN(__glewIndexFuncEXT)
+
+#define GLEW_EXT_index_func GLEW_GET_VAR(__GLEW_EXT_index_func)
+
+#endif /* GL_EXT_index_func */
+
+/* ------------------------- GL_EXT_index_material ------------------------- */
+
+#ifndef GL_EXT_index_material
+#define GL_EXT_index_material 1
+
+typedef void (GLAPIENTRY * PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode);
+
+#define glIndexMaterialEXT GLEW_GET_FUN(__glewIndexMaterialEXT)
+
+#define GLEW_EXT_index_material GLEW_GET_VAR(__GLEW_EXT_index_material)
+
+#endif /* GL_EXT_index_material */
+
+/* -------------------------- GL_EXT_index_texture ------------------------- */
+
+#ifndef GL_EXT_index_texture
+#define GL_EXT_index_texture 1
+
+#define GLEW_EXT_index_texture GLEW_GET_VAR(__GLEW_EXT_index_texture)
+
+#endif /* GL_EXT_index_texture */
+
+/* -------------------------- GL_EXT_light_texture ------------------------- */
+
+#ifndef GL_EXT_light_texture
+#define GL_EXT_light_texture 1
+
+#define GL_FRAGMENT_MATERIAL_EXT 0x8349
+#define GL_FRAGMENT_NORMAL_EXT 0x834A
+#define GL_FRAGMENT_COLOR_EXT 0x834C
+#define GL_ATTENUATION_EXT 0x834D
+#define GL_SHADOW_ATTENUATION_EXT 0x834E
+#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F
+#define GL_TEXTURE_LIGHT_EXT 0x8350
+#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351
+#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352
+
+typedef void (GLAPIENTRY * PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode);
+typedef void (GLAPIENTRY * PFNGLTEXTURELIGHTEXTPROC) (GLenum pname);
+typedef void (GLAPIENTRY * PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode);
+
+#define glApplyTextureEXT GLEW_GET_FUN(__glewApplyTextureEXT)
+#define glTextureLightEXT GLEW_GET_FUN(__glewTextureLightEXT)
+#define glTextureMaterialEXT GLEW_GET_FUN(__glewTextureMaterialEXT)
+
+#define GLEW_EXT_light_texture GLEW_GET_VAR(__GLEW_EXT_light_texture)
+
+#endif /* GL_EXT_light_texture */
+
+/* ------------------------- GL_EXT_misc_attribute ------------------------- */
+
+#ifndef GL_EXT_misc_attribute
+#define GL_EXT_misc_attribute 1
+
+#define GLEW_EXT_misc_attribute GLEW_GET_VAR(__GLEW_EXT_misc_attribute)
+
+#endif /* GL_EXT_misc_attribute */
+
+/* ------------------------ GL_EXT_multi_draw_arrays ----------------------- */
+
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, GLsizei* count, GLenum type, const GLvoid * const *indices, GLsizei primcount);
+
+#define glMultiDrawArraysEXT GLEW_GET_FUN(__glewMultiDrawArraysEXT)
+#define glMultiDrawElementsEXT GLEW_GET_FUN(__glewMultiDrawElementsEXT)
+
+#define GLEW_EXT_multi_draw_arrays GLEW_GET_VAR(__GLEW_EXT_multi_draw_arrays)
+
+#endif /* GL_EXT_multi_draw_arrays */
+
+/* --------------------------- GL_EXT_multisample -------------------------- */
+
+#ifndef GL_EXT_multisample
+#define GL_EXT_multisample 1
+
+#define GL_MULTISAMPLE_EXT 0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F
+#define GL_SAMPLE_MASK_EXT 0x80A0
+#define GL_1PASS_EXT 0x80A1
+#define GL_2PASS_0_EXT 0x80A2
+#define GL_2PASS_1_EXT 0x80A3
+#define GL_4PASS_0_EXT 0x80A4
+#define GL_4PASS_1_EXT 0x80A5
+#define GL_4PASS_2_EXT 0x80A6
+#define GL_4PASS_3_EXT 0x80A7
+#define GL_SAMPLE_BUFFERS_EXT 0x80A8
+#define GL_SAMPLES_EXT 0x80A9
+#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA
+#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB
+#define GL_SAMPLE_PATTERN_EXT 0x80AC
+#define GL_MULTISAMPLE_BIT_EXT 0x20000000
+
+typedef void (GLAPIENTRY * PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert);
+typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern);
+
+#define glSampleMaskEXT GLEW_GET_FUN(__glewSampleMaskEXT)
+#define glSamplePatternEXT GLEW_GET_FUN(__glewSamplePatternEXT)
+
+#define GLEW_EXT_multisample GLEW_GET_VAR(__GLEW_EXT_multisample)
+
+#endif /* GL_EXT_multisample */
+
+/* ---------------------- GL_EXT_packed_depth_stencil ---------------------- */
+
+#ifndef GL_EXT_packed_depth_stencil
+#define GL_EXT_packed_depth_stencil 1
+
+#define GL_DEPTH_STENCIL_EXT 0x84F9
+#define GL_UNSIGNED_INT_24_8_EXT 0x84FA
+#define GL_DEPTH24_STENCIL8_EXT 0x88F0
+#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
+
+#define GLEW_EXT_packed_depth_stencil GLEW_GET_VAR(__GLEW_EXT_packed_depth_stencil)
+
+#endif /* GL_EXT_packed_depth_stencil */
+
+/* -------------------------- GL_EXT_packed_float -------------------------- */
+
+#ifndef GL_EXT_packed_float
+#define GL_EXT_packed_float 1
+
+#define GL_R11F_G11F_B10F_EXT 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B
+#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C
+
+#define GLEW_EXT_packed_float GLEW_GET_VAR(__GLEW_EXT_packed_float)
+
+#endif /* GL_EXT_packed_float */
+
+/* -------------------------- GL_EXT_packed_pixels ------------------------- */
+
+#ifndef GL_EXT_packed_pixels
+#define GL_EXT_packed_pixels 1
+
+#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036
+
+#define GLEW_EXT_packed_pixels GLEW_GET_VAR(__GLEW_EXT_packed_pixels)
+
+#endif /* GL_EXT_packed_pixels */
+
+/* ------------------------ GL_EXT_paletted_texture ------------------------ */
+
+#ifndef GL_EXT_paletted_texture
+#define GL_EXT_paletted_texture 1
+
+#define GL_TEXTURE_1D 0x0DE0
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_PROXY_TEXTURE_1D 0x8063
+#define GL_PROXY_TEXTURE_2D 0x8064
+#define GL_COLOR_TABLE_FORMAT_EXT 0x80D8
+#define GL_COLOR_TABLE_WIDTH_EXT 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE_EXT 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE_EXT 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE_EXT 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE_EXT 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE_EXT 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE_EXT 0x80DF
+#define GL_COLOR_INDEX1_EXT 0x80E2
+#define GL_COLOR_INDEX2_EXT 0x80E3
+#define GL_COLOR_INDEX4_EXT 0x80E4
+#define GL_COLOR_INDEX8_EXT 0x80E5
+#define GL_COLOR_INDEX12_EXT 0x80E6
+#define GL_COLOR_INDEX16_EXT 0x80E7
+#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED
+#define GL_TEXTURE_CUBE_MAP_ARB 0x8513
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
+
+typedef void (GLAPIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params);
+
+#define glColorTableEXT GLEW_GET_FUN(__glewColorTableEXT)
+#define glGetColorTableEXT GLEW_GET_FUN(__glewGetColorTableEXT)
+#define glGetColorTableParameterfvEXT GLEW_GET_FUN(__glewGetColorTableParameterfvEXT)
+#define glGetColorTableParameterivEXT GLEW_GET_FUN(__glewGetColorTableParameterivEXT)
+
+#define GLEW_EXT_paletted_texture GLEW_GET_VAR(__GLEW_EXT_paletted_texture)
+
+#endif /* GL_EXT_paletted_texture */
+
+/* ----------------------- GL_EXT_pixel_buffer_object ---------------------- */
+
+#ifndef GL_EXT_pixel_buffer_object
+#define GL_EXT_pixel_buffer_object 1
+
+#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF
+
+#define GLEW_EXT_pixel_buffer_object GLEW_GET_VAR(__GLEW_EXT_pixel_buffer_object)
+
+#endif /* GL_EXT_pixel_buffer_object */
+
+/* ------------------------- GL_EXT_pixel_transform ------------------------ */
+
+#ifndef GL_EXT_pixel_transform
+#define GL_EXT_pixel_transform 1
+
+#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330
+#define GL_PIXEL_MAG_FILTER_EXT 0x8331
+#define GL_PIXEL_MIN_FILTER_EXT 0x8332
+#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333
+#define GL_CUBIC_EXT 0x8334
+#define GL_AVERAGE_EXT 0x8335
+#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336
+#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337
+#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338
+
+typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, const GLfloat param);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, const GLint param);
+typedef void (GLAPIENTRY * PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint* params);
+
+#define glGetPixelTransformParameterfvEXT GLEW_GET_FUN(__glewGetPixelTransformParameterfvEXT)
+#define glGetPixelTransformParameterivEXT GLEW_GET_FUN(__glewGetPixelTransformParameterivEXT)
+#define glPixelTransformParameterfEXT GLEW_GET_FUN(__glewPixelTransformParameterfEXT)
+#define glPixelTransformParameterfvEXT GLEW_GET_FUN(__glewPixelTransformParameterfvEXT)
+#define glPixelTransformParameteriEXT GLEW_GET_FUN(__glewPixelTransformParameteriEXT)
+#define glPixelTransformParameterivEXT GLEW_GET_FUN(__glewPixelTransformParameterivEXT)
+
+#define GLEW_EXT_pixel_transform GLEW_GET_VAR(__GLEW_EXT_pixel_transform)
+
+#endif /* GL_EXT_pixel_transform */
+
+/* ------------------- GL_EXT_pixel_transform_color_table ------------------ */
+
+#ifndef GL_EXT_pixel_transform_color_table
+#define GL_EXT_pixel_transform_color_table 1
+
+#define GLEW_EXT_pixel_transform_color_table GLEW_GET_VAR(__GLEW_EXT_pixel_transform_color_table)
+
+#endif /* GL_EXT_pixel_transform_color_table */
+
+/* ------------------------ GL_EXT_point_parameters ------------------------ */
+
+#ifndef GL_EXT_point_parameters
+#define GL_EXT_point_parameters 1
+
+#define GL_POINT_SIZE_MIN_EXT 0x8126
+#define GL_POINT_SIZE_MAX_EXT 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128
+#define GL_DISTANCE_ATTENUATION_EXT 0x8129
+
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat* params);
+
+#define glPointParameterfEXT GLEW_GET_FUN(__glewPointParameterfEXT)
+#define glPointParameterfvEXT GLEW_GET_FUN(__glewPointParameterfvEXT)
+
+#define GLEW_EXT_point_parameters GLEW_GET_VAR(__GLEW_EXT_point_parameters)
+
+#endif /* GL_EXT_point_parameters */
+
+/* ------------------------- GL_EXT_polygon_offset ------------------------- */
+
+#ifndef GL_EXT_polygon_offset
+#define GL_EXT_polygon_offset 1
+
+#define GL_POLYGON_OFFSET_EXT 0x8037
+#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038
+#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039
+
+typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias);
+
+#define glPolygonOffsetEXT GLEW_GET_FUN(__glewPolygonOffsetEXT)
+
+#define GLEW_EXT_polygon_offset GLEW_GET_VAR(__GLEW_EXT_polygon_offset)
+
+#endif /* GL_EXT_polygon_offset */
+
+/* ------------------------ GL_EXT_provoking_vertex ------------------------ */
+
+#ifndef GL_EXT_provoking_vertex
+#define GL_EXT_provoking_vertex 1
+
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E
+#define GL_PROVOKING_VERTEX_EXT 0x8E4F
+
+typedef void (GLAPIENTRY * PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode);
+
+#define glProvokingVertexEXT GLEW_GET_FUN(__glewProvokingVertexEXT)
+
+#define GLEW_EXT_provoking_vertex GLEW_GET_VAR(__GLEW_EXT_provoking_vertex)
+
+#endif /* GL_EXT_provoking_vertex */
+
+/* ------------------------- GL_EXT_rescale_normal ------------------------- */
+
+#ifndef GL_EXT_rescale_normal
+#define GL_EXT_rescale_normal 1
+
+#define GL_RESCALE_NORMAL_EXT 0x803A
+
+#define GLEW_EXT_rescale_normal GLEW_GET_VAR(__GLEW_EXT_rescale_normal)
+
+#endif /* GL_EXT_rescale_normal */
+
+/* -------------------------- GL_EXT_scene_marker -------------------------- */
+
+#ifndef GL_EXT_scene_marker
+#define GL_EXT_scene_marker 1
+
+typedef void (GLAPIENTRY * PFNGLBEGINSCENEEXTPROC) (void);
+typedef void (GLAPIENTRY * PFNGLENDSCENEEXTPROC) (void);
+
+#define glBeginSceneEXT GLEW_GET_FUN(__glewBeginSceneEXT)
+#define glEndSceneEXT GLEW_GET_FUN(__glewEndSceneEXT)
+
+#define GLEW_EXT_scene_marker GLEW_GET_VAR(__GLEW_EXT_scene_marker)
+
+#endif /* GL_EXT_scene_marker */
+
+/* ------------------------- GL_EXT_secondary_color ------------------------ */
+
+#ifndef GL_EXT_secondary_color
+#define GL_EXT_secondary_color 1
+
+#define GL_COLOR_SUM_EXT 0x8458
+#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D
+#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E
+
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+
+#define glSecondaryColor3bEXT GLEW_GET_FUN(__glewSecondaryColor3bEXT)
+#define glSecondaryColor3bvEXT GLEW_GET_FUN(__glewSecondaryColor3bvEXT)
+#define glSecondaryColor3dEXT GLEW_GET_FUN(__glewSecondaryColor3dEXT)
+#define glSecondaryColor3dvEXT GLEW_GET_FUN(__glewSecondaryColor3dvEXT)
+#define glSecondaryColor3fEXT GLEW_GET_FUN(__glewSecondaryColor3fEXT)
+#define glSecondaryColor3fvEXT GLEW_GET_FUN(__glewSecondaryColor3fvEXT)
+#define glSecondaryColor3iEXT GLEW_GET_FUN(__glewSecondaryColor3iEXT)
+#define glSecondaryColor3ivEXT GLEW_GET_FUN(__glewSecondaryColor3ivEXT)
+#define glSecondaryColor3sEXT GLEW_GET_FUN(__glewSecondaryColor3sEXT)
+#define glSecondaryColor3svEXT GLEW_GET_FUN(__glewSecondaryColor3svEXT)
+#define glSecondaryColor3ubEXT GLEW_GET_FUN(__glewSecondaryColor3ubEXT)
+#define glSecondaryColor3ubvEXT GLEW_GET_FUN(__glewSecondaryColor3ubvEXT)
+#define glSecondaryColor3uiEXT GLEW_GET_FUN(__glewSecondaryColor3uiEXT)
+#define glSecondaryColor3uivEXT GLEW_GET_FUN(__glewSecondaryColor3uivEXT)
+#define glSecondaryColor3usEXT GLEW_GET_FUN(__glewSecondaryColor3usEXT)
+#define glSecondaryColor3usvEXT GLEW_GET_FUN(__glewSecondaryColor3usvEXT)
+#define glSecondaryColorPointerEXT GLEW_GET_FUN(__glewSecondaryColorPointerEXT)
+
+#define GLEW_EXT_secondary_color GLEW_GET_VAR(__GLEW_EXT_secondary_color)
+
+#endif /* GL_EXT_secondary_color */
+
+/* --------------------- GL_EXT_separate_shader_objects -------------------- */
+
+#ifndef GL_EXT_separate_shader_objects
+#define GL_EXT_separate_shader_objects 1
+
+#define GL_ACTIVE_PROGRAM_EXT 0x8B8D
+
+typedef void (GLAPIENTRY * PFNGLACTIVEPROGRAMEXTPROC) (GLuint program);
+typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar* string);
+typedef void (GLAPIENTRY * PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program);
+
+#define glActiveProgramEXT GLEW_GET_FUN(__glewActiveProgramEXT)
+#define glCreateShaderProgramEXT GLEW_GET_FUN(__glewCreateShaderProgramEXT)
+#define glUseShaderProgramEXT GLEW_GET_FUN(__glewUseShaderProgramEXT)
+
+#define GLEW_EXT_separate_shader_objects GLEW_GET_VAR(__GLEW_EXT_separate_shader_objects)
+
+#endif /* GL_EXT_separate_shader_objects */
+
+/* --------------------- GL_EXT_separate_specular_color -------------------- */
+
+#ifndef GL_EXT_separate_specular_color
+#define GL_EXT_separate_specular_color 1
+
+#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8
+#define GL_SINGLE_COLOR_EXT 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA
+
+#define GLEW_EXT_separate_specular_color GLEW_GET_VAR(__GLEW_EXT_separate_specular_color)
+
+#endif /* GL_EXT_separate_specular_color */
+
+/* --------------------- GL_EXT_shader_image_load_store -------------------- */
+
+#ifndef GL_EXT_shader_image_load_store
+#define GL_EXT_shader_image_load_store 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001
+#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002
+#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004
+#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020
+#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040
+#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080
+#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100
+#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200
+#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800
+#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000
+#define GL_MAX_IMAGE_UNITS_EXT 0x8F38
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39
+#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A
+#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B
+#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C
+#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D
+#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E
+#define GL_IMAGE_1D_EXT 0x904C
+#define GL_IMAGE_2D_EXT 0x904D
+#define GL_IMAGE_3D_EXT 0x904E
+#define GL_IMAGE_2D_RECT_EXT 0x904F
+#define GL_IMAGE_CUBE_EXT 0x9050
+#define GL_IMAGE_BUFFER_EXT 0x9051
+#define GL_IMAGE_1D_ARRAY_EXT 0x9052
+#define GL_IMAGE_2D_ARRAY_EXT 0x9053
+#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054
+#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056
+#define GL_INT_IMAGE_1D_EXT 0x9057
+#define GL_INT_IMAGE_2D_EXT 0x9058
+#define GL_INT_IMAGE_3D_EXT 0x9059
+#define GL_INT_IMAGE_2D_RECT_EXT 0x905A
+#define GL_INT_IMAGE_CUBE_EXT 0x905B
+#define GL_INT_IMAGE_BUFFER_EXT 0x905C
+#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D
+#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F
+#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061
+#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062
+#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063
+#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066
+#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C
+#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D
+#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E
+#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF
+
+typedef void (GLAPIENTRY * PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format);
+typedef void (GLAPIENTRY * PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers);
+
+#define glBindImageTextureEXT GLEW_GET_FUN(__glewBindImageTextureEXT)
+#define glMemoryBarrierEXT GLEW_GET_FUN(__glewMemoryBarrierEXT)
+
+#define GLEW_EXT_shader_image_load_store GLEW_GET_VAR(__GLEW_EXT_shader_image_load_store)
+
+#endif /* GL_EXT_shader_image_load_store */
+
+/* -------------------------- GL_EXT_shadow_funcs -------------------------- */
+
+#ifndef GL_EXT_shadow_funcs
+#define GL_EXT_shadow_funcs 1
+
+#define GLEW_EXT_shadow_funcs GLEW_GET_VAR(__GLEW_EXT_shadow_funcs)
+
+#endif /* GL_EXT_shadow_funcs */
+
+/* --------------------- GL_EXT_shared_texture_palette --------------------- */
+
+#ifndef GL_EXT_shared_texture_palette
+#define GL_EXT_shared_texture_palette 1
+
+#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB
+
+#define GLEW_EXT_shared_texture_palette GLEW_GET_VAR(__GLEW_EXT_shared_texture_palette)
+
+#endif /* GL_EXT_shared_texture_palette */
+
+/* ------------------------ GL_EXT_stencil_clear_tag ----------------------- */
+
+#ifndef GL_EXT_stencil_clear_tag
+#define GL_EXT_stencil_clear_tag 1
+
+#define GL_STENCIL_TAG_BITS_EXT 0x88F2
+#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3
+
+#define GLEW_EXT_stencil_clear_tag GLEW_GET_VAR(__GLEW_EXT_stencil_clear_tag)
+
+#endif /* GL_EXT_stencil_clear_tag */
+
+/* ------------------------ GL_EXT_stencil_two_side ------------------------ */
+
+#ifndef GL_EXT_stencil_two_side
+#define GL_EXT_stencil_two_side 1
+
+#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910
+#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911
+
+typedef void (GLAPIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
+
+#define glActiveStencilFaceEXT GLEW_GET_FUN(__glewActiveStencilFaceEXT)
+
+#define GLEW_EXT_stencil_two_side GLEW_GET_VAR(__GLEW_EXT_stencil_two_side)
+
+#endif /* GL_EXT_stencil_two_side */
+
+/* -------------------------- GL_EXT_stencil_wrap -------------------------- */
+
+#ifndef GL_EXT_stencil_wrap
+#define GL_EXT_stencil_wrap 1
+
+#define GL_INCR_WRAP_EXT 0x8507
+#define GL_DECR_WRAP_EXT 0x8508
+
+#define GLEW_EXT_stencil_wrap GLEW_GET_VAR(__GLEW_EXT_stencil_wrap)
+
+#endif /* GL_EXT_stencil_wrap */
+
+/* --------------------------- GL_EXT_subtexture --------------------------- */
+
+#ifndef GL_EXT_subtexture
+#define GL_EXT_subtexture 1
+
+typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+
+#define glTexSubImage1DEXT GLEW_GET_FUN(__glewTexSubImage1DEXT)
+#define glTexSubImage2DEXT GLEW_GET_FUN(__glewTexSubImage2DEXT)
+#define glTexSubImage3DEXT GLEW_GET_FUN(__glewTexSubImage3DEXT)
+
+#define GLEW_EXT_subtexture GLEW_GET_VAR(__GLEW_EXT_subtexture)
+
+#endif /* GL_EXT_subtexture */
+
+/* ----------------------------- GL_EXT_texture ---------------------------- */
+
+#ifndef GL_EXT_texture
+#define GL_EXT_texture 1
+
+#define GL_ALPHA4_EXT 0x803B
+#define GL_ALPHA8_EXT 0x803C
+#define GL_ALPHA12_EXT 0x803D
+#define GL_ALPHA16_EXT 0x803E
+#define GL_LUMINANCE4_EXT 0x803F
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE12_EXT 0x8041
+#define GL_LUMINANCE16_EXT 0x8042
+#define GL_LUMINANCE4_ALPHA4_EXT 0x8043
+#define GL_LUMINANCE6_ALPHA2_EXT 0x8044
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_LUMINANCE12_ALPHA4_EXT 0x8046
+#define GL_LUMINANCE12_ALPHA12_EXT 0x8047
+#define GL_LUMINANCE16_ALPHA16_EXT 0x8048
+#define GL_INTENSITY_EXT 0x8049
+#define GL_INTENSITY4_EXT 0x804A
+#define GL_INTENSITY8_EXT 0x804B
+#define GL_INTENSITY12_EXT 0x804C
+#define GL_INTENSITY16_EXT 0x804D
+#define GL_RGB2_EXT 0x804E
+#define GL_RGB4_EXT 0x804F
+#define GL_RGB5_EXT 0x8050
+#define GL_RGB8_EXT 0x8051
+#define GL_RGB10_EXT 0x8052
+#define GL_RGB12_EXT 0x8053
+#define GL_RGB16_EXT 0x8054
+#define GL_RGBA2_EXT 0x8055
+#define GL_RGBA4_EXT 0x8056
+#define GL_RGB5_A1_EXT 0x8057
+#define GL_RGBA8_EXT 0x8058
+#define GL_RGB10_A2_EXT 0x8059
+#define GL_RGBA12_EXT 0x805A
+#define GL_RGBA16_EXT 0x805B
+#define GL_TEXTURE_RED_SIZE_EXT 0x805C
+#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D
+#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E
+#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F
+#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060
+#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061
+#define GL_REPLACE_EXT 0x8062
+#define GL_PROXY_TEXTURE_1D_EXT 0x8063
+#define GL_PROXY_TEXTURE_2D_EXT 0x8064
+
+#define GLEW_EXT_texture GLEW_GET_VAR(__GLEW_EXT_texture)
+
+#endif /* GL_EXT_texture */
+
+/* ---------------------------- GL_EXT_texture3D --------------------------- */
+
+#ifndef GL_EXT_texture3D
+#define GL_EXT_texture3D 1
+
+#define GL_PACK_SKIP_IMAGES_EXT 0x806B
+#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C
+#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E
+#define GL_TEXTURE_3D_EXT 0x806F
+#define GL_PROXY_TEXTURE_3D_EXT 0x8070
+#define GL_TEXTURE_DEPTH_EXT 0x8071
+#define GL_TEXTURE_WRAP_R_EXT 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073
+
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+
+#define glTexImage3DEXT GLEW_GET_FUN(__glewTexImage3DEXT)
+
+#define GLEW_EXT_texture3D GLEW_GET_VAR(__GLEW_EXT_texture3D)
+
+#endif /* GL_EXT_texture3D */
+
+/* -------------------------- GL_EXT_texture_array ------------------------- */
+
+#ifndef GL_EXT_texture_array
+#define GL_EXT_texture_array 1
+
+#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E
+#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF
+#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18
+#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19
+#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A
+#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B
+#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D
+
+typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+
+#define glFramebufferTextureLayerEXT GLEW_GET_FUN(__glewFramebufferTextureLayerEXT)
+
+#define GLEW_EXT_texture_array GLEW_GET_VAR(__GLEW_EXT_texture_array)
+
+#endif /* GL_EXT_texture_array */
+
+/* ---------------------- GL_EXT_texture_buffer_object --------------------- */
+
+#ifndef GL_EXT_texture_buffer_object
+#define GL_EXT_texture_buffer_object 1
+
+#define GL_TEXTURE_BUFFER_EXT 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E
+
+typedef void (GLAPIENTRY * PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+
+#define glTexBufferEXT GLEW_GET_FUN(__glewTexBufferEXT)
+
+#define GLEW_EXT_texture_buffer_object GLEW_GET_VAR(__GLEW_EXT_texture_buffer_object)
+
+#endif /* GL_EXT_texture_buffer_object */
+
+/* -------------------- GL_EXT_texture_compression_dxt1 -------------------- */
+
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_EXT_texture_compression_dxt1 1
+
+#define GLEW_EXT_texture_compression_dxt1 GLEW_GET_VAR(__GLEW_EXT_texture_compression_dxt1)
+
+#endif /* GL_EXT_texture_compression_dxt1 */
+
+/* -------------------- GL_EXT_texture_compression_latc -------------------- */
+
+#ifndef GL_EXT_texture_compression_latc
+#define GL_EXT_texture_compression_latc 1
+
+#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
+#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71
+#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
+#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73
+
+#define GLEW_EXT_texture_compression_latc GLEW_GET_VAR(__GLEW_EXT_texture_compression_latc)
+
+#endif /* GL_EXT_texture_compression_latc */
+
+/* -------------------- GL_EXT_texture_compression_rgtc -------------------- */
+
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_EXT_texture_compression_rgtc 1
+
+#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
+#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
+#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
+
+#define GLEW_EXT_texture_compression_rgtc GLEW_GET_VAR(__GLEW_EXT_texture_compression_rgtc)
+
+#endif /* GL_EXT_texture_compression_rgtc */
+
+/* -------------------- GL_EXT_texture_compression_s3tc -------------------- */
+
+#ifndef GL_EXT_texture_compression_s3tc
+#define GL_EXT_texture_compression_s3tc 1
+
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
+
+#define GLEW_EXT_texture_compression_s3tc GLEW_GET_VAR(__GLEW_EXT_texture_compression_s3tc)
+
+#endif /* GL_EXT_texture_compression_s3tc */
+
+/* ------------------------ GL_EXT_texture_cube_map ------------------------ */
+
+#ifndef GL_EXT_texture_cube_map
+#define GL_EXT_texture_cube_map 1
+
+#define GL_NORMAL_MAP_EXT 0x8511
+#define GL_REFLECTION_MAP_EXT 0x8512
+#define GL_TEXTURE_CUBE_MAP_EXT 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C
+
+#define GLEW_EXT_texture_cube_map GLEW_GET_VAR(__GLEW_EXT_texture_cube_map)
+
+#endif /* GL_EXT_texture_cube_map */
+
+/* ----------------------- GL_EXT_texture_edge_clamp ----------------------- */
+
+#ifndef GL_EXT_texture_edge_clamp
+#define GL_EXT_texture_edge_clamp 1
+
+#define GL_CLAMP_TO_EDGE_EXT 0x812F
+
+#define GLEW_EXT_texture_edge_clamp GLEW_GET_VAR(__GLEW_EXT_texture_edge_clamp)
+
+#endif /* GL_EXT_texture_edge_clamp */
+
+/* --------------------------- GL_EXT_texture_env -------------------------- */
+
+#ifndef GL_EXT_texture_env
+#define GL_EXT_texture_env 1
+
+#define GLEW_EXT_texture_env GLEW_GET_VAR(__GLEW_EXT_texture_env)
+
+#endif /* GL_EXT_texture_env */
+
+/* ------------------------- GL_EXT_texture_env_add ------------------------ */
+
+#ifndef GL_EXT_texture_env_add
+#define GL_EXT_texture_env_add 1
+
+#define GLEW_EXT_texture_env_add GLEW_GET_VAR(__GLEW_EXT_texture_env_add)
+
+#endif /* GL_EXT_texture_env_add */
+
+/* ----------------------- GL_EXT_texture_env_combine ---------------------- */
+
+#ifndef GL_EXT_texture_env_combine
+#define GL_EXT_texture_env_combine 1
+
+#define GL_COMBINE_EXT 0x8570
+#define GL_COMBINE_RGB_EXT 0x8571
+#define GL_COMBINE_ALPHA_EXT 0x8572
+#define GL_RGB_SCALE_EXT 0x8573
+#define GL_ADD_SIGNED_EXT 0x8574
+#define GL_INTERPOLATE_EXT 0x8575
+#define GL_CONSTANT_EXT 0x8576
+#define GL_PRIMARY_COLOR_EXT 0x8577
+#define GL_PREVIOUS_EXT 0x8578
+#define GL_SOURCE0_RGB_EXT 0x8580
+#define GL_SOURCE1_RGB_EXT 0x8581
+#define GL_SOURCE2_RGB_EXT 0x8582
+#define GL_SOURCE0_ALPHA_EXT 0x8588
+#define GL_SOURCE1_ALPHA_EXT 0x8589
+#define GL_SOURCE2_ALPHA_EXT 0x858A
+#define GL_OPERAND0_RGB_EXT 0x8590
+#define GL_OPERAND1_RGB_EXT 0x8591
+#define GL_OPERAND2_RGB_EXT 0x8592
+#define GL_OPERAND0_ALPHA_EXT 0x8598
+#define GL_OPERAND1_ALPHA_EXT 0x8599
+#define GL_OPERAND2_ALPHA_EXT 0x859A
+
+#define GLEW_EXT_texture_env_combine GLEW_GET_VAR(__GLEW_EXT_texture_env_combine)
+
+#endif /* GL_EXT_texture_env_combine */
+
+/* ------------------------ GL_EXT_texture_env_dot3 ------------------------ */
+
+#ifndef GL_EXT_texture_env_dot3
+#define GL_EXT_texture_env_dot3 1
+
+#define GL_DOT3_RGB_EXT 0x8740
+#define GL_DOT3_RGBA_EXT 0x8741
+
+#define GLEW_EXT_texture_env_dot3 GLEW_GET_VAR(__GLEW_EXT_texture_env_dot3)
+
+#endif /* GL_EXT_texture_env_dot3 */
+
+/* ------------------- GL_EXT_texture_filter_anisotropic ------------------- */
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+
+#define GLEW_EXT_texture_filter_anisotropic GLEW_GET_VAR(__GLEW_EXT_texture_filter_anisotropic)
+
+#endif /* GL_EXT_texture_filter_anisotropic */
+
+/* ------------------------- GL_EXT_texture_integer ------------------------ */
+
+#ifndef GL_EXT_texture_integer
+#define GL_EXT_texture_integer 1
+
+#define GL_RGBA32UI_EXT 0x8D70
+#define GL_RGB32UI_EXT 0x8D71
+#define GL_ALPHA32UI_EXT 0x8D72
+#define GL_INTENSITY32UI_EXT 0x8D73
+#define GL_LUMINANCE32UI_EXT 0x8D74
+#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75
+#define GL_RGBA16UI_EXT 0x8D76
+#define GL_RGB16UI_EXT 0x8D77
+#define GL_ALPHA16UI_EXT 0x8D78
+#define GL_INTENSITY16UI_EXT 0x8D79
+#define GL_LUMINANCE16UI_EXT 0x8D7A
+#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B
+#define GL_RGBA8UI_EXT 0x8D7C
+#define GL_RGB8UI_EXT 0x8D7D
+#define GL_ALPHA8UI_EXT 0x8D7E
+#define GL_INTENSITY8UI_EXT 0x8D7F
+#define GL_LUMINANCE8UI_EXT 0x8D80
+#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81
+#define GL_RGBA32I_EXT 0x8D82
+#define GL_RGB32I_EXT 0x8D83
+#define GL_ALPHA32I_EXT 0x8D84
+#define GL_INTENSITY32I_EXT 0x8D85
+#define GL_LUMINANCE32I_EXT 0x8D86
+#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87
+#define GL_RGBA16I_EXT 0x8D88
+#define GL_RGB16I_EXT 0x8D89
+#define GL_ALPHA16I_EXT 0x8D8A
+#define GL_INTENSITY16I_EXT 0x8D8B
+#define GL_LUMINANCE16I_EXT 0x8D8C
+#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D
+#define GL_RGBA8I_EXT 0x8D8E
+#define GL_RGB8I_EXT 0x8D8F
+#define GL_ALPHA8I_EXT 0x8D90
+#define GL_INTENSITY8I_EXT 0x8D91
+#define GL_LUMINANCE8I_EXT 0x8D92
+#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93
+#define GL_RED_INTEGER_EXT 0x8D94
+#define GL_GREEN_INTEGER_EXT 0x8D95
+#define GL_BLUE_INTEGER_EXT 0x8D96
+#define GL_ALPHA_INTEGER_EXT 0x8D97
+#define GL_RGB_INTEGER_EXT 0x8D98
+#define GL_RGBA_INTEGER_EXT 0x8D99
+#define GL_BGR_INTEGER_EXT 0x8D9A
+#define GL_BGRA_INTEGER_EXT 0x8D9B
+#define GL_LUMINANCE_INTEGER_EXT 0x8D9C
+#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D
+#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E
+
+typedef void (GLAPIENTRY * PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha);
+typedef void (GLAPIENTRY * PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha);
+typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params);
+
+#define glClearColorIiEXT GLEW_GET_FUN(__glewClearColorIiEXT)
+#define glClearColorIuiEXT GLEW_GET_FUN(__glewClearColorIuiEXT)
+#define glGetTexParameterIivEXT GLEW_GET_FUN(__glewGetTexParameterIivEXT)
+#define glGetTexParameterIuivEXT GLEW_GET_FUN(__glewGetTexParameterIuivEXT)
+#define glTexParameterIivEXT GLEW_GET_FUN(__glewTexParameterIivEXT)
+#define glTexParameterIuivEXT GLEW_GET_FUN(__glewTexParameterIuivEXT)
+
+#define GLEW_EXT_texture_integer GLEW_GET_VAR(__GLEW_EXT_texture_integer)
+
+#endif /* GL_EXT_texture_integer */
+
+/* ------------------------ GL_EXT_texture_lod_bias ------------------------ */
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_EXT_texture_lod_bias 1
+
+#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD
+#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500
+#define GL_TEXTURE_LOD_BIAS_EXT 0x8501
+
+#define GLEW_EXT_texture_lod_bias GLEW_GET_VAR(__GLEW_EXT_texture_lod_bias)
+
+#endif /* GL_EXT_texture_lod_bias */
+
+/* ---------------------- GL_EXT_texture_mirror_clamp ---------------------- */
+
+#ifndef GL_EXT_texture_mirror_clamp
+#define GL_EXT_texture_mirror_clamp 1
+
+#define GL_MIRROR_CLAMP_EXT 0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743
+#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912
+
+#define GLEW_EXT_texture_mirror_clamp GLEW_GET_VAR(__GLEW_EXT_texture_mirror_clamp)
+
+#endif /* GL_EXT_texture_mirror_clamp */
+
+/* ------------------------- GL_EXT_texture_object ------------------------- */
+
+#ifndef GL_EXT_texture_object
+#define GL_EXT_texture_object 1
+
+#define GL_TEXTURE_PRIORITY_EXT 0x8066
+#define GL_TEXTURE_RESIDENT_EXT 0x8067
+#define GL_TEXTURE_1D_BINDING_EXT 0x8068
+#define GL_TEXTURE_2D_BINDING_EXT 0x8069
+#define GL_TEXTURE_3D_BINDING_EXT 0x806A
+
+typedef GLboolean (GLAPIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint* textures, GLboolean* residences);
+typedef void (GLAPIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture);
+typedef void (GLAPIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint* textures);
+typedef void (GLAPIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint* textures);
+typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture);
+typedef void (GLAPIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint* textures, const GLclampf* priorities);
+
+#define glAreTexturesResidentEXT GLEW_GET_FUN(__glewAreTexturesResidentEXT)
+#define glBindTextureEXT GLEW_GET_FUN(__glewBindTextureEXT)
+#define glDeleteTexturesEXT GLEW_GET_FUN(__glewDeleteTexturesEXT)
+#define glGenTexturesEXT GLEW_GET_FUN(__glewGenTexturesEXT)
+#define glIsTextureEXT GLEW_GET_FUN(__glewIsTextureEXT)
+#define glPrioritizeTexturesEXT GLEW_GET_FUN(__glewPrioritizeTexturesEXT)
+
+#define GLEW_EXT_texture_object GLEW_GET_VAR(__GLEW_EXT_texture_object)
+
+#endif /* GL_EXT_texture_object */
+
+/* --------------------- GL_EXT_texture_perturb_normal --------------------- */
+
+#ifndef GL_EXT_texture_perturb_normal
+#define GL_EXT_texture_perturb_normal 1
+
+#define GL_PERTURB_EXT 0x85AE
+#define GL_TEXTURE_NORMAL_EXT 0x85AF
+
+typedef void (GLAPIENTRY * PFNGLTEXTURENORMALEXTPROC) (GLenum mode);
+
+#define glTextureNormalEXT GLEW_GET_FUN(__glewTextureNormalEXT)
+
+#define GLEW_EXT_texture_perturb_normal GLEW_GET_VAR(__GLEW_EXT_texture_perturb_normal)
+
+#endif /* GL_EXT_texture_perturb_normal */
+
+/* ------------------------ GL_EXT_texture_rectangle ----------------------- */
+
+#ifndef GL_EXT_texture_rectangle
+#define GL_EXT_texture_rectangle 1
+
+#define GL_TEXTURE_RECTANGLE_EXT 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_EXT 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_EXT 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT 0x84F8
+
+#define GLEW_EXT_texture_rectangle GLEW_GET_VAR(__GLEW_EXT_texture_rectangle)
+
+#endif /* GL_EXT_texture_rectangle */
+
+/* -------------------------- GL_EXT_texture_sRGB -------------------------- */
+
+#ifndef GL_EXT_texture_sRGB
+#define GL_EXT_texture_sRGB 1
+
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB8_EXT 0x8C41
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+#define GL_SLUMINANCE_ALPHA_EXT 0x8C44
+#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
+#define GL_SLUMINANCE_EXT 0x8C46
+#define GL_SLUMINANCE8_EXT 0x8C47
+#define GL_COMPRESSED_SRGB_EXT 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
+#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
+
+#define GLEW_EXT_texture_sRGB GLEW_GET_VAR(__GLEW_EXT_texture_sRGB)
+
+#endif /* GL_EXT_texture_sRGB */
+
+/* ----------------------- GL_EXT_texture_sRGB_decode ---------------------- */
+
+#ifndef GL_EXT_texture_sRGB_decode
+#define GL_EXT_texture_sRGB_decode 1
+
+#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48
+#define GL_DECODE_EXT 0x8A49
+#define GL_SKIP_DECODE_EXT 0x8A4A
+
+#define GLEW_EXT_texture_sRGB_decode GLEW_GET_VAR(__GLEW_EXT_texture_sRGB_decode)
+
+#endif /* GL_EXT_texture_sRGB_decode */
+
+/* --------------------- GL_EXT_texture_shared_exponent -------------------- */
+
+#ifndef GL_EXT_texture_shared_exponent
+#define GL_EXT_texture_shared_exponent 1
+
+#define GL_RGB9_E5_EXT 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E
+#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F
+
+#define GLEW_EXT_texture_shared_exponent GLEW_GET_VAR(__GLEW_EXT_texture_shared_exponent)
+
+#endif /* GL_EXT_texture_shared_exponent */
+
+/* -------------------------- GL_EXT_texture_snorm ------------------------- */
+
+#ifndef GL_EXT_texture_snorm
+#define GL_EXT_texture_snorm 1
+
+#define GL_RED_SNORM 0x8F90
+#define GL_RG_SNORM 0x8F91
+#define GL_RGB_SNORM 0x8F92
+#define GL_RGBA_SNORM 0x8F93
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_R16_SNORM 0x8F98
+#define GL_RG16_SNORM 0x8F99
+#define GL_RGB16_SNORM 0x8F9A
+#define GL_RGBA16_SNORM 0x8F9B
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_ALPHA_SNORM 0x9010
+#define GL_LUMINANCE_SNORM 0x9011
+#define GL_LUMINANCE_ALPHA_SNORM 0x9012
+#define GL_INTENSITY_SNORM 0x9013
+#define GL_ALPHA8_SNORM 0x9014
+#define GL_LUMINANCE8_SNORM 0x9015
+#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016
+#define GL_INTENSITY8_SNORM 0x9017
+#define GL_ALPHA16_SNORM 0x9018
+#define GL_LUMINANCE16_SNORM 0x9019
+#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A
+#define GL_INTENSITY16_SNORM 0x901B
+
+#define GLEW_EXT_texture_snorm GLEW_GET_VAR(__GLEW_EXT_texture_snorm)
+
+#endif /* GL_EXT_texture_snorm */
+
+/* ------------------------- GL_EXT_texture_swizzle ------------------------ */
+
+#ifndef GL_EXT_texture_swizzle
+#define GL_EXT_texture_swizzle 1
+
+#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42
+#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43
+#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44
+#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45
+#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46
+
+#define GLEW_EXT_texture_swizzle GLEW_GET_VAR(__GLEW_EXT_texture_swizzle)
+
+#endif /* GL_EXT_texture_swizzle */
+
+/* --------------------------- GL_EXT_timer_query -------------------------- */
+
+#ifndef GL_EXT_timer_query
+#define GL_EXT_timer_query 1
+
+#define GL_TIME_ELAPSED_EXT 0x88BF
+
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params);
+typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params);
+
+#define glGetQueryObjecti64vEXT GLEW_GET_FUN(__glewGetQueryObjecti64vEXT)
+#define glGetQueryObjectui64vEXT GLEW_GET_FUN(__glewGetQueryObjectui64vEXT)
+
+#define GLEW_EXT_timer_query GLEW_GET_VAR(__GLEW_EXT_timer_query)
+
+#endif /* GL_EXT_timer_query */
+
+/* ----------------------- GL_EXT_transform_feedback ----------------------- */
+
+#ifndef GL_EXT_transform_feedback
+#define GL_EXT_transform_feedback 1
+
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85
+#define GL_PRIMITIVES_GENERATED_EXT 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88
+#define GL_RASTERIZER_DISCARD_EXT 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C
+#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F
+
+typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void);
+typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar * const* varyings, GLenum bufferMode);
+
+#define glBeginTransformFeedbackEXT GLEW_GET_FUN(__glewBeginTransformFeedbackEXT)
+#define glBindBufferBaseEXT GLEW_GET_FUN(__glewBindBufferBaseEXT)
+#define glBindBufferOffsetEXT GLEW_GET_FUN(__glewBindBufferOffsetEXT)
+#define glBindBufferRangeEXT GLEW_GET_FUN(__glewBindBufferRangeEXT)
+#define glEndTransformFeedbackEXT GLEW_GET_FUN(__glewEndTransformFeedbackEXT)
+#define glGetTransformFeedbackVaryingEXT GLEW_GET_FUN(__glewGetTransformFeedbackVaryingEXT)
+#define glTransformFeedbackVaryingsEXT GLEW_GET_FUN(__glewTransformFeedbackVaryingsEXT)
+
+#define GLEW_EXT_transform_feedback GLEW_GET_VAR(__GLEW_EXT_transform_feedback)
+
+#endif /* GL_EXT_transform_feedback */
+
+/* -------------------------- GL_EXT_vertex_array -------------------------- */
+
+#ifndef GL_EXT_vertex_array
+#define GL_EXT_vertex_array 1
+
+#define GL_DOUBLE_EXT 0x140A
+#define GL_VERTEX_ARRAY_EXT 0x8074
+#define GL_NORMAL_ARRAY_EXT 0x8075
+#define GL_COLOR_ARRAY_EXT 0x8076
+#define GL_INDEX_ARRAY_EXT 0x8077
+#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078
+#define GL_EDGE_FLAG_ARRAY_EXT 0x8079
+#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A
+#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B
+#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C
+#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D
+#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E
+#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F
+#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080
+#define GL_COLOR_ARRAY_SIZE_EXT 0x8081
+#define GL_COLOR_ARRAY_TYPE_EXT 0x8082
+#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083
+#define GL_COLOR_ARRAY_COUNT_EXT 0x8084
+#define GL_INDEX_ARRAY_TYPE_EXT 0x8085
+#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086
+#define GL_INDEX_ARRAY_COUNT_EXT 0x8087
+#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A
+#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B
+#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C
+#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D
+#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E
+#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F
+#define GL_COLOR_ARRAY_POINTER_EXT 0x8090
+#define GL_INDEX_ARRAY_POINTER_EXT 0x8091
+#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092
+#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093
+
+typedef void (GLAPIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i);
+typedef void (GLAPIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean* pointer);
+typedef void (GLAPIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+
+#define glArrayElementEXT GLEW_GET_FUN(__glewArrayElementEXT)
+#define glColorPointerEXT GLEW_GET_FUN(__glewColorPointerEXT)
+#define glDrawArraysEXT GLEW_GET_FUN(__glewDrawArraysEXT)
+#define glEdgeFlagPointerEXT GLEW_GET_FUN(__glewEdgeFlagPointerEXT)
+#define glIndexPointerEXT GLEW_GET_FUN(__glewIndexPointerEXT)
+#define glNormalPointerEXT GLEW_GET_FUN(__glewNormalPointerEXT)
+#define glTexCoordPointerEXT GLEW_GET_FUN(__glewTexCoordPointerEXT)
+#define glVertexPointerEXT GLEW_GET_FUN(__glewVertexPointerEXT)
+
+#define GLEW_EXT_vertex_array GLEW_GET_VAR(__GLEW_EXT_vertex_array)
+
+#endif /* GL_EXT_vertex_array */
+
+/* ------------------------ GL_EXT_vertex_array_bgra ----------------------- */
+
+#ifndef GL_EXT_vertex_array_bgra
+#define GL_EXT_vertex_array_bgra 1
+
+#define GL_BGRA 0x80E1
+
+#define GLEW_EXT_vertex_array_bgra GLEW_GET_VAR(__GLEW_EXT_vertex_array_bgra)
+
+#endif /* GL_EXT_vertex_array_bgra */
+
+/* ----------------------- GL_EXT_vertex_attrib_64bit ---------------------- */
+
+#ifndef GL_EXT_vertex_attrib_64bit
+#define GL_EXT_vertex_attrib_64bit 1
+
+#define GL_DOUBLE_MAT2_EXT 0x8F46
+#define GL_DOUBLE_MAT3_EXT 0x8F47
+#define GL_DOUBLE_MAT4_EXT 0x8F48
+#define GL_DOUBLE_MAT2x3_EXT 0x8F49
+#define GL_DOUBLE_MAT2x4_EXT 0x8F4A
+#define GL_DOUBLE_MAT3x2_EXT 0x8F4B
+#define GL_DOUBLE_MAT3x4_EXT 0x8F4C
+#define GL_DOUBLE_MAT4x2_EXT 0x8F4D
+#define GL_DOUBLE_MAT4x3_EXT 0x8F4E
+#define GL_DOUBLE_VEC2_EXT 0x8FFC
+#define GL_DOUBLE_VEC3_EXT 0x8FFD
+#define GL_DOUBLE_VEC4_EXT 0x8FFE
+
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+
+#define glGetVertexAttribLdvEXT GLEW_GET_FUN(__glewGetVertexAttribLdvEXT)
+#define glVertexArrayVertexAttribLOffsetEXT GLEW_GET_FUN(__glewVertexArrayVertexAttribLOffsetEXT)
+#define glVertexAttribL1dEXT GLEW_GET_FUN(__glewVertexAttribL1dEXT)
+#define glVertexAttribL1dvEXT GLEW_GET_FUN(__glewVertexAttribL1dvEXT)
+#define glVertexAttribL2dEXT GLEW_GET_FUN(__glewVertexAttribL2dEXT)
+#define glVertexAttribL2dvEXT GLEW_GET_FUN(__glewVertexAttribL2dvEXT)
+#define glVertexAttribL3dEXT GLEW_GET_FUN(__glewVertexAttribL3dEXT)
+#define glVertexAttribL3dvEXT GLEW_GET_FUN(__glewVertexAttribL3dvEXT)
+#define glVertexAttribL4dEXT GLEW_GET_FUN(__glewVertexAttribL4dEXT)
+#define glVertexAttribL4dvEXT GLEW_GET_FUN(__glewVertexAttribL4dvEXT)
+#define glVertexAttribLPointerEXT GLEW_GET_FUN(__glewVertexAttribLPointerEXT)
+
+#define GLEW_EXT_vertex_attrib_64bit GLEW_GET_VAR(__GLEW_EXT_vertex_attrib_64bit)
+
+#endif /* GL_EXT_vertex_attrib_64bit */
+
+/* -------------------------- GL_EXT_vertex_shader ------------------------- */
+
+#ifndef GL_EXT_vertex_shader
+#define GL_EXT_vertex_shader 1
+
+#define GL_VERTEX_SHADER_EXT 0x8780
+#define GL_VERTEX_SHADER_BINDING_EXT 0x8781
+#define GL_OP_INDEX_EXT 0x8782
+#define GL_OP_NEGATE_EXT 0x8783
+#define GL_OP_DOT3_EXT 0x8784
+#define GL_OP_DOT4_EXT 0x8785
+#define GL_OP_MUL_EXT 0x8786
+#define GL_OP_ADD_EXT 0x8787
+#define GL_OP_MADD_EXT 0x8788
+#define GL_OP_FRAC_EXT 0x8789
+#define GL_OP_MAX_EXT 0x878A
+#define GL_OP_MIN_EXT 0x878B
+#define GL_OP_SET_GE_EXT 0x878C
+#define GL_OP_SET_LT_EXT 0x878D
+#define GL_OP_CLAMP_EXT 0x878E
+#define GL_OP_FLOOR_EXT 0x878F
+#define GL_OP_ROUND_EXT 0x8790
+#define GL_OP_EXP_BASE_2_EXT 0x8791
+#define GL_OP_LOG_BASE_2_EXT 0x8792
+#define GL_OP_POWER_EXT 0x8793
+#define GL_OP_RECIP_EXT 0x8794
+#define GL_OP_RECIP_SQRT_EXT 0x8795
+#define GL_OP_SUB_EXT 0x8796
+#define GL_OP_CROSS_PRODUCT_EXT 0x8797
+#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798
+#define GL_OP_MOV_EXT 0x8799
+#define GL_OUTPUT_VERTEX_EXT 0x879A
+#define GL_OUTPUT_COLOR0_EXT 0x879B
+#define GL_OUTPUT_COLOR1_EXT 0x879C
+#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D
+#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E
+#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F
+#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0
+#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1
+#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2
+#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3
+#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4
+#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5
+#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6
+#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7
+#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8
+#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9
+#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA
+#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB
+#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC
+#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD
+#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE
+#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF
+#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0
+#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1
+#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2
+#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3
+#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4
+#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5
+#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6
+#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7
+#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8
+#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9
+#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA
+#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB
+#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC
+#define GL_OUTPUT_FOG_EXT 0x87BD
+#define GL_SCALAR_EXT 0x87BE
+#define GL_VECTOR_EXT 0x87BF
+#define GL_MATRIX_EXT 0x87C0
+#define GL_VARIANT_EXT 0x87C1
+#define GL_INVARIANT_EXT 0x87C2
+#define GL_LOCAL_CONSTANT_EXT 0x87C3
+#define GL_LOCAL_EXT 0x87C4
+#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5
+#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6
+#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7
+#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8
+#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CC
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CD
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE
+#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF
+#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0
+#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1
+#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2
+#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3
+#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4
+#define GL_X_EXT 0x87D5
+#define GL_Y_EXT 0x87D6
+#define GL_Z_EXT 0x87D7
+#define GL_W_EXT 0x87D8
+#define GL_NEGATIVE_X_EXT 0x87D9
+#define GL_NEGATIVE_Y_EXT 0x87DA
+#define GL_NEGATIVE_Z_EXT 0x87DB
+#define GL_NEGATIVE_W_EXT 0x87DC
+#define GL_ZERO_EXT 0x87DD
+#define GL_ONE_EXT 0x87DE
+#define GL_NEGATIVE_ONE_EXT 0x87DF
+#define GL_NORMALIZED_RANGE_EXT 0x87E0
+#define GL_FULL_RANGE_EXT 0x87E1
+#define GL_CURRENT_VERTEX_EXT 0x87E2
+#define GL_MVP_MATRIX_EXT 0x87E3
+#define GL_VARIANT_VALUE_EXT 0x87E4
+#define GL_VARIANT_DATATYPE_EXT 0x87E5
+#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6
+#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7
+#define GL_VARIANT_ARRAY_EXT 0x87E8
+#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9
+#define GL_INVARIANT_VALUE_EXT 0x87EA
+#define GL_INVARIANT_DATATYPE_EXT 0x87EB
+#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC
+#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED
+
+typedef void (GLAPIENTRY * PFNGLBEGINVERTEXSHADEREXTPROC) (void);
+typedef GLuint (GLAPIENTRY * PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value);
+typedef GLuint (GLAPIENTRY * PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value);
+typedef GLuint (GLAPIENTRY * PFNGLBINDPARAMETEREXTPROC) (GLenum value);
+typedef GLuint (GLAPIENTRY * PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value);
+typedef GLuint (GLAPIENTRY * PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value);
+typedef void (GLAPIENTRY * PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLENDVERTEXSHADEREXTPROC) (void);
+typedef void (GLAPIENTRY * PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num);
+typedef GLuint (GLAPIENTRY * PFNGLGENSYMBOLSEXTPROC) (GLenum dataType, GLenum storageType, GLenum range, GLuint components);
+typedef GLuint (GLAPIENTRY * PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range);
+typedef void (GLAPIENTRY * PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (GLAPIENTRY * PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (GLAPIENTRY * PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (GLAPIENTRY * PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (GLAPIENTRY * PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (GLAPIENTRY * PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (GLAPIENTRY * PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (GLAPIENTRY * PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid **data);
+typedef void (GLAPIENTRY * PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num);
+typedef GLboolean (GLAPIENTRY * PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap);
+typedef void (GLAPIENTRY * PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, GLvoid *addr);
+typedef void (GLAPIENTRY * PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, GLvoid *addr);
+typedef void (GLAPIENTRY * PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1);
+typedef void (GLAPIENTRY * PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2);
+typedef void (GLAPIENTRY * PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3);
+typedef void (GLAPIENTRY * PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+typedef void (GLAPIENTRY * PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, GLvoid *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTBVEXTPROC) (GLuint id, GLbyte *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTDVEXTPROC) (GLuint id, GLdouble *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTFVEXTPROC) (GLuint id, GLfloat *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTIVEXTPROC) (GLuint id, GLint *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTSVEXTPROC) (GLuint id, GLshort *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTUBVEXTPROC) (GLuint id, GLubyte *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTUIVEXTPROC) (GLuint id, GLuint *addr);
+typedef void (GLAPIENTRY * PFNGLVARIANTUSVEXTPROC) (GLuint id, GLushort *addr);
+typedef void (GLAPIENTRY * PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+
+#define glBeginVertexShaderEXT GLEW_GET_FUN(__glewBeginVertexShaderEXT)
+#define glBindLightParameterEXT GLEW_GET_FUN(__glewBindLightParameterEXT)
+#define glBindMaterialParameterEXT GLEW_GET_FUN(__glewBindMaterialParameterEXT)
+#define glBindParameterEXT GLEW_GET_FUN(__glewBindParameterEXT)
+#define glBindTexGenParameterEXT GLEW_GET_FUN(__glewBindTexGenParameterEXT)
+#define glBindTextureUnitParameterEXT GLEW_GET_FUN(__glewBindTextureUnitParameterEXT)
+#define glBindVertexShaderEXT GLEW_GET_FUN(__glewBindVertexShaderEXT)
+#define glDeleteVertexShaderEXT GLEW_GET_FUN(__glewDeleteVertexShaderEXT)
+#define glDisableVariantClientStateEXT GLEW_GET_FUN(__glewDisableVariantClientStateEXT)
+#define glEnableVariantClientStateEXT GLEW_GET_FUN(__glewEnableVariantClientStateEXT)
+#define glEndVertexShaderEXT GLEW_GET_FUN(__glewEndVertexShaderEXT)
+#define glExtractComponentEXT GLEW_GET_FUN(__glewExtractComponentEXT)
+#define glGenSymbolsEXT GLEW_GET_FUN(__glewGenSymbolsEXT)
+#define glGenVertexShadersEXT GLEW_GET_FUN(__glewGenVertexShadersEXT)
+#define glGetInvariantBooleanvEXT GLEW_GET_FUN(__glewGetInvariantBooleanvEXT)
+#define glGetInvariantFloatvEXT GLEW_GET_FUN(__glewGetInvariantFloatvEXT)
+#define glGetInvariantIntegervEXT GLEW_GET_FUN(__glewGetInvariantIntegervEXT)
+#define glGetLocalConstantBooleanvEXT GLEW_GET_FUN(__glewGetLocalConstantBooleanvEXT)
+#define glGetLocalConstantFloatvEXT GLEW_GET_FUN(__glewGetLocalConstantFloatvEXT)
+#define glGetLocalConstantIntegervEXT GLEW_GET_FUN(__glewGetLocalConstantIntegervEXT)
+#define glGetVariantBooleanvEXT GLEW_GET_FUN(__glewGetVariantBooleanvEXT)
+#define glGetVariantFloatvEXT GLEW_GET_FUN(__glewGetVariantFloatvEXT)
+#define glGetVariantIntegervEXT GLEW_GET_FUN(__glewGetVariantIntegervEXT)
+#define glGetVariantPointervEXT GLEW_GET_FUN(__glewGetVariantPointervEXT)
+#define glInsertComponentEXT GLEW_GET_FUN(__glewInsertComponentEXT)
+#define glIsVariantEnabledEXT GLEW_GET_FUN(__glewIsVariantEnabledEXT)
+#define glSetInvariantEXT GLEW_GET_FUN(__glewSetInvariantEXT)
+#define glSetLocalConstantEXT GLEW_GET_FUN(__glewSetLocalConstantEXT)
+#define glShaderOp1EXT GLEW_GET_FUN(__glewShaderOp1EXT)
+#define glShaderOp2EXT GLEW_GET_FUN(__glewShaderOp2EXT)
+#define glShaderOp3EXT GLEW_GET_FUN(__glewShaderOp3EXT)
+#define glSwizzleEXT GLEW_GET_FUN(__glewSwizzleEXT)
+#define glVariantPointerEXT GLEW_GET_FUN(__glewVariantPointerEXT)
+#define glVariantbvEXT GLEW_GET_FUN(__glewVariantbvEXT)
+#define glVariantdvEXT GLEW_GET_FUN(__glewVariantdvEXT)
+#define glVariantfvEXT GLEW_GET_FUN(__glewVariantfvEXT)
+#define glVariantivEXT GLEW_GET_FUN(__glewVariantivEXT)
+#define glVariantsvEXT GLEW_GET_FUN(__glewVariantsvEXT)
+#define glVariantubvEXT GLEW_GET_FUN(__glewVariantubvEXT)
+#define glVariantuivEXT GLEW_GET_FUN(__glewVariantuivEXT)
+#define glVariantusvEXT GLEW_GET_FUN(__glewVariantusvEXT)
+#define glWriteMaskEXT GLEW_GET_FUN(__glewWriteMaskEXT)
+
+#define GLEW_EXT_vertex_shader GLEW_GET_VAR(__GLEW_EXT_vertex_shader)
+
+#endif /* GL_EXT_vertex_shader */
+
+/* ------------------------ GL_EXT_vertex_weighting ------------------------ */
+
+#ifndef GL_EXT_vertex_weighting
+#define GL_EXT_vertex_weighting 1
+
+#define GL_MODELVIEW0_STACK_DEPTH_EXT 0x0BA3
+#define GL_MODELVIEW0_MATRIX_EXT 0x0BA6
+#define GL_MODELVIEW0_EXT 0x1700
+#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502
+#define GL_MODELVIEW1_MATRIX_EXT 0x8506
+#define GL_VERTEX_WEIGHTING_EXT 0x8509
+#define GL_MODELVIEW1_EXT 0x850A
+#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B
+#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C
+#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D
+#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E
+#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F
+#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510
+
+typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight);
+typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (GLfloat* weight);
+
+#define glVertexWeightPointerEXT GLEW_GET_FUN(__glewVertexWeightPointerEXT)
+#define glVertexWeightfEXT GLEW_GET_FUN(__glewVertexWeightfEXT)
+#define glVertexWeightfvEXT GLEW_GET_FUN(__glewVertexWeightfvEXT)
+
+#define GLEW_EXT_vertex_weighting GLEW_GET_VAR(__GLEW_EXT_vertex_weighting)
+
+#endif /* GL_EXT_vertex_weighting */
+
+/* ------------------------- GL_EXT_x11_sync_object ------------------------ */
+
+#ifndef GL_EXT_x11_sync_object
+#define GL_EXT_x11_sync_object 1
+
+#define GL_SYNC_X11_FENCE_EXT 0x90E1
+
+typedef GLsync (GLAPIENTRY * PFNGLIMPORTSYNCEXTPROC) (GLenum external_sync_type, GLintptr external_sync, GLbitfield flags);
+
+#define glImportSyncEXT GLEW_GET_FUN(__glewImportSyncEXT)
+
+#define GLEW_EXT_x11_sync_object GLEW_GET_VAR(__GLEW_EXT_x11_sync_object)
+
+#endif /* GL_EXT_x11_sync_object */
+
+/* ---------------------- GL_GREMEDY_frame_terminator ---------------------- */
+
+#ifndef GL_GREMEDY_frame_terminator
+#define GL_GREMEDY_frame_terminator 1
+
+typedef void (GLAPIENTRY * PFNGLFRAMETERMINATORGREMEDYPROC) (void);
+
+#define glFrameTerminatorGREMEDY GLEW_GET_FUN(__glewFrameTerminatorGREMEDY)
+
+#define GLEW_GREMEDY_frame_terminator GLEW_GET_VAR(__GLEW_GREMEDY_frame_terminator)
+
+#endif /* GL_GREMEDY_frame_terminator */
+
+/* ------------------------ GL_GREMEDY_string_marker ----------------------- */
+
+#ifndef GL_GREMEDY_string_marker
+#define GL_GREMEDY_string_marker 1
+
+typedef void (GLAPIENTRY * PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string);
+
+#define glStringMarkerGREMEDY GLEW_GET_FUN(__glewStringMarkerGREMEDY)
+
+#define GLEW_GREMEDY_string_marker GLEW_GET_VAR(__GLEW_GREMEDY_string_marker)
+
+#endif /* GL_GREMEDY_string_marker */
+
+/* --------------------- GL_HP_convolution_border_modes -------------------- */
+
+#ifndef GL_HP_convolution_border_modes
+#define GL_HP_convolution_border_modes 1
+
+#define GLEW_HP_convolution_border_modes GLEW_GET_VAR(__GLEW_HP_convolution_border_modes)
+
+#endif /* GL_HP_convolution_border_modes */
+
+/* ------------------------- GL_HP_image_transform ------------------------- */
+
+#ifndef GL_HP_image_transform
+#define GL_HP_image_transform 1
+
+typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, const GLfloat param);
+typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, const GLint param);
+typedef void (GLAPIENTRY * PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint* params);
+
+#define glGetImageTransformParameterfvHP GLEW_GET_FUN(__glewGetImageTransformParameterfvHP)
+#define glGetImageTransformParameterivHP GLEW_GET_FUN(__glewGetImageTransformParameterivHP)
+#define glImageTransformParameterfHP GLEW_GET_FUN(__glewImageTransformParameterfHP)
+#define glImageTransformParameterfvHP GLEW_GET_FUN(__glewImageTransformParameterfvHP)
+#define glImageTransformParameteriHP GLEW_GET_FUN(__glewImageTransformParameteriHP)
+#define glImageTransformParameterivHP GLEW_GET_FUN(__glewImageTransformParameterivHP)
+
+#define GLEW_HP_image_transform GLEW_GET_VAR(__GLEW_HP_image_transform)
+
+#endif /* GL_HP_image_transform */
+
+/* -------------------------- GL_HP_occlusion_test ------------------------- */
+
+#ifndef GL_HP_occlusion_test
+#define GL_HP_occlusion_test 1
+
+#define GLEW_HP_occlusion_test GLEW_GET_VAR(__GLEW_HP_occlusion_test)
+
+#endif /* GL_HP_occlusion_test */
+
+/* ------------------------- GL_HP_texture_lighting ------------------------ */
+
+#ifndef GL_HP_texture_lighting
+#define GL_HP_texture_lighting 1
+
+#define GLEW_HP_texture_lighting GLEW_GET_VAR(__GLEW_HP_texture_lighting)
+
+#endif /* GL_HP_texture_lighting */
+
+/* --------------------------- GL_IBM_cull_vertex -------------------------- */
+
+#ifndef GL_IBM_cull_vertex
+#define GL_IBM_cull_vertex 1
+
+#define GL_CULL_VERTEX_IBM 103050
+
+#define GLEW_IBM_cull_vertex GLEW_GET_VAR(__GLEW_IBM_cull_vertex)
+
+#endif /* GL_IBM_cull_vertex */
+
+/* ---------------------- GL_IBM_multimode_draw_arrays --------------------- */
+
+#ifndef GL_IBM_multimode_draw_arrays
+#define GL_IBM_multimode_draw_arrays 1
+
+typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum* mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride);
+typedef void (GLAPIENTRY * PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum* mode, const GLsizei *count, GLenum type, const GLvoid * const *indices, GLsizei primcount, GLint modestride);
+
+#define glMultiModeDrawArraysIBM GLEW_GET_FUN(__glewMultiModeDrawArraysIBM)
+#define glMultiModeDrawElementsIBM GLEW_GET_FUN(__glewMultiModeDrawElementsIBM)
+
+#define GLEW_IBM_multimode_draw_arrays GLEW_GET_VAR(__GLEW_IBM_multimode_draw_arrays)
+
+#endif /* GL_IBM_multimode_draw_arrays */
+
+/* ------------------------- GL_IBM_rasterpos_clip ------------------------- */
+
+#ifndef GL_IBM_rasterpos_clip
+#define GL_IBM_rasterpos_clip 1
+
+#define GL_RASTER_POSITION_UNCLIPPED_IBM 103010
+
+#define GLEW_IBM_rasterpos_clip GLEW_GET_VAR(__GLEW_IBM_rasterpos_clip)
+
+#endif /* GL_IBM_rasterpos_clip */
+
+/* --------------------------- GL_IBM_static_data -------------------------- */
+
+#ifndef GL_IBM_static_data
+#define GL_IBM_static_data 1
+
+#define GL_ALL_STATIC_DATA_IBM 103060
+#define GL_STATIC_VERTEX_ARRAY_IBM 103061
+
+#define GLEW_IBM_static_data GLEW_GET_VAR(__GLEW_IBM_static_data)
+
+#endif /* GL_IBM_static_data */
+
+/* --------------------- GL_IBM_texture_mirrored_repeat -------------------- */
+
+#ifndef GL_IBM_texture_mirrored_repeat
+#define GL_IBM_texture_mirrored_repeat 1
+
+#define GL_MIRRORED_REPEAT_IBM 0x8370
+
+#define GLEW_IBM_texture_mirrored_repeat GLEW_GET_VAR(__GLEW_IBM_texture_mirrored_repeat)
+
+#endif /* GL_IBM_texture_mirrored_repeat */
+
+/* ----------------------- GL_IBM_vertex_array_lists ----------------------- */
+
+#ifndef GL_IBM_vertex_array_lists
+#define GL_IBM_vertex_array_lists 1
+
+#define GL_VERTEX_ARRAY_LIST_IBM 103070
+#define GL_NORMAL_ARRAY_LIST_IBM 103071
+#define GL_COLOR_ARRAY_LIST_IBM 103072
+#define GL_INDEX_ARRAY_LIST_IBM 103073
+#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074
+#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075
+#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076
+#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077
+#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080
+#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081
+#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082
+#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083
+#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084
+#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085
+#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086
+#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087
+
+typedef void (GLAPIENTRY * PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride);
+typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean ** pointer, GLint ptrstride);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride);
+typedef void (GLAPIENTRY * PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride);
+typedef void (GLAPIENTRY * PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride);
+typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid ** pointer, GLint ptrstride);
+
+#define glColorPointerListIBM GLEW_GET_FUN(__glewColorPointerListIBM)
+#define glEdgeFlagPointerListIBM GLEW_GET_FUN(__glewEdgeFlagPointerListIBM)
+#define glFogCoordPointerListIBM GLEW_GET_FUN(__glewFogCoordPointerListIBM)
+#define glIndexPointerListIBM GLEW_GET_FUN(__glewIndexPointerListIBM)
+#define glNormalPointerListIBM GLEW_GET_FUN(__glewNormalPointerListIBM)
+#define glSecondaryColorPointerListIBM GLEW_GET_FUN(__glewSecondaryColorPointerListIBM)
+#define glTexCoordPointerListIBM GLEW_GET_FUN(__glewTexCoordPointerListIBM)
+#define glVertexPointerListIBM GLEW_GET_FUN(__glewVertexPointerListIBM)
+
+#define GLEW_IBM_vertex_array_lists GLEW_GET_VAR(__GLEW_IBM_vertex_array_lists)
+
+#endif /* GL_IBM_vertex_array_lists */
+
+/* -------------------------- GL_INGR_color_clamp -------------------------- */
+
+#ifndef GL_INGR_color_clamp
+#define GL_INGR_color_clamp 1
+
+#define GL_RED_MIN_CLAMP_INGR 0x8560
+#define GL_GREEN_MIN_CLAMP_INGR 0x8561
+#define GL_BLUE_MIN_CLAMP_INGR 0x8562
+#define GL_ALPHA_MIN_CLAMP_INGR 0x8563
+#define GL_RED_MAX_CLAMP_INGR 0x8564
+#define GL_GREEN_MAX_CLAMP_INGR 0x8565
+#define GL_BLUE_MAX_CLAMP_INGR 0x8566
+#define GL_ALPHA_MAX_CLAMP_INGR 0x8567
+
+#define GLEW_INGR_color_clamp GLEW_GET_VAR(__GLEW_INGR_color_clamp)
+
+#endif /* GL_INGR_color_clamp */
+
+/* ------------------------- GL_INGR_interlace_read ------------------------ */
+
+#ifndef GL_INGR_interlace_read
+#define GL_INGR_interlace_read 1
+
+#define GL_INTERLACE_READ_INGR 0x8568
+
+#define GLEW_INGR_interlace_read GLEW_GET_VAR(__GLEW_INGR_interlace_read)
+
+#endif /* GL_INGR_interlace_read */
+
+/* -------------------------- GL_INTEL_map_texture ------------------------- */
+
+#ifndef GL_INTEL_map_texture
+#define GL_INTEL_map_texture 1
+
+#define GL_LAYOUT_DEFAULT_INTEL 0
+#define GL_LAYOUT_LINEAR_INTEL 1
+#define GL_LAYOUT_LINEAR_CPU_CACHED_INTEL 2
+#define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF
+
+typedef GLvoid * (GLAPIENTRY * PFNGLMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level, GLbitfield access, GLint* stride, GLenum *layout);
+typedef void (GLAPIENTRY * PFNGLSYNCTEXTUREINTELPROC) (GLuint texture);
+typedef void (GLAPIENTRY * PFNGLUNMAPTEXTURE2DINTELPROC) (GLuint texture, GLint level);
+
+#define glMapTexture2DINTEL GLEW_GET_FUN(__glewMapTexture2DINTEL)
+#define glSyncTextureINTEL GLEW_GET_FUN(__glewSyncTextureINTEL)
+#define glUnmapTexture2DINTEL GLEW_GET_FUN(__glewUnmapTexture2DINTEL)
+
+#define GLEW_INTEL_map_texture GLEW_GET_VAR(__GLEW_INTEL_map_texture)
+
+#endif /* GL_INTEL_map_texture */
+
+/* ------------------------ GL_INTEL_parallel_arrays ----------------------- */
+
+#ifndef GL_INTEL_parallel_arrays
+#define GL_INTEL_parallel_arrays 1
+
+#define GL_PARALLEL_ARRAYS_INTEL 0x83F4
+#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5
+#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6
+#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7
+#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8
+
+typedef void (GLAPIENTRY * PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer);
+typedef void (GLAPIENTRY * PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const void** pointer);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer);
+typedef void (GLAPIENTRY * PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const void** pointer);
+
+#define glColorPointervINTEL GLEW_GET_FUN(__glewColorPointervINTEL)
+#define glNormalPointervINTEL GLEW_GET_FUN(__glewNormalPointervINTEL)
+#define glTexCoordPointervINTEL GLEW_GET_FUN(__glewTexCoordPointervINTEL)
+#define glVertexPointervINTEL GLEW_GET_FUN(__glewVertexPointervINTEL)
+
+#define GLEW_INTEL_parallel_arrays GLEW_GET_VAR(__GLEW_INTEL_parallel_arrays)
+
+#endif /* GL_INTEL_parallel_arrays */
+
+/* ------------------------ GL_INTEL_texture_scissor ----------------------- */
+
+#ifndef GL_INTEL_texture_scissor
+#define GL_INTEL_texture_scissor 1
+
+typedef void (GLAPIENTRY * PFNGLTEXSCISSORFUNCINTELPROC) (GLenum target, GLenum lfunc, GLenum hfunc);
+typedef void (GLAPIENTRY * PFNGLTEXSCISSORINTELPROC) (GLenum target, GLclampf tlow, GLclampf thigh);
+
+#define glTexScissorFuncINTEL GLEW_GET_FUN(__glewTexScissorFuncINTEL)
+#define glTexScissorINTEL GLEW_GET_FUN(__glewTexScissorINTEL)
+
+#define GLEW_INTEL_texture_scissor GLEW_GET_VAR(__GLEW_INTEL_texture_scissor)
+
+#endif /* GL_INTEL_texture_scissor */
+
+/* ------------------------------ GL_KHR_debug ----------------------------- */
+
+#ifndef GL_KHR_debug
+#define GL_KHR_debug 1
+
+#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
+#define GL_STACK_OVERFLOW 0x0503
+#define GL_STACK_UNDERFLOW 0x0504
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
+#define GL_DEBUG_SOURCE_API 0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
+#define GL_DEBUG_SOURCE_APPLICATION 0x824A
+#define GL_DEBUG_SOURCE_OTHER 0x824B
+#define GL_DEBUG_TYPE_ERROR 0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY 0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
+#define GL_DEBUG_TYPE_OTHER 0x8251
+#define GL_DEBUG_TYPE_MARKER 0x8268
+#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
+#define GL_DEBUG_TYPE_POP_GROUP 0x826A
+#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
+#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
+#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
+#define GL_BUFFER 0x82E0
+#define GL_SHADER 0x82E1
+#define GL_PROGRAM 0x82E2
+#define GL_QUERY 0x82E3
+#define GL_PROGRAM_PIPELINE 0x82E4
+#define GL_SAMPLER 0x82E6
+#define GL_DISPLAY_LIST 0x82E7
+#define GL_MAX_LABEL_LENGTH 0x82E8
+#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES 0x9145
+#define GL_DEBUG_SEVERITY_HIGH 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
+#define GL_DEBUG_SEVERITY_LOW 0x9148
+#define GL_DEBUG_OUTPUT 0x92E0
+
+typedef void (APIENTRY *GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, GLvoid* userParam);
+
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const GLvoid *userParam);
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled);
+typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf);
+typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufsize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog);
+typedef void (GLAPIENTRY * PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar *label);
+typedef void (GLAPIENTRY * PFNGLGETOBJECTPTRLABELPROC) (void* ptr, GLsizei bufSize, GLsizei* length, GLchar *label);
+typedef void (GLAPIENTRY * PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar* label);
+typedef void (GLAPIENTRY * PFNGLOBJECTPTRLABELPROC) (void* ptr, GLsizei length, const GLchar* label);
+typedef void (GLAPIENTRY * PFNGLPOPDEBUGGROUPPROC) (void);
+typedef void (GLAPIENTRY * PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar * message);
+
+#define glDebugMessageCallback GLEW_GET_FUN(__glewDebugMessageCallback)
+#define glDebugMessageControl GLEW_GET_FUN(__glewDebugMessageControl)
+#define glDebugMessageInsert GLEW_GET_FUN(__glewDebugMessageInsert)
+#define glGetDebugMessageLog GLEW_GET_FUN(__glewGetDebugMessageLog)
+#define glGetObjectLabel GLEW_GET_FUN(__glewGetObjectLabel)
+#define glGetObjectPtrLabel GLEW_GET_FUN(__glewGetObjectPtrLabel)
+#define glObjectLabel GLEW_GET_FUN(__glewObjectLabel)
+#define glObjectPtrLabel GLEW_GET_FUN(__glewObjectPtrLabel)
+#define glPopDebugGroup GLEW_GET_FUN(__glewPopDebugGroup)
+#define glPushDebugGroup GLEW_GET_FUN(__glewPushDebugGroup)
+
+#define GLEW_KHR_debug GLEW_GET_VAR(__GLEW_KHR_debug)
+
+#endif /* GL_KHR_debug */
+
+/* ------------------ GL_KHR_texture_compression_astc_ldr ------------------ */
+
+#ifndef GL_KHR_texture_compression_astc_ldr
+#define GL_KHR_texture_compression_astc_ldr 1
+
+#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
+#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
+#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
+#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
+#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
+#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
+#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
+#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
+#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
+#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
+#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
+#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
+#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
+#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
+
+#define GLEW_KHR_texture_compression_astc_ldr GLEW_GET_VAR(__GLEW_KHR_texture_compression_astc_ldr)
+
+#endif /* GL_KHR_texture_compression_astc_ldr */
+
+/* -------------------------- GL_KTX_buffer_region ------------------------- */
+
+#ifndef GL_KTX_buffer_region
+#define GL_KTX_buffer_region 1
+
+#define GL_KTX_FRONT_REGION 0x0
+#define GL_KTX_BACK_REGION 0x1
+#define GL_KTX_Z_REGION 0x2
+#define GL_KTX_STENCIL_REGION 0x3
+
+typedef GLuint (GLAPIENTRY * PFNGLBUFFERREGIONENABLEDPROC) (void);
+typedef void (GLAPIENTRY * PFNGLDELETEBUFFERREGIONPROC) (GLenum region);
+typedef void (GLAPIENTRY * PFNGLDRAWBUFFERREGIONPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height, GLint xDest, GLint yDest);
+typedef GLuint (GLAPIENTRY * PFNGLNEWBUFFERREGIONPROC) (GLenum region);
+typedef void (GLAPIENTRY * PFNGLREADBUFFERREGIONPROC) (GLuint region, GLint x, GLint y, GLsizei width, GLsizei height);
+
+#define glBufferRegionEnabled GLEW_GET_FUN(__glewBufferRegionEnabled)
+#define glDeleteBufferRegion GLEW_GET_FUN(__glewDeleteBufferRegion)
+#define glDrawBufferRegion GLEW_GET_FUN(__glewDrawBufferRegion)
+#define glNewBufferRegion GLEW_GET_FUN(__glewNewBufferRegion)
+#define glReadBufferRegion GLEW_GET_FUN(__glewReadBufferRegion)
+
+#define GLEW_KTX_buffer_region GLEW_GET_VAR(__GLEW_KTX_buffer_region)
+
+#endif /* GL_KTX_buffer_region */
+
+/* ------------------------- GL_MESAX_texture_stack ------------------------ */
+
+#ifndef GL_MESAX_texture_stack
+#define GL_MESAX_texture_stack 1
+
+#define GL_TEXTURE_1D_STACK_MESAX 0x8759
+#define GL_TEXTURE_2D_STACK_MESAX 0x875A
+#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B
+#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C
+#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D
+#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E
+
+#define GLEW_MESAX_texture_stack GLEW_GET_VAR(__GLEW_MESAX_texture_stack)
+
+#endif /* GL_MESAX_texture_stack */
+
+/* -------------------------- GL_MESA_pack_invert -------------------------- */
+
+#ifndef GL_MESA_pack_invert
+#define GL_MESA_pack_invert 1
+
+#define GL_PACK_INVERT_MESA 0x8758
+
+#define GLEW_MESA_pack_invert GLEW_GET_VAR(__GLEW_MESA_pack_invert)
+
+#endif /* GL_MESA_pack_invert */
+
+/* ------------------------- GL_MESA_resize_buffers ------------------------ */
+
+#ifndef GL_MESA_resize_buffers
+#define GL_MESA_resize_buffers 1
+
+typedef void (GLAPIENTRY * PFNGLRESIZEBUFFERSMESAPROC) (void);
+
+#define glResizeBuffersMESA GLEW_GET_FUN(__glewResizeBuffersMESA)
+
+#define GLEW_MESA_resize_buffers GLEW_GET_VAR(__GLEW_MESA_resize_buffers)
+
+#endif /* GL_MESA_resize_buffers */
+
+/* --------------------------- GL_MESA_window_pos -------------------------- */
+
+#ifndef GL_MESA_window_pos
+#define GL_MESA_window_pos 1
+
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVMESAPROC) (const GLint* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVMESAPROC) (const GLshort* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVMESAPROC) (const GLint* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVMESAPROC) (const GLshort* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4IVMESAPROC) (const GLint* p);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (GLAPIENTRY * PFNGLWINDOWPOS4SVMESAPROC) (const GLshort* p);
+
+#define glWindowPos2dMESA GLEW_GET_FUN(__glewWindowPos2dMESA)
+#define glWindowPos2dvMESA GLEW_GET_FUN(__glewWindowPos2dvMESA)
+#define glWindowPos2fMESA GLEW_GET_FUN(__glewWindowPos2fMESA)
+#define glWindowPos2fvMESA GLEW_GET_FUN(__glewWindowPos2fvMESA)
+#define glWindowPos2iMESA GLEW_GET_FUN(__glewWindowPos2iMESA)
+#define glWindowPos2ivMESA GLEW_GET_FUN(__glewWindowPos2ivMESA)
+#define glWindowPos2sMESA GLEW_GET_FUN(__glewWindowPos2sMESA)
+#define glWindowPos2svMESA GLEW_GET_FUN(__glewWindowPos2svMESA)
+#define glWindowPos3dMESA GLEW_GET_FUN(__glewWindowPos3dMESA)
+#define glWindowPos3dvMESA GLEW_GET_FUN(__glewWindowPos3dvMESA)
+#define glWindowPos3fMESA GLEW_GET_FUN(__glewWindowPos3fMESA)
+#define glWindowPos3fvMESA GLEW_GET_FUN(__glewWindowPos3fvMESA)
+#define glWindowPos3iMESA GLEW_GET_FUN(__glewWindowPos3iMESA)
+#define glWindowPos3ivMESA GLEW_GET_FUN(__glewWindowPos3ivMESA)
+#define glWindowPos3sMESA GLEW_GET_FUN(__glewWindowPos3sMESA)
+#define glWindowPos3svMESA GLEW_GET_FUN(__glewWindowPos3svMESA)
+#define glWindowPos4dMESA GLEW_GET_FUN(__glewWindowPos4dMESA)
+#define glWindowPos4dvMESA GLEW_GET_FUN(__glewWindowPos4dvMESA)
+#define glWindowPos4fMESA GLEW_GET_FUN(__glewWindowPos4fMESA)
+#define glWindowPos4fvMESA GLEW_GET_FUN(__glewWindowPos4fvMESA)
+#define glWindowPos4iMESA GLEW_GET_FUN(__glewWindowPos4iMESA)
+#define glWindowPos4ivMESA GLEW_GET_FUN(__glewWindowPos4ivMESA)
+#define glWindowPos4sMESA GLEW_GET_FUN(__glewWindowPos4sMESA)
+#define glWindowPos4svMESA GLEW_GET_FUN(__glewWindowPos4svMESA)
+
+#define GLEW_MESA_window_pos GLEW_GET_VAR(__GLEW_MESA_window_pos)
+
+#endif /* GL_MESA_window_pos */
+
+/* ------------------------- GL_MESA_ycbcr_texture ------------------------- */
+
+#ifndef GL_MESA_ycbcr_texture
+#define GL_MESA_ycbcr_texture 1
+
+#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB
+#define GL_YCBCR_MESA 0x8757
+
+#define GLEW_MESA_ycbcr_texture GLEW_GET_VAR(__GLEW_MESA_ycbcr_texture)
+
+#endif /* GL_MESA_ycbcr_texture */
+
+/* ----------------------- GL_NVX_conditional_render ----------------------- */
+
+#ifndef GL_NVX_conditional_render
+#define GL_NVX_conditional_render 1
+
+typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVXPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVXPROC) (void);
+
+#define glBeginConditionalRenderNVX GLEW_GET_FUN(__glewBeginConditionalRenderNVX)
+#define glEndConditionalRenderNVX GLEW_GET_FUN(__glewEndConditionalRenderNVX)
+
+#define GLEW_NVX_conditional_render GLEW_GET_VAR(__GLEW_NVX_conditional_render)
+
+#endif /* GL_NVX_conditional_render */
+
+/* ------------------------- GL_NVX_gpu_memory_info ------------------------ */
+
+#ifndef GL_NVX_gpu_memory_info
+#define GL_NVX_gpu_memory_info 1
+
+#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
+#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
+#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
+#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A
+#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B
+
+#define GLEW_NVX_gpu_memory_info GLEW_GET_VAR(__GLEW_NVX_gpu_memory_info)
+
+#endif /* GL_NVX_gpu_memory_info */
+
+/* ------------------- GL_NV_bindless_multi_draw_indirect ------------------ */
+
+#ifndef GL_NV_bindless_multi_draw_indirect
+#define GL_NV_bindless_multi_draw_indirect 1
+
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC) (GLenum mode, const GLvoid *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount);
+typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC) (GLenum mode, GLenum type, const GLvoid *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount);
+
+#define glMultiDrawArraysIndirectBindlessNV GLEW_GET_FUN(__glewMultiDrawArraysIndirectBindlessNV)
+#define glMultiDrawElementsIndirectBindlessNV GLEW_GET_FUN(__glewMultiDrawElementsIndirectBindlessNV)
+
+#define GLEW_NV_bindless_multi_draw_indirect GLEW_GET_VAR(__GLEW_NV_bindless_multi_draw_indirect)
+
+#endif /* GL_NV_bindless_multi_draw_indirect */
+
+/* ------------------------- GL_NV_bindless_texture ------------------------ */
+
+#ifndef GL_NV_bindless_texture
+#define GL_NV_bindless_texture 1
+
+typedef GLuint64 (GLAPIENTRY * PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);
+typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture);
+typedef GLuint64 (GLAPIENTRY * PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler);
+typedef GLboolean (GLAPIENTRY * PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle);
+typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access);
+typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64* values);
+typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64* value);
+
+#define glGetImageHandleNV GLEW_GET_FUN(__glewGetImageHandleNV)
+#define glGetTextureHandleNV GLEW_GET_FUN(__glewGetTextureHandleNV)
+#define glGetTextureSamplerHandleNV GLEW_GET_FUN(__glewGetTextureSamplerHandleNV)
+#define glIsImageHandleResidentNV GLEW_GET_FUN(__glewIsImageHandleResidentNV)
+#define glIsTextureHandleResidentNV GLEW_GET_FUN(__glewIsTextureHandleResidentNV)
+#define glMakeImageHandleNonResidentNV GLEW_GET_FUN(__glewMakeImageHandleNonResidentNV)
+#define glMakeImageHandleResidentNV GLEW_GET_FUN(__glewMakeImageHandleResidentNV)
+#define glMakeTextureHandleNonResidentNV GLEW_GET_FUN(__glewMakeTextureHandleNonResidentNV)
+#define glMakeTextureHandleResidentNV GLEW_GET_FUN(__glewMakeTextureHandleResidentNV)
+#define glProgramUniformHandleui64NV GLEW_GET_FUN(__glewProgramUniformHandleui64NV)
+#define glProgramUniformHandleui64vNV GLEW_GET_FUN(__glewProgramUniformHandleui64vNV)
+#define glUniformHandleui64NV GLEW_GET_FUN(__glewUniformHandleui64NV)
+#define glUniformHandleui64vNV GLEW_GET_FUN(__glewUniformHandleui64vNV)
+
+#define GLEW_NV_bindless_texture GLEW_GET_VAR(__GLEW_NV_bindless_texture)
+
+#endif /* GL_NV_bindless_texture */
+
+/* --------------------- GL_NV_blend_equation_advanced --------------------- */
+
+#ifndef GL_NV_blend_equation_advanced
+#define GL_NV_blend_equation_advanced 1
+
+#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280
+#define GL_BLEND_OVERLAP_NV 0x9281
+#define GL_UNCORRELATED_NV 0x9282
+#define GL_DISJOINT_NV 0x9283
+#define GL_CONJOINT_NV 0x9284
+#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285
+#define GL_SRC_NV 0x9286
+#define GL_DST_NV 0x9287
+#define GL_SRC_OVER_NV 0x9288
+#define GL_DST_OVER_NV 0x9289
+#define GL_SRC_IN_NV 0x928A
+#define GL_DST_IN_NV 0x928B
+#define GL_SRC_OUT_NV 0x928C
+#define GL_DST_OUT_NV 0x928D
+#define GL_SRC_ATOP_NV 0x928E
+#define GL_DST_ATOP_NV 0x928F
+#define GL_PLUS_NV 0x9291
+#define GL_PLUS_DARKER_NV 0x9292
+#define GL_MULTIPLY_NV 0x9294
+#define GL_SCREEN_NV 0x9295
+#define GL_OVERLAY_NV 0x9296
+#define GL_DARKEN_NV 0x9297
+#define GL_LIGHTEN_NV 0x9298
+#define GL_COLORDODGE_NV 0x9299
+#define GL_COLORBURN_NV 0x929A
+#define GL_HARDLIGHT_NV 0x929B
+#define GL_SOFTLIGHT_NV 0x929C
+#define GL_DIFFERENCE_NV 0x929E
+#define GL_MINUS_NV 0x929F
+#define GL_EXCLUSION_NV 0x92A0
+#define GL_CONTRAST_NV 0x92A1
+#define GL_INVERT_RGB_NV 0x92A3
+#define GL_LINEARDODGE_NV 0x92A4
+#define GL_LINEARBURN_NV 0x92A5
+#define GL_VIVIDLIGHT_NV 0x92A6
+#define GL_LINEARLIGHT_NV 0x92A7
+#define GL_PINLIGHT_NV 0x92A8
+#define GL_HARDMIX_NV 0x92A9
+#define GL_HSL_HUE_NV 0x92AD
+#define GL_HSL_SATURATION_NV 0x92AE
+#define GL_HSL_COLOR_NV 0x92AF
+#define GL_HSL_LUMINOSITY_NV 0x92B0
+#define GL_PLUS_CLAMPED_NV 0x92B1
+#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2
+#define GL_MINUS_CLAMPED_NV 0x92B3
+#define GL_INVERT_OVG_NV 0x92B4
+
+typedef void (GLAPIENTRY * PFNGLBLENDBARRIERNVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value);
+
+#define glBlendBarrierNV GLEW_GET_FUN(__glewBlendBarrierNV)
+#define glBlendParameteriNV GLEW_GET_FUN(__glewBlendParameteriNV)
+
+#define GLEW_NV_blend_equation_advanced GLEW_GET_VAR(__GLEW_NV_blend_equation_advanced)
+
+#endif /* GL_NV_blend_equation_advanced */
+
+/* ----------------- GL_NV_blend_equation_advanced_coherent ---------------- */
+
+#ifndef GL_NV_blend_equation_advanced_coherent
+#define GL_NV_blend_equation_advanced_coherent 1
+
+#define GLEW_NV_blend_equation_advanced_coherent GLEW_GET_VAR(__GLEW_NV_blend_equation_advanced_coherent)
+
+#endif /* GL_NV_blend_equation_advanced_coherent */
+
+/* --------------------------- GL_NV_blend_square -------------------------- */
+
+#ifndef GL_NV_blend_square
+#define GL_NV_blend_square 1
+
+#define GLEW_NV_blend_square GLEW_GET_VAR(__GLEW_NV_blend_square)
+
+#endif /* GL_NV_blend_square */
+
+/* ------------------------- GL_NV_compute_program5 ------------------------ */
+
+#ifndef GL_NV_compute_program5
+#define GL_NV_compute_program5 1
+
+#define GL_COMPUTE_PROGRAM_NV 0x90FB
+#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC
+
+#define GLEW_NV_compute_program5 GLEW_GET_VAR(__GLEW_NV_compute_program5)
+
+#endif /* GL_NV_compute_program5 */
+
+/* ------------------------ GL_NV_conditional_render ----------------------- */
+
+#ifndef GL_NV_conditional_render
+#define GL_NV_conditional_render 1
+
+#define GL_QUERY_WAIT_NV 0x8E13
+#define GL_QUERY_NO_WAIT_NV 0x8E14
+#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16
+
+typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVPROC) (void);
+
+#define glBeginConditionalRenderNV GLEW_GET_FUN(__glewBeginConditionalRenderNV)
+#define glEndConditionalRenderNV GLEW_GET_FUN(__glewEndConditionalRenderNV)
+
+#define GLEW_NV_conditional_render GLEW_GET_VAR(__GLEW_NV_conditional_render)
+
+#endif /* GL_NV_conditional_render */
+
+/* ----------------------- GL_NV_copy_depth_to_color ----------------------- */
+
+#ifndef GL_NV_copy_depth_to_color
+#define GL_NV_copy_depth_to_color 1
+
+#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E
+#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F
+
+#define GLEW_NV_copy_depth_to_color GLEW_GET_VAR(__GLEW_NV_copy_depth_to_color)
+
+#endif /* GL_NV_copy_depth_to_color */
+
+/* ---------------------------- GL_NV_copy_image --------------------------- */
+
+#ifndef GL_NV_copy_image
+#define GL_NV_copy_image 1
+
+typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+
+#define glCopyImageSubDataNV GLEW_GET_FUN(__glewCopyImageSubDataNV)
+
+#define GLEW_NV_copy_image GLEW_GET_VAR(__GLEW_NV_copy_image)
+
+#endif /* GL_NV_copy_image */
+
+/* -------------------------- GL_NV_deep_texture3D ------------------------- */
+
+#ifndef GL_NV_deep_texture3D
+#define GL_NV_deep_texture3D 1
+
+#define GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV 0x90D0
+#define GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV 0x90D1
+
+#define GLEW_NV_deep_texture3D GLEW_GET_VAR(__GLEW_NV_deep_texture3D)
+
+#endif /* GL_NV_deep_texture3D */
+
+/* ------------------------ GL_NV_depth_buffer_float ----------------------- */
+
+#ifndef GL_NV_depth_buffer_float
+#define GL_NV_depth_buffer_float 1
+
+#define GL_DEPTH_COMPONENT32F_NV 0x8DAB
+#define GL_DEPTH32F_STENCIL8_NV 0x8DAC
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD
+#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF
+
+typedef void (GLAPIENTRY * PFNGLCLEARDEPTHDNVPROC) (GLdouble depth);
+typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax);
+typedef void (GLAPIENTRY * PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar);
+
+#define glClearDepthdNV GLEW_GET_FUN(__glewClearDepthdNV)
+#define glDepthBoundsdNV GLEW_GET_FUN(__glewDepthBoundsdNV)
+#define glDepthRangedNV GLEW_GET_FUN(__glewDepthRangedNV)
+
+#define GLEW_NV_depth_buffer_float GLEW_GET_VAR(__GLEW_NV_depth_buffer_float)
+
+#endif /* GL_NV_depth_buffer_float */
+
+/* --------------------------- GL_NV_depth_clamp --------------------------- */
+
+#ifndef GL_NV_depth_clamp
+#define GL_NV_depth_clamp 1
+
+#define GL_DEPTH_CLAMP_NV 0x864F
+
+#define GLEW_NV_depth_clamp GLEW_GET_VAR(__GLEW_NV_depth_clamp)
+
+#endif /* GL_NV_depth_clamp */
+
+/* ---------------------- GL_NV_depth_range_unclamped ---------------------- */
+
+#ifndef GL_NV_depth_range_unclamped
+#define GL_NV_depth_range_unclamped 1
+
+#define GL_SAMPLE_COUNT_BITS_NV 0x8864
+#define GL_CURRENT_SAMPLE_COUNT_QUERY_NV 0x8865
+#define GL_QUERY_RESULT_NV 0x8866
+#define GL_QUERY_RESULT_AVAILABLE_NV 0x8867
+#define GL_SAMPLE_COUNT_NV 0x8914
+
+#define GLEW_NV_depth_range_unclamped GLEW_GET_VAR(__GLEW_NV_depth_range_unclamped)
+
+#endif /* GL_NV_depth_range_unclamped */
+
+/* --------------------------- GL_NV_draw_texture -------------------------- */
+
+#ifndef GL_NV_draw_texture
+#define GL_NV_draw_texture 1
+
+typedef void (GLAPIENTRY * PFNGLDRAWTEXTURENVPROC) (GLuint texture, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1);
+
+#define glDrawTextureNV GLEW_GET_FUN(__glewDrawTextureNV)
+
+#define GLEW_NV_draw_texture GLEW_GET_VAR(__GLEW_NV_draw_texture)
+
+#endif /* GL_NV_draw_texture */
+
+/* ---------------------------- GL_NV_evaluators --------------------------- */
+
+#ifndef GL_NV_evaluators
+#define GL_NV_evaluators 1
+
+#define GL_EVAL_2D_NV 0x86C0
+#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1
+#define GL_MAP_TESSELLATION_NV 0x86C2
+#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3
+#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4
+#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5
+#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6
+#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7
+#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8
+#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9
+#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA
+#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB
+#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC
+#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD
+#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE
+#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF
+#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0
+#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1
+#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2
+#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3
+#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4
+#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5
+#define GL_MAX_MAP_TESSELLATION_NV 0x86D6
+#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7
+
+typedef void (GLAPIENTRY * PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points);
+typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points);
+typedef void (GLAPIENTRY * PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint* params);
+
+#define glEvalMapsNV GLEW_GET_FUN(__glewEvalMapsNV)
+#define glGetMapAttribParameterfvNV GLEW_GET_FUN(__glewGetMapAttribParameterfvNV)
+#define glGetMapAttribParameterivNV GLEW_GET_FUN(__glewGetMapAttribParameterivNV)
+#define glGetMapControlPointsNV GLEW_GET_FUN(__glewGetMapControlPointsNV)
+#define glGetMapParameterfvNV GLEW_GET_FUN(__glewGetMapParameterfvNV)
+#define glGetMapParameterivNV GLEW_GET_FUN(__glewGetMapParameterivNV)
+#define glMapControlPointsNV GLEW_GET_FUN(__glewMapControlPointsNV)
+#define glMapParameterfvNV GLEW_GET_FUN(__glewMapParameterfvNV)
+#define glMapParameterivNV GLEW_GET_FUN(__glewMapParameterivNV)
+
+#define GLEW_NV_evaluators GLEW_GET_VAR(__GLEW_NV_evaluators)
+
+#endif /* GL_NV_evaluators */
+
+/* ----------------------- GL_NV_explicit_multisample ---------------------- */
+
+#ifndef GL_NV_explicit_multisample
+#define GL_NV_explicit_multisample 1
+
+#define GL_SAMPLE_POSITION_NV 0x8E50
+#define GL_SAMPLE_MASK_NV 0x8E51
+#define GL_SAMPLE_MASK_VALUE_NV 0x8E52
+#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53
+#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54
+#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55
+#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56
+#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57
+#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58
+#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59
+
+typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat* val);
+typedef void (GLAPIENTRY * PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask);
+typedef void (GLAPIENTRY * PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer);
+
+#define glGetMultisamplefvNV GLEW_GET_FUN(__glewGetMultisamplefvNV)
+#define glSampleMaskIndexedNV GLEW_GET_FUN(__glewSampleMaskIndexedNV)
+#define glTexRenderbufferNV GLEW_GET_FUN(__glewTexRenderbufferNV)
+
+#define GLEW_NV_explicit_multisample GLEW_GET_VAR(__GLEW_NV_explicit_multisample)
+
+#endif /* GL_NV_explicit_multisample */
+
+/* ------------------------------ GL_NV_fence ------------------------------ */
+
+#ifndef GL_NV_fence
+#define GL_NV_fence 1
+
+#define GL_ALL_COMPLETED_NV 0x84F2
+#define GL_FENCE_STATUS_NV 0x84F3
+#define GL_FENCE_CONDITION_NV 0x84F4
+
+typedef void (GLAPIENTRY * PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint* fences);
+typedef void (GLAPIENTRY * PFNGLFINISHFENCENVPROC) (GLuint fence);
+typedef void (GLAPIENTRY * PFNGLGENFENCESNVPROC) (GLsizei n, GLuint* fences);
+typedef void (GLAPIENTRY * PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISFENCENVPROC) (GLuint fence);
+typedef void (GLAPIENTRY * PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
+typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCENVPROC) (GLuint fence);
+
+#define glDeleteFencesNV GLEW_GET_FUN(__glewDeleteFencesNV)
+#define glFinishFenceNV GLEW_GET_FUN(__glewFinishFenceNV)
+#define glGenFencesNV GLEW_GET_FUN(__glewGenFencesNV)
+#define glGetFenceivNV GLEW_GET_FUN(__glewGetFenceivNV)
+#define glIsFenceNV GLEW_GET_FUN(__glewIsFenceNV)
+#define glSetFenceNV GLEW_GET_FUN(__glewSetFenceNV)
+#define glTestFenceNV GLEW_GET_FUN(__glewTestFenceNV)
+
+#define GLEW_NV_fence GLEW_GET_VAR(__GLEW_NV_fence)
+
+#endif /* GL_NV_fence */
+
+/* --------------------------- GL_NV_float_buffer -------------------------- */
+
+#ifndef GL_NV_float_buffer
+#define GL_NV_float_buffer 1
+
+#define GL_FLOAT_R_NV 0x8880
+#define GL_FLOAT_RG_NV 0x8881
+#define GL_FLOAT_RGB_NV 0x8882
+#define GL_FLOAT_RGBA_NV 0x8883
+#define GL_FLOAT_R16_NV 0x8884
+#define GL_FLOAT_R32_NV 0x8885
+#define GL_FLOAT_RG16_NV 0x8886
+#define GL_FLOAT_RG32_NV 0x8887
+#define GL_FLOAT_RGB16_NV 0x8888
+#define GL_FLOAT_RGB32_NV 0x8889
+#define GL_FLOAT_RGBA16_NV 0x888A
+#define GL_FLOAT_RGBA32_NV 0x888B
+#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C
+#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D
+#define GL_FLOAT_RGBA_MODE_NV 0x888E
+
+#define GLEW_NV_float_buffer GLEW_GET_VAR(__GLEW_NV_float_buffer)
+
+#endif /* GL_NV_float_buffer */
+
+/* --------------------------- GL_NV_fog_distance -------------------------- */
+
+#ifndef GL_NV_fog_distance
+#define GL_NV_fog_distance 1
+
+#define GL_FOG_DISTANCE_MODE_NV 0x855A
+#define GL_EYE_RADIAL_NV 0x855B
+#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C
+
+#define GLEW_NV_fog_distance GLEW_GET_VAR(__GLEW_NV_fog_distance)
+
+#endif /* GL_NV_fog_distance */
+
+/* ------------------------- GL_NV_fragment_program ------------------------ */
+
+#ifndef GL_NV_fragment_program
+#define GL_NV_fragment_program 1
+
+#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868
+#define GL_FRAGMENT_PROGRAM_NV 0x8870
+#define GL_MAX_TEXTURE_COORDS_NV 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872
+#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873
+#define GL_PROGRAM_ERROR_STRING_NV 0x8874
+
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble *params);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLdouble v[]);
+typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte* name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte* name, const GLfloat v[]);
+
+#define glGetProgramNamedParameterdvNV GLEW_GET_FUN(__glewGetProgramNamedParameterdvNV)
+#define glGetProgramNamedParameterfvNV GLEW_GET_FUN(__glewGetProgramNamedParameterfvNV)
+#define glProgramNamedParameter4dNV GLEW_GET_FUN(__glewProgramNamedParameter4dNV)
+#define glProgramNamedParameter4dvNV GLEW_GET_FUN(__glewProgramNamedParameter4dvNV)
+#define glProgramNamedParameter4fNV GLEW_GET_FUN(__glewProgramNamedParameter4fNV)
+#define glProgramNamedParameter4fvNV GLEW_GET_FUN(__glewProgramNamedParameter4fvNV)
+
+#define GLEW_NV_fragment_program GLEW_GET_VAR(__GLEW_NV_fragment_program)
+
+#endif /* GL_NV_fragment_program */
+
+/* ------------------------ GL_NV_fragment_program2 ------------------------ */
+
+#ifndef GL_NV_fragment_program2
+#define GL_NV_fragment_program2 1
+
+#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4
+#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5
+#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6
+#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7
+#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8
+
+#define GLEW_NV_fragment_program2 GLEW_GET_VAR(__GLEW_NV_fragment_program2)
+
+#endif /* GL_NV_fragment_program2 */
+
+/* ------------------------ GL_NV_fragment_program4 ------------------------ */
+
+#ifndef GL_NV_fragment_program4
+#define GL_NV_fragment_program4 1
+
+#define GLEW_NV_fragment_program4 GLEW_GET_VAR(__GLEW_NV_fragment_program4)
+
+#endif /* GL_NV_fragment_program4 */
+
+/* --------------------- GL_NV_fragment_program_option --------------------- */
+
+#ifndef GL_NV_fragment_program_option
+#define GL_NV_fragment_program_option 1
+
+#define GLEW_NV_fragment_program_option GLEW_GET_VAR(__GLEW_NV_fragment_program_option)
+
+#endif /* GL_NV_fragment_program_option */
+
+/* ----------------- GL_NV_framebuffer_multisample_coverage ---------------- */
+
+#ifndef GL_NV_framebuffer_multisample_coverage
+#define GL_NV_framebuffer_multisample_coverage 1
+
+#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB
+#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10
+#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11
+#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12
+
+typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+
+#define glRenderbufferStorageMultisampleCoverageNV GLEW_GET_FUN(__glewRenderbufferStorageMultisampleCoverageNV)
+
+#define GLEW_NV_framebuffer_multisample_coverage GLEW_GET_VAR(__GLEW_NV_framebuffer_multisample_coverage)
+
+#endif /* GL_NV_framebuffer_multisample_coverage */
+
+/* ------------------------ GL_NV_geometry_program4 ------------------------ */
+
+#ifndef GL_NV_geometry_program4
+#define GL_NV_geometry_program4 1
+
+#define GL_GEOMETRY_PROGRAM_NV 0x8C26
+#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27
+#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28
+
+typedef void (GLAPIENTRY * PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit);
+
+#define glProgramVertexLimitNV GLEW_GET_FUN(__glewProgramVertexLimitNV)
+
+#define GLEW_NV_geometry_program4 GLEW_GET_VAR(__GLEW_NV_geometry_program4)
+
+#endif /* GL_NV_geometry_program4 */
+
+/* ------------------------- GL_NV_geometry_shader4 ------------------------ */
+
+#ifndef GL_NV_geometry_shader4
+#define GL_NV_geometry_shader4 1
+
+#define GLEW_NV_geometry_shader4 GLEW_GET_VAR(__GLEW_NV_geometry_shader4)
+
+#endif /* GL_NV_geometry_shader4 */
+
+/* --------------------------- GL_NV_gpu_program4 -------------------------- */
+
+#ifndef GL_NV_gpu_program4
+#define GL_NV_gpu_program4 1
+
+#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905
+#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906
+#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907
+#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908
+#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909
+#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5
+#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6
+
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+
+#define glProgramEnvParameterI4iNV GLEW_GET_FUN(__glewProgramEnvParameterI4iNV)
+#define glProgramEnvParameterI4ivNV GLEW_GET_FUN(__glewProgramEnvParameterI4ivNV)
+#define glProgramEnvParameterI4uiNV GLEW_GET_FUN(__glewProgramEnvParameterI4uiNV)
+#define glProgramEnvParameterI4uivNV GLEW_GET_FUN(__glewProgramEnvParameterI4uivNV)
+#define glProgramEnvParametersI4ivNV GLEW_GET_FUN(__glewProgramEnvParametersI4ivNV)
+#define glProgramEnvParametersI4uivNV GLEW_GET_FUN(__glewProgramEnvParametersI4uivNV)
+#define glProgramLocalParameterI4iNV GLEW_GET_FUN(__glewProgramLocalParameterI4iNV)
+#define glProgramLocalParameterI4ivNV GLEW_GET_FUN(__glewProgramLocalParameterI4ivNV)
+#define glProgramLocalParameterI4uiNV GLEW_GET_FUN(__glewProgramLocalParameterI4uiNV)
+#define glProgramLocalParameterI4uivNV GLEW_GET_FUN(__glewProgramLocalParameterI4uivNV)
+#define glProgramLocalParametersI4ivNV GLEW_GET_FUN(__glewProgramLocalParametersI4ivNV)
+#define glProgramLocalParametersI4uivNV GLEW_GET_FUN(__glewProgramLocalParametersI4uivNV)
+
+#define GLEW_NV_gpu_program4 GLEW_GET_VAR(__GLEW_NV_gpu_program4)
+
+#endif /* GL_NV_gpu_program4 */
+
+/* --------------------------- GL_NV_gpu_program5 -------------------------- */
+
+#ifndef GL_NV_gpu_program5
+#define GL_NV_gpu_program5 1
+
+#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C
+#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F
+
+#define GLEW_NV_gpu_program5 GLEW_GET_VAR(__GLEW_NV_gpu_program5)
+
+#endif /* GL_NV_gpu_program5 */
+
+/* -------------------- GL_NV_gpu_program5_mem_extended -------------------- */
+
+#ifndef GL_NV_gpu_program5_mem_extended
+#define GL_NV_gpu_program5_mem_extended 1
+
+#define GLEW_NV_gpu_program5_mem_extended GLEW_GET_VAR(__GLEW_NV_gpu_program5_mem_extended)
+
+#endif /* GL_NV_gpu_program5_mem_extended */
+
+/* ------------------------- GL_NV_gpu_program_fp64 ------------------------ */
+
+#ifndef GL_NV_gpu_program_fp64
+#define GL_NV_gpu_program_fp64 1
+
+#define GLEW_NV_gpu_program_fp64 GLEW_GET_VAR(__GLEW_NV_gpu_program_fp64)
+
+#endif /* GL_NV_gpu_program_fp64 */
+
+/* --------------------------- GL_NV_gpu_shader5 --------------------------- */
+
+#ifndef GL_NV_gpu_shader5
+#define GL_NV_gpu_shader5 1
+
+#define GL_INT64_NV 0x140E
+#define GL_UNSIGNED_INT64_NV 0x140F
+#define GL_INT8_NV 0x8FE0
+#define GL_INT8_VEC2_NV 0x8FE1
+#define GL_INT8_VEC3_NV 0x8FE2
+#define GL_INT8_VEC4_NV 0x8FE3
+#define GL_INT16_NV 0x8FE4
+#define GL_INT16_VEC2_NV 0x8FE5
+#define GL_INT16_VEC3_NV 0x8FE6
+#define GL_INT16_VEC4_NV 0x8FE7
+#define GL_INT64_VEC2_NV 0x8FE9
+#define GL_INT64_VEC3_NV 0x8FEA
+#define GL_INT64_VEC4_NV 0x8FEB
+#define GL_UNSIGNED_INT8_NV 0x8FEC
+#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED
+#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE
+#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF
+#define GL_UNSIGNED_INT16_NV 0x8FF0
+#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1
+#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2
+#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3
+#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5
+#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6
+#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7
+#define GL_FLOAT16_NV 0x8FF8
+#define GL_FLOAT16_VEC2_NV 0x8FF9
+#define GL_FLOAT16_VEC3_NV 0x8FFA
+#define GL_FLOAT16_VEC4_NV 0x8FFB
+
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x);
+typedef void (GLAPIENTRY * PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (GLAPIENTRY * PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (GLAPIENTRY * PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (GLAPIENTRY * PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value);
+
+#define glGetUniformi64vNV GLEW_GET_FUN(__glewGetUniformi64vNV)
+#define glGetUniformui64vNV GLEW_GET_FUN(__glewGetUniformui64vNV)
+#define glProgramUniform1i64NV GLEW_GET_FUN(__glewProgramUniform1i64NV)
+#define glProgramUniform1i64vNV GLEW_GET_FUN(__glewProgramUniform1i64vNV)
+#define glProgramUniform1ui64NV GLEW_GET_FUN(__glewProgramUniform1ui64NV)
+#define glProgramUniform1ui64vNV GLEW_GET_FUN(__glewProgramUniform1ui64vNV)
+#define glProgramUniform2i64NV GLEW_GET_FUN(__glewProgramUniform2i64NV)
+#define glProgramUniform2i64vNV GLEW_GET_FUN(__glewProgramUniform2i64vNV)
+#define glProgramUniform2ui64NV GLEW_GET_FUN(__glewProgramUniform2ui64NV)
+#define glProgramUniform2ui64vNV GLEW_GET_FUN(__glewProgramUniform2ui64vNV)
+#define glProgramUniform3i64NV GLEW_GET_FUN(__glewProgramUniform3i64NV)
+#define glProgramUniform3i64vNV GLEW_GET_FUN(__glewProgramUniform3i64vNV)
+#define glProgramUniform3ui64NV GLEW_GET_FUN(__glewProgramUniform3ui64NV)
+#define glProgramUniform3ui64vNV GLEW_GET_FUN(__glewProgramUniform3ui64vNV)
+#define glProgramUniform4i64NV GLEW_GET_FUN(__glewProgramUniform4i64NV)
+#define glProgramUniform4i64vNV GLEW_GET_FUN(__glewProgramUniform4i64vNV)
+#define glProgramUniform4ui64NV GLEW_GET_FUN(__glewProgramUniform4ui64NV)
+#define glProgramUniform4ui64vNV GLEW_GET_FUN(__glewProgramUniform4ui64vNV)
+#define glUniform1i64NV GLEW_GET_FUN(__glewUniform1i64NV)
+#define glUniform1i64vNV GLEW_GET_FUN(__glewUniform1i64vNV)
+#define glUniform1ui64NV GLEW_GET_FUN(__glewUniform1ui64NV)
+#define glUniform1ui64vNV GLEW_GET_FUN(__glewUniform1ui64vNV)
+#define glUniform2i64NV GLEW_GET_FUN(__glewUniform2i64NV)
+#define glUniform2i64vNV GLEW_GET_FUN(__glewUniform2i64vNV)
+#define glUniform2ui64NV GLEW_GET_FUN(__glewUniform2ui64NV)
+#define glUniform2ui64vNV GLEW_GET_FUN(__glewUniform2ui64vNV)
+#define glUniform3i64NV GLEW_GET_FUN(__glewUniform3i64NV)
+#define glUniform3i64vNV GLEW_GET_FUN(__glewUniform3i64vNV)
+#define glUniform3ui64NV GLEW_GET_FUN(__glewUniform3ui64NV)
+#define glUniform3ui64vNV GLEW_GET_FUN(__glewUniform3ui64vNV)
+#define glUniform4i64NV GLEW_GET_FUN(__glewUniform4i64NV)
+#define glUniform4i64vNV GLEW_GET_FUN(__glewUniform4i64vNV)
+#define glUniform4ui64NV GLEW_GET_FUN(__glewUniform4ui64NV)
+#define glUniform4ui64vNV GLEW_GET_FUN(__glewUniform4ui64vNV)
+
+#define GLEW_NV_gpu_shader5 GLEW_GET_VAR(__GLEW_NV_gpu_shader5)
+
+#endif /* GL_NV_gpu_shader5 */
+
+/* ---------------------------- GL_NV_half_float --------------------------- */
+
+#ifndef GL_NV_half_float
+#define GL_NV_half_float 1
+
+#define GL_HALF_FLOAT_NV 0x140B
+
+typedef unsigned short GLhalf;
+
+typedef void (GLAPIENTRY * PFNGLCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue);
+typedef void (GLAPIENTRY * PFNGLCOLOR3HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4HNVPROC) (GLhalf red, GLhalf green, GLhalf blue, GLhalf alpha);
+typedef void (GLAPIENTRY * PFNGLCOLOR4HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDHNVPROC) (GLhalf fog);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDHVNVPROC) (const GLhalf* fog);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalf s);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalf s, GLhalf t);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalf s, GLhalf t, GLhalf r, GLhalf q);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLNORMAL3HNVPROC) (GLhalf nx, GLhalf ny, GLhalf nz);
+typedef void (GLAPIENTRY * PFNGLNORMAL3HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HNVPROC) (GLhalf red, GLhalf green, GLhalf blue);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD1HNVPROC) (GLhalf s);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD1HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2HNVPROC) (GLhalf s, GLhalf t);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD3HNVPROC) (GLhalf s, GLhalf t, GLhalf r);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD3HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4HNVPROC) (GLhalf s, GLhalf t, GLhalf r, GLhalf q);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEX2HNVPROC) (GLhalf x, GLhalf y);
+typedef void (GLAPIENTRY * PFNGLVERTEX2HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEX3HNVPROC) (GLhalf x, GLhalf y, GLhalf z);
+typedef void (GLAPIENTRY * PFNGLVERTEX3HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEX4HNVPROC) (GLhalf x, GLhalf y, GLhalf z, GLhalf w);
+typedef void (GLAPIENTRY * PFNGLVERTEX4HVNVPROC) (const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalf x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalf x, GLhalf y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalf x, GLhalf y, GLhalf z, GLhalf w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalf* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHNVPROC) (GLhalf weight);
+typedef void (GLAPIENTRY * PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalf* weight);
+
+#define glColor3hNV GLEW_GET_FUN(__glewColor3hNV)
+#define glColor3hvNV GLEW_GET_FUN(__glewColor3hvNV)
+#define glColor4hNV GLEW_GET_FUN(__glewColor4hNV)
+#define glColor4hvNV GLEW_GET_FUN(__glewColor4hvNV)
+#define glFogCoordhNV GLEW_GET_FUN(__glewFogCoordhNV)
+#define glFogCoordhvNV GLEW_GET_FUN(__glewFogCoordhvNV)
+#define glMultiTexCoord1hNV GLEW_GET_FUN(__glewMultiTexCoord1hNV)
+#define glMultiTexCoord1hvNV GLEW_GET_FUN(__glewMultiTexCoord1hvNV)
+#define glMultiTexCoord2hNV GLEW_GET_FUN(__glewMultiTexCoord2hNV)
+#define glMultiTexCoord2hvNV GLEW_GET_FUN(__glewMultiTexCoord2hvNV)
+#define glMultiTexCoord3hNV GLEW_GET_FUN(__glewMultiTexCoord3hNV)
+#define glMultiTexCoord3hvNV GLEW_GET_FUN(__glewMultiTexCoord3hvNV)
+#define glMultiTexCoord4hNV GLEW_GET_FUN(__glewMultiTexCoord4hNV)
+#define glMultiTexCoord4hvNV GLEW_GET_FUN(__glewMultiTexCoord4hvNV)
+#define glNormal3hNV GLEW_GET_FUN(__glewNormal3hNV)
+#define glNormal3hvNV GLEW_GET_FUN(__glewNormal3hvNV)
+#define glSecondaryColor3hNV GLEW_GET_FUN(__glewSecondaryColor3hNV)
+#define glSecondaryColor3hvNV GLEW_GET_FUN(__glewSecondaryColor3hvNV)
+#define glTexCoord1hNV GLEW_GET_FUN(__glewTexCoord1hNV)
+#define glTexCoord1hvNV GLEW_GET_FUN(__glewTexCoord1hvNV)
+#define glTexCoord2hNV GLEW_GET_FUN(__glewTexCoord2hNV)
+#define glTexCoord2hvNV GLEW_GET_FUN(__glewTexCoord2hvNV)
+#define glTexCoord3hNV GLEW_GET_FUN(__glewTexCoord3hNV)
+#define glTexCoord3hvNV GLEW_GET_FUN(__glewTexCoord3hvNV)
+#define glTexCoord4hNV GLEW_GET_FUN(__glewTexCoord4hNV)
+#define glTexCoord4hvNV GLEW_GET_FUN(__glewTexCoord4hvNV)
+#define glVertex2hNV GLEW_GET_FUN(__glewVertex2hNV)
+#define glVertex2hvNV GLEW_GET_FUN(__glewVertex2hvNV)
+#define glVertex3hNV GLEW_GET_FUN(__glewVertex3hNV)
+#define glVertex3hvNV GLEW_GET_FUN(__glewVertex3hvNV)
+#define glVertex4hNV GLEW_GET_FUN(__glewVertex4hNV)
+#define glVertex4hvNV GLEW_GET_FUN(__glewVertex4hvNV)
+#define glVertexAttrib1hNV GLEW_GET_FUN(__glewVertexAttrib1hNV)
+#define glVertexAttrib1hvNV GLEW_GET_FUN(__glewVertexAttrib1hvNV)
+#define glVertexAttrib2hNV GLEW_GET_FUN(__glewVertexAttrib2hNV)
+#define glVertexAttrib2hvNV GLEW_GET_FUN(__glewVertexAttrib2hvNV)
+#define glVertexAttrib3hNV GLEW_GET_FUN(__glewVertexAttrib3hNV)
+#define glVertexAttrib3hvNV GLEW_GET_FUN(__glewVertexAttrib3hvNV)
+#define glVertexAttrib4hNV GLEW_GET_FUN(__glewVertexAttrib4hNV)
+#define glVertexAttrib4hvNV GLEW_GET_FUN(__glewVertexAttrib4hvNV)
+#define glVertexAttribs1hvNV GLEW_GET_FUN(__glewVertexAttribs1hvNV)
+#define glVertexAttribs2hvNV GLEW_GET_FUN(__glewVertexAttribs2hvNV)
+#define glVertexAttribs3hvNV GLEW_GET_FUN(__glewVertexAttribs3hvNV)
+#define glVertexAttribs4hvNV GLEW_GET_FUN(__glewVertexAttribs4hvNV)
+#define glVertexWeighthNV GLEW_GET_FUN(__glewVertexWeighthNV)
+#define glVertexWeighthvNV GLEW_GET_FUN(__glewVertexWeighthvNV)
+
+#define GLEW_NV_half_float GLEW_GET_VAR(__GLEW_NV_half_float)
+
+#endif /* GL_NV_half_float */
+
+/* ------------------------ GL_NV_light_max_exponent ----------------------- */
+
+#ifndef GL_NV_light_max_exponent
+#define GL_NV_light_max_exponent 1
+
+#define GL_MAX_SHININESS_NV 0x8504
+#define GL_MAX_SPOT_EXPONENT_NV 0x8505
+
+#define GLEW_NV_light_max_exponent GLEW_GET_VAR(__GLEW_NV_light_max_exponent)
+
+#endif /* GL_NV_light_max_exponent */
+
+/* ----------------------- GL_NV_multisample_coverage ---------------------- */
+
+#ifndef GL_NV_multisample_coverage
+#define GL_NV_multisample_coverage 1
+
+#define GL_COLOR_SAMPLES_NV 0x8E20
+
+#define GLEW_NV_multisample_coverage GLEW_GET_VAR(__GLEW_NV_multisample_coverage)
+
+#endif /* GL_NV_multisample_coverage */
+
+/* --------------------- GL_NV_multisample_filter_hint --------------------- */
+
+#ifndef GL_NV_multisample_filter_hint
+#define GL_NV_multisample_filter_hint 1
+
+#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534
+
+#define GLEW_NV_multisample_filter_hint GLEW_GET_VAR(__GLEW_NV_multisample_filter_hint)
+
+#endif /* GL_NV_multisample_filter_hint */
+
+/* ------------------------- GL_NV_occlusion_query ------------------------- */
+
+#ifndef GL_NV_occlusion_query
+#define GL_NV_occlusion_query 1
+
+#define GL_PIXEL_COUNTER_BITS_NV 0x8864
+#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865
+#define GL_PIXEL_COUNT_NV 0x8866
+#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867
+
+typedef void (GLAPIENTRY * PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLENDOCCLUSIONQUERYNVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id);
+
+#define glBeginOcclusionQueryNV GLEW_GET_FUN(__glewBeginOcclusionQueryNV)
+#define glDeleteOcclusionQueriesNV GLEW_GET_FUN(__glewDeleteOcclusionQueriesNV)
+#define glEndOcclusionQueryNV GLEW_GET_FUN(__glewEndOcclusionQueryNV)
+#define glGenOcclusionQueriesNV GLEW_GET_FUN(__glewGenOcclusionQueriesNV)
+#define glGetOcclusionQueryivNV GLEW_GET_FUN(__glewGetOcclusionQueryivNV)
+#define glGetOcclusionQueryuivNV GLEW_GET_FUN(__glewGetOcclusionQueryuivNV)
+#define glIsOcclusionQueryNV GLEW_GET_FUN(__glewIsOcclusionQueryNV)
+
+#define GLEW_NV_occlusion_query GLEW_GET_VAR(__GLEW_NV_occlusion_query)
+
+#endif /* GL_NV_occlusion_query */
+
+/* ----------------------- GL_NV_packed_depth_stencil ---------------------- */
+
+#ifndef GL_NV_packed_depth_stencil
+#define GL_NV_packed_depth_stencil 1
+
+#define GL_DEPTH_STENCIL_NV 0x84F9
+#define GL_UNSIGNED_INT_24_8_NV 0x84FA
+
+#define GLEW_NV_packed_depth_stencil GLEW_GET_VAR(__GLEW_NV_packed_depth_stencil)
+
+#endif /* GL_NV_packed_depth_stencil */
+
+/* --------------------- GL_NV_parameter_buffer_object --------------------- */
+
+#ifndef GL_NV_parameter_buffer_object
+#define GL_NV_parameter_buffer_object 1
+
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1
+#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2
+#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3
+#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4
+
+typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params);
+
+#define glProgramBufferParametersIivNV GLEW_GET_FUN(__glewProgramBufferParametersIivNV)
+#define glProgramBufferParametersIuivNV GLEW_GET_FUN(__glewProgramBufferParametersIuivNV)
+#define glProgramBufferParametersfvNV GLEW_GET_FUN(__glewProgramBufferParametersfvNV)
+
+#define GLEW_NV_parameter_buffer_object GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object)
+
+#endif /* GL_NV_parameter_buffer_object */
+
+/* --------------------- GL_NV_parameter_buffer_object2 -------------------- */
+
+#ifndef GL_NV_parameter_buffer_object2
+#define GL_NV_parameter_buffer_object2 1
+
+#define GLEW_NV_parameter_buffer_object2 GLEW_GET_VAR(__GLEW_NV_parameter_buffer_object2)
+
+#endif /* GL_NV_parameter_buffer_object2 */
+
+/* -------------------------- GL_NV_path_rendering ------------------------- */
+
+#ifndef GL_NV_path_rendering
+#define GL_NV_path_rendering 1
+
+#define GL_CLOSE_PATH_NV 0x00
+#define GL_BOLD_BIT_NV 0x01
+#define GL_GLYPH_WIDTH_BIT_NV 0x01
+#define GL_GLYPH_HEIGHT_BIT_NV 0x02
+#define GL_ITALIC_BIT_NV 0x02
+#define GL_MOVE_TO_NV 0x02
+#define GL_RELATIVE_MOVE_TO_NV 0x03
+#define GL_LINE_TO_NV 0x04
+#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04
+#define GL_RELATIVE_LINE_TO_NV 0x05
+#define GL_HORIZONTAL_LINE_TO_NV 0x06
+#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07
+#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08
+#define GL_VERTICAL_LINE_TO_NV 0x08
+#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09
+#define GL_QUADRATIC_CURVE_TO_NV 0x0A
+#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B
+#define GL_CUBIC_CURVE_TO_NV 0x0C
+#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D
+#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E
+#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F
+#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10
+#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10
+#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11
+#define GL_SMALL_CCW_ARC_TO_NV 0x12
+#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13
+#define GL_SMALL_CW_ARC_TO_NV 0x14
+#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15
+#define GL_LARGE_CCW_ARC_TO_NV 0x16
+#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17
+#define GL_LARGE_CW_ARC_TO_NV 0x18
+#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19
+#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20
+#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40
+#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80
+#define GL_RESTART_PATH_NV 0xF0
+#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2
+#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4
+#define GL_RECT_NV 0xF6
+#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8
+#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA
+#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC
+#define GL_ARC_TO_NV 0xFE
+#define GL_RELATIVE_ARC_TO_NV 0xFF
+#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100
+#define GL_PRIMARY_COLOR 0x8577
+#define GL_PATH_FORMAT_SVG_NV 0x9070
+#define GL_PATH_FORMAT_PS_NV 0x9071
+#define GL_STANDARD_FONT_NAME_NV 0x9072
+#define GL_SYSTEM_FONT_NAME_NV 0x9073
+#define GL_FILE_NAME_NV 0x9074
+#define GL_PATH_STROKE_WIDTH_NV 0x9075
+#define GL_PATH_END_CAPS_NV 0x9076
+#define GL_PATH_INITIAL_END_CAP_NV 0x9077
+#define GL_PATH_TERMINAL_END_CAP_NV 0x9078
+#define GL_PATH_JOIN_STYLE_NV 0x9079
+#define GL_PATH_MITER_LIMIT_NV 0x907A
+#define GL_PATH_DASH_CAPS_NV 0x907B
+#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C
+#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D
+#define GL_PATH_DASH_OFFSET_NV 0x907E
+#define GL_PATH_CLIENT_LENGTH_NV 0x907F
+#define GL_PATH_FILL_MODE_NV 0x9080
+#define GL_PATH_FILL_MASK_NV 0x9081
+#define GL_PATH_FILL_COVER_MODE_NV 0x9082
+#define GL_PATH_STROKE_COVER_MODE_NV 0x9083
+#define GL_PATH_STROKE_MASK_NV 0x9084
+#define GL_COUNT_UP_NV 0x9088
+#define GL_COUNT_DOWN_NV 0x9089
+#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A
+#define GL_CONVEX_HULL_NV 0x908B
+#define GL_BOUNDING_BOX_NV 0x908D
+#define GL_TRANSLATE_X_NV 0x908E
+#define GL_TRANSLATE_Y_NV 0x908F
+#define GL_TRANSLATE_2D_NV 0x9090
+#define GL_TRANSLATE_3D_NV 0x9091
+#define GL_AFFINE_2D_NV 0x9092
+#define GL_AFFINE_3D_NV 0x9094
+#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096
+#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098
+#define GL_UTF8_NV 0x909A
+#define GL_UTF16_NV 0x909B
+#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C
+#define GL_PATH_COMMAND_COUNT_NV 0x909D
+#define GL_PATH_COORD_COUNT_NV 0x909E
+#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F
+#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0
+#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1
+#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2
+#define GL_SQUARE_NV 0x90A3
+#define GL_ROUND_NV 0x90A4
+#define GL_TRIANGULAR_NV 0x90A5
+#define GL_BEVEL_NV 0x90A6
+#define GL_MITER_REVERT_NV 0x90A7
+#define GL_MITER_TRUNCATE_NV 0x90A8
+#define GL_SKIP_MISSING_GLYPH_NV 0x90A9
+#define GL_USE_MISSING_GLYPH_NV 0x90AA
+#define GL_PATH_ERROR_POSITION_NV 0x90AB
+#define GL_PATH_FOG_GEN_MODE_NV 0x90AC
+#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD
+#define GL_ADJACENT_PAIRS_NV 0x90AE
+#define GL_FIRST_TO_REST_NV 0x90AF
+#define GL_PATH_GEN_MODE_NV 0x90B0
+#define GL_PATH_GEN_COEFF_NV 0x90B1
+#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2
+#define GL_PATH_GEN_COMPONENTS_NV 0x90B3
+#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4
+#define GL_MOVE_TO_RESETS_NV 0x90B5
+#define GL_MOVE_TO_CONTINUES_NV 0x90B6
+#define GL_PATH_STENCIL_FUNC_NV 0x90B7
+#define GL_PATH_STENCIL_REF_NV 0x90B8
+#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9
+#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD
+#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE
+#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF
+#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000
+#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000
+#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000
+#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000
+#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000
+#define GL_FONT_ASCENDER_BIT_NV 0x00200000
+#define GL_FONT_DESCENDER_BIT_NV 0x00400000
+#define GL_FONT_HEIGHT_BIT_NV 0x00800000
+#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000
+#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000
+#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000
+#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000
+#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000
+
+typedef void (GLAPIENTRY * PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath);
+typedef void (GLAPIENTRY * PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void* paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GLAPIENTRY * PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode);
+typedef void (GLAPIENTRY * PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void* paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GLAPIENTRY * PFNGLCOVERSTROKEPATHNVPROC) (GLuint name, GLenum coverMode);
+typedef void (GLAPIENTRY * PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range);
+typedef GLuint (GLAPIENTRY * PFNGLGENPATHSNVPROC) (GLsizei range);
+typedef void (GLAPIENTRY * PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint* value);
+typedef void (GLAPIENTRY * PFNGLGETPATHCOMMANDSNVPROC) (GLuint name, GLubyte* commands);
+typedef void (GLAPIENTRY * PFNGLGETPATHCOORDSNVPROC) (GLuint name, GLfloat* coords);
+typedef void (GLAPIENTRY * PFNGLGETPATHDASHARRAYNVPROC) (GLuint name, GLfloat* dashArray);
+typedef GLfloat (GLAPIENTRY * PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments);
+typedef void (GLAPIENTRY * PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint fistPathName, GLsizei numPaths, GLsizei stride, GLfloat* metrics);
+typedef void (GLAPIENTRY * PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void* paths, GLuint pathBase, GLsizei stride, GLfloat *metrics);
+typedef void (GLAPIENTRY * PFNGLGETPATHPARAMETERFVNVPROC) (GLuint name, GLenum param, GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLGETPATHPARAMETERIVNVPROC) (GLuint name, GLenum param, GLint* value);
+typedef void (GLAPIENTRY * PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void* paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing);
+typedef void (GLAPIENTRY * PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint* value);
+typedef void (GLAPIENTRY * PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight);
+typedef GLboolean (GLAPIENTRY * PFNGLISPATHNVPROC) (GLuint path);
+typedef GLboolean (GLAPIENTRY * PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y);
+typedef GLboolean (GLAPIENTRY * PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat* coeffs);
+typedef void (GLAPIENTRY * PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte* commands, GLsizei numCoords, GLenum coordType, const GLvoid*coords);
+typedef void (GLAPIENTRY * PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void* coords);
+typedef void (GLAPIENTRY * PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum zfunc);
+typedef void (GLAPIENTRY * PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat* dashArray);
+typedef void (GLAPIENTRY * PFNGLPATHFOGGENNVPROC) (GLenum genMode);
+typedef void (GLAPIENTRY * PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void* fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (GLAPIENTRY * PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void* fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const GLvoid*charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (GLAPIENTRY * PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value);
+typedef void (GLAPIENTRY * PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat* value);
+typedef void (GLAPIENTRY * PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value);
+typedef void (GLAPIENTRY * PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint* value);
+typedef void (GLAPIENTRY * PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units);
+typedef void (GLAPIENTRY * PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask);
+typedef void (GLAPIENTRY * PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void* pathString);
+typedef void (GLAPIENTRY * PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte* commands, GLsizei numCoords, GLenum coordType, const GLvoid*coords);
+typedef void (GLAPIENTRY * PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void* coords);
+typedef void (GLAPIENTRY * PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat* coeffs);
+typedef GLboolean (GLAPIENTRY * PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat* x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY);
+typedef void (GLAPIENTRY * PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void* paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+typedef void (GLAPIENTRY * PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask);
+typedef void (GLAPIENTRY * PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void* paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+typedef void (GLAPIENTRY * PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask);
+typedef void (GLAPIENTRY * PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat* transformValues);
+typedef void (GLAPIENTRY * PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint paths[], const GLfloat weights[]);
+
+#define glCopyPathNV GLEW_GET_FUN(__glewCopyPathNV)
+#define glCoverFillPathInstancedNV GLEW_GET_FUN(__glewCoverFillPathInstancedNV)
+#define glCoverFillPathNV GLEW_GET_FUN(__glewCoverFillPathNV)
+#define glCoverStrokePathInstancedNV GLEW_GET_FUN(__glewCoverStrokePathInstancedNV)
+#define glCoverStrokePathNV GLEW_GET_FUN(__glewCoverStrokePathNV)
+#define glDeletePathsNV GLEW_GET_FUN(__glewDeletePathsNV)
+#define glGenPathsNV GLEW_GET_FUN(__glewGenPathsNV)
+#define glGetPathColorGenfvNV GLEW_GET_FUN(__glewGetPathColorGenfvNV)
+#define glGetPathColorGenivNV GLEW_GET_FUN(__glewGetPathColorGenivNV)
+#define glGetPathCommandsNV GLEW_GET_FUN(__glewGetPathCommandsNV)
+#define glGetPathCoordsNV GLEW_GET_FUN(__glewGetPathCoordsNV)
+#define glGetPathDashArrayNV GLEW_GET_FUN(__glewGetPathDashArrayNV)
+#define glGetPathLengthNV GLEW_GET_FUN(__glewGetPathLengthNV)
+#define glGetPathMetricRangeNV GLEW_GET_FUN(__glewGetPathMetricRangeNV)
+#define glGetPathMetricsNV GLEW_GET_FUN(__glewGetPathMetricsNV)
+#define glGetPathParameterfvNV GLEW_GET_FUN(__glewGetPathParameterfvNV)
+#define glGetPathParameterivNV GLEW_GET_FUN(__glewGetPathParameterivNV)
+#define glGetPathSpacingNV GLEW_GET_FUN(__glewGetPathSpacingNV)
+#define glGetPathTexGenfvNV GLEW_GET_FUN(__glewGetPathTexGenfvNV)
+#define glGetPathTexGenivNV GLEW_GET_FUN(__glewGetPathTexGenivNV)
+#define glInterpolatePathsNV GLEW_GET_FUN(__glewInterpolatePathsNV)
+#define glIsPathNV GLEW_GET_FUN(__glewIsPathNV)
+#define glIsPointInFillPathNV GLEW_GET_FUN(__glewIsPointInFillPathNV)
+#define glIsPointInStrokePathNV GLEW_GET_FUN(__glewIsPointInStrokePathNV)
+#define glPathColorGenNV GLEW_GET_FUN(__glewPathColorGenNV)
+#define glPathCommandsNV GLEW_GET_FUN(__glewPathCommandsNV)
+#define glPathCoordsNV GLEW_GET_FUN(__glewPathCoordsNV)
+#define glPathCoverDepthFuncNV GLEW_GET_FUN(__glewPathCoverDepthFuncNV)
+#define glPathDashArrayNV GLEW_GET_FUN(__glewPathDashArrayNV)
+#define glPathFogGenNV GLEW_GET_FUN(__glewPathFogGenNV)
+#define glPathGlyphRangeNV GLEW_GET_FUN(__glewPathGlyphRangeNV)
+#define glPathGlyphsNV GLEW_GET_FUN(__glewPathGlyphsNV)
+#define glPathParameterfNV GLEW_GET_FUN(__glewPathParameterfNV)
+#define glPathParameterfvNV GLEW_GET_FUN(__glewPathParameterfvNV)
+#define glPathParameteriNV GLEW_GET_FUN(__glewPathParameteriNV)
+#define glPathParameterivNV GLEW_GET_FUN(__glewPathParameterivNV)
+#define glPathStencilDepthOffsetNV GLEW_GET_FUN(__glewPathStencilDepthOffsetNV)
+#define glPathStencilFuncNV GLEW_GET_FUN(__glewPathStencilFuncNV)
+#define glPathStringNV GLEW_GET_FUN(__glewPathStringNV)
+#define glPathSubCommandsNV GLEW_GET_FUN(__glewPathSubCommandsNV)
+#define glPathSubCoordsNV GLEW_GET_FUN(__glewPathSubCoordsNV)
+#define glPathTexGenNV GLEW_GET_FUN(__glewPathTexGenNV)
+#define glPointAlongPathNV GLEW_GET_FUN(__glewPointAlongPathNV)
+#define glStencilFillPathInstancedNV GLEW_GET_FUN(__glewStencilFillPathInstancedNV)
+#define glStencilFillPathNV GLEW_GET_FUN(__glewStencilFillPathNV)
+#define glStencilStrokePathInstancedNV GLEW_GET_FUN(__glewStencilStrokePathInstancedNV)
+#define glStencilStrokePathNV GLEW_GET_FUN(__glewStencilStrokePathNV)
+#define glTransformPathNV GLEW_GET_FUN(__glewTransformPathNV)
+#define glWeightPathsNV GLEW_GET_FUN(__glewWeightPathsNV)
+
+#define GLEW_NV_path_rendering GLEW_GET_VAR(__GLEW_NV_path_rendering)
+
+#endif /* GL_NV_path_rendering */
+
+/* ------------------------- GL_NV_pixel_data_range ------------------------ */
+
+#ifndef GL_NV_pixel_data_range
+#define GL_NV_pixel_data_range 1
+
+#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878
+#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879
+#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A
+#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B
+#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C
+#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D
+
+typedef void (GLAPIENTRY * PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer);
+
+#define glFlushPixelDataRangeNV GLEW_GET_FUN(__glewFlushPixelDataRangeNV)
+#define glPixelDataRangeNV GLEW_GET_FUN(__glewPixelDataRangeNV)
+
+#define GLEW_NV_pixel_data_range GLEW_GET_VAR(__GLEW_NV_pixel_data_range)
+
+#endif /* GL_NV_pixel_data_range */
+
+/* --------------------------- GL_NV_point_sprite -------------------------- */
+
+#ifndef GL_NV_point_sprite
+#define GL_NV_point_sprite 1
+
+#define GL_POINT_SPRITE_NV 0x8861
+#define GL_COORD_REPLACE_NV 0x8862
+#define GL_POINT_SPRITE_R_MODE_NV 0x8863
+
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint* params);
+
+#define glPointParameteriNV GLEW_GET_FUN(__glewPointParameteriNV)
+#define glPointParameterivNV GLEW_GET_FUN(__glewPointParameterivNV)
+
+#define GLEW_NV_point_sprite GLEW_GET_VAR(__GLEW_NV_point_sprite)
+
+#endif /* GL_NV_point_sprite */
+
+/* -------------------------- GL_NV_present_video -------------------------- */
+
+#ifndef GL_NV_present_video
+#define GL_NV_present_video 1
+
+#define GL_FRAME_NV 0x8E26
+#define GL_FIELDS_NV 0x8E27
+#define GL_CURRENT_TIME_NV 0x8E28
+#define GL_NUM_FILL_STREAMS_NV 0x8E29
+#define GL_PRESENT_TIME_NV 0x8E2A
+#define GL_PRESENT_DURATION_NV 0x8E2B
+
+typedef void (GLAPIENTRY * PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint* params);
+typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3);
+typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1);
+
+#define glGetVideoi64vNV GLEW_GET_FUN(__glewGetVideoi64vNV)
+#define glGetVideoivNV GLEW_GET_FUN(__glewGetVideoivNV)
+#define glGetVideoui64vNV GLEW_GET_FUN(__glewGetVideoui64vNV)
+#define glGetVideouivNV GLEW_GET_FUN(__glewGetVideouivNV)
+#define glPresentFrameDualFillNV GLEW_GET_FUN(__glewPresentFrameDualFillNV)
+#define glPresentFrameKeyedNV GLEW_GET_FUN(__glewPresentFrameKeyedNV)
+
+#define GLEW_NV_present_video GLEW_GET_VAR(__GLEW_NV_present_video)
+
+#endif /* GL_NV_present_video */
+
+/* ------------------------ GL_NV_primitive_restart ------------------------ */
+
+#ifndef GL_NV_primitive_restart
+#define GL_NV_primitive_restart 1
+
+#define GL_PRIMITIVE_RESTART_NV 0x8558
+#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559
+
+typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index);
+typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTNVPROC) (void);
+
+#define glPrimitiveRestartIndexNV GLEW_GET_FUN(__glewPrimitiveRestartIndexNV)
+#define glPrimitiveRestartNV GLEW_GET_FUN(__glewPrimitiveRestartNV)
+
+#define GLEW_NV_primitive_restart GLEW_GET_VAR(__GLEW_NV_primitive_restart)
+
+#endif /* GL_NV_primitive_restart */
+
+/* ------------------------ GL_NV_register_combiners ----------------------- */
+
+#ifndef GL_NV_register_combiners
+#define GL_NV_register_combiners 1
+
+#define GL_REGISTER_COMBINERS_NV 0x8522
+#define GL_VARIABLE_A_NV 0x8523
+#define GL_VARIABLE_B_NV 0x8524
+#define GL_VARIABLE_C_NV 0x8525
+#define GL_VARIABLE_D_NV 0x8526
+#define GL_VARIABLE_E_NV 0x8527
+#define GL_VARIABLE_F_NV 0x8528
+#define GL_VARIABLE_G_NV 0x8529
+#define GL_CONSTANT_COLOR0_NV 0x852A
+#define GL_CONSTANT_COLOR1_NV 0x852B
+#define GL_PRIMARY_COLOR_NV 0x852C
+#define GL_SECONDARY_COLOR_NV 0x852D
+#define GL_SPARE0_NV 0x852E
+#define GL_SPARE1_NV 0x852F
+#define GL_DISCARD_NV 0x8530
+#define GL_E_TIMES_F_NV 0x8531
+#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532
+#define GL_UNSIGNED_IDENTITY_NV 0x8536
+#define GL_UNSIGNED_INVERT_NV 0x8537
+#define GL_EXPAND_NORMAL_NV 0x8538
+#define GL_EXPAND_NEGATE_NV 0x8539
+#define GL_HALF_BIAS_NORMAL_NV 0x853A
+#define GL_HALF_BIAS_NEGATE_NV 0x853B
+#define GL_SIGNED_IDENTITY_NV 0x853C
+#define GL_SIGNED_NEGATE_NV 0x853D
+#define GL_SCALE_BY_TWO_NV 0x853E
+#define GL_SCALE_BY_FOUR_NV 0x853F
+#define GL_SCALE_BY_ONE_HALF_NV 0x8540
+#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541
+#define GL_COMBINER_INPUT_NV 0x8542
+#define GL_COMBINER_MAPPING_NV 0x8543
+#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544
+#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545
+#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546
+#define GL_COMBINER_MUX_SUM_NV 0x8547
+#define GL_COMBINER_SCALE_NV 0x8548
+#define GL_COMBINER_BIAS_NV 0x8549
+#define GL_COMBINER_AB_OUTPUT_NV 0x854A
+#define GL_COMBINER_CD_OUTPUT_NV 0x854B
+#define GL_COMBINER_SUM_OUTPUT_NV 0x854C
+#define GL_MAX_GENERAL_COMBINERS_NV 0x854D
+#define GL_NUM_GENERAL_COMBINERS_NV 0x854E
+#define GL_COLOR_SUM_CLAMP_NV 0x854F
+#define GL_COMBINER0_NV 0x8550
+#define GL_COMBINER1_NV 0x8551
+#define GL_COMBINER2_NV 0x8552
+#define GL_COMBINER3_NV 0x8553
+#define GL_COMBINER4_NV 0x8554
+#define GL_COMBINER5_NV 0x8555
+#define GL_COMBINER6_NV 0x8556
+#define GL_COMBINER7_NV 0x8557
+
+typedef void (GLAPIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (GLAPIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum);
+typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint* params);
+
+#define glCombinerInputNV GLEW_GET_FUN(__glewCombinerInputNV)
+#define glCombinerOutputNV GLEW_GET_FUN(__glewCombinerOutputNV)
+#define glCombinerParameterfNV GLEW_GET_FUN(__glewCombinerParameterfNV)
+#define glCombinerParameterfvNV GLEW_GET_FUN(__glewCombinerParameterfvNV)
+#define glCombinerParameteriNV GLEW_GET_FUN(__glewCombinerParameteriNV)
+#define glCombinerParameterivNV GLEW_GET_FUN(__glewCombinerParameterivNV)
+#define glFinalCombinerInputNV GLEW_GET_FUN(__glewFinalCombinerInputNV)
+#define glGetCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetCombinerInputParameterfvNV)
+#define glGetCombinerInputParameterivNV GLEW_GET_FUN(__glewGetCombinerInputParameterivNV)
+#define glGetCombinerOutputParameterfvNV GLEW_GET_FUN(__glewGetCombinerOutputParameterfvNV)
+#define glGetCombinerOutputParameterivNV GLEW_GET_FUN(__glewGetCombinerOutputParameterivNV)
+#define glGetFinalCombinerInputParameterfvNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterfvNV)
+#define glGetFinalCombinerInputParameterivNV GLEW_GET_FUN(__glewGetFinalCombinerInputParameterivNV)
+
+#define GLEW_NV_register_combiners GLEW_GET_VAR(__GLEW_NV_register_combiners)
+
+#endif /* GL_NV_register_combiners */
+
+/* ----------------------- GL_NV_register_combiners2 ----------------------- */
+
+#ifndef GL_NV_register_combiners2
+#define GL_NV_register_combiners2 1
+
+#define GL_PER_STAGE_CONSTANTS_NV 0x8535
+
+typedef void (GLAPIENTRY * PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat* params);
+
+#define glCombinerStageParameterfvNV GLEW_GET_FUN(__glewCombinerStageParameterfvNV)
+#define glGetCombinerStageParameterfvNV GLEW_GET_FUN(__glewGetCombinerStageParameterfvNV)
+
+#define GLEW_NV_register_combiners2 GLEW_GET_VAR(__GLEW_NV_register_combiners2)
+
+#endif /* GL_NV_register_combiners2 */
+
+/* ---------------------- GL_NV_shader_atomic_counters --------------------- */
+
+#ifndef GL_NV_shader_atomic_counters
+#define GL_NV_shader_atomic_counters 1
+
+#define GLEW_NV_shader_atomic_counters GLEW_GET_VAR(__GLEW_NV_shader_atomic_counters)
+
+#endif /* GL_NV_shader_atomic_counters */
+
+/* ----------------------- GL_NV_shader_atomic_float ----------------------- */
+
+#ifndef GL_NV_shader_atomic_float
+#define GL_NV_shader_atomic_float 1
+
+#define GLEW_NV_shader_atomic_float GLEW_GET_VAR(__GLEW_NV_shader_atomic_float)
+
+#endif /* GL_NV_shader_atomic_float */
+
+/* ------------------------ GL_NV_shader_buffer_load ----------------------- */
+
+#ifndef GL_NV_shader_buffer_load
+#define GL_NV_shader_buffer_load 1
+
+#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D
+#define GL_GPU_ADDRESS_NV 0x8F34
+#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35
+
+typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT* result);
+typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERRESIDENTNVPROC) (GLenum target);
+typedef GLboolean (GLAPIENTRY * PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target);
+typedef void (GLAPIENTRY * PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access);
+typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value);
+typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT* value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value);
+typedef void (GLAPIENTRY * PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT* value);
+
+#define glGetBufferParameterui64vNV GLEW_GET_FUN(__glewGetBufferParameterui64vNV)
+#define glGetIntegerui64vNV GLEW_GET_FUN(__glewGetIntegerui64vNV)
+#define glGetNamedBufferParameterui64vNV GLEW_GET_FUN(__glewGetNamedBufferParameterui64vNV)
+#define glIsBufferResidentNV GLEW_GET_FUN(__glewIsBufferResidentNV)
+#define glIsNamedBufferResidentNV GLEW_GET_FUN(__glewIsNamedBufferResidentNV)
+#define glMakeBufferNonResidentNV GLEW_GET_FUN(__glewMakeBufferNonResidentNV)
+#define glMakeBufferResidentNV GLEW_GET_FUN(__glewMakeBufferResidentNV)
+#define glMakeNamedBufferNonResidentNV GLEW_GET_FUN(__glewMakeNamedBufferNonResidentNV)
+#define glMakeNamedBufferResidentNV GLEW_GET_FUN(__glewMakeNamedBufferResidentNV)
+#define glProgramUniformui64NV GLEW_GET_FUN(__glewProgramUniformui64NV)
+#define glProgramUniformui64vNV GLEW_GET_FUN(__glewProgramUniformui64vNV)
+#define glUniformui64NV GLEW_GET_FUN(__glewUniformui64NV)
+#define glUniformui64vNV GLEW_GET_FUN(__glewUniformui64vNV)
+
+#define GLEW_NV_shader_buffer_load GLEW_GET_VAR(__GLEW_NV_shader_buffer_load)
+
+#endif /* GL_NV_shader_buffer_load */
+
+/* ------------------- GL_NV_shader_storage_buffer_object ------------------ */
+
+#ifndef GL_NV_shader_storage_buffer_object
+#define GL_NV_shader_storage_buffer_object 1
+
+#define GLEW_NV_shader_storage_buffer_object GLEW_GET_VAR(__GLEW_NV_shader_storage_buffer_object)
+
+#endif /* GL_NV_shader_storage_buffer_object */
+
+/* ---------------------- GL_NV_tessellation_program5 ---------------------- */
+
+#ifndef GL_NV_tessellation_program5
+#define GL_NV_tessellation_program5 1
+
+#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8
+#define GL_TESS_CONTROL_PROGRAM_NV 0x891E
+#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F
+#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74
+#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75
+
+#define GLEW_NV_tessellation_program5 GLEW_GET_VAR(__GLEW_NV_tessellation_program5)
+
+#endif /* GL_NV_tessellation_program5 */
+
+/* -------------------------- GL_NV_texgen_emboss -------------------------- */
+
+#ifndef GL_NV_texgen_emboss
+#define GL_NV_texgen_emboss 1
+
+#define GL_EMBOSS_LIGHT_NV 0x855D
+#define GL_EMBOSS_CONSTANT_NV 0x855E
+#define GL_EMBOSS_MAP_NV 0x855F
+
+#define GLEW_NV_texgen_emboss GLEW_GET_VAR(__GLEW_NV_texgen_emboss)
+
+#endif /* GL_NV_texgen_emboss */
+
+/* ------------------------ GL_NV_texgen_reflection ------------------------ */
+
+#ifndef GL_NV_texgen_reflection
+#define GL_NV_texgen_reflection 1
+
+#define GL_NORMAL_MAP_NV 0x8511
+#define GL_REFLECTION_MAP_NV 0x8512
+
+#define GLEW_NV_texgen_reflection GLEW_GET_VAR(__GLEW_NV_texgen_reflection)
+
+#endif /* GL_NV_texgen_reflection */
+
+/* ------------------------- GL_NV_texture_barrier ------------------------- */
+
+#ifndef GL_NV_texture_barrier
+#define GL_NV_texture_barrier 1
+
+typedef void (GLAPIENTRY * PFNGLTEXTUREBARRIERNVPROC) (void);
+
+#define glTextureBarrierNV GLEW_GET_FUN(__glewTextureBarrierNV)
+
+#define GLEW_NV_texture_barrier GLEW_GET_VAR(__GLEW_NV_texture_barrier)
+
+#endif /* GL_NV_texture_barrier */
+
+/* --------------------- GL_NV_texture_compression_vtc --------------------- */
+
+#ifndef GL_NV_texture_compression_vtc
+#define GL_NV_texture_compression_vtc 1
+
+#define GLEW_NV_texture_compression_vtc GLEW_GET_VAR(__GLEW_NV_texture_compression_vtc)
+
+#endif /* GL_NV_texture_compression_vtc */
+
+/* ----------------------- GL_NV_texture_env_combine4 ---------------------- */
+
+#ifndef GL_NV_texture_env_combine4
+#define GL_NV_texture_env_combine4 1
+
+#define GL_COMBINE4_NV 0x8503
+#define GL_SOURCE3_RGB_NV 0x8583
+#define GL_SOURCE3_ALPHA_NV 0x858B
+#define GL_OPERAND3_RGB_NV 0x8593
+#define GL_OPERAND3_ALPHA_NV 0x859B
+
+#define GLEW_NV_texture_env_combine4 GLEW_GET_VAR(__GLEW_NV_texture_env_combine4)
+
+#endif /* GL_NV_texture_env_combine4 */
+
+/* ---------------------- GL_NV_texture_expand_normal ---------------------- */
+
+#ifndef GL_NV_texture_expand_normal
+#define GL_NV_texture_expand_normal 1
+
+#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F
+
+#define GLEW_NV_texture_expand_normal GLEW_GET_VAR(__GLEW_NV_texture_expand_normal)
+
+#endif /* GL_NV_texture_expand_normal */
+
+/* ----------------------- GL_NV_texture_multisample ----------------------- */
+
+#ifndef GL_NV_texture_multisample
+#define GL_NV_texture_multisample 1
+
+#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045
+#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046
+
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+
+#define glTexImage2DMultisampleCoverageNV GLEW_GET_FUN(__glewTexImage2DMultisampleCoverageNV)
+#define glTexImage3DMultisampleCoverageNV GLEW_GET_FUN(__glewTexImage3DMultisampleCoverageNV)
+#define glTextureImage2DMultisampleCoverageNV GLEW_GET_FUN(__glewTextureImage2DMultisampleCoverageNV)
+#define glTextureImage2DMultisampleNV GLEW_GET_FUN(__glewTextureImage2DMultisampleNV)
+#define glTextureImage3DMultisampleCoverageNV GLEW_GET_FUN(__glewTextureImage3DMultisampleCoverageNV)
+#define glTextureImage3DMultisampleNV GLEW_GET_FUN(__glewTextureImage3DMultisampleNV)
+
+#define GLEW_NV_texture_multisample GLEW_GET_VAR(__GLEW_NV_texture_multisample)
+
+#endif /* GL_NV_texture_multisample */
+
+/* ------------------------ GL_NV_texture_rectangle ------------------------ */
+
+#ifndef GL_NV_texture_rectangle
+#define GL_NV_texture_rectangle 1
+
+#define GL_TEXTURE_RECTANGLE_NV 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8
+
+#define GLEW_NV_texture_rectangle GLEW_GET_VAR(__GLEW_NV_texture_rectangle)
+
+#endif /* GL_NV_texture_rectangle */
+
+/* -------------------------- GL_NV_texture_shader ------------------------- */
+
+#ifndef GL_NV_texture_shader
+#define GL_NV_texture_shader 1
+
+#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C
+#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D
+#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E
+#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9
+#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA
+#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB
+#define GL_DSDT_MAG_INTENSITY_NV 0x86DC
+#define GL_SHADER_CONSISTENT_NV 0x86DD
+#define GL_TEXTURE_SHADER_NV 0x86DE
+#define GL_SHADER_OPERATION_NV 0x86DF
+#define GL_CULL_MODES_NV 0x86E0
+#define GL_OFFSET_TEXTURE_2D_MATRIX_NV 0x86E1
+#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1
+#define GL_OFFSET_TEXTURE_2D_SCALE_NV 0x86E2
+#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2
+#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3
+#define GL_OFFSET_TEXTURE_2D_BIAS_NV 0x86E3
+#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4
+#define GL_CONST_EYE_NV 0x86E5
+#define GL_PASS_THROUGH_NV 0x86E6
+#define GL_CULL_FRAGMENT_NV 0x86E7
+#define GL_OFFSET_TEXTURE_2D_NV 0x86E8
+#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9
+#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA
+#define GL_DOT_PRODUCT_NV 0x86EC
+#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED
+#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE
+#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0
+#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1
+#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2
+#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3
+#define GL_HILO_NV 0x86F4
+#define GL_DSDT_NV 0x86F5
+#define GL_DSDT_MAG_NV 0x86F6
+#define GL_DSDT_MAG_VIB_NV 0x86F7
+#define GL_HILO16_NV 0x86F8
+#define GL_SIGNED_HILO_NV 0x86F9
+#define GL_SIGNED_HILO16_NV 0x86FA
+#define GL_SIGNED_RGBA_NV 0x86FB
+#define GL_SIGNED_RGBA8_NV 0x86FC
+#define GL_SIGNED_RGB_NV 0x86FE
+#define GL_SIGNED_RGB8_NV 0x86FF
+#define GL_SIGNED_LUMINANCE_NV 0x8701
+#define GL_SIGNED_LUMINANCE8_NV 0x8702
+#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703
+#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704
+#define GL_SIGNED_ALPHA_NV 0x8705
+#define GL_SIGNED_ALPHA8_NV 0x8706
+#define GL_SIGNED_INTENSITY_NV 0x8707
+#define GL_SIGNED_INTENSITY8_NV 0x8708
+#define GL_DSDT8_NV 0x8709
+#define GL_DSDT8_MAG8_NV 0x870A
+#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B
+#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C
+#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D
+#define GL_HI_SCALE_NV 0x870E
+#define GL_LO_SCALE_NV 0x870F
+#define GL_DS_SCALE_NV 0x8710
+#define GL_DT_SCALE_NV 0x8711
+#define GL_MAGNITUDE_SCALE_NV 0x8712
+#define GL_VIBRANCE_SCALE_NV 0x8713
+#define GL_HI_BIAS_NV 0x8714
+#define GL_LO_BIAS_NV 0x8715
+#define GL_DS_BIAS_NV 0x8716
+#define GL_DT_BIAS_NV 0x8717
+#define GL_MAGNITUDE_BIAS_NV 0x8718
+#define GL_VIBRANCE_BIAS_NV 0x8719
+#define GL_TEXTURE_BORDER_VALUES_NV 0x871A
+#define GL_TEXTURE_HI_SIZE_NV 0x871B
+#define GL_TEXTURE_LO_SIZE_NV 0x871C
+#define GL_TEXTURE_DS_SIZE_NV 0x871D
+#define GL_TEXTURE_DT_SIZE_NV 0x871E
+#define GL_TEXTURE_MAG_SIZE_NV 0x871F
+
+#define GLEW_NV_texture_shader GLEW_GET_VAR(__GLEW_NV_texture_shader)
+
+#endif /* GL_NV_texture_shader */
+
+/* ------------------------- GL_NV_texture_shader2 ------------------------- */
+
+#ifndef GL_NV_texture_shader2
+#define GL_NV_texture_shader2 1
+
+#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA
+#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB
+#define GL_DSDT_MAG_INTENSITY_NV 0x86DC
+#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF
+#define GL_HILO_NV 0x86F4
+#define GL_DSDT_NV 0x86F5
+#define GL_DSDT_MAG_NV 0x86F6
+#define GL_DSDT_MAG_VIB_NV 0x86F7
+#define GL_HILO16_NV 0x86F8
+#define GL_SIGNED_HILO_NV 0x86F9
+#define GL_SIGNED_HILO16_NV 0x86FA
+#define GL_SIGNED_RGBA_NV 0x86FB
+#define GL_SIGNED_RGBA8_NV 0x86FC
+#define GL_SIGNED_RGB_NV 0x86FE
+#define GL_SIGNED_RGB8_NV 0x86FF
+#define GL_SIGNED_LUMINANCE_NV 0x8701
+#define GL_SIGNED_LUMINANCE8_NV 0x8702
+#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703
+#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704
+#define GL_SIGNED_ALPHA_NV 0x8705
+#define GL_SIGNED_ALPHA8_NV 0x8706
+#define GL_SIGNED_INTENSITY_NV 0x8707
+#define GL_SIGNED_INTENSITY8_NV 0x8708
+#define GL_DSDT8_NV 0x8709
+#define GL_DSDT8_MAG8_NV 0x870A
+#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B
+#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C
+#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D
+
+#define GLEW_NV_texture_shader2 GLEW_GET_VAR(__GLEW_NV_texture_shader2)
+
+#endif /* GL_NV_texture_shader2 */
+
+/* ------------------------- GL_NV_texture_shader3 ------------------------- */
+
+#ifndef GL_NV_texture_shader3
+#define GL_NV_texture_shader3 1
+
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853
+#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854
+#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857
+#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858
+#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859
+#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A
+#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B
+#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C
+#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D
+#define GL_HILO8_NV 0x885E
+#define GL_SIGNED_HILO8_NV 0x885F
+#define GL_FORCE_BLUE_TO_ONE_NV 0x8860
+
+#define GLEW_NV_texture_shader3 GLEW_GET_VAR(__GLEW_NV_texture_shader3)
+
+#endif /* GL_NV_texture_shader3 */
+
+/* ------------------------ GL_NV_transform_feedback ----------------------- */
+
+#ifndef GL_NV_transform_feedback
+#define GL_NV_transform_feedback 1
+
+#define GL_BACK_PRIMARY_COLOR_NV 0x8C77
+#define GL_BACK_SECONDARY_COLOR_NV 0x8C78
+#define GL_TEXTURE_COORD_NV 0x8C79
+#define GL_CLIP_DISTANCE_NV 0x8C7A
+#define GL_VERTEX_ID_NV 0x8C7B
+#define GL_PRIMITIVE_ID_NV 0x8C7C
+#define GL_GENERIC_ATTRIB_NV 0x8C7D
+#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80
+#define GL_ACTIVE_VARYINGS_NV 0x8C81
+#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85
+#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86
+#define GL_PRIMITIVES_GENERATED_NV 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88
+#define GL_RASTERIZER_DISCARD_NV 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C
+#define GL_SEPARATE_ATTRIBS_NV 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F
+
+typedef void (GLAPIENTRY * PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name);
+typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKNVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location);
+typedef GLint (GLAPIENTRY * PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name);
+typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode);
+typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode);
+
+#define glActiveVaryingNV GLEW_GET_FUN(__glewActiveVaryingNV)
+#define glBeginTransformFeedbackNV GLEW_GET_FUN(__glewBeginTransformFeedbackNV)
+#define glBindBufferBaseNV GLEW_GET_FUN(__glewBindBufferBaseNV)
+#define glBindBufferOffsetNV GLEW_GET_FUN(__glewBindBufferOffsetNV)
+#define glBindBufferRangeNV GLEW_GET_FUN(__glewBindBufferRangeNV)
+#define glEndTransformFeedbackNV GLEW_GET_FUN(__glewEndTransformFeedbackNV)
+#define glGetActiveVaryingNV GLEW_GET_FUN(__glewGetActiveVaryingNV)
+#define glGetTransformFeedbackVaryingNV GLEW_GET_FUN(__glewGetTransformFeedbackVaryingNV)
+#define glGetVaryingLocationNV GLEW_GET_FUN(__glewGetVaryingLocationNV)
+#define glTransformFeedbackAttribsNV GLEW_GET_FUN(__glewTransformFeedbackAttribsNV)
+#define glTransformFeedbackVaryingsNV GLEW_GET_FUN(__glewTransformFeedbackVaryingsNV)
+
+#define GLEW_NV_transform_feedback GLEW_GET_VAR(__GLEW_NV_transform_feedback)
+
+#endif /* GL_NV_transform_feedback */
+
+/* ----------------------- GL_NV_transform_feedback2 ----------------------- */
+
+#ifndef GL_NV_transform_feedback2
+#define GL_NV_transform_feedback2 1
+
+#define GL_TRANSFORM_FEEDBACK_NV 0x8E22
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25
+
+typedef void (GLAPIENTRY * PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id);
+typedef void (GLAPIENTRY * PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint* ids);
+typedef GLboolean (GLAPIENTRY * PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void);
+
+#define glBindTransformFeedbackNV GLEW_GET_FUN(__glewBindTransformFeedbackNV)
+#define glDeleteTransformFeedbacksNV GLEW_GET_FUN(__glewDeleteTransformFeedbacksNV)
+#define glDrawTransformFeedbackNV GLEW_GET_FUN(__glewDrawTransformFeedbackNV)
+#define glGenTransformFeedbacksNV GLEW_GET_FUN(__glewGenTransformFeedbacksNV)
+#define glIsTransformFeedbackNV GLEW_GET_FUN(__glewIsTransformFeedbackNV)
+#define glPauseTransformFeedbackNV GLEW_GET_FUN(__glewPauseTransformFeedbackNV)
+#define glResumeTransformFeedbackNV GLEW_GET_FUN(__glewResumeTransformFeedbackNV)
+
+#define GLEW_NV_transform_feedback2 GLEW_GET_VAR(__GLEW_NV_transform_feedback2)
+
+#endif /* GL_NV_transform_feedback2 */
+
+/* -------------------------- GL_NV_vdpau_interop -------------------------- */
+
+#ifndef GL_NV_vdpau_interop
+#define GL_NV_vdpau_interop 1
+
+#define GL_SURFACE_STATE_NV 0x86EB
+#define GL_SURFACE_REGISTERED_NV 0x86FD
+#define GL_SURFACE_MAPPED_NV 0x8700
+#define GL_WRITE_DISCARD_NV 0x88BE
+
+typedef GLintptr GLvdpauSurfaceNV;
+
+typedef void (GLAPIENTRY * PFNGLVDPAUFININVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei* length, GLint *values);
+typedef void (GLAPIENTRY * PFNGLVDPAUINITNVPROC) (const void* vdpDevice, const GLvoid*getProcAddress);
+typedef void (GLAPIENTRY * PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface);
+typedef void (GLAPIENTRY * PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV* surfaces);
+typedef GLvdpauSurfaceNV (GLAPIENTRY * PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (const void* vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+typedef GLvdpauSurfaceNV (GLAPIENTRY * PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (const void* vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+typedef void (GLAPIENTRY * PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access);
+typedef void (GLAPIENTRY * PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV* surfaces);
+typedef void (GLAPIENTRY * PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface);
+
+#define glVDPAUFiniNV GLEW_GET_FUN(__glewVDPAUFiniNV)
+#define glVDPAUGetSurfaceivNV GLEW_GET_FUN(__glewVDPAUGetSurfaceivNV)
+#define glVDPAUInitNV GLEW_GET_FUN(__glewVDPAUInitNV)
+#define glVDPAUIsSurfaceNV GLEW_GET_FUN(__glewVDPAUIsSurfaceNV)
+#define glVDPAUMapSurfacesNV GLEW_GET_FUN(__glewVDPAUMapSurfacesNV)
+#define glVDPAURegisterOutputSurfaceNV GLEW_GET_FUN(__glewVDPAURegisterOutputSurfaceNV)
+#define glVDPAURegisterVideoSurfaceNV GLEW_GET_FUN(__glewVDPAURegisterVideoSurfaceNV)
+#define glVDPAUSurfaceAccessNV GLEW_GET_FUN(__glewVDPAUSurfaceAccessNV)
+#define glVDPAUUnmapSurfacesNV GLEW_GET_FUN(__glewVDPAUUnmapSurfacesNV)
+#define glVDPAUUnregisterSurfaceNV GLEW_GET_FUN(__glewVDPAUUnregisterSurfaceNV)
+
+#define GLEW_NV_vdpau_interop GLEW_GET_VAR(__GLEW_NV_vdpau_interop)
+
+#endif /* GL_NV_vdpau_interop */
+
+/* ------------------------ GL_NV_vertex_array_range ----------------------- */
+
+#ifndef GL_NV_vertex_array_range
+#define GL_NV_vertex_array_range 1
+
+#define GL_VERTEX_ARRAY_RANGE_NV 0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E
+#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F
+#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520
+#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521
+
+typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void);
+typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, GLvoid *pointer);
+
+#define glFlushVertexArrayRangeNV GLEW_GET_FUN(__glewFlushVertexArrayRangeNV)
+#define glVertexArrayRangeNV GLEW_GET_FUN(__glewVertexArrayRangeNV)
+
+#define GLEW_NV_vertex_array_range GLEW_GET_VAR(__GLEW_NV_vertex_array_range)
+
+#endif /* GL_NV_vertex_array_range */
+
+/* ----------------------- GL_NV_vertex_array_range2 ----------------------- */
+
+#ifndef GL_NV_vertex_array_range2
+#define GL_NV_vertex_array_range2 1
+
+#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533
+
+#define GLEW_NV_vertex_array_range2 GLEW_GET_VAR(__GLEW_NV_vertex_array_range2)
+
+#endif /* GL_NV_vertex_array_range2 */
+
+/* ------------------- GL_NV_vertex_attrib_integer_64bit ------------------- */
+
+#ifndef GL_NV_vertex_attrib_integer_64bit
+#define GL_NV_vertex_attrib_integer_64bit 1
+
+#define GL_INT64_NV 0x140E
+#define GL_UNSIGNED_INT64_NV 0x140F
+
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT* params);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);
+
+#define glGetVertexAttribLi64vNV GLEW_GET_FUN(__glewGetVertexAttribLi64vNV)
+#define glGetVertexAttribLui64vNV GLEW_GET_FUN(__glewGetVertexAttribLui64vNV)
+#define glVertexAttribL1i64NV GLEW_GET_FUN(__glewVertexAttribL1i64NV)
+#define glVertexAttribL1i64vNV GLEW_GET_FUN(__glewVertexAttribL1i64vNV)
+#define glVertexAttribL1ui64NV GLEW_GET_FUN(__glewVertexAttribL1ui64NV)
+#define glVertexAttribL1ui64vNV GLEW_GET_FUN(__glewVertexAttribL1ui64vNV)
+#define glVertexAttribL2i64NV GLEW_GET_FUN(__glewVertexAttribL2i64NV)
+#define glVertexAttribL2i64vNV GLEW_GET_FUN(__glewVertexAttribL2i64vNV)
+#define glVertexAttribL2ui64NV GLEW_GET_FUN(__glewVertexAttribL2ui64NV)
+#define glVertexAttribL2ui64vNV GLEW_GET_FUN(__glewVertexAttribL2ui64vNV)
+#define glVertexAttribL3i64NV GLEW_GET_FUN(__glewVertexAttribL3i64NV)
+#define glVertexAttribL3i64vNV GLEW_GET_FUN(__glewVertexAttribL3i64vNV)
+#define glVertexAttribL3ui64NV GLEW_GET_FUN(__glewVertexAttribL3ui64NV)
+#define glVertexAttribL3ui64vNV GLEW_GET_FUN(__glewVertexAttribL3ui64vNV)
+#define glVertexAttribL4i64NV GLEW_GET_FUN(__glewVertexAttribL4i64NV)
+#define glVertexAttribL4i64vNV GLEW_GET_FUN(__glewVertexAttribL4i64vNV)
+#define glVertexAttribL4ui64NV GLEW_GET_FUN(__glewVertexAttribL4ui64NV)
+#define glVertexAttribL4ui64vNV GLEW_GET_FUN(__glewVertexAttribL4ui64vNV)
+#define glVertexAttribLFormatNV GLEW_GET_FUN(__glewVertexAttribLFormatNV)
+
+#define GLEW_NV_vertex_attrib_integer_64bit GLEW_GET_VAR(__GLEW_NV_vertex_attrib_integer_64bit)
+
+#endif /* GL_NV_vertex_attrib_integer_64bit */
+
+/* ------------------- GL_NV_vertex_buffer_unified_memory ------------------ */
+
+#ifndef GL_NV_vertex_buffer_unified_memory
+#define GL_NV_vertex_buffer_unified_memory 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E
+#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F
+#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20
+#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21
+#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22
+#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23
+#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24
+#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25
+#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26
+#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27
+#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28
+#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29
+#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A
+#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B
+#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C
+#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D
+#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E
+#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F
+#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30
+#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31
+#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32
+#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33
+#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40
+#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41
+#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42
+
+typedef void (GLAPIENTRY * PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length);
+typedef void (GLAPIENTRY * PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT result[]);
+typedef void (GLAPIENTRY * PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);
+typedef void (GLAPIENTRY * PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+
+#define glBufferAddressRangeNV GLEW_GET_FUN(__glewBufferAddressRangeNV)
+#define glColorFormatNV GLEW_GET_FUN(__glewColorFormatNV)
+#define glEdgeFlagFormatNV GLEW_GET_FUN(__glewEdgeFlagFormatNV)
+#define glFogCoordFormatNV GLEW_GET_FUN(__glewFogCoordFormatNV)
+#define glGetIntegerui64i_vNV GLEW_GET_FUN(__glewGetIntegerui64i_vNV)
+#define glIndexFormatNV GLEW_GET_FUN(__glewIndexFormatNV)
+#define glNormalFormatNV GLEW_GET_FUN(__glewNormalFormatNV)
+#define glSecondaryColorFormatNV GLEW_GET_FUN(__glewSecondaryColorFormatNV)
+#define glTexCoordFormatNV GLEW_GET_FUN(__glewTexCoordFormatNV)
+#define glVertexAttribFormatNV GLEW_GET_FUN(__glewVertexAttribFormatNV)
+#define glVertexAttribIFormatNV GLEW_GET_FUN(__glewVertexAttribIFormatNV)
+#define glVertexFormatNV GLEW_GET_FUN(__glewVertexFormatNV)
+
+#define GLEW_NV_vertex_buffer_unified_memory GLEW_GET_VAR(__GLEW_NV_vertex_buffer_unified_memory)
+
+#endif /* GL_NV_vertex_buffer_unified_memory */
+
+/* -------------------------- GL_NV_vertex_program ------------------------- */
+
+#ifndef GL_NV_vertex_program
+#define GL_NV_vertex_program 1
+
+#define GL_VERTEX_PROGRAM_NV 0x8620
+#define GL_VERTEX_STATE_PROGRAM_NV 0x8621
+#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623
+#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624
+#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625
+#define GL_CURRENT_ATTRIB_NV 0x8626
+#define GL_PROGRAM_LENGTH_NV 0x8627
+#define GL_PROGRAM_STRING_NV 0x8628
+#define GL_MODELVIEW_PROJECTION_NV 0x8629
+#define GL_IDENTITY_NV 0x862A
+#define GL_INVERSE_NV 0x862B
+#define GL_TRANSPOSE_NV 0x862C
+#define GL_INVERSE_TRANSPOSE_NV 0x862D
+#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E
+#define GL_MAX_TRACK_MATRICES_NV 0x862F
+#define GL_MATRIX0_NV 0x8630
+#define GL_MATRIX1_NV 0x8631
+#define GL_MATRIX2_NV 0x8632
+#define GL_MATRIX3_NV 0x8633
+#define GL_MATRIX4_NV 0x8634
+#define GL_MATRIX5_NV 0x8635
+#define GL_MATRIX6_NV 0x8636
+#define GL_MATRIX7_NV 0x8637
+#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640
+#define GL_CURRENT_MATRIX_NV 0x8641
+#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643
+#define GL_PROGRAM_PARAMETER_NV 0x8644
+#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645
+#define GL_PROGRAM_TARGET_NV 0x8646
+#define GL_PROGRAM_RESIDENT_NV 0x8647
+#define GL_TRACK_MATRIX_NV 0x8648
+#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649
+#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A
+#define GL_PROGRAM_ERROR_POSITION_NV 0x864B
+#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650
+#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651
+#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652
+#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653
+#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654
+#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655
+#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656
+#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657
+#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658
+#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659
+#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A
+#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B
+#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C
+#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D
+#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E
+#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F
+#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660
+#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661
+#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662
+#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663
+#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664
+#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665
+#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666
+#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667
+#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668
+#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669
+#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A
+#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B
+#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C
+#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D
+#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E
+#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F
+#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670
+#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671
+#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672
+#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673
+#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674
+#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675
+#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676
+#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677
+#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678
+#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679
+#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A
+#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B
+#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C
+#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D
+#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E
+#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F
+
+typedef GLboolean (GLAPIENTRY * PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint* ids, GLboolean *residences);
+typedef void (GLAPIENTRY * PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id);
+typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte* program);
+typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid** pointer);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint* params);
+typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMNVPROC) (GLuint id);
+typedef void (GLAPIENTRY * PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte* program);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei num, const GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei num, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, GLuint* ids);
+typedef void (GLAPIENTRY * PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei n, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei n, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei n, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei n, const GLdouble* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei n, const GLfloat* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei n, const GLshort* v);
+typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei n, const GLubyte* v);
+
+#define glAreProgramsResidentNV GLEW_GET_FUN(__glewAreProgramsResidentNV)
+#define glBindProgramNV GLEW_GET_FUN(__glewBindProgramNV)
+#define glDeleteProgramsNV GLEW_GET_FUN(__glewDeleteProgramsNV)
+#define glExecuteProgramNV GLEW_GET_FUN(__glewExecuteProgramNV)
+#define glGenProgramsNV GLEW_GET_FUN(__glewGenProgramsNV)
+#define glGetProgramParameterdvNV GLEW_GET_FUN(__glewGetProgramParameterdvNV)
+#define glGetProgramParameterfvNV GLEW_GET_FUN(__glewGetProgramParameterfvNV)
+#define glGetProgramStringNV GLEW_GET_FUN(__glewGetProgramStringNV)
+#define glGetProgramivNV GLEW_GET_FUN(__glewGetProgramivNV)
+#define glGetTrackMatrixivNV GLEW_GET_FUN(__glewGetTrackMatrixivNV)
+#define glGetVertexAttribPointervNV GLEW_GET_FUN(__glewGetVertexAttribPointervNV)
+#define glGetVertexAttribdvNV GLEW_GET_FUN(__glewGetVertexAttribdvNV)
+#define glGetVertexAttribfvNV GLEW_GET_FUN(__glewGetVertexAttribfvNV)
+#define glGetVertexAttribivNV GLEW_GET_FUN(__glewGetVertexAttribivNV)
+#define glIsProgramNV GLEW_GET_FUN(__glewIsProgramNV)
+#define glLoadProgramNV GLEW_GET_FUN(__glewLoadProgramNV)
+#define glProgramParameter4dNV GLEW_GET_FUN(__glewProgramParameter4dNV)
+#define glProgramParameter4dvNV GLEW_GET_FUN(__glewProgramParameter4dvNV)
+#define glProgramParameter4fNV GLEW_GET_FUN(__glewProgramParameter4fNV)
+#define glProgramParameter4fvNV GLEW_GET_FUN(__glewProgramParameter4fvNV)
+#define glProgramParameters4dvNV GLEW_GET_FUN(__glewProgramParameters4dvNV)
+#define glProgramParameters4fvNV GLEW_GET_FUN(__glewProgramParameters4fvNV)
+#define glRequestResidentProgramsNV GLEW_GET_FUN(__glewRequestResidentProgramsNV)
+#define glTrackMatrixNV GLEW_GET_FUN(__glewTrackMatrixNV)
+#define glVertexAttrib1dNV GLEW_GET_FUN(__glewVertexAttrib1dNV)
+#define glVertexAttrib1dvNV GLEW_GET_FUN(__glewVertexAttrib1dvNV)
+#define glVertexAttrib1fNV GLEW_GET_FUN(__glewVertexAttrib1fNV)
+#define glVertexAttrib1fvNV GLEW_GET_FUN(__glewVertexAttrib1fvNV)
+#define glVertexAttrib1sNV GLEW_GET_FUN(__glewVertexAttrib1sNV)
+#define glVertexAttrib1svNV GLEW_GET_FUN(__glewVertexAttrib1svNV)
+#define glVertexAttrib2dNV GLEW_GET_FUN(__glewVertexAttrib2dNV)
+#define glVertexAttrib2dvNV GLEW_GET_FUN(__glewVertexAttrib2dvNV)
+#define glVertexAttrib2fNV GLEW_GET_FUN(__glewVertexAttrib2fNV)
+#define glVertexAttrib2fvNV GLEW_GET_FUN(__glewVertexAttrib2fvNV)
+#define glVertexAttrib2sNV GLEW_GET_FUN(__glewVertexAttrib2sNV)
+#define glVertexAttrib2svNV GLEW_GET_FUN(__glewVertexAttrib2svNV)
+#define glVertexAttrib3dNV GLEW_GET_FUN(__glewVertexAttrib3dNV)
+#define glVertexAttrib3dvNV GLEW_GET_FUN(__glewVertexAttrib3dvNV)
+#define glVertexAttrib3fNV GLEW_GET_FUN(__glewVertexAttrib3fNV)
+#define glVertexAttrib3fvNV GLEW_GET_FUN(__glewVertexAttrib3fvNV)
+#define glVertexAttrib3sNV GLEW_GET_FUN(__glewVertexAttrib3sNV)
+#define glVertexAttrib3svNV GLEW_GET_FUN(__glewVertexAttrib3svNV)
+#define glVertexAttrib4dNV GLEW_GET_FUN(__glewVertexAttrib4dNV)
+#define glVertexAttrib4dvNV GLEW_GET_FUN(__glewVertexAttrib4dvNV)
+#define glVertexAttrib4fNV GLEW_GET_FUN(__glewVertexAttrib4fNV)
+#define glVertexAttrib4fvNV GLEW_GET_FUN(__glewVertexAttrib4fvNV)
+#define glVertexAttrib4sNV GLEW_GET_FUN(__glewVertexAttrib4sNV)
+#define glVertexAttrib4svNV GLEW_GET_FUN(__glewVertexAttrib4svNV)
+#define glVertexAttrib4ubNV GLEW_GET_FUN(__glewVertexAttrib4ubNV)
+#define glVertexAttrib4ubvNV GLEW_GET_FUN(__glewVertexAttrib4ubvNV)
+#define glVertexAttribPointerNV GLEW_GET_FUN(__glewVertexAttribPointerNV)
+#define glVertexAttribs1dvNV GLEW_GET_FUN(__glewVertexAttribs1dvNV)
+#define glVertexAttribs1fvNV GLEW_GET_FUN(__glewVertexAttribs1fvNV)
+#define glVertexAttribs1svNV GLEW_GET_FUN(__glewVertexAttribs1svNV)
+#define glVertexAttribs2dvNV GLEW_GET_FUN(__glewVertexAttribs2dvNV)
+#define glVertexAttribs2fvNV GLEW_GET_FUN(__glewVertexAttribs2fvNV)
+#define glVertexAttribs2svNV GLEW_GET_FUN(__glewVertexAttribs2svNV)
+#define glVertexAttribs3dvNV GLEW_GET_FUN(__glewVertexAttribs3dvNV)
+#define glVertexAttribs3fvNV GLEW_GET_FUN(__glewVertexAttribs3fvNV)
+#define glVertexAttribs3svNV GLEW_GET_FUN(__glewVertexAttribs3svNV)
+#define glVertexAttribs4dvNV GLEW_GET_FUN(__glewVertexAttribs4dvNV)
+#define glVertexAttribs4fvNV GLEW_GET_FUN(__glewVertexAttribs4fvNV)
+#define glVertexAttribs4svNV GLEW_GET_FUN(__glewVertexAttribs4svNV)
+#define glVertexAttribs4ubvNV GLEW_GET_FUN(__glewVertexAttribs4ubvNV)
+
+#define GLEW_NV_vertex_program GLEW_GET_VAR(__GLEW_NV_vertex_program)
+
+#endif /* GL_NV_vertex_program */
+
+/* ------------------------ GL_NV_vertex_program1_1 ------------------------ */
+
+#ifndef GL_NV_vertex_program1_1
+#define GL_NV_vertex_program1_1 1
+
+#define GLEW_NV_vertex_program1_1 GLEW_GET_VAR(__GLEW_NV_vertex_program1_1)
+
+#endif /* GL_NV_vertex_program1_1 */
+
+/* ------------------------- GL_NV_vertex_program2 ------------------------- */
+
+#ifndef GL_NV_vertex_program2
+#define GL_NV_vertex_program2 1
+
+#define GLEW_NV_vertex_program2 GLEW_GET_VAR(__GLEW_NV_vertex_program2)
+
+#endif /* GL_NV_vertex_program2 */
+
+/* ---------------------- GL_NV_vertex_program2_option --------------------- */
+
+#ifndef GL_NV_vertex_program2_option
+#define GL_NV_vertex_program2_option 1
+
+#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4
+#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5
+
+#define GLEW_NV_vertex_program2_option GLEW_GET_VAR(__GLEW_NV_vertex_program2_option)
+
+#endif /* GL_NV_vertex_program2_option */
+
+/* ------------------------- GL_NV_vertex_program3 ------------------------- */
+
+#ifndef GL_NV_vertex_program3
+#define GL_NV_vertex_program3 1
+
+#define MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C
+
+#define GLEW_NV_vertex_program3 GLEW_GET_VAR(__GLEW_NV_vertex_program3)
+
+#endif /* GL_NV_vertex_program3 */
+
+/* ------------------------- GL_NV_vertex_program4 ------------------------- */
+
+#ifndef GL_NV_vertex_program4
+#define GL_NV_vertex_program4 1
+
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD
+
+#define GLEW_NV_vertex_program4 GLEW_GET_VAR(__GLEW_NV_vertex_program4)
+
+#endif /* GL_NV_vertex_program4 */
+
+/* -------------------------- GL_NV_video_capture -------------------------- */
+
+#ifndef GL_NV_video_capture
+#define GL_NV_video_capture 1
+
+#define GL_VIDEO_BUFFER_NV 0x9020
+#define GL_VIDEO_BUFFER_BINDING_NV 0x9021
+#define GL_FIELD_UPPER_NV 0x9022
+#define GL_FIELD_LOWER_NV 0x9023
+#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024
+#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025
+#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026
+#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027
+#define GL_VIDEO_BUFFER_PITCH_NV 0x9028
+#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029
+#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A
+#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B
+#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C
+#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D
+#define GL_PARTIAL_SUCCESS_NV 0x902E
+#define GL_SUCCESS_NV 0x902F
+#define GL_FAILURE_NV 0x9030
+#define GL_YCBYCR8_422_NV 0x9031
+#define GL_YCBAYCR8A_4224_NV 0x9032
+#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033
+#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034
+#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035
+#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036
+#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037
+#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038
+#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039
+#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A
+#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B
+#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C
+
+typedef void (GLAPIENTRY * PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot);
+typedef void (GLAPIENTRY * PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset);
+typedef void (GLAPIENTRY * PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture);
+typedef void (GLAPIENTRY * PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot);
+typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint* params);
+typedef GLenum (GLAPIENTRY * PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint* sequence_num, GLuint64EXT *capture_time);
+typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble* params);
+typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint* params);
+
+#define glBeginVideoCaptureNV GLEW_GET_FUN(__glewBeginVideoCaptureNV)
+#define glBindVideoCaptureStreamBufferNV GLEW_GET_FUN(__glewBindVideoCaptureStreamBufferNV)
+#define glBindVideoCaptureStreamTextureNV GLEW_GET_FUN(__glewBindVideoCaptureStreamTextureNV)
+#define glEndVideoCaptureNV GLEW_GET_FUN(__glewEndVideoCaptureNV)
+#define glGetVideoCaptureStreamdvNV GLEW_GET_FUN(__glewGetVideoCaptureStreamdvNV)
+#define glGetVideoCaptureStreamfvNV GLEW_GET_FUN(__glewGetVideoCaptureStreamfvNV)
+#define glGetVideoCaptureStreamivNV GLEW_GET_FUN(__glewGetVideoCaptureStreamivNV)
+#define glGetVideoCaptureivNV GLEW_GET_FUN(__glewGetVideoCaptureivNV)
+#define glVideoCaptureNV GLEW_GET_FUN(__glewVideoCaptureNV)
+#define glVideoCaptureStreamParameterdvNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterdvNV)
+#define glVideoCaptureStreamParameterfvNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterfvNV)
+#define glVideoCaptureStreamParameterivNV GLEW_GET_FUN(__glewVideoCaptureStreamParameterivNV)
+
+#define GLEW_NV_video_capture GLEW_GET_VAR(__GLEW_NV_video_capture)
+
+#endif /* GL_NV_video_capture */
+
+/* ------------------------ GL_OES_byte_coordinates ------------------------ */
+
+#ifndef GL_OES_byte_coordinates
+#define GL_OES_byte_coordinates 1
+
+#define GLEW_OES_byte_coordinates GLEW_GET_VAR(__GLEW_OES_byte_coordinates)
+
+#endif /* GL_OES_byte_coordinates */
+
+/* ------------------- GL_OES_compressed_paletted_texture ------------------ */
+
+#ifndef GL_OES_compressed_paletted_texture
+#define GL_OES_compressed_paletted_texture 1
+
+#define GL_PALETTE4_RGB8_OES 0x8B90
+#define GL_PALETTE4_RGBA8_OES 0x8B91
+#define GL_PALETTE4_R5_G6_B5_OES 0x8B92
+#define GL_PALETTE4_RGBA4_OES 0x8B93
+#define GL_PALETTE4_RGB5_A1_OES 0x8B94
+#define GL_PALETTE8_RGB8_OES 0x8B95
+#define GL_PALETTE8_RGBA8_OES 0x8B96
+#define GL_PALETTE8_R5_G6_B5_OES 0x8B97
+#define GL_PALETTE8_RGBA4_OES 0x8B98
+#define GL_PALETTE8_RGB5_A1_OES 0x8B99
+
+#define GLEW_OES_compressed_paletted_texture GLEW_GET_VAR(__GLEW_OES_compressed_paletted_texture)
+
+#endif /* GL_OES_compressed_paletted_texture */
+
+/* --------------------------- GL_OES_read_format -------------------------- */
+
+#ifndef GL_OES_read_format
+#define GL_OES_read_format 1
+
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B
+
+#define GLEW_OES_read_format GLEW_GET_VAR(__GLEW_OES_read_format)
+
+#endif /* GL_OES_read_format */
+
+/* ------------------------ GL_OES_single_precision ------------------------ */
+
+#ifndef GL_OES_single_precision
+#define GL_OES_single_precision 1
+
+typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFOESPROC) (GLclampd depth);
+typedef void (GLAPIENTRY * PFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat* equation);
+typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f);
+typedef void (GLAPIENTRY * PFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
+typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat* equation);
+typedef void (GLAPIENTRY * PFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
+
+#define glClearDepthfOES GLEW_GET_FUN(__glewClearDepthfOES)
+#define glClipPlanefOES GLEW_GET_FUN(__glewClipPlanefOES)
+#define glDepthRangefOES GLEW_GET_FUN(__glewDepthRangefOES)
+#define glFrustumfOES GLEW_GET_FUN(__glewFrustumfOES)
+#define glGetClipPlanefOES GLEW_GET_FUN(__glewGetClipPlanefOES)
+#define glOrthofOES GLEW_GET_FUN(__glewOrthofOES)
+
+#define GLEW_OES_single_precision GLEW_GET_VAR(__GLEW_OES_single_precision)
+
+#endif /* GL_OES_single_precision */
+
+/* ---------------------------- GL_OML_interlace --------------------------- */
+
+#ifndef GL_OML_interlace
+#define GL_OML_interlace 1
+
+#define GL_INTERLACE_OML 0x8980
+#define GL_INTERLACE_READ_OML 0x8981
+
+#define GLEW_OML_interlace GLEW_GET_VAR(__GLEW_OML_interlace)
+
+#endif /* GL_OML_interlace */
+
+/* ---------------------------- GL_OML_resample ---------------------------- */
+
+#ifndef GL_OML_resample
+#define GL_OML_resample 1
+
+#define GL_PACK_RESAMPLE_OML 0x8984
+#define GL_UNPACK_RESAMPLE_OML 0x8985
+#define GL_RESAMPLE_REPLICATE_OML 0x8986
+#define GL_RESAMPLE_ZERO_FILL_OML 0x8987
+#define GL_RESAMPLE_AVERAGE_OML 0x8988
+#define GL_RESAMPLE_DECIMATE_OML 0x8989
+
+#define GLEW_OML_resample GLEW_GET_VAR(__GLEW_OML_resample)
+
+#endif /* GL_OML_resample */
+
+/* ---------------------------- GL_OML_subsample --------------------------- */
+
+#ifndef GL_OML_subsample
+#define GL_OML_subsample 1
+
+#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982
+#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983
+
+#define GLEW_OML_subsample GLEW_GET_VAR(__GLEW_OML_subsample)
+
+#endif /* GL_OML_subsample */
+
+/* --------------------------- GL_PGI_misc_hints --------------------------- */
+
+#ifndef GL_PGI_misc_hints
+#define GL_PGI_misc_hints 1
+
+#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 107000
+#define GL_CONSERVE_MEMORY_HINT_PGI 107005
+#define GL_RECLAIM_MEMORY_HINT_PGI 107006
+#define GL_NATIVE_GRAPHICS_HANDLE_PGI 107010
+#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 107011
+#define GL_NATIVE_GRAPHICS_END_HINT_PGI 107012
+#define GL_ALWAYS_FAST_HINT_PGI 107020
+#define GL_ALWAYS_SOFT_HINT_PGI 107021
+#define GL_ALLOW_DRAW_OBJ_HINT_PGI 107022
+#define GL_ALLOW_DRAW_WIN_HINT_PGI 107023
+#define GL_ALLOW_DRAW_FRG_HINT_PGI 107024
+#define GL_ALLOW_DRAW_MEM_HINT_PGI 107025
+#define GL_STRICT_DEPTHFUNC_HINT_PGI 107030
+#define GL_STRICT_LIGHTING_HINT_PGI 107031
+#define GL_STRICT_SCISSOR_HINT_PGI 107032
+#define GL_FULL_STIPPLE_HINT_PGI 107033
+#define GL_CLIP_NEAR_HINT_PGI 107040
+#define GL_CLIP_FAR_HINT_PGI 107041
+#define GL_WIDE_LINE_HINT_PGI 107042
+#define GL_BACK_NORMALS_HINT_PGI 107043
+
+#define GLEW_PGI_misc_hints GLEW_GET_VAR(__GLEW_PGI_misc_hints)
+
+#endif /* GL_PGI_misc_hints */
+
+/* -------------------------- GL_PGI_vertex_hints -------------------------- */
+
+#ifndef GL_PGI_vertex_hints
+#define GL_PGI_vertex_hints 1
+
+#define GL_VERTEX23_BIT_PGI 0x00000004
+#define GL_VERTEX4_BIT_PGI 0x00000008
+#define GL_COLOR3_BIT_PGI 0x00010000
+#define GL_COLOR4_BIT_PGI 0x00020000
+#define GL_EDGEFLAG_BIT_PGI 0x00040000
+#define GL_INDEX_BIT_PGI 0x00080000
+#define GL_MAT_AMBIENT_BIT_PGI 0x00100000
+#define GL_VERTEX_DATA_HINT_PGI 107050
+#define GL_VERTEX_CONSISTENT_HINT_PGI 107051
+#define GL_MATERIAL_SIDE_HINT_PGI 107052
+#define GL_MAX_VERTEX_HINT_PGI 107053
+#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000
+#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000
+#define GL_MAT_EMISSION_BIT_PGI 0x00800000
+#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000
+#define GL_MAT_SHININESS_BIT_PGI 0x02000000
+#define GL_MAT_SPECULAR_BIT_PGI 0x04000000
+#define GL_NORMAL_BIT_PGI 0x08000000
+#define GL_TEXCOORD1_BIT_PGI 0x10000000
+#define GL_TEXCOORD2_BIT_PGI 0x20000000
+#define GL_TEXCOORD3_BIT_PGI 0x40000000
+#define GL_TEXCOORD4_BIT_PGI 0x80000000
+
+#define GLEW_PGI_vertex_hints GLEW_GET_VAR(__GLEW_PGI_vertex_hints)
+
+#endif /* GL_PGI_vertex_hints */
+
+/* ---------------------- GL_REGAL_ES1_0_compatibility --------------------- */
+
+#ifndef GL_REGAL_ES1_0_compatibility
+#define GL_REGAL_ES1_0_compatibility 1
+
+typedef int GLclampx;
+
+typedef void (GLAPIENTRY * PFNGLALPHAFUNCXPROC) (GLenum func, GLclampx ref);
+typedef void (GLAPIENTRY * PFNGLCLEARCOLORXPROC) (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+typedef void (GLAPIENTRY * PFNGLCLEARDEPTHXPROC) (GLclampx depth);
+typedef void (GLAPIENTRY * PFNGLCOLOR4XPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+typedef void (GLAPIENTRY * PFNGLDEPTHRANGEXPROC) (GLclampx zNear, GLclampx zFar);
+typedef void (GLAPIENTRY * PFNGLFOGXPROC) (GLenum pname, GLfixed param);
+typedef void (GLAPIENTRY * PFNGLFOGXVPROC) (GLenum pname, const GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLFRUSTUMFPROC) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+typedef void (GLAPIENTRY * PFNGLFRUSTUMXPROC) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+typedef void (GLAPIENTRY * PFNGLLIGHTMODELXPROC) (GLenum pname, GLfixed param);
+typedef void (GLAPIENTRY * PFNGLLIGHTMODELXVPROC) (GLenum pname, const GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLLIGHTXPROC) (GLenum light, GLenum pname, GLfixed param);
+typedef void (GLAPIENTRY * PFNGLLIGHTXVPROC) (GLenum light, GLenum pname, const GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLLINEWIDTHXPROC) (GLfixed width);
+typedef void (GLAPIENTRY * PFNGLLOADMATRIXXPROC) (const GLfixed* m);
+typedef void (GLAPIENTRY * PFNGLMATERIALXPROC) (GLenum face, GLenum pname, GLfixed param);
+typedef void (GLAPIENTRY * PFNGLMATERIALXVPROC) (GLenum face, GLenum pname, const GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLMULTMATRIXXPROC) (const GLfixed* m);
+typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4XPROC) (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+typedef void (GLAPIENTRY * PFNGLNORMAL3XPROC) (GLfixed nx, GLfixed ny, GLfixed nz);
+typedef void (GLAPIENTRY * PFNGLORTHOFPROC) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+typedef void (GLAPIENTRY * PFNGLORTHOXPROC) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+typedef void (GLAPIENTRY * PFNGLPOINTSIZEXPROC) (GLfixed size);
+typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETXPROC) (GLfixed factor, GLfixed units);
+typedef void (GLAPIENTRY * PFNGLROTATEXPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEXPROC) (GLclampx value, GLboolean invert);
+typedef void (GLAPIENTRY * PFNGLSCALEXPROC) (GLfixed x, GLfixed y, GLfixed z);
+typedef void (GLAPIENTRY * PFNGLTEXENVXPROC) (GLenum target, GLenum pname, GLfixed param);
+typedef void (GLAPIENTRY * PFNGLTEXENVXVPROC) (GLenum target, GLenum pname, const GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERXPROC) (GLenum target, GLenum pname, GLfixed param);
+typedef void (GLAPIENTRY * PFNGLTRANSLATEXPROC) (GLfixed x, GLfixed y, GLfixed z);
+
+#define glAlphaFuncx GLEW_GET_FUN(__glewAlphaFuncx)
+#define glClearColorx GLEW_GET_FUN(__glewClearColorx)
+#define glClearDepthx GLEW_GET_FUN(__glewClearDepthx)
+#define glColor4x GLEW_GET_FUN(__glewColor4x)
+#define glDepthRangex GLEW_GET_FUN(__glewDepthRangex)
+#define glFogx GLEW_GET_FUN(__glewFogx)
+#define glFogxv GLEW_GET_FUN(__glewFogxv)
+#define glFrustumf GLEW_GET_FUN(__glewFrustumf)
+#define glFrustumx GLEW_GET_FUN(__glewFrustumx)
+#define glLightModelx GLEW_GET_FUN(__glewLightModelx)
+#define glLightModelxv GLEW_GET_FUN(__glewLightModelxv)
+#define glLightx GLEW_GET_FUN(__glewLightx)
+#define glLightxv GLEW_GET_FUN(__glewLightxv)
+#define glLineWidthx GLEW_GET_FUN(__glewLineWidthx)
+#define glLoadMatrixx GLEW_GET_FUN(__glewLoadMatrixx)
+#define glMaterialx GLEW_GET_FUN(__glewMaterialx)
+#define glMaterialxv GLEW_GET_FUN(__glewMaterialxv)
+#define glMultMatrixx GLEW_GET_FUN(__glewMultMatrixx)
+#define glMultiTexCoord4x GLEW_GET_FUN(__glewMultiTexCoord4x)
+#define glNormal3x GLEW_GET_FUN(__glewNormal3x)
+#define glOrthof GLEW_GET_FUN(__glewOrthof)
+#define glOrthox GLEW_GET_FUN(__glewOrthox)
+#define glPointSizex GLEW_GET_FUN(__glewPointSizex)
+#define glPolygonOffsetx GLEW_GET_FUN(__glewPolygonOffsetx)
+#define glRotatex GLEW_GET_FUN(__glewRotatex)
+#define glSampleCoveragex GLEW_GET_FUN(__glewSampleCoveragex)
+#define glScalex GLEW_GET_FUN(__glewScalex)
+#define glTexEnvx GLEW_GET_FUN(__glewTexEnvx)
+#define glTexEnvxv GLEW_GET_FUN(__glewTexEnvxv)
+#define glTexParameterx GLEW_GET_FUN(__glewTexParameterx)
+#define glTranslatex GLEW_GET_FUN(__glewTranslatex)
+
+#define GLEW_REGAL_ES1_0_compatibility GLEW_GET_VAR(__GLEW_REGAL_ES1_0_compatibility)
+
+#endif /* GL_REGAL_ES1_0_compatibility */
+
+/* ---------------------- GL_REGAL_ES1_1_compatibility --------------------- */
+
+#ifndef GL_REGAL_ES1_1_compatibility
+#define GL_REGAL_ES1_1_compatibility 1
+
+typedef void (GLAPIENTRY * PFNGLCLIPPLANEFPROC) (GLenum plane, const GLfloat* equation);
+typedef void (GLAPIENTRY * PFNGLCLIPPLANEXPROC) (GLenum plane, const GLfixed* equation);
+typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEFPROC) (GLenum pname, GLfloat eqn[4]);
+typedef void (GLAPIENTRY * PFNGLGETCLIPPLANEXPROC) (GLenum pname, GLfixed eqn[4]);
+typedef void (GLAPIENTRY * PFNGLGETFIXEDVPROC) (GLenum pname, GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLGETLIGHTXVPROC) (GLenum light, GLenum pname, GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLGETMATERIALXVPROC) (GLenum face, GLenum pname, GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXENVXVPROC) (GLenum env, GLenum pname, GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERXVPROC) (GLenum target, GLenum pname, GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERXPROC) (GLenum pname, GLfixed param);
+typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERXVPROC) (GLenum pname, const GLfixed* params);
+typedef void (GLAPIENTRY * PFNGLPOINTSIZEPOINTEROESPROC) (GLenum type, GLsizei stride, const GLvoid* pointer);
+typedef void (GLAPIENTRY * PFNGLTEXPARAMETERXVPROC) (GLenum target, GLenum pname, const GLfixed* params);
+
+#define glClipPlanef GLEW_GET_FUN(__glewClipPlanef)
+#define glClipPlanex GLEW_GET_FUN(__glewClipPlanex)
+#define glGetClipPlanef GLEW_GET_FUN(__glewGetClipPlanef)
+#define glGetClipPlanex GLEW_GET_FUN(__glewGetClipPlanex)
+#define glGetFixedv GLEW_GET_FUN(__glewGetFixedv)
+#define glGetLightxv GLEW_GET_FUN(__glewGetLightxv)
+#define glGetMaterialxv GLEW_GET_FUN(__glewGetMaterialxv)
+#define glGetTexEnvxv GLEW_GET_FUN(__glewGetTexEnvxv)
+#define glGetTexParameterxv GLEW_GET_FUN(__glewGetTexParameterxv)
+#define glPointParameterx GLEW_GET_FUN(__glewPointParameterx)
+#define glPointParameterxv GLEW_GET_FUN(__glewPointParameterxv)
+#define glPointSizePointerOES GLEW_GET_FUN(__glewPointSizePointerOES)
+#define glTexParameterxv GLEW_GET_FUN(__glewTexParameterxv)
+
+#define GLEW_REGAL_ES1_1_compatibility GLEW_GET_VAR(__GLEW_REGAL_ES1_1_compatibility)
+
+#endif /* GL_REGAL_ES1_1_compatibility */
+
+/* ---------------------------- GL_REGAL_enable ---------------------------- */
+
+#ifndef GL_REGAL_enable
+#define GL_REGAL_enable 1
+
+#define GL_ERROR_REGAL 0x9322
+#define GL_DEBUG_REGAL 0x9323
+#define GL_LOG_REGAL 0x9324
+#define GL_EMULATION_REGAL 0x9325
+#define GL_DRIVER_REGAL 0x9326
+#define GL_MISSING_REGAL 0x9360
+#define GL_TRACE_REGAL 0x9361
+#define GL_CACHE_REGAL 0x9362
+#define GL_CODE_REGAL 0x9363
+#define GL_STATISTICS_REGAL 0x9364
+
+#define GLEW_REGAL_enable GLEW_GET_VAR(__GLEW_REGAL_enable)
+
+#endif /* GL_REGAL_enable */
+
+/* ------------------------- GL_REGAL_error_string ------------------------- */
+
+#ifndef GL_REGAL_error_string
+#define GL_REGAL_error_string 1
+
+typedef const GLchar* (GLAPIENTRY * PFNGLERRORSTRINGREGALPROC) (GLenum error);
+
+#define glErrorStringREGAL GLEW_GET_FUN(__glewErrorStringREGAL)
+
+#define GLEW_REGAL_error_string GLEW_GET_VAR(__GLEW_REGAL_error_string)
+
+#endif /* GL_REGAL_error_string */
+
+/* ------------------------ GL_REGAL_extension_query ----------------------- */
+
+#ifndef GL_REGAL_extension_query
+#define GL_REGAL_extension_query 1
+
+typedef GLboolean (GLAPIENTRY * PFNGLGETEXTENSIONREGALPROC) (const GLchar* ext);
+typedef GLboolean (GLAPIENTRY * PFNGLISSUPPORTEDREGALPROC) (const GLchar* ext);
+
+#define glGetExtensionREGAL GLEW_GET_FUN(__glewGetExtensionREGAL)
+#define glIsSupportedREGAL GLEW_GET_FUN(__glewIsSupportedREGAL)
+
+#define GLEW_REGAL_extension_query GLEW_GET_VAR(__GLEW_REGAL_extension_query)
+
+#endif /* GL_REGAL_extension_query */
+
+/* ------------------------------ GL_REGAL_log ----------------------------- */
+
+#ifndef GL_REGAL_log
+#define GL_REGAL_log 1
+
+#define GL_LOG_ERROR_REGAL 0x9319
+#define GL_LOG_WARNING_REGAL 0x931A
+#define GL_LOG_INFO_REGAL 0x931B
+#define GL_LOG_APP_REGAL 0x931C
+#define GL_LOG_DRIVER_REGAL 0x931D
+#define GL_LOG_INTERNAL_REGAL 0x931E
+#define GL_LOG_DEBUG_REGAL 0x931F
+#define GL_LOG_STATUS_REGAL 0x9320
+#define GL_LOG_HTTP_REGAL 0x9321
+
+typedef void (APIENTRY *GLLOGPROCREGAL)(GLenum stream, GLsizei length, const GLchar *message, GLvoid *context);
+
+typedef void (GLAPIENTRY * PFNGLLOGMESSAGECALLBACKREGALPROC) (GLLOGPROCREGAL callback);
+
+#define glLogMessageCallbackREGAL GLEW_GET_FUN(__glewLogMessageCallbackREGAL)
+
+#define GLEW_REGAL_log GLEW_GET_VAR(__GLEW_REGAL_log)
+
+#endif /* GL_REGAL_log */
+
+/* ----------------------- GL_REND_screen_coordinates ---------------------- */
+
+#ifndef GL_REND_screen_coordinates
+#define GL_REND_screen_coordinates 1
+
+#define GL_SCREEN_COORDINATES_REND 0x8490
+#define GL_INVERTED_SCREEN_W_REND 0x8491
+
+#define GLEW_REND_screen_coordinates GLEW_GET_VAR(__GLEW_REND_screen_coordinates)
+
+#endif /* GL_REND_screen_coordinates */
+
+/* ------------------------------- GL_S3_s3tc ------------------------------ */
+
+#ifndef GL_S3_s3tc
+#define GL_S3_s3tc 1
+
+#define GL_RGB_S3TC 0x83A0
+#define GL_RGB4_S3TC 0x83A1
+#define GL_RGBA_S3TC 0x83A2
+#define GL_RGBA4_S3TC 0x83A3
+#define GL_RGBA_DXT5_S3TC 0x83A4
+#define GL_RGBA4_DXT5_S3TC 0x83A5
+
+#define GLEW_S3_s3tc GLEW_GET_VAR(__GLEW_S3_s3tc)
+
+#endif /* GL_S3_s3tc */
+
+/* -------------------------- GL_SGIS_color_range -------------------------- */
+
+#ifndef GL_SGIS_color_range
+#define GL_SGIS_color_range 1
+
+#define GL_EXTENDED_RANGE_SGIS 0x85A5
+#define GL_MIN_RED_SGIS 0x85A6
+#define GL_MAX_RED_SGIS 0x85A7
+#define GL_MIN_GREEN_SGIS 0x85A8
+#define GL_MAX_GREEN_SGIS 0x85A9
+#define GL_MIN_BLUE_SGIS 0x85AA
+#define GL_MAX_BLUE_SGIS 0x85AB
+#define GL_MIN_ALPHA_SGIS 0x85AC
+#define GL_MAX_ALPHA_SGIS 0x85AD
+
+#define GLEW_SGIS_color_range GLEW_GET_VAR(__GLEW_SGIS_color_range)
+
+#endif /* GL_SGIS_color_range */
+
+/* ------------------------- GL_SGIS_detail_texture ------------------------ */
+
+#ifndef GL_SGIS_detail_texture
+#define GL_SGIS_detail_texture 1
+
+typedef void (GLAPIENTRY * PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points);
+typedef void (GLAPIENTRY * PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat* points);
+
+#define glDetailTexFuncSGIS GLEW_GET_FUN(__glewDetailTexFuncSGIS)
+#define glGetDetailTexFuncSGIS GLEW_GET_FUN(__glewGetDetailTexFuncSGIS)
+
+#define GLEW_SGIS_detail_texture GLEW_GET_VAR(__GLEW_SGIS_detail_texture)
+
+#endif /* GL_SGIS_detail_texture */
+
+/* -------------------------- GL_SGIS_fog_function ------------------------- */
+
+#ifndef GL_SGIS_fog_function
+#define GL_SGIS_fog_function 1
+
+typedef void (GLAPIENTRY * PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat* points);
+typedef void (GLAPIENTRY * PFNGLGETFOGFUNCSGISPROC) (GLfloat* points);
+
+#define glFogFuncSGIS GLEW_GET_FUN(__glewFogFuncSGIS)
+#define glGetFogFuncSGIS GLEW_GET_FUN(__glewGetFogFuncSGIS)
+
+#define GLEW_SGIS_fog_function GLEW_GET_VAR(__GLEW_SGIS_fog_function)
+
+#endif /* GL_SGIS_fog_function */
+
+/* ------------------------ GL_SGIS_generate_mipmap ------------------------ */
+
+#ifndef GL_SGIS_generate_mipmap
+#define GL_SGIS_generate_mipmap 1
+
+#define GL_GENERATE_MIPMAP_SGIS 0x8191
+#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
+
+#define GLEW_SGIS_generate_mipmap GLEW_GET_VAR(__GLEW_SGIS_generate_mipmap)
+
+#endif /* GL_SGIS_generate_mipmap */
+
+/* -------------------------- GL_SGIS_multisample -------------------------- */
+
+#ifndef GL_SGIS_multisample
+#define GL_SGIS_multisample 1
+
+#define GL_MULTISAMPLE_SGIS 0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F
+#define GL_SAMPLE_MASK_SGIS 0x80A0
+#define GL_1PASS_SGIS 0x80A1
+#define GL_2PASS_0_SGIS 0x80A2
+#define GL_2PASS_1_SGIS 0x80A3
+#define GL_4PASS_0_SGIS 0x80A4
+#define GL_4PASS_1_SGIS 0x80A5
+#define GL_4PASS_2_SGIS 0x80A6
+#define GL_4PASS_3_SGIS 0x80A7
+#define GL_SAMPLE_BUFFERS_SGIS 0x80A8
+#define GL_SAMPLES_SGIS 0x80A9
+#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA
+#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB
+#define GL_SAMPLE_PATTERN_SGIS 0x80AC
+
+typedef void (GLAPIENTRY * PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert);
+typedef void (GLAPIENTRY * PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern);
+
+#define glSampleMaskSGIS GLEW_GET_FUN(__glewSampleMaskSGIS)
+#define glSamplePatternSGIS GLEW_GET_FUN(__glewSamplePatternSGIS)
+
+#define GLEW_SGIS_multisample GLEW_GET_VAR(__GLEW_SGIS_multisample)
+
+#endif /* GL_SGIS_multisample */
+
+/* ------------------------- GL_SGIS_pixel_texture ------------------------- */
+
+#ifndef GL_SGIS_pixel_texture
+#define GL_SGIS_pixel_texture 1
+
+#define GLEW_SGIS_pixel_texture GLEW_GET_VAR(__GLEW_SGIS_pixel_texture)
+
+#endif /* GL_SGIS_pixel_texture */
+
+/* ----------------------- GL_SGIS_point_line_texgen ----------------------- */
+
+#ifndef GL_SGIS_point_line_texgen
+#define GL_SGIS_point_line_texgen 1
+
+#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0
+#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1
+#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2
+#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3
+#define GL_EYE_POINT_SGIS 0x81F4
+#define GL_OBJECT_POINT_SGIS 0x81F5
+#define GL_EYE_LINE_SGIS 0x81F6
+#define GL_OBJECT_LINE_SGIS 0x81F7
+
+#define GLEW_SGIS_point_line_texgen GLEW_GET_VAR(__GLEW_SGIS_point_line_texgen)
+
+#endif /* GL_SGIS_point_line_texgen */
+
+/* ------------------------ GL_SGIS_sharpen_texture ------------------------ */
+
+#ifndef GL_SGIS_sharpen_texture
+#define GL_SGIS_sharpen_texture 1
+
+typedef void (GLAPIENTRY * PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat* points);
+typedef void (GLAPIENTRY * PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat* points);
+
+#define glGetSharpenTexFuncSGIS GLEW_GET_FUN(__glewGetSharpenTexFuncSGIS)
+#define glSharpenTexFuncSGIS GLEW_GET_FUN(__glewSharpenTexFuncSGIS)
+
+#define GLEW_SGIS_sharpen_texture GLEW_GET_VAR(__GLEW_SGIS_sharpen_texture)
+
+#endif /* GL_SGIS_sharpen_texture */
+
+/* --------------------------- GL_SGIS_texture4D --------------------------- */
+
+#ifndef GL_SGIS_texture4D
+#define GL_SGIS_texture4D 1
+
+typedef void (GLAPIENTRY * PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLenum format, GLenum type, const GLvoid *pixels);
+
+#define glTexImage4DSGIS GLEW_GET_FUN(__glewTexImage4DSGIS)
+#define glTexSubImage4DSGIS GLEW_GET_FUN(__glewTexSubImage4DSGIS)
+
+#define GLEW_SGIS_texture4D GLEW_GET_VAR(__GLEW_SGIS_texture4D)
+
+#endif /* GL_SGIS_texture4D */
+
+/* ---------------------- GL_SGIS_texture_border_clamp --------------------- */
+
+#ifndef GL_SGIS_texture_border_clamp
+#define GL_SGIS_texture_border_clamp 1
+
+#define GL_CLAMP_TO_BORDER_SGIS 0x812D
+
+#define GLEW_SGIS_texture_border_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_border_clamp)
+
+#endif /* GL_SGIS_texture_border_clamp */
+
+/* ----------------------- GL_SGIS_texture_edge_clamp ---------------------- */
+
+#ifndef GL_SGIS_texture_edge_clamp
+#define GL_SGIS_texture_edge_clamp 1
+
+#define GL_CLAMP_TO_EDGE_SGIS 0x812F
+
+#define GLEW_SGIS_texture_edge_clamp GLEW_GET_VAR(__GLEW_SGIS_texture_edge_clamp)
+
+#endif /* GL_SGIS_texture_edge_clamp */
+
+/* ------------------------ GL_SGIS_texture_filter4 ------------------------ */
+
+#ifndef GL_SGIS_texture_filter4
+#define GL_SGIS_texture_filter4 1
+
+typedef void (GLAPIENTRY * PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat* weights);
+typedef void (GLAPIENTRY * PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat* weights);
+
+#define glGetTexFilterFuncSGIS GLEW_GET_FUN(__glewGetTexFilterFuncSGIS)
+#define glTexFilterFuncSGIS GLEW_GET_FUN(__glewTexFilterFuncSGIS)
+
+#define GLEW_SGIS_texture_filter4 GLEW_GET_VAR(__GLEW_SGIS_texture_filter4)
+
+#endif /* GL_SGIS_texture_filter4 */
+
+/* -------------------------- GL_SGIS_texture_lod -------------------------- */
+
+#ifndef GL_SGIS_texture_lod
+#define GL_SGIS_texture_lod 1
+
+#define GL_TEXTURE_MIN_LOD_SGIS 0x813A
+#define GL_TEXTURE_MAX_LOD_SGIS 0x813B
+#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C
+#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D
+
+#define GLEW_SGIS_texture_lod GLEW_GET_VAR(__GLEW_SGIS_texture_lod)
+
+#endif /* GL_SGIS_texture_lod */
+
+/* ------------------------- GL_SGIS_texture_select ------------------------ */
+
+#ifndef GL_SGIS_texture_select
+#define GL_SGIS_texture_select 1
+
+#define GLEW_SGIS_texture_select GLEW_GET_VAR(__GLEW_SGIS_texture_select)
+
+#endif /* GL_SGIS_texture_select */
+
+/* ----------------------------- GL_SGIX_async ----------------------------- */
+
+#ifndef GL_SGIX_async
+#define GL_SGIX_async 1
+
+#define GL_ASYNC_MARKER_SGIX 0x8329
+
+typedef void (GLAPIENTRY * PFNGLASYNCMARKERSGIXPROC) (GLuint marker);
+typedef void (GLAPIENTRY * PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range);
+typedef GLint (GLAPIENTRY * PFNGLFINISHASYNCSGIXPROC) (GLuint* markerp);
+typedef GLuint (GLAPIENTRY * PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range);
+typedef GLboolean (GLAPIENTRY * PFNGLISASYNCMARKERSGIXPROC) (GLuint marker);
+typedef GLint (GLAPIENTRY * PFNGLPOLLASYNCSGIXPROC) (GLuint* markerp);
+
+#define glAsyncMarkerSGIX GLEW_GET_FUN(__glewAsyncMarkerSGIX)
+#define glDeleteAsyncMarkersSGIX GLEW_GET_FUN(__glewDeleteAsyncMarkersSGIX)
+#define glFinishAsyncSGIX GLEW_GET_FUN(__glewFinishAsyncSGIX)
+#define glGenAsyncMarkersSGIX GLEW_GET_FUN(__glewGenAsyncMarkersSGIX)
+#define glIsAsyncMarkerSGIX GLEW_GET_FUN(__glewIsAsyncMarkerSGIX)
+#define glPollAsyncSGIX GLEW_GET_FUN(__glewPollAsyncSGIX)
+
+#define GLEW_SGIX_async GLEW_GET_VAR(__GLEW_SGIX_async)
+
+#endif /* GL_SGIX_async */
+
+/* ------------------------ GL_SGIX_async_histogram ------------------------ */
+
+#ifndef GL_SGIX_async_histogram
+#define GL_SGIX_async_histogram 1
+
+#define GL_ASYNC_HISTOGRAM_SGIX 0x832C
+#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D
+
+#define GLEW_SGIX_async_histogram GLEW_GET_VAR(__GLEW_SGIX_async_histogram)
+
+#endif /* GL_SGIX_async_histogram */
+
+/* -------------------------- GL_SGIX_async_pixel -------------------------- */
+
+#ifndef GL_SGIX_async_pixel
+#define GL_SGIX_async_pixel 1
+
+#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C
+#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D
+#define GL_ASYNC_READ_PIXELS_SGIX 0x835E
+#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F
+#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360
+#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361
+
+#define GLEW_SGIX_async_pixel GLEW_GET_VAR(__GLEW_SGIX_async_pixel)
+
+#endif /* GL_SGIX_async_pixel */
+
+/* ----------------------- GL_SGIX_blend_alpha_minmax ---------------------- */
+
+#ifndef GL_SGIX_blend_alpha_minmax
+#define GL_SGIX_blend_alpha_minmax 1
+
+#define GL_ALPHA_MIN_SGIX 0x8320
+#define GL_ALPHA_MAX_SGIX 0x8321
+
+#define GLEW_SGIX_blend_alpha_minmax GLEW_GET_VAR(__GLEW_SGIX_blend_alpha_minmax)
+
+#endif /* GL_SGIX_blend_alpha_minmax */
+
+/* ---------------------------- GL_SGIX_clipmap ---------------------------- */
+
+#ifndef GL_SGIX_clipmap
+#define GL_SGIX_clipmap 1
+
+#define GLEW_SGIX_clipmap GLEW_GET_VAR(__GLEW_SGIX_clipmap)
+
+#endif /* GL_SGIX_clipmap */
+
+/* ---------------------- GL_SGIX_convolution_accuracy --------------------- */
+
+#ifndef GL_SGIX_convolution_accuracy
+#define GL_SGIX_convolution_accuracy 1
+
+#define GL_CONVOLUTION_HINT_SGIX 0x8316
+
+#define GLEW_SGIX_convolution_accuracy GLEW_GET_VAR(__GLEW_SGIX_convolution_accuracy)
+
+#endif /* GL_SGIX_convolution_accuracy */
+
+/* ------------------------- GL_SGIX_depth_texture ------------------------- */
+
+#ifndef GL_SGIX_depth_texture
+#define GL_SGIX_depth_texture 1
+
+#define GL_DEPTH_COMPONENT16_SGIX 0x81A5
+#define GL_DEPTH_COMPONENT24_SGIX 0x81A6
+#define GL_DEPTH_COMPONENT32_SGIX 0x81A7
+
+#define GLEW_SGIX_depth_texture GLEW_GET_VAR(__GLEW_SGIX_depth_texture)
+
+#endif /* GL_SGIX_depth_texture */
+
+/* -------------------------- GL_SGIX_flush_raster ------------------------- */
+
+#ifndef GL_SGIX_flush_raster
+#define GL_SGIX_flush_raster 1
+
+typedef void (GLAPIENTRY * PFNGLFLUSHRASTERSGIXPROC) (void);
+
+#define glFlushRasterSGIX GLEW_GET_FUN(__glewFlushRasterSGIX)
+
+#define GLEW_SGIX_flush_raster GLEW_GET_VAR(__GLEW_SGIX_flush_raster)
+
+#endif /* GL_SGIX_flush_raster */
+
+/* --------------------------- GL_SGIX_fog_offset -------------------------- */
+
+#ifndef GL_SGIX_fog_offset
+#define GL_SGIX_fog_offset 1
+
+#define GL_FOG_OFFSET_SGIX 0x8198
+#define GL_FOG_OFFSET_VALUE_SGIX 0x8199
+
+#define GLEW_SGIX_fog_offset GLEW_GET_VAR(__GLEW_SGIX_fog_offset)
+
+#endif /* GL_SGIX_fog_offset */
+
+/* -------------------------- GL_SGIX_fog_texture -------------------------- */
+
+#ifndef GL_SGIX_fog_texture
+#define GL_SGIX_fog_texture 1
+
+#define GL_TEXTURE_FOG_SGIX 0
+#define GL_FOG_PATCHY_FACTOR_SGIX 0
+#define GL_FRAGMENT_FOG_SGIX 0
+
+typedef void (GLAPIENTRY * PFNGLTEXTUREFOGSGIXPROC) (GLenum pname);
+
+#define glTextureFogSGIX GLEW_GET_FUN(__glewTextureFogSGIX)
+
+#define GLEW_SGIX_fog_texture GLEW_GET_VAR(__GLEW_SGIX_fog_texture)
+
+#endif /* GL_SGIX_fog_texture */
+
+/* ------------------- GL_SGIX_fragment_specular_lighting ------------------ */
+
+#ifndef GL_SGIX_fragment_specular_lighting
+#define GL_SGIX_fragment_specular_lighting 1
+
+typedef void (GLAPIENTRY * PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, const GLfloat param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, const GLint param);
+typedef void (GLAPIENTRY * PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum value, GLfloat* data);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum value, GLint* data);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat* data);
+typedef void (GLAPIENTRY * PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint* data);
+
+#define glFragmentColorMaterialSGIX GLEW_GET_FUN(__glewFragmentColorMaterialSGIX)
+#define glFragmentLightModelfSGIX GLEW_GET_FUN(__glewFragmentLightModelfSGIX)
+#define glFragmentLightModelfvSGIX GLEW_GET_FUN(__glewFragmentLightModelfvSGIX)
+#define glFragmentLightModeliSGIX GLEW_GET_FUN(__glewFragmentLightModeliSGIX)
+#define glFragmentLightModelivSGIX GLEW_GET_FUN(__glewFragmentLightModelivSGIX)
+#define glFragmentLightfSGIX GLEW_GET_FUN(__glewFragmentLightfSGIX)
+#define glFragmentLightfvSGIX GLEW_GET_FUN(__glewFragmentLightfvSGIX)
+#define glFragmentLightiSGIX GLEW_GET_FUN(__glewFragmentLightiSGIX)
+#define glFragmentLightivSGIX GLEW_GET_FUN(__glewFragmentLightivSGIX)
+#define glFragmentMaterialfSGIX GLEW_GET_FUN(__glewFragmentMaterialfSGIX)
+#define glFragmentMaterialfvSGIX GLEW_GET_FUN(__glewFragmentMaterialfvSGIX)
+#define glFragmentMaterialiSGIX GLEW_GET_FUN(__glewFragmentMaterialiSGIX)
+#define glFragmentMaterialivSGIX GLEW_GET_FUN(__glewFragmentMaterialivSGIX)
+#define glGetFragmentLightfvSGIX GLEW_GET_FUN(__glewGetFragmentLightfvSGIX)
+#define glGetFragmentLightivSGIX GLEW_GET_FUN(__glewGetFragmentLightivSGIX)
+#define glGetFragmentMaterialfvSGIX GLEW_GET_FUN(__glewGetFragmentMaterialfvSGIX)
+#define glGetFragmentMaterialivSGIX GLEW_GET_FUN(__glewGetFragmentMaterialivSGIX)
+
+#define GLEW_SGIX_fragment_specular_lighting GLEW_GET_VAR(__GLEW_SGIX_fragment_specular_lighting)
+
+#endif /* GL_SGIX_fragment_specular_lighting */
+
+/* --------------------------- GL_SGIX_framezoom --------------------------- */
+
+#ifndef GL_SGIX_framezoom
+#define GL_SGIX_framezoom 1
+
+typedef void (GLAPIENTRY * PFNGLFRAMEZOOMSGIXPROC) (GLint factor);
+
+#define glFrameZoomSGIX GLEW_GET_FUN(__glewFrameZoomSGIX)
+
+#define GLEW_SGIX_framezoom GLEW_GET_VAR(__GLEW_SGIX_framezoom)
+
+#endif /* GL_SGIX_framezoom */
+
+/* --------------------------- GL_SGIX_interlace --------------------------- */
+
+#ifndef GL_SGIX_interlace
+#define GL_SGIX_interlace 1
+
+#define GL_INTERLACE_SGIX 0x8094
+
+#define GLEW_SGIX_interlace GLEW_GET_VAR(__GLEW_SGIX_interlace)
+
+#endif /* GL_SGIX_interlace */
+
+/* ------------------------- GL_SGIX_ir_instrument1 ------------------------ */
+
+#ifndef GL_SGIX_ir_instrument1
+#define GL_SGIX_ir_instrument1 1
+
+#define GLEW_SGIX_ir_instrument1 GLEW_GET_VAR(__GLEW_SGIX_ir_instrument1)
+
+#endif /* GL_SGIX_ir_instrument1 */
+
+/* ------------------------- GL_SGIX_list_priority ------------------------- */
+
+#ifndef GL_SGIX_list_priority
+#define GL_SGIX_list_priority 1
+
+#define GLEW_SGIX_list_priority GLEW_GET_VAR(__GLEW_SGIX_list_priority)
+
+#endif /* GL_SGIX_list_priority */
+
+/* ------------------------- GL_SGIX_pixel_texture ------------------------- */
+
+#ifndef GL_SGIX_pixel_texture
+#define GL_SGIX_pixel_texture 1
+
+typedef void (GLAPIENTRY * PFNGLPIXELTEXGENSGIXPROC) (GLenum mode);
+
+#define glPixelTexGenSGIX GLEW_GET_FUN(__glewPixelTexGenSGIX)
+
+#define GLEW_SGIX_pixel_texture GLEW_GET_VAR(__GLEW_SGIX_pixel_texture)
+
+#endif /* GL_SGIX_pixel_texture */
+
+/* ----------------------- GL_SGIX_pixel_texture_bits ---------------------- */
+
+#ifndef GL_SGIX_pixel_texture_bits
+#define GL_SGIX_pixel_texture_bits 1
+
+#define GLEW_SGIX_pixel_texture_bits GLEW_GET_VAR(__GLEW_SGIX_pixel_texture_bits)
+
+#endif /* GL_SGIX_pixel_texture_bits */
+
+/* ------------------------ GL_SGIX_reference_plane ------------------------ */
+
+#ifndef GL_SGIX_reference_plane
+#define GL_SGIX_reference_plane 1
+
+typedef void (GLAPIENTRY * PFNGLREFERENCEPLANESGIXPROC) (const GLdouble* equation);
+
+#define glReferencePlaneSGIX GLEW_GET_FUN(__glewReferencePlaneSGIX)
+
+#define GLEW_SGIX_reference_plane GLEW_GET_VAR(__GLEW_SGIX_reference_plane)
+
+#endif /* GL_SGIX_reference_plane */
+
+/* ---------------------------- GL_SGIX_resample --------------------------- */
+
+#ifndef GL_SGIX_resample
+#define GL_SGIX_resample 1
+
+#define GL_PACK_RESAMPLE_SGIX 0x842E
+#define GL_UNPACK_RESAMPLE_SGIX 0x842F
+#define GL_RESAMPLE_DECIMATE_SGIX 0x8430
+#define GL_RESAMPLE_REPLICATE_SGIX 0x8433
+#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434
+
+#define GLEW_SGIX_resample GLEW_GET_VAR(__GLEW_SGIX_resample)
+
+#endif /* GL_SGIX_resample */
+
+/* ----------------------------- GL_SGIX_shadow ---------------------------- */
+
+#ifndef GL_SGIX_shadow
+#define GL_SGIX_shadow 1
+
+#define GL_TEXTURE_COMPARE_SGIX 0x819A
+#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B
+#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C
+#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D
+
+#define GLEW_SGIX_shadow GLEW_GET_VAR(__GLEW_SGIX_shadow)
+
+#endif /* GL_SGIX_shadow */
+
+/* ------------------------- GL_SGIX_shadow_ambient ------------------------ */
+
+#ifndef GL_SGIX_shadow_ambient
+#define GL_SGIX_shadow_ambient 1
+
+#define GL_SHADOW_AMBIENT_SGIX 0x80BF
+
+#define GLEW_SGIX_shadow_ambient GLEW_GET_VAR(__GLEW_SGIX_shadow_ambient)
+
+#endif /* GL_SGIX_shadow_ambient */
+
+/* ----------------------------- GL_SGIX_sprite ---------------------------- */
+
+#ifndef GL_SGIX_sprite
+#define GL_SGIX_sprite 1
+
+typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param);
+typedef void (GLAPIENTRY * PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, GLint* params);
+
+#define glSpriteParameterfSGIX GLEW_GET_FUN(__glewSpriteParameterfSGIX)
+#define glSpriteParameterfvSGIX GLEW_GET_FUN(__glewSpriteParameterfvSGIX)
+#define glSpriteParameteriSGIX GLEW_GET_FUN(__glewSpriteParameteriSGIX)
+#define glSpriteParameterivSGIX GLEW_GET_FUN(__glewSpriteParameterivSGIX)
+
+#define GLEW_SGIX_sprite GLEW_GET_VAR(__GLEW_SGIX_sprite)
+
+#endif /* GL_SGIX_sprite */
+
+/* ----------------------- GL_SGIX_tag_sample_buffer ----------------------- */
+
+#ifndef GL_SGIX_tag_sample_buffer
+#define GL_SGIX_tag_sample_buffer 1
+
+typedef void (GLAPIENTRY * PFNGLTAGSAMPLEBUFFERSGIXPROC) (void);
+
+#define glTagSampleBufferSGIX GLEW_GET_FUN(__glewTagSampleBufferSGIX)
+
+#define GLEW_SGIX_tag_sample_buffer GLEW_GET_VAR(__GLEW_SGIX_tag_sample_buffer)
+
+#endif /* GL_SGIX_tag_sample_buffer */
+
+/* ------------------------ GL_SGIX_texture_add_env ------------------------ */
+
+#ifndef GL_SGIX_texture_add_env
+#define GL_SGIX_texture_add_env 1
+
+#define GLEW_SGIX_texture_add_env GLEW_GET_VAR(__GLEW_SGIX_texture_add_env)
+
+#endif /* GL_SGIX_texture_add_env */
+
+/* -------------------- GL_SGIX_texture_coordinate_clamp ------------------- */
+
+#ifndef GL_SGIX_texture_coordinate_clamp
+#define GL_SGIX_texture_coordinate_clamp 1
+
+#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369
+#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A
+#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B
+
+#define GLEW_SGIX_texture_coordinate_clamp GLEW_GET_VAR(__GLEW_SGIX_texture_coordinate_clamp)
+
+#endif /* GL_SGIX_texture_coordinate_clamp */
+
+/* ------------------------ GL_SGIX_texture_lod_bias ----------------------- */
+
+#ifndef GL_SGIX_texture_lod_bias
+#define GL_SGIX_texture_lod_bias 1
+
+#define GLEW_SGIX_texture_lod_bias GLEW_GET_VAR(__GLEW_SGIX_texture_lod_bias)
+
+#endif /* GL_SGIX_texture_lod_bias */
+
+/* ---------------------- GL_SGIX_texture_multi_buffer --------------------- */
+
+#ifndef GL_SGIX_texture_multi_buffer
+#define GL_SGIX_texture_multi_buffer 1
+
+#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E
+
+#define GLEW_SGIX_texture_multi_buffer GLEW_GET_VAR(__GLEW_SGIX_texture_multi_buffer)
+
+#endif /* GL_SGIX_texture_multi_buffer */
+
+/* ------------------------- GL_SGIX_texture_range ------------------------- */
+
+#ifndef GL_SGIX_texture_range
+#define GL_SGIX_texture_range 1
+
+#define GL_RGB_SIGNED_SGIX 0x85E0
+#define GL_RGBA_SIGNED_SGIX 0x85E1
+#define GL_ALPHA_SIGNED_SGIX 0x85E2
+#define GL_LUMINANCE_SIGNED_SGIX 0x85E3
+#define GL_INTENSITY_SIGNED_SGIX 0x85E4
+#define GL_LUMINANCE_ALPHA_SIGNED_SGIX 0x85E5
+#define GL_RGB16_SIGNED_SGIX 0x85E6
+#define GL_RGBA16_SIGNED_SGIX 0x85E7
+#define GL_ALPHA16_SIGNED_SGIX 0x85E8
+#define GL_LUMINANCE16_SIGNED_SGIX 0x85E9
+#define GL_INTENSITY16_SIGNED_SGIX 0x85EA
+#define GL_LUMINANCE16_ALPHA16_SIGNED_SGIX 0x85EB
+#define GL_RGB_EXTENDED_RANGE_SGIX 0x85EC
+#define GL_RGBA_EXTENDED_RANGE_SGIX 0x85ED
+#define GL_ALPHA_EXTENDED_RANGE_SGIX 0x85EE
+#define GL_LUMINANCE_EXTENDED_RANGE_SGIX 0x85EF
+#define GL_INTENSITY_EXTENDED_RANGE_SGIX 0x85F0
+#define GL_LUMINANCE_ALPHA_EXTENDED_RANGE_SGIX 0x85F1
+#define GL_RGB16_EXTENDED_RANGE_SGIX 0x85F2
+#define GL_RGBA16_EXTENDED_RANGE_SGIX 0x85F3
+#define GL_ALPHA16_EXTENDED_RANGE_SGIX 0x85F4
+#define GL_LUMINANCE16_EXTENDED_RANGE_SGIX 0x85F5
+#define GL_INTENSITY16_EXTENDED_RANGE_SGIX 0x85F6
+#define GL_LUMINANCE16_ALPHA16_EXTENDED_RANGE_SGIX 0x85F7
+#define GL_MIN_LUMINANCE_SGIS 0x85F8
+#define GL_MAX_LUMINANCE_SGIS 0x85F9
+#define GL_MIN_INTENSITY_SGIS 0x85FA
+#define GL_MAX_INTENSITY_SGIS 0x85FB
+
+#define GLEW_SGIX_texture_range GLEW_GET_VAR(__GLEW_SGIX_texture_range)
+
+#endif /* GL_SGIX_texture_range */
+
+/* ----------------------- GL_SGIX_texture_scale_bias ---------------------- */
+
+#ifndef GL_SGIX_texture_scale_bias
+#define GL_SGIX_texture_scale_bias 1
+
+#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179
+#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A
+#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B
+#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C
+
+#define GLEW_SGIX_texture_scale_bias GLEW_GET_VAR(__GLEW_SGIX_texture_scale_bias)
+
+#endif /* GL_SGIX_texture_scale_bias */
+
+/* ------------------------- GL_SGIX_vertex_preclip ------------------------ */
+
+#ifndef GL_SGIX_vertex_preclip
+#define GL_SGIX_vertex_preclip 1
+
+#define GL_VERTEX_PRECLIP_SGIX 0x83EE
+#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF
+
+#define GLEW_SGIX_vertex_preclip GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip)
+
+#endif /* GL_SGIX_vertex_preclip */
+
+/* ---------------------- GL_SGIX_vertex_preclip_hint ---------------------- */
+
+#ifndef GL_SGIX_vertex_preclip_hint
+#define GL_SGIX_vertex_preclip_hint 1
+
+#define GL_VERTEX_PRECLIP_SGIX 0x83EE
+#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF
+
+#define GLEW_SGIX_vertex_preclip_hint GLEW_GET_VAR(__GLEW_SGIX_vertex_preclip_hint)
+
+#endif /* GL_SGIX_vertex_preclip_hint */
+
+/* ----------------------------- GL_SGIX_ycrcb ----------------------------- */
+
+#ifndef GL_SGIX_ycrcb
+#define GL_SGIX_ycrcb 1
+
+#define GLEW_SGIX_ycrcb GLEW_GET_VAR(__GLEW_SGIX_ycrcb)
+
+#endif /* GL_SGIX_ycrcb */
+
+/* -------------------------- GL_SGI_color_matrix -------------------------- */
+
+#ifndef GL_SGI_color_matrix
+#define GL_SGI_color_matrix 1
+
+#define GL_COLOR_MATRIX_SGI 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB
+
+#define GLEW_SGI_color_matrix GLEW_GET_VAR(__GLEW_SGI_color_matrix)
+
+#endif /* GL_SGI_color_matrix */
+
+/* --------------------------- GL_SGI_color_table -------------------------- */
+
+#ifndef GL_SGI_color_table
+#define GL_SGI_color_table 1
+
+#define GL_COLOR_TABLE_SGI 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2
+#define GL_PROXY_COLOR_TABLE_SGI 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5
+#define GL_COLOR_TABLE_SCALE_SGI 0x80D6
+#define GL_COLOR_TABLE_BIAS_SGI 0x80D7
+#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8
+#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF
+
+typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint* params);
+typedef void (GLAPIENTRY * PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat* params);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint* params);
+typedef void (GLAPIENTRY * PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+
+#define glColorTableParameterfvSGI GLEW_GET_FUN(__glewColorTableParameterfvSGI)
+#define glColorTableParameterivSGI GLEW_GET_FUN(__glewColorTableParameterivSGI)
+#define glColorTableSGI GLEW_GET_FUN(__glewColorTableSGI)
+#define glCopyColorTableSGI GLEW_GET_FUN(__glewCopyColorTableSGI)
+#define glGetColorTableParameterfvSGI GLEW_GET_FUN(__glewGetColorTableParameterfvSGI)
+#define glGetColorTableParameterivSGI GLEW_GET_FUN(__glewGetColorTableParameterivSGI)
+#define glGetColorTableSGI GLEW_GET_FUN(__glewGetColorTableSGI)
+
+#define GLEW_SGI_color_table GLEW_GET_VAR(__GLEW_SGI_color_table)
+
+#endif /* GL_SGI_color_table */
+
+/* ----------------------- GL_SGI_texture_color_table ---------------------- */
+
+#ifndef GL_SGI_texture_color_table
+#define GL_SGI_texture_color_table 1
+
+#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC
+#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD
+
+#define GLEW_SGI_texture_color_table GLEW_GET_VAR(__GLEW_SGI_texture_color_table)
+
+#endif /* GL_SGI_texture_color_table */
+
+/* ------------------------- GL_SUNX_constant_data ------------------------- */
+
+#ifndef GL_SUNX_constant_data
+#define GL_SUNX_constant_data 1
+
+#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5
+#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6
+
+typedef void (GLAPIENTRY * PFNGLFINISHTEXTURESUNXPROC) (void);
+
+#define glFinishTextureSUNX GLEW_GET_FUN(__glewFinishTextureSUNX)
+
+#define GLEW_SUNX_constant_data GLEW_GET_VAR(__GLEW_SUNX_constant_data)
+
+#endif /* GL_SUNX_constant_data */
+
+/* -------------------- GL_SUN_convolution_border_modes -------------------- */
+
+#ifndef GL_SUN_convolution_border_modes
+#define GL_SUN_convolution_border_modes 1
+
+#define GL_WRAP_BORDER_SUN 0x81D4
+
+#define GLEW_SUN_convolution_border_modes GLEW_GET_VAR(__GLEW_SUN_convolution_border_modes)
+
+#endif /* GL_SUN_convolution_border_modes */
+
+/* -------------------------- GL_SUN_global_alpha -------------------------- */
+
+#ifndef GL_SUN_global_alpha
+#define GL_SUN_global_alpha 1
+
+#define GL_GLOBAL_ALPHA_SUN 0x81D9
+#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA
+
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor);
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor);
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor);
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor);
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor);
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor);
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor);
+typedef void (GLAPIENTRY * PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor);
+
+#define glGlobalAlphaFactorbSUN GLEW_GET_FUN(__glewGlobalAlphaFactorbSUN)
+#define glGlobalAlphaFactordSUN GLEW_GET_FUN(__glewGlobalAlphaFactordSUN)
+#define glGlobalAlphaFactorfSUN GLEW_GET_FUN(__glewGlobalAlphaFactorfSUN)
+#define glGlobalAlphaFactoriSUN GLEW_GET_FUN(__glewGlobalAlphaFactoriSUN)
+#define glGlobalAlphaFactorsSUN GLEW_GET_FUN(__glewGlobalAlphaFactorsSUN)
+#define glGlobalAlphaFactorubSUN GLEW_GET_FUN(__glewGlobalAlphaFactorubSUN)
+#define glGlobalAlphaFactoruiSUN GLEW_GET_FUN(__glewGlobalAlphaFactoruiSUN)
+#define glGlobalAlphaFactorusSUN GLEW_GET_FUN(__glewGlobalAlphaFactorusSUN)
+
+#define GLEW_SUN_global_alpha GLEW_GET_VAR(__GLEW_SUN_global_alpha)
+
+#endif /* GL_SUN_global_alpha */
+
+/* --------------------------- GL_SUN_mesh_array --------------------------- */
+
+#ifndef GL_SUN_mesh_array
+#define GL_SUN_mesh_array 1
+
+#define GL_QUAD_MESH_SUN 0x8614
+#define GL_TRIANGLE_MESH_SUN 0x8615
+
+#define GLEW_SUN_mesh_array GLEW_GET_VAR(__GLEW_SUN_mesh_array)
+
+#endif /* GL_SUN_mesh_array */
+
+/* ------------------------ GL_SUN_read_video_pixels ----------------------- */
+
+#ifndef GL_SUN_read_video_pixels
+#define GL_SUN_read_video_pixels 1
+
+typedef void (GLAPIENTRY * PFNGLREADVIDEOPIXELSSUNPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+
+#define glReadVideoPixelsSUN GLEW_GET_FUN(__glewReadVideoPixelsSUN)
+
+#define GLEW_SUN_read_video_pixels GLEW_GET_VAR(__GLEW_SUN_read_video_pixels)
+
+#endif /* GL_SUN_read_video_pixels */
+
+/* --------------------------- GL_SUN_slice_accum -------------------------- */
+
+#ifndef GL_SUN_slice_accum
+#define GL_SUN_slice_accum 1
+
+#define GL_SLICE_ACCUM_SUN 0x85CC
+
+#define GLEW_SUN_slice_accum GLEW_GET_VAR(__GLEW_SUN_slice_accum)
+
+#endif /* GL_SUN_slice_accum */
+
+/* -------------------------- GL_SUN_triangle_list ------------------------- */
+
+#ifndef GL_SUN_triangle_list
+#define GL_SUN_triangle_list 1
+
+#define GL_RESTART_SUN 0x01
+#define GL_REPLACE_MIDDLE_SUN 0x02
+#define GL_REPLACE_OLDEST_SUN 0x03
+#define GL_TRIANGLE_LIST_SUN 0x81D7
+#define GL_REPLACEMENT_CODE_SUN 0x81D8
+#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0
+#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1
+#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2
+#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3
+#define GL_R1UI_V3F_SUN 0x85C4
+#define GL_R1UI_C4UB_V3F_SUN 0x85C5
+#define GL_R1UI_C3F_V3F_SUN 0x85C6
+#define GL_R1UI_N3F_V3F_SUN 0x85C7
+#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8
+#define GL_R1UI_T2F_V3F_SUN 0x85C9
+#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA
+#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB
+
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte* code);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint* code);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort* code);
+
+#define glReplacementCodePointerSUN GLEW_GET_FUN(__glewReplacementCodePointerSUN)
+#define glReplacementCodeubSUN GLEW_GET_FUN(__glewReplacementCodeubSUN)
+#define glReplacementCodeubvSUN GLEW_GET_FUN(__glewReplacementCodeubvSUN)
+#define glReplacementCodeuiSUN GLEW_GET_FUN(__glewReplacementCodeuiSUN)
+#define glReplacementCodeuivSUN GLEW_GET_FUN(__glewReplacementCodeuivSUN)
+#define glReplacementCodeusSUN GLEW_GET_FUN(__glewReplacementCodeusSUN)
+#define glReplacementCodeusvSUN GLEW_GET_FUN(__glewReplacementCodeusvSUN)
+
+#define GLEW_SUN_triangle_list GLEW_GET_VAR(__GLEW_SUN_triangle_list)
+
+#endif /* GL_SUN_triangle_list */
+
+/* ----------------------------- GL_SUN_vertex ----------------------------- */
+
+#ifndef GL_SUN_vertex
+#define GL_SUN_vertex 1
+
+typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* c, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y);
+typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte* c, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte* c, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint* rc, const GLubyte *c, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *tc, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint* rc, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat* tc, const GLubyte *c, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat* tc, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GLAPIENTRY * PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat* tc, const GLfloat *v);
+
+#define glColor3fVertex3fSUN GLEW_GET_FUN(__glewColor3fVertex3fSUN)
+#define glColor3fVertex3fvSUN GLEW_GET_FUN(__glewColor3fVertex3fvSUN)
+#define glColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fSUN)
+#define glColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewColor4fNormal3fVertex3fvSUN)
+#define glColor4ubVertex2fSUN GLEW_GET_FUN(__glewColor4ubVertex2fSUN)
+#define glColor4ubVertex2fvSUN GLEW_GET_FUN(__glewColor4ubVertex2fvSUN)
+#define glColor4ubVertex3fSUN GLEW_GET_FUN(__glewColor4ubVertex3fSUN)
+#define glColor4ubVertex3fvSUN GLEW_GET_FUN(__glewColor4ubVertex3fvSUN)
+#define glNormal3fVertex3fSUN GLEW_GET_FUN(__glewNormal3fVertex3fSUN)
+#define glNormal3fVertex3fvSUN GLEW_GET_FUN(__glewNormal3fVertex3fvSUN)
+#define glReplacementCodeuiColor3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fSUN)
+#define glReplacementCodeuiColor3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor3fVertex3fvSUN)
+#define glReplacementCodeuiColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fSUN)
+#define glReplacementCodeuiColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4fNormal3fVertex3fvSUN)
+#define glReplacementCodeuiColor4ubVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fSUN)
+#define glReplacementCodeuiColor4ubVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiColor4ubVertex3fvSUN)
+#define glReplacementCodeuiNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fSUN)
+#define glReplacementCodeuiNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiNormal3fVertex3fvSUN)
+#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN)
+#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN)
+#define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN)
+#define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN)
+#define glReplacementCodeuiTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fSUN)
+#define glReplacementCodeuiTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiTexCoord2fVertex3fvSUN)
+#define glReplacementCodeuiVertex3fSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fSUN)
+#define glReplacementCodeuiVertex3fvSUN GLEW_GET_FUN(__glewReplacementCodeuiVertex3fvSUN)
+#define glTexCoord2fColor3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fSUN)
+#define glTexCoord2fColor3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor3fVertex3fvSUN)
+#define glTexCoord2fColor4fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fSUN)
+#define glTexCoord2fColor4fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4fNormal3fVertex3fvSUN)
+#define glTexCoord2fColor4ubVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fSUN)
+#define glTexCoord2fColor4ubVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fColor4ubVertex3fvSUN)
+#define glTexCoord2fNormal3fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fSUN)
+#define glTexCoord2fNormal3fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fNormal3fVertex3fvSUN)
+#define glTexCoord2fVertex3fSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fSUN)
+#define glTexCoord2fVertex3fvSUN GLEW_GET_FUN(__glewTexCoord2fVertex3fvSUN)
+#define glTexCoord4fColor4fNormal3fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fSUN)
+#define glTexCoord4fColor4fNormal3fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fColor4fNormal3fVertex4fvSUN)
+#define glTexCoord4fVertex4fSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fSUN)
+#define glTexCoord4fVertex4fvSUN GLEW_GET_FUN(__glewTexCoord4fVertex4fvSUN)
+
+#define GLEW_SUN_vertex GLEW_GET_VAR(__GLEW_SUN_vertex)
+
+#endif /* GL_SUN_vertex */
+
+/* -------------------------- GL_WIN_phong_shading ------------------------- */
+
+#ifndef GL_WIN_phong_shading
+#define GL_WIN_phong_shading 1
+
+#define GL_PHONG_WIN 0x80EA
+#define GL_PHONG_HINT_WIN 0x80EB
+
+#define GLEW_WIN_phong_shading GLEW_GET_VAR(__GLEW_WIN_phong_shading)
+
+#endif /* GL_WIN_phong_shading */
+
+/* -------------------------- GL_WIN_specular_fog -------------------------- */
+
+#ifndef GL_WIN_specular_fog
+#define GL_WIN_specular_fog 1
+
+#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC
+
+#define GLEW_WIN_specular_fog GLEW_GET_VAR(__GLEW_WIN_specular_fog)
+
+#endif /* GL_WIN_specular_fog */
+
+/* ---------------------------- GL_WIN_swap_hint --------------------------- */
+
+#ifndef GL_WIN_swap_hint
+#define GL_WIN_swap_hint 1
+
+typedef void (GLAPIENTRY * PFNGLADDSWAPHINTRECTWINPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+
+#define glAddSwapHintRectWIN GLEW_GET_FUN(__glewAddSwapHintRectWIN)
+
+#define GLEW_WIN_swap_hint GLEW_GET_VAR(__GLEW_WIN_swap_hint)
+
+#endif /* GL_WIN_swap_hint */
+
+/* ------------------------------------------------------------------------- */
+
+#if defined(GLEW_MX) && defined(_WIN32)
+#define GLEW_FUN_EXPORT
+#else
+#define GLEW_FUN_EXPORT GLEWAPI
+#endif /* GLEW_MX */
+
+#if defined(GLEW_MX)
+#define GLEW_VAR_EXPORT
+#else
+#define GLEW_VAR_EXPORT GLEWAPI
+#endif /* GLEW_MX */
+
+#if defined(GLEW_MX) && defined(_WIN32)
+struct GLEWContextStruct
+{
+#endif /* GLEW_MX */
+
+#ifdef GLEW_INIT_OPENGL11_FUNCTIONS
+
+GLEW_FUN_EXPORT PFNGLACCUMPROC __glewAccum;
+GLEW_FUN_EXPORT PFNGLALPHAFUNCPROC __glewAlphaFunc;
+GLEW_FUN_EXPORT PFNGLARETEXTURESRESIDENTPROC __glewAreTexturesResident;
+GLEW_FUN_EXPORT PFNGLARRAYELEMENTPROC __glewArrayElement;
+GLEW_FUN_EXPORT PFNGLBEGINPROC __glewBegin;
+GLEW_FUN_EXPORT PFNGLBINDTEXTUREPROC __glewBindTexture;
+GLEW_FUN_EXPORT PFNGLBITMAPPROC __glewBitmap;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCPROC __glewBlendFunc;
+GLEW_FUN_EXPORT PFNGLCALLLISTPROC __glewCallList;
+GLEW_FUN_EXPORT PFNGLCALLLISTSPROC __glewCallLists;
+GLEW_FUN_EXPORT PFNGLCLEARPROC __glewClear;
+GLEW_FUN_EXPORT PFNGLCLEARACCUMPROC __glewClearAccum;
+GLEW_FUN_EXPORT PFNGLCLEARCOLORPROC __glewClearColor;
+GLEW_FUN_EXPORT PFNGLCLEARDEPTHPROC __glewClearDepth;
+GLEW_FUN_EXPORT PFNGLCLEARINDEXPROC __glewClearIndex;
+GLEW_FUN_EXPORT PFNGLCLEARSTENCILPROC __glewClearStencil;
+GLEW_FUN_EXPORT PFNGLCLIPPLANEPROC __glewClipPlane;
+GLEW_FUN_EXPORT PFNGLCOLOR3BPROC __glewColor3b;
+GLEW_FUN_EXPORT PFNGLCOLOR3BVPROC __glewColor3bv;
+GLEW_FUN_EXPORT PFNGLCOLOR3DPROC __glewColor3d;
+GLEW_FUN_EXPORT PFNGLCOLOR3DVPROC __glewColor3dv;
+GLEW_FUN_EXPORT PFNGLCOLOR3FPROC __glewColor3f;
+GLEW_FUN_EXPORT PFNGLCOLOR3FVPROC __glewColor3fv;
+GLEW_FUN_EXPORT PFNGLCOLOR3IPROC __glewColor3i;
+GLEW_FUN_EXPORT PFNGLCOLOR3IVPROC __glewColor3iv;
+GLEW_FUN_EXPORT PFNGLCOLOR3SPROC __glewColor3s;
+GLEW_FUN_EXPORT PFNGLCOLOR3SVPROC __glewColor3sv;
+GLEW_FUN_EXPORT PFNGLCOLOR3UBPROC __glewColor3ub;
+GLEW_FUN_EXPORT PFNGLCOLOR3UBVPROC __glewColor3ubv;
+GLEW_FUN_EXPORT PFNGLCOLOR3UIPROC __glewColor3ui;
+GLEW_FUN_EXPORT PFNGLCOLOR3UIVPROC __glewColor3uiv;
+GLEW_FUN_EXPORT PFNGLCOLOR3USPROC __glewColor3us;
+GLEW_FUN_EXPORT PFNGLCOLOR3USVPROC __glewColor3usv;
+GLEW_FUN_EXPORT PFNGLCOLOR4BPROC __glewColor4b;
+GLEW_FUN_EXPORT PFNGLCOLOR4BVPROC __glewColor4bv;
+GLEW_FUN_EXPORT PFNGLCOLOR4DPROC __glewColor4d;
+GLEW_FUN_EXPORT PFNGLCOLOR4DVPROC __glewColor4dv;
+GLEW_FUN_EXPORT PFNGLCOLOR4FPROC __glewColor4f;
+GLEW_FUN_EXPORT PFNGLCOLOR4FVPROC __glewColor4fv;
+GLEW_FUN_EXPORT PFNGLCOLOR4IPROC __glewColor4i;
+GLEW_FUN_EXPORT PFNGLCOLOR4IVPROC __glewColor4iv;
+GLEW_FUN_EXPORT PFNGLCOLOR4SPROC __glewColor4s;
+GLEW_FUN_EXPORT PFNGLCOLOR4SVPROC __glewColor4sv;
+GLEW_FUN_EXPORT PFNGLCOLOR4UBPROC __glewColor4ub;
+GLEW_FUN_EXPORT PFNGLCOLOR4UBVPROC __glewColor4ubv;
+GLEW_FUN_EXPORT PFNGLCOLOR4UIPROC __glewColor4ui;
+GLEW_FUN_EXPORT PFNGLCOLOR4UIVPROC __glewColor4uiv;
+GLEW_FUN_EXPORT PFNGLCOLOR4USPROC __glewColor4us;
+GLEW_FUN_EXPORT PFNGLCOLOR4USVPROC __glewColor4usv;
+GLEW_FUN_EXPORT PFNGLCOLORMASKPROC __glewColorMask;
+GLEW_FUN_EXPORT PFNGLCOLORMATERIALPROC __glewColorMaterial;
+GLEW_FUN_EXPORT PFNGLCOLORPOINTERPROC __glewColorPointer;
+GLEW_FUN_EXPORT PFNGLCOPYPIXELSPROC __glewCopyPixels;
+GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE1DPROC __glewCopyTexImage1D;
+GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE2DPROC __glewCopyTexImage2D;
+GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE1DPROC __glewCopyTexSubImage1D;
+GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE2DPROC __glewCopyTexSubImage2D;
+GLEW_FUN_EXPORT PFNGLCULLFACEPROC __glewCullFace;
+GLEW_FUN_EXPORT PFNGLDELETELISTSPROC __glewDeleteLists;
+GLEW_FUN_EXPORT PFNGLDELETETEXTURESPROC __glewDeleteTextures;
+GLEW_FUN_EXPORT PFNGLDEPTHFUNCPROC __glewDepthFunc;
+GLEW_FUN_EXPORT PFNGLDEPTHMASKPROC __glewDepthMask;
+GLEW_FUN_EXPORT PFNGLDEPTHRANGEPROC __glewDepthRange;
+GLEW_FUN_EXPORT PFNGLDISABLEPROC __glewDisable;
+GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEPROC __glewDisableClientState;
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSPROC __glewDrawArrays;
+GLEW_FUN_EXPORT PFNGLDRAWBUFFERPROC __glewDrawBuffer;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSPROC __glewDrawElements;
+GLEW_FUN_EXPORT PFNGLDRAWPIXELSPROC __glewDrawPixels;
+GLEW_FUN_EXPORT PFNGLEDGEFLAGPROC __glewEdgeFlag;
+GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTERPROC __glewEdgeFlagPointer;
+GLEW_FUN_EXPORT PFNGLEDGEFLAGVPROC __glewEdgeFlagv;
+GLEW_FUN_EXPORT PFNGLENABLEPROC __glewEnable;
+GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEPROC __glewEnableClientState;
+GLEW_FUN_EXPORT PFNGLENDPROC __glewEnd;
+GLEW_FUN_EXPORT PFNGLENDLISTPROC __glewEndList;
+GLEW_FUN_EXPORT PFNGLEVALCOORD1DPROC __glewEvalCoord1d;
+GLEW_FUN_EXPORT PFNGLEVALCOORD1DVPROC __glewEvalCoord1dv;
+GLEW_FUN_EXPORT PFNGLEVALCOORD1FPROC __glewEvalCoord1f;
+GLEW_FUN_EXPORT PFNGLEVALCOORD1FVPROC __glewEvalCoord1fv;
+GLEW_FUN_EXPORT PFNGLEVALCOORD2DPROC __glewEvalCoord2d;
+GLEW_FUN_EXPORT PFNGLEVALCOORD2DVPROC __glewEvalCoord2dv;
+GLEW_FUN_EXPORT PFNGLEVALCOORD2FPROC __glewEvalCoord2f;
+GLEW_FUN_EXPORT PFNGLEVALCOORD2FVPROC __glewEvalCoord2fv;
+GLEW_FUN_EXPORT PFNGLEVALMESH1PROC __glewEvalMesh1;
+GLEW_FUN_EXPORT PFNGLEVALMESH2PROC __glewEvalMesh2;
+GLEW_FUN_EXPORT PFNGLEVALPOINT1PROC __glewEvalPoint1;
+GLEW_FUN_EXPORT PFNGLEVALPOINT2PROC __glewEvalPoint2;
+GLEW_FUN_EXPORT PFNGLFEEDBACKBUFFERPROC __glewFeedbackBuffer;
+GLEW_FUN_EXPORT PFNGLFINISHPROC __glewFinish;
+GLEW_FUN_EXPORT PFNGLFLUSHPROC __glewFlush;
+GLEW_FUN_EXPORT PFNGLFOGFPROC __glewFogf;
+GLEW_FUN_EXPORT PFNGLFOGFVPROC __glewFogfv;
+GLEW_FUN_EXPORT PFNGLFOGIPROC __glewFogi;
+GLEW_FUN_EXPORT PFNGLFOGIVPROC __glewFogiv;
+GLEW_FUN_EXPORT PFNGLFRONTFACEPROC __glewFrontFace;
+GLEW_FUN_EXPORT PFNGLFRUSTUMPROC __glewFrustum;
+GLEW_FUN_EXPORT PFNGLGENLISTSPROC __glewGenLists;
+GLEW_FUN_EXPORT PFNGLGENTEXTURESPROC __glewGenTextures;
+GLEW_FUN_EXPORT PFNGLGETBOOLEANVPROC __glewGetBooleanv;
+GLEW_FUN_EXPORT PFNGLGETCLIPPLANEPROC __glewGetClipPlane;
+GLEW_FUN_EXPORT PFNGLGETDOUBLEVPROC __glewGetDoublev;
+GLEW_FUN_EXPORT PFNGLGETERRORPROC __glewGetError;
+GLEW_FUN_EXPORT PFNGLGETFLOATVPROC __glewGetFloatv;
+GLEW_FUN_EXPORT PFNGLGETINTEGERVPROC __glewGetIntegerv;
+GLEW_FUN_EXPORT PFNGLGETLIGHTFVPROC __glewGetLightfv;
+GLEW_FUN_EXPORT PFNGLGETLIGHTIVPROC __glewGetLightiv;
+GLEW_FUN_EXPORT PFNGLGETMAPDVPROC __glewGetMapdv;
+GLEW_FUN_EXPORT PFNGLGETMAPFVPROC __glewGetMapfv;
+GLEW_FUN_EXPORT PFNGLGETMAPIVPROC __glewGetMapiv;
+GLEW_FUN_EXPORT PFNGLGETMATERIALFVPROC __glewGetMaterialfv;
+GLEW_FUN_EXPORT PFNGLGETMATERIALIVPROC __glewGetMaterialiv;
+GLEW_FUN_EXPORT PFNGLGETPIXELMAPFVPROC __glewGetPixelMapfv;
+GLEW_FUN_EXPORT PFNGLGETPIXELMAPUIVPROC __glewGetPixelMapuiv;
+GLEW_FUN_EXPORT PFNGLGETPIXELMAPUSVPROC __glewGetPixelMapusv;
+GLEW_FUN_EXPORT PFNGLGETPOINTERVPROC __glewGetPointerv;
+GLEW_FUN_EXPORT PFNGLGETPOLYGONSTIPPLEPROC __glewGetPolygonStipple;
+GLEW_FUN_EXPORT PFNGLGETSTRINGPROC __glewGetString;
+GLEW_FUN_EXPORT PFNGLGETTEXENVFVPROC __glewGetTexEnvfv;
+GLEW_FUN_EXPORT PFNGLGETTEXENVIVPROC __glewGetTexEnviv;
+GLEW_FUN_EXPORT PFNGLGETTEXGENDVPROC __glewGetTexGendv;
+GLEW_FUN_EXPORT PFNGLGETTEXGENFVPROC __glewGetTexGenfv;
+GLEW_FUN_EXPORT PFNGLGETTEXGENIVPROC __glewGetTexGeniv;
+GLEW_FUN_EXPORT PFNGLGETTEXIMAGEPROC __glewGetTexImage;
+GLEW_FUN_EXPORT PFNGLGETTEXLEVELPARAMETERFVPROC __glewGetTexLevelParameterfv;
+GLEW_FUN_EXPORT PFNGLGETTEXLEVELPARAMETERIVPROC __glewGetTexLevelParameteriv;
+GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERFVPROC __glewGetTexParameterfv;
+GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIVPROC __glewGetTexParameteriv;
+GLEW_FUN_EXPORT PFNGLHINTPROC __glewHint;
+GLEW_FUN_EXPORT PFNGLINDEXMASKPROC __glewIndexMask;
+GLEW_FUN_EXPORT PFNGLINDEXPOINTERPROC __glewIndexPointer;
+GLEW_FUN_EXPORT PFNGLINDEXDPROC __glewIndexd;
+GLEW_FUN_EXPORT PFNGLINDEXDVPROC __glewIndexdv;
+GLEW_FUN_EXPORT PFNGLINDEXFPROC __glewIndexf;
+GLEW_FUN_EXPORT PFNGLINDEXFVPROC __glewIndexfv;
+GLEW_FUN_EXPORT PFNGLINDEXIPROC __glewIndexi;
+GLEW_FUN_EXPORT PFNGLINDEXIVPROC __glewIndexiv;
+GLEW_FUN_EXPORT PFNGLINDEXSPROC __glewIndexs;
+GLEW_FUN_EXPORT PFNGLINDEXSVPROC __glewIndexsv;
+GLEW_FUN_EXPORT PFNGLINDEXUBPROC __glewIndexub;
+GLEW_FUN_EXPORT PFNGLINDEXUBVPROC __glewIndexubv;
+GLEW_FUN_EXPORT PFNGLINITNAMESPROC __glewInitNames;
+GLEW_FUN_EXPORT PFNGLINTERLEAVEDARRAYSPROC __glewInterleavedArrays;
+GLEW_FUN_EXPORT PFNGLISENABLEDPROC __glewIsEnabled;
+GLEW_FUN_EXPORT PFNGLISLISTPROC __glewIsList;
+GLEW_FUN_EXPORT PFNGLISTEXTUREPROC __glewIsTexture;
+GLEW_FUN_EXPORT PFNGLLIGHTMODELFPROC __glewLightModelf;
+GLEW_FUN_EXPORT PFNGLLIGHTMODELFVPROC __glewLightModelfv;
+GLEW_FUN_EXPORT PFNGLLIGHTMODELIPROC __glewLightModeli;
+GLEW_FUN_EXPORT PFNGLLIGHTMODELIVPROC __glewLightModeliv;
+GLEW_FUN_EXPORT PFNGLLIGHTFPROC __glewLightf;
+GLEW_FUN_EXPORT PFNGLLIGHTFVPROC __glewLightfv;
+GLEW_FUN_EXPORT PFNGLLIGHTIPROC __glewLighti;
+GLEW_FUN_EXPORT PFNGLLIGHTIVPROC __glewLightiv;
+GLEW_FUN_EXPORT PFNGLLINESTIPPLEPROC __glewLineStipple;
+GLEW_FUN_EXPORT PFNGLLINEWIDTHPROC __glewLineWidth;
+GLEW_FUN_EXPORT PFNGLLISTBASEPROC __glewListBase;
+GLEW_FUN_EXPORT PFNGLLOADIDENTITYPROC __glewLoadIdentity;
+GLEW_FUN_EXPORT PFNGLLOADMATRIXDPROC __glewLoadMatrixd;
+GLEW_FUN_EXPORT PFNGLLOADMATRIXFPROC __glewLoadMatrixf;
+GLEW_FUN_EXPORT PFNGLLOADNAMEPROC __glewLoadName;
+GLEW_FUN_EXPORT PFNGLLOGICOPPROC __glewLogicOp;
+GLEW_FUN_EXPORT PFNGLMAP1DPROC __glewMap1d;
+GLEW_FUN_EXPORT PFNGLMAP1FPROC __glewMap1f;
+GLEW_FUN_EXPORT PFNGLMAP2DPROC __glewMap2d;
+GLEW_FUN_EXPORT PFNGLMAP2FPROC __glewMap2f;
+GLEW_FUN_EXPORT PFNGLMAPGRID1DPROC __glewMapGrid1d;
+GLEW_FUN_EXPORT PFNGLMAPGRID1FPROC __glewMapGrid1f;
+GLEW_FUN_EXPORT PFNGLMAPGRID2DPROC __glewMapGrid2d;
+GLEW_FUN_EXPORT PFNGLMAPGRID2FPROC __glewMapGrid2f;
+GLEW_FUN_EXPORT PFNGLMATERIALFPROC __glewMaterialf;
+GLEW_FUN_EXPORT PFNGLMATERIALFVPROC __glewMaterialfv;
+GLEW_FUN_EXPORT PFNGLMATERIALIPROC __glewMateriali;
+GLEW_FUN_EXPORT PFNGLMATERIALIVPROC __glewMaterialiv;
+GLEW_FUN_EXPORT PFNGLMATRIXMODEPROC __glewMatrixMode;
+GLEW_FUN_EXPORT PFNGLMULTMATRIXDPROC __glewMultMatrixd;
+GLEW_FUN_EXPORT PFNGLMULTMATRIXFPROC __glewMultMatrixf;
+GLEW_FUN_EXPORT PFNGLNEWLISTPROC __glewNewList;
+GLEW_FUN_EXPORT PFNGLNORMAL3BPROC __glewNormal3b;
+GLEW_FUN_EXPORT PFNGLNORMAL3BVPROC __glewNormal3bv;
+GLEW_FUN_EXPORT PFNGLNORMAL3DPROC __glewNormal3d;
+GLEW_FUN_EXPORT PFNGLNORMAL3DVPROC __glewNormal3dv;
+GLEW_FUN_EXPORT PFNGLNORMAL3FPROC __glewNormal3f;
+GLEW_FUN_EXPORT PFNGLNORMAL3FVPROC __glewNormal3fv;
+GLEW_FUN_EXPORT PFNGLNORMAL3IPROC __glewNormal3i;
+GLEW_FUN_EXPORT PFNGLNORMAL3IVPROC __glewNormal3iv;
+GLEW_FUN_EXPORT PFNGLNORMAL3SPROC __glewNormal3s;
+GLEW_FUN_EXPORT PFNGLNORMAL3SVPROC __glewNormal3sv;
+GLEW_FUN_EXPORT PFNGLNORMALPOINTERPROC __glewNormalPointer;
+GLEW_FUN_EXPORT PFNGLORTHOPROC __glewOrtho;
+GLEW_FUN_EXPORT PFNGLPASSTHROUGHPROC __glewPassThrough;
+GLEW_FUN_EXPORT PFNGLPIXELMAPFVPROC __glewPixelMapfv;
+GLEW_FUN_EXPORT PFNGLPIXELMAPUIVPROC __glewPixelMapuiv;
+GLEW_FUN_EXPORT PFNGLPIXELMAPUSVPROC __glewPixelMapusv;
+GLEW_FUN_EXPORT PFNGLPIXELSTOREFPROC __glewPixelStoref;
+GLEW_FUN_EXPORT PFNGLPIXELSTOREIPROC __glewPixelStorei;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFERFPROC __glewPixelTransferf;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFERIPROC __glewPixelTransferi;
+GLEW_FUN_EXPORT PFNGLPIXELZOOMPROC __glewPixelZoom;
+GLEW_FUN_EXPORT PFNGLPOINTSIZEPROC __glewPointSize;
+GLEW_FUN_EXPORT PFNGLPOLYGONMODEPROC __glewPolygonMode;
+GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETPROC __glewPolygonOffset;
+GLEW_FUN_EXPORT PFNGLPOLYGONSTIPPLEPROC __glewPolygonStipple;
+GLEW_FUN_EXPORT PFNGLPOPATTRIBPROC __glewPopAttrib;
+GLEW_FUN_EXPORT PFNGLPOPCLIENTATTRIBPROC __glewPopClientAttrib;
+GLEW_FUN_EXPORT PFNGLPOPMATRIXPROC __glewPopMatrix;
+GLEW_FUN_EXPORT PFNGLPOPNAMEPROC __glewPopName;
+GLEW_FUN_EXPORT PFNGLPRIORITIZETEXTURESPROC __glewPrioritizeTextures;
+GLEW_FUN_EXPORT PFNGLPUSHATTRIBPROC __glewPushAttrib;
+GLEW_FUN_EXPORT PFNGLPUSHCLIENTATTRIBPROC __glewPushClientAttrib;
+GLEW_FUN_EXPORT PFNGLPUSHMATRIXPROC __glewPushMatrix;
+GLEW_FUN_EXPORT PFNGLPUSHNAMEPROC __glewPushName;
+GLEW_FUN_EXPORT PFNGLRASTERPOS2DPROC __glewRasterPos2d;
+GLEW_FUN_EXPORT PFNGLRASTERPOS2DVPROC __glewRasterPos2dv;
+GLEW_FUN_EXPORT PFNGLRASTERPOS2FPROC __glewRasterPos2f;
+GLEW_FUN_EXPORT PFNGLRASTERPOS2FVPROC __glewRasterPos2fv;
+GLEW_FUN_EXPORT PFNGLRASTERPOS2IPROC __glewRasterPos2i;
+GLEW_FUN_EXPORT PFNGLRASTERPOS2IVPROC __glewRasterPos2iv;
+GLEW_FUN_EXPORT PFNGLRASTERPOS2SPROC __glewRasterPos2s;
+GLEW_FUN_EXPORT PFNGLRASTERPOS2SVPROC __glewRasterPos2sv;
+GLEW_FUN_EXPORT PFNGLRASTERPOS3DPROC __glewRasterPos3d;
+GLEW_FUN_EXPORT PFNGLRASTERPOS3DVPROC __glewRasterPos3dv;
+GLEW_FUN_EXPORT PFNGLRASTERPOS3FPROC __glewRasterPos3f;
+GLEW_FUN_EXPORT PFNGLRASTERPOS3FVPROC __glewRasterPos3fv;
+GLEW_FUN_EXPORT PFNGLRASTERPOS3IPROC __glewRasterPos3i;
+GLEW_FUN_EXPORT PFNGLRASTERPOS3IVPROC __glewRasterPos3iv;
+GLEW_FUN_EXPORT PFNGLRASTERPOS3SPROC __glewRasterPos3s;
+GLEW_FUN_EXPORT PFNGLRASTERPOS3SVPROC __glewRasterPos3sv;
+GLEW_FUN_EXPORT PFNGLRASTERPOS4DPROC __glewRasterPos4d;
+GLEW_FUN_EXPORT PFNGLRASTERPOS4DVPROC __glewRasterPos4dv;
+GLEW_FUN_EXPORT PFNGLRASTERPOS4FPROC __glewRasterPos4f;
+GLEW_FUN_EXPORT PFNGLRASTERPOS4FVPROC __glewRasterPos4fv;
+GLEW_FUN_EXPORT PFNGLRASTERPOS4IPROC __glewRasterPos4i;
+GLEW_FUN_EXPORT PFNGLRASTERPOS4IVPROC __glewRasterPos4iv;
+GLEW_FUN_EXPORT PFNGLRASTERPOS4SPROC __glewRasterPos4s;
+GLEW_FUN_EXPORT PFNGLRASTERPOS4SVPROC __glewRasterPos4sv;
+GLEW_FUN_EXPORT PFNGLREADBUFFERPROC __glewReadBuffer;
+GLEW_FUN_EXPORT PFNGLREADPIXELSPROC __glewReadPixels;
+GLEW_FUN_EXPORT PFNGLRECTDPROC __glewRectd;
+GLEW_FUN_EXPORT PFNGLRECTDVPROC __glewRectdv;
+GLEW_FUN_EXPORT PFNGLRECTFPROC __glewRectf;
+GLEW_FUN_EXPORT PFNGLRECTFVPROC __glewRectfv;
+GLEW_FUN_EXPORT PFNGLRECTIPROC __glewRecti;
+GLEW_FUN_EXPORT PFNGLRECTIVPROC __glewRectiv;
+GLEW_FUN_EXPORT PFNGLRECTSPROC __glewRects;
+GLEW_FUN_EXPORT PFNGLRECTSVPROC __glewRectsv;
+GLEW_FUN_EXPORT PFNGLRENDERMODEPROC __glewRenderMode;
+GLEW_FUN_EXPORT PFNGLROTATEDPROC __glewRotated;
+GLEW_FUN_EXPORT PFNGLROTATEFPROC __glewRotatef;
+GLEW_FUN_EXPORT PFNGLSCALEDPROC __glewScaled;
+GLEW_FUN_EXPORT PFNGLSCALEFPROC __glewScalef;
+GLEW_FUN_EXPORT PFNGLSCISSORPROC __glewScissor;
+GLEW_FUN_EXPORT PFNGLSELECTBUFFERPROC __glewSelectBuffer;
+GLEW_FUN_EXPORT PFNGLSHADEMODELPROC __glewShadeModel;
+GLEW_FUN_EXPORT PFNGLSTENCILFUNCPROC __glewStencilFunc;
+GLEW_FUN_EXPORT PFNGLSTENCILMASKPROC __glewStencilMask;
+GLEW_FUN_EXPORT PFNGLSTENCILOPPROC __glewStencilOp;
+GLEW_FUN_EXPORT PFNGLTEXCOORD1DPROC __glewTexCoord1d;
+GLEW_FUN_EXPORT PFNGLTEXCOORD1DVPROC __glewTexCoord1dv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD1FPROC __glewTexCoord1f;
+GLEW_FUN_EXPORT PFNGLTEXCOORD1FVPROC __glewTexCoord1fv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD1IPROC __glewTexCoord1i;
+GLEW_FUN_EXPORT PFNGLTEXCOORD1IVPROC __glewTexCoord1iv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD1SPROC __glewTexCoord1s;
+GLEW_FUN_EXPORT PFNGLTEXCOORD1SVPROC __glewTexCoord1sv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2DPROC __glewTexCoord2d;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2DVPROC __glewTexCoord2dv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FPROC __glewTexCoord2f;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FVPROC __glewTexCoord2fv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2IPROC __glewTexCoord2i;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2IVPROC __glewTexCoord2iv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2SPROC __glewTexCoord2s;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2SVPROC __glewTexCoord2sv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD3DPROC __glewTexCoord3d;
+GLEW_FUN_EXPORT PFNGLTEXCOORD3DVPROC __glewTexCoord3dv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD3FPROC __glewTexCoord3f;
+GLEW_FUN_EXPORT PFNGLTEXCOORD3FVPROC __glewTexCoord3fv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD3IPROC __glewTexCoord3i;
+GLEW_FUN_EXPORT PFNGLTEXCOORD3IVPROC __glewTexCoord3iv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD3SPROC __glewTexCoord3s;
+GLEW_FUN_EXPORT PFNGLTEXCOORD3SVPROC __glewTexCoord3sv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4DPROC __glewTexCoord4d;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4DVPROC __glewTexCoord4dv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4FPROC __glewTexCoord4f;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4FVPROC __glewTexCoord4fv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4IPROC __glewTexCoord4i;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4IVPROC __glewTexCoord4iv;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4SPROC __glewTexCoord4s;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4SVPROC __glewTexCoord4sv;
+GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERPROC __glewTexCoordPointer;
+GLEW_FUN_EXPORT PFNGLTEXENVFPROC __glewTexEnvf;
+GLEW_FUN_EXPORT PFNGLTEXENVFVPROC __glewTexEnvfv;
+GLEW_FUN_EXPORT PFNGLTEXENVIPROC __glewTexEnvi;
+GLEW_FUN_EXPORT PFNGLTEXENVIVPROC __glewTexEnviv;
+GLEW_FUN_EXPORT PFNGLTEXGENDPROC __glewTexGend;
+GLEW_FUN_EXPORT PFNGLTEXGENDVPROC __glewTexGendv;
+GLEW_FUN_EXPORT PFNGLTEXGENFPROC __glewTexGenf;
+GLEW_FUN_EXPORT PFNGLTEXGENFVPROC __glewTexGenfv;
+GLEW_FUN_EXPORT PFNGLTEXGENIPROC __glewTexGeni;
+GLEW_FUN_EXPORT PFNGLTEXGENIVPROC __glewTexGeniv;
+GLEW_FUN_EXPORT PFNGLTEXIMAGE1DPROC __glewTexImage1D;
+GLEW_FUN_EXPORT PFNGLTEXIMAGE2DPROC __glewTexImage2D;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERFPROC __glewTexParameterf;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERFVPROC __glewTexParameterfv;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERIPROC __glewTexParameteri;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERIVPROC __glewTexParameteriv;
+GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE1DPROC __glewTexSubImage1D;
+GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE2DPROC __glewTexSubImage2D;
+GLEW_FUN_EXPORT PFNGLTRANSLATEDPROC __glewTranslated;
+GLEW_FUN_EXPORT PFNGLTRANSLATEFPROC __glewTranslatef;
+GLEW_FUN_EXPORT PFNGLVERTEX2DPROC __glewVertex2d;
+GLEW_FUN_EXPORT PFNGLVERTEX2DVPROC __glewVertex2dv;
+GLEW_FUN_EXPORT PFNGLVERTEX2FPROC __glewVertex2f;
+GLEW_FUN_EXPORT PFNGLVERTEX2FVPROC __glewVertex2fv;
+GLEW_FUN_EXPORT PFNGLVERTEX2IPROC __glewVertex2i;
+GLEW_FUN_EXPORT PFNGLVERTEX2IVPROC __glewVertex2iv;
+GLEW_FUN_EXPORT PFNGLVERTEX2SPROC __glewVertex2s;
+GLEW_FUN_EXPORT PFNGLVERTEX2SVPROC __glewVertex2sv;
+GLEW_FUN_EXPORT PFNGLVERTEX3DPROC __glewVertex3d;
+GLEW_FUN_EXPORT PFNGLVERTEX3DVPROC __glewVertex3dv;
+GLEW_FUN_EXPORT PFNGLVERTEX3FPROC __glewVertex3f;
+GLEW_FUN_EXPORT PFNGLVERTEX3FVPROC __glewVertex3fv;
+GLEW_FUN_EXPORT PFNGLVERTEX3IPROC __glewVertex3i;
+GLEW_FUN_EXPORT PFNGLVERTEX3IVPROC __glewVertex3iv;
+GLEW_FUN_EXPORT PFNGLVERTEX3SPROC __glewVertex3s;
+GLEW_FUN_EXPORT PFNGLVERTEX3SVPROC __glewVertex3sv;
+GLEW_FUN_EXPORT PFNGLVERTEX4DPROC __glewVertex4d;
+GLEW_FUN_EXPORT PFNGLVERTEX4DVPROC __glewVertex4dv;
+GLEW_FUN_EXPORT PFNGLVERTEX4FPROC __glewVertex4f;
+GLEW_FUN_EXPORT PFNGLVERTEX4FVPROC __glewVertex4fv;
+GLEW_FUN_EXPORT PFNGLVERTEX4IPROC __glewVertex4i;
+GLEW_FUN_EXPORT PFNGLVERTEX4IVPROC __glewVertex4iv;
+GLEW_FUN_EXPORT PFNGLVERTEX4SPROC __glewVertex4s;
+GLEW_FUN_EXPORT PFNGLVERTEX4SVPROC __glewVertex4sv;
+GLEW_FUN_EXPORT PFNGLVERTEXPOINTERPROC __glewVertexPointer;
+GLEW_FUN_EXPORT PFNGLVIEWPORTPROC __glewViewport;
+#endif //#ifdef GLEW_INIT_OPENGL11_FUNCTIONS
+
+GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D;
+GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements;
+GLEW_FUN_EXPORT PFNGLTEXIMAGE3DPROC __glewTexImage3D;
+GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D;
+
+GLEW_FUN_EXPORT PFNGLACTIVETEXTUREPROC __glewActiveTexture;
+GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D;
+GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage;
+GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd;
+GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf;
+GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd;
+GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv;
+GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage;
+
+GLEW_FUN_EXPORT PFNGLBLENDCOLORPROC __glewBlendColor;
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONPROC __glewBlendEquation;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate;
+GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer;
+GLEW_FUN_EXPORT PFNGLFOGCOORDDPROC __glewFogCoordd;
+GLEW_FUN_EXPORT PFNGLFOGCOORDDVPROC __glewFogCoorddv;
+GLEW_FUN_EXPORT PFNGLFOGCOORDFPROC __glewFogCoordf;
+GLEW_FUN_EXPORT PFNGLFOGCOORDFVPROC __glewFogCoordfv;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFPROC __glewPointParameterf;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIPROC __glewPointParameteri;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2DPROC __glewWindowPos2d;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2FPROC __glewWindowPos2f;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2IPROC __glewWindowPos2i;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2SPROC __glewWindowPos2s;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3DPROC __glewWindowPos3d;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3FPROC __glewWindowPos3f;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3IPROC __glewWindowPos3i;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3SPROC __glewWindowPos3s;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv;
+
+GLEW_FUN_EXPORT PFNGLBEGINQUERYPROC __glewBeginQuery;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERPROC __glewBindBuffer;
+GLEW_FUN_EXPORT PFNGLBUFFERDATAPROC __glewBufferData;
+GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAPROC __glewBufferSubData;
+GLEW_FUN_EXPORT PFNGLDELETEBUFFERSPROC __glewDeleteBuffers;
+GLEW_FUN_EXPORT PFNGLDELETEQUERIESPROC __glewDeleteQueries;
+GLEW_FUN_EXPORT PFNGLENDQUERYPROC __glewEndQuery;
+GLEW_FUN_EXPORT PFNGLGENBUFFERSPROC __glewGenBuffers;
+GLEW_FUN_EXPORT PFNGLGENQUERIESPROC __glewGenQueries;
+GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv;
+GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv;
+GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv;
+GLEW_FUN_EXPORT PFNGLGETQUERYIVPROC __glewGetQueryiv;
+GLEW_FUN_EXPORT PFNGLISBUFFERPROC __glewIsBuffer;
+GLEW_FUN_EXPORT PFNGLISQUERYPROC __glewIsQuery;
+GLEW_FUN_EXPORT PFNGLMAPBUFFERPROC __glewMapBuffer;
+GLEW_FUN_EXPORT PFNGLUNMAPBUFFERPROC __glewUnmapBuffer;
+
+GLEW_FUN_EXPORT PFNGLATTACHSHADERPROC __glewAttachShader;
+GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation;
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate;
+GLEW_FUN_EXPORT PFNGLCOMPILESHADERPROC __glewCompileShader;
+GLEW_FUN_EXPORT PFNGLCREATEPROGRAMPROC __glewCreateProgram;
+GLEW_FUN_EXPORT PFNGLCREATESHADERPROC __glewCreateShader;
+GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPROC __glewDeleteProgram;
+GLEW_FUN_EXPORT PFNGLDELETESHADERPROC __glewDeleteShader;
+GLEW_FUN_EXPORT PFNGLDETACHSHADERPROC __glewDetachShader;
+GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray;
+GLEW_FUN_EXPORT PFNGLDRAWBUFFERSPROC __glewDrawBuffers;
+GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray;
+GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform;
+GLEW_FUN_EXPORT PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders;
+GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMIVPROC __glewGetProgramiv;
+GLEW_FUN_EXPORT PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog;
+GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEPROC __glewGetShaderSource;
+GLEW_FUN_EXPORT PFNGLGETSHADERIVPROC __glewGetShaderiv;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMFVPROC __glewGetUniformfv;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMIVPROC __glewGetUniformiv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv;
+GLEW_FUN_EXPORT PFNGLISPROGRAMPROC __glewIsProgram;
+GLEW_FUN_EXPORT PFNGLISSHADERPROC __glewIsShader;
+GLEW_FUN_EXPORT PFNGLLINKPROGRAMPROC __glewLinkProgram;
+GLEW_FUN_EXPORT PFNGLSHADERSOURCEPROC __glewShaderSource;
+GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate;
+GLEW_FUN_EXPORT PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate;
+GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate;
+GLEW_FUN_EXPORT PFNGLUNIFORM1FPROC __glewUniform1f;
+GLEW_FUN_EXPORT PFNGLUNIFORM1FVPROC __glewUniform1fv;
+GLEW_FUN_EXPORT PFNGLUNIFORM1IPROC __glewUniform1i;
+GLEW_FUN_EXPORT PFNGLUNIFORM1IVPROC __glewUniform1iv;
+GLEW_FUN_EXPORT PFNGLUNIFORM2FPROC __glewUniform2f;
+GLEW_FUN_EXPORT PFNGLUNIFORM2FVPROC __glewUniform2fv;
+GLEW_FUN_EXPORT PFNGLUNIFORM2IPROC __glewUniform2i;
+GLEW_FUN_EXPORT PFNGLUNIFORM2IVPROC __glewUniform2iv;
+GLEW_FUN_EXPORT PFNGLUNIFORM3FPROC __glewUniform3f;
+GLEW_FUN_EXPORT PFNGLUNIFORM3FVPROC __glewUniform3fv;
+GLEW_FUN_EXPORT PFNGLUNIFORM3IPROC __glewUniform3i;
+GLEW_FUN_EXPORT PFNGLUNIFORM3IVPROC __glewUniform3iv;
+GLEW_FUN_EXPORT PFNGLUNIFORM4FPROC __glewUniform4f;
+GLEW_FUN_EXPORT PFNGLUNIFORM4FVPROC __glewUniform4fv;
+GLEW_FUN_EXPORT PFNGLUNIFORM4IPROC __glewUniform4i;
+GLEW_FUN_EXPORT PFNGLUNIFORM4IVPROC __glewUniform4iv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv;
+GLEW_FUN_EXPORT PFNGLUSEPROGRAMPROC __glewUseProgram;
+GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPROC __glewValidateProgram;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer;
+
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv;
+
+GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender;
+GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback;
+GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation;
+GLEW_FUN_EXPORT PFNGLCLAMPCOLORPROC __glewClampColor;
+GLEW_FUN_EXPORT PFNGLCLEARBUFFERFIPROC __glewClearBufferfi;
+GLEW_FUN_EXPORT PFNGLCLEARBUFFERFVPROC __glewClearBufferfv;
+GLEW_FUN_EXPORT PFNGLCLEARBUFFERIVPROC __glewClearBufferiv;
+GLEW_FUN_EXPORT PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv;
+GLEW_FUN_EXPORT PFNGLCOLORMASKIPROC __glewColorMaski;
+GLEW_FUN_EXPORT PFNGLDISABLEIPROC __glewDisablei;
+GLEW_FUN_EXPORT PFNGLENABLEIPROC __glewEnablei;
+GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender;
+GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback;
+GLEW_FUN_EXPORT PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v;
+GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation;
+GLEW_FUN_EXPORT PFNGLGETSTRINGIPROC __glewGetStringi;
+GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv;
+GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv;
+GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv;
+GLEW_FUN_EXPORT PFNGLISENABLEDIPROC __glewIsEnabledi;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv;
+GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings;
+GLEW_FUN_EXPORT PFNGLUNIFORM1UIPROC __glewUniform1ui;
+GLEW_FUN_EXPORT PFNGLUNIFORM1UIVPROC __glewUniform1uiv;
+GLEW_FUN_EXPORT PFNGLUNIFORM2UIPROC __glewUniform2ui;
+GLEW_FUN_EXPORT PFNGLUNIFORM2UIVPROC __glewUniform2uiv;
+GLEW_FUN_EXPORT PFNGLUNIFORM3UIPROC __glewUniform3ui;
+GLEW_FUN_EXPORT PFNGLUNIFORM3UIVPROC __glewUniform3uiv;
+GLEW_FUN_EXPORT PFNGLUNIFORM4UIPROC __glewUniform4ui;
+GLEW_FUN_EXPORT PFNGLUNIFORM4UIVPROC __glewUniform4uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer;
+
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDPROC __glewDrawArraysInstanced;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDPROC __glewDrawElementsInstanced;
+GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXPROC __glewPrimitiveRestartIndex;
+GLEW_FUN_EXPORT PFNGLTEXBUFFERPROC __glewTexBuffer;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREPROC __glewFramebufferTexture;
+GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERI64VPROC __glewGetBufferParameteri64v;
+GLEW_FUN_EXPORT PFNGLGETINTEGER64I_VPROC __glewGetInteger64i_v;
+
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORPROC __glewVertexAttribDivisor;
+
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIPROC __glewBlendEquationSeparatei;
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIPROC __glewBlendEquationi;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIPROC __glewBlendFuncSeparatei;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCIPROC __glewBlendFunci;
+GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGPROC __glewMinSampleShading;
+
+GLEW_FUN_EXPORT PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX;
+
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKAMDPROC __glewDebugMessageCallbackAMD;
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEENABLEAMDPROC __glewDebugMessageEnableAMD;
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTAMDPROC __glewDebugMessageInsertAMD;
+GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGAMDPROC __glewGetDebugMessageLogAMD;
+
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONINDEXEDAMDPROC __glewBlendEquationIndexedAMD;
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC __glewBlendEquationSeparateIndexedAMD;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCINDEXEDAMDPROC __glewBlendFuncIndexedAMD;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC __glewBlendFuncSeparateIndexedAMD;
+
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPARAMETERIAMDPROC __glewVertexAttribParameteriAMD;
+
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC __glewMultiDrawArraysIndirectAMD;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC __glewMultiDrawElementsIndirectAMD;
+
+GLEW_FUN_EXPORT PFNGLDELETENAMESAMDPROC __glewDeleteNamesAMD;
+GLEW_FUN_EXPORT PFNGLGENNAMESAMDPROC __glewGenNamesAMD;
+GLEW_FUN_EXPORT PFNGLISNAMEAMDPROC __glewIsNameAMD;
+
+GLEW_FUN_EXPORT PFNGLBEGINPERFMONITORAMDPROC __glewBeginPerfMonitorAMD;
+GLEW_FUN_EXPORT PFNGLDELETEPERFMONITORSAMDPROC __glewDeletePerfMonitorsAMD;
+GLEW_FUN_EXPORT PFNGLENDPERFMONITORAMDPROC __glewEndPerfMonitorAMD;
+GLEW_FUN_EXPORT PFNGLGENPERFMONITORSAMDPROC __glewGenPerfMonitorsAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERDATAAMDPROC __glewGetPerfMonitorCounterDataAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERINFOAMDPROC __glewGetPerfMonitorCounterInfoAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC __glewGetPerfMonitorCounterStringAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORCOUNTERSAMDPROC __glewGetPerfMonitorCountersAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSTRINGAMDPROC __glewGetPerfMonitorGroupStringAMD;
+GLEW_FUN_EXPORT PFNGLGETPERFMONITORGROUPSAMDPROC __glewGetPerfMonitorGroupsAMD;
+GLEW_FUN_EXPORT PFNGLSELECTPERFMONITORCOUNTERSAMDPROC __glewSelectPerfMonitorCountersAMD;
+
+GLEW_FUN_EXPORT PFNGLSETMULTISAMPLEFVAMDPROC __glewSetMultisamplefvAMD;
+
+GLEW_FUN_EXPORT PFNGLTEXSTORAGESPARSEAMDPROC __glewTexStorageSparseAMD;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGESPARSEAMDPROC __glewTextureStorageSparseAMD;
+
+GLEW_FUN_EXPORT PFNGLSTENCILOPVALUEAMDPROC __glewStencilOpValueAMD;
+
+GLEW_FUN_EXPORT PFNGLTESSELLATIONFACTORAMDPROC __glewTessellationFactorAMD;
+GLEW_FUN_EXPORT PFNGLTESSELLATIONMODEAMDPROC __glewTessellationModeAMD;
+
+GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERANGLEPROC __glewBlitFramebufferANGLE;
+
+GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC __glewRenderbufferStorageMultisampleANGLE;
+
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDANGLEPROC __glewDrawArraysInstancedANGLE;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDANGLEPROC __glewDrawElementsInstancedANGLE;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORANGLEPROC __glewVertexAttribDivisorANGLE;
+
+GLEW_FUN_EXPORT PFNGLBEGINQUERYANGLEPROC __glewBeginQueryANGLE;
+GLEW_FUN_EXPORT PFNGLDELETEQUERIESANGLEPROC __glewDeleteQueriesANGLE;
+GLEW_FUN_EXPORT PFNGLENDQUERYANGLEPROC __glewEndQueryANGLE;
+GLEW_FUN_EXPORT PFNGLGENQUERIESANGLEPROC __glewGenQueriesANGLE;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VANGLEPROC __glewGetQueryObjecti64vANGLE;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVANGLEPROC __glewGetQueryObjectivANGLE;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VANGLEPROC __glewGetQueryObjectui64vANGLE;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVANGLEPROC __glewGetQueryObjectuivANGLE;
+GLEW_FUN_EXPORT PFNGLGETQUERYIVANGLEPROC __glewGetQueryivANGLE;
+GLEW_FUN_EXPORT PFNGLISQUERYANGLEPROC __glewIsQueryANGLE;
+GLEW_FUN_EXPORT PFNGLQUERYCOUNTERANGLEPROC __glewQueryCounterANGLE;
+
+GLEW_FUN_EXPORT PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC __glewGetTranslatedShaderSourceANGLE;
+
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE;
+GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE;
+GLEW_FUN_EXPORT PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE;
+
+GLEW_FUN_EXPORT PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE;
+GLEW_FUN_EXPORT PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE;
+GLEW_FUN_EXPORT PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE;
+GLEW_FUN_EXPORT PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE;
+GLEW_FUN_EXPORT PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE;
+GLEW_FUN_EXPORT PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE;
+GLEW_FUN_EXPORT PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE;
+GLEW_FUN_EXPORT PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE;
+
+GLEW_FUN_EXPORT PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE;
+GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE;
+
+GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVAPPLEPROC __glewGetObjectParameterivAPPLE;
+GLEW_FUN_EXPORT PFNGLOBJECTPURGEABLEAPPLEPROC __glewObjectPurgeableAPPLE;
+GLEW_FUN_EXPORT PFNGLOBJECTUNPURGEABLEAPPLEPROC __glewObjectUnpurgeableAPPLE;
+
+GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE;
+GLEW_FUN_EXPORT PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE;
+
+GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE;
+GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE;
+GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE;
+GLEW_FUN_EXPORT PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE;
+
+GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE;
+
+GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBAPPLEPROC __glewDisableVertexAttribAPPLE;
+GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBAPPLEPROC __glewEnableVertexAttribAPPLE;
+GLEW_FUN_EXPORT PFNGLISVERTEXATTRIBENABLEDAPPLEPROC __glewIsVertexAttribEnabledAPPLE;
+GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1DAPPLEPROC __glewMapVertexAttrib1dAPPLE;
+GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB1FAPPLEPROC __glewMapVertexAttrib1fAPPLE;
+GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2DAPPLEPROC __glewMapVertexAttrib2dAPPLE;
+GLEW_FUN_EXPORT PFNGLMAPVERTEXATTRIB2FAPPLEPROC __glewMapVertexAttrib2fAPPLE;
+
+GLEW_FUN_EXPORT PFNGLCLEARDEPTHFPROC __glewClearDepthf;
+GLEW_FUN_EXPORT PFNGLDEPTHRANGEFPROC __glewDepthRangef;
+GLEW_FUN_EXPORT PFNGLGETSHADERPRECISIONFORMATPROC __glewGetShaderPrecisionFormat;
+GLEW_FUN_EXPORT PFNGLRELEASESHADERCOMPILERPROC __glewReleaseShaderCompiler;
+GLEW_FUN_EXPORT PFNGLSHADERBINARYPROC __glewShaderBinary;
+
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC __glewDrawArraysInstancedBaseInstance;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC __glewDrawElementsInstancedBaseInstance;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC __glewDrawElementsInstancedBaseVertexBaseInstance;
+
+GLEW_FUN_EXPORT PFNGLGETIMAGEHANDLEARBPROC __glewGetImageHandleARB;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREHANDLEARBPROC __glewGetTextureHandleARB;
+GLEW_FUN_EXPORT PFNGLGETTEXTURESAMPLERHANDLEARBPROC __glewGetTextureSamplerHandleARB;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLUI64VARBPROC __glewGetVertexAttribLui64vARB;
+GLEW_FUN_EXPORT PFNGLISIMAGEHANDLERESIDENTARBPROC __glewIsImageHandleResidentARB;
+GLEW_FUN_EXPORT PFNGLISTEXTUREHANDLERESIDENTARBPROC __glewIsTextureHandleResidentARB;
+GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC __glewMakeImageHandleNonResidentARB;
+GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLERESIDENTARBPROC __glewMakeImageHandleResidentARB;
+GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC __glewMakeTextureHandleNonResidentARB;
+GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLERESIDENTARBPROC __glewMakeTextureHandleResidentARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC __glewProgramUniformHandleui64ARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC __glewProgramUniformHandleui64vARB;
+GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64ARBPROC __glewUniformHandleui64ARB;
+GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64VARBPROC __glewUniformHandleui64vARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64ARBPROC __glewVertexAttribL1ui64ARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64VARBPROC __glewVertexAttribL1ui64vARB;
+
+GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONINDEXEDPROC __glewBindFragDataLocationIndexed;
+GLEW_FUN_EXPORT PFNGLGETFRAGDATAINDEXPROC __glewGetFragDataIndex;
+
+GLEW_FUN_EXPORT PFNGLBUFFERSTORAGEPROC __glewBufferStorage;
+GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSTORAGEEXTPROC __glewNamedBufferStorageEXT;
+
+GLEW_FUN_EXPORT PFNGLCREATESYNCFROMCLEVENTARBPROC __glewCreateSyncFromCLeventARB;
+
+GLEW_FUN_EXPORT PFNGLCLEARBUFFERDATAPROC __glewClearBufferData;
+GLEW_FUN_EXPORT PFNGLCLEARBUFFERSUBDATAPROC __glewClearBufferSubData;
+GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERDATAEXTPROC __glewClearNamedBufferDataEXT;
+GLEW_FUN_EXPORT PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC __glewClearNamedBufferSubDataEXT;
+
+GLEW_FUN_EXPORT PFNGLCLEARTEXIMAGEPROC __glewClearTexImage;
+GLEW_FUN_EXPORT PFNGLCLEARTEXSUBIMAGEPROC __glewClearTexSubImage;
+
+GLEW_FUN_EXPORT PFNGLCLAMPCOLORARBPROC __glewClampColorARB;
+
+GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEPROC __glewDispatchCompute;
+GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEINDIRECTPROC __glewDispatchComputeIndirect;
+
+GLEW_FUN_EXPORT PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC __glewDispatchComputeGroupSizeARB;
+
+GLEW_FUN_EXPORT PFNGLCOPYBUFFERSUBDATAPROC __glewCopyBufferSubData;
+
+GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATAPROC __glewCopyImageSubData;
+
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKARBPROC __glewDebugMessageCallbackARB;
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECONTROLARBPROC __glewDebugMessageControlARB;
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTARBPROC __glewDebugMessageInsertARB;
+GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGARBPROC __glewGetDebugMessageLogARB;
+
+GLEW_FUN_EXPORT PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB;
+
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEIARBPROC __glewBlendEquationSeparateiARB;
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONIARBPROC __glewBlendEquationiARB;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEIARBPROC __glewBlendFuncSeparateiARB;
+GLEW_FUN_EXPORT PFNGLBLENDFUNCIARBPROC __glewBlendFunciARB;
+
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSBASEVERTEXPROC __glewDrawElementsBaseVertex;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __glewDrawElementsInstancedBaseVertex;
+GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC __glewDrawRangeElementsBaseVertex;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC __glewMultiDrawElementsBaseVertex;
+
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINDIRECTPROC __glewDrawArraysIndirect;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINDIRECTPROC __glewDrawElementsIndirect;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERPARAMETERIPROC __glewFramebufferParameteri;
+GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVPROC __glewGetFramebufferParameteriv;
+GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC __glewGetNamedFramebufferParameterivEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC __glewNamedFramebufferParameteriEXT;
+
+GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer;
+GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer;
+GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer;
+GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus;
+GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers;
+GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer;
+GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers;
+GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers;
+GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap;
+GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv;
+GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv;
+GLEW_FUN_EXPORT PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer;
+GLEW_FUN_EXPORT PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer;
+GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage;
+GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB;
+
+GLEW_FUN_EXPORT PFNGLGETPROGRAMBINARYPROC __glewGetProgramBinary;
+GLEW_FUN_EXPORT PFNGLPROGRAMBINARYPROC __glewProgramBinary;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIPROC __glewProgramParameteri;
+
+GLEW_FUN_EXPORT PFNGLGETUNIFORMDVPROC __glewGetUniformdv;
+GLEW_FUN_EXPORT PFNGLUNIFORM1DPROC __glewUniform1d;
+GLEW_FUN_EXPORT PFNGLUNIFORM1DVPROC __glewUniform1dv;
+GLEW_FUN_EXPORT PFNGLUNIFORM2DPROC __glewUniform2d;
+GLEW_FUN_EXPORT PFNGLUNIFORM2DVPROC __glewUniform2dv;
+GLEW_FUN_EXPORT PFNGLUNIFORM3DPROC __glewUniform3d;
+GLEW_FUN_EXPORT PFNGLUNIFORM3DVPROC __glewUniform3dv;
+GLEW_FUN_EXPORT PFNGLUNIFORM4DPROC __glewUniform4d;
+GLEW_FUN_EXPORT PFNGLUNIFORM4DVPROC __glewUniform4dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2DVPROC __glewUniformMatrix2dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X3DVPROC __glewUniformMatrix2x3dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2X4DVPROC __glewUniformMatrix2x4dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3DVPROC __glewUniformMatrix3dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X2DVPROC __glewUniformMatrix3x2dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3X4DVPROC __glewUniformMatrix3x4dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4DVPROC __glewUniformMatrix4dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X2DVPROC __glewUniformMatrix4x2dv;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4X3DVPROC __glewUniformMatrix4x3dv;
+
+GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEPROC __glewColorSubTable;
+GLEW_FUN_EXPORT PFNGLCOLORTABLEPROC __glewColorTable;
+GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv;
+GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv;
+GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable;
+GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable;
+GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D;
+GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPROC __glewGetColorTable;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv;
+GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter;
+GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv;
+GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv;
+GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPROC __glewGetHistogram;
+GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv;
+GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv;
+GLEW_FUN_EXPORT PFNGLGETMINMAXPROC __glewGetMinmax;
+GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv;
+GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv;
+GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter;
+GLEW_FUN_EXPORT PFNGLHISTOGRAMPROC __glewHistogram;
+GLEW_FUN_EXPORT PFNGLMINMAXPROC __glewMinmax;
+GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMPROC __glewResetHistogram;
+GLEW_FUN_EXPORT PFNGLRESETMINMAXPROC __glewResetMinmax;
+GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D;
+
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC __glewMultiDrawArraysIndirectCountARB;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC __glewMultiDrawElementsIndirectCountARB;
+
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB;
+
+GLEW_FUN_EXPORT PFNGLGETINTERNALFORMATIVPROC __glewGetInternalformativ;
+
+GLEW_FUN_EXPORT PFNGLGETINTERNALFORMATI64VPROC __glewGetInternalformati64v;
+
+GLEW_FUN_EXPORT PFNGLINVALIDATEBUFFERDATAPROC __glewInvalidateBufferData;
+GLEW_FUN_EXPORT PFNGLINVALIDATEBUFFERSUBDATAPROC __glewInvalidateBufferSubData;
+GLEW_FUN_EXPORT PFNGLINVALIDATEFRAMEBUFFERPROC __glewInvalidateFramebuffer;
+GLEW_FUN_EXPORT PFNGLINVALIDATESUBFRAMEBUFFERPROC __glewInvalidateSubFramebuffer;
+GLEW_FUN_EXPORT PFNGLINVALIDATETEXIMAGEPROC __glewInvalidateTexImage;
+GLEW_FUN_EXPORT PFNGLINVALIDATETEXSUBIMAGEPROC __glewInvalidateTexSubImage;
+
+GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange;
+GLEW_FUN_EXPORT PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange;
+
+GLEW_FUN_EXPORT PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB;
+GLEW_FUN_EXPORT PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB;
+GLEW_FUN_EXPORT PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB;
+GLEW_FUN_EXPORT PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB;
+GLEW_FUN_EXPORT PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB;
+
+GLEW_FUN_EXPORT PFNGLBINDBUFFERSBASEPROC __glewBindBuffersBase;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERSRANGEPROC __glewBindBuffersRange;
+GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTURESPROC __glewBindImageTextures;
+GLEW_FUN_EXPORT PFNGLBINDSAMPLERSPROC __glewBindSamplers;
+GLEW_FUN_EXPORT PFNGLBINDTEXTURESPROC __glewBindTextures;
+GLEW_FUN_EXPORT PFNGLBINDVERTEXBUFFERSPROC __glewBindVertexBuffers;
+
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTPROC __glewMultiDrawArraysIndirect;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTPROC __glewMultiDrawElementsIndirect;
+
+GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB;
+
+GLEW_FUN_EXPORT PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB;
+GLEW_FUN_EXPORT PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB;
+
+GLEW_FUN_EXPORT PFNGLBEGINQUERYARBPROC __glewBeginQueryARB;
+GLEW_FUN_EXPORT PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB;
+GLEW_FUN_EXPORT PFNGLENDQUERYARBPROC __glewEndQueryARB;
+GLEW_FUN_EXPORT PFNGLGENQUERIESARBPROC __glewGenQueriesARB;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB;
+GLEW_FUN_EXPORT PFNGLGETQUERYIVARBPROC __glewGetQueryivARB;
+GLEW_FUN_EXPORT PFNGLISQUERYARBPROC __glewIsQueryARB;
+
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB;
+
+GLEW_FUN_EXPORT PFNGLGETPROGRAMINTERFACEIVPROC __glewGetProgramInterfaceiv;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCEINDEXPROC __glewGetProgramResourceIndex;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCELOCATIONPROC __glewGetProgramResourceLocation;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC __glewGetProgramResourceLocationIndex;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCENAMEPROC __glewGetProgramResourceName;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMRESOURCEIVPROC __glewGetProgramResourceiv;
+
+GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXPROC __glewProvokingVertex;
+
+GLEW_FUN_EXPORT PFNGLGETGRAPHICSRESETSTATUSARBPROC __glewGetGraphicsResetStatusARB;
+GLEW_FUN_EXPORT PFNGLGETNCOLORTABLEARBPROC __glewGetnColorTableARB;
+GLEW_FUN_EXPORT PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC __glewGetnCompressedTexImageARB;
+GLEW_FUN_EXPORT PFNGLGETNCONVOLUTIONFILTERARBPROC __glewGetnConvolutionFilterARB;
+GLEW_FUN_EXPORT PFNGLGETNHISTOGRAMARBPROC __glewGetnHistogramARB;
+GLEW_FUN_EXPORT PFNGLGETNMAPDVARBPROC __glewGetnMapdvARB;
+GLEW_FUN_EXPORT PFNGLGETNMAPFVARBPROC __glewGetnMapfvARB;
+GLEW_FUN_EXPORT PFNGLGETNMAPIVARBPROC __glewGetnMapivARB;
+GLEW_FUN_EXPORT PFNGLGETNMINMAXARBPROC __glewGetnMinmaxARB;
+GLEW_FUN_EXPORT PFNGLGETNPIXELMAPFVARBPROC __glewGetnPixelMapfvARB;
+GLEW_FUN_EXPORT PFNGLGETNPIXELMAPUIVARBPROC __glewGetnPixelMapuivARB;
+GLEW_FUN_EXPORT PFNGLGETNPIXELMAPUSVARBPROC __glewGetnPixelMapusvARB;
+GLEW_FUN_EXPORT PFNGLGETNPOLYGONSTIPPLEARBPROC __glewGetnPolygonStippleARB;
+GLEW_FUN_EXPORT PFNGLGETNSEPARABLEFILTERARBPROC __glewGetnSeparableFilterARB;
+GLEW_FUN_EXPORT PFNGLGETNTEXIMAGEARBPROC __glewGetnTexImageARB;
+GLEW_FUN_EXPORT PFNGLGETNUNIFORMDVARBPROC __glewGetnUniformdvARB;
+GLEW_FUN_EXPORT PFNGLGETNUNIFORMFVARBPROC __glewGetnUniformfvARB;
+GLEW_FUN_EXPORT PFNGLGETNUNIFORMIVARBPROC __glewGetnUniformivARB;
+GLEW_FUN_EXPORT PFNGLGETNUNIFORMUIVARBPROC __glewGetnUniformuivARB;
+GLEW_FUN_EXPORT PFNGLREADNPIXELSARBPROC __glewReadnPixelsARB;
+
+GLEW_FUN_EXPORT PFNGLMINSAMPLESHADINGARBPROC __glewMinSampleShadingARB;
+
+GLEW_FUN_EXPORT PFNGLBINDSAMPLERPROC __glewBindSampler;
+GLEW_FUN_EXPORT PFNGLDELETESAMPLERSPROC __glewDeleteSamplers;
+GLEW_FUN_EXPORT PFNGLGENSAMPLERSPROC __glewGenSamplers;
+GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIIVPROC __glewGetSamplerParameterIiv;
+GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIUIVPROC __glewGetSamplerParameterIuiv;
+GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERFVPROC __glewGetSamplerParameterfv;
+GLEW_FUN_EXPORT PFNGLGETSAMPLERPARAMETERIVPROC __glewGetSamplerParameteriv;
+GLEW_FUN_EXPORT PFNGLISSAMPLERPROC __glewIsSampler;
+GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIIVPROC __glewSamplerParameterIiv;
+GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIUIVPROC __glewSamplerParameterIuiv;
+GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERFPROC __glewSamplerParameterf;
+GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERFVPROC __glewSamplerParameterfv;
+GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIPROC __glewSamplerParameteri;
+GLEW_FUN_EXPORT PFNGLSAMPLERPARAMETERIVPROC __glewSamplerParameteriv;
+
+GLEW_FUN_EXPORT PFNGLACTIVESHADERPROGRAMPROC __glewActiveShaderProgram;
+GLEW_FUN_EXPORT PFNGLBINDPROGRAMPIPELINEPROC __glewBindProgramPipeline;
+GLEW_FUN_EXPORT PFNGLCREATESHADERPROGRAMVPROC __glewCreateShaderProgramv;
+GLEW_FUN_EXPORT PFNGLDELETEPROGRAMPIPELINESPROC __glewDeleteProgramPipelines;
+GLEW_FUN_EXPORT PFNGLGENPROGRAMPIPELINESPROC __glewGenProgramPipelines;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMPIPELINEINFOLOGPROC __glewGetProgramPipelineInfoLog;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMPIPELINEIVPROC __glewGetProgramPipelineiv;
+GLEW_FUN_EXPORT PFNGLISPROGRAMPIPELINEPROC __glewIsProgramPipeline;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1DPROC __glewProgramUniform1d;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1DVPROC __glewProgramUniform1dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FPROC __glewProgramUniform1f;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVPROC __glewProgramUniform1fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IPROC __glewProgramUniform1i;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVPROC __glewProgramUniform1iv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIPROC __glewProgramUniform1ui;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVPROC __glewProgramUniform1uiv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2DPROC __glewProgramUniform2d;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2DVPROC __glewProgramUniform2dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FPROC __glewProgramUniform2f;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVPROC __glewProgramUniform2fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IPROC __glewProgramUniform2i;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVPROC __glewProgramUniform2iv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIPROC __glewProgramUniform2ui;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVPROC __glewProgramUniform2uiv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3DPROC __glewProgramUniform3d;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3DVPROC __glewProgramUniform3dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FPROC __glewProgramUniform3f;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVPROC __glewProgramUniform3fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IPROC __glewProgramUniform3i;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVPROC __glewProgramUniform3iv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIPROC __glewProgramUniform3ui;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVPROC __glewProgramUniform3uiv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4DPROC __glewProgramUniform4d;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4DVPROC __glewProgramUniform4dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FPROC __glewProgramUniform4f;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVPROC __glewProgramUniform4fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IPROC __glewProgramUniform4i;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVPROC __glewProgramUniform4iv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIPROC __glewProgramUniform4ui;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVPROC __glewProgramUniform4uiv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2DVPROC __glewProgramUniformMatrix2dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVPROC __glewProgramUniformMatrix2fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC __glewProgramUniformMatrix2x3dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC __glewProgramUniformMatrix2x3fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC __glewProgramUniformMatrix2x4dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC __glewProgramUniformMatrix2x4fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3DVPROC __glewProgramUniformMatrix3dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVPROC __glewProgramUniformMatrix3fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC __glewProgramUniformMatrix3x2dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC __glewProgramUniformMatrix3x2fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC __glewProgramUniformMatrix3x4dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC __glewProgramUniformMatrix3x4fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4DVPROC __glewProgramUniformMatrix4dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVPROC __glewProgramUniformMatrix4fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC __glewProgramUniformMatrix4x2dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC __glewProgramUniformMatrix4x2fv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC __glewProgramUniformMatrix4x3dv;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC __glewProgramUniformMatrix4x3fv;
+GLEW_FUN_EXPORT PFNGLUSEPROGRAMSTAGESPROC __glewUseProgramStages;
+GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMPIPELINEPROC __glewValidateProgramPipeline;
+
+GLEW_FUN_EXPORT PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC __glewGetActiveAtomicCounterBufferiv;
+
+GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTUREPROC __glewBindImageTexture;
+GLEW_FUN_EXPORT PFNGLMEMORYBARRIERPROC __glewMemoryBarrier;
+
+GLEW_FUN_EXPORT PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB;
+GLEW_FUN_EXPORT PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB;
+GLEW_FUN_EXPORT PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB;
+GLEW_FUN_EXPORT PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB;
+GLEW_FUN_EXPORT PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB;
+GLEW_FUN_EXPORT PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB;
+GLEW_FUN_EXPORT PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB;
+GLEW_FUN_EXPORT PFNGLGETHANDLEARBPROC __glewGetHandleARB;
+GLEW_FUN_EXPORT PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB;
+GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB;
+GLEW_FUN_EXPORT PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB;
+GLEW_FUN_EXPORT PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB;
+GLEW_FUN_EXPORT PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB;
+GLEW_FUN_EXPORT PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM1FARBPROC __glewUniform1fARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM1IARBPROC __glewUniform1iARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM2FARBPROC __glewUniform2fARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM2IARBPROC __glewUniform2iARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM3FARBPROC __glewUniform3fARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM3IARBPROC __glewUniform3iARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM4FARBPROC __glewUniform4fARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM4IARBPROC __glewUniform4iARB;
+GLEW_FUN_EXPORT PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB;
+GLEW_FUN_EXPORT PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB;
+GLEW_FUN_EXPORT PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB;
+GLEW_FUN_EXPORT PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB;
+
+GLEW_FUN_EXPORT PFNGLSHADERSTORAGEBLOCKBINDINGPROC __glewShaderStorageBlockBinding;
+
+GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINENAMEPROC __glewGetActiveSubroutineName;
+GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC __glewGetActiveSubroutineUniformName;
+GLEW_FUN_EXPORT PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC __glewGetActiveSubroutineUniformiv;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMSTAGEIVPROC __glewGetProgramStageiv;
+GLEW_FUN_EXPORT PFNGLGETSUBROUTINEINDEXPROC __glewGetSubroutineIndex;
+GLEW_FUN_EXPORT PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC __glewGetSubroutineUniformLocation;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMSUBROUTINEUIVPROC __glewGetUniformSubroutineuiv;
+GLEW_FUN_EXPORT PFNGLUNIFORMSUBROUTINESUIVPROC __glewUniformSubroutinesuiv;
+
+GLEW_FUN_EXPORT PFNGLCOMPILESHADERINCLUDEARBPROC __glewCompileShaderIncludeARB;
+GLEW_FUN_EXPORT PFNGLDELETENAMEDSTRINGARBPROC __glewDeleteNamedStringARB;
+GLEW_FUN_EXPORT PFNGLGETNAMEDSTRINGARBPROC __glewGetNamedStringARB;
+GLEW_FUN_EXPORT PFNGLGETNAMEDSTRINGIVARBPROC __glewGetNamedStringivARB;
+GLEW_FUN_EXPORT PFNGLISNAMEDSTRINGARBPROC __glewIsNamedStringARB;
+GLEW_FUN_EXPORT PFNGLNAMEDSTRINGARBPROC __glewNamedStringARB;
+
+GLEW_FUN_EXPORT PFNGLTEXPAGECOMMITMENTARBPROC __glewTexPageCommitmentARB;
+GLEW_FUN_EXPORT PFNGLTEXTUREPAGECOMMITMENTEXTPROC __glewTexturePageCommitmentEXT;
+
+GLEW_FUN_EXPORT PFNGLCLIENTWAITSYNCPROC __glewClientWaitSync;
+GLEW_FUN_EXPORT PFNGLDELETESYNCPROC __glewDeleteSync;
+GLEW_FUN_EXPORT PFNGLFENCESYNCPROC __glewFenceSync;
+GLEW_FUN_EXPORT PFNGLGETINTEGER64VPROC __glewGetInteger64v;
+GLEW_FUN_EXPORT PFNGLGETSYNCIVPROC __glewGetSynciv;
+GLEW_FUN_EXPORT PFNGLISSYNCPROC __glewIsSync;
+GLEW_FUN_EXPORT PFNGLWAITSYNCPROC __glewWaitSync;
+
+GLEW_FUN_EXPORT PFNGLPATCHPARAMETERFVPROC __glewPatchParameterfv;
+GLEW_FUN_EXPORT PFNGLPATCHPARAMETERIPROC __glewPatchParameteri;
+
+GLEW_FUN_EXPORT PFNGLTEXBUFFERARBPROC __glewTexBufferARB;
+
+GLEW_FUN_EXPORT PFNGLTEXBUFFERRANGEPROC __glewTexBufferRange;
+GLEW_FUN_EXPORT PFNGLTEXTUREBUFFERRANGEEXTPROC __glewTextureBufferRangeEXT;
+
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB;
+GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB;
+
+GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVPROC __glewGetMultisamplefv;
+GLEW_FUN_EXPORT PFNGLSAMPLEMASKIPROC __glewSampleMaski;
+GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLEPROC __glewTexImage2DMultisample;
+GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLEPROC __glewTexImage3DMultisample;
+
+GLEW_FUN_EXPORT PFNGLTEXSTORAGE1DPROC __glewTexStorage1D;
+GLEW_FUN_EXPORT PFNGLTEXSTORAGE2DPROC __glewTexStorage2D;
+GLEW_FUN_EXPORT PFNGLTEXSTORAGE3DPROC __glewTexStorage3D;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE1DEXTPROC __glewTextureStorage1DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DEXTPROC __glewTextureStorage2DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DEXTPROC __glewTextureStorage3DEXT;
+
+GLEW_FUN_EXPORT PFNGLTEXSTORAGE2DMULTISAMPLEPROC __glewTexStorage2DMultisample;
+GLEW_FUN_EXPORT PFNGLTEXSTORAGE3DMULTISAMPLEPROC __glewTexStorage3DMultisample;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC __glewTextureStorage2DMultisampleEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC __glewTextureStorage3DMultisampleEXT;
+
+GLEW_FUN_EXPORT PFNGLTEXTUREVIEWPROC __glewTextureView;
+
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VPROC __glewGetQueryObjecti64v;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VPROC __glewGetQueryObjectui64v;
+GLEW_FUN_EXPORT PFNGLQUERYCOUNTERPROC __glewQueryCounter;
+
+GLEW_FUN_EXPORT PFNGLBINDTRANSFORMFEEDBACKPROC __glewBindTransformFeedback;
+GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSPROC __glewDeleteTransformFeedbacks;
+GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKPROC __glewDrawTransformFeedback;
+GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSPROC __glewGenTransformFeedbacks;
+GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKPROC __glewIsTransformFeedback;
+GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKPROC __glewPauseTransformFeedback;
+GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKPROC __glewResumeTransformFeedback;
+
+GLEW_FUN_EXPORT PFNGLBEGINQUERYINDEXEDPROC __glewBeginQueryIndexed;
+GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC __glewDrawTransformFeedbackStream;
+GLEW_FUN_EXPORT PFNGLENDQUERYINDEXEDPROC __glewEndQueryIndexed;
+GLEW_FUN_EXPORT PFNGLGETQUERYINDEXEDIVPROC __glewGetQueryIndexediv;
+
+GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC __glewDrawTransformFeedbackInstanced;
+GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC __glewDrawTransformFeedbackStreamInstanced;
+
+GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB;
+GLEW_FUN_EXPORT PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB;
+GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB;
+GLEW_FUN_EXPORT PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB;
+
+GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEPROC __glewBindBufferBase;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC __glewGetActiveUniformBlockName;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMBLOCKIVPROC __glewGetActiveUniformBlockiv;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMNAMEPROC __glewGetActiveUniformName;
+GLEW_FUN_EXPORT PFNGLGETACTIVEUNIFORMSIVPROC __glewGetActiveUniformsiv;
+GLEW_FUN_EXPORT PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMBLOCKINDEXPROC __glewGetUniformBlockIndex;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMINDICESPROC __glewGetUniformIndices;
+GLEW_FUN_EXPORT PFNGLUNIFORMBLOCKBINDINGPROC __glewUniformBlockBinding;
+
+GLEW_FUN_EXPORT PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray;
+GLEW_FUN_EXPORT PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays;
+GLEW_FUN_EXPORT PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays;
+GLEW_FUN_EXPORT PFNGLISVERTEXARRAYPROC __glewIsVertexArray;
+
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLDVPROC __glewGetVertexAttribLdv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DPROC __glewVertexAttribL1d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DVPROC __glewVertexAttribL1dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DPROC __glewVertexAttribL2d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DVPROC __glewVertexAttribL2dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DPROC __glewVertexAttribL3d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DVPROC __glewVertexAttribL3dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DPROC __glewVertexAttribL4d;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DVPROC __glewVertexAttribL4dv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLPOINTERPROC __glewVertexAttribLPointer;
+
+GLEW_FUN_EXPORT PFNGLBINDVERTEXBUFFERPROC __glewBindVertexBuffer;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBBINDINGPROC __glewVertexAttribBinding;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBFORMATPROC __glewVertexAttribFormat;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIFORMATPROC __glewVertexAttribIFormat;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLFORMATPROC __glewVertexAttribLFormat;
+GLEW_FUN_EXPORT PFNGLVERTEXBINDINGDIVISORPROC __glewVertexBindingDivisor;
+
+GLEW_FUN_EXPORT PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTBVARBPROC __glewWeightbvARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTDVARBPROC __glewWeightdvARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTFVARBPROC __glewWeightfvARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTIVARBPROC __glewWeightivARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTSVARBPROC __glewWeightsvARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTUBVARBPROC __glewWeightubvARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTUIVARBPROC __glewWeightuivARB;
+GLEW_FUN_EXPORT PFNGLWEIGHTUSVARBPROC __glewWeightusvARB;
+
+GLEW_FUN_EXPORT PFNGLBINDBUFFERARBPROC __glewBindBufferARB;
+GLEW_FUN_EXPORT PFNGLBUFFERDATAARBPROC __glewBufferDataARB;
+GLEW_FUN_EXPORT PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB;
+GLEW_FUN_EXPORT PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB;
+GLEW_FUN_EXPORT PFNGLGENBUFFERSARBPROC __glewGenBuffersARB;
+GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB;
+GLEW_FUN_EXPORT PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB;
+GLEW_FUN_EXPORT PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB;
+GLEW_FUN_EXPORT PFNGLISBUFFERARBPROC __glewIsBufferARB;
+GLEW_FUN_EXPORT PFNGLMAPBUFFERARBPROC __glewMapBufferARB;
+GLEW_FUN_EXPORT PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB;
+
+GLEW_FUN_EXPORT PFNGLBINDPROGRAMARBPROC __glewBindProgramARB;
+GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB;
+GLEW_FUN_EXPORT PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB;
+GLEW_FUN_EXPORT PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB;
+GLEW_FUN_EXPORT PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB;
+GLEW_FUN_EXPORT PFNGLISPROGRAMARBPROC __glewIsProgramARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB;
+GLEW_FUN_EXPORT PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB;
+
+GLEW_FUN_EXPORT PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB;
+GLEW_FUN_EXPORT PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB;
+GLEW_FUN_EXPORT PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB;
+
+GLEW_FUN_EXPORT PFNGLCOLORP3UIPROC __glewColorP3ui;
+GLEW_FUN_EXPORT PFNGLCOLORP3UIVPROC __glewColorP3uiv;
+GLEW_FUN_EXPORT PFNGLCOLORP4UIPROC __glewColorP4ui;
+GLEW_FUN_EXPORT PFNGLCOLORP4UIVPROC __glewColorP4uiv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP1UIPROC __glewMultiTexCoordP1ui;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP1UIVPROC __glewMultiTexCoordP1uiv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP2UIPROC __glewMultiTexCoordP2ui;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP2UIVPROC __glewMultiTexCoordP2uiv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP3UIPROC __glewMultiTexCoordP3ui;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP3UIVPROC __glewMultiTexCoordP3uiv;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP4UIPROC __glewMultiTexCoordP4ui;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDP4UIVPROC __glewMultiTexCoordP4uiv;
+GLEW_FUN_EXPORT PFNGLNORMALP3UIPROC __glewNormalP3ui;
+GLEW_FUN_EXPORT PFNGLNORMALP3UIVPROC __glewNormalP3uiv;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLORP3UIPROC __glewSecondaryColorP3ui;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLORP3UIVPROC __glewSecondaryColorP3uiv;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP1UIPROC __glewTexCoordP1ui;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP1UIVPROC __glewTexCoordP1uiv;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP2UIPROC __glewTexCoordP2ui;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP2UIVPROC __glewTexCoordP2uiv;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP3UIPROC __glewTexCoordP3ui;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP3UIVPROC __glewTexCoordP3uiv;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP4UIPROC __glewTexCoordP4ui;
+GLEW_FUN_EXPORT PFNGLTEXCOORDP4UIVPROC __glewTexCoordP4uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP1UIPROC __glewVertexAttribP1ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP1UIVPROC __glewVertexAttribP1uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP2UIPROC __glewVertexAttribP2ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP2UIVPROC __glewVertexAttribP2uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP3UIPROC __glewVertexAttribP3ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP3UIVPROC __glewVertexAttribP3uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP4UIPROC __glewVertexAttribP4ui;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBP4UIVPROC __glewVertexAttribP4uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXP2UIPROC __glewVertexP2ui;
+GLEW_FUN_EXPORT PFNGLVERTEXP2UIVPROC __glewVertexP2uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXP3UIPROC __glewVertexP3ui;
+GLEW_FUN_EXPORT PFNGLVERTEXP3UIVPROC __glewVertexP3uiv;
+GLEW_FUN_EXPORT PFNGLVERTEXP4UIPROC __glewVertexP4ui;
+GLEW_FUN_EXPORT PFNGLVERTEXP4UIVPROC __glewVertexP4uiv;
+
+GLEW_FUN_EXPORT PFNGLDEPTHRANGEARRAYVPROC __glewDepthRangeArrayv;
+GLEW_FUN_EXPORT PFNGLDEPTHRANGEINDEXEDPROC __glewDepthRangeIndexed;
+GLEW_FUN_EXPORT PFNGLGETDOUBLEI_VPROC __glewGetDoublei_v;
+GLEW_FUN_EXPORT PFNGLGETFLOATI_VPROC __glewGetFloati_v;
+GLEW_FUN_EXPORT PFNGLSCISSORARRAYVPROC __glewScissorArrayv;
+GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDPROC __glewScissorIndexed;
+GLEW_FUN_EXPORT PFNGLSCISSORINDEXEDVPROC __glewScissorIndexedv;
+GLEW_FUN_EXPORT PFNGLVIEWPORTARRAYVPROC __glewViewportArrayv;
+GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFPROC __glewViewportIndexedf;
+GLEW_FUN_EXPORT PFNGLVIEWPORTINDEXEDFVPROC __glewViewportIndexedfv;
+
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB;
+
+GLEW_FUN_EXPORT PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI;
+
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI;
+GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI;
+GLEW_FUN_EXPORT PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI;
+
+GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI;
+GLEW_FUN_EXPORT PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI;
+GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI;
+GLEW_FUN_EXPORT PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI;
+
+GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI;
+GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI;
+GLEW_FUN_EXPORT PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI;
+GLEW_FUN_EXPORT PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI;
+GLEW_FUN_EXPORT PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI;
+GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI;
+GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI;
+GLEW_FUN_EXPORT PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI;
+GLEW_FUN_EXPORT PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI;
+GLEW_FUN_EXPORT PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI;
+GLEW_FUN_EXPORT PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI;
+GLEW_FUN_EXPORT PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI;
+GLEW_FUN_EXPORT PFNGLSAMPLEMAPATIPROC __glewSampleMapATI;
+GLEW_FUN_EXPORT PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI;
+
+GLEW_FUN_EXPORT PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI;
+GLEW_FUN_EXPORT PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI;
+
+GLEW_FUN_EXPORT PFNGLPNTRIANGLESFATIPROC __glewPNTrianglesfATI;
+GLEW_FUN_EXPORT PFNGLPNTRIANGLESIATIPROC __glewPNTrianglesiATI;
+
+GLEW_FUN_EXPORT PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI;
+GLEW_FUN_EXPORT PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI;
+
+GLEW_FUN_EXPORT PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI;
+GLEW_FUN_EXPORT PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI;
+GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI;
+GLEW_FUN_EXPORT PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI;
+GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI;
+GLEW_FUN_EXPORT PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI;
+GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI;
+GLEW_FUN_EXPORT PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI;
+GLEW_FUN_EXPORT PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI;
+GLEW_FUN_EXPORT PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI;
+GLEW_FUN_EXPORT PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI;
+GLEW_FUN_EXPORT PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI;
+
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI;
+
+GLEW_FUN_EXPORT PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI;
+GLEW_FUN_EXPORT PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI;
+GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI;
+GLEW_FUN_EXPORT PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1DATIPROC __glewVertexStream1dATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1DVATIPROC __glewVertexStream1dvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1FATIPROC __glewVertexStream1fATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1FVATIPROC __glewVertexStream1fvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1IATIPROC __glewVertexStream1iATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1IVATIPROC __glewVertexStream1ivATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1SATIPROC __glewVertexStream1sATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM1SVATIPROC __glewVertexStream1svATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI;
+GLEW_FUN_EXPORT PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI;
+
+GLEW_FUN_EXPORT PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT;
+
+GLEW_FUN_EXPORT PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT;
+
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT;
+
+GLEW_FUN_EXPORT PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT;
+
+GLEW_FUN_EXPORT PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT;
+
+GLEW_FUN_EXPORT PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT;
+GLEW_FUN_EXPORT PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT;
+
+GLEW_FUN_EXPORT PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT;
+GLEW_FUN_EXPORT PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT;
+
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT;
+GLEW_FUN_EXPORT PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT;
+GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT;
+GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT;
+GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT;
+GLEW_FUN_EXPORT PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT;
+
+GLEW_FUN_EXPORT PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT;
+GLEW_FUN_EXPORT PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT;
+
+GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT;
+
+GLEW_FUN_EXPORT PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT;
+GLEW_FUN_EXPORT PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT;
+
+GLEW_FUN_EXPORT PFNGLINSERTEVENTMARKEREXTPROC __glewInsertEventMarkerEXT;
+GLEW_FUN_EXPORT PFNGLPOPGROUPMARKEREXTPROC __glewPopGroupMarkerEXT;
+GLEW_FUN_EXPORT PFNGLPUSHGROUPMARKEREXTPROC __glewPushGroupMarkerEXT;
+
+GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT;
+
+GLEW_FUN_EXPORT PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT;
+GLEW_FUN_EXPORT PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT;
+GLEW_FUN_EXPORT PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT;
+GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT;
+GLEW_FUN_EXPORT PFNGLDISABLECLIENTSTATEIEXTPROC __glewDisableClientStateiEXT;
+GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC __glewDisableVertexArrayAttribEXT;
+GLEW_FUN_EXPORT PFNGLDISABLEVERTEXARRAYEXTPROC __glewDisableVertexArrayEXT;
+GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT;
+GLEW_FUN_EXPORT PFNGLENABLECLIENTSTATEIEXTPROC __glewEnableClientStateiEXT;
+GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYATTRIBEXTPROC __glewEnableVertexArrayAttribEXT;
+GLEW_FUN_EXPORT PFNGLENABLEVERTEXARRAYEXTPROC __glewEnableVertexArrayEXT;
+GLEW_FUN_EXPORT PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC __glewFlushMappedNamedBufferRangeEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT;
+GLEW_FUN_EXPORT PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT;
+GLEW_FUN_EXPORT PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT;
+GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT;
+GLEW_FUN_EXPORT PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT;
+GLEW_FUN_EXPORT PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT;
+GLEW_FUN_EXPORT PFNGLGETDOUBLEI_VEXTPROC __glewGetDoublei_vEXT;
+GLEW_FUN_EXPORT PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT;
+GLEW_FUN_EXPORT PFNGLGETFLOATI_VEXTPROC __glewGetFloati_vEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT;
+GLEW_FUN_EXPORT PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT;
+GLEW_FUN_EXPORT PFNGLGETPOINTERI_VEXTPROC __glewGetPointeri_vEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC __glewGetVertexArrayIntegeri_vEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYINTEGERVEXTPROC __glewGetVertexArrayIntegervEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC __glewGetVertexArrayPointeri_vEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXARRAYPOINTERVEXTPROC __glewGetVertexArrayPointervEXT;
+GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT;
+GLEW_FUN_EXPORT PFNGLMAPNAMEDBUFFERRANGEEXTPROC __glewMapNamedBufferRangeEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT;
+GLEW_FUN_EXPORT PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC __glewNamedCopyBufferSubDataEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT;
+GLEW_FUN_EXPORT PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT;
+GLEW_FUN_EXPORT PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT;
+GLEW_FUN_EXPORT PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYCOLOROFFSETEXTPROC __glewVertexArrayColorOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC __glewVertexArrayEdgeFlagOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC __glewVertexArrayFogCoordOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYINDEXOFFSETEXTPROC __glewVertexArrayIndexOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC __glewVertexArrayMultiTexCoordOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYNORMALOFFSETEXTPROC __glewVertexArrayNormalOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC __glewVertexArraySecondaryColorOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC __glewVertexArrayTexCoordOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC __glewVertexArrayVertexAttribIOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC __glewVertexArrayVertexAttribOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC __glewVertexArrayVertexOffsetEXT;
+
+GLEW_FUN_EXPORT PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT;
+GLEW_FUN_EXPORT PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT;
+GLEW_FUN_EXPORT PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT;
+GLEW_FUN_EXPORT PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT;
+GLEW_FUN_EXPORT PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT;
+GLEW_FUN_EXPORT PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT;
+
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT;
+GLEW_FUN_EXPORT PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT;
+
+GLEW_FUN_EXPORT PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT;
+
+GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT;
+GLEW_FUN_EXPORT PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT;
+GLEW_FUN_EXPORT PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT;
+GLEW_FUN_EXPORT PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT;
+GLEW_FUN_EXPORT PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT;
+
+GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT;
+GLEW_FUN_EXPORT PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT;
+
+GLEW_FUN_EXPORT PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT;
+
+GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT;
+
+GLEW_FUN_EXPORT PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT;
+GLEW_FUN_EXPORT PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT;
+GLEW_FUN_EXPORT PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT;
+GLEW_FUN_EXPORT PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT;
+GLEW_FUN_EXPORT PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT;
+GLEW_FUN_EXPORT PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT;
+GLEW_FUN_EXPORT PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT;
+GLEW_FUN_EXPORT PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT;
+GLEW_FUN_EXPORT PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT;
+GLEW_FUN_EXPORT PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT;
+GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT;
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT;
+
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT;
+
+GLEW_FUN_EXPORT PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT;
+GLEW_FUN_EXPORT PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT;
+GLEW_FUN_EXPORT PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT;
+
+GLEW_FUN_EXPORT PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT;
+GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT;
+GLEW_FUN_EXPORT PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT;
+GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT;
+GLEW_FUN_EXPORT PFNGLHISTOGRAMEXTPROC __glewHistogramEXT;
+GLEW_FUN_EXPORT PFNGLMINMAXEXTPROC __glewMinmaxEXT;
+GLEW_FUN_EXPORT PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT;
+GLEW_FUN_EXPORT PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT;
+
+GLEW_FUN_EXPORT PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT;
+
+GLEW_FUN_EXPORT PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT;
+
+GLEW_FUN_EXPORT PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT;
+GLEW_FUN_EXPORT PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT;
+GLEW_FUN_EXPORT PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT;
+
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT;
+
+GLEW_FUN_EXPORT PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT;
+GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT;
+
+GLEW_FUN_EXPORT PFNGLCOLORTABLEEXTPROC __glewColorTableEXT;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT;
+
+GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT;
+GLEW_FUN_EXPORT PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT;
+
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT;
+
+GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT;
+
+GLEW_FUN_EXPORT PFNGLPROVOKINGVERTEXEXTPROC __glewProvokingVertexEXT;
+
+GLEW_FUN_EXPORT PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT;
+GLEW_FUN_EXPORT PFNGLENDSCENEEXTPROC __glewEndSceneEXT;
+
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT;
+
+GLEW_FUN_EXPORT PFNGLACTIVEPROGRAMEXTPROC __glewActiveProgramEXT;
+GLEW_FUN_EXPORT PFNGLCREATESHADERPROGRAMEXTPROC __glewCreateShaderProgramEXT;
+GLEW_FUN_EXPORT PFNGLUSESHADERPROGRAMEXTPROC __glewUseShaderProgramEXT;
+
+GLEW_FUN_EXPORT PFNGLBINDIMAGETEXTUREEXTPROC __glewBindImageTextureEXT;
+GLEW_FUN_EXPORT PFNGLMEMORYBARRIEREXTPROC __glewMemoryBarrierEXT;
+
+GLEW_FUN_EXPORT PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT;
+
+GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT;
+GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT;
+GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT;
+
+GLEW_FUN_EXPORT PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT;
+
+GLEW_FUN_EXPORT PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT;
+
+GLEW_FUN_EXPORT PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT;
+
+GLEW_FUN_EXPORT PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT;
+GLEW_FUN_EXPORT PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT;
+GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT;
+
+GLEW_FUN_EXPORT PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT;
+GLEW_FUN_EXPORT PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT;
+GLEW_FUN_EXPORT PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT;
+GLEW_FUN_EXPORT PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT;
+GLEW_FUN_EXPORT PFNGLISTEXTUREEXTPROC __glewIsTextureEXT;
+GLEW_FUN_EXPORT PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT;
+
+GLEW_FUN_EXPORT PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT;
+
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT;
+GLEW_FUN_EXPORT PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT;
+
+GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT;
+GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT;
+GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT;
+GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT;
+GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT;
+
+GLEW_FUN_EXPORT PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT;
+GLEW_FUN_EXPORT PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT;
+GLEW_FUN_EXPORT PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT;
+GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT;
+GLEW_FUN_EXPORT PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT;
+GLEW_FUN_EXPORT PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT;
+GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT;
+
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLDVEXTPROC __glewGetVertexAttribLdvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC __glewVertexArrayVertexAttribLOffsetEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DEXTPROC __glewVertexAttribL1dEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1DVEXTPROC __glewVertexAttribL1dvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DEXTPROC __glewVertexAttribL2dEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2DVEXTPROC __glewVertexAttribL2dvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DEXTPROC __glewVertexAttribL3dEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3DVEXTPROC __glewVertexAttribL3dvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DEXTPROC __glewVertexAttribL4dEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4DVEXTPROC __glewVertexAttribL4dvEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLPOINTEREXTPROC __glewVertexAttribLPointerEXT;
+
+GLEW_FUN_EXPORT PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT;
+GLEW_FUN_EXPORT PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT;
+GLEW_FUN_EXPORT PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT;
+GLEW_FUN_EXPORT PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT;
+GLEW_FUN_EXPORT PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT;
+GLEW_FUN_EXPORT PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT;
+GLEW_FUN_EXPORT PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT;
+GLEW_FUN_EXPORT PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT;
+GLEW_FUN_EXPORT PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT;
+GLEW_FUN_EXPORT PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT;
+GLEW_FUN_EXPORT PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT;
+GLEW_FUN_EXPORT PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT;
+GLEW_FUN_EXPORT PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT;
+GLEW_FUN_EXPORT PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT;
+GLEW_FUN_EXPORT PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT;
+GLEW_FUN_EXPORT PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT;
+GLEW_FUN_EXPORT PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT;
+GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT;
+GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT;
+GLEW_FUN_EXPORT PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT;
+GLEW_FUN_EXPORT PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT;
+GLEW_FUN_EXPORT PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT;
+GLEW_FUN_EXPORT PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT;
+GLEW_FUN_EXPORT PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT;
+GLEW_FUN_EXPORT PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT;
+GLEW_FUN_EXPORT PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT;
+GLEW_FUN_EXPORT PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT;
+GLEW_FUN_EXPORT PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT;
+GLEW_FUN_EXPORT PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT;
+GLEW_FUN_EXPORT PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT;
+GLEW_FUN_EXPORT PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT;
+GLEW_FUN_EXPORT PFNGLSWIZZLEEXTPROC __glewSwizzleEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTBVEXTPROC __glewVariantbvEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTDVEXTPROC __glewVariantdvEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTFVEXTPROC __glewVariantfvEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTIVEXTPROC __glewVariantivEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTSVEXTPROC __glewVariantsvEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT;
+GLEW_FUN_EXPORT PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT;
+GLEW_FUN_EXPORT PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT;
+
+GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT;
+GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT;
+
+GLEW_FUN_EXPORT PFNGLIMPORTSYNCEXTPROC __glewImportSyncEXT;
+
+GLEW_FUN_EXPORT PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY;
+
+GLEW_FUN_EXPORT PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY;
+
+GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP;
+GLEW_FUN_EXPORT PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP;
+GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP;
+GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP;
+GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP;
+GLEW_FUN_EXPORT PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP;
+
+GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM;
+GLEW_FUN_EXPORT PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM;
+
+GLEW_FUN_EXPORT PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM;
+GLEW_FUN_EXPORT PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM;
+GLEW_FUN_EXPORT PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM;
+GLEW_FUN_EXPORT PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM;
+GLEW_FUN_EXPORT PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM;
+GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM;
+GLEW_FUN_EXPORT PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM;
+
+GLEW_FUN_EXPORT PFNGLMAPTEXTURE2DINTELPROC __glewMapTexture2DINTEL;
+GLEW_FUN_EXPORT PFNGLSYNCTEXTUREINTELPROC __glewSyncTextureINTEL;
+GLEW_FUN_EXPORT PFNGLUNMAPTEXTURE2DINTELPROC __glewUnmapTexture2DINTEL;
+
+GLEW_FUN_EXPORT PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL;
+GLEW_FUN_EXPORT PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL;
+GLEW_FUN_EXPORT PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL;
+GLEW_FUN_EXPORT PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL;
+
+GLEW_FUN_EXPORT PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL;
+GLEW_FUN_EXPORT PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL;
+
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECALLBACKPROC __glewDebugMessageCallback;
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGECONTROLPROC __glewDebugMessageControl;
+GLEW_FUN_EXPORT PFNGLDEBUGMESSAGEINSERTPROC __glewDebugMessageInsert;
+GLEW_FUN_EXPORT PFNGLGETDEBUGMESSAGELOGPROC __glewGetDebugMessageLog;
+GLEW_FUN_EXPORT PFNGLGETOBJECTLABELPROC __glewGetObjectLabel;
+GLEW_FUN_EXPORT PFNGLGETOBJECTPTRLABELPROC __glewGetObjectPtrLabel;
+GLEW_FUN_EXPORT PFNGLOBJECTLABELPROC __glewObjectLabel;
+GLEW_FUN_EXPORT PFNGLOBJECTPTRLABELPROC __glewObjectPtrLabel;
+GLEW_FUN_EXPORT PFNGLPOPDEBUGGROUPPROC __glewPopDebugGroup;
+GLEW_FUN_EXPORT PFNGLPUSHDEBUGGROUPPROC __glewPushDebugGroup;
+
+GLEW_FUN_EXPORT PFNGLBUFFERREGIONENABLEDPROC __glewBufferRegionEnabled;
+GLEW_FUN_EXPORT PFNGLDELETEBUFFERREGIONPROC __glewDeleteBufferRegion;
+GLEW_FUN_EXPORT PFNGLDRAWBUFFERREGIONPROC __glewDrawBufferRegion;
+GLEW_FUN_EXPORT PFNGLNEWBUFFERREGIONPROC __glewNewBufferRegion;
+GLEW_FUN_EXPORT PFNGLREADBUFFERREGIONPROC __glewReadBufferRegion;
+
+GLEW_FUN_EXPORT PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA;
+
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA;
+GLEW_FUN_EXPORT PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA;
+
+GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVXPROC __glewBeginConditionalRenderNVX;
+GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVXPROC __glewEndConditionalRenderNVX;
+
+GLEW_FUN_EXPORT PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC __glewMultiDrawArraysIndirectBindlessNV;
+GLEW_FUN_EXPORT PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC __glewMultiDrawElementsIndirectBindlessNV;
+
+GLEW_FUN_EXPORT PFNGLGETIMAGEHANDLENVPROC __glewGetImageHandleNV;
+GLEW_FUN_EXPORT PFNGLGETTEXTUREHANDLENVPROC __glewGetTextureHandleNV;
+GLEW_FUN_EXPORT PFNGLGETTEXTURESAMPLERHANDLENVPROC __glewGetTextureSamplerHandleNV;
+GLEW_FUN_EXPORT PFNGLISIMAGEHANDLERESIDENTNVPROC __glewIsImageHandleResidentNV;
+GLEW_FUN_EXPORT PFNGLISTEXTUREHANDLERESIDENTNVPROC __glewIsTextureHandleResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC __glewMakeImageHandleNonResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKEIMAGEHANDLERESIDENTNVPROC __glewMakeImageHandleResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC __glewMakeTextureHandleNonResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKETEXTUREHANDLERESIDENTNVPROC __glewMakeTextureHandleResidentNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC __glewProgramUniformHandleui64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC __glewProgramUniformHandleui64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64NVPROC __glewUniformHandleui64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORMHANDLEUI64VNVPROC __glewUniformHandleui64vNV;
+
+GLEW_FUN_EXPORT PFNGLBLENDBARRIERNVPROC __glewBlendBarrierNV;
+GLEW_FUN_EXPORT PFNGLBLENDPARAMETERINVPROC __glewBlendParameteriNV;
+
+GLEW_FUN_EXPORT PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV;
+GLEW_FUN_EXPORT PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV;
+
+GLEW_FUN_EXPORT PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV;
+
+GLEW_FUN_EXPORT PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV;
+GLEW_FUN_EXPORT PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV;
+GLEW_FUN_EXPORT PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV;
+
+GLEW_FUN_EXPORT PFNGLDRAWTEXTURENVPROC __glewDrawTextureNV;
+
+GLEW_FUN_EXPORT PFNGLEVALMAPSNVPROC __glewEvalMapsNV;
+GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV;
+GLEW_FUN_EXPORT PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV;
+GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV;
+GLEW_FUN_EXPORT PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV;
+GLEW_FUN_EXPORT PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV;
+GLEW_FUN_EXPORT PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV;
+
+GLEW_FUN_EXPORT PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV;
+GLEW_FUN_EXPORT PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV;
+GLEW_FUN_EXPORT PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV;
+
+GLEW_FUN_EXPORT PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV;
+GLEW_FUN_EXPORT PFNGLFINISHFENCENVPROC __glewFinishFenceNV;
+GLEW_FUN_EXPORT PFNGLGENFENCESNVPROC __glewGenFencesNV;
+GLEW_FUN_EXPORT PFNGLGETFENCEIVNVPROC __glewGetFenceivNV;
+GLEW_FUN_EXPORT PFNGLISFENCENVPROC __glewIsFenceNV;
+GLEW_FUN_EXPORT PFNGLSETFENCENVPROC __glewSetFenceNV;
+GLEW_FUN_EXPORT PFNGLTESTFENCENVPROC __glewTestFenceNV;
+
+GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV;
+
+GLEW_FUN_EXPORT PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV;
+
+GLEW_FUN_EXPORT PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV;
+
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV;
+
+GLEW_FUN_EXPORT PFNGLGETUNIFORMI64VNVPROC __glewGetUniformi64vNV;
+GLEW_FUN_EXPORT PFNGLGETUNIFORMUI64VNVPROC __glewGetUniformui64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64NVPROC __glewProgramUniform1i64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1I64VNVPROC __glewProgramUniform1i64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64NVPROC __glewProgramUniform1ui64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM1UI64VNVPROC __glewProgramUniform1ui64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64NVPROC __glewProgramUniform2i64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2I64VNVPROC __glewProgramUniform2i64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64NVPROC __glewProgramUniform2ui64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM2UI64VNVPROC __glewProgramUniform2ui64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64NVPROC __glewProgramUniform3i64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3I64VNVPROC __glewProgramUniform3i64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64NVPROC __glewProgramUniform3ui64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM3UI64VNVPROC __glewProgramUniform3ui64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64NVPROC __glewProgramUniform4i64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4I64VNVPROC __glewProgramUniform4i64vNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64NVPROC __glewProgramUniform4ui64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORM4UI64VNVPROC __glewProgramUniform4ui64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM1I64NVPROC __glewUniform1i64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM1I64VNVPROC __glewUniform1i64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM1UI64NVPROC __glewUniform1ui64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM1UI64VNVPROC __glewUniform1ui64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM2I64NVPROC __glewUniform2i64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM2I64VNVPROC __glewUniform2i64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM2UI64NVPROC __glewUniform2ui64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM2UI64VNVPROC __glewUniform2ui64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM3I64NVPROC __glewUniform3i64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM3I64VNVPROC __glewUniform3i64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM3UI64NVPROC __glewUniform3ui64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM3UI64VNVPROC __glewUniform3ui64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM4I64NVPROC __glewUniform4i64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM4I64VNVPROC __glewUniform4i64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORM4UI64NVPROC __glewUniform4ui64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORM4UI64VNVPROC __glewUniform4ui64vNV;
+
+GLEW_FUN_EXPORT PFNGLCOLOR3HNVPROC __glewColor3hNV;
+GLEW_FUN_EXPORT PFNGLCOLOR3HVNVPROC __glewColor3hvNV;
+GLEW_FUN_EXPORT PFNGLCOLOR4HNVPROC __glewColor4hNV;
+GLEW_FUN_EXPORT PFNGLCOLOR4HVNVPROC __glewColor4hvNV;
+GLEW_FUN_EXPORT PFNGLFOGCOORDHNVPROC __glewFogCoordhNV;
+GLEW_FUN_EXPORT PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV;
+GLEW_FUN_EXPORT PFNGLNORMAL3HNVPROC __glewNormal3hNV;
+GLEW_FUN_EXPORT PFNGLNORMAL3HVNVPROC __glewNormal3hvNV;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEX2HNVPROC __glewVertex2hNV;
+GLEW_FUN_EXPORT PFNGLVERTEX2HVNVPROC __glewVertex2hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEX3HNVPROC __glewVertex3hNV;
+GLEW_FUN_EXPORT PFNGLVERTEX3HVNVPROC __glewVertex3hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEX4HNVPROC __glewVertex4hNV;
+GLEW_FUN_EXPORT PFNGLVERTEX4HVNVPROC __glewVertex4hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV;
+GLEW_FUN_EXPORT PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV;
+
+GLEW_FUN_EXPORT PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV;
+GLEW_FUN_EXPORT PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV;
+GLEW_FUN_EXPORT PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV;
+GLEW_FUN_EXPORT PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV;
+GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV;
+GLEW_FUN_EXPORT PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV;
+GLEW_FUN_EXPORT PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV;
+
+GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV;
+
+GLEW_FUN_EXPORT PFNGLCOPYPATHNVPROC __glewCopyPathNV;
+GLEW_FUN_EXPORT PFNGLCOVERFILLPATHINSTANCEDNVPROC __glewCoverFillPathInstancedNV;
+GLEW_FUN_EXPORT PFNGLCOVERFILLPATHNVPROC __glewCoverFillPathNV;
+GLEW_FUN_EXPORT PFNGLCOVERSTROKEPATHINSTANCEDNVPROC __glewCoverStrokePathInstancedNV;
+GLEW_FUN_EXPORT PFNGLCOVERSTROKEPATHNVPROC __glewCoverStrokePathNV;
+GLEW_FUN_EXPORT PFNGLDELETEPATHSNVPROC __glewDeletePathsNV;
+GLEW_FUN_EXPORT PFNGLGENPATHSNVPROC __glewGenPathsNV;
+GLEW_FUN_EXPORT PFNGLGETPATHCOLORGENFVNVPROC __glewGetPathColorGenfvNV;
+GLEW_FUN_EXPORT PFNGLGETPATHCOLORGENIVNVPROC __glewGetPathColorGenivNV;
+GLEW_FUN_EXPORT PFNGLGETPATHCOMMANDSNVPROC __glewGetPathCommandsNV;
+GLEW_FUN_EXPORT PFNGLGETPATHCOORDSNVPROC __glewGetPathCoordsNV;
+GLEW_FUN_EXPORT PFNGLGETPATHDASHARRAYNVPROC __glewGetPathDashArrayNV;
+GLEW_FUN_EXPORT PFNGLGETPATHLENGTHNVPROC __glewGetPathLengthNV;
+GLEW_FUN_EXPORT PFNGLGETPATHMETRICRANGENVPROC __glewGetPathMetricRangeNV;
+GLEW_FUN_EXPORT PFNGLGETPATHMETRICSNVPROC __glewGetPathMetricsNV;
+GLEW_FUN_EXPORT PFNGLGETPATHPARAMETERFVNVPROC __glewGetPathParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETPATHPARAMETERIVNVPROC __glewGetPathParameterivNV;
+GLEW_FUN_EXPORT PFNGLGETPATHSPACINGNVPROC __glewGetPathSpacingNV;
+GLEW_FUN_EXPORT PFNGLGETPATHTEXGENFVNVPROC __glewGetPathTexGenfvNV;
+GLEW_FUN_EXPORT PFNGLGETPATHTEXGENIVNVPROC __glewGetPathTexGenivNV;
+GLEW_FUN_EXPORT PFNGLINTERPOLATEPATHSNVPROC __glewInterpolatePathsNV;
+GLEW_FUN_EXPORT PFNGLISPATHNVPROC __glewIsPathNV;
+GLEW_FUN_EXPORT PFNGLISPOINTINFILLPATHNVPROC __glewIsPointInFillPathNV;
+GLEW_FUN_EXPORT PFNGLISPOINTINSTROKEPATHNVPROC __glewIsPointInStrokePathNV;
+GLEW_FUN_EXPORT PFNGLPATHCOLORGENNVPROC __glewPathColorGenNV;
+GLEW_FUN_EXPORT PFNGLPATHCOMMANDSNVPROC __glewPathCommandsNV;
+GLEW_FUN_EXPORT PFNGLPATHCOORDSNVPROC __glewPathCoordsNV;
+GLEW_FUN_EXPORT PFNGLPATHCOVERDEPTHFUNCNVPROC __glewPathCoverDepthFuncNV;
+GLEW_FUN_EXPORT PFNGLPATHDASHARRAYNVPROC __glewPathDashArrayNV;
+GLEW_FUN_EXPORT PFNGLPATHFOGGENNVPROC __glewPathFogGenNV;
+GLEW_FUN_EXPORT PFNGLPATHGLYPHRANGENVPROC __glewPathGlyphRangeNV;
+GLEW_FUN_EXPORT PFNGLPATHGLYPHSNVPROC __glewPathGlyphsNV;
+GLEW_FUN_EXPORT PFNGLPATHPARAMETERFNVPROC __glewPathParameterfNV;
+GLEW_FUN_EXPORT PFNGLPATHPARAMETERFVNVPROC __glewPathParameterfvNV;
+GLEW_FUN_EXPORT PFNGLPATHPARAMETERINVPROC __glewPathParameteriNV;
+GLEW_FUN_EXPORT PFNGLPATHPARAMETERIVNVPROC __glewPathParameterivNV;
+GLEW_FUN_EXPORT PFNGLPATHSTENCILDEPTHOFFSETNVPROC __glewPathStencilDepthOffsetNV;
+GLEW_FUN_EXPORT PFNGLPATHSTENCILFUNCNVPROC __glewPathStencilFuncNV;
+GLEW_FUN_EXPORT PFNGLPATHSTRINGNVPROC __glewPathStringNV;
+GLEW_FUN_EXPORT PFNGLPATHSUBCOMMANDSNVPROC __glewPathSubCommandsNV;
+GLEW_FUN_EXPORT PFNGLPATHSUBCOORDSNVPROC __glewPathSubCoordsNV;
+GLEW_FUN_EXPORT PFNGLPATHTEXGENNVPROC __glewPathTexGenNV;
+GLEW_FUN_EXPORT PFNGLPOINTALONGPATHNVPROC __glewPointAlongPathNV;
+GLEW_FUN_EXPORT PFNGLSTENCILFILLPATHINSTANCEDNVPROC __glewStencilFillPathInstancedNV;
+GLEW_FUN_EXPORT PFNGLSTENCILFILLPATHNVPROC __glewStencilFillPathNV;
+GLEW_FUN_EXPORT PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC __glewStencilStrokePathInstancedNV;
+GLEW_FUN_EXPORT PFNGLSTENCILSTROKEPATHNVPROC __glewStencilStrokePathNV;
+GLEW_FUN_EXPORT PFNGLTRANSFORMPATHNVPROC __glewTransformPathNV;
+GLEW_FUN_EXPORT PFNGLWEIGHTPATHSNVPROC __glewWeightPathsNV;
+
+GLEW_FUN_EXPORT PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV;
+GLEW_FUN_EXPORT PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV;
+
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV;
+
+GLEW_FUN_EXPORT PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV;
+GLEW_FUN_EXPORT PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV;
+GLEW_FUN_EXPORT PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV;
+GLEW_FUN_EXPORT PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV;
+GLEW_FUN_EXPORT PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV;
+GLEW_FUN_EXPORT PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV;
+
+GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV;
+GLEW_FUN_EXPORT PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV;
+
+GLEW_FUN_EXPORT PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV;
+GLEW_FUN_EXPORT PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV;
+GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV;
+GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV;
+GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV;
+GLEW_FUN_EXPORT PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV;
+GLEW_FUN_EXPORT PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV;
+GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV;
+GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV;
+GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV;
+
+GLEW_FUN_EXPORT PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV;
+
+GLEW_FUN_EXPORT PFNGLGETBUFFERPARAMETERUI64VNVPROC __glewGetBufferParameterui64vNV;
+GLEW_FUN_EXPORT PFNGLGETINTEGERUI64VNVPROC __glewGetIntegerui64vNV;
+GLEW_FUN_EXPORT PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC __glewGetNamedBufferParameterui64vNV;
+GLEW_FUN_EXPORT PFNGLISBUFFERRESIDENTNVPROC __glewIsBufferResidentNV;
+GLEW_FUN_EXPORT PFNGLISNAMEDBUFFERRESIDENTNVPROC __glewIsNamedBufferResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKEBUFFERNONRESIDENTNVPROC __glewMakeBufferNonResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKEBUFFERRESIDENTNVPROC __glewMakeBufferResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC __glewMakeNamedBufferNonResidentNV;
+GLEW_FUN_EXPORT PFNGLMAKENAMEDBUFFERRESIDENTNVPROC __glewMakeNamedBufferResidentNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64NVPROC __glewProgramUniformui64NV;
+GLEW_FUN_EXPORT PFNGLPROGRAMUNIFORMUI64VNVPROC __glewProgramUniformui64vNV;
+GLEW_FUN_EXPORT PFNGLUNIFORMUI64NVPROC __glewUniformui64NV;
+GLEW_FUN_EXPORT PFNGLUNIFORMUI64VNVPROC __glewUniformui64vNV;
+
+GLEW_FUN_EXPORT PFNGLTEXTUREBARRIERNVPROC __glewTextureBarrierNV;
+
+GLEW_FUN_EXPORT PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTexImage2DMultisampleCoverageNV;
+GLEW_FUN_EXPORT PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTexImage3DMultisampleCoverageNV;
+GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTextureImage2DMultisampleCoverageNV;
+GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC __glewTextureImage2DMultisampleNV;
+GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTextureImage3DMultisampleCoverageNV;
+GLEW_FUN_EXPORT PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC __glewTextureImage3DMultisampleNV;
+
+GLEW_FUN_EXPORT PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV;
+GLEW_FUN_EXPORT PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV;
+GLEW_FUN_EXPORT PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV;
+GLEW_FUN_EXPORT PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV;
+GLEW_FUN_EXPORT PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV;
+GLEW_FUN_EXPORT PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV;
+GLEW_FUN_EXPORT PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV;
+GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV;
+GLEW_FUN_EXPORT PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV;
+
+GLEW_FUN_EXPORT PFNGLBINDTRANSFORMFEEDBACKNVPROC __glewBindTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLDELETETRANSFORMFEEDBACKSNVPROC __glewDeleteTransformFeedbacksNV;
+GLEW_FUN_EXPORT PFNGLDRAWTRANSFORMFEEDBACKNVPROC __glewDrawTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLGENTRANSFORMFEEDBACKSNVPROC __glewGenTransformFeedbacksNV;
+GLEW_FUN_EXPORT PFNGLISTRANSFORMFEEDBACKNVPROC __glewIsTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLPAUSETRANSFORMFEEDBACKNVPROC __glewPauseTransformFeedbackNV;
+GLEW_FUN_EXPORT PFNGLRESUMETRANSFORMFEEDBACKNVPROC __glewResumeTransformFeedbackNV;
+
+GLEW_FUN_EXPORT PFNGLVDPAUFININVPROC __glewVDPAUFiniNV;
+GLEW_FUN_EXPORT PFNGLVDPAUGETSURFACEIVNVPROC __glewVDPAUGetSurfaceivNV;
+GLEW_FUN_EXPORT PFNGLVDPAUINITNVPROC __glewVDPAUInitNV;
+GLEW_FUN_EXPORT PFNGLVDPAUISSURFACENVPROC __glewVDPAUIsSurfaceNV;
+GLEW_FUN_EXPORT PFNGLVDPAUMAPSURFACESNVPROC __glewVDPAUMapSurfacesNV;
+GLEW_FUN_EXPORT PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC __glewVDPAURegisterOutputSurfaceNV;
+GLEW_FUN_EXPORT PFNGLVDPAUREGISTERVIDEOSURFACENVPROC __glewVDPAURegisterVideoSurfaceNV;
+GLEW_FUN_EXPORT PFNGLVDPAUSURFACEACCESSNVPROC __glewVDPAUSurfaceAccessNV;
+GLEW_FUN_EXPORT PFNGLVDPAUUNMAPSURFACESNVPROC __glewVDPAUUnmapSurfacesNV;
+GLEW_FUN_EXPORT PFNGLVDPAUUNREGISTERSURFACENVPROC __glewVDPAUUnregisterSurfaceNV;
+
+GLEW_FUN_EXPORT PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV;
+GLEW_FUN_EXPORT PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV;
+
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLI64VNVPROC __glewGetVertexAttribLi64vNV;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBLUI64VNVPROC __glewGetVertexAttribLui64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1I64NVPROC __glewVertexAttribL1i64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1I64VNVPROC __glewVertexAttribL1i64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64NVPROC __glewVertexAttribL1ui64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL1UI64VNVPROC __glewVertexAttribL1ui64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2I64NVPROC __glewVertexAttribL2i64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2I64VNVPROC __glewVertexAttribL2i64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2UI64NVPROC __glewVertexAttribL2ui64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL2UI64VNVPROC __glewVertexAttribL2ui64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3I64NVPROC __glewVertexAttribL3i64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3I64VNVPROC __glewVertexAttribL3i64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3UI64NVPROC __glewVertexAttribL3ui64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL3UI64VNVPROC __glewVertexAttribL3ui64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4I64NVPROC __glewVertexAttribL4i64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4I64VNVPROC __glewVertexAttribL4i64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4UI64NVPROC __glewVertexAttribL4ui64NV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBL4UI64VNVPROC __glewVertexAttribL4ui64vNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBLFORMATNVPROC __glewVertexAttribLFormatNV;
+
+GLEW_FUN_EXPORT PFNGLBUFFERADDRESSRANGENVPROC __glewBufferAddressRangeNV;
+GLEW_FUN_EXPORT PFNGLCOLORFORMATNVPROC __glewColorFormatNV;
+GLEW_FUN_EXPORT PFNGLEDGEFLAGFORMATNVPROC __glewEdgeFlagFormatNV;
+GLEW_FUN_EXPORT PFNGLFOGCOORDFORMATNVPROC __glewFogCoordFormatNV;
+GLEW_FUN_EXPORT PFNGLGETINTEGERUI64I_VNVPROC __glewGetIntegerui64i_vNV;
+GLEW_FUN_EXPORT PFNGLINDEXFORMATNVPROC __glewIndexFormatNV;
+GLEW_FUN_EXPORT PFNGLNORMALFORMATNVPROC __glewNormalFormatNV;
+GLEW_FUN_EXPORT PFNGLSECONDARYCOLORFORMATNVPROC __glewSecondaryColorFormatNV;
+GLEW_FUN_EXPORT PFNGLTEXCOORDFORMATNVPROC __glewTexCoordFormatNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBFORMATNVPROC __glewVertexAttribFormatNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBIFORMATNVPROC __glewVertexAttribIFormatNV;
+GLEW_FUN_EXPORT PFNGLVERTEXFORMATNVPROC __glewVertexFormatNV;
+
+GLEW_FUN_EXPORT PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV;
+GLEW_FUN_EXPORT PFNGLBINDPROGRAMNVPROC __glewBindProgramNV;
+GLEW_FUN_EXPORT PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV;
+GLEW_FUN_EXPORT PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV;
+GLEW_FUN_EXPORT PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV;
+GLEW_FUN_EXPORT PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV;
+GLEW_FUN_EXPORT PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV;
+GLEW_FUN_EXPORT PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV;
+GLEW_FUN_EXPORT PFNGLISPROGRAMNVPROC __glewIsProgramNV;
+GLEW_FUN_EXPORT PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV;
+GLEW_FUN_EXPORT PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV;
+GLEW_FUN_EXPORT PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV;
+GLEW_FUN_EXPORT PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV;
+GLEW_FUN_EXPORT PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV;
+
+GLEW_FUN_EXPORT PFNGLBEGINVIDEOCAPTURENVPROC __glewBeginVideoCaptureNV;
+GLEW_FUN_EXPORT PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC __glewBindVideoCaptureStreamBufferNV;
+GLEW_FUN_EXPORT PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC __glewBindVideoCaptureStreamTextureNV;
+GLEW_FUN_EXPORT PFNGLENDVIDEOCAPTURENVPROC __glewEndVideoCaptureNV;
+GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMDVNVPROC __glewGetVideoCaptureStreamdvNV;
+GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMFVNVPROC __glewGetVideoCaptureStreamfvNV;
+GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTURESTREAMIVNVPROC __glewGetVideoCaptureStreamivNV;
+GLEW_FUN_EXPORT PFNGLGETVIDEOCAPTUREIVNVPROC __glewGetVideoCaptureivNV;
+GLEW_FUN_EXPORT PFNGLVIDEOCAPTURENVPROC __glewVideoCaptureNV;
+GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC __glewVideoCaptureStreamParameterdvNV;
+GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC __glewVideoCaptureStreamParameterfvNV;
+GLEW_FUN_EXPORT PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC __glewVideoCaptureStreamParameterivNV;
+
+GLEW_FUN_EXPORT PFNGLCLEARDEPTHFOESPROC __glewClearDepthfOES;
+GLEW_FUN_EXPORT PFNGLCLIPPLANEFOESPROC __glewClipPlanefOES;
+GLEW_FUN_EXPORT PFNGLDEPTHRANGEFOESPROC __glewDepthRangefOES;
+GLEW_FUN_EXPORT PFNGLFRUSTUMFOESPROC __glewFrustumfOES;
+GLEW_FUN_EXPORT PFNGLGETCLIPPLANEFOESPROC __glewGetClipPlanefOES;
+GLEW_FUN_EXPORT PFNGLORTHOFOESPROC __glewOrthofOES;
+
+GLEW_FUN_EXPORT PFNGLALPHAFUNCXPROC __glewAlphaFuncx;
+GLEW_FUN_EXPORT PFNGLCLEARCOLORXPROC __glewClearColorx;
+GLEW_FUN_EXPORT PFNGLCLEARDEPTHXPROC __glewClearDepthx;
+GLEW_FUN_EXPORT PFNGLCOLOR4XPROC __glewColor4x;
+GLEW_FUN_EXPORT PFNGLDEPTHRANGEXPROC __glewDepthRangex;
+GLEW_FUN_EXPORT PFNGLFOGXPROC __glewFogx;
+GLEW_FUN_EXPORT PFNGLFOGXVPROC __glewFogxv;
+GLEW_FUN_EXPORT PFNGLFRUSTUMFPROC __glewFrustumf;
+GLEW_FUN_EXPORT PFNGLFRUSTUMXPROC __glewFrustumx;
+GLEW_FUN_EXPORT PFNGLLIGHTMODELXPROC __glewLightModelx;
+GLEW_FUN_EXPORT PFNGLLIGHTMODELXVPROC __glewLightModelxv;
+GLEW_FUN_EXPORT PFNGLLIGHTXPROC __glewLightx;
+GLEW_FUN_EXPORT PFNGLLIGHTXVPROC __glewLightxv;
+GLEW_FUN_EXPORT PFNGLLINEWIDTHXPROC __glewLineWidthx;
+GLEW_FUN_EXPORT PFNGLLOADMATRIXXPROC __glewLoadMatrixx;
+GLEW_FUN_EXPORT PFNGLMATERIALXPROC __glewMaterialx;
+GLEW_FUN_EXPORT PFNGLMATERIALXVPROC __glewMaterialxv;
+GLEW_FUN_EXPORT PFNGLMULTMATRIXXPROC __glewMultMatrixx;
+GLEW_FUN_EXPORT PFNGLMULTITEXCOORD4XPROC __glewMultiTexCoord4x;
+GLEW_FUN_EXPORT PFNGLNORMAL3XPROC __glewNormal3x;
+GLEW_FUN_EXPORT PFNGLORTHOFPROC __glewOrthof;
+GLEW_FUN_EXPORT PFNGLORTHOXPROC __glewOrthox;
+GLEW_FUN_EXPORT PFNGLPOINTSIZEXPROC __glewPointSizex;
+GLEW_FUN_EXPORT PFNGLPOLYGONOFFSETXPROC __glewPolygonOffsetx;
+GLEW_FUN_EXPORT PFNGLROTATEXPROC __glewRotatex;
+GLEW_FUN_EXPORT PFNGLSAMPLECOVERAGEXPROC __glewSampleCoveragex;
+GLEW_FUN_EXPORT PFNGLSCALEXPROC __glewScalex;
+GLEW_FUN_EXPORT PFNGLTEXENVXPROC __glewTexEnvx;
+GLEW_FUN_EXPORT PFNGLTEXENVXVPROC __glewTexEnvxv;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERXPROC __glewTexParameterx;
+GLEW_FUN_EXPORT PFNGLTRANSLATEXPROC __glewTranslatex;
+
+GLEW_FUN_EXPORT PFNGLCLIPPLANEFPROC __glewClipPlanef;
+GLEW_FUN_EXPORT PFNGLCLIPPLANEXPROC __glewClipPlanex;
+GLEW_FUN_EXPORT PFNGLGETCLIPPLANEFPROC __glewGetClipPlanef;
+GLEW_FUN_EXPORT PFNGLGETCLIPPLANEXPROC __glewGetClipPlanex;
+GLEW_FUN_EXPORT PFNGLGETFIXEDVPROC __glewGetFixedv;
+GLEW_FUN_EXPORT PFNGLGETLIGHTXVPROC __glewGetLightxv;
+GLEW_FUN_EXPORT PFNGLGETMATERIALXVPROC __glewGetMaterialxv;
+GLEW_FUN_EXPORT PFNGLGETTEXENVXVPROC __glewGetTexEnvxv;
+GLEW_FUN_EXPORT PFNGLGETTEXPARAMETERXVPROC __glewGetTexParameterxv;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERXPROC __glewPointParameterx;
+GLEW_FUN_EXPORT PFNGLPOINTPARAMETERXVPROC __glewPointParameterxv;
+GLEW_FUN_EXPORT PFNGLPOINTSIZEPOINTEROESPROC __glewPointSizePointerOES;
+GLEW_FUN_EXPORT PFNGLTEXPARAMETERXVPROC __glewTexParameterxv;
+
+GLEW_FUN_EXPORT PFNGLERRORSTRINGREGALPROC __glewErrorStringREGAL;
+
+GLEW_FUN_EXPORT PFNGLGETEXTENSIONREGALPROC __glewGetExtensionREGAL;
+GLEW_FUN_EXPORT PFNGLISSUPPORTEDREGALPROC __glewIsSupportedREGAL;
+
+GLEW_FUN_EXPORT PFNGLLOGMESSAGECALLBACKREGALPROC __glewLogMessageCallbackREGAL;
+
+GLEW_FUN_EXPORT PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS;
+GLEW_FUN_EXPORT PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS;
+
+GLEW_FUN_EXPORT PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS;
+GLEW_FUN_EXPORT PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS;
+
+GLEW_FUN_EXPORT PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS;
+GLEW_FUN_EXPORT PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS;
+
+GLEW_FUN_EXPORT PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS;
+GLEW_FUN_EXPORT PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS;
+
+GLEW_FUN_EXPORT PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS;
+GLEW_FUN_EXPORT PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS;
+
+GLEW_FUN_EXPORT PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS;
+GLEW_FUN_EXPORT PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS;
+
+GLEW_FUN_EXPORT PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX;
+GLEW_FUN_EXPORT PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX;
+GLEW_FUN_EXPORT PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX;
+GLEW_FUN_EXPORT PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX;
+GLEW_FUN_EXPORT PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX;
+GLEW_FUN_EXPORT PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX;
+
+GLEW_FUN_EXPORT PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX;
+
+GLEW_FUN_EXPORT PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX;
+
+GLEW_FUN_EXPORT PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX;
+GLEW_FUN_EXPORT PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX;
+GLEW_FUN_EXPORT PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX;
+
+GLEW_FUN_EXPORT PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX;
+
+GLEW_FUN_EXPORT PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX;
+
+GLEW_FUN_EXPORT PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX;
+
+GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX;
+GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX;
+GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX;
+GLEW_FUN_EXPORT PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX;
+
+GLEW_FUN_EXPORT PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX;
+
+GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI;
+GLEW_FUN_EXPORT PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI;
+GLEW_FUN_EXPORT PFNGLCOLORTABLESGIPROC __glewColorTableSGI;
+GLEW_FUN_EXPORT PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI;
+GLEW_FUN_EXPORT PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI;
+
+GLEW_FUN_EXPORT PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX;
+
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN;
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN;
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN;
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN;
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN;
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN;
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN;
+GLEW_FUN_EXPORT PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN;
+
+GLEW_FUN_EXPORT PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN;
+
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN;
+
+GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN;
+GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN;
+GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN;
+GLEW_FUN_EXPORT PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN;
+
+GLEW_FUN_EXPORT PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN;
+
+#if defined(GLEW_MX) && !defined(_WIN32)
+struct GLEWContextStruct
+{
+#endif /* GLEW_MX */
+
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_1;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_2_1;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_3;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_4;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_1_5;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_0;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_2_1;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_0;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_1;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_2;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_3_3;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_0;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_1;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_2;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_3;
+GLEW_VAR_EXPORT GLboolean __GLEW_VERSION_4_4;
+GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_tbuffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_3DFX_texture_compression_FXT1;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_blend_minmax_factor;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_conservative_depth;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_debug_output;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_depth_clamp_separate;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_draw_buffers_blend;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_interleaved_elements;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_multi_draw_indirect;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_name_gen_delete;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_performance_monitor;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_pinned_memory;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_query_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_sample_positions;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_seamless_cubemap_per_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_stencil_export;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_shader_trinary_minmax;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_sparse_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_stencil_operation_extended;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_texture_texture4;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_transform_feedback3_lines_triangles;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_layer;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_tessellator;
+GLEW_VAR_EXPORT GLboolean __GLEW_AMD_vertex_shader_viewport_index;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_depth_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_framebuffer_blit;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_framebuffer_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_instanced_arrays;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_pack_reverse_row_order;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_program_binary;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt1;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt3;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_compression_dxt5;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_texture_usage;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_timer_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_ANGLE_translated_shader_source;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_aux_depth_stencil;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_client_storage;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_element_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_fence;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_float_pixels;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_flush_buffer_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_object_purgeable;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_pixel_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_rgb_422;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_row_bytes;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_specular_vector;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_texture_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_transform_hint;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_array_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_vertex_program_evaluators;
+GLEW_VAR_EXPORT GLboolean __GLEW_APPLE_ycbcr_422;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES2_compatibility;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_ES3_compatibility;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_arrays_of_arrays;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_base_instance;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_bindless_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_blend_func_extended;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_buffer_storage;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_cl_event;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_clear_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_clear_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_color_buffer_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compatibility;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compressed_texture_pixel_storage;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compute_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_compute_variable_group_size;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_conservative_depth;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_copy_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_copy_image;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_debug_output;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_buffer_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_depth_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_buffers_blend;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_elements_base_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_indirect;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_draw_instanced;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_enhanced_layouts;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_explicit_attrib_location;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_explicit_uniform_location;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_coord_conventions;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_layer_viewport;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_program_shadow;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_fragment_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_no_attachments;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_framebuffer_sRGB;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_geometry_shader4;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_get_program_binary;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader5;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_gpu_shader_fp64;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_pixel;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_half_float_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_imaging;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_indirect_parameters;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_instanced_arrays;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_internalformat_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_internalformat_query2;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_invalidate_subdata;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_alignment;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_map_buffer_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_matrix_palette;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multi_bind;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multi_draw_indirect;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_multitexture;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_occlusion_query2;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_pixel_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_parameters;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_point_sprite;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_program_interface_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_provoking_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_query_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robust_buffer_access_behavior;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness_application_isolation;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_robustness_share_group_isolation;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sample_shading;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sampler_objects;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_seamless_cube_map;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_seamless_cubemap_per_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_separate_shader_objects;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_atomic_counters;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_bit_encoding;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_draw_parameters;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_group_vote;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_image_load_store;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_image_size;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_objects;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_precision;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_stencil_export;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_storage_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_subroutine;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shader_texture_lod;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_100;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_420pack;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_include;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shading_language_packing;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_shadow_ambient;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sparse_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_stencil_texturing;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_sync;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_tessellation_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_border_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_object_rgb32;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_buffer_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_bptc;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_compression_rgtc;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_cube_map_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_add;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_combine;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_crossbar;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_env_dot3;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_gather;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirror_clamp_to_edge;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_mirrored_repeat;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_non_power_of_two;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_query_levels;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_query_lod;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rectangle;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rg;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_rgb10_a2ui;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_stencil8;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_storage;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_storage_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_swizzle;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_texture_view;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_timer_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback2;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback3;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transform_feedback_instanced;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_transpose_matrix;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_uniform_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_bgra;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_array_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_attrib_64bit;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_attrib_binding;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_blend;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_program;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_type_10f_11f_11f_rev;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_vertex_type_2_10_10_10_rev;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_viewport_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_ARB_window_pos;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_point_sprites;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_combine3;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_texture_env_route;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATIX_vertex_shader_output_point_size;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_draw_buffers;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_element_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_envmap_bumpmap;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_fragment_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_map_object_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_meminfo;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_pn_triangles;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_separate_stencil;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_shader_texture_lod;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_text_fragment_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_compression_3dc;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_env_combine3;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_texture_mirror_once;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_array_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_attrib_array_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_ATI_vertex_streams;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_422_pixels;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_Cg_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_abgr;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bgra;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_bindable_uniform;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_color;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_equation_separate;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_func_separate;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_logic_op;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_minmax;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_blend_subtract;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_clip_volume_hint;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cmyka;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_color_subtable;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_compiled_vertex_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_convolution;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_coordinate_frame;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_copy_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_cull_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_debug_marker;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_depth_bounds_test;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_direct_state_access;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_buffers2;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_instanced;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_draw_range_elements;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fog_coord;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_fragment_lighting;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_blit;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_multisample_blit_scaled;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_framebuffer_sRGB;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_geometry_shader4;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_program_parameters;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_gpu_shader4;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_histogram;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_array_formats;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_func;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_material;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_index_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_light_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_misc_attribute;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multi_draw_arrays;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_depth_stencil;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_packed_pixels;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_paletted_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_pixel_transform_color_table;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_point_parameters;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_polygon_offset;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_provoking_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_rescale_normal;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_scene_marker;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_secondary_color;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_shader_objects;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_separate_specular_color;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shader_image_load_store;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shadow_funcs;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_shared_texture_palette;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_clear_tag;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_two_side;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_stencil_wrap;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_subtexture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture3D;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_dxt1;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_latc;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_rgtc;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_compression_s3tc;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_cube_map;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_edge_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_add;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_combine;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_env_dot3;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_filter_anisotropic;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_integer;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_lod_bias;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_mirror_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_perturb_normal;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_rectangle;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_sRGB_decode;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_shared_exponent;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_snorm;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_texture_swizzle;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_timer_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_transform_feedback;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_array_bgra;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_attrib_64bit;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_vertex_weighting;
+GLEW_VAR_EXPORT GLboolean __GLEW_EXT_x11_sync_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_frame_terminator;
+GLEW_VAR_EXPORT GLboolean __GLEW_GREMEDY_string_marker;
+GLEW_VAR_EXPORT GLboolean __GLEW_HP_convolution_border_modes;
+GLEW_VAR_EXPORT GLboolean __GLEW_HP_image_transform;
+GLEW_VAR_EXPORT GLboolean __GLEW_HP_occlusion_test;
+GLEW_VAR_EXPORT GLboolean __GLEW_HP_texture_lighting;
+GLEW_VAR_EXPORT GLboolean __GLEW_IBM_cull_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_IBM_multimode_draw_arrays;
+GLEW_VAR_EXPORT GLboolean __GLEW_IBM_rasterpos_clip;
+GLEW_VAR_EXPORT GLboolean __GLEW_IBM_static_data;
+GLEW_VAR_EXPORT GLboolean __GLEW_IBM_texture_mirrored_repeat;
+GLEW_VAR_EXPORT GLboolean __GLEW_IBM_vertex_array_lists;
+GLEW_VAR_EXPORT GLboolean __GLEW_INGR_color_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_INGR_interlace_read;
+GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_map_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_parallel_arrays;
+GLEW_VAR_EXPORT GLboolean __GLEW_INTEL_texture_scissor;
+GLEW_VAR_EXPORT GLboolean __GLEW_KHR_debug;
+GLEW_VAR_EXPORT GLboolean __GLEW_KHR_texture_compression_astc_ldr;
+GLEW_VAR_EXPORT GLboolean __GLEW_KTX_buffer_region;
+GLEW_VAR_EXPORT GLboolean __GLEW_MESAX_texture_stack;
+GLEW_VAR_EXPORT GLboolean __GLEW_MESA_pack_invert;
+GLEW_VAR_EXPORT GLboolean __GLEW_MESA_resize_buffers;
+GLEW_VAR_EXPORT GLboolean __GLEW_MESA_window_pos;
+GLEW_VAR_EXPORT GLboolean __GLEW_MESA_ycbcr_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_NVX_conditional_render;
+GLEW_VAR_EXPORT GLboolean __GLEW_NVX_gpu_memory_info;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_multi_draw_indirect;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_bindless_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_equation_advanced;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_equation_advanced_coherent;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_blend_square;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_compute_program5;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_conditional_render;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_depth_to_color;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_copy_image;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_deep_texture3D;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_buffer_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_depth_range_unclamped;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_draw_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_evaluators;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_explicit_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fence;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_float_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fog_distance;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program4;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_fragment_program_option;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_framebuffer_multisample_coverage;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_program4;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_geometry_shader4;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program4;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program5;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program5_mem_extended;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_program_fp64;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_gpu_shader5;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_half_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_light_max_exponent;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_coverage;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_multisample_filter_hint;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_occlusion_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_packed_depth_stencil;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_parameter_buffer_object2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_path_rendering;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_pixel_data_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_point_sprite;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_present_video;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_primitive_restart;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_register_combiners2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_counters;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_atomic_float;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_buffer_load;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_shader_storage_buffer_object;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_tessellation_program5;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_emboss;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texgen_reflection;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_barrier;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_compression_vtc;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_env_combine4;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_expand_normal;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_rectangle;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_texture_shader3;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_transform_feedback2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vdpau_interop;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_array_range2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_attrib_integer_64bit;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_buffer_unified_memory;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program1_1;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program2_option;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program3;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_vertex_program4;
+GLEW_VAR_EXPORT GLboolean __GLEW_NV_video_capture;
+GLEW_VAR_EXPORT GLboolean __GLEW_OES_byte_coordinates;
+GLEW_VAR_EXPORT GLboolean __GLEW_OES_compressed_paletted_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_OES_read_format;
+GLEW_VAR_EXPORT GLboolean __GLEW_OES_single_precision;
+GLEW_VAR_EXPORT GLboolean __GLEW_OML_interlace;
+GLEW_VAR_EXPORT GLboolean __GLEW_OML_resample;
+GLEW_VAR_EXPORT GLboolean __GLEW_OML_subsample;
+GLEW_VAR_EXPORT GLboolean __GLEW_PGI_misc_hints;
+GLEW_VAR_EXPORT GLboolean __GLEW_PGI_vertex_hints;
+GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_ES1_0_compatibility;
+GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_ES1_1_compatibility;
+GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_enable;
+GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_error_string;
+GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_extension_query;
+GLEW_VAR_EXPORT GLboolean __GLEW_REGAL_log;
+GLEW_VAR_EXPORT GLboolean __GLEW_REND_screen_coordinates;
+GLEW_VAR_EXPORT GLboolean __GLEW_S3_s3tc;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_color_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_detail_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_fog_function;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_generate_mipmap;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_multisample;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_pixel_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_point_line_texgen;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_sharpen_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture4D;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_border_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_edge_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_filter4;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_lod;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIS_texture_select;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_histogram;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_async_pixel;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_blend_alpha_minmax;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_clipmap;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_convolution_accuracy;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_depth_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_flush_raster;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_offset;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fog_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_fragment_specular_lighting;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_framezoom;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_interlace;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ir_instrument1;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_list_priority;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_pixel_texture_bits;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_reference_plane;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_resample;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_shadow_ambient;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_sprite;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_tag_sample_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_add_env;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_coordinate_clamp;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_lod_bias;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_multi_buffer;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_range;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_texture_scale_bias;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_vertex_preclip_hint;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGIX_ycrcb;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_matrix;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGI_color_table;
+GLEW_VAR_EXPORT GLboolean __GLEW_SGI_texture_color_table;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUNX_constant_data;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUN_convolution_border_modes;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUN_global_alpha;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUN_mesh_array;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUN_read_video_pixels;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUN_slice_accum;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUN_triangle_list;
+GLEW_VAR_EXPORT GLboolean __GLEW_SUN_vertex;
+GLEW_VAR_EXPORT GLboolean __GLEW_WIN_phong_shading;
+GLEW_VAR_EXPORT GLboolean __GLEW_WIN_specular_fog;
+GLEW_VAR_EXPORT GLboolean __GLEW_WIN_swap_hint;
+
+#ifdef GLEW_MX
+}; /* GLEWContextStruct */
+#endif /* GLEW_MX */
+
+/* ------------------------------------------------------------------------- */
+
+/* error codes */
+#define GLEW_OK 0
+#define GLEW_NO_ERROR 0
+#define GLEW_ERROR_NO_GL_VERSION 1 /* missing GL version */
+#define GLEW_ERROR_GL_VERSION_10_ONLY 2 /* Need at least OpenGL 1.1 */
+#define GLEW_ERROR_GLX_VERSION_11_ONLY 3 /* Need at least GLX 1.2 */
+
+/* string codes */
+#define GLEW_VERSION 1
+#define GLEW_VERSION_MAJOR 2
+#define GLEW_VERSION_MINOR 3
+#define GLEW_VERSION_MICRO 4
+
+/* API */
+#ifdef GLEW_MX
+
+typedef struct GLEWContextStruct GLEWContext;
+GLEWAPI GLenum GLEWAPIENTRY glewContextInit (GLEWContext *ctx);
+GLEWAPI GLboolean GLEWAPIENTRY glewContextIsSupported (const GLEWContext *ctx, const char *name);
+
+#define glewInit() glewContextInit(glewGetContext())
+#define glewIsSupported(x) glewContextIsSupported(glewGetContext(), x)
+#define glewIsExtensionSupported(x) glewIsSupported(x)
+
+#define GLEW_GET_VAR(x) (*(const GLboolean*)&(glewGetContext()->x))
+#ifdef _WIN32
+# define GLEW_GET_FUN(x) glewGetContext()->x
+#else
+# define GLEW_GET_FUN(x) x
+#endif
+
+#else /* GLEW_MX */
+
+GLEWAPI GLenum GLEWAPIENTRY glewInit (void);
+GLEWAPI GLboolean GLEWAPIENTRY glewIsSupported (const char *name);
+#define glewIsExtensionSupported(x) glewIsSupported(x)
+
+#define GLEW_GET_VAR(x) (*(const GLboolean*)&x)
+#define GLEW_GET_FUN(x) x
+
+#endif /* GLEW_MX */
+
+GLEWAPI GLboolean glewExperimental;
+GLEWAPI GLboolean GLEWAPIENTRY glewGetExtension (const char *name);
+GLEWAPI const GLubyte * GLEWAPIENTRY glewGetErrorString (GLenum error);
+GLEWAPI const GLubyte * GLEWAPIENTRY glewGetString (GLenum name);
+
+#ifdef GLEW_INIT_OPENGL11_FUNCTIONS
+GLEWAPI GLboolean GLEWAPIENTRY glewOpenGL11Init(void);
+#endif //GLEW_INIT_OPENGL11_FUNCTIONS
+
+#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+GLEWAPI GLboolean GLEWAPIENTRY glewXInit(void);
+#endif //GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef GLEW_APIENTRY_DEFINED
+#undef GLEW_APIENTRY_DEFINED
+#undef APIENTRY
+#undef GLAPIENTRY
+#define GLAPIENTRY
+#endif
+
+#ifdef GLEW_CALLBACK_DEFINED
+#undef GLEW_CALLBACK_DEFINED
+#undef CALLBACK
+#endif
+
+#ifdef GLEW_WINGDIAPI_DEFINED
+#undef GLEW_WINGDIAPI_DEFINED
+#undef WINGDIAPI
+#endif
+
+#undef GLAPI
+/* #undef GLEWAPI */
+
+#endif /* __glew_h__ */
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/glxew.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/glxew.h
new file mode 100644
index 0000000000..6115d611e1
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/glxew.h
@@ -0,0 +1,1750 @@
+/*
+** The OpenGL Extension Wrangler Library
+** Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org>
+** Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org>
+** Copyright (C) 2002, Lev Povalahev
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** * The name of the author may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+** THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.0
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * 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
+ * BRIAN PAUL 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.
+ */
+
+/*
+** Copyright (c) 2007 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are 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 Materials.
+**
+** THE MATERIALS ARE 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 AUTHORS OR COPYRIGHT HOLDERS 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
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#ifndef __glxew_h__
+#define __glxew_h__
+#define __GLXEW_H__
+
+#ifdef __glxext_h_
+#error glxext.h included before glxew.h
+#endif
+
+#if defined(GLX_H) || defined(__GLX_glx_h__) || defined(__glx_h__)
+#error glx.h included before glxew.h
+#endif
+
+#define __glxext_h_
+
+#define GLX_H
+#define __GLX_glx_h__
+#define __glx_h__
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xmd.h>
+#include "glew.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ---------------------------- GLX_VERSION_1_0 --------------------------- */
+
+#ifndef GLX_VERSION_1_0
+#define GLX_VERSION_1_0 1
+
+#define GLX_USE_GL 1
+#define GLX_BUFFER_SIZE 2
+#define GLX_LEVEL 3
+#define GLX_RGBA 4
+#define GLX_DOUBLEBUFFER 5
+#define GLX_STEREO 6
+#define GLX_AUX_BUFFERS 7
+#define GLX_RED_SIZE 8
+#define GLX_GREEN_SIZE 9
+#define GLX_BLUE_SIZE 10
+#define GLX_ALPHA_SIZE 11
+#define GLX_DEPTH_SIZE 12
+#define GLX_STENCIL_SIZE 13
+#define GLX_ACCUM_RED_SIZE 14
+#define GLX_ACCUM_GREEN_SIZE 15
+#define GLX_ACCUM_BLUE_SIZE 16
+#define GLX_ACCUM_ALPHA_SIZE 17
+#define GLX_BAD_SCREEN 1
+#define GLX_BAD_ATTRIBUTE 2
+#define GLX_NO_EXTENSION 3
+#define GLX_BAD_VISUAL 4
+#define GLX_BAD_CONTEXT 5
+#define GLX_BAD_VALUE 6
+#define GLX_BAD_ENUM 7
+
+typedef XID GLXDrawable;
+typedef XID GLXPixmap;
+#ifdef __sun
+typedef struct __glXContextRec *GLXContext;
+#else
+typedef struct __GLXcontextRec *GLXContext;
+#endif
+
+typedef unsigned int GLXVideoDeviceNV;
+
+#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+
+typedef Bool (* PFNGLXQUERYEXTENSION) (Display *dpy, int *errorBase, int *eventBase);
+#define glXQueryExtension GLXEW_GET_FUN(__glewXQueryExtension)
+
+typedef Bool (* PFNGLXQUERYVERSION) (Display *dpy, int *major, int *minor);
+#define glXQueryVersion GLXEW_GET_FUN(__glewXQueryVersion)
+
+typedef int (* PFNGLXGETCONFIG) (Display *dpy, XVisualInfo *vis, int attrib, int *value);
+#define glXGetConfig GLXEW_GET_FUN(__glewXGetConfig)
+
+typedef XVisualInfo* (* PFNGLXCHOOSEVISUAL) (Display *dpy, int screen, int *attribList);
+#define glXChooseVisual GLXEW_GET_FUN(__glewXChooseVisual)
+
+//extern GLXPixmap glXCreateGLXPixmap (Display *dpy, XVisualInfo *vis, Pixmap pixmap);
+//extern void glXDestroyGLXPixmap (Display *dpy, GLXPixmap pix);
+typedef GLXContext (* PFNGLXCREATECONTEXT) (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct);
+#define glXCreateContext GLXEW_GET_FUN(__glewXCreateContext)
+
+
+typedef void (*PFNGLXDESTROYCONTEXT) (Display *dpy, GLXContext ctx);
+#define glXDestroyContext GLXEW_GET_FUN(__glewXDestroyContext)
+
+typedef Bool (* PFNGLXISDIRECT) (Display *dpy, GLXContext ctx);
+#define glXIsDirect GLXEW_GET_FUN(__glewXIsDirect)
+
+
+//extern void glXCopyContext (Display *dpy, GLXContext src, GLXContext dst, GLulong mask);
+typedef Bool (*PFNGLXMAKECURRENT) (Display *dpy, GLXDrawable drawable, GLXContext ctx);
+#define glXMakeCurrent GLXEW_GET_FUN(__glewXMakeCurrent)
+
+//extern GLXContext glXGetCurrentContext (void);
+//extern GLXDrawable glXGetCurrentDrawable (void);
+//extern void glXWaitGL (void);
+//extern void glXWaitX (void);
+typedef void (*PFNGLXSWAPBUFFERS) (Display *dpy, GLXDrawable drawable);
+#define glXSwapBuffers GLXEW_GET_FUN(__glewXSwapBuffers)
+
+//extern void glXUseXFont (Font font, int first, int count, int listBase);
+
+
+#else//GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+extern Bool glXQueryExtension (Display *dpy, int *errorBase, int *eventBase);
+extern Bool glXQueryVersion (Display *dpy, int *major, int *minor);
+extern int glXGetConfig (Display *dpy, XVisualInfo *vis, int attrib, int *value);
+extern XVisualInfo* glXChooseVisual (Display *dpy, int screen, int *attribList);
+extern GLXPixmap glXCreateGLXPixmap (Display *dpy, XVisualInfo *vis, Pixmap pixmap);
+extern void glXDestroyGLXPixmap (Display *dpy, GLXPixmap pix);
+extern GLXContext glXCreateContext (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct);
+extern void glXDestroyContext (Display *dpy, GLXContext ctx);
+extern Bool glXIsDirect (Display *dpy, GLXContext ctx);
+extern void glXCopyContext (Display *dpy, GLXContext src, GLXContext dst, GLulong mask);
+extern Bool glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx);
+extern GLXContext glXGetCurrentContext (void);
+extern GLXDrawable glXGetCurrentDrawable (void);
+extern void glXWaitGL (void);
+extern void glXWaitX (void);
+extern void glXSwapBuffers (Display *dpy, GLXDrawable drawable);
+extern void glXUseXFont (Font font, int first, int count, int listBase);
+#endif //GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+
+#define GLXEW_VERSION_1_0 GLXEW_GET_VAR(__GLXEW_VERSION_1_0)
+
+#endif /* GLX_VERSION_1_0 */
+
+/* ---------------------------- GLX_VERSION_1_1 --------------------------- */
+
+#ifndef GLX_VERSION_1_1
+#define GLX_VERSION_1_1
+
+#define GLX_VENDOR 0x1
+#define GLX_VERSION 0x2
+#define GLX_EXTENSIONS 0x3
+
+#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+
+typedef const char* (*PFNGLXQUERYEXTENSIONSSTRING) (Display *dpy, int screen);
+#define glXQueryExtensionsString GLXEW_GET_FUN(__glewXQueryExtensionsString)
+
+typedef const char* (*PFNGLXGETCLIENTSTRING) (Display *dpy, int name);
+#define glXGetClientString GLXEW_GET_FUN(__glewXGetClientString)
+
+typedef const char* (*PFNGLXQUERYSERVERSTRING) (Display *dpy, int screen, int name);
+#define glXQueryServerString GLXEW_GET_FUN(__glewXQueryServerString)
+
+#else//GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+extern const char* glXQueryExtensionsString (Display *dpy, int screen);
+extern const char* glXGetClientString (Display *dpy, int name);
+extern const char* glXQueryServerString (Display *dpy, int screen, int name);
+#endif//GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+
+#define GLXEW_VERSION_1_1 GLXEW_GET_VAR(__GLXEW_VERSION_1_1)
+
+#endif /* GLX_VERSION_1_1 */
+
+/* ---------------------------- GLX_VERSION_1_2 ---------------------------- */
+
+#ifndef GLX_VERSION_1_2
+#define GLX_VERSION_1_2 1
+
+typedef Display* ( * PFNGLXGETCURRENTDISPLAYPROC) (void);
+
+#define glXGetCurrentDisplay GLXEW_GET_FUN(__glewXGetCurrentDisplay)
+
+#define GLXEW_VERSION_1_2 GLXEW_GET_VAR(__GLXEW_VERSION_1_2)
+
+#endif /* GLX_VERSION_1_2 */
+
+/* ---------------------------- GLX_VERSION_1_3 ---------------------------- */
+
+#ifndef GLX_VERSION_1_3
+#define GLX_VERSION_1_3 1
+
+#define GLX_RGBA_BIT 0x00000001
+#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
+#define GLX_WINDOW_BIT 0x00000001
+#define GLX_COLOR_INDEX_BIT 0x00000002
+#define GLX_PIXMAP_BIT 0x00000002
+#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
+#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004
+#define GLX_PBUFFER_BIT 0x00000004
+#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
+#define GLX_AUX_BUFFERS_BIT 0x00000010
+#define GLX_CONFIG_CAVEAT 0x20
+#define GLX_DEPTH_BUFFER_BIT 0x00000020
+#define GLX_X_VISUAL_TYPE 0x22
+#define GLX_TRANSPARENT_TYPE 0x23
+#define GLX_TRANSPARENT_INDEX_VALUE 0x24
+#define GLX_TRANSPARENT_RED_VALUE 0x25
+#define GLX_TRANSPARENT_GREEN_VALUE 0x26
+#define GLX_TRANSPARENT_BLUE_VALUE 0x27
+#define GLX_TRANSPARENT_ALPHA_VALUE 0x28
+#define GLX_STENCIL_BUFFER_BIT 0x00000040
+#define GLX_ACCUM_BUFFER_BIT 0x00000080
+#define GLX_NONE 0x8000
+#define GLX_SLOW_CONFIG 0x8001
+#define GLX_TRUE_COLOR 0x8002
+#define GLX_DIRECT_COLOR 0x8003
+#define GLX_PSEUDO_COLOR 0x8004
+#define GLX_STATIC_COLOR 0x8005
+#define GLX_GRAY_SCALE 0x8006
+#define GLX_STATIC_GRAY 0x8007
+#define GLX_TRANSPARENT_RGB 0x8008
+#define GLX_TRANSPARENT_INDEX 0x8009
+#define GLX_VISUAL_ID 0x800B
+#define GLX_SCREEN 0x800C
+#define GLX_NON_CONFORMANT_CONFIG 0x800D
+#define GLX_DRAWABLE_TYPE 0x8010
+#define GLX_RENDER_TYPE 0x8011
+#define GLX_X_RENDERABLE 0x8012
+#define GLX_FBCONFIG_ID 0x8013
+#define GLX_RGBA_TYPE 0x8014
+#define GLX_COLOR_INDEX_TYPE 0x8015
+#define GLX_MAX_PBUFFER_WIDTH 0x8016
+#define GLX_MAX_PBUFFER_HEIGHT 0x8017
+#define GLX_MAX_PBUFFER_PIXELS 0x8018
+#define GLX_PRESERVED_CONTENTS 0x801B
+#define GLX_LARGEST_PBUFFER 0x801C
+#define GLX_WIDTH 0x801D
+#define GLX_HEIGHT 0x801E
+#define GLX_EVENT_MASK 0x801F
+#define GLX_DAMAGED 0x8020
+#define GLX_SAVED 0x8021
+#define GLX_WINDOW 0x8022
+#define GLX_PBUFFER 0x8023
+#define GLX_PBUFFER_HEIGHT 0x8040
+#define GLX_PBUFFER_WIDTH 0x8041
+#define GLX_PBUFFER_CLOBBER_MASK 0x08000000
+#define GLX_DONT_CARE 0xFFFFFFFF
+
+typedef XID GLXFBConfigID;
+typedef XID GLXPbuffer;
+typedef XID GLXWindow;
+typedef struct __GLXFBConfigRec *GLXFBConfig;
+
+typedef struct {
+ int event_type;
+ int draw_type;
+ unsigned long serial;
+ Bool send_event;
+ Display *display;
+ GLXDrawable drawable;
+ unsigned int buffer_mask;
+ unsigned int aux_buffer;
+ int x, y;
+ int width, height;
+ int count;
+} GLXPbufferClobberEvent;
+typedef union __GLXEvent {
+ GLXPbufferClobberEvent glxpbufferclobber;
+ long pad[24];
+} GLXEvent;
+
+typedef GLXFBConfig* ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
+typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list);
+typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
+typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list);
+typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf);
+typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap);
+typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win);
+typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void);
+typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value);
+typedef GLXFBConfig* ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements);
+typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask);
+typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config);
+typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value);
+typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
+typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask);
+
+#define glXChooseFBConfig GLXEW_GET_FUN(__glewXChooseFBConfig)
+#define glXCreateNewContext GLXEW_GET_FUN(__glewXCreateNewContext)
+#define glXCreatePbuffer GLXEW_GET_FUN(__glewXCreatePbuffer)
+#define glXCreatePixmap GLXEW_GET_FUN(__glewXCreatePixmap)
+#define glXCreateWindow GLXEW_GET_FUN(__glewXCreateWindow)
+#define glXDestroyPbuffer GLXEW_GET_FUN(__glewXDestroyPbuffer)
+#define glXDestroyPixmap GLXEW_GET_FUN(__glewXDestroyPixmap)
+#define glXDestroyWindow GLXEW_GET_FUN(__glewXDestroyWindow)
+#define glXGetCurrentReadDrawable GLXEW_GET_FUN(__glewXGetCurrentReadDrawable)
+#define glXGetFBConfigAttrib GLXEW_GET_FUN(__glewXGetFBConfigAttrib)
+#define glXGetFBConfigs GLXEW_GET_FUN(__glewXGetFBConfigs)
+#define glXGetSelectedEvent GLXEW_GET_FUN(__glewXGetSelectedEvent)
+#define glXGetVisualFromFBConfig GLXEW_GET_FUN(__glewXGetVisualFromFBConfig)
+#define glXMakeContextCurrent GLXEW_GET_FUN(__glewXMakeContextCurrent)
+#define glXQueryContext GLXEW_GET_FUN(__glewXQueryContext)
+#define glXQueryDrawable GLXEW_GET_FUN(__glewXQueryDrawable)
+#define glXSelectEvent GLXEW_GET_FUN(__glewXSelectEvent)
+
+#define GLXEW_VERSION_1_3 GLXEW_GET_VAR(__GLXEW_VERSION_1_3)
+
+#endif /* GLX_VERSION_1_3 */
+
+/* ---------------------------- GLX_VERSION_1_4 ---------------------------- */
+
+#ifndef GLX_VERSION_1_4
+#define GLX_VERSION_1_4 1
+
+#define GLX_SAMPLE_BUFFERS 100000
+#define GLX_SAMPLES 100001
+
+extern void ( * glXGetProcAddress (const GLubyte *procName)) (void);
+
+#define GLXEW_VERSION_1_4 GLXEW_GET_VAR(__GLXEW_VERSION_1_4)
+
+#endif /* GLX_VERSION_1_4 */
+
+/* -------------------------- GLX_3DFX_multisample ------------------------- */
+
+#ifndef GLX_3DFX_multisample
+#define GLX_3DFX_multisample 1
+
+#define GLX_SAMPLE_BUFFERS_3DFX 0x8050
+#define GLX_SAMPLES_3DFX 0x8051
+
+#define GLXEW_3DFX_multisample GLXEW_GET_VAR(__GLXEW_3DFX_multisample)
+
+#endif /* GLX_3DFX_multisample */
+
+/* ------------------------ GLX_AMD_gpu_association ------------------------ */
+
+#ifndef GLX_AMD_gpu_association
+#define GLX_AMD_gpu_association 1
+
+#define GLX_GPU_VENDOR_AMD 0x1F00
+#define GLX_GPU_RENDERER_STRING_AMD 0x1F01
+#define GLX_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
+#define GLX_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
+#define GLX_GPU_RAM_AMD 0x21A3
+#define GLX_GPU_CLOCK_AMD 0x21A4
+#define GLX_GPU_NUM_PIPES_AMD 0x21A5
+#define GLX_GPU_NUM_SIMD_AMD 0x21A6
+#define GLX_GPU_NUM_RB_AMD 0x21A7
+#define GLX_GPU_NUM_SPI_AMD 0x21A8
+
+typedef void ( * PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC) (GLXContext dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef GLXContext ( * PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC) (unsigned int id, GLXContext share_list);
+typedef GLXContext ( * PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (unsigned int id, GLXContext share_context, const int* attribList);
+typedef Bool ( * PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC) (GLXContext ctx);
+typedef unsigned int ( * PFNGLXGETCONTEXTGPUIDAMDPROC) (GLXContext ctx);
+typedef GLXContext ( * PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
+typedef unsigned int ( * PFNGLXGETGPUIDSAMDPROC) (unsigned int maxCount, unsigned int* ids);
+typedef int ( * PFNGLXGETGPUINFOAMDPROC) (unsigned int id, int property, GLenum dataType, unsigned int size, void* data);
+typedef Bool ( * PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (GLXContext ctx);
+
+#define glXBlitContextFramebufferAMD GLXEW_GET_FUN(__glewXBlitContextFramebufferAMD)
+#define glXCreateAssociatedContextAMD GLXEW_GET_FUN(__glewXCreateAssociatedContextAMD)
+#define glXCreateAssociatedContextAttribsAMD GLXEW_GET_FUN(__glewXCreateAssociatedContextAttribsAMD)
+#define glXDeleteAssociatedContextAMD GLXEW_GET_FUN(__glewXDeleteAssociatedContextAMD)
+#define glXGetContextGPUIDAMD GLXEW_GET_FUN(__glewXGetContextGPUIDAMD)
+#define glXGetCurrentAssociatedContextAMD GLXEW_GET_FUN(__glewXGetCurrentAssociatedContextAMD)
+#define glXGetGPUIDsAMD GLXEW_GET_FUN(__glewXGetGPUIDsAMD)
+#define glXGetGPUInfoAMD GLXEW_GET_FUN(__glewXGetGPUInfoAMD)
+#define glXMakeAssociatedContextCurrentAMD GLXEW_GET_FUN(__glewXMakeAssociatedContextCurrentAMD)
+
+#define GLXEW_AMD_gpu_association GLXEW_GET_VAR(__GLXEW_AMD_gpu_association)
+
+#endif /* GLX_AMD_gpu_association */
+
+/* ------------------------- GLX_ARB_create_context ------------------------ */
+
+#ifndef GLX_ARB_create_context
+#define GLX_ARB_create_context 1
+
+#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001
+#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
+#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define GLX_CONTEXT_FLAGS_ARB 0x2094
+
+typedef GLXContext ( * PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
+
+#define glXCreateContextAttribsARB GLXEW_GET_FUN(__glewXCreateContextAttribsARB)
+
+#define GLXEW_ARB_create_context GLXEW_GET_VAR(__GLXEW_ARB_create_context)
+
+#endif /* GLX_ARB_create_context */
+
+/* --------------------- GLX_ARB_create_context_profile -------------------- */
+
+#ifndef GLX_ARB_create_context_profile
+#define GLX_ARB_create_context_profile 1
+
+#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
+
+#define GLXEW_ARB_create_context_profile GLXEW_GET_VAR(__GLXEW_ARB_create_context_profile)
+
+#endif /* GLX_ARB_create_context_profile */
+
+/* ------------------- GLX_ARB_create_context_robustness ------------------- */
+
+#ifndef GLX_ARB_create_context_robustness
+#define GLX_ARB_create_context_robustness 1
+
+#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261
+
+#define GLXEW_ARB_create_context_robustness GLXEW_GET_VAR(__GLXEW_ARB_create_context_robustness)
+
+#endif /* GLX_ARB_create_context_robustness */
+
+/* ------------------------- GLX_ARB_fbconfig_float ------------------------ */
+
+#ifndef GLX_ARB_fbconfig_float
+#define GLX_ARB_fbconfig_float 1
+
+#define GLX_RGBA_FLOAT_BIT 0x00000004
+#define GLX_RGBA_FLOAT_TYPE 0x20B9
+
+#define GLXEW_ARB_fbconfig_float GLXEW_GET_VAR(__GLXEW_ARB_fbconfig_float)
+
+#endif /* GLX_ARB_fbconfig_float */
+
+/* ------------------------ GLX_ARB_framebuffer_sRGB ----------------------- */
+
+#ifndef GLX_ARB_framebuffer_sRGB
+#define GLX_ARB_framebuffer_sRGB 1
+
+#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
+
+#define GLXEW_ARB_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_ARB_framebuffer_sRGB)
+
+#endif /* GLX_ARB_framebuffer_sRGB */
+
+/* ------------------------ GLX_ARB_get_proc_address ----------------------- */
+
+#ifndef GLX_ARB_get_proc_address
+#define GLX_ARB_get_proc_address 1
+
+#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+typedef void* ( * PFNGLXGETPROCADDRESSARBPROC) (const GLubyte *procName);
+#define glXGetProcAddressARB GLXEW_GET_FUN(__glewXGetProcAddressARB)
+
+#else//GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+extern void ( * glXGetProcAddressARB (const GLubyte *procName)) (void);
+#endif //GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+
+#define GLXEW_ARB_get_proc_address GLXEW_GET_VAR(__GLXEW_ARB_get_proc_address)
+
+#endif /* GLX_ARB_get_proc_address */
+
+/* -------------------------- GLX_ARB_multisample -------------------------- */
+
+#ifndef GLX_ARB_multisample
+#define GLX_ARB_multisample 1
+
+#define GLX_SAMPLE_BUFFERS_ARB 100000
+#define GLX_SAMPLES_ARB 100001
+
+#define GLXEW_ARB_multisample GLXEW_GET_VAR(__GLXEW_ARB_multisample)
+
+#endif /* GLX_ARB_multisample */
+
+/* ---------------- GLX_ARB_robustness_application_isolation --------------- */
+
+#ifndef GLX_ARB_robustness_application_isolation
+#define GLX_ARB_robustness_application_isolation 1
+
+#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
+
+#define GLXEW_ARB_robustness_application_isolation GLXEW_GET_VAR(__GLXEW_ARB_robustness_application_isolation)
+
+#endif /* GLX_ARB_robustness_application_isolation */
+
+/* ---------------- GLX_ARB_robustness_share_group_isolation --------------- */
+
+#ifndef GLX_ARB_robustness_share_group_isolation
+#define GLX_ARB_robustness_share_group_isolation 1
+
+#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
+
+#define GLXEW_ARB_robustness_share_group_isolation GLXEW_GET_VAR(__GLXEW_ARB_robustness_share_group_isolation)
+
+#endif /* GLX_ARB_robustness_share_group_isolation */
+
+/* ---------------------- GLX_ARB_vertex_buffer_object --------------------- */
+
+#ifndef GLX_ARB_vertex_buffer_object
+#define GLX_ARB_vertex_buffer_object 1
+
+#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095
+
+#define GLXEW_ARB_vertex_buffer_object GLXEW_GET_VAR(__GLXEW_ARB_vertex_buffer_object)
+
+#endif /* GLX_ARB_vertex_buffer_object */
+
+/* ----------------------- GLX_ATI_pixel_format_float ---------------------- */
+
+#ifndef GLX_ATI_pixel_format_float
+#define GLX_ATI_pixel_format_float 1
+
+#define GLX_RGBA_FLOAT_ATI_BIT 0x00000100
+
+#define GLXEW_ATI_pixel_format_float GLXEW_GET_VAR(__GLXEW_ATI_pixel_format_float)
+
+#endif /* GLX_ATI_pixel_format_float */
+
+/* ------------------------- GLX_ATI_render_texture ------------------------ */
+
+#ifndef GLX_ATI_render_texture
+#define GLX_ATI_render_texture 1
+
+#define GLX_BIND_TO_TEXTURE_RGB_ATI 0x9800
+#define GLX_BIND_TO_TEXTURE_RGBA_ATI 0x9801
+#define GLX_TEXTURE_FORMAT_ATI 0x9802
+#define GLX_TEXTURE_TARGET_ATI 0x9803
+#define GLX_MIPMAP_TEXTURE_ATI 0x9804
+#define GLX_TEXTURE_RGB_ATI 0x9805
+#define GLX_TEXTURE_RGBA_ATI 0x9806
+#define GLX_NO_TEXTURE_ATI 0x9807
+#define GLX_TEXTURE_CUBE_MAP_ATI 0x9808
+#define GLX_TEXTURE_1D_ATI 0x9809
+#define GLX_TEXTURE_2D_ATI 0x980A
+#define GLX_MIPMAP_LEVEL_ATI 0x980B
+#define GLX_CUBE_MAP_FACE_ATI 0x980C
+#define GLX_TEXTURE_CUBE_MAP_POSITIVE_X_ATI 0x980D
+#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_X_ATI 0x980E
+#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Y_ATI 0x980F
+#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Y_ATI 0x9810
+#define GLX_TEXTURE_CUBE_MAP_POSITIVE_Z_ATI 0x9811
+#define GLX_TEXTURE_CUBE_MAP_NEGATIVE_Z_ATI 0x9812
+#define GLX_FRONT_LEFT_ATI 0x9813
+#define GLX_FRONT_RIGHT_ATI 0x9814
+#define GLX_BACK_LEFT_ATI 0x9815
+#define GLX_BACK_RIGHT_ATI 0x9816
+#define GLX_AUX0_ATI 0x9817
+#define GLX_AUX1_ATI 0x9818
+#define GLX_AUX2_ATI 0x9819
+#define GLX_AUX3_ATI 0x981A
+#define GLX_AUX4_ATI 0x981B
+#define GLX_AUX5_ATI 0x981C
+#define GLX_AUX6_ATI 0x981D
+#define GLX_AUX7_ATI 0x981E
+#define GLX_AUX8_ATI 0x981F
+#define GLX_AUX9_ATI 0x9820
+#define GLX_BIND_TO_TEXTURE_LUMINANCE_ATI 0x9821
+#define GLX_BIND_TO_TEXTURE_INTENSITY_ATI 0x9822
+
+typedef void ( * PFNGLXBINDTEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer);
+typedef void ( * PFNGLXDRAWABLEATTRIBATIPROC) (Display *dpy, GLXDrawable draw, const int *attrib_list);
+typedef void ( * PFNGLXRELEASETEXIMAGEATIPROC) (Display *dpy, GLXPbuffer pbuf, int buffer);
+
+#define glXBindTexImageATI GLXEW_GET_FUN(__glewXBindTexImageATI)
+#define glXDrawableAttribATI GLXEW_GET_FUN(__glewXDrawableAttribATI)
+#define glXReleaseTexImageATI GLXEW_GET_FUN(__glewXReleaseTexImageATI)
+
+#define GLXEW_ATI_render_texture GLXEW_GET_VAR(__GLXEW_ATI_render_texture)
+
+#endif /* GLX_ATI_render_texture */
+
+/* --------------------------- GLX_EXT_buffer_age -------------------------- */
+
+#ifndef GLX_EXT_buffer_age
+#define GLX_EXT_buffer_age 1
+
+#define GLX_BACK_BUFFER_AGE_EXT 0x20F4
+
+#define GLXEW_EXT_buffer_age GLXEW_GET_VAR(__GLXEW_EXT_buffer_age)
+
+#endif /* GLX_EXT_buffer_age */
+
+/* ------------------- GLX_EXT_create_context_es2_profile ------------------ */
+
+#ifndef GLX_EXT_create_context_es2_profile
+#define GLX_EXT_create_context_es2_profile 1
+
+#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+
+#define GLXEW_EXT_create_context_es2_profile GLXEW_GET_VAR(__GLXEW_EXT_create_context_es2_profile)
+
+#endif /* GLX_EXT_create_context_es2_profile */
+
+/* ------------------- GLX_EXT_create_context_es_profile ------------------- */
+
+#ifndef GLX_EXT_create_context_es_profile
+#define GLX_EXT_create_context_es_profile 1
+
+#define GLX_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
+
+#define GLXEW_EXT_create_context_es_profile GLXEW_GET_VAR(__GLXEW_EXT_create_context_es_profile)
+
+#endif /* GLX_EXT_create_context_es_profile */
+
+/* --------------------- GLX_EXT_fbconfig_packed_float --------------------- */
+
+#ifndef GLX_EXT_fbconfig_packed_float
+#define GLX_EXT_fbconfig_packed_float 1
+
+#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008
+#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1
+
+#define GLXEW_EXT_fbconfig_packed_float GLXEW_GET_VAR(__GLXEW_EXT_fbconfig_packed_float)
+
+#endif /* GLX_EXT_fbconfig_packed_float */
+
+/* ------------------------ GLX_EXT_framebuffer_sRGB ----------------------- */
+
+#ifndef GLX_EXT_framebuffer_sRGB
+#define GLX_EXT_framebuffer_sRGB 1
+
+#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2
+
+#define GLXEW_EXT_framebuffer_sRGB GLXEW_GET_VAR(__GLXEW_EXT_framebuffer_sRGB)
+
+#endif /* GLX_EXT_framebuffer_sRGB */
+
+/* ------------------------- GLX_EXT_import_context ------------------------ */
+
+#ifndef GLX_EXT_import_context
+#define GLX_EXT_import_context 1
+
+#define GLX_SHARE_CONTEXT_EXT 0x800A
+#define GLX_VISUAL_ID_EXT 0x800B
+#define GLX_SCREEN_EXT 0x800C
+
+typedef XID GLXContextID;
+
+typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display* dpy, GLXContext context);
+typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context);
+typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display* dpy, GLXContextID contextID);
+typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display* dpy, GLXContext context, int attribute,int *value);
+
+#define glXFreeContextEXT GLXEW_GET_FUN(__glewXFreeContextEXT)
+#define glXGetContextIDEXT GLXEW_GET_FUN(__glewXGetContextIDEXT)
+#define glXImportContextEXT GLXEW_GET_FUN(__glewXImportContextEXT)
+#define glXQueryContextInfoEXT GLXEW_GET_FUN(__glewXQueryContextInfoEXT)
+
+#define GLXEW_EXT_import_context GLXEW_GET_VAR(__GLXEW_EXT_import_context)
+
+#endif /* GLX_EXT_import_context */
+
+/* -------------------------- GLX_EXT_scene_marker ------------------------- */
+
+#ifndef GLX_EXT_scene_marker
+#define GLX_EXT_scene_marker 1
+
+#define GLXEW_EXT_scene_marker GLXEW_GET_VAR(__GLXEW_EXT_scene_marker)
+
+#endif /* GLX_EXT_scene_marker */
+
+/* -------------------------- GLX_EXT_swap_control ------------------------- */
+
+#ifndef GLX_EXT_swap_control
+#define GLX_EXT_swap_control 1
+
+#define GLX_SWAP_INTERVAL_EXT 0x20F1
+#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
+
+typedef void ( * PFNGLXSWAPINTERVALEXTPROC) (Display* dpy, GLXDrawable drawable, int interval);
+
+#define glXSwapIntervalEXT GLXEW_GET_FUN(__glewXSwapIntervalEXT)
+
+#define GLXEW_EXT_swap_control GLXEW_GET_VAR(__GLXEW_EXT_swap_control)
+
+#endif /* GLX_EXT_swap_control */
+
+/* ----------------------- GLX_EXT_swap_control_tear ----------------------- */
+
+#ifndef GLX_EXT_swap_control_tear
+#define GLX_EXT_swap_control_tear 1
+
+#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3
+
+#define GLXEW_EXT_swap_control_tear GLXEW_GET_VAR(__GLXEW_EXT_swap_control_tear)
+
+#endif /* GLX_EXT_swap_control_tear */
+
+/* ---------------------- GLX_EXT_texture_from_pixmap ---------------------- */
+
+#ifndef GLX_EXT_texture_from_pixmap
+#define GLX_EXT_texture_from_pixmap 1
+
+#define GLX_TEXTURE_1D_BIT_EXT 0x00000001
+#define GLX_TEXTURE_2D_BIT_EXT 0x00000002
+#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004
+#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
+#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1
+#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2
+#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3
+#define GLX_Y_INVERTED_EXT 0x20D4
+#define GLX_TEXTURE_FORMAT_EXT 0x20D5
+#define GLX_TEXTURE_TARGET_EXT 0x20D6
+#define GLX_MIPMAP_TEXTURE_EXT 0x20D7
+#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8
+#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9
+#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA
+#define GLX_TEXTURE_1D_EXT 0x20DB
+#define GLX_TEXTURE_2D_EXT 0x20DC
+#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD
+#define GLX_FRONT_LEFT_EXT 0x20DE
+#define GLX_FRONT_RIGHT_EXT 0x20DF
+#define GLX_BACK_LEFT_EXT 0x20E0
+#define GLX_BACK_RIGHT_EXT 0x20E1
+#define GLX_AUX0_EXT 0x20E2
+#define GLX_AUX1_EXT 0x20E3
+#define GLX_AUX2_EXT 0x20E4
+#define GLX_AUX3_EXT 0x20E5
+#define GLX_AUX4_EXT 0x20E6
+#define GLX_AUX5_EXT 0x20E7
+#define GLX_AUX6_EXT 0x20E8
+#define GLX_AUX7_EXT 0x20E9
+#define GLX_AUX8_EXT 0x20EA
+#define GLX_AUX9_EXT 0x20EB
+
+typedef void ( * PFNGLXBINDTEXIMAGEEXTPROC) (Display* display, GLXDrawable drawable, int buffer, const int *attrib_list);
+typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display* display, GLXDrawable drawable, int buffer);
+
+#define glXBindTexImageEXT GLXEW_GET_FUN(__glewXBindTexImageEXT)
+#define glXReleaseTexImageEXT GLXEW_GET_FUN(__glewXReleaseTexImageEXT)
+
+#define GLXEW_EXT_texture_from_pixmap GLXEW_GET_VAR(__GLXEW_EXT_texture_from_pixmap)
+
+#endif /* GLX_EXT_texture_from_pixmap */
+
+/* -------------------------- GLX_EXT_visual_info -------------------------- */
+
+#ifndef GLX_EXT_visual_info
+#define GLX_EXT_visual_info 1
+
+#define GLX_X_VISUAL_TYPE_EXT 0x22
+#define GLX_TRANSPARENT_TYPE_EXT 0x23
+#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24
+#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25
+#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26
+#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27
+#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28
+#define GLX_NONE_EXT 0x8000
+#define GLX_TRUE_COLOR_EXT 0x8002
+#define GLX_DIRECT_COLOR_EXT 0x8003
+#define GLX_PSEUDO_COLOR_EXT 0x8004
+#define GLX_STATIC_COLOR_EXT 0x8005
+#define GLX_GRAY_SCALE_EXT 0x8006
+#define GLX_STATIC_GRAY_EXT 0x8007
+#define GLX_TRANSPARENT_RGB_EXT 0x8008
+#define GLX_TRANSPARENT_INDEX_EXT 0x8009
+
+#define GLXEW_EXT_visual_info GLXEW_GET_VAR(__GLXEW_EXT_visual_info)
+
+#endif /* GLX_EXT_visual_info */
+
+/* ------------------------- GLX_EXT_visual_rating ------------------------- */
+
+#ifndef GLX_EXT_visual_rating
+#define GLX_EXT_visual_rating 1
+
+#define GLX_VISUAL_CAVEAT_EXT 0x20
+#define GLX_SLOW_VISUAL_EXT 0x8001
+#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
+
+#define GLXEW_EXT_visual_rating GLXEW_GET_VAR(__GLXEW_EXT_visual_rating)
+
+#endif /* GLX_EXT_visual_rating */
+
+/* -------------------------- GLX_INTEL_swap_event ------------------------- */
+
+#ifndef GLX_INTEL_swap_event
+#define GLX_INTEL_swap_event 1
+
+#define GLX_EXCHANGE_COMPLETE_INTEL 0x8180
+#define GLX_COPY_COMPLETE_INTEL 0x8181
+#define GLX_FLIP_COMPLETE_INTEL 0x8182
+#define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000
+
+#define GLXEW_INTEL_swap_event GLXEW_GET_VAR(__GLXEW_INTEL_swap_event)
+
+#endif /* GLX_INTEL_swap_event */
+
+/* -------------------------- GLX_MESA_agp_offset -------------------------- */
+
+#ifndef GLX_MESA_agp_offset
+#define GLX_MESA_agp_offset 1
+
+typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void* pointer);
+
+#define glXGetAGPOffsetMESA GLXEW_GET_FUN(__glewXGetAGPOffsetMESA)
+
+#define GLXEW_MESA_agp_offset GLXEW_GET_VAR(__GLXEW_MESA_agp_offset)
+
+#endif /* GLX_MESA_agp_offset */
+
+/* ------------------------ GLX_MESA_copy_sub_buffer ----------------------- */
+
+#ifndef GLX_MESA_copy_sub_buffer
+#define GLX_MESA_copy_sub_buffer 1
+
+typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display* dpy, GLXDrawable drawable, int x, int y, int width, int height);
+
+#define glXCopySubBufferMESA GLXEW_GET_FUN(__glewXCopySubBufferMESA)
+
+#define GLXEW_MESA_copy_sub_buffer GLXEW_GET_VAR(__GLXEW_MESA_copy_sub_buffer)
+
+#endif /* GLX_MESA_copy_sub_buffer */
+
+/* ------------------------ GLX_MESA_pixmap_colormap ----------------------- */
+
+#ifndef GLX_MESA_pixmap_colormap
+#define GLX_MESA_pixmap_colormap 1
+
+typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display* dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap);
+
+#define glXCreateGLXPixmapMESA GLXEW_GET_FUN(__glewXCreateGLXPixmapMESA)
+
+#define GLXEW_MESA_pixmap_colormap GLXEW_GET_VAR(__GLXEW_MESA_pixmap_colormap)
+
+#endif /* GLX_MESA_pixmap_colormap */
+
+/* ------------------------ GLX_MESA_release_buffers ----------------------- */
+
+#ifndef GLX_MESA_release_buffers
+#define GLX_MESA_release_buffers 1
+
+typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display* dpy, GLXDrawable d);
+
+#define glXReleaseBuffersMESA GLXEW_GET_FUN(__glewXReleaseBuffersMESA)
+
+#define GLXEW_MESA_release_buffers GLXEW_GET_VAR(__GLXEW_MESA_release_buffers)
+
+#endif /* GLX_MESA_release_buffers */
+
+/* ------------------------- GLX_MESA_set_3dfx_mode ------------------------ */
+
+#ifndef GLX_MESA_set_3dfx_mode
+#define GLX_MESA_set_3dfx_mode 1
+
+#define GLX_3DFX_WINDOW_MODE_MESA 0x1
+#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2
+
+typedef GLboolean ( * PFNGLXSET3DFXMODEMESAPROC) (GLint mode);
+
+#define glXSet3DfxModeMESA GLXEW_GET_FUN(__glewXSet3DfxModeMESA)
+
+#define GLXEW_MESA_set_3dfx_mode GLXEW_GET_VAR(__GLXEW_MESA_set_3dfx_mode)
+
+#endif /* GLX_MESA_set_3dfx_mode */
+
+/* ------------------------- GLX_MESA_swap_control ------------------------- */
+
+#ifndef GLX_MESA_swap_control
+#define GLX_MESA_swap_control 1
+
+typedef int ( * PFNGLXGETSWAPINTERVALMESAPROC) (void);
+typedef int ( * PFNGLXSWAPINTERVALMESAPROC) (unsigned int interval);
+
+#define glXGetSwapIntervalMESA GLXEW_GET_FUN(__glewXGetSwapIntervalMESA)
+#define glXSwapIntervalMESA GLXEW_GET_FUN(__glewXSwapIntervalMESA)
+
+#define GLXEW_MESA_swap_control GLXEW_GET_VAR(__GLXEW_MESA_swap_control)
+
+#endif /* GLX_MESA_swap_control */
+
+/* --------------------------- GLX_NV_copy_image --------------------------- */
+
+#ifndef GLX_NV_copy_image
+#define GLX_NV_copy_image 1
+
+typedef void ( * PFNGLXCOPYIMAGESUBDATANVPROC) (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+
+#define glXCopyImageSubDataNV GLXEW_GET_FUN(__glewXCopyImageSubDataNV)
+
+#define GLXEW_NV_copy_image GLXEW_GET_VAR(__GLXEW_NV_copy_image)
+
+#endif /* GLX_NV_copy_image */
+
+/* -------------------------- GLX_NV_float_buffer -------------------------- */
+
+#ifndef GLX_NV_float_buffer
+#define GLX_NV_float_buffer 1
+
+#define GLX_FLOAT_COMPONENTS_NV 0x20B0
+
+#define GLXEW_NV_float_buffer GLXEW_GET_VAR(__GLXEW_NV_float_buffer)
+
+#endif /* GLX_NV_float_buffer */
+
+/* ---------------------- GLX_NV_multisample_coverage ---------------------- */
+
+#ifndef GLX_NV_multisample_coverage
+#define GLX_NV_multisample_coverage 1
+
+#define GLX_COLOR_SAMPLES_NV 0x20B3
+#define GLX_COVERAGE_SAMPLES_NV 100001
+
+#define GLXEW_NV_multisample_coverage GLXEW_GET_VAR(__GLXEW_NV_multisample_coverage)
+
+#endif /* GLX_NV_multisample_coverage */
+
+/* -------------------------- GLX_NV_present_video ------------------------- */
+
+#ifndef GLX_NV_present_video
+#define GLX_NV_present_video 1
+
+#define GLX_NUM_VIDEO_SLOTS_NV 0x20F0
+
+typedef int ( * PFNGLXBINDVIDEODEVICENVPROC) (Display* dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list);
+typedef unsigned int* ( * PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int screen, int *nelements);
+
+#define glXBindVideoDeviceNV GLXEW_GET_FUN(__glewXBindVideoDeviceNV)
+#define glXEnumerateVideoDevicesNV GLXEW_GET_FUN(__glewXEnumerateVideoDevicesNV)
+
+#define GLXEW_NV_present_video GLXEW_GET_VAR(__GLXEW_NV_present_video)
+
+#endif /* GLX_NV_present_video */
+
+/* --------------------------- GLX_NV_swap_group --------------------------- */
+
+#ifndef GLX_NV_swap_group
+#define GLX_NV_swap_group 1
+
+typedef Bool ( * PFNGLXBINDSWAPBARRIERNVPROC) (Display* dpy, GLuint group, GLuint barrier);
+typedef Bool ( * PFNGLXJOINSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint group);
+typedef Bool ( * PFNGLXQUERYFRAMECOUNTNVPROC) (Display* dpy, int screen, GLuint *count);
+typedef Bool ( * PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display* dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers);
+typedef Bool ( * PFNGLXQUERYSWAPGROUPNVPROC) (Display* dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier);
+typedef Bool ( * PFNGLXRESETFRAMECOUNTNVPROC) (Display* dpy, int screen);
+
+#define glXBindSwapBarrierNV GLXEW_GET_FUN(__glewXBindSwapBarrierNV)
+#define glXJoinSwapGroupNV GLXEW_GET_FUN(__glewXJoinSwapGroupNV)
+#define glXQueryFrameCountNV GLXEW_GET_FUN(__glewXQueryFrameCountNV)
+#define glXQueryMaxSwapGroupsNV GLXEW_GET_FUN(__glewXQueryMaxSwapGroupsNV)
+#define glXQuerySwapGroupNV GLXEW_GET_FUN(__glewXQuerySwapGroupNV)
+#define glXResetFrameCountNV GLXEW_GET_FUN(__glewXResetFrameCountNV)
+
+#define GLXEW_NV_swap_group GLXEW_GET_VAR(__GLXEW_NV_swap_group)
+
+#endif /* GLX_NV_swap_group */
+
+/* ----------------------- GLX_NV_vertex_array_range ----------------------- */
+
+#ifndef GLX_NV_vertex_array_range
+#define GLX_NV_vertex_array_range 1
+
+typedef void * ( * PFNGLXALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority);
+typedef void ( * PFNGLXFREEMEMORYNVPROC) (void *pointer);
+
+#define glXAllocateMemoryNV GLXEW_GET_FUN(__glewXAllocateMemoryNV)
+#define glXFreeMemoryNV GLXEW_GET_FUN(__glewXFreeMemoryNV)
+
+#define GLXEW_NV_vertex_array_range GLXEW_GET_VAR(__GLXEW_NV_vertex_array_range)
+
+#endif /* GLX_NV_vertex_array_range */
+
+/* -------------------------- GLX_NV_video_capture ------------------------- */
+
+#ifndef GLX_NV_video_capture
+#define GLX_NV_video_capture 1
+
+#define GLX_DEVICE_ID_NV 0x20CD
+#define GLX_UNIQUE_ID_NV 0x20CE
+#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
+
+typedef XID GLXVideoCaptureDeviceNV;
+
+typedef int ( * PFNGLXBINDVIDEOCAPTUREDEVICENVPROC) (Display* dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device);
+typedef GLXVideoCaptureDeviceNV * ( * PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC) (Display* dpy, int screen, int *nelements);
+typedef void ( * PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device);
+typedef int ( * PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value);
+typedef void ( * PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC) (Display* dpy, GLXVideoCaptureDeviceNV device);
+
+#define glXBindVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXBindVideoCaptureDeviceNV)
+#define glXEnumerateVideoCaptureDevicesNV GLXEW_GET_FUN(__glewXEnumerateVideoCaptureDevicesNV)
+#define glXLockVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXLockVideoCaptureDeviceNV)
+#define glXQueryVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXQueryVideoCaptureDeviceNV)
+#define glXReleaseVideoCaptureDeviceNV GLXEW_GET_FUN(__glewXReleaseVideoCaptureDeviceNV)
+
+#define GLXEW_NV_video_capture GLXEW_GET_VAR(__GLXEW_NV_video_capture)
+
+#endif /* GLX_NV_video_capture */
+
+/* -------------------------- GLX_NV_video_output -------------------------- */
+
+#ifndef GLX_NV_video_output
+#define GLX_NV_video_output 1
+
+#define GLX_VIDEO_OUT_COLOR_NV 0x20C3
+#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4
+#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5
+#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
+#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
+#define GLX_VIDEO_OUT_FRAME_NV 0x20C8
+#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9
+#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA
+#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB
+#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC
+
+typedef int ( * PFNGLXBINDVIDEOIMAGENVPROC) (Display* dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer);
+typedef int ( * PFNGLXGETVIDEODEVICENVPROC) (Display* dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice);
+typedef int ( * PFNGLXGETVIDEOINFONVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+typedef int ( * PFNGLXRELEASEVIDEODEVICENVPROC) (Display* dpy, int screen, GLXVideoDeviceNV VideoDevice);
+typedef int ( * PFNGLXRELEASEVIDEOIMAGENVPROC) (Display* dpy, GLXPbuffer pbuf);
+typedef int ( * PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display* dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock);
+
+#define glXBindVideoImageNV GLXEW_GET_FUN(__glewXBindVideoImageNV)
+#define glXGetVideoDeviceNV GLXEW_GET_FUN(__glewXGetVideoDeviceNV)
+#define glXGetVideoInfoNV GLXEW_GET_FUN(__glewXGetVideoInfoNV)
+#define glXReleaseVideoDeviceNV GLXEW_GET_FUN(__glewXReleaseVideoDeviceNV)
+#define glXReleaseVideoImageNV GLXEW_GET_FUN(__glewXReleaseVideoImageNV)
+#define glXSendPbufferToVideoNV GLXEW_GET_FUN(__glewXSendPbufferToVideoNV)
+
+#define GLXEW_NV_video_output GLXEW_GET_VAR(__GLXEW_NV_video_output)
+
+#endif /* GLX_NV_video_output */
+
+/* -------------------------- GLX_OML_swap_method -------------------------- */
+
+#ifndef GLX_OML_swap_method
+#define GLX_OML_swap_method 1
+
+#define GLX_SWAP_METHOD_OML 0x8060
+#define GLX_SWAP_EXCHANGE_OML 0x8061
+#define GLX_SWAP_COPY_OML 0x8062
+#define GLX_SWAP_UNDEFINED_OML 0x8063
+
+#define GLXEW_OML_swap_method GLXEW_GET_VAR(__GLXEW_OML_swap_method)
+
+#endif /* GLX_OML_swap_method */
+
+/* -------------------------- GLX_OML_sync_control ------------------------- */
+
+#ifndef GLX_OML_sync_control
+#define GLX_OML_sync_control 1
+
+typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator);
+typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc);
+typedef int64_t ( * PFNGLXSWAPBUFFERSMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder);
+typedef Bool ( * PFNGLXWAITFORMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc);
+typedef Bool ( * PFNGLXWAITFORSBCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc);
+
+#define glXGetMscRateOML GLXEW_GET_FUN(__glewXGetMscRateOML)
+#define glXGetSyncValuesOML GLXEW_GET_FUN(__glewXGetSyncValuesOML)
+#define glXSwapBuffersMscOML GLXEW_GET_FUN(__glewXSwapBuffersMscOML)
+#define glXWaitForMscOML GLXEW_GET_FUN(__glewXWaitForMscOML)
+#define glXWaitForSbcOML GLXEW_GET_FUN(__glewXWaitForSbcOML)
+
+#define GLXEW_OML_sync_control GLXEW_GET_VAR(__GLXEW_OML_sync_control)
+
+#endif /* GLX_OML_sync_control */
+
+/* ------------------------ GLX_SGIS_blended_overlay ----------------------- */
+
+#ifndef GLX_SGIS_blended_overlay
+#define GLX_SGIS_blended_overlay 1
+
+#define GLX_BLENDED_RGBA_SGIS 0x8025
+
+#define GLXEW_SGIS_blended_overlay GLXEW_GET_VAR(__GLXEW_SGIS_blended_overlay)
+
+#endif /* GLX_SGIS_blended_overlay */
+
+/* -------------------------- GLX_SGIS_color_range ------------------------- */
+
+#ifndef GLX_SGIS_color_range
+#define GLX_SGIS_color_range 1
+
+#define GLXEW_SGIS_color_range GLXEW_GET_VAR(__GLXEW_SGIS_color_range)
+
+#endif /* GLX_SGIS_color_range */
+
+/* -------------------------- GLX_SGIS_multisample ------------------------- */
+
+#ifndef GLX_SGIS_multisample
+#define GLX_SGIS_multisample 1
+
+#define GLX_SAMPLE_BUFFERS_SGIS 100000
+#define GLX_SAMPLES_SGIS 100001
+
+#define GLXEW_SGIS_multisample GLXEW_GET_VAR(__GLXEW_SGIS_multisample)
+
+#endif /* GLX_SGIS_multisample */
+
+/* ---------------------- GLX_SGIS_shared_multisample ---------------------- */
+
+#ifndef GLX_SGIS_shared_multisample
+#define GLX_SGIS_shared_multisample 1
+
+#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026
+#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027
+
+#define GLXEW_SGIS_shared_multisample GLXEW_GET_VAR(__GLXEW_SGIS_shared_multisample)
+
+#endif /* GLX_SGIS_shared_multisample */
+
+/* --------------------------- GLX_SGIX_fbconfig --------------------------- */
+
+#ifndef GLX_SGIX_fbconfig
+#define GLX_SGIX_fbconfig 1
+
+#define GLX_WINDOW_BIT_SGIX 0x00000001
+#define GLX_RGBA_BIT_SGIX 0x00000001
+#define GLX_PIXMAP_BIT_SGIX 0x00000002
+#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002
+#define GLX_SCREEN_EXT 0x800C
+#define GLX_DRAWABLE_TYPE_SGIX 0x8010
+#define GLX_RENDER_TYPE_SGIX 0x8011
+#define GLX_X_RENDERABLE_SGIX 0x8012
+#define GLX_FBCONFIG_ID_SGIX 0x8013
+#define GLX_RGBA_TYPE_SGIX 0x8014
+#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015
+
+typedef XID GLXFBConfigIDSGIX;
+typedef struct __GLXFBConfigRec *GLXFBConfigSGIX;
+
+typedef GLXFBConfigSGIX* ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
+typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display* dpy, GLXFBConfig config, Pixmap pixmap);
+typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display* dpy, GLXFBConfigSGIX config, int attribute, int *value);
+typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display* dpy, XVisualInfo *vis);
+typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfig config);
+
+#define glXChooseFBConfigSGIX GLXEW_GET_FUN(__glewXChooseFBConfigSGIX)
+#define glXCreateContextWithConfigSGIX GLXEW_GET_FUN(__glewXCreateContextWithConfigSGIX)
+#define glXCreateGLXPixmapWithConfigSGIX GLXEW_GET_FUN(__glewXCreateGLXPixmapWithConfigSGIX)
+#define glXGetFBConfigAttribSGIX GLXEW_GET_FUN(__glewXGetFBConfigAttribSGIX)
+#define glXGetFBConfigFromVisualSGIX GLXEW_GET_FUN(__glewXGetFBConfigFromVisualSGIX)
+#define glXGetVisualFromFBConfigSGIX GLXEW_GET_FUN(__glewXGetVisualFromFBConfigSGIX)
+
+#define GLXEW_SGIX_fbconfig GLXEW_GET_VAR(__GLXEW_SGIX_fbconfig)
+
+#endif /* GLX_SGIX_fbconfig */
+
+/* --------------------------- GLX_SGIX_hyperpipe -------------------------- */
+
+#ifndef GLX_SGIX_hyperpipe
+#define GLX_SGIX_hyperpipe 1
+
+#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001
+#define GLX_PIPE_RECT_SGIX 0x00000001
+#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002
+#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002
+#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003
+#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004
+#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80
+#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91
+#define GLX_BAD_HYPERPIPE_SGIX 92
+#define GLX_HYPERPIPE_ID_SGIX 0x8030
+
+typedef struct {
+ char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+ int networkId;
+} GLXHyperpipeNetworkSGIX;
+typedef struct {
+ char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+ int XOrigin;
+ int YOrigin;
+ int maxHeight;
+ int maxWidth;
+} GLXPipeRectLimits;
+typedef struct {
+ char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+ int channel;
+ unsigned int participationType;
+ int timeSlice;
+} GLXHyperpipeConfigSGIX;
+typedef struct {
+ char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+ int srcXOrigin;
+ int srcYOrigin;
+ int srcWidth;
+ int srcHeight;
+ int destXOrigin;
+ int destYOrigin;
+ int destWidth;
+ int destHeight;
+} GLXPipeRect;
+
+typedef int ( * PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId);
+typedef int ( * PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId);
+typedef int ( * PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList);
+typedef int ( * PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId);
+typedef int ( * PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList);
+typedef int ( * PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList);
+typedef GLXHyperpipeConfigSGIX * ( * PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes);
+typedef GLXHyperpipeNetworkSGIX * ( * PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes);
+
+#define glXBindHyperpipeSGIX GLXEW_GET_FUN(__glewXBindHyperpipeSGIX)
+#define glXDestroyHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXDestroyHyperpipeConfigSGIX)
+#define glXHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXHyperpipeAttribSGIX)
+#define glXHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXHyperpipeConfigSGIX)
+#define glXQueryHyperpipeAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeAttribSGIX)
+#define glXQueryHyperpipeBestAttribSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeBestAttribSGIX)
+#define glXQueryHyperpipeConfigSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeConfigSGIX)
+#define glXQueryHyperpipeNetworkSGIX GLXEW_GET_FUN(__glewXQueryHyperpipeNetworkSGIX)
+
+#define GLXEW_SGIX_hyperpipe GLXEW_GET_VAR(__GLXEW_SGIX_hyperpipe)
+
+#endif /* GLX_SGIX_hyperpipe */
+
+/* ---------------------------- GLX_SGIX_pbuffer --------------------------- */
+
+#ifndef GLX_SGIX_pbuffer
+#define GLX_SGIX_pbuffer 1
+
+#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001
+#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002
+#define GLX_PBUFFER_BIT_SGIX 0x00000004
+#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004
+#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008
+#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010
+#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020
+#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040
+#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080
+#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100
+#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016
+#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017
+#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018
+#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019
+#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A
+#define GLX_PRESERVED_CONTENTS_SGIX 0x801B
+#define GLX_LARGEST_PBUFFER_SGIX 0x801C
+#define GLX_WIDTH_SGIX 0x801D
+#define GLX_HEIGHT_SGIX 0x801E
+#define GLX_EVENT_MASK_SGIX 0x801F
+#define GLX_DAMAGED_SGIX 0x8020
+#define GLX_SAVED_SGIX 0x8021
+#define GLX_WINDOW_SGIX 0x8022
+#define GLX_PBUFFER_SGIX 0x8023
+#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000
+
+typedef XID GLXPbufferSGIX;
+typedef struct { int type; unsigned long serial; Bool send_event; Display *display; GLXDrawable drawable; int event_type; int draw_type; unsigned int mask; int x, y; int width, height; int count; } GLXBufferClobberEventSGIX;
+
+typedef GLXPbuffer ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display* dpy, GLXFBConfig config, unsigned int width, unsigned int height, int *attrib_list);
+typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf);
+typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long *mask);
+typedef void ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display* dpy, GLXPbuffer pbuf, int attribute, unsigned int *value);
+typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display* dpy, GLXDrawable drawable, unsigned long mask);
+
+#define glXCreateGLXPbufferSGIX GLXEW_GET_FUN(__glewXCreateGLXPbufferSGIX)
+#define glXDestroyGLXPbufferSGIX GLXEW_GET_FUN(__glewXDestroyGLXPbufferSGIX)
+#define glXGetSelectedEventSGIX GLXEW_GET_FUN(__glewXGetSelectedEventSGIX)
+#define glXQueryGLXPbufferSGIX GLXEW_GET_FUN(__glewXQueryGLXPbufferSGIX)
+#define glXSelectEventSGIX GLXEW_GET_FUN(__glewXSelectEventSGIX)
+
+#define GLXEW_SGIX_pbuffer GLXEW_GET_VAR(__GLXEW_SGIX_pbuffer)
+
+#endif /* GLX_SGIX_pbuffer */
+
+/* ------------------------- GLX_SGIX_swap_barrier ------------------------- */
+
+#ifndef GLX_SGIX_swap_barrier
+#define GLX_SGIX_swap_barrier 1
+
+typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier);
+typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max);
+
+#define glXBindSwapBarrierSGIX GLXEW_GET_FUN(__glewXBindSwapBarrierSGIX)
+#define glXQueryMaxSwapBarriersSGIX GLXEW_GET_FUN(__glewXQueryMaxSwapBarriersSGIX)
+
+#define GLXEW_SGIX_swap_barrier GLXEW_GET_VAR(__GLXEW_SGIX_swap_barrier)
+
+#endif /* GLX_SGIX_swap_barrier */
+
+/* -------------------------- GLX_SGIX_swap_group -------------------------- */
+
+#ifndef GLX_SGIX_swap_group
+#define GLX_SGIX_swap_group 1
+
+typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member);
+
+#define glXJoinSwapGroupSGIX GLXEW_GET_FUN(__glewXJoinSwapGroupSGIX)
+
+#define GLXEW_SGIX_swap_group GLXEW_GET_VAR(__GLXEW_SGIX_swap_group)
+
+#endif /* GLX_SGIX_swap_group */
+
+/* ------------------------- GLX_SGIX_video_resize ------------------------- */
+
+#ifndef GLX_SGIX_video_resize
+#define GLX_SGIX_video_resize 1
+
+#define GLX_SYNC_FRAME_SGIX 0x00000000
+#define GLX_SYNC_SWAP_SGIX 0x00000001
+
+typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display* display, int screen, int channel, Window window);
+typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int x, int y, int w, int h);
+typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display* display, int screen, int channel, GLenum synctype);
+typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display* display, int screen, int channel, int *x, int *y, int *w, int *h);
+typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display* display, int screen, int channel, int *dx, int *dy, int *dw, int *dh);
+
+#define glXBindChannelToWindowSGIX GLXEW_GET_FUN(__glewXBindChannelToWindowSGIX)
+#define glXChannelRectSGIX GLXEW_GET_FUN(__glewXChannelRectSGIX)
+#define glXChannelRectSyncSGIX GLXEW_GET_FUN(__glewXChannelRectSyncSGIX)
+#define glXQueryChannelDeltasSGIX GLXEW_GET_FUN(__glewXQueryChannelDeltasSGIX)
+#define glXQueryChannelRectSGIX GLXEW_GET_FUN(__glewXQueryChannelRectSGIX)
+
+#define GLXEW_SGIX_video_resize GLXEW_GET_VAR(__GLXEW_SGIX_video_resize)
+
+#endif /* GLX_SGIX_video_resize */
+
+/* ---------------------- GLX_SGIX_visual_select_group --------------------- */
+
+#ifndef GLX_SGIX_visual_select_group
+#define GLX_SGIX_visual_select_group 1
+
+#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028
+
+#define GLXEW_SGIX_visual_select_group GLXEW_GET_VAR(__GLXEW_SGIX_visual_select_group)
+
+#endif /* GLX_SGIX_visual_select_group */
+
+/* ---------------------------- GLX_SGI_cushion ---------------------------- */
+
+#ifndef GLX_SGI_cushion
+#define GLX_SGI_cushion 1
+
+typedef void ( * PFNGLXCUSHIONSGIPROC) (Display* dpy, Window window, float cushion);
+
+#define glXCushionSGI GLXEW_GET_FUN(__glewXCushionSGI)
+
+#define GLXEW_SGI_cushion GLXEW_GET_VAR(__GLXEW_SGI_cushion)
+
+#endif /* GLX_SGI_cushion */
+
+/* ----------------------- GLX_SGI_make_current_read ----------------------- */
+
+#ifndef GLX_SGI_make_current_read
+#define GLX_SGI_make_current_read 1
+
+typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void);
+typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+
+#define glXGetCurrentReadDrawableSGI GLXEW_GET_FUN(__glewXGetCurrentReadDrawableSGI)
+#define glXMakeCurrentReadSGI GLXEW_GET_FUN(__glewXMakeCurrentReadSGI)
+
+#define GLXEW_SGI_make_current_read GLXEW_GET_VAR(__GLXEW_SGI_make_current_read)
+
+#endif /* GLX_SGI_make_current_read */
+
+/* -------------------------- GLX_SGI_swap_control ------------------------- */
+
+#ifndef GLX_SGI_swap_control
+#define GLX_SGI_swap_control 1
+
+typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval);
+
+#define glXSwapIntervalSGI GLXEW_GET_FUN(__glewXSwapIntervalSGI)
+
+#define GLXEW_SGI_swap_control GLXEW_GET_VAR(__GLXEW_SGI_swap_control)
+
+#endif /* GLX_SGI_swap_control */
+
+/* --------------------------- GLX_SGI_video_sync -------------------------- */
+
+#ifndef GLX_SGI_video_sync
+#define GLX_SGI_video_sync 1
+
+typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int* count);
+typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int* count);
+
+#define glXGetVideoSyncSGI GLXEW_GET_FUN(__glewXGetVideoSyncSGI)
+#define glXWaitVideoSyncSGI GLXEW_GET_FUN(__glewXWaitVideoSyncSGI)
+
+#define GLXEW_SGI_video_sync GLXEW_GET_VAR(__GLXEW_SGI_video_sync)
+
+#endif /* GLX_SGI_video_sync */
+
+/* --------------------- GLX_SUN_get_transparent_index --------------------- */
+
+#ifndef GLX_SUN_get_transparent_index
+#define GLX_SUN_get_transparent_index 1
+
+typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display* dpy, Window overlay, Window underlay, unsigned long *pTransparentIndex);
+
+#define glXGetTransparentIndexSUN GLXEW_GET_FUN(__glewXGetTransparentIndexSUN)
+
+#define GLXEW_SUN_get_transparent_index GLXEW_GET_VAR(__GLXEW_SUN_get_transparent_index)
+
+#endif /* GLX_SUN_get_transparent_index */
+
+/* -------------------------- GLX_SUN_video_resize ------------------------- */
+
+#ifndef GLX_SUN_video_resize
+#define GLX_SUN_video_resize 1
+
+#define GLX_VIDEO_RESIZE_SUN 0x8171
+#define GL_VIDEO_RESIZE_COMPENSATION_SUN 0x85CD
+
+typedef int ( * PFNGLXGETVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float* factor);
+typedef int ( * PFNGLXVIDEORESIZESUNPROC) (Display* display, GLXDrawable window, float factor);
+
+#define glXGetVideoResizeSUN GLXEW_GET_FUN(__glewXGetVideoResizeSUN)
+#define glXVideoResizeSUN GLXEW_GET_FUN(__glewXVideoResizeSUN)
+
+#define GLXEW_SUN_video_resize GLXEW_GET_VAR(__GLXEW_SUN_video_resize)
+
+#endif /* GLX_SUN_video_resize */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef GLEW_MX
+#define GLXEW_FUN_EXPORT GLEW_FUN_EXPORT
+#define GLXEW_VAR_EXPORT
+#else
+#define GLXEW_FUN_EXPORT GLEW_FUN_EXPORT
+#define GLXEW_VAR_EXPORT GLEW_VAR_EXPORT
+#endif /* GLEW_MX */
+
+#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+GLXEW_FUN_EXPORT PFNGLXGETPROCADDRESSARBPROC __glewXGetProcAddressARB;
+GLXEW_FUN_EXPORT PFNGLXQUERYEXTENSION __glewXQueryExtension;
+GLXEW_FUN_EXPORT PFNGLXQUERYVERSION __glewXQueryVersion;
+GLXEW_FUN_EXPORT PFNGLXGETCONFIG __glewXGetConfig;
+GLXEW_FUN_EXPORT PFNGLXCHOOSEVISUAL __glewXChooseVisual;
+GLXEW_FUN_EXPORT PFNGLXCREATECONTEXT __glewXCreateContext;
+GLXEW_FUN_EXPORT PFNGLXDESTROYCONTEXT __glewXDestroyContext;
+GLXEW_FUN_EXPORT PFNGLXISDIRECT __glewXIsDirect;
+GLXEW_FUN_EXPORT PFNGLXMAKECURRENT __glewXMakeCurrent;
+GLXEW_FUN_EXPORT PFNGLXQUERYEXTENSIONSSTRING __glewXQueryExtensionsString;
+GLXEW_FUN_EXPORT PFNGLXGETCLIENTSTRING __glewXGetClientString;
+GLXEW_FUN_EXPORT PFNGLXQUERYSERVERSTRING __glewXQueryServerString;
+GLXEW_FUN_EXPORT PFNGLXSWAPBUFFERS __glewXSwapBuffers;
+
+
+#endif //GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+
+GLXEW_FUN_EXPORT PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay;
+
+GLXEW_FUN_EXPORT PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig;
+GLXEW_FUN_EXPORT PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext;
+GLXEW_FUN_EXPORT PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer;
+GLXEW_FUN_EXPORT PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap;
+GLXEW_FUN_EXPORT PFNGLXCREATEWINDOWPROC __glewXCreateWindow;
+GLXEW_FUN_EXPORT PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer;
+GLXEW_FUN_EXPORT PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap;
+GLXEW_FUN_EXPORT PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow;
+GLXEW_FUN_EXPORT PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable;
+GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib;
+GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs;
+GLXEW_FUN_EXPORT PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent;
+GLXEW_FUN_EXPORT PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig;
+GLXEW_FUN_EXPORT PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent;
+GLXEW_FUN_EXPORT PFNGLXQUERYCONTEXTPROC __glewXQueryContext;
+GLXEW_FUN_EXPORT PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable;
+GLXEW_FUN_EXPORT PFNGLXSELECTEVENTPROC __glewXSelectEvent;
+
+GLXEW_FUN_EXPORT PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC __glewXBlitContextFramebufferAMD;
+GLXEW_FUN_EXPORT PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC __glewXCreateAssociatedContextAMD;
+GLXEW_FUN_EXPORT PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __glewXCreateAssociatedContextAttribsAMD;
+GLXEW_FUN_EXPORT PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC __glewXDeleteAssociatedContextAMD;
+GLXEW_FUN_EXPORT PFNGLXGETCONTEXTGPUIDAMDPROC __glewXGetContextGPUIDAMD;
+GLXEW_FUN_EXPORT PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC __glewXGetCurrentAssociatedContextAMD;
+GLXEW_FUN_EXPORT PFNGLXGETGPUIDSAMDPROC __glewXGetGPUIDsAMD;
+GLXEW_FUN_EXPORT PFNGLXGETGPUINFOAMDPROC __glewXGetGPUInfoAMD;
+GLXEW_FUN_EXPORT PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __glewXMakeAssociatedContextCurrentAMD;
+
+GLXEW_FUN_EXPORT PFNGLXCREATECONTEXTATTRIBSARBPROC __glewXCreateContextAttribsARB;
+
+
+GLXEW_FUN_EXPORT PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI;
+GLXEW_FUN_EXPORT PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI;
+GLXEW_FUN_EXPORT PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI;
+
+GLXEW_FUN_EXPORT PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT;
+GLXEW_FUN_EXPORT PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT;
+GLXEW_FUN_EXPORT PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT;
+GLXEW_FUN_EXPORT PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT;
+
+GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALEXTPROC __glewXSwapIntervalEXT;
+
+GLXEW_FUN_EXPORT PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT;
+GLXEW_FUN_EXPORT PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT;
+
+GLXEW_FUN_EXPORT PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA;
+
+GLXEW_FUN_EXPORT PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA;
+
+GLXEW_FUN_EXPORT PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA;
+
+GLXEW_FUN_EXPORT PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA;
+
+GLXEW_FUN_EXPORT PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA;
+
+GLXEW_FUN_EXPORT PFNGLXGETSWAPINTERVALMESAPROC __glewXGetSwapIntervalMESA;
+GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALMESAPROC __glewXSwapIntervalMESA;
+
+GLXEW_FUN_EXPORT PFNGLXCOPYIMAGESUBDATANVPROC __glewXCopyImageSubDataNV;
+
+GLXEW_FUN_EXPORT PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV;
+GLXEW_FUN_EXPORT PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV;
+
+GLXEW_FUN_EXPORT PFNGLXBINDSWAPBARRIERNVPROC __glewXBindSwapBarrierNV;
+GLXEW_FUN_EXPORT PFNGLXJOINSWAPGROUPNVPROC __glewXJoinSwapGroupNV;
+GLXEW_FUN_EXPORT PFNGLXQUERYFRAMECOUNTNVPROC __glewXQueryFrameCountNV;
+GLXEW_FUN_EXPORT PFNGLXQUERYMAXSWAPGROUPSNVPROC __glewXQueryMaxSwapGroupsNV;
+GLXEW_FUN_EXPORT PFNGLXQUERYSWAPGROUPNVPROC __glewXQuerySwapGroupNV;
+GLXEW_FUN_EXPORT PFNGLXRESETFRAMECOUNTNVPROC __glewXResetFrameCountNV;
+
+GLXEW_FUN_EXPORT PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV;
+GLXEW_FUN_EXPORT PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV;
+
+GLXEW_FUN_EXPORT PFNGLXBINDVIDEOCAPTUREDEVICENVPROC __glewXBindVideoCaptureDeviceNV;
+GLXEW_FUN_EXPORT PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC __glewXEnumerateVideoCaptureDevicesNV;
+GLXEW_FUN_EXPORT PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC __glewXLockVideoCaptureDeviceNV;
+GLXEW_FUN_EXPORT PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC __glewXQueryVideoCaptureDeviceNV;
+GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC __glewXReleaseVideoCaptureDeviceNV;
+
+GLXEW_FUN_EXPORT PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV;
+GLXEW_FUN_EXPORT PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV;
+GLXEW_FUN_EXPORT PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV;
+GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV;
+GLXEW_FUN_EXPORT PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV;
+GLXEW_FUN_EXPORT PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV;
+
+GLXEW_FUN_EXPORT PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML;
+GLXEW_FUN_EXPORT PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML;
+GLXEW_FUN_EXPORT PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML;
+GLXEW_FUN_EXPORT PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML;
+GLXEW_FUN_EXPORT PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML;
+
+GLXEW_FUN_EXPORT PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX;
+GLXEW_FUN_EXPORT PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX;
+GLXEW_FUN_EXPORT PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX;
+GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX;
+GLXEW_FUN_EXPORT PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX;
+GLXEW_FUN_EXPORT PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX;
+
+GLXEW_FUN_EXPORT PFNGLXBINDHYPERPIPESGIXPROC __glewXBindHyperpipeSGIX;
+GLXEW_FUN_EXPORT PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC __glewXDestroyHyperpipeConfigSGIX;
+GLXEW_FUN_EXPORT PFNGLXHYPERPIPEATTRIBSGIXPROC __glewXHyperpipeAttribSGIX;
+GLXEW_FUN_EXPORT PFNGLXHYPERPIPECONFIGSGIXPROC __glewXHyperpipeConfigSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC __glewXQueryHyperpipeAttribSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC __glewXQueryHyperpipeBestAttribSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPECONFIGSGIXPROC __glewXQueryHyperpipeConfigSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYHYPERPIPENETWORKSGIXPROC __glewXQueryHyperpipeNetworkSGIX;
+
+GLXEW_FUN_EXPORT PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX;
+GLXEW_FUN_EXPORT PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX;
+GLXEW_FUN_EXPORT PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX;
+GLXEW_FUN_EXPORT PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX;
+
+GLXEW_FUN_EXPORT PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX;
+
+GLXEW_FUN_EXPORT PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX;
+
+GLXEW_FUN_EXPORT PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX;
+GLXEW_FUN_EXPORT PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX;
+GLXEW_FUN_EXPORT PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX;
+GLXEW_FUN_EXPORT PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX;
+
+GLXEW_FUN_EXPORT PFNGLXCUSHIONSGIPROC __glewXCushionSGI;
+
+GLXEW_FUN_EXPORT PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI;
+GLXEW_FUN_EXPORT PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI;
+
+GLXEW_FUN_EXPORT PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI;
+
+GLXEW_FUN_EXPORT PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI;
+GLXEW_FUN_EXPORT PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI;
+
+GLXEW_FUN_EXPORT PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN;
+
+GLXEW_FUN_EXPORT PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN;
+GLXEW_FUN_EXPORT PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN;
+
+#if defined(GLEW_MX)
+struct GLXEWContextStruct
+{
+#endif /* GLEW_MX */
+
+GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_0;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_1;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_2;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_3;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_VERSION_1_4;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_3DFX_multisample;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_AMD_gpu_association;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context_profile;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_create_context_robustness;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_fbconfig_float;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_framebuffer_sRGB;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_get_proc_address;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_multisample;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_robustness_application_isolation;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_robustness_share_group_isolation;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ARB_vertex_buffer_object;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ATI_pixel_format_float;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_ATI_render_texture;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_buffer_age;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_create_context_es2_profile;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_create_context_es_profile;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_fbconfig_packed_float;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_framebuffer_sRGB;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_import_context;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_scene_marker;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_swap_control;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_swap_control_tear;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_texture_from_pixmap;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_visual_info;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_EXT_visual_rating;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_INTEL_swap_event;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_agp_offset;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_copy_sub_buffer;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_pixmap_colormap;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_release_buffers;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_set_3dfx_mode;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_MESA_swap_control;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_copy_image;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_float_buffer;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_multisample_coverage;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_present_video;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_swap_group;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_vertex_array_range;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_video_capture;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_NV_video_output;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_OML_swap_method;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_OML_sync_control;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_blended_overlay;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_color_range;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_multisample;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIS_shared_multisample;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_fbconfig;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_hyperpipe;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_pbuffer;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_swap_barrier;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_swap_group;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_video_resize;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGIX_visual_select_group;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_cushion;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_make_current_read;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_swap_control;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SGI_video_sync;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SUN_get_transparent_index;
+GLXEW_VAR_EXPORT GLboolean __GLXEW_SUN_video_resize;
+
+#ifdef GLEW_MX
+}; /* GLXEWContextStruct */
+#endif /* GLEW_MX */
+
+/* ------------------------------------------------------------------------ */
+
+#ifdef GLEW_MX
+
+typedef struct GLXEWContextStruct GLXEWContext;
+GLEWAPI GLenum GLEWAPIENTRY glxewContextInit (GLXEWContext *ctx);
+GLEWAPI GLboolean GLEWAPIENTRY glxewContextIsSupported (const GLXEWContext *ctx, const char *name);
+
+#define glxewInit() glxewContextInit(glxewGetContext())
+#define glxewIsSupported(x) glxewContextIsSupported(glxewGetContext(), x)
+
+#define GLXEW_GET_VAR(x) (*(const GLboolean*)&(glxewGetContext()->x))
+#define GLXEW_GET_FUN(x) x
+
+#else /* GLEW_MX */
+
+#define GLXEW_GET_VAR(x) (*(const GLboolean*)&x)
+#define GLXEW_GET_FUN(x) x
+
+GLEWAPI GLboolean GLEWAPIENTRY glxewIsSupported (const char *name);
+
+#endif /* GLEW_MX */
+
+GLEWAPI GLboolean GLEWAPIENTRY glxewGetExtension (const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __glxew_h__ */
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/wglew.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/wglew.h
new file mode 100644
index 0000000000..8659841d35
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/CustomGL/wglew.h
@@ -0,0 +1,1421 @@
+/*
+** The OpenGL Extension Wrangler Library
+** Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org>
+** Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org>
+** Copyright (C) 2002, Lev Povalahev
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** * The name of the author may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+** THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+** Copyright (c) 2007 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are 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 Materials.
+**
+** THE MATERIALS ARE 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 AUTHORS OR COPYRIGHT HOLDERS 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
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#ifndef __wglew_h__
+#define __wglew_h__
+#define __WGLEW_H__
+
+#ifdef __wglext_h_
+#error wglext.h included before wglew.h
+#endif
+
+#define __wglext_h_
+
+#if !defined(WINAPI)
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN 1
+# endif
+#include <windows.h>
+# undef WIN32_LEAN_AND_MEAN
+#endif
+
+/*
+ * GLEW_STATIC needs to be set when using the static version.
+ * GLEW_BUILD is set when building the DLL version.
+ */
+#ifdef GLEW_STATIC
+# define GLEWAPI extern
+#else
+# ifdef GLEW_BUILD
+# define GLEWAPI extern __declspec(dllexport)
+# else
+# define GLEWAPI extern __declspec(dllimport)
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* -------------------------- WGL_3DFX_multisample ------------------------- */
+
+#ifndef WGL_3DFX_multisample
+#define WGL_3DFX_multisample 1
+
+#define WGL_SAMPLE_BUFFERS_3DFX 0x2060
+#define WGL_SAMPLES_3DFX 0x2061
+
+#define WGLEW_3DFX_multisample WGLEW_GET_VAR(__WGLEW_3DFX_multisample)
+
+#endif /* WGL_3DFX_multisample */
+
+/* ------------------------- WGL_3DL_stereo_control ------------------------ */
+
+#ifndef WGL_3DL_stereo_control
+#define WGL_3DL_stereo_control 1
+
+#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
+#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
+#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
+#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
+
+typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState);
+
+#define wglSetStereoEmitterState3DL WGLEW_GET_FUN(__wglewSetStereoEmitterState3DL)
+
+#define WGLEW_3DL_stereo_control WGLEW_GET_VAR(__WGLEW_3DL_stereo_control)
+
+#endif /* WGL_3DL_stereo_control */
+
+/* ------------------------ WGL_AMD_gpu_association ------------------------ */
+
+#ifndef WGL_AMD_gpu_association
+#define WGL_AMD_gpu_association 1
+
+#define WGL_GPU_VENDOR_AMD 0x1F00
+#define WGL_GPU_RENDERER_STRING_AMD 0x1F01
+#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
+#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
+#define WGL_GPU_RAM_AMD 0x21A3
+#define WGL_GPU_CLOCK_AMD 0x21A4
+#define WGL_GPU_NUM_PIPES_AMD 0x21A5
+#define WGL_GPU_NUM_SIMD_AMD 0x21A6
+#define WGL_GPU_NUM_RB_AMD 0x21A7
+#define WGL_GPU_NUM_SPI_AMD 0x21A8
+
+typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int* attribList);
+typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
+typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
+typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
+typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT* ids);
+typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, INT property, GLenum dataType, UINT size, void* data);
+typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
+
+#define wglBlitContextFramebufferAMD WGLEW_GET_FUN(__wglewBlitContextFramebufferAMD)
+#define wglCreateAssociatedContextAMD WGLEW_GET_FUN(__wglewCreateAssociatedContextAMD)
+#define wglCreateAssociatedContextAttribsAMD WGLEW_GET_FUN(__wglewCreateAssociatedContextAttribsAMD)
+#define wglDeleteAssociatedContextAMD WGLEW_GET_FUN(__wglewDeleteAssociatedContextAMD)
+#define wglGetContextGPUIDAMD WGLEW_GET_FUN(__wglewGetContextGPUIDAMD)
+#define wglGetCurrentAssociatedContextAMD WGLEW_GET_FUN(__wglewGetCurrentAssociatedContextAMD)
+#define wglGetGPUIDsAMD WGLEW_GET_FUN(__wglewGetGPUIDsAMD)
+#define wglGetGPUInfoAMD WGLEW_GET_FUN(__wglewGetGPUInfoAMD)
+#define wglMakeAssociatedContextCurrentAMD WGLEW_GET_FUN(__wglewMakeAssociatedContextCurrentAMD)
+
+#define WGLEW_AMD_gpu_association WGLEW_GET_VAR(__WGLEW_AMD_gpu_association)
+
+#endif /* WGL_AMD_gpu_association */
+
+/* ------------------------- WGL_ARB_buffer_region ------------------------- */
+
+#ifndef WGL_ARB_buffer_region
+#define WGL_ARB_buffer_region 1
+
+#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
+#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
+#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
+#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
+
+typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
+typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
+typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
+typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
+
+#define wglCreateBufferRegionARB WGLEW_GET_FUN(__wglewCreateBufferRegionARB)
+#define wglDeleteBufferRegionARB WGLEW_GET_FUN(__wglewDeleteBufferRegionARB)
+#define wglRestoreBufferRegionARB WGLEW_GET_FUN(__wglewRestoreBufferRegionARB)
+#define wglSaveBufferRegionARB WGLEW_GET_FUN(__wglewSaveBufferRegionARB)
+
+#define WGLEW_ARB_buffer_region WGLEW_GET_VAR(__WGLEW_ARB_buffer_region)
+
+#endif /* WGL_ARB_buffer_region */
+
+/* ------------------------- WGL_ARB_create_context ------------------------ */
+
+#ifndef WGL_ARB_create_context
+#define WGL_ARB_create_context 1
+
+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define ERROR_INVALID_VERSION_ARB 0x2095
+#define ERROR_INVALID_PROFILE_ARB 0x2096
+
+typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int* attribList);
+
+#define wglCreateContextAttribsARB WGLEW_GET_FUN(__wglewCreateContextAttribsARB)
+
+#define WGLEW_ARB_create_context WGLEW_GET_VAR(__WGLEW_ARB_create_context)
+
+#endif /* WGL_ARB_create_context */
+
+/* --------------------- WGL_ARB_create_context_profile -------------------- */
+
+#ifndef WGL_ARB_create_context_profile
+#define WGL_ARB_create_context_profile 1
+
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+
+#define WGLEW_ARB_create_context_profile WGLEW_GET_VAR(__WGLEW_ARB_create_context_profile)
+
+#endif /* WGL_ARB_create_context_profile */
+
+/* ------------------- WGL_ARB_create_context_robustness ------------------- */
+
+#ifndef WGL_ARB_create_context_robustness
+#define WGL_ARB_create_context_robustness 1
+
+#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
+
+#define WGLEW_ARB_create_context_robustness WGLEW_GET_VAR(__WGLEW_ARB_create_context_robustness)
+
+#endif /* WGL_ARB_create_context_robustness */
+
+/* ----------------------- WGL_ARB_extensions_string ----------------------- */
+
+#ifndef WGL_ARB_extensions_string
+#define WGL_ARB_extensions_string 1
+
+typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
+
+#define wglGetExtensionsStringARB WGLEW_GET_FUN(__wglewGetExtensionsStringARB)
+
+#define WGLEW_ARB_extensions_string WGLEW_GET_VAR(__WGLEW_ARB_extensions_string)
+
+#endif /* WGL_ARB_extensions_string */
+
+/* ------------------------ WGL_ARB_framebuffer_sRGB ----------------------- */
+
+#ifndef WGL_ARB_framebuffer_sRGB
+#define WGL_ARB_framebuffer_sRGB 1
+
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
+
+#define WGLEW_ARB_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_ARB_framebuffer_sRGB)
+
+#endif /* WGL_ARB_framebuffer_sRGB */
+
+/* ----------------------- WGL_ARB_make_current_read ----------------------- */
+
+#ifndef WGL_ARB_make_current_read
+#define WGL_ARB_make_current_read 1
+
+#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
+#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
+
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (VOID);
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+
+#define wglGetCurrentReadDCARB WGLEW_GET_FUN(__wglewGetCurrentReadDCARB)
+#define wglMakeContextCurrentARB WGLEW_GET_FUN(__wglewMakeContextCurrentARB)
+
+#define WGLEW_ARB_make_current_read WGLEW_GET_VAR(__WGLEW_ARB_make_current_read)
+
+#endif /* WGL_ARB_make_current_read */
+
+/* -------------------------- WGL_ARB_multisample -------------------------- */
+
+#ifndef WGL_ARB_multisample
+#define WGL_ARB_multisample 1
+
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+
+#define WGLEW_ARB_multisample WGLEW_GET_VAR(__WGLEW_ARB_multisample)
+
+#endif /* WGL_ARB_multisample */
+
+/* ---------------------------- WGL_ARB_pbuffer ---------------------------- */
+
+#ifndef WGL_ARB_pbuffer
+#define WGL_ARB_pbuffer 1
+
+#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
+#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
+#define WGL_PBUFFER_LARGEST_ARB 0x2033
+#define WGL_PBUFFER_WIDTH_ARB 0x2034
+#define WGL_PBUFFER_HEIGHT_ARB 0x2035
+#define WGL_PBUFFER_LOST_ARB 0x2036
+
+DECLARE_HANDLE(HPBUFFERARB);
+
+typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int* piValue);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
+
+#define wglCreatePbufferARB WGLEW_GET_FUN(__wglewCreatePbufferARB)
+#define wglDestroyPbufferARB WGLEW_GET_FUN(__wglewDestroyPbufferARB)
+#define wglGetPbufferDCARB WGLEW_GET_FUN(__wglewGetPbufferDCARB)
+#define wglQueryPbufferARB WGLEW_GET_FUN(__wglewQueryPbufferARB)
+#define wglReleasePbufferDCARB WGLEW_GET_FUN(__wglewReleasePbufferDCARB)
+
+#define WGLEW_ARB_pbuffer WGLEW_GET_VAR(__WGLEW_ARB_pbuffer)
+
+#endif /* WGL_ARB_pbuffer */
+
+/* -------------------------- WGL_ARB_pixel_format ------------------------- */
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_ARB_pixel_format 1
+
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_DRAW_TO_BITMAP_ARB 0x2002
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_NEED_PALETTE_ARB 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
+#define WGL_SWAP_METHOD_ARB 0x2007
+#define WGL_NUMBER_OVERLAYS_ARB 0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
+#define WGL_TRANSPARENT_ARB 0x200A
+#define WGL_SHARE_DEPTH_ARB 0x200C
+#define WGL_SHARE_STENCIL_ARB 0x200D
+#define WGL_SHARE_ACCUM_ARB 0x200E
+#define WGL_SUPPORT_GDI_ARB 0x200F
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_STEREO_ARB 0x2012
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_RED_SHIFT_ARB 0x2016
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_GREEN_SHIFT_ARB 0x2018
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_BLUE_SHIFT_ARB 0x201A
+#define WGL_ALPHA_BITS_ARB 0x201B
+#define WGL_ALPHA_SHIFT_ARB 0x201C
+#define WGL_ACCUM_BITS_ARB 0x201D
+#define WGL_ACCUM_RED_BITS_ARB 0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_NO_ACCELERATION_ARB 0x2025
+#define WGL_GENERIC_ACCELERATION_ARB 0x2026
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#define WGL_SWAP_EXCHANGE_ARB 0x2028
+#define WGL_SWAP_COPY_ARB 0x2029
+#define WGL_SWAP_UNDEFINED_ARB 0x202A
+#define WGL_TYPE_RGBA_ARB 0x202B
+#define WGL_TYPE_COLORINDEX_ARB 0x202C
+#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, int *piValues);
+
+#define wglChoosePixelFormatARB WGLEW_GET_FUN(__wglewChoosePixelFormatARB)
+#define wglGetPixelFormatAttribfvARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvARB)
+#define wglGetPixelFormatAttribivARB WGLEW_GET_FUN(__wglewGetPixelFormatAttribivARB)
+
+#define WGLEW_ARB_pixel_format WGLEW_GET_VAR(__WGLEW_ARB_pixel_format)
+
+#endif /* WGL_ARB_pixel_format */
+
+/* ----------------------- WGL_ARB_pixel_format_float ---------------------- */
+
+#ifndef WGL_ARB_pixel_format_float
+#define WGL_ARB_pixel_format_float 1
+
+#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
+
+#define WGLEW_ARB_pixel_format_float WGLEW_GET_VAR(__WGLEW_ARB_pixel_format_float)
+
+#endif /* WGL_ARB_pixel_format_float */
+
+/* ------------------------- WGL_ARB_render_texture ------------------------ */
+
+#ifndef WGL_ARB_render_texture
+#define WGL_ARB_render_texture 1
+
+#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
+#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
+#define WGL_TEXTURE_FORMAT_ARB 0x2072
+#define WGL_TEXTURE_TARGET_ARB 0x2073
+#define WGL_MIPMAP_TEXTURE_ARB 0x2074
+#define WGL_TEXTURE_RGB_ARB 0x2075
+#define WGL_TEXTURE_RGBA_ARB 0x2076
+#define WGL_NO_TEXTURE_ARB 0x2077
+#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
+#define WGL_TEXTURE_1D_ARB 0x2079
+#define WGL_TEXTURE_2D_ARB 0x207A
+#define WGL_MIPMAP_LEVEL_ARB 0x207B
+#define WGL_CUBE_MAP_FACE_ARB 0x207C
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
+#define WGL_FRONT_LEFT_ARB 0x2083
+#define WGL_FRONT_RIGHT_ARB 0x2084
+#define WGL_BACK_LEFT_ARB 0x2085
+#define WGL_BACK_RIGHT_ARB 0x2086
+#define WGL_AUX0_ARB 0x2087
+#define WGL_AUX1_ARB 0x2088
+#define WGL_AUX2_ARB 0x2089
+#define WGL_AUX3_ARB 0x208A
+#define WGL_AUX4_ARB 0x208B
+#define WGL_AUX5_ARB 0x208C
+#define WGL_AUX6_ARB 0x208D
+#define WGL_AUX7_ARB 0x208E
+#define WGL_AUX8_ARB 0x208F
+#define WGL_AUX9_ARB 0x2090
+
+typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int* piAttribList);
+
+#define wglBindTexImageARB WGLEW_GET_FUN(__wglewBindTexImageARB)
+#define wglReleaseTexImageARB WGLEW_GET_FUN(__wglewReleaseTexImageARB)
+#define wglSetPbufferAttribARB WGLEW_GET_FUN(__wglewSetPbufferAttribARB)
+
+#define WGLEW_ARB_render_texture WGLEW_GET_VAR(__WGLEW_ARB_render_texture)
+
+#endif /* WGL_ARB_render_texture */
+
+/* ---------------- WGL_ARB_robustness_application_isolation --------------- */
+
+#ifndef WGL_ARB_robustness_application_isolation
+#define WGL_ARB_robustness_application_isolation 1
+
+#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
+
+#define WGLEW_ARB_robustness_application_isolation WGLEW_GET_VAR(__WGLEW_ARB_robustness_application_isolation)
+
+#endif /* WGL_ARB_robustness_application_isolation */
+
+/* ---------------- WGL_ARB_robustness_share_group_isolation --------------- */
+
+#ifndef WGL_ARB_robustness_share_group_isolation
+#define WGL_ARB_robustness_share_group_isolation 1
+
+#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
+
+#define WGLEW_ARB_robustness_share_group_isolation WGLEW_GET_VAR(__WGLEW_ARB_robustness_share_group_isolation)
+
+#endif /* WGL_ARB_robustness_share_group_isolation */
+
+/* ----------------------- WGL_ATI_pixel_format_float ---------------------- */
+
+#ifndef WGL_ATI_pixel_format_float
+#define WGL_ATI_pixel_format_float 1
+
+#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
+#define GL_RGBA_FLOAT_MODE_ATI 0x8820
+#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835
+
+#define WGLEW_ATI_pixel_format_float WGLEW_GET_VAR(__WGLEW_ATI_pixel_format_float)
+
+#endif /* WGL_ATI_pixel_format_float */
+
+/* -------------------- WGL_ATI_render_texture_rectangle ------------------- */
+
+#ifndef WGL_ATI_render_texture_rectangle
+#define WGL_ATI_render_texture_rectangle 1
+
+#define WGL_TEXTURE_RECTANGLE_ATI 0x21A5
+
+#define WGLEW_ATI_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_ATI_render_texture_rectangle)
+
+#endif /* WGL_ATI_render_texture_rectangle */
+
+/* ------------------- WGL_EXT_create_context_es2_profile ------------------ */
+
+#ifndef WGL_EXT_create_context_es2_profile
+#define WGL_EXT_create_context_es2_profile 1
+
+#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+
+#define WGLEW_EXT_create_context_es2_profile WGLEW_GET_VAR(__WGLEW_EXT_create_context_es2_profile)
+
+#endif /* WGL_EXT_create_context_es2_profile */
+
+/* ------------------- WGL_EXT_create_context_es_profile ------------------- */
+
+#ifndef WGL_EXT_create_context_es_profile
+#define WGL_EXT_create_context_es_profile 1
+
+#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
+
+#define WGLEW_EXT_create_context_es_profile WGLEW_GET_VAR(__WGLEW_EXT_create_context_es_profile)
+
+#endif /* WGL_EXT_create_context_es_profile */
+
+/* -------------------------- WGL_EXT_depth_float -------------------------- */
+
+#ifndef WGL_EXT_depth_float
+#define WGL_EXT_depth_float 1
+
+#define WGL_DEPTH_FLOAT_EXT 0x2040
+
+#define WGLEW_EXT_depth_float WGLEW_GET_VAR(__WGLEW_EXT_depth_float)
+
+#endif /* WGL_EXT_depth_float */
+
+/* ---------------------- WGL_EXT_display_color_table ---------------------- */
+
+#ifndef WGL_EXT_display_color_table
+#define WGL_EXT_display_color_table 1
+
+typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef void (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (GLushort* table, GLuint length);
+
+#define wglBindDisplayColorTableEXT WGLEW_GET_FUN(__wglewBindDisplayColorTableEXT)
+#define wglCreateDisplayColorTableEXT WGLEW_GET_FUN(__wglewCreateDisplayColorTableEXT)
+#define wglDestroyDisplayColorTableEXT WGLEW_GET_FUN(__wglewDestroyDisplayColorTableEXT)
+#define wglLoadDisplayColorTableEXT WGLEW_GET_FUN(__wglewLoadDisplayColorTableEXT)
+
+#define WGLEW_EXT_display_color_table WGLEW_GET_VAR(__WGLEW_EXT_display_color_table)
+
+#endif /* WGL_EXT_display_color_table */
+
+/* ----------------------- WGL_EXT_extensions_string ----------------------- */
+
+#ifndef WGL_EXT_extensions_string
+#define WGL_EXT_extensions_string 1
+
+typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
+
+#define wglGetExtensionsStringEXT WGLEW_GET_FUN(__wglewGetExtensionsStringEXT)
+
+#define WGLEW_EXT_extensions_string WGLEW_GET_VAR(__WGLEW_EXT_extensions_string)
+
+#endif /* WGL_EXT_extensions_string */
+
+/* ------------------------ WGL_EXT_framebuffer_sRGB ----------------------- */
+
+#ifndef WGL_EXT_framebuffer_sRGB
+#define WGL_EXT_framebuffer_sRGB 1
+
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
+
+#define WGLEW_EXT_framebuffer_sRGB WGLEW_GET_VAR(__WGLEW_EXT_framebuffer_sRGB)
+
+#endif /* WGL_EXT_framebuffer_sRGB */
+
+/* ----------------------- WGL_EXT_make_current_read ----------------------- */
+
+#ifndef WGL_EXT_make_current_read
+#define WGL_EXT_make_current_read 1
+
+#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
+
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (VOID);
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+
+#define wglGetCurrentReadDCEXT WGLEW_GET_FUN(__wglewGetCurrentReadDCEXT)
+#define wglMakeContextCurrentEXT WGLEW_GET_FUN(__wglewMakeContextCurrentEXT)
+
+#define WGLEW_EXT_make_current_read WGLEW_GET_VAR(__WGLEW_EXT_make_current_read)
+
+#endif /* WGL_EXT_make_current_read */
+
+/* -------------------------- WGL_EXT_multisample -------------------------- */
+
+#ifndef WGL_EXT_multisample
+#define WGL_EXT_multisample 1
+
+#define WGL_SAMPLE_BUFFERS_EXT 0x2041
+#define WGL_SAMPLES_EXT 0x2042
+
+#define WGLEW_EXT_multisample WGLEW_GET_VAR(__WGLEW_EXT_multisample)
+
+#endif /* WGL_EXT_multisample */
+
+/* ---------------------------- WGL_EXT_pbuffer ---------------------------- */
+
+#ifndef WGL_EXT_pbuffer
+#define WGL_EXT_pbuffer 1
+
+#define WGL_DRAW_TO_PBUFFER_EXT 0x202D
+#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
+#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
+#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
+#define WGL_PBUFFER_LARGEST_EXT 0x2033
+#define WGL_PBUFFER_WIDTH_EXT 0x2034
+#define WGL_PBUFFER_HEIGHT_EXT 0x2035
+
+DECLARE_HANDLE(HPBUFFEREXT);
+
+typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int* piAttribList);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int* piValue);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
+
+#define wglCreatePbufferEXT WGLEW_GET_FUN(__wglewCreatePbufferEXT)
+#define wglDestroyPbufferEXT WGLEW_GET_FUN(__wglewDestroyPbufferEXT)
+#define wglGetPbufferDCEXT WGLEW_GET_FUN(__wglewGetPbufferDCEXT)
+#define wglQueryPbufferEXT WGLEW_GET_FUN(__wglewQueryPbufferEXT)
+#define wglReleasePbufferDCEXT WGLEW_GET_FUN(__wglewReleasePbufferDCEXT)
+
+#define WGLEW_EXT_pbuffer WGLEW_GET_VAR(__WGLEW_EXT_pbuffer)
+
+#endif /* WGL_EXT_pbuffer */
+
+/* -------------------------- WGL_EXT_pixel_format ------------------------- */
+
+#ifndef WGL_EXT_pixel_format
+#define WGL_EXT_pixel_format 1
+
+#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
+#define WGL_DRAW_TO_WINDOW_EXT 0x2001
+#define WGL_DRAW_TO_BITMAP_EXT 0x2002
+#define WGL_ACCELERATION_EXT 0x2003
+#define WGL_NEED_PALETTE_EXT 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
+#define WGL_SWAP_METHOD_EXT 0x2007
+#define WGL_NUMBER_OVERLAYS_EXT 0x2008
+#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
+#define WGL_TRANSPARENT_EXT 0x200A
+#define WGL_TRANSPARENT_VALUE_EXT 0x200B
+#define WGL_SHARE_DEPTH_EXT 0x200C
+#define WGL_SHARE_STENCIL_EXT 0x200D
+#define WGL_SHARE_ACCUM_EXT 0x200E
+#define WGL_SUPPORT_GDI_EXT 0x200F
+#define WGL_SUPPORT_OPENGL_EXT 0x2010
+#define WGL_DOUBLE_BUFFER_EXT 0x2011
+#define WGL_STEREO_EXT 0x2012
+#define WGL_PIXEL_TYPE_EXT 0x2013
+#define WGL_COLOR_BITS_EXT 0x2014
+#define WGL_RED_BITS_EXT 0x2015
+#define WGL_RED_SHIFT_EXT 0x2016
+#define WGL_GREEN_BITS_EXT 0x2017
+#define WGL_GREEN_SHIFT_EXT 0x2018
+#define WGL_BLUE_BITS_EXT 0x2019
+#define WGL_BLUE_SHIFT_EXT 0x201A
+#define WGL_ALPHA_BITS_EXT 0x201B
+#define WGL_ALPHA_SHIFT_EXT 0x201C
+#define WGL_ACCUM_BITS_EXT 0x201D
+#define WGL_ACCUM_RED_BITS_EXT 0x201E
+#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
+#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
+#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
+#define WGL_DEPTH_BITS_EXT 0x2022
+#define WGL_STENCIL_BITS_EXT 0x2023
+#define WGL_AUX_BUFFERS_EXT 0x2024
+#define WGL_NO_ACCELERATION_EXT 0x2025
+#define WGL_GENERIC_ACCELERATION_EXT 0x2026
+#define WGL_FULL_ACCELERATION_EXT 0x2027
+#define WGL_SWAP_EXCHANGE_EXT 0x2028
+#define WGL_SWAP_COPY_EXT 0x2029
+#define WGL_SWAP_UNDEFINED_EXT 0x202A
+#define WGL_TYPE_RGBA_EXT 0x202B
+#define WGL_TYPE_COLORINDEX_EXT 0x202C
+
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues);
+
+#define wglChoosePixelFormatEXT WGLEW_GET_FUN(__wglewChoosePixelFormatEXT)
+#define wglGetPixelFormatAttribfvEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribfvEXT)
+#define wglGetPixelFormatAttribivEXT WGLEW_GET_FUN(__wglewGetPixelFormatAttribivEXT)
+
+#define WGLEW_EXT_pixel_format WGLEW_GET_VAR(__WGLEW_EXT_pixel_format)
+
+#endif /* WGL_EXT_pixel_format */
+
+/* ------------------- WGL_EXT_pixel_format_packed_float ------------------- */
+
+#ifndef WGL_EXT_pixel_format_packed_float
+#define WGL_EXT_pixel_format_packed_float 1
+
+#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
+
+#define WGLEW_EXT_pixel_format_packed_float WGLEW_GET_VAR(__WGLEW_EXT_pixel_format_packed_float)
+
+#endif /* WGL_EXT_pixel_format_packed_float */
+
+/* -------------------------- WGL_EXT_swap_control ------------------------- */
+
+#ifndef WGL_EXT_swap_control
+#define WGL_EXT_swap_control 1
+
+typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
+typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
+
+#define wglGetSwapIntervalEXT WGLEW_GET_FUN(__wglewGetSwapIntervalEXT)
+#define wglSwapIntervalEXT WGLEW_GET_FUN(__wglewSwapIntervalEXT)
+
+#define WGLEW_EXT_swap_control WGLEW_GET_VAR(__WGLEW_EXT_swap_control)
+
+#endif /* WGL_EXT_swap_control */
+
+/* ----------------------- WGL_EXT_swap_control_tear ----------------------- */
+
+#ifndef WGL_EXT_swap_control_tear
+#define WGL_EXT_swap_control_tear 1
+
+#define WGLEW_EXT_swap_control_tear WGLEW_GET_VAR(__WGLEW_EXT_swap_control_tear)
+
+#endif /* WGL_EXT_swap_control_tear */
+
+/* --------------------- WGL_I3D_digital_video_control --------------------- */
+
+#ifndef WGL_I3D_digital_video_control
+#define WGL_I3D_digital_video_control 1
+
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
+#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
+#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
+
+typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue);
+typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue);
+
+#define wglGetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewGetDigitalVideoParametersI3D)
+#define wglSetDigitalVideoParametersI3D WGLEW_GET_FUN(__wglewSetDigitalVideoParametersI3D)
+
+#define WGLEW_I3D_digital_video_control WGLEW_GET_VAR(__WGLEW_I3D_digital_video_control)
+
+#endif /* WGL_I3D_digital_video_control */
+
+/* ----------------------------- WGL_I3D_gamma ----------------------------- */
+
+#ifndef WGL_I3D_gamma
+#define WGL_I3D_gamma 1
+
+#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
+#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
+
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT* puRed, USHORT *puGreen, USHORT *puBlue);
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int* piValue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT* puRed, const USHORT *puGreen, const USHORT *puBlue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int* piValue);
+
+#define wglGetGammaTableI3D WGLEW_GET_FUN(__wglewGetGammaTableI3D)
+#define wglGetGammaTableParametersI3D WGLEW_GET_FUN(__wglewGetGammaTableParametersI3D)
+#define wglSetGammaTableI3D WGLEW_GET_FUN(__wglewSetGammaTableI3D)
+#define wglSetGammaTableParametersI3D WGLEW_GET_FUN(__wglewSetGammaTableParametersI3D)
+
+#define WGLEW_I3D_gamma WGLEW_GET_VAR(__WGLEW_I3D_gamma)
+
+#endif /* WGL_I3D_gamma */
+
+/* ---------------------------- WGL_I3D_genlock ---------------------------- */
+
+#ifndef WGL_I3D_genlock
+#define WGL_I3D_genlock 1
+
+#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
+#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045
+#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046
+#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047
+#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
+#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
+#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
+#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
+#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
+
+typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT* uRate);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT* uDelay);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT* uEdge);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT* uSource);
+typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL* pFlag);
+typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT* uMaxLineDelay, UINT *uMaxPixelDelay);
+
+#define wglDisableGenlockI3D WGLEW_GET_FUN(__wglewDisableGenlockI3D)
+#define wglEnableGenlockI3D WGLEW_GET_FUN(__wglewEnableGenlockI3D)
+#define wglGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGenlockSampleRateI3D)
+#define wglGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGenlockSourceDelayI3D)
+#define wglGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGenlockSourceEdgeI3D)
+#define wglGenlockSourceI3D WGLEW_GET_FUN(__wglewGenlockSourceI3D)
+#define wglGetGenlockSampleRateI3D WGLEW_GET_FUN(__wglewGetGenlockSampleRateI3D)
+#define wglGetGenlockSourceDelayI3D WGLEW_GET_FUN(__wglewGetGenlockSourceDelayI3D)
+#define wglGetGenlockSourceEdgeI3D WGLEW_GET_FUN(__wglewGetGenlockSourceEdgeI3D)
+#define wglGetGenlockSourceI3D WGLEW_GET_FUN(__wglewGetGenlockSourceI3D)
+#define wglIsEnabledGenlockI3D WGLEW_GET_FUN(__wglewIsEnabledGenlockI3D)
+#define wglQueryGenlockMaxSourceDelayI3D WGLEW_GET_FUN(__wglewQueryGenlockMaxSourceDelayI3D)
+
+#define WGLEW_I3D_genlock WGLEW_GET_VAR(__WGLEW_I3D_genlock)
+
+#endif /* WGL_I3D_genlock */
+
+/* -------------------------- WGL_I3D_image_buffer ------------------------- */
+
+#ifndef WGL_I3D_image_buffer
+#define WGL_I3D_image_buffer 1
+
+#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
+#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
+
+typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, HANDLE* pEvent, LPVOID *pAddress, DWORD *pSize, UINT count);
+typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
+typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
+typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hdc, LPVOID* pAddress, UINT count);
+
+#define wglAssociateImageBufferEventsI3D WGLEW_GET_FUN(__wglewAssociateImageBufferEventsI3D)
+#define wglCreateImageBufferI3D WGLEW_GET_FUN(__wglewCreateImageBufferI3D)
+#define wglDestroyImageBufferI3D WGLEW_GET_FUN(__wglewDestroyImageBufferI3D)
+#define wglReleaseImageBufferEventsI3D WGLEW_GET_FUN(__wglewReleaseImageBufferEventsI3D)
+
+#define WGLEW_I3D_image_buffer WGLEW_GET_VAR(__WGLEW_I3D_image_buffer)
+
+#endif /* WGL_I3D_image_buffer */
+
+/* ------------------------ WGL_I3D_swap_frame_lock ------------------------ */
+
+#ifndef WGL_I3D_swap_frame_lock
+#define WGL_I3D_swap_frame_lock 1
+
+typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (VOID);
+typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (VOID);
+typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL* pFlag);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL* pFlag);
+
+#define wglDisableFrameLockI3D WGLEW_GET_FUN(__wglewDisableFrameLockI3D)
+#define wglEnableFrameLockI3D WGLEW_GET_FUN(__wglewEnableFrameLockI3D)
+#define wglIsEnabledFrameLockI3D WGLEW_GET_FUN(__wglewIsEnabledFrameLockI3D)
+#define wglQueryFrameLockMasterI3D WGLEW_GET_FUN(__wglewQueryFrameLockMasterI3D)
+
+#define WGLEW_I3D_swap_frame_lock WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_lock)
+
+#endif /* WGL_I3D_swap_frame_lock */
+
+/* ------------------------ WGL_I3D_swap_frame_usage ----------------------- */
+
+#ifndef WGL_I3D_swap_frame_usage
+#define WGL_I3D_swap_frame_usage 1
+
+typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float* pUsage);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD* pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
+
+#define wglBeginFrameTrackingI3D WGLEW_GET_FUN(__wglewBeginFrameTrackingI3D)
+#define wglEndFrameTrackingI3D WGLEW_GET_FUN(__wglewEndFrameTrackingI3D)
+#define wglGetFrameUsageI3D WGLEW_GET_FUN(__wglewGetFrameUsageI3D)
+#define wglQueryFrameTrackingI3D WGLEW_GET_FUN(__wglewQueryFrameTrackingI3D)
+
+#define WGLEW_I3D_swap_frame_usage WGLEW_GET_VAR(__WGLEW_I3D_swap_frame_usage)
+
+#endif /* WGL_I3D_swap_frame_usage */
+
+/* --------------------------- WGL_NV_DX_interop --------------------------- */
+
+#ifndef WGL_NV_DX_interop
+#define WGL_NV_DX_interop 1
+
+#define WGL_ACCESS_READ_ONLY_NV 0x0000
+#define WGL_ACCESS_READ_WRITE_NV 0x0001
+#define WGL_ACCESS_WRITE_DISCARD_NV 0x0002
+
+typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice);
+typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects);
+typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access);
+typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void* dxDevice);
+typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void* dxObject, GLuint name, GLenum type, GLenum access);
+typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void* dxObject, HANDLE shareHandle);
+typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects);
+typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject);
+
+#define wglDXCloseDeviceNV WGLEW_GET_FUN(__wglewDXCloseDeviceNV)
+#define wglDXLockObjectsNV WGLEW_GET_FUN(__wglewDXLockObjectsNV)
+#define wglDXObjectAccessNV WGLEW_GET_FUN(__wglewDXObjectAccessNV)
+#define wglDXOpenDeviceNV WGLEW_GET_FUN(__wglewDXOpenDeviceNV)
+#define wglDXRegisterObjectNV WGLEW_GET_FUN(__wglewDXRegisterObjectNV)
+#define wglDXSetResourceShareHandleNV WGLEW_GET_FUN(__wglewDXSetResourceShareHandleNV)
+#define wglDXUnlockObjectsNV WGLEW_GET_FUN(__wglewDXUnlockObjectsNV)
+#define wglDXUnregisterObjectNV WGLEW_GET_FUN(__wglewDXUnregisterObjectNV)
+
+#define WGLEW_NV_DX_interop WGLEW_GET_VAR(__WGLEW_NV_DX_interop)
+
+#endif /* WGL_NV_DX_interop */
+
+/* --------------------------- WGL_NV_DX_interop2 -------------------------- */
+
+#ifndef WGL_NV_DX_interop2
+#define WGL_NV_DX_interop2 1
+
+#define WGLEW_NV_DX_interop2 WGLEW_GET_VAR(__WGLEW_NV_DX_interop2)
+
+#endif /* WGL_NV_DX_interop2 */
+
+/* --------------------------- WGL_NV_copy_image --------------------------- */
+
+#ifndef WGL_NV_copy_image
+#define WGL_NV_copy_image 1
+
+typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+
+#define wglCopyImageSubDataNV WGLEW_GET_FUN(__wglewCopyImageSubDataNV)
+
+#define WGLEW_NV_copy_image WGLEW_GET_VAR(__WGLEW_NV_copy_image)
+
+#endif /* WGL_NV_copy_image */
+
+/* -------------------------- WGL_NV_float_buffer -------------------------- */
+
+#ifndef WGL_NV_float_buffer
+#define WGL_NV_float_buffer 1
+
+#define WGL_FLOAT_COMPONENTS_NV 0x20B0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
+#define WGL_TEXTURE_FLOAT_R_NV 0x20B5
+#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6
+#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
+#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
+
+#define WGLEW_NV_float_buffer WGLEW_GET_VAR(__WGLEW_NV_float_buffer)
+
+#endif /* WGL_NV_float_buffer */
+
+/* -------------------------- WGL_NV_gpu_affinity -------------------------- */
+
+#ifndef WGL_NV_gpu_affinity
+#define WGL_NV_gpu_affinity 1
+
+#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0
+#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1
+
+DECLARE_HANDLE(HGPUNV);
+typedef struct _GPU_DEVICE {
+ DWORD cb;
+ CHAR DeviceName[32];
+ CHAR DeviceString[128];
+ DWORD Flags;
+ RECT rcVirtualScreen;
+} GPU_DEVICE, *PGPU_DEVICE;
+
+typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList);
+typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc);
+typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
+typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
+typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu);
+
+#define wglCreateAffinityDCNV WGLEW_GET_FUN(__wglewCreateAffinityDCNV)
+#define wglDeleteDCNV WGLEW_GET_FUN(__wglewDeleteDCNV)
+#define wglEnumGpuDevicesNV WGLEW_GET_FUN(__wglewEnumGpuDevicesNV)
+#define wglEnumGpusFromAffinityDCNV WGLEW_GET_FUN(__wglewEnumGpusFromAffinityDCNV)
+#define wglEnumGpusNV WGLEW_GET_FUN(__wglewEnumGpusNV)
+
+#define WGLEW_NV_gpu_affinity WGLEW_GET_VAR(__WGLEW_NV_gpu_affinity)
+
+#endif /* WGL_NV_gpu_affinity */
+
+/* ---------------------- WGL_NV_multisample_coverage ---------------------- */
+
+#ifndef WGL_NV_multisample_coverage
+#define WGL_NV_multisample_coverage 1
+
+#define WGL_COVERAGE_SAMPLES_NV 0x2042
+#define WGL_COLOR_SAMPLES_NV 0x20B9
+
+#define WGLEW_NV_multisample_coverage WGLEW_GET_VAR(__WGLEW_NV_multisample_coverage)
+
+#endif /* WGL_NV_multisample_coverage */
+
+/* -------------------------- WGL_NV_present_video ------------------------- */
+
+#ifndef WGL_NV_present_video
+#define WGL_NV_present_video 1
+
+#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0
+
+DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
+
+typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDc, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int* piAttribList);
+typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDc, HVIDEOOUTPUTDEVICENV* phDeviceList);
+typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int* piValue);
+
+#define wglBindVideoDeviceNV WGLEW_GET_FUN(__wglewBindVideoDeviceNV)
+#define wglEnumerateVideoDevicesNV WGLEW_GET_FUN(__wglewEnumerateVideoDevicesNV)
+#define wglQueryCurrentContextNV WGLEW_GET_FUN(__wglewQueryCurrentContextNV)
+
+#define WGLEW_NV_present_video WGLEW_GET_VAR(__WGLEW_NV_present_video)
+
+#endif /* WGL_NV_present_video */
+
+/* ---------------------- WGL_NV_render_depth_texture ---------------------- */
+
+#ifndef WGL_NV_render_depth_texture
+#define WGL_NV_render_depth_texture 1
+
+#define WGL_NO_TEXTURE_ARB 0x2077
+#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
+#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
+#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
+#define WGL_DEPTH_COMPONENT_NV 0x20A7
+
+#define WGLEW_NV_render_depth_texture WGLEW_GET_VAR(__WGLEW_NV_render_depth_texture)
+
+#endif /* WGL_NV_render_depth_texture */
+
+/* -------------------- WGL_NV_render_texture_rectangle -------------------- */
+
+#ifndef WGL_NV_render_texture_rectangle
+#define WGL_NV_render_texture_rectangle 1
+
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
+#define WGL_TEXTURE_RECTANGLE_NV 0x20A2
+
+#define WGLEW_NV_render_texture_rectangle WGLEW_GET_VAR(__WGLEW_NV_render_texture_rectangle)
+
+#endif /* WGL_NV_render_texture_rectangle */
+
+/* --------------------------- WGL_NV_swap_group --------------------------- */
+
+#ifndef WGL_NV_swap_group
+#define WGL_NV_swap_group 1
+
+typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
+typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint* count);
+typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint* maxGroups, GLuint *maxBarriers);
+typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint* group, GLuint *barrier);
+typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
+
+#define wglBindSwapBarrierNV WGLEW_GET_FUN(__wglewBindSwapBarrierNV)
+#define wglJoinSwapGroupNV WGLEW_GET_FUN(__wglewJoinSwapGroupNV)
+#define wglQueryFrameCountNV WGLEW_GET_FUN(__wglewQueryFrameCountNV)
+#define wglQueryMaxSwapGroupsNV WGLEW_GET_FUN(__wglewQueryMaxSwapGroupsNV)
+#define wglQuerySwapGroupNV WGLEW_GET_FUN(__wglewQuerySwapGroupNV)
+#define wglResetFrameCountNV WGLEW_GET_FUN(__wglewResetFrameCountNV)
+
+#define WGLEW_NV_swap_group WGLEW_GET_VAR(__WGLEW_NV_swap_group)
+
+#endif /* WGL_NV_swap_group */
+
+/* ----------------------- WGL_NV_vertex_array_range ----------------------- */
+
+#ifndef WGL_NV_vertex_array_range
+#define WGL_NV_vertex_array_range 1
+
+typedef void * (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readFrequency, GLfloat writeFrequency, GLfloat priority);
+typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
+
+#define wglAllocateMemoryNV WGLEW_GET_FUN(__wglewAllocateMemoryNV)
+#define wglFreeMemoryNV WGLEW_GET_FUN(__wglewFreeMemoryNV)
+
+#define WGLEW_NV_vertex_array_range WGLEW_GET_VAR(__WGLEW_NV_vertex_array_range)
+
+#endif /* WGL_NV_vertex_array_range */
+
+/* -------------------------- WGL_NV_video_capture ------------------------- */
+
+#ifndef WGL_NV_video_capture
+#define WGL_NV_video_capture 1
+
+#define WGL_UNIQUE_ID_NV 0x20CE
+#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
+
+DECLARE_HANDLE(HVIDEOINPUTDEVICENV);
+
+typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
+typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV* phDeviceList);
+typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int* piValue);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+
+#define wglBindVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewBindVideoCaptureDeviceNV)
+#define wglEnumerateVideoCaptureDevicesNV WGLEW_GET_FUN(__wglewEnumerateVideoCaptureDevicesNV)
+#define wglLockVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewLockVideoCaptureDeviceNV)
+#define wglQueryVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewQueryVideoCaptureDeviceNV)
+#define wglReleaseVideoCaptureDeviceNV WGLEW_GET_FUN(__wglewReleaseVideoCaptureDeviceNV)
+
+#define WGLEW_NV_video_capture WGLEW_GET_VAR(__WGLEW_NV_video_capture)
+
+#endif /* WGL_NV_video_capture */
+
+/* -------------------------- WGL_NV_video_output -------------------------- */
+
+#ifndef WGL_NV_video_output
+#define WGL_NV_video_output 1
+
+#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0
+#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1
+#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
+#define WGL_VIDEO_OUT_COLOR_NV 0x20C3
+#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4
+#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5
+#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
+#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
+#define WGL_VIDEO_OUT_FRAME 0x20C8
+#define WGL_VIDEO_OUT_FIELD_1 0x20C9
+#define WGL_VIDEO_OUT_FIELD_2 0x20CA
+#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
+#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
+
+DECLARE_HANDLE(HPVIDEODEV);
+
+typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
+typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV* hVideoDevice);
+typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long* pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer);
+typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long* pulCounterPbuffer, BOOL bBlock);
+
+#define wglBindVideoImageNV WGLEW_GET_FUN(__wglewBindVideoImageNV)
+#define wglGetVideoDeviceNV WGLEW_GET_FUN(__wglewGetVideoDeviceNV)
+#define wglGetVideoInfoNV WGLEW_GET_FUN(__wglewGetVideoInfoNV)
+#define wglReleaseVideoDeviceNV WGLEW_GET_FUN(__wglewReleaseVideoDeviceNV)
+#define wglReleaseVideoImageNV WGLEW_GET_FUN(__wglewReleaseVideoImageNV)
+#define wglSendPbufferToVideoNV WGLEW_GET_FUN(__wglewSendPbufferToVideoNV)
+
+#define WGLEW_NV_video_output WGLEW_GET_VAR(__WGLEW_NV_video_output)
+
+#endif /* WGL_NV_video_output */
+
+/* -------------------------- WGL_OML_sync_control ------------------------- */
+
+#ifndef WGL_OML_sync_control
+#define WGL_OML_sync_control 1
+
+typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32* numerator, INT32 *denominator);
+typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64* ust, INT64 *msc, INT64 *sbc);
+typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, INT fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64* ust, INT64 *msc, INT64 *sbc);
+typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64* ust, INT64 *msc, INT64 *sbc);
+
+#define wglGetMscRateOML WGLEW_GET_FUN(__wglewGetMscRateOML)
+#define wglGetSyncValuesOML WGLEW_GET_FUN(__wglewGetSyncValuesOML)
+#define wglSwapBuffersMscOML WGLEW_GET_FUN(__wglewSwapBuffersMscOML)
+#define wglSwapLayerBuffersMscOML WGLEW_GET_FUN(__wglewSwapLayerBuffersMscOML)
+#define wglWaitForMscOML WGLEW_GET_FUN(__wglewWaitForMscOML)
+#define wglWaitForSbcOML WGLEW_GET_FUN(__wglewWaitForSbcOML)
+
+#define WGLEW_OML_sync_control WGLEW_GET_VAR(__WGLEW_OML_sync_control)
+
+#endif /* WGL_OML_sync_control */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef GLEW_MX
+#define WGLEW_FUN_EXPORT
+#define WGLEW_VAR_EXPORT
+#else
+#define WGLEW_FUN_EXPORT GLEW_FUN_EXPORT
+#define WGLEW_VAR_EXPORT GLEW_VAR_EXPORT
+#endif /* GLEW_MX */
+
+#ifdef GLEW_MX
+struct WGLEWContextStruct
+{
+#endif /* GLEW_MX */
+
+WGLEW_FUN_EXPORT PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL;
+
+WGLEW_FUN_EXPORT PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC __wglewBlitContextFramebufferAMD;
+WGLEW_FUN_EXPORT PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC __wglewCreateAssociatedContextAMD;
+WGLEW_FUN_EXPORT PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __wglewCreateAssociatedContextAttribsAMD;
+WGLEW_FUN_EXPORT PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC __wglewDeleteAssociatedContextAMD;
+WGLEW_FUN_EXPORT PFNWGLGETCONTEXTGPUIDAMDPROC __wglewGetContextGPUIDAMD;
+WGLEW_FUN_EXPORT PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC __wglewGetCurrentAssociatedContextAMD;
+WGLEW_FUN_EXPORT PFNWGLGETGPUIDSAMDPROC __wglewGetGPUIDsAMD;
+WGLEW_FUN_EXPORT PFNWGLGETGPUINFOAMDPROC __wglewGetGPUInfoAMD;
+WGLEW_FUN_EXPORT PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __wglewMakeAssociatedContextCurrentAMD;
+
+WGLEW_FUN_EXPORT PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB;
+WGLEW_FUN_EXPORT PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB;
+WGLEW_FUN_EXPORT PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB;
+WGLEW_FUN_EXPORT PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB;
+
+WGLEW_FUN_EXPORT PFNWGLCREATECONTEXTATTRIBSARBPROC __wglewCreateContextAttribsARB;
+
+WGLEW_FUN_EXPORT PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB;
+
+WGLEW_FUN_EXPORT PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB;
+WGLEW_FUN_EXPORT PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB;
+
+WGLEW_FUN_EXPORT PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB;
+WGLEW_FUN_EXPORT PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB;
+WGLEW_FUN_EXPORT PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB;
+WGLEW_FUN_EXPORT PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB;
+WGLEW_FUN_EXPORT PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB;
+
+WGLEW_FUN_EXPORT PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB;
+WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB;
+WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB;
+
+WGLEW_FUN_EXPORT PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB;
+WGLEW_FUN_EXPORT PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB;
+WGLEW_FUN_EXPORT PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB;
+
+WGLEW_FUN_EXPORT PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT;
+WGLEW_FUN_EXPORT PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT;
+WGLEW_FUN_EXPORT PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT;
+WGLEW_FUN_EXPORT PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT;
+
+WGLEW_FUN_EXPORT PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT;
+
+WGLEW_FUN_EXPORT PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT;
+WGLEW_FUN_EXPORT PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT;
+
+WGLEW_FUN_EXPORT PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT;
+WGLEW_FUN_EXPORT PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT;
+WGLEW_FUN_EXPORT PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT;
+WGLEW_FUN_EXPORT PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT;
+WGLEW_FUN_EXPORT PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT;
+
+WGLEW_FUN_EXPORT PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT;
+WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT;
+WGLEW_FUN_EXPORT PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT;
+
+WGLEW_FUN_EXPORT PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT;
+WGLEW_FUN_EXPORT PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT;
+
+WGLEW_FUN_EXPORT PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D;
+WGLEW_FUN_EXPORT PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D;
+
+WGLEW_FUN_EXPORT PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D;
+WGLEW_FUN_EXPORT PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D;
+WGLEW_FUN_EXPORT PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D;
+WGLEW_FUN_EXPORT PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D;
+
+WGLEW_FUN_EXPORT PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D;
+WGLEW_FUN_EXPORT PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D;
+WGLEW_FUN_EXPORT PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D;
+WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D;
+WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D;
+WGLEW_FUN_EXPORT PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D;
+WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D;
+WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D;
+WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D;
+WGLEW_FUN_EXPORT PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D;
+WGLEW_FUN_EXPORT PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D;
+WGLEW_FUN_EXPORT PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D;
+
+WGLEW_FUN_EXPORT PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D;
+WGLEW_FUN_EXPORT PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D;
+WGLEW_FUN_EXPORT PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D;
+WGLEW_FUN_EXPORT PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D;
+
+WGLEW_FUN_EXPORT PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D;
+WGLEW_FUN_EXPORT PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D;
+WGLEW_FUN_EXPORT PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D;
+WGLEW_FUN_EXPORT PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D;
+
+WGLEW_FUN_EXPORT PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D;
+WGLEW_FUN_EXPORT PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D;
+WGLEW_FUN_EXPORT PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D;
+WGLEW_FUN_EXPORT PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D;
+
+WGLEW_FUN_EXPORT PFNWGLDXCLOSEDEVICENVPROC __wglewDXCloseDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLDXLOCKOBJECTSNVPROC __wglewDXLockObjectsNV;
+WGLEW_FUN_EXPORT PFNWGLDXOBJECTACCESSNVPROC __wglewDXObjectAccessNV;
+WGLEW_FUN_EXPORT PFNWGLDXOPENDEVICENVPROC __wglewDXOpenDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLDXREGISTEROBJECTNVPROC __wglewDXRegisterObjectNV;
+WGLEW_FUN_EXPORT PFNWGLDXSETRESOURCESHAREHANDLENVPROC __wglewDXSetResourceShareHandleNV;
+WGLEW_FUN_EXPORT PFNWGLDXUNLOCKOBJECTSNVPROC __wglewDXUnlockObjectsNV;
+WGLEW_FUN_EXPORT PFNWGLDXUNREGISTEROBJECTNVPROC __wglewDXUnregisterObjectNV;
+
+WGLEW_FUN_EXPORT PFNWGLCOPYIMAGESUBDATANVPROC __wglewCopyImageSubDataNV;
+
+WGLEW_FUN_EXPORT PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV;
+WGLEW_FUN_EXPORT PFNWGLDELETEDCNVPROC __wglewDeleteDCNV;
+WGLEW_FUN_EXPORT PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV;
+WGLEW_FUN_EXPORT PFNWGLENUMGPUSFROMAFFINITYDCNVPROC __wglewEnumGpusFromAffinityDCNV;
+WGLEW_FUN_EXPORT PFNWGLENUMGPUSNVPROC __wglewEnumGpusNV;
+
+WGLEW_FUN_EXPORT PFNWGLBINDVIDEODEVICENVPROC __wglewBindVideoDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLENUMERATEVIDEODEVICESNVPROC __wglewEnumerateVideoDevicesNV;
+WGLEW_FUN_EXPORT PFNWGLQUERYCURRENTCONTEXTNVPROC __wglewQueryCurrentContextNV;
+
+WGLEW_FUN_EXPORT PFNWGLBINDSWAPBARRIERNVPROC __wglewBindSwapBarrierNV;
+WGLEW_FUN_EXPORT PFNWGLJOINSWAPGROUPNVPROC __wglewJoinSwapGroupNV;
+WGLEW_FUN_EXPORT PFNWGLQUERYFRAMECOUNTNVPROC __wglewQueryFrameCountNV;
+WGLEW_FUN_EXPORT PFNWGLQUERYMAXSWAPGROUPSNVPROC __wglewQueryMaxSwapGroupsNV;
+WGLEW_FUN_EXPORT PFNWGLQUERYSWAPGROUPNVPROC __wglewQuerySwapGroupNV;
+WGLEW_FUN_EXPORT PFNWGLRESETFRAMECOUNTNVPROC __wglewResetFrameCountNV;
+
+WGLEW_FUN_EXPORT PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV;
+WGLEW_FUN_EXPORT PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV;
+
+WGLEW_FUN_EXPORT PFNWGLBINDVIDEOCAPTUREDEVICENVPROC __wglewBindVideoCaptureDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC __wglewEnumerateVideoCaptureDevicesNV;
+WGLEW_FUN_EXPORT PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC __wglewLockVideoCaptureDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC __wglewQueryVideoCaptureDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC __wglewReleaseVideoCaptureDeviceNV;
+
+WGLEW_FUN_EXPORT PFNWGLBINDVIDEOIMAGENVPROC __wglewBindVideoImageNV;
+WGLEW_FUN_EXPORT PFNWGLGETVIDEODEVICENVPROC __wglewGetVideoDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLGETVIDEOINFONVPROC __wglewGetVideoInfoNV;
+WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEODEVICENVPROC __wglewReleaseVideoDeviceNV;
+WGLEW_FUN_EXPORT PFNWGLRELEASEVIDEOIMAGENVPROC __wglewReleaseVideoImageNV;
+WGLEW_FUN_EXPORT PFNWGLSENDPBUFFERTOVIDEONVPROC __wglewSendPbufferToVideoNV;
+
+WGLEW_FUN_EXPORT PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML;
+WGLEW_FUN_EXPORT PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML;
+WGLEW_FUN_EXPORT PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML;
+WGLEW_FUN_EXPORT PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML;
+WGLEW_FUN_EXPORT PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML;
+WGLEW_FUN_EXPORT PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_3DFX_multisample;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_3DL_stereo_control;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_AMD_gpu_association;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_buffer_region;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context_profile;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_create_context_robustness;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_extensions_string;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_framebuffer_sRGB;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_make_current_read;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_multisample;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pbuffer;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pixel_format;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_pixel_format_float;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_render_texture;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_robustness_application_isolation;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ARB_robustness_share_group_isolation;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ATI_pixel_format_float;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_ATI_render_texture_rectangle;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_create_context_es2_profile;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_create_context_es_profile;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_depth_float;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_display_color_table;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_extensions_string;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_framebuffer_sRGB;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_make_current_read;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_multisample;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pbuffer;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pixel_format;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_pixel_format_packed_float;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_swap_control;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_EXT_swap_control_tear;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_digital_video_control;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_gamma;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_genlock;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_image_buffer;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_swap_frame_lock;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_I3D_swap_frame_usage;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_DX_interop;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_DX_interop2;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_copy_image;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_float_buffer;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_gpu_affinity;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_multisample_coverage;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_present_video;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_render_depth_texture;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_render_texture_rectangle;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_swap_group;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_vertex_array_range;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_video_capture;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_NV_video_output;
+WGLEW_VAR_EXPORT GLboolean __WGLEW_OML_sync_control;
+
+#ifdef GLEW_MX
+}; /* WGLEWContextStruct */
+#endif /* GLEW_MX */
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef GLEW_MX
+
+typedef struct WGLEWContextStruct WGLEWContext;
+GLEWAPI GLenum GLEWAPIENTRY wglewContextInit (WGLEWContext *ctx);
+GLEWAPI GLboolean GLEWAPIENTRY wglewContextIsSupported (const WGLEWContext *ctx, const char *name);
+
+#define wglewInit() wglewContextInit(wglewGetContext())
+#define wglewIsSupported(x) wglewContextIsSupported(wglewGetContext(), x)
+
+#define WGLEW_GET_VAR(x) (*(const GLboolean*)&(wglewGetContext()->x))
+#define WGLEW_GET_FUN(x) wglewGetContext()->x
+
+#else /* GLEW_MX */
+
+#define WGLEW_GET_VAR(x) (*(const GLboolean*)&x)
+#define WGLEW_GET_FUN(x) x
+
+GLEWAPI GLboolean GLEWAPIENTRY wglewIsSupported (const char *name);
+
+#endif /* GLEW_MX */
+
+GLEWAPI GLboolean GLEWAPIENTRY wglewGetExtension (const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#undef GLEWAPI
+
+#endif /* __wglew_h__ */
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/glew.c b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/glew.c
new file mode 100644
index 0000000000..1be61489e0
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/Glew/glew.c
@@ -0,0 +1,18897 @@
+/*
+** The OpenGL Extension Wrangler Library
+** Copyright (C) 2002-2008, Milan Ikits <milan ikits[]ieee org>
+** Copyright (C) 2002-2008, Marcelo E. Magallon <mmagallo[]debian org>
+** Copyright (C) 2002, Lev Povalahev
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** * The name of the author may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+** THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "CustomGL/glew.h"
+
+#if defined(_WIN32)
+# include <CustomGL/wglew.h>
+#elif !defined(__ANDROID__) && !defined(__native_client__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX))
+# include "CustomGL/glxew.h"
+
+#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void* dlglXGetProcAddressARB(const GLubyte* name)
+{
+ static void* h = NULL;
+ static void* gpa;
+
+ if (h == NULL)
+ {
+ if ((h = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL)) == NULL)
+ {
+ return NULL;
+ }
+ gpa = dlsym(h, "glXGetProcAddressARB");
+ }
+
+ if (gpa != NULL)
+ return ((void*(*)(const GLubyte*))gpa)(name);
+ else
+ return dlsym(h, (const char*)name);
+}
+
+
+
+#endif //GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+
+#endif
+
+/*
+ * Define glewGetContext and related helper macros.
+ */
+#ifdef GLEW_MX
+# define glewGetContext() ctx
+# ifdef _WIN32
+# define GLEW_CONTEXT_ARG_DEF_INIT GLEWContext* ctx
+# define GLEW_CONTEXT_ARG_VAR_INIT ctx
+# define wglewGetContext() ctx
+# define WGLEW_CONTEXT_ARG_DEF_INIT WGLEWContext* ctx
+# define WGLEW_CONTEXT_ARG_DEF_LIST WGLEWContext* ctx
+# else /* _WIN32 */
+# define GLEW_CONTEXT_ARG_DEF_INIT void
+# define GLEW_CONTEXT_ARG_VAR_INIT
+# define glxewGetContext() ctx
+# define GLXEW_CONTEXT_ARG_DEF_INIT void
+# define GLXEW_CONTEXT_ARG_DEF_LIST GLXEWContext* ctx
+# endif /* _WIN32 */
+# define GLEW_CONTEXT_ARG_DEF_LIST GLEWContext* ctx
+#else /* GLEW_MX */
+# define GLEW_CONTEXT_ARG_DEF_INIT void
+# define GLEW_CONTEXT_ARG_VAR_INIT
+# define GLEW_CONTEXT_ARG_DEF_LIST void
+# define WGLEW_CONTEXT_ARG_DEF_INIT void
+# define WGLEW_CONTEXT_ARG_DEF_LIST void
+# define GLXEW_CONTEXT_ARG_DEF_INIT void
+# define GLXEW_CONTEXT_ARG_DEF_LIST void
+#endif /* GLEW_MX */
+
+#if defined(__sgi) || defined (__sun) || defined(GLEW_APPLE_GLX)
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void* dlGetProcAddress (const GLubyte* name)
+{
+ static void* h = NULL;
+ static void* gpa;
+
+ if (h == NULL)
+ {
+ if ((h = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL)) == NULL) return NULL;
+ gpa = dlsym(h, "glXGetProcAddress");
+ }
+
+ if (gpa != NULL)
+ return ((void*(*)(const GLubyte*))gpa)(name);
+ else
+ return dlsym(h, (const char*)name);
+}
+#endif /* __sgi || __sun || GLEW_APPLE_GLX */
+
+#if defined(__APPLE__)
+#include <stdlib.h>
+#include <string.h>
+#include <AvailabilityMacros.h>
+
+#ifdef MAC_OS_X_VERSION_10_3
+
+#include <dlfcn.h>
+
+void* NSGLGetProcAddress (const GLubyte *name)
+{
+ static void* image = NULL;
+ void* addr;
+ if (NULL == image)
+ {
+#ifdef GLEW_REGAL
+ image = dlopen("libRegal.dylib", RTLD_LAZY);
+#else
+ image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
+#endif
+ }
+ if( !image ) return NULL;
+ addr = dlsym(image, (const char*)name);
+ if( addr ) return addr;
+#ifdef GLEW_APPLE_GLX
+ return dlGetProcAddress( name ); // try next for glx symbols
+#else
+ return NULL;
+#endif
+}
+#else
+
+#include <mach-o/dyld.h>
+
+void* NSGLGetProcAddress (const GLubyte *name)
+{
+ static const struct mach_header* image = NULL;
+ NSSymbol symbol;
+ char* symbolName;
+ if (NULL == image)
+ {
+#ifdef GLEW_REGAL
+ image = NSAddImage("libRegal.dylib", NSADDIMAGE_OPTION_RETURN_ON_ERROR);
+#else
+ image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR);
+#endif
+ }
+ /* prepend a '_' for the Unix C symbol mangling convention */
+ symbolName = malloc(strlen((const char*)name) + 2);
+ strcpy(symbolName+1, (const char*)name);
+ symbolName[0] = '_';
+ symbol = NULL;
+ /* if (NSIsSymbolNameDefined(symbolName))
+ symbol = NSLookupAndBindSymbol(symbolName); */
+ symbol = image ? NSLookupSymbolInImage(image, symbolName, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : NULL;
+ free(symbolName);
+ if( symbol ) return NSAddressOfSymbol(symbol);
+#ifdef GLEW_APPLE_GLX
+ return dlGetProcAddress( name ); // try next for glx symbols
+#else
+ return NULL;
+#endif
+}
+#endif /* MAC_OS_X_VERSION_10_3 */
+#endif /* __APPLE__ */
+
+/*
+ * Define glewGetProcAddress.
+ */
+#if defined(_WIN32)
+# define glewGetProcAddress(name) wglGetProcAddress((LPCSTR)name)
+#elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX)
+# define glewGetProcAddress(name) NSGLGetProcAddress(name)
+#elif defined(__sgi) || defined(__sun)
+# define glewGetProcAddress(name) dlGetProcAddress(name)
+#elif defined(__ANDROID__)
+# define glewGetProcAddress(name) NULL /* TODO */
+#elif defined(__native_client__)
+# define glewGetProcAddress(name) NULL /* TODO */
+#else /* __linux */
+#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+# define glewGetProcAddress(name) dlglXGetProcAddressARB(name)
+#else//GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+# define glewGetProcAddress(name) (*glXGetProcAddressARB)(name)
+#endif//GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+#endif
+
+/*
+ * Define GLboolean const cast.
+ */
+#define CONST_CAST(x) (*(GLboolean*)&x)
+
+/*
+ * GLEW, just like OpenGL or GLU, does not rely on the standard C library.
+ * These functions implement the functionality required in this file.
+ */
+static GLuint _glewStrLen (const GLubyte* s)
+{
+ GLuint i=0;
+ if (s == NULL) return 0;
+ while (s[i] != '\0') i++;
+ return i;
+}
+
+static GLuint _glewStrCLen (const GLubyte* s, GLubyte c)
+{
+ GLuint i=0;
+ if (s == NULL) return 0;
+ while (s[i] != '\0' && s[i] != c) i++;
+ return (s[i] == '\0' || s[i] == c) ? i : 0;
+}
+
+static GLboolean _glewStrSame (const GLubyte* a, const GLubyte* b, GLuint n)
+{
+ GLuint i=0;
+ if(a == NULL || b == NULL)
+ return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE;
+ while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++;
+ return i == n ? GL_TRUE : GL_FALSE;
+}
+
+static GLboolean _glewStrSame1 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb)
+{
+ while (*na > 0 && (**a == ' ' || **a == '\n' || **a == '\r' || **a == '\t'))
+ {
+ (*a)++;
+ (*na)--;
+ }
+ if(*na >= nb)
+ {
+ GLuint i=0;
+ while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++;
+ if(i == nb)
+ {
+ *a = *a + nb;
+ *na = *na - nb;
+ return GL_TRUE;
+ }
+ }
+ return GL_FALSE;
+}
+
+static GLboolean _glewStrSame2 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb)
+{
+ if(*na >= nb)
+ {
+ GLuint i=0;
+ while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++;
+ if(i == nb)
+ {
+ *a = *a + nb;
+ *na = *na - nb;
+ return GL_TRUE;
+ }
+ }
+ return GL_FALSE;
+}
+
+static GLboolean _glewStrSame3 (GLubyte** a, GLuint* na, const GLubyte* b, GLuint nb)
+{
+ if(*na >= nb)
+ {
+ GLuint i=0;
+ while (i < nb && (*a)+i != NULL && b+i != NULL && (*a)[i] == b[i]) i++;
+ if (i == nb && (*na == nb || (*a)[i] == ' ' || (*a)[i] == '\n' || (*a)[i] == '\r' || (*a)[i] == '\t'))
+ {
+ *a = *a + nb;
+ *na = *na - nb;
+ return GL_TRUE;
+ }
+ }
+ return GL_FALSE;
+}
+
+/*
+ * Search for name in the extensions string. Use of strstr()
+ * is not sufficient because extension names can be prefixes of
+ * other extension names. Could use strtok() but the constant
+ * string returned by glGetString might be in read-only memory.
+ */
+static GLboolean _glewSearchExtension (const char* name, const GLubyte *start, const GLubyte *end)
+{
+ const GLubyte* p;
+ GLuint len = _glewStrLen((const GLubyte*)name);
+ p = start;
+ while (p < end)
+ {
+ GLuint n = _glewStrCLen(p, ' ');
+ if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE;
+ p += n+1;
+ }
+ return GL_FALSE;
+}
+
+#if !defined(_WIN32) || !defined(GLEW_MX)
+
+PFNGLCOPYTEXSUBIMAGE3DPROC __glewCopyTexSubImage3D = NULL;
+PFNGLDRAWRANGEELEMENTSPROC __glewDrawRangeElements = NULL;
+PFNGLTEXIMAGE3DPROC __glewTexImage3D = NULL;
+PFNGLTEXSUBIMAGE3DPROC __glewTexSubImage3D = NULL;
+
+PFNGLACTIVETEXTUREPROC __glewActiveTexture = NULL;
+PFNGLCLIENTACTIVETEXTUREPROC __glewClientActiveTexture = NULL;
+PFNGLCOMPRESSEDTEXIMAGE1DPROC __glewCompressedTexImage1D = NULL;
+PFNGLCOMPRESSEDTEXIMAGE2DPROC __glewCompressedTexImage2D = NULL;
+PFNGLCOMPRESSEDTEXIMAGE3DPROC __glewCompressedTexImage3D = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC __glewCompressedTexSubImage1D = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC __glewCompressedTexSubImage2D = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC __glewCompressedTexSubImage3D = NULL;
+PFNGLGETCOMPRESSEDTEXIMAGEPROC __glewGetCompressedTexImage = NULL;
+PFNGLLOADTRANSPOSEMATRIXDPROC __glewLoadTransposeMatrixd = NULL;
+PFNGLLOADTRANSPOSEMATRIXFPROC __glewLoadTransposeMatrixf = NULL;
+PFNGLMULTTRANSPOSEMATRIXDPROC __glewMultTransposeMatrixd = NULL;
+PFNGLMULTTRANSPOSEMATRIXFPROC __glewMultTransposeMatrixf = NULL;
+PFNGLMULTITEXCOORD1DPROC __glewMultiTexCoord1d = NULL;
+PFNGLMULTITEXCOORD1DVPROC __glewMultiTexCoord1dv = NULL;
+PFNGLMULTITEXCOORD1FPROC __glewMultiTexCoord1f = NULL;
+PFNGLMULTITEXCOORD1FVPROC __glewMultiTexCoord1fv = NULL;
+PFNGLMULTITEXCOORD1IPROC __glewMultiTexCoord1i = NULL;
+PFNGLMULTITEXCOORD1IVPROC __glewMultiTexCoord1iv = NULL;
+PFNGLMULTITEXCOORD1SPROC __glewMultiTexCoord1s = NULL;
+PFNGLMULTITEXCOORD1SVPROC __glewMultiTexCoord1sv = NULL;
+PFNGLMULTITEXCOORD2DPROC __glewMultiTexCoord2d = NULL;
+PFNGLMULTITEXCOORD2DVPROC __glewMultiTexCoord2dv = NULL;
+PFNGLMULTITEXCOORD2FPROC __glewMultiTexCoord2f = NULL;
+PFNGLMULTITEXCOORD2FVPROC __glewMultiTexCoord2fv = NULL;
+PFNGLMULTITEXCOORD2IPROC __glewMultiTexCoord2i = NULL;
+PFNGLMULTITEXCOORD2IVPROC __glewMultiTexCoord2iv = NULL;
+PFNGLMULTITEXCOORD2SPROC __glewMultiTexCoord2s = NULL;
+PFNGLMULTITEXCOORD2SVPROC __glewMultiTexCoord2sv = NULL;
+PFNGLMULTITEXCOORD3DPROC __glewMultiTexCoord3d = NULL;
+PFNGLMULTITEXCOORD3DVPROC __glewMultiTexCoord3dv = NULL;
+PFNGLMULTITEXCOORD3FPROC __glewMultiTexCoord3f = NULL;
+PFNGLMULTITEXCOORD3FVPROC __glewMultiTexCoord3fv = NULL;
+PFNGLMULTITEXCOORD3IPROC __glewMultiTexCoord3i = NULL;
+PFNGLMULTITEXCOORD3IVPROC __glewMultiTexCoord3iv = NULL;
+PFNGLMULTITEXCOORD3SPROC __glewMultiTexCoord3s = NULL;
+PFNGLMULTITEXCOORD3SVPROC __glewMultiTexCoord3sv = NULL;
+PFNGLMULTITEXCOORD4DPROC __glewMultiTexCoord4d = NULL;
+PFNGLMULTITEXCOORD4DVPROC __glewMultiTexCoord4dv = NULL;
+PFNGLMULTITEXCOORD4FPROC __glewMultiTexCoord4f = NULL;
+PFNGLMULTITEXCOORD4FVPROC __glewMultiTexCoord4fv = NULL;
+PFNGLMULTITEXCOORD4IPROC __glewMultiTexCoord4i = NULL;
+PFNGLMULTITEXCOORD4IVPROC __glewMultiTexCoord4iv = NULL;
+PFNGLMULTITEXCOORD4SPROC __glewMultiTexCoord4s = NULL;
+PFNGLMULTITEXCOORD4SVPROC __glewMultiTexCoord4sv = NULL;
+PFNGLSAMPLECOVERAGEPROC __glewSampleCoverage = NULL;
+
+PFNGLBLENDCOLORPROC __glewBlendColor = NULL;
+PFNGLBLENDEQUATIONPROC __glewBlendEquation = NULL;
+PFNGLBLENDFUNCSEPARATEPROC __glewBlendFuncSeparate = NULL;
+PFNGLFOGCOORDPOINTERPROC __glewFogCoordPointer = NULL;
+PFNGLFOGCOORDDPROC __glewFogCoordd = NULL;
+PFNGLFOGCOORDDVPROC __glewFogCoorddv = NULL;
+PFNGLFOGCOORDFPROC __glewFogCoordf = NULL;
+PFNGLFOGCOORDFVPROC __glewFogCoordfv = NULL;
+PFNGLMULTIDRAWARRAYSPROC __glewMultiDrawArrays = NULL;
+PFNGLMULTIDRAWELEMENTSPROC __glewMultiDrawElements = NULL;
+PFNGLPOINTPARAMETERFPROC __glewPointParameterf = NULL;
+PFNGLPOINTPARAMETERFVPROC __glewPointParameterfv = NULL;
+PFNGLPOINTPARAMETERIPROC __glewPointParameteri = NULL;
+PFNGLPOINTPARAMETERIVPROC __glewPointParameteriv = NULL;
+PFNGLSECONDARYCOLOR3BPROC __glewSecondaryColor3b = NULL;
+PFNGLSECONDARYCOLOR3BVPROC __glewSecondaryColor3bv = NULL;
+PFNGLSECONDARYCOLOR3DPROC __glewSecondaryColor3d = NULL;
+PFNGLSECONDARYCOLOR3DVPROC __glewSecondaryColor3dv = NULL;
+PFNGLSECONDARYCOLOR3FPROC __glewSecondaryColor3f = NULL;
+PFNGLSECONDARYCOLOR3FVPROC __glewSecondaryColor3fv = NULL;
+PFNGLSECONDARYCOLOR3IPROC __glewSecondaryColor3i = NULL;
+PFNGLSECONDARYCOLOR3IVPROC __glewSecondaryColor3iv = NULL;
+PFNGLSECONDARYCOLOR3SPROC __glewSecondaryColor3s = NULL;
+PFNGLSECONDARYCOLOR3SVPROC __glewSecondaryColor3sv = NULL;
+PFNGLSECONDARYCOLOR3UBPROC __glewSecondaryColor3ub = NULL;
+PFNGLSECONDARYCOLOR3UBVPROC __glewSecondaryColor3ubv = NULL;
+PFNGLSECONDARYCOLOR3UIPROC __glewSecondaryColor3ui = NULL;
+PFNGLSECONDARYCOLOR3UIVPROC __glewSecondaryColor3uiv = NULL;
+PFNGLSECONDARYCOLOR3USPROC __glewSecondaryColor3us = NULL;
+PFNGLSECONDARYCOLOR3USVPROC __glewSecondaryColor3usv = NULL;
+PFNGLSECONDARYCOLORPOINTERPROC __glewSecondaryColorPointer = NULL;
+PFNGLWINDOWPOS2DPROC __glewWindowPos2d = NULL;
+PFNGLWINDOWPOS2DVPROC __glewWindowPos2dv = NULL;
+PFNGLWINDOWPOS2FPROC __glewWindowPos2f = NULL;
+PFNGLWINDOWPOS2FVPROC __glewWindowPos2fv = NULL;
+PFNGLWINDOWPOS2IPROC __glewWindowPos2i = NULL;
+PFNGLWINDOWPOS2IVPROC __glewWindowPos2iv = NULL;
+PFNGLWINDOWPOS2SPROC __glewWindowPos2s = NULL;
+PFNGLWINDOWPOS2SVPROC __glewWindowPos2sv = NULL;
+PFNGLWINDOWPOS3DPROC __glewWindowPos3d = NULL;
+PFNGLWINDOWPOS3DVPROC __glewWindowPos3dv = NULL;
+PFNGLWINDOWPOS3FPROC __glewWindowPos3f = NULL;
+PFNGLWINDOWPOS3FVPROC __glewWindowPos3fv = NULL;
+PFNGLWINDOWPOS3IPROC __glewWindowPos3i = NULL;
+PFNGLWINDOWPOS3IVPROC __glewWindowPos3iv = NULL;
+PFNGLWINDOWPOS3SPROC __glewWindowPos3s = NULL;
+PFNGLWINDOWPOS3SVPROC __glewWindowPos3sv = NULL;
+
+PFNGLBEGINQUERYPROC __glewBeginQuery = NULL;
+PFNGLBINDBUFFERPROC __glewBindBuffer = NULL;
+PFNGLBUFFERDATAPROC __glewBufferData = NULL;
+PFNGLBUFFERSUBDATAPROC __glewBufferSubData = NULL;
+PFNGLDELETEBUFFERSPROC __glewDeleteBuffers = NULL;
+PFNGLDELETEQUERIESPROC __glewDeleteQueries = NULL;
+PFNGLENDQUERYPROC __glewEndQuery = NULL;
+PFNGLGENBUFFERSPROC __glewGenBuffers = NULL;
+PFNGLGENQUERIESPROC __glewGenQueries = NULL;
+PFNGLGETBUFFERPARAMETERIVPROC __glewGetBufferParameteriv = NULL;
+PFNGLGETBUFFERPOINTERVPROC __glewGetBufferPointerv = NULL;
+PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData = NULL;
+PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv = NULL;
+PFNGLGETQUERYOBJECTUIVPROC __glewGetQueryObjectuiv = NULL;
+PFNGLGETQUERYIVPROC __glewGetQueryiv = NULL;
+PFNGLISBUFFERPROC __glewIsBuffer = NULL;
+PFNGLISQUERYPROC __glewIsQuery = NULL;
+PFNGLMAPBUFFERPROC __glewMapBuffer = NULL;
+PFNGLUNMAPBUFFERPROC __glewUnmapBuffer = NULL;
+
+PFNGLATTACHSHADERPROC __glewAttachShader = NULL;
+PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation = NULL;
+PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate = NULL;
+PFNGLCOMPILESHADERPROC __glewCompileShader = NULL;
+PFNGLCREATEPROGRAMPROC __glewCreateProgram = NULL;
+PFNGLCREATESHADERPROC __glewCreateShader = NULL;
+PFNGLDELETEPROGRAMPROC __glewDeleteProgram = NULL;
+PFNGLDELETESHADERPROC __glewDeleteShader = NULL;
+PFNGLDETACHSHADERPROC __glewDetachShader = NULL;
+PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray = NULL;
+PFNGLDRAWBUFFERSPROC __glewDrawBuffers = NULL;
+PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray = NULL;
+PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib = NULL;
+PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform = NULL;
+PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders = NULL;
+PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation = NULL;
+PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog = NULL;
+PFNGLGETPROGRAMIVPROC __glewGetProgramiv = NULL;
+PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog = NULL;
+PFNGLGETSHADERSOURCEPROC __glewGetShaderSource = NULL;
+PFNGLGETSHADERIVPROC __glewGetShaderiv = NULL;
+PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation = NULL;
+PFNGLGETUNIFORMFVPROC __glewGetUniformfv = NULL;
+PFNGLGETUNIFORMIVPROC __glewGetUniformiv = NULL;
+PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv = NULL;
+PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv = NULL;
+PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv = NULL;
+PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv = NULL;
+PFNGLISPROGRAMPROC __glewIsProgram = NULL;
+PFNGLISSHADERPROC __glewIsShader = NULL;
+PFNGLLINKPROGRAMPROC __glewLinkProgram = NULL;
+PFNGLSHADERSOURCEPROC __glewShaderSource = NULL;
+PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate = NULL;
+PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate = NULL;
+PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate = NULL;
+PFNGLUNIFORM1FPROC __glewUniform1f = NULL;
+PFNGLUNIFORM1FVPROC __glewUniform1fv = NULL;
+PFNGLUNIFORM1IPROC __glewUniform1i = NULL;
+PFNGLUNIFORM1IVPROC __glewUniform1iv = NULL;
+PFNGLUNIFORM2FPROC __glewUniform2f = NULL;
+PFNGLUNIFORM2FVPROC __glewUniform2fv = NULL;
+PFNGLUNIFORM2IPROC __glewUniform2i = NULL;
+PFNGLUNIFORM2IVPROC __glewUniform2iv = NULL;
+PFNGLUNIFORM3FPROC __glewUniform3f = NULL;
+PFNGLUNIFORM3FVPROC __glewUniform3fv = NULL;
+PFNGLUNIFORM3IPROC __glewUniform3i = NULL;
+PFNGLUNIFORM3IVPROC __glewUniform3iv = NULL;
+PFNGLUNIFORM4FPROC __glewUniform4f = NULL;
+PFNGLUNIFORM4FVPROC __glewUniform4fv = NULL;
+PFNGLUNIFORM4IPROC __glewUniform4i = NULL;
+PFNGLUNIFORM4IVPROC __glewUniform4iv = NULL;
+PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv = NULL;
+PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv = NULL;
+PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv = NULL;
+PFNGLUSEPROGRAMPROC __glewUseProgram = NULL;
+PFNGLVALIDATEPROGRAMPROC __glewValidateProgram = NULL;
+PFNGLVERTEXATTRIB1DPROC __glewVertexAttrib1d = NULL;
+PFNGLVERTEXATTRIB1DVPROC __glewVertexAttrib1dv = NULL;
+PFNGLVERTEXATTRIB1FPROC __glewVertexAttrib1f = NULL;
+PFNGLVERTEXATTRIB1FVPROC __glewVertexAttrib1fv = NULL;
+PFNGLVERTEXATTRIB1SPROC __glewVertexAttrib1s = NULL;
+PFNGLVERTEXATTRIB1SVPROC __glewVertexAttrib1sv = NULL;
+PFNGLVERTEXATTRIB2DPROC __glewVertexAttrib2d = NULL;
+PFNGLVERTEXATTRIB2DVPROC __glewVertexAttrib2dv = NULL;
+PFNGLVERTEXATTRIB2FPROC __glewVertexAttrib2f = NULL;
+PFNGLVERTEXATTRIB2FVPROC __glewVertexAttrib2fv = NULL;
+PFNGLVERTEXATTRIB2SPROC __glewVertexAttrib2s = NULL;
+PFNGLVERTEXATTRIB2SVPROC __glewVertexAttrib2sv = NULL;
+PFNGLVERTEXATTRIB3DPROC __glewVertexAttrib3d = NULL;
+PFNGLVERTEXATTRIB3DVPROC __glewVertexAttrib3dv = NULL;
+PFNGLVERTEXATTRIB3FPROC __glewVertexAttrib3f = NULL;
+PFNGLVERTEXATTRIB3FVPROC __glewVertexAttrib3fv = NULL;
+PFNGLVERTEXATTRIB3SPROC __glewVertexAttrib3s = NULL;
+PFNGLVERTEXATTRIB3SVPROC __glewVertexAttrib3sv = NULL;
+PFNGLVERTEXATTRIB4NBVPROC __glewVertexAttrib4Nbv = NULL;
+PFNGLVERTEXATTRIB4NIVPROC __glewVertexAttrib4Niv = NULL;
+PFNGLVERTEXATTRIB4NSVPROC __glewVertexAttrib4Nsv = NULL;
+PFNGLVERTEXATTRIB4NUBPROC __glewVertexAttrib4Nub = NULL;
+PFNGLVERTEXATTRIB4NUBVPROC __glewVertexAttrib4Nubv = NULL;
+PFNGLVERTEXATTRIB4NUIVPROC __glewVertexAttrib4Nuiv = NULL;
+PFNGLVERTEXATTRIB4NUSVPROC __glewVertexAttrib4Nusv = NULL;
+PFNGLVERTEXATTRIB4BVPROC __glewVertexAttrib4bv = NULL;
+PFNGLVERTEXATTRIB4DPROC __glewVertexAttrib4d = NULL;
+PFNGLVERTEXATTRIB4DVPROC __glewVertexAttrib4dv = NULL;
+PFNGLVERTEXATTRIB4FPROC __glewVertexAttrib4f = NULL;
+PFNGLVERTEXATTRIB4FVPROC __glewVertexAttrib4fv = NULL;
+PFNGLVERTEXATTRIB4IVPROC __glewVertexAttrib4iv = NULL;
+PFNGLVERTEXATTRIB4SPROC __glewVertexAttrib4s = NULL;
+PFNGLVERTEXATTRIB4SVPROC __glewVertexAttrib4sv = NULL;
+PFNGLVERTEXATTRIB4UBVPROC __glewVertexAttrib4ubv = NULL;
+PFNGLVERTEXATTRIB4UIVPROC __glewVertexAttrib4uiv = NULL;
+PFNGLVERTEXATTRIB4USVPROC __glewVertexAttrib4usv = NULL;
+PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer = NULL;
+
+PFNGLUNIFORMMATRIX2X3FVPROC __glewUniformMatrix2x3fv = NULL;
+PFNGLUNIFORMMATRIX2X4FVPROC __glewUniformMatrix2x4fv = NULL;
+PFNGLUNIFORMMATRIX3X2FVPROC __glewUniformMatrix3x2fv = NULL;
+PFNGLUNIFORMMATRIX3X4FVPROC __glewUniformMatrix3x4fv = NULL;
+PFNGLUNIFORMMATRIX4X2FVPROC __glewUniformMatrix4x2fv = NULL;
+PFNGLUNIFORMMATRIX4X3FVPROC __glewUniformMatrix4x3fv = NULL;
+
+PFNGLBEGINCONDITIONALRENDERPROC __glewBeginConditionalRender = NULL;
+PFNGLBEGINTRANSFORMFEEDBACKPROC __glewBeginTransformFeedback = NULL;
+PFNGLBINDFRAGDATALOCATIONPROC __glewBindFragDataLocation = NULL;
+PFNGLCLAMPCOLORPROC __glewClampColor = NULL;
+PFNGLCLEARBUFFERFIPROC __glewClearBufferfi = NULL;
+PFNGLCLEARBUFFERFVPROC __glewClearBufferfv = NULL;
+PFNGLCLEARBUFFERIVPROC __glewClearBufferiv = NULL;
+PFNGLCLEARBUFFERUIVPROC __glewClearBufferuiv = NULL;
+PFNGLCOLORMASKIPROC __glewColorMaski = NULL;
+PFNGLDISABLEIPROC __glewDisablei = NULL;
+PFNGLENABLEIPROC __glewEnablei = NULL;
+PFNGLENDCONDITIONALRENDERPROC __glewEndConditionalRender = NULL;
+PFNGLENDTRANSFORMFEEDBACKPROC __glewEndTransformFeedback = NULL;
+PFNGLGETBOOLEANI_VPROC __glewGetBooleani_v = NULL;
+PFNGLGETFRAGDATALOCATIONPROC __glewGetFragDataLocation = NULL;
+PFNGLGETSTRINGIPROC __glewGetStringi = NULL;
+PFNGLGETTEXPARAMETERIIVPROC __glewGetTexParameterIiv = NULL;
+PFNGLGETTEXPARAMETERIUIVPROC __glewGetTexParameterIuiv = NULL;
+PFNGLGETTRANSFORMFEEDBACKVARYINGPROC __glewGetTransformFeedbackVarying = NULL;
+PFNGLGETUNIFORMUIVPROC __glewGetUniformuiv = NULL;
+PFNGLGETVERTEXATTRIBIIVPROC __glewGetVertexAttribIiv = NULL;
+PFNGLGETVERTEXATTRIBIUIVPROC __glewGetVertexAttribIuiv = NULL;
+PFNGLISENABLEDIPROC __glewIsEnabledi = NULL;
+PFNGLTEXPARAMETERIIVPROC __glewTexParameterIiv = NULL;
+PFNGLTEXPARAMETERIUIVPROC __glewTexParameterIuiv = NULL;
+PFNGLTRANSFORMFEEDBACKVARYINGSPROC __glewTransformFeedbackVaryings = NULL;
+PFNGLUNIFORM1UIPROC __glewUniform1ui = NULL;
+PFNGLUNIFORM1UIVPROC __glewUniform1uiv = NULL;
+PFNGLUNIFORM2UIPROC __glewUniform2ui = NULL;
+PFNGLUNIFORM2UIVPROC __glewUniform2uiv = NULL;
+PFNGLUNIFORM3UIPROC __glewUniform3ui = NULL;
+PFNGLUNIFORM3UIVPROC __glewUniform3uiv = NULL;
+PFNGLUNIFORM4UIPROC __glewUniform4ui = NULL;
+PFNGLUNIFORM4UIVPROC __glewUniform4uiv = NULL;
+PFNGLVERTEXATTRIBI1IPROC __glewVertexAttribI1i = NULL;
+PFNGLVERTEXATTRIBI1IVPROC __glewVertexAttribI1iv = NULL;
+PFNGLVERTEXATTRIBI1UIPROC __glewVertexAttribI1ui = NULL;
+PFNGLVERTEXATTRIBI1UIVPROC __glewVertexAttribI1uiv = NULL;
+PFNGLVERTEXATTRIBI2IPROC __glewVertexAttribI2i = NULL;
+PFNGLVERTEXATTRIBI2IVPROC __glewVertexAttribI2iv = NULL;
+PFNGLVERTEXATTRIBI2UIPROC __glewVertexAttribI2ui = NULL;
+PFNGLVERTEXATTRIBI2UIVPROC __glewVertexAttribI2uiv = NULL;
+PFNGLVERTEXATTRIBI3IPROC __glewVertexAttribI3i = NULL;
+PFNGLVERTEXATTRIBI3IVPROC __glewVertexAttribI3iv = NULL;
+PFNGLVERTEXATTRIBI3UIPROC __glewVertexAttribI3ui = NULL;
+PFNGLVERTEXATTRIBI3UIVPROC __glewVertexAttribI3uiv = NULL;
+PFNGLVERTEXATTRIBI4BVPROC __glewVertexAttribI4bv = NULL;
+PFNGLVERTEXATTRIBI4IPROC __glewVertexAttribI4i = NULL;
+PFNGLVERTEXATTRIBI4IVPROC __glewVertexAttribI4iv = NULL;
+PFNGLVERTEXATTRIBI4SVPROC __glewVertexAttribI4sv = NULL;
+PFNGLVERTEXATTRIBI4UBVPROC __glewVertexAttribI4ubv = NULL;
+PFNGLVERTEXATTRIBI4UIPROC __glewVertexAttribI4ui = NULL;
+PFNGLVERTEXATTRIBI4UIVPROC __glewVertexAttribI4uiv = NULL;
+PFNGLVERTEXATTRIBI4USVPROC __glewVertexAttribI4usv = NULL;
+PFNGLVERTEXATTRIBIPOINTERPROC __glewVertexAttribIPointer = NULL;
+
+PFNGLDRAWARRAYSINSTANCEDPROC __glewDrawArraysInstanced = NULL;
+PFNGLDRAWELEMENTSINSTANCEDPROC __glewDrawElementsInstanced = NULL;
+PFNGLPRIMITIVERESTARTINDEXPROC __glewPrimitiveRestartIndex = NULL;
+PFNGLTEXBUFFERPROC __glewTexBuffer = NULL;
+
+PFNGLFRAMEBUFFERTEXTUREPROC __glewFramebufferTexture = NULL;
+PFNGLGETBUFFERPARAMETERI64VPROC __glewGetBufferParameteri64v = NULL;
+PFNGLGETINTEGER64I_VPROC __glewGetInteger64i_v = NULL;
+
+PFNGLVERTEXATTRIBDIVISORPROC __glewVertexAttribDivisor = NULL;
+
+PFNGLBLENDEQUATIONSEPARATEIPROC __glewBlendEquationSeparatei = NULL;
+PFNGLBLENDEQUATIONIPROC __glewBlendEquationi = NULL;
+PFNGLBLENDFUNCSEPARATEIPROC __glewBlendFuncSeparatei = NULL;
+PFNGLBLENDFUNCIPROC __glewBlendFunci = NULL;
+PFNGLMINSAMPLESHADINGPROC __glewMinSampleShading = NULL;
+
+PFNGLTBUFFERMASK3DFXPROC __glewTbufferMask3DFX = NULL;
+
+PFNGLDEBUGMESSAGECALLBACKAMDPROC __glewDebugMessageCallbackAMD = NULL;
+PFNGLDEBUGMESSAGEENABLEAMDPROC __glewDebugMessageEnableAMD = NULL;
+PFNGLDEBUGMESSAGEINSERTAMDPROC __glewDebugMessageInsertAMD = NULL;
+PFNGLGETDEBUGMESSAGELOGAMDPROC __glewGetDebugMessageLogAMD = NULL;
+
+PFNGLBLENDEQUATIONINDEXEDAMDPROC __glewBlendEquationIndexedAMD = NULL;
+PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC __glewBlendEquationSeparateIndexedAMD = NULL;
+PFNGLBLENDFUNCINDEXEDAMDPROC __glewBlendFuncIndexedAMD = NULL;
+PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC __glewBlendFuncSeparateIndexedAMD = NULL;
+
+PFNGLVERTEXATTRIBPARAMETERIAMDPROC __glewVertexAttribParameteriAMD = NULL;
+
+PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC __glewMultiDrawArraysIndirectAMD = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC __glewMultiDrawElementsIndirectAMD = NULL;
+
+PFNGLDELETENAMESAMDPROC __glewDeleteNamesAMD = NULL;
+PFNGLGENNAMESAMDPROC __glewGenNamesAMD = NULL;
+PFNGLISNAMEAMDPROC __glewIsNameAMD = NULL;
+
+PFNGLBEGINPERFMONITORAMDPROC __glewBeginPerfMonitorAMD = NULL;
+PFNGLDELETEPERFMONITORSAMDPROC __glewDeletePerfMonitorsAMD = NULL;
+PFNGLENDPERFMONITORAMDPROC __glewEndPerfMonitorAMD = NULL;
+PFNGLGENPERFMONITORSAMDPROC __glewGenPerfMonitorsAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERDATAAMDPROC __glewGetPerfMonitorCounterDataAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERINFOAMDPROC __glewGetPerfMonitorCounterInfoAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC __glewGetPerfMonitorCounterStringAMD = NULL;
+PFNGLGETPERFMONITORCOUNTERSAMDPROC __glewGetPerfMonitorCountersAMD = NULL;
+PFNGLGETPERFMONITORGROUPSTRINGAMDPROC __glewGetPerfMonitorGroupStringAMD = NULL;
+PFNGLGETPERFMONITORGROUPSAMDPROC __glewGetPerfMonitorGroupsAMD = NULL;
+PFNGLSELECTPERFMONITORCOUNTERSAMDPROC __glewSelectPerfMonitorCountersAMD = NULL;
+
+PFNGLSETMULTISAMPLEFVAMDPROC __glewSetMultisamplefvAMD = NULL;
+
+PFNGLTEXSTORAGESPARSEAMDPROC __glewTexStorageSparseAMD = NULL;
+PFNGLTEXTURESTORAGESPARSEAMDPROC __glewTextureStorageSparseAMD = NULL;
+
+PFNGLSTENCILOPVALUEAMDPROC __glewStencilOpValueAMD = NULL;
+
+PFNGLTESSELLATIONFACTORAMDPROC __glewTessellationFactorAMD = NULL;
+PFNGLTESSELLATIONMODEAMDPROC __glewTessellationModeAMD = NULL;
+
+PFNGLBLITFRAMEBUFFERANGLEPROC __glewBlitFramebufferANGLE = NULL;
+
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC __glewRenderbufferStorageMultisampleANGLE = NULL;
+
+PFNGLDRAWARRAYSINSTANCEDANGLEPROC __glewDrawArraysInstancedANGLE = NULL;
+PFNGLDRAWELEMENTSINSTANCEDANGLEPROC __glewDrawElementsInstancedANGLE = NULL;
+PFNGLVERTEXATTRIBDIVISORANGLEPROC __glewVertexAttribDivisorANGLE = NULL;
+
+PFNGLBEGINQUERYANGLEPROC __glewBeginQueryANGLE = NULL;
+PFNGLDELETEQUERIESANGLEPROC __glewDeleteQueriesANGLE = NULL;
+PFNGLENDQUERYANGLEPROC __glewEndQueryANGLE = NULL;
+PFNGLGENQUERIESANGLEPROC __glewGenQueriesANGLE = NULL;
+PFNGLGETQUERYOBJECTI64VANGLEPROC __glewGetQueryObjecti64vANGLE = NULL;
+PFNGLGETQUERYOBJECTIVANGLEPROC __glewGetQueryObjectivANGLE = NULL;
+PFNGLGETQUERYOBJECTUI64VANGLEPROC __glewGetQueryObjectui64vANGLE = NULL;
+PFNGLGETQUERYOBJECTUIVANGLEPROC __glewGetQueryObjectuivANGLE = NULL;
+PFNGLGETQUERYIVANGLEPROC __glewGetQueryivANGLE = NULL;
+PFNGLISQUERYANGLEPROC __glewIsQueryANGLE = NULL;
+PFNGLQUERYCOUNTERANGLEPROC __glewQueryCounterANGLE = NULL;
+
+PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC __glewGetTranslatedShaderSourceANGLE = NULL;
+
+PFNGLDRAWELEMENTARRAYAPPLEPROC __glewDrawElementArrayAPPLE = NULL;
+PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC __glewDrawRangeElementArrayAPPLE = NULL;
+PFNGLELEMENTPOINTERAPPLEPROC __glewElementPointerAPPLE = NULL;
+PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC __glewMultiDrawElementArrayAPPLE = NULL;
+PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC __glewMultiDrawRangeElementArrayAPPLE = NULL;
+
+PFNGLDELETEFENCESAPPLEPROC __glewDeleteFencesAPPLE = NULL;
+PFNGLFINISHFENCEAPPLEPROC __glewFinishFenceAPPLE = NULL;
+PFNGLFINISHOBJECTAPPLEPROC __glewFinishObjectAPPLE = NULL;
+PFNGLGENFENCESAPPLEPROC __glewGenFencesAPPLE = NULL;
+PFNGLISFENCEAPPLEPROC __glewIsFenceAPPLE = NULL;
+PFNGLSETFENCEAPPLEPROC __glewSetFenceAPPLE = NULL;
+PFNGLTESTFENCEAPPLEPROC __glewTestFenceAPPLE = NULL;
+PFNGLTESTOBJECTAPPLEPROC __glewTestObjectAPPLE = NULL;
+
+PFNGLBUFFERPARAMETERIAPPLEPROC __glewBufferParameteriAPPLE = NULL;
+PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC __glewFlushMappedBufferRangeAPPLE = NULL;
+
+PFNGLGETOBJECTPARAMETERIVAPPLEPROC __glewGetObjectParameterivAPPLE = NULL;
+PFNGLOBJECTPURGEABLEAPPLEPROC __glewObjectPurgeableAPPLE = NULL;
+PFNGLOBJECTUNPURGEABLEAPPLEPROC __glewObjectUnpurgeableAPPLE = NULL;
+
+PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC __glewGetTexParameterPointervAPPLE = NULL;
+PFNGLTEXTURERANGEAPPLEPROC __glewTextureRangeAPPLE = NULL;
+
+PFNGLBINDVERTEXARRAYAPPLEPROC __glewBindVertexArrayAPPLE = NULL;
+PFNGLDELETEVERTEXARRAYSAPPLEPROC __glewDeleteVertexArraysAPPLE = NULL;
+PFNGLGENVERTEXARRAYSAPPLEPROC __glewGenVertexArraysAPPLE = NULL;
+PFNGLISVERTEXARRAYAPPLEPROC __glewIsVertexArrayAPPLE = NULL;
+
+PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC __glewFlushVertexArrayRangeAPPLE = NULL;
+PFNGLVERTEXARRAYPARAMETERIAPPLEPROC __glewVertexArrayParameteriAPPLE = NULL;
+PFNGLVERTEXARRAYRANGEAPPLEPROC __glewVertexArrayRangeAPPLE = NULL;
+
+PFNGLDISABLEVERTEXATTRIBAPPLEPROC __glewDisableVertexAttribAPPLE = NULL;
+PFNGLENABLEVERTEXATTRIBAPPLEPROC __glewEnableVertexAttribAPPLE = NULL;
+PFNGLISVERTEXATTRIBENABLEDAPPLEPROC __glewIsVertexAttribEnabledAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB1DAPPLEPROC __glewMapVertexAttrib1dAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB1FAPPLEPROC __glewMapVertexAttrib1fAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB2DAPPLEPROC __glewMapVertexAttrib2dAPPLE = NULL;
+PFNGLMAPVERTEXATTRIB2FAPPLEPROC __glewMapVertexAttrib2fAPPLE = NULL;
+
+PFNGLCLEARDEPTHFPROC __glewClearDepthf = NULL;
+PFNGLDEPTHRANGEFPROC __glewDepthRangef = NULL;
+PFNGLGETSHADERPRECISIONFORMATPROC __glewGetShaderPrecisionFormat = NULL;
+PFNGLRELEASESHADERCOMPILERPROC __glewReleaseShaderCompiler = NULL;
+PFNGLSHADERBINARYPROC __glewShaderBinary = NULL;
+
+PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC __glewDrawArraysInstancedBaseInstance = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC __glewDrawElementsInstancedBaseInstance = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC __glewDrawElementsInstancedBaseVertexBaseInstance = NULL;
+
+PFNGLGETIMAGEHANDLEARBPROC __glewGetImageHandleARB = NULL;
+PFNGLGETTEXTUREHANDLEARBPROC __glewGetTextureHandleARB = NULL;
+PFNGLGETTEXTURESAMPLERHANDLEARBPROC __glewGetTextureSamplerHandleARB = NULL;
+PFNGLGETVERTEXATTRIBLUI64VARBPROC __glewGetVertexAttribLui64vARB = NULL;
+PFNGLISIMAGEHANDLERESIDENTARBPROC __glewIsImageHandleResidentARB = NULL;
+PFNGLISTEXTUREHANDLERESIDENTARBPROC __glewIsTextureHandleResidentARB = NULL;
+PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC __glewMakeImageHandleNonResidentARB = NULL;
+PFNGLMAKEIMAGEHANDLERESIDENTARBPROC __glewMakeImageHandleResidentARB = NULL;
+PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC __glewMakeTextureHandleNonResidentARB = NULL;
+PFNGLMAKETEXTUREHANDLERESIDENTARBPROC __glewMakeTextureHandleResidentARB = NULL;
+PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC __glewProgramUniformHandleui64ARB = NULL;
+PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC __glewProgramUniformHandleui64vARB = NULL;
+PFNGLUNIFORMHANDLEUI64ARBPROC __glewUniformHandleui64ARB = NULL;
+PFNGLUNIFORMHANDLEUI64VARBPROC __glewUniformHandleui64vARB = NULL;
+PFNGLVERTEXATTRIBL1UI64ARBPROC __glewVertexAttribL1ui64ARB = NULL;
+PFNGLVERTEXATTRIBL1UI64VARBPROC __glewVertexAttribL1ui64vARB = NULL;
+
+PFNGLBINDFRAGDATALOCATIONINDEXEDPROC __glewBindFragDataLocationIndexed = NULL;
+PFNGLGETFRAGDATAINDEXPROC __glewGetFragDataIndex = NULL;
+
+PFNGLBUFFERSTORAGEPROC __glewBufferStorage = NULL;
+PFNGLNAMEDBUFFERSTORAGEEXTPROC __glewNamedBufferStorageEXT = NULL;
+
+PFNGLCREATESYNCFROMCLEVENTARBPROC __glewCreateSyncFromCLeventARB = NULL;
+
+PFNGLCLEARBUFFERDATAPROC __glewClearBufferData = NULL;
+PFNGLCLEARBUFFERSUBDATAPROC __glewClearBufferSubData = NULL;
+PFNGLCLEARNAMEDBUFFERDATAEXTPROC __glewClearNamedBufferDataEXT = NULL;
+PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC __glewClearNamedBufferSubDataEXT = NULL;
+
+PFNGLCLEARTEXIMAGEPROC __glewClearTexImage = NULL;
+PFNGLCLEARTEXSUBIMAGEPROC __glewClearTexSubImage = NULL;
+
+PFNGLCLAMPCOLORARBPROC __glewClampColorARB = NULL;
+
+PFNGLDISPATCHCOMPUTEPROC __glewDispatchCompute = NULL;
+PFNGLDISPATCHCOMPUTEINDIRECTPROC __glewDispatchComputeIndirect = NULL;
+
+PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC __glewDispatchComputeGroupSizeARB = NULL;
+
+PFNGLCOPYBUFFERSUBDATAPROC __glewCopyBufferSubData = NULL;
+
+PFNGLCOPYIMAGESUBDATAPROC __glewCopyImageSubData = NULL;
+
+PFNGLDEBUGMESSAGECALLBACKARBPROC __glewDebugMessageCallbackARB = NULL;
+PFNGLDEBUGMESSAGECONTROLARBPROC __glewDebugMessageControlARB = NULL;
+PFNGLDEBUGMESSAGEINSERTARBPROC __glewDebugMessageInsertARB = NULL;
+PFNGLGETDEBUGMESSAGELOGARBPROC __glewGetDebugMessageLogARB = NULL;
+
+PFNGLDRAWBUFFERSARBPROC __glewDrawBuffersARB = NULL;
+
+PFNGLBLENDEQUATIONSEPARATEIARBPROC __glewBlendEquationSeparateiARB = NULL;
+PFNGLBLENDEQUATIONIARBPROC __glewBlendEquationiARB = NULL;
+PFNGLBLENDFUNCSEPARATEIARBPROC __glewBlendFuncSeparateiARB = NULL;
+PFNGLBLENDFUNCIARBPROC __glewBlendFunciARB = NULL;
+
+PFNGLDRAWELEMENTSBASEVERTEXPROC __glewDrawElementsBaseVertex = NULL;
+PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC __glewDrawElementsInstancedBaseVertex = NULL;
+PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC __glewDrawRangeElementsBaseVertex = NULL;
+PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC __glewMultiDrawElementsBaseVertex = NULL;
+
+PFNGLDRAWARRAYSINDIRECTPROC __glewDrawArraysIndirect = NULL;
+PFNGLDRAWELEMENTSINDIRECTPROC __glewDrawElementsIndirect = NULL;
+
+PFNGLFRAMEBUFFERPARAMETERIPROC __glewFramebufferParameteri = NULL;
+PFNGLGETFRAMEBUFFERPARAMETERIVPROC __glewGetFramebufferParameteriv = NULL;
+PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC __glewGetNamedFramebufferParameterivEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC __glewNamedFramebufferParameteriEXT = NULL;
+
+PFNGLBINDFRAMEBUFFERPROC __glewBindFramebuffer = NULL;
+PFNGLBINDRENDERBUFFERPROC __glewBindRenderbuffer = NULL;
+PFNGLBLITFRAMEBUFFERPROC __glewBlitFramebuffer = NULL;
+PFNGLCHECKFRAMEBUFFERSTATUSPROC __glewCheckFramebufferStatus = NULL;
+PFNGLDELETEFRAMEBUFFERSPROC __glewDeleteFramebuffers = NULL;
+PFNGLDELETERENDERBUFFERSPROC __glewDeleteRenderbuffers = NULL;
+PFNGLFRAMEBUFFERRENDERBUFFERPROC __glewFramebufferRenderbuffer = NULL;
+PFNGLFRAMEBUFFERTEXTURE1DPROC __glewFramebufferTexture1D = NULL;
+PFNGLFRAMEBUFFERTEXTURE2DPROC __glewFramebufferTexture2D = NULL;
+PFNGLFRAMEBUFFERTEXTURE3DPROC __glewFramebufferTexture3D = NULL;
+PFNGLFRAMEBUFFERTEXTURELAYERPROC __glewFramebufferTextureLayer = NULL;
+PFNGLGENFRAMEBUFFERSPROC __glewGenFramebuffers = NULL;
+PFNGLGENRENDERBUFFERSPROC __glewGenRenderbuffers = NULL;
+PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap = NULL;
+PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC __glewGetFramebufferAttachmentParameteriv = NULL;
+PFNGLGETRENDERBUFFERPARAMETERIVPROC __glewGetRenderbufferParameteriv = NULL;
+PFNGLISFRAMEBUFFERPROC __glewIsFramebuffer = NULL;
+PFNGLISRENDERBUFFERPROC __glewIsRenderbuffer = NULL;
+PFNGLRENDERBUFFERSTORAGEPROC __glewRenderbufferStorage = NULL;
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC __glewRenderbufferStorageMultisample = NULL;
+
+PFNGLFRAMEBUFFERTEXTUREARBPROC __glewFramebufferTextureARB = NULL;
+PFNGLFRAMEBUFFERTEXTUREFACEARBPROC __glewFramebufferTextureFaceARB = NULL;
+PFNGLFRAMEBUFFERTEXTURELAYERARBPROC __glewFramebufferTextureLayerARB = NULL;
+PFNGLPROGRAMPARAMETERIARBPROC __glewProgramParameteriARB = NULL;
+
+PFNGLGETPROGRAMBINARYPROC __glewGetProgramBinary = NULL;
+PFNGLPROGRAMBINARYPROC __glewProgramBinary = NULL;
+PFNGLPROGRAMPARAMETERIPROC __glewProgramParameteri = NULL;
+
+PFNGLGETUNIFORMDVPROC __glewGetUniformdv = NULL;
+PFNGLUNIFORM1DPROC __glewUniform1d = NULL;
+PFNGLUNIFORM1DVPROC __glewUniform1dv = NULL;
+PFNGLUNIFORM2DPROC __glewUniform2d = NULL;
+PFNGLUNIFORM2DVPROC __glewUniform2dv = NULL;
+PFNGLUNIFORM3DPROC __glewUniform3d = NULL;
+PFNGLUNIFORM3DVPROC __glewUniform3dv = NULL;
+PFNGLUNIFORM4DPROC __glewUniform4d = NULL;
+PFNGLUNIFORM4DVPROC __glewUniform4dv = NULL;
+PFNGLUNIFORMMATRIX2DVPROC __glewUniformMatrix2dv = NULL;
+PFNGLUNIFORMMATRIX2X3DVPROC __glewUniformMatrix2x3dv = NULL;
+PFNGLUNIFORMMATRIX2X4DVPROC __glewUniformMatrix2x4dv = NULL;
+PFNGLUNIFORMMATRIX3DVPROC __glewUniformMatrix3dv = NULL;
+PFNGLUNIFORMMATRIX3X2DVPROC __glewUniformMatrix3x2dv = NULL;
+PFNGLUNIFORMMATRIX3X4DVPROC __glewUniformMatrix3x4dv = NULL;
+PFNGLUNIFORMMATRIX4DVPROC __glewUniformMatrix4dv = NULL;
+PFNGLUNIFORMMATRIX4X2DVPROC __glewUniformMatrix4x2dv = NULL;
+PFNGLUNIFORMMATRIX4X3DVPROC __glewUniformMatrix4x3dv = NULL;
+
+PFNGLCOLORSUBTABLEPROC __glewColorSubTable = NULL;
+PFNGLCOLORTABLEPROC __glewColorTable = NULL;
+PFNGLCOLORTABLEPARAMETERFVPROC __glewColorTableParameterfv = NULL;
+PFNGLCOLORTABLEPARAMETERIVPROC __glewColorTableParameteriv = NULL;
+PFNGLCONVOLUTIONFILTER1DPROC __glewConvolutionFilter1D = NULL;
+PFNGLCONVOLUTIONFILTER2DPROC __glewConvolutionFilter2D = NULL;
+PFNGLCONVOLUTIONPARAMETERFPROC __glewConvolutionParameterf = NULL;
+PFNGLCONVOLUTIONPARAMETERFVPROC __glewConvolutionParameterfv = NULL;
+PFNGLCONVOLUTIONPARAMETERIPROC __glewConvolutionParameteri = NULL;
+PFNGLCONVOLUTIONPARAMETERIVPROC __glewConvolutionParameteriv = NULL;
+PFNGLCOPYCOLORSUBTABLEPROC __glewCopyColorSubTable = NULL;
+PFNGLCOPYCOLORTABLEPROC __glewCopyColorTable = NULL;
+PFNGLCOPYCONVOLUTIONFILTER1DPROC __glewCopyConvolutionFilter1D = NULL;
+PFNGLCOPYCONVOLUTIONFILTER2DPROC __glewCopyConvolutionFilter2D = NULL;
+PFNGLGETCOLORTABLEPROC __glewGetColorTable = NULL;
+PFNGLGETCOLORTABLEPARAMETERFVPROC __glewGetColorTableParameterfv = NULL;
+PFNGLGETCOLORTABLEPARAMETERIVPROC __glewGetColorTableParameteriv = NULL;
+PFNGLGETCONVOLUTIONFILTERPROC __glewGetConvolutionFilter = NULL;
+PFNGLGETCONVOLUTIONPARAMETERFVPROC __glewGetConvolutionParameterfv = NULL;
+PFNGLGETCONVOLUTIONPARAMETERIVPROC __glewGetConvolutionParameteriv = NULL;
+PFNGLGETHISTOGRAMPROC __glewGetHistogram = NULL;
+PFNGLGETHISTOGRAMPARAMETERFVPROC __glewGetHistogramParameterfv = NULL;
+PFNGLGETHISTOGRAMPARAMETERIVPROC __glewGetHistogramParameteriv = NULL;
+PFNGLGETMINMAXPROC __glewGetMinmax = NULL;
+PFNGLGETMINMAXPARAMETERFVPROC __glewGetMinmaxParameterfv = NULL;
+PFNGLGETMINMAXPARAMETERIVPROC __glewGetMinmaxParameteriv = NULL;
+PFNGLGETSEPARABLEFILTERPROC __glewGetSeparableFilter = NULL;
+PFNGLHISTOGRAMPROC __glewHistogram = NULL;
+PFNGLMINMAXPROC __glewMinmax = NULL;
+PFNGLRESETHISTOGRAMPROC __glewResetHistogram = NULL;
+PFNGLRESETMINMAXPROC __glewResetMinmax = NULL;
+PFNGLSEPARABLEFILTER2DPROC __glewSeparableFilter2D = NULL;
+
+PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC __glewMultiDrawArraysIndirectCountARB = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC __glewMultiDrawElementsIndirectCountARB = NULL;
+
+PFNGLDRAWARRAYSINSTANCEDARBPROC __glewDrawArraysInstancedARB = NULL;
+PFNGLDRAWELEMENTSINSTANCEDARBPROC __glewDrawElementsInstancedARB = NULL;
+PFNGLVERTEXATTRIBDIVISORARBPROC __glewVertexAttribDivisorARB = NULL;
+
+PFNGLGETINTERNALFORMATIVPROC __glewGetInternalformativ = NULL;
+
+PFNGLGETINTERNALFORMATI64VPROC __glewGetInternalformati64v = NULL;
+
+PFNGLINVALIDATEBUFFERDATAPROC __glewInvalidateBufferData = NULL;
+PFNGLINVALIDATEBUFFERSUBDATAPROC __glewInvalidateBufferSubData = NULL;
+PFNGLINVALIDATEFRAMEBUFFERPROC __glewInvalidateFramebuffer = NULL;
+PFNGLINVALIDATESUBFRAMEBUFFERPROC __glewInvalidateSubFramebuffer = NULL;
+PFNGLINVALIDATETEXIMAGEPROC __glewInvalidateTexImage = NULL;
+PFNGLINVALIDATETEXSUBIMAGEPROC __glewInvalidateTexSubImage = NULL;
+
+PFNGLFLUSHMAPPEDBUFFERRANGEPROC __glewFlushMappedBufferRange = NULL;
+PFNGLMAPBUFFERRANGEPROC __glewMapBufferRange = NULL;
+
+PFNGLCURRENTPALETTEMATRIXARBPROC __glewCurrentPaletteMatrixARB = NULL;
+PFNGLMATRIXINDEXPOINTERARBPROC __glewMatrixIndexPointerARB = NULL;
+PFNGLMATRIXINDEXUBVARBPROC __glewMatrixIndexubvARB = NULL;
+PFNGLMATRIXINDEXUIVARBPROC __glewMatrixIndexuivARB = NULL;
+PFNGLMATRIXINDEXUSVARBPROC __glewMatrixIndexusvARB = NULL;
+
+PFNGLBINDBUFFERSBASEPROC __glewBindBuffersBase = NULL;
+PFNGLBINDBUFFERSRANGEPROC __glewBindBuffersRange = NULL;
+PFNGLBINDIMAGETEXTURESPROC __glewBindImageTextures = NULL;
+PFNGLBINDSAMPLERSPROC __glewBindSamplers = NULL;
+PFNGLBINDTEXTURESPROC __glewBindTextures = NULL;
+PFNGLBINDVERTEXBUFFERSPROC __glewBindVertexBuffers = NULL;
+
+PFNGLMULTIDRAWARRAYSINDIRECTPROC __glewMultiDrawArraysIndirect = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTPROC __glewMultiDrawElementsIndirect = NULL;
+
+PFNGLSAMPLECOVERAGEARBPROC __glewSampleCoverageARB = NULL;
+
+PFNGLACTIVETEXTUREARBPROC __glewActiveTextureARB = NULL;
+PFNGLCLIENTACTIVETEXTUREARBPROC __glewClientActiveTextureARB = NULL;
+PFNGLMULTITEXCOORD1DARBPROC __glewMultiTexCoord1dARB = NULL;
+PFNGLMULTITEXCOORD1DVARBPROC __glewMultiTexCoord1dvARB = NULL;
+PFNGLMULTITEXCOORD1FARBPROC __glewMultiTexCoord1fARB = NULL;
+PFNGLMULTITEXCOORD1FVARBPROC __glewMultiTexCoord1fvARB = NULL;
+PFNGLMULTITEXCOORD1IARBPROC __glewMultiTexCoord1iARB = NULL;
+PFNGLMULTITEXCOORD1IVARBPROC __glewMultiTexCoord1ivARB = NULL;
+PFNGLMULTITEXCOORD1SARBPROC __glewMultiTexCoord1sARB = NULL;
+PFNGLMULTITEXCOORD1SVARBPROC __glewMultiTexCoord1svARB = NULL;
+PFNGLMULTITEXCOORD2DARBPROC __glewMultiTexCoord2dARB = NULL;
+PFNGLMULTITEXCOORD2DVARBPROC __glewMultiTexCoord2dvARB = NULL;
+PFNGLMULTITEXCOORD2FARBPROC __glewMultiTexCoord2fARB = NULL;
+PFNGLMULTITEXCOORD2FVARBPROC __glewMultiTexCoord2fvARB = NULL;
+PFNGLMULTITEXCOORD2IARBPROC __glewMultiTexCoord2iARB = NULL;
+PFNGLMULTITEXCOORD2IVARBPROC __glewMultiTexCoord2ivARB = NULL;
+PFNGLMULTITEXCOORD2SARBPROC __glewMultiTexCoord2sARB = NULL;
+PFNGLMULTITEXCOORD2SVARBPROC __glewMultiTexCoord2svARB = NULL;
+PFNGLMULTITEXCOORD3DARBPROC __glewMultiTexCoord3dARB = NULL;
+PFNGLMULTITEXCOORD3DVARBPROC __glewMultiTexCoord3dvARB = NULL;
+PFNGLMULTITEXCOORD3FARBPROC __glewMultiTexCoord3fARB = NULL;
+PFNGLMULTITEXCOORD3FVARBPROC __glewMultiTexCoord3fvARB = NULL;
+PFNGLMULTITEXCOORD3IARBPROC __glewMultiTexCoord3iARB = NULL;
+PFNGLMULTITEXCOORD3IVARBPROC __glewMultiTexCoord3ivARB = NULL;
+PFNGLMULTITEXCOORD3SARBPROC __glewMultiTexCoord3sARB = NULL;
+PFNGLMULTITEXCOORD3SVARBPROC __glewMultiTexCoord3svARB = NULL;
+PFNGLMULTITEXCOORD4DARBPROC __glewMultiTexCoord4dARB = NULL;
+PFNGLMULTITEXCOORD4DVARBPROC __glewMultiTexCoord4dvARB = NULL;
+PFNGLMULTITEXCOORD4FARBPROC __glewMultiTexCoord4fARB = NULL;
+PFNGLMULTITEXCOORD4FVARBPROC __glewMultiTexCoord4fvARB = NULL;
+PFNGLMULTITEXCOORD4IARBPROC __glewMultiTexCoord4iARB = NULL;
+PFNGLMULTITEXCOORD4IVARBPROC __glewMultiTexCoord4ivARB = NULL;
+PFNGLMULTITEXCOORD4SARBPROC __glewMultiTexCoord4sARB = NULL;
+PFNGLMULTITEXCOORD4SVARBPROC __glewMultiTexCoord4svARB = NULL;
+
+PFNGLBEGINQUERYARBPROC __glewBeginQueryARB = NULL;
+PFNGLDELETEQUERIESARBPROC __glewDeleteQueriesARB = NULL;
+PFNGLENDQUERYARBPROC __glewEndQueryARB = NULL;
+PFNGLGENQUERIESARBPROC __glewGenQueriesARB = NULL;
+PFNGLGETQUERYOBJECTIVARBPROC __glewGetQueryObjectivARB = NULL;
+PFNGLGETQUERYOBJECTUIVARBPROC __glewGetQueryObjectuivARB = NULL;
+PFNGLGETQUERYIVARBPROC __glewGetQueryivARB = NULL;
+PFNGLISQUERYARBPROC __glewIsQueryARB = NULL;
+
+PFNGLPOINTPARAMETERFARBPROC __glewPointParameterfARB = NULL;
+PFNGLPOINTPARAMETERFVARBPROC __glewPointParameterfvARB = NULL;
+
+PFNGLGETPROGRAMINTERFACEIVPROC __glewGetProgramInterfaceiv = NULL;
+PFNGLGETPROGRAMRESOURCEINDEXPROC __glewGetProgramResourceIndex = NULL;
+PFNGLGETPROGRAMRESOURCELOCATIONPROC __glewGetProgramResourceLocation = NULL;
+PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC __glewGetProgramResourceLocationIndex = NULL;
+PFNGLGETPROGRAMRESOURCENAMEPROC __glewGetProgramResourceName = NULL;
+PFNGLGETPROGRAMRESOURCEIVPROC __glewGetProgramResourceiv = NULL;
+
+PFNGLPROVOKINGVERTEXPROC __glewProvokingVertex = NULL;
+
+PFNGLGETGRAPHICSRESETSTATUSARBPROC __glewGetGraphicsResetStatusARB = NULL;
+PFNGLGETNCOLORTABLEARBPROC __glewGetnColorTableARB = NULL;
+PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC __glewGetnCompressedTexImageARB = NULL;
+PFNGLGETNCONVOLUTIONFILTERARBPROC __glewGetnConvolutionFilterARB = NULL;
+PFNGLGETNHISTOGRAMARBPROC __glewGetnHistogramARB = NULL;
+PFNGLGETNMAPDVARBPROC __glewGetnMapdvARB = NULL;
+PFNGLGETNMAPFVARBPROC __glewGetnMapfvARB = NULL;
+PFNGLGETNMAPIVARBPROC __glewGetnMapivARB = NULL;
+PFNGLGETNMINMAXARBPROC __glewGetnMinmaxARB = NULL;
+PFNGLGETNPIXELMAPFVARBPROC __glewGetnPixelMapfvARB = NULL;
+PFNGLGETNPIXELMAPUIVARBPROC __glewGetnPixelMapuivARB = NULL;
+PFNGLGETNPIXELMAPUSVARBPROC __glewGetnPixelMapusvARB = NULL;
+PFNGLGETNPOLYGONSTIPPLEARBPROC __glewGetnPolygonStippleARB = NULL;
+PFNGLGETNSEPARABLEFILTERARBPROC __glewGetnSeparableFilterARB = NULL;
+PFNGLGETNTEXIMAGEARBPROC __glewGetnTexImageARB = NULL;
+PFNGLGETNUNIFORMDVARBPROC __glewGetnUniformdvARB = NULL;
+PFNGLGETNUNIFORMFVARBPROC __glewGetnUniformfvARB = NULL;
+PFNGLGETNUNIFORMIVARBPROC __glewGetnUniformivARB = NULL;
+PFNGLGETNUNIFORMUIVARBPROC __glewGetnUniformuivARB = NULL;
+PFNGLREADNPIXELSARBPROC __glewReadnPixelsARB = NULL;
+
+PFNGLMINSAMPLESHADINGARBPROC __glewMinSampleShadingARB = NULL;
+
+PFNGLBINDSAMPLERPROC __glewBindSampler = NULL;
+PFNGLDELETESAMPLERSPROC __glewDeleteSamplers = NULL;
+PFNGLGENSAMPLERSPROC __glewGenSamplers = NULL;
+PFNGLGETSAMPLERPARAMETERIIVPROC __glewGetSamplerParameterIiv = NULL;
+PFNGLGETSAMPLERPARAMETERIUIVPROC __glewGetSamplerParameterIuiv = NULL;
+PFNGLGETSAMPLERPARAMETERFVPROC __glewGetSamplerParameterfv = NULL;
+PFNGLGETSAMPLERPARAMETERIVPROC __glewGetSamplerParameteriv = NULL;
+PFNGLISSAMPLERPROC __glewIsSampler = NULL;
+PFNGLSAMPLERPARAMETERIIVPROC __glewSamplerParameterIiv = NULL;
+PFNGLSAMPLERPARAMETERIUIVPROC __glewSamplerParameterIuiv = NULL;
+PFNGLSAMPLERPARAMETERFPROC __glewSamplerParameterf = NULL;
+PFNGLSAMPLERPARAMETERFVPROC __glewSamplerParameterfv = NULL;
+PFNGLSAMPLERPARAMETERIPROC __glewSamplerParameteri = NULL;
+PFNGLSAMPLERPARAMETERIVPROC __glewSamplerParameteriv = NULL;
+
+PFNGLACTIVESHADERPROGRAMPROC __glewActiveShaderProgram = NULL;
+PFNGLBINDPROGRAMPIPELINEPROC __glewBindProgramPipeline = NULL;
+PFNGLCREATESHADERPROGRAMVPROC __glewCreateShaderProgramv = NULL;
+PFNGLDELETEPROGRAMPIPELINESPROC __glewDeleteProgramPipelines = NULL;
+PFNGLGENPROGRAMPIPELINESPROC __glewGenProgramPipelines = NULL;
+PFNGLGETPROGRAMPIPELINEINFOLOGPROC __glewGetProgramPipelineInfoLog = NULL;
+PFNGLGETPROGRAMPIPELINEIVPROC __glewGetProgramPipelineiv = NULL;
+PFNGLISPROGRAMPIPELINEPROC __glewIsProgramPipeline = NULL;
+PFNGLPROGRAMUNIFORM1DPROC __glewProgramUniform1d = NULL;
+PFNGLPROGRAMUNIFORM1DVPROC __glewProgramUniform1dv = NULL;
+PFNGLPROGRAMUNIFORM1FPROC __glewProgramUniform1f = NULL;
+PFNGLPROGRAMUNIFORM1FVPROC __glewProgramUniform1fv = NULL;
+PFNGLPROGRAMUNIFORM1IPROC __glewProgramUniform1i = NULL;
+PFNGLPROGRAMUNIFORM1IVPROC __glewProgramUniform1iv = NULL;
+PFNGLPROGRAMUNIFORM1UIPROC __glewProgramUniform1ui = NULL;
+PFNGLPROGRAMUNIFORM1UIVPROC __glewProgramUniform1uiv = NULL;
+PFNGLPROGRAMUNIFORM2DPROC __glewProgramUniform2d = NULL;
+PFNGLPROGRAMUNIFORM2DVPROC __glewProgramUniform2dv = NULL;
+PFNGLPROGRAMUNIFORM2FPROC __glewProgramUniform2f = NULL;
+PFNGLPROGRAMUNIFORM2FVPROC __glewProgramUniform2fv = NULL;
+PFNGLPROGRAMUNIFORM2IPROC __glewProgramUniform2i = NULL;
+PFNGLPROGRAMUNIFORM2IVPROC __glewProgramUniform2iv = NULL;
+PFNGLPROGRAMUNIFORM2UIPROC __glewProgramUniform2ui = NULL;
+PFNGLPROGRAMUNIFORM2UIVPROC __glewProgramUniform2uiv = NULL;
+PFNGLPROGRAMUNIFORM3DPROC __glewProgramUniform3d = NULL;
+PFNGLPROGRAMUNIFORM3DVPROC __glewProgramUniform3dv = NULL;
+PFNGLPROGRAMUNIFORM3FPROC __glewProgramUniform3f = NULL;
+PFNGLPROGRAMUNIFORM3FVPROC __glewProgramUniform3fv = NULL;
+PFNGLPROGRAMUNIFORM3IPROC __glewProgramUniform3i = NULL;
+PFNGLPROGRAMUNIFORM3IVPROC __glewProgramUniform3iv = NULL;
+PFNGLPROGRAMUNIFORM3UIPROC __glewProgramUniform3ui = NULL;
+PFNGLPROGRAMUNIFORM3UIVPROC __glewProgramUniform3uiv = NULL;
+PFNGLPROGRAMUNIFORM4DPROC __glewProgramUniform4d = NULL;
+PFNGLPROGRAMUNIFORM4DVPROC __glewProgramUniform4dv = NULL;
+PFNGLPROGRAMUNIFORM4FPROC __glewProgramUniform4f = NULL;
+PFNGLPROGRAMUNIFORM4FVPROC __glewProgramUniform4fv = NULL;
+PFNGLPROGRAMUNIFORM4IPROC __glewProgramUniform4i = NULL;
+PFNGLPROGRAMUNIFORM4IVPROC __glewProgramUniform4iv = NULL;
+PFNGLPROGRAMUNIFORM4UIPROC __glewProgramUniform4ui = NULL;
+PFNGLPROGRAMUNIFORM4UIVPROC __glewProgramUniform4uiv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2DVPROC __glewProgramUniformMatrix2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2FVPROC __glewProgramUniformMatrix2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC __glewProgramUniformMatrix2x3dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC __glewProgramUniformMatrix2x3fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC __glewProgramUniformMatrix2x4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC __glewProgramUniformMatrix2x4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3DVPROC __glewProgramUniformMatrix3dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3FVPROC __glewProgramUniformMatrix3fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC __glewProgramUniformMatrix3x2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC __glewProgramUniformMatrix3x2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC __glewProgramUniformMatrix3x4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC __glewProgramUniformMatrix3x4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4DVPROC __glewProgramUniformMatrix4dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4FVPROC __glewProgramUniformMatrix4fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC __glewProgramUniformMatrix4x2dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC __glewProgramUniformMatrix4x2fv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC __glewProgramUniformMatrix4x3dv = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC __glewProgramUniformMatrix4x3fv = NULL;
+PFNGLUSEPROGRAMSTAGESPROC __glewUseProgramStages = NULL;
+PFNGLVALIDATEPROGRAMPIPELINEPROC __glewValidateProgramPipeline = NULL;
+
+PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC __glewGetActiveAtomicCounterBufferiv = NULL;
+
+PFNGLBINDIMAGETEXTUREPROC __glewBindImageTexture = NULL;
+PFNGLMEMORYBARRIERPROC __glewMemoryBarrier = NULL;
+
+PFNGLATTACHOBJECTARBPROC __glewAttachObjectARB = NULL;
+PFNGLCOMPILESHADERARBPROC __glewCompileShaderARB = NULL;
+PFNGLCREATEPROGRAMOBJECTARBPROC __glewCreateProgramObjectARB = NULL;
+PFNGLCREATESHADEROBJECTARBPROC __glewCreateShaderObjectARB = NULL;
+PFNGLDELETEOBJECTARBPROC __glewDeleteObjectARB = NULL;
+PFNGLDETACHOBJECTARBPROC __glewDetachObjectARB = NULL;
+PFNGLGETACTIVEUNIFORMARBPROC __glewGetActiveUniformARB = NULL;
+PFNGLGETATTACHEDOBJECTSARBPROC __glewGetAttachedObjectsARB = NULL;
+PFNGLGETHANDLEARBPROC __glewGetHandleARB = NULL;
+PFNGLGETINFOLOGARBPROC __glewGetInfoLogARB = NULL;
+PFNGLGETOBJECTPARAMETERFVARBPROC __glewGetObjectParameterfvARB = NULL;
+PFNGLGETOBJECTPARAMETERIVARBPROC __glewGetObjectParameterivARB = NULL;
+PFNGLGETSHADERSOURCEARBPROC __glewGetShaderSourceARB = NULL;
+PFNGLGETUNIFORMLOCATIONARBPROC __glewGetUniformLocationARB = NULL;
+PFNGLGETUNIFORMFVARBPROC __glewGetUniformfvARB = NULL;
+PFNGLGETUNIFORMIVARBPROC __glewGetUniformivARB = NULL;
+PFNGLLINKPROGRAMARBPROC __glewLinkProgramARB = NULL;
+PFNGLSHADERSOURCEARBPROC __glewShaderSourceARB = NULL;
+PFNGLUNIFORM1FARBPROC __glewUniform1fARB = NULL;
+PFNGLUNIFORM1FVARBPROC __glewUniform1fvARB = NULL;
+PFNGLUNIFORM1IARBPROC __glewUniform1iARB = NULL;
+PFNGLUNIFORM1IVARBPROC __glewUniform1ivARB = NULL;
+PFNGLUNIFORM2FARBPROC __glewUniform2fARB = NULL;
+PFNGLUNIFORM2FVARBPROC __glewUniform2fvARB = NULL;
+PFNGLUNIFORM2IARBPROC __glewUniform2iARB = NULL;
+PFNGLUNIFORM2IVARBPROC __glewUniform2ivARB = NULL;
+PFNGLUNIFORM3FARBPROC __glewUniform3fARB = NULL;
+PFNGLUNIFORM3FVARBPROC __glewUniform3fvARB = NULL;
+PFNGLUNIFORM3IARBPROC __glewUniform3iARB = NULL;
+PFNGLUNIFORM3IVARBPROC __glewUniform3ivARB = NULL;
+PFNGLUNIFORM4FARBPROC __glewUniform4fARB = NULL;
+PFNGLUNIFORM4FVARBPROC __glewUniform4fvARB = NULL;
+PFNGLUNIFORM4IARBPROC __glewUniform4iARB = NULL;
+PFNGLUNIFORM4IVARBPROC __glewUniform4ivARB = NULL;
+PFNGLUNIFORMMATRIX2FVARBPROC __glewUniformMatrix2fvARB = NULL;
+PFNGLUNIFORMMATRIX3FVARBPROC __glewUniformMatrix3fvARB = NULL;
+PFNGLUNIFORMMATRIX4FVARBPROC __glewUniformMatrix4fvARB = NULL;
+PFNGLUSEPROGRAMOBJECTARBPROC __glewUseProgramObjectARB = NULL;
+PFNGLVALIDATEPROGRAMARBPROC __glewValidateProgramARB = NULL;
+
+PFNGLSHADERSTORAGEBLOCKBINDINGPROC __glewShaderStorageBlockBinding = NULL;
+
+PFNGLGETACTIVESUBROUTINENAMEPROC __glewGetActiveSubroutineName = NULL;
+PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC __glewGetActiveSubroutineUniformName = NULL;
+PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC __glewGetActiveSubroutineUniformiv = NULL;
+PFNGLGETPROGRAMSTAGEIVPROC __glewGetProgramStageiv = NULL;
+PFNGLGETSUBROUTINEINDEXPROC __glewGetSubroutineIndex = NULL;
+PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC __glewGetSubroutineUniformLocation = NULL;
+PFNGLGETUNIFORMSUBROUTINEUIVPROC __glewGetUniformSubroutineuiv = NULL;
+PFNGLUNIFORMSUBROUTINESUIVPROC __glewUniformSubroutinesuiv = NULL;
+
+PFNGLCOMPILESHADERINCLUDEARBPROC __glewCompileShaderIncludeARB = NULL;
+PFNGLDELETENAMEDSTRINGARBPROC __glewDeleteNamedStringARB = NULL;
+PFNGLGETNAMEDSTRINGARBPROC __glewGetNamedStringARB = NULL;
+PFNGLGETNAMEDSTRINGIVARBPROC __glewGetNamedStringivARB = NULL;
+PFNGLISNAMEDSTRINGARBPROC __glewIsNamedStringARB = NULL;
+PFNGLNAMEDSTRINGARBPROC __glewNamedStringARB = NULL;
+
+PFNGLTEXPAGECOMMITMENTARBPROC __glewTexPageCommitmentARB = NULL;
+PFNGLTEXTUREPAGECOMMITMENTEXTPROC __glewTexturePageCommitmentEXT = NULL;
+
+PFNGLCLIENTWAITSYNCPROC __glewClientWaitSync = NULL;
+PFNGLDELETESYNCPROC __glewDeleteSync = NULL;
+PFNGLFENCESYNCPROC __glewFenceSync = NULL;
+PFNGLGETINTEGER64VPROC __glewGetInteger64v = NULL;
+PFNGLGETSYNCIVPROC __glewGetSynciv = NULL;
+PFNGLISSYNCPROC __glewIsSync = NULL;
+PFNGLWAITSYNCPROC __glewWaitSync = NULL;
+
+PFNGLPATCHPARAMETERFVPROC __glewPatchParameterfv = NULL;
+PFNGLPATCHPARAMETERIPROC __glewPatchParameteri = NULL;
+
+PFNGLTEXBUFFERARBPROC __glewTexBufferARB = NULL;
+
+PFNGLTEXBUFFERRANGEPROC __glewTexBufferRange = NULL;
+PFNGLTEXTUREBUFFERRANGEEXTPROC __glewTextureBufferRangeEXT = NULL;
+
+PFNGLCOMPRESSEDTEXIMAGE1DARBPROC __glewCompressedTexImage1DARB = NULL;
+PFNGLCOMPRESSEDTEXIMAGE2DARBPROC __glewCompressedTexImage2DARB = NULL;
+PFNGLCOMPRESSEDTEXIMAGE3DARBPROC __glewCompressedTexImage3DARB = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC __glewCompressedTexSubImage1DARB = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC __glewCompressedTexSubImage2DARB = NULL;
+PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC __glewCompressedTexSubImage3DARB = NULL;
+PFNGLGETCOMPRESSEDTEXIMAGEARBPROC __glewGetCompressedTexImageARB = NULL;
+
+PFNGLGETMULTISAMPLEFVPROC __glewGetMultisamplefv = NULL;
+PFNGLSAMPLEMASKIPROC __glewSampleMaski = NULL;
+PFNGLTEXIMAGE2DMULTISAMPLEPROC __glewTexImage2DMultisample = NULL;
+PFNGLTEXIMAGE3DMULTISAMPLEPROC __glewTexImage3DMultisample = NULL;
+
+PFNGLTEXSTORAGE1DPROC __glewTexStorage1D = NULL;
+PFNGLTEXSTORAGE2DPROC __glewTexStorage2D = NULL;
+PFNGLTEXSTORAGE3DPROC __glewTexStorage3D = NULL;
+PFNGLTEXTURESTORAGE1DEXTPROC __glewTextureStorage1DEXT = NULL;
+PFNGLTEXTURESTORAGE2DEXTPROC __glewTextureStorage2DEXT = NULL;
+PFNGLTEXTURESTORAGE3DEXTPROC __glewTextureStorage3DEXT = NULL;
+
+PFNGLTEXSTORAGE2DMULTISAMPLEPROC __glewTexStorage2DMultisample = NULL;
+PFNGLTEXSTORAGE3DMULTISAMPLEPROC __glewTexStorage3DMultisample = NULL;
+PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC __glewTextureStorage2DMultisampleEXT = NULL;
+PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC __glewTextureStorage3DMultisampleEXT = NULL;
+
+PFNGLTEXTUREVIEWPROC __glewTextureView = NULL;
+
+PFNGLGETQUERYOBJECTI64VPROC __glewGetQueryObjecti64v = NULL;
+PFNGLGETQUERYOBJECTUI64VPROC __glewGetQueryObjectui64v = NULL;
+PFNGLQUERYCOUNTERPROC __glewQueryCounter = NULL;
+
+PFNGLBINDTRANSFORMFEEDBACKPROC __glewBindTransformFeedback = NULL;
+PFNGLDELETETRANSFORMFEEDBACKSPROC __glewDeleteTransformFeedbacks = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKPROC __glewDrawTransformFeedback = NULL;
+PFNGLGENTRANSFORMFEEDBACKSPROC __glewGenTransformFeedbacks = NULL;
+PFNGLISTRANSFORMFEEDBACKPROC __glewIsTransformFeedback = NULL;
+PFNGLPAUSETRANSFORMFEEDBACKPROC __glewPauseTransformFeedback = NULL;
+PFNGLRESUMETRANSFORMFEEDBACKPROC __glewResumeTransformFeedback = NULL;
+
+PFNGLBEGINQUERYINDEXEDPROC __glewBeginQueryIndexed = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC __glewDrawTransformFeedbackStream = NULL;
+PFNGLENDQUERYINDEXEDPROC __glewEndQueryIndexed = NULL;
+PFNGLGETQUERYINDEXEDIVPROC __glewGetQueryIndexediv = NULL;
+
+PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC __glewDrawTransformFeedbackInstanced = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC __glewDrawTransformFeedbackStreamInstanced = NULL;
+
+PFNGLLOADTRANSPOSEMATRIXDARBPROC __glewLoadTransposeMatrixdARB = NULL;
+PFNGLLOADTRANSPOSEMATRIXFARBPROC __glewLoadTransposeMatrixfARB = NULL;
+PFNGLMULTTRANSPOSEMATRIXDARBPROC __glewMultTransposeMatrixdARB = NULL;
+PFNGLMULTTRANSPOSEMATRIXFARBPROC __glewMultTransposeMatrixfARB = NULL;
+
+PFNGLBINDBUFFERBASEPROC __glewBindBufferBase = NULL;
+PFNGLBINDBUFFERRANGEPROC __glewBindBufferRange = NULL;
+PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC __glewGetActiveUniformBlockName = NULL;
+PFNGLGETACTIVEUNIFORMBLOCKIVPROC __glewGetActiveUniformBlockiv = NULL;
+PFNGLGETACTIVEUNIFORMNAMEPROC __glewGetActiveUniformName = NULL;
+PFNGLGETACTIVEUNIFORMSIVPROC __glewGetActiveUniformsiv = NULL;
+PFNGLGETINTEGERI_VPROC __glewGetIntegeri_v = NULL;
+PFNGLGETUNIFORMBLOCKINDEXPROC __glewGetUniformBlockIndex = NULL;
+PFNGLGETUNIFORMINDICESPROC __glewGetUniformIndices = NULL;
+PFNGLUNIFORMBLOCKBINDINGPROC __glewUniformBlockBinding = NULL;
+
+PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray = NULL;
+PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays = NULL;
+PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays = NULL;
+PFNGLISVERTEXARRAYPROC __glewIsVertexArray = NULL;
+
+PFNGLGETVERTEXATTRIBLDVPROC __glewGetVertexAttribLdv = NULL;
+PFNGLVERTEXATTRIBL1DPROC __glewVertexAttribL1d = NULL;
+PFNGLVERTEXATTRIBL1DVPROC __glewVertexAttribL1dv = NULL;
+PFNGLVERTEXATTRIBL2DPROC __glewVertexAttribL2d = NULL;
+PFNGLVERTEXATTRIBL2DVPROC __glewVertexAttribL2dv = NULL;
+PFNGLVERTEXATTRIBL3DPROC __glewVertexAttribL3d = NULL;
+PFNGLVERTEXATTRIBL3DVPROC __glewVertexAttribL3dv = NULL;
+PFNGLVERTEXATTRIBL4DPROC __glewVertexAttribL4d = NULL;
+PFNGLVERTEXATTRIBL4DVPROC __glewVertexAttribL4dv = NULL;
+PFNGLVERTEXATTRIBLPOINTERPROC __glewVertexAttribLPointer = NULL;
+
+PFNGLBINDVERTEXBUFFERPROC __glewBindVertexBuffer = NULL;
+PFNGLVERTEXATTRIBBINDINGPROC __glewVertexAttribBinding = NULL;
+PFNGLVERTEXATTRIBFORMATPROC __glewVertexAttribFormat = NULL;
+PFNGLVERTEXATTRIBIFORMATPROC __glewVertexAttribIFormat = NULL;
+PFNGLVERTEXATTRIBLFORMATPROC __glewVertexAttribLFormat = NULL;
+PFNGLVERTEXBINDINGDIVISORPROC __glewVertexBindingDivisor = NULL;
+
+PFNGLVERTEXBLENDARBPROC __glewVertexBlendARB = NULL;
+PFNGLWEIGHTPOINTERARBPROC __glewWeightPointerARB = NULL;
+PFNGLWEIGHTBVARBPROC __glewWeightbvARB = NULL;
+PFNGLWEIGHTDVARBPROC __glewWeightdvARB = NULL;
+PFNGLWEIGHTFVARBPROC __glewWeightfvARB = NULL;
+PFNGLWEIGHTIVARBPROC __glewWeightivARB = NULL;
+PFNGLWEIGHTSVARBPROC __glewWeightsvARB = NULL;
+PFNGLWEIGHTUBVARBPROC __glewWeightubvARB = NULL;
+PFNGLWEIGHTUIVARBPROC __glewWeightuivARB = NULL;
+PFNGLWEIGHTUSVARBPROC __glewWeightusvARB = NULL;
+
+PFNGLBINDBUFFERARBPROC __glewBindBufferARB = NULL;
+PFNGLBUFFERDATAARBPROC __glewBufferDataARB = NULL;
+PFNGLBUFFERSUBDATAARBPROC __glewBufferSubDataARB = NULL;
+PFNGLDELETEBUFFERSARBPROC __glewDeleteBuffersARB = NULL;
+PFNGLGENBUFFERSARBPROC __glewGenBuffersARB = NULL;
+PFNGLGETBUFFERPARAMETERIVARBPROC __glewGetBufferParameterivARB = NULL;
+PFNGLGETBUFFERPOINTERVARBPROC __glewGetBufferPointervARB = NULL;
+PFNGLGETBUFFERSUBDATAARBPROC __glewGetBufferSubDataARB = NULL;
+PFNGLISBUFFERARBPROC __glewIsBufferARB = NULL;
+PFNGLMAPBUFFERARBPROC __glewMapBufferARB = NULL;
+PFNGLUNMAPBUFFERARBPROC __glewUnmapBufferARB = NULL;
+
+PFNGLBINDPROGRAMARBPROC __glewBindProgramARB = NULL;
+PFNGLDELETEPROGRAMSARBPROC __glewDeleteProgramsARB = NULL;
+PFNGLDISABLEVERTEXATTRIBARRAYARBPROC __glewDisableVertexAttribArrayARB = NULL;
+PFNGLENABLEVERTEXATTRIBARRAYARBPROC __glewEnableVertexAttribArrayARB = NULL;
+PFNGLGENPROGRAMSARBPROC __glewGenProgramsARB = NULL;
+PFNGLGETPROGRAMENVPARAMETERDVARBPROC __glewGetProgramEnvParameterdvARB = NULL;
+PFNGLGETPROGRAMENVPARAMETERFVARBPROC __glewGetProgramEnvParameterfvARB = NULL;
+PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC __glewGetProgramLocalParameterdvARB = NULL;
+PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC __glewGetProgramLocalParameterfvARB = NULL;
+PFNGLGETPROGRAMSTRINGARBPROC __glewGetProgramStringARB = NULL;
+PFNGLGETPROGRAMIVARBPROC __glewGetProgramivARB = NULL;
+PFNGLGETVERTEXATTRIBPOINTERVARBPROC __glewGetVertexAttribPointervARB = NULL;
+PFNGLGETVERTEXATTRIBDVARBPROC __glewGetVertexAttribdvARB = NULL;
+PFNGLGETVERTEXATTRIBFVARBPROC __glewGetVertexAttribfvARB = NULL;
+PFNGLGETVERTEXATTRIBIVARBPROC __glewGetVertexAttribivARB = NULL;
+PFNGLISPROGRAMARBPROC __glewIsProgramARB = NULL;
+PFNGLPROGRAMENVPARAMETER4DARBPROC __glewProgramEnvParameter4dARB = NULL;
+PFNGLPROGRAMENVPARAMETER4DVARBPROC __glewProgramEnvParameter4dvARB = NULL;
+PFNGLPROGRAMENVPARAMETER4FARBPROC __glewProgramEnvParameter4fARB = NULL;
+PFNGLPROGRAMENVPARAMETER4FVARBPROC __glewProgramEnvParameter4fvARB = NULL;
+PFNGLPROGRAMLOCALPARAMETER4DARBPROC __glewProgramLocalParameter4dARB = NULL;
+PFNGLPROGRAMLOCALPARAMETER4DVARBPROC __glewProgramLocalParameter4dvARB = NULL;
+PFNGLPROGRAMLOCALPARAMETER4FARBPROC __glewProgramLocalParameter4fARB = NULL;
+PFNGLPROGRAMLOCALPARAMETER4FVARBPROC __glewProgramLocalParameter4fvARB = NULL;
+PFNGLPROGRAMSTRINGARBPROC __glewProgramStringARB = NULL;
+PFNGLVERTEXATTRIB1DARBPROC __glewVertexAttrib1dARB = NULL;
+PFNGLVERTEXATTRIB1DVARBPROC __glewVertexAttrib1dvARB = NULL;
+PFNGLVERTEXATTRIB1FARBPROC __glewVertexAttrib1fARB = NULL;
+PFNGLVERTEXATTRIB1FVARBPROC __glewVertexAttrib1fvARB = NULL;
+PFNGLVERTEXATTRIB1SARBPROC __glewVertexAttrib1sARB = NULL;
+PFNGLVERTEXATTRIB1SVARBPROC __glewVertexAttrib1svARB = NULL;
+PFNGLVERTEXATTRIB2DARBPROC __glewVertexAttrib2dARB = NULL;
+PFNGLVERTEXATTRIB2DVARBPROC __glewVertexAttrib2dvARB = NULL;
+PFNGLVERTEXATTRIB2FARBPROC __glewVertexAttrib2fARB = NULL;
+PFNGLVERTEXATTRIB2FVARBPROC __glewVertexAttrib2fvARB = NULL;
+PFNGLVERTEXATTRIB2SARBPROC __glewVertexAttrib2sARB = NULL;
+PFNGLVERTEXATTRIB2SVARBPROC __glewVertexAttrib2svARB = NULL;
+PFNGLVERTEXATTRIB3DARBPROC __glewVertexAttrib3dARB = NULL;
+PFNGLVERTEXATTRIB3DVARBPROC __glewVertexAttrib3dvARB = NULL;
+PFNGLVERTEXATTRIB3FARBPROC __glewVertexAttrib3fARB = NULL;
+PFNGLVERTEXATTRIB3FVARBPROC __glewVertexAttrib3fvARB = NULL;
+PFNGLVERTEXATTRIB3SARBPROC __glewVertexAttrib3sARB = NULL;
+PFNGLVERTEXATTRIB3SVARBPROC __glewVertexAttrib3svARB = NULL;
+PFNGLVERTEXATTRIB4NBVARBPROC __glewVertexAttrib4NbvARB = NULL;
+PFNGLVERTEXATTRIB4NIVARBPROC __glewVertexAttrib4NivARB = NULL;
+PFNGLVERTEXATTRIB4NSVARBPROC __glewVertexAttrib4NsvARB = NULL;
+PFNGLVERTEXATTRIB4NUBARBPROC __glewVertexAttrib4NubARB = NULL;
+PFNGLVERTEXATTRIB4NUBVARBPROC __glewVertexAttrib4NubvARB = NULL;
+PFNGLVERTEXATTRIB4NUIVARBPROC __glewVertexAttrib4NuivARB = NULL;
+PFNGLVERTEXATTRIB4NUSVARBPROC __glewVertexAttrib4NusvARB = NULL;
+PFNGLVERTEXATTRIB4BVARBPROC __glewVertexAttrib4bvARB = NULL;
+PFNGLVERTEXATTRIB4DARBPROC __glewVertexAttrib4dARB = NULL;
+PFNGLVERTEXATTRIB4DVARBPROC __glewVertexAttrib4dvARB = NULL;
+PFNGLVERTEXATTRIB4FARBPROC __glewVertexAttrib4fARB = NULL;
+PFNGLVERTEXATTRIB4FVARBPROC __glewVertexAttrib4fvARB = NULL;
+PFNGLVERTEXATTRIB4IVARBPROC __glewVertexAttrib4ivARB = NULL;
+PFNGLVERTEXATTRIB4SARBPROC __glewVertexAttrib4sARB = NULL;
+PFNGLVERTEXATTRIB4SVARBPROC __glewVertexAttrib4svARB = NULL;
+PFNGLVERTEXATTRIB4UBVARBPROC __glewVertexAttrib4ubvARB = NULL;
+PFNGLVERTEXATTRIB4UIVARBPROC __glewVertexAttrib4uivARB = NULL;
+PFNGLVERTEXATTRIB4USVARBPROC __glewVertexAttrib4usvARB = NULL;
+PFNGLVERTEXATTRIBPOINTERARBPROC __glewVertexAttribPointerARB = NULL;
+
+PFNGLBINDATTRIBLOCATIONARBPROC __glewBindAttribLocationARB = NULL;
+PFNGLGETACTIVEATTRIBARBPROC __glewGetActiveAttribARB = NULL;
+PFNGLGETATTRIBLOCATIONARBPROC __glewGetAttribLocationARB = NULL;
+
+PFNGLCOLORP3UIPROC __glewColorP3ui = NULL;
+PFNGLCOLORP3UIVPROC __glewColorP3uiv = NULL;
+PFNGLCOLORP4UIPROC __glewColorP4ui = NULL;
+PFNGLCOLORP4UIVPROC __glewColorP4uiv = NULL;
+PFNGLMULTITEXCOORDP1UIPROC __glewMultiTexCoordP1ui = NULL;
+PFNGLMULTITEXCOORDP1UIVPROC __glewMultiTexCoordP1uiv = NULL;
+PFNGLMULTITEXCOORDP2UIPROC __glewMultiTexCoordP2ui = NULL;
+PFNGLMULTITEXCOORDP2UIVPROC __glewMultiTexCoordP2uiv = NULL;
+PFNGLMULTITEXCOORDP3UIPROC __glewMultiTexCoordP3ui = NULL;
+PFNGLMULTITEXCOORDP3UIVPROC __glewMultiTexCoordP3uiv = NULL;
+PFNGLMULTITEXCOORDP4UIPROC __glewMultiTexCoordP4ui = NULL;
+PFNGLMULTITEXCOORDP4UIVPROC __glewMultiTexCoordP4uiv = NULL;
+PFNGLNORMALP3UIPROC __glewNormalP3ui = NULL;
+PFNGLNORMALP3UIVPROC __glewNormalP3uiv = NULL;
+PFNGLSECONDARYCOLORP3UIPROC __glewSecondaryColorP3ui = NULL;
+PFNGLSECONDARYCOLORP3UIVPROC __glewSecondaryColorP3uiv = NULL;
+PFNGLTEXCOORDP1UIPROC __glewTexCoordP1ui = NULL;
+PFNGLTEXCOORDP1UIVPROC __glewTexCoordP1uiv = NULL;
+PFNGLTEXCOORDP2UIPROC __glewTexCoordP2ui = NULL;
+PFNGLTEXCOORDP2UIVPROC __glewTexCoordP2uiv = NULL;
+PFNGLTEXCOORDP3UIPROC __glewTexCoordP3ui = NULL;
+PFNGLTEXCOORDP3UIVPROC __glewTexCoordP3uiv = NULL;
+PFNGLTEXCOORDP4UIPROC __glewTexCoordP4ui = NULL;
+PFNGLTEXCOORDP4UIVPROC __glewTexCoordP4uiv = NULL;
+PFNGLVERTEXATTRIBP1UIPROC __glewVertexAttribP1ui = NULL;
+PFNGLVERTEXATTRIBP1UIVPROC __glewVertexAttribP1uiv = NULL;
+PFNGLVERTEXATTRIBP2UIPROC __glewVertexAttribP2ui = NULL;
+PFNGLVERTEXATTRIBP2UIVPROC __glewVertexAttribP2uiv = NULL;
+PFNGLVERTEXATTRIBP3UIPROC __glewVertexAttribP3ui = NULL;
+PFNGLVERTEXATTRIBP3UIVPROC __glewVertexAttribP3uiv = NULL;
+PFNGLVERTEXATTRIBP4UIPROC __glewVertexAttribP4ui = NULL;
+PFNGLVERTEXATTRIBP4UIVPROC __glewVertexAttribP4uiv = NULL;
+PFNGLVERTEXP2UIPROC __glewVertexP2ui = NULL;
+PFNGLVERTEXP2UIVPROC __glewVertexP2uiv = NULL;
+PFNGLVERTEXP3UIPROC __glewVertexP3ui = NULL;
+PFNGLVERTEXP3UIVPROC __glewVertexP3uiv = NULL;
+PFNGLVERTEXP4UIPROC __glewVertexP4ui = NULL;
+PFNGLVERTEXP4UIVPROC __glewVertexP4uiv = NULL;
+
+PFNGLDEPTHRANGEARRAYVPROC __glewDepthRangeArrayv = NULL;
+PFNGLDEPTHRANGEINDEXEDPROC __glewDepthRangeIndexed = NULL;
+PFNGLGETDOUBLEI_VPROC __glewGetDoublei_v = NULL;
+PFNGLGETFLOATI_VPROC __glewGetFloati_v = NULL;
+PFNGLSCISSORARRAYVPROC __glewScissorArrayv = NULL;
+PFNGLSCISSORINDEXEDPROC __glewScissorIndexed = NULL;
+PFNGLSCISSORINDEXEDVPROC __glewScissorIndexedv = NULL;
+PFNGLVIEWPORTARRAYVPROC __glewViewportArrayv = NULL;
+PFNGLVIEWPORTINDEXEDFPROC __glewViewportIndexedf = NULL;
+PFNGLVIEWPORTINDEXEDFVPROC __glewViewportIndexedfv = NULL;
+
+PFNGLWINDOWPOS2DARBPROC __glewWindowPos2dARB = NULL;
+PFNGLWINDOWPOS2DVARBPROC __glewWindowPos2dvARB = NULL;
+PFNGLWINDOWPOS2FARBPROC __glewWindowPos2fARB = NULL;
+PFNGLWINDOWPOS2FVARBPROC __glewWindowPos2fvARB = NULL;
+PFNGLWINDOWPOS2IARBPROC __glewWindowPos2iARB = NULL;
+PFNGLWINDOWPOS2IVARBPROC __glewWindowPos2ivARB = NULL;
+PFNGLWINDOWPOS2SARBPROC __glewWindowPos2sARB = NULL;
+PFNGLWINDOWPOS2SVARBPROC __glewWindowPos2svARB = NULL;
+PFNGLWINDOWPOS3DARBPROC __glewWindowPos3dARB = NULL;
+PFNGLWINDOWPOS3DVARBPROC __glewWindowPos3dvARB = NULL;
+PFNGLWINDOWPOS3FARBPROC __glewWindowPos3fARB = NULL;
+PFNGLWINDOWPOS3FVARBPROC __glewWindowPos3fvARB = NULL;
+PFNGLWINDOWPOS3IARBPROC __glewWindowPos3iARB = NULL;
+PFNGLWINDOWPOS3IVARBPROC __glewWindowPos3ivARB = NULL;
+PFNGLWINDOWPOS3SARBPROC __glewWindowPos3sARB = NULL;
+PFNGLWINDOWPOS3SVARBPROC __glewWindowPos3svARB = NULL;
+
+PFNGLDRAWBUFFERSATIPROC __glewDrawBuffersATI = NULL;
+
+PFNGLDRAWELEMENTARRAYATIPROC __glewDrawElementArrayATI = NULL;
+PFNGLDRAWRANGEELEMENTARRAYATIPROC __glewDrawRangeElementArrayATI = NULL;
+PFNGLELEMENTPOINTERATIPROC __glewElementPointerATI = NULL;
+
+PFNGLGETTEXBUMPPARAMETERFVATIPROC __glewGetTexBumpParameterfvATI = NULL;
+PFNGLGETTEXBUMPPARAMETERIVATIPROC __glewGetTexBumpParameterivATI = NULL;
+PFNGLTEXBUMPPARAMETERFVATIPROC __glewTexBumpParameterfvATI = NULL;
+PFNGLTEXBUMPPARAMETERIVATIPROC __glewTexBumpParameterivATI = NULL;
+
+PFNGLALPHAFRAGMENTOP1ATIPROC __glewAlphaFragmentOp1ATI = NULL;
+PFNGLALPHAFRAGMENTOP2ATIPROC __glewAlphaFragmentOp2ATI = NULL;
+PFNGLALPHAFRAGMENTOP3ATIPROC __glewAlphaFragmentOp3ATI = NULL;
+PFNGLBEGINFRAGMENTSHADERATIPROC __glewBeginFragmentShaderATI = NULL;
+PFNGLBINDFRAGMENTSHADERATIPROC __glewBindFragmentShaderATI = NULL;
+PFNGLCOLORFRAGMENTOP1ATIPROC __glewColorFragmentOp1ATI = NULL;
+PFNGLCOLORFRAGMENTOP2ATIPROC __glewColorFragmentOp2ATI = NULL;
+PFNGLCOLORFRAGMENTOP3ATIPROC __glewColorFragmentOp3ATI = NULL;
+PFNGLDELETEFRAGMENTSHADERATIPROC __glewDeleteFragmentShaderATI = NULL;
+PFNGLENDFRAGMENTSHADERATIPROC __glewEndFragmentShaderATI = NULL;
+PFNGLGENFRAGMENTSHADERSATIPROC __glewGenFragmentShadersATI = NULL;
+PFNGLPASSTEXCOORDATIPROC __glewPassTexCoordATI = NULL;
+PFNGLSAMPLEMAPATIPROC __glewSampleMapATI = NULL;
+PFNGLSETFRAGMENTSHADERCONSTANTATIPROC __glewSetFragmentShaderConstantATI = NULL;
+
+PFNGLMAPOBJECTBUFFERATIPROC __glewMapObjectBufferATI = NULL;
+PFNGLUNMAPOBJECTBUFFERATIPROC __glewUnmapObjectBufferATI = NULL;
+
+PFNGLPNTRIANGLESFATIPROC __glewPNTrianglesfATI = NULL;
+PFNGLPNTRIANGLESIATIPROC __glewPNTrianglesiATI = NULL;
+
+PFNGLSTENCILFUNCSEPARATEATIPROC __glewStencilFuncSeparateATI = NULL;
+PFNGLSTENCILOPSEPARATEATIPROC __glewStencilOpSeparateATI = NULL;
+
+PFNGLARRAYOBJECTATIPROC __glewArrayObjectATI = NULL;
+PFNGLFREEOBJECTBUFFERATIPROC __glewFreeObjectBufferATI = NULL;
+PFNGLGETARRAYOBJECTFVATIPROC __glewGetArrayObjectfvATI = NULL;
+PFNGLGETARRAYOBJECTIVATIPROC __glewGetArrayObjectivATI = NULL;
+PFNGLGETOBJECTBUFFERFVATIPROC __glewGetObjectBufferfvATI = NULL;
+PFNGLGETOBJECTBUFFERIVATIPROC __glewGetObjectBufferivATI = NULL;
+PFNGLGETVARIANTARRAYOBJECTFVATIPROC __glewGetVariantArrayObjectfvATI = NULL;
+PFNGLGETVARIANTARRAYOBJECTIVATIPROC __glewGetVariantArrayObjectivATI = NULL;
+PFNGLISOBJECTBUFFERATIPROC __glewIsObjectBufferATI = NULL;
+PFNGLNEWOBJECTBUFFERATIPROC __glewNewObjectBufferATI = NULL;
+PFNGLUPDATEOBJECTBUFFERATIPROC __glewUpdateObjectBufferATI = NULL;
+PFNGLVARIANTARRAYOBJECTATIPROC __glewVariantArrayObjectATI = NULL;
+
+PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC __glewGetVertexAttribArrayObjectfvATI = NULL;
+PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC __glewGetVertexAttribArrayObjectivATI = NULL;
+PFNGLVERTEXATTRIBARRAYOBJECTATIPROC __glewVertexAttribArrayObjectATI = NULL;
+
+PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC __glewClientActiveVertexStreamATI = NULL;
+PFNGLNORMALSTREAM3BATIPROC __glewNormalStream3bATI = NULL;
+PFNGLNORMALSTREAM3BVATIPROC __glewNormalStream3bvATI = NULL;
+PFNGLNORMALSTREAM3DATIPROC __glewNormalStream3dATI = NULL;
+PFNGLNORMALSTREAM3DVATIPROC __glewNormalStream3dvATI = NULL;
+PFNGLNORMALSTREAM3FATIPROC __glewNormalStream3fATI = NULL;
+PFNGLNORMALSTREAM3FVATIPROC __glewNormalStream3fvATI = NULL;
+PFNGLNORMALSTREAM3IATIPROC __glewNormalStream3iATI = NULL;
+PFNGLNORMALSTREAM3IVATIPROC __glewNormalStream3ivATI = NULL;
+PFNGLNORMALSTREAM3SATIPROC __glewNormalStream3sATI = NULL;
+PFNGLNORMALSTREAM3SVATIPROC __glewNormalStream3svATI = NULL;
+PFNGLVERTEXBLENDENVFATIPROC __glewVertexBlendEnvfATI = NULL;
+PFNGLVERTEXBLENDENVIATIPROC __glewVertexBlendEnviATI = NULL;
+PFNGLVERTEXSTREAM1DATIPROC __glewVertexStream1dATI = NULL;
+PFNGLVERTEXSTREAM1DVATIPROC __glewVertexStream1dvATI = NULL;
+PFNGLVERTEXSTREAM1FATIPROC __glewVertexStream1fATI = NULL;
+PFNGLVERTEXSTREAM1FVATIPROC __glewVertexStream1fvATI = NULL;
+PFNGLVERTEXSTREAM1IATIPROC __glewVertexStream1iATI = NULL;
+PFNGLVERTEXSTREAM1IVATIPROC __glewVertexStream1ivATI = NULL;
+PFNGLVERTEXSTREAM1SATIPROC __glewVertexStream1sATI = NULL;
+PFNGLVERTEXSTREAM1SVATIPROC __glewVertexStream1svATI = NULL;
+PFNGLVERTEXSTREAM2DATIPROC __glewVertexStream2dATI = NULL;
+PFNGLVERTEXSTREAM2DVATIPROC __glewVertexStream2dvATI = NULL;
+PFNGLVERTEXSTREAM2FATIPROC __glewVertexStream2fATI = NULL;
+PFNGLVERTEXSTREAM2FVATIPROC __glewVertexStream2fvATI = NULL;
+PFNGLVERTEXSTREAM2IATIPROC __glewVertexStream2iATI = NULL;
+PFNGLVERTEXSTREAM2IVATIPROC __glewVertexStream2ivATI = NULL;
+PFNGLVERTEXSTREAM2SATIPROC __glewVertexStream2sATI = NULL;
+PFNGLVERTEXSTREAM2SVATIPROC __glewVertexStream2svATI = NULL;
+PFNGLVERTEXSTREAM3DATIPROC __glewVertexStream3dATI = NULL;
+PFNGLVERTEXSTREAM3DVATIPROC __glewVertexStream3dvATI = NULL;
+PFNGLVERTEXSTREAM3FATIPROC __glewVertexStream3fATI = NULL;
+PFNGLVERTEXSTREAM3FVATIPROC __glewVertexStream3fvATI = NULL;
+PFNGLVERTEXSTREAM3IATIPROC __glewVertexStream3iATI = NULL;
+PFNGLVERTEXSTREAM3IVATIPROC __glewVertexStream3ivATI = NULL;
+PFNGLVERTEXSTREAM3SATIPROC __glewVertexStream3sATI = NULL;
+PFNGLVERTEXSTREAM3SVATIPROC __glewVertexStream3svATI = NULL;
+PFNGLVERTEXSTREAM4DATIPROC __glewVertexStream4dATI = NULL;
+PFNGLVERTEXSTREAM4DVATIPROC __glewVertexStream4dvATI = NULL;
+PFNGLVERTEXSTREAM4FATIPROC __glewVertexStream4fATI = NULL;
+PFNGLVERTEXSTREAM4FVATIPROC __glewVertexStream4fvATI = NULL;
+PFNGLVERTEXSTREAM4IATIPROC __glewVertexStream4iATI = NULL;
+PFNGLVERTEXSTREAM4IVATIPROC __glewVertexStream4ivATI = NULL;
+PFNGLVERTEXSTREAM4SATIPROC __glewVertexStream4sATI = NULL;
+PFNGLVERTEXSTREAM4SVATIPROC __glewVertexStream4svATI = NULL;
+
+PFNGLGETUNIFORMBUFFERSIZEEXTPROC __glewGetUniformBufferSizeEXT = NULL;
+PFNGLGETUNIFORMOFFSETEXTPROC __glewGetUniformOffsetEXT = NULL;
+PFNGLUNIFORMBUFFEREXTPROC __glewUniformBufferEXT = NULL;
+
+PFNGLBLENDCOLOREXTPROC __glewBlendColorEXT = NULL;
+
+PFNGLBLENDEQUATIONSEPARATEEXTPROC __glewBlendEquationSeparateEXT = NULL;
+
+PFNGLBLENDFUNCSEPARATEEXTPROC __glewBlendFuncSeparateEXT = NULL;
+
+PFNGLBLENDEQUATIONEXTPROC __glewBlendEquationEXT = NULL;
+
+PFNGLCOLORSUBTABLEEXTPROC __glewColorSubTableEXT = NULL;
+PFNGLCOPYCOLORSUBTABLEEXTPROC __glewCopyColorSubTableEXT = NULL;
+
+PFNGLLOCKARRAYSEXTPROC __glewLockArraysEXT = NULL;
+PFNGLUNLOCKARRAYSEXTPROC __glewUnlockArraysEXT = NULL;
+
+PFNGLCONVOLUTIONFILTER1DEXTPROC __glewConvolutionFilter1DEXT = NULL;
+PFNGLCONVOLUTIONFILTER2DEXTPROC __glewConvolutionFilter2DEXT = NULL;
+PFNGLCONVOLUTIONPARAMETERFEXTPROC __glewConvolutionParameterfEXT = NULL;
+PFNGLCONVOLUTIONPARAMETERFVEXTPROC __glewConvolutionParameterfvEXT = NULL;
+PFNGLCONVOLUTIONPARAMETERIEXTPROC __glewConvolutionParameteriEXT = NULL;
+PFNGLCONVOLUTIONPARAMETERIVEXTPROC __glewConvolutionParameterivEXT = NULL;
+PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC __glewCopyConvolutionFilter1DEXT = NULL;
+PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC __glewCopyConvolutionFilter2DEXT = NULL;
+PFNGLGETCONVOLUTIONFILTEREXTPROC __glewGetConvolutionFilterEXT = NULL;
+PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC __glewGetConvolutionParameterfvEXT = NULL;
+PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC __glewGetConvolutionParameterivEXT = NULL;
+PFNGLGETSEPARABLEFILTEREXTPROC __glewGetSeparableFilterEXT = NULL;
+PFNGLSEPARABLEFILTER2DEXTPROC __glewSeparableFilter2DEXT = NULL;
+
+PFNGLBINORMALPOINTEREXTPROC __glewBinormalPointerEXT = NULL;
+PFNGLTANGENTPOINTEREXTPROC __glewTangentPointerEXT = NULL;
+
+PFNGLCOPYTEXIMAGE1DEXTPROC __glewCopyTexImage1DEXT = NULL;
+PFNGLCOPYTEXIMAGE2DEXTPROC __glewCopyTexImage2DEXT = NULL;
+PFNGLCOPYTEXSUBIMAGE1DEXTPROC __glewCopyTexSubImage1DEXT = NULL;
+PFNGLCOPYTEXSUBIMAGE2DEXTPROC __glewCopyTexSubImage2DEXT = NULL;
+PFNGLCOPYTEXSUBIMAGE3DEXTPROC __glewCopyTexSubImage3DEXT = NULL;
+
+PFNGLCULLPARAMETERDVEXTPROC __glewCullParameterdvEXT = NULL;
+PFNGLCULLPARAMETERFVEXTPROC __glewCullParameterfvEXT = NULL;
+
+PFNGLINSERTEVENTMARKEREXTPROC __glewInsertEventMarkerEXT = NULL;
+PFNGLPOPGROUPMARKEREXTPROC __glewPopGroupMarkerEXT = NULL;
+PFNGLPUSHGROUPMARKEREXTPROC __glewPushGroupMarkerEXT = NULL;
+
+PFNGLDEPTHBOUNDSEXTPROC __glewDepthBoundsEXT = NULL;
+
+PFNGLBINDMULTITEXTUREEXTPROC __glewBindMultiTextureEXT = NULL;
+PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC __glewCheckNamedFramebufferStatusEXT = NULL;
+PFNGLCLIENTATTRIBDEFAULTEXTPROC __glewClientAttribDefaultEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC __glewCompressedMultiTexImage1DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC __glewCompressedMultiTexImage2DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC __glewCompressedMultiTexImage3DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC __glewCompressedMultiTexSubImage1DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC __glewCompressedMultiTexSubImage2DEXT = NULL;
+PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC __glewCompressedMultiTexSubImage3DEXT = NULL;
+PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC __glewCompressedTextureImage1DEXT = NULL;
+PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC __glewCompressedTextureImage2DEXT = NULL;
+PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC __glewCompressedTextureImage3DEXT = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC __glewCompressedTextureSubImage1DEXT = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC __glewCompressedTextureSubImage2DEXT = NULL;
+PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC __glewCompressedTextureSubImage3DEXT = NULL;
+PFNGLCOPYMULTITEXIMAGE1DEXTPROC __glewCopyMultiTexImage1DEXT = NULL;
+PFNGLCOPYMULTITEXIMAGE2DEXTPROC __glewCopyMultiTexImage2DEXT = NULL;
+PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC __glewCopyMultiTexSubImage1DEXT = NULL;
+PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC __glewCopyMultiTexSubImage2DEXT = NULL;
+PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC __glewCopyMultiTexSubImage3DEXT = NULL;
+PFNGLCOPYTEXTUREIMAGE1DEXTPROC __glewCopyTextureImage1DEXT = NULL;
+PFNGLCOPYTEXTUREIMAGE2DEXTPROC __glewCopyTextureImage2DEXT = NULL;
+PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC __glewCopyTextureSubImage1DEXT = NULL;
+PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC __glewCopyTextureSubImage2DEXT = NULL;
+PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC __glewCopyTextureSubImage3DEXT = NULL;
+PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC __glewDisableClientStateIndexedEXT = NULL;
+PFNGLDISABLECLIENTSTATEIEXTPROC __glewDisableClientStateiEXT = NULL;
+PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC __glewDisableVertexArrayAttribEXT = NULL;
+PFNGLDISABLEVERTEXARRAYEXTPROC __glewDisableVertexArrayEXT = NULL;
+PFNGLENABLECLIENTSTATEINDEXEDEXTPROC __glewEnableClientStateIndexedEXT = NULL;
+PFNGLENABLECLIENTSTATEIEXTPROC __glewEnableClientStateiEXT = NULL;
+PFNGLENABLEVERTEXARRAYATTRIBEXTPROC __glewEnableVertexArrayAttribEXT = NULL;
+PFNGLENABLEVERTEXARRAYEXTPROC __glewEnableVertexArrayEXT = NULL;
+PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC __glewFlushMappedNamedBufferRangeEXT = NULL;
+PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC __glewFramebufferDrawBufferEXT = NULL;
+PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC __glewFramebufferDrawBuffersEXT = NULL;
+PFNGLFRAMEBUFFERREADBUFFEREXTPROC __glewFramebufferReadBufferEXT = NULL;
+PFNGLGENERATEMULTITEXMIPMAPEXTPROC __glewGenerateMultiTexMipmapEXT = NULL;
+PFNGLGENERATETEXTUREMIPMAPEXTPROC __glewGenerateTextureMipmapEXT = NULL;
+PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC __glewGetCompressedMultiTexImageEXT = NULL;
+PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC __glewGetCompressedTextureImageEXT = NULL;
+PFNGLGETDOUBLEINDEXEDVEXTPROC __glewGetDoubleIndexedvEXT = NULL;
+PFNGLGETDOUBLEI_VEXTPROC __glewGetDoublei_vEXT = NULL;
+PFNGLGETFLOATINDEXEDVEXTPROC __glewGetFloatIndexedvEXT = NULL;
+PFNGLGETFLOATI_VEXTPROC __glewGetFloati_vEXT = NULL;
+PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC __glewGetFramebufferParameterivEXT = NULL;
+PFNGLGETMULTITEXENVFVEXTPROC __glewGetMultiTexEnvfvEXT = NULL;
+PFNGLGETMULTITEXENVIVEXTPROC __glewGetMultiTexEnvivEXT = NULL;
+PFNGLGETMULTITEXGENDVEXTPROC __glewGetMultiTexGendvEXT = NULL;
+PFNGLGETMULTITEXGENFVEXTPROC __glewGetMultiTexGenfvEXT = NULL;
+PFNGLGETMULTITEXGENIVEXTPROC __glewGetMultiTexGenivEXT = NULL;
+PFNGLGETMULTITEXIMAGEEXTPROC __glewGetMultiTexImageEXT = NULL;
+PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC __glewGetMultiTexLevelParameterfvEXT = NULL;
+PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC __glewGetMultiTexLevelParameterivEXT = NULL;
+PFNGLGETMULTITEXPARAMETERIIVEXTPROC __glewGetMultiTexParameterIivEXT = NULL;
+PFNGLGETMULTITEXPARAMETERIUIVEXTPROC __glewGetMultiTexParameterIuivEXT = NULL;
+PFNGLGETMULTITEXPARAMETERFVEXTPROC __glewGetMultiTexParameterfvEXT = NULL;
+PFNGLGETMULTITEXPARAMETERIVEXTPROC __glewGetMultiTexParameterivEXT = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC __glewGetNamedBufferParameterivEXT = NULL;
+PFNGLGETNAMEDBUFFERPOINTERVEXTPROC __glewGetNamedBufferPointervEXT = NULL;
+PFNGLGETNAMEDBUFFERSUBDATAEXTPROC __glewGetNamedBufferSubDataEXT = NULL;
+PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetNamedFramebufferAttachmentParameterivEXT = NULL;
+PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC __glewGetNamedProgramLocalParameterIivEXT = NULL;
+PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC __glewGetNamedProgramLocalParameterIuivEXT = NULL;
+PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC __glewGetNamedProgramLocalParameterdvEXT = NULL;
+PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC __glewGetNamedProgramLocalParameterfvEXT = NULL;
+PFNGLGETNAMEDPROGRAMSTRINGEXTPROC __glewGetNamedProgramStringEXT = NULL;
+PFNGLGETNAMEDPROGRAMIVEXTPROC __glewGetNamedProgramivEXT = NULL;
+PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC __glewGetNamedRenderbufferParameterivEXT = NULL;
+PFNGLGETPOINTERINDEXEDVEXTPROC __glewGetPointerIndexedvEXT = NULL;
+PFNGLGETPOINTERI_VEXTPROC __glewGetPointeri_vEXT = NULL;
+PFNGLGETTEXTUREIMAGEEXTPROC __glewGetTextureImageEXT = NULL;
+PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC __glewGetTextureLevelParameterfvEXT = NULL;
+PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC __glewGetTextureLevelParameterivEXT = NULL;
+PFNGLGETTEXTUREPARAMETERIIVEXTPROC __glewGetTextureParameterIivEXT = NULL;
+PFNGLGETTEXTUREPARAMETERIUIVEXTPROC __glewGetTextureParameterIuivEXT = NULL;
+PFNGLGETTEXTUREPARAMETERFVEXTPROC __glewGetTextureParameterfvEXT = NULL;
+PFNGLGETTEXTUREPARAMETERIVEXTPROC __glewGetTextureParameterivEXT = NULL;
+PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC __glewGetVertexArrayIntegeri_vEXT = NULL;
+PFNGLGETVERTEXARRAYINTEGERVEXTPROC __glewGetVertexArrayIntegervEXT = NULL;
+PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC __glewGetVertexArrayPointeri_vEXT = NULL;
+PFNGLGETVERTEXARRAYPOINTERVEXTPROC __glewGetVertexArrayPointervEXT = NULL;
+PFNGLMAPNAMEDBUFFEREXTPROC __glewMapNamedBufferEXT = NULL;
+PFNGLMAPNAMEDBUFFERRANGEEXTPROC __glewMapNamedBufferRangeEXT = NULL;
+PFNGLMATRIXFRUSTUMEXTPROC __glewMatrixFrustumEXT = NULL;
+PFNGLMATRIXLOADIDENTITYEXTPROC __glewMatrixLoadIdentityEXT = NULL;
+PFNGLMATRIXLOADTRANSPOSEDEXTPROC __glewMatrixLoadTransposedEXT = NULL;
+PFNGLMATRIXLOADTRANSPOSEFEXTPROC __glewMatrixLoadTransposefEXT = NULL;
+PFNGLMATRIXLOADDEXTPROC __glewMatrixLoaddEXT = NULL;
+PFNGLMATRIXLOADFEXTPROC __glewMatrixLoadfEXT = NULL;
+PFNGLMATRIXMULTTRANSPOSEDEXTPROC __glewMatrixMultTransposedEXT = NULL;
+PFNGLMATRIXMULTTRANSPOSEFEXTPROC __glewMatrixMultTransposefEXT = NULL;
+PFNGLMATRIXMULTDEXTPROC __glewMatrixMultdEXT = NULL;
+PFNGLMATRIXMULTFEXTPROC __glewMatrixMultfEXT = NULL;
+PFNGLMATRIXORTHOEXTPROC __glewMatrixOrthoEXT = NULL;
+PFNGLMATRIXPOPEXTPROC __glewMatrixPopEXT = NULL;
+PFNGLMATRIXPUSHEXTPROC __glewMatrixPushEXT = NULL;
+PFNGLMATRIXROTATEDEXTPROC __glewMatrixRotatedEXT = NULL;
+PFNGLMATRIXROTATEFEXTPROC __glewMatrixRotatefEXT = NULL;
+PFNGLMATRIXSCALEDEXTPROC __glewMatrixScaledEXT = NULL;
+PFNGLMATRIXSCALEFEXTPROC __glewMatrixScalefEXT = NULL;
+PFNGLMATRIXTRANSLATEDEXTPROC __glewMatrixTranslatedEXT = NULL;
+PFNGLMATRIXTRANSLATEFEXTPROC __glewMatrixTranslatefEXT = NULL;
+PFNGLMULTITEXBUFFEREXTPROC __glewMultiTexBufferEXT = NULL;
+PFNGLMULTITEXCOORDPOINTEREXTPROC __glewMultiTexCoordPointerEXT = NULL;
+PFNGLMULTITEXENVFEXTPROC __glewMultiTexEnvfEXT = NULL;
+PFNGLMULTITEXENVFVEXTPROC __glewMultiTexEnvfvEXT = NULL;
+PFNGLMULTITEXENVIEXTPROC __glewMultiTexEnviEXT = NULL;
+PFNGLMULTITEXENVIVEXTPROC __glewMultiTexEnvivEXT = NULL;
+PFNGLMULTITEXGENDEXTPROC __glewMultiTexGendEXT = NULL;
+PFNGLMULTITEXGENDVEXTPROC __glewMultiTexGendvEXT = NULL;
+PFNGLMULTITEXGENFEXTPROC __glewMultiTexGenfEXT = NULL;
+PFNGLMULTITEXGENFVEXTPROC __glewMultiTexGenfvEXT = NULL;
+PFNGLMULTITEXGENIEXTPROC __glewMultiTexGeniEXT = NULL;
+PFNGLMULTITEXGENIVEXTPROC __glewMultiTexGenivEXT = NULL;
+PFNGLMULTITEXIMAGE1DEXTPROC __glewMultiTexImage1DEXT = NULL;
+PFNGLMULTITEXIMAGE2DEXTPROC __glewMultiTexImage2DEXT = NULL;
+PFNGLMULTITEXIMAGE3DEXTPROC __glewMultiTexImage3DEXT = NULL;
+PFNGLMULTITEXPARAMETERIIVEXTPROC __glewMultiTexParameterIivEXT = NULL;
+PFNGLMULTITEXPARAMETERIUIVEXTPROC __glewMultiTexParameterIuivEXT = NULL;
+PFNGLMULTITEXPARAMETERFEXTPROC __glewMultiTexParameterfEXT = NULL;
+PFNGLMULTITEXPARAMETERFVEXTPROC __glewMultiTexParameterfvEXT = NULL;
+PFNGLMULTITEXPARAMETERIEXTPROC __glewMultiTexParameteriEXT = NULL;
+PFNGLMULTITEXPARAMETERIVEXTPROC __glewMultiTexParameterivEXT = NULL;
+PFNGLMULTITEXRENDERBUFFEREXTPROC __glewMultiTexRenderbufferEXT = NULL;
+PFNGLMULTITEXSUBIMAGE1DEXTPROC __glewMultiTexSubImage1DEXT = NULL;
+PFNGLMULTITEXSUBIMAGE2DEXTPROC __glewMultiTexSubImage2DEXT = NULL;
+PFNGLMULTITEXSUBIMAGE3DEXTPROC __glewMultiTexSubImage3DEXT = NULL;
+PFNGLNAMEDBUFFERDATAEXTPROC __glewNamedBufferDataEXT = NULL;
+PFNGLNAMEDBUFFERSUBDATAEXTPROC __glewNamedBufferSubDataEXT = NULL;
+PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC __glewNamedCopyBufferSubDataEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC __glewNamedFramebufferRenderbufferEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC __glewNamedFramebufferTexture1DEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC __glewNamedFramebufferTexture2DEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC __glewNamedFramebufferTexture3DEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC __glewNamedFramebufferTextureEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC __glewNamedFramebufferTextureFaceEXT = NULL;
+PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC __glewNamedFramebufferTextureLayerEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC __glewNamedProgramLocalParameter4dEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC __glewNamedProgramLocalParameter4dvEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC __glewNamedProgramLocalParameter4fEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC __glewNamedProgramLocalParameter4fvEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC __glewNamedProgramLocalParameterI4iEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC __glewNamedProgramLocalParameterI4ivEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC __glewNamedProgramLocalParameterI4uiEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC __glewNamedProgramLocalParameterI4uivEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC __glewNamedProgramLocalParameters4fvEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC __glewNamedProgramLocalParametersI4ivEXT = NULL;
+PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC __glewNamedProgramLocalParametersI4uivEXT = NULL;
+PFNGLNAMEDPROGRAMSTRINGEXTPROC __glewNamedProgramStringEXT = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC __glewNamedRenderbufferStorageEXT = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC __glewNamedRenderbufferStorageMultisampleCoverageEXT = NULL;
+PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewNamedRenderbufferStorageMultisampleEXT = NULL;
+PFNGLPROGRAMUNIFORM1FEXTPROC __glewProgramUniform1fEXT = NULL;
+PFNGLPROGRAMUNIFORM1FVEXTPROC __glewProgramUniform1fvEXT = NULL;
+PFNGLPROGRAMUNIFORM1IEXTPROC __glewProgramUniform1iEXT = NULL;
+PFNGLPROGRAMUNIFORM1IVEXTPROC __glewProgramUniform1ivEXT = NULL;
+PFNGLPROGRAMUNIFORM1UIEXTPROC __glewProgramUniform1uiEXT = NULL;
+PFNGLPROGRAMUNIFORM1UIVEXTPROC __glewProgramUniform1uivEXT = NULL;
+PFNGLPROGRAMUNIFORM2FEXTPROC __glewProgramUniform2fEXT = NULL;
+PFNGLPROGRAMUNIFORM2FVEXTPROC __glewProgramUniform2fvEXT = NULL;
+PFNGLPROGRAMUNIFORM2IEXTPROC __glewProgramUniform2iEXT = NULL;
+PFNGLPROGRAMUNIFORM2IVEXTPROC __glewProgramUniform2ivEXT = NULL;
+PFNGLPROGRAMUNIFORM2UIEXTPROC __glewProgramUniform2uiEXT = NULL;
+PFNGLPROGRAMUNIFORM2UIVEXTPROC __glewProgramUniform2uivEXT = NULL;
+PFNGLPROGRAMUNIFORM3FEXTPROC __glewProgramUniform3fEXT = NULL;
+PFNGLPROGRAMUNIFORM3FVEXTPROC __glewProgramUniform3fvEXT = NULL;
+PFNGLPROGRAMUNIFORM3IEXTPROC __glewProgramUniform3iEXT = NULL;
+PFNGLPROGRAMUNIFORM3IVEXTPROC __glewProgramUniform3ivEXT = NULL;
+PFNGLPROGRAMUNIFORM3UIEXTPROC __glewProgramUniform3uiEXT = NULL;
+PFNGLPROGRAMUNIFORM3UIVEXTPROC __glewProgramUniform3uivEXT = NULL;
+PFNGLPROGRAMUNIFORM4FEXTPROC __glewProgramUniform4fEXT = NULL;
+PFNGLPROGRAMUNIFORM4FVEXTPROC __glewProgramUniform4fvEXT = NULL;
+PFNGLPROGRAMUNIFORM4IEXTPROC __glewProgramUniform4iEXT = NULL;
+PFNGLPROGRAMUNIFORM4IVEXTPROC __glewProgramUniform4ivEXT = NULL;
+PFNGLPROGRAMUNIFORM4UIEXTPROC __glewProgramUniform4uiEXT = NULL;
+PFNGLPROGRAMUNIFORM4UIVEXTPROC __glewProgramUniform4uivEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC __glewProgramUniformMatrix2fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC __glewProgramUniformMatrix2x3fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC __glewProgramUniformMatrix2x4fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC __glewProgramUniformMatrix3fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC __glewProgramUniformMatrix3x2fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC __glewProgramUniformMatrix3x4fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC __glewProgramUniformMatrix4fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC __glewProgramUniformMatrix4x2fvEXT = NULL;
+PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC __glewProgramUniformMatrix4x3fvEXT = NULL;
+PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC __glewPushClientAttribDefaultEXT = NULL;
+PFNGLTEXTUREBUFFEREXTPROC __glewTextureBufferEXT = NULL;
+PFNGLTEXTUREIMAGE1DEXTPROC __glewTextureImage1DEXT = NULL;
+PFNGLTEXTUREIMAGE2DEXTPROC __glewTextureImage2DEXT = NULL;
+PFNGLTEXTUREIMAGE3DEXTPROC __glewTextureImage3DEXT = NULL;
+PFNGLTEXTUREPARAMETERIIVEXTPROC __glewTextureParameterIivEXT = NULL;
+PFNGLTEXTUREPARAMETERIUIVEXTPROC __glewTextureParameterIuivEXT = NULL;
+PFNGLTEXTUREPARAMETERFEXTPROC __glewTextureParameterfEXT = NULL;
+PFNGLTEXTUREPARAMETERFVEXTPROC __glewTextureParameterfvEXT = NULL;
+PFNGLTEXTUREPARAMETERIEXTPROC __glewTextureParameteriEXT = NULL;
+PFNGLTEXTUREPARAMETERIVEXTPROC __glewTextureParameterivEXT = NULL;
+PFNGLTEXTURERENDERBUFFEREXTPROC __glewTextureRenderbufferEXT = NULL;
+PFNGLTEXTURESUBIMAGE1DEXTPROC __glewTextureSubImage1DEXT = NULL;
+PFNGLTEXTURESUBIMAGE2DEXTPROC __glewTextureSubImage2DEXT = NULL;
+PFNGLTEXTURESUBIMAGE3DEXTPROC __glewTextureSubImage3DEXT = NULL;
+PFNGLUNMAPNAMEDBUFFEREXTPROC __glewUnmapNamedBufferEXT = NULL;
+PFNGLVERTEXARRAYCOLOROFFSETEXTPROC __glewVertexArrayColorOffsetEXT = NULL;
+PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC __glewVertexArrayEdgeFlagOffsetEXT = NULL;
+PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC __glewVertexArrayFogCoordOffsetEXT = NULL;
+PFNGLVERTEXARRAYINDEXOFFSETEXTPROC __glewVertexArrayIndexOffsetEXT = NULL;
+PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC __glewVertexArrayMultiTexCoordOffsetEXT = NULL;
+PFNGLVERTEXARRAYNORMALOFFSETEXTPROC __glewVertexArrayNormalOffsetEXT = NULL;
+PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC __glewVertexArraySecondaryColorOffsetEXT = NULL;
+PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC __glewVertexArrayTexCoordOffsetEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC __glewVertexArrayVertexAttribIOffsetEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC __glewVertexArrayVertexAttribOffsetEXT = NULL;
+PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC __glewVertexArrayVertexOffsetEXT = NULL;
+
+PFNGLCOLORMASKINDEXEDEXTPROC __glewColorMaskIndexedEXT = NULL;
+PFNGLDISABLEINDEXEDEXTPROC __glewDisableIndexedEXT = NULL;
+PFNGLENABLEINDEXEDEXTPROC __glewEnableIndexedEXT = NULL;
+PFNGLGETBOOLEANINDEXEDVEXTPROC __glewGetBooleanIndexedvEXT = NULL;
+PFNGLGETINTEGERINDEXEDVEXTPROC __glewGetIntegerIndexedvEXT = NULL;
+PFNGLISENABLEDINDEXEDEXTPROC __glewIsEnabledIndexedEXT = NULL;
+
+PFNGLDRAWARRAYSINSTANCEDEXTPROC __glewDrawArraysInstancedEXT = NULL;
+PFNGLDRAWELEMENTSINSTANCEDEXTPROC __glewDrawElementsInstancedEXT = NULL;
+
+PFNGLDRAWRANGEELEMENTSEXTPROC __glewDrawRangeElementsEXT = NULL;
+
+PFNGLFOGCOORDPOINTEREXTPROC __glewFogCoordPointerEXT = NULL;
+PFNGLFOGCOORDDEXTPROC __glewFogCoorddEXT = NULL;
+PFNGLFOGCOORDDVEXTPROC __glewFogCoorddvEXT = NULL;
+PFNGLFOGCOORDFEXTPROC __glewFogCoordfEXT = NULL;
+PFNGLFOGCOORDFVEXTPROC __glewFogCoordfvEXT = NULL;
+
+PFNGLFRAGMENTCOLORMATERIALEXTPROC __glewFragmentColorMaterialEXT = NULL;
+PFNGLFRAGMENTLIGHTMODELFEXTPROC __glewFragmentLightModelfEXT = NULL;
+PFNGLFRAGMENTLIGHTMODELFVEXTPROC __glewFragmentLightModelfvEXT = NULL;
+PFNGLFRAGMENTLIGHTMODELIEXTPROC __glewFragmentLightModeliEXT = NULL;
+PFNGLFRAGMENTLIGHTMODELIVEXTPROC __glewFragmentLightModelivEXT = NULL;
+PFNGLFRAGMENTLIGHTFEXTPROC __glewFragmentLightfEXT = NULL;
+PFNGLFRAGMENTLIGHTFVEXTPROC __glewFragmentLightfvEXT = NULL;
+PFNGLFRAGMENTLIGHTIEXTPROC __glewFragmentLightiEXT = NULL;
+PFNGLFRAGMENTLIGHTIVEXTPROC __glewFragmentLightivEXT = NULL;
+PFNGLFRAGMENTMATERIALFEXTPROC __glewFragmentMaterialfEXT = NULL;
+PFNGLFRAGMENTMATERIALFVEXTPROC __glewFragmentMaterialfvEXT = NULL;
+PFNGLFRAGMENTMATERIALIEXTPROC __glewFragmentMaterialiEXT = NULL;
+PFNGLFRAGMENTMATERIALIVEXTPROC __glewFragmentMaterialivEXT = NULL;
+PFNGLGETFRAGMENTLIGHTFVEXTPROC __glewGetFragmentLightfvEXT = NULL;
+PFNGLGETFRAGMENTLIGHTIVEXTPROC __glewGetFragmentLightivEXT = NULL;
+PFNGLGETFRAGMENTMATERIALFVEXTPROC __glewGetFragmentMaterialfvEXT = NULL;
+PFNGLGETFRAGMENTMATERIALIVEXTPROC __glewGetFragmentMaterialivEXT = NULL;
+PFNGLLIGHTENVIEXTPROC __glewLightEnviEXT = NULL;
+
+PFNGLBLITFRAMEBUFFEREXTPROC __glewBlitFramebufferEXT = NULL;
+
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC __glewRenderbufferStorageMultisampleEXT = NULL;
+
+PFNGLBINDFRAMEBUFFEREXTPROC __glewBindFramebufferEXT = NULL;
+PFNGLBINDRENDERBUFFEREXTPROC __glewBindRenderbufferEXT = NULL;
+PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC __glewCheckFramebufferStatusEXT = NULL;
+PFNGLDELETEFRAMEBUFFERSEXTPROC __glewDeleteFramebuffersEXT = NULL;
+PFNGLDELETERENDERBUFFERSEXTPROC __glewDeleteRenderbuffersEXT = NULL;
+PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC __glewFramebufferRenderbufferEXT = NULL;
+PFNGLFRAMEBUFFERTEXTURE1DEXTPROC __glewFramebufferTexture1DEXT = NULL;
+PFNGLFRAMEBUFFERTEXTURE2DEXTPROC __glewFramebufferTexture2DEXT = NULL;
+PFNGLFRAMEBUFFERTEXTURE3DEXTPROC __glewFramebufferTexture3DEXT = NULL;
+PFNGLGENFRAMEBUFFERSEXTPROC __glewGenFramebuffersEXT = NULL;
+PFNGLGENRENDERBUFFERSEXTPROC __glewGenRenderbuffersEXT = NULL;
+PFNGLGENERATEMIPMAPEXTPROC __glewGenerateMipmapEXT = NULL;
+PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC __glewGetFramebufferAttachmentParameterivEXT = NULL;
+PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC __glewGetRenderbufferParameterivEXT = NULL;
+PFNGLISFRAMEBUFFEREXTPROC __glewIsFramebufferEXT = NULL;
+PFNGLISRENDERBUFFEREXTPROC __glewIsRenderbufferEXT = NULL;
+PFNGLRENDERBUFFERSTORAGEEXTPROC __glewRenderbufferStorageEXT = NULL;
+
+PFNGLFRAMEBUFFERTEXTUREEXTPROC __glewFramebufferTextureEXT = NULL;
+PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC __glewFramebufferTextureFaceEXT = NULL;
+PFNGLPROGRAMPARAMETERIEXTPROC __glewProgramParameteriEXT = NULL;
+
+PFNGLPROGRAMENVPARAMETERS4FVEXTPROC __glewProgramEnvParameters4fvEXT = NULL;
+PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC __glewProgramLocalParameters4fvEXT = NULL;
+
+PFNGLBINDFRAGDATALOCATIONEXTPROC __glewBindFragDataLocationEXT = NULL;
+PFNGLGETFRAGDATALOCATIONEXTPROC __glewGetFragDataLocationEXT = NULL;
+PFNGLGETUNIFORMUIVEXTPROC __glewGetUniformuivEXT = NULL;
+PFNGLGETVERTEXATTRIBIIVEXTPROC __glewGetVertexAttribIivEXT = NULL;
+PFNGLGETVERTEXATTRIBIUIVEXTPROC __glewGetVertexAttribIuivEXT = NULL;
+PFNGLUNIFORM1UIEXTPROC __glewUniform1uiEXT = NULL;
+PFNGLUNIFORM1UIVEXTPROC __glewUniform1uivEXT = NULL;
+PFNGLUNIFORM2UIEXTPROC __glewUniform2uiEXT = NULL;
+PFNGLUNIFORM2UIVEXTPROC __glewUniform2uivEXT = NULL;
+PFNGLUNIFORM3UIEXTPROC __glewUniform3uiEXT = NULL;
+PFNGLUNIFORM3UIVEXTPROC __glewUniform3uivEXT = NULL;
+PFNGLUNIFORM4UIEXTPROC __glewUniform4uiEXT = NULL;
+PFNGLUNIFORM4UIVEXTPROC __glewUniform4uivEXT = NULL;
+PFNGLVERTEXATTRIBI1IEXTPROC __glewVertexAttribI1iEXT = NULL;
+PFNGLVERTEXATTRIBI1IVEXTPROC __glewVertexAttribI1ivEXT = NULL;
+PFNGLVERTEXATTRIBI1UIEXTPROC __glewVertexAttribI1uiEXT = NULL;
+PFNGLVERTEXATTRIBI1UIVEXTPROC __glewVertexAttribI1uivEXT = NULL;
+PFNGLVERTEXATTRIBI2IEXTPROC __glewVertexAttribI2iEXT = NULL;
+PFNGLVERTEXATTRIBI2IVEXTPROC __glewVertexAttribI2ivEXT = NULL;
+PFNGLVERTEXATTRIBI2UIEXTPROC __glewVertexAttribI2uiEXT = NULL;
+PFNGLVERTEXATTRIBI2UIVEXTPROC __glewVertexAttribI2uivEXT = NULL;
+PFNGLVERTEXATTRIBI3IEXTPROC __glewVertexAttribI3iEXT = NULL;
+PFNGLVERTEXATTRIBI3IVEXTPROC __glewVertexAttribI3ivEXT = NULL;
+PFNGLVERTEXATTRIBI3UIEXTPROC __glewVertexAttribI3uiEXT = NULL;
+PFNGLVERTEXATTRIBI3UIVEXTPROC __glewVertexAttribI3uivEXT = NULL;
+PFNGLVERTEXATTRIBI4BVEXTPROC __glewVertexAttribI4bvEXT = NULL;
+PFNGLVERTEXATTRIBI4IEXTPROC __glewVertexAttribI4iEXT = NULL;
+PFNGLVERTEXATTRIBI4IVEXTPROC __glewVertexAttribI4ivEXT = NULL;
+PFNGLVERTEXATTRIBI4SVEXTPROC __glewVertexAttribI4svEXT = NULL;
+PFNGLVERTEXATTRIBI4UBVEXTPROC __glewVertexAttribI4ubvEXT = NULL;
+PFNGLVERTEXATTRIBI4UIEXTPROC __glewVertexAttribI4uiEXT = NULL;
+PFNGLVERTEXATTRIBI4UIVEXTPROC __glewVertexAttribI4uivEXT = NULL;
+PFNGLVERTEXATTRIBI4USVEXTPROC __glewVertexAttribI4usvEXT = NULL;
+PFNGLVERTEXATTRIBIPOINTEREXTPROC __glewVertexAttribIPointerEXT = NULL;
+
+PFNGLGETHISTOGRAMEXTPROC __glewGetHistogramEXT = NULL;
+PFNGLGETHISTOGRAMPARAMETERFVEXTPROC __glewGetHistogramParameterfvEXT = NULL;
+PFNGLGETHISTOGRAMPARAMETERIVEXTPROC __glewGetHistogramParameterivEXT = NULL;
+PFNGLGETMINMAXEXTPROC __glewGetMinmaxEXT = NULL;
+PFNGLGETMINMAXPARAMETERFVEXTPROC __glewGetMinmaxParameterfvEXT = NULL;
+PFNGLGETMINMAXPARAMETERIVEXTPROC __glewGetMinmaxParameterivEXT = NULL;
+PFNGLHISTOGRAMEXTPROC __glewHistogramEXT = NULL;
+PFNGLMINMAXEXTPROC __glewMinmaxEXT = NULL;
+PFNGLRESETHISTOGRAMEXTPROC __glewResetHistogramEXT = NULL;
+PFNGLRESETMINMAXEXTPROC __glewResetMinmaxEXT = NULL;
+
+PFNGLINDEXFUNCEXTPROC __glewIndexFuncEXT = NULL;
+
+PFNGLINDEXMATERIALEXTPROC __glewIndexMaterialEXT = NULL;
+
+PFNGLAPPLYTEXTUREEXTPROC __glewApplyTextureEXT = NULL;
+PFNGLTEXTURELIGHTEXTPROC __glewTextureLightEXT = NULL;
+PFNGLTEXTUREMATERIALEXTPROC __glewTextureMaterialEXT = NULL;
+
+PFNGLMULTIDRAWARRAYSEXTPROC __glewMultiDrawArraysEXT = NULL;
+PFNGLMULTIDRAWELEMENTSEXTPROC __glewMultiDrawElementsEXT = NULL;
+
+PFNGLSAMPLEMASKEXTPROC __glewSampleMaskEXT = NULL;
+PFNGLSAMPLEPATTERNEXTPROC __glewSamplePatternEXT = NULL;
+
+PFNGLCOLORTABLEEXTPROC __glewColorTableEXT = NULL;
+PFNGLGETCOLORTABLEEXTPROC __glewGetColorTableEXT = NULL;
+PFNGLGETCOLORTABLEPARAMETERFVEXTPROC __glewGetColorTableParameterfvEXT = NULL;
+PFNGLGETCOLORTABLEPARAMETERIVEXTPROC __glewGetColorTableParameterivEXT = NULL;
+
+PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC __glewGetPixelTransformParameterfvEXT = NULL;
+PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC __glewGetPixelTransformParameterivEXT = NULL;
+PFNGLPIXELTRANSFORMPARAMETERFEXTPROC __glewPixelTransformParameterfEXT = NULL;
+PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC __glewPixelTransformParameterfvEXT = NULL;
+PFNGLPIXELTRANSFORMPARAMETERIEXTPROC __glewPixelTransformParameteriEXT = NULL;
+PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC __glewPixelTransformParameterivEXT = NULL;
+
+PFNGLPOINTPARAMETERFEXTPROC __glewPointParameterfEXT = NULL;
+PFNGLPOINTPARAMETERFVEXTPROC __glewPointParameterfvEXT = NULL;
+
+PFNGLPOLYGONOFFSETEXTPROC __glewPolygonOffsetEXT = NULL;
+
+PFNGLPROVOKINGVERTEXEXTPROC __glewProvokingVertexEXT = NULL;
+
+PFNGLBEGINSCENEEXTPROC __glewBeginSceneEXT = NULL;
+PFNGLENDSCENEEXTPROC __glewEndSceneEXT = NULL;
+
+PFNGLSECONDARYCOLOR3BEXTPROC __glewSecondaryColor3bEXT = NULL;
+PFNGLSECONDARYCOLOR3BVEXTPROC __glewSecondaryColor3bvEXT = NULL;
+PFNGLSECONDARYCOLOR3DEXTPROC __glewSecondaryColor3dEXT = NULL;
+PFNGLSECONDARYCOLOR3DVEXTPROC __glewSecondaryColor3dvEXT = NULL;
+PFNGLSECONDARYCOLOR3FEXTPROC __glewSecondaryColor3fEXT = NULL;
+PFNGLSECONDARYCOLOR3FVEXTPROC __glewSecondaryColor3fvEXT = NULL;
+PFNGLSECONDARYCOLOR3IEXTPROC __glewSecondaryColor3iEXT = NULL;
+PFNGLSECONDARYCOLOR3IVEXTPROC __glewSecondaryColor3ivEXT = NULL;
+PFNGLSECONDARYCOLOR3SEXTPROC __glewSecondaryColor3sEXT = NULL;
+PFNGLSECONDARYCOLOR3SVEXTPROC __glewSecondaryColor3svEXT = NULL;
+PFNGLSECONDARYCOLOR3UBEXTPROC __glewSecondaryColor3ubEXT = NULL;
+PFNGLSECONDARYCOLOR3UBVEXTPROC __glewSecondaryColor3ubvEXT = NULL;
+PFNGLSECONDARYCOLOR3UIEXTPROC __glewSecondaryColor3uiEXT = NULL;
+PFNGLSECONDARYCOLOR3UIVEXTPROC __glewSecondaryColor3uivEXT = NULL;
+PFNGLSECONDARYCOLOR3USEXTPROC __glewSecondaryColor3usEXT = NULL;
+PFNGLSECONDARYCOLOR3USVEXTPROC __glewSecondaryColor3usvEXT = NULL;
+PFNGLSECONDARYCOLORPOINTEREXTPROC __glewSecondaryColorPointerEXT = NULL;
+
+PFNGLACTIVEPROGRAMEXTPROC __glewActiveProgramEXT = NULL;
+PFNGLCREATESHADERPROGRAMEXTPROC __glewCreateShaderProgramEXT = NULL;
+PFNGLUSESHADERPROGRAMEXTPROC __glewUseShaderProgramEXT = NULL;
+
+PFNGLBINDIMAGETEXTUREEXTPROC __glewBindImageTextureEXT = NULL;
+PFNGLMEMORYBARRIEREXTPROC __glewMemoryBarrierEXT = NULL;
+
+PFNGLACTIVESTENCILFACEEXTPROC __glewActiveStencilFaceEXT = NULL;
+
+PFNGLTEXSUBIMAGE1DEXTPROC __glewTexSubImage1DEXT = NULL;
+PFNGLTEXSUBIMAGE2DEXTPROC __glewTexSubImage2DEXT = NULL;
+PFNGLTEXSUBIMAGE3DEXTPROC __glewTexSubImage3DEXT = NULL;
+
+PFNGLTEXIMAGE3DEXTPROC __glewTexImage3DEXT = NULL;
+
+PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC __glewFramebufferTextureLayerEXT = NULL;
+
+PFNGLTEXBUFFEREXTPROC __glewTexBufferEXT = NULL;
+
+PFNGLCLEARCOLORIIEXTPROC __glewClearColorIiEXT = NULL;
+PFNGLCLEARCOLORIUIEXTPROC __glewClearColorIuiEXT = NULL;
+PFNGLGETTEXPARAMETERIIVEXTPROC __glewGetTexParameterIivEXT = NULL;
+PFNGLGETTEXPARAMETERIUIVEXTPROC __glewGetTexParameterIuivEXT = NULL;
+PFNGLTEXPARAMETERIIVEXTPROC __glewTexParameterIivEXT = NULL;
+PFNGLTEXPARAMETERIUIVEXTPROC __glewTexParameterIuivEXT = NULL;
+
+PFNGLARETEXTURESRESIDENTEXTPROC __glewAreTexturesResidentEXT = NULL;
+PFNGLBINDTEXTUREEXTPROC __glewBindTextureEXT = NULL;
+PFNGLDELETETEXTURESEXTPROC __glewDeleteTexturesEXT = NULL;
+PFNGLGENTEXTURESEXTPROC __glewGenTexturesEXT = NULL;
+PFNGLISTEXTUREEXTPROC __glewIsTextureEXT = NULL;
+PFNGLPRIORITIZETEXTURESEXTPROC __glewPrioritizeTexturesEXT = NULL;
+
+PFNGLTEXTURENORMALEXTPROC __glewTextureNormalEXT = NULL;
+
+PFNGLGETQUERYOBJECTI64VEXTPROC __glewGetQueryObjecti64vEXT = NULL;
+PFNGLGETQUERYOBJECTUI64VEXTPROC __glewGetQueryObjectui64vEXT = NULL;
+
+PFNGLBEGINTRANSFORMFEEDBACKEXTPROC __glewBeginTransformFeedbackEXT = NULL;
+PFNGLBINDBUFFERBASEEXTPROC __glewBindBufferBaseEXT = NULL;
+PFNGLBINDBUFFEROFFSETEXTPROC __glewBindBufferOffsetEXT = NULL;
+PFNGLBINDBUFFERRANGEEXTPROC __glewBindBufferRangeEXT = NULL;
+PFNGLENDTRANSFORMFEEDBACKEXTPROC __glewEndTransformFeedbackEXT = NULL;
+PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC __glewGetTransformFeedbackVaryingEXT = NULL;
+PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC __glewTransformFeedbackVaryingsEXT = NULL;
+
+PFNGLARRAYELEMENTEXTPROC __glewArrayElementEXT = NULL;
+PFNGLCOLORPOINTEREXTPROC __glewColorPointerEXT = NULL;
+PFNGLDRAWARRAYSEXTPROC __glewDrawArraysEXT = NULL;
+PFNGLEDGEFLAGPOINTEREXTPROC __glewEdgeFlagPointerEXT = NULL;
+PFNGLINDEXPOINTEREXTPROC __glewIndexPointerEXT = NULL;
+PFNGLNORMALPOINTEREXTPROC __glewNormalPointerEXT = NULL;
+PFNGLTEXCOORDPOINTEREXTPROC __glewTexCoordPointerEXT = NULL;
+PFNGLVERTEXPOINTEREXTPROC __glewVertexPointerEXT = NULL;
+
+PFNGLGETVERTEXATTRIBLDVEXTPROC __glewGetVertexAttribLdvEXT = NULL;
+PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC __glewVertexArrayVertexAttribLOffsetEXT = NULL;
+PFNGLVERTEXATTRIBL1DEXTPROC __glewVertexAttribL1dEXT = NULL;
+PFNGLVERTEXATTRIBL1DVEXTPROC __glewVertexAttribL1dvEXT = NULL;
+PFNGLVERTEXATTRIBL2DEXTPROC __glewVertexAttribL2dEXT = NULL;
+PFNGLVERTEXATTRIBL2DVEXTPROC __glewVertexAttribL2dvEXT = NULL;
+PFNGLVERTEXATTRIBL3DEXTPROC __glewVertexAttribL3dEXT = NULL;
+PFNGLVERTEXATTRIBL3DVEXTPROC __glewVertexAttribL3dvEXT = NULL;
+PFNGLVERTEXATTRIBL4DEXTPROC __glewVertexAttribL4dEXT = NULL;
+PFNGLVERTEXATTRIBL4DVEXTPROC __glewVertexAttribL4dvEXT = NULL;
+PFNGLVERTEXATTRIBLPOINTEREXTPROC __glewVertexAttribLPointerEXT = NULL;
+
+PFNGLBEGINVERTEXSHADEREXTPROC __glewBeginVertexShaderEXT = NULL;
+PFNGLBINDLIGHTPARAMETEREXTPROC __glewBindLightParameterEXT = NULL;
+PFNGLBINDMATERIALPARAMETEREXTPROC __glewBindMaterialParameterEXT = NULL;
+PFNGLBINDPARAMETEREXTPROC __glewBindParameterEXT = NULL;
+PFNGLBINDTEXGENPARAMETEREXTPROC __glewBindTexGenParameterEXT = NULL;
+PFNGLBINDTEXTUREUNITPARAMETEREXTPROC __glewBindTextureUnitParameterEXT = NULL;
+PFNGLBINDVERTEXSHADEREXTPROC __glewBindVertexShaderEXT = NULL;
+PFNGLDELETEVERTEXSHADEREXTPROC __glewDeleteVertexShaderEXT = NULL;
+PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC __glewDisableVariantClientStateEXT = NULL;
+PFNGLENABLEVARIANTCLIENTSTATEEXTPROC __glewEnableVariantClientStateEXT = NULL;
+PFNGLENDVERTEXSHADEREXTPROC __glewEndVertexShaderEXT = NULL;
+PFNGLEXTRACTCOMPONENTEXTPROC __glewExtractComponentEXT = NULL;
+PFNGLGENSYMBOLSEXTPROC __glewGenSymbolsEXT = NULL;
+PFNGLGENVERTEXSHADERSEXTPROC __glewGenVertexShadersEXT = NULL;
+PFNGLGETINVARIANTBOOLEANVEXTPROC __glewGetInvariantBooleanvEXT = NULL;
+PFNGLGETINVARIANTFLOATVEXTPROC __glewGetInvariantFloatvEXT = NULL;
+PFNGLGETINVARIANTINTEGERVEXTPROC __glewGetInvariantIntegervEXT = NULL;
+PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC __glewGetLocalConstantBooleanvEXT = NULL;
+PFNGLGETLOCALCONSTANTFLOATVEXTPROC __glewGetLocalConstantFloatvEXT = NULL;
+PFNGLGETLOCALCONSTANTINTEGERVEXTPROC __glewGetLocalConstantIntegervEXT = NULL;
+PFNGLGETVARIANTBOOLEANVEXTPROC __glewGetVariantBooleanvEXT = NULL;
+PFNGLGETVARIANTFLOATVEXTPROC __glewGetVariantFloatvEXT = NULL;
+PFNGLGETVARIANTINTEGERVEXTPROC __glewGetVariantIntegervEXT = NULL;
+PFNGLGETVARIANTPOINTERVEXTPROC __glewGetVariantPointervEXT = NULL;
+PFNGLINSERTCOMPONENTEXTPROC __glewInsertComponentEXT = NULL;
+PFNGLISVARIANTENABLEDEXTPROC __glewIsVariantEnabledEXT = NULL;
+PFNGLSETINVARIANTEXTPROC __glewSetInvariantEXT = NULL;
+PFNGLSETLOCALCONSTANTEXTPROC __glewSetLocalConstantEXT = NULL;
+PFNGLSHADEROP1EXTPROC __glewShaderOp1EXT = NULL;
+PFNGLSHADEROP2EXTPROC __glewShaderOp2EXT = NULL;
+PFNGLSHADEROP3EXTPROC __glewShaderOp3EXT = NULL;
+PFNGLSWIZZLEEXTPROC __glewSwizzleEXT = NULL;
+PFNGLVARIANTPOINTEREXTPROC __glewVariantPointerEXT = NULL;
+PFNGLVARIANTBVEXTPROC __glewVariantbvEXT = NULL;
+PFNGLVARIANTDVEXTPROC __glewVariantdvEXT = NULL;
+PFNGLVARIANTFVEXTPROC __glewVariantfvEXT = NULL;
+PFNGLVARIANTIVEXTPROC __glewVariantivEXT = NULL;
+PFNGLVARIANTSVEXTPROC __glewVariantsvEXT = NULL;
+PFNGLVARIANTUBVEXTPROC __glewVariantubvEXT = NULL;
+PFNGLVARIANTUIVEXTPROC __glewVariantuivEXT = NULL;
+PFNGLVARIANTUSVEXTPROC __glewVariantusvEXT = NULL;
+PFNGLWRITEMASKEXTPROC __glewWriteMaskEXT = NULL;
+
+PFNGLVERTEXWEIGHTPOINTEREXTPROC __glewVertexWeightPointerEXT = NULL;
+PFNGLVERTEXWEIGHTFEXTPROC __glewVertexWeightfEXT = NULL;
+PFNGLVERTEXWEIGHTFVEXTPROC __glewVertexWeightfvEXT = NULL;
+
+PFNGLIMPORTSYNCEXTPROC __glewImportSyncEXT = NULL;
+
+PFNGLFRAMETERMINATORGREMEDYPROC __glewFrameTerminatorGREMEDY = NULL;
+
+PFNGLSTRINGMARKERGREMEDYPROC __glewStringMarkerGREMEDY = NULL;
+
+PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC __glewGetImageTransformParameterfvHP = NULL;
+PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC __glewGetImageTransformParameterivHP = NULL;
+PFNGLIMAGETRANSFORMPARAMETERFHPPROC __glewImageTransformParameterfHP = NULL;
+PFNGLIMAGETRANSFORMPARAMETERFVHPPROC __glewImageTransformParameterfvHP = NULL;
+PFNGLIMAGETRANSFORMPARAMETERIHPPROC __glewImageTransformParameteriHP = NULL;
+PFNGLIMAGETRANSFORMPARAMETERIVHPPROC __glewImageTransformParameterivHP = NULL;
+
+PFNGLMULTIMODEDRAWARRAYSIBMPROC __glewMultiModeDrawArraysIBM = NULL;
+PFNGLMULTIMODEDRAWELEMENTSIBMPROC __glewMultiModeDrawElementsIBM = NULL;
+
+PFNGLCOLORPOINTERLISTIBMPROC __glewColorPointerListIBM = NULL;
+PFNGLEDGEFLAGPOINTERLISTIBMPROC __glewEdgeFlagPointerListIBM = NULL;
+PFNGLFOGCOORDPOINTERLISTIBMPROC __glewFogCoordPointerListIBM = NULL;
+PFNGLINDEXPOINTERLISTIBMPROC __glewIndexPointerListIBM = NULL;
+PFNGLNORMALPOINTERLISTIBMPROC __glewNormalPointerListIBM = NULL;
+PFNGLSECONDARYCOLORPOINTERLISTIBMPROC __glewSecondaryColorPointerListIBM = NULL;
+PFNGLTEXCOORDPOINTERLISTIBMPROC __glewTexCoordPointerListIBM = NULL;
+PFNGLVERTEXPOINTERLISTIBMPROC __glewVertexPointerListIBM = NULL;
+
+PFNGLMAPTEXTURE2DINTELPROC __glewMapTexture2DINTEL = NULL;
+PFNGLSYNCTEXTUREINTELPROC __glewSyncTextureINTEL = NULL;
+PFNGLUNMAPTEXTURE2DINTELPROC __glewUnmapTexture2DINTEL = NULL;
+
+PFNGLCOLORPOINTERVINTELPROC __glewColorPointervINTEL = NULL;
+PFNGLNORMALPOINTERVINTELPROC __glewNormalPointervINTEL = NULL;
+PFNGLTEXCOORDPOINTERVINTELPROC __glewTexCoordPointervINTEL = NULL;
+PFNGLVERTEXPOINTERVINTELPROC __glewVertexPointervINTEL = NULL;
+
+PFNGLTEXSCISSORFUNCINTELPROC __glewTexScissorFuncINTEL = NULL;
+PFNGLTEXSCISSORINTELPROC __glewTexScissorINTEL = NULL;
+
+PFNGLDEBUGMESSAGECALLBACKPROC __glewDebugMessageCallback = NULL;
+PFNGLDEBUGMESSAGECONTROLPROC __glewDebugMessageControl = NULL;
+PFNGLDEBUGMESSAGEINSERTPROC __glewDebugMessageInsert = NULL;
+PFNGLGETDEBUGMESSAGELOGPROC __glewGetDebugMessageLog = NULL;
+PFNGLGETOBJECTLABELPROC __glewGetObjectLabel = NULL;
+PFNGLGETOBJECTPTRLABELPROC __glewGetObjectPtrLabel = NULL;
+PFNGLOBJECTLABELPROC __glewObjectLabel = NULL;
+PFNGLOBJECTPTRLABELPROC __glewObjectPtrLabel = NULL;
+PFNGLPOPDEBUGGROUPPROC __glewPopDebugGroup = NULL;
+PFNGLPUSHDEBUGGROUPPROC __glewPushDebugGroup = NULL;
+
+PFNGLBUFFERREGIONENABLEDPROC __glewBufferRegionEnabled = NULL;
+PFNGLDELETEBUFFERREGIONPROC __glewDeleteBufferRegion = NULL;
+PFNGLDRAWBUFFERREGIONPROC __glewDrawBufferRegion = NULL;
+PFNGLNEWBUFFERREGIONPROC __glewNewBufferRegion = NULL;
+PFNGLREADBUFFERREGIONPROC __glewReadBufferRegion = NULL;
+
+PFNGLRESIZEBUFFERSMESAPROC __glewResizeBuffersMESA = NULL;
+
+PFNGLWINDOWPOS2DMESAPROC __glewWindowPos2dMESA = NULL;
+PFNGLWINDOWPOS2DVMESAPROC __glewWindowPos2dvMESA = NULL;
+PFNGLWINDOWPOS2FMESAPROC __glewWindowPos2fMESA = NULL;
+PFNGLWINDOWPOS2FVMESAPROC __glewWindowPos2fvMESA = NULL;
+PFNGLWINDOWPOS2IMESAPROC __glewWindowPos2iMESA = NULL;
+PFNGLWINDOWPOS2IVMESAPROC __glewWindowPos2ivMESA = NULL;
+PFNGLWINDOWPOS2SMESAPROC __glewWindowPos2sMESA = NULL;
+PFNGLWINDOWPOS2SVMESAPROC __glewWindowPos2svMESA = NULL;
+PFNGLWINDOWPOS3DMESAPROC __glewWindowPos3dMESA = NULL;
+PFNGLWINDOWPOS3DVMESAPROC __glewWindowPos3dvMESA = NULL;
+PFNGLWINDOWPOS3FMESAPROC __glewWindowPos3fMESA = NULL;
+PFNGLWINDOWPOS3FVMESAPROC __glewWindowPos3fvMESA = NULL;
+PFNGLWINDOWPOS3IMESAPROC __glewWindowPos3iMESA = NULL;
+PFNGLWINDOWPOS3IVMESAPROC __glewWindowPos3ivMESA = NULL;
+PFNGLWINDOWPOS3SMESAPROC __glewWindowPos3sMESA = NULL;
+PFNGLWINDOWPOS3SVMESAPROC __glewWindowPos3svMESA = NULL;
+PFNGLWINDOWPOS4DMESAPROC __glewWindowPos4dMESA = NULL;
+PFNGLWINDOWPOS4DVMESAPROC __glewWindowPos4dvMESA = NULL;
+PFNGLWINDOWPOS4FMESAPROC __glewWindowPos4fMESA = NULL;
+PFNGLWINDOWPOS4FVMESAPROC __glewWindowPos4fvMESA = NULL;
+PFNGLWINDOWPOS4IMESAPROC __glewWindowPos4iMESA = NULL;
+PFNGLWINDOWPOS4IVMESAPROC __glewWindowPos4ivMESA = NULL;
+PFNGLWINDOWPOS4SMESAPROC __glewWindowPos4sMESA = NULL;
+PFNGLWINDOWPOS4SVMESAPROC __glewWindowPos4svMESA = NULL;
+
+PFNGLBEGINCONDITIONALRENDERNVXPROC __glewBeginConditionalRenderNVX = NULL;
+PFNGLENDCONDITIONALRENDERNVXPROC __glewEndConditionalRenderNVX = NULL;
+
+PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC __glewMultiDrawArraysIndirectBindlessNV = NULL;
+PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC __glewMultiDrawElementsIndirectBindlessNV = NULL;
+
+PFNGLGETIMAGEHANDLENVPROC __glewGetImageHandleNV = NULL;
+PFNGLGETTEXTUREHANDLENVPROC __glewGetTextureHandleNV = NULL;
+PFNGLGETTEXTURESAMPLERHANDLENVPROC __glewGetTextureSamplerHandleNV = NULL;
+PFNGLISIMAGEHANDLERESIDENTNVPROC __glewIsImageHandleResidentNV = NULL;
+PFNGLISTEXTUREHANDLERESIDENTNVPROC __glewIsTextureHandleResidentNV = NULL;
+PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC __glewMakeImageHandleNonResidentNV = NULL;
+PFNGLMAKEIMAGEHANDLERESIDENTNVPROC __glewMakeImageHandleResidentNV = NULL;
+PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC __glewMakeTextureHandleNonResidentNV = NULL;
+PFNGLMAKETEXTUREHANDLERESIDENTNVPROC __glewMakeTextureHandleResidentNV = NULL;
+PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC __glewProgramUniformHandleui64NV = NULL;
+PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC __glewProgramUniformHandleui64vNV = NULL;
+PFNGLUNIFORMHANDLEUI64NVPROC __glewUniformHandleui64NV = NULL;
+PFNGLUNIFORMHANDLEUI64VNVPROC __glewUniformHandleui64vNV = NULL;
+
+PFNGLBLENDBARRIERNVPROC __glewBlendBarrierNV = NULL;
+PFNGLBLENDPARAMETERINVPROC __glewBlendParameteriNV = NULL;
+
+PFNGLBEGINCONDITIONALRENDERNVPROC __glewBeginConditionalRenderNV = NULL;
+PFNGLENDCONDITIONALRENDERNVPROC __glewEndConditionalRenderNV = NULL;
+
+PFNGLCOPYIMAGESUBDATANVPROC __glewCopyImageSubDataNV = NULL;
+
+PFNGLCLEARDEPTHDNVPROC __glewClearDepthdNV = NULL;
+PFNGLDEPTHBOUNDSDNVPROC __glewDepthBoundsdNV = NULL;
+PFNGLDEPTHRANGEDNVPROC __glewDepthRangedNV = NULL;
+
+PFNGLDRAWTEXTURENVPROC __glewDrawTextureNV = NULL;
+
+PFNGLEVALMAPSNVPROC __glewEvalMapsNV = NULL;
+PFNGLGETMAPATTRIBPARAMETERFVNVPROC __glewGetMapAttribParameterfvNV = NULL;
+PFNGLGETMAPATTRIBPARAMETERIVNVPROC __glewGetMapAttribParameterivNV = NULL;
+PFNGLGETMAPCONTROLPOINTSNVPROC __glewGetMapControlPointsNV = NULL;
+PFNGLGETMAPPARAMETERFVNVPROC __glewGetMapParameterfvNV = NULL;
+PFNGLGETMAPPARAMETERIVNVPROC __glewGetMapParameterivNV = NULL;
+PFNGLMAPCONTROLPOINTSNVPROC __glewMapControlPointsNV = NULL;
+PFNGLMAPPARAMETERFVNVPROC __glewMapParameterfvNV = NULL;
+PFNGLMAPPARAMETERIVNVPROC __glewMapParameterivNV = NULL;
+
+PFNGLGETMULTISAMPLEFVNVPROC __glewGetMultisamplefvNV = NULL;
+PFNGLSAMPLEMASKINDEXEDNVPROC __glewSampleMaskIndexedNV = NULL;
+PFNGLTEXRENDERBUFFERNVPROC __glewTexRenderbufferNV = NULL;
+
+PFNGLDELETEFENCESNVPROC __glewDeleteFencesNV = NULL;
+PFNGLFINISHFENCENVPROC __glewFinishFenceNV = NULL;
+PFNGLGENFENCESNVPROC __glewGenFencesNV = NULL;
+PFNGLGETFENCEIVNVPROC __glewGetFenceivNV = NULL;
+PFNGLISFENCENVPROC __glewIsFenceNV = NULL;
+PFNGLSETFENCENVPROC __glewSetFenceNV = NULL;
+PFNGLTESTFENCENVPROC __glewTestFenceNV = NULL;
+
+PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC __glewGetProgramNamedParameterdvNV = NULL;
+PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC __glewGetProgramNamedParameterfvNV = NULL;
+PFNGLPROGRAMNAMEDPARAMETER4DNVPROC __glewProgramNamedParameter4dNV = NULL;
+PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC __glewProgramNamedParameter4dvNV = NULL;
+PFNGLPROGRAMNAMEDPARAMETER4FNVPROC __glewProgramNamedParameter4fNV = NULL;
+PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC __glewProgramNamedParameter4fvNV = NULL;
+
+PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC __glewRenderbufferStorageMultisampleCoverageNV = NULL;
+
+PFNGLPROGRAMVERTEXLIMITNVPROC __glewProgramVertexLimitNV = NULL;
+
+PFNGLPROGRAMENVPARAMETERI4INVPROC __glewProgramEnvParameterI4iNV = NULL;
+PFNGLPROGRAMENVPARAMETERI4IVNVPROC __glewProgramEnvParameterI4ivNV = NULL;
+PFNGLPROGRAMENVPARAMETERI4UINVPROC __glewProgramEnvParameterI4uiNV = NULL;
+PFNGLPROGRAMENVPARAMETERI4UIVNVPROC __glewProgramEnvParameterI4uivNV = NULL;
+PFNGLPROGRAMENVPARAMETERSI4IVNVPROC __glewProgramEnvParametersI4ivNV = NULL;
+PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC __glewProgramEnvParametersI4uivNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERI4INVPROC __glewProgramLocalParameterI4iNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC __glewProgramLocalParameterI4ivNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERI4UINVPROC __glewProgramLocalParameterI4uiNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC __glewProgramLocalParameterI4uivNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC __glewProgramLocalParametersI4ivNV = NULL;
+PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC __glewProgramLocalParametersI4uivNV = NULL;
+
+PFNGLGETUNIFORMI64VNVPROC __glewGetUniformi64vNV = NULL;
+PFNGLGETUNIFORMUI64VNVPROC __glewGetUniformui64vNV = NULL;
+PFNGLPROGRAMUNIFORM1I64NVPROC __glewProgramUniform1i64NV = NULL;
+PFNGLPROGRAMUNIFORM1I64VNVPROC __glewProgramUniform1i64vNV = NULL;
+PFNGLPROGRAMUNIFORM1UI64NVPROC __glewProgramUniform1ui64NV = NULL;
+PFNGLPROGRAMUNIFORM1UI64VNVPROC __glewProgramUniform1ui64vNV = NULL;
+PFNGLPROGRAMUNIFORM2I64NVPROC __glewProgramUniform2i64NV = NULL;
+PFNGLPROGRAMUNIFORM2I64VNVPROC __glewProgramUniform2i64vNV = NULL;
+PFNGLPROGRAMUNIFORM2UI64NVPROC __glewProgramUniform2ui64NV = NULL;
+PFNGLPROGRAMUNIFORM2UI64VNVPROC __glewProgramUniform2ui64vNV = NULL;
+PFNGLPROGRAMUNIFORM3I64NVPROC __glewProgramUniform3i64NV = NULL;
+PFNGLPROGRAMUNIFORM3I64VNVPROC __glewProgramUniform3i64vNV = NULL;
+PFNGLPROGRAMUNIFORM3UI64NVPROC __glewProgramUniform3ui64NV = NULL;
+PFNGLPROGRAMUNIFORM3UI64VNVPROC __glewProgramUniform3ui64vNV = NULL;
+PFNGLPROGRAMUNIFORM4I64NVPROC __glewProgramUniform4i64NV = NULL;
+PFNGLPROGRAMUNIFORM4I64VNVPROC __glewProgramUniform4i64vNV = NULL;
+PFNGLPROGRAMUNIFORM4UI64NVPROC __glewProgramUniform4ui64NV = NULL;
+PFNGLPROGRAMUNIFORM4UI64VNVPROC __glewProgramUniform4ui64vNV = NULL;
+PFNGLUNIFORM1I64NVPROC __glewUniform1i64NV = NULL;
+PFNGLUNIFORM1I64VNVPROC __glewUniform1i64vNV = NULL;
+PFNGLUNIFORM1UI64NVPROC __glewUniform1ui64NV = NULL;
+PFNGLUNIFORM1UI64VNVPROC __glewUniform1ui64vNV = NULL;
+PFNGLUNIFORM2I64NVPROC __glewUniform2i64NV = NULL;
+PFNGLUNIFORM2I64VNVPROC __glewUniform2i64vNV = NULL;
+PFNGLUNIFORM2UI64NVPROC __glewUniform2ui64NV = NULL;
+PFNGLUNIFORM2UI64VNVPROC __glewUniform2ui64vNV = NULL;
+PFNGLUNIFORM3I64NVPROC __glewUniform3i64NV = NULL;
+PFNGLUNIFORM3I64VNVPROC __glewUniform3i64vNV = NULL;
+PFNGLUNIFORM3UI64NVPROC __glewUniform3ui64NV = NULL;
+PFNGLUNIFORM3UI64VNVPROC __glewUniform3ui64vNV = NULL;
+PFNGLUNIFORM4I64NVPROC __glewUniform4i64NV = NULL;
+PFNGLUNIFORM4I64VNVPROC __glewUniform4i64vNV = NULL;
+PFNGLUNIFORM4UI64NVPROC __glewUniform4ui64NV = NULL;
+PFNGLUNIFORM4UI64VNVPROC __glewUniform4ui64vNV = NULL;
+
+PFNGLCOLOR3HNVPROC __glewColor3hNV = NULL;
+PFNGLCOLOR3HVNVPROC __glewColor3hvNV = NULL;
+PFNGLCOLOR4HNVPROC __glewColor4hNV = NULL;
+PFNGLCOLOR4HVNVPROC __glewColor4hvNV = NULL;
+PFNGLFOGCOORDHNVPROC __glewFogCoordhNV = NULL;
+PFNGLFOGCOORDHVNVPROC __glewFogCoordhvNV = NULL;
+PFNGLMULTITEXCOORD1HNVPROC __glewMultiTexCoord1hNV = NULL;
+PFNGLMULTITEXCOORD1HVNVPROC __glewMultiTexCoord1hvNV = NULL;
+PFNGLMULTITEXCOORD2HNVPROC __glewMultiTexCoord2hNV = NULL;
+PFNGLMULTITEXCOORD2HVNVPROC __glewMultiTexCoord2hvNV = NULL;
+PFNGLMULTITEXCOORD3HNVPROC __glewMultiTexCoord3hNV = NULL;
+PFNGLMULTITEXCOORD3HVNVPROC __glewMultiTexCoord3hvNV = NULL;
+PFNGLMULTITEXCOORD4HNVPROC __glewMultiTexCoord4hNV = NULL;
+PFNGLMULTITEXCOORD4HVNVPROC __glewMultiTexCoord4hvNV = NULL;
+PFNGLNORMAL3HNVPROC __glewNormal3hNV = NULL;
+PFNGLNORMAL3HVNVPROC __glewNormal3hvNV = NULL;
+PFNGLSECONDARYCOLOR3HNVPROC __glewSecondaryColor3hNV = NULL;
+PFNGLSECONDARYCOLOR3HVNVPROC __glewSecondaryColor3hvNV = NULL;
+PFNGLTEXCOORD1HNVPROC __glewTexCoord1hNV = NULL;
+PFNGLTEXCOORD1HVNVPROC __glewTexCoord1hvNV = NULL;
+PFNGLTEXCOORD2HNVPROC __glewTexCoord2hNV = NULL;
+PFNGLTEXCOORD2HVNVPROC __glewTexCoord2hvNV = NULL;
+PFNGLTEXCOORD3HNVPROC __glewTexCoord3hNV = NULL;
+PFNGLTEXCOORD3HVNVPROC __glewTexCoord3hvNV = NULL;
+PFNGLTEXCOORD4HNVPROC __glewTexCoord4hNV = NULL;
+PFNGLTEXCOORD4HVNVPROC __glewTexCoord4hvNV = NULL;
+PFNGLVERTEX2HNVPROC __glewVertex2hNV = NULL;
+PFNGLVERTEX2HVNVPROC __glewVertex2hvNV = NULL;
+PFNGLVERTEX3HNVPROC __glewVertex3hNV = NULL;
+PFNGLVERTEX3HVNVPROC __glewVertex3hvNV = NULL;
+PFNGLVERTEX4HNVPROC __glewVertex4hNV = NULL;
+PFNGLVERTEX4HVNVPROC __glewVertex4hvNV = NULL;
+PFNGLVERTEXATTRIB1HNVPROC __glewVertexAttrib1hNV = NULL;
+PFNGLVERTEXATTRIB1HVNVPROC __glewVertexAttrib1hvNV = NULL;
+PFNGLVERTEXATTRIB2HNVPROC __glewVertexAttrib2hNV = NULL;
+PFNGLVERTEXATTRIB2HVNVPROC __glewVertexAttrib2hvNV = NULL;
+PFNGLVERTEXATTRIB3HNVPROC __glewVertexAttrib3hNV = NULL;
+PFNGLVERTEXATTRIB3HVNVPROC __glewVertexAttrib3hvNV = NULL;
+PFNGLVERTEXATTRIB4HNVPROC __glewVertexAttrib4hNV = NULL;
+PFNGLVERTEXATTRIB4HVNVPROC __glewVertexAttrib4hvNV = NULL;
+PFNGLVERTEXATTRIBS1HVNVPROC __glewVertexAttribs1hvNV = NULL;
+PFNGLVERTEXATTRIBS2HVNVPROC __glewVertexAttribs2hvNV = NULL;
+PFNGLVERTEXATTRIBS3HVNVPROC __glewVertexAttribs3hvNV = NULL;
+PFNGLVERTEXATTRIBS4HVNVPROC __glewVertexAttribs4hvNV = NULL;
+PFNGLVERTEXWEIGHTHNVPROC __glewVertexWeighthNV = NULL;
+PFNGLVERTEXWEIGHTHVNVPROC __glewVertexWeighthvNV = NULL;
+
+PFNGLBEGINOCCLUSIONQUERYNVPROC __glewBeginOcclusionQueryNV = NULL;
+PFNGLDELETEOCCLUSIONQUERIESNVPROC __glewDeleteOcclusionQueriesNV = NULL;
+PFNGLENDOCCLUSIONQUERYNVPROC __glewEndOcclusionQueryNV = NULL;
+PFNGLGENOCCLUSIONQUERIESNVPROC __glewGenOcclusionQueriesNV = NULL;
+PFNGLGETOCCLUSIONQUERYIVNVPROC __glewGetOcclusionQueryivNV = NULL;
+PFNGLGETOCCLUSIONQUERYUIVNVPROC __glewGetOcclusionQueryuivNV = NULL;
+PFNGLISOCCLUSIONQUERYNVPROC __glewIsOcclusionQueryNV = NULL;
+
+PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC __glewProgramBufferParametersIivNV = NULL;
+PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC __glewProgramBufferParametersIuivNV = NULL;
+PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC __glewProgramBufferParametersfvNV = NULL;
+
+PFNGLCOPYPATHNVPROC __glewCopyPathNV = NULL;
+PFNGLCOVERFILLPATHINSTANCEDNVPROC __glewCoverFillPathInstancedNV = NULL;
+PFNGLCOVERFILLPATHNVPROC __glewCoverFillPathNV = NULL;
+PFNGLCOVERSTROKEPATHINSTANCEDNVPROC __glewCoverStrokePathInstancedNV = NULL;
+PFNGLCOVERSTROKEPATHNVPROC __glewCoverStrokePathNV = NULL;
+PFNGLDELETEPATHSNVPROC __glewDeletePathsNV = NULL;
+PFNGLGENPATHSNVPROC __glewGenPathsNV = NULL;
+PFNGLGETPATHCOLORGENFVNVPROC __glewGetPathColorGenfvNV = NULL;
+PFNGLGETPATHCOLORGENIVNVPROC __glewGetPathColorGenivNV = NULL;
+PFNGLGETPATHCOMMANDSNVPROC __glewGetPathCommandsNV = NULL;
+PFNGLGETPATHCOORDSNVPROC __glewGetPathCoordsNV = NULL;
+PFNGLGETPATHDASHARRAYNVPROC __glewGetPathDashArrayNV = NULL;
+PFNGLGETPATHLENGTHNVPROC __glewGetPathLengthNV = NULL;
+PFNGLGETPATHMETRICRANGENVPROC __glewGetPathMetricRangeNV = NULL;
+PFNGLGETPATHMETRICSNVPROC __glewGetPathMetricsNV = NULL;
+PFNGLGETPATHPARAMETERFVNVPROC __glewGetPathParameterfvNV = NULL;
+PFNGLGETPATHPARAMETERIVNVPROC __glewGetPathParameterivNV = NULL;
+PFNGLGETPATHSPACINGNVPROC __glewGetPathSpacingNV = NULL;
+PFNGLGETPATHTEXGENFVNVPROC __glewGetPathTexGenfvNV = NULL;
+PFNGLGETPATHTEXGENIVNVPROC __glewGetPathTexGenivNV = NULL;
+PFNGLINTERPOLATEPATHSNVPROC __glewInterpolatePathsNV = NULL;
+PFNGLISPATHNVPROC __glewIsPathNV = NULL;
+PFNGLISPOINTINFILLPATHNVPROC __glewIsPointInFillPathNV = NULL;
+PFNGLISPOINTINSTROKEPATHNVPROC __glewIsPointInStrokePathNV = NULL;
+PFNGLPATHCOLORGENNVPROC __glewPathColorGenNV = NULL;
+PFNGLPATHCOMMANDSNVPROC __glewPathCommandsNV = NULL;
+PFNGLPATHCOORDSNVPROC __glewPathCoordsNV = NULL;
+PFNGLPATHCOVERDEPTHFUNCNVPROC __glewPathCoverDepthFuncNV = NULL;
+PFNGLPATHDASHARRAYNVPROC __glewPathDashArrayNV = NULL;
+PFNGLPATHFOGGENNVPROC __glewPathFogGenNV = NULL;
+PFNGLPATHGLYPHRANGENVPROC __glewPathGlyphRangeNV = NULL;
+PFNGLPATHGLYPHSNVPROC __glewPathGlyphsNV = NULL;
+PFNGLPATHPARAMETERFNVPROC __glewPathParameterfNV = NULL;
+PFNGLPATHPARAMETERFVNVPROC __glewPathParameterfvNV = NULL;
+PFNGLPATHPARAMETERINVPROC __glewPathParameteriNV = NULL;
+PFNGLPATHPARAMETERIVNVPROC __glewPathParameterivNV = NULL;
+PFNGLPATHSTENCILDEPTHOFFSETNVPROC __glewPathStencilDepthOffsetNV = NULL;
+PFNGLPATHSTENCILFUNCNVPROC __glewPathStencilFuncNV = NULL;
+PFNGLPATHSTRINGNVPROC __glewPathStringNV = NULL;
+PFNGLPATHSUBCOMMANDSNVPROC __glewPathSubCommandsNV = NULL;
+PFNGLPATHSUBCOORDSNVPROC __glewPathSubCoordsNV = NULL;
+PFNGLPATHTEXGENNVPROC __glewPathTexGenNV = NULL;
+PFNGLPOINTALONGPATHNVPROC __glewPointAlongPathNV = NULL;
+PFNGLSTENCILFILLPATHINSTANCEDNVPROC __glewStencilFillPathInstancedNV = NULL;
+PFNGLSTENCILFILLPATHNVPROC __glewStencilFillPathNV = NULL;
+PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC __glewStencilStrokePathInstancedNV = NULL;
+PFNGLSTENCILSTROKEPATHNVPROC __glewStencilStrokePathNV = NULL;
+PFNGLTRANSFORMPATHNVPROC __glewTransformPathNV = NULL;
+PFNGLWEIGHTPATHSNVPROC __glewWeightPathsNV = NULL;
+
+PFNGLFLUSHPIXELDATARANGENVPROC __glewFlushPixelDataRangeNV = NULL;
+PFNGLPIXELDATARANGENVPROC __glewPixelDataRangeNV = NULL;
+
+PFNGLPOINTPARAMETERINVPROC __glewPointParameteriNV = NULL;
+PFNGLPOINTPARAMETERIVNVPROC __glewPointParameterivNV = NULL;
+
+PFNGLGETVIDEOI64VNVPROC __glewGetVideoi64vNV = NULL;
+PFNGLGETVIDEOIVNVPROC __glewGetVideoivNV = NULL;
+PFNGLGETVIDEOUI64VNVPROC __glewGetVideoui64vNV = NULL;
+PFNGLGETVIDEOUIVNVPROC __glewGetVideouivNV = NULL;
+PFNGLPRESENTFRAMEDUALFILLNVPROC __glewPresentFrameDualFillNV = NULL;
+PFNGLPRESENTFRAMEKEYEDNVPROC __glewPresentFrameKeyedNV = NULL;
+
+PFNGLPRIMITIVERESTARTINDEXNVPROC __glewPrimitiveRestartIndexNV = NULL;
+PFNGLPRIMITIVERESTARTNVPROC __glewPrimitiveRestartNV = NULL;
+
+PFNGLCOMBINERINPUTNVPROC __glewCombinerInputNV = NULL;
+PFNGLCOMBINEROUTPUTNVPROC __glewCombinerOutputNV = NULL;
+PFNGLCOMBINERPARAMETERFNVPROC __glewCombinerParameterfNV = NULL;
+PFNGLCOMBINERPARAMETERFVNVPROC __glewCombinerParameterfvNV = NULL;
+PFNGLCOMBINERPARAMETERINVPROC __glewCombinerParameteriNV = NULL;
+PFNGLCOMBINERPARAMETERIVNVPROC __glewCombinerParameterivNV = NULL;
+PFNGLFINALCOMBINERINPUTNVPROC __glewFinalCombinerInputNV = NULL;
+PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC __glewGetCombinerInputParameterfvNV = NULL;
+PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC __glewGetCombinerInputParameterivNV = NULL;
+PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC __glewGetCombinerOutputParameterfvNV = NULL;
+PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC __glewGetCombinerOutputParameterivNV = NULL;
+PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC __glewGetFinalCombinerInputParameterfvNV = NULL;
+PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC __glewGetFinalCombinerInputParameterivNV = NULL;
+
+PFNGLCOMBINERSTAGEPARAMETERFVNVPROC __glewCombinerStageParameterfvNV = NULL;
+PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC __glewGetCombinerStageParameterfvNV = NULL;
+
+PFNGLGETBUFFERPARAMETERUI64VNVPROC __glewGetBufferParameterui64vNV = NULL;
+PFNGLGETINTEGERUI64VNVPROC __glewGetIntegerui64vNV = NULL;
+PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC __glewGetNamedBufferParameterui64vNV = NULL;
+PFNGLISBUFFERRESIDENTNVPROC __glewIsBufferResidentNV = NULL;
+PFNGLISNAMEDBUFFERRESIDENTNVPROC __glewIsNamedBufferResidentNV = NULL;
+PFNGLMAKEBUFFERNONRESIDENTNVPROC __glewMakeBufferNonResidentNV = NULL;
+PFNGLMAKEBUFFERRESIDENTNVPROC __glewMakeBufferResidentNV = NULL;
+PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC __glewMakeNamedBufferNonResidentNV = NULL;
+PFNGLMAKENAMEDBUFFERRESIDENTNVPROC __glewMakeNamedBufferResidentNV = NULL;
+PFNGLPROGRAMUNIFORMUI64NVPROC __glewProgramUniformui64NV = NULL;
+PFNGLPROGRAMUNIFORMUI64VNVPROC __glewProgramUniformui64vNV = NULL;
+PFNGLUNIFORMUI64NVPROC __glewUniformui64NV = NULL;
+PFNGLUNIFORMUI64VNVPROC __glewUniformui64vNV = NULL;
+
+PFNGLTEXTUREBARRIERNVPROC __glewTextureBarrierNV = NULL;
+
+PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTexImage2DMultisampleCoverageNV = NULL;
+PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTexImage3DMultisampleCoverageNV = NULL;
+PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC __glewTextureImage2DMultisampleCoverageNV = NULL;
+PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC __glewTextureImage2DMultisampleNV = NULL;
+PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC __glewTextureImage3DMultisampleCoverageNV = NULL;
+PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC __glewTextureImage3DMultisampleNV = NULL;
+
+PFNGLACTIVEVARYINGNVPROC __glewActiveVaryingNV = NULL;
+PFNGLBEGINTRANSFORMFEEDBACKNVPROC __glewBeginTransformFeedbackNV = NULL;
+PFNGLBINDBUFFERBASENVPROC __glewBindBufferBaseNV = NULL;
+PFNGLBINDBUFFEROFFSETNVPROC __glewBindBufferOffsetNV = NULL;
+PFNGLBINDBUFFERRANGENVPROC __glewBindBufferRangeNV = NULL;
+PFNGLENDTRANSFORMFEEDBACKNVPROC __glewEndTransformFeedbackNV = NULL;
+PFNGLGETACTIVEVARYINGNVPROC __glewGetActiveVaryingNV = NULL;
+PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC __glewGetTransformFeedbackVaryingNV = NULL;
+PFNGLGETVARYINGLOCATIONNVPROC __glewGetVaryingLocationNV = NULL;
+PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC __glewTransformFeedbackAttribsNV = NULL;
+PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC __glewTransformFeedbackVaryingsNV = NULL;
+
+PFNGLBINDTRANSFORMFEEDBACKNVPROC __glewBindTransformFeedbackNV = NULL;
+PFNGLDELETETRANSFORMFEEDBACKSNVPROC __glewDeleteTransformFeedbacksNV = NULL;
+PFNGLDRAWTRANSFORMFEEDBACKNVPROC __glewDrawTransformFeedbackNV = NULL;
+PFNGLGENTRANSFORMFEEDBACKSNVPROC __glewGenTransformFeedbacksNV = NULL;
+PFNGLISTRANSFORMFEEDBACKNVPROC __glewIsTransformFeedbackNV = NULL;
+PFNGLPAUSETRANSFORMFEEDBACKNVPROC __glewPauseTransformFeedbackNV = NULL;
+PFNGLRESUMETRANSFORMFEEDBACKNVPROC __glewResumeTransformFeedbackNV = NULL;
+
+PFNGLVDPAUFININVPROC __glewVDPAUFiniNV = NULL;
+PFNGLVDPAUGETSURFACEIVNVPROC __glewVDPAUGetSurfaceivNV = NULL;
+PFNGLVDPAUINITNVPROC __glewVDPAUInitNV = NULL;
+PFNGLVDPAUISSURFACENVPROC __glewVDPAUIsSurfaceNV = NULL;
+PFNGLVDPAUMAPSURFACESNVPROC __glewVDPAUMapSurfacesNV = NULL;
+PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC __glewVDPAURegisterOutputSurfaceNV = NULL;
+PFNGLVDPAUREGISTERVIDEOSURFACENVPROC __glewVDPAURegisterVideoSurfaceNV = NULL;
+PFNGLVDPAUSURFACEACCESSNVPROC __glewVDPAUSurfaceAccessNV = NULL;
+PFNGLVDPAUUNMAPSURFACESNVPROC __glewVDPAUUnmapSurfacesNV = NULL;
+PFNGLVDPAUUNREGISTERSURFACENVPROC __glewVDPAUUnregisterSurfaceNV = NULL;
+
+PFNGLFLUSHVERTEXARRAYRANGENVPROC __glewFlushVertexArrayRangeNV = NULL;
+PFNGLVERTEXARRAYRANGENVPROC __glewVertexArrayRangeNV = NULL;
+
+PFNGLGETVERTEXATTRIBLI64VNVPROC __glewGetVertexAttribLi64vNV = NULL;
+PFNGLGETVERTEXATTRIBLUI64VNVPROC __glewGetVertexAttribLui64vNV = NULL;
+PFNGLVERTEXATTRIBL1I64NVPROC __glewVertexAttribL1i64NV = NULL;
+PFNGLVERTEXATTRIBL1I64VNVPROC __glewVertexAttribL1i64vNV = NULL;
+PFNGLVERTEXATTRIBL1UI64NVPROC __glewVertexAttribL1ui64NV = NULL;
+PFNGLVERTEXATTRIBL1UI64VNVPROC __glewVertexAttribL1ui64vNV = NULL;
+PFNGLVERTEXATTRIBL2I64NVPROC __glewVertexAttribL2i64NV = NULL;
+PFNGLVERTEXATTRIBL2I64VNVPROC __glewVertexAttribL2i64vNV = NULL;
+PFNGLVERTEXATTRIBL2UI64NVPROC __glewVertexAttribL2ui64NV = NULL;
+PFNGLVERTEXATTRIBL2UI64VNVPROC __glewVertexAttribL2ui64vNV = NULL;
+PFNGLVERTEXATTRIBL3I64NVPROC __glewVertexAttribL3i64NV = NULL;
+PFNGLVERTEXATTRIBL3I64VNVPROC __glewVertexAttribL3i64vNV = NULL;
+PFNGLVERTEXATTRIBL3UI64NVPROC __glewVertexAttribL3ui64NV = NULL;
+PFNGLVERTEXATTRIBL3UI64VNVPROC __glewVertexAttribL3ui64vNV = NULL;
+PFNGLVERTEXATTRIBL4I64NVPROC __glewVertexAttribL4i64NV = NULL;
+PFNGLVERTEXATTRIBL4I64VNVPROC __glewVertexAttribL4i64vNV = NULL;
+PFNGLVERTEXATTRIBL4UI64NVPROC __glewVertexAttribL4ui64NV = NULL;
+PFNGLVERTEXATTRIBL4UI64VNVPROC __glewVertexAttribL4ui64vNV = NULL;
+PFNGLVERTEXATTRIBLFORMATNVPROC __glewVertexAttribLFormatNV = NULL;
+
+PFNGLBUFFERADDRESSRANGENVPROC __glewBufferAddressRangeNV = NULL;
+PFNGLCOLORFORMATNVPROC __glewColorFormatNV = NULL;
+PFNGLEDGEFLAGFORMATNVPROC __glewEdgeFlagFormatNV = NULL;
+PFNGLFOGCOORDFORMATNVPROC __glewFogCoordFormatNV = NULL;
+PFNGLGETINTEGERUI64I_VNVPROC __glewGetIntegerui64i_vNV = NULL;
+PFNGLINDEXFORMATNVPROC __glewIndexFormatNV = NULL;
+PFNGLNORMALFORMATNVPROC __glewNormalFormatNV = NULL;
+PFNGLSECONDARYCOLORFORMATNVPROC __glewSecondaryColorFormatNV = NULL;
+PFNGLTEXCOORDFORMATNVPROC __glewTexCoordFormatNV = NULL;
+PFNGLVERTEXATTRIBFORMATNVPROC __glewVertexAttribFormatNV = NULL;
+PFNGLVERTEXATTRIBIFORMATNVPROC __glewVertexAttribIFormatNV = NULL;
+PFNGLVERTEXFORMATNVPROC __glewVertexFormatNV = NULL;
+
+PFNGLAREPROGRAMSRESIDENTNVPROC __glewAreProgramsResidentNV = NULL;
+PFNGLBINDPROGRAMNVPROC __glewBindProgramNV = NULL;
+PFNGLDELETEPROGRAMSNVPROC __glewDeleteProgramsNV = NULL;
+PFNGLEXECUTEPROGRAMNVPROC __glewExecuteProgramNV = NULL;
+PFNGLGENPROGRAMSNVPROC __glewGenProgramsNV = NULL;
+PFNGLGETPROGRAMPARAMETERDVNVPROC __glewGetProgramParameterdvNV = NULL;
+PFNGLGETPROGRAMPARAMETERFVNVPROC __glewGetProgramParameterfvNV = NULL;
+PFNGLGETPROGRAMSTRINGNVPROC __glewGetProgramStringNV = NULL;
+PFNGLGETPROGRAMIVNVPROC __glewGetProgramivNV = NULL;
+PFNGLGETTRACKMATRIXIVNVPROC __glewGetTrackMatrixivNV = NULL;
+PFNGLGETVERTEXATTRIBPOINTERVNVPROC __glewGetVertexAttribPointervNV = NULL;
+PFNGLGETVERTEXATTRIBDVNVPROC __glewGetVertexAttribdvNV = NULL;
+PFNGLGETVERTEXATTRIBFVNVPROC __glewGetVertexAttribfvNV = NULL;
+PFNGLGETVERTEXATTRIBIVNVPROC __glewGetVertexAttribivNV = NULL;
+PFNGLISPROGRAMNVPROC __glewIsProgramNV = NULL;
+PFNGLLOADPROGRAMNVPROC __glewLoadProgramNV = NULL;
+PFNGLPROGRAMPARAMETER4DNVPROC __glewProgramParameter4dNV = NULL;
+PFNGLPROGRAMPARAMETER4DVNVPROC __glewProgramParameter4dvNV = NULL;
+PFNGLPROGRAMPARAMETER4FNVPROC __glewProgramParameter4fNV = NULL;
+PFNGLPROGRAMPARAMETER4FVNVPROC __glewProgramParameter4fvNV = NULL;
+PFNGLPROGRAMPARAMETERS4DVNVPROC __glewProgramParameters4dvNV = NULL;
+PFNGLPROGRAMPARAMETERS4FVNVPROC __glewProgramParameters4fvNV = NULL;
+PFNGLREQUESTRESIDENTPROGRAMSNVPROC __glewRequestResidentProgramsNV = NULL;
+PFNGLTRACKMATRIXNVPROC __glewTrackMatrixNV = NULL;
+PFNGLVERTEXATTRIB1DNVPROC __glewVertexAttrib1dNV = NULL;
+PFNGLVERTEXATTRIB1DVNVPROC __glewVertexAttrib1dvNV = NULL;
+PFNGLVERTEXATTRIB1FNVPROC __glewVertexAttrib1fNV = NULL;
+PFNGLVERTEXATTRIB1FVNVPROC __glewVertexAttrib1fvNV = NULL;
+PFNGLVERTEXATTRIB1SNVPROC __glewVertexAttrib1sNV = NULL;
+PFNGLVERTEXATTRIB1SVNVPROC __glewVertexAttrib1svNV = NULL;
+PFNGLVERTEXATTRIB2DNVPROC __glewVertexAttrib2dNV = NULL;
+PFNGLVERTEXATTRIB2DVNVPROC __glewVertexAttrib2dvNV = NULL;
+PFNGLVERTEXATTRIB2FNVPROC __glewVertexAttrib2fNV = NULL;
+PFNGLVERTEXATTRIB2FVNVPROC __glewVertexAttrib2fvNV = NULL;
+PFNGLVERTEXATTRIB2SNVPROC __glewVertexAttrib2sNV = NULL;
+PFNGLVERTEXATTRIB2SVNVPROC __glewVertexAttrib2svNV = NULL;
+PFNGLVERTEXATTRIB3DNVPROC __glewVertexAttrib3dNV = NULL;
+PFNGLVERTEXATTRIB3DVNVPROC __glewVertexAttrib3dvNV = NULL;
+PFNGLVERTEXATTRIB3FNVPROC __glewVertexAttrib3fNV = NULL;
+PFNGLVERTEXATTRIB3FVNVPROC __glewVertexAttrib3fvNV = NULL;
+PFNGLVERTEXATTRIB3SNVPROC __glewVertexAttrib3sNV = NULL;
+PFNGLVERTEXATTRIB3SVNVPROC __glewVertexAttrib3svNV = NULL;
+PFNGLVERTEXATTRIB4DNVPROC __glewVertexAttrib4dNV = NULL;
+PFNGLVERTEXATTRIB4DVNVPROC __glewVertexAttrib4dvNV = NULL;
+PFNGLVERTEXATTRIB4FNVPROC __glewVertexAttrib4fNV = NULL;
+PFNGLVERTEXATTRIB4FVNVPROC __glewVertexAttrib4fvNV = NULL;
+PFNGLVERTEXATTRIB4SNVPROC __glewVertexAttrib4sNV = NULL;
+PFNGLVERTEXATTRIB4SVNVPROC __glewVertexAttrib4svNV = NULL;
+PFNGLVERTEXATTRIB4UBNVPROC __glewVertexAttrib4ubNV = NULL;
+PFNGLVERTEXATTRIB4UBVNVPROC __glewVertexAttrib4ubvNV = NULL;
+PFNGLVERTEXATTRIBPOINTERNVPROC __glewVertexAttribPointerNV = NULL;
+PFNGLVERTEXATTRIBS1DVNVPROC __glewVertexAttribs1dvNV = NULL;
+PFNGLVERTEXATTRIBS1FVNVPROC __glewVertexAttribs1fvNV = NULL;
+PFNGLVERTEXATTRIBS1SVNVPROC __glewVertexAttribs1svNV = NULL;
+PFNGLVERTEXATTRIBS2DVNVPROC __glewVertexAttribs2dvNV = NULL;
+PFNGLVERTEXATTRIBS2FVNVPROC __glewVertexAttribs2fvNV = NULL;
+PFNGLVERTEXATTRIBS2SVNVPROC __glewVertexAttribs2svNV = NULL;
+PFNGLVERTEXATTRIBS3DVNVPROC __glewVertexAttribs3dvNV = NULL;
+PFNGLVERTEXATTRIBS3FVNVPROC __glewVertexAttribs3fvNV = NULL;
+PFNGLVERTEXATTRIBS3SVNVPROC __glewVertexAttribs3svNV = NULL;
+PFNGLVERTEXATTRIBS4DVNVPROC __glewVertexAttribs4dvNV = NULL;
+PFNGLVERTEXATTRIBS4FVNVPROC __glewVertexAttribs4fvNV = NULL;
+PFNGLVERTEXATTRIBS4SVNVPROC __glewVertexAttribs4svNV = NULL;
+PFNGLVERTEXATTRIBS4UBVNVPROC __glewVertexAttribs4ubvNV = NULL;
+
+PFNGLBEGINVIDEOCAPTURENVPROC __glewBeginVideoCaptureNV = NULL;
+PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC __glewBindVideoCaptureStreamBufferNV = NULL;
+PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC __glewBindVideoCaptureStreamTextureNV = NULL;
+PFNGLENDVIDEOCAPTURENVPROC __glewEndVideoCaptureNV = NULL;
+PFNGLGETVIDEOCAPTURESTREAMDVNVPROC __glewGetVideoCaptureStreamdvNV = NULL;
+PFNGLGETVIDEOCAPTURESTREAMFVNVPROC __glewGetVideoCaptureStreamfvNV = NULL;
+PFNGLGETVIDEOCAPTURESTREAMIVNVPROC __glewGetVideoCaptureStreamivNV = NULL;
+PFNGLGETVIDEOCAPTUREIVNVPROC __glewGetVideoCaptureivNV = NULL;
+PFNGLVIDEOCAPTURENVPROC __glewVideoCaptureNV = NULL;
+PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC __glewVideoCaptureStreamParameterdvNV = NULL;
+PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC __glewVideoCaptureStreamParameterfvNV = NULL;
+PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC __glewVideoCaptureStreamParameterivNV = NULL;
+
+PFNGLCLEARDEPTHFOESPROC __glewClearDepthfOES = NULL;
+PFNGLCLIPPLANEFOESPROC __glewClipPlanefOES = NULL;
+PFNGLDEPTHRANGEFOESPROC __glewDepthRangefOES = NULL;
+PFNGLFRUSTUMFOESPROC __glewFrustumfOES = NULL;
+PFNGLGETCLIPPLANEFOESPROC __glewGetClipPlanefOES = NULL;
+PFNGLORTHOFOESPROC __glewOrthofOES = NULL;
+
+PFNGLALPHAFUNCXPROC __glewAlphaFuncx = NULL;
+PFNGLCLEARCOLORXPROC __glewClearColorx = NULL;
+PFNGLCLEARDEPTHXPROC __glewClearDepthx = NULL;
+PFNGLCOLOR4XPROC __glewColor4x = NULL;
+PFNGLDEPTHRANGEXPROC __glewDepthRangex = NULL;
+PFNGLFOGXPROC __glewFogx = NULL;
+PFNGLFOGXVPROC __glewFogxv = NULL;
+PFNGLFRUSTUMFPROC __glewFrustumf = NULL;
+PFNGLFRUSTUMXPROC __glewFrustumx = NULL;
+PFNGLLIGHTMODELXPROC __glewLightModelx = NULL;
+PFNGLLIGHTMODELXVPROC __glewLightModelxv = NULL;
+PFNGLLIGHTXPROC __glewLightx = NULL;
+PFNGLLIGHTXVPROC __glewLightxv = NULL;
+PFNGLLINEWIDTHXPROC __glewLineWidthx = NULL;
+PFNGLLOADMATRIXXPROC __glewLoadMatrixx = NULL;
+PFNGLMATERIALXPROC __glewMaterialx = NULL;
+PFNGLMATERIALXVPROC __glewMaterialxv = NULL;
+PFNGLMULTMATRIXXPROC __glewMultMatrixx = NULL;
+PFNGLMULTITEXCOORD4XPROC __glewMultiTexCoord4x = NULL;
+PFNGLNORMAL3XPROC __glewNormal3x = NULL;
+PFNGLORTHOFPROC __glewOrthof = NULL;
+PFNGLORTHOXPROC __glewOrthox = NULL;
+PFNGLPOINTSIZEXPROC __glewPointSizex = NULL;
+PFNGLPOLYGONOFFSETXPROC __glewPolygonOffsetx = NULL;
+PFNGLROTATEXPROC __glewRotatex = NULL;
+PFNGLSAMPLECOVERAGEXPROC __glewSampleCoveragex = NULL;
+PFNGLSCALEXPROC __glewScalex = NULL;
+PFNGLTEXENVXPROC __glewTexEnvx = NULL;
+PFNGLTEXENVXVPROC __glewTexEnvxv = NULL;
+PFNGLTEXPARAMETERXPROC __glewTexParameterx = NULL;
+PFNGLTRANSLATEXPROC __glewTranslatex = NULL;
+
+PFNGLCLIPPLANEFPROC __glewClipPlanef = NULL;
+PFNGLCLIPPLANEXPROC __glewClipPlanex = NULL;
+PFNGLGETCLIPPLANEFPROC __glewGetClipPlanef = NULL;
+PFNGLGETCLIPPLANEXPROC __glewGetClipPlanex = NULL;
+PFNGLGETFIXEDVPROC __glewGetFixedv = NULL;
+PFNGLGETLIGHTXVPROC __glewGetLightxv = NULL;
+PFNGLGETMATERIALXVPROC __glewGetMaterialxv = NULL;
+PFNGLGETTEXENVXVPROC __glewGetTexEnvxv = NULL;
+PFNGLGETTEXPARAMETERXVPROC __glewGetTexParameterxv = NULL;
+PFNGLPOINTPARAMETERXPROC __glewPointParameterx = NULL;
+PFNGLPOINTPARAMETERXVPROC __glewPointParameterxv = NULL;
+PFNGLPOINTSIZEPOINTEROESPROC __glewPointSizePointerOES = NULL;
+PFNGLTEXPARAMETERXVPROC __glewTexParameterxv = NULL;
+
+PFNGLERRORSTRINGREGALPROC __glewErrorStringREGAL = NULL;
+
+PFNGLGETEXTENSIONREGALPROC __glewGetExtensionREGAL = NULL;
+PFNGLISSUPPORTEDREGALPROC __glewIsSupportedREGAL = NULL;
+
+PFNGLLOGMESSAGECALLBACKREGALPROC __glewLogMessageCallbackREGAL = NULL;
+
+PFNGLDETAILTEXFUNCSGISPROC __glewDetailTexFuncSGIS = NULL;
+PFNGLGETDETAILTEXFUNCSGISPROC __glewGetDetailTexFuncSGIS = NULL;
+
+PFNGLFOGFUNCSGISPROC __glewFogFuncSGIS = NULL;
+PFNGLGETFOGFUNCSGISPROC __glewGetFogFuncSGIS = NULL;
+
+PFNGLSAMPLEMASKSGISPROC __glewSampleMaskSGIS = NULL;
+PFNGLSAMPLEPATTERNSGISPROC __glewSamplePatternSGIS = NULL;
+
+PFNGLGETSHARPENTEXFUNCSGISPROC __glewGetSharpenTexFuncSGIS = NULL;
+PFNGLSHARPENTEXFUNCSGISPROC __glewSharpenTexFuncSGIS = NULL;
+
+PFNGLTEXIMAGE4DSGISPROC __glewTexImage4DSGIS = NULL;
+PFNGLTEXSUBIMAGE4DSGISPROC __glewTexSubImage4DSGIS = NULL;
+
+PFNGLGETTEXFILTERFUNCSGISPROC __glewGetTexFilterFuncSGIS = NULL;
+PFNGLTEXFILTERFUNCSGISPROC __glewTexFilterFuncSGIS = NULL;
+
+PFNGLASYNCMARKERSGIXPROC __glewAsyncMarkerSGIX = NULL;
+PFNGLDELETEASYNCMARKERSSGIXPROC __glewDeleteAsyncMarkersSGIX = NULL;
+PFNGLFINISHASYNCSGIXPROC __glewFinishAsyncSGIX = NULL;
+PFNGLGENASYNCMARKERSSGIXPROC __glewGenAsyncMarkersSGIX = NULL;
+PFNGLISASYNCMARKERSGIXPROC __glewIsAsyncMarkerSGIX = NULL;
+PFNGLPOLLASYNCSGIXPROC __glewPollAsyncSGIX = NULL;
+
+PFNGLFLUSHRASTERSGIXPROC __glewFlushRasterSGIX = NULL;
+
+PFNGLTEXTUREFOGSGIXPROC __glewTextureFogSGIX = NULL;
+
+PFNGLFRAGMENTCOLORMATERIALSGIXPROC __glewFragmentColorMaterialSGIX = NULL;
+PFNGLFRAGMENTLIGHTMODELFSGIXPROC __glewFragmentLightModelfSGIX = NULL;
+PFNGLFRAGMENTLIGHTMODELFVSGIXPROC __glewFragmentLightModelfvSGIX = NULL;
+PFNGLFRAGMENTLIGHTMODELISGIXPROC __glewFragmentLightModeliSGIX = NULL;
+PFNGLFRAGMENTLIGHTMODELIVSGIXPROC __glewFragmentLightModelivSGIX = NULL;
+PFNGLFRAGMENTLIGHTFSGIXPROC __glewFragmentLightfSGIX = NULL;
+PFNGLFRAGMENTLIGHTFVSGIXPROC __glewFragmentLightfvSGIX = NULL;
+PFNGLFRAGMENTLIGHTISGIXPROC __glewFragmentLightiSGIX = NULL;
+PFNGLFRAGMENTLIGHTIVSGIXPROC __glewFragmentLightivSGIX = NULL;
+PFNGLFRAGMENTMATERIALFSGIXPROC __glewFragmentMaterialfSGIX = NULL;
+PFNGLFRAGMENTMATERIALFVSGIXPROC __glewFragmentMaterialfvSGIX = NULL;
+PFNGLFRAGMENTMATERIALISGIXPROC __glewFragmentMaterialiSGIX = NULL;
+PFNGLFRAGMENTMATERIALIVSGIXPROC __glewFragmentMaterialivSGIX = NULL;
+PFNGLGETFRAGMENTLIGHTFVSGIXPROC __glewGetFragmentLightfvSGIX = NULL;
+PFNGLGETFRAGMENTLIGHTIVSGIXPROC __glewGetFragmentLightivSGIX = NULL;
+PFNGLGETFRAGMENTMATERIALFVSGIXPROC __glewGetFragmentMaterialfvSGIX = NULL;
+PFNGLGETFRAGMENTMATERIALIVSGIXPROC __glewGetFragmentMaterialivSGIX = NULL;
+
+PFNGLFRAMEZOOMSGIXPROC __glewFrameZoomSGIX = NULL;
+
+PFNGLPIXELTEXGENSGIXPROC __glewPixelTexGenSGIX = NULL;
+
+PFNGLREFERENCEPLANESGIXPROC __glewReferencePlaneSGIX = NULL;
+
+PFNGLSPRITEPARAMETERFSGIXPROC __glewSpriteParameterfSGIX = NULL;
+PFNGLSPRITEPARAMETERFVSGIXPROC __glewSpriteParameterfvSGIX = NULL;
+PFNGLSPRITEPARAMETERISGIXPROC __glewSpriteParameteriSGIX = NULL;
+PFNGLSPRITEPARAMETERIVSGIXPROC __glewSpriteParameterivSGIX = NULL;
+
+PFNGLTAGSAMPLEBUFFERSGIXPROC __glewTagSampleBufferSGIX = NULL;
+
+PFNGLCOLORTABLEPARAMETERFVSGIPROC __glewColorTableParameterfvSGI = NULL;
+PFNGLCOLORTABLEPARAMETERIVSGIPROC __glewColorTableParameterivSGI = NULL;
+PFNGLCOLORTABLESGIPROC __glewColorTableSGI = NULL;
+PFNGLCOPYCOLORTABLESGIPROC __glewCopyColorTableSGI = NULL;
+PFNGLGETCOLORTABLEPARAMETERFVSGIPROC __glewGetColorTableParameterfvSGI = NULL;
+PFNGLGETCOLORTABLEPARAMETERIVSGIPROC __glewGetColorTableParameterivSGI = NULL;
+PFNGLGETCOLORTABLESGIPROC __glewGetColorTableSGI = NULL;
+
+PFNGLFINISHTEXTURESUNXPROC __glewFinishTextureSUNX = NULL;
+
+PFNGLGLOBALALPHAFACTORBSUNPROC __glewGlobalAlphaFactorbSUN = NULL;
+PFNGLGLOBALALPHAFACTORDSUNPROC __glewGlobalAlphaFactordSUN = NULL;
+PFNGLGLOBALALPHAFACTORFSUNPROC __glewGlobalAlphaFactorfSUN = NULL;
+PFNGLGLOBALALPHAFACTORISUNPROC __glewGlobalAlphaFactoriSUN = NULL;
+PFNGLGLOBALALPHAFACTORSSUNPROC __glewGlobalAlphaFactorsSUN = NULL;
+PFNGLGLOBALALPHAFACTORUBSUNPROC __glewGlobalAlphaFactorubSUN = NULL;
+PFNGLGLOBALALPHAFACTORUISUNPROC __glewGlobalAlphaFactoruiSUN = NULL;
+PFNGLGLOBALALPHAFACTORUSSUNPROC __glewGlobalAlphaFactorusSUN = NULL;
+
+PFNGLREADVIDEOPIXELSSUNPROC __glewReadVideoPixelsSUN = NULL;
+
+PFNGLREPLACEMENTCODEPOINTERSUNPROC __glewReplacementCodePointerSUN = NULL;
+PFNGLREPLACEMENTCODEUBSUNPROC __glewReplacementCodeubSUN = NULL;
+PFNGLREPLACEMENTCODEUBVSUNPROC __glewReplacementCodeubvSUN = NULL;
+PFNGLREPLACEMENTCODEUISUNPROC __glewReplacementCodeuiSUN = NULL;
+PFNGLREPLACEMENTCODEUIVSUNPROC __glewReplacementCodeuivSUN = NULL;
+PFNGLREPLACEMENTCODEUSSUNPROC __glewReplacementCodeusSUN = NULL;
+PFNGLREPLACEMENTCODEUSVSUNPROC __glewReplacementCodeusvSUN = NULL;
+
+PFNGLCOLOR3FVERTEX3FSUNPROC __glewColor3fVertex3fSUN = NULL;
+PFNGLCOLOR3FVERTEX3FVSUNPROC __glewColor3fVertex3fvSUN = NULL;
+PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewColor4fNormal3fVertex3fSUN = NULL;
+PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewColor4fNormal3fVertex3fvSUN = NULL;
+PFNGLCOLOR4UBVERTEX2FSUNPROC __glewColor4ubVertex2fSUN = NULL;
+PFNGLCOLOR4UBVERTEX2FVSUNPROC __glewColor4ubVertex2fvSUN = NULL;
+PFNGLCOLOR4UBVERTEX3FSUNPROC __glewColor4ubVertex3fSUN = NULL;
+PFNGLCOLOR4UBVERTEX3FVSUNPROC __glewColor4ubVertex3fvSUN = NULL;
+PFNGLNORMAL3FVERTEX3FSUNPROC __glewNormal3fVertex3fSUN = NULL;
+PFNGLNORMAL3FVERTEX3FVSUNPROC __glewNormal3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC __glewReplacementCodeuiColor3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiColor4fNormal3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC __glewReplacementCodeuiColor4ubVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC __glewReplacementCodeuiColor4ubVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiNormal3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiNormal3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC __glewReplacementCodeuiTexCoord2fVertex3fvSUN = NULL;
+PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC __glewReplacementCodeuiVertex3fSUN = NULL;
+PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC __glewReplacementCodeuiVertex3fvSUN = NULL;
+PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC __glewTexCoord2fColor3fVertex3fSUN = NULL;
+PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC __glewTexCoord2fColor3fVertex3fvSUN = NULL;
+PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fSUN = NULL;
+PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fColor4fNormal3fVertex3fvSUN = NULL;
+PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC __glewTexCoord2fColor4ubVertex3fSUN = NULL;
+PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC __glewTexCoord2fColor4ubVertex3fvSUN = NULL;
+PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC __glewTexCoord2fNormal3fVertex3fSUN = NULL;
+PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC __glewTexCoord2fNormal3fVertex3fvSUN = NULL;
+PFNGLTEXCOORD2FVERTEX3FSUNPROC __glewTexCoord2fVertex3fSUN = NULL;
+PFNGLTEXCOORD2FVERTEX3FVSUNPROC __glewTexCoord2fVertex3fvSUN = NULL;
+PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fSUN = NULL;
+PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC __glewTexCoord4fColor4fNormal3fVertex4fvSUN = NULL;
+PFNGLTEXCOORD4FVERTEX4FSUNPROC __glewTexCoord4fVertex4fSUN = NULL;
+PFNGLTEXCOORD4FVERTEX4FVSUNPROC __glewTexCoord4fVertex4fvSUN = NULL;
+
+PFNGLADDSWAPHINTRECTWINPROC __glewAddSwapHintRectWIN = NULL;
+
+#endif /* !WIN32 || !GLEW_MX */
+
+#if !defined(GLEW_MX)
+
+GLboolean __GLEW_VERSION_1_1 = GL_FALSE;
+GLboolean __GLEW_VERSION_1_2 = GL_FALSE;
+GLboolean __GLEW_VERSION_1_2_1 = GL_FALSE;
+GLboolean __GLEW_VERSION_1_3 = GL_FALSE;
+GLboolean __GLEW_VERSION_1_4 = GL_FALSE;
+GLboolean __GLEW_VERSION_1_5 = GL_FALSE;
+GLboolean __GLEW_VERSION_2_0 = GL_FALSE;
+GLboolean __GLEW_VERSION_2_1 = GL_FALSE;
+GLboolean __GLEW_VERSION_3_0 = GL_FALSE;
+GLboolean __GLEW_VERSION_3_1 = GL_FALSE;
+GLboolean __GLEW_VERSION_3_2 = GL_FALSE;
+GLboolean __GLEW_VERSION_3_3 = GL_FALSE;
+GLboolean __GLEW_VERSION_4_0 = GL_FALSE;
+GLboolean __GLEW_VERSION_4_1 = GL_FALSE;
+GLboolean __GLEW_VERSION_4_2 = GL_FALSE;
+GLboolean __GLEW_VERSION_4_3 = GL_FALSE;
+GLboolean __GLEW_VERSION_4_4 = GL_FALSE;
+GLboolean __GLEW_3DFX_multisample = GL_FALSE;
+GLboolean __GLEW_3DFX_tbuffer = GL_FALSE;
+GLboolean __GLEW_3DFX_texture_compression_FXT1 = GL_FALSE;
+GLboolean __GLEW_AMD_blend_minmax_factor = GL_FALSE;
+GLboolean __GLEW_AMD_conservative_depth = GL_FALSE;
+GLboolean __GLEW_AMD_debug_output = GL_FALSE;
+GLboolean __GLEW_AMD_depth_clamp_separate = GL_FALSE;
+GLboolean __GLEW_AMD_draw_buffers_blend = GL_FALSE;
+GLboolean __GLEW_AMD_interleaved_elements = GL_FALSE;
+GLboolean __GLEW_AMD_multi_draw_indirect = GL_FALSE;
+GLboolean __GLEW_AMD_name_gen_delete = GL_FALSE;
+GLboolean __GLEW_AMD_performance_monitor = GL_FALSE;
+GLboolean __GLEW_AMD_pinned_memory = GL_FALSE;
+GLboolean __GLEW_AMD_query_buffer_object = GL_FALSE;
+GLboolean __GLEW_AMD_sample_positions = GL_FALSE;
+GLboolean __GLEW_AMD_seamless_cubemap_per_texture = GL_FALSE;
+GLboolean __GLEW_AMD_shader_stencil_export = GL_FALSE;
+GLboolean __GLEW_AMD_shader_trinary_minmax = GL_FALSE;
+GLboolean __GLEW_AMD_sparse_texture = GL_FALSE;
+GLboolean __GLEW_AMD_stencil_operation_extended = GL_FALSE;
+GLboolean __GLEW_AMD_texture_texture4 = GL_FALSE;
+GLboolean __GLEW_AMD_transform_feedback3_lines_triangles = GL_FALSE;
+GLboolean __GLEW_AMD_vertex_shader_layer = GL_FALSE;
+GLboolean __GLEW_AMD_vertex_shader_tessellator = GL_FALSE;
+GLboolean __GLEW_AMD_vertex_shader_viewport_index = GL_FALSE;
+GLboolean __GLEW_ANGLE_depth_texture = GL_FALSE;
+GLboolean __GLEW_ANGLE_framebuffer_blit = GL_FALSE;
+GLboolean __GLEW_ANGLE_framebuffer_multisample = GL_FALSE;
+GLboolean __GLEW_ANGLE_instanced_arrays = GL_FALSE;
+GLboolean __GLEW_ANGLE_pack_reverse_row_order = GL_FALSE;
+GLboolean __GLEW_ANGLE_program_binary = GL_FALSE;
+GLboolean __GLEW_ANGLE_texture_compression_dxt1 = GL_FALSE;
+GLboolean __GLEW_ANGLE_texture_compression_dxt3 = GL_FALSE;
+GLboolean __GLEW_ANGLE_texture_compression_dxt5 = GL_FALSE;
+GLboolean __GLEW_ANGLE_texture_usage = GL_FALSE;
+GLboolean __GLEW_ANGLE_timer_query = GL_FALSE;
+GLboolean __GLEW_ANGLE_translated_shader_source = GL_FALSE;
+GLboolean __GLEW_APPLE_aux_depth_stencil = GL_FALSE;
+GLboolean __GLEW_APPLE_client_storage = GL_FALSE;
+GLboolean __GLEW_APPLE_element_array = GL_FALSE;
+GLboolean __GLEW_APPLE_fence = GL_FALSE;
+GLboolean __GLEW_APPLE_float_pixels = GL_FALSE;
+GLboolean __GLEW_APPLE_flush_buffer_range = GL_FALSE;
+GLboolean __GLEW_APPLE_object_purgeable = GL_FALSE;
+GLboolean __GLEW_APPLE_pixel_buffer = GL_FALSE;
+GLboolean __GLEW_APPLE_rgb_422 = GL_FALSE;
+GLboolean __GLEW_APPLE_row_bytes = GL_FALSE;
+GLboolean __GLEW_APPLE_specular_vector = GL_FALSE;
+GLboolean __GLEW_APPLE_texture_range = GL_FALSE;
+GLboolean __GLEW_APPLE_transform_hint = GL_FALSE;
+GLboolean __GLEW_APPLE_vertex_array_object = GL_FALSE;
+GLboolean __GLEW_APPLE_vertex_array_range = GL_FALSE;
+GLboolean __GLEW_APPLE_vertex_program_evaluators = GL_FALSE;
+GLboolean __GLEW_APPLE_ycbcr_422 = GL_FALSE;
+GLboolean __GLEW_ARB_ES2_compatibility = GL_FALSE;
+GLboolean __GLEW_ARB_ES3_compatibility = GL_FALSE;
+GLboolean __GLEW_ARB_arrays_of_arrays = GL_FALSE;
+GLboolean __GLEW_ARB_base_instance = GL_FALSE;
+GLboolean __GLEW_ARB_bindless_texture = GL_FALSE;
+GLboolean __GLEW_ARB_blend_func_extended = GL_FALSE;
+GLboolean __GLEW_ARB_buffer_storage = GL_FALSE;
+GLboolean __GLEW_ARB_cl_event = GL_FALSE;
+GLboolean __GLEW_ARB_clear_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_clear_texture = GL_FALSE;
+GLboolean __GLEW_ARB_color_buffer_float = GL_FALSE;
+GLboolean __GLEW_ARB_compatibility = GL_FALSE;
+GLboolean __GLEW_ARB_compressed_texture_pixel_storage = GL_FALSE;
+GLboolean __GLEW_ARB_compute_shader = GL_FALSE;
+GLboolean __GLEW_ARB_compute_variable_group_size = GL_FALSE;
+GLboolean __GLEW_ARB_conservative_depth = GL_FALSE;
+GLboolean __GLEW_ARB_copy_buffer = GL_FALSE;
+GLboolean __GLEW_ARB_copy_image = GL_FALSE;
+GLboolean __GLEW_ARB_debug_output = GL_FALSE;
+GLboolean __GLEW_ARB_depth_buffer_float = GL_FALSE;
+GLboolean __GLEW_ARB_depth_clamp = GL_FALSE;
+GLboolean __GLEW_ARB_depth_texture = GL_FALSE;
+GLboolean __GLEW_ARB_draw_buffers = GL_FALSE;
+GLboolean __GLEW_ARB_draw_buffers_blend = GL_FALSE;
+GLboolean __GLEW_ARB_draw_elements_base_vertex = GL_FALSE;
+GLboolean __GLEW_ARB_draw_indirect = GL_FALSE;
+GLboolean __GLEW_ARB_draw_instanced = GL_FALSE;
+GLboolean __GLEW_ARB_enhanced_layouts = GL_FALSE;
+GLboolean __GLEW_ARB_explicit_attrib_location = GL_FALSE;
+GLboolean __GLEW_ARB_explicit_uniform_location = GL_FALSE;
+GLboolean __GLEW_ARB_fragment_coord_conventions = GL_FALSE;
+GLboolean __GLEW_ARB_fragment_layer_viewport = GL_FALSE;
+GLboolean __GLEW_ARB_fragment_program = GL_FALSE;
+GLboolean __GLEW_ARB_fragment_program_shadow = GL_FALSE;
+GLboolean __GLEW_ARB_fragment_shader = GL_FALSE;
+GLboolean __GLEW_ARB_framebuffer_no_attachments = GL_FALSE;
+GLboolean __GLEW_ARB_framebuffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_framebuffer_sRGB = GL_FALSE;
+GLboolean __GLEW_ARB_geometry_shader4 = GL_FALSE;
+GLboolean __GLEW_ARB_get_program_binary = GL_FALSE;
+GLboolean __GLEW_ARB_gpu_shader5 = GL_FALSE;
+GLboolean __GLEW_ARB_gpu_shader_fp64 = GL_FALSE;
+GLboolean __GLEW_ARB_half_float_pixel = GL_FALSE;
+GLboolean __GLEW_ARB_half_float_vertex = GL_FALSE;
+GLboolean __GLEW_ARB_imaging = GL_FALSE;
+GLboolean __GLEW_ARB_indirect_parameters = GL_FALSE;
+GLboolean __GLEW_ARB_instanced_arrays = GL_FALSE;
+GLboolean __GLEW_ARB_internalformat_query = GL_FALSE;
+GLboolean __GLEW_ARB_internalformat_query2 = GL_FALSE;
+GLboolean __GLEW_ARB_invalidate_subdata = GL_FALSE;
+GLboolean __GLEW_ARB_map_buffer_alignment = GL_FALSE;
+GLboolean __GLEW_ARB_map_buffer_range = GL_FALSE;
+GLboolean __GLEW_ARB_matrix_palette = GL_FALSE;
+GLboolean __GLEW_ARB_multi_bind = GL_FALSE;
+GLboolean __GLEW_ARB_multi_draw_indirect = GL_FALSE;
+GLboolean __GLEW_ARB_multisample = GL_FALSE;
+GLboolean __GLEW_ARB_multitexture = GL_FALSE;
+GLboolean __GLEW_ARB_occlusion_query = GL_FALSE;
+GLboolean __GLEW_ARB_occlusion_query2 = GL_FALSE;
+GLboolean __GLEW_ARB_pixel_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_point_parameters = GL_FALSE;
+GLboolean __GLEW_ARB_point_sprite = GL_FALSE;
+GLboolean __GLEW_ARB_program_interface_query = GL_FALSE;
+GLboolean __GLEW_ARB_provoking_vertex = GL_FALSE;
+GLboolean __GLEW_ARB_query_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_robust_buffer_access_behavior = GL_FALSE;
+GLboolean __GLEW_ARB_robustness = GL_FALSE;
+GLboolean __GLEW_ARB_robustness_application_isolation = GL_FALSE;
+GLboolean __GLEW_ARB_robustness_share_group_isolation = GL_FALSE;
+GLboolean __GLEW_ARB_sample_shading = GL_FALSE;
+GLboolean __GLEW_ARB_sampler_objects = GL_FALSE;
+GLboolean __GLEW_ARB_seamless_cube_map = GL_FALSE;
+GLboolean __GLEW_ARB_seamless_cubemap_per_texture = GL_FALSE;
+GLboolean __GLEW_ARB_separate_shader_objects = GL_FALSE;
+GLboolean __GLEW_ARB_shader_atomic_counters = GL_FALSE;
+GLboolean __GLEW_ARB_shader_bit_encoding = GL_FALSE;
+GLboolean __GLEW_ARB_shader_draw_parameters = GL_FALSE;
+GLboolean __GLEW_ARB_shader_group_vote = GL_FALSE;
+GLboolean __GLEW_ARB_shader_image_load_store = GL_FALSE;
+GLboolean __GLEW_ARB_shader_image_size = GL_FALSE;
+GLboolean __GLEW_ARB_shader_objects = GL_FALSE;
+GLboolean __GLEW_ARB_shader_precision = GL_FALSE;
+GLboolean __GLEW_ARB_shader_stencil_export = GL_FALSE;
+GLboolean __GLEW_ARB_shader_storage_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_shader_subroutine = GL_FALSE;
+GLboolean __GLEW_ARB_shader_texture_lod = GL_FALSE;
+GLboolean __GLEW_ARB_shading_language_100 = GL_FALSE;
+GLboolean __GLEW_ARB_shading_language_420pack = GL_FALSE;
+GLboolean __GLEW_ARB_shading_language_include = GL_FALSE;
+GLboolean __GLEW_ARB_shading_language_packing = GL_FALSE;
+GLboolean __GLEW_ARB_shadow = GL_FALSE;
+GLboolean __GLEW_ARB_shadow_ambient = GL_FALSE;
+GLboolean __GLEW_ARB_sparse_texture = GL_FALSE;
+GLboolean __GLEW_ARB_stencil_texturing = GL_FALSE;
+GLboolean __GLEW_ARB_sync = GL_FALSE;
+GLboolean __GLEW_ARB_tessellation_shader = GL_FALSE;
+GLboolean __GLEW_ARB_texture_border_clamp = GL_FALSE;
+GLboolean __GLEW_ARB_texture_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_texture_buffer_object_rgb32 = GL_FALSE;
+GLboolean __GLEW_ARB_texture_buffer_range = GL_FALSE;
+GLboolean __GLEW_ARB_texture_compression = GL_FALSE;
+GLboolean __GLEW_ARB_texture_compression_bptc = GL_FALSE;
+GLboolean __GLEW_ARB_texture_compression_rgtc = GL_FALSE;
+GLboolean __GLEW_ARB_texture_cube_map = GL_FALSE;
+GLboolean __GLEW_ARB_texture_cube_map_array = GL_FALSE;
+GLboolean __GLEW_ARB_texture_env_add = GL_FALSE;
+GLboolean __GLEW_ARB_texture_env_combine = GL_FALSE;
+GLboolean __GLEW_ARB_texture_env_crossbar = GL_FALSE;
+GLboolean __GLEW_ARB_texture_env_dot3 = GL_FALSE;
+GLboolean __GLEW_ARB_texture_float = GL_FALSE;
+GLboolean __GLEW_ARB_texture_gather = GL_FALSE;
+GLboolean __GLEW_ARB_texture_mirror_clamp_to_edge = GL_FALSE;
+GLboolean __GLEW_ARB_texture_mirrored_repeat = GL_FALSE;
+GLboolean __GLEW_ARB_texture_multisample = GL_FALSE;
+GLboolean __GLEW_ARB_texture_non_power_of_two = GL_FALSE;
+GLboolean __GLEW_ARB_texture_query_levels = GL_FALSE;
+GLboolean __GLEW_ARB_texture_query_lod = GL_FALSE;
+GLboolean __GLEW_ARB_texture_rectangle = GL_FALSE;
+GLboolean __GLEW_ARB_texture_rg = GL_FALSE;
+GLboolean __GLEW_ARB_texture_rgb10_a2ui = GL_FALSE;
+GLboolean __GLEW_ARB_texture_stencil8 = GL_FALSE;
+GLboolean __GLEW_ARB_texture_storage = GL_FALSE;
+GLboolean __GLEW_ARB_texture_storage_multisample = GL_FALSE;
+GLboolean __GLEW_ARB_texture_swizzle = GL_FALSE;
+GLboolean __GLEW_ARB_texture_view = GL_FALSE;
+GLboolean __GLEW_ARB_timer_query = GL_FALSE;
+GLboolean __GLEW_ARB_transform_feedback2 = GL_FALSE;
+GLboolean __GLEW_ARB_transform_feedback3 = GL_FALSE;
+GLboolean __GLEW_ARB_transform_feedback_instanced = GL_FALSE;
+GLboolean __GLEW_ARB_transpose_matrix = GL_FALSE;
+GLboolean __GLEW_ARB_uniform_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_array_bgra = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_array_object = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_attrib_64bit = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_attrib_binding = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_blend = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_buffer_object = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_program = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_shader = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_type_10f_11f_11f_rev = GL_FALSE;
+GLboolean __GLEW_ARB_vertex_type_2_10_10_10_rev = GL_FALSE;
+GLboolean __GLEW_ARB_viewport_array = GL_FALSE;
+GLboolean __GLEW_ARB_window_pos = GL_FALSE;
+GLboolean __GLEW_ATIX_point_sprites = GL_FALSE;
+GLboolean __GLEW_ATIX_texture_env_combine3 = GL_FALSE;
+GLboolean __GLEW_ATIX_texture_env_route = GL_FALSE;
+GLboolean __GLEW_ATIX_vertex_shader_output_point_size = GL_FALSE;
+GLboolean __GLEW_ATI_draw_buffers = GL_FALSE;
+GLboolean __GLEW_ATI_element_array = GL_FALSE;
+GLboolean __GLEW_ATI_envmap_bumpmap = GL_FALSE;
+GLboolean __GLEW_ATI_fragment_shader = GL_FALSE;
+GLboolean __GLEW_ATI_map_object_buffer = GL_FALSE;
+GLboolean __GLEW_ATI_meminfo = GL_FALSE;
+GLboolean __GLEW_ATI_pn_triangles = GL_FALSE;
+GLboolean __GLEW_ATI_separate_stencil = GL_FALSE;
+GLboolean __GLEW_ATI_shader_texture_lod = GL_FALSE;
+GLboolean __GLEW_ATI_text_fragment_shader = GL_FALSE;
+GLboolean __GLEW_ATI_texture_compression_3dc = GL_FALSE;
+GLboolean __GLEW_ATI_texture_env_combine3 = GL_FALSE;
+GLboolean __GLEW_ATI_texture_float = GL_FALSE;
+GLboolean __GLEW_ATI_texture_mirror_once = GL_FALSE;
+GLboolean __GLEW_ATI_vertex_array_object = GL_FALSE;
+GLboolean __GLEW_ATI_vertex_attrib_array_object = GL_FALSE;
+GLboolean __GLEW_ATI_vertex_streams = GL_FALSE;
+GLboolean __GLEW_EXT_422_pixels = GL_FALSE;
+GLboolean __GLEW_EXT_Cg_shader = GL_FALSE;
+GLboolean __GLEW_EXT_abgr = GL_FALSE;
+GLboolean __GLEW_EXT_bgra = GL_FALSE;
+GLboolean __GLEW_EXT_bindable_uniform = GL_FALSE;
+GLboolean __GLEW_EXT_blend_color = GL_FALSE;
+GLboolean __GLEW_EXT_blend_equation_separate = GL_FALSE;
+GLboolean __GLEW_EXT_blend_func_separate = GL_FALSE;
+GLboolean __GLEW_EXT_blend_logic_op = GL_FALSE;
+GLboolean __GLEW_EXT_blend_minmax = GL_FALSE;
+GLboolean __GLEW_EXT_blend_subtract = GL_FALSE;
+GLboolean __GLEW_EXT_clip_volume_hint = GL_FALSE;
+GLboolean __GLEW_EXT_cmyka = GL_FALSE;
+GLboolean __GLEW_EXT_color_subtable = GL_FALSE;
+GLboolean __GLEW_EXT_compiled_vertex_array = GL_FALSE;
+GLboolean __GLEW_EXT_convolution = GL_FALSE;
+GLboolean __GLEW_EXT_coordinate_frame = GL_FALSE;
+GLboolean __GLEW_EXT_copy_texture = GL_FALSE;
+GLboolean __GLEW_EXT_cull_vertex = GL_FALSE;
+GLboolean __GLEW_EXT_debug_marker = GL_FALSE;
+GLboolean __GLEW_EXT_depth_bounds_test = GL_FALSE;
+GLboolean __GLEW_EXT_direct_state_access = GL_FALSE;
+GLboolean __GLEW_EXT_draw_buffers2 = GL_FALSE;
+GLboolean __GLEW_EXT_draw_instanced = GL_FALSE;
+GLboolean __GLEW_EXT_draw_range_elements = GL_FALSE;
+GLboolean __GLEW_EXT_fog_coord = GL_FALSE;
+GLboolean __GLEW_EXT_fragment_lighting = GL_FALSE;
+GLboolean __GLEW_EXT_framebuffer_blit = GL_FALSE;
+GLboolean __GLEW_EXT_framebuffer_multisample = GL_FALSE;
+GLboolean __GLEW_EXT_framebuffer_multisample_blit_scaled = GL_FALSE;
+GLboolean __GLEW_EXT_framebuffer_object = GL_FALSE;
+GLboolean __GLEW_EXT_framebuffer_sRGB = GL_FALSE;
+GLboolean __GLEW_EXT_geometry_shader4 = GL_FALSE;
+GLboolean __GLEW_EXT_gpu_program_parameters = GL_FALSE;
+GLboolean __GLEW_EXT_gpu_shader4 = GL_FALSE;
+GLboolean __GLEW_EXT_histogram = GL_FALSE;
+GLboolean __GLEW_EXT_index_array_formats = GL_FALSE;
+GLboolean __GLEW_EXT_index_func = GL_FALSE;
+GLboolean __GLEW_EXT_index_material = GL_FALSE;
+GLboolean __GLEW_EXT_index_texture = GL_FALSE;
+GLboolean __GLEW_EXT_light_texture = GL_FALSE;
+GLboolean __GLEW_EXT_misc_attribute = GL_FALSE;
+GLboolean __GLEW_EXT_multi_draw_arrays = GL_FALSE;
+GLboolean __GLEW_EXT_multisample = GL_FALSE;
+GLboolean __GLEW_EXT_packed_depth_stencil = GL_FALSE;
+GLboolean __GLEW_EXT_packed_float = GL_FALSE;
+GLboolean __GLEW_EXT_packed_pixels = GL_FALSE;
+GLboolean __GLEW_EXT_paletted_texture = GL_FALSE;
+GLboolean __GLEW_EXT_pixel_buffer_object = GL_FALSE;
+GLboolean __GLEW_EXT_pixel_transform = GL_FALSE;
+GLboolean __GLEW_EXT_pixel_transform_color_table = GL_FALSE;
+GLboolean __GLEW_EXT_point_parameters = GL_FALSE;
+GLboolean __GLEW_EXT_polygon_offset = GL_FALSE;
+GLboolean __GLEW_EXT_provoking_vertex = GL_FALSE;
+GLboolean __GLEW_EXT_rescale_normal = GL_FALSE;
+GLboolean __GLEW_EXT_scene_marker = GL_FALSE;
+GLboolean __GLEW_EXT_secondary_color = GL_FALSE;
+GLboolean __GLEW_EXT_separate_shader_objects = GL_FALSE;
+GLboolean __GLEW_EXT_separate_specular_color = GL_FALSE;
+GLboolean __GLEW_EXT_shader_image_load_store = GL_FALSE;
+GLboolean __GLEW_EXT_shadow_funcs = GL_FALSE;
+GLboolean __GLEW_EXT_shared_texture_palette = GL_FALSE;
+GLboolean __GLEW_EXT_stencil_clear_tag = GL_FALSE;
+GLboolean __GLEW_EXT_stencil_two_side = GL_FALSE;
+GLboolean __GLEW_EXT_stencil_wrap = GL_FALSE;
+GLboolean __GLEW_EXT_subtexture = GL_FALSE;
+GLboolean __GLEW_EXT_texture = GL_FALSE;
+GLboolean __GLEW_EXT_texture3D = GL_FALSE;
+GLboolean __GLEW_EXT_texture_array = GL_FALSE;
+GLboolean __GLEW_EXT_texture_buffer_object = GL_FALSE;
+GLboolean __GLEW_EXT_texture_compression_dxt1 = GL_FALSE;
+GLboolean __GLEW_EXT_texture_compression_latc = GL_FALSE;
+GLboolean __GLEW_EXT_texture_compression_rgtc = GL_FALSE;
+GLboolean __GLEW_EXT_texture_compression_s3tc = GL_FALSE;
+GLboolean __GLEW_EXT_texture_cube_map = GL_FALSE;
+GLboolean __GLEW_EXT_texture_edge_clamp = GL_FALSE;
+GLboolean __GLEW_EXT_texture_env = GL_FALSE;
+GLboolean __GLEW_EXT_texture_env_add = GL_FALSE;
+GLboolean __GLEW_EXT_texture_env_combine = GL_FALSE;
+GLboolean __GLEW_EXT_texture_env_dot3 = GL_FALSE;
+GLboolean __GLEW_EXT_texture_filter_anisotropic = GL_FALSE;
+GLboolean __GLEW_EXT_texture_integer = GL_FALSE;
+GLboolean __GLEW_EXT_texture_lod_bias = GL_FALSE;
+GLboolean __GLEW_EXT_texture_mirror_clamp = GL_FALSE;
+GLboolean __GLEW_EXT_texture_object = GL_FALSE;
+GLboolean __GLEW_EXT_texture_perturb_normal = GL_FALSE;
+GLboolean __GLEW_EXT_texture_rectangle = GL_FALSE;
+GLboolean __GLEW_EXT_texture_sRGB = GL_FALSE;
+GLboolean __GLEW_EXT_texture_sRGB_decode = GL_FALSE;
+GLboolean __GLEW_EXT_texture_shared_exponent = GL_FALSE;
+GLboolean __GLEW_EXT_texture_snorm = GL_FALSE;
+GLboolean __GLEW_EXT_texture_swizzle = GL_FALSE;
+GLboolean __GLEW_EXT_timer_query = GL_FALSE;
+GLboolean __GLEW_EXT_transform_feedback = GL_FALSE;
+GLboolean __GLEW_EXT_vertex_array = GL_FALSE;
+GLboolean __GLEW_EXT_vertex_array_bgra = GL_FALSE;
+GLboolean __GLEW_EXT_vertex_attrib_64bit = GL_FALSE;
+GLboolean __GLEW_EXT_vertex_shader = GL_FALSE;
+GLboolean __GLEW_EXT_vertex_weighting = GL_FALSE;
+GLboolean __GLEW_EXT_x11_sync_object = GL_FALSE;
+GLboolean __GLEW_GREMEDY_frame_terminator = GL_FALSE;
+GLboolean __GLEW_GREMEDY_string_marker = GL_FALSE;
+GLboolean __GLEW_HP_convolution_border_modes = GL_FALSE;
+GLboolean __GLEW_HP_image_transform = GL_FALSE;
+GLboolean __GLEW_HP_occlusion_test = GL_FALSE;
+GLboolean __GLEW_HP_texture_lighting = GL_FALSE;
+GLboolean __GLEW_IBM_cull_vertex = GL_FALSE;
+GLboolean __GLEW_IBM_multimode_draw_arrays = GL_FALSE;
+GLboolean __GLEW_IBM_rasterpos_clip = GL_FALSE;
+GLboolean __GLEW_IBM_static_data = GL_FALSE;
+GLboolean __GLEW_IBM_texture_mirrored_repeat = GL_FALSE;
+GLboolean __GLEW_IBM_vertex_array_lists = GL_FALSE;
+GLboolean __GLEW_INGR_color_clamp = GL_FALSE;
+GLboolean __GLEW_INGR_interlace_read = GL_FALSE;
+GLboolean __GLEW_INTEL_map_texture = GL_FALSE;
+GLboolean __GLEW_INTEL_parallel_arrays = GL_FALSE;
+GLboolean __GLEW_INTEL_texture_scissor = GL_FALSE;
+GLboolean __GLEW_KHR_debug = GL_FALSE;
+GLboolean __GLEW_KHR_texture_compression_astc_ldr = GL_FALSE;
+GLboolean __GLEW_KTX_buffer_region = GL_FALSE;
+GLboolean __GLEW_MESAX_texture_stack = GL_FALSE;
+GLboolean __GLEW_MESA_pack_invert = GL_FALSE;
+GLboolean __GLEW_MESA_resize_buffers = GL_FALSE;
+GLboolean __GLEW_MESA_window_pos = GL_FALSE;
+GLboolean __GLEW_MESA_ycbcr_texture = GL_FALSE;
+GLboolean __GLEW_NVX_conditional_render = GL_FALSE;
+GLboolean __GLEW_NVX_gpu_memory_info = GL_FALSE;
+GLboolean __GLEW_NV_bindless_multi_draw_indirect = GL_FALSE;
+GLboolean __GLEW_NV_bindless_texture = GL_FALSE;
+GLboolean __GLEW_NV_blend_equation_advanced = GL_FALSE;
+GLboolean __GLEW_NV_blend_equation_advanced_coherent = GL_FALSE;
+GLboolean __GLEW_NV_blend_square = GL_FALSE;
+GLboolean __GLEW_NV_compute_program5 = GL_FALSE;
+GLboolean __GLEW_NV_conditional_render = GL_FALSE;
+GLboolean __GLEW_NV_copy_depth_to_color = GL_FALSE;
+GLboolean __GLEW_NV_copy_image = GL_FALSE;
+GLboolean __GLEW_NV_deep_texture3D = GL_FALSE;
+GLboolean __GLEW_NV_depth_buffer_float = GL_FALSE;
+GLboolean __GLEW_NV_depth_clamp = GL_FALSE;
+GLboolean __GLEW_NV_depth_range_unclamped = GL_FALSE;
+GLboolean __GLEW_NV_draw_texture = GL_FALSE;
+GLboolean __GLEW_NV_evaluators = GL_FALSE;
+GLboolean __GLEW_NV_explicit_multisample = GL_FALSE;
+GLboolean __GLEW_NV_fence = GL_FALSE;
+GLboolean __GLEW_NV_float_buffer = GL_FALSE;
+GLboolean __GLEW_NV_fog_distance = GL_FALSE;
+GLboolean __GLEW_NV_fragment_program = GL_FALSE;
+GLboolean __GLEW_NV_fragment_program2 = GL_FALSE;
+GLboolean __GLEW_NV_fragment_program4 = GL_FALSE;
+GLboolean __GLEW_NV_fragment_program_option = GL_FALSE;
+GLboolean __GLEW_NV_framebuffer_multisample_coverage = GL_FALSE;
+GLboolean __GLEW_NV_geometry_program4 = GL_FALSE;
+GLboolean __GLEW_NV_geometry_shader4 = GL_FALSE;
+GLboolean __GLEW_NV_gpu_program4 = GL_FALSE;
+GLboolean __GLEW_NV_gpu_program5 = GL_FALSE;
+GLboolean __GLEW_NV_gpu_program5_mem_extended = GL_FALSE;
+GLboolean __GLEW_NV_gpu_program_fp64 = GL_FALSE;
+GLboolean __GLEW_NV_gpu_shader5 = GL_FALSE;
+GLboolean __GLEW_NV_half_float = GL_FALSE;
+GLboolean __GLEW_NV_light_max_exponent = GL_FALSE;
+GLboolean __GLEW_NV_multisample_coverage = GL_FALSE;
+GLboolean __GLEW_NV_multisample_filter_hint = GL_FALSE;
+GLboolean __GLEW_NV_occlusion_query = GL_FALSE;
+GLboolean __GLEW_NV_packed_depth_stencil = GL_FALSE;
+GLboolean __GLEW_NV_parameter_buffer_object = GL_FALSE;
+GLboolean __GLEW_NV_parameter_buffer_object2 = GL_FALSE;
+GLboolean __GLEW_NV_path_rendering = GL_FALSE;
+GLboolean __GLEW_NV_pixel_data_range = GL_FALSE;
+GLboolean __GLEW_NV_point_sprite = GL_FALSE;
+GLboolean __GLEW_NV_present_video = GL_FALSE;
+GLboolean __GLEW_NV_primitive_restart = GL_FALSE;
+GLboolean __GLEW_NV_register_combiners = GL_FALSE;
+GLboolean __GLEW_NV_register_combiners2 = GL_FALSE;
+GLboolean __GLEW_NV_shader_atomic_counters = GL_FALSE;
+GLboolean __GLEW_NV_shader_atomic_float = GL_FALSE;
+GLboolean __GLEW_NV_shader_buffer_load = GL_FALSE;
+GLboolean __GLEW_NV_shader_storage_buffer_object = GL_FALSE;
+GLboolean __GLEW_NV_tessellation_program5 = GL_FALSE;
+GLboolean __GLEW_NV_texgen_emboss = GL_FALSE;
+GLboolean __GLEW_NV_texgen_reflection = GL_FALSE;
+GLboolean __GLEW_NV_texture_barrier = GL_FALSE;
+GLboolean __GLEW_NV_texture_compression_vtc = GL_FALSE;
+GLboolean __GLEW_NV_texture_env_combine4 = GL_FALSE;
+GLboolean __GLEW_NV_texture_expand_normal = GL_FALSE;
+GLboolean __GLEW_NV_texture_multisample = GL_FALSE;
+GLboolean __GLEW_NV_texture_rectangle = GL_FALSE;
+GLboolean __GLEW_NV_texture_shader = GL_FALSE;
+GLboolean __GLEW_NV_texture_shader2 = GL_FALSE;
+GLboolean __GLEW_NV_texture_shader3 = GL_FALSE;
+GLboolean __GLEW_NV_transform_feedback = GL_FALSE;
+GLboolean __GLEW_NV_transform_feedback2 = GL_FALSE;
+GLboolean __GLEW_NV_vdpau_interop = GL_FALSE;
+GLboolean __GLEW_NV_vertex_array_range = GL_FALSE;
+GLboolean __GLEW_NV_vertex_array_range2 = GL_FALSE;
+GLboolean __GLEW_NV_vertex_attrib_integer_64bit = GL_FALSE;
+GLboolean __GLEW_NV_vertex_buffer_unified_memory = GL_FALSE;
+GLboolean __GLEW_NV_vertex_program = GL_FALSE;
+GLboolean __GLEW_NV_vertex_program1_1 = GL_FALSE;
+GLboolean __GLEW_NV_vertex_program2 = GL_FALSE;
+GLboolean __GLEW_NV_vertex_program2_option = GL_FALSE;
+GLboolean __GLEW_NV_vertex_program3 = GL_FALSE;
+GLboolean __GLEW_NV_vertex_program4 = GL_FALSE;
+GLboolean __GLEW_NV_video_capture = GL_FALSE;
+GLboolean __GLEW_OES_byte_coordinates = GL_FALSE;
+GLboolean __GLEW_OES_compressed_paletted_texture = GL_FALSE;
+GLboolean __GLEW_OES_read_format = GL_FALSE;
+GLboolean __GLEW_OES_single_precision = GL_FALSE;
+GLboolean __GLEW_OML_interlace = GL_FALSE;
+GLboolean __GLEW_OML_resample = GL_FALSE;
+GLboolean __GLEW_OML_subsample = GL_FALSE;
+GLboolean __GLEW_PGI_misc_hints = GL_FALSE;
+GLboolean __GLEW_PGI_vertex_hints = GL_FALSE;
+GLboolean __GLEW_REGAL_ES1_0_compatibility = GL_FALSE;
+GLboolean __GLEW_REGAL_ES1_1_compatibility = GL_FALSE;
+GLboolean __GLEW_REGAL_enable = GL_FALSE;
+GLboolean __GLEW_REGAL_error_string = GL_FALSE;
+GLboolean __GLEW_REGAL_extension_query = GL_FALSE;
+GLboolean __GLEW_REGAL_log = GL_FALSE;
+GLboolean __GLEW_REND_screen_coordinates = GL_FALSE;
+GLboolean __GLEW_S3_s3tc = GL_FALSE;
+GLboolean __GLEW_SGIS_color_range = GL_FALSE;
+GLboolean __GLEW_SGIS_detail_texture = GL_FALSE;
+GLboolean __GLEW_SGIS_fog_function = GL_FALSE;
+GLboolean __GLEW_SGIS_generate_mipmap = GL_FALSE;
+GLboolean __GLEW_SGIS_multisample = GL_FALSE;
+GLboolean __GLEW_SGIS_pixel_texture = GL_FALSE;
+GLboolean __GLEW_SGIS_point_line_texgen = GL_FALSE;
+GLboolean __GLEW_SGIS_sharpen_texture = GL_FALSE;
+GLboolean __GLEW_SGIS_texture4D = GL_FALSE;
+GLboolean __GLEW_SGIS_texture_border_clamp = GL_FALSE;
+GLboolean __GLEW_SGIS_texture_edge_clamp = GL_FALSE;
+GLboolean __GLEW_SGIS_texture_filter4 = GL_FALSE;
+GLboolean __GLEW_SGIS_texture_lod = GL_FALSE;
+GLboolean __GLEW_SGIS_texture_select = GL_FALSE;
+GLboolean __GLEW_SGIX_async = GL_FALSE;
+GLboolean __GLEW_SGIX_async_histogram = GL_FALSE;
+GLboolean __GLEW_SGIX_async_pixel = GL_FALSE;
+GLboolean __GLEW_SGIX_blend_alpha_minmax = GL_FALSE;
+GLboolean __GLEW_SGIX_clipmap = GL_FALSE;
+GLboolean __GLEW_SGIX_convolution_accuracy = GL_FALSE;
+GLboolean __GLEW_SGIX_depth_texture = GL_FALSE;
+GLboolean __GLEW_SGIX_flush_raster = GL_FALSE;
+GLboolean __GLEW_SGIX_fog_offset = GL_FALSE;
+GLboolean __GLEW_SGIX_fog_texture = GL_FALSE;
+GLboolean __GLEW_SGIX_fragment_specular_lighting = GL_FALSE;
+GLboolean __GLEW_SGIX_framezoom = GL_FALSE;
+GLboolean __GLEW_SGIX_interlace = GL_FALSE;
+GLboolean __GLEW_SGIX_ir_instrument1 = GL_FALSE;
+GLboolean __GLEW_SGIX_list_priority = GL_FALSE;
+GLboolean __GLEW_SGIX_pixel_texture = GL_FALSE;
+GLboolean __GLEW_SGIX_pixel_texture_bits = GL_FALSE;
+GLboolean __GLEW_SGIX_reference_plane = GL_FALSE;
+GLboolean __GLEW_SGIX_resample = GL_FALSE;
+GLboolean __GLEW_SGIX_shadow = GL_FALSE;
+GLboolean __GLEW_SGIX_shadow_ambient = GL_FALSE;
+GLboolean __GLEW_SGIX_sprite = GL_FALSE;
+GLboolean __GLEW_SGIX_tag_sample_buffer = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_add_env = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_coordinate_clamp = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_lod_bias = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_multi_buffer = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_range = GL_FALSE;
+GLboolean __GLEW_SGIX_texture_scale_bias = GL_FALSE;
+GLboolean __GLEW_SGIX_vertex_preclip = GL_FALSE;
+GLboolean __GLEW_SGIX_vertex_preclip_hint = GL_FALSE;
+GLboolean __GLEW_SGIX_ycrcb = GL_FALSE;
+GLboolean __GLEW_SGI_color_matrix = GL_FALSE;
+GLboolean __GLEW_SGI_color_table = GL_FALSE;
+GLboolean __GLEW_SGI_texture_color_table = GL_FALSE;
+GLboolean __GLEW_SUNX_constant_data = GL_FALSE;
+GLboolean __GLEW_SUN_convolution_border_modes = GL_FALSE;
+GLboolean __GLEW_SUN_global_alpha = GL_FALSE;
+GLboolean __GLEW_SUN_mesh_array = GL_FALSE;
+GLboolean __GLEW_SUN_read_video_pixels = GL_FALSE;
+GLboolean __GLEW_SUN_slice_accum = GL_FALSE;
+GLboolean __GLEW_SUN_triangle_list = GL_FALSE;
+GLboolean __GLEW_SUN_vertex = GL_FALSE;
+GLboolean __GLEW_WIN_phong_shading = GL_FALSE;
+GLboolean __GLEW_WIN_specular_fog = GL_FALSE;
+GLboolean __GLEW_WIN_swap_hint = GL_FALSE;
+
+#endif /* !GLEW_MX */
+
+#ifdef GL_VERSION_1_2
+
+static GLboolean _glewInit_GL_VERSION_1_2 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3D")) == NULL) || r;
+ r = ((glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElements")) == NULL) || r;
+ r = ((glTexImage3D = (PFNGLTEXIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexImage3D")) == NULL) || r;
+ r = ((glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_1_2 */
+
+#ifdef GL_VERSION_1_2_1
+
+#endif /* GL_VERSION_1_2_1 */
+
+#ifdef GL_VERSION_1_3
+
+static GLboolean _glewInit_GL_VERSION_1_3 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glActiveTexture = (PFNGLACTIVETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glActiveTexture")) == NULL) || r;
+ r = ((glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glClientActiveTexture")) == NULL) || r;
+ r = ((glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage1D")) == NULL) || r;
+ r = ((glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage2D")) == NULL) || r;
+ r = ((glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3D")) == NULL) || r;
+ r = ((glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage1D")) == NULL) || r;
+ r = ((glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage2D")) == NULL) || r;
+ r = ((glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3D")) == NULL) || r;
+ r = ((glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTexImage")) == NULL) || r;
+ r = ((glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixd")) == NULL) || r;
+ r = ((glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixf")) == NULL) || r;
+ r = ((glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixd")) == NULL) || r;
+ r = ((glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixf")) == NULL) || r;
+ r = ((glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1d")) == NULL) || r;
+ r = ((glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dv")) == NULL) || r;
+ r = ((glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1f")) == NULL) || r;
+ r = ((glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fv")) == NULL) || r;
+ r = ((glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1i")) == NULL) || r;
+ r = ((glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1iv")) == NULL) || r;
+ r = ((glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1s")) == NULL) || r;
+ r = ((glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1sv")) == NULL) || r;
+ r = ((glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2d")) == NULL) || r;
+ r = ((glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dv")) == NULL) || r;
+ r = ((glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2f")) == NULL) || r;
+ r = ((glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fv")) == NULL) || r;
+ r = ((glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2i")) == NULL) || r;
+ r = ((glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2iv")) == NULL) || r;
+ r = ((glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2s")) == NULL) || r;
+ r = ((glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2sv")) == NULL) || r;
+ r = ((glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3d")) == NULL) || r;
+ r = ((glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dv")) == NULL) || r;
+ r = ((glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3f")) == NULL) || r;
+ r = ((glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fv")) == NULL) || r;
+ r = ((glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3i")) == NULL) || r;
+ r = ((glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3iv")) == NULL) || r;
+ r = ((glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3s")) == NULL) || r;
+ r = ((glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3sv")) == NULL) || r;
+ r = ((glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4d")) == NULL) || r;
+ r = ((glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dv")) == NULL) || r;
+ r = ((glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4f")) == NULL) || r;
+ r = ((glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fv")) == NULL) || r;
+ r = ((glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4i")) == NULL) || r;
+ r = ((glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4iv")) == NULL) || r;
+ r = ((glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4s")) == NULL) || r;
+ r = ((glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4sv")) == NULL) || r;
+ r = ((glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)glewGetProcAddress((const GLubyte*)"glSampleCoverage")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_1_3 */
+
+#ifdef GL_VERSION_1_4
+
+static GLboolean _glewInit_GL_VERSION_1_4 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendColor = (PFNGLBLENDCOLORPROC)glewGetProcAddress((const GLubyte*)"glBlendColor")) == NULL) || r;
+ r = ((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte*)"glBlendEquation")) == NULL) || r;
+ r = ((glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparate")) == NULL) || r;
+ r = ((glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointer")) == NULL) || r;
+ r = ((glFogCoordd = (PFNGLFOGCOORDDPROC)glewGetProcAddress((const GLubyte*)"glFogCoordd")) == NULL) || r;
+ r = ((glFogCoorddv = (PFNGLFOGCOORDDVPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddv")) == NULL) || r;
+ r = ((glFogCoordf = (PFNGLFOGCOORDFPROC)glewGetProcAddress((const GLubyte*)"glFogCoordf")) == NULL) || r;
+ r = ((glFogCoordfv = (PFNGLFOGCOORDFVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfv")) == NULL) || r;
+ r = ((glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArrays")) == NULL) || r;
+ r = ((glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElements")) == NULL) || r;
+ r = ((glPointParameterf = (PFNGLPOINTPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glPointParameterf")) == NULL) || r;
+ r = ((glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfv")) == NULL) || r;
+ r = ((glPointParameteri = (PFNGLPOINTPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glPointParameteri")) == NULL) || r;
+ r = ((glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glPointParameteriv")) == NULL) || r;
+ r = ((glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3b")) == NULL) || r;
+ r = ((glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bv")) == NULL) || r;
+ r = ((glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3d")) == NULL) || r;
+ r = ((glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dv")) == NULL) || r;
+ r = ((glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3f")) == NULL) || r;
+ r = ((glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fv")) == NULL) || r;
+ r = ((glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3i")) == NULL) || r;
+ r = ((glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3iv")) == NULL) || r;
+ r = ((glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3s")) == NULL) || r;
+ r = ((glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3sv")) == NULL) || r;
+ r = ((glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ub")) == NULL) || r;
+ r = ((glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubv")) == NULL) || r;
+ r = ((glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ui")) == NULL) || r;
+ r = ((glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uiv")) == NULL) || r;
+ r = ((glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3us")) == NULL) || r;
+ r = ((glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usv")) == NULL) || r;
+ r = ((glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointer")) == NULL) || r;
+ r = ((glWindowPos2d = (PFNGLWINDOWPOS2DPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2d")) == NULL) || r;
+ r = ((glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dv")) == NULL) || r;
+ r = ((glWindowPos2f = (PFNGLWINDOWPOS2FPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2f")) == NULL) || r;
+ r = ((glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fv")) == NULL) || r;
+ r = ((glWindowPos2i = (PFNGLWINDOWPOS2IPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2i")) == NULL) || r;
+ r = ((glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iv")) == NULL) || r;
+ r = ((glWindowPos2s = (PFNGLWINDOWPOS2SPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2s")) == NULL) || r;
+ r = ((glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sv")) == NULL) || r;
+ r = ((glWindowPos3d = (PFNGLWINDOWPOS3DPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3d")) == NULL) || r;
+ r = ((glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dv")) == NULL) || r;
+ r = ((glWindowPos3f = (PFNGLWINDOWPOS3FPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3f")) == NULL) || r;
+ r = ((glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fv")) == NULL) || r;
+ r = ((glWindowPos3i = (PFNGLWINDOWPOS3IPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3i")) == NULL) || r;
+ r = ((glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iv")) == NULL) || r;
+ r = ((glWindowPos3s = (PFNGLWINDOWPOS3SPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3s")) == NULL) || r;
+ r = ((glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_1_4 */
+
+#ifdef GL_VERSION_1_5
+
+static GLboolean _glewInit_GL_VERSION_1_5 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginQuery = (PFNGLBEGINQUERYPROC)glewGetProcAddress((const GLubyte*)"glBeginQuery")) == NULL) || r;
+ r = ((glBindBuffer = (PFNGLBINDBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindBuffer")) == NULL) || r;
+ r = ((glBufferData = (PFNGLBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glBufferData")) == NULL) || r;
+ r = ((glBufferSubData = (PFNGLBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glBufferSubData")) == NULL) || r;
+ r = ((glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteBuffers")) == NULL) || r;
+ r = ((glDeleteQueries = (PFNGLDELETEQUERIESPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueries")) == NULL) || r;
+ r = ((glEndQuery = (PFNGLENDQUERYPROC)glewGetProcAddress((const GLubyte*)"glEndQuery")) == NULL) || r;
+ r = ((glGenBuffers = (PFNGLGENBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenBuffers")) == NULL) || r;
+ r = ((glGenQueries = (PFNGLGENQUERIESPROC)glewGetProcAddress((const GLubyte*)"glGenQueries")) == NULL) || r;
+ r = ((glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameteriv")) == NULL) || r;
+ r = ((glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferPointerv")) == NULL) || r;
+ r = ((glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glGetBufferSubData")) == NULL) || r;
+ r = ((glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectiv")) == NULL) || r;
+ r = ((glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuiv")) == NULL) || r;
+ r = ((glGetQueryiv = (PFNGLGETQUERYIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryiv")) == NULL) || r;
+ r = ((glIsBuffer = (PFNGLISBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsBuffer")) == NULL) || r;
+ r = ((glIsQuery = (PFNGLISQUERYPROC)glewGetProcAddress((const GLubyte*)"glIsQuery")) == NULL) || r;
+ r = ((glMapBuffer = (PFNGLMAPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glMapBuffer")) == NULL) || r;
+ r = ((glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glUnmapBuffer")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_1_5 */
+
+#ifdef GL_VERSION_2_0
+
+static GLboolean _glewInit_GL_VERSION_2_0 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAttachShader = (PFNGLATTACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glAttachShader")) == NULL) || r;
+ r = ((glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocation")) == NULL) || r;
+ r = ((glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparate")) == NULL) || r;
+ r = ((glCompileShader = (PFNGLCOMPILESHADERPROC)glewGetProcAddress((const GLubyte*)"glCompileShader")) == NULL) || r;
+ r = ((glCreateProgram = (PFNGLCREATEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glCreateProgram")) == NULL) || r;
+ r = ((glCreateShader = (PFNGLCREATESHADERPROC)glewGetProcAddress((const GLubyte*)"glCreateShader")) == NULL) || r;
+ r = ((glDeleteProgram = (PFNGLDELETEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgram")) == NULL) || r;
+ r = ((glDeleteShader = (PFNGLDELETESHADERPROC)glewGetProcAddress((const GLubyte*)"glDeleteShader")) == NULL) || r;
+ r = ((glDetachShader = (PFNGLDETACHSHADERPROC)glewGetProcAddress((const GLubyte*)"glDetachShader")) == NULL) || r;
+ r = ((glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribArray")) == NULL) || r;
+ r = ((glDrawBuffers = (PFNGLDRAWBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffers")) == NULL) || r;
+ r = ((glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribArray")) == NULL) || r;
+ r = ((glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAttrib")) == NULL) || r;
+ r = ((glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniform")) == NULL) || r;
+ r = ((glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)glewGetProcAddress((const GLubyte*)"glGetAttachedShaders")) == NULL) || r;
+ r = ((glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetAttribLocation")) == NULL) || r;
+ r = ((glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetProgramInfoLog")) == NULL) || r;
+ r = ((glGetProgramiv = (PFNGLGETPROGRAMIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramiv")) == NULL) || r;
+ r = ((glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetShaderInfoLog")) == NULL) || r;
+ r = ((glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)glewGetProcAddress((const GLubyte*)"glGetShaderSource")) == NULL) || r;
+ r = ((glGetShaderiv = (PFNGLGETSHADERIVPROC)glewGetProcAddress((const GLubyte*)"glGetShaderiv")) == NULL) || r;
+ r = ((glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetUniformLocation")) == NULL) || r;
+ r = ((glGetUniformfv = (PFNGLGETUNIFORMFVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformfv")) == NULL) || r;
+ r = ((glGetUniformiv = (PFNGLGETUNIFORMIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformiv")) == NULL) || r;
+ r = ((glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointerv")) == NULL) || r;
+ r = ((glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdv")) == NULL) || r;
+ r = ((glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfv")) == NULL) || r;
+ r = ((glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribiv")) == NULL) || r;
+ r = ((glIsProgram = (PFNGLISPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glIsProgram")) == NULL) || r;
+ r = ((glIsShader = (PFNGLISSHADERPROC)glewGetProcAddress((const GLubyte*)"glIsShader")) == NULL) || r;
+ r = ((glLinkProgram = (PFNGLLINKPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glLinkProgram")) == NULL) || r;
+ r = ((glShaderSource = (PFNGLSHADERSOURCEPROC)glewGetProcAddress((const GLubyte*)"glShaderSource")) == NULL) || r;
+ r = ((glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilFuncSeparate")) == NULL) || r;
+ r = ((glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilMaskSeparate")) == NULL) || r;
+ r = ((glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)glewGetProcAddress((const GLubyte*)"glStencilOpSeparate")) == NULL) || r;
+ r = ((glUniform1f = (PFNGLUNIFORM1FPROC)glewGetProcAddress((const GLubyte*)"glUniform1f")) == NULL) || r;
+ r = ((glUniform1fv = (PFNGLUNIFORM1FVPROC)glewGetProcAddress((const GLubyte*)"glUniform1fv")) == NULL) || r;
+ r = ((glUniform1i = (PFNGLUNIFORM1IPROC)glewGetProcAddress((const GLubyte*)"glUniform1i")) == NULL) || r;
+ r = ((glUniform1iv = (PFNGLUNIFORM1IVPROC)glewGetProcAddress((const GLubyte*)"glUniform1iv")) == NULL) || r;
+ r = ((glUniform2f = (PFNGLUNIFORM2FPROC)glewGetProcAddress((const GLubyte*)"glUniform2f")) == NULL) || r;
+ r = ((glUniform2fv = (PFNGLUNIFORM2FVPROC)glewGetProcAddress((const GLubyte*)"glUniform2fv")) == NULL) || r;
+ r = ((glUniform2i = (PFNGLUNIFORM2IPROC)glewGetProcAddress((const GLubyte*)"glUniform2i")) == NULL) || r;
+ r = ((glUniform2iv = (PFNGLUNIFORM2IVPROC)glewGetProcAddress((const GLubyte*)"glUniform2iv")) == NULL) || r;
+ r = ((glUniform3f = (PFNGLUNIFORM3FPROC)glewGetProcAddress((const GLubyte*)"glUniform3f")) == NULL) || r;
+ r = ((glUniform3fv = (PFNGLUNIFORM3FVPROC)glewGetProcAddress((const GLubyte*)"glUniform3fv")) == NULL) || r;
+ r = ((glUniform3i = (PFNGLUNIFORM3IPROC)glewGetProcAddress((const GLubyte*)"glUniform3i")) == NULL) || r;
+ r = ((glUniform3iv = (PFNGLUNIFORM3IVPROC)glewGetProcAddress((const GLubyte*)"glUniform3iv")) == NULL) || r;
+ r = ((glUniform4f = (PFNGLUNIFORM4FPROC)glewGetProcAddress((const GLubyte*)"glUniform4f")) == NULL) || r;
+ r = ((glUniform4fv = (PFNGLUNIFORM4FVPROC)glewGetProcAddress((const GLubyte*)"glUniform4fv")) == NULL) || r;
+ r = ((glUniform4i = (PFNGLUNIFORM4IPROC)glewGetProcAddress((const GLubyte*)"glUniform4i")) == NULL) || r;
+ r = ((glUniform4iv = (PFNGLUNIFORM4IVPROC)glewGetProcAddress((const GLubyte*)"glUniform4iv")) == NULL) || r;
+ r = ((glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2fv")) == NULL) || r;
+ r = ((glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3fv")) == NULL) || r;
+ r = ((glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4fv")) == NULL) || r;
+ r = ((glUseProgram = (PFNGLUSEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glUseProgram")) == NULL) || r;
+ r = ((glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glValidateProgram")) == NULL) || r;
+ r = ((glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1d")) == NULL) || r;
+ r = ((glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dv")) == NULL) || r;
+ r = ((glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1f")) == NULL) || r;
+ r = ((glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fv")) == NULL) || r;
+ r = ((glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1s")) == NULL) || r;
+ r = ((glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sv")) == NULL) || r;
+ r = ((glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2d")) == NULL) || r;
+ r = ((glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dv")) == NULL) || r;
+ r = ((glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2f")) == NULL) || r;
+ r = ((glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fv")) == NULL) || r;
+ r = ((glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2s")) == NULL) || r;
+ r = ((glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sv")) == NULL) || r;
+ r = ((glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3d")) == NULL) || r;
+ r = ((glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dv")) == NULL) || r;
+ r = ((glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3f")) == NULL) || r;
+ r = ((glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fv")) == NULL) || r;
+ r = ((glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3s")) == NULL) || r;
+ r = ((glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sv")) == NULL) || r;
+ r = ((glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nbv")) == NULL) || r;
+ r = ((glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Niv")) == NULL) || r;
+ r = ((glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nsv")) == NULL) || r;
+ r = ((glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nub")) == NULL) || r;
+ r = ((glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nubv")) == NULL) || r;
+ r = ((glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nuiv")) == NULL) || r;
+ r = ((glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4Nusv")) == NULL) || r;
+ r = ((glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4bv")) == NULL) || r;
+ r = ((glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4d")) == NULL) || r;
+ r = ((glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dv")) == NULL) || r;
+ r = ((glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4f")) == NULL) || r;
+ r = ((glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fv")) == NULL) || r;
+ r = ((glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4iv")) == NULL) || r;
+ r = ((glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4s")) == NULL) || r;
+ r = ((glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sv")) == NULL) || r;
+ r = ((glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubv")) == NULL) || r;
+ r = ((glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uiv")) == NULL) || r;
+ r = ((glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usv")) == NULL) || r;
+ r = ((glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointer")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_2_0 */
+
+#ifdef GL_VERSION_2_1
+
+static GLboolean _glewInit_GL_VERSION_2_1 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x3fv")) == NULL) || r;
+ r = ((glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x4fv")) == NULL) || r;
+ r = ((glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x2fv")) == NULL) || r;
+ r = ((glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x4fv")) == NULL) || r;
+ r = ((glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x2fv")) == NULL) || r;
+ r = ((glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x3fv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_2_1 */
+
+#ifdef GL_VERSION_3_0
+
+static GLboolean _glewInit_GL_VERSION_3_0 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRender")) == NULL) || r;
+ r = ((glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedback")) == NULL) || r;
+ r = ((glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocation")) == NULL) || r;
+ r = ((glClampColor = (PFNGLCLAMPCOLORPROC)glewGetProcAddress((const GLubyte*)"glClampColor")) == NULL) || r;
+ r = ((glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)glewGetProcAddress((const GLubyte*)"glClearBufferfi")) == NULL) || r;
+ r = ((glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferfv")) == NULL) || r;
+ r = ((glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferiv")) == NULL) || r;
+ r = ((glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)glewGetProcAddress((const GLubyte*)"glClearBufferuiv")) == NULL) || r;
+ r = ((glColorMaski = (PFNGLCOLORMASKIPROC)glewGetProcAddress((const GLubyte*)"glColorMaski")) == NULL) || r;
+ r = ((glDisablei = (PFNGLDISABLEIPROC)glewGetProcAddress((const GLubyte*)"glDisablei")) == NULL) || r;
+ r = ((glEnablei = (PFNGLENABLEIPROC)glewGetProcAddress((const GLubyte*)"glEnablei")) == NULL) || r;
+ r = ((glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRender")) == NULL) || r;
+ r = ((glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedback")) == NULL) || r;
+ r = ((glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)glewGetProcAddress((const GLubyte*)"glGetBooleani_v")) == NULL) || r;
+ r = ((glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataLocation")) == NULL) || r;
+ r = ((glGetStringi = (PFNGLGETSTRINGIPROC)glewGetProcAddress((const GLubyte*)"glGetStringi")) == NULL) || r;
+ r = ((glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIiv")) == NULL) || r;
+ r = ((glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIuiv")) == NULL) || r;
+ r = ((glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVarying")) == NULL) || r;
+ r = ((glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformuiv")) == NULL) || r;
+ r = ((glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIiv")) == NULL) || r;
+ r = ((glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIuiv")) == NULL) || r;
+ r = ((glIsEnabledi = (PFNGLISENABLEDIPROC)glewGetProcAddress((const GLubyte*)"glIsEnabledi")) == NULL) || r;
+ r = ((glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIiv")) == NULL) || r;
+ r = ((glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIuiv")) == NULL) || r;
+ r = ((glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryings")) == NULL) || r;
+ r = ((glUniform1ui = (PFNGLUNIFORM1UIPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui")) == NULL) || r;
+ r = ((glUniform1uiv = (PFNGLUNIFORM1UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform1uiv")) == NULL) || r;
+ r = ((glUniform2ui = (PFNGLUNIFORM2UIPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui")) == NULL) || r;
+ r = ((glUniform2uiv = (PFNGLUNIFORM2UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform2uiv")) == NULL) || r;
+ r = ((glUniform3ui = (PFNGLUNIFORM3UIPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui")) == NULL) || r;
+ r = ((glUniform3uiv = (PFNGLUNIFORM3UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform3uiv")) == NULL) || r;
+ r = ((glUniform4ui = (PFNGLUNIFORM4UIPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui")) == NULL) || r;
+ r = ((glUniform4uiv = (PFNGLUNIFORM4UIVPROC)glewGetProcAddress((const GLubyte*)"glUniform4uiv")) == NULL) || r;
+ r = ((glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1i")) == NULL) || r;
+ r = ((glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1iv")) == NULL) || r;
+ r = ((glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1ui")) == NULL) || r;
+ r = ((glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uiv")) == NULL) || r;
+ r = ((glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2i")) == NULL) || r;
+ r = ((glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2iv")) == NULL) || r;
+ r = ((glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2ui")) == NULL) || r;
+ r = ((glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uiv")) == NULL) || r;
+ r = ((glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3i")) == NULL) || r;
+ r = ((glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3iv")) == NULL) || r;
+ r = ((glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3ui")) == NULL) || r;
+ r = ((glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uiv")) == NULL) || r;
+ r = ((glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4bv")) == NULL) || r;
+ r = ((glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4i")) == NULL) || r;
+ r = ((glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4iv")) == NULL) || r;
+ r = ((glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4sv")) == NULL) || r;
+ r = ((glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ubv")) == NULL) || r;
+ r = ((glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ui")) == NULL) || r;
+ r = ((glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uiv")) == NULL) || r;
+ r = ((glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4usv")) == NULL) || r;
+ r = ((glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIPointer")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_3_0 */
+
+#ifdef GL_VERSION_3_1
+
+static GLboolean _glewInit_GL_VERSION_3_1 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstanced")) == NULL) || r;
+ r = ((glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstanced")) == NULL) || r;
+ r = ((glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartIndex")) == NULL) || r;
+ r = ((glTexBuffer = (PFNGLTEXBUFFERPROC)glewGetProcAddress((const GLubyte*)"glTexBuffer")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_3_1 */
+
+#ifdef GL_VERSION_3_2
+
+static GLboolean _glewInit_GL_VERSION_3_2 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture")) == NULL) || r;
+ r = ((glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameteri64v")) == NULL) || r;
+ r = ((glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)glewGetProcAddress((const GLubyte*)"glGetInteger64i_v")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_3_2 */
+
+#ifdef GL_VERSION_3_3
+
+static GLboolean _glewInit_GL_VERSION_3_3 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisor")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_3_3 */
+
+#ifdef GL_VERSION_4_0
+
+static GLboolean _glewInit_GL_VERSION_4_0 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparatei")) == NULL) || r;
+ r = ((glBlendEquationi = (PFNGLBLENDEQUATIONIPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationi")) == NULL) || r;
+ r = ((glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparatei")) == NULL) || r;
+ r = ((glBlendFunci = (PFNGLBLENDFUNCIPROC)glewGetProcAddress((const GLubyte*)"glBlendFunci")) == NULL) || r;
+ r = ((glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC)glewGetProcAddress((const GLubyte*)"glMinSampleShading")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_VERSION_4_0 */
+
+#ifdef GL_VERSION_4_1
+
+#endif /* GL_VERSION_4_1 */
+
+#ifdef GL_VERSION_4_2
+
+#endif /* GL_VERSION_4_2 */
+
+#ifdef GL_VERSION_4_3
+
+#endif /* GL_VERSION_4_3 */
+
+#ifdef GL_VERSION_4_4
+
+#endif /* GL_VERSION_4_4 */
+
+#ifdef GL_3DFX_multisample
+
+#endif /* GL_3DFX_multisample */
+
+#ifdef GL_3DFX_tbuffer
+
+static GLboolean _glewInit_GL_3DFX_tbuffer (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTbufferMask3DFX = (PFNGLTBUFFERMASK3DFXPROC)glewGetProcAddress((const GLubyte*)"glTbufferMask3DFX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_3DFX_tbuffer */
+
+#ifdef GL_3DFX_texture_compression_FXT1
+
+#endif /* GL_3DFX_texture_compression_FXT1 */
+
+#ifdef GL_AMD_blend_minmax_factor
+
+#endif /* GL_AMD_blend_minmax_factor */
+
+#ifdef GL_AMD_conservative_depth
+
+#endif /* GL_AMD_conservative_depth */
+
+#ifdef GL_AMD_debug_output
+
+static GLboolean _glewInit_GL_AMD_debug_output (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDebugMessageCallbackAMD = (PFNGLDEBUGMESSAGECALLBACKAMDPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageCallbackAMD")) == NULL) || r;
+ r = ((glDebugMessageEnableAMD = (PFNGLDEBUGMESSAGEENABLEAMDPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageEnableAMD")) == NULL) || r;
+ r = ((glDebugMessageInsertAMD = (PFNGLDEBUGMESSAGEINSERTAMDPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageInsertAMD")) == NULL) || r;
+ r = ((glGetDebugMessageLogAMD = (PFNGLGETDEBUGMESSAGELOGAMDPROC)glewGetProcAddress((const GLubyte*)"glGetDebugMessageLogAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_debug_output */
+
+#ifdef GL_AMD_depth_clamp_separate
+
+#endif /* GL_AMD_depth_clamp_separate */
+
+#ifdef GL_AMD_draw_buffers_blend
+
+static GLboolean _glewInit_GL_AMD_draw_buffers_blend (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationIndexedAMD")) == NULL) || r;
+ r = ((glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateIndexedAMD")) == NULL) || r;
+ r = ((glBlendFuncIndexedAMD = (PFNGLBLENDFUNCINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncIndexedAMD")) == NULL) || r;
+ r = ((glBlendFuncSeparateIndexedAMD = (PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateIndexedAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_draw_buffers_blend */
+
+#ifdef GL_AMD_interleaved_elements
+
+static GLboolean _glewInit_GL_AMD_interleaved_elements (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glVertexAttribParameteriAMD = (PFNGLVERTEXATTRIBPARAMETERIAMDPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribParameteriAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_interleaved_elements */
+
+#ifdef GL_AMD_multi_draw_indirect
+
+static GLboolean _glewInit_GL_AMD_multi_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiDrawArraysIndirectAMD = (PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectAMD")) == NULL) || r;
+ r = ((glMultiDrawElementsIndirectAMD = (PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_multi_draw_indirect */
+
+#ifdef GL_AMD_name_gen_delete
+
+static GLboolean _glewInit_GL_AMD_name_gen_delete (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDeleteNamesAMD = (PFNGLDELETENAMESAMDPROC)glewGetProcAddress((const GLubyte*)"glDeleteNamesAMD")) == NULL) || r;
+ r = ((glGenNamesAMD = (PFNGLGENNAMESAMDPROC)glewGetProcAddress((const GLubyte*)"glGenNamesAMD")) == NULL) || r;
+ r = ((glIsNameAMD = (PFNGLISNAMEAMDPROC)glewGetProcAddress((const GLubyte*)"glIsNameAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_name_gen_delete */
+
+#ifdef GL_AMD_performance_monitor
+
+static GLboolean _glewInit_GL_AMD_performance_monitor (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginPerfMonitorAMD = (PFNGLBEGINPERFMONITORAMDPROC)glewGetProcAddress((const GLubyte*)"glBeginPerfMonitorAMD")) == NULL) || r;
+ r = ((glDeletePerfMonitorsAMD = (PFNGLDELETEPERFMONITORSAMDPROC)glewGetProcAddress((const GLubyte*)"glDeletePerfMonitorsAMD")) == NULL) || r;
+ r = ((glEndPerfMonitorAMD = (PFNGLENDPERFMONITORAMDPROC)glewGetProcAddress((const GLubyte*)"glEndPerfMonitorAMD")) == NULL) || r;
+ r = ((glGenPerfMonitorsAMD = (PFNGLGENPERFMONITORSAMDPROC)glewGetProcAddress((const GLubyte*)"glGenPerfMonitorsAMD")) == NULL) || r;
+ r = ((glGetPerfMonitorCounterDataAMD = (PFNGLGETPERFMONITORCOUNTERDATAAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterDataAMD")) == NULL) || r;
+ r = ((glGetPerfMonitorCounterInfoAMD = (PFNGLGETPERFMONITORCOUNTERINFOAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterInfoAMD")) == NULL) || r;
+ r = ((glGetPerfMonitorCounterStringAMD = (PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCounterStringAMD")) == NULL) || r;
+ r = ((glGetPerfMonitorCountersAMD = (PFNGLGETPERFMONITORCOUNTERSAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorCountersAMD")) == NULL) || r;
+ r = ((glGetPerfMonitorGroupStringAMD = (PFNGLGETPERFMONITORGROUPSTRINGAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorGroupStringAMD")) == NULL) || r;
+ r = ((glGetPerfMonitorGroupsAMD = (PFNGLGETPERFMONITORGROUPSAMDPROC)glewGetProcAddress((const GLubyte*)"glGetPerfMonitorGroupsAMD")) == NULL) || r;
+ r = ((glSelectPerfMonitorCountersAMD = (PFNGLSELECTPERFMONITORCOUNTERSAMDPROC)glewGetProcAddress((const GLubyte*)"glSelectPerfMonitorCountersAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_performance_monitor */
+
+#ifdef GL_AMD_pinned_memory
+
+#endif /* GL_AMD_pinned_memory */
+
+#ifdef GL_AMD_query_buffer_object
+
+#endif /* GL_AMD_query_buffer_object */
+
+#ifdef GL_AMD_sample_positions
+
+static GLboolean _glewInit_GL_AMD_sample_positions (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSetMultisamplefvAMD = (PFNGLSETMULTISAMPLEFVAMDPROC)glewGetProcAddress((const GLubyte*)"glSetMultisamplefvAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_sample_positions */
+
+#ifdef GL_AMD_seamless_cubemap_per_texture
+
+#endif /* GL_AMD_seamless_cubemap_per_texture */
+
+#ifdef GL_AMD_shader_stencil_export
+
+#endif /* GL_AMD_shader_stencil_export */
+
+#ifdef GL_AMD_shader_trinary_minmax
+
+#endif /* GL_AMD_shader_trinary_minmax */
+
+#ifdef GL_AMD_sparse_texture
+
+static GLboolean _glewInit_GL_AMD_sparse_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexStorageSparseAMD = (PFNGLTEXSTORAGESPARSEAMDPROC)glewGetProcAddress((const GLubyte*)"glTexStorageSparseAMD")) == NULL) || r;
+ r = ((glTextureStorageSparseAMD = (PFNGLTEXTURESTORAGESPARSEAMDPROC)glewGetProcAddress((const GLubyte*)"glTextureStorageSparseAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_sparse_texture */
+
+#ifdef GL_AMD_stencil_operation_extended
+
+static GLboolean _glewInit_GL_AMD_stencil_operation_extended (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glStencilOpValueAMD = (PFNGLSTENCILOPVALUEAMDPROC)glewGetProcAddress((const GLubyte*)"glStencilOpValueAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_stencil_operation_extended */
+
+#ifdef GL_AMD_texture_texture4
+
+#endif /* GL_AMD_texture_texture4 */
+
+#ifdef GL_AMD_transform_feedback3_lines_triangles
+
+#endif /* GL_AMD_transform_feedback3_lines_triangles */
+
+#ifdef GL_AMD_vertex_shader_layer
+
+#endif /* GL_AMD_vertex_shader_layer */
+
+#ifdef GL_AMD_vertex_shader_tessellator
+
+static GLboolean _glewInit_GL_AMD_vertex_shader_tessellator (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTessellationFactorAMD = (PFNGLTESSELLATIONFACTORAMDPROC)glewGetProcAddress((const GLubyte*)"glTessellationFactorAMD")) == NULL) || r;
+ r = ((glTessellationModeAMD = (PFNGLTESSELLATIONMODEAMDPROC)glewGetProcAddress((const GLubyte*)"glTessellationModeAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_AMD_vertex_shader_tessellator */
+
+#ifdef GL_AMD_vertex_shader_viewport_index
+
+#endif /* GL_AMD_vertex_shader_viewport_index */
+
+#ifdef GL_ANGLE_depth_texture
+
+#endif /* GL_ANGLE_depth_texture */
+
+#ifdef GL_ANGLE_framebuffer_blit
+
+static GLboolean _glewInit_GL_ANGLE_framebuffer_blit (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlitFramebufferANGLE = (PFNGLBLITFRAMEBUFFERANGLEPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebufferANGLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ANGLE_framebuffer_blit */
+
+#ifdef GL_ANGLE_framebuffer_multisample
+
+static GLboolean _glewInit_GL_ANGLE_framebuffer_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glRenderbufferStorageMultisampleANGLE = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleANGLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ANGLE_framebuffer_multisample */
+
+#ifdef GL_ANGLE_instanced_arrays
+
+static GLboolean _glewInit_GL_ANGLE_instanced_arrays (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawArraysInstancedANGLE = (PFNGLDRAWARRAYSINSTANCEDANGLEPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedANGLE")) == NULL) || r;
+ r = ((glDrawElementsInstancedANGLE = (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedANGLE")) == NULL) || r;
+ r = ((glVertexAttribDivisorANGLE = (PFNGLVERTEXATTRIBDIVISORANGLEPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorANGLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ANGLE_instanced_arrays */
+
+#ifdef GL_ANGLE_pack_reverse_row_order
+
+#endif /* GL_ANGLE_pack_reverse_row_order */
+
+#ifdef GL_ANGLE_program_binary
+
+#endif /* GL_ANGLE_program_binary */
+
+#ifdef GL_ANGLE_texture_compression_dxt1
+
+#endif /* GL_ANGLE_texture_compression_dxt1 */
+
+#ifdef GL_ANGLE_texture_compression_dxt3
+
+#endif /* GL_ANGLE_texture_compression_dxt3 */
+
+#ifdef GL_ANGLE_texture_compression_dxt5
+
+#endif /* GL_ANGLE_texture_compression_dxt5 */
+
+#ifdef GL_ANGLE_texture_usage
+
+#endif /* GL_ANGLE_texture_usage */
+
+#ifdef GL_ANGLE_timer_query
+
+static GLboolean _glewInit_GL_ANGLE_timer_query (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginQueryANGLE = (PFNGLBEGINQUERYANGLEPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryANGLE")) == NULL) || r;
+ r = ((glDeleteQueriesANGLE = (PFNGLDELETEQUERIESANGLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueriesANGLE")) == NULL) || r;
+ r = ((glEndQueryANGLE = (PFNGLENDQUERYANGLEPROC)glewGetProcAddress((const GLubyte*)"glEndQueryANGLE")) == NULL) || r;
+ r = ((glGenQueriesANGLE = (PFNGLGENQUERIESANGLEPROC)glewGetProcAddress((const GLubyte*)"glGenQueriesANGLE")) == NULL) || r;
+ r = ((glGetQueryObjecti64vANGLE = (PFNGLGETQUERYOBJECTI64VANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjecti64vANGLE")) == NULL) || r;
+ r = ((glGetQueryObjectivANGLE = (PFNGLGETQUERYOBJECTIVANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectivANGLE")) == NULL) || r;
+ r = ((glGetQueryObjectui64vANGLE = (PFNGLGETQUERYOBJECTUI64VANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectui64vANGLE")) == NULL) || r;
+ r = ((glGetQueryObjectuivANGLE = (PFNGLGETQUERYOBJECTUIVANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuivANGLE")) == NULL) || r;
+ r = ((glGetQueryivANGLE = (PFNGLGETQUERYIVANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetQueryivANGLE")) == NULL) || r;
+ r = ((glIsQueryANGLE = (PFNGLISQUERYANGLEPROC)glewGetProcAddress((const GLubyte*)"glIsQueryANGLE")) == NULL) || r;
+ r = ((glQueryCounterANGLE = (PFNGLQUERYCOUNTERANGLEPROC)glewGetProcAddress((const GLubyte*)"glQueryCounterANGLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ANGLE_timer_query */
+
+#ifdef GL_ANGLE_translated_shader_source
+
+static GLboolean _glewInit_GL_ANGLE_translated_shader_source (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetTranslatedShaderSourceANGLE = (PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC)glewGetProcAddress((const GLubyte*)"glGetTranslatedShaderSourceANGLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ANGLE_translated_shader_source */
+
+#ifdef GL_APPLE_aux_depth_stencil
+
+#endif /* GL_APPLE_aux_depth_stencil */
+
+#ifdef GL_APPLE_client_storage
+
+#endif /* GL_APPLE_client_storage */
+
+#ifdef GL_APPLE_element_array
+
+static GLboolean _glewInit_GL_APPLE_element_array (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawElementArrayAPPLE = (PFNGLDRAWELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementArrayAPPLE")) == NULL) || r;
+ r = ((glDrawRangeElementArrayAPPLE = (PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementArrayAPPLE")) == NULL) || r;
+ r = ((glElementPointerAPPLE = (PFNGLELEMENTPOINTERAPPLEPROC)glewGetProcAddress((const GLubyte*)"glElementPointerAPPLE")) == NULL) || r;
+ r = ((glMultiDrawElementArrayAPPLE = (PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementArrayAPPLE")) == NULL) || r;
+ r = ((glMultiDrawRangeElementArrayAPPLE = (PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawRangeElementArrayAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_element_array */
+
+#ifdef GL_APPLE_fence
+
+static GLboolean _glewInit_GL_APPLE_fence (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDeleteFencesAPPLE = (PFNGLDELETEFENCESAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteFencesAPPLE")) == NULL) || r;
+ r = ((glFinishFenceAPPLE = (PFNGLFINISHFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFinishFenceAPPLE")) == NULL) || r;
+ r = ((glFinishObjectAPPLE = (PFNGLFINISHOBJECTAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFinishObjectAPPLE")) == NULL) || r;
+ r = ((glGenFencesAPPLE = (PFNGLGENFENCESAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGenFencesAPPLE")) == NULL) || r;
+ r = ((glIsFenceAPPLE = (PFNGLISFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsFenceAPPLE")) == NULL) || r;
+ r = ((glSetFenceAPPLE = (PFNGLSETFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glSetFenceAPPLE")) == NULL) || r;
+ r = ((glTestFenceAPPLE = (PFNGLTESTFENCEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTestFenceAPPLE")) == NULL) || r;
+ r = ((glTestObjectAPPLE = (PFNGLTESTOBJECTAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTestObjectAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_fence */
+
+#ifdef GL_APPLE_float_pixels
+
+#endif /* GL_APPLE_float_pixels */
+
+#ifdef GL_APPLE_flush_buffer_range
+
+static GLboolean _glewInit_GL_APPLE_flush_buffer_range (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBufferParameteriAPPLE = (PFNGLBUFFERPARAMETERIAPPLEPROC)glewGetProcAddress((const GLubyte*)"glBufferParameteriAPPLE")) == NULL) || r;
+ r = ((glFlushMappedBufferRangeAPPLE = (PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedBufferRangeAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_flush_buffer_range */
+
+#ifdef GL_APPLE_object_purgeable
+
+static GLboolean _glewInit_GL_APPLE_object_purgeable (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetObjectParameterivAPPLE = (PFNGLGETOBJECTPARAMETERIVAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterivAPPLE")) == NULL) || r;
+ r = ((glObjectPurgeableAPPLE = (PFNGLOBJECTPURGEABLEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glObjectPurgeableAPPLE")) == NULL) || r;
+ r = ((glObjectUnpurgeableAPPLE = (PFNGLOBJECTUNPURGEABLEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glObjectUnpurgeableAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_object_purgeable */
+
+#ifdef GL_APPLE_pixel_buffer
+
+#endif /* GL_APPLE_pixel_buffer */
+
+#ifdef GL_APPLE_rgb_422
+
+#endif /* GL_APPLE_rgb_422 */
+
+#ifdef GL_APPLE_row_bytes
+
+#endif /* GL_APPLE_row_bytes */
+
+#ifdef GL_APPLE_specular_vector
+
+#endif /* GL_APPLE_specular_vector */
+
+#ifdef GL_APPLE_texture_range
+
+static GLboolean _glewInit_GL_APPLE_texture_range (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetTexParameterPointervAPPLE = (PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterPointervAPPLE")) == NULL) || r;
+ r = ((glTextureRangeAPPLE = (PFNGLTEXTURERANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glTextureRangeAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_texture_range */
+
+#ifdef GL_APPLE_transform_hint
+
+#endif /* GL_APPLE_transform_hint */
+
+#ifdef GL_APPLE_vertex_array_object
+
+static GLboolean _glewInit_GL_APPLE_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindVertexArrayAPPLE = (PFNGLBINDVERTEXARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArrayAPPLE")) == NULL) || r;
+ r = ((glDeleteVertexArraysAPPLE = (PFNGLDELETEVERTEXARRAYSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArraysAPPLE")) == NULL) || r;
+ r = ((glGenVertexArraysAPPLE = (PFNGLGENVERTEXARRAYSAPPLEPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArraysAPPLE")) == NULL) || r;
+ r = ((glIsVertexArrayAPPLE = (PFNGLISVERTEXARRAYAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArrayAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_vertex_array_object */
+
+#ifdef GL_APPLE_vertex_array_range
+
+static GLboolean _glewInit_GL_APPLE_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFlushVertexArrayRangeAPPLE = (PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glFlushVertexArrayRangeAPPLE")) == NULL) || r;
+ r = ((glVertexArrayParameteriAPPLE = (PFNGLVERTEXARRAYPARAMETERIAPPLEPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayParameteriAPPLE")) == NULL) || r;
+ r = ((glVertexArrayRangeAPPLE = (PFNGLVERTEXARRAYRANGEAPPLEPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayRangeAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_vertex_array_range */
+
+#ifdef GL_APPLE_vertex_program_evaluators
+
+static GLboolean _glewInit_GL_APPLE_vertex_program_evaluators (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDisableVertexAttribAPPLE = (PFNGLDISABLEVERTEXATTRIBAPPLEPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribAPPLE")) == NULL) || r;
+ r = ((glEnableVertexAttribAPPLE = (PFNGLENABLEVERTEXATTRIBAPPLEPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribAPPLE")) == NULL) || r;
+ r = ((glIsVertexAttribEnabledAPPLE = (PFNGLISVERTEXATTRIBENABLEDAPPLEPROC)glewGetProcAddress((const GLubyte*)"glIsVertexAttribEnabledAPPLE")) == NULL) || r;
+ r = ((glMapVertexAttrib1dAPPLE = (PFNGLMAPVERTEXATTRIB1DAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib1dAPPLE")) == NULL) || r;
+ r = ((glMapVertexAttrib1fAPPLE = (PFNGLMAPVERTEXATTRIB1FAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib1fAPPLE")) == NULL) || r;
+ r = ((glMapVertexAttrib2dAPPLE = (PFNGLMAPVERTEXATTRIB2DAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib2dAPPLE")) == NULL) || r;
+ r = ((glMapVertexAttrib2fAPPLE = (PFNGLMAPVERTEXATTRIB2FAPPLEPROC)glewGetProcAddress((const GLubyte*)"glMapVertexAttrib2fAPPLE")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_APPLE_vertex_program_evaluators */
+
+#ifdef GL_APPLE_ycbcr_422
+
+#endif /* GL_APPLE_ycbcr_422 */
+
+#ifdef GL_ARB_ES2_compatibility
+
+static GLboolean _glewInit_GL_ARB_ES2_compatibility (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClearDepthf = (PFNGLCLEARDEPTHFPROC)glewGetProcAddress((const GLubyte*)"glClearDepthf")) == NULL) || r;
+ r = ((glDepthRangef = (PFNGLDEPTHRANGEFPROC)glewGetProcAddress((const GLubyte*)"glDepthRangef")) == NULL) || r;
+ r = ((glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC)glewGetProcAddress((const GLubyte*)"glGetShaderPrecisionFormat")) == NULL) || r;
+ r = ((glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC)glewGetProcAddress((const GLubyte*)"glReleaseShaderCompiler")) == NULL) || r;
+ r = ((glShaderBinary = (PFNGLSHADERBINARYPROC)glewGetProcAddress((const GLubyte*)"glShaderBinary")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_ES2_compatibility */
+
+#ifdef GL_ARB_ES3_compatibility
+
+#endif /* GL_ARB_ES3_compatibility */
+
+#ifdef GL_ARB_arrays_of_arrays
+
+#endif /* GL_ARB_arrays_of_arrays */
+
+#ifdef GL_ARB_base_instance
+
+static GLboolean _glewInit_GL_ARB_base_instance (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedBaseInstance")) == NULL) || r;
+ r = ((glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseInstance")) == NULL) || r;
+ r = ((glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseVertexBaseInstance")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_base_instance */
+
+#ifdef GL_ARB_bindless_texture
+
+static GLboolean _glewInit_GL_ARB_bindless_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetImageHandleARB = (PFNGLGETIMAGEHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetImageHandleARB")) == NULL) || r;
+ r = ((glGetTextureHandleARB = (PFNGLGETTEXTUREHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetTextureHandleARB")) == NULL) || r;
+ r = ((glGetTextureSamplerHandleARB = (PFNGLGETTEXTURESAMPLERHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetTextureSamplerHandleARB")) == NULL) || r;
+ r = ((glGetVertexAttribLui64vARB = (PFNGLGETVERTEXATTRIBLUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLui64vARB")) == NULL) || r;
+ r = ((glIsImageHandleResidentARB = (PFNGLISIMAGEHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glIsImageHandleResidentARB")) == NULL) || r;
+ r = ((glIsTextureHandleResidentARB = (PFNGLISTEXTUREHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glIsTextureHandleResidentARB")) == NULL) || r;
+ r = ((glMakeImageHandleNonResidentARB = (PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleNonResidentARB")) == NULL) || r;
+ r = ((glMakeImageHandleResidentARB = (PFNGLMAKEIMAGEHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleResidentARB")) == NULL) || r;
+ r = ((glMakeTextureHandleNonResidentARB = (PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleNonResidentARB")) == NULL) || r;
+ r = ((glMakeTextureHandleResidentARB = (PFNGLMAKETEXTUREHANDLERESIDENTARBPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleResidentARB")) == NULL) || r;
+ r = ((glProgramUniformHandleui64ARB = (PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64ARB")) == NULL) || r;
+ r = ((glProgramUniformHandleui64vARB = (PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64vARB")) == NULL) || r;
+ r = ((glUniformHandleui64ARB = (PFNGLUNIFORMHANDLEUI64ARBPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64ARB")) == NULL) || r;
+ r = ((glUniformHandleui64vARB = (PFNGLUNIFORMHANDLEUI64VARBPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64vARB")) == NULL) || r;
+ r = ((glVertexAttribL1ui64ARB = (PFNGLVERTEXATTRIBL1UI64ARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64ARB")) == NULL) || r;
+ r = ((glVertexAttribL1ui64vARB = (PFNGLVERTEXATTRIBL1UI64VARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64vARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_bindless_texture */
+
+#ifdef GL_ARB_blend_func_extended
+
+static GLboolean _glewInit_GL_ARB_blend_func_extended (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocationIndexed")) == NULL) || r;
+ r = ((glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataIndex")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_blend_func_extended */
+
+#ifdef GL_ARB_buffer_storage
+
+static GLboolean _glewInit_GL_ARB_buffer_storage (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBufferStorage = (PFNGLBUFFERSTORAGEPROC)glewGetProcAddress((const GLubyte*)"glBufferStorage")) == NULL) || r;
+ r = ((glNamedBufferStorageEXT = (PFNGLNAMEDBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferStorageEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_buffer_storage */
+
+#ifdef GL_ARB_cl_event
+
+static GLboolean _glewInit_GL_ARB_cl_event (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCreateSyncFromCLeventARB = (PFNGLCREATESYNCFROMCLEVENTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateSyncFromCLeventARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_cl_event */
+
+#ifdef GL_ARB_clear_buffer_object
+
+static GLboolean _glewInit_GL_ARB_clear_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClearBufferData = (PFNGLCLEARBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glClearBufferData")) == NULL) || r;
+ r = ((glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glClearBufferSubData")) == NULL) || r;
+ r = ((glClearNamedBufferDataEXT = (PFNGLCLEARNAMEDBUFFERDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glClearNamedBufferDataEXT")) == NULL) || r;
+ r = ((glClearNamedBufferSubDataEXT = (PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glClearNamedBufferSubDataEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_clear_buffer_object */
+
+#ifdef GL_ARB_clear_texture
+
+static GLboolean _glewInit_GL_ARB_clear_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClearTexImage = (PFNGLCLEARTEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glClearTexImage")) == NULL) || r;
+ r = ((glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC)glewGetProcAddress((const GLubyte*)"glClearTexSubImage")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_clear_texture */
+
+#ifdef GL_ARB_color_buffer_float
+
+static GLboolean _glewInit_GL_ARB_color_buffer_float (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClampColorARB = (PFNGLCLAMPCOLORARBPROC)glewGetProcAddress((const GLubyte*)"glClampColorARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_color_buffer_float */
+
+#ifdef GL_ARB_compatibility
+
+#endif /* GL_ARB_compatibility */
+
+#ifdef GL_ARB_compressed_texture_pixel_storage
+
+#endif /* GL_ARB_compressed_texture_pixel_storage */
+
+#ifdef GL_ARB_compute_shader
+
+static GLboolean _glewInit_GL_ARB_compute_shader (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)glewGetProcAddress((const GLubyte*)"glDispatchCompute")) == NULL) || r;
+ r = ((glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glDispatchComputeIndirect")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_compute_shader */
+
+#ifdef GL_ARB_compute_variable_group_size
+
+static GLboolean _glewInit_GL_ARB_compute_variable_group_size (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDispatchComputeGroupSizeARB = (PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC)glewGetProcAddress((const GLubyte*)"glDispatchComputeGroupSizeARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_compute_variable_group_size */
+
+#ifdef GL_ARB_conservative_depth
+
+#endif /* GL_ARB_conservative_depth */
+
+#ifdef GL_ARB_copy_buffer
+
+static GLboolean _glewInit_GL_ARB_copy_buffer (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glCopyBufferSubData")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_copy_buffer */
+
+#ifdef GL_ARB_copy_image
+
+static GLboolean _glewInit_GL_ARB_copy_image (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC)glewGetProcAddress((const GLubyte*)"glCopyImageSubData")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_copy_image */
+
+#ifdef GL_ARB_debug_output
+
+static GLboolean _glewInit_GL_ARB_debug_output (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageCallbackARB")) == NULL) || r;
+ r = ((glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageControlARB")) == NULL) || r;
+ r = ((glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageInsertARB")) == NULL) || r;
+ r = ((glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC)glewGetProcAddress((const GLubyte*)"glGetDebugMessageLogARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_debug_output */
+
+#ifdef GL_ARB_depth_buffer_float
+
+#endif /* GL_ARB_depth_buffer_float */
+
+#ifdef GL_ARB_depth_clamp
+
+#endif /* GL_ARB_depth_clamp */
+
+#ifdef GL_ARB_depth_texture
+
+#endif /* GL_ARB_depth_texture */
+
+#ifdef GL_ARB_draw_buffers
+
+static GLboolean _glewInit_GL_ARB_draw_buffers (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_draw_buffers */
+
+#ifdef GL_ARB_draw_buffers_blend
+
+static GLboolean _glewInit_GL_ARB_draw_buffers_blend (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendEquationSeparateiARB = (PFNGLBLENDEQUATIONSEPARATEIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateiARB")) == NULL) || r;
+ r = ((glBlendEquationiARB = (PFNGLBLENDEQUATIONIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationiARB")) == NULL) || r;
+ r = ((glBlendFuncSeparateiARB = (PFNGLBLENDFUNCSEPARATEIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateiARB")) == NULL) || r;
+ r = ((glBlendFunciARB = (PFNGLBLENDFUNCIARBPROC)glewGetProcAddress((const GLubyte*)"glBlendFunciARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_draw_buffers_blend */
+
+#ifdef GL_ARB_draw_elements_base_vertex
+
+static GLboolean _glewInit_GL_ARB_draw_elements_base_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsBaseVertex")) == NULL) || r;
+ r = ((glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedBaseVertex")) == NULL) || r;
+ r = ((glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementsBaseVertex")) == NULL) || r;
+ r = ((glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsBaseVertex")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_draw_elements_base_vertex */
+
+#ifdef GL_ARB_draw_indirect
+
+static GLboolean _glewInit_GL_ARB_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysIndirect")) == NULL) || r;
+ r = ((glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsIndirect")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_draw_indirect */
+
+#ifdef GL_ARB_draw_instanced
+
+#endif /* GL_ARB_draw_instanced */
+
+#ifdef GL_ARB_enhanced_layouts
+
+#endif /* GL_ARB_enhanced_layouts */
+
+#ifdef GL_ARB_explicit_attrib_location
+
+#endif /* GL_ARB_explicit_attrib_location */
+
+#ifdef GL_ARB_explicit_uniform_location
+
+#endif /* GL_ARB_explicit_uniform_location */
+
+#ifdef GL_ARB_fragment_coord_conventions
+
+#endif /* GL_ARB_fragment_coord_conventions */
+
+#ifdef GL_ARB_fragment_layer_viewport
+
+#endif /* GL_ARB_fragment_layer_viewport */
+
+#ifdef GL_ARB_fragment_program
+
+#endif /* GL_ARB_fragment_program */
+
+#ifdef GL_ARB_fragment_program_shadow
+
+#endif /* GL_ARB_fragment_program_shadow */
+
+#ifdef GL_ARB_fragment_shader
+
+#endif /* GL_ARB_fragment_shader */
+
+#ifdef GL_ARB_framebuffer_no_attachments
+
+static GLboolean _glewInit_GL_ARB_framebuffer_no_attachments (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glFramebufferParameteri")) == NULL) || r;
+ r = ((glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferParameteriv")) == NULL) || r;
+ r = ((glGetNamedFramebufferParameterivEXT = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferParameterivEXT")) == NULL) || r;
+ r = ((glNamedFramebufferParameteriEXT = (PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferParameteriEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_framebuffer_no_attachments */
+
+#ifdef GL_ARB_framebuffer_object
+
+static GLboolean _glewInit_GL_ARB_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindFramebuffer")) == NULL) || r;
+ r = ((glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindRenderbuffer")) == NULL) || r;
+ r = ((glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebuffer")) == NULL) || r;
+ r = ((glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)glewGetProcAddress((const GLubyte*)"glCheckFramebufferStatus")) == NULL) || r;
+ r = ((glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffers")) == NULL) || r;
+ r = ((glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffers")) == NULL) || r;
+ r = ((glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbuffer")) == NULL) || r;
+ r = ((glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1D")) == NULL) || r;
+ r = ((glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2D")) == NULL) || r;
+ r = ((glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3D")) == NULL) || r;
+ r = ((glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayer")) == NULL) || r;
+ r = ((glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenFramebuffers")) == NULL) || r;
+ r = ((glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glGenRenderbuffers")) == NULL) || r;
+ r = ((glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)glewGetProcAddress((const GLubyte*)"glGenerateMipmap")) == NULL) || r;
+ r = ((glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferAttachmentParameteriv")) == NULL) || r;
+ r = ((glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetRenderbufferParameteriv")) == NULL) || r;
+ r = ((glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsFramebuffer")) == NULL) || r;
+ r = ((glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)glewGetProcAddress((const GLubyte*)"glIsRenderbuffer")) == NULL) || r;
+ r = ((glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorage")) == NULL) || r;
+ r = ((glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisample")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_framebuffer_object */
+
+#ifdef GL_ARB_framebuffer_sRGB
+
+#endif /* GL_ARB_framebuffer_sRGB */
+
+#ifdef GL_ARB_geometry_shader4
+
+static GLboolean _glewInit_GL_ARB_geometry_shader4 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferTextureARB = (PFNGLFRAMEBUFFERTEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureARB")) == NULL) || r;
+ r = ((glFramebufferTextureFaceARB = (PFNGLFRAMEBUFFERTEXTUREFACEARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureFaceARB")) == NULL) || r;
+ r = ((glFramebufferTextureLayerARB = (PFNGLFRAMEBUFFERTEXTURELAYERARBPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerARB")) == NULL) || r;
+ r = ((glProgramParameteriARB = (PFNGLPROGRAMPARAMETERIARBPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteriARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_geometry_shader4 */
+
+#ifdef GL_ARB_get_program_binary
+
+static GLboolean _glewInit_GL_ARB_get_program_binary (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)glewGetProcAddress((const GLubyte*)"glGetProgramBinary")) == NULL) || r;
+ r = ((glProgramBinary = (PFNGLPROGRAMBINARYPROC)glewGetProcAddress((const GLubyte*)"glProgramBinary")) == NULL) || r;
+ r = ((glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteri")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_get_program_binary */
+
+#ifdef GL_ARB_gpu_shader5
+
+#endif /* GL_ARB_gpu_shader5 */
+
+#ifdef GL_ARB_gpu_shader_fp64
+
+static GLboolean _glewInit_GL_ARB_gpu_shader_fp64 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetUniformdv = (PFNGLGETUNIFORMDVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformdv")) == NULL) || r;
+ r = ((glUniform1d = (PFNGLUNIFORM1DPROC)glewGetProcAddress((const GLubyte*)"glUniform1d")) == NULL) || r;
+ r = ((glUniform1dv = (PFNGLUNIFORM1DVPROC)glewGetProcAddress((const GLubyte*)"glUniform1dv")) == NULL) || r;
+ r = ((glUniform2d = (PFNGLUNIFORM2DPROC)glewGetProcAddress((const GLubyte*)"glUniform2d")) == NULL) || r;
+ r = ((glUniform2dv = (PFNGLUNIFORM2DVPROC)glewGetProcAddress((const GLubyte*)"glUniform2dv")) == NULL) || r;
+ r = ((glUniform3d = (PFNGLUNIFORM3DPROC)glewGetProcAddress((const GLubyte*)"glUniform3d")) == NULL) || r;
+ r = ((glUniform3dv = (PFNGLUNIFORM3DVPROC)glewGetProcAddress((const GLubyte*)"glUniform3dv")) == NULL) || r;
+ r = ((glUniform4d = (PFNGLUNIFORM4DPROC)glewGetProcAddress((const GLubyte*)"glUniform4d")) == NULL) || r;
+ r = ((glUniform4dv = (PFNGLUNIFORM4DVPROC)glewGetProcAddress((const GLubyte*)"glUniform4dv")) == NULL) || r;
+ r = ((glUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2dv")) == NULL) || r;
+ r = ((glUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x3dv")) == NULL) || r;
+ r = ((glUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2x4dv")) == NULL) || r;
+ r = ((glUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3dv")) == NULL) || r;
+ r = ((glUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x2dv")) == NULL) || r;
+ r = ((glUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3x4dv")) == NULL) || r;
+ r = ((glUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4dv")) == NULL) || r;
+ r = ((glUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x2dv")) == NULL) || r;
+ r = ((glUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4x3dv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_gpu_shader_fp64 */
+
+#ifdef GL_ARB_half_float_pixel
+
+#endif /* GL_ARB_half_float_pixel */
+
+#ifdef GL_ARB_half_float_vertex
+
+#endif /* GL_ARB_half_float_vertex */
+
+#ifdef GL_ARB_imaging
+
+static GLboolean _glewInit_GL_ARB_imaging (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte*)"glBlendEquation")) == NULL) || r;
+ r = ((glColorSubTable = (PFNGLCOLORSUBTABLEPROC)glewGetProcAddress((const GLubyte*)"glColorSubTable")) == NULL) || r;
+ r = ((glColorTable = (PFNGLCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glColorTable")) == NULL) || r;
+ r = ((glColorTableParameterfv = (PFNGLCOLORTABLEPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterfv")) == NULL) || r;
+ r = ((glColorTableParameteriv = (PFNGLCOLORTABLEPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameteriv")) == NULL) || r;
+ r = ((glConvolutionFilter1D = (PFNGLCONVOLUTIONFILTER1DPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter1D")) == NULL) || r;
+ r = ((glConvolutionFilter2D = (PFNGLCONVOLUTIONFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter2D")) == NULL) || r;
+ r = ((glConvolutionParameterf = (PFNGLCONVOLUTIONPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterf")) == NULL) || r;
+ r = ((glConvolutionParameterfv = (PFNGLCONVOLUTIONPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfv")) == NULL) || r;
+ r = ((glConvolutionParameteri = (PFNGLCONVOLUTIONPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteri")) == NULL) || r;
+ r = ((glConvolutionParameteriv = (PFNGLCONVOLUTIONPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteriv")) == NULL) || r;
+ r = ((glCopyColorSubTable = (PFNGLCOPYCOLORSUBTABLEPROC)glewGetProcAddress((const GLubyte*)"glCopyColorSubTable")) == NULL) || r;
+ r = ((glCopyColorTable = (PFNGLCOPYCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glCopyColorTable")) == NULL) || r;
+ r = ((glCopyConvolutionFilter1D = (PFNGLCOPYCONVOLUTIONFILTER1DPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter1D")) == NULL) || r;
+ r = ((glCopyConvolutionFilter2D = (PFNGLCOPYCONVOLUTIONFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter2D")) == NULL) || r;
+ r = ((glGetColorTable = (PFNGLGETCOLORTABLEPROC)glewGetProcAddress((const GLubyte*)"glGetColorTable")) == NULL) || r;
+ r = ((glGetColorTableParameterfv = (PFNGLGETCOLORTABLEPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfv")) == NULL) || r;
+ r = ((glGetColorTableParameteriv = (PFNGLGETCOLORTABLEPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameteriv")) == NULL) || r;
+ r = ((glGetConvolutionFilter = (PFNGLGETCONVOLUTIONFILTERPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionFilter")) == NULL) || r;
+ r = ((glGetConvolutionParameterfv = (PFNGLGETCONVOLUTIONPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterfv")) == NULL) || r;
+ r = ((glGetConvolutionParameteriv = (PFNGLGETCONVOLUTIONPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameteriv")) == NULL) || r;
+ r = ((glGetHistogram = (PFNGLGETHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glGetHistogram")) == NULL) || r;
+ r = ((glGetHistogramParameterfv = (PFNGLGETHISTOGRAMPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterfv")) == NULL) || r;
+ r = ((glGetHistogramParameteriv = (PFNGLGETHISTOGRAMPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameteriv")) == NULL) || r;
+ r = ((glGetMinmax = (PFNGLGETMINMAXPROC)glewGetProcAddress((const GLubyte*)"glGetMinmax")) == NULL) || r;
+ r = ((glGetMinmaxParameterfv = (PFNGLGETMINMAXPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterfv")) == NULL) || r;
+ r = ((glGetMinmaxParameteriv = (PFNGLGETMINMAXPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameteriv")) == NULL) || r;
+ r = ((glGetSeparableFilter = (PFNGLGETSEPARABLEFILTERPROC)glewGetProcAddress((const GLubyte*)"glGetSeparableFilter")) == NULL) || r;
+ r = ((glHistogram = (PFNGLHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glHistogram")) == NULL) || r;
+ r = ((glMinmax = (PFNGLMINMAXPROC)glewGetProcAddress((const GLubyte*)"glMinmax")) == NULL) || r;
+ r = ((glResetHistogram = (PFNGLRESETHISTOGRAMPROC)glewGetProcAddress((const GLubyte*)"glResetHistogram")) == NULL) || r;
+ r = ((glResetMinmax = (PFNGLRESETMINMAXPROC)glewGetProcAddress((const GLubyte*)"glResetMinmax")) == NULL) || r;
+ r = ((glSeparableFilter2D = (PFNGLSEPARABLEFILTER2DPROC)glewGetProcAddress((const GLubyte*)"glSeparableFilter2D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_imaging */
+
+#ifdef GL_ARB_indirect_parameters
+
+static GLboolean _glewInit_GL_ARB_indirect_parameters (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiDrawArraysIndirectCountARB = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectCountARB")) == NULL) || r;
+ r = ((glMultiDrawElementsIndirectCountARB = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectCountARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_indirect_parameters */
+
+#ifdef GL_ARB_instanced_arrays
+
+static GLboolean _glewInit_GL_ARB_instanced_arrays (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawArraysInstancedARB = (PFNGLDRAWARRAYSINSTANCEDARBPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedARB")) == NULL) || r;
+ r = ((glDrawElementsInstancedARB = (PFNGLDRAWELEMENTSINSTANCEDARBPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedARB")) == NULL) || r;
+ r = ((glVertexAttribDivisorARB = (PFNGLVERTEXATTRIBDIVISORARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribDivisorARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_instanced_arrays */
+
+#ifdef GL_ARB_internalformat_query
+
+static GLboolean _glewInit_GL_ARB_internalformat_query (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)glewGetProcAddress((const GLubyte*)"glGetInternalformativ")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_internalformat_query */
+
+#ifdef GL_ARB_internalformat_query2
+
+static GLboolean _glewInit_GL_ARB_internalformat_query2 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC)glewGetProcAddress((const GLubyte*)"glGetInternalformati64v")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_internalformat_query2 */
+
+#ifdef GL_ARB_invalidate_subdata
+
+static GLboolean _glewInit_GL_ARB_invalidate_subdata (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC)glewGetProcAddress((const GLubyte*)"glInvalidateBufferData")) == NULL) || r;
+ r = ((glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC)glewGetProcAddress((const GLubyte*)"glInvalidateBufferSubData")) == NULL) || r;
+ r = ((glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glInvalidateFramebuffer")) == NULL) || r;
+ r = ((glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC)glewGetProcAddress((const GLubyte*)"glInvalidateSubFramebuffer")) == NULL) || r;
+ r = ((glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC)glewGetProcAddress((const GLubyte*)"glInvalidateTexImage")) == NULL) || r;
+ r = ((glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC)glewGetProcAddress((const GLubyte*)"glInvalidateTexSubImage")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_invalidate_subdata */
+
+#ifdef GL_ARB_map_buffer_alignment
+
+#endif /* GL_ARB_map_buffer_alignment */
+
+#ifdef GL_ARB_map_buffer_range
+
+static GLboolean _glewInit_GL_ARB_map_buffer_range (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedBufferRange")) == NULL) || r;
+ r = ((glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glMapBufferRange")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_map_buffer_range */
+
+#ifdef GL_ARB_matrix_palette
+
+static GLboolean _glewInit_GL_ARB_matrix_palette (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCurrentPaletteMatrixARB = (PFNGLCURRENTPALETTEMATRIXARBPROC)glewGetProcAddress((const GLubyte*)"glCurrentPaletteMatrixARB")) == NULL) || r;
+ r = ((glMatrixIndexPointerARB = (PFNGLMATRIXINDEXPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexPointerARB")) == NULL) || r;
+ r = ((glMatrixIndexubvARB = (PFNGLMATRIXINDEXUBVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexubvARB")) == NULL) || r;
+ r = ((glMatrixIndexuivARB = (PFNGLMATRIXINDEXUIVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexuivARB")) == NULL) || r;
+ r = ((glMatrixIndexusvARB = (PFNGLMATRIXINDEXUSVARBPROC)glewGetProcAddress((const GLubyte*)"glMatrixIndexusvARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_matrix_palette */
+
+#ifdef GL_ARB_multi_bind
+
+static GLboolean _glewInit_GL_ARB_multi_bind (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindBuffersBase = (PFNGLBINDBUFFERSBASEPROC)glewGetProcAddress((const GLubyte*)"glBindBuffersBase")) == NULL) || r;
+ r = ((glBindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC)glewGetProcAddress((const GLubyte*)"glBindBuffersRange")) == NULL) || r;
+ r = ((glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)glewGetProcAddress((const GLubyte*)"glBindImageTextures")) == NULL) || r;
+ r = ((glBindSamplers = (PFNGLBINDSAMPLERSPROC)glewGetProcAddress((const GLubyte*)"glBindSamplers")) == NULL) || r;
+ r = ((glBindTextures = (PFNGLBINDTEXTURESPROC)glewGetProcAddress((const GLubyte*)"glBindTextures")) == NULL) || r;
+ r = ((glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC)glewGetProcAddress((const GLubyte*)"glBindVertexBuffers")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_multi_bind */
+
+#ifdef GL_ARB_multi_draw_indirect
+
+static GLboolean _glewInit_GL_ARB_multi_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirect")) == NULL) || r;
+ r = ((glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirect")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_multi_draw_indirect */
+
+#ifdef GL_ARB_multisample
+
+static GLboolean _glewInit_GL_ARB_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSampleCoverageARB = (PFNGLSAMPLECOVERAGEARBPROC)glewGetProcAddress((const GLubyte*)"glSampleCoverageARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_multisample */
+
+#ifdef GL_ARB_multitexture
+
+static GLboolean _glewInit_GL_ARB_multitexture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glActiveTextureARB")) == NULL) || r;
+ r = ((glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)glewGetProcAddress((const GLubyte*)"glClientActiveTextureARB")) == NULL) || r;
+ r = ((glMultiTexCoord1dARB = (PFNGLMULTITEXCOORD1DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dARB")) == NULL) || r;
+ r = ((glMultiTexCoord1dvARB = (PFNGLMULTITEXCOORD1DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1dvARB")) == NULL) || r;
+ r = ((glMultiTexCoord1fARB = (PFNGLMULTITEXCOORD1FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fARB")) == NULL) || r;
+ r = ((glMultiTexCoord1fvARB = (PFNGLMULTITEXCOORD1FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1fvARB")) == NULL) || r;
+ r = ((glMultiTexCoord1iARB = (PFNGLMULTITEXCOORD1IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1iARB")) == NULL) || r;
+ r = ((glMultiTexCoord1ivARB = (PFNGLMULTITEXCOORD1IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1ivARB")) == NULL) || r;
+ r = ((glMultiTexCoord1sARB = (PFNGLMULTITEXCOORD1SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1sARB")) == NULL) || r;
+ r = ((glMultiTexCoord1svARB = (PFNGLMULTITEXCOORD1SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1svARB")) == NULL) || r;
+ r = ((glMultiTexCoord2dARB = (PFNGLMULTITEXCOORD2DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dARB")) == NULL) || r;
+ r = ((glMultiTexCoord2dvARB = (PFNGLMULTITEXCOORD2DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2dvARB")) == NULL) || r;
+ r = ((glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fARB")) == NULL) || r;
+ r = ((glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2fvARB")) == NULL) || r;
+ r = ((glMultiTexCoord2iARB = (PFNGLMULTITEXCOORD2IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2iARB")) == NULL) || r;
+ r = ((glMultiTexCoord2ivARB = (PFNGLMULTITEXCOORD2IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2ivARB")) == NULL) || r;
+ r = ((glMultiTexCoord2sARB = (PFNGLMULTITEXCOORD2SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2sARB")) == NULL) || r;
+ r = ((glMultiTexCoord2svARB = (PFNGLMULTITEXCOORD2SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2svARB")) == NULL) || r;
+ r = ((glMultiTexCoord3dARB = (PFNGLMULTITEXCOORD3DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dARB")) == NULL) || r;
+ r = ((glMultiTexCoord3dvARB = (PFNGLMULTITEXCOORD3DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3dvARB")) == NULL) || r;
+ r = ((glMultiTexCoord3fARB = (PFNGLMULTITEXCOORD3FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fARB")) == NULL) || r;
+ r = ((glMultiTexCoord3fvARB = (PFNGLMULTITEXCOORD3FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3fvARB")) == NULL) || r;
+ r = ((glMultiTexCoord3iARB = (PFNGLMULTITEXCOORD3IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3iARB")) == NULL) || r;
+ r = ((glMultiTexCoord3ivARB = (PFNGLMULTITEXCOORD3IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3ivARB")) == NULL) || r;
+ r = ((glMultiTexCoord3sARB = (PFNGLMULTITEXCOORD3SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3sARB")) == NULL) || r;
+ r = ((glMultiTexCoord3svARB = (PFNGLMULTITEXCOORD3SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3svARB")) == NULL) || r;
+ r = ((glMultiTexCoord4dARB = (PFNGLMULTITEXCOORD4DARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dARB")) == NULL) || r;
+ r = ((glMultiTexCoord4dvARB = (PFNGLMULTITEXCOORD4DVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4dvARB")) == NULL) || r;
+ r = ((glMultiTexCoord4fARB = (PFNGLMULTITEXCOORD4FARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fARB")) == NULL) || r;
+ r = ((glMultiTexCoord4fvARB = (PFNGLMULTITEXCOORD4FVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4fvARB")) == NULL) || r;
+ r = ((glMultiTexCoord4iARB = (PFNGLMULTITEXCOORD4IARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4iARB")) == NULL) || r;
+ r = ((glMultiTexCoord4ivARB = (PFNGLMULTITEXCOORD4IVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4ivARB")) == NULL) || r;
+ r = ((glMultiTexCoord4sARB = (PFNGLMULTITEXCOORD4SARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4sARB")) == NULL) || r;
+ r = ((glMultiTexCoord4svARB = (PFNGLMULTITEXCOORD4SVARBPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4svARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_multitexture */
+
+#ifdef GL_ARB_occlusion_query
+
+static GLboolean _glewInit_GL_ARB_occlusion_query (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryARB")) == NULL) || r;
+ r = ((glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteQueriesARB")) == NULL) || r;
+ r = ((glEndQueryARB = (PFNGLENDQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glEndQueryARB")) == NULL) || r;
+ r = ((glGenQueriesARB = (PFNGLGENQUERIESARBPROC)glewGetProcAddress((const GLubyte*)"glGenQueriesARB")) == NULL) || r;
+ r = ((glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectivARB")) == NULL) || r;
+ r = ((glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectuivARB")) == NULL) || r;
+ r = ((glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetQueryivARB")) == NULL) || r;
+ r = ((glIsQueryARB = (PFNGLISQUERYARBPROC)glewGetProcAddress((const GLubyte*)"glIsQueryARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_occlusion_query */
+
+#ifdef GL_ARB_occlusion_query2
+
+#endif /* GL_ARB_occlusion_query2 */
+
+#ifdef GL_ARB_pixel_buffer_object
+
+#endif /* GL_ARB_pixel_buffer_object */
+
+#ifdef GL_ARB_point_parameters
+
+static GLboolean _glewInit_GL_ARB_point_parameters (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfARB")) == NULL) || r;
+ r = ((glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfvARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_point_parameters */
+
+#ifdef GL_ARB_point_sprite
+
+#endif /* GL_ARB_point_sprite */
+
+#ifdef GL_ARB_program_interface_query
+
+static GLboolean _glewInit_GL_ARB_program_interface_query (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramInterfaceiv")) == NULL) || r;
+ r = ((glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceIndex")) == NULL) || r;
+ r = ((glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceLocation")) == NULL) || r;
+ r = ((glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceLocationIndex")) == NULL) || r;
+ r = ((glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceName")) == NULL) || r;
+ r = ((glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramResourceiv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_program_interface_query */
+
+#ifdef GL_ARB_provoking_vertex
+
+static GLboolean _glewInit_GL_ARB_provoking_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)glewGetProcAddress((const GLubyte*)"glProvokingVertex")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_provoking_vertex */
+
+#ifdef GL_ARB_query_buffer_object
+
+#endif /* GL_ARB_query_buffer_object */
+
+#ifdef GL_ARB_robust_buffer_access_behavior
+
+#endif /* GL_ARB_robust_buffer_access_behavior */
+
+#ifdef GL_ARB_robustness
+
+static GLboolean _glewInit_GL_ARB_robustness (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetGraphicsResetStatusARB = (PFNGLGETGRAPHICSRESETSTATUSARBPROC)glewGetProcAddress((const GLubyte*)"glGetGraphicsResetStatusARB")) == NULL) || r;
+ r = ((glGetnColorTableARB = (PFNGLGETNCOLORTABLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnColorTableARB")) == NULL) || r;
+ r = ((glGetnCompressedTexImageARB = (PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnCompressedTexImageARB")) == NULL) || r;
+ r = ((glGetnConvolutionFilterARB = (PFNGLGETNCONVOLUTIONFILTERARBPROC)glewGetProcAddress((const GLubyte*)"glGetnConvolutionFilterARB")) == NULL) || r;
+ r = ((glGetnHistogramARB = (PFNGLGETNHISTOGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glGetnHistogramARB")) == NULL) || r;
+ r = ((glGetnMapdvARB = (PFNGLGETNMAPDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMapdvARB")) == NULL) || r;
+ r = ((glGetnMapfvARB = (PFNGLGETNMAPFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMapfvARB")) == NULL) || r;
+ r = ((glGetnMapivARB = (PFNGLGETNMAPIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMapivARB")) == NULL) || r;
+ r = ((glGetnMinmaxARB = (PFNGLGETNMINMAXARBPROC)glewGetProcAddress((const GLubyte*)"glGetnMinmaxARB")) == NULL) || r;
+ r = ((glGetnPixelMapfvARB = (PFNGLGETNPIXELMAPFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPixelMapfvARB")) == NULL) || r;
+ r = ((glGetnPixelMapuivARB = (PFNGLGETNPIXELMAPUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPixelMapuivARB")) == NULL) || r;
+ r = ((glGetnPixelMapusvARB = (PFNGLGETNPIXELMAPUSVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPixelMapusvARB")) == NULL) || r;
+ r = ((glGetnPolygonStippleARB = (PFNGLGETNPOLYGONSTIPPLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnPolygonStippleARB")) == NULL) || r;
+ r = ((glGetnSeparableFilterARB = (PFNGLGETNSEPARABLEFILTERARBPROC)glewGetProcAddress((const GLubyte*)"glGetnSeparableFilterARB")) == NULL) || r;
+ r = ((glGetnTexImageARB = (PFNGLGETNTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetnTexImageARB")) == NULL) || r;
+ r = ((glGetnUniformdvARB = (PFNGLGETNUNIFORMDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformdvARB")) == NULL) || r;
+ r = ((glGetnUniformfvARB = (PFNGLGETNUNIFORMFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformfvARB")) == NULL) || r;
+ r = ((glGetnUniformivARB = (PFNGLGETNUNIFORMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformivARB")) == NULL) || r;
+ r = ((glGetnUniformuivARB = (PFNGLGETNUNIFORMUIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetnUniformuivARB")) == NULL) || r;
+ r = ((glReadnPixelsARB = (PFNGLREADNPIXELSARBPROC)glewGetProcAddress((const GLubyte*)"glReadnPixelsARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_robustness */
+
+#ifdef GL_ARB_robustness_application_isolation
+
+#endif /* GL_ARB_robustness_application_isolation */
+
+#ifdef GL_ARB_robustness_share_group_isolation
+
+#endif /* GL_ARB_robustness_share_group_isolation */
+
+#ifdef GL_ARB_sample_shading
+
+static GLboolean _glewInit_GL_ARB_sample_shading (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMinSampleShadingARB = (PFNGLMINSAMPLESHADINGARBPROC)glewGetProcAddress((const GLubyte*)"glMinSampleShadingARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_sample_shading */
+
+#ifdef GL_ARB_sampler_objects
+
+static GLboolean _glewInit_GL_ARB_sampler_objects (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindSampler = (PFNGLBINDSAMPLERPROC)glewGetProcAddress((const GLubyte*)"glBindSampler")) == NULL) || r;
+ r = ((glDeleteSamplers = (PFNGLDELETESAMPLERSPROC)glewGetProcAddress((const GLubyte*)"glDeleteSamplers")) == NULL) || r;
+ r = ((glGenSamplers = (PFNGLGENSAMPLERSPROC)glewGetProcAddress((const GLubyte*)"glGenSamplers")) == NULL) || r;
+ r = ((glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameterIiv")) == NULL) || r;
+ r = ((glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameterIuiv")) == NULL) || r;
+ r = ((glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameterfv")) == NULL) || r;
+ r = ((glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glGetSamplerParameteriv")) == NULL) || r;
+ r = ((glIsSampler = (PFNGLISSAMPLERPROC)glewGetProcAddress((const GLubyte*)"glIsSampler")) == NULL) || r;
+ r = ((glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterIiv")) == NULL) || r;
+ r = ((glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterIuiv")) == NULL) || r;
+ r = ((glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterf")) == NULL) || r;
+ r = ((glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameterfv")) == NULL) || r;
+ r = ((glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameteri")) == NULL) || r;
+ r = ((glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC)glewGetProcAddress((const GLubyte*)"glSamplerParameteriv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_sampler_objects */
+
+#ifdef GL_ARB_seamless_cube_map
+
+#endif /* GL_ARB_seamless_cube_map */
+
+#ifdef GL_ARB_seamless_cubemap_per_texture
+
+#endif /* GL_ARB_seamless_cubemap_per_texture */
+
+#ifdef GL_ARB_separate_shader_objects
+
+static GLboolean _glewInit_GL_ARB_separate_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC)glewGetProcAddress((const GLubyte*)"glActiveShaderProgram")) == NULL) || r;
+ r = ((glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC)glewGetProcAddress((const GLubyte*)"glBindProgramPipeline")) == NULL) || r;
+ r = ((glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderProgramv")) == NULL) || r;
+ r = ((glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramPipelines")) == NULL) || r;
+ r = ((glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC)glewGetProcAddress((const GLubyte*)"glGenProgramPipelines")) == NULL) || r;
+ r = ((glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC)glewGetProcAddress((const GLubyte*)"glGetProgramPipelineInfoLog")) == NULL) || r;
+ r = ((glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramPipelineiv")) == NULL) || r;
+ r = ((glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC)glewGetProcAddress((const GLubyte*)"glIsProgramPipeline")) == NULL) || r;
+ r = ((glProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1d")) == NULL) || r;
+ r = ((glProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1dv")) == NULL) || r;
+ r = ((glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1f")) == NULL) || r;
+ r = ((glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fv")) == NULL) || r;
+ r = ((glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i")) == NULL) || r;
+ r = ((glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1iv")) == NULL) || r;
+ r = ((glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui")) == NULL) || r;
+ r = ((glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uiv")) == NULL) || r;
+ r = ((glProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2d")) == NULL) || r;
+ r = ((glProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2dv")) == NULL) || r;
+ r = ((glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2f")) == NULL) || r;
+ r = ((glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fv")) == NULL) || r;
+ r = ((glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i")) == NULL) || r;
+ r = ((glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2iv")) == NULL) || r;
+ r = ((glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui")) == NULL) || r;
+ r = ((glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uiv")) == NULL) || r;
+ r = ((glProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3d")) == NULL) || r;
+ r = ((glProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3dv")) == NULL) || r;
+ r = ((glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3f")) == NULL) || r;
+ r = ((glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fv")) == NULL) || r;
+ r = ((glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i")) == NULL) || r;
+ r = ((glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3iv")) == NULL) || r;
+ r = ((glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui")) == NULL) || r;
+ r = ((glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uiv")) == NULL) || r;
+ r = ((glProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4d")) == NULL) || r;
+ r = ((glProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4dv")) == NULL) || r;
+ r = ((glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4f")) == NULL) || r;
+ r = ((glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fv")) == NULL) || r;
+ r = ((glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i")) == NULL) || r;
+ r = ((glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4iv")) == NULL) || r;
+ r = ((glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui")) == NULL) || r;
+ r = ((glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uiv")) == NULL) || r;
+ r = ((glProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x3dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x3fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x4dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x4fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x2dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x2fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x4dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x4fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x2dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x2fv")) == NULL) || r;
+ r = ((glProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x3dv")) == NULL) || r;
+ r = ((glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x3fv")) == NULL) || r;
+ r = ((glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC)glewGetProcAddress((const GLubyte*)"glUseProgramStages")) == NULL) || r;
+ r = ((glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC)glewGetProcAddress((const GLubyte*)"glValidateProgramPipeline")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_separate_shader_objects */
+
+#ifdef GL_ARB_shader_atomic_counters
+
+static GLboolean _glewInit_GL_ARB_shader_atomic_counters (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAtomicCounterBufferiv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_shader_atomic_counters */
+
+#ifdef GL_ARB_shader_bit_encoding
+
+#endif /* GL_ARB_shader_bit_encoding */
+
+#ifdef GL_ARB_shader_draw_parameters
+
+#endif /* GL_ARB_shader_draw_parameters */
+
+#ifdef GL_ARB_shader_group_vote
+
+#endif /* GL_ARB_shader_group_vote */
+
+#ifdef GL_ARB_shader_image_load_store
+
+static GLboolean _glewInit_GL_ARB_shader_image_load_store (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)glewGetProcAddress((const GLubyte*)"glBindImageTexture")) == NULL) || r;
+ r = ((glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)glewGetProcAddress((const GLubyte*)"glMemoryBarrier")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_shader_image_load_store */
+
+#ifdef GL_ARB_shader_image_size
+
+#endif /* GL_ARB_shader_image_size */
+
+#ifdef GL_ARB_shader_objects
+
+static GLboolean _glewInit_GL_ARB_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glAttachObjectARB")) == NULL) || r;
+ r = ((glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)glewGetProcAddress((const GLubyte*)"glCompileShaderARB")) == NULL) || r;
+ r = ((glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateProgramObjectARB")) == NULL) || r;
+ r = ((glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderObjectARB")) == NULL) || r;
+ r = ((glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteObjectARB")) == NULL) || r;
+ r = ((glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glDetachObjectARB")) == NULL) || r;
+ r = ((glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformARB")) == NULL) || r;
+ r = ((glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC)glewGetProcAddress((const GLubyte*)"glGetAttachedObjectsARB")) == NULL) || r;
+ r = ((glGetHandleARB = (PFNGLGETHANDLEARBPROC)glewGetProcAddress((const GLubyte*)"glGetHandleARB")) == NULL) || r;
+ r = ((glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)glewGetProcAddress((const GLubyte*)"glGetInfoLogARB")) == NULL) || r;
+ r = ((glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterfvARB")) == NULL) || r;
+ r = ((glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetObjectParameterivARB")) == NULL) || r;
+ r = ((glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC)glewGetProcAddress((const GLubyte*)"glGetShaderSourceARB")) == NULL) || r;
+ r = ((glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformLocationARB")) == NULL) || r;
+ r = ((glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformfvARB")) == NULL) || r;
+ r = ((glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetUniformivARB")) == NULL) || r;
+ r = ((glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glLinkProgramARB")) == NULL) || r;
+ r = ((glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)glewGetProcAddress((const GLubyte*)"glShaderSourceARB")) == NULL) || r;
+ r = ((glUniform1fARB = (PFNGLUNIFORM1FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1fARB")) == NULL) || r;
+ r = ((glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1fvARB")) == NULL) || r;
+ r = ((glUniform1iARB = (PFNGLUNIFORM1IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1iARB")) == NULL) || r;
+ r = ((glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform1ivARB")) == NULL) || r;
+ r = ((glUniform2fARB = (PFNGLUNIFORM2FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2fARB")) == NULL) || r;
+ r = ((glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2fvARB")) == NULL) || r;
+ r = ((glUniform2iARB = (PFNGLUNIFORM2IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2iARB")) == NULL) || r;
+ r = ((glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform2ivARB")) == NULL) || r;
+ r = ((glUniform3fARB = (PFNGLUNIFORM3FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3fARB")) == NULL) || r;
+ r = ((glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3fvARB")) == NULL) || r;
+ r = ((glUniform3iARB = (PFNGLUNIFORM3IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3iARB")) == NULL) || r;
+ r = ((glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform3ivARB")) == NULL) || r;
+ r = ((glUniform4fARB = (PFNGLUNIFORM4FARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4fARB")) == NULL) || r;
+ r = ((glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4fvARB")) == NULL) || r;
+ r = ((glUniform4iARB = (PFNGLUNIFORM4IARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4iARB")) == NULL) || r;
+ r = ((glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC)glewGetProcAddress((const GLubyte*)"glUniform4ivARB")) == NULL) || r;
+ r = ((glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix2fvARB")) == NULL) || r;
+ r = ((glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix3fvARB")) == NULL) || r;
+ r = ((glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC)glewGetProcAddress((const GLubyte*)"glUniformMatrix4fvARB")) == NULL) || r;
+ r = ((glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)glewGetProcAddress((const GLubyte*)"glUseProgramObjectARB")) == NULL) || r;
+ r = ((glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glValidateProgramARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_shader_objects */
+
+#ifdef GL_ARB_shader_precision
+
+#endif /* GL_ARB_shader_precision */
+
+#ifdef GL_ARB_shader_stencil_export
+
+#endif /* GL_ARB_shader_stencil_export */
+
+#ifdef GL_ARB_shader_storage_buffer_object
+
+static GLboolean _glewInit_GL_ARB_shader_storage_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC)glewGetProcAddress((const GLubyte*)"glShaderStorageBlockBinding")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_shader_storage_buffer_object */
+
+#ifdef GL_ARB_shader_subroutine
+
+static GLboolean _glewInit_GL_ARB_shader_subroutine (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveSubroutineName")) == NULL) || r;
+ r = ((glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveSubroutineUniformName")) == NULL) || r;
+ r = ((glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveSubroutineUniformiv")) == NULL) || r;
+ r = ((glGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStageiv")) == NULL) || r;
+ r = ((glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetSubroutineIndex")) == NULL) || r;
+ r = ((glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)glewGetProcAddress((const GLubyte*)"glGetSubroutineUniformLocation")) == NULL) || r;
+ r = ((glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformSubroutineuiv")) == NULL) || r;
+ r = ((glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC)glewGetProcAddress((const GLubyte*)"glUniformSubroutinesuiv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_shader_subroutine */
+
+#ifdef GL_ARB_shader_texture_lod
+
+#endif /* GL_ARB_shader_texture_lod */
+
+#ifdef GL_ARB_shading_language_100
+
+#endif /* GL_ARB_shading_language_100 */
+
+#ifdef GL_ARB_shading_language_420pack
+
+#endif /* GL_ARB_shading_language_420pack */
+
+#ifdef GL_ARB_shading_language_include
+
+static GLboolean _glewInit_GL_ARB_shading_language_include (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCompileShaderIncludeARB = (PFNGLCOMPILESHADERINCLUDEARBPROC)glewGetProcAddress((const GLubyte*)"glCompileShaderIncludeARB")) == NULL) || r;
+ r = ((glDeleteNamedStringARB = (PFNGLDELETENAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteNamedStringARB")) == NULL) || r;
+ r = ((glGetNamedStringARB = (PFNGLGETNAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glGetNamedStringARB")) == NULL) || r;
+ r = ((glGetNamedStringivARB = (PFNGLGETNAMEDSTRINGIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetNamedStringivARB")) == NULL) || r;
+ r = ((glIsNamedStringARB = (PFNGLISNAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glIsNamedStringARB")) == NULL) || r;
+ r = ((glNamedStringARB = (PFNGLNAMEDSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glNamedStringARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_shading_language_include */
+
+#ifdef GL_ARB_shading_language_packing
+
+#endif /* GL_ARB_shading_language_packing */
+
+#ifdef GL_ARB_shadow
+
+#endif /* GL_ARB_shadow */
+
+#ifdef GL_ARB_shadow_ambient
+
+#endif /* GL_ARB_shadow_ambient */
+
+#ifdef GL_ARB_sparse_texture
+
+static GLboolean _glewInit_GL_ARB_sparse_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexPageCommitmentARB = (PFNGLTEXPAGECOMMITMENTARBPROC)glewGetProcAddress((const GLubyte*)"glTexPageCommitmentARB")) == NULL) || r;
+ r = ((glTexturePageCommitmentEXT = (PFNGLTEXTUREPAGECOMMITMENTEXTPROC)glewGetProcAddress((const GLubyte*)"glTexturePageCommitmentEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_sparse_texture */
+
+#ifdef GL_ARB_stencil_texturing
+
+#endif /* GL_ARB_stencil_texturing */
+
+#ifdef GL_ARB_sync
+
+static GLboolean _glewInit_GL_ARB_sync (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)glewGetProcAddress((const GLubyte*)"glClientWaitSync")) == NULL) || r;
+ r = ((glDeleteSync = (PFNGLDELETESYNCPROC)glewGetProcAddress((const GLubyte*)"glDeleteSync")) == NULL) || r;
+ r = ((glFenceSync = (PFNGLFENCESYNCPROC)glewGetProcAddress((const GLubyte*)"glFenceSync")) == NULL) || r;
+ r = ((glGetInteger64v = (PFNGLGETINTEGER64VPROC)glewGetProcAddress((const GLubyte*)"glGetInteger64v")) == NULL) || r;
+ r = ((glGetSynciv = (PFNGLGETSYNCIVPROC)glewGetProcAddress((const GLubyte*)"glGetSynciv")) == NULL) || r;
+ r = ((glIsSync = (PFNGLISSYNCPROC)glewGetProcAddress((const GLubyte*)"glIsSync")) == NULL) || r;
+ r = ((glWaitSync = (PFNGLWAITSYNCPROC)glewGetProcAddress((const GLubyte*)"glWaitSync")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_sync */
+
+#ifdef GL_ARB_tessellation_shader
+
+static GLboolean _glewInit_GL_ARB_tessellation_shader (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC)glewGetProcAddress((const GLubyte*)"glPatchParameterfv")) == NULL) || r;
+ r = ((glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)glewGetProcAddress((const GLubyte*)"glPatchParameteri")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_tessellation_shader */
+
+#ifdef GL_ARB_texture_border_clamp
+
+#endif /* GL_ARB_texture_border_clamp */
+
+#ifdef GL_ARB_texture_buffer_object
+
+static GLboolean _glewInit_GL_ARB_texture_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexBufferARB = (PFNGLTEXBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glTexBufferARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_buffer_object */
+
+#ifdef GL_ARB_texture_buffer_object_rgb32
+
+#endif /* GL_ARB_texture_buffer_object_rgb32 */
+
+#ifdef GL_ARB_texture_buffer_range
+
+static GLboolean _glewInit_GL_ARB_texture_buffer_range (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glTexBufferRange")) == NULL) || r;
+ r = ((glTextureBufferRangeEXT = (PFNGLTEXTUREBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureBufferRangeEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_buffer_range */
+
+#ifdef GL_ARB_texture_compression
+
+static GLboolean _glewInit_GL_ARB_texture_compression (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCompressedTexImage1DARB = (PFNGLCOMPRESSEDTEXIMAGE1DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage1DARB")) == NULL) || r;
+ r = ((glCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage2DARB")) == NULL) || r;
+ r = ((glCompressedTexImage3DARB = (PFNGLCOMPRESSEDTEXIMAGE3DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexImage3DARB")) == NULL) || r;
+ r = ((glCompressedTexSubImage1DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage1DARB")) == NULL) || r;
+ r = ((glCompressedTexSubImage2DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage2DARB")) == NULL) || r;
+ r = ((glCompressedTexSubImage3DARB = (PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC)glewGetProcAddress((const GLubyte*)"glCompressedTexSubImage3DARB")) == NULL) || r;
+ r = ((glGetCompressedTexImageARB = (PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTexImageARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_compression */
+
+#ifdef GL_ARB_texture_compression_bptc
+
+#endif /* GL_ARB_texture_compression_bptc */
+
+#ifdef GL_ARB_texture_compression_rgtc
+
+#endif /* GL_ARB_texture_compression_rgtc */
+
+#ifdef GL_ARB_texture_cube_map
+
+#endif /* GL_ARB_texture_cube_map */
+
+#ifdef GL_ARB_texture_cube_map_array
+
+#endif /* GL_ARB_texture_cube_map_array */
+
+#ifdef GL_ARB_texture_env_add
+
+#endif /* GL_ARB_texture_env_add */
+
+#ifdef GL_ARB_texture_env_combine
+
+#endif /* GL_ARB_texture_env_combine */
+
+#ifdef GL_ARB_texture_env_crossbar
+
+#endif /* GL_ARB_texture_env_crossbar */
+
+#ifdef GL_ARB_texture_env_dot3
+
+#endif /* GL_ARB_texture_env_dot3 */
+
+#ifdef GL_ARB_texture_float
+
+#endif /* GL_ARB_texture_float */
+
+#ifdef GL_ARB_texture_gather
+
+#endif /* GL_ARB_texture_gather */
+
+#ifdef GL_ARB_texture_mirror_clamp_to_edge
+
+#endif /* GL_ARB_texture_mirror_clamp_to_edge */
+
+#ifdef GL_ARB_texture_mirrored_repeat
+
+#endif /* GL_ARB_texture_mirrored_repeat */
+
+#ifdef GL_ARB_texture_multisample
+
+static GLboolean _glewInit_GL_ARB_texture_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)glewGetProcAddress((const GLubyte*)"glGetMultisamplefv")) == NULL) || r;
+ r = ((glSampleMaski = (PFNGLSAMPLEMASKIPROC)glewGetProcAddress((const GLubyte*)"glSampleMaski")) == NULL) || r;
+ r = ((glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexImage2DMultisample")) == NULL) || r;
+ r = ((glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DMultisample")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_multisample */
+
+#ifdef GL_ARB_texture_non_power_of_two
+
+#endif /* GL_ARB_texture_non_power_of_two */
+
+#ifdef GL_ARB_texture_query_levels
+
+#endif /* GL_ARB_texture_query_levels */
+
+#ifdef GL_ARB_texture_query_lod
+
+#endif /* GL_ARB_texture_query_lod */
+
+#ifdef GL_ARB_texture_rectangle
+
+#endif /* GL_ARB_texture_rectangle */
+
+#ifdef GL_ARB_texture_rg
+
+#endif /* GL_ARB_texture_rg */
+
+#ifdef GL_ARB_texture_rgb10_a2ui
+
+#endif /* GL_ARB_texture_rgb10_a2ui */
+
+#ifdef GL_ARB_texture_stencil8
+
+#endif /* GL_ARB_texture_stencil8 */
+
+#ifdef GL_ARB_texture_storage
+
+static GLboolean _glewInit_GL_ARB_texture_storage (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)glewGetProcAddress((const GLubyte*)"glTexStorage1D")) == NULL) || r;
+ r = ((glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)glewGetProcAddress((const GLubyte*)"glTexStorage2D")) == NULL) || r;
+ r = ((glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)glewGetProcAddress((const GLubyte*)"glTexStorage3D")) == NULL) || r;
+ r = ((glTextureStorage1DEXT = (PFNGLTEXTURESTORAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage1DEXT")) == NULL) || r;
+ r = ((glTextureStorage2DEXT = (PFNGLTEXTURESTORAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage2DEXT")) == NULL) || r;
+ r = ((glTextureStorage3DEXT = (PFNGLTEXTURESTORAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage3DEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_storage */
+
+#ifdef GL_ARB_texture_storage_multisample
+
+static GLboolean _glewInit_GL_ARB_texture_storage_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexStorage2DMultisample")) == NULL) || r;
+ r = ((glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC)glewGetProcAddress((const GLubyte*)"glTexStorage3DMultisample")) == NULL) || r;
+ r = ((glTextureStorage2DMultisampleEXT = (PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage2DMultisampleEXT")) == NULL) || r;
+ r = ((glTextureStorage3DMultisampleEXT = (PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureStorage3DMultisampleEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_storage_multisample */
+
+#ifdef GL_ARB_texture_swizzle
+
+#endif /* GL_ARB_texture_swizzle */
+
+#ifdef GL_ARB_texture_view
+
+static GLboolean _glewInit_GL_ARB_texture_view (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTextureView = (PFNGLTEXTUREVIEWPROC)glewGetProcAddress((const GLubyte*)"glTextureView")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_texture_view */
+
+#ifdef GL_ARB_timer_query
+
+static GLboolean _glewInit_GL_ARB_timer_query (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjecti64v")) == NULL) || r;
+ r = ((glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectui64v")) == NULL) || r;
+ r = ((glQueryCounter = (PFNGLQUERYCOUNTERPROC)glewGetProcAddress((const GLubyte*)"glQueryCounter")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_timer_query */
+
+#ifdef GL_ARB_transform_feedback2
+
+static GLboolean _glewInit_GL_ARB_transform_feedback2 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glBindTransformFeedback")) == NULL) || r;
+ r = ((glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC)glewGetProcAddress((const GLubyte*)"glDeleteTransformFeedbacks")) == NULL) || r;
+ r = ((glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedback")) == NULL) || r;
+ r = ((glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)glewGetProcAddress((const GLubyte*)"glGenTransformFeedbacks")) == NULL) || r;
+ r = ((glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glIsTransformFeedback")) == NULL) || r;
+ r = ((glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glPauseTransformFeedback")) == NULL) || r;
+ r = ((glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC)glewGetProcAddress((const GLubyte*)"glResumeTransformFeedback")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_transform_feedback2 */
+
+#ifdef GL_ARB_transform_feedback3
+
+static GLboolean _glewInit_GL_ARB_transform_feedback3 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glBeginQueryIndexed")) == NULL) || r;
+ r = ((glDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackStream")) == NULL) || r;
+ r = ((glEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glEndQueryIndexed")) == NULL) || r;
+ r = ((glGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC)glewGetProcAddress((const GLubyte*)"glGetQueryIndexediv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_transform_feedback3 */
+
+#ifdef GL_ARB_transform_feedback_instanced
+
+static GLboolean _glewInit_GL_ARB_transform_feedback_instanced (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackInstanced")) == NULL) || r;
+ r = ((glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackStreamInstanced")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_transform_feedback_instanced */
+
+#ifdef GL_ARB_transpose_matrix
+
+static GLboolean _glewInit_GL_ARB_transpose_matrix (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glLoadTransposeMatrixdARB = (PFNGLLOADTRANSPOSEMATRIXDARBPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixdARB")) == NULL) || r;
+ r = ((glLoadTransposeMatrixfARB = (PFNGLLOADTRANSPOSEMATRIXFARBPROC)glewGetProcAddress((const GLubyte*)"glLoadTransposeMatrixfARB")) == NULL) || r;
+ r = ((glMultTransposeMatrixdARB = (PFNGLMULTTRANSPOSEMATRIXDARBPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixdARB")) == NULL) || r;
+ r = ((glMultTransposeMatrixfARB = (PFNGLMULTTRANSPOSEMATRIXFARBPROC)glewGetProcAddress((const GLubyte*)"glMultTransposeMatrixfARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_transpose_matrix */
+
+#ifdef GL_ARB_uniform_buffer_object
+
+static GLboolean _glewInit_GL_ARB_uniform_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBase")) == NULL) || r;
+ r = ((glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRange")) == NULL) || r;
+ r = ((glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformBlockName")) == NULL) || r;
+ r = ((glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformBlockiv")) == NULL) || r;
+ r = ((glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformName")) == NULL) || r;
+ r = ((glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveUniformsiv")) == NULL) || r;
+ r = ((glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)glewGetProcAddress((const GLubyte*)"glGetIntegeri_v")) == NULL) || r;
+ r = ((glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)glewGetProcAddress((const GLubyte*)"glGetUniformBlockIndex")) == NULL) || r;
+ r = ((glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)glewGetProcAddress((const GLubyte*)"glGetUniformIndices")) == NULL) || r;
+ r = ((glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)glewGetProcAddress((const GLubyte*)"glUniformBlockBinding")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_uniform_buffer_object */
+
+#ifdef GL_ARB_vertex_array_bgra
+
+#endif /* GL_ARB_vertex_array_bgra */
+
+#ifdef GL_ARB_vertex_array_object
+
+static GLboolean _glewInit_GL_ARB_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glBindVertexArray")) == NULL) || r;
+ r = ((glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexArrays")) == NULL) || r;
+ r = ((glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)glewGetProcAddress((const GLubyte*)"glGenVertexArrays")) == NULL) || r;
+ r = ((glIsVertexArray = (PFNGLISVERTEXARRAYPROC)glewGetProcAddress((const GLubyte*)"glIsVertexArray")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_array_object */
+
+#ifdef GL_ARB_vertex_attrib_64bit
+
+static GLboolean _glewInit_GL_ARB_vertex_attrib_64bit (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLdv")) == NULL) || r;
+ r = ((glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1d")) == NULL) || r;
+ r = ((glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1dv")) == NULL) || r;
+ r = ((glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2d")) == NULL) || r;
+ r = ((glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2dv")) == NULL) || r;
+ r = ((glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3d")) == NULL) || r;
+ r = ((glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3dv")) == NULL) || r;
+ r = ((glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4d")) == NULL) || r;
+ r = ((glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4dv")) == NULL) || r;
+ r = ((glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLPointer")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_attrib_64bit */
+
+#ifdef GL_ARB_vertex_attrib_binding
+
+static GLboolean _glewInit_GL_ARB_vertex_attrib_binding (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC)glewGetProcAddress((const GLubyte*)"glBindVertexBuffer")) == NULL) || r;
+ r = ((glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribBinding")) == NULL) || r;
+ r = ((glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribFormat")) == NULL) || r;
+ r = ((glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIFormat")) == NULL) || r;
+ r = ((glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLFormat")) == NULL) || r;
+ r = ((glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC)glewGetProcAddress((const GLubyte*)"glVertexBindingDivisor")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_attrib_binding */
+
+#ifdef GL_ARB_vertex_blend
+
+static GLboolean _glewInit_GL_ARB_vertex_blend (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glVertexBlendARB = (PFNGLVERTEXBLENDARBPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendARB")) == NULL) || r;
+ r = ((glWeightPointerARB = (PFNGLWEIGHTPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glWeightPointerARB")) == NULL) || r;
+ r = ((glWeightbvARB = (PFNGLWEIGHTBVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightbvARB")) == NULL) || r;
+ r = ((glWeightdvARB = (PFNGLWEIGHTDVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightdvARB")) == NULL) || r;
+ r = ((glWeightfvARB = (PFNGLWEIGHTFVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightfvARB")) == NULL) || r;
+ r = ((glWeightivARB = (PFNGLWEIGHTIVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightivARB")) == NULL) || r;
+ r = ((glWeightsvARB = (PFNGLWEIGHTSVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightsvARB")) == NULL) || r;
+ r = ((glWeightubvARB = (PFNGLWEIGHTUBVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightubvARB")) == NULL) || r;
+ r = ((glWeightuivARB = (PFNGLWEIGHTUIVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightuivARB")) == NULL) || r;
+ r = ((glWeightusvARB = (PFNGLWEIGHTUSVARBPROC)glewGetProcAddress((const GLubyte*)"glWeightusvARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_blend */
+
+#ifdef GL_ARB_vertex_buffer_object
+
+static GLboolean _glewInit_GL_ARB_vertex_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindBufferARB = (PFNGLBINDBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glBindBufferARB")) == NULL) || r;
+ r = ((glBufferDataARB = (PFNGLBUFFERDATAARBPROC)glewGetProcAddress((const GLubyte*)"glBufferDataARB")) == NULL) || r;
+ r = ((glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)glewGetProcAddress((const GLubyte*)"glBufferSubDataARB")) == NULL) || r;
+ r = ((glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteBuffersARB")) == NULL) || r;
+ r = ((glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)glewGetProcAddress((const GLubyte*)"glGenBuffersARB")) == NULL) || r;
+ r = ((glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameterivARB")) == NULL) || r;
+ r = ((glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferPointervARB")) == NULL) || r;
+ r = ((glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)glewGetProcAddress((const GLubyte*)"glGetBufferSubDataARB")) == NULL) || r;
+ r = ((glIsBufferARB = (PFNGLISBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glIsBufferARB")) == NULL) || r;
+ r = ((glMapBufferARB = (PFNGLMAPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glMapBufferARB")) == NULL) || r;
+ r = ((glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"glUnmapBufferARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_buffer_object */
+
+#ifdef GL_ARB_vertex_program
+
+static GLboolean _glewInit_GL_ARB_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindProgramARB = (PFNGLBINDPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glBindProgramARB")) == NULL) || r;
+ r = ((glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramsARB")) == NULL) || r;
+ r = ((glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexAttribArrayARB")) == NULL) || r;
+ r = ((glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexAttribArrayARB")) == NULL) || r;
+ r = ((glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)glewGetProcAddress((const GLubyte*)"glGenProgramsARB")) == NULL) || r;
+ r = ((glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramEnvParameterdvARB")) == NULL) || r;
+ r = ((glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramEnvParameterfvARB")) == NULL) || r;
+ r = ((glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramLocalParameterdvARB")) == NULL) || r;
+ r = ((glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramLocalParameterfvARB")) == NULL) || r;
+ r = ((glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStringARB")) == NULL) || r;
+ r = ((glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetProgramivARB")) == NULL) || r;
+ r = ((glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointervARB")) == NULL) || r;
+ r = ((glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdvARB")) == NULL) || r;
+ r = ((glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfvARB")) == NULL) || r;
+ r = ((glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribivARB")) == NULL) || r;
+ r = ((glIsProgramARB = (PFNGLISPROGRAMARBPROC)glewGetProcAddress((const GLubyte*)"glIsProgramARB")) == NULL) || r;
+ r = ((glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4dARB")) == NULL) || r;
+ r = ((glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4dvARB")) == NULL) || r;
+ r = ((glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4fARB")) == NULL) || r;
+ r = ((glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameter4fvARB")) == NULL) || r;
+ r = ((glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4dARB")) == NULL) || r;
+ r = ((glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4dvARB")) == NULL) || r;
+ r = ((glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4fARB")) == NULL) || r;
+ r = ((glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameter4fvARB")) == NULL) || r;
+ r = ((glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"glProgramStringARB")) == NULL) || r;
+ r = ((glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dARB")) == NULL) || r;
+ r = ((glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dvARB")) == NULL) || r;
+ r = ((glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fARB")) == NULL) || r;
+ r = ((glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fvARB")) == NULL) || r;
+ r = ((glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sARB")) == NULL) || r;
+ r = ((glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1svARB")) == NULL) || r;
+ r = ((glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dARB")) == NULL) || r;
+ r = ((glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dvARB")) == NULL) || r;
+ r = ((glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fARB")) == NULL) || r;
+ r = ((glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fvARB")) == NULL) || r;
+ r = ((glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sARB")) == NULL) || r;
+ r = ((glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2svARB")) == NULL) || r;
+ r = ((glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dARB")) == NULL) || r;
+ r = ((glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dvARB")) == NULL) || r;
+ r = ((glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fARB")) == NULL) || r;
+ r = ((glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fvARB")) == NULL) || r;
+ r = ((glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sARB")) == NULL) || r;
+ r = ((glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3svARB")) == NULL) || r;
+ r = ((glVertexAttrib4NbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NbvARB")) == NULL) || r;
+ r = ((glVertexAttrib4NivARB = (PFNGLVERTEXATTRIB4NIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NivARB")) == NULL) || r;
+ r = ((glVertexAttrib4NsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NsvARB")) == NULL) || r;
+ r = ((glVertexAttrib4NubARB = (PFNGLVERTEXATTRIB4NUBARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NubARB")) == NULL) || r;
+ r = ((glVertexAttrib4NubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NubvARB")) == NULL) || r;
+ r = ((glVertexAttrib4NuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NuivARB")) == NULL) || r;
+ r = ((glVertexAttrib4NusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4NusvARB")) == NULL) || r;
+ r = ((glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4bvARB")) == NULL) || r;
+ r = ((glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dARB")) == NULL) || r;
+ r = ((glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dvARB")) == NULL) || r;
+ r = ((glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fARB")) == NULL) || r;
+ r = ((glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fvARB")) == NULL) || r;
+ r = ((glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ivARB")) == NULL) || r;
+ r = ((glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sARB")) == NULL) || r;
+ r = ((glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4svARB")) == NULL) || r;
+ r = ((glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubvARB")) == NULL) || r;
+ r = ((glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4uivARB")) == NULL) || r;
+ r = ((glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4usvARB")) == NULL) || r;
+ r = ((glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointerARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_program */
+
+#ifdef GL_ARB_vertex_shader
+
+static GLboolean _glewInit_GL_ARB_vertex_shader (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glBindAttribLocationARB")) == NULL) || r;
+ r = ((glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC)glewGetProcAddress((const GLubyte*)"glGetActiveAttribARB")) == NULL) || r;
+ r = ((glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)glewGetProcAddress((const GLubyte*)"glGetAttribLocationARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_shader */
+
+#ifdef GL_ARB_vertex_type_10f_11f_11f_rev
+
+#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */
+
+#ifdef GL_ARB_vertex_type_2_10_10_10_rev
+
+static GLboolean _glewInit_GL_ARB_vertex_type_2_10_10_10_rev (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColorP3ui = (PFNGLCOLORP3UIPROC)glewGetProcAddress((const GLubyte*)"glColorP3ui")) == NULL) || r;
+ r = ((glColorP3uiv = (PFNGLCOLORP3UIVPROC)glewGetProcAddress((const GLubyte*)"glColorP3uiv")) == NULL) || r;
+ r = ((glColorP4ui = (PFNGLCOLORP4UIPROC)glewGetProcAddress((const GLubyte*)"glColorP4ui")) == NULL) || r;
+ r = ((glColorP4uiv = (PFNGLCOLORP4UIVPROC)glewGetProcAddress((const GLubyte*)"glColorP4uiv")) == NULL) || r;
+ r = ((glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP1ui")) == NULL) || r;
+ r = ((glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP1uiv")) == NULL) || r;
+ r = ((glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP2ui")) == NULL) || r;
+ r = ((glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP2uiv")) == NULL) || r;
+ r = ((glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP3ui")) == NULL) || r;
+ r = ((glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP3uiv")) == NULL) || r;
+ r = ((glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP4ui")) == NULL) || r;
+ r = ((glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordP4uiv")) == NULL) || r;
+ r = ((glNormalP3ui = (PFNGLNORMALP3UIPROC)glewGetProcAddress((const GLubyte*)"glNormalP3ui")) == NULL) || r;
+ r = ((glNormalP3uiv = (PFNGLNORMALP3UIVPROC)glewGetProcAddress((const GLubyte*)"glNormalP3uiv")) == NULL) || r;
+ r = ((glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorP3ui")) == NULL) || r;
+ r = ((glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorP3uiv")) == NULL) || r;
+ r = ((glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP1ui")) == NULL) || r;
+ r = ((glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP1uiv")) == NULL) || r;
+ r = ((glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP2ui")) == NULL) || r;
+ r = ((glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP2uiv")) == NULL) || r;
+ r = ((glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP3ui")) == NULL) || r;
+ r = ((glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP3uiv")) == NULL) || r;
+ r = ((glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP4ui")) == NULL) || r;
+ r = ((glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordP4uiv")) == NULL) || r;
+ r = ((glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP1ui")) == NULL) || r;
+ r = ((glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP1uiv")) == NULL) || r;
+ r = ((glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP2ui")) == NULL) || r;
+ r = ((glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP2uiv")) == NULL) || r;
+ r = ((glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP3ui")) == NULL) || r;
+ r = ((glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP3uiv")) == NULL) || r;
+ r = ((glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP4ui")) == NULL) || r;
+ r = ((glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribP4uiv")) == NULL) || r;
+ r = ((glVertexP2ui = (PFNGLVERTEXP2UIPROC)glewGetProcAddress((const GLubyte*)"glVertexP2ui")) == NULL) || r;
+ r = ((glVertexP2uiv = (PFNGLVERTEXP2UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexP2uiv")) == NULL) || r;
+ r = ((glVertexP3ui = (PFNGLVERTEXP3UIPROC)glewGetProcAddress((const GLubyte*)"glVertexP3ui")) == NULL) || r;
+ r = ((glVertexP3uiv = (PFNGLVERTEXP3UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexP3uiv")) == NULL) || r;
+ r = ((glVertexP4ui = (PFNGLVERTEXP4UIPROC)glewGetProcAddress((const GLubyte*)"glVertexP4ui")) == NULL) || r;
+ r = ((glVertexP4uiv = (PFNGLVERTEXP4UIVPROC)glewGetProcAddress((const GLubyte*)"glVertexP4uiv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_vertex_type_2_10_10_10_rev */
+
+#ifdef GL_ARB_viewport_array
+
+static GLboolean _glewInit_GL_ARB_viewport_array (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC)glewGetProcAddress((const GLubyte*)"glDepthRangeArrayv")) == NULL) || r;
+ r = ((glDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glDepthRangeIndexed")) == NULL) || r;
+ r = ((glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC)glewGetProcAddress((const GLubyte*)"glGetDoublei_v")) == NULL) || r;
+ r = ((glGetFloati_v = (PFNGLGETFLOATI_VPROC)glewGetProcAddress((const GLubyte*)"glGetFloati_v")) == NULL) || r;
+ r = ((glScissorArrayv = (PFNGLSCISSORARRAYVPROC)glewGetProcAddress((const GLubyte*)"glScissorArrayv")) == NULL) || r;
+ r = ((glScissorIndexed = (PFNGLSCISSORINDEXEDPROC)glewGetProcAddress((const GLubyte*)"glScissorIndexed")) == NULL) || r;
+ r = ((glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC)glewGetProcAddress((const GLubyte*)"glScissorIndexedv")) == NULL) || r;
+ r = ((glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)glewGetProcAddress((const GLubyte*)"glViewportArrayv")) == NULL) || r;
+ r = ((glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC)glewGetProcAddress((const GLubyte*)"glViewportIndexedf")) == NULL) || r;
+ r = ((glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC)glewGetProcAddress((const GLubyte*)"glViewportIndexedfv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_viewport_array */
+
+#ifdef GL_ARB_window_pos
+
+static GLboolean _glewInit_GL_ARB_window_pos (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glWindowPos2dARB = (PFNGLWINDOWPOS2DARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dARB")) == NULL) || r;
+ r = ((glWindowPos2dvARB = (PFNGLWINDOWPOS2DVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dvARB")) == NULL) || r;
+ r = ((glWindowPos2fARB = (PFNGLWINDOWPOS2FARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fARB")) == NULL) || r;
+ r = ((glWindowPos2fvARB = (PFNGLWINDOWPOS2FVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fvARB")) == NULL) || r;
+ r = ((glWindowPos2iARB = (PFNGLWINDOWPOS2IARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iARB")) == NULL) || r;
+ r = ((glWindowPos2ivARB = (PFNGLWINDOWPOS2IVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2ivARB")) == NULL) || r;
+ r = ((glWindowPos2sARB = (PFNGLWINDOWPOS2SARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sARB")) == NULL) || r;
+ r = ((glWindowPos2svARB = (PFNGLWINDOWPOS2SVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2svARB")) == NULL) || r;
+ r = ((glWindowPos3dARB = (PFNGLWINDOWPOS3DARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dARB")) == NULL) || r;
+ r = ((glWindowPos3dvARB = (PFNGLWINDOWPOS3DVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dvARB")) == NULL) || r;
+ r = ((glWindowPos3fARB = (PFNGLWINDOWPOS3FARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fARB")) == NULL) || r;
+ r = ((glWindowPos3fvARB = (PFNGLWINDOWPOS3FVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fvARB")) == NULL) || r;
+ r = ((glWindowPos3iARB = (PFNGLWINDOWPOS3IARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iARB")) == NULL) || r;
+ r = ((glWindowPos3ivARB = (PFNGLWINDOWPOS3IVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3ivARB")) == NULL) || r;
+ r = ((glWindowPos3sARB = (PFNGLWINDOWPOS3SARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sARB")) == NULL) || r;
+ r = ((glWindowPos3svARB = (PFNGLWINDOWPOS3SVARBPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3svARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ARB_window_pos */
+
+#ifdef GL_ATIX_point_sprites
+
+#endif /* GL_ATIX_point_sprites */
+
+#ifdef GL_ATIX_texture_env_combine3
+
+#endif /* GL_ATIX_texture_env_combine3 */
+
+#ifdef GL_ATIX_texture_env_route
+
+#endif /* GL_ATIX_texture_env_route */
+
+#ifdef GL_ATIX_vertex_shader_output_point_size
+
+#endif /* GL_ATIX_vertex_shader_output_point_size */
+
+#ifdef GL_ATI_draw_buffers
+
+static GLboolean _glewInit_GL_ATI_draw_buffers (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawBuffersATI = (PFNGLDRAWBUFFERSATIPROC)glewGetProcAddress((const GLubyte*)"glDrawBuffersATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_draw_buffers */
+
+#ifdef GL_ATI_element_array
+
+static GLboolean _glewInit_GL_ATI_element_array (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawElementArrayATI = (PFNGLDRAWELEMENTARRAYATIPROC)glewGetProcAddress((const GLubyte*)"glDrawElementArrayATI")) == NULL) || r;
+ r = ((glDrawRangeElementArrayATI = (PFNGLDRAWRANGEELEMENTARRAYATIPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementArrayATI")) == NULL) || r;
+ r = ((glElementPointerATI = (PFNGLELEMENTPOINTERATIPROC)glewGetProcAddress((const GLubyte*)"glElementPointerATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_element_array */
+
+#ifdef GL_ATI_envmap_bumpmap
+
+static GLboolean _glewInit_GL_ATI_envmap_bumpmap (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetTexBumpParameterfvATI = (PFNGLGETTEXBUMPPARAMETERFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetTexBumpParameterfvATI")) == NULL) || r;
+ r = ((glGetTexBumpParameterivATI = (PFNGLGETTEXBUMPPARAMETERIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetTexBumpParameterivATI")) == NULL) || r;
+ r = ((glTexBumpParameterfvATI = (PFNGLTEXBUMPPARAMETERFVATIPROC)glewGetProcAddress((const GLubyte*)"glTexBumpParameterfvATI")) == NULL) || r;
+ r = ((glTexBumpParameterivATI = (PFNGLTEXBUMPPARAMETERIVATIPROC)glewGetProcAddress((const GLubyte*)"glTexBumpParameterivATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_envmap_bumpmap */
+
+#ifdef GL_ATI_fragment_shader
+
+static GLboolean _glewInit_GL_ATI_fragment_shader (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAlphaFragmentOp1ATI = (PFNGLALPHAFRAGMENTOP1ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp1ATI")) == NULL) || r;
+ r = ((glAlphaFragmentOp2ATI = (PFNGLALPHAFRAGMENTOP2ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp2ATI")) == NULL) || r;
+ r = ((glAlphaFragmentOp3ATI = (PFNGLALPHAFRAGMENTOP3ATIPROC)glewGetProcAddress((const GLubyte*)"glAlphaFragmentOp3ATI")) == NULL) || r;
+ r = ((glBeginFragmentShaderATI = (PFNGLBEGINFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glBeginFragmentShaderATI")) == NULL) || r;
+ r = ((glBindFragmentShaderATI = (PFNGLBINDFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glBindFragmentShaderATI")) == NULL) || r;
+ r = ((glColorFragmentOp1ATI = (PFNGLCOLORFRAGMENTOP1ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp1ATI")) == NULL) || r;
+ r = ((glColorFragmentOp2ATI = (PFNGLCOLORFRAGMENTOP2ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp2ATI")) == NULL) || r;
+ r = ((glColorFragmentOp3ATI = (PFNGLCOLORFRAGMENTOP3ATIPROC)glewGetProcAddress((const GLubyte*)"glColorFragmentOp3ATI")) == NULL) || r;
+ r = ((glDeleteFragmentShaderATI = (PFNGLDELETEFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glDeleteFragmentShaderATI")) == NULL) || r;
+ r = ((glEndFragmentShaderATI = (PFNGLENDFRAGMENTSHADERATIPROC)glewGetProcAddress((const GLubyte*)"glEndFragmentShaderATI")) == NULL) || r;
+ r = ((glGenFragmentShadersATI = (PFNGLGENFRAGMENTSHADERSATIPROC)glewGetProcAddress((const GLubyte*)"glGenFragmentShadersATI")) == NULL) || r;
+ r = ((glPassTexCoordATI = (PFNGLPASSTEXCOORDATIPROC)glewGetProcAddress((const GLubyte*)"glPassTexCoordATI")) == NULL) || r;
+ r = ((glSampleMapATI = (PFNGLSAMPLEMAPATIPROC)glewGetProcAddress((const GLubyte*)"glSampleMapATI")) == NULL) || r;
+ r = ((glSetFragmentShaderConstantATI = (PFNGLSETFRAGMENTSHADERCONSTANTATIPROC)glewGetProcAddress((const GLubyte*)"glSetFragmentShaderConstantATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_fragment_shader */
+
+#ifdef GL_ATI_map_object_buffer
+
+static GLboolean _glewInit_GL_ATI_map_object_buffer (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMapObjectBufferATI = (PFNGLMAPOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glMapObjectBufferATI")) == NULL) || r;
+ r = ((glUnmapObjectBufferATI = (PFNGLUNMAPOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glUnmapObjectBufferATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_map_object_buffer */
+
+#ifdef GL_ATI_meminfo
+
+#endif /* GL_ATI_meminfo */
+
+#ifdef GL_ATI_pn_triangles
+
+static GLboolean _glewInit_GL_ATI_pn_triangles (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPNTrianglesfATI = (PFNGLPNTRIANGLESFATIPROC)glewGetProcAddress((const GLubyte*)"glPNTrianglesfATI")) == NULL) || r;
+ r = ((glPNTrianglesiATI = (PFNGLPNTRIANGLESIATIPROC)glewGetProcAddress((const GLubyte*)"glPNTrianglesiATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_pn_triangles */
+
+#ifdef GL_ATI_separate_stencil
+
+static GLboolean _glewInit_GL_ATI_separate_stencil (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glStencilFuncSeparateATI = (PFNGLSTENCILFUNCSEPARATEATIPROC)glewGetProcAddress((const GLubyte*)"glStencilFuncSeparateATI")) == NULL) || r;
+ r = ((glStencilOpSeparateATI = (PFNGLSTENCILOPSEPARATEATIPROC)glewGetProcAddress((const GLubyte*)"glStencilOpSeparateATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_separate_stencil */
+
+#ifdef GL_ATI_shader_texture_lod
+
+#endif /* GL_ATI_shader_texture_lod */
+
+#ifdef GL_ATI_text_fragment_shader
+
+#endif /* GL_ATI_text_fragment_shader */
+
+#ifdef GL_ATI_texture_compression_3dc
+
+#endif /* GL_ATI_texture_compression_3dc */
+
+#ifdef GL_ATI_texture_env_combine3
+
+#endif /* GL_ATI_texture_env_combine3 */
+
+#ifdef GL_ATI_texture_float
+
+#endif /* GL_ATI_texture_float */
+
+#ifdef GL_ATI_texture_mirror_once
+
+#endif /* GL_ATI_texture_mirror_once */
+
+#ifdef GL_ATI_vertex_array_object
+
+static GLboolean _glewInit_GL_ATI_vertex_array_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glArrayObjectATI = (PFNGLARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glArrayObjectATI")) == NULL) || r;
+ r = ((glFreeObjectBufferATI = (PFNGLFREEOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glFreeObjectBufferATI")) == NULL) || r;
+ r = ((glGetArrayObjectfvATI = (PFNGLGETARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetArrayObjectfvATI")) == NULL) || r;
+ r = ((glGetArrayObjectivATI = (PFNGLGETARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetArrayObjectivATI")) == NULL) || r;
+ r = ((glGetObjectBufferfvATI = (PFNGLGETOBJECTBUFFERFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetObjectBufferfvATI")) == NULL) || r;
+ r = ((glGetObjectBufferivATI = (PFNGLGETOBJECTBUFFERIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetObjectBufferivATI")) == NULL) || r;
+ r = ((glGetVariantArrayObjectfvATI = (PFNGLGETVARIANTARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVariantArrayObjectfvATI")) == NULL) || r;
+ r = ((glGetVariantArrayObjectivATI = (PFNGLGETVARIANTARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVariantArrayObjectivATI")) == NULL) || r;
+ r = ((glIsObjectBufferATI = (PFNGLISOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glIsObjectBufferATI")) == NULL) || r;
+ r = ((glNewObjectBufferATI = (PFNGLNEWOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glNewObjectBufferATI")) == NULL) || r;
+ r = ((glUpdateObjectBufferATI = (PFNGLUPDATEOBJECTBUFFERATIPROC)glewGetProcAddress((const GLubyte*)"glUpdateObjectBufferATI")) == NULL) || r;
+ r = ((glVariantArrayObjectATI = (PFNGLVARIANTARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glVariantArrayObjectATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_vertex_array_object */
+
+#ifdef GL_ATI_vertex_attrib_array_object
+
+static GLboolean _glewInit_GL_ATI_vertex_attrib_array_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetVertexAttribArrayObjectfvATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribArrayObjectfvATI")) == NULL) || r;
+ r = ((glGetVertexAttribArrayObjectivATI = (PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribArrayObjectivATI")) == NULL) || r;
+ r = ((glVertexAttribArrayObjectATI = (PFNGLVERTEXATTRIBARRAYOBJECTATIPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribArrayObjectATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_vertex_attrib_array_object */
+
+#ifdef GL_ATI_vertex_streams
+
+static GLboolean _glewInit_GL_ATI_vertex_streams (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClientActiveVertexStreamATI = (PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC)glewGetProcAddress((const GLubyte*)"glClientActiveVertexStreamATI")) == NULL) || r;
+ r = ((glNormalStream3bATI = (PFNGLNORMALSTREAM3BATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3bATI")) == NULL) || r;
+ r = ((glNormalStream3bvATI = (PFNGLNORMALSTREAM3BVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3bvATI")) == NULL) || r;
+ r = ((glNormalStream3dATI = (PFNGLNORMALSTREAM3DATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3dATI")) == NULL) || r;
+ r = ((glNormalStream3dvATI = (PFNGLNORMALSTREAM3DVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3dvATI")) == NULL) || r;
+ r = ((glNormalStream3fATI = (PFNGLNORMALSTREAM3FATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3fATI")) == NULL) || r;
+ r = ((glNormalStream3fvATI = (PFNGLNORMALSTREAM3FVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3fvATI")) == NULL) || r;
+ r = ((glNormalStream3iATI = (PFNGLNORMALSTREAM3IATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3iATI")) == NULL) || r;
+ r = ((glNormalStream3ivATI = (PFNGLNORMALSTREAM3IVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3ivATI")) == NULL) || r;
+ r = ((glNormalStream3sATI = (PFNGLNORMALSTREAM3SATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3sATI")) == NULL) || r;
+ r = ((glNormalStream3svATI = (PFNGLNORMALSTREAM3SVATIPROC)glewGetProcAddress((const GLubyte*)"glNormalStream3svATI")) == NULL) || r;
+ r = ((glVertexBlendEnvfATI = (PFNGLVERTEXBLENDENVFATIPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendEnvfATI")) == NULL) || r;
+ r = ((glVertexBlendEnviATI = (PFNGLVERTEXBLENDENVIATIPROC)glewGetProcAddress((const GLubyte*)"glVertexBlendEnviATI")) == NULL) || r;
+ r = ((glVertexStream1dATI = (PFNGLVERTEXSTREAM1DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1dATI")) == NULL) || r;
+ r = ((glVertexStream1dvATI = (PFNGLVERTEXSTREAM1DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1dvATI")) == NULL) || r;
+ r = ((glVertexStream1fATI = (PFNGLVERTEXSTREAM1FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1fATI")) == NULL) || r;
+ r = ((glVertexStream1fvATI = (PFNGLVERTEXSTREAM1FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1fvATI")) == NULL) || r;
+ r = ((glVertexStream1iATI = (PFNGLVERTEXSTREAM1IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1iATI")) == NULL) || r;
+ r = ((glVertexStream1ivATI = (PFNGLVERTEXSTREAM1IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1ivATI")) == NULL) || r;
+ r = ((glVertexStream1sATI = (PFNGLVERTEXSTREAM1SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1sATI")) == NULL) || r;
+ r = ((glVertexStream1svATI = (PFNGLVERTEXSTREAM1SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream1svATI")) == NULL) || r;
+ r = ((glVertexStream2dATI = (PFNGLVERTEXSTREAM2DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2dATI")) == NULL) || r;
+ r = ((glVertexStream2dvATI = (PFNGLVERTEXSTREAM2DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2dvATI")) == NULL) || r;
+ r = ((glVertexStream2fATI = (PFNGLVERTEXSTREAM2FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2fATI")) == NULL) || r;
+ r = ((glVertexStream2fvATI = (PFNGLVERTEXSTREAM2FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2fvATI")) == NULL) || r;
+ r = ((glVertexStream2iATI = (PFNGLVERTEXSTREAM2IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2iATI")) == NULL) || r;
+ r = ((glVertexStream2ivATI = (PFNGLVERTEXSTREAM2IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2ivATI")) == NULL) || r;
+ r = ((glVertexStream2sATI = (PFNGLVERTEXSTREAM2SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2sATI")) == NULL) || r;
+ r = ((glVertexStream2svATI = (PFNGLVERTEXSTREAM2SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream2svATI")) == NULL) || r;
+ r = ((glVertexStream3dATI = (PFNGLVERTEXSTREAM3DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3dATI")) == NULL) || r;
+ r = ((glVertexStream3dvATI = (PFNGLVERTEXSTREAM3DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3dvATI")) == NULL) || r;
+ r = ((glVertexStream3fATI = (PFNGLVERTEXSTREAM3FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3fATI")) == NULL) || r;
+ r = ((glVertexStream3fvATI = (PFNGLVERTEXSTREAM3FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3fvATI")) == NULL) || r;
+ r = ((glVertexStream3iATI = (PFNGLVERTEXSTREAM3IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3iATI")) == NULL) || r;
+ r = ((glVertexStream3ivATI = (PFNGLVERTEXSTREAM3IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3ivATI")) == NULL) || r;
+ r = ((glVertexStream3sATI = (PFNGLVERTEXSTREAM3SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3sATI")) == NULL) || r;
+ r = ((glVertexStream3svATI = (PFNGLVERTEXSTREAM3SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream3svATI")) == NULL) || r;
+ r = ((glVertexStream4dATI = (PFNGLVERTEXSTREAM4DATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4dATI")) == NULL) || r;
+ r = ((glVertexStream4dvATI = (PFNGLVERTEXSTREAM4DVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4dvATI")) == NULL) || r;
+ r = ((glVertexStream4fATI = (PFNGLVERTEXSTREAM4FATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4fATI")) == NULL) || r;
+ r = ((glVertexStream4fvATI = (PFNGLVERTEXSTREAM4FVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4fvATI")) == NULL) || r;
+ r = ((glVertexStream4iATI = (PFNGLVERTEXSTREAM4IATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4iATI")) == NULL) || r;
+ r = ((glVertexStream4ivATI = (PFNGLVERTEXSTREAM4IVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4ivATI")) == NULL) || r;
+ r = ((glVertexStream4sATI = (PFNGLVERTEXSTREAM4SATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4sATI")) == NULL) || r;
+ r = ((glVertexStream4svATI = (PFNGLVERTEXSTREAM4SVATIPROC)glewGetProcAddress((const GLubyte*)"glVertexStream4svATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_ATI_vertex_streams */
+
+#ifdef GL_EXT_422_pixels
+
+#endif /* GL_EXT_422_pixels */
+
+#ifdef GL_EXT_Cg_shader
+
+#endif /* GL_EXT_Cg_shader */
+
+#ifdef GL_EXT_abgr
+
+#endif /* GL_EXT_abgr */
+
+#ifdef GL_EXT_bgra
+
+#endif /* GL_EXT_bgra */
+
+#ifdef GL_EXT_bindable_uniform
+
+static GLboolean _glewInit_GL_EXT_bindable_uniform (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetUniformBufferSizeEXT = (PFNGLGETUNIFORMBUFFERSIZEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformBufferSizeEXT")) == NULL) || r;
+ r = ((glGetUniformOffsetEXT = (PFNGLGETUNIFORMOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformOffsetEXT")) == NULL) || r;
+ r = ((glUniformBufferEXT = (PFNGLUNIFORMBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glUniformBufferEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_bindable_uniform */
+
+#ifdef GL_EXT_blend_color
+
+static GLboolean _glewInit_GL_EXT_blend_color (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendColorEXT = (PFNGLBLENDCOLOREXTPROC)glewGetProcAddress((const GLubyte*)"glBlendColorEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_blend_color */
+
+#ifdef GL_EXT_blend_equation_separate
+
+static GLboolean _glewInit_GL_EXT_blend_equation_separate (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendEquationSeparateEXT = (PFNGLBLENDEQUATIONSEPARATEEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationSeparateEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_blend_equation_separate */
+
+#ifdef GL_EXT_blend_func_separate
+
+static GLboolean _glewInit_GL_EXT_blend_func_separate (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendFuncSeparateEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_blend_func_separate */
+
+#ifdef GL_EXT_blend_logic_op
+
+#endif /* GL_EXT_blend_logic_op */
+
+#ifdef GL_EXT_blend_minmax
+
+static GLboolean _glewInit_GL_EXT_blend_minmax (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glBlendEquationEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_blend_minmax */
+
+#ifdef GL_EXT_blend_subtract
+
+#endif /* GL_EXT_blend_subtract */
+
+#ifdef GL_EXT_clip_volume_hint
+
+#endif /* GL_EXT_clip_volume_hint */
+
+#ifdef GL_EXT_cmyka
+
+#endif /* GL_EXT_cmyka */
+
+#ifdef GL_EXT_color_subtable
+
+static GLboolean _glewInit_GL_EXT_color_subtable (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColorSubTableEXT = (PFNGLCOLORSUBTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glColorSubTableEXT")) == NULL) || r;
+ r = ((glCopyColorSubTableEXT = (PFNGLCOPYCOLORSUBTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyColorSubTableEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_color_subtable */
+
+#ifdef GL_EXT_compiled_vertex_array
+
+static GLboolean _glewInit_GL_EXT_compiled_vertex_array (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glLockArraysEXT = (PFNGLLOCKARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glLockArraysEXT")) == NULL) || r;
+ r = ((glUnlockArraysEXT = (PFNGLUNLOCKARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glUnlockArraysEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_compiled_vertex_array */
+
+#ifdef GL_EXT_convolution
+
+static GLboolean _glewInit_GL_EXT_convolution (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glConvolutionFilter1DEXT = (PFNGLCONVOLUTIONFILTER1DEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter1DEXT")) == NULL) || r;
+ r = ((glConvolutionFilter2DEXT = (PFNGLCONVOLUTIONFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionFilter2DEXT")) == NULL) || r;
+ r = ((glConvolutionParameterfEXT = (PFNGLCONVOLUTIONPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfEXT")) == NULL) || r;
+ r = ((glConvolutionParameterfvEXT = (PFNGLCONVOLUTIONPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterfvEXT")) == NULL) || r;
+ r = ((glConvolutionParameteriEXT = (PFNGLCONVOLUTIONPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameteriEXT")) == NULL) || r;
+ r = ((glConvolutionParameterivEXT = (PFNGLCONVOLUTIONPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glConvolutionParameterivEXT")) == NULL) || r;
+ r = ((glCopyConvolutionFilter1DEXT = (PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter1DEXT")) == NULL) || r;
+ r = ((glCopyConvolutionFilter2DEXT = (PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyConvolutionFilter2DEXT")) == NULL) || r;
+ r = ((glGetConvolutionFilterEXT = (PFNGLGETCONVOLUTIONFILTEREXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionFilterEXT")) == NULL) || r;
+ r = ((glGetConvolutionParameterfvEXT = (PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterfvEXT")) == NULL) || r;
+ r = ((glGetConvolutionParameterivEXT = (PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetConvolutionParameterivEXT")) == NULL) || r;
+ r = ((glGetSeparableFilterEXT = (PFNGLGETSEPARABLEFILTEREXTPROC)glewGetProcAddress((const GLubyte*)"glGetSeparableFilterEXT")) == NULL) || r;
+ r = ((glSeparableFilter2DEXT = (PFNGLSEPARABLEFILTER2DEXTPROC)glewGetProcAddress((const GLubyte*)"glSeparableFilter2DEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_convolution */
+
+#ifdef GL_EXT_coordinate_frame
+
+static GLboolean _glewInit_GL_EXT_coordinate_frame (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBinormalPointerEXT = (PFNGLBINORMALPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glBinormalPointerEXT")) == NULL) || r;
+ r = ((glTangentPointerEXT = (PFNGLTANGENTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glTangentPointerEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_coordinate_frame */
+
+#ifdef GL_EXT_copy_texture
+
+static GLboolean _glewInit_GL_EXT_copy_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyTexImage1DEXT = (PFNGLCOPYTEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexImage1DEXT")) == NULL) || r;
+ r = ((glCopyTexImage2DEXT = (PFNGLCOPYTEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexImage2DEXT")) == NULL) || r;
+ r = ((glCopyTexSubImage1DEXT = (PFNGLCOPYTEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage1DEXT")) == NULL) || r;
+ r = ((glCopyTexSubImage2DEXT = (PFNGLCOPYTEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage2DEXT")) == NULL) || r;
+ r = ((glCopyTexSubImage3DEXT = (PFNGLCOPYTEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTexSubImage3DEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_copy_texture */
+
+#ifdef GL_EXT_cull_vertex
+
+static GLboolean _glewInit_GL_EXT_cull_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCullParameterdvEXT = (PFNGLCULLPARAMETERDVEXTPROC)glewGetProcAddress((const GLubyte*)"glCullParameterdvEXT")) == NULL) || r;
+ r = ((glCullParameterfvEXT = (PFNGLCULLPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glCullParameterfvEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_cull_vertex */
+
+#ifdef GL_EXT_debug_marker
+
+static GLboolean _glewInit_GL_EXT_debug_marker (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glInsertEventMarkerEXT = (PFNGLINSERTEVENTMARKEREXTPROC)glewGetProcAddress((const GLubyte*)"glInsertEventMarkerEXT")) == NULL) || r;
+ r = ((glPopGroupMarkerEXT = (PFNGLPOPGROUPMARKEREXTPROC)glewGetProcAddress((const GLubyte*)"glPopGroupMarkerEXT")) == NULL) || r;
+ r = ((glPushGroupMarkerEXT = (PFNGLPUSHGROUPMARKEREXTPROC)glewGetProcAddress((const GLubyte*)"glPushGroupMarkerEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_debug_marker */
+
+#ifdef GL_EXT_depth_bounds_test
+
+static GLboolean _glewInit_GL_EXT_depth_bounds_test (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDepthBoundsEXT = (PFNGLDEPTHBOUNDSEXTPROC)glewGetProcAddress((const GLubyte*)"glDepthBoundsEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_depth_bounds_test */
+
+#ifdef GL_EXT_direct_state_access
+
+static GLboolean _glewInit_GL_EXT_direct_state_access (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindMultiTextureEXT = (PFNGLBINDMULTITEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindMultiTextureEXT")) == NULL) || r;
+ r = ((glCheckNamedFramebufferStatusEXT = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC)glewGetProcAddress((const GLubyte*)"glCheckNamedFramebufferStatusEXT")) == NULL) || r;
+ r = ((glClientAttribDefaultEXT = (PFNGLCLIENTATTRIBDEFAULTEXTPROC)glewGetProcAddress((const GLubyte*)"glClientAttribDefaultEXT")) == NULL) || r;
+ r = ((glCompressedMultiTexImage1DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage1DEXT")) == NULL) || r;
+ r = ((glCompressedMultiTexImage2DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage2DEXT")) == NULL) || r;
+ r = ((glCompressedMultiTexImage3DEXT = (PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexImage3DEXT")) == NULL) || r;
+ r = ((glCompressedMultiTexSubImage1DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage1DEXT")) == NULL) || r;
+ r = ((glCompressedMultiTexSubImage2DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage2DEXT")) == NULL) || r;
+ r = ((glCompressedMultiTexSubImage3DEXT = (PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedMultiTexSubImage3DEXT")) == NULL) || r;
+ r = ((glCompressedTextureImage1DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage1DEXT")) == NULL) || r;
+ r = ((glCompressedTextureImage2DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage2DEXT")) == NULL) || r;
+ r = ((glCompressedTextureImage3DEXT = (PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureImage3DEXT")) == NULL) || r;
+ r = ((glCompressedTextureSubImage1DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage1DEXT")) == NULL) || r;
+ r = ((glCompressedTextureSubImage2DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage2DEXT")) == NULL) || r;
+ r = ((glCompressedTextureSubImage3DEXT = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCompressedTextureSubImage3DEXT")) == NULL) || r;
+ r = ((glCopyMultiTexImage1DEXT = (PFNGLCOPYMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexImage1DEXT")) == NULL) || r;
+ r = ((glCopyMultiTexImage2DEXT = (PFNGLCOPYMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexImage2DEXT")) == NULL) || r;
+ r = ((glCopyMultiTexSubImage1DEXT = (PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage1DEXT")) == NULL) || r;
+ r = ((glCopyMultiTexSubImage2DEXT = (PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage2DEXT")) == NULL) || r;
+ r = ((glCopyMultiTexSubImage3DEXT = (PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyMultiTexSubImage3DEXT")) == NULL) || r;
+ r = ((glCopyTextureImage1DEXT = (PFNGLCOPYTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureImage1DEXT")) == NULL) || r;
+ r = ((glCopyTextureImage2DEXT = (PFNGLCOPYTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureImage2DEXT")) == NULL) || r;
+ r = ((glCopyTextureSubImage1DEXT = (PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage1DEXT")) == NULL) || r;
+ r = ((glCopyTextureSubImage2DEXT = (PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage2DEXT")) == NULL) || r;
+ r = ((glCopyTextureSubImage3DEXT = (PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glCopyTextureSubImage3DEXT")) == NULL) || r;
+ r = ((glDisableClientStateIndexedEXT = (PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableClientStateIndexedEXT")) == NULL) || r;
+ r = ((glDisableClientStateiEXT = (PFNGLDISABLECLIENTSTATEIEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableClientStateiEXT")) == NULL) || r;
+ r = ((glDisableVertexArrayAttribEXT = (PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexArrayAttribEXT")) == NULL) || r;
+ r = ((glDisableVertexArrayEXT = (PFNGLDISABLEVERTEXARRAYEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVertexArrayEXT")) == NULL) || r;
+ r = ((glEnableClientStateIndexedEXT = (PFNGLENABLECLIENTSTATEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableClientStateIndexedEXT")) == NULL) || r;
+ r = ((glEnableClientStateiEXT = (PFNGLENABLECLIENTSTATEIEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableClientStateiEXT")) == NULL) || r;
+ r = ((glEnableVertexArrayAttribEXT = (PFNGLENABLEVERTEXARRAYATTRIBEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexArrayAttribEXT")) == NULL) || r;
+ r = ((glEnableVertexArrayEXT = (PFNGLENABLEVERTEXARRAYEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVertexArrayEXT")) == NULL) || r;
+ r = ((glFlushMappedNamedBufferRangeEXT = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glFlushMappedNamedBufferRangeEXT")) == NULL) || r;
+ r = ((glFramebufferDrawBufferEXT = (PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferDrawBufferEXT")) == NULL) || r;
+ r = ((glFramebufferDrawBuffersEXT = (PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferDrawBuffersEXT")) == NULL) || r;
+ r = ((glFramebufferReadBufferEXT = (PFNGLFRAMEBUFFERREADBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferReadBufferEXT")) == NULL) || r;
+ r = ((glGenerateMultiTexMipmapEXT = (PFNGLGENERATEMULTITEXMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateMultiTexMipmapEXT")) == NULL) || r;
+ r = ((glGenerateTextureMipmapEXT = (PFNGLGENERATETEXTUREMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateTextureMipmapEXT")) == NULL) || r;
+ r = ((glGetCompressedMultiTexImageEXT = (PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedMultiTexImageEXT")) == NULL) || r;
+ r = ((glGetCompressedTextureImageEXT = (PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetCompressedTextureImageEXT")) == NULL) || r;
+ r = ((glGetDoubleIndexedvEXT = (PFNGLGETDOUBLEINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetDoubleIndexedvEXT")) == NULL) || r;
+ r = ((glGetDoublei_vEXT = (PFNGLGETDOUBLEI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetDoublei_vEXT")) == NULL) || r;
+ r = ((glGetFloatIndexedvEXT = (PFNGLGETFLOATINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFloatIndexedvEXT")) == NULL) || r;
+ r = ((glGetFloati_vEXT = (PFNGLGETFLOATI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFloati_vEXT")) == NULL) || r;
+ r = ((glGetFramebufferParameterivEXT = (PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferParameterivEXT")) == NULL) || r;
+ r = ((glGetMultiTexEnvfvEXT = (PFNGLGETMULTITEXENVFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexEnvfvEXT")) == NULL) || r;
+ r = ((glGetMultiTexEnvivEXT = (PFNGLGETMULTITEXENVIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexEnvivEXT")) == NULL) || r;
+ r = ((glGetMultiTexGendvEXT = (PFNGLGETMULTITEXGENDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGendvEXT")) == NULL) || r;
+ r = ((glGetMultiTexGenfvEXT = (PFNGLGETMULTITEXGENFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGenfvEXT")) == NULL) || r;
+ r = ((glGetMultiTexGenivEXT = (PFNGLGETMULTITEXGENIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexGenivEXT")) == NULL) || r;
+ r = ((glGetMultiTexImageEXT = (PFNGLGETMULTITEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexImageEXT")) == NULL) || r;
+ r = ((glGetMultiTexLevelParameterfvEXT = (PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexLevelParameterfvEXT")) == NULL) || r;
+ r = ((glGetMultiTexLevelParameterivEXT = (PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexLevelParameterivEXT")) == NULL) || r;
+ r = ((glGetMultiTexParameterIivEXT = (PFNGLGETMULTITEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterIivEXT")) == NULL) || r;
+ r = ((glGetMultiTexParameterIuivEXT = (PFNGLGETMULTITEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterIuivEXT")) == NULL) || r;
+ r = ((glGetMultiTexParameterfvEXT = (PFNGLGETMULTITEXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterfvEXT")) == NULL) || r;
+ r = ((glGetMultiTexParameterivEXT = (PFNGLGETMULTITEXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMultiTexParameterivEXT")) == NULL) || r;
+ r = ((glGetNamedBufferParameterivEXT = (PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameterivEXT")) == NULL) || r;
+ r = ((glGetNamedBufferPointervEXT = (PFNGLGETNAMEDBUFFERPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferPointervEXT")) == NULL) || r;
+ r = ((glGetNamedBufferSubDataEXT = (PFNGLGETNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferSubDataEXT")) == NULL) || r;
+ r = ((glGetNamedFramebufferAttachmentParameterivEXT = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedFramebufferAttachmentParameterivEXT")) == NULL) || r;
+ r = ((glGetNamedProgramLocalParameterIivEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterIivEXT")) == NULL) || r;
+ r = ((glGetNamedProgramLocalParameterIuivEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterIuivEXT")) == NULL) || r;
+ r = ((glGetNamedProgramLocalParameterdvEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterdvEXT")) == NULL) || r;
+ r = ((glGetNamedProgramLocalParameterfvEXT = (PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramLocalParameterfvEXT")) == NULL) || r;
+ r = ((glGetNamedProgramStringEXT = (PFNGLGETNAMEDPROGRAMSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramStringEXT")) == NULL) || r;
+ r = ((glGetNamedProgramivEXT = (PFNGLGETNAMEDPROGRAMIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedProgramivEXT")) == NULL) || r;
+ r = ((glGetNamedRenderbufferParameterivEXT = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetNamedRenderbufferParameterivEXT")) == NULL) || r;
+ r = ((glGetPointerIndexedvEXT = (PFNGLGETPOINTERINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointerIndexedvEXT")) == NULL) || r;
+ r = ((glGetPointeri_vEXT = (PFNGLGETPOINTERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPointeri_vEXT")) == NULL) || r;
+ r = ((glGetTextureImageEXT = (PFNGLGETTEXTUREIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureImageEXT")) == NULL) || r;
+ r = ((glGetTextureLevelParameterfvEXT = (PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterfvEXT")) == NULL) || r;
+ r = ((glGetTextureLevelParameterivEXT = (PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureLevelParameterivEXT")) == NULL) || r;
+ r = ((glGetTextureParameterIivEXT = (PFNGLGETTEXTUREPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIivEXT")) == NULL) || r;
+ r = ((glGetTextureParameterIuivEXT = (PFNGLGETTEXTUREPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterIuivEXT")) == NULL) || r;
+ r = ((glGetTextureParameterfvEXT = (PFNGLGETTEXTUREPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterfvEXT")) == NULL) || r;
+ r = ((glGetTextureParameterivEXT = (PFNGLGETTEXTUREPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTextureParameterivEXT")) == NULL) || r;
+ r = ((glGetVertexArrayIntegeri_vEXT = (PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayIntegeri_vEXT")) == NULL) || r;
+ r = ((glGetVertexArrayIntegervEXT = (PFNGLGETVERTEXARRAYINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayIntegervEXT")) == NULL) || r;
+ r = ((glGetVertexArrayPointeri_vEXT = (PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayPointeri_vEXT")) == NULL) || r;
+ r = ((glGetVertexArrayPointervEXT = (PFNGLGETVERTEXARRAYPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexArrayPointervEXT")) == NULL) || r;
+ r = ((glMapNamedBufferEXT = (PFNGLMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferEXT")) == NULL) || r;
+ r = ((glMapNamedBufferRangeEXT = (PFNGLMAPNAMEDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glMapNamedBufferRangeEXT")) == NULL) || r;
+ r = ((glMatrixFrustumEXT = (PFNGLMATRIXFRUSTUMEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixFrustumEXT")) == NULL) || r;
+ r = ((glMatrixLoadIdentityEXT = (PFNGLMATRIXLOADIDENTITYEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadIdentityEXT")) == NULL) || r;
+ r = ((glMatrixLoadTransposedEXT = (PFNGLMATRIXLOADTRANSPOSEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTransposedEXT")) == NULL) || r;
+ r = ((glMatrixLoadTransposefEXT = (PFNGLMATRIXLOADTRANSPOSEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadTransposefEXT")) == NULL) || r;
+ r = ((glMatrixLoaddEXT = (PFNGLMATRIXLOADDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoaddEXT")) == NULL) || r;
+ r = ((glMatrixLoadfEXT = (PFNGLMATRIXLOADFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixLoadfEXT")) == NULL) || r;
+ r = ((glMatrixMultTransposedEXT = (PFNGLMATRIXMULTTRANSPOSEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultTransposedEXT")) == NULL) || r;
+ r = ((glMatrixMultTransposefEXT = (PFNGLMATRIXMULTTRANSPOSEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultTransposefEXT")) == NULL) || r;
+ r = ((glMatrixMultdEXT = (PFNGLMATRIXMULTDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultdEXT")) == NULL) || r;
+ r = ((glMatrixMultfEXT = (PFNGLMATRIXMULTFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixMultfEXT")) == NULL) || r;
+ r = ((glMatrixOrthoEXT = (PFNGLMATRIXORTHOEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixOrthoEXT")) == NULL) || r;
+ r = ((glMatrixPopEXT = (PFNGLMATRIXPOPEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixPopEXT")) == NULL) || r;
+ r = ((glMatrixPushEXT = (PFNGLMATRIXPUSHEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixPushEXT")) == NULL) || r;
+ r = ((glMatrixRotatedEXT = (PFNGLMATRIXROTATEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixRotatedEXT")) == NULL) || r;
+ r = ((glMatrixRotatefEXT = (PFNGLMATRIXROTATEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixRotatefEXT")) == NULL) || r;
+ r = ((glMatrixScaledEXT = (PFNGLMATRIXSCALEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixScaledEXT")) == NULL) || r;
+ r = ((glMatrixScalefEXT = (PFNGLMATRIXSCALEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixScalefEXT")) == NULL) || r;
+ r = ((glMatrixTranslatedEXT = (PFNGLMATRIXTRANSLATEDEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixTranslatedEXT")) == NULL) || r;
+ r = ((glMatrixTranslatefEXT = (PFNGLMATRIXTRANSLATEFEXTPROC)glewGetProcAddress((const GLubyte*)"glMatrixTranslatefEXT")) == NULL) || r;
+ r = ((glMultiTexBufferEXT = (PFNGLMULTITEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexBufferEXT")) == NULL) || r;
+ r = ((glMultiTexCoordPointerEXT = (PFNGLMULTITEXCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoordPointerEXT")) == NULL) || r;
+ r = ((glMultiTexEnvfEXT = (PFNGLMULTITEXENVFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvfEXT")) == NULL) || r;
+ r = ((glMultiTexEnvfvEXT = (PFNGLMULTITEXENVFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvfvEXT")) == NULL) || r;
+ r = ((glMultiTexEnviEXT = (PFNGLMULTITEXENVIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnviEXT")) == NULL) || r;
+ r = ((glMultiTexEnvivEXT = (PFNGLMULTITEXENVIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexEnvivEXT")) == NULL) || r;
+ r = ((glMultiTexGendEXT = (PFNGLMULTITEXGENDEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGendEXT")) == NULL) || r;
+ r = ((glMultiTexGendvEXT = (PFNGLMULTITEXGENDVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGendvEXT")) == NULL) || r;
+ r = ((glMultiTexGenfEXT = (PFNGLMULTITEXGENFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenfEXT")) == NULL) || r;
+ r = ((glMultiTexGenfvEXT = (PFNGLMULTITEXGENFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenfvEXT")) == NULL) || r;
+ r = ((glMultiTexGeniEXT = (PFNGLMULTITEXGENIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGeniEXT")) == NULL) || r;
+ r = ((glMultiTexGenivEXT = (PFNGLMULTITEXGENIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexGenivEXT")) == NULL) || r;
+ r = ((glMultiTexImage1DEXT = (PFNGLMULTITEXIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage1DEXT")) == NULL) || r;
+ r = ((glMultiTexImage2DEXT = (PFNGLMULTITEXIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage2DEXT")) == NULL) || r;
+ r = ((glMultiTexImage3DEXT = (PFNGLMULTITEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexImage3DEXT")) == NULL) || r;
+ r = ((glMultiTexParameterIivEXT = (PFNGLMULTITEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterIivEXT")) == NULL) || r;
+ r = ((glMultiTexParameterIuivEXT = (PFNGLMULTITEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterIuivEXT")) == NULL) || r;
+ r = ((glMultiTexParameterfEXT = (PFNGLMULTITEXPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterfEXT")) == NULL) || r;
+ r = ((glMultiTexParameterfvEXT = (PFNGLMULTITEXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterfvEXT")) == NULL) || r;
+ r = ((glMultiTexParameteriEXT = (PFNGLMULTITEXPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameteriEXT")) == NULL) || r;
+ r = ((glMultiTexParameterivEXT = (PFNGLMULTITEXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexParameterivEXT")) == NULL) || r;
+ r = ((glMultiTexRenderbufferEXT = (PFNGLMULTITEXRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexRenderbufferEXT")) == NULL) || r;
+ r = ((glMultiTexSubImage1DEXT = (PFNGLMULTITEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage1DEXT")) == NULL) || r;
+ r = ((glMultiTexSubImage2DEXT = (PFNGLMULTITEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage2DEXT")) == NULL) || r;
+ r = ((glMultiTexSubImage3DEXT = (PFNGLMULTITEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiTexSubImage3DEXT")) == NULL) || r;
+ r = ((glNamedBufferDataEXT = (PFNGLNAMEDBUFFERDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferDataEXT")) == NULL) || r;
+ r = ((glNamedBufferSubDataEXT = (PFNGLNAMEDBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedBufferSubDataEXT")) == NULL) || r;
+ r = ((glNamedCopyBufferSubDataEXT = (PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedCopyBufferSubDataEXT")) == NULL) || r;
+ r = ((glNamedFramebufferRenderbufferEXT = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferRenderbufferEXT")) == NULL) || r;
+ r = ((glNamedFramebufferTexture1DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture1DEXT")) == NULL) || r;
+ r = ((glNamedFramebufferTexture2DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture2DEXT")) == NULL) || r;
+ r = ((glNamedFramebufferTexture3DEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTexture3DEXT")) == NULL) || r;
+ r = ((glNamedFramebufferTextureEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureEXT")) == NULL) || r;
+ r = ((glNamedFramebufferTextureFaceEXT = (PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureFaceEXT")) == NULL) || r;
+ r = ((glNamedFramebufferTextureLayerEXT = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC)glewGetProcAddress((const GLubyte*)"glNamedFramebufferTextureLayerEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameter4dEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4dEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameter4dvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4dvEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameter4fEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4fEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameter4fvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameter4fvEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameterI4iEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4iEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameterI4ivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4ivEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameterI4uiEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4uiEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameterI4uivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameterI4uivEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParameters4fvEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParameters4fvEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParametersI4ivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParametersI4ivEXT")) == NULL) || r;
+ r = ((glNamedProgramLocalParametersI4uivEXT = (PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramLocalParametersI4uivEXT")) == NULL) || r;
+ r = ((glNamedProgramStringEXT = (PFNGLNAMEDPROGRAMSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedProgramStringEXT")) == NULL) || r;
+ r = ((glNamedRenderbufferStorageEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageEXT")) == NULL) || r;
+ r = ((glNamedRenderbufferStorageMultisampleCoverageEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageMultisampleCoverageEXT")) == NULL) || r;
+ r = ((glNamedRenderbufferStorageMultisampleEXT = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glNamedRenderbufferStorageMultisampleEXT")) == NULL) || r;
+ r = ((glProgramUniform1fEXT = (PFNGLPROGRAMUNIFORM1FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fEXT")) == NULL) || r;
+ r = ((glProgramUniform1fvEXT = (PFNGLPROGRAMUNIFORM1FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1fvEXT")) == NULL) || r;
+ r = ((glProgramUniform1iEXT = (PFNGLPROGRAMUNIFORM1IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1iEXT")) == NULL) || r;
+ r = ((glProgramUniform1ivEXT = (PFNGLPROGRAMUNIFORM1IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ivEXT")) == NULL) || r;
+ r = ((glProgramUniform1uiEXT = (PFNGLPROGRAMUNIFORM1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uiEXT")) == NULL) || r;
+ r = ((glProgramUniform1uivEXT = (PFNGLPROGRAMUNIFORM1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1uivEXT")) == NULL) || r;
+ r = ((glProgramUniform2fEXT = (PFNGLPROGRAMUNIFORM2FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fEXT")) == NULL) || r;
+ r = ((glProgramUniform2fvEXT = (PFNGLPROGRAMUNIFORM2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2fvEXT")) == NULL) || r;
+ r = ((glProgramUniform2iEXT = (PFNGLPROGRAMUNIFORM2IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2iEXT")) == NULL) || r;
+ r = ((glProgramUniform2ivEXT = (PFNGLPROGRAMUNIFORM2IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ivEXT")) == NULL) || r;
+ r = ((glProgramUniform2uiEXT = (PFNGLPROGRAMUNIFORM2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uiEXT")) == NULL) || r;
+ r = ((glProgramUniform2uivEXT = (PFNGLPROGRAMUNIFORM2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2uivEXT")) == NULL) || r;
+ r = ((glProgramUniform3fEXT = (PFNGLPROGRAMUNIFORM3FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fEXT")) == NULL) || r;
+ r = ((glProgramUniform3fvEXT = (PFNGLPROGRAMUNIFORM3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3fvEXT")) == NULL) || r;
+ r = ((glProgramUniform3iEXT = (PFNGLPROGRAMUNIFORM3IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3iEXT")) == NULL) || r;
+ r = ((glProgramUniform3ivEXT = (PFNGLPROGRAMUNIFORM3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ivEXT")) == NULL) || r;
+ r = ((glProgramUniform3uiEXT = (PFNGLPROGRAMUNIFORM3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uiEXT")) == NULL) || r;
+ r = ((glProgramUniform3uivEXT = (PFNGLPROGRAMUNIFORM3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3uivEXT")) == NULL) || r;
+ r = ((glProgramUniform4fEXT = (PFNGLPROGRAMUNIFORM4FEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fEXT")) == NULL) || r;
+ r = ((glProgramUniform4fvEXT = (PFNGLPROGRAMUNIFORM4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4fvEXT")) == NULL) || r;
+ r = ((glProgramUniform4iEXT = (PFNGLPROGRAMUNIFORM4IEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4iEXT")) == NULL) || r;
+ r = ((glProgramUniform4ivEXT = (PFNGLPROGRAMUNIFORM4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ivEXT")) == NULL) || r;
+ r = ((glProgramUniform4uiEXT = (PFNGLPROGRAMUNIFORM4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uiEXT")) == NULL) || r;
+ r = ((glProgramUniform4uivEXT = (PFNGLPROGRAMUNIFORM4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4uivEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix2x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x3fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix2x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix2x4fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix3x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x2fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix3x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix3x4fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix4x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x2fvEXT")) == NULL) || r;
+ r = ((glProgramUniformMatrix4x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformMatrix4x3fvEXT")) == NULL) || r;
+ r = ((glPushClientAttribDefaultEXT = (PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC)glewGetProcAddress((const GLubyte*)"glPushClientAttribDefaultEXT")) == NULL) || r;
+ r = ((glTextureBufferEXT = (PFNGLTEXTUREBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTextureBufferEXT")) == NULL) || r;
+ r = ((glTextureImage1DEXT = (PFNGLTEXTUREIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage1DEXT")) == NULL) || r;
+ r = ((glTextureImage2DEXT = (PFNGLTEXTUREIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage2DEXT")) == NULL) || r;
+ r = ((glTextureImage3DEXT = (PFNGLTEXTUREIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureImage3DEXT")) == NULL) || r;
+ r = ((glTextureParameterIivEXT = (PFNGLTEXTUREPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIivEXT")) == NULL) || r;
+ r = ((glTextureParameterIuivEXT = (PFNGLTEXTUREPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterIuivEXT")) == NULL) || r;
+ r = ((glTextureParameterfEXT = (PFNGLTEXTUREPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterfEXT")) == NULL) || r;
+ r = ((glTextureParameterfvEXT = (PFNGLTEXTUREPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterfvEXT")) == NULL) || r;
+ r = ((glTextureParameteriEXT = (PFNGLTEXTUREPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameteriEXT")) == NULL) || r;
+ r = ((glTextureParameterivEXT = (PFNGLTEXTUREPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureParameterivEXT")) == NULL) || r;
+ r = ((glTextureRenderbufferEXT = (PFNGLTEXTURERENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTextureRenderbufferEXT")) == NULL) || r;
+ r = ((glTextureSubImage1DEXT = (PFNGLTEXTURESUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage1DEXT")) == NULL) || r;
+ r = ((glTextureSubImage2DEXT = (PFNGLTEXTURESUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage2DEXT")) == NULL) || r;
+ r = ((glTextureSubImage3DEXT = (PFNGLTEXTURESUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureSubImage3DEXT")) == NULL) || r;
+ r = ((glUnmapNamedBufferEXT = (PFNGLUNMAPNAMEDBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glUnmapNamedBufferEXT")) == NULL) || r;
+ r = ((glVertexArrayColorOffsetEXT = (PFNGLVERTEXARRAYCOLOROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayColorOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayEdgeFlagOffsetEXT = (PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayEdgeFlagOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayFogCoordOffsetEXT = (PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayFogCoordOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayIndexOffsetEXT = (PFNGLVERTEXARRAYINDEXOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayIndexOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayMultiTexCoordOffsetEXT = (PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayMultiTexCoordOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayNormalOffsetEXT = (PFNGLVERTEXARRAYNORMALOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayNormalOffsetEXT")) == NULL) || r;
+ r = ((glVertexArraySecondaryColorOffsetEXT = (PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArraySecondaryColorOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayTexCoordOffsetEXT = (PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayTexCoordOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayVertexAttribIOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribIOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayVertexAttribOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribOffsetEXT")) == NULL) || r;
+ r = ((glVertexArrayVertexOffsetEXT = (PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexOffsetEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_direct_state_access */
+
+#ifdef GL_EXT_draw_buffers2
+
+static GLboolean _glewInit_GL_EXT_draw_buffers2 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColorMaskIndexedEXT = (PFNGLCOLORMASKINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glColorMaskIndexedEXT")) == NULL) || r;
+ r = ((glDisableIndexedEXT = (PFNGLDISABLEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableIndexedEXT")) == NULL) || r;
+ r = ((glEnableIndexedEXT = (PFNGLENABLEINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableIndexedEXT")) == NULL) || r;
+ r = ((glGetBooleanIndexedvEXT = (PFNGLGETBOOLEANINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetBooleanIndexedvEXT")) == NULL) || r;
+ r = ((glGetIntegerIndexedvEXT = (PFNGLGETINTEGERINDEXEDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerIndexedvEXT")) == NULL) || r;
+ r = ((glIsEnabledIndexedEXT = (PFNGLISENABLEDINDEXEDEXTPROC)glewGetProcAddress((const GLubyte*)"glIsEnabledIndexedEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_draw_buffers2 */
+
+#ifdef GL_EXT_draw_instanced
+
+static GLboolean _glewInit_GL_EXT_draw_instanced (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysInstancedEXT")) == NULL) || r;
+ r = ((glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstancedEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_draw_instanced */
+
+#ifdef GL_EXT_draw_range_elements
+
+static GLboolean _glewInit_GL_EXT_draw_range_elements (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawRangeElementsEXT = (PFNGLDRAWRANGEELEMENTSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawRangeElementsEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_draw_range_elements */
+
+#ifdef GL_EXT_fog_coord
+
+static GLboolean _glewInit_GL_EXT_fog_coord (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointerEXT")) == NULL) || r;
+ r = ((glFogCoorddEXT = (PFNGLFOGCOORDDEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddEXT")) == NULL) || r;
+ r = ((glFogCoorddvEXT = (PFNGLFOGCOORDDVEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoorddvEXT")) == NULL) || r;
+ r = ((glFogCoordfEXT = (PFNGLFOGCOORDFEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfEXT")) == NULL) || r;
+ r = ((glFogCoordfvEXT = (PFNGLFOGCOORDFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFogCoordfvEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_fog_coord */
+
+#ifdef GL_EXT_fragment_lighting
+
+static GLboolean _glewInit_GL_EXT_fragment_lighting (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFragmentColorMaterialEXT = (PFNGLFRAGMENTCOLORMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentColorMaterialEXT")) == NULL) || r;
+ r = ((glFragmentLightModelfEXT = (PFNGLFRAGMENTLIGHTMODELFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfEXT")) == NULL) || r;
+ r = ((glFragmentLightModelfvEXT = (PFNGLFRAGMENTLIGHTMODELFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfvEXT")) == NULL) || r;
+ r = ((glFragmentLightModeliEXT = (PFNGLFRAGMENTLIGHTMODELIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModeliEXT")) == NULL) || r;
+ r = ((glFragmentLightModelivEXT = (PFNGLFRAGMENTLIGHTMODELIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelivEXT")) == NULL) || r;
+ r = ((glFragmentLightfEXT = (PFNGLFRAGMENTLIGHTFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfEXT")) == NULL) || r;
+ r = ((glFragmentLightfvEXT = (PFNGLFRAGMENTLIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfvEXT")) == NULL) || r;
+ r = ((glFragmentLightiEXT = (PFNGLFRAGMENTLIGHTIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightiEXT")) == NULL) || r;
+ r = ((glFragmentLightivEXT = (PFNGLFRAGMENTLIGHTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightivEXT")) == NULL) || r;
+ r = ((glFragmentMaterialfEXT = (PFNGLFRAGMENTMATERIALFEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfEXT")) == NULL) || r;
+ r = ((glFragmentMaterialfvEXT = (PFNGLFRAGMENTMATERIALFVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfvEXT")) == NULL) || r;
+ r = ((glFragmentMaterialiEXT = (PFNGLFRAGMENTMATERIALIEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialiEXT")) == NULL) || r;
+ r = ((glFragmentMaterialivEXT = (PFNGLFRAGMENTMATERIALIVEXTPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialivEXT")) == NULL) || r;
+ r = ((glGetFragmentLightfvEXT = (PFNGLGETFRAGMENTLIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightfvEXT")) == NULL) || r;
+ r = ((glGetFragmentLightivEXT = (PFNGLGETFRAGMENTLIGHTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightivEXT")) == NULL) || r;
+ r = ((glGetFragmentMaterialfvEXT = (PFNGLGETFRAGMENTMATERIALFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialfvEXT")) == NULL) || r;
+ r = ((glGetFragmentMaterialivEXT = (PFNGLGETFRAGMENTMATERIALIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialivEXT")) == NULL) || r;
+ r = ((glLightEnviEXT = (PFNGLLIGHTENVIEXTPROC)glewGetProcAddress((const GLubyte*)"glLightEnviEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_fragment_lighting */
+
+#ifdef GL_EXT_framebuffer_blit
+
+static GLboolean _glewInit_GL_EXT_framebuffer_blit (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBlitFramebufferEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_framebuffer_blit */
+
+#ifdef GL_EXT_framebuffer_multisample
+
+static GLboolean _glewInit_GL_EXT_framebuffer_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_framebuffer_multisample */
+
+#ifdef GL_EXT_framebuffer_multisample_blit_scaled
+
+#endif /* GL_EXT_framebuffer_multisample_blit_scaled */
+
+#ifdef GL_EXT_framebuffer_object
+
+static GLboolean _glewInit_GL_EXT_framebuffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindFramebufferEXT")) == NULL) || r;
+ r = ((glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindRenderbufferEXT")) == NULL) || r;
+ r = ((glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)glewGetProcAddress((const GLubyte*)"glCheckFramebufferStatusEXT")) == NULL) || r;
+ r = ((glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteFramebuffersEXT")) == NULL) || r;
+ r = ((glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteRenderbuffersEXT")) == NULL) || r;
+ r = ((glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferRenderbufferEXT")) == NULL) || r;
+ r = ((glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture1DEXT")) == NULL) || r;
+ r = ((glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture2DEXT")) == NULL) || r;
+ r = ((glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTexture3DEXT")) == NULL) || r;
+ r = ((glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenFramebuffersEXT")) == NULL) || r;
+ r = ((glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenRenderbuffersEXT")) == NULL) || r;
+ r = ((glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)glewGetProcAddress((const GLubyte*)"glGenerateMipmapEXT")) == NULL) || r;
+ r = ((glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFramebufferAttachmentParameterivEXT")) == NULL) || r;
+ r = ((glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetRenderbufferParameterivEXT")) == NULL) || r;
+ r = ((glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glIsFramebufferEXT")) == NULL) || r;
+ r = ((glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glIsRenderbufferEXT")) == NULL) || r;
+ r = ((glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_framebuffer_object */
+
+#ifdef GL_EXT_framebuffer_sRGB
+
+#endif /* GL_EXT_framebuffer_sRGB */
+
+#ifdef GL_EXT_geometry_shader4
+
+static GLboolean _glewInit_GL_EXT_geometry_shader4 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferTextureEXT = (PFNGLFRAMEBUFFERTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureEXT")) == NULL) || r;
+ r = ((glFramebufferTextureFaceEXT = (PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureFaceEXT")) == NULL) || r;
+ r = ((glProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramParameteriEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_geometry_shader4 */
+
+#ifdef GL_EXT_gpu_program_parameters
+
+static GLboolean _glewInit_GL_EXT_gpu_program_parameters (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glProgramEnvParameters4fvEXT = (PFNGLPROGRAMENVPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameters4fvEXT")) == NULL) || r;
+ r = ((glProgramLocalParameters4fvEXT = (PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameters4fvEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_gpu_program_parameters */
+
+#ifdef GL_EXT_gpu_shader4
+
+static GLboolean _glewInit_GL_EXT_gpu_shader4 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindFragDataLocationEXT = (PFNGLBINDFRAGDATALOCATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glBindFragDataLocationEXT")) == NULL) || r;
+ r = ((glGetFragDataLocationEXT = (PFNGLGETFRAGDATALOCATIONEXTPROC)glewGetProcAddress((const GLubyte*)"glGetFragDataLocationEXT")) == NULL) || r;
+ r = ((glGetUniformuivEXT = (PFNGLGETUNIFORMUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetUniformuivEXT")) == NULL) || r;
+ r = ((glGetVertexAttribIivEXT = (PFNGLGETVERTEXATTRIBIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIivEXT")) == NULL) || r;
+ r = ((glGetVertexAttribIuivEXT = (PFNGLGETVERTEXATTRIBIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribIuivEXT")) == NULL) || r;
+ r = ((glUniform1uiEXT = (PFNGLUNIFORM1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform1uiEXT")) == NULL) || r;
+ r = ((glUniform1uivEXT = (PFNGLUNIFORM1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform1uivEXT")) == NULL) || r;
+ r = ((glUniform2uiEXT = (PFNGLUNIFORM2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform2uiEXT")) == NULL) || r;
+ r = ((glUniform2uivEXT = (PFNGLUNIFORM2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform2uivEXT")) == NULL) || r;
+ r = ((glUniform3uiEXT = (PFNGLUNIFORM3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform3uiEXT")) == NULL) || r;
+ r = ((glUniform3uivEXT = (PFNGLUNIFORM3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform3uivEXT")) == NULL) || r;
+ r = ((glUniform4uiEXT = (PFNGLUNIFORM4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform4uiEXT")) == NULL) || r;
+ r = ((glUniform4uivEXT = (PFNGLUNIFORM4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glUniform4uivEXT")) == NULL) || r;
+ r = ((glVertexAttribI1iEXT = (PFNGLVERTEXATTRIBI1IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1iEXT")) == NULL) || r;
+ r = ((glVertexAttribI1ivEXT = (PFNGLVERTEXATTRIBI1IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1ivEXT")) == NULL) || r;
+ r = ((glVertexAttribI1uiEXT = (PFNGLVERTEXATTRIBI1UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uiEXT")) == NULL) || r;
+ r = ((glVertexAttribI1uivEXT = (PFNGLVERTEXATTRIBI1UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI1uivEXT")) == NULL) || r;
+ r = ((glVertexAttribI2iEXT = (PFNGLVERTEXATTRIBI2IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2iEXT")) == NULL) || r;
+ r = ((glVertexAttribI2ivEXT = (PFNGLVERTEXATTRIBI2IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2ivEXT")) == NULL) || r;
+ r = ((glVertexAttribI2uiEXT = (PFNGLVERTEXATTRIBI2UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uiEXT")) == NULL) || r;
+ r = ((glVertexAttribI2uivEXT = (PFNGLVERTEXATTRIBI2UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI2uivEXT")) == NULL) || r;
+ r = ((glVertexAttribI3iEXT = (PFNGLVERTEXATTRIBI3IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3iEXT")) == NULL) || r;
+ r = ((glVertexAttribI3ivEXT = (PFNGLVERTEXATTRIBI3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3ivEXT")) == NULL) || r;
+ r = ((glVertexAttribI3uiEXT = (PFNGLVERTEXATTRIBI3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uiEXT")) == NULL) || r;
+ r = ((glVertexAttribI3uivEXT = (PFNGLVERTEXATTRIBI3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI3uivEXT")) == NULL) || r;
+ r = ((glVertexAttribI4bvEXT = (PFNGLVERTEXATTRIBI4BVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4bvEXT")) == NULL) || r;
+ r = ((glVertexAttribI4iEXT = (PFNGLVERTEXATTRIBI4IEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4iEXT")) == NULL) || r;
+ r = ((glVertexAttribI4ivEXT = (PFNGLVERTEXATTRIBI4IVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ivEXT")) == NULL) || r;
+ r = ((glVertexAttribI4svEXT = (PFNGLVERTEXATTRIBI4SVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4svEXT")) == NULL) || r;
+ r = ((glVertexAttribI4ubvEXT = (PFNGLVERTEXATTRIBI4UBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4ubvEXT")) == NULL) || r;
+ r = ((glVertexAttribI4uiEXT = (PFNGLVERTEXATTRIBI4UIEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uiEXT")) == NULL) || r;
+ r = ((glVertexAttribI4uivEXT = (PFNGLVERTEXATTRIBI4UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4uivEXT")) == NULL) || r;
+ r = ((glVertexAttribI4usvEXT = (PFNGLVERTEXATTRIBI4USVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribI4usvEXT")) == NULL) || r;
+ r = ((glVertexAttribIPointerEXT = (PFNGLVERTEXATTRIBIPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIPointerEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_gpu_shader4 */
+
+#ifdef GL_EXT_histogram
+
+static GLboolean _glewInit_GL_EXT_histogram (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetHistogramEXT = (PFNGLGETHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramEXT")) == NULL) || r;
+ r = ((glGetHistogramParameterfvEXT = (PFNGLGETHISTOGRAMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterfvEXT")) == NULL) || r;
+ r = ((glGetHistogramParameterivEXT = (PFNGLGETHISTOGRAMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetHistogramParameterivEXT")) == NULL) || r;
+ r = ((glGetMinmaxEXT = (PFNGLGETMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxEXT")) == NULL) || r;
+ r = ((glGetMinmaxParameterfvEXT = (PFNGLGETMINMAXPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterfvEXT")) == NULL) || r;
+ r = ((glGetMinmaxParameterivEXT = (PFNGLGETMINMAXPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetMinmaxParameterivEXT")) == NULL) || r;
+ r = ((glHistogramEXT = (PFNGLHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glHistogramEXT")) == NULL) || r;
+ r = ((glMinmaxEXT = (PFNGLMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glMinmaxEXT")) == NULL) || r;
+ r = ((glResetHistogramEXT = (PFNGLRESETHISTOGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glResetHistogramEXT")) == NULL) || r;
+ r = ((glResetMinmaxEXT = (PFNGLRESETMINMAXEXTPROC)glewGetProcAddress((const GLubyte*)"glResetMinmaxEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_histogram */
+
+#ifdef GL_EXT_index_array_formats
+
+#endif /* GL_EXT_index_array_formats */
+
+#ifdef GL_EXT_index_func
+
+static GLboolean _glewInit_GL_EXT_index_func (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glIndexFuncEXT = (PFNGLINDEXFUNCEXTPROC)glewGetProcAddress((const GLubyte*)"glIndexFuncEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_index_func */
+
+#ifdef GL_EXT_index_material
+
+static GLboolean _glewInit_GL_EXT_index_material (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glIndexMaterialEXT = (PFNGLINDEXMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glIndexMaterialEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_index_material */
+
+#ifdef GL_EXT_index_texture
+
+#endif /* GL_EXT_index_texture */
+
+#ifdef GL_EXT_light_texture
+
+static GLboolean _glewInit_GL_EXT_light_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glApplyTextureEXT = (PFNGLAPPLYTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glApplyTextureEXT")) == NULL) || r;
+ r = ((glTextureLightEXT = (PFNGLTEXTURELIGHTEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureLightEXT")) == NULL) || r;
+ r = ((glTextureMaterialEXT = (PFNGLTEXTUREMATERIALEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureMaterialEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_light_texture */
+
+#ifdef GL_EXT_misc_attribute
+
+#endif /* GL_EXT_misc_attribute */
+
+#ifdef GL_EXT_multi_draw_arrays
+
+static GLboolean _glewInit_GL_EXT_multi_draw_arrays (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiDrawArraysEXT = (PFNGLMULTIDRAWARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysEXT")) == NULL) || r;
+ r = ((glMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTSEXTPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_multi_draw_arrays */
+
+#ifdef GL_EXT_multisample
+
+static GLboolean _glewInit_GL_EXT_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSampleMaskEXT = (PFNGLSAMPLEMASKEXTPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskEXT")) == NULL) || r;
+ r = ((glSamplePatternEXT = (PFNGLSAMPLEPATTERNEXTPROC)glewGetProcAddress((const GLubyte*)"glSamplePatternEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_multisample */
+
+#ifdef GL_EXT_packed_depth_stencil
+
+#endif /* GL_EXT_packed_depth_stencil */
+
+#ifdef GL_EXT_packed_float
+
+#endif /* GL_EXT_packed_float */
+
+#ifdef GL_EXT_packed_pixels
+
+#endif /* GL_EXT_packed_pixels */
+
+#ifdef GL_EXT_paletted_texture
+
+static GLboolean _glewInit_GL_EXT_paletted_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColorTableEXT = (PFNGLCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glColorTableEXT")) == NULL) || r;
+ r = ((glGetColorTableEXT = (PFNGLGETCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableEXT")) == NULL) || r;
+ r = ((glGetColorTableParameterfvEXT = (PFNGLGETCOLORTABLEPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfvEXT")) == NULL) || r;
+ r = ((glGetColorTableParameterivEXT = (PFNGLGETCOLORTABLEPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterivEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_paletted_texture */
+
+#ifdef GL_EXT_pixel_buffer_object
+
+#endif /* GL_EXT_pixel_buffer_object */
+
+#ifdef GL_EXT_pixel_transform
+
+static GLboolean _glewInit_GL_EXT_pixel_transform (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetPixelTransformParameterfvEXT = (PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterfvEXT")) == NULL) || r;
+ r = ((glGetPixelTransformParameterivEXT = (PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetPixelTransformParameterivEXT")) == NULL) || r;
+ r = ((glPixelTransformParameterfEXT = (PFNGLPIXELTRANSFORMPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfEXT")) == NULL) || r;
+ r = ((glPixelTransformParameterfvEXT = (PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterfvEXT")) == NULL) || r;
+ r = ((glPixelTransformParameteriEXT = (PFNGLPIXELTRANSFORMPARAMETERIEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameteriEXT")) == NULL) || r;
+ r = ((glPixelTransformParameterivEXT = (PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC)glewGetProcAddress((const GLubyte*)"glPixelTransformParameterivEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_pixel_transform */
+
+#ifdef GL_EXT_pixel_transform_color_table
+
+#endif /* GL_EXT_pixel_transform_color_table */
+
+#ifdef GL_EXT_point_parameters
+
+static GLboolean _glewInit_GL_EXT_point_parameters (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPointParameterfEXT = (PFNGLPOINTPARAMETERFEXTPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfEXT")) == NULL) || r;
+ r = ((glPointParameterfvEXT = (PFNGLPOINTPARAMETERFVEXTPROC)glewGetProcAddress((const GLubyte*)"glPointParameterfvEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_point_parameters */
+
+#ifdef GL_EXT_polygon_offset
+
+static GLboolean _glewInit_GL_EXT_polygon_offset (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPolygonOffsetEXT = (PFNGLPOLYGONOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_polygon_offset */
+
+#ifdef GL_EXT_provoking_vertex
+
+static GLboolean _glewInit_GL_EXT_provoking_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glProvokingVertexEXT = (PFNGLPROVOKINGVERTEXEXTPROC)glewGetProcAddress((const GLubyte*)"glProvokingVertexEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_provoking_vertex */
+
+#ifdef GL_EXT_rescale_normal
+
+#endif /* GL_EXT_rescale_normal */
+
+#ifdef GL_EXT_scene_marker
+
+static GLboolean _glewInit_GL_EXT_scene_marker (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginSceneEXT = (PFNGLBEGINSCENEEXTPROC)glewGetProcAddress((const GLubyte*)"glBeginSceneEXT")) == NULL) || r;
+ r = ((glEndSceneEXT = (PFNGLENDSCENEEXTPROC)glewGetProcAddress((const GLubyte*)"glEndSceneEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_scene_marker */
+
+#ifdef GL_EXT_secondary_color
+
+static GLboolean _glewInit_GL_EXT_secondary_color (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSecondaryColor3bEXT = (PFNGLSECONDARYCOLOR3BEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bEXT")) == NULL) || r;
+ r = ((glSecondaryColor3bvEXT = (PFNGLSECONDARYCOLOR3BVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3bvEXT")) == NULL) || r;
+ r = ((glSecondaryColor3dEXT = (PFNGLSECONDARYCOLOR3DEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dEXT")) == NULL) || r;
+ r = ((glSecondaryColor3dvEXT = (PFNGLSECONDARYCOLOR3DVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3dvEXT")) == NULL) || r;
+ r = ((glSecondaryColor3fEXT = (PFNGLSECONDARYCOLOR3FEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fEXT")) == NULL) || r;
+ r = ((glSecondaryColor3fvEXT = (PFNGLSECONDARYCOLOR3FVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3fvEXT")) == NULL) || r;
+ r = ((glSecondaryColor3iEXT = (PFNGLSECONDARYCOLOR3IEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3iEXT")) == NULL) || r;
+ r = ((glSecondaryColor3ivEXT = (PFNGLSECONDARYCOLOR3IVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ivEXT")) == NULL) || r;
+ r = ((glSecondaryColor3sEXT = (PFNGLSECONDARYCOLOR3SEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3sEXT")) == NULL) || r;
+ r = ((glSecondaryColor3svEXT = (PFNGLSECONDARYCOLOR3SVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3svEXT")) == NULL) || r;
+ r = ((glSecondaryColor3ubEXT = (PFNGLSECONDARYCOLOR3UBEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubEXT")) == NULL) || r;
+ r = ((glSecondaryColor3ubvEXT = (PFNGLSECONDARYCOLOR3UBVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3ubvEXT")) == NULL) || r;
+ r = ((glSecondaryColor3uiEXT = (PFNGLSECONDARYCOLOR3UIEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uiEXT")) == NULL) || r;
+ r = ((glSecondaryColor3uivEXT = (PFNGLSECONDARYCOLOR3UIVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3uivEXT")) == NULL) || r;
+ r = ((glSecondaryColor3usEXT = (PFNGLSECONDARYCOLOR3USEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usEXT")) == NULL) || r;
+ r = ((glSecondaryColor3usvEXT = (PFNGLSECONDARYCOLOR3USVEXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3usvEXT")) == NULL) || r;
+ r = ((glSecondaryColorPointerEXT = (PFNGLSECONDARYCOLORPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointerEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_secondary_color */
+
+#ifdef GL_EXT_separate_shader_objects
+
+static GLboolean _glewInit_GL_EXT_separate_shader_objects (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glActiveProgramEXT = (PFNGLACTIVEPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glActiveProgramEXT")) == NULL) || r;
+ r = ((glCreateShaderProgramEXT = (PFNGLCREATESHADERPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glCreateShaderProgramEXT")) == NULL) || r;
+ r = ((glUseShaderProgramEXT = (PFNGLUSESHADERPROGRAMEXTPROC)glewGetProcAddress((const GLubyte*)"glUseShaderProgramEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_separate_shader_objects */
+
+#ifdef GL_EXT_separate_specular_color
+
+#endif /* GL_EXT_separate_specular_color */
+
+#ifdef GL_EXT_shader_image_load_store
+
+static GLboolean _glewInit_GL_EXT_shader_image_load_store (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindImageTextureEXT = (PFNGLBINDIMAGETEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindImageTextureEXT")) == NULL) || r;
+ r = ((glMemoryBarrierEXT = (PFNGLMEMORYBARRIEREXTPROC)glewGetProcAddress((const GLubyte*)"glMemoryBarrierEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_shader_image_load_store */
+
+#ifdef GL_EXT_shadow_funcs
+
+#endif /* GL_EXT_shadow_funcs */
+
+#ifdef GL_EXT_shared_texture_palette
+
+#endif /* GL_EXT_shared_texture_palette */
+
+#ifdef GL_EXT_stencil_clear_tag
+
+#endif /* GL_EXT_stencil_clear_tag */
+
+#ifdef GL_EXT_stencil_two_side
+
+static GLboolean _glewInit_GL_EXT_stencil_two_side (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)glewGetProcAddress((const GLubyte*)"glActiveStencilFaceEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_stencil_two_side */
+
+#ifdef GL_EXT_stencil_wrap
+
+#endif /* GL_EXT_stencil_wrap */
+
+#ifdef GL_EXT_subtexture
+
+static GLboolean _glewInit_GL_EXT_subtexture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexSubImage1DEXT = (PFNGLTEXSUBIMAGE1DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage1DEXT")) == NULL) || r;
+ r = ((glTexSubImage2DEXT = (PFNGLTEXSUBIMAGE2DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage2DEXT")) == NULL) || r;
+ r = ((glTexSubImage3DEXT = (PFNGLTEXSUBIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage3DEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_subtexture */
+
+#ifdef GL_EXT_texture
+
+#endif /* GL_EXT_texture */
+
+#ifdef GL_EXT_texture3D
+
+static GLboolean _glewInit_GL_EXT_texture3D (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexImage3DEXT = (PFNGLTEXIMAGE3DEXTPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_texture3D */
+
+#ifdef GL_EXT_texture_array
+
+static GLboolean _glewInit_GL_EXT_texture_array (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFramebufferTextureLayerEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC)glewGetProcAddress((const GLubyte*)"glFramebufferTextureLayerEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_texture_array */
+
+#ifdef GL_EXT_texture_buffer_object
+
+static GLboolean _glewInit_GL_EXT_texture_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexBufferEXT = (PFNGLTEXBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"glTexBufferEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_texture_buffer_object */
+
+#ifdef GL_EXT_texture_compression_dxt1
+
+#endif /* GL_EXT_texture_compression_dxt1 */
+
+#ifdef GL_EXT_texture_compression_latc
+
+#endif /* GL_EXT_texture_compression_latc */
+
+#ifdef GL_EXT_texture_compression_rgtc
+
+#endif /* GL_EXT_texture_compression_rgtc */
+
+#ifdef GL_EXT_texture_compression_s3tc
+
+#endif /* GL_EXT_texture_compression_s3tc */
+
+#ifdef GL_EXT_texture_cube_map
+
+#endif /* GL_EXT_texture_cube_map */
+
+#ifdef GL_EXT_texture_edge_clamp
+
+#endif /* GL_EXT_texture_edge_clamp */
+
+#ifdef GL_EXT_texture_env
+
+#endif /* GL_EXT_texture_env */
+
+#ifdef GL_EXT_texture_env_add
+
+#endif /* GL_EXT_texture_env_add */
+
+#ifdef GL_EXT_texture_env_combine
+
+#endif /* GL_EXT_texture_env_combine */
+
+#ifdef GL_EXT_texture_env_dot3
+
+#endif /* GL_EXT_texture_env_dot3 */
+
+#ifdef GL_EXT_texture_filter_anisotropic
+
+#endif /* GL_EXT_texture_filter_anisotropic */
+
+#ifdef GL_EXT_texture_integer
+
+static GLboolean _glewInit_GL_EXT_texture_integer (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClearColorIiEXT = (PFNGLCLEARCOLORIIEXTPROC)glewGetProcAddress((const GLubyte*)"glClearColorIiEXT")) == NULL) || r;
+ r = ((glClearColorIuiEXT = (PFNGLCLEARCOLORIUIEXTPROC)glewGetProcAddress((const GLubyte*)"glClearColorIuiEXT")) == NULL) || r;
+ r = ((glGetTexParameterIivEXT = (PFNGLGETTEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIivEXT")) == NULL) || r;
+ r = ((glGetTexParameterIuivEXT = (PFNGLGETTEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterIuivEXT")) == NULL) || r;
+ r = ((glTexParameterIivEXT = (PFNGLTEXPARAMETERIIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIivEXT")) == NULL) || r;
+ r = ((glTexParameterIuivEXT = (PFNGLTEXPARAMETERIUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glTexParameterIuivEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_texture_integer */
+
+#ifdef GL_EXT_texture_lod_bias
+
+#endif /* GL_EXT_texture_lod_bias */
+
+#ifdef GL_EXT_texture_mirror_clamp
+
+#endif /* GL_EXT_texture_mirror_clamp */
+
+#ifdef GL_EXT_texture_object
+
+static GLboolean _glewInit_GL_EXT_texture_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAreTexturesResidentEXT = (PFNGLARETEXTURESRESIDENTEXTPROC)glewGetProcAddress((const GLubyte*)"glAreTexturesResidentEXT")) == NULL) || r;
+ r = ((glBindTextureEXT = (PFNGLBINDTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glBindTextureEXT")) == NULL) || r;
+ r = ((glDeleteTexturesEXT = (PFNGLDELETETEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteTexturesEXT")) == NULL) || r;
+ r = ((glGenTexturesEXT = (PFNGLGENTEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glGenTexturesEXT")) == NULL) || r;
+ r = ((glIsTextureEXT = (PFNGLISTEXTUREEXTPROC)glewGetProcAddress((const GLubyte*)"glIsTextureEXT")) == NULL) || r;
+ r = ((glPrioritizeTexturesEXT = (PFNGLPRIORITIZETEXTURESEXTPROC)glewGetProcAddress((const GLubyte*)"glPrioritizeTexturesEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_texture_object */
+
+#ifdef GL_EXT_texture_perturb_normal
+
+static GLboolean _glewInit_GL_EXT_texture_perturb_normal (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTextureNormalEXT = (PFNGLTEXTURENORMALEXTPROC)glewGetProcAddress((const GLubyte*)"glTextureNormalEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_texture_perturb_normal */
+
+#ifdef GL_EXT_texture_rectangle
+
+#endif /* GL_EXT_texture_rectangle */
+
+#ifdef GL_EXT_texture_sRGB
+
+#endif /* GL_EXT_texture_sRGB */
+
+#ifdef GL_EXT_texture_sRGB_decode
+
+#endif /* GL_EXT_texture_sRGB_decode */
+
+#ifdef GL_EXT_texture_shared_exponent
+
+#endif /* GL_EXT_texture_shared_exponent */
+
+#ifdef GL_EXT_texture_snorm
+
+#endif /* GL_EXT_texture_snorm */
+
+#ifdef GL_EXT_texture_swizzle
+
+#endif /* GL_EXT_texture_swizzle */
+
+#ifdef GL_EXT_timer_query
+
+static GLboolean _glewInit_GL_EXT_timer_query (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetQueryObjecti64vEXT = (PFNGLGETQUERYOBJECTI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjecti64vEXT")) == NULL) || r;
+ r = ((glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)glewGetProcAddress((const GLubyte*)"glGetQueryObjectui64vEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_timer_query */
+
+#ifdef GL_EXT_transform_feedback
+
+static GLboolean _glewInit_GL_EXT_transform_feedback (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginTransformFeedbackEXT = (PFNGLBEGINTRANSFORMFEEDBACKEXTPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedbackEXT")) == NULL) || r;
+ r = ((glBindBufferBaseEXT = (PFNGLBINDBUFFERBASEEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBaseEXT")) == NULL) || r;
+ r = ((glBindBufferOffsetEXT = (PFNGLBINDBUFFEROFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferOffsetEXT")) == NULL) || r;
+ r = ((glBindBufferRangeEXT = (PFNGLBINDBUFFERRANGEEXTPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRangeEXT")) == NULL) || r;
+ r = ((glEndTransformFeedbackEXT = (PFNGLENDTRANSFORMFEEDBACKEXTPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedbackEXT")) == NULL) || r;
+ r = ((glGetTransformFeedbackVaryingEXT = (PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVaryingEXT")) == NULL) || r;
+ r = ((glTransformFeedbackVaryingsEXT = (PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryingsEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_transform_feedback */
+
+#ifdef GL_EXT_vertex_array
+
+static GLboolean _glewInit_GL_EXT_vertex_array (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glArrayElementEXT = (PFNGLARRAYELEMENTEXTPROC)glewGetProcAddress((const GLubyte*)"glArrayElementEXT")) == NULL) || r;
+ r = ((glColorPointerEXT = (PFNGLCOLORPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glColorPointerEXT")) == NULL) || r;
+ r = ((glDrawArraysEXT = (PFNGLDRAWARRAYSEXTPROC)glewGetProcAddress((const GLubyte*)"glDrawArraysEXT")) == NULL) || r;
+ r = ((glEdgeFlagPointerEXT = (PFNGLEDGEFLAGPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagPointerEXT")) == NULL) || r;
+ r = ((glIndexPointerEXT = (PFNGLINDEXPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glIndexPointerEXT")) == NULL) || r;
+ r = ((glNormalPointerEXT = (PFNGLNORMALPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glNormalPointerEXT")) == NULL) || r;
+ r = ((glTexCoordPointerEXT = (PFNGLTEXCOORDPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointerEXT")) == NULL) || r;
+ r = ((glVertexPointerEXT = (PFNGLVERTEXPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexPointerEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_vertex_array */
+
+#ifdef GL_EXT_vertex_array_bgra
+
+#endif /* GL_EXT_vertex_array_bgra */
+
+#ifdef GL_EXT_vertex_attrib_64bit
+
+static GLboolean _glewInit_GL_EXT_vertex_attrib_64bit (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetVertexAttribLdvEXT = (PFNGLGETVERTEXATTRIBLDVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLdvEXT")) == NULL) || r;
+ r = ((glVertexArrayVertexAttribLOffsetEXT = (PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayVertexAttribLOffsetEXT")) == NULL) || r;
+ r = ((glVertexAttribL1dEXT = (PFNGLVERTEXATTRIBL1DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1dEXT")) == NULL) || r;
+ r = ((glVertexAttribL1dvEXT = (PFNGLVERTEXATTRIBL1DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1dvEXT")) == NULL) || r;
+ r = ((glVertexAttribL2dEXT = (PFNGLVERTEXATTRIBL2DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2dEXT")) == NULL) || r;
+ r = ((glVertexAttribL2dvEXT = (PFNGLVERTEXATTRIBL2DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2dvEXT")) == NULL) || r;
+ r = ((glVertexAttribL3dEXT = (PFNGLVERTEXATTRIBL3DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3dEXT")) == NULL) || r;
+ r = ((glVertexAttribL3dvEXT = (PFNGLVERTEXATTRIBL3DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3dvEXT")) == NULL) || r;
+ r = ((glVertexAttribL4dEXT = (PFNGLVERTEXATTRIBL4DEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4dEXT")) == NULL) || r;
+ r = ((glVertexAttribL4dvEXT = (PFNGLVERTEXATTRIBL4DVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4dvEXT")) == NULL) || r;
+ r = ((glVertexAttribLPointerEXT = (PFNGLVERTEXATTRIBLPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLPointerEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_vertex_attrib_64bit */
+
+#ifdef GL_EXT_vertex_shader
+
+static GLboolean _glewInit_GL_EXT_vertex_shader (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginVertexShaderEXT = (PFNGLBEGINVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glBeginVertexShaderEXT")) == NULL) || r;
+ r = ((glBindLightParameterEXT = (PFNGLBINDLIGHTPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindLightParameterEXT")) == NULL) || r;
+ r = ((glBindMaterialParameterEXT = (PFNGLBINDMATERIALPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindMaterialParameterEXT")) == NULL) || r;
+ r = ((glBindParameterEXT = (PFNGLBINDPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindParameterEXT")) == NULL) || r;
+ r = ((glBindTexGenParameterEXT = (PFNGLBINDTEXGENPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindTexGenParameterEXT")) == NULL) || r;
+ r = ((glBindTextureUnitParameterEXT = (PFNGLBINDTEXTUREUNITPARAMETEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindTextureUnitParameterEXT")) == NULL) || r;
+ r = ((glBindVertexShaderEXT = (PFNGLBINDVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glBindVertexShaderEXT")) == NULL) || r;
+ r = ((glDeleteVertexShaderEXT = (PFNGLDELETEVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glDeleteVertexShaderEXT")) == NULL) || r;
+ r = ((glDisableVariantClientStateEXT = (PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC)glewGetProcAddress((const GLubyte*)"glDisableVariantClientStateEXT")) == NULL) || r;
+ r = ((glEnableVariantClientStateEXT = (PFNGLENABLEVARIANTCLIENTSTATEEXTPROC)glewGetProcAddress((const GLubyte*)"glEnableVariantClientStateEXT")) == NULL) || r;
+ r = ((glEndVertexShaderEXT = (PFNGLENDVERTEXSHADEREXTPROC)glewGetProcAddress((const GLubyte*)"glEndVertexShaderEXT")) == NULL) || r;
+ r = ((glExtractComponentEXT = (PFNGLEXTRACTCOMPONENTEXTPROC)glewGetProcAddress((const GLubyte*)"glExtractComponentEXT")) == NULL) || r;
+ r = ((glGenSymbolsEXT = (PFNGLGENSYMBOLSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenSymbolsEXT")) == NULL) || r;
+ r = ((glGenVertexShadersEXT = (PFNGLGENVERTEXSHADERSEXTPROC)glewGetProcAddress((const GLubyte*)"glGenVertexShadersEXT")) == NULL) || r;
+ r = ((glGetInvariantBooleanvEXT = (PFNGLGETINVARIANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantBooleanvEXT")) == NULL) || r;
+ r = ((glGetInvariantFloatvEXT = (PFNGLGETINVARIANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantFloatvEXT")) == NULL) || r;
+ r = ((glGetInvariantIntegervEXT = (PFNGLGETINVARIANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetInvariantIntegervEXT")) == NULL) || r;
+ r = ((glGetLocalConstantBooleanvEXT = (PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantBooleanvEXT")) == NULL) || r;
+ r = ((glGetLocalConstantFloatvEXT = (PFNGLGETLOCALCONSTANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantFloatvEXT")) == NULL) || r;
+ r = ((glGetLocalConstantIntegervEXT = (PFNGLGETLOCALCONSTANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetLocalConstantIntegervEXT")) == NULL) || r;
+ r = ((glGetVariantBooleanvEXT = (PFNGLGETVARIANTBOOLEANVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantBooleanvEXT")) == NULL) || r;
+ r = ((glGetVariantFloatvEXT = (PFNGLGETVARIANTFLOATVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantFloatvEXT")) == NULL) || r;
+ r = ((glGetVariantIntegervEXT = (PFNGLGETVARIANTINTEGERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantIntegervEXT")) == NULL) || r;
+ r = ((glGetVariantPointervEXT = (PFNGLGETVARIANTPOINTERVEXTPROC)glewGetProcAddress((const GLubyte*)"glGetVariantPointervEXT")) == NULL) || r;
+ r = ((glInsertComponentEXT = (PFNGLINSERTCOMPONENTEXTPROC)glewGetProcAddress((const GLubyte*)"glInsertComponentEXT")) == NULL) || r;
+ r = ((glIsVariantEnabledEXT = (PFNGLISVARIANTENABLEDEXTPROC)glewGetProcAddress((const GLubyte*)"glIsVariantEnabledEXT")) == NULL) || r;
+ r = ((glSetInvariantEXT = (PFNGLSETINVARIANTEXTPROC)glewGetProcAddress((const GLubyte*)"glSetInvariantEXT")) == NULL) || r;
+ r = ((glSetLocalConstantEXT = (PFNGLSETLOCALCONSTANTEXTPROC)glewGetProcAddress((const GLubyte*)"glSetLocalConstantEXT")) == NULL) || r;
+ r = ((glShaderOp1EXT = (PFNGLSHADEROP1EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp1EXT")) == NULL) || r;
+ r = ((glShaderOp2EXT = (PFNGLSHADEROP2EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp2EXT")) == NULL) || r;
+ r = ((glShaderOp3EXT = (PFNGLSHADEROP3EXTPROC)glewGetProcAddress((const GLubyte*)"glShaderOp3EXT")) == NULL) || r;
+ r = ((glSwizzleEXT = (PFNGLSWIZZLEEXTPROC)glewGetProcAddress((const GLubyte*)"glSwizzleEXT")) == NULL) || r;
+ r = ((glVariantPointerEXT = (PFNGLVARIANTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVariantPointerEXT")) == NULL) || r;
+ r = ((glVariantbvEXT = (PFNGLVARIANTBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantbvEXT")) == NULL) || r;
+ r = ((glVariantdvEXT = (PFNGLVARIANTDVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantdvEXT")) == NULL) || r;
+ r = ((glVariantfvEXT = (PFNGLVARIANTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantfvEXT")) == NULL) || r;
+ r = ((glVariantivEXT = (PFNGLVARIANTIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantivEXT")) == NULL) || r;
+ r = ((glVariantsvEXT = (PFNGLVARIANTSVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantsvEXT")) == NULL) || r;
+ r = ((glVariantubvEXT = (PFNGLVARIANTUBVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantubvEXT")) == NULL) || r;
+ r = ((glVariantuivEXT = (PFNGLVARIANTUIVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantuivEXT")) == NULL) || r;
+ r = ((glVariantusvEXT = (PFNGLVARIANTUSVEXTPROC)glewGetProcAddress((const GLubyte*)"glVariantusvEXT")) == NULL) || r;
+ r = ((glWriteMaskEXT = (PFNGLWRITEMASKEXTPROC)glewGetProcAddress((const GLubyte*)"glWriteMaskEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_vertex_shader */
+
+#ifdef GL_EXT_vertex_weighting
+
+static GLboolean _glewInit_GL_EXT_vertex_weighting (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glVertexWeightPointerEXT = (PFNGLVERTEXWEIGHTPOINTEREXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightPointerEXT")) == NULL) || r;
+ r = ((glVertexWeightfEXT = (PFNGLVERTEXWEIGHTFEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightfEXT")) == NULL) || r;
+ r = ((glVertexWeightfvEXT = (PFNGLVERTEXWEIGHTFVEXTPROC)glewGetProcAddress((const GLubyte*)"glVertexWeightfvEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_vertex_weighting */
+
+#ifdef GL_EXT_x11_sync_object
+
+static GLboolean _glewInit_GL_EXT_x11_sync_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glImportSyncEXT = (PFNGLIMPORTSYNCEXTPROC)glewGetProcAddress((const GLubyte*)"glImportSyncEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_EXT_x11_sync_object */
+
+#ifdef GL_GREMEDY_frame_terminator
+
+static GLboolean _glewInit_GL_GREMEDY_frame_terminator (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFrameTerminatorGREMEDY = (PFNGLFRAMETERMINATORGREMEDYPROC)glewGetProcAddress((const GLubyte*)"glFrameTerminatorGREMEDY")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_GREMEDY_frame_terminator */
+
+#ifdef GL_GREMEDY_string_marker
+
+static GLboolean _glewInit_GL_GREMEDY_string_marker (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glStringMarkerGREMEDY = (PFNGLSTRINGMARKERGREMEDYPROC)glewGetProcAddress((const GLubyte*)"glStringMarkerGREMEDY")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_GREMEDY_string_marker */
+
+#ifdef GL_HP_convolution_border_modes
+
+#endif /* GL_HP_convolution_border_modes */
+
+#ifdef GL_HP_image_transform
+
+static GLboolean _glewInit_GL_HP_image_transform (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetImageTransformParameterfvHP = (PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC)glewGetProcAddress((const GLubyte*)"glGetImageTransformParameterfvHP")) == NULL) || r;
+ r = ((glGetImageTransformParameterivHP = (PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC)glewGetProcAddress((const GLubyte*)"glGetImageTransformParameterivHP")) == NULL) || r;
+ r = ((glImageTransformParameterfHP = (PFNGLIMAGETRANSFORMPARAMETERFHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterfHP")) == NULL) || r;
+ r = ((glImageTransformParameterfvHP = (PFNGLIMAGETRANSFORMPARAMETERFVHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterfvHP")) == NULL) || r;
+ r = ((glImageTransformParameteriHP = (PFNGLIMAGETRANSFORMPARAMETERIHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameteriHP")) == NULL) || r;
+ r = ((glImageTransformParameterivHP = (PFNGLIMAGETRANSFORMPARAMETERIVHPPROC)glewGetProcAddress((const GLubyte*)"glImageTransformParameterivHP")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_HP_image_transform */
+
+#ifdef GL_HP_occlusion_test
+
+#endif /* GL_HP_occlusion_test */
+
+#ifdef GL_HP_texture_lighting
+
+#endif /* GL_HP_texture_lighting */
+
+#ifdef GL_IBM_cull_vertex
+
+#endif /* GL_IBM_cull_vertex */
+
+#ifdef GL_IBM_multimode_draw_arrays
+
+static GLboolean _glewInit_GL_IBM_multimode_draw_arrays (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiModeDrawArraysIBM = (PFNGLMULTIMODEDRAWARRAYSIBMPROC)glewGetProcAddress((const GLubyte*)"glMultiModeDrawArraysIBM")) == NULL) || r;
+ r = ((glMultiModeDrawElementsIBM = (PFNGLMULTIMODEDRAWELEMENTSIBMPROC)glewGetProcAddress((const GLubyte*)"glMultiModeDrawElementsIBM")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_IBM_multimode_draw_arrays */
+
+#ifdef GL_IBM_rasterpos_clip
+
+#endif /* GL_IBM_rasterpos_clip */
+
+#ifdef GL_IBM_static_data
+
+#endif /* GL_IBM_static_data */
+
+#ifdef GL_IBM_texture_mirrored_repeat
+
+#endif /* GL_IBM_texture_mirrored_repeat */
+
+#ifdef GL_IBM_vertex_array_lists
+
+static GLboolean _glewInit_GL_IBM_vertex_array_lists (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColorPointerListIBM = (PFNGLCOLORPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glColorPointerListIBM")) == NULL) || r;
+ r = ((glEdgeFlagPointerListIBM = (PFNGLEDGEFLAGPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagPointerListIBM")) == NULL) || r;
+ r = ((glFogCoordPointerListIBM = (PFNGLFOGCOORDPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glFogCoordPointerListIBM")) == NULL) || r;
+ r = ((glIndexPointerListIBM = (PFNGLINDEXPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glIndexPointerListIBM")) == NULL) || r;
+ r = ((glNormalPointerListIBM = (PFNGLNORMALPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glNormalPointerListIBM")) == NULL) || r;
+ r = ((glSecondaryColorPointerListIBM = (PFNGLSECONDARYCOLORPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorPointerListIBM")) == NULL) || r;
+ r = ((glTexCoordPointerListIBM = (PFNGLTEXCOORDPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointerListIBM")) == NULL) || r;
+ r = ((glVertexPointerListIBM = (PFNGLVERTEXPOINTERLISTIBMPROC)glewGetProcAddress((const GLubyte*)"glVertexPointerListIBM")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_IBM_vertex_array_lists */
+
+#ifdef GL_INGR_color_clamp
+
+#endif /* GL_INGR_color_clamp */
+
+#ifdef GL_INGR_interlace_read
+
+#endif /* GL_INGR_interlace_read */
+
+#ifdef GL_INTEL_map_texture
+
+static GLboolean _glewInit_GL_INTEL_map_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMapTexture2DINTEL = (PFNGLMAPTEXTURE2DINTELPROC)glewGetProcAddress((const GLubyte*)"glMapTexture2DINTEL")) == NULL) || r;
+ r = ((glSyncTextureINTEL = (PFNGLSYNCTEXTUREINTELPROC)glewGetProcAddress((const GLubyte*)"glSyncTextureINTEL")) == NULL) || r;
+ r = ((glUnmapTexture2DINTEL = (PFNGLUNMAPTEXTURE2DINTELPROC)glewGetProcAddress((const GLubyte*)"glUnmapTexture2DINTEL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_INTEL_map_texture */
+
+#ifdef GL_INTEL_parallel_arrays
+
+static GLboolean _glewInit_GL_INTEL_parallel_arrays (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColorPointervINTEL = (PFNGLCOLORPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glColorPointervINTEL")) == NULL) || r;
+ r = ((glNormalPointervINTEL = (PFNGLNORMALPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glNormalPointervINTEL")) == NULL) || r;
+ r = ((glTexCoordPointervINTEL = (PFNGLTEXCOORDPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glTexCoordPointervINTEL")) == NULL) || r;
+ r = ((glVertexPointervINTEL = (PFNGLVERTEXPOINTERVINTELPROC)glewGetProcAddress((const GLubyte*)"glVertexPointervINTEL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_INTEL_parallel_arrays */
+
+#ifdef GL_INTEL_texture_scissor
+
+static GLboolean _glewInit_GL_INTEL_texture_scissor (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexScissorFuncINTEL = (PFNGLTEXSCISSORFUNCINTELPROC)glewGetProcAddress((const GLubyte*)"glTexScissorFuncINTEL")) == NULL) || r;
+ r = ((glTexScissorINTEL = (PFNGLTEXSCISSORINTELPROC)glewGetProcAddress((const GLubyte*)"glTexScissorINTEL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_INTEL_texture_scissor */
+
+#ifdef GL_KHR_debug
+
+static GLboolean _glewInit_GL_KHR_debug (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageCallback")) == NULL) || r;
+ r = ((glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageControl")) == NULL) || r;
+ r = ((glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC)glewGetProcAddress((const GLubyte*)"glDebugMessageInsert")) == NULL) || r;
+ r = ((glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC)glewGetProcAddress((const GLubyte*)"glGetDebugMessageLog")) == NULL) || r;
+ r = ((glGetObjectLabel = (PFNGLGETOBJECTLABELPROC)glewGetProcAddress((const GLubyte*)"glGetObjectLabel")) == NULL) || r;
+ r = ((glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC)glewGetProcAddress((const GLubyte*)"glGetObjectPtrLabel")) == NULL) || r;
+ r = ((glObjectLabel = (PFNGLOBJECTLABELPROC)glewGetProcAddress((const GLubyte*)"glObjectLabel")) == NULL) || r;
+ r = ((glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC)glewGetProcAddress((const GLubyte*)"glObjectPtrLabel")) == NULL) || r;
+ r = ((glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC)glewGetProcAddress((const GLubyte*)"glPopDebugGroup")) == NULL) || r;
+ r = ((glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC)glewGetProcAddress((const GLubyte*)"glPushDebugGroup")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_KHR_debug */
+
+#ifdef GL_KHR_texture_compression_astc_ldr
+
+#endif /* GL_KHR_texture_compression_astc_ldr */
+
+#ifdef GL_KTX_buffer_region
+
+static GLboolean _glewInit_GL_KTX_buffer_region (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBufferRegionEnabled = (PFNGLBUFFERREGIONENABLEDPROC)glewGetProcAddress((const GLubyte*)"glBufferRegionEnabled")) == NULL) || r;
+ r = ((glDeleteBufferRegion = (PFNGLDELETEBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glDeleteBufferRegion")) == NULL) || r;
+ r = ((glDrawBufferRegion = (PFNGLDRAWBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glDrawBufferRegion")) == NULL) || r;
+ r = ((glNewBufferRegion = (PFNGLNEWBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glNewBufferRegion")) == NULL) || r;
+ r = ((glReadBufferRegion = (PFNGLREADBUFFERREGIONPROC)glewGetProcAddress((const GLubyte*)"glReadBufferRegion")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_KTX_buffer_region */
+
+#ifdef GL_MESAX_texture_stack
+
+#endif /* GL_MESAX_texture_stack */
+
+#ifdef GL_MESA_pack_invert
+
+#endif /* GL_MESA_pack_invert */
+
+#ifdef GL_MESA_resize_buffers
+
+static GLboolean _glewInit_GL_MESA_resize_buffers (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glResizeBuffersMESA = (PFNGLRESIZEBUFFERSMESAPROC)glewGetProcAddress((const GLubyte*)"glResizeBuffersMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_MESA_resize_buffers */
+
+#ifdef GL_MESA_window_pos
+
+static GLboolean _glewInit_GL_MESA_window_pos (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glWindowPos2dMESA = (PFNGLWINDOWPOS2DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dMESA")) == NULL) || r;
+ r = ((glWindowPos2dvMESA = (PFNGLWINDOWPOS2DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2dvMESA")) == NULL) || r;
+ r = ((glWindowPos2fMESA = (PFNGLWINDOWPOS2FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fMESA")) == NULL) || r;
+ r = ((glWindowPos2fvMESA = (PFNGLWINDOWPOS2FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2fvMESA")) == NULL) || r;
+ r = ((glWindowPos2iMESA = (PFNGLWINDOWPOS2IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2iMESA")) == NULL) || r;
+ r = ((glWindowPos2ivMESA = (PFNGLWINDOWPOS2IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2ivMESA")) == NULL) || r;
+ r = ((glWindowPos2sMESA = (PFNGLWINDOWPOS2SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2sMESA")) == NULL) || r;
+ r = ((glWindowPos2svMESA = (PFNGLWINDOWPOS2SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos2svMESA")) == NULL) || r;
+ r = ((glWindowPos3dMESA = (PFNGLWINDOWPOS3DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dMESA")) == NULL) || r;
+ r = ((glWindowPos3dvMESA = (PFNGLWINDOWPOS3DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3dvMESA")) == NULL) || r;
+ r = ((glWindowPos3fMESA = (PFNGLWINDOWPOS3FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fMESA")) == NULL) || r;
+ r = ((glWindowPos3fvMESA = (PFNGLWINDOWPOS3FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3fvMESA")) == NULL) || r;
+ r = ((glWindowPos3iMESA = (PFNGLWINDOWPOS3IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3iMESA")) == NULL) || r;
+ r = ((glWindowPos3ivMESA = (PFNGLWINDOWPOS3IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3ivMESA")) == NULL) || r;
+ r = ((glWindowPos3sMESA = (PFNGLWINDOWPOS3SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3sMESA")) == NULL) || r;
+ r = ((glWindowPos3svMESA = (PFNGLWINDOWPOS3SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos3svMESA")) == NULL) || r;
+ r = ((glWindowPos4dMESA = (PFNGLWINDOWPOS4DMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4dMESA")) == NULL) || r;
+ r = ((glWindowPos4dvMESA = (PFNGLWINDOWPOS4DVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4dvMESA")) == NULL) || r;
+ r = ((glWindowPos4fMESA = (PFNGLWINDOWPOS4FMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4fMESA")) == NULL) || r;
+ r = ((glWindowPos4fvMESA = (PFNGLWINDOWPOS4FVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4fvMESA")) == NULL) || r;
+ r = ((glWindowPos4iMESA = (PFNGLWINDOWPOS4IMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4iMESA")) == NULL) || r;
+ r = ((glWindowPos4ivMESA = (PFNGLWINDOWPOS4IVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4ivMESA")) == NULL) || r;
+ r = ((glWindowPos4sMESA = (PFNGLWINDOWPOS4SMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4sMESA")) == NULL) || r;
+ r = ((glWindowPos4svMESA = (PFNGLWINDOWPOS4SVMESAPROC)glewGetProcAddress((const GLubyte*)"glWindowPos4svMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_MESA_window_pos */
+
+#ifdef GL_MESA_ycbcr_texture
+
+#endif /* GL_MESA_ycbcr_texture */
+
+#ifdef GL_NVX_conditional_render
+
+static GLboolean _glewInit_GL_NVX_conditional_render (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginConditionalRenderNVX = (PFNGLBEGINCONDITIONALRENDERNVXPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRenderNVX")) == NULL) || r;
+ r = ((glEndConditionalRenderNVX = (PFNGLENDCONDITIONALRENDERNVXPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRenderNVX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NVX_conditional_render */
+
+#ifdef GL_NVX_gpu_memory_info
+
+#endif /* GL_NVX_gpu_memory_info */
+
+#ifdef GL_NV_bindless_multi_draw_indirect
+
+static GLboolean _glewInit_GL_NV_bindless_multi_draw_indirect (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glMultiDrawArraysIndirectBindlessNV = (PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawArraysIndirectBindlessNV")) == NULL) || r;
+ r = ((glMultiDrawElementsIndirectBindlessNV = (PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC)glewGetProcAddress((const GLubyte*)"glMultiDrawElementsIndirectBindlessNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_bindless_multi_draw_indirect */
+
+#ifdef GL_NV_bindless_texture
+
+static GLboolean _glewInit_GL_NV_bindless_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetImageHandleNV = (PFNGLGETIMAGEHANDLENVPROC)glewGetProcAddress((const GLubyte*)"glGetImageHandleNV")) == NULL) || r;
+ r = ((glGetTextureHandleNV = (PFNGLGETTEXTUREHANDLENVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureHandleNV")) == NULL) || r;
+ r = ((glGetTextureSamplerHandleNV = (PFNGLGETTEXTURESAMPLERHANDLENVPROC)glewGetProcAddress((const GLubyte*)"glGetTextureSamplerHandleNV")) == NULL) || r;
+ r = ((glIsImageHandleResidentNV = (PFNGLISIMAGEHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsImageHandleResidentNV")) == NULL) || r;
+ r = ((glIsTextureHandleResidentNV = (PFNGLISTEXTUREHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsTextureHandleResidentNV")) == NULL) || r;
+ r = ((glMakeImageHandleNonResidentNV = (PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleNonResidentNV")) == NULL) || r;
+ r = ((glMakeImageHandleResidentNV = (PFNGLMAKEIMAGEHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeImageHandleResidentNV")) == NULL) || r;
+ r = ((glMakeTextureHandleNonResidentNV = (PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleNonResidentNV")) == NULL) || r;
+ r = ((glMakeTextureHandleResidentNV = (PFNGLMAKETEXTUREHANDLERESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeTextureHandleResidentNV")) == NULL) || r;
+ r = ((glProgramUniformHandleui64NV = (PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64NV")) == NULL) || r;
+ r = ((glProgramUniformHandleui64vNV = (PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformHandleui64vNV")) == NULL) || r;
+ r = ((glUniformHandleui64NV = (PFNGLUNIFORMHANDLEUI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64NV")) == NULL) || r;
+ r = ((glUniformHandleui64vNV = (PFNGLUNIFORMHANDLEUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniformHandleui64vNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_bindless_texture */
+
+#ifdef GL_NV_blend_equation_advanced
+
+static GLboolean _glewInit_GL_NV_blend_equation_advanced (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBlendBarrierNV = (PFNGLBLENDBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glBlendBarrierNV")) == NULL) || r;
+ r = ((glBlendParameteriNV = (PFNGLBLENDPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glBlendParameteriNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_blend_equation_advanced */
+
+#ifdef GL_NV_blend_equation_advanced_coherent
+
+#endif /* GL_NV_blend_equation_advanced_coherent */
+
+#ifdef GL_NV_blend_square
+
+#endif /* GL_NV_blend_square */
+
+#ifdef GL_NV_compute_program5
+
+#endif /* GL_NV_compute_program5 */
+
+#ifdef GL_NV_conditional_render
+
+static GLboolean _glewInit_GL_NV_conditional_render (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginConditionalRenderNV = (PFNGLBEGINCONDITIONALRENDERNVPROC)glewGetProcAddress((const GLubyte*)"glBeginConditionalRenderNV")) == NULL) || r;
+ r = ((glEndConditionalRenderNV = (PFNGLENDCONDITIONALRENDERNVPROC)glewGetProcAddress((const GLubyte*)"glEndConditionalRenderNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_conditional_render */
+
+#ifdef GL_NV_copy_depth_to_color
+
+#endif /* GL_NV_copy_depth_to_color */
+
+#ifdef GL_NV_copy_image
+
+static GLboolean _glewInit_GL_NV_copy_image (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyImageSubDataNV = (PFNGLCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glCopyImageSubDataNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_copy_image */
+
+#ifdef GL_NV_deep_texture3D
+
+#endif /* GL_NV_deep_texture3D */
+
+#ifdef GL_NV_depth_buffer_float
+
+static GLboolean _glewInit_GL_NV_depth_buffer_float (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClearDepthdNV = (PFNGLCLEARDEPTHDNVPROC)glewGetProcAddress((const GLubyte*)"glClearDepthdNV")) == NULL) || r;
+ r = ((glDepthBoundsdNV = (PFNGLDEPTHBOUNDSDNVPROC)glewGetProcAddress((const GLubyte*)"glDepthBoundsdNV")) == NULL) || r;
+ r = ((glDepthRangedNV = (PFNGLDEPTHRANGEDNVPROC)glewGetProcAddress((const GLubyte*)"glDepthRangedNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_depth_buffer_float */
+
+#ifdef GL_NV_depth_clamp
+
+#endif /* GL_NV_depth_clamp */
+
+#ifdef GL_NV_depth_range_unclamped
+
+#endif /* GL_NV_depth_range_unclamped */
+
+#ifdef GL_NV_draw_texture
+
+static GLboolean _glewInit_GL_NV_draw_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDrawTextureNV = (PFNGLDRAWTEXTURENVPROC)glewGetProcAddress((const GLubyte*)"glDrawTextureNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_draw_texture */
+
+#ifdef GL_NV_evaluators
+
+static GLboolean _glewInit_GL_NV_evaluators (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glEvalMapsNV = (PFNGLEVALMAPSNVPROC)glewGetProcAddress((const GLubyte*)"glEvalMapsNV")) == NULL) || r;
+ r = ((glGetMapAttribParameterfvNV = (PFNGLGETMAPATTRIBPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapAttribParameterfvNV")) == NULL) || r;
+ r = ((glGetMapAttribParameterivNV = (PFNGLGETMAPATTRIBPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapAttribParameterivNV")) == NULL) || r;
+ r = ((glGetMapControlPointsNV = (PFNGLGETMAPCONTROLPOINTSNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapControlPointsNV")) == NULL) || r;
+ r = ((glGetMapParameterfvNV = (PFNGLGETMAPPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapParameterfvNV")) == NULL) || r;
+ r = ((glGetMapParameterivNV = (PFNGLGETMAPPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMapParameterivNV")) == NULL) || r;
+ r = ((glMapControlPointsNV = (PFNGLMAPCONTROLPOINTSNVPROC)glewGetProcAddress((const GLubyte*)"glMapControlPointsNV")) == NULL) || r;
+ r = ((glMapParameterfvNV = (PFNGLMAPPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glMapParameterfvNV")) == NULL) || r;
+ r = ((glMapParameterivNV = (PFNGLMAPPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glMapParameterivNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_evaluators */
+
+#ifdef GL_NV_explicit_multisample
+
+static GLboolean _glewInit_GL_NV_explicit_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetMultisamplefvNV = (PFNGLGETMULTISAMPLEFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetMultisamplefvNV")) == NULL) || r;
+ r = ((glSampleMaskIndexedNV = (PFNGLSAMPLEMASKINDEXEDNVPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskIndexedNV")) == NULL) || r;
+ r = ((glTexRenderbufferNV = (PFNGLTEXRENDERBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glTexRenderbufferNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_explicit_multisample */
+
+#ifdef GL_NV_fence
+
+static GLboolean _glewInit_GL_NV_fence (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDeleteFencesNV = (PFNGLDELETEFENCESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteFencesNV")) == NULL) || r;
+ r = ((glFinishFenceNV = (PFNGLFINISHFENCENVPROC)glewGetProcAddress((const GLubyte*)"glFinishFenceNV")) == NULL) || r;
+ r = ((glGenFencesNV = (PFNGLGENFENCESNVPROC)glewGetProcAddress((const GLubyte*)"glGenFencesNV")) == NULL) || r;
+ r = ((glGetFenceivNV = (PFNGLGETFENCEIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFenceivNV")) == NULL) || r;
+ r = ((glIsFenceNV = (PFNGLISFENCENVPROC)glewGetProcAddress((const GLubyte*)"glIsFenceNV")) == NULL) || r;
+ r = ((glSetFenceNV = (PFNGLSETFENCENVPROC)glewGetProcAddress((const GLubyte*)"glSetFenceNV")) == NULL) || r;
+ r = ((glTestFenceNV = (PFNGLTESTFENCENVPROC)glewGetProcAddress((const GLubyte*)"glTestFenceNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_fence */
+
+#ifdef GL_NV_float_buffer
+
+#endif /* GL_NV_float_buffer */
+
+#ifdef GL_NV_fog_distance
+
+#endif /* GL_NV_fog_distance */
+
+#ifdef GL_NV_fragment_program
+
+static GLboolean _glewInit_GL_NV_fragment_program (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetProgramNamedParameterdvNV = (PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramNamedParameterdvNV")) == NULL) || r;
+ r = ((glGetProgramNamedParameterfvNV = (PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramNamedParameterfvNV")) == NULL) || r;
+ r = ((glProgramNamedParameter4dNV = (PFNGLPROGRAMNAMEDPARAMETER4DNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4dNV")) == NULL) || r;
+ r = ((glProgramNamedParameter4dvNV = (PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4dvNV")) == NULL) || r;
+ r = ((glProgramNamedParameter4fNV = (PFNGLPROGRAMNAMEDPARAMETER4FNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4fNV")) == NULL) || r;
+ r = ((glProgramNamedParameter4fvNV = (PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramNamedParameter4fvNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_fragment_program */
+
+#ifdef GL_NV_fragment_program2
+
+#endif /* GL_NV_fragment_program2 */
+
+#ifdef GL_NV_fragment_program4
+
+#endif /* GL_NV_fragment_program4 */
+
+#ifdef GL_NV_fragment_program_option
+
+#endif /* GL_NV_fragment_program_option */
+
+#ifdef GL_NV_framebuffer_multisample_coverage
+
+static GLboolean _glewInit_GL_NV_framebuffer_multisample_coverage (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glRenderbufferStorageMultisampleCoverageNV = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glRenderbufferStorageMultisampleCoverageNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_framebuffer_multisample_coverage */
+
+#ifdef GL_NV_geometry_program4
+
+static GLboolean _glewInit_GL_NV_geometry_program4 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glProgramVertexLimitNV = (PFNGLPROGRAMVERTEXLIMITNVPROC)glewGetProcAddress((const GLubyte*)"glProgramVertexLimitNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_geometry_program4 */
+
+#ifdef GL_NV_geometry_shader4
+
+#endif /* GL_NV_geometry_shader4 */
+
+#ifdef GL_NV_gpu_program4
+
+static GLboolean _glewInit_GL_NV_gpu_program4 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glProgramEnvParameterI4iNV = (PFNGLPROGRAMENVPARAMETERI4INVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4iNV")) == NULL) || r;
+ r = ((glProgramEnvParameterI4ivNV = (PFNGLPROGRAMENVPARAMETERI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4ivNV")) == NULL) || r;
+ r = ((glProgramEnvParameterI4uiNV = (PFNGLPROGRAMENVPARAMETERI4UINVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4uiNV")) == NULL) || r;
+ r = ((glProgramEnvParameterI4uivNV = (PFNGLPROGRAMENVPARAMETERI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParameterI4uivNV")) == NULL) || r;
+ r = ((glProgramEnvParametersI4ivNV = (PFNGLPROGRAMENVPARAMETERSI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParametersI4ivNV")) == NULL) || r;
+ r = ((glProgramEnvParametersI4uivNV = (PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramEnvParametersI4uivNV")) == NULL) || r;
+ r = ((glProgramLocalParameterI4iNV = (PFNGLPROGRAMLOCALPARAMETERI4INVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4iNV")) == NULL) || r;
+ r = ((glProgramLocalParameterI4ivNV = (PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4ivNV")) == NULL) || r;
+ r = ((glProgramLocalParameterI4uiNV = (PFNGLPROGRAMLOCALPARAMETERI4UINVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4uiNV")) == NULL) || r;
+ r = ((glProgramLocalParameterI4uivNV = (PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParameterI4uivNV")) == NULL) || r;
+ r = ((glProgramLocalParametersI4ivNV = (PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParametersI4ivNV")) == NULL) || r;
+ r = ((glProgramLocalParametersI4uivNV = (PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramLocalParametersI4uivNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_gpu_program4 */
+
+#ifdef GL_NV_gpu_program5
+
+#endif /* GL_NV_gpu_program5 */
+
+#ifdef GL_NV_gpu_program5_mem_extended
+
+#endif /* GL_NV_gpu_program5_mem_extended */
+
+#ifdef GL_NV_gpu_program_fp64
+
+#endif /* GL_NV_gpu_program_fp64 */
+
+#ifdef GL_NV_gpu_shader5
+
+static GLboolean _glewInit_GL_NV_gpu_shader5 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetUniformi64vNV = (PFNGLGETUNIFORMI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformi64vNV")) == NULL) || r;
+ r = ((glGetUniformui64vNV = (PFNGLGETUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetUniformui64vNV")) == NULL) || r;
+ r = ((glProgramUniform1i64NV = (PFNGLPROGRAMUNIFORM1I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i64NV")) == NULL) || r;
+ r = ((glProgramUniform1i64vNV = (PFNGLPROGRAMUNIFORM1I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1i64vNV")) == NULL) || r;
+ r = ((glProgramUniform1ui64NV = (PFNGLPROGRAMUNIFORM1UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui64NV")) == NULL) || r;
+ r = ((glProgramUniform1ui64vNV = (PFNGLPROGRAMUNIFORM1UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform1ui64vNV")) == NULL) || r;
+ r = ((glProgramUniform2i64NV = (PFNGLPROGRAMUNIFORM2I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i64NV")) == NULL) || r;
+ r = ((glProgramUniform2i64vNV = (PFNGLPROGRAMUNIFORM2I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2i64vNV")) == NULL) || r;
+ r = ((glProgramUniform2ui64NV = (PFNGLPROGRAMUNIFORM2UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui64NV")) == NULL) || r;
+ r = ((glProgramUniform2ui64vNV = (PFNGLPROGRAMUNIFORM2UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform2ui64vNV")) == NULL) || r;
+ r = ((glProgramUniform3i64NV = (PFNGLPROGRAMUNIFORM3I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i64NV")) == NULL) || r;
+ r = ((glProgramUniform3i64vNV = (PFNGLPROGRAMUNIFORM3I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3i64vNV")) == NULL) || r;
+ r = ((glProgramUniform3ui64NV = (PFNGLPROGRAMUNIFORM3UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui64NV")) == NULL) || r;
+ r = ((glProgramUniform3ui64vNV = (PFNGLPROGRAMUNIFORM3UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform3ui64vNV")) == NULL) || r;
+ r = ((glProgramUniform4i64NV = (PFNGLPROGRAMUNIFORM4I64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i64NV")) == NULL) || r;
+ r = ((glProgramUniform4i64vNV = (PFNGLPROGRAMUNIFORM4I64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4i64vNV")) == NULL) || r;
+ r = ((glProgramUniform4ui64NV = (PFNGLPROGRAMUNIFORM4UI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui64NV")) == NULL) || r;
+ r = ((glProgramUniform4ui64vNV = (PFNGLPROGRAMUNIFORM4UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniform4ui64vNV")) == NULL) || r;
+ r = ((glUniform1i64NV = (PFNGLUNIFORM1I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform1i64NV")) == NULL) || r;
+ r = ((glUniform1i64vNV = (PFNGLUNIFORM1I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform1i64vNV")) == NULL) || r;
+ r = ((glUniform1ui64NV = (PFNGLUNIFORM1UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui64NV")) == NULL) || r;
+ r = ((glUniform1ui64vNV = (PFNGLUNIFORM1UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform1ui64vNV")) == NULL) || r;
+ r = ((glUniform2i64NV = (PFNGLUNIFORM2I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform2i64NV")) == NULL) || r;
+ r = ((glUniform2i64vNV = (PFNGLUNIFORM2I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform2i64vNV")) == NULL) || r;
+ r = ((glUniform2ui64NV = (PFNGLUNIFORM2UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui64NV")) == NULL) || r;
+ r = ((glUniform2ui64vNV = (PFNGLUNIFORM2UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform2ui64vNV")) == NULL) || r;
+ r = ((glUniform3i64NV = (PFNGLUNIFORM3I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform3i64NV")) == NULL) || r;
+ r = ((glUniform3i64vNV = (PFNGLUNIFORM3I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform3i64vNV")) == NULL) || r;
+ r = ((glUniform3ui64NV = (PFNGLUNIFORM3UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui64NV")) == NULL) || r;
+ r = ((glUniform3ui64vNV = (PFNGLUNIFORM3UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform3ui64vNV")) == NULL) || r;
+ r = ((glUniform4i64NV = (PFNGLUNIFORM4I64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform4i64NV")) == NULL) || r;
+ r = ((glUniform4i64vNV = (PFNGLUNIFORM4I64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform4i64vNV")) == NULL) || r;
+ r = ((glUniform4ui64NV = (PFNGLUNIFORM4UI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui64NV")) == NULL) || r;
+ r = ((glUniform4ui64vNV = (PFNGLUNIFORM4UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniform4ui64vNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_gpu_shader5 */
+
+#ifdef GL_NV_half_float
+
+static GLboolean _glewInit_GL_NV_half_float (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColor3hNV = (PFNGLCOLOR3HNVPROC)glewGetProcAddress((const GLubyte*)"glColor3hNV")) == NULL) || r;
+ r = ((glColor3hvNV = (PFNGLCOLOR3HVNVPROC)glewGetProcAddress((const GLubyte*)"glColor3hvNV")) == NULL) || r;
+ r = ((glColor4hNV = (PFNGLCOLOR4HNVPROC)glewGetProcAddress((const GLubyte*)"glColor4hNV")) == NULL) || r;
+ r = ((glColor4hvNV = (PFNGLCOLOR4HVNVPROC)glewGetProcAddress((const GLubyte*)"glColor4hvNV")) == NULL) || r;
+ r = ((glFogCoordhNV = (PFNGLFOGCOORDHNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordhNV")) == NULL) || r;
+ r = ((glFogCoordhvNV = (PFNGLFOGCOORDHVNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordhvNV")) == NULL) || r;
+ r = ((glMultiTexCoord1hNV = (PFNGLMULTITEXCOORD1HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1hNV")) == NULL) || r;
+ r = ((glMultiTexCoord1hvNV = (PFNGLMULTITEXCOORD1HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord1hvNV")) == NULL) || r;
+ r = ((glMultiTexCoord2hNV = (PFNGLMULTITEXCOORD2HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2hNV")) == NULL) || r;
+ r = ((glMultiTexCoord2hvNV = (PFNGLMULTITEXCOORD2HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord2hvNV")) == NULL) || r;
+ r = ((glMultiTexCoord3hNV = (PFNGLMULTITEXCOORD3HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3hNV")) == NULL) || r;
+ r = ((glMultiTexCoord3hvNV = (PFNGLMULTITEXCOORD3HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord3hvNV")) == NULL) || r;
+ r = ((glMultiTexCoord4hNV = (PFNGLMULTITEXCOORD4HNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4hNV")) == NULL) || r;
+ r = ((glMultiTexCoord4hvNV = (PFNGLMULTITEXCOORD4HVNVPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4hvNV")) == NULL) || r;
+ r = ((glNormal3hNV = (PFNGLNORMAL3HNVPROC)glewGetProcAddress((const GLubyte*)"glNormal3hNV")) == NULL) || r;
+ r = ((glNormal3hvNV = (PFNGLNORMAL3HVNVPROC)glewGetProcAddress((const GLubyte*)"glNormal3hvNV")) == NULL) || r;
+ r = ((glSecondaryColor3hNV = (PFNGLSECONDARYCOLOR3HNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3hNV")) == NULL) || r;
+ r = ((glSecondaryColor3hvNV = (PFNGLSECONDARYCOLOR3HVNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColor3hvNV")) == NULL) || r;
+ r = ((glTexCoord1hNV = (PFNGLTEXCOORD1HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord1hNV")) == NULL) || r;
+ r = ((glTexCoord1hvNV = (PFNGLTEXCOORD1HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord1hvNV")) == NULL) || r;
+ r = ((glTexCoord2hNV = (PFNGLTEXCOORD2HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2hNV")) == NULL) || r;
+ r = ((glTexCoord2hvNV = (PFNGLTEXCOORD2HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2hvNV")) == NULL) || r;
+ r = ((glTexCoord3hNV = (PFNGLTEXCOORD3HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord3hNV")) == NULL) || r;
+ r = ((glTexCoord3hvNV = (PFNGLTEXCOORD3HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord3hvNV")) == NULL) || r;
+ r = ((glTexCoord4hNV = (PFNGLTEXCOORD4HNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4hNV")) == NULL) || r;
+ r = ((glTexCoord4hvNV = (PFNGLTEXCOORD4HVNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4hvNV")) == NULL) || r;
+ r = ((glVertex2hNV = (PFNGLVERTEX2HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex2hNV")) == NULL) || r;
+ r = ((glVertex2hvNV = (PFNGLVERTEX2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex2hvNV")) == NULL) || r;
+ r = ((glVertex3hNV = (PFNGLVERTEX3HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex3hNV")) == NULL) || r;
+ r = ((glVertex3hvNV = (PFNGLVERTEX3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex3hvNV")) == NULL) || r;
+ r = ((glVertex4hNV = (PFNGLVERTEX4HNVPROC)glewGetProcAddress((const GLubyte*)"glVertex4hNV")) == NULL) || r;
+ r = ((glVertex4hvNV = (PFNGLVERTEX4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertex4hvNV")) == NULL) || r;
+ r = ((glVertexAttrib1hNV = (PFNGLVERTEXATTRIB1HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1hNV")) == NULL) || r;
+ r = ((glVertexAttrib1hvNV = (PFNGLVERTEXATTRIB1HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1hvNV")) == NULL) || r;
+ r = ((glVertexAttrib2hNV = (PFNGLVERTEXATTRIB2HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2hNV")) == NULL) || r;
+ r = ((glVertexAttrib2hvNV = (PFNGLVERTEXATTRIB2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2hvNV")) == NULL) || r;
+ r = ((glVertexAttrib3hNV = (PFNGLVERTEXATTRIB3HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3hNV")) == NULL) || r;
+ r = ((glVertexAttrib3hvNV = (PFNGLVERTEXATTRIB3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3hvNV")) == NULL) || r;
+ r = ((glVertexAttrib4hNV = (PFNGLVERTEXATTRIB4HNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4hNV")) == NULL) || r;
+ r = ((glVertexAttrib4hvNV = (PFNGLVERTEXATTRIB4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4hvNV")) == NULL) || r;
+ r = ((glVertexAttribs1hvNV = (PFNGLVERTEXATTRIBS1HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1hvNV")) == NULL) || r;
+ r = ((glVertexAttribs2hvNV = (PFNGLVERTEXATTRIBS2HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2hvNV")) == NULL) || r;
+ r = ((glVertexAttribs3hvNV = (PFNGLVERTEXATTRIBS3HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3hvNV")) == NULL) || r;
+ r = ((glVertexAttribs4hvNV = (PFNGLVERTEXATTRIBS4HVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4hvNV")) == NULL) || r;
+ r = ((glVertexWeighthNV = (PFNGLVERTEXWEIGHTHNVPROC)glewGetProcAddress((const GLubyte*)"glVertexWeighthNV")) == NULL) || r;
+ r = ((glVertexWeighthvNV = (PFNGLVERTEXWEIGHTHVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexWeighthvNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_half_float */
+
+#ifdef GL_NV_light_max_exponent
+
+#endif /* GL_NV_light_max_exponent */
+
+#ifdef GL_NV_multisample_coverage
+
+#endif /* GL_NV_multisample_coverage */
+
+#ifdef GL_NV_multisample_filter_hint
+
+#endif /* GL_NV_multisample_filter_hint */
+
+#ifdef GL_NV_occlusion_query
+
+static GLboolean _glewInit_GL_NV_occlusion_query (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginOcclusionQueryNV = (PFNGLBEGINOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glBeginOcclusionQueryNV")) == NULL) || r;
+ r = ((glDeleteOcclusionQueriesNV = (PFNGLDELETEOCCLUSIONQUERIESNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteOcclusionQueriesNV")) == NULL) || r;
+ r = ((glEndOcclusionQueryNV = (PFNGLENDOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glEndOcclusionQueryNV")) == NULL) || r;
+ r = ((glGenOcclusionQueriesNV = (PFNGLGENOCCLUSIONQUERIESNVPROC)glewGetProcAddress((const GLubyte*)"glGenOcclusionQueriesNV")) == NULL) || r;
+ r = ((glGetOcclusionQueryivNV = (PFNGLGETOCCLUSIONQUERYIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetOcclusionQueryivNV")) == NULL) || r;
+ r = ((glGetOcclusionQueryuivNV = (PFNGLGETOCCLUSIONQUERYUIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetOcclusionQueryuivNV")) == NULL) || r;
+ r = ((glIsOcclusionQueryNV = (PFNGLISOCCLUSIONQUERYNVPROC)glewGetProcAddress((const GLubyte*)"glIsOcclusionQueryNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_occlusion_query */
+
+#ifdef GL_NV_packed_depth_stencil
+
+#endif /* GL_NV_packed_depth_stencil */
+
+#ifdef GL_NV_parameter_buffer_object
+
+static GLboolean _glewInit_GL_NV_parameter_buffer_object (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glProgramBufferParametersIivNV = (PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersIivNV")) == NULL) || r;
+ r = ((glProgramBufferParametersIuivNV = (PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersIuivNV")) == NULL) || r;
+ r = ((glProgramBufferParametersfvNV = (PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramBufferParametersfvNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_parameter_buffer_object */
+
+#ifdef GL_NV_parameter_buffer_object2
+
+#endif /* GL_NV_parameter_buffer_object2 */
+
+#ifdef GL_NV_path_rendering
+
+static GLboolean _glewInit_GL_NV_path_rendering (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCopyPathNV = (PFNGLCOPYPATHNVPROC)glewGetProcAddress((const GLubyte*)"glCopyPathNV")) == NULL) || r;
+ r = ((glCoverFillPathInstancedNV = (PFNGLCOVERFILLPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glCoverFillPathInstancedNV")) == NULL) || r;
+ r = ((glCoverFillPathNV = (PFNGLCOVERFILLPATHNVPROC)glewGetProcAddress((const GLubyte*)"glCoverFillPathNV")) == NULL) || r;
+ r = ((glCoverStrokePathInstancedNV = (PFNGLCOVERSTROKEPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glCoverStrokePathInstancedNV")) == NULL) || r;
+ r = ((glCoverStrokePathNV = (PFNGLCOVERSTROKEPATHNVPROC)glewGetProcAddress((const GLubyte*)"glCoverStrokePathNV")) == NULL) || r;
+ r = ((glDeletePathsNV = (PFNGLDELETEPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glDeletePathsNV")) == NULL) || r;
+ r = ((glGenPathsNV = (PFNGLGENPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glGenPathsNV")) == NULL) || r;
+ r = ((glGetPathColorGenfvNV = (PFNGLGETPATHCOLORGENFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathColorGenfvNV")) == NULL) || r;
+ r = ((glGetPathColorGenivNV = (PFNGLGETPATHCOLORGENIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathColorGenivNV")) == NULL) || r;
+ r = ((glGetPathCommandsNV = (PFNGLGETPATHCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathCommandsNV")) == NULL) || r;
+ r = ((glGetPathCoordsNV = (PFNGLGETPATHCOORDSNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathCoordsNV")) == NULL) || r;
+ r = ((glGetPathDashArrayNV = (PFNGLGETPATHDASHARRAYNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathDashArrayNV")) == NULL) || r;
+ r = ((glGetPathLengthNV = (PFNGLGETPATHLENGTHNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathLengthNV")) == NULL) || r;
+ r = ((glGetPathMetricRangeNV = (PFNGLGETPATHMETRICRANGENVPROC)glewGetProcAddress((const GLubyte*)"glGetPathMetricRangeNV")) == NULL) || r;
+ r = ((glGetPathMetricsNV = (PFNGLGETPATHMETRICSNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathMetricsNV")) == NULL) || r;
+ r = ((glGetPathParameterfvNV = (PFNGLGETPATHPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathParameterfvNV")) == NULL) || r;
+ r = ((glGetPathParameterivNV = (PFNGLGETPATHPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathParameterivNV")) == NULL) || r;
+ r = ((glGetPathSpacingNV = (PFNGLGETPATHSPACINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathSpacingNV")) == NULL) || r;
+ r = ((glGetPathTexGenfvNV = (PFNGLGETPATHTEXGENFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathTexGenfvNV")) == NULL) || r;
+ r = ((glGetPathTexGenivNV = (PFNGLGETPATHTEXGENIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetPathTexGenivNV")) == NULL) || r;
+ r = ((glInterpolatePathsNV = (PFNGLINTERPOLATEPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glInterpolatePathsNV")) == NULL) || r;
+ r = ((glIsPathNV = (PFNGLISPATHNVPROC)glewGetProcAddress((const GLubyte*)"glIsPathNV")) == NULL) || r;
+ r = ((glIsPointInFillPathNV = (PFNGLISPOINTINFILLPATHNVPROC)glewGetProcAddress((const GLubyte*)"glIsPointInFillPathNV")) == NULL) || r;
+ r = ((glIsPointInStrokePathNV = (PFNGLISPOINTINSTROKEPATHNVPROC)glewGetProcAddress((const GLubyte*)"glIsPointInStrokePathNV")) == NULL) || r;
+ r = ((glPathColorGenNV = (PFNGLPATHCOLORGENNVPROC)glewGetProcAddress((const GLubyte*)"glPathColorGenNV")) == NULL) || r;
+ r = ((glPathCommandsNV = (PFNGLPATHCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathCommandsNV")) == NULL) || r;
+ r = ((glPathCoordsNV = (PFNGLPATHCOORDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathCoordsNV")) == NULL) || r;
+ r = ((glPathCoverDepthFuncNV = (PFNGLPATHCOVERDEPTHFUNCNVPROC)glewGetProcAddress((const GLubyte*)"glPathCoverDepthFuncNV")) == NULL) || r;
+ r = ((glPathDashArrayNV = (PFNGLPATHDASHARRAYNVPROC)glewGetProcAddress((const GLubyte*)"glPathDashArrayNV")) == NULL) || r;
+ r = ((glPathFogGenNV = (PFNGLPATHFOGGENNVPROC)glewGetProcAddress((const GLubyte*)"glPathFogGenNV")) == NULL) || r;
+ r = ((glPathGlyphRangeNV = (PFNGLPATHGLYPHRANGENVPROC)glewGetProcAddress((const GLubyte*)"glPathGlyphRangeNV")) == NULL) || r;
+ r = ((glPathGlyphsNV = (PFNGLPATHGLYPHSNVPROC)glewGetProcAddress((const GLubyte*)"glPathGlyphsNV")) == NULL) || r;
+ r = ((glPathParameterfNV = (PFNGLPATHPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glPathParameterfNV")) == NULL) || r;
+ r = ((glPathParameterfvNV = (PFNGLPATHPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glPathParameterfvNV")) == NULL) || r;
+ r = ((glPathParameteriNV = (PFNGLPATHPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glPathParameteriNV")) == NULL) || r;
+ r = ((glPathParameterivNV = (PFNGLPATHPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glPathParameterivNV")) == NULL) || r;
+ r = ((glPathStencilDepthOffsetNV = (PFNGLPATHSTENCILDEPTHOFFSETNVPROC)glewGetProcAddress((const GLubyte*)"glPathStencilDepthOffsetNV")) == NULL) || r;
+ r = ((glPathStencilFuncNV = (PFNGLPATHSTENCILFUNCNVPROC)glewGetProcAddress((const GLubyte*)"glPathStencilFuncNV")) == NULL) || r;
+ r = ((glPathStringNV = (PFNGLPATHSTRINGNVPROC)glewGetProcAddress((const GLubyte*)"glPathStringNV")) == NULL) || r;
+ r = ((glPathSubCommandsNV = (PFNGLPATHSUBCOMMANDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathSubCommandsNV")) == NULL) || r;
+ r = ((glPathSubCoordsNV = (PFNGLPATHSUBCOORDSNVPROC)glewGetProcAddress((const GLubyte*)"glPathSubCoordsNV")) == NULL) || r;
+ r = ((glPathTexGenNV = (PFNGLPATHTEXGENNVPROC)glewGetProcAddress((const GLubyte*)"glPathTexGenNV")) == NULL) || r;
+ r = ((glPointAlongPathNV = (PFNGLPOINTALONGPATHNVPROC)glewGetProcAddress((const GLubyte*)"glPointAlongPathNV")) == NULL) || r;
+ r = ((glStencilFillPathInstancedNV = (PFNGLSTENCILFILLPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glStencilFillPathInstancedNV")) == NULL) || r;
+ r = ((glStencilFillPathNV = (PFNGLSTENCILFILLPATHNVPROC)glewGetProcAddress((const GLubyte*)"glStencilFillPathNV")) == NULL) || r;
+ r = ((glStencilStrokePathInstancedNV = (PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC)glewGetProcAddress((const GLubyte*)"glStencilStrokePathInstancedNV")) == NULL) || r;
+ r = ((glStencilStrokePathNV = (PFNGLSTENCILSTROKEPATHNVPROC)glewGetProcAddress((const GLubyte*)"glStencilStrokePathNV")) == NULL) || r;
+ r = ((glTransformPathNV = (PFNGLTRANSFORMPATHNVPROC)glewGetProcAddress((const GLubyte*)"glTransformPathNV")) == NULL) || r;
+ r = ((glWeightPathsNV = (PFNGLWEIGHTPATHSNVPROC)glewGetProcAddress((const GLubyte*)"glWeightPathsNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_path_rendering */
+
+#ifdef GL_NV_pixel_data_range
+
+static GLboolean _glewInit_GL_NV_pixel_data_range (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFlushPixelDataRangeNV = (PFNGLFLUSHPIXELDATARANGENVPROC)glewGetProcAddress((const GLubyte*)"glFlushPixelDataRangeNV")) == NULL) || r;
+ r = ((glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC)glewGetProcAddress((const GLubyte*)"glPixelDataRangeNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_pixel_data_range */
+
+#ifdef GL_NV_point_sprite
+
+static GLboolean _glewInit_GL_NV_point_sprite (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPointParameteriNV = (PFNGLPOINTPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glPointParameteriNV")) == NULL) || r;
+ r = ((glPointParameterivNV = (PFNGLPOINTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterivNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_point_sprite */
+
+#ifdef GL_NV_present_video
+
+static GLboolean _glewInit_GL_NV_present_video (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetVideoi64vNV = (PFNGLGETVIDEOI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoi64vNV")) == NULL) || r;
+ r = ((glGetVideoivNV = (PFNGLGETVIDEOIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoivNV")) == NULL) || r;
+ r = ((glGetVideoui64vNV = (PFNGLGETVIDEOUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoui64vNV")) == NULL) || r;
+ r = ((glGetVideouivNV = (PFNGLGETVIDEOUIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideouivNV")) == NULL) || r;
+ r = ((glPresentFrameDualFillNV = (PFNGLPRESENTFRAMEDUALFILLNVPROC)glewGetProcAddress((const GLubyte*)"glPresentFrameDualFillNV")) == NULL) || r;
+ r = ((glPresentFrameKeyedNV = (PFNGLPRESENTFRAMEKEYEDNVPROC)glewGetProcAddress((const GLubyte*)"glPresentFrameKeyedNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_present_video */
+
+#ifdef GL_NV_primitive_restart
+
+static GLboolean _glewInit_GL_NV_primitive_restart (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPrimitiveRestartIndexNV = (PFNGLPRIMITIVERESTARTINDEXNVPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartIndexNV")) == NULL) || r;
+ r = ((glPrimitiveRestartNV = (PFNGLPRIMITIVERESTARTNVPROC)glewGetProcAddress((const GLubyte*)"glPrimitiveRestartNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_primitive_restart */
+
+#ifdef GL_NV_register_combiners
+
+static GLboolean _glewInit_GL_NV_register_combiners (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCombinerInputNV = (PFNGLCOMBINERINPUTNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerInputNV")) == NULL) || r;
+ r = ((glCombinerOutputNV = (PFNGLCOMBINEROUTPUTNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerOutputNV")) == NULL) || r;
+ r = ((glCombinerParameterfNV = (PFNGLCOMBINERPARAMETERFNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterfNV")) == NULL) || r;
+ r = ((glCombinerParameterfvNV = (PFNGLCOMBINERPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterfvNV")) == NULL) || r;
+ r = ((glCombinerParameteriNV = (PFNGLCOMBINERPARAMETERINVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameteriNV")) == NULL) || r;
+ r = ((glCombinerParameterivNV = (PFNGLCOMBINERPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerParameterivNV")) == NULL) || r;
+ r = ((glFinalCombinerInputNV = (PFNGLFINALCOMBINERINPUTNVPROC)glewGetProcAddress((const GLubyte*)"glFinalCombinerInputNV")) == NULL) || r;
+ r = ((glGetCombinerInputParameterfvNV = (PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerInputParameterfvNV")) == NULL) || r;
+ r = ((glGetCombinerInputParameterivNV = (PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerInputParameterivNV")) == NULL) || r;
+ r = ((glGetCombinerOutputParameterfvNV = (PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerOutputParameterfvNV")) == NULL) || r;
+ r = ((glGetCombinerOutputParameterivNV = (PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerOutputParameterivNV")) == NULL) || r;
+ r = ((glGetFinalCombinerInputParameterfvNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFinalCombinerInputParameterfvNV")) == NULL) || r;
+ r = ((glGetFinalCombinerInputParameterivNV = (PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetFinalCombinerInputParameterivNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_register_combiners */
+
+#ifdef GL_NV_register_combiners2
+
+static GLboolean _glewInit_GL_NV_register_combiners2 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glCombinerStageParameterfvNV = (PFNGLCOMBINERSTAGEPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glCombinerStageParameterfvNV")) == NULL) || r;
+ r = ((glGetCombinerStageParameterfvNV = (PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetCombinerStageParameterfvNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_register_combiners2 */
+
+#ifdef GL_NV_shader_atomic_counters
+
+#endif /* GL_NV_shader_atomic_counters */
+
+#ifdef GL_NV_shader_atomic_float
+
+#endif /* GL_NV_shader_atomic_float */
+
+#ifdef GL_NV_shader_buffer_load
+
+static GLboolean _glewInit_GL_NV_shader_buffer_load (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetBufferParameterui64vNV = (PFNGLGETBUFFERPARAMETERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetBufferParameterui64vNV")) == NULL) || r;
+ r = ((glGetIntegerui64vNV = (PFNGLGETINTEGERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerui64vNV")) == NULL) || r;
+ r = ((glGetNamedBufferParameterui64vNV = (PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetNamedBufferParameterui64vNV")) == NULL) || r;
+ r = ((glIsBufferResidentNV = (PFNGLISBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsBufferResidentNV")) == NULL) || r;
+ r = ((glIsNamedBufferResidentNV = (PFNGLISNAMEDBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glIsNamedBufferResidentNV")) == NULL) || r;
+ r = ((glMakeBufferNonResidentNV = (PFNGLMAKEBUFFERNONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeBufferNonResidentNV")) == NULL) || r;
+ r = ((glMakeBufferResidentNV = (PFNGLMAKEBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeBufferResidentNV")) == NULL) || r;
+ r = ((glMakeNamedBufferNonResidentNV = (PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeNamedBufferNonResidentNV")) == NULL) || r;
+ r = ((glMakeNamedBufferResidentNV = (PFNGLMAKENAMEDBUFFERRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glMakeNamedBufferResidentNV")) == NULL) || r;
+ r = ((glProgramUniformui64NV = (PFNGLPROGRAMUNIFORMUI64NVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformui64NV")) == NULL) || r;
+ r = ((glProgramUniformui64vNV = (PFNGLPROGRAMUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glProgramUniformui64vNV")) == NULL) || r;
+ r = ((glUniformui64NV = (PFNGLUNIFORMUI64NVPROC)glewGetProcAddress((const GLubyte*)"glUniformui64NV")) == NULL) || r;
+ r = ((glUniformui64vNV = (PFNGLUNIFORMUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glUniformui64vNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_shader_buffer_load */
+
+#ifdef GL_NV_shader_storage_buffer_object
+
+#endif /* GL_NV_shader_storage_buffer_object */
+
+#ifdef GL_NV_tessellation_program5
+
+#endif /* GL_NV_tessellation_program5 */
+
+#ifdef GL_NV_texgen_emboss
+
+#endif /* GL_NV_texgen_emboss */
+
+#ifdef GL_NV_texgen_reflection
+
+#endif /* GL_NV_texgen_reflection */
+
+#ifdef GL_NV_texture_barrier
+
+static GLboolean _glewInit_GL_NV_texture_barrier (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTextureBarrierNV = (PFNGLTEXTUREBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glTextureBarrierNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_texture_barrier */
+
+#ifdef GL_NV_texture_compression_vtc
+
+#endif /* GL_NV_texture_compression_vtc */
+
+#ifdef GL_NV_texture_env_combine4
+
+#endif /* GL_NV_texture_env_combine4 */
+
+#ifdef GL_NV_texture_expand_normal
+
+#endif /* GL_NV_texture_expand_normal */
+
+#ifdef GL_NV_texture_multisample
+
+static GLboolean _glewInit_GL_NV_texture_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexImage2DMultisampleCoverageNV = (PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTexImage2DMultisampleCoverageNV")) == NULL) || r;
+ r = ((glTexImage3DMultisampleCoverageNV = (PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTexImage3DMultisampleCoverageNV")) == NULL) || r;
+ r = ((glTextureImage2DMultisampleCoverageNV = (PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage2DMultisampleCoverageNV")) == NULL) || r;
+ r = ((glTextureImage2DMultisampleNV = (PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage2DMultisampleNV")) == NULL) || r;
+ r = ((glTextureImage3DMultisampleCoverageNV = (PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage3DMultisampleCoverageNV")) == NULL) || r;
+ r = ((glTextureImage3DMultisampleNV = (PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC)glewGetProcAddress((const GLubyte*)"glTextureImage3DMultisampleNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_texture_multisample */
+
+#ifdef GL_NV_texture_rectangle
+
+#endif /* GL_NV_texture_rectangle */
+
+#ifdef GL_NV_texture_shader
+
+#endif /* GL_NV_texture_shader */
+
+#ifdef GL_NV_texture_shader2
+
+#endif /* GL_NV_texture_shader2 */
+
+#ifdef GL_NV_texture_shader3
+
+#endif /* GL_NV_texture_shader3 */
+
+#ifdef GL_NV_transform_feedback
+
+static GLboolean _glewInit_GL_NV_transform_feedback (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glActiveVaryingNV = (PFNGLACTIVEVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glActiveVaryingNV")) == NULL) || r;
+ r = ((glBeginTransformFeedbackNV = (PFNGLBEGINTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glBeginTransformFeedbackNV")) == NULL) || r;
+ r = ((glBindBufferBaseNV = (PFNGLBINDBUFFERBASENVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferBaseNV")) == NULL) || r;
+ r = ((glBindBufferOffsetNV = (PFNGLBINDBUFFEROFFSETNVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferOffsetNV")) == NULL) || r;
+ r = ((glBindBufferRangeNV = (PFNGLBINDBUFFERRANGENVPROC)glewGetProcAddress((const GLubyte*)"glBindBufferRangeNV")) == NULL) || r;
+ r = ((glEndTransformFeedbackNV = (PFNGLENDTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glEndTransformFeedbackNV")) == NULL) || r;
+ r = ((glGetActiveVaryingNV = (PFNGLGETACTIVEVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetActiveVaryingNV")) == NULL) || r;
+ r = ((glGetTransformFeedbackVaryingNV = (PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetTransformFeedbackVaryingNV")) == NULL) || r;
+ r = ((glGetVaryingLocationNV = (PFNGLGETVARYINGLOCATIONNVPROC)glewGetProcAddress((const GLubyte*)"glGetVaryingLocationNV")) == NULL) || r;
+ r = ((glTransformFeedbackAttribsNV = (PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackAttribsNV")) == NULL) || r;
+ r = ((glTransformFeedbackVaryingsNV = (PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC)glewGetProcAddress((const GLubyte*)"glTransformFeedbackVaryingsNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_transform_feedback */
+
+#ifdef GL_NV_transform_feedback2
+
+static GLboolean _glewInit_GL_NV_transform_feedback2 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBindTransformFeedbackNV = (PFNGLBINDTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glBindTransformFeedbackNV")) == NULL) || r;
+ r = ((glDeleteTransformFeedbacksNV = (PFNGLDELETETRANSFORMFEEDBACKSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteTransformFeedbacksNV")) == NULL) || r;
+ r = ((glDrawTransformFeedbackNV = (PFNGLDRAWTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glDrawTransformFeedbackNV")) == NULL) || r;
+ r = ((glGenTransformFeedbacksNV = (PFNGLGENTRANSFORMFEEDBACKSNVPROC)glewGetProcAddress((const GLubyte*)"glGenTransformFeedbacksNV")) == NULL) || r;
+ r = ((glIsTransformFeedbackNV = (PFNGLISTRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glIsTransformFeedbackNV")) == NULL) || r;
+ r = ((glPauseTransformFeedbackNV = (PFNGLPAUSETRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glPauseTransformFeedbackNV")) == NULL) || r;
+ r = ((glResumeTransformFeedbackNV = (PFNGLRESUMETRANSFORMFEEDBACKNVPROC)glewGetProcAddress((const GLubyte*)"glResumeTransformFeedbackNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_transform_feedback2 */
+
+#ifdef GL_NV_vdpau_interop
+
+static GLboolean _glewInit_GL_NV_vdpau_interop (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glVDPAUFiniNV = (PFNGLVDPAUFININVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUFiniNV")) == NULL) || r;
+ r = ((glVDPAUGetSurfaceivNV = (PFNGLVDPAUGETSURFACEIVNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUGetSurfaceivNV")) == NULL) || r;
+ r = ((glVDPAUInitNV = (PFNGLVDPAUINITNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUInitNV")) == NULL) || r;
+ r = ((glVDPAUIsSurfaceNV = (PFNGLVDPAUISSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUIsSurfaceNV")) == NULL) || r;
+ r = ((glVDPAUMapSurfacesNV = (PFNGLVDPAUMAPSURFACESNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUMapSurfacesNV")) == NULL) || r;
+ r = ((glVDPAURegisterOutputSurfaceNV = (PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAURegisterOutputSurfaceNV")) == NULL) || r;
+ r = ((glVDPAURegisterVideoSurfaceNV = (PFNGLVDPAUREGISTERVIDEOSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAURegisterVideoSurfaceNV")) == NULL) || r;
+ r = ((glVDPAUSurfaceAccessNV = (PFNGLVDPAUSURFACEACCESSNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUSurfaceAccessNV")) == NULL) || r;
+ r = ((glVDPAUUnmapSurfacesNV = (PFNGLVDPAUUNMAPSURFACESNVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUUnmapSurfacesNV")) == NULL) || r;
+ r = ((glVDPAUUnregisterSurfaceNV = (PFNGLVDPAUUNREGISTERSURFACENVPROC)glewGetProcAddress((const GLubyte*)"glVDPAUUnregisterSurfaceNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_vdpau_interop */
+
+#ifdef GL_NV_vertex_array_range
+
+static GLboolean _glewInit_GL_NV_vertex_array_range (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFlushVertexArrayRangeNV = (PFNGLFLUSHVERTEXARRAYRANGENVPROC)glewGetProcAddress((const GLubyte*)"glFlushVertexArrayRangeNV")) == NULL) || r;
+ r = ((glVertexArrayRangeNV = (PFNGLVERTEXARRAYRANGENVPROC)glewGetProcAddress((const GLubyte*)"glVertexArrayRangeNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_vertex_array_range */
+
+#ifdef GL_NV_vertex_array_range2
+
+#endif /* GL_NV_vertex_array_range2 */
+
+#ifdef GL_NV_vertex_attrib_integer_64bit
+
+static GLboolean _glewInit_GL_NV_vertex_attrib_integer_64bit (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetVertexAttribLi64vNV = (PFNGLGETVERTEXATTRIBLI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLi64vNV")) == NULL) || r;
+ r = ((glGetVertexAttribLui64vNV = (PFNGLGETVERTEXATTRIBLUI64VNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribLui64vNV")) == NULL) || r;
+ r = ((glVertexAttribL1i64NV = (PFNGLVERTEXATTRIBL1I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1i64NV")) == NULL) || r;
+ r = ((glVertexAttribL1i64vNV = (PFNGLVERTEXATTRIBL1I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1i64vNV")) == NULL) || r;
+ r = ((glVertexAttribL1ui64NV = (PFNGLVERTEXATTRIBL1UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64NV")) == NULL) || r;
+ r = ((glVertexAttribL1ui64vNV = (PFNGLVERTEXATTRIBL1UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL1ui64vNV")) == NULL) || r;
+ r = ((glVertexAttribL2i64NV = (PFNGLVERTEXATTRIBL2I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2i64NV")) == NULL) || r;
+ r = ((glVertexAttribL2i64vNV = (PFNGLVERTEXATTRIBL2I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2i64vNV")) == NULL) || r;
+ r = ((glVertexAttribL2ui64NV = (PFNGLVERTEXATTRIBL2UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2ui64NV")) == NULL) || r;
+ r = ((glVertexAttribL2ui64vNV = (PFNGLVERTEXATTRIBL2UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL2ui64vNV")) == NULL) || r;
+ r = ((glVertexAttribL3i64NV = (PFNGLVERTEXATTRIBL3I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3i64NV")) == NULL) || r;
+ r = ((glVertexAttribL3i64vNV = (PFNGLVERTEXATTRIBL3I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3i64vNV")) == NULL) || r;
+ r = ((glVertexAttribL3ui64NV = (PFNGLVERTEXATTRIBL3UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3ui64NV")) == NULL) || r;
+ r = ((glVertexAttribL3ui64vNV = (PFNGLVERTEXATTRIBL3UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL3ui64vNV")) == NULL) || r;
+ r = ((glVertexAttribL4i64NV = (PFNGLVERTEXATTRIBL4I64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4i64NV")) == NULL) || r;
+ r = ((glVertexAttribL4i64vNV = (PFNGLVERTEXATTRIBL4I64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4i64vNV")) == NULL) || r;
+ r = ((glVertexAttribL4ui64NV = (PFNGLVERTEXATTRIBL4UI64NVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4ui64NV")) == NULL) || r;
+ r = ((glVertexAttribL4ui64vNV = (PFNGLVERTEXATTRIBL4UI64VNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribL4ui64vNV")) == NULL) || r;
+ r = ((glVertexAttribLFormatNV = (PFNGLVERTEXATTRIBLFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribLFormatNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_vertex_attrib_integer_64bit */
+
+#ifdef GL_NV_vertex_buffer_unified_memory
+
+static GLboolean _glewInit_GL_NV_vertex_buffer_unified_memory (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBufferAddressRangeNV = (PFNGLBUFFERADDRESSRANGENVPROC)glewGetProcAddress((const GLubyte*)"glBufferAddressRangeNV")) == NULL) || r;
+ r = ((glColorFormatNV = (PFNGLCOLORFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glColorFormatNV")) == NULL) || r;
+ r = ((glEdgeFlagFormatNV = (PFNGLEDGEFLAGFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glEdgeFlagFormatNV")) == NULL) || r;
+ r = ((glFogCoordFormatNV = (PFNGLFOGCOORDFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glFogCoordFormatNV")) == NULL) || r;
+ r = ((glGetIntegerui64i_vNV = (PFNGLGETINTEGERUI64I_VNVPROC)glewGetProcAddress((const GLubyte*)"glGetIntegerui64i_vNV")) == NULL) || r;
+ r = ((glIndexFormatNV = (PFNGLINDEXFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glIndexFormatNV")) == NULL) || r;
+ r = ((glNormalFormatNV = (PFNGLNORMALFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glNormalFormatNV")) == NULL) || r;
+ r = ((glSecondaryColorFormatNV = (PFNGLSECONDARYCOLORFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glSecondaryColorFormatNV")) == NULL) || r;
+ r = ((glTexCoordFormatNV = (PFNGLTEXCOORDFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glTexCoordFormatNV")) == NULL) || r;
+ r = ((glVertexAttribFormatNV = (PFNGLVERTEXATTRIBFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribFormatNV")) == NULL) || r;
+ r = ((glVertexAttribIFormatNV = (PFNGLVERTEXATTRIBIFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribIFormatNV")) == NULL) || r;
+ r = ((glVertexFormatNV = (PFNGLVERTEXFORMATNVPROC)glewGetProcAddress((const GLubyte*)"glVertexFormatNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_vertex_buffer_unified_memory */
+
+#ifdef GL_NV_vertex_program
+
+static GLboolean _glewInit_GL_NV_vertex_program (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAreProgramsResidentNV = (PFNGLAREPROGRAMSRESIDENTNVPROC)glewGetProcAddress((const GLubyte*)"glAreProgramsResidentNV")) == NULL) || r;
+ r = ((glBindProgramNV = (PFNGLBINDPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glBindProgramNV")) == NULL) || r;
+ r = ((glDeleteProgramsNV = (PFNGLDELETEPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glDeleteProgramsNV")) == NULL) || r;
+ r = ((glExecuteProgramNV = (PFNGLEXECUTEPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glExecuteProgramNV")) == NULL) || r;
+ r = ((glGenProgramsNV = (PFNGLGENPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glGenProgramsNV")) == NULL) || r;
+ r = ((glGetProgramParameterdvNV = (PFNGLGETPROGRAMPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramParameterdvNV")) == NULL) || r;
+ r = ((glGetProgramParameterfvNV = (PFNGLGETPROGRAMPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramParameterfvNV")) == NULL) || r;
+ r = ((glGetProgramStringNV = (PFNGLGETPROGRAMSTRINGNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramStringNV")) == NULL) || r;
+ r = ((glGetProgramivNV = (PFNGLGETPROGRAMIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetProgramivNV")) == NULL) || r;
+ r = ((glGetTrackMatrixivNV = (PFNGLGETTRACKMATRIXIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetTrackMatrixivNV")) == NULL) || r;
+ r = ((glGetVertexAttribPointervNV = (PFNGLGETVERTEXATTRIBPOINTERVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribPointervNV")) == NULL) || r;
+ r = ((glGetVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribdvNV")) == NULL) || r;
+ r = ((glGetVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribfvNV")) == NULL) || r;
+ r = ((glGetVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVertexAttribivNV")) == NULL) || r;
+ r = ((glIsProgramNV = (PFNGLISPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glIsProgramNV")) == NULL) || r;
+ r = ((glLoadProgramNV = (PFNGLLOADPROGRAMNVPROC)glewGetProcAddress((const GLubyte*)"glLoadProgramNV")) == NULL) || r;
+ r = ((glProgramParameter4dNV = (PFNGLPROGRAMPARAMETER4DNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4dNV")) == NULL) || r;
+ r = ((glProgramParameter4dvNV = (PFNGLPROGRAMPARAMETER4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4dvNV")) == NULL) || r;
+ r = ((glProgramParameter4fNV = (PFNGLPROGRAMPARAMETER4FNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4fNV")) == NULL) || r;
+ r = ((glProgramParameter4fvNV = (PFNGLPROGRAMPARAMETER4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameter4fvNV")) == NULL) || r;
+ r = ((glProgramParameters4dvNV = (PFNGLPROGRAMPARAMETERS4DVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameters4dvNV")) == NULL) || r;
+ r = ((glProgramParameters4fvNV = (PFNGLPROGRAMPARAMETERS4FVNVPROC)glewGetProcAddress((const GLubyte*)"glProgramParameters4fvNV")) == NULL) || r;
+ r = ((glRequestResidentProgramsNV = (PFNGLREQUESTRESIDENTPROGRAMSNVPROC)glewGetProcAddress((const GLubyte*)"glRequestResidentProgramsNV")) == NULL) || r;
+ r = ((glTrackMatrixNV = (PFNGLTRACKMATRIXNVPROC)glewGetProcAddress((const GLubyte*)"glTrackMatrixNV")) == NULL) || r;
+ r = ((glVertexAttrib1dNV = (PFNGLVERTEXATTRIB1DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dNV")) == NULL) || r;
+ r = ((glVertexAttrib1dvNV = (PFNGLVERTEXATTRIB1DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1dvNV")) == NULL) || r;
+ r = ((glVertexAttrib1fNV = (PFNGLVERTEXATTRIB1FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fNV")) == NULL) || r;
+ r = ((glVertexAttrib1fvNV = (PFNGLVERTEXATTRIB1FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1fvNV")) == NULL) || r;
+ r = ((glVertexAttrib1sNV = (PFNGLVERTEXATTRIB1SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1sNV")) == NULL) || r;
+ r = ((glVertexAttrib1svNV = (PFNGLVERTEXATTRIB1SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib1svNV")) == NULL) || r;
+ r = ((glVertexAttrib2dNV = (PFNGLVERTEXATTRIB2DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dNV")) == NULL) || r;
+ r = ((glVertexAttrib2dvNV = (PFNGLVERTEXATTRIB2DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2dvNV")) == NULL) || r;
+ r = ((glVertexAttrib2fNV = (PFNGLVERTEXATTRIB2FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fNV")) == NULL) || r;
+ r = ((glVertexAttrib2fvNV = (PFNGLVERTEXATTRIB2FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2fvNV")) == NULL) || r;
+ r = ((glVertexAttrib2sNV = (PFNGLVERTEXATTRIB2SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2sNV")) == NULL) || r;
+ r = ((glVertexAttrib2svNV = (PFNGLVERTEXATTRIB2SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib2svNV")) == NULL) || r;
+ r = ((glVertexAttrib3dNV = (PFNGLVERTEXATTRIB3DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dNV")) == NULL) || r;
+ r = ((glVertexAttrib3dvNV = (PFNGLVERTEXATTRIB3DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3dvNV")) == NULL) || r;
+ r = ((glVertexAttrib3fNV = (PFNGLVERTEXATTRIB3FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fNV")) == NULL) || r;
+ r = ((glVertexAttrib3fvNV = (PFNGLVERTEXATTRIB3FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3fvNV")) == NULL) || r;
+ r = ((glVertexAttrib3sNV = (PFNGLVERTEXATTRIB3SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3sNV")) == NULL) || r;
+ r = ((glVertexAttrib3svNV = (PFNGLVERTEXATTRIB3SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib3svNV")) == NULL) || r;
+ r = ((glVertexAttrib4dNV = (PFNGLVERTEXATTRIB4DNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dNV")) == NULL) || r;
+ r = ((glVertexAttrib4dvNV = (PFNGLVERTEXATTRIB4DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4dvNV")) == NULL) || r;
+ r = ((glVertexAttrib4fNV = (PFNGLVERTEXATTRIB4FNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fNV")) == NULL) || r;
+ r = ((glVertexAttrib4fvNV = (PFNGLVERTEXATTRIB4FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4fvNV")) == NULL) || r;
+ r = ((glVertexAttrib4sNV = (PFNGLVERTEXATTRIB4SNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4sNV")) == NULL) || r;
+ r = ((glVertexAttrib4svNV = (PFNGLVERTEXATTRIB4SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4svNV")) == NULL) || r;
+ r = ((glVertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubNV")) == NULL) || r;
+ r = ((glVertexAttrib4ubvNV = (PFNGLVERTEXATTRIB4UBVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttrib4ubvNV")) == NULL) || r;
+ r = ((glVertexAttribPointerNV = (PFNGLVERTEXATTRIBPOINTERNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribPointerNV")) == NULL) || r;
+ r = ((glVertexAttribs1dvNV = (PFNGLVERTEXATTRIBS1DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1dvNV")) == NULL) || r;
+ r = ((glVertexAttribs1fvNV = (PFNGLVERTEXATTRIBS1FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1fvNV")) == NULL) || r;
+ r = ((glVertexAttribs1svNV = (PFNGLVERTEXATTRIBS1SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs1svNV")) == NULL) || r;
+ r = ((glVertexAttribs2dvNV = (PFNGLVERTEXATTRIBS2DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2dvNV")) == NULL) || r;
+ r = ((glVertexAttribs2fvNV = (PFNGLVERTEXATTRIBS2FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2fvNV")) == NULL) || r;
+ r = ((glVertexAttribs2svNV = (PFNGLVERTEXATTRIBS2SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs2svNV")) == NULL) || r;
+ r = ((glVertexAttribs3dvNV = (PFNGLVERTEXATTRIBS3DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3dvNV")) == NULL) || r;
+ r = ((glVertexAttribs3fvNV = (PFNGLVERTEXATTRIBS3FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3fvNV")) == NULL) || r;
+ r = ((glVertexAttribs3svNV = (PFNGLVERTEXATTRIBS3SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs3svNV")) == NULL) || r;
+ r = ((glVertexAttribs4dvNV = (PFNGLVERTEXATTRIBS4DVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4dvNV")) == NULL) || r;
+ r = ((glVertexAttribs4fvNV = (PFNGLVERTEXATTRIBS4FVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4fvNV")) == NULL) || r;
+ r = ((glVertexAttribs4svNV = (PFNGLVERTEXATTRIBS4SVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4svNV")) == NULL) || r;
+ r = ((glVertexAttribs4ubvNV = (PFNGLVERTEXATTRIBS4UBVNVPROC)glewGetProcAddress((const GLubyte*)"glVertexAttribs4ubvNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_vertex_program */
+
+#ifdef GL_NV_vertex_program1_1
+
+#endif /* GL_NV_vertex_program1_1 */
+
+#ifdef GL_NV_vertex_program2
+
+#endif /* GL_NV_vertex_program2 */
+
+#ifdef GL_NV_vertex_program2_option
+
+#endif /* GL_NV_vertex_program2_option */
+
+#ifdef GL_NV_vertex_program3
+
+#endif /* GL_NV_vertex_program3 */
+
+#ifdef GL_NV_vertex_program4
+
+#endif /* GL_NV_vertex_program4 */
+
+#ifdef GL_NV_video_capture
+
+static GLboolean _glewInit_GL_NV_video_capture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glBeginVideoCaptureNV = (PFNGLBEGINVIDEOCAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glBeginVideoCaptureNV")) == NULL) || r;
+ r = ((glBindVideoCaptureStreamBufferNV = (PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC)glewGetProcAddress((const GLubyte*)"glBindVideoCaptureStreamBufferNV")) == NULL) || r;
+ r = ((glBindVideoCaptureStreamTextureNV = (PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC)glewGetProcAddress((const GLubyte*)"glBindVideoCaptureStreamTextureNV")) == NULL) || r;
+ r = ((glEndVideoCaptureNV = (PFNGLENDVIDEOCAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glEndVideoCaptureNV")) == NULL) || r;
+ r = ((glGetVideoCaptureStreamdvNV = (PFNGLGETVIDEOCAPTURESTREAMDVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureStreamdvNV")) == NULL) || r;
+ r = ((glGetVideoCaptureStreamfvNV = (PFNGLGETVIDEOCAPTURESTREAMFVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureStreamfvNV")) == NULL) || r;
+ r = ((glGetVideoCaptureStreamivNV = (PFNGLGETVIDEOCAPTURESTREAMIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureStreamivNV")) == NULL) || r;
+ r = ((glGetVideoCaptureivNV = (PFNGLGETVIDEOCAPTUREIVNVPROC)glewGetProcAddress((const GLubyte*)"glGetVideoCaptureivNV")) == NULL) || r;
+ r = ((glVideoCaptureNV = (PFNGLVIDEOCAPTURENVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureNV")) == NULL) || r;
+ r = ((glVideoCaptureStreamParameterdvNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureStreamParameterdvNV")) == NULL) || r;
+ r = ((glVideoCaptureStreamParameterfvNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureStreamParameterfvNV")) == NULL) || r;
+ r = ((glVideoCaptureStreamParameterivNV = (PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC)glewGetProcAddress((const GLubyte*)"glVideoCaptureStreamParameterivNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_NV_video_capture */
+
+#ifdef GL_OES_byte_coordinates
+
+#endif /* GL_OES_byte_coordinates */
+
+#ifdef GL_OES_compressed_paletted_texture
+
+#endif /* GL_OES_compressed_paletted_texture */
+
+#ifdef GL_OES_read_format
+
+#endif /* GL_OES_read_format */
+
+#ifdef GL_OES_single_precision
+
+static GLboolean _glewInit_GL_OES_single_precision (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClearDepthfOES = (PFNGLCLEARDEPTHFOESPROC)glewGetProcAddress((const GLubyte*)"glClearDepthfOES")) == NULL) || r;
+ r = ((glClipPlanefOES = (PFNGLCLIPPLANEFOESPROC)glewGetProcAddress((const GLubyte*)"glClipPlanefOES")) == NULL) || r;
+ r = ((glDepthRangefOES = (PFNGLDEPTHRANGEFOESPROC)glewGetProcAddress((const GLubyte*)"glDepthRangefOES")) == NULL) || r;
+ r = ((glFrustumfOES = (PFNGLFRUSTUMFOESPROC)glewGetProcAddress((const GLubyte*)"glFrustumfOES")) == NULL) || r;
+ r = ((glGetClipPlanefOES = (PFNGLGETCLIPPLANEFOESPROC)glewGetProcAddress((const GLubyte*)"glGetClipPlanefOES")) == NULL) || r;
+ r = ((glOrthofOES = (PFNGLORTHOFOESPROC)glewGetProcAddress((const GLubyte*)"glOrthofOES")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_OES_single_precision */
+
+#ifdef GL_OML_interlace
+
+#endif /* GL_OML_interlace */
+
+#ifdef GL_OML_resample
+
+#endif /* GL_OML_resample */
+
+#ifdef GL_OML_subsample
+
+#endif /* GL_OML_subsample */
+
+#ifdef GL_PGI_misc_hints
+
+#endif /* GL_PGI_misc_hints */
+
+#ifdef GL_PGI_vertex_hints
+
+#endif /* GL_PGI_vertex_hints */
+
+#ifdef GL_REGAL_ES1_0_compatibility
+
+static GLboolean _glewInit_GL_REGAL_ES1_0_compatibility (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAlphaFuncx = (PFNGLALPHAFUNCXPROC)glewGetProcAddress((const GLubyte*)"glAlphaFuncx")) == NULL) || r;
+ r = ((glClearColorx = (PFNGLCLEARCOLORXPROC)glewGetProcAddress((const GLubyte*)"glClearColorx")) == NULL) || r;
+ r = ((glClearDepthx = (PFNGLCLEARDEPTHXPROC)glewGetProcAddress((const GLubyte*)"glClearDepthx")) == NULL) || r;
+ r = ((glColor4x = (PFNGLCOLOR4XPROC)glewGetProcAddress((const GLubyte*)"glColor4x")) == NULL) || r;
+ r = ((glDepthRangex = (PFNGLDEPTHRANGEXPROC)glewGetProcAddress((const GLubyte*)"glDepthRangex")) == NULL) || r;
+ r = ((glFogx = (PFNGLFOGXPROC)glewGetProcAddress((const GLubyte*)"glFogx")) == NULL) || r;
+ r = ((glFogxv = (PFNGLFOGXVPROC)glewGetProcAddress((const GLubyte*)"glFogxv")) == NULL) || r;
+ r = ((glFrustumf = (PFNGLFRUSTUMFPROC)glewGetProcAddress((const GLubyte*)"glFrustumf")) == NULL) || r;
+ r = ((glFrustumx = (PFNGLFRUSTUMXPROC)glewGetProcAddress((const GLubyte*)"glFrustumx")) == NULL) || r;
+ r = ((glLightModelx = (PFNGLLIGHTMODELXPROC)glewGetProcAddress((const GLubyte*)"glLightModelx")) == NULL) || r;
+ r = ((glLightModelxv = (PFNGLLIGHTMODELXVPROC)glewGetProcAddress((const GLubyte*)"glLightModelxv")) == NULL) || r;
+ r = ((glLightx = (PFNGLLIGHTXPROC)glewGetProcAddress((const GLubyte*)"glLightx")) == NULL) || r;
+ r = ((glLightxv = (PFNGLLIGHTXVPROC)glewGetProcAddress((const GLubyte*)"glLightxv")) == NULL) || r;
+ r = ((glLineWidthx = (PFNGLLINEWIDTHXPROC)glewGetProcAddress((const GLubyte*)"glLineWidthx")) == NULL) || r;
+ r = ((glLoadMatrixx = (PFNGLLOADMATRIXXPROC)glewGetProcAddress((const GLubyte*)"glLoadMatrixx")) == NULL) || r;
+ r = ((glMaterialx = (PFNGLMATERIALXPROC)glewGetProcAddress((const GLubyte*)"glMaterialx")) == NULL) || r;
+ r = ((glMaterialxv = (PFNGLMATERIALXVPROC)glewGetProcAddress((const GLubyte*)"glMaterialxv")) == NULL) || r;
+ r = ((glMultMatrixx = (PFNGLMULTMATRIXXPROC)glewGetProcAddress((const GLubyte*)"glMultMatrixx")) == NULL) || r;
+ r = ((glMultiTexCoord4x = (PFNGLMULTITEXCOORD4XPROC)glewGetProcAddress((const GLubyte*)"glMultiTexCoord4x")) == NULL) || r;
+ r = ((glNormal3x = (PFNGLNORMAL3XPROC)glewGetProcAddress((const GLubyte*)"glNormal3x")) == NULL) || r;
+ r = ((glOrthof = (PFNGLORTHOFPROC)glewGetProcAddress((const GLubyte*)"glOrthof")) == NULL) || r;
+ r = ((glOrthox = (PFNGLORTHOXPROC)glewGetProcAddress((const GLubyte*)"glOrthox")) == NULL) || r;
+ r = ((glPointSizex = (PFNGLPOINTSIZEXPROC)glewGetProcAddress((const GLubyte*)"glPointSizex")) == NULL) || r;
+ r = ((glPolygonOffsetx = (PFNGLPOLYGONOFFSETXPROC)glewGetProcAddress((const GLubyte*)"glPolygonOffsetx")) == NULL) || r;
+ r = ((glRotatex = (PFNGLROTATEXPROC)glewGetProcAddress((const GLubyte*)"glRotatex")) == NULL) || r;
+ r = ((glSampleCoveragex = (PFNGLSAMPLECOVERAGEXPROC)glewGetProcAddress((const GLubyte*)"glSampleCoveragex")) == NULL) || r;
+ r = ((glScalex = (PFNGLSCALEXPROC)glewGetProcAddress((const GLubyte*)"glScalex")) == NULL) || r;
+ r = ((glTexEnvx = (PFNGLTEXENVXPROC)glewGetProcAddress((const GLubyte*)"glTexEnvx")) == NULL) || r;
+ r = ((glTexEnvxv = (PFNGLTEXENVXVPROC)glewGetProcAddress((const GLubyte*)"glTexEnvxv")) == NULL) || r;
+ r = ((glTexParameterx = (PFNGLTEXPARAMETERXPROC)glewGetProcAddress((const GLubyte*)"glTexParameterx")) == NULL) || r;
+ r = ((glTranslatex = (PFNGLTRANSLATEXPROC)glewGetProcAddress((const GLubyte*)"glTranslatex")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_REGAL_ES1_0_compatibility */
+
+#ifdef GL_REGAL_ES1_1_compatibility
+
+static GLboolean _glewInit_GL_REGAL_ES1_1_compatibility (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glClipPlanef = (PFNGLCLIPPLANEFPROC)glewGetProcAddress((const GLubyte*)"glClipPlanef")) == NULL) || r;
+ r = ((glClipPlanex = (PFNGLCLIPPLANEXPROC)glewGetProcAddress((const GLubyte*)"glClipPlanex")) == NULL) || r;
+ r = ((glGetClipPlanef = (PFNGLGETCLIPPLANEFPROC)glewGetProcAddress((const GLubyte*)"glGetClipPlanef")) == NULL) || r;
+ r = ((glGetClipPlanex = (PFNGLGETCLIPPLANEXPROC)glewGetProcAddress((const GLubyte*)"glGetClipPlanex")) == NULL) || r;
+ r = ((glGetFixedv = (PFNGLGETFIXEDVPROC)glewGetProcAddress((const GLubyte*)"glGetFixedv")) == NULL) || r;
+ r = ((glGetLightxv = (PFNGLGETLIGHTXVPROC)glewGetProcAddress((const GLubyte*)"glGetLightxv")) == NULL) || r;
+ r = ((glGetMaterialxv = (PFNGLGETMATERIALXVPROC)glewGetProcAddress((const GLubyte*)"glGetMaterialxv")) == NULL) || r;
+ r = ((glGetTexEnvxv = (PFNGLGETTEXENVXVPROC)glewGetProcAddress((const GLubyte*)"glGetTexEnvxv")) == NULL) || r;
+ r = ((glGetTexParameterxv = (PFNGLGETTEXPARAMETERXVPROC)glewGetProcAddress((const GLubyte*)"glGetTexParameterxv")) == NULL) || r;
+ r = ((glPointParameterx = (PFNGLPOINTPARAMETERXPROC)glewGetProcAddress((const GLubyte*)"glPointParameterx")) == NULL) || r;
+ r = ((glPointParameterxv = (PFNGLPOINTPARAMETERXVPROC)glewGetProcAddress((const GLubyte*)"glPointParameterxv")) == NULL) || r;
+ r = ((glPointSizePointerOES = (PFNGLPOINTSIZEPOINTEROESPROC)glewGetProcAddress((const GLubyte*)"glPointSizePointerOES")) == NULL) || r;
+ r = ((glTexParameterxv = (PFNGLTEXPARAMETERXVPROC)glewGetProcAddress((const GLubyte*)"glTexParameterxv")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_REGAL_ES1_1_compatibility */
+
+#ifdef GL_REGAL_enable
+
+#endif /* GL_REGAL_enable */
+
+#ifdef GL_REGAL_error_string
+
+static GLboolean _glewInit_GL_REGAL_error_string (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glErrorStringREGAL = (PFNGLERRORSTRINGREGALPROC)glewGetProcAddress((const GLubyte*)"glErrorStringREGAL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_REGAL_error_string */
+
+#ifdef GL_REGAL_extension_query
+
+static GLboolean _glewInit_GL_REGAL_extension_query (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetExtensionREGAL = (PFNGLGETEXTENSIONREGALPROC)glewGetProcAddress((const GLubyte*)"glGetExtensionREGAL")) == NULL) || r;
+ r = ((glIsSupportedREGAL = (PFNGLISSUPPORTEDREGALPROC)glewGetProcAddress((const GLubyte*)"glIsSupportedREGAL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_REGAL_extension_query */
+
+#ifdef GL_REGAL_log
+
+static GLboolean _glewInit_GL_REGAL_log (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glLogMessageCallbackREGAL = (PFNGLLOGMESSAGECALLBACKREGALPROC)glewGetProcAddress((const GLubyte*)"glLogMessageCallbackREGAL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_REGAL_log */
+
+#ifdef GL_REND_screen_coordinates
+
+#endif /* GL_REND_screen_coordinates */
+
+#ifdef GL_S3_s3tc
+
+#endif /* GL_S3_s3tc */
+
+#ifdef GL_SGIS_color_range
+
+#endif /* GL_SGIS_color_range */
+
+#ifdef GL_SGIS_detail_texture
+
+static GLboolean _glewInit_GL_SGIS_detail_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glDetailTexFuncSGIS = (PFNGLDETAILTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glDetailTexFuncSGIS")) == NULL) || r;
+ r = ((glGetDetailTexFuncSGIS = (PFNGLGETDETAILTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetDetailTexFuncSGIS")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIS_detail_texture */
+
+#ifdef GL_SGIS_fog_function
+
+static GLboolean _glewInit_GL_SGIS_fog_function (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFogFuncSGIS = (PFNGLFOGFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glFogFuncSGIS")) == NULL) || r;
+ r = ((glGetFogFuncSGIS = (PFNGLGETFOGFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetFogFuncSGIS")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIS_fog_function */
+
+#ifdef GL_SGIS_generate_mipmap
+
+#endif /* GL_SGIS_generate_mipmap */
+
+#ifdef GL_SGIS_multisample
+
+static GLboolean _glewInit_GL_SGIS_multisample (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSampleMaskSGIS = (PFNGLSAMPLEMASKSGISPROC)glewGetProcAddress((const GLubyte*)"glSampleMaskSGIS")) == NULL) || r;
+ r = ((glSamplePatternSGIS = (PFNGLSAMPLEPATTERNSGISPROC)glewGetProcAddress((const GLubyte*)"glSamplePatternSGIS")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIS_multisample */
+
+#ifdef GL_SGIS_pixel_texture
+
+#endif /* GL_SGIS_pixel_texture */
+
+#ifdef GL_SGIS_point_line_texgen
+
+#endif /* GL_SGIS_point_line_texgen */
+
+#ifdef GL_SGIS_sharpen_texture
+
+static GLboolean _glewInit_GL_SGIS_sharpen_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetSharpenTexFuncSGIS = (PFNGLGETSHARPENTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetSharpenTexFuncSGIS")) == NULL) || r;
+ r = ((glSharpenTexFuncSGIS = (PFNGLSHARPENTEXFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glSharpenTexFuncSGIS")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIS_sharpen_texture */
+
+#ifdef GL_SGIS_texture4D
+
+static GLboolean _glewInit_GL_SGIS_texture4D (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTexImage4DSGIS = (PFNGLTEXIMAGE4DSGISPROC)glewGetProcAddress((const GLubyte*)"glTexImage4DSGIS")) == NULL) || r;
+ r = ((glTexSubImage4DSGIS = (PFNGLTEXSUBIMAGE4DSGISPROC)glewGetProcAddress((const GLubyte*)"glTexSubImage4DSGIS")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIS_texture4D */
+
+#ifdef GL_SGIS_texture_border_clamp
+
+#endif /* GL_SGIS_texture_border_clamp */
+
+#ifdef GL_SGIS_texture_edge_clamp
+
+#endif /* GL_SGIS_texture_edge_clamp */
+
+#ifdef GL_SGIS_texture_filter4
+
+static GLboolean _glewInit_GL_SGIS_texture_filter4 (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGetTexFilterFuncSGIS = (PFNGLGETTEXFILTERFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glGetTexFilterFuncSGIS")) == NULL) || r;
+ r = ((glTexFilterFuncSGIS = (PFNGLTEXFILTERFUNCSGISPROC)glewGetProcAddress((const GLubyte*)"glTexFilterFuncSGIS")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIS_texture_filter4 */
+
+#ifdef GL_SGIS_texture_lod
+
+#endif /* GL_SGIS_texture_lod */
+
+#ifdef GL_SGIS_texture_select
+
+#endif /* GL_SGIS_texture_select */
+
+#ifdef GL_SGIX_async
+
+static GLboolean _glewInit_GL_SGIX_async (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAsyncMarkerSGIX = (PFNGLASYNCMARKERSGIXPROC)glewGetProcAddress((const GLubyte*)"glAsyncMarkerSGIX")) == NULL) || r;
+ r = ((glDeleteAsyncMarkersSGIX = (PFNGLDELETEASYNCMARKERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glDeleteAsyncMarkersSGIX")) == NULL) || r;
+ r = ((glFinishAsyncSGIX = (PFNGLFINISHASYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glFinishAsyncSGIX")) == NULL) || r;
+ r = ((glGenAsyncMarkersSGIX = (PFNGLGENASYNCMARKERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glGenAsyncMarkersSGIX")) == NULL) || r;
+ r = ((glIsAsyncMarkerSGIX = (PFNGLISASYNCMARKERSGIXPROC)glewGetProcAddress((const GLubyte*)"glIsAsyncMarkerSGIX")) == NULL) || r;
+ r = ((glPollAsyncSGIX = (PFNGLPOLLASYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glPollAsyncSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_async */
+
+#ifdef GL_SGIX_async_histogram
+
+#endif /* GL_SGIX_async_histogram */
+
+#ifdef GL_SGIX_async_pixel
+
+#endif /* GL_SGIX_async_pixel */
+
+#ifdef GL_SGIX_blend_alpha_minmax
+
+#endif /* GL_SGIX_blend_alpha_minmax */
+
+#ifdef GL_SGIX_clipmap
+
+#endif /* GL_SGIX_clipmap */
+
+#ifdef GL_SGIX_convolution_accuracy
+
+#endif /* GL_SGIX_convolution_accuracy */
+
+#ifdef GL_SGIX_depth_texture
+
+#endif /* GL_SGIX_depth_texture */
+
+#ifdef GL_SGIX_flush_raster
+
+static GLboolean _glewInit_GL_SGIX_flush_raster (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFlushRasterSGIX = (PFNGLFLUSHRASTERSGIXPROC)glewGetProcAddress((const GLubyte*)"glFlushRasterSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_flush_raster */
+
+#ifdef GL_SGIX_fog_offset
+
+#endif /* GL_SGIX_fog_offset */
+
+#ifdef GL_SGIX_fog_texture
+
+static GLboolean _glewInit_GL_SGIX_fog_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTextureFogSGIX = (PFNGLTEXTUREFOGSGIXPROC)glewGetProcAddress((const GLubyte*)"glTextureFogSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_fog_texture */
+
+#ifdef GL_SGIX_fragment_specular_lighting
+
+static GLboolean _glewInit_GL_SGIX_fragment_specular_lighting (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFragmentColorMaterialSGIX = (PFNGLFRAGMENTCOLORMATERIALSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentColorMaterialSGIX")) == NULL) || r;
+ r = ((glFragmentLightModelfSGIX = (PFNGLFRAGMENTLIGHTMODELFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfSGIX")) == NULL) || r;
+ r = ((glFragmentLightModelfvSGIX = (PFNGLFRAGMENTLIGHTMODELFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelfvSGIX")) == NULL) || r;
+ r = ((glFragmentLightModeliSGIX = (PFNGLFRAGMENTLIGHTMODELISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModeliSGIX")) == NULL) || r;
+ r = ((glFragmentLightModelivSGIX = (PFNGLFRAGMENTLIGHTMODELIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightModelivSGIX")) == NULL) || r;
+ r = ((glFragmentLightfSGIX = (PFNGLFRAGMENTLIGHTFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfSGIX")) == NULL) || r;
+ r = ((glFragmentLightfvSGIX = (PFNGLFRAGMENTLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightfvSGIX")) == NULL) || r;
+ r = ((glFragmentLightiSGIX = (PFNGLFRAGMENTLIGHTISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightiSGIX")) == NULL) || r;
+ r = ((glFragmentLightivSGIX = (PFNGLFRAGMENTLIGHTIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentLightivSGIX")) == NULL) || r;
+ r = ((glFragmentMaterialfSGIX = (PFNGLFRAGMENTMATERIALFSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfSGIX")) == NULL) || r;
+ r = ((glFragmentMaterialfvSGIX = (PFNGLFRAGMENTMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialfvSGIX")) == NULL) || r;
+ r = ((glFragmentMaterialiSGIX = (PFNGLFRAGMENTMATERIALISGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialiSGIX")) == NULL) || r;
+ r = ((glFragmentMaterialivSGIX = (PFNGLFRAGMENTMATERIALIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glFragmentMaterialivSGIX")) == NULL) || r;
+ r = ((glGetFragmentLightfvSGIX = (PFNGLGETFRAGMENTLIGHTFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightfvSGIX")) == NULL) || r;
+ r = ((glGetFragmentLightivSGIX = (PFNGLGETFRAGMENTLIGHTIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentLightivSGIX")) == NULL) || r;
+ r = ((glGetFragmentMaterialfvSGIX = (PFNGLGETFRAGMENTMATERIALFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialfvSGIX")) == NULL) || r;
+ r = ((glGetFragmentMaterialivSGIX = (PFNGLGETFRAGMENTMATERIALIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glGetFragmentMaterialivSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_fragment_specular_lighting */
+
+#ifdef GL_SGIX_framezoom
+
+static GLboolean _glewInit_GL_SGIX_framezoom (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFrameZoomSGIX = (PFNGLFRAMEZOOMSGIXPROC)glewGetProcAddress((const GLubyte*)"glFrameZoomSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_framezoom */
+
+#ifdef GL_SGIX_interlace
+
+#endif /* GL_SGIX_interlace */
+
+#ifdef GL_SGIX_ir_instrument1
+
+#endif /* GL_SGIX_ir_instrument1 */
+
+#ifdef GL_SGIX_list_priority
+
+#endif /* GL_SGIX_list_priority */
+
+#ifdef GL_SGIX_pixel_texture
+
+static GLboolean _glewInit_GL_SGIX_pixel_texture (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glPixelTexGenSGIX = (PFNGLPIXELTEXGENSGIXPROC)glewGetProcAddress((const GLubyte*)"glPixelTexGenSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_pixel_texture */
+
+#ifdef GL_SGIX_pixel_texture_bits
+
+#endif /* GL_SGIX_pixel_texture_bits */
+
+#ifdef GL_SGIX_reference_plane
+
+static GLboolean _glewInit_GL_SGIX_reference_plane (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glReferencePlaneSGIX = (PFNGLREFERENCEPLANESGIXPROC)glewGetProcAddress((const GLubyte*)"glReferencePlaneSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_reference_plane */
+
+#ifdef GL_SGIX_resample
+
+#endif /* GL_SGIX_resample */
+
+#ifdef GL_SGIX_shadow
+
+#endif /* GL_SGIX_shadow */
+
+#ifdef GL_SGIX_shadow_ambient
+
+#endif /* GL_SGIX_shadow_ambient */
+
+#ifdef GL_SGIX_sprite
+
+static GLboolean _glewInit_GL_SGIX_sprite (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glSpriteParameterfSGIX = (PFNGLSPRITEPARAMETERFSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterfSGIX")) == NULL) || r;
+ r = ((glSpriteParameterfvSGIX = (PFNGLSPRITEPARAMETERFVSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterfvSGIX")) == NULL) || r;
+ r = ((glSpriteParameteriSGIX = (PFNGLSPRITEPARAMETERISGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameteriSGIX")) == NULL) || r;
+ r = ((glSpriteParameterivSGIX = (PFNGLSPRITEPARAMETERIVSGIXPROC)glewGetProcAddress((const GLubyte*)"glSpriteParameterivSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_sprite */
+
+#ifdef GL_SGIX_tag_sample_buffer
+
+static GLboolean _glewInit_GL_SGIX_tag_sample_buffer (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glTagSampleBufferSGIX = (PFNGLTAGSAMPLEBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glTagSampleBufferSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGIX_tag_sample_buffer */
+
+#ifdef GL_SGIX_texture_add_env
+
+#endif /* GL_SGIX_texture_add_env */
+
+#ifdef GL_SGIX_texture_coordinate_clamp
+
+#endif /* GL_SGIX_texture_coordinate_clamp */
+
+#ifdef GL_SGIX_texture_lod_bias
+
+#endif /* GL_SGIX_texture_lod_bias */
+
+#ifdef GL_SGIX_texture_multi_buffer
+
+#endif /* GL_SGIX_texture_multi_buffer */
+
+#ifdef GL_SGIX_texture_range
+
+#endif /* GL_SGIX_texture_range */
+
+#ifdef GL_SGIX_texture_scale_bias
+
+#endif /* GL_SGIX_texture_scale_bias */
+
+#ifdef GL_SGIX_vertex_preclip
+
+#endif /* GL_SGIX_vertex_preclip */
+
+#ifdef GL_SGIX_vertex_preclip_hint
+
+#endif /* GL_SGIX_vertex_preclip_hint */
+
+#ifdef GL_SGIX_ycrcb
+
+#endif /* GL_SGIX_ycrcb */
+
+#ifdef GL_SGI_color_matrix
+
+#endif /* GL_SGI_color_matrix */
+
+#ifdef GL_SGI_color_table
+
+static GLboolean _glewInit_GL_SGI_color_table (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColorTableParameterfvSGI = (PFNGLCOLORTABLEPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterfvSGI")) == NULL) || r;
+ r = ((glColorTableParameterivSGI = (PFNGLCOLORTABLEPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableParameterivSGI")) == NULL) || r;
+ r = ((glColorTableSGI = (PFNGLCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glColorTableSGI")) == NULL) || r;
+ r = ((glCopyColorTableSGI = (PFNGLCOPYCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glCopyColorTableSGI")) == NULL) || r;
+ r = ((glGetColorTableParameterfvSGI = (PFNGLGETCOLORTABLEPARAMETERFVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterfvSGI")) == NULL) || r;
+ r = ((glGetColorTableParameterivSGI = (PFNGLGETCOLORTABLEPARAMETERIVSGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableParameterivSGI")) == NULL) || r;
+ r = ((glGetColorTableSGI = (PFNGLGETCOLORTABLESGIPROC)glewGetProcAddress((const GLubyte*)"glGetColorTableSGI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SGI_color_table */
+
+#ifdef GL_SGI_texture_color_table
+
+#endif /* GL_SGI_texture_color_table */
+
+#ifdef GL_SUNX_constant_data
+
+static GLboolean _glewInit_GL_SUNX_constant_data (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glFinishTextureSUNX = (PFNGLFINISHTEXTURESUNXPROC)glewGetProcAddress((const GLubyte*)"glFinishTextureSUNX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SUNX_constant_data */
+
+#ifdef GL_SUN_convolution_border_modes
+
+#endif /* GL_SUN_convolution_border_modes */
+
+#ifdef GL_SUN_global_alpha
+
+static GLboolean _glewInit_GL_SUN_global_alpha (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glGlobalAlphaFactorbSUN = (PFNGLGLOBALALPHAFACTORBSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorbSUN")) == NULL) || r;
+ r = ((glGlobalAlphaFactordSUN = (PFNGLGLOBALALPHAFACTORDSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactordSUN")) == NULL) || r;
+ r = ((glGlobalAlphaFactorfSUN = (PFNGLGLOBALALPHAFACTORFSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorfSUN")) == NULL) || r;
+ r = ((glGlobalAlphaFactoriSUN = (PFNGLGLOBALALPHAFACTORISUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactoriSUN")) == NULL) || r;
+ r = ((glGlobalAlphaFactorsSUN = (PFNGLGLOBALALPHAFACTORSSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorsSUN")) == NULL) || r;
+ r = ((glGlobalAlphaFactorubSUN = (PFNGLGLOBALALPHAFACTORUBSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorubSUN")) == NULL) || r;
+ r = ((glGlobalAlphaFactoruiSUN = (PFNGLGLOBALALPHAFACTORUISUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactoruiSUN")) == NULL) || r;
+ r = ((glGlobalAlphaFactorusSUN = (PFNGLGLOBALALPHAFACTORUSSUNPROC)glewGetProcAddress((const GLubyte*)"glGlobalAlphaFactorusSUN")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SUN_global_alpha */
+
+#ifdef GL_SUN_mesh_array
+
+#endif /* GL_SUN_mesh_array */
+
+#ifdef GL_SUN_read_video_pixels
+
+static GLboolean _glewInit_GL_SUN_read_video_pixels (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glReadVideoPixelsSUN = (PFNGLREADVIDEOPIXELSSUNPROC)glewGetProcAddress((const GLubyte*)"glReadVideoPixelsSUN")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SUN_read_video_pixels */
+
+#ifdef GL_SUN_slice_accum
+
+#endif /* GL_SUN_slice_accum */
+
+#ifdef GL_SUN_triangle_list
+
+static GLboolean _glewInit_GL_SUN_triangle_list (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glReplacementCodePointerSUN = (PFNGLREPLACEMENTCODEPOINTERSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodePointerSUN")) == NULL) || r;
+ r = ((glReplacementCodeubSUN = (PFNGLREPLACEMENTCODEUBSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeubSUN")) == NULL) || r;
+ r = ((glReplacementCodeubvSUN = (PFNGLREPLACEMENTCODEUBVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeubvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiSUN = (PFNGLREPLACEMENTCODEUISUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiSUN")) == NULL) || r;
+ r = ((glReplacementCodeuivSUN = (PFNGLREPLACEMENTCODEUIVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuivSUN")) == NULL) || r;
+ r = ((glReplacementCodeusSUN = (PFNGLREPLACEMENTCODEUSSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeusSUN")) == NULL) || r;
+ r = ((glReplacementCodeusvSUN = (PFNGLREPLACEMENTCODEUSVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeusvSUN")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SUN_triangle_list */
+
+#ifdef GL_SUN_vertex
+
+static GLboolean _glewInit_GL_SUN_vertex (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glColor3fVertex3fSUN = (PFNGLCOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor3fVertex3fSUN")) == NULL) || r;
+ r = ((glColor3fVertex3fvSUN = (PFNGLCOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor3fVertex3fvSUN")) == NULL) || r;
+ r = ((glColor4fNormal3fVertex3fSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4fNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glColor4fNormal3fVertex3fvSUN = (PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4fNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glColor4ubVertex2fSUN = (PFNGLCOLOR4UBVERTEX2FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex2fSUN")) == NULL) || r;
+ r = ((glColor4ubVertex2fvSUN = (PFNGLCOLOR4UBVERTEX2FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex2fvSUN")) == NULL) || r;
+ r = ((glColor4ubVertex3fSUN = (PFNGLCOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex3fSUN")) == NULL) || r;
+ r = ((glColor4ubVertex3fvSUN = (PFNGLCOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glColor4ubVertex3fvSUN")) == NULL) || r;
+ r = ((glNormal3fVertex3fSUN = (PFNGLNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glNormal3fVertex3fvSUN = (PFNGLNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiColor3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor3fVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiColor3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor3fVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4fNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4fNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiColor4ubVertex3fSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4ubVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiColor4ubVertex3fvSUN = (PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiColor4ubVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiTexCoord2fVertex3fSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiTexCoord2fVertex3fvSUN = (PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiTexCoord2fVertex3fvSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiVertex3fSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiVertex3fSUN")) == NULL) || r;
+ r = ((glReplacementCodeuiVertex3fvSUN = (PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glReplacementCodeuiVertex3fvSUN")) == NULL) || r;
+ r = ((glTexCoord2fColor3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor3fVertex3fSUN")) == NULL) || r;
+ r = ((glTexCoord2fColor3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor3fVertex3fvSUN")) == NULL) || r;
+ r = ((glTexCoord2fColor4fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4fNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glTexCoord2fColor4fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4fNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glTexCoord2fColor4ubVertex3fSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4ubVertex3fSUN")) == NULL) || r;
+ r = ((glTexCoord2fColor4ubVertex3fvSUN = (PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fColor4ubVertex3fvSUN")) == NULL) || r;
+ r = ((glTexCoord2fNormal3fVertex3fSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fNormal3fVertex3fSUN")) == NULL) || r;
+ r = ((glTexCoord2fNormal3fVertex3fvSUN = (PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fNormal3fVertex3fvSUN")) == NULL) || r;
+ r = ((glTexCoord2fVertex3fSUN = (PFNGLTEXCOORD2FVERTEX3FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fVertex3fSUN")) == NULL) || r;
+ r = ((glTexCoord2fVertex3fvSUN = (PFNGLTEXCOORD2FVERTEX3FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord2fVertex3fvSUN")) == NULL) || r;
+ r = ((glTexCoord4fColor4fNormal3fVertex4fSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fColor4fNormal3fVertex4fSUN")) == NULL) || r;
+ r = ((glTexCoord4fColor4fNormal3fVertex4fvSUN = (PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fColor4fNormal3fVertex4fvSUN")) == NULL) || r;
+ r = ((glTexCoord4fVertex4fSUN = (PFNGLTEXCOORD4FVERTEX4FSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fVertex4fSUN")) == NULL) || r;
+ r = ((glTexCoord4fVertex4fvSUN = (PFNGLTEXCOORD4FVERTEX4FVSUNPROC)glewGetProcAddress((const GLubyte*)"glTexCoord4fVertex4fvSUN")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_SUN_vertex */
+
+#ifdef GL_WIN_phong_shading
+
+#endif /* GL_WIN_phong_shading */
+
+#ifdef GL_WIN_specular_fog
+
+#endif /* GL_WIN_specular_fog */
+
+#ifdef GL_WIN_swap_hint
+
+static GLboolean _glewInit_GL_WIN_swap_hint (GLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAddSwapHintRectWIN = (PFNGLADDSWAPHINTRECTWINPROC)glewGetProcAddress((const GLubyte*)"glAddSwapHintRectWIN")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GL_WIN_swap_hint */
+
+/* ------------------------------------------------------------------------- */
+
+GLboolean GLEWAPIENTRY glewGetExtension (const char* name)
+{
+ const GLubyte* start;
+ const GLubyte* end;
+ start = (const GLubyte*)glGetString(GL_EXTENSIONS);
+ if (start == 0)
+ return GL_FALSE;
+ end = start + _glewStrLen(start);
+ return _glewSearchExtension(name, start, end);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#ifndef GLEW_MX
+static
+#endif
+GLenum GLEWAPIENTRY glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST)
+{
+ const GLubyte* s;
+ GLuint dot;
+ GLint major, minor;
+ const GLubyte* extStart;
+ const GLubyte* extEnd;
+ /* query opengl version */
+ s = glGetString(GL_VERSION);
+ dot = _glewStrCLen(s, '.');
+ if (dot == 0)
+ return GLEW_ERROR_NO_GL_VERSION;
+
+ major = s[dot-1]-'0';
+ minor = s[dot+1]-'0';
+
+ if (minor < 0 || minor > 9)
+ minor = 0;
+ if (major<0 || major>9)
+ return GLEW_ERROR_NO_GL_VERSION;
+
+
+ if (major == 1 && minor == 0)
+ {
+ return GLEW_ERROR_GL_VERSION_10_ONLY;
+ }
+ else
+ {
+ CONST_CAST(GLEW_VERSION_4_4) = ( major > 4 ) || ( major == 4 && minor >= 4 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_4_3) = GLEW_VERSION_4_4 == GL_TRUE || ( major == 4 && minor >= 3 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_4_2) = GLEW_VERSION_4_3 == GL_TRUE || ( major == 4 && minor >= 2 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_4_1) = GLEW_VERSION_4_2 == GL_TRUE || ( major == 4 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_4_0) = GLEW_VERSION_4_1 == GL_TRUE || ( major == 4 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_3_3) = GLEW_VERSION_4_0 == GL_TRUE || ( major == 3 && minor >= 3 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_3_2) = GLEW_VERSION_3_3 == GL_TRUE || ( major == 3 && minor >= 2 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_3_1) = GLEW_VERSION_3_2 == GL_TRUE || ( major == 3 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_3_0) = GLEW_VERSION_3_1 == GL_TRUE || ( major == 3 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_2_1) = GLEW_VERSION_3_0 == GL_TRUE || ( major == 2 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_2_0) = GLEW_VERSION_2_1 == GL_TRUE || ( major == 2 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_1_5) = GLEW_VERSION_2_0 == GL_TRUE || ( major == 1 && minor >= 5 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_1_4) = GLEW_VERSION_1_5 == GL_TRUE || ( major == 1 && minor >= 4 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_1_3) = GLEW_VERSION_1_4 == GL_TRUE || ( major == 1 && minor >= 3 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_1_2_1) = GLEW_VERSION_1_3 == GL_TRUE ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_1_2) = GLEW_VERSION_1_2_1 == GL_TRUE || ( major == 1 && minor >= 2 ) ? GL_TRUE : GL_FALSE;
+ CONST_CAST(GLEW_VERSION_1_1) = GLEW_VERSION_1_2 == GL_TRUE || ( major == 1 && minor >= 1 ) ? GL_TRUE : GL_FALSE;
+ }
+
+ /* query opengl extensions string */
+ extStart = glGetString(GL_EXTENSIONS);
+ if (extStart == 0)
+ extStart = (const GLubyte*)"";
+ extEnd = extStart + _glewStrLen(extStart);
+
+ /* initialize extensions */
+#ifdef GL_VERSION_1_2
+ if (glewExperimental || GLEW_VERSION_1_2) CONST_CAST(GLEW_VERSION_1_2) = !_glewInit_GL_VERSION_1_2(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_VERSION_1_2 */
+#ifdef GL_VERSION_1_2_1
+#endif /* GL_VERSION_1_2_1 */
+#ifdef GL_VERSION_1_3
+ if (glewExperimental || GLEW_VERSION_1_3) CONST_CAST(GLEW_VERSION_1_3) = !_glewInit_GL_VERSION_1_3(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_VERSION_1_3 */
+#ifdef GL_VERSION_1_4
+ if (glewExperimental || GLEW_VERSION_1_4) CONST_CAST(GLEW_VERSION_1_4) = !_glewInit_GL_VERSION_1_4(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_VERSION_1_4 */
+#ifdef GL_VERSION_1_5
+ if (glewExperimental || GLEW_VERSION_1_5) CONST_CAST(GLEW_VERSION_1_5) = !_glewInit_GL_VERSION_1_5(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_VERSION_1_5 */
+#ifdef GL_VERSION_2_0
+ if (glewExperimental || GLEW_VERSION_2_0) CONST_CAST(GLEW_VERSION_2_0) = !_glewInit_GL_VERSION_2_0(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_VERSION_2_0 */
+#ifdef GL_VERSION_2_1
+ if (glewExperimental || GLEW_VERSION_2_1) CONST_CAST(GLEW_VERSION_2_1) = !_glewInit_GL_VERSION_2_1(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_VERSION_2_1 */
+#ifdef GL_VERSION_3_0
+ if (glewExperimental || GLEW_VERSION_3_0) CONST_CAST(GLEW_VERSION_3_0) = !_glewInit_GL_VERSION_3_0(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_VERSION_3_0 */
+#ifdef GL_VERSION_3_1
+ if (glewExperimental || GLEW_VERSION_3_1) CONST_CAST(GLEW_VERSION_3_1) = !_glewInit_GL_VERSION_3_1(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_VERSION_3_1 */
+#ifdef GL_VERSION_3_2
+ if (glewExperimental || GLEW_VERSION_3_2) CONST_CAST(GLEW_VERSION_3_2) = !_glewInit_GL_VERSION_3_2(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_VERSION_3_2 */
+#ifdef GL_VERSION_3_3
+ if (glewExperimental || GLEW_VERSION_3_3) CONST_CAST(GLEW_VERSION_3_3) = !_glewInit_GL_VERSION_3_3(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_VERSION_3_3 */
+#ifdef GL_VERSION_4_0
+ if (glewExperimental || GLEW_VERSION_4_0) CONST_CAST(GLEW_VERSION_4_0) = !_glewInit_GL_VERSION_4_0(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_VERSION_4_0 */
+#ifdef GL_VERSION_4_1
+#endif /* GL_VERSION_4_1 */
+#ifdef GL_VERSION_4_2
+#endif /* GL_VERSION_4_2 */
+#ifdef GL_VERSION_4_3
+#endif /* GL_VERSION_4_3 */
+#ifdef GL_VERSION_4_4
+#endif /* GL_VERSION_4_4 */
+#ifdef GL_3DFX_multisample
+ CONST_CAST(GLEW_3DFX_multisample) = _glewSearchExtension("GL_3DFX_multisample", extStart, extEnd);
+#endif /* GL_3DFX_multisample */
+#ifdef GL_3DFX_tbuffer
+ CONST_CAST(GLEW_3DFX_tbuffer) = _glewSearchExtension("GL_3DFX_tbuffer", extStart, extEnd);
+ if (glewExperimental || GLEW_3DFX_tbuffer) CONST_CAST(GLEW_3DFX_tbuffer) = !_glewInit_GL_3DFX_tbuffer(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_3DFX_tbuffer */
+#ifdef GL_3DFX_texture_compression_FXT1
+ CONST_CAST(GLEW_3DFX_texture_compression_FXT1) = _glewSearchExtension("GL_3DFX_texture_compression_FXT1", extStart, extEnd);
+#endif /* GL_3DFX_texture_compression_FXT1 */
+#ifdef GL_AMD_blend_minmax_factor
+ CONST_CAST(GLEW_AMD_blend_minmax_factor) = _glewSearchExtension("GL_AMD_blend_minmax_factor", extStart, extEnd);
+#endif /* GL_AMD_blend_minmax_factor */
+#ifdef GL_AMD_conservative_depth
+ CONST_CAST(GLEW_AMD_conservative_depth) = _glewSearchExtension("GL_AMD_conservative_depth", extStart, extEnd);
+#endif /* GL_AMD_conservative_depth */
+#ifdef GL_AMD_debug_output
+ CONST_CAST(GLEW_AMD_debug_output) = _glewSearchExtension("GL_AMD_debug_output", extStart, extEnd);
+ if (glewExperimental || GLEW_AMD_debug_output) CONST_CAST(GLEW_AMD_debug_output) = !_glewInit_GL_AMD_debug_output(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_AMD_debug_output */
+#ifdef GL_AMD_depth_clamp_separate
+ CONST_CAST(GLEW_AMD_depth_clamp_separate) = _glewSearchExtension("GL_AMD_depth_clamp_separate", extStart, extEnd);
+#endif /* GL_AMD_depth_clamp_separate */
+#ifdef GL_AMD_draw_buffers_blend
+ CONST_CAST(GLEW_AMD_draw_buffers_blend) = _glewSearchExtension("GL_AMD_draw_buffers_blend", extStart, extEnd);
+ if (glewExperimental || GLEW_AMD_draw_buffers_blend) CONST_CAST(GLEW_AMD_draw_buffers_blend) = !_glewInit_GL_AMD_draw_buffers_blend(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_AMD_draw_buffers_blend */
+#ifdef GL_AMD_interleaved_elements
+ CONST_CAST(GLEW_AMD_interleaved_elements) = _glewSearchExtension("GL_AMD_interleaved_elements", extStart, extEnd);
+ if (glewExperimental || GLEW_AMD_interleaved_elements) CONST_CAST(GLEW_AMD_interleaved_elements) = !_glewInit_GL_AMD_interleaved_elements(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_AMD_interleaved_elements */
+#ifdef GL_AMD_multi_draw_indirect
+ CONST_CAST(GLEW_AMD_multi_draw_indirect) = _glewSearchExtension("GL_AMD_multi_draw_indirect", extStart, extEnd);
+ if (glewExperimental || GLEW_AMD_multi_draw_indirect) CONST_CAST(GLEW_AMD_multi_draw_indirect) = !_glewInit_GL_AMD_multi_draw_indirect(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_AMD_multi_draw_indirect */
+#ifdef GL_AMD_name_gen_delete
+ CONST_CAST(GLEW_AMD_name_gen_delete) = _glewSearchExtension("GL_AMD_name_gen_delete", extStart, extEnd);
+ if (glewExperimental || GLEW_AMD_name_gen_delete) CONST_CAST(GLEW_AMD_name_gen_delete) = !_glewInit_GL_AMD_name_gen_delete(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_AMD_name_gen_delete */
+#ifdef GL_AMD_performance_monitor
+ CONST_CAST(GLEW_AMD_performance_monitor) = _glewSearchExtension("GL_AMD_performance_monitor", extStart, extEnd);
+ if (glewExperimental || GLEW_AMD_performance_monitor) CONST_CAST(GLEW_AMD_performance_monitor) = !_glewInit_GL_AMD_performance_monitor(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_AMD_performance_monitor */
+#ifdef GL_AMD_pinned_memory
+ CONST_CAST(GLEW_AMD_pinned_memory) = _glewSearchExtension("GL_AMD_pinned_memory", extStart, extEnd);
+#endif /* GL_AMD_pinned_memory */
+#ifdef GL_AMD_query_buffer_object
+ CONST_CAST(GLEW_AMD_query_buffer_object) = _glewSearchExtension("GL_AMD_query_buffer_object", extStart, extEnd);
+#endif /* GL_AMD_query_buffer_object */
+#ifdef GL_AMD_sample_positions
+ CONST_CAST(GLEW_AMD_sample_positions) = _glewSearchExtension("GL_AMD_sample_positions", extStart, extEnd);
+ if (glewExperimental || GLEW_AMD_sample_positions) CONST_CAST(GLEW_AMD_sample_positions) = !_glewInit_GL_AMD_sample_positions(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_AMD_sample_positions */
+#ifdef GL_AMD_seamless_cubemap_per_texture
+ CONST_CAST(GLEW_AMD_seamless_cubemap_per_texture) = _glewSearchExtension("GL_AMD_seamless_cubemap_per_texture", extStart, extEnd);
+#endif /* GL_AMD_seamless_cubemap_per_texture */
+#ifdef GL_AMD_shader_stencil_export
+ CONST_CAST(GLEW_AMD_shader_stencil_export) = _glewSearchExtension("GL_AMD_shader_stencil_export", extStart, extEnd);
+#endif /* GL_AMD_shader_stencil_export */
+#ifdef GL_AMD_shader_trinary_minmax
+ CONST_CAST(GLEW_AMD_shader_trinary_minmax) = _glewSearchExtension("GL_AMD_shader_trinary_minmax", extStart, extEnd);
+#endif /* GL_AMD_shader_trinary_minmax */
+#ifdef GL_AMD_sparse_texture
+ CONST_CAST(GLEW_AMD_sparse_texture) = _glewSearchExtension("GL_AMD_sparse_texture", extStart, extEnd);
+ if (glewExperimental || GLEW_AMD_sparse_texture) CONST_CAST(GLEW_AMD_sparse_texture) = !_glewInit_GL_AMD_sparse_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_AMD_sparse_texture */
+#ifdef GL_AMD_stencil_operation_extended
+ CONST_CAST(GLEW_AMD_stencil_operation_extended) = _glewSearchExtension("GL_AMD_stencil_operation_extended", extStart, extEnd);
+ if (glewExperimental || GLEW_AMD_stencil_operation_extended) CONST_CAST(GLEW_AMD_stencil_operation_extended) = !_glewInit_GL_AMD_stencil_operation_extended(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_AMD_stencil_operation_extended */
+#ifdef GL_AMD_texture_texture4
+ CONST_CAST(GLEW_AMD_texture_texture4) = _glewSearchExtension("GL_AMD_texture_texture4", extStart, extEnd);
+#endif /* GL_AMD_texture_texture4 */
+#ifdef GL_AMD_transform_feedback3_lines_triangles
+ CONST_CAST(GLEW_AMD_transform_feedback3_lines_triangles) = _glewSearchExtension("GL_AMD_transform_feedback3_lines_triangles", extStart, extEnd);
+#endif /* GL_AMD_transform_feedback3_lines_triangles */
+#ifdef GL_AMD_vertex_shader_layer
+ CONST_CAST(GLEW_AMD_vertex_shader_layer) = _glewSearchExtension("GL_AMD_vertex_shader_layer", extStart, extEnd);
+#endif /* GL_AMD_vertex_shader_layer */
+#ifdef GL_AMD_vertex_shader_tessellator
+ CONST_CAST(GLEW_AMD_vertex_shader_tessellator) = _glewSearchExtension("GL_AMD_vertex_shader_tessellator", extStart, extEnd);
+ if (glewExperimental || GLEW_AMD_vertex_shader_tessellator) CONST_CAST(GLEW_AMD_vertex_shader_tessellator) = !_glewInit_GL_AMD_vertex_shader_tessellator(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_AMD_vertex_shader_tessellator */
+#ifdef GL_AMD_vertex_shader_viewport_index
+ CONST_CAST(GLEW_AMD_vertex_shader_viewport_index) = _glewSearchExtension("GL_AMD_vertex_shader_viewport_index", extStart, extEnd);
+#endif /* GL_AMD_vertex_shader_viewport_index */
+#ifdef GL_ANGLE_depth_texture
+ CONST_CAST(GLEW_ANGLE_depth_texture) = _glewSearchExtension("GL_ANGLE_depth_texture", extStart, extEnd);
+#endif /* GL_ANGLE_depth_texture */
+#ifdef GL_ANGLE_framebuffer_blit
+ CONST_CAST(GLEW_ANGLE_framebuffer_blit) = _glewSearchExtension("GL_ANGLE_framebuffer_blit", extStart, extEnd);
+ if (glewExperimental || GLEW_ANGLE_framebuffer_blit) CONST_CAST(GLEW_ANGLE_framebuffer_blit) = !_glewInit_GL_ANGLE_framebuffer_blit(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ANGLE_framebuffer_blit */
+#ifdef GL_ANGLE_framebuffer_multisample
+ CONST_CAST(GLEW_ANGLE_framebuffer_multisample) = _glewSearchExtension("GL_ANGLE_framebuffer_multisample", extStart, extEnd);
+ if (glewExperimental || GLEW_ANGLE_framebuffer_multisample) CONST_CAST(GLEW_ANGLE_framebuffer_multisample) = !_glewInit_GL_ANGLE_framebuffer_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ANGLE_framebuffer_multisample */
+#ifdef GL_ANGLE_instanced_arrays
+ CONST_CAST(GLEW_ANGLE_instanced_arrays) = _glewSearchExtension("GL_ANGLE_instanced_arrays", extStart, extEnd);
+ if (glewExperimental || GLEW_ANGLE_instanced_arrays) CONST_CAST(GLEW_ANGLE_instanced_arrays) = !_glewInit_GL_ANGLE_instanced_arrays(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ANGLE_instanced_arrays */
+#ifdef GL_ANGLE_pack_reverse_row_order
+ CONST_CAST(GLEW_ANGLE_pack_reverse_row_order) = _glewSearchExtension("GL_ANGLE_pack_reverse_row_order", extStart, extEnd);
+#endif /* GL_ANGLE_pack_reverse_row_order */
+#ifdef GL_ANGLE_program_binary
+ CONST_CAST(GLEW_ANGLE_program_binary) = _glewSearchExtension("GL_ANGLE_program_binary", extStart, extEnd);
+#endif /* GL_ANGLE_program_binary */
+#ifdef GL_ANGLE_texture_compression_dxt1
+ CONST_CAST(GLEW_ANGLE_texture_compression_dxt1) = _glewSearchExtension("GL_ANGLE_texture_compression_dxt1", extStart, extEnd);
+#endif /* GL_ANGLE_texture_compression_dxt1 */
+#ifdef GL_ANGLE_texture_compression_dxt3
+ CONST_CAST(GLEW_ANGLE_texture_compression_dxt3) = _glewSearchExtension("GL_ANGLE_texture_compression_dxt3", extStart, extEnd);
+#endif /* GL_ANGLE_texture_compression_dxt3 */
+#ifdef GL_ANGLE_texture_compression_dxt5
+ CONST_CAST(GLEW_ANGLE_texture_compression_dxt5) = _glewSearchExtension("GL_ANGLE_texture_compression_dxt5", extStart, extEnd);
+#endif /* GL_ANGLE_texture_compression_dxt5 */
+#ifdef GL_ANGLE_texture_usage
+ CONST_CAST(GLEW_ANGLE_texture_usage) = _glewSearchExtension("GL_ANGLE_texture_usage", extStart, extEnd);
+#endif /* GL_ANGLE_texture_usage */
+#ifdef GL_ANGLE_timer_query
+ CONST_CAST(GLEW_ANGLE_timer_query) = _glewSearchExtension("GL_ANGLE_timer_query", extStart, extEnd);
+ if (glewExperimental || GLEW_ANGLE_timer_query) CONST_CAST(GLEW_ANGLE_timer_query) = !_glewInit_GL_ANGLE_timer_query(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ANGLE_timer_query */
+#ifdef GL_ANGLE_translated_shader_source
+ CONST_CAST(GLEW_ANGLE_translated_shader_source) = _glewSearchExtension("GL_ANGLE_translated_shader_source", extStart, extEnd);
+ if (glewExperimental || GLEW_ANGLE_translated_shader_source) CONST_CAST(GLEW_ANGLE_translated_shader_source) = !_glewInit_GL_ANGLE_translated_shader_source(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ANGLE_translated_shader_source */
+#ifdef GL_APPLE_aux_depth_stencil
+ CONST_CAST(GLEW_APPLE_aux_depth_stencil) = _glewSearchExtension("GL_APPLE_aux_depth_stencil", extStart, extEnd);
+#endif /* GL_APPLE_aux_depth_stencil */
+#ifdef GL_APPLE_client_storage
+ CONST_CAST(GLEW_APPLE_client_storage) = _glewSearchExtension("GL_APPLE_client_storage", extStart, extEnd);
+#endif /* GL_APPLE_client_storage */
+#ifdef GL_APPLE_element_array
+ CONST_CAST(GLEW_APPLE_element_array) = _glewSearchExtension("GL_APPLE_element_array", extStart, extEnd);
+ if (glewExperimental || GLEW_APPLE_element_array) CONST_CAST(GLEW_APPLE_element_array) = !_glewInit_GL_APPLE_element_array(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_APPLE_element_array */
+#ifdef GL_APPLE_fence
+ CONST_CAST(GLEW_APPLE_fence) = _glewSearchExtension("GL_APPLE_fence", extStart, extEnd);
+ if (glewExperimental || GLEW_APPLE_fence) CONST_CAST(GLEW_APPLE_fence) = !_glewInit_GL_APPLE_fence(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_APPLE_fence */
+#ifdef GL_APPLE_float_pixels
+ CONST_CAST(GLEW_APPLE_float_pixels) = _glewSearchExtension("GL_APPLE_float_pixels", extStart, extEnd);
+#endif /* GL_APPLE_float_pixels */
+#ifdef GL_APPLE_flush_buffer_range
+ CONST_CAST(GLEW_APPLE_flush_buffer_range) = _glewSearchExtension("GL_APPLE_flush_buffer_range", extStart, extEnd);
+ if (glewExperimental || GLEW_APPLE_flush_buffer_range) CONST_CAST(GLEW_APPLE_flush_buffer_range) = !_glewInit_GL_APPLE_flush_buffer_range(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_APPLE_flush_buffer_range */
+#ifdef GL_APPLE_object_purgeable
+ CONST_CAST(GLEW_APPLE_object_purgeable) = _glewSearchExtension("GL_APPLE_object_purgeable", extStart, extEnd);
+ if (glewExperimental || GLEW_APPLE_object_purgeable) CONST_CAST(GLEW_APPLE_object_purgeable) = !_glewInit_GL_APPLE_object_purgeable(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_APPLE_object_purgeable */
+#ifdef GL_APPLE_pixel_buffer
+ CONST_CAST(GLEW_APPLE_pixel_buffer) = _glewSearchExtension("GL_APPLE_pixel_buffer", extStart, extEnd);
+#endif /* GL_APPLE_pixel_buffer */
+#ifdef GL_APPLE_rgb_422
+ CONST_CAST(GLEW_APPLE_rgb_422) = _glewSearchExtension("GL_APPLE_rgb_422", extStart, extEnd);
+#endif /* GL_APPLE_rgb_422 */
+#ifdef GL_APPLE_row_bytes
+ CONST_CAST(GLEW_APPLE_row_bytes) = _glewSearchExtension("GL_APPLE_row_bytes", extStart, extEnd);
+#endif /* GL_APPLE_row_bytes */
+#ifdef GL_APPLE_specular_vector
+ CONST_CAST(GLEW_APPLE_specular_vector) = _glewSearchExtension("GL_APPLE_specular_vector", extStart, extEnd);
+#endif /* GL_APPLE_specular_vector */
+#ifdef GL_APPLE_texture_range
+ CONST_CAST(GLEW_APPLE_texture_range) = _glewSearchExtension("GL_APPLE_texture_range", extStart, extEnd);
+ if (glewExperimental || GLEW_APPLE_texture_range) CONST_CAST(GLEW_APPLE_texture_range) = !_glewInit_GL_APPLE_texture_range(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_APPLE_texture_range */
+#ifdef GL_APPLE_transform_hint
+ CONST_CAST(GLEW_APPLE_transform_hint) = _glewSearchExtension("GL_APPLE_transform_hint", extStart, extEnd);
+#endif /* GL_APPLE_transform_hint */
+#ifdef GL_APPLE_vertex_array_object
+ CONST_CAST(GLEW_APPLE_vertex_array_object) = _glewSearchExtension("GL_APPLE_vertex_array_object", extStart, extEnd);
+ if (glewExperimental || GLEW_APPLE_vertex_array_object) CONST_CAST(GLEW_APPLE_vertex_array_object) = !_glewInit_GL_APPLE_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_APPLE_vertex_array_object */
+#ifdef GL_APPLE_vertex_array_range
+ CONST_CAST(GLEW_APPLE_vertex_array_range) = _glewSearchExtension("GL_APPLE_vertex_array_range", extStart, extEnd);
+ if (glewExperimental || GLEW_APPLE_vertex_array_range) CONST_CAST(GLEW_APPLE_vertex_array_range) = !_glewInit_GL_APPLE_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_APPLE_vertex_array_range */
+#ifdef GL_APPLE_vertex_program_evaluators
+ CONST_CAST(GLEW_APPLE_vertex_program_evaluators) = _glewSearchExtension("GL_APPLE_vertex_program_evaluators", extStart, extEnd);
+ if (glewExperimental || GLEW_APPLE_vertex_program_evaluators) CONST_CAST(GLEW_APPLE_vertex_program_evaluators) = !_glewInit_GL_APPLE_vertex_program_evaluators(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_APPLE_vertex_program_evaluators */
+#ifdef GL_APPLE_ycbcr_422
+ CONST_CAST(GLEW_APPLE_ycbcr_422) = _glewSearchExtension("GL_APPLE_ycbcr_422", extStart, extEnd);
+#endif /* GL_APPLE_ycbcr_422 */
+#ifdef GL_ARB_ES2_compatibility
+ CONST_CAST(GLEW_ARB_ES2_compatibility) = _glewSearchExtension("GL_ARB_ES2_compatibility", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_ES2_compatibility) CONST_CAST(GLEW_ARB_ES2_compatibility) = !_glewInit_GL_ARB_ES2_compatibility(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_ES2_compatibility */
+#ifdef GL_ARB_ES3_compatibility
+ CONST_CAST(GLEW_ARB_ES3_compatibility) = _glewSearchExtension("GL_ARB_ES3_compatibility", extStart, extEnd);
+#endif /* GL_ARB_ES3_compatibility */
+#ifdef GL_ARB_arrays_of_arrays
+ CONST_CAST(GLEW_ARB_arrays_of_arrays) = _glewSearchExtension("GL_ARB_arrays_of_arrays", extStart, extEnd);
+#endif /* GL_ARB_arrays_of_arrays */
+#ifdef GL_ARB_base_instance
+ CONST_CAST(GLEW_ARB_base_instance) = _glewSearchExtension("GL_ARB_base_instance", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_base_instance) CONST_CAST(GLEW_ARB_base_instance) = !_glewInit_GL_ARB_base_instance(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_base_instance */
+#ifdef GL_ARB_bindless_texture
+ CONST_CAST(GLEW_ARB_bindless_texture) = _glewSearchExtension("GL_ARB_bindless_texture", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_bindless_texture) CONST_CAST(GLEW_ARB_bindless_texture) = !_glewInit_GL_ARB_bindless_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_bindless_texture */
+#ifdef GL_ARB_blend_func_extended
+ CONST_CAST(GLEW_ARB_blend_func_extended) = _glewSearchExtension("GL_ARB_blend_func_extended", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_blend_func_extended) CONST_CAST(GLEW_ARB_blend_func_extended) = !_glewInit_GL_ARB_blend_func_extended(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_blend_func_extended */
+#ifdef GL_ARB_buffer_storage
+ CONST_CAST(GLEW_ARB_buffer_storage) = _glewSearchExtension("GL_ARB_buffer_storage", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_buffer_storage) CONST_CAST(GLEW_ARB_buffer_storage) = !_glewInit_GL_ARB_buffer_storage(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_buffer_storage */
+#ifdef GL_ARB_cl_event
+ CONST_CAST(GLEW_ARB_cl_event) = _glewSearchExtension("GL_ARB_cl_event", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_cl_event) CONST_CAST(GLEW_ARB_cl_event) = !_glewInit_GL_ARB_cl_event(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_cl_event */
+#ifdef GL_ARB_clear_buffer_object
+ CONST_CAST(GLEW_ARB_clear_buffer_object) = _glewSearchExtension("GL_ARB_clear_buffer_object", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_clear_buffer_object) CONST_CAST(GLEW_ARB_clear_buffer_object) = !_glewInit_GL_ARB_clear_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_clear_buffer_object */
+#ifdef GL_ARB_clear_texture
+ CONST_CAST(GLEW_ARB_clear_texture) = _glewSearchExtension("GL_ARB_clear_texture", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_clear_texture) CONST_CAST(GLEW_ARB_clear_texture) = !_glewInit_GL_ARB_clear_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_clear_texture */
+#ifdef GL_ARB_color_buffer_float
+ CONST_CAST(GLEW_ARB_color_buffer_float) = _glewSearchExtension("GL_ARB_color_buffer_float", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_color_buffer_float) CONST_CAST(GLEW_ARB_color_buffer_float) = !_glewInit_GL_ARB_color_buffer_float(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_color_buffer_float */
+#ifdef GL_ARB_compatibility
+ CONST_CAST(GLEW_ARB_compatibility) = _glewSearchExtension("GL_ARB_compatibility", extStart, extEnd);
+#endif /* GL_ARB_compatibility */
+#ifdef GL_ARB_compressed_texture_pixel_storage
+ CONST_CAST(GLEW_ARB_compressed_texture_pixel_storage) = _glewSearchExtension("GL_ARB_compressed_texture_pixel_storage", extStart, extEnd);
+#endif /* GL_ARB_compressed_texture_pixel_storage */
+#ifdef GL_ARB_compute_shader
+ CONST_CAST(GLEW_ARB_compute_shader) = _glewSearchExtension("GL_ARB_compute_shader", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_compute_shader) CONST_CAST(GLEW_ARB_compute_shader) = !_glewInit_GL_ARB_compute_shader(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_compute_shader */
+#ifdef GL_ARB_compute_variable_group_size
+ CONST_CAST(GLEW_ARB_compute_variable_group_size) = _glewSearchExtension("GL_ARB_compute_variable_group_size", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_compute_variable_group_size) CONST_CAST(GLEW_ARB_compute_variable_group_size) = !_glewInit_GL_ARB_compute_variable_group_size(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_compute_variable_group_size */
+#ifdef GL_ARB_conservative_depth
+ CONST_CAST(GLEW_ARB_conservative_depth) = _glewSearchExtension("GL_ARB_conservative_depth", extStart, extEnd);
+#endif /* GL_ARB_conservative_depth */
+#ifdef GL_ARB_copy_buffer
+ CONST_CAST(GLEW_ARB_copy_buffer) = _glewSearchExtension("GL_ARB_copy_buffer", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_copy_buffer) CONST_CAST(GLEW_ARB_copy_buffer) = !_glewInit_GL_ARB_copy_buffer(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_copy_buffer */
+#ifdef GL_ARB_copy_image
+ CONST_CAST(GLEW_ARB_copy_image) = _glewSearchExtension("GL_ARB_copy_image", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_copy_image) CONST_CAST(GLEW_ARB_copy_image) = !_glewInit_GL_ARB_copy_image(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_copy_image */
+#ifdef GL_ARB_debug_output
+ CONST_CAST(GLEW_ARB_debug_output) = _glewSearchExtension("GL_ARB_debug_output", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_debug_output) CONST_CAST(GLEW_ARB_debug_output) = !_glewInit_GL_ARB_debug_output(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_debug_output */
+#ifdef GL_ARB_depth_buffer_float
+ CONST_CAST(GLEW_ARB_depth_buffer_float) = _glewSearchExtension("GL_ARB_depth_buffer_float", extStart, extEnd);
+#endif /* GL_ARB_depth_buffer_float */
+#ifdef GL_ARB_depth_clamp
+ CONST_CAST(GLEW_ARB_depth_clamp) = _glewSearchExtension("GL_ARB_depth_clamp", extStart, extEnd);
+#endif /* GL_ARB_depth_clamp */
+#ifdef GL_ARB_depth_texture
+ CONST_CAST(GLEW_ARB_depth_texture) = _glewSearchExtension("GL_ARB_depth_texture", extStart, extEnd);
+#endif /* GL_ARB_depth_texture */
+#ifdef GL_ARB_draw_buffers
+ CONST_CAST(GLEW_ARB_draw_buffers) = _glewSearchExtension("GL_ARB_draw_buffers", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_draw_buffers) CONST_CAST(GLEW_ARB_draw_buffers) = !_glewInit_GL_ARB_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_draw_buffers */
+#ifdef GL_ARB_draw_buffers_blend
+ CONST_CAST(GLEW_ARB_draw_buffers_blend) = _glewSearchExtension("GL_ARB_draw_buffers_blend", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_draw_buffers_blend) CONST_CAST(GLEW_ARB_draw_buffers_blend) = !_glewInit_GL_ARB_draw_buffers_blend(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_draw_buffers_blend */
+#ifdef GL_ARB_draw_elements_base_vertex
+ CONST_CAST(GLEW_ARB_draw_elements_base_vertex) = _glewSearchExtension("GL_ARB_draw_elements_base_vertex", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_draw_elements_base_vertex) CONST_CAST(GLEW_ARB_draw_elements_base_vertex) = !_glewInit_GL_ARB_draw_elements_base_vertex(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_draw_elements_base_vertex */
+#ifdef GL_ARB_draw_indirect
+ CONST_CAST(GLEW_ARB_draw_indirect) = _glewSearchExtension("GL_ARB_draw_indirect", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_draw_indirect) CONST_CAST(GLEW_ARB_draw_indirect) = !_glewInit_GL_ARB_draw_indirect(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_draw_indirect */
+#ifdef GL_ARB_draw_instanced
+ CONST_CAST(GLEW_ARB_draw_instanced) = _glewSearchExtension("GL_ARB_draw_instanced", extStart, extEnd);
+#endif /* GL_ARB_draw_instanced */
+#ifdef GL_ARB_enhanced_layouts
+ CONST_CAST(GLEW_ARB_enhanced_layouts) = _glewSearchExtension("GL_ARB_enhanced_layouts", extStart, extEnd);
+#endif /* GL_ARB_enhanced_layouts */
+#ifdef GL_ARB_explicit_attrib_location
+ CONST_CAST(GLEW_ARB_explicit_attrib_location) = _glewSearchExtension("GL_ARB_explicit_attrib_location", extStart, extEnd);
+#endif /* GL_ARB_explicit_attrib_location */
+#ifdef GL_ARB_explicit_uniform_location
+ CONST_CAST(GLEW_ARB_explicit_uniform_location) = _glewSearchExtension("GL_ARB_explicit_uniform_location", extStart, extEnd);
+#endif /* GL_ARB_explicit_uniform_location */
+#ifdef GL_ARB_fragment_coord_conventions
+ CONST_CAST(GLEW_ARB_fragment_coord_conventions) = _glewSearchExtension("GL_ARB_fragment_coord_conventions", extStart, extEnd);
+#endif /* GL_ARB_fragment_coord_conventions */
+#ifdef GL_ARB_fragment_layer_viewport
+ CONST_CAST(GLEW_ARB_fragment_layer_viewport) = _glewSearchExtension("GL_ARB_fragment_layer_viewport", extStart, extEnd);
+#endif /* GL_ARB_fragment_layer_viewport */
+#ifdef GL_ARB_fragment_program
+ CONST_CAST(GLEW_ARB_fragment_program) = _glewSearchExtension("GL_ARB_fragment_program", extStart, extEnd);
+#endif /* GL_ARB_fragment_program */
+#ifdef GL_ARB_fragment_program_shadow
+ CONST_CAST(GLEW_ARB_fragment_program_shadow) = _glewSearchExtension("GL_ARB_fragment_program_shadow", extStart, extEnd);
+#endif /* GL_ARB_fragment_program_shadow */
+#ifdef GL_ARB_fragment_shader
+ CONST_CAST(GLEW_ARB_fragment_shader) = _glewSearchExtension("GL_ARB_fragment_shader", extStart, extEnd);
+#endif /* GL_ARB_fragment_shader */
+#ifdef GL_ARB_framebuffer_no_attachments
+ CONST_CAST(GLEW_ARB_framebuffer_no_attachments) = _glewSearchExtension("GL_ARB_framebuffer_no_attachments", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_framebuffer_no_attachments) CONST_CAST(GLEW_ARB_framebuffer_no_attachments) = !_glewInit_GL_ARB_framebuffer_no_attachments(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_framebuffer_no_attachments */
+#ifdef GL_ARB_framebuffer_object
+ CONST_CAST(GLEW_ARB_framebuffer_object) = _glewSearchExtension("GL_ARB_framebuffer_object", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_framebuffer_object) CONST_CAST(GLEW_ARB_framebuffer_object) = !_glewInit_GL_ARB_framebuffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_framebuffer_object */
+#ifdef GL_ARB_framebuffer_sRGB
+ CONST_CAST(GLEW_ARB_framebuffer_sRGB) = _glewSearchExtension("GL_ARB_framebuffer_sRGB", extStart, extEnd);
+#endif /* GL_ARB_framebuffer_sRGB */
+#ifdef GL_ARB_geometry_shader4
+ CONST_CAST(GLEW_ARB_geometry_shader4) = _glewSearchExtension("GL_ARB_geometry_shader4", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_geometry_shader4) CONST_CAST(GLEW_ARB_geometry_shader4) = !_glewInit_GL_ARB_geometry_shader4(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_geometry_shader4 */
+#ifdef GL_ARB_get_program_binary
+ CONST_CAST(GLEW_ARB_get_program_binary) = _glewSearchExtension("GL_ARB_get_program_binary", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_get_program_binary) CONST_CAST(GLEW_ARB_get_program_binary) = !_glewInit_GL_ARB_get_program_binary(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_get_program_binary */
+#ifdef GL_ARB_gpu_shader5
+ CONST_CAST(GLEW_ARB_gpu_shader5) = _glewSearchExtension("GL_ARB_gpu_shader5", extStart, extEnd);
+#endif /* GL_ARB_gpu_shader5 */
+#ifdef GL_ARB_gpu_shader_fp64
+ CONST_CAST(GLEW_ARB_gpu_shader_fp64) = _glewSearchExtension("GL_ARB_gpu_shader_fp64", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_gpu_shader_fp64) CONST_CAST(GLEW_ARB_gpu_shader_fp64) = !_glewInit_GL_ARB_gpu_shader_fp64(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_gpu_shader_fp64 */
+#ifdef GL_ARB_half_float_pixel
+ CONST_CAST(GLEW_ARB_half_float_pixel) = _glewSearchExtension("GL_ARB_half_float_pixel", extStart, extEnd);
+#endif /* GL_ARB_half_float_pixel */
+#ifdef GL_ARB_half_float_vertex
+ CONST_CAST(GLEW_ARB_half_float_vertex) = _glewSearchExtension("GL_ARB_half_float_vertex", extStart, extEnd);
+#endif /* GL_ARB_half_float_vertex */
+#ifdef GL_ARB_imaging
+ CONST_CAST(GLEW_ARB_imaging) = _glewSearchExtension("GL_ARB_imaging", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_imaging) CONST_CAST(GLEW_ARB_imaging) = !_glewInit_GL_ARB_imaging(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_imaging */
+#ifdef GL_ARB_indirect_parameters
+ CONST_CAST(GLEW_ARB_indirect_parameters) = _glewSearchExtension("GL_ARB_indirect_parameters", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_indirect_parameters) CONST_CAST(GLEW_ARB_indirect_parameters) = !_glewInit_GL_ARB_indirect_parameters(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_indirect_parameters */
+#ifdef GL_ARB_instanced_arrays
+ CONST_CAST(GLEW_ARB_instanced_arrays) = _glewSearchExtension("GL_ARB_instanced_arrays", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_instanced_arrays) CONST_CAST(GLEW_ARB_instanced_arrays) = !_glewInit_GL_ARB_instanced_arrays(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_instanced_arrays */
+#ifdef GL_ARB_internalformat_query
+ CONST_CAST(GLEW_ARB_internalformat_query) = _glewSearchExtension("GL_ARB_internalformat_query", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_internalformat_query) CONST_CAST(GLEW_ARB_internalformat_query) = !_glewInit_GL_ARB_internalformat_query(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_internalformat_query */
+#ifdef GL_ARB_internalformat_query2
+ CONST_CAST(GLEW_ARB_internalformat_query2) = _glewSearchExtension("GL_ARB_internalformat_query2", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_internalformat_query2) CONST_CAST(GLEW_ARB_internalformat_query2) = !_glewInit_GL_ARB_internalformat_query2(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_internalformat_query2 */
+#ifdef GL_ARB_invalidate_subdata
+ CONST_CAST(GLEW_ARB_invalidate_subdata) = _glewSearchExtension("GL_ARB_invalidate_subdata", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_invalidate_subdata) CONST_CAST(GLEW_ARB_invalidate_subdata) = !_glewInit_GL_ARB_invalidate_subdata(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_invalidate_subdata */
+#ifdef GL_ARB_map_buffer_alignment
+ CONST_CAST(GLEW_ARB_map_buffer_alignment) = _glewSearchExtension("GL_ARB_map_buffer_alignment", extStart, extEnd);
+#endif /* GL_ARB_map_buffer_alignment */
+#ifdef GL_ARB_map_buffer_range
+ CONST_CAST(GLEW_ARB_map_buffer_range) = _glewSearchExtension("GL_ARB_map_buffer_range", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_map_buffer_range) CONST_CAST(GLEW_ARB_map_buffer_range) = !_glewInit_GL_ARB_map_buffer_range(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_map_buffer_range */
+#ifdef GL_ARB_matrix_palette
+ CONST_CAST(GLEW_ARB_matrix_palette) = _glewSearchExtension("GL_ARB_matrix_palette", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_matrix_palette) CONST_CAST(GLEW_ARB_matrix_palette) = !_glewInit_GL_ARB_matrix_palette(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_matrix_palette */
+#ifdef GL_ARB_multi_bind
+ CONST_CAST(GLEW_ARB_multi_bind) = _glewSearchExtension("GL_ARB_multi_bind", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_multi_bind) CONST_CAST(GLEW_ARB_multi_bind) = !_glewInit_GL_ARB_multi_bind(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_multi_bind */
+#ifdef GL_ARB_multi_draw_indirect
+ CONST_CAST(GLEW_ARB_multi_draw_indirect) = _glewSearchExtension("GL_ARB_multi_draw_indirect", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_multi_draw_indirect) CONST_CAST(GLEW_ARB_multi_draw_indirect) = !_glewInit_GL_ARB_multi_draw_indirect(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_multi_draw_indirect */
+#ifdef GL_ARB_multisample
+ CONST_CAST(GLEW_ARB_multisample) = _glewSearchExtension("GL_ARB_multisample", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_multisample) CONST_CAST(GLEW_ARB_multisample) = !_glewInit_GL_ARB_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_multisample */
+#ifdef GL_ARB_multitexture
+ CONST_CAST(GLEW_ARB_multitexture) = _glewSearchExtension("GL_ARB_multitexture", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_multitexture) CONST_CAST(GLEW_ARB_multitexture) = !_glewInit_GL_ARB_multitexture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_multitexture */
+#ifdef GL_ARB_occlusion_query
+ CONST_CAST(GLEW_ARB_occlusion_query) = _glewSearchExtension("GL_ARB_occlusion_query", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_occlusion_query) CONST_CAST(GLEW_ARB_occlusion_query) = !_glewInit_GL_ARB_occlusion_query(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_occlusion_query */
+#ifdef GL_ARB_occlusion_query2
+ CONST_CAST(GLEW_ARB_occlusion_query2) = _glewSearchExtension("GL_ARB_occlusion_query2", extStart, extEnd);
+#endif /* GL_ARB_occlusion_query2 */
+#ifdef GL_ARB_pixel_buffer_object
+ CONST_CAST(GLEW_ARB_pixel_buffer_object) = _glewSearchExtension("GL_ARB_pixel_buffer_object", extStart, extEnd);
+#endif /* GL_ARB_pixel_buffer_object */
+#ifdef GL_ARB_point_parameters
+ CONST_CAST(GLEW_ARB_point_parameters) = _glewSearchExtension("GL_ARB_point_parameters", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_point_parameters) CONST_CAST(GLEW_ARB_point_parameters) = !_glewInit_GL_ARB_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_point_parameters */
+#ifdef GL_ARB_point_sprite
+ CONST_CAST(GLEW_ARB_point_sprite) = _glewSearchExtension("GL_ARB_point_sprite", extStart, extEnd);
+#endif /* GL_ARB_point_sprite */
+#ifdef GL_ARB_program_interface_query
+ CONST_CAST(GLEW_ARB_program_interface_query) = _glewSearchExtension("GL_ARB_program_interface_query", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_program_interface_query) CONST_CAST(GLEW_ARB_program_interface_query) = !_glewInit_GL_ARB_program_interface_query(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_program_interface_query */
+#ifdef GL_ARB_provoking_vertex
+ CONST_CAST(GLEW_ARB_provoking_vertex) = _glewSearchExtension("GL_ARB_provoking_vertex", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_provoking_vertex) CONST_CAST(GLEW_ARB_provoking_vertex) = !_glewInit_GL_ARB_provoking_vertex(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_provoking_vertex */
+#ifdef GL_ARB_query_buffer_object
+ CONST_CAST(GLEW_ARB_query_buffer_object) = _glewSearchExtension("GL_ARB_query_buffer_object", extStart, extEnd);
+#endif /* GL_ARB_query_buffer_object */
+#ifdef GL_ARB_robust_buffer_access_behavior
+ CONST_CAST(GLEW_ARB_robust_buffer_access_behavior) = _glewSearchExtension("GL_ARB_robust_buffer_access_behavior", extStart, extEnd);
+#endif /* GL_ARB_robust_buffer_access_behavior */
+#ifdef GL_ARB_robustness
+ CONST_CAST(GLEW_ARB_robustness) = _glewSearchExtension("GL_ARB_robustness", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_robustness) CONST_CAST(GLEW_ARB_robustness) = !_glewInit_GL_ARB_robustness(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_robustness */
+#ifdef GL_ARB_robustness_application_isolation
+ CONST_CAST(GLEW_ARB_robustness_application_isolation) = _glewSearchExtension("GL_ARB_robustness_application_isolation", extStart, extEnd);
+#endif /* GL_ARB_robustness_application_isolation */
+#ifdef GL_ARB_robustness_share_group_isolation
+ CONST_CAST(GLEW_ARB_robustness_share_group_isolation) = _glewSearchExtension("GL_ARB_robustness_share_group_isolation", extStart, extEnd);
+#endif /* GL_ARB_robustness_share_group_isolation */
+#ifdef GL_ARB_sample_shading
+ CONST_CAST(GLEW_ARB_sample_shading) = _glewSearchExtension("GL_ARB_sample_shading", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_sample_shading) CONST_CAST(GLEW_ARB_sample_shading) = !_glewInit_GL_ARB_sample_shading(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_sample_shading */
+#ifdef GL_ARB_sampler_objects
+ CONST_CAST(GLEW_ARB_sampler_objects) = _glewSearchExtension("GL_ARB_sampler_objects", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_sampler_objects) CONST_CAST(GLEW_ARB_sampler_objects) = !_glewInit_GL_ARB_sampler_objects(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_sampler_objects */
+#ifdef GL_ARB_seamless_cube_map
+ CONST_CAST(GLEW_ARB_seamless_cube_map) = _glewSearchExtension("GL_ARB_seamless_cube_map", extStart, extEnd);
+#endif /* GL_ARB_seamless_cube_map */
+#ifdef GL_ARB_seamless_cubemap_per_texture
+ CONST_CAST(GLEW_ARB_seamless_cubemap_per_texture) = _glewSearchExtension("GL_ARB_seamless_cubemap_per_texture", extStart, extEnd);
+#endif /* GL_ARB_seamless_cubemap_per_texture */
+#ifdef GL_ARB_separate_shader_objects
+ CONST_CAST(GLEW_ARB_separate_shader_objects) = _glewSearchExtension("GL_ARB_separate_shader_objects", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_separate_shader_objects) CONST_CAST(GLEW_ARB_separate_shader_objects) = !_glewInit_GL_ARB_separate_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_separate_shader_objects */
+#ifdef GL_ARB_shader_atomic_counters
+ CONST_CAST(GLEW_ARB_shader_atomic_counters) = _glewSearchExtension("GL_ARB_shader_atomic_counters", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_shader_atomic_counters) CONST_CAST(GLEW_ARB_shader_atomic_counters) = !_glewInit_GL_ARB_shader_atomic_counters(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_shader_atomic_counters */
+#ifdef GL_ARB_shader_bit_encoding
+ CONST_CAST(GLEW_ARB_shader_bit_encoding) = _glewSearchExtension("GL_ARB_shader_bit_encoding", extStart, extEnd);
+#endif /* GL_ARB_shader_bit_encoding */
+#ifdef GL_ARB_shader_draw_parameters
+ CONST_CAST(GLEW_ARB_shader_draw_parameters) = _glewSearchExtension("GL_ARB_shader_draw_parameters", extStart, extEnd);
+#endif /* GL_ARB_shader_draw_parameters */
+#ifdef GL_ARB_shader_group_vote
+ CONST_CAST(GLEW_ARB_shader_group_vote) = _glewSearchExtension("GL_ARB_shader_group_vote", extStart, extEnd);
+#endif /* GL_ARB_shader_group_vote */
+#ifdef GL_ARB_shader_image_load_store
+ CONST_CAST(GLEW_ARB_shader_image_load_store) = _glewSearchExtension("GL_ARB_shader_image_load_store", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_shader_image_load_store) CONST_CAST(GLEW_ARB_shader_image_load_store) = !_glewInit_GL_ARB_shader_image_load_store(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_shader_image_load_store */
+#ifdef GL_ARB_shader_image_size
+ CONST_CAST(GLEW_ARB_shader_image_size) = _glewSearchExtension("GL_ARB_shader_image_size", extStart, extEnd);
+#endif /* GL_ARB_shader_image_size */
+#ifdef GL_ARB_shader_objects
+ CONST_CAST(GLEW_ARB_shader_objects) = _glewSearchExtension("GL_ARB_shader_objects", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_shader_objects) CONST_CAST(GLEW_ARB_shader_objects) = !_glewInit_GL_ARB_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_shader_objects */
+#ifdef GL_ARB_shader_precision
+ CONST_CAST(GLEW_ARB_shader_precision) = _glewSearchExtension("GL_ARB_shader_precision", extStart, extEnd);
+#endif /* GL_ARB_shader_precision */
+#ifdef GL_ARB_shader_stencil_export
+ CONST_CAST(GLEW_ARB_shader_stencil_export) = _glewSearchExtension("GL_ARB_shader_stencil_export", extStart, extEnd);
+#endif /* GL_ARB_shader_stencil_export */
+#ifdef GL_ARB_shader_storage_buffer_object
+ CONST_CAST(GLEW_ARB_shader_storage_buffer_object) = _glewSearchExtension("GL_ARB_shader_storage_buffer_object", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_shader_storage_buffer_object) CONST_CAST(GLEW_ARB_shader_storage_buffer_object) = !_glewInit_GL_ARB_shader_storage_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_shader_storage_buffer_object */
+#ifdef GL_ARB_shader_subroutine
+ CONST_CAST(GLEW_ARB_shader_subroutine) = _glewSearchExtension("GL_ARB_shader_subroutine", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_shader_subroutine) CONST_CAST(GLEW_ARB_shader_subroutine) = !_glewInit_GL_ARB_shader_subroutine(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_shader_subroutine */
+#ifdef GL_ARB_shader_texture_lod
+ CONST_CAST(GLEW_ARB_shader_texture_lod) = _glewSearchExtension("GL_ARB_shader_texture_lod", extStart, extEnd);
+#endif /* GL_ARB_shader_texture_lod */
+#ifdef GL_ARB_shading_language_100
+ CONST_CAST(GLEW_ARB_shading_language_100) = _glewSearchExtension("GL_ARB_shading_language_100", extStart, extEnd);
+#endif /* GL_ARB_shading_language_100 */
+#ifdef GL_ARB_shading_language_420pack
+ CONST_CAST(GLEW_ARB_shading_language_420pack) = _glewSearchExtension("GL_ARB_shading_language_420pack", extStart, extEnd);
+#endif /* GL_ARB_shading_language_420pack */
+#ifdef GL_ARB_shading_language_include
+ CONST_CAST(GLEW_ARB_shading_language_include) = _glewSearchExtension("GL_ARB_shading_language_include", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_shading_language_include) CONST_CAST(GLEW_ARB_shading_language_include) = !_glewInit_GL_ARB_shading_language_include(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_shading_language_include */
+#ifdef GL_ARB_shading_language_packing
+ CONST_CAST(GLEW_ARB_shading_language_packing) = _glewSearchExtension("GL_ARB_shading_language_packing", extStart, extEnd);
+#endif /* GL_ARB_shading_language_packing */
+#ifdef GL_ARB_shadow
+ CONST_CAST(GLEW_ARB_shadow) = _glewSearchExtension("GL_ARB_shadow", extStart, extEnd);
+#endif /* GL_ARB_shadow */
+#ifdef GL_ARB_shadow_ambient
+ CONST_CAST(GLEW_ARB_shadow_ambient) = _glewSearchExtension("GL_ARB_shadow_ambient", extStart, extEnd);
+#endif /* GL_ARB_shadow_ambient */
+#ifdef GL_ARB_sparse_texture
+ CONST_CAST(GLEW_ARB_sparse_texture) = _glewSearchExtension("GL_ARB_sparse_texture", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_sparse_texture) CONST_CAST(GLEW_ARB_sparse_texture) = !_glewInit_GL_ARB_sparse_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_sparse_texture */
+#ifdef GL_ARB_stencil_texturing
+ CONST_CAST(GLEW_ARB_stencil_texturing) = _glewSearchExtension("GL_ARB_stencil_texturing", extStart, extEnd);
+#endif /* GL_ARB_stencil_texturing */
+#ifdef GL_ARB_sync
+ CONST_CAST(GLEW_ARB_sync) = _glewSearchExtension("GL_ARB_sync", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_sync) CONST_CAST(GLEW_ARB_sync) = !_glewInit_GL_ARB_sync(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_sync */
+#ifdef GL_ARB_tessellation_shader
+ CONST_CAST(GLEW_ARB_tessellation_shader) = _glewSearchExtension("GL_ARB_tessellation_shader", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_tessellation_shader) CONST_CAST(GLEW_ARB_tessellation_shader) = !_glewInit_GL_ARB_tessellation_shader(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_tessellation_shader */
+#ifdef GL_ARB_texture_border_clamp
+ CONST_CAST(GLEW_ARB_texture_border_clamp) = _glewSearchExtension("GL_ARB_texture_border_clamp", extStart, extEnd);
+#endif /* GL_ARB_texture_border_clamp */
+#ifdef GL_ARB_texture_buffer_object
+ CONST_CAST(GLEW_ARB_texture_buffer_object) = _glewSearchExtension("GL_ARB_texture_buffer_object", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_texture_buffer_object) CONST_CAST(GLEW_ARB_texture_buffer_object) = !_glewInit_GL_ARB_texture_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_texture_buffer_object */
+#ifdef GL_ARB_texture_buffer_object_rgb32
+ CONST_CAST(GLEW_ARB_texture_buffer_object_rgb32) = _glewSearchExtension("GL_ARB_texture_buffer_object_rgb32", extStart, extEnd);
+#endif /* GL_ARB_texture_buffer_object_rgb32 */
+#ifdef GL_ARB_texture_buffer_range
+ CONST_CAST(GLEW_ARB_texture_buffer_range) = _glewSearchExtension("GL_ARB_texture_buffer_range", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_texture_buffer_range) CONST_CAST(GLEW_ARB_texture_buffer_range) = !_glewInit_GL_ARB_texture_buffer_range(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_texture_buffer_range */
+#ifdef GL_ARB_texture_compression
+ CONST_CAST(GLEW_ARB_texture_compression) = _glewSearchExtension("GL_ARB_texture_compression", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_texture_compression) CONST_CAST(GLEW_ARB_texture_compression) = !_glewInit_GL_ARB_texture_compression(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_texture_compression */
+#ifdef GL_ARB_texture_compression_bptc
+ CONST_CAST(GLEW_ARB_texture_compression_bptc) = _glewSearchExtension("GL_ARB_texture_compression_bptc", extStart, extEnd);
+#endif /* GL_ARB_texture_compression_bptc */
+#ifdef GL_ARB_texture_compression_rgtc
+ CONST_CAST(GLEW_ARB_texture_compression_rgtc) = _glewSearchExtension("GL_ARB_texture_compression_rgtc", extStart, extEnd);
+#endif /* GL_ARB_texture_compression_rgtc */
+#ifdef GL_ARB_texture_cube_map
+ CONST_CAST(GLEW_ARB_texture_cube_map) = _glewSearchExtension("GL_ARB_texture_cube_map", extStart, extEnd);
+#endif /* GL_ARB_texture_cube_map */
+#ifdef GL_ARB_texture_cube_map_array
+ CONST_CAST(GLEW_ARB_texture_cube_map_array) = _glewSearchExtension("GL_ARB_texture_cube_map_array", extStart, extEnd);
+#endif /* GL_ARB_texture_cube_map_array */
+#ifdef GL_ARB_texture_env_add
+ CONST_CAST(GLEW_ARB_texture_env_add) = _glewSearchExtension("GL_ARB_texture_env_add", extStart, extEnd);
+#endif /* GL_ARB_texture_env_add */
+#ifdef GL_ARB_texture_env_combine
+ CONST_CAST(GLEW_ARB_texture_env_combine) = _glewSearchExtension("GL_ARB_texture_env_combine", extStart, extEnd);
+#endif /* GL_ARB_texture_env_combine */
+#ifdef GL_ARB_texture_env_crossbar
+ CONST_CAST(GLEW_ARB_texture_env_crossbar) = _glewSearchExtension("GL_ARB_texture_env_crossbar", extStart, extEnd);
+#endif /* GL_ARB_texture_env_crossbar */
+#ifdef GL_ARB_texture_env_dot3
+ CONST_CAST(GLEW_ARB_texture_env_dot3) = _glewSearchExtension("GL_ARB_texture_env_dot3", extStart, extEnd);
+#endif /* GL_ARB_texture_env_dot3 */
+#ifdef GL_ARB_texture_float
+ CONST_CAST(GLEW_ARB_texture_float) = _glewSearchExtension("GL_ARB_texture_float", extStart, extEnd);
+#endif /* GL_ARB_texture_float */
+#ifdef GL_ARB_texture_gather
+ CONST_CAST(GLEW_ARB_texture_gather) = _glewSearchExtension("GL_ARB_texture_gather", extStart, extEnd);
+#endif /* GL_ARB_texture_gather */
+#ifdef GL_ARB_texture_mirror_clamp_to_edge
+ CONST_CAST(GLEW_ARB_texture_mirror_clamp_to_edge) = _glewSearchExtension("GL_ARB_texture_mirror_clamp_to_edge", extStart, extEnd);
+#endif /* GL_ARB_texture_mirror_clamp_to_edge */
+#ifdef GL_ARB_texture_mirrored_repeat
+ CONST_CAST(GLEW_ARB_texture_mirrored_repeat) = _glewSearchExtension("GL_ARB_texture_mirrored_repeat", extStart, extEnd);
+#endif /* GL_ARB_texture_mirrored_repeat */
+#ifdef GL_ARB_texture_multisample
+ CONST_CAST(GLEW_ARB_texture_multisample) = _glewSearchExtension("GL_ARB_texture_multisample", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_texture_multisample) CONST_CAST(GLEW_ARB_texture_multisample) = !_glewInit_GL_ARB_texture_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_texture_multisample */
+#ifdef GL_ARB_texture_non_power_of_two
+ CONST_CAST(GLEW_ARB_texture_non_power_of_two) = _glewSearchExtension("GL_ARB_texture_non_power_of_two", extStart, extEnd);
+#endif /* GL_ARB_texture_non_power_of_two */
+#ifdef GL_ARB_texture_query_levels
+ CONST_CAST(GLEW_ARB_texture_query_levels) = _glewSearchExtension("GL_ARB_texture_query_levels", extStart, extEnd);
+#endif /* GL_ARB_texture_query_levels */
+#ifdef GL_ARB_texture_query_lod
+ CONST_CAST(GLEW_ARB_texture_query_lod) = _glewSearchExtension("GL_ARB_texture_query_lod", extStart, extEnd);
+#endif /* GL_ARB_texture_query_lod */
+#ifdef GL_ARB_texture_rectangle
+ CONST_CAST(GLEW_ARB_texture_rectangle) = _glewSearchExtension("GL_ARB_texture_rectangle", extStart, extEnd);
+#endif /* GL_ARB_texture_rectangle */
+#ifdef GL_ARB_texture_rg
+ CONST_CAST(GLEW_ARB_texture_rg) = _glewSearchExtension("GL_ARB_texture_rg", extStart, extEnd);
+#endif /* GL_ARB_texture_rg */
+#ifdef GL_ARB_texture_rgb10_a2ui
+ CONST_CAST(GLEW_ARB_texture_rgb10_a2ui) = _glewSearchExtension("GL_ARB_texture_rgb10_a2ui", extStart, extEnd);
+#endif /* GL_ARB_texture_rgb10_a2ui */
+#ifdef GL_ARB_texture_stencil8
+ CONST_CAST(GLEW_ARB_texture_stencil8) = _glewSearchExtension("GL_ARB_texture_stencil8", extStart, extEnd);
+#endif /* GL_ARB_texture_stencil8 */
+#ifdef GL_ARB_texture_storage
+ CONST_CAST(GLEW_ARB_texture_storage) = _glewSearchExtension("GL_ARB_texture_storage", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_texture_storage) CONST_CAST(GLEW_ARB_texture_storage) = !_glewInit_GL_ARB_texture_storage(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_texture_storage */
+#ifdef GL_ARB_texture_storage_multisample
+ CONST_CAST(GLEW_ARB_texture_storage_multisample) = _glewSearchExtension("GL_ARB_texture_storage_multisample", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_texture_storage_multisample) CONST_CAST(GLEW_ARB_texture_storage_multisample) = !_glewInit_GL_ARB_texture_storage_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_texture_storage_multisample */
+#ifdef GL_ARB_texture_swizzle
+ CONST_CAST(GLEW_ARB_texture_swizzle) = _glewSearchExtension("GL_ARB_texture_swizzle", extStart, extEnd);
+#endif /* GL_ARB_texture_swizzle */
+#ifdef GL_ARB_texture_view
+ CONST_CAST(GLEW_ARB_texture_view) = _glewSearchExtension("GL_ARB_texture_view", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_texture_view) CONST_CAST(GLEW_ARB_texture_view) = !_glewInit_GL_ARB_texture_view(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_texture_view */
+#ifdef GL_ARB_timer_query
+ CONST_CAST(GLEW_ARB_timer_query) = _glewSearchExtension("GL_ARB_timer_query", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_timer_query) CONST_CAST(GLEW_ARB_timer_query) = !_glewInit_GL_ARB_timer_query(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_timer_query */
+#ifdef GL_ARB_transform_feedback2
+ CONST_CAST(GLEW_ARB_transform_feedback2) = _glewSearchExtension("GL_ARB_transform_feedback2", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_transform_feedback2) CONST_CAST(GLEW_ARB_transform_feedback2) = !_glewInit_GL_ARB_transform_feedback2(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_transform_feedback2 */
+#ifdef GL_ARB_transform_feedback3
+ CONST_CAST(GLEW_ARB_transform_feedback3) = _glewSearchExtension("GL_ARB_transform_feedback3", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_transform_feedback3) CONST_CAST(GLEW_ARB_transform_feedback3) = !_glewInit_GL_ARB_transform_feedback3(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_transform_feedback3 */
+#ifdef GL_ARB_transform_feedback_instanced
+ CONST_CAST(GLEW_ARB_transform_feedback_instanced) = _glewSearchExtension("GL_ARB_transform_feedback_instanced", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_transform_feedback_instanced) CONST_CAST(GLEW_ARB_transform_feedback_instanced) = !_glewInit_GL_ARB_transform_feedback_instanced(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_transform_feedback_instanced */
+#ifdef GL_ARB_transpose_matrix
+ CONST_CAST(GLEW_ARB_transpose_matrix) = _glewSearchExtension("GL_ARB_transpose_matrix", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_transpose_matrix) CONST_CAST(GLEW_ARB_transpose_matrix) = !_glewInit_GL_ARB_transpose_matrix(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_transpose_matrix */
+#ifdef GL_ARB_uniform_buffer_object
+ CONST_CAST(GLEW_ARB_uniform_buffer_object) = _glewSearchExtension("GL_ARB_uniform_buffer_object", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_uniform_buffer_object) CONST_CAST(GLEW_ARB_uniform_buffer_object) = !_glewInit_GL_ARB_uniform_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_uniform_buffer_object */
+#ifdef GL_ARB_vertex_array_bgra
+ CONST_CAST(GLEW_ARB_vertex_array_bgra) = _glewSearchExtension("GL_ARB_vertex_array_bgra", extStart, extEnd);
+#endif /* GL_ARB_vertex_array_bgra */
+#ifdef GL_ARB_vertex_array_object
+ CONST_CAST(GLEW_ARB_vertex_array_object) = _glewSearchExtension("GL_ARB_vertex_array_object", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_vertex_array_object) CONST_CAST(GLEW_ARB_vertex_array_object) = !_glewInit_GL_ARB_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_vertex_array_object */
+#ifdef GL_ARB_vertex_attrib_64bit
+ CONST_CAST(GLEW_ARB_vertex_attrib_64bit) = _glewSearchExtension("GL_ARB_vertex_attrib_64bit", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_vertex_attrib_64bit) CONST_CAST(GLEW_ARB_vertex_attrib_64bit) = !_glewInit_GL_ARB_vertex_attrib_64bit(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_vertex_attrib_64bit */
+#ifdef GL_ARB_vertex_attrib_binding
+ CONST_CAST(GLEW_ARB_vertex_attrib_binding) = _glewSearchExtension("GL_ARB_vertex_attrib_binding", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_vertex_attrib_binding) CONST_CAST(GLEW_ARB_vertex_attrib_binding) = !_glewInit_GL_ARB_vertex_attrib_binding(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_vertex_attrib_binding */
+#ifdef GL_ARB_vertex_blend
+ CONST_CAST(GLEW_ARB_vertex_blend) = _glewSearchExtension("GL_ARB_vertex_blend", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_vertex_blend) CONST_CAST(GLEW_ARB_vertex_blend) = !_glewInit_GL_ARB_vertex_blend(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_vertex_blend */
+#ifdef GL_ARB_vertex_buffer_object
+ CONST_CAST(GLEW_ARB_vertex_buffer_object) = _glewSearchExtension("GL_ARB_vertex_buffer_object", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_vertex_buffer_object) CONST_CAST(GLEW_ARB_vertex_buffer_object) = !_glewInit_GL_ARB_vertex_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_vertex_buffer_object */
+#ifdef GL_ARB_vertex_program
+ CONST_CAST(GLEW_ARB_vertex_program) = _glewSearchExtension("GL_ARB_vertex_program", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_vertex_program) CONST_CAST(GLEW_ARB_vertex_program) = !_glewInit_GL_ARB_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_vertex_program */
+#ifdef GL_ARB_vertex_shader
+ CONST_CAST(GLEW_ARB_vertex_shader) = _glewSearchExtension("GL_ARB_vertex_shader", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_vertex_shader) CONST_CAST(GLEW_ARB_vertex_shader) = !_glewInit_GL_ARB_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_vertex_shader */
+#ifdef GL_ARB_vertex_type_10f_11f_11f_rev
+ CONST_CAST(GLEW_ARB_vertex_type_10f_11f_11f_rev) = _glewSearchExtension("GL_ARB_vertex_type_10f_11f_11f_rev", extStart, extEnd);
+#endif /* GL_ARB_vertex_type_10f_11f_11f_rev */
+#ifdef GL_ARB_vertex_type_2_10_10_10_rev
+ CONST_CAST(GLEW_ARB_vertex_type_2_10_10_10_rev) = _glewSearchExtension("GL_ARB_vertex_type_2_10_10_10_rev", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_vertex_type_2_10_10_10_rev) CONST_CAST(GLEW_ARB_vertex_type_2_10_10_10_rev) = !_glewInit_GL_ARB_vertex_type_2_10_10_10_rev(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_vertex_type_2_10_10_10_rev */
+#ifdef GL_ARB_viewport_array
+ CONST_CAST(GLEW_ARB_viewport_array) = _glewSearchExtension("GL_ARB_viewport_array", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_viewport_array) CONST_CAST(GLEW_ARB_viewport_array) = !_glewInit_GL_ARB_viewport_array(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_viewport_array */
+#ifdef GL_ARB_window_pos
+ CONST_CAST(GLEW_ARB_window_pos) = _glewSearchExtension("GL_ARB_window_pos", extStart, extEnd);
+ if (glewExperimental || GLEW_ARB_window_pos) CONST_CAST(GLEW_ARB_window_pos) = !_glewInit_GL_ARB_window_pos(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ARB_window_pos */
+#ifdef GL_ATIX_point_sprites
+ CONST_CAST(GLEW_ATIX_point_sprites) = _glewSearchExtension("GL_ATIX_point_sprites", extStart, extEnd);
+#endif /* GL_ATIX_point_sprites */
+#ifdef GL_ATIX_texture_env_combine3
+ CONST_CAST(GLEW_ATIX_texture_env_combine3) = _glewSearchExtension("GL_ATIX_texture_env_combine3", extStart, extEnd);
+#endif /* GL_ATIX_texture_env_combine3 */
+#ifdef GL_ATIX_texture_env_route
+ CONST_CAST(GLEW_ATIX_texture_env_route) = _glewSearchExtension("GL_ATIX_texture_env_route", extStart, extEnd);
+#endif /* GL_ATIX_texture_env_route */
+#ifdef GL_ATIX_vertex_shader_output_point_size
+ CONST_CAST(GLEW_ATIX_vertex_shader_output_point_size) = _glewSearchExtension("GL_ATIX_vertex_shader_output_point_size", extStart, extEnd);
+#endif /* GL_ATIX_vertex_shader_output_point_size */
+#ifdef GL_ATI_draw_buffers
+ CONST_CAST(GLEW_ATI_draw_buffers) = _glewSearchExtension("GL_ATI_draw_buffers", extStart, extEnd);
+ if (glewExperimental || GLEW_ATI_draw_buffers) CONST_CAST(GLEW_ATI_draw_buffers) = !_glewInit_GL_ATI_draw_buffers(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ATI_draw_buffers */
+#ifdef GL_ATI_element_array
+ CONST_CAST(GLEW_ATI_element_array) = _glewSearchExtension("GL_ATI_element_array", extStart, extEnd);
+ if (glewExperimental || GLEW_ATI_element_array) CONST_CAST(GLEW_ATI_element_array) = !_glewInit_GL_ATI_element_array(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ATI_element_array */
+#ifdef GL_ATI_envmap_bumpmap
+ CONST_CAST(GLEW_ATI_envmap_bumpmap) = _glewSearchExtension("GL_ATI_envmap_bumpmap", extStart, extEnd);
+ if (glewExperimental || GLEW_ATI_envmap_bumpmap) CONST_CAST(GLEW_ATI_envmap_bumpmap) = !_glewInit_GL_ATI_envmap_bumpmap(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ATI_envmap_bumpmap */
+#ifdef GL_ATI_fragment_shader
+ CONST_CAST(GLEW_ATI_fragment_shader) = _glewSearchExtension("GL_ATI_fragment_shader", extStart, extEnd);
+ if (glewExperimental || GLEW_ATI_fragment_shader) CONST_CAST(GLEW_ATI_fragment_shader) = !_glewInit_GL_ATI_fragment_shader(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ATI_fragment_shader */
+#ifdef GL_ATI_map_object_buffer
+ CONST_CAST(GLEW_ATI_map_object_buffer) = _glewSearchExtension("GL_ATI_map_object_buffer", extStart, extEnd);
+ if (glewExperimental || GLEW_ATI_map_object_buffer) CONST_CAST(GLEW_ATI_map_object_buffer) = !_glewInit_GL_ATI_map_object_buffer(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ATI_map_object_buffer */
+#ifdef GL_ATI_meminfo
+ CONST_CAST(GLEW_ATI_meminfo) = _glewSearchExtension("GL_ATI_meminfo", extStart, extEnd);
+#endif /* GL_ATI_meminfo */
+#ifdef GL_ATI_pn_triangles
+ CONST_CAST(GLEW_ATI_pn_triangles) = _glewSearchExtension("GL_ATI_pn_triangles", extStart, extEnd);
+ if (glewExperimental || GLEW_ATI_pn_triangles) CONST_CAST(GLEW_ATI_pn_triangles) = !_glewInit_GL_ATI_pn_triangles(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ATI_pn_triangles */
+#ifdef GL_ATI_separate_stencil
+ CONST_CAST(GLEW_ATI_separate_stencil) = _glewSearchExtension("GL_ATI_separate_stencil", extStart, extEnd);
+ if (glewExperimental || GLEW_ATI_separate_stencil) CONST_CAST(GLEW_ATI_separate_stencil) = !_glewInit_GL_ATI_separate_stencil(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ATI_separate_stencil */
+#ifdef GL_ATI_shader_texture_lod
+ CONST_CAST(GLEW_ATI_shader_texture_lod) = _glewSearchExtension("GL_ATI_shader_texture_lod", extStart, extEnd);
+#endif /* GL_ATI_shader_texture_lod */
+#ifdef GL_ATI_text_fragment_shader
+ CONST_CAST(GLEW_ATI_text_fragment_shader) = _glewSearchExtension("GL_ATI_text_fragment_shader", extStart, extEnd);
+#endif /* GL_ATI_text_fragment_shader */
+#ifdef GL_ATI_texture_compression_3dc
+ CONST_CAST(GLEW_ATI_texture_compression_3dc) = _glewSearchExtension("GL_ATI_texture_compression_3dc", extStart, extEnd);
+#endif /* GL_ATI_texture_compression_3dc */
+#ifdef GL_ATI_texture_env_combine3
+ CONST_CAST(GLEW_ATI_texture_env_combine3) = _glewSearchExtension("GL_ATI_texture_env_combine3", extStart, extEnd);
+#endif /* GL_ATI_texture_env_combine3 */
+#ifdef GL_ATI_texture_float
+ CONST_CAST(GLEW_ATI_texture_float) = _glewSearchExtension("GL_ATI_texture_float", extStart, extEnd);
+#endif /* GL_ATI_texture_float */
+#ifdef GL_ATI_texture_mirror_once
+ CONST_CAST(GLEW_ATI_texture_mirror_once) = _glewSearchExtension("GL_ATI_texture_mirror_once", extStart, extEnd);
+#endif /* GL_ATI_texture_mirror_once */
+#ifdef GL_ATI_vertex_array_object
+ CONST_CAST(GLEW_ATI_vertex_array_object) = _glewSearchExtension("GL_ATI_vertex_array_object", extStart, extEnd);
+ if (glewExperimental || GLEW_ATI_vertex_array_object) CONST_CAST(GLEW_ATI_vertex_array_object) = !_glewInit_GL_ATI_vertex_array_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ATI_vertex_array_object */
+#ifdef GL_ATI_vertex_attrib_array_object
+ CONST_CAST(GLEW_ATI_vertex_attrib_array_object) = _glewSearchExtension("GL_ATI_vertex_attrib_array_object", extStart, extEnd);
+ if (glewExperimental || GLEW_ATI_vertex_attrib_array_object) CONST_CAST(GLEW_ATI_vertex_attrib_array_object) = !_glewInit_GL_ATI_vertex_attrib_array_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ATI_vertex_attrib_array_object */
+#ifdef GL_ATI_vertex_streams
+ CONST_CAST(GLEW_ATI_vertex_streams) = _glewSearchExtension("GL_ATI_vertex_streams", extStart, extEnd);
+ if (glewExperimental || GLEW_ATI_vertex_streams) CONST_CAST(GLEW_ATI_vertex_streams) = !_glewInit_GL_ATI_vertex_streams(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_ATI_vertex_streams */
+#ifdef GL_EXT_422_pixels
+ CONST_CAST(GLEW_EXT_422_pixels) = _glewSearchExtension("GL_EXT_422_pixels", extStart, extEnd);
+#endif /* GL_EXT_422_pixels */
+#ifdef GL_EXT_Cg_shader
+ CONST_CAST(GLEW_EXT_Cg_shader) = _glewSearchExtension("GL_EXT_Cg_shader", extStart, extEnd);
+#endif /* GL_EXT_Cg_shader */
+#ifdef GL_EXT_abgr
+ CONST_CAST(GLEW_EXT_abgr) = _glewSearchExtension("GL_EXT_abgr", extStart, extEnd);
+#endif /* GL_EXT_abgr */
+#ifdef GL_EXT_bgra
+ CONST_CAST(GLEW_EXT_bgra) = _glewSearchExtension("GL_EXT_bgra", extStart, extEnd);
+#endif /* GL_EXT_bgra */
+#ifdef GL_EXT_bindable_uniform
+ CONST_CAST(GLEW_EXT_bindable_uniform) = _glewSearchExtension("GL_EXT_bindable_uniform", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_bindable_uniform) CONST_CAST(GLEW_EXT_bindable_uniform) = !_glewInit_GL_EXT_bindable_uniform(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_bindable_uniform */
+#ifdef GL_EXT_blend_color
+ CONST_CAST(GLEW_EXT_blend_color) = _glewSearchExtension("GL_EXT_blend_color", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_blend_color) CONST_CAST(GLEW_EXT_blend_color) = !_glewInit_GL_EXT_blend_color(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_blend_color */
+#ifdef GL_EXT_blend_equation_separate
+ CONST_CAST(GLEW_EXT_blend_equation_separate) = _glewSearchExtension("GL_EXT_blend_equation_separate", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_blend_equation_separate) CONST_CAST(GLEW_EXT_blend_equation_separate) = !_glewInit_GL_EXT_blend_equation_separate(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_blend_equation_separate */
+#ifdef GL_EXT_blend_func_separate
+ CONST_CAST(GLEW_EXT_blend_func_separate) = _glewSearchExtension("GL_EXT_blend_func_separate", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_blend_func_separate) CONST_CAST(GLEW_EXT_blend_func_separate) = !_glewInit_GL_EXT_blend_func_separate(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_blend_func_separate */
+#ifdef GL_EXT_blend_logic_op
+ CONST_CAST(GLEW_EXT_blend_logic_op) = _glewSearchExtension("GL_EXT_blend_logic_op", extStart, extEnd);
+#endif /* GL_EXT_blend_logic_op */
+#ifdef GL_EXT_blend_minmax
+ CONST_CAST(GLEW_EXT_blend_minmax) = _glewSearchExtension("GL_EXT_blend_minmax", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_blend_minmax) CONST_CAST(GLEW_EXT_blend_minmax) = !_glewInit_GL_EXT_blend_minmax(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_blend_minmax */
+#ifdef GL_EXT_blend_subtract
+ CONST_CAST(GLEW_EXT_blend_subtract) = _glewSearchExtension("GL_EXT_blend_subtract", extStart, extEnd);
+#endif /* GL_EXT_blend_subtract */
+#ifdef GL_EXT_clip_volume_hint
+ CONST_CAST(GLEW_EXT_clip_volume_hint) = _glewSearchExtension("GL_EXT_clip_volume_hint", extStart, extEnd);
+#endif /* GL_EXT_clip_volume_hint */
+#ifdef GL_EXT_cmyka
+ CONST_CAST(GLEW_EXT_cmyka) = _glewSearchExtension("GL_EXT_cmyka", extStart, extEnd);
+#endif /* GL_EXT_cmyka */
+#ifdef GL_EXT_color_subtable
+ CONST_CAST(GLEW_EXT_color_subtable) = _glewSearchExtension("GL_EXT_color_subtable", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_color_subtable) CONST_CAST(GLEW_EXT_color_subtable) = !_glewInit_GL_EXT_color_subtable(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_color_subtable */
+#ifdef GL_EXT_compiled_vertex_array
+ CONST_CAST(GLEW_EXT_compiled_vertex_array) = _glewSearchExtension("GL_EXT_compiled_vertex_array", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_compiled_vertex_array) CONST_CAST(GLEW_EXT_compiled_vertex_array) = !_glewInit_GL_EXT_compiled_vertex_array(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_compiled_vertex_array */
+#ifdef GL_EXT_convolution
+ CONST_CAST(GLEW_EXT_convolution) = _glewSearchExtension("GL_EXT_convolution", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_convolution) CONST_CAST(GLEW_EXT_convolution) = !_glewInit_GL_EXT_convolution(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_convolution */
+#ifdef GL_EXT_coordinate_frame
+ CONST_CAST(GLEW_EXT_coordinate_frame) = _glewSearchExtension("GL_EXT_coordinate_frame", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_coordinate_frame) CONST_CAST(GLEW_EXT_coordinate_frame) = !_glewInit_GL_EXT_coordinate_frame(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_coordinate_frame */
+#ifdef GL_EXT_copy_texture
+ CONST_CAST(GLEW_EXT_copy_texture) = _glewSearchExtension("GL_EXT_copy_texture", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_copy_texture) CONST_CAST(GLEW_EXT_copy_texture) = !_glewInit_GL_EXT_copy_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_copy_texture */
+#ifdef GL_EXT_cull_vertex
+ CONST_CAST(GLEW_EXT_cull_vertex) = _glewSearchExtension("GL_EXT_cull_vertex", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_cull_vertex) CONST_CAST(GLEW_EXT_cull_vertex) = !_glewInit_GL_EXT_cull_vertex(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_cull_vertex */
+#ifdef GL_EXT_debug_marker
+ CONST_CAST(GLEW_EXT_debug_marker) = _glewSearchExtension("GL_EXT_debug_marker", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_debug_marker) CONST_CAST(GLEW_EXT_debug_marker) = !_glewInit_GL_EXT_debug_marker(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_debug_marker */
+#ifdef GL_EXT_depth_bounds_test
+ CONST_CAST(GLEW_EXT_depth_bounds_test) = _glewSearchExtension("GL_EXT_depth_bounds_test", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_depth_bounds_test) CONST_CAST(GLEW_EXT_depth_bounds_test) = !_glewInit_GL_EXT_depth_bounds_test(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_depth_bounds_test */
+#ifdef GL_EXT_direct_state_access
+ CONST_CAST(GLEW_EXT_direct_state_access) = _glewSearchExtension("GL_EXT_direct_state_access", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_direct_state_access) CONST_CAST(GLEW_EXT_direct_state_access) = !_glewInit_GL_EXT_direct_state_access(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_direct_state_access */
+#ifdef GL_EXT_draw_buffers2
+ CONST_CAST(GLEW_EXT_draw_buffers2) = _glewSearchExtension("GL_EXT_draw_buffers2", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_draw_buffers2) CONST_CAST(GLEW_EXT_draw_buffers2) = !_glewInit_GL_EXT_draw_buffers2(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_draw_buffers2 */
+#ifdef GL_EXT_draw_instanced
+ CONST_CAST(GLEW_EXT_draw_instanced) = _glewSearchExtension("GL_EXT_draw_instanced", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_draw_instanced) CONST_CAST(GLEW_EXT_draw_instanced) = !_glewInit_GL_EXT_draw_instanced(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_draw_instanced */
+#ifdef GL_EXT_draw_range_elements
+ CONST_CAST(GLEW_EXT_draw_range_elements) = _glewSearchExtension("GL_EXT_draw_range_elements", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_draw_range_elements) CONST_CAST(GLEW_EXT_draw_range_elements) = !_glewInit_GL_EXT_draw_range_elements(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_draw_range_elements */
+#ifdef GL_EXT_fog_coord
+ CONST_CAST(GLEW_EXT_fog_coord) = _glewSearchExtension("GL_EXT_fog_coord", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_fog_coord) CONST_CAST(GLEW_EXT_fog_coord) = !_glewInit_GL_EXT_fog_coord(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_fog_coord */
+#ifdef GL_EXT_fragment_lighting
+ CONST_CAST(GLEW_EXT_fragment_lighting) = _glewSearchExtension("GL_EXT_fragment_lighting", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_fragment_lighting) CONST_CAST(GLEW_EXT_fragment_lighting) = !_glewInit_GL_EXT_fragment_lighting(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_fragment_lighting */
+#ifdef GL_EXT_framebuffer_blit
+ CONST_CAST(GLEW_EXT_framebuffer_blit) = _glewSearchExtension("GL_EXT_framebuffer_blit", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_framebuffer_blit) CONST_CAST(GLEW_EXT_framebuffer_blit) = !_glewInit_GL_EXT_framebuffer_blit(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_framebuffer_blit */
+#ifdef GL_EXT_framebuffer_multisample
+ CONST_CAST(GLEW_EXT_framebuffer_multisample) = _glewSearchExtension("GL_EXT_framebuffer_multisample", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_framebuffer_multisample) CONST_CAST(GLEW_EXT_framebuffer_multisample) = !_glewInit_GL_EXT_framebuffer_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_framebuffer_multisample */
+#ifdef GL_EXT_framebuffer_multisample_blit_scaled
+ CONST_CAST(GLEW_EXT_framebuffer_multisample_blit_scaled) = _glewSearchExtension("GL_EXT_framebuffer_multisample_blit_scaled", extStart, extEnd);
+#endif /* GL_EXT_framebuffer_multisample_blit_scaled */
+#ifdef GL_EXT_framebuffer_object
+ CONST_CAST(GLEW_EXT_framebuffer_object) = _glewSearchExtension("GL_EXT_framebuffer_object", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_framebuffer_object) CONST_CAST(GLEW_EXT_framebuffer_object) = !_glewInit_GL_EXT_framebuffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_framebuffer_object */
+#ifdef GL_EXT_framebuffer_sRGB
+ CONST_CAST(GLEW_EXT_framebuffer_sRGB) = _glewSearchExtension("GL_EXT_framebuffer_sRGB", extStart, extEnd);
+#endif /* GL_EXT_framebuffer_sRGB */
+#ifdef GL_EXT_geometry_shader4
+ CONST_CAST(GLEW_EXT_geometry_shader4) = _glewSearchExtension("GL_EXT_geometry_shader4", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_geometry_shader4) CONST_CAST(GLEW_EXT_geometry_shader4) = !_glewInit_GL_EXT_geometry_shader4(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_geometry_shader4 */
+#ifdef GL_EXT_gpu_program_parameters
+ CONST_CAST(GLEW_EXT_gpu_program_parameters) = _glewSearchExtension("GL_EXT_gpu_program_parameters", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_gpu_program_parameters) CONST_CAST(GLEW_EXT_gpu_program_parameters) = !_glewInit_GL_EXT_gpu_program_parameters(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_gpu_program_parameters */
+#ifdef GL_EXT_gpu_shader4
+ CONST_CAST(GLEW_EXT_gpu_shader4) = _glewSearchExtension("GL_EXT_gpu_shader4", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_gpu_shader4) CONST_CAST(GLEW_EXT_gpu_shader4) = !_glewInit_GL_EXT_gpu_shader4(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_gpu_shader4 */
+#ifdef GL_EXT_histogram
+ CONST_CAST(GLEW_EXT_histogram) = _glewSearchExtension("GL_EXT_histogram", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_histogram) CONST_CAST(GLEW_EXT_histogram) = !_glewInit_GL_EXT_histogram(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_histogram */
+#ifdef GL_EXT_index_array_formats
+ CONST_CAST(GLEW_EXT_index_array_formats) = _glewSearchExtension("GL_EXT_index_array_formats", extStart, extEnd);
+#endif /* GL_EXT_index_array_formats */
+#ifdef GL_EXT_index_func
+ CONST_CAST(GLEW_EXT_index_func) = _glewSearchExtension("GL_EXT_index_func", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_index_func) CONST_CAST(GLEW_EXT_index_func) = !_glewInit_GL_EXT_index_func(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_index_func */
+#ifdef GL_EXT_index_material
+ CONST_CAST(GLEW_EXT_index_material) = _glewSearchExtension("GL_EXT_index_material", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_index_material) CONST_CAST(GLEW_EXT_index_material) = !_glewInit_GL_EXT_index_material(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_index_material */
+#ifdef GL_EXT_index_texture
+ CONST_CAST(GLEW_EXT_index_texture) = _glewSearchExtension("GL_EXT_index_texture", extStart, extEnd);
+#endif /* GL_EXT_index_texture */
+#ifdef GL_EXT_light_texture
+ CONST_CAST(GLEW_EXT_light_texture) = _glewSearchExtension("GL_EXT_light_texture", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_light_texture) CONST_CAST(GLEW_EXT_light_texture) = !_glewInit_GL_EXT_light_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_light_texture */
+#ifdef GL_EXT_misc_attribute
+ CONST_CAST(GLEW_EXT_misc_attribute) = _glewSearchExtension("GL_EXT_misc_attribute", extStart, extEnd);
+#endif /* GL_EXT_misc_attribute */
+#ifdef GL_EXT_multi_draw_arrays
+ CONST_CAST(GLEW_EXT_multi_draw_arrays) = _glewSearchExtension("GL_EXT_multi_draw_arrays", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_multi_draw_arrays) CONST_CAST(GLEW_EXT_multi_draw_arrays) = !_glewInit_GL_EXT_multi_draw_arrays(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_multi_draw_arrays */
+#ifdef GL_EXT_multisample
+ CONST_CAST(GLEW_EXT_multisample) = _glewSearchExtension("GL_EXT_multisample", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_multisample) CONST_CAST(GLEW_EXT_multisample) = !_glewInit_GL_EXT_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_multisample */
+#ifdef GL_EXT_packed_depth_stencil
+ CONST_CAST(GLEW_EXT_packed_depth_stencil) = _glewSearchExtension("GL_EXT_packed_depth_stencil", extStart, extEnd);
+#endif /* GL_EXT_packed_depth_stencil */
+#ifdef GL_EXT_packed_float
+ CONST_CAST(GLEW_EXT_packed_float) = _glewSearchExtension("GL_EXT_packed_float", extStart, extEnd);
+#endif /* GL_EXT_packed_float */
+#ifdef GL_EXT_packed_pixels
+ CONST_CAST(GLEW_EXT_packed_pixels) = _glewSearchExtension("GL_EXT_packed_pixels", extStart, extEnd);
+#endif /* GL_EXT_packed_pixels */
+#ifdef GL_EXT_paletted_texture
+ CONST_CAST(GLEW_EXT_paletted_texture) = _glewSearchExtension("GL_EXT_paletted_texture", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_paletted_texture) CONST_CAST(GLEW_EXT_paletted_texture) = !_glewInit_GL_EXT_paletted_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_paletted_texture */
+#ifdef GL_EXT_pixel_buffer_object
+ CONST_CAST(GLEW_EXT_pixel_buffer_object) = _glewSearchExtension("GL_EXT_pixel_buffer_object", extStart, extEnd);
+#endif /* GL_EXT_pixel_buffer_object */
+#ifdef GL_EXT_pixel_transform
+ CONST_CAST(GLEW_EXT_pixel_transform) = _glewSearchExtension("GL_EXT_pixel_transform", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_pixel_transform) CONST_CAST(GLEW_EXT_pixel_transform) = !_glewInit_GL_EXT_pixel_transform(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_pixel_transform */
+#ifdef GL_EXT_pixel_transform_color_table
+ CONST_CAST(GLEW_EXT_pixel_transform_color_table) = _glewSearchExtension("GL_EXT_pixel_transform_color_table", extStart, extEnd);
+#endif /* GL_EXT_pixel_transform_color_table */
+#ifdef GL_EXT_point_parameters
+ CONST_CAST(GLEW_EXT_point_parameters) = _glewSearchExtension("GL_EXT_point_parameters", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_point_parameters) CONST_CAST(GLEW_EXT_point_parameters) = !_glewInit_GL_EXT_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_point_parameters */
+#ifdef GL_EXT_polygon_offset
+ CONST_CAST(GLEW_EXT_polygon_offset) = _glewSearchExtension("GL_EXT_polygon_offset", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_polygon_offset) CONST_CAST(GLEW_EXT_polygon_offset) = !_glewInit_GL_EXT_polygon_offset(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_polygon_offset */
+#ifdef GL_EXT_provoking_vertex
+ CONST_CAST(GLEW_EXT_provoking_vertex) = _glewSearchExtension("GL_EXT_provoking_vertex", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_provoking_vertex) CONST_CAST(GLEW_EXT_provoking_vertex) = !_glewInit_GL_EXT_provoking_vertex(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_provoking_vertex */
+#ifdef GL_EXT_rescale_normal
+ CONST_CAST(GLEW_EXT_rescale_normal) = _glewSearchExtension("GL_EXT_rescale_normal", extStart, extEnd);
+#endif /* GL_EXT_rescale_normal */
+#ifdef GL_EXT_scene_marker
+ CONST_CAST(GLEW_EXT_scene_marker) = _glewSearchExtension("GL_EXT_scene_marker", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_scene_marker) CONST_CAST(GLEW_EXT_scene_marker) = !_glewInit_GL_EXT_scene_marker(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_scene_marker */
+#ifdef GL_EXT_secondary_color
+ CONST_CAST(GLEW_EXT_secondary_color) = _glewSearchExtension("GL_EXT_secondary_color", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_secondary_color) CONST_CAST(GLEW_EXT_secondary_color) = !_glewInit_GL_EXT_secondary_color(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_secondary_color */
+#ifdef GL_EXT_separate_shader_objects
+ CONST_CAST(GLEW_EXT_separate_shader_objects) = _glewSearchExtension("GL_EXT_separate_shader_objects", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_separate_shader_objects) CONST_CAST(GLEW_EXT_separate_shader_objects) = !_glewInit_GL_EXT_separate_shader_objects(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_separate_shader_objects */
+#ifdef GL_EXT_separate_specular_color
+ CONST_CAST(GLEW_EXT_separate_specular_color) = _glewSearchExtension("GL_EXT_separate_specular_color", extStart, extEnd);
+#endif /* GL_EXT_separate_specular_color */
+#ifdef GL_EXT_shader_image_load_store
+ CONST_CAST(GLEW_EXT_shader_image_load_store) = _glewSearchExtension("GL_EXT_shader_image_load_store", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_shader_image_load_store) CONST_CAST(GLEW_EXT_shader_image_load_store) = !_glewInit_GL_EXT_shader_image_load_store(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_shader_image_load_store */
+#ifdef GL_EXT_shadow_funcs
+ CONST_CAST(GLEW_EXT_shadow_funcs) = _glewSearchExtension("GL_EXT_shadow_funcs", extStart, extEnd);
+#endif /* GL_EXT_shadow_funcs */
+#ifdef GL_EXT_shared_texture_palette
+ CONST_CAST(GLEW_EXT_shared_texture_palette) = _glewSearchExtension("GL_EXT_shared_texture_palette", extStart, extEnd);
+#endif /* GL_EXT_shared_texture_palette */
+#ifdef GL_EXT_stencil_clear_tag
+ CONST_CAST(GLEW_EXT_stencil_clear_tag) = _glewSearchExtension("GL_EXT_stencil_clear_tag", extStart, extEnd);
+#endif /* GL_EXT_stencil_clear_tag */
+#ifdef GL_EXT_stencil_two_side
+ CONST_CAST(GLEW_EXT_stencil_two_side) = _glewSearchExtension("GL_EXT_stencil_two_side", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_stencil_two_side) CONST_CAST(GLEW_EXT_stencil_two_side) = !_glewInit_GL_EXT_stencil_two_side(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_stencil_two_side */
+#ifdef GL_EXT_stencil_wrap
+ CONST_CAST(GLEW_EXT_stencil_wrap) = _glewSearchExtension("GL_EXT_stencil_wrap", extStart, extEnd);
+#endif /* GL_EXT_stencil_wrap */
+#ifdef GL_EXT_subtexture
+ CONST_CAST(GLEW_EXT_subtexture) = _glewSearchExtension("GL_EXT_subtexture", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_subtexture) CONST_CAST(GLEW_EXT_subtexture) = !_glewInit_GL_EXT_subtexture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_subtexture */
+#ifdef GL_EXT_texture
+ CONST_CAST(GLEW_EXT_texture) = _glewSearchExtension("GL_EXT_texture", extStart, extEnd);
+#endif /* GL_EXT_texture */
+#ifdef GL_EXT_texture3D
+ CONST_CAST(GLEW_EXT_texture3D) = _glewSearchExtension("GL_EXT_texture3D", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_texture3D) CONST_CAST(GLEW_EXT_texture3D) = !_glewInit_GL_EXT_texture3D(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_texture3D */
+#ifdef GL_EXT_texture_array
+ CONST_CAST(GLEW_EXT_texture_array) = _glewSearchExtension("GL_EXT_texture_array", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_texture_array) CONST_CAST(GLEW_EXT_texture_array) = !_glewInit_GL_EXT_texture_array(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_texture_array */
+#ifdef GL_EXT_texture_buffer_object
+ CONST_CAST(GLEW_EXT_texture_buffer_object) = _glewSearchExtension("GL_EXT_texture_buffer_object", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_texture_buffer_object) CONST_CAST(GLEW_EXT_texture_buffer_object) = !_glewInit_GL_EXT_texture_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_texture_buffer_object */
+#ifdef GL_EXT_texture_compression_dxt1
+ CONST_CAST(GLEW_EXT_texture_compression_dxt1) = _glewSearchExtension("GL_EXT_texture_compression_dxt1", extStart, extEnd);
+#endif /* GL_EXT_texture_compression_dxt1 */
+#ifdef GL_EXT_texture_compression_latc
+ CONST_CAST(GLEW_EXT_texture_compression_latc) = _glewSearchExtension("GL_EXT_texture_compression_latc", extStart, extEnd);
+#endif /* GL_EXT_texture_compression_latc */
+#ifdef GL_EXT_texture_compression_rgtc
+ CONST_CAST(GLEW_EXT_texture_compression_rgtc) = _glewSearchExtension("GL_EXT_texture_compression_rgtc", extStart, extEnd);
+#endif /* GL_EXT_texture_compression_rgtc */
+#ifdef GL_EXT_texture_compression_s3tc
+ CONST_CAST(GLEW_EXT_texture_compression_s3tc) = _glewSearchExtension("GL_EXT_texture_compression_s3tc", extStart, extEnd);
+#endif /* GL_EXT_texture_compression_s3tc */
+#ifdef GL_EXT_texture_cube_map
+ CONST_CAST(GLEW_EXT_texture_cube_map) = _glewSearchExtension("GL_EXT_texture_cube_map", extStart, extEnd);
+#endif /* GL_EXT_texture_cube_map */
+#ifdef GL_EXT_texture_edge_clamp
+ CONST_CAST(GLEW_EXT_texture_edge_clamp) = _glewSearchExtension("GL_EXT_texture_edge_clamp", extStart, extEnd);
+#endif /* GL_EXT_texture_edge_clamp */
+#ifdef GL_EXT_texture_env
+ CONST_CAST(GLEW_EXT_texture_env) = _glewSearchExtension("GL_EXT_texture_env", extStart, extEnd);
+#endif /* GL_EXT_texture_env */
+#ifdef GL_EXT_texture_env_add
+ CONST_CAST(GLEW_EXT_texture_env_add) = _glewSearchExtension("GL_EXT_texture_env_add", extStart, extEnd);
+#endif /* GL_EXT_texture_env_add */
+#ifdef GL_EXT_texture_env_combine
+ CONST_CAST(GLEW_EXT_texture_env_combine) = _glewSearchExtension("GL_EXT_texture_env_combine", extStart, extEnd);
+#endif /* GL_EXT_texture_env_combine */
+#ifdef GL_EXT_texture_env_dot3
+ CONST_CAST(GLEW_EXT_texture_env_dot3) = _glewSearchExtension("GL_EXT_texture_env_dot3", extStart, extEnd);
+#endif /* GL_EXT_texture_env_dot3 */
+#ifdef GL_EXT_texture_filter_anisotropic
+ CONST_CAST(GLEW_EXT_texture_filter_anisotropic) = _glewSearchExtension("GL_EXT_texture_filter_anisotropic", extStart, extEnd);
+#endif /* GL_EXT_texture_filter_anisotropic */
+#ifdef GL_EXT_texture_integer
+ CONST_CAST(GLEW_EXT_texture_integer) = _glewSearchExtension("GL_EXT_texture_integer", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_texture_integer) CONST_CAST(GLEW_EXT_texture_integer) = !_glewInit_GL_EXT_texture_integer(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_texture_integer */
+#ifdef GL_EXT_texture_lod_bias
+ CONST_CAST(GLEW_EXT_texture_lod_bias) = _glewSearchExtension("GL_EXT_texture_lod_bias", extStart, extEnd);
+#endif /* GL_EXT_texture_lod_bias */
+#ifdef GL_EXT_texture_mirror_clamp
+ CONST_CAST(GLEW_EXT_texture_mirror_clamp) = _glewSearchExtension("GL_EXT_texture_mirror_clamp", extStart, extEnd);
+#endif /* GL_EXT_texture_mirror_clamp */
+#ifdef GL_EXT_texture_object
+ CONST_CAST(GLEW_EXT_texture_object) = _glewSearchExtension("GL_EXT_texture_object", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_texture_object) CONST_CAST(GLEW_EXT_texture_object) = !_glewInit_GL_EXT_texture_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_texture_object */
+#ifdef GL_EXT_texture_perturb_normal
+ CONST_CAST(GLEW_EXT_texture_perturb_normal) = _glewSearchExtension("GL_EXT_texture_perturb_normal", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_texture_perturb_normal) CONST_CAST(GLEW_EXT_texture_perturb_normal) = !_glewInit_GL_EXT_texture_perturb_normal(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_texture_perturb_normal */
+#ifdef GL_EXT_texture_rectangle
+ CONST_CAST(GLEW_EXT_texture_rectangle) = _glewSearchExtension("GL_EXT_texture_rectangle", extStart, extEnd);
+#endif /* GL_EXT_texture_rectangle */
+#ifdef GL_EXT_texture_sRGB
+ CONST_CAST(GLEW_EXT_texture_sRGB) = _glewSearchExtension("GL_EXT_texture_sRGB", extStart, extEnd);
+#endif /* GL_EXT_texture_sRGB */
+#ifdef GL_EXT_texture_sRGB_decode
+ CONST_CAST(GLEW_EXT_texture_sRGB_decode) = _glewSearchExtension("GL_EXT_texture_sRGB_decode", extStart, extEnd);
+#endif /* GL_EXT_texture_sRGB_decode */
+#ifdef GL_EXT_texture_shared_exponent
+ CONST_CAST(GLEW_EXT_texture_shared_exponent) = _glewSearchExtension("GL_EXT_texture_shared_exponent", extStart, extEnd);
+#endif /* GL_EXT_texture_shared_exponent */
+#ifdef GL_EXT_texture_snorm
+ CONST_CAST(GLEW_EXT_texture_snorm) = _glewSearchExtension("GL_EXT_texture_snorm", extStart, extEnd);
+#endif /* GL_EXT_texture_snorm */
+#ifdef GL_EXT_texture_swizzle
+ CONST_CAST(GLEW_EXT_texture_swizzle) = _glewSearchExtension("GL_EXT_texture_swizzle", extStart, extEnd);
+#endif /* GL_EXT_texture_swizzle */
+#ifdef GL_EXT_timer_query
+ CONST_CAST(GLEW_EXT_timer_query) = _glewSearchExtension("GL_EXT_timer_query", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_timer_query) CONST_CAST(GLEW_EXT_timer_query) = !_glewInit_GL_EXT_timer_query(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_timer_query */
+#ifdef GL_EXT_transform_feedback
+ CONST_CAST(GLEW_EXT_transform_feedback) = _glewSearchExtension("GL_EXT_transform_feedback", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_transform_feedback) CONST_CAST(GLEW_EXT_transform_feedback) = !_glewInit_GL_EXT_transform_feedback(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_transform_feedback */
+#ifdef GL_EXT_vertex_array
+ CONST_CAST(GLEW_EXT_vertex_array) = _glewSearchExtension("GL_EXT_vertex_array", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_vertex_array) CONST_CAST(GLEW_EXT_vertex_array) = !_glewInit_GL_EXT_vertex_array(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_vertex_array */
+#ifdef GL_EXT_vertex_array_bgra
+ CONST_CAST(GLEW_EXT_vertex_array_bgra) = _glewSearchExtension("GL_EXT_vertex_array_bgra", extStart, extEnd);
+#endif /* GL_EXT_vertex_array_bgra */
+#ifdef GL_EXT_vertex_attrib_64bit
+ CONST_CAST(GLEW_EXT_vertex_attrib_64bit) = _glewSearchExtension("GL_EXT_vertex_attrib_64bit", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_vertex_attrib_64bit) CONST_CAST(GLEW_EXT_vertex_attrib_64bit) = !_glewInit_GL_EXT_vertex_attrib_64bit(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_vertex_attrib_64bit */
+#ifdef GL_EXT_vertex_shader
+ CONST_CAST(GLEW_EXT_vertex_shader) = _glewSearchExtension("GL_EXT_vertex_shader", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_vertex_shader) CONST_CAST(GLEW_EXT_vertex_shader) = !_glewInit_GL_EXT_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_vertex_shader */
+#ifdef GL_EXT_vertex_weighting
+ CONST_CAST(GLEW_EXT_vertex_weighting) = _glewSearchExtension("GL_EXT_vertex_weighting", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_vertex_weighting) CONST_CAST(GLEW_EXT_vertex_weighting) = !_glewInit_GL_EXT_vertex_weighting(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_vertex_weighting */
+#ifdef GL_EXT_x11_sync_object
+ CONST_CAST(GLEW_EXT_x11_sync_object) = _glewSearchExtension("GL_EXT_x11_sync_object", extStart, extEnd);
+ if (glewExperimental || GLEW_EXT_x11_sync_object) CONST_CAST(GLEW_EXT_x11_sync_object) = !_glewInit_GL_EXT_x11_sync_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_EXT_x11_sync_object */
+#ifdef GL_GREMEDY_frame_terminator
+ CONST_CAST(GLEW_GREMEDY_frame_terminator) = _glewSearchExtension("GL_GREMEDY_frame_terminator", extStart, extEnd);
+ if (glewExperimental || GLEW_GREMEDY_frame_terminator) CONST_CAST(GLEW_GREMEDY_frame_terminator) = !_glewInit_GL_GREMEDY_frame_terminator(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_GREMEDY_frame_terminator */
+#ifdef GL_GREMEDY_string_marker
+ CONST_CAST(GLEW_GREMEDY_string_marker) = _glewSearchExtension("GL_GREMEDY_string_marker", extStart, extEnd);
+ if (glewExperimental || GLEW_GREMEDY_string_marker) CONST_CAST(GLEW_GREMEDY_string_marker) = !_glewInit_GL_GREMEDY_string_marker(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_GREMEDY_string_marker */
+#ifdef GL_HP_convolution_border_modes
+ CONST_CAST(GLEW_HP_convolution_border_modes) = _glewSearchExtension("GL_HP_convolution_border_modes", extStart, extEnd);
+#endif /* GL_HP_convolution_border_modes */
+#ifdef GL_HP_image_transform
+ CONST_CAST(GLEW_HP_image_transform) = _glewSearchExtension("GL_HP_image_transform", extStart, extEnd);
+ if (glewExperimental || GLEW_HP_image_transform) CONST_CAST(GLEW_HP_image_transform) = !_glewInit_GL_HP_image_transform(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_HP_image_transform */
+#ifdef GL_HP_occlusion_test
+ CONST_CAST(GLEW_HP_occlusion_test) = _glewSearchExtension("GL_HP_occlusion_test", extStart, extEnd);
+#endif /* GL_HP_occlusion_test */
+#ifdef GL_HP_texture_lighting
+ CONST_CAST(GLEW_HP_texture_lighting) = _glewSearchExtension("GL_HP_texture_lighting", extStart, extEnd);
+#endif /* GL_HP_texture_lighting */
+#ifdef GL_IBM_cull_vertex
+ CONST_CAST(GLEW_IBM_cull_vertex) = _glewSearchExtension("GL_IBM_cull_vertex", extStart, extEnd);
+#endif /* GL_IBM_cull_vertex */
+#ifdef GL_IBM_multimode_draw_arrays
+ CONST_CAST(GLEW_IBM_multimode_draw_arrays) = _glewSearchExtension("GL_IBM_multimode_draw_arrays", extStart, extEnd);
+ if (glewExperimental || GLEW_IBM_multimode_draw_arrays) CONST_CAST(GLEW_IBM_multimode_draw_arrays) = !_glewInit_GL_IBM_multimode_draw_arrays(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_IBM_multimode_draw_arrays */
+#ifdef GL_IBM_rasterpos_clip
+ CONST_CAST(GLEW_IBM_rasterpos_clip) = _glewSearchExtension("GL_IBM_rasterpos_clip", extStart, extEnd);
+#endif /* GL_IBM_rasterpos_clip */
+#ifdef GL_IBM_static_data
+ CONST_CAST(GLEW_IBM_static_data) = _glewSearchExtension("GL_IBM_static_data", extStart, extEnd);
+#endif /* GL_IBM_static_data */
+#ifdef GL_IBM_texture_mirrored_repeat
+ CONST_CAST(GLEW_IBM_texture_mirrored_repeat) = _glewSearchExtension("GL_IBM_texture_mirrored_repeat", extStart, extEnd);
+#endif /* GL_IBM_texture_mirrored_repeat */
+#ifdef GL_IBM_vertex_array_lists
+ CONST_CAST(GLEW_IBM_vertex_array_lists) = _glewSearchExtension("GL_IBM_vertex_array_lists", extStart, extEnd);
+ if (glewExperimental || GLEW_IBM_vertex_array_lists) CONST_CAST(GLEW_IBM_vertex_array_lists) = !_glewInit_GL_IBM_vertex_array_lists(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_IBM_vertex_array_lists */
+#ifdef GL_INGR_color_clamp
+ CONST_CAST(GLEW_INGR_color_clamp) = _glewSearchExtension("GL_INGR_color_clamp", extStart, extEnd);
+#endif /* GL_INGR_color_clamp */
+#ifdef GL_INGR_interlace_read
+ CONST_CAST(GLEW_INGR_interlace_read) = _glewSearchExtension("GL_INGR_interlace_read", extStart, extEnd);
+#endif /* GL_INGR_interlace_read */
+#ifdef GL_INTEL_map_texture
+ CONST_CAST(GLEW_INTEL_map_texture) = _glewSearchExtension("GL_INTEL_map_texture", extStart, extEnd);
+ if (glewExperimental || GLEW_INTEL_map_texture) CONST_CAST(GLEW_INTEL_map_texture) = !_glewInit_GL_INTEL_map_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_INTEL_map_texture */
+#ifdef GL_INTEL_parallel_arrays
+ CONST_CAST(GLEW_INTEL_parallel_arrays) = _glewSearchExtension("GL_INTEL_parallel_arrays", extStart, extEnd);
+ if (glewExperimental || GLEW_INTEL_parallel_arrays) CONST_CAST(GLEW_INTEL_parallel_arrays) = !_glewInit_GL_INTEL_parallel_arrays(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_INTEL_parallel_arrays */
+#ifdef GL_INTEL_texture_scissor
+ CONST_CAST(GLEW_INTEL_texture_scissor) = _glewSearchExtension("GL_INTEL_texture_scissor", extStart, extEnd);
+ if (glewExperimental || GLEW_INTEL_texture_scissor) CONST_CAST(GLEW_INTEL_texture_scissor) = !_glewInit_GL_INTEL_texture_scissor(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_INTEL_texture_scissor */
+#ifdef GL_KHR_debug
+ CONST_CAST(GLEW_KHR_debug) = _glewSearchExtension("GL_KHR_debug", extStart, extEnd);
+ if (glewExperimental || GLEW_KHR_debug) CONST_CAST(GLEW_KHR_debug) = !_glewInit_GL_KHR_debug(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_KHR_debug */
+#ifdef GL_KHR_texture_compression_astc_ldr
+ CONST_CAST(GLEW_KHR_texture_compression_astc_ldr) = _glewSearchExtension("GL_KHR_texture_compression_astc_ldr", extStart, extEnd);
+#endif /* GL_KHR_texture_compression_astc_ldr */
+#ifdef GL_KTX_buffer_region
+ CONST_CAST(GLEW_KTX_buffer_region) = _glewSearchExtension("GL_KTX_buffer_region", extStart, extEnd);
+ if (glewExperimental || GLEW_KTX_buffer_region) CONST_CAST(GLEW_KTX_buffer_region) = !_glewInit_GL_KTX_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_KTX_buffer_region */
+#ifdef GL_MESAX_texture_stack
+ CONST_CAST(GLEW_MESAX_texture_stack) = _glewSearchExtension("GL_MESAX_texture_stack", extStart, extEnd);
+#endif /* GL_MESAX_texture_stack */
+#ifdef GL_MESA_pack_invert
+ CONST_CAST(GLEW_MESA_pack_invert) = _glewSearchExtension("GL_MESA_pack_invert", extStart, extEnd);
+#endif /* GL_MESA_pack_invert */
+#ifdef GL_MESA_resize_buffers
+ CONST_CAST(GLEW_MESA_resize_buffers) = _glewSearchExtension("GL_MESA_resize_buffers", extStart, extEnd);
+ if (glewExperimental || GLEW_MESA_resize_buffers) CONST_CAST(GLEW_MESA_resize_buffers) = !_glewInit_GL_MESA_resize_buffers(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_MESA_resize_buffers */
+#ifdef GL_MESA_window_pos
+ CONST_CAST(GLEW_MESA_window_pos) = _glewSearchExtension("GL_MESA_window_pos", extStart, extEnd);
+ if (glewExperimental || GLEW_MESA_window_pos) CONST_CAST(GLEW_MESA_window_pos) = !_glewInit_GL_MESA_window_pos(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_MESA_window_pos */
+#ifdef GL_MESA_ycbcr_texture
+ CONST_CAST(GLEW_MESA_ycbcr_texture) = _glewSearchExtension("GL_MESA_ycbcr_texture", extStart, extEnd);
+#endif /* GL_MESA_ycbcr_texture */
+#ifdef GL_NVX_conditional_render
+ CONST_CAST(GLEW_NVX_conditional_render) = _glewSearchExtension("GL_NVX_conditional_render", extStart, extEnd);
+ if (glewExperimental || GLEW_NVX_conditional_render) CONST_CAST(GLEW_NVX_conditional_render) = !_glewInit_GL_NVX_conditional_render(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NVX_conditional_render */
+#ifdef GL_NVX_gpu_memory_info
+ CONST_CAST(GLEW_NVX_gpu_memory_info) = _glewSearchExtension("GL_NVX_gpu_memory_info", extStart, extEnd);
+#endif /* GL_NVX_gpu_memory_info */
+#ifdef GL_NV_bindless_multi_draw_indirect
+ CONST_CAST(GLEW_NV_bindless_multi_draw_indirect) = _glewSearchExtension("GL_NV_bindless_multi_draw_indirect", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_bindless_multi_draw_indirect) CONST_CAST(GLEW_NV_bindless_multi_draw_indirect) = !_glewInit_GL_NV_bindless_multi_draw_indirect(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_bindless_multi_draw_indirect */
+#ifdef GL_NV_bindless_texture
+ CONST_CAST(GLEW_NV_bindless_texture) = _glewSearchExtension("GL_NV_bindless_texture", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_bindless_texture) CONST_CAST(GLEW_NV_bindless_texture) = !_glewInit_GL_NV_bindless_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_bindless_texture */
+#ifdef GL_NV_blend_equation_advanced
+ CONST_CAST(GLEW_NV_blend_equation_advanced) = _glewSearchExtension("GL_NV_blend_equation_advanced", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_blend_equation_advanced) CONST_CAST(GLEW_NV_blend_equation_advanced) = !_glewInit_GL_NV_blend_equation_advanced(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_blend_equation_advanced */
+#ifdef GL_NV_blend_equation_advanced_coherent
+ CONST_CAST(GLEW_NV_blend_equation_advanced_coherent) = _glewSearchExtension("GL_NV_blend_equation_advanced_coherent", extStart, extEnd);
+#endif /* GL_NV_blend_equation_advanced_coherent */
+#ifdef GL_NV_blend_square
+ CONST_CAST(GLEW_NV_blend_square) = _glewSearchExtension("GL_NV_blend_square", extStart, extEnd);
+#endif /* GL_NV_blend_square */
+#ifdef GL_NV_compute_program5
+ CONST_CAST(GLEW_NV_compute_program5) = _glewSearchExtension("GL_NV_compute_program5", extStart, extEnd);
+#endif /* GL_NV_compute_program5 */
+#ifdef GL_NV_conditional_render
+ CONST_CAST(GLEW_NV_conditional_render) = _glewSearchExtension("GL_NV_conditional_render", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_conditional_render) CONST_CAST(GLEW_NV_conditional_render) = !_glewInit_GL_NV_conditional_render(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_conditional_render */
+#ifdef GL_NV_copy_depth_to_color
+ CONST_CAST(GLEW_NV_copy_depth_to_color) = _glewSearchExtension("GL_NV_copy_depth_to_color", extStart, extEnd);
+#endif /* GL_NV_copy_depth_to_color */
+#ifdef GL_NV_copy_image
+ CONST_CAST(GLEW_NV_copy_image) = _glewSearchExtension("GL_NV_copy_image", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_copy_image) CONST_CAST(GLEW_NV_copy_image) = !_glewInit_GL_NV_copy_image(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_copy_image */
+#ifdef GL_NV_deep_texture3D
+ CONST_CAST(GLEW_NV_deep_texture3D) = _glewSearchExtension("GL_NV_deep_texture3D", extStart, extEnd);
+#endif /* GL_NV_deep_texture3D */
+#ifdef GL_NV_depth_buffer_float
+ CONST_CAST(GLEW_NV_depth_buffer_float) = _glewSearchExtension("GL_NV_depth_buffer_float", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_depth_buffer_float) CONST_CAST(GLEW_NV_depth_buffer_float) = !_glewInit_GL_NV_depth_buffer_float(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_depth_buffer_float */
+#ifdef GL_NV_depth_clamp
+ CONST_CAST(GLEW_NV_depth_clamp) = _glewSearchExtension("GL_NV_depth_clamp", extStart, extEnd);
+#endif /* GL_NV_depth_clamp */
+#ifdef GL_NV_depth_range_unclamped
+ CONST_CAST(GLEW_NV_depth_range_unclamped) = _glewSearchExtension("GL_NV_depth_range_unclamped", extStart, extEnd);
+#endif /* GL_NV_depth_range_unclamped */
+#ifdef GL_NV_draw_texture
+ CONST_CAST(GLEW_NV_draw_texture) = _glewSearchExtension("GL_NV_draw_texture", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_draw_texture) CONST_CAST(GLEW_NV_draw_texture) = !_glewInit_GL_NV_draw_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_draw_texture */
+#ifdef GL_NV_evaluators
+ CONST_CAST(GLEW_NV_evaluators) = _glewSearchExtension("GL_NV_evaluators", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_evaluators) CONST_CAST(GLEW_NV_evaluators) = !_glewInit_GL_NV_evaluators(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_evaluators */
+#ifdef GL_NV_explicit_multisample
+ CONST_CAST(GLEW_NV_explicit_multisample) = _glewSearchExtension("GL_NV_explicit_multisample", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_explicit_multisample) CONST_CAST(GLEW_NV_explicit_multisample) = !_glewInit_GL_NV_explicit_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_explicit_multisample */
+#ifdef GL_NV_fence
+ CONST_CAST(GLEW_NV_fence) = _glewSearchExtension("GL_NV_fence", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_fence) CONST_CAST(GLEW_NV_fence) = !_glewInit_GL_NV_fence(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_fence */
+#ifdef GL_NV_float_buffer
+ CONST_CAST(GLEW_NV_float_buffer) = _glewSearchExtension("GL_NV_float_buffer", extStart, extEnd);
+#endif /* GL_NV_float_buffer */
+#ifdef GL_NV_fog_distance
+ CONST_CAST(GLEW_NV_fog_distance) = _glewSearchExtension("GL_NV_fog_distance", extStart, extEnd);
+#endif /* GL_NV_fog_distance */
+#ifdef GL_NV_fragment_program
+ CONST_CAST(GLEW_NV_fragment_program) = _glewSearchExtension("GL_NV_fragment_program", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_fragment_program) CONST_CAST(GLEW_NV_fragment_program) = !_glewInit_GL_NV_fragment_program(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_fragment_program */
+#ifdef GL_NV_fragment_program2
+ CONST_CAST(GLEW_NV_fragment_program2) = _glewSearchExtension("GL_NV_fragment_program2", extStart, extEnd);
+#endif /* GL_NV_fragment_program2 */
+#ifdef GL_NV_fragment_program4
+ CONST_CAST(GLEW_NV_fragment_program4) = _glewSearchExtension("GL_NV_gpu_program4", extStart, extEnd);
+#endif /* GL_NV_fragment_program4 */
+#ifdef GL_NV_fragment_program_option
+ CONST_CAST(GLEW_NV_fragment_program_option) = _glewSearchExtension("GL_NV_fragment_program_option", extStart, extEnd);
+#endif /* GL_NV_fragment_program_option */
+#ifdef GL_NV_framebuffer_multisample_coverage
+ CONST_CAST(GLEW_NV_framebuffer_multisample_coverage) = _glewSearchExtension("GL_NV_framebuffer_multisample_coverage", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_framebuffer_multisample_coverage) CONST_CAST(GLEW_NV_framebuffer_multisample_coverage) = !_glewInit_GL_NV_framebuffer_multisample_coverage(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_framebuffer_multisample_coverage */
+#ifdef GL_NV_geometry_program4
+ CONST_CAST(GLEW_NV_geometry_program4) = _glewSearchExtension("GL_NV_gpu_program4", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_geometry_program4) CONST_CAST(GLEW_NV_geometry_program4) = !_glewInit_GL_NV_geometry_program4(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_geometry_program4 */
+#ifdef GL_NV_geometry_shader4
+ CONST_CAST(GLEW_NV_geometry_shader4) = _glewSearchExtension("GL_NV_geometry_shader4", extStart, extEnd);
+#endif /* GL_NV_geometry_shader4 */
+#ifdef GL_NV_gpu_program4
+ CONST_CAST(GLEW_NV_gpu_program4) = _glewSearchExtension("GL_NV_gpu_program4", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_gpu_program4) CONST_CAST(GLEW_NV_gpu_program4) = !_glewInit_GL_NV_gpu_program4(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_gpu_program4 */
+#ifdef GL_NV_gpu_program5
+ CONST_CAST(GLEW_NV_gpu_program5) = _glewSearchExtension("GL_NV_gpu_program5", extStart, extEnd);
+#endif /* GL_NV_gpu_program5 */
+#ifdef GL_NV_gpu_program5_mem_extended
+ CONST_CAST(GLEW_NV_gpu_program5_mem_extended) = _glewSearchExtension("GL_NV_gpu_program5_mem_extended", extStart, extEnd);
+#endif /* GL_NV_gpu_program5_mem_extended */
+#ifdef GL_NV_gpu_program_fp64
+ CONST_CAST(GLEW_NV_gpu_program_fp64) = _glewSearchExtension("GL_NV_gpu_program_fp64", extStart, extEnd);
+#endif /* GL_NV_gpu_program_fp64 */
+#ifdef GL_NV_gpu_shader5
+ CONST_CAST(GLEW_NV_gpu_shader5) = _glewSearchExtension("GL_NV_gpu_shader5", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_gpu_shader5) CONST_CAST(GLEW_NV_gpu_shader5) = !_glewInit_GL_NV_gpu_shader5(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_gpu_shader5 */
+#ifdef GL_NV_half_float
+ CONST_CAST(GLEW_NV_half_float) = _glewSearchExtension("GL_NV_half_float", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_half_float) CONST_CAST(GLEW_NV_half_float) = !_glewInit_GL_NV_half_float(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_half_float */
+#ifdef GL_NV_light_max_exponent
+ CONST_CAST(GLEW_NV_light_max_exponent) = _glewSearchExtension("GL_NV_light_max_exponent", extStart, extEnd);
+#endif /* GL_NV_light_max_exponent */
+#ifdef GL_NV_multisample_coverage
+ CONST_CAST(GLEW_NV_multisample_coverage) = _glewSearchExtension("GL_NV_multisample_coverage", extStart, extEnd);
+#endif /* GL_NV_multisample_coverage */
+#ifdef GL_NV_multisample_filter_hint
+ CONST_CAST(GLEW_NV_multisample_filter_hint) = _glewSearchExtension("GL_NV_multisample_filter_hint", extStart, extEnd);
+#endif /* GL_NV_multisample_filter_hint */
+#ifdef GL_NV_occlusion_query
+ CONST_CAST(GLEW_NV_occlusion_query) = _glewSearchExtension("GL_NV_occlusion_query", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_occlusion_query) CONST_CAST(GLEW_NV_occlusion_query) = !_glewInit_GL_NV_occlusion_query(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_occlusion_query */
+#ifdef GL_NV_packed_depth_stencil
+ CONST_CAST(GLEW_NV_packed_depth_stencil) = _glewSearchExtension("GL_NV_packed_depth_stencil", extStart, extEnd);
+#endif /* GL_NV_packed_depth_stencil */
+#ifdef GL_NV_parameter_buffer_object
+ CONST_CAST(GLEW_NV_parameter_buffer_object) = _glewSearchExtension("GL_NV_parameter_buffer_object", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_parameter_buffer_object) CONST_CAST(GLEW_NV_parameter_buffer_object) = !_glewInit_GL_NV_parameter_buffer_object(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_parameter_buffer_object */
+#ifdef GL_NV_parameter_buffer_object2
+ CONST_CAST(GLEW_NV_parameter_buffer_object2) = _glewSearchExtension("GL_NV_parameter_buffer_object2", extStart, extEnd);
+#endif /* GL_NV_parameter_buffer_object2 */
+#ifdef GL_NV_path_rendering
+ CONST_CAST(GLEW_NV_path_rendering) = _glewSearchExtension("GL_NV_path_rendering", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_path_rendering) CONST_CAST(GLEW_NV_path_rendering) = !_glewInit_GL_NV_path_rendering(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_path_rendering */
+#ifdef GL_NV_pixel_data_range
+ CONST_CAST(GLEW_NV_pixel_data_range) = _glewSearchExtension("GL_NV_pixel_data_range", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_pixel_data_range) CONST_CAST(GLEW_NV_pixel_data_range) = !_glewInit_GL_NV_pixel_data_range(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_pixel_data_range */
+#ifdef GL_NV_point_sprite
+ CONST_CAST(GLEW_NV_point_sprite) = _glewSearchExtension("GL_NV_point_sprite", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_point_sprite) CONST_CAST(GLEW_NV_point_sprite) = !_glewInit_GL_NV_point_sprite(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_point_sprite */
+#ifdef GL_NV_present_video
+ CONST_CAST(GLEW_NV_present_video) = _glewSearchExtension("GL_NV_present_video", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_present_video) CONST_CAST(GLEW_NV_present_video) = !_glewInit_GL_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_present_video */
+#ifdef GL_NV_primitive_restart
+ CONST_CAST(GLEW_NV_primitive_restart) = _glewSearchExtension("GL_NV_primitive_restart", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_primitive_restart) CONST_CAST(GLEW_NV_primitive_restart) = !_glewInit_GL_NV_primitive_restart(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_primitive_restart */
+#ifdef GL_NV_register_combiners
+ CONST_CAST(GLEW_NV_register_combiners) = _glewSearchExtension("GL_NV_register_combiners", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_register_combiners) CONST_CAST(GLEW_NV_register_combiners) = !_glewInit_GL_NV_register_combiners(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_register_combiners */
+#ifdef GL_NV_register_combiners2
+ CONST_CAST(GLEW_NV_register_combiners2) = _glewSearchExtension("GL_NV_register_combiners2", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_register_combiners2) CONST_CAST(GLEW_NV_register_combiners2) = !_glewInit_GL_NV_register_combiners2(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_register_combiners2 */
+#ifdef GL_NV_shader_atomic_counters
+ CONST_CAST(GLEW_NV_shader_atomic_counters) = _glewSearchExtension("GL_NV_shader_atomic_counters", extStart, extEnd);
+#endif /* GL_NV_shader_atomic_counters */
+#ifdef GL_NV_shader_atomic_float
+ CONST_CAST(GLEW_NV_shader_atomic_float) = _glewSearchExtension("GL_NV_shader_atomic_float", extStart, extEnd);
+#endif /* GL_NV_shader_atomic_float */
+#ifdef GL_NV_shader_buffer_load
+ CONST_CAST(GLEW_NV_shader_buffer_load) = _glewSearchExtension("GL_NV_shader_buffer_load", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_shader_buffer_load) CONST_CAST(GLEW_NV_shader_buffer_load) = !_glewInit_GL_NV_shader_buffer_load(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_shader_buffer_load */
+#ifdef GL_NV_shader_storage_buffer_object
+ CONST_CAST(GLEW_NV_shader_storage_buffer_object) = _glewSearchExtension("GL_NV_shader_storage_buffer_object", extStart, extEnd);
+#endif /* GL_NV_shader_storage_buffer_object */
+#ifdef GL_NV_tessellation_program5
+ CONST_CAST(GLEW_NV_tessellation_program5) = _glewSearchExtension("GL_NV_gpu_program5", extStart, extEnd);
+#endif /* GL_NV_tessellation_program5 */
+#ifdef GL_NV_texgen_emboss
+ CONST_CAST(GLEW_NV_texgen_emboss) = _glewSearchExtension("GL_NV_texgen_emboss", extStart, extEnd);
+#endif /* GL_NV_texgen_emboss */
+#ifdef GL_NV_texgen_reflection
+ CONST_CAST(GLEW_NV_texgen_reflection) = _glewSearchExtension("GL_NV_texgen_reflection", extStart, extEnd);
+#endif /* GL_NV_texgen_reflection */
+#ifdef GL_NV_texture_barrier
+ CONST_CAST(GLEW_NV_texture_barrier) = _glewSearchExtension("GL_NV_texture_barrier", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_texture_barrier) CONST_CAST(GLEW_NV_texture_barrier) = !_glewInit_GL_NV_texture_barrier(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_texture_barrier */
+#ifdef GL_NV_texture_compression_vtc
+ CONST_CAST(GLEW_NV_texture_compression_vtc) = _glewSearchExtension("GL_NV_texture_compression_vtc", extStart, extEnd);
+#endif /* GL_NV_texture_compression_vtc */
+#ifdef GL_NV_texture_env_combine4
+ CONST_CAST(GLEW_NV_texture_env_combine4) = _glewSearchExtension("GL_NV_texture_env_combine4", extStart, extEnd);
+#endif /* GL_NV_texture_env_combine4 */
+#ifdef GL_NV_texture_expand_normal
+ CONST_CAST(GLEW_NV_texture_expand_normal) = _glewSearchExtension("GL_NV_texture_expand_normal", extStart, extEnd);
+#endif /* GL_NV_texture_expand_normal */
+#ifdef GL_NV_texture_multisample
+ CONST_CAST(GLEW_NV_texture_multisample) = _glewSearchExtension("GL_NV_texture_multisample", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_texture_multisample) CONST_CAST(GLEW_NV_texture_multisample) = !_glewInit_GL_NV_texture_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_texture_multisample */
+#ifdef GL_NV_texture_rectangle
+ CONST_CAST(GLEW_NV_texture_rectangle) = _glewSearchExtension("GL_NV_texture_rectangle", extStart, extEnd);
+#endif /* GL_NV_texture_rectangle */
+#ifdef GL_NV_texture_shader
+ CONST_CAST(GLEW_NV_texture_shader) = _glewSearchExtension("GL_NV_texture_shader", extStart, extEnd);
+#endif /* GL_NV_texture_shader */
+#ifdef GL_NV_texture_shader2
+ CONST_CAST(GLEW_NV_texture_shader2) = _glewSearchExtension("GL_NV_texture_shader2", extStart, extEnd);
+#endif /* GL_NV_texture_shader2 */
+#ifdef GL_NV_texture_shader3
+ CONST_CAST(GLEW_NV_texture_shader3) = _glewSearchExtension("GL_NV_texture_shader3", extStart, extEnd);
+#endif /* GL_NV_texture_shader3 */
+#ifdef GL_NV_transform_feedback
+ CONST_CAST(GLEW_NV_transform_feedback) = _glewSearchExtension("GL_NV_transform_feedback", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_transform_feedback) CONST_CAST(GLEW_NV_transform_feedback) = !_glewInit_GL_NV_transform_feedback(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_transform_feedback */
+#ifdef GL_NV_transform_feedback2
+ CONST_CAST(GLEW_NV_transform_feedback2) = _glewSearchExtension("GL_NV_transform_feedback2", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_transform_feedback2) CONST_CAST(GLEW_NV_transform_feedback2) = !_glewInit_GL_NV_transform_feedback2(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_transform_feedback2 */
+#ifdef GL_NV_vdpau_interop
+ CONST_CAST(GLEW_NV_vdpau_interop) = _glewSearchExtension("GL_NV_vdpau_interop", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_vdpau_interop) CONST_CAST(GLEW_NV_vdpau_interop) = !_glewInit_GL_NV_vdpau_interop(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_vdpau_interop */
+#ifdef GL_NV_vertex_array_range
+ CONST_CAST(GLEW_NV_vertex_array_range) = _glewSearchExtension("GL_NV_vertex_array_range", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_vertex_array_range) CONST_CAST(GLEW_NV_vertex_array_range) = !_glewInit_GL_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_vertex_array_range */
+#ifdef GL_NV_vertex_array_range2
+ CONST_CAST(GLEW_NV_vertex_array_range2) = _glewSearchExtension("GL_NV_vertex_array_range2", extStart, extEnd);
+#endif /* GL_NV_vertex_array_range2 */
+#ifdef GL_NV_vertex_attrib_integer_64bit
+ CONST_CAST(GLEW_NV_vertex_attrib_integer_64bit) = _glewSearchExtension("GL_NV_vertex_attrib_integer_64bit", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_vertex_attrib_integer_64bit) CONST_CAST(GLEW_NV_vertex_attrib_integer_64bit) = !_glewInit_GL_NV_vertex_attrib_integer_64bit(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_vertex_attrib_integer_64bit */
+#ifdef GL_NV_vertex_buffer_unified_memory
+ CONST_CAST(GLEW_NV_vertex_buffer_unified_memory) = _glewSearchExtension("GL_NV_vertex_buffer_unified_memory", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_vertex_buffer_unified_memory) CONST_CAST(GLEW_NV_vertex_buffer_unified_memory) = !_glewInit_GL_NV_vertex_buffer_unified_memory(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_vertex_buffer_unified_memory */
+#ifdef GL_NV_vertex_program
+ CONST_CAST(GLEW_NV_vertex_program) = _glewSearchExtension("GL_NV_vertex_program", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_vertex_program) CONST_CAST(GLEW_NV_vertex_program) = !_glewInit_GL_NV_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_vertex_program */
+#ifdef GL_NV_vertex_program1_1
+ CONST_CAST(GLEW_NV_vertex_program1_1) = _glewSearchExtension("GL_NV_vertex_program1_1", extStart, extEnd);
+#endif /* GL_NV_vertex_program1_1 */
+#ifdef GL_NV_vertex_program2
+ CONST_CAST(GLEW_NV_vertex_program2) = _glewSearchExtension("GL_NV_vertex_program2", extStart, extEnd);
+#endif /* GL_NV_vertex_program2 */
+#ifdef GL_NV_vertex_program2_option
+ CONST_CAST(GLEW_NV_vertex_program2_option) = _glewSearchExtension("GL_NV_vertex_program2_option", extStart, extEnd);
+#endif /* GL_NV_vertex_program2_option */
+#ifdef GL_NV_vertex_program3
+ CONST_CAST(GLEW_NV_vertex_program3) = _glewSearchExtension("GL_NV_vertex_program3", extStart, extEnd);
+#endif /* GL_NV_vertex_program3 */
+#ifdef GL_NV_vertex_program4
+ CONST_CAST(GLEW_NV_vertex_program4) = _glewSearchExtension("GL_NV_gpu_program4", extStart, extEnd);
+#endif /* GL_NV_vertex_program4 */
+#ifdef GL_NV_video_capture
+ CONST_CAST(GLEW_NV_video_capture) = _glewSearchExtension("GL_NV_video_capture", extStart, extEnd);
+ if (glewExperimental || GLEW_NV_video_capture) CONST_CAST(GLEW_NV_video_capture) = !_glewInit_GL_NV_video_capture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_NV_video_capture */
+#ifdef GL_OES_byte_coordinates
+ CONST_CAST(GLEW_OES_byte_coordinates) = _glewSearchExtension("GL_OES_byte_coordinates", extStart, extEnd);
+#endif /* GL_OES_byte_coordinates */
+#ifdef GL_OES_compressed_paletted_texture
+ CONST_CAST(GLEW_OES_compressed_paletted_texture) = _glewSearchExtension("GL_OES_compressed_paletted_texture", extStart, extEnd);
+#endif /* GL_OES_compressed_paletted_texture */
+#ifdef GL_OES_read_format
+ CONST_CAST(GLEW_OES_read_format) = _glewSearchExtension("GL_OES_read_format", extStart, extEnd);
+#endif /* GL_OES_read_format */
+#ifdef GL_OES_single_precision
+ CONST_CAST(GLEW_OES_single_precision) = _glewSearchExtension("GL_OES_single_precision", extStart, extEnd);
+ if (glewExperimental || GLEW_OES_single_precision) CONST_CAST(GLEW_OES_single_precision) = !_glewInit_GL_OES_single_precision(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_OES_single_precision */
+#ifdef GL_OML_interlace
+ CONST_CAST(GLEW_OML_interlace) = _glewSearchExtension("GL_OML_interlace", extStart, extEnd);
+#endif /* GL_OML_interlace */
+#ifdef GL_OML_resample
+ CONST_CAST(GLEW_OML_resample) = _glewSearchExtension("GL_OML_resample", extStart, extEnd);
+#endif /* GL_OML_resample */
+#ifdef GL_OML_subsample
+ CONST_CAST(GLEW_OML_subsample) = _glewSearchExtension("GL_OML_subsample", extStart, extEnd);
+#endif /* GL_OML_subsample */
+#ifdef GL_PGI_misc_hints
+ CONST_CAST(GLEW_PGI_misc_hints) = _glewSearchExtension("GL_PGI_misc_hints", extStart, extEnd);
+#endif /* GL_PGI_misc_hints */
+#ifdef GL_PGI_vertex_hints
+ CONST_CAST(GLEW_PGI_vertex_hints) = _glewSearchExtension("GL_PGI_vertex_hints", extStart, extEnd);
+#endif /* GL_PGI_vertex_hints */
+#ifdef GL_REGAL_ES1_0_compatibility
+ CONST_CAST(GLEW_REGAL_ES1_0_compatibility) = _glewSearchExtension("GL_REGAL_ES1_0_compatibility", extStart, extEnd);
+ if (glewExperimental || GLEW_REGAL_ES1_0_compatibility) CONST_CAST(GLEW_REGAL_ES1_0_compatibility) = !_glewInit_GL_REGAL_ES1_0_compatibility(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_REGAL_ES1_0_compatibility */
+#ifdef GL_REGAL_ES1_1_compatibility
+ CONST_CAST(GLEW_REGAL_ES1_1_compatibility) = _glewSearchExtension("GL_REGAL_ES1_1_compatibility", extStart, extEnd);
+ if (glewExperimental || GLEW_REGAL_ES1_1_compatibility) CONST_CAST(GLEW_REGAL_ES1_1_compatibility) = !_glewInit_GL_REGAL_ES1_1_compatibility(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_REGAL_ES1_1_compatibility */
+#ifdef GL_REGAL_enable
+ CONST_CAST(GLEW_REGAL_enable) = _glewSearchExtension("GL_REGAL_enable", extStart, extEnd);
+#endif /* GL_REGAL_enable */
+#ifdef GL_REGAL_error_string
+ CONST_CAST(GLEW_REGAL_error_string) = _glewSearchExtension("GL_REGAL_error_string", extStart, extEnd);
+ if (glewExperimental || GLEW_REGAL_error_string) CONST_CAST(GLEW_REGAL_error_string) = !_glewInit_GL_REGAL_error_string(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_REGAL_error_string */
+#ifdef GL_REGAL_extension_query
+ CONST_CAST(GLEW_REGAL_extension_query) = _glewSearchExtension("GL_REGAL_extension_query", extStart, extEnd);
+ if (glewExperimental || GLEW_REGAL_extension_query) CONST_CAST(GLEW_REGAL_extension_query) = !_glewInit_GL_REGAL_extension_query(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_REGAL_extension_query */
+#ifdef GL_REGAL_log
+ CONST_CAST(GLEW_REGAL_log) = _glewSearchExtension("GL_REGAL_log", extStart, extEnd);
+ if (glewExperimental || GLEW_REGAL_log) CONST_CAST(GLEW_REGAL_log) = !_glewInit_GL_REGAL_log(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_REGAL_log */
+#ifdef GL_REND_screen_coordinates
+ CONST_CAST(GLEW_REND_screen_coordinates) = _glewSearchExtension("GL_REND_screen_coordinates", extStart, extEnd);
+#endif /* GL_REND_screen_coordinates */
+#ifdef GL_S3_s3tc
+ CONST_CAST(GLEW_S3_s3tc) = _glewSearchExtension("GL_S3_s3tc", extStart, extEnd);
+#endif /* GL_S3_s3tc */
+#ifdef GL_SGIS_color_range
+ CONST_CAST(GLEW_SGIS_color_range) = _glewSearchExtension("GL_SGIS_color_range", extStart, extEnd);
+#endif /* GL_SGIS_color_range */
+#ifdef GL_SGIS_detail_texture
+ CONST_CAST(GLEW_SGIS_detail_texture) = _glewSearchExtension("GL_SGIS_detail_texture", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIS_detail_texture) CONST_CAST(GLEW_SGIS_detail_texture) = !_glewInit_GL_SGIS_detail_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIS_detail_texture */
+#ifdef GL_SGIS_fog_function
+ CONST_CAST(GLEW_SGIS_fog_function) = _glewSearchExtension("GL_SGIS_fog_function", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIS_fog_function) CONST_CAST(GLEW_SGIS_fog_function) = !_glewInit_GL_SGIS_fog_function(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIS_fog_function */
+#ifdef GL_SGIS_generate_mipmap
+ CONST_CAST(GLEW_SGIS_generate_mipmap) = _glewSearchExtension("GL_SGIS_generate_mipmap", extStart, extEnd);
+#endif /* GL_SGIS_generate_mipmap */
+#ifdef GL_SGIS_multisample
+ CONST_CAST(GLEW_SGIS_multisample) = _glewSearchExtension("GL_SGIS_multisample", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIS_multisample) CONST_CAST(GLEW_SGIS_multisample) = !_glewInit_GL_SGIS_multisample(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIS_multisample */
+#ifdef GL_SGIS_pixel_texture
+ CONST_CAST(GLEW_SGIS_pixel_texture) = _glewSearchExtension("GL_SGIS_pixel_texture", extStart, extEnd);
+#endif /* GL_SGIS_pixel_texture */
+#ifdef GL_SGIS_point_line_texgen
+ CONST_CAST(GLEW_SGIS_point_line_texgen) = _glewSearchExtension("GL_SGIS_point_line_texgen", extStart, extEnd);
+#endif /* GL_SGIS_point_line_texgen */
+#ifdef GL_SGIS_sharpen_texture
+ CONST_CAST(GLEW_SGIS_sharpen_texture) = _glewSearchExtension("GL_SGIS_sharpen_texture", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIS_sharpen_texture) CONST_CAST(GLEW_SGIS_sharpen_texture) = !_glewInit_GL_SGIS_sharpen_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIS_sharpen_texture */
+#ifdef GL_SGIS_texture4D
+ CONST_CAST(GLEW_SGIS_texture4D) = _glewSearchExtension("GL_SGIS_texture4D", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIS_texture4D) CONST_CAST(GLEW_SGIS_texture4D) = !_glewInit_GL_SGIS_texture4D(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIS_texture4D */
+#ifdef GL_SGIS_texture_border_clamp
+ CONST_CAST(GLEW_SGIS_texture_border_clamp) = _glewSearchExtension("GL_SGIS_texture_border_clamp", extStart, extEnd);
+#endif /* GL_SGIS_texture_border_clamp */
+#ifdef GL_SGIS_texture_edge_clamp
+ CONST_CAST(GLEW_SGIS_texture_edge_clamp) = _glewSearchExtension("GL_SGIS_texture_edge_clamp", extStart, extEnd);
+#endif /* GL_SGIS_texture_edge_clamp */
+#ifdef GL_SGIS_texture_filter4
+ CONST_CAST(GLEW_SGIS_texture_filter4) = _glewSearchExtension("GL_SGIS_texture_filter4", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIS_texture_filter4) CONST_CAST(GLEW_SGIS_texture_filter4) = !_glewInit_GL_SGIS_texture_filter4(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIS_texture_filter4 */
+#ifdef GL_SGIS_texture_lod
+ CONST_CAST(GLEW_SGIS_texture_lod) = _glewSearchExtension("GL_SGIS_texture_lod", extStart, extEnd);
+#endif /* GL_SGIS_texture_lod */
+#ifdef GL_SGIS_texture_select
+ CONST_CAST(GLEW_SGIS_texture_select) = _glewSearchExtension("GL_SGIS_texture_select", extStart, extEnd);
+#endif /* GL_SGIS_texture_select */
+#ifdef GL_SGIX_async
+ CONST_CAST(GLEW_SGIX_async) = _glewSearchExtension("GL_SGIX_async", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIX_async) CONST_CAST(GLEW_SGIX_async) = !_glewInit_GL_SGIX_async(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIX_async */
+#ifdef GL_SGIX_async_histogram
+ CONST_CAST(GLEW_SGIX_async_histogram) = _glewSearchExtension("GL_SGIX_async_histogram", extStart, extEnd);
+#endif /* GL_SGIX_async_histogram */
+#ifdef GL_SGIX_async_pixel
+ CONST_CAST(GLEW_SGIX_async_pixel) = _glewSearchExtension("GL_SGIX_async_pixel", extStart, extEnd);
+#endif /* GL_SGIX_async_pixel */
+#ifdef GL_SGIX_blend_alpha_minmax
+ CONST_CAST(GLEW_SGIX_blend_alpha_minmax) = _glewSearchExtension("GL_SGIX_blend_alpha_minmax", extStart, extEnd);
+#endif /* GL_SGIX_blend_alpha_minmax */
+#ifdef GL_SGIX_clipmap
+ CONST_CAST(GLEW_SGIX_clipmap) = _glewSearchExtension("GL_SGIX_clipmap", extStart, extEnd);
+#endif /* GL_SGIX_clipmap */
+#ifdef GL_SGIX_convolution_accuracy
+ CONST_CAST(GLEW_SGIX_convolution_accuracy) = _glewSearchExtension("GL_SGIX_convolution_accuracy", extStart, extEnd);
+#endif /* GL_SGIX_convolution_accuracy */
+#ifdef GL_SGIX_depth_texture
+ CONST_CAST(GLEW_SGIX_depth_texture) = _glewSearchExtension("GL_SGIX_depth_texture", extStart, extEnd);
+#endif /* GL_SGIX_depth_texture */
+#ifdef GL_SGIX_flush_raster
+ CONST_CAST(GLEW_SGIX_flush_raster) = _glewSearchExtension("GL_SGIX_flush_raster", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIX_flush_raster) CONST_CAST(GLEW_SGIX_flush_raster) = !_glewInit_GL_SGIX_flush_raster(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIX_flush_raster */
+#ifdef GL_SGIX_fog_offset
+ CONST_CAST(GLEW_SGIX_fog_offset) = _glewSearchExtension("GL_SGIX_fog_offset", extStart, extEnd);
+#endif /* GL_SGIX_fog_offset */
+#ifdef GL_SGIX_fog_texture
+ CONST_CAST(GLEW_SGIX_fog_texture) = _glewSearchExtension("GL_SGIX_fog_texture", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIX_fog_texture) CONST_CAST(GLEW_SGIX_fog_texture) = !_glewInit_GL_SGIX_fog_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIX_fog_texture */
+#ifdef GL_SGIX_fragment_specular_lighting
+ CONST_CAST(GLEW_SGIX_fragment_specular_lighting) = _glewSearchExtension("GL_SGIX_fragment_specular_lighting", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIX_fragment_specular_lighting) CONST_CAST(GLEW_SGIX_fragment_specular_lighting) = !_glewInit_GL_SGIX_fragment_specular_lighting(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIX_fragment_specular_lighting */
+#ifdef GL_SGIX_framezoom
+ CONST_CAST(GLEW_SGIX_framezoom) = _glewSearchExtension("GL_SGIX_framezoom", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIX_framezoom) CONST_CAST(GLEW_SGIX_framezoom) = !_glewInit_GL_SGIX_framezoom(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIX_framezoom */
+#ifdef GL_SGIX_interlace
+ CONST_CAST(GLEW_SGIX_interlace) = _glewSearchExtension("GL_SGIX_interlace", extStart, extEnd);
+#endif /* GL_SGIX_interlace */
+#ifdef GL_SGIX_ir_instrument1
+ CONST_CAST(GLEW_SGIX_ir_instrument1) = _glewSearchExtension("GL_SGIX_ir_instrument1", extStart, extEnd);
+#endif /* GL_SGIX_ir_instrument1 */
+#ifdef GL_SGIX_list_priority
+ CONST_CAST(GLEW_SGIX_list_priority) = _glewSearchExtension("GL_SGIX_list_priority", extStart, extEnd);
+#endif /* GL_SGIX_list_priority */
+#ifdef GL_SGIX_pixel_texture
+ CONST_CAST(GLEW_SGIX_pixel_texture) = _glewSearchExtension("GL_SGIX_pixel_texture", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIX_pixel_texture) CONST_CAST(GLEW_SGIX_pixel_texture) = !_glewInit_GL_SGIX_pixel_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIX_pixel_texture */
+#ifdef GL_SGIX_pixel_texture_bits
+ CONST_CAST(GLEW_SGIX_pixel_texture_bits) = _glewSearchExtension("GL_SGIX_pixel_texture_bits", extStart, extEnd);
+#endif /* GL_SGIX_pixel_texture_bits */
+#ifdef GL_SGIX_reference_plane
+ CONST_CAST(GLEW_SGIX_reference_plane) = _glewSearchExtension("GL_SGIX_reference_plane", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIX_reference_plane) CONST_CAST(GLEW_SGIX_reference_plane) = !_glewInit_GL_SGIX_reference_plane(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIX_reference_plane */
+#ifdef GL_SGIX_resample
+ CONST_CAST(GLEW_SGIX_resample) = _glewSearchExtension("GL_SGIX_resample", extStart, extEnd);
+#endif /* GL_SGIX_resample */
+#ifdef GL_SGIX_shadow
+ CONST_CAST(GLEW_SGIX_shadow) = _glewSearchExtension("GL_SGIX_shadow", extStart, extEnd);
+#endif /* GL_SGIX_shadow */
+#ifdef GL_SGIX_shadow_ambient
+ CONST_CAST(GLEW_SGIX_shadow_ambient) = _glewSearchExtension("GL_SGIX_shadow_ambient", extStart, extEnd);
+#endif /* GL_SGIX_shadow_ambient */
+#ifdef GL_SGIX_sprite
+ CONST_CAST(GLEW_SGIX_sprite) = _glewSearchExtension("GL_SGIX_sprite", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIX_sprite) CONST_CAST(GLEW_SGIX_sprite) = !_glewInit_GL_SGIX_sprite(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIX_sprite */
+#ifdef GL_SGIX_tag_sample_buffer
+ CONST_CAST(GLEW_SGIX_tag_sample_buffer) = _glewSearchExtension("GL_SGIX_tag_sample_buffer", extStart, extEnd);
+ if (glewExperimental || GLEW_SGIX_tag_sample_buffer) CONST_CAST(GLEW_SGIX_tag_sample_buffer) = !_glewInit_GL_SGIX_tag_sample_buffer(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGIX_tag_sample_buffer */
+#ifdef GL_SGIX_texture_add_env
+ CONST_CAST(GLEW_SGIX_texture_add_env) = _glewSearchExtension("GL_SGIX_texture_add_env", extStart, extEnd);
+#endif /* GL_SGIX_texture_add_env */
+#ifdef GL_SGIX_texture_coordinate_clamp
+ CONST_CAST(GLEW_SGIX_texture_coordinate_clamp) = _glewSearchExtension("GL_SGIX_texture_coordinate_clamp", extStart, extEnd);
+#endif /* GL_SGIX_texture_coordinate_clamp */
+#ifdef GL_SGIX_texture_lod_bias
+ CONST_CAST(GLEW_SGIX_texture_lod_bias) = _glewSearchExtension("GL_SGIX_texture_lod_bias", extStart, extEnd);
+#endif /* GL_SGIX_texture_lod_bias */
+#ifdef GL_SGIX_texture_multi_buffer
+ CONST_CAST(GLEW_SGIX_texture_multi_buffer) = _glewSearchExtension("GL_SGIX_texture_multi_buffer", extStart, extEnd);
+#endif /* GL_SGIX_texture_multi_buffer */
+#ifdef GL_SGIX_texture_range
+ CONST_CAST(GLEW_SGIX_texture_range) = _glewSearchExtension("GL_SGIX_texture_range", extStart, extEnd);
+#endif /* GL_SGIX_texture_range */
+#ifdef GL_SGIX_texture_scale_bias
+ CONST_CAST(GLEW_SGIX_texture_scale_bias) = _glewSearchExtension("GL_SGIX_texture_scale_bias", extStart, extEnd);
+#endif /* GL_SGIX_texture_scale_bias */
+#ifdef GL_SGIX_vertex_preclip
+ CONST_CAST(GLEW_SGIX_vertex_preclip) = _glewSearchExtension("GL_SGIX_vertex_preclip", extStart, extEnd);
+#endif /* GL_SGIX_vertex_preclip */
+#ifdef GL_SGIX_vertex_preclip_hint
+ CONST_CAST(GLEW_SGIX_vertex_preclip_hint) = _glewSearchExtension("GL_SGIX_vertex_preclip_hint", extStart, extEnd);
+#endif /* GL_SGIX_vertex_preclip_hint */
+#ifdef GL_SGIX_ycrcb
+ CONST_CAST(GLEW_SGIX_ycrcb) = _glewSearchExtension("GL_SGIX_ycrcb", extStart, extEnd);
+#endif /* GL_SGIX_ycrcb */
+#ifdef GL_SGI_color_matrix
+ CONST_CAST(GLEW_SGI_color_matrix) = _glewSearchExtension("GL_SGI_color_matrix", extStart, extEnd);
+#endif /* GL_SGI_color_matrix */
+#ifdef GL_SGI_color_table
+ CONST_CAST(GLEW_SGI_color_table) = _glewSearchExtension("GL_SGI_color_table", extStart, extEnd);
+ if (glewExperimental || GLEW_SGI_color_table) CONST_CAST(GLEW_SGI_color_table) = !_glewInit_GL_SGI_color_table(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SGI_color_table */
+#ifdef GL_SGI_texture_color_table
+ CONST_CAST(GLEW_SGI_texture_color_table) = _glewSearchExtension("GL_SGI_texture_color_table", extStart, extEnd);
+#endif /* GL_SGI_texture_color_table */
+#ifdef GL_SUNX_constant_data
+ CONST_CAST(GLEW_SUNX_constant_data) = _glewSearchExtension("GL_SUNX_constant_data", extStart, extEnd);
+ if (glewExperimental || GLEW_SUNX_constant_data) CONST_CAST(GLEW_SUNX_constant_data) = !_glewInit_GL_SUNX_constant_data(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SUNX_constant_data */
+#ifdef GL_SUN_convolution_border_modes
+ CONST_CAST(GLEW_SUN_convolution_border_modes) = _glewSearchExtension("GL_SUN_convolution_border_modes", extStart, extEnd);
+#endif /* GL_SUN_convolution_border_modes */
+#ifdef GL_SUN_global_alpha
+ CONST_CAST(GLEW_SUN_global_alpha) = _glewSearchExtension("GL_SUN_global_alpha", extStart, extEnd);
+ if (glewExperimental || GLEW_SUN_global_alpha) CONST_CAST(GLEW_SUN_global_alpha) = !_glewInit_GL_SUN_global_alpha(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SUN_global_alpha */
+#ifdef GL_SUN_mesh_array
+ CONST_CAST(GLEW_SUN_mesh_array) = _glewSearchExtension("GL_SUN_mesh_array", extStart, extEnd);
+#endif /* GL_SUN_mesh_array */
+#ifdef GL_SUN_read_video_pixels
+ CONST_CAST(GLEW_SUN_read_video_pixels) = _glewSearchExtension("GL_SUN_read_video_pixels", extStart, extEnd);
+ if (glewExperimental || GLEW_SUN_read_video_pixels) CONST_CAST(GLEW_SUN_read_video_pixels) = !_glewInit_GL_SUN_read_video_pixels(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SUN_read_video_pixels */
+#ifdef GL_SUN_slice_accum
+ CONST_CAST(GLEW_SUN_slice_accum) = _glewSearchExtension("GL_SUN_slice_accum", extStart, extEnd);
+#endif /* GL_SUN_slice_accum */
+#ifdef GL_SUN_triangle_list
+ CONST_CAST(GLEW_SUN_triangle_list) = _glewSearchExtension("GL_SUN_triangle_list", extStart, extEnd);
+ if (glewExperimental || GLEW_SUN_triangle_list) CONST_CAST(GLEW_SUN_triangle_list) = !_glewInit_GL_SUN_triangle_list(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SUN_triangle_list */
+#ifdef GL_SUN_vertex
+ CONST_CAST(GLEW_SUN_vertex) = _glewSearchExtension("GL_SUN_vertex", extStart, extEnd);
+ if (glewExperimental || GLEW_SUN_vertex) CONST_CAST(GLEW_SUN_vertex) = !_glewInit_GL_SUN_vertex(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_SUN_vertex */
+#ifdef GL_WIN_phong_shading
+ CONST_CAST(GLEW_WIN_phong_shading) = _glewSearchExtension("GL_WIN_phong_shading", extStart, extEnd);
+#endif /* GL_WIN_phong_shading */
+#ifdef GL_WIN_specular_fog
+ CONST_CAST(GLEW_WIN_specular_fog) = _glewSearchExtension("GL_WIN_specular_fog", extStart, extEnd);
+#endif /* GL_WIN_specular_fog */
+#ifdef GL_WIN_swap_hint
+ CONST_CAST(GLEW_WIN_swap_hint) = _glewSearchExtension("GL_WIN_swap_hint", extStart, extEnd);
+ if (glewExperimental || GLEW_WIN_swap_hint) CONST_CAST(GLEW_WIN_swap_hint) = !_glewInit_GL_WIN_swap_hint(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GL_WIN_swap_hint */
+
+ return GLEW_OK;
+}
+
+
+#if defined(_WIN32)
+
+#if !defined(GLEW_MX)
+
+PFNWGLSETSTEREOEMITTERSTATE3DLPROC __wglewSetStereoEmitterState3DL = NULL;
+
+PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC __wglewBlitContextFramebufferAMD = NULL;
+PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC __wglewCreateAssociatedContextAMD = NULL;
+PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __wglewCreateAssociatedContextAttribsAMD = NULL;
+PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC __wglewDeleteAssociatedContextAMD = NULL;
+PFNWGLGETCONTEXTGPUIDAMDPROC __wglewGetContextGPUIDAMD = NULL;
+PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC __wglewGetCurrentAssociatedContextAMD = NULL;
+PFNWGLGETGPUIDSAMDPROC __wglewGetGPUIDsAMD = NULL;
+PFNWGLGETGPUINFOAMDPROC __wglewGetGPUInfoAMD = NULL;
+PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __wglewMakeAssociatedContextCurrentAMD = NULL;
+
+PFNWGLCREATEBUFFERREGIONARBPROC __wglewCreateBufferRegionARB = NULL;
+PFNWGLDELETEBUFFERREGIONARBPROC __wglewDeleteBufferRegionARB = NULL;
+PFNWGLRESTOREBUFFERREGIONARBPROC __wglewRestoreBufferRegionARB = NULL;
+PFNWGLSAVEBUFFERREGIONARBPROC __wglewSaveBufferRegionARB = NULL;
+
+PFNWGLCREATECONTEXTATTRIBSARBPROC __wglewCreateContextAttribsARB = NULL;
+
+PFNWGLGETEXTENSIONSSTRINGARBPROC __wglewGetExtensionsStringARB = NULL;
+
+PFNWGLGETCURRENTREADDCARBPROC __wglewGetCurrentReadDCARB = NULL;
+PFNWGLMAKECONTEXTCURRENTARBPROC __wglewMakeContextCurrentARB = NULL;
+
+PFNWGLCREATEPBUFFERARBPROC __wglewCreatePbufferARB = NULL;
+PFNWGLDESTROYPBUFFERARBPROC __wglewDestroyPbufferARB = NULL;
+PFNWGLGETPBUFFERDCARBPROC __wglewGetPbufferDCARB = NULL;
+PFNWGLQUERYPBUFFERARBPROC __wglewQueryPbufferARB = NULL;
+PFNWGLRELEASEPBUFFERDCARBPROC __wglewReleasePbufferDCARB = NULL;
+
+PFNWGLCHOOSEPIXELFORMATARBPROC __wglewChoosePixelFormatARB = NULL;
+PFNWGLGETPIXELFORMATATTRIBFVARBPROC __wglewGetPixelFormatAttribfvARB = NULL;
+PFNWGLGETPIXELFORMATATTRIBIVARBPROC __wglewGetPixelFormatAttribivARB = NULL;
+
+PFNWGLBINDTEXIMAGEARBPROC __wglewBindTexImageARB = NULL;
+PFNWGLRELEASETEXIMAGEARBPROC __wglewReleaseTexImageARB = NULL;
+PFNWGLSETPBUFFERATTRIBARBPROC __wglewSetPbufferAttribARB = NULL;
+
+PFNWGLBINDDISPLAYCOLORTABLEEXTPROC __wglewBindDisplayColorTableEXT = NULL;
+PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC __wglewCreateDisplayColorTableEXT = NULL;
+PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC __wglewDestroyDisplayColorTableEXT = NULL;
+PFNWGLLOADDISPLAYCOLORTABLEEXTPROC __wglewLoadDisplayColorTableEXT = NULL;
+
+PFNWGLGETEXTENSIONSSTRINGEXTPROC __wglewGetExtensionsStringEXT = NULL;
+
+PFNWGLGETCURRENTREADDCEXTPROC __wglewGetCurrentReadDCEXT = NULL;
+PFNWGLMAKECONTEXTCURRENTEXTPROC __wglewMakeContextCurrentEXT = NULL;
+
+PFNWGLCREATEPBUFFEREXTPROC __wglewCreatePbufferEXT = NULL;
+PFNWGLDESTROYPBUFFEREXTPROC __wglewDestroyPbufferEXT = NULL;
+PFNWGLGETPBUFFERDCEXTPROC __wglewGetPbufferDCEXT = NULL;
+PFNWGLQUERYPBUFFEREXTPROC __wglewQueryPbufferEXT = NULL;
+PFNWGLRELEASEPBUFFERDCEXTPROC __wglewReleasePbufferDCEXT = NULL;
+
+PFNWGLCHOOSEPIXELFORMATEXTPROC __wglewChoosePixelFormatEXT = NULL;
+PFNWGLGETPIXELFORMATATTRIBFVEXTPROC __wglewGetPixelFormatAttribfvEXT = NULL;
+PFNWGLGETPIXELFORMATATTRIBIVEXTPROC __wglewGetPixelFormatAttribivEXT = NULL;
+
+PFNWGLGETSWAPINTERVALEXTPROC __wglewGetSwapIntervalEXT = NULL;
+PFNWGLSWAPINTERVALEXTPROC __wglewSwapIntervalEXT = NULL;
+
+PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC __wglewGetDigitalVideoParametersI3D = NULL;
+PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC __wglewSetDigitalVideoParametersI3D = NULL;
+
+PFNWGLGETGAMMATABLEI3DPROC __wglewGetGammaTableI3D = NULL;
+PFNWGLGETGAMMATABLEPARAMETERSI3DPROC __wglewGetGammaTableParametersI3D = NULL;
+PFNWGLSETGAMMATABLEI3DPROC __wglewSetGammaTableI3D = NULL;
+PFNWGLSETGAMMATABLEPARAMETERSI3DPROC __wglewSetGammaTableParametersI3D = NULL;
+
+PFNWGLDISABLEGENLOCKI3DPROC __wglewDisableGenlockI3D = NULL;
+PFNWGLENABLEGENLOCKI3DPROC __wglewEnableGenlockI3D = NULL;
+PFNWGLGENLOCKSAMPLERATEI3DPROC __wglewGenlockSampleRateI3D = NULL;
+PFNWGLGENLOCKSOURCEDELAYI3DPROC __wglewGenlockSourceDelayI3D = NULL;
+PFNWGLGENLOCKSOURCEEDGEI3DPROC __wglewGenlockSourceEdgeI3D = NULL;
+PFNWGLGENLOCKSOURCEI3DPROC __wglewGenlockSourceI3D = NULL;
+PFNWGLGETGENLOCKSAMPLERATEI3DPROC __wglewGetGenlockSampleRateI3D = NULL;
+PFNWGLGETGENLOCKSOURCEDELAYI3DPROC __wglewGetGenlockSourceDelayI3D = NULL;
+PFNWGLGETGENLOCKSOURCEEDGEI3DPROC __wglewGetGenlockSourceEdgeI3D = NULL;
+PFNWGLGETGENLOCKSOURCEI3DPROC __wglewGetGenlockSourceI3D = NULL;
+PFNWGLISENABLEDGENLOCKI3DPROC __wglewIsEnabledGenlockI3D = NULL;
+PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC __wglewQueryGenlockMaxSourceDelayI3D = NULL;
+
+PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC __wglewAssociateImageBufferEventsI3D = NULL;
+PFNWGLCREATEIMAGEBUFFERI3DPROC __wglewCreateImageBufferI3D = NULL;
+PFNWGLDESTROYIMAGEBUFFERI3DPROC __wglewDestroyImageBufferI3D = NULL;
+PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC __wglewReleaseImageBufferEventsI3D = NULL;
+
+PFNWGLDISABLEFRAMELOCKI3DPROC __wglewDisableFrameLockI3D = NULL;
+PFNWGLENABLEFRAMELOCKI3DPROC __wglewEnableFrameLockI3D = NULL;
+PFNWGLISENABLEDFRAMELOCKI3DPROC __wglewIsEnabledFrameLockI3D = NULL;
+PFNWGLQUERYFRAMELOCKMASTERI3DPROC __wglewQueryFrameLockMasterI3D = NULL;
+
+PFNWGLBEGINFRAMETRACKINGI3DPROC __wglewBeginFrameTrackingI3D = NULL;
+PFNWGLENDFRAMETRACKINGI3DPROC __wglewEndFrameTrackingI3D = NULL;
+PFNWGLGETFRAMEUSAGEI3DPROC __wglewGetFrameUsageI3D = NULL;
+PFNWGLQUERYFRAMETRACKINGI3DPROC __wglewQueryFrameTrackingI3D = NULL;
+
+PFNWGLDXCLOSEDEVICENVPROC __wglewDXCloseDeviceNV = NULL;
+PFNWGLDXLOCKOBJECTSNVPROC __wglewDXLockObjectsNV = NULL;
+PFNWGLDXOBJECTACCESSNVPROC __wglewDXObjectAccessNV = NULL;
+PFNWGLDXOPENDEVICENVPROC __wglewDXOpenDeviceNV = NULL;
+PFNWGLDXREGISTEROBJECTNVPROC __wglewDXRegisterObjectNV = NULL;
+PFNWGLDXSETRESOURCESHAREHANDLENVPROC __wglewDXSetResourceShareHandleNV = NULL;
+PFNWGLDXUNLOCKOBJECTSNVPROC __wglewDXUnlockObjectsNV = NULL;
+PFNWGLDXUNREGISTEROBJECTNVPROC __wglewDXUnregisterObjectNV = NULL;
+
+PFNWGLCOPYIMAGESUBDATANVPROC __wglewCopyImageSubDataNV = NULL;
+
+PFNWGLCREATEAFFINITYDCNVPROC __wglewCreateAffinityDCNV = NULL;
+PFNWGLDELETEDCNVPROC __wglewDeleteDCNV = NULL;
+PFNWGLENUMGPUDEVICESNVPROC __wglewEnumGpuDevicesNV = NULL;
+PFNWGLENUMGPUSFROMAFFINITYDCNVPROC __wglewEnumGpusFromAffinityDCNV = NULL;
+PFNWGLENUMGPUSNVPROC __wglewEnumGpusNV = NULL;
+
+PFNWGLBINDVIDEODEVICENVPROC __wglewBindVideoDeviceNV = NULL;
+PFNWGLENUMERATEVIDEODEVICESNVPROC __wglewEnumerateVideoDevicesNV = NULL;
+PFNWGLQUERYCURRENTCONTEXTNVPROC __wglewQueryCurrentContextNV = NULL;
+
+PFNWGLBINDSWAPBARRIERNVPROC __wglewBindSwapBarrierNV = NULL;
+PFNWGLJOINSWAPGROUPNVPROC __wglewJoinSwapGroupNV = NULL;
+PFNWGLQUERYFRAMECOUNTNVPROC __wglewQueryFrameCountNV = NULL;
+PFNWGLQUERYMAXSWAPGROUPSNVPROC __wglewQueryMaxSwapGroupsNV = NULL;
+PFNWGLQUERYSWAPGROUPNVPROC __wglewQuerySwapGroupNV = NULL;
+PFNWGLRESETFRAMECOUNTNVPROC __wglewResetFrameCountNV = NULL;
+
+PFNWGLALLOCATEMEMORYNVPROC __wglewAllocateMemoryNV = NULL;
+PFNWGLFREEMEMORYNVPROC __wglewFreeMemoryNV = NULL;
+
+PFNWGLBINDVIDEOCAPTUREDEVICENVPROC __wglewBindVideoCaptureDeviceNV = NULL;
+PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC __wglewEnumerateVideoCaptureDevicesNV = NULL;
+PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC __wglewLockVideoCaptureDeviceNV = NULL;
+PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC __wglewQueryVideoCaptureDeviceNV = NULL;
+PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC __wglewReleaseVideoCaptureDeviceNV = NULL;
+
+PFNWGLBINDVIDEOIMAGENVPROC __wglewBindVideoImageNV = NULL;
+PFNWGLGETVIDEODEVICENVPROC __wglewGetVideoDeviceNV = NULL;
+PFNWGLGETVIDEOINFONVPROC __wglewGetVideoInfoNV = NULL;
+PFNWGLRELEASEVIDEODEVICENVPROC __wglewReleaseVideoDeviceNV = NULL;
+PFNWGLRELEASEVIDEOIMAGENVPROC __wglewReleaseVideoImageNV = NULL;
+PFNWGLSENDPBUFFERTOVIDEONVPROC __wglewSendPbufferToVideoNV = NULL;
+
+PFNWGLGETMSCRATEOMLPROC __wglewGetMscRateOML = NULL;
+PFNWGLGETSYNCVALUESOMLPROC __wglewGetSyncValuesOML = NULL;
+PFNWGLSWAPBUFFERSMSCOMLPROC __wglewSwapBuffersMscOML = NULL;
+PFNWGLSWAPLAYERBUFFERSMSCOMLPROC __wglewSwapLayerBuffersMscOML = NULL;
+PFNWGLWAITFORMSCOMLPROC __wglewWaitForMscOML = NULL;
+PFNWGLWAITFORSBCOMLPROC __wglewWaitForSbcOML = NULL;
+GLboolean __WGLEW_3DFX_multisample = GL_FALSE;
+GLboolean __WGLEW_3DL_stereo_control = GL_FALSE;
+GLboolean __WGLEW_AMD_gpu_association = GL_FALSE;
+GLboolean __WGLEW_ARB_buffer_region = GL_FALSE;
+GLboolean __WGLEW_ARB_create_context = GL_FALSE;
+GLboolean __WGLEW_ARB_create_context_profile = GL_FALSE;
+GLboolean __WGLEW_ARB_create_context_robustness = GL_FALSE;
+GLboolean __WGLEW_ARB_extensions_string = GL_FALSE;
+GLboolean __WGLEW_ARB_framebuffer_sRGB = GL_FALSE;
+GLboolean __WGLEW_ARB_make_current_read = GL_FALSE;
+GLboolean __WGLEW_ARB_multisample = GL_FALSE;
+GLboolean __WGLEW_ARB_pbuffer = GL_FALSE;
+GLboolean __WGLEW_ARB_pixel_format = GL_FALSE;
+GLboolean __WGLEW_ARB_pixel_format_float = GL_FALSE;
+GLboolean __WGLEW_ARB_render_texture = GL_FALSE;
+GLboolean __WGLEW_ARB_robustness_application_isolation = GL_FALSE;
+GLboolean __WGLEW_ARB_robustness_share_group_isolation = GL_FALSE;
+GLboolean __WGLEW_ATI_pixel_format_float = GL_FALSE;
+GLboolean __WGLEW_ATI_render_texture_rectangle = GL_FALSE;
+GLboolean __WGLEW_EXT_create_context_es2_profile = GL_FALSE;
+GLboolean __WGLEW_EXT_create_context_es_profile = GL_FALSE;
+GLboolean __WGLEW_EXT_depth_float = GL_FALSE;
+GLboolean __WGLEW_EXT_display_color_table = GL_FALSE;
+GLboolean __WGLEW_EXT_extensions_string = GL_FALSE;
+GLboolean __WGLEW_EXT_framebuffer_sRGB = GL_FALSE;
+GLboolean __WGLEW_EXT_make_current_read = GL_FALSE;
+GLboolean __WGLEW_EXT_multisample = GL_FALSE;
+GLboolean __WGLEW_EXT_pbuffer = GL_FALSE;
+GLboolean __WGLEW_EXT_pixel_format = GL_FALSE;
+GLboolean __WGLEW_EXT_pixel_format_packed_float = GL_FALSE;
+GLboolean __WGLEW_EXT_swap_control = GL_FALSE;
+GLboolean __WGLEW_EXT_swap_control_tear = GL_FALSE;
+GLboolean __WGLEW_I3D_digital_video_control = GL_FALSE;
+GLboolean __WGLEW_I3D_gamma = GL_FALSE;
+GLboolean __WGLEW_I3D_genlock = GL_FALSE;
+GLboolean __WGLEW_I3D_image_buffer = GL_FALSE;
+GLboolean __WGLEW_I3D_swap_frame_lock = GL_FALSE;
+GLboolean __WGLEW_I3D_swap_frame_usage = GL_FALSE;
+GLboolean __WGLEW_NV_DX_interop = GL_FALSE;
+GLboolean __WGLEW_NV_DX_interop2 = GL_FALSE;
+GLboolean __WGLEW_NV_copy_image = GL_FALSE;
+GLboolean __WGLEW_NV_float_buffer = GL_FALSE;
+GLboolean __WGLEW_NV_gpu_affinity = GL_FALSE;
+GLboolean __WGLEW_NV_multisample_coverage = GL_FALSE;
+GLboolean __WGLEW_NV_present_video = GL_FALSE;
+GLboolean __WGLEW_NV_render_depth_texture = GL_FALSE;
+GLboolean __WGLEW_NV_render_texture_rectangle = GL_FALSE;
+GLboolean __WGLEW_NV_swap_group = GL_FALSE;
+GLboolean __WGLEW_NV_vertex_array_range = GL_FALSE;
+GLboolean __WGLEW_NV_video_capture = GL_FALSE;
+GLboolean __WGLEW_NV_video_output = GL_FALSE;
+GLboolean __WGLEW_OML_sync_control = GL_FALSE;
+
+#endif /* !GLEW_MX */
+
+#ifdef WGL_3DFX_multisample
+
+#endif /* WGL_3DFX_multisample */
+
+#ifdef WGL_3DL_stereo_control
+
+static GLboolean _glewInit_WGL_3DL_stereo_control (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglSetStereoEmitterState3DL = (PFNWGLSETSTEREOEMITTERSTATE3DLPROC)glewGetProcAddress((const GLubyte*)"wglSetStereoEmitterState3DL")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_3DL_stereo_control */
+
+#ifdef WGL_AMD_gpu_association
+
+static GLboolean _glewInit_WGL_AMD_gpu_association (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBlitContextFramebufferAMD = (PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC)glewGetProcAddress((const GLubyte*)"wglBlitContextFramebufferAMD")) == NULL) || r;
+ r = ((wglCreateAssociatedContextAMD = (PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"wglCreateAssociatedContextAMD")) == NULL) || r;
+ r = ((wglCreateAssociatedContextAttribsAMD = (PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC)glewGetProcAddress((const GLubyte*)"wglCreateAssociatedContextAttribsAMD")) == NULL) || r;
+ r = ((wglDeleteAssociatedContextAMD = (PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"wglDeleteAssociatedContextAMD")) == NULL) || r;
+ r = ((wglGetContextGPUIDAMD = (PFNWGLGETCONTEXTGPUIDAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetContextGPUIDAMD")) == NULL) || r;
+ r = ((wglGetCurrentAssociatedContextAMD = (PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentAssociatedContextAMD")) == NULL) || r;
+ r = ((wglGetGPUIDsAMD = (PFNWGLGETGPUIDSAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetGPUIDsAMD")) == NULL) || r;
+ r = ((wglGetGPUInfoAMD = (PFNWGLGETGPUINFOAMDPROC)glewGetProcAddress((const GLubyte*)"wglGetGPUInfoAMD")) == NULL) || r;
+ r = ((wglMakeAssociatedContextCurrentAMD = (PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC)glewGetProcAddress((const GLubyte*)"wglMakeAssociatedContextCurrentAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_AMD_gpu_association */
+
+#ifdef WGL_ARB_buffer_region
+
+static GLboolean _glewInit_WGL_ARB_buffer_region (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglCreateBufferRegionARB = (PFNWGLCREATEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglCreateBufferRegionARB")) == NULL) || r;
+ r = ((wglDeleteBufferRegionARB = (PFNWGLDELETEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglDeleteBufferRegionARB")) == NULL) || r;
+ r = ((wglRestoreBufferRegionARB = (PFNWGLRESTOREBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglRestoreBufferRegionARB")) == NULL) || r;
+ r = ((wglSaveBufferRegionARB = (PFNWGLSAVEBUFFERREGIONARBPROC)glewGetProcAddress((const GLubyte*)"wglSaveBufferRegionARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_ARB_buffer_region */
+
+#ifdef WGL_ARB_create_context
+
+static GLboolean _glewInit_WGL_ARB_create_context (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)glewGetProcAddress((const GLubyte*)"wglCreateContextAttribsARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_ARB_create_context */
+
+#ifdef WGL_ARB_create_context_profile
+
+#endif /* WGL_ARB_create_context_profile */
+
+#ifdef WGL_ARB_create_context_robustness
+
+#endif /* WGL_ARB_create_context_robustness */
+
+#ifdef WGL_ARB_extensions_string
+
+static GLboolean _glewInit_WGL_ARB_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_ARB_extensions_string */
+
+#ifdef WGL_ARB_framebuffer_sRGB
+
+#endif /* WGL_ARB_framebuffer_sRGB */
+
+#ifdef WGL_ARB_make_current_read
+
+static GLboolean _glewInit_WGL_ARB_make_current_read (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetCurrentReadDCARB = (PFNWGLGETCURRENTREADDCARBPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentReadDCARB")) == NULL) || r;
+ r = ((wglMakeContextCurrentARB = (PFNWGLMAKECONTEXTCURRENTARBPROC)glewGetProcAddress((const GLubyte*)"wglMakeContextCurrentARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_ARB_make_current_read */
+
+#ifdef WGL_ARB_multisample
+
+#endif /* WGL_ARB_multisample */
+
+#ifdef WGL_ARB_pbuffer
+
+static GLboolean _glewInit_WGL_ARB_pbuffer (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglCreatePbufferARB")) == NULL) || r;
+ r = ((wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglDestroyPbufferARB")) == NULL) || r;
+ r = ((wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPbufferDCARB")) == NULL) || r;
+ r = ((wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)glewGetProcAddress((const GLubyte*)"wglQueryPbufferARB")) == NULL) || r;
+ r = ((wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)glewGetProcAddress((const GLubyte*)"wglReleasePbufferDCARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_ARB_pbuffer */
+
+#ifdef WGL_ARB_pixel_format
+
+static GLboolean _glewInit_WGL_ARB_pixel_format (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)glewGetProcAddress((const GLubyte*)"wglChoosePixelFormatARB")) == NULL) || r;
+ r = ((wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribfvARB")) == NULL) || r;
+ r = ((wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribivARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_ARB_pixel_format */
+
+#ifdef WGL_ARB_pixel_format_float
+
+#endif /* WGL_ARB_pixel_format_float */
+
+#ifdef WGL_ARB_render_texture
+
+static GLboolean _glewInit_WGL_ARB_render_texture (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBindTexImageARB = (PFNWGLBINDTEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"wglBindTexImageARB")) == NULL) || r;
+ r = ((wglReleaseTexImageARB = (PFNWGLRELEASETEXIMAGEARBPROC)glewGetProcAddress((const GLubyte*)"wglReleaseTexImageARB")) == NULL) || r;
+ r = ((wglSetPbufferAttribARB = (PFNWGLSETPBUFFERATTRIBARBPROC)glewGetProcAddress((const GLubyte*)"wglSetPbufferAttribARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_ARB_render_texture */
+
+#ifdef WGL_ARB_robustness_application_isolation
+
+#endif /* WGL_ARB_robustness_application_isolation */
+
+#ifdef WGL_ARB_robustness_share_group_isolation
+
+#endif /* WGL_ARB_robustness_share_group_isolation */
+
+#ifdef WGL_ATI_pixel_format_float
+
+#endif /* WGL_ATI_pixel_format_float */
+
+#ifdef WGL_ATI_render_texture_rectangle
+
+#endif /* WGL_ATI_render_texture_rectangle */
+
+#ifdef WGL_EXT_create_context_es2_profile
+
+#endif /* WGL_EXT_create_context_es2_profile */
+
+#ifdef WGL_EXT_create_context_es_profile
+
+#endif /* WGL_EXT_create_context_es_profile */
+
+#ifdef WGL_EXT_depth_float
+
+#endif /* WGL_EXT_depth_float */
+
+#ifdef WGL_EXT_display_color_table
+
+static GLboolean _glewInit_WGL_EXT_display_color_table (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBindDisplayColorTableEXT = (PFNWGLBINDDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglBindDisplayColorTableEXT")) == NULL) || r;
+ r = ((wglCreateDisplayColorTableEXT = (PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglCreateDisplayColorTableEXT")) == NULL) || r;
+ r = ((wglDestroyDisplayColorTableEXT = (PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglDestroyDisplayColorTableEXT")) == NULL) || r;
+ r = ((wglLoadDisplayColorTableEXT = (PFNWGLLOADDISPLAYCOLORTABLEEXTPROC)glewGetProcAddress((const GLubyte*)"wglLoadDisplayColorTableEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_EXT_display_color_table */
+
+#ifdef WGL_EXT_extensions_string
+
+static GLboolean _glewInit_WGL_EXT_extensions_string (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_EXT_extensions_string */
+
+#ifdef WGL_EXT_framebuffer_sRGB
+
+#endif /* WGL_EXT_framebuffer_sRGB */
+
+#ifdef WGL_EXT_make_current_read
+
+static GLboolean _glewInit_WGL_EXT_make_current_read (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetCurrentReadDCEXT = (PFNWGLGETCURRENTREADDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetCurrentReadDCEXT")) == NULL) || r;
+ r = ((wglMakeContextCurrentEXT = (PFNWGLMAKECONTEXTCURRENTEXTPROC)glewGetProcAddress((const GLubyte*)"wglMakeContextCurrentEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_EXT_make_current_read */
+
+#ifdef WGL_EXT_multisample
+
+#endif /* WGL_EXT_multisample */
+
+#ifdef WGL_EXT_pbuffer
+
+static GLboolean _glewInit_WGL_EXT_pbuffer (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglCreatePbufferEXT = (PFNWGLCREATEPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglCreatePbufferEXT")) == NULL) || r;
+ r = ((wglDestroyPbufferEXT = (PFNWGLDESTROYPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglDestroyPbufferEXT")) == NULL) || r;
+ r = ((wglGetPbufferDCEXT = (PFNWGLGETPBUFFERDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPbufferDCEXT")) == NULL) || r;
+ r = ((wglQueryPbufferEXT = (PFNWGLQUERYPBUFFEREXTPROC)glewGetProcAddress((const GLubyte*)"wglQueryPbufferEXT")) == NULL) || r;
+ r = ((wglReleasePbufferDCEXT = (PFNWGLRELEASEPBUFFERDCEXTPROC)glewGetProcAddress((const GLubyte*)"wglReleasePbufferDCEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_EXT_pbuffer */
+
+#ifdef WGL_EXT_pixel_format
+
+static GLboolean _glewInit_WGL_EXT_pixel_format (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglChoosePixelFormatEXT = (PFNWGLCHOOSEPIXELFORMATEXTPROC)glewGetProcAddress((const GLubyte*)"wglChoosePixelFormatEXT")) == NULL) || r;
+ r = ((wglGetPixelFormatAttribfvEXT = (PFNWGLGETPIXELFORMATATTRIBFVEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribfvEXT")) == NULL) || r;
+ r = ((wglGetPixelFormatAttribivEXT = (PFNWGLGETPIXELFORMATATTRIBIVEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetPixelFormatAttribivEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_EXT_pixel_format */
+
+#ifdef WGL_EXT_pixel_format_packed_float
+
+#endif /* WGL_EXT_pixel_format_packed_float */
+
+#ifdef WGL_EXT_swap_control
+
+static GLboolean _glewInit_WGL_EXT_swap_control (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetSwapIntervalEXT")) == NULL) || r;
+ r = ((wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"wglSwapIntervalEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_EXT_swap_control */
+
+#ifdef WGL_EXT_swap_control_tear
+
+#endif /* WGL_EXT_swap_control_tear */
+
+#ifdef WGL_I3D_digital_video_control
+
+static GLboolean _glewInit_WGL_I3D_digital_video_control (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetDigitalVideoParametersI3D = (PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetDigitalVideoParametersI3D")) == NULL) || r;
+ r = ((wglSetDigitalVideoParametersI3D = (PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetDigitalVideoParametersI3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_I3D_digital_video_control */
+
+#ifdef WGL_I3D_gamma
+
+static GLboolean _glewInit_WGL_I3D_gamma (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetGammaTableI3D = (PFNWGLGETGAMMATABLEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGammaTableI3D")) == NULL) || r;
+ r = ((wglGetGammaTableParametersI3D = (PFNWGLGETGAMMATABLEPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGammaTableParametersI3D")) == NULL) || r;
+ r = ((wglSetGammaTableI3D = (PFNWGLSETGAMMATABLEI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetGammaTableI3D")) == NULL) || r;
+ r = ((wglSetGammaTableParametersI3D = (PFNWGLSETGAMMATABLEPARAMETERSI3DPROC)glewGetProcAddress((const GLubyte*)"wglSetGammaTableParametersI3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_I3D_gamma */
+
+#ifdef WGL_I3D_genlock
+
+static GLboolean _glewInit_WGL_I3D_genlock (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglDisableGenlockI3D = (PFNWGLDISABLEGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglDisableGenlockI3D")) == NULL) || r;
+ r = ((wglEnableGenlockI3D = (PFNWGLENABLEGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglEnableGenlockI3D")) == NULL) || r;
+ r = ((wglGenlockSampleRateI3D = (PFNWGLGENLOCKSAMPLERATEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSampleRateI3D")) == NULL) || r;
+ r = ((wglGenlockSourceDelayI3D = (PFNWGLGENLOCKSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceDelayI3D")) == NULL) || r;
+ r = ((wglGenlockSourceEdgeI3D = (PFNWGLGENLOCKSOURCEEDGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceEdgeI3D")) == NULL) || r;
+ r = ((wglGenlockSourceI3D = (PFNWGLGENLOCKSOURCEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGenlockSourceI3D")) == NULL) || r;
+ r = ((wglGetGenlockSampleRateI3D = (PFNWGLGETGENLOCKSAMPLERATEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSampleRateI3D")) == NULL) || r;
+ r = ((wglGetGenlockSourceDelayI3D = (PFNWGLGETGENLOCKSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceDelayI3D")) == NULL) || r;
+ r = ((wglGetGenlockSourceEdgeI3D = (PFNWGLGETGENLOCKSOURCEEDGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceEdgeI3D")) == NULL) || r;
+ r = ((wglGetGenlockSourceI3D = (PFNWGLGETGENLOCKSOURCEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetGenlockSourceI3D")) == NULL) || r;
+ r = ((wglIsEnabledGenlockI3D = (PFNWGLISENABLEDGENLOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglIsEnabledGenlockI3D")) == NULL) || r;
+ r = ((wglQueryGenlockMaxSourceDelayI3D = (PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryGenlockMaxSourceDelayI3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_I3D_genlock */
+
+#ifdef WGL_I3D_image_buffer
+
+static GLboolean _glewInit_WGL_I3D_image_buffer (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglAssociateImageBufferEventsI3D = (PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC)glewGetProcAddress((const GLubyte*)"wglAssociateImageBufferEventsI3D")) == NULL) || r;
+ r = ((wglCreateImageBufferI3D = (PFNWGLCREATEIMAGEBUFFERI3DPROC)glewGetProcAddress((const GLubyte*)"wglCreateImageBufferI3D")) == NULL) || r;
+ r = ((wglDestroyImageBufferI3D = (PFNWGLDESTROYIMAGEBUFFERI3DPROC)glewGetProcAddress((const GLubyte*)"wglDestroyImageBufferI3D")) == NULL) || r;
+ r = ((wglReleaseImageBufferEventsI3D = (PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC)glewGetProcAddress((const GLubyte*)"wglReleaseImageBufferEventsI3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_I3D_image_buffer */
+
+#ifdef WGL_I3D_swap_frame_lock
+
+static GLboolean _glewInit_WGL_I3D_swap_frame_lock (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglDisableFrameLockI3D = (PFNWGLDISABLEFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglDisableFrameLockI3D")) == NULL) || r;
+ r = ((wglEnableFrameLockI3D = (PFNWGLENABLEFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglEnableFrameLockI3D")) == NULL) || r;
+ r = ((wglIsEnabledFrameLockI3D = (PFNWGLISENABLEDFRAMELOCKI3DPROC)glewGetProcAddress((const GLubyte*)"wglIsEnabledFrameLockI3D")) == NULL) || r;
+ r = ((wglQueryFrameLockMasterI3D = (PFNWGLQUERYFRAMELOCKMASTERI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameLockMasterI3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_I3D_swap_frame_lock */
+
+#ifdef WGL_I3D_swap_frame_usage
+
+static GLboolean _glewInit_WGL_I3D_swap_frame_usage (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBeginFrameTrackingI3D = (PFNWGLBEGINFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglBeginFrameTrackingI3D")) == NULL) || r;
+ r = ((wglEndFrameTrackingI3D = (PFNWGLENDFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglEndFrameTrackingI3D")) == NULL) || r;
+ r = ((wglGetFrameUsageI3D = (PFNWGLGETFRAMEUSAGEI3DPROC)glewGetProcAddress((const GLubyte*)"wglGetFrameUsageI3D")) == NULL) || r;
+ r = ((wglQueryFrameTrackingI3D = (PFNWGLQUERYFRAMETRACKINGI3DPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameTrackingI3D")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_I3D_swap_frame_usage */
+
+#ifdef WGL_NV_DX_interop
+
+static GLboolean _glewInit_WGL_NV_DX_interop (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglDXCloseDeviceNV = (PFNWGLDXCLOSEDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglDXCloseDeviceNV")) == NULL) || r;
+ r = ((wglDXLockObjectsNV = (PFNWGLDXLOCKOBJECTSNVPROC)glewGetProcAddress((const GLubyte*)"wglDXLockObjectsNV")) == NULL) || r;
+ r = ((wglDXObjectAccessNV = (PFNWGLDXOBJECTACCESSNVPROC)glewGetProcAddress((const GLubyte*)"wglDXObjectAccessNV")) == NULL) || r;
+ r = ((wglDXOpenDeviceNV = (PFNWGLDXOPENDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglDXOpenDeviceNV")) == NULL) || r;
+ r = ((wglDXRegisterObjectNV = (PFNWGLDXREGISTEROBJECTNVPROC)glewGetProcAddress((const GLubyte*)"wglDXRegisterObjectNV")) == NULL) || r;
+ r = ((wglDXSetResourceShareHandleNV = (PFNWGLDXSETRESOURCESHAREHANDLENVPROC)glewGetProcAddress((const GLubyte*)"wglDXSetResourceShareHandleNV")) == NULL) || r;
+ r = ((wglDXUnlockObjectsNV = (PFNWGLDXUNLOCKOBJECTSNVPROC)glewGetProcAddress((const GLubyte*)"wglDXUnlockObjectsNV")) == NULL) || r;
+ r = ((wglDXUnregisterObjectNV = (PFNWGLDXUNREGISTEROBJECTNVPROC)glewGetProcAddress((const GLubyte*)"wglDXUnregisterObjectNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_DX_interop */
+
+#ifdef WGL_NV_DX_interop2
+
+#endif /* WGL_NV_DX_interop2 */
+
+#ifdef WGL_NV_copy_image
+
+static GLboolean _glewInit_WGL_NV_copy_image (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglCopyImageSubDataNV = (PFNWGLCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"wglCopyImageSubDataNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_copy_image */
+
+#ifdef WGL_NV_float_buffer
+
+#endif /* WGL_NV_float_buffer */
+
+#ifdef WGL_NV_gpu_affinity
+
+static GLboolean _glewInit_WGL_NV_gpu_affinity (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglCreateAffinityDCNV = (PFNWGLCREATEAFFINITYDCNVPROC)glewGetProcAddress((const GLubyte*)"wglCreateAffinityDCNV")) == NULL) || r;
+ r = ((wglDeleteDCNV = (PFNWGLDELETEDCNVPROC)glewGetProcAddress((const GLubyte*)"wglDeleteDCNV")) == NULL) || r;
+ r = ((wglEnumGpuDevicesNV = (PFNWGLENUMGPUDEVICESNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpuDevicesNV")) == NULL) || r;
+ r = ((wglEnumGpusFromAffinityDCNV = (PFNWGLENUMGPUSFROMAFFINITYDCNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpusFromAffinityDCNV")) == NULL) || r;
+ r = ((wglEnumGpusNV = (PFNWGLENUMGPUSNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumGpusNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_gpu_affinity */
+
+#ifdef WGL_NV_multisample_coverage
+
+#endif /* WGL_NV_multisample_coverage */
+
+#ifdef WGL_NV_present_video
+
+static GLboolean _glewInit_WGL_NV_present_video (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBindVideoDeviceNV = (PFNWGLBINDVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglBindVideoDeviceNV")) == NULL) || r;
+ r = ((wglEnumerateVideoDevicesNV = (PFNWGLENUMERATEVIDEODEVICESNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumerateVideoDevicesNV")) == NULL) || r;
+ r = ((wglQueryCurrentContextNV = (PFNWGLQUERYCURRENTCONTEXTNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryCurrentContextNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_present_video */
+
+#ifdef WGL_NV_render_depth_texture
+
+#endif /* WGL_NV_render_depth_texture */
+
+#ifdef WGL_NV_render_texture_rectangle
+
+#endif /* WGL_NV_render_texture_rectangle */
+
+#ifdef WGL_NV_swap_group
+
+static GLboolean _glewInit_WGL_NV_swap_group (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBindSwapBarrierNV = (PFNWGLBINDSWAPBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"wglBindSwapBarrierNV")) == NULL) || r;
+ r = ((wglJoinSwapGroupNV = (PFNWGLJOINSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"wglJoinSwapGroupNV")) == NULL) || r;
+ r = ((wglQueryFrameCountNV = (PFNWGLQUERYFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryFrameCountNV")) == NULL) || r;
+ r = ((wglQueryMaxSwapGroupsNV = (PFNWGLQUERYMAXSWAPGROUPSNVPROC)glewGetProcAddress((const GLubyte*)"wglQueryMaxSwapGroupsNV")) == NULL) || r;
+ r = ((wglQuerySwapGroupNV = (PFNWGLQUERYSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"wglQuerySwapGroupNV")) == NULL) || r;
+ r = ((wglResetFrameCountNV = (PFNWGLRESETFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"wglResetFrameCountNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_swap_group */
+
+#ifdef WGL_NV_vertex_array_range
+
+static GLboolean _glewInit_WGL_NV_vertex_array_range (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"wglAllocateMemoryNV")) == NULL) || r;
+ r = ((wglFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"wglFreeMemoryNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_vertex_array_range */
+
+#ifdef WGL_NV_video_capture
+
+static GLboolean _glewInit_WGL_NV_video_capture (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBindVideoCaptureDeviceNV = (PFNWGLBINDVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglBindVideoCaptureDeviceNV")) == NULL) || r;
+ r = ((wglEnumerateVideoCaptureDevicesNV = (PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC)glewGetProcAddress((const GLubyte*)"wglEnumerateVideoCaptureDevicesNV")) == NULL) || r;
+ r = ((wglLockVideoCaptureDeviceNV = (PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglLockVideoCaptureDeviceNV")) == NULL) || r;
+ r = ((wglQueryVideoCaptureDeviceNV = (PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglQueryVideoCaptureDeviceNV")) == NULL) || r;
+ r = ((wglReleaseVideoCaptureDeviceNV = (PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglReleaseVideoCaptureDeviceNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_video_capture */
+
+#ifdef WGL_NV_video_output
+
+static GLboolean _glewInit_WGL_NV_video_output (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglBindVideoImageNV = (PFNWGLBINDVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"wglBindVideoImageNV")) == NULL) || r;
+ r = ((wglGetVideoDeviceNV = (PFNWGLGETVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglGetVideoDeviceNV")) == NULL) || r;
+ r = ((wglGetVideoInfoNV = (PFNWGLGETVIDEOINFONVPROC)glewGetProcAddress((const GLubyte*)"wglGetVideoInfoNV")) == NULL) || r;
+ r = ((wglReleaseVideoDeviceNV = (PFNWGLRELEASEVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"wglReleaseVideoDeviceNV")) == NULL) || r;
+ r = ((wglReleaseVideoImageNV = (PFNWGLRELEASEVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"wglReleaseVideoImageNV")) == NULL) || r;
+ r = ((wglSendPbufferToVideoNV = (PFNWGLSENDPBUFFERTOVIDEONVPROC)glewGetProcAddress((const GLubyte*)"wglSendPbufferToVideoNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_NV_video_output */
+
+#ifdef WGL_OML_sync_control
+
+static GLboolean _glewInit_WGL_OML_sync_control (WGLEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((wglGetMscRateOML = (PFNWGLGETMSCRATEOMLPROC)glewGetProcAddress((const GLubyte*)"wglGetMscRateOML")) == NULL) || r;
+ r = ((wglGetSyncValuesOML = (PFNWGLGETSYNCVALUESOMLPROC)glewGetProcAddress((const GLubyte*)"wglGetSyncValuesOML")) == NULL) || r;
+ r = ((wglSwapBuffersMscOML = (PFNWGLSWAPBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglSwapBuffersMscOML")) == NULL) || r;
+ r = ((wglSwapLayerBuffersMscOML = (PFNWGLSWAPLAYERBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglSwapLayerBuffersMscOML")) == NULL) || r;
+ r = ((wglWaitForMscOML = (PFNWGLWAITFORMSCOMLPROC)glewGetProcAddress((const GLubyte*)"wglWaitForMscOML")) == NULL) || r;
+ r = ((wglWaitForSbcOML = (PFNWGLWAITFORSBCOMLPROC)glewGetProcAddress((const GLubyte*)"wglWaitForSbcOML")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* WGL_OML_sync_control */
+
+/* ------------------------------------------------------------------------- */
+
+static PFNWGLGETEXTENSIONSSTRINGARBPROC _wglewGetExtensionsStringARB = NULL;
+static PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglewGetExtensionsStringEXT = NULL;
+
+GLboolean GLEWAPIENTRY wglewGetExtension (const char* name)
+{
+ const GLubyte* start;
+ const GLubyte* end;
+ if (_wglewGetExtensionsStringARB == NULL)
+ if (_wglewGetExtensionsStringEXT == NULL)
+ return GL_FALSE;
+ else
+ start = (const GLubyte*)_wglewGetExtensionsStringEXT();
+ else
+ start = (const GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC());
+ if (start == 0)
+ return GL_FALSE;
+ end = start + _glewStrLen(start);
+ return _glewSearchExtension(name, start, end);
+}
+
+GLenum GLEWAPIENTRY wglewContextInit (WGLEW_CONTEXT_ARG_DEF_LIST)
+{
+ GLboolean crippled;
+ const GLubyte* extStart;
+ const GLubyte* extEnd;
+ /* find wgl extension string query functions */
+ _wglewGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringARB");
+ _wglewGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)glewGetProcAddress((const GLubyte*)"wglGetExtensionsStringEXT");
+ /* query wgl extension string */
+ if (_wglewGetExtensionsStringARB == NULL)
+ if (_wglewGetExtensionsStringEXT == NULL)
+ extStart = (const GLubyte*)"";
+ else
+ extStart = (const GLubyte*)_wglewGetExtensionsStringEXT();
+ else
+ extStart = (const GLubyte*)_wglewGetExtensionsStringARB(wglGetCurrentDC());
+ extEnd = extStart + _glewStrLen(extStart);
+ /* initialize extensions */
+ crippled = _wglewGetExtensionsStringARB == NULL && _wglewGetExtensionsStringEXT == NULL;
+#ifdef WGL_3DFX_multisample
+ CONST_CAST(WGLEW_3DFX_multisample) = _glewSearchExtension("WGL_3DFX_multisample", extStart, extEnd);
+#endif /* WGL_3DFX_multisample */
+#ifdef WGL_3DL_stereo_control
+ CONST_CAST(WGLEW_3DL_stereo_control) = _glewSearchExtension("WGL_3DL_stereo_control", extStart, extEnd);
+ if (glewExperimental || WGLEW_3DL_stereo_control|| crippled) CONST_CAST(WGLEW_3DL_stereo_control)= !_glewInit_WGL_3DL_stereo_control(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_3DL_stereo_control */
+#ifdef WGL_AMD_gpu_association
+ CONST_CAST(WGLEW_AMD_gpu_association) = _glewSearchExtension("WGL_AMD_gpu_association", extStart, extEnd);
+ if (glewExperimental || WGLEW_AMD_gpu_association|| crippled) CONST_CAST(WGLEW_AMD_gpu_association)= !_glewInit_WGL_AMD_gpu_association(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_AMD_gpu_association */
+#ifdef WGL_ARB_buffer_region
+ CONST_CAST(WGLEW_ARB_buffer_region) = _glewSearchExtension("WGL_ARB_buffer_region", extStart, extEnd);
+ if (glewExperimental || WGLEW_ARB_buffer_region|| crippled) CONST_CAST(WGLEW_ARB_buffer_region)= !_glewInit_WGL_ARB_buffer_region(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_ARB_buffer_region */
+#ifdef WGL_ARB_create_context
+ CONST_CAST(WGLEW_ARB_create_context) = _glewSearchExtension("WGL_ARB_create_context", extStart, extEnd);
+ if (glewExperimental || WGLEW_ARB_create_context|| crippled) CONST_CAST(WGLEW_ARB_create_context)= !_glewInit_WGL_ARB_create_context(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_ARB_create_context */
+#ifdef WGL_ARB_create_context_profile
+ CONST_CAST(WGLEW_ARB_create_context_profile) = _glewSearchExtension("WGL_ARB_create_context_profile", extStart, extEnd);
+#endif /* WGL_ARB_create_context_profile */
+#ifdef WGL_ARB_create_context_robustness
+ CONST_CAST(WGLEW_ARB_create_context_robustness) = _glewSearchExtension("WGL_ARB_create_context_robustness", extStart, extEnd);
+#endif /* WGL_ARB_create_context_robustness */
+#ifdef WGL_ARB_extensions_string
+ CONST_CAST(WGLEW_ARB_extensions_string) = _glewSearchExtension("WGL_ARB_extensions_string", extStart, extEnd);
+ if (glewExperimental || WGLEW_ARB_extensions_string|| crippled) CONST_CAST(WGLEW_ARB_extensions_string)= !_glewInit_WGL_ARB_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_ARB_extensions_string */
+#ifdef WGL_ARB_framebuffer_sRGB
+ CONST_CAST(WGLEW_ARB_framebuffer_sRGB) = _glewSearchExtension("WGL_ARB_framebuffer_sRGB", extStart, extEnd);
+#endif /* WGL_ARB_framebuffer_sRGB */
+#ifdef WGL_ARB_make_current_read
+ CONST_CAST(WGLEW_ARB_make_current_read) = _glewSearchExtension("WGL_ARB_make_current_read", extStart, extEnd);
+ if (glewExperimental || WGLEW_ARB_make_current_read|| crippled) CONST_CAST(WGLEW_ARB_make_current_read)= !_glewInit_WGL_ARB_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_ARB_make_current_read */
+#ifdef WGL_ARB_multisample
+ CONST_CAST(WGLEW_ARB_multisample) = _glewSearchExtension("WGL_ARB_multisample", extStart, extEnd);
+#endif /* WGL_ARB_multisample */
+#ifdef WGL_ARB_pbuffer
+ CONST_CAST(WGLEW_ARB_pbuffer) = _glewSearchExtension("WGL_ARB_pbuffer", extStart, extEnd);
+ if (glewExperimental || WGLEW_ARB_pbuffer|| crippled) CONST_CAST(WGLEW_ARB_pbuffer)= !_glewInit_WGL_ARB_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_ARB_pbuffer */
+#ifdef WGL_ARB_pixel_format
+ CONST_CAST(WGLEW_ARB_pixel_format) = _glewSearchExtension("WGL_ARB_pixel_format", extStart, extEnd);
+ if (glewExperimental || WGLEW_ARB_pixel_format|| crippled) CONST_CAST(WGLEW_ARB_pixel_format)= !_glewInit_WGL_ARB_pixel_format(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_ARB_pixel_format */
+#ifdef WGL_ARB_pixel_format_float
+ CONST_CAST(WGLEW_ARB_pixel_format_float) = _glewSearchExtension("WGL_ARB_pixel_format_float", extStart, extEnd);
+#endif /* WGL_ARB_pixel_format_float */
+#ifdef WGL_ARB_render_texture
+ CONST_CAST(WGLEW_ARB_render_texture) = _glewSearchExtension("WGL_ARB_render_texture", extStart, extEnd);
+ if (glewExperimental || WGLEW_ARB_render_texture|| crippled) CONST_CAST(WGLEW_ARB_render_texture)= !_glewInit_WGL_ARB_render_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_ARB_render_texture */
+#ifdef WGL_ARB_robustness_application_isolation
+ CONST_CAST(WGLEW_ARB_robustness_application_isolation) = _glewSearchExtension("WGL_ARB_robustness_application_isolation", extStart, extEnd);
+#endif /* WGL_ARB_robustness_application_isolation */
+#ifdef WGL_ARB_robustness_share_group_isolation
+ CONST_CAST(WGLEW_ARB_robustness_share_group_isolation) = _glewSearchExtension("WGL_ARB_robustness_share_group_isolation", extStart, extEnd);
+#endif /* WGL_ARB_robustness_share_group_isolation */
+#ifdef WGL_ATI_pixel_format_float
+ CONST_CAST(WGLEW_ATI_pixel_format_float) = _glewSearchExtension("WGL_ATI_pixel_format_float", extStart, extEnd);
+#endif /* WGL_ATI_pixel_format_float */
+#ifdef WGL_ATI_render_texture_rectangle
+ CONST_CAST(WGLEW_ATI_render_texture_rectangle) = _glewSearchExtension("WGL_ATI_render_texture_rectangle", extStart, extEnd);
+#endif /* WGL_ATI_render_texture_rectangle */
+#ifdef WGL_EXT_create_context_es2_profile
+ CONST_CAST(WGLEW_EXT_create_context_es2_profile) = _glewSearchExtension("WGL_EXT_create_context_es2_profile", extStart, extEnd);
+#endif /* WGL_EXT_create_context_es2_profile */
+#ifdef WGL_EXT_create_context_es_profile
+ CONST_CAST(WGLEW_EXT_create_context_es_profile) = _glewSearchExtension("WGL_EXT_create_context_es_profile", extStart, extEnd);
+#endif /* WGL_EXT_create_context_es_profile */
+#ifdef WGL_EXT_depth_float
+ CONST_CAST(WGLEW_EXT_depth_float) = _glewSearchExtension("WGL_EXT_depth_float", extStart, extEnd);
+#endif /* WGL_EXT_depth_float */
+#ifdef WGL_EXT_display_color_table
+ CONST_CAST(WGLEW_EXT_display_color_table) = _glewSearchExtension("WGL_EXT_display_color_table", extStart, extEnd);
+ if (glewExperimental || WGLEW_EXT_display_color_table|| crippled) CONST_CAST(WGLEW_EXT_display_color_table)= !_glewInit_WGL_EXT_display_color_table(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_EXT_display_color_table */
+#ifdef WGL_EXT_extensions_string
+ CONST_CAST(WGLEW_EXT_extensions_string) = _glewSearchExtension("WGL_EXT_extensions_string", extStart, extEnd);
+ if (glewExperimental || WGLEW_EXT_extensions_string|| crippled) CONST_CAST(WGLEW_EXT_extensions_string)= !_glewInit_WGL_EXT_extensions_string(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_EXT_extensions_string */
+#ifdef WGL_EXT_framebuffer_sRGB
+ CONST_CAST(WGLEW_EXT_framebuffer_sRGB) = _glewSearchExtension("WGL_EXT_framebuffer_sRGB", extStart, extEnd);
+#endif /* WGL_EXT_framebuffer_sRGB */
+#ifdef WGL_EXT_make_current_read
+ CONST_CAST(WGLEW_EXT_make_current_read) = _glewSearchExtension("WGL_EXT_make_current_read", extStart, extEnd);
+ if (glewExperimental || WGLEW_EXT_make_current_read|| crippled) CONST_CAST(WGLEW_EXT_make_current_read)= !_glewInit_WGL_EXT_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_EXT_make_current_read */
+#ifdef WGL_EXT_multisample
+ CONST_CAST(WGLEW_EXT_multisample) = _glewSearchExtension("WGL_EXT_multisample", extStart, extEnd);
+#endif /* WGL_EXT_multisample */
+#ifdef WGL_EXT_pbuffer
+ CONST_CAST(WGLEW_EXT_pbuffer) = _glewSearchExtension("WGL_EXT_pbuffer", extStart, extEnd);
+ if (glewExperimental || WGLEW_EXT_pbuffer|| crippled) CONST_CAST(WGLEW_EXT_pbuffer)= !_glewInit_WGL_EXT_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_EXT_pbuffer */
+#ifdef WGL_EXT_pixel_format
+ CONST_CAST(WGLEW_EXT_pixel_format) = _glewSearchExtension("WGL_EXT_pixel_format", extStart, extEnd);
+ if (glewExperimental || WGLEW_EXT_pixel_format|| crippled) CONST_CAST(WGLEW_EXT_pixel_format)= !_glewInit_WGL_EXT_pixel_format(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_EXT_pixel_format */
+#ifdef WGL_EXT_pixel_format_packed_float
+ CONST_CAST(WGLEW_EXT_pixel_format_packed_float) = _glewSearchExtension("WGL_EXT_pixel_format_packed_float", extStart, extEnd);
+#endif /* WGL_EXT_pixel_format_packed_float */
+#ifdef WGL_EXT_swap_control
+ CONST_CAST(WGLEW_EXT_swap_control) = _glewSearchExtension("WGL_EXT_swap_control", extStart, extEnd);
+ if (glewExperimental || WGLEW_EXT_swap_control|| crippled) CONST_CAST(WGLEW_EXT_swap_control)= !_glewInit_WGL_EXT_swap_control(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_EXT_swap_control */
+#ifdef WGL_EXT_swap_control_tear
+ CONST_CAST(WGLEW_EXT_swap_control_tear) = _glewSearchExtension("WGL_EXT_swap_control_tear", extStart, extEnd);
+#endif /* WGL_EXT_swap_control_tear */
+#ifdef WGL_I3D_digital_video_control
+ CONST_CAST(WGLEW_I3D_digital_video_control) = _glewSearchExtension("WGL_I3D_digital_video_control", extStart, extEnd);
+ if (glewExperimental || WGLEW_I3D_digital_video_control|| crippled) CONST_CAST(WGLEW_I3D_digital_video_control)= !_glewInit_WGL_I3D_digital_video_control(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_I3D_digital_video_control */
+#ifdef WGL_I3D_gamma
+ CONST_CAST(WGLEW_I3D_gamma) = _glewSearchExtension("WGL_I3D_gamma", extStart, extEnd);
+ if (glewExperimental || WGLEW_I3D_gamma|| crippled) CONST_CAST(WGLEW_I3D_gamma)= !_glewInit_WGL_I3D_gamma(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_I3D_gamma */
+#ifdef WGL_I3D_genlock
+ CONST_CAST(WGLEW_I3D_genlock) = _glewSearchExtension("WGL_I3D_genlock", extStart, extEnd);
+ if (glewExperimental || WGLEW_I3D_genlock|| crippled) CONST_CAST(WGLEW_I3D_genlock)= !_glewInit_WGL_I3D_genlock(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_I3D_genlock */
+#ifdef WGL_I3D_image_buffer
+ CONST_CAST(WGLEW_I3D_image_buffer) = _glewSearchExtension("WGL_I3D_image_buffer", extStart, extEnd);
+ if (glewExperimental || WGLEW_I3D_image_buffer|| crippled) CONST_CAST(WGLEW_I3D_image_buffer)= !_glewInit_WGL_I3D_image_buffer(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_I3D_image_buffer */
+#ifdef WGL_I3D_swap_frame_lock
+ CONST_CAST(WGLEW_I3D_swap_frame_lock) = _glewSearchExtension("WGL_I3D_swap_frame_lock", extStart, extEnd);
+ if (glewExperimental || WGLEW_I3D_swap_frame_lock|| crippled) CONST_CAST(WGLEW_I3D_swap_frame_lock)= !_glewInit_WGL_I3D_swap_frame_lock(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_I3D_swap_frame_lock */
+#ifdef WGL_I3D_swap_frame_usage
+ CONST_CAST(WGLEW_I3D_swap_frame_usage) = _glewSearchExtension("WGL_I3D_swap_frame_usage", extStart, extEnd);
+ if (glewExperimental || WGLEW_I3D_swap_frame_usage|| crippled) CONST_CAST(WGLEW_I3D_swap_frame_usage)= !_glewInit_WGL_I3D_swap_frame_usage(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_I3D_swap_frame_usage */
+#ifdef WGL_NV_DX_interop
+ CONST_CAST(WGLEW_NV_DX_interop) = _glewSearchExtension("WGL_NV_DX_interop", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_DX_interop|| crippled) CONST_CAST(WGLEW_NV_DX_interop)= !_glewInit_WGL_NV_DX_interop(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_NV_DX_interop */
+#ifdef WGL_NV_DX_interop2
+ CONST_CAST(WGLEW_NV_DX_interop2) = _glewSearchExtension("WGL_NV_DX_interop2", extStart, extEnd);
+#endif /* WGL_NV_DX_interop2 */
+#ifdef WGL_NV_copy_image
+ CONST_CAST(WGLEW_NV_copy_image) = _glewSearchExtension("WGL_NV_copy_image", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_copy_image|| crippled) CONST_CAST(WGLEW_NV_copy_image)= !_glewInit_WGL_NV_copy_image(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_NV_copy_image */
+#ifdef WGL_NV_float_buffer
+ CONST_CAST(WGLEW_NV_float_buffer) = _glewSearchExtension("WGL_NV_float_buffer", extStart, extEnd);
+#endif /* WGL_NV_float_buffer */
+#ifdef WGL_NV_gpu_affinity
+ CONST_CAST(WGLEW_NV_gpu_affinity) = _glewSearchExtension("WGL_NV_gpu_affinity", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_gpu_affinity|| crippled) CONST_CAST(WGLEW_NV_gpu_affinity)= !_glewInit_WGL_NV_gpu_affinity(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_NV_gpu_affinity */
+#ifdef WGL_NV_multisample_coverage
+ CONST_CAST(WGLEW_NV_multisample_coverage) = _glewSearchExtension("WGL_NV_multisample_coverage", extStart, extEnd);
+#endif /* WGL_NV_multisample_coverage */
+#ifdef WGL_NV_present_video
+ CONST_CAST(WGLEW_NV_present_video) = _glewSearchExtension("WGL_NV_present_video", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_present_video|| crippled) CONST_CAST(WGLEW_NV_present_video)= !_glewInit_WGL_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_NV_present_video */
+#ifdef WGL_NV_render_depth_texture
+ CONST_CAST(WGLEW_NV_render_depth_texture) = _glewSearchExtension("WGL_NV_render_depth_texture", extStart, extEnd);
+#endif /* WGL_NV_render_depth_texture */
+#ifdef WGL_NV_render_texture_rectangle
+ CONST_CAST(WGLEW_NV_render_texture_rectangle) = _glewSearchExtension("WGL_NV_render_texture_rectangle", extStart, extEnd);
+#endif /* WGL_NV_render_texture_rectangle */
+#ifdef WGL_NV_swap_group
+ CONST_CAST(WGLEW_NV_swap_group) = _glewSearchExtension("WGL_NV_swap_group", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_swap_group|| crippled) CONST_CAST(WGLEW_NV_swap_group)= !_glewInit_WGL_NV_swap_group(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_NV_swap_group */
+#ifdef WGL_NV_vertex_array_range
+ CONST_CAST(WGLEW_NV_vertex_array_range) = _glewSearchExtension("WGL_NV_vertex_array_range", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_vertex_array_range|| crippled) CONST_CAST(WGLEW_NV_vertex_array_range)= !_glewInit_WGL_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_NV_vertex_array_range */
+#ifdef WGL_NV_video_capture
+ CONST_CAST(WGLEW_NV_video_capture) = _glewSearchExtension("WGL_NV_video_capture", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_video_capture|| crippled) CONST_CAST(WGLEW_NV_video_capture)= !_glewInit_WGL_NV_video_capture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_NV_video_capture */
+#ifdef WGL_NV_video_output
+ CONST_CAST(WGLEW_NV_video_output) = _glewSearchExtension("WGL_NV_video_output", extStart, extEnd);
+ if (glewExperimental || WGLEW_NV_video_output|| crippled) CONST_CAST(WGLEW_NV_video_output)= !_glewInit_WGL_NV_video_output(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_NV_video_output */
+#ifdef WGL_OML_sync_control
+ CONST_CAST(WGLEW_OML_sync_control) = _glewSearchExtension("WGL_OML_sync_control", extStart, extEnd);
+ if (glewExperimental || WGLEW_OML_sync_control|| crippled) CONST_CAST(WGLEW_OML_sync_control)= !_glewInit_WGL_OML_sync_control(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* WGL_OML_sync_control */
+
+ return GLEW_OK;
+}
+
+#elif !defined(__ANDROID__) && !defined(__native_client__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX))
+
+
+#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+PFNGLXGETPROCADDRESSARBPROC __glewXGetProcAddressARB = NULL;
+PFNGLXQUERYEXTENSION __glewXQueryExtension=NULL;
+PFNGLXQUERYVERSION __glewXQueryVersion=NULL;
+PFNGLXGETCONFIG __glewXGetConfig=NULL;
+PFNGLXCHOOSEVISUAL __glewXChooseVisual=NULL;
+PFNGLXCREATECONTEXT __glewXCreateContext=NULL;
+PFNGLXDESTROYCONTEXT __glewXDestroyContext=NULL;
+PFNGLXISDIRECT __glewXIsDirect=NULL;
+PFNGLXMAKECURRENT __glewXMakeCurrent=NULL;
+PFNGLXQUERYEXTENSIONSSTRING __glewXQueryExtensionsString=NULL;
+PFNGLXGETCLIENTSTRING __glewXGetClientString=NULL;
+PFNGLXQUERYSERVERSTRING __glewXQueryServerString=NULL;
+PFNGLXSWAPBUFFERS __glewXSwapBuffers=NULL;
+
+#endif//GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+
+PFNGLXGETCURRENTDISPLAYPROC __glewXGetCurrentDisplay = NULL;
+
+PFNGLXCHOOSEFBCONFIGPROC __glewXChooseFBConfig = NULL;
+PFNGLXCREATENEWCONTEXTPROC __glewXCreateNewContext = NULL;
+PFNGLXCREATEPBUFFERPROC __glewXCreatePbuffer = NULL;
+PFNGLXCREATEPIXMAPPROC __glewXCreatePixmap = NULL;
+PFNGLXCREATEWINDOWPROC __glewXCreateWindow = NULL;
+PFNGLXDESTROYPBUFFERPROC __glewXDestroyPbuffer = NULL;
+PFNGLXDESTROYPIXMAPPROC __glewXDestroyPixmap = NULL;
+PFNGLXDESTROYWINDOWPROC __glewXDestroyWindow = NULL;
+PFNGLXGETCURRENTREADDRAWABLEPROC __glewXGetCurrentReadDrawable = NULL;
+PFNGLXGETFBCONFIGATTRIBPROC __glewXGetFBConfigAttrib = NULL;
+PFNGLXGETFBCONFIGSPROC __glewXGetFBConfigs = NULL;
+PFNGLXGETSELECTEDEVENTPROC __glewXGetSelectedEvent = NULL;
+PFNGLXGETVISUALFROMFBCONFIGPROC __glewXGetVisualFromFBConfig = NULL;
+PFNGLXMAKECONTEXTCURRENTPROC __glewXMakeContextCurrent = NULL;
+PFNGLXQUERYCONTEXTPROC __glewXQueryContext = NULL;
+PFNGLXQUERYDRAWABLEPROC __glewXQueryDrawable = NULL;
+PFNGLXSELECTEVENTPROC __glewXSelectEvent = NULL;
+
+PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC __glewXBlitContextFramebufferAMD = NULL;
+PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC __glewXCreateAssociatedContextAMD = NULL;
+PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC __glewXCreateAssociatedContextAttribsAMD = NULL;
+PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC __glewXDeleteAssociatedContextAMD = NULL;
+PFNGLXGETCONTEXTGPUIDAMDPROC __glewXGetContextGPUIDAMD = NULL;
+PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC __glewXGetCurrentAssociatedContextAMD = NULL;
+PFNGLXGETGPUIDSAMDPROC __glewXGetGPUIDsAMD = NULL;
+PFNGLXGETGPUINFOAMDPROC __glewXGetGPUInfoAMD = NULL;
+PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC __glewXMakeAssociatedContextCurrentAMD = NULL;
+
+PFNGLXCREATECONTEXTATTRIBSARBPROC __glewXCreateContextAttribsARB = NULL;
+
+PFNGLXBINDTEXIMAGEATIPROC __glewXBindTexImageATI = NULL;
+PFNGLXDRAWABLEATTRIBATIPROC __glewXDrawableAttribATI = NULL;
+PFNGLXRELEASETEXIMAGEATIPROC __glewXReleaseTexImageATI = NULL;
+
+PFNGLXFREECONTEXTEXTPROC __glewXFreeContextEXT = NULL;
+PFNGLXGETCONTEXTIDEXTPROC __glewXGetContextIDEXT = NULL;
+PFNGLXIMPORTCONTEXTEXTPROC __glewXImportContextEXT = NULL;
+PFNGLXQUERYCONTEXTINFOEXTPROC __glewXQueryContextInfoEXT = NULL;
+
+PFNGLXSWAPINTERVALEXTPROC __glewXSwapIntervalEXT = NULL;
+
+PFNGLXBINDTEXIMAGEEXTPROC __glewXBindTexImageEXT = NULL;
+PFNGLXRELEASETEXIMAGEEXTPROC __glewXReleaseTexImageEXT = NULL;
+
+PFNGLXGETAGPOFFSETMESAPROC __glewXGetAGPOffsetMESA = NULL;
+
+PFNGLXCOPYSUBBUFFERMESAPROC __glewXCopySubBufferMESA = NULL;
+
+PFNGLXCREATEGLXPIXMAPMESAPROC __glewXCreateGLXPixmapMESA = NULL;
+
+PFNGLXRELEASEBUFFERSMESAPROC __glewXReleaseBuffersMESA = NULL;
+
+PFNGLXSET3DFXMODEMESAPROC __glewXSet3DfxModeMESA = NULL;
+
+PFNGLXGETSWAPINTERVALMESAPROC __glewXGetSwapIntervalMESA = NULL;
+PFNGLXSWAPINTERVALMESAPROC __glewXSwapIntervalMESA = NULL;
+
+PFNGLXCOPYIMAGESUBDATANVPROC __glewXCopyImageSubDataNV = NULL;
+
+PFNGLXBINDVIDEODEVICENVPROC __glewXBindVideoDeviceNV = NULL;
+PFNGLXENUMERATEVIDEODEVICESNVPROC __glewXEnumerateVideoDevicesNV = NULL;
+
+PFNGLXBINDSWAPBARRIERNVPROC __glewXBindSwapBarrierNV = NULL;
+PFNGLXJOINSWAPGROUPNVPROC __glewXJoinSwapGroupNV = NULL;
+PFNGLXQUERYFRAMECOUNTNVPROC __glewXQueryFrameCountNV = NULL;
+PFNGLXQUERYMAXSWAPGROUPSNVPROC __glewXQueryMaxSwapGroupsNV = NULL;
+PFNGLXQUERYSWAPGROUPNVPROC __glewXQuerySwapGroupNV = NULL;
+PFNGLXRESETFRAMECOUNTNVPROC __glewXResetFrameCountNV = NULL;
+
+PFNGLXALLOCATEMEMORYNVPROC __glewXAllocateMemoryNV = NULL;
+PFNGLXFREEMEMORYNVPROC __glewXFreeMemoryNV = NULL;
+
+PFNGLXBINDVIDEOCAPTUREDEVICENVPROC __glewXBindVideoCaptureDeviceNV = NULL;
+PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC __glewXEnumerateVideoCaptureDevicesNV = NULL;
+PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC __glewXLockVideoCaptureDeviceNV = NULL;
+PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC __glewXQueryVideoCaptureDeviceNV = NULL;
+PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC __glewXReleaseVideoCaptureDeviceNV = NULL;
+
+PFNGLXBINDVIDEOIMAGENVPROC __glewXBindVideoImageNV = NULL;
+PFNGLXGETVIDEODEVICENVPROC __glewXGetVideoDeviceNV = NULL;
+PFNGLXGETVIDEOINFONVPROC __glewXGetVideoInfoNV = NULL;
+PFNGLXRELEASEVIDEODEVICENVPROC __glewXReleaseVideoDeviceNV = NULL;
+PFNGLXRELEASEVIDEOIMAGENVPROC __glewXReleaseVideoImageNV = NULL;
+PFNGLXSENDPBUFFERTOVIDEONVPROC __glewXSendPbufferToVideoNV = NULL;
+
+PFNGLXGETMSCRATEOMLPROC __glewXGetMscRateOML = NULL;
+PFNGLXGETSYNCVALUESOMLPROC __glewXGetSyncValuesOML = NULL;
+PFNGLXSWAPBUFFERSMSCOMLPROC __glewXSwapBuffersMscOML = NULL;
+PFNGLXWAITFORMSCOMLPROC __glewXWaitForMscOML = NULL;
+PFNGLXWAITFORSBCOMLPROC __glewXWaitForSbcOML = NULL;
+
+PFNGLXCHOOSEFBCONFIGSGIXPROC __glewXChooseFBConfigSGIX = NULL;
+PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC __glewXCreateContextWithConfigSGIX = NULL;
+PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC __glewXCreateGLXPixmapWithConfigSGIX = NULL;
+PFNGLXGETFBCONFIGATTRIBSGIXPROC __glewXGetFBConfigAttribSGIX = NULL;
+PFNGLXGETFBCONFIGFROMVISUALSGIXPROC __glewXGetFBConfigFromVisualSGIX = NULL;
+PFNGLXGETVISUALFROMFBCONFIGSGIXPROC __glewXGetVisualFromFBConfigSGIX = NULL;
+
+PFNGLXBINDHYPERPIPESGIXPROC __glewXBindHyperpipeSGIX = NULL;
+PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC __glewXDestroyHyperpipeConfigSGIX = NULL;
+PFNGLXHYPERPIPEATTRIBSGIXPROC __glewXHyperpipeAttribSGIX = NULL;
+PFNGLXHYPERPIPECONFIGSGIXPROC __glewXHyperpipeConfigSGIX = NULL;
+PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC __glewXQueryHyperpipeAttribSGIX = NULL;
+PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC __glewXQueryHyperpipeBestAttribSGIX = NULL;
+PFNGLXQUERYHYPERPIPECONFIGSGIXPROC __glewXQueryHyperpipeConfigSGIX = NULL;
+PFNGLXQUERYHYPERPIPENETWORKSGIXPROC __glewXQueryHyperpipeNetworkSGIX = NULL;
+
+PFNGLXCREATEGLXPBUFFERSGIXPROC __glewXCreateGLXPbufferSGIX = NULL;
+PFNGLXDESTROYGLXPBUFFERSGIXPROC __glewXDestroyGLXPbufferSGIX = NULL;
+PFNGLXGETSELECTEDEVENTSGIXPROC __glewXGetSelectedEventSGIX = NULL;
+PFNGLXQUERYGLXPBUFFERSGIXPROC __glewXQueryGLXPbufferSGIX = NULL;
+PFNGLXSELECTEVENTSGIXPROC __glewXSelectEventSGIX = NULL;
+
+PFNGLXBINDSWAPBARRIERSGIXPROC __glewXBindSwapBarrierSGIX = NULL;
+PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC __glewXQueryMaxSwapBarriersSGIX = NULL;
+
+PFNGLXJOINSWAPGROUPSGIXPROC __glewXJoinSwapGroupSGIX = NULL;
+
+PFNGLXBINDCHANNELTOWINDOWSGIXPROC __glewXBindChannelToWindowSGIX = NULL;
+PFNGLXCHANNELRECTSGIXPROC __glewXChannelRectSGIX = NULL;
+PFNGLXCHANNELRECTSYNCSGIXPROC __glewXChannelRectSyncSGIX = NULL;
+PFNGLXQUERYCHANNELDELTASSGIXPROC __glewXQueryChannelDeltasSGIX = NULL;
+PFNGLXQUERYCHANNELRECTSGIXPROC __glewXQueryChannelRectSGIX = NULL;
+
+PFNGLXCUSHIONSGIPROC __glewXCushionSGI = NULL;
+
+PFNGLXGETCURRENTREADDRAWABLESGIPROC __glewXGetCurrentReadDrawableSGI = NULL;
+PFNGLXMAKECURRENTREADSGIPROC __glewXMakeCurrentReadSGI = NULL;
+
+PFNGLXSWAPINTERVALSGIPROC __glewXSwapIntervalSGI = NULL;
+
+PFNGLXGETVIDEOSYNCSGIPROC __glewXGetVideoSyncSGI = NULL;
+PFNGLXWAITVIDEOSYNCSGIPROC __glewXWaitVideoSyncSGI = NULL;
+
+PFNGLXGETTRANSPARENTINDEXSUNPROC __glewXGetTransparentIndexSUN = NULL;
+
+PFNGLXGETVIDEORESIZESUNPROC __glewXGetVideoResizeSUN = NULL;
+PFNGLXVIDEORESIZESUNPROC __glewXVideoResizeSUN = NULL;
+
+#if !defined(GLEW_MX)
+
+GLboolean __GLXEW_VERSION_1_0 = GL_FALSE;
+GLboolean __GLXEW_VERSION_1_1 = GL_FALSE;
+GLboolean __GLXEW_VERSION_1_2 = GL_FALSE;
+GLboolean __GLXEW_VERSION_1_3 = GL_FALSE;
+GLboolean __GLXEW_VERSION_1_4 = GL_FALSE;
+GLboolean __GLXEW_3DFX_multisample = GL_FALSE;
+GLboolean __GLXEW_AMD_gpu_association = GL_FALSE;
+GLboolean __GLXEW_ARB_create_context = GL_FALSE;
+GLboolean __GLXEW_ARB_create_context_profile = GL_FALSE;
+GLboolean __GLXEW_ARB_create_context_robustness = GL_FALSE;
+GLboolean __GLXEW_ARB_fbconfig_float = GL_FALSE;
+GLboolean __GLXEW_ARB_framebuffer_sRGB = GL_FALSE;
+GLboolean __GLXEW_ARB_get_proc_address = GL_FALSE;
+GLboolean __GLXEW_ARB_multisample = GL_FALSE;
+GLboolean __GLXEW_ARB_robustness_application_isolation = GL_FALSE;
+GLboolean __GLXEW_ARB_robustness_share_group_isolation = GL_FALSE;
+GLboolean __GLXEW_ARB_vertex_buffer_object = GL_FALSE;
+GLboolean __GLXEW_ATI_pixel_format_float = GL_FALSE;
+GLboolean __GLXEW_ATI_render_texture = GL_FALSE;
+GLboolean __GLXEW_EXT_buffer_age = GL_FALSE;
+GLboolean __GLXEW_EXT_create_context_es2_profile = GL_FALSE;
+GLboolean __GLXEW_EXT_create_context_es_profile = GL_FALSE;
+GLboolean __GLXEW_EXT_fbconfig_packed_float = GL_FALSE;
+GLboolean __GLXEW_EXT_framebuffer_sRGB = GL_FALSE;
+GLboolean __GLXEW_EXT_import_context = GL_FALSE;
+GLboolean __GLXEW_EXT_scene_marker = GL_FALSE;
+GLboolean __GLXEW_EXT_swap_control = GL_FALSE;
+GLboolean __GLXEW_EXT_swap_control_tear = GL_FALSE;
+GLboolean __GLXEW_EXT_texture_from_pixmap = GL_FALSE;
+GLboolean __GLXEW_EXT_visual_info = GL_FALSE;
+GLboolean __GLXEW_EXT_visual_rating = GL_FALSE;
+GLboolean __GLXEW_INTEL_swap_event = GL_FALSE;
+GLboolean __GLXEW_MESA_agp_offset = GL_FALSE;
+GLboolean __GLXEW_MESA_copy_sub_buffer = GL_FALSE;
+GLboolean __GLXEW_MESA_pixmap_colormap = GL_FALSE;
+GLboolean __GLXEW_MESA_release_buffers = GL_FALSE;
+GLboolean __GLXEW_MESA_set_3dfx_mode = GL_FALSE;
+GLboolean __GLXEW_MESA_swap_control = GL_FALSE;
+GLboolean __GLXEW_NV_copy_image = GL_FALSE;
+GLboolean __GLXEW_NV_float_buffer = GL_FALSE;
+GLboolean __GLXEW_NV_multisample_coverage = GL_FALSE;
+GLboolean __GLXEW_NV_present_video = GL_FALSE;
+GLboolean __GLXEW_NV_swap_group = GL_FALSE;
+GLboolean __GLXEW_NV_vertex_array_range = GL_FALSE;
+GLboolean __GLXEW_NV_video_capture = GL_FALSE;
+GLboolean __GLXEW_NV_video_output = GL_FALSE;
+GLboolean __GLXEW_OML_swap_method = GL_FALSE;
+GLboolean __GLXEW_OML_sync_control = GL_FALSE;
+GLboolean __GLXEW_SGIS_blended_overlay = GL_FALSE;
+GLboolean __GLXEW_SGIS_color_range = GL_FALSE;
+GLboolean __GLXEW_SGIS_multisample = GL_FALSE;
+GLboolean __GLXEW_SGIS_shared_multisample = GL_FALSE;
+GLboolean __GLXEW_SGIX_fbconfig = GL_FALSE;
+GLboolean __GLXEW_SGIX_hyperpipe = GL_FALSE;
+GLboolean __GLXEW_SGIX_pbuffer = GL_FALSE;
+GLboolean __GLXEW_SGIX_swap_barrier = GL_FALSE;
+GLboolean __GLXEW_SGIX_swap_group = GL_FALSE;
+GLboolean __GLXEW_SGIX_video_resize = GL_FALSE;
+GLboolean __GLXEW_SGIX_visual_select_group = GL_FALSE;
+GLboolean __GLXEW_SGI_cushion = GL_FALSE;
+GLboolean __GLXEW_SGI_make_current_read = GL_FALSE;
+GLboolean __GLXEW_SGI_swap_control = GL_FALSE;
+GLboolean __GLXEW_SGI_video_sync = GL_FALSE;
+GLboolean __GLXEW_SUN_get_transparent_index = GL_FALSE;
+GLboolean __GLXEW_SUN_video_resize = GL_FALSE;
+
+#endif /* !GLEW_MX */
+
+#ifdef GLX_VERSION_1_2
+
+static GLboolean _glewInit_GLX_VERSION_1_2 (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentDisplay")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_VERSION_1_2 */
+
+#ifdef GLX_VERSION_1_3
+
+static GLboolean _glewInit_GLX_VERSION_1_3 (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glewGetProcAddress((const GLubyte*)"glXChooseFBConfig")) == NULL) || r;
+ r = ((glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC)glewGetProcAddress((const GLubyte*)"glXCreateNewContext")) == NULL) || r;
+ r = ((glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glXCreatePbuffer")) == NULL) || r;
+ r = ((glXCreatePixmap = (PFNGLXCREATEPIXMAPPROC)glewGetProcAddress((const GLubyte*)"glXCreatePixmap")) == NULL) || r;
+ r = ((glXCreateWindow = (PFNGLXCREATEWINDOWPROC)glewGetProcAddress((const GLubyte*)"glXCreateWindow")) == NULL) || r;
+ r = ((glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC)glewGetProcAddress((const GLubyte*)"glXDestroyPbuffer")) == NULL) || r;
+ r = ((glXDestroyPixmap = (PFNGLXDESTROYPIXMAPPROC)glewGetProcAddress((const GLubyte*)"glXDestroyPixmap")) == NULL) || r;
+ r = ((glXDestroyWindow = (PFNGLXDESTROYWINDOWPROC)glewGetProcAddress((const GLubyte*)"glXDestroyWindow")) == NULL) || r;
+ r = ((glXGetCurrentReadDrawable = (PFNGLXGETCURRENTREADDRAWABLEPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentReadDrawable")) == NULL) || r;
+ r = ((glXGetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigAttrib")) == NULL) || r;
+ r = ((glXGetFBConfigs = (PFNGLXGETFBCONFIGSPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigs")) == NULL) || r;
+ r = ((glXGetSelectedEvent = (PFNGLXGETSELECTEDEVENTPROC)glewGetProcAddress((const GLubyte*)"glXGetSelectedEvent")) == NULL) || r;
+ r = ((glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glewGetProcAddress((const GLubyte*)"glXGetVisualFromFBConfig")) == NULL) || r;
+ r = ((glXMakeContextCurrent = (PFNGLXMAKECONTEXTCURRENTPROC)glewGetProcAddress((const GLubyte*)"glXMakeContextCurrent")) == NULL) || r;
+ r = ((glXQueryContext = (PFNGLXQUERYCONTEXTPROC)glewGetProcAddress((const GLubyte*)"glXQueryContext")) == NULL) || r;
+ r = ((glXQueryDrawable = (PFNGLXQUERYDRAWABLEPROC)glewGetProcAddress((const GLubyte*)"glXQueryDrawable")) == NULL) || r;
+ r = ((glXSelectEvent = (PFNGLXSELECTEVENTPROC)glewGetProcAddress((const GLubyte*)"glXSelectEvent")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_VERSION_1_3 */
+
+#ifdef GLX_VERSION_1_4
+
+#endif /* GLX_VERSION_1_4 */
+
+#ifdef GLX_3DFX_multisample
+
+#endif /* GLX_3DFX_multisample */
+
+#ifdef GLX_AMD_gpu_association
+
+static GLboolean _glewInit_GLX_AMD_gpu_association (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBlitContextFramebufferAMD = (PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC)glewGetProcAddress((const GLubyte*)"glXBlitContextFramebufferAMD")) == NULL) || r;
+ r = ((glXCreateAssociatedContextAMD = (PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"glXCreateAssociatedContextAMD")) == NULL) || r;
+ r = ((glXCreateAssociatedContextAttribsAMD = (PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC)glewGetProcAddress((const GLubyte*)"glXCreateAssociatedContextAttribsAMD")) == NULL) || r;
+ r = ((glXDeleteAssociatedContextAMD = (PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"glXDeleteAssociatedContextAMD")) == NULL) || r;
+ r = ((glXGetContextGPUIDAMD = (PFNGLXGETCONTEXTGPUIDAMDPROC)glewGetProcAddress((const GLubyte*)"glXGetContextGPUIDAMD")) == NULL) || r;
+ r = ((glXGetCurrentAssociatedContextAMD = (PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentAssociatedContextAMD")) == NULL) || r;
+ r = ((glXGetGPUIDsAMD = (PFNGLXGETGPUIDSAMDPROC)glewGetProcAddress((const GLubyte*)"glXGetGPUIDsAMD")) == NULL) || r;
+ r = ((glXGetGPUInfoAMD = (PFNGLXGETGPUINFOAMDPROC)glewGetProcAddress((const GLubyte*)"glXGetGPUInfoAMD")) == NULL) || r;
+ r = ((glXMakeAssociatedContextCurrentAMD = (PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC)glewGetProcAddress((const GLubyte*)"glXMakeAssociatedContextCurrentAMD")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_AMD_gpu_association */
+
+#ifdef GLX_ARB_create_context
+
+static GLboolean _glewInit_GLX_ARB_create_context (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glewGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_ARB_create_context */
+
+#ifdef GLX_ARB_create_context_profile
+
+#endif /* GLX_ARB_create_context_profile */
+
+#ifdef GLX_ARB_create_context_robustness
+
+#endif /* GLX_ARB_create_context_robustness */
+
+#ifdef GLX_ARB_fbconfig_float
+
+#endif /* GLX_ARB_fbconfig_float */
+
+#ifdef GLX_ARB_framebuffer_sRGB
+
+#endif /* GLX_ARB_framebuffer_sRGB */
+
+#ifdef GLX_ARB_get_proc_address
+
+#endif /* GLX_ARB_get_proc_address */
+
+#ifdef GLX_ARB_multisample
+
+#endif /* GLX_ARB_multisample */
+
+#ifdef GLX_ARB_robustness_application_isolation
+
+#endif /* GLX_ARB_robustness_application_isolation */
+
+#ifdef GLX_ARB_robustness_share_group_isolation
+
+#endif /* GLX_ARB_robustness_share_group_isolation */
+
+#ifdef GLX_ARB_vertex_buffer_object
+
+#endif /* GLX_ARB_vertex_buffer_object */
+
+#ifdef GLX_ATI_pixel_format_float
+
+#endif /* GLX_ATI_pixel_format_float */
+
+#ifdef GLX_ATI_render_texture
+
+static GLboolean _glewInit_GLX_ATI_render_texture (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindTexImageATI = (PFNGLXBINDTEXIMAGEATIPROC)glewGetProcAddress((const GLubyte*)"glXBindTexImageATI")) == NULL) || r;
+ r = ((glXDrawableAttribATI = (PFNGLXDRAWABLEATTRIBATIPROC)glewGetProcAddress((const GLubyte*)"glXDrawableAttribATI")) == NULL) || r;
+ r = ((glXReleaseTexImageATI = (PFNGLXRELEASETEXIMAGEATIPROC)glewGetProcAddress((const GLubyte*)"glXReleaseTexImageATI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_ATI_render_texture */
+
+#ifdef GLX_EXT_buffer_age
+
+#endif /* GLX_EXT_buffer_age */
+
+#ifdef GLX_EXT_create_context_es2_profile
+
+#endif /* GLX_EXT_create_context_es2_profile */
+
+#ifdef GLX_EXT_create_context_es_profile
+
+#endif /* GLX_EXT_create_context_es_profile */
+
+#ifdef GLX_EXT_fbconfig_packed_float
+
+#endif /* GLX_EXT_fbconfig_packed_float */
+
+#ifdef GLX_EXT_framebuffer_sRGB
+
+#endif /* GLX_EXT_framebuffer_sRGB */
+
+#ifdef GLX_EXT_import_context
+
+static GLboolean _glewInit_GLX_EXT_import_context (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXFreeContextEXT = (PFNGLXFREECONTEXTEXTPROC)glewGetProcAddress((const GLubyte*)"glXFreeContextEXT")) == NULL) || r;
+ r = ((glXGetContextIDEXT = (PFNGLXGETCONTEXTIDEXTPROC)glewGetProcAddress((const GLubyte*)"glXGetContextIDEXT")) == NULL) || r;
+ r = ((glXImportContextEXT = (PFNGLXIMPORTCONTEXTEXTPROC)glewGetProcAddress((const GLubyte*)"glXImportContextEXT")) == NULL) || r;
+ r = ((glXQueryContextInfoEXT = (PFNGLXQUERYCONTEXTINFOEXTPROC)glewGetProcAddress((const GLubyte*)"glXQueryContextInfoEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_EXT_import_context */
+
+#ifdef GLX_EXT_scene_marker
+
+#endif /* GLX_EXT_scene_marker */
+
+#ifdef GLX_EXT_swap_control
+
+static GLboolean _glewInit_GLX_EXT_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glewGetProcAddress((const GLubyte*)"glXSwapIntervalEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_EXT_swap_control */
+
+#ifdef GLX_EXT_swap_control_tear
+
+#endif /* GLX_EXT_swap_control_tear */
+
+#ifdef GLX_EXT_texture_from_pixmap
+
+static GLboolean _glewInit_GLX_EXT_texture_from_pixmap (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glXBindTexImageEXT")) == NULL) || r;
+ r = ((glXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC)glewGetProcAddress((const GLubyte*)"glXReleaseTexImageEXT")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_EXT_texture_from_pixmap */
+
+#ifdef GLX_EXT_visual_info
+
+#endif /* GLX_EXT_visual_info */
+
+#ifdef GLX_EXT_visual_rating
+
+#endif /* GLX_EXT_visual_rating */
+
+#ifdef GLX_INTEL_swap_event
+
+#endif /* GLX_INTEL_swap_event */
+
+#ifdef GLX_MESA_agp_offset
+
+static GLboolean _glewInit_GLX_MESA_agp_offset (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetAGPOffsetMESA = (PFNGLXGETAGPOFFSETMESAPROC)glewGetProcAddress((const GLubyte*)"glXGetAGPOffsetMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_MESA_agp_offset */
+
+#ifdef GLX_MESA_copy_sub_buffer
+
+static GLboolean _glewInit_GLX_MESA_copy_sub_buffer (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXCopySubBufferMESA = (PFNGLXCOPYSUBBUFFERMESAPROC)glewGetProcAddress((const GLubyte*)"glXCopySubBufferMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_MESA_copy_sub_buffer */
+
+#ifdef GLX_MESA_pixmap_colormap
+
+static GLboolean _glewInit_GLX_MESA_pixmap_colormap (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXCreateGLXPixmapMESA = (PFNGLXCREATEGLXPIXMAPMESAPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPixmapMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_MESA_pixmap_colormap */
+
+#ifdef GLX_MESA_release_buffers
+
+static GLboolean _glewInit_GLX_MESA_release_buffers (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXReleaseBuffersMESA = (PFNGLXRELEASEBUFFERSMESAPROC)glewGetProcAddress((const GLubyte*)"glXReleaseBuffersMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_MESA_release_buffers */
+
+#ifdef GLX_MESA_set_3dfx_mode
+
+static GLboolean _glewInit_GLX_MESA_set_3dfx_mode (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXSet3DfxModeMESA = (PFNGLXSET3DFXMODEMESAPROC)glewGetProcAddress((const GLubyte*)"glXSet3DfxModeMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_MESA_set_3dfx_mode */
+
+#ifdef GLX_MESA_swap_control
+
+static GLboolean _glewInit_GLX_MESA_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC)glewGetProcAddress((const GLubyte*)"glXGetSwapIntervalMESA")) == NULL) || r;
+ r = ((glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)glewGetProcAddress((const GLubyte*)"glXSwapIntervalMESA")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_MESA_swap_control */
+
+#ifdef GLX_NV_copy_image
+
+static GLboolean _glewInit_GLX_NV_copy_image (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXCopyImageSubDataNV = (PFNGLXCOPYIMAGESUBDATANVPROC)glewGetProcAddress((const GLubyte*)"glXCopyImageSubDataNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_NV_copy_image */
+
+#ifdef GLX_NV_float_buffer
+
+#endif /* GLX_NV_float_buffer */
+
+#ifdef GLX_NV_multisample_coverage
+
+#endif /* GLX_NV_multisample_coverage */
+
+#ifdef GLX_NV_present_video
+
+static GLboolean _glewInit_GLX_NV_present_video (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindVideoDeviceNV = (PFNGLXBINDVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXBindVideoDeviceNV")) == NULL) || r;
+ r = ((glXEnumerateVideoDevicesNV = (PFNGLXENUMERATEVIDEODEVICESNVPROC)glewGetProcAddress((const GLubyte*)"glXEnumerateVideoDevicesNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_NV_present_video */
+
+#ifdef GLX_NV_swap_group
+
+static GLboolean _glewInit_GLX_NV_swap_group (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindSwapBarrierNV = (PFNGLXBINDSWAPBARRIERNVPROC)glewGetProcAddress((const GLubyte*)"glXBindSwapBarrierNV")) == NULL) || r;
+ r = ((glXJoinSwapGroupNV = (PFNGLXJOINSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"glXJoinSwapGroupNV")) == NULL) || r;
+ r = ((glXQueryFrameCountNV = (PFNGLXQUERYFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"glXQueryFrameCountNV")) == NULL) || r;
+ r = ((glXQueryMaxSwapGroupsNV = (PFNGLXQUERYMAXSWAPGROUPSNVPROC)glewGetProcAddress((const GLubyte*)"glXQueryMaxSwapGroupsNV")) == NULL) || r;
+ r = ((glXQuerySwapGroupNV = (PFNGLXQUERYSWAPGROUPNVPROC)glewGetProcAddress((const GLubyte*)"glXQuerySwapGroupNV")) == NULL) || r;
+ r = ((glXResetFrameCountNV = (PFNGLXRESETFRAMECOUNTNVPROC)glewGetProcAddress((const GLubyte*)"glXResetFrameCountNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_NV_swap_group */
+
+#ifdef GLX_NV_vertex_array_range
+
+static GLboolean _glewInit_GLX_NV_vertex_array_range (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXAllocateMemoryNV = (PFNGLXALLOCATEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"glXAllocateMemoryNV")) == NULL) || r;
+ r = ((glXFreeMemoryNV = (PFNGLXFREEMEMORYNVPROC)glewGetProcAddress((const GLubyte*)"glXFreeMemoryNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_NV_vertex_array_range */
+
+#ifdef GLX_NV_video_capture
+
+static GLboolean _glewInit_GLX_NV_video_capture (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindVideoCaptureDeviceNV = (PFNGLXBINDVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXBindVideoCaptureDeviceNV")) == NULL) || r;
+ r = ((glXEnumerateVideoCaptureDevicesNV = (PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC)glewGetProcAddress((const GLubyte*)"glXEnumerateVideoCaptureDevicesNV")) == NULL) || r;
+ r = ((glXLockVideoCaptureDeviceNV = (PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXLockVideoCaptureDeviceNV")) == NULL) || r;
+ r = ((glXQueryVideoCaptureDeviceNV = (PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXQueryVideoCaptureDeviceNV")) == NULL) || r;
+ r = ((glXReleaseVideoCaptureDeviceNV = (PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXReleaseVideoCaptureDeviceNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_NV_video_capture */
+
+#ifdef GLX_NV_video_output
+
+static GLboolean _glewInit_GLX_NV_video_output (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindVideoImageNV = (PFNGLXBINDVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"glXBindVideoImageNV")) == NULL) || r;
+ r = ((glXGetVideoDeviceNV = (PFNGLXGETVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoDeviceNV")) == NULL) || r;
+ r = ((glXGetVideoInfoNV = (PFNGLXGETVIDEOINFONVPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoInfoNV")) == NULL) || r;
+ r = ((glXReleaseVideoDeviceNV = (PFNGLXRELEASEVIDEODEVICENVPROC)glewGetProcAddress((const GLubyte*)"glXReleaseVideoDeviceNV")) == NULL) || r;
+ r = ((glXReleaseVideoImageNV = (PFNGLXRELEASEVIDEOIMAGENVPROC)glewGetProcAddress((const GLubyte*)"glXReleaseVideoImageNV")) == NULL) || r;
+ r = ((glXSendPbufferToVideoNV = (PFNGLXSENDPBUFFERTOVIDEONVPROC)glewGetProcAddress((const GLubyte*)"glXSendPbufferToVideoNV")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_NV_video_output */
+
+#ifdef GLX_OML_swap_method
+
+#endif /* GLX_OML_swap_method */
+
+#ifdef GLX_OML_sync_control
+
+static GLboolean _glewInit_GLX_OML_sync_control (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetMscRateOML = (PFNGLXGETMSCRATEOMLPROC)glewGetProcAddress((const GLubyte*)"glXGetMscRateOML")) == NULL) || r;
+ r = ((glXGetSyncValuesOML = (PFNGLXGETSYNCVALUESOMLPROC)glewGetProcAddress((const GLubyte*)"glXGetSyncValuesOML")) == NULL) || r;
+ r = ((glXSwapBuffersMscOML = (PFNGLXSWAPBUFFERSMSCOMLPROC)glewGetProcAddress((const GLubyte*)"glXSwapBuffersMscOML")) == NULL) || r;
+ r = ((glXWaitForMscOML = (PFNGLXWAITFORMSCOMLPROC)glewGetProcAddress((const GLubyte*)"glXWaitForMscOML")) == NULL) || r;
+ r = ((glXWaitForSbcOML = (PFNGLXWAITFORSBCOMLPROC)glewGetProcAddress((const GLubyte*)"glXWaitForSbcOML")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_OML_sync_control */
+
+#ifdef GLX_SGIS_blended_overlay
+
+#endif /* GLX_SGIS_blended_overlay */
+
+#ifdef GLX_SGIS_color_range
+
+#endif /* GLX_SGIS_color_range */
+
+#ifdef GLX_SGIS_multisample
+
+#endif /* GLX_SGIS_multisample */
+
+#ifdef GLX_SGIS_shared_multisample
+
+#endif /* GLX_SGIS_shared_multisample */
+
+#ifdef GLX_SGIX_fbconfig
+
+static GLboolean _glewInit_GLX_SGIX_fbconfig (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChooseFBConfigSGIX")) == NULL) || r;
+ r = ((glXCreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateContextWithConfigSGIX")) == NULL) || r;
+ r = ((glXCreateGLXPixmapWithConfigSGIX = (PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPixmapWithConfigSGIX")) == NULL) || r;
+ r = ((glXGetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigAttribSGIX")) == NULL) || r;
+ r = ((glXGetFBConfigFromVisualSGIX = (PFNGLXGETFBCONFIGFROMVISUALSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetFBConfigFromVisualSGIX")) == NULL) || r;
+ r = ((glXGetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetVisualFromFBConfigSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGIX_fbconfig */
+
+#ifdef GLX_SGIX_hyperpipe
+
+static GLboolean _glewInit_GLX_SGIX_hyperpipe (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindHyperpipeSGIX = (PFNGLXBINDHYPERPIPESGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindHyperpipeSGIX")) == NULL) || r;
+ r = ((glXDestroyHyperpipeConfigSGIX = (PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXDestroyHyperpipeConfigSGIX")) == NULL) || r;
+ r = ((glXHyperpipeAttribSGIX = (PFNGLXHYPERPIPEATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXHyperpipeAttribSGIX")) == NULL) || r;
+ r = ((glXHyperpipeConfigSGIX = (PFNGLXHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXHyperpipeConfigSGIX")) == NULL) || r;
+ r = ((glXQueryHyperpipeAttribSGIX = (PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeAttribSGIX")) == NULL) || r;
+ r = ((glXQueryHyperpipeBestAttribSGIX = (PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeBestAttribSGIX")) == NULL) || r;
+ r = ((glXQueryHyperpipeConfigSGIX = (PFNGLXQUERYHYPERPIPECONFIGSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeConfigSGIX")) == NULL) || r;
+ r = ((glXQueryHyperpipeNetworkSGIX = (PFNGLXQUERYHYPERPIPENETWORKSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryHyperpipeNetworkSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGIX_hyperpipe */
+
+#ifdef GLX_SGIX_pbuffer
+
+static GLboolean _glewInit_GLX_SGIX_pbuffer (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXCreateGLXPbufferSGIX = (PFNGLXCREATEGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXCreateGLXPbufferSGIX")) == NULL) || r;
+ r = ((glXDestroyGLXPbufferSGIX = (PFNGLXDESTROYGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXDestroyGLXPbufferSGIX")) == NULL) || r;
+ r = ((glXGetSelectedEventSGIX = (PFNGLXGETSELECTEDEVENTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXGetSelectedEventSGIX")) == NULL) || r;
+ r = ((glXQueryGLXPbufferSGIX = (PFNGLXQUERYGLXPBUFFERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryGLXPbufferSGIX")) == NULL) || r;
+ r = ((glXSelectEventSGIX = (PFNGLXSELECTEVENTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXSelectEventSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGIX_pbuffer */
+
+#ifdef GLX_SGIX_swap_barrier
+
+static GLboolean _glewInit_GLX_SGIX_swap_barrier (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindSwapBarrierSGIX = (PFNGLXBINDSWAPBARRIERSGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindSwapBarrierSGIX")) == NULL) || r;
+ r = ((glXQueryMaxSwapBarriersSGIX = (PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryMaxSwapBarriersSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGIX_swap_barrier */
+
+#ifdef GLX_SGIX_swap_group
+
+static GLboolean _glewInit_GLX_SGIX_swap_group (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXJoinSwapGroupSGIX = (PFNGLXJOINSWAPGROUPSGIXPROC)glewGetProcAddress((const GLubyte*)"glXJoinSwapGroupSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGIX_swap_group */
+
+#ifdef GLX_SGIX_video_resize
+
+static GLboolean _glewInit_GLX_SGIX_video_resize (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXBindChannelToWindowSGIX = (PFNGLXBINDCHANNELTOWINDOWSGIXPROC)glewGetProcAddress((const GLubyte*)"glXBindChannelToWindowSGIX")) == NULL) || r;
+ r = ((glXChannelRectSGIX = (PFNGLXCHANNELRECTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChannelRectSGIX")) == NULL) || r;
+ r = ((glXChannelRectSyncSGIX = (PFNGLXCHANNELRECTSYNCSGIXPROC)glewGetProcAddress((const GLubyte*)"glXChannelRectSyncSGIX")) == NULL) || r;
+ r = ((glXQueryChannelDeltasSGIX = (PFNGLXQUERYCHANNELDELTASSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryChannelDeltasSGIX")) == NULL) || r;
+ r = ((glXQueryChannelRectSGIX = (PFNGLXQUERYCHANNELRECTSGIXPROC)glewGetProcAddress((const GLubyte*)"glXQueryChannelRectSGIX")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGIX_video_resize */
+
+#ifdef GLX_SGIX_visual_select_group
+
+#endif /* GLX_SGIX_visual_select_group */
+
+#ifdef GLX_SGI_cushion
+
+static GLboolean _glewInit_GLX_SGI_cushion (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXCushionSGI = (PFNGLXCUSHIONSGIPROC)glewGetProcAddress((const GLubyte*)"glXCushionSGI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGI_cushion */
+
+#ifdef GLX_SGI_make_current_read
+
+static GLboolean _glewInit_GLX_SGI_make_current_read (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetCurrentReadDrawableSGI = (PFNGLXGETCURRENTREADDRAWABLESGIPROC)glewGetProcAddress((const GLubyte*)"glXGetCurrentReadDrawableSGI")) == NULL) || r;
+ r = ((glXMakeCurrentReadSGI = (PFNGLXMAKECURRENTREADSGIPROC)glewGetProcAddress((const GLubyte*)"glXMakeCurrentReadSGI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGI_make_current_read */
+
+#ifdef GLX_SGI_swap_control
+
+static GLboolean _glewInit_GLX_SGI_swap_control (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glewGetProcAddress((const GLubyte*)"glXSwapIntervalSGI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGI_swap_control */
+
+#ifdef GLX_SGI_video_sync
+
+static GLboolean _glewInit_GLX_SGI_video_sync (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetVideoSyncSGI = (PFNGLXGETVIDEOSYNCSGIPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoSyncSGI")) == NULL) || r;
+ r = ((glXWaitVideoSyncSGI = (PFNGLXWAITVIDEOSYNCSGIPROC)glewGetProcAddress((const GLubyte*)"glXWaitVideoSyncSGI")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SGI_video_sync */
+
+#ifdef GLX_SUN_get_transparent_index
+
+static GLboolean _glewInit_GLX_SUN_get_transparent_index (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetTransparentIndexSUN = (PFNGLXGETTRANSPARENTINDEXSUNPROC)glewGetProcAddress((const GLubyte*)"glXGetTransparentIndexSUN")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SUN_get_transparent_index */
+
+#ifdef GLX_SUN_video_resize
+
+static GLboolean _glewInit_GLX_SUN_video_resize (GLXEW_CONTEXT_ARG_DEF_INIT)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glXGetVideoResizeSUN = (PFNGLXGETVIDEORESIZESUNPROC)glewGetProcAddress((const GLubyte*)"glXGetVideoResizeSUN")) == NULL) || r;
+ r = ((glXVideoResizeSUN = (PFNGLXVIDEORESIZESUNPROC)glewGetProcAddress((const GLubyte*)"glXVideoResizeSUN")) == NULL) || r;
+
+ return r;
+}
+
+#endif /* GLX_SUN_video_resize */
+
+/* ------------------------------------------------------------------------ */
+
+GLboolean glxewGetExtension (const char* name)
+{
+ const GLubyte* start;
+ const GLubyte* end;
+
+ if (glXGetCurrentDisplay == NULL) return GL_FALSE;
+ start = (const GLubyte*)glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS);
+ if (0 == start) return GL_FALSE;
+ end = start + _glewStrLen(start);
+ return _glewSearchExtension(name, start, end);
+}
+
+GLenum glxewContextInit (GLXEW_CONTEXT_ARG_DEF_LIST)
+{
+ int major, minor;
+ const GLubyte* extStart;
+ const GLubyte* extEnd;
+ /* initialize core GLX 1.2 */
+ if (_glewInit_GLX_VERSION_1_2(GLEW_CONTEXT_ARG_VAR_INIT)) return GLEW_ERROR_GLX_VERSION_11_ONLY;
+ /* initialize flags */
+ CONST_CAST(GLXEW_VERSION_1_0) = GL_TRUE;
+ CONST_CAST(GLXEW_VERSION_1_1) = GL_TRUE;
+ CONST_CAST(GLXEW_VERSION_1_2) = GL_TRUE;
+ CONST_CAST(GLXEW_VERSION_1_3) = GL_TRUE;
+ CONST_CAST(GLXEW_VERSION_1_4) = GL_TRUE;
+ /* query GLX version */
+ glXQueryVersion(glXGetCurrentDisplay(), &major, &minor);
+ if (major == 1 && minor <= 3)
+ {
+ switch (minor)
+ {
+ case 3:
+ CONST_CAST(GLXEW_VERSION_1_4) = GL_FALSE;
+ break;
+ case 2:
+ CONST_CAST(GLXEW_VERSION_1_4) = GL_FALSE;
+ CONST_CAST(GLXEW_VERSION_1_3) = GL_FALSE;
+ break;
+ default:
+ return GLEW_ERROR_GLX_VERSION_11_ONLY;
+ break;
+ }
+ }
+ /* query GLX extension string */
+ extStart = 0;
+ if (glXGetCurrentDisplay != NULL)
+ extStart = (const GLubyte*)glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS);
+ if (extStart == 0)
+ extStart = (const GLubyte *)"";
+ extEnd = extStart + _glewStrLen(extStart);
+ /* initialize extensions */
+#ifdef GLX_VERSION_1_3
+ if (glewExperimental || GLXEW_VERSION_1_3) CONST_CAST(GLXEW_VERSION_1_3) = !_glewInit_GLX_VERSION_1_3(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_VERSION_1_3 */
+#ifdef GLX_3DFX_multisample
+ CONST_CAST(GLXEW_3DFX_multisample) = _glewSearchExtension("GLX_3DFX_multisample", extStart, extEnd);
+#endif /* GLX_3DFX_multisample */
+#ifdef GLX_AMD_gpu_association
+ CONST_CAST(GLXEW_AMD_gpu_association) = _glewSearchExtension("GLX_AMD_gpu_association", extStart, extEnd);
+ if (glewExperimental || GLXEW_AMD_gpu_association) CONST_CAST(GLXEW_AMD_gpu_association) = !_glewInit_GLX_AMD_gpu_association(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_AMD_gpu_association */
+#ifdef GLX_ARB_create_context
+ CONST_CAST(GLXEW_ARB_create_context) = _glewSearchExtension("GLX_ARB_create_context", extStart, extEnd);
+ if (glewExperimental || GLXEW_ARB_create_context) CONST_CAST(GLXEW_ARB_create_context) = !_glewInit_GLX_ARB_create_context(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_ARB_create_context */
+#ifdef GLX_ARB_create_context_profile
+ CONST_CAST(GLXEW_ARB_create_context_profile) = _glewSearchExtension("GLX_ARB_create_context_profile", extStart, extEnd);
+#endif /* GLX_ARB_create_context_profile */
+#ifdef GLX_ARB_create_context_robustness
+ CONST_CAST(GLXEW_ARB_create_context_robustness) = _glewSearchExtension("GLX_ARB_create_context_robustness", extStart, extEnd);
+#endif /* GLX_ARB_create_context_robustness */
+#ifdef GLX_ARB_fbconfig_float
+ CONST_CAST(GLXEW_ARB_fbconfig_float) = _glewSearchExtension("GLX_ARB_fbconfig_float", extStart, extEnd);
+#endif /* GLX_ARB_fbconfig_float */
+#ifdef GLX_ARB_framebuffer_sRGB
+ CONST_CAST(GLXEW_ARB_framebuffer_sRGB) = _glewSearchExtension("GLX_ARB_framebuffer_sRGB", extStart, extEnd);
+#endif /* GLX_ARB_framebuffer_sRGB */
+#ifdef GLX_ARB_get_proc_address
+ CONST_CAST(GLXEW_ARB_get_proc_address) = _glewSearchExtension("GLX_ARB_get_proc_address", extStart, extEnd);
+#endif /* GLX_ARB_get_proc_address */
+#ifdef GLX_ARB_multisample
+ CONST_CAST(GLXEW_ARB_multisample) = _glewSearchExtension("GLX_ARB_multisample", extStart, extEnd);
+#endif /* GLX_ARB_multisample */
+#ifdef GLX_ARB_robustness_application_isolation
+ CONST_CAST(GLXEW_ARB_robustness_application_isolation) = _glewSearchExtension("GLX_ARB_robustness_application_isolation", extStart, extEnd);
+#endif /* GLX_ARB_robustness_application_isolation */
+#ifdef GLX_ARB_robustness_share_group_isolation
+ CONST_CAST(GLXEW_ARB_robustness_share_group_isolation) = _glewSearchExtension("GLX_ARB_robustness_share_group_isolation", extStart, extEnd);
+#endif /* GLX_ARB_robustness_share_group_isolation */
+#ifdef GLX_ARB_vertex_buffer_object
+ CONST_CAST(GLXEW_ARB_vertex_buffer_object) = _glewSearchExtension("GLX_ARB_vertex_buffer_object", extStart, extEnd);
+#endif /* GLX_ARB_vertex_buffer_object */
+#ifdef GLX_ATI_pixel_format_float
+ CONST_CAST(GLXEW_ATI_pixel_format_float) = _glewSearchExtension("GLX_ATI_pixel_format_float", extStart, extEnd);
+#endif /* GLX_ATI_pixel_format_float */
+#ifdef GLX_ATI_render_texture
+ CONST_CAST(GLXEW_ATI_render_texture) = _glewSearchExtension("GLX_ATI_render_texture", extStart, extEnd);
+ if (glewExperimental || GLXEW_ATI_render_texture) CONST_CAST(GLXEW_ATI_render_texture) = !_glewInit_GLX_ATI_render_texture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_ATI_render_texture */
+#ifdef GLX_EXT_buffer_age
+ CONST_CAST(GLXEW_EXT_buffer_age) = _glewSearchExtension("GLX_EXT_buffer_age", extStart, extEnd);
+#endif /* GLX_EXT_buffer_age */
+#ifdef GLX_EXT_create_context_es2_profile
+ CONST_CAST(GLXEW_EXT_create_context_es2_profile) = _glewSearchExtension("GLX_EXT_create_context_es2_profile", extStart, extEnd);
+#endif /* GLX_EXT_create_context_es2_profile */
+#ifdef GLX_EXT_create_context_es_profile
+ CONST_CAST(GLXEW_EXT_create_context_es_profile) = _glewSearchExtension("GLX_EXT_create_context_es_profile", extStart, extEnd);
+#endif /* GLX_EXT_create_context_es_profile */
+#ifdef GLX_EXT_fbconfig_packed_float
+ CONST_CAST(GLXEW_EXT_fbconfig_packed_float) = _glewSearchExtension("GLX_EXT_fbconfig_packed_float", extStart, extEnd);
+#endif /* GLX_EXT_fbconfig_packed_float */
+#ifdef GLX_EXT_framebuffer_sRGB
+ CONST_CAST(GLXEW_EXT_framebuffer_sRGB) = _glewSearchExtension("GLX_EXT_framebuffer_sRGB", extStart, extEnd);
+#endif /* GLX_EXT_framebuffer_sRGB */
+#ifdef GLX_EXT_import_context
+ CONST_CAST(GLXEW_EXT_import_context) = _glewSearchExtension("GLX_EXT_import_context", extStart, extEnd);
+ if (glewExperimental || GLXEW_EXT_import_context) CONST_CAST(GLXEW_EXT_import_context) = !_glewInit_GLX_EXT_import_context(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_EXT_import_context */
+#ifdef GLX_EXT_scene_marker
+ CONST_CAST(GLXEW_EXT_scene_marker) = _glewSearchExtension("GLX_EXT_scene_marker", extStart, extEnd);
+#endif /* GLX_EXT_scene_marker */
+#ifdef GLX_EXT_swap_control
+ CONST_CAST(GLXEW_EXT_swap_control) = _glewSearchExtension("GLX_EXT_swap_control", extStart, extEnd);
+ if (glewExperimental || GLXEW_EXT_swap_control) CONST_CAST(GLXEW_EXT_swap_control) = !_glewInit_GLX_EXT_swap_control(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_EXT_swap_control */
+#ifdef GLX_EXT_swap_control_tear
+ CONST_CAST(GLXEW_EXT_swap_control_tear) = _glewSearchExtension("GLX_EXT_swap_control_tear", extStart, extEnd);
+#endif /* GLX_EXT_swap_control_tear */
+#ifdef GLX_EXT_texture_from_pixmap
+ CONST_CAST(GLXEW_EXT_texture_from_pixmap) = _glewSearchExtension("GLX_EXT_texture_from_pixmap", extStart, extEnd);
+ if (glewExperimental || GLXEW_EXT_texture_from_pixmap) CONST_CAST(GLXEW_EXT_texture_from_pixmap) = !_glewInit_GLX_EXT_texture_from_pixmap(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_EXT_texture_from_pixmap */
+#ifdef GLX_EXT_visual_info
+ CONST_CAST(GLXEW_EXT_visual_info) = _glewSearchExtension("GLX_EXT_visual_info", extStart, extEnd);
+#endif /* GLX_EXT_visual_info */
+#ifdef GLX_EXT_visual_rating
+ CONST_CAST(GLXEW_EXT_visual_rating) = _glewSearchExtension("GLX_EXT_visual_rating", extStart, extEnd);
+#endif /* GLX_EXT_visual_rating */
+#ifdef GLX_INTEL_swap_event
+ CONST_CAST(GLXEW_INTEL_swap_event) = _glewSearchExtension("GLX_INTEL_swap_event", extStart, extEnd);
+#endif /* GLX_INTEL_swap_event */
+#ifdef GLX_MESA_agp_offset
+ CONST_CAST(GLXEW_MESA_agp_offset) = _glewSearchExtension("GLX_MESA_agp_offset", extStart, extEnd);
+ if (glewExperimental || GLXEW_MESA_agp_offset) CONST_CAST(GLXEW_MESA_agp_offset) = !_glewInit_GLX_MESA_agp_offset(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_MESA_agp_offset */
+#ifdef GLX_MESA_copy_sub_buffer
+ CONST_CAST(GLXEW_MESA_copy_sub_buffer) = _glewSearchExtension("GLX_MESA_copy_sub_buffer", extStart, extEnd);
+ if (glewExperimental || GLXEW_MESA_copy_sub_buffer) CONST_CAST(GLXEW_MESA_copy_sub_buffer) = !_glewInit_GLX_MESA_copy_sub_buffer(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_MESA_copy_sub_buffer */
+#ifdef GLX_MESA_pixmap_colormap
+ CONST_CAST(GLXEW_MESA_pixmap_colormap) = _glewSearchExtension("GLX_MESA_pixmap_colormap", extStart, extEnd);
+ if (glewExperimental || GLXEW_MESA_pixmap_colormap) CONST_CAST(GLXEW_MESA_pixmap_colormap) = !_glewInit_GLX_MESA_pixmap_colormap(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_MESA_pixmap_colormap */
+#ifdef GLX_MESA_release_buffers
+ CONST_CAST(GLXEW_MESA_release_buffers) = _glewSearchExtension("GLX_MESA_release_buffers", extStart, extEnd);
+ if (glewExperimental || GLXEW_MESA_release_buffers) CONST_CAST(GLXEW_MESA_release_buffers) = !_glewInit_GLX_MESA_release_buffers(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_MESA_release_buffers */
+#ifdef GLX_MESA_set_3dfx_mode
+ CONST_CAST(GLXEW_MESA_set_3dfx_mode) = _glewSearchExtension("GLX_MESA_set_3dfx_mode", extStart, extEnd);
+ if (glewExperimental || GLXEW_MESA_set_3dfx_mode) CONST_CAST(GLXEW_MESA_set_3dfx_mode) = !_glewInit_GLX_MESA_set_3dfx_mode(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_MESA_set_3dfx_mode */
+#ifdef GLX_MESA_swap_control
+ CONST_CAST(GLXEW_MESA_swap_control) = _glewSearchExtension("GLX_MESA_swap_control", extStart, extEnd);
+ if (glewExperimental || GLXEW_MESA_swap_control) CONST_CAST(GLXEW_MESA_swap_control) = !_glewInit_GLX_MESA_swap_control(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_MESA_swap_control */
+#ifdef GLX_NV_copy_image
+ CONST_CAST(GLXEW_NV_copy_image) = _glewSearchExtension("GLX_NV_copy_image", extStart, extEnd);
+ if (glewExperimental || GLXEW_NV_copy_image) CONST_CAST(GLXEW_NV_copy_image) = !_glewInit_GLX_NV_copy_image(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_NV_copy_image */
+#ifdef GLX_NV_float_buffer
+ CONST_CAST(GLXEW_NV_float_buffer) = _glewSearchExtension("GLX_NV_float_buffer", extStart, extEnd);
+#endif /* GLX_NV_float_buffer */
+#ifdef GLX_NV_multisample_coverage
+ CONST_CAST(GLXEW_NV_multisample_coverage) = _glewSearchExtension("GLX_NV_multisample_coverage", extStart, extEnd);
+#endif /* GLX_NV_multisample_coverage */
+#ifdef GLX_NV_present_video
+ CONST_CAST(GLXEW_NV_present_video) = _glewSearchExtension("GLX_NV_present_video", extStart, extEnd);
+ if (glewExperimental || GLXEW_NV_present_video) CONST_CAST(GLXEW_NV_present_video) = !_glewInit_GLX_NV_present_video(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_NV_present_video */
+#ifdef GLX_NV_swap_group
+ CONST_CAST(GLXEW_NV_swap_group) = _glewSearchExtension("GLX_NV_swap_group", extStart, extEnd);
+ if (glewExperimental || GLXEW_NV_swap_group) CONST_CAST(GLXEW_NV_swap_group) = !_glewInit_GLX_NV_swap_group(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_NV_swap_group */
+#ifdef GLX_NV_vertex_array_range
+ CONST_CAST(GLXEW_NV_vertex_array_range) = _glewSearchExtension("GLX_NV_vertex_array_range", extStart, extEnd);
+ if (glewExperimental || GLXEW_NV_vertex_array_range) CONST_CAST(GLXEW_NV_vertex_array_range) = !_glewInit_GLX_NV_vertex_array_range(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_NV_vertex_array_range */
+#ifdef GLX_NV_video_capture
+ CONST_CAST(GLXEW_NV_video_capture) = _glewSearchExtension("GLX_NV_video_capture", extStart, extEnd);
+ if (glewExperimental || GLXEW_NV_video_capture) CONST_CAST(GLXEW_NV_video_capture) = !_glewInit_GLX_NV_video_capture(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_NV_video_capture */
+#ifdef GLX_NV_video_output
+ CONST_CAST(GLXEW_NV_video_output) = _glewSearchExtension("GLX_NV_video_output", extStart, extEnd);
+ if (glewExperimental || GLXEW_NV_video_output) CONST_CAST(GLXEW_NV_video_output) = !_glewInit_GLX_NV_video_output(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_NV_video_output */
+#ifdef GLX_OML_swap_method
+ CONST_CAST(GLXEW_OML_swap_method) = _glewSearchExtension("GLX_OML_swap_method", extStart, extEnd);
+#endif /* GLX_OML_swap_method */
+#ifdef GLX_OML_sync_control
+ CONST_CAST(GLXEW_OML_sync_control) = _glewSearchExtension("GLX_OML_sync_control", extStart, extEnd);
+ if (glewExperimental || GLXEW_OML_sync_control) CONST_CAST(GLXEW_OML_sync_control) = !_glewInit_GLX_OML_sync_control(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_OML_sync_control */
+#ifdef GLX_SGIS_blended_overlay
+ CONST_CAST(GLXEW_SGIS_blended_overlay) = _glewSearchExtension("GLX_SGIS_blended_overlay", extStart, extEnd);
+#endif /* GLX_SGIS_blended_overlay */
+#ifdef GLX_SGIS_color_range
+ CONST_CAST(GLXEW_SGIS_color_range) = _glewSearchExtension("GLX_SGIS_color_range", extStart, extEnd);
+#endif /* GLX_SGIS_color_range */
+#ifdef GLX_SGIS_multisample
+ CONST_CAST(GLXEW_SGIS_multisample) = _glewSearchExtension("GLX_SGIS_multisample", extStart, extEnd);
+#endif /* GLX_SGIS_multisample */
+#ifdef GLX_SGIS_shared_multisample
+ CONST_CAST(GLXEW_SGIS_shared_multisample) = _glewSearchExtension("GLX_SGIS_shared_multisample", extStart, extEnd);
+#endif /* GLX_SGIS_shared_multisample */
+#ifdef GLX_SGIX_fbconfig
+ CONST_CAST(GLXEW_SGIX_fbconfig) = _glewSearchExtension("GLX_SGIX_fbconfig", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGIX_fbconfig) CONST_CAST(GLXEW_SGIX_fbconfig) = !_glewInit_GLX_SGIX_fbconfig(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_SGIX_fbconfig */
+#ifdef GLX_SGIX_hyperpipe
+ CONST_CAST(GLXEW_SGIX_hyperpipe) = _glewSearchExtension("GLX_SGIX_hyperpipe", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGIX_hyperpipe) CONST_CAST(GLXEW_SGIX_hyperpipe) = !_glewInit_GLX_SGIX_hyperpipe(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_SGIX_hyperpipe */
+#ifdef GLX_SGIX_pbuffer
+ CONST_CAST(GLXEW_SGIX_pbuffer) = _glewSearchExtension("GLX_SGIX_pbuffer", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGIX_pbuffer) CONST_CAST(GLXEW_SGIX_pbuffer) = !_glewInit_GLX_SGIX_pbuffer(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_SGIX_pbuffer */
+#ifdef GLX_SGIX_swap_barrier
+ CONST_CAST(GLXEW_SGIX_swap_barrier) = _glewSearchExtension("GLX_SGIX_swap_barrier", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGIX_swap_barrier) CONST_CAST(GLXEW_SGIX_swap_barrier) = !_glewInit_GLX_SGIX_swap_barrier(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_SGIX_swap_barrier */
+#ifdef GLX_SGIX_swap_group
+ CONST_CAST(GLXEW_SGIX_swap_group) = _glewSearchExtension("GLX_SGIX_swap_group", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGIX_swap_group) CONST_CAST(GLXEW_SGIX_swap_group) = !_glewInit_GLX_SGIX_swap_group(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_SGIX_swap_group */
+#ifdef GLX_SGIX_video_resize
+ CONST_CAST(GLXEW_SGIX_video_resize) = _glewSearchExtension("GLX_SGIX_video_resize", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGIX_video_resize) CONST_CAST(GLXEW_SGIX_video_resize) = !_glewInit_GLX_SGIX_video_resize(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_SGIX_video_resize */
+#ifdef GLX_SGIX_visual_select_group
+ CONST_CAST(GLXEW_SGIX_visual_select_group) = _glewSearchExtension("GLX_SGIX_visual_select_group", extStart, extEnd);
+#endif /* GLX_SGIX_visual_select_group */
+#ifdef GLX_SGI_cushion
+ CONST_CAST(GLXEW_SGI_cushion) = _glewSearchExtension("GLX_SGI_cushion", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGI_cushion) CONST_CAST(GLXEW_SGI_cushion) = !_glewInit_GLX_SGI_cushion(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_SGI_cushion */
+#ifdef GLX_SGI_make_current_read
+ CONST_CAST(GLXEW_SGI_make_current_read) = _glewSearchExtension("GLX_SGI_make_current_read", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGI_make_current_read) CONST_CAST(GLXEW_SGI_make_current_read) = !_glewInit_GLX_SGI_make_current_read(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_SGI_make_current_read */
+#ifdef GLX_SGI_swap_control
+ CONST_CAST(GLXEW_SGI_swap_control) = _glewSearchExtension("GLX_SGI_swap_control", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGI_swap_control) CONST_CAST(GLXEW_SGI_swap_control) = !_glewInit_GLX_SGI_swap_control(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_SGI_swap_control */
+#ifdef GLX_SGI_video_sync
+ CONST_CAST(GLXEW_SGI_video_sync) = _glewSearchExtension("GLX_SGI_video_sync", extStart, extEnd);
+ if (glewExperimental || GLXEW_SGI_video_sync) CONST_CAST(GLXEW_SGI_video_sync) = !_glewInit_GLX_SGI_video_sync(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_SGI_video_sync */
+#ifdef GLX_SUN_get_transparent_index
+ CONST_CAST(GLXEW_SUN_get_transparent_index) = _glewSearchExtension("GLX_SUN_get_transparent_index", extStart, extEnd);
+ if (glewExperimental || GLXEW_SUN_get_transparent_index) CONST_CAST(GLXEW_SUN_get_transparent_index) = !_glewInit_GLX_SUN_get_transparent_index(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_SUN_get_transparent_index */
+#ifdef GLX_SUN_video_resize
+ CONST_CAST(GLXEW_SUN_video_resize) = _glewSearchExtension("GLX_SUN_video_resize", extStart, extEnd);
+ if (glewExperimental || GLXEW_SUN_video_resize) CONST_CAST(GLXEW_SUN_video_resize) = !_glewInit_GLX_SUN_video_resize(GLEW_CONTEXT_ARG_VAR_INIT);
+#endif /* GLX_SUN_video_resize */
+
+ return GLEW_OK;
+}
+
+#endif /* !defined(__ANDROID__) && !defined(__native_client__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX)) */
+
+/* ------------------------------------------------------------------------ */
+
+const GLubyte * GLEWAPIENTRY glewGetErrorString (GLenum error)
+{
+ static const GLubyte* _glewErrorString[] =
+ {
+ (const GLubyte*)"No error",
+ (const GLubyte*)"Missing GL version",
+ (const GLubyte*)"GL 1.1 and up are not supported",
+ (const GLubyte*)"GLX 1.2 and up are not supported",
+ (const GLubyte*)"Unknown error"
+ };
+ const int max_error = sizeof(_glewErrorString)/sizeof(*_glewErrorString) - 1;
+ return _glewErrorString[(int)error > max_error ? max_error : (int)error];
+}
+
+const GLubyte * GLEWAPIENTRY glewGetString (GLenum name)
+{
+ static const GLubyte* _glewString[] =
+ {
+ (const GLubyte*)NULL,
+ (const GLubyte*)"1.10.0",
+ (const GLubyte*)"1",
+ (const GLubyte*)"10",
+ (const GLubyte*)"0"
+ };
+ const int max_string = sizeof(_glewString)/sizeof(*_glewString) - 1;
+ return _glewString[(int)name > max_string ? 0 : (int)name];
+}
+
+/* ------------------------------------------------------------------------ */
+
+GLboolean glewExperimental = GL_FALSE;
+
+#if !defined(GLEW_MX)
+
+#if defined(_WIN32)
+extern GLenum GLEWAPIENTRY wglewContextInit (void);
+#elif !defined(__ANDROID__) && !defined(__native_client__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX))
+extern GLenum GLEWAPIENTRY glxewContextInit (void);
+#endif /* _WIN32 */
+
+#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+GLboolean GLEWAPIENTRY glewXInit(void)
+{
+ GLboolean r = GL_FALSE;
+ r = ((glXGetProcAddressARB = (PFNGLXGETPROCADDRESSARBPROC)dlglXGetProcAddressARB((const GLubyte*)"glXGetProcAddressARB")) == NULL) || r;
+ r = ((glXQueryExtension = (PFNGLXQUERYEXTENSION)dlglXGetProcAddressARB((const GLubyte*)"glXQueryExtension")) == NULL) || r;
+ r = ((glXQueryVersion = (PFNGLXQUERYVERSION)dlglXGetProcAddressARB((const GLubyte*)"glXQueryVersion")) == NULL) || r;
+ r = ((glXGetConfig = (PFNGLXGETCONFIG)dlglXGetProcAddressARB((const GLubyte*)"glXGetConfig")) == NULL) || r;
+ r = ((glXChooseVisual = (PFNGLXCHOOSEVISUAL)dlglXGetProcAddressARB((const GLubyte*)"glXChooseVisual")) == NULL) || r;
+ r = ((glXCreateContext = (PFNGLXCREATECONTEXT)dlglXGetProcAddressARB((const GLubyte*)"glXCreateContext")) == NULL) || r;
+ r = ((glXDestroyContext = (PFNGLXDESTROYCONTEXT)dlglXGetProcAddressARB((const GLubyte*)"glXDestroyContext")) == NULL) || r;
+ r = ((glXDestroyContext = (PFNGLXDESTROYCONTEXT)dlglXGetProcAddressARB((const GLubyte*)"glXDestroyContext")) == NULL) || r;
+ r = ((glXIsDirect = (PFNGLXISDIRECT)dlglXGetProcAddressARB((const GLubyte*)"glXIsDirect")) == NULL) || r;
+ r = ((glXMakeCurrent = (PFNGLXMAKECURRENT)dlglXGetProcAddressARB((const GLubyte*)"glXMakeCurrent")) == NULL) || r;
+ r = ((glXQueryExtensionsString = (PFNGLXQUERYEXTENSIONSSTRING)dlglXGetProcAddressARB((const GLubyte*)"glXQueryExtensionsString")) == NULL) || r;
+ r = ((glXGetClientString = (PFNGLXGETCLIENTSTRING)dlglXGetProcAddressARB((const GLubyte*)"glXGetClientString")) == NULL) || r;
+ r = ((glXQueryServerString = (PFNGLXQUERYSERVERSTRING)dlglXGetProcAddressARB((const GLubyte*)"glXQueryServerString")) == NULL) || r;
+ r = ((glXSwapBuffers = (PFNGLXSWAPBUFFERS)dlglXGetProcAddressARB((const GLubyte*)"glXSwapBuffers")) == NULL) || r;
+ //glxewContextInit();
+ _glewInit_GLX_VERSION_1_3();
+
+ if (r==0)
+ {
+ printf("glewXInit dynamically loaded using dlopen/dlsym OK\n");
+ }
+ return r;
+}
+#endif //GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
+
+#ifdef GLEW_INIT_OPENGL11_FUNCTIONS
+
+PFNGLACCUMPROC __glewAccum = NULL;
+PFNGLALPHAFUNCPROC __glewAlphaFunc = NULL;
+PFNGLARETEXTURESRESIDENTPROC __glewAreTexturesResident = NULL;
+PFNGLARRAYELEMENTPROC __glewArrayElement = NULL;
+PFNGLBEGINPROC __glewBegin = NULL;
+PFNGLBINDTEXTUREPROC __glewBindTexture = NULL;
+PFNGLBITMAPPROC __glewBitmap = NULL;
+PFNGLBLENDFUNCPROC __glewBlendFunc = NULL;
+PFNGLCALLLISTPROC __glewCallList = NULL;
+PFNGLCALLLISTSPROC __glewCallLists = NULL;
+PFNGLCLEARPROC __glewClear = NULL;
+PFNGLCLEARACCUMPROC __glewClearAccum = NULL;
+PFNGLCLEARCOLORPROC __glewClearColor = NULL;
+PFNGLCLEARDEPTHPROC __glewClearDepth = NULL;
+PFNGLCLEARINDEXPROC __glewClearIndex = NULL;
+PFNGLCLEARSTENCILPROC __glewClearStencil = NULL;
+PFNGLCLIPPLANEPROC __glewClipPlane = NULL;
+PFNGLCOLOR3BPROC __glewColor3b = NULL;
+PFNGLCOLOR3BVPROC __glewColor3bv = NULL;
+PFNGLCOLOR3DPROC __glewColor3d = NULL;
+PFNGLCOLOR3DVPROC __glewColor3dv = NULL;
+PFNGLCOLOR3FPROC __glewColor3f = NULL;
+PFNGLCOLOR3FVPROC __glewColor3fv = NULL;
+PFNGLCOLOR3IPROC __glewColor3i = NULL;
+PFNGLCOLOR3IVPROC __glewColor3iv = NULL;
+PFNGLCOLOR3SPROC __glewColor3s = NULL;
+PFNGLCOLOR3SVPROC __glewColor3sv = NULL;
+PFNGLCOLOR3UBPROC __glewColor3ub = NULL;
+PFNGLCOLOR3UBVPROC __glewColor3ubv = NULL;
+PFNGLCOLOR3UIPROC __glewColor3ui = NULL;
+PFNGLCOLOR3UIVPROC __glewColor3uiv = NULL;
+PFNGLCOLOR3USPROC __glewColor3us = NULL;
+PFNGLCOLOR3USVPROC __glewColor3usv = NULL;
+PFNGLCOLOR4BPROC __glewColor4b = NULL;
+PFNGLCOLOR4BVPROC __glewColor4bv = NULL;
+PFNGLCOLOR4DPROC __glewColor4d = NULL;
+PFNGLCOLOR4DVPROC __glewColor4dv = NULL;
+PFNGLCOLOR4FPROC __glewColor4f = NULL;
+PFNGLCOLOR4FVPROC __glewColor4fv = NULL;
+PFNGLCOLOR4IPROC __glewColor4i = NULL;
+PFNGLCOLOR4IVPROC __glewColor4iv = NULL;
+PFNGLCOLOR4SPROC __glewColor4s = NULL;
+PFNGLCOLOR4SVPROC __glewColor4sv = NULL;
+PFNGLCOLOR4UBPROC __glewColor4ub = NULL;
+PFNGLCOLOR4UBVPROC __glewColor4ubv = NULL;
+PFNGLCOLOR4UIPROC __glewColor4ui = NULL;
+PFNGLCOLOR4UIVPROC __glewColor4uiv = NULL;
+PFNGLCOLOR4USPROC __glewColor4us = NULL;
+PFNGLCOLOR4USVPROC __glewColor4usv = NULL;
+PFNGLCOLORMASKPROC __glewColorMask = NULL;
+PFNGLCOLORMATERIALPROC __glewColorMaterial = NULL;
+PFNGLCOLORPOINTERPROC __glewColorPointer = NULL;
+PFNGLCOPYPIXELSPROC __glewCopyPixels = NULL;
+PFNGLCOPYTEXIMAGE1DPROC __glewCopyTexImage1D = NULL;
+PFNGLCOPYTEXIMAGE2DPROC __glewCopyTexImage2D = NULL;
+PFNGLCOPYTEXSUBIMAGE1DPROC __glewCopyTexSubImage1D = NULL;
+PFNGLCOPYTEXSUBIMAGE2DPROC __glewCopyTexSubImage2D = NULL;
+PFNGLCULLFACEPROC __glewCullFace = NULL;
+PFNGLDELETELISTSPROC __glewDeleteLists = NULL;
+PFNGLDELETETEXTURESPROC __glewDeleteTextures = NULL;
+PFNGLDEPTHFUNCPROC __glewDepthFunc = NULL;
+PFNGLDEPTHMASKPROC __glewDepthMask = NULL;
+PFNGLDEPTHRANGEPROC __glewDepthRange = NULL;
+PFNGLDISABLEPROC __glewDisable = NULL;
+PFNGLDISABLECLIENTSTATEPROC __glewDisableClientState = NULL;
+PFNGLDRAWARRAYSPROC __glewDrawArrays = NULL;
+PFNGLDRAWBUFFERPROC __glewDrawBuffer = NULL;
+PFNGLDRAWELEMENTSPROC __glewDrawElements = NULL;
+PFNGLDRAWPIXELSPROC __glewDrawPixels = NULL;
+PFNGLEDGEFLAGPROC __glewEdgeFlag = NULL;
+PFNGLEDGEFLAGPOINTERPROC __glewEdgeFlagPointer = NULL;
+PFNGLEDGEFLAGVPROC __glewEdgeFlagv = NULL;
+PFNGLENABLEPROC __glewEnable = NULL;
+PFNGLENABLECLIENTSTATEPROC __glewEnableClientState = NULL;
+PFNGLENDPROC __glewEnd = NULL;
+PFNGLENDLISTPROC __glewEndList = NULL;
+PFNGLEVALCOORD1DPROC __glewEvalCoord1d = NULL;
+PFNGLEVALCOORD1DVPROC __glewEvalCoord1dv = NULL;
+PFNGLEVALCOORD1FPROC __glewEvalCoord1f = NULL;
+PFNGLEVALCOORD1FVPROC __glewEvalCoord1fv = NULL;
+PFNGLEVALCOORD2DPROC __glewEvalCoord2d = NULL;
+PFNGLEVALCOORD2DVPROC __glewEvalCoord2dv = NULL;
+PFNGLEVALCOORD2FPROC __glewEvalCoord2f = NULL;
+PFNGLEVALCOORD2FVPROC __glewEvalCoord2fv = NULL;
+PFNGLEVALMESH1PROC __glewEvalMesh1 = NULL;
+PFNGLEVALMESH2PROC __glewEvalMesh2 = NULL;
+PFNGLEVALPOINT1PROC __glewEvalPoint1 = NULL;
+PFNGLEVALPOINT2PROC __glewEvalPoint2 = NULL;
+PFNGLFEEDBACKBUFFERPROC __glewFeedbackBuffer = NULL;
+PFNGLFINISHPROC __glewFinish = NULL;
+PFNGLFLUSHPROC __glewFlush = NULL;
+PFNGLFOGFPROC __glewFogf = NULL;
+PFNGLFOGFVPROC __glewFogfv = NULL;
+PFNGLFOGIPROC __glewFogi = NULL;
+PFNGLFOGIVPROC __glewFogiv = NULL;
+PFNGLFRONTFACEPROC __glewFrontFace = NULL;
+PFNGLFRUSTUMPROC __glewFrustum = NULL;
+PFNGLGENLISTSPROC __glewGenLists = NULL;
+PFNGLGENTEXTURESPROC __glewGenTextures = NULL;
+PFNGLGETBOOLEANVPROC __glewGetBooleanv = NULL;
+PFNGLGETCLIPPLANEPROC __glewGetClipPlane = NULL;
+PFNGLGETDOUBLEVPROC __glewGetDoublev = NULL;
+PFNGLGETERRORPROC __glewGetError = NULL;
+PFNGLGETFLOATVPROC __glewGetFloatv = NULL;
+PFNGLGETINTEGERVPROC __glewGetIntegerv = NULL;
+PFNGLGETLIGHTFVPROC __glewGetLightfv = NULL;
+PFNGLGETLIGHTIVPROC __glewGetLightiv = NULL;
+PFNGLGETMAPDVPROC __glewGetMapdv = NULL;
+PFNGLGETMAPFVPROC __glewGetMapfv = NULL;
+PFNGLGETMAPIVPROC __glewGetMapiv = NULL;
+PFNGLGETMATERIALFVPROC __glewGetMaterialfv = NULL;
+PFNGLGETMATERIALIVPROC __glewGetMaterialiv = NULL;
+PFNGLGETPIXELMAPFVPROC __glewGetPixelMapfv = NULL;
+PFNGLGETPIXELMAPUIVPROC __glewGetPixelMapuiv = NULL;
+PFNGLGETPIXELMAPUSVPROC __glewGetPixelMapusv = NULL;
+PFNGLGETPOINTERVPROC __glewGetPointerv = NULL;
+PFNGLGETPOLYGONSTIPPLEPROC __glewGetPolygonStipple = NULL;
+PFNGLGETSTRINGPROC __glewGetString = NULL;
+PFNGLGETTEXENVFVPROC __glewGetTexEnvfv = NULL;
+PFNGLGETTEXENVIVPROC __glewGetTexEnviv = NULL;
+PFNGLGETTEXGENDVPROC __glewGetTexGendv = NULL;
+PFNGLGETTEXGENFVPROC __glewGetTexGenfv = NULL;
+PFNGLGETTEXGENIVPROC __glewGetTexGeniv = NULL;
+PFNGLGETTEXIMAGEPROC __glewGetTexImage = NULL;
+PFNGLGETTEXLEVELPARAMETERFVPROC __glewGetTexLevelParameterfv = NULL;
+PFNGLGETTEXLEVELPARAMETERIVPROC __glewGetTexLevelParameteriv = NULL;
+PFNGLGETTEXPARAMETERFVPROC __glewGetTexParameterfv = NULL;
+PFNGLGETTEXPARAMETERIVPROC __glewGetTexParameteriv = NULL;
+PFNGLHINTPROC __glewHint = NULL;
+PFNGLINDEXMASKPROC __glewIndexMask = NULL;
+PFNGLINDEXPOINTERPROC __glewIndexPointer = NULL;
+PFNGLINDEXDPROC __glewIndexd = NULL;
+PFNGLINDEXDVPROC __glewIndexdv = NULL;
+PFNGLINDEXFPROC __glewIndexf = NULL;
+PFNGLINDEXFVPROC __glewIndexfv = NULL;
+PFNGLINDEXIPROC __glewIndexi = NULL;
+PFNGLINDEXIVPROC __glewIndexiv = NULL;
+PFNGLINDEXSPROC __glewIndexs = NULL;
+PFNGLINDEXSVPROC __glewIndexsv = NULL;
+PFNGLINDEXUBPROC __glewIndexub = NULL;
+PFNGLINDEXUBVPROC __glewIndexubv = NULL;
+PFNGLINITNAMESPROC __glewInitNames = NULL;
+PFNGLINTERLEAVEDARRAYSPROC __glewInterleavedArrays = NULL;
+PFNGLISENABLEDPROC __glewIsEnabled = NULL;
+PFNGLISLISTPROC __glewIsList = NULL;
+PFNGLISTEXTUREPROC __glewIsTexture = NULL;
+PFNGLLIGHTMODELFPROC __glewLightModelf = NULL;
+PFNGLLIGHTMODELFVPROC __glewLightModelfv = NULL;
+PFNGLLIGHTMODELIPROC __glewLightModeli = NULL;
+PFNGLLIGHTMODELIVPROC __glewLightModeliv = NULL;
+PFNGLLIGHTFPROC __glewLightf = NULL;
+PFNGLLIGHTFVPROC __glewLightfv = NULL;
+PFNGLLIGHTIPROC __glewLighti = NULL;
+PFNGLLIGHTIVPROC __glewLightiv = NULL;
+PFNGLLINESTIPPLEPROC __glewLineStipple = NULL;
+PFNGLLINEWIDTHPROC __glewLineWidth = NULL;
+PFNGLLISTBASEPROC __glewListBase = NULL;
+PFNGLLOADIDENTITYPROC __glewLoadIdentity = NULL;
+PFNGLLOADMATRIXDPROC __glewLoadMatrixd = NULL;
+PFNGLLOADMATRIXFPROC __glewLoadMatrixf = NULL;
+PFNGLLOADNAMEPROC __glewLoadName = NULL;
+PFNGLLOGICOPPROC __glewLogicOp = NULL;
+PFNGLMAP1DPROC __glewMap1d = NULL;
+PFNGLMAP1FPROC __glewMap1f = NULL;
+PFNGLMAP2DPROC __glewMap2d = NULL;
+PFNGLMAP2FPROC __glewMap2f = NULL;
+PFNGLMAPGRID1DPROC __glewMapGrid1d = NULL;
+PFNGLMAPGRID1FPROC __glewMapGrid1f = NULL;
+PFNGLMAPGRID2DPROC __glewMapGrid2d = NULL;
+PFNGLMAPGRID2FPROC __glewMapGrid2f = NULL;
+PFNGLMATERIALFPROC __glewMaterialf = NULL;
+PFNGLMATERIALFVPROC __glewMaterialfv = NULL;
+PFNGLMATERIALIPROC __glewMateriali = NULL;
+PFNGLMATERIALIVPROC __glewMaterialiv = NULL;
+PFNGLMATRIXMODEPROC __glewMatrixMode = NULL;
+PFNGLMULTMATRIXDPROC __glewMultMatrixd = NULL;
+PFNGLMULTMATRIXFPROC __glewMultMatrixf = NULL;
+PFNGLNEWLISTPROC __glewNewList = NULL;
+PFNGLNORMAL3BPROC __glewNormal3b = NULL;
+PFNGLNORMAL3BVPROC __glewNormal3bv = NULL;
+PFNGLNORMAL3DPROC __glewNormal3d = NULL;
+PFNGLNORMAL3DVPROC __glewNormal3dv = NULL;
+PFNGLNORMAL3FPROC __glewNormal3f = NULL;
+PFNGLNORMAL3FVPROC __glewNormal3fv = NULL;
+PFNGLNORMAL3IPROC __glewNormal3i = NULL;
+PFNGLNORMAL3IVPROC __glewNormal3iv = NULL;
+PFNGLNORMAL3SPROC __glewNormal3s = NULL;
+PFNGLNORMAL3SVPROC __glewNormal3sv = NULL;
+PFNGLNORMALPOINTERPROC __glewNormalPointer = NULL;
+PFNGLORTHOPROC __glewOrtho = NULL;
+PFNGLPASSTHROUGHPROC __glewPassThrough = NULL;
+PFNGLPIXELMAPFVPROC __glewPixelMapfv = NULL;
+PFNGLPIXELMAPUIVPROC __glewPixelMapuiv = NULL;
+PFNGLPIXELMAPUSVPROC __glewPixelMapusv = NULL;
+PFNGLPIXELSTOREFPROC __glewPixelStoref = NULL;
+PFNGLPIXELSTOREIPROC __glewPixelStorei = NULL;
+PFNGLPIXELTRANSFERFPROC __glewPixelTransferf = NULL;
+PFNGLPIXELTRANSFERIPROC __glewPixelTransferi = NULL;
+PFNGLPIXELZOOMPROC __glewPixelZoom = NULL;
+PFNGLPOINTSIZEPROC __glewPointSize = NULL;
+PFNGLPOLYGONMODEPROC __glewPolygonMode = NULL;
+PFNGLPOLYGONOFFSETPROC __glewPolygonOffset = NULL;
+PFNGLPOLYGONSTIPPLEPROC __glewPolygonStipple = NULL;
+PFNGLPOPATTRIBPROC __glewPopAttrib = NULL;
+PFNGLPOPCLIENTATTRIBPROC __glewPopClientAttrib = NULL;
+PFNGLPOPMATRIXPROC __glewPopMatrix = NULL;
+PFNGLPOPNAMEPROC __glewPopName = NULL;
+PFNGLPRIORITIZETEXTURESPROC __glewPrioritizeTextures = NULL;
+PFNGLPUSHATTRIBPROC __glewPushAttrib = NULL;
+PFNGLPUSHCLIENTATTRIBPROC __glewPushClientAttrib = NULL;
+PFNGLPUSHMATRIXPROC __glewPushMatrix = NULL;
+PFNGLPUSHNAMEPROC __glewPushName = NULL;
+PFNGLRASTERPOS2DPROC __glewRasterPos2d = NULL;
+PFNGLRASTERPOS2DVPROC __glewRasterPos2dv = NULL;
+PFNGLRASTERPOS2FPROC __glewRasterPos2f = NULL;
+PFNGLRASTERPOS2FVPROC __glewRasterPos2fv = NULL;
+PFNGLRASTERPOS2IPROC __glewRasterPos2i = NULL;
+PFNGLRASTERPOS2IVPROC __glewRasterPos2iv = NULL;
+PFNGLRASTERPOS2SPROC __glewRasterPos2s = NULL;
+PFNGLRASTERPOS2SVPROC __glewRasterPos2sv = NULL;
+PFNGLRASTERPOS3DPROC __glewRasterPos3d = NULL;
+PFNGLRASTERPOS3DVPROC __glewRasterPos3dv = NULL;
+PFNGLRASTERPOS3FPROC __glewRasterPos3f = NULL;
+PFNGLRASTERPOS3FVPROC __glewRasterPos3fv = NULL;
+PFNGLRASTERPOS3IPROC __glewRasterPos3i = NULL;
+PFNGLRASTERPOS3IVPROC __glewRasterPos3iv = NULL;
+PFNGLRASTERPOS3SPROC __glewRasterPos3s = NULL;
+PFNGLRASTERPOS3SVPROC __glewRasterPos3sv = NULL;
+PFNGLRASTERPOS4DPROC __glewRasterPos4d = NULL;
+PFNGLRASTERPOS4DVPROC __glewRasterPos4dv = NULL;
+PFNGLRASTERPOS4FPROC __glewRasterPos4f = NULL;
+PFNGLRASTERPOS4FVPROC __glewRasterPos4fv = NULL;
+PFNGLRASTERPOS4IPROC __glewRasterPos4i = NULL;
+PFNGLRASTERPOS4IVPROC __glewRasterPos4iv = NULL;
+PFNGLRASTERPOS4SPROC __glewRasterPos4s = NULL;
+PFNGLRASTERPOS4SVPROC __glewRasterPos4sv = NULL;
+PFNGLREADBUFFERPROC __glewReadBuffer = NULL;
+PFNGLREADPIXELSPROC __glewReadPixels = NULL;
+PFNGLRECTDPROC __glewRectd = NULL;
+PFNGLRECTDVPROC __glewRectdv = NULL;
+PFNGLRECTFPROC __glewRectf = NULL;
+PFNGLRECTFVPROC __glewRectfv = NULL;
+PFNGLRECTIPROC __glewRecti = NULL;
+PFNGLRECTIVPROC __glewRectiv = NULL;
+PFNGLRECTSPROC __glewRects = NULL;
+PFNGLRECTSVPROC __glewRectsv = NULL;
+PFNGLRENDERMODEPROC __glewRenderMode = NULL;
+PFNGLROTATEDPROC __glewRotated = NULL;
+PFNGLROTATEFPROC __glewRotatef = NULL;
+PFNGLSCALEDPROC __glewScaled = NULL;
+PFNGLSCALEFPROC __glewScalef = NULL;
+PFNGLSCISSORPROC __glewScissor = NULL;
+PFNGLSELECTBUFFERPROC __glewSelectBuffer = NULL;
+PFNGLSHADEMODELPROC __glewShadeModel = NULL;
+PFNGLSTENCILFUNCPROC __glewStencilFunc = NULL;
+PFNGLSTENCILMASKPROC __glewStencilMask = NULL;
+PFNGLSTENCILOPPROC __glewStencilOp = NULL;
+PFNGLTEXCOORD1DPROC __glewTexCoord1d = NULL;
+PFNGLTEXCOORD1DVPROC __glewTexCoord1dv = NULL;
+PFNGLTEXCOORD1FPROC __glewTexCoord1f = NULL;
+PFNGLTEXCOORD1FVPROC __glewTexCoord1fv = NULL;
+PFNGLTEXCOORD1IPROC __glewTexCoord1i = NULL;
+PFNGLTEXCOORD1IVPROC __glewTexCoord1iv = NULL;
+PFNGLTEXCOORD1SPROC __glewTexCoord1s = NULL;
+PFNGLTEXCOORD1SVPROC __glewTexCoord1sv = NULL;
+PFNGLTEXCOORD2DPROC __glewTexCoord2d = NULL;
+PFNGLTEXCOORD2DVPROC __glewTexCoord2dv = NULL;
+PFNGLTEXCOORD2FPROC __glewTexCoord2f = NULL;
+PFNGLTEXCOORD2FVPROC __glewTexCoord2fv = NULL;
+PFNGLTEXCOORD2IPROC __glewTexCoord2i = NULL;
+PFNGLTEXCOORD2IVPROC __glewTexCoord2iv = NULL;
+PFNGLTEXCOORD2SPROC __glewTexCoord2s = NULL;
+PFNGLTEXCOORD2SVPROC __glewTexCoord2sv = NULL;
+PFNGLTEXCOORD3DPROC __glewTexCoord3d = NULL;
+PFNGLTEXCOORD3DVPROC __glewTexCoord3dv = NULL;
+PFNGLTEXCOORD3FPROC __glewTexCoord3f = NULL;
+PFNGLTEXCOORD3FVPROC __glewTexCoord3fv = NULL;
+PFNGLTEXCOORD3IPROC __glewTexCoord3i = NULL;
+PFNGLTEXCOORD3IVPROC __glewTexCoord3iv = NULL;
+PFNGLTEXCOORD3SPROC __glewTexCoord3s = NULL;
+PFNGLTEXCOORD3SVPROC __glewTexCoord3sv = NULL;
+PFNGLTEXCOORD4DPROC __glewTexCoord4d = NULL;
+PFNGLTEXCOORD4DVPROC __glewTexCoord4dv = NULL;
+PFNGLTEXCOORD4FPROC __glewTexCoord4f = NULL;
+PFNGLTEXCOORD4FVPROC __glewTexCoord4fv = NULL;
+PFNGLTEXCOORD4IPROC __glewTexCoord4i = NULL;
+PFNGLTEXCOORD4IVPROC __glewTexCoord4iv = NULL;
+PFNGLTEXCOORD4SPROC __glewTexCoord4s = NULL;
+PFNGLTEXCOORD4SVPROC __glewTexCoord4sv = NULL;
+PFNGLTEXCOORDPOINTERPROC __glewTexCoordPointer = NULL;
+PFNGLTEXENVFPROC __glewTexEnvf = NULL;
+PFNGLTEXENVFVPROC __glewTexEnvfv = NULL;
+PFNGLTEXENVIPROC __glewTexEnvi = NULL;
+PFNGLTEXENVIVPROC __glewTexEnviv = NULL;
+PFNGLTEXGENDPROC __glewTexGend = NULL;
+PFNGLTEXGENDVPROC __glewTexGendv = NULL;
+PFNGLTEXGENFPROC __glewTexGenf = NULL;
+PFNGLTEXGENFVPROC __glewTexGenfv = NULL;
+PFNGLTEXGENIPROC __glewTexGeni = NULL;
+PFNGLTEXGENIVPROC __glewTexGeniv = NULL;
+PFNGLTEXIMAGE1DPROC __glewTexImage1D = NULL;
+PFNGLTEXIMAGE2DPROC __glewTexImage2D = NULL;
+PFNGLTEXPARAMETERFPROC __glewTexParameterf = NULL;
+PFNGLTEXPARAMETERFVPROC __glewTexParameterfv = NULL;
+PFNGLTEXPARAMETERIPROC __glewTexParameteri = NULL;
+PFNGLTEXPARAMETERIVPROC __glewTexParameteriv = NULL;
+PFNGLTEXSUBIMAGE1DPROC __glewTexSubImage1D = NULL;
+PFNGLTEXSUBIMAGE2DPROC __glewTexSubImage2D = NULL;
+PFNGLTRANSLATEDPROC __glewTranslated = NULL;
+PFNGLTRANSLATEFPROC __glewTranslatef = NULL;
+PFNGLVERTEX2DPROC __glewVertex2d = NULL;
+PFNGLVERTEX2DVPROC __glewVertex2dv = NULL;
+PFNGLVERTEX2FPROC __glewVertex2f = NULL;
+PFNGLVERTEX2FVPROC __glewVertex2fv = NULL;
+PFNGLVERTEX2IPROC __glewVertex2i = NULL;
+PFNGLVERTEX2IVPROC __glewVertex2iv = NULL;
+PFNGLVERTEX2SPROC __glewVertex2s = NULL;
+PFNGLVERTEX2SVPROC __glewVertex2sv = NULL;
+PFNGLVERTEX3DPROC __glewVertex3d = NULL;
+PFNGLVERTEX3DVPROC __glewVertex3dv = NULL;
+PFNGLVERTEX3FPROC __glewVertex3f = NULL;
+PFNGLVERTEX3FVPROC __glewVertex3fv = NULL;
+PFNGLVERTEX3IPROC __glewVertex3i = NULL;
+PFNGLVERTEX3IVPROC __glewVertex3iv = NULL;
+PFNGLVERTEX3SPROC __glewVertex3s = NULL;
+PFNGLVERTEX3SVPROC __glewVertex3sv = NULL;
+PFNGLVERTEX4DPROC __glewVertex4d = NULL;
+PFNGLVERTEX4DVPROC __glewVertex4dv = NULL;
+PFNGLVERTEX4FPROC __glewVertex4f = NULL;
+PFNGLVERTEX4FVPROC __glewVertex4fv = NULL;
+PFNGLVERTEX4IPROC __glewVertex4i = NULL;
+PFNGLVERTEX4IVPROC __glewVertex4iv = NULL;
+PFNGLVERTEX4SPROC __glewVertex4s = NULL;
+PFNGLVERTEX4SVPROC __glewVertex4sv = NULL;
+PFNGLVERTEXPOINTERPROC __glewVertexPointer = NULL;
+PFNGLVIEWPORTPROC __glewViewport = NULL;
+
+#define fqn_from_convention(convention, fqn) \
+ (const GLubyte*)fqn
+
+GLboolean GLEWAPIENTRY glewOpenGL11Init(void)
+{
+ GLboolean r = GL_FALSE;
+
+ r = ((glAccum = (PFNGLACCUMPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glAccum"))) == NULL) || r;
+ r = ((glAlphaFunc = (PFNGLALPHAFUNCPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glAlphaFunc"))) == NULL) || r;
+ r = ((glAreTexturesResident = (PFNGLARETEXTURESRESIDENTPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glAreTexturesResident"))) == NULL) || r;
+ r = ((glArrayElement = (PFNGLARRAYELEMENTPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glArrayElement"))) == NULL) || r;
+ r = ((glBegin = (PFNGLBEGINPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glBegin"))) == NULL) || r;
+ r = ((glBindTexture = (PFNGLBINDTEXTUREPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glBindTexture"))) == NULL) || r;
+ r = ((glBitmap = (PFNGLBITMAPPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glBitmap"))) == NULL) || r;
+ r = ((glBlendFunc = (PFNGLBLENDFUNCPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glBlendFunc"))) == NULL) || r;
+ r = ((glCallList = (PFNGLCALLLISTPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glCallList"))) == NULL) || r;
+ r = ((glCallLists = (PFNGLCALLLISTSPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glCallLists"))) == NULL) || r;
+ r = ((glClear = (PFNGLCLEARPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glClear"))) == NULL) || r;
+ r = ((glClearAccum = (PFNGLCLEARACCUMPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glClearAccum"))) == NULL) || r;
+ r = ((glClearColor = (PFNGLCLEARCOLORPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glClearColor"))) == NULL) || r;
+ r = ((glClearDepth = (PFNGLCLEARDEPTHPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glClearDepth"))) == NULL) || r;
+ r = ((glClearIndex = (PFNGLCLEARINDEXPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glClearIndex"))) == NULL) || r;
+ r = ((glClearStencil = (PFNGLCLEARSTENCILPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glClearStencil"))) == NULL) || r;
+ r = ((glClipPlane = (PFNGLCLIPPLANEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glClipPlane"))) == NULL) || r;
+ r = ((glColor3b = (PFNGLCOLOR3BPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3b"))) == NULL) || r;
+ r = ((glColor3bv = (PFNGLCOLOR3BVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3bv"))) == NULL) || r;
+ r = ((glColor3d = (PFNGLCOLOR3DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3d"))) == NULL) || r;
+ r = ((glColor3dv = (PFNGLCOLOR3DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3dv"))) == NULL) || r;
+ r = ((glColor3f = (PFNGLCOLOR3FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3f"))) == NULL) || r;
+ r = ((glColor3fv = (PFNGLCOLOR3FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3fv"))) == NULL) || r;
+ r = ((glColor3i = (PFNGLCOLOR3IPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3i"))) == NULL) || r;
+ r = ((glColor3iv = (PFNGLCOLOR3IVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3iv"))) == NULL) || r;
+ r = ((glColor3s = (PFNGLCOLOR3SPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3s"))) == NULL) || r;
+ r = ((glColor3sv = (PFNGLCOLOR3SVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3sv"))) == NULL) || r;
+ r = ((glColor3ub = (PFNGLCOLOR3UBPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3ub"))) == NULL) || r;
+ r = ((glColor3ubv = (PFNGLCOLOR3UBVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3ubv"))) == NULL) || r;
+ r = ((glColor3ui = (PFNGLCOLOR3UIPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3ui"))) == NULL) || r;
+ r = ((glColor3uiv = (PFNGLCOLOR3UIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3uiv"))) == NULL) || r;
+ r = ((glColor3us = (PFNGLCOLOR3USPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3us"))) == NULL) || r;
+ r = ((glColor3usv = (PFNGLCOLOR3USVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor3usv"))) == NULL) || r;
+ r = ((glColor4b = (PFNGLCOLOR4BPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4b"))) == NULL) || r;
+ r = ((glColor4bv = (PFNGLCOLOR4BVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4bv"))) == NULL) || r;
+ r = ((glColor4d = (PFNGLCOLOR4DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4d"))) == NULL) || r;
+ r = ((glColor4dv = (PFNGLCOLOR4DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4dv"))) == NULL) || r;
+ r = ((glColor4f = (PFNGLCOLOR4FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4f"))) == NULL) || r;
+ r = ((glColor4fv = (PFNGLCOLOR4FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4fv"))) == NULL) || r;
+ r = ((glColor4i = (PFNGLCOLOR4IPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4i"))) == NULL) || r;
+ r = ((glColor4iv = (PFNGLCOLOR4IVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4iv"))) == NULL) || r;
+ r = ((glColor4s = (PFNGLCOLOR4SPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4s"))) == NULL) || r;
+ r = ((glColor4sv = (PFNGLCOLOR4SVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4sv"))) == NULL) || r;
+ r = ((glColor4ub = (PFNGLCOLOR4UBPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4ub"))) == NULL) || r;
+ r = ((glColor4ubv = (PFNGLCOLOR4UBVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4ubv"))) == NULL) || r;
+ r = ((glColor4ui = (PFNGLCOLOR4UIPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4ui"))) == NULL) || r;
+ r = ((glColor4uiv = (PFNGLCOLOR4UIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4uiv"))) == NULL) || r;
+ r = ((glColor4us = (PFNGLCOLOR4USPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4us"))) == NULL) || r;
+ r = ((glColor4usv = (PFNGLCOLOR4USVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColor4usv"))) == NULL) || r;
+ r = ((glColorMask = (PFNGLCOLORMASKPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColorMask"))) == NULL) || r;
+ r = ((glColorMaterial = (PFNGLCOLORMATERIALPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColorMaterial"))) == NULL) || r;
+ r = ((glColorPointer = (PFNGLCOLORPOINTERPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glColorPointer"))) == NULL) || r;
+ r = ((glCopyPixels = (PFNGLCOPYPIXELSPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glCopyPixels"))) == NULL) || r;
+ r = ((glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glCopyTexImage1D"))) == NULL) || r;
+ r = ((glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glCopyTexImage2D"))) == NULL) || r;
+ r = ((glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glCopyTexSubImage1D"))) == NULL) || r;
+ r = ((glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glCopyTexSubImage2D"))) == NULL) || r;
+ r = ((glCullFace = (PFNGLCULLFACEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glCullFace"))) == NULL) || r;
+ r = ((glDeleteLists = (PFNGLDELETELISTSPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glDeleteLists"))) == NULL) || r;
+ r = ((glDeleteTextures = (PFNGLDELETETEXTURESPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glDeleteTextures"))) == NULL) || r;
+ r = ((glDepthFunc = (PFNGLDEPTHFUNCPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glDepthFunc"))) == NULL) || r;
+ r = ((glDepthMask = (PFNGLDEPTHMASKPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glDepthMask"))) == NULL) || r;
+ r = ((glDepthRange = (PFNGLDEPTHRANGEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glDepthRange"))) == NULL) || r;
+ r = ((glDisable = (PFNGLDISABLEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glDisable"))) == NULL) || r;
+ r = ((glDisableClientState = (PFNGLDISABLECLIENTSTATEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glDisableClientState"))) == NULL) || r;
+ r = ((glDrawArrays = (PFNGLDRAWARRAYSPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glDrawArrays"))) == NULL) || r;
+ r = ((glDrawBuffer = (PFNGLDRAWBUFFERPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glDrawBuffer"))) == NULL) || r;
+ r = ((glDrawElements = (PFNGLDRAWELEMENTSPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glDrawElements"))) == NULL) || r;
+ r = ((glDrawPixels = (PFNGLDRAWPIXELSPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glDrawPixels"))) == NULL) || r;
+ r = ((glEdgeFlag = (PFNGLEDGEFLAGPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEdgeFlag"))) == NULL) || r;
+ r = ((glEdgeFlagPointer = (PFNGLEDGEFLAGPOINTERPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEdgeFlagPointer"))) == NULL) || r;
+ r = ((glEdgeFlagv = (PFNGLEDGEFLAGVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEdgeFlagv"))) == NULL) || r;
+ r = ((glEnable = (PFNGLENABLEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEnable"))) == NULL) || r;
+ r = ((glEnableClientState = (PFNGLENABLECLIENTSTATEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEnableClientState"))) == NULL) || r;
+ r = ((glEnd = (PFNGLENDPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEnd"))) == NULL) || r;
+ r = ((glEndList = (PFNGLENDLISTPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEndList"))) == NULL) || r;
+ r = ((glEvalCoord1d = (PFNGLEVALCOORD1DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEvalCoord1d"))) == NULL) || r;
+ r = ((glEvalCoord1dv = (PFNGLEVALCOORD1DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEvalCoord1dv"))) == NULL) || r;
+ r = ((glEvalCoord1f = (PFNGLEVALCOORD1FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEvalCoord1f"))) == NULL) || r;
+ r = ((glEvalCoord1fv = (PFNGLEVALCOORD1FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEvalCoord1fv"))) == NULL) || r;
+ r = ((glEvalCoord2d = (PFNGLEVALCOORD2DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEvalCoord2d"))) == NULL) || r;
+ r = ((glEvalCoord2dv = (PFNGLEVALCOORD2DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEvalCoord2dv"))) == NULL) || r;
+ r = ((glEvalCoord2f = (PFNGLEVALCOORD2FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEvalCoord2f"))) == NULL) || r;
+ r = ((glEvalCoord2fv = (PFNGLEVALCOORD2FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEvalCoord2fv"))) == NULL) || r;
+ r = ((glEvalMesh1 = (PFNGLEVALMESH1PROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEvalMesh1"))) == NULL) || r;
+ r = ((glEvalMesh2 = (PFNGLEVALMESH2PROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEvalMesh2"))) == NULL) || r;
+ r = ((glEvalPoint1 = (PFNGLEVALPOINT1PROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEvalPoint1"))) == NULL) || r;
+ r = ((glEvalPoint2 = (PFNGLEVALPOINT2PROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glEvalPoint2"))) == NULL) || r;
+ r = ((glFeedbackBuffer = (PFNGLFEEDBACKBUFFERPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glFeedbackBuffer"))) == NULL) || r;
+ r = ((glFinish = (PFNGLFINISHPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glFinish"))) == NULL) || r;
+ r = ((glFlush = (PFNGLFLUSHPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glFlush"))) == NULL) || r;
+ r = ((glFogf = (PFNGLFOGFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glFogf"))) == NULL) || r;
+ r = ((glFogfv = (PFNGLFOGFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glFogfv"))) == NULL) || r;
+ r = ((glFogi = (PFNGLFOGIPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glFogi"))) == NULL) || r;
+ r = ((glFogiv = (PFNGLFOGIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glFogiv"))) == NULL) || r;
+ r = ((glFrontFace = (PFNGLFRONTFACEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glFrontFace"))) == NULL) || r;
+ r = ((glFrustum = (PFNGLFRUSTUMPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glFrustum"))) == NULL) || r;
+ r = ((glGenLists = (PFNGLGENLISTSPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGenLists"))) == NULL) || r;
+ r = ((glGenTextures = (PFNGLGENTEXTURESPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGenTextures"))) == NULL) || r;
+ r = ((glGetBooleanv = (PFNGLGETBOOLEANVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetBooleanv"))) == NULL) || r;
+ r = ((glGetClipPlane = (PFNGLGETCLIPPLANEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetClipPlane"))) == NULL) || r;
+ r = ((glGetDoublev = (PFNGLGETDOUBLEVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetDoublev"))) == NULL) || r;
+ r = ((glGetError = (PFNGLGETERRORPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetError"))) == NULL) || r;
+ r = ((glGetFloatv = (PFNGLGETFLOATVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetFloatv"))) == NULL) || r;
+ r = ((glGetIntegerv = (PFNGLGETINTEGERVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetIntegerv"))) == NULL) || r;
+ r = ((glGetLightfv = (PFNGLGETLIGHTFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetLightfv"))) == NULL) || r;
+ r = ((glGetLightiv = (PFNGLGETLIGHTIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetLightiv"))) == NULL) || r;
+ r = ((glGetMapdv = (PFNGLGETMAPDVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetMapdv"))) == NULL) || r;
+ r = ((glGetMapfv = (PFNGLGETMAPFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetMapfv"))) == NULL) || r;
+ r = ((glGetMapiv = (PFNGLGETMAPIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetMapiv"))) == NULL) || r;
+ r = ((glGetMaterialfv = (PFNGLGETMATERIALFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetMaterialfv"))) == NULL) || r;
+ r = ((glGetMaterialiv = (PFNGLGETMATERIALIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetMaterialiv"))) == NULL) || r;
+ r = ((glGetPixelMapfv = (PFNGLGETPIXELMAPFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetPixelMapfv"))) == NULL) || r;
+ r = ((glGetPixelMapuiv = (PFNGLGETPIXELMAPUIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetPixelMapuiv"))) == NULL) || r;
+ r = ((glGetPixelMapusv = (PFNGLGETPIXELMAPUSVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetPixelMapusv"))) == NULL) || r;
+ r = ((glGetPointerv = (PFNGLGETPOINTERVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetPointerv"))) == NULL) || r;
+ r = ((glGetPolygonStipple = (PFNGLGETPOLYGONSTIPPLEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetPolygonStipple"))) == NULL) || r;
+ r = ((glGetString = (PFNGLGETSTRINGPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetString"))) == NULL) || r;
+ r = ((glGetTexEnvfv = (PFNGLGETTEXENVFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetTexEnvfv"))) == NULL) || r;
+ r = ((glGetTexEnviv = (PFNGLGETTEXENVIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetTexEnviv"))) == NULL) || r;
+ r = ((glGetTexGendv = (PFNGLGETTEXGENDVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetTexGendv"))) == NULL) || r;
+ r = ((glGetTexGenfv = (PFNGLGETTEXGENFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetTexGenfv"))) == NULL) || r;
+ r = ((glGetTexGeniv = (PFNGLGETTEXGENIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetTexGeniv"))) == NULL) || r;
+ r = ((glGetTexImage = (PFNGLGETTEXIMAGEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetTexImage"))) == NULL) || r;
+ r = ((glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetTexLevelParameterfv"))) == NULL) || r;
+ r = ((glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetTexLevelParameteriv"))) == NULL) || r;
+ r = ((glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetTexParameterfv"))) == NULL) || r;
+ r = ((glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glGetTexParameteriv"))) == NULL) || r;
+ r = ((glHint = (PFNGLHINTPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glHint"))) == NULL) || r;
+ r = ((glIndexMask = (PFNGLINDEXMASKPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIndexMask"))) == NULL) || r;
+ r = ((glIndexPointer = (PFNGLINDEXPOINTERPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIndexPointer"))) == NULL) || r;
+ r = ((glIndexd = (PFNGLINDEXDPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIndexd"))) == NULL) || r;
+ r = ((glIndexdv = (PFNGLINDEXDVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIndexdv"))) == NULL) || r;
+ r = ((glIndexf = (PFNGLINDEXFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIndexf"))) == NULL) || r;
+ r = ((glIndexfv = (PFNGLINDEXFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIndexfv"))) == NULL) || r;
+ r = ((glIndexi = (PFNGLINDEXIPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIndexi"))) == NULL) || r;
+ r = ((glIndexiv = (PFNGLINDEXIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIndexiv"))) == NULL) || r;
+ r = ((glIndexs = (PFNGLINDEXSPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIndexs"))) == NULL) || r;
+ r = ((glIndexsv = (PFNGLINDEXSVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIndexsv"))) == NULL) || r;
+ r = ((glIndexub = (PFNGLINDEXUBPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIndexub"))) == NULL) || r;
+ r = ((glIndexubv = (PFNGLINDEXUBVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIndexubv"))) == NULL) || r;
+ r = ((glInitNames = (PFNGLINITNAMESPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glInitNames"))) == NULL) || r;
+ r = ((glInterleavedArrays = (PFNGLINTERLEAVEDARRAYSPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glInterleavedArrays"))) == NULL) || r;
+ r = ((glIsEnabled = (PFNGLISENABLEDPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIsEnabled"))) == NULL) || r;
+ r = ((glIsList = (PFNGLISLISTPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIsList"))) == NULL) || r;
+ r = ((glIsTexture = (PFNGLISTEXTUREPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glIsTexture"))) == NULL) || r;
+ r = ((glLightModelf = (PFNGLLIGHTMODELFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLightModelf"))) == NULL) || r;
+ r = ((glLightModelfv = (PFNGLLIGHTMODELFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLightModelfv"))) == NULL) || r;
+ r = ((glLightModeli = (PFNGLLIGHTMODELIPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLightModeli"))) == NULL) || r;
+ r = ((glLightModeliv = (PFNGLLIGHTMODELIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLightModeliv"))) == NULL) || r;
+ r = ((glLightf = (PFNGLLIGHTFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLightf"))) == NULL) || r;
+ r = ((glLightfv = (PFNGLLIGHTFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLightfv"))) == NULL) || r;
+ r = ((glLighti = (PFNGLLIGHTIPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLighti"))) == NULL) || r;
+ r = ((glLightiv = (PFNGLLIGHTIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLightiv"))) == NULL) || r;
+ r = ((glLineStipple = (PFNGLLINESTIPPLEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLineStipple"))) == NULL) || r;
+ r = ((glLineWidth = (PFNGLLINEWIDTHPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLineWidth"))) == NULL) || r;
+ r = ((glListBase = (PFNGLLISTBASEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glListBase"))) == NULL) || r;
+ r = ((glLoadIdentity = (PFNGLLOADIDENTITYPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLoadIdentity"))) == NULL) || r;
+ r = ((glLoadMatrixd = (PFNGLLOADMATRIXDPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLoadMatrixd"))) == NULL) || r;
+ r = ((glLoadMatrixf = (PFNGLLOADMATRIXFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLoadMatrixf"))) == NULL) || r;
+ r = ((glLoadName = (PFNGLLOADNAMEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLoadName"))) == NULL) || r;
+ r = ((glLogicOp = (PFNGLLOGICOPPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glLogicOp"))) == NULL) || r;
+ r = ((glMap1d = (PFNGLMAP1DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMap1d"))) == NULL) || r;
+ r = ((glMap1f = (PFNGLMAP1FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMap1f"))) == NULL) || r;
+ r = ((glMap2d = (PFNGLMAP2DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMap2d"))) == NULL) || r;
+ r = ((glMap2f = (PFNGLMAP2FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMap2f"))) == NULL) || r;
+ r = ((glMapGrid1d = (PFNGLMAPGRID1DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMapGrid1d"))) == NULL) || r;
+ r = ((glMapGrid1f = (PFNGLMAPGRID1FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMapGrid1f"))) == NULL) || r;
+ r = ((glMapGrid2d = (PFNGLMAPGRID2DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMapGrid2d"))) == NULL) || r;
+ r = ((glMapGrid2f = (PFNGLMAPGRID2FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMapGrid2f"))) == NULL) || r;
+ r = ((glMaterialf = (PFNGLMATERIALFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMaterialf"))) == NULL) || r;
+ r = ((glMaterialfv = (PFNGLMATERIALFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMaterialfv"))) == NULL) || r;
+ r = ((glMateriali = (PFNGLMATERIALIPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMateriali"))) == NULL) || r;
+ r = ((glMaterialiv = (PFNGLMATERIALIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMaterialiv"))) == NULL) || r;
+ r = ((glMatrixMode = (PFNGLMATRIXMODEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMatrixMode"))) == NULL) || r;
+ r = ((glMultMatrixd = (PFNGLMULTMATRIXDPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMultMatrixd"))) == NULL) || r;
+ r = ((glMultMatrixf = (PFNGLMULTMATRIXFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glMultMatrixf"))) == NULL) || r;
+ r = ((glNewList = (PFNGLNEWLISTPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glNewList"))) == NULL) || r;
+ r = ((glNormal3b = (PFNGLNORMAL3BPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glNormal3b"))) == NULL) || r;
+ r = ((glNormal3bv = (PFNGLNORMAL3BVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glNormal3bv"))) == NULL) || r;
+ r = ((glNormal3d = (PFNGLNORMAL3DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glNormal3d"))) == NULL) || r;
+ r = ((glNormal3dv = (PFNGLNORMAL3DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glNormal3dv"))) == NULL) || r;
+ r = ((glNormal3f = (PFNGLNORMAL3FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glNormal3f"))) == NULL) || r;
+ r = ((glNormal3fv = (PFNGLNORMAL3FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glNormal3fv"))) == NULL) || r;
+ r = ((glNormal3i = (PFNGLNORMAL3IPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glNormal3i"))) == NULL) || r;
+ r = ((glNormal3iv = (PFNGLNORMAL3IVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glNormal3iv"))) == NULL) || r;
+ r = ((glNormal3s = (PFNGLNORMAL3SPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glNormal3s"))) == NULL) || r;
+ r = ((glNormal3sv = (PFNGLNORMAL3SVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glNormal3sv"))) == NULL) || r;
+ r = ((glNormalPointer = (PFNGLNORMALPOINTERPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glNormalPointer"))) == NULL) || r;
+ r = ((glOrtho = (PFNGLORTHOPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glOrtho"))) == NULL) || r;
+ r = ((glPassThrough = (PFNGLPASSTHROUGHPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPassThrough"))) == NULL) || r;
+ r = ((glPixelMapfv = (PFNGLPIXELMAPFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPixelMapfv"))) == NULL) || r;
+ r = ((glPixelMapuiv = (PFNGLPIXELMAPUIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPixelMapuiv"))) == NULL) || r;
+ r = ((glPixelMapusv = (PFNGLPIXELMAPUSVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPixelMapusv"))) == NULL) || r;
+ r = ((glPixelStoref = (PFNGLPIXELSTOREFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPixelStoref"))) == NULL) || r;
+ r = ((glPixelStorei = (PFNGLPIXELSTOREIPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPixelStorei"))) == NULL) || r;
+ r = ((glPixelTransferf = (PFNGLPIXELTRANSFERFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPixelTransferf"))) == NULL) || r;
+ r = ((glPixelTransferi = (PFNGLPIXELTRANSFERIPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPixelTransferi"))) == NULL) || r;
+ r = ((glPixelZoom = (PFNGLPIXELZOOMPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPixelZoom"))) == NULL) || r;
+ r = ((glPointSize = (PFNGLPOINTSIZEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPointSize"))) == NULL) || r;
+ r = ((glPolygonMode = (PFNGLPOLYGONMODEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPolygonMode"))) == NULL) || r;
+ r = ((glPolygonOffset = (PFNGLPOLYGONOFFSETPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPolygonOffset"))) == NULL) || r;
+ r = ((glPolygonStipple = (PFNGLPOLYGONSTIPPLEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPolygonStipple"))) == NULL) || r;
+ r = ((glPopAttrib = (PFNGLPOPATTRIBPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPopAttrib"))) == NULL) || r;
+ r = ((glPopClientAttrib = (PFNGLPOPCLIENTATTRIBPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPopClientAttrib"))) == NULL) || r;
+ r = ((glPopMatrix = (PFNGLPOPMATRIXPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPopMatrix"))) == NULL) || r;
+ r = ((glPopName = (PFNGLPOPNAMEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPopName"))) == NULL) || r;
+ r = ((glPrioritizeTextures = (PFNGLPRIORITIZETEXTURESPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPrioritizeTextures"))) == NULL) || r;
+ r = ((glPushAttrib = (PFNGLPUSHATTRIBPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPushAttrib"))) == NULL) || r;
+ r = ((glPushClientAttrib = (PFNGLPUSHCLIENTATTRIBPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPushClientAttrib"))) == NULL) || r;
+ r = ((glPushMatrix = (PFNGLPUSHMATRIXPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPushMatrix"))) == NULL) || r;
+ r = ((glPushName = (PFNGLPUSHNAMEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glPushName"))) == NULL) || r;
+ r = ((glRasterPos2d = (PFNGLRASTERPOS2DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos2d"))) == NULL) || r;
+ r = ((glRasterPos2dv = (PFNGLRASTERPOS2DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos2dv"))) == NULL) || r;
+ r = ((glRasterPos2f = (PFNGLRASTERPOS2FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos2f"))) == NULL) || r;
+ r = ((glRasterPos2fv = (PFNGLRASTERPOS2FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos2fv"))) == NULL) || r;
+ r = ((glRasterPos2i = (PFNGLRASTERPOS2IPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos2i"))) == NULL) || r;
+ r = ((glRasterPos2iv = (PFNGLRASTERPOS2IVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos2iv"))) == NULL) || r;
+ r = ((glRasterPos2s = (PFNGLRASTERPOS2SPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos2s"))) == NULL) || r;
+ r = ((glRasterPos2sv = (PFNGLRASTERPOS2SVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos2sv"))) == NULL) || r;
+ r = ((glRasterPos3d = (PFNGLRASTERPOS3DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos3d"))) == NULL) || r;
+ r = ((glRasterPos3dv = (PFNGLRASTERPOS3DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos3dv"))) == NULL) || r;
+ r = ((glRasterPos3f = (PFNGLRASTERPOS3FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos3f"))) == NULL) || r;
+ r = ((glRasterPos3fv = (PFNGLRASTERPOS3FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos3fv"))) == NULL) || r;
+ r = ((glRasterPos3i = (PFNGLRASTERPOS3IPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos3i"))) == NULL) || r;
+ r = ((glRasterPos3iv = (PFNGLRASTERPOS3IVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos3iv"))) == NULL) || r;
+ r = ((glRasterPos3s = (PFNGLRASTERPOS3SPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos3s"))) == NULL) || r;
+ r = ((glRasterPos3sv = (PFNGLRASTERPOS3SVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos3sv"))) == NULL) || r;
+ r = ((glRasterPos4d = (PFNGLRASTERPOS4DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos4d"))) == NULL) || r;
+ r = ((glRasterPos4dv = (PFNGLRASTERPOS4DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos4dv"))) == NULL) || r;
+ r = ((glRasterPos4f = (PFNGLRASTERPOS4FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos4f"))) == NULL) || r;
+ r = ((glRasterPos4fv = (PFNGLRASTERPOS4FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos4fv"))) == NULL) || r;
+ r = ((glRasterPos4i = (PFNGLRASTERPOS4IPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos4i"))) == NULL) || r;
+ r = ((glRasterPos4iv = (PFNGLRASTERPOS4IVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos4iv"))) == NULL) || r;
+ r = ((glRasterPos4s = (PFNGLRASTERPOS4SPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos4s"))) == NULL) || r;
+ r = ((glRasterPos4sv = (PFNGLRASTERPOS4SVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRasterPos4sv"))) == NULL) || r;
+ r = ((glReadBuffer = (PFNGLREADBUFFERPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glReadBuffer"))) == NULL) || r;
+ r = ((glReadPixels = (PFNGLREADPIXELSPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glReadPixels"))) == NULL) || r;
+ r = ((glRectd = (PFNGLRECTDPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRectd"))) == NULL) || r;
+ r = ((glRectdv = (PFNGLRECTDVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRectdv"))) == NULL) || r;
+ r = ((glRectf = (PFNGLRECTFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRectf"))) == NULL) || r;
+ r = ((glRectfv = (PFNGLRECTFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRectfv"))) == NULL) || r;
+ r = ((glRecti = (PFNGLRECTIPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRecti"))) == NULL) || r;
+ r = ((glRectiv = (PFNGLRECTIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRectiv"))) == NULL) || r;
+ r = ((glRects = (PFNGLRECTSPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRects"))) == NULL) || r;
+ r = ((glRectsv = (PFNGLRECTSVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRectsv"))) == NULL) || r;
+ r = ((glRenderMode = (PFNGLRENDERMODEPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRenderMode"))) == NULL) || r;
+ r = ((glRotated = (PFNGLROTATEDPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRotated"))) == NULL) || r;
+ r = ((glRotatef = (PFNGLROTATEFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glRotatef"))) == NULL) || r;
+ r = ((glScaled = (PFNGLSCALEDPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glScaled"))) == NULL) || r;
+ r = ((glScalef = (PFNGLSCALEFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glScalef"))) == NULL) || r;
+ r = ((glScissor = (PFNGLSCISSORPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glScissor"))) == NULL) || r;
+ r = ((glSelectBuffer = (PFNGLSELECTBUFFERPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glSelectBuffer"))) == NULL) || r;
+ r = ((glShadeModel = (PFNGLSHADEMODELPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glShadeModel"))) == NULL) || r;
+ r = ((glStencilFunc = (PFNGLSTENCILFUNCPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glStencilFunc"))) == NULL) || r;
+ r = ((glStencilMask = (PFNGLSTENCILMASKPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glStencilMask"))) == NULL) || r;
+ r = ((glStencilOp = (PFNGLSTENCILOPPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glStencilOp"))) == NULL) || r;
+ r = ((glTexCoord1d = (PFNGLTEXCOORD1DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord1d"))) == NULL) || r;
+ r = ((glTexCoord1dv = (PFNGLTEXCOORD1DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord1dv"))) == NULL) || r;
+ r = ((glTexCoord1f = (PFNGLTEXCOORD1FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord1f"))) == NULL) || r;
+ r = ((glTexCoord1fv = (PFNGLTEXCOORD1FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord1fv"))) == NULL) || r;
+ r = ((glTexCoord1i = (PFNGLTEXCOORD1IPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord1i"))) == NULL) || r;
+ r = ((glTexCoord1iv = (PFNGLTEXCOORD1IVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord1iv"))) == NULL) || r;
+ r = ((glTexCoord1s = (PFNGLTEXCOORD1SPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord1s"))) == NULL) || r;
+ r = ((glTexCoord1sv = (PFNGLTEXCOORD1SVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord1sv"))) == NULL) || r;
+ r = ((glTexCoord2d = (PFNGLTEXCOORD2DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord2d"))) == NULL) || r;
+ r = ((glTexCoord2dv = (PFNGLTEXCOORD2DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord2dv"))) == NULL) || r;
+ r = ((glTexCoord2f = (PFNGLTEXCOORD2FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord2f"))) == NULL) || r;
+ r = ((glTexCoord2fv = (PFNGLTEXCOORD2FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord2fv"))) == NULL) || r;
+ r = ((glTexCoord2i = (PFNGLTEXCOORD2IPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord2i"))) == NULL) || r;
+ r = ((glTexCoord2iv = (PFNGLTEXCOORD2IVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord2iv"))) == NULL) || r;
+ r = ((glTexCoord2s = (PFNGLTEXCOORD2SPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord2s"))) == NULL) || r;
+ r = ((glTexCoord2sv = (PFNGLTEXCOORD2SVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord2sv"))) == NULL) || r;
+ r = ((glTexCoord3d = (PFNGLTEXCOORD3DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord3d"))) == NULL) || r;
+ r = ((glTexCoord3dv = (PFNGLTEXCOORD3DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord3dv"))) == NULL) || r;
+ r = ((glTexCoord3f = (PFNGLTEXCOORD3FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord3f"))) == NULL) || r;
+ r = ((glTexCoord3fv = (PFNGLTEXCOORD3FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord3fv"))) == NULL) || r;
+ r = ((glTexCoord3i = (PFNGLTEXCOORD3IPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord3i"))) == NULL) || r;
+ r = ((glTexCoord3iv = (PFNGLTEXCOORD3IVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord3iv"))) == NULL) || r;
+ r = ((glTexCoord3s = (PFNGLTEXCOORD3SPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord3s"))) == NULL) || r;
+ r = ((glTexCoord3sv = (PFNGLTEXCOORD3SVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord3sv"))) == NULL) || r;
+ r = ((glTexCoord4d = (PFNGLTEXCOORD4DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord4d"))) == NULL) || r;
+ r = ((glTexCoord4dv = (PFNGLTEXCOORD4DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord4dv"))) == NULL) || r;
+ r = ((glTexCoord4f = (PFNGLTEXCOORD4FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord4f"))) == NULL) || r;
+ r = ((glTexCoord4fv = (PFNGLTEXCOORD4FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord4fv"))) == NULL) || r;
+ r = ((glTexCoord4i = (PFNGLTEXCOORD4IPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord4i"))) == NULL) || r;
+ r = ((glTexCoord4iv = (PFNGLTEXCOORD4IVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord4iv"))) == NULL) || r;
+ r = ((glTexCoord4s = (PFNGLTEXCOORD4SPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord4s"))) == NULL) || r;
+ r = ((glTexCoord4sv = (PFNGLTEXCOORD4SVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoord4sv"))) == NULL) || r;
+ r = ((glTexCoordPointer = (PFNGLTEXCOORDPOINTERPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexCoordPointer"))) == NULL) || r;
+ r = ((glTexEnvf = (PFNGLTEXENVFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexEnvf"))) == NULL) || r;
+ r = ((glTexEnvfv = (PFNGLTEXENVFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexEnvfv"))) == NULL) || r;
+ r = ((glTexEnvi = (PFNGLTEXENVIPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexEnvi"))) == NULL) || r;
+ r = ((glTexEnviv = (PFNGLTEXENVIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexEnviv"))) == NULL) || r;
+ r = ((glTexGend = (PFNGLTEXGENDPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexGend"))) == NULL) || r;
+ r = ((glTexGendv = (PFNGLTEXGENDVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexGendv"))) == NULL) || r;
+ r = ((glTexGenf = (PFNGLTEXGENFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexGenf"))) == NULL) || r;
+ r = ((glTexGenfv = (PFNGLTEXGENFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexGenfv"))) == NULL) || r;
+ r = ((glTexGeni = (PFNGLTEXGENIPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexGeni"))) == NULL) || r;
+ r = ((glTexGeniv = (PFNGLTEXGENIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexGeniv"))) == NULL) || r;
+ r = ((glTexImage1D = (PFNGLTEXIMAGE1DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexImage1D"))) == NULL) || r;
+ r = ((glTexImage2D = (PFNGLTEXIMAGE2DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexImage2D"))) == NULL) || r;
+ r = ((glTexParameterf = (PFNGLTEXPARAMETERFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexParameterf"))) == NULL) || r;
+ r = ((glTexParameterfv = (PFNGLTEXPARAMETERFVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexParameterfv"))) == NULL) || r;
+ r = ((glTexParameteri = (PFNGLTEXPARAMETERIPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexParameteri"))) == NULL) || r;
+ r = ((glTexParameteriv = (PFNGLTEXPARAMETERIVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexParameteriv"))) == NULL) || r;
+ r = ((glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexSubImage1D"))) == NULL) || r;
+ r = ((glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTexSubImage2D"))) == NULL) || r;
+ r = ((glTranslated = (PFNGLTRANSLATEDPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTranslated"))) == NULL) || r;
+ r = ((glTranslatef = (PFNGLTRANSLATEFPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glTranslatef"))) == NULL) || r;
+ r = ((glVertex2d = (PFNGLVERTEX2DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex2d"))) == NULL) || r;
+ r = ((glVertex2dv = (PFNGLVERTEX2DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex2dv"))) == NULL) || r;
+ r = ((glVertex2f = (PFNGLVERTEX2FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex2f"))) == NULL) || r;
+ r = ((glVertex2fv = (PFNGLVERTEX2FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex2fv"))) == NULL) || r;
+ r = ((glVertex2i = (PFNGLVERTEX2IPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex2i"))) == NULL) || r;
+ r = ((glVertex2iv = (PFNGLVERTEX2IVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex2iv"))) == NULL) || r;
+ r = ((glVertex2s = (PFNGLVERTEX2SPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex2s"))) == NULL) || r;
+ r = ((glVertex2sv = (PFNGLVERTEX2SVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex2sv"))) == NULL) || r;
+ r = ((glVertex3d = (PFNGLVERTEX3DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex3d"))) == NULL) || r;
+ r = ((glVertex3dv = (PFNGLVERTEX3DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex3dv"))) == NULL) || r;
+ r = ((glVertex3f = (PFNGLVERTEX3FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex3f"))) == NULL) || r;
+ r = ((glVertex3fv = (PFNGLVERTEX3FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex3fv"))) == NULL) || r;
+ r = ((glVertex3i = (PFNGLVERTEX3IPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex3i"))) == NULL) || r;
+ r = ((glVertex3iv = (PFNGLVERTEX3IVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex3iv"))) == NULL) || r;
+ r = ((glVertex3s = (PFNGLVERTEX3SPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex3s"))) == NULL) || r;
+ r = ((glVertex3sv = (PFNGLVERTEX3SVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex3sv"))) == NULL) || r;
+ r = ((glVertex4d = (PFNGLVERTEX4DPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex4d"))) == NULL) || r;
+ r = ((glVertex4dv = (PFNGLVERTEX4DVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex4dv"))) == NULL) || r;
+ r = ((glVertex4f = (PFNGLVERTEX4FPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex4f"))) == NULL) || r;
+ r = ((glVertex4fv = (PFNGLVERTEX4FVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex4fv"))) == NULL) || r;
+ r = ((glVertex4i = (PFNGLVERTEX4IPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex4i"))) == NULL) || r;
+ r = ((glVertex4iv = (PFNGLVERTEX4IVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex4iv"))) == NULL) || r;
+ r = ((glVertex4s = (PFNGLVERTEX4SPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex4s"))) == NULL) || r;
+ r = ((glVertex4sv = (PFNGLVERTEX4SVPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertex4sv"))) == NULL) || r;
+ r = ((glVertexPointer = (PFNGLVERTEXPOINTERPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glVertexPointer"))) == NULL) || r;
+ r = ((glViewport = (PFNGLVIEWPORTPROC)glewGetProcAddress(fqn_from_convention(glew_convention, "glViewport"))) == NULL) || r;
+
+ if (r==0)
+ {
+ printf("glewOpenGL11Init dynamically loaded using dlopen/dlsym OK\n");
+ }
+ return r;
+}
+#endif //GLEW_INIT_OPENGL11_FUNCTIONS
+
+
+GLenum GLEWAPIENTRY glewInit (void)
+{
+ GLenum r;
+ r = glewContextInit();
+ if ( r != 0 ) return r;
+#if defined(_WIN32)
+ return wglewContextInit();
+#elif !defined(__ANDROID__) && !defined(__native_client__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX)) /* _UNIX */
+ return glxewContextInit();
+#else
+ return r;
+#endif /* _WIN32 */
+}
+
+#endif /* !GLEW_MX */
+#ifdef GLEW_MX
+GLboolean GLEWAPIENTRY glewContextIsSupported (const GLEWContext* ctx, const char* name)
+#else
+GLboolean GLEWAPIENTRY glewIsSupported (const char* name)
+#endif
+{
+ GLubyte* pos = (GLubyte*)name;
+ GLuint len = _glewStrLen(pos);
+ GLboolean ret = GL_TRUE;
+ while (ret && len > 0)
+ {
+ if (_glewStrSame1(&pos, &len, (const GLubyte*)"GL_", 3))
+ {
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8))
+ {
+#ifdef GL_VERSION_1_2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3))
+ {
+ ret = GLEW_VERSION_1_2;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_1_2_1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2_1", 5))
+ {
+ ret = GLEW_VERSION_1_2_1;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_1_3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3))
+ {
+ ret = GLEW_VERSION_1_3;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_1_4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3))
+ {
+ ret = GLEW_VERSION_1_4;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_1_5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_5", 3))
+ {
+ ret = GLEW_VERSION_1_5;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_2_0
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"2_0", 3))
+ {
+ ret = GLEW_VERSION_2_0;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_2_1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"2_1", 3))
+ {
+ ret = GLEW_VERSION_2_1;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_3_0
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_0", 3))
+ {
+ ret = GLEW_VERSION_3_0;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_3_1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_1", 3))
+ {
+ ret = GLEW_VERSION_3_1;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_3_2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_2", 3))
+ {
+ ret = GLEW_VERSION_3_2;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_3_3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"3_3", 3))
+ {
+ ret = GLEW_VERSION_3_3;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_4_0
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_0", 3))
+ {
+ ret = GLEW_VERSION_4_0;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_4_1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_1", 3))
+ {
+ ret = GLEW_VERSION_4_1;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_4_2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_2", 3))
+ {
+ ret = GLEW_VERSION_4_2;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_4_3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_3", 3))
+ {
+ ret = GLEW_VERSION_4_3;
+ continue;
+ }
+#endif
+#ifdef GL_VERSION_4_4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"4_4", 3))
+ {
+ ret = GLEW_VERSION_4_4;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5))
+ {
+#ifdef GL_3DFX_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = GLEW_3DFX_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_3DFX_tbuffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"tbuffer", 7))
+ {
+ ret = GLEW_3DFX_tbuffer;
+ continue;
+ }
+#endif
+#ifdef GL_3DFX_texture_compression_FXT1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_FXT1", 24))
+ {
+ ret = GLEW_3DFX_texture_compression_FXT1;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"AMD_", 4))
+ {
+#ifdef GL_AMD_blend_minmax_factor
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_minmax_factor", 19))
+ {
+ ret = GLEW_AMD_blend_minmax_factor;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_conservative_depth
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_depth", 18))
+ {
+ ret = GLEW_AMD_conservative_depth;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_debug_output
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_output", 12))
+ {
+ ret = GLEW_AMD_debug_output;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_depth_clamp_separate
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp_separate", 20))
+ {
+ ret = GLEW_AMD_depth_clamp_separate;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_draw_buffers_blend
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers_blend", 18))
+ {
+ ret = GLEW_AMD_draw_buffers_blend;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_interleaved_elements
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"interleaved_elements", 20))
+ {
+ ret = GLEW_AMD_interleaved_elements;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_multi_draw_indirect
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_indirect", 19))
+ {
+ ret = GLEW_AMD_multi_draw_indirect;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_name_gen_delete
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"name_gen_delete", 15))
+ {
+ ret = GLEW_AMD_name_gen_delete;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_performance_monitor
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"performance_monitor", 19))
+ {
+ ret = GLEW_AMD_performance_monitor;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_pinned_memory
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pinned_memory", 13))
+ {
+ ret = GLEW_AMD_pinned_memory;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_query_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"query_buffer_object", 19))
+ {
+ ret = GLEW_AMD_query_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_sample_positions
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_positions", 16))
+ {
+ ret = GLEW_AMD_sample_positions;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_seamless_cubemap_per_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"seamless_cubemap_per_texture", 28))
+ {
+ ret = GLEW_AMD_seamless_cubemap_per_texture;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_shader_stencil_export
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_stencil_export", 21))
+ {
+ ret = GLEW_AMD_shader_stencil_export;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_shader_trinary_minmax
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_trinary_minmax", 21))
+ {
+ ret = GLEW_AMD_shader_trinary_minmax;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_sparse_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture", 14))
+ {
+ ret = GLEW_AMD_sparse_texture;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_stencil_operation_extended
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_operation_extended", 26))
+ {
+ ret = GLEW_AMD_stencil_operation_extended;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_texture_texture4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_texture4", 16))
+ {
+ ret = GLEW_AMD_texture_texture4;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_transform_feedback3_lines_triangles
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback3_lines_triangles", 35))
+ {
+ ret = GLEW_AMD_transform_feedback3_lines_triangles;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_vertex_shader_layer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_layer", 19))
+ {
+ ret = GLEW_AMD_vertex_shader_layer;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_vertex_shader_tessellator
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_tessellator", 25))
+ {
+ ret = GLEW_AMD_vertex_shader_tessellator;
+ continue;
+ }
+#endif
+#ifdef GL_AMD_vertex_shader_viewport_index
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_viewport_index", 28))
+ {
+ ret = GLEW_AMD_vertex_shader_viewport_index;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ANGLE_", 6))
+ {
+#ifdef GL_ANGLE_depth_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13))
+ {
+ ret = GLEW_ANGLE_depth_texture;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_framebuffer_blit
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_blit", 16))
+ {
+ ret = GLEW_ANGLE_framebuffer_blit;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_framebuffer_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23))
+ {
+ ret = GLEW_ANGLE_framebuffer_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_instanced_arrays
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"instanced_arrays", 16))
+ {
+ ret = GLEW_ANGLE_instanced_arrays;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_pack_reverse_row_order
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pack_reverse_row_order", 22))
+ {
+ ret = GLEW_ANGLE_pack_reverse_row_order;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_program_binary
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"program_binary", 14))
+ {
+ ret = GLEW_ANGLE_program_binary;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt1", 24))
+ {
+ ret = GLEW_ANGLE_texture_compression_dxt1;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt3", 24))
+ {
+ ret = GLEW_ANGLE_texture_compression_dxt3;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_texture_compression_dxt5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt5", 24))
+ {
+ ret = GLEW_ANGLE_texture_compression_dxt5;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_texture_usage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_usage", 13))
+ {
+ ret = GLEW_ANGLE_texture_usage;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_timer_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"timer_query", 11))
+ {
+ ret = GLEW_ANGLE_timer_query;
+ continue;
+ }
+#endif
+#ifdef GL_ANGLE_translated_shader_source
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"translated_shader_source", 24))
+ {
+ ret = GLEW_ANGLE_translated_shader_source;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"APPLE_", 6))
+ {
+#ifdef GL_APPLE_aux_depth_stencil
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"aux_depth_stencil", 17))
+ {
+ ret = GLEW_APPLE_aux_depth_stencil;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_client_storage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"client_storage", 14))
+ {
+ ret = GLEW_APPLE_client_storage;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_element_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"element_array", 13))
+ {
+ ret = GLEW_APPLE_element_array;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_fence
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence", 5))
+ {
+ ret = GLEW_APPLE_fence;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_float_pixels
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_pixels", 12))
+ {
+ ret = GLEW_APPLE_float_pixels;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_flush_buffer_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"flush_buffer_range", 18))
+ {
+ ret = GLEW_APPLE_flush_buffer_range;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_object_purgeable
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"object_purgeable", 16))
+ {
+ ret = GLEW_APPLE_object_purgeable;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_pixel_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer", 12))
+ {
+ ret = GLEW_APPLE_pixel_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_rgb_422
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"rgb_422", 7))
+ {
+ ret = GLEW_APPLE_rgb_422;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_row_bytes
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"row_bytes", 9))
+ {
+ ret = GLEW_APPLE_row_bytes;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_specular_vector
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_vector", 15))
+ {
+ ret = GLEW_APPLE_specular_vector;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_texture_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_range", 13))
+ {
+ ret = GLEW_APPLE_texture_range;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_transform_hint
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_hint", 14))
+ {
+ ret = GLEW_APPLE_transform_hint;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_vertex_array_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19))
+ {
+ ret = GLEW_APPLE_vertex_array_object;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_vertex_array_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18))
+ {
+ ret = GLEW_APPLE_vertex_array_range;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_vertex_program_evaluators
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program_evaluators", 25))
+ {
+ ret = GLEW_APPLE_vertex_program_evaluators;
+ continue;
+ }
+#endif
+#ifdef GL_APPLE_ycbcr_422
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_422", 9))
+ {
+ ret = GLEW_APPLE_ycbcr_422;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4))
+ {
+#ifdef GL_ARB_ES2_compatibility
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES2_compatibility", 17))
+ {
+ ret = GLEW_ARB_ES2_compatibility;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_ES3_compatibility
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES3_compatibility", 17))
+ {
+ ret = GLEW_ARB_ES3_compatibility;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_arrays_of_arrays
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"arrays_of_arrays", 16))
+ {
+ ret = GLEW_ARB_arrays_of_arrays;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_base_instance
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"base_instance", 13))
+ {
+ ret = GLEW_ARB_base_instance;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_bindless_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindless_texture", 16))
+ {
+ ret = GLEW_ARB_bindless_texture;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_blend_func_extended
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_func_extended", 19))
+ {
+ ret = GLEW_ARB_blend_func_extended;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_buffer_storage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_storage", 14))
+ {
+ ret = GLEW_ARB_buffer_storage;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_cl_event
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cl_event", 8))
+ {
+ ret = GLEW_ARB_cl_event;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_clear_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clear_buffer_object", 19))
+ {
+ ret = GLEW_ARB_clear_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_clear_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clear_texture", 13))
+ {
+ ret = GLEW_ARB_clear_texture;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_color_buffer_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_buffer_float", 18))
+ {
+ ret = GLEW_ARB_color_buffer_float;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_compatibility
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compatibility", 13))
+ {
+ ret = GLEW_ARB_compatibility;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_compressed_texture_pixel_storage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compressed_texture_pixel_storage", 32))
+ {
+ ret = GLEW_ARB_compressed_texture_pixel_storage;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_compute_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compute_shader", 14))
+ {
+ ret = GLEW_ARB_compute_shader;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_compute_variable_group_size
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compute_variable_group_size", 27))
+ {
+ ret = GLEW_ARB_compute_variable_group_size;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_conservative_depth
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conservative_depth", 18))
+ {
+ ret = GLEW_ARB_conservative_depth;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_copy_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_buffer", 11))
+ {
+ ret = GLEW_ARB_copy_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_copy_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10))
+ {
+ ret = GLEW_ARB_copy_image;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_debug_output
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_output", 12))
+ {
+ ret = GLEW_ARB_debug_output;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_depth_buffer_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_buffer_float", 18))
+ {
+ ret = GLEW_ARB_depth_buffer_float;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_depth_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp", 11))
+ {
+ ret = GLEW_ARB_depth_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_depth_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13))
+ {
+ ret = GLEW_ARB_depth_texture;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_draw_buffers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12))
+ {
+ ret = GLEW_ARB_draw_buffers;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_draw_buffers_blend
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers_blend", 18))
+ {
+ ret = GLEW_ARB_draw_buffers_blend;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_draw_elements_base_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_elements_base_vertex", 25))
+ {
+ ret = GLEW_ARB_draw_elements_base_vertex;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_draw_indirect
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_indirect", 13))
+ {
+ ret = GLEW_ARB_draw_indirect;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_draw_instanced
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14))
+ {
+ ret = GLEW_ARB_draw_instanced;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_enhanced_layouts
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"enhanced_layouts", 16))
+ {
+ ret = GLEW_ARB_enhanced_layouts;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_explicit_attrib_location
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_attrib_location", 24))
+ {
+ ret = GLEW_ARB_explicit_attrib_location;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_explicit_uniform_location
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_uniform_location", 25))
+ {
+ ret = GLEW_ARB_explicit_uniform_location;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_fragment_coord_conventions
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_coord_conventions", 26))
+ {
+ ret = GLEW_ARB_fragment_coord_conventions;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_fragment_layer_viewport
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_layer_viewport", 23))
+ {
+ ret = GLEW_ARB_fragment_layer_viewport;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_fragment_program
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16))
+ {
+ ret = GLEW_ARB_fragment_program;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_fragment_program_shadow
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program_shadow", 23))
+ {
+ ret = GLEW_ARB_fragment_program_shadow;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_fragment_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader", 15))
+ {
+ ret = GLEW_ARB_fragment_shader;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_framebuffer_no_attachments
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_no_attachments", 26))
+ {
+ ret = GLEW_ARB_framebuffer_no_attachments;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_framebuffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_object", 18))
+ {
+ ret = GLEW_ARB_framebuffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_framebuffer_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16))
+ {
+ ret = GLEW_ARB_framebuffer_sRGB;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_geometry_shader4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16))
+ {
+ ret = GLEW_ARB_geometry_shader4;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_get_program_binary
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_program_binary", 18))
+ {
+ ret = GLEW_ARB_get_program_binary;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_gpu_shader5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader5", 11))
+ {
+ ret = GLEW_ARB_gpu_shader5;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_gpu_shader_fp64
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader_fp64", 15))
+ {
+ ret = GLEW_ARB_gpu_shader_fp64;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_half_float_pixel
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float_pixel", 16))
+ {
+ ret = GLEW_ARB_half_float_pixel;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_half_float_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float_vertex", 17))
+ {
+ ret = GLEW_ARB_half_float_vertex;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_imaging
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"imaging", 7))
+ {
+ ret = GLEW_ARB_imaging;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_indirect_parameters
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"indirect_parameters", 19))
+ {
+ ret = GLEW_ARB_indirect_parameters;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_instanced_arrays
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"instanced_arrays", 16))
+ {
+ ret = GLEW_ARB_instanced_arrays;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_internalformat_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"internalformat_query", 20))
+ {
+ ret = GLEW_ARB_internalformat_query;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_internalformat_query2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"internalformat_query2", 21))
+ {
+ ret = GLEW_ARB_internalformat_query2;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_invalidate_subdata
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"invalidate_subdata", 18))
+ {
+ ret = GLEW_ARB_invalidate_subdata;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_map_buffer_alignment
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_buffer_alignment", 20))
+ {
+ ret = GLEW_ARB_map_buffer_alignment;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_map_buffer_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_buffer_range", 16))
+ {
+ ret = GLEW_ARB_map_buffer_range;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_matrix_palette
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"matrix_palette", 14))
+ {
+ ret = GLEW_ARB_matrix_palette;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_multi_bind
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_bind", 10))
+ {
+ ret = GLEW_ARB_multi_bind;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_multi_draw_indirect
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_indirect", 19))
+ {
+ ret = GLEW_ARB_multi_draw_indirect;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = GLEW_ARB_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_multitexture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multitexture", 12))
+ {
+ ret = GLEW_ARB_multitexture;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_occlusion_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query", 15))
+ {
+ ret = GLEW_ARB_occlusion_query;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_occlusion_query2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query2", 16))
+ {
+ ret = GLEW_ARB_occlusion_query2;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_pixel_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19))
+ {
+ ret = GLEW_ARB_pixel_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_point_parameters
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_parameters", 16))
+ {
+ ret = GLEW_ARB_point_parameters;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_point_sprite
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprite", 12))
+ {
+ ret = GLEW_ARB_point_sprite;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_program_interface_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"program_interface_query", 23))
+ {
+ ret = GLEW_ARB_program_interface_query;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_provoking_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"provoking_vertex", 16))
+ {
+ ret = GLEW_ARB_provoking_vertex;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_query_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"query_buffer_object", 19))
+ {
+ ret = GLEW_ARB_query_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_robust_buffer_access_behavior
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robust_buffer_access_behavior", 29))
+ {
+ ret = GLEW_ARB_robust_buffer_access_behavior;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_robustness
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness", 10))
+ {
+ ret = GLEW_ARB_robustness;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_robustness_application_isolation
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_application_isolation", 32))
+ {
+ ret = GLEW_ARB_robustness_application_isolation;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_robustness_share_group_isolation
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_share_group_isolation", 32))
+ {
+ ret = GLEW_ARB_robustness_share_group_isolation;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_sample_shading
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sample_shading", 14))
+ {
+ ret = GLEW_ARB_sample_shading;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_sampler_objects
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sampler_objects", 15))
+ {
+ ret = GLEW_ARB_sampler_objects;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_seamless_cube_map
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"seamless_cube_map", 17))
+ {
+ ret = GLEW_ARB_seamless_cube_map;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_seamless_cubemap_per_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"seamless_cubemap_per_texture", 28))
+ {
+ ret = GLEW_ARB_seamless_cubemap_per_texture;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_separate_shader_objects
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_shader_objects", 23))
+ {
+ ret = GLEW_ARB_separate_shader_objects;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_atomic_counters
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_counters", 22))
+ {
+ ret = GLEW_ARB_shader_atomic_counters;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_bit_encoding
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_bit_encoding", 19))
+ {
+ ret = GLEW_ARB_shader_bit_encoding;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_draw_parameters
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_draw_parameters", 22))
+ {
+ ret = GLEW_ARB_shader_draw_parameters;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_group_vote
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_group_vote", 17))
+ {
+ ret = GLEW_ARB_shader_group_vote;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_image_load_store
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_load_store", 23))
+ {
+ ret = GLEW_ARB_shader_image_load_store;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_image_size
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_size", 17))
+ {
+ ret = GLEW_ARB_shader_image_size;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_objects
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_objects", 14))
+ {
+ ret = GLEW_ARB_shader_objects;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_precision
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_precision", 16))
+ {
+ ret = GLEW_ARB_shader_precision;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_stencil_export
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_stencil_export", 21))
+ {
+ ret = GLEW_ARB_shader_stencil_export;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_storage_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_storage_buffer_object", 28))
+ {
+ ret = GLEW_ARB_shader_storage_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_subroutine
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_subroutine", 17))
+ {
+ ret = GLEW_ARB_shader_subroutine;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shader_texture_lod
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_lod", 18))
+ {
+ ret = GLEW_ARB_shader_texture_lod;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shading_language_100
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_100", 20))
+ {
+ ret = GLEW_ARB_shading_language_100;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shading_language_420pack
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_420pack", 24))
+ {
+ ret = GLEW_ARB_shading_language_420pack;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shading_language_include
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_include", 24))
+ {
+ ret = GLEW_ARB_shading_language_include;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shading_language_packing
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shading_language_packing", 24))
+ {
+ ret = GLEW_ARB_shading_language_packing;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shadow
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow", 6))
+ {
+ ret = GLEW_ARB_shadow;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_shadow_ambient
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_ambient", 14))
+ {
+ ret = GLEW_ARB_shadow_ambient;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_sparse_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sparse_texture", 14))
+ {
+ ret = GLEW_ARB_sparse_texture;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_stencil_texturing
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_texturing", 17))
+ {
+ ret = GLEW_ARB_stencil_texturing;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync", 4))
+ {
+ ret = GLEW_ARB_sync;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_tessellation_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"tessellation_shader", 19))
+ {
+ ret = GLEW_ARB_tessellation_shader;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_border_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20))
+ {
+ ret = GLEW_ARB_texture_border_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object", 21))
+ {
+ ret = GLEW_ARB_texture_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_buffer_object_rgb32
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object_rgb32", 27))
+ {
+ ret = GLEW_ARB_texture_buffer_object_rgb32;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_buffer_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_range", 20))
+ {
+ ret = GLEW_ARB_texture_buffer_range;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_compression
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression", 19))
+ {
+ ret = GLEW_ARB_texture_compression;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_compression_bptc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_bptc", 24))
+ {
+ ret = GLEW_ARB_texture_compression_bptc;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_compression_rgtc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_rgtc", 24))
+ {
+ ret = GLEW_ARB_texture_compression_rgtc;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_cube_map
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map", 16))
+ {
+ ret = GLEW_ARB_texture_cube_map;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_cube_map_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map_array", 22))
+ {
+ ret = GLEW_ARB_texture_cube_map_array;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_env_add
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15))
+ {
+ ret = GLEW_ARB_texture_env_add;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_env_combine
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine", 19))
+ {
+ ret = GLEW_ARB_texture_env_combine;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_env_crossbar
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_crossbar", 20))
+ {
+ ret = GLEW_ARB_texture_env_crossbar;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_env_dot3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_dot3", 16))
+ {
+ ret = GLEW_ARB_texture_env_dot3;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_float", 13))
+ {
+ ret = GLEW_ARB_texture_float;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_gather
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_gather", 14))
+ {
+ ret = GLEW_ARB_texture_gather;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_mirror_clamp_to_edge
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_clamp_to_edge", 28))
+ {
+ ret = GLEW_ARB_texture_mirror_clamp_to_edge;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_mirrored_repeat
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23))
+ {
+ ret = GLEW_ARB_texture_mirrored_repeat;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multisample", 19))
+ {
+ ret = GLEW_ARB_texture_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_non_power_of_two
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_non_power_of_two", 24))
+ {
+ ret = GLEW_ARB_texture_non_power_of_two;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_query_levels
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_query_levels", 20))
+ {
+ ret = GLEW_ARB_texture_query_levels;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_query_lod
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_query_lod", 17))
+ {
+ ret = GLEW_ARB_texture_query_lod;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_rectangle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17))
+ {
+ ret = GLEW_ARB_texture_rectangle;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_rg
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rg", 10))
+ {
+ ret = GLEW_ARB_texture_rg;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_rgb10_a2ui
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rgb10_a2ui", 18))
+ {
+ ret = GLEW_ARB_texture_rgb10_a2ui;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_stencil8
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_stencil8", 16))
+ {
+ ret = GLEW_ARB_texture_stencil8;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_storage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_storage", 15))
+ {
+ ret = GLEW_ARB_texture_storage;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_storage_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_storage_multisample", 27))
+ {
+ ret = GLEW_ARB_texture_storage_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_swizzle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_swizzle", 15))
+ {
+ ret = GLEW_ARB_texture_swizzle;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_texture_view
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_view", 12))
+ {
+ ret = GLEW_ARB_texture_view;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_timer_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"timer_query", 11))
+ {
+ ret = GLEW_ARB_timer_query;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_transform_feedback2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback2", 19))
+ {
+ ret = GLEW_ARB_transform_feedback2;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_transform_feedback3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback3", 19))
+ {
+ ret = GLEW_ARB_transform_feedback3;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_transform_feedback_instanced
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback_instanced", 28))
+ {
+ ret = GLEW_ARB_transform_feedback_instanced;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_transpose_matrix
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transpose_matrix", 16))
+ {
+ ret = GLEW_ARB_transpose_matrix;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_uniform_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"uniform_buffer_object", 21))
+ {
+ ret = GLEW_ARB_uniform_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_array_bgra
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_bgra", 17))
+ {
+ ret = GLEW_ARB_vertex_array_bgra;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_array_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19))
+ {
+ ret = GLEW_ARB_vertex_array_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_attrib_64bit
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_64bit", 19))
+ {
+ ret = GLEW_ARB_vertex_attrib_64bit;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_attrib_binding
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_binding", 21))
+ {
+ ret = GLEW_ARB_vertex_attrib_binding;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_blend
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_blend", 12))
+ {
+ ret = GLEW_ARB_vertex_blend;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_object", 20))
+ {
+ ret = GLEW_ARB_vertex_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_program
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14))
+ {
+ ret = GLEW_ARB_vertex_program;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader", 13))
+ {
+ ret = GLEW_ARB_vertex_shader;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_type_10f_11f_11f_rev
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_type_10f_11f_11f_rev", 27))
+ {
+ ret = GLEW_ARB_vertex_type_10f_11f_11f_rev;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_vertex_type_2_10_10_10_rev
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_type_2_10_10_10_rev", 26))
+ {
+ ret = GLEW_ARB_vertex_type_2_10_10_10_rev;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_viewport_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"viewport_array", 14))
+ {
+ ret = GLEW_ARB_viewport_array;
+ continue;
+ }
+#endif
+#ifdef GL_ARB_window_pos
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10))
+ {
+ ret = GLEW_ARB_window_pos;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATIX_", 5))
+ {
+#ifdef GL_ATIX_point_sprites
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprites", 13))
+ {
+ ret = GLEW_ATIX_point_sprites;
+ continue;
+ }
+#endif
+#ifdef GL_ATIX_texture_env_combine3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine3", 20))
+ {
+ ret = GLEW_ATIX_texture_env_combine3;
+ continue;
+ }
+#endif
+#ifdef GL_ATIX_texture_env_route
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_route", 17))
+ {
+ ret = GLEW_ATIX_texture_env_route;
+ continue;
+ }
+#endif
+#ifdef GL_ATIX_vertex_shader_output_point_size
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader_output_point_size", 31))
+ {
+ ret = GLEW_ATIX_vertex_shader_output_point_size;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4))
+ {
+#ifdef GL_ATI_draw_buffers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers", 12))
+ {
+ ret = GLEW_ATI_draw_buffers;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_element_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"element_array", 13))
+ {
+ ret = GLEW_ATI_element_array;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_envmap_bumpmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"envmap_bumpmap", 14))
+ {
+ ret = GLEW_ATI_envmap_bumpmap;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_fragment_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_shader", 15))
+ {
+ ret = GLEW_ATI_fragment_shader;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_map_object_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_object_buffer", 17))
+ {
+ ret = GLEW_ATI_map_object_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_meminfo
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"meminfo", 7))
+ {
+ ret = GLEW_ATI_meminfo;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_pn_triangles
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pn_triangles", 12))
+ {
+ ret = GLEW_ATI_pn_triangles;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_separate_stencil
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_stencil", 16))
+ {
+ ret = GLEW_ATI_separate_stencil;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_shader_texture_lod
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_texture_lod", 18))
+ {
+ ret = GLEW_ATI_shader_texture_lod;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_text_fragment_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"text_fragment_shader", 20))
+ {
+ ret = GLEW_ATI_text_fragment_shader;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_texture_compression_3dc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_3dc", 23))
+ {
+ ret = GLEW_ATI_texture_compression_3dc;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_texture_env_combine3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine3", 20))
+ {
+ ret = GLEW_ATI_texture_env_combine3;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_texture_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_float", 13))
+ {
+ ret = GLEW_ATI_texture_float;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_texture_mirror_once
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_once", 19))
+ {
+ ret = GLEW_ATI_texture_mirror_once;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_vertex_array_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_object", 19))
+ {
+ ret = GLEW_ATI_vertex_array_object;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_vertex_attrib_array_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_array_object", 26))
+ {
+ ret = GLEW_ATI_vertex_attrib_array_object;
+ continue;
+ }
+#endif
+#ifdef GL_ATI_vertex_streams
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_streams", 14))
+ {
+ ret = GLEW_ATI_vertex_streams;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4))
+ {
+#ifdef GL_EXT_422_pixels
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"422_pixels", 10))
+ {
+ ret = GLEW_EXT_422_pixels;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_Cg_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"Cg_shader", 9))
+ {
+ ret = GLEW_EXT_Cg_shader;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_abgr
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"abgr", 4))
+ {
+ ret = GLEW_EXT_abgr;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_bgra
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bgra", 4))
+ {
+ ret = GLEW_EXT_bgra;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_bindable_uniform
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindable_uniform", 16))
+ {
+ ret = GLEW_EXT_bindable_uniform;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_blend_color
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_color", 11))
+ {
+ ret = GLEW_EXT_blend_color;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_blend_equation_separate
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_separate", 23))
+ {
+ ret = GLEW_EXT_blend_equation_separate;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_blend_func_separate
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_func_separate", 19))
+ {
+ ret = GLEW_EXT_blend_func_separate;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_blend_logic_op
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_logic_op", 14))
+ {
+ ret = GLEW_EXT_blend_logic_op;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_blend_minmax
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_minmax", 12))
+ {
+ ret = GLEW_EXT_blend_minmax;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_blend_subtract
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_subtract", 14))
+ {
+ ret = GLEW_EXT_blend_subtract;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_clip_volume_hint
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clip_volume_hint", 16))
+ {
+ ret = GLEW_EXT_clip_volume_hint;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_cmyka
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cmyka", 5))
+ {
+ ret = GLEW_EXT_cmyka;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_color_subtable
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_subtable", 14))
+ {
+ ret = GLEW_EXT_color_subtable;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_compiled_vertex_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compiled_vertex_array", 21))
+ {
+ ret = GLEW_EXT_compiled_vertex_array;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_convolution
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution", 11))
+ {
+ ret = GLEW_EXT_convolution;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_coordinate_frame
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"coordinate_frame", 16))
+ {
+ ret = GLEW_EXT_coordinate_frame;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_copy_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_texture", 12))
+ {
+ ret = GLEW_EXT_copy_texture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_cull_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_vertex", 11))
+ {
+ ret = GLEW_EXT_cull_vertex;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_debug_marker
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug_marker", 12))
+ {
+ ret = GLEW_EXT_debug_marker;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_depth_bounds_test
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_bounds_test", 17))
+ {
+ ret = GLEW_EXT_depth_bounds_test;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_direct_state_access
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"direct_state_access", 19))
+ {
+ ret = GLEW_EXT_direct_state_access;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_draw_buffers2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_buffers2", 13))
+ {
+ ret = GLEW_EXT_draw_buffers2;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_draw_instanced
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_instanced", 14))
+ {
+ ret = GLEW_EXT_draw_instanced;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_draw_range_elements
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_range_elements", 19))
+ {
+ ret = GLEW_EXT_draw_range_elements;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_fog_coord
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_coord", 9))
+ {
+ ret = GLEW_EXT_fog_coord;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_fragment_lighting
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_lighting", 17))
+ {
+ ret = GLEW_EXT_fragment_lighting;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_framebuffer_blit
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_blit", 16))
+ {
+ ret = GLEW_EXT_framebuffer_blit;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_framebuffer_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample", 23))
+ {
+ ret = GLEW_EXT_framebuffer_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_framebuffer_multisample_blit_scaled
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample_blit_scaled", 35))
+ {
+ ret = GLEW_EXT_framebuffer_multisample_blit_scaled;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_framebuffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_object", 18))
+ {
+ ret = GLEW_EXT_framebuffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_framebuffer_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16))
+ {
+ ret = GLEW_EXT_framebuffer_sRGB;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_geometry_shader4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16))
+ {
+ ret = GLEW_EXT_geometry_shader4;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_gpu_program_parameters
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program_parameters", 22))
+ {
+ ret = GLEW_EXT_gpu_program_parameters;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_gpu_shader4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader4", 11))
+ {
+ ret = GLEW_EXT_gpu_shader4;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_histogram
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"histogram", 9))
+ {
+ ret = GLEW_EXT_histogram;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_index_array_formats
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_array_formats", 19))
+ {
+ ret = GLEW_EXT_index_array_formats;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_index_func
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_func", 10))
+ {
+ ret = GLEW_EXT_index_func;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_index_material
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_material", 14))
+ {
+ ret = GLEW_EXT_index_material;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_index_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"index_texture", 13))
+ {
+ ret = GLEW_EXT_index_texture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_light_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"light_texture", 13))
+ {
+ ret = GLEW_EXT_light_texture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_misc_attribute
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"misc_attribute", 14))
+ {
+ ret = GLEW_EXT_misc_attribute;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_multi_draw_arrays
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multi_draw_arrays", 17))
+ {
+ ret = GLEW_EXT_multi_draw_arrays;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = GLEW_EXT_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_packed_depth_stencil
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_depth_stencil", 20))
+ {
+ ret = GLEW_EXT_packed_depth_stencil;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_packed_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_float", 12))
+ {
+ ret = GLEW_EXT_packed_float;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_packed_pixels
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_pixels", 13))
+ {
+ ret = GLEW_EXT_packed_pixels;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_paletted_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"paletted_texture", 16))
+ {
+ ret = GLEW_EXT_paletted_texture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_pixel_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_buffer_object", 19))
+ {
+ ret = GLEW_EXT_pixel_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_pixel_transform
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_transform", 15))
+ {
+ ret = GLEW_EXT_pixel_transform;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_pixel_transform_color_table
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_transform_color_table", 27))
+ {
+ ret = GLEW_EXT_pixel_transform_color_table;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_point_parameters
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_parameters", 16))
+ {
+ ret = GLEW_EXT_point_parameters;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_polygon_offset
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"polygon_offset", 14))
+ {
+ ret = GLEW_EXT_polygon_offset;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_provoking_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"provoking_vertex", 16))
+ {
+ ret = GLEW_EXT_provoking_vertex;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_rescale_normal
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"rescale_normal", 14))
+ {
+ ret = GLEW_EXT_rescale_normal;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_scene_marker
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_marker", 12))
+ {
+ ret = GLEW_EXT_scene_marker;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_secondary_color
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"secondary_color", 15))
+ {
+ ret = GLEW_EXT_secondary_color;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_separate_shader_objects
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_shader_objects", 23))
+ {
+ ret = GLEW_EXT_separate_shader_objects;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_separate_specular_color
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"separate_specular_color", 23))
+ {
+ ret = GLEW_EXT_separate_specular_color;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shader_image_load_store
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_image_load_store", 23))
+ {
+ ret = GLEW_EXT_shader_image_load_store;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shadow_funcs
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_funcs", 12))
+ {
+ ret = GLEW_EXT_shadow_funcs;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_shared_texture_palette
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_texture_palette", 22))
+ {
+ ret = GLEW_EXT_shared_texture_palette;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_stencil_clear_tag
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_clear_tag", 17))
+ {
+ ret = GLEW_EXT_stencil_clear_tag;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_stencil_two_side
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_two_side", 16))
+ {
+ ret = GLEW_EXT_stencil_two_side;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_stencil_wrap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stencil_wrap", 12))
+ {
+ ret = GLEW_EXT_stencil_wrap;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_subtexture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"subtexture", 10))
+ {
+ ret = GLEW_EXT_subtexture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture", 7))
+ {
+ ret = GLEW_EXT_texture;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture3D
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture3D", 9))
+ {
+ ret = GLEW_EXT_texture3D;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_array", 13))
+ {
+ ret = GLEW_EXT_texture_array;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_buffer_object", 21))
+ {
+ ret = GLEW_EXT_texture_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_compression_dxt1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_dxt1", 24))
+ {
+ ret = GLEW_EXT_texture_compression_dxt1;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_compression_latc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_latc", 24))
+ {
+ ret = GLEW_EXT_texture_compression_latc;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_compression_rgtc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_rgtc", 24))
+ {
+ ret = GLEW_EXT_texture_compression_rgtc;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_compression_s3tc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_s3tc", 24))
+ {
+ ret = GLEW_EXT_texture_compression_s3tc;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_cube_map
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_cube_map", 16))
+ {
+ ret = GLEW_EXT_texture_cube_map;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_edge_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_edge_clamp", 18))
+ {
+ ret = GLEW_EXT_texture_edge_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_env
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env", 11))
+ {
+ ret = GLEW_EXT_texture_env;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_env_add
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_add", 15))
+ {
+ ret = GLEW_EXT_texture_env_add;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_env_combine
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine", 19))
+ {
+ ret = GLEW_EXT_texture_env_combine;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_env_dot3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_dot3", 16))
+ {
+ ret = GLEW_EXT_texture_env_dot3;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_filter_anisotropic
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter_anisotropic", 26))
+ {
+ ret = GLEW_EXT_texture_filter_anisotropic;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_integer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_integer", 15))
+ {
+ ret = GLEW_EXT_texture_integer;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_lod_bias
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod_bias", 16))
+ {
+ ret = GLEW_EXT_texture_lod_bias;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_mirror_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirror_clamp", 20))
+ {
+ ret = GLEW_EXT_texture_mirror_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_object", 14))
+ {
+ ret = GLEW_EXT_texture_object;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_perturb_normal
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_perturb_normal", 22))
+ {
+ ret = GLEW_EXT_texture_perturb_normal;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_rectangle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17))
+ {
+ ret = GLEW_EXT_texture_rectangle;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB", 12))
+ {
+ ret = GLEW_EXT_texture_sRGB;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_sRGB_decode
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_sRGB_decode", 19))
+ {
+ ret = GLEW_EXT_texture_sRGB_decode;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_shared_exponent
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shared_exponent", 23))
+ {
+ ret = GLEW_EXT_texture_shared_exponent;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_snorm
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_snorm", 13))
+ {
+ ret = GLEW_EXT_texture_snorm;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_texture_swizzle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_swizzle", 15))
+ {
+ ret = GLEW_EXT_texture_swizzle;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_timer_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"timer_query", 11))
+ {
+ ret = GLEW_EXT_timer_query;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_transform_feedback
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback", 18))
+ {
+ ret = GLEW_EXT_transform_feedback;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_vertex_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array", 12))
+ {
+ ret = GLEW_EXT_vertex_array;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_vertex_array_bgra
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_bgra", 17))
+ {
+ ret = GLEW_EXT_vertex_array_bgra;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_vertex_attrib_64bit
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_64bit", 19))
+ {
+ ret = GLEW_EXT_vertex_attrib_64bit;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_vertex_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_shader", 13))
+ {
+ ret = GLEW_EXT_vertex_shader;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_vertex_weighting
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_weighting", 16))
+ {
+ ret = GLEW_EXT_vertex_weighting;
+ continue;
+ }
+#endif
+#ifdef GL_EXT_x11_sync_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"x11_sync_object", 15))
+ {
+ ret = GLEW_EXT_x11_sync_object;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"GREMEDY_", 8))
+ {
+#ifdef GL_GREMEDY_frame_terminator
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"frame_terminator", 16))
+ {
+ ret = GLEW_GREMEDY_frame_terminator;
+ continue;
+ }
+#endif
+#ifdef GL_GREMEDY_string_marker
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"string_marker", 13))
+ {
+ ret = GLEW_GREMEDY_string_marker;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"HP_", 3))
+ {
+#ifdef GL_HP_convolution_border_modes
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_border_modes", 24))
+ {
+ ret = GLEW_HP_convolution_border_modes;
+ continue;
+ }
+#endif
+#ifdef GL_HP_image_transform
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_transform", 15))
+ {
+ ret = GLEW_HP_image_transform;
+ continue;
+ }
+#endif
+#ifdef GL_HP_occlusion_test
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_test", 14))
+ {
+ ret = GLEW_HP_occlusion_test;
+ continue;
+ }
+#endif
+#ifdef GL_HP_texture_lighting
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lighting", 16))
+ {
+ ret = GLEW_HP_texture_lighting;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"IBM_", 4))
+ {
+#ifdef GL_IBM_cull_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cull_vertex", 11))
+ {
+ ret = GLEW_IBM_cull_vertex;
+ continue;
+ }
+#endif
+#ifdef GL_IBM_multimode_draw_arrays
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multimode_draw_arrays", 21))
+ {
+ ret = GLEW_IBM_multimode_draw_arrays;
+ continue;
+ }
+#endif
+#ifdef GL_IBM_rasterpos_clip
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"rasterpos_clip", 14))
+ {
+ ret = GLEW_IBM_rasterpos_clip;
+ continue;
+ }
+#endif
+#ifdef GL_IBM_static_data
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"static_data", 11))
+ {
+ ret = GLEW_IBM_static_data;
+ continue;
+ }
+#endif
+#ifdef GL_IBM_texture_mirrored_repeat
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_mirrored_repeat", 23))
+ {
+ ret = GLEW_IBM_texture_mirrored_repeat;
+ continue;
+ }
+#endif
+#ifdef GL_IBM_vertex_array_lists
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_lists", 18))
+ {
+ ret = GLEW_IBM_vertex_array_lists;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"INGR_", 5))
+ {
+#ifdef GL_INGR_color_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_clamp", 11))
+ {
+ ret = GLEW_INGR_color_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_INGR_interlace_read
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace_read", 14))
+ {
+ ret = GLEW_INGR_interlace_read;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"INTEL_", 6))
+ {
+#ifdef GL_INTEL_map_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"map_texture", 11))
+ {
+ ret = GLEW_INTEL_map_texture;
+ continue;
+ }
+#endif
+#ifdef GL_INTEL_parallel_arrays
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"parallel_arrays", 15))
+ {
+ ret = GLEW_INTEL_parallel_arrays;
+ continue;
+ }
+#endif
+#ifdef GL_INTEL_texture_scissor
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_scissor", 15))
+ {
+ ret = GLEW_INTEL_texture_scissor;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"KHR_", 4))
+ {
+#ifdef GL_KHR_debug
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"debug", 5))
+ {
+ ret = GLEW_KHR_debug;
+ continue;
+ }
+#endif
+#ifdef GL_KHR_texture_compression_astc_ldr
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_astc_ldr", 28))
+ {
+ ret = GLEW_KHR_texture_compression_astc_ldr;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"KTX_", 4))
+ {
+#ifdef GL_KTX_buffer_region
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_region", 13))
+ {
+ ret = GLEW_KTX_buffer_region;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESAX_", 6))
+ {
+#ifdef GL_MESAX_texture_stack
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_stack", 13))
+ {
+ ret = GLEW_MESAX_texture_stack;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5))
+ {
+#ifdef GL_MESA_pack_invert
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pack_invert", 11))
+ {
+ ret = GLEW_MESA_pack_invert;
+ continue;
+ }
+#endif
+#ifdef GL_MESA_resize_buffers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"resize_buffers", 14))
+ {
+ ret = GLEW_MESA_resize_buffers;
+ continue;
+ }
+#endif
+#ifdef GL_MESA_window_pos
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"window_pos", 10))
+ {
+ ret = GLEW_MESA_window_pos;
+ continue;
+ }
+#endif
+#ifdef GL_MESA_ycbcr_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycbcr_texture", 13))
+ {
+ ret = GLEW_MESA_ycbcr_texture;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"NVX_", 4))
+ {
+#ifdef GL_NVX_conditional_render
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conditional_render", 18))
+ {
+ ret = GLEW_NVX_conditional_render;
+ continue;
+ }
+#endif
+#ifdef GL_NVX_gpu_memory_info
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_memory_info", 15))
+ {
+ ret = GLEW_NVX_gpu_memory_info;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3))
+ {
+#ifdef GL_NV_bindless_multi_draw_indirect
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindless_multi_draw_indirect", 28))
+ {
+ ret = GLEW_NV_bindless_multi_draw_indirect;
+ continue;
+ }
+#endif
+#ifdef GL_NV_bindless_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"bindless_texture", 16))
+ {
+ ret = GLEW_NV_bindless_texture;
+ continue;
+ }
+#endif
+#ifdef GL_NV_blend_equation_advanced
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced", 23))
+ {
+ ret = GLEW_NV_blend_equation_advanced;
+ continue;
+ }
+#endif
+#ifdef GL_NV_blend_equation_advanced_coherent
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_equation_advanced_coherent", 32))
+ {
+ ret = GLEW_NV_blend_equation_advanced_coherent;
+ continue;
+ }
+#endif
+#ifdef GL_NV_blend_square
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_square", 12))
+ {
+ ret = GLEW_NV_blend_square;
+ continue;
+ }
+#endif
+#ifdef GL_NV_compute_program5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compute_program5", 16))
+ {
+ ret = GLEW_NV_compute_program5;
+ continue;
+ }
+#endif
+#ifdef GL_NV_conditional_render
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"conditional_render", 18))
+ {
+ ret = GLEW_NV_conditional_render;
+ continue;
+ }
+#endif
+#ifdef GL_NV_copy_depth_to_color
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_depth_to_color", 19))
+ {
+ ret = GLEW_NV_copy_depth_to_color;
+ continue;
+ }
+#endif
+#ifdef GL_NV_copy_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10))
+ {
+ ret = GLEW_NV_copy_image;
+ continue;
+ }
+#endif
+#ifdef GL_NV_deep_texture3D
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"deep_texture3D", 14))
+ {
+ ret = GLEW_NV_deep_texture3D;
+ continue;
+ }
+#endif
+#ifdef GL_NV_depth_buffer_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_buffer_float", 18))
+ {
+ ret = GLEW_NV_depth_buffer_float;
+ continue;
+ }
+#endif
+#ifdef GL_NV_depth_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_clamp", 11))
+ {
+ ret = GLEW_NV_depth_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_NV_depth_range_unclamped
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_range_unclamped", 21))
+ {
+ ret = GLEW_NV_depth_range_unclamped;
+ continue;
+ }
+#endif
+#ifdef GL_NV_draw_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"draw_texture", 12))
+ {
+ ret = GLEW_NV_draw_texture;
+ continue;
+ }
+#endif
+#ifdef GL_NV_evaluators
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"evaluators", 10))
+ {
+ ret = GLEW_NV_evaluators;
+ continue;
+ }
+#endif
+#ifdef GL_NV_explicit_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"explicit_multisample", 20))
+ {
+ ret = GLEW_NV_explicit_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fence
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fence", 5))
+ {
+ ret = GLEW_NV_fence;
+ continue;
+ }
+#endif
+#ifdef GL_NV_float_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12))
+ {
+ ret = GLEW_NV_float_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fog_distance
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_distance", 12))
+ {
+ ret = GLEW_NV_fog_distance;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fragment_program
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program", 16))
+ {
+ ret = GLEW_NV_fragment_program;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fragment_program2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program2", 17))
+ {
+ ret = GLEW_NV_fragment_program2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fragment_program4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program4", 17))
+ {
+ ret = GLEW_NV_fragment_program4;
+ continue;
+ }
+#endif
+#ifdef GL_NV_fragment_program_option
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_program_option", 23))
+ {
+ ret = GLEW_NV_fragment_program_option;
+ continue;
+ }
+#endif
+#ifdef GL_NV_framebuffer_multisample_coverage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_multisample_coverage", 32))
+ {
+ ret = GLEW_NV_framebuffer_multisample_coverage;
+ continue;
+ }
+#endif
+#ifdef GL_NV_geometry_program4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_program4", 17))
+ {
+ ret = GLEW_NV_geometry_program4;
+ continue;
+ }
+#endif
+#ifdef GL_NV_geometry_shader4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"geometry_shader4", 16))
+ {
+ ret = GLEW_NV_geometry_shader4;
+ continue;
+ }
+#endif
+#ifdef GL_NV_gpu_program4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program4", 12))
+ {
+ ret = GLEW_NV_gpu_program4;
+ continue;
+ }
+#endif
+#ifdef GL_NV_gpu_program5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program5", 12))
+ {
+ ret = GLEW_NV_gpu_program5;
+ continue;
+ }
+#endif
+#ifdef GL_NV_gpu_program5_mem_extended
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program5_mem_extended", 25))
+ {
+ ret = GLEW_NV_gpu_program5_mem_extended;
+ continue;
+ }
+#endif
+#ifdef GL_NV_gpu_program_fp64
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_program_fp64", 16))
+ {
+ ret = GLEW_NV_gpu_program_fp64;
+ continue;
+ }
+#endif
+#ifdef GL_NV_gpu_shader5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_shader5", 11))
+ {
+ ret = GLEW_NV_gpu_shader5;
+ continue;
+ }
+#endif
+#ifdef GL_NV_half_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"half_float", 10))
+ {
+ ret = GLEW_NV_half_float;
+ continue;
+ }
+#endif
+#ifdef GL_NV_light_max_exponent
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"light_max_exponent", 18))
+ {
+ ret = GLEW_NV_light_max_exponent;
+ continue;
+ }
+#endif
+#ifdef GL_NV_multisample_coverage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_coverage", 20))
+ {
+ ret = GLEW_NV_multisample_coverage;
+ continue;
+ }
+#endif
+#ifdef GL_NV_multisample_filter_hint
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_filter_hint", 23))
+ {
+ ret = GLEW_NV_multisample_filter_hint;
+ continue;
+ }
+#endif
+#ifdef GL_NV_occlusion_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"occlusion_query", 15))
+ {
+ ret = GLEW_NV_occlusion_query;
+ continue;
+ }
+#endif
+#ifdef GL_NV_packed_depth_stencil
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"packed_depth_stencil", 20))
+ {
+ ret = GLEW_NV_packed_depth_stencil;
+ continue;
+ }
+#endif
+#ifdef GL_NV_parameter_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"parameter_buffer_object", 23))
+ {
+ ret = GLEW_NV_parameter_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_NV_parameter_buffer_object2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"parameter_buffer_object2", 24))
+ {
+ ret = GLEW_NV_parameter_buffer_object2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_path_rendering
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"path_rendering", 14))
+ {
+ ret = GLEW_NV_path_rendering;
+ continue;
+ }
+#endif
+#ifdef GL_NV_pixel_data_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_data_range", 16))
+ {
+ ret = GLEW_NV_pixel_data_range;
+ continue;
+ }
+#endif
+#ifdef GL_NV_point_sprite
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_sprite", 12))
+ {
+ ret = GLEW_NV_point_sprite;
+ continue;
+ }
+#endif
+#ifdef GL_NV_present_video
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13))
+ {
+ ret = GLEW_NV_present_video;
+ continue;
+ }
+#endif
+#ifdef GL_NV_primitive_restart
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"primitive_restart", 17))
+ {
+ ret = GLEW_NV_primitive_restart;
+ continue;
+ }
+#endif
+#ifdef GL_NV_register_combiners
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"register_combiners", 18))
+ {
+ ret = GLEW_NV_register_combiners;
+ continue;
+ }
+#endif
+#ifdef GL_NV_register_combiners2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"register_combiners2", 19))
+ {
+ ret = GLEW_NV_register_combiners2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shader_atomic_counters
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_counters", 22))
+ {
+ ret = GLEW_NV_shader_atomic_counters;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shader_atomic_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_atomic_float", 19))
+ {
+ ret = GLEW_NV_shader_atomic_float;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shader_buffer_load
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_buffer_load", 18))
+ {
+ ret = GLEW_NV_shader_buffer_load;
+ continue;
+ }
+#endif
+#ifdef GL_NV_shader_storage_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shader_storage_buffer_object", 28))
+ {
+ ret = GLEW_NV_shader_storage_buffer_object;
+ continue;
+ }
+#endif
+#ifdef GL_NV_tessellation_program5
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"tessellation_program5", 21))
+ {
+ ret = GLEW_NV_tessellation_program5;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texgen_emboss
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_emboss", 13))
+ {
+ ret = GLEW_NV_texgen_emboss;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texgen_reflection
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texgen_reflection", 17))
+ {
+ ret = GLEW_NV_texgen_reflection;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_barrier
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_barrier", 15))
+ {
+ ret = GLEW_NV_texture_barrier;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_compression_vtc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_compression_vtc", 23))
+ {
+ ret = GLEW_NV_texture_compression_vtc;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_env_combine4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_env_combine4", 20))
+ {
+ ret = GLEW_NV_texture_env_combine4;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_expand_normal
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_expand_normal", 21))
+ {
+ ret = GLEW_NV_texture_expand_normal;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multisample", 19))
+ {
+ ret = GLEW_NV_texture_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_rectangle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_rectangle", 17))
+ {
+ ret = GLEW_NV_texture_rectangle;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_shader
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader", 14))
+ {
+ ret = GLEW_NV_texture_shader;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_shader2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader2", 15))
+ {
+ ret = GLEW_NV_texture_shader2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_texture_shader3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_shader3", 15))
+ {
+ ret = GLEW_NV_texture_shader3;
+ continue;
+ }
+#endif
+#ifdef GL_NV_transform_feedback
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback", 18))
+ {
+ ret = GLEW_NV_transform_feedback;
+ continue;
+ }
+#endif
+#ifdef GL_NV_transform_feedback2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"transform_feedback2", 19))
+ {
+ ret = GLEW_NV_transform_feedback2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vdpau_interop
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vdpau_interop", 13))
+ {
+ ret = GLEW_NV_vdpau_interop;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_array_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18))
+ {
+ ret = GLEW_NV_vertex_array_range;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_array_range2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range2", 19))
+ {
+ ret = GLEW_NV_vertex_array_range2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_attrib_integer_64bit
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_attrib_integer_64bit", 27))
+ {
+ ret = GLEW_NV_vertex_attrib_integer_64bit;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_buffer_unified_memory
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_unified_memory", 28))
+ {
+ ret = GLEW_NV_vertex_buffer_unified_memory;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_program
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program", 14))
+ {
+ ret = GLEW_NV_vertex_program;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_program1_1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program1_1", 17))
+ {
+ ret = GLEW_NV_vertex_program1_1;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_program2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program2", 15))
+ {
+ ret = GLEW_NV_vertex_program2;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_program2_option
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program2_option", 22))
+ {
+ ret = GLEW_NV_vertex_program2_option;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_program3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program3", 15))
+ {
+ ret = GLEW_NV_vertex_program3;
+ continue;
+ }
+#endif
+#ifdef GL_NV_vertex_program4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_program4", 15))
+ {
+ ret = GLEW_NV_vertex_program4;
+ continue;
+ }
+#endif
+#ifdef GL_NV_video_capture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_capture", 13))
+ {
+ ret = GLEW_NV_video_capture;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"OES_", 4))
+ {
+#ifdef GL_OES_byte_coordinates
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"byte_coordinates", 16))
+ {
+ ret = GLEW_OES_byte_coordinates;
+ continue;
+ }
+#endif
+#ifdef GL_OES_compressed_paletted_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"compressed_paletted_texture", 27))
+ {
+ ret = GLEW_OES_compressed_paletted_texture;
+ continue;
+ }
+#endif
+#ifdef GL_OES_read_format
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_format", 11))
+ {
+ ret = GLEW_OES_read_format;
+ continue;
+ }
+#endif
+#ifdef GL_OES_single_precision
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"single_precision", 16))
+ {
+ ret = GLEW_OES_single_precision;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4))
+ {
+#ifdef GL_OML_interlace
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace", 9))
+ {
+ ret = GLEW_OML_interlace;
+ continue;
+ }
+#endif
+#ifdef GL_OML_resample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"resample", 8))
+ {
+ ret = GLEW_OML_resample;
+ continue;
+ }
+#endif
+#ifdef GL_OML_subsample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"subsample", 9))
+ {
+ ret = GLEW_OML_subsample;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"PGI_", 4))
+ {
+#ifdef GL_PGI_misc_hints
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"misc_hints", 10))
+ {
+ ret = GLEW_PGI_misc_hints;
+ continue;
+ }
+#endif
+#ifdef GL_PGI_vertex_hints
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_hints", 12))
+ {
+ ret = GLEW_PGI_vertex_hints;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"REGAL_", 6))
+ {
+#ifdef GL_REGAL_ES1_0_compatibility
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES1_0_compatibility", 19))
+ {
+ ret = GLEW_REGAL_ES1_0_compatibility;
+ continue;
+ }
+#endif
+#ifdef GL_REGAL_ES1_1_compatibility
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ES1_1_compatibility", 19))
+ {
+ ret = GLEW_REGAL_ES1_1_compatibility;
+ continue;
+ }
+#endif
+#ifdef GL_REGAL_enable
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"enable", 6))
+ {
+ ret = GLEW_REGAL_enable;
+ continue;
+ }
+#endif
+#ifdef GL_REGAL_error_string
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"error_string", 12))
+ {
+ ret = GLEW_REGAL_error_string;
+ continue;
+ }
+#endif
+#ifdef GL_REGAL_extension_query
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"extension_query", 15))
+ {
+ ret = GLEW_REGAL_extension_query;
+ continue;
+ }
+#endif
+#ifdef GL_REGAL_log
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"log", 3))
+ {
+ ret = GLEW_REGAL_log;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"REND_", 5))
+ {
+#ifdef GL_REND_screen_coordinates
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"screen_coordinates", 18))
+ {
+ ret = GLEW_REND_screen_coordinates;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"S3_", 3))
+ {
+#ifdef GL_S3_s3tc
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"s3tc", 4))
+ {
+ ret = GLEW_S3_s3tc;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIS_", 5))
+ {
+#ifdef GL_SGIS_color_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_range", 11))
+ {
+ ret = GLEW_SGIS_color_range;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_detail_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"detail_texture", 14))
+ {
+ ret = GLEW_SGIS_detail_texture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_fog_function
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_function", 12))
+ {
+ ret = GLEW_SGIS_fog_function;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_generate_mipmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"generate_mipmap", 15))
+ {
+ ret = GLEW_SGIS_generate_mipmap;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = GLEW_SGIS_multisample;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_pixel_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture", 13))
+ {
+ ret = GLEW_SGIS_pixel_texture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_point_line_texgen
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"point_line_texgen", 17))
+ {
+ ret = GLEW_SGIS_point_line_texgen;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_sharpen_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sharpen_texture", 15))
+ {
+ ret = GLEW_SGIS_sharpen_texture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_texture4D
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture4D", 9))
+ {
+ ret = GLEW_SGIS_texture4D;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_texture_border_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_border_clamp", 20))
+ {
+ ret = GLEW_SGIS_texture_border_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_texture_edge_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_edge_clamp", 18))
+ {
+ ret = GLEW_SGIS_texture_edge_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_texture_filter4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_filter4", 15))
+ {
+ ret = GLEW_SGIS_texture_filter4;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_texture_lod
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod", 11))
+ {
+ ret = GLEW_SGIS_texture_lod;
+ continue;
+ }
+#endif
+#ifdef GL_SGIS_texture_select
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_select", 14))
+ {
+ ret = GLEW_SGIS_texture_select;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIX_", 5))
+ {
+#ifdef GL_SGIX_async
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"async", 5))
+ {
+ ret = GLEW_SGIX_async;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_async_histogram
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"async_histogram", 15))
+ {
+ ret = GLEW_SGIX_async_histogram;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_async_pixel
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"async_pixel", 11))
+ {
+ ret = GLEW_SGIX_async_pixel;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_blend_alpha_minmax
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blend_alpha_minmax", 18))
+ {
+ ret = GLEW_SGIX_blend_alpha_minmax;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_clipmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"clipmap", 7))
+ {
+ ret = GLEW_SGIX_clipmap;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_convolution_accuracy
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_accuracy", 20))
+ {
+ ret = GLEW_SGIX_convolution_accuracy;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_depth_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_texture", 13))
+ {
+ ret = GLEW_SGIX_depth_texture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_flush_raster
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"flush_raster", 12))
+ {
+ ret = GLEW_SGIX_flush_raster;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_fog_offset
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_offset", 10))
+ {
+ ret = GLEW_SGIX_fog_offset;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_fog_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fog_texture", 11))
+ {
+ ret = GLEW_SGIX_fog_texture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_fragment_specular_lighting
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fragment_specular_lighting", 26))
+ {
+ ret = GLEW_SGIX_fragment_specular_lighting;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_framezoom
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framezoom", 9))
+ {
+ ret = GLEW_SGIX_framezoom;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_interlace
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"interlace", 9))
+ {
+ ret = GLEW_SGIX_interlace;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_ir_instrument1
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ir_instrument1", 14))
+ {
+ ret = GLEW_SGIX_ir_instrument1;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_list_priority
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"list_priority", 13))
+ {
+ ret = GLEW_SGIX_list_priority;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_pixel_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture", 13))
+ {
+ ret = GLEW_SGIX_pixel_texture;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_pixel_texture_bits
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_texture_bits", 18))
+ {
+ ret = GLEW_SGIX_pixel_texture_bits;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_reference_plane
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"reference_plane", 15))
+ {
+ ret = GLEW_SGIX_reference_plane;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_resample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"resample", 8))
+ {
+ ret = GLEW_SGIX_resample;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_shadow
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow", 6))
+ {
+ ret = GLEW_SGIX_shadow;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_shadow_ambient
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shadow_ambient", 14))
+ {
+ ret = GLEW_SGIX_shadow_ambient;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_sprite
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sprite", 6))
+ {
+ ret = GLEW_SGIX_sprite;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_tag_sample_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"tag_sample_buffer", 17))
+ {
+ ret = GLEW_SGIX_tag_sample_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_add_env
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_add_env", 15))
+ {
+ ret = GLEW_SGIX_texture_add_env;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_coordinate_clamp
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_coordinate_clamp", 24))
+ {
+ ret = GLEW_SGIX_texture_coordinate_clamp;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_lod_bias
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_lod_bias", 16))
+ {
+ ret = GLEW_SGIX_texture_lod_bias;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_multi_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_multi_buffer", 20))
+ {
+ ret = GLEW_SGIX_texture_multi_buffer;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_range", 13))
+ {
+ ret = GLEW_SGIX_texture_range;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_texture_scale_bias
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_scale_bias", 18))
+ {
+ ret = GLEW_SGIX_texture_scale_bias;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_vertex_preclip
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_preclip", 14))
+ {
+ ret = GLEW_SGIX_vertex_preclip;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_vertex_preclip_hint
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_preclip_hint", 19))
+ {
+ ret = GLEW_SGIX_vertex_preclip_hint;
+ continue;
+ }
+#endif
+#ifdef GL_SGIX_ycrcb
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"ycrcb", 5))
+ {
+ ret = GLEW_SGIX_ycrcb;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGI_", 4))
+ {
+#ifdef GL_SGI_color_matrix
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_matrix", 12))
+ {
+ ret = GLEW_SGI_color_matrix;
+ continue;
+ }
+#endif
+#ifdef GL_SGI_color_table
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_table", 11))
+ {
+ ret = GLEW_SGI_color_table;
+ continue;
+ }
+#endif
+#ifdef GL_SGI_texture_color_table
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_color_table", 19))
+ {
+ ret = GLEW_SGI_texture_color_table;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUNX_", 5))
+ {
+#ifdef GL_SUNX_constant_data
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"constant_data", 13))
+ {
+ ret = GLEW_SUNX_constant_data;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUN_", 4))
+ {
+#ifdef GL_SUN_convolution_border_modes
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"convolution_border_modes", 24))
+ {
+ ret = GLEW_SUN_convolution_border_modes;
+ continue;
+ }
+#endif
+#ifdef GL_SUN_global_alpha
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"global_alpha", 12))
+ {
+ ret = GLEW_SUN_global_alpha;
+ continue;
+ }
+#endif
+#ifdef GL_SUN_mesh_array
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"mesh_array", 10))
+ {
+ ret = GLEW_SUN_mesh_array;
+ continue;
+ }
+#endif
+#ifdef GL_SUN_read_video_pixels
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"read_video_pixels", 17))
+ {
+ ret = GLEW_SUN_read_video_pixels;
+ continue;
+ }
+#endif
+#ifdef GL_SUN_slice_accum
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"slice_accum", 11))
+ {
+ ret = GLEW_SUN_slice_accum;
+ continue;
+ }
+#endif
+#ifdef GL_SUN_triangle_list
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"triangle_list", 13))
+ {
+ ret = GLEW_SUN_triangle_list;
+ continue;
+ }
+#endif
+#ifdef GL_SUN_vertex
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex", 6))
+ {
+ ret = GLEW_SUN_vertex;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"WIN_", 4))
+ {
+#ifdef GL_WIN_phong_shading
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"phong_shading", 13))
+ {
+ ret = GLEW_WIN_phong_shading;
+ continue;
+ }
+#endif
+#ifdef GL_WIN_specular_fog
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"specular_fog", 12))
+ {
+ ret = GLEW_WIN_specular_fog;
+ continue;
+ }
+#endif
+#ifdef GL_WIN_swap_hint
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_hint", 9))
+ {
+ ret = GLEW_WIN_swap_hint;
+ continue;
+ }
+#endif
+ }
+ }
+ ret = (len == 0);
+ }
+ return ret;
+}
+
+#if defined(_WIN32)
+
+#if defined(GLEW_MX)
+GLboolean GLEWAPIENTRY wglewContextIsSupported (const WGLEWContext* ctx, const char* name)
+#else
+GLboolean GLEWAPIENTRY wglewIsSupported (const char* name)
+#endif
+{
+ GLubyte* pos = (GLubyte*)name;
+ GLuint len = _glewStrLen(pos);
+ GLboolean ret = GL_TRUE;
+ while (ret && len > 0)
+ {
+ if (_glewStrSame1(&pos, &len, (const GLubyte*)"WGL_", 4))
+ {
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5))
+ {
+#ifdef WGL_3DFX_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = WGLEW_3DFX_multisample;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DL_", 4))
+ {
+#ifdef WGL_3DL_stereo_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"stereo_control", 14))
+ {
+ ret = WGLEW_3DL_stereo_control;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"AMD_", 4))
+ {
+#ifdef WGL_AMD_gpu_association
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_association", 15))
+ {
+ ret = WGLEW_AMD_gpu_association;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4))
+ {
+#ifdef WGL_ARB_buffer_region
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_region", 13))
+ {
+ ret = WGLEW_ARB_buffer_region;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_create_context
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context", 14))
+ {
+ ret = WGLEW_ARB_create_context;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_create_context_profile
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_profile", 22))
+ {
+ ret = WGLEW_ARB_create_context_profile;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_create_context_robustness
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_robustness", 25))
+ {
+ ret = WGLEW_ARB_create_context_robustness;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_extensions_string
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"extensions_string", 17))
+ {
+ ret = WGLEW_ARB_extensions_string;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_framebuffer_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16))
+ {
+ ret = WGLEW_ARB_framebuffer_sRGB;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_make_current_read
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17))
+ {
+ ret = WGLEW_ARB_make_current_read;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = WGLEW_ARB_multisample;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_pbuffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7))
+ {
+ ret = WGLEW_ARB_pbuffer;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_pixel_format
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format", 12))
+ {
+ ret = WGLEW_ARB_pixel_format;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_pixel_format_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18))
+ {
+ ret = WGLEW_ARB_pixel_format_float;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_render_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture", 14))
+ {
+ ret = WGLEW_ARB_render_texture;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_robustness_application_isolation
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_application_isolation", 32))
+ {
+ ret = WGLEW_ARB_robustness_application_isolation;
+ continue;
+ }
+#endif
+#ifdef WGL_ARB_robustness_share_group_isolation
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_share_group_isolation", 32))
+ {
+ ret = WGLEW_ARB_robustness_share_group_isolation;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4))
+ {
+#ifdef WGL_ATI_pixel_format_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18))
+ {
+ ret = WGLEW_ATI_pixel_format_float;
+ continue;
+ }
+#endif
+#ifdef WGL_ATI_render_texture_rectangle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture_rectangle", 24))
+ {
+ ret = WGLEW_ATI_render_texture_rectangle;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4))
+ {
+#ifdef WGL_EXT_create_context_es2_profile
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_es2_profile", 26))
+ {
+ ret = WGLEW_EXT_create_context_es2_profile;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_create_context_es_profile
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_es_profile", 25))
+ {
+ ret = WGLEW_EXT_create_context_es_profile;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_depth_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"depth_float", 11))
+ {
+ ret = WGLEW_EXT_depth_float;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_display_color_table
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"display_color_table", 19))
+ {
+ ret = WGLEW_EXT_display_color_table;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_extensions_string
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"extensions_string", 17))
+ {
+ ret = WGLEW_EXT_extensions_string;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_framebuffer_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16))
+ {
+ ret = WGLEW_EXT_framebuffer_sRGB;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_make_current_read
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17))
+ {
+ ret = WGLEW_EXT_make_current_read;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = WGLEW_EXT_multisample;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_pbuffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7))
+ {
+ ret = WGLEW_EXT_pbuffer;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_pixel_format
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format", 12))
+ {
+ ret = WGLEW_EXT_pixel_format;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_pixel_format_packed_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_packed_float", 25))
+ {
+ ret = WGLEW_EXT_pixel_format_packed_float;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_swap_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12))
+ {
+ ret = WGLEW_EXT_swap_control;
+ continue;
+ }
+#endif
+#ifdef WGL_EXT_swap_control_tear
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control_tear", 17))
+ {
+ ret = WGLEW_EXT_swap_control_tear;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"I3D_", 4))
+ {
+#ifdef WGL_I3D_digital_video_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"digital_video_control", 21))
+ {
+ ret = WGLEW_I3D_digital_video_control;
+ continue;
+ }
+#endif
+#ifdef WGL_I3D_gamma
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gamma", 5))
+ {
+ ret = WGLEW_I3D_gamma;
+ continue;
+ }
+#endif
+#ifdef WGL_I3D_genlock
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"genlock", 7))
+ {
+ ret = WGLEW_I3D_genlock;
+ continue;
+ }
+#endif
+#ifdef WGL_I3D_image_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"image_buffer", 12))
+ {
+ ret = WGLEW_I3D_image_buffer;
+ continue;
+ }
+#endif
+#ifdef WGL_I3D_swap_frame_lock
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_frame_lock", 15))
+ {
+ ret = WGLEW_I3D_swap_frame_lock;
+ continue;
+ }
+#endif
+#ifdef WGL_I3D_swap_frame_usage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_frame_usage", 16))
+ {
+ ret = WGLEW_I3D_swap_frame_usage;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3))
+ {
+#ifdef WGL_NV_DX_interop
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"DX_interop", 10))
+ {
+ ret = WGLEW_NV_DX_interop;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_DX_interop2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"DX_interop2", 11))
+ {
+ ret = WGLEW_NV_DX_interop2;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_copy_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10))
+ {
+ ret = WGLEW_NV_copy_image;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_float_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12))
+ {
+ ret = WGLEW_NV_float_buffer;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_gpu_affinity
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_affinity", 12))
+ {
+ ret = WGLEW_NV_gpu_affinity;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_multisample_coverage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_coverage", 20))
+ {
+ ret = WGLEW_NV_multisample_coverage;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_present_video
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13))
+ {
+ ret = WGLEW_NV_present_video;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_render_depth_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_depth_texture", 20))
+ {
+ ret = WGLEW_NV_render_depth_texture;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_render_texture_rectangle
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture_rectangle", 24))
+ {
+ ret = WGLEW_NV_render_texture_rectangle;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_swap_group
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10))
+ {
+ ret = WGLEW_NV_swap_group;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_vertex_array_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18))
+ {
+ ret = WGLEW_NV_vertex_array_range;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_video_capture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_capture", 13))
+ {
+ ret = WGLEW_NV_video_capture;
+ continue;
+ }
+#endif
+#ifdef WGL_NV_video_output
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_output", 12))
+ {
+ ret = WGLEW_NV_video_output;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4))
+ {
+#ifdef WGL_OML_sync_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync_control", 12))
+ {
+ ret = WGLEW_OML_sync_control;
+ continue;
+ }
+#endif
+ }
+ }
+ ret = (len == 0);
+ }
+ return ret;
+}
+
+#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__APPLE__) || defined(GLEW_APPLE_GLX)
+
+#if defined(GLEW_MX)
+GLboolean glxewContextIsSupported (const GLXEWContext* ctx, const char* name)
+#else
+GLboolean glxewIsSupported (const char* name)
+#endif
+{
+ GLubyte* pos = (GLubyte*)name;
+ GLuint len = _glewStrLen(pos);
+ GLboolean ret = GL_TRUE;
+ while (ret && len > 0)
+ {
+ if(_glewStrSame1(&pos, &len, (const GLubyte*)"GLX_", 4))
+ {
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"VERSION_", 8))
+ {
+#ifdef GLX_VERSION_1_2
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_2", 3))
+ {
+ ret = GLXEW_VERSION_1_2;
+ continue;
+ }
+#endif
+#ifdef GLX_VERSION_1_3
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_3", 3))
+ {
+ ret = GLXEW_VERSION_1_3;
+ continue;
+ }
+#endif
+#ifdef GLX_VERSION_1_4
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"1_4", 3))
+ {
+ ret = GLXEW_VERSION_1_4;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"3DFX_", 5))
+ {
+#ifdef GLX_3DFX_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = GLXEW_3DFX_multisample;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"AMD_", 4))
+ {
+#ifdef GLX_AMD_gpu_association
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"gpu_association", 15))
+ {
+ ret = GLXEW_AMD_gpu_association;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ARB_", 4))
+ {
+#ifdef GLX_ARB_create_context
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context", 14))
+ {
+ ret = GLXEW_ARB_create_context;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_create_context_profile
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_profile", 22))
+ {
+ ret = GLXEW_ARB_create_context_profile;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_create_context_robustness
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_robustness", 25))
+ {
+ ret = GLXEW_ARB_create_context_robustness;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_fbconfig_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig_float", 14))
+ {
+ ret = GLXEW_ARB_fbconfig_float;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_framebuffer_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16))
+ {
+ ret = GLXEW_ARB_framebuffer_sRGB;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_get_proc_address
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_proc_address", 16))
+ {
+ ret = GLXEW_ARB_get_proc_address;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = GLXEW_ARB_multisample;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_robustness_application_isolation
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_application_isolation", 32))
+ {
+ ret = GLXEW_ARB_robustness_application_isolation;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_robustness_share_group_isolation
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"robustness_share_group_isolation", 32))
+ {
+ ret = GLXEW_ARB_robustness_share_group_isolation;
+ continue;
+ }
+#endif
+#ifdef GLX_ARB_vertex_buffer_object
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_buffer_object", 20))
+ {
+ ret = GLXEW_ARB_vertex_buffer_object;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"ATI_", 4))
+ {
+#ifdef GLX_ATI_pixel_format_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixel_format_float", 18))
+ {
+ ret = GLXEW_ATI_pixel_format_float;
+ continue;
+ }
+#endif
+#ifdef GLX_ATI_render_texture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"render_texture", 14))
+ {
+ ret = GLXEW_ATI_render_texture;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"EXT_", 4))
+ {
+#ifdef GLX_EXT_buffer_age
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"buffer_age", 10))
+ {
+ ret = GLXEW_EXT_buffer_age;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_create_context_es2_profile
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_es2_profile", 26))
+ {
+ ret = GLXEW_EXT_create_context_es2_profile;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_create_context_es_profile
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"create_context_es_profile", 25))
+ {
+ ret = GLXEW_EXT_create_context_es_profile;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_fbconfig_packed_float
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig_packed_float", 21))
+ {
+ ret = GLXEW_EXT_fbconfig_packed_float;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_framebuffer_sRGB
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"framebuffer_sRGB", 16))
+ {
+ ret = GLXEW_EXT_framebuffer_sRGB;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_import_context
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"import_context", 14))
+ {
+ ret = GLXEW_EXT_import_context;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_scene_marker
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"scene_marker", 12))
+ {
+ ret = GLXEW_EXT_scene_marker;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_swap_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12))
+ {
+ ret = GLXEW_EXT_swap_control;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_swap_control_tear
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control_tear", 17))
+ {
+ ret = GLXEW_EXT_swap_control_tear;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_texture_from_pixmap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"texture_from_pixmap", 19))
+ {
+ ret = GLXEW_EXT_texture_from_pixmap;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_visual_info
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_info", 11))
+ {
+ ret = GLXEW_EXT_visual_info;
+ continue;
+ }
+#endif
+#ifdef GLX_EXT_visual_rating
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_rating", 13))
+ {
+ ret = GLXEW_EXT_visual_rating;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"INTEL_", 6))
+ {
+#ifdef GLX_INTEL_swap_event
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_event", 10))
+ {
+ ret = GLXEW_INTEL_swap_event;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"MESA_", 5))
+ {
+#ifdef GLX_MESA_agp_offset
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"agp_offset", 10))
+ {
+ ret = GLXEW_MESA_agp_offset;
+ continue;
+ }
+#endif
+#ifdef GLX_MESA_copy_sub_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_sub_buffer", 15))
+ {
+ ret = GLXEW_MESA_copy_sub_buffer;
+ continue;
+ }
+#endif
+#ifdef GLX_MESA_pixmap_colormap
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pixmap_colormap", 15))
+ {
+ ret = GLXEW_MESA_pixmap_colormap;
+ continue;
+ }
+#endif
+#ifdef GLX_MESA_release_buffers
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"release_buffers", 15))
+ {
+ ret = GLXEW_MESA_release_buffers;
+ continue;
+ }
+#endif
+#ifdef GLX_MESA_set_3dfx_mode
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"set_3dfx_mode", 13))
+ {
+ ret = GLXEW_MESA_set_3dfx_mode;
+ continue;
+ }
+#endif
+#ifdef GLX_MESA_swap_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12))
+ {
+ ret = GLXEW_MESA_swap_control;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"NV_", 3))
+ {
+#ifdef GLX_NV_copy_image
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"copy_image", 10))
+ {
+ ret = GLXEW_NV_copy_image;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_float_buffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"float_buffer", 12))
+ {
+ ret = GLXEW_NV_float_buffer;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_multisample_coverage
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample_coverage", 20))
+ {
+ ret = GLXEW_NV_multisample_coverage;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_present_video
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"present_video", 13))
+ {
+ ret = GLXEW_NV_present_video;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_swap_group
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10))
+ {
+ ret = GLXEW_NV_swap_group;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_vertex_array_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"vertex_array_range", 18))
+ {
+ ret = GLXEW_NV_vertex_array_range;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_video_capture
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_capture", 13))
+ {
+ ret = GLXEW_NV_video_capture;
+ continue;
+ }
+#endif
+#ifdef GLX_NV_video_output
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_output", 12))
+ {
+ ret = GLXEW_NV_video_output;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"OML_", 4))
+ {
+#ifdef GLX_OML_swap_method
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_method", 11))
+ {
+ ret = GLXEW_OML_swap_method;
+ continue;
+ }
+#endif
+#ifdef GLX_OML_sync_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"sync_control", 12))
+ {
+ ret = GLXEW_OML_sync_control;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIS_", 5))
+ {
+#ifdef GLX_SGIS_blended_overlay
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"blended_overlay", 15))
+ {
+ ret = GLXEW_SGIS_blended_overlay;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIS_color_range
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"color_range", 11))
+ {
+ ret = GLXEW_SGIS_color_range;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIS_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"multisample", 11))
+ {
+ ret = GLXEW_SGIS_multisample;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIS_shared_multisample
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"shared_multisample", 18))
+ {
+ ret = GLXEW_SGIS_shared_multisample;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGIX_", 5))
+ {
+#ifdef GLX_SGIX_fbconfig
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"fbconfig", 8))
+ {
+ ret = GLXEW_SGIX_fbconfig;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIX_hyperpipe
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"hyperpipe", 9))
+ {
+ ret = GLXEW_SGIX_hyperpipe;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIX_pbuffer
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"pbuffer", 7))
+ {
+ ret = GLXEW_SGIX_pbuffer;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIX_swap_barrier
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_barrier", 12))
+ {
+ ret = GLXEW_SGIX_swap_barrier;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIX_swap_group
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_group", 10))
+ {
+ ret = GLXEW_SGIX_swap_group;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIX_video_resize
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_resize", 12))
+ {
+ ret = GLXEW_SGIX_video_resize;
+ continue;
+ }
+#endif
+#ifdef GLX_SGIX_visual_select_group
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"visual_select_group", 19))
+ {
+ ret = GLXEW_SGIX_visual_select_group;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SGI_", 4))
+ {
+#ifdef GLX_SGI_cushion
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"cushion", 7))
+ {
+ ret = GLXEW_SGI_cushion;
+ continue;
+ }
+#endif
+#ifdef GLX_SGI_make_current_read
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"make_current_read", 17))
+ {
+ ret = GLXEW_SGI_make_current_read;
+ continue;
+ }
+#endif
+#ifdef GLX_SGI_swap_control
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"swap_control", 12))
+ {
+ ret = GLXEW_SGI_swap_control;
+ continue;
+ }
+#endif
+#ifdef GLX_SGI_video_sync
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_sync", 10))
+ {
+ ret = GLXEW_SGI_video_sync;
+ continue;
+ }
+#endif
+ }
+ if (_glewStrSame2(&pos, &len, (const GLubyte*)"SUN_", 4))
+ {
+#ifdef GLX_SUN_get_transparent_index
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"get_transparent_index", 21))
+ {
+ ret = GLXEW_SUN_get_transparent_index;
+ continue;
+ }
+#endif
+#ifdef GLX_SUN_video_resize
+ if (_glewStrSame3(&pos, &len, (const GLubyte*)"video_resize", 12))
+ {
+ ret = GLXEW_SUN_video_resize;
+ continue;
+ }
+#endif
+ }
+ }
+ ret = (len == 0);
+ }
+ return ret;
+}
+
+#endif /* _WIN32 */
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/LICENSE b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/LICENSE
new file mode 100644
index 0000000000..3ab103c551
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/LICENSE
@@ -0,0 +1,16 @@
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/README.md b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/README.md
new file mode 100644
index 0000000000..7ff1008a39
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/README.md
@@ -0,0 +1,137 @@
+# Native File Dialog #
+
+A tiny, neat C library that portably invokes native file open and save dialogs. Write dialog code once and have it pop up native dialogs on all supported platforms. Avoid linking large dependencies like wxWidgets and qt.
+
+Features:
+
+ - Lean C API, static library -- no ObjC, no C++, no STL.
+ - Zlib licensed.
+ - Consistent UTF-8 support on all platforms.
+ - Simple universal file filter syntax.
+ - Paid support available.
+ - Multiple file selection support.
+ - 64-bit and 32-bit friendly.
+ - GCC, Clang and Visual Studio supported.
+ - No third party dependencies.
+ - Support for Vista's modern `IFileDialog` on Windows.
+ - Support for non-deprecated Cocoa APIs on OS X.
+ - GTK+3 dialog on Linux.
+ - Tested, works alongside [http://www.libsdl.org](SDL2) on all platforms, for the game developers out there.
+
+# Example Usage #
+
+```C
+#include <nfd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main( void )
+{
+ nfdchar_t *outPath = NULL;
+ nfdresult_t result = NFD_OpenDialog( NULL, NULL, &outPath );
+
+ if ( result == NFD_OKAY ) {
+ puts("Success!");
+ puts(outPath);
+ free(outPath);
+ }
+ else if ( result == NFD_CANCEL ) {
+ puts("User pressed cancel.");
+ }
+ else {
+ printf("Error: %s\n", NFD_GetError() );
+ }
+
+ return 0;
+}
+```
+
+See [NFD.h](src/include/nfd.h) for more options.
+
+# Screenshots #
+
+![Windows 8 rendering an IFileOpenDialog](screens/open_win8.png?raw=true)
+![GTK3 on Linux](screens/open_gtk3.png?raw=true)
+![Cocoa on Yosemite](screens/open_cocoa.png?raw=true)
+
+
+## Building ##
+
+NFD uses [SCons](http://www.scons.org) for cross-platform builds. After installing SCons, build it with:
+
+ cd src
+ scons debug=[0,1]
+
+Alternatively, you can avoid Scons by just including NFD files to your existing project:
+
+ 1. Add all header files in `src/` and `src/include` to your project.
+ 2. Add `src/include` to your include search path or copy it into your existing search path.
+ 3. Add `src/nfd_common.c` to your project.
+ 4. Add `src/nfd_<platform>` to your project, where `<platform>` is the NFD backend for the platform you are fixing to build.
+ 5. On Visual Studio, define `_CRT_SECURE_NO_WARNINGS` to avoid warnings.
+
+### Compiling Your Programs ###
+
+ 1. Add `src/include` to your include search path.
+ 2. Add `nfd.lib` to the list of list of static libraries to link against.
+ 3. Add `src/` to the library search path.
+
+On Linux, you must compile and link against GTK+. Recommend use of `pkg-config --cflags --libs gtk+-3.0`.
+
+On Mac OS X, add `AppKit` to the list of frameworks.
+
+On Windows, ensure you are building against `comctl32.lib`.
+
+## Usage ##
+
+See `NFD.h` for API calls. See `tests/*.c` for example code.
+
+See `tests/SConstruct` for a working build script that compiles on all platforms.
+
+## File Filter Syntax ##
+
+There is a form of file filtering in every file dialog, but no consistent means of supporting it. NFD provides support for filtering files by groups of extensions, providing its own descriptions (where applicable) for the extensions.
+
+A wildcard filter is always added to every dialog.
+
+### Separators ###
+
+ - `;` Begin a new filter.
+ - `,` Add a separate type to the filter.
+
+#### Examples ####
+
+`txt` The default filter is for text files. There is a wildcard option in a dropdown.
+
+`png,jpg;psd` The default filter is for png and jpg files. A second filter is available for psd files. There is a wildcard option in a dropdown.
+
+`NULL` Wildcard only.
+
+## Iterating Over PathSets ##
+
+See [test_opendialogmultiple.c](test/test_opendialogmultiple.c).
+
+# Known Limitations #
+
+I accept quality code patches, or will resolve these and other matters through support.
+
+ - No support for Windows XP's legacy dialogs such as `GetOpenFileName`.
+ - No support for file filter names -- ex: "Image Files" (*.png, *.jpg). Nameless filters are supported, though.
+ - No support for selecting folders instead of files.
+ - On Linux, GTK+ cannot be uninitialized to save memory. Launching a file dialog costs memory. I am open to accepting an alternative `nfd_zenity.c` implementation which uses Zenity and pipes.
+
+# Copyright and Credit #
+
+Copyright &copy; 2014 [Frogtoss Games](http://www.frogtoss.com), Inc.
+File [LICENSE](LICENSE) covers all files in this repo.
+
+Native File Dialog by Michael Labbe
+<mike@frogtoss.com>
+
+Tomasz Konojacki for [microutf8](http://puszcza.gnu.org.ua/software/microutf8/)
+
+## Support ##
+
+Directed support for this work is available from the original author under a paid agreement.
+
+[Contact Frogtoss Games](http://www.frogtoss.com/pages/contact.html).
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_cocoa.png b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_cocoa.png
new file mode 100644
index 0000000000..932306ebac
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_cocoa.png
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_gtk3.png b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_gtk3.png
new file mode 100644
index 0000000000..f835396e66
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_gtk3.png
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_win8.png b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_win8.png
new file mode 100644
index 0000000000..3ce0a5a3fa
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/screens/open_win8.png
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/SConstruct b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/SConstruct
new file mode 100644
index 0000000000..342fa1a3a8
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/SConstruct
@@ -0,0 +1,99 @@
+#
+# Native File Dialog
+#
+# Scons build script -- GCC, Clang, Visual Studio
+# Does not build test
+
+
+import os
+
+
+# target arch is build arch -- extend here for OS cross compiling
+target_os=str(Platform())
+
+# Corresponds to TARGET_ARCH set to environ.
+target_arch = ARGUMENTS.get('target_arch', None)
+
+# visual studio does not import from environment
+if target_os != 'win32':
+ IMPORT_FROM_ENV =['CC', 'CXX', 'CFLAGS', 'CXXFLAGS', 'ARFLAGS']
+else:
+ IMPORT_FROM_ENV =[]
+
+
+debug = int(ARGUMENTS.get( 'debug', 0 ))
+
+nfd_files = ['nfd_common.c']
+
+# Due to a Scons limitation, TARGET_ARCH cannot be appended to an existing environment.
+if target_arch != None:
+ nfd_env = Environment( TARGET_ARCH=target_arch )
+else:
+ nfd_env = Environment()
+
+# import specific environment variables from the command line, overriding
+# Scons environment defaults
+for env_key in IMPORT_FROM_ENV:
+ if env_key in os.environ:
+ print "Making %s => %s" % ( env_key, os.environ[env_key] )
+ nfd_env[env_key] = os.environ[env_key]
+
+# Windows runtime library types
+win_rtl = {'debug': '/MDd',
+ 'release': '/MD'}
+
+def set_debug(env):
+ if target_os == 'win32':
+ env.Append( CCFLAGS=['/Z7', # obj contains full symbols
+ win_rtl['debug']
+ ])
+ else:
+ env.Append( CFLAGS=['-g'] )
+
+
+def set_release(env):
+ if target_os == 'win32':
+ env.Append( CCFLAGS=[win_rtl['release'],
+ '/O2'] )
+ else:
+ env.Append( CFLAGS=['-O3'] )
+
+
+def set_warnings(env):
+ if target_os == 'win32':
+ env.Append( CCFLAGS=['/W3'],
+ CPPDEFINES=['_CRT_SECURE_NO_WARNINGS'] )
+ else:
+ env.Append( CFLAGS=['-Wall', '-pedantic'] )
+
+
+def get_lib_name(base, is_debug):
+ if is_debug:
+ return base + '_d'
+ else:
+ return base
+
+
+# Cocoa OS X builds - clang
+if target_os == 'darwin':
+ nfd_files.append('nfd_cocoa.m')
+ nfd_env.CC='clang -fcolor-diagnostics'
+
+# Linux GTK+ 3 builds - GCC
+elif target_os == 'posix':
+ nfd_files.append('nfd_gtk.c')
+ nfd_env.ParseConfig( 'pkg-config --cflags gtk+-3.0' )
+
+# Windows builds - Visual Studio
+elif target_os == 'win32':
+ nfd_files.append('nfd_win.cpp')
+
+if debug:
+ set_debug(nfd_env)
+else:
+ set_release(nfd_env)
+
+set_warnings(nfd_env)
+
+nfd_env.Append( CPPPATH=['.','./include'] )
+nfd_env.StaticLibrary( get_lib_name('nfd', debug), nfd_files )
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/common.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/common.h
new file mode 100644
index 0000000000..688b0b1fdc
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/common.h
@@ -0,0 +1,21 @@
+/*
+ Native File Dialog
+
+ Internal, common across platforms
+
+ http://www.frogtoss.com/labs
+ */
+
+
+#ifndef _NFD_COMMON_H
+#define _NFD_COMMON_H
+
+#define NFD_MAX_STRLEN 256
+#define _NFD_UNUSED(x) ((void)x)
+
+void *NFDi_Malloc( size_t bytes );
+void NFDi_Free( void *ptr );
+void NFDi_SetError( const char *msg );
+void NFDi_SafeStrncpy( char *dst, const char *src, size_t maxCopy );
+
+#endif
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/include/nfd.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/include/nfd.h
new file mode 100644
index 0000000000..03fe532069
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/include/nfd.h
@@ -0,0 +1,69 @@
+/*
+ Native File Dialog
+
+ User API
+
+ http://www.frogtoss.com/labs
+ */
+
+
+#ifndef _NFD_H
+#define _NFD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+
+/* denotes UTF-8 char */
+typedef char nfdchar_t;
+
+/* opaque data structure -- see NFD_PathSet_* */
+typedef struct {
+ nfdchar_t *buf;
+ size_t *indices; /* byte offsets into buf */
+ size_t count; /* number of indices into buf */
+}nfdpathset_t;
+
+typedef enum {
+ NFD_ERROR, /* programmatic error */
+ NFD_OKAY, /* user pressed okay, or successful return */
+ NFD_CANCEL /* user pressed cancel */
+}nfdresult_t;
+
+
+/* nfd_<targetplatform>.c */
+
+/* single file open dialog */
+nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList,
+ const nfdchar_t *defaultPath,
+ nfdchar_t **outPath );
+
+/* multiple file open dialog */
+nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
+ const nfdchar_t *defaultPath,
+ nfdpathset_t *outPaths );
+
+/* save dialog */
+nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
+ const nfdchar_t *defaultPath,
+ nfdchar_t **outPath );
+
+/* nfd_common.c */
+
+/* get last error -- set when nfdresult_t returns NFD_ERROR */
+const char *NFD_GetError( void );
+/* get the number of entries stored in pathSet */
+size_t NFD_PathSet_GetCount( const nfdpathset_t *pathSet );
+/* Get the UTF-8 path at offset index */
+nfdchar_t *NFD_PathSet_GetPath( const nfdpathset_t *pathSet, size_t index );
+/* Free the pathSet */
+void NFD_PathSet_Free( nfdpathset_t *pathSet );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_cocoa.m b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_cocoa.m
new file mode 100644
index 0000000000..a73e15714a
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_cocoa.m
@@ -0,0 +1,235 @@
+/*
+ Native File Dialog
+
+ http://www.frogtoss.com/labs
+ */
+
+#include <AppKit/AppKit.h>
+#include "nfd.h"
+#include "nfd_common.h"
+
+static NSArray *BuildAllowedFileTypes( const char *filterList )
+{
+ // Commas and semicolons are the same thing on this platform
+
+ NSMutableArray *buildFilterList = [[NSMutableArray alloc] init];
+
+ char typebuf[NFD_MAX_STRLEN] = {0};
+
+ size_t filterListLen = strlen(filterList);
+ char *p_typebuf = typebuf;
+ for ( size_t i = 0; i < filterListLen+1; ++i )
+ {
+ if ( filterList[i] == ',' || filterList[i] == ';' || filterList[i] == '\0' )
+ {
+ ++p_typebuf;
+ *p_typebuf = '\0';
+ NSString *thisType = [NSString stringWithUTF8String: typebuf];
+ [buildFilterList addObject:thisType];
+ p_typebuf = typebuf;
+ *p_typebuf = '\0';
+ }
+ else
+ {
+ *p_typebuf = filterList[i];
+ ++p_typebuf;
+
+ }
+ }
+
+ NSArray *returnArray = [NSArray arrayWithArray:buildFilterList];
+
+ [buildFilterList release];
+ return returnArray;
+}
+
+static void AddFilterListToDialog( NSSavePanel *dialog, const char *filterList )
+{
+ if ( !filterList || strlen(filterList) == 0 )
+ return;
+
+ NSArray *allowedFileTypes = BuildAllowedFileTypes( filterList );
+ if ( [allowedFileTypes count] != 0 )
+ {
+ [dialog setAllowedFileTypes:allowedFileTypes];
+ }
+}
+
+static void SetDefaultPath( NSSavePanel *dialog, const nfdchar_t *defaultPath )
+{
+ if ( !defaultPath || strlen(defaultPath) == 0 )
+ return;
+
+ NSString *defaultPathString = [NSString stringWithUTF8String: defaultPath];
+ NSURL *url = [NSURL fileURLWithPath:defaultPathString isDirectory:YES];
+ [dialog setDirectoryURL:url];
+}
+
+
+/* fixme: pathset should be pathSet */
+static nfdresult_t AllocPathSet( NSArray *urls, nfdpathset_t *pathset )
+{
+ assert(pathset);
+ assert([urls count]);
+
+ pathset->count = (size_t)[urls count];
+ pathset->indices = NFDi_Malloc( sizeof(size_t)*pathset->count );
+ if ( !pathset->indices )
+ {
+ return NFD_ERROR;
+ }
+
+ // count the total space needed for buf
+ size_t bufsize = 0;
+ for ( NSURL *url in urls )
+ {
+ NSString *path = [url path];
+ bufsize += [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1;
+ }
+
+ pathset->buf = NFDi_Malloc( sizeof(nfdchar_t) * bufsize );
+ if ( !pathset->buf )
+ {
+ return NFD_ERROR;
+ }
+
+ // fill buf
+ nfdchar_t *p_buf = pathset->buf;
+ size_t count = 0;
+ for ( NSURL *url in urls )
+ {
+ NSString *path = [url path];
+ const nfdchar_t *utf8Path = [path UTF8String];
+ size_t byteLen = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1;
+ memcpy( p_buf, utf8Path, byteLen );
+
+ ptrdiff_t index = p_buf - pathset->buf;
+ assert( index >= 0 );
+ pathset->indices[count] = (size_t)index;
+
+ p_buf += byteLen;
+ ++count;
+ }
+
+ return NFD_OKAY;
+}
+
+/* public */
+
+
+nfdresult_t NFD_OpenDialog( const char *filterList,
+ const nfdchar_t *defaultPath,
+ nfdchar_t **outPath )
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ NSOpenPanel *dialog = [NSOpenPanel openPanel];
+ [dialog setAllowsMultipleSelection:NO];
+
+ // Build the filter list
+ AddFilterListToDialog(dialog, filterList);
+
+ // Set the starting directory
+ SetDefaultPath(dialog, defaultPath);
+
+ nfdresult_t nfdResult = NFD_CANCEL;
+ if ( [dialog runModal] == NSModalResponseOK )
+ {
+ NSURL *url = [dialog URL];
+ const char *utf8Path = [[url path] UTF8String];
+
+ // byte count, not char count
+ size_t len = strlen(utf8Path);//NFDi_UTF8_Strlen(utf8Path);
+
+ *outPath = NFDi_Malloc( len+1 );
+ if ( !*outPath )
+ {
+ [pool release];
+ return NFD_ERROR;
+ }
+ memcpy( *outPath, utf8Path, len+1 ); /* copy null term */
+ nfdResult = NFD_OKAY;
+ }
+ [pool release];
+
+ return nfdResult;
+}
+
+
+nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
+ const nfdchar_t *defaultPath,
+ nfdpathset_t *outPaths )
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ NSOpenPanel *dialog = [NSOpenPanel openPanel];
+ [dialog setAllowsMultipleSelection:YES];
+
+ // Build the fiter list.
+ AddFilterListToDialog(dialog, filterList);
+
+ // Set the starting directory
+ SetDefaultPath(dialog, defaultPath);
+
+ nfdresult_t nfdResult = NFD_CANCEL;
+ if ( [dialog runModal] == NSModalResponseOK )
+ {
+ NSArray *urls = [dialog URLs];
+
+ if ( [urls count] == 0 )
+ {
+ [pool release];
+ return NFD_CANCEL;
+ }
+
+ if ( AllocPathSet( urls, outPaths ) == NFD_ERROR )
+ {
+ [pool release];
+ return NFD_ERROR;
+ }
+
+ nfdResult = NFD_OKAY;
+ }
+ [pool release];
+
+ return nfdResult;
+}
+
+
+nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
+ const nfdchar_t *defaultPath,
+ nfdchar_t **outPath )
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ NSSavePanel *dialog = [NSSavePanel savePanel];
+ [dialog setExtensionHidden:NO];
+
+ // Build the filter list.
+ AddFilterListToDialog(dialog, filterList);
+
+ // Set the starting directory
+ SetDefaultPath(dialog, defaultPath);
+
+ nfdresult_t nfdResult = NFD_CANCEL;
+ if ( [dialog runModal] == NSModalResponseOK )
+ {
+ NSURL *url = [dialog URL];
+ const char *utf8Path = [[url path] UTF8String];
+
+ size_t byteLen = [url.path lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1;
+
+ *outPath = NFDi_Malloc( byteLen );
+ if ( !*outPath )
+ {
+ [pool release];
+ return NFD_ERROR;
+ }
+ memcpy( *outPath, utf8Path, byteLen );
+ nfdResult = NFD_OKAY;
+ }
+
+ [pool release];
+
+ return nfdResult;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_common.c b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_common.c
new file mode 100644
index 0000000000..269fbd2135
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_common.c
@@ -0,0 +1,142 @@
+/*
+ Native File Dialog
+
+ http://www.frogtoss.com/labs
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "nfd_common.h"
+
+static char g_errorstr[NFD_MAX_STRLEN] = {0};
+
+/* public routines */
+
+const char *NFD_GetError( void )
+{
+ return g_errorstr;
+}
+
+size_t NFD_PathSet_GetCount( const nfdpathset_t *pathset )
+{
+ assert(pathset);
+ return pathset->count;
+}
+
+nfdchar_t *NFD_PathSet_GetPath( const nfdpathset_t *pathset, size_t num )
+{
+ assert(pathset);
+ assert(num < pathset->count);
+
+ return pathset->buf + pathset->indices[num];
+}
+
+void NFD_PathSet_Free( nfdpathset_t *pathset )
+{
+ assert(pathset);
+ NFDi_Free( pathset->indices );
+ NFDi_Free( pathset->buf );
+}
+
+/* internal routines */
+
+void *NFDi_Malloc( size_t bytes )
+{
+ void *ptr = malloc(bytes);
+ if ( !ptr )
+ NFDi_SetError("NFDi_Malloc failed.");
+
+ return ptr;
+}
+
+void NFDi_Free( void *ptr )
+{
+ assert(ptr);
+ free(ptr);
+}
+
+void NFDi_SetError( const char *msg )
+{
+ int bTruncate = NFDi_SafeStrncpy( g_errorstr, msg, NFD_MAX_STRLEN );
+ assert( !bTruncate ); _NFD_UNUSED(bTruncate);
+}
+
+
+int NFDi_SafeStrncpy( char *dst, const char *src, size_t maxCopy )
+{
+ size_t n = maxCopy;
+ char *d = dst;
+
+ assert( src );
+ assert( dst );
+
+ while ( n > 0 && *src != '\0' )
+ {
+ *d++ = *src++;
+ --n;
+ }
+
+ /* Truncation case -
+ terminate string and return true */
+ if ( n == 0 )
+ {
+ dst[maxCopy-1] = '\0';
+ return 1;
+ }
+
+ /* No truncation. Append a single NULL and return. */
+ *d = '\0';
+ return 0;
+}
+
+
+/* adapted from microutf8 */
+size_t NFDi_UTF8_Strlen( const nfdchar_t *str )
+{
+ /* This function doesn't properly check validity of UTF-8 character
+ sequence, it is supposed to use only with valid UTF-8 strings. */
+
+ size_t character_count = 0;
+ size_t i = 0; /* Counter used to iterate over string. */
+ nfdchar_t maybe_bom[4];
+
+ /* If there is UTF-8 BOM ignore it. */
+ if (strlen(str) > 2)
+ {
+ strncpy(maybe_bom, str, 3);
+ maybe_bom[3] = 0;
+ if (strcmp(maybe_bom, (nfdchar_t*)NFD_UTF8_BOM) == 0)
+ i += 3;
+ }
+
+ while(str[i])
+ {
+ if (str[i] >> 7 == 0)
+ {
+ /* If bit pattern begins with 0 we have ascii character. */
+ ++character_count;
+ }
+ else if (str[i] >> 6 == 3)
+ {
+ /* If bit pattern begins with 11 it is beginning of UTF-8 byte sequence. */
+ ++character_count;
+ }
+ else if (str[i] >> 6 == 2)
+ ; /* If bit pattern begins with 10 it is middle of utf-8 byte sequence. */
+ else
+ {
+ /* In any other case this is not valid UTF-8. */
+ return -1;
+ }
+ ++i;
+ }
+
+ return character_count;
+}
+
+int NFDi_IsFilterSegmentChar( char ch )
+{
+ return (ch==','||ch==';'||ch=='\0');
+}
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_common.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_common.h
new file mode 100644
index 0000000000..a3f6b4ad64
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_common.h
@@ -0,0 +1,37 @@
+/*
+ Native File Dialog
+
+ Internal, common across platforms
+
+ http://www.frogtoss.com/labs
+ */
+
+
+#ifndef _NFD_COMMON_H
+#define _NFD_COMMON_H
+
+#include "nfd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NFD_MAX_STRLEN 256
+#define _NFD_UNUSED(x) ((void)x)
+
+#define NFD_UTF8_BOM "\xEF\xBB\xBF"
+
+
+void *NFDi_Malloc( size_t bytes );
+void NFDi_Free( void *ptr );
+void NFDi_SetError( const char *msg );
+int NFDi_SafeStrncpy( char *dst, const char *src, size_t maxCopy );
+size_t NFDi_UTF8_Strlen( const nfdchar_t *str );
+int NFDi_IsFilterSegmentChar( char ch );
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_gtk.c b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_gtk.c
new file mode 100644
index 0000000000..2d7b9b5f6e
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_gtk.c
@@ -0,0 +1,326 @@
+/*
+ Native File Dialog
+
+ http://www.frogtoss.com/labs
+*/
+
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include "nfd.h"
+#include "nfd_common.h"
+
+
+const char INIT_FAIL_MSG[] = "gtk_init_check failed to initilaize GTK+";
+
+
+static void AddTypeToFilterName( const char *typebuf, char *filterName, size_t bufsize )
+{
+ const char SEP[] = ", ";
+
+ size_t len = strlen(filterName);
+ if ( len != 0 )
+ {
+ strncat( filterName, SEP, bufsize - len - 1 );
+ len += strlen(SEP);
+ }
+
+ strncat( filterName, typebuf, bufsize - len - 1 );
+}
+
+static void AddFiltersToDialog( GtkWidget *dialog, const char *filterList )
+{
+ GtkFileFilter *filter;
+ char typebuf[NFD_MAX_STRLEN] = {0};
+ const char *p_filterList = filterList;
+ char *p_typebuf = typebuf;
+ char filterName[NFD_MAX_STRLEN] = {0};
+
+ if ( !filterList || strlen(filterList) == 0 )
+ return;
+
+ filter = gtk_file_filter_new();
+ while ( 1 )
+ {
+
+ if ( NFDi_IsFilterSegmentChar(*p_filterList) )
+ {
+ char typebufWildcard[NFD_MAX_STRLEN];
+ /* add another type to the filter */
+ assert( strlen(typebuf) > 0 );
+ assert( strlen(typebuf) < NFD_MAX_STRLEN-1 );
+
+ snprintf( typebufWildcard, NFD_MAX_STRLEN, "*.%s", typebuf );
+ AddTypeToFilterName( typebuf, filterName, NFD_MAX_STRLEN );
+
+ gtk_file_filter_add_pattern( filter, typebufWildcard );
+
+ p_typebuf = typebuf;
+ memset( typebuf, 0, sizeof(char) * NFD_MAX_STRLEN );
+ }
+
+ if ( *p_filterList == ';' || *p_filterList == '\0' )
+ {
+ /* end of filter -- add it to the dialog */
+
+ gtk_file_filter_set_name( filter, filterName );
+ gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(dialog), filter );
+
+ filterName[0] = '\0';
+
+ if ( *p_filterList == '\0' )
+ break;
+
+ filter = gtk_file_filter_new();
+ }
+
+ if ( !NFDi_IsFilterSegmentChar( *p_filterList ) )
+ {
+ *p_typebuf = *p_filterList;
+ p_typebuf++;
+ }
+
+ p_filterList++;
+ }
+
+ /* always append a wildcard option to the end*/
+
+ filter = gtk_file_filter_new();
+ gtk_file_filter_set_name( filter, "*.*" );
+ gtk_file_filter_add_pattern( filter, "*" );
+ gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(dialog), filter );
+}
+
+static void SetDefaultPath( GtkWidget *dialog, const char *defaultPath )
+{
+ if ( !defaultPath || strlen(defaultPath) == 0 )
+ return;
+
+ /* GTK+ manual recommends not specifically setting the default path.
+ We do it anyway in order to be consistent across platforms.
+
+ If consistency with the native OS is preferred, this is the line
+ to comment out. -ml */
+ gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(dialog), defaultPath );
+}
+
+static nfdresult_t AllocPathSet( GSList *fileList, nfdpathset_t *pathSet )
+{
+ size_t bufSize = 0;
+ GSList *node;
+ nfdchar_t *p_buf;
+ size_t count = 0;
+
+ assert(fileList);
+ assert(pathSet);
+
+ pathSet->count = (size_t)g_slist_length( fileList );
+ assert( pathSet->count > 0 );
+
+ pathSet->indices = NFDi_Malloc( sizeof(size_t)*pathSet->count );
+ if ( !pathSet->indices )
+ {
+ return NFD_ERROR;
+ }
+
+ /* count the total space needed for buf */
+ for ( node = fileList; node; node = node->next )
+ {
+ assert(node->data);
+ bufSize += strlen( (const gchar*)node->data ) + 1;
+ }
+
+ pathSet->buf = NFDi_Malloc( sizeof(nfdchar_t) * bufSize );
+
+ /* fill buf */
+ p_buf = pathSet->buf;
+ for ( node = fileList; node; node = node->next )
+ {
+ nfdchar_t *path = (nfdchar_t*)(node->data);
+ size_t byteLen = strlen(path)+1;
+ ptrdiff_t index;
+
+ memcpy( p_buf, path, byteLen );
+ g_free(node->data);
+
+ index = p_buf - pathSet->buf;
+ assert( index >= 0 );
+ pathSet->indices[count] = (size_t)index;
+
+ p_buf += byteLen;
+ ++count;
+ }
+
+ g_slist_free( fileList );
+
+ return NFD_OKAY;
+}
+
+static void WaitForCleanup(void)
+{
+ while (gtk_events_pending())
+ gtk_main_iteration();
+}
+
+/* public */
+
+nfdresult_t NFD_OpenDialog( const char *filterList,
+ const nfdchar_t *defaultPath,
+ nfdchar_t **outPath )
+{
+ GtkWidget *dialog;
+ nfdresult_t result;
+
+ if ( !gtk_init_check( NULL, NULL ) )
+ {
+ NFDi_SetError(INIT_FAIL_MSG);
+ return NFD_ERROR;
+ }
+
+ dialog = gtk_file_chooser_dialog_new( "Open File",
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ "_Cancel", GTK_RESPONSE_CANCEL,
+ "_Open", GTK_RESPONSE_ACCEPT,
+ NULL );
+
+ /* Build the filter list */
+ AddFiltersToDialog(dialog, filterList);
+
+ /* Set the default path */
+ SetDefaultPath(dialog, defaultPath);
+
+ result = NFD_CANCEL;
+ if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
+ {
+ char *filename;
+
+ filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) );
+
+ {
+ size_t len = strlen(filename);
+ *outPath = NFDi_Malloc( len + 1 );
+ memcpy( *outPath, filename, len + 1 );
+ if ( !*outPath )
+ {
+ g_free( filename );
+ gtk_widget_destroy(dialog);
+ return NFD_ERROR;
+ }
+ }
+ g_free( filename );
+
+ result = NFD_OKAY;
+ }
+
+ WaitForCleanup();
+ gtk_widget_destroy(dialog);
+ WaitForCleanup();
+
+ return result;
+}
+
+
+nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
+ const nfdchar_t *defaultPath,
+ nfdpathset_t *outPaths )
+{
+ GtkWidget *dialog;
+ nfdresult_t result;
+
+ if ( !gtk_init_check( NULL, NULL ) )
+ {
+ NFDi_SetError(INIT_FAIL_MSG);
+ return NFD_ERROR;
+ }
+
+ dialog = gtk_file_chooser_dialog_new( "Open Files",
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ "_Cancel", GTK_RESPONSE_CANCEL,
+ "_Open", GTK_RESPONSE_ACCEPT,
+ NULL );
+ gtk_file_chooser_set_select_multiple( GTK_FILE_CHOOSER(dialog), TRUE );
+
+ /* Build the filter list */
+ AddFiltersToDialog(dialog, filterList);
+
+ /* Set the default path */
+ SetDefaultPath(dialog, defaultPath);
+
+ result = NFD_CANCEL;
+ if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
+ {
+ GSList *fileList = gtk_file_chooser_get_filenames( GTK_FILE_CHOOSER(dialog) );
+ if ( AllocPathSet( fileList, outPaths ) == NFD_ERROR )
+ {
+ gtk_widget_destroy(dialog);
+ return NFD_ERROR;
+ }
+
+ result = NFD_OKAY;
+ }
+
+ WaitForCleanup();
+ gtk_widget_destroy(dialog);
+ WaitForCleanup();
+
+ return result;
+}
+
+nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
+ const nfdchar_t *defaultPath,
+ nfdchar_t **outPath )
+{
+ GtkWidget *dialog;
+ nfdresult_t result;
+
+ if ( !gtk_init_check( NULL, NULL ) )
+ {
+ NFDi_SetError(INIT_FAIL_MSG);
+ return NFD_ERROR;
+ }
+
+ dialog = gtk_file_chooser_dialog_new( "Save File",
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ "_Cancel", GTK_RESPONSE_CANCEL,
+ "_Save", GTK_RESPONSE_ACCEPT,
+ NULL );
+ gtk_file_chooser_set_do_overwrite_confirmation( GTK_FILE_CHOOSER(dialog), TRUE );
+
+ /* Build the filter list */
+ AddFiltersToDialog(dialog, filterList);
+
+ /* Set the default path */
+ SetDefaultPath(dialog, defaultPath);
+
+ result = NFD_CANCEL;
+ if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
+ {
+ char *filename;
+ filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) );
+
+ {
+ size_t len = strlen(filename);
+ *outPath = NFDi_Malloc( len + 1 );
+ memcpy( *outPath, filename, len + 1 );
+ if ( !*outPath )
+ {
+ g_free( filename );
+ gtk_widget_destroy(dialog);
+ return NFD_ERROR;
+ }
+ }
+ g_free(filename);
+
+ result = NFD_OKAY;
+ }
+
+ WaitForCleanup();
+ gtk_widget_destroy(dialog);
+ WaitForCleanup();
+
+ return result;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_win.cpp b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_win.cpp
new file mode 100644
index 0000000000..b065d69cb7
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/src/nfd_win.cpp
@@ -0,0 +1,619 @@
+/*
+ Native File Dialog
+
+ http://www.frogtoss.com/labs
+ */
+
+/* only locally define UNICODE in this compilation unit */
+#ifndef UNICODE
+#define UNICODE
+#endif
+
+
+#include <wchar.h>
+#include <stdio.h>
+#include <assert.h>
+#include <atlbase.h>
+#include <windows.h>
+#include <ShObjIdl.h>
+
+#include "nfd_common.h"
+
+
+// allocs the space in outPath -- call free()
+static void CopyWCharToNFDChar( const wchar_t *inStr, nfdchar_t **outStr )
+{
+ int inStrCharacterCount = static_cast<int>(wcslen(inStr));
+ int bytesNeeded = WideCharToMultiByte( CP_UTF8, 0,
+ inStr, inStrCharacterCount,
+ NULL, 0, NULL, NULL );
+ assert( bytesNeeded );
+ bytesNeeded += 1;
+
+ *outStr = (nfdchar_t*)NFDi_Malloc( bytesNeeded );
+ if ( !*outStr )
+ return;
+
+ int bytesWritten = WideCharToMultiByte( CP_UTF8, 0,
+ inStr, -1,
+ *outStr, bytesNeeded,
+ NULL, NULL );
+ assert( bytesWritten ); _NFD_UNUSED( bytesWritten );
+}
+
+/* includes NULL terminator byte in return */
+static size_t GetUTF8ByteCountForWChar( const wchar_t *str )
+{
+ int bytesNeeded = WideCharToMultiByte( CP_UTF8, 0,
+ str, -1,
+ NULL, 0, NULL, NULL );
+ assert( bytesNeeded );
+ return bytesNeeded+1;
+}
+
+// write to outPtr -- no free() necessary. No memory stomp tests are done -- they must be done
+// before entering this function.
+static int CopyWCharToExistingNFDCharBuffer( const wchar_t *inStr, nfdchar_t *outPtr )
+{
+ int inStrCharacterCount = static_cast<int>(wcslen(inStr));
+ int bytesNeeded = static_cast<int>(GetUTF8ByteCountForWChar( inStr ));
+
+ /* invocation copies null term */
+ int bytesWritten = WideCharToMultiByte( CP_UTF8, 0,
+ inStr, -1,
+ outPtr, bytesNeeded,
+ NULL, 0 );
+ assert( bytesWritten );
+
+ return bytesWritten;
+
+}
+
+
+// allocs the space in outStr -- call free()
+static void CopyNFDCharToWChar( const nfdchar_t *inStr, wchar_t **outStr )
+{
+ int inStrByteCount = static_cast<int>(strlen(inStr));
+ int charsNeeded = MultiByteToWideChar(CP_UTF8, 0,
+ inStr, inStrByteCount,
+ NULL, 0 );
+ assert( charsNeeded );
+ assert( !*outStr );
+ charsNeeded += 1; // terminator
+
+ *outStr = (wchar_t*)NFDi_Malloc( charsNeeded * sizeof(wchar_t) );
+ if ( !*outStr )
+ return;
+
+ int ret = MultiByteToWideChar(CP_UTF8, 0,
+ inStr, inStrByteCount,
+ *outStr, charsNeeded);
+ (*outStr)[charsNeeded-1] = '\0';
+
+#ifdef _DEBUG
+ int inStrCharacterCount = static_cast<int>(NFDi_UTF8_Strlen(inStr));
+ assert( ret == inStrCharacterCount );
+#else
+ _NFD_UNUSED(ret);
+#endif
+}
+
+
+/* ext is in format "jpg", no wildcards or separators */
+static int AppendExtensionToSpecBuf( const char *ext, char *specBuf, size_t specBufLen )
+{
+ const char SEP[] = ";";
+ assert( specBufLen > strlen(ext)+3 );
+
+ if ( strlen(specBuf) > 0 )
+ {
+ strncat( specBuf, SEP, specBufLen - strlen(specBuf) - 1 );
+ specBufLen += strlen(SEP);
+ }
+
+ char extWildcard[NFD_MAX_STRLEN];
+ int bytesWritten = sprintf_s( extWildcard, NFD_MAX_STRLEN, "*.%s", ext );
+ assert( bytesWritten == strlen(ext)+2 );
+
+ strncat( specBuf, extWildcard, specBufLen - strlen(specBuf) - 1 );
+
+ return NFD_OKAY;
+}
+
+static nfdresult_t AddFiltersToDialog( ::IFileDialog *fileOpenDialog, const char *filterList )
+{
+ const wchar_t EMPTY_WSTR[] = L"";
+ const wchar_t WILDCARD[] = L"*.*";
+
+ if ( !filterList || strlen(filterList) == 0 )
+ return NFD_OKAY;
+
+ // Count rows to alloc
+ UINT filterCount = 1; /* guaranteed to have one filter on a correct, non-empty parse */
+ const char *p_filterList;
+ for ( p_filterList = filterList; *p_filterList; ++p_filterList )
+ {
+ if ( *p_filterList == ';' )
+ ++filterCount;
+ }
+
+ assert(filterCount);
+ if ( !filterCount )
+ {
+ NFDi_SetError("Error parsing filters.");
+ return NFD_ERROR;
+ }
+
+ /* filterCount plus 1 because we hardcode the *.* wildcard after the while loop */
+ COMDLG_FILTERSPEC *specList = (COMDLG_FILTERSPEC*)NFDi_Malloc( sizeof(COMDLG_FILTERSPEC) * (filterCount + 1) );
+ if ( !specList )
+ {
+ return NFD_ERROR;
+ }
+ for (size_t i = 0; i < filterCount+1; ++i )
+ {
+ specList[i].pszName = NULL;
+ specList[i].pszSpec = NULL;
+ }
+
+ size_t specIdx = 0;
+ p_filterList = filterList;
+ char typebuf[NFD_MAX_STRLEN] = {0}; /* one per comma or semicolon */
+ char *p_typebuf = typebuf;
+ char filterName[NFD_MAX_STRLEN] = {0};
+
+ char specbuf[NFD_MAX_STRLEN] = {0}; /* one per semicolon */
+
+ while ( 1 )
+ {
+ if ( NFDi_IsFilterSegmentChar(*p_filterList) )
+ {
+ /* append a type to the specbuf (pending filter) */
+ AppendExtensionToSpecBuf( typebuf, specbuf, NFD_MAX_STRLEN );
+
+ p_typebuf = typebuf;
+ memset( typebuf, 0, sizeof(char)*NFD_MAX_STRLEN );
+ }
+
+ if ( *p_filterList == ';' || *p_filterList == '\0' )
+ {
+ /* end of filter -- add it to specList */
+
+ // Empty filter name -- Windows describes them by extension.
+ specList[specIdx].pszName = EMPTY_WSTR;
+ CopyNFDCharToWChar( specbuf, (wchar_t**)&specList[specIdx].pszSpec );
+
+ memset( specbuf, 0, sizeof(char)*NFD_MAX_STRLEN );
+ ++specIdx;
+ if ( specIdx == filterCount )
+ break;
+ }
+
+ if ( !NFDi_IsFilterSegmentChar( *p_filterList ))
+ {
+ *p_typebuf = *p_filterList;
+ ++p_typebuf;
+ }
+
+ ++p_filterList;
+ }
+
+ /* Add wildcard */
+ specList[specIdx].pszSpec = WILDCARD;
+ specList[specIdx].pszName = EMPTY_WSTR;
+
+ fileOpenDialog->SetFileTypes( filterCount+1, specList );
+
+ /* free speclist */
+ for ( size_t i = 0; i < filterCount; ++i )
+ {
+ NFDi_Free( (void*)specList[i].pszSpec );
+ }
+ NFDi_Free( specList );
+
+ return NFD_OKAY;
+}
+
+static nfdresult_t AllocPathSet( IShellItemArray *shellItems, nfdpathset_t *pathSet )
+{
+ const char ERRORMSG[] = "Error allocating pathset.";
+
+ assert(shellItems);
+ assert(pathSet);
+
+ // How many items in shellItems?
+ DWORD numShellItems;
+ HRESULT result = shellItems->GetCount(&numShellItems);
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError(ERRORMSG);
+ return NFD_ERROR;
+ }
+
+ pathSet->count = static_cast<size_t>(numShellItems);
+ assert( pathSet->count > 0 );
+
+ pathSet->indices = (size_t*)NFDi_Malloc( sizeof(size_t)*pathSet->count );
+ if ( !pathSet->indices )
+ {
+ return NFD_ERROR;
+ }
+
+ /* count the total bytes needed for buf */
+ size_t bufSize = 0;
+ for ( DWORD i = 0; i < numShellItems; ++i )
+ {
+ ::IShellItem *shellItem;
+ result = shellItems->GetItemAt(i, &shellItem);
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError(ERRORMSG);
+ return NFD_ERROR;
+ }
+
+ // Confirm SFGAO_FILESYSTEM is true for this shellitem, or ignore it.
+ SFGAOF attribs;
+ result = shellItem->GetAttributes( SFGAO_FILESYSTEM, &attribs );
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError(ERRORMSG);
+ return NFD_ERROR;
+ }
+ if ( !(attribs & SFGAO_FILESYSTEM) )
+ continue;
+
+ LPWSTR name;
+ shellItem->GetDisplayName(SIGDN_FILESYSPATH, &name);
+
+ // Calculate length of name with UTF-8 encoding
+ bufSize += GetUTF8ByteCountForWChar( name );
+ }
+
+ assert(bufSize);
+
+ pathSet->buf = (nfdchar_t*)NFDi_Malloc( sizeof(nfdchar_t) * bufSize );
+ memset( pathSet->buf, 0, sizeof(nfdchar_t) * bufSize );
+
+ /* fill buf */
+ nfdchar_t *p_buf = pathSet->buf;
+ for (DWORD i = 0; i < numShellItems; ++i )
+ {
+ ::IShellItem *shellItem;
+ result = shellItems->GetItemAt(i, &shellItem);
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError(ERRORMSG);
+ return NFD_ERROR;
+ }
+
+ // Confirm SFGAO_FILESYSTEM is true for this shellitem, or ignore it.
+ SFGAOF attribs;
+ result = shellItem->GetAttributes( SFGAO_FILESYSTEM, &attribs );
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError(ERRORMSG);
+ return NFD_ERROR;
+ }
+ if ( !(attribs & SFGAO_FILESYSTEM) )
+ continue;
+
+ LPWSTR name;
+ shellItem->GetDisplayName(SIGDN_FILESYSPATH, &name);
+
+ int bytesWritten = CopyWCharToExistingNFDCharBuffer(name, p_buf);
+
+ ptrdiff_t index = p_buf - pathSet->buf;
+ assert( index >= 0 );
+ pathSet->indices[i] = static_cast<size_t>(index);
+
+ p_buf += bytesWritten;
+ }
+
+ return NFD_OKAY;
+}
+
+
+static nfdresult_t SetDefaultPath( IFileDialog *dialog, const char *defaultPath )
+{
+ if ( !defaultPath || strlen(defaultPath) == 0 )
+ return NFD_OKAY;
+
+ wchar_t *defaultPathW = {0};
+ CopyNFDCharToWChar( defaultPath, &defaultPathW );
+
+ IShellItem *folder;
+ HRESULT result = SHCreateItemFromParsingName( defaultPathW, NULL, IID_PPV_ARGS(&folder) );
+
+ // Valid non results.
+ if ( result == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || result == HRESULT_FROM_WIN32(ERROR_INVALID_DRIVE) )
+ {
+ NFDi_Free( defaultPathW );
+ return NFD_OKAY;
+ }
+
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError("Error creating ShellItem");
+ NFDi_Free( defaultPathW );
+ return NFD_ERROR;
+ }
+
+ // Could also call SetDefaultFolder(), but this guarantees defaultPath -- more consistency across API.
+ dialog->SetFolder( folder );
+
+ NFDi_Free( defaultPathW );
+ folder->Release();
+
+ return NFD_OKAY;
+}
+
+/* public */
+
+
+nfdresult_t NFD_OpenDialog( const char *filterList,
+ const nfdchar_t *defaultPath,
+ nfdchar_t **outPath )
+{
+ nfdresult_t nfdResult = NFD_ERROR;
+
+ // Init COM library.
+ HRESULT result = ::CoInitializeEx(NULL,
+ ::COINIT_APARTMENTTHREADED |
+ ::COINIT_DISABLE_OLE1DDE );
+ if ( !SUCCEEDED(result))
+ {
+ NFDi_SetError("Could not initialize COM.");
+ goto end;
+ }
+
+ ::IFileOpenDialog *fileOpenDialog(NULL);
+
+ // Create dialog
+ result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL,
+ CLSCTX_ALL, ::IID_IFileOpenDialog,
+ reinterpret_cast<void**>(&fileOpenDialog) );
+
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError("Could not create dialog.");
+ goto end;
+ }
+
+ // Build the filter list
+ if ( !AddFiltersToDialog( fileOpenDialog, filterList ) )
+ {
+ goto end;
+ }
+
+ // Set the default path
+ if ( !SetDefaultPath( fileOpenDialog, defaultPath ) )
+ {
+ goto end;
+ }
+
+ // Show the dialog.
+ result = fileOpenDialog->Show(NULL);
+ if ( SUCCEEDED(result) )
+ {
+ // Get the file name
+ ::IShellItem *shellItem(NULL);
+ result = fileOpenDialog->GetResult(&shellItem);
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError("Could not get shell item from dialog.");
+ goto end;
+ }
+ wchar_t *filePath(NULL);
+ result = shellItem->GetDisplayName(::SIGDN_FILESYSPATH, &filePath);
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError("Could not get file path for selected.");
+ goto end;
+ }
+
+ CopyWCharToNFDChar( filePath, outPath );
+ CoTaskMemFree(filePath);
+ if ( !*outPath )
+ {
+ /* error is malloc-based, error message would be redundant */
+ goto end;
+ }
+
+ nfdResult = NFD_OKAY;
+ shellItem->Release();
+ }
+ else if (result == HRESULT_FROM_WIN32(ERROR_CANCELLED) )
+ {
+ nfdResult = NFD_CANCEL;
+ }
+ else
+ {
+ NFDi_SetError("File dialog box show failed.");
+ nfdResult = NFD_ERROR;
+ }
+
+ end:
+ ::CoUninitialize();
+
+ return nfdResult;
+}
+
+nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
+ const nfdchar_t *defaultPath,
+ nfdpathset_t *outPaths )
+{
+ nfdresult_t nfdResult = NFD_ERROR;
+
+ // Init COM library.
+ HRESULT result = ::CoInitializeEx(NULL,
+ ::COINIT_APARTMENTTHREADED |
+ ::COINIT_DISABLE_OLE1DDE );
+ if ( !SUCCEEDED(result))
+ {
+ NFDi_SetError("Could not initialize COM.");
+ return NFD_ERROR;
+ }
+
+ ::IFileOpenDialog *fileOpenDialog(NULL);
+
+ // Create dialog
+ result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL,
+ CLSCTX_ALL, ::IID_IFileOpenDialog,
+ reinterpret_cast<void**>(&fileOpenDialog) );
+
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError("Could not create dialog.");
+ goto end;
+ }
+
+ // Build the filter list
+ if ( !AddFiltersToDialog( fileOpenDialog, filterList ) )
+ {
+ goto end;
+ }
+
+ // Set the default path
+ if ( !SetDefaultPath( fileOpenDialog, defaultPath ) )
+ {
+ goto end;
+ }
+
+ // Set a flag for multiple options
+ DWORD dwFlags;
+ result = fileOpenDialog->GetOptions(&dwFlags);
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError("Could not get options.");
+ goto end;
+ }
+ result = fileOpenDialog->SetOptions(dwFlags | FOS_ALLOWMULTISELECT);
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError("Could not set options.");
+ goto end;
+ }
+
+ // Show the dialog.
+ result = fileOpenDialog->Show(NULL);
+ if ( SUCCEEDED(result) )
+ {
+ IShellItemArray *shellItems;
+ result = fileOpenDialog->GetResults( &shellItems );
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError("Could not get shell items.");
+ goto end;
+ }
+
+ if ( AllocPathSet( shellItems, outPaths ) == NFD_ERROR )
+ {
+ goto end;
+ }
+
+ shellItems->Release();
+ nfdResult = NFD_OKAY;
+ }
+ else if (result == HRESULT_FROM_WIN32(ERROR_CANCELLED) )
+ {
+ nfdResult = NFD_CANCEL;
+ }
+ else
+ {
+ NFDi_SetError("File dialog box show failed.");
+ nfdResult = NFD_ERROR;
+ }
+
+ end:
+ ::CoUninitialize();
+
+ return nfdResult;
+}
+
+nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
+ const nfdchar_t *defaultPath,
+ nfdchar_t **outPath )
+{
+ nfdresult_t nfdResult = NFD_ERROR;
+
+ // Init COM library.
+ HRESULT result = ::CoInitializeEx(NULL,
+ ::COINIT_APARTMENTTHREADED |
+ ::COINIT_DISABLE_OLE1DDE );
+ if ( !SUCCEEDED(result))
+ {
+ NFDi_SetError("Could not initialize COM.");
+ return NFD_ERROR;
+ }
+
+ ::IFileSaveDialog *fileSaveDialog(NULL);
+
+ // Create dialog
+ result = ::CoCreateInstance(::CLSID_FileSaveDialog, NULL,
+ CLSCTX_ALL, ::IID_IFileSaveDialog,
+ reinterpret_cast<void**>(&fileSaveDialog) );
+
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError("Could not create dialog.");
+ goto end;
+ }
+
+ // Build the filter list
+ if ( !AddFiltersToDialog( fileSaveDialog, filterList ) )
+ {
+ goto end;
+ }
+
+ // Set the default path
+ if ( !SetDefaultPath( fileSaveDialog, defaultPath ) )
+ {
+ goto end;
+ }
+
+ // Show the dialog.
+ result = fileSaveDialog->Show(NULL);
+ if ( SUCCEEDED(result) )
+ {
+ // Get the file name
+ ::IShellItem *shellItem;
+ result = fileSaveDialog->GetResult(&shellItem);
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError("Could not get shell item from dialog.");
+ goto end;
+ }
+ wchar_t *filePath(NULL);
+ result = shellItem->GetDisplayName(::SIGDN_FILESYSPATH, &filePath);
+ if ( !SUCCEEDED(result) )
+ {
+ NFDi_SetError("Could not get file path for selected.");
+ goto end;
+ }
+
+ CopyWCharToNFDChar( filePath, outPath );
+ CoTaskMemFree(filePath);
+ if ( !*outPath )
+ {
+ /* error is malloc-based, error message would be redundant */
+ goto end;
+ }
+
+ nfdResult = NFD_OKAY;
+ shellItem->Release();
+ }
+ else if (result == HRESULT_FROM_WIN32(ERROR_CANCELLED) )
+ {
+ nfdResult = NFD_CANCEL;
+ }
+ else
+ {
+ NFDi_SetError("File dialog box show failed.");
+ nfdResult = NFD_ERROR;
+ }
+
+ end:
+ ::CoUninitialize();
+
+ return nfdResult;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/SConstruct b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/SConstruct
new file mode 100644
index 0000000000..14e98912b4
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/SConstruct
@@ -0,0 +1,70 @@
+#
+# Native file dialog
+#
+# Build tests
+
+target_arch=str(Platform())
+debug = int(ARGUMENTS.get( 'debug', 0 ))
+
+files = {'test_opendialog': ['test_opendialog.c'],
+ 'test_opendialogmultiple': ['test_opendialogmultiple.c'],
+ 'test_savedialog': ['test_savedialog.c']}
+
+test_env = Environment()
+
+
+# Windows runtime library types
+win_rtl = {'debug': '/MDd',
+ 'release': '/MD'}
+
+
+def set_debug(env):
+ if target_arch == 'win32':
+ env.Append( CFLAGS=['/Z7', # obj contains full symbols
+ win_rtl['debug'] ] )
+ else:
+ env.Append( CFLAGS=['-g'] )
+
+
+def set_release(env):
+ if target_arch == 'win32':
+ env.Append( CFLAGS=[win_rtl['release'],
+ '/O2',
+ ])
+ else:
+ env.Append( CFLAGS=['-O3'] )
+
+
+def get_lib_name(base, is_debug):
+ if is_debug:
+ return base + '_d'
+ else:
+ return base
+
+
+if debug:
+ set_debug(test_env)
+else:
+ set_release(test_env)
+
+test_env.Append( CPPPATH=['../src/include'], # API header path only, no internals allowed
+ LIBPATH=['../src'],
+ LIBS=get_lib_name('nfd', debug) )
+
+
+# Cocoa OS X builds
+if target_arch == 'darwin':
+ test_env.Append( FRAMEWORKS='AppKit' )
+ test_env.CC='clang -fcolor-diagnostics'
+
+# Linux GTK+ 3 builds
+elif target_arch == 'posix':
+ test_env.ParseConfig( 'pkg-config --cflags --libs gtk+-3.0' )
+
+elif target_arch == 'win32':
+ test_env.Append(
+ LINKFLAGS=['/NODEFAULTLIB:LIBCMT'])
+
+for codebase in files:
+ output_name = get_lib_name(codebase, debug)
+ test_env.Program( output_name, files[codebase] )
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_opendialog.c b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_opendialog.c
new file mode 100644
index 0000000000..2984acf990
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_opendialog.c
@@ -0,0 +1,29 @@
+#include <nfd.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/* this test should compile on all supported platforms */
+
+int main( void )
+{
+ nfdchar_t *outPath = NULL;
+ nfdresult_t result = NFD_OpenDialog( "png,jpg;pdf", NULL, &outPath );
+ if ( result == NFD_OKAY )
+ {
+ puts("Success!");
+ puts(outPath);
+ free(outPath);
+ }
+ else if ( result == NFD_CANCEL )
+ {
+ puts("User pressed cancel.");
+ }
+ else
+ {
+ printf("Error: %s\n", NFD_GetError() );
+ }
+
+ return 0;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_opendialogmultiple.c b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_opendialogmultiple.c
new file mode 100644
index 0000000000..16cd675542
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_opendialogmultiple.c
@@ -0,0 +1,34 @@
+#include <nfd.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* this test should compile on all supported platforms */
+
+int main( void )
+{
+ nfdchar_t *outPath = NULL;
+
+ nfdpathset_t pathSet;
+ nfdresult_t result = NFD_OpenDialogMultiple( "png,jpg;pdf", NULL, &pathSet );
+ if ( result == NFD_OKAY )
+ {
+ size_t i;
+ for ( i = 0; i < NFD_PathSet_GetCount(&pathSet); ++i )
+ {
+ nfdchar_t *path = NFD_PathSet_GetPath(&pathSet, i);
+ printf("Path %li: %s\n", i, path );
+ }
+ NFD_PathSet_Free(&pathSet);
+ }
+ else if ( result == NFD_CANCEL )
+ {
+ puts("User pressed cancel.");
+ }
+ else
+ {
+ printf("Error: %s\n", NFD_GetError() );
+ }
+
+ return 0;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_savedialog.c b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_savedialog.c
new file mode 100644
index 0000000000..4e1f69efc4
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/ThirdPartyLibs/nativefiledialog/test/test_savedialog.c
@@ -0,0 +1,28 @@
+#include <nfd.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* this test should compile on all supported platforms */
+
+int main( void )
+{
+ nfdchar_t *savePath = NULL;
+ nfdresult_t result = NFD_SaveDialog( "png,jpg;pdf", NULL, &savePath );
+ if ( result == NFD_OKAY )
+ {
+ puts("Success!");
+ puts(savePath);
+ free(savePath);
+ }
+ else if ( result == NFD_CANCEL )
+ {
+ puts("User pressed cancel.");
+ }
+ else
+ {
+ printf("Error: %s\n", NFD_GetError() );
+ }
+
+ return 0;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/exr-io.cc b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/exr-io.cc
new file mode 100644
index 0000000000..5c2821b75b
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/exr-io.cc
@@ -0,0 +1,60 @@
+#define TINYEXR_IMPLEMENTATION
+#include "tinyexr.h"
+
+#include "exr-io.h"
+
+#include <cstdio>
+#include <iostream>
+
+namespace exrio {
+
+bool GetEXRLayers(const char *filename)
+{
+ const char** layer_names = nullptr;
+ int num_layers = 0;
+ const char *err = nullptr;
+ int ret = EXRLayers(filename, &layer_names, &num_layers, &err);
+
+ if (err) {
+ fprintf(stderr, "EXR error = %s\n", err);
+ }
+
+ if (ret != 0) {
+ fprintf(stderr, "Load EXR err: %s\n", err);
+ return false;
+ }
+ if (num_layers > 0)
+ {
+ fprintf(stdout, "EXR Contains %i Layers\n", num_layers);
+ for (size_t i = 0; i < num_layers; ++i) {
+ fprintf(stdout, "Layer %i : %s\n", i + 1, layer_names[i]);
+ }
+ }
+ free(layer_names);
+ return true;
+}
+
+bool LoadEXRRGBA(float** rgba, int *w, int *h, const char* filename, const char* layername)
+{
+ int width, height;
+ float* image;
+ const char *err = nullptr;
+ int ret = LoadEXRWithLayer(&image, &width, &height, filename, layername, &err);
+
+ if (err) {
+ fprintf(stderr, "EXR error = %s\n", err);
+ }
+
+ if (ret != 0) {
+ fprintf(stderr, "Load EXR err: %s\n", err);
+ return false;
+ }
+
+ (*rgba) = image;
+ (*w) = width;
+ (*h) = height;
+
+ return true;
+}
+
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/exr-io.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/exr-io.h
new file mode 100644
index 0000000000..d338ff6977
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/exr-io.h
@@ -0,0 +1,16 @@
+#ifndef EXR_IO_H_
+#define EXR_IO_H_
+
+#include "tinyexr.h"
+
+namespace exrio
+{
+
+bool GetEXRLayers(const char *filename);
+
+bool LoadEXRRGBA(float** rgba, int* w, int *h, const char* filename, const char* layername = nullptr);
+
+}
+
+
+#endif // EXR_IO_H_
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/findOpenGLGlewGlut.lua b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/findOpenGLGlewGlut.lua
new file mode 100644
index 0000000000..c3c3582ff6
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/findOpenGLGlewGlut.lua
@@ -0,0 +1,90 @@
+
+ function findOpenGL()
+ configuration{}
+ if os.is("Linux") then
+ return true
+ end
+ --assume OpenGL is available on Mac OSX, Windows etc
+ return true
+ end
+
+ function findOpenGL3()
+ configuration{}
+ if os.is("MacOSX") then
+ local osversion = os.getversion()
+ --Mac OSX 10.9 and above supports OpenGL 3, below doesn't, so ...
+ if osversion.majorversion > 10 or (osversion.majorversion == 10 and osversion.minorversion >=9) then
+ return findOpenGL()
+ else
+ return false
+ end
+ else
+ return findOpenGL()
+ end
+ end
+
+
+ function initOpenGL()
+ configuration {}
+ configuration {"Windows"}
+ links {"opengl32","glu32"}
+ configuration {"MacOSX"}
+ links { "OpenGL.framework"}
+ configuration {"not Windows", "not MacOSX"}
+ if os.is("Linux") then
+ if _OPTIONS["enable_system_opengl"] and (os.isdir("/usr/include") and os.isfile("/usr/include/GL/gl.h")) then
+ links {"GL"}
+ else
+ print("No GL/gl.h found, using dynamic loading of GL using glew")
+ defines {"GLEW_INIT_OPENGL11_FUNCTIONS=1"}
+ links {"dl"}
+ end
+ end
+ configuration{}
+ end
+
+
+ function initGlew()
+ configuration {}
+ if os.is("Windows") then
+ configuration {"Windows"}
+ defines { "GLEW_STATIC"}
+ includedirs {
+ projectRootDir .. "ThirdPartyLibs/Glew"
+ }
+ files { projectRootDir .. "ThirdPartyLibs/Glew/glew.c"}
+ end
+ if os.is("Linux") then
+ configuration{"Linux"}
+ if _OPTIONS["enable_system_opengl"] and (os.isdir("/usr/include") and os.isfile("/usr/include/GL/gl.h") and os.isfile("/usr/include/GL/glew.h")) then
+ links {"GLEW"}
+ print ("linking against system GLEW")
+ else
+ print("Using static glew and dynamic loading of glx functions")
+ defines { "GLEW_STATIC","GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS=1"}
+ includedirs {
+ projectRootDir .. "ThirdPartyLibs/Glew"
+ }
+ files { projectRootDir .. "ThirdPartyLibs/Glew/glew.c"}
+ links {"dl"}
+ end
+
+ end
+ configuration{}
+ end
+
+ function initX11()
+ if os.is("Linux") then
+ if _OPTIONS["enable_system_x11"] and (os.isdir("/usr/include") and os.isfile("/usr/include/X11/X.h")) then
+ links{"X11","pthread"}
+ else
+ print("No X11/X.h found, using dynamic loading of X11")
+ includedirs {
+ projectRootDir .. "ThirdPartyLibs/optionalX11"
+ }
+ defines {"DYNAMIC_LOAD_X11_FUNCTIONS"}
+ links {"dl","pthread"}
+ end
+ end
+ end
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/main.cc b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/main.cc
new file mode 100644
index 0000000000..2254fe7078
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/main.cc
@@ -0,0 +1,541 @@
+#define USE_OPENGL2
+#include "OpenGLWindow/OpenGLInclude.h"
+#ifdef _WIN32
+#include "OpenGLWindow/Win32OpenGLWindow.h"
+#elif defined __APPLE__
+#include "OpenGLWindow/MacOpenGLWindow.h"
+#else
+// assume linux
+#include "OpenGLWindow/X11OpenGLWindow.h"
+#endif
+
+#ifdef _WIN32
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <time.h>
+#else
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#endif
+
+#include <cstdio>
+#include <cstdlib>
+#include <string>
+#include <cstring>
+
+#ifdef USE_NATIVEFILEDIALOG
+#include <nfd.h>
+#endif
+
+#define NK_INCLUDE_FIXED_TYPES
+#define NK_INCLUDE_STANDARD_IO
+#define NK_INCLUDE_DEFAULT_ALLOCATOR
+#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+#define NK_INCLUDE_FONT_BAKING
+#define NK_INCLUDE_DEFAULT_FONT
+#define NK_IMPLEMENTATION
+#define NK_BTGUI_GL2_IMPLEMENTATION
+#include "nuklear.h"
+#include "nuklear_btgui_gl2.h"
+
+#include "exr-io.h"
+
+b3gDefaultOpenGLWindow* window = 0;
+int gWidth = 512;
+int gHeight = 512;
+GLuint gTexId;
+float gIntensityScale = 1.0;
+float gGamma = 1.0;
+int gExrWidth, gExrHeight;
+float* gExrRGBA;
+int gMousePosX, gMousePosY;
+
+struct nk_context* ctx;
+
+#define MAX_VERTEX_BUFFER 512 * 1024
+#define MAX_ELEMENT_BUFFER 128 * 1024
+
+void checkErrors(std::string desc) {
+ GLenum e = glGetError();
+ if (e != GL_NO_ERROR) {
+ fprintf(stderr, "OpenGL error in \"%s\": %d (%d)\n", desc.c_str(), e, e);
+ exit(20);
+ }
+}
+
+void keyboardCallback(int keycode, int state) {
+ // printf("hello key %d, state %d\n", keycode, state);
+ if (keycode == 27) {
+ if (window) window->setRequestExit();
+ }
+}
+
+void mouseMoveCallback(float x, float y) {
+ // printf("Mouse Move: %f, %f\n", x, y);
+
+ gMousePosX = (int)x;
+ gMousePosY = (int)y;
+
+ // @todo { move to nuklear_btgui_gl2.h }
+ nk_btgui_update_mouse_pos((int)x, (int)y);
+}
+void mouseButtonCallback(int button, int state, float x, float y) {
+ nk_btgui_update_mouse_state((button == 0) && (state == 1), 0, 0);
+}
+
+void resizeCallback(float width, float height) {
+ GLfloat h = (GLfloat)height / (GLfloat)width;
+ GLfloat xmax, znear, zfar;
+
+ znear = 1.0f;
+ zfar = 1000.0f;
+ xmax = znear * 0.5f;
+
+ gWidth = width;
+ gHeight = height;
+}
+
+GLuint GenTexture(int w, int h, const float* rgba)
+{
+ // Create floating point RGBA texture
+ GLuint texHandle;
+ glGenTextures(1, &texHandle);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texHandle);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ // @todo { Use GL_RGBA32F for internal texture format. }
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_FLOAT, rgba);
+ checkErrors("GenTexture");
+
+ return texHandle;
+}
+
+
+bool
+LoadShader(
+ GLenum shaderType, // GL_VERTEX_SHADER or GL_FRAGMENT_SHADER(or maybe GL_COMPUTE_SHADER)
+ GLuint& shader,
+ const char* shaderSourceFilename)
+{
+ GLint val = 0;
+
+ // free old shader/program
+ if (shader != 0) glDeleteShader(shader);
+
+ static GLchar srcbuf[16384];
+ FILE *fp = fopen(shaderSourceFilename, "rb");
+ if (!fp) {
+ fprintf(stderr, "failed to load shader: %s\n", shaderSourceFilename);
+ return false;
+ }
+ fseek(fp, 0, SEEK_END);
+ size_t len = ftell(fp);
+ rewind(fp);
+ len = fread(srcbuf, 1, len, fp);
+ srcbuf[len] = 0;
+ fclose(fp);
+
+ static const GLchar *src = srcbuf;
+
+ shader = glCreateShader(shaderType);
+ glShaderSource(shader, 1, &src, NULL);
+ glCompileShader(shader);
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &val);
+ if (val != GL_TRUE) {
+ char log[4096];
+ GLsizei msglen;
+ glGetShaderInfoLog(shader, 4096, &msglen, log);
+ printf("%s\n", log);
+ assert(val == GL_TRUE && "failed to compile shader");
+ }
+
+ printf("Load shader [ %s ] OK\n", shaderSourceFilename);
+ return true;
+}
+
+bool
+LinkShader(
+ GLuint& prog,
+ GLuint& vertShader,
+ GLuint& fragShader)
+{
+ GLint val = 0;
+
+ if (prog != 0) {
+ glDeleteProgram(prog);
+ }
+
+ prog = glCreateProgram();
+
+ glAttachShader(prog, vertShader);
+ glAttachShader(prog, fragShader);
+ glLinkProgram(prog);
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &val);
+ assert(val == GL_TRUE && "failed to link shader");
+
+ printf("Link shader OK\n");
+
+ return true;
+}
+
+void
+Render(GLuint prog_id, int w, int h)
+{
+ glDisable(GL_DEPTH_TEST);
+
+ glUseProgram(prog_id);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, gTexId);
+
+ glEnable(GL_TEXTURE_2D);
+ GLint texLoc = glGetUniformLocation(prog_id, "tex");
+ assert(texLoc >= 0);
+ glUniform1i(texLoc, 0); // TEXTURE0
+
+ GLint intensityScaleLoc = glGetUniformLocation(prog_id, "intensity_scale");
+ if (intensityScaleLoc >= 0) {
+ glUniform1f(intensityScaleLoc, gIntensityScale);
+ }
+
+ GLint gammaLoc = glGetUniformLocation(prog_id, "gamma");
+ if (gammaLoc >= 0) {
+ glUniform1f(gammaLoc, gGamma);
+ }
+
+ GLint pos_id = glGetAttribLocation(prog_id, "in_position");
+ assert(pos_id >= 0);
+ GLint texcoord_id = glGetAttribLocation(prog_id, "in_texcoord");
+ assert(texcoord_id >= 0);
+
+ const float vertices[] = {-1, -1, -1, 1, 1, 1, 1, -1};
+ const float texcoords[] = {0, 1, 0, 0, 1, 0, 1, 1};
+
+ glVertexAttribPointer(pos_id, 2, GL_FLOAT, GL_FALSE, 0, (const void*)(vertices));
+ glVertexAttribPointer(texcoord_id, 2, GL_FLOAT, GL_FALSE, 0, (const void*)(texcoords));
+
+ glEnableVertexAttribArray(pos_id);
+ glEnableVertexAttribArray(texcoord_id);
+
+ glDrawArrays(GL_QUADS, 0, 4);
+
+ glDisableVertexAttribArray(pos_id);
+ glDisableVertexAttribArray(texcoord_id);
+
+ checkErrors("render");
+
+ glUseProgram(0);
+ checkErrors("UseProgram(0)");
+
+ glEnable(GL_DEPTH_TEST);
+ glDisable(GL_TEXTURE_2D);
+}
+
+void InspectPixel(float rgba[4], int x, int y) {
+ if (x < 0) x = 0;
+ if (x > (gExrWidth-1)) x = gExrWidth - 1;
+
+ if (y < 0) y = 0;
+ if (y > (gExrHeight-1)) y = gExrHeight - 1;
+
+ rgba[0] = gExrRGBA[4 * (y * gExrWidth + x) + 0];
+ rgba[1] = gExrRGBA[4 * (y * gExrWidth + x) + 1];
+ rgba[2] = gExrRGBA[4 * (y * gExrWidth + x) + 2];
+ rgba[3] = gExrRGBA[4 * (y * gExrWidth + x) + 3];
+}
+
+int main(int argc, char** argv) {
+
+ const char *filename = NULL;
+ const char *layername = NULL;
+
+#ifdef USE_NATIVEFILEDIALOG
+ if (argc < 2) {
+ nfdchar_t *outPath = NULL;
+ nfdresult_t result = NFD_OpenDialog( "exr", NULL, &outPath );
+ if ( result == NFD_OKAY )
+ {
+ puts("Success!");
+ filename = strdup(outPath);
+ }
+ else if ( result == NFD_CANCEL )
+ {
+ puts("User pressed cancel.");
+ exit(-1);
+ }
+ else
+ {
+ printf("Error: %s\n", NFD_GetError() );
+ exit(-1);
+ }
+ } else {
+ filename = argv[1];
+ if (argc > 2) {
+ layername = argv[2];
+ }
+ }
+#else
+ if (argc < 2) {
+ printf("Usage: exrview input.exr [layer name]\n");
+ exit(-1);
+ }
+ filename = argv[1];
+ if (argc > 2) {
+ layername = argv[2];
+ }
+#endif
+
+ {
+ bool ret = exrio::GetEXRLayers(filename);
+ if (!ret) {
+ exit(-1);
+ }
+ }
+
+ {
+ bool ret = exrio::LoadEXRRGBA(&gExrRGBA, &gExrWidth, &gExrHeight, filename, layername);
+ if (!ret) {
+ exit(-1);
+ }
+ }
+
+ window = new b3gDefaultOpenGLWindow;
+ b3gWindowConstructionInfo ci;
+#ifdef USE_OPENGL2
+ ci.m_openglVersion = 2;
+#endif
+ ci.m_width = gExrWidth;
+ ci.m_height = gExrHeight;
+ window->createWindow(ci);
+
+ char title[1024];
+ sprintf(title, "%s (%d x %d)", filename, gExrWidth, gExrHeight);
+ window->setWindowTitle(title);
+
+#ifndef __APPLE__
+#ifndef _WIN32
+ //some Linux implementations need the 'glewExperimental' to be true
+ glewExperimental = GL_TRUE;
+#endif
+ if (glewInit() != GLEW_OK) {
+ fprintf(stderr, "Failed to initialize GLEW\n");
+ exit(-1);
+ }
+
+ if (!GLEW_VERSION_2_1) {
+ fprintf(stderr, "OpenGL 2.1 is not available\n");
+ exit(-1);
+ }
+#endif
+
+
+ checkErrors("init");
+
+ window->setMouseButtonCallback(mouseButtonCallback);
+ window->setMouseMoveCallback(mouseMoveCallback);
+ checkErrors("mouse");
+ window->setKeyboardCallback(keyboardCallback);
+ checkErrors("keyboard");
+ window->setResizeCallback(resizeCallback);
+ checkErrors("resize");
+
+ struct nk_color background;
+ background = nk_rgb(28,48,62);
+
+
+ {
+ // Upload EXR image to OpenGL texture.
+ gTexId = GenTexture(gExrWidth, gExrHeight, gExrRGBA);
+ if (gTexId == 0) {
+ fprintf(stderr, "OpenGL texture error\n");
+ exit(-1);
+ }
+ }
+
+
+ /* GUI */
+ ctx = nk_btgui_init(window, NK_BTGUI3_DEFAULT);
+ /* Load Fonts: if none of these are loaded a default font will be used */
+ {
+ struct nk_font_atlas* atlas;
+ nk_btgui_font_stash_begin(&atlas);
+ /*struct nk_font *droid = nk_font_atlas_add_from_file(atlas,
+ * "../../../extra_font/DroidSans.ttf", 14, 0);*/
+ /*struct nk_font *roboto = nk_font_atlas_add_from_file(atlas,
+ * "../../../extra_font/Roboto-Regular.ttf", 14, 0);*/
+ /*struct nk_font *future = nk_font_atlas_add_from_file(atlas,
+ * "../../../extra_font/kenvector_future_thin.ttf", 13, 0);*/
+ /*struct nk_font *clean = nk_font_atlas_add_from_file(atlas,
+ * "../../../extra_font/ProggyClean.ttf", 12, 0);*/
+ /*struct nk_font *tiny = nk_font_atlas_add_from_file(atlas,
+ * "../../../extra_font/ProggyTiny.ttf", 10, 0);*/
+ /*struct nk_font *cousine = nk_font_atlas_add_from_file(atlas,
+ * "../../../extra_font/Cousine-Regular.ttf", 13, 0);*/
+ struct nk_font *droid = nk_font_atlas_add_from_file(atlas,
+ "./DroidSans.ttf", 14, 0);
+ nk_btgui_font_stash_end();
+ if (droid) {
+ nk_style_set_font(ctx, &droid->handle);
+ }
+
+ // Color
+ struct nk_color table[NK_COLOR_COUNT];
+ table[NK_COLOR_TEXT] = nk_rgba(210, 210, 210, 255);
+ table[NK_COLOR_WINDOW] = nk_rgba(57, 67, 71, 245);
+ table[NK_COLOR_HEADER] = nk_rgba(51, 51, 56, 230);
+ table[NK_COLOR_BORDER] = nk_rgba(46, 46, 46, 255);
+ table[NK_COLOR_BUTTON] = nk_rgba(48, 48, 48, 255);
+ table[NK_COLOR_BUTTON_HOVER] = nk_rgba(58, 93, 121, 255);
+ table[NK_COLOR_BUTTON_ACTIVE] = nk_rgba(63, 98, 126, 255);
+ table[NK_COLOR_TOGGLE] = nk_rgba(50, 58, 61, 255);
+ table[NK_COLOR_TOGGLE_HOVER] = nk_rgba(45, 53, 56, 255);
+ table[NK_COLOR_TOGGLE_CURSOR] = nk_rgba(48, 83, 111, 255);
+ table[NK_COLOR_SELECT] = nk_rgba(57, 67, 61, 255);
+ table[NK_COLOR_SELECT_ACTIVE] = nk_rgba(48, 83, 111, 255);
+ table[NK_COLOR_SLIDER] = nk_rgba(50, 58, 61, 255);
+ table[NK_COLOR_SLIDER_CURSOR] = nk_rgba(48, 83, 111, 245);
+ table[NK_COLOR_SLIDER_CURSOR_HOVER] = nk_rgba(53, 88, 116, 255);
+ table[NK_COLOR_SLIDER_CURSOR_ACTIVE] = nk_rgba(58, 93, 121, 255);
+ table[NK_COLOR_PROPERTY] = nk_rgba(50, 58, 61, 255);
+ table[NK_COLOR_EDIT] = nk_rgba(50, 58, 61, 225);
+ table[NK_COLOR_EDIT_CURSOR] = nk_rgba(210, 210, 210, 255);
+ table[NK_COLOR_COMBO] = nk_rgba(50, 58, 61, 255);
+ table[NK_COLOR_CHART] = nk_rgba(50, 58, 61, 255);
+ table[NK_COLOR_CHART_COLOR] = nk_rgba(48, 83, 111, 255);
+ table[NK_COLOR_CHART_COLOR_HIGHLIGHT] = nk_rgba(255, 0, 0, 255);
+ table[NK_COLOR_SCROLLBAR] = nk_rgba(50, 58, 61, 255);
+ table[NK_COLOR_SCROLLBAR_CURSOR] = nk_rgba(48, 83, 111, 255);
+ table[NK_COLOR_SCROLLBAR_CURSOR_HOVER] = nk_rgba(53, 88, 116, 255);
+ table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE] = nk_rgba(58, 93, 121, 255);
+ table[NK_COLOR_TAB_HEADER] = nk_rgba(48, 83, 111, 255);
+ nk_style_from_table(ctx, table);
+ }
+
+ checkErrors("start");
+
+ GLuint vert_id = 0, frag_id = 0, prog_id = 0;
+ {
+ bool ret = LoadShader(GL_VERTEX_SHADER, vert_id, "shader.vert");
+ if (!ret) {
+ fprintf(stderr, "Failed to compile vertex shader.\n");
+ exit(-1);
+ }
+ }
+ checkErrors("vertex shader load");
+
+ {
+ bool ret = LoadShader(GL_FRAGMENT_SHADER, frag_id, "shader.frag");
+ if (!ret) {
+ fprintf(stderr, "Failed to compile fragment shader.\n");
+ exit(-1);
+ }
+ }
+ checkErrors("fragment shader load");
+
+ {
+ bool ret = LinkShader(prog_id, vert_id, frag_id);
+ if (!ret) {
+ fprintf(stderr, "Failed to link shader.\n");
+ exit(-1);
+ }
+ }
+ checkErrors("link shader");
+
+
+ while (!window->requestedExit()) {
+ window->startRendering();
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ checkErrors("begin frame");
+ nk_btgui_new_frame();
+
+ float pixel[4];
+ InspectPixel(pixel, gMousePosX, gMousePosY);
+
+ /* GUI */
+ {
+ //struct nk_panel layout;
+ if (nk_begin(ctx, "UI", nk_rect(50, 50, 350, 250),
+ NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE |
+ NK_WINDOW_MINIMIZABLE | NK_WINDOW_TITLE)) {
+ nk_layout_row_static(ctx, 30, 300, 1);
+ //if (nk_button_label(ctx, "button", NK_BUTTON_DEFAULT))
+ // fprintf(stdout, "button pressed\n");
+
+ nk_label(ctx, "Intensity", NK_TEXT_LEFT);
+ if (nk_slider_float(ctx, 0, &gIntensityScale, 10.0, 0.1f)) {
+ fprintf(stdout, "Intensity: %f\n", gIntensityScale);
+ }
+ nk_label(ctx, "Display gamma", NK_TEXT_LEFT);
+ if (nk_slider_float(ctx, 0, &gGamma, 10.0, 0.01f)) {
+ fprintf(stdout, "Gamma: %f\n", gGamma);
+ }
+
+ nk_label(ctx, "RAW pixel value", NK_TEXT_LEFT);
+ char txt[1024];
+ sprintf(txt, "(%d, %d) = %f, %f, %f, %f", gMousePosX, gMousePosY, pixel[0], pixel[1], pixel[2], pixel[3]);
+ nk_text(ctx, txt, strlen(txt), NK_TEXT_LEFT);
+
+#if 0
+ nk_layout_row_dynamic(ctx, 25, 1);
+ nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1);
+
+ {
+ struct nk_panel combo;
+ nk_layout_row_dynamic(ctx, 20, 1);
+ nk_label(ctx, "background:", NK_TEXT_LEFT);
+ nk_layout_row_dynamic(ctx, 25, 1);
+ if (nk_combo_begin_color(ctx, &combo, background, 400)) {
+ nk_layout_row_dynamic(ctx, 120, 1);
+ background = nk_color_picker(ctx, background, NK_RGBA);
+ nk_layout_row_dynamic(ctx, 25, 1);
+ background.r =
+ (nk_byte)nk_propertyi(ctx, "#R:", 0, background.r, 255, 1, 1);
+ background.g =
+ (nk_byte)nk_propertyi(ctx, "#G:", 0, background.g, 255, 1, 1);
+ background.b =
+ (nk_byte)nk_propertyi(ctx, "#B:", 0, background.b, 255, 1, 1);
+ background.a =
+ (nk_byte)nk_propertyi(ctx, "#A:", 0, background.a, 255, 1, 1);
+ nk_combo_end(ctx);
+ }
+ }
+#endif
+ }
+ nk_end(ctx);
+ }
+
+ /* Draw */
+ {
+ float bg[4];
+ nk_color_fv(bg, background);
+ glViewport(0, 0, window->getWidth(), window->getHeight());
+ glClear(GL_COLOR_BUFFER_BIT);
+ glClearColor(bg[0], bg[1], bg[2], bg[3]);
+
+ Render(prog_id, window->getWidth(), window->getHeight());
+
+ /* IMPORTANT: `nk_glfw_render` modifies some global OpenGL state
+ * with blending, scissor, face culling and depth test and defaults
+ * everything
+ * back into a default state. Make sure to either save and restore or
+ * reset your own state after drawing rendering the UI. */
+ nk_btgui_render(NK_ANTI_ALIASING_ON, MAX_VERTEX_BUFFER,
+ MAX_ELEMENT_BUFFER);
+ }
+
+ window->endRendering();
+ }
+
+ nk_btgui_shutdown();
+
+ delete window;
+
+ return EXIT_SUCCESS;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/nuklear.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/nuklear.h
new file mode 100644
index 0000000000..15f2cc7bf3
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/nuklear.h
@@ -0,0 +1,25417 @@
+/*/// # Nuklear
+/// ![](https://cloud.githubusercontent.com/assets/8057201/11761525/ae06f0ca-a0c6-11e5-819d-5610b25f6ef4.gif)
+///
+/// ## Contents
+/// 1. About section
+/// 2. Highlights section
+/// 3. Features section
+/// 4. Usage section
+/// 1. Flags section
+/// 2. Constants section
+/// 3. Dependencies section
+/// 5. Example section
+/// 6. API section
+/// 1. Context section
+/// 2. Input section
+/// 3. Drawing section
+/// 4. Window section
+/// 5. Layouting section
+/// 6. Groups section
+/// 7. Tree section
+/// 8. Properties section
+/// 7. License section
+/// 8. Changelog section
+/// 9. Gallery section
+/// 10. Credits section
+///
+/// ## About
+/// This is a minimal state immediate mode graphical user interface toolkit
+/// written in ANSI C and licensed under public domain. It was designed as a simple
+/// embeddable user interface for application and does not have any dependencies,
+/// a default renderbackend or OS window and input handling but instead provides a very modular
+/// library approach by using simple input state for input and draw
+/// commands describing primitive shapes as output. So instead of providing a
+/// layered library that tries to abstract over a number of platform and
+/// render backends it only focuses on the actual UI.
+///
+/// ## Highlights
+/// - Graphical user interface toolkit
+/// - Single header library
+/// - Written in C89 (a.k.a. ANSI C or ISO C90)
+/// - Small codebase (~18kLOC)
+/// - Focus on portability, efficiency and simplicity
+/// - No dependencies (not even the standard library if not wanted)
+/// - Fully skinnable and customizable
+/// - Low memory footprint with total memory control if needed or wanted
+/// - UTF-8 support
+/// - No global or hidden state
+/// - Customizable library modules (you can compile and use only what you need)
+/// - Optional font baker and vertex buffer output
+///
+/// ## Features
+/// - Absolutely no platform dependent code
+/// - Memory management control ranging from/to
+/// - Ease of use by allocating everything from standard library
+/// - Control every byte of memory inside the library
+/// - Font handling control ranging from/to
+/// - Use your own font implementation for everything
+/// - Use this libraries internal font baking and handling API
+/// - Drawing output control ranging from/to
+/// - Simple shapes for more high level APIs which already have drawing capabilities
+/// - Hardware accessible anti-aliased vertex buffer output
+/// - Customizable colors and properties ranging from/to
+/// - Simple changes to color by filling a simple color table
+/// - Complete control with ability to use skinning to decorate widgets
+/// - Bendable UI library with widget ranging from/to
+/// - Basic widgets like buttons, checkboxes, slider, ...
+/// - Advanced widget like abstract comboboxes, contextual menus,...
+/// - Compile time configuration to only compile what you need
+/// - Subset which can be used if you do not want to link or use the standard library
+/// - Can be easily modified to only update on user input instead of frame updates
+///
+/// ## Usage
+/// This library is self contained in one single header file and can be used either
+/// in header only mode or in implementation mode. The header only mode is used
+/// by default when included and allows including this header in other headers
+/// and does not contain the actual implementation. <br /><br />
+///
+/// The implementation mode requires to define the preprocessor macro
+/// NK_IMPLEMENTATION in *one* .c/.cpp file before #includeing this file, e.g.:
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~C
+/// #define NK_IMPLEMENTATION
+/// #include "nuklear.h"
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Also optionally define the symbols listed in the section "OPTIONAL DEFINES"
+/// below in header and implementation mode if you want to use additional functionality
+/// or need more control over the library.
+///
+/// !!! WARNING
+/// Every time nuklear is included define the same compiler flags. This very important not doing so could lead to compiler errors or even worse stack corruptions.
+///
+/// ### Flags
+/// Flag | Description
+/// --------------------------------|------------------------------------------
+/// NK_PRIVATE | If defined declares all functions as static, so they can only be accessed inside the file that contains the implementation
+/// NK_INCLUDE_FIXED_TYPES | If defined it will include header `<stdint.h>` for fixed sized types otherwise nuklear tries to select the correct type. If that fails it will throw a compiler error and you have to select the correct types yourself.
+/// NK_INCLUDE_DEFAULT_ALLOCATOR | If defined it will include header `<stdlib.h>` and provide additional functions to use this library without caring for memory allocation control and therefore ease memory management.
+/// NK_INCLUDE_STANDARD_IO | If defined it will include header `<stdio.h>` and provide additional functions depending on file loading.
+/// NK_INCLUDE_STANDARD_VARARGS | If defined it will include header <stdio.h> and provide additional functions depending on file loading.
+/// NK_INCLUDE_VERTEX_BUFFER_OUTPUT | Defining this adds a vertex draw command list backend to this library, which allows you to convert queue commands into vertex draw commands. This is mainly if you need a hardware accessible format for OpenGL, DirectX, Vulkan, Metal,...
+/// NK_INCLUDE_FONT_BAKING | Defining this adds `stb_truetype` and `stb_rect_pack` implementation to this library and provides font baking and rendering. If you already have font handling or do not want to use this font handler you don't have to define it.
+/// NK_INCLUDE_DEFAULT_FONT | Defining this adds the default font: ProggyClean.ttf into this library which can be loaded into a font atlas and allows using this library without having a truetype font
+/// NK_INCLUDE_COMMAND_USERDATA | Defining this adds a userdata pointer into each command. Can be useful for example if you want to provide custom shaders depending on the used widget. Can be combined with the style structures.
+/// NK_BUTTON_TRIGGER_ON_RELEASE | Different platforms require button clicks occurring either on buttons being pressed (up to down) or released (down to up). By default this library will react on buttons being pressed, but if you define this it will only trigger if a button is released.
+/// NK_ZERO_COMMAND_MEMORY | Defining this will zero out memory for each drawing command added to a drawing queue (inside nk_command_buffer_push). Zeroing command memory is very useful for fast checking (using memcmp) if command buffers are equal and avoid drawing frames when nothing on screen has changed since previous frame.
+///
+/// !!! WARNING
+/// The following flags will pull in the standard C library:
+/// - NK_INCLUDE_DEFAULT_ALLOCATOR
+/// - NK_INCLUDE_STANDARD_IO
+/// - NK_INCLUDE_STANDARD_VARARGS
+///
+/// !!! WARNING
+/// The following flags if defined need to be defined for both header and implementation:
+/// - NK_INCLUDE_FIXED_TYPES
+/// - NK_INCLUDE_DEFAULT_ALLOCATOR
+/// - NK_INCLUDE_STANDARD_VARARGS
+/// - NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+/// - NK_INCLUDE_FONT_BAKING
+/// - NK_INCLUDE_DEFAULT_FONT
+/// - NK_INCLUDE_STANDARD_VARARGS
+/// - NK_INCLUDE_COMMAND_USERDATA
+///
+/// ### Constants
+/// Define | Description
+/// --------------------------------|---------------------------------------
+/// NK_BUFFER_DEFAULT_INITIAL_SIZE | Initial buffer size allocated by all buffers while using the default allocator functions included by defining NK_INCLUDE_DEFAULT_ALLOCATOR. If you don't want to allocate the default 4k memory then redefine it.
+/// NK_MAX_NUMBER_BUFFER | Maximum buffer size for the conversion buffer between float and string Under normal circumstances this should be more than sufficient.
+/// NK_INPUT_MAX | Defines the max number of bytes which can be added as text input in one frame. Under normal circumstances this should be more than sufficient.
+///
+/// !!! WARNING
+/// The following constants if defined need to be defined for both header and implementation:
+/// - NK_MAX_NUMBER_BUFFER
+/// - NK_BUFFER_DEFAULT_INITIAL_SIZE
+/// - NK_INPUT_MAX
+///
+/// ### Dependencies
+/// Function | Description
+/// ------------|---------------------------------------------------------------
+/// NK_ASSERT | If you don't define this, nuklear will use <assert.h> with assert().
+/// NK_MEMSET | You can define this to 'memset' or your own memset implementation replacement. If not nuklear will use its own version.
+/// NK_MEMCPY | You can define this to 'memcpy' or your own memcpy implementation replacement. If not nuklear will use its own version.
+/// NK_SQRT | You can define this to 'sqrt' or your own sqrt implementation replacement. If not nuklear will use its own slow and not highly accurate version.
+/// NK_SIN | You can define this to 'sinf' or your own sine implementation replacement. If not nuklear will use its own approximation implementation.
+/// NK_COS | You can define this to 'cosf' or your own cosine implementation replacement. If not nuklear will use its own approximation implementation.
+/// NK_STRTOD | You can define this to `strtod` or your own string to double conversion implementation replacement. If not defined nuklear will use its own imprecise and possibly unsafe version (does not handle nan or infinity!).
+/// NK_DTOA | You can define this to `dtoa` or your own double to string conversion implementation replacement. If not defined nuklear will use its own imprecise and possibly unsafe version (does not handle nan or infinity!).
+/// NK_VSNPRINTF| If you define `NK_INCLUDE_STANDARD_VARARGS` as well as `NK_INCLUDE_STANDARD_IO` and want to be safe define this to `vsnprintf` on compilers supporting later versions of C or C++. By default nuklear will check for your stdlib version in C as well as compiler version in C++. if `vsnprintf` is available it will define it to `vsnprintf` directly. If not defined and if you have older versions of C or C++ it will be defined to `vsprintf` which is unsafe.
+///
+/// !!! WARNING
+/// The following dependencies will pull in the standard C library if not redefined:
+/// - NK_ASSERT
+///
+/// !!! WARNING
+/// The following dependencies if defined need to be defined for both header and implementation:
+/// - NK_ASSERT
+///
+/// !!! WARNING
+/// The following dependencies if defined need to be defined only for the implementation part:
+/// - NK_MEMSET
+/// - NK_MEMCPY
+/// - NK_SQRT
+/// - NK_SIN
+/// - NK_COS
+/// - NK_STRTOD
+/// - NK_DTOA
+/// - NK_VSNPRINTF
+///
+/// ## Example
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// // init gui state
+/// enum {EASY, HARD};
+/// static int op = EASY;
+/// static float value = 0.6f;
+/// static int i = 20;
+/// struct nk_context ctx;
+///
+/// nk_init_fixed(&ctx, calloc(1, MAX_MEMORY), MAX_MEMORY, &font);
+/// if (nk_begin(&ctx, "Show", nk_rect(50, 50, 220, 220),
+/// NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_CLOSABLE)) {
+/// // fixed widget pixel width
+/// nk_layout_row_static(&ctx, 30, 80, 1);
+/// if (nk_button_label(&ctx, "button")) {
+/// // event handling
+/// }
+///
+/// // fixed widget window ratio width
+/// nk_layout_row_dynamic(&ctx, 30, 2);
+/// if (nk_option_label(&ctx, "easy", op == EASY)) op = EASY;
+/// if (nk_option_label(&ctx, "hard", op == HARD)) op = HARD;
+///
+/// // custom widget pixel width
+/// nk_layout_row_begin(&ctx, NK_STATIC, 30, 2);
+/// {
+/// nk_layout_row_push(&ctx, 50);
+/// nk_label(&ctx, "Volume:", NK_TEXT_LEFT);
+/// nk_layout_row_push(&ctx, 110);
+/// nk_slider_float(&ctx, 0, &value, 1.0f, 0.1f);
+/// }
+/// nk_layout_row_end(&ctx);
+/// }
+/// nk_end(&ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// ![](https://cloud.githubusercontent.com/assets/8057201/10187981/584ecd68-675c-11e5-897c-822ef534a876.png)
+///
+/// ## API
+///
+*/
+#ifndef NK_NUKLEAR_H_
+#define NK_NUKLEAR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * ==============================================================
+ *
+ * CONSTANTS
+ *
+ * ===============================================================
+ */
+#define NK_UNDEFINED (-1.0f)
+#define NK_UTF_INVALID 0xFFFD /* internal invalid utf8 rune */
+#define NK_UTF_SIZE 4 /* describes the number of bytes a glyph consists of*/
+#ifndef NK_INPUT_MAX
+ #define NK_INPUT_MAX 16
+#endif
+#ifndef NK_MAX_NUMBER_BUFFER
+ #define NK_MAX_NUMBER_BUFFER 64
+#endif
+#ifndef NK_SCROLLBAR_HIDING_TIMEOUT
+ #define NK_SCROLLBAR_HIDING_TIMEOUT 4.0f
+#endif
+/*
+ * ==============================================================
+ *
+ * HELPER
+ *
+ * ===============================================================
+ */
+#ifndef NK_API
+ #ifdef NK_PRIVATE
+ #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199409L))
+ #define NK_API static inline
+ #elif defined(__cplusplus)
+ #define NK_API static inline
+ #else
+ #define NK_API static
+ #endif
+ #else
+ #define NK_API extern
+ #endif
+#endif
+
+#define NK_INTERN static
+#define NK_STORAGE static
+#define NK_GLOBAL static
+
+#define NK_FLAG(x) (1 << (x))
+#define NK_STRINGIFY(x) #x
+#define NK_MACRO_STRINGIFY(x) NK_STRINGIFY(x)
+#define NK_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2
+#define NK_STRING_JOIN_DELAY(arg1, arg2) NK_STRING_JOIN_IMMEDIATE(arg1, arg2)
+#define NK_STRING_JOIN(arg1, arg2) NK_STRING_JOIN_DELAY(arg1, arg2)
+
+#ifdef _MSC_VER
+ #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__COUNTER__)
+#else
+ #define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name,__LINE__)
+#endif
+
+#ifndef NK_STATIC_ASSERT
+ #define NK_STATIC_ASSERT(exp) typedef char NK_UNIQUE_NAME(_dummy_array)[(exp)?1:-1]
+#endif
+
+#ifndef NK_FILE_LINE
+#ifdef _MSC_VER
+ #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__COUNTER__)
+#else
+ #define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__LINE__)
+#endif
+#endif
+
+#define NK_MIN(a,b) ((a) < (b) ? (a) : (b))
+#define NK_MAX(a,b) ((a) < (b) ? (b) : (a))
+#define NK_CLAMP(i,v,x) (NK_MAX(NK_MIN(v,x), i))
+
+#ifdef NK_INCLUDE_STANDARD_VARARGS
+ #if defined(_MSC_VER) && (_MSC_VER >= 1600) /* VS 2010 and above */
+ #include <sal.h>
+ #define NK_PRINTF_FORMAT_STRING _Printf_format_string_
+ #else
+ #define NK_PRINTF_FORMAT_STRING
+ #endif
+ #if defined(__GNUC__)
+ #define NK_PRINTF_VARARG_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, fmtargnumber+1)))
+ #else
+ #define NK_PRINTF_VARARG_FUNC(fmtargnumber)
+ #endif
+#endif
+
+/*
+ * ===============================================================
+ *
+ * BASIC
+ *
+ * ===============================================================
+ */
+#ifdef NK_INCLUDE_FIXED_TYPES
+ #include <stdint.h>
+ #define NK_INT8 int8_t
+ #define NK_UINT8 uint8_t
+ #define NK_INT16 int16_t
+ #define NK_UINT16 uint16_t
+ #define NK_INT32 int32_t
+ #define NK_UINT32 uint32_t
+ #define NK_SIZE_TYPE uintptr_t
+ #define NK_POINTER_TYPE uintptr_t
+#else
+ #ifndef NK_INT8
+ #define NK_INT8 char
+ #endif
+ #ifndef NK_UINT8
+ #define NK_UINT8 unsigned char
+ #endif
+ #ifndef NK_INT16
+ #define NK_INT16 signed short
+ #endif
+ #ifndef NK_UINT16
+ #define NK_UINT16 unsigned short
+ #endif
+ #ifndef NK_INT32
+ #if defined(_MSC_VER)
+ #define NK_INT32 __int32
+ #else
+ #define NK_INT32 signed int
+ #endif
+ #endif
+ #ifndef NK_UINT32
+ #if defined(_MSC_VER)
+ #define NK_UINT32 unsigned __int32
+ #else
+ #define NK_UINT32 unsigned int
+ #endif
+ #endif
+ #ifndef NK_SIZE_TYPE
+ #if defined(_WIN64) && defined(_MSC_VER)
+ #define NK_SIZE_TYPE unsigned __int64
+ #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
+ #define NK_SIZE_TYPE unsigned __int32
+ #elif defined(__GNUC__) || defined(__clang__)
+ #if defined(__x86_64__) || defined(__ppc64__)
+ #define NK_SIZE_TYPE unsigned long
+ #else
+ #define NK_SIZE_TYPE unsigned int
+ #endif
+ #else
+ #define NK_SIZE_TYPE unsigned long
+ #endif
+ #endif
+ #ifndef NK_POINTER_TYPE
+ #if defined(_WIN64) && defined(_MSC_VER)
+ #define NK_POINTER_TYPE unsigned __int64
+ #elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
+ #define NK_POINTER_TYPE unsigned __int32
+ #elif defined(__GNUC__) || defined(__clang__)
+ #if defined(__x86_64__) || defined(__ppc64__)
+ #define NK_POINTER_TYPE unsigned long
+ #else
+ #define NK_POINTER_TYPE unsigned int
+ #endif
+ #else
+ #define NK_POINTER_TYPE unsigned long
+ #endif
+ #endif
+#endif
+
+typedef NK_INT8 nk_char;
+typedef NK_UINT8 nk_uchar;
+typedef NK_UINT8 nk_byte;
+typedef NK_INT16 nk_short;
+typedef NK_UINT16 nk_ushort;
+typedef NK_INT32 nk_int;
+typedef NK_UINT32 nk_uint;
+typedef NK_SIZE_TYPE nk_size;
+typedef NK_POINTER_TYPE nk_ptr;
+
+typedef nk_uint nk_hash;
+typedef nk_uint nk_flags;
+typedef nk_uint nk_rune;
+
+/* Make sure correct type size:
+ * This will fire with a negative subscript error if the type sizes
+ * are set incorrectly by the compiler, and compile out if not */
+NK_STATIC_ASSERT(sizeof(nk_short) == 2);
+NK_STATIC_ASSERT(sizeof(nk_ushort) == 2);
+NK_STATIC_ASSERT(sizeof(nk_uint) == 4);
+NK_STATIC_ASSERT(sizeof(nk_int) == 4);
+NK_STATIC_ASSERT(sizeof(nk_byte) == 1);
+NK_STATIC_ASSERT(sizeof(nk_flags) >= 4);
+NK_STATIC_ASSERT(sizeof(nk_rune) >= 4);
+NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*));
+NK_STATIC_ASSERT(sizeof(nk_ptr) >= sizeof(void*));
+
+/* ============================================================================
+ *
+ * API
+ *
+ * =========================================================================== */
+struct nk_buffer;
+struct nk_allocator;
+struct nk_command_buffer;
+struct nk_draw_command;
+struct nk_convert_config;
+struct nk_style_item;
+struct nk_text_edit;
+struct nk_draw_list;
+struct nk_user_font;
+struct nk_panel;
+struct nk_context;
+struct nk_draw_vertex_layout_element;
+struct nk_style_button;
+struct nk_style_toggle;
+struct nk_style_selectable;
+struct nk_style_slide;
+struct nk_style_progress;
+struct nk_style_scrollbar;
+struct nk_style_edit;
+struct nk_style_property;
+struct nk_style_chart;
+struct nk_style_combo;
+struct nk_style_tab;
+struct nk_style_window_header;
+struct nk_style_window;
+
+enum {nk_false, nk_true};
+struct nk_color {nk_byte r,g,b,a;};
+struct nk_colorf {float r,g,b,a;};
+struct nk_vec2 {float x,y;};
+struct nk_vec2i {short x, y;};
+struct nk_rect {float x,y,w,h;};
+struct nk_recti {short x,y,w,h;};
+typedef char nk_glyph[NK_UTF_SIZE];
+typedef union {void *ptr; int id;} nk_handle;
+struct nk_image {nk_handle handle;unsigned short w,h;unsigned short region[4];};
+struct nk_cursor {struct nk_image img; struct nk_vec2 size, offset;};
+struct nk_scroll {nk_uint x, y;};
+
+enum nk_heading {NK_UP, NK_RIGHT, NK_DOWN, NK_LEFT};
+enum nk_button_behavior {NK_BUTTON_DEFAULT, NK_BUTTON_REPEATER};
+enum nk_modify {NK_FIXED = nk_false, NK_MODIFIABLE = nk_true};
+enum nk_orientation {NK_VERTICAL, NK_HORIZONTAL};
+enum nk_collapse_states {NK_MINIMIZED = nk_false, NK_MAXIMIZED = nk_true};
+enum nk_show_states {NK_HIDDEN = nk_false, NK_SHOWN = nk_true};
+enum nk_chart_type {NK_CHART_LINES, NK_CHART_COLUMN, NK_CHART_MAX};
+enum nk_chart_event {NK_CHART_HOVERING = 0x01, NK_CHART_CLICKED = 0x02};
+enum nk_color_format {NK_RGB, NK_RGBA};
+enum nk_popup_type {NK_POPUP_STATIC, NK_POPUP_DYNAMIC};
+enum nk_layout_format {NK_DYNAMIC, NK_STATIC};
+enum nk_tree_type {NK_TREE_NODE, NK_TREE_TAB};
+
+typedef void*(*nk_plugin_alloc)(nk_handle, void *old, nk_size);
+typedef void (*nk_plugin_free)(nk_handle, void *old);
+typedef int(*nk_plugin_filter)(const struct nk_text_edit*, nk_rune unicode);
+typedef void(*nk_plugin_paste)(nk_handle, struct nk_text_edit*);
+typedef void(*nk_plugin_copy)(nk_handle, const char*, int len);
+
+struct nk_allocator {
+ nk_handle userdata;
+ nk_plugin_alloc alloc;
+ nk_plugin_free free;
+};
+enum nk_symbol_type {
+ NK_SYMBOL_NONE,
+ NK_SYMBOL_X,
+ NK_SYMBOL_UNDERSCORE,
+ NK_SYMBOL_CIRCLE_SOLID,
+ NK_SYMBOL_CIRCLE_OUTLINE,
+ NK_SYMBOL_RECT_SOLID,
+ NK_SYMBOL_RECT_OUTLINE,
+ NK_SYMBOL_TRIANGLE_UP,
+ NK_SYMBOL_TRIANGLE_DOWN,
+ NK_SYMBOL_TRIANGLE_LEFT,
+ NK_SYMBOL_TRIANGLE_RIGHT,
+ NK_SYMBOL_PLUS,
+ NK_SYMBOL_MINUS,
+ NK_SYMBOL_MAX
+};
+/* =============================================================================
+ *
+ * CONTEXT
+ *
+ * =============================================================================*/
+/*/// ### Context
+/// Contexts are the main entry point and the majestro of nuklear and contain all required state.
+/// They are used for window, memory, input, style, stack, commands and time management and need
+/// to be passed into all nuklear GUI specific functions.
+///
+/// #### Usage
+/// To use a context it first has to be initialized which can be achieved by calling
+/// one of either `nk_init_default`, `nk_init_fixed`, `nk_init`, `nk_init_custom`.
+/// Each takes in a font handle and a specific way of handling memory. Memory control
+/// hereby ranges from standard library to just specifying a fixed sized block of memory
+/// which nuklear has to manage itself from.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_context ctx;
+/// nk_init_xxx(&ctx, ...);
+/// while (1) {
+/// // [...]
+/// nk_clear(&ctx);
+/// }
+/// nk_free(&ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// #### Reference
+/// Function | Description
+/// --------------------|-------------------------------------------------------
+/// __nk_init_default__ | Initializes context with standard library memory allocation (malloc,free)
+/// __nk_init_fixed__ | Initializes context from single fixed size memory block
+/// __nk_init__ | Initializes context with memory allocator callbacks for alloc and free
+/// __nk_init_custom__ | Initializes context from two buffers. One for draw commands the other for window/panel/table allocations
+/// __nk_clear__ | Called at the end of the frame to reset and prepare the context for the next frame
+/// __nk_free__ | Shutdown and free all memory allocated inside the context
+/// __nk_set_user_data__| Utility function to pass user data to draw command
+ */
+#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
+/*/// #### nk_init_default
+/// Initializes a `nk_context` struct with a default standard library allocator.
+/// Should be used if you don't want to be bothered with memory management in nuklear.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_init_default(struct nk_context *ctx, const struct nk_user_font *font);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|---------------------------------------------------------------
+/// __ctx__ | Must point to an either stack or heap allocated `nk_context` struct
+/// __font__ | Must point to a previously initialized font handle for more info look at font documentation
+///
+/// Returns either `false(0)` on failure or `true(1)` on success.
+///
+*/
+NK_API int nk_init_default(struct nk_context*, const struct nk_user_font*);
+#endif
+/*/// #### nk_init_fixed
+/// Initializes a `nk_context` struct from single fixed size memory block
+/// Should be used if you want complete control over nuklear's memory management.
+/// Especially recommended for system with little memory or systems with virtual memory.
+/// For the later case you can just allocate for example 16MB of virtual memory
+/// and only the required amount of memory will actually be committed.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_init_fixed(struct nk_context *ctx, void *memory, nk_size size, const struct nk_user_font *font);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// !!! Warning
+/// make sure the passed memory block is aligned correctly for `nk_draw_commands`.
+///
+/// Parameter | Description
+/// ------------|--------------------------------------------------------------
+/// __ctx__ | Must point to an either stack or heap allocated `nk_context` struct
+/// __memory__ | Must point to a previously allocated memory block
+/// __size__ | Must contain the total size of __memory__
+/// __font__ | Must point to a previously initialized font handle for more info look at font documentation
+///
+/// Returns either `false(0)` on failure or `true(1)` on success.
+*/
+NK_API int nk_init_fixed(struct nk_context*, void *memory, nk_size size, const struct nk_user_font*);
+/*/// #### nk_init
+/// Initializes a `nk_context` struct with memory allocation callbacks for nuklear to allocate
+/// memory from. Used internally for `nk_init_default` and provides a kitchen sink allocation
+/// interface to nuklear. Can be useful for cases like monitoring memory consumption.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_init(struct nk_context *ctx, struct nk_allocator *alloc, const struct nk_user_font *font);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|---------------------------------------------------------------
+/// __ctx__ | Must point to an either stack or heap allocated `nk_context` struct
+/// __alloc__ | Must point to a previously allocated memory allocator
+/// __font__ | Must point to a previously initialized font handle for more info look at font documentation
+///
+/// Returns either `false(0)` on failure or `true(1)` on success.
+*/
+NK_API int nk_init(struct nk_context*, struct nk_allocator*, const struct nk_user_font*);
+/*/// #### nk_init_custom
+/// Initializes a `nk_context` struct from two different either fixed or growing
+/// buffers. The first buffer is for allocating draw commands while the second buffer is
+/// used for allocating windows, panels and state tables.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_init_custom(struct nk_context *ctx, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font *font);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|---------------------------------------------------------------
+/// __ctx__ | Must point to an either stack or heap allocated `nk_context` struct
+/// __cmds__ | Must point to a previously initialized memory buffer either fixed or dynamic to store draw commands into
+/// __pool__ | Must point to a previously initialized memory buffer either fixed or dynamic to store windows, panels and tables
+/// __font__ | Must point to a previously initialized font handle for more info look at font documentation
+///
+/// Returns either `false(0)` on failure or `true(1)` on success.
+*/
+NK_API int nk_init_custom(struct nk_context*, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font*);
+/*/// #### nk_clear
+/// Resets the context state at the end of the frame. This includes mostly
+/// garbage collector tasks like removing windows or table not called and therefore
+/// used anymore.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_clear(struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to a previously initialized `nk_context` struct
+*/
+NK_API void nk_clear(struct nk_context*);
+/*/// #### nk_free
+/// Frees all memory allocated by nuklear. Not needed if context was
+/// initialized with `nk_init_fixed`.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_free(struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to a previously initialized `nk_context` struct
+*/
+NK_API void nk_free(struct nk_context*);
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+/*/// #### nk_set_user_data
+/// Sets the currently passed userdata passed down into each draw command.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_set_user_data(struct nk_context *ctx, nk_handle data);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|--------------------------------------------------------------
+/// __ctx__ | Must point to a previously initialized `nk_context` struct
+/// __data__ | Handle with either pointer or index to be passed into every draw commands
+*/
+NK_API void nk_set_user_data(struct nk_context*, nk_handle handle);
+#endif
+/* =============================================================================
+ *
+ * INPUT
+ *
+ * =============================================================================*/
+/*/// ### Input
+/// The input API is responsible for holding the current input state composed of
+/// mouse, key and text input states.
+/// It is worth noting that no direct os or window handling is done in nuklear.
+/// Instead all input state has to be provided by platform specific code. This in one hand
+/// expects more work from the user and complicates usage but on the other hand
+/// provides simple abstraction over a big number of platforms, libraries and other
+/// already provided functionality.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// nk_input_begin(&ctx);
+/// while (GetEvent(&evt)) {
+/// if (evt.type == MOUSE_MOVE)
+/// nk_input_motion(&ctx, evt.motion.x, evt.motion.y);
+/// else if (evt.type == [...]) {
+/// // [...]
+/// }
+/// } nk_input_end(&ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// #### Usage
+/// Input state needs to be provided to nuklear by first calling `nk_input_begin`
+/// which resets internal state like delta mouse position and button transistions.
+/// After `nk_input_begin` all current input state needs to be provided. This includes
+/// mouse motion, button and key pressed and released, text input and scrolling.
+/// Both event- or state-based input handling are supported by this API
+/// and should work without problems. Finally after all input state has been
+/// mirrored `nk_input_end` needs to be called to finish input process.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_context ctx;
+/// nk_init_xxx(&ctx, ...);
+/// while (1) {
+/// Event evt;
+/// nk_input_begin(&ctx);
+/// while (GetEvent(&evt)) {
+/// if (evt.type == MOUSE_MOVE)
+/// nk_input_motion(&ctx, evt.motion.x, evt.motion.y);
+/// else if (evt.type == [...]) {
+/// // [...]
+/// }
+/// }
+/// nk_input_end(&ctx);
+/// // [...]
+/// nk_clear(&ctx);
+/// } nk_free(&ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// #### Reference
+/// Function | Description
+/// --------------------|-------------------------------------------------------
+/// __nk_input_begin__ | Begins the input mirroring process. Needs to be called before all other `nk_input_xxx` calls
+/// __nk_input_motion__ | Mirrors mouse cursor position
+/// __nk_input_key__ | Mirrors key state with either pressed or released
+/// __nk_input_button__ | Mirrors mouse button state with either pressed or released
+/// __nk_input_scroll__ | Mirrors mouse scroll values
+/// __nk_input_char__ | Adds a single ASCII text character into an internal text buffer
+/// __nk_input_glyph__ | Adds a single multi-byte UTF-8 character into an internal text buffer
+/// __nk_input_unicode__| Adds a single unicode rune into an internal text buffer
+/// __nk_input_end__ | Ends the input mirroring process by calculating state changes. Don't call any `nk_input_xxx` function referenced above after this call
+*/
+enum nk_keys {
+ NK_KEY_NONE,
+ NK_KEY_SHIFT,
+ NK_KEY_CTRL,
+ NK_KEY_DEL,
+ NK_KEY_ENTER,
+ NK_KEY_TAB,
+ NK_KEY_BACKSPACE,
+ NK_KEY_COPY,
+ NK_KEY_CUT,
+ NK_KEY_PASTE,
+ NK_KEY_UP,
+ NK_KEY_DOWN,
+ NK_KEY_LEFT,
+ NK_KEY_RIGHT,
+ /* Shortcuts: text field */
+ NK_KEY_TEXT_INSERT_MODE,
+ NK_KEY_TEXT_REPLACE_MODE,
+ NK_KEY_TEXT_RESET_MODE,
+ NK_KEY_TEXT_LINE_START,
+ NK_KEY_TEXT_LINE_END,
+ NK_KEY_TEXT_START,
+ NK_KEY_TEXT_END,
+ NK_KEY_TEXT_UNDO,
+ NK_KEY_TEXT_REDO,
+ NK_KEY_TEXT_SELECT_ALL,
+ NK_KEY_TEXT_WORD_LEFT,
+ NK_KEY_TEXT_WORD_RIGHT,
+ /* Shortcuts: scrollbar */
+ NK_KEY_SCROLL_START,
+ NK_KEY_SCROLL_END,
+ NK_KEY_SCROLL_DOWN,
+ NK_KEY_SCROLL_UP,
+ NK_KEY_MAX
+};
+enum nk_buttons {
+ NK_BUTTON_LEFT,
+ NK_BUTTON_MIDDLE,
+ NK_BUTTON_RIGHT,
+ NK_BUTTON_DOUBLE,
+ NK_BUTTON_MAX
+};
+/*/// #### nk_input_begin
+/// Begins the input mirroring process by resetting text, scroll
+/// mouse previous mouse position and movement as well as key state transitions,
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_input_begin(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to a previously initialized `nk_context` struct
+*/
+NK_API void nk_input_begin(struct nk_context*);
+/*/// #### nk_input_motion
+/// Mirrors current mouse position to nuklear
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_input_motion(struct nk_context *ctx, int x, int y);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to a previously initialized `nk_context` struct
+/// __x__ | Must hold an integer describing the current mouse cursor x-position
+/// __y__ | Must hold an integer describing the current mouse cursor y-position
+*/
+NK_API void nk_input_motion(struct nk_context*, int x, int y);
+/*/// #### nk_input_key
+/// Mirrors state of a specific key to nuklear
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_input_key(struct nk_context*, enum nk_keys key, int down);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to a previously initialized `nk_context` struct
+/// __key__ | Must be any value specified in enum `nk_keys` that needs to be mirrored
+/// __down__ | Must be 0 for key is up and 1 for key is down
+*/
+NK_API void nk_input_key(struct nk_context*, enum nk_keys, int down);
+/*/// #### nk_input_button
+/// Mirrors the state of a specific mouse button to nuklear
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_input_button(struct nk_context *ctx, enum nk_buttons btn, int x, int y, int down);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to a previously initialized `nk_context` struct
+/// __btn__ | Must be any value specified in enum `nk_buttons` that needs to be mirrored
+/// __x__ | Must contain an integer describing mouse cursor x-position on click up/down
+/// __y__ | Must contain an integer describing mouse cursor y-position on click up/down
+/// __down__ | Must be 0 for key is up and 1 for key is down
+*/
+NK_API void nk_input_button(struct nk_context*, enum nk_buttons, int x, int y, int down);
+/*/// #### nk_input_scroll
+/// Copies the last mouse scroll value to nuklear. Is generally
+/// a scroll value. So does not have to come from mouse and could also originate
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_input_scroll(struct nk_context *ctx, struct nk_vec2 val);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to a previously initialized `nk_context` struct
+/// __val__ | vector with both X- as well as Y-scroll value
+*/
+NK_API void nk_input_scroll(struct nk_context*, struct nk_vec2 val);
+/*/// #### nk_input_char
+/// Copies a single ASCII character into an internal text buffer
+/// This is basically a helper function to quickly push ASCII characters into
+/// nuklear.
+///
+/// !!! Note
+/// Stores up to NK_INPUT_MAX bytes between `nk_input_begin` and `nk_input_end`.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_input_char(struct nk_context *ctx, char c);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to a previously initialized `nk_context` struct
+/// __c__ | Must be a single ASCII character preferable one that can be printed
+*/
+NK_API void nk_input_char(struct nk_context*, char);
+/*/// #### nk_input_glyph
+/// Converts an encoded unicode rune into UTF-8 and copies the result into an
+/// internal text buffer.
+///
+/// !!! Note
+/// Stores up to NK_INPUT_MAX bytes between `nk_input_begin` and `nk_input_end`.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_input_glyph(struct nk_context *ctx, const nk_glyph g);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to a previously initialized `nk_context` struct
+/// __g__ | UTF-32 unicode codepoint
+*/
+NK_API void nk_input_glyph(struct nk_context*, const nk_glyph);
+/*/// #### nk_input_unicode
+/// Converts a unicode rune into UTF-8 and copies the result
+/// into an internal text buffer.
+/// !!! Note
+/// Stores up to NK_INPUT_MAX bytes between `nk_input_begin` and `nk_input_end`.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_input_unicode(struct nk_context*, nk_rune rune);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to a previously initialized `nk_context` struct
+/// __rune__ | UTF-32 unicode codepoint
+*/
+NK_API void nk_input_unicode(struct nk_context*, nk_rune);
+/*/// #### nk_input_end
+/// End the input mirroring process by resetting mouse grabbing
+/// state to ensure the mouse cursor is not grabbed indefinitely.///
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_input_end(struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to a previously initialized `nk_context` struct
+*/
+NK_API void nk_input_end(struct nk_context*);
+/* =============================================================================
+ *
+ * DRAWING
+ *
+ * =============================================================================*/
+/*/// ### Drawing
+/// This library was designed to be render backend agnostic so it does
+/// not draw anything to screen directly. Instead all drawn shapes, widgets
+/// are made of, are buffered into memory and make up a command queue.
+/// Each frame therefore fills the command buffer with draw commands
+/// that then need to be executed by the user and his own render backend.
+/// After that the command buffer needs to be cleared and a new frame can be
+/// started. It is probably important to note that the command buffer is the main
+/// drawing API and the optional vertex buffer API only takes this format and
+/// converts it into a hardware accessible format.
+///
+/// #### Usage
+/// To draw all draw commands accumulated over a frame you need your own render
+/// backend able to draw a number of 2D primitives. This includes at least
+/// filled and stroked rectangles, circles, text, lines, triangles and scissors.
+/// As soon as this criterion is met you can iterate over each draw command
+/// and execute each draw command in a interpreter like fashion:
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// const struct nk_command *cmd = 0;
+/// nk_foreach(cmd, &ctx) {
+/// switch (cmd->type) {
+/// case NK_COMMAND_LINE:
+/// your_draw_line_function(...)
+/// break;
+/// case NK_COMMAND_RECT
+/// your_draw_rect_function(...)
+/// break;
+/// case //...:
+/// //[...]
+/// }
+/// }
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// In program flow context draw commands need to be executed after input has been
+/// gathered and the complete UI with windows and their contained widgets have
+/// been executed and before calling `nk_clear` which frees all previously
+/// allocated draw commands.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_context ctx;
+/// nk_init_xxx(&ctx, ...);
+/// while (1) {
+/// Event evt;
+/// nk_input_begin(&ctx);
+/// while (GetEvent(&evt)) {
+/// if (evt.type == MOUSE_MOVE)
+/// nk_input_motion(&ctx, evt.motion.x, evt.motion.y);
+/// else if (evt.type == [...]) {
+/// [...]
+/// }
+/// }
+/// nk_input_end(&ctx);
+/// //
+/// // [...]
+/// //
+/// const struct nk_command *cmd = 0;
+/// nk_foreach(cmd, &ctx) {
+/// switch (cmd->type) {
+/// case NK_COMMAND_LINE:
+/// your_draw_line_function(...)
+/// break;
+/// case NK_COMMAND_RECT
+/// your_draw_rect_function(...)
+/// break;
+/// case ...:
+/// // [...]
+/// }
+/// nk_clear(&ctx);
+/// }
+/// nk_free(&ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// You probably noticed that you have to draw all of the UI each frame which is
+/// quite wasteful. While the actual UI updating loop is quite fast rendering
+/// without actually needing it is not. So there are multiple things you could do.
+///
+/// First is only update on input. This of course is only an option if your
+/// application only depends on the UI and does not require any outside calculations.
+/// If you actually only update on input make sure to update the UI two times each
+/// frame and call `nk_clear` directly after the first pass and only draw in
+/// the second pass. In addition it is recommended to also add additional timers
+/// to make sure the UI is not drawn more than a fixed number of frames per second.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_context ctx;
+/// nk_init_xxx(&ctx, ...);
+/// while (1) {
+/// // [...wait for input ]
+/// // [...do two UI passes ...]
+/// do_ui(...)
+/// nk_clear(&ctx);
+/// do_ui(...)
+/// //
+/// // draw
+/// const struct nk_command *cmd = 0;
+/// nk_foreach(cmd, &ctx) {
+/// switch (cmd->type) {
+/// case NK_COMMAND_LINE:
+/// your_draw_line_function(...)
+/// break;
+/// case NK_COMMAND_RECT
+/// your_draw_rect_function(...)
+/// break;
+/// case ...:
+/// //[...]
+/// }
+/// nk_clear(&ctx);
+/// }
+/// nk_free(&ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// The second probably more applicable trick is to only draw if anything changed.
+/// It is not really useful for applications with continuous draw loop but
+/// quite useful for desktop applications. To actually get nuklear to only
+/// draw on changes you first have to define `NK_ZERO_COMMAND_MEMORY` and
+/// allocate a memory buffer that will store each unique drawing output.
+/// After each frame you compare the draw command memory inside the library
+/// with your allocated buffer by memcmp. If memcmp detects differences
+/// you have to copy the command buffer into the allocated buffer
+/// and then draw like usual (this example uses fixed memory but you could
+/// use dynamically allocated memory).
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// //[... other defines ...]
+/// #define NK_ZERO_COMMAND_MEMORY
+/// #include "nuklear.h"
+/// //
+/// // setup context
+/// struct nk_context ctx;
+/// void *last = calloc(1,64*1024);
+/// void *buf = calloc(1,64*1024);
+/// nk_init_fixed(&ctx, buf, 64*1024);
+/// //
+/// // loop
+/// while (1) {
+/// // [...input...]
+/// // [...ui...]
+/// void *cmds = nk_buffer_memory(&ctx.memory);
+/// if (memcmp(cmds, last, ctx.memory.allocated)) {
+/// memcpy(last,cmds,ctx.memory.allocated);
+/// const struct nk_command *cmd = 0;
+/// nk_foreach(cmd, &ctx) {
+/// switch (cmd->type) {
+/// case NK_COMMAND_LINE:
+/// your_draw_line_function(...)
+/// break;
+/// case NK_COMMAND_RECT
+/// your_draw_rect_function(...)
+/// break;
+/// case ...:
+/// // [...]
+/// }
+/// }
+/// }
+/// nk_clear(&ctx);
+/// }
+/// nk_free(&ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Finally while using draw commands makes sense for higher abstracted platforms like
+/// X11 and Win32 or drawing libraries it is often desirable to use graphics
+/// hardware directly. Therefore it is possible to just define
+/// `NK_INCLUDE_VERTEX_BUFFER_OUTPUT` which includes optional vertex output.
+/// To access the vertex output you first have to convert all draw commands into
+/// vertexes by calling `nk_convert` which takes in your preferred vertex format.
+/// After successfully converting all draw commands just iterate over and execute all
+/// vertex draw commands:
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// // fill configuration
+/// struct nk_convert_config cfg = {};
+/// static const struct nk_draw_vertex_layout_element vertex_layout[] = {
+/// {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct your_vertex, pos)},
+/// {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct your_vertex, uv)},
+/// {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct your_vertex, col)},
+/// {NK_VERTEX_LAYOUT_END}
+/// };
+/// cfg.shape_AA = NK_ANTI_ALIASING_ON;
+/// cfg.line_AA = NK_ANTI_ALIASING_ON;
+/// cfg.vertex_layout = vertex_layout;
+/// cfg.vertex_size = sizeof(struct your_vertex);
+/// cfg.vertex_alignment = NK_ALIGNOF(struct your_vertex);
+/// cfg.circle_segment_count = 22;
+/// cfg.curve_segment_count = 22;
+/// cfg.arc_segment_count = 22;
+/// cfg.global_alpha = 1.0f;
+/// cfg.null = dev->null;
+/// //
+/// // setup buffers and convert
+/// struct nk_buffer cmds, verts, idx;
+/// nk_buffer_init_default(&cmds);
+/// nk_buffer_init_default(&verts);
+/// nk_buffer_init_default(&idx);
+/// nk_convert(&ctx, &cmds, &verts, &idx, &cfg);
+/// //
+/// // draw
+/// nk_draw_foreach(cmd, &ctx, &cmds) {
+/// if (!cmd->elem_count) continue;
+/// //[...]
+/// }
+/// nk_buffer_free(&cms);
+/// nk_buffer_free(&verts);
+/// nk_buffer_free(&idx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// #### Reference
+/// Function | Description
+/// --------------------|-------------------------------------------------------
+/// __nk__begin__ | Returns the first draw command in the context draw command list to be drawn
+/// __nk__next__ | Increments the draw command iterator to the next command inside the context draw command list
+/// __nk_foreach__ | Iterates over each draw command inside the context draw command list
+/// __nk_convert__ | Converts from the abstract draw commands list into a hardware accessible vertex format
+/// __nk_draw_begin__ | Returns the first vertex command in the context vertex draw list to be executed
+/// __nk__draw_next__ | Increments the vertex command iterator to the next command inside the context vertex command list
+/// __nk__draw_end__ | Returns the end of the vertex draw list
+/// __nk_draw_foreach__ | Iterates over each vertex draw command inside the vertex draw list
+*/
+enum nk_anti_aliasing {NK_ANTI_ALIASING_OFF, NK_ANTI_ALIASING_ON};
+enum nk_convert_result {
+ NK_CONVERT_SUCCESS = 0,
+ NK_CONVERT_INVALID_PARAM = 1,
+ NK_CONVERT_COMMAND_BUFFER_FULL = NK_FLAG(1),
+ NK_CONVERT_VERTEX_BUFFER_FULL = NK_FLAG(2),
+ NK_CONVERT_ELEMENT_BUFFER_FULL = NK_FLAG(3)
+};
+struct nk_draw_null_texture {
+ nk_handle texture; /* texture handle to a texture with a white pixel */
+ struct nk_vec2 uv; /* coordinates to a white pixel in the texture */
+};
+struct nk_convert_config {
+ float global_alpha; /* global alpha value */
+ enum nk_anti_aliasing line_AA; /* line anti-aliasing flag can be turned off if you are tight on memory */
+ enum nk_anti_aliasing shape_AA; /* shape anti-aliasing flag can be turned off if you are tight on memory */
+ unsigned circle_segment_count; /* number of segments used for circles: default to 22 */
+ unsigned arc_segment_count; /* number of segments used for arcs: default to 22 */
+ unsigned curve_segment_count; /* number of segments used for curves: default to 22 */
+ struct nk_draw_null_texture null; /* handle to texture with a white pixel for shape drawing */
+ const struct nk_draw_vertex_layout_element *vertex_layout; /* describes the vertex output format and packing */
+ nk_size vertex_size; /* sizeof one vertex for vertex packing */
+ nk_size vertex_alignment; /* vertex alignment: Can be obtained by NK_ALIGNOF */
+};
+/*/// #### nk__begin
+/// Returns a draw command list iterator to iterate all draw
+/// commands accumulated over one frame.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// const struct nk_command* nk__begin(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | must point to an previously initialized `nk_context` struct at the end of a frame
+///
+/// Returns draw command pointer pointing to the first command inside the draw command list
+*/
+NK_API const struct nk_command* nk__begin(struct nk_context*);
+/*/// #### nk__next
+/// Returns a draw command list iterator to iterate all draw
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// const struct nk_command* nk__next(struct nk_context*, const struct nk_command*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct at the end of a frame
+/// __cmd__ | Must point to an previously a draw command either returned by `nk__begin` or `nk__next`
+///
+/// Returns draw command pointer pointing to the next command inside the draw command list
+*/
+NK_API const struct nk_command* nk__next(struct nk_context*, const struct nk_command*);
+/*/// #### nk_foreach
+/// Iterates over each draw command inside the context draw command list
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// #define nk_foreach(c, ctx)
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct at the end of a frame
+/// __cmd__ | Command pointer initialized to NULL
+///
+/// Returns draw command pointer pointing to the next command inside the draw command list
+*/
+#define nk_foreach(c, ctx) for((c) = nk__begin(ctx); (c) != 0; (c) = nk__next(ctx,c))
+#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+/*/// #### nk_convert
+/// Converts all internal draw commands into vertex draw commands and fills
+/// three buffers with vertexes, vertex draw commands and vertex indices. The vertex format
+/// as well as some other configuration values have to be configured by filling out a
+/// `nk_convert_config` struct.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// nk_flags nk_convert(struct nk_context *ctx, struct nk_buffer *cmds,
+// struct nk_buffer *vertices, struct nk_buffer *elements, const struct nk_convert_config*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct at the end of a frame
+/// __cmds__ | Must point to a previously initialized buffer to hold converted vertex draw commands
+/// __vertices__| Must point to a previously initialized buffer to hold all produced vertices
+/// __elements__| Must point to a previously initialized buffer to hold all produced vertex indices
+/// __config__ | Must point to a filled out `nk_config` struct to configure the conversion process
+///
+/// Returns one of enum nk_convert_result error codes
+///
+/// Parameter | Description
+/// --------------------------------|-----------------------------------------------------------
+/// NK_CONVERT_SUCCESS | Signals a successful draw command to vertex buffer conversion
+/// NK_CONVERT_INVALID_PARAM | An invalid argument was passed in the function call
+/// NK_CONVERT_COMMAND_BUFFER_FULL | The provided buffer for storing draw commands is full or failed to allocate more memory
+/// NK_CONVERT_VERTEX_BUFFER_FULL | The provided buffer for storing vertices is full or failed to allocate more memory
+/// NK_CONVERT_ELEMENT_BUFFER_FULL | The provided buffer for storing indicies is full or failed to allocate more memory
+*/
+NK_API nk_flags nk_convert(struct nk_context*, struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements, const struct nk_convert_config*);
+/*/// #### nk__draw_begin
+/// Returns a draw vertex command buffer iterator to iterate each the vertex draw command buffer
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// const struct nk_draw_command* nk__draw_begin(const struct nk_context*, const struct nk_buffer*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct at the end of a frame
+/// __buf__ | Must point to an previously by `nk_convert` filled out vertex draw command buffer
+///
+/// Returns vertex draw command pointer pointing to the first command inside the vertex draw command buffer
+*/
+NK_API const struct nk_draw_command* nk__draw_begin(const struct nk_context*, const struct nk_buffer*);
+/*/// #### nk__draw_end
+/// Returns the vertex draw command at the end of the vertex draw command buffer
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// const struct nk_draw_command* nk__draw_end(const struct nk_context *ctx, const struct nk_buffer *buf);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct at the end of a frame
+/// __buf__ | Must point to an previously by `nk_convert` filled out vertex draw command buffer
+///
+/// Returns vertex draw command pointer pointing to the end of the last vertex draw command inside the vertex draw command buffer
+*/
+NK_API const struct nk_draw_command* nk__draw_end(const struct nk_context*, const struct nk_buffer*);
+/*/// #### nk__draw_next
+/// Increments the vertex draw command buffer iterator
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*, const struct nk_buffer*, const struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __cmd__ | Must point to an previously either by `nk__draw_begin` or `nk__draw_next` returned vertex draw command
+/// __buf__ | Must point to an previously by `nk_convert` filled out vertex draw command buffer
+/// __ctx__ | Must point to an previously initialized `nk_context` struct at the end of a frame
+///
+/// Returns vertex draw command pointer pointing to the end of the last vertex draw command inside the vertex draw command buffer
+*/
+NK_API const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*, const struct nk_buffer*, const struct nk_context*);
+/*/// #### nk_draw_foreach
+/// Iterates over each vertex draw command inside a vertex draw command buffer
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// #define nk_draw_foreach(cmd,ctx, b)
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __cmd__ | `nk_draw_command`iterator set to NULL
+/// __buf__ | Must point to an previously by `nk_convert` filled out vertex draw command buffer
+/// __ctx__ | Must point to an previously initialized `nk_context` struct at the end of a frame
+*/
+#define nk_draw_foreach(cmd,ctx, b) for((cmd)=nk__draw_begin(ctx, b); (cmd)!=0; (cmd)=nk__draw_next(cmd, b, ctx))
+#endif
+/* =============================================================================
+ *
+ * WINDOW
+ *
+ * =============================================================================
+/// ### Window
+/// Windows are the main persistent state used inside nuklear and are life time
+/// controlled by simply "retouching" (i.e. calling) each window each frame.
+/// All widgets inside nuklear can only be added inside function pair `nk_begin_xxx`
+/// and `nk_end`. Calling any widgets outside these two functions will result in an
+/// assert in debug or no state change in release mode.<br /><br />
+///
+/// Each window holds frame persistent state like position, size, flags, state tables,
+/// and some garbage collected internal persistent widget state. Each window
+/// is linked into a window stack list which determines the drawing and overlapping
+/// order. The topmost window thereby is the currently active window.<br /><br />
+///
+/// To change window position inside the stack occurs either automatically by
+/// user input by being clicked on or programmatically by calling `nk_window_focus`.
+/// Windows by default are visible unless explicitly being defined with flag
+/// `NK_WINDOW_HIDDEN`, the user clicked the close button on windows with flag
+/// `NK_WINDOW_CLOSABLE` or if a window was explicitly hidden by calling
+/// `nk_window_show`. To explicitly close and destroy a window call `nk_window_close`.<br /><br />
+///
+/// #### Usage
+/// To create and keep a window you have to call one of the two `nk_begin_xxx`
+/// functions to start window declarations and `nk_end` at the end. Furthermore it
+/// is recommended to check the return value of `nk_begin_xxx` and only process
+/// widgets inside the window if the value is not 0. Either way you have to call
+/// `nk_end` at the end of window declarations. Furthermore, do not attempt to
+/// nest `nk_begin_xxx` calls which will hopefully result in an assert or if not
+/// in a segmentation fault.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// if (nk_begin_xxx(...) {
+/// // [... widgets ...]
+/// }
+/// nk_end(ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// In the grand concept window and widget declarations need to occur after input
+/// handling and before drawing to screen. Not doing so can result in higher
+/// latency or at worst invalid behavior. Furthermore make sure that `nk_clear`
+/// is called at the end of the frame. While nuklear's default platform backends
+/// already call `nk_clear` for you if you write your own backend not calling
+/// `nk_clear` can cause asserts or even worse undefined behavior.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_context ctx;
+/// nk_init_xxx(&ctx, ...);
+/// while (1) {
+/// Event evt;
+/// nk_input_begin(&ctx);
+/// while (GetEvent(&evt)) {
+/// if (evt.type == MOUSE_MOVE)
+/// nk_input_motion(&ctx, evt.motion.x, evt.motion.y);
+/// else if (evt.type == [...]) {
+/// nk_input_xxx(...);
+/// }
+/// }
+/// nk_input_end(&ctx);
+///
+/// if (nk_begin_xxx(...) {
+/// //[...]
+/// }
+/// nk_end(ctx);
+///
+/// const struct nk_command *cmd = 0;
+/// nk_foreach(cmd, &ctx) {
+/// case NK_COMMAND_LINE:
+/// your_draw_line_function(...)
+/// break;
+/// case NK_COMMAND_RECT
+/// your_draw_rect_function(...)
+/// break;
+/// case //...:
+/// //[...]
+/// }
+/// nk_clear(&ctx);
+/// }
+/// nk_free(&ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// #### Reference
+/// Function | Description
+/// ------------------------------------|----------------------------------------
+/// nk_begin | Starts a new window; needs to be called every frame for every window (unless hidden) or otherwise the window gets removed
+/// nk_begin_titled | Extended window start with separated title and identifier to allow multiple windows with same name but not title
+/// nk_end | Needs to be called at the end of the window building process to process scaling, scrollbars and general cleanup
+//
+/// nk_window_find | Finds and returns the window with give name
+/// nk_window_get_bounds | Returns a rectangle with screen position and size of the currently processed window.
+/// nk_window_get_position | Returns the position of the currently processed window
+/// nk_window_get_size | Returns the size with width and height of the currently processed window
+/// nk_window_get_width | Returns the width of the currently processed window
+/// nk_window_get_height | Returns the height of the currently processed window
+/// nk_window_get_panel | Returns the underlying panel which contains all processing state of the current window
+/// nk_window_get_content_region | Returns the position and size of the currently visible and non-clipped space inside the currently processed window
+/// nk_window_get_content_region_min | Returns the upper rectangle position of the currently visible and non-clipped space inside the currently processed window
+/// nk_window_get_content_region_max | Returns the upper rectangle position of the currently visible and non-clipped space inside the currently processed window
+/// nk_window_get_content_region_size | Returns the size of the currently visible and non-clipped space inside the currently processed window
+/// nk_window_get_canvas | Returns the draw command buffer. Can be used to draw custom widgets
+/// nk_window_has_focus | Returns if the currently processed window is currently active
+/// nk_window_is_collapsed | Returns if the window with given name is currently minimized/collapsed
+/// nk_window_is_closed | Returns if the currently processed window was closed
+/// nk_window_is_hidden | Returns if the currently processed window was hidden
+/// nk_window_is_active | Same as nk_window_has_focus for some reason
+/// nk_window_is_hovered | Returns if the currently processed window is currently being hovered by mouse
+/// nk_window_is_any_hovered | Return if any window currently hovered
+/// nk_item_is_any_active | Returns if any window or widgets is currently hovered or active
+//
+/// nk_window_set_bounds | Updates position and size of the currently processed window
+/// nk_window_set_position | Updates position of the currently process window
+/// nk_window_set_size | Updates the size of the currently processed window
+/// nk_window_set_focus | Set the currently processed window as active window
+//
+/// nk_window_close | Closes the window with given window name which deletes the window at the end of the frame
+/// nk_window_collapse | Collapses the window with given window name
+/// nk_window_collapse_if | Collapses the window with given window name if the given condition was met
+/// nk_window_show | Hides a visible or reshows a hidden window
+/// nk_window_show_if | Hides/shows a window depending on condition
+*/
+/*
+/// #### nk_panel_flags
+/// Flag | Description
+/// ----------------------------|----------------------------------------
+/// NK_WINDOW_BORDER | Draws a border around the window to visually separate window from the background
+/// NK_WINDOW_MOVABLE | The movable flag indicates that a window can be moved by user input or by dragging the window header
+/// NK_WINDOW_SCALABLE | The scalable flag indicates that a window can be scaled by user input by dragging a scaler icon at the button of the window
+/// NK_WINDOW_CLOSABLE | Adds a closable icon into the header
+/// NK_WINDOW_MINIMIZABLE | Adds a minimize icon into the header
+/// NK_WINDOW_NO_SCROLLBAR | Removes the scrollbar from the window
+/// NK_WINDOW_TITLE | Forces a header at the top at the window showing the title
+/// NK_WINDOW_SCROLL_AUTO_HIDE | Automatically hides the window scrollbar if no user interaction: also requires delta time in `nk_context` to be set each frame
+/// NK_WINDOW_BACKGROUND | Always keep window in the background
+/// NK_WINDOW_SCALE_LEFT | Puts window scaler in the left-ottom corner instead right-bottom
+/// NK_WINDOW_NO_INPUT | Prevents window of scaling, moving or getting focus
+///
+/// #### nk_collapse_states
+/// State | Description
+/// ----------------|-----------------------------------------------------------
+/// __NK_MINIMIZED__| UI section is collased and not visibile until maximized
+/// __NK_MAXIMIZED__| UI section is extended and visibile until minimized
+/// <br /><br />
+*/
+enum nk_panel_flags {
+ NK_WINDOW_BORDER = NK_FLAG(0),
+ NK_WINDOW_MOVABLE = NK_FLAG(1),
+ NK_WINDOW_SCALABLE = NK_FLAG(2),
+ NK_WINDOW_CLOSABLE = NK_FLAG(3),
+ NK_WINDOW_MINIMIZABLE = NK_FLAG(4),
+ NK_WINDOW_NO_SCROLLBAR = NK_FLAG(5),
+ NK_WINDOW_TITLE = NK_FLAG(6),
+ NK_WINDOW_SCROLL_AUTO_HIDE = NK_FLAG(7),
+ NK_WINDOW_BACKGROUND = NK_FLAG(8),
+ NK_WINDOW_SCALE_LEFT = NK_FLAG(9),
+ NK_WINDOW_NO_INPUT = NK_FLAG(10)
+};
+/*/// #### nk_begin
+/// Starts a new window; needs to be called every frame for every
+/// window (unless hidden) or otherwise the window gets removed
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __title__ | Window title and identifier. Needs to be persistent over frames to identify the window
+/// __bounds__ | Initial position and window size. However if you do not define `NK_WINDOW_SCALABLE` or `NK_WINDOW_MOVABLE` you can set window position and size every frame
+/// __flags__ | Window flags defined in the nk_panel_flags section with a number of different window behaviors
+///
+/// Returns `true(1)` if the window can be filled up with widgets from this point
+/// until `nk_end` or `false(0)` otherwise for example if minimized
+*/
+NK_API int nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags);
+/*/// #### nk_begin_titled
+/// Extended window start with separated title and identifier to allow multiple
+/// windows with same name but not title
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags flags);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Window identifier. Needs to be persistent over frames to identify the window
+/// __title__ | Window title displayed inside header if flag `NK_WINDOW_TITLE` or either `NK_WINDOW_CLOSABLE` or `NK_WINDOW_MINIMIZED` was set
+/// __bounds__ | Initial position and window size. However if you do not define `NK_WINDOW_SCALABLE` or `NK_WINDOW_MOVABLE` you can set window position and size every frame
+/// __flags__ | Window flags defined in the nk_panel_flags section with a number of different window behaviors
+///
+/// Returns `true(1)` if the window can be filled up with widgets from this point
+/// until `nk_end` or `false(0)` otherwise for example if minimized
+*/
+NK_API int nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags flags);
+/*/// #### nk_end
+/// Needs to be called at the end of the window building process to process scaling, scrollbars and general cleanup.
+/// All widget calls after this functions will result in asserts or no state changes
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_end(struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+*/
+NK_API void nk_end(struct nk_context *ctx);
+/*/// #### nk_window_find
+/// Finds and returns a window from passed name
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_end(struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Window identifier
+///
+/// Returns a `nk_window` struct pointing to the identified window or NULL if
+/// no window with given name was found
+*/
+NK_API struct nk_window *nk_window_find(struct nk_context *ctx, const char *name);
+/*/// #### nk_window_get_bounds
+///
+/// Returns a rectangle with screen position and size of the currently processed window
+/// !!! WARNING
+/// Only call this function between calls `nk_begin_xxx` and `nk_end`
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_rect nk_window_get_bounds(const struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// Returns a `nk_rect` struct with window upper left window position and size
+*/
+NK_API struct nk_rect nk_window_get_bounds(const struct nk_context *ctx);
+/*/// #### nk_window_get_bounds
+///
+/// Returns the position of the currently processed window.
+/// !!! WARNING
+/// Only call this function between calls `nk_begin_xxx` and `nk_end`
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_vec2 nk_window_get_position(const struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// Returns a `nk_vec2` struct with window upper left position
+*/
+NK_API struct nk_vec2 nk_window_get_position(const struct nk_context *ctx);
+/*/// #### nk_window_get_size
+///
+/// Returns the size with width and height of the currently processed window.
+/// !!! WARNING
+/// Only call this function between calls `nk_begin_xxx` and `nk_end`
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_vec2 nk_window_get_size(const struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// Returns a `nk_vec2` struct with window width and height
+*/
+NK_API struct nk_vec2 nk_window_get_size(const struct nk_context*);
+/*/// #### nk_window_get_width
+///
+/// Returns the width of the currently processed window.
+/// !!! WARNING
+/// Only call this function between calls `nk_begin_xxx` and `nk_end`
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// float nk_window_get_width(const struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// Returns the current window width
+*/
+NK_API float nk_window_get_width(const struct nk_context*);
+/*/// #### nk_window_get_height
+///
+/// Returns the height of the currently processed window.
+/// !!! WARNING
+/// Only call this function between calls `nk_begin_xxx` and `nk_end`
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// float nk_window_get_height(const struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// Returns the current window height
+*/
+NK_API float nk_window_get_height(const struct nk_context*);
+/*/// #### nk_window_get_panel
+///
+/// Returns the underlying panel which contains all processing state of the current window.
+/// !!! WARNING
+/// Only call this function between calls `nk_begin_xxx` and `nk_end`
+/// !!! WARNING
+/// Do not keep the returned panel pointer around it is only valid until `nk_end`
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_panel* nk_window_get_panel(struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// Returns a pointer to window internal `nk_panel` state.
+*/
+NK_API struct nk_panel* nk_window_get_panel(struct nk_context*);
+/*/// #### nk_window_get_content_region
+///
+/// Returns the position and size of the currently visible and non-clipped space
+/// inside the currently processed window.
+/// !!! WARNING
+/// Only call this function between calls `nk_begin_xxx` and `nk_end`
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_rect nk_window_get_content_region(struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// Returns `nk_rect` struct with screen position and size (no scrollbar offset)
+/// of the visible space inside the current window
+*/
+NK_API struct nk_rect nk_window_get_content_region(struct nk_context*);
+/*/// #### nk_window_get_content_region_min
+///
+/// Returns the upper left position of the currently visible and non-clipped
+/// space inside the currently processed window.
+/// !!! WARNING
+/// Only call this function between calls `nk_begin_xxx` and `nk_end`
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_vec2 nk_window_get_content_region_min(struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// returns `nk_vec2` struct with upper left screen position (no scrollbar offset)
+/// of the visible space inside the current window
+*/
+NK_API struct nk_vec2 nk_window_get_content_region_min(struct nk_context*);
+/*/// #### nk_window_get_content_region_max
+///
+/// Returns the lower right screen position of the currently visible and
+/// non-clipped space inside the currently processed window.
+/// !!! WARNING
+/// Only call this function between calls `nk_begin_xxx` and `nk_end`
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_vec2 nk_window_get_content_region_max(struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// Returns `nk_vec2` struct with lower right screen position (no scrollbar offset)
+/// of the visible space inside the current window
+*/
+NK_API struct nk_vec2 nk_window_get_content_region_max(struct nk_context*);
+/*/// #### nk_window_get_content_region_size
+///
+/// Returns the size of the currently visible and non-clipped space inside the
+/// currently processed window
+/// !!! WARNING
+/// Only call this function between calls `nk_begin_xxx` and `nk_end`
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_vec2 nk_window_get_content_region_size(struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// Returns `nk_vec2` struct with size the visible space inside the current window
+*/
+NK_API struct nk_vec2 nk_window_get_content_region_size(struct nk_context*);
+/*/// #### nk_window_get_canvas
+/// Returns the draw command buffer. Can be used to draw custom widgets
+/// !!! WARNING
+/// Only call this function between calls `nk_begin_xxx` and `nk_end`
+/// !!! WARNING
+/// Do not keep the returned command buffer pointer around it is only valid until `nk_end`
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_command_buffer* nk_window_get_canvas(struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// Returns a pointer to window internal `nk_command_buffer` struct used as
+/// drawing canvas. Can be used to do custom drawing.
+*/
+NK_API struct nk_command_buffer* nk_window_get_canvas(struct nk_context*);
+/*/// #### nk_window_has_focus
+/// Returns if the currently processed window is currently active
+/// !!! WARNING
+/// Only call this function between calls `nk_begin_xxx` and `nk_end`
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_window_has_focus(const struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// Returns `false(0)` if current window is not active or `true(1)` if it is
+*/
+NK_API int nk_window_has_focus(const struct nk_context*);
+/*/// #### nk_window_is_hovered
+/// Return if the current window is being hovered
+/// !!! WARNING
+/// Only call this function between calls `nk_begin_xxx` and `nk_end`
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_window_is_hovered(struct nk_context *ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// Returns `true(1)` if current window is hovered or `false(0)` otherwise
+*/
+NK_API int nk_window_is_hovered(struct nk_context*);
+/*/// #### nk_window_is_collapsed
+/// Returns if the window with given name is currently minimized/collapsed
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_window_is_collapsed(struct nk_context *ctx, const char *name);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Identifier of window you want to check if it is collapsed
+///
+/// Returns `true(1)` if current window is minimized and `false(0)` if window not
+/// found or is not minimized
+*/
+NK_API int nk_window_is_collapsed(struct nk_context *ctx, const char *name);
+/*/// #### nk_window_is_closed
+/// Returns if the window with given name was closed by calling `nk_close`
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_window_is_closed(struct nk_context *ctx, const char *name);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Identifier of window you want to check if it is closed
+///
+/// Returns `true(1)` if current window was closed or `false(0)` window not found or not closed
+*/
+NK_API int nk_window_is_closed(struct nk_context*, const char*);
+/*/// #### nk_window_is_hidden
+/// Returns if the window with given name is hidden
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_window_is_hidden(struct nk_context *ctx, const char *name);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Identifier of window you want to check if it is hidden
+///
+/// Returns `true(1)` if current window is hidden or `false(0)` window not found or visible
+*/
+NK_API int nk_window_is_hidden(struct nk_context*, const char*);
+/*/// #### nk_window_is_active
+/// Same as nk_window_has_focus for some reason
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_window_is_active(struct nk_context *ctx, const char *name);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Identifier of window you want to check if it is active
+///
+/// Returns `true(1)` if current window is active or `false(0)` window not found or not active
+*/
+NK_API int nk_window_is_active(struct nk_context*, const char*);
+/*/// #### nk_window_is_any_hovered
+/// Returns if the any window is being hovered
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_window_is_any_hovered(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// Returns `true(1)` if any window is hovered or `false(0)` otherwise
+*/
+NK_API int nk_window_is_any_hovered(struct nk_context*);
+/*/// #### nk_item_is_any_active
+/// Returns if the any window is being hovered or any widget is currently active.
+/// Can be used to decide if input should be processed by UI or your specific input handling.
+/// Example could be UI and 3D camera to move inside a 3D space.
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_item_is_any_active(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+///
+/// Returns `true(1)` if any window is hovered or any item is active or `false(0)` otherwise
+*/
+NK_API int nk_item_is_any_active(struct nk_context*);
+/*/// #### nk_window_set_bounds
+/// Updates position and size of window with passed in name
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_window_set_bounds(struct nk_context*, const char *name, struct nk_rect bounds);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Identifier of the window to modify both position and size
+/// __bounds__ | Must point to a `nk_rect` struct with the new position and size
+*/
+NK_API void nk_window_set_bounds(struct nk_context*, const char *name, struct nk_rect bounds);
+/*/// #### nk_window_set_position
+/// Updates position of window with passed name
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_window_set_position(struct nk_context*, const char *name, struct nk_vec2 pos);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Identifier of the window to modify both position
+/// __pos__ | Must point to a `nk_vec2` struct with the new position
+*/
+NK_API void nk_window_set_position(struct nk_context*, const char *name, struct nk_vec2 pos);
+/*/// #### nk_window_set_size
+/// Updates size of window with passed in name
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_window_set_size(struct nk_context*, const char *name, struct nk_vec2);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Identifier of the window to modify both window size
+/// __size__ | Must point to a `nk_vec2` struct with new window size
+*/
+NK_API void nk_window_set_size(struct nk_context*, const char *name, struct nk_vec2);
+/*/// #### nk_window_set_focus
+/// Sets the window with given name as active
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_window_set_focus(struct nk_context*, const char *name);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Identifier of the window to set focus on
+*/
+NK_API void nk_window_set_focus(struct nk_context*, const char *name);
+/*/// #### nk_window_close
+/// Closes a window and marks it for being freed at the end of the frame
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_window_close(struct nk_context *ctx, const char *name);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Identifier of the window to close
+*/
+NK_API void nk_window_close(struct nk_context *ctx, const char *name);
+/*/// #### nk_window_collapse
+/// Updates collapse state of a window with given name
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_window_collapse(struct nk_context*, const char *name, enum nk_collapse_states state);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Identifier of the window to close
+/// __state__ | value out of nk_collapse_states section
+*/
+NK_API void nk_window_collapse(struct nk_context*, const char *name, enum nk_collapse_states state);
+/*/// #### nk_window_collapse_if
+/// Updates collapse state of a window with given name if given condition is met
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_window_collapse_if(struct nk_context*, const char *name, enum nk_collapse_states, int cond);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Identifier of the window to either collapse or maximize
+/// __state__ | value out of nk_collapse_states section the window should be put into
+/// __cond__ | condition that has to be met to actually commit the collapse state change
+*/
+NK_API void nk_window_collapse_if(struct nk_context*, const char *name, enum nk_collapse_states, int cond);
+/*/// #### nk_window_show
+/// updates visibility state of a window with given name
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_window_show(struct nk_context*, const char *name, enum nk_show_states);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Identifier of the window to either collapse or maximize
+/// __state__ | state with either visible or hidden to modify the window with
+*/
+NK_API void nk_window_show(struct nk_context*, const char *name, enum nk_show_states);
+/*/// #### nk_window_show_if
+/// Updates visibility state of a window with given name if a given condition is met
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_window_show_if(struct nk_context*, const char *name, enum nk_show_states, int cond);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __name__ | Identifier of the window to either hide or show
+/// __state__ | state with either visible or hidden to modify the window with
+/// __cond__ | condition that has to be met to actually commit the visbility state change
+*/
+NK_API void nk_window_show_if(struct nk_context*, const char *name, enum nk_show_states, int cond);
+/* =============================================================================
+ *
+ * LAYOUT
+ *
+ * =============================================================================
+/// ### Layouting
+/// Layouting in general describes placing widget inside a window with position and size.
+/// While in this particular implementation there are five different APIs for layouting
+/// each with different trade offs between control and ease of use. <br /><br />
+///
+/// All layouting methods in this library are based around the concept of a row.
+/// A row has a height the window content grows by and a number of columns and each
+/// layouting method specifies how each widget is placed inside the row.
+/// After a row has been allocated by calling a layouting functions and then
+/// filled with widgets will advance an internal pointer over the allocated row. <br /><br />
+///
+/// To actually define a layout you just call the appropriate layouting function
+/// and each subsequent widget call will place the widget as specified. Important
+/// here is that if you define more widgets then columns defined inside the layout
+/// functions it will allocate the next row without you having to make another layouting <br /><br />
+/// call.
+///
+/// Biggest limitation with using all these APIs outside the `nk_layout_space_xxx` API
+/// is that you have to define the row height for each. However the row height
+/// often depends on the height of the font. <br /><br />
+///
+/// To fix that internally nuklear uses a minimum row height that is set to the
+/// height plus padding of currently active font and overwrites the row height
+/// value if zero. <br /><br />
+///
+/// If you manually want to change the minimum row height then
+/// use nk_layout_set_min_row_height, and use nk_layout_reset_min_row_height to
+/// reset it back to be derived from font height. <br /><br />
+///
+/// Also if you change the font in nuklear it will automatically change the minimum
+/// row height for you and. This means if you change the font but still want
+/// a minimum row height smaller than the font you have to repush your value. <br /><br />
+///
+/// For actually more advanced UI I would even recommend using the `nk_layout_space_xxx`
+/// layouting method in combination with a cassowary constraint solver (there are
+/// some versions on github with permissive license model) to take over all control over widget
+/// layouting yourself. However for quick and dirty layouting using all the other layouting
+/// functions should be fine.
+///
+/// #### Usage
+/// 1. __nk_layout_row_dynamic__<br /><br />
+/// The easiest layouting function is `nk_layout_row_dynamic`. It provides each
+/// widgets with same horizontal space inside the row and dynamically grows
+/// if the owning window grows in width. So the number of columns dictates
+/// the size of each widget dynamically by formula:
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// widget_width = (window_width - padding - spacing) * (1/colum_count)
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Just like all other layouting APIs if you define more widget than columns this
+/// library will allocate a new row and keep all layouting parameters previously
+/// defined.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// if (nk_begin_xxx(...) {
+/// // first row with height: 30 composed of two widgets
+/// nk_layout_row_dynamic(&ctx, 30, 2);
+/// nk_widget(...);
+/// nk_widget(...);
+/// //
+/// // second row with same parameter as defined above
+/// nk_widget(...);
+/// nk_widget(...);
+/// //
+/// // third row uses 0 for height which will use auto layouting
+/// nk_layout_row_dynamic(&ctx, 0, 2);
+/// nk_widget(...);
+/// nk_widget(...);
+/// }
+/// nk_end(...);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// 2. __nk_layout_row_static__<br /><br />
+/// Another easy layouting function is `nk_layout_row_static`. It provides each
+/// widget with same horizontal pixel width inside the row and does not grow
+/// if the owning window scales smaller or bigger.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// if (nk_begin_xxx(...) {
+/// // first row with height: 30 composed of two widgets with width: 80
+/// nk_layout_row_static(&ctx, 30, 80, 2);
+/// nk_widget(...);
+/// nk_widget(...);
+/// //
+/// // second row with same parameter as defined above
+/// nk_widget(...);
+/// nk_widget(...);
+/// //
+/// // third row uses 0 for height which will use auto layouting
+/// nk_layout_row_static(&ctx, 0, 80, 2);
+/// nk_widget(...);
+/// nk_widget(...);
+/// }
+/// nk_end(...);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// 3. __nk_layout_row_xxx__<br /><br />
+/// A little bit more advanced layouting API are functions `nk_layout_row_begin`,
+/// `nk_layout_row_push` and `nk_layout_row_end`. They allow to directly
+/// specify each column pixel or window ratio in a row. It supports either
+/// directly setting per column pixel width or widget window ratio but not
+/// both. Furthermore it is a immediate mode API so each value is directly
+/// pushed before calling a widget. Therefore the layout is not automatically
+/// repeating like the last two layouting functions.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// if (nk_begin_xxx(...) {
+/// // first row with height: 25 composed of two widgets with width 60 and 40
+/// nk_layout_row_begin(ctx, NK_STATIC, 25, 2);
+/// nk_layout_row_push(ctx, 60);
+/// nk_widget(...);
+/// nk_layout_row_push(ctx, 40);
+/// nk_widget(...);
+/// nk_layout_row_end(ctx);
+/// //
+/// // second row with height: 25 composed of two widgets with window ratio 0.25 and 0.75
+/// nk_layout_row_begin(ctx, NK_DYNAMIC, 25, 2);
+/// nk_layout_row_push(ctx, 0.25f);
+/// nk_widget(...);
+/// nk_layout_row_push(ctx, 0.75f);
+/// nk_widget(...);
+/// nk_layout_row_end(ctx);
+/// //
+/// // third row with auto generated height: composed of two widgets with window ratio 0.25 and 0.75
+/// nk_layout_row_begin(ctx, NK_DYNAMIC, 0, 2);
+/// nk_layout_row_push(ctx, 0.25f);
+/// nk_widget(...);
+/// nk_layout_row_push(ctx, 0.75f);
+/// nk_widget(...);
+/// nk_layout_row_end(ctx);
+/// }
+/// nk_end(...);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// 4. __nk_layout_row__<br /><br />
+/// The array counterpart to API nk_layout_row_xxx is the single nk_layout_row
+/// functions. Instead of pushing either pixel or window ratio for every widget
+/// it allows to define it by array. The trade of for less control is that
+/// `nk_layout_row` is automatically repeating. Otherwise the behavior is the
+/// same.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// if (nk_begin_xxx(...) {
+/// // two rows with height: 30 composed of two widgets with width 60 and 40
+/// const float size[] = {60,40};
+/// nk_layout_row(ctx, NK_STATIC, 30, 2, ratio);
+/// nk_widget(...);
+/// nk_widget(...);
+/// nk_widget(...);
+/// nk_widget(...);
+/// //
+/// // two rows with height: 30 composed of two widgets with window ratio 0.25 and 0.75
+/// const float ratio[] = {0.25, 0.75};
+/// nk_layout_row(ctx, NK_DYNAMIC, 30, 2, ratio);
+/// nk_widget(...);
+/// nk_widget(...);
+/// nk_widget(...);
+/// nk_widget(...);
+/// //
+/// // two rows with auto generated height composed of two widgets with window ratio 0.25 and 0.75
+/// const float ratio[] = {0.25, 0.75};
+/// nk_layout_row(ctx, NK_DYNAMIC, 30, 2, ratio);
+/// nk_widget(...);
+/// nk_widget(...);
+/// nk_widget(...);
+/// nk_widget(...);
+/// }
+/// nk_end(...);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// 5. __nk_layout_row_template_xxx__<br /><br />
+/// The most complex and second most flexible API is a simplified flexbox version without
+/// line wrapping and weights for dynamic widgets. It is an immediate mode API but
+/// unlike `nk_layout_row_xxx` it has auto repeat behavior and needs to be called
+/// before calling the templated widgets.
+/// The row template layout has three different per widget size specifier. The first
+/// one is the `nk_layout_row_template_push_static` with fixed widget pixel width.
+/// They do not grow if the row grows and will always stay the same.
+/// The second size specifier is `nk_layout_row_template_push_variable`
+/// which defines a minimum widget size but it also can grow if more space is available
+/// not taken by other widgets.
+/// Finally there are dynamic widgets with `nk_layout_row_template_push_dynamic`
+/// which are completely flexible and unlike variable widgets can even shrink
+/// to zero if not enough space is provided.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// if (nk_begin_xxx(...) {
+/// // two rows with height: 30 composed of three widgets
+/// nk_layout_row_template_begin(ctx, 30);
+/// nk_layout_row_template_push_dynamic(ctx);
+/// nk_layout_row_template_push_variable(ctx, 80);
+/// nk_layout_row_template_push_static(ctx, 80);
+/// nk_layout_row_template_end(ctx);
+/// //
+/// // first row
+/// nk_widget(...); // dynamic widget can go to zero if not enough space
+/// nk_widget(...); // variable widget with min 80 pixel but can grow bigger if enough space
+/// nk_widget(...); // static widget with fixed 80 pixel width
+/// //
+/// // second row same layout
+/// nk_widget(...);
+/// nk_widget(...);
+/// nk_widget(...);
+/// }
+/// nk_end(...);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// 6. __nk_layout_space_xxx__<br /><br />
+/// Finally the most flexible API directly allows you to place widgets inside the
+/// window. The space layout API is an immediate mode API which does not support
+/// row auto repeat and directly sets position and size of a widget. Position
+/// and size hereby can be either specified as ratio of allocated space or
+/// allocated space local position and pixel size. Since this API is quite
+/// powerful there are a number of utility functions to get the available space
+/// and convert between local allocated space and screen space.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// if (nk_begin_xxx(...) {
+/// // static row with height: 500 (you can set column count to INT_MAX if you don't want to be bothered)
+/// nk_layout_space_begin(ctx, NK_STATIC, 500, INT_MAX);
+/// nk_layout_space_push(ctx, nk_rect(0,0,150,200));
+/// nk_widget(...);
+/// nk_layout_space_push(ctx, nk_rect(200,200,100,200));
+/// nk_widget(...);
+/// nk_layout_space_end(ctx);
+/// //
+/// // dynamic row with height: 500 (you can set column count to INT_MAX if you don't want to be bothered)
+/// nk_layout_space_begin(ctx, NK_DYNAMIC, 500, INT_MAX);
+/// nk_layout_space_push(ctx, nk_rect(0.5,0.5,0.1,0.1));
+/// nk_widget(...);
+/// nk_layout_space_push(ctx, nk_rect(0.7,0.6,0.1,0.1));
+/// nk_widget(...);
+/// }
+/// nk_end(...);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// #### Reference
+/// Function | Description
+/// ----------------------------------------|------------------------------------
+/// nk_layout_set_min_row_height | Set the currently used minimum row height to a specified value
+/// nk_layout_reset_min_row_height | Resets the currently used minimum row height to font height
+/// nk_layout_widget_bounds | Calculates current width a static layout row can fit inside a window
+/// nk_layout_ratio_from_pixel | Utility functions to calculate window ratio from pixel size
+//
+/// nk_layout_row_dynamic | Current layout is divided into n same sized growing columns
+/// nk_layout_row_static | Current layout is divided into n same fixed sized columns
+/// nk_layout_row_begin | Starts a new row with given height and number of columns
+/// nk_layout_row_push | Pushes another column with given size or window ratio
+/// nk_layout_row_end | Finished previously started row
+/// nk_layout_row | Specifies row columns in array as either window ratio or size
+//
+/// nk_layout_row_template_begin | Begins the row template declaration
+/// nk_layout_row_template_push_dynamic | Adds a dynamic column that dynamically grows and can go to zero if not enough space
+/// nk_layout_row_template_push_variable | Adds a variable column that dynamically grows but does not shrink below specified pixel width
+/// nk_layout_row_template_push_static | Adds a static column that does not grow and will always have the same size
+/// nk_layout_row_template_end | Marks the end of the row template
+//
+/// nk_layout_space_begin | Begins a new layouting space that allows to specify each widgets position and size
+/// nk_layout_space_push | Pushes position and size of the next widget in own coordinate space either as pixel or ratio
+/// nk_layout_space_end | Marks the end of the layouting space
+//
+/// nk_layout_space_bounds | Callable after nk_layout_space_begin and returns total space allocated
+/// nk_layout_space_to_screen | Converts vector from nk_layout_space coordinate space into screen space
+/// nk_layout_space_to_local | Converts vector from screen space into nk_layout_space coordinates
+/// nk_layout_space_rect_to_screen | Converts rectangle from nk_layout_space coordinate space into screen space
+/// nk_layout_space_rect_to_local | Converts rectangle from screen space into nk_layout_space coordinates
+*/
+/*/// #### nk_layout_set_min_row_height
+/// Sets the currently used minimum row height.
+/// !!! WARNING
+/// The passed height needs to include both your preferred row height
+/// as well as padding. No internal padding is added.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_set_min_row_height(struct nk_context*, float height);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+/// __height__ | New minimum row height to be used for auto generating the row height
+*/
+NK_API void nk_layout_set_min_row_height(struct nk_context*, float height);
+/*/// #### nk_layout_reset_min_row_height
+/// Reset the currently used minimum row height back to `font_height + text_padding + padding`
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_reset_min_row_height(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+*/
+NK_API void nk_layout_reset_min_row_height(struct nk_context*);
+/*/// #### nk_layout_widget_bounds
+/// Returns the width of the next row allocate by one of the layouting functions
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_rect nk_layout_widget_bounds(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+///
+/// Return `nk_rect` with both position and size of the next row
+*/
+NK_API struct nk_rect nk_layout_widget_bounds(struct nk_context*);
+/*/// #### nk_layout_ratio_from_pixel
+/// Utility functions to calculate window ratio from pixel size
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// float nk_layout_ratio_from_pixel(struct nk_context*, float pixel_width);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+/// __pixel__ | Pixel_width to convert to window ratio
+///
+/// Returns `nk_rect` with both position and size of the next row
+*/
+NK_API float nk_layout_ratio_from_pixel(struct nk_context*, float pixel_width);
+/*/// #### nk_layout_row_dynamic
+/// Sets current row layout to share horizontal space
+/// between @cols number of widgets evenly. Once called all subsequent widget
+/// calls greater than @cols will allocate a new row with same layout.
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+/// __height__ | Holds height of each widget in row or zero for auto layouting
+/// __columns__ | Number of widget inside row
+*/
+NK_API void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols);
+/*/// #### nk_layout_row_dynamic
+/// Sets current row layout to fill @cols number of widgets
+/// in row with same @item_width horizontal size. Once called all subsequent widget
+/// calls greater than @cols will allocate a new row with same layout.
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+/// __height__ | Holds height of each widget in row or zero for auto layouting
+/// __width__ | Holds pixel width of each widget in the row
+/// __columns__ | Number of widget inside row
+*/
+NK_API void nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols);
+/*/// #### nk_layout_row_begin
+/// Starts a new dynamic or fixed row with given height and columns.
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+/// __fmt__ | either `NK_DYNAMIC` for window ratio or `NK_STATIC` for fixed size columns
+/// __height__ | holds height of each widget in row or zero for auto layouting
+/// __columns__ | Number of widget inside row
+*/
+NK_API void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols);
+/*/// #### nk_layout_row_push
+/// Specifies either window ratio or width of a single column
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_row_push(struct nk_context*, float value);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+/// __value__ | either a window ratio or fixed width depending on @fmt in previous `nk_layout_row_begin` call
+*/
+NK_API void nk_layout_row_push(struct nk_context*, float value);
+/*/// #### nk_layout_row_end
+/// Finished previously started row
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_row_end(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+*/
+NK_API void nk_layout_row_end(struct nk_context*);
+/*/// #### nk_layout_row
+/// Specifies row columns in array as either window ratio or size
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_row(struct nk_context*, enum nk_layout_format, float height, int cols, const float *ratio);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+/// __fmt__ | Either `NK_DYNAMIC` for window ratio or `NK_STATIC` for fixed size columns
+/// __height__ | Holds height of each widget in row or zero for auto layouting
+/// __columns__ | Number of widget inside row
+*/
+NK_API void nk_layout_row(struct nk_context*, enum nk_layout_format, float height, int cols, const float *ratio);
+/*/// #### nk_layout_row_template_begin
+/// Begins the row template declaration
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_row_template_begin(struct nk_context*, float row_height);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+/// __height__ | Holds height of each widget in row or zero for auto layouting
+*/
+NK_API void nk_layout_row_template_begin(struct nk_context*, float row_height);
+/*/// #### nk_layout_row_template_push_dynamic
+/// Adds a dynamic column that dynamically grows and can go to zero if not enough space
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_row_template_push_dynamic(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+/// __height__ | Holds height of each widget in row or zero for auto layouting
+*/
+NK_API void nk_layout_row_template_push_dynamic(struct nk_context*);
+/*/// #### nk_layout_row_template_push_variable
+/// Adds a variable column that dynamically grows but does not shrink below specified pixel width
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_row_template_push_variable(struct nk_context*, float min_width);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+/// __width__ | Holds the minimum pixel width the next column must always be
+*/
+NK_API void nk_layout_row_template_push_variable(struct nk_context*, float min_width);
+/*/// #### nk_layout_row_template_push_static
+/// Adds a static column that does not grow and will always have the same size
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_row_template_push_static(struct nk_context*, float width);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+/// __width__ | Holds the absolute pixel width value the next column must be
+*/
+NK_API void nk_layout_row_template_push_static(struct nk_context*, float width);
+/*/// #### nk_layout_row_template_end
+/// Marks the end of the row template
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_row_template_end(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+*/
+NK_API void nk_layout_row_template_end(struct nk_context*);
+/*/// #### nk_layout_space_begin
+/// Begins a new layouting space that allows to specify each widgets position and size.
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_space_begin(struct nk_context*, enum nk_layout_format, float height, int widget_count);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx`
+/// __fmt__ | Either `NK_DYNAMIC` for window ratio or `NK_STATIC` for fixed size columns
+/// __height__ | Holds height of each widget in row or zero for auto layouting
+/// __columns__ | Number of widgets inside row
+*/
+NK_API void nk_layout_space_begin(struct nk_context*, enum nk_layout_format, float height, int widget_count);
+/*/// #### nk_layout_space_push
+/// Pushes position and size of the next widget in own coordinate space either as pixel or ratio
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_space_push(struct nk_context *ctx, struct nk_rect bounds);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
+/// __bounds__ | Position and size in laoyut space local coordinates
+*/
+NK_API void nk_layout_space_push(struct nk_context*, struct nk_rect bounds);
+/*/// #### nk_layout_space_end
+/// Marks the end of the layout space
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_layout_space_end(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
+*/
+NK_API void nk_layout_space_end(struct nk_context*);
+/*/// #### nk_layout_space_bounds
+/// Utility function to calculate total space allocated for `nk_layout_space`
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_rect nk_layout_space_bounds(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
+///
+/// Returns `nk_rect` holding the total space allocated
+*/
+NK_API struct nk_rect nk_layout_space_bounds(struct nk_context*);
+/*/// #### nk_layout_space_to_screen
+/// Converts vector from nk_layout_space coordinate space into screen space
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_vec2 nk_layout_space_to_screen(struct nk_context*, struct nk_vec2);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
+/// __vec__ | Position to convert from layout space into screen coordinate space
+///
+/// Returns transformed `nk_vec2` in screen space coordinates
+*/
+NK_API struct nk_vec2 nk_layout_space_to_screen(struct nk_context*, struct nk_vec2);
+/*/// #### nk_layout_space_to_screen
+/// Converts vector from layout space into screen space
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_vec2 nk_layout_space_to_local(struct nk_context*, struct nk_vec2);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
+/// __vec__ | Position to convert from screen space into layout coordinate space
+///
+/// Returns transformed `nk_vec2` in layout space coordinates
+*/
+NK_API struct nk_vec2 nk_layout_space_to_local(struct nk_context*, struct nk_vec2);
+/*/// #### nk_layout_space_rect_to_screen
+/// Converts rectangle from screen space into layout space
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_rect nk_layout_space_rect_to_screen(struct nk_context*, struct nk_rect);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
+/// __bounds__ | Rectangle to convert from layout space into screen space
+///
+/// Returns transformed `nk_rect` in screen space coordinates
+*/
+NK_API struct nk_rect nk_layout_space_rect_to_screen(struct nk_context*, struct nk_rect);
+/*/// #### nk_layout_space_rect_to_local
+/// Converts rectangle from layout space into screen space
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_rect nk_layout_space_rect_to_local(struct nk_context*, struct nk_rect);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin`
+/// __bounds__ | Rectangle to convert from layout space into screen space
+///
+/// Returns transformed `nk_rect` in layout space coordinates
+*/
+NK_API struct nk_rect nk_layout_space_rect_to_local(struct nk_context*, struct nk_rect);
+/* =============================================================================
+ *
+ * GROUP
+ *
+ * =============================================================================
+/// ### Groups
+/// Groups are basically windows inside windows. They allow to subdivide space
+/// in a window to layout widgets as a group. Almost all more complex widget
+/// layouting requirements can be solved using groups and basic layouting
+/// fuctionality. Groups just like windows are identified by an unique name and
+/// internally keep track of scrollbar offsets by default. However additional
+/// versions are provided to directly manage the scrollbar.
+///
+/// #### Usage
+/// To create a group you have to call one of the three `nk_group_begin_xxx`
+/// functions to start group declarations and `nk_group_end` at the end. Furthermore it
+/// is required to check the return value of `nk_group_begin_xxx` and only process
+/// widgets inside the window if the value is not 0.
+/// Nesting groups is possible and even encouraged since many layouting schemes
+/// can only be achieved by nesting. Groups, unlike windows, need `nk_group_end`
+/// to be only called if the corosponding `nk_group_begin_xxx` call does not return 0:
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// if (nk_group_begin_xxx(ctx, ...) {
+/// // [... widgets ...]
+/// nk_group_end(ctx);
+/// }
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// In the grand concept groups can be called after starting a window
+/// with `nk_begin_xxx` and before calling `nk_end`:
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// struct nk_context ctx;
+/// nk_init_xxx(&ctx, ...);
+/// while (1) {
+/// // Input
+/// Event evt;
+/// nk_input_begin(&ctx);
+/// while (GetEvent(&evt)) {
+/// if (evt.type == MOUSE_MOVE)
+/// nk_input_motion(&ctx, evt.motion.x, evt.motion.y);
+/// else if (evt.type == [...]) {
+/// nk_input_xxx(...);
+/// }
+/// }
+/// nk_input_end(&ctx);
+/// //
+/// // Window
+/// if (nk_begin_xxx(...) {
+/// // [...widgets...]
+/// nk_layout_row_dynamic(...);
+/// if (nk_group_begin_xxx(ctx, ...) {
+/// //[... widgets ...]
+/// nk_group_end(ctx);
+/// }
+/// }
+/// nk_end(ctx);
+/// //
+/// // Draw
+/// const struct nk_command *cmd = 0;
+/// nk_foreach(cmd, &ctx) {
+/// switch (cmd->type) {
+/// case NK_COMMAND_LINE:
+/// your_draw_line_function(...)
+/// break;
+/// case NK_COMMAND_RECT
+/// your_draw_rect_function(...)
+/// break;
+/// case ...:
+/// // [...]
+/// }
+// nk_clear(&ctx);
+/// }
+/// nk_free(&ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+/// #### Reference
+/// Function | Description
+/// --------------------------------|-------------------------------------------
+/// nk_group_begin | Start a new group with internal scrollbar handling
+/// nk_group_begin_titled | Start a new group with separeted name and title and internal scrollbar handling
+/// nk_group_end | Ends a group. Should only be called if nk_group_begin returned non-zero
+/// nk_group_scrolled_offset_begin | Start a new group with manual separated handling of scrollbar x- and y-offset
+/// nk_group_scrolled_begin | Start a new group with manual scrollbar handling
+/// nk_group_scrolled_end | Ends a group with manual scrollbar handling. Should only be called if nk_group_begin returned non-zero
+*/
+/*/// #### nk_group_begin
+/// Starts a new widget group. Requires a previous layouting function to specify a pos/size.
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_group_begin(struct nk_context*, const char *title, nk_flags);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __title__ | Must be an unique identifier for this group that is also used for the group header
+/// __flags__ | Window flags defined in the nk_panel_flags section with a number of different group behaviors
+///
+/// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
+*/
+NK_API int nk_group_begin(struct nk_context*, const char *title, nk_flags);
+/*/// #### nk_group_begin_titled
+/// Starts a new widget group. Requires a previous layouting function to specify a pos/size.
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_group_begin_titled(struct nk_context*, const char *name, const char *title, nk_flags);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __id__ | Must be an unique identifier for this group
+/// __title__ | Group header title
+/// __flags__ | Window flags defined in the nk_panel_flags section with a number of different group behaviors
+///
+/// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
+*/
+NK_API int nk_group_begin_titled(struct nk_context*, const char *name, const char *title, nk_flags);
+/*/// #### nk_group_end
+/// Ends a widget group
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_group_end(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+*/
+NK_API void nk_group_end(struct nk_context*);
+/*/// #### nk_group_scrolled_offset_begin
+/// starts a new widget group. requires a previous layouting function to specify
+/// a size. Does not keep track of scrollbar.
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_group_scrolled_offset_begin(struct nk_context*, nk_uint *x_offset, nk_uint *y_offset, const char *title, nk_flags flags);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __x_offset__| Scrollbar x-offset to offset all widgets inside the group horizontally.
+/// __y_offset__| Scrollbar y-offset to offset all widgets inside the group vertically
+/// __title__ | Window unique group title used to both identify and display in the group header
+/// __flags__ | Window flags from the nk_panel_flags section
+///
+/// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
+*/
+NK_API int nk_group_scrolled_offset_begin(struct nk_context*, nk_uint *x_offset, nk_uint *y_offset, const char *title, nk_flags flags);
+/*/// #### nk_group_scrolled_begin
+/// Starts a new widget group. requires a previous
+/// layouting function to specify a size. Does not keep track of scrollbar.
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_group_scrolled_begin(struct nk_context*, struct nk_scroll *off, const char *title, nk_flags);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __off__ | Both x- and y- scroll offset. Allows for manual scrollbar control
+/// __title__ | Window unique group title used to both identify and display in the group header
+/// __flags__ | Window flags from nk_panel_flags section
+///
+/// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
+*/
+NK_API int nk_group_scrolled_begin(struct nk_context*, struct nk_scroll *off, const char *title, nk_flags);
+/*/// #### nk_group_scrolled_end
+/// Ends a widget group after calling nk_group_scrolled_offset_begin or nk_group_scrolled_begin.
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_group_scrolled_end(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+*/
+NK_API void nk_group_scrolled_end(struct nk_context*);
+/* =============================================================================
+ *
+ * TREE
+ *
+ * =============================================================================
+/// ### Tree
+/// Trees represent two different concept. First the concept of a collapsable
+/// UI section that can be either in a hidden or visibile state. They allow the UI
+/// user to selectively minimize the current set of visible UI to comprehend.
+/// The second concept are tree widgets for visual UI representation of trees.<br /><br />
+///
+/// Trees thereby can be nested for tree representations and multiple nested
+/// collapsable UI sections. All trees are started by calling of the
+/// `nk_tree_xxx_push_tree` functions and ended by calling one of the
+/// `nk_tree_xxx_pop_xxx()` functions. Each starting functions takes a title label
+/// and optionally an image to be displayed and the initial collapse state from
+/// the nk_collapse_states section.<br /><br />
+///
+/// The runtime state of the tree is either stored outside the library by the caller
+/// or inside which requires a unique ID. The unique ID can either be generated
+/// automatically from `__FILE__` and `__LINE__` with function `nk_tree_push`,
+/// by `__FILE__` and a user provided ID generated for example by loop index with
+/// function `nk_tree_push_id` or completely provided from outside by user with
+/// function `nk_tree_push_hashed`.
+///
+/// #### Usage
+/// To create a tree you have to call one of the seven `nk_tree_xxx_push_xxx`
+/// functions to start a collapsable UI section and `nk_tree_xxx_pop` to mark the
+/// end.
+/// Each starting function will either return `false(0)` if the tree is collapsed
+/// or hidden and therefore does not need to be filled with content or `true(1)`
+/// if visible and required to be filled.
+///
+/// !!! Note
+/// The tree header does not require and layouting function and instead
+/// calculates a auto height based on the currently used font size
+///
+/// The tree ending functions only need to be called if the tree content is
+/// actually visible. So make sure the tree push function is guarded by `if`
+/// and the pop call is only taken if the tree is visible.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// if (nk_tree_push(ctx, NK_TREE_TAB, "Tree", NK_MINIMIZED)) {
+/// nk_layout_row_dynamic(...);
+/// nk_widget(...);
+/// nk_tree_pop(ctx);
+/// }
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// #### Reference
+/// Function | Description
+/// ----------------------------|-------------------------------------------
+/// nk_tree_push | Start a collapsable UI section with internal state management
+/// nk_tree_push_id | Start a collapsable UI section with internal state management callable in a look
+/// nk_tree_push_hashed | Start a collapsable UI section with internal state management with full control over internal unique ID use to store state
+/// nk_tree_image_push | Start a collapsable UI section with image and label header
+/// nk_tree_image_push_id | Start a collapsable UI section with image and label header and internal state management callable in a look
+/// nk_tree_image_push_hashed | Start a collapsable UI section with image and label header and internal state management with full control over internal unique ID use to store state
+/// nk_tree_pop | Ends a collapsable UI section
+//
+/// nk_tree_state_push | Start a collapsable UI section with external state management
+/// nk_tree_state_image_push | Start a collapsable UI section with image and label header and external state management
+/// nk_tree_state_pop | Ends a collapsabale UI section
+///
+/// #### nk_tree_type
+/// Flag | Description
+/// ----------------|----------------------------------------
+/// NK_TREE_NODE | Highlighted tree header to mark a collapsable UI section
+/// NK_TREE_TAB | Non-highighted tree header closer to tree representations
+*/
+/*/// #### nk_tree_push
+/// Starts a collapsable UI section with internal state management
+/// !!! WARNING
+/// To keep track of the runtime tree collapsable state this function uses
+/// defines `__FILE__` and `__LINE__` to generate a unique ID. If you want
+/// to call this function in a loop please use `nk_tree_push_id` or
+/// `nk_tree_push_hashed` instead.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// #define nk_tree_push(ctx, type, title, state)
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __type__ | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
+/// __title__ | Label printed in the tree header
+/// __state__ | Initial tree state value out of nk_collapse_states
+///
+/// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
+*/
+#define nk_tree_push(ctx, type, title, state) nk_tree_push_hashed(ctx, type, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
+/*/// #### nk_tree_push_id
+/// Starts a collapsable UI section with internal state management callable in a look
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// #define nk_tree_push_id(ctx, type, title, state, id)
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __type__ | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
+/// __title__ | Label printed in the tree header
+/// __state__ | Initial tree state value out of nk_collapse_states
+/// __id__ | Loop counter index if this function is called in a loop
+///
+/// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
+*/
+#define nk_tree_push_id(ctx, type, title, state, id) nk_tree_push_hashed(ctx, type, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
+/*/// #### nk_tree_push_hashed
+/// Start a collapsable UI section with internal state management with full
+/// control over internal unique ID used to store state
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_tree_push_hashed(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, const char *hash, int len,int seed);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __type__ | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
+/// __title__ | Label printed in the tree header
+/// __state__ | Initial tree state value out of nk_collapse_states
+/// __hash__ | Memory block or string to generate the ID from
+/// __len__ | Size of passed memory block or string in __hash__
+/// __seed__ | Seeding value if this function is called in a loop or default to `0`
+///
+/// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
+*/
+NK_API int nk_tree_push_hashed(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states initial_state, const char *hash, int len,int seed);
+/*/// #### nk_tree_image_push
+/// Start a collapsable UI section with image and label header
+/// !!! WARNING
+/// To keep track of the runtime tree collapsable state this function uses
+/// defines `__FILE__` and `__LINE__` to generate a unique ID. If you want
+/// to call this function in a loop please use `nk_tree_image_push_id` or
+/// `nk_tree_image_push_hashed` instead.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// #define nk_tree_image_push(ctx, type, img, title, state)
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __type__ | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
+/// __img__ | Image to display inside the header on the left of the label
+/// __title__ | Label printed in the tree header
+/// __state__ | Initial tree state value out of nk_collapse_states
+///
+/// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
+*/
+#define nk_tree_image_push(ctx, type, img, title, state) nk_tree_image_push_hashed(ctx, type, img, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),__LINE__)
+/*/// #### nk_tree_image_push_id
+/// Start a collapsable UI section with image and label header and internal state
+/// management callable in a look
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// #define nk_tree_image_push_id(ctx, type, img, title, state, id)
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __type__ | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
+/// __img__ | Image to display inside the header on the left of the label
+/// __title__ | Label printed in the tree header
+/// __state__ | Initial tree state value out of nk_collapse_states
+/// __id__ | Loop counter index if this function is called in a loop
+///
+/// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
+*/
+#define nk_tree_image_push_id(ctx, type, img, title, state, id) nk_tree_image_push_hashed(ctx, type, img, title, state, NK_FILE_LINE,nk_strlen(NK_FILE_LINE),id)
+/*/// #### nk_tree_image_push_hashed
+/// Start a collapsable UI section with internal state management with full
+/// control over internal unique ID used to store state
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_tree_image_push_hashed(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states initial_state, const char *hash, int len,int seed);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct
+/// __type__ | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
+/// __img__ | Image to display inside the header on the left of the label
+/// __title__ | Label printed in the tree header
+/// __state__ | Initial tree state value out of nk_collapse_states
+/// __hash__ | Memory block or string to generate the ID from
+/// __len__ | Size of passed memory block or string in __hash__
+/// __seed__ | Seeding value if this function is called in a loop or default to `0`
+///
+/// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
+*/
+NK_API int nk_tree_image_push_hashed(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states initial_state, const char *hash, int len,int seed);
+/*/// #### nk_tree_pop
+/// Ends a collapsabale UI section
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_tree_pop(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after calling `nk_tree_xxx_push_xxx`
+*/
+NK_API void nk_tree_pop(struct nk_context*);
+/*/// #### nk_tree_state_push
+/// Start a collapsable UI section with external state management
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_tree_state_push(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states *state);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after calling `nk_tree_xxx_push_xxx`
+/// __type__ | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
+/// __title__ | Label printed in the tree header
+/// __state__ | Persistent state to update
+///
+/// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
+*/
+NK_API int nk_tree_state_push(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states *state);
+/*/// #### nk_tree_state_image_push
+/// Start a collapsable UI section with image and label header and external state management
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_tree_state_image_push(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states *state);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after calling `nk_tree_xxx_push_xxx`
+/// __img__ | Image to display inside the header on the left of the label
+/// __type__ | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable UI section or tree node
+/// __title__ | Label printed in the tree header
+/// __state__ | Persistent state to update
+///
+/// Returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise
+*/
+NK_API int nk_tree_state_image_push(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states *state);
+/*/// #### nk_tree_state_pop
+/// Ends a collapsabale UI section
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_tree_state_pop(struct nk_context*);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// ------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after calling `nk_tree_xxx_push_xxx`
+*/
+NK_API void nk_tree_state_pop(struct nk_context*);
+/* =============================================================================
+ *
+ * LIST VIEW
+ *
+ * ============================================================================= */
+struct nk_list_view {
+/* public: */
+ int begin, end, count;
+/* private: */
+ int total_height;
+ struct nk_context *ctx;
+ nk_uint *scroll_pointer;
+ nk_uint scroll_value;
+};
+NK_API int nk_list_view_begin(struct nk_context*, struct nk_list_view *out, const char *id, nk_flags, int row_height, int row_count);
+NK_API void nk_list_view_end(struct nk_list_view*);
+/* =============================================================================
+ *
+ * WIDGET
+ *
+ * ============================================================================= */
+enum nk_widget_layout_states {
+ NK_WIDGET_INVALID, /* The widget cannot be seen and is completely out of view */
+ NK_WIDGET_VALID, /* The widget is completely inside the window and can be updated and drawn */
+ NK_WIDGET_ROM /* The widget is partially visible and cannot be updated */
+};
+enum nk_widget_states {
+ NK_WIDGET_STATE_MODIFIED = NK_FLAG(1),
+ NK_WIDGET_STATE_INACTIVE = NK_FLAG(2), /* widget is neither active nor hovered */
+ NK_WIDGET_STATE_ENTERED = NK_FLAG(3), /* widget has been hovered on the current frame */
+ NK_WIDGET_STATE_HOVER = NK_FLAG(4), /* widget is being hovered */
+ NK_WIDGET_STATE_ACTIVED = NK_FLAG(5),/* widget is currently activated */
+ NK_WIDGET_STATE_LEFT = NK_FLAG(6), /* widget is from this frame on not hovered anymore */
+ NK_WIDGET_STATE_HOVERED = NK_WIDGET_STATE_HOVER|NK_WIDGET_STATE_MODIFIED, /* widget is being hovered */
+ NK_WIDGET_STATE_ACTIVE = NK_WIDGET_STATE_ACTIVED|NK_WIDGET_STATE_MODIFIED /* widget is currently activated */
+};
+NK_API enum nk_widget_layout_states nk_widget(struct nk_rect*, const struct nk_context*);
+NK_API enum nk_widget_layout_states nk_widget_fitting(struct nk_rect*, struct nk_context*, struct nk_vec2);
+NK_API struct nk_rect nk_widget_bounds(struct nk_context*);
+NK_API struct nk_vec2 nk_widget_position(struct nk_context*);
+NK_API struct nk_vec2 nk_widget_size(struct nk_context*);
+NK_API float nk_widget_width(struct nk_context*);
+NK_API float nk_widget_height(struct nk_context*);
+NK_API int nk_widget_is_hovered(struct nk_context*);
+NK_API int nk_widget_is_mouse_clicked(struct nk_context*, enum nk_buttons);
+NK_API int nk_widget_has_mouse_click_down(struct nk_context*, enum nk_buttons, int down);
+NK_API void nk_spacing(struct nk_context*, int cols);
+/* =============================================================================
+ *
+ * TEXT
+ *
+ * ============================================================================= */
+enum nk_text_align {
+ NK_TEXT_ALIGN_LEFT = 0x01,
+ NK_TEXT_ALIGN_CENTERED = 0x02,
+ NK_TEXT_ALIGN_RIGHT = 0x04,
+ NK_TEXT_ALIGN_TOP = 0x08,
+ NK_TEXT_ALIGN_MIDDLE = 0x10,
+ NK_TEXT_ALIGN_BOTTOM = 0x20
+};
+enum nk_text_alignment {
+ NK_TEXT_LEFT = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_LEFT,
+ NK_TEXT_CENTERED = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_CENTERED,
+ NK_TEXT_RIGHT = NK_TEXT_ALIGN_MIDDLE|NK_TEXT_ALIGN_RIGHT
+};
+NK_API void nk_text(struct nk_context*, const char*, int, nk_flags);
+NK_API void nk_text_colored(struct nk_context*, const char*, int, nk_flags, struct nk_color);
+NK_API void nk_text_wrap(struct nk_context*, const char*, int);
+NK_API void nk_text_wrap_colored(struct nk_context*, const char*, int, struct nk_color);
+NK_API void nk_label(struct nk_context*, const char*, nk_flags align);
+NK_API void nk_label_colored(struct nk_context*, const char*, nk_flags align, struct nk_color);
+NK_API void nk_label_wrap(struct nk_context*, const char*);
+NK_API void nk_label_colored_wrap(struct nk_context*, const char*, struct nk_color);
+NK_API void nk_image(struct nk_context*, struct nk_image);
+#ifdef NK_INCLUDE_STANDARD_VARARGS
+NK_API void nk_labelf(struct nk_context*, nk_flags, NK_PRINTF_FORMAT_STRING const char*, ...) NK_PRINTF_VARARG_FUNC(3);
+NK_API void nk_labelf_colored(struct nk_context*, nk_flags, struct nk_color, NK_PRINTF_FORMAT_STRING const char*,...) NK_PRINTF_VARARG_FUNC(4);
+NK_API void nk_labelf_wrap(struct nk_context*, NK_PRINTF_FORMAT_STRING const char*,...) NK_PRINTF_VARARG_FUNC(2);
+NK_API void nk_labelf_colored_wrap(struct nk_context*, struct nk_color, NK_PRINTF_FORMAT_STRING const char*,...) NK_PRINTF_VARARG_FUNC(3);
+NK_API void nk_value_bool(struct nk_context*, const char *prefix, int);
+NK_API void nk_value_int(struct nk_context*, const char *prefix, int);
+NK_API void nk_value_uint(struct nk_context*, const char *prefix, unsigned int);
+NK_API void nk_value_float(struct nk_context*, const char *prefix, float);
+NK_API void nk_value_color_byte(struct nk_context*, const char *prefix, struct nk_color);
+NK_API void nk_value_color_float(struct nk_context*, const char *prefix, struct nk_color);
+NK_API void nk_value_color_hex(struct nk_context*, const char *prefix, struct nk_color);
+#endif
+/* =============================================================================
+ *
+ * BUTTON
+ *
+ * ============================================================================= */
+NK_API int nk_button_text(struct nk_context*, const char *title, int len);
+NK_API int nk_button_label(struct nk_context*, const char *title);
+NK_API int nk_button_color(struct nk_context*, struct nk_color);
+NK_API int nk_button_symbol(struct nk_context*, enum nk_symbol_type);
+NK_API int nk_button_image(struct nk_context*, struct nk_image img);
+NK_API int nk_button_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags text_alignment);
+NK_API int nk_button_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
+NK_API int nk_button_image_label(struct nk_context*, struct nk_image img, const char*, nk_flags text_alignment);
+NK_API int nk_button_image_text(struct nk_context*, struct nk_image img, const char*, int, nk_flags alignment);
+NK_API int nk_button_text_styled(struct nk_context*, const struct nk_style_button*, const char *title, int len);
+NK_API int nk_button_label_styled(struct nk_context*, const struct nk_style_button*, const char *title);
+NK_API int nk_button_symbol_styled(struct nk_context*, const struct nk_style_button*, enum nk_symbol_type);
+NK_API int nk_button_image_styled(struct nk_context*, const struct nk_style_button*, struct nk_image img);
+NK_API int nk_button_symbol_text_styled(struct nk_context*,const struct nk_style_button*, enum nk_symbol_type, const char*, int, nk_flags alignment);
+NK_API int nk_button_symbol_label_styled(struct nk_context *ctx, const struct nk_style_button *style, enum nk_symbol_type symbol, const char *title, nk_flags align);
+NK_API int nk_button_image_label_styled(struct nk_context*,const struct nk_style_button*, struct nk_image img, const char*, nk_flags text_alignment);
+NK_API int nk_button_image_text_styled(struct nk_context*,const struct nk_style_button*, struct nk_image img, const char*, int, nk_flags alignment);
+NK_API void nk_button_set_behavior(struct nk_context*, enum nk_button_behavior);
+NK_API int nk_button_push_behavior(struct nk_context*, enum nk_button_behavior);
+NK_API int nk_button_pop_behavior(struct nk_context*);
+/* =============================================================================
+ *
+ * CHECKBOX
+ *
+ * ============================================================================= */
+NK_API int nk_check_label(struct nk_context*, const char*, int active);
+NK_API int nk_check_text(struct nk_context*, const char*, int,int active);
+NK_API unsigned nk_check_flags_label(struct nk_context*, const char*, unsigned int flags, unsigned int value);
+NK_API unsigned nk_check_flags_text(struct nk_context*, const char*, int, unsigned int flags, unsigned int value);
+NK_API int nk_checkbox_label(struct nk_context*, const char*, int *active);
+NK_API int nk_checkbox_text(struct nk_context*, const char*, int, int *active);
+NK_API int nk_checkbox_flags_label(struct nk_context*, const char*, unsigned int *flags, unsigned int value);
+NK_API int nk_checkbox_flags_text(struct nk_context*, const char*, int, unsigned int *flags, unsigned int value);
+/* =============================================================================
+ *
+ * RADIO BUTTON
+ *
+ * ============================================================================= */
+NK_API int nk_radio_label(struct nk_context*, const char*, int *active);
+NK_API int nk_radio_text(struct nk_context*, const char*, int, int *active);
+NK_API int nk_option_label(struct nk_context*, const char*, int active);
+NK_API int nk_option_text(struct nk_context*, const char*, int, int active);
+/* =============================================================================
+ *
+ * SELECTABLE
+ *
+ * ============================================================================= */
+NK_API int nk_selectable_label(struct nk_context*, const char*, nk_flags align, int *value);
+NK_API int nk_selectable_text(struct nk_context*, const char*, int, nk_flags align, int *value);
+NK_API int nk_selectable_image_label(struct nk_context*,struct nk_image, const char*, nk_flags align, int *value);
+NK_API int nk_selectable_image_text(struct nk_context*,struct nk_image, const char*, int, nk_flags align, int *value);
+NK_API int nk_select_label(struct nk_context*, const char*, nk_flags align, int value);
+NK_API int nk_select_text(struct nk_context*, const char*, int, nk_flags align, int value);
+NK_API int nk_select_image_label(struct nk_context*, struct nk_image,const char*, nk_flags align, int value);
+NK_API int nk_select_image_text(struct nk_context*, struct nk_image,const char*, int, nk_flags align, int value);
+/* =============================================================================
+ *
+ * SLIDER
+ *
+ * ============================================================================= */
+NK_API float nk_slide_float(struct nk_context*, float min, float val, float max, float step);
+NK_API int nk_slide_int(struct nk_context*, int min, int val, int max, int step);
+NK_API int nk_slider_float(struct nk_context*, float min, float *val, float max, float step);
+NK_API int nk_slider_int(struct nk_context*, int min, int *val, int max, int step);
+/* =============================================================================
+ *
+ * PROGRESSBAR
+ *
+ * ============================================================================= */
+NK_API int nk_progress(struct nk_context*, nk_size *cur, nk_size max, int modifyable);
+NK_API nk_size nk_prog(struct nk_context*, nk_size cur, nk_size max, int modifyable);
+
+/* =============================================================================
+ *
+ * COLOR PICKER
+ *
+ * ============================================================================= */
+NK_API struct nk_colorf nk_color_picker(struct nk_context*, struct nk_colorf, enum nk_color_format);
+NK_API int nk_color_pick(struct nk_context*, struct nk_colorf*, enum nk_color_format);
+/* =============================================================================
+ *
+ * PROPERTIES
+ *
+ * =============================================================================
+/// ### Properties
+/// Properties are the main value modification widgets in Nuklear. Changing a value
+/// can be achieved by dragging, adding/removing incremental steps on button click
+/// or by directly typing a number.
+///
+/// #### Usage
+/// Each property requires a unique name for identifaction that is also used for
+/// displaying a label. If you want to use the same name multiple times make sure
+/// add a '#' before your name. The '#' will not be shown but will generate a
+/// unique ID. Each propery also takes in a minimum and maximum value. If you want
+/// to make use of the complete number range of a type just use the provided
+/// type limits from `limits.h`. For example `INT_MIN` and `INT_MAX` for
+/// `nk_property_int` and `nk_propertyi`. In additional each property takes in
+/// a increment value that will be added or subtracted if either the increment
+/// decrement button is clicked. Finally there is a value for increment per pixel
+/// dragged that is added or subtracted from the value.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int value = 0;
+/// struct nk_context ctx;
+/// nk_init_xxx(&ctx, ...);
+/// while (1) {
+/// // Input
+/// Event evt;
+/// nk_input_begin(&ctx);
+/// while (GetEvent(&evt)) {
+/// if (evt.type == MOUSE_MOVE)
+/// nk_input_motion(&ctx, evt.motion.x, evt.motion.y);
+/// else if (evt.type == [...]) {
+/// nk_input_xxx(...);
+/// }
+/// }
+/// nk_input_end(&ctx);
+/// //
+/// // Window
+/// if (nk_begin_xxx(...) {
+/// // Property
+/// nk_layout_row_dynamic(...);
+/// nk_property_int(ctx, "ID", INT_MIN, &value, INT_MAX, 1, 1);
+/// }
+/// nk_end(ctx);
+/// //
+/// // Draw
+/// const struct nk_command *cmd = 0;
+/// nk_foreach(cmd, &ctx) {
+/// switch (cmd->type) {
+/// case NK_COMMAND_LINE:
+/// your_draw_line_function(...)
+/// break;
+/// case NK_COMMAND_RECT
+/// your_draw_rect_function(...)
+/// break;
+/// case ...:
+/// // [...]
+/// }
+// nk_clear(&ctx);
+/// }
+/// nk_free(&ctx);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// #### Reference
+/// Function | Description
+/// --------------------|-------------------------------------------
+/// nk_property_int | Integer property directly modifing a passed in value
+/// nk_property_float | Float property directly modifing a passed in value
+/// nk_property_double | Double property directly modifing a passed in value
+/// nk_propertyi | Integer property returning the modified int value
+/// nk_propertyf | Float property returning the modified float value
+/// nk_propertyd | Double property returning the modified double value
+///
+*/
+/*/// #### nk_property_int
+/// Integer property directly modifing a passed in value
+/// !!! WARNING
+/// To generate a unique property ID using the same label make sure to insert
+/// a `#` at the beginning. It will not be shown but guarantees correct behavior.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_property_int(struct nk_context *ctx, const char *name, int min, int *val, int max, int step, float inc_per_pixel);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// --------------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after calling a layouting function
+/// __name__ | String used both as a label as well as a unique identifier
+/// __min__ | Minimum value not allowed to be underflown
+/// __val__ | Integer pointer to be modified
+/// __max__ | Maximum value not allowed to be overflown
+/// __step__ | Increment added and subtracted on increment and decrement button
+/// __inc_per_pixel__ | Value per pixel added or subtracted on dragging
+*/
+NK_API void nk_property_int(struct nk_context*, const char *name, int min, int *val, int max, int step, float inc_per_pixel);
+/*/// #### nk_property_float
+/// Float property directly modifing a passed in value
+/// !!! WARNING
+/// To generate a unique property ID using the same label make sure to insert
+/// a `#` at the beginning. It will not be shown but guarantees correct behavior.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_property_float(struct nk_context *ctx, const char *name, float min, float *val, float max, float step, float inc_per_pixel);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// --------------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after calling a layouting function
+/// __name__ | String used both as a label as well as a unique identifier
+/// __min__ | Minimum value not allowed to be underflown
+/// __val__ | Float pointer to be modified
+/// __max__ | Maximum value not allowed to be overflown
+/// __step__ | Increment added and subtracted on increment and decrement button
+/// __inc_per_pixel__ | Value per pixel added or subtracted on dragging
+*/
+NK_API void nk_property_float(struct nk_context*, const char *name, float min, float *val, float max, float step, float inc_per_pixel);
+/*/// #### nk_property_double
+/// Double property directly modifing a passed in value
+/// !!! WARNING
+/// To generate a unique property ID using the same label make sure to insert
+/// a `#` at the beginning. It will not be shown but guarantees correct behavior.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// void nk_property_double(struct nk_context *ctx, const char *name, double min, double *val, double max, double step, double inc_per_pixel);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// --------------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after calling a layouting function
+/// __name__ | String used both as a label as well as a unique identifier
+/// __min__ | Minimum value not allowed to be underflown
+/// __val__ | Double pointer to be modified
+/// __max__ | Maximum value not allowed to be overflown
+/// __step__ | Increment added and subtracted on increment and decrement button
+/// __inc_per_pixel__ | Value per pixel added or subtracted on dragging
+*/
+NK_API void nk_property_double(struct nk_context*, const char *name, double min, double *val, double max, double step, float inc_per_pixel);
+/*/// #### nk_propertyi
+/// Integer property modifing a passed in value and returning the new value
+/// !!! WARNING
+/// To generate a unique property ID using the same label make sure to insert
+/// a `#` at the beginning. It will not be shown but guarantees correct behavior.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// int nk_propertyi(struct nk_context *ctx, const char *name, int min, int val, int max, int step, float inc_per_pixel);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// --------------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after calling a layouting function
+/// __name__ | String used both as a label as well as a unique identifier
+/// __min__ | Minimum value not allowed to be underflown
+/// __val__ | Current integer value to be modified and returned
+/// __max__ | Maximum value not allowed to be overflown
+/// __step__ | Increment added and subtracted on increment and decrement button
+/// __inc_per_pixel__ | Value per pixel added or subtracted on dragging
+///
+/// Returns the new modified integer value
+*/
+NK_API int nk_propertyi(struct nk_context*, const char *name, int min, int val, int max, int step, float inc_per_pixel);
+/*/// #### nk_propertyf
+/// Float property modifing a passed in value and returning the new value
+/// !!! WARNING
+/// To generate a unique property ID using the same label make sure to insert
+/// a `#` at the beginning. It will not be shown but guarantees correct behavior.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// float nk_propertyf(struct nk_context *ctx, const char *name, float min, float val, float max, float step, float inc_per_pixel);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// --------------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after calling a layouting function
+/// __name__ | String used both as a label as well as a unique identifier
+/// __min__ | Minimum value not allowed to be underflown
+/// __val__ | Current float value to be modified and returned
+/// __max__ | Maximum value not allowed to be overflown
+/// __step__ | Increment added and subtracted on increment and decrement button
+/// __inc_per_pixel__ | Value per pixel added or subtracted on dragging
+///
+/// Returns the new modified float value
+*/
+NK_API float nk_propertyf(struct nk_context*, const char *name, float min, float val, float max, float step, float inc_per_pixel);
+/*/// #### nk_propertyd
+/// Float property modifing a passed in value and returning the new value
+/// !!! WARNING
+/// To generate a unique property ID using the same label make sure to insert
+/// a `#` at the beginning. It will not be shown but guarantees correct behavior.
+///
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~c
+/// float nk_propertyd(struct nk_context *ctx, const char *name, double min, double val, double max, double step, double inc_per_pixel);
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// Parameter | Description
+/// --------------------|-----------------------------------------------------------
+/// __ctx__ | Must point to an previously initialized `nk_context` struct after calling a layouting function
+/// __name__ | String used both as a label as well as a unique identifier
+/// __min__ | Minimum value not allowed to be underflown
+/// __val__ | Current double value to be modified and returned
+/// __max__ | Maximum value not allowed to be overflown
+/// __step__ | Increment added and subtracted on increment and decrement button
+/// __inc_per_pixel__ | Value per pixel added or subtracted on dragging
+///
+/// Returns the new modified double value
+*/
+NK_API double nk_propertyd(struct nk_context*, const char *name, double min, double val, double max, double step, float inc_per_pixel);
+/* =============================================================================
+ *
+ * TEXT EDIT
+ *
+ * ============================================================================= */
+enum nk_edit_flags {
+ NK_EDIT_DEFAULT = 0,
+ NK_EDIT_READ_ONLY = NK_FLAG(0),
+ NK_EDIT_AUTO_SELECT = NK_FLAG(1),
+ NK_EDIT_SIG_ENTER = NK_FLAG(2),
+ NK_EDIT_ALLOW_TAB = NK_FLAG(3),
+ NK_EDIT_NO_CURSOR = NK_FLAG(4),
+ NK_EDIT_SELECTABLE = NK_FLAG(5),
+ NK_EDIT_CLIPBOARD = NK_FLAG(6),
+ NK_EDIT_CTRL_ENTER_NEWLINE = NK_FLAG(7),
+ NK_EDIT_NO_HORIZONTAL_SCROLL = NK_FLAG(8),
+ NK_EDIT_ALWAYS_INSERT_MODE = NK_FLAG(9),
+ NK_EDIT_MULTILINE = NK_FLAG(10),
+ NK_EDIT_GOTO_END_ON_ACTIVATE = NK_FLAG(11)
+};
+enum nk_edit_types {
+ NK_EDIT_SIMPLE = NK_EDIT_ALWAYS_INSERT_MODE,
+ NK_EDIT_FIELD = NK_EDIT_SIMPLE|NK_EDIT_SELECTABLE|NK_EDIT_CLIPBOARD,
+ NK_EDIT_BOX = NK_EDIT_ALWAYS_INSERT_MODE| NK_EDIT_SELECTABLE| NK_EDIT_MULTILINE|NK_EDIT_ALLOW_TAB|NK_EDIT_CLIPBOARD,
+ NK_EDIT_EDITOR = NK_EDIT_SELECTABLE|NK_EDIT_MULTILINE|NK_EDIT_ALLOW_TAB| NK_EDIT_CLIPBOARD
+};
+enum nk_edit_events {
+ NK_EDIT_ACTIVE = NK_FLAG(0), /* edit widget is currently being modified */
+ NK_EDIT_INACTIVE = NK_FLAG(1), /* edit widget is not active and is not being modified */
+ NK_EDIT_ACTIVATED = NK_FLAG(2), /* edit widget went from state inactive to state active */
+ NK_EDIT_DEACTIVATED = NK_FLAG(3), /* edit widget went from state active to state inactive */
+ NK_EDIT_COMMITED = NK_FLAG(4) /* edit widget has received an enter and lost focus */
+};
+NK_API nk_flags nk_edit_string(struct nk_context*, nk_flags, char *buffer, int *len, int max, nk_plugin_filter);
+NK_API nk_flags nk_edit_string_zero_terminated(struct nk_context*, nk_flags, char *buffer, int max, nk_plugin_filter);
+NK_API nk_flags nk_edit_buffer(struct nk_context*, nk_flags, struct nk_text_edit*, nk_plugin_filter);
+NK_API void nk_edit_focus(struct nk_context*, nk_flags flags);
+NK_API void nk_edit_unfocus(struct nk_context*);
+/* =============================================================================
+ *
+ * CHART
+ *
+ * ============================================================================= */
+NK_API int nk_chart_begin(struct nk_context*, enum nk_chart_type, int num, float min, float max);
+NK_API int nk_chart_begin_colored(struct nk_context*, enum nk_chart_type, struct nk_color, struct nk_color active, int num, float min, float max);
+NK_API void nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type, int count, float min_value, float max_value);
+NK_API void nk_chart_add_slot_colored(struct nk_context *ctx, const enum nk_chart_type, struct nk_color, struct nk_color active, int count, float min_value, float max_value);
+NK_API nk_flags nk_chart_push(struct nk_context*, float);
+NK_API nk_flags nk_chart_push_slot(struct nk_context*, float, int);
+NK_API void nk_chart_end(struct nk_context*);
+NK_API void nk_plot(struct nk_context*, enum nk_chart_type, const float *values, int count, int offset);
+NK_API void nk_plot_function(struct nk_context*, enum nk_chart_type, void *userdata, float(*value_getter)(void* user, int index), int count, int offset);
+/* =============================================================================
+ *
+ * POPUP
+ *
+ * ============================================================================= */
+NK_API int nk_popup_begin(struct nk_context*, enum nk_popup_type, const char*, nk_flags, struct nk_rect bounds);
+NK_API void nk_popup_close(struct nk_context*);
+NK_API void nk_popup_end(struct nk_context*);
+/* =============================================================================
+ *
+ * COMBOBOX
+ *
+ * ============================================================================= */
+NK_API int nk_combo(struct nk_context*, const char **items, int count, int selected, int item_height, struct nk_vec2 size);
+NK_API int nk_combo_separator(struct nk_context*, const char *items_separated_by_separator, int separator, int selected, int count, int item_height, struct nk_vec2 size);
+NK_API int nk_combo_string(struct nk_context*, const char *items_separated_by_zeros, int selected, int count, int item_height, struct nk_vec2 size);
+NK_API int nk_combo_callback(struct nk_context*, void(*item_getter)(void*, int, const char**), void *userdata, int selected, int count, int item_height, struct nk_vec2 size);
+NK_API void nk_combobox(struct nk_context*, const char **items, int count, int *selected, int item_height, struct nk_vec2 size);
+NK_API void nk_combobox_string(struct nk_context*, const char *items_separated_by_zeros, int *selected, int count, int item_height, struct nk_vec2 size);
+NK_API void nk_combobox_separator(struct nk_context*, const char *items_separated_by_separator, int separator,int *selected, int count, int item_height, struct nk_vec2 size);
+NK_API void nk_combobox_callback(struct nk_context*, void(*item_getter)(void*, int, const char**), void*, int *selected, int count, int item_height, struct nk_vec2 size);
+/* =============================================================================
+ *
+ * ABSTRACT COMBOBOX
+ *
+ * ============================================================================= */
+NK_API int nk_combo_begin_text(struct nk_context*, const char *selected, int, struct nk_vec2 size);
+NK_API int nk_combo_begin_label(struct nk_context*, const char *selected, struct nk_vec2 size);
+NK_API int nk_combo_begin_color(struct nk_context*, struct nk_color color, struct nk_vec2 size);
+NK_API int nk_combo_begin_symbol(struct nk_context*, enum nk_symbol_type, struct nk_vec2 size);
+NK_API int nk_combo_begin_symbol_label(struct nk_context*, const char *selected, enum nk_symbol_type, struct nk_vec2 size);
+NK_API int nk_combo_begin_symbol_text(struct nk_context*, const char *selected, int, enum nk_symbol_type, struct nk_vec2 size);
+NK_API int nk_combo_begin_image(struct nk_context*, struct nk_image img, struct nk_vec2 size);
+NK_API int nk_combo_begin_image_label(struct nk_context*, const char *selected, struct nk_image, struct nk_vec2 size);
+NK_API int nk_combo_begin_image_text(struct nk_context*, const char *selected, int, struct nk_image, struct nk_vec2 size);
+NK_API int nk_combo_item_label(struct nk_context*, const char*, nk_flags alignment);
+NK_API int nk_combo_item_text(struct nk_context*, const char*,int, nk_flags alignment);
+NK_API int nk_combo_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
+NK_API int nk_combo_item_image_text(struct nk_context*, struct nk_image, const char*, int,nk_flags alignment);
+NK_API int nk_combo_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
+NK_API int nk_combo_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
+NK_API void nk_combo_close(struct nk_context*);
+NK_API void nk_combo_end(struct nk_context*);
+/* =============================================================================
+ *
+ * CONTEXTUAL
+ *
+ * ============================================================================= */
+NK_API int nk_contextual_begin(struct nk_context*, nk_flags, struct nk_vec2, struct nk_rect trigger_bounds);
+NK_API int nk_contextual_item_text(struct nk_context*, const char*, int,nk_flags align);
+NK_API int nk_contextual_item_label(struct nk_context*, const char*, nk_flags align);
+NK_API int nk_contextual_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
+NK_API int nk_contextual_item_image_text(struct nk_context*, struct nk_image, const char*, int len, nk_flags alignment);
+NK_API int nk_contextual_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
+NK_API int nk_contextual_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
+NK_API void nk_contextual_close(struct nk_context*);
+NK_API void nk_contextual_end(struct nk_context*);
+/* =============================================================================
+ *
+ * TOOLTIP
+ *
+ * ============================================================================= */
+NK_API void nk_tooltip(struct nk_context*, const char*);
+#ifdef NK_INCLUDE_STANDARD_VARARGS
+NK_API void nk_tooltipf(struct nk_context*, const char*, ...);
+#endif
+NK_API int nk_tooltip_begin(struct nk_context*, float width);
+NK_API void nk_tooltip_end(struct nk_context*);
+/* =============================================================================
+ *
+ * MENU
+ *
+ * ============================================================================= */
+NK_API void nk_menubar_begin(struct nk_context*);
+NK_API void nk_menubar_end(struct nk_context*);
+NK_API int nk_menu_begin_text(struct nk_context*, const char* title, int title_len, nk_flags align, struct nk_vec2 size);
+NK_API int nk_menu_begin_label(struct nk_context*, const char*, nk_flags align, struct nk_vec2 size);
+NK_API int nk_menu_begin_image(struct nk_context*, const char*, struct nk_image, struct nk_vec2 size);
+NK_API int nk_menu_begin_image_text(struct nk_context*, const char*, int,nk_flags align,struct nk_image, struct nk_vec2 size);
+NK_API int nk_menu_begin_image_label(struct nk_context*, const char*, nk_flags align,struct nk_image, struct nk_vec2 size);
+NK_API int nk_menu_begin_symbol(struct nk_context*, const char*, enum nk_symbol_type, struct nk_vec2 size);
+NK_API int nk_menu_begin_symbol_text(struct nk_context*, const char*, int,nk_flags align,enum nk_symbol_type, struct nk_vec2 size);
+NK_API int nk_menu_begin_symbol_label(struct nk_context*, const char*, nk_flags align,enum nk_symbol_type, struct nk_vec2 size);
+NK_API int nk_menu_item_text(struct nk_context*, const char*, int,nk_flags align);
+NK_API int nk_menu_item_label(struct nk_context*, const char*, nk_flags alignment);
+NK_API int nk_menu_item_image_label(struct nk_context*, struct nk_image, const char*, nk_flags alignment);
+NK_API int nk_menu_item_image_text(struct nk_context*, struct nk_image, const char*, int len, nk_flags alignment);
+NK_API int nk_menu_item_symbol_text(struct nk_context*, enum nk_symbol_type, const char*, int, nk_flags alignment);
+NK_API int nk_menu_item_symbol_label(struct nk_context*, enum nk_symbol_type, const char*, nk_flags alignment);
+NK_API void nk_menu_close(struct nk_context*);
+NK_API void nk_menu_end(struct nk_context*);
+/* =============================================================================
+ *
+ * STYLE
+ *
+ * ============================================================================= */
+enum nk_style_colors {
+ NK_COLOR_TEXT,
+ NK_COLOR_WINDOW,
+ NK_COLOR_HEADER,
+ NK_COLOR_BORDER,
+ NK_COLOR_BUTTON,
+ NK_COLOR_BUTTON_HOVER,
+ NK_COLOR_BUTTON_ACTIVE,
+ NK_COLOR_TOGGLE,
+ NK_COLOR_TOGGLE_HOVER,
+ NK_COLOR_TOGGLE_CURSOR,
+ NK_COLOR_SELECT,
+ NK_COLOR_SELECT_ACTIVE,
+ NK_COLOR_SLIDER,
+ NK_COLOR_SLIDER_CURSOR,
+ NK_COLOR_SLIDER_CURSOR_HOVER,
+ NK_COLOR_SLIDER_CURSOR_ACTIVE,
+ NK_COLOR_PROPERTY,
+ NK_COLOR_EDIT,
+ NK_COLOR_EDIT_CURSOR,
+ NK_COLOR_COMBO,
+ NK_COLOR_CHART,
+ NK_COLOR_CHART_COLOR,
+ NK_COLOR_CHART_COLOR_HIGHLIGHT,
+ NK_COLOR_SCROLLBAR,
+ NK_COLOR_SCROLLBAR_CURSOR,
+ NK_COLOR_SCROLLBAR_CURSOR_HOVER,
+ NK_COLOR_SCROLLBAR_CURSOR_ACTIVE,
+ NK_COLOR_TAB_HEADER,
+ NK_COLOR_COUNT
+};
+enum nk_style_cursor {
+ NK_CURSOR_ARROW,
+ NK_CURSOR_TEXT,
+ NK_CURSOR_MOVE,
+ NK_CURSOR_RESIZE_VERTICAL,
+ NK_CURSOR_RESIZE_HORIZONTAL,
+ NK_CURSOR_RESIZE_TOP_LEFT_DOWN_RIGHT,
+ NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT,
+ NK_CURSOR_COUNT
+};
+NK_API void nk_style_default(struct nk_context*);
+NK_API void nk_style_from_table(struct nk_context*, const struct nk_color*);
+NK_API void nk_style_load_cursor(struct nk_context*, enum nk_style_cursor, const struct nk_cursor*);
+NK_API void nk_style_load_all_cursors(struct nk_context*, struct nk_cursor*);
+NK_API const char* nk_style_get_color_by_name(enum nk_style_colors);
+NK_API void nk_style_set_font(struct nk_context*, const struct nk_user_font*);
+NK_API int nk_style_set_cursor(struct nk_context*, enum nk_style_cursor);
+NK_API void nk_style_show_cursor(struct nk_context*);
+NK_API void nk_style_hide_cursor(struct nk_context*);
+
+NK_API int nk_style_push_font(struct nk_context*, const struct nk_user_font*);
+NK_API int nk_style_push_float(struct nk_context*, float*, float);
+NK_API int nk_style_push_vec2(struct nk_context*, struct nk_vec2*, struct nk_vec2);
+NK_API int nk_style_push_style_item(struct nk_context*, struct nk_style_item*, struct nk_style_item);
+NK_API int nk_style_push_flags(struct nk_context*, nk_flags*, nk_flags);
+NK_API int nk_style_push_color(struct nk_context*, struct nk_color*, struct nk_color);
+
+NK_API int nk_style_pop_font(struct nk_context*);
+NK_API int nk_style_pop_float(struct nk_context*);
+NK_API int nk_style_pop_vec2(struct nk_context*);
+NK_API int nk_style_pop_style_item(struct nk_context*);
+NK_API int nk_style_pop_flags(struct nk_context*);
+NK_API int nk_style_pop_color(struct nk_context*);
+/* =============================================================================
+ *
+ * COLOR
+ *
+ * ============================================================================= */
+NK_API struct nk_color nk_rgb(int r, int g, int b);
+NK_API struct nk_color nk_rgb_iv(const int *rgb);
+NK_API struct nk_color nk_rgb_bv(const nk_byte* rgb);
+NK_API struct nk_color nk_rgb_f(float r, float g, float b);
+NK_API struct nk_color nk_rgb_fv(const float *rgb);
+NK_API struct nk_color nk_rgb_cf(struct nk_colorf c);
+NK_API struct nk_color nk_rgb_hex(const char *rgb);
+
+NK_API struct nk_color nk_rgba(int r, int g, int b, int a);
+NK_API struct nk_color nk_rgba_u32(nk_uint);
+NK_API struct nk_color nk_rgba_iv(const int *rgba);
+NK_API struct nk_color nk_rgba_bv(const nk_byte *rgba);
+NK_API struct nk_color nk_rgba_f(float r, float g, float b, float a);
+NK_API struct nk_color nk_rgba_fv(const float *rgba);
+NK_API struct nk_color nk_rgba_cf(struct nk_colorf c);
+NK_API struct nk_color nk_rgba_hex(const char *rgb);
+
+NK_API struct nk_colorf nk_hsva_colorf(float h, float s, float v, float a);
+NK_API struct nk_colorf nk_hsva_colorfv(float *c);
+NK_API void nk_colorf_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_colorf in);
+NK_API void nk_colorf_hsva_fv(float *hsva, struct nk_colorf in);
+
+NK_API struct nk_color nk_hsv(int h, int s, int v);
+NK_API struct nk_color nk_hsv_iv(const int *hsv);
+NK_API struct nk_color nk_hsv_bv(const nk_byte *hsv);
+NK_API struct nk_color nk_hsv_f(float h, float s, float v);
+NK_API struct nk_color nk_hsv_fv(const float *hsv);
+
+NK_API struct nk_color nk_hsva(int h, int s, int v, int a);
+NK_API struct nk_color nk_hsva_iv(const int *hsva);
+NK_API struct nk_color nk_hsva_bv(const nk_byte *hsva);
+NK_API struct nk_color nk_hsva_f(float h, float s, float v, float a);
+NK_API struct nk_color nk_hsva_fv(const float *hsva);
+
+/* color (conversion nuklear --> user) */
+NK_API void nk_color_f(float *r, float *g, float *b, float *a, struct nk_color);
+NK_API void nk_color_fv(float *rgba_out, struct nk_color);
+NK_API struct nk_colorf nk_color_cf(struct nk_color);
+NK_API void nk_color_d(double *r, double *g, double *b, double *a, struct nk_color);
+NK_API void nk_color_dv(double *rgba_out, struct nk_color);
+
+NK_API nk_uint nk_color_u32(struct nk_color);
+NK_API void nk_color_hex_rgba(char *output, struct nk_color);
+NK_API void nk_color_hex_rgb(char *output, struct nk_color);
+
+NK_API void nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color);
+NK_API void nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color);
+NK_API void nk_color_hsv_iv(int *hsv_out, struct nk_color);
+NK_API void nk_color_hsv_bv(nk_byte *hsv_out, struct nk_color);
+NK_API void nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color);
+NK_API void nk_color_hsv_fv(float *hsv_out, struct nk_color);
+
+NK_API void nk_color_hsva_i(int *h, int *s, int *v, int *a, struct nk_color);
+NK_API void nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color);
+NK_API void nk_color_hsva_iv(int *hsva_out, struct nk_color);
+NK_API void nk_color_hsva_bv(nk_byte *hsva_out, struct nk_color);
+NK_API void nk_color_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_color);
+NK_API void nk_color_hsva_fv(float *hsva_out, struct nk_color);
+/* =============================================================================
+ *
+ * IMAGE
+ *
+ * ============================================================================= */
+NK_API nk_handle nk_handle_ptr(void*);
+NK_API nk_handle nk_handle_id(int);
+NK_API struct nk_image nk_image_handle(nk_handle);
+NK_API struct nk_image nk_image_ptr(void*);
+NK_API struct nk_image nk_image_id(int);
+NK_API int nk_image_is_subimage(const struct nk_image* img);
+NK_API struct nk_image nk_subimage_ptr(void*, unsigned short w, unsigned short h, struct nk_rect sub_region);
+NK_API struct nk_image nk_subimage_id(int, unsigned short w, unsigned short h, struct nk_rect sub_region);
+NK_API struct nk_image nk_subimage_handle(nk_handle, unsigned short w, unsigned short h, struct nk_rect sub_region);
+/* =============================================================================
+ *
+ * MATH
+ *
+ * ============================================================================= */
+NK_API nk_hash nk_murmur_hash(const void *key, int len, nk_hash seed);
+NK_API void nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r, float pad_x, float pad_y, enum nk_heading);
+
+NK_API struct nk_vec2 nk_vec2(float x, float y);
+NK_API struct nk_vec2 nk_vec2i(int x, int y);
+NK_API struct nk_vec2 nk_vec2v(const float *xy);
+NK_API struct nk_vec2 nk_vec2iv(const int *xy);
+
+NK_API struct nk_rect nk_get_null_rect(void);
+NK_API struct nk_rect nk_rect(float x, float y, float w, float h);
+NK_API struct nk_rect nk_recti(int x, int y, int w, int h);
+NK_API struct nk_rect nk_recta(struct nk_vec2 pos, struct nk_vec2 size);
+NK_API struct nk_rect nk_rectv(const float *xywh);
+NK_API struct nk_rect nk_rectiv(const int *xywh);
+NK_API struct nk_vec2 nk_rect_pos(struct nk_rect);
+NK_API struct nk_vec2 nk_rect_size(struct nk_rect);
+/* =============================================================================
+ *
+ * STRING
+ *
+ * ============================================================================= */
+NK_API int nk_strlen(const char *str);
+NK_API int nk_stricmp(const char *s1, const char *s2);
+NK_API int nk_stricmpn(const char *s1, const char *s2, int n);
+NK_API int nk_strtoi(const char *str, const char **endptr);
+NK_API float nk_strtof(const char *str, const char **endptr);
+NK_API double nk_strtod(const char *str, const char **endptr);
+NK_API int nk_strfilter(const char *text, const char *regexp);
+NK_API int nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score);
+NK_API int nk_strmatch_fuzzy_text(const char *txt, int txt_len, const char *pattern, int *out_score);
+/* =============================================================================
+ *
+ * UTF-8
+ *
+ * ============================================================================= */
+NK_API int nk_utf_decode(const char*, nk_rune*, int);
+NK_API int nk_utf_encode(nk_rune, char*, int);
+NK_API int nk_utf_len(const char*, int byte_len);
+NK_API const char* nk_utf_at(const char *buffer, int length, int index, nk_rune *unicode, int *len);
+/* ===============================================================
+ *
+ * FONT
+ *
+ * ===============================================================*/
+/* Font handling in this library was designed to be quite customizable and lets
+ you decide what you want to use and what you want to provide. There are three
+ different ways to use the font atlas. The first two will use your font
+ handling scheme and only requires essential data to run nuklear. The next
+ slightly more advanced features is font handling with vertex buffer output.
+ Finally the most complex API wise is using nuklear's font baking API.
+
+ 1.) Using your own implementation without vertex buffer output
+ --------------------------------------------------------------
+ So first up the easiest way to do font handling is by just providing a
+ `nk_user_font` struct which only requires the height in pixel of the used
+ font and a callback to calculate the width of a string. This way of handling
+ fonts is best fitted for using the normal draw shape command API where you
+ do all the text drawing yourself and the library does not require any kind
+ of deeper knowledge about which font handling mechanism you use.
+ IMPORTANT: the `nk_user_font` pointer provided to nuklear has to persist
+ over the complete life time! I know this sucks but it is currently the only
+ way to switch between fonts.
+
+ float your_text_width_calculation(nk_handle handle, float height, const char *text, int len)
+ {
+ your_font_type *type = handle.ptr;
+ float text_width = ...;
+ return text_width;
+ }
+
+ struct nk_user_font font;
+ font.userdata.ptr = &your_font_class_or_struct;
+ font.height = your_font_height;
+ font.width = your_text_width_calculation;
+
+ struct nk_context ctx;
+ nk_init_default(&ctx, &font);
+
+ 2.) Using your own implementation with vertex buffer output
+ --------------------------------------------------------------
+ While the first approach works fine if you don't want to use the optional
+ vertex buffer output it is not enough if you do. To get font handling working
+ for these cases you have to provide two additional parameters inside the
+ `nk_user_font`. First a texture atlas handle used to draw text as subimages
+ of a bigger font atlas texture and a callback to query a character's glyph
+ information (offset, size, ...). So it is still possible to provide your own
+ font and use the vertex buffer output.
+
+ float your_text_width_calculation(nk_handle handle, float height, const char *text, int len)
+ {
+ your_font_type *type = handle.ptr;
+ float text_width = ...;
+ return text_width;
+ }
+ void query_your_font_glyph(nk_handle handle, float font_height, struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint)
+ {
+ your_font_type *type = handle.ptr;
+ glyph.width = ...;
+ glyph.height = ...;
+ glyph.xadvance = ...;
+ glyph.uv[0].x = ...;
+ glyph.uv[0].y = ...;
+ glyph.uv[1].x = ...;
+ glyph.uv[1].y = ...;
+ glyph.offset.x = ...;
+ glyph.offset.y = ...;
+ }
+
+ struct nk_user_font font;
+ font.userdata.ptr = &your_font_class_or_struct;
+ font.height = your_font_height;
+ font.width = your_text_width_calculation;
+ font.query = query_your_font_glyph;
+ font.texture.id = your_font_texture;
+
+ struct nk_context ctx;
+ nk_init_default(&ctx, &font);
+
+ 3.) Nuklear font baker
+ ------------------------------------
+ The final approach if you do not have a font handling functionality or don't
+ want to use it in this library is by using the optional font baker.
+ The font baker APIs can be used to create a font plus font atlas texture
+ and can be used with or without the vertex buffer output.
+
+ It still uses the `nk_user_font` struct and the two different approaches
+ previously stated still work. The font baker is not located inside
+ `nk_context` like all other systems since it can be understood as more of
+ an extension to nuklear and does not really depend on any `nk_context` state.
+
+ Font baker need to be initialized first by one of the nk_font_atlas_init_xxx
+ functions. If you don't care about memory just call the default version
+ `nk_font_atlas_init_default` which will allocate all memory from the standard library.
+ If you want to control memory allocation but you don't care if the allocated
+ memory is temporary and therefore can be freed directly after the baking process
+ is over or permanent you can call `nk_font_atlas_init`.
+
+ After successfully initializing the font baker you can add Truetype(.ttf) fonts from
+ different sources like memory or from file by calling one of the `nk_font_atlas_add_xxx`.
+ functions. Adding font will permanently store each font, font config and ttf memory block(!)
+ inside the font atlas and allows to reuse the font atlas. If you don't want to reuse
+ the font baker by for example adding additional fonts you can call
+ `nk_font_atlas_cleanup` after the baking process is over (after calling nk_font_atlas_end).
+
+ As soon as you added all fonts you wanted you can now start the baking process
+ for every selected glyph to image by calling `nk_font_atlas_bake`.
+ The baking process returns image memory, width and height which can be used to
+ either create your own image object or upload it to any graphics library.
+ No matter which case you finally have to call `nk_font_atlas_end` which
+ will free all temporary memory including the font atlas image so make sure
+ you created our texture beforehand. `nk_font_atlas_end` requires a handle
+ to your font texture or object and optionally fills a `struct nk_draw_null_texture`
+ which can be used for the optional vertex output. If you don't want it just
+ set the argument to `NULL`.
+
+ At this point you are done and if you don't want to reuse the font atlas you
+ can call `nk_font_atlas_cleanup` to free all truetype blobs and configuration
+ memory. Finally if you don't use the font atlas and any of it's fonts anymore
+ you need to call `nk_font_atlas_clear` to free all memory still being used.
+
+ struct nk_font_atlas atlas;
+ nk_font_atlas_init_default(&atlas);
+ nk_font_atlas_begin(&atlas);
+ nk_font *font = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font.ttf", 13, 0);
+ nk_font *font2 = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font2.ttf", 16, 0);
+ const void* img = nk_font_atlas_bake(&atlas, &img_width, &img_height, NK_FONT_ATLAS_RGBA32);
+ nk_font_atlas_end(&atlas, nk_handle_id(texture), 0);
+
+ struct nk_context ctx;
+ nk_init_default(&ctx, &font->handle);
+ while (1) {
+
+ }
+ nk_font_atlas_clear(&atlas);
+
+ The font baker API is probably the most complex API inside this library and
+ I would suggest reading some of my examples `example/` to get a grip on how
+ to use the font atlas. There are a number of details I left out. For example
+ how to merge fonts, configure a font with `nk_font_config` to use other languages,
+ use another texture coordinate format and a lot more:
+
+ struct nk_font_config cfg = nk_font_config(font_pixel_height);
+ cfg.merge_mode = nk_false or nk_true;
+ cfg.range = nk_font_korean_glyph_ranges();
+ cfg.coord_type = NK_COORD_PIXEL;
+ nk_font *font = nk_font_atlas_add_from_file(&atlas, "Path/To/Your/TTF_Font.ttf", 13, &cfg);
+
+*/
+struct nk_user_font_glyph;
+typedef float(*nk_text_width_f)(nk_handle, float h, const char*, int len);
+typedef void(*nk_query_font_glyph_f)(nk_handle handle, float font_height,
+ struct nk_user_font_glyph *glyph,
+ nk_rune codepoint, nk_rune next_codepoint);
+
+#if defined(NK_INCLUDE_VERTEX_BUFFER_OUTPUT) || defined(NK_INCLUDE_SOFTWARE_FONT)
+struct nk_user_font_glyph {
+ struct nk_vec2 uv[2];
+ /* texture coordinates */
+ struct nk_vec2 offset;
+ /* offset between top left and glyph */
+ float width, height;
+ /* size of the glyph */
+ float xadvance;
+ /* offset to the next glyph */
+};
+#endif
+
+struct nk_user_font {
+ nk_handle userdata;
+ /* user provided font handle */
+ float height;
+ /* max height of the font */
+ nk_text_width_f width;
+ /* font string width in pixel callback */
+#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+ nk_query_font_glyph_f query;
+ /* font glyph callback to query drawing info */
+ nk_handle texture;
+ /* texture handle to the used font atlas or texture */
+#endif
+};
+
+#ifdef NK_INCLUDE_FONT_BAKING
+enum nk_font_coord_type {
+ NK_COORD_UV, /* texture coordinates inside font glyphs are clamped between 0-1 */
+ NK_COORD_PIXEL /* texture coordinates inside font glyphs are in absolute pixel */
+};
+
+struct nk_font;
+struct nk_baked_font {
+ float height;
+ /* height of the font */
+ float ascent, descent;
+ /* font glyphs ascent and descent */
+ nk_rune glyph_offset;
+ /* glyph array offset inside the font glyph baking output array */
+ nk_rune glyph_count;
+ /* number of glyphs of this font inside the glyph baking array output */
+ const nk_rune *ranges;
+ /* font codepoint ranges as pairs of (from/to) and 0 as last element */
+};
+
+struct nk_font_config {
+ struct nk_font_config *next;
+ /* NOTE: only used internally */
+ void *ttf_blob;
+ /* pointer to loaded TTF file memory block.
+ * NOTE: not needed for nk_font_atlas_add_from_memory and nk_font_atlas_add_from_file. */
+ nk_size ttf_size;
+ /* size of the loaded TTF file memory block
+ * NOTE: not needed for nk_font_atlas_add_from_memory and nk_font_atlas_add_from_file. */
+
+ unsigned char ttf_data_owned_by_atlas;
+ /* used inside font atlas: default to: 0*/
+ unsigned char merge_mode;
+ /* merges this font into the last font */
+ unsigned char pixel_snap;
+ /* align every character to pixel boundary (if true set oversample (1,1)) */
+ unsigned char oversample_v, oversample_h;
+ /* rasterize at hight quality for sub-pixel position */
+ unsigned char padding[3];
+
+ float size;
+ /* baked pixel height of the font */
+ enum nk_font_coord_type coord_type;
+ /* texture coordinate format with either pixel or UV coordinates */
+ struct nk_vec2 spacing;
+ /* extra pixel spacing between glyphs */
+ const nk_rune *range;
+ /* list of unicode ranges (2 values per range, zero terminated) */
+ struct nk_baked_font *font;
+ /* font to setup in the baking process: NOTE: not needed for font atlas */
+ nk_rune fallback_glyph;
+ /* fallback glyph to use if a given rune is not found */
+ struct nk_font_config *n;
+ struct nk_font_config *p;
+};
+
+struct nk_font_glyph {
+ nk_rune codepoint;
+ float xadvance;
+ float x0, y0, x1, y1, w, h;
+ float u0, v0, u1, v1;
+};
+
+struct nk_font {
+ struct nk_font *next;
+ struct nk_user_font handle;
+ struct nk_baked_font info;
+ float scale;
+ struct nk_font_glyph *glyphs;
+ const struct nk_font_glyph *fallback;
+ nk_rune fallback_codepoint;
+ nk_handle texture;
+ struct nk_font_config *config;
+};
+
+enum nk_font_atlas_format {
+ NK_FONT_ATLAS_ALPHA8,
+ NK_FONT_ATLAS_RGBA32
+};
+
+struct nk_font_atlas {
+ void *pixel;
+ int tex_width;
+ int tex_height;
+
+ struct nk_allocator permanent;
+ struct nk_allocator temporary;
+
+ struct nk_recti custom;
+ struct nk_cursor cursors[NK_CURSOR_COUNT];
+
+ int glyph_count;
+ struct nk_font_glyph *glyphs;
+ struct nk_font *default_font;
+ struct nk_font *fonts;
+ struct nk_font_config *config;
+ int font_num;
+};
+
+/* some language glyph codepoint ranges */
+NK_API const nk_rune *nk_font_default_glyph_ranges(void);
+NK_API const nk_rune *nk_font_chinese_glyph_ranges(void);
+NK_API const nk_rune *nk_font_cyrillic_glyph_ranges(void);
+NK_API const nk_rune *nk_font_korean_glyph_ranges(void);
+
+#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
+NK_API void nk_font_atlas_init_default(struct nk_font_atlas*);
+#endif
+NK_API void nk_font_atlas_init(struct nk_font_atlas*, struct nk_allocator*);
+NK_API void nk_font_atlas_init_custom(struct nk_font_atlas*, struct nk_allocator *persistent, struct nk_allocator *transient);
+NK_API void nk_font_atlas_begin(struct nk_font_atlas*);
+NK_API struct nk_font_config nk_font_config(float pixel_height);
+NK_API struct nk_font *nk_font_atlas_add(struct nk_font_atlas*, const struct nk_font_config*);
+#ifdef NK_INCLUDE_DEFAULT_FONT
+NK_API struct nk_font* nk_font_atlas_add_default(struct nk_font_atlas*, float height, const struct nk_font_config*);
+#endif
+NK_API struct nk_font* nk_font_atlas_add_from_memory(struct nk_font_atlas *atlas, void *memory, nk_size size, float height, const struct nk_font_config *config);
+#ifdef NK_INCLUDE_STANDARD_IO
+NK_API struct nk_font* nk_font_atlas_add_from_file(struct nk_font_atlas *atlas, const char *file_path, float height, const struct nk_font_config*);
+#endif
+NK_API struct nk_font *nk_font_atlas_add_compressed(struct nk_font_atlas*, void *memory, nk_size size, float height, const struct nk_font_config*);
+NK_API struct nk_font* nk_font_atlas_add_compressed_base85(struct nk_font_atlas*, const char *data, float height, const struct nk_font_config *config);
+NK_API const void* nk_font_atlas_bake(struct nk_font_atlas*, int *width, int *height, enum nk_font_atlas_format);
+NK_API void nk_font_atlas_end(struct nk_font_atlas*, nk_handle tex, struct nk_draw_null_texture*);
+NK_API const struct nk_font_glyph* nk_font_find_glyph(struct nk_font*, nk_rune unicode);
+NK_API void nk_font_atlas_cleanup(struct nk_font_atlas *atlas);
+NK_API void nk_font_atlas_clear(struct nk_font_atlas*);
+
+#endif
+
+/* ==============================================================
+ *
+ * MEMORY BUFFER
+ *
+ * ===============================================================*/
+/* A basic (double)-buffer with linear allocation and resetting as only
+ freeing policy. The buffer's main purpose is to control all memory management
+ inside the GUI toolkit and still leave memory control as much as possible in
+ the hand of the user while also making sure the library is easy to use if
+ not as much control is needed.
+ In general all memory inside this library can be provided from the user in
+ three different ways.
+
+ The first way and the one providing most control is by just passing a fixed
+ size memory block. In this case all control lies in the hand of the user
+ since he can exactly control where the memory comes from and how much memory
+ the library should consume. Of course using the fixed size API removes the
+ ability to automatically resize a buffer if not enough memory is provided so
+ you have to take over the resizing. While being a fixed sized buffer sounds
+ quite limiting, it is very effective in this library since the actual memory
+ consumption is quite stable and has a fixed upper bound for a lot of cases.
+
+ If you don't want to think about how much memory the library should allocate
+ at all time or have a very dynamic UI with unpredictable memory consumption
+ habits but still want control over memory allocation you can use the dynamic
+ allocator based API. The allocator consists of two callbacks for allocating
+ and freeing memory and optional userdata so you can plugin your own allocator.
+
+ The final and easiest way can be used by defining
+ NK_INCLUDE_DEFAULT_ALLOCATOR which uses the standard library memory
+ allocation functions malloc and free and takes over complete control over
+ memory in this library.
+*/
+struct nk_memory_status {
+ void *memory;
+ unsigned int type;
+ nk_size size;
+ nk_size allocated;
+ nk_size needed;
+ nk_size calls;
+};
+
+enum nk_allocation_type {
+ NK_BUFFER_FIXED,
+ NK_BUFFER_DYNAMIC
+};
+
+enum nk_buffer_allocation_type {
+ NK_BUFFER_FRONT,
+ NK_BUFFER_BACK,
+ NK_BUFFER_MAX
+};
+
+struct nk_buffer_marker {
+ int active;
+ nk_size offset;
+};
+
+struct nk_memory {void *ptr;nk_size size;};
+struct nk_buffer {
+ struct nk_buffer_marker marker[NK_BUFFER_MAX];
+ /* buffer marker to free a buffer to a certain offset */
+ struct nk_allocator pool;
+ /* allocator callback for dynamic buffers */
+ enum nk_allocation_type type;
+ /* memory management type */
+ struct nk_memory memory;
+ /* memory and size of the current memory block */
+ float grow_factor;
+ /* growing factor for dynamic memory management */
+ nk_size allocated;
+ /* total amount of memory allocated */
+ nk_size needed;
+ /* totally consumed memory given that enough memory is present */
+ nk_size calls;
+ /* number of allocation calls */
+ nk_size size;
+ /* current size of the buffer */
+};
+
+#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
+NK_API void nk_buffer_init_default(struct nk_buffer*);
+#endif
+NK_API void nk_buffer_init(struct nk_buffer*, const struct nk_allocator*, nk_size size);
+NK_API void nk_buffer_init_fixed(struct nk_buffer*, void *memory, nk_size size);
+NK_API void nk_buffer_info(struct nk_memory_status*, struct nk_buffer*);
+NK_API void nk_buffer_push(struct nk_buffer*, enum nk_buffer_allocation_type type, const void *memory, nk_size size, nk_size align);
+NK_API void nk_buffer_mark(struct nk_buffer*, enum nk_buffer_allocation_type type);
+NK_API void nk_buffer_reset(struct nk_buffer*, enum nk_buffer_allocation_type type);
+NK_API void nk_buffer_clear(struct nk_buffer*);
+NK_API void nk_buffer_free(struct nk_buffer*);
+NK_API void *nk_buffer_memory(struct nk_buffer*);
+NK_API const void *nk_buffer_memory_const(const struct nk_buffer*);
+NK_API nk_size nk_buffer_total(struct nk_buffer*);
+
+/* ==============================================================
+ *
+ * STRING
+ *
+ * ===============================================================*/
+/* Basic string buffer which is only used in context with the text editor
+ * to manage and manipulate dynamic or fixed size string content. This is _NOT_
+ * the default string handling method. The only instance you should have any contact
+ * with this API is if you interact with an `nk_text_edit` object inside one of the
+ * copy and paste functions and even there only for more advanced cases. */
+struct nk_str {
+ struct nk_buffer buffer;
+ int len; /* in codepoints/runes/glyphs */
+};
+
+#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
+NK_API void nk_str_init_default(struct nk_str*);
+#endif
+NK_API void nk_str_init(struct nk_str*, const struct nk_allocator*, nk_size size);
+NK_API void nk_str_init_fixed(struct nk_str*, void *memory, nk_size size);
+NK_API void nk_str_clear(struct nk_str*);
+NK_API void nk_str_free(struct nk_str*);
+
+NK_API int nk_str_append_text_char(struct nk_str*, const char*, int);
+NK_API int nk_str_append_str_char(struct nk_str*, const char*);
+NK_API int nk_str_append_text_utf8(struct nk_str*, const char*, int);
+NK_API int nk_str_append_str_utf8(struct nk_str*, const char*);
+NK_API int nk_str_append_text_runes(struct nk_str*, const nk_rune*, int);
+NK_API int nk_str_append_str_runes(struct nk_str*, const nk_rune*);
+
+NK_API int nk_str_insert_at_char(struct nk_str*, int pos, const char*, int);
+NK_API int nk_str_insert_at_rune(struct nk_str*, int pos, const char*, int);
+
+NK_API int nk_str_insert_text_char(struct nk_str*, int pos, const char*, int);
+NK_API int nk_str_insert_str_char(struct nk_str*, int pos, const char*);
+NK_API int nk_str_insert_text_utf8(struct nk_str*, int pos, const char*, int);
+NK_API int nk_str_insert_str_utf8(struct nk_str*, int pos, const char*);
+NK_API int nk_str_insert_text_runes(struct nk_str*, int pos, const nk_rune*, int);
+NK_API int nk_str_insert_str_runes(struct nk_str*, int pos, const nk_rune*);
+
+NK_API void nk_str_remove_chars(struct nk_str*, int len);
+NK_API void nk_str_remove_runes(struct nk_str *str, int len);
+NK_API void nk_str_delete_chars(struct nk_str*, int pos, int len);
+NK_API void nk_str_delete_runes(struct nk_str*, int pos, int len);
+
+NK_API char *nk_str_at_char(struct nk_str*, int pos);
+NK_API char *nk_str_at_rune(struct nk_str*, int pos, nk_rune *unicode, int *len);
+NK_API nk_rune nk_str_rune_at(const struct nk_str*, int pos);
+NK_API const char *nk_str_at_char_const(const struct nk_str*, int pos);
+NK_API const char *nk_str_at_const(const struct nk_str*, int pos, nk_rune *unicode, int *len);
+
+NK_API char *nk_str_get(struct nk_str*);
+NK_API const char *nk_str_get_const(const struct nk_str*);
+NK_API int nk_str_len(struct nk_str*);
+NK_API int nk_str_len_char(struct nk_str*);
+
+/*===============================================================
+ *
+ * TEXT EDITOR
+ *
+ * ===============================================================*/
+/* Editing text in this library is handled by either `nk_edit_string` or
+ * `nk_edit_buffer`. But like almost everything in this library there are multiple
+ * ways of doing it and a balance between control and ease of use with memory
+ * as well as functionality controlled by flags.
+ *
+ * This library generally allows three different levels of memory control:
+ * First of is the most basic way of just providing a simple char array with
+ * string length. This method is probably the easiest way of handling simple
+ * user text input. Main upside is complete control over memory while the biggest
+ * downside in comparison with the other two approaches is missing undo/redo.
+ *
+ * For UIs that require undo/redo the second way was created. It is based on
+ * a fixed size nk_text_edit struct, which has an internal undo/redo stack.
+ * This is mainly useful if you want something more like a text editor but don't want
+ * to have a dynamically growing buffer.
+ *
+ * The final way is using a dynamically growing nk_text_edit struct, which
+ * has both a default version if you don't care where memory comes from and an
+ * allocator version if you do. While the text editor is quite powerful for its
+ * complexity I would not recommend editing gigabytes of data with it.
+ * It is rather designed for uses cases which make sense for a GUI library not for
+ * an full blown text editor.
+ */
+#ifndef NK_TEXTEDIT_UNDOSTATECOUNT
+#define NK_TEXTEDIT_UNDOSTATECOUNT 99
+#endif
+
+#ifndef NK_TEXTEDIT_UNDOCHARCOUNT
+#define NK_TEXTEDIT_UNDOCHARCOUNT 999
+#endif
+
+struct nk_text_edit;
+struct nk_clipboard {
+ nk_handle userdata;
+ nk_plugin_paste paste;
+ nk_plugin_copy copy;
+};
+
+struct nk_text_undo_record {
+ int where;
+ short insert_length;
+ short delete_length;
+ short char_storage;
+};
+
+struct nk_text_undo_state {
+ struct nk_text_undo_record undo_rec[NK_TEXTEDIT_UNDOSTATECOUNT];
+ nk_rune undo_char[NK_TEXTEDIT_UNDOCHARCOUNT];
+ short undo_point;
+ short redo_point;
+ short undo_char_point;
+ short redo_char_point;
+};
+
+enum nk_text_edit_type {
+ NK_TEXT_EDIT_SINGLE_LINE,
+ NK_TEXT_EDIT_MULTI_LINE
+};
+
+enum nk_text_edit_mode {
+ NK_TEXT_EDIT_MODE_VIEW,
+ NK_TEXT_EDIT_MODE_INSERT,
+ NK_TEXT_EDIT_MODE_REPLACE
+};
+
+struct nk_text_edit {
+ struct nk_clipboard clip;
+ struct nk_str string;
+ nk_plugin_filter filter;
+ struct nk_vec2 scrollbar;
+
+ int cursor;
+ int select_start;
+ int select_end;
+ unsigned char mode;
+ unsigned char cursor_at_end_of_line;
+ unsigned char initialized;
+ unsigned char has_preferred_x;
+ unsigned char single_line;
+ unsigned char active;
+ unsigned char padding1;
+ float preferred_x;
+ struct nk_text_undo_state undo;
+};
+
+/* filter function */
+NK_API int nk_filter_default(const struct nk_text_edit*, nk_rune unicode);
+NK_API int nk_filter_ascii(const struct nk_text_edit*, nk_rune unicode);
+NK_API int nk_filter_float(const struct nk_text_edit*, nk_rune unicode);
+NK_API int nk_filter_decimal(const struct nk_text_edit*, nk_rune unicode);
+NK_API int nk_filter_hex(const struct nk_text_edit*, nk_rune unicode);
+NK_API int nk_filter_oct(const struct nk_text_edit*, nk_rune unicode);
+NK_API int nk_filter_binary(const struct nk_text_edit*, nk_rune unicode);
+
+/* text editor */
+#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
+NK_API void nk_textedit_init_default(struct nk_text_edit*);
+#endif
+NK_API void nk_textedit_init(struct nk_text_edit*, struct nk_allocator*, nk_size size);
+NK_API void nk_textedit_init_fixed(struct nk_text_edit*, void *memory, nk_size size);
+NK_API void nk_textedit_free(struct nk_text_edit*);
+NK_API void nk_textedit_text(struct nk_text_edit*, const char*, int total_len);
+NK_API void nk_textedit_delete(struct nk_text_edit*, int where, int len);
+NK_API void nk_textedit_delete_selection(struct nk_text_edit*);
+NK_API void nk_textedit_select_all(struct nk_text_edit*);
+NK_API int nk_textedit_cut(struct nk_text_edit*);
+NK_API int nk_textedit_paste(struct nk_text_edit*, char const*, int len);
+NK_API void nk_textedit_undo(struct nk_text_edit*);
+NK_API void nk_textedit_redo(struct nk_text_edit*);
+
+/* ===============================================================
+ *
+ * DRAWING
+ *
+ * ===============================================================*/
+/* This library was designed to be render backend agnostic so it does
+ not draw anything to screen. Instead all drawn shapes, widgets
+ are made of, are buffered into memory and make up a command queue.
+ Each frame therefore fills the command buffer with draw commands
+ that then need to be executed by the user and his own render backend.
+ After that the command buffer needs to be cleared and a new frame can be
+ started. It is probably important to note that the command buffer is the main
+ drawing API and the optional vertex buffer API only takes this format and
+ converts it into a hardware accessible format.
+
+ To use the command queue to draw your own widgets you can access the
+ command buffer of each window by calling `nk_window_get_canvas` after
+ previously having called `nk_begin`:
+
+ void draw_red_rectangle_widget(struct nk_context *ctx)
+ {
+ struct nk_command_buffer *canvas;
+ struct nk_input *input = &ctx->input;
+ canvas = nk_window_get_canvas(ctx);
+
+ struct nk_rect space;
+ enum nk_widget_layout_states state;
+ state = nk_widget(&space, ctx);
+ if (!state) return;
+
+ if (state != NK_WIDGET_ROM)
+ update_your_widget_by_user_input(...);
+ nk_fill_rect(canvas, space, 0, nk_rgb(255,0,0));
+ }
+
+ if (nk_begin(...)) {
+ nk_layout_row_dynamic(ctx, 25, 1);
+ draw_red_rectangle_widget(ctx);
+ }
+ nk_end(..)
+
+ Important to know if you want to create your own widgets is the `nk_widget`
+ call. It allocates space on the panel reserved for this widget to be used,
+ but also returns the state of the widget space. If your widget is not seen and does
+ not have to be updated it is '0' and you can just return. If it only has
+ to be drawn the state will be `NK_WIDGET_ROM` otherwise you can do both
+ update and draw your widget. The reason for separating is to only draw and
+ update what is actually necessary which is crucial for performance.
+*/
+enum nk_command_type {
+ NK_COMMAND_NOP,
+ NK_COMMAND_SCISSOR,
+ NK_COMMAND_LINE,
+ NK_COMMAND_CURVE,
+ NK_COMMAND_RECT,
+ NK_COMMAND_RECT_FILLED,
+ NK_COMMAND_RECT_MULTI_COLOR,
+ NK_COMMAND_CIRCLE,
+ NK_COMMAND_CIRCLE_FILLED,
+ NK_COMMAND_ARC,
+ NK_COMMAND_ARC_FILLED,
+ NK_COMMAND_TRIANGLE,
+ NK_COMMAND_TRIANGLE_FILLED,
+ NK_COMMAND_POLYGON,
+ NK_COMMAND_POLYGON_FILLED,
+ NK_COMMAND_POLYLINE,
+ NK_COMMAND_TEXT,
+ NK_COMMAND_IMAGE,
+ NK_COMMAND_CUSTOM
+};
+
+/* command base and header of every command inside the buffer */
+struct nk_command {
+ enum nk_command_type type;
+ nk_size next;
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+ nk_handle userdata;
+#endif
+};
+
+struct nk_command_scissor {
+ struct nk_command header;
+ short x, y;
+ unsigned short w, h;
+};
+
+struct nk_command_line {
+ struct nk_command header;
+ unsigned short line_thickness;
+ struct nk_vec2i begin;
+ struct nk_vec2i end;
+ struct nk_color color;
+};
+
+struct nk_command_curve {
+ struct nk_command header;
+ unsigned short line_thickness;
+ struct nk_vec2i begin;
+ struct nk_vec2i end;
+ struct nk_vec2i ctrl[2];
+ struct nk_color color;
+};
+
+struct nk_command_rect {
+ struct nk_command header;
+ unsigned short rounding;
+ unsigned short line_thickness;
+ short x, y;
+ unsigned short w, h;
+ struct nk_color color;
+};
+
+struct nk_command_rect_filled {
+ struct nk_command header;
+ unsigned short rounding;
+ short x, y;
+ unsigned short w, h;
+ struct nk_color color;
+};
+
+struct nk_command_rect_multi_color {
+ struct nk_command header;
+ short x, y;
+ unsigned short w, h;
+ struct nk_color left;
+ struct nk_color top;
+ struct nk_color bottom;
+ struct nk_color right;
+};
+
+struct nk_command_triangle {
+ struct nk_command header;
+ unsigned short line_thickness;
+ struct nk_vec2i a;
+ struct nk_vec2i b;
+ struct nk_vec2i c;
+ struct nk_color color;
+};
+
+struct nk_command_triangle_filled {
+ struct nk_command header;
+ struct nk_vec2i a;
+ struct nk_vec2i b;
+ struct nk_vec2i c;
+ struct nk_color color;
+};
+
+struct nk_command_circle {
+ struct nk_command header;
+ short x, y;
+ unsigned short line_thickness;
+ unsigned short w, h;
+ struct nk_color color;
+};
+
+struct nk_command_circle_filled {
+ struct nk_command header;
+ short x, y;
+ unsigned short w, h;
+ struct nk_color color;
+};
+
+struct nk_command_arc {
+ struct nk_command header;
+ short cx, cy;
+ unsigned short r;
+ unsigned short line_thickness;
+ float a[2];
+ struct nk_color color;
+};
+
+struct nk_command_arc_filled {
+ struct nk_command header;
+ short cx, cy;
+ unsigned short r;
+ float a[2];
+ struct nk_color color;
+};
+
+struct nk_command_polygon {
+ struct nk_command header;
+ struct nk_color color;
+ unsigned short line_thickness;
+ unsigned short point_count;
+ struct nk_vec2i points[1];
+};
+
+struct nk_command_polygon_filled {
+ struct nk_command header;
+ struct nk_color color;
+ unsigned short point_count;
+ struct nk_vec2i points[1];
+};
+
+struct nk_command_polyline {
+ struct nk_command header;
+ struct nk_color color;
+ unsigned short line_thickness;
+ unsigned short point_count;
+ struct nk_vec2i points[1];
+};
+
+struct nk_command_image {
+ struct nk_command header;
+ short x, y;
+ unsigned short w, h;
+ struct nk_image img;
+ struct nk_color col;
+};
+
+typedef void (*nk_command_custom_callback)(void *canvas, short x,short y,
+ unsigned short w, unsigned short h, nk_handle callback_data);
+struct nk_command_custom {
+ struct nk_command header;
+ short x, y;
+ unsigned short w, h;
+ nk_handle callback_data;
+ nk_command_custom_callback callback;
+};
+
+struct nk_command_text {
+ struct nk_command header;
+ const struct nk_user_font *font;
+ struct nk_color background;
+ struct nk_color foreground;
+ short x, y;
+ unsigned short w, h;
+ float height;
+ int length;
+ char string[1];
+};
+
+enum nk_command_clipping {
+ NK_CLIPPING_OFF = nk_false,
+ NK_CLIPPING_ON = nk_true
+};
+
+struct nk_command_buffer {
+ struct nk_buffer *base;
+ struct nk_rect clip;
+ int use_clipping;
+ nk_handle userdata;
+ nk_size begin, end, last;
+};
+
+/* shape outlines */
+NK_API void nk_stroke_line(struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float line_thickness, struct nk_color);
+NK_API void nk_stroke_curve(struct nk_command_buffer*, float, float, float, float, float, float, float, float, float line_thickness, struct nk_color);
+NK_API void nk_stroke_rect(struct nk_command_buffer*, struct nk_rect, float rounding, float line_thickness, struct nk_color);
+NK_API void nk_stroke_circle(struct nk_command_buffer*, struct nk_rect, float line_thickness, struct nk_color);
+NK_API void nk_stroke_arc(struct nk_command_buffer*, float cx, float cy, float radius, float a_min, float a_max, float line_thickness, struct nk_color);
+NK_API void nk_stroke_triangle(struct nk_command_buffer*, float, float, float, float, float, float, float line_thichness, struct nk_color);
+NK_API void nk_stroke_polyline(struct nk_command_buffer*, float *points, int point_count, float line_thickness, struct nk_color col);
+NK_API void nk_stroke_polygon(struct nk_command_buffer*, float*, int point_count, float line_thickness, struct nk_color);
+
+/* filled shades */
+NK_API void nk_fill_rect(struct nk_command_buffer*, struct nk_rect, float rounding, struct nk_color);
+NK_API void nk_fill_rect_multi_color(struct nk_command_buffer*, struct nk_rect, struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom);
+NK_API void nk_fill_circle(struct nk_command_buffer*, struct nk_rect, struct nk_color);
+NK_API void nk_fill_arc(struct nk_command_buffer*, float cx, float cy, float radius, float a_min, float a_max, struct nk_color);
+NK_API void nk_fill_triangle(struct nk_command_buffer*, float x0, float y0, float x1, float y1, float x2, float y2, struct nk_color);
+NK_API void nk_fill_polygon(struct nk_command_buffer*, float*, int point_count, struct nk_color);
+
+/* misc */
+NK_API void nk_draw_image(struct nk_command_buffer*, struct nk_rect, const struct nk_image*, struct nk_color);
+NK_API void nk_draw_text(struct nk_command_buffer*, struct nk_rect, const char *text, int len, const struct nk_user_font*, struct nk_color, struct nk_color);
+NK_API void nk_push_scissor(struct nk_command_buffer*, struct nk_rect);
+NK_API void nk_push_custom(struct nk_command_buffer*, struct nk_rect, nk_command_custom_callback, nk_handle usr);
+
+/* ===============================================================
+ *
+ * INPUT
+ *
+ * ===============================================================*/
+struct nk_mouse_button {
+ int down;
+ unsigned int clicked;
+ struct nk_vec2 clicked_pos;
+};
+struct nk_mouse {
+ struct nk_mouse_button buttons[NK_BUTTON_MAX];
+ struct nk_vec2 pos;
+ struct nk_vec2 prev;
+ struct nk_vec2 delta;
+ struct nk_vec2 scroll_delta;
+ unsigned char grab;
+ unsigned char grabbed;
+ unsigned char ungrab;
+};
+
+struct nk_key {
+ int down;
+ unsigned int clicked;
+};
+struct nk_keyboard {
+ struct nk_key keys[NK_KEY_MAX];
+ char text[NK_INPUT_MAX];
+ int text_len;
+};
+
+struct nk_input {
+ struct nk_keyboard keyboard;
+ struct nk_mouse mouse;
+};
+
+NK_API int nk_input_has_mouse_click(const struct nk_input*, enum nk_buttons);
+NK_API int nk_input_has_mouse_click_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect);
+NK_API int nk_input_has_mouse_click_down_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect, int down);
+NK_API int nk_input_is_mouse_click_in_rect(const struct nk_input*, enum nk_buttons, struct nk_rect);
+NK_API int nk_input_is_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id, struct nk_rect b, int down);
+NK_API int nk_input_any_mouse_click_in_rect(const struct nk_input*, struct nk_rect);
+NK_API int nk_input_is_mouse_prev_hovering_rect(const struct nk_input*, struct nk_rect);
+NK_API int nk_input_is_mouse_hovering_rect(const struct nk_input*, struct nk_rect);
+NK_API int nk_input_mouse_clicked(const struct nk_input*, enum nk_buttons, struct nk_rect);
+NK_API int nk_input_is_mouse_down(const struct nk_input*, enum nk_buttons);
+NK_API int nk_input_is_mouse_pressed(const struct nk_input*, enum nk_buttons);
+NK_API int nk_input_is_mouse_released(const struct nk_input*, enum nk_buttons);
+NK_API int nk_input_is_key_pressed(const struct nk_input*, enum nk_keys);
+NK_API int nk_input_is_key_released(const struct nk_input*, enum nk_keys);
+NK_API int nk_input_is_key_down(const struct nk_input*, enum nk_keys);
+
+/* ===============================================================
+ *
+ * DRAW LIST
+ *
+ * ===============================================================*/
+#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+/* The optional vertex buffer draw list provides a 2D drawing context
+ with antialiasing functionality which takes basic filled or outlined shapes
+ or a path and outputs vertexes, elements and draw commands.
+ The actual draw list API is not required to be used directly while using this
+ library since converting the default library draw command output is done by
+ just calling `nk_convert` but I decided to still make this library accessible
+ since it can be useful.
+
+ The draw list is based on a path buffering and polygon and polyline
+ rendering API which allows a lot of ways to draw 2D content to screen.
+ In fact it is probably more powerful than needed but allows even more crazy
+ things than this library provides by default.
+*/
+typedef nk_ushort nk_draw_index;
+enum nk_draw_list_stroke {
+ NK_STROKE_OPEN = nk_false,
+ /* build up path has no connection back to the beginning */
+ NK_STROKE_CLOSED = nk_true
+ /* build up path has a connection back to the beginning */
+};
+
+enum nk_draw_vertex_layout_attribute {
+ NK_VERTEX_POSITION,
+ NK_VERTEX_COLOR,
+ NK_VERTEX_TEXCOORD,
+ NK_VERTEX_ATTRIBUTE_COUNT
+};
+
+enum nk_draw_vertex_layout_format {
+ NK_FORMAT_SCHAR,
+ NK_FORMAT_SSHORT,
+ NK_FORMAT_SINT,
+ NK_FORMAT_UCHAR,
+ NK_FORMAT_USHORT,
+ NK_FORMAT_UINT,
+ NK_FORMAT_FLOAT,
+ NK_FORMAT_DOUBLE,
+
+NK_FORMAT_COLOR_BEGIN,
+ NK_FORMAT_R8G8B8 = NK_FORMAT_COLOR_BEGIN,
+ NK_FORMAT_R16G15B16,
+ NK_FORMAT_R32G32B32,
+
+ NK_FORMAT_R8G8B8A8,
+ NK_FORMAT_B8G8R8A8,
+ NK_FORMAT_R16G15B16A16,
+ NK_FORMAT_R32G32B32A32,
+ NK_FORMAT_R32G32B32A32_FLOAT,
+ NK_FORMAT_R32G32B32A32_DOUBLE,
+
+ NK_FORMAT_RGB32,
+ NK_FORMAT_RGBA32,
+NK_FORMAT_COLOR_END = NK_FORMAT_RGBA32,
+ NK_FORMAT_COUNT
+};
+
+#define NK_VERTEX_LAYOUT_END NK_VERTEX_ATTRIBUTE_COUNT,NK_FORMAT_COUNT,0
+struct nk_draw_vertex_layout_element {
+ enum nk_draw_vertex_layout_attribute attribute;
+ enum nk_draw_vertex_layout_format format;
+ nk_size offset;
+};
+
+struct nk_draw_command {
+ unsigned int elem_count;
+ /* number of elements in the current draw batch */
+ struct nk_rect clip_rect;
+ /* current screen clipping rectangle */
+ nk_handle texture;
+ /* current texture to set */
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+ nk_handle userdata;
+#endif
+};
+
+struct nk_draw_list {
+ struct nk_rect clip_rect;
+ struct nk_vec2 circle_vtx[12];
+ struct nk_convert_config config;
+
+ struct nk_buffer *buffer;
+ struct nk_buffer *vertices;
+ struct nk_buffer *elements;
+
+ unsigned int element_count;
+ unsigned int vertex_count;
+ unsigned int cmd_count;
+ nk_size cmd_offset;
+
+ unsigned int path_count;
+ unsigned int path_offset;
+
+ enum nk_anti_aliasing line_AA;
+ enum nk_anti_aliasing shape_AA;
+
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+ nk_handle userdata;
+#endif
+};
+
+/* draw list */
+NK_API void nk_draw_list_init(struct nk_draw_list*);
+NK_API void nk_draw_list_setup(struct nk_draw_list*, const struct nk_convert_config*, struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements, enum nk_anti_aliasing line_aa,enum nk_anti_aliasing shape_aa);
+NK_API void nk_draw_list_clear(struct nk_draw_list*);
+
+/* drawing */
+#define nk_draw_list_foreach(cmd, can, b) for((cmd)=nk__draw_list_begin(can, b); (cmd)!=0; (cmd)=nk__draw_list_next(cmd, b, can))
+NK_API const struct nk_draw_command* nk__draw_list_begin(const struct nk_draw_list*, const struct nk_buffer*);
+NK_API const struct nk_draw_command* nk__draw_list_next(const struct nk_draw_command*, const struct nk_buffer*, const struct nk_draw_list*);
+NK_API const struct nk_draw_command* nk__draw_list_end(const struct nk_draw_list*, const struct nk_buffer*);
+
+/* path */
+NK_API void nk_draw_list_path_clear(struct nk_draw_list*);
+NK_API void nk_draw_list_path_line_to(struct nk_draw_list*, struct nk_vec2 pos);
+NK_API void nk_draw_list_path_arc_to_fast(struct nk_draw_list*, struct nk_vec2 center, float radius, int a_min, int a_max);
+NK_API void nk_draw_list_path_arc_to(struct nk_draw_list*, struct nk_vec2 center, float radius, float a_min, float a_max, unsigned int segments);
+NK_API void nk_draw_list_path_rect_to(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, float rounding);
+NK_API void nk_draw_list_path_curve_to(struct nk_draw_list*, struct nk_vec2 p2, struct nk_vec2 p3, struct nk_vec2 p4, unsigned int num_segments);
+NK_API void nk_draw_list_path_fill(struct nk_draw_list*, struct nk_color);
+NK_API void nk_draw_list_path_stroke(struct nk_draw_list*, struct nk_color, enum nk_draw_list_stroke closed, float thickness);
+
+/* stroke */
+NK_API void nk_draw_list_stroke_line(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, struct nk_color, float thickness);
+NK_API void nk_draw_list_stroke_rect(struct nk_draw_list*, struct nk_rect rect, struct nk_color, float rounding, float thickness);
+NK_API void nk_draw_list_stroke_triangle(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, struct nk_vec2 c, struct nk_color, float thickness);
+NK_API void nk_draw_list_stroke_circle(struct nk_draw_list*, struct nk_vec2 center, float radius, struct nk_color, unsigned int segs, float thickness);
+NK_API void nk_draw_list_stroke_curve(struct nk_draw_list*, struct nk_vec2 p0, struct nk_vec2 cp0, struct nk_vec2 cp1, struct nk_vec2 p1, struct nk_color, unsigned int segments, float thickness);
+NK_API void nk_draw_list_stroke_poly_line(struct nk_draw_list*, const struct nk_vec2 *pnts, const unsigned int cnt, struct nk_color, enum nk_draw_list_stroke, float thickness, enum nk_anti_aliasing);
+
+/* fill */
+NK_API void nk_draw_list_fill_rect(struct nk_draw_list*, struct nk_rect rect, struct nk_color, float rounding);
+NK_API void nk_draw_list_fill_rect_multi_color(struct nk_draw_list*, struct nk_rect rect, struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom);
+NK_API void nk_draw_list_fill_triangle(struct nk_draw_list*, struct nk_vec2 a, struct nk_vec2 b, struct nk_vec2 c, struct nk_color);
+NK_API void nk_draw_list_fill_circle(struct nk_draw_list*, struct nk_vec2 center, float radius, struct nk_color col, unsigned int segs);
+NK_API void nk_draw_list_fill_poly_convex(struct nk_draw_list*, const struct nk_vec2 *points, const unsigned int count, struct nk_color, enum nk_anti_aliasing);
+
+/* misc */
+NK_API void nk_draw_list_add_image(struct nk_draw_list*, struct nk_image texture, struct nk_rect rect, struct nk_color);
+NK_API void nk_draw_list_add_text(struct nk_draw_list*, const struct nk_user_font*, struct nk_rect, const char *text, int len, float font_height, struct nk_color);
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+NK_API void nk_draw_list_push_userdata(struct nk_draw_list*, nk_handle userdata);
+#endif
+
+#endif
+
+/* ===============================================================
+ *
+ * GUI
+ *
+ * ===============================================================*/
+enum nk_style_item_type {
+ NK_STYLE_ITEM_COLOR,
+ NK_STYLE_ITEM_IMAGE
+};
+
+union nk_style_item_data {
+ struct nk_image image;
+ struct nk_color color;
+};
+
+struct nk_style_item {
+ enum nk_style_item_type type;
+ union nk_style_item_data data;
+};
+
+struct nk_style_text {
+ struct nk_color color;
+ struct nk_vec2 padding;
+};
+
+struct nk_style_button {
+ /* background */
+ struct nk_style_item normal;
+ struct nk_style_item hover;
+ struct nk_style_item active;
+ struct nk_color border_color;
+
+ /* text */
+ struct nk_color text_background;
+ struct nk_color text_normal;
+ struct nk_color text_hover;
+ struct nk_color text_active;
+ nk_flags text_alignment;
+
+ /* properties */
+ float border;
+ float rounding;
+ struct nk_vec2 padding;
+ struct nk_vec2 image_padding;
+ struct nk_vec2 touch_padding;
+
+ /* optional user callbacks */
+ nk_handle userdata;
+ void(*draw_begin)(struct nk_command_buffer*, nk_handle userdata);
+ void(*draw_end)(struct nk_command_buffer*, nk_handle userdata);
+};
+
+struct nk_style_toggle {
+ /* background */
+ struct nk_style_item normal;
+ struct nk_style_item hover;
+ struct nk_style_item active;
+ struct nk_color border_color;
+
+ /* cursor */
+ struct nk_style_item cursor_normal;
+ struct nk_style_item cursor_hover;
+
+ /* text */
+ struct nk_color text_normal;
+ struct nk_color text_hover;
+ struct nk_color text_active;
+ struct nk_color text_background;
+ nk_flags text_alignment;
+
+ /* properties */
+ struct nk_vec2 padding;
+ struct nk_vec2 touch_padding;
+ float spacing;
+ float border;
+
+ /* optional user callbacks */
+ nk_handle userdata;
+ void(*draw_begin)(struct nk_command_buffer*, nk_handle);
+ void(*draw_end)(struct nk_command_buffer*, nk_handle);
+};
+
+struct nk_style_selectable {
+ /* background (inactive) */
+ struct nk_style_item normal;
+ struct nk_style_item hover;
+ struct nk_style_item pressed;
+
+ /* background (active) */
+ struct nk_style_item normal_active;
+ struct nk_style_item hover_active;
+ struct nk_style_item pressed_active;
+
+ /* text color (inactive) */
+ struct nk_color text_normal;
+ struct nk_color text_hover;
+ struct nk_color text_pressed;
+
+ /* text color (active) */
+ struct nk_color text_normal_active;
+ struct nk_color text_hover_active;
+ struct nk_color text_pressed_active;
+ struct nk_color text_background;
+ nk_flags text_alignment;
+
+ /* properties */
+ float rounding;
+ struct nk_vec2 padding;
+ struct nk_vec2 touch_padding;
+ struct nk_vec2 image_padding;
+
+ /* optional user callbacks */
+ nk_handle userdata;
+ void(*draw_begin)(struct nk_command_buffer*, nk_handle);
+ void(*draw_end)(struct nk_command_buffer*, nk_handle);
+};
+
+struct nk_style_slider {
+ /* background */
+ struct nk_style_item normal;
+ struct nk_style_item hover;
+ struct nk_style_item active;
+ struct nk_color border_color;
+
+ /* background bar */
+ struct nk_color bar_normal;
+ struct nk_color bar_hover;
+ struct nk_color bar_active;
+ struct nk_color bar_filled;
+
+ /* cursor */
+ struct nk_style_item cursor_normal;
+ struct nk_style_item cursor_hover;
+ struct nk_style_item cursor_active;
+
+ /* properties */
+ float border;
+ float rounding;
+ float bar_height;
+ struct nk_vec2 padding;
+ struct nk_vec2 spacing;
+ struct nk_vec2 cursor_size;
+
+ /* optional buttons */
+ int show_buttons;
+ struct nk_style_button inc_button;
+ struct nk_style_button dec_button;
+ enum nk_symbol_type inc_symbol;
+ enum nk_symbol_type dec_symbol;
+
+ /* optional user callbacks */
+ nk_handle userdata;
+ void(*draw_begin)(struct nk_command_buffer*, nk_handle);
+ void(*draw_end)(struct nk_command_buffer*, nk_handle);
+};
+
+struct nk_style_progress {
+ /* background */
+ struct nk_style_item normal;
+ struct nk_style_item hover;
+ struct nk_style_item active;
+ struct nk_color border_color;
+
+ /* cursor */
+ struct nk_style_item cursor_normal;
+ struct nk_style_item cursor_hover;
+ struct nk_style_item cursor_active;
+ struct nk_color cursor_border_color;
+
+ /* properties */
+ float rounding;
+ float border;
+ float cursor_border;
+ float cursor_rounding;
+ struct nk_vec2 padding;
+
+ /* optional user callbacks */
+ nk_handle userdata;
+ void(*draw_begin)(struct nk_command_buffer*, nk_handle);
+ void(*draw_end)(struct nk_command_buffer*, nk_handle);
+};
+
+struct nk_style_scrollbar {
+ /* background */
+ struct nk_style_item normal;
+ struct nk_style_item hover;
+ struct nk_style_item active;
+ struct nk_color border_color;
+
+ /* cursor */
+ struct nk_style_item cursor_normal;
+ struct nk_style_item cursor_hover;
+ struct nk_style_item cursor_active;
+ struct nk_color cursor_border_color;
+
+ /* properties */
+ float border;
+ float rounding;
+ float border_cursor;
+ float rounding_cursor;
+ struct nk_vec2 padding;
+
+ /* optional buttons */
+ int show_buttons;
+ struct nk_style_button inc_button;
+ struct nk_style_button dec_button;
+ enum nk_symbol_type inc_symbol;
+ enum nk_symbol_type dec_symbol;
+
+ /* optional user callbacks */
+ nk_handle userdata;
+ void(*draw_begin)(struct nk_command_buffer*, nk_handle);
+ void(*draw_end)(struct nk_command_buffer*, nk_handle);
+};
+
+struct nk_style_edit {
+ /* background */
+ struct nk_style_item normal;
+ struct nk_style_item hover;
+ struct nk_style_item active;
+ struct nk_color border_color;
+ struct nk_style_scrollbar scrollbar;
+
+ /* cursor */
+ struct nk_color cursor_normal;
+ struct nk_color cursor_hover;
+ struct nk_color cursor_text_normal;
+ struct nk_color cursor_text_hover;
+
+ /* text (unselected) */
+ struct nk_color text_normal;
+ struct nk_color text_hover;
+ struct nk_color text_active;
+
+ /* text (selected) */
+ struct nk_color selected_normal;
+ struct nk_color selected_hover;
+ struct nk_color selected_text_normal;
+ struct nk_color selected_text_hover;
+
+ /* properties */
+ float border;
+ float rounding;
+ float cursor_size;
+ struct nk_vec2 scrollbar_size;
+ struct nk_vec2 padding;
+ float row_padding;
+};
+
+struct nk_style_property {
+ /* background */
+ struct nk_style_item normal;
+ struct nk_style_item hover;
+ struct nk_style_item active;
+ struct nk_color border_color;
+
+ /* text */
+ struct nk_color label_normal;
+ struct nk_color label_hover;
+ struct nk_color label_active;
+
+ /* symbols */
+ enum nk_symbol_type sym_left;
+ enum nk_symbol_type sym_right;
+
+ /* properties */
+ float border;
+ float rounding;
+ struct nk_vec2 padding;
+
+ struct nk_style_edit edit;
+ struct nk_style_button inc_button;
+ struct nk_style_button dec_button;
+
+ /* optional user callbacks */
+ nk_handle userdata;
+ void(*draw_begin)(struct nk_command_buffer*, nk_handle);
+ void(*draw_end)(struct nk_command_buffer*, nk_handle);
+};
+
+struct nk_style_chart {
+ /* colors */
+ struct nk_style_item background;
+ struct nk_color border_color;
+ struct nk_color selected_color;
+ struct nk_color color;
+
+ /* properties */
+ float border;
+ float rounding;
+ struct nk_vec2 padding;
+};
+
+struct nk_style_combo {
+ /* background */
+ struct nk_style_item normal;
+ struct nk_style_item hover;
+ struct nk_style_item active;
+ struct nk_color border_color;
+
+ /* label */
+ struct nk_color label_normal;
+ struct nk_color label_hover;
+ struct nk_color label_active;
+
+ /* symbol */
+ struct nk_color symbol_normal;
+ struct nk_color symbol_hover;
+ struct nk_color symbol_active;
+
+ /* button */
+ struct nk_style_button button;
+ enum nk_symbol_type sym_normal;
+ enum nk_symbol_type sym_hover;
+ enum nk_symbol_type sym_active;
+
+ /* properties */
+ float border;
+ float rounding;
+ struct nk_vec2 content_padding;
+ struct nk_vec2 button_padding;
+ struct nk_vec2 spacing;
+};
+
+struct nk_style_tab {
+ /* background */
+ struct nk_style_item background;
+ struct nk_color border_color;
+ struct nk_color text;
+
+ /* button */
+ struct nk_style_button tab_maximize_button;
+ struct nk_style_button tab_minimize_button;
+ struct nk_style_button node_maximize_button;
+ struct nk_style_button node_minimize_button;
+ enum nk_symbol_type sym_minimize;
+ enum nk_symbol_type sym_maximize;
+
+ /* properties */
+ float border;
+ float rounding;
+ float indent;
+ struct nk_vec2 padding;
+ struct nk_vec2 spacing;
+};
+
+enum nk_style_header_align {
+ NK_HEADER_LEFT,
+ NK_HEADER_RIGHT
+};
+struct nk_style_window_header {
+ /* background */
+ struct nk_style_item normal;
+ struct nk_style_item hover;
+ struct nk_style_item active;
+
+ /* button */
+ struct nk_style_button close_button;
+ struct nk_style_button minimize_button;
+ enum nk_symbol_type close_symbol;
+ enum nk_symbol_type minimize_symbol;
+ enum nk_symbol_type maximize_symbol;
+
+ /* title */
+ struct nk_color label_normal;
+ struct nk_color label_hover;
+ struct nk_color label_active;
+
+ /* properties */
+ enum nk_style_header_align align;
+ struct nk_vec2 padding;
+ struct nk_vec2 label_padding;
+ struct nk_vec2 spacing;
+};
+
+struct nk_style_window {
+ struct nk_style_window_header header;
+ struct nk_style_item fixed_background;
+ struct nk_color background;
+
+ struct nk_color border_color;
+ struct nk_color popup_border_color;
+ struct nk_color combo_border_color;
+ struct nk_color contextual_border_color;
+ struct nk_color menu_border_color;
+ struct nk_color group_border_color;
+ struct nk_color tooltip_border_color;
+ struct nk_style_item scaler;
+
+ float border;
+ float combo_border;
+ float contextual_border;
+ float menu_border;
+ float group_border;
+ float tooltip_border;
+ float popup_border;
+ float min_row_height_padding;
+
+ float rounding;
+ struct nk_vec2 spacing;
+ struct nk_vec2 scrollbar_size;
+ struct nk_vec2 min_size;
+
+ struct nk_vec2 padding;
+ struct nk_vec2 group_padding;
+ struct nk_vec2 popup_padding;
+ struct nk_vec2 combo_padding;
+ struct nk_vec2 contextual_padding;
+ struct nk_vec2 menu_padding;
+ struct nk_vec2 tooltip_padding;
+};
+
+struct nk_style {
+ const struct nk_user_font *font;
+ const struct nk_cursor *cursors[NK_CURSOR_COUNT];
+ const struct nk_cursor *cursor_active;
+ struct nk_cursor *cursor_last;
+ int cursor_visible;
+
+ struct nk_style_text text;
+ struct nk_style_button button;
+ struct nk_style_button contextual_button;
+ struct nk_style_button menu_button;
+ struct nk_style_toggle option;
+ struct nk_style_toggle checkbox;
+ struct nk_style_selectable selectable;
+ struct nk_style_slider slider;
+ struct nk_style_progress progress;
+ struct nk_style_property property;
+ struct nk_style_edit edit;
+ struct nk_style_chart chart;
+ struct nk_style_scrollbar scrollh;
+ struct nk_style_scrollbar scrollv;
+ struct nk_style_tab tab;
+ struct nk_style_combo combo;
+ struct nk_style_window window;
+};
+
+NK_API struct nk_style_item nk_style_item_image(struct nk_image img);
+NK_API struct nk_style_item nk_style_item_color(struct nk_color);
+NK_API struct nk_style_item nk_style_item_hide(void);
+
+/*==============================================================
+ * PANEL
+ * =============================================================*/
+#ifndef NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS
+#define NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS 16
+#endif
+#ifndef NK_CHART_MAX_SLOT
+#define NK_CHART_MAX_SLOT 4
+#endif
+
+enum nk_panel_type {
+ NK_PANEL_WINDOW = NK_FLAG(0),
+ NK_PANEL_GROUP = NK_FLAG(1),
+ NK_PANEL_POPUP = NK_FLAG(2),
+ NK_PANEL_CONTEXTUAL = NK_FLAG(4),
+ NK_PANEL_COMBO = NK_FLAG(5),
+ NK_PANEL_MENU = NK_FLAG(6),
+ NK_PANEL_TOOLTIP = NK_FLAG(7)
+};
+enum nk_panel_set {
+ NK_PANEL_SET_NONBLOCK = NK_PANEL_CONTEXTUAL|NK_PANEL_COMBO|NK_PANEL_MENU|NK_PANEL_TOOLTIP,
+ NK_PANEL_SET_POPUP = NK_PANEL_SET_NONBLOCK|NK_PANEL_POPUP,
+ NK_PANEL_SET_SUB = NK_PANEL_SET_POPUP|NK_PANEL_GROUP
+};
+
+struct nk_chart_slot {
+ enum nk_chart_type type;
+ struct nk_color color;
+ struct nk_color highlight;
+ float min, max, range;
+ int count;
+ struct nk_vec2 last;
+ int index;
+};
+
+struct nk_chart {
+ int slot;
+ float x, y, w, h;
+ struct nk_chart_slot slots[NK_CHART_MAX_SLOT];
+};
+
+enum nk_panel_row_layout_type {
+ NK_LAYOUT_DYNAMIC_FIXED = 0,
+ NK_LAYOUT_DYNAMIC_ROW,
+ NK_LAYOUT_DYNAMIC_FREE,
+ NK_LAYOUT_DYNAMIC,
+ NK_LAYOUT_STATIC_FIXED,
+ NK_LAYOUT_STATIC_ROW,
+ NK_LAYOUT_STATIC_FREE,
+ NK_LAYOUT_STATIC,
+ NK_LAYOUT_TEMPLATE,
+ NK_LAYOUT_COUNT
+};
+struct nk_row_layout {
+ enum nk_panel_row_layout_type type;
+ int index;
+ float height;
+ float min_height;
+ int columns;
+ const float *ratio;
+ float item_width;
+ float item_height;
+ float item_offset;
+ float filled;
+ struct nk_rect item;
+ int tree_depth;
+ float templates[NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS];
+};
+
+struct nk_popup_buffer {
+ nk_size begin;
+ nk_size parent;
+ nk_size last;
+ nk_size end;
+ int active;
+};
+
+struct nk_menu_state {
+ float x, y, w, h;
+ struct nk_scroll offset;
+};
+
+struct nk_panel {
+ enum nk_panel_type type;
+ nk_flags flags;
+ struct nk_rect bounds;
+ nk_uint *offset_x;
+ nk_uint *offset_y;
+ float at_x, at_y, max_x;
+ float footer_height;
+ float header_height;
+ float border;
+ unsigned int has_scrolling;
+ struct nk_rect clip;
+ struct nk_menu_state menu;
+ struct nk_row_layout row;
+ struct nk_chart chart;
+ struct nk_command_buffer *buffer;
+ struct nk_panel *parent;
+};
+
+/*==============================================================
+ * WINDOW
+ * =============================================================*/
+#ifndef NK_WINDOW_MAX_NAME
+#define NK_WINDOW_MAX_NAME 64
+#endif
+
+struct nk_table;
+enum nk_window_flags {
+ NK_WINDOW_PRIVATE = NK_FLAG(11),
+ NK_WINDOW_DYNAMIC = NK_WINDOW_PRIVATE,
+ /* special window type growing up in height while being filled to a certain maximum height */
+ NK_WINDOW_ROM = NK_FLAG(12),
+ /* sets window widgets into a read only mode and does not allow input changes */
+ NK_WINDOW_NOT_INTERACTIVE = NK_WINDOW_ROM|NK_WINDOW_NO_INPUT,
+ /* prevents all interaction caused by input to either window or widgets inside */
+ NK_WINDOW_HIDDEN = NK_FLAG(13),
+ /* Hides window and stops any window interaction and drawing */
+ NK_WINDOW_CLOSED = NK_FLAG(14),
+ /* Directly closes and frees the window at the end of the frame */
+ NK_WINDOW_MINIMIZED = NK_FLAG(15),
+ /* marks the window as minimized */
+ NK_WINDOW_REMOVE_ROM = NK_FLAG(16)
+ /* Removes read only mode at the end of the window */
+};
+
+struct nk_popup_state {
+ struct nk_window *win;
+ enum nk_panel_type type;
+ struct nk_popup_buffer buf;
+ nk_hash name;
+ int active;
+ unsigned combo_count;
+ unsigned con_count, con_old;
+ unsigned active_con;
+ struct nk_rect header;
+};
+
+struct nk_edit_state {
+ nk_hash name;
+ unsigned int seq;
+ unsigned int old;
+ int active, prev;
+ int cursor;
+ int sel_start;
+ int sel_end;
+ struct nk_scroll scrollbar;
+ unsigned char mode;
+ unsigned char single_line;
+};
+
+struct nk_property_state {
+ int active, prev;
+ char buffer[NK_MAX_NUMBER_BUFFER];
+ int length;
+ int cursor;
+ int select_start;
+ int select_end;
+ nk_hash name;
+ unsigned int seq;
+ unsigned int old;
+ int state;
+};
+
+struct nk_window {
+ unsigned int seq;
+ nk_hash name;
+ char name_string[NK_WINDOW_MAX_NAME];
+ nk_flags flags;
+
+ struct nk_rect bounds;
+ struct nk_scroll scrollbar;
+ struct nk_command_buffer buffer;
+ struct nk_panel *layout;
+ float scrollbar_hiding_timer;
+
+ /* persistent widget state */
+ struct nk_property_state property;
+ struct nk_popup_state popup;
+ struct nk_edit_state edit;
+ unsigned int scrolled;
+
+ struct nk_table *tables;
+ unsigned int table_count;
+
+ /* window list hooks */
+ struct nk_window *next;
+ struct nk_window *prev;
+ struct nk_window *parent;
+};
+
+/*==============================================================
+ * STACK
+ * =============================================================*/
+/* The style modifier stack can be used to temporarily change a
+ * property inside `nk_style`. For example if you want a special
+ * red button you can temporarily push the old button color onto a stack
+ * draw the button with a red color and then you just pop the old color
+ * back from the stack:
+ *
+ * nk_style_push_style_item(ctx, &ctx->style.button.normal, nk_style_item_color(nk_rgb(255,0,0)));
+ * nk_style_push_style_item(ctx, &ctx->style.button.hover, nk_style_item_color(nk_rgb(255,0,0)));
+ * nk_style_push_style_item(ctx, &ctx->style.button.active, nk_style_item_color(nk_rgb(255,0,0)));
+ * nk_style_push_vec2(ctx, &cx->style.button.padding, nk_vec2(2,2));
+ *
+ * nk_button(...);
+ *
+ * nk_style_pop_style_item(ctx);
+ * nk_style_pop_style_item(ctx);
+ * nk_style_pop_style_item(ctx);
+ * nk_style_pop_vec2(ctx);
+ *
+ * Nuklear has a stack for style_items, float properties, vector properties,
+ * flags, colors, fonts and for button_behavior. Each has it's own fixed size stack
+ * which can be changed at compile time.
+ */
+#ifndef NK_BUTTON_BEHAVIOR_STACK_SIZE
+#define NK_BUTTON_BEHAVIOR_STACK_SIZE 8
+#endif
+
+#ifndef NK_FONT_STACK_SIZE
+#define NK_FONT_STACK_SIZE 8
+#endif
+
+#ifndef NK_STYLE_ITEM_STACK_SIZE
+#define NK_STYLE_ITEM_STACK_SIZE 16
+#endif
+
+#ifndef NK_FLOAT_STACK_SIZE
+#define NK_FLOAT_STACK_SIZE 32
+#endif
+
+#ifndef NK_VECTOR_STACK_SIZE
+#define NK_VECTOR_STACK_SIZE 16
+#endif
+
+#ifndef NK_FLAGS_STACK_SIZE
+#define NK_FLAGS_STACK_SIZE 32
+#endif
+
+#ifndef NK_COLOR_STACK_SIZE
+#define NK_COLOR_STACK_SIZE 32
+#endif
+
+#define NK_CONFIGURATION_STACK_TYPE(prefix, name, type)\
+ struct nk_config_stack_##name##_element {\
+ prefix##_##type *address;\
+ prefix##_##type old_value;\
+ }
+#define NK_CONFIG_STACK(type,size)\
+ struct nk_config_stack_##type {\
+ int head;\
+ struct nk_config_stack_##type##_element elements[size];\
+ }
+
+#define nk_float float
+NK_CONFIGURATION_STACK_TYPE(struct nk, style_item, style_item);
+NK_CONFIGURATION_STACK_TYPE(nk ,float, float);
+NK_CONFIGURATION_STACK_TYPE(struct nk, vec2, vec2);
+NK_CONFIGURATION_STACK_TYPE(nk ,flags, flags);
+NK_CONFIGURATION_STACK_TYPE(struct nk, color, color);
+NK_CONFIGURATION_STACK_TYPE(const struct nk, user_font, user_font*);
+NK_CONFIGURATION_STACK_TYPE(enum nk, button_behavior, button_behavior);
+
+NK_CONFIG_STACK(style_item, NK_STYLE_ITEM_STACK_SIZE);
+NK_CONFIG_STACK(float, NK_FLOAT_STACK_SIZE);
+NK_CONFIG_STACK(vec2, NK_VECTOR_STACK_SIZE);
+NK_CONFIG_STACK(flags, NK_FLAGS_STACK_SIZE);
+NK_CONFIG_STACK(color, NK_COLOR_STACK_SIZE);
+NK_CONFIG_STACK(user_font, NK_FONT_STACK_SIZE);
+NK_CONFIG_STACK(button_behavior, NK_BUTTON_BEHAVIOR_STACK_SIZE);
+
+struct nk_configuration_stacks {
+ struct nk_config_stack_style_item style_items;
+ struct nk_config_stack_float floats;
+ struct nk_config_stack_vec2 vectors;
+ struct nk_config_stack_flags flags;
+ struct nk_config_stack_color colors;
+ struct nk_config_stack_user_font fonts;
+ struct nk_config_stack_button_behavior button_behaviors;
+};
+
+/*==============================================================
+ * CONTEXT
+ * =============================================================*/
+#define NK_VALUE_PAGE_CAPACITY \
+ (((NK_MAX(sizeof(struct nk_window),sizeof(struct nk_panel)) / sizeof(nk_uint))) / 2)
+
+struct nk_table {
+ unsigned int seq;
+ unsigned int size;
+ nk_hash keys[NK_VALUE_PAGE_CAPACITY];
+ nk_uint values[NK_VALUE_PAGE_CAPACITY];
+ struct nk_table *next, *prev;
+};
+
+union nk_page_data {
+ struct nk_table tbl;
+ struct nk_panel pan;
+ struct nk_window win;
+};
+
+struct nk_page_element {
+ union nk_page_data data;
+ struct nk_page_element *next;
+ struct nk_page_element *prev;
+};
+
+struct nk_page {
+ unsigned int size;
+ struct nk_page *next;
+ struct nk_page_element win[1];
+};
+
+struct nk_pool {
+ struct nk_allocator alloc;
+ enum nk_allocation_type type;
+ unsigned int page_count;
+ struct nk_page *pages;
+ struct nk_page_element *freelist;
+ unsigned capacity;
+ nk_size size;
+ nk_size cap;
+};
+
+struct nk_context {
+/* public: can be accessed freely */
+ struct nk_input input;
+ struct nk_style style;
+ struct nk_buffer memory;
+ struct nk_clipboard clip;
+ nk_flags last_widget_state;
+ enum nk_button_behavior button_behavior;
+ struct nk_configuration_stacks stacks;
+ float delta_time_seconds;
+
+/* private:
+ should only be accessed if you
+ know what you are doing */
+#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+ struct nk_draw_list draw_list;
+#endif
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+ nk_handle userdata;
+#endif
+ /* text editor objects are quite big because of an internal
+ * undo/redo stack. Therefore it does not make sense to have one for
+ * each window for temporary use cases, so I only provide *one* instance
+ * for all windows. This works because the content is cleared anyway */
+ struct nk_text_edit text_edit;
+ /* draw buffer used for overlay drawing operation like cursor */
+ struct nk_command_buffer overlay;
+
+ /* windows */
+ int build;
+ int use_pool;
+ struct nk_pool pool;
+ struct nk_window *begin;
+ struct nk_window *end;
+ struct nk_window *active;
+ struct nk_window *current;
+ struct nk_page_element *freelist;
+ unsigned int count;
+ unsigned int seq;
+};
+
+/* ==============================================================
+ * MATH
+ * =============================================================== */
+#define NK_PI 3.141592654f
+#define NK_UTF_INVALID 0xFFFD
+#define NK_MAX_FLOAT_PRECISION 2
+
+#define NK_UNUSED(x) ((void)(x))
+#define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x)))
+#define NK_LEN(a) (sizeof(a)/sizeof(a)[0])
+#define NK_ABS(a) (((a) < 0) ? -(a) : (a))
+#define NK_BETWEEN(x, a, b) ((a) <= (x) && (x) < (b))
+#define NK_INBOX(px, py, x, y, w, h)\
+ (NK_BETWEEN(px,x,x+w) && NK_BETWEEN(py,y,y+h))
+#define NK_INTERSECT(x0, y0, w0, h0, x1, y1, w1, h1) \
+ (!(((x1 > (x0 + w0)) || ((x1 + w1) < x0) || (y1 > (y0 + h0)) || (y1 + h1) < y0)))
+#define NK_CONTAINS(x, y, w, h, bx, by, bw, bh)\
+ (NK_INBOX(x,y, bx, by, bw, bh) && NK_INBOX(x+w,y+h, bx, by, bw, bh))
+
+#define nk_vec2_sub(a, b) nk_vec2((a).x - (b).x, (a).y - (b).y)
+#define nk_vec2_add(a, b) nk_vec2((a).x + (b).x, (a).y + (b).y)
+#define nk_vec2_len_sqr(a) ((a).x*(a).x+(a).y*(a).y)
+#define nk_vec2_muls(a, t) nk_vec2((a).x * (t), (a).y * (t))
+
+#define nk_ptr_add(t, p, i) ((t*)((void*)((nk_byte*)(p) + (i))))
+#define nk_ptr_add_const(t, p, i) ((const t*)((const void*)((const nk_byte*)(p) + (i))))
+#define nk_zero_struct(s) nk_zero(&s, sizeof(s))
+
+/* ==============================================================
+ * ALIGNMENT
+ * =============================================================== */
+/* Pointer to Integer type conversion for pointer alignment */
+#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC*/
+# define NK_UINT_TO_PTR(x) ((void*)(__PTRDIFF_TYPE__)(x))
+# define NK_PTR_TO_UINT(x) ((nk_size)(__PTRDIFF_TYPE__)(x))
+#elif !defined(__GNUC__) /* works for compilers other than LLVM */
+# define NK_UINT_TO_PTR(x) ((void*)&((char*)0)[x])
+# define NK_PTR_TO_UINT(x) ((nk_size)(((char*)x)-(char*)0))
+#elif defined(NK_USE_FIXED_TYPES) /* used if we have <stdint.h> */
+# define NK_UINT_TO_PTR(x) ((void*)(uintptr_t)(x))
+# define NK_PTR_TO_UINT(x) ((uintptr_t)(x))
+#else /* generates warning but works */
+# define NK_UINT_TO_PTR(x) ((void*)(x))
+# define NK_PTR_TO_UINT(x) ((nk_size)(x))
+#endif
+
+#define NK_ALIGN_PTR(x, mask)\
+ (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x) + (mask-1)) & ~(mask-1))))
+#define NK_ALIGN_PTR_BACK(x, mask)\
+ (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte*)(x)) & ~(mask-1))))
+
+#define NK_OFFSETOF(st,m) ((nk_ptr)&(((st*)0)->m))
+#define NK_CONTAINER_OF(ptr,type,member)\
+ (type*)((void*)((char*)(1 ? (ptr): &((type*)0)->member) - NK_OFFSETOF(type, member)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef __cplusplus
+template<typename T> struct nk_alignof;
+template<typename T, int size_diff> struct nk_helper{enum {value = size_diff};};
+template<typename T> struct nk_helper<T,0>{enum {value = nk_alignof<T>::value};};
+template<typename T> struct nk_alignof{struct Big {T x; char c;}; enum {
+ diff = sizeof(Big) - sizeof(T), value = nk_helper<Big, diff>::value};};
+#define NK_ALIGNOF(t) (nk_alignof<t>::value)
+#elif defined(_MSC_VER)
+#define NK_ALIGNOF(t) (__alignof(t))
+#else
+#define NK_ALIGNOF(t) ((char*)(&((struct {char c; t _h;}*)0)->_h) - (char*)0)
+#endif
+
+#endif /* NK_NUKLEAR_H_ */
+/*
+ * ==============================================================
+ *
+ * IMPLEMENTATION
+ *
+ * ===============================================================
+ */
+#ifdef NK_IMPLEMENTATION
+
+#ifndef NK_POOL_DEFAULT_CAPACITY
+#define NK_POOL_DEFAULT_CAPACITY 16
+#endif
+
+#ifndef NK_DEFAULT_COMMAND_BUFFER_SIZE
+#define NK_DEFAULT_COMMAND_BUFFER_SIZE (4*1024)
+#endif
+
+#ifndef NK_BUFFER_DEFAULT_INITIAL_SIZE
+#define NK_BUFFER_DEFAULT_INITIAL_SIZE (4*1024)
+#endif
+
+/* standard library headers */
+#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
+#include <stdlib.h> /* malloc, free */
+#endif
+#ifdef NK_INCLUDE_STANDARD_IO
+#include <stdio.h> /* fopen, fclose,... */
+#endif
+#ifdef NK_INCLUDE_STANDARD_VARARGS
+#include <stdarg.h> /* valist, va_start, va_end, ... */
+#endif
+#ifndef NK_ASSERT
+#include <assert.h>
+#define NK_ASSERT(expr) assert(expr)
+#endif
+
+#ifndef NK_MEMSET
+#define NK_MEMSET nk_memset
+#endif
+#ifndef NK_MEMCPY
+#define NK_MEMCPY nk_memcopy
+#endif
+#ifndef NK_SQRT
+#define NK_SQRT nk_sqrt
+#endif
+#ifndef NK_SIN
+#define NK_SIN nk_sin
+#endif
+#ifndef NK_COS
+#define NK_COS nk_cos
+#endif
+#ifndef NK_STRTOD
+#define NK_STRTOD nk_strtod
+#endif
+#ifndef NK_DTOA
+#define NK_DTOA nk_dtoa
+#endif
+
+#define NK_DEFAULT (-1)
+
+#ifndef NK_VSNPRINTF
+/* If your compiler does support `vsnprintf` I would highly recommend
+ * defining this to vsnprintf instead since `vsprintf` is basically
+ * unbelievable unsafe and should *NEVER* be used. But I have to support
+ * it since C89 only provides this unsafe version. */
+ #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) ||\
+ (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
+ (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) ||\
+ (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) ||\
+ defined(_ISOC99_SOURCE) || defined(_BSD_SOURCE)
+ #define NK_VSNPRINTF(s,n,f,a) vsnprintf(s,n,f,a)
+ #else
+ #define NK_VSNPRINTF(s,n,f,a) vsprintf(s,f,a)
+ #endif
+#endif
+
+#define NK_SCHAR_MIN (-127)
+#define NK_SCHAR_MAX 127
+#define NK_UCHAR_MIN 0
+#define NK_UCHAR_MAX 256
+#define NK_SSHORT_MIN (-32767)
+#define NK_SSHORT_MAX 32767
+#define NK_USHORT_MIN 0
+#define NK_USHORT_MAX 65535
+#define NK_SINT_MIN (-2147483647)
+#define NK_SINT_MAX 2147483647
+#define NK_UINT_MIN 0
+#define NK_UINT_MAX 4294967295u
+
+/* Make sure correct type size:
+ * This will fire with a negative subscript error if the type sizes
+ * are set incorrectly by the compiler, and compile out if not */
+NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void*));
+NK_STATIC_ASSERT(sizeof(nk_ptr) == sizeof(void*));
+NK_STATIC_ASSERT(sizeof(nk_flags) >= 4);
+NK_STATIC_ASSERT(sizeof(nk_rune) >= 4);
+NK_STATIC_ASSERT(sizeof(nk_ushort) == 2);
+NK_STATIC_ASSERT(sizeof(nk_short) == 2);
+NK_STATIC_ASSERT(sizeof(nk_uint) == 4);
+NK_STATIC_ASSERT(sizeof(nk_int) == 4);
+NK_STATIC_ASSERT(sizeof(nk_byte) == 1);
+
+NK_GLOBAL const struct nk_rect nk_null_rect = {-8192.0f, -8192.0f, 16384, 16384};
+#define NK_FLOAT_PRECISION 0.00000000000001
+
+NK_GLOBAL const struct nk_color nk_red = {255,0,0,255};
+NK_GLOBAL const struct nk_color nk_green = {0,255,0,255};
+NK_GLOBAL const struct nk_color nk_blue = {0,0,255,255};
+NK_GLOBAL const struct nk_color nk_white = {255,255,255,255};
+NK_GLOBAL const struct nk_color nk_black = {0,0,0,255};
+NK_GLOBAL const struct nk_color nk_yellow = {255,255,0,255};
+
+/*
+ * ==============================================================
+ *
+ * MATH
+ *
+ * ===============================================================
+ */
+/* Since nuklear is supposed to work on all systems providing floating point
+ math without any dependencies I also had to implement my own math functions
+ for sqrt, sin and cos. Since the actual highly accurate implementations for
+ the standard library functions are quite complex and I do not need high
+ precision for my use cases I use approximations.
+
+ Sqrt
+ ----
+ For square root nuklear uses the famous fast inverse square root:
+ https://en.wikipedia.org/wiki/Fast_inverse_square_root with
+ slightly tweaked magic constant. While on today's hardware it is
+ probably not faster it is still fast and accurate enough for
+ nuklear's use cases. IMPORTANT: this requires float format IEEE 754
+
+ Sine/Cosine
+ -----------
+ All constants inside both function are generated Remez's minimax
+ approximations for value range 0...2*PI. The reason why I decided to
+ approximate exactly that range is that nuklear only needs sine and
+ cosine to generate circles which only requires that exact range.
+ In addition I used Remez instead of Taylor for additional precision:
+ www.lolengine.net/blog/2011/12/21/better-function-approximations.
+
+ The tool I used to generate constants for both sine and cosine
+ (it can actually approximate a lot more functions) can be
+ found here: www.lolengine.net/wiki/oss/lolremez
+*/
+NK_INTERN float
+nk_inv_sqrt(float number)
+{
+ float x2;
+ const float threehalfs = 1.5f;
+ union {nk_uint i; float f;} conv = {0};
+ conv.f = number;
+ x2 = number * 0.5f;
+ conv.i = 0x5f375A84 - (conv.i >> 1);
+ conv.f = conv.f * (threehalfs - (x2 * conv.f * conv.f));
+ return conv.f;
+}
+
+NK_INTERN float
+nk_sqrt(float x)
+{
+ return x * nk_inv_sqrt(x);
+}
+
+NK_INTERN float
+nk_sin(float x)
+{
+ NK_STORAGE const float a0 = +1.91059300966915117e-31f;
+ NK_STORAGE const float a1 = +1.00086760103908896f;
+ NK_STORAGE const float a2 = -1.21276126894734565e-2f;
+ NK_STORAGE const float a3 = -1.38078780785773762e-1f;
+ NK_STORAGE const float a4 = -2.67353392911981221e-2f;
+ NK_STORAGE const float a5 = +2.08026600266304389e-2f;
+ NK_STORAGE const float a6 = -3.03996055049204407e-3f;
+ NK_STORAGE const float a7 = +1.38235642404333740e-4f;
+ return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*a7))))));
+}
+
+NK_INTERN float
+nk_cos(float x)
+{
+ NK_STORAGE const float a0 = +1.00238601909309722f;
+ NK_STORAGE const float a1 = -3.81919947353040024e-2f;
+ NK_STORAGE const float a2 = -3.94382342128062756e-1f;
+ NK_STORAGE const float a3 = -1.18134036025221444e-1f;
+ NK_STORAGE const float a4 = +1.07123798512170878e-1f;
+ NK_STORAGE const float a5 = -1.86637164165180873e-2f;
+ NK_STORAGE const float a6 = +9.90140908664079833e-4f;
+ NK_STORAGE const float a7 = -5.23022132118824778e-14f;
+ return a0 + x*(a1 + x*(a2 + x*(a3 + x*(a4 + x*(a5 + x*(a6 + x*a7))))));
+}
+
+NK_INTERN nk_uint
+nk_round_up_pow2(nk_uint v)
+{
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ v++;
+ return v;
+}
+
+NK_API struct nk_rect
+nk_get_null_rect(void)
+{
+ return nk_null_rect;
+}
+
+NK_API struct nk_rect
+nk_rect(float x, float y, float w, float h)
+{
+ struct nk_rect r;
+ r.x = x; r.y = y;
+ r.w = w; r.h = h;
+ return r;
+}
+
+NK_API struct nk_rect
+nk_recti(int x, int y, int w, int h)
+{
+ struct nk_rect r;
+ r.x = (float)x;
+ r.y = (float)y;
+ r.w = (float)w;
+ r.h = (float)h;
+ return r;
+}
+
+NK_API struct nk_rect
+nk_recta(struct nk_vec2 pos, struct nk_vec2 size)
+{
+ return nk_rect(pos.x, pos.y, size.x, size.y);
+}
+
+NK_API struct nk_rect
+nk_rectv(const float *r)
+{
+ return nk_rect(r[0], r[1], r[2], r[3]);
+}
+
+NK_API struct nk_rect
+nk_rectiv(const int *r)
+{
+ return nk_recti(r[0], r[1], r[2], r[3]);
+}
+
+NK_API struct nk_vec2
+nk_rect_pos(struct nk_rect r)
+{
+ struct nk_vec2 ret;
+ ret.x = r.x; ret.y = r.y;
+ return ret;
+}
+
+NK_API struct nk_vec2
+nk_rect_size(struct nk_rect r)
+{
+ struct nk_vec2 ret;
+ ret.x = r.w; ret.y = r.h;
+ return ret;
+}
+
+NK_INTERN struct nk_rect
+nk_shrink_rect(struct nk_rect r, float amount)
+{
+ struct nk_rect res;
+ r.w = NK_MAX(r.w, 2 * amount);
+ r.h = NK_MAX(r.h, 2 * amount);
+ res.x = r.x + amount;
+ res.y = r.y + amount;
+ res.w = r.w - 2 * amount;
+ res.h = r.h - 2 * amount;
+ return res;
+}
+
+NK_INTERN struct nk_rect
+nk_pad_rect(struct nk_rect r, struct nk_vec2 pad)
+{
+ r.w = NK_MAX(r.w, 2 * pad.x);
+ r.h = NK_MAX(r.h, 2 * pad.y);
+ r.x += pad.x; r.y += pad.y;
+ r.w -= 2 * pad.x;
+ r.h -= 2 * pad.y;
+ return r;
+}
+
+NK_API struct nk_vec2
+nk_vec2(float x, float y)
+{
+ struct nk_vec2 ret;
+ ret.x = x; ret.y = y;
+ return ret;
+}
+
+NK_API struct nk_vec2
+nk_vec2i(int x, int y)
+{
+ struct nk_vec2 ret;
+ ret.x = (float)x;
+ ret.y = (float)y;
+ return ret;
+}
+
+NK_API struct nk_vec2
+nk_vec2v(const float *v)
+{
+ return nk_vec2(v[0], v[1]);
+}
+
+NK_API struct nk_vec2
+nk_vec2iv(const int *v)
+{
+ return nk_vec2i(v[0], v[1]);
+}
+
+/*
+ * ==============================================================
+ *
+ * UTIL
+ *
+ * ===============================================================
+ */
+NK_INTERN int nk_str_match_here(const char *regexp, const char *text);
+NK_INTERN int nk_str_match_star(int c, const char *regexp, const char *text);
+NK_INTERN int nk_is_lower(int c) {return (c >= 'a' && c <= 'z') || (c >= 0xE0 && c <= 0xFF);}
+NK_INTERN int nk_is_upper(int c){return (c >= 'A' && c <= 'Z') || (c >= 0xC0 && c <= 0xDF);}
+NK_INTERN int nk_to_upper(int c) {return (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c;}
+NK_INTERN int nk_to_lower(int c) {return (c >= 'A' && c <= 'Z') ? (c - ('a' + 'A')) : c;}
+
+NK_INTERN void*
+nk_memcopy(void *dst0, const void *src0, nk_size length)
+{
+ nk_ptr t;
+ char *dst = (char*)dst0;
+ const char *src = (const char*)src0;
+ if (length == 0 || dst == src)
+ goto done;
+
+ #define nk_word int
+ #define nk_wsize sizeof(nk_word)
+ #define nk_wmask (nk_wsize-1)
+ #define NK_TLOOP(s) if (t) NK_TLOOP1(s)
+ #define NK_TLOOP1(s) do { s; } while (--t)
+
+ if (dst < src) {
+ t = (nk_ptr)src; /* only need low bits */
+ if ((t | (nk_ptr)dst) & nk_wmask) {
+ if ((t ^ (nk_ptr)dst) & nk_wmask || length < nk_wsize)
+ t = length;
+ else
+ t = nk_wsize - (t & nk_wmask);
+ length -= t;
+ NK_TLOOP1(*dst++ = *src++);
+ }
+ t = length / nk_wsize;
+ NK_TLOOP(*(nk_word*)(void*)dst = *(const nk_word*)(const void*)src;
+ src += nk_wsize; dst += nk_wsize);
+ t = length & nk_wmask;
+ NK_TLOOP(*dst++ = *src++);
+ } else {
+ src += length;
+ dst += length;
+ t = (nk_ptr)src;
+ if ((t | (nk_ptr)dst) & nk_wmask) {
+ if ((t ^ (nk_ptr)dst) & nk_wmask || length <= nk_wsize)
+ t = length;
+ else
+ t &= nk_wmask;
+ length -= t;
+ NK_TLOOP1(*--dst = *--src);
+ }
+ t = length / nk_wsize;
+ NK_TLOOP(src -= nk_wsize; dst -= nk_wsize;
+ *(nk_word*)(void*)dst = *(const nk_word*)(const void*)src);
+ t = length & nk_wmask;
+ NK_TLOOP(*--dst = *--src);
+ }
+ #undef nk_word
+ #undef nk_wsize
+ #undef nk_wmask
+ #undef NK_TLOOP
+ #undef NK_TLOOP1
+done:
+ return (dst0);
+}
+
+NK_INTERN void
+nk_memset(void *ptr, int c0, nk_size size)
+{
+ #define nk_word unsigned
+ #define nk_wsize sizeof(nk_word)
+ #define nk_wmask (nk_wsize - 1)
+ nk_byte *dst = (nk_byte*)ptr;
+ unsigned c = 0;
+ nk_size t = 0;
+
+ if ((c = (nk_byte)c0) != 0) {
+ c = (c << 8) | c; /* at least 16-bits */
+ if (sizeof(unsigned int) > 2)
+ c = (c << 16) | c; /* at least 32-bits*/
+ }
+
+ /* too small of a word count */
+ dst = (nk_byte*)ptr;
+ if (size < 3 * nk_wsize) {
+ while (size--) *dst++ = (nk_byte)c0;
+ return;
+ }
+
+ /* align destination */
+ if ((t = NK_PTR_TO_UINT(dst) & nk_wmask) != 0) {
+ t = nk_wsize -t;
+ size -= t;
+ do {
+ *dst++ = (nk_byte)c0;
+ } while (--t != 0);
+ }
+
+ /* fill word */
+ t = size / nk_wsize;
+ do {
+ *(nk_word*)((void*)dst) = c;
+ dst += nk_wsize;
+ } while (--t != 0);
+
+ /* fill trailing bytes */
+ t = (size & nk_wmask);
+ if (t != 0) {
+ do {
+ *dst++ = (nk_byte)c0;
+ } while (--t != 0);
+ }
+
+ #undef nk_word
+ #undef nk_wsize
+ #undef nk_wmask
+}
+
+NK_INTERN void
+nk_zero(void *ptr, nk_size size)
+{
+ NK_ASSERT(ptr);
+ NK_MEMSET(ptr, 0, size);
+}
+
+NK_API int
+nk_strlen(const char *str)
+{
+ int siz = 0;
+ NK_ASSERT(str);
+ while (str && *str++ != '\0') siz++;
+ return siz;
+}
+
+NK_API int
+nk_strtoi(const char *str, const char **endptr)
+{
+ int neg = 1;
+ const char *p = str;
+ int value = 0;
+
+ NK_ASSERT(str);
+ if (!str) return 0;
+
+ /* skip whitespace */
+ while (*p == ' ') p++;
+ if (*p == '-') {
+ neg = -1;
+ p++;
+ }
+ while (*p && *p >= '0' && *p <= '9') {
+ value = value * 10 + (int) (*p - '0');
+ p++;
+ }
+ if (endptr)
+ *endptr = p;
+ return neg*value;
+}
+
+NK_API double
+nk_strtod(const char *str, const char **endptr)
+{
+ double m;
+ double neg = 1.0;
+ const char *p = str;
+ double value = 0;
+ double number = 0;
+
+ NK_ASSERT(str);
+ if (!str) return 0;
+
+ /* skip whitespace */
+ while (*p == ' ') p++;
+ if (*p == '-') {
+ neg = -1.0;
+ p++;
+ }
+
+ while (*p && *p != '.' && *p != 'e') {
+ value = value * 10.0 + (double) (*p - '0');
+ p++;
+ }
+
+ if (*p == '.') {
+ p++;
+ for(m = 0.1; *p && *p != 'e'; p++ ) {
+ value = value + (double) (*p - '0') * m;
+ m *= 0.1;
+ }
+ }
+ if (*p == 'e') {
+ int i, pow, div;
+ p++;
+ if (*p == '-') {
+ div = nk_true;
+ p++;
+ } else if (*p == '+') {
+ div = nk_false;
+ p++;
+ } else div = nk_false;
+
+ for (pow = 0; *p; p++)
+ pow = pow * 10 + (int) (*p - '0');
+
+ for (m = 1.0, i = 0; i < pow; i++)
+ m *= 10.0;
+
+ if (div)
+ value /= m;
+ else value *= m;
+ }
+ number = value * neg;
+ if (endptr)
+ *endptr = p;
+ return number;
+}
+
+NK_API float
+nk_strtof(const char *str, const char **endptr)
+{
+ float float_value;
+ double double_value;
+ double_value = NK_STRTOD(str, endptr);
+ float_value = (float)double_value;
+ return float_value;
+}
+
+NK_API int
+nk_stricmp(const char *s1, const char *s2)
+{
+ nk_int c1,c2,d;
+ do {
+ c1 = *s1++;
+ c2 = *s2++;
+ d = c1 - c2;
+ while (d) {
+ if (c1 <= 'Z' && c1 >= 'A') {
+ d += ('a' - 'A');
+ if (!d) break;
+ }
+ if (c2 <= 'Z' && c2 >= 'A') {
+ d -= ('a' - 'A');
+ if (!d) break;
+ }
+ return ((d >= 0) << 1) - 1;
+ }
+ } while (c1);
+ return 0;
+}
+
+NK_API int
+nk_stricmpn(const char *s1, const char *s2, int n)
+{
+ int c1,c2,d;
+ NK_ASSERT(n >= 0);
+ do {
+ c1 = *s1++;
+ c2 = *s2++;
+ if (!n--) return 0;
+
+ d = c1 - c2;
+ while (d) {
+ if (c1 <= 'Z' && c1 >= 'A') {
+ d += ('a' - 'A');
+ if (!d) break;
+ }
+ if (c2 <= 'Z' && c2 >= 'A') {
+ d -= ('a' - 'A');
+ if (!d) break;
+ }
+ return ((d >= 0) << 1) - 1;
+ }
+ } while (c1);
+ return 0;
+}
+
+NK_INTERN int
+nk_str_match_here(const char *regexp, const char *text)
+{
+ if (regexp[0] == '\0')
+ return 1;
+ if (regexp[1] == '*')
+ return nk_str_match_star(regexp[0], regexp+2, text);
+ if (regexp[0] == '$' && regexp[1] == '\0')
+ return *text == '\0';
+ if (*text!='\0' && (regexp[0]=='.' || regexp[0]==*text))
+ return nk_str_match_here(regexp+1, text+1);
+ return 0;
+}
+
+NK_INTERN int
+nk_str_match_star(int c, const char *regexp, const char *text)
+{
+ do {/* a '* matches zero or more instances */
+ if (nk_str_match_here(regexp, text))
+ return 1;
+ } while (*text != '\0' && (*text++ == c || c == '.'));
+ return 0;
+}
+
+NK_API int
+nk_strfilter(const char *text, const char *regexp)
+{
+ /*
+ c matches any literal character c
+ . matches any single character
+ ^ matches the beginning of the input string
+ $ matches the end of the input string
+ * matches zero or more occurrences of the previous character*/
+ if (regexp[0] == '^')
+ return nk_str_match_here(regexp+1, text);
+ do { /* must look even if string is empty */
+ if (nk_str_match_here(regexp, text))
+ return 1;
+ } while (*text++ != '\0');
+ return 0;
+}
+
+NK_API int
+nk_strmatch_fuzzy_text(const char *str, int str_len,
+ const char *pattern, int *out_score)
+{
+ /* Returns true if each character in pattern is found sequentially within str
+ * if found then out_score is also set. Score value has no intrinsic meaning.
+ * Range varies with pattern. Can only compare scores with same search pattern. */
+
+ /* bonus for adjacent matches */
+ #define NK_ADJACENCY_BONUS 5
+ /* bonus if match occurs after a separator */
+ #define NK_SEPARATOR_BONUS 10
+ /* bonus if match is uppercase and prev is lower */
+ #define NK_CAMEL_BONUS 10
+ /* penalty applied for every letter in str before the first match */
+ #define NK_LEADING_LETTER_PENALTY (-3)
+ /* maximum penalty for leading letters */
+ #define NK_MAX_LEADING_LETTER_PENALTY (-9)
+ /* penalty for every letter that doesn't matter */
+ #define NK_UNMATCHED_LETTER_PENALTY (-1)
+
+ /* loop variables */
+ int score = 0;
+ char const * pattern_iter = pattern;
+ int str_iter = 0;
+ int prev_matched = nk_false;
+ int prev_lower = nk_false;
+ /* true so if first letter match gets separator bonus*/
+ int prev_separator = nk_true;
+
+ /* use "best" matched letter if multiple string letters match the pattern */
+ char const * best_letter = 0;
+ int best_letter_score = 0;
+
+ /* loop over strings */
+ NK_ASSERT(str);
+ NK_ASSERT(pattern);
+ if (!str || !str_len || !pattern) return 0;
+ while (str_iter < str_len)
+ {
+ const char pattern_letter = *pattern_iter;
+ const char str_letter = str[str_iter];
+
+ int next_match = *pattern_iter != '\0' &&
+ nk_to_lower(pattern_letter) == nk_to_lower(str_letter);
+ int rematch = best_letter && nk_to_upper(*best_letter) == nk_to_upper(str_letter);
+
+ int advanced = next_match && best_letter;
+ int pattern_repeat = best_letter && *pattern_iter != '\0';
+ pattern_repeat = pattern_repeat &&
+ nk_to_lower(*best_letter) == nk_to_lower(pattern_letter);
+
+ if (advanced || pattern_repeat) {
+ score += best_letter_score;
+ best_letter = 0;
+ best_letter_score = 0;
+ }
+
+ if (next_match || rematch)
+ {
+ int new_score = 0;
+ /* Apply penalty for each letter before the first pattern match */
+ if (pattern_iter == pattern) {
+ int count = (int)(&str[str_iter] - str);
+ int penalty = NK_LEADING_LETTER_PENALTY * count;
+ if (penalty < NK_MAX_LEADING_LETTER_PENALTY)
+ penalty = NK_MAX_LEADING_LETTER_PENALTY;
+
+ score += penalty;
+ }
+
+ /* apply bonus for consecutive bonuses */
+ if (prev_matched)
+ new_score += NK_ADJACENCY_BONUS;
+
+ /* apply bonus for matches after a separator */
+ if (prev_separator)
+ new_score += NK_SEPARATOR_BONUS;
+
+ /* apply bonus across camel case boundaries */
+ if (prev_lower && nk_is_upper(str_letter))
+ new_score += NK_CAMEL_BONUS;
+
+ /* update pattern iter IFF the next pattern letter was matched */
+ if (next_match)
+ ++pattern_iter;
+
+ /* update best letter in str which may be for a "next" letter or a rematch */
+ if (new_score >= best_letter_score) {
+ /* apply penalty for now skipped letter */
+ if (best_letter != 0)
+ score += NK_UNMATCHED_LETTER_PENALTY;
+
+ best_letter = &str[str_iter];
+ best_letter_score = new_score;
+ }
+ prev_matched = nk_true;
+ } else {
+ score += NK_UNMATCHED_LETTER_PENALTY;
+ prev_matched = nk_false;
+ }
+
+ /* separators should be more easily defined */
+ prev_lower = nk_is_lower(str_letter) != 0;
+ prev_separator = str_letter == '_' || str_letter == ' ';
+
+ ++str_iter;
+ }
+
+ /* apply score for last match */
+ if (best_letter)
+ score += best_letter_score;
+
+ /* did not match full pattern */
+ if (*pattern_iter != '\0')
+ return nk_false;
+
+ if (out_score)
+ *out_score = score;
+ return nk_true;
+}
+
+NK_API int
+nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score)
+{return nk_strmatch_fuzzy_text(str, nk_strlen(str), pattern, out_score);}
+
+NK_INTERN int
+nk_string_float_limit(char *string, int prec)
+{
+ int dot = 0;
+ char *c = string;
+ while (*c) {
+ if (*c == '.') {
+ dot = 1;
+ c++;
+ continue;
+ }
+ if (dot == (prec+1)) {
+ *c = 0;
+ break;
+ }
+ if (dot > 0) dot++;
+ c++;
+ }
+ return (int)(c - string);
+}
+
+NK_INTERN double
+nk_pow(double x, int n)
+{
+ /* check the sign of n */
+ double r = 1;
+ int plus = n >= 0;
+ n = (plus) ? n : -n;
+ while (n > 0) {
+ if ((n & 1) == 1)
+ r *= x;
+ n /= 2;
+ x *= x;
+ }
+ return plus ? r : 1.0 / r;
+}
+
+NK_INTERN int
+nk_ifloord(double x)
+{
+ x = (double)((int)x - ((x < 0.0) ? 1 : 0));
+ return (int)x;
+}
+
+NK_INTERN int
+nk_ifloorf(float x)
+{
+ x = (float)((int)x - ((x < 0.0f) ? 1 : 0));
+ return (int)x;
+}
+
+NK_INTERN int
+nk_iceilf(float x)
+{
+ if (x >= 0) {
+ int i = (int)x;
+ return (x > i) ? i+1: i;
+ } else {
+ int t = (int)x;
+ float r = x - (float)t;
+ return (r > 0.0f) ? t+1: t;
+ }
+}
+
+NK_INTERN int
+nk_log10(double n)
+{
+ int neg;
+ int ret;
+ int exp = 0;
+
+ neg = (n < 0) ? 1 : 0;
+ ret = (neg) ? (int)-n : (int)n;
+ while ((ret / 10) > 0) {
+ ret /= 10;
+ exp++;
+ }
+ if (neg) exp = -exp;
+ return exp;
+}
+
+NK_INTERN void
+nk_strrev_ascii(char *s)
+{
+ int len = nk_strlen(s);
+ int end = len / 2;
+ int i = 0;
+ char t;
+ for (; i < end; ++i) {
+ t = s[i];
+ s[i] = s[len - 1 - i];
+ s[len -1 - i] = t;
+ }
+}
+
+NK_INTERN char*
+nk_itoa(char *s, long n)
+{
+ long i = 0;
+ if (n == 0) {
+ s[i++] = '0';
+ s[i] = 0;
+ return s;
+ }
+ if (n < 0) {
+ s[i++] = '-';
+ n = -n;
+ }
+ while (n > 0) {
+ s[i++] = (char)('0' + (n % 10));
+ n /= 10;
+ }
+ s[i] = 0;
+ if (s[0] == '-')
+ ++s;
+
+ nk_strrev_ascii(s);
+ return s;
+}
+
+NK_INTERN char*
+nk_dtoa(char *s, double n)
+{
+ int useExp = 0;
+ int digit = 0, m = 0, m1 = 0;
+ char *c = s;
+ int neg = 0;
+
+ NK_ASSERT(s);
+ if (!s) return 0;
+
+ if (n == 0.0) {
+ s[0] = '0'; s[1] = '\0';
+ return s;
+ }
+
+ neg = (n < 0);
+ if (neg) n = -n;
+
+ /* calculate magnitude */
+ m = nk_log10(n);
+ useExp = (m >= 14 || (neg && m >= 9) || m <= -9);
+ if (neg) *(c++) = '-';
+
+ /* set up for scientific notation */
+ if (useExp) {
+ if (m < 0)
+ m -= 1;
+ n = n / (double)nk_pow(10.0, m);
+ m1 = m;
+ m = 0;
+ }
+ if (m < 1.0) {
+ m = 0;
+ }
+
+ /* convert the number */
+ while (n > NK_FLOAT_PRECISION || m >= 0) {
+ double weight = nk_pow(10.0, m);
+ if (weight > 0) {
+ double t = (double)n / weight;
+ digit = nk_ifloord(t);
+ n -= ((double)digit * weight);
+ *(c++) = (char)('0' + (char)digit);
+ }
+ if (m == 0 && n > 0)
+ *(c++) = '.';
+ m--;
+ }
+
+ if (useExp) {
+ /* convert the exponent */
+ int i, j;
+ *(c++) = 'e';
+ if (m1 > 0) {
+ *(c++) = '+';
+ } else {
+ *(c++) = '-';
+ m1 = -m1;
+ }
+ m = 0;
+ while (m1 > 0) {
+ *(c++) = (char)('0' + (char)(m1 % 10));
+ m1 /= 10;
+ m++;
+ }
+ c -= m;
+ for (i = 0, j = m-1; i<j; i++, j--) {
+ /* swap without temporary */
+ c[i] ^= c[j];
+ c[j] ^= c[i];
+ c[i] ^= c[j];
+ }
+ c += m;
+ }
+ *(c) = '\0';
+ return s;
+}
+
+#ifdef NK_INCLUDE_STANDARD_VARARGS
+#ifndef NK_INCLUDE_STANDARD_IO
+static int
+nk_vsnprintf(char *buf, int buf_size, const char *fmt, va_list args)
+{
+ enum nk_arg_type {
+ NK_ARG_TYPE_CHAR,
+ NK_ARG_TYPE_SHORT,
+ NK_ARG_TYPE_DEFAULT,
+ NK_ARG_TYPE_LONG
+ };
+ enum nk_arg_flags {
+ NK_ARG_FLAG_LEFT = 0x01,
+ NK_ARG_FLAG_PLUS = 0x02,
+ NK_ARG_FLAG_SPACE = 0x04,
+ NK_ARG_FLAG_NUM = 0x10,
+ NK_ARG_FLAG_ZERO = 0x20
+ };
+
+ char number_buffer[NK_MAX_NUMBER_BUFFER];
+ enum nk_arg_type arg_type = NK_ARG_TYPE_DEFAULT;
+ int precision = NK_DEFAULT;
+ int width = NK_DEFAULT;
+ nk_flags flag = 0;
+
+ int len = 0;
+ int result = -1;
+ const char *iter = fmt;
+
+ NK_ASSERT(buf);
+ NK_ASSERT(buf_size);
+ if (!buf || !buf_size || !fmt) return 0;
+ for (iter = fmt; *iter && len < buf_size; iter++) {
+ /* copy all non-format characters */
+ while (*iter && (*iter != '%') && (len < buf_size))
+ buf[len++] = *iter++;
+ if (!(*iter) || len >= buf_size) break;
+ iter++;
+
+ /* flag arguments */
+ while (*iter) {
+ if (*iter == '-') flag |= NK_ARG_FLAG_LEFT;
+ else if (*iter == '+') flag |= NK_ARG_FLAG_PLUS;
+ else if (*iter == ' ') flag |= NK_ARG_FLAG_SPACE;
+ else if (*iter == '#') flag |= NK_ARG_FLAG_NUM;
+ else if (*iter == '0') flag |= NK_ARG_FLAG_ZERO;
+ else break;
+ iter++;
+ }
+
+ /* width argument */
+ width = NK_DEFAULT;
+ if (*iter >= '1' && *iter <= '9') {
+ const char *end;
+ width = nk_strtoi(iter, &end);
+ if (end == iter)
+ width = -1;
+ else iter = end;
+ } else if (*iter == '*') {
+ width = va_arg(args, int);
+ iter++;
+ }
+
+ /* precision argument */
+ precision = NK_DEFAULT;
+ if (*iter == '.') {
+ iter++;
+ if (*iter == '*') {
+ precision = va_arg(args, int);
+ iter++;
+ } else {
+ const char *end;
+ precision = nk_strtoi(iter, &end);
+ if (end == iter)
+ precision = -1;
+ else iter = end;
+ }
+ }
+
+ /* length modifier */
+ if (*iter == 'h') {
+ if (*(iter+1) == 'h') {
+ arg_type = NK_ARG_TYPE_CHAR;
+ iter++;
+ } else arg_type = NK_ARG_TYPE_SHORT;
+ iter++;
+ } else if (*iter == 'l') {
+ arg_type = NK_ARG_TYPE_LONG;
+ iter++;
+ } else arg_type = NK_ARG_TYPE_DEFAULT;
+
+ /* specifier */
+ if (*iter == '%') {
+ NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
+ NK_ASSERT(precision == NK_DEFAULT);
+ NK_ASSERT(width == NK_DEFAULT);
+ if (len < buf_size)
+ buf[len++] = '%';
+ } else if (*iter == 's') {
+ /* string */
+ const char *str = va_arg(args, const char*);
+ NK_ASSERT(str != buf && "buffer and argument are not allowed to overlap!");
+ NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
+ NK_ASSERT(precision == NK_DEFAULT);
+ NK_ASSERT(width == NK_DEFAULT);
+ if (str == buf) return -1;
+ while (str && *str && len < buf_size)
+ buf[len++] = *str++;
+ } else if (*iter == 'n') {
+ /* current length callback */
+ signed int *n = va_arg(args, int*);
+ NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
+ NK_ASSERT(precision == NK_DEFAULT);
+ NK_ASSERT(width == NK_DEFAULT);
+ if (n) *n = len;
+ } else if (*iter == 'c' || *iter == 'i' || *iter == 'd') {
+ /* signed integer */
+ long value = 0;
+ const char *num_iter;
+ int num_len, num_print, padding;
+ int cur_precision = NK_MAX(precision, 1);
+ int cur_width = NK_MAX(width, 0);
+
+ /* retrieve correct value type */
+ if (arg_type == NK_ARG_TYPE_CHAR)
+ value = (signed char)va_arg(args, int);
+ else if (arg_type == NK_ARG_TYPE_SHORT)
+ value = (signed short)va_arg(args, int);
+ else if (arg_type == NK_ARG_TYPE_LONG)
+ value = va_arg(args, signed long);
+ else if (*iter == 'c')
+ value = (unsigned char)va_arg(args, int);
+ else value = va_arg(args, signed int);
+
+ /* convert number to string */
+ nk_itoa(number_buffer, value);
+ num_len = nk_strlen(number_buffer);
+ padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0);
+ if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
+ padding = NK_MAX(padding-1, 0);
+
+ /* fill left padding up to a total of `width` characters */
+ if (!(flag & NK_ARG_FLAG_LEFT)) {
+ while (padding-- > 0 && (len < buf_size)) {
+ if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
+ buf[len++] = '0';
+ else buf[len++] = ' ';
+ }
+ }
+
+ /* copy string value representation into buffer */
+ if ((flag & NK_ARG_FLAG_PLUS) && value >= 0 && len < buf_size)
+ buf[len++] = '+';
+ else if ((flag & NK_ARG_FLAG_SPACE) && value >= 0 && len < buf_size)
+ buf[len++] = ' ';
+
+ /* fill up to precision number of digits with '0' */
+ num_print = NK_MAX(cur_precision, num_len);
+ while (precision && (num_print > num_len) && (len < buf_size)) {
+ buf[len++] = '0';
+ num_print--;
+ }
+
+ /* copy string value representation into buffer */
+ num_iter = number_buffer;
+ while (precision && *num_iter && len < buf_size)
+ buf[len++] = *num_iter++;
+
+ /* fill right padding up to width characters */
+ if (flag & NK_ARG_FLAG_LEFT) {
+ while ((padding-- > 0) && (len < buf_size))
+ buf[len++] = ' ';
+ }
+ } else if (*iter == 'o' || *iter == 'x' || *iter == 'X' || *iter == 'u') {
+ /* unsigned integer */
+ unsigned long value = 0;
+ int num_len = 0, num_print, padding = 0;
+ int cur_precision = NK_MAX(precision, 1);
+ int cur_width = NK_MAX(width, 0);
+ unsigned int base = (*iter == 'o') ? 8: (*iter == 'u')? 10: 16;
+
+ /* print oct/hex/dec value */
+ const char *upper_output_format = "0123456789ABCDEF";
+ const char *lower_output_format = "0123456789abcdef";
+ const char *output_format = (*iter == 'x') ?
+ lower_output_format: upper_output_format;
+
+ /* retrieve correct value type */
+ if (arg_type == NK_ARG_TYPE_CHAR)
+ value = (unsigned char)va_arg(args, int);
+ else if (arg_type == NK_ARG_TYPE_SHORT)
+ value = (unsigned short)va_arg(args, int);
+ else if (arg_type == NK_ARG_TYPE_LONG)
+ value = va_arg(args, unsigned long);
+ else value = va_arg(args, unsigned int);
+
+ do {
+ /* convert decimal number into hex/oct number */
+ int digit = output_format[value % base];
+ if (num_len < NK_MAX_NUMBER_BUFFER)
+ number_buffer[num_len++] = (char)digit;
+ value /= base;
+ } while (value > 0);
+
+ num_print = NK_MAX(cur_precision, num_len);
+ padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0);
+ if (flag & NK_ARG_FLAG_NUM)
+ padding = NK_MAX(padding-1, 0);
+
+ /* fill left padding up to a total of `width` characters */
+ if (!(flag & NK_ARG_FLAG_LEFT)) {
+ while ((padding-- > 0) && (len < buf_size)) {
+ if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT))
+ buf[len++] = '0';
+ else buf[len++] = ' ';
+ }
+ }
+
+ /* fill up to precision number of digits */
+ if (num_print && (flag & NK_ARG_FLAG_NUM)) {
+ if ((*iter == 'o') && (len < buf_size)) {
+ buf[len++] = '0';
+ } else if ((*iter == 'x') && ((len+1) < buf_size)) {
+ buf[len++] = '0';
+ buf[len++] = 'x';
+ } else if ((*iter == 'X') && ((len+1) < buf_size)) {
+ buf[len++] = '0';
+ buf[len++] = 'X';
+ }
+ }
+ while (precision && (num_print > num_len) && (len < buf_size)) {
+ buf[len++] = '0';
+ num_print--;
+ }
+
+ /* reverse number direction */
+ while (num_len > 0) {
+ if (precision && (len < buf_size))
+ buf[len++] = number_buffer[num_len-1];
+ num_len--;
+ }
+
+ /* fill right padding up to width characters */
+ if (flag & NK_ARG_FLAG_LEFT) {
+ while ((padding-- > 0) && (len < buf_size))
+ buf[len++] = ' ';
+ }
+ } else if (*iter == 'f') {
+ /* floating point */
+ const char *num_iter;
+ int cur_precision = (precision < 0) ? 6: precision;
+ int prefix, cur_width = NK_MAX(width, 0);
+ double value = va_arg(args, double);
+ int num_len = 0, frac_len = 0, dot = 0;
+ int padding = 0;
+
+ NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT);
+ NK_DTOA(number_buffer, value);
+ num_len = nk_strlen(number_buffer);
+
+ /* calculate padding */
+ num_iter = number_buffer;
+ while (*num_iter && *num_iter != '.')
+ num_iter++;
+
+ prefix = (*num_iter == '.')?(int)(num_iter - number_buffer)+1:0;
+ padding = NK_MAX(cur_width - (prefix + NK_MIN(cur_precision, num_len - prefix)) , 0);
+ if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE))
+ padding = NK_MAX(padding-1, 0);
+
+ /* fill left padding up to a total of `width` characters */
+ if (!(flag & NK_ARG_FLAG_LEFT)) {
+ while (padding-- > 0 && (len < buf_size)) {
+ if (flag & NK_ARG_FLAG_ZERO)
+ buf[len++] = '0';
+ else buf[len++] = ' ';
+ }
+ }
+
+ /* copy string value representation into buffer */
+ num_iter = number_buffer;
+ if ((flag & NK_ARG_FLAG_PLUS) && (value >= 0) && (len < buf_size))
+ buf[len++] = '+';
+ else if ((flag & NK_ARG_FLAG_SPACE) && (value >= 0) && (len < buf_size))
+ buf[len++] = ' ';
+ while (*num_iter) {
+ if (dot) frac_len++;
+ if (len < buf_size)
+ buf[len++] = *num_iter;
+ if (*num_iter == '.') dot = 1;
+ if (frac_len >= cur_precision) break;
+ num_iter++;
+ }
+
+ /* fill number up to precision */
+ while (frac_len < cur_precision) {
+ if (!dot && len < buf_size) {
+ buf[len++] = '.';
+ dot = 1;
+ }
+ if (len < buf_size)
+ buf[len++] = '0';
+ frac_len++;
+ }
+
+ /* fill right padding up to width characters */
+ if (flag & NK_ARG_FLAG_LEFT) {
+ while ((padding-- > 0) && (len < buf_size))
+ buf[len++] = ' ';
+ }
+ } else {
+ /* Specifier not supported: g,G,e,E,p,z */
+ NK_ASSERT(0 && "specifier is not supported!");
+ return result;
+ }
+ }
+ buf[(len >= buf_size)?(buf_size-1):len] = 0;
+ result = (len >= buf_size)?-1:len;
+ return result;
+}
+#endif
+
+NK_INTERN int
+nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args)
+{
+ int result = -1;
+ NK_ASSERT(buf);
+ NK_ASSERT(buf_size);
+ if (!buf || !buf_size || !fmt) return 0;
+#ifdef NK_INCLUDE_STANDARD_IO
+ result = NK_VSNPRINTF(buf, (nk_size)buf_size, fmt, args);
+ result = (result >= buf_size) ? -1: result;
+ buf[buf_size-1] = 0;
+#else
+ result = nk_vsnprintf(buf, buf_size, fmt, args);
+#endif
+ return result;
+}
+#endif
+
+NK_API nk_hash
+nk_murmur_hash(const void * key, int len, nk_hash seed)
+{
+ /* 32-Bit MurmurHash3: https://code.google.com/p/smhasher/wiki/MurmurHash3*/
+ #define NK_ROTL(x,r) ((x) << (r) | ((x) >> (32 - r)))
+ union {const nk_uint *i; const nk_byte *b;} conv = {0};
+ const nk_byte *data = (const nk_byte*)key;
+ const int nblocks = len/4;
+ nk_uint h1 = seed;
+ const nk_uint c1 = 0xcc9e2d51;
+ const nk_uint c2 = 0x1b873593;
+ const nk_byte *tail;
+ const nk_uint *blocks;
+ nk_uint k1;
+ int i;
+
+ /* body */
+ if (!key) return 0;
+ conv.b = (data + nblocks*4);
+ blocks = (const nk_uint*)conv.i;
+ for (i = -nblocks; i; ++i) {
+ k1 = blocks[i];
+ k1 *= c1;
+ k1 = NK_ROTL(k1,15);
+ k1 *= c2;
+
+ h1 ^= k1;
+ h1 = NK_ROTL(h1,13);
+ h1 = h1*5+0xe6546b64;
+ }
+
+ /* tail */
+ tail = (const nk_byte*)(data + nblocks*4);
+ k1 = 0;
+ switch (len & 3) {
+ case 3: k1 ^= (nk_uint)(tail[2] << 16); /* fallthrough */
+ case 2: k1 ^= (nk_uint)(tail[1] << 8u); /* fallthrough */
+ case 1: k1 ^= tail[0];
+ k1 *= c1;
+ k1 = NK_ROTL(k1,15);
+ k1 *= c2;
+ h1 ^= k1;
+ break;
+ default: break;
+ }
+
+ /* finalization */
+ h1 ^= (nk_uint)len;
+ /* fmix32 */
+ h1 ^= h1 >> 16;
+ h1 *= 0x85ebca6b;
+ h1 ^= h1 >> 13;
+ h1 *= 0xc2b2ae35;
+ h1 ^= h1 >> 16;
+
+ #undef NK_ROTL
+ return h1;
+}
+
+#ifdef NK_INCLUDE_STANDARD_IO
+NK_INTERN char*
+nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc)
+{
+ char *buf;
+ FILE *fd;
+ long ret;
+
+ NK_ASSERT(path);
+ NK_ASSERT(siz);
+ NK_ASSERT(alloc);
+ if (!path || !siz || !alloc)
+ return 0;
+
+ fd = fopen(path, "rb");
+ if (!fd) return 0;
+ fseek(fd, 0, SEEK_END);
+ ret = ftell(fd);
+ if (ret < 0) {
+ fclose(fd);
+ return 0;
+ }
+ *siz = (nk_size)ret;
+ fseek(fd, 0, SEEK_SET);
+ buf = (char*)alloc->alloc(alloc->userdata,0, *siz);
+ NK_ASSERT(buf);
+ if (!buf) {
+ fclose(fd);
+ return 0;
+ }
+ *siz = (nk_size)fread(buf, 1,*siz, fd);
+ fclose(fd);
+ return buf;
+}
+#endif
+
+/*
+ * ==============================================================
+ *
+ * COLOR
+ *
+ * ===============================================================
+ */
+NK_INTERN int
+nk_parse_hex(const char *p, int length)
+{
+ int i = 0;
+ int len = 0;
+ while (len < length) {
+ i <<= 4;
+ if (p[len] >= 'a' && p[len] <= 'f')
+ i += ((p[len] - 'a') + 10);
+ else if (p[len] >= 'A' && p[len] <= 'F')
+ i += ((p[len] - 'A') + 10);
+ else i += (p[len] - '0');
+ len++;
+ }
+ return i;
+}
+
+NK_API struct nk_color
+nk_rgba(int r, int g, int b, int a)
+{
+ struct nk_color ret;
+ ret.r = (nk_byte)NK_CLAMP(0, r, 255);
+ ret.g = (nk_byte)NK_CLAMP(0, g, 255);
+ ret.b = (nk_byte)NK_CLAMP(0, b, 255);
+ ret.a = (nk_byte)NK_CLAMP(0, a, 255);
+ return ret;
+}
+
+NK_API struct nk_color
+nk_rgb_hex(const char *rgb)
+{
+ struct nk_color col;
+ const char *c = rgb;
+ if (*c == '#') c++;
+ col.r = (nk_byte)nk_parse_hex(c, 2);
+ col.g = (nk_byte)nk_parse_hex(c+2, 2);
+ col.b = (nk_byte)nk_parse_hex(c+4, 2);
+ col.a = 255;
+ return col;
+}
+
+NK_API struct nk_color
+nk_rgba_hex(const char *rgb)
+{
+ struct nk_color col;
+ const char *c = rgb;
+ if (*c == '#') c++;
+ col.r = (nk_byte)nk_parse_hex(c, 2);
+ col.g = (nk_byte)nk_parse_hex(c+2, 2);
+ col.b = (nk_byte)nk_parse_hex(c+4, 2);
+ col.a = (nk_byte)nk_parse_hex(c+6, 2);
+ return col;
+}
+
+NK_API void
+nk_color_hex_rgba(char *output, struct nk_color col)
+{
+ #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
+ output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4);
+ output[1] = (char)NK_TO_HEX((col.r & 0x0F));
+ output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4);
+ output[3] = (char)NK_TO_HEX((col.g & 0x0F));
+ output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4);
+ output[5] = (char)NK_TO_HEX((col.b & 0x0F));
+ output[6] = (char)NK_TO_HEX((col.a & 0xF0) >> 4);
+ output[7] = (char)NK_TO_HEX((col.a & 0x0F));
+ output[8] = '\0';
+ #undef NK_TO_HEX
+}
+
+NK_API void
+nk_color_hex_rgb(char *output, struct nk_color col)
+{
+ #define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i): 'A' - 10 + (i))
+ output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4);
+ output[1] = (char)NK_TO_HEX((col.r & 0x0F));
+ output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4);
+ output[3] = (char)NK_TO_HEX((col.g & 0x0F));
+ output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4);
+ output[5] = (char)NK_TO_HEX((col.b & 0x0F));
+ output[6] = '\0';
+ #undef NK_TO_HEX
+}
+
+NK_API struct nk_color
+nk_rgba_iv(const int *c)
+{
+ return nk_rgba(c[0], c[1], c[2], c[3]);
+}
+
+NK_API struct nk_color
+nk_rgba_bv(const nk_byte *c)
+{
+ return nk_rgba(c[0], c[1], c[2], c[3]);
+}
+
+NK_API struct nk_color
+nk_rgb(int r, int g, int b)
+{
+ struct nk_color ret;
+ ret.r = (nk_byte)NK_CLAMP(0, r, 255);
+ ret.g = (nk_byte)NK_CLAMP(0, g, 255);
+ ret.b = (nk_byte)NK_CLAMP(0, b, 255);
+ ret.a = (nk_byte)255;
+ return ret;
+}
+
+NK_API struct nk_color
+nk_rgb_iv(const int *c)
+{
+ return nk_rgb(c[0], c[1], c[2]);
+}
+
+NK_API struct nk_color
+nk_rgb_bv(const nk_byte* c)
+{
+ return nk_rgb(c[0], c[1], c[2]);
+}
+
+NK_API struct nk_color
+nk_rgba_u32(nk_uint in)
+{
+ struct nk_color ret;
+ ret.r = (in & 0xFF);
+ ret.g = ((in >> 8) & 0xFF);
+ ret.b = ((in >> 16) & 0xFF);
+ ret.a = (nk_byte)((in >> 24) & 0xFF);
+ return ret;
+}
+
+NK_API struct nk_color
+nk_rgba_f(float r, float g, float b, float a)
+{
+ struct nk_color ret;
+ ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f);
+ ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f);
+ ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f);
+ ret.a = (nk_byte)(NK_SATURATE(a) * 255.0f);
+ return ret;
+}
+
+NK_API struct nk_color
+nk_rgba_fv(const float *c)
+{
+ return nk_rgba_f(c[0], c[1], c[2], c[3]);
+}
+
+NK_API struct nk_color
+nk_rgba_cf(struct nk_colorf c)
+{
+ return nk_rgba_f(c.r, c.g, c.b, c.a);
+}
+
+NK_API struct nk_color
+nk_rgb_f(float r, float g, float b)
+{
+ struct nk_color ret;
+ ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f);
+ ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f);
+ ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f);
+ ret.a = 255;
+ return ret;
+}
+
+NK_API struct nk_color
+nk_rgb_fv(const float *c)
+{
+ return nk_rgb_f(c[0], c[1], c[2]);
+}
+
+NK_API struct nk_color
+nk_rgb_cf(struct nk_colorf c)
+{
+ return nk_rgb_f(c.r, c.g, c.b);
+}
+
+NK_API struct nk_color
+nk_hsv(int h, int s, int v)
+{
+ return nk_hsva(h, s, v, 255);
+}
+
+NK_API struct nk_color
+nk_hsv_iv(const int *c)
+{
+ return nk_hsv(c[0], c[1], c[2]);
+}
+
+NK_API struct nk_color
+nk_hsv_bv(const nk_byte *c)
+{
+ return nk_hsv(c[0], c[1], c[2]);
+}
+
+NK_API struct nk_color
+nk_hsv_f(float h, float s, float v)
+{
+ return nk_hsva_f(h, s, v, 1.0f);
+}
+
+NK_API struct nk_color
+nk_hsv_fv(const float *c)
+{
+ return nk_hsv_f(c[0], c[1], c[2]);
+}
+
+NK_API struct nk_color
+nk_hsva(int h, int s, int v, int a)
+{
+ float hf = ((float)NK_CLAMP(0, h, 255)) / 255.0f;
+ float sf = ((float)NK_CLAMP(0, s, 255)) / 255.0f;
+ float vf = ((float)NK_CLAMP(0, v, 255)) / 255.0f;
+ float af = ((float)NK_CLAMP(0, a, 255)) / 255.0f;
+ return nk_hsva_f(hf, sf, vf, af);
+}
+
+NK_API struct nk_color
+nk_hsva_iv(const int *c)
+{
+ return nk_hsva(c[0], c[1], c[2], c[3]);
+}
+
+NK_API struct nk_color
+nk_hsva_bv(const nk_byte *c)
+{
+ return nk_hsva(c[0], c[1], c[2], c[3]);
+}
+
+NK_API struct nk_colorf
+nk_hsva_colorf(float h, float s, float v, float a)
+{
+ int i;
+ float p, q, t, f;
+ struct nk_colorf out = {0,0,0,0};
+ if (s <= 0.0f) {
+ out.r = v; out.g = v; out.b = v; out.a = a;
+ return out;
+ }
+ h = h / (60.0f/360.0f);
+ i = (int)h;
+ f = h - (float)i;
+ p = v * (1.0f - s);
+ q = v * (1.0f - (s * f));
+ t = v * (1.0f - s * (1.0f - f));
+
+ switch (i) {
+ case 0: default: out.r = v; out.g = t; out.b = p; break;
+ case 1: out.r = q; out.g = v; out.b = p; break;
+ case 2: out.r = p; out.g = v; out.b = t; break;
+ case 3: out.r = p; out.g = q; out.b = v; break;
+ case 4: out.r = t; out.g = p; out.b = v; break;
+ case 5: out.r = v; out.g = p; out.b = q; break;}
+ out.a = a;
+ return out;
+}
+
+NK_API struct nk_colorf
+nk_hsva_colorfv(float *c)
+{
+ return nk_hsva_colorf(c[0], c[1], c[2], c[3]);
+}
+
+NK_API struct nk_color
+nk_hsva_f(float h, float s, float v, float a)
+{
+ struct nk_colorf c = nk_hsva_colorf(h, s, v, a);
+ return nk_rgba_f(c.r, c.g, c.b, c.a);
+}
+
+NK_API struct nk_color
+nk_hsva_fv(const float *c)
+{
+ return nk_hsva_f(c[0], c[1], c[2], c[3]);
+}
+
+NK_API nk_uint
+nk_color_u32(struct nk_color in)
+{
+ nk_uint out = (nk_uint)in.r;
+ out |= ((nk_uint)in.g << 8);
+ out |= ((nk_uint)in.b << 16);
+ out |= ((nk_uint)in.a << 24);
+ return out;
+}
+
+NK_API void
+nk_color_f(float *r, float *g, float *b, float *a, struct nk_color in)
+{
+ NK_STORAGE const float s = 1.0f/255.0f;
+ *r = (float)in.r * s;
+ *g = (float)in.g * s;
+ *b = (float)in.b * s;
+ *a = (float)in.a * s;
+}
+
+NK_API void
+nk_color_fv(float *c, struct nk_color in)
+{
+ nk_color_f(&c[0], &c[1], &c[2], &c[3], in);
+}
+
+NK_API struct nk_colorf
+nk_color_cf(struct nk_color in)
+{
+ struct nk_colorf o;
+ nk_color_f(&o.r, &o.g, &o.b, &o.a, in);
+ return o;
+}
+
+NK_API void
+nk_color_d(double *r, double *g, double *b, double *a, struct nk_color in)
+{
+ NK_STORAGE const double s = 1.0/255.0;
+ *r = (double)in.r * s;
+ *g = (double)in.g * s;
+ *b = (double)in.b * s;
+ *a = (double)in.a * s;
+}
+
+NK_API void
+nk_color_dv(double *c, struct nk_color in)
+{
+ nk_color_d(&c[0], &c[1], &c[2], &c[3], in);
+}
+
+NK_API void
+nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color in)
+{
+ float a;
+ nk_color_hsva_f(out_h, out_s, out_v, &a, in);
+}
+
+NK_API void
+nk_color_hsv_fv(float *out, struct nk_color in)
+{
+ float a;
+ nk_color_hsva_f(&out[0], &out[1], &out[2], &a, in);
+}
+
+NK_API void
+nk_colorf_hsva_f(float *out_h, float *out_s,
+ float *out_v, float *out_a, struct nk_colorf in)
+{
+ float chroma;
+ float K = 0.0f;
+ if (in.g < in.b) {
+ const float t = in.g; in.g = in.b; in.b = t;
+ K = -1.f;
+ }
+ if (in.r < in.g) {
+ const float t = in.r; in.r = in.g; in.g = t;
+ K = -2.f/6.0f - K;
+ }
+ chroma = in.r - ((in.g < in.b) ? in.g: in.b);
+ *out_h = NK_ABS(K + (in.g - in.b)/(6.0f * chroma + 1e-20f));
+ *out_s = chroma / (in.r + 1e-20f);
+ *out_v = in.r;
+ *out_a = in.a;
+
+}
+
+NK_API void
+nk_colorf_hsva_fv(float *hsva, struct nk_colorf in)
+{
+ nk_colorf_hsva_f(&hsva[0], &hsva[1], &hsva[2], &hsva[3], in);
+}
+NK_API void
+nk_color_hsva_f(float *out_h, float *out_s,
+ float *out_v, float *out_a, struct nk_color in)
+{
+ struct nk_colorf col;
+ nk_color_f(&col.r,&col.g,&col.b,&col.a, in);
+ nk_colorf_hsva_f(out_h, out_s, out_v, out_a, col);
+}
+
+NK_API void
+nk_color_hsva_fv(float *out, struct nk_color in)
+{
+ nk_color_hsva_f(&out[0], &out[1], &out[2], &out[3], in);
+}
+
+NK_API void
+nk_color_hsva_i(int *out_h, int *out_s, int *out_v,
+ int *out_a, struct nk_color in)
+{
+ float h,s,v,a;
+ nk_color_hsva_f(&h, &s, &v, &a, in);
+ *out_h = (nk_byte)(h * 255.0f);
+ *out_s = (nk_byte)(s * 255.0f);
+ *out_v = (nk_byte)(v * 255.0f);
+ *out_a = (nk_byte)(a * 255.0f);
+}
+
+NK_API void
+nk_color_hsva_iv(int *out, struct nk_color in)
+{
+ nk_color_hsva_i(&out[0], &out[1], &out[2], &out[3], in);
+}
+
+NK_API void
+nk_color_hsva_bv(nk_byte *out, struct nk_color in)
+{
+ int tmp[4];
+ nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
+ out[0] = (nk_byte)tmp[0];
+ out[1] = (nk_byte)tmp[1];
+ out[2] = (nk_byte)tmp[2];
+ out[3] = (nk_byte)tmp[3];
+}
+
+NK_API void
+nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color in)
+{
+ int tmp[4];
+ nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
+ *h = (nk_byte)tmp[0];
+ *s = (nk_byte)tmp[1];
+ *v = (nk_byte)tmp[2];
+ *a = (nk_byte)tmp[3];
+}
+
+NK_API void
+nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color in)
+{
+ int a;
+ nk_color_hsva_i(out_h, out_s, out_v, &a, in);
+}
+
+NK_API void
+nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color in)
+{
+ int tmp[4];
+ nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in);
+ *out_h = (nk_byte)tmp[0];
+ *out_s = (nk_byte)tmp[1];
+ *out_v = (nk_byte)tmp[2];
+}
+
+NK_API void
+nk_color_hsv_iv(int *out, struct nk_color in)
+{
+ nk_color_hsv_i(&out[0], &out[1], &out[2], in);
+}
+
+NK_API void
+nk_color_hsv_bv(nk_byte *out, struct nk_color in)
+{
+ int tmp[4];
+ nk_color_hsv_i(&tmp[0], &tmp[1], &tmp[2], in);
+ out[0] = (nk_byte)tmp[0];
+ out[1] = (nk_byte)tmp[1];
+ out[2] = (nk_byte)tmp[2];
+}
+/*
+ * ==============================================================
+ *
+ * IMAGE
+ *
+ * ===============================================================
+ */
+NK_API nk_handle
+nk_handle_ptr(void *ptr)
+{
+ nk_handle handle = {0};
+ handle.ptr = ptr;
+ return handle;
+}
+
+NK_API nk_handle
+nk_handle_id(int id)
+{
+ nk_handle handle;
+ nk_zero_struct(handle);
+ handle.id = id;
+ return handle;
+}
+
+NK_API struct nk_image
+nk_subimage_ptr(void *ptr, unsigned short w, unsigned short h, struct nk_rect r)
+{
+ struct nk_image s;
+ nk_zero(&s, sizeof(s));
+ s.handle.ptr = ptr;
+ s.w = w; s.h = h;
+ s.region[0] = (unsigned short)r.x;
+ s.region[1] = (unsigned short)r.y;
+ s.region[2] = (unsigned short)r.w;
+ s.region[3] = (unsigned short)r.h;
+ return s;
+}
+
+NK_API struct nk_image
+nk_subimage_id(int id, unsigned short w, unsigned short h, struct nk_rect r)
+{
+ struct nk_image s;
+ nk_zero(&s, sizeof(s));
+ s.handle.id = id;
+ s.w = w; s.h = h;
+ s.region[0] = (unsigned short)r.x;
+ s.region[1] = (unsigned short)r.y;
+ s.region[2] = (unsigned short)r.w;
+ s.region[3] = (unsigned short)r.h;
+ return s;
+}
+
+NK_API struct nk_image
+nk_subimage_handle(nk_handle handle, unsigned short w, unsigned short h,
+ struct nk_rect r)
+{
+ struct nk_image s;
+ nk_zero(&s, sizeof(s));
+ s.handle = handle;
+ s.w = w; s.h = h;
+ s.region[0] = (unsigned short)r.x;
+ s.region[1] = (unsigned short)r.y;
+ s.region[2] = (unsigned short)r.w;
+ s.region[3] = (unsigned short)r.h;
+ return s;
+}
+
+NK_API struct nk_image
+nk_image_handle(nk_handle handle)
+{
+ struct nk_image s;
+ nk_zero(&s, sizeof(s));
+ s.handle = handle;
+ s.w = 0; s.h = 0;
+ s.region[0] = 0;
+ s.region[1] = 0;
+ s.region[2] = 0;
+ s.region[3] = 0;
+ return s;
+}
+
+NK_API struct nk_image
+nk_image_ptr(void *ptr)
+{
+ struct nk_image s;
+ nk_zero(&s, sizeof(s));
+ NK_ASSERT(ptr);
+ s.handle.ptr = ptr;
+ s.w = 0; s.h = 0;
+ s.region[0] = 0;
+ s.region[1] = 0;
+ s.region[2] = 0;
+ s.region[3] = 0;
+ return s;
+}
+
+NK_API struct nk_image
+nk_image_id(int id)
+{
+ struct nk_image s;
+ nk_zero(&s, sizeof(s));
+ s.handle.id = id;
+ s.w = 0; s.h = 0;
+ s.region[0] = 0;
+ s.region[1] = 0;
+ s.region[2] = 0;
+ s.region[3] = 0;
+ return s;
+}
+
+NK_API int
+nk_image_is_subimage(const struct nk_image* img)
+{
+ NK_ASSERT(img);
+ return !(img->w == 0 && img->h == 0);
+}
+
+NK_INTERN void
+nk_unify(struct nk_rect *clip, const struct nk_rect *a, float x0, float y0,
+ float x1, float y1)
+{
+ NK_ASSERT(a);
+ NK_ASSERT(clip);
+ clip->x = NK_MAX(a->x, x0);
+ clip->y = NK_MAX(a->y, y0);
+ clip->w = NK_MIN(a->x + a->w, x1) - clip->x;
+ clip->h = NK_MIN(a->y + a->h, y1) - clip->y;
+ clip->w = NK_MAX(0, clip->w);
+ clip->h = NK_MAX(0, clip->h);
+}
+
+NK_API void
+nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r,
+ float pad_x, float pad_y, enum nk_heading direction)
+{
+ float w_half, h_half;
+ NK_ASSERT(result);
+
+ r.w = NK_MAX(2 * pad_x, r.w);
+ r.h = NK_MAX(2 * pad_y, r.h);
+ r.w = r.w - 2 * pad_x;
+ r.h = r.h - 2 * pad_y;
+
+ r.x = r.x + pad_x;
+ r.y = r.y + pad_y;
+
+ w_half = r.w / 2.0f;
+ h_half = r.h / 2.0f;
+
+ if (direction == NK_UP) {
+ result[0] = nk_vec2(r.x + w_half, r.y);
+ result[1] = nk_vec2(r.x + r.w, r.y + r.h);
+ result[2] = nk_vec2(r.x, r.y + r.h);
+ } else if (direction == NK_RIGHT) {
+ result[0] = nk_vec2(r.x, r.y);
+ result[1] = nk_vec2(r.x + r.w, r.y + h_half);
+ result[2] = nk_vec2(r.x, r.y + r.h);
+ } else if (direction == NK_DOWN) {
+ result[0] = nk_vec2(r.x, r.y);
+ result[1] = nk_vec2(r.x + r.w, r.y);
+ result[2] = nk_vec2(r.x + w_half, r.y + r.h);
+ } else {
+ result[0] = nk_vec2(r.x, r.y + h_half);
+ result[1] = nk_vec2(r.x + r.w, r.y);
+ result[2] = nk_vec2(r.x + r.w, r.y + r.h);
+ }
+}
+
+NK_INTERN int
+nk_text_clamp(const struct nk_user_font *font, const char *text,
+ int text_len, float space, int *glyphs, float *text_width,
+ nk_rune *sep_list, int sep_count)
+{
+ int i = 0;
+ int glyph_len = 0;
+ float last_width = 0;
+ nk_rune unicode = 0;
+ float width = 0;
+ int len = 0;
+ int g = 0;
+ float s;
+
+ int sep_len = 0;
+ int sep_g = 0;
+ float sep_width = 0;
+ sep_count = NK_MAX(sep_count,0);
+
+ glyph_len = nk_utf_decode(text, &unicode, text_len);
+ while (glyph_len && (width < space) && (len < text_len)) {
+ len += glyph_len;
+ s = font->width(font->userdata, font->height, text, len);
+ for (i = 0; i < sep_count; ++i) {
+ if (unicode != sep_list[i]) continue;
+ sep_width = last_width = width;
+ sep_g = g+1;
+ sep_len = len;
+ break;
+ }
+ if (i == sep_count){
+ last_width = sep_width = width;
+ sep_g = g+1;
+ }
+ width = s;
+ glyph_len = nk_utf_decode(&text[len], &unicode, text_len - len);
+ g++;
+ }
+ if (len >= text_len) {
+ *glyphs = g;
+ *text_width = last_width;
+ return len;
+ } else {
+ *glyphs = sep_g;
+ *text_width = sep_width;
+ return (!sep_len) ? len: sep_len;
+ }
+}
+
+enum {NK_DO_NOT_STOP_ON_NEW_LINE, NK_STOP_ON_NEW_LINE};
+NK_INTERN struct nk_vec2
+nk_text_calculate_text_bounds(const struct nk_user_font *font,
+ const char *begin, int byte_len, float row_height, const char **remaining,
+ struct nk_vec2 *out_offset, int *glyphs, int op)
+{
+ float line_height = row_height;
+ struct nk_vec2 text_size = nk_vec2(0,0);
+ float line_width = 0.0f;
+
+ float glyph_width;
+ int glyph_len = 0;
+ nk_rune unicode = 0;
+ int text_len = 0;
+ if (!begin || byte_len <= 0 || !font)
+ return nk_vec2(0,row_height);
+
+ glyph_len = nk_utf_decode(begin, &unicode, byte_len);
+ if (!glyph_len) return text_size;
+ glyph_width = font->width(font->userdata, font->height, begin, glyph_len);
+
+ *glyphs = 0;
+ while ((text_len < byte_len) && glyph_len) {
+ if (unicode == '\n') {
+ text_size.x = NK_MAX(text_size.x, line_width);
+ text_size.y += line_height;
+ line_width = 0;
+ *glyphs+=1;
+ if (op == NK_STOP_ON_NEW_LINE)
+ break;
+
+ text_len++;
+ glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
+ continue;
+ }
+
+ if (unicode == '\r') {
+ text_len++;
+ *glyphs+=1;
+ glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
+ continue;
+ }
+
+ *glyphs = *glyphs + 1;
+ text_len += glyph_len;
+ line_width += (float)glyph_width;
+ glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len-text_len);
+ glyph_width = font->width(font->userdata, font->height, begin+text_len, glyph_len);
+ continue;
+ }
+
+ if (text_size.x < line_width)
+ text_size.x = line_width;
+ if (out_offset)
+ *out_offset = nk_vec2(line_width, text_size.y + line_height);
+ if (line_width > 0 || text_size.y == 0.0f)
+ text_size.y += line_height;
+ if (remaining)
+ *remaining = begin+text_len;
+ return text_size;
+}
+
+/* ==============================================================
+ *
+ * UTF-8
+ *
+ * ===============================================================*/
+NK_GLOBAL const nk_byte nk_utfbyte[NK_UTF_SIZE+1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
+NK_GLOBAL const nk_byte nk_utfmask[NK_UTF_SIZE+1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
+NK_GLOBAL const nk_uint nk_utfmin[NK_UTF_SIZE+1] = {0, 0, 0x80, 0x800, 0x10000};
+NK_GLOBAL const nk_uint nk_utfmax[NK_UTF_SIZE+1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
+
+NK_INTERN int
+nk_utf_validate(nk_rune *u, int i)
+{
+ NK_ASSERT(u);
+ if (!u) return 0;
+ if (!NK_BETWEEN(*u, nk_utfmin[i], nk_utfmax[i]) ||
+ NK_BETWEEN(*u, 0xD800, 0xDFFF))
+ *u = NK_UTF_INVALID;
+ for (i = 1; *u > nk_utfmax[i]; ++i);
+ return i;
+}
+
+NK_INTERN nk_rune
+nk_utf_decode_byte(char c, int *i)
+{
+ NK_ASSERT(i);
+ if (!i) return 0;
+ for(*i = 0; *i < (int)NK_LEN(nk_utfmask); ++(*i)) {
+ if (((nk_byte)c & nk_utfmask[*i]) == nk_utfbyte[*i])
+ return (nk_byte)(c & ~nk_utfmask[*i]);
+ }
+ return 0;
+}
+
+NK_API int
+nk_utf_decode(const char *c, nk_rune *u, int clen)
+{
+ int i, j, len, type=0;
+ nk_rune udecoded;
+
+ NK_ASSERT(c);
+ NK_ASSERT(u);
+
+ if (!c || !u) return 0;
+ if (!clen) return 0;
+ *u = NK_UTF_INVALID;
+
+ udecoded = nk_utf_decode_byte(c[0], &len);
+ if (!NK_BETWEEN(len, 1, NK_UTF_SIZE))
+ return 1;
+
+ for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
+ udecoded = (udecoded << 6) | nk_utf_decode_byte(c[i], &type);
+ if (type != 0)
+ return j;
+ }
+ if (j < len)
+ return 0;
+ *u = udecoded;
+ nk_utf_validate(u, len);
+ return len;
+}
+
+NK_INTERN char
+nk_utf_encode_byte(nk_rune u, int i)
+{
+ return (char)((nk_utfbyte[i]) | ((nk_byte)u & ~nk_utfmask[i]));
+}
+
+NK_API int
+nk_utf_encode(nk_rune u, char *c, int clen)
+{
+ int len, i;
+ len = nk_utf_validate(&u, 0);
+ if (clen < len || !len || len > NK_UTF_SIZE)
+ return 0;
+
+ for (i = len - 1; i != 0; --i) {
+ c[i] = nk_utf_encode_byte(u, 0);
+ u >>= 6;
+ }
+ c[0] = nk_utf_encode_byte(u, len);
+ return len;
+}
+
+NK_API int
+nk_utf_len(const char *str, int len)
+{
+ const char *text;
+ int glyphs = 0;
+ int text_len;
+ int glyph_len;
+ int src_len = 0;
+ nk_rune unicode;
+
+ NK_ASSERT(str);
+ if (!str || !len) return 0;
+
+ text = str;
+ text_len = len;
+ glyph_len = nk_utf_decode(text, &unicode, text_len);
+ while (glyph_len && src_len < len) {
+ glyphs++;
+ src_len = src_len + glyph_len;
+ glyph_len = nk_utf_decode(text + src_len, &unicode, text_len - src_len);
+ }
+ return glyphs;
+}
+
+NK_API const char*
+nk_utf_at(const char *buffer, int length, int index,
+ nk_rune *unicode, int *len)
+{
+ int i = 0;
+ int src_len = 0;
+ int glyph_len = 0;
+ const char *text;
+ int text_len;
+
+ NK_ASSERT(buffer);
+ NK_ASSERT(unicode);
+ NK_ASSERT(len);
+
+ if (!buffer || !unicode || !len) return 0;
+ if (index < 0) {
+ *unicode = NK_UTF_INVALID;
+ *len = 0;
+ return 0;
+ }
+
+ text = buffer;
+ text_len = length;
+ glyph_len = nk_utf_decode(text, unicode, text_len);
+ while (glyph_len) {
+ if (i == index) {
+ *len = glyph_len;
+ break;
+ }
+
+ i++;
+ src_len = src_len + glyph_len;
+ glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
+ }
+ if (i != index) return 0;
+ return buffer + src_len;
+}
+
+/* ==============================================================
+ *
+ * BUFFER
+ *
+ * ===============================================================*/
+#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
+NK_INTERN void* nk_malloc(nk_handle unused, void *old,nk_size size)
+{NK_UNUSED(unused); NK_UNUSED(old); return malloc(size);}
+NK_INTERN void nk_mfree(nk_handle unused, void *ptr)
+{NK_UNUSED(unused); free(ptr);}
+
+NK_API void
+nk_buffer_init_default(struct nk_buffer *buffer)
+{
+ struct nk_allocator alloc;
+ alloc.userdata.ptr = 0;
+ alloc.alloc = nk_malloc;
+ alloc.free = nk_mfree;
+ nk_buffer_init(buffer, &alloc, NK_BUFFER_DEFAULT_INITIAL_SIZE);
+}
+#endif
+
+NK_API void
+nk_buffer_init(struct nk_buffer *b, const struct nk_allocator *a,
+ nk_size initial_size)
+{
+ NK_ASSERT(b);
+ NK_ASSERT(a);
+ NK_ASSERT(initial_size);
+ if (!b || !a || !initial_size) return;
+
+ nk_zero(b, sizeof(*b));
+ b->type = NK_BUFFER_DYNAMIC;
+ b->memory.ptr = a->alloc(a->userdata,0, initial_size);
+ b->memory.size = initial_size;
+ b->size = initial_size;
+ b->grow_factor = 2.0f;
+ b->pool = *a;
+}
+
+NK_API void
+nk_buffer_init_fixed(struct nk_buffer *b, void *m, nk_size size)
+{
+ NK_ASSERT(b);
+ NK_ASSERT(m);
+ NK_ASSERT(size);
+ if (!b || !m || !size) return;
+
+ nk_zero(b, sizeof(*b));
+ b->type = NK_BUFFER_FIXED;
+ b->memory.ptr = m;
+ b->memory.size = size;
+ b->size = size;
+}
+
+NK_INTERN void*
+nk_buffer_align(void *unaligned, nk_size align, nk_size *alignment,
+ enum nk_buffer_allocation_type type)
+{
+ void *memory = 0;
+ switch (type) {
+ default:
+ case NK_BUFFER_MAX:
+ case NK_BUFFER_FRONT:
+ if (align) {
+ memory = NK_ALIGN_PTR(unaligned, align);
+ *alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned);
+ } else {
+ memory = unaligned;
+ *alignment = 0;
+ }
+ break;
+ case NK_BUFFER_BACK:
+ if (align) {
+ memory = NK_ALIGN_PTR_BACK(unaligned, align);
+ *alignment = (nk_size)((nk_byte*)unaligned - (nk_byte*)memory);
+ } else {
+ memory = unaligned;
+ *alignment = 0;
+ }
+ break;
+ }
+ return memory;
+}
+
+NK_INTERN void*
+nk_buffer_realloc(struct nk_buffer *b, nk_size capacity, nk_size *size)
+{
+ void *temp;
+ nk_size buffer_size;
+
+ NK_ASSERT(b);
+ NK_ASSERT(size);
+ if (!b || !size || !b->pool.alloc || !b->pool.free)
+ return 0;
+
+ buffer_size = b->memory.size;
+ temp = b->pool.alloc(b->pool.userdata, b->memory.ptr, capacity);
+ NK_ASSERT(temp);
+ if (!temp) return 0;
+
+ *size = capacity;
+ if (temp != b->memory.ptr) {
+ NK_MEMCPY(temp, b->memory.ptr, buffer_size);
+ b->pool.free(b->pool.userdata, b->memory.ptr);
+ }
+
+ if (b->size == buffer_size) {
+ /* no back buffer so just set correct size */
+ b->size = capacity;
+ return temp;
+ } else {
+ /* copy back buffer to the end of the new buffer */
+ void *dst, *src;
+ nk_size back_size;
+ back_size = buffer_size - b->size;
+ dst = nk_ptr_add(void, temp, capacity - back_size);
+ src = nk_ptr_add(void, temp, b->size);
+ NK_MEMCPY(dst, src, back_size);
+ b->size = capacity - back_size;
+ }
+ return temp;
+}
+
+NK_INTERN void*
+nk_buffer_alloc(struct nk_buffer *b, enum nk_buffer_allocation_type type,
+ nk_size size, nk_size align)
+{
+ int full;
+ nk_size alignment;
+ void *unaligned;
+ void *memory;
+
+ NK_ASSERT(b);
+ NK_ASSERT(size);
+ if (!b || !size) return 0;
+ b->needed += size;
+
+ /* calculate total size with needed alignment + size */
+ if (type == NK_BUFFER_FRONT)
+ unaligned = nk_ptr_add(void, b->memory.ptr, b->allocated);
+ else unaligned = nk_ptr_add(void, b->memory.ptr, b->size - size);
+ memory = nk_buffer_align(unaligned, align, &alignment, type);
+
+ /* check if buffer has enough memory*/
+ if (type == NK_BUFFER_FRONT)
+ full = ((b->allocated + size + alignment) > b->size);
+ else full = ((b->size - NK_MIN(b->size,(size + alignment))) <= b->allocated);
+
+ if (full) {
+ nk_size capacity;
+ if (b->type != NK_BUFFER_DYNAMIC)
+ return 0;
+ NK_ASSERT(b->pool.alloc && b->pool.free);
+ if (b->type != NK_BUFFER_DYNAMIC || !b->pool.alloc || !b->pool.free)
+ return 0;
+
+ /* buffer is full so allocate bigger buffer if dynamic */
+ capacity = (nk_size)((float)b->memory.size * b->grow_factor);
+ capacity = NK_MAX(capacity, nk_round_up_pow2((nk_uint)(b->allocated + size)));
+ b->memory.ptr = nk_buffer_realloc(b, capacity, &b->memory.size);
+ if (!b->memory.ptr) return 0;
+
+ /* align newly allocated pointer */
+ if (type == NK_BUFFER_FRONT)
+ unaligned = nk_ptr_add(void, b->memory.ptr, b->allocated);
+ else unaligned = nk_ptr_add(void, b->memory.ptr, b->size - size);
+ memory = nk_buffer_align(unaligned, align, &alignment, type);
+ }
+ if (type == NK_BUFFER_FRONT)
+ b->allocated += size + alignment;
+ else b->size -= (size + alignment);
+ b->needed += alignment;
+ b->calls++;
+ return memory;
+}
+
+NK_API void
+nk_buffer_push(struct nk_buffer *b, enum nk_buffer_allocation_type type,
+ const void *memory, nk_size size, nk_size align)
+{
+ void *mem = nk_buffer_alloc(b, type, size, align);
+ if (!mem) return;
+ NK_MEMCPY(mem, memory, size);
+}
+
+NK_API void
+nk_buffer_mark(struct nk_buffer *buffer, enum nk_buffer_allocation_type type)
+{
+ NK_ASSERT(buffer);
+ if (!buffer) return;
+ buffer->marker[type].active = nk_true;
+ if (type == NK_BUFFER_BACK)
+ buffer->marker[type].offset = buffer->size;
+ else buffer->marker[type].offset = buffer->allocated;
+}
+
+NK_API void
+nk_buffer_reset(struct nk_buffer *buffer, enum nk_buffer_allocation_type type)
+{
+ NK_ASSERT(buffer);
+ if (!buffer) return;
+ if (type == NK_BUFFER_BACK) {
+ /* reset back buffer either back to marker or empty */
+ buffer->needed -= (buffer->memory.size - buffer->marker[type].offset);
+ if (buffer->marker[type].active)
+ buffer->size = buffer->marker[type].offset;
+ else buffer->size = buffer->memory.size;
+ buffer->marker[type].active = nk_false;
+ } else {
+ /* reset front buffer either back to back marker or empty */
+ buffer->needed -= (buffer->allocated - buffer->marker[type].offset);
+ if (buffer->marker[type].active)
+ buffer->allocated = buffer->marker[type].offset;
+ else buffer->allocated = 0;
+ buffer->marker[type].active = nk_false;
+ }
+}
+
+NK_API void
+nk_buffer_clear(struct nk_buffer *b)
+{
+ NK_ASSERT(b);
+ if (!b) return;
+ b->allocated = 0;
+ b->size = b->memory.size;
+ b->calls = 0;
+ b->needed = 0;
+}
+
+NK_API void
+nk_buffer_free(struct nk_buffer *b)
+{
+ NK_ASSERT(b);
+ if (!b || !b->memory.ptr) return;
+ if (b->type == NK_BUFFER_FIXED) return;
+ if (!b->pool.free) return;
+ NK_ASSERT(b->pool.free);
+ b->pool.free(b->pool.userdata, b->memory.ptr);
+}
+
+NK_API void
+nk_buffer_info(struct nk_memory_status *s, struct nk_buffer *b)
+{
+ NK_ASSERT(b);
+ NK_ASSERT(s);
+ if (!s || !b) return;
+ s->allocated = b->allocated;
+ s->size = b->memory.size;
+ s->needed = b->needed;
+ s->memory = b->memory.ptr;
+ s->calls = b->calls;
+}
+
+NK_API void*
+nk_buffer_memory(struct nk_buffer *buffer)
+{
+ NK_ASSERT(buffer);
+ if (!buffer) return 0;
+ return buffer->memory.ptr;
+}
+
+NK_API const void*
+nk_buffer_memory_const(const struct nk_buffer *buffer)
+{
+ NK_ASSERT(buffer);
+ if (!buffer) return 0;
+ return buffer->memory.ptr;
+}
+
+NK_API nk_size
+nk_buffer_total(struct nk_buffer *buffer)
+{
+ NK_ASSERT(buffer);
+ if (!buffer) return 0;
+ return buffer->memory.size;
+}
+
+/*
+ * ==============================================================
+ *
+ * STRING
+ *
+ * ===============================================================
+ */
+#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
+NK_API void
+nk_str_init_default(struct nk_str *str)
+{
+ struct nk_allocator alloc;
+ alloc.userdata.ptr = 0;
+ alloc.alloc = nk_malloc;
+ alloc.free = nk_mfree;
+ nk_buffer_init(&str->buffer, &alloc, 32);
+ str->len = 0;
+}
+#endif
+
+NK_API void
+nk_str_init(struct nk_str *str, const struct nk_allocator *alloc, nk_size size)
+{
+ nk_buffer_init(&str->buffer, alloc, size);
+ str->len = 0;
+}
+
+NK_API void
+nk_str_init_fixed(struct nk_str *str, void *memory, nk_size size)
+{
+ nk_buffer_init_fixed(&str->buffer, memory, size);
+ str->len = 0;
+}
+
+NK_API int
+nk_str_append_text_char(struct nk_str *s, const char *str, int len)
+{
+ char *mem;
+ NK_ASSERT(s);
+ NK_ASSERT(str);
+ if (!s || !str || !len) return 0;
+ mem = (char*)nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0);
+ if (!mem) return 0;
+ NK_MEMCPY(mem, str, (nk_size)len * sizeof(char));
+ s->len += nk_utf_len(str, len);
+ return len;
+}
+
+NK_API int
+nk_str_append_str_char(struct nk_str *s, const char *str)
+{
+ return nk_str_append_text_char(s, str, nk_strlen(str));
+}
+
+NK_API int
+nk_str_append_text_utf8(struct nk_str *str, const char *text, int len)
+{
+ int i = 0;
+ int byte_len = 0;
+ nk_rune unicode;
+ if (!str || !text || !len) return 0;
+ for (i = 0; i < len; ++i)
+ byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
+ nk_str_append_text_char(str, text, byte_len);
+ return len;
+}
+
+NK_API int
+nk_str_append_str_utf8(struct nk_str *str, const char *text)
+{
+ int runes = 0;
+ int byte_len = 0;
+ int num_runes = 0;
+ int glyph_len = 0;
+ nk_rune unicode;
+ if (!str || !text) return 0;
+
+ glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
+ while (unicode != '\0' && glyph_len) {
+ glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
+ byte_len += glyph_len;
+ num_runes++;
+ }
+ nk_str_append_text_char(str, text, byte_len);
+ return runes;
+}
+
+NK_API int
+nk_str_append_text_runes(struct nk_str *str, const nk_rune *text, int len)
+{
+ int i = 0;
+ int byte_len = 0;
+ nk_glyph glyph;
+
+ NK_ASSERT(str);
+ if (!str || !text || !len) return 0;
+ for (i = 0; i < len; ++i) {
+ byte_len = nk_utf_encode(text[i], glyph, NK_UTF_SIZE);
+ if (!byte_len) break;
+ nk_str_append_text_char(str, glyph, byte_len);
+ }
+ return len;
+}
+
+NK_API int
+nk_str_append_str_runes(struct nk_str *str, const nk_rune *runes)
+{
+ int i = 0;
+ nk_glyph glyph;
+ int byte_len;
+ NK_ASSERT(str);
+ if (!str || !runes) return 0;
+ while (runes[i] != '\0') {
+ byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
+ nk_str_append_text_char(str, glyph, byte_len);
+ i++;
+ }
+ return i;
+}
+
+NK_API int
+nk_str_insert_at_char(struct nk_str *s, int pos, const char *str, int len)
+{
+ int i;
+ void *mem;
+ char *src;
+ char *dst;
+
+ int copylen;
+ NK_ASSERT(s);
+ NK_ASSERT(str);
+ NK_ASSERT(len >= 0);
+ if (!s || !str || !len || (nk_size)pos > s->buffer.allocated) return 0;
+ if ((s->buffer.allocated + (nk_size)len >= s->buffer.memory.size) &&
+ (s->buffer.type == NK_BUFFER_FIXED)) return 0;
+
+ copylen = (int)s->buffer.allocated - pos;
+ if (!copylen) {
+ nk_str_append_text_char(s, str, len);
+ return 1;
+ }
+ mem = nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0);
+ if (!mem) return 0;
+
+ /* memmove */
+ NK_ASSERT(((int)pos + (int)len + ((int)copylen - 1)) >= 0);
+ NK_ASSERT(((int)pos + ((int)copylen - 1)) >= 0);
+ dst = nk_ptr_add(char, s->buffer.memory.ptr, pos + len + (copylen - 1));
+ src = nk_ptr_add(char, s->buffer.memory.ptr, pos + (copylen-1));
+ for (i = 0; i < copylen; ++i) *dst-- = *src--;
+ mem = nk_ptr_add(void, s->buffer.memory.ptr, pos);
+ NK_MEMCPY(mem, str, (nk_size)len * sizeof(char));
+ s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
+ return 1;
+}
+
+NK_API int
+nk_str_insert_at_rune(struct nk_str *str, int pos, const char *cstr, int len)
+{
+ int glyph_len;
+ nk_rune unicode;
+ const char *begin;
+ const char *buffer;
+
+ NK_ASSERT(str);
+ NK_ASSERT(cstr);
+ NK_ASSERT(len);
+ if (!str || !cstr || !len) return 0;
+ begin = nk_str_at_rune(str, pos, &unicode, &glyph_len);
+ if (!str->len)
+ return nk_str_append_text_char(str, cstr, len);
+ buffer = nk_str_get_const(str);
+ if (!begin) return 0;
+ return nk_str_insert_at_char(str, (int)(begin - buffer), cstr, len);
+}
+
+NK_API int
+nk_str_insert_text_char(struct nk_str *str, int pos, const char *text, int len)
+{
+ return nk_str_insert_text_utf8(str, pos, text, len);
+}
+
+NK_API int
+nk_str_insert_str_char(struct nk_str *str, int pos, const char *text)
+{
+ return nk_str_insert_text_utf8(str, pos, text, nk_strlen(text));
+}
+
+NK_API int
+nk_str_insert_text_utf8(struct nk_str *str, int pos, const char *text, int len)
+{
+ int i = 0;
+ int byte_len = 0;
+ nk_rune unicode;
+
+ NK_ASSERT(str);
+ NK_ASSERT(text);
+ if (!str || !text || !len) return 0;
+ for (i = 0; i < len; ++i)
+ byte_len += nk_utf_decode(text+byte_len, &unicode, 4);
+ nk_str_insert_at_rune(str, pos, text, byte_len);
+ return len;
+}
+
+NK_API int
+nk_str_insert_str_utf8(struct nk_str *str, int pos, const char *text)
+{
+ int runes = 0;
+ int byte_len = 0;
+ int num_runes = 0;
+ int glyph_len = 0;
+ nk_rune unicode;
+ if (!str || !text) return 0;
+
+ glyph_len = byte_len = nk_utf_decode(text+byte_len, &unicode, 4);
+ while (unicode != '\0' && glyph_len) {
+ glyph_len = nk_utf_decode(text+byte_len, &unicode, 4);
+ byte_len += glyph_len;
+ num_runes++;
+ }
+ nk_str_insert_at_rune(str, pos, text, byte_len);
+ return runes;
+}
+
+NK_API int
+nk_str_insert_text_runes(struct nk_str *str, int pos, const nk_rune *runes, int len)
+{
+ int i = 0;
+ int byte_len = 0;
+ nk_glyph glyph;
+
+ NK_ASSERT(str);
+ if (!str || !runes || !len) return 0;
+ for (i = 0; i < len; ++i) {
+ byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
+ if (!byte_len) break;
+ nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
+ }
+ return len;
+}
+
+NK_API int
+nk_str_insert_str_runes(struct nk_str *str, int pos, const nk_rune *runes)
+{
+ int i = 0;
+ nk_glyph glyph;
+ int byte_len;
+ NK_ASSERT(str);
+ if (!str || !runes) return 0;
+ while (runes[i] != '\0') {
+ byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE);
+ nk_str_insert_at_rune(str, pos+i, glyph, byte_len);
+ i++;
+ }
+ return i;
+}
+
+NK_API void
+nk_str_remove_chars(struct nk_str *s, int len)
+{
+ NK_ASSERT(s);
+ NK_ASSERT(len >= 0);
+ if (!s || len < 0 || (nk_size)len > s->buffer.allocated) return;
+ NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0);
+ s->buffer.allocated -= (nk_size)len;
+ s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
+}
+
+NK_API void
+nk_str_remove_runes(struct nk_str *str, int len)
+{
+ int index;
+ const char *begin;
+ const char *end;
+ nk_rune unicode;
+
+ NK_ASSERT(str);
+ NK_ASSERT(len >= 0);
+ if (!str || len < 0) return;
+ if (len >= str->len) {
+ str->len = 0;
+ return;
+ }
+
+ index = str->len - len;
+ begin = nk_str_at_rune(str, index, &unicode, &len);
+ end = (const char*)str->buffer.memory.ptr + str->buffer.allocated;
+ nk_str_remove_chars(str, (int)(end-begin)+1);
+}
+
+NK_API void
+nk_str_delete_chars(struct nk_str *s, int pos, int len)
+{
+ NK_ASSERT(s);
+ if (!s || !len || (nk_size)pos > s->buffer.allocated ||
+ (nk_size)(pos + len) > s->buffer.allocated) return;
+
+ if ((nk_size)(pos + len) < s->buffer.allocated) {
+ /* memmove */
+ char *dst = nk_ptr_add(char, s->buffer.memory.ptr, pos);
+ char *src = nk_ptr_add(char, s->buffer.memory.ptr, pos + len);
+ NK_MEMCPY(dst, src, s->buffer.allocated - (nk_size)(pos + len));
+ NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0);
+ s->buffer.allocated -= (nk_size)len;
+ } else nk_str_remove_chars(s, len);
+ s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated);
+}
+
+NK_API void
+nk_str_delete_runes(struct nk_str *s, int pos, int len)
+{
+ char *temp;
+ nk_rune unicode;
+ char *begin;
+ char *end;
+ int unused;
+
+ NK_ASSERT(s);
+ NK_ASSERT(s->len >= pos + len);
+ if (s->len < pos + len)
+ len = NK_CLAMP(0, (s->len - pos), s->len);
+ if (!len) return;
+
+ temp = (char *)s->buffer.memory.ptr;
+ begin = nk_str_at_rune(s, pos, &unicode, &unused);
+ if (!begin) return;
+ s->buffer.memory.ptr = begin;
+ end = nk_str_at_rune(s, len, &unicode, &unused);
+ s->buffer.memory.ptr = temp;
+ if (!end) return;
+ nk_str_delete_chars(s, (int)(begin - temp), (int)(end - begin));
+}
+
+NK_API char*
+nk_str_at_char(struct nk_str *s, int pos)
+{
+ NK_ASSERT(s);
+ if (!s || pos > (int)s->buffer.allocated) return 0;
+ return nk_ptr_add(char, s->buffer.memory.ptr, pos);
+}
+
+NK_API char*
+nk_str_at_rune(struct nk_str *str, int pos, nk_rune *unicode, int *len)
+{
+ int i = 0;
+ int src_len = 0;
+ int glyph_len = 0;
+ char *text;
+ int text_len;
+
+ NK_ASSERT(str);
+ NK_ASSERT(unicode);
+ NK_ASSERT(len);
+
+ if (!str || !unicode || !len) return 0;
+ if (pos < 0) {
+ *unicode = 0;
+ *len = 0;
+ return 0;
+ }
+
+ text = (char*)str->buffer.memory.ptr;
+ text_len = (int)str->buffer.allocated;
+ glyph_len = nk_utf_decode(text, unicode, text_len);
+ while (glyph_len) {
+ if (i == pos) {
+ *len = glyph_len;
+ break;
+ }
+
+ i++;
+ src_len = src_len + glyph_len;
+ glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
+ }
+ if (i != pos) return 0;
+ return text + src_len;
+}
+
+NK_API const char*
+nk_str_at_char_const(const struct nk_str *s, int pos)
+{
+ NK_ASSERT(s);
+ if (!s || pos > (int)s->buffer.allocated) return 0;
+ return nk_ptr_add(char, s->buffer.memory.ptr, pos);
+}
+
+NK_API const char*
+nk_str_at_const(const struct nk_str *str, int pos, nk_rune *unicode, int *len)
+{
+ int i = 0;
+ int src_len = 0;
+ int glyph_len = 0;
+ char *text;
+ int text_len;
+
+ NK_ASSERT(str);
+ NK_ASSERT(unicode);
+ NK_ASSERT(len);
+
+ if (!str || !unicode || !len) return 0;
+ if (pos < 0) {
+ *unicode = 0;
+ *len = 0;
+ return 0;
+ }
+
+ text = (char*)str->buffer.memory.ptr;
+ text_len = (int)str->buffer.allocated;
+ glyph_len = nk_utf_decode(text, unicode, text_len);
+ while (glyph_len) {
+ if (i == pos) {
+ *len = glyph_len;
+ break;
+ }
+
+ i++;
+ src_len = src_len + glyph_len;
+ glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len);
+ }
+ if (i != pos) return 0;
+ return text + src_len;
+}
+
+NK_API nk_rune
+nk_str_rune_at(const struct nk_str *str, int pos)
+{
+ int len;
+ nk_rune unicode = 0;
+ nk_str_at_const(str, pos, &unicode, &len);
+ return unicode;
+}
+
+NK_API char*
+nk_str_get(struct nk_str *s)
+{
+ NK_ASSERT(s);
+ if (!s || !s->len || !s->buffer.allocated) return 0;
+ return (char*)s->buffer.memory.ptr;
+}
+
+NK_API const char*
+nk_str_get_const(const struct nk_str *s)
+{
+ NK_ASSERT(s);
+ if (!s || !s->len || !s->buffer.allocated) return 0;
+ return (const char*)s->buffer.memory.ptr;
+}
+
+NK_API int
+nk_str_len(struct nk_str *s)
+{
+ NK_ASSERT(s);
+ if (!s || !s->len || !s->buffer.allocated) return 0;
+ return s->len;
+}
+
+NK_API int
+nk_str_len_char(struct nk_str *s)
+{
+ NK_ASSERT(s);
+ if (!s || !s->len || !s->buffer.allocated) return 0;
+ return (int)s->buffer.allocated;
+}
+
+NK_API void
+nk_str_clear(struct nk_str *str)
+{
+ NK_ASSERT(str);
+ nk_buffer_clear(&str->buffer);
+ str->len = 0;
+}
+
+NK_API void
+nk_str_free(struct nk_str *str)
+{
+ NK_ASSERT(str);
+ nk_buffer_free(&str->buffer);
+ str->len = 0;
+}
+
+/*
+ * ==============================================================
+ *
+ * Command buffer
+ *
+ * ===============================================================
+*/
+NK_INTERN void
+nk_command_buffer_init(struct nk_command_buffer *cmdbuf,
+ struct nk_buffer *buffer, enum nk_command_clipping clip)
+{
+ NK_ASSERT(cmdbuf);
+ NK_ASSERT(buffer);
+ if (!cmdbuf || !buffer) return;
+ cmdbuf->base = buffer;
+ cmdbuf->use_clipping = clip;
+ cmdbuf->begin = buffer->allocated;
+ cmdbuf->end = buffer->allocated;
+ cmdbuf->last = buffer->allocated;
+}
+
+NK_INTERN void
+nk_command_buffer_reset(struct nk_command_buffer *buffer)
+{
+ NK_ASSERT(buffer);
+ if (!buffer) return;
+ buffer->begin = 0;
+ buffer->end = 0;
+ buffer->last = 0;
+ buffer->clip = nk_null_rect;
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+ buffer->userdata.ptr = 0;
+#endif
+}
+
+NK_INTERN void*
+nk_command_buffer_push(struct nk_command_buffer* b,
+ enum nk_command_type t, nk_size size)
+{
+ NK_STORAGE const nk_size align = NK_ALIGNOF(struct nk_command);
+ struct nk_command *cmd;
+ nk_size alignment;
+ void *unaligned;
+ void *memory;
+
+ NK_ASSERT(b);
+ NK_ASSERT(b->base);
+ if (!b) return 0;
+ cmd = (struct nk_command*)nk_buffer_alloc(b->base,NK_BUFFER_FRONT,size,align);
+ if (!cmd) return 0;
+
+ /* make sure the offset to the next command is aligned */
+ b->last = (nk_size)((nk_byte*)cmd - (nk_byte*)b->base->memory.ptr);
+ unaligned = (nk_byte*)cmd + size;
+ memory = NK_ALIGN_PTR(unaligned, align);
+ alignment = (nk_size)((nk_byte*)memory - (nk_byte*)unaligned);
+#ifdef NK_ZERO_COMMAND_MEMORY
+ NK_MEMSET(cmd, 0, size + alignment);
+#endif
+
+ cmd->type = t;
+ cmd->next = b->base->allocated + alignment;
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+ cmd->userdata = b->userdata;
+#endif
+ b->end = cmd->next;
+ return cmd;
+}
+
+NK_API void
+nk_push_scissor(struct nk_command_buffer *b, struct nk_rect r)
+{
+ struct nk_command_scissor *cmd;
+ NK_ASSERT(b);
+ if (!b) return;
+
+ b->clip.x = r.x;
+ b->clip.y = r.y;
+ b->clip.w = r.w;
+ b->clip.h = r.h;
+ cmd = (struct nk_command_scissor*)
+ nk_command_buffer_push(b, NK_COMMAND_SCISSOR, sizeof(*cmd));
+
+ if (!cmd) return;
+ cmd->x = (short)r.x;
+ cmd->y = (short)r.y;
+ cmd->w = (unsigned short)NK_MAX(0, r.w);
+ cmd->h = (unsigned short)NK_MAX(0, r.h);
+}
+
+NK_API void
+nk_stroke_line(struct nk_command_buffer *b, float x0, float y0,
+ float x1, float y1, float line_thickness, struct nk_color c)
+{
+ struct nk_command_line *cmd;
+ NK_ASSERT(b);
+ if (!b || line_thickness <= 0) return;
+ cmd = (struct nk_command_line*)
+ nk_command_buffer_push(b, NK_COMMAND_LINE, sizeof(*cmd));
+ if (!cmd) return;
+ cmd->line_thickness = (unsigned short)line_thickness;
+ cmd->begin.x = (short)x0;
+ cmd->begin.y = (short)y0;
+ cmd->end.x = (short)x1;
+ cmd->end.y = (short)y1;
+ cmd->color = c;
+}
+
+NK_API void
+nk_stroke_curve(struct nk_command_buffer *b, float ax, float ay,
+ float ctrl0x, float ctrl0y, float ctrl1x, float ctrl1y,
+ float bx, float by, float line_thickness, struct nk_color col)
+{
+ struct nk_command_curve *cmd;
+ NK_ASSERT(b);
+ if (!b || col.a == 0 || line_thickness <= 0) return;
+
+ cmd = (struct nk_command_curve*)
+ nk_command_buffer_push(b, NK_COMMAND_CURVE, sizeof(*cmd));
+ if (!cmd) return;
+ cmd->line_thickness = (unsigned short)line_thickness;
+ cmd->begin.x = (short)ax;
+ cmd->begin.y = (short)ay;
+ cmd->ctrl[0].x = (short)ctrl0x;
+ cmd->ctrl[0].y = (short)ctrl0y;
+ cmd->ctrl[1].x = (short)ctrl1x;
+ cmd->ctrl[1].y = (short)ctrl1y;
+ cmd->end.x = (short)bx;
+ cmd->end.y = (short)by;
+ cmd->color = col;
+}
+
+NK_API void
+nk_stroke_rect(struct nk_command_buffer *b, struct nk_rect rect,
+ float rounding, float line_thickness, struct nk_color c)
+{
+ struct nk_command_rect *cmd;
+ NK_ASSERT(b);
+ if (!b || c.a == 0 || rect.w == 0 || rect.h == 0 || line_thickness <= 0) return;
+ if (b->use_clipping) {
+ const struct nk_rect *clip = &b->clip;
+ if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
+ clip->x, clip->y, clip->w, clip->h)) return;
+ }
+ cmd = (struct nk_command_rect*)
+ nk_command_buffer_push(b, NK_COMMAND_RECT, sizeof(*cmd));
+ if (!cmd) return;
+ cmd->rounding = (unsigned short)rounding;
+ cmd->line_thickness = (unsigned short)line_thickness;
+ cmd->x = (short)rect.x;
+ cmd->y = (short)rect.y;
+ cmd->w = (unsigned short)NK_MAX(0, rect.w);
+ cmd->h = (unsigned short)NK_MAX(0, rect.h);
+ cmd->color = c;
+}
+
+NK_API void
+nk_fill_rect(struct nk_command_buffer *b, struct nk_rect rect,
+ float rounding, struct nk_color c)
+{
+ struct nk_command_rect_filled *cmd;
+ NK_ASSERT(b);
+ if (!b || c.a == 0 || rect.w == 0 || rect.h == 0) return;
+ if (b->use_clipping) {
+ const struct nk_rect *clip = &b->clip;
+ if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
+ clip->x, clip->y, clip->w, clip->h)) return;
+ }
+
+ cmd = (struct nk_command_rect_filled*)
+ nk_command_buffer_push(b, NK_COMMAND_RECT_FILLED, sizeof(*cmd));
+ if (!cmd) return;
+ cmd->rounding = (unsigned short)rounding;
+ cmd->x = (short)rect.x;
+ cmd->y = (short)rect.y;
+ cmd->w = (unsigned short)NK_MAX(0, rect.w);
+ cmd->h = (unsigned short)NK_MAX(0, rect.h);
+ cmd->color = c;
+}
+
+NK_API void
+nk_fill_rect_multi_color(struct nk_command_buffer *b, struct nk_rect rect,
+ struct nk_color left, struct nk_color top, struct nk_color right,
+ struct nk_color bottom)
+{
+ struct nk_command_rect_multi_color *cmd;
+ NK_ASSERT(b);
+ if (!b || rect.w == 0 || rect.h == 0) return;
+ if (b->use_clipping) {
+ const struct nk_rect *clip = &b->clip;
+ if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
+ clip->x, clip->y, clip->w, clip->h)) return;
+ }
+
+ cmd = (struct nk_command_rect_multi_color*)
+ nk_command_buffer_push(b, NK_COMMAND_RECT_MULTI_COLOR, sizeof(*cmd));
+ if (!cmd) return;
+ cmd->x = (short)rect.x;
+ cmd->y = (short)rect.y;
+ cmd->w = (unsigned short)NK_MAX(0, rect.w);
+ cmd->h = (unsigned short)NK_MAX(0, rect.h);
+ cmd->left = left;
+ cmd->top = top;
+ cmd->right = right;
+ cmd->bottom = bottom;
+}
+
+NK_API void
+nk_stroke_circle(struct nk_command_buffer *b, struct nk_rect r,
+ float line_thickness, struct nk_color c)
+{
+ struct nk_command_circle *cmd;
+ if (!b || r.w == 0 || r.h == 0 || line_thickness <= 0) return;
+ if (b->use_clipping) {
+ const struct nk_rect *clip = &b->clip;
+ if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
+ return;
+ }
+
+ cmd = (struct nk_command_circle*)
+ nk_command_buffer_push(b, NK_COMMAND_CIRCLE, sizeof(*cmd));
+ if (!cmd) return;
+ cmd->line_thickness = (unsigned short)line_thickness;
+ cmd->x = (short)r.x;
+ cmd->y = (short)r.y;
+ cmd->w = (unsigned short)NK_MAX(r.w, 0);
+ cmd->h = (unsigned short)NK_MAX(r.h, 0);
+ cmd->color = c;
+}
+
+NK_API void
+nk_fill_circle(struct nk_command_buffer *b, struct nk_rect r, struct nk_color c)
+{
+ struct nk_command_circle_filled *cmd;
+ NK_ASSERT(b);
+ if (!b || c.a == 0 || r.w == 0 || r.h == 0) return;
+ if (b->use_clipping) {
+ const struct nk_rect *clip = &b->clip;
+ if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h))
+ return;
+ }
+
+ cmd = (struct nk_command_circle_filled*)
+ nk_command_buffer_push(b, NK_COMMAND_CIRCLE_FILLED, sizeof(*cmd));
+ if (!cmd) return;
+ cmd->x = (short)r.x;
+ cmd->y = (short)r.y;
+ cmd->w = (unsigned short)NK_MAX(r.w, 0);
+ cmd->h = (unsigned short)NK_MAX(r.h, 0);
+ cmd->color = c;
+}
+
+NK_API void
+nk_stroke_arc(struct nk_command_buffer *b, float cx, float cy, float radius,
+ float a_min, float a_max, float line_thickness, struct nk_color c)
+{
+ struct nk_command_arc *cmd;
+ if (!b || c.a == 0 || line_thickness <= 0) return;
+ cmd = (struct nk_command_arc*)
+ nk_command_buffer_push(b, NK_COMMAND_ARC, sizeof(*cmd));
+ if (!cmd) return;
+ cmd->line_thickness = (unsigned short)line_thickness;
+ cmd->cx = (short)cx;
+ cmd->cy = (short)cy;
+ cmd->r = (unsigned short)radius;
+ cmd->a[0] = a_min;
+ cmd->a[1] = a_max;
+ cmd->color = c;
+}
+
+NK_API void
+nk_fill_arc(struct nk_command_buffer *b, float cx, float cy, float radius,
+ float a_min, float a_max, struct nk_color c)
+{
+ struct nk_command_arc_filled *cmd;
+ NK_ASSERT(b);
+ if (!b || c.a == 0) return;
+ cmd = (struct nk_command_arc_filled*)
+ nk_command_buffer_push(b, NK_COMMAND_ARC_FILLED, sizeof(*cmd));
+ if (!cmd) return;
+ cmd->cx = (short)cx;
+ cmd->cy = (short)cy;
+ cmd->r = (unsigned short)radius;
+ cmd->a[0] = a_min;
+ cmd->a[1] = a_max;
+ cmd->color = c;
+}
+
+NK_API void
+nk_stroke_triangle(struct nk_command_buffer *b, float x0, float y0, float x1,
+ float y1, float x2, float y2, float line_thickness, struct nk_color c)
+{
+ struct nk_command_triangle *cmd;
+ NK_ASSERT(b);
+ if (!b || c.a == 0 || line_thickness <= 0) return;
+ if (b->use_clipping) {
+ const struct nk_rect *clip = &b->clip;
+ if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
+ !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) &&
+ !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h))
+ return;
+ }
+
+ cmd = (struct nk_command_triangle*)
+ nk_command_buffer_push(b, NK_COMMAND_TRIANGLE, sizeof(*cmd));
+ if (!cmd) return;
+ cmd->line_thickness = (unsigned short)line_thickness;
+ cmd->a.x = (short)x0;
+ cmd->a.y = (short)y0;
+ cmd->b.x = (short)x1;
+ cmd->b.y = (short)y1;
+ cmd->c.x = (short)x2;
+ cmd->c.y = (short)y2;
+ cmd->color = c;
+}
+
+NK_API void
+nk_fill_triangle(struct nk_command_buffer *b, float x0, float y0, float x1,
+ float y1, float x2, float y2, struct nk_color c)
+{
+ struct nk_command_triangle_filled *cmd;
+ NK_ASSERT(b);
+ if (!b || c.a == 0) return;
+ if (!b) return;
+ if (b->use_clipping) {
+ const struct nk_rect *clip = &b->clip;
+ if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) &&
+ !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) &&
+ !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h))
+ return;
+ }
+
+ cmd = (struct nk_command_triangle_filled*)
+ nk_command_buffer_push(b, NK_COMMAND_TRIANGLE_FILLED, sizeof(*cmd));
+ if (!cmd) return;
+ cmd->a.x = (short)x0;
+ cmd->a.y = (short)y0;
+ cmd->b.x = (short)x1;
+ cmd->b.y = (short)y1;
+ cmd->c.x = (short)x2;
+ cmd->c.y = (short)y2;
+ cmd->color = c;
+}
+
+NK_API void
+nk_stroke_polygon(struct nk_command_buffer *b, float *points, int point_count,
+ float line_thickness, struct nk_color col)
+{
+ int i;
+ nk_size size = 0;
+ struct nk_command_polygon *cmd;
+
+ NK_ASSERT(b);
+ if (!b || col.a == 0 || line_thickness <= 0) return;
+ size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
+ cmd = (struct nk_command_polygon*) nk_command_buffer_push(b, NK_COMMAND_POLYGON, size);
+ if (!cmd) return;
+ cmd->color = col;
+ cmd->line_thickness = (unsigned short)line_thickness;
+ cmd->point_count = (unsigned short)point_count;
+ for (i = 0; i < point_count; ++i) {
+ cmd->points[i].x = (short)points[i*2];
+ cmd->points[i].y = (short)points[i*2+1];
+ }
+}
+
+NK_API void
+nk_fill_polygon(struct nk_command_buffer *b, float *points, int point_count,
+ struct nk_color col)
+{
+ int i;
+ nk_size size = 0;
+ struct nk_command_polygon_filled *cmd;
+
+ NK_ASSERT(b);
+ if (!b || col.a == 0) return;
+ size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
+ cmd = (struct nk_command_polygon_filled*)
+ nk_command_buffer_push(b, NK_COMMAND_POLYGON_FILLED, size);
+ if (!cmd) return;
+ cmd->color = col;
+ cmd->point_count = (unsigned short)point_count;
+ for (i = 0; i < point_count; ++i) {
+ cmd->points[i].x = (short)points[i*2+0];
+ cmd->points[i].y = (short)points[i*2+1];
+ }
+}
+
+NK_API void
+nk_stroke_polyline(struct nk_command_buffer *b, float *points, int point_count,
+ float line_thickness, struct nk_color col)
+{
+ int i;
+ nk_size size = 0;
+ struct nk_command_polyline *cmd;
+
+ NK_ASSERT(b);
+ if (!b || col.a == 0 || line_thickness <= 0) return;
+ size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count;
+ cmd = (struct nk_command_polyline*) nk_command_buffer_push(b, NK_COMMAND_POLYLINE, size);
+ if (!cmd) return;
+ cmd->color = col;
+ cmd->point_count = (unsigned short)point_count;
+ cmd->line_thickness = (unsigned short)line_thickness;
+ for (i = 0; i < point_count; ++i) {
+ cmd->points[i].x = (short)points[i*2];
+ cmd->points[i].y = (short)points[i*2+1];
+ }
+}
+
+NK_API void
+nk_draw_image(struct nk_command_buffer *b, struct nk_rect r,
+ const struct nk_image *img, struct nk_color col)
+{
+ struct nk_command_image *cmd;
+ NK_ASSERT(b);
+ if (!b) return;
+ if (b->use_clipping) {
+ const struct nk_rect *c = &b->clip;
+ if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
+ return;
+ }
+
+ cmd = (struct nk_command_image*)
+ nk_command_buffer_push(b, NK_COMMAND_IMAGE, sizeof(*cmd));
+ if (!cmd) return;
+ cmd->x = (short)r.x;
+ cmd->y = (short)r.y;
+ cmd->w = (unsigned short)NK_MAX(0, r.w);
+ cmd->h = (unsigned short)NK_MAX(0, r.h);
+ cmd->img = *img;
+ cmd->col = col;
+}
+
+NK_API void
+nk_push_custom(struct nk_command_buffer *b, struct nk_rect r,
+ nk_command_custom_callback cb, nk_handle usr)
+{
+ struct nk_command_custom *cmd;
+ NK_ASSERT(b);
+ if (!b) return;
+ if (b->use_clipping) {
+ const struct nk_rect *c = &b->clip;
+ if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
+ return;
+ }
+
+ cmd = (struct nk_command_custom*)
+ nk_command_buffer_push(b, NK_COMMAND_CUSTOM, sizeof(*cmd));
+ if (!cmd) return;
+ cmd->x = (short)r.x;
+ cmd->y = (short)r.y;
+ cmd->w = (unsigned short)NK_MAX(0, r.w);
+ cmd->h = (unsigned short)NK_MAX(0, r.h);
+ cmd->callback_data = usr;
+ cmd->callback = cb;
+}
+
+NK_API void
+nk_draw_text(struct nk_command_buffer *b, struct nk_rect r,
+ const char *string, int length, const struct nk_user_font *font,
+ struct nk_color bg, struct nk_color fg)
+{
+ float text_width = 0;
+ struct nk_command_text *cmd;
+
+ NK_ASSERT(b);
+ NK_ASSERT(font);
+ if (!b || !string || !length || (bg.a == 0 && fg.a == 0)) return;
+ if (b->use_clipping) {
+ const struct nk_rect *c = &b->clip;
+ if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h))
+ return;
+ }
+
+ /* make sure text fits inside bounds */
+ text_width = font->width(font->userdata, font->height, string, length);
+ if (text_width > r.w){
+ int glyphs = 0;
+ float txt_width = (float)text_width;
+ length = nk_text_clamp(font, string, length, r.w, &glyphs, &txt_width, 0,0);
+ }
+
+ if (!length) return;
+ cmd = (struct nk_command_text*)
+ nk_command_buffer_push(b, NK_COMMAND_TEXT, sizeof(*cmd) + (nk_size)(length + 1));
+ if (!cmd) return;
+ cmd->x = (short)r.x;
+ cmd->y = (short)r.y;
+ cmd->w = (unsigned short)r.w;
+ cmd->h = (unsigned short)r.h;
+ cmd->background = bg;
+ cmd->foreground = fg;
+ cmd->font = font;
+ cmd->length = length;
+ cmd->height = font->height;
+ NK_MEMCPY(cmd->string, string, (nk_size)length);
+ cmd->string[length] = '\0';
+}
+
+/* ==============================================================
+ *
+ * DRAW LIST
+ *
+ * ===============================================================*/
+#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+NK_API void
+nk_draw_list_init(struct nk_draw_list *list)
+{
+ nk_size i = 0;
+ NK_ASSERT(list);
+ if (!list) return;
+ nk_zero(list, sizeof(*list));
+ for (i = 0; i < NK_LEN(list->circle_vtx); ++i) {
+ const float a = ((float)i / (float)NK_LEN(list->circle_vtx)) * 2 * NK_PI;
+ list->circle_vtx[i].x = (float)NK_COS(a);
+ list->circle_vtx[i].y = (float)NK_SIN(a);
+ }
+}
+
+NK_API void
+nk_draw_list_setup(struct nk_draw_list *canvas, const struct nk_convert_config *config,
+ struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements,
+ enum nk_anti_aliasing line_aa, enum nk_anti_aliasing shape_aa)
+{
+ NK_ASSERT(canvas);
+ NK_ASSERT(config);
+ NK_ASSERT(cmds);
+ NK_ASSERT(vertices);
+ NK_ASSERT(elements);
+ if (!canvas || !config || !cmds || !vertices || !elements)
+ return;
+
+ canvas->buffer = cmds;
+ canvas->config = *config;
+ canvas->elements = elements;
+ canvas->vertices = vertices;
+ canvas->line_AA = line_aa;
+ canvas->shape_AA = shape_aa;
+ canvas->clip_rect = nk_null_rect;
+}
+
+NK_API const struct nk_draw_command*
+nk__draw_list_begin(const struct nk_draw_list *canvas, const struct nk_buffer *buffer)
+{
+ nk_byte *memory;
+ nk_size offset;
+ const struct nk_draw_command *cmd;
+
+ NK_ASSERT(buffer);
+ if (!buffer || !buffer->size || !canvas->cmd_count)
+ return 0;
+
+ memory = (nk_byte*)buffer->memory.ptr;
+ offset = buffer->memory.size - canvas->cmd_offset;
+ cmd = nk_ptr_add(const struct nk_draw_command, memory, offset);
+ return cmd;
+}
+
+NK_API const struct nk_draw_command*
+nk__draw_list_end(const struct nk_draw_list *canvas, const struct nk_buffer *buffer)
+{
+ nk_size size;
+ nk_size offset;
+ nk_byte *memory;
+ const struct nk_draw_command *end;
+
+ NK_ASSERT(buffer);
+ NK_ASSERT(canvas);
+ if (!buffer || !canvas)
+ return 0;
+
+ memory = (nk_byte*)buffer->memory.ptr;
+ size = buffer->memory.size;
+ offset = size - canvas->cmd_offset;
+ end = nk_ptr_add(const struct nk_draw_command, memory, offset);
+ end -= (canvas->cmd_count-1);
+ return end;
+}
+
+NK_API const struct nk_draw_command*
+nk__draw_list_next(const struct nk_draw_command *cmd,
+ const struct nk_buffer *buffer, const struct nk_draw_list *canvas)
+{
+ const struct nk_draw_command *end;
+ NK_ASSERT(buffer);
+ NK_ASSERT(canvas);
+ if (!cmd || !buffer || !canvas)
+ return 0;
+
+ end = nk__draw_list_end(canvas, buffer);
+ if (cmd <= end) return 0;
+ return (cmd-1);
+}
+
+NK_API void
+nk_draw_list_clear(struct nk_draw_list *list)
+{
+ NK_ASSERT(list);
+ if (!list) return;
+ if (list->buffer)
+ nk_buffer_clear(list->buffer);
+ if (list->vertices)
+ nk_buffer_clear(list->vertices);
+ if (list->elements)
+ nk_buffer_clear(list->elements);
+
+ list->element_count = 0;
+ list->vertex_count = 0;
+ list->cmd_offset = 0;
+ list->cmd_count = 0;
+ list->path_count = 0;
+ list->vertices = 0;
+ list->elements = 0;
+ list->clip_rect = nk_null_rect;
+}
+
+NK_INTERN struct nk_vec2*
+nk_draw_list_alloc_path(struct nk_draw_list *list, int count)
+{
+ struct nk_vec2 *points;
+ NK_STORAGE const nk_size point_align = NK_ALIGNOF(struct nk_vec2);
+ NK_STORAGE const nk_size point_size = sizeof(struct nk_vec2);
+ points = (struct nk_vec2*)
+ nk_buffer_alloc(list->buffer, NK_BUFFER_FRONT,
+ point_size * (nk_size)count, point_align);
+
+ if (!points) return 0;
+ if (!list->path_offset) {
+ void *memory = nk_buffer_memory(list->buffer);
+ list->path_offset = (unsigned int)((nk_byte*)points - (nk_byte*)memory);
+ }
+ list->path_count += (unsigned int)count;
+ return points;
+}
+
+NK_INTERN struct nk_vec2
+nk_draw_list_path_last(struct nk_draw_list *list)
+{
+ void *memory;
+ struct nk_vec2 *point;
+ NK_ASSERT(list->path_count);
+ memory = nk_buffer_memory(list->buffer);
+ point = nk_ptr_add(struct nk_vec2, memory, list->path_offset);
+ point += (list->path_count-1);
+ return *point;
+}
+
+NK_INTERN struct nk_draw_command*
+nk_draw_list_push_command(struct nk_draw_list *list, struct nk_rect clip,
+ nk_handle texture)
+{
+ NK_STORAGE const nk_size cmd_align = NK_ALIGNOF(struct nk_draw_command);
+ NK_STORAGE const nk_size cmd_size = sizeof(struct nk_draw_command);
+ struct nk_draw_command *cmd;
+
+ NK_ASSERT(list);
+ cmd = (struct nk_draw_command*)
+ nk_buffer_alloc(list->buffer, NK_BUFFER_BACK, cmd_size, cmd_align);
+
+ if (!cmd) return 0;
+ if (!list->cmd_count) {
+ nk_byte *memory = (nk_byte*)nk_buffer_memory(list->buffer);
+ nk_size total = nk_buffer_total(list->buffer);
+ memory = nk_ptr_add(nk_byte, memory, total);
+ list->cmd_offset = (nk_size)(memory - (nk_byte*)cmd);
+ }
+
+ cmd->elem_count = 0;
+ cmd->clip_rect = clip;
+ cmd->texture = texture;
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+ cmd->userdata = list->userdata;
+#endif
+
+ list->cmd_count++;
+ list->clip_rect = clip;
+ return cmd;
+}
+
+NK_INTERN struct nk_draw_command*
+nk_draw_list_command_last(struct nk_draw_list *list)
+{
+ void *memory;
+ nk_size size;
+ struct nk_draw_command *cmd;
+ NK_ASSERT(list->cmd_count);
+
+ memory = nk_buffer_memory(list->buffer);
+ size = nk_buffer_total(list->buffer);
+ cmd = nk_ptr_add(struct nk_draw_command, memory, size - list->cmd_offset);
+ return (cmd - (list->cmd_count-1));
+}
+
+NK_INTERN void
+nk_draw_list_add_clip(struct nk_draw_list *list, struct nk_rect rect)
+{
+ NK_ASSERT(list);
+ if (!list) return;
+ if (!list->cmd_count) {
+ nk_draw_list_push_command(list, rect, list->config.null.texture);
+ } else {
+ struct nk_draw_command *prev = nk_draw_list_command_last(list);
+ if (prev->elem_count == 0)
+ prev->clip_rect = rect;
+ nk_draw_list_push_command(list, rect, prev->texture);
+ }
+}
+
+NK_INTERN void
+nk_draw_list_push_image(struct nk_draw_list *list, nk_handle texture)
+{
+ NK_ASSERT(list);
+ if (!list) return;
+ if (!list->cmd_count) {
+ nk_draw_list_push_command(list, nk_null_rect, texture);
+ } else {
+ struct nk_draw_command *prev = nk_draw_list_command_last(list);
+ if (prev->elem_count == 0) {
+ prev->texture = texture;
+ #ifdef NK_INCLUDE_COMMAND_USERDATA
+ prev->userdata = list->userdata;
+ #endif
+ } else if (prev->texture.id != texture.id
+ #ifdef NK_INCLUDE_COMMAND_USERDATA
+ || prev->userdata.id != list->userdata.id
+ #endif
+ ) nk_draw_list_push_command(list, prev->clip_rect, texture);
+ }
+}
+
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+NK_API void
+nk_draw_list_push_userdata(struct nk_draw_list *list, nk_handle userdata)
+{
+ list->userdata = userdata;
+}
+#endif
+
+NK_INTERN void*
+nk_draw_list_alloc_vertices(struct nk_draw_list *list, nk_size count)
+{
+ void *vtx;
+ NK_ASSERT(list);
+ if (!list) return 0;
+ vtx = nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT,
+ list->config.vertex_size*count, list->config.vertex_alignment);
+ if (!vtx) return 0;
+ list->vertex_count += (unsigned int)count;
+ return vtx;
+}
+
+NK_INTERN nk_draw_index*
+nk_draw_list_alloc_elements(struct nk_draw_list *list, nk_size count)
+{
+ nk_draw_index *ids;
+ struct nk_draw_command *cmd;
+ NK_STORAGE const nk_size elem_align = NK_ALIGNOF(nk_draw_index);
+ NK_STORAGE const nk_size elem_size = sizeof(nk_draw_index);
+ NK_ASSERT(list);
+ if (!list) return 0;
+
+ ids = (nk_draw_index*)
+ nk_buffer_alloc(list->elements, NK_BUFFER_FRONT, elem_size*count, elem_align);
+ if (!ids) return 0;
+ cmd = nk_draw_list_command_last(list);
+ list->element_count += (unsigned int)count;
+ cmd->elem_count += (unsigned int)count;
+ return ids;
+}
+
+NK_INTERN int
+nk_draw_vertex_layout_element_is_end_of_layout(
+ const struct nk_draw_vertex_layout_element *element)
+{
+ return (element->attribute == NK_VERTEX_ATTRIBUTE_COUNT ||
+ element->format == NK_FORMAT_COUNT);
+}
+
+NK_INTERN void
+nk_draw_vertex_color(void *attr, const float *vals,
+ enum nk_draw_vertex_layout_format format)
+{
+ /* if this triggers you tried to provide a value format for a color */
+ float val[4];
+ NK_ASSERT(format >= NK_FORMAT_COLOR_BEGIN);
+ NK_ASSERT(format <= NK_FORMAT_COLOR_END);
+ if (format < NK_FORMAT_COLOR_BEGIN || format > NK_FORMAT_COLOR_END) return;
+
+ val[0] = NK_SATURATE(vals[0]);
+ val[1] = NK_SATURATE(vals[1]);
+ val[2] = NK_SATURATE(vals[2]);
+ val[3] = NK_SATURATE(vals[3]);
+
+ switch (format) {
+ default: NK_ASSERT(0 && "Invalid vertex layout color format"); break;
+ case NK_FORMAT_R8G8B8A8:
+ case NK_FORMAT_R8G8B8: {
+ struct nk_color col = nk_rgba_fv(val);
+ NK_MEMCPY(attr, &col.r, sizeof(col));
+ } break;
+ case NK_FORMAT_B8G8R8A8: {
+ struct nk_color col = nk_rgba_fv(val);
+ struct nk_color bgra = nk_rgba(col.b, col.g, col.r, col.a);
+ NK_MEMCPY(attr, &bgra, sizeof(bgra));
+ } break;
+ case NK_FORMAT_R16G15B16: {
+ nk_ushort col[3];
+ col[0] = (nk_ushort)(val[0]*(float)NK_USHORT_MAX);
+ col[1] = (nk_ushort)(val[1]*(float)NK_USHORT_MAX);
+ col[2] = (nk_ushort)(val[2]*(float)NK_USHORT_MAX);
+ NK_MEMCPY(attr, col, sizeof(col));
+ } break;
+ case NK_FORMAT_R16G15B16A16: {
+ nk_ushort col[4];
+ col[0] = (nk_ushort)(val[0]*(float)NK_USHORT_MAX);
+ col[1] = (nk_ushort)(val[1]*(float)NK_USHORT_MAX);
+ col[2] = (nk_ushort)(val[2]*(float)NK_USHORT_MAX);
+ col[3] = (nk_ushort)(val[3]*(float)NK_USHORT_MAX);
+ NK_MEMCPY(attr, col, sizeof(col));
+ } break;
+ case NK_FORMAT_R32G32B32: {
+ nk_uint col[3];
+ col[0] = (nk_uint)(val[0]*(float)NK_UINT_MAX);
+ col[1] = (nk_uint)(val[1]*(float)NK_UINT_MAX);
+ col[2] = (nk_uint)(val[2]*(float)NK_UINT_MAX);
+ NK_MEMCPY(attr, col, sizeof(col));
+ } break;
+ case NK_FORMAT_R32G32B32A32: {
+ nk_uint col[4];
+ col[0] = (nk_uint)(val[0]*(float)NK_UINT_MAX);
+ col[1] = (nk_uint)(val[1]*(float)NK_UINT_MAX);
+ col[2] = (nk_uint)(val[2]*(float)NK_UINT_MAX);
+ col[3] = (nk_uint)(val[3]*(float)NK_UINT_MAX);
+ NK_MEMCPY(attr, col, sizeof(col));
+ } break;
+ case NK_FORMAT_R32G32B32A32_FLOAT:
+ NK_MEMCPY(attr, val, sizeof(float)*4);
+ break;
+ case NK_FORMAT_R32G32B32A32_DOUBLE: {
+ double col[4];
+ col[0] = (double)val[0];
+ col[1] = (double)val[1];
+ col[2] = (double)val[2];
+ col[3] = (double)val[3];
+ NK_MEMCPY(attr, col, sizeof(col));
+ } break;
+ case NK_FORMAT_RGB32:
+ case NK_FORMAT_RGBA32: {
+ struct nk_color col = nk_rgba_fv(val);
+ nk_uint color = nk_color_u32(col);
+ NK_MEMCPY(attr, &color, sizeof(color));
+ } break; }
+}
+
+NK_INTERN void
+nk_draw_vertex_element(void *dst, const float *values, int value_count,
+ enum nk_draw_vertex_layout_format format)
+{
+ int value_index;
+ void *attribute = dst;
+ /* if this triggers you tried to provide a color format for a value */
+ NK_ASSERT(format < NK_FORMAT_COLOR_BEGIN);
+ if (format >= NK_FORMAT_COLOR_BEGIN && format <= NK_FORMAT_COLOR_END) return;
+ for (value_index = 0; value_index < value_count; ++value_index) {
+ switch (format) {
+ default: NK_ASSERT(0 && "invalid vertex layout format"); break;
+ case NK_FORMAT_SCHAR: {
+ char value = (char)NK_CLAMP((float)NK_SCHAR_MIN, values[value_index], (float)NK_SCHAR_MAX);
+ NK_MEMCPY(attribute, &value, sizeof(value));
+ attribute = (void*)((char*)attribute + sizeof(char));
+ } break;
+ case NK_FORMAT_SSHORT: {
+ nk_short value = (nk_short)NK_CLAMP((float)NK_SSHORT_MIN, values[value_index], (float)NK_SSHORT_MAX);
+ NK_MEMCPY(attribute, &value, sizeof(value));
+ attribute = (void*)((char*)attribute + sizeof(value));
+ } break;
+ case NK_FORMAT_SINT: {
+ nk_int value = (nk_int)NK_CLAMP((float)NK_SINT_MIN, values[value_index], (float)NK_SINT_MAX);
+ NK_MEMCPY(attribute, &value, sizeof(value));
+ attribute = (void*)((char*)attribute + sizeof(nk_int));
+ } break;
+ case NK_FORMAT_UCHAR: {
+ unsigned char value = (unsigned char)NK_CLAMP((float)NK_UCHAR_MIN, values[value_index], (float)NK_UCHAR_MAX);
+ NK_MEMCPY(attribute, &value, sizeof(value));
+ attribute = (void*)((char*)attribute + sizeof(unsigned char));
+ } break;
+ case NK_FORMAT_USHORT: {
+ nk_ushort value = (nk_ushort)NK_CLAMP((float)NK_USHORT_MIN, values[value_index], (float)NK_USHORT_MAX);
+ NK_MEMCPY(attribute, &value, sizeof(value));
+ attribute = (void*)((char*)attribute + sizeof(value));
+ } break;
+ case NK_FORMAT_UINT: {
+ nk_uint value = (nk_uint)NK_CLAMP((float)NK_UINT_MIN, values[value_index], (float)NK_UINT_MAX);
+ NK_MEMCPY(attribute, &value, sizeof(value));
+ attribute = (void*)((char*)attribute + sizeof(nk_uint));
+ } break;
+ case NK_FORMAT_FLOAT:
+ NK_MEMCPY(attribute, &values[value_index], sizeof(values[value_index]));
+ attribute = (void*)((char*)attribute + sizeof(float));
+ break;
+ case NK_FORMAT_DOUBLE: {
+ double value = (double)values[value_index];
+ NK_MEMCPY(attribute, &value, sizeof(value));
+ attribute = (void*)((char*)attribute + sizeof(double));
+ } break;
+ }
+ }
+}
+
+NK_INTERN void*
+nk_draw_vertex(void *dst, const struct nk_convert_config *config,
+ struct nk_vec2 pos, struct nk_vec2 uv, struct nk_colorf color)
+{
+ void *result = (void*)((char*)dst + config->vertex_size);
+ const struct nk_draw_vertex_layout_element *elem_iter = config->vertex_layout;
+ while (!nk_draw_vertex_layout_element_is_end_of_layout(elem_iter)) {
+ void *address = (void*)((char*)dst + elem_iter->offset);
+ switch (elem_iter->attribute) {
+ case NK_VERTEX_ATTRIBUTE_COUNT:
+ default: NK_ASSERT(0 && "wrong element attribute"); break;
+ case NK_VERTEX_POSITION: nk_draw_vertex_element(address, &pos.x, 2, elem_iter->format); break;
+ case NK_VERTEX_TEXCOORD: nk_draw_vertex_element(address, &uv.x, 2, elem_iter->format); break;
+ case NK_VERTEX_COLOR: nk_draw_vertex_color(address, &color.r, elem_iter->format); break;
+ }
+ elem_iter++;
+ }
+ return result;
+}
+
+NK_API void
+nk_draw_list_stroke_poly_line(struct nk_draw_list *list, const struct nk_vec2 *points,
+ const unsigned int points_count, struct nk_color color, enum nk_draw_list_stroke closed,
+ float thickness, enum nk_anti_aliasing aliasing)
+{
+ nk_size count;
+ int thick_line;
+ struct nk_colorf col;
+ struct nk_colorf col_trans;
+ NK_ASSERT(list);
+ if (!list || points_count < 2) return;
+
+ color.a = (nk_byte)((float)color.a * list->config.global_alpha);
+ count = points_count;
+ if (!closed) count = points_count-1;
+ thick_line = thickness > 1.0f;
+
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+ nk_draw_list_push_userdata(list, list->userdata);
+#endif
+
+ color.a = (nk_byte)((float)color.a * list->config.global_alpha);
+ nk_color_fv(&col.r, color);
+ col_trans = col;
+ col_trans.a = 0;
+
+ if (aliasing == NK_ANTI_ALIASING_ON) {
+ /* ANTI-ALIASED STROKE */
+ const float AA_SIZE = 1.0f;
+ NK_STORAGE const nk_size pnt_align = NK_ALIGNOF(struct nk_vec2);
+ NK_STORAGE const nk_size pnt_size = sizeof(struct nk_vec2);
+
+ /* allocate vertices and elements */
+ nk_size i1 = 0;
+ nk_size vertex_offset;
+ nk_size index = list->vertex_count;
+
+ const nk_size idx_count = (thick_line) ? (count * 18) : (count * 12);
+ const nk_size vtx_count = (thick_line) ? (points_count * 4): (points_count *3);
+
+ void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
+ nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
+
+ nk_size size;
+ struct nk_vec2 *normals, *temp;
+ if (!vtx || !ids) return;
+
+ /* temporary allocate normals + points */
+ vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr);
+ nk_buffer_mark(list->vertices, NK_BUFFER_FRONT);
+ size = pnt_size * ((thick_line) ? 5 : 3) * points_count;
+ normals = (struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align);
+ NK_ASSERT(normals);
+ if (!normals) return;
+ temp = normals + points_count;
+
+ /* make sure vertex pointer is still correct */
+ vtx = (void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset);
+
+ /* calculate normals */
+ for (i1 = 0; i1 < count; ++i1) {
+ const nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
+ struct nk_vec2 diff = nk_vec2_sub(points[i2], points[i1]);
+ float len;
+
+ /* vec2 inverted length */
+ len = nk_vec2_len_sqr(diff);
+ if (len != 0.0f)
+ len = nk_inv_sqrt(len);
+ else len = 1.0f;
+
+ diff = nk_vec2_muls(diff, len);
+ normals[i1].x = diff.y;
+ normals[i1].y = -diff.x;
+ }
+
+ if (!closed)
+ normals[points_count-1] = normals[points_count-2];
+
+ if (!thick_line) {
+ nk_size idx1, i;
+ if (!closed) {
+ struct nk_vec2 d;
+ temp[0] = nk_vec2_add(points[0], nk_vec2_muls(normals[0], AA_SIZE));
+ temp[1] = nk_vec2_sub(points[0], nk_vec2_muls(normals[0], AA_SIZE));
+ d = nk_vec2_muls(normals[points_count-1], AA_SIZE);
+ temp[(points_count-1) * 2 + 0] = nk_vec2_add(points[points_count-1], d);
+ temp[(points_count-1) * 2 + 1] = nk_vec2_sub(points[points_count-1], d);
+ }
+
+ /* fill elements */
+ idx1 = index;
+ for (i1 = 0; i1 < count; i1++) {
+ struct nk_vec2 dm;
+ float dmr2;
+ nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1);
+ nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 3);
+
+ /* average normals */
+ dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f);
+ dmr2 = dm.x * dm.x + dm.y* dm.y;
+ if (dmr2 > 0.000001f) {
+ float scale = 1.0f/dmr2;
+ scale = NK_MIN(100.0f, scale);
+ dm = nk_vec2_muls(dm, scale);
+ }
+
+ dm = nk_vec2_muls(dm, AA_SIZE);
+ temp[i2*2+0] = nk_vec2_add(points[i2], dm);
+ temp[i2*2+1] = nk_vec2_sub(points[i2], dm);
+
+ ids[0] = (nk_draw_index)(idx2 + 0); ids[1] = (nk_draw_index)(idx1+0);
+ ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
+ ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+0);
+ ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
+ ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
+ ids[10]= (nk_draw_index)(idx2 + 0); ids[11]= (nk_draw_index)(idx2+1);
+ ids += 12;
+ idx1 = idx2;
+ }
+
+ /* fill vertices */
+ for (i = 0; i < points_count; ++i) {
+ const struct nk_vec2 uv = list->config.null.uv;
+ vtx = nk_draw_vertex(vtx, &list->config, points[i], uv, col);
+ vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+0], uv, col_trans);
+ vtx = nk_draw_vertex(vtx, &list->config, temp[i*2+1], uv, col_trans);
+ }
+ } else {
+ nk_size idx1, i;
+ const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f;
+ if (!closed) {
+ struct nk_vec2 d1 = nk_vec2_muls(normals[0], half_inner_thickness + AA_SIZE);
+ struct nk_vec2 d2 = nk_vec2_muls(normals[0], half_inner_thickness);
+
+ temp[0] = nk_vec2_add(points[0], d1);
+ temp[1] = nk_vec2_add(points[0], d2);
+ temp[2] = nk_vec2_sub(points[0], d2);
+ temp[3] = nk_vec2_sub(points[0], d1);
+
+ d1 = nk_vec2_muls(normals[points_count-1], half_inner_thickness + AA_SIZE);
+ d2 = nk_vec2_muls(normals[points_count-1], half_inner_thickness);
+
+ temp[(points_count-1)*4+0] = nk_vec2_add(points[points_count-1], d1);
+ temp[(points_count-1)*4+1] = nk_vec2_add(points[points_count-1], d2);
+ temp[(points_count-1)*4+2] = nk_vec2_sub(points[points_count-1], d2);
+ temp[(points_count-1)*4+3] = nk_vec2_sub(points[points_count-1], d1);
+ }
+
+ /* add all elements */
+ idx1 = index;
+ for (i1 = 0; i1 < count; ++i1) {
+ struct nk_vec2 dm_out, dm_in;
+ const nk_size i2 = ((i1+1) == points_count) ? 0: (i1 + 1);
+ nk_size idx2 = ((i1+1) == points_count) ? index: (idx1 + 4);
+
+ /* average normals */
+ struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f);
+ float dmr2 = dm.x * dm.x + dm.y* dm.y;
+ if (dmr2 > 0.000001f) {
+ float scale = 1.0f/dmr2;
+ scale = NK_MIN(100.0f, scale);
+ dm = nk_vec2_muls(dm, scale);
+ }
+
+ dm_out = nk_vec2_muls(dm, ((half_inner_thickness) + AA_SIZE));
+ dm_in = nk_vec2_muls(dm, half_inner_thickness);
+ temp[i2*4+0] = nk_vec2_add(points[i2], dm_out);
+ temp[i2*4+1] = nk_vec2_add(points[i2], dm_in);
+ temp[i2*4+2] = nk_vec2_sub(points[i2], dm_in);
+ temp[i2*4+3] = nk_vec2_sub(points[i2], dm_out);
+
+ /* add indexes */
+ ids[0] = (nk_draw_index)(idx2 + 1); ids[1] = (nk_draw_index)(idx1+1);
+ ids[2] = (nk_draw_index)(idx1 + 2); ids[3] = (nk_draw_index)(idx1+2);
+ ids[4] = (nk_draw_index)(idx2 + 2); ids[5] = (nk_draw_index)(idx2+1);
+ ids[6] = (nk_draw_index)(idx2 + 1); ids[7] = (nk_draw_index)(idx1+1);
+ ids[8] = (nk_draw_index)(idx1 + 0); ids[9] = (nk_draw_index)(idx1+0);
+ ids[10]= (nk_draw_index)(idx2 + 0); ids[11] = (nk_draw_index)(idx2+1);
+ ids[12]= (nk_draw_index)(idx2 + 2); ids[13] = (nk_draw_index)(idx1+2);
+ ids[14]= (nk_draw_index)(idx1 + 3); ids[15] = (nk_draw_index)(idx1+3);
+ ids[16]= (nk_draw_index)(idx2 + 3); ids[17] = (nk_draw_index)(idx2+2);
+ ids += 18;
+ idx1 = idx2;
+ }
+
+ /* add vertices */
+ for (i = 0; i < points_count; ++i) {
+ const struct nk_vec2 uv = list->config.null.uv;
+ vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+0], uv, col_trans);
+ vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+1], uv, col);
+ vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+2], uv, col);
+ vtx = nk_draw_vertex(vtx, &list->config, temp[i*4+3], uv, col_trans);
+ }
+ }
+ /* free temporary normals + points */
+ nk_buffer_reset(list->vertices, NK_BUFFER_FRONT);
+ } else {
+ /* NON ANTI-ALIASED STROKE */
+ nk_size i1 = 0;
+ nk_size idx = list->vertex_count;
+ const nk_size idx_count = count * 6;
+ const nk_size vtx_count = count * 4;
+ void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
+ nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
+ if (!vtx || !ids) return;
+
+ for (i1 = 0; i1 < count; ++i1) {
+ float dx, dy;
+ const struct nk_vec2 uv = list->config.null.uv;
+ const nk_size i2 = ((i1+1) == points_count) ? 0 : i1 + 1;
+ const struct nk_vec2 p1 = points[i1];
+ const struct nk_vec2 p2 = points[i2];
+ struct nk_vec2 diff = nk_vec2_sub(p2, p1);
+ float len;
+
+ /* vec2 inverted length */
+ len = nk_vec2_len_sqr(diff);
+ if (len != 0.0f)
+ len = nk_inv_sqrt(len);
+ else len = 1.0f;
+ diff = nk_vec2_muls(diff, len);
+
+ /* add vertices */
+ dx = diff.x * (thickness * 0.5f);
+ dy = diff.y * (thickness * 0.5f);
+
+ vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p1.x + dy, p1.y - dx), uv, col);
+ vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p2.x + dy, p2.y - dx), uv, col);
+ vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p2.x - dy, p2.y + dx), uv, col);
+ vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p1.x - dy, p1.y + dx), uv, col);
+
+ ids[0] = (nk_draw_index)(idx+0); ids[1] = (nk_draw_index)(idx+1);
+ ids[2] = (nk_draw_index)(idx+2); ids[3] = (nk_draw_index)(idx+0);
+ ids[4] = (nk_draw_index)(idx+2); ids[5] = (nk_draw_index)(idx+3);
+
+ ids += 6;
+ idx += 4;
+ }
+ }
+}
+
+NK_API void
+nk_draw_list_fill_poly_convex(struct nk_draw_list *list,
+ const struct nk_vec2 *points, const unsigned int points_count,
+ struct nk_color color, enum nk_anti_aliasing aliasing)
+{
+ struct nk_colorf col;
+ struct nk_colorf col_trans;
+
+ NK_STORAGE const nk_size pnt_align = NK_ALIGNOF(struct nk_vec2);
+ NK_STORAGE const nk_size pnt_size = sizeof(struct nk_vec2);
+ NK_ASSERT(list);
+ if (!list || points_count < 3) return;
+
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+ nk_draw_list_push_userdata(list, list->userdata);
+#endif
+
+ color.a = (nk_byte)((float)color.a * list->config.global_alpha);
+ nk_color_fv(&col.r, color);
+ col_trans = col;
+ col_trans.a = 0;
+
+ if (aliasing == NK_ANTI_ALIASING_ON) {
+ nk_size i = 0;
+ nk_size i0 = 0;
+ nk_size i1 = 0;
+
+ const float AA_SIZE = 1.0f;
+ nk_size vertex_offset = 0;
+ nk_size index = list->vertex_count;
+
+ const nk_size idx_count = (points_count-2)*3 + points_count*6;
+ const nk_size vtx_count = (points_count*2);
+
+ void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
+ nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
+
+ nk_size size = 0;
+ struct nk_vec2 *normals = 0;
+ unsigned int vtx_inner_idx = (unsigned int)(index + 0);
+ unsigned int vtx_outer_idx = (unsigned int)(index + 1);
+ if (!vtx || !ids) return;
+
+ /* temporary allocate normals */
+ vertex_offset = (nk_size)((nk_byte*)vtx - (nk_byte*)list->vertices->memory.ptr);
+ nk_buffer_mark(list->vertices, NK_BUFFER_FRONT);
+ size = pnt_size * points_count;
+ normals = (struct nk_vec2*) nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align);
+ NK_ASSERT(normals);
+ if (!normals) return;
+ vtx = (void*)((nk_byte*)list->vertices->memory.ptr + vertex_offset);
+
+ /* add elements */
+ for (i = 2; i < points_count; i++) {
+ ids[0] = (nk_draw_index)(vtx_inner_idx);
+ ids[1] = (nk_draw_index)(vtx_inner_idx + ((i-1) << 1));
+ ids[2] = (nk_draw_index)(vtx_inner_idx + (i << 1));
+ ids += 3;
+ }
+
+ /* compute normals */
+ for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
+ struct nk_vec2 p0 = points[i0];
+ struct nk_vec2 p1 = points[i1];
+ struct nk_vec2 diff = nk_vec2_sub(p1, p0);
+
+ /* vec2 inverted length */
+ float len = nk_vec2_len_sqr(diff);
+ if (len != 0.0f)
+ len = nk_inv_sqrt(len);
+ else len = 1.0f;
+ diff = nk_vec2_muls(diff, len);
+
+ normals[i0].x = diff.y;
+ normals[i0].y = -diff.x;
+ }
+
+ /* add vertices + indexes */
+ for (i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) {
+ const struct nk_vec2 uv = list->config.null.uv;
+ struct nk_vec2 n0 = normals[i0];
+ struct nk_vec2 n1 = normals[i1];
+ struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(n0, n1), 0.5f);
+ float dmr2 = dm.x*dm.x + dm.y*dm.y;
+ if (dmr2 > 0.000001f) {
+ float scale = 1.0f / dmr2;
+ scale = NK_MIN(scale, 100.0f);
+ dm = nk_vec2_muls(dm, scale);
+ }
+ dm = nk_vec2_muls(dm, AA_SIZE * 0.5f);
+
+ /* add vertices */
+ vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_sub(points[i1], dm), uv, col);
+ vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_add(points[i1], dm), uv, col_trans);
+
+ /* add indexes */
+ ids[0] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
+ ids[1] = (nk_draw_index)(vtx_inner_idx+(i0<<1));
+ ids[2] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
+ ids[3] = (nk_draw_index)(vtx_outer_idx+(i0<<1));
+ ids[4] = (nk_draw_index)(vtx_outer_idx+(i1<<1));
+ ids[5] = (nk_draw_index)(vtx_inner_idx+(i1<<1));
+ ids += 6;
+ }
+ /* free temporary normals + points */
+ nk_buffer_reset(list->vertices, NK_BUFFER_FRONT);
+ } else {
+ nk_size i = 0;
+ nk_size index = list->vertex_count;
+ const nk_size idx_count = (points_count-2)*3;
+ const nk_size vtx_count = points_count;
+ void *vtx = nk_draw_list_alloc_vertices(list, vtx_count);
+ nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count);
+
+ if (!vtx || !ids) return;
+ for (i = 0; i < vtx_count; ++i)
+ vtx = nk_draw_vertex(vtx, &list->config, points[i], list->config.null.uv, col);
+ for (i = 2; i < points_count; ++i) {
+ ids[0] = (nk_draw_index)index;
+ ids[1] = (nk_draw_index)(index+ i - 1);
+ ids[2] = (nk_draw_index)(index+i);
+ ids += 3;
+ }
+ }
+}
+
+NK_API void
+nk_draw_list_path_clear(struct nk_draw_list *list)
+{
+ NK_ASSERT(list);
+ if (!list) return;
+ nk_buffer_reset(list->buffer, NK_BUFFER_FRONT);
+ list->path_count = 0;
+ list->path_offset = 0;
+}
+
+NK_API void
+nk_draw_list_path_line_to(struct nk_draw_list *list, struct nk_vec2 pos)
+{
+ struct nk_vec2 *points = 0;
+ struct nk_draw_command *cmd = 0;
+ NK_ASSERT(list);
+ if (!list) return;
+ if (!list->cmd_count)
+ nk_draw_list_add_clip(list, nk_null_rect);
+
+ cmd = nk_draw_list_command_last(list);
+ if (cmd && cmd->texture.ptr != list->config.null.texture.ptr)
+ nk_draw_list_push_image(list, list->config.null.texture);
+
+ points = nk_draw_list_alloc_path(list, 1);
+ if (!points) return;
+ points[0] = pos;
+}
+
+NK_API void
+nk_draw_list_path_arc_to_fast(struct nk_draw_list *list, struct nk_vec2 center,
+ float radius, int a_min, int a_max)
+{
+ int a = 0;
+ NK_ASSERT(list);
+ if (!list) return;
+ if (a_min <= a_max) {
+ for (a = a_min; a <= a_max; a++) {
+ const struct nk_vec2 c = list->circle_vtx[(nk_size)a % NK_LEN(list->circle_vtx)];
+ const float x = center.x + c.x * radius;
+ const float y = center.y + c.y * radius;
+ nk_draw_list_path_line_to(list, nk_vec2(x, y));
+ }
+ }
+}
+
+NK_API void
+nk_draw_list_path_arc_to(struct nk_draw_list *list, struct nk_vec2 center,
+ float radius, float a_min, float a_max, unsigned int segments)
+{
+ unsigned int i = 0;
+ NK_ASSERT(list);
+ if (!list) return;
+ if (radius == 0.0f) return;
+
+ /* This algorithm for arc drawing relies on these two trigonometric identities[1]:
+ sin(a + b) = sin(a) * cos(b) + cos(a) * sin(b)
+ cos(a + b) = cos(a) * cos(b) - sin(a) * sin(b)
+
+ Two coordinates (x, y) of a point on a circle centered on
+ the origin can be written in polar form as:
+ x = r * cos(a)
+ y = r * sin(a)
+ where r is the radius of the circle,
+ a is the angle between (x, y) and the origin.
+
+ This allows us to rotate the coordinates around the
+ origin by an angle b using the following transformation:
+ x' = r * cos(a + b) = x * cos(b) - y * sin(b)
+ y' = r * sin(a + b) = y * cos(b) + x * sin(b)
+
+ [1] https://en.wikipedia.org/wiki/List_of_trigonometric_identities#Angle_sum_and_difference_identities
+ */
+ {const float d_angle = (a_max - a_min) / (float)segments;
+ const float sin_d = (float)NK_SIN(d_angle);
+ const float cos_d = (float)NK_COS(d_angle);
+
+ float cx = (float)NK_COS(a_min) * radius;
+ float cy = (float)NK_SIN(a_min) * radius;
+ for(i = 0; i <= segments; ++i) {
+ float new_cx, new_cy;
+ const float x = center.x + cx;
+ const float y = center.y + cy;
+ nk_draw_list_path_line_to(list, nk_vec2(x, y));
+
+ new_cx = cx * cos_d - cy * sin_d;
+ new_cy = cy * cos_d + cx * sin_d;
+ cx = new_cx;
+ cy = new_cy;
+ }}
+}
+
+NK_API void
+nk_draw_list_path_rect_to(struct nk_draw_list *list, struct nk_vec2 a,
+ struct nk_vec2 b, float rounding)
+{
+ float r;
+ NK_ASSERT(list);
+ if (!list) return;
+ r = rounding;
+ r = NK_MIN(r, ((b.x-a.x) < 0) ? -(b.x-a.x): (b.x-a.x));
+ r = NK_MIN(r, ((b.y-a.y) < 0) ? -(b.y-a.y): (b.y-a.y));
+
+ if (r == 0.0f) {
+ nk_draw_list_path_line_to(list, a);
+ nk_draw_list_path_line_to(list, nk_vec2(b.x,a.y));
+ nk_draw_list_path_line_to(list, b);
+ nk_draw_list_path_line_to(list, nk_vec2(a.x,b.y));
+ } else {
+ nk_draw_list_path_arc_to_fast(list, nk_vec2(a.x + r, a.y + r), r, 6, 9);
+ nk_draw_list_path_arc_to_fast(list, nk_vec2(b.x - r, a.y + r), r, 9, 12);
+ nk_draw_list_path_arc_to_fast(list, nk_vec2(b.x - r, b.y - r), r, 0, 3);
+ nk_draw_list_path_arc_to_fast(list, nk_vec2(a.x + r, b.y - r), r, 3, 6);
+ }
+}
+
+NK_API void
+nk_draw_list_path_curve_to(struct nk_draw_list *list, struct nk_vec2 p2,
+ struct nk_vec2 p3, struct nk_vec2 p4, unsigned int num_segments)
+{
+ float t_step;
+ unsigned int i_step;
+ struct nk_vec2 p1;
+
+ NK_ASSERT(list);
+ NK_ASSERT(list->path_count);
+ if (!list || !list->path_count) return;
+ num_segments = NK_MAX(num_segments, 1);
+
+ p1 = nk_draw_list_path_last(list);
+ t_step = 1.0f/(float)num_segments;
+ for (i_step = 1; i_step <= num_segments; ++i_step) {
+ float t = t_step * (float)i_step;
+ float u = 1.0f - t;
+ float w1 = u*u*u;
+ float w2 = 3*u*u*t;
+ float w3 = 3*u*t*t;
+ float w4 = t * t *t;
+ float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x;
+ float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y;
+ nk_draw_list_path_line_to(list, nk_vec2(x,y));
+ }
+}
+
+NK_API void
+nk_draw_list_path_fill(struct nk_draw_list *list, struct nk_color color)
+{
+ struct nk_vec2 *points;
+ NK_ASSERT(list);
+ if (!list) return;
+ points = (struct nk_vec2*)nk_buffer_memory(list->buffer);
+ nk_draw_list_fill_poly_convex(list, points, list->path_count, color, list->config.shape_AA);
+ nk_draw_list_path_clear(list);
+}
+
+NK_API void
+nk_draw_list_path_stroke(struct nk_draw_list *list, struct nk_color color,
+ enum nk_draw_list_stroke closed, float thickness)
+{
+ struct nk_vec2 *points;
+ NK_ASSERT(list);
+ if (!list) return;
+ points = (struct nk_vec2*)nk_buffer_memory(list->buffer);
+ nk_draw_list_stroke_poly_line(list, points, list->path_count, color,
+ closed, thickness, list->config.line_AA);
+ nk_draw_list_path_clear(list);
+}
+
+NK_API void
+nk_draw_list_stroke_line(struct nk_draw_list *list, struct nk_vec2 a,
+ struct nk_vec2 b, struct nk_color col, float thickness)
+{
+ NK_ASSERT(list);
+ if (!list || !col.a) return;
+ if (list->line_AA == NK_ANTI_ALIASING_ON) {
+ nk_draw_list_path_line_to(list, a);
+ nk_draw_list_path_line_to(list, b);
+ } else {
+ nk_draw_list_path_line_to(list, nk_vec2_sub(a,nk_vec2(0.5f,0.5f)));
+ nk_draw_list_path_line_to(list, nk_vec2_sub(b,nk_vec2(0.5f,0.5f)));
+ }
+ nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
+}
+
+NK_API void
+nk_draw_list_fill_rect(struct nk_draw_list *list, struct nk_rect rect,
+ struct nk_color col, float rounding)
+{
+ NK_ASSERT(list);
+ if (!list || !col.a) return;
+
+ if (list->line_AA == NK_ANTI_ALIASING_ON) {
+ nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y),
+ nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
+ } else {
+ nk_draw_list_path_rect_to(list, nk_vec2(rect.x-0.5f, rect.y-0.5f),
+ nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
+ } nk_draw_list_path_fill(list, col);
+}
+
+NK_API void
+nk_draw_list_stroke_rect(struct nk_draw_list *list, struct nk_rect rect,
+ struct nk_color col, float rounding, float thickness)
+{
+ NK_ASSERT(list);
+ if (!list || !col.a) return;
+ if (list->line_AA == NK_ANTI_ALIASING_ON) {
+ nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y),
+ nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
+ } else {
+ nk_draw_list_path_rect_to(list, nk_vec2(rect.x-0.5f, rect.y-0.5f),
+ nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding);
+ } nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
+}
+
+NK_API void
+nk_draw_list_fill_rect_multi_color(struct nk_draw_list *list, struct nk_rect rect,
+ struct nk_color left, struct nk_color top, struct nk_color right,
+ struct nk_color bottom)
+{
+ void *vtx;
+ struct nk_colorf col_left, col_top;
+ struct nk_colorf col_right, col_bottom;
+ nk_draw_index *idx;
+ nk_draw_index index;
+
+ nk_color_fv(&col_left.r, left);
+ nk_color_fv(&col_right.r, right);
+ nk_color_fv(&col_top.r, top);
+ nk_color_fv(&col_bottom.r, bottom);
+
+ NK_ASSERT(list);
+ if (!list) return;
+
+ nk_draw_list_push_image(list, list->config.null.texture);
+ index = (nk_draw_index)list->vertex_count;
+ vtx = nk_draw_list_alloc_vertices(list, 4);
+ idx = nk_draw_list_alloc_elements(list, 6);
+ if (!vtx || !idx) return;
+
+ idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
+ idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
+ idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
+
+ vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y), list->config.null.uv, col_left);
+ vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y), list->config.null.uv, col_top);
+ vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y + rect.h), list->config.null.uv, col_right);
+ vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y + rect.h), list->config.null.uv, col_bottom);
+}
+
+NK_API void
+nk_draw_list_fill_triangle(struct nk_draw_list *list, struct nk_vec2 a,
+ struct nk_vec2 b, struct nk_vec2 c, struct nk_color col)
+{
+ NK_ASSERT(list);
+ if (!list || !col.a) return;
+ nk_draw_list_path_line_to(list, a);
+ nk_draw_list_path_line_to(list, b);
+ nk_draw_list_path_line_to(list, c);
+ nk_draw_list_path_fill(list, col);
+}
+
+NK_API void
+nk_draw_list_stroke_triangle(struct nk_draw_list *list, struct nk_vec2 a,
+ struct nk_vec2 b, struct nk_vec2 c, struct nk_color col, float thickness)
+{
+ NK_ASSERT(list);
+ if (!list || !col.a) return;
+ nk_draw_list_path_line_to(list, a);
+ nk_draw_list_path_line_to(list, b);
+ nk_draw_list_path_line_to(list, c);
+ nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
+}
+
+NK_API void
+nk_draw_list_fill_circle(struct nk_draw_list *list, struct nk_vec2 center,
+ float radius, struct nk_color col, unsigned int segs)
+{
+ float a_max;
+ NK_ASSERT(list);
+ if (!list || !col.a) return;
+ a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
+ nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
+ nk_draw_list_path_fill(list, col);
+}
+
+NK_API void
+nk_draw_list_stroke_circle(struct nk_draw_list *list, struct nk_vec2 center,
+ float radius, struct nk_color col, unsigned int segs, float thickness)
+{
+ float a_max;
+ NK_ASSERT(list);
+ if (!list || !col.a) return;
+ a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs;
+ nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs);
+ nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness);
+}
+
+NK_API void
+nk_draw_list_stroke_curve(struct nk_draw_list *list, struct nk_vec2 p0,
+ struct nk_vec2 cp0, struct nk_vec2 cp1, struct nk_vec2 p1,
+ struct nk_color col, unsigned int segments, float thickness)
+{
+ NK_ASSERT(list);
+ if (!list || !col.a) return;
+ nk_draw_list_path_line_to(list, p0);
+ nk_draw_list_path_curve_to(list, cp0, cp1, p1, segments);
+ nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness);
+}
+
+NK_INTERN void
+nk_draw_list_push_rect_uv(struct nk_draw_list *list, struct nk_vec2 a,
+ struct nk_vec2 c, struct nk_vec2 uva, struct nk_vec2 uvc,
+ struct nk_color color)
+{
+ void *vtx;
+ struct nk_vec2 uvb;
+ struct nk_vec2 uvd;
+ struct nk_vec2 b;
+ struct nk_vec2 d;
+
+ struct nk_colorf col;
+ nk_draw_index *idx;
+ nk_draw_index index;
+ NK_ASSERT(list);
+ if (!list) return;
+
+ nk_color_fv(&col.r, color);
+ uvb = nk_vec2(uvc.x, uva.y);
+ uvd = nk_vec2(uva.x, uvc.y);
+ b = nk_vec2(c.x, a.y);
+ d = nk_vec2(a.x, c.y);
+
+ index = (nk_draw_index)list->vertex_count;
+ vtx = nk_draw_list_alloc_vertices(list, 4);
+ idx = nk_draw_list_alloc_elements(list, 6);
+ if (!vtx || !idx) return;
+
+ idx[0] = (nk_draw_index)(index+0); idx[1] = (nk_draw_index)(index+1);
+ idx[2] = (nk_draw_index)(index+2); idx[3] = (nk_draw_index)(index+0);
+ idx[4] = (nk_draw_index)(index+2); idx[5] = (nk_draw_index)(index+3);
+
+ vtx = nk_draw_vertex(vtx, &list->config, a, uva, col);
+ vtx = nk_draw_vertex(vtx, &list->config, b, uvb, col);
+ vtx = nk_draw_vertex(vtx, &list->config, c, uvc, col);
+ vtx = nk_draw_vertex(vtx, &list->config, d, uvd, col);
+}
+
+NK_API void
+nk_draw_list_add_image(struct nk_draw_list *list, struct nk_image texture,
+ struct nk_rect rect, struct nk_color color)
+{
+ NK_ASSERT(list);
+ if (!list) return;
+ /* push new command with given texture */
+ nk_draw_list_push_image(list, texture.handle);
+ if (nk_image_is_subimage(&texture)) {
+ /* add region inside of the texture */
+ struct nk_vec2 uv[2];
+ uv[0].x = (float)texture.region[0]/(float)texture.w;
+ uv[0].y = (float)texture.region[1]/(float)texture.h;
+ uv[1].x = (float)(texture.region[0] + texture.region[2])/(float)texture.w;
+ uv[1].y = (float)(texture.region[1] + texture.region[3])/(float)texture.h;
+ nk_draw_list_push_rect_uv(list, nk_vec2(rect.x, rect.y),
+ nk_vec2(rect.x + rect.w, rect.y + rect.h), uv[0], uv[1], color);
+ } else nk_draw_list_push_rect_uv(list, nk_vec2(rect.x, rect.y),
+ nk_vec2(rect.x + rect.w, rect.y + rect.h),
+ nk_vec2(0.0f, 0.0f), nk_vec2(1.0f, 1.0f),color);
+}
+
+NK_API void
+nk_draw_list_add_text(struct nk_draw_list *list, const struct nk_user_font *font,
+ struct nk_rect rect, const char *text, int len, float font_height,
+ struct nk_color fg)
+{
+ float x = 0;
+ int text_len = 0;
+ nk_rune unicode = 0;
+ nk_rune next = 0;
+ int glyph_len = 0;
+ int next_glyph_len = 0;
+ struct nk_user_font_glyph g;
+
+ NK_ASSERT(list);
+ if (!list || !len || !text) return;
+ if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h,
+ list->clip_rect.x, list->clip_rect.y, list->clip_rect.w, list->clip_rect.h)) return;
+
+ nk_draw_list_push_image(list, font->texture);
+ x = rect.x;
+ glyph_len = nk_utf_decode(text, &unicode, len);
+ if (!glyph_len) return;
+
+ /* draw every glyph image */
+ fg.a = (nk_byte)((float)fg.a * list->config.global_alpha);
+ while (text_len < len && glyph_len) {
+ float gx, gy, gh, gw;
+ float char_width = 0;
+ if (unicode == NK_UTF_INVALID) break;
+
+ /* query currently drawn glyph information */
+ next_glyph_len = nk_utf_decode(text + text_len + glyph_len, &next, (int)len - text_len);
+ font->query(font->userdata, font_height, &g, unicode,
+ (next == NK_UTF_INVALID) ? '\0' : next);
+
+ /* calculate and draw glyph drawing rectangle and image */
+ gx = x + g.offset.x;
+ gy = rect.y + g.offset.y;
+ gw = g.width; gh = g.height;
+ char_width = g.xadvance;
+ nk_draw_list_push_rect_uv(list, nk_vec2(gx,gy), nk_vec2(gx + gw, gy+ gh),
+ g.uv[0], g.uv[1], fg);
+
+ /* offset next glyph */
+ text_len += glyph_len;
+ x += char_width;
+ glyph_len = next_glyph_len;
+ unicode = next;
+ }
+}
+
+NK_API nk_flags
+nk_convert(struct nk_context *ctx, struct nk_buffer *cmds,
+ struct nk_buffer *vertices, struct nk_buffer *elements,
+ const struct nk_convert_config *config)
+{
+ nk_flags res = NK_CONVERT_SUCCESS;
+ const struct nk_command *cmd;
+ NK_ASSERT(ctx);
+ NK_ASSERT(cmds);
+ NK_ASSERT(vertices);
+ NK_ASSERT(elements);
+ NK_ASSERT(config);
+ NK_ASSERT(config->vertex_layout);
+ NK_ASSERT(config->vertex_size);
+ if (!ctx || !cmds || !vertices || !elements || !config || !config->vertex_layout)
+ return NK_CONVERT_INVALID_PARAM;
+
+ nk_draw_list_setup(&ctx->draw_list, config, cmds, vertices, elements,
+ config->line_AA, config->shape_AA);
+ nk_foreach(cmd, ctx)
+ {
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+ ctx->draw_list.userdata = cmd->userdata;
+#endif
+ switch (cmd->type) {
+ case NK_COMMAND_NOP: break;
+ case NK_COMMAND_SCISSOR: {
+ const struct nk_command_scissor *s = (const struct nk_command_scissor*)cmd;
+ nk_draw_list_add_clip(&ctx->draw_list, nk_rect(s->x, s->y, s->w, s->h));
+ } break;
+ case NK_COMMAND_LINE: {
+ const struct nk_command_line *l = (const struct nk_command_line*)cmd;
+ nk_draw_list_stroke_line(&ctx->draw_list, nk_vec2(l->begin.x, l->begin.y),
+ nk_vec2(l->end.x, l->end.y), l->color, l->line_thickness);
+ } break;
+ case NK_COMMAND_CURVE: {
+ const struct nk_command_curve *q = (const struct nk_command_curve*)cmd;
+ nk_draw_list_stroke_curve(&ctx->draw_list, nk_vec2(q->begin.x, q->begin.y),
+ nk_vec2(q->ctrl[0].x, q->ctrl[0].y), nk_vec2(q->ctrl[1].x,
+ q->ctrl[1].y), nk_vec2(q->end.x, q->end.y), q->color,
+ config->curve_segment_count, q->line_thickness);
+ } break;
+ case NK_COMMAND_RECT: {
+ const struct nk_command_rect *r = (const struct nk_command_rect*)cmd;
+ nk_draw_list_stroke_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
+ r->color, (float)r->rounding, r->line_thickness);
+ } break;
+ case NK_COMMAND_RECT_FILLED: {
+ const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled*)cmd;
+ nk_draw_list_fill_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
+ r->color, (float)r->rounding);
+ } break;
+ case NK_COMMAND_RECT_MULTI_COLOR: {
+ const struct nk_command_rect_multi_color *r = (const struct nk_command_rect_multi_color*)cmd;
+ nk_draw_list_fill_rect_multi_color(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h),
+ r->left, r->top, r->right, r->bottom);
+ } break;
+ case NK_COMMAND_CIRCLE: {
+ const struct nk_command_circle *c = (const struct nk_command_circle*)cmd;
+ nk_draw_list_stroke_circle(&ctx->draw_list, nk_vec2((float)c->x + (float)c->w/2,
+ (float)c->y + (float)c->h/2), (float)c->w/2, c->color,
+ config->circle_segment_count, c->line_thickness);
+ } break;
+ case NK_COMMAND_CIRCLE_FILLED: {
+ const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
+ nk_draw_list_fill_circle(&ctx->draw_list, nk_vec2((float)c->x + (float)c->w/2,
+ (float)c->y + (float)c->h/2), (float)c->w/2, c->color,
+ config->circle_segment_count);
+ } break;
+ case NK_COMMAND_ARC: {
+ const struct nk_command_arc *c = (const struct nk_command_arc*)cmd;
+ nk_draw_list_path_line_to(&ctx->draw_list, nk_vec2(c->cx, c->cy));
+ nk_draw_list_path_arc_to(&ctx->draw_list, nk_vec2(c->cx, c->cy), c->r,
+ c->a[0], c->a[1], config->arc_segment_count);
+ nk_draw_list_path_stroke(&ctx->draw_list, c->color, NK_STROKE_CLOSED, c->line_thickness);
+ } break;
+ case NK_COMMAND_ARC_FILLED: {
+ const struct nk_command_arc_filled *c = (const struct nk_command_arc_filled*)cmd;
+ nk_draw_list_path_line_to(&ctx->draw_list, nk_vec2(c->cx, c->cy));
+ nk_draw_list_path_arc_to(&ctx->draw_list, nk_vec2(c->cx, c->cy), c->r,
+ c->a[0], c->a[1], config->arc_segment_count);
+ nk_draw_list_path_fill(&ctx->draw_list, c->color);
+ } break;
+ case NK_COMMAND_TRIANGLE: {
+ const struct nk_command_triangle *t = (const struct nk_command_triangle*)cmd;
+ nk_draw_list_stroke_triangle(&ctx->draw_list, nk_vec2(t->a.x, t->a.y),
+ nk_vec2(t->b.x, t->b.y), nk_vec2(t->c.x, t->c.y), t->color,
+ t->line_thickness);
+ } break;
+ case NK_COMMAND_TRIANGLE_FILLED: {
+ const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled*)cmd;
+ nk_draw_list_fill_triangle(&ctx->draw_list, nk_vec2(t->a.x, t->a.y),
+ nk_vec2(t->b.x, t->b.y), nk_vec2(t->c.x, t->c.y), t->color);
+ } break;
+ case NK_COMMAND_POLYGON: {
+ int i;
+ const struct nk_command_polygon*p = (const struct nk_command_polygon*)cmd;
+ for (i = 0; i < p->point_count; ++i) {
+ struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
+ nk_draw_list_path_line_to(&ctx->draw_list, pnt);
+ }
+ nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_CLOSED, p->line_thickness);
+ } break;
+ case NK_COMMAND_POLYGON_FILLED: {
+ int i;
+ const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled*)cmd;
+ for (i = 0; i < p->point_count; ++i) {
+ struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
+ nk_draw_list_path_line_to(&ctx->draw_list, pnt);
+ }
+ nk_draw_list_path_fill(&ctx->draw_list, p->color);
+ } break;
+ case NK_COMMAND_POLYLINE: {
+ int i;
+ const struct nk_command_polyline *p = (const struct nk_command_polyline*)cmd;
+ for (i = 0; i < p->point_count; ++i) {
+ struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y);
+ nk_draw_list_path_line_to(&ctx->draw_list, pnt);
+ }
+ nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_OPEN, p->line_thickness);
+ } break;
+ case NK_COMMAND_TEXT: {
+ const struct nk_command_text *t = (const struct nk_command_text*)cmd;
+ nk_draw_list_add_text(&ctx->draw_list, t->font, nk_rect(t->x, t->y, t->w, t->h),
+ t->string, t->length, t->height, t->foreground);
+ } break;
+ case NK_COMMAND_IMAGE: {
+ const struct nk_command_image *i = (const struct nk_command_image*)cmd;
+ nk_draw_list_add_image(&ctx->draw_list, i->img, nk_rect(i->x, i->y, i->w, i->h), i->col);
+ } break;
+ case NK_COMMAND_CUSTOM: {
+ const struct nk_command_custom *c = (const struct nk_command_custom*)cmd;
+ c->callback(&ctx->draw_list, c->x, c->y, c->w, c->h, c->callback_data);
+ } break;
+ default: break;
+ }
+ }
+ res |= (cmds->needed > cmds->allocated + (cmds->memory.size - cmds->size)) ? NK_CONVERT_COMMAND_BUFFER_FULL: 0;
+ res |= (vertices->needed > vertices->allocated) ? NK_CONVERT_VERTEX_BUFFER_FULL: 0;
+ res |= (elements->needed > elements->allocated) ? NK_CONVERT_ELEMENT_BUFFER_FULL: 0;
+ return res;
+}
+NK_API const struct nk_draw_command*
+nk__draw_begin(const struct nk_context *ctx,
+ const struct nk_buffer *buffer)
+{return nk__draw_list_begin(&ctx->draw_list, buffer);}
+
+NK_API const struct nk_draw_command*
+nk__draw_end(const struct nk_context *ctx, const struct nk_buffer *buffer)
+{return nk__draw_list_end(&ctx->draw_list, buffer);}
+
+NK_API const struct nk_draw_command*
+nk__draw_next(const struct nk_draw_command *cmd,
+ const struct nk_buffer *buffer, const struct nk_context *ctx)
+{return nk__draw_list_next(cmd, buffer, &ctx->draw_list);}
+
+#endif
+
+/*
+ * ==============================================================
+ *
+ * FONT HANDLING
+ *
+ * ===============================================================
+ */
+#ifdef NK_INCLUDE_FONT_BAKING
+/* -------------------------------------------------------------
+ *
+ * RECT PACK
+ *
+ * --------------------------------------------------------------*/
+/* stb_rect_pack.h - v0.05 - public domain - rectangle packing */
+/* Sean Barrett 2014 */
+#define NK_RP__MAXVAL 0xffff
+typedef unsigned short nk_rp_coord;
+
+struct nk_rp_rect {
+ /* reserved for your use: */
+ int id;
+ /* input: */
+ nk_rp_coord w, h;
+ /* output: */
+ nk_rp_coord x, y;
+ int was_packed;
+ /* non-zero if valid packing */
+}; /* 16 bytes, nominally */
+
+struct nk_rp_node {
+ nk_rp_coord x,y;
+ struct nk_rp_node *next;
+};
+
+struct nk_rp_context {
+ int width;
+ int height;
+ int align;
+ int init_mode;
+ int heuristic;
+ int num_nodes;
+ struct nk_rp_node *active_head;
+ struct nk_rp_node *free_head;
+ struct nk_rp_node extra[2];
+ /* we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' */
+};
+
+struct nk_rp__findresult {
+ int x,y;
+ struct nk_rp_node **prev_link;
+};
+
+enum NK_RP_HEURISTIC {
+ NK_RP_HEURISTIC_Skyline_default=0,
+ NK_RP_HEURISTIC_Skyline_BL_sortHeight = NK_RP_HEURISTIC_Skyline_default,
+ NK_RP_HEURISTIC_Skyline_BF_sortHeight
+};
+enum NK_RP_INIT_STATE{NK_RP__INIT_skyline = 1};
+
+NK_INTERN void
+nk_rp_setup_allow_out_of_mem(struct nk_rp_context *context, int allow_out_of_mem)
+{
+ if (allow_out_of_mem)
+ /* if it's ok to run out of memory, then don't bother aligning them; */
+ /* this gives better packing, but may fail due to OOM (even though */
+ /* the rectangles easily fit). @TODO a smarter approach would be to only */
+ /* quantize once we've hit OOM, then we could get rid of this parameter. */
+ context->align = 1;
+ else {
+ /* if it's not ok to run out of memory, then quantize the widths */
+ /* so that num_nodes is always enough nodes. */
+ /* */
+ /* I.e. num_nodes * align >= width */
+ /* align >= width / num_nodes */
+ /* align = ceil(width/num_nodes) */
+ context->align = (context->width + context->num_nodes-1) / context->num_nodes;
+ }
+}
+
+NK_INTERN void
+nk_rp_init_target(struct nk_rp_context *context, int width, int height,
+ struct nk_rp_node *nodes, int num_nodes)
+{
+ int i;
+#ifndef STBRP_LARGE_RECTS
+ NK_ASSERT(width <= 0xffff && height <= 0xffff);
+#endif
+
+ for (i=0; i < num_nodes-1; ++i)
+ nodes[i].next = &nodes[i+1];
+ nodes[i].next = 0;
+ context->init_mode = NK_RP__INIT_skyline;
+ context->heuristic = NK_RP_HEURISTIC_Skyline_default;
+ context->free_head = &nodes[0];
+ context->active_head = &context->extra[0];
+ context->width = width;
+ context->height = height;
+ context->num_nodes = num_nodes;
+ nk_rp_setup_allow_out_of_mem(context, 0);
+
+ /* node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) */
+ context->extra[0].x = 0;
+ context->extra[0].y = 0;
+ context->extra[0].next = &context->extra[1];
+ context->extra[1].x = (nk_rp_coord) width;
+ context->extra[1].y = 65535;
+ context->extra[1].next = 0;
+}
+
+/* find minimum y position if it starts at x1 */
+NK_INTERN int
+nk_rp__skyline_find_min_y(struct nk_rp_context *c, struct nk_rp_node *first,
+ int x0, int width, int *pwaste)
+{
+ struct nk_rp_node *node = first;
+ int x1 = x0 + width;
+ int min_y, visited_width, waste_area;
+ NK_ASSERT(first->x <= x0);
+ NK_UNUSED(c);
+
+ NK_ASSERT(node->next->x > x0);
+ /* we ended up handling this in the caller for efficiency */
+ NK_ASSERT(node->x <= x0);
+
+ min_y = 0;
+ waste_area = 0;
+ visited_width = 0;
+ while (node->x < x1)
+ {
+ if (node->y > min_y) {
+ /* raise min_y higher. */
+ /* we've accounted for all waste up to min_y, */
+ /* but we'll now add more waste for everything we've visited */
+ waste_area += visited_width * (node->y - min_y);
+ min_y = node->y;
+ /* the first time through, visited_width might be reduced */
+ if (node->x < x0)
+ visited_width += node->next->x - x0;
+ else
+ visited_width += node->next->x - node->x;
+ } else {
+ /* add waste area */
+ int under_width = node->next->x - node->x;
+ if (under_width + visited_width > width)
+ under_width = width - visited_width;
+ waste_area += under_width * (min_y - node->y);
+ visited_width += under_width;
+ }
+ node = node->next;
+ }
+ *pwaste = waste_area;
+ return min_y;
+}
+
+NK_INTERN struct nk_rp__findresult
+nk_rp__skyline_find_best_pos(struct nk_rp_context *c, int width, int height)
+{
+ int best_waste = (1<<30), best_x, best_y = (1 << 30);
+ struct nk_rp__findresult fr;
+ struct nk_rp_node **prev, *node, *tail, **best = 0;
+
+ /* align to multiple of c->align */
+ width = (width + c->align - 1);
+ width -= width % c->align;
+ NK_ASSERT(width % c->align == 0);
+
+ node = c->active_head;
+ prev = &c->active_head;
+ while (node->x + width <= c->width) {
+ int y,waste;
+ y = nk_rp__skyline_find_min_y(c, node, node->x, width, &waste);
+ /* actually just want to test BL */
+ if (c->heuristic == NK_RP_HEURISTIC_Skyline_BL_sortHeight) {
+ /* bottom left */
+ if (y < best_y) {
+ best_y = y;
+ best = prev;
+ }
+ } else {
+ /* best-fit */
+ if (y + height <= c->height) {
+ /* can only use it if it first vertically */
+ if (y < best_y || (y == best_y && waste < best_waste)) {
+ best_y = y;
+ best_waste = waste;
+ best = prev;
+ }
+ }
+ }
+ prev = &node->next;
+ node = node->next;
+ }
+ best_x = (best == 0) ? 0 : (*best)->x;
+
+ /* if doing best-fit (BF), we also have to try aligning right edge to each node position */
+ /* */
+ /* e.g, if fitting */
+ /* */
+ /* ____________________ */
+ /* |____________________| */
+ /* */
+ /* into */
+ /* */
+ /* | | */
+ /* | ____________| */
+ /* |____________| */
+ /* */
+ /* then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned */
+ /* */
+ /* This makes BF take about 2x the time */
+ if (c->heuristic == NK_RP_HEURISTIC_Skyline_BF_sortHeight)
+ {
+ tail = c->active_head;
+ node = c->active_head;
+ prev = &c->active_head;
+ /* find first node that's admissible */
+ while (tail->x < width)
+ tail = tail->next;
+ while (tail)
+ {
+ int xpos = tail->x - width;
+ int y,waste;
+ NK_ASSERT(xpos >= 0);
+ /* find the left position that matches this */
+ while (node->next->x <= xpos) {
+ prev = &node->next;
+ node = node->next;
+ }
+ NK_ASSERT(node->next->x > xpos && node->x <= xpos);
+ y = nk_rp__skyline_find_min_y(c, node, xpos, width, &waste);
+ if (y + height < c->height) {
+ if (y <= best_y) {
+ if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
+ best_x = xpos;
+ NK_ASSERT(y <= best_y);
+ best_y = y;
+ best_waste = waste;
+ best = prev;
+ }
+ }
+ }
+ tail = tail->next;
+ }
+ }
+ fr.prev_link = best;
+ fr.x = best_x;
+ fr.y = best_y;
+ return fr;
+}
+
+NK_INTERN struct nk_rp__findresult
+nk_rp__skyline_pack_rectangle(struct nk_rp_context *context, int width, int height)
+{
+ /* find best position according to heuristic */
+ struct nk_rp__findresult res = nk_rp__skyline_find_best_pos(context, width, height);
+ struct nk_rp_node *node, *cur;
+
+ /* bail if: */
+ /* 1. it failed */
+ /* 2. the best node doesn't fit (we don't always check this) */
+ /* 3. we're out of memory */
+ if (res.prev_link == 0 || res.y + height > context->height || context->free_head == 0) {
+ res.prev_link = 0;
+ return res;
+ }
+
+ /* on success, create new node */
+ node = context->free_head;
+ node->x = (nk_rp_coord) res.x;
+ node->y = (nk_rp_coord) (res.y + height);
+
+ context->free_head = node->next;
+
+ /* insert the new node into the right starting point, and */
+ /* let 'cur' point to the remaining nodes needing to be */
+ /* stitched back in */
+ cur = *res.prev_link;
+ if (cur->x < res.x) {
+ /* preserve the existing one, so start testing with the next one */
+ struct nk_rp_node *next = cur->next;
+ cur->next = node;
+ cur = next;
+ } else {
+ *res.prev_link = node;
+ }
+
+ /* from here, traverse cur and free the nodes, until we get to one */
+ /* that shouldn't be freed */
+ while (cur->next && cur->next->x <= res.x + width) {
+ struct nk_rp_node *next = cur->next;
+ /* move the current node to the free list */
+ cur->next = context->free_head;
+ context->free_head = cur;
+ cur = next;
+ }
+ /* stitch the list back in */
+ node->next = cur;
+
+ if (cur->x < res.x + width)
+ cur->x = (nk_rp_coord) (res.x + width);
+ return res;
+}
+
+NK_INTERN int
+nk_rect_height_compare(const void *a, const void *b)
+{
+ const struct nk_rp_rect *p = (const struct nk_rp_rect *) a;
+ const struct nk_rp_rect *q = (const struct nk_rp_rect *) b;
+ if (p->h > q->h)
+ return -1;
+ if (p->h < q->h)
+ return 1;
+ return (p->w > q->w) ? -1 : (p->w < q->w);
+}
+
+NK_INTERN int
+nk_rect_original_order(const void *a, const void *b)
+{
+ const struct nk_rp_rect *p = (const struct nk_rp_rect *) a;
+ const struct nk_rp_rect *q = (const struct nk_rp_rect *) b;
+ return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
+}
+
+NK_INTERN void
+nk_rp_qsort(struct nk_rp_rect *array, unsigned int len, int(*cmp)(const void*,const void*))
+{
+ /* iterative quick sort */
+ #define NK_MAX_SORT_STACK 64
+ unsigned right, left = 0, stack[NK_MAX_SORT_STACK], pos = 0;
+ unsigned seed = len/2 * 69069+1;
+ for (;;) {
+ for (; left+1 < len; len++) {
+ struct nk_rp_rect pivot, tmp;
+ if (pos == NK_MAX_SORT_STACK) len = stack[pos = 0];
+ pivot = array[left+seed%(len-left)];
+ seed = seed * 69069 + 1;
+ stack[pos++] = len;
+ for (right = left-1;;) {
+ while (cmp(&array[++right], &pivot) < 0);
+ while (cmp(&pivot, &array[--len]) < 0);
+ if (right >= len) break;
+ tmp = array[right];
+ array[right] = array[len];
+ array[len] = tmp;
+ }
+ }
+ if (pos == 0) break;
+ left = len;
+ len = stack[--pos];
+ }
+ #undef NK_MAX_SORT_STACK
+}
+
+NK_INTERN void
+nk_rp_pack_rects(struct nk_rp_context *context, struct nk_rp_rect *rects, int num_rects)
+{
+ int i;
+ /* we use the 'was_packed' field internally to allow sorting/unsorting */
+ for (i=0; i < num_rects; ++i) {
+ rects[i].was_packed = i;
+ }
+
+ /* sort according to heuristic */
+ nk_rp_qsort(rects, (unsigned)num_rects, nk_rect_height_compare);
+
+ for (i=0; i < num_rects; ++i) {
+ struct nk_rp__findresult fr = nk_rp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
+ if (fr.prev_link) {
+ rects[i].x = (nk_rp_coord) fr.x;
+ rects[i].y = (nk_rp_coord) fr.y;
+ } else {
+ rects[i].x = rects[i].y = NK_RP__MAXVAL;
+ }
+ }
+
+ /* unsort */
+ nk_rp_qsort(rects, (unsigned)num_rects, nk_rect_original_order);
+
+ /* set was_packed flags */
+ for (i=0; i < num_rects; ++i)
+ rects[i].was_packed = !(rects[i].x == NK_RP__MAXVAL && rects[i].y == NK_RP__MAXVAL);
+}
+
+/*
+ * ==============================================================
+ *
+ * TRUETYPE
+ *
+ * ===============================================================
+ */
+/* stb_truetype.h - v1.07 - public domain */
+#define NK_TT_MAX_OVERSAMPLE 8
+#define NK_TT__OVER_MASK (NK_TT_MAX_OVERSAMPLE-1)
+
+struct nk_tt_bakedchar {
+ unsigned short x0,y0,x1,y1;
+ /* coordinates of bbox in bitmap */
+ float xoff,yoff,xadvance;
+};
+
+struct nk_tt_aligned_quad{
+ float x0,y0,s0,t0; /* top-left */
+ float x1,y1,s1,t1; /* bottom-right */
+};
+
+struct nk_tt_packedchar {
+ unsigned short x0,y0,x1,y1;
+ /* coordinates of bbox in bitmap */
+ float xoff,yoff,xadvance;
+ float xoff2,yoff2;
+};
+
+struct nk_tt_pack_range {
+ float font_size;
+ int first_unicode_codepoint_in_range;
+ /* if non-zero, then the chars are continuous, and this is the first codepoint */
+ int *array_of_unicode_codepoints;
+ /* if non-zero, then this is an array of unicode codepoints */
+ int num_chars;
+ struct nk_tt_packedchar *chardata_for_range; /* output */
+ unsigned char h_oversample, v_oversample;
+ /* don't set these, they're used internally */
+};
+
+struct nk_tt_pack_context {
+ void *pack_info;
+ int width;
+ int height;
+ int stride_in_bytes;
+ int padding;
+ unsigned int h_oversample, v_oversample;
+ unsigned char *pixels;
+ void *nodes;
+};
+
+struct nk_tt_fontinfo {
+ const unsigned char* data; /* pointer to .ttf file */
+ int fontstart;/* offset of start of font */
+ int numGlyphs;/* number of glyphs, needed for range checking */
+ int loca,head,glyf,hhea,hmtx,kern; /* table locations as offset from start of .ttf */
+ int index_map; /* a cmap mapping for our chosen character encoding */
+ int indexToLocFormat; /* format needed to map from glyph index to glyph */
+};
+
+enum {
+ NK_TT_vmove=1,
+ NK_TT_vline,
+ NK_TT_vcurve
+};
+
+struct nk_tt_vertex {
+ short x,y,cx,cy;
+ unsigned char type,padding;
+};
+
+struct nk_tt__bitmap{
+ int w,h,stride;
+ unsigned char *pixels;
+};
+
+struct nk_tt__hheap_chunk {
+ struct nk_tt__hheap_chunk *next;
+};
+struct nk_tt__hheap {
+ struct nk_allocator alloc;
+ struct nk_tt__hheap_chunk *head;
+ void *first_free;
+ int num_remaining_in_head_chunk;
+};
+
+struct nk_tt__edge {
+ float x0,y0, x1,y1;
+ int invert;
+};
+
+struct nk_tt__active_edge {
+ struct nk_tt__active_edge *next;
+ float fx,fdx,fdy;
+ float direction;
+ float sy;
+ float ey;
+};
+struct nk_tt__point {float x,y;};
+
+#define NK_TT_MACSTYLE_DONTCARE 0
+#define NK_TT_MACSTYLE_BOLD 1
+#define NK_TT_MACSTYLE_ITALIC 2
+#define NK_TT_MACSTYLE_UNDERSCORE 4
+#define NK_TT_MACSTYLE_NONE 8
+/* <= not same as 0, this makes us check the bitfield is 0 */
+
+enum { /* platformID */
+ NK_TT_PLATFORM_ID_UNICODE =0,
+ NK_TT_PLATFORM_ID_MAC =1,
+ NK_TT_PLATFORM_ID_ISO =2,
+ NK_TT_PLATFORM_ID_MICROSOFT =3
+};
+
+enum { /* encodingID for NK_TT_PLATFORM_ID_UNICODE */
+ NK_TT_UNICODE_EID_UNICODE_1_0 =0,
+ NK_TT_UNICODE_EID_UNICODE_1_1 =1,
+ NK_TT_UNICODE_EID_ISO_10646 =2,
+ NK_TT_UNICODE_EID_UNICODE_2_0_BMP=3,
+ NK_TT_UNICODE_EID_UNICODE_2_0_FULL=4
+};
+
+enum { /* encodingID for NK_TT_PLATFORM_ID_MICROSOFT */
+ NK_TT_MS_EID_SYMBOL =0,
+ NK_TT_MS_EID_UNICODE_BMP =1,
+ NK_TT_MS_EID_SHIFTJIS =2,
+ NK_TT_MS_EID_UNICODE_FULL =10
+};
+
+enum { /* encodingID for NK_TT_PLATFORM_ID_MAC; same as Script Manager codes */
+ NK_TT_MAC_EID_ROMAN =0, NK_TT_MAC_EID_ARABIC =4,
+ NK_TT_MAC_EID_JAPANESE =1, NK_TT_MAC_EID_HEBREW =5,
+ NK_TT_MAC_EID_CHINESE_TRAD =2, NK_TT_MAC_EID_GREEK =6,
+ NK_TT_MAC_EID_KOREAN =3, NK_TT_MAC_EID_RUSSIAN =7
+};
+
+enum { /* languageID for NK_TT_PLATFORM_ID_MICROSOFT; same as LCID... */
+ /* problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs */
+ NK_TT_MS_LANG_ENGLISH =0x0409, NK_TT_MS_LANG_ITALIAN =0x0410,
+ NK_TT_MS_LANG_CHINESE =0x0804, NK_TT_MS_LANG_JAPANESE =0x0411,
+ NK_TT_MS_LANG_DUTCH =0x0413, NK_TT_MS_LANG_KOREAN =0x0412,
+ NK_TT_MS_LANG_FRENCH =0x040c, NK_TT_MS_LANG_RUSSIAN =0x0419,
+ NK_TT_MS_LANG_GERMAN =0x0407, NK_TT_MS_LANG_SPANISH =0x0409,
+ NK_TT_MS_LANG_HEBREW =0x040d, NK_TT_MS_LANG_SWEDISH =0x041D
+};
+
+enum { /* languageID for NK_TT_PLATFORM_ID_MAC */
+ NK_TT_MAC_LANG_ENGLISH =0 , NK_TT_MAC_LANG_JAPANESE =11,
+ NK_TT_MAC_LANG_ARABIC =12, NK_TT_MAC_LANG_KOREAN =23,
+ NK_TT_MAC_LANG_DUTCH =4 , NK_TT_MAC_LANG_RUSSIAN =32,
+ NK_TT_MAC_LANG_FRENCH =1 , NK_TT_MAC_LANG_SPANISH =6 ,
+ NK_TT_MAC_LANG_GERMAN =2 , NK_TT_MAC_LANG_SWEDISH =5 ,
+ NK_TT_MAC_LANG_HEBREW =10, NK_TT_MAC_LANG_CHINESE_SIMPLIFIED =33,
+ NK_TT_MAC_LANG_ITALIAN =3 , NK_TT_MAC_LANG_CHINESE_TRAD =19
+};
+
+#define nk_ttBYTE(p) (* (const nk_byte *) (p))
+#define nk_ttCHAR(p) (* (const char *) (p))
+
+#if defined(NK_BIGENDIAN) && !defined(NK_ALLOW_UNALIGNED_TRUETYPE)
+ #define nk_ttUSHORT(p) (* (nk_ushort *) (p))
+ #define nk_ttSHORT(p) (* (nk_short *) (p))
+ #define nk_ttULONG(p) (* (nk_uint *) (p))
+ #define nk_ttLONG(p) (* (nk_int *) (p))
+#else
+ static nk_ushort nk_ttUSHORT(const nk_byte *p) { return (nk_ushort)(p[0]*256 + p[1]); }
+ static nk_short nk_ttSHORT(const nk_byte *p) { return (nk_short)(p[0]*256 + p[1]); }
+ static nk_uint nk_ttULONG(const nk_byte *p) { return (nk_uint)((p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]); }
+#endif
+
+#define nk_tt_tag4(p,c0,c1,c2,c3)\
+ ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
+#define nk_tt_tag(p,str) nk_tt_tag4(p,str[0],str[1],str[2],str[3])
+
+NK_INTERN int nk_tt_GetGlyphShape(const struct nk_tt_fontinfo *info, struct nk_allocator *alloc,
+ int glyph_index, struct nk_tt_vertex **pvertices);
+
+NK_INTERN nk_uint
+nk_tt__find_table(const nk_byte *data, nk_uint fontstart, const char *tag)
+{
+ /* @OPTIMIZE: binary search */
+ nk_int num_tables = nk_ttUSHORT(data+fontstart+4);
+ nk_uint tabledir = fontstart + 12;
+ nk_int i;
+ for (i = 0; i < num_tables; ++i) {
+ nk_uint loc = tabledir + (nk_uint)(16*i);
+ if (nk_tt_tag(data+loc+0, tag))
+ return nk_ttULONG(data+loc+8);
+ }
+ return 0;
+}
+
+NK_INTERN int
+nk_tt_InitFont(struct nk_tt_fontinfo *info, const unsigned char *data2, int fontstart)
+{
+ nk_uint cmap, t;
+ nk_int i,numTables;
+ const nk_byte *data = (const nk_byte *) data2;
+
+ info->data = data;
+ info->fontstart = fontstart;
+
+ cmap = nk_tt__find_table(data, (nk_uint)fontstart, "cmap"); /* required */
+ info->loca = (int)nk_tt__find_table(data, (nk_uint)fontstart, "loca"); /* required */
+ info->head = (int)nk_tt__find_table(data, (nk_uint)fontstart, "head"); /* required */
+ info->glyf = (int)nk_tt__find_table(data, (nk_uint)fontstart, "glyf"); /* required */
+ info->hhea = (int)nk_tt__find_table(data, (nk_uint)fontstart, "hhea"); /* required */
+ info->hmtx = (int)nk_tt__find_table(data, (nk_uint)fontstart, "hmtx"); /* required */
+ info->kern = (int)nk_tt__find_table(data, (nk_uint)fontstart, "kern"); /* not required */
+ if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx)
+ return 0;
+
+ t = nk_tt__find_table(data, (nk_uint)fontstart, "maxp");
+ if (t) info->numGlyphs = nk_ttUSHORT(data+t+4);
+ else info->numGlyphs = 0xffff;
+
+ /* find a cmap encoding table we understand *now* to avoid searching */
+ /* later. (todo: could make this installable) */
+ /* the same regardless of glyph. */
+ numTables = nk_ttUSHORT(data + cmap + 2);
+ info->index_map = 0;
+ for (i=0; i < numTables; ++i)
+ {
+ nk_uint encoding_record = cmap + 4 + 8 * (nk_uint)i;
+ /* find an encoding we understand: */
+ switch(nk_ttUSHORT(data+encoding_record)) {
+ case NK_TT_PLATFORM_ID_MICROSOFT:
+ switch (nk_ttUSHORT(data+encoding_record+2)) {
+ case NK_TT_MS_EID_UNICODE_BMP:
+ case NK_TT_MS_EID_UNICODE_FULL:
+ /* MS/Unicode */
+ info->index_map = (int)(cmap + nk_ttULONG(data+encoding_record+4));
+ break;
+ default: break;
+ } break;
+ case NK_TT_PLATFORM_ID_UNICODE:
+ /* Mac/iOS has these */
+ /* all the encodingIDs are unicode, so we don't bother to check it */
+ info->index_map = (int)(cmap + nk_ttULONG(data+encoding_record+4));
+ break;
+ default: break;
+ }
+ }
+ if (info->index_map == 0)
+ return 0;
+ info->indexToLocFormat = nk_ttUSHORT(data+info->head + 50);
+ return 1;
+}
+
+NK_INTERN int
+nk_tt_FindGlyphIndex(const struct nk_tt_fontinfo *info, int unicode_codepoint)
+{
+ const nk_byte *data = info->data;
+ nk_uint index_map = (nk_uint)info->index_map;
+
+ nk_ushort format = nk_ttUSHORT(data + index_map + 0);
+ if (format == 0) { /* apple byte encoding */
+ nk_int bytes = nk_ttUSHORT(data + index_map + 2);
+ if (unicode_codepoint < bytes-6)
+ return nk_ttBYTE(data + index_map + 6 + unicode_codepoint);
+ return 0;
+ } else if (format == 6) {
+ nk_uint first = nk_ttUSHORT(data + index_map + 6);
+ nk_uint count = nk_ttUSHORT(data + index_map + 8);
+ if ((nk_uint) unicode_codepoint >= first && (nk_uint) unicode_codepoint < first+count)
+ return nk_ttUSHORT(data + index_map + 10 + (unicode_codepoint - (int)first)*2);
+ return 0;
+ } else if (format == 2) {
+ NK_ASSERT(0); /* @TODO: high-byte mapping for japanese/chinese/korean */
+ return 0;
+ } else if (format == 4) { /* standard mapping for windows fonts: binary search collection of ranges */
+ nk_ushort segcount = nk_ttUSHORT(data+index_map+6) >> 1;
+ nk_ushort searchRange = nk_ttUSHORT(data+index_map+8) >> 1;
+ nk_ushort entrySelector = nk_ttUSHORT(data+index_map+10);
+ nk_ushort rangeShift = nk_ttUSHORT(data+index_map+12) >> 1;
+
+ /* do a binary search of the segments */
+ nk_uint endCount = index_map + 14;
+ nk_uint search = endCount;
+
+ if (unicode_codepoint > 0xffff)
+ return 0;
+
+ /* they lie from endCount .. endCount + segCount */
+ /* but searchRange is the nearest power of two, so... */
+ if (unicode_codepoint >= nk_ttUSHORT(data + search + rangeShift*2))
+ search += (nk_uint)(rangeShift*2);
+
+ /* now decrement to bias correctly to find smallest */
+ search -= 2;
+ while (entrySelector) {
+ nk_ushort end;
+ searchRange >>= 1;
+ end = nk_ttUSHORT(data + search + searchRange*2);
+ if (unicode_codepoint > end)
+ search += (nk_uint)(searchRange*2);
+ --entrySelector;
+ }
+ search += 2;
+
+ {
+ nk_ushort offset, start;
+ nk_ushort item = (nk_ushort) ((search - endCount) >> 1);
+
+ NK_ASSERT(unicode_codepoint <= nk_ttUSHORT(data + endCount + 2*item));
+ start = nk_ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
+ if (unicode_codepoint < start)
+ return 0;
+
+ offset = nk_ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
+ if (offset == 0)
+ return (nk_ushort) (unicode_codepoint + nk_ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));
+
+ return nk_ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
+ }
+ } else if (format == 12 || format == 13) {
+ nk_uint ngroups = nk_ttULONG(data+index_map+12);
+ nk_int low,high;
+ low = 0; high = (nk_int)ngroups;
+ /* Binary search the right group. */
+ while (low < high) {
+ nk_int mid = low + ((high-low) >> 1); /* rounds down, so low <= mid < high */
+ nk_uint start_char = nk_ttULONG(data+index_map+16+mid*12);
+ nk_uint end_char = nk_ttULONG(data+index_map+16+mid*12+4);
+ if ((nk_uint) unicode_codepoint < start_char)
+ high = mid;
+ else if ((nk_uint) unicode_codepoint > end_char)
+ low = mid+1;
+ else {
+ nk_uint start_glyph = nk_ttULONG(data+index_map+16+mid*12+8);
+ if (format == 12)
+ return (int)start_glyph + (int)unicode_codepoint - (int)start_char;
+ else /* format == 13 */
+ return (int)start_glyph;
+ }
+ }
+ return 0; /* not found */
+ }
+ /* @TODO */
+ NK_ASSERT(0);
+ return 0;
+}
+
+NK_INTERN void
+nk_tt_setvertex(struct nk_tt_vertex *v, nk_byte type, nk_int x, nk_int y, nk_int cx, nk_int cy)
+{
+ v->type = type;
+ v->x = (nk_short) x;
+ v->y = (nk_short) y;
+ v->cx = (nk_short) cx;
+ v->cy = (nk_short) cy;
+}
+
+NK_INTERN int
+nk_tt__GetGlyfOffset(const struct nk_tt_fontinfo *info, int glyph_index)
+{
+ int g1,g2;
+ if (glyph_index >= info->numGlyphs) return -1; /* glyph index out of range */
+ if (info->indexToLocFormat >= 2) return -1; /* unknown index->glyph map format */
+
+ if (info->indexToLocFormat == 0) {
+ g1 = info->glyf + nk_ttUSHORT(info->data + info->loca + glyph_index * 2) * 2;
+ g2 = info->glyf + nk_ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2;
+ } else {
+ g1 = info->glyf + (int)nk_ttULONG (info->data + info->loca + glyph_index * 4);
+ g2 = info->glyf + (int)nk_ttULONG (info->data + info->loca + glyph_index * 4 + 4);
+ }
+ return g1==g2 ? -1 : g1; /* if length is 0, return -1 */
+}
+
+NK_INTERN int
+nk_tt_GetGlyphBox(const struct nk_tt_fontinfo *info, int glyph_index,
+ int *x0, int *y0, int *x1, int *y1)
+{
+ int g = nk_tt__GetGlyfOffset(info, glyph_index);
+ if (g < 0) return 0;
+
+ if (x0) *x0 = nk_ttSHORT(info->data + g + 2);
+ if (y0) *y0 = nk_ttSHORT(info->data + g + 4);
+ if (x1) *x1 = nk_ttSHORT(info->data + g + 6);
+ if (y1) *y1 = nk_ttSHORT(info->data + g + 8);
+ return 1;
+}
+
+NK_INTERN int
+nk_tt__close_shape(struct nk_tt_vertex *vertices, int num_vertices, int was_off,
+ int start_off, nk_int sx, nk_int sy, nk_int scx, nk_int scy, nk_int cx, nk_int cy)
+{
+ if (start_off) {
+ if (was_off)
+ nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy);
+ nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, sx,sy,scx,scy);
+ } else {
+ if (was_off)
+ nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve,sx,sy,cx,cy);
+ else
+ nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vline,sx,sy,0,0);
+ }
+ return num_vertices;
+}
+
+NK_INTERN int
+nk_tt_GetGlyphShape(const struct nk_tt_fontinfo *info, struct nk_allocator *alloc,
+ int glyph_index, struct nk_tt_vertex **pvertices)
+{
+ nk_short numberOfContours;
+ const nk_byte *endPtsOfContours;
+ const nk_byte *data = info->data;
+ struct nk_tt_vertex *vertices=0;
+ int num_vertices=0;
+ int g = nk_tt__GetGlyfOffset(info, glyph_index);
+ *pvertices = 0;
+
+ if (g < 0) return 0;
+ numberOfContours = nk_ttSHORT(data + g);
+ if (numberOfContours > 0) {
+ nk_byte flags=0,flagcount;
+ nk_int ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0;
+ nk_int x,y,cx,cy,sx,sy, scx,scy;
+ const nk_byte *points;
+ endPtsOfContours = (data + g + 10);
+ ins = nk_ttUSHORT(data + g + 10 + numberOfContours * 2);
+ points = data + g + 10 + numberOfContours * 2 + 2 + ins;
+
+ n = 1+nk_ttUSHORT(endPtsOfContours + numberOfContours*2-2);
+ m = n + 2*numberOfContours; /* a loose bound on how many vertices we might need */
+ vertices = (struct nk_tt_vertex *)alloc->alloc(alloc->userdata, 0, (nk_size)m * sizeof(vertices[0]));
+ if (vertices == 0)
+ return 0;
+
+ next_move = 0;
+ flagcount=0;
+
+ /* in first pass, we load uninterpreted data into the allocated array */
+ /* above, shifted to the end of the array so we won't overwrite it when */
+ /* we create our final data starting from the front */
+ off = m - n; /* starting offset for uninterpreted data, regardless of how m ends up being calculated */
+
+ /* first load flags */
+ for (i=0; i < n; ++i) {
+ if (flagcount == 0) {
+ flags = *points++;
+ if (flags & 8)
+ flagcount = *points++;
+ } else --flagcount;
+ vertices[off+i].type = flags;
+ }
+
+ /* now load x coordinates */
+ x=0;
+ for (i=0; i < n; ++i) {
+ flags = vertices[off+i].type;
+ if (flags & 2) {
+ nk_short dx = *points++;
+ x += (flags & 16) ? dx : -dx; /* ??? */
+ } else {
+ if (!(flags & 16)) {
+ x = x + (nk_short) (points[0]*256 + points[1]);
+ points += 2;
+ }
+ }
+ vertices[off+i].x = (nk_short) x;
+ }
+
+ /* now load y coordinates */
+ y=0;
+ for (i=0; i < n; ++i) {
+ flags = vertices[off+i].type;
+ if (flags & 4) {
+ nk_short dy = *points++;
+ y += (flags & 32) ? dy : -dy; /* ??? */
+ } else {
+ if (!(flags & 32)) {
+ y = y + (nk_short) (points[0]*256 + points[1]);
+ points += 2;
+ }
+ }
+ vertices[off+i].y = (nk_short) y;
+ }
+
+ /* now convert them to our format */
+ num_vertices=0;
+ sx = sy = cx = cy = scx = scy = 0;
+ for (i=0; i < n; ++i)
+ {
+ flags = vertices[off+i].type;
+ x = (nk_short) vertices[off+i].x;
+ y = (nk_short) vertices[off+i].y;
+
+ if (next_move == i) {
+ if (i != 0)
+ num_vertices = nk_tt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
+
+ /* now start the new one */
+ start_off = !(flags & 1);
+ if (start_off) {
+ /* if we start off with an off-curve point, then when we need to find a point on the curve */
+ /* where we can start, and we need to save some state for when we wraparound. */
+ scx = x;
+ scy = y;
+ if (!(vertices[off+i+1].type & 1)) {
+ /* next point is also a curve point, so interpolate an on-point curve */
+ sx = (x + (nk_int) vertices[off+i+1].x) >> 1;
+ sy = (y + (nk_int) vertices[off+i+1].y) >> 1;
+ } else {
+ /* otherwise just use the next point as our start point */
+ sx = (nk_int) vertices[off+i+1].x;
+ sy = (nk_int) vertices[off+i+1].y;
+ ++i; /* we're using point i+1 as the starting point, so skip it */
+ }
+ } else {
+ sx = x;
+ sy = y;
+ }
+ nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vmove,sx,sy,0,0);
+ was_off = 0;
+ next_move = 1 + nk_ttUSHORT(endPtsOfContours+j*2);
+ ++j;
+ } else {
+ if (!(flags & 1))
+ { /* if it's a curve */
+ if (was_off) /* two off-curve control points in a row means interpolate an on-curve midpoint */
+ nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy);
+ cx = x;
+ cy = y;
+ was_off = 1;
+ } else {
+ if (was_off)
+ nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vcurve, x,y, cx, cy);
+ else nk_tt_setvertex(&vertices[num_vertices++], NK_TT_vline, x,y,0,0);
+ was_off = 0;
+ }
+ }
+ }
+ num_vertices = nk_tt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
+ } else if (numberOfContours == -1) {
+ /* Compound shapes. */
+ int more = 1;
+ const nk_byte *comp = data + g + 10;
+ num_vertices = 0;
+ vertices = 0;
+
+ while (more)
+ {
+ nk_ushort flags, gidx;
+ int comp_num_verts = 0, i;
+ struct nk_tt_vertex *comp_verts = 0, *tmp = 0;
+ float mtx[6] = {1,0,0,1,0,0}, m, n;
+
+ flags = (nk_ushort)nk_ttSHORT(comp); comp+=2;
+ gidx = (nk_ushort)nk_ttSHORT(comp); comp+=2;
+
+ if (flags & 2) { /* XY values */
+ if (flags & 1) { /* shorts */
+ mtx[4] = nk_ttSHORT(comp); comp+=2;
+ mtx[5] = nk_ttSHORT(comp); comp+=2;
+ } else {
+ mtx[4] = nk_ttCHAR(comp); comp+=1;
+ mtx[5] = nk_ttCHAR(comp); comp+=1;
+ }
+ } else {
+ /* @TODO handle matching point */
+ NK_ASSERT(0);
+ }
+ if (flags & (1<<3)) { /* WE_HAVE_A_SCALE */
+ mtx[0] = mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
+ mtx[1] = mtx[2] = 0;
+ } else if (flags & (1<<6)) { /* WE_HAVE_AN_X_AND_YSCALE */
+ mtx[0] = nk_ttSHORT(comp)/16384.0f; comp+=2;
+ mtx[1] = mtx[2] = 0;
+ mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
+ } else if (flags & (1<<7)) { /* WE_HAVE_A_TWO_BY_TWO */
+ mtx[0] = nk_ttSHORT(comp)/16384.0f; comp+=2;
+ mtx[1] = nk_ttSHORT(comp)/16384.0f; comp+=2;
+ mtx[2] = nk_ttSHORT(comp)/16384.0f; comp+=2;
+ mtx[3] = nk_ttSHORT(comp)/16384.0f; comp+=2;
+ }
+
+ /* Find transformation scales. */
+ m = (float) NK_SQRT(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
+ n = (float) NK_SQRT(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
+
+ /* Get indexed glyph. */
+ comp_num_verts = nk_tt_GetGlyphShape(info, alloc, gidx, &comp_verts);
+ if (comp_num_verts > 0)
+ {
+ /* Transform vertices. */
+ for (i = 0; i < comp_num_verts; ++i) {
+ struct nk_tt_vertex* v = &comp_verts[i];
+ short x,y;
+ x=v->x; y=v->y;
+ v->x = (short)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
+ v->y = (short)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
+ x=v->cx; y=v->cy;
+ v->cx = (short)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
+ v->cy = (short)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
+ }
+ /* Append vertices. */
+ tmp = (struct nk_tt_vertex*)alloc->alloc(alloc->userdata, 0,
+ (nk_size)(num_vertices+comp_num_verts)*sizeof(struct nk_tt_vertex));
+ if (!tmp) {
+ if (vertices) alloc->free(alloc->userdata, vertices);
+ if (comp_verts) alloc->free(alloc->userdata, comp_verts);
+ return 0;
+ }
+ if (num_vertices > 0) NK_MEMCPY(tmp, vertices, (nk_size)num_vertices*sizeof(struct nk_tt_vertex));
+ NK_MEMCPY(tmp+num_vertices, comp_verts, (nk_size)comp_num_verts*sizeof(struct nk_tt_vertex));
+ if (vertices) alloc->free(alloc->userdata,vertices);
+ vertices = tmp;
+ alloc->free(alloc->userdata,comp_verts);
+ num_vertices += comp_num_verts;
+ }
+ /* More components ? */
+ more = flags & (1<<5);
+ }
+ } else if (numberOfContours < 0) {
+ /* @TODO other compound variations? */
+ NK_ASSERT(0);
+ } else {
+ /* numberOfCounters == 0, do nothing */
+ }
+ *pvertices = vertices;
+ return num_vertices;
+}
+
+NK_INTERN void
+nk_tt_GetGlyphHMetrics(const struct nk_tt_fontinfo *info, int glyph_index,
+ int *advanceWidth, int *leftSideBearing)
+{
+ nk_ushort numOfLongHorMetrics = nk_ttUSHORT(info->data+info->hhea + 34);
+ if (glyph_index < numOfLongHorMetrics) {
+ if (advanceWidth)
+ *advanceWidth = nk_ttSHORT(info->data + info->hmtx + 4*glyph_index);
+ if (leftSideBearing)
+ *leftSideBearing = nk_ttSHORT(info->data + info->hmtx + 4*glyph_index + 2);
+ } else {
+ if (advanceWidth)
+ *advanceWidth = nk_ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1));
+ if (leftSideBearing)
+ *leftSideBearing = nk_ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
+ }
+}
+
+NK_INTERN void
+nk_tt_GetFontVMetrics(const struct nk_tt_fontinfo *info,
+ int *ascent, int *descent, int *lineGap)
+{
+ if (ascent ) *ascent = nk_ttSHORT(info->data+info->hhea + 4);
+ if (descent) *descent = nk_ttSHORT(info->data+info->hhea + 6);
+ if (lineGap) *lineGap = nk_ttSHORT(info->data+info->hhea + 8);
+}
+
+NK_INTERN float
+nk_tt_ScaleForPixelHeight(const struct nk_tt_fontinfo *info, float height)
+{
+ int fheight = nk_ttSHORT(info->data + info->hhea + 4) - nk_ttSHORT(info->data + info->hhea + 6);
+ return (float) height / (float)fheight;
+}
+
+NK_INTERN float
+nk_tt_ScaleForMappingEmToPixels(const struct nk_tt_fontinfo *info, float pixels)
+{
+ int unitsPerEm = nk_ttUSHORT(info->data + info->head + 18);
+ return pixels / (float)unitsPerEm;
+}
+
+/*-------------------------------------------------------------
+ * antialiasing software rasterizer
+ * --------------------------------------------------------------*/
+NK_INTERN void
+nk_tt_GetGlyphBitmapBoxSubpixel(const struct nk_tt_fontinfo *font,
+ int glyph, float scale_x, float scale_y,float shift_x, float shift_y,
+ int *ix0, int *iy0, int *ix1, int *iy1)
+{
+ int x0,y0,x1,y1;
+ if (!nk_tt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
+ /* e.g. space character */
+ if (ix0) *ix0 = 0;
+ if (iy0) *iy0 = 0;
+ if (ix1) *ix1 = 0;
+ if (iy1) *iy1 = 0;
+ } else {
+ /* move to integral bboxes (treating pixels as little squares, what pixels get touched)? */
+ if (ix0) *ix0 = nk_ifloorf((float)x0 * scale_x + shift_x);
+ if (iy0) *iy0 = nk_ifloorf((float)-y1 * scale_y + shift_y);
+ if (ix1) *ix1 = nk_iceilf ((float)x1 * scale_x + shift_x);
+ if (iy1) *iy1 = nk_iceilf ((float)-y0 * scale_y + shift_y);
+ }
+}
+
+NK_INTERN void
+nk_tt_GetGlyphBitmapBox(const struct nk_tt_fontinfo *font, int glyph,
+ float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
+{
+ nk_tt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
+}
+
+/*-------------------------------------------------------------
+ * Rasterizer
+ * --------------------------------------------------------------*/
+NK_INTERN void*
+nk_tt__hheap_alloc(struct nk_tt__hheap *hh, nk_size size)
+{
+ if (hh->first_free) {
+ void *p = hh->first_free;
+ hh->first_free = * (void **) p;
+ return p;
+ } else {
+ if (hh->num_remaining_in_head_chunk == 0) {
+ int count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
+ struct nk_tt__hheap_chunk *c = (struct nk_tt__hheap_chunk *)
+ hh->alloc.alloc(hh->alloc.userdata, 0,
+ sizeof(struct nk_tt__hheap_chunk) + size * (nk_size)count);
+ if (c == 0) return 0;
+ c->next = hh->head;
+ hh->head = c;
+ hh->num_remaining_in_head_chunk = count;
+ }
+ --hh->num_remaining_in_head_chunk;
+ return (char *) (hh->head) + size * (nk_size)hh->num_remaining_in_head_chunk;
+ }
+}
+
+NK_INTERN void
+nk_tt__hheap_free(struct nk_tt__hheap *hh, void *p)
+{
+ *(void **) p = hh->first_free;
+ hh->first_free = p;
+}
+
+NK_INTERN void
+nk_tt__hheap_cleanup(struct nk_tt__hheap *hh)
+{
+ struct nk_tt__hheap_chunk *c = hh->head;
+ while (c) {
+ struct nk_tt__hheap_chunk *n = c->next;
+ hh->alloc.free(hh->alloc.userdata, c);
+ c = n;
+ }
+}
+
+NK_INTERN struct nk_tt__active_edge*
+nk_tt__new_active(struct nk_tt__hheap *hh, struct nk_tt__edge *e,
+ int off_x, float start_point)
+{
+ struct nk_tt__active_edge *z = (struct nk_tt__active_edge *)
+ nk_tt__hheap_alloc(hh, sizeof(*z));
+ float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
+ /*STBTT_assert(e->y0 <= start_point); */
+ if (!z) return z;
+ z->fdx = dxdy;
+ z->fdy = (dxdy != 0) ? (1/dxdy): 0;
+ z->fx = e->x0 + dxdy * (start_point - e->y0);
+ z->fx -= (float)off_x;
+ z->direction = e->invert ? 1.0f : -1.0f;
+ z->sy = e->y0;
+ z->ey = e->y1;
+ z->next = 0;
+ return z;
+}
+
+NK_INTERN void
+nk_tt__handle_clipped_edge(float *scanline, int x, struct nk_tt__active_edge *e,
+ float x0, float y0, float x1, float y1)
+{
+ if (y0 == y1) return;
+ NK_ASSERT(y0 < y1);
+ NK_ASSERT(e->sy <= e->ey);
+ if (y0 > e->ey) return;
+ if (y1 < e->sy) return;
+ if (y0 < e->sy) {
+ x0 += (x1-x0) * (e->sy - y0) / (y1-y0);
+ y0 = e->sy;
+ }
+ if (y1 > e->ey) {
+ x1 += (x1-x0) * (e->ey - y1) / (y1-y0);
+ y1 = e->ey;
+ }
+
+ if (x0 == x) NK_ASSERT(x1 <= x+1);
+ else if (x0 == x+1) NK_ASSERT(x1 >= x);
+ else if (x0 <= x) NK_ASSERT(x1 <= x);
+ else if (x0 >= x+1) NK_ASSERT(x1 >= x+1);
+ else NK_ASSERT(x1 >= x && x1 <= x+1);
+
+ if (x0 <= x && x1 <= x)
+ scanline[x] += e->direction * (y1-y0);
+ else if (x0 >= x+1 && x1 >= x+1);
+ else {
+ NK_ASSERT(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1);
+ /* coverage = 1 - average x position */
+ scanline[x] += (float)e->direction * (float)(y1-y0) * (1.0f-((x0-(float)x)+(x1-(float)x))/2.0f);
+ }
+}
+
+NK_INTERN void
+nk_tt__fill_active_edges_new(float *scanline, float *scanline_fill, int len,
+ struct nk_tt__active_edge *e, float y_top)
+{
+ float y_bottom = y_top+1;
+ while (e)
+ {
+ /* brute force every pixel */
+ /* compute intersection points with top & bottom */
+ NK_ASSERT(e->ey >= y_top);
+ if (e->fdx == 0) {
+ float x0 = e->fx;
+ if (x0 < len) {
+ if (x0 >= 0) {
+ nk_tt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom);
+ nk_tt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom);
+ } else {
+ nk_tt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom);
+ }
+ }
+ } else {
+ float x0 = e->fx;
+ float dx = e->fdx;
+ float xb = x0 + dx;
+ float x_top, x_bottom;
+ float y0,y1;
+ float dy = e->fdy;
+ NK_ASSERT(e->sy <= y_bottom && e->ey >= y_top);
+
+ /* compute endpoints of line segment clipped to this scanline (if the */
+ /* line segment starts on this scanline. x0 is the intersection of the */
+ /* line with y_top, but that may be off the line segment. */
+ if (e->sy > y_top) {
+ x_top = x0 + dx * (e->sy - y_top);
+ y0 = e->sy;
+ } else {
+ x_top = x0;
+ y0 = y_top;
+ }
+
+ if (e->ey < y_bottom) {
+ x_bottom = x0 + dx * (e->ey - y_top);
+ y1 = e->ey;
+ } else {
+ x_bottom = xb;
+ y1 = y_bottom;
+ }
+
+ if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len)
+ {
+ /* from here on, we don't have to range check x values */
+ if ((int) x_top == (int) x_bottom) {
+ float height;
+ /* simple case, only spans one pixel */
+ int x = (int) x_top;
+ height = y1 - y0;
+ NK_ASSERT(x >= 0 && x < len);
+ scanline[x] += e->direction * (1.0f-(((float)x_top - (float)x) + ((float)x_bottom-(float)x))/2.0f) * (float)height;
+ scanline_fill[x] += e->direction * (float)height; /* everything right of this pixel is filled */
+ } else {
+ int x,x1,x2;
+ float y_crossing, step, sign, area;
+ /* covers 2+ pixels */
+ if (x_top > x_bottom)
+ {
+ /* flip scanline vertically; signed area is the same */
+ float t;
+ y0 = y_bottom - (y0 - y_top);
+ y1 = y_bottom - (y1 - y_top);
+ t = y0; y0 = y1; y1 = t;
+ t = x_bottom; x_bottom = x_top; x_top = t;
+ dx = -dx;
+ dy = -dy;
+ t = x0; x0 = xb; xb = t;
+ }
+
+ x1 = (int) x_top;
+ x2 = (int) x_bottom;
+ /* compute intersection with y axis at x1+1 */
+ y_crossing = ((float)x1+1 - (float)x0) * (float)dy + (float)y_top;
+
+ sign = e->direction;
+ /* area of the rectangle covered from y0..y_crossing */
+ area = sign * (y_crossing-y0);
+ /* area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) */
+ scanline[x1] += area * (1.0f-((float)((float)x_top - (float)x1)+(float)(x1+1-x1))/2.0f);
+
+ step = sign * dy;
+ for (x = x1+1; x < x2; ++x) {
+ scanline[x] += area + step/2;
+ area += step;
+ }
+ y_crossing += (float)dy * (float)(x2 - (x1+1));
+
+ scanline[x2] += area + sign * (1.0f-((float)(x2-x2)+((float)x_bottom-(float)x2))/2.0f) * (y1-y_crossing);
+ scanline_fill[x2] += sign * (y1-y0);
+ }
+ }
+ else
+ {
+ /* if edge goes outside of box we're drawing, we require */
+ /* clipping logic. since this does not match the intended use */
+ /* of this library, we use a different, very slow brute */
+ /* force implementation */
+ int x;
+ for (x=0; x < len; ++x)
+ {
+ /* cases: */
+ /* */
+ /* there can be up to two intersections with the pixel. any intersection */
+ /* with left or right edges can be handled by splitting into two (or three) */
+ /* regions. intersections with top & bottom do not necessitate case-wise logic. */
+ /* */
+ /* the old way of doing this found the intersections with the left & right edges, */
+ /* then used some simple logic to produce up to three segments in sorted order */
+ /* from top-to-bottom. however, this had a problem: if an x edge was epsilon */
+ /* across the x border, then the corresponding y position might not be distinct */
+ /* from the other y segment, and it might ignored as an empty segment. to avoid */
+ /* that, we need to explicitly produce segments based on x positions. */
+
+ /* rename variables to clear pairs */
+ float ya = y_top;
+ float x1 = (float) (x);
+ float x2 = (float) (x+1);
+ float x3 = xb;
+ float y3 = y_bottom;
+ float yb,y2;
+
+ yb = ((float)x - x0) / dx + y_top;
+ y2 = ((float)x+1 - x0) / dx + y_top;
+
+ if (x0 < x1 && x3 > x2) { /* three segments descending down-right */
+ nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
+ nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x2,y2);
+ nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
+ } else if (x3 < x1 && x0 > x2) { /* three segments descending down-left */
+ nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
+ nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x1,yb);
+ nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
+ } else if (x0 < x1 && x3 > x1) { /* two segments across x, down-right */
+ nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
+ nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
+ } else if (x3 < x1 && x0 > x1) { /* two segments across x, down-left */
+ nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x1,yb);
+ nk_tt__handle_clipped_edge(scanline,x,e, x1,yb, x3,y3);
+ } else if (x0 < x2 && x3 > x2) { /* two segments across x+1, down-right */
+ nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
+ nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
+ } else if (x3 < x2 && x0 > x2) { /* two segments across x+1, down-left */
+ nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x2,y2);
+ nk_tt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3);
+ } else { /* one segment */
+ nk_tt__handle_clipped_edge(scanline,x,e, x0,ya, x3,y3);
+ }
+ }
+ }
+ }
+ e = e->next;
+ }
+}
+
+/* directly AA rasterize edges w/o supersampling */
+NK_INTERN void
+nk_tt__rasterize_sorted_edges(struct nk_tt__bitmap *result, struct nk_tt__edge *e,
+ int n, int vsubsample, int off_x, int off_y, struct nk_allocator *alloc)
+{
+ struct nk_tt__hheap hh;
+ struct nk_tt__active_edge *active = 0;
+ int y,j=0, i;
+ float scanline_data[129], *scanline, *scanline2;
+
+ NK_UNUSED(vsubsample);
+ nk_zero_struct(hh);
+ hh.alloc = *alloc;
+
+ if (result->w > 64)
+ scanline = (float *) alloc->alloc(alloc->userdata,0, (nk_size)(result->w*2+1) * sizeof(float));
+ else scanline = scanline_data;
+
+ scanline2 = scanline + result->w;
+ y = off_y;
+ e[n].y0 = (float) (off_y + result->h) + 1;
+
+ while (j < result->h)
+ {
+ /* find center of pixel for this scanline */
+ float scan_y_top = (float)y + 0.0f;
+ float scan_y_bottom = (float)y + 1.0f;
+ struct nk_tt__active_edge **step = &active;
+
+ NK_MEMSET(scanline , 0, (nk_size)result->w*sizeof(scanline[0]));
+ NK_MEMSET(scanline2, 0, (nk_size)(result->w+1)*sizeof(scanline[0]));
+
+ /* update all active edges; */
+ /* remove all active edges that terminate before the top of this scanline */
+ while (*step) {
+ struct nk_tt__active_edge * z = *step;
+ if (z->ey <= scan_y_top) {
+ *step = z->next; /* delete from list */
+ NK_ASSERT(z->direction);
+ z->direction = 0;
+ nk_tt__hheap_free(&hh, z);
+ } else {
+ step = &((*step)->next); /* advance through list */
+ }
+ }
+
+ /* insert all edges that start before the bottom of this scanline */
+ while (e->y0 <= scan_y_bottom) {
+ if (e->y0 != e->y1) {
+ struct nk_tt__active_edge *z = nk_tt__new_active(&hh, e, off_x, scan_y_top);
+ if (z != 0) {
+ NK_ASSERT(z->ey >= scan_y_top);
+ /* insert at front */
+ z->next = active;
+ active = z;
+ }
+ }
+ ++e;
+ }
+
+ /* now process all active edges */
+ if (active)
+ nk_tt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top);
+
+ {
+ float sum = 0;
+ for (i=0; i < result->w; ++i) {
+ float k;
+ int m;
+ sum += scanline2[i];
+ k = scanline[i] + sum;
+ k = (float) NK_ABS(k) * 255.0f + 0.5f;
+ m = (int) k;
+ if (m > 255) m = 255;
+ result->pixels[j*result->stride + i] = (unsigned char) m;
+ }
+ }
+ /* advance all the edges */
+ step = &active;
+ while (*step) {
+ struct nk_tt__active_edge *z = *step;
+ z->fx += z->fdx; /* advance to position for current scanline */
+ step = &((*step)->next); /* advance through list */
+ }
+ ++y;
+ ++j;
+ }
+ nk_tt__hheap_cleanup(&hh);
+ if (scanline != scanline_data)
+ alloc->free(alloc->userdata, scanline);
+}
+
+#define NK_TT__COMPARE(a,b) ((a)->y0 < (b)->y0)
+NK_INTERN void
+nk_tt__sort_edges_ins_sort(struct nk_tt__edge *p, int n)
+{
+ int i,j;
+ for (i=1; i < n; ++i) {
+ struct nk_tt__edge t = p[i], *a = &t;
+ j = i;
+ while (j > 0) {
+ struct nk_tt__edge *b = &p[j-1];
+ int c = NK_TT__COMPARE(a,b);
+ if (!c) break;
+ p[j] = p[j-1];
+ --j;
+ }
+ if (i != j)
+ p[j] = t;
+ }
+}
+
+NK_INTERN void
+nk_tt__sort_edges_quicksort(struct nk_tt__edge *p, int n)
+{
+ /* threshold for transitioning to insertion sort */
+ while (n > 12) {
+ struct nk_tt__edge t;
+ int c01,c12,c,m,i,j;
+
+ /* compute median of three */
+ m = n >> 1;
+ c01 = NK_TT__COMPARE(&p[0],&p[m]);
+ c12 = NK_TT__COMPARE(&p[m],&p[n-1]);
+
+ /* if 0 >= mid >= end, or 0 < mid < end, then use mid */
+ if (c01 != c12) {
+ /* otherwise, we'll need to swap something else to middle */
+ int z;
+ c = NK_TT__COMPARE(&p[0],&p[n-1]);
+ /* 0>mid && mid<n: 0>n => n; 0<n => 0 */
+ /* 0<mid && mid>n: 0>n => 0; 0<n => n */
+ z = (c == c12) ? 0 : n-1;
+ t = p[z];
+ p[z] = p[m];
+ p[m] = t;
+ }
+
+ /* now p[m] is the median-of-three */
+ /* swap it to the beginning so it won't move around */
+ t = p[0];
+ p[0] = p[m];
+ p[m] = t;
+
+ /* partition loop */
+ i=1;
+ j=n-1;
+ for(;;) {
+ /* handling of equality is crucial here */
+ /* for sentinels & efficiency with duplicates */
+ for (;;++i) {
+ if (!NK_TT__COMPARE(&p[i], &p[0])) break;
+ }
+ for (;;--j) {
+ if (!NK_TT__COMPARE(&p[0], &p[j])) break;
+ }
+
+ /* make sure we haven't crossed */
+ if (i >= j) break;
+ t = p[i];
+ p[i] = p[j];
+ p[j] = t;
+
+ ++i;
+ --j;
+
+ }
+
+ /* recurse on smaller side, iterate on larger */
+ if (j < (n-i)) {
+ nk_tt__sort_edges_quicksort(p,j);
+ p = p+i;
+ n = n-i;
+ } else {
+ nk_tt__sort_edges_quicksort(p+i, n-i);
+ n = j;
+ }
+ }
+}
+
+NK_INTERN void
+nk_tt__sort_edges(struct nk_tt__edge *p, int n)
+{
+ nk_tt__sort_edges_quicksort(p, n);
+ nk_tt__sort_edges_ins_sort(p, n);
+}
+
+NK_INTERN void
+nk_tt__rasterize(struct nk_tt__bitmap *result, struct nk_tt__point *pts,
+ int *wcount, int windings, float scale_x, float scale_y,
+ float shift_x, float shift_y, int off_x, int off_y, int invert,
+ struct nk_allocator *alloc)
+{
+ float y_scale_inv = invert ? -scale_y : scale_y;
+ struct nk_tt__edge *e;
+ int n,i,j,k,m;
+ int vsubsample = 1;
+ /* vsubsample should divide 255 evenly; otherwise we won't reach full opacity */
+
+ /* now we have to blow out the windings into explicit edge lists */
+ n = 0;
+ for (i=0; i < windings; ++i)
+ n += wcount[i];
+
+ e = (struct nk_tt__edge*)
+ alloc->alloc(alloc->userdata, 0,(sizeof(*e) * (nk_size)(n+1)));
+ if (e == 0) return;
+ n = 0;
+
+ m=0;
+ for (i=0; i < windings; ++i)
+ {
+ struct nk_tt__point *p = pts + m;
+ m += wcount[i];
+ j = wcount[i]-1;
+ for (k=0; k < wcount[i]; j=k++) {
+ int a=k,b=j;
+ /* skip the edge if horizontal */
+ if (p[j].y == p[k].y)
+ continue;
+
+ /* add edge from j to k to the list */
+ e[n].invert = 0;
+ if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
+ e[n].invert = 1;
+ a=j,b=k;
+ }
+ e[n].x0 = p[a].x * scale_x + shift_x;
+ e[n].y0 = (p[a].y * y_scale_inv + shift_y) * (float)vsubsample;
+ e[n].x1 = p[b].x * scale_x + shift_x;
+ e[n].y1 = (p[b].y * y_scale_inv + shift_y) * (float)vsubsample;
+ ++n;
+ }
+ }
+
+ /* now sort the edges by their highest point (should snap to integer, and then by x) */
+ /*STBTT_sort(e, n, sizeof(e[0]), nk_tt__edge_compare); */
+ nk_tt__sort_edges(e, n);
+ /* now, traverse the scanlines and find the intersections on each scanline, use xor winding rule */
+ nk_tt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, alloc);
+ alloc->free(alloc->userdata, e);
+}
+
+NK_INTERN void
+nk_tt__add_point(struct nk_tt__point *points, int n, float x, float y)
+{
+ if (!points) return; /* during first pass, it's unallocated */
+ points[n].x = x;
+ points[n].y = y;
+}
+
+NK_INTERN int
+nk_tt__tesselate_curve(struct nk_tt__point *points, int *num_points,
+ float x0, float y0, float x1, float y1, float x2, float y2,
+ float objspace_flatness_squared, int n)
+{
+ /* tesselate until threshold p is happy...
+ * @TODO warped to compensate for non-linear stretching */
+ /* midpoint */
+ float mx = (x0 + 2*x1 + x2)/4;
+ float my = (y0 + 2*y1 + y2)/4;
+ /* versus directly drawn line */
+ float dx = (x0+x2)/2 - mx;
+ float dy = (y0+y2)/2 - my;
+ if (n > 16) /* 65536 segments on one curve better be enough! */
+ return 1;
+
+ /* half-pixel error allowed... need to be smaller if AA */
+ if (dx*dx+dy*dy > objspace_flatness_squared) {
+ nk_tt__tesselate_curve(points, num_points, x0,y0,
+ (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
+ nk_tt__tesselate_curve(points, num_points, mx,my,
+ (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
+ } else {
+ nk_tt__add_point(points, *num_points,x2,y2);
+ *num_points = *num_points+1;
+ }
+ return 1;
+}
+
+/* returns number of contours */
+NK_INTERN struct nk_tt__point*
+nk_tt_FlattenCurves(struct nk_tt_vertex *vertices, int num_verts,
+ float objspace_flatness, int **contour_lengths, int *num_contours,
+ struct nk_allocator *alloc)
+{
+ struct nk_tt__point *points=0;
+ int num_points=0;
+ float objspace_flatness_squared = objspace_flatness * objspace_flatness;
+ int i;
+ int n=0;
+ int start=0;
+ int pass;
+
+ /* count how many "moves" there are to get the contour count */
+ for (i=0; i < num_verts; ++i)
+ if (vertices[i].type == NK_TT_vmove) ++n;
+
+ *num_contours = n;
+ if (n == 0) return 0;
+
+ *contour_lengths = (int *)
+ alloc->alloc(alloc->userdata,0, (sizeof(**contour_lengths) * (nk_size)n));
+ if (*contour_lengths == 0) {
+ *num_contours = 0;
+ return 0;
+ }
+
+ /* make two passes through the points so we don't need to realloc */
+ for (pass=0; pass < 2; ++pass)
+ {
+ float x=0,y=0;
+ if (pass == 1) {
+ points = (struct nk_tt__point *)
+ alloc->alloc(alloc->userdata,0, (nk_size)num_points * sizeof(points[0]));
+ if (points == 0) goto error;
+ }
+ num_points = 0;
+ n= -1;
+
+ for (i=0; i < num_verts; ++i)
+ {
+ switch (vertices[i].type) {
+ case NK_TT_vmove:
+ /* start the next contour */
+ if (n >= 0)
+ (*contour_lengths)[n] = num_points - start;
+ ++n;
+ start = num_points;
+
+ x = vertices[i].x, y = vertices[i].y;
+ nk_tt__add_point(points, num_points++, x,y);
+ break;
+ case NK_TT_vline:
+ x = vertices[i].x, y = vertices[i].y;
+ nk_tt__add_point(points, num_points++, x, y);
+ break;
+ case NK_TT_vcurve:
+ nk_tt__tesselate_curve(points, &num_points, x,y,
+ vertices[i].cx, vertices[i].cy,
+ vertices[i].x, vertices[i].y,
+ objspace_flatness_squared, 0);
+ x = vertices[i].x, y = vertices[i].y;
+ break;
+ default: break;
+ }
+ }
+ (*contour_lengths)[n] = num_points - start;
+ }
+ return points;
+
+error:
+ alloc->free(alloc->userdata, points);
+ alloc->free(alloc->userdata, *contour_lengths);
+ *contour_lengths = 0;
+ *num_contours = 0;
+ return 0;
+}
+
+NK_INTERN void
+nk_tt_Rasterize(struct nk_tt__bitmap *result, float flatness_in_pixels,
+ struct nk_tt_vertex *vertices, int num_verts,
+ float scale_x, float scale_y, float shift_x, float shift_y,
+ int x_off, int y_off, int invert, struct nk_allocator *alloc)
+{
+ float scale = scale_x > scale_y ? scale_y : scale_x;
+ int winding_count, *winding_lengths;
+ struct nk_tt__point *windings = nk_tt_FlattenCurves(vertices, num_verts,
+ flatness_in_pixels / scale, &winding_lengths, &winding_count, alloc);
+
+ NK_ASSERT(alloc);
+ if (windings) {
+ nk_tt__rasterize(result, windings, winding_lengths, winding_count,
+ scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, alloc);
+ alloc->free(alloc->userdata, winding_lengths);
+ alloc->free(alloc->userdata, windings);
+ }
+}
+
+NK_INTERN void
+nk_tt_MakeGlyphBitmapSubpixel(const struct nk_tt_fontinfo *info, unsigned char *output,
+ int out_w, int out_h, int out_stride, float scale_x, float scale_y,
+ float shift_x, float shift_y, int glyph, struct nk_allocator *alloc)
+{
+ int ix0,iy0;
+ struct nk_tt_vertex *vertices;
+ int num_verts = nk_tt_GetGlyphShape(info, alloc, glyph, &vertices);
+ struct nk_tt__bitmap gbm;
+
+ nk_tt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x,
+ shift_y, &ix0,&iy0,0,0);
+ gbm.pixels = output;
+ gbm.w = out_w;
+ gbm.h = out_h;
+ gbm.stride = out_stride;
+
+ if (gbm.w && gbm.h)
+ nk_tt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y,
+ shift_x, shift_y, ix0,iy0, 1, alloc);
+ alloc->free(alloc->userdata, vertices);
+}
+
+/*-------------------------------------------------------------
+ * Bitmap baking
+ * --------------------------------------------------------------*/
+NK_INTERN int
+nk_tt_PackBegin(struct nk_tt_pack_context *spc, unsigned char *pixels,
+ int pw, int ph, int stride_in_bytes, int padding, struct nk_allocator *alloc)
+{
+ int num_nodes = pw - padding;
+ struct nk_rp_context *context = (struct nk_rp_context *)
+ alloc->alloc(alloc->userdata,0, sizeof(*context));
+ struct nk_rp_node *nodes = (struct nk_rp_node*)
+ alloc->alloc(alloc->userdata,0, (sizeof(*nodes ) * (nk_size)num_nodes));
+
+ if (context == 0 || nodes == 0) {
+ if (context != 0) alloc->free(alloc->userdata, context);
+ if (nodes != 0) alloc->free(alloc->userdata, nodes);
+ return 0;
+ }
+
+ spc->width = pw;
+ spc->height = ph;
+ spc->pixels = pixels;
+ spc->pack_info = context;
+ spc->nodes = nodes;
+ spc->padding = padding;
+ spc->stride_in_bytes = (stride_in_bytes != 0) ? stride_in_bytes : pw;
+ spc->h_oversample = 1;
+ spc->v_oversample = 1;
+
+ nk_rp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
+ if (pixels)
+ NK_MEMSET(pixels, 0, (nk_size)(pw*ph)); /* background of 0 around pixels */
+ return 1;
+}
+
+NK_INTERN void
+nk_tt_PackEnd(struct nk_tt_pack_context *spc, struct nk_allocator *alloc)
+{
+ alloc->free(alloc->userdata, spc->nodes);
+ alloc->free(alloc->userdata, spc->pack_info);
+}
+
+NK_INTERN void
+nk_tt_PackSetOversampling(struct nk_tt_pack_context *spc,
+ unsigned int h_oversample, unsigned int v_oversample)
+{
+ NK_ASSERT(h_oversample <= NK_TT_MAX_OVERSAMPLE);
+ NK_ASSERT(v_oversample <= NK_TT_MAX_OVERSAMPLE);
+ if (h_oversample <= NK_TT_MAX_OVERSAMPLE)
+ spc->h_oversample = h_oversample;
+ if (v_oversample <= NK_TT_MAX_OVERSAMPLE)
+ spc->v_oversample = v_oversample;
+}
+
+NK_INTERN void
+nk_tt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes,
+ int kernel_width)
+{
+ unsigned char buffer[NK_TT_MAX_OVERSAMPLE];
+ int safe_w = w - kernel_width;
+ int j;
+
+ for (j=0; j < h; ++j)
+ {
+ int i;
+ unsigned int total;
+ NK_MEMSET(buffer, 0, (nk_size)kernel_width);
+
+ total = 0;
+
+ /* make kernel_width a constant in common cases so compiler can optimize out the divide */
+ switch (kernel_width) {
+ case 2:
+ for (i=0; i <= safe_w; ++i) {
+ total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
+ buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
+ pixels[i] = (unsigned char) (total / 2);
+ }
+ break;
+ case 3:
+ for (i=0; i <= safe_w; ++i) {
+ total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
+ buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
+ pixels[i] = (unsigned char) (total / 3);
+ }
+ break;
+ case 4:
+ for (i=0; i <= safe_w; ++i) {
+ total += (unsigned int)pixels[i] - buffer[i & NK_TT__OVER_MASK];
+ buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
+ pixels[i] = (unsigned char) (total / 4);
+ }
+ break;
+ case 5:
+ for (i=0; i <= safe_w; ++i) {
+ total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
+ buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
+ pixels[i] = (unsigned char) (total / 5);
+ }
+ break;
+ default:
+ for (i=0; i <= safe_w; ++i) {
+ total += (unsigned int)(pixels[i] - buffer[i & NK_TT__OVER_MASK]);
+ buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i];
+ pixels[i] = (unsigned char) (total / (unsigned int)kernel_width);
+ }
+ break;
+ }
+
+ for (; i < w; ++i) {
+ NK_ASSERT(pixels[i] == 0);
+ total -= (unsigned int)(buffer[i & NK_TT__OVER_MASK]);
+ pixels[i] = (unsigned char) (total / (unsigned int)kernel_width);
+ }
+ pixels += stride_in_bytes;
+ }
+}
+
+NK_INTERN void
+nk_tt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes,
+ int kernel_width)
+{
+ unsigned char buffer[NK_TT_MAX_OVERSAMPLE];
+ int safe_h = h - kernel_width;
+ int j;
+
+ for (j=0; j < w; ++j)
+ {
+ int i;
+ unsigned int total;
+ NK_MEMSET(buffer, 0, (nk_size)kernel_width);
+
+ total = 0;
+
+ /* make kernel_width a constant in common cases so compiler can optimize out the divide */
+ switch (kernel_width) {
+ case 2:
+ for (i=0; i <= safe_h; ++i) {
+ total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
+ buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
+ pixels[i*stride_in_bytes] = (unsigned char) (total / 2);
+ }
+ break;
+ case 3:
+ for (i=0; i <= safe_h; ++i) {
+ total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
+ buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
+ pixels[i*stride_in_bytes] = (unsigned char) (total / 3);
+ }
+ break;
+ case 4:
+ for (i=0; i <= safe_h; ++i) {
+ total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
+ buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
+ pixels[i*stride_in_bytes] = (unsigned char) (total / 4);
+ }
+ break;
+ case 5:
+ for (i=0; i <= safe_h; ++i) {
+ total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
+ buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
+ pixels[i*stride_in_bytes] = (unsigned char) (total / 5);
+ }
+ break;
+ default:
+ for (i=0; i <= safe_h; ++i) {
+ total += (unsigned int)(pixels[i*stride_in_bytes] - buffer[i & NK_TT__OVER_MASK]);
+ buffer[(i+kernel_width) & NK_TT__OVER_MASK] = pixels[i*stride_in_bytes];
+ pixels[i*stride_in_bytes] = (unsigned char) (total / (unsigned int)kernel_width);
+ }
+ break;
+ }
+
+ for (; i < h; ++i) {
+ NK_ASSERT(pixels[i*stride_in_bytes] == 0);
+ total -= (unsigned int)(buffer[i & NK_TT__OVER_MASK]);
+ pixels[i*stride_in_bytes] = (unsigned char) (total / (unsigned int)kernel_width);
+ }
+ pixels += 1;
+ }
+}
+
+NK_INTERN float
+nk_tt__oversample_shift(int oversample)
+{
+ if (!oversample)
+ return 0.0f;
+
+ /* The prefilter is a box filter of width "oversample", */
+ /* which shifts phase by (oversample - 1)/2 pixels in */
+ /* oversampled space. We want to shift in the opposite */
+ /* direction to counter this. */
+ return (float)-(oversample - 1) / (2.0f * (float)oversample);
+}
+
+/* rects array must be big enough to accommodate all characters in the given ranges */
+NK_INTERN int
+nk_tt_PackFontRangesGatherRects(struct nk_tt_pack_context *spc,
+ struct nk_tt_fontinfo *info, struct nk_tt_pack_range *ranges,
+ int num_ranges, struct nk_rp_rect *rects)
+{
+ int i,j,k;
+ k = 0;
+
+ for (i=0; i < num_ranges; ++i) {
+ float fh = ranges[i].font_size;
+ float scale = (fh > 0) ? nk_tt_ScaleForPixelHeight(info, fh):
+ nk_tt_ScaleForMappingEmToPixels(info, -fh);
+ ranges[i].h_oversample = (unsigned char) spc->h_oversample;
+ ranges[i].v_oversample = (unsigned char) spc->v_oversample;
+ for (j=0; j < ranges[i].num_chars; ++j) {
+ int x0,y0,x1,y1;
+ int codepoint = ranges[i].first_unicode_codepoint_in_range ?
+ ranges[i].first_unicode_codepoint_in_range + j :
+ ranges[i].array_of_unicode_codepoints[j];
+
+ int glyph = nk_tt_FindGlyphIndex(info, codepoint);
+ nk_tt_GetGlyphBitmapBoxSubpixel(info,glyph, scale * (float)spc->h_oversample,
+ scale * (float)spc->v_oversample, 0,0, &x0,&y0,&x1,&y1);
+ rects[k].w = (nk_rp_coord) (x1-x0 + spc->padding + (int)spc->h_oversample-1);
+ rects[k].h = (nk_rp_coord) (y1-y0 + spc->padding + (int)spc->v_oversample-1);
+ ++k;
+ }
+ }
+ return k;
+}
+
+NK_INTERN int
+nk_tt_PackFontRangesRenderIntoRects(struct nk_tt_pack_context *spc,
+ struct nk_tt_fontinfo *info, struct nk_tt_pack_range *ranges,
+ int num_ranges, struct nk_rp_rect *rects, struct nk_allocator *alloc)
+{
+ int i,j,k, return_value = 1;
+ /* save current values */
+ int old_h_over = (int)spc->h_oversample;
+ int old_v_over = (int)spc->v_oversample;
+ /* rects array must be big enough to accommodate all characters in the given ranges */
+
+ k = 0;
+ for (i=0; i < num_ranges; ++i)
+ {
+ float fh = ranges[i].font_size;
+ float recip_h,recip_v,sub_x,sub_y;
+ float scale = fh > 0 ? nk_tt_ScaleForPixelHeight(info, fh):
+ nk_tt_ScaleForMappingEmToPixels(info, -fh);
+
+ spc->h_oversample = ranges[i].h_oversample;
+ spc->v_oversample = ranges[i].v_oversample;
+
+ recip_h = 1.0f / (float)spc->h_oversample;
+ recip_v = 1.0f / (float)spc->v_oversample;
+
+ sub_x = nk_tt__oversample_shift((int)spc->h_oversample);
+ sub_y = nk_tt__oversample_shift((int)spc->v_oversample);
+
+ for (j=0; j < ranges[i].num_chars; ++j)
+ {
+ struct nk_rp_rect *r = &rects[k];
+ if (r->was_packed)
+ {
+ struct nk_tt_packedchar *bc = &ranges[i].chardata_for_range[j];
+ int advance, lsb, x0,y0,x1,y1;
+ int codepoint = ranges[i].first_unicode_codepoint_in_range ?
+ ranges[i].first_unicode_codepoint_in_range + j :
+ ranges[i].array_of_unicode_codepoints[j];
+ int glyph = nk_tt_FindGlyphIndex(info, codepoint);
+ nk_rp_coord pad = (nk_rp_coord) spc->padding;
+
+ /* pad on left and top */
+ r->x = (nk_rp_coord)((int)r->x + (int)pad);
+ r->y = (nk_rp_coord)((int)r->y + (int)pad);
+ r->w = (nk_rp_coord)((int)r->w - (int)pad);
+ r->h = (nk_rp_coord)((int)r->h - (int)pad);
+
+ nk_tt_GetGlyphHMetrics(info, glyph, &advance, &lsb);
+ nk_tt_GetGlyphBitmapBox(info, glyph, scale * (float)spc->h_oversample,
+ (scale * (float)spc->v_oversample), &x0,&y0,&x1,&y1);
+ nk_tt_MakeGlyphBitmapSubpixel(info, spc->pixels + r->x + r->y*spc->stride_in_bytes,
+ (int)(r->w - spc->h_oversample+1), (int)(r->h - spc->v_oversample+1),
+ spc->stride_in_bytes, scale * (float)spc->h_oversample,
+ scale * (float)spc->v_oversample, 0,0, glyph, alloc);
+
+ if (spc->h_oversample > 1)
+ nk_tt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
+ r->w, r->h, spc->stride_in_bytes, (int)spc->h_oversample);
+
+ if (spc->v_oversample > 1)
+ nk_tt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
+ r->w, r->h, spc->stride_in_bytes, (int)spc->v_oversample);
+
+ bc->x0 = (nk_ushort) r->x;
+ bc->y0 = (nk_ushort) r->y;
+ bc->x1 = (nk_ushort) (r->x + r->w);
+ bc->y1 = (nk_ushort) (r->y + r->h);
+ bc->xadvance = scale * (float)advance;
+ bc->xoff = (float) x0 * recip_h + sub_x;
+ bc->yoff = (float) y0 * recip_v + sub_y;
+ bc->xoff2 = ((float)x0 + r->w) * recip_h + sub_x;
+ bc->yoff2 = ((float)y0 + r->h) * recip_v + sub_y;
+ } else {
+ return_value = 0; /* if any fail, report failure */
+ }
+ ++k;
+ }
+ }
+ /* restore original values */
+ spc->h_oversample = (unsigned int)old_h_over;
+ spc->v_oversample = (unsigned int)old_v_over;
+ return return_value;
+}
+
+NK_INTERN void
+nk_tt_GetPackedQuad(struct nk_tt_packedchar *chardata, int pw, int ph,
+ int char_index, float *xpos, float *ypos, struct nk_tt_aligned_quad *q,
+ int align_to_integer)
+{
+ float ipw = 1.0f / (float)pw, iph = 1.0f / (float)ph;
+ struct nk_tt_packedchar *b = (struct nk_tt_packedchar*)(chardata + char_index);
+ if (align_to_integer) {
+ int tx = nk_ifloorf((*xpos + b->xoff) + 0.5f);
+ int ty = nk_ifloorf((*ypos + b->yoff) + 0.5f);
+
+ float x = (float)tx;
+ float y = (float)ty;
+
+ q->x0 = x;
+ q->y0 = y;
+ q->x1 = x + b->xoff2 - b->xoff;
+ q->y1 = y + b->yoff2 - b->yoff;
+ } else {
+ q->x0 = *xpos + b->xoff;
+ q->y0 = *ypos + b->yoff;
+ q->x1 = *xpos + b->xoff2;
+ q->y1 = *ypos + b->yoff2;
+ }
+ q->s0 = b->x0 * ipw;
+ q->t0 = b->y0 * iph;
+ q->s1 = b->x1 * ipw;
+ q->t1 = b->y1 * iph;
+ *xpos += b->xadvance;
+}
+
+/* -------------------------------------------------------------
+ *
+ * FONT BAKING
+ *
+ * --------------------------------------------------------------*/
+struct nk_font_bake_data {
+ struct nk_tt_fontinfo info;
+ struct nk_rp_rect *rects;
+ struct nk_tt_pack_range *ranges;
+ nk_rune range_count;
+};
+
+struct nk_font_baker {
+ struct nk_allocator alloc;
+ struct nk_tt_pack_context spc;
+ struct nk_font_bake_data *build;
+ struct nk_tt_packedchar *packed_chars;
+ struct nk_rp_rect *rects;
+ struct nk_tt_pack_range *ranges;
+};
+
+NK_GLOBAL const nk_size nk_rect_align = NK_ALIGNOF(struct nk_rp_rect);
+NK_GLOBAL const nk_size nk_range_align = NK_ALIGNOF(struct nk_tt_pack_range);
+NK_GLOBAL const nk_size nk_char_align = NK_ALIGNOF(struct nk_tt_packedchar);
+NK_GLOBAL const nk_size nk_build_align = NK_ALIGNOF(struct nk_font_bake_data);
+NK_GLOBAL const nk_size nk_baker_align = NK_ALIGNOF(struct nk_font_baker);
+
+NK_INTERN int
+nk_range_count(const nk_rune *range)
+{
+ const nk_rune *iter = range;
+ NK_ASSERT(range);
+ if (!range) return 0;
+ while (*(iter++) != 0);
+ return (iter == range) ? 0 : (int)((iter - range)/2);
+}
+
+NK_INTERN int
+nk_range_glyph_count(const nk_rune *range, int count)
+{
+ int i = 0;
+ int total_glyphs = 0;
+ for (i = 0; i < count; ++i) {
+ int diff;
+ nk_rune f = range[(i*2)+0];
+ nk_rune t = range[(i*2)+1];
+ NK_ASSERT(t >= f);
+ diff = (int)((t - f) + 1);
+ total_glyphs += diff;
+ }
+ return total_glyphs;
+}
+
+NK_API const nk_rune*
+nk_font_default_glyph_ranges(void)
+{
+ NK_STORAGE const nk_rune ranges[] = {0x0020, 0x00FF, 0};
+ return ranges;
+}
+
+NK_API const nk_rune*
+nk_font_chinese_glyph_ranges(void)
+{
+ NK_STORAGE const nk_rune ranges[] = {
+ 0x0020, 0x00FF,
+ 0x3000, 0x30FF,
+ 0x31F0, 0x31FF,
+ 0xFF00, 0xFFEF,
+ 0x4e00, 0x9FAF,
+ 0
+ };
+ return ranges;
+}
+
+NK_API const nk_rune*
+nk_font_cyrillic_glyph_ranges(void)
+{
+ NK_STORAGE const nk_rune ranges[] = {
+ 0x0020, 0x00FF,
+ 0x0400, 0x052F,
+ 0x2DE0, 0x2DFF,
+ 0xA640, 0xA69F,
+ 0
+ };
+ return ranges;
+}
+
+NK_API const nk_rune*
+nk_font_korean_glyph_ranges(void)
+{
+ NK_STORAGE const nk_rune ranges[] = {
+ 0x0020, 0x00FF,
+ 0x3131, 0x3163,
+ 0xAC00, 0xD79D,
+ 0
+ };
+ return ranges;
+}
+
+NK_INTERN void
+nk_font_baker_memory(nk_size *temp, int *glyph_count,
+ struct nk_font_config *config_list, int count)
+{
+ int range_count = 0;
+ int total_range_count = 0;
+ struct nk_font_config *iter, *i;
+
+ NK_ASSERT(config_list);
+ NK_ASSERT(glyph_count);
+ if (!config_list) {
+ *temp = 0;
+ *glyph_count = 0;
+ return;
+ }
+ *glyph_count = 0;
+ for (iter = config_list; iter; iter = iter->next) {
+ i = iter;
+ do {if (!i->range) iter->range = nk_font_default_glyph_ranges();
+ range_count = nk_range_count(i->range);
+ total_range_count += range_count;
+ *glyph_count += nk_range_glyph_count(i->range, range_count);
+ } while ((i = i->n) != iter);
+ }
+ *temp = (nk_size)*glyph_count * sizeof(struct nk_rp_rect);
+ *temp += (nk_size)total_range_count * sizeof(struct nk_tt_pack_range);
+ *temp += (nk_size)*glyph_count * sizeof(struct nk_tt_packedchar);
+ *temp += (nk_size)count * sizeof(struct nk_font_bake_data);
+ *temp += sizeof(struct nk_font_baker);
+ *temp += nk_rect_align + nk_range_align + nk_char_align;
+ *temp += nk_build_align + nk_baker_align;
+}
+
+NK_INTERN struct nk_font_baker*
+nk_font_baker(void *memory, int glyph_count, int count, struct nk_allocator *alloc)
+{
+ struct nk_font_baker *baker;
+ if (!memory) return 0;
+ /* setup baker inside a memory block */
+ baker = (struct nk_font_baker*)NK_ALIGN_PTR(memory, nk_baker_align);
+ baker->build = (struct nk_font_bake_data*)NK_ALIGN_PTR((baker + 1), nk_build_align);
+ baker->packed_chars = (struct nk_tt_packedchar*)NK_ALIGN_PTR((baker->build + count), nk_char_align);
+ baker->rects = (struct nk_rp_rect*)NK_ALIGN_PTR((baker->packed_chars + glyph_count), nk_rect_align);
+ baker->ranges = (struct nk_tt_pack_range*)NK_ALIGN_PTR((baker->rects + glyph_count), nk_range_align);
+ baker->alloc = *alloc;
+ return baker;
+}
+
+NK_INTERN int
+nk_font_bake_pack(struct nk_font_baker *baker,
+ nk_size *image_memory, int *width, int *height, struct nk_recti *custom,
+ const struct nk_font_config *config_list, int count,
+ struct nk_allocator *alloc)
+{
+ NK_STORAGE const nk_size max_height = 1024 * 32;
+ const struct nk_font_config *config_iter, *it;
+ int total_glyph_count = 0;
+ int total_range_count = 0;
+ int range_count = 0;
+ int i = 0;
+
+ NK_ASSERT(image_memory);
+ NK_ASSERT(width);
+ NK_ASSERT(height);
+ NK_ASSERT(config_list);
+ NK_ASSERT(count);
+ NK_ASSERT(alloc);
+
+ if (!image_memory || !width || !height || !config_list || !count) return nk_false;
+ for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
+ it = config_iter;
+ do {range_count = nk_range_count(it->range);
+ total_range_count += range_count;
+ total_glyph_count += nk_range_glyph_count(it->range, range_count);
+ } while ((it = it->n) != config_iter);
+ }
+ /* setup font baker from temporary memory */
+ for (config_iter = config_list; config_iter; config_iter = config_iter->next) {
+ it = config_iter;
+ do {if (!nk_tt_InitFont(&baker->build[i++].info, (const unsigned char*)it->ttf_blob, 0))
+ return nk_false;
+ } while ((it = it->n) != config_iter);
+ }
+ *height = 0;
+ *width = (total_glyph_count > 1000) ? 1024 : 512;
+ nk_tt_PackBegin(&baker->spc, 0, (int)*width, (int)max_height, 0, 1, alloc);
+ {
+ int input_i = 0;
+ int range_n = 0;
+ int rect_n = 0;
+ int char_n = 0;
+
+ if (custom) {
+ /* pack custom user data first so it will be in the upper left corner*/
+ struct nk_rp_rect custom_space;
+ nk_zero(&custom_space, sizeof(custom_space));
+ custom_space.w = (nk_rp_coord)(custom->w);
+ custom_space.h = (nk_rp_coord)(custom->h);
+
+ nk_tt_PackSetOversampling(&baker->spc, 1, 1);
+ nk_rp_pack_rects((struct nk_rp_context*)baker->spc.pack_info, &custom_space, 1);
+ *height = NK_MAX(*height, (int)(custom_space.y + custom_space.h));
+
+ custom->x = (short)custom_space.x;
+ custom->y = (short)custom_space.y;
+ custom->w = (short)custom_space.w;
+ custom->h = (short)custom_space.h;
+ }
+
+ /* first font pass: pack all glyphs */
+ for (input_i = 0, config_iter = config_list; input_i < count && config_iter;
+ config_iter = config_iter->next) {
+ it = config_iter;
+ do {int n = 0;
+ int glyph_count;
+ const nk_rune *in_range;
+ const struct nk_font_config *cfg = it;
+ struct nk_font_bake_data *tmp = &baker->build[input_i++];
+
+ /* count glyphs + ranges in current font */
+ glyph_count = 0; range_count = 0;
+ for (in_range = cfg->range; in_range[0] && in_range[1]; in_range += 2) {
+ glyph_count += (int)(in_range[1] - in_range[0]) + 1;
+ range_count++;
+ }
+
+ /* setup ranges */
+ tmp->ranges = baker->ranges + range_n;
+ tmp->range_count = (nk_rune)range_count;
+ range_n += range_count;
+ for (i = 0; i < range_count; ++i) {
+ in_range = &cfg->range[i * 2];
+ tmp->ranges[i].font_size = cfg->size;
+ tmp->ranges[i].first_unicode_codepoint_in_range = (int)in_range[0];
+ tmp->ranges[i].num_chars = (int)(in_range[1]- in_range[0]) + 1;
+ tmp->ranges[i].chardata_for_range = baker->packed_chars + char_n;
+ char_n += tmp->ranges[i].num_chars;
+ }
+
+ /* pack */
+ tmp->rects = baker->rects + rect_n;
+ rect_n += glyph_count;
+ nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
+ n = nk_tt_PackFontRangesGatherRects(&baker->spc, &tmp->info,
+ tmp->ranges, (int)tmp->range_count, tmp->rects);
+ nk_rp_pack_rects((struct nk_rp_context*)baker->spc.pack_info, tmp->rects, (int)n);
+
+ /* texture height */
+ for (i = 0; i < n; ++i) {
+ if (tmp->rects[i].was_packed)
+ *height = NK_MAX(*height, tmp->rects[i].y + tmp->rects[i].h);
+ }
+ } while ((it = it->n) != config_iter);
+ }
+ NK_ASSERT(rect_n == total_glyph_count);
+ NK_ASSERT(char_n == total_glyph_count);
+ NK_ASSERT(range_n == total_range_count);
+ }
+ *height = (int)nk_round_up_pow2((nk_uint)*height);
+ *image_memory = (nk_size)(*width) * (nk_size)(*height);
+ return nk_true;
+}
+
+NK_INTERN void
+nk_font_bake(struct nk_font_baker *baker, void *image_memory, int width, int height,
+ struct nk_font_glyph *glyphs, int glyphs_count,
+ const struct nk_font_config *config_list, int font_count)
+{
+ int input_i = 0;
+ nk_rune glyph_n = 0;
+ const struct nk_font_config *config_iter;
+ const struct nk_font_config *it;
+
+ NK_ASSERT(image_memory);
+ NK_ASSERT(width);
+ NK_ASSERT(height);
+ NK_ASSERT(config_list);
+ NK_ASSERT(baker);
+ NK_ASSERT(font_count);
+ NK_ASSERT(glyphs_count);
+ if (!image_memory || !width || !height || !config_list ||
+ !font_count || !glyphs || !glyphs_count)
+ return;
+
+ /* second font pass: render glyphs */
+ nk_zero(image_memory, (nk_size)((nk_size)width * (nk_size)height));
+ baker->spc.pixels = (unsigned char*)image_memory;
+ baker->spc.height = (int)height;
+ for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
+ config_iter = config_iter->next) {
+ it = config_iter;
+ do {const struct nk_font_config *cfg = it;
+ struct nk_font_bake_data *tmp = &baker->build[input_i++];
+ nk_tt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v);
+ nk_tt_PackFontRangesRenderIntoRects(&baker->spc, &tmp->info, tmp->ranges,
+ (int)tmp->range_count, tmp->rects, &baker->alloc);
+ } while ((it = it->n) != config_iter);
+ } nk_tt_PackEnd(&baker->spc, &baker->alloc);
+
+ /* third pass: setup font and glyphs */
+ for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter;
+ config_iter = config_iter->next) {
+ it = config_iter;
+ do {nk_size i = 0;
+ int char_idx = 0;
+ nk_rune glyph_count = 0;
+ const struct nk_font_config *cfg = it;
+ struct nk_font_bake_data *tmp = &baker->build[input_i++];
+ struct nk_baked_font *dst_font = cfg->font;
+
+ float font_scale = nk_tt_ScaleForPixelHeight(&tmp->info, cfg->size);
+ int unscaled_ascent, unscaled_descent, unscaled_line_gap;
+ nk_tt_GetFontVMetrics(&tmp->info, &unscaled_ascent, &unscaled_descent,
+ &unscaled_line_gap);
+
+ /* fill baked font */
+ if (!cfg->merge_mode) {
+ dst_font->ranges = cfg->range;
+ dst_font->height = cfg->size;
+ dst_font->ascent = ((float)unscaled_ascent * font_scale);
+ dst_font->descent = ((float)unscaled_descent * font_scale);
+ dst_font->glyph_offset = glyph_n;
+ }
+
+ /* fill own baked font glyph array */
+ for (i = 0; i < tmp->range_count; ++i) {
+ struct nk_tt_pack_range *range = &tmp->ranges[i];
+ for (char_idx = 0; char_idx < range->num_chars; char_idx++)
+ {
+ nk_rune codepoint = 0;
+ float dummy_x = 0, dummy_y = 0;
+ struct nk_tt_aligned_quad q;
+ struct nk_font_glyph *glyph;
+
+ /* query glyph bounds from stb_truetype */
+ const struct nk_tt_packedchar *pc = &range->chardata_for_range[char_idx];
+ if (!pc->x0 && !pc->x1 && !pc->y0 && !pc->y1) continue;
+ codepoint = (nk_rune)(range->first_unicode_codepoint_in_range + char_idx);
+ nk_tt_GetPackedQuad(range->chardata_for_range, (int)width,
+ (int)height, char_idx, &dummy_x, &dummy_y, &q, 0);
+
+ /* fill own glyph type with data */
+ glyph = &glyphs[dst_font->glyph_offset + dst_font->glyph_count + (unsigned int)glyph_count];
+ glyph->codepoint = codepoint;
+ glyph->x0 = q.x0; glyph->y0 = q.y0;
+ glyph->x1 = q.x1; glyph->y1 = q.y1;
+ glyph->y0 += (dst_font->ascent + 0.5f);
+ glyph->y1 += (dst_font->ascent + 0.5f);
+ glyph->w = glyph->x1 - glyph->x0 + 0.5f;
+ glyph->h = glyph->y1 - glyph->y0;
+
+ if (cfg->coord_type == NK_COORD_PIXEL) {
+ glyph->u0 = q.s0 * (float)width;
+ glyph->v0 = q.t0 * (float)height;
+ glyph->u1 = q.s1 * (float)width;
+ glyph->v1 = q.t1 * (float)height;
+ } else {
+ glyph->u0 = q.s0;
+ glyph->v0 = q.t0;
+ glyph->u1 = q.s1;
+ glyph->v1 = q.t1;
+ }
+ glyph->xadvance = (pc->xadvance + cfg->spacing.x);
+ if (cfg->pixel_snap)
+ glyph->xadvance = (float)(int)(glyph->xadvance + 0.5f);
+ glyph_count++;
+ }
+ }
+ dst_font->glyph_count += glyph_count;
+ glyph_n += glyph_count;
+ } while ((it = it->n) != config_iter);
+ }
+}
+
+NK_INTERN void
+nk_font_bake_custom_data(void *img_memory, int img_width, int img_height,
+ struct nk_recti img_dst, const char *texture_data_mask, int tex_width,
+ int tex_height, char white, char black)
+{
+ nk_byte *pixels;
+ int y = 0;
+ int x = 0;
+ int n = 0;
+
+ NK_ASSERT(img_memory);
+ NK_ASSERT(img_width);
+ NK_ASSERT(img_height);
+ NK_ASSERT(texture_data_mask);
+ NK_UNUSED(tex_height);
+ if (!img_memory || !img_width || !img_height || !texture_data_mask)
+ return;
+
+ pixels = (nk_byte*)img_memory;
+ for (y = 0, n = 0; y < tex_height; ++y) {
+ for (x = 0; x < tex_width; ++x, ++n) {
+ const int off0 = ((img_dst.x + x) + (img_dst.y + y) * img_width);
+ const int off1 = off0 + 1 + tex_width;
+ pixels[off0] = (texture_data_mask[n] == white) ? 0xFF : 0x00;
+ pixels[off1] = (texture_data_mask[n] == black) ? 0xFF : 0x00;
+ }
+ }
+}
+
+NK_INTERN void
+nk_font_bake_convert(void *out_memory, int img_width, int img_height,
+ const void *in_memory)
+{
+ int n = 0;
+ nk_rune *dst;
+ const nk_byte *src;
+
+ NK_ASSERT(out_memory);
+ NK_ASSERT(in_memory);
+ NK_ASSERT(img_width);
+ NK_ASSERT(img_height);
+ if (!out_memory || !in_memory || !img_height || !img_width) return;
+
+ dst = (nk_rune*)out_memory;
+ src = (const nk_byte*)in_memory;
+ for (n = (int)(img_width * img_height); n > 0; n--)
+ *dst++ = ((nk_rune)(*src++) << 24) | 0x00FFFFFF;
+}
+
+/* -------------------------------------------------------------
+ *
+ * FONT
+ *
+ * --------------------------------------------------------------*/
+NK_INTERN float
+nk_font_text_width(nk_handle handle, float height, const char *text, int len)
+{
+ nk_rune unicode;
+ int text_len = 0;
+ float text_width = 0;
+ int glyph_len = 0;
+ float scale = 0;
+
+ struct nk_font *font = (struct nk_font*)handle.ptr;
+ NK_ASSERT(font);
+ NK_ASSERT(font->glyphs);
+ if (!font || !text || !len)
+ return 0;
+
+ scale = height/font->info.height;
+ glyph_len = text_len = nk_utf_decode(text, &unicode, (int)len);
+ if (!glyph_len) return 0;
+ while (text_len <= (int)len && glyph_len) {
+ const struct nk_font_glyph *g;
+ if (unicode == NK_UTF_INVALID) break;
+
+ /* query currently drawn glyph information */
+ g = nk_font_find_glyph(font, unicode);
+ text_width += g->xadvance * scale;
+
+ /* offset next glyph */
+ glyph_len = nk_utf_decode(text + text_len, &unicode, (int)len - text_len);
+ text_len += glyph_len;
+ }
+ return text_width;
+}
+
+#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+NK_INTERN void
+nk_font_query_font_glyph(nk_handle handle, float height,
+ struct nk_user_font_glyph *glyph, nk_rune codepoint, nk_rune next_codepoint)
+{
+ float scale;
+ const struct nk_font_glyph *g;
+ struct nk_font *font;
+
+ NK_ASSERT(glyph);
+ NK_UNUSED(next_codepoint);
+
+ font = (struct nk_font*)handle.ptr;
+ NK_ASSERT(font);
+ NK_ASSERT(font->glyphs);
+ if (!font || !glyph)
+ return;
+
+ scale = height/font->info.height;
+ g = nk_font_find_glyph(font, codepoint);
+ glyph->width = (g->x1 - g->x0) * scale;
+ glyph->height = (g->y1 - g->y0) * scale;
+ glyph->offset = nk_vec2(g->x0 * scale, g->y0 * scale);
+ glyph->xadvance = (g->xadvance * scale);
+ glyph->uv[0] = nk_vec2(g->u0, g->v0);
+ glyph->uv[1] = nk_vec2(g->u1, g->v1);
+}
+#endif
+
+NK_API const struct nk_font_glyph*
+nk_font_find_glyph(struct nk_font *font, nk_rune unicode)
+{
+ int i = 0;
+ int count;
+ int total_glyphs = 0;
+ const struct nk_font_glyph *glyph = 0;
+ const struct nk_font_config *iter = 0;
+
+ NK_ASSERT(font);
+ NK_ASSERT(font->glyphs);
+ NK_ASSERT(font->info.ranges);
+ if (!font || !font->glyphs) return 0;
+
+ glyph = font->fallback;
+ iter = font->config;
+ do {count = nk_range_count(iter->range);
+ for (i = 0; i < count; ++i) {
+ nk_rune f = iter->range[(i*2)+0];
+ nk_rune t = iter->range[(i*2)+1];
+ int diff = (int)((t - f) + 1);
+ if (unicode >= f && unicode <= t)
+ return &font->glyphs[((nk_rune)total_glyphs + (unicode - f))];
+ total_glyphs += diff;
+ }
+ } while ((iter = iter->n) != font->config);
+ return glyph;
+}
+
+NK_INTERN void
+nk_font_init(struct nk_font *font, float pixel_height,
+ nk_rune fallback_codepoint, struct nk_font_glyph *glyphs,
+ const struct nk_baked_font *baked_font, nk_handle atlas)
+{
+ struct nk_baked_font baked;
+ NK_ASSERT(font);
+ NK_ASSERT(glyphs);
+ NK_ASSERT(baked_font);
+ if (!font || !glyphs || !baked_font)
+ return;
+
+ baked = *baked_font;
+ font->fallback = 0;
+ font->info = baked;
+ font->scale = (float)pixel_height / (float)font->info.height;
+ font->glyphs = &glyphs[baked_font->glyph_offset];
+ font->texture = atlas;
+ font->fallback_codepoint = fallback_codepoint;
+ font->fallback = nk_font_find_glyph(font, fallback_codepoint);
+
+ font->handle.height = font->info.height * font->scale;
+ font->handle.width = nk_font_text_width;
+ font->handle.userdata.ptr = font;
+#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+ font->handle.query = nk_font_query_font_glyph;
+ font->handle.texture = font->texture;
+#endif
+}
+
+/* ---------------------------------------------------------------------------
+ *
+ * DEFAULT FONT
+ *
+ * ProggyClean.ttf
+ * Copyright (c) 2004, 2005 Tristan Grimmer
+ * MIT license (see License.txt in http://www.upperbounds.net/download/ProggyClean.ttf.zip)
+ * Download and more information at http://upperbounds.net
+ *-----------------------------------------------------------------------------*/
+#ifdef NK_INCLUDE_DEFAULT_FONT
+
+ #ifdef __clang__
+#pragma clang diagnostic push
+
+#pragma clang diagnostic ignored "-Woverlength-strings"
+#elif defined(__GNUC__) || defined(__GNUG__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Woverlength-strings"
+#endif
+
+NK_GLOBAL const char nk_proggy_clean_ttf_compressed_data_base85[11980+1] =
+ "7])#######hV0qs'/###[),##/l:$#Q6>##5[n42>c-TH`->>#/e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCp#-i>.r$<$6pD>Lb';9Crc6tgXmKVeU2cD4Eo3R/"
+ "2*>]b(MC;$jPfY.;h^`IWM9<Lh2TlS+f-s$o6Q<BWH`YiU.xfLq$N;$0iR/GX:U(jcW2p/W*q?-qmnUCI;jHSAiFWM.R*kU@C=GH?a9wp8f$e.-4^Qg1)Q-GL(lf(r/7GrRgwV%MS=C#"
+ "`8ND>Qo#t'X#(v#Y9w0#1D$CIf;W'#pWUPXOuxXuU(H9M(1<q-UE31#^-V'8IRUo7Qf./L>=Ke$$'5F%)]0^#0X@U.a<r:QLtFsLcL6##lOj)#.Y5<-R&KgLwqJfLgN&;Q?gI^#DY2uL"
+ "i@^rMl9t=cWq6##weg>$FBjVQTSDgEKnIS7EM9>ZY9w0#L;>>#Mx&4Mvt//L[MkA#W@lK.N'[0#7RL_&#w+F%HtG9M#XL`N&.,GM4Pg;-<nLENhvx>-VsM.M0rJfLH2eTM`*oJMHRC`N"
+ "kfimM2J,W-jXS:)r0wK#@Fge$U>`w'N7G#$#fB#$E^$#:9:hk+eOe--6x)F7*E%?76%^GMHePW-Z5l'&GiF#$956:rS?dA#fiK:)Yr+`&#0j@'DbG&#^$PG.Ll+DNa<XCMKEV*N)LN/N"
+ "*b=%Q6pia-Xg8I$<MR&,VdJe$<(7G;Ckl'&hF;;$<_=X(b.RS%%)###MPBuuE1V:v&cX&#2m#(&cV]`k9OhLMbn%s$G2,B$BfD3X*sp5#l,$R#]x_X1xKX%b5U*[r5iMfUo9U`N99hG)"
+ "tm+/Us9pG)XPu`<0s-)WTt(gCRxIg(%6sfh=ktMKn3j)<6<b5Sk_/0(^]AaN#(p/L>&VZ>1i%h1S9u5o@YaaW$e+b<TWFn/Z:Oh(Cx2$lNEoN^e)#CFY@@I;BOQ*sRwZtZxRcU7uW6CX"
+ "ow0i(?$Q[cjOd[P4d)]>ROPOpxTO7Stwi1::iB1q)C_=dV26J;2,]7op$]uQr@_V7$q^%lQwtuHY]=DX,n3L#0PHDO4f9>dC@O>HBuKPpP*E,N+b3L#lpR/MrTEH.IAQk.a>D[.e;mc."
+ "x]Ip.PH^'/aqUO/$1WxLoW0[iLA<QT;5HKD+@qQ'NQ(3_PLhE48R.qAPSwQ0/WK?Z,[x?-J;jQTWA0X@KJ(_Y8N-:/M74:/-ZpKrUss?d#dZq]DAbkU*JqkL+nwX@@47`5>w=4h(9.`G"
+ "CRUxHPeR`5Mjol(dUWxZa(>STrPkrJiWx`5U7F#.g*jrohGg`cg:lSTvEY/EV_7H4Q9[Z%cnv;JQYZ5q.l7Zeas:HOIZOB?G<Nald$qs]@]L<J7bR*>gv:[7MI2k).'2($5FNP&EQ(,)"
+ "U]W]+fh18.vsai00);D3@4ku5P?DP8aJt+;qUM]=+b'8@;mViBKx0DE[-auGl8:PJ&Dj+M6OC]O^((##]`0i)drT;-7X`=-H3[igUnPG-NZlo.#k@h#=Ork$m>a>$-?Tm$UV(?#P6YY#"
+ "'/###xe7q.73rI3*pP/$1>s9)W,JrM7SN]'/4C#v$U`0#V.[0>xQsH$fEmPMgY2u7Kh(G%siIfLSoS+MK2eTM$=5,M8p`A.;_R%#u[K#$x4AG8.kK/HSB==-'Ie/QTtG?-.*^N-4B/ZM"
+ "_3YlQC7(p7q)&](`6_c)$/*JL(L-^(]$wIM`dPtOdGA,U3:w2M-0<q-]L_?^)1vw'.,MRsqVr.L;aN&#/EgJ)PBc[-f>+WomX2u7lqM2iEumMTcsF?-aT=Z-97UEnXglEn1K-bnEO`gu"
+ "Ft(c%=;Am_Qs@jLooI&NX;]0#j4#F14;gl8-GQpgwhrq8'=l_f-b49'UOqkLu7-##oDY2L(te+Mch&gLYtJ,MEtJfLh'x'M=$CS-ZZ%P]8bZ>#S?YY#%Q&q'3^Fw&?D)UDNrocM3A76/"
+ "/oL?#h7gl85[qW/NDOk%16ij;+:1a'iNIdb-ou8.P*w,v5#EI$TWS>Pot-R*H'-SEpA:g)f+O$%%`kA#G=8RMmG1&O`>to8bC]T&$,n.LoO>29sp3dt-52U%VM#q7'DHpg+#Z9%H[K<L"
+ "%a2E-grWVM3@2=-k22tL]4$##6We'8UJCKE[d_=%wI;'6X-GsLX4j^SgJ$##R*w,vP3wK#iiW&#*h^D&R?jp7+/u&#(AP##XU8c$fSYW-J95_-Dp[g9wcO&#M-h1OcJlc-*vpw0xUX&#"
+ "OQFKNX@QI'IoPp7nb,QU//MQ&ZDkKP)X<WSVL(68uVl&#c'[0#(s1X&xm$Y%B7*K:eDA323j998GXbA#pwMs-jgD$9QISB-A_(aN4xoFM^@C58D0+Q+q3n0#3U1InDjF682-SjMXJK)("
+ "h$hxua_K]ul92%'BOU&#BRRh-slg8KDlr:%L71Ka:.A;%YULjDPmL<LYs8i#XwJOYaKPKc1h:'9Ke,g)b),78=I39B;xiY$bgGw-&.Zi9InXDuYa%G*f2Bq7mn9^#p1vv%#(Wi-;/Z5h"
+ "o;#2:;%d&#x9v68C5g?ntX0X)pT`;%pB3q7mgGN)3%(P8nTd5L7GeA-GL@+%J3u2:(Yf>et`e;)f#Km8&+DC$I46>#Kr]]u-[=99tts1.qb#q72g1WJO81q+eN'03'eM>&1XxY-caEnO"
+ "j%2n8)),?ILR5^.Ibn<-X-Mq7[a82Lq:F&#ce+S9wsCK*x`569E8ew'He]h:sI[2LM$[guka3ZRd6:t%IG:;$%YiJ:Nq=?eAw;/:nnDq0(CYcMpG)qLN4$##&J<j$UpK<Q4a1]MupW^-"
+ "sj_$%[HK%'F####QRZJ::Y3EGl4'@%FkiAOg#p[##O`gukTfBHagL<LHw%q&OV0##F=6/:chIm0@eCP8X]:kFI%hl8hgO@RcBhS-@Qb$%+m=hPDLg*%K8ln(wcf3/'DW-$.lR?n[nCH-"
+ "eXOONTJlh:.RYF%3'p6sq:UIMA945&^HFS87@$EP2iG<-lCO$%c`uKGD3rC$x0BL8aFn--`ke%#HMP'vh1/R&O_J9'um,.<tx[@%wsJk&bUT2`0uMv7gg#qp/ij.L56'hl;.s5CUrxjO"
+ "M7-##.l+Au'A&O:-T72L]P`&=;ctp'XScX*rU.>-XTt,%OVU4)S1+R-#dg0/Nn?Ku1^0f$B*P:Rowwm-`0PKjYDDM'3]d39VZHEl4,.j']Pk-M.h^&:0FACm$maq-&sgw0t7/6(^xtk%"
+ "LuH88Fj-ekm>GA#_>568x6(OFRl-IZp`&b,_P'$M<Jnq79VsJW/mWS*PUiq76;]/NM_>hLbxfc$mj`,O;&%W2m`Zh:/)Uetw:aJ%]K9h:TcF]u_-Sj9,VK3M.*'&0D[Ca]J9gp8,kAW]"
+ "%(?A%R$f<->Zts'^kn=-^@c4%-pY6qI%J%1IGxfLU9CP8cbPlXv);C=b),<2mOvP8up,UVf3839acAWAW-W?#ao/^#%KYo8fRULNd2.>%m]UK:n%r$'sw]J;5pAoO_#2mO3n,'=H5(et"
+ "Hg*`+RLgv>=4U8guD$I%D:W>-r5V*%j*W:Kvej.Lp$<M-SGZ':+Q_k+uvOSLiEo(<aD/K<CCc`'Lx>'?;++O'>()jLR-^u68PHm8ZFWe+ej8h:9r6L*0//c&iH&R8pRbA#Kjm%upV1g:"
+ "a_#Ur7FuA#(tRh#.Y5K+@?3<-8m0$PEn;J:rh6?I6uG<-`wMU'ircp0LaE_OtlMb&1#6T.#FDKu#1Lw%u%+GM+X'e?YLfjM[VO0MbuFp7;>Q&#WIo)0@F%q7c#4XAXN-U&VB<HFF*qL("
+ "$/V,;(kXZejWO`<[5?\?ewY(*9=%wDc;,u<'9t3W-(H1th3+G]ucQ]kLs7df($/*JL]@*t7Bu_G3_7mp7<iaQjO@.kLg;x3B0lqp7Hf,^Ze7-##@/c58Mo(3;knp0%)A7?-W+eI'o8)b<"
+ "nKnw'Ho8C=Y>pqB>0ie&jhZ[?iLR@@_AvA-iQC(=ksRZRVp7`.=+NpBC%rh&3]R:8XDmE5^V8O(x<<aG/1N$#FX$0V5Y6x'aErI3I$7x%E`v<-BY,)%-?Psf*l?%C3.mM(=/M0:JxG'?"
+ "7WhH%o'a<-80g0NBxoO(GH<dM]n.+%q@jH?f.UsJ2Ggs&4<-e47&Kl+f//9@`b+?.TeN_&B8Ss?v;^Trk;f#YvJkl&w$]>-+k?'(<S:68tq*WoDfZu';mM?8X[ma8W%*`-=;D.(nc7/;"
+ ")g:T1=^J$&BRV(-lTmNB6xqB[@0*o.erM*<SWF]u2=st-*(6v>^](H.aREZSi,#1:[IXaZFOm<-ui#qUq2$##Ri;u75OK#(RtaW-K-F`S+cF]uN`-KMQ%rP/Xri.LRcB##=YL3BgM/3M"
+ "D?@f&1'BW-)Ju<L25gl8uhVm1hL$##*8###'A3/LkKW+(^rWX?5W_8g)a(m&K8P>#bmmWCMkk&#TR`C,5d>g)F;t,4:@_l8G/5h4vUd%&%950:VXD'QdWoY-F$BtUwmfe$YqL'8(PWX("
+ "P?^@Po3$##`MSs?DWBZ/S>+4%>fX,VWv/w'KD`LP5IbH;rTV>n3cEK8U#bX]l-/V+^lj3;vlMb&[5YQ8#pekX9JP3XUC72L,,?+Ni&co7ApnO*5NK,((W-i:$,kp'UDAO(G0Sq7MVjJs"
+ "bIu)'Z,*[>br5fX^:FPAWr-m2KgL<LUN098kTF&#lvo58=/vjDo;.;)Ka*hLR#/k=rKbxuV`>Q_nN6'8uTG&#1T5g)uLv:873UpTLgH+#FgpH'_o1780Ph8KmxQJ8#H72L4@768@Tm&Q"
+ "h4CB/5OvmA&,Q&QbUoi$a_%3M01H)4x7I^&KQVgtFnV+;[Pc>[m4k//,]1?#`VY[Jr*3&&slRfLiVZJ:]?=K3Sw=[$=uRB?3xk48@aeg<Z'<$#4H)6,>e0jT6'N#(q%.O=?2S]u*(m<-"
+ "V8J'(1)G][68hW$5'q[GC&5j`TE?m'esFGNRM)j,ffZ?-qx8;->g4t*:CIP/[Qap7/9'#(1sao7w-.qNUdkJ)tCF&#B^;xGvn2r9FEPFFFcL@.iFNkTve$m%#QvQS8U@)2Z+3K:AKM5i"
+ "sZ88+dKQ)W6>J%CL<KE>`.d*(B`-n8D9oK<Up]c$X$(,)M8Zt7/[rdkqTgl-0cuGMv'?>-XV1q['-5k'cAZ69e;D_?$ZPP&s^+7])$*$#@QYi9,5P&#9r+$%CE=68>K8r0=dSC%%(@p7"
+ ".m7jilQ02'0-VWAg<a/''3u.=4L$Y)6k/K:_[3=&jvL<L0C/2'v:^;-DIBW,B4E68:kZ;%?8(Q8BH=kO65BW?xSG&#@uU,DS*,?.+(o(#1vCS8#CHF>TlGW'b)Tq7VT9q^*^$$.:&N@@"
+ "$&)WHtPm*5_rO0&e%K&#-30j(E4#'Zb.o/(Tpm$>K'f@[PvFl,hfINTNU6u'0pao7%XUp9]5.>%h`8_=VYbxuel.NTSsJfLacFu3B'lQSu/m6-Oqem8T+oE--$0a/k]uj9EwsG>%veR*"
+ "hv^BFpQj:K'#SJ,sB-'#](j.Lg92rTw-*n%@/;39rrJF,l#qV%OrtBeC6/,;qB3ebNW[?,Hqj2L.1NP&GjUR=1D8QaS3Up&@*9wP?+lo7b?@%'k4`p0Z$22%K3+iCZj?XJN4Nm&+YF]u"
+ "@-W$U%VEQ/,,>>#)D<h#`)h0:<Q6909ua+&VU%n2:cG3FJ-%@Bj-DgLr`Hw&HAKjKjseK</xKT*)B,N9X3]krc12t'pgTV(Lv-tL[xg_%=M_q7a^x?7Ubd>#%8cY#YZ?=,`Wdxu/ae&#"
+ "w6)R89tI#6@s'(6Bf7a&?S=^ZI_kS&ai`&=tE72L_D,;^R)7[$s<Eh#c&)q.MXI%#v9ROa5FZO%sF7q7Nwb&#ptUJ:aqJe$Sl68%.D###EC><?-aF&#RNQv>o8lKN%5/$(vdfq7+ebA#"
+ "u1p]ovUKW&Y%q]'>$1@-[xfn$7ZTp7mM,G,Ko7a&Gu%G[RMxJs[0MM%wci.LFDK)(<c`Q8N)jEIF*+?P2a8g%)$q]o2aH8C&<SibC/q,(e:v;-b#6[$NtDZ84Je2KNvB#$P5?tQ3nt(0"
+ "d=j.LQf./Ll33+(;q3L-w=8dX$#WF&uIJ@-bfI>%:_i2B5CsR8&9Z&#=mPEnm0f`<&c)QL5uJ#%u%lJj+D-r;BoF&#4DoS97h5g)E#o:&S4weDF,9^Hoe`h*L+_a*NrLW-1pG_&2UdB8"
+ "6e%B/:=>)N4xeW.*wft-;$'58-ESqr<b?UI(_%@[P46>#U`'6AQ]m&6/`Z>#S?YY#Vc;r7U2&326d=w&H####?TZ`*4?&.MK?LP8Vxg>$[QXc%QJv92.(Db*B)gb*BM9dM*hJMAo*c&#"
+ "b0v=Pjer]$gG&JXDf->'StvU7505l9$AFvgYRI^&<^b68?j#q9QX4SM'RO#&sL1IM.rJfLUAj221]d##DW=m83u5;'bYx,*Sl0hL(W;;$doB&O/TQ:(Z^xBdLjL<Lni;''X.`$#8+1GD"
+ ":k$YUWsbn8ogh6rxZ2Z9]%nd+>V#*8U_72Lh+2Q8Cj0i:6hp&$C/:p(HK>T8Y[gHQ4`4)'$Ab(Nof%V'8hL&#<NEdtg(n'=S1A(Q1/I&4([%dM`,Iu'1:_hL>SfD07&6D<fp8dHM7/g+"
+ "tlPN9J*rKaPct&?'uBCem^jn%9_K)<,C5K3s=5g&GmJb*[SYq7K;TRLGCsM-$$;S%:Y@r7AK0pprpL<Lrh,q7e/%KWK:50I^+m'vi`3?%Zp+<-d+$L-Sv:@.o19n$s0&39;kn;S%BSq*"
+ "$3WoJSCLweV[aZ'MQIjO<7;X-X;&+dMLvu#^UsGEC9WEc[X(wI7#2.(F0jV*eZf<-Qv3J-c+J5AlrB#$p(H68LvEA'q3n0#m,[`*8Ft)FcYgEud]CWfm68,(aLA$@EFTgLXoBq/UPlp7"
+ ":d[/;r_ix=:TF`S5H-b<LI&HY(K=h#)]Lk$K14lVfm:x$H<3^Ql<M`$OhapBnkup'D#L$Pb_`N*g]2e;X/Dtg,bsj&K#2[-:iYr'_wgH)NUIR8a1n#S?Yej'h8^58UbZd+^FKD*T@;6A"
+ "7aQC[K8d-(v6GI$x:T<&'Gp5Uf>@M.*J:;$-rv29'M]8qMv-tLp,'886iaC=Hb*YJoKJ,(j%K=H`K.v9HggqBIiZu'QvBT.#=)0ukruV&.)3=(^1`o*Pj4<-<aN((^7('#Z0wK#5GX@7"
+ "u][`*S^43933A4rl][`*O4CgLEl]v$1Q3AeF37dbXk,.)vj#x'd`;qgbQR%FW,2(?LO=s%Sc68%NP'##Aotl8x=BE#j1UD([3$M(]UI2LX3RpKN@;/#f'f/&_mt&F)XdF<9t4)Qa.*kT"
+ "LwQ'(TTB9.xH'>#MJ+gLq9-##@HuZPN0]u:h7.T..G:;$/Usj(T7`Q8tT72LnYl<-qx8;-HV7Q-&Xdx%1a,hC=0u+HlsV>nuIQL-5<N?)NBS)QN*_I,?&)2'IM%L3I)X((e/dl2&8'<M"
+ ":^#M*Q+[T.Xri.LYS3v%fF`68h;b-X[/En'CR.q7E)p'/kle2HM,u;^%OKC-N+Ll%F9CF<Nf'^#t2L,;27W:0O@6##U6W7:$rJfLWHj$#)woqBefIZ.PK<b*t7ed;p*_m;4ExK#h@&]>"
+ "_>@kXQtMacfD.m-VAb8;IReM3$wf0''hra*so568'Ip&vRs849'MRYSp%:t:h5qSgwpEr$B>Q,;s(C#$)`svQuF$##-D,##,g68@2[T;.XSdN9Qe)rpt._K-#5wF)sP'##p#C0c%-Gb%"
+ "hd+<-j'Ai*x&&HMkT]C'OSl##5RG[JXaHN;d'uA#x._U;.`PU@(Z3dt4r152@:v,'R.Sj'w#0<-;kPI)FfJ&#AYJ&#//)>-k=m=*XnK$>=)72L]0I%>.G690a:$##<,);?;72#?x9+d;"
+ "^V'9;jY@;)br#q^YQpx:X#Te$Z^'=-=bGhLf:D6&bNwZ9-ZD#n^9HhLMr5G;']d&6'wYmTFmL<LD)F^%[tC'8;+9E#C$g%#5Y>q9wI>P(9mI[>kC-ekLC/R&CH+s'B;K-M6$EB%is00:"
+ "+A4[7xks.LrNk0&E)wILYF@2L'0Nb$+pv<(2.768/FrY&h$^3i&@+G%JT'<-,v`3;_)I9M^AE]CN?Cl2AZg+%4iTpT3<n-&%H%b<FDj2M<hH=&Eh<2Len$b*aTX=-8QxN)k11IM1c^j%"
+ "9s<L<NFSo)B?+<-(GxsF,^-Eh@$4dXhN$+#rxK8'je'D7k`e;)2pYwPA'_p9&@^18ml1^[@g4t*[JOa*[=Qp7(qJ_oOL^('7fB&Hq-:sf,sNj8xq^>$U4O]GKx'm9)b@p7YsvK3w^YR-"
+ "CdQ*:Ir<($u&)#(&?L9Rg3H)4fiEp^iI9O8KnTj,]H?D*r7'M;PwZ9K0E^k&-cpI;.p/6_vwoFMV<->#%Xi.LxVnrU(4&8/P+:hLSKj$#U%]49t'I:rgMi'FL@a:0Y-uA[39',(vbma*"
+ "hU%<-SRF`Tt:542R_VV$p@[p8DV[A,?1839FWdF<TddF<9Ah-6&9tWoDlh]&1SpGMq>Ti1O*H&#(AL8[_P%.M>v^-))qOT*F5Cq0`Ye%+$B6i:7@0IX<N+T+0MlMBPQ*Vj>SsD<U4JHY"
+ "8kD2)2fU/M#$e.)T4,_=8hLim[&);?UkK'-x?'(:siIfL<$pFM`i<?%W(mGDHM%>iWP,##P`%/L<eXi:@Z9C.7o=@(pXdAO/NLQ8lPl+HPOQa8wD8=^GlPa8TKI1CjhsCTSLJM'/Wl>-"
+ "S(qw%sf/@%#B6;/U7K]uZbi^Oc^2n<bhPmUkMw>%t<)'mEVE''n`WnJra$^TKvX5B>;_aSEK',(hwa0:i4G?.Bci.(X[?b*($,=-n<.Q%`(X=?+@Am*Js0&=3bh8K]mL<LoNs'6,'85`"
+ "0?t/'_U59@]ddF<#LdF<eWdF<OuN/45rY<-L@&#+fm>69=Lb,OcZV/);TTm8VI;?%OtJ<(b4mq7M6:u?KRdF<gR@2L=FNU-<b[(9c/ML3m;Z[$oF3g)GAWqpARc=<ROu7cL5l;-[A]%/"
+ "+fsd;l#SafT/f*W]0=O'$(Tb<[)*@e775R-:Yob%g*>l*:xP?Yb.5)%w_I?7uk5JC+FS(m#i'k.'a0i)9<7b'fs'59hq$*5Uhv##pi^8+hIEBF`nvo`;'l0.^S1<-wUK2/Coh58KKhLj"
+ "M=SO*rfO`+qC`W-On.=AJ56>>i2@2LH6A:&5q`?9I3@@'04&p2/LVa*T-4<-i3;M9UvZd+N7>b*eIwg:CC)c<>nO&#<IGe;__.thjZl<%w(Wk2xmp4Q@I#I9,DF]u7-P=.-_:YJ]aS@V"
+ "?6*C()dOp7:WL,b&3Rg/.cmM9&r^>$(>.Z-I&J(Q0Hd5Q%7Co-b`-c<N(6r@ip+AurK<m86QIth*#v;-OBqi+L7wDE-Ir8K['m+DDSLwK&/.?-V%U_%3:qKNu$_b*B-kp7NaD'QdWQPK"
+ "Yq[@>P)hI;*_F]u`Rb[.j8_Q/<&>uu+VsH$sM9TA%?)(vmJ80),P7E>)tjD%2L=-t#fK[%`v=Q8<FfNkgg^oIbah*#8/Qt$F&:K*-(N/'+1vMB,u()-a.VUU*#[e%gAAO(S>WlA2);Sa"
+ ">gXm8YB`1d@K#n]76-a$U,mF<fX]idqd)<3,]J7JmW4`6]uks=4-72L(jEk+:bJ0M^q-8Dm_Z?0olP1C9Sa&H[d&c$ooQUj]Exd*3ZM@-WGW2%s',B-_M%>%Ul:#/'xoFM9QX-$.QN'>"
+ "[%$Z$uF6pA6Ki2O5:8w*vP1<-1`[G,)-m#>0`P&#eb#.3i)rtB61(o'$?X3B</R90;eZ]%Ncq;-Tl]#F>2Qft^ae_5tKL9MUe9b*sLEQ95C&`=G?@Mj=wh*'3E>=-<)Gt*Iw)'QG:`@I"
+ "wOf7&]1i'S01B+Ev/Nac#9S;=;YQpg_6U`*kVY39xK,[/6Aj7:'1Bm-_1EYfa1+o&o4hp7KN_Q(OlIo@S%;jVdn0'1<Vc52=u`3^o-n1'g4v58Hj&6_t7$##?M)c<$bgQ_'SY((-xkA#"
+ "Y(,p'H9rIVY-b,'%bCPF7.J<Up^,(dU1VY*5#WkTU>h19w,WQhLI)3S#f$2(eb,jr*b;3Vw]*7NH%$c4Vs,eD9>XW8?N]o+(*pgC%/72LV-u<Hp,3@e^9UB1J+ak9-TN/mhKPg+AJYd$"
+ "MlvAF_jCK*.O-^(63adMT->W%iewS8W6m2rtCpo'RS1R84=@paTKt)>=%&1[)*vp'u+x,VrwN;&]kuO9JDbg=pO$J*.jVe;u'm0dr9l,<*wMK*Oe=g8lV_KEBFkO'oU]^=[-792#ok,)"
+ "i]lR8qQ2oA8wcRCZ^7w/Njh;?.stX?Q1>S1q4Bn$)K1<-rGdO'$Wr.Lc.CG)$/*JL4tNR/,SVO3,aUw'DJN:)Ss;wGn9A32ijw%FL+Z0Fn.U9;reSq)bmI32U==5ALuG&#Vf1398/pVo"
+ "1*c-(aY168o<`JsSbk-,1N;$>0:OUas(3:8Z972LSfF8eb=c-;>SPw7.6hn3m`9^Xkn(r.qS[0;T%&Qc=+STRxX'q1BNk3&*eu2;&8q$&x>Q#Q7^Tf+6<(d%ZVmj2bDi%.3L2n+4W'$P"
+ "iDDG)g,r%+?,$@?uou5tSe2aN_AQU*<h`e-GI7)?OK2A.d7_c)?wQ5AS@DL3r#7fSkgl6-++D:'A,uq7SvlB$pcpH'q3n0#_%dY#xCpr-l<F0NR@-##FEV6NTF6##$l84N1w?AO>'IAO"
+ "URQ##V^Fv-XFbGM7Fl(N<3DhLGF%q.1rC$#:T__&Pi68%0xi_&[qFJ(77j_&JWoF.V735&T,[R*:xFR*K5>>#`bW-?4Ne_&6Ne_&6Ne_&n`kr-#GJcM6X;uM6X;uM(.a..^2TkL%oR(#"
+ ";u.T%fAr%4tJ8&><1=GHZ_+m9/#H1F^R#SC#*N=BA9(D?v[UiFY>>^8p,KKF.W]L29uLkLlu/+4T<XoIB&hx=T1PcDaB&;HH+-AFr?(m9HZV)FKS8JCw;SD=6[^/DZUL`EUDf]GGlG&>"
+ "w$)F./^n3+rlo+DB;5sIYGNk+i1t-69Jg--0pao7Sm#K)pdHW&;LuDNH@H>#/X-TI(;P>#,Gc>#0Su>#4`1?#8lC?#<xU?#@.i?#D:%@#HF7@#LRI@#P_[@#Tkn@#Xw*A#]-=A#a9OA#"
+ "d<F&#*;G##.GY##2Sl##6`($#:l:$#>xL$#B.`$#F:r$#JF.%#NR@%#R_R%#Vke%#Zww%#_-4&#3^Rh%Sflr-k'MS.o?.5/sWel/wpEM0%3'/1)K^f1-d>G21&v(35>V`39V7A4=onx4"
+ "A1OY5EI0;6Ibgr6M$HS7Q<)58C5w,;WoA*#[%T*#`1g*#d=#+#hI5+#lUG+#pbY+#tnl+#x$),#&1;,#*=M,#.I`,#2Ur,#6b.-#;w[H#iQtA#m^0B#qjBB#uvTB##-hB#'9$C#+E6C#"
+ "/QHC#3^ZC#7jmC#;v)D#?,<D#C8ND#GDaD#KPsD#O]/E#g1A5#KA*1#gC17#MGd;#8(02#L-d3#rWM4#Hga1#,<w0#T.j<#O#'2#CYN1#qa^:#_4m3#o@/=#eG8=#t8J5#`+78#4uI-#"
+ "m3B2#SB[8#Q0@8#i[*9#iOn8#1Nm;#^sN9#qh<9#:=x-#P;K2#$%X9#bC+.#Rg;<#mN=.#MTF.#RZO.#2?)4#Y#(/#[)1/#b;L/#dAU/#0Sv;#lY$0#n`-0#sf60#(F24#wrH0#%/e0#"
+ "TmD<#%JSMFove:CTBEXI:<eh2g)B,3h2^G3i;#d3jD>)4kMYD4lVu`4m`:&5niUA5@(A5BA1]PBB:xlBCC=2CDLXMCEUtiCf&0g2'tN?PGT4CPGT4CPGT4CPGT4CPGT4CPGT4CPGT4CP"
+ "GT4CPGT4CPGT4CPGT4CPGT4CPGT4CP-qekC`.9kEg^+F$kwViFJTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5o,^<-28ZI'O?;xp"
+ "O?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xp;7q-#lLYI:xvD=#";
+#endif /* NK_INCLUDE_DEFAULT_FONT */
+
+#define NK_CURSOR_DATA_W 90
+#define NK_CURSOR_DATA_H 27
+NK_GLOBAL const char nk_custom_cursor_data[NK_CURSOR_DATA_W * NK_CURSOR_DATA_H + 1] =
+{
+ "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX"
+ "..- -X.....X- X.X - X.X -X.....X - X.....X"
+ "--- -XXX.XXX- X...X - X...X -X....X - X....X"
+ "X - X.X - X.....X - X.....X -X...X - X...X"
+ "XX - X.X -X.......X- X.......X -X..X.X - X.X..X"
+ "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X"
+ "X..X - X.X - X.X - X.X -XX X.X - X.X XX"
+ "X...X - X.X - X.X - XX X.X XX - X.X - X.X "
+ "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X "
+ "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X "
+ "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X "
+ "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X "
+ "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X "
+ "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X "
+ "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X "
+ "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X "
+ "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX "
+ "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------"
+ "X.X X..X - -X.......X- X.......X - XX XX - "
+ "XX X..X - - X.....X - X.....X - X.X X.X - "
+ " X..X - X...X - X...X - X..X X..X - "
+ " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - "
+ "------------ - X - X -X.....................X- "
+ " ----------------------------------- X...XXXXXXXXXXXXX...X - "
+ " - X..X X..X - "
+ " - X.X X.X - "
+ " - XX XX - "
+};
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#elif defined(__GNUC__) || defined(__GNUG__)
+#pragma GCC diagnostic pop
+#endif
+
+NK_INTERN unsigned int
+nk_decompress_length(unsigned char *input)
+{
+ return (unsigned int)((input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]);
+}
+
+NK_GLOBAL unsigned char *nk__barrier;
+NK_GLOBAL unsigned char *nk__barrier2;
+NK_GLOBAL unsigned char *nk__barrier3;
+NK_GLOBAL unsigned char *nk__barrier4;
+NK_GLOBAL unsigned char *nk__dout;
+
+NK_INTERN void
+nk__match(unsigned char *data, unsigned int length)
+{
+ /* INVERSE of memmove... write each byte before copying the next...*/
+ NK_ASSERT (nk__dout + length <= nk__barrier);
+ if (nk__dout + length > nk__barrier) { nk__dout += length; return; }
+ if (data < nk__barrier4) { nk__dout = nk__barrier+1; return; }
+ while (length--) *nk__dout++ = *data++;
+}
+
+NK_INTERN void
+nk__lit(unsigned char *data, unsigned int length)
+{
+ NK_ASSERT (nk__dout + length <= nk__barrier);
+ if (nk__dout + length > nk__barrier) { nk__dout += length; return; }
+ if (data < nk__barrier2) { nk__dout = nk__barrier+1; return; }
+ NK_MEMCPY(nk__dout, data, length);
+ nk__dout += length;
+}
+
+#define nk__in2(x) ((i[x] << 8) + i[(x)+1])
+#define nk__in3(x) ((i[x] << 16) + nk__in2((x)+1))
+#define nk__in4(x) ((i[x] << 24) + nk__in3((x)+1))
+
+NK_INTERN unsigned char*
+nk_decompress_token(unsigned char *i)
+{
+ if (*i >= 0x20) { /* use fewer if's for cases that expand small */
+ if (*i >= 0x80) nk__match(nk__dout-i[1]-1, (unsigned int)i[0] - 0x80 + 1), i += 2;
+ else if (*i >= 0x40) nk__match(nk__dout-(nk__in2(0) - 0x4000 + 1), (unsigned int)i[2]+1), i += 3;
+ else /* *i >= 0x20 */ nk__lit(i+1, (unsigned int)i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1);
+ } else { /* more ifs for cases that expand large, since overhead is amortized */
+ if (*i >= 0x18) nk__match(nk__dout-(unsigned int)(nk__in3(0) - 0x180000 + 1), (unsigned int)i[3]+1), i += 4;
+ else if (*i >= 0x10) nk__match(nk__dout-(unsigned int)(nk__in3(0) - 0x100000 + 1), (unsigned int)nk__in2(3)+1), i += 5;
+ else if (*i >= 0x08) nk__lit(i+2, (unsigned int)nk__in2(0) - 0x0800 + 1), i += 2 + (nk__in2(0) - 0x0800 + 1);
+ else if (*i == 0x07) nk__lit(i+3, (unsigned int)nk__in2(1) + 1), i += 3 + (nk__in2(1) + 1);
+ else if (*i == 0x06) nk__match(nk__dout-(unsigned int)(nk__in3(1)+1), i[4]+1u), i += 5;
+ else if (*i == 0x04) nk__match(nk__dout-(unsigned int)(nk__in3(1)+1), (unsigned int)nk__in2(4)+1u), i += 6;
+ }
+ return i;
+}
+
+NK_INTERN unsigned int
+nk_adler32(unsigned int adler32, unsigned char *buffer, unsigned int buflen)
+{
+ const unsigned long ADLER_MOD = 65521;
+ unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
+ unsigned long blocklen, i;
+
+ blocklen = buflen % 5552;
+ while (buflen) {
+ for (i=0; i + 7 < blocklen; i += 8) {
+ s1 += buffer[0]; s2 += s1;
+ s1 += buffer[1]; s2 += s1;
+ s1 += buffer[2]; s2 += s1;
+ s1 += buffer[3]; s2 += s1;
+ s1 += buffer[4]; s2 += s1;
+ s1 += buffer[5]; s2 += s1;
+ s1 += buffer[6]; s2 += s1;
+ s1 += buffer[7]; s2 += s1;
+ buffer += 8;
+ }
+ for (; i < blocklen; ++i) {
+ s1 += *buffer++; s2 += s1;
+ }
+
+ s1 %= ADLER_MOD; s2 %= ADLER_MOD;
+ buflen -= (unsigned int)blocklen;
+ blocklen = 5552;
+ }
+ return (unsigned int)(s2 << 16) + (unsigned int)s1;
+}
+
+NK_INTERN unsigned int
+nk_decompress(unsigned char *output, unsigned char *i, unsigned int length)
+{
+ unsigned int olen;
+ if (nk__in4(0) != 0x57bC0000) return 0;
+ if (nk__in4(4) != 0) return 0; /* error! stream is > 4GB */
+ olen = nk_decompress_length(i);
+ nk__barrier2 = i;
+ nk__barrier3 = i+length;
+ nk__barrier = output + olen;
+ nk__barrier4 = output;
+ i += 16;
+
+ nk__dout = output;
+ for (;;) {
+ unsigned char *old_i = i;
+ i = nk_decompress_token(i);
+ if (i == old_i) {
+ if (*i == 0x05 && i[1] == 0xfa) {
+ NK_ASSERT(nk__dout == output + olen);
+ if (nk__dout != output + olen) return 0;
+ if (nk_adler32(1, output, olen) != (unsigned int) nk__in4(2))
+ return 0;
+ return olen;
+ } else {
+ NK_ASSERT(0); /* NOTREACHED */
+ return 0;
+ }
+ }
+ NK_ASSERT(nk__dout <= output + olen);
+ if (nk__dout > output + olen)
+ return 0;
+ }
+}
+
+NK_INTERN unsigned int
+nk_decode_85_byte(char c)
+{ return (unsigned int)((c >= '\\') ? c-36 : c-35); }
+
+NK_INTERN void
+nk_decode_85(unsigned char* dst, const unsigned char* src)
+{
+ while (*src)
+ {
+ unsigned int tmp =
+ nk_decode_85_byte((char)src[0]) +
+ 85 * (nk_decode_85_byte((char)src[1]) +
+ 85 * (nk_decode_85_byte((char)src[2]) +
+ 85 * (nk_decode_85_byte((char)src[3]) +
+ 85 * nk_decode_85_byte((char)src[4]))));
+
+ /* we can't assume little-endianess. */
+ dst[0] = (unsigned char)((tmp >> 0) & 0xFF);
+ dst[1] = (unsigned char)((tmp >> 8) & 0xFF);
+ dst[2] = (unsigned char)((tmp >> 16) & 0xFF);
+ dst[3] = (unsigned char)((tmp >> 24) & 0xFF);
+
+ src += 5;
+ dst += 4;
+ }
+}
+
+/* -------------------------------------------------------------
+ *
+ * FONT ATLAS
+ *
+ * --------------------------------------------------------------*/
+NK_API struct nk_font_config
+nk_font_config(float pixel_height)
+{
+ struct nk_font_config cfg;
+ nk_zero_struct(cfg);
+ cfg.ttf_blob = 0;
+ cfg.ttf_size = 0;
+ cfg.ttf_data_owned_by_atlas = 0;
+ cfg.size = pixel_height;
+ cfg.oversample_h = 3;
+ cfg.oversample_v = 1;
+ cfg.pixel_snap = 0;
+ cfg.coord_type = NK_COORD_UV;
+ cfg.spacing = nk_vec2(0,0);
+ cfg.range = nk_font_default_glyph_ranges();
+ cfg.merge_mode = 0;
+ cfg.fallback_glyph = '?';
+ cfg.font = 0;
+ cfg.n = 0;
+ return cfg;
+}
+
+#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
+NK_API void
+nk_font_atlas_init_default(struct nk_font_atlas *atlas)
+{
+ NK_ASSERT(atlas);
+ if (!atlas) return;
+ nk_zero_struct(*atlas);
+ atlas->temporary.userdata.ptr = 0;
+ atlas->temporary.alloc = nk_malloc;
+ atlas->temporary.free = nk_mfree;
+ atlas->permanent.userdata.ptr = 0;
+ atlas->permanent.alloc = nk_malloc;
+ atlas->permanent.free = nk_mfree;
+}
+#endif
+
+NK_API void
+nk_font_atlas_init(struct nk_font_atlas *atlas, struct nk_allocator *alloc)
+{
+ NK_ASSERT(atlas);
+ NK_ASSERT(alloc);
+ if (!atlas || !alloc) return;
+ nk_zero_struct(*atlas);
+ atlas->permanent = *alloc;
+ atlas->temporary = *alloc;
+}
+
+NK_API void
+nk_font_atlas_init_custom(struct nk_font_atlas *atlas,
+ struct nk_allocator *permanent, struct nk_allocator *temporary)
+{
+ NK_ASSERT(atlas);
+ NK_ASSERT(permanent);
+ NK_ASSERT(temporary);
+ if (!atlas || !permanent || !temporary) return;
+ nk_zero_struct(*atlas);
+ atlas->permanent = *permanent;
+ atlas->temporary = *temporary;
+}
+
+NK_API void
+nk_font_atlas_begin(struct nk_font_atlas *atlas)
+{
+ NK_ASSERT(atlas);
+ NK_ASSERT(atlas->temporary.alloc && atlas->temporary.free);
+ NK_ASSERT(atlas->permanent.alloc && atlas->permanent.free);
+ if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free ||
+ !atlas->temporary.alloc || !atlas->temporary.free) return;
+ if (atlas->glyphs) {
+ atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
+ atlas->glyphs = 0;
+ }
+ if (atlas->pixel) {
+ atlas->permanent.free(atlas->permanent.userdata, atlas->pixel);
+ atlas->pixel = 0;
+ }
+}
+
+NK_API struct nk_font*
+nk_font_atlas_add(struct nk_font_atlas *atlas, const struct nk_font_config *config)
+{
+ struct nk_font *font = 0;
+ struct nk_font_config *cfg;
+
+ NK_ASSERT(atlas);
+ NK_ASSERT(atlas->permanent.alloc);
+ NK_ASSERT(atlas->permanent.free);
+ NK_ASSERT(atlas->temporary.alloc);
+ NK_ASSERT(atlas->temporary.free);
+
+ NK_ASSERT(config);
+ NK_ASSERT(config->ttf_blob);
+ NK_ASSERT(config->ttf_size);
+ NK_ASSERT(config->size > 0.0f);
+
+ if (!atlas || !config || !config->ttf_blob || !config->ttf_size || config->size <= 0.0f||
+ !atlas->permanent.alloc || !atlas->permanent.free ||
+ !atlas->temporary.alloc || !atlas->temporary.free)
+ return 0;
+
+ /* allocate font config */
+ cfg = (struct nk_font_config*)
+ atlas->permanent.alloc(atlas->permanent.userdata,0, sizeof(struct nk_font_config));
+ NK_MEMCPY(cfg, config, sizeof(*config));
+ cfg->n = cfg;
+ cfg->p = cfg;
+
+ if (!config->merge_mode) {
+ /* insert font config into list */
+ if (!atlas->config) {
+ atlas->config = cfg;
+ cfg->next = 0;
+ } else {
+ struct nk_font_config *i = atlas->config;
+ while (i->next) i = i->next;
+ i->next = cfg;
+ cfg->next = 0;
+ }
+ /* allocate new font */
+ font = (struct nk_font*)
+ atlas->permanent.alloc(atlas->permanent.userdata,0, sizeof(struct nk_font));
+ NK_ASSERT(font);
+ nk_zero(font, sizeof(*font));
+ if (!font) return 0;
+ font->config = cfg;
+
+ /* insert font into list */
+ if (!atlas->fonts) {
+ atlas->fonts = font;
+ font->next = 0;
+ } else {
+ struct nk_font *i = atlas->fonts;
+ while (i->next) i = i->next;
+ i->next = font;
+ font->next = 0;
+ }
+ cfg->font = &font->info;
+ } else {
+ /* extend previously added font */
+ struct nk_font *f = 0;
+ struct nk_font_config *c = 0;
+ NK_ASSERT(atlas->font_num);
+ f = atlas->fonts;
+ c = f->config;
+ cfg->font = &f->info;
+
+ cfg->n = c;
+ cfg->p = c->p;
+ c->p->n = cfg;
+ c->p = cfg;
+ }
+ /* create own copy of .TTF font blob */
+ if (!config->ttf_data_owned_by_atlas) {
+ cfg->ttf_blob = atlas->permanent.alloc(atlas->permanent.userdata,0, cfg->ttf_size);
+ NK_ASSERT(cfg->ttf_blob);
+ if (!cfg->ttf_blob) {
+ atlas->font_num++;
+ return 0;
+ }
+ NK_MEMCPY(cfg->ttf_blob, config->ttf_blob, cfg->ttf_size);
+ cfg->ttf_data_owned_by_atlas = 1;
+ }
+ atlas->font_num++;
+ return font;
+}
+
+NK_API struct nk_font*
+nk_font_atlas_add_from_memory(struct nk_font_atlas *atlas, void *memory,
+ nk_size size, float height, const struct nk_font_config *config)
+{
+ struct nk_font_config cfg;
+ NK_ASSERT(memory);
+ NK_ASSERT(size);
+
+ NK_ASSERT(atlas);
+ NK_ASSERT(atlas->temporary.alloc);
+ NK_ASSERT(atlas->temporary.free);
+ NK_ASSERT(atlas->permanent.alloc);
+ NK_ASSERT(atlas->permanent.free);
+ if (!atlas || !atlas->temporary.alloc || !atlas->temporary.free || !memory || !size ||
+ !atlas->permanent.alloc || !atlas->permanent.free)
+ return 0;
+
+ cfg = (config) ? *config: nk_font_config(height);
+ cfg.ttf_blob = memory;
+ cfg.ttf_size = size;
+ cfg.size = height;
+ cfg.ttf_data_owned_by_atlas = 0;
+ return nk_font_atlas_add(atlas, &cfg);
+}
+
+#ifdef NK_INCLUDE_STANDARD_IO
+NK_API struct nk_font*
+nk_font_atlas_add_from_file(struct nk_font_atlas *atlas, const char *file_path,
+ float height, const struct nk_font_config *config)
+{
+ nk_size size;
+ char *memory;
+ struct nk_font_config cfg;
+
+ NK_ASSERT(atlas);
+ NK_ASSERT(atlas->temporary.alloc);
+ NK_ASSERT(atlas->temporary.free);
+ NK_ASSERT(atlas->permanent.alloc);
+ NK_ASSERT(atlas->permanent.free);
+
+ if (!atlas || !file_path) return 0;
+ memory = nk_file_load(file_path, &size, &atlas->permanent);
+ if (!memory) return 0;
+
+ cfg = (config) ? *config: nk_font_config(height);
+ cfg.ttf_blob = memory;
+ cfg.ttf_size = size;
+ cfg.size = height;
+ cfg.ttf_data_owned_by_atlas = 1;
+ return nk_font_atlas_add(atlas, &cfg);
+}
+#endif
+
+NK_API struct nk_font*
+nk_font_atlas_add_compressed(struct nk_font_atlas *atlas,
+ void *compressed_data, nk_size compressed_size, float height,
+ const struct nk_font_config *config)
+{
+ unsigned int decompressed_size;
+ void *decompressed_data;
+ struct nk_font_config cfg;
+
+ NK_ASSERT(atlas);
+ NK_ASSERT(atlas->temporary.alloc);
+ NK_ASSERT(atlas->temporary.free);
+ NK_ASSERT(atlas->permanent.alloc);
+ NK_ASSERT(atlas->permanent.free);
+
+ NK_ASSERT(compressed_data);
+ NK_ASSERT(compressed_size);
+ if (!atlas || !compressed_data || !atlas->temporary.alloc || !atlas->temporary.free ||
+ !atlas->permanent.alloc || !atlas->permanent.free)
+ return 0;
+
+ decompressed_size = nk_decompress_length((unsigned char*)compressed_data);
+ decompressed_data = atlas->permanent.alloc(atlas->permanent.userdata,0,decompressed_size);
+ NK_ASSERT(decompressed_data);
+ if (!decompressed_data) return 0;
+ nk_decompress((unsigned char*)decompressed_data, (unsigned char*)compressed_data,
+ (unsigned int)compressed_size);
+
+ cfg = (config) ? *config: nk_font_config(height);
+ cfg.ttf_blob = decompressed_data;
+ cfg.ttf_size = decompressed_size;
+ cfg.size = height;
+ cfg.ttf_data_owned_by_atlas = 1;
+ return nk_font_atlas_add(atlas, &cfg);
+}
+
+NK_API struct nk_font*
+nk_font_atlas_add_compressed_base85(struct nk_font_atlas *atlas,
+ const char *data_base85, float height, const struct nk_font_config *config)
+{
+ int compressed_size;
+ void *compressed_data;
+ struct nk_font *font;
+
+ NK_ASSERT(atlas);
+ NK_ASSERT(atlas->temporary.alloc);
+ NK_ASSERT(atlas->temporary.free);
+ NK_ASSERT(atlas->permanent.alloc);
+ NK_ASSERT(atlas->permanent.free);
+
+ NK_ASSERT(data_base85);
+ if (!atlas || !data_base85 || !atlas->temporary.alloc || !atlas->temporary.free ||
+ !atlas->permanent.alloc || !atlas->permanent.free)
+ return 0;
+
+ compressed_size = (((int)nk_strlen(data_base85) + 4) / 5) * 4;
+ compressed_data = atlas->temporary.alloc(atlas->temporary.userdata,0, (nk_size)compressed_size);
+ NK_ASSERT(compressed_data);
+ if (!compressed_data) return 0;
+ nk_decode_85((unsigned char*)compressed_data, (const unsigned char*)data_base85);
+ font = nk_font_atlas_add_compressed(atlas, compressed_data,
+ (nk_size)compressed_size, height, config);
+ atlas->temporary.free(atlas->temporary.userdata, compressed_data);
+ return font;
+}
+
+#ifdef NK_INCLUDE_DEFAULT_FONT
+NK_API struct nk_font*
+nk_font_atlas_add_default(struct nk_font_atlas *atlas,
+ float pixel_height, const struct nk_font_config *config)
+{
+ NK_ASSERT(atlas);
+ NK_ASSERT(atlas->temporary.alloc);
+ NK_ASSERT(atlas->temporary.free);
+ NK_ASSERT(atlas->permanent.alloc);
+ NK_ASSERT(atlas->permanent.free);
+ return nk_font_atlas_add_compressed_base85(atlas,
+ nk_proggy_clean_ttf_compressed_data_base85, pixel_height, config);
+}
+#endif
+
+NK_API const void*
+nk_font_atlas_bake(struct nk_font_atlas *atlas, int *width, int *height,
+ enum nk_font_atlas_format fmt)
+{
+ int i = 0;
+ void *tmp = 0;
+ nk_size tmp_size, img_size;
+ struct nk_font *font_iter;
+ struct nk_font_baker *baker;
+
+ NK_ASSERT(atlas);
+ NK_ASSERT(atlas->temporary.alloc);
+ NK_ASSERT(atlas->temporary.free);
+ NK_ASSERT(atlas->permanent.alloc);
+ NK_ASSERT(atlas->permanent.free);
+
+ NK_ASSERT(width);
+ NK_ASSERT(height);
+ if (!atlas || !width || !height ||
+ !atlas->temporary.alloc || !atlas->temporary.free ||
+ !atlas->permanent.alloc || !atlas->permanent.free)
+ return 0;
+
+#ifdef NK_INCLUDE_DEFAULT_FONT
+ /* no font added so just use default font */
+ if (!atlas->font_num)
+ atlas->default_font = nk_font_atlas_add_default(atlas, 13.0f, 0);
+#endif
+ NK_ASSERT(atlas->font_num);
+ if (!atlas->font_num) return 0;
+
+ /* allocate temporary baker memory required for the baking process */
+ nk_font_baker_memory(&tmp_size, &atlas->glyph_count, atlas->config, atlas->font_num);
+ tmp = atlas->temporary.alloc(atlas->temporary.userdata,0, tmp_size);
+ NK_ASSERT(tmp);
+ if (!tmp) goto failed;
+
+ /* allocate glyph memory for all fonts */
+ baker = nk_font_baker(tmp, atlas->glyph_count, atlas->font_num, &atlas->temporary);
+ atlas->glyphs = (struct nk_font_glyph*)atlas->permanent.alloc(
+ atlas->permanent.userdata,0, sizeof(struct nk_font_glyph)*(nk_size)atlas->glyph_count);
+ NK_ASSERT(atlas->glyphs);
+ if (!atlas->glyphs)
+ goto failed;
+
+ /* pack all glyphs into a tight fit space */
+ atlas->custom.w = (NK_CURSOR_DATA_W*2)+1;
+ atlas->custom.h = NK_CURSOR_DATA_H + 1;
+ if (!nk_font_bake_pack(baker, &img_size, width, height, &atlas->custom,
+ atlas->config, atlas->font_num, &atlas->temporary))
+ goto failed;
+
+ /* allocate memory for the baked image font atlas */
+ atlas->pixel = atlas->temporary.alloc(atlas->temporary.userdata,0, img_size);
+ NK_ASSERT(atlas->pixel);
+ if (!atlas->pixel)
+ goto failed;
+
+ /* bake glyphs and custom white pixel into image */
+ nk_font_bake(baker, atlas->pixel, *width, *height,
+ atlas->glyphs, atlas->glyph_count, atlas->config, atlas->font_num);
+ nk_font_bake_custom_data(atlas->pixel, *width, *height, atlas->custom,
+ nk_custom_cursor_data, NK_CURSOR_DATA_W, NK_CURSOR_DATA_H, '.', 'X');
+
+ if (fmt == NK_FONT_ATLAS_RGBA32) {
+ /* convert alpha8 image into rgba32 image */
+ void *img_rgba = atlas->temporary.alloc(atlas->temporary.userdata,0,
+ (nk_size)(*width * *height * 4));
+ NK_ASSERT(img_rgba);
+ if (!img_rgba) goto failed;
+ nk_font_bake_convert(img_rgba, *width, *height, atlas->pixel);
+ atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
+ atlas->pixel = img_rgba;
+ }
+ atlas->tex_width = *width;
+ atlas->tex_height = *height;
+
+ /* initialize each font */
+ for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
+ struct nk_font *font = font_iter;
+ struct nk_font_config *config = font->config;
+ nk_font_init(font, config->size, config->fallback_glyph, atlas->glyphs,
+ config->font, nk_handle_ptr(0));
+ }
+
+ /* initialize each cursor */
+ {NK_STORAGE const struct nk_vec2 nk_cursor_data[NK_CURSOR_COUNT][3] = {
+ /* Pos Size Offset */
+ {{ 0, 3}, {12,19}, { 0, 0}},
+ {{13, 0}, { 7,16}, { 4, 8}},
+ {{31, 0}, {23,23}, {11,11}},
+ {{21, 0}, { 9, 23}, { 5,11}},
+ {{55,18}, {23, 9}, {11, 5}},
+ {{73, 0}, {17,17}, { 9, 9}},
+ {{55, 0}, {17,17}, { 9, 9}}
+ };
+ for (i = 0; i < NK_CURSOR_COUNT; ++i) {
+ struct nk_cursor *cursor = &atlas->cursors[i];
+ cursor->img.w = (unsigned short)*width;
+ cursor->img.h = (unsigned short)*height;
+ cursor->img.region[0] = (unsigned short)(atlas->custom.x + nk_cursor_data[i][0].x);
+ cursor->img.region[1] = (unsigned short)(atlas->custom.y + nk_cursor_data[i][0].y);
+ cursor->img.region[2] = (unsigned short)nk_cursor_data[i][1].x;
+ cursor->img.region[3] = (unsigned short)nk_cursor_data[i][1].y;
+ cursor->size = nk_cursor_data[i][1];
+ cursor->offset = nk_cursor_data[i][2];
+ }}
+ /* free temporary memory */
+ atlas->temporary.free(atlas->temporary.userdata, tmp);
+ return atlas->pixel;
+
+failed:
+ /* error so cleanup all memory */
+ if (tmp) atlas->temporary.free(atlas->temporary.userdata, tmp);
+ if (atlas->glyphs) {
+ atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
+ atlas->glyphs = 0;
+ }
+ if (atlas->pixel) {
+ atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
+ atlas->pixel = 0;
+ }
+ return 0;
+}
+
+NK_API void
+nk_font_atlas_end(struct nk_font_atlas *atlas, nk_handle texture,
+ struct nk_draw_null_texture *null)
+{
+ int i = 0;
+ struct nk_font *font_iter;
+ NK_ASSERT(atlas);
+ if (!atlas) {
+ if (!null) return;
+ null->texture = texture;
+ null->uv = nk_vec2(0.5f,0.5f);
+ }
+ if (null) {
+ null->texture = texture;
+ null->uv.x = (atlas->custom.x + 0.5f)/(float)atlas->tex_width;
+ null->uv.y = (atlas->custom.y + 0.5f)/(float)atlas->tex_height;
+ }
+ for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) {
+ font_iter->texture = texture;
+#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+ font_iter->handle.texture = texture;
+#endif
+ }
+ for (i = 0; i < NK_CURSOR_COUNT; ++i)
+ atlas->cursors[i].img.handle = texture;
+
+ atlas->temporary.free(atlas->temporary.userdata, atlas->pixel);
+ atlas->pixel = 0;
+ atlas->tex_width = 0;
+ atlas->tex_height = 0;
+ atlas->custom.x = 0;
+ atlas->custom.y = 0;
+ atlas->custom.w = 0;
+ atlas->custom.h = 0;
+}
+
+NK_API void
+nk_font_atlas_cleanup(struct nk_font_atlas *atlas)
+{
+ NK_ASSERT(atlas);
+ NK_ASSERT(atlas->temporary.alloc);
+ NK_ASSERT(atlas->temporary.free);
+ NK_ASSERT(atlas->permanent.alloc);
+ NK_ASSERT(atlas->permanent.free);
+ if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) return;
+ if (atlas->config) {
+ struct nk_font_config *iter;
+ for (iter = atlas->config; iter; iter = iter->next) {
+ struct nk_font_config *i;
+ for (i = iter->n; i != iter; i = i->n) {
+ atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
+ i->ttf_blob = 0;
+ }
+ atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
+ iter->ttf_blob = 0;
+ }
+ }
+}
+
+NK_API void
+nk_font_atlas_clear(struct nk_font_atlas *atlas)
+{
+ NK_ASSERT(atlas);
+ NK_ASSERT(atlas->temporary.alloc);
+ NK_ASSERT(atlas->temporary.free);
+ NK_ASSERT(atlas->permanent.alloc);
+ NK_ASSERT(atlas->permanent.free);
+ if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) return;
+
+ if (atlas->config) {
+ struct nk_font_config *iter, *next;
+ for (iter = atlas->config; iter; iter = next) {
+ struct nk_font_config *i, *n;
+ for (i = iter->n; i != iter; i = n) {
+ n = i->n;
+ if (i->ttf_blob)
+ atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob);
+ atlas->permanent.free(atlas->permanent.userdata, i);
+ }
+ next = iter->next;
+ if (i->ttf_blob)
+ atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob);
+ atlas->permanent.free(atlas->permanent.userdata, iter);
+ }
+ atlas->config = 0;
+ }
+ if (atlas->fonts) {
+ struct nk_font *iter, *next;
+ for (iter = atlas->fonts; iter; iter = next) {
+ next = iter->next;
+ atlas->permanent.free(atlas->permanent.userdata, iter);
+ }
+ atlas->fonts = 0;
+ }
+ if (atlas->glyphs)
+ atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs);
+ nk_zero_struct(*atlas);
+}
+#endif
+/* ==============================================================
+ *
+ * INPUT
+ *
+ * ===============================================================*/
+NK_API void
+nk_input_begin(struct nk_context *ctx)
+{
+ int i;
+ struct nk_input *in;
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ in = &ctx->input;
+ for (i = 0; i < NK_BUTTON_MAX; ++i)
+ in->mouse.buttons[i].clicked = 0;
+
+ in->keyboard.text_len = 0;
+ in->mouse.scroll_delta = nk_vec2(0,0);
+ in->mouse.prev.x = in->mouse.pos.x;
+ in->mouse.prev.y = in->mouse.pos.y;
+ in->mouse.delta.x = 0;
+ in->mouse.delta.y = 0;
+ for (i = 0; i < NK_KEY_MAX; i++)
+ in->keyboard.keys[i].clicked = 0;
+}
+
+NK_API void
+nk_input_end(struct nk_context *ctx)
+{
+ struct nk_input *in;
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ in = &ctx->input;
+ if (in->mouse.grab)
+ in->mouse.grab = 0;
+ if (in->mouse.ungrab) {
+ in->mouse.grabbed = 0;
+ in->mouse.ungrab = 0;
+ in->mouse.grab = 0;
+ }
+}
+
+NK_API void
+nk_input_motion(struct nk_context *ctx, int x, int y)
+{
+ struct nk_input *in;
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ in = &ctx->input;
+ in->mouse.pos.x = (float)x;
+ in->mouse.pos.y = (float)y;
+ in->mouse.delta.x = in->mouse.pos.x - in->mouse.prev.x;
+ in->mouse.delta.y = in->mouse.pos.y - in->mouse.prev.y;
+}
+
+NK_API void
+nk_input_key(struct nk_context *ctx, enum nk_keys key, int down)
+{
+ struct nk_input *in;
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ in = &ctx->input;
+ if (in->keyboard.keys[key].down != down)
+ in->keyboard.keys[key].clicked++;
+ in->keyboard.keys[key].down = down;
+}
+
+NK_API void
+nk_input_button(struct nk_context *ctx, enum nk_buttons id, int x, int y, int down)
+{
+ struct nk_mouse_button *btn;
+ struct nk_input *in;
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ in = &ctx->input;
+ if (in->mouse.buttons[id].down == down) return;
+
+ btn = &in->mouse.buttons[id];
+ btn->clicked_pos.x = (float)x;
+ btn->clicked_pos.y = (float)y;
+ btn->down = down;
+ btn->clicked++;
+}
+
+NK_API void
+nk_input_scroll(struct nk_context *ctx, struct nk_vec2 val)
+{
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ ctx->input.mouse.scroll_delta.x += val.x;
+ ctx->input.mouse.scroll_delta.y += val.y;
+}
+
+NK_API void
+nk_input_glyph(struct nk_context *ctx, const nk_glyph glyph)
+{
+ int len = 0;
+ nk_rune unicode;
+ struct nk_input *in;
+
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ in = &ctx->input;
+
+ len = nk_utf_decode(glyph, &unicode, NK_UTF_SIZE);
+ if (len && ((in->keyboard.text_len + len) < NK_INPUT_MAX)) {
+ nk_utf_encode(unicode, &in->keyboard.text[in->keyboard.text_len],
+ NK_INPUT_MAX - in->keyboard.text_len);
+ in->keyboard.text_len += len;
+ }
+}
+
+NK_API void
+nk_input_char(struct nk_context *ctx, char c)
+{
+ nk_glyph glyph;
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ glyph[0] = c;
+ nk_input_glyph(ctx, glyph);
+}
+
+NK_API void
+nk_input_unicode(struct nk_context *ctx, nk_rune unicode)
+{
+ nk_glyph rune;
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ nk_utf_encode(unicode, rune, NK_UTF_SIZE);
+ nk_input_glyph(ctx, rune);
+}
+
+NK_API int
+nk_input_has_mouse_click(const struct nk_input *i, enum nk_buttons id)
+{
+ const struct nk_mouse_button *btn;
+ if (!i) return nk_false;
+ btn = &i->mouse.buttons[id];
+ return (btn->clicked && btn->down == nk_false) ? nk_true : nk_false;
+}
+
+NK_API int
+nk_input_has_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id,
+ struct nk_rect b)
+{
+ const struct nk_mouse_button *btn;
+ if (!i) return nk_false;
+ btn = &i->mouse.buttons[id];
+ if (!NK_INBOX(btn->clicked_pos.x,btn->clicked_pos.y,b.x,b.y,b.w,b.h))
+ return nk_false;
+ return nk_true;
+}
+
+NK_API int
+nk_input_has_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id,
+ struct nk_rect b, int down)
+{
+ const struct nk_mouse_button *btn;
+ if (!i) return nk_false;
+ btn = &i->mouse.buttons[id];
+ return nk_input_has_mouse_click_in_rect(i, id, b) && (btn->down == down);
+}
+
+NK_API int
+nk_input_is_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id,
+ struct nk_rect b)
+{
+ const struct nk_mouse_button *btn;
+ if (!i) return nk_false;
+ btn = &i->mouse.buttons[id];
+ return (nk_input_has_mouse_click_down_in_rect(i, id, b, nk_false) &&
+ btn->clicked) ? nk_true : nk_false;
+}
+
+NK_API int
+nk_input_is_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id,
+ struct nk_rect b, int down)
+{
+ const struct nk_mouse_button *btn;
+ if (!i) return nk_false;
+ btn = &i->mouse.buttons[id];
+ return (nk_input_has_mouse_click_down_in_rect(i, id, b, down) &&
+ btn->clicked) ? nk_true : nk_false;
+}
+
+NK_API int
+nk_input_any_mouse_click_in_rect(const struct nk_input *in, struct nk_rect b)
+{
+ int i, down = 0;
+ for (i = 0; i < NK_BUTTON_MAX; ++i)
+ down = down || nk_input_is_mouse_click_in_rect(in, (enum nk_buttons)i, b);
+ return down;
+}
+
+NK_API int
+nk_input_is_mouse_hovering_rect(const struct nk_input *i, struct nk_rect rect)
+{
+ if (!i) return nk_false;
+ return NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h);
+}
+
+NK_API int
+nk_input_is_mouse_prev_hovering_rect(const struct nk_input *i, struct nk_rect rect)
+{
+ if (!i) return nk_false;
+ return NK_INBOX(i->mouse.prev.x, i->mouse.prev.y, rect.x, rect.y, rect.w, rect.h);
+}
+
+NK_API int
+nk_input_mouse_clicked(const struct nk_input *i, enum nk_buttons id, struct nk_rect rect)
+{
+ if (!i) return nk_false;
+ if (!nk_input_is_mouse_hovering_rect(i, rect)) return nk_false;
+ return nk_input_is_mouse_click_in_rect(i, id, rect);
+}
+
+NK_API int
+nk_input_is_mouse_down(const struct nk_input *i, enum nk_buttons id)
+{
+ if (!i) return nk_false;
+ return i->mouse.buttons[id].down;
+}
+
+NK_API int
+nk_input_is_mouse_pressed(const struct nk_input *i, enum nk_buttons id)
+{
+ const struct nk_mouse_button *b;
+ if (!i) return nk_false;
+ b = &i->mouse.buttons[id];
+ if (b->down && b->clicked)
+ return nk_true;
+ return nk_false;
+}
+
+NK_API int
+nk_input_is_mouse_released(const struct nk_input *i, enum nk_buttons id)
+{
+ if (!i) return nk_false;
+ return (!i->mouse.buttons[id].down && i->mouse.buttons[id].clicked);
+}
+
+NK_API int
+nk_input_is_key_pressed(const struct nk_input *i, enum nk_keys key)
+{
+ const struct nk_key *k;
+ if (!i) return nk_false;
+ k = &i->keyboard.keys[key];
+ if ((k->down && k->clicked) || (!k->down && k->clicked >= 2))
+ return nk_true;
+ return nk_false;
+}
+
+NK_API int
+nk_input_is_key_released(const struct nk_input *i, enum nk_keys key)
+{
+ const struct nk_key *k;
+ if (!i) return nk_false;
+ k = &i->keyboard.keys[key];
+ if ((!k->down && k->clicked) || (k->down && k->clicked >= 2))
+ return nk_true;
+ return nk_false;
+}
+
+NK_API int
+nk_input_is_key_down(const struct nk_input *i, enum nk_keys key)
+{
+ const struct nk_key *k;
+ if (!i) return nk_false;
+ k = &i->keyboard.keys[key];
+ if (k->down) return nk_true;
+ return nk_false;
+}
+
+/*
+ * ==============================================================
+ *
+ * TEXT EDITOR
+ *
+ * ===============================================================
+ */
+/* stb_textedit.h - v1.8 - public domain - Sean Barrett */
+struct nk_text_find {
+ float x,y; /* position of n'th character */
+ float height; /* height of line */
+ int first_char, length; /* first char of row, and length */
+ int prev_first; /*_ first char of previous row */
+};
+
+struct nk_text_edit_row {
+ float x0,x1;
+ /* starting x location, end x location (allows for align=right, etc) */
+ float baseline_y_delta;
+ /* position of baseline relative to previous row's baseline*/
+ float ymin,ymax;
+ /* height of row above and below baseline */
+ int num_chars;
+};
+
+/* forward declarations */
+NK_INTERN void nk_textedit_makeundo_delete(struct nk_text_edit*, int, int);
+NK_INTERN void nk_textedit_makeundo_insert(struct nk_text_edit*, int, int);
+NK_INTERN void nk_textedit_makeundo_replace(struct nk_text_edit*, int, int, int);
+#define NK_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
+
+NK_INTERN float
+nk_textedit_get_width(const struct nk_text_edit *edit, int line_start, int char_id,
+ const struct nk_user_font *font)
+{
+ int len = 0;
+ nk_rune unicode = 0;
+ const char *str = nk_str_at_const(&edit->string, line_start + char_id, &unicode, &len);
+ return font->width(font->userdata, font->height, str, len);
+}
+
+NK_INTERN void
+nk_textedit_layout_row(struct nk_text_edit_row *r, struct nk_text_edit *edit,
+ int line_start_id, float row_height, const struct nk_user_font *font)
+{
+ int l;
+ int glyphs = 0;
+ nk_rune unicode;
+ const char *remaining;
+ int len = nk_str_len_char(&edit->string);
+ const char *end = nk_str_get_const(&edit->string) + len;
+ const char *text = nk_str_at_const(&edit->string, line_start_id, &unicode, &l);
+ const struct nk_vec2 size = nk_text_calculate_text_bounds(font,
+ text, (int)(end - text), row_height, &remaining, 0, &glyphs, NK_STOP_ON_NEW_LINE);
+
+ r->x0 = 0.0f;
+ r->x1 = size.x;
+ r->baseline_y_delta = size.y;
+ r->ymin = 0.0f;
+ r->ymax = size.y;
+ r->num_chars = glyphs;
+}
+
+NK_INTERN int
+nk_textedit_locate_coord(struct nk_text_edit *edit, float x, float y,
+ const struct nk_user_font *font, float row_height)
+{
+ struct nk_text_edit_row r;
+ int n = edit->string.len;
+ float base_y = 0, prev_x;
+ int i=0, k;
+
+ r.x0 = r.x1 = 0;
+ r.ymin = r.ymax = 0;
+ r.num_chars = 0;
+
+ /* search rows to find one that straddles 'y' */
+ while (i < n) {
+ nk_textedit_layout_row(&r, edit, i, row_height, font);
+ if (r.num_chars <= 0)
+ return n;
+
+ if (i==0 && y < base_y + r.ymin)
+ return 0;
+
+ if (y < base_y + r.ymax)
+ break;
+
+ i += r.num_chars;
+ base_y += r.baseline_y_delta;
+ }
+
+ /* below all text, return 'after' last character */
+ if (i >= n)
+ return n;
+
+ /* check if it's before the beginning of the line */
+ if (x < r.x0)
+ return i;
+
+ /* check if it's before the end of the line */
+ if (x < r.x1) {
+ /* search characters in row for one that straddles 'x' */
+ k = i;
+ prev_x = r.x0;
+ for (i=0; i < r.num_chars; ++i) {
+ float w = nk_textedit_get_width(edit, k, i, font);
+ if (x < prev_x+w) {
+ if (x < prev_x+w/2)
+ return k+i;
+ else return k+i+1;
+ }
+ prev_x += w;
+ }
+ /* shouldn't happen, but if it does, fall through to end-of-line case */
+ }
+
+ /* if the last character is a newline, return that.
+ * otherwise return 'after' the last character */
+ if (nk_str_rune_at(&edit->string, i+r.num_chars-1) == '\n')
+ return i+r.num_chars-1;
+ else return i+r.num_chars;
+}
+
+NK_INTERN void
+nk_textedit_click(struct nk_text_edit *state, float x, float y,
+ const struct nk_user_font *font, float row_height)
+{
+ /* API click: on mouse down, move the cursor to the clicked location,
+ * and reset the selection */
+ state->cursor = nk_textedit_locate_coord(state, x, y, font, row_height);
+ state->select_start = state->cursor;
+ state->select_end = state->cursor;
+ state->has_preferred_x = 0;
+}
+
+NK_INTERN void
+nk_textedit_drag(struct nk_text_edit *state, float x, float y,
+ const struct nk_user_font *font, float row_height)
+{
+ /* API drag: on mouse drag, move the cursor and selection endpoint
+ * to the clicked location */
+ int p = nk_textedit_locate_coord(state, x, y, font, row_height);
+ if (state->select_start == state->select_end)
+ state->select_start = state->cursor;
+ state->cursor = state->select_end = p;
+}
+
+NK_INTERN void
+nk_textedit_find_charpos(struct nk_text_find *find, struct nk_text_edit *state,
+ int n, int single_line, const struct nk_user_font *font, float row_height)
+{
+ /* find the x/y location of a character, and remember info about the previous
+ * row in case we get a move-up event (for page up, we'll have to rescan) */
+ struct nk_text_edit_row r;
+ int prev_start = 0;
+ int z = state->string.len;
+ int i=0, first;
+
+ nk_zero_struct(r);
+ if (n == z) {
+ /* if it's at the end, then find the last line -- simpler than trying to
+ explicitly handle this case in the regular code */
+ nk_textedit_layout_row(&r, state, 0, row_height, font);
+ if (single_line) {
+ find->first_char = 0;
+ find->length = z;
+ } else {
+ while (i < z) {
+ prev_start = i;
+ i += r.num_chars;
+ nk_textedit_layout_row(&r, state, i, row_height, font);
+ }
+
+ find->first_char = i;
+ find->length = r.num_chars;
+ }
+ find->x = r.x1;
+ find->y = r.ymin;
+ find->height = r.ymax - r.ymin;
+ find->prev_first = prev_start;
+ return;
+ }
+
+ /* search rows to find the one that straddles character n */
+ find->y = 0;
+
+ for(;;) {
+ nk_textedit_layout_row(&r, state, i, row_height, font);
+ if (n < i + r.num_chars) break;
+ prev_start = i;
+ i += r.num_chars;
+ find->y += r.baseline_y_delta;
+ }
+
+ find->first_char = first = i;
+ find->length = r.num_chars;
+ find->height = r.ymax - r.ymin;
+ find->prev_first = prev_start;
+
+ /* now scan to find xpos */
+ find->x = r.x0;
+ for (i=0; first+i < n; ++i)
+ find->x += nk_textedit_get_width(state, first, i, font);
+}
+
+NK_INTERN void
+nk_textedit_clamp(struct nk_text_edit *state)
+{
+ /* make the selection/cursor state valid if client altered the string */
+ int n = state->string.len;
+ if (NK_TEXT_HAS_SELECTION(state)) {
+ if (state->select_start > n) state->select_start = n;
+ if (state->select_end > n) state->select_end = n;
+ /* if clamping forced them to be equal, move the cursor to match */
+ if (state->select_start == state->select_end)
+ state->cursor = state->select_start;
+ }
+ if (state->cursor > n) state->cursor = n;
+}
+
+NK_API void
+nk_textedit_delete(struct nk_text_edit *state, int where, int len)
+{
+ /* delete characters while updating undo */
+ nk_textedit_makeundo_delete(state, where, len);
+ nk_str_delete_runes(&state->string, where, len);
+ state->has_preferred_x = 0;
+}
+
+NK_API void
+nk_textedit_delete_selection(struct nk_text_edit *state)
+{
+ /* delete the section */
+ nk_textedit_clamp(state);
+ if (NK_TEXT_HAS_SELECTION(state)) {
+ if (state->select_start < state->select_end) {
+ nk_textedit_delete(state, state->select_start,
+ state->select_end - state->select_start);
+ state->select_end = state->cursor = state->select_start;
+ } else {
+ nk_textedit_delete(state, state->select_end,
+ state->select_start - state->select_end);
+ state->select_start = state->cursor = state->select_end;
+ }
+ state->has_preferred_x = 0;
+ }
+}
+
+NK_INTERN void
+nk_textedit_sortselection(struct nk_text_edit *state)
+{
+ /* canonicalize the selection so start <= end */
+ if (state->select_end < state->select_start) {
+ int temp = state->select_end;
+ state->select_end = state->select_start;
+ state->select_start = temp;
+ }
+}
+
+NK_INTERN void
+nk_textedit_move_to_first(struct nk_text_edit *state)
+{
+ /* move cursor to first character of selection */
+ if (NK_TEXT_HAS_SELECTION(state)) {
+ nk_textedit_sortselection(state);
+ state->cursor = state->select_start;
+ state->select_end = state->select_start;
+ state->has_preferred_x = 0;
+ }
+}
+
+NK_INTERN void
+nk_textedit_move_to_last(struct nk_text_edit *state)
+{
+ /* move cursor to last character of selection */
+ if (NK_TEXT_HAS_SELECTION(state)) {
+ nk_textedit_sortselection(state);
+ nk_textedit_clamp(state);
+ state->cursor = state->select_end;
+ state->select_start = state->select_end;
+ state->has_preferred_x = 0;
+ }
+}
+
+NK_INTERN int
+nk_is_word_boundary( struct nk_text_edit *state, int idx)
+{
+ int len;
+ nk_rune c;
+ if (idx <= 0) return 1;
+ if (!nk_str_at_rune(&state->string, idx, &c, &len)) return 1;
+ return (c == ' ' || c == '\t' ||c == 0x3000 || c == ',' || c == ';' ||
+ c == '(' || c == ')' || c == '{' || c == '}' || c == '[' || c == ']' ||
+ c == '|');
+}
+
+NK_INTERN int
+nk_textedit_move_to_word_previous(struct nk_text_edit *state)
+{
+ int c = state->cursor - 1;
+ while( c >= 0 && !nk_is_word_boundary(state, c))
+ --c;
+
+ if( c < 0 )
+ c = 0;
+
+ return c;
+}
+
+NK_INTERN int
+nk_textedit_move_to_word_next(struct nk_text_edit *state)
+{
+ const int len = state->string.len;
+ int c = state->cursor+1;
+ while( c < len && !nk_is_word_boundary(state, c))
+ ++c;
+
+ if( c > len )
+ c = len;
+
+ return c;
+}
+
+NK_INTERN void
+nk_textedit_prep_selection_at_cursor(struct nk_text_edit *state)
+{
+ /* update selection and cursor to match each other */
+ if (!NK_TEXT_HAS_SELECTION(state))
+ state->select_start = state->select_end = state->cursor;
+ else state->cursor = state->select_end;
+}
+
+NK_API int
+nk_textedit_cut(struct nk_text_edit *state)
+{
+ /* API cut: delete selection */
+ if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
+ return 0;
+ if (NK_TEXT_HAS_SELECTION(state)) {
+ nk_textedit_delete_selection(state); /* implicitly clamps */
+ state->has_preferred_x = 0;
+ return 1;
+ }
+ return 0;
+}
+
+NK_API int
+nk_textedit_paste(struct nk_text_edit *state, char const *ctext, int len)
+{
+ /* API paste: replace existing selection with passed-in text */
+ int glyphs;
+ const char *text = (const char *) ctext;
+ if (state->mode == NK_TEXT_EDIT_MODE_VIEW) return 0;
+
+ /* if there's a selection, the paste should delete it */
+ nk_textedit_clamp(state);
+ nk_textedit_delete_selection(state);
+
+ /* try to insert the characters */
+ glyphs = nk_utf_len(ctext, len);
+ if (nk_str_insert_text_char(&state->string, state->cursor, text, len)) {
+ nk_textedit_makeundo_insert(state, state->cursor, glyphs);
+ state->cursor += len;
+ state->has_preferred_x = 0;
+ return 1;
+ }
+ /* remove the undo since we didn't actually insert the characters */
+ if (state->undo.undo_point)
+ --state->undo.undo_point;
+ return 0;
+}
+
+NK_API void
+nk_textedit_text(struct nk_text_edit *state, const char *text, int total_len)
+{
+ nk_rune unicode;
+ int glyph_len;
+ int text_len = 0;
+
+ NK_ASSERT(state);
+ NK_ASSERT(text);
+ if (!text || !total_len || state->mode == NK_TEXT_EDIT_MODE_VIEW) return;
+
+ glyph_len = nk_utf_decode(text, &unicode, total_len);
+ while ((text_len < total_len) && glyph_len)
+ {
+ /* don't insert a backward delete, just process the event */
+ if (unicode == 127) goto next;
+ /* can't add newline in single-line mode */
+ if (unicode == '\n' && state->single_line) goto next;
+ /* filter incoming text */
+ if (state->filter && !state->filter(state, unicode)) goto next;
+
+ if (!NK_TEXT_HAS_SELECTION(state) &&
+ state->cursor < state->string.len)
+ {
+ if (state->mode == NK_TEXT_EDIT_MODE_REPLACE) {
+ nk_textedit_makeundo_replace(state, state->cursor, 1, 1);
+ nk_str_delete_runes(&state->string, state->cursor, 1);
+ }
+ if (nk_str_insert_text_utf8(&state->string, state->cursor,
+ text+text_len, 1))
+ {
+ ++state->cursor;
+ state->has_preferred_x = 0;
+ }
+ } else {
+ nk_textedit_delete_selection(state); /* implicitly clamps */
+ if (nk_str_insert_text_utf8(&state->string, state->cursor,
+ text+text_len, 1))
+ {
+ nk_textedit_makeundo_insert(state, state->cursor, 1);
+ ++state->cursor;
+ state->has_preferred_x = 0;
+ }
+ }
+ next:
+ text_len += glyph_len;
+ glyph_len = nk_utf_decode(text + text_len, &unicode, total_len-text_len);
+ }
+}
+
+NK_INTERN void
+nk_textedit_key(struct nk_text_edit *state, enum nk_keys key, int shift_mod,
+ const struct nk_user_font *font, float row_height)
+{
+retry:
+ switch (key)
+ {
+ case NK_KEY_NONE:
+ case NK_KEY_CTRL:
+ case NK_KEY_ENTER:
+ case NK_KEY_SHIFT:
+ case NK_KEY_TAB:
+ case NK_KEY_COPY:
+ case NK_KEY_CUT:
+ case NK_KEY_PASTE:
+ case NK_KEY_MAX:
+ default: break;
+ case NK_KEY_TEXT_UNDO:
+ nk_textedit_undo(state);
+ state->has_preferred_x = 0;
+ break;
+
+ case NK_KEY_TEXT_REDO:
+ nk_textedit_redo(state);
+ state->has_preferred_x = 0;
+ break;
+
+ case NK_KEY_TEXT_SELECT_ALL:
+ nk_textedit_select_all(state);
+ state->has_preferred_x = 0;
+ break;
+
+ case NK_KEY_TEXT_INSERT_MODE:
+ if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
+ state->mode = NK_TEXT_EDIT_MODE_INSERT;
+ break;
+ case NK_KEY_TEXT_REPLACE_MODE:
+ if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
+ state->mode = NK_TEXT_EDIT_MODE_REPLACE;
+ break;
+ case NK_KEY_TEXT_RESET_MODE:
+ if (state->mode == NK_TEXT_EDIT_MODE_INSERT ||
+ state->mode == NK_TEXT_EDIT_MODE_REPLACE)
+ state->mode = NK_TEXT_EDIT_MODE_VIEW;
+ break;
+
+ case NK_KEY_LEFT:
+ if (shift_mod) {
+ nk_textedit_clamp(state);
+ nk_textedit_prep_selection_at_cursor(state);
+ /* move selection left */
+ if (state->select_end > 0)
+ --state->select_end;
+ state->cursor = state->select_end;
+ state->has_preferred_x = 0;
+ } else {
+ /* if currently there's a selection,
+ * move cursor to start of selection */
+ if (NK_TEXT_HAS_SELECTION(state))
+ nk_textedit_move_to_first(state);
+ else if (state->cursor > 0)
+ --state->cursor;
+ state->has_preferred_x = 0;
+ } break;
+
+ case NK_KEY_RIGHT:
+ if (shift_mod) {
+ nk_textedit_prep_selection_at_cursor(state);
+ /* move selection right */
+ ++state->select_end;
+ nk_textedit_clamp(state);
+ state->cursor = state->select_end;
+ state->has_preferred_x = 0;
+ } else {
+ /* if currently there's a selection,
+ * move cursor to end of selection */
+ if (NK_TEXT_HAS_SELECTION(state))
+ nk_textedit_move_to_last(state);
+ else ++state->cursor;
+ nk_textedit_clamp(state);
+ state->has_preferred_x = 0;
+ } break;
+
+ case NK_KEY_TEXT_WORD_LEFT:
+ if (shift_mod) {
+ if( !NK_TEXT_HAS_SELECTION( state ) )
+ nk_textedit_prep_selection_at_cursor(state);
+ state->cursor = nk_textedit_move_to_word_previous(state);
+ state->select_end = state->cursor;
+ nk_textedit_clamp(state );
+ } else {
+ if (NK_TEXT_HAS_SELECTION(state))
+ nk_textedit_move_to_first(state);
+ else {
+ state->cursor = nk_textedit_move_to_word_previous(state);
+ nk_textedit_clamp(state );
+ }
+ } break;
+
+ case NK_KEY_TEXT_WORD_RIGHT:
+ if (shift_mod) {
+ if( !NK_TEXT_HAS_SELECTION( state ) )
+ nk_textedit_prep_selection_at_cursor(state);
+ state->cursor = nk_textedit_move_to_word_next(state);
+ state->select_end = state->cursor;
+ nk_textedit_clamp(state);
+ } else {
+ if (NK_TEXT_HAS_SELECTION(state))
+ nk_textedit_move_to_last(state);
+ else {
+ state->cursor = nk_textedit_move_to_word_next(state);
+ nk_textedit_clamp(state );
+ }
+ } break;
+
+ case NK_KEY_DOWN: {
+ struct nk_text_find find;
+ struct nk_text_edit_row row;
+ int i, sel = shift_mod;
+
+ if (state->single_line) {
+ /* on windows, up&down in single-line behave like left&right */
+ key = NK_KEY_RIGHT;
+ goto retry;
+ }
+
+ if (sel)
+ nk_textedit_prep_selection_at_cursor(state);
+ else if (NK_TEXT_HAS_SELECTION(state))
+ nk_textedit_move_to_last(state);
+
+ /* compute current position of cursor point */
+ nk_textedit_clamp(state);
+ nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
+ font, row_height);
+
+ /* now find character position down a row */
+ if (find.length)
+ {
+ float x;
+ float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
+ int start = find.first_char + find.length;
+
+ state->cursor = start;
+ nk_textedit_layout_row(&row, state, state->cursor, row_height, font);
+ x = row.x0;
+
+ for (i=0; i < row.num_chars && x < row.x1; ++i) {
+ float dx = nk_textedit_get_width(state, start, i, font);
+ x += dx;
+ if (x > goal_x)
+ break;
+ ++state->cursor;
+ }
+ nk_textedit_clamp(state);
+
+ state->has_preferred_x = 1;
+ state->preferred_x = goal_x;
+ if (sel)
+ state->select_end = state->cursor;
+ }
+ } break;
+
+ case NK_KEY_UP: {
+ struct nk_text_find find;
+ struct nk_text_edit_row row;
+ int i, sel = shift_mod;
+
+ if (state->single_line) {
+ /* on windows, up&down become left&right */
+ key = NK_KEY_LEFT;
+ goto retry;
+ }
+
+ if (sel)
+ nk_textedit_prep_selection_at_cursor(state);
+ else if (NK_TEXT_HAS_SELECTION(state))
+ nk_textedit_move_to_first(state);
+
+ /* compute current position of cursor point */
+ nk_textedit_clamp(state);
+ nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
+ font, row_height);
+
+ /* can only go up if there's a previous row */
+ if (find.prev_first != find.first_char) {
+ /* now find character position up a row */
+ float x;
+ float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
+
+ state->cursor = find.prev_first;
+ nk_textedit_layout_row(&row, state, state->cursor, row_height, font);
+ x = row.x0;
+
+ for (i=0; i < row.num_chars && x < row.x1; ++i) {
+ float dx = nk_textedit_get_width(state, find.prev_first, i, font);
+ x += dx;
+ if (x > goal_x)
+ break;
+ ++state->cursor;
+ }
+ nk_textedit_clamp(state);
+
+ state->has_preferred_x = 1;
+ state->preferred_x = goal_x;
+ if (sel) state->select_end = state->cursor;
+ }
+ } break;
+
+ case NK_KEY_DEL:
+ if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
+ break;
+ if (NK_TEXT_HAS_SELECTION(state))
+ nk_textedit_delete_selection(state);
+ else {
+ int n = state->string.len;
+ if (state->cursor < n)
+ nk_textedit_delete(state, state->cursor, 1);
+ }
+ state->has_preferred_x = 0;
+ break;
+
+ case NK_KEY_BACKSPACE:
+ if (state->mode == NK_TEXT_EDIT_MODE_VIEW)
+ break;
+ if (NK_TEXT_HAS_SELECTION(state))
+ nk_textedit_delete_selection(state);
+ else {
+ nk_textedit_clamp(state);
+ if (state->cursor > 0) {
+ nk_textedit_delete(state, state->cursor-1, 1);
+ --state->cursor;
+ }
+ }
+ state->has_preferred_x = 0;
+ break;
+
+ case NK_KEY_TEXT_START:
+ if (shift_mod) {
+ nk_textedit_prep_selection_at_cursor(state);
+ state->cursor = state->select_end = 0;
+ state->has_preferred_x = 0;
+ } else {
+ state->cursor = state->select_start = state->select_end = 0;
+ state->has_preferred_x = 0;
+ }
+ break;
+
+ case NK_KEY_TEXT_END:
+ if (shift_mod) {
+ nk_textedit_prep_selection_at_cursor(state);
+ state->cursor = state->select_end = state->string.len;
+ state->has_preferred_x = 0;
+ } else {
+ state->cursor = state->string.len;
+ state->select_start = state->select_end = 0;
+ state->has_preferred_x = 0;
+ }
+ break;
+
+ case NK_KEY_TEXT_LINE_START: {
+ if (shift_mod) {
+ struct nk_text_find find;
+ nk_textedit_clamp(state);
+ nk_textedit_prep_selection_at_cursor(state);
+ if (state->string.len && state->cursor == state->string.len)
+ --state->cursor;
+ nk_textedit_find_charpos(&find, state,state->cursor, state->single_line,
+ font, row_height);
+ state->cursor = state->select_end = find.first_char;
+ state->has_preferred_x = 0;
+ } else {
+ struct nk_text_find find;
+ if (state->string.len && state->cursor == state->string.len)
+ --state->cursor;
+ nk_textedit_clamp(state);
+ nk_textedit_move_to_first(state);
+ nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
+ font, row_height);
+ state->cursor = find.first_char;
+ state->has_preferred_x = 0;
+ }
+ } break;
+
+ case NK_KEY_TEXT_LINE_END: {
+ if (shift_mod) {
+ struct nk_text_find find;
+ nk_textedit_clamp(state);
+ nk_textedit_prep_selection_at_cursor(state);
+ nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
+ font, row_height);
+ state->has_preferred_x = 0;
+ state->cursor = find.first_char + find.length;
+ if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor-1) == '\n')
+ --state->cursor;
+ state->select_end = state->cursor;
+ } else {
+ struct nk_text_find find;
+ nk_textedit_clamp(state);
+ nk_textedit_move_to_first(state);
+ nk_textedit_find_charpos(&find, state, state->cursor, state->single_line,
+ font, row_height);
+
+ state->has_preferred_x = 0;
+ state->cursor = find.first_char + find.length;
+ if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor-1) == '\n')
+ --state->cursor;
+ }} break;
+ }
+}
+
+NK_INTERN void
+nk_textedit_flush_redo(struct nk_text_undo_state *state)
+{
+ state->redo_point = NK_TEXTEDIT_UNDOSTATECOUNT;
+ state->redo_char_point = NK_TEXTEDIT_UNDOCHARCOUNT;
+}
+
+NK_INTERN void
+nk_textedit_discard_undo(struct nk_text_undo_state *state)
+{
+ /* discard the oldest entry in the undo list */
+ if (state->undo_point > 0) {
+ /* if the 0th undo state has characters, clean those up */
+ if (state->undo_rec[0].char_storage >= 0) {
+ int n = state->undo_rec[0].insert_length, i;
+ /* delete n characters from all other records */
+ state->undo_char_point = (short)(state->undo_char_point - n);
+ NK_MEMCPY(state->undo_char, state->undo_char + n,
+ (nk_size)state->undo_char_point*sizeof(nk_rune));
+ for (i=0; i < state->undo_point; ++i) {
+ if (state->undo_rec[i].char_storage >= 0)
+ state->undo_rec[i].char_storage = (short)
+ (state->undo_rec[i].char_storage - n);
+ }
+ }
+ --state->undo_point;
+ NK_MEMCPY(state->undo_rec, state->undo_rec+1,
+ (nk_size)((nk_size)state->undo_point * sizeof(state->undo_rec[0])));
+ }
+}
+
+NK_INTERN void
+nk_textedit_discard_redo(struct nk_text_undo_state *state)
+{
+/* discard the oldest entry in the redo list--it's bad if this
+ ever happens, but because undo & redo have to store the actual
+ characters in different cases, the redo character buffer can
+ fill up even though the undo buffer didn't */
+ nk_size num;
+ int k = NK_TEXTEDIT_UNDOSTATECOUNT-1;
+ if (state->redo_point <= k) {
+ /* if the k'th undo state has characters, clean those up */
+ if (state->undo_rec[k].char_storage >= 0) {
+ int n = state->undo_rec[k].insert_length, i;
+ /* delete n characters from all other records */
+ state->redo_char_point = (short)(state->redo_char_point + n);
+ num = (nk_size)(NK_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point);
+ NK_MEMCPY(state->undo_char + state->redo_char_point,
+ state->undo_char + state->redo_char_point-n, num * sizeof(char));
+ for (i = state->redo_point; i < k; ++i) {
+ if (state->undo_rec[i].char_storage >= 0) {
+ state->undo_rec[i].char_storage = (short)
+ (state->undo_rec[i].char_storage + n);
+ }
+ }
+ }
+ ++state->redo_point;
+ num = (nk_size)(NK_TEXTEDIT_UNDOSTATECOUNT - state->redo_point);
+ if (num) NK_MEMCPY(state->undo_rec + state->redo_point-1,
+ state->undo_rec + state->redo_point, num * sizeof(state->undo_rec[0]));
+ }
+}
+
+NK_INTERN struct nk_text_undo_record*
+nk_textedit_create_undo_record(struct nk_text_undo_state *state, int numchars)
+{
+ /* any time we create a new undo record, we discard redo*/
+ nk_textedit_flush_redo(state);
+
+ /* if we have no free records, we have to make room,
+ * by sliding the existing records down */
+ if (state->undo_point == NK_TEXTEDIT_UNDOSTATECOUNT)
+ nk_textedit_discard_undo(state);
+
+ /* if the characters to store won't possibly fit in the buffer,
+ * we can't undo */
+ if (numchars > NK_TEXTEDIT_UNDOCHARCOUNT) {
+ state->undo_point = 0;
+ state->undo_char_point = 0;
+ return 0;
+ }
+
+ /* if we don't have enough free characters in the buffer,
+ * we have to make room */
+ while (state->undo_char_point + numchars > NK_TEXTEDIT_UNDOCHARCOUNT)
+ nk_textedit_discard_undo(state);
+ return &state->undo_rec[state->undo_point++];
+}
+
+NK_INTERN nk_rune*
+nk_textedit_createundo(struct nk_text_undo_state *state, int pos,
+ int insert_len, int delete_len)
+{
+ struct nk_text_undo_record *r = nk_textedit_create_undo_record(state, insert_len);
+ if (r == 0)
+ return 0;
+
+ r->where = pos;
+ r->insert_length = (short) insert_len;
+ r->delete_length = (short) delete_len;
+
+ if (insert_len == 0) {
+ r->char_storage = -1;
+ return 0;
+ } else {
+ r->char_storage = state->undo_char_point;
+ state->undo_char_point = (short)(state->undo_char_point + insert_len);
+ return &state->undo_char[r->char_storage];
+ }
+}
+
+NK_API void
+nk_textedit_undo(struct nk_text_edit *state)
+{
+ struct nk_text_undo_state *s = &state->undo;
+ struct nk_text_undo_record u, *r;
+ if (s->undo_point == 0)
+ return;
+
+ /* we need to do two things: apply the undo record, and create a redo record */
+ u = s->undo_rec[s->undo_point-1];
+ r = &s->undo_rec[s->redo_point-1];
+ r->char_storage = -1;
+
+ r->insert_length = u.delete_length;
+ r->delete_length = u.insert_length;
+ r->where = u.where;
+
+ if (u.delete_length)
+ {
+ /* if the undo record says to delete characters, then the redo record will
+ need to re-insert the characters that get deleted, so we need to store
+ them.
+ there are three cases:
+ - there's enough room to store the characters
+ - characters stored for *redoing* don't leave room for redo
+ - characters stored for *undoing* don't leave room for redo
+ if the last is true, we have to bail */
+ if (s->undo_char_point + u.delete_length >= NK_TEXTEDIT_UNDOCHARCOUNT) {
+ /* the undo records take up too much character space; there's no space
+ * to store the redo characters */
+ r->insert_length = 0;
+ } else {
+ int i;
+ /* there's definitely room to store the characters eventually */
+ while (s->undo_char_point + u.delete_length > s->redo_char_point) {
+ /* there's currently not enough room, so discard a redo record */
+ nk_textedit_discard_redo(s);
+ /* should never happen: */
+ if (s->redo_point == NK_TEXTEDIT_UNDOSTATECOUNT)
+ return;
+ }
+
+ r = &s->undo_rec[s->redo_point-1];
+ r->char_storage = (short)(s->redo_char_point - u.delete_length);
+ s->redo_char_point = (short)(s->redo_char_point - u.delete_length);
+
+ /* now save the characters */
+ for (i=0; i < u.delete_length; ++i)
+ s->undo_char[r->char_storage + i] =
+ nk_str_rune_at(&state->string, u.where + i);
+ }
+ /* now we can carry out the deletion */
+ nk_str_delete_runes(&state->string, u.where, u.delete_length);
+ }
+
+ /* check type of recorded action: */
+ if (u.insert_length) {
+ /* easy case: was a deletion, so we need to insert n characters */
+ nk_str_insert_text_runes(&state->string, u.where,
+ &s->undo_char[u.char_storage], u.insert_length);
+ s->undo_char_point = (short)(s->undo_char_point - u.insert_length);
+ }
+ state->cursor = (short)(u.where + u.insert_length);
+
+ s->undo_point--;
+ s->redo_point--;
+}
+
+NK_API void
+nk_textedit_redo(struct nk_text_edit *state)
+{
+ struct nk_text_undo_state *s = &state->undo;
+ struct nk_text_undo_record *u, r;
+ if (s->redo_point == NK_TEXTEDIT_UNDOSTATECOUNT)
+ return;
+
+ /* we need to do two things: apply the redo record, and create an undo record */
+ u = &s->undo_rec[s->undo_point];
+ r = s->undo_rec[s->redo_point];
+
+ /* we KNOW there must be room for the undo record, because the redo record
+ was derived from an undo record */
+ u->delete_length = r.insert_length;
+ u->insert_length = r.delete_length;
+ u->where = r.where;
+ u->char_storage = -1;
+
+ if (r.delete_length) {
+ /* the redo record requires us to delete characters, so the undo record
+ needs to store the characters */
+ if (s->undo_char_point + u->insert_length > s->redo_char_point) {
+ u->insert_length = 0;
+ u->delete_length = 0;
+ } else {
+ int i;
+ u->char_storage = s->undo_char_point;
+ s->undo_char_point = (short)(s->undo_char_point + u->insert_length);
+
+ /* now save the characters */
+ for (i=0; i < u->insert_length; ++i) {
+ s->undo_char[u->char_storage + i] =
+ nk_str_rune_at(&state->string, u->where + i);
+ }
+ }
+ nk_str_delete_runes(&state->string, r.where, r.delete_length);
+ }
+
+ if (r.insert_length) {
+ /* easy case: need to insert n characters */
+ nk_str_insert_text_runes(&state->string, r.where,
+ &s->undo_char[r.char_storage], r.insert_length);
+ }
+ state->cursor = r.where + r.insert_length;
+
+ s->undo_point++;
+ s->redo_point++;
+}
+
+NK_INTERN void
+nk_textedit_makeundo_insert(struct nk_text_edit *state, int where, int length)
+{
+ nk_textedit_createundo(&state->undo, where, 0, length);
+}
+
+NK_INTERN void
+nk_textedit_makeundo_delete(struct nk_text_edit *state, int where, int length)
+{
+ int i;
+ nk_rune *p = nk_textedit_createundo(&state->undo, where, length, 0);
+ if (p) {
+ for (i=0; i < length; ++i)
+ p[i] = nk_str_rune_at(&state->string, where+i);
+ }
+}
+
+NK_INTERN void
+nk_textedit_makeundo_replace(struct nk_text_edit *state, int where,
+ int old_length, int new_length)
+{
+ int i;
+ nk_rune *p = nk_textedit_createundo(&state->undo, where, old_length, new_length);
+ if (p) {
+ for (i=0; i < old_length; ++i)
+ p[i] = nk_str_rune_at(&state->string, where+i);
+ }
+}
+
+NK_INTERN void
+nk_textedit_clear_state(struct nk_text_edit *state, enum nk_text_edit_type type,
+ nk_plugin_filter filter)
+{
+ /* reset the state to default */
+ state->undo.undo_point = 0;
+ state->undo.undo_char_point = 0;
+ state->undo.redo_point = NK_TEXTEDIT_UNDOSTATECOUNT;
+ state->undo.redo_char_point = NK_TEXTEDIT_UNDOCHARCOUNT;
+ state->select_end = state->select_start = 0;
+ state->cursor = 0;
+ state->has_preferred_x = 0;
+ state->preferred_x = 0;
+ state->cursor_at_end_of_line = 0;
+ state->initialized = 1;
+ state->single_line = (unsigned char)(type == NK_TEXT_EDIT_SINGLE_LINE);
+ state->mode = NK_TEXT_EDIT_MODE_VIEW;
+ state->filter = filter;
+ state->scrollbar = nk_vec2(0,0);
+}
+
+NK_API void
+nk_textedit_init_fixed(struct nk_text_edit *state, void *memory, nk_size size)
+{
+ NK_ASSERT(state);
+ NK_ASSERT(memory);
+ if (!state || !memory || !size) return;
+ NK_MEMSET(state, 0, sizeof(struct nk_text_edit));
+ nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
+ nk_str_init_fixed(&state->string, memory, size);
+}
+
+NK_API void
+nk_textedit_init(struct nk_text_edit *state, struct nk_allocator *alloc, nk_size size)
+{
+ NK_ASSERT(state);
+ NK_ASSERT(alloc);
+ if (!state || !alloc) return;
+ NK_MEMSET(state, 0, sizeof(struct nk_text_edit));
+ nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
+ nk_str_init(&state->string, alloc, size);
+}
+
+#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
+NK_API void
+nk_textedit_init_default(struct nk_text_edit *state)
+{
+ NK_ASSERT(state);
+ if (!state) return;
+ NK_MEMSET(state, 0, sizeof(struct nk_text_edit));
+ nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0);
+ nk_str_init_default(&state->string);
+}
+#endif
+
+NK_API void
+nk_textedit_select_all(struct nk_text_edit *state)
+{
+ NK_ASSERT(state);
+ state->select_start = 0;
+ state->select_end = state->string.len;
+}
+
+NK_API void
+nk_textedit_free(struct nk_text_edit *state)
+{
+ NK_ASSERT(state);
+ if (!state) return;
+ nk_str_free(&state->string);
+}
+
+/* ===============================================================
+ *
+ * TEXT WIDGET
+ *
+ * ===============================================================*/
+#define nk_widget_state_reset(s)\
+ if ((*(s)) & NK_WIDGET_STATE_MODIFIED)\
+ (*(s)) = NK_WIDGET_STATE_INACTIVE|NK_WIDGET_STATE_MODIFIED;\
+ else (*(s)) = NK_WIDGET_STATE_INACTIVE;
+
+struct nk_text {
+ struct nk_vec2 padding;
+ struct nk_color background;
+ struct nk_color text;
+};
+
+NK_INTERN void
+nk_widget_text(struct nk_command_buffer *o, struct nk_rect b,
+ const char *string, int len, const struct nk_text *t,
+ nk_flags a, const struct nk_user_font *f)
+{
+ struct nk_rect label;
+ float text_width;
+
+ NK_ASSERT(o);
+ NK_ASSERT(t);
+ if (!o || !t) return;
+
+ b.h = NK_MAX(b.h, 2 * t->padding.y);
+ label.x = 0; label.w = 0;
+ label.y = b.y + t->padding.y;
+ label.h = NK_MIN(f->height, b.h - 2 * t->padding.y);
+
+ text_width = f->width(f->userdata, f->height, (const char*)string, len);
+ text_width += (2.0f * t->padding.x);
+
+ /* align in x-axis */
+ if (a & NK_TEXT_ALIGN_LEFT) {
+ label.x = b.x + t->padding.x;
+ label.w = NK_MAX(0, b.w - 2 * t->padding.x);
+ } else if (a & NK_TEXT_ALIGN_CENTERED) {
+ label.w = NK_MAX(1, 2 * t->padding.x + (float)text_width);
+ label.x = (b.x + t->padding.x + ((b.w - 2 * t->padding.x) - label.w) / 2);
+ label.x = NK_MAX(b.x + t->padding.x, label.x);
+ label.w = NK_MIN(b.x + b.w, label.x + label.w);
+ if (label.w >= label.x) label.w -= label.x;
+ } else if (a & NK_TEXT_ALIGN_RIGHT) {
+ label.x = NK_MAX(b.x + t->padding.x, (b.x + b.w) - (2 * t->padding.x + (float)text_width));
+ label.w = (float)text_width + 2 * t->padding.x;
+ } else return;
+
+ /* align in y-axis */
+ if (a & NK_TEXT_ALIGN_MIDDLE) {
+ label.y = b.y + b.h/2.0f - (float)f->height/2.0f;
+ label.h = NK_MAX(b.h/2.0f, b.h - (b.h/2.0f + f->height/2.0f));
+ } else if (a & NK_TEXT_ALIGN_BOTTOM) {
+ label.y = b.y + b.h - f->height;
+ label.h = f->height;
+ }
+ nk_draw_text(o, label, (const char*)string,
+ len, f, t->background, t->text);
+}
+
+NK_INTERN void
+nk_widget_text_wrap(struct nk_command_buffer *o, struct nk_rect b,
+ const char *string, int len, const struct nk_text *t,
+ const struct nk_user_font *f)
+{
+ float width;
+ int glyphs = 0;
+ int fitting = 0;
+ int done = 0;
+ struct nk_rect line;
+ struct nk_text text;
+ NK_INTERN nk_rune seperator[] = {' '};
+
+ NK_ASSERT(o);
+ NK_ASSERT(t);
+ if (!o || !t) return;
+
+ text.padding = nk_vec2(0,0);
+ text.background = t->background;
+ text.text = t->text;
+
+ b.w = NK_MAX(b.w, 2 * t->padding.x);
+ b.h = NK_MAX(b.h, 2 * t->padding.y);
+ b.h = b.h - 2 * t->padding.y;
+
+ line.x = b.x + t->padding.x;
+ line.y = b.y + t->padding.y;
+ line.w = b.w - 2 * t->padding.x;
+ line.h = 2 * t->padding.y + f->height;
+
+ fitting = nk_text_clamp(f, string, len, line.w, &glyphs, &width, seperator,NK_LEN(seperator));
+ while (done < len) {
+ if (!fitting || line.y + line.h >= (b.y + b.h)) break;
+ nk_widget_text(o, line, &string[done], fitting, &text, NK_TEXT_LEFT, f);
+ done += fitting;
+ line.y += f->height + 2 * t->padding.y;
+ fitting = nk_text_clamp(f, &string[done], len - done, line.w, &glyphs, &width, seperator,NK_LEN(seperator));
+ }
+}
+
+/* ===============================================================
+ *
+ * BUTTON
+ *
+ * ===============================================================*/
+NK_INTERN void
+nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type,
+ struct nk_rect content, struct nk_color background, struct nk_color foreground,
+ float border_width, const struct nk_user_font *font)
+{
+ switch (type) {
+ case NK_SYMBOL_X:
+ case NK_SYMBOL_UNDERSCORE:
+ case NK_SYMBOL_PLUS:
+ case NK_SYMBOL_MINUS: {
+ /* single character text symbol */
+ const char *X = (type == NK_SYMBOL_X) ? "x":
+ (type == NK_SYMBOL_UNDERSCORE) ? "_":
+ (type == NK_SYMBOL_PLUS) ? "+": "-";
+ struct nk_text text;
+ text.padding = nk_vec2(0,0);
+ text.background = background;
+ text.text = foreground;
+ nk_widget_text(out, content, X, 1, &text, NK_TEXT_CENTERED, font);
+ } break;
+ case NK_SYMBOL_CIRCLE_SOLID:
+ case NK_SYMBOL_CIRCLE_OUTLINE:
+ case NK_SYMBOL_RECT_SOLID:
+ case NK_SYMBOL_RECT_OUTLINE: {
+ /* simple empty/filled shapes */
+ if (type == NK_SYMBOL_RECT_SOLID || type == NK_SYMBOL_RECT_OUTLINE) {
+ nk_fill_rect(out, content, 0, foreground);
+ if (type == NK_SYMBOL_RECT_OUTLINE)
+ nk_fill_rect(out, nk_shrink_rect(content, border_width), 0, background);
+ } else {
+ nk_fill_circle(out, content, foreground);
+ if (type == NK_SYMBOL_CIRCLE_OUTLINE)
+ nk_fill_circle(out, nk_shrink_rect(content, 1), background);
+ }
+ } break;
+ case NK_SYMBOL_TRIANGLE_UP:
+ case NK_SYMBOL_TRIANGLE_DOWN:
+ case NK_SYMBOL_TRIANGLE_LEFT:
+ case NK_SYMBOL_TRIANGLE_RIGHT: {
+ enum nk_heading heading;
+ struct nk_vec2 points[3];
+ heading = (type == NK_SYMBOL_TRIANGLE_RIGHT) ? NK_RIGHT :
+ (type == NK_SYMBOL_TRIANGLE_LEFT) ? NK_LEFT:
+ (type == NK_SYMBOL_TRIANGLE_UP) ? NK_UP: NK_DOWN;
+ nk_triangle_from_direction(points, content, 0, 0, heading);
+ nk_fill_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y,
+ points[2].x, points[2].y, foreground);
+ } break;
+ default:
+ case NK_SYMBOL_NONE:
+ case NK_SYMBOL_MAX: break;
+ }
+}
+
+NK_INTERN int
+nk_button_behavior(nk_flags *state, struct nk_rect r,
+ const struct nk_input *i, enum nk_button_behavior behavior)
+{
+ int ret = 0;
+ nk_widget_state_reset(state);
+ if (!i) return 0;
+ if (nk_input_is_mouse_hovering_rect(i, r)) {
+ *state = NK_WIDGET_STATE_HOVERED;
+ if (nk_input_is_mouse_down(i, NK_BUTTON_LEFT))
+ *state = NK_WIDGET_STATE_ACTIVE;
+ if (nk_input_has_mouse_click_in_rect(i, NK_BUTTON_LEFT, r)) {
+ ret = (behavior != NK_BUTTON_DEFAULT) ?
+ nk_input_is_mouse_down(i, NK_BUTTON_LEFT):
+#ifdef NK_BUTTON_TRIGGER_ON_RELEASE
+ nk_input_is_mouse_released(i, NK_BUTTON_LEFT);
+#else
+ nk_input_is_mouse_pressed(i, NK_BUTTON_LEFT);
+#endif
+ }
+ }
+ if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(i, r))
+ *state |= NK_WIDGET_STATE_ENTERED;
+ else if (nk_input_is_mouse_prev_hovering_rect(i, r))
+ *state |= NK_WIDGET_STATE_LEFT;
+ return ret;
+}
+
+NK_INTERN const struct nk_style_item*
+nk_draw_button(struct nk_command_buffer *out,
+ const struct nk_rect *bounds, nk_flags state,
+ const struct nk_style_button *style)
+{
+ const struct nk_style_item *background;
+ if (state & NK_WIDGET_STATE_HOVER)
+ background = &style->hover;
+ else if (state & NK_WIDGET_STATE_ACTIVED)
+ background = &style->active;
+ else background = &style->normal;
+
+ if (background->type == NK_STYLE_ITEM_IMAGE) {
+ nk_draw_image(out, *bounds, &background->data.image, nk_white);
+ } else {
+ nk_fill_rect(out, *bounds, style->rounding, background->data.color);
+ nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
+ }
+ return background;
+}
+
+NK_INTERN int
+nk_do_button(nk_flags *state, struct nk_command_buffer *out, struct nk_rect r,
+ const struct nk_style_button *style, const struct nk_input *in,
+ enum nk_button_behavior behavior, struct nk_rect *content)
+{
+ struct nk_rect bounds;
+ NK_ASSERT(style);
+ NK_ASSERT(state);
+ NK_ASSERT(out);
+ if (!out || !style)
+ return nk_false;
+
+ /* calculate button content space */
+ content->x = r.x + style->padding.x + style->border + style->rounding;
+ content->y = r.y + style->padding.y + style->border + style->rounding;
+ content->w = r.w - (2 * style->padding.x + style->border + style->rounding*2);
+ content->h = r.h - (2 * style->padding.y + style->border + style->rounding*2);
+
+ /* execute button behavior */
+ bounds.x = r.x - style->touch_padding.x;
+ bounds.y = r.y - style->touch_padding.y;
+ bounds.w = r.w + 2 * style->touch_padding.x;
+ bounds.h = r.h + 2 * style->touch_padding.y;
+ return nk_button_behavior(state, bounds, in, behavior);
+}
+
+NK_INTERN void
+nk_draw_button_text(struct nk_command_buffer *out,
+ const struct nk_rect *bounds, const struct nk_rect *content, nk_flags state,
+ const struct nk_style_button *style, const char *txt, int len,
+ nk_flags text_alignment, const struct nk_user_font *font)
+{
+ struct nk_text text;
+ const struct nk_style_item *background;
+ background = nk_draw_button(out, bounds, state, style);
+
+ /* select correct colors/images */
+ if (background->type == NK_STYLE_ITEM_COLOR)
+ text.background = background->data.color;
+ else text.background = style->text_background;
+ if (state & NK_WIDGET_STATE_HOVER)
+ text.text = style->text_hover;
+ else if (state & NK_WIDGET_STATE_ACTIVED)
+ text.text = style->text_active;
+ else text.text = style->text_normal;
+
+ text.padding = nk_vec2(0,0);
+ nk_widget_text(out, *content, txt, len, &text, text_alignment, font);
+}
+
+NK_INTERN int
+nk_do_button_text(nk_flags *state,
+ struct nk_command_buffer *out, struct nk_rect bounds,
+ const char *string, int len, nk_flags align, enum nk_button_behavior behavior,
+ const struct nk_style_button *style, const struct nk_input *in,
+ const struct nk_user_font *font)
+{
+ struct nk_rect content;
+ int ret = nk_false;
+
+ NK_ASSERT(state);
+ NK_ASSERT(style);
+ NK_ASSERT(out);
+ NK_ASSERT(string);
+ NK_ASSERT(font);
+ if (!out || !style || !font || !string)
+ return nk_false;
+
+ ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
+ if (style->draw_begin) style->draw_begin(out, style->userdata);
+ nk_draw_button_text(out, &bounds, &content, *state, style, string, len, align, font);
+ if (style->draw_end) style->draw_end(out, style->userdata);
+ return ret;
+}
+
+NK_INTERN void
+nk_draw_button_symbol(struct nk_command_buffer *out,
+ const struct nk_rect *bounds, const struct nk_rect *content,
+ nk_flags state, const struct nk_style_button *style,
+ enum nk_symbol_type type, const struct nk_user_font *font)
+{
+ struct nk_color sym, bg;
+ const struct nk_style_item *background;
+
+ /* select correct colors/images */
+ background = nk_draw_button(out, bounds, state, style);
+ if (background->type == NK_STYLE_ITEM_COLOR)
+ bg = background->data.color;
+ else bg = style->text_background;
+
+ if (state & NK_WIDGET_STATE_HOVER)
+ sym = style->text_hover;
+ else if (state & NK_WIDGET_STATE_ACTIVED)
+ sym = style->text_active;
+ else sym = style->text_normal;
+ nk_draw_symbol(out, type, *content, bg, sym, 1, font);
+}
+
+NK_INTERN int
+nk_do_button_symbol(nk_flags *state,
+ struct nk_command_buffer *out, struct nk_rect bounds,
+ enum nk_symbol_type symbol, enum nk_button_behavior behavior,
+ const struct nk_style_button *style, const struct nk_input *in,
+ const struct nk_user_font *font)
+{
+ int ret;
+ struct nk_rect content;
+
+ NK_ASSERT(state);
+ NK_ASSERT(style);
+ NK_ASSERT(font);
+ NK_ASSERT(out);
+ if (!out || !style || !font || !state)
+ return nk_false;
+
+ ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
+ if (style->draw_begin) style->draw_begin(out, style->userdata);
+ nk_draw_button_symbol(out, &bounds, &content, *state, style, symbol, font);
+ if (style->draw_end) style->draw_end(out, style->userdata);
+ return ret;
+}
+
+NK_INTERN void
+nk_draw_button_image(struct nk_command_buffer *out,
+ const struct nk_rect *bounds, const struct nk_rect *content,
+ nk_flags state, const struct nk_style_button *style, const struct nk_image *img)
+{
+ nk_draw_button(out, bounds, state, style);
+ nk_draw_image(out, *content, img, nk_white);
+}
+
+NK_INTERN int
+nk_do_button_image(nk_flags *state,
+ struct nk_command_buffer *out, struct nk_rect bounds,
+ struct nk_image img, enum nk_button_behavior b,
+ const struct nk_style_button *style, const struct nk_input *in)
+{
+ int ret;
+ struct nk_rect content;
+
+ NK_ASSERT(state);
+ NK_ASSERT(style);
+ NK_ASSERT(out);
+ if (!out || !style || !state)
+ return nk_false;
+
+ ret = nk_do_button(state, out, bounds, style, in, b, &content);
+ content.x += style->image_padding.x;
+ content.y += style->image_padding.y;
+ content.w -= 2 * style->image_padding.x;
+ content.h -= 2 * style->image_padding.y;
+
+ if (style->draw_begin) style->draw_begin(out, style->userdata);
+ nk_draw_button_image(out, &bounds, &content, *state, style, &img);
+ if (style->draw_end) style->draw_end(out, style->userdata);
+ return ret;
+}
+
+NK_INTERN void
+nk_draw_button_text_symbol(struct nk_command_buffer *out,
+ const struct nk_rect *bounds, const struct nk_rect *label,
+ const struct nk_rect *symbol, nk_flags state, const struct nk_style_button *style,
+ const char *str, int len, enum nk_symbol_type type,
+ const struct nk_user_font *font)
+{
+ struct nk_color sym;
+ struct nk_text text;
+ const struct nk_style_item *background;
+
+ /* select correct background colors/images */
+ background = nk_draw_button(out, bounds, state, style);
+ if (background->type == NK_STYLE_ITEM_COLOR)
+ text.background = background->data.color;
+ else text.background = style->text_background;
+
+ /* select correct text colors */
+ if (state & NK_WIDGET_STATE_HOVER) {
+ sym = style->text_hover;
+ text.text = style->text_hover;
+ } else if (state & NK_WIDGET_STATE_ACTIVED) {
+ sym = style->text_active;
+ text.text = style->text_active;
+ } else {
+ sym = style->text_normal;
+ text.text = style->text_normal;
+ }
+
+ text.padding = nk_vec2(0,0);
+ nk_draw_symbol(out, type, *symbol, style->text_background, sym, 0, font);
+ nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font);
+}
+
+NK_INTERN int
+nk_do_button_text_symbol(nk_flags *state,
+ struct nk_command_buffer *out, struct nk_rect bounds,
+ enum nk_symbol_type symbol, const char *str, int len, nk_flags align,
+ enum nk_button_behavior behavior, const struct nk_style_button *style,
+ const struct nk_user_font *font, const struct nk_input *in)
+{
+ int ret;
+ struct nk_rect tri = {0,0,0,0};
+ struct nk_rect content;
+
+ NK_ASSERT(style);
+ NK_ASSERT(out);
+ NK_ASSERT(font);
+ if (!out || !style || !font)
+ return nk_false;
+
+ ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
+ tri.y = content.y + (content.h/2) - font->height/2;
+ tri.w = font->height; tri.h = font->height;
+ if (align & NK_TEXT_ALIGN_LEFT) {
+ tri.x = (content.x + content.w) - (2 * style->padding.x + tri.w);
+ tri.x = NK_MAX(tri.x, 0);
+ } else tri.x = content.x + 2 * style->padding.x;
+
+ /* draw button */
+ if (style->draw_begin) style->draw_begin(out, style->userdata);
+ nk_draw_button_text_symbol(out, &bounds, &content, &tri,
+ *state, style, str, len, symbol, font);
+ if (style->draw_end) style->draw_end(out, style->userdata);
+ return ret;
+}
+
+NK_INTERN void
+nk_draw_button_text_image(struct nk_command_buffer *out,
+ const struct nk_rect *bounds, const struct nk_rect *label,
+ const struct nk_rect *image, nk_flags state, const struct nk_style_button *style,
+ const char *str, int len, const struct nk_user_font *font,
+ const struct nk_image *img)
+{
+ struct nk_text text;
+ const struct nk_style_item *background;
+ background = nk_draw_button(out, bounds, state, style);
+
+ /* select correct colors */
+ if (background->type == NK_STYLE_ITEM_COLOR)
+ text.background = background->data.color;
+ else text.background = style->text_background;
+ if (state & NK_WIDGET_STATE_HOVER)
+ text.text = style->text_hover;
+ else if (state & NK_WIDGET_STATE_ACTIVED)
+ text.text = style->text_active;
+ else text.text = style->text_normal;
+
+ text.padding = nk_vec2(0,0);
+ nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font);
+ nk_draw_image(out, *image, img, nk_white);
+}
+
+NK_INTERN int
+nk_do_button_text_image(nk_flags *state,
+ struct nk_command_buffer *out, struct nk_rect bounds,
+ struct nk_image img, const char* str, int len, nk_flags align,
+ enum nk_button_behavior behavior, const struct nk_style_button *style,
+ const struct nk_user_font *font, const struct nk_input *in)
+{
+ int ret;
+ struct nk_rect icon;
+ struct nk_rect content;
+
+ NK_ASSERT(style);
+ NK_ASSERT(state);
+ NK_ASSERT(font);
+ NK_ASSERT(out);
+ if (!out || !font || !style || !str)
+ return nk_false;
+
+ ret = nk_do_button(state, out, bounds, style, in, behavior, &content);
+ icon.y = bounds.y + style->padding.y;
+ icon.w = icon.h = bounds.h - 2 * style->padding.y;
+ if (align & NK_TEXT_ALIGN_LEFT) {
+ icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
+ icon.x = NK_MAX(icon.x, 0);
+ } else icon.x = bounds.x + 2 * style->padding.x;
+
+ icon.x += style->image_padding.x;
+ icon.y += style->image_padding.y;
+ icon.w -= 2 * style->image_padding.x;
+ icon.h -= 2 * style->image_padding.y;
+
+ if (style->draw_begin) style->draw_begin(out, style->userdata);
+ nk_draw_button_text_image(out, &bounds, &content, &icon, *state, style, str, len, font, &img);
+ if (style->draw_end) style->draw_end(out, style->userdata);
+ return ret;
+}
+
+/* ===============================================================
+ *
+ * TOGGLE
+ *
+ * ===============================================================*/
+enum nk_toggle_type {
+ NK_TOGGLE_CHECK,
+ NK_TOGGLE_OPTION
+};
+
+NK_INTERN int
+nk_toggle_behavior(const struct nk_input *in, struct nk_rect select,
+ nk_flags *state, int active)
+{
+ nk_widget_state_reset(state);
+ if (nk_button_behavior(state, select, in, NK_BUTTON_DEFAULT)) {
+ *state = NK_WIDGET_STATE_ACTIVE;
+ active = !active;
+ }
+ if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, select))
+ *state |= NK_WIDGET_STATE_ENTERED;
+ else if (nk_input_is_mouse_prev_hovering_rect(in, select))
+ *state |= NK_WIDGET_STATE_LEFT;
+ return active;
+}
+
+NK_INTERN void
+nk_draw_checkbox(struct nk_command_buffer *out,
+ nk_flags state, const struct nk_style_toggle *style, int active,
+ const struct nk_rect *label, const struct nk_rect *selector,
+ const struct nk_rect *cursors, const char *string, int len,
+ const struct nk_user_font *font)
+{
+ const struct nk_style_item *background;
+ const struct nk_style_item *cursor;
+ struct nk_text text;
+
+ /* select correct colors/images */
+ if (state & NK_WIDGET_STATE_HOVER) {
+ background = &style->hover;
+ cursor = &style->cursor_hover;
+ text.text = style->text_hover;
+ } else if (state & NK_WIDGET_STATE_ACTIVED) {
+ background = &style->hover;
+ cursor = &style->cursor_hover;
+ text.text = style->text_active;
+ } else {
+ background = &style->normal;
+ cursor = &style->cursor_normal;
+ text.text = style->text_normal;
+ }
+
+ /* draw background and cursor */
+ if (background->type == NK_STYLE_ITEM_COLOR) {
+ nk_fill_rect(out, *selector, 0, style->border_color);
+ nk_fill_rect(out, nk_shrink_rect(*selector, style->border), 0, background->data.color);
+ } else nk_draw_image(out, *selector, &background->data.image, nk_white);
+ if (active) {
+ if (cursor->type == NK_STYLE_ITEM_IMAGE)
+ nk_draw_image(out, *cursors, &cursor->data.image, nk_white);
+ else nk_fill_rect(out, *cursors, 0, cursor->data.color);
+ }
+
+ text.padding.x = 0;
+ text.padding.y = 0;
+ text.background = style->text_background;
+ nk_widget_text(out, *label, string, len, &text, NK_TEXT_LEFT, font);
+}
+
+NK_INTERN void
+nk_draw_option(struct nk_command_buffer *out,
+ nk_flags state, const struct nk_style_toggle *style, int active,
+ const struct nk_rect *label, const struct nk_rect *selector,
+ const struct nk_rect *cursors, const char *string, int len,
+ const struct nk_user_font *font)
+{
+ const struct nk_style_item *background;
+ const struct nk_style_item *cursor;
+ struct nk_text text;
+
+ /* select correct colors/images */
+ if (state & NK_WIDGET_STATE_HOVER) {
+ background = &style->hover;
+ cursor = &style->cursor_hover;
+ text.text = style->text_hover;
+ } else if (state & NK_WIDGET_STATE_ACTIVED) {
+ background = &style->hover;
+ cursor = &style->cursor_hover;
+ text.text = style->text_active;
+ } else {
+ background = &style->normal;
+ cursor = &style->cursor_normal;
+ text.text = style->text_normal;
+ }
+
+ /* draw background and cursor */
+ if (background->type == NK_STYLE_ITEM_COLOR) {
+ nk_fill_circle(out, *selector, style->border_color);
+ nk_fill_circle(out, nk_shrink_rect(*selector, style->border), background->data.color);
+ } else nk_draw_image(out, *selector, &background->data.image, nk_white);
+ if (active) {
+ if (cursor->type == NK_STYLE_ITEM_IMAGE)
+ nk_draw_image(out, *cursors, &cursor->data.image, nk_white);
+ else nk_fill_circle(out, *cursors, cursor->data.color);
+ }
+
+ text.padding.x = 0;
+ text.padding.y = 0;
+ text.background = style->text_background;
+ nk_widget_text(out, *label, string, len, &text, NK_TEXT_LEFT, font);
+}
+
+NK_INTERN int
+nk_do_toggle(nk_flags *state,
+ struct nk_command_buffer *out, struct nk_rect r,
+ int *active, const char *str, int len, enum nk_toggle_type type,
+ const struct nk_style_toggle *style, const struct nk_input *in,
+ const struct nk_user_font *font)
+{
+ int was_active;
+ struct nk_rect bounds;
+ struct nk_rect select;
+ struct nk_rect cursor;
+ struct nk_rect label;
+
+ NK_ASSERT(style);
+ NK_ASSERT(out);
+ NK_ASSERT(font);
+ if (!out || !style || !font || !active)
+ return 0;
+
+ r.w = NK_MAX(r.w, font->height + 2 * style->padding.x);
+ r.h = NK_MAX(r.h, font->height + 2 * style->padding.y);
+
+ /* add additional touch padding for touch screen devices */
+ bounds.x = r.x - style->touch_padding.x;
+ bounds.y = r.y - style->touch_padding.y;
+ bounds.w = r.w + 2 * style->touch_padding.x;
+ bounds.h = r.h + 2 * style->touch_padding.y;
+
+ /* calculate the selector space */
+ select.w = font->height;
+ select.h = select.w;
+ select.y = r.y + r.h/2.0f - select.h/2.0f;
+ select.x = r.x;
+
+ /* calculate the bounds of the cursor inside the selector */
+ cursor.x = select.x + style->padding.x + style->border;
+ cursor.y = select.y + style->padding.y + style->border;
+ cursor.w = select.w - (2 * style->padding.x + 2 * style->border);
+ cursor.h = select.h - (2 * style->padding.y + 2 * style->border);
+
+ /* label behind the selector */
+ label.x = select.x + select.w + style->spacing;
+ label.y = select.y;
+ label.w = NK_MAX(r.x + r.w, label.x) - label.x;
+ label.h = select.w;
+
+ /* update selector */
+ was_active = *active;
+ *active = nk_toggle_behavior(in, bounds, state, *active);
+
+ /* draw selector */
+ if (style->draw_begin)
+ style->draw_begin(out, style->userdata);
+ if (type == NK_TOGGLE_CHECK) {
+ nk_draw_checkbox(out, *state, style, *active, &label, &select, &cursor, str, len, font);
+ } else {
+ nk_draw_option(out, *state, style, *active, &label, &select, &cursor, str, len, font);
+ }
+ if (style->draw_end)
+ style->draw_end(out, style->userdata);
+ return (was_active != *active);
+}
+
+/* ===============================================================
+ *
+ * SELECTABLE
+ *
+ * ===============================================================*/
+NK_INTERN void
+nk_draw_selectable(struct nk_command_buffer *out,
+ nk_flags state, const struct nk_style_selectable *style, int active,
+ const struct nk_rect *bounds, const struct nk_rect *icon, const struct nk_image *img,
+ const char *string, int len, nk_flags align, const struct nk_user_font *font)
+{
+ const struct nk_style_item *background;
+ struct nk_text text;
+ text.padding = style->padding;
+
+ /* select correct colors/images */
+ if (!active) {
+ if (state & NK_WIDGET_STATE_ACTIVED) {
+ background = &style->pressed;
+ text.text = style->text_pressed;
+ } else if (state & NK_WIDGET_STATE_HOVER) {
+ background = &style->hover;
+ text.text = style->text_hover;
+ } else {
+ background = &style->normal;
+ text.text = style->text_normal;
+ }
+ } else {
+ if (state & NK_WIDGET_STATE_ACTIVED) {
+ background = &style->pressed_active;
+ text.text = style->text_pressed_active;
+ } else if (state & NK_WIDGET_STATE_HOVER) {
+ background = &style->hover_active;
+ text.text = style->text_hover_active;
+ } else {
+ background = &style->normal_active;
+ text.text = style->text_normal_active;
+ }
+ }
+
+
+ /* draw selectable background and text */
+ if (background->type == NK_STYLE_ITEM_IMAGE) {
+ nk_draw_image(out, *bounds, &background->data.image, nk_white);
+ text.background = nk_rgba(0,0,0,0);
+ } else {
+ nk_fill_rect(out, *bounds, style->rounding, background->data.color);
+ text.background = background->data.color;
+ }
+ if (img && icon) nk_draw_image(out, *icon, img, nk_white);
+ nk_widget_text(out, *bounds, string, len, &text, align, font);
+}
+
+NK_INTERN int
+nk_do_selectable(nk_flags *state, struct nk_command_buffer *out,
+ struct nk_rect bounds, const char *str, int len, nk_flags align, int *value,
+ const struct nk_style_selectable *style, const struct nk_input *in,
+ const struct nk_user_font *font)
+{
+ int old_value;
+ struct nk_rect touch;
+
+ NK_ASSERT(state);
+ NK_ASSERT(out);
+ NK_ASSERT(str);
+ NK_ASSERT(len);
+ NK_ASSERT(value);
+ NK_ASSERT(style);
+ NK_ASSERT(font);
+
+ if (!state || !out || !str || !len || !value || !style || !font) return 0;
+ old_value = *value;
+
+ /* remove padding */
+ touch.x = bounds.x - style->touch_padding.x;
+ touch.y = bounds.y - style->touch_padding.y;
+ touch.w = bounds.w + style->touch_padding.x * 2;
+ touch.h = bounds.h + style->touch_padding.y * 2;
+
+ /* update button */
+ if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
+ *value = !(*value);
+
+ /* draw selectable */
+ if (style->draw_begin) style->draw_begin(out, style->userdata);
+ nk_draw_selectable(out, *state, style, *value, &bounds, 0,0, str, len, align, font);
+ if (style->draw_end) style->draw_end(out, style->userdata);
+ return old_value != *value;
+}
+
+NK_INTERN int
+nk_do_selectable_image(nk_flags *state, struct nk_command_buffer *out,
+ struct nk_rect bounds, const char *str, int len, nk_flags align, int *value,
+ const struct nk_image *img, const struct nk_style_selectable *style,
+ const struct nk_input *in, const struct nk_user_font *font)
+{
+ int old_value;
+ struct nk_rect touch;
+ struct nk_rect icon;
+
+ NK_ASSERT(state);
+ NK_ASSERT(out);
+ NK_ASSERT(str);
+ NK_ASSERT(len);
+ NK_ASSERT(value);
+ NK_ASSERT(style);
+ NK_ASSERT(font);
+
+ if (!state || !out || !str || !len || !value || !style || !font) return 0;
+ old_value = *value;
+
+ /* toggle behavior */
+ touch.x = bounds.x - style->touch_padding.x;
+ touch.y = bounds.y - style->touch_padding.y;
+ touch.w = bounds.w + style->touch_padding.x * 2;
+ touch.h = bounds.h + style->touch_padding.y * 2;
+ if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT))
+ *value = !(*value);
+
+ icon.y = bounds.y + style->padding.y;
+ icon.w = icon.h = bounds.h - 2 * style->padding.y;
+ if (align & NK_TEXT_ALIGN_LEFT) {
+ icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w);
+ icon.x = NK_MAX(icon.x, 0);
+ } else icon.x = bounds.x + 2 * style->padding.x;
+
+ icon.x += style->image_padding.x;
+ icon.y += style->image_padding.y;
+ icon.w -= 2 * style->image_padding.x;
+ icon.h -= 2 * style->image_padding.y;
+
+ /* draw selectable */
+ if (style->draw_begin) style->draw_begin(out, style->userdata);
+ nk_draw_selectable(out, *state, style, *value, &bounds, &icon, img, str, len, align, font);
+ if (style->draw_end) style->draw_end(out, style->userdata);
+ return old_value != *value;
+}
+
+
+/* ===============================================================
+ *
+ * SLIDER
+ *
+ * ===============================================================*/
+NK_INTERN float
+nk_slider_behavior(nk_flags *state, struct nk_rect *logical_cursor,
+ struct nk_rect *visual_cursor, struct nk_input *in,
+ struct nk_rect bounds, float slider_min, float slider_max, float slider_value,
+ float slider_step, float slider_steps)
+{
+ int left_mouse_down;
+ int left_mouse_click_in_cursor;
+
+ /* check if visual cursor is being dragged */
+ nk_widget_state_reset(state);
+ left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
+ left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in,
+ NK_BUTTON_LEFT, *visual_cursor, nk_true);
+
+ if (left_mouse_down && left_mouse_click_in_cursor) {
+ float ratio = 0;
+ const float d = in->mouse.pos.x - (visual_cursor->x+visual_cursor->w*0.5f);
+ const float pxstep = bounds.w / slider_steps;
+
+ /* only update value if the next slider step is reached */
+ *state = NK_WIDGET_STATE_ACTIVE;
+ if (NK_ABS(d) >= pxstep) {
+ const float steps = (float)((int)(NK_ABS(d) / pxstep));
+ slider_value += (d > 0) ? (slider_step*steps) : -(slider_step*steps);
+ slider_value = NK_CLAMP(slider_min, slider_value, slider_max);
+ ratio = (slider_value - slider_min)/slider_step;
+ logical_cursor->x = bounds.x + (logical_cursor->w * ratio);
+ in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = logical_cursor->x;
+ }
+ }
+
+ /* slider widget state */
+ if (nk_input_is_mouse_hovering_rect(in, bounds))
+ *state = NK_WIDGET_STATE_HOVERED;
+ if (*state & NK_WIDGET_STATE_HOVER &&
+ !nk_input_is_mouse_prev_hovering_rect(in, bounds))
+ *state |= NK_WIDGET_STATE_ENTERED;
+ else if (nk_input_is_mouse_prev_hovering_rect(in, bounds))
+ *state |= NK_WIDGET_STATE_LEFT;
+ return slider_value;
+}
+
+NK_INTERN void
+nk_draw_slider(struct nk_command_buffer *out, nk_flags state,
+ const struct nk_style_slider *style, const struct nk_rect *bounds,
+ const struct nk_rect *visual_cursor, float min, float value, float max)
+{
+ struct nk_rect fill;
+ struct nk_rect bar;
+ const struct nk_style_item *background;
+
+ /* select correct slider images/colors */
+ struct nk_color bar_color;
+ const struct nk_style_item *cursor;
+
+ NK_UNUSED(min);
+ NK_UNUSED(max);
+ NK_UNUSED(value);
+
+ if (state & NK_WIDGET_STATE_ACTIVED) {
+ background = &style->active;
+ bar_color = style->bar_active;
+ cursor = &style->cursor_active;
+ } else if (state & NK_WIDGET_STATE_HOVER) {
+ background = &style->hover;
+ bar_color = style->bar_hover;
+ cursor = &style->cursor_hover;
+ } else {
+ background = &style->normal;
+ bar_color = style->bar_normal;
+ cursor = &style->cursor_normal;
+ }
+
+ /* calculate slider background bar */
+ bar.x = bounds->x;
+ bar.y = (visual_cursor->y + visual_cursor->h/2) - bounds->h/12;
+ bar.w = bounds->w;
+ bar.h = bounds->h/6;
+
+ /* filled background bar style */
+ fill.w = (visual_cursor->x + (visual_cursor->w/2.0f)) - bar.x;
+ fill.x = bar.x;
+ fill.y = bar.y;
+ fill.h = bar.h;
+
+ /* draw background */
+ if (background->type == NK_STYLE_ITEM_IMAGE) {
+ nk_draw_image(out, *bounds, &background->data.image, nk_white);
+ } else {
+ nk_fill_rect(out, *bounds, style->rounding, background->data.color);
+ nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
+ }
+
+ /* draw slider bar */
+ nk_fill_rect(out, bar, style->rounding, bar_color);
+ nk_fill_rect(out, fill, style->rounding, style->bar_filled);
+
+ /* draw cursor */
+ if (cursor->type == NK_STYLE_ITEM_IMAGE)
+ nk_draw_image(out, *visual_cursor, &cursor->data.image, nk_white);
+ else nk_fill_circle(out, *visual_cursor, cursor->data.color);
+}
+
+NK_INTERN float
+nk_do_slider(nk_flags *state,
+ struct nk_command_buffer *out, struct nk_rect bounds,
+ float min, float val, float max, float step,
+ const struct nk_style_slider *style, struct nk_input *in,
+ const struct nk_user_font *font)
+{
+ float slider_range;
+ float slider_min;
+ float slider_max;
+ float slider_value;
+ float slider_steps;
+ float cursor_offset;
+
+ struct nk_rect visual_cursor;
+ struct nk_rect logical_cursor;
+
+ NK_ASSERT(style);
+ NK_ASSERT(out);
+ if (!out || !style)
+ return 0;
+
+ /* remove padding from slider bounds */
+ bounds.x = bounds.x + style->padding.x;
+ bounds.y = bounds.y + style->padding.y;
+ bounds.h = NK_MAX(bounds.h, 2*style->padding.y);
+ bounds.w = NK_MAX(bounds.w, 2*style->padding.x + style->cursor_size.x);
+ bounds.w -= 2 * style->padding.x;
+ bounds.h -= 2 * style->padding.y;
+
+ /* optional buttons */
+ if (style->show_buttons) {
+ nk_flags ws;
+ struct nk_rect button;
+ button.y = bounds.y;
+ button.w = bounds.h;
+ button.h = bounds.h;
+
+ /* decrement button */
+ button.x = bounds.x;
+ if (nk_do_button_symbol(&ws, out, button, style->dec_symbol, NK_BUTTON_DEFAULT,
+ &style->dec_button, in, font))
+ val -= step;
+
+ /* increment button */
+ button.x = (bounds.x + bounds.w) - button.w;
+ if (nk_do_button_symbol(&ws, out, button, style->inc_symbol, NK_BUTTON_DEFAULT,
+ &style->inc_button, in, font))
+ val += step;
+
+ bounds.x = bounds.x + button.w + style->spacing.x;
+ bounds.w = bounds.w - (2*button.w + 2*style->spacing.x);
+ }
+
+ /* remove one cursor size to support visual cursor */
+ bounds.x += style->cursor_size.x*0.5f;
+ bounds.w -= style->cursor_size.x;
+
+ /* make sure the provided values are correct */
+ slider_max = NK_MAX(min, max);
+ slider_min = NK_MIN(min, max);
+ slider_value = NK_CLAMP(slider_min, val, slider_max);
+ slider_range = slider_max - slider_min;
+ slider_steps = slider_range / step;
+ cursor_offset = (slider_value - slider_min) / step;
+
+ /* calculate cursor
+ Basically you have two cursors. One for visual representation and interaction
+ and one for updating the actual cursor value. */
+ logical_cursor.h = bounds.h;
+ logical_cursor.w = bounds.w / slider_steps;
+ logical_cursor.x = bounds.x + (logical_cursor.w * cursor_offset);
+ logical_cursor.y = bounds.y;
+
+ visual_cursor.h = style->cursor_size.y;
+ visual_cursor.w = style->cursor_size.x;
+ visual_cursor.y = (bounds.y + bounds.h*0.5f) - visual_cursor.h*0.5f;
+ visual_cursor.x = logical_cursor.x - visual_cursor.w*0.5f;
+
+ slider_value = nk_slider_behavior(state, &logical_cursor, &visual_cursor,
+ in, bounds, slider_min, slider_max, slider_value, step, slider_steps);
+ visual_cursor.x = logical_cursor.x - visual_cursor.w*0.5f;
+
+ /* draw slider */
+ if (style->draw_begin) style->draw_begin(out, style->userdata);
+ nk_draw_slider(out, *state, style, &bounds, &visual_cursor, slider_min, slider_value, slider_max);
+ if (style->draw_end) style->draw_end(out, style->userdata);
+ return slider_value;
+}
+
+/* ===============================================================
+ *
+ * PROGRESSBAR
+ *
+ * ===============================================================*/
+NK_INTERN nk_size
+nk_progress_behavior(nk_flags *state, struct nk_input *in,
+ struct nk_rect r, struct nk_rect cursor, nk_size max, nk_size value, int modifiable)
+{
+ int left_mouse_down = 0;
+ int left_mouse_click_in_cursor = 0;
+
+ nk_widget_state_reset(state);
+ if (!in || !modifiable) return value;
+ left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
+ left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in,
+ NK_BUTTON_LEFT, cursor, nk_true);
+ if (nk_input_is_mouse_hovering_rect(in, r))
+ *state = NK_WIDGET_STATE_HOVERED;
+
+ if (in && left_mouse_down && left_mouse_click_in_cursor) {
+ if (left_mouse_down && left_mouse_click_in_cursor) {
+ float ratio = NK_MAX(0, (float)(in->mouse.pos.x - cursor.x)) / (float)cursor.w;
+ value = (nk_size)NK_CLAMP(0, (float)max * ratio, (float)max);
+ in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor.x + cursor.w/2.0f;
+ *state |= NK_WIDGET_STATE_ACTIVE;
+ }
+ }
+ /* set progressbar widget state */
+ if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, r))
+ *state |= NK_WIDGET_STATE_ENTERED;
+ else if (nk_input_is_mouse_prev_hovering_rect(in, r))
+ *state |= NK_WIDGET_STATE_LEFT;
+ return value;
+}
+
+NK_INTERN void
+nk_draw_progress(struct nk_command_buffer *out, nk_flags state,
+ const struct nk_style_progress *style, const struct nk_rect *bounds,
+ const struct nk_rect *scursor, nk_size value, nk_size max)
+{
+ const struct nk_style_item *background;
+ const struct nk_style_item *cursor;
+
+ NK_UNUSED(max);
+ NK_UNUSED(value);
+
+ /* select correct colors/images to draw */
+ if (state & NK_WIDGET_STATE_ACTIVED) {
+ background = &style->active;
+ cursor = &style->cursor_active;
+ } else if (state & NK_WIDGET_STATE_HOVER){
+ background = &style->hover;
+ cursor = &style->cursor_hover;
+ } else {
+ background = &style->normal;
+ cursor = &style->cursor_normal;
+ }
+
+ /* draw background */
+ if (background->type == NK_STYLE_ITEM_COLOR) {
+ nk_fill_rect(out, *bounds, style->rounding, background->data.color);
+ nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
+ } else nk_draw_image(out, *bounds, &background->data.image, nk_white);
+
+ /* draw cursor */
+ if (cursor->type == NK_STYLE_ITEM_COLOR) {
+ nk_fill_rect(out, *scursor, style->rounding, cursor->data.color);
+ nk_stroke_rect(out, *scursor, style->rounding, style->border, style->border_color);
+ } else nk_draw_image(out, *scursor, &cursor->data.image, nk_white);
+}
+
+NK_INTERN nk_size
+nk_do_progress(nk_flags *state,
+ struct nk_command_buffer *out, struct nk_rect bounds,
+ nk_size value, nk_size max, int modifiable,
+ const struct nk_style_progress *style, struct nk_input *in)
+{
+ float prog_scale;
+ nk_size prog_value;
+ struct nk_rect cursor;
+
+ NK_ASSERT(style);
+ NK_ASSERT(out);
+ if (!out || !style) return 0;
+
+ /* calculate progressbar cursor */
+ cursor.w = NK_MAX(bounds.w, 2 * style->padding.x + 2 * style->border);
+ cursor.h = NK_MAX(bounds.h, 2 * style->padding.y + 2 * style->border);
+ cursor = nk_pad_rect(bounds, nk_vec2(style->padding.x + style->border, style->padding.y + style->border));
+ prog_scale = (float)value / (float)max;
+
+ /* update progressbar */
+ prog_value = NK_MIN(value, max);
+ prog_value = nk_progress_behavior(state, in, bounds, cursor,max, prog_value, modifiable);
+ cursor.w = cursor.w * prog_scale;
+
+ /* draw progressbar */
+ if (style->draw_begin) style->draw_begin(out, style->userdata);
+ nk_draw_progress(out, *state, style, &bounds, &cursor, value, max);
+ if (style->draw_end) style->draw_end(out, style->userdata);
+ return prog_value;
+}
+
+/* ===============================================================
+ *
+ * SCROLLBAR
+ *
+ * ===============================================================*/
+NK_INTERN float
+nk_scrollbar_behavior(nk_flags *state, struct nk_input *in,
+ int has_scrolling, const struct nk_rect *scroll,
+ const struct nk_rect *cursor, const struct nk_rect *empty0,
+ const struct nk_rect *empty1, float scroll_offset,
+ float target, float scroll_step, enum nk_orientation o)
+{
+ nk_flags ws = 0;
+ int left_mouse_down;
+ int left_mouse_click_in_cursor;
+ float scroll_delta;
+
+ nk_widget_state_reset(state);
+ if (!in) return scroll_offset;
+
+ left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
+ left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in,
+ NK_BUTTON_LEFT, *cursor, nk_true);
+ if (nk_input_is_mouse_hovering_rect(in, *scroll))
+ *state = NK_WIDGET_STATE_HOVERED;
+
+ scroll_delta = (o == NK_VERTICAL) ? in->mouse.scroll_delta.y: in->mouse.scroll_delta.x;
+ if (left_mouse_down && left_mouse_click_in_cursor) {
+ /* update cursor by mouse dragging */
+ float pixel, delta;
+ *state = NK_WIDGET_STATE_ACTIVE;
+ if (o == NK_VERTICAL) {
+ float cursor_y;
+ pixel = in->mouse.delta.y;
+ delta = (pixel / scroll->h) * target;
+ scroll_offset = NK_CLAMP(0, scroll_offset + delta, target - scroll->h);
+ cursor_y = scroll->y + ((scroll_offset/target) * scroll->h);
+ in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = cursor_y + cursor->h/2.0f;
+ } else {
+ float cursor_x;
+ pixel = in->mouse.delta.x;
+ delta = (pixel / scroll->w) * target;
+ scroll_offset = NK_CLAMP(0, scroll_offset + delta, target - scroll->w);
+ cursor_x = scroll->x + ((scroll_offset/target) * scroll->w);
+ in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor_x + cursor->w/2.0f;
+ }
+ } else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_UP) && o == NK_VERTICAL && has_scrolling)||
+ nk_button_behavior(&ws, *empty0, in, NK_BUTTON_DEFAULT)) {
+ /* scroll page up by click on empty space or shortcut */
+ if (o == NK_VERTICAL)
+ scroll_offset = NK_MAX(0, scroll_offset - scroll->h);
+ else scroll_offset = NK_MAX(0, scroll_offset - scroll->w);
+ } else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_DOWN) && o == NK_VERTICAL && has_scrolling) ||
+ nk_button_behavior(&ws, *empty1, in, NK_BUTTON_DEFAULT)) {
+ /* scroll page down by click on empty space or shortcut */
+ if (o == NK_VERTICAL)
+ scroll_offset = NK_MIN(scroll_offset + scroll->h, target - scroll->h);
+ else scroll_offset = NK_MIN(scroll_offset + scroll->w, target - scroll->w);
+ } else if (has_scrolling) {
+ if ((scroll_delta < 0 || (scroll_delta > 0))) {
+ /* update cursor by mouse scrolling */
+ scroll_offset = scroll_offset + scroll_step * (-scroll_delta);
+ if (o == NK_VERTICAL)
+ scroll_offset = NK_CLAMP(0, scroll_offset, target - scroll->h);
+ else scroll_offset = NK_CLAMP(0, scroll_offset, target - scroll->w);
+ } else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_START)) {
+ /* update cursor to the beginning */
+ if (o == NK_VERTICAL) scroll_offset = 0;
+ } else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_END)) {
+ /* update cursor to the end */
+ if (o == NK_VERTICAL) scroll_offset = target - scroll->h;
+ }
+ }
+ if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, *scroll))
+ *state |= NK_WIDGET_STATE_ENTERED;
+ else if (nk_input_is_mouse_prev_hovering_rect(in, *scroll))
+ *state |= NK_WIDGET_STATE_LEFT;
+ return scroll_offset;
+}
+
+NK_INTERN void
+nk_draw_scrollbar(struct nk_command_buffer *out, nk_flags state,
+ const struct nk_style_scrollbar *style, const struct nk_rect *bounds,
+ const struct nk_rect *scroll)
+{
+ const struct nk_style_item *background;
+ const struct nk_style_item *cursor;
+
+ /* select correct colors/images to draw */
+ if (state & NK_WIDGET_STATE_ACTIVED) {
+ background = &style->active;
+ cursor = &style->cursor_active;
+ } else if (state & NK_WIDGET_STATE_HOVER) {
+ background = &style->hover;
+ cursor = &style->cursor_hover;
+ } else {
+ background = &style->normal;
+ cursor = &style->cursor_normal;
+ }
+
+ /* draw background */
+ if (background->type == NK_STYLE_ITEM_COLOR) {
+ nk_fill_rect(out, *bounds, style->rounding, background->data.color);
+ nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color);
+ } else {
+ nk_draw_image(out, *bounds, &background->data.image, nk_white);
+ }
+
+ /* draw cursor */
+ if (background->type == NK_STYLE_ITEM_COLOR) {
+ nk_fill_rect(out, *scroll, style->rounding_cursor, cursor->data.color);
+ nk_stroke_rect(out, *scroll, style->rounding_cursor, style->border_cursor, style->cursor_border_color);
+ } else nk_draw_image(out, *scroll, &cursor->data.image, nk_white);
+}
+
+NK_INTERN float
+nk_do_scrollbarv(nk_flags *state,
+ struct nk_command_buffer *out, struct nk_rect scroll, int has_scrolling,
+ float offset, float target, float step, float button_pixel_inc,
+ const struct nk_style_scrollbar *style, struct nk_input *in,
+ const struct nk_user_font *font)
+{
+ struct nk_rect empty_north;
+ struct nk_rect empty_south;
+ struct nk_rect cursor;
+
+ float scroll_step;
+ float scroll_offset;
+ float scroll_off;
+ float scroll_ratio;
+
+ NK_ASSERT(out);
+ NK_ASSERT(style);
+ NK_ASSERT(state);
+ if (!out || !style) return 0;
+
+ scroll.w = NK_MAX(scroll.w, 1);
+ scroll.h = NK_MAX(scroll.h, 0);
+ if (target <= scroll.h) return 0;
+
+ /* optional scrollbar buttons */
+ if (style->show_buttons) {
+ nk_flags ws;
+ float scroll_h;
+ struct nk_rect button;
+
+ button.x = scroll.x;
+ button.w = scroll.w;
+ button.h = scroll.w;
+
+ scroll_h = NK_MAX(scroll.h - 2 * button.h,0);
+ scroll_step = NK_MIN(step, button_pixel_inc);
+
+ /* decrement button */
+ button.y = scroll.y;
+ if (nk_do_button_symbol(&ws, out, button, style->dec_symbol,
+ NK_BUTTON_REPEATER, &style->dec_button, in, font))
+ offset = offset - scroll_step;
+
+ /* increment button */
+ button.y = scroll.y + scroll.h - button.h;
+ if (nk_do_button_symbol(&ws, out, button, style->inc_symbol,
+ NK_BUTTON_REPEATER, &style->inc_button, in, font))
+ offset = offset + scroll_step;
+
+ scroll.y = scroll.y + button.h;
+ scroll.h = scroll_h;
+ }
+
+ /* calculate scrollbar constants */
+ scroll_step = NK_MIN(step, scroll.h);
+ scroll_offset = NK_CLAMP(0, offset, target - scroll.h);
+ scroll_ratio = scroll.h / target;
+ scroll_off = scroll_offset / target;
+
+ /* calculate scrollbar cursor bounds */
+ cursor.h = NK_MAX((scroll_ratio * scroll.h) - (2*style->border + 2*style->padding.y), 0);
+ cursor.y = scroll.y + (scroll_off * scroll.h) + style->border + style->padding.y;
+ cursor.w = scroll.w - (2 * style->border + 2 * style->padding.x);
+ cursor.x = scroll.x + style->border + style->padding.x;
+
+ /* calculate empty space around cursor */
+ empty_north.x = scroll.x;
+ empty_north.y = scroll.y;
+ empty_north.w = scroll.w;
+ empty_north.h = NK_MAX(cursor.y - scroll.y, 0);
+
+ empty_south.x = scroll.x;
+ empty_south.y = cursor.y + cursor.h;
+ empty_south.w = scroll.w;
+ empty_south.h = NK_MAX((scroll.y + scroll.h) - (cursor.y + cursor.h), 0);
+
+ /* update scrollbar */
+ scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor,
+ &empty_north, &empty_south, scroll_offset, target, scroll_step, NK_VERTICAL);
+ scroll_off = scroll_offset / target;
+ cursor.y = scroll.y + (scroll_off * scroll.h) + style->border_cursor + style->padding.y;
+
+ /* draw scrollbar */
+ if (style->draw_begin) style->draw_begin(out, style->userdata);
+ nk_draw_scrollbar(out, *state, style, &scroll, &cursor);
+ if (style->draw_end) style->draw_end(out, style->userdata);
+ return scroll_offset;
+}
+
+NK_INTERN float
+nk_do_scrollbarh(nk_flags *state,
+ struct nk_command_buffer *out, struct nk_rect scroll, int has_scrolling,
+ float offset, float target, float step, float button_pixel_inc,
+ const struct nk_style_scrollbar *style, struct nk_input *in,
+ const struct nk_user_font *font)
+{
+ struct nk_rect cursor;
+ struct nk_rect empty_west;
+ struct nk_rect empty_east;
+
+ float scroll_step;
+ float scroll_offset;
+ float scroll_off;
+ float scroll_ratio;
+
+ NK_ASSERT(out);
+ NK_ASSERT(style);
+ if (!out || !style) return 0;
+
+ /* scrollbar background */
+ scroll.h = NK_MAX(scroll.h, 1);
+ scroll.w = NK_MAX(scroll.w, 2 * scroll.h);
+ if (target <= scroll.w) return 0;
+
+ /* optional scrollbar buttons */
+ if (style->show_buttons) {
+ nk_flags ws;
+ float scroll_w;
+ struct nk_rect button;
+ button.y = scroll.y;
+ button.w = scroll.h;
+ button.h = scroll.h;
+
+ scroll_w = scroll.w - 2 * button.w;
+ scroll_step = NK_MIN(step, button_pixel_inc);
+
+ /* decrement button */
+ button.x = scroll.x;
+ if (nk_do_button_symbol(&ws, out, button, style->dec_symbol,
+ NK_BUTTON_REPEATER, &style->dec_button, in, font))
+ offset = offset - scroll_step;
+
+ /* increment button */
+ button.x = scroll.x + scroll.w - button.w;
+ if (nk_do_button_symbol(&ws, out, button, style->inc_symbol,
+ NK_BUTTON_REPEATER, &style->inc_button, in, font))
+ offset = offset + scroll_step;
+
+ scroll.x = scroll.x + button.w;
+ scroll.w = scroll_w;
+ }
+
+ /* calculate scrollbar constants */
+ scroll_step = NK_MIN(step, scroll.w);
+ scroll_offset = NK_CLAMP(0, offset, target - scroll.w);
+ scroll_ratio = scroll.w / target;
+ scroll_off = scroll_offset / target;
+
+ /* calculate cursor bounds */
+ cursor.w = (scroll_ratio * scroll.w) - (2*style->border + 2*style->padding.x);
+ cursor.x = scroll.x + (scroll_off * scroll.w) + style->border + style->padding.x;
+ cursor.h = scroll.h - (2 * style->border + 2 * style->padding.y);
+ cursor.y = scroll.y + style->border + style->padding.y;
+
+ /* calculate empty space around cursor */
+ empty_west.x = scroll.x;
+ empty_west.y = scroll.y;
+ empty_west.w = cursor.x - scroll.x;
+ empty_west.h = scroll.h;
+
+ empty_east.x = cursor.x + cursor.w;
+ empty_east.y = scroll.y;
+ empty_east.w = (scroll.x + scroll.w) - (cursor.x + cursor.w);
+ empty_east.h = scroll.h;
+
+ /* update scrollbar */
+ scroll_offset = nk_scrollbar_behavior(state, in, has_scrolling, &scroll, &cursor,
+ &empty_west, &empty_east, scroll_offset, target, scroll_step, NK_HORIZONTAL);
+ scroll_off = scroll_offset / target;
+ cursor.x = scroll.x + (scroll_off * scroll.w);
+
+ /* draw scrollbar */
+ if (style->draw_begin) style->draw_begin(out, style->userdata);
+ nk_draw_scrollbar(out, *state, style, &scroll, &cursor);
+ if (style->draw_end) style->draw_end(out, style->userdata);
+ return scroll_offset;
+}
+
+/* ===============================================================
+ *
+ * FILTER
+ *
+ * ===============================================================*/
+NK_API int nk_filter_default(const struct nk_text_edit *box, nk_rune unicode)
+{(void)unicode;NK_UNUSED(box);return nk_true;}
+
+NK_API int
+nk_filter_ascii(const struct nk_text_edit *box, nk_rune unicode)
+{
+ NK_UNUSED(box);
+ if (unicode > 128) return nk_false;
+ else return nk_true;
+}
+
+NK_API int
+nk_filter_float(const struct nk_text_edit *box, nk_rune unicode)
+{
+ NK_UNUSED(box);
+ if ((unicode < '0' || unicode > '9') && unicode != '.' && unicode != '-')
+ return nk_false;
+ else return nk_true;
+}
+
+NK_API int
+nk_filter_decimal(const struct nk_text_edit *box, nk_rune unicode)
+{
+ NK_UNUSED(box);
+ if ((unicode < '0' || unicode > '9') && unicode != '-')
+ return nk_false;
+ else return nk_true;
+}
+
+NK_API int
+nk_filter_hex(const struct nk_text_edit *box, nk_rune unicode)
+{
+ NK_UNUSED(box);
+ if ((unicode < '0' || unicode > '9') &&
+ (unicode < 'a' || unicode > 'f') &&
+ (unicode < 'A' || unicode > 'F'))
+ return nk_false;
+ else return nk_true;
+}
+
+NK_API int
+nk_filter_oct(const struct nk_text_edit *box, nk_rune unicode)
+{
+ NK_UNUSED(box);
+ if (unicode < '0' || unicode > '7')
+ return nk_false;
+ else return nk_true;
+}
+
+NK_API int
+nk_filter_binary(const struct nk_text_edit *box, nk_rune unicode)
+{
+ NK_UNUSED(box);
+ if (unicode != '0' && unicode != '1')
+ return nk_false;
+ else return nk_true;
+}
+
+/* ===============================================================
+ *
+ * EDIT
+ *
+ * ===============================================================*/
+NK_INTERN void
+nk_edit_draw_text(struct nk_command_buffer *out,
+ const struct nk_style_edit *style, float pos_x, float pos_y,
+ float x_offset, const char *text, int byte_len, float row_height,
+ const struct nk_user_font *font, struct nk_color background,
+ struct nk_color foreground, int is_selected)
+{
+ NK_ASSERT(out);
+ NK_ASSERT(font);
+ NK_ASSERT(style);
+ if (!text || !byte_len || !out || !style) return;
+
+ {int glyph_len = 0;
+ nk_rune unicode = 0;
+ int text_len = 0;
+ float line_width = 0;
+ float glyph_width;
+ const char *line = text;
+ float line_offset = 0;
+ int line_count = 0;
+
+ struct nk_text txt;
+ txt.padding = nk_vec2(0,0);
+ txt.background = background;
+ txt.text = foreground;
+
+ glyph_len = nk_utf_decode(text+text_len, &unicode, byte_len-text_len);
+ if (!glyph_len) return;
+ while ((text_len < byte_len) && glyph_len)
+ {
+ if (unicode == '\n') {
+ /* new line separator so draw previous line */
+ struct nk_rect label;
+ label.y = pos_y + line_offset;
+ label.h = row_height;
+ label.w = line_width;
+ label.x = pos_x;
+ if (!line_count)
+ label.x += x_offset;
+
+ if (is_selected) /* selection needs to draw different background color */
+ nk_fill_rect(out, label, 0, background);
+ nk_widget_text(out, label, line, (int)((text + text_len) - line),
+ &txt, NK_TEXT_CENTERED, font);
+
+ text_len++;
+ line_count++;
+ line_width = 0;
+ line = text + text_len;
+ line_offset += row_height;
+ glyph_len = nk_utf_decode(text + text_len, &unicode, (int)(byte_len-text_len));
+ continue;
+ }
+ if (unicode == '\r') {
+ text_len++;
+ glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
+ continue;
+ }
+ glyph_width = font->width(font->userdata, font->height, text+text_len, glyph_len);
+ line_width += (float)glyph_width;
+ text_len += glyph_len;
+ glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len-text_len);
+ continue;
+ }
+ if (line_width > 0) {
+ /* draw last line */
+ struct nk_rect label;
+ label.y = pos_y + line_offset;
+ label.h = row_height;
+ label.w = line_width;
+ label.x = pos_x;
+ if (!line_count)
+ label.x += x_offset;
+
+ if (is_selected)
+ nk_fill_rect(out, label, 0, background);
+ nk_widget_text(out, label, line, (int)((text + text_len) - line),
+ &txt, NK_TEXT_LEFT, font);
+ }}
+}
+
+NK_INTERN nk_flags
+nk_do_edit(nk_flags *state, struct nk_command_buffer *out,
+ struct nk_rect bounds, nk_flags flags, nk_plugin_filter filter,
+ struct nk_text_edit *edit, const struct nk_style_edit *style,
+ struct nk_input *in, const struct nk_user_font *font)
+{
+ struct nk_rect area;
+ nk_flags ret = 0;
+ float row_height;
+ char prev_state = 0;
+ char is_hovered = 0;
+ char select_all = 0;
+ char cursor_follow = 0;
+ struct nk_rect old_clip;
+ struct nk_rect clip;
+
+ NK_ASSERT(state);
+ NK_ASSERT(out);
+ NK_ASSERT(style);
+ if (!state || !out || !style)
+ return ret;
+
+ /* visible text area calculation */
+ area.x = bounds.x + style->padding.x + style->border;
+ area.y = bounds.y + style->padding.y + style->border;
+ area.w = bounds.w - (2.0f * style->padding.x + 2 * style->border);
+ area.h = bounds.h - (2.0f * style->padding.y + 2 * style->border);
+ if (flags & NK_EDIT_MULTILINE)
+ area.w = NK_MAX(0, area.w - style->scrollbar_size.x);
+ row_height = (flags & NK_EDIT_MULTILINE)? font->height + style->row_padding: area.h;
+
+ /* calculate clipping rectangle */
+ old_clip = out->clip;
+ nk_unify(&clip, &old_clip, area.x, area.y, area.x + area.w, area.y + area.h);
+
+ /* update edit state */
+ prev_state = (char)edit->active;
+ is_hovered = (char)nk_input_is_mouse_hovering_rect(in, bounds);
+ if (in && in->mouse.buttons[NK_BUTTON_LEFT].clicked && in->mouse.buttons[NK_BUTTON_LEFT].down) {
+ edit->active = NK_INBOX(in->mouse.pos.x, in->mouse.pos.y,
+ bounds.x, bounds.y, bounds.w, bounds.h);
+ }
+
+ /* (de)activate text editor */
+ if (!prev_state && edit->active) {
+ const enum nk_text_edit_type type = (flags & NK_EDIT_MULTILINE) ?
+ NK_TEXT_EDIT_MULTI_LINE: NK_TEXT_EDIT_SINGLE_LINE;
+ nk_textedit_clear_state(edit, type, filter);
+ if (flags & NK_EDIT_AUTO_SELECT)
+ select_all = nk_true;
+ if (flags & NK_EDIT_GOTO_END_ON_ACTIVATE) {
+ edit->cursor = edit->string.len;
+ in = 0;
+ }
+ } else if (!edit->active) edit->mode = NK_TEXT_EDIT_MODE_VIEW;
+ if (flags & NK_EDIT_READ_ONLY)
+ edit->mode = NK_TEXT_EDIT_MODE_VIEW;
+ else if (flags & NK_EDIT_ALWAYS_INSERT_MODE)
+ edit->mode = NK_TEXT_EDIT_MODE_INSERT;
+
+ ret = (edit->active) ? NK_EDIT_ACTIVE: NK_EDIT_INACTIVE;
+ if (prev_state != edit->active)
+ ret |= (edit->active) ? NK_EDIT_ACTIVATED: NK_EDIT_DEACTIVATED;
+
+ /* handle user input */
+ if (edit->active && in)
+ {
+ int shift_mod = in->keyboard.keys[NK_KEY_SHIFT].down;
+ const float mouse_x = (in->mouse.pos.x - area.x) + edit->scrollbar.x;
+ const float mouse_y = (in->mouse.pos.y - area.y) + edit->scrollbar.y;
+
+ /* mouse click handler */
+ is_hovered = (char)nk_input_is_mouse_hovering_rect(in, area);
+ if (select_all) {
+ nk_textedit_select_all(edit);
+ } else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down &&
+ in->mouse.buttons[NK_BUTTON_LEFT].clicked) {
+ nk_textedit_click(edit, mouse_x, mouse_y, font, row_height);
+ } else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down &&
+ (in->mouse.delta.x != 0.0f || in->mouse.delta.y != 0.0f)) {
+ nk_textedit_drag(edit, mouse_x, mouse_y, font, row_height);
+ cursor_follow = nk_true;
+ } else if (is_hovered && in->mouse.buttons[NK_BUTTON_RIGHT].clicked &&
+ in->mouse.buttons[NK_BUTTON_RIGHT].down) {
+ nk_textedit_key(edit, NK_KEY_TEXT_WORD_LEFT, nk_false, font, row_height);
+ nk_textedit_key(edit, NK_KEY_TEXT_WORD_RIGHT, nk_true, font, row_height);
+ cursor_follow = nk_true;
+ }
+
+ {int i; /* keyboard input */
+ int old_mode = edit->mode;
+ for (i = 0; i < NK_KEY_MAX; ++i) {
+ if (i == NK_KEY_ENTER || i == NK_KEY_TAB) continue; /* special case */
+ if (nk_input_is_key_pressed(in, (enum nk_keys)i)) {
+ nk_textedit_key(edit, (enum nk_keys)i, shift_mod, font, row_height);
+ cursor_follow = nk_true;
+ }
+ }
+ if (old_mode != edit->mode) {
+ in->keyboard.text_len = 0;
+ }}
+
+ /* text input */
+ edit->filter = filter;
+ if (in->keyboard.text_len) {
+ nk_textedit_text(edit, in->keyboard.text, in->keyboard.text_len);
+ cursor_follow = nk_true;
+ in->keyboard.text_len = 0;
+ }
+
+ /* enter key handler */
+ if (nk_input_is_key_pressed(in, NK_KEY_ENTER)) {
+ cursor_follow = nk_true;
+ if (flags & NK_EDIT_CTRL_ENTER_NEWLINE && shift_mod)
+ nk_textedit_text(edit, "\n", 1);
+ else if (flags & NK_EDIT_SIG_ENTER)
+ ret |= NK_EDIT_COMMITED;
+ else nk_textedit_text(edit, "\n", 1);
+ }
+
+ /* cut & copy handler */
+ {int copy= nk_input_is_key_pressed(in, NK_KEY_COPY);
+ int cut = nk_input_is_key_pressed(in, NK_KEY_CUT);
+ if ((copy || cut) && (flags & NK_EDIT_CLIPBOARD))
+ {
+ int glyph_len;
+ nk_rune unicode;
+ const char *text;
+ int b = edit->select_start;
+ int e = edit->select_end;
+
+ int begin = NK_MIN(b, e);
+ int end = NK_MAX(b, e);
+ text = nk_str_at_const(&edit->string, begin, &unicode, &glyph_len);
+ if (edit->clip.copy)
+ edit->clip.copy(edit->clip.userdata, text, end - begin);
+ if (cut && !(flags & NK_EDIT_READ_ONLY)){
+ nk_textedit_cut(edit);
+ cursor_follow = nk_true;
+ }
+ }}
+
+ /* paste handler */
+ {int paste = nk_input_is_key_pressed(in, NK_KEY_PASTE);
+ if (paste && (flags & NK_EDIT_CLIPBOARD) && edit->clip.paste) {
+ edit->clip.paste(edit->clip.userdata, edit);
+ cursor_follow = nk_true;
+ }}
+
+ /* tab handler */
+ {int tab = nk_input_is_key_pressed(in, NK_KEY_TAB);
+ if (tab && (flags & NK_EDIT_ALLOW_TAB)) {
+ nk_textedit_text(edit, " ", 4);
+ cursor_follow = nk_true;
+ }}
+ }
+
+ /* set widget state */
+ if (edit->active)
+ *state = NK_WIDGET_STATE_ACTIVE;
+ else nk_widget_state_reset(state);
+
+ if (is_hovered)
+ *state |= NK_WIDGET_STATE_HOVERED;
+
+ /* DRAW EDIT */
+ {const char *text = nk_str_get_const(&edit->string);
+ int len = nk_str_len_char(&edit->string);
+
+ {/* select background colors/images */
+ const struct nk_style_item *background;
+ if (*state & NK_WIDGET_STATE_ACTIVED)
+ background = &style->active;
+ else if (*state & NK_WIDGET_STATE_HOVER)
+ background = &style->hover;
+ else background = &style->normal;
+
+ /* draw background frame */
+ if (background->type == NK_STYLE_ITEM_COLOR) {
+ nk_stroke_rect(out, bounds, style->rounding, style->border, style->border_color);
+ nk_fill_rect(out, bounds, style->rounding, background->data.color);
+ } else nk_draw_image(out, bounds, &background->data.image, nk_white);}
+
+ area.w = NK_MAX(0, area.w - style->cursor_size);
+ if (edit->active)
+ {
+ int total_lines = 1;
+ struct nk_vec2 text_size = nk_vec2(0,0);
+
+ /* text pointer positions */
+ const char *cursor_ptr = 0;
+ const char *select_begin_ptr = 0;
+ const char *select_end_ptr = 0;
+
+ /* 2D pixel positions */
+ struct nk_vec2 cursor_pos = nk_vec2(0,0);
+ struct nk_vec2 selection_offset_start = nk_vec2(0,0);
+ struct nk_vec2 selection_offset_end = nk_vec2(0,0);
+
+ int selection_begin = NK_MIN(edit->select_start, edit->select_end);
+ int selection_end = NK_MAX(edit->select_start, edit->select_end);
+
+ /* calculate total line count + total space + cursor/selection position */
+ float line_width = 0.0f;
+ if (text && len)
+ {
+ /* utf8 encoding */
+ float glyph_width;
+ int glyph_len = 0;
+ nk_rune unicode = 0;
+ int text_len = 0;
+ int glyphs = 0;
+ int row_begin = 0;
+
+ glyph_len = nk_utf_decode(text, &unicode, len);
+ glyph_width = font->width(font->userdata, font->height, text, glyph_len);
+ line_width = 0;
+
+ /* iterate all lines */
+ while ((text_len < len) && glyph_len)
+ {
+ /* set cursor 2D position and line */
+ if (!cursor_ptr && glyphs == edit->cursor)
+ {
+ int glyph_offset;
+ struct nk_vec2 out_offset;
+ struct nk_vec2 row_size;
+ const char *remaining;
+
+ /* calculate 2d position */
+ cursor_pos.y = (float)(total_lines-1) * row_height;
+ row_size = nk_text_calculate_text_bounds(font, text+row_begin,
+ text_len-row_begin, row_height, &remaining,
+ &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
+ cursor_pos.x = row_size.x;
+ cursor_ptr = text + text_len;
+ }
+
+ /* set start selection 2D position and line */
+ if (!select_begin_ptr && edit->select_start != edit->select_end &&
+ glyphs == selection_begin)
+ {
+ int glyph_offset;
+ struct nk_vec2 out_offset;
+ struct nk_vec2 row_size;
+ const char *remaining;
+
+ /* calculate 2d position */
+ selection_offset_start.y = (float)(NK_MAX(total_lines-1,0)) * row_height;
+ row_size = nk_text_calculate_text_bounds(font, text+row_begin,
+ text_len-row_begin, row_height, &remaining,
+ &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
+ selection_offset_start.x = row_size.x;
+ select_begin_ptr = text + text_len;
+ }
+
+ /* set end selection 2D position and line */
+ if (!select_end_ptr && edit->select_start != edit->select_end &&
+ glyphs == selection_end)
+ {
+ int glyph_offset;
+ struct nk_vec2 out_offset;
+ struct nk_vec2 row_size;
+ const char *remaining;
+
+ /* calculate 2d position */
+ selection_offset_end.y = (float)(total_lines-1) * row_height;
+ row_size = nk_text_calculate_text_bounds(font, text+row_begin,
+ text_len-row_begin, row_height, &remaining,
+ &out_offset, &glyph_offset, NK_STOP_ON_NEW_LINE);
+ selection_offset_end.x = row_size.x;
+ select_end_ptr = text + text_len;
+ }
+ if (unicode == '\n') {
+ text_size.x = NK_MAX(text_size.x, line_width);
+ total_lines++;
+ line_width = 0;
+ text_len++;
+ glyphs++;
+ row_begin = text_len;
+ glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len);
+ glyph_width = font->width(font->userdata, font->height, text+text_len, glyph_len);
+ continue;
+ }
+
+ glyphs++;
+ text_len += glyph_len;
+ line_width += (float)glyph_width;
+
+ glyph_len = nk_utf_decode(text + text_len, &unicode, len-text_len);
+ glyph_width = font->width(font->userdata, font->height,
+ text+text_len, glyph_len);
+ continue;
+ }
+ text_size.y = (float)total_lines * row_height;
+
+ /* handle case when cursor is at end of text buffer */
+ if (!cursor_ptr && edit->cursor == edit->string.len) {
+ cursor_pos.x = line_width;
+ cursor_pos.y = text_size.y - row_height;
+ }
+ }
+ {
+ /* scrollbar */
+ if (cursor_follow)
+ {
+ /* update scrollbar to follow cursor */
+ if (!(flags & NK_EDIT_NO_HORIZONTAL_SCROLL)) {
+ /* horizontal scroll */
+ const float scroll_increment = area.w * 0.25f;
+ if (cursor_pos.x < edit->scrollbar.x)
+ edit->scrollbar.x = (float)(int)NK_MAX(0.0f, cursor_pos.x - scroll_increment);
+ if (cursor_pos.x >= edit->scrollbar.x + area.w)
+ edit->scrollbar.x = (float)(int)NK_MAX(0.0f, cursor_pos.x);
+ } else edit->scrollbar.x = 0;
+
+ if (flags & NK_EDIT_MULTILINE) {
+ /* vertical scroll */
+ if (cursor_pos.y < edit->scrollbar.y)
+ edit->scrollbar.y = NK_MAX(0.0f, cursor_pos.y - row_height);
+ if (cursor_pos.y >= edit->scrollbar.y + area.h)
+ edit->scrollbar.y = edit->scrollbar.y + row_height;
+ } else edit->scrollbar.y = 0;
+ }
+
+ /* scrollbar widget */
+ if (flags & NK_EDIT_MULTILINE)
+ {
+ nk_flags ws;
+ struct nk_rect scroll;
+ float scroll_target;
+ float scroll_offset;
+ float scroll_step;
+ float scroll_inc;
+
+ scroll = area;
+ scroll.x = (bounds.x + bounds.w - style->border) - style->scrollbar_size.x;
+ scroll.w = style->scrollbar_size.x;
+
+ scroll_offset = edit->scrollbar.y;
+ scroll_step = scroll.h * 0.10f;
+ scroll_inc = scroll.h * 0.01f;
+ scroll_target = text_size.y;
+ edit->scrollbar.y = nk_do_scrollbarv(&ws, out, scroll, 0,
+ scroll_offset, scroll_target, scroll_step, scroll_inc,
+ &style->scrollbar, in, font);
+ }
+ }
+
+ /* draw text */
+ {struct nk_color background_color;
+ struct nk_color text_color;
+ struct nk_color sel_background_color;
+ struct nk_color sel_text_color;
+ struct nk_color cursor_color;
+ struct nk_color cursor_text_color;
+ const struct nk_style_item *background;
+ nk_push_scissor(out, clip);
+
+ /* select correct colors to draw */
+ if (*state & NK_WIDGET_STATE_ACTIVED) {
+ background = &style->active;
+ text_color = style->text_active;
+ sel_text_color = style->selected_text_hover;
+ sel_background_color = style->selected_hover;
+ cursor_color = style->cursor_hover;
+ cursor_text_color = style->cursor_text_hover;
+ } else if (*state & NK_WIDGET_STATE_HOVER) {
+ background = &style->hover;
+ text_color = style->text_hover;
+ sel_text_color = style->selected_text_hover;
+ sel_background_color = style->selected_hover;
+ cursor_text_color = style->cursor_text_hover;
+ cursor_color = style->cursor_hover;
+ } else {
+ background = &style->normal;
+ text_color = style->text_normal;
+ sel_text_color = style->selected_text_normal;
+ sel_background_color = style->selected_normal;
+ cursor_color = style->cursor_normal;
+ cursor_text_color = style->cursor_text_normal;
+ }
+ if (background->type == NK_STYLE_ITEM_IMAGE)
+ background_color = nk_rgba(0,0,0,0);
+ else background_color = background->data.color;
+
+
+ if (edit->select_start == edit->select_end) {
+ /* no selection so just draw the complete text */
+ const char *begin = nk_str_get_const(&edit->string);
+ int l = nk_str_len_char(&edit->string);
+ nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
+ area.y - edit->scrollbar.y, 0, begin, l, row_height, font,
+ background_color, text_color, nk_false);
+ } else {
+ /* edit has selection so draw 1-3 text chunks */
+ if (edit->select_start != edit->select_end && selection_begin > 0){
+ /* draw unselected text before selection */
+ const char *begin = nk_str_get_const(&edit->string);
+ NK_ASSERT(select_begin_ptr);
+ nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
+ area.y - edit->scrollbar.y, 0, begin, (int)(select_begin_ptr - begin),
+ row_height, font, background_color, text_color, nk_false);
+ }
+ if (edit->select_start != edit->select_end) {
+ /* draw selected text */
+ NK_ASSERT(select_begin_ptr);
+ if (!select_end_ptr) {
+ const char *begin = nk_str_get_const(&edit->string);
+ select_end_ptr = begin + nk_str_len_char(&edit->string);
+ }
+ nk_edit_draw_text(out, style,
+ area.x - edit->scrollbar.x,
+ area.y + selection_offset_start.y - edit->scrollbar.y,
+ selection_offset_start.x,
+ select_begin_ptr, (int)(select_end_ptr - select_begin_ptr),
+ row_height, font, sel_background_color, sel_text_color, nk_true);
+ }
+ if ((edit->select_start != edit->select_end &&
+ selection_end < edit->string.len))
+ {
+ /* draw unselected text after selected text */
+ const char *begin = select_end_ptr;
+ const char *end = nk_str_get_const(&edit->string) +
+ nk_str_len_char(&edit->string);
+ NK_ASSERT(select_end_ptr);
+ nk_edit_draw_text(out, style,
+ area.x - edit->scrollbar.x,
+ area.y + selection_offset_end.y - edit->scrollbar.y,
+ selection_offset_end.x,
+ begin, (int)(end - begin), row_height, font,
+ background_color, text_color, nk_true);
+ }
+ }
+
+ /* cursor */
+ if (edit->select_start == edit->select_end)
+ {
+ if (edit->cursor >= nk_str_len(&edit->string) ||
+ (cursor_ptr && *cursor_ptr == '\n')) {
+ /* draw cursor at end of line */
+ struct nk_rect cursor;
+ cursor.w = style->cursor_size;
+ cursor.h = font->height;
+ cursor.x = area.x + cursor_pos.x - edit->scrollbar.x;
+ cursor.y = area.y + cursor_pos.y + row_height/2.0f - cursor.h/2.0f;
+ cursor.y -= edit->scrollbar.y;
+ nk_fill_rect(out, cursor, 0, cursor_color);
+ } else {
+ /* draw cursor inside text */
+ int glyph_len;
+ struct nk_rect label;
+ struct nk_text txt;
+
+ nk_rune unicode;
+ NK_ASSERT(cursor_ptr);
+ glyph_len = nk_utf_decode(cursor_ptr, &unicode, 4);
+
+ label.x = area.x + cursor_pos.x - edit->scrollbar.x;
+ label.y = area.y + cursor_pos.y - edit->scrollbar.y;
+ label.w = font->width(font->userdata, font->height, cursor_ptr, glyph_len);
+ label.h = row_height;
+
+ txt.padding = nk_vec2(0,0);
+ txt.background = cursor_color;;
+ txt.text = cursor_text_color;
+ nk_fill_rect(out, label, 0, cursor_color);
+ nk_widget_text(out, label, cursor_ptr, glyph_len, &txt, NK_TEXT_LEFT, font);
+ }
+ }}
+ } else {
+ /* not active so just draw text */
+ int l = nk_str_len_char(&edit->string);
+ const char *begin = nk_str_get_const(&edit->string);
+
+ const struct nk_style_item *background;
+ struct nk_color background_color;
+ struct nk_color text_color;
+ nk_push_scissor(out, clip);
+ if (*state & NK_WIDGET_STATE_ACTIVED) {
+ background = &style->active;
+ text_color = style->text_active;
+ } else if (*state & NK_WIDGET_STATE_HOVER) {
+ background = &style->hover;
+ text_color = style->text_hover;
+ } else {
+ background = &style->normal;
+ text_color = style->text_normal;
+ }
+ if (background->type == NK_STYLE_ITEM_IMAGE)
+ background_color = nk_rgba(0,0,0,0);
+ else background_color = background->data.color;
+ nk_edit_draw_text(out, style, area.x - edit->scrollbar.x,
+ area.y - edit->scrollbar.y, 0, begin, l, row_height, font,
+ background_color, text_color, nk_false);
+ }
+ nk_push_scissor(out, old_clip);}
+ return ret;
+}
+
+/* ===============================================================
+ *
+ * PROPERTY
+ *
+ * ===============================================================*/
+enum nk_property_status {
+ NK_PROPERTY_DEFAULT,
+ NK_PROPERTY_EDIT,
+ NK_PROPERTY_DRAG
+};
+enum nk_property_filter {
+ NK_FILTER_INT,
+ NK_FILTER_FLOAT
+};
+enum nk_property_kind {
+ NK_PROPERTY_INT,
+ NK_PROPERTY_FLOAT,
+ NK_PROPERTY_DOUBLE
+};
+union nk_property {
+ int i;
+ float f;
+ double d;
+};
+struct nk_property_variant {
+ enum nk_property_kind kind;
+ union nk_property value;
+ union nk_property min_value;
+ union nk_property max_value;
+ union nk_property step;
+};
+
+NK_INTERN void
+nk_drag_behavior(nk_flags *state, const struct nk_input *in,
+ struct nk_rect drag, struct nk_property_variant *variant,
+ float inc_per_pixel)
+{
+ int left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down;
+ int left_mouse_click_in_cursor = in &&
+ nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, drag, nk_true);
+
+ nk_widget_state_reset(state);
+ if (nk_input_is_mouse_hovering_rect(in, drag))
+ *state = NK_WIDGET_STATE_HOVERED;
+
+ if (left_mouse_down && left_mouse_click_in_cursor) {
+ float delta, pixels;
+ pixels = in->mouse.delta.x;
+ delta = pixels * inc_per_pixel;
+ switch (variant->kind) {
+ default: break;
+ case NK_PROPERTY_INT:
+ variant->value.i = variant->value.i + (int)delta;
+ variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
+ break;
+ case NK_PROPERTY_FLOAT:
+ variant->value.f = variant->value.f + (float)delta;
+ variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
+ break;
+ case NK_PROPERTY_DOUBLE:
+ variant->value.d = variant->value.d + (double)delta;
+ variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
+ break;
+ }
+ *state = NK_WIDGET_STATE_ACTIVE;
+ }
+ if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, drag))
+ *state |= NK_WIDGET_STATE_ENTERED;
+ else if (nk_input_is_mouse_prev_hovering_rect(in, drag))
+ *state |= NK_WIDGET_STATE_LEFT;
+}
+
+NK_INTERN void
+nk_property_behavior(nk_flags *ws, const struct nk_input *in,
+ struct nk_rect property, struct nk_rect label, struct nk_rect edit,
+ struct nk_rect empty, int *state, struct nk_property_variant *variant,
+ float inc_per_pixel)
+{
+ if (in && *state == NK_PROPERTY_DEFAULT) {
+ if (nk_button_behavior(ws, edit, in, NK_BUTTON_DEFAULT))
+ *state = NK_PROPERTY_EDIT;
+ else if (nk_input_is_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, label, nk_true))
+ *state = NK_PROPERTY_DRAG;
+ else if (nk_input_is_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, empty, nk_true))
+ *state = NK_PROPERTY_DRAG;
+ }
+ if (*state == NK_PROPERTY_DRAG) {
+ nk_drag_behavior(ws, in, property, variant, inc_per_pixel);
+ if (!(*ws & NK_WIDGET_STATE_ACTIVED)) *state = NK_PROPERTY_DEFAULT;
+ }
+}
+
+NK_INTERN void
+nk_draw_property(struct nk_command_buffer *out, const struct nk_style_property *style,
+ const struct nk_rect *bounds, const struct nk_rect *label, nk_flags state,
+ const char *name, int len, const struct nk_user_font *font)
+{
+ struct nk_text text;
+ const struct nk_style_item *background;
+
+ /* select correct background and text color */
+ if (state & NK_WIDGET_STATE_ACTIVED) {
+ background = &style->active;
+ text.text = style->label_active;
+ } else if (state & NK_WIDGET_STATE_HOVER) {
+ background = &style->hover;
+ text.text = style->label_hover;
+ } else {
+ background = &style->normal;
+ text.text = style->label_normal;
+ }
+
+ /* draw background */
+ if (background->type == NK_STYLE_ITEM_IMAGE) {
+ nk_draw_image(out, *bounds, &background->data.image, nk_white);
+ text.background = nk_rgba(0,0,0,0);
+ } else {
+ text.background = background->data.color;
+ nk_fill_rect(out, *bounds, style->rounding, background->data.color);
+ nk_stroke_rect(out, *bounds, style->rounding, style->border, background->data.color);
+ }
+
+ /* draw label */
+ text.padding = nk_vec2(0,0);
+ nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font);
+}
+
+NK_INTERN void
+nk_do_property(nk_flags *ws,
+ struct nk_command_buffer *out, struct nk_rect property,
+ const char *name, struct nk_property_variant *variant,
+ float inc_per_pixel, char *buffer, int *len,
+ int *state, int *cursor, int *select_begin, int *select_end,
+ const struct nk_style_property *style,
+ enum nk_property_filter filter, struct nk_input *in,
+ const struct nk_user_font *font, struct nk_text_edit *text_edit,
+ enum nk_button_behavior behavior)
+{
+ const nk_plugin_filter filters[] = {
+ nk_filter_decimal,
+ nk_filter_float
+ };
+ int active, old;
+ int num_len, name_len;
+ char string[NK_MAX_NUMBER_BUFFER];
+ float size;
+
+ char *dst = 0;
+ int *length;
+
+ struct nk_rect left;
+ struct nk_rect right;
+ struct nk_rect label;
+ struct nk_rect edit;
+ struct nk_rect empty;
+
+ /* left decrement button */
+ left.h = font->height/2;
+ left.w = left.h;
+ left.x = property.x + style->border + style->padding.x;
+ left.y = property.y + style->border + property.h/2.0f - left.h/2;
+
+ /* text label */
+ name_len = nk_strlen(name);
+ size = font->width(font->userdata, font->height, name, name_len);
+ label.x = left.x + left.w + style->padding.x;
+ label.w = (float)size + 2 * style->padding.x;
+ label.y = property.y + style->border + style->padding.y;
+ label.h = property.h - (2 * style->border + 2 * style->padding.y);
+
+ /* right increment button */
+ right.y = left.y;
+ right.w = left.w;
+ right.h = left.h;
+ right.x = property.x + property.w - (right.w + style->padding.x);
+
+ /* edit */
+ if (*state == NK_PROPERTY_EDIT) {
+ size = font->width(font->userdata, font->height, buffer, *len);
+ size += style->edit.cursor_size;
+ length = len;
+ dst = buffer;
+ } else {
+ switch (variant->kind) {
+ default: break;
+ case NK_PROPERTY_INT:
+ nk_itoa(string, variant->value.i);
+ num_len = nk_strlen(string);
+ break;
+ case NK_PROPERTY_FLOAT:
+ NK_DTOA(string, (double)variant->value.f);
+ num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
+ break;
+ case NK_PROPERTY_DOUBLE:
+ NK_DTOA(string, variant->value.d);
+ num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
+ break;
+ }
+ size = font->width(font->userdata, font->height, string, num_len);
+ dst = string;
+ length = &num_len;
+ }
+
+ edit.w = (float)size + 2 * style->padding.x;
+ edit.w = NK_MIN(edit.w, right.x - (label.x + label.w));
+ edit.x = right.x - (edit.w + style->padding.x);
+ edit.y = property.y + style->border;
+ edit.h = property.h - (2 * style->border);
+
+ /* empty left space activator */
+ empty.w = edit.x - (label.x + label.w);
+ empty.x = label.x + label.w;
+ empty.y = property.y;
+ empty.h = property.h;
+
+ /* update property */
+ old = (*state == NK_PROPERTY_EDIT);
+ nk_property_behavior(ws, in, property, label, edit, empty, state, variant, inc_per_pixel);
+
+ /* draw property */
+ if (style->draw_begin) style->draw_begin(out, style->userdata);
+ nk_draw_property(out, style, &property, &label, *ws, name, name_len, font);
+ if (style->draw_end) style->draw_end(out, style->userdata);
+
+ /* execute right button */
+ if (nk_do_button_symbol(ws, out, left, style->sym_left, behavior, &style->dec_button, in, font)) {
+ switch (variant->kind) {
+ default: break;
+ case NK_PROPERTY_INT:
+ variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i - variant->step.i, variant->max_value.i); break;
+ case NK_PROPERTY_FLOAT:
+ variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f - variant->step.f, variant->max_value.f); break;
+ case NK_PROPERTY_DOUBLE:
+ variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d - variant->step.d, variant->max_value.d); break;
+ }
+ }
+ /* execute left button */
+ if (nk_do_button_symbol(ws, out, right, style->sym_right, behavior, &style->inc_button, in, font)) {
+ switch (variant->kind) {
+ default: break;
+ case NK_PROPERTY_INT:
+ variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i + variant->step.i, variant->max_value.i); break;
+ case NK_PROPERTY_FLOAT:
+ variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f + variant->step.f, variant->max_value.f); break;
+ case NK_PROPERTY_DOUBLE:
+ variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d + variant->step.d, variant->max_value.d); break;
+ }
+ }
+ if (old != NK_PROPERTY_EDIT && (*state == NK_PROPERTY_EDIT)) {
+ /* property has been activated so setup buffer */
+ NK_MEMCPY(buffer, dst, (nk_size)*length);
+ *cursor = nk_utf_len(buffer, *length);
+ *len = *length;
+ length = len;
+ dst = buffer;
+ active = 0;
+ } else active = (*state == NK_PROPERTY_EDIT);
+
+ /* execute and run text edit field */
+ nk_textedit_clear_state(text_edit, NK_TEXT_EDIT_SINGLE_LINE, filters[filter]);
+ text_edit->active = (unsigned char)active;
+ text_edit->string.len = *length;
+ text_edit->cursor = NK_CLAMP(0, *cursor, *length);
+ text_edit->select_start = NK_CLAMP(0,*select_begin, *length);
+ text_edit->select_end = NK_CLAMP(0,*select_end, *length);
+ text_edit->string.buffer.allocated = (nk_size)*length;
+ text_edit->string.buffer.memory.size = NK_MAX_NUMBER_BUFFER;
+ text_edit->string.buffer.memory.ptr = dst;
+ text_edit->string.buffer.size = NK_MAX_NUMBER_BUFFER;
+ text_edit->mode = NK_TEXT_EDIT_MODE_INSERT;
+ nk_do_edit(ws, out, edit, NK_EDIT_FIELD|NK_EDIT_AUTO_SELECT,
+ filters[filter], text_edit, &style->edit, (*state == NK_PROPERTY_EDIT) ? in: 0, font);
+
+ *length = text_edit->string.len;
+ *cursor = text_edit->cursor;
+ *select_begin = text_edit->select_start;
+ *select_end = text_edit->select_end;
+ if (text_edit->active && nk_input_is_key_pressed(in, NK_KEY_ENTER))
+ text_edit->active = nk_false;
+
+ if (active && !text_edit->active) {
+ /* property is now not active so convert edit text to value*/
+ *state = NK_PROPERTY_DEFAULT;
+ buffer[*len] = '\0';
+ switch (variant->kind) {
+ default: break;
+ case NK_PROPERTY_INT:
+ variant->value.i = nk_strtoi(buffer, 0);
+ variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
+ break;
+ case NK_PROPERTY_FLOAT:
+ nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
+ variant->value.f = nk_strtof(buffer, 0);
+ variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
+ break;
+ case NK_PROPERTY_DOUBLE:
+ nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
+ variant->value.d = nk_strtod(buffer, 0);
+ variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
+ break;
+ }
+ }
+}
+/* ===============================================================
+ *
+ * COLOR PICKER
+ *
+ * ===============================================================*/
+NK_INTERN int
+nk_color_picker_behavior(nk_flags *state,
+ const struct nk_rect *bounds, const struct nk_rect *matrix,
+ const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar,
+ struct nk_colorf *color, const struct nk_input *in)
+{
+ float hsva[4];
+ int value_changed = 0;
+ int hsv_changed = 0;
+
+ NK_ASSERT(state);
+ NK_ASSERT(matrix);
+ NK_ASSERT(hue_bar);
+ NK_ASSERT(color);
+
+ /* color matrix */
+ nk_colorf_hsva_fv(hsva, *color);
+ if (nk_button_behavior(state, *matrix, in, NK_BUTTON_REPEATER)) {
+ hsva[1] = NK_SATURATE((in->mouse.pos.x - matrix->x) / (matrix->w-1));
+ hsva[2] = 1.0f - NK_SATURATE((in->mouse.pos.y - matrix->y) / (matrix->h-1));
+ value_changed = hsv_changed = 1;
+ }
+ /* hue bar */
+ if (nk_button_behavior(state, *hue_bar, in, NK_BUTTON_REPEATER)) {
+ hsva[0] = NK_SATURATE((in->mouse.pos.y - hue_bar->y) / (hue_bar->h-1));
+ value_changed = hsv_changed = 1;
+ }
+ /* alpha bar */
+ if (alpha_bar) {
+ if (nk_button_behavior(state, *alpha_bar, in, NK_BUTTON_REPEATER)) {
+ hsva[3] = 1.0f - NK_SATURATE((in->mouse.pos.y - alpha_bar->y) / (alpha_bar->h-1));
+ value_changed = 1;
+ }
+ }
+ nk_widget_state_reset(state);
+ if (hsv_changed) {
+ *color = nk_hsva_colorfv(hsva);
+ *state = NK_WIDGET_STATE_ACTIVE;
+ }
+ if (value_changed) {
+ color->a = hsva[3];
+ *state = NK_WIDGET_STATE_ACTIVE;
+ }
+ /* set color picker widget state */
+ if (nk_input_is_mouse_hovering_rect(in, *bounds))
+ *state = NK_WIDGET_STATE_HOVERED;
+ if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, *bounds))
+ *state |= NK_WIDGET_STATE_ENTERED;
+ else if (nk_input_is_mouse_prev_hovering_rect(in, *bounds))
+ *state |= NK_WIDGET_STATE_LEFT;
+ return value_changed;
+}
+
+NK_INTERN void
+nk_draw_color_picker(struct nk_command_buffer *o, const struct nk_rect *matrix,
+ const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar,
+ struct nk_colorf col)
+{
+ NK_STORAGE const struct nk_color black = {0,0,0,255};
+ NK_STORAGE const struct nk_color white = {255, 255, 255, 255};
+ NK_STORAGE const struct nk_color black_trans = {0,0,0,0};
+
+ const float crosshair_size = 7.0f;
+ struct nk_color temp;
+ float hsva[4];
+ float line_y;
+ int i;
+
+ NK_ASSERT(o);
+ NK_ASSERT(matrix);
+ NK_ASSERT(hue_bar);
+
+ /* draw hue bar */
+ nk_colorf_hsva_fv(hsva, col);
+ for (i = 0; i < 6; ++i) {
+ NK_GLOBAL const struct nk_color hue_colors[] = {
+ {255, 0, 0, 255}, {255,255,0,255}, {0,255,0,255}, {0, 255,255,255},
+ {0,0,255,255}, {255, 0, 255, 255}, {255, 0, 0, 255}
+ };
+ nk_fill_rect_multi_color(o,
+ nk_rect(hue_bar->x, hue_bar->y + (float)i * (hue_bar->h/6.0f) + 0.5f,
+ hue_bar->w, (hue_bar->h/6.0f) + 0.5f), hue_colors[i], hue_colors[i],
+ hue_colors[i+1], hue_colors[i+1]);
+ }
+ line_y = (float)(int)(hue_bar->y + hsva[0] * matrix->h + 0.5f);
+ nk_stroke_line(o, hue_bar->x-1, line_y, hue_bar->x + hue_bar->w + 2,
+ line_y, 1, nk_rgb(255,255,255));
+
+ /* draw alpha bar */
+ if (alpha_bar) {
+ float alpha = NK_SATURATE(col.a);
+ line_y = (float)(int)(alpha_bar->y + (1.0f - alpha) * matrix->h + 0.5f);
+
+ nk_fill_rect_multi_color(o, *alpha_bar, white, white, black, black);
+ nk_stroke_line(o, alpha_bar->x-1, line_y, alpha_bar->x + alpha_bar->w + 2,
+ line_y, 1, nk_rgb(255,255,255));
+ }
+
+ /* draw color matrix */
+ temp = nk_hsv_f(hsva[0], 1.0f, 1.0f);
+ nk_fill_rect_multi_color(o, *matrix, white, temp, temp, white);
+ nk_fill_rect_multi_color(o, *matrix, black_trans, black_trans, black, black);
+
+ /* draw cross-hair */
+ {struct nk_vec2 p; float S = hsva[1]; float V = hsva[2];
+ p.x = (float)(int)(matrix->x + S * matrix->w);
+ p.y = (float)(int)(matrix->y + (1.0f - V) * matrix->h);
+ nk_stroke_line(o, p.x - crosshair_size, p.y, p.x-2, p.y, 1.0f, white);
+ nk_stroke_line(o, p.x + crosshair_size + 1, p.y, p.x+3, p.y, 1.0f, white);
+ nk_stroke_line(o, p.x, p.y + crosshair_size + 1, p.x, p.y+3, 1.0f, white);
+ nk_stroke_line(o, p.x, p.y - crosshair_size, p.x, p.y-2, 1.0f, white);}
+}
+
+NK_INTERN int
+nk_do_color_picker(nk_flags *state,
+ struct nk_command_buffer *out, struct nk_colorf *col,
+ enum nk_color_format fmt, struct nk_rect bounds,
+ struct nk_vec2 padding, const struct nk_input *in,
+ const struct nk_user_font *font)
+{
+ int ret = 0;
+ struct nk_rect matrix;
+ struct nk_rect hue_bar;
+ struct nk_rect alpha_bar;
+ float bar_w;
+
+ NK_ASSERT(out);
+ NK_ASSERT(col);
+ NK_ASSERT(state);
+ NK_ASSERT(font);
+ if (!out || !col || !state || !font)
+ return ret;
+
+ bar_w = font->height;
+ bounds.x += padding.x;
+ bounds.y += padding.x;
+ bounds.w -= 2 * padding.x;
+ bounds.h -= 2 * padding.y;
+
+ matrix.x = bounds.x;
+ matrix.y = bounds.y;
+ matrix.h = bounds.h;
+ matrix.w = bounds.w - (3 * padding.x + 2 * bar_w);
+
+ hue_bar.w = bar_w;
+ hue_bar.y = bounds.y;
+ hue_bar.h = matrix.h;
+ hue_bar.x = matrix.x + matrix.w + padding.x;
+
+ alpha_bar.x = hue_bar.x + hue_bar.w + padding.x;
+ alpha_bar.y = bounds.y;
+ alpha_bar.w = bar_w;
+ alpha_bar.h = matrix.h;
+
+ ret = nk_color_picker_behavior(state, &bounds, &matrix, &hue_bar,
+ (fmt == NK_RGBA) ? &alpha_bar:0, col, in);
+ nk_draw_color_picker(out, &matrix, &hue_bar, (fmt == NK_RGBA) ? &alpha_bar:0, *col);
+ return ret;
+}
+
+/* ==============================================================
+ *
+ * STYLE
+ *
+ * ===============================================================*/
+NK_API void nk_style_default(struct nk_context *ctx){nk_style_from_table(ctx, 0);}
+#define NK_COLOR_MAP(NK_COLOR)\
+ NK_COLOR(NK_COLOR_TEXT, 175,175,175,255) \
+ NK_COLOR(NK_COLOR_WINDOW, 45, 45, 45, 255) \
+ NK_COLOR(NK_COLOR_HEADER, 40, 40, 40, 255) \
+ NK_COLOR(NK_COLOR_BORDER, 65, 65, 65, 255) \
+ NK_COLOR(NK_COLOR_BUTTON, 50, 50, 50, 255) \
+ NK_COLOR(NK_COLOR_BUTTON_HOVER, 40, 40, 40, 255) \
+ NK_COLOR(NK_COLOR_BUTTON_ACTIVE, 35, 35, 35, 255) \
+ NK_COLOR(NK_COLOR_TOGGLE, 100,100,100,255) \
+ NK_COLOR(NK_COLOR_TOGGLE_HOVER, 120,120,120,255) \
+ NK_COLOR(NK_COLOR_TOGGLE_CURSOR, 45, 45, 45, 255) \
+ NK_COLOR(NK_COLOR_SELECT, 45, 45, 45, 255) \
+ NK_COLOR(NK_COLOR_SELECT_ACTIVE, 35, 35, 35,255) \
+ NK_COLOR(NK_COLOR_SLIDER, 38, 38, 38, 255) \
+ NK_COLOR(NK_COLOR_SLIDER_CURSOR, 100,100,100,255) \
+ NK_COLOR(NK_COLOR_SLIDER_CURSOR_HOVER, 120,120,120,255) \
+ NK_COLOR(NK_COLOR_SLIDER_CURSOR_ACTIVE, 150,150,150,255) \
+ NK_COLOR(NK_COLOR_PROPERTY, 38, 38, 38, 255) \
+ NK_COLOR(NK_COLOR_EDIT, 38, 38, 38, 255) \
+ NK_COLOR(NK_COLOR_EDIT_CURSOR, 175,175,175,255) \
+ NK_COLOR(NK_COLOR_COMBO, 45, 45, 45, 255) \
+ NK_COLOR(NK_COLOR_CHART, 120,120,120,255) \
+ NK_COLOR(NK_COLOR_CHART_COLOR, 45, 45, 45, 255) \
+ NK_COLOR(NK_COLOR_CHART_COLOR_HIGHLIGHT,255, 0, 0, 255) \
+ NK_COLOR(NK_COLOR_SCROLLBAR, 40, 40, 40, 255) \
+ NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR, 100,100,100,255) \
+ NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_HOVER,120,120,120,255) \
+ NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_ACTIVE,150,150,150,255) \
+ NK_COLOR(NK_COLOR_TAB_HEADER, 40, 40, 40,255)
+
+NK_GLOBAL const struct nk_color
+nk_default_color_style[NK_COLOR_COUNT] = {
+#define NK_COLOR(a,b,c,d,e) {b,c,d,e},
+ NK_COLOR_MAP(NK_COLOR)
+#undef NK_COLOR
+};
+
+NK_GLOBAL const char *nk_color_names[NK_COLOR_COUNT] = {
+#define NK_COLOR(a,b,c,d,e) #a,
+ NK_COLOR_MAP(NK_COLOR)
+#undef NK_COLOR
+};
+
+NK_API const char *nk_style_get_color_by_name(enum nk_style_colors c)
+{return nk_color_names[c];}
+
+NK_API struct nk_style_item nk_style_item_image(struct nk_image img)
+{struct nk_style_item i; i.type = NK_STYLE_ITEM_IMAGE; i.data.image = img; return i;}
+
+NK_API struct nk_style_item nk_style_item_color(struct nk_color col)
+{struct nk_style_item i; i.type = NK_STYLE_ITEM_COLOR; i.data.color = col; return i;}
+
+NK_API struct nk_style_item nk_style_item_hide(void)
+{struct nk_style_item i; i.type = NK_STYLE_ITEM_COLOR; i.data.color = nk_rgba(0,0,0,0); return i;}
+
+NK_API void
+nk_style_from_table(struct nk_context *ctx, const struct nk_color *table)
+{
+ struct nk_style *style;
+ struct nk_style_text *text;
+ struct nk_style_button *button;
+ struct nk_style_toggle *toggle;
+ struct nk_style_selectable *select;
+ struct nk_style_slider *slider;
+ struct nk_style_progress *prog;
+ struct nk_style_scrollbar *scroll;
+ struct nk_style_edit *edit;
+ struct nk_style_property *property;
+ struct nk_style_combo *combo;
+ struct nk_style_chart *chart;
+ struct nk_style_tab *tab;
+ struct nk_style_window *win;
+
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ style = &ctx->style;
+ table = (!table) ? nk_default_color_style: table;
+
+ /* default text */
+ text = &style->text;
+ text->color = table[NK_COLOR_TEXT];
+ text->padding = nk_vec2(0,0);
+
+ /* default button */
+ button = &style->button;
+ nk_zero_struct(*button);
+ button->normal = nk_style_item_color(table[NK_COLOR_BUTTON]);
+ button->hover = nk_style_item_color(table[NK_COLOR_BUTTON_HOVER]);
+ button->active = nk_style_item_color(table[NK_COLOR_BUTTON_ACTIVE]);
+ button->border_color = table[NK_COLOR_BORDER];
+ button->text_background = table[NK_COLOR_BUTTON];
+ button->text_normal = table[NK_COLOR_TEXT];
+ button->text_hover = table[NK_COLOR_TEXT];
+ button->text_active = table[NK_COLOR_TEXT];
+ button->padding = nk_vec2(2.0f,2.0f);
+ button->image_padding = nk_vec2(0.0f,0.0f);
+ button->touch_padding = nk_vec2(0.0f, 0.0f);
+ button->userdata = nk_handle_ptr(0);
+ button->text_alignment = NK_TEXT_CENTERED;
+ button->border = 1.0f;
+ button->rounding = 4.0f;
+ button->draw_begin = 0;
+ button->draw_end = 0;
+
+ /* contextual button */
+ button = &style->contextual_button;
+ nk_zero_struct(*button);
+ button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
+ button->hover = nk_style_item_color(table[NK_COLOR_BUTTON_HOVER]);
+ button->active = nk_style_item_color(table[NK_COLOR_BUTTON_ACTIVE]);
+ button->border_color = table[NK_COLOR_WINDOW];
+ button->text_background = table[NK_COLOR_WINDOW];
+ button->text_normal = table[NK_COLOR_TEXT];
+ button->text_hover = table[NK_COLOR_TEXT];
+ button->text_active = table[NK_COLOR_TEXT];
+ button->padding = nk_vec2(2.0f,2.0f);
+ button->touch_padding = nk_vec2(0.0f,0.0f);
+ button->userdata = nk_handle_ptr(0);
+ button->text_alignment = NK_TEXT_CENTERED;
+ button->border = 0.0f;
+ button->rounding = 0.0f;
+ button->draw_begin = 0;
+ button->draw_end = 0;
+
+ /* menu button */
+ button = &style->menu_button;
+ nk_zero_struct(*button);
+ button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
+ button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]);
+ button->active = nk_style_item_color(table[NK_COLOR_WINDOW]);
+ button->border_color = table[NK_COLOR_WINDOW];
+ button->text_background = table[NK_COLOR_WINDOW];
+ button->text_normal = table[NK_COLOR_TEXT];
+ button->text_hover = table[NK_COLOR_TEXT];
+ button->text_active = table[NK_COLOR_TEXT];
+ button->padding = nk_vec2(2.0f,2.0f);
+ button->touch_padding = nk_vec2(0.0f,0.0f);
+ button->userdata = nk_handle_ptr(0);
+ button->text_alignment = NK_TEXT_CENTERED;
+ button->border = 0.0f;
+ button->rounding = 1.0f;
+ button->draw_begin = 0;
+ button->draw_end = 0;
+
+ /* checkbox toggle */
+ toggle = &style->checkbox;
+ nk_zero_struct(*toggle);
+ toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]);
+ toggle->hover = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]);
+ toggle->active = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]);
+ toggle->cursor_normal = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]);
+ toggle->cursor_hover = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]);
+ toggle->userdata = nk_handle_ptr(0);
+ toggle->text_background = table[NK_COLOR_WINDOW];
+ toggle->text_normal = table[NK_COLOR_TEXT];
+ toggle->text_hover = table[NK_COLOR_TEXT];
+ toggle->text_active = table[NK_COLOR_TEXT];
+ toggle->padding = nk_vec2(2.0f, 2.0f);
+ toggle->touch_padding = nk_vec2(0,0);
+ toggle->border_color = nk_rgba(0,0,0,0);
+ toggle->border = 0.0f;
+ toggle->spacing = 4;
+
+ /* option toggle */
+ toggle = &style->option;
+ nk_zero_struct(*toggle);
+ toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]);
+ toggle->hover = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]);
+ toggle->active = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]);
+ toggle->cursor_normal = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]);
+ toggle->cursor_hover = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]);
+ toggle->userdata = nk_handle_ptr(0);
+ toggle->text_background = table[NK_COLOR_WINDOW];
+ toggle->text_normal = table[NK_COLOR_TEXT];
+ toggle->text_hover = table[NK_COLOR_TEXT];
+ toggle->text_active = table[NK_COLOR_TEXT];
+ toggle->padding = nk_vec2(3.0f, 3.0f);
+ toggle->touch_padding = nk_vec2(0,0);
+ toggle->border_color = nk_rgba(0,0,0,0);
+ toggle->border = 0.0f;
+ toggle->spacing = 4;
+
+ /* selectable */
+ select = &style->selectable;
+ nk_zero_struct(*select);
+ select->normal = nk_style_item_color(table[NK_COLOR_SELECT]);
+ select->hover = nk_style_item_color(table[NK_COLOR_SELECT]);
+ select->pressed = nk_style_item_color(table[NK_COLOR_SELECT]);
+ select->normal_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]);
+ select->hover_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]);
+ select->pressed_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]);
+ select->text_normal = table[NK_COLOR_TEXT];
+ select->text_hover = table[NK_COLOR_TEXT];
+ select->text_pressed = table[NK_COLOR_TEXT];
+ select->text_normal_active = table[NK_COLOR_TEXT];
+ select->text_hover_active = table[NK_COLOR_TEXT];
+ select->text_pressed_active = table[NK_COLOR_TEXT];
+ select->padding = nk_vec2(2.0f,2.0f);
+ select->touch_padding = nk_vec2(0,0);
+ select->userdata = nk_handle_ptr(0);
+ select->rounding = 0.0f;
+ select->draw_begin = 0;
+ select->draw_end = 0;
+
+ /* slider */
+ slider = &style->slider;
+ nk_zero_struct(*slider);
+ slider->normal = nk_style_item_hide();
+ slider->hover = nk_style_item_hide();
+ slider->active = nk_style_item_hide();
+ slider->bar_normal = table[NK_COLOR_SLIDER];
+ slider->bar_hover = table[NK_COLOR_SLIDER];
+ slider->bar_active = table[NK_COLOR_SLIDER];
+ slider->bar_filled = table[NK_COLOR_SLIDER_CURSOR];
+ slider->cursor_normal = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR]);
+ slider->cursor_hover = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_HOVER]);
+ slider->cursor_active = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_ACTIVE]);
+ slider->inc_symbol = NK_SYMBOL_TRIANGLE_RIGHT;
+ slider->dec_symbol = NK_SYMBOL_TRIANGLE_LEFT;
+ slider->cursor_size = nk_vec2(16,16);
+ slider->padding = nk_vec2(2,2);
+ slider->spacing = nk_vec2(2,2);
+ slider->userdata = nk_handle_ptr(0);
+ slider->show_buttons = nk_false;
+ slider->bar_height = 8;
+ slider->rounding = 0;
+ slider->draw_begin = 0;
+ slider->draw_end = 0;
+
+ /* slider buttons */
+ button = &style->slider.inc_button;
+ button->normal = nk_style_item_color(nk_rgb(40,40,40));
+ button->hover = nk_style_item_color(nk_rgb(42,42,42));
+ button->active = nk_style_item_color(nk_rgb(44,44,44));
+ button->border_color = nk_rgb(65,65,65);
+ button->text_background = nk_rgb(40,40,40);
+ button->text_normal = nk_rgb(175,175,175);
+ button->text_hover = nk_rgb(175,175,175);
+ button->text_active = nk_rgb(175,175,175);
+ button->padding = nk_vec2(8.0f,8.0f);
+ button->touch_padding = nk_vec2(0.0f,0.0f);
+ button->userdata = nk_handle_ptr(0);
+ button->text_alignment = NK_TEXT_CENTERED;
+ button->border = 1.0f;
+ button->rounding = 0.0f;
+ button->draw_begin = 0;
+ button->draw_end = 0;
+ style->slider.dec_button = style->slider.inc_button;
+
+ /* progressbar */
+ prog = &style->progress;
+ nk_zero_struct(*prog);
+ prog->normal = nk_style_item_color(table[NK_COLOR_SLIDER]);
+ prog->hover = nk_style_item_color(table[NK_COLOR_SLIDER]);
+ prog->active = nk_style_item_color(table[NK_COLOR_SLIDER]);
+ prog->cursor_normal = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR]);
+ prog->cursor_hover = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_HOVER]);
+ prog->cursor_active = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_ACTIVE]);
+ prog->border_color = nk_rgba(0,0,0,0);
+ prog->cursor_border_color = nk_rgba(0,0,0,0);
+ prog->userdata = nk_handle_ptr(0);
+ prog->padding = nk_vec2(4,4);
+ prog->rounding = 0;
+ prog->border = 0;
+ prog->cursor_rounding = 0;
+ prog->cursor_border = 0;
+ prog->draw_begin = 0;
+ prog->draw_end = 0;
+
+ /* scrollbars */
+ scroll = &style->scrollh;
+ nk_zero_struct(*scroll);
+ scroll->normal = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
+ scroll->hover = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
+ scroll->active = nk_style_item_color(table[NK_COLOR_SCROLLBAR]);
+ scroll->cursor_normal = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR]);
+ scroll->cursor_hover = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR_HOVER]);
+ scroll->cursor_active = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE]);
+ scroll->dec_symbol = NK_SYMBOL_CIRCLE_SOLID;
+ scroll->inc_symbol = NK_SYMBOL_CIRCLE_SOLID;
+ scroll->userdata = nk_handle_ptr(0);
+ scroll->border_color = table[NK_COLOR_SCROLLBAR];
+ scroll->cursor_border_color = table[NK_COLOR_SCROLLBAR];
+ scroll->padding = nk_vec2(0,0);
+ scroll->show_buttons = nk_false;
+ scroll->border = 0;
+ scroll->rounding = 0;
+ scroll->border_cursor = 0;
+ scroll->rounding_cursor = 0;
+ scroll->draw_begin = 0;
+ scroll->draw_end = 0;
+ style->scrollv = style->scrollh;
+
+ /* scrollbars buttons */
+ button = &style->scrollh.inc_button;
+ button->normal = nk_style_item_color(nk_rgb(40,40,40));
+ button->hover = nk_style_item_color(nk_rgb(42,42,42));
+ button->active = nk_style_item_color(nk_rgb(44,44,44));
+ button->border_color = nk_rgb(65,65,65);
+ button->text_background = nk_rgb(40,40,40);
+ button->text_normal = nk_rgb(175,175,175);
+ button->text_hover = nk_rgb(175,175,175);
+ button->text_active = nk_rgb(175,175,175);
+ button->padding = nk_vec2(4.0f,4.0f);
+ button->touch_padding = nk_vec2(0.0f,0.0f);
+ button->userdata = nk_handle_ptr(0);
+ button->text_alignment = NK_TEXT_CENTERED;
+ button->border = 1.0f;
+ button->rounding = 0.0f;
+ button->draw_begin = 0;
+ button->draw_end = 0;
+ style->scrollh.dec_button = style->scrollh.inc_button;
+ style->scrollv.inc_button = style->scrollh.inc_button;
+ style->scrollv.dec_button = style->scrollh.inc_button;
+
+ /* edit */
+ edit = &style->edit;
+ nk_zero_struct(*edit);
+ edit->normal = nk_style_item_color(table[NK_COLOR_EDIT]);
+ edit->hover = nk_style_item_color(table[NK_COLOR_EDIT]);
+ edit->active = nk_style_item_color(table[NK_COLOR_EDIT]);
+ edit->cursor_normal = table[NK_COLOR_TEXT];
+ edit->cursor_hover = table[NK_COLOR_TEXT];
+ edit->cursor_text_normal= table[NK_COLOR_EDIT];
+ edit->cursor_text_hover = table[NK_COLOR_EDIT];
+ edit->border_color = table[NK_COLOR_BORDER];
+ edit->text_normal = table[NK_COLOR_TEXT];
+ edit->text_hover = table[NK_COLOR_TEXT];
+ edit->text_active = table[NK_COLOR_TEXT];
+ edit->selected_normal = table[NK_COLOR_TEXT];
+ edit->selected_hover = table[NK_COLOR_TEXT];
+ edit->selected_text_normal = table[NK_COLOR_EDIT];
+ edit->selected_text_hover = table[NK_COLOR_EDIT];
+ edit->scrollbar_size = nk_vec2(10,10);
+ edit->scrollbar = style->scrollv;
+ edit->padding = nk_vec2(4,4);
+ edit->row_padding = 2;
+ edit->cursor_size = 4;
+ edit->border = 1;
+ edit->rounding = 0;
+
+ /* property */
+ property = &style->property;
+ nk_zero_struct(*property);
+ property->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
+ property->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
+ property->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
+ property->border_color = table[NK_COLOR_BORDER];
+ property->label_normal = table[NK_COLOR_TEXT];
+ property->label_hover = table[NK_COLOR_TEXT];
+ property->label_active = table[NK_COLOR_TEXT];
+ property->sym_left = NK_SYMBOL_TRIANGLE_LEFT;
+ property->sym_right = NK_SYMBOL_TRIANGLE_RIGHT;
+ property->userdata = nk_handle_ptr(0);
+ property->padding = nk_vec2(4,4);
+ property->border = 1;
+ property->rounding = 10;
+ property->draw_begin = 0;
+ property->draw_end = 0;
+
+ /* property buttons */
+ button = &style->property.dec_button;
+ nk_zero_struct(*button);
+ button->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
+ button->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
+ button->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
+ button->border_color = nk_rgba(0,0,0,0);
+ button->text_background = table[NK_COLOR_PROPERTY];
+ button->text_normal = table[NK_COLOR_TEXT];
+ button->text_hover = table[NK_COLOR_TEXT];
+ button->text_active = table[NK_COLOR_TEXT];
+ button->padding = nk_vec2(0.0f,0.0f);
+ button->touch_padding = nk_vec2(0.0f,0.0f);
+ button->userdata = nk_handle_ptr(0);
+ button->text_alignment = NK_TEXT_CENTERED;
+ button->border = 0.0f;
+ button->rounding = 0.0f;
+ button->draw_begin = 0;
+ button->draw_end = 0;
+ style->property.inc_button = style->property.dec_button;
+
+ /* property edit */
+ edit = &style->property.edit;
+ nk_zero_struct(*edit);
+ edit->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]);
+ edit->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]);
+ edit->active = nk_style_item_color(table[NK_COLOR_PROPERTY]);
+ edit->border_color = nk_rgba(0,0,0,0);
+ edit->cursor_normal = table[NK_COLOR_TEXT];
+ edit->cursor_hover = table[NK_COLOR_TEXT];
+ edit->cursor_text_normal= table[NK_COLOR_EDIT];
+ edit->cursor_text_hover = table[NK_COLOR_EDIT];
+ edit->text_normal = table[NK_COLOR_TEXT];
+ edit->text_hover = table[NK_COLOR_TEXT];
+ edit->text_active = table[NK_COLOR_TEXT];
+ edit->selected_normal = table[NK_COLOR_TEXT];
+ edit->selected_hover = table[NK_COLOR_TEXT];
+ edit->selected_text_normal = table[NK_COLOR_EDIT];
+ edit->selected_text_hover = table[NK_COLOR_EDIT];
+ edit->padding = nk_vec2(0,0);
+ edit->cursor_size = 8;
+ edit->border = 0;
+ edit->rounding = 0;
+
+ /* chart */
+ chart = &style->chart;
+ nk_zero_struct(*chart);
+ chart->background = nk_style_item_color(table[NK_COLOR_CHART]);
+ chart->border_color = table[NK_COLOR_BORDER];
+ chart->selected_color = table[NK_COLOR_CHART_COLOR_HIGHLIGHT];
+ chart->color = table[NK_COLOR_CHART_COLOR];
+ chart->padding = nk_vec2(4,4);
+ chart->border = 0;
+ chart->rounding = 0;
+
+ /* combo */
+ combo = &style->combo;
+ combo->normal = nk_style_item_color(table[NK_COLOR_COMBO]);
+ combo->hover = nk_style_item_color(table[NK_COLOR_COMBO]);
+ combo->active = nk_style_item_color(table[NK_COLOR_COMBO]);
+ combo->border_color = table[NK_COLOR_BORDER];
+ combo->label_normal = table[NK_COLOR_TEXT];
+ combo->label_hover = table[NK_COLOR_TEXT];
+ combo->label_active = table[NK_COLOR_TEXT];
+ combo->sym_normal = NK_SYMBOL_TRIANGLE_DOWN;
+ combo->sym_hover = NK_SYMBOL_TRIANGLE_DOWN;
+ combo->sym_active = NK_SYMBOL_TRIANGLE_DOWN;
+ combo->content_padding = nk_vec2(4,4);
+ combo->button_padding = nk_vec2(0,4);
+ combo->spacing = nk_vec2(4,0);
+ combo->border = 1;
+ combo->rounding = 0;
+
+ /* combo button */
+ button = &style->combo.button;
+ nk_zero_struct(*button);
+ button->normal = nk_style_item_color(table[NK_COLOR_COMBO]);
+ button->hover = nk_style_item_color(table[NK_COLOR_COMBO]);
+ button->active = nk_style_item_color(table[NK_COLOR_COMBO]);
+ button->border_color = nk_rgba(0,0,0,0);
+ button->text_background = table[NK_COLOR_COMBO];
+ button->text_normal = table[NK_COLOR_TEXT];
+ button->text_hover = table[NK_COLOR_TEXT];
+ button->text_active = table[NK_COLOR_TEXT];
+ button->padding = nk_vec2(2.0f,2.0f);
+ button->touch_padding = nk_vec2(0.0f,0.0f);
+ button->userdata = nk_handle_ptr(0);
+ button->text_alignment = NK_TEXT_CENTERED;
+ button->border = 0.0f;
+ button->rounding = 0.0f;
+ button->draw_begin = 0;
+ button->draw_end = 0;
+
+ /* tab */
+ tab = &style->tab;
+ tab->background = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
+ tab->border_color = table[NK_COLOR_BORDER];
+ tab->text = table[NK_COLOR_TEXT];
+ tab->sym_minimize = NK_SYMBOL_TRIANGLE_RIGHT;
+ tab->sym_maximize = NK_SYMBOL_TRIANGLE_DOWN;
+ tab->padding = nk_vec2(4,4);
+ tab->spacing = nk_vec2(4,4);
+ tab->indent = 10.0f;
+ tab->border = 1;
+ tab->rounding = 0;
+
+ /* tab button */
+ button = &style->tab.tab_minimize_button;
+ nk_zero_struct(*button);
+ button->normal = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
+ button->hover = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
+ button->active = nk_style_item_color(table[NK_COLOR_TAB_HEADER]);
+ button->border_color = nk_rgba(0,0,0,0);
+ button->text_background = table[NK_COLOR_TAB_HEADER];
+ button->text_normal = table[NK_COLOR_TEXT];
+ button->text_hover = table[NK_COLOR_TEXT];
+ button->text_active = table[NK_COLOR_TEXT];
+ button->padding = nk_vec2(2.0f,2.0f);
+ button->touch_padding = nk_vec2(0.0f,0.0f);
+ button->userdata = nk_handle_ptr(0);
+ button->text_alignment = NK_TEXT_CENTERED;
+ button->border = 0.0f;
+ button->rounding = 0.0f;
+ button->draw_begin = 0;
+ button->draw_end = 0;
+ style->tab.tab_maximize_button =*button;
+
+ /* node button */
+ button = &style->tab.node_minimize_button;
+ nk_zero_struct(*button);
+ button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]);
+ button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]);
+ button->active = nk_style_item_color(table[NK_COLOR_WINDOW]);
+ button->border_color = nk_rgba(0,0,0,0);
+ button->text_background = table[NK_COLOR_TAB_HEADER];
+ button->text_normal = table[NK_COLOR_TEXT];
+ button->text_hover = table[NK_COLOR_TEXT];
+ button->text_active = table[NK_COLOR_TEXT];
+ button->padding = nk_vec2(2.0f,2.0f);
+ button->touch_padding = nk_vec2(0.0f,0.0f);
+ button->userdata = nk_handle_ptr(0);
+ button->text_alignment = NK_TEXT_CENTERED;
+ button->border = 0.0f;
+ button->rounding = 0.0f;
+ button->draw_begin = 0;
+ button->draw_end = 0;
+ style->tab.node_maximize_button =*button;
+
+ /* window header */
+ win = &style->window;
+ win->header.align = NK_HEADER_RIGHT;
+ win->header.close_symbol = NK_SYMBOL_X;
+ win->header.minimize_symbol = NK_SYMBOL_MINUS;
+ win->header.maximize_symbol = NK_SYMBOL_PLUS;
+ win->header.normal = nk_style_item_color(table[NK_COLOR_HEADER]);
+ win->header.hover = nk_style_item_color(table[NK_COLOR_HEADER]);
+ win->header.active = nk_style_item_color(table[NK_COLOR_HEADER]);
+ win->header.label_normal = table[NK_COLOR_TEXT];
+ win->header.label_hover = table[NK_COLOR_TEXT];
+ win->header.label_active = table[NK_COLOR_TEXT];
+ win->header.label_padding = nk_vec2(4,4);
+ win->header.padding = nk_vec2(4,4);
+ win->header.spacing = nk_vec2(0,0);
+
+ /* window header close button */
+ button = &style->window.header.close_button;
+ nk_zero_struct(*button);
+ button->normal = nk_style_item_color(table[NK_COLOR_HEADER]);
+ button->hover = nk_style_item_color(table[NK_COLOR_HEADER]);
+ button->active = nk_style_item_color(table[NK_COLOR_HEADER]);
+ button->border_color = nk_rgba(0,0,0,0);
+ button->text_background = table[NK_COLOR_HEADER];
+ button->text_normal = table[NK_COLOR_TEXT];
+ button->text_hover = table[NK_COLOR_TEXT];
+ button->text_active = table[NK_COLOR_TEXT];
+ button->padding = nk_vec2(0.0f,0.0f);
+ button->touch_padding = nk_vec2(0.0f,0.0f);
+ button->userdata = nk_handle_ptr(0);
+ button->text_alignment = NK_TEXT_CENTERED;
+ button->border = 0.0f;
+ button->rounding = 0.0f;
+ button->draw_begin = 0;
+ button->draw_end = 0;
+
+ /* window header minimize button */
+ button = &style->window.header.minimize_button;
+ nk_zero_struct(*button);
+ button->normal = nk_style_item_color(table[NK_COLOR_HEADER]);
+ button->hover = nk_style_item_color(table[NK_COLOR_HEADER]);
+ button->active = nk_style_item_color(table[NK_COLOR_HEADER]);
+ button->border_color = nk_rgba(0,0,0,0);
+ button->text_background = table[NK_COLOR_HEADER];
+ button->text_normal = table[NK_COLOR_TEXT];
+ button->text_hover = table[NK_COLOR_TEXT];
+ button->text_active = table[NK_COLOR_TEXT];
+ button->padding = nk_vec2(0.0f,0.0f);
+ button->touch_padding = nk_vec2(0.0f,0.0f);
+ button->userdata = nk_handle_ptr(0);
+ button->text_alignment = NK_TEXT_CENTERED;
+ button->border = 0.0f;
+ button->rounding = 0.0f;
+ button->draw_begin = 0;
+ button->draw_end = 0;
+
+ /* window */
+ win->background = table[NK_COLOR_WINDOW];
+ win->fixed_background = nk_style_item_color(table[NK_COLOR_WINDOW]);
+ win->border_color = table[NK_COLOR_BORDER];
+ win->popup_border_color = table[NK_COLOR_BORDER];
+ win->combo_border_color = table[NK_COLOR_BORDER];
+ win->contextual_border_color = table[NK_COLOR_BORDER];
+ win->menu_border_color = table[NK_COLOR_BORDER];
+ win->group_border_color = table[NK_COLOR_BORDER];
+ win->tooltip_border_color = table[NK_COLOR_BORDER];
+ win->scaler = nk_style_item_color(table[NK_COLOR_TEXT]);
+
+ win->rounding = 0.0f;
+ win->spacing = nk_vec2(4,4);
+ win->scrollbar_size = nk_vec2(10,10);
+ win->min_size = nk_vec2(64,64);
+
+ win->combo_border = 1.0f;
+ win->contextual_border = 1.0f;
+ win->menu_border = 1.0f;
+ win->group_border = 1.0f;
+ win->tooltip_border = 1.0f;
+ win->popup_border = 1.0f;
+ win->border = 2.0f;
+ win->min_row_height_padding = 8;
+
+ win->padding = nk_vec2(4,4);
+ win->group_padding = nk_vec2(4,4);
+ win->popup_padding = nk_vec2(4,4);
+ win->combo_padding = nk_vec2(4,4);
+ win->contextual_padding = nk_vec2(4,4);
+ win->menu_padding = nk_vec2(4,4);
+ win->tooltip_padding = nk_vec2(4,4);
+}
+
+NK_API void
+nk_style_set_font(struct nk_context *ctx, const struct nk_user_font *font)
+{
+ struct nk_style *style;
+ NK_ASSERT(ctx);
+
+ if (!ctx) return;
+ style = &ctx->style;
+ style->font = font;
+ ctx->stacks.fonts.head = 0;
+ if (ctx->current)
+ nk_layout_reset_min_row_height(ctx);
+}
+
+NK_API int
+nk_style_push_font(struct nk_context *ctx, const struct nk_user_font *font)
+{
+ struct nk_config_stack_user_font *font_stack;
+ struct nk_config_stack_user_font_element *element;
+
+ NK_ASSERT(ctx);
+ if (!ctx) return 0;
+
+ font_stack = &ctx->stacks.fonts;
+ NK_ASSERT(font_stack->head < (int)NK_LEN(font_stack->elements));
+ if (font_stack->head >= (int)NK_LEN(font_stack->elements))
+ return 0;
+
+ element = &font_stack->elements[font_stack->head++];
+ element->address = &ctx->style.font;
+ element->old_value = ctx->style.font;
+ ctx->style.font = font;
+ return 1;
+}
+
+NK_API int
+nk_style_pop_font(struct nk_context *ctx)
+{
+ struct nk_config_stack_user_font *font_stack;
+ struct nk_config_stack_user_font_element *element;
+
+ NK_ASSERT(ctx);
+ if (!ctx) return 0;
+
+ font_stack = &ctx->stacks.fonts;
+ NK_ASSERT(font_stack->head > 0);
+ if (font_stack->head < 1)
+ return 0;
+
+ element = &font_stack->elements[--font_stack->head];
+ *element->address = element->old_value;
+ return 1;
+}
+
+#define NK_STYLE_PUSH_IMPLEMENATION(prefix, type, stack) \
+nk_style_push_##type(struct nk_context *ctx, prefix##_##type *address, prefix##_##type value)\
+{\
+ struct nk_config_stack_##type * type_stack;\
+ struct nk_config_stack_##type##_element *element;\
+ NK_ASSERT(ctx);\
+ if (!ctx) return 0;\
+ type_stack = &ctx->stacks.stack;\
+ NK_ASSERT(type_stack->head < (int)NK_LEN(type_stack->elements));\
+ if (type_stack->head >= (int)NK_LEN(type_stack->elements))\
+ return 0;\
+ element = &type_stack->elements[type_stack->head++];\
+ element->address = address;\
+ element->old_value = *address;\
+ *address = value;\
+ return 1;\
+}
+
+#define NK_STYLE_POP_IMPLEMENATION(type, stack) \
+nk_style_pop_##type(struct nk_context *ctx)\
+{\
+ struct nk_config_stack_##type *type_stack;\
+ struct nk_config_stack_##type##_element *element;\
+ NK_ASSERT(ctx);\
+ if (!ctx) return 0;\
+ type_stack = &ctx->stacks.stack;\
+ NK_ASSERT(type_stack->head > 0);\
+ if (type_stack->head < 1)\
+ return 0;\
+ element = &type_stack->elements[--type_stack->head];\
+ *element->address = element->old_value;\
+ return 1;\
+}
+
+NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk, style_item, style_items)
+NK_API int NK_STYLE_PUSH_IMPLEMENATION(nk,float, floats)
+NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk, vec2, vectors)
+NK_API int NK_STYLE_PUSH_IMPLEMENATION(nk,flags, flags)
+NK_API int NK_STYLE_PUSH_IMPLEMENATION(struct nk,color, colors)
+
+NK_API int NK_STYLE_POP_IMPLEMENATION(style_item, style_items)
+NK_API int NK_STYLE_POP_IMPLEMENATION(float,floats)
+NK_API int NK_STYLE_POP_IMPLEMENATION(vec2, vectors)
+NK_API int NK_STYLE_POP_IMPLEMENATION(flags,flags)
+NK_API int NK_STYLE_POP_IMPLEMENATION(color,colors)
+
+NK_API int
+nk_style_set_cursor(struct nk_context *ctx, enum nk_style_cursor c)
+{
+ struct nk_style *style;
+ NK_ASSERT(ctx);
+ if (!ctx) return 0;
+ style = &ctx->style;
+ if (style->cursors[c]) {
+ style->cursor_active = style->cursors[c];
+ return 1;
+ }
+ return 0;
+}
+
+NK_API void
+nk_style_show_cursor(struct nk_context *ctx)
+{
+ ctx->style.cursor_visible = nk_true;
+}
+
+NK_API void
+nk_style_hide_cursor(struct nk_context *ctx)
+{
+ ctx->style.cursor_visible = nk_false;
+}
+
+NK_API void
+nk_style_load_cursor(struct nk_context *ctx, enum nk_style_cursor cursor,
+ const struct nk_cursor *c)
+{
+ struct nk_style *style;
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ style = &ctx->style;
+ style->cursors[cursor] = c;
+}
+
+NK_API void
+nk_style_load_all_cursors(struct nk_context *ctx, struct nk_cursor *cursors)
+{
+ int i = 0;
+ struct nk_style *style;
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ style = &ctx->style;
+ for (i = 0; i < NK_CURSOR_COUNT; ++i)
+ style->cursors[i] = &cursors[i];
+ style->cursor_visible = nk_true;
+}
+
+/* ===============================================================
+ *
+ * POOL
+ *
+ * ===============================================================*/
+NK_INTERN void
+nk_pool_init(struct nk_pool *pool, struct nk_allocator *alloc,
+ unsigned int capacity)
+{
+ nk_zero(pool, sizeof(*pool));
+ pool->alloc = *alloc;
+ pool->capacity = capacity;
+ pool->type = NK_BUFFER_DYNAMIC;
+ pool->pages = 0;
+}
+
+NK_INTERN void
+nk_pool_free(struct nk_pool *pool)
+{
+ struct nk_page *iter = pool->pages;
+ if (!pool) return;
+ if (pool->type == NK_BUFFER_FIXED) return;
+ while (iter) {
+ struct nk_page *next = iter->next;
+ pool->alloc.free(pool->alloc.userdata, iter);
+ iter = next;
+ }
+}
+
+NK_INTERN void
+nk_pool_init_fixed(struct nk_pool *pool, void *memory, nk_size size)
+{
+ nk_zero(pool, sizeof(*pool));
+ NK_ASSERT(size >= sizeof(struct nk_page));
+ if (size < sizeof(struct nk_page)) return;
+ pool->capacity = (unsigned)(size - sizeof(struct nk_page)) / sizeof(struct nk_page_element);
+ pool->pages = (struct nk_page*)memory;
+ pool->type = NK_BUFFER_FIXED;
+ pool->size = size;
+}
+
+NK_INTERN struct nk_page_element*
+nk_pool_alloc(struct nk_pool *pool)
+{
+ if (!pool->pages || pool->pages->size >= pool->capacity) {
+ /* allocate new page */
+ struct nk_page *page;
+ if (pool->type == NK_BUFFER_FIXED) {
+ if (!pool->pages) {
+ NK_ASSERT(pool->pages);
+ return 0;
+ }
+ NK_ASSERT(pool->pages->size < pool->capacity);
+ return 0;
+ } else {
+ nk_size size = sizeof(struct nk_page);
+ size += NK_POOL_DEFAULT_CAPACITY * sizeof(union nk_page_data);
+ page = (struct nk_page*)pool->alloc.alloc(pool->alloc.userdata,0, size);
+ page->next = pool->pages;
+ pool->pages = page;
+ page->size = 0;
+ }
+ }
+ return &pool->pages->win[pool->pages->size++];
+}
+
+/* ===============================================================
+ *
+ * CONTEXT
+ *
+ * ===============================================================*/
+NK_INTERN void* nk_create_window(struct nk_context *ctx);
+NK_INTERN void nk_remove_window(struct nk_context*, struct nk_window*);
+NK_INTERN void nk_free_window(struct nk_context *ctx, struct nk_window *win);
+NK_INTERN void nk_free_table(struct nk_context *ctx, struct nk_table *tbl);
+NK_INTERN void nk_remove_table(struct nk_window *win, struct nk_table *tbl);
+NK_INTERN void* nk_create_panel(struct nk_context *ctx);
+NK_INTERN void nk_free_panel(struct nk_context*, struct nk_panel *pan);
+
+NK_INTERN void
+nk_setup(struct nk_context *ctx, const struct nk_user_font *font)
+{
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ nk_zero_struct(*ctx);
+ nk_style_default(ctx);
+ ctx->seq = 1;
+ if (font) ctx->style.font = font;
+#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+ nk_draw_list_init(&ctx->draw_list);
+#endif
+}
+
+#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR
+NK_API int
+nk_init_default(struct nk_context *ctx, const struct nk_user_font *font)
+{
+ struct nk_allocator alloc;
+ alloc.userdata.ptr = 0;
+ alloc.alloc = nk_malloc;
+ alloc.free = nk_mfree;
+ return nk_init(ctx, &alloc, font);
+}
+#endif
+
+NK_API int
+nk_init_fixed(struct nk_context *ctx, void *memory, nk_size size,
+ const struct nk_user_font *font)
+{
+ NK_ASSERT(memory);
+ if (!memory) return 0;
+ nk_setup(ctx, font);
+ nk_buffer_init_fixed(&ctx->memory, memory, size);
+ ctx->use_pool = nk_false;
+ return 1;
+}
+
+NK_API int
+nk_init_custom(struct nk_context *ctx, struct nk_buffer *cmds,
+ struct nk_buffer *pool, const struct nk_user_font *font)
+{
+ NK_ASSERT(cmds);
+ NK_ASSERT(pool);
+ if (!cmds || !pool) return 0;
+
+ nk_setup(ctx, font);
+ ctx->memory = *cmds;
+ if (pool->type == NK_BUFFER_FIXED) {
+ /* take memory from buffer and alloc fixed pool */
+ nk_pool_init_fixed(&ctx->pool, pool->memory.ptr, pool->memory.size);
+ } else {
+ /* create dynamic pool from buffer allocator */
+ struct nk_allocator *alloc = &pool->pool;
+ nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY);
+ }
+ ctx->use_pool = nk_true;
+ return 1;
+}
+
+NK_API int
+nk_init(struct nk_context *ctx, struct nk_allocator *alloc,
+ const struct nk_user_font *font)
+{
+ NK_ASSERT(alloc);
+ if (!alloc) return 0;
+ nk_setup(ctx, font);
+ nk_buffer_init(&ctx->memory, alloc, NK_DEFAULT_COMMAND_BUFFER_SIZE);
+ nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY);
+ ctx->use_pool = nk_true;
+ return 1;
+}
+
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+NK_API void
+nk_set_user_data(struct nk_context *ctx, nk_handle handle)
+{
+ if (!ctx) return;
+ ctx->userdata = handle;
+ if (ctx->current)
+ ctx->current->buffer.userdata = handle;
+}
+#endif
+
+NK_API void
+nk_free(struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ nk_buffer_free(&ctx->memory);
+ if (ctx->use_pool)
+ nk_pool_free(&ctx->pool);
+
+ nk_zero(&ctx->input, sizeof(ctx->input));
+ nk_zero(&ctx->style, sizeof(ctx->style));
+ nk_zero(&ctx->memory, sizeof(ctx->memory));
+
+ ctx->seq = 0;
+ ctx->build = 0;
+ ctx->begin = 0;
+ ctx->end = 0;
+ ctx->active = 0;
+ ctx->current = 0;
+ ctx->freelist = 0;
+ ctx->count = 0;
+}
+
+NK_API void
+nk_clear(struct nk_context *ctx)
+{
+ struct nk_window *iter;
+ struct nk_window *next;
+ NK_ASSERT(ctx);
+
+ if (!ctx) return;
+ if (ctx->use_pool)
+ nk_buffer_clear(&ctx->memory);
+ else nk_buffer_reset(&ctx->memory, NK_BUFFER_FRONT);
+
+ ctx->build = 0;
+ ctx->memory.calls = 0;
+ ctx->last_widget_state = 0;
+ ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_ARROW];
+ NK_MEMSET(&ctx->overlay, 0, sizeof(ctx->overlay));
+#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT
+ nk_draw_list_clear(&ctx->draw_list);
+#endif
+
+ /* garbage collector */
+ iter = ctx->begin;
+ while (iter) {
+ /* make sure valid minimized windows do not get removed */
+ if ((iter->flags & NK_WINDOW_MINIMIZED) &&
+ !(iter->flags & NK_WINDOW_CLOSED) &&
+ iter->seq == ctx->seq) {
+ iter = iter->next;
+ continue;
+ }
+ /* remove hotness from hidden or closed windows*/
+ if (((iter->flags & NK_WINDOW_HIDDEN) ||
+ (iter->flags & NK_WINDOW_CLOSED)) &&
+ iter == ctx->active) {
+ ctx->active = iter->prev;
+ ctx->end = iter->prev;
+ if (!ctx->end)
+ ctx->begin = 0;
+ if (ctx->active)
+ ctx->active->flags &= ~(unsigned)NK_WINDOW_ROM;
+ }
+ /* free unused popup windows */
+ if (iter->popup.win && iter->popup.win->seq != ctx->seq) {
+ nk_free_window(ctx, iter->popup.win);
+ iter->popup.win = 0;
+ }
+ /* remove unused window state tables */
+ {struct nk_table *n, *it = iter->tables;
+ while (it) {
+ n = it->next;
+ if (it->seq != ctx->seq) {
+ nk_remove_table(iter, it);
+ nk_zero(it, sizeof(union nk_page_data));
+ nk_free_table(ctx, it);
+ if (it == iter->tables)
+ iter->tables = n;
+ } it = n;
+ }}
+ /* window itself is not used anymore so free */
+ if (iter->seq != ctx->seq || iter->flags & NK_WINDOW_CLOSED) {
+ next = iter->next;
+ nk_remove_window(ctx, iter);
+ nk_free_window(ctx, iter);
+ iter = next;
+ } else iter = iter->next;
+ }
+ ctx->seq++;
+}
+
+/* ----------------------------------------------------------------
+ *
+ * BUFFERING
+ *
+ * ---------------------------------------------------------------*/
+NK_INTERN void
+nk_start_buffer(struct nk_context *ctx, struct nk_command_buffer *buffer)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(buffer);
+ if (!ctx || !buffer) return;
+ buffer->begin = ctx->memory.allocated;
+ buffer->end = buffer->begin;
+ buffer->last = buffer->begin;
+ buffer->clip = nk_null_rect;
+}
+
+NK_INTERN void
+nk_start(struct nk_context *ctx, struct nk_window *win)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(win);
+ nk_start_buffer(ctx, &win->buffer);
+}
+
+NK_INTERN void
+nk_start_popup(struct nk_context *ctx, struct nk_window *win)
+{
+ struct nk_popup_buffer *buf;
+ NK_ASSERT(ctx);
+ NK_ASSERT(win);
+ if (!ctx || !win) return;
+
+ /* save buffer fill state for popup */
+ buf = &win->popup.buf;
+ buf->begin = win->buffer.end;
+ buf->end = win->buffer.end;
+ buf->parent = win->buffer.last;
+ buf->last = buf->begin;
+ buf->active = nk_true;
+}
+
+NK_INTERN void
+nk_finish_popup(struct nk_context *ctx, struct nk_window *win)
+{
+ struct nk_popup_buffer *buf;
+ NK_ASSERT(ctx);
+ NK_ASSERT(win);
+ if (!ctx || !win) return;
+
+ buf = &win->popup.buf;
+ buf->last = win->buffer.last;
+ buf->end = win->buffer.end;
+}
+
+NK_INTERN void
+nk_finish_buffer(struct nk_context *ctx, struct nk_command_buffer *buffer)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(buffer);
+ if (!ctx || !buffer) return;
+ buffer->end = ctx->memory.allocated;
+}
+
+NK_INTERN void
+nk_finish(struct nk_context *ctx, struct nk_window *win)
+{
+ struct nk_popup_buffer *buf;
+ struct nk_command *parent_last;
+ void *memory;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(win);
+ if (!ctx || !win) return;
+ nk_finish_buffer(ctx, &win->buffer);
+ if (!win->popup.buf.active) return;
+
+ buf = &win->popup.buf;
+ memory = ctx->memory.memory.ptr;
+ parent_last = nk_ptr_add(struct nk_command, memory, buf->parent);
+ parent_last->next = buf->end;
+}
+
+NK_INTERN void
+nk_build(struct nk_context *ctx)
+{
+ struct nk_window *it = 0;
+ struct nk_command *cmd = 0;
+ nk_byte *buffer = 0;
+
+ /* draw cursor overlay */
+ if (!ctx->style.cursor_active)
+ ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_ARROW];
+ if (ctx->style.cursor_active && !ctx->input.mouse.grabbed && ctx->style.cursor_visible) {
+ struct nk_rect mouse_bounds;
+ const struct nk_cursor *cursor = ctx->style.cursor_active;
+ nk_command_buffer_init(&ctx->overlay, &ctx->memory, NK_CLIPPING_OFF);
+ nk_start_buffer(ctx, &ctx->overlay);
+
+ mouse_bounds.x = ctx->input.mouse.pos.x - cursor->offset.x;
+ mouse_bounds.y = ctx->input.mouse.pos.y - cursor->offset.y;
+ mouse_bounds.w = cursor->size.x;
+ mouse_bounds.h = cursor->size.y;
+
+ nk_draw_image(&ctx->overlay, mouse_bounds, &cursor->img, nk_white);
+ nk_finish_buffer(ctx, &ctx->overlay);
+ }
+ /* build one big draw command list out of all window buffers */
+ it = ctx->begin;
+ buffer = (nk_byte*)ctx->memory.memory.ptr;
+ while (it != 0) {
+ struct nk_window *next = it->next;
+ if (it->buffer.last == it->buffer.begin || (it->flags & NK_WINDOW_HIDDEN)||
+ it->seq != ctx->seq)
+ goto cont;
+
+ cmd = nk_ptr_add(struct nk_command, buffer, it->buffer.last);
+ while (next && ((next->buffer.last == next->buffer.begin) ||
+ (next->flags & NK_WINDOW_HIDDEN)))
+ next = next->next; /* skip empty command buffers */
+
+ if (next) cmd->next = next->buffer.begin;
+ cont: it = next;
+ }
+ /* append all popup draw commands into lists */
+ it = ctx->begin;
+ while (it != 0) {
+ struct nk_window *next = it->next;
+ struct nk_popup_buffer *buf;
+ if (!it->popup.buf.active)
+ goto skip;
+
+ buf = &it->popup.buf;
+ cmd->next = buf->begin;
+ cmd = nk_ptr_add(struct nk_command, buffer, buf->last);
+ buf->active = nk_false;
+ skip: it = next;
+ }
+ if (cmd) {
+ /* append overlay commands */
+ if (ctx->overlay.end != ctx->overlay.begin)
+ cmd->next = ctx->overlay.begin;
+ else cmd->next = ctx->memory.allocated;
+ }
+}
+
+NK_API const struct nk_command*
+nk__begin(struct nk_context *ctx)
+{
+ struct nk_window *iter;
+ nk_byte *buffer;
+ NK_ASSERT(ctx);
+ if (!ctx) return 0;
+ if (!ctx->count) return 0;
+
+ buffer = (nk_byte*)ctx->memory.memory.ptr;
+ if (!ctx->build) {
+ nk_build(ctx);
+ ctx->build = nk_true;
+ }
+ iter = ctx->begin;
+ while (iter && ((iter->buffer.begin == iter->buffer.end) ||
+ (iter->flags & NK_WINDOW_HIDDEN) || iter->seq != ctx->seq))
+ iter = iter->next;
+ if (!iter) return 0;
+ return nk_ptr_add_const(struct nk_command, buffer, iter->buffer.begin);
+}
+
+NK_API const struct nk_command*
+nk__next(struct nk_context *ctx, const struct nk_command *cmd)
+{
+ nk_byte *buffer;
+ const struct nk_command *next;
+ NK_ASSERT(ctx);
+ if (!ctx || !cmd || !ctx->count) return 0;
+ if (cmd->next >= ctx->memory.allocated) return 0;
+ buffer = (nk_byte*)ctx->memory.memory.ptr;
+ next = nk_ptr_add_const(struct nk_command, buffer, cmd->next);
+ return next;
+}
+
+/* ----------------------------------------------------------------
+ *
+ * PANEL
+ *
+ * ---------------------------------------------------------------*/
+static int
+nk_panel_has_header(nk_flags flags, const char *title)
+{
+ int active = 0;
+ active = (flags & (NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE));
+ active = active || (flags & NK_WINDOW_TITLE);
+ active = active && !(flags & NK_WINDOW_HIDDEN) && title;
+ return active;
+}
+
+NK_INTERN struct nk_vec2
+nk_panel_get_padding(const struct nk_style *style, enum nk_panel_type type)
+{
+ switch (type) {
+ default:
+ case NK_PANEL_WINDOW: return style->window.padding;
+ case NK_PANEL_GROUP: return style->window.group_padding;
+ case NK_PANEL_POPUP: return style->window.popup_padding;
+ case NK_PANEL_CONTEXTUAL: return style->window.contextual_padding;
+ case NK_PANEL_COMBO: return style->window.combo_padding;
+ case NK_PANEL_MENU: return style->window.menu_padding;
+ case NK_PANEL_TOOLTIP: return style->window.menu_padding;
+ }
+}
+
+NK_INTERN float
+nk_panel_get_border(const struct nk_style *style, nk_flags flags,
+ enum nk_panel_type type)
+{
+ if (flags & NK_WINDOW_BORDER) {
+ switch (type) {
+ default:
+ case NK_PANEL_WINDOW: return style->window.border;
+ case NK_PANEL_GROUP: return style->window.group_border;
+ case NK_PANEL_POPUP: return style->window.popup_border;
+ case NK_PANEL_CONTEXTUAL: return style->window.contextual_border;
+ case NK_PANEL_COMBO: return style->window.combo_border;
+ case NK_PANEL_MENU: return style->window.menu_border;
+ case NK_PANEL_TOOLTIP: return style->window.menu_border;
+ }} else return 0;
+}
+
+NK_INTERN struct nk_color
+nk_panel_get_border_color(const struct nk_style *style, enum nk_panel_type type)
+{
+ switch (type) {
+ default:
+ case NK_PANEL_WINDOW: return style->window.border_color;
+ case NK_PANEL_GROUP: return style->window.group_border_color;
+ case NK_PANEL_POPUP: return style->window.popup_border_color;
+ case NK_PANEL_CONTEXTUAL: return style->window.contextual_border_color;
+ case NK_PANEL_COMBO: return style->window.combo_border_color;
+ case NK_PANEL_MENU: return style->window.menu_border_color;
+ case NK_PANEL_TOOLTIP: return style->window.menu_border_color;
+ }
+}
+
+NK_INTERN int
+nk_panel_is_sub(enum nk_panel_type type)
+{
+ return (type & NK_PANEL_SET_SUB)?1:0;
+}
+
+NK_INTERN int
+nk_panel_is_nonblock(enum nk_panel_type type)
+{
+ return (type & NK_PANEL_SET_NONBLOCK)?1:0;
+}
+
+NK_INTERN int
+nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type panel_type)
+{
+ struct nk_input *in;
+ struct nk_window *win;
+ struct nk_panel *layout;
+ struct nk_command_buffer *out;
+ const struct nk_style *style;
+ const struct nk_user_font *font;
+
+ struct nk_vec2 scrollbar_size;
+ struct nk_vec2 panel_padding;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout) return 0;
+ nk_zero(ctx->current->layout, sizeof(*ctx->current->layout));
+ if ((ctx->current->flags & NK_WINDOW_HIDDEN) || (ctx->current->flags & NK_WINDOW_CLOSED)) {
+ nk_zero(ctx->current->layout, sizeof(struct nk_panel));
+ ctx->current->layout->type = panel_type;
+ return 0;
+ }
+ /* pull state into local stack */
+ style = &ctx->style;
+ font = style->font;
+ win = ctx->current;
+ layout = win->layout;
+ out = &win->buffer;
+ in = (win->flags & NK_WINDOW_NO_INPUT) ? 0: &ctx->input;
+#ifdef NK_INCLUDE_COMMAND_USERDATA
+ win->buffer.userdata = ctx->userdata;
+#endif
+ /* pull style configuration into local stack */
+ scrollbar_size = style->window.scrollbar_size;
+ panel_padding = nk_panel_get_padding(style, panel_type);
+
+ /* window movement */
+ if ((win->flags & NK_WINDOW_MOVABLE) && !(win->flags & NK_WINDOW_ROM)) {
+ int left_mouse_down;
+ int left_mouse_click_in_cursor;
+
+ /* calculate draggable window space */
+ struct nk_rect header;
+ header.x = win->bounds.x;
+ header.y = win->bounds.y;
+ header.w = win->bounds.w;
+ if (nk_panel_has_header(win->flags, title)) {
+ header.h = font->height + 2.0f * style->window.header.padding.y;
+ header.h += 2.0f * style->window.header.label_padding.y;
+ } else header.h = panel_padding.y;
+
+ /* window movement by dragging */
+ left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
+ left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in,
+ NK_BUTTON_LEFT, header, nk_true);
+ if (left_mouse_down && left_mouse_click_in_cursor) {
+ win->bounds.x = win->bounds.x + in->mouse.delta.x;
+ win->bounds.y = win->bounds.y + in->mouse.delta.y;
+ in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x += in->mouse.delta.x;
+ in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y += in->mouse.delta.y;
+ ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_MOVE];
+ }
+ }
+
+ /* setup panel */
+ layout->type = panel_type;
+ layout->flags = win->flags;
+ layout->bounds = win->bounds;
+ layout->bounds.x += panel_padding.x;
+ layout->bounds.w -= 2*panel_padding.x;
+ if (win->flags & NK_WINDOW_BORDER) {
+ layout->border = nk_panel_get_border(style, win->flags, panel_type);
+ layout->bounds = nk_shrink_rect(layout->bounds, layout->border);
+ } else layout->border = 0;
+ layout->at_y = layout->bounds.y;
+ layout->at_x = layout->bounds.x;
+ layout->max_x = 0;
+ layout->header_height = 0;
+ layout->footer_height = 0;
+ nk_layout_reset_min_row_height(ctx);
+ layout->row.index = 0;
+ layout->row.columns = 0;
+ layout->row.ratio = 0;
+ layout->row.item_width = 0;
+ layout->row.tree_depth = 0;
+ layout->row.height = panel_padding.y;
+ layout->has_scrolling = nk_true;
+ if (!(win->flags & NK_WINDOW_NO_SCROLLBAR))
+ layout->bounds.w -= scrollbar_size.x;
+ if (!nk_panel_is_nonblock(panel_type)) {
+ layout->footer_height = 0;
+ if (!(win->flags & NK_WINDOW_NO_SCROLLBAR) || win->flags & NK_WINDOW_SCALABLE)
+ layout->footer_height = scrollbar_size.y;
+ layout->bounds.h -= layout->footer_height;
+ }
+
+ /* panel header */
+ if (nk_panel_has_header(win->flags, title))
+ {
+ struct nk_text text;
+ struct nk_rect header;
+ const struct nk_style_item *background = 0;
+
+ /* calculate header bounds */
+ header.x = win->bounds.x;
+ header.y = win->bounds.y;
+ header.w = win->bounds.w;
+ header.h = font->height + 2.0f * style->window.header.padding.y;
+ header.h += (2.0f * style->window.header.label_padding.y);
+
+ /* shrink panel by header */
+ layout->header_height = header.h;
+ layout->bounds.y += header.h;
+ layout->bounds.h -= header.h;
+ layout->at_y += header.h;
+
+ /* select correct header background and text color */
+ if (ctx->active == win) {
+ background = &style->window.header.active;
+ text.text = style->window.header.label_active;
+ } else if (nk_input_is_mouse_hovering_rect(&ctx->input, header)) {
+ background = &style->window.header.hover;
+ text.text = style->window.header.label_hover;
+ } else {
+ background = &style->window.header.normal;
+ text.text = style->window.header.label_normal;
+ }
+
+ /* draw header background */
+ header.h += 1.0f;
+ if (background->type == NK_STYLE_ITEM_IMAGE) {
+ text.background = nk_rgba(0,0,0,0);
+ nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
+ } else {
+ text.background = background->data.color;
+ nk_fill_rect(out, header, 0, background->data.color);
+ }
+
+ /* window close button */
+ {struct nk_rect button;
+ button.y = header.y + style->window.header.padding.y;
+ button.h = header.h - 2 * style->window.header.padding.y;
+ button.w = button.h;
+ if (win->flags & NK_WINDOW_CLOSABLE) {
+ nk_flags ws = 0;
+ if (style->window.header.align == NK_HEADER_RIGHT) {
+ button.x = (header.w + header.x) - (button.w + style->window.header.padding.x);
+ header.w -= button.w + style->window.header.spacing.x + style->window.header.padding.x;
+ } else {
+ button.x = header.x + style->window.header.padding.x;
+ header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x;
+ }
+
+ if (nk_do_button_symbol(&ws, &win->buffer, button,
+ style->window.header.close_symbol, NK_BUTTON_DEFAULT,
+ &style->window.header.close_button, in, style->font) && !(win->flags & NK_WINDOW_ROM))
+ {
+ layout->flags |= NK_WINDOW_HIDDEN;
+ layout->flags &= (nk_flags)~NK_WINDOW_MINIMIZED;
+ }
+ }
+
+ /* window minimize button */
+ if (win->flags & NK_WINDOW_MINIMIZABLE) {
+ nk_flags ws = 0;
+ if (style->window.header.align == NK_HEADER_RIGHT) {
+ button.x = (header.w + header.x) - button.w;
+ if (!(win->flags & NK_WINDOW_CLOSABLE)) {
+ button.x -= style->window.header.padding.x;
+ header.w -= style->window.header.padding.x;
+ }
+ header.w -= button.w + style->window.header.spacing.x;
+ } else {
+ button.x = header.x;
+ header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x;
+ }
+ if (nk_do_button_symbol(&ws, &win->buffer, button, (layout->flags & NK_WINDOW_MINIMIZED)?
+ style->window.header.maximize_symbol: style->window.header.minimize_symbol,
+ NK_BUTTON_DEFAULT, &style->window.header.minimize_button, in, style->font) && !(win->flags & NK_WINDOW_ROM))
+ layout->flags = (layout->flags & NK_WINDOW_MINIMIZED) ?
+ layout->flags & (nk_flags)~NK_WINDOW_MINIMIZED:
+ layout->flags | NK_WINDOW_MINIMIZED;
+ }}
+
+ {/* window header title */
+ int text_len = nk_strlen(title);
+ struct nk_rect label = {0,0,0,0};
+ float t = font->width(font->userdata, font->height, title, text_len);
+ text.padding = nk_vec2(0,0);
+
+ label.x = header.x + style->window.header.padding.x;
+ label.x += style->window.header.label_padding.x;
+ label.y = header.y + style->window.header.label_padding.y;
+ label.h = font->height + 2 * style->window.header.label_padding.y;
+ label.w = t + 2 * style->window.header.spacing.x;
+ label.w = NK_CLAMP(0, label.w, header.x + header.w - label.x);
+ nk_widget_text(out, label,(const char*)title, text_len, &text, NK_TEXT_LEFT, font);}
+ }
+
+ /* draw window background */
+ if (!(layout->flags & NK_WINDOW_MINIMIZED) && !(layout->flags & NK_WINDOW_DYNAMIC)) {
+ struct nk_rect body;
+ body.x = win->bounds.x;
+ body.w = win->bounds.w;
+ body.y = (win->bounds.y + layout->header_height);
+ body.h = (win->bounds.h - layout->header_height);
+ if (style->window.fixed_background.type == NK_STYLE_ITEM_IMAGE)
+ nk_draw_image(out, body, &style->window.fixed_background.data.image, nk_white);
+ else nk_fill_rect(out, body, 0, style->window.fixed_background.data.color);
+ }
+
+ /* set clipping rectangle */
+ {struct nk_rect clip;
+ layout->clip = layout->bounds;
+ nk_unify(&clip, &win->buffer.clip, layout->clip.x, layout->clip.y,
+ layout->clip.x + layout->clip.w, layout->clip.y + layout->clip.h);
+ nk_push_scissor(out, clip);
+ layout->clip = clip;}
+ return !(layout->flags & NK_WINDOW_HIDDEN) && !(layout->flags & NK_WINDOW_MINIMIZED);
+}
+
+NK_INTERN void
+nk_panel_end(struct nk_context *ctx)
+{
+ struct nk_input *in;
+ struct nk_window *window;
+ struct nk_panel *layout;
+ const struct nk_style *style;
+ struct nk_command_buffer *out;
+
+ struct nk_vec2 scrollbar_size;
+ struct nk_vec2 panel_padding;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ window = ctx->current;
+ layout = window->layout;
+ style = &ctx->style;
+ out = &window->buffer;
+ in = (layout->flags & NK_WINDOW_ROM || layout->flags & NK_WINDOW_NO_INPUT) ? 0 :&ctx->input;
+ if (!nk_panel_is_sub(layout->type))
+ nk_push_scissor(out, nk_null_rect);
+
+ /* cache configuration data */
+ scrollbar_size = style->window.scrollbar_size;
+ panel_padding = nk_panel_get_padding(style, layout->type);
+
+ /* update the current cursor Y-position to point over the last added widget */
+ layout->at_y += layout->row.height;
+
+ /* dynamic panels */
+ if (layout->flags & NK_WINDOW_DYNAMIC && !(layout->flags & NK_WINDOW_MINIMIZED))
+ {
+ /* update panel height to fit dynamic growth */
+ struct nk_rect empty_space;
+ if (layout->at_y < (layout->bounds.y + layout->bounds.h))
+ layout->bounds.h = layout->at_y - layout->bounds.y;
+
+ /* fill top empty space */
+ empty_space.x = window->bounds.x;
+ empty_space.y = layout->bounds.y;
+ empty_space.h = panel_padding.y;
+ empty_space.w = window->bounds.w;
+ nk_fill_rect(out, empty_space, 0, style->window.background);
+
+ /* fill left empty space */
+ empty_space.x = window->bounds.x;
+ empty_space.y = layout->bounds.y;
+ empty_space.w = panel_padding.x + layout->border;
+ empty_space.h = layout->bounds.h;
+ nk_fill_rect(out, empty_space, 0, style->window.background);
+
+ /* fill right empty space */
+ empty_space.x = layout->bounds.x + layout->bounds.w - layout->border;
+ empty_space.y = layout->bounds.y;
+ empty_space.w = panel_padding.x + layout->border;
+ empty_space.h = layout->bounds.h;
+ if (*layout->offset_y == 0 && !(layout->flags & NK_WINDOW_NO_SCROLLBAR))
+ empty_space.w += scrollbar_size.x;
+ nk_fill_rect(out, empty_space, 0, style->window.background);
+
+ /* fill bottom empty space */
+ if (*layout->offset_x != 0 && !(layout->flags & NK_WINDOW_NO_SCROLLBAR)) {
+ empty_space.x = window->bounds.x;
+ empty_space.y = layout->bounds.y + layout->bounds.h;
+ empty_space.w = window->bounds.w;
+ empty_space.h = scrollbar_size.y;
+ nk_fill_rect(out, empty_space, 0, style->window.background);
+ }
+ }
+
+ /* scrollbars */
+ if (!(layout->flags & NK_WINDOW_NO_SCROLLBAR) &&
+ !(layout->flags & NK_WINDOW_MINIMIZED) &&
+ window->scrollbar_hiding_timer < NK_SCROLLBAR_HIDING_TIMEOUT)
+ {
+ struct nk_rect scroll;
+ int scroll_has_scrolling;
+ float scroll_target;
+ float scroll_offset;
+ float scroll_step;
+ float scroll_inc;
+
+ /* mouse wheel scrolling */
+ if (nk_panel_is_sub(layout->type))
+ {
+ /* sub-window mouse wheel scrolling */
+ struct nk_window *root_window = window;
+ struct nk_panel *root_panel = window->layout;
+ while (root_panel->parent)
+ root_panel = root_panel->parent;
+ while (root_window->parent)
+ root_window = root_window->parent;
+
+ /* only allow scrolling if parent window is active */
+ scroll_has_scrolling = 0;
+ if ((root_window == ctx->active) && layout->has_scrolling) {
+ /* and panel is being hovered and inside clip rect*/
+ if (nk_input_is_mouse_hovering_rect(in, layout->bounds) &&
+ NK_INTERSECT(layout->bounds.x, layout->bounds.y, layout->bounds.w, layout->bounds.h,
+ root_panel->clip.x, root_panel->clip.y, root_panel->clip.w, root_panel->clip.h))
+ {
+ /* deactivate all parent scrolling */
+ root_panel = window->layout;
+ while (root_panel->parent) {
+ root_panel->has_scrolling = nk_false;
+ root_panel = root_panel->parent;
+ }
+ root_panel->has_scrolling = nk_false;
+ scroll_has_scrolling = nk_true;
+ }
+ }
+ } else if (!nk_panel_is_sub(layout->type)) {
+ /* window mouse wheel scrolling */
+ scroll_has_scrolling = (window == ctx->active) && layout->has_scrolling;
+ if (in && (in->mouse.scroll_delta.y > 0 || in->mouse.scroll_delta.x > 0) && scroll_has_scrolling)
+ window->scrolled = nk_true;
+ else window->scrolled = nk_false;
+ } else scroll_has_scrolling = nk_false;
+
+ {
+ /* vertical scrollbar */
+ nk_flags state = 0;
+ scroll.x = layout->bounds.x + layout->bounds.w + panel_padding.x;
+ scroll.y = layout->bounds.y;
+ scroll.w = scrollbar_size.x;
+ scroll.h = layout->bounds.h;
+
+ scroll_offset = (float)*layout->offset_y;
+ scroll_step = scroll.h * 0.10f;
+ scroll_inc = scroll.h * 0.01f;
+ scroll_target = (float)(int)(layout->at_y - scroll.y);
+ scroll_offset = nk_do_scrollbarv(&state, out, scroll, scroll_has_scrolling,
+ scroll_offset, scroll_target, scroll_step, scroll_inc,
+ &ctx->style.scrollv, in, style->font);
+ *layout->offset_y = (nk_uint)scroll_offset;
+ if (in && scroll_has_scrolling)
+ in->mouse.scroll_delta.y = 0;
+ }
+ {
+ /* horizontal scrollbar */
+ nk_flags state = 0;
+ scroll.x = layout->bounds.x;
+ scroll.y = layout->bounds.y + layout->bounds.h;
+ scroll.w = layout->bounds.w;
+ scroll.h = scrollbar_size.y;
+
+ scroll_offset = (float)*layout->offset_x;
+ scroll_target = (float)(int)(layout->max_x - scroll.x);
+ scroll_step = layout->max_x * 0.05f;
+ scroll_inc = layout->max_x * 0.005f;
+ scroll_offset = nk_do_scrollbarh(&state, out, scroll, scroll_has_scrolling,
+ scroll_offset, scroll_target, scroll_step, scroll_inc,
+ &ctx->style.scrollh, in, style->font);
+ *layout->offset_x = (nk_uint)scroll_offset;
+ }
+ }
+
+ /* hide scroll if no user input */
+ if (window->flags & NK_WINDOW_SCROLL_AUTO_HIDE) {
+ int has_input = ctx->input.mouse.delta.x != 0 || ctx->input.mouse.delta.y != 0 || ctx->input.mouse.scroll_delta.y != 0;
+ int is_window_hovered = nk_window_is_hovered(ctx);
+ int any_item_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED);
+ if ((!has_input && is_window_hovered) || (!is_window_hovered && !any_item_active))
+ window->scrollbar_hiding_timer += ctx->delta_time_seconds;
+ else window->scrollbar_hiding_timer = 0;
+ } else window->scrollbar_hiding_timer = 0;
+
+ /* window border */
+ if (layout->flags & NK_WINDOW_BORDER)
+ {
+ struct nk_color border_color = nk_panel_get_border_color(style, layout->type);
+ const float padding_y = (layout->flags & NK_WINDOW_MINIMIZED)
+ ? (style->window.border + window->bounds.y + layout->header_height)
+ : ((layout->flags & NK_WINDOW_DYNAMIC)
+ ? (layout->bounds.y + layout->bounds.h + layout->footer_height)
+ : (window->bounds.y + window->bounds.h));
+ struct nk_rect b = window->bounds;
+ b.h = padding_y - window->bounds.y;
+ nk_stroke_rect(out, b, 0, layout->border, border_color);
+ }
+
+ /* scaler */
+ if ((layout->flags & NK_WINDOW_SCALABLE) && in && !(layout->flags & NK_WINDOW_MINIMIZED))
+ {
+ /* calculate scaler bounds */
+ struct nk_rect scaler;
+ scaler.w = scrollbar_size.x;
+ scaler.h = scrollbar_size.y;
+ scaler.y = layout->bounds.y + layout->bounds.h;
+ if (layout->flags & NK_WINDOW_SCALE_LEFT)
+ scaler.x = layout->bounds.x - panel_padding.x * 0.5f;
+ else scaler.x = layout->bounds.x + layout->bounds.w + panel_padding.x;
+ if (layout->flags & NK_WINDOW_NO_SCROLLBAR)
+ scaler.x -= scaler.w;
+
+ /* draw scaler */
+ {const struct nk_style_item *item = &style->window.scaler;
+ if (item->type == NK_STYLE_ITEM_IMAGE)
+ nk_draw_image(out, scaler, &item->data.image, nk_white);
+ else {
+ if (layout->flags & NK_WINDOW_SCALE_LEFT) {
+ nk_fill_triangle(out, scaler.x, scaler.y, scaler.x,
+ scaler.y + scaler.h, scaler.x + scaler.w,
+ scaler.y + scaler.h, item->data.color);
+ } else {
+ nk_fill_triangle(out, scaler.x + scaler.w, scaler.y, scaler.x + scaler.w,
+ scaler.y + scaler.h, scaler.x, scaler.y + scaler.h, item->data.color);
+ }
+ }}
+
+ /* do window scaling */
+ if (!(window->flags & NK_WINDOW_ROM)) {
+ struct nk_vec2 window_size = style->window.min_size;
+ int left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down;
+ int left_mouse_click_in_scaler = nk_input_has_mouse_click_down_in_rect(in,
+ NK_BUTTON_LEFT, scaler, nk_true);
+
+ if (left_mouse_down && left_mouse_click_in_scaler) {
+ float delta_x = in->mouse.delta.x;
+ if (layout->flags & NK_WINDOW_SCALE_LEFT) {
+ delta_x = -delta_x;
+ window->bounds.x += in->mouse.delta.x;
+ }
+ /* dragging in x-direction */
+ if (window->bounds.w + delta_x >= window_size.x) {
+ if ((delta_x < 0) || (delta_x > 0 && in->mouse.pos.x >= scaler.x)) {
+ window->bounds.w = window->bounds.w + delta_x;
+ scaler.x += in->mouse.delta.x;
+ }
+ }
+ /* dragging in y-direction (only possible if static window) */
+ if (!(layout->flags & NK_WINDOW_DYNAMIC)) {
+ if (window_size.y < window->bounds.h + in->mouse.delta.y) {
+ if ((in->mouse.delta.y < 0) || (in->mouse.delta.y > 0 && in->mouse.pos.y >= scaler.y)) {
+ window->bounds.h = window->bounds.h + in->mouse.delta.y;
+ scaler.y += in->mouse.delta.y;
+ }
+ }
+ }
+ ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT];
+ in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = scaler.x + scaler.w/2.0f;
+ in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = scaler.y + scaler.h/2.0f;
+ }
+ }
+ }
+ if (!nk_panel_is_sub(layout->type)) {
+ /* window is hidden so clear command buffer */
+ if (layout->flags & NK_WINDOW_HIDDEN)
+ nk_command_buffer_reset(&window->buffer);
+ /* window is visible and not tab */
+ else nk_finish(ctx, window);
+ }
+
+ /* NK_WINDOW_REMOVE_ROM flag was set so remove NK_WINDOW_ROM */
+ if (layout->flags & NK_WINDOW_REMOVE_ROM) {
+ layout->flags &= ~(nk_flags)NK_WINDOW_ROM;
+ layout->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM;
+ }
+ window->flags = layout->flags;
+
+ /* property garbage collector */
+ if (window->property.active && window->property.old != window->property.seq &&
+ window->property.active == window->property.prev) {
+ nk_zero(&window->property, sizeof(window->property));
+ } else {
+ window->property.old = window->property.seq;
+ window->property.prev = window->property.active;
+ window->property.seq = 0;
+ }
+ /* edit garbage collector */
+ if (window->edit.active && window->edit.old != window->edit.seq &&
+ window->edit.active == window->edit.prev) {
+ nk_zero(&window->edit, sizeof(window->edit));
+ } else {
+ window->edit.old = window->edit.seq;
+ window->edit.prev = window->edit.active;
+ window->edit.seq = 0;
+ }
+ /* contextual garbage collector */
+ if (window->popup.active_con && window->popup.con_old != window->popup.con_count) {
+ window->popup.con_count = 0;
+ window->popup.con_old = 0;
+ window->popup.active_con = 0;
+ } else {
+ window->popup.con_old = window->popup.con_count;
+ window->popup.con_count = 0;
+ }
+ window->popup.combo_count = 0;
+ /* helper to make sure you have a 'nk_tree_push' for every 'nk_tree_pop' */
+ NK_ASSERT(!layout->row.tree_depth);
+}
+
+/* ----------------------------------------------------------------
+ *
+ * PAGE ELEMENT
+ *
+ * ---------------------------------------------------------------*/
+NK_INTERN struct nk_page_element*
+nk_create_page_element(struct nk_context *ctx)
+{
+ struct nk_page_element *elem;
+ if (ctx->freelist) {
+ /* unlink page element from free list */
+ elem = ctx->freelist;
+ ctx->freelist = elem->next;
+ } else if (ctx->use_pool) {
+ /* allocate page element from memory pool */
+ elem = nk_pool_alloc(&ctx->pool);
+ NK_ASSERT(elem);
+ if (!elem) return 0;
+ } else {
+ /* allocate new page element from back of fixed size memory buffer */
+ NK_STORAGE const nk_size size = sizeof(struct nk_page_element);
+ NK_STORAGE const nk_size align = NK_ALIGNOF(struct nk_page_element);
+ elem = (struct nk_page_element*)nk_buffer_alloc(&ctx->memory, NK_BUFFER_BACK, size, align);
+ NK_ASSERT(elem);
+ if (!elem) return 0;
+ }
+ nk_zero_struct(*elem);
+ elem->next = 0;
+ elem->prev = 0;
+ return elem;
+}
+
+NK_INTERN void
+nk_link_page_element_into_freelist(struct nk_context *ctx,
+ struct nk_page_element *elem)
+{
+ /* link table into freelist */
+ if (!ctx->freelist) {
+ ctx->freelist = elem;
+ } else {
+ elem->next = ctx->freelist;
+ ctx->freelist = elem;
+ }
+}
+
+NK_INTERN void
+nk_free_page_element(struct nk_context *ctx, struct nk_page_element *elem)
+{
+ /* we have a pool so just add to free list */
+ if (ctx->use_pool) {
+ nk_link_page_element_into_freelist(ctx, elem);
+ return;
+ }
+ /* if possible remove last element from back of fixed memory buffer */
+ {void *elem_end = (void*)(elem + 1);
+ void *buffer_end = (nk_byte*)ctx->memory.memory.ptr + ctx->memory.size;
+ if (elem_end == buffer_end)
+ ctx->memory.size -= sizeof(struct nk_page_element);
+ else nk_link_page_element_into_freelist(ctx, elem);}
+}
+
+/* ----------------------------------------------------------------
+ *
+ * PANEL
+ *
+ * ---------------------------------------------------------------*/
+NK_INTERN void*
+nk_create_panel(struct nk_context *ctx)
+{
+ struct nk_page_element *elem;
+ elem = nk_create_page_element(ctx);
+ if (!elem) return 0;
+ nk_zero_struct(*elem);
+ return &elem->data.pan;
+}
+
+NK_INTERN void
+nk_free_panel(struct nk_context *ctx, struct nk_panel *pan)
+{
+ union nk_page_data *pd = NK_CONTAINER_OF(pan, union nk_page_data, pan);
+ struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data);
+ nk_free_page_element(ctx, pe);
+}
+
+/* ----------------------------------------------------------------
+ *
+ * TABLES
+ *
+ * ---------------------------------------------------------------*/
+NK_INTERN struct nk_table*
+nk_create_table(struct nk_context *ctx)
+{
+ struct nk_page_element *elem;
+ elem = nk_create_page_element(ctx);
+ if (!elem) return 0;
+ nk_zero_struct(*elem);
+ return &elem->data.tbl;
+}
+
+NK_INTERN void
+nk_free_table(struct nk_context *ctx, struct nk_table *tbl)
+{
+ union nk_page_data *pd = NK_CONTAINER_OF(tbl, union nk_page_data, tbl);
+ struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data);
+ nk_free_page_element(ctx, pe);
+}
+
+NK_INTERN void
+nk_push_table(struct nk_window *win, struct nk_table *tbl)
+{
+ if (!win->tables) {
+ win->tables = tbl;
+ tbl->next = 0;
+ tbl->prev = 0;
+ tbl->size = 0;
+ win->table_count = 1;
+ return;
+ }
+ win->tables->prev = tbl;
+ tbl->next = win->tables;
+ tbl->prev = 0;
+ tbl->size = 0;
+ win->tables = tbl;
+ win->table_count++;
+}
+
+NK_INTERN void
+nk_remove_table(struct nk_window *win, struct nk_table *tbl)
+{
+ if (win->tables == tbl)
+ win->tables = tbl->next;
+ if (tbl->next)
+ tbl->next->prev = tbl->prev;
+ if (tbl->prev)
+ tbl->prev->next = tbl->next;
+ tbl->next = 0;
+ tbl->prev = 0;
+}
+
+NK_INTERN nk_uint*
+nk_add_value(struct nk_context *ctx, struct nk_window *win,
+ nk_hash name, nk_uint value)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(win);
+ if (!win || !ctx) return 0;
+ if (!win->tables || win->tables->size >= NK_VALUE_PAGE_CAPACITY) {
+ struct nk_table *tbl = nk_create_table(ctx);
+ NK_ASSERT(tbl);
+ if (!tbl) return 0;
+ nk_push_table(win, tbl);
+ }
+ win->tables->seq = win->seq;
+ win->tables->keys[win->tables->size] = name;
+ win->tables->values[win->tables->size] = value;
+ return &win->tables->values[win->tables->size++];
+}
+
+NK_INTERN nk_uint*
+nk_find_value(struct nk_window *win, nk_hash name)
+{
+ struct nk_table *iter = win->tables;
+ while (iter) {
+ unsigned int i = 0;
+ unsigned int size = iter->size;
+ for (i = 0; i < size; ++i) {
+ if (iter->keys[i] == name) {
+ iter->seq = win->seq;
+ return &iter->values[i];
+ }
+ } size = NK_VALUE_PAGE_CAPACITY;
+ iter = iter->next;
+ }
+ return 0;
+}
+
+/* ----------------------------------------------------------------
+ *
+ * WINDOW
+ *
+ * ---------------------------------------------------------------*/
+NK_INTERN void*
+nk_create_window(struct nk_context *ctx)
+{
+ struct nk_page_element *elem;
+ elem = nk_create_page_element(ctx);
+ if (!elem) return 0;
+ elem->data.win.seq = ctx->seq;
+ return &elem->data.win;
+}
+
+NK_INTERN void
+nk_free_window(struct nk_context *ctx, struct nk_window *win)
+{
+ /* unlink windows from list */
+ struct nk_table *it = win->tables;
+ if (win->popup.win) {
+ nk_free_window(ctx, win->popup.win);
+ win->popup.win = 0;
+ }
+ win->next = 0;
+ win->prev = 0;
+
+ while (it) {
+ /*free window state tables */
+ struct nk_table *n = it->next;
+ nk_remove_table(win, it);
+ nk_free_table(ctx, it);
+ if (it == win->tables)
+ win->tables = n;
+ it = n;
+ }
+
+ /* link windows into freelist */
+ {union nk_page_data *pd = NK_CONTAINER_OF(win, union nk_page_data, win);
+ struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data);
+ nk_free_page_element(ctx, pe);}
+}
+
+NK_INTERN struct nk_window*
+nk_find_window(struct nk_context *ctx, nk_hash hash, const char *name)
+{
+ struct nk_window *iter;
+ iter = ctx->begin;
+ while (iter) {
+ NK_ASSERT(iter != iter->next);
+ if (iter->name == hash) {
+ int max_len = nk_strlen(iter->name_string);
+ if (!nk_stricmpn(iter->name_string, name, max_len))
+ return iter;
+ }
+ iter = iter->next;
+ }
+ return 0;
+}
+
+enum nk_window_insert_location {
+ NK_INSERT_BACK, /* inserts window into the back of list (front of screen) */
+ NK_INSERT_FRONT /* inserts window into the front of list (back of screen) */
+};
+NK_INTERN void
+nk_insert_window(struct nk_context *ctx, struct nk_window *win,
+ enum nk_window_insert_location loc)
+{
+ const struct nk_window *iter;
+ NK_ASSERT(ctx);
+ NK_ASSERT(win);
+ if (!win || !ctx) return;
+
+ iter = ctx->begin;
+ while (iter) {
+ NK_ASSERT(iter != iter->next);
+ NK_ASSERT(iter != win);
+ if (iter == win) return;
+ iter = iter->next;
+ }
+
+ if (!ctx->begin) {
+ win->next = 0;
+ win->prev = 0;
+ ctx->begin = win;
+ ctx->end = win;
+ ctx->count = 1;
+ return;
+ }
+ if (loc == NK_INSERT_BACK) {
+ struct nk_window *end;
+ end = ctx->end;
+ end->flags |= NK_WINDOW_ROM;
+ end->next = win;
+ win->prev = ctx->end;
+ win->next = 0;
+ ctx->end = win;
+ ctx->active = ctx->end;
+ ctx->end->flags &= ~(nk_flags)NK_WINDOW_ROM;
+ } else {
+ /*ctx->end->flags |= NK_WINDOW_ROM;*/
+ ctx->begin->prev = win;
+ win->next = ctx->begin;
+ win->prev = 0;
+ ctx->begin = win;
+ ctx->begin->flags &= ~(nk_flags)NK_WINDOW_ROM;
+ }
+ ctx->count++;
+}
+
+NK_INTERN void
+nk_remove_window(struct nk_context *ctx, struct nk_window *win)
+{
+ if (win == ctx->begin || win == ctx->end) {
+ if (win == ctx->begin) {
+ ctx->begin = win->next;
+ if (win->next)
+ win->next->prev = 0;
+ }
+ if (win == ctx->end) {
+ ctx->end = win->prev;
+ if (win->prev)
+ win->prev->next = 0;
+ }
+ } else {
+ if (win->next)
+ win->next->prev = win->prev;
+ if (win->prev)
+ win->prev->next = win->next;
+ }
+ if (win == ctx->active || !ctx->active) {
+ ctx->active = ctx->end;
+ if (ctx->end)
+ ctx->end->flags &= ~(nk_flags)NK_WINDOW_ROM;
+ }
+ win->next = 0;
+ win->prev = 0;
+ ctx->count--;
+}
+
+NK_API int
+nk_begin(struct nk_context *ctx, const char *title,
+ struct nk_rect bounds, nk_flags flags)
+{
+ return nk_begin_titled(ctx, title, title, bounds, flags);
+}
+
+NK_API int
+nk_begin_titled(struct nk_context *ctx, const char *name, const char *title,
+ struct nk_rect bounds, nk_flags flags)
+{
+ struct nk_window *win;
+ struct nk_style *style;
+ nk_hash title_hash;
+ int title_len;
+ int ret = 0;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(name);
+ NK_ASSERT(title);
+ NK_ASSERT(ctx->style.font && ctx->style.font->width && "if this triggers you forgot to add a font");
+ NK_ASSERT(!ctx->current && "if this triggers you missed a `nk_end` call");
+ if (!ctx || ctx->current || !title || !name)
+ return 0;
+
+ /* find or create window */
+ style = &ctx->style;
+ title_len = (int)nk_strlen(name);
+ title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
+ win = nk_find_window(ctx, title_hash, name);
+ if (!win) {
+ /* create new window */
+ nk_size name_length = (nk_size)nk_strlen(name);
+ win = (struct nk_window*)nk_create_window(ctx);
+ NK_ASSERT(win);
+ if (!win) return 0;
+
+ if (flags & NK_WINDOW_BACKGROUND)
+ nk_insert_window(ctx, win, NK_INSERT_FRONT);
+ else nk_insert_window(ctx, win, NK_INSERT_BACK);
+ nk_command_buffer_init(&win->buffer, &ctx->memory, NK_CLIPPING_ON);
+
+ win->flags = flags;
+ win->bounds = bounds;
+ win->name = title_hash;
+ name_length = NK_MIN(name_length, NK_WINDOW_MAX_NAME-1);
+ NK_MEMCPY(win->name_string, name, name_length);
+ win->name_string[name_length] = 0;
+ win->popup.win = 0;
+ if (!ctx->active)
+ ctx->active = win;
+ } else {
+ /* update window */
+ win->flags &= ~(nk_flags)(NK_WINDOW_PRIVATE-1);
+ win->flags |= flags;
+ if (!(win->flags & (NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE)))
+ win->bounds = bounds;
+ /* If this assert triggers you either:
+ *
+ * I.) Have more than one window with the same name or
+ * II.) You forgot to actually draw the window.
+ * More specific you did not call `nk_clear` (nk_clear will be
+ * automatically called for you if you are using one of the
+ * provided demo backends). */
+ NK_ASSERT(win->seq != ctx->seq);
+ win->seq = ctx->seq;
+ if (!ctx->active && !(win->flags & NK_WINDOW_HIDDEN)) {
+ ctx->active = win;
+ ctx->end = win;
+ }
+ }
+ if (win->flags & NK_WINDOW_HIDDEN) {
+ ctx->current = win;
+ win->layout = 0;
+ return 0;
+ } else nk_start(ctx, win);
+
+ /* window overlapping */
+ if (!(win->flags & NK_WINDOW_HIDDEN) && !(win->flags & NK_WINDOW_NO_INPUT))
+ {
+ int inpanel, ishovered;
+ struct nk_window *iter = win;
+ float h = ctx->style.font->height + 2.0f * style->window.header.padding.y +
+ (2.0f * style->window.header.label_padding.y);
+ struct nk_rect win_bounds = (!(win->flags & NK_WINDOW_MINIMIZED))?
+ win->bounds: nk_rect(win->bounds.x, win->bounds.y, win->bounds.w, h);
+
+ /* activate window if hovered and no other window is overlapping this window */
+ inpanel = nk_input_has_mouse_click_down_in_rect(&ctx->input, NK_BUTTON_LEFT, win_bounds, nk_true);
+ inpanel = inpanel && ctx->input.mouse.buttons[NK_BUTTON_LEFT].clicked;
+ ishovered = nk_input_is_mouse_hovering_rect(&ctx->input, win_bounds);
+ if ((win != ctx->active) && ishovered && !ctx->input.mouse.buttons[NK_BUTTON_LEFT].down) {
+ iter = win->next;
+ while (iter) {
+ struct nk_rect iter_bounds = (!(iter->flags & NK_WINDOW_MINIMIZED))?
+ iter->bounds: nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h);
+ if (NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
+ iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) &&
+ (!(iter->flags & NK_WINDOW_HIDDEN)))
+ break;
+
+ if (iter->popup.win && iter->popup.active && !(iter->flags & NK_WINDOW_HIDDEN) &&
+ NK_INTERSECT(win->bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
+ iter->popup.win->bounds.x, iter->popup.win->bounds.y,
+ iter->popup.win->bounds.w, iter->popup.win->bounds.h))
+ break;
+ iter = iter->next;
+ }
+ }
+
+ /* activate window if clicked */
+ if (iter && inpanel && (win != ctx->end)) {
+ iter = win->next;
+ while (iter) {
+ /* try to find a panel with higher priority in the same position */
+ struct nk_rect iter_bounds = (!(iter->flags & NK_WINDOW_MINIMIZED))?
+ iter->bounds: nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h);
+ if (NK_INBOX(ctx->input.mouse.pos.x, ctx->input.mouse.pos.y,
+ iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) &&
+ !(iter->flags & NK_WINDOW_HIDDEN))
+ break;
+ if (iter->popup.win && iter->popup.active && !(iter->flags & NK_WINDOW_HIDDEN) &&
+ NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h,
+ iter->popup.win->bounds.x, iter->popup.win->bounds.y,
+ iter->popup.win->bounds.w, iter->popup.win->bounds.h))
+ break;
+ iter = iter->next;
+ }
+ }
+ if (iter && !(win->flags & NK_WINDOW_ROM) && (win->flags & NK_WINDOW_BACKGROUND)) {
+ win->flags |= (nk_flags)NK_WINDOW_ROM;
+ iter->flags &= ~(nk_flags)NK_WINDOW_ROM;
+ ctx->active = iter;
+ if (!(iter->flags & NK_WINDOW_BACKGROUND)) {
+ /* current window is active in that position so transfer to top
+ * at the highest priority in stack */
+ nk_remove_window(ctx, iter);
+ nk_insert_window(ctx, iter, NK_INSERT_BACK);
+ }
+ } else {
+ if (!iter && ctx->end != win) {
+ if (!(win->flags & NK_WINDOW_BACKGROUND)) {
+ /* current window is active in that position so transfer to top
+ * at the highest priority in stack */
+ nk_remove_window(ctx, win);
+ nk_insert_window(ctx, win, NK_INSERT_BACK);
+ }
+ win->flags &= ~(nk_flags)NK_WINDOW_ROM;
+ ctx->active = win;
+ }
+ if (ctx->end != win && !(win->flags & NK_WINDOW_BACKGROUND))
+ win->flags |= NK_WINDOW_ROM;
+ }
+ }
+ win->layout = (struct nk_panel*)nk_create_panel(ctx);
+ ctx->current = win;
+ ret = nk_panel_begin(ctx, title, NK_PANEL_WINDOW);
+ win->layout->offset_x = &win->scrollbar.x;
+ win->layout->offset_y = &win->scrollbar.y;
+ return ret;
+}
+
+NK_API void
+nk_end(struct nk_context *ctx)
+{
+ struct nk_panel *layout;
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current && "if this triggers you forgot to call `nk_begin`");
+ if (!ctx || !ctx->current)
+ return;
+
+ layout = ctx->current->layout;
+ if (!layout || (layout->type == NK_PANEL_WINDOW && (ctx->current->flags & NK_WINDOW_HIDDEN))) {
+ ctx->current = 0;
+ return;
+ }
+ nk_panel_end(ctx);
+ nk_free_panel(ctx, ctx->current->layout);
+ ctx->current = 0;
+}
+
+NK_API struct nk_rect
+nk_window_get_bounds(const struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current) return nk_rect(0,0,0,0);
+ return ctx->current->bounds;
+}
+
+NK_API struct nk_vec2
+nk_window_get_position(const struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current) return nk_vec2(0,0);
+ return nk_vec2(ctx->current->bounds.x, ctx->current->bounds.y);
+}
+
+NK_API struct nk_vec2
+nk_window_get_size(const struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current) return nk_vec2(0,0);
+ return nk_vec2(ctx->current->bounds.w, ctx->current->bounds.h);
+}
+
+NK_API float
+nk_window_get_width(const struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current) return 0;
+ return ctx->current->bounds.w;
+}
+
+NK_API float
+nk_window_get_height(const struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current) return 0;
+ return ctx->current->bounds.h;
+}
+
+NK_API struct nk_rect
+nk_window_get_content_region(struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current) return nk_rect(0,0,0,0);
+ return ctx->current->layout->clip;
+}
+
+NK_API struct nk_vec2
+nk_window_get_content_region_min(struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current) return nk_vec2(0,0);
+ return nk_vec2(ctx->current->layout->clip.x, ctx->current->layout->clip.y);
+}
+
+NK_API struct nk_vec2
+nk_window_get_content_region_max(struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current) return nk_vec2(0,0);
+ return nk_vec2(ctx->current->layout->clip.x + ctx->current->layout->clip.w,
+ ctx->current->layout->clip.y + ctx->current->layout->clip.h);
+}
+
+NK_API struct nk_vec2
+nk_window_get_content_region_size(struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current) return nk_vec2(0,0);
+ return nk_vec2(ctx->current->layout->clip.w, ctx->current->layout->clip.h);
+}
+
+NK_API struct nk_command_buffer*
+nk_window_get_canvas(struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current) return 0;
+ return &ctx->current->buffer;
+}
+
+NK_API struct nk_panel*
+nk_window_get_panel(struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current) return 0;
+ return ctx->current->layout;
+}
+
+NK_API int
+nk_window_has_focus(const struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current) return 0;
+ return ctx->current == ctx->active;
+}
+
+NK_API int
+nk_window_is_hovered(struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current) return 0;
+ if(ctx->current->flags & NK_WINDOW_HIDDEN)
+ return 0;
+ return nk_input_is_mouse_hovering_rect(&ctx->input, ctx->current->bounds);
+}
+
+NK_API int
+nk_window_is_any_hovered(struct nk_context *ctx)
+{
+ struct nk_window *iter;
+ NK_ASSERT(ctx);
+ if (!ctx) return 0;
+ iter = ctx->begin;
+ while (iter) {
+ /* check if window is being hovered */
+ if(!(iter->flags & NK_WINDOW_HIDDEN)) {
+ /* check if window popup is being hovered */
+ if (iter->popup.active && iter->popup.win && nk_input_is_mouse_hovering_rect(&ctx->input, iter->popup.win->bounds))
+ return 1;
+
+ if (iter->flags & NK_WINDOW_MINIMIZED) {
+ struct nk_rect header = iter->bounds;
+ header.h = ctx->style.font->height + 2 * ctx->style.window.header.padding.y;
+ if (nk_input_is_mouse_hovering_rect(&ctx->input, header))
+ return 1;
+ } else if (nk_input_is_mouse_hovering_rect(&ctx->input, iter->bounds)) {
+ return 1;
+ }
+ }
+ iter = iter->next;
+ }
+ return 0;
+}
+
+NK_API int
+nk_item_is_any_active(struct nk_context *ctx)
+{
+ int any_hovered = nk_window_is_any_hovered(ctx);
+ int any_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED);
+ return any_hovered || any_active;
+}
+
+NK_API int
+nk_window_is_collapsed(struct nk_context *ctx, const char *name)
+{
+ int title_len;
+ nk_hash title_hash;
+ struct nk_window *win;
+ NK_ASSERT(ctx);
+ if (!ctx) return 0;
+
+ title_len = (int)nk_strlen(name);
+ title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
+ win = nk_find_window(ctx, title_hash, name);
+ if (!win) return 0;
+ return win->flags & NK_WINDOW_MINIMIZED;
+}
+
+NK_API int
+nk_window_is_closed(struct nk_context *ctx, const char *name)
+{
+ int title_len;
+ nk_hash title_hash;
+ struct nk_window *win;
+ NK_ASSERT(ctx);
+ if (!ctx) return 1;
+
+ title_len = (int)nk_strlen(name);
+ title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
+ win = nk_find_window(ctx, title_hash, name);
+ if (!win) return 1;
+ return (win->flags & NK_WINDOW_CLOSED);
+}
+
+NK_API int
+nk_window_is_hidden(struct nk_context *ctx, const char *name)
+{
+ int title_len;
+ nk_hash title_hash;
+ struct nk_window *win;
+ NK_ASSERT(ctx);
+ if (!ctx) return 1;
+
+ title_len = (int)nk_strlen(name);
+ title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
+ win = nk_find_window(ctx, title_hash, name);
+ if (!win) return 1;
+ return (win->flags & NK_WINDOW_HIDDEN);
+}
+
+NK_API int
+nk_window_is_active(struct nk_context *ctx, const char *name)
+{
+ int title_len;
+ nk_hash title_hash;
+ struct nk_window *win;
+ NK_ASSERT(ctx);
+ if (!ctx) return 0;
+
+ title_len = (int)nk_strlen(name);
+ title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
+ win = nk_find_window(ctx, title_hash, name);
+ if (!win) return 0;
+ return win == ctx->active;
+}
+
+NK_API struct nk_window*
+nk_window_find(struct nk_context *ctx, const char *name)
+{
+ int title_len;
+ nk_hash title_hash;
+ title_len = (int)nk_strlen(name);
+ title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
+ return nk_find_window(ctx, title_hash, name);
+}
+
+NK_API void
+nk_window_close(struct nk_context *ctx, const char *name)
+{
+ struct nk_window *win;
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ win = nk_window_find(ctx, name);
+ if (!win) return;
+ NK_ASSERT(ctx->current != win && "You cannot close a currently active window");
+ if (ctx->current == win) return;
+ win->flags |= NK_WINDOW_HIDDEN;
+ win->flags |= NK_WINDOW_CLOSED;
+}
+
+NK_API void
+nk_window_set_bounds(struct nk_context *ctx,
+ const char *name, struct nk_rect bounds)
+{
+ struct nk_window *win;
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ win = nk_window_find(ctx, name);
+ if (!win) return;
+ NK_ASSERT(ctx->current != win && "You cannot update a currently in procecss window");
+ win->bounds = bounds;
+}
+
+NK_API void
+nk_window_set_position(struct nk_context *ctx,
+ const char *name, struct nk_vec2 pos)
+{
+ struct nk_window *win = nk_window_find(ctx, name);
+ if (!win) return;
+ win->bounds.x = pos.x;
+ win->bounds.y = pos.y;
+}
+
+NK_API void
+nk_window_set_size(struct nk_context *ctx,
+ const char *name, struct nk_vec2 size)
+{
+ struct nk_window *win = nk_window_find(ctx, name);
+ if (!win) return;
+ win->bounds.w = size.x;
+ win->bounds.h = size.y;
+}
+
+NK_API void
+nk_window_collapse(struct nk_context *ctx, const char *name,
+ enum nk_collapse_states c)
+{
+ int title_len;
+ nk_hash title_hash;
+ struct nk_window *win;
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+
+ title_len = (int)nk_strlen(name);
+ title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
+ win = nk_find_window(ctx, title_hash, name);
+ if (!win) return;
+ if (c == NK_MINIMIZED)
+ win->flags |= NK_WINDOW_MINIMIZED;
+ else win->flags &= ~(nk_flags)NK_WINDOW_MINIMIZED;
+}
+
+NK_API void
+nk_window_collapse_if(struct nk_context *ctx, const char *name,
+ enum nk_collapse_states c, int cond)
+{
+ NK_ASSERT(ctx);
+ if (!ctx || !cond) return;
+ nk_window_collapse(ctx, name, c);
+}
+
+NK_API void
+nk_window_show(struct nk_context *ctx, const char *name, enum nk_show_states s)
+{
+ int title_len;
+ nk_hash title_hash;
+ struct nk_window *win;
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+
+ title_len = (int)nk_strlen(name);
+ title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
+ win = nk_find_window(ctx, title_hash, name);
+ if (!win) return;
+ if (s == NK_HIDDEN) {
+ win->flags |= NK_WINDOW_HIDDEN;
+ } else win->flags &= ~(nk_flags)NK_WINDOW_HIDDEN;
+}
+
+NK_API void
+nk_window_show_if(struct nk_context *ctx, const char *name,
+ enum nk_show_states s, int cond)
+{
+ NK_ASSERT(ctx);
+ if (!ctx || !cond) return;
+ nk_window_show(ctx, name, s);
+}
+
+NK_API void
+nk_window_set_focus(struct nk_context *ctx, const char *name)
+{
+ int title_len;
+ nk_hash title_hash;
+ struct nk_window *win;
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+
+ title_len = (int)nk_strlen(name);
+ title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE);
+ win = nk_find_window(ctx, title_hash, name);
+ if (win && ctx->end != win) {
+ nk_remove_window(ctx, win);
+ nk_insert_window(ctx, win, NK_INSERT_BACK);
+ }
+ ctx->active = win;
+}
+
+/*----------------------------------------------------------------
+ *
+ * MENUBAR
+ *
+ * --------------------------------------------------------------*/
+NK_API void
+nk_menubar_begin(struct nk_context *ctx)
+{
+ struct nk_panel *layout;
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ layout = ctx->current->layout;
+ NK_ASSERT(layout->at_y == layout->bounds.y);
+ /* if this assert triggers you allocated space between nk_begin and nk_menubar_begin.
+ If you want a menubar the first nuklear function after `nk_begin` has to be a
+ `nk_menubar_begin` call. Inside the menubar you then have to allocate space for
+ widgets (also supports multiple rows).
+ Example:
+ if (nk_begin(...)) {
+ nk_menubar_begin(...);
+ nk_layout_xxxx(...);
+ nk_button(...);
+ nk_layout_xxxx(...);
+ nk_button(...);
+ nk_menubar_end(...);
+ }
+ nk_end(...);
+ */
+ if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED)
+ return;
+
+ layout->menu.x = layout->at_x;
+ layout->menu.y = layout->at_y + layout->row.height;
+ layout->menu.w = layout->bounds.w;
+ layout->menu.offset.x = *layout->offset_x;
+ layout->menu.offset.y = *layout->offset_y;
+ *layout->offset_y = 0;
+}
+
+NK_API void
+nk_menubar_end(struct nk_context *ctx)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ struct nk_command_buffer *out;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ out = &win->buffer;
+ layout = win->layout;
+ if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED)
+ return;
+
+ layout->menu.h = layout->at_y - layout->menu.y;
+ layout->bounds.y += layout->menu.h + ctx->style.window.spacing.y + layout->row.height;
+ layout->bounds.h -= layout->menu.h + ctx->style.window.spacing.y + layout->row.height;
+
+ *layout->offset_x = layout->menu.offset.x;
+ *layout->offset_y = layout->menu.offset.y;
+ layout->at_y = layout->bounds.y - layout->row.height;
+
+ layout->clip.y = layout->bounds.y;
+ layout->clip.h = layout->bounds.h;
+ nk_push_scissor(out, layout->clip);
+}
+/* -------------------------------------------------------------
+ *
+ * LAYOUT
+ *
+ * --------------------------------------------------------------*/
+NK_API void
+nk_layout_set_min_row_height(struct nk_context *ctx, float height)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ layout->row.min_height = height;
+}
+
+NK_API void
+nk_layout_reset_min_row_height(struct nk_context *ctx)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ layout->row.min_height = ctx->style.font->height;
+ layout->row.min_height += ctx->style.text.padding.y*2;
+ layout->row.min_height += ctx->style.window.min_row_height_padding*2;
+}
+
+NK_INTERN float
+nk_layout_row_calculate_usable_space(const struct nk_style *style, enum nk_panel_type type,
+ float total_space, int columns)
+{
+ float panel_padding;
+ float panel_spacing;
+ float panel_space;
+
+ struct nk_vec2 spacing;
+ struct nk_vec2 padding;
+
+ spacing = style->window.spacing;
+ padding = nk_panel_get_padding(style, type);
+
+ /* calculate the usable panel space */
+ panel_padding = 2 * padding.x;
+ panel_spacing = (float)NK_MAX(columns - 1, 0) * spacing.x;
+ panel_space = total_space - panel_padding - panel_spacing;
+ return panel_space;
+}
+
+NK_INTERN void
+nk_panel_layout(const struct nk_context *ctx, struct nk_window *win,
+ float height, int cols)
+{
+ struct nk_panel *layout;
+ const struct nk_style *style;
+ struct nk_command_buffer *out;
+
+ struct nk_vec2 item_spacing;
+ struct nk_color color;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ /* prefetch some configuration data */
+ layout = win->layout;
+ style = &ctx->style;
+ out = &win->buffer;
+ color = style->window.background;
+ item_spacing = style->window.spacing;
+
+ /* if one of these triggers you forgot to add an `if` condition around either
+ a window, group, popup, combobox or contextual menu `begin` and `end` block.
+ Example:
+ if (nk_begin(...) {...} nk_end(...); or
+ if (nk_group_begin(...) { nk_group_end(...);} */
+ NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED));
+ NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN));
+ NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED));
+
+ /* update the current row and set the current row layout */
+ layout->row.index = 0;
+ layout->at_y += layout->row.height;
+ layout->row.columns = cols;
+ if (height == 0.0f)
+ layout->row.height = NK_MAX(height, layout->row.min_height) + item_spacing.y;
+ else layout->row.height = height + item_spacing.y;
+
+ layout->row.item_offset = 0;
+ if (layout->flags & NK_WINDOW_DYNAMIC) {
+ /* draw background for dynamic panels */
+ struct nk_rect background;
+ background.x = win->bounds.x;
+ background.w = win->bounds.w;
+ background.y = layout->at_y - 1.0f;
+ background.h = layout->row.height + 1.0f;
+ nk_fill_rect(out, background, 0, color);
+ }
+}
+
+NK_INTERN void
+nk_row_layout(struct nk_context *ctx, enum nk_layout_format fmt,
+ float height, int cols, int width)
+{
+ /* update the current row and set the current row layout */
+ struct nk_window *win;
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ nk_panel_layout(ctx, win, height, cols);
+ if (fmt == NK_DYNAMIC)
+ win->layout->row.type = NK_LAYOUT_DYNAMIC_FIXED;
+ else win->layout->row.type = NK_LAYOUT_STATIC_FIXED;
+
+ win->layout->row.ratio = 0;
+ win->layout->row.filled = 0;
+ win->layout->row.item_offset = 0;
+ win->layout->row.item_width = (float)width;
+}
+
+NK_API float
+nk_layout_ratio_from_pixel(struct nk_context *ctx, float pixel_width)
+{
+ struct nk_window *win;
+ NK_ASSERT(ctx);
+ NK_ASSERT(pixel_width);
+ if (!ctx || !ctx->current || !ctx->current->layout) return 0;
+ win = ctx->current;
+ return NK_CLAMP(0.0f, pixel_width/win->bounds.x, 1.0f);
+}
+
+NK_API void
+nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols)
+{
+ nk_row_layout(ctx, NK_DYNAMIC, height, cols, 0);
+}
+
+NK_API void
+nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols)
+{
+ nk_row_layout(ctx, NK_STATIC, height, cols, item_width);
+}
+
+NK_API void
+nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt,
+ float row_height, int cols)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ nk_panel_layout(ctx, win, row_height, cols);
+ if (fmt == NK_DYNAMIC)
+ layout->row.type = NK_LAYOUT_DYNAMIC_ROW;
+ else layout->row.type = NK_LAYOUT_STATIC_ROW;
+
+ layout->row.ratio = 0;
+ layout->row.filled = 0;
+ layout->row.item_width = 0;
+ layout->row.item_offset = 0;
+ layout->row.columns = cols;
+}
+
+NK_API void
+nk_layout_row_push(struct nk_context *ctx, float ratio_or_width)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW);
+ if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW)
+ return;
+
+ if (layout->row.type == NK_LAYOUT_DYNAMIC_ROW) {
+ float ratio = ratio_or_width;
+ if ((ratio + layout->row.filled) > 1.0f) return;
+ if (ratio > 0.0f)
+ layout->row.item_width = NK_SATURATE(ratio);
+ else layout->row.item_width = 1.0f - layout->row.filled;
+ } else layout->row.item_width = ratio_or_width;
+}
+
+NK_API void
+nk_layout_row_end(struct nk_context *ctx)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW);
+ if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW)
+ return;
+ layout->row.item_width = 0;
+ layout->row.item_offset = 0;
+}
+
+NK_API void
+nk_layout_row(struct nk_context *ctx, enum nk_layout_format fmt,
+ float height, int cols, const float *ratio)
+{
+ int i;
+ int n_undef = 0;
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ nk_panel_layout(ctx, win, height, cols);
+ if (fmt == NK_DYNAMIC) {
+ /* calculate width of undefined widget ratios */
+ float r = 0;
+ layout->row.ratio = ratio;
+ for (i = 0; i < cols; ++i) {
+ if (ratio[i] < 0.0f)
+ n_undef++;
+ else r += ratio[i];
+ }
+ r = NK_SATURATE(1.0f - r);
+ layout->row.type = NK_LAYOUT_DYNAMIC;
+ layout->row.item_width = (r > 0 && n_undef > 0) ? (r / (float)n_undef):0;
+ } else {
+ layout->row.ratio = ratio;
+ layout->row.type = NK_LAYOUT_STATIC;
+ layout->row.item_width = 0;
+ layout->row.item_offset = 0;
+ }
+ layout->row.item_offset = 0;
+ layout->row.filled = 0;
+}
+
+NK_API void
+nk_layout_row_template_begin(struct nk_context *ctx, float height)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ nk_panel_layout(ctx, win, height, 1);
+ layout->row.type = NK_LAYOUT_TEMPLATE;
+ layout->row.columns = 0;
+ layout->row.ratio = 0;
+ layout->row.item_width = 0;
+ layout->row.item_height = 0;
+ layout->row.item_offset = 0;
+ layout->row.filled = 0;
+ layout->row.item.x = 0;
+ layout->row.item.y = 0;
+ layout->row.item.w = 0;
+ layout->row.item.h = 0;
+}
+
+NK_API void
+nk_layout_row_template_push_dynamic(struct nk_context *ctx)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
+ NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
+ if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
+ if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
+ layout->row.templates[layout->row.columns++] = -1.0f;
+}
+
+NK_API void
+nk_layout_row_template_push_variable(struct nk_context *ctx, float min_width)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
+ NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
+ if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
+ if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
+ layout->row.templates[layout->row.columns++] = -min_width;
+}
+
+NK_API void
+nk_layout_row_template_push_static(struct nk_context *ctx, float width)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
+ NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
+ if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
+ if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) return;
+ layout->row.templates[layout->row.columns++] = width;
+}
+
+NK_API void
+nk_layout_row_template_end(struct nk_context *ctx)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ int i = 0;
+ int variable_count = 0;
+ int min_variable_count = 0;
+ float min_fixed_width = 0.0f;
+ float total_fixed_width = 0.0f;
+ float max_variable_width = 0.0f;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE);
+ if (layout->row.type != NK_LAYOUT_TEMPLATE) return;
+ for (i = 0; i < layout->row.columns; ++i) {
+ float width = layout->row.templates[i];
+ if (width >= 0.0f) {
+ total_fixed_width += width;
+ min_fixed_width += width;
+ } else if (width < -1.0f) {
+ width = -width;
+ total_fixed_width += width;
+ max_variable_width = NK_MAX(max_variable_width, width);
+ variable_count++;
+ } else {
+ min_variable_count++;
+ variable_count++;
+ }
+ }
+ if (variable_count) {
+ float space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type,
+ layout->bounds.w, layout->row.columns);
+ float var_width = (NK_MAX(space-min_fixed_width,0.0f)) / (float)variable_count;
+ int enough_space = var_width >= max_variable_width;
+ if (!enough_space)
+ var_width = (NK_MAX(space-total_fixed_width,0)) / (float)min_variable_count;
+ for (i = 0; i < layout->row.columns; ++i) {
+ float *width = &layout->row.templates[i];
+ *width = (*width >= 0.0f)? *width: (*width < -1.0f && !enough_space)? -(*width): var_width;
+ }
+ }
+}
+
+NK_API void
+nk_layout_space_begin(struct nk_context *ctx, enum nk_layout_format fmt,
+ float height, int widget_count)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ nk_panel_layout(ctx, win, height, widget_count);
+ if (fmt == NK_STATIC)
+ layout->row.type = NK_LAYOUT_STATIC_FREE;
+ else layout->row.type = NK_LAYOUT_DYNAMIC_FREE;
+
+ layout->row.ratio = 0;
+ layout->row.filled = 0;
+ layout->row.item_width = 0;
+ layout->row.item_offset = 0;
+}
+
+NK_API void
+nk_layout_space_end(struct nk_context *ctx)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ layout->row.item_width = 0;
+ layout->row.item_height = 0;
+ layout->row.item_offset = 0;
+ nk_zero(&layout->row.item, sizeof(layout->row.item));
+}
+
+NK_API void
+nk_layout_space_push(struct nk_context *ctx, struct nk_rect rect)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ layout->row.item = rect;
+}
+
+NK_API struct nk_rect
+nk_layout_space_bounds(struct nk_context *ctx)
+{
+ struct nk_rect ret;
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ win = ctx->current;
+ layout = win->layout;
+
+ ret.x = layout->clip.x;
+ ret.y = layout->clip.y;
+ ret.w = layout->clip.w;
+ ret.h = layout->row.height;
+ return ret;
+}
+
+NK_API struct nk_rect
+nk_layout_widget_bounds(struct nk_context *ctx)
+{
+ struct nk_rect ret;
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ win = ctx->current;
+ layout = win->layout;
+
+ ret.x = layout->at_x;
+ ret.y = layout->at_y;
+ ret.w = layout->bounds.w - NK_MAX(layout->at_x - layout->bounds.x,0);
+ ret.h = layout->row.height;
+ return ret;
+}
+
+NK_API struct nk_vec2
+nk_layout_space_to_screen(struct nk_context *ctx, struct nk_vec2 ret)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ win = ctx->current;
+ layout = win->layout;
+
+ ret.x += layout->at_x - (float)*layout->offset_x;
+ ret.y += layout->at_y - (float)*layout->offset_y;
+ return ret;
+}
+
+NK_API struct nk_vec2
+nk_layout_space_to_local(struct nk_context *ctx, struct nk_vec2 ret)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ win = ctx->current;
+ layout = win->layout;
+
+ ret.x += -layout->at_x + (float)*layout->offset_x;
+ ret.y += -layout->at_y + (float)*layout->offset_y;
+ return ret;
+}
+
+NK_API struct nk_rect
+nk_layout_space_rect_to_screen(struct nk_context *ctx, struct nk_rect ret)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ win = ctx->current;
+ layout = win->layout;
+
+ ret.x += layout->at_x - (float)*layout->offset_x;
+ ret.y += layout->at_y - (float)*layout->offset_y;
+ return ret;
+}
+
+NK_API struct nk_rect
+nk_layout_space_rect_to_local(struct nk_context *ctx, struct nk_rect ret)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ win = ctx->current;
+ layout = win->layout;
+
+ ret.x += -layout->at_x + (float)*layout->offset_x;
+ ret.y += -layout->at_y + (float)*layout->offset_y;
+ return ret;
+}
+
+NK_INTERN void
+nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win)
+{
+ struct nk_panel *layout = win->layout;
+ struct nk_vec2 spacing = ctx->style.window.spacing;
+ const float row_height = layout->row.height - spacing.y;
+ nk_panel_layout(ctx, win, row_height, layout->row.columns);
+}
+
+NK_INTERN void
+nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx,
+ struct nk_window *win, int modify)
+{
+ struct nk_panel *layout;
+ const struct nk_style *style;
+
+ struct nk_vec2 spacing;
+ struct nk_vec2 padding;
+
+ float item_offset = 0;
+ float item_width = 0;
+ float item_spacing = 0;
+ float panel_space = 0;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ style = &ctx->style;
+ NK_ASSERT(bounds);
+
+ spacing = style->window.spacing;
+ padding = nk_panel_get_padding(style, layout->type);
+ panel_space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type,
+ layout->bounds.w, layout->row.columns);
+
+ /* calculate the width of one item inside the current layout space */
+ switch (layout->row.type) {
+ case NK_LAYOUT_DYNAMIC_FIXED: {
+ /* scaling fixed size widgets item width */
+ item_width = NK_MAX(1.0f,panel_space) / (float)layout->row.columns;
+ item_offset = (float)layout->row.index * item_width;
+ item_spacing = (float)layout->row.index * spacing.x;
+ } break;
+ case NK_LAYOUT_DYNAMIC_ROW: {
+ /* scaling single ratio widget width */
+ item_width = layout->row.item_width * panel_space;
+ item_offset = layout->row.item_offset;
+ item_spacing = 0;
+
+ if (modify) {
+ layout->row.item_offset += item_width + spacing.x;
+ layout->row.filled += layout->row.item_width;
+ layout->row.index = 0;
+ }
+ } break;
+ case NK_LAYOUT_DYNAMIC_FREE: {
+ /* panel width depended free widget placing */
+ bounds->x = layout->at_x + (layout->bounds.w * layout->row.item.x);
+ bounds->x -= (float)*layout->offset_x;
+ bounds->y = layout->at_y + (layout->row.height * layout->row.item.y);
+ bounds->y -= (float)*layout->offset_y;
+ bounds->w = layout->bounds.w * layout->row.item.w;
+ bounds->h = layout->row.height * layout->row.item.h;
+ return;
+ } break;
+ case NK_LAYOUT_DYNAMIC: {
+ /* scaling arrays of panel width ratios for every widget */
+ float ratio;
+ NK_ASSERT(layout->row.ratio);
+ ratio = (layout->row.ratio[layout->row.index] < 0) ?
+ layout->row.item_width : layout->row.ratio[layout->row.index];
+
+ item_spacing = (float)layout->row.index * spacing.x;
+ item_width = (ratio * panel_space);
+ item_offset = layout->row.item_offset;
+
+ if (modify) {
+ layout->row.item_offset += item_width;
+ layout->row.filled += ratio;
+ }
+ } break;
+ case NK_LAYOUT_STATIC_FIXED: {
+ /* non-scaling fixed widgets item width */
+ item_width = layout->row.item_width;
+ item_offset = (float)layout->row.index * item_width;
+ item_spacing = (float)layout->row.index * spacing.x;
+ } break;
+ case NK_LAYOUT_STATIC_ROW: {
+ /* scaling single ratio widget width */
+ item_width = layout->row.item_width;
+ item_offset = layout->row.item_offset;
+ item_spacing = (float)layout->row.index * spacing.x;
+ if (modify) layout->row.item_offset += item_width;
+ } break;
+ case NK_LAYOUT_STATIC_FREE: {
+ /* free widget placing */
+ bounds->x = layout->at_x + layout->row.item.x;
+ bounds->w = layout->row.item.w;
+ if (((bounds->x + bounds->w) > layout->max_x) && modify)
+ layout->max_x = (bounds->x + bounds->w);
+ bounds->x -= (float)*layout->offset_x;
+ bounds->y = layout->at_y + layout->row.item.y;
+ bounds->y -= (float)*layout->offset_y;
+ bounds->h = layout->row.item.h;
+ return;
+ } break;
+ case NK_LAYOUT_STATIC: {
+ /* non-scaling array of panel pixel width for every widget */
+ item_spacing = (float)layout->row.index * spacing.x;
+ item_width = layout->row.ratio[layout->row.index];
+ item_offset = layout->row.item_offset;
+ if (modify) layout->row.item_offset += item_width;
+ } break;
+ case NK_LAYOUT_TEMPLATE: {
+ /* stretchy row layout with combined dynamic/static widget width*/
+ NK_ASSERT(layout->row.index < layout->row.columns);
+ NK_ASSERT(layout->row.index < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS);
+ item_width = layout->row.templates[layout->row.index];
+ item_offset = layout->row.item_offset;
+ item_spacing = (float)layout->row.index * spacing.x;
+ if (modify) layout->row.item_offset += item_width;
+ } break;
+ default: NK_ASSERT(0); break;
+ };
+
+ /* set the bounds of the newly allocated widget */
+ bounds->w = item_width;
+ bounds->h = layout->row.height - spacing.y;
+ bounds->y = layout->at_y - (float)*layout->offset_y;
+ bounds->x = layout->at_x + item_offset + item_spacing + padding.x;
+ if (((bounds->x + bounds->w) > layout->max_x) && modify)
+ layout->max_x = bounds->x + bounds->w;
+ bounds->x -= (float)*layout->offset_x;
+}
+
+NK_INTERN void
+nk_panel_alloc_space(struct nk_rect *bounds, const struct nk_context *ctx)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ /* check if the end of the row has been hit and begin new row if so */
+ win = ctx->current;
+ layout = win->layout;
+ if (layout->row.index >= layout->row.columns)
+ nk_panel_alloc_row(ctx, win);
+
+ /* calculate widget position and size */
+ nk_layout_widget_space(bounds, ctx, win, nk_true);
+ layout->row.index++;
+}
+
+NK_INTERN void
+nk_layout_peek(struct nk_rect *bounds, struct nk_context *ctx)
+{
+ float y;
+ int index;
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ y = layout->at_y;
+ index = layout->row.index;
+ if (layout->row.index >= layout->row.columns) {
+ layout->at_y += layout->row.height;
+ layout->row.index = 0;
+ }
+ nk_layout_widget_space(bounds, ctx, win, nk_false);
+ if (!layout->row.index) {
+ bounds->x -= layout->row.item_offset;
+ }
+ layout->at_y = y;
+ layout->row.index = index;
+}
+
+NK_INTERN int
+nk_tree_state_base(struct nk_context *ctx, enum nk_tree_type type,
+ struct nk_image *img, const char *title, enum nk_collapse_states *state)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_style *style;
+ struct nk_command_buffer *out;
+ const struct nk_input *in;
+ const struct nk_style_button *button;
+ enum nk_symbol_type symbol;
+ float row_height;
+
+ struct nk_vec2 item_spacing;
+ struct nk_rect header = {0,0,0,0};
+ struct nk_rect sym = {0,0,0,0};
+ struct nk_text text;
+
+ nk_flags ws = 0;
+ enum nk_widget_layout_states widget_state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ /* cache some data */
+ win = ctx->current;
+ layout = win->layout;
+ out = &win->buffer;
+ style = &ctx->style;
+ item_spacing = style->window.spacing;
+
+ /* calculate header bounds and draw background */
+ row_height = style->font->height + 2 * style->tab.padding.y;
+ nk_layout_set_min_row_height(ctx, row_height);
+ nk_layout_row_dynamic(ctx, row_height, 1);
+ nk_layout_reset_min_row_height(ctx);
+
+ widget_state = nk_widget(&header, ctx);
+ if (type == NK_TREE_TAB) {
+ const struct nk_style_item *background = &style->tab.background;
+ if (background->type == NK_STYLE_ITEM_IMAGE) {
+ nk_draw_image(out, header, &background->data.image, nk_white);
+ text.background = nk_rgba(0,0,0,0);
+ } else {
+ text.background = background->data.color;
+ nk_fill_rect(out, header, 0, style->tab.border_color);
+ nk_fill_rect(out, nk_shrink_rect(header, style->tab.border),
+ style->tab.rounding, background->data.color);
+ }
+ } else text.background = style->window.background;
+
+ /* update node state */
+ in = (!(layout->flags & NK_WINDOW_ROM)) ? &ctx->input: 0;
+ in = (in && widget_state == NK_WIDGET_VALID) ? &ctx->input : 0;
+ if (nk_button_behavior(&ws, header, in, NK_BUTTON_DEFAULT))
+ *state = (*state == NK_MAXIMIZED) ? NK_MINIMIZED : NK_MAXIMIZED;
+
+ /* select correct button style */
+ if (*state == NK_MAXIMIZED) {
+ symbol = style->tab.sym_maximize;
+ if (type == NK_TREE_TAB)
+ button = &style->tab.tab_maximize_button;
+ else button = &style->tab.node_maximize_button;
+ } else {
+ symbol = style->tab.sym_minimize;
+ if (type == NK_TREE_TAB)
+ button = &style->tab.tab_minimize_button;
+ else button = &style->tab.node_minimize_button;
+ }
+
+ {/* draw triangle button */
+ sym.w = sym.h = style->font->height;
+ sym.y = header.y + style->tab.padding.y;
+ sym.x = header.x + style->tab.padding.x;
+ nk_do_button_symbol(&ws, &win->buffer, sym, symbol, NK_BUTTON_DEFAULT,
+ button, 0, style->font);
+
+ if (img) {
+ /* draw optional image icon */
+ sym.x = sym.x + sym.w + 4 * item_spacing.x;
+ nk_draw_image(&win->buffer, sym, img, nk_white);
+ sym.w = style->font->height + style->tab.spacing.x;}
+ }
+
+ {/* draw label */
+ struct nk_rect label;
+ header.w = NK_MAX(header.w, sym.w + item_spacing.x);
+ label.x = sym.x + sym.w + item_spacing.x;
+ label.y = sym.y;
+ label.w = header.w - (sym.w + item_spacing.y + style->tab.indent);
+ label.h = style->font->height;
+ text.text = style->tab.text;
+ text.padding = nk_vec2(0,0);
+ nk_widget_text(out, label, title, nk_strlen(title), &text,
+ NK_TEXT_LEFT, style->font);}
+
+ /* increase x-axis cursor widget position pointer */
+ if (*state == NK_MAXIMIZED) {
+ layout->at_x = header.x + (float)*layout->offset_x + style->tab.indent;
+ layout->bounds.w = NK_MAX(layout->bounds.w, style->tab.indent);
+ layout->bounds.w -= (style->tab.indent + style->window.padding.x);
+ layout->row.tree_depth++;
+ return nk_true;
+ } else return nk_false;
+}
+
+NK_INTERN int
+nk_tree_base(struct nk_context *ctx, enum nk_tree_type type,
+ struct nk_image *img, const char *title, enum nk_collapse_states initial_state,
+ const char *hash, int len, int line)
+{
+ struct nk_window *win = ctx->current;
+ int title_len = 0;
+ nk_hash tree_hash = 0;
+ nk_uint *state = 0;
+
+ /* retrieve tree state from internal widget state tables */
+ if (!hash) {
+ title_len = (int)nk_strlen(title);
+ tree_hash = nk_murmur_hash(title, (int)title_len, (nk_hash)line);
+ } else tree_hash = nk_murmur_hash(hash, len, (nk_hash)line);
+ state = nk_find_value(win, tree_hash);
+ if (!state) {
+ state = nk_add_value(ctx, win, tree_hash, 0);
+ *state = initial_state;
+ }
+ return nk_tree_state_base(ctx, type, img, title, (enum nk_collapse_states*)state);
+}
+
+NK_API int
+nk_tree_state_push(struct nk_context *ctx, enum nk_tree_type type,
+ const char *title, enum nk_collapse_states *state)
+{return nk_tree_state_base(ctx, type, 0, title, state);}
+
+NK_API int
+nk_tree_state_image_push(struct nk_context *ctx, enum nk_tree_type type,
+ struct nk_image img, const char *title, enum nk_collapse_states *state)
+{return nk_tree_state_base(ctx, type, &img, title, state);}
+
+NK_API void
+nk_tree_state_pop(struct nk_context *ctx)
+{
+ struct nk_window *win = 0;
+ struct nk_panel *layout = 0;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ layout->at_x -= ctx->style.tab.indent + ctx->style.window.padding.x;
+ layout->bounds.w += ctx->style.tab.indent + ctx->style.window.padding.x;
+ NK_ASSERT(layout->row.tree_depth);
+ layout->row.tree_depth--;
+}
+
+NK_API int
+nk_tree_push_hashed(struct nk_context *ctx, enum nk_tree_type type,
+ const char *title, enum nk_collapse_states initial_state,
+ const char *hash, int len, int line)
+{return nk_tree_base(ctx, type, 0, title, initial_state, hash, len, line);}
+
+NK_API int
+nk_tree_image_push_hashed(struct nk_context *ctx, enum nk_tree_type type,
+ struct nk_image img, const char *title, enum nk_collapse_states initial_state,
+ const char *hash, int len,int seed)
+{return nk_tree_base(ctx, type, &img, title, initial_state, hash, len, seed);}
+
+NK_API void
+nk_tree_pop(struct nk_context *ctx)
+{nk_tree_state_pop(ctx);}
+
+/*----------------------------------------------------------------
+ *
+ * WIDGETS
+ *
+ * --------------------------------------------------------------*/
+NK_API struct nk_rect
+nk_widget_bounds(struct nk_context *ctx)
+{
+ struct nk_rect bounds;
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current)
+ return nk_rect(0,0,0,0);
+ nk_layout_peek(&bounds, ctx);
+ return bounds;
+}
+
+NK_API struct nk_vec2
+nk_widget_position(struct nk_context *ctx)
+{
+ struct nk_rect bounds;
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current)
+ return nk_vec2(0,0);
+
+ nk_layout_peek(&bounds, ctx);
+ return nk_vec2(bounds.x, bounds.y);
+}
+
+NK_API struct nk_vec2
+nk_widget_size(struct nk_context *ctx)
+{
+ struct nk_rect bounds;
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current)
+ return nk_vec2(0,0);
+
+ nk_layout_peek(&bounds, ctx);
+ return nk_vec2(bounds.w, bounds.h);
+}
+
+NK_API float
+nk_widget_width(struct nk_context *ctx)
+{
+ struct nk_rect bounds;
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current)
+ return 0;
+
+ nk_layout_peek(&bounds, ctx);
+ return bounds.w;
+}
+
+NK_API float
+nk_widget_height(struct nk_context *ctx)
+{
+ struct nk_rect bounds;
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current)
+ return 0;
+
+ nk_layout_peek(&bounds, ctx);
+ return bounds.h;
+}
+
+NK_API int
+nk_widget_is_hovered(struct nk_context *ctx)
+{
+ struct nk_rect c, v;
+ struct nk_rect bounds;
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current || ctx->active != ctx->current)
+ return 0;
+
+ c = ctx->current->layout->clip;
+ c.x = (float)((int)c.x);
+ c.y = (float)((int)c.y);
+ c.w = (float)((int)c.w);
+ c.h = (float)((int)c.h);
+
+ nk_layout_peek(&bounds, ctx);
+ nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
+ if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
+ return 0;
+ return nk_input_is_mouse_hovering_rect(&ctx->input, bounds);
+}
+
+NK_API int
+nk_widget_is_mouse_clicked(struct nk_context *ctx, enum nk_buttons btn)
+{
+ struct nk_rect c, v;
+ struct nk_rect bounds;
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current || ctx->active != ctx->current)
+ return 0;
+
+ c = ctx->current->layout->clip;
+ c.x = (float)((int)c.x);
+ c.y = (float)((int)c.y);
+ c.w = (float)((int)c.w);
+ c.h = (float)((int)c.h);
+
+ nk_layout_peek(&bounds, ctx);
+ nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
+ if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
+ return 0;
+ return nk_input_mouse_clicked(&ctx->input, btn, bounds);
+}
+
+NK_API int
+nk_widget_has_mouse_click_down(struct nk_context *ctx, enum nk_buttons btn, int down)
+{
+ struct nk_rect c, v;
+ struct nk_rect bounds;
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current || ctx->active != ctx->current)
+ return 0;
+
+ c = ctx->current->layout->clip;
+ c.x = (float)((int)c.x);
+ c.y = (float)((int)c.y);
+ c.w = (float)((int)c.w);
+ c.h = (float)((int)c.h);
+
+ nk_layout_peek(&bounds, ctx);
+ nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h);
+ if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h))
+ return 0;
+ return nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down);
+}
+
+NK_API enum nk_widget_layout_states
+nk_widget(struct nk_rect *bounds, const struct nk_context *ctx)
+{
+ struct nk_rect c, v;
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_input *in;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return NK_WIDGET_INVALID;
+
+ /* allocate space and check if the widget needs to be updated and drawn */
+ nk_panel_alloc_space(bounds, ctx);
+ win = ctx->current;
+ layout = win->layout;
+ in = &ctx->input;
+ c = layout->clip;
+
+ /* if one of these triggers you forgot to add an `if` condition around either
+ a window, group, popup, combobox or contextual menu `begin` and `end` block.
+ Example:
+ if (nk_begin(...) {...} nk_end(...); or
+ if (nk_group_begin(...) { nk_group_end(...);} */
+ NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED));
+ NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN));
+ NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED));
+
+ /* need to convert to int here to remove floating point errors */
+ bounds->x = (float)((int)bounds->x);
+ bounds->y = (float)((int)bounds->y);
+ bounds->w = (float)((int)bounds->w);
+ bounds->h = (float)((int)bounds->h);
+
+ c.x = (float)((int)c.x);
+ c.y = (float)((int)c.y);
+ c.w = (float)((int)c.w);
+ c.h = (float)((int)c.h);
+
+ nk_unify(&v, &c, bounds->x, bounds->y, bounds->x + bounds->w, bounds->y + bounds->h);
+ if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds->x, bounds->y, bounds->w, bounds->h))
+ return NK_WIDGET_INVALID;
+ if (!NK_INBOX(in->mouse.pos.x, in->mouse.pos.y, v.x, v.y, v.w, v.h))
+ return NK_WIDGET_ROM;
+ return NK_WIDGET_VALID;
+}
+
+NK_API enum nk_widget_layout_states
+nk_widget_fitting(struct nk_rect *bounds, struct nk_context *ctx,
+ struct nk_vec2 item_padding)
+{
+ /* update the bounds to stand without padding */
+ struct nk_window *win;
+ struct nk_style *style;
+ struct nk_panel *layout;
+ enum nk_widget_layout_states state;
+ struct nk_vec2 panel_padding;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return NK_WIDGET_INVALID;
+
+ win = ctx->current;
+ style = &ctx->style;
+ layout = win->layout;
+ state = nk_widget(bounds, ctx);
+
+ panel_padding = nk_panel_get_padding(style, layout->type);
+ if (layout->row.index == 1) {
+ bounds->w += panel_padding.x;
+ bounds->x -= panel_padding.x;
+ } else bounds->x -= item_padding.x;
+
+ if (layout->row.index == layout->row.columns)
+ bounds->w += panel_padding.x;
+ else bounds->w += item_padding.x;
+ return state;
+}
+
+/*----------------------------------------------------------------
+ *
+ * MISC
+ *
+ * --------------------------------------------------------------*/
+NK_API void
+nk_spacing(struct nk_context *ctx, int cols)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ struct nk_rect none;
+ int i, index, rows;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ /* spacing over row boundaries */
+ win = ctx->current;
+ layout = win->layout;
+ index = (layout->row.index + cols) % layout->row.columns;
+ rows = (layout->row.index + cols) / layout->row.columns;
+ if (rows) {
+ for (i = 0; i < rows; ++i)
+ nk_panel_alloc_row(ctx, win);
+ cols = index;
+ }
+ /* non table layout need to allocate space */
+ if (layout->row.type != NK_LAYOUT_DYNAMIC_FIXED &&
+ layout->row.type != NK_LAYOUT_STATIC_FIXED) {
+ for (i = 0; i < cols; ++i)
+ nk_panel_alloc_space(&none, ctx);
+ }
+ layout->row.index = index;
+}
+
+/*----------------------------------------------------------------
+ *
+ * TEXT
+ *
+ * --------------------------------------------------------------*/
+NK_API void
+nk_text_colored(struct nk_context *ctx, const char *str, int len,
+ nk_flags alignment, struct nk_color color)
+{
+ struct nk_window *win;
+ const struct nk_style *style;
+
+ struct nk_vec2 item_padding;
+ struct nk_rect bounds;
+ struct nk_text text;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout) return;
+
+ win = ctx->current;
+ style = &ctx->style;
+ nk_panel_alloc_space(&bounds, ctx);
+ item_padding = style->text.padding;
+
+ text.padding.x = item_padding.x;
+ text.padding.y = item_padding.y;
+ text.background = style->window.background;
+ text.text = color;
+ nk_widget_text(&win->buffer, bounds, str, len, &text, alignment, style->font);
+}
+
+NK_API void
+nk_text_wrap_colored(struct nk_context *ctx, const char *str,
+ int len, struct nk_color color)
+{
+ struct nk_window *win;
+ const struct nk_style *style;
+
+ struct nk_vec2 item_padding;
+ struct nk_rect bounds;
+ struct nk_text text;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout) return;
+
+ win = ctx->current;
+ style = &ctx->style;
+ nk_panel_alloc_space(&bounds, ctx);
+ item_padding = style->text.padding;
+
+ text.padding.x = item_padding.x;
+ text.padding.y = item_padding.y;
+ text.background = style->window.background;
+ text.text = color;
+ nk_widget_text_wrap(&win->buffer, bounds, str, len, &text, style->font);
+}
+
+#ifdef NK_INCLUDE_STANDARD_VARARGS
+NK_API void
+nk_labelf_colored(struct nk_context *ctx, nk_flags flags,
+ struct nk_color color, const char *fmt, ...)
+{
+ char buf[256];
+ va_list args;
+ va_start(args, fmt);
+ nk_strfmt(buf, NK_LEN(buf), fmt, args);
+ nk_label_colored(ctx, buf, flags, color);
+ va_end(args);
+}
+
+NK_API void
+nk_labelf_colored_wrap(struct nk_context *ctx, struct nk_color color,
+ const char *fmt, ...)
+{
+ char buf[256];
+ va_list args;
+ va_start(args, fmt);
+ nk_strfmt(buf, NK_LEN(buf), fmt, args);
+ nk_label_colored_wrap(ctx, buf, color);
+ va_end(args);
+}
+
+NK_API void
+nk_labelf(struct nk_context *ctx, nk_flags flags, const char *fmt, ...)
+{
+ char buf[256];
+ va_list args;
+ va_start(args, fmt);
+ nk_strfmt(buf, NK_LEN(buf), fmt, args);
+ nk_label(ctx, buf, flags);
+ va_end(args);
+}
+
+NK_API void
+nk_labelf_wrap(struct nk_context *ctx, const char *fmt,...)
+{
+ char buf[256];
+ va_list args;
+ va_start(args, fmt);
+ nk_strfmt(buf, NK_LEN(buf), fmt, args);
+ nk_label_wrap(ctx, buf);
+ va_end(args);
+}
+
+NK_API void
+nk_value_bool(struct nk_context *ctx, const char *prefix, int value)
+{nk_labelf(ctx, NK_TEXT_LEFT, "%s: %s", prefix, ((value) ? "true": "false"));}
+
+NK_API void
+nk_value_int(struct nk_context *ctx, const char *prefix, int value)
+{nk_labelf(ctx, NK_TEXT_LEFT, "%s: %d", prefix, value);}
+
+NK_API void
+nk_value_uint(struct nk_context *ctx, const char *prefix, unsigned int value)
+{nk_labelf(ctx, NK_TEXT_LEFT, "%s: %u", prefix, value);}
+
+NK_API void
+nk_value_float(struct nk_context *ctx, const char *prefix, float value)
+{
+ double double_value = (double)value;
+ nk_labelf(ctx, NK_TEXT_LEFT, "%s: %.3f", prefix, double_value);
+}
+
+NK_API void
+nk_value_color_byte(struct nk_context *ctx, const char *p, struct nk_color c)
+{nk_labelf(ctx, NK_TEXT_LEFT, "%s: (%d, %d, %d, %d)", p, c.r, c.g, c.b, c.a);}
+
+NK_API void
+nk_value_color_float(struct nk_context *ctx, const char *p, struct nk_color color)
+{
+ double c[4]; nk_color_dv(c, color);
+ nk_labelf(ctx, NK_TEXT_LEFT, "%s: (%.2f, %.2f, %.2f, %.2f)",
+ p, c[0], c[1], c[2], c[3]);
+}
+
+NK_API void
+nk_value_color_hex(struct nk_context *ctx, const char *prefix, struct nk_color color)
+{
+ char hex[16];
+ nk_color_hex_rgba(hex, color);
+ nk_labelf(ctx, NK_TEXT_LEFT, "%s: %s", prefix, hex);
+}
+#endif
+
+NK_API void
+nk_text(struct nk_context *ctx, const char *str, int len, nk_flags alignment)
+{
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ nk_text_colored(ctx, str, len, alignment, ctx->style.text.color);
+}
+
+NK_API void
+nk_text_wrap(struct nk_context *ctx, const char *str, int len)
+{
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ nk_text_wrap_colored(ctx, str, len, ctx->style.text.color);
+}
+
+NK_API void
+nk_label(struct nk_context *ctx, const char *str, nk_flags alignment)
+{nk_text(ctx, str, nk_strlen(str), alignment);}
+
+NK_API void
+nk_label_colored(struct nk_context *ctx, const char *str, nk_flags align,
+ struct nk_color color)
+{nk_text_colored(ctx, str, nk_strlen(str), align, color);}
+
+NK_API void
+nk_label_wrap(struct nk_context *ctx, const char *str)
+{nk_text_wrap(ctx, str, nk_strlen(str));}
+
+NK_API void
+nk_label_colored_wrap(struct nk_context *ctx, const char *str, struct nk_color color)
+{nk_text_wrap_colored(ctx, str, nk_strlen(str), color);}
+
+NK_API void
+nk_image(struct nk_context *ctx, struct nk_image img)
+{
+ struct nk_window *win;
+ struct nk_rect bounds;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout) return;
+
+ win = ctx->current;
+ if (!nk_widget(&bounds, ctx)) return;
+ nk_draw_image(&win->buffer, bounds, &img, nk_white);
+}
+
+/*----------------------------------------------------------------
+ *
+ * BUTTON
+ *
+ * --------------------------------------------------------------*/
+NK_API void
+nk_button_set_behavior(struct nk_context *ctx, enum nk_button_behavior behavior)
+{
+ NK_ASSERT(ctx);
+ if (!ctx) return;
+ ctx->button_behavior = behavior;
+}
+
+NK_API int
+nk_button_push_behavior(struct nk_context *ctx, enum nk_button_behavior behavior)
+{
+ struct nk_config_stack_button_behavior *button_stack;
+ struct nk_config_stack_button_behavior_element *element;
+
+ NK_ASSERT(ctx);
+ if (!ctx) return 0;
+
+ button_stack = &ctx->stacks.button_behaviors;
+ NK_ASSERT(button_stack->head < (int)NK_LEN(button_stack->elements));
+ if (button_stack->head >= (int)NK_LEN(button_stack->elements))
+ return 0;
+
+ element = &button_stack->elements[button_stack->head++];
+ element->address = &ctx->button_behavior;
+ element->old_value = ctx->button_behavior;
+ ctx->button_behavior = behavior;
+ return 1;
+}
+
+NK_API int
+nk_button_pop_behavior(struct nk_context *ctx)
+{
+ struct nk_config_stack_button_behavior *button_stack;
+ struct nk_config_stack_button_behavior_element *element;
+
+ NK_ASSERT(ctx);
+ if (!ctx) return 0;
+
+ button_stack = &ctx->stacks.button_behaviors;
+ NK_ASSERT(button_stack->head > 0);
+ if (button_stack->head < 1)
+ return 0;
+
+ element = &button_stack->elements[--button_stack->head];
+ *element->address = element->old_value;
+ return 1;
+}
+
+NK_API int
+nk_button_text_styled(struct nk_context *ctx,
+ const struct nk_style_button *style, const char *title, int len)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_input *in;
+
+ struct nk_rect bounds;
+ enum nk_widget_layout_states state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(style);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!style || !ctx || !ctx->current || !ctx->current->layout) return 0;
+
+ win = ctx->current;
+ layout = win->layout;
+ state = nk_widget(&bounds, ctx);
+
+ if (!state) return 0;
+ in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ return nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds,
+ title, len, style->text_alignment, ctx->button_behavior,
+ style, in, ctx->style.font);
+}
+
+NK_API int
+nk_button_text(struct nk_context *ctx, const char *title, int len)
+{
+ NK_ASSERT(ctx);
+ if (!ctx) return 0;
+ return nk_button_text_styled(ctx, &ctx->style.button, title, len);
+}
+
+NK_API int nk_button_label_styled(struct nk_context *ctx,
+ const struct nk_style_button *style, const char *title)
+{return nk_button_text_styled(ctx, style, title, nk_strlen(title));}
+
+NK_API int nk_button_label(struct nk_context *ctx, const char *title)
+{return nk_button_text(ctx, title, nk_strlen(title));}
+
+NK_API int
+nk_button_color(struct nk_context *ctx, struct nk_color color)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_input *in;
+ struct nk_style_button button;
+
+ int ret = 0;
+ struct nk_rect bounds;
+ struct nk_rect content;
+ enum nk_widget_layout_states state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ layout = win->layout;
+
+ state = nk_widget(&bounds, ctx);
+ if (!state) return 0;
+ in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+
+ button = ctx->style.button;
+ button.normal = nk_style_item_color(color);
+ button.hover = nk_style_item_color(color);
+ button.active = nk_style_item_color(color);
+ ret = nk_do_button(&ctx->last_widget_state, &win->buffer, bounds,
+ &button, in, ctx->button_behavior, &content);
+ nk_draw_button(&win->buffer, &bounds, ctx->last_widget_state, &button);
+ return ret;
+}
+
+NK_API int
+nk_button_symbol_styled(struct nk_context *ctx,
+ const struct nk_style_button *style, enum nk_symbol_type symbol)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_input *in;
+
+ struct nk_rect bounds;
+ enum nk_widget_layout_states state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ layout = win->layout;
+ state = nk_widget(&bounds, ctx);
+ if (!state) return 0;
+ in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ return nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, bounds,
+ symbol, ctx->button_behavior, style, in, ctx->style.font);
+}
+
+NK_API int
+nk_button_symbol(struct nk_context *ctx, enum nk_symbol_type symbol)
+{
+ NK_ASSERT(ctx);
+ if (!ctx) return 0;
+ return nk_button_symbol_styled(ctx, &ctx->style.button, symbol);
+}
+
+NK_API int
+nk_button_image_styled(struct nk_context *ctx, const struct nk_style_button *style,
+ struct nk_image img)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_input *in;
+
+ struct nk_rect bounds;
+ enum nk_widget_layout_states state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ layout = win->layout;
+
+ state = nk_widget(&bounds, ctx);
+ if (!state) return 0;
+ in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ return nk_do_button_image(&ctx->last_widget_state, &win->buffer, bounds,
+ img, ctx->button_behavior, style, in);
+}
+
+NK_API int
+nk_button_image(struct nk_context *ctx, struct nk_image img)
+{
+ NK_ASSERT(ctx);
+ if (!ctx) return 0;
+ return nk_button_image_styled(ctx, &ctx->style.button, img);
+}
+
+NK_API int
+nk_button_symbol_text_styled(struct nk_context *ctx,
+ const struct nk_style_button *style, enum nk_symbol_type symbol,
+ const char *text, int len, nk_flags align)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_input *in;
+
+ struct nk_rect bounds;
+ enum nk_widget_layout_states state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ layout = win->layout;
+
+ state = nk_widget(&bounds, ctx);
+ if (!state) return 0;
+ in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ return nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds,
+ symbol, text, len, align, ctx->button_behavior,
+ style, ctx->style.font, in);
+}
+
+NK_API int
+nk_button_symbol_text(struct nk_context *ctx, enum nk_symbol_type symbol,
+ const char* text, int len, nk_flags align)
+{
+ NK_ASSERT(ctx);
+ if (!ctx) return 0;
+ return nk_button_symbol_text_styled(ctx, &ctx->style.button, symbol, text, len, align);
+}
+
+NK_API int nk_button_symbol_label(struct nk_context *ctx, enum nk_symbol_type symbol,
+ const char *label, nk_flags align)
+{return nk_button_symbol_text(ctx, symbol, label, nk_strlen(label), align);}
+
+NK_API int nk_button_symbol_label_styled(struct nk_context *ctx,
+ const struct nk_style_button *style, enum nk_symbol_type symbol,
+ const char *title, nk_flags align)
+{return nk_button_symbol_text_styled(ctx, style, symbol, title, nk_strlen(title), align);}
+
+NK_API int
+nk_button_image_text_styled(struct nk_context *ctx,
+ const struct nk_style_button *style, struct nk_image img, const char *text,
+ int len, nk_flags align)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_input *in;
+
+ struct nk_rect bounds;
+ enum nk_widget_layout_states state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ layout = win->layout;
+
+ state = nk_widget(&bounds, ctx);
+ if (!state) return 0;
+ in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ return nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
+ bounds, img, text, len, align, ctx->button_behavior,
+ style, ctx->style.font, in);
+}
+
+NK_API int
+nk_button_image_text(struct nk_context *ctx, struct nk_image img,
+ const char *text, int len, nk_flags align)
+{return nk_button_image_text_styled(ctx, &ctx->style.button,img, text, len, align);}
+
+
+NK_API int nk_button_image_label(struct nk_context *ctx, struct nk_image img,
+ const char *label, nk_flags align)
+{return nk_button_image_text(ctx, img, label, nk_strlen(label), align);}
+
+NK_API int nk_button_image_label_styled(struct nk_context *ctx,
+ const struct nk_style_button *style, struct nk_image img,
+ const char *label, nk_flags text_alignment)
+{return nk_button_image_text_styled(ctx, style, img, label, nk_strlen(label), text_alignment);}
+
+/*----------------------------------------------------------------
+ *
+ * SELECTABLE
+ *
+ * --------------------------------------------------------------*/
+NK_API int
+nk_selectable_text(struct nk_context *ctx, const char *str, int len,
+ nk_flags align, int *value)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_input *in;
+ const struct nk_style *style;
+
+ enum nk_widget_layout_states state;
+ struct nk_rect bounds;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(value);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout || !value)
+ return 0;
+
+ win = ctx->current;
+ layout = win->layout;
+ style = &ctx->style;
+
+ state = nk_widget(&bounds, ctx);
+ if (!state) return 0;
+ in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ return nk_do_selectable(&ctx->last_widget_state, &win->buffer, bounds,
+ str, len, align, value, &style->selectable, in, style->font);
+}
+
+NK_API int
+nk_selectable_image_text(struct nk_context *ctx, struct nk_image img,
+ const char *str, int len, nk_flags align, int *value)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_input *in;
+ const struct nk_style *style;
+
+ enum nk_widget_layout_states state;
+ struct nk_rect bounds;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(value);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout || !value)
+ return 0;
+
+ win = ctx->current;
+ layout = win->layout;
+ style = &ctx->style;
+
+ state = nk_widget(&bounds, ctx);
+ if (!state) return 0;
+ in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ return nk_do_selectable_image(&ctx->last_widget_state, &win->buffer, bounds,
+ str, len, align, value, &img, &style->selectable, in, style->font);
+}
+
+NK_API int nk_select_text(struct nk_context *ctx, const char *str, int len,
+ nk_flags align, int value)
+{nk_selectable_text(ctx, str, len, align, &value);return value;}
+
+NK_API int nk_selectable_label(struct nk_context *ctx, const char *str, nk_flags align, int *value)
+{return nk_selectable_text(ctx, str, nk_strlen(str), align, value);}
+
+NK_API int nk_selectable_image_label(struct nk_context *ctx,struct nk_image img,
+ const char *str, nk_flags align, int *value)
+{return nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, value);}
+
+NK_API int nk_select_label(struct nk_context *ctx, const char *str, nk_flags align, int value)
+{nk_selectable_text(ctx, str, nk_strlen(str), align, &value);return value;}
+
+NK_API int nk_select_image_label(struct nk_context *ctx, struct nk_image img,
+ const char *str, nk_flags align, int value)
+{nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, &value);return value;}
+
+NK_API int nk_select_image_text(struct nk_context *ctx, struct nk_image img,
+ const char *str, int len, nk_flags align, int value)
+{nk_selectable_image_text(ctx, img, str, len, align, &value);return value;}
+
+/*----------------------------------------------------------------
+ *
+ * CHECKBOX
+ *
+ * --------------------------------------------------------------*/
+NK_API int
+nk_check_text(struct nk_context *ctx, const char *text, int len, int active)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_input *in;
+ const struct nk_style *style;
+
+ struct nk_rect bounds;
+ enum nk_widget_layout_states state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return active;
+
+ win = ctx->current;
+ style = &ctx->style;
+ layout = win->layout;
+
+ state = nk_widget(&bounds, ctx);
+ if (!state) return active;
+ in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &active,
+ text, len, NK_TOGGLE_CHECK, &style->checkbox, in, style->font);
+ return active;
+}
+
+NK_API unsigned int
+nk_check_flags_text(struct nk_context *ctx, const char *text, int len,
+ unsigned int flags, unsigned int value)
+{
+ int old_active;
+ NK_ASSERT(ctx);
+ NK_ASSERT(text);
+ if (!ctx || !text) return flags;
+ old_active = (int)((flags & value) & value);
+ if (nk_check_text(ctx, text, len, old_active))
+ flags |= value;
+ else flags &= ~value;
+ return flags;
+}
+
+NK_API int
+nk_checkbox_text(struct nk_context *ctx, const char *text, int len, int *active)
+{
+ int old_val;
+ NK_ASSERT(ctx);
+ NK_ASSERT(text);
+ NK_ASSERT(active);
+ if (!ctx || !text || !active) return 0;
+ old_val = *active;
+ *active = nk_check_text(ctx, text, len, *active);
+ return old_val != *active;
+}
+
+NK_API int
+nk_checkbox_flags_text(struct nk_context *ctx, const char *text, int len,
+ unsigned int *flags, unsigned int value)
+{
+ int active;
+ NK_ASSERT(ctx);
+ NK_ASSERT(text);
+ NK_ASSERT(flags);
+ if (!ctx || !text || !flags) return 0;
+
+ active = (int)((*flags & value) & value);
+ if (nk_checkbox_text(ctx, text, len, &active)) {
+ if (active) *flags |= value;
+ else *flags &= ~value;
+ return 1;
+ }
+ return 0;
+}
+
+NK_API int nk_check_label(struct nk_context *ctx, const char *label, int active)
+{return nk_check_text(ctx, label, nk_strlen(label), active);}
+
+NK_API unsigned int nk_check_flags_label(struct nk_context *ctx, const char *label,
+ unsigned int flags, unsigned int value)
+{return nk_check_flags_text(ctx, label, nk_strlen(label), flags, value);}
+
+NK_API int nk_checkbox_label(struct nk_context *ctx, const char *label, int *active)
+{return nk_checkbox_text(ctx, label, nk_strlen(label), active);}
+
+NK_API int nk_checkbox_flags_label(struct nk_context *ctx, const char *label,
+ unsigned int *flags, unsigned int value)
+{return nk_checkbox_flags_text(ctx, label, nk_strlen(label), flags, value);}
+
+/*----------------------------------------------------------------
+ *
+ * OPTION
+ *
+ * --------------------------------------------------------------*/
+NK_API int
+nk_option_text(struct nk_context *ctx, const char *text, int len, int is_active)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_input *in;
+ const struct nk_style *style;
+
+ struct nk_rect bounds;
+ enum nk_widget_layout_states state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return is_active;
+
+ win = ctx->current;
+ style = &ctx->style;
+ layout = win->layout;
+
+ state = nk_widget(&bounds, ctx);
+ if (!state) return state;
+ in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &is_active,
+ text, len, NK_TOGGLE_OPTION, &style->option, in, style->font);
+ return is_active;
+}
+
+NK_API int
+nk_radio_text(struct nk_context *ctx, const char *text, int len, int *active)
+{
+ int old_value;
+ NK_ASSERT(ctx);
+ NK_ASSERT(text);
+ NK_ASSERT(active);
+ if (!ctx || !text || !active) return 0;
+ old_value = *active;
+ *active = nk_option_text(ctx, text, len, old_value);
+ return old_value != *active;
+}
+
+NK_API int
+nk_option_label(struct nk_context *ctx, const char *label, int active)
+{return nk_option_text(ctx, label, nk_strlen(label), active);}
+
+NK_API int
+nk_radio_label(struct nk_context *ctx, const char *label, int *active)
+{return nk_radio_text(ctx, label, nk_strlen(label), active);}
+
+/*----------------------------------------------------------------
+ *
+ * SLIDER
+ *
+ * --------------------------------------------------------------*/
+NK_API int
+nk_slider_float(struct nk_context *ctx, float min_value, float *value, float max_value,
+ float value_step)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ struct nk_input *in;
+ const struct nk_style *style;
+
+ int ret = 0;
+ float old_value;
+ struct nk_rect bounds;
+ enum nk_widget_layout_states state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ NK_ASSERT(value);
+ if (!ctx || !ctx->current || !ctx->current->layout || !value)
+ return ret;
+
+ win = ctx->current;
+ style = &ctx->style;
+ layout = win->layout;
+
+ state = nk_widget(&bounds, ctx);
+ if (!state) return ret;
+ in = (/*state == NK_WIDGET_ROM || */ layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+
+ old_value = *value;
+ *value = nk_do_slider(&ctx->last_widget_state, &win->buffer, bounds, min_value,
+ old_value, max_value, value_step, &style->slider, in, style->font);
+ return (old_value > *value || old_value < *value);
+}
+
+NK_API float
+nk_slide_float(struct nk_context *ctx, float min, float val, float max, float step)
+{
+ nk_slider_float(ctx, min, &val, max, step); return val;
+}
+
+NK_API int
+nk_slide_int(struct nk_context *ctx, int min, int val, int max, int step)
+{
+ float value = (float)val;
+ nk_slider_float(ctx, (float)min, &value, (float)max, (float)step);
+ return (int)value;
+}
+
+NK_API int
+nk_slider_int(struct nk_context *ctx, int min, int *val, int max, int step)
+{
+ int ret;
+ float value = (float)*val;
+ ret = nk_slider_float(ctx, (float)min, &value, (float)max, (float)step);
+ *val = (int)value;
+ return ret;
+}
+
+/*----------------------------------------------------------------
+ *
+ * PROGRESSBAR
+ *
+ * --------------------------------------------------------------*/
+NK_API int
+nk_progress(struct nk_context *ctx, nk_size *cur, nk_size max, int is_modifyable)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_style *style;
+ struct nk_input *in;
+
+ struct nk_rect bounds;
+ enum nk_widget_layout_states state;
+ nk_size old_value;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(cur);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout || !cur)
+ return 0;
+
+ win = ctx->current;
+ style = &ctx->style;
+ layout = win->layout;
+ state = nk_widget(&bounds, ctx);
+ if (!state) return 0;
+
+ in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ old_value = *cur;
+ *cur = nk_do_progress(&ctx->last_widget_state, &win->buffer, bounds,
+ *cur, max, is_modifyable, &style->progress, in);
+ return (*cur != old_value);
+}
+
+NK_API nk_size nk_prog(struct nk_context *ctx, nk_size cur, nk_size max, int modifyable)
+{nk_progress(ctx, &cur, max, modifyable);return cur;}
+
+/*----------------------------------------------------------------
+ *
+ * EDIT
+ *
+ * --------------------------------------------------------------*/
+NK_API void
+nk_edit_focus(struct nk_context *ctx, nk_flags flags)
+{
+ nk_hash hash;
+ struct nk_window *win;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current) return;
+
+ win = ctx->current;
+ hash = win->edit.seq;
+ win->edit.active = nk_true;
+ win->edit.name = hash;
+ if (flags & NK_EDIT_ALWAYS_INSERT_MODE)
+ win->edit.mode = NK_TEXT_EDIT_MODE_INSERT;
+}
+
+NK_API void
+nk_edit_unfocus(struct nk_context *ctx)
+{
+ struct nk_window *win;
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current) return;
+
+ win = ctx->current;
+ win->edit.active = nk_false;
+ win->edit.name = 0;
+}
+
+NK_API nk_flags
+nk_edit_string(struct nk_context *ctx, nk_flags flags,
+ char *memory, int *len, int max, nk_plugin_filter filter)
+{
+ nk_hash hash;
+ nk_flags state;
+ struct nk_text_edit *edit;
+ struct nk_window *win;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(memory);
+ NK_ASSERT(len);
+ if (!ctx || !memory || !len)
+ return 0;
+
+ filter = (!filter) ? nk_filter_default: filter;
+ win = ctx->current;
+ hash = win->edit.seq;
+ edit = &ctx->text_edit;
+ nk_textedit_clear_state(&ctx->text_edit, (flags & NK_EDIT_MULTILINE)?
+ NK_TEXT_EDIT_MULTI_LINE: NK_TEXT_EDIT_SINGLE_LINE, filter);
+
+ if (win->edit.active && hash == win->edit.name) {
+ if (flags & NK_EDIT_NO_CURSOR)
+ edit->cursor = nk_utf_len(memory, *len);
+ else edit->cursor = win->edit.cursor;
+ if (!(flags & NK_EDIT_SELECTABLE)) {
+ edit->select_start = win->edit.cursor;
+ edit->select_end = win->edit.cursor;
+ } else {
+ edit->select_start = win->edit.sel_start;
+ edit->select_end = win->edit.sel_end;
+ }
+ edit->mode = win->edit.mode;
+ edit->scrollbar.x = (float)win->edit.scrollbar.x;
+ edit->scrollbar.y = (float)win->edit.scrollbar.y;
+ edit->active = nk_true;
+ } else edit->active = nk_false;
+
+ max = NK_MAX(1, max);
+ *len = NK_MIN(*len, max-1);
+ nk_str_init_fixed(&edit->string, memory, (nk_size)max);
+ edit->string.buffer.allocated = (nk_size)*len;
+ edit->string.len = nk_utf_len(memory, *len);
+ state = nk_edit_buffer(ctx, flags, edit, filter);
+ *len = (int)edit->string.buffer.allocated;
+
+ if (edit->active) {
+ win->edit.cursor = edit->cursor;
+ win->edit.sel_start = edit->select_start;
+ win->edit.sel_end = edit->select_end;
+ win->edit.mode = edit->mode;
+ win->edit.scrollbar.x = (nk_uint)edit->scrollbar.x;
+ win->edit.scrollbar.y = (nk_uint)edit->scrollbar.y;
+ } return state;
+}
+
+NK_API nk_flags
+nk_edit_buffer(struct nk_context *ctx, nk_flags flags,
+ struct nk_text_edit *edit, nk_plugin_filter filter)
+{
+ struct nk_window *win;
+ struct nk_style *style;
+ struct nk_input *in;
+
+ enum nk_widget_layout_states state;
+ struct nk_rect bounds;
+
+ nk_flags ret_flags = 0;
+ unsigned char prev_state;
+ nk_hash hash;
+
+ /* make sure correct values */
+ NK_ASSERT(ctx);
+ NK_ASSERT(edit);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ style = &ctx->style;
+ state = nk_widget(&bounds, ctx);
+ if (!state) return state;
+ in = (win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+
+ /* check if edit is currently hot item */
+ hash = win->edit.seq++;
+ if (win->edit.active && hash == win->edit.name) {
+ if (flags & NK_EDIT_NO_CURSOR)
+ edit->cursor = edit->string.len;
+ if (!(flags & NK_EDIT_SELECTABLE)) {
+ edit->select_start = edit->cursor;
+ edit->select_end = edit->cursor;
+ }
+ if (flags & NK_EDIT_CLIPBOARD)
+ edit->clip = ctx->clip;
+ edit->active = (unsigned char)win->edit.active;
+ } else edit->active = nk_false;
+ edit->mode = win->edit.mode;
+
+ filter = (!filter) ? nk_filter_default: filter;
+ prev_state = (unsigned char)edit->active;
+ in = (flags & NK_EDIT_READ_ONLY) ? 0: in;
+ ret_flags = nk_do_edit(&ctx->last_widget_state, &win->buffer, bounds, flags,
+ filter, edit, &style->edit, in, style->font);
+
+ if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
+ ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_TEXT];
+ if (edit->active && prev_state != edit->active) {
+ /* current edit is now hot */
+ win->edit.active = nk_true;
+ win->edit.name = hash;
+ } else if (prev_state && !edit->active) {
+ /* current edit is now cold */
+ win->edit.active = nk_false;
+ } return ret_flags;
+}
+
+NK_API nk_flags
+nk_edit_string_zero_terminated(struct nk_context *ctx, nk_flags flags,
+ char *buffer, int max, nk_plugin_filter filter)
+{
+ nk_flags result;
+ int len = nk_strlen(buffer);
+ result = nk_edit_string(ctx, flags, buffer, &len, max, filter);
+ buffer[NK_MIN(NK_MAX(max-1,0), len)] = '\0';
+ return result;
+}
+
+/*----------------------------------------------------------------
+ *
+ * PROPERTY
+ *
+ * --------------------------------------------------------------*/
+NK_INTERN struct nk_property_variant
+nk_property_variant_int(int value, int min_value, int max_value, int step)
+{
+ struct nk_property_variant result;
+ result.kind = NK_PROPERTY_INT;
+ result.value.i = value;
+ result.min_value.i = min_value;
+ result.max_value.i = max_value;
+ result.step.i = step;
+ return result;
+}
+
+NK_INTERN struct nk_property_variant
+nk_property_variant_float(float value, float min_value, float max_value, float step)
+{
+ struct nk_property_variant result;
+ result.kind = NK_PROPERTY_FLOAT;
+ result.value.f = value;
+ result.min_value.f = min_value;
+ result.max_value.f = max_value;
+ result.step.f = step;
+ return result;
+}
+
+NK_INTERN struct nk_property_variant
+nk_property_variant_double(double value, double min_value, double max_value,
+ double step)
+{
+ struct nk_property_variant result;
+ result.kind = NK_PROPERTY_DOUBLE;
+ result.value.d = value;
+ result.min_value.d = min_value;
+ result.max_value.d = max_value;
+ result.step.d = step;
+ return result;
+}
+
+NK_INTERN void
+nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant *variant,
+ float inc_per_pixel, const enum nk_property_filter filter)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ struct nk_input *in;
+ const struct nk_style *style;
+
+ struct nk_rect bounds;
+ enum nk_widget_layout_states s;
+
+ int *state = 0;
+ nk_hash hash = 0;
+ char *buffer = 0;
+ int *len = 0;
+ int *cursor = 0;
+ int *select_begin = 0;
+ int *select_end = 0;
+ int old_state;
+
+ char dummy_buffer[NK_MAX_NUMBER_BUFFER];
+ int dummy_state = NK_PROPERTY_DEFAULT;
+ int dummy_length = 0;
+ int dummy_cursor = 0;
+ int dummy_select_begin = 0;
+ int dummy_select_end = 0;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ win = ctx->current;
+ layout = win->layout;
+ style = &ctx->style;
+ s = nk_widget(&bounds, ctx);
+ if (!s) return;
+
+ /* calculate hash from name */
+ if (name[0] == '#') {
+ hash = nk_murmur_hash(name, (int)nk_strlen(name), win->property.seq++);
+ name++; /* special number hash */
+ } else hash = nk_murmur_hash(name, (int)nk_strlen(name), 42);
+
+ /* check if property is currently hot item */
+ if (win->property.active && hash == win->property.name) {
+ buffer = win->property.buffer;
+ len = &win->property.length;
+ cursor = &win->property.cursor;
+ state = &win->property.state;
+ select_begin = &win->property.select_start;
+ select_end = &win->property.select_end;
+ } else {
+ buffer = dummy_buffer;
+ len = &dummy_length;
+ cursor = &dummy_cursor;
+ state = &dummy_state;
+ select_begin = &dummy_select_begin;
+ select_end = &dummy_select_end;
+ }
+
+ /* execute property widget */
+ old_state = *state;
+ ctx->text_edit.clip = ctx->clip;
+ in = ((s == NK_WIDGET_ROM && !win->property.active) ||
+ layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ nk_do_property(&ctx->last_widget_state, &win->buffer, bounds, name,
+ variant, inc_per_pixel, buffer, len, state, cursor, select_begin,
+ select_end, &style->property, filter, in, style->font, &ctx->text_edit,
+ ctx->button_behavior);
+
+ if (in && *state != NK_PROPERTY_DEFAULT && !win->property.active) {
+ /* current property is now hot */
+ win->property.active = 1;
+ NK_MEMCPY(win->property.buffer, buffer, (nk_size)*len);
+ win->property.length = *len;
+ win->property.cursor = *cursor;
+ win->property.state = *state;
+ win->property.name = hash;
+ win->property.select_start = *select_begin;
+ win->property.select_end = *select_end;
+ if (*state == NK_PROPERTY_DRAG) {
+ ctx->input.mouse.grab = nk_true;
+ ctx->input.mouse.grabbed = nk_true;
+ }
+ }
+ /* check if previously active property is now inactive */
+ if (*state == NK_PROPERTY_DEFAULT && old_state != NK_PROPERTY_DEFAULT) {
+ if (old_state == NK_PROPERTY_DRAG) {
+ ctx->input.mouse.grab = nk_false;
+ ctx->input.mouse.grabbed = nk_false;
+ ctx->input.mouse.ungrab = nk_true;
+ }
+ win->property.select_start = 0;
+ win->property.select_end = 0;
+ win->property.active = 0;
+ }
+}
+
+NK_API void
+nk_property_int(struct nk_context *ctx, const char *name,
+ int min, int *val, int max, int step, float inc_per_pixel)
+{
+ struct nk_property_variant variant;
+ NK_ASSERT(ctx);
+ NK_ASSERT(name);
+ NK_ASSERT(val);
+
+ if (!ctx || !ctx->current || !name || !val) return;
+ variant = nk_property_variant_int(*val, min, max, step);
+ nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
+ *val = variant.value.i;
+}
+
+NK_API void
+nk_property_float(struct nk_context *ctx, const char *name,
+ float min, float *val, float max, float step, float inc_per_pixel)
+{
+ struct nk_property_variant variant;
+ NK_ASSERT(ctx);
+ NK_ASSERT(name);
+ NK_ASSERT(val);
+
+ if (!ctx || !ctx->current || !name || !val) return;
+ variant = nk_property_variant_float(*val, min, max, step);
+ nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
+ *val = variant.value.f;
+}
+
+NK_API void
+nk_property_double(struct nk_context *ctx, const char *name,
+ double min, double *val, double max, double step, float inc_per_pixel)
+{
+ struct nk_property_variant variant;
+ NK_ASSERT(ctx);
+ NK_ASSERT(name);
+ NK_ASSERT(val);
+
+ if (!ctx || !ctx->current || !name || !val) return;
+ variant = nk_property_variant_double(*val, min, max, step);
+ nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
+ *val = variant.value.d;
+}
+
+NK_API int
+nk_propertyi(struct nk_context *ctx, const char *name, int min, int val,
+ int max, int step, float inc_per_pixel)
+{
+ struct nk_property_variant variant;
+ NK_ASSERT(ctx);
+ NK_ASSERT(name);
+
+ if (!ctx || !ctx->current || !name) return val;
+ variant = nk_property_variant_int(val, min, max, step);
+ nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT);
+ val = variant.value.i;
+ return val;
+}
+
+NK_API float
+nk_propertyf(struct nk_context *ctx, const char *name, float min,
+ float val, float max, float step, float inc_per_pixel)
+{
+ struct nk_property_variant variant;
+ NK_ASSERT(ctx);
+ NK_ASSERT(name);
+
+ if (!ctx || !ctx->current || !name) return val;
+ variant = nk_property_variant_float(val, min, max, step);
+ nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
+ val = variant.value.f;
+ return val;
+}
+
+NK_API double
+nk_propertyd(struct nk_context *ctx, const char *name, double min,
+ double val, double max, double step, float inc_per_pixel)
+{
+ struct nk_property_variant variant;
+ NK_ASSERT(ctx);
+ NK_ASSERT(name);
+
+ if (!ctx || !ctx->current || !name) return val;
+ variant = nk_property_variant_double(val, min, max, step);
+ nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT);
+ val = variant.value.d;
+ return val;
+}
+
+/*----------------------------------------------------------------
+ *
+ * COLOR PICKER
+ *
+ * --------------------------------------------------------------*/
+NK_API int
+nk_color_pick(struct nk_context * ctx, struct nk_colorf *color,
+ enum nk_color_format fmt)
+{
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_style *config;
+ const struct nk_input *in;
+
+ enum nk_widget_layout_states state;
+ struct nk_rect bounds;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(color);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout || !color)
+ return 0;
+
+ win = ctx->current;
+ config = &ctx->style;
+ layout = win->layout;
+ state = nk_widget(&bounds, ctx);
+ if (!state) return 0;
+ in = (state == NK_WIDGET_ROM || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ return nk_do_color_picker(&ctx->last_widget_state, &win->buffer, color, fmt, bounds,
+ nk_vec2(0,0), in, config->font);
+}
+
+NK_API struct nk_colorf
+nk_color_picker(struct nk_context *ctx, struct nk_colorf color,
+ enum nk_color_format fmt)
+{
+ nk_color_pick(ctx, &color, fmt);
+ return color;
+}
+
+/* -------------------------------------------------------------
+ *
+ * CHART
+ *
+ * --------------------------------------------------------------*/
+NK_API int
+nk_chart_begin_colored(struct nk_context *ctx, enum nk_chart_type type,
+ struct nk_color color, struct nk_color highlight,
+ int count, float min_value, float max_value)
+{
+ struct nk_window *win;
+ struct nk_chart *chart;
+ const struct nk_style *config;
+ const struct nk_style_chart *style;
+
+ const struct nk_style_item *background;
+ struct nk_rect bounds = {0, 0, 0, 0};
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+
+ if (!ctx || !ctx->current || !ctx->current->layout) return 0;
+ if (!nk_widget(&bounds, ctx)) {
+ chart = &ctx->current->layout->chart;
+ nk_zero(chart, sizeof(*chart));
+ return 0;
+ }
+
+ win = ctx->current;
+ config = &ctx->style;
+ chart = &win->layout->chart;
+ style = &config->chart;
+
+ /* setup basic generic chart */
+ nk_zero(chart, sizeof(*chart));
+ chart->x = bounds.x + style->padding.x;
+ chart->y = bounds.y + style->padding.y;
+ chart->w = bounds.w - 2 * style->padding.x;
+ chart->h = bounds.h - 2 * style->padding.y;
+ chart->w = NK_MAX(chart->w, 2 * style->padding.x);
+ chart->h = NK_MAX(chart->h, 2 * style->padding.y);
+
+ /* add first slot into chart */
+ {struct nk_chart_slot *slot = &chart->slots[chart->slot++];
+ slot->type = type;
+ slot->count = count;
+ slot->color = color;
+ slot->highlight = highlight;
+ slot->min = NK_MIN(min_value, max_value);
+ slot->max = NK_MAX(min_value, max_value);
+ slot->range = slot->max - slot->min;}
+
+ /* draw chart background */
+ background = &style->background;
+ if (background->type == NK_STYLE_ITEM_IMAGE) {
+ nk_draw_image(&win->buffer, bounds, &background->data.image, nk_white);
+ } else {
+ nk_fill_rect(&win->buffer, bounds, style->rounding, style->border_color);
+ nk_fill_rect(&win->buffer, nk_shrink_rect(bounds, style->border),
+ style->rounding, style->background.data.color);
+ }
+ return 1;
+}
+
+NK_API int
+nk_chart_begin(struct nk_context *ctx, const enum nk_chart_type type,
+ int count, float min_value, float max_value)
+{return nk_chart_begin_colored(ctx, type, ctx->style.chart.color, ctx->style.chart.selected_color, count, min_value, max_value);}
+
+NK_API void
+nk_chart_add_slot_colored(struct nk_context *ctx, const enum nk_chart_type type,
+ struct nk_color color, struct nk_color highlight,
+ int count, float min_value, float max_value)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ NK_ASSERT(ctx->current->layout->chart.slot < NK_CHART_MAX_SLOT);
+ if (!ctx || !ctx->current || !ctx->current->layout) return;
+ if (ctx->current->layout->chart.slot >= NK_CHART_MAX_SLOT) return;
+
+ /* add another slot into the graph */
+ {struct nk_chart *chart = &ctx->current->layout->chart;
+ struct nk_chart_slot *slot = &chart->slots[chart->slot++];
+ slot->type = type;
+ slot->count = count;
+ slot->color = color;
+ slot->highlight = highlight;
+ slot->min = NK_MIN(min_value, max_value);
+ slot->max = NK_MAX(min_value, max_value);
+ slot->range = slot->max - slot->min;}
+}
+
+NK_API void
+nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type type,
+ int count, float min_value, float max_value)
+{nk_chart_add_slot_colored(ctx, type, ctx->style.chart.color, ctx->style.chart.selected_color, count, min_value, max_value);}
+
+NK_INTERN nk_flags
+nk_chart_push_line(struct nk_context *ctx, struct nk_window *win,
+ struct nk_chart *g, float value, int slot)
+{
+ struct nk_panel *layout = win->layout;
+ const struct nk_input *i = &ctx->input;
+ struct nk_command_buffer *out = &win->buffer;
+
+ nk_flags ret = 0;
+ struct nk_vec2 cur;
+ struct nk_rect bounds;
+ struct nk_color color;
+ float step;
+ float range;
+ float ratio;
+
+ NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
+ step = g->w / (float)g->slots[slot].count;
+ range = g->slots[slot].max - g->slots[slot].min;
+ ratio = (value - g->slots[slot].min) / range;
+
+ if (g->slots[slot].index == 0) {
+ /* first data point does not have a connection */
+ g->slots[slot].last.x = g->x;
+ g->slots[slot].last.y = (g->y + g->h) - ratio * (float)g->h;
+
+ bounds.x = g->slots[slot].last.x - 2;
+ bounds.y = g->slots[slot].last.y - 2;
+ bounds.w = bounds.h = 4;
+
+ color = g->slots[slot].color;
+ if (!(layout->flags & NK_WINDOW_ROM) &&
+ NK_INBOX(i->mouse.pos.x,i->mouse.pos.y, g->slots[slot].last.x-3, g->slots[slot].last.y-3, 6, 6)){
+ ret = nk_input_is_mouse_hovering_rect(i, bounds) ? NK_CHART_HOVERING : 0;
+ ret |= (i->mouse.buttons[NK_BUTTON_LEFT].down &&
+ i->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED: 0;
+ color = g->slots[slot].highlight;
+ }
+ nk_fill_rect(out, bounds, 0, color);
+ g->slots[slot].index += 1;
+ return ret;
+ }
+
+ /* draw a line between the last data point and the new one */
+ color = g->slots[slot].color;
+ cur.x = g->x + (float)(step * (float)g->slots[slot].index);
+ cur.y = (g->y + g->h) - (ratio * (float)g->h);
+ nk_stroke_line(out, g->slots[slot].last.x, g->slots[slot].last.y, cur.x, cur.y, 1.0f, color);
+
+ bounds.x = cur.x - 3;
+ bounds.y = cur.y - 3;
+ bounds.w = bounds.h = 6;
+
+ /* user selection of current data point */
+ if (!(layout->flags & NK_WINDOW_ROM)) {
+ if (nk_input_is_mouse_hovering_rect(i, bounds)) {
+ ret = NK_CHART_HOVERING;
+ ret |= (!i->mouse.buttons[NK_BUTTON_LEFT].down &&
+ i->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED: 0;
+ color = g->slots[slot].highlight;
+ }
+ }
+ nk_fill_rect(out, nk_rect(cur.x - 2, cur.y - 2, 4, 4), 0, color);
+
+ /* save current data point position */
+ g->slots[slot].last.x = cur.x;
+ g->slots[slot].last.y = cur.y;
+ g->slots[slot].index += 1;
+ return ret;
+}
+
+NK_INTERN nk_flags
+nk_chart_push_column(const struct nk_context *ctx, struct nk_window *win,
+ struct nk_chart *chart, float value, int slot)
+{
+ struct nk_command_buffer *out = &win->buffer;
+ const struct nk_input *in = &ctx->input;
+ struct nk_panel *layout = win->layout;
+
+ float ratio;
+ nk_flags ret = 0;
+ struct nk_color color;
+ struct nk_rect item = {0,0,0,0};
+
+ NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
+ if (chart->slots[slot].index >= chart->slots[slot].count)
+ return nk_false;
+ if (chart->slots[slot].count) {
+ float padding = (float)(chart->slots[slot].count-1);
+ item.w = (chart->w - padding) / (float)(chart->slots[slot].count);
+ }
+
+ /* calculate bounds of current bar chart entry */
+ color = chart->slots[slot].color;;
+ item.h = chart->h * NK_ABS((value/chart->slots[slot].range));
+ if (value >= 0) {
+ ratio = (value + NK_ABS(chart->slots[slot].min)) / NK_ABS(chart->slots[slot].range);
+ item.y = (chart->y + chart->h) - chart->h * ratio;
+ } else {
+ ratio = (value - chart->slots[slot].max) / chart->slots[slot].range;
+ item.y = chart->y + (chart->h * NK_ABS(ratio)) - item.h;
+ }
+ item.x = chart->x + ((float)chart->slots[slot].index * item.w);
+ item.x = item.x + ((float)chart->slots[slot].index);
+
+ /* user chart bar selection */
+ if (!(layout->flags & NK_WINDOW_ROM) &&
+ NK_INBOX(in->mouse.pos.x,in->mouse.pos.y,item.x,item.y,item.w,item.h)) {
+ ret = NK_CHART_HOVERING;
+ ret |= (!in->mouse.buttons[NK_BUTTON_LEFT].down &&
+ in->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED: 0;
+ color = chart->slots[slot].highlight;
+ }
+ nk_fill_rect(out, item, 0, color);
+ chart->slots[slot].index += 1;
+ return ret;
+}
+
+NK_API nk_flags
+nk_chart_push_slot(struct nk_context *ctx, float value, int slot)
+{
+ nk_flags flags;
+ struct nk_window *win;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT);
+ NK_ASSERT(slot < ctx->current->layout->chart.slot);
+ if (!ctx || !ctx->current || slot >= NK_CHART_MAX_SLOT) return nk_false;
+ if (slot >= ctx->current->layout->chart.slot) return nk_false;
+
+ win = ctx->current;
+ if (win->layout->chart.slot < slot) return nk_false;
+ switch (win->layout->chart.slots[slot].type) {
+ case NK_CHART_LINES:
+ flags = nk_chart_push_line(ctx, win, &win->layout->chart, value, slot); break;
+ case NK_CHART_COLUMN:
+ flags = nk_chart_push_column(ctx, win, &win->layout->chart, value, slot); break;
+ default:
+ case NK_CHART_MAX:
+ flags = 0;
+ }
+ return flags;
+}
+
+NK_API nk_flags
+nk_chart_push(struct nk_context *ctx, float value)
+{return nk_chart_push_slot(ctx, value, 0);}
+
+NK_API void
+nk_chart_end(struct nk_context *ctx)
+{
+ struct nk_window *win;
+ struct nk_chart *chart;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current)
+ return;
+
+ win = ctx->current;
+ chart = &win->layout->chart;
+ NK_MEMSET(chart, 0, sizeof(*chart));
+ return;
+}
+
+NK_API void
+nk_plot(struct nk_context *ctx, enum nk_chart_type type, const float *values,
+ int count, int offset)
+{
+ int i = 0;
+ float min_value;
+ float max_value;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(values);
+ if (!ctx || !values || !count) return;
+
+ min_value = values[offset];
+ max_value = values[offset];
+ for (i = 0; i < count; ++i) {
+ min_value = NK_MIN(values[i + offset], min_value);
+ max_value = NK_MAX(values[i + offset], max_value);
+ }
+
+ if (nk_chart_begin(ctx, type, count, min_value, max_value)) {
+ for (i = 0; i < count; ++i)
+ nk_chart_push(ctx, values[i + offset]);
+ nk_chart_end(ctx);
+ }
+}
+
+NK_API void
+nk_plot_function(struct nk_context *ctx, enum nk_chart_type type, void *userdata,
+ float(*value_getter)(void* user, int index), int count, int offset)
+{
+ int i = 0;
+ float min_value;
+ float max_value;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(value_getter);
+ if (!ctx || !value_getter || !count) return;
+
+ max_value = min_value = value_getter(userdata, offset);
+ for (i = 0; i < count; ++i) {
+ float value = value_getter(userdata, i + offset);
+ min_value = NK_MIN(value, min_value);
+ max_value = NK_MAX(value, max_value);
+ }
+
+ if (nk_chart_begin(ctx, type, count, min_value, max_value)) {
+ for (i = 0; i < count; ++i)
+ nk_chart_push(ctx, value_getter(userdata, i + offset));
+ nk_chart_end(ctx);
+ }
+}
+
+/* -------------------------------------------------------------
+ *
+ * GROUP
+ *
+ * --------------------------------------------------------------*/
+NK_API int
+nk_group_scrolled_offset_begin(struct nk_context *ctx,
+ nk_uint *x_offset, nk_uint *y_offset, const char *title, nk_flags flags)
+{
+ struct nk_rect bounds;
+ struct nk_window panel;
+ struct nk_window *win;
+
+ win = ctx->current;
+ nk_panel_alloc_space(&bounds, ctx);
+ {const struct nk_rect *c = &win->layout->clip;
+ if (!NK_INTERSECT(c->x, c->y, c->w, c->h, bounds.x, bounds.y, bounds.w, bounds.h) &&
+ !(flags & NK_WINDOW_MOVABLE)) {
+ return 0;
+ }}
+ if (win->flags & NK_WINDOW_ROM)
+ flags |= NK_WINDOW_ROM;
+
+ /* initialize a fake window to create the panel from */
+ nk_zero(&panel, sizeof(panel));
+ panel.bounds = bounds;
+ panel.flags = flags;
+ panel.scrollbar.x = *x_offset;
+ panel.scrollbar.y = *y_offset;
+ panel.buffer = win->buffer;
+ panel.layout = (struct nk_panel*)nk_create_panel(ctx);
+ ctx->current = &panel;
+ nk_panel_begin(ctx, (flags & NK_WINDOW_TITLE) ? title: 0, NK_PANEL_GROUP);
+
+ win->buffer = panel.buffer;
+ win->buffer.clip = panel.layout->clip;
+ panel.layout->offset_x = x_offset;
+ panel.layout->offset_y = y_offset;
+ panel.layout->parent = win->layout;
+ win->layout = panel.layout;
+
+ ctx->current = win;
+ if ((panel.layout->flags & NK_WINDOW_CLOSED) ||
+ (panel.layout->flags & NK_WINDOW_MINIMIZED))
+ {
+ nk_flags f = panel.layout->flags;
+ nk_group_scrolled_end(ctx);
+ if (f & NK_WINDOW_CLOSED)
+ return NK_WINDOW_CLOSED;
+ if (f & NK_WINDOW_MINIMIZED)
+ return NK_WINDOW_MINIMIZED;
+ }
+ return 1;
+}
+
+NK_API void
+nk_group_scrolled_end(struct nk_context *ctx)
+{
+ struct nk_window *win;
+ struct nk_panel *parent;
+ struct nk_panel *g;
+
+ struct nk_rect clip;
+ struct nk_window pan;
+ struct nk_vec2 panel_padding;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current)
+ return;
+
+ /* make sure nk_group_begin was called correctly */
+ NK_ASSERT(ctx->current);
+ win = ctx->current;
+ NK_ASSERT(win->layout);
+ g = win->layout;
+ NK_ASSERT(g->parent);
+ parent = g->parent;
+
+ /* dummy window */
+ nk_zero_struct(pan);
+ panel_padding = nk_panel_get_padding(&ctx->style, NK_PANEL_GROUP);
+ pan.bounds.y = g->bounds.y - (g->header_height + g->menu.h);
+ pan.bounds.x = g->bounds.x - panel_padding.x;
+ pan.bounds.w = g->bounds.w + 2 * panel_padding.x;
+ pan.bounds.h = g->bounds.h + g->header_height + g->menu.h;
+ if (g->flags & NK_WINDOW_BORDER) {
+ pan.bounds.x -= g->border;
+ pan.bounds.y -= g->border;
+ pan.bounds.w += 2*g->border;
+ pan.bounds.h += 2*g->border;
+ }
+ if (!(g->flags & NK_WINDOW_NO_SCROLLBAR)) {
+ pan.bounds.w += ctx->style.window.scrollbar_size.x;
+ pan.bounds.h += ctx->style.window.scrollbar_size.y;
+ }
+ pan.scrollbar.x = *g->offset_x;
+ pan.scrollbar.y = *g->offset_y;
+ pan.flags = g->flags;
+ pan.buffer = win->buffer;
+ pan.layout = g;
+ pan.parent = win;
+ ctx->current = &pan;
+
+ /* make sure group has correct clipping rectangle */
+ nk_unify(&clip, &parent->clip, pan.bounds.x, pan.bounds.y,
+ pan.bounds.x + pan.bounds.w, pan.bounds.y + pan.bounds.h + panel_padding.x);
+ nk_push_scissor(&pan.buffer, clip);
+ nk_end(ctx);
+
+ win->buffer = pan.buffer;
+ nk_push_scissor(&win->buffer, parent->clip);
+ ctx->current = win;
+ win->layout = parent;
+ g->bounds = pan.bounds;
+ return;
+}
+
+NK_API int
+nk_group_scrolled_begin(struct nk_context *ctx,
+ struct nk_scroll *scroll, const char *title, nk_flags flags)
+{return nk_group_scrolled_offset_begin(ctx, &scroll->x, &scroll->y, title, flags);}
+
+NK_API int
+nk_group_begin_titled(struct nk_context *ctx, const char *id,
+ const char *title, nk_flags flags)
+{
+ int id_len;
+ nk_hash id_hash;
+ struct nk_window *win;
+ nk_uint *x_offset;
+ nk_uint *y_offset;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(id);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout || !id)
+ return 0;
+
+ /* find persistent group scrollbar value */
+ win = ctx->current;
+ id_len = (int)nk_strlen(id);
+ id_hash = nk_murmur_hash(id, (int)id_len, NK_PANEL_GROUP);
+ x_offset = nk_find_value(win, id_hash);
+ if (!x_offset) {
+ x_offset = nk_add_value(ctx, win, id_hash, 0);
+ y_offset = nk_add_value(ctx, win, id_hash+1, 0);
+
+ NK_ASSERT(x_offset);
+ NK_ASSERT(y_offset);
+ if (!x_offset || !y_offset) return 0;
+ *x_offset = *y_offset = 0;
+ } else y_offset = nk_find_value(win, id_hash+1);
+ return nk_group_scrolled_offset_begin(ctx, x_offset, y_offset, title, flags);
+}
+
+NK_API int
+nk_group_begin(struct nk_context *ctx, const char *title, nk_flags flags)
+{
+ return nk_group_begin_titled(ctx, title, title, flags);
+}
+
+NK_API void
+nk_group_end(struct nk_context *ctx)
+{nk_group_scrolled_end(ctx);}
+
+NK_API int
+nk_list_view_begin(struct nk_context *ctx, struct nk_list_view *view,
+ const char *title, nk_flags flags, int row_height, int row_count)
+{
+ int title_len;
+ nk_hash title_hash;
+ nk_uint *x_offset;
+ nk_uint *y_offset;
+
+ int result;
+ struct nk_window *win;
+ struct nk_panel *layout;
+ const struct nk_style *style;
+ struct nk_vec2 item_spacing;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(view);
+ NK_ASSERT(title);
+ if (!ctx || !view || !title) return 0;
+
+ win = ctx->current;
+ style = &ctx->style;
+ item_spacing = style->window.spacing;
+ row_height += NK_MAX(0, (int)item_spacing.y);
+
+ /* find persistent list view scrollbar offset */
+ title_len = (int)nk_strlen(title);
+ title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_GROUP);
+ x_offset = nk_find_value(win, title_hash);
+ if (!x_offset) {
+ x_offset = nk_add_value(ctx, win, title_hash, 0);
+ y_offset = nk_add_value(ctx, win, title_hash+1, 0);
+
+ NK_ASSERT(x_offset);
+ NK_ASSERT(y_offset);
+ if (!x_offset || !y_offset) return 0;
+ *x_offset = *y_offset = 0;
+ } else y_offset = nk_find_value(win, title_hash+1);
+ view->scroll_value = *y_offset;
+ view->scroll_pointer = y_offset;
+
+ *y_offset = 0;
+ result = nk_group_scrolled_offset_begin(ctx, x_offset, y_offset, title, flags);
+ win = ctx->current;
+ layout = win->layout;
+
+ view->total_height = row_height * NK_MAX(row_count,1);
+ view->begin = (int)NK_MAX(((float)view->scroll_value / (float)row_height), 0.0f);
+ view->count = (int)NK_MAX(nk_iceilf((layout->clip.h)/(float)row_height), 0);
+ view->end = view->begin + view->count;
+ view->ctx = ctx;
+ return result;
+}
+
+NK_API void
+nk_list_view_end(struct nk_list_view *view)
+{
+ struct nk_context *ctx;
+ struct nk_window *win;
+ struct nk_panel *layout;
+
+ NK_ASSERT(view);
+ NK_ASSERT(view->ctx);
+ NK_ASSERT(view->scroll_pointer);
+ if (!view || !view->ctx) return;
+
+ ctx = view->ctx;
+ win = ctx->current;
+ layout = win->layout;
+ layout->at_y = layout->bounds.y + (float)view->total_height;
+ *view->scroll_pointer = *view->scroll_pointer + view->scroll_value;
+ nk_group_end(view->ctx);
+}
+
+/* --------------------------------------------------------------
+ *
+ * POPUP
+ *
+ * --------------------------------------------------------------*/
+NK_API int
+nk_popup_begin(struct nk_context *ctx, enum nk_popup_type type,
+ const char *title, nk_flags flags, struct nk_rect rect)
+{
+ struct nk_window *popup;
+ struct nk_window *win;
+ struct nk_panel *panel;
+
+ int title_len;
+ nk_hash title_hash;
+ nk_size allocated;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(title);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ panel = win->layout;
+ NK_ASSERT(!(panel->type & NK_PANEL_SET_POPUP) && "popups are not allowed to have popups");
+ (void)panel;
+ title_len = (int)nk_strlen(title);
+ title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_POPUP);
+
+ popup = win->popup.win;
+ if (!popup) {
+ popup = (struct nk_window*)nk_create_window(ctx);
+ popup->parent = win;
+ win->popup.win = popup;
+ win->popup.active = 0;
+ win->popup.type = NK_PANEL_POPUP;
+ }
+
+ /* make sure we have correct popup */
+ if (win->popup.name != title_hash) {
+ if (!win->popup.active) {
+ nk_zero(popup, sizeof(*popup));
+ win->popup.name = title_hash;
+ win->popup.active = 1;
+ win->popup.type = NK_PANEL_POPUP;
+ } else return 0;
+ }
+
+ /* popup position is local to window */
+ ctx->current = popup;
+ rect.x += win->layout->clip.x;
+ rect.y += win->layout->clip.y;
+
+ /* setup popup data */
+ popup->parent = win;
+ popup->bounds = rect;
+ popup->seq = ctx->seq;
+ popup->layout = (struct nk_panel*)nk_create_panel(ctx);
+ popup->flags = flags;
+ popup->flags |= NK_WINDOW_BORDER;
+ if (type == NK_POPUP_DYNAMIC)
+ popup->flags |= NK_WINDOW_DYNAMIC;
+
+ popup->buffer = win->buffer;
+ nk_start_popup(ctx, win);
+ allocated = ctx->memory.allocated;
+ nk_push_scissor(&popup->buffer, nk_null_rect);
+
+ if (nk_panel_begin(ctx, title, NK_PANEL_POPUP)) {
+ /* popup is running therefore invalidate parent panels */
+ struct nk_panel *root;
+ root = win->layout;
+ while (root) {
+ root->flags |= NK_WINDOW_ROM;
+ root->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM;
+ root = root->parent;
+ }
+ win->popup.active = 1;
+ popup->layout->offset_x = &popup->scrollbar.x;
+ popup->layout->offset_y = &popup->scrollbar.y;
+ popup->layout->parent = win->layout;
+ return 1;
+ } else {
+ /* popup was closed/is invalid so cleanup */
+ struct nk_panel *root;
+ root = win->layout;
+ while (root) {
+ root->flags |= NK_WINDOW_REMOVE_ROM;
+ root = root->parent;
+ }
+ win->popup.buf.active = 0;
+ win->popup.active = 0;
+ ctx->memory.allocated = allocated;
+ ctx->current = win;
+ nk_free_panel(ctx, popup->layout);
+ popup->layout = 0;
+ return 0;
+ }
+}
+
+NK_INTERN int
+nk_nonblock_begin(struct nk_context *ctx,
+ nk_flags flags, struct nk_rect body, struct nk_rect header,
+ enum nk_panel_type panel_type)
+{
+ struct nk_window *popup;
+ struct nk_window *win;
+ struct nk_panel *panel;
+ int is_active = nk_true;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ /* popups cannot have popups */
+ win = ctx->current;
+ panel = win->layout;
+ NK_ASSERT(!(panel->type & NK_PANEL_SET_POPUP));
+ (void)panel;
+ popup = win->popup.win;
+ if (!popup) {
+ /* create window for nonblocking popup */
+ popup = (struct nk_window*)nk_create_window(ctx);
+ popup->parent = win;
+ win->popup.win = popup;
+ win->popup.type = panel_type;
+ nk_command_buffer_init(&popup->buffer, &ctx->memory, NK_CLIPPING_ON);
+ } else {
+ /* close the popup if user pressed outside or in the header */
+ int pressed, in_body, in_header;
+ pressed = nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT);
+ in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body);
+ in_header = nk_input_is_mouse_hovering_rect(&ctx->input, header);
+ if (pressed && (!in_body || in_header))
+ is_active = nk_false;
+ }
+ win->popup.header = header;
+
+ if (!is_active) {
+ /* remove read only mode from all parent panels */
+ struct nk_panel *root = win->layout;
+ while (root) {
+ root->flags |= NK_WINDOW_REMOVE_ROM;
+ root = root->parent;
+ }
+ return is_active;
+ }
+
+ popup->bounds = body;
+ popup->parent = win;
+ popup->layout = (struct nk_panel*)nk_create_panel(ctx);
+ popup->flags = flags;
+ popup->flags |= NK_WINDOW_BORDER;
+ popup->flags |= NK_WINDOW_DYNAMIC;
+ popup->seq = ctx->seq;
+ win->popup.active = 1;
+ NK_ASSERT(popup->layout);
+
+ nk_start_popup(ctx, win);
+ popup->buffer = win->buffer;
+ nk_push_scissor(&popup->buffer, nk_null_rect);
+ ctx->current = popup;
+
+ nk_panel_begin(ctx, 0, panel_type);
+ win->buffer = popup->buffer;
+ popup->layout->parent = win->layout;
+ popup->layout->offset_x = &popup->scrollbar.x;
+ popup->layout->offset_y = &popup->scrollbar.y;
+
+ /* set read only mode to all parent panels */
+ {struct nk_panel *root;
+ root = win->layout;
+ while (root) {
+ root->flags |= NK_WINDOW_ROM;
+ root = root->parent;
+ }}
+ return is_active;
+}
+
+NK_API void
+nk_popup_close(struct nk_context *ctx)
+{
+ struct nk_window *popup;
+ NK_ASSERT(ctx);
+ if (!ctx || !ctx->current) return;
+
+ popup = ctx->current;
+ NK_ASSERT(popup->parent);
+ NK_ASSERT(popup->layout->type & NK_PANEL_SET_POPUP);
+ popup->flags |= NK_WINDOW_HIDDEN;
+}
+
+NK_API void
+nk_popup_end(struct nk_context *ctx)
+{
+ struct nk_window *win;
+ struct nk_window *popup;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return;
+
+ popup = ctx->current;
+ if (!popup->parent) return;
+ win = popup->parent;
+ if (popup->flags & NK_WINDOW_HIDDEN) {
+ struct nk_panel *root;
+ root = win->layout;
+ while (root) {
+ root->flags |= NK_WINDOW_REMOVE_ROM;
+ root = root->parent;
+ }
+ win->popup.active = 0;
+ }
+ nk_push_scissor(&popup->buffer, nk_null_rect);
+ nk_end(ctx);
+
+ win->buffer = popup->buffer;
+ nk_finish_popup(ctx, win);
+ ctx->current = win;
+ nk_push_scissor(&win->buffer, win->layout->clip);
+}
+/* -------------------------------------------------------------
+ *
+ * TOOLTIP
+ *
+ * -------------------------------------------------------------- */
+NK_API int
+nk_tooltip_begin(struct nk_context *ctx, float width)
+{
+ int x,y,w,h;
+ struct nk_window *win;
+ const struct nk_input *in;
+ struct nk_rect bounds;
+ int ret;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ /* make sure that no nonblocking popup is currently active */
+ win = ctx->current;
+ in = &ctx->input;
+ if (win->popup.win && (win->popup.type & NK_PANEL_SET_NONBLOCK))
+ return 0;
+
+ w = nk_iceilf(width);
+ h = nk_iceilf(nk_null_rect.h);
+ x = nk_ifloorf(in->mouse.pos.x + 1) - (int)win->layout->clip.x;
+ y = nk_ifloorf(in->mouse.pos.y + 1) - (int)win->layout->clip.y;
+
+ bounds.x = (float)x;
+ bounds.y = (float)y;
+ bounds.w = (float)w;
+ bounds.h = (float)h;
+
+ ret = nk_popup_begin(ctx, NK_POPUP_DYNAMIC,
+ "__##Tooltip##__", NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER, bounds);
+ if (ret) win->layout->flags &= ~(nk_flags)NK_WINDOW_ROM;
+ win->popup.type = NK_PANEL_TOOLTIP;
+ ctx->current->layout->type = NK_PANEL_TOOLTIP;
+ return ret;
+}
+
+NK_API void
+nk_tooltip_end(struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current) return;
+ ctx->current->seq--;
+ nk_popup_close(ctx);
+ nk_popup_end(ctx);
+}
+
+NK_API void
+nk_tooltip(struct nk_context *ctx, const char *text)
+{
+ const struct nk_style *style;
+ struct nk_vec2 padding;
+
+ int text_len;
+ float text_width;
+ float text_height;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ NK_ASSERT(text);
+ if (!ctx || !ctx->current || !ctx->current->layout || !text)
+ return;
+
+ /* fetch configuration data */
+ style = &ctx->style;
+ padding = style->window.padding;
+
+ /* calculate size of the text and tooltip */
+ text_len = nk_strlen(text);
+ text_width = style->font->width(style->font->userdata,
+ style->font->height, text, text_len);
+ text_width += (4 * padding.x);
+ text_height = (style->font->height + 2 * padding.y);
+
+ /* execute tooltip and fill with text */
+ if (nk_tooltip_begin(ctx, (float)text_width)) {
+ nk_layout_row_dynamic(ctx, (float)text_height, 1);
+ nk_text(ctx, text, text_len, NK_TEXT_LEFT);
+ nk_tooltip_end(ctx);
+ }
+}
+#ifdef NK_INCLUDE_STANDARD_VARARGS
+NK_API void
+nk_tooltipf(struct nk_context *ctx, const char *fmt, ...)
+{
+ char buf[256];
+ va_list args;
+ va_start(args, fmt);
+ nk_strfmt(buf, NK_LEN(buf), fmt, args);
+ va_end(args);
+ nk_tooltip(ctx, buf);
+}
+#endif
+
+/* -------------------------------------------------------------
+ *
+ * CONTEXTUAL
+ *
+ * -------------------------------------------------------------- */
+NK_API int
+nk_contextual_begin(struct nk_context *ctx, nk_flags flags, struct nk_vec2 size,
+ struct nk_rect trigger_bounds)
+{
+ struct nk_window *win;
+ struct nk_window *popup;
+ struct nk_rect body;
+
+ NK_STORAGE const struct nk_rect null_rect = {0,0,0,0};
+ int is_clicked = 0;
+ int is_active = 0;
+ int is_open = 0;
+ int ret = 0;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ ++win->popup.con_count;
+
+ /* check if currently active contextual is active */
+ popup = win->popup.win;
+ is_open = (popup && win->popup.type == NK_PANEL_CONTEXTUAL);
+ is_clicked = nk_input_mouse_clicked(&ctx->input, NK_BUTTON_RIGHT, trigger_bounds);
+ if (win->popup.active_con && win->popup.con_count != win->popup.active_con)
+ return 0;
+ if ((is_clicked && is_open && !is_active) || (!is_open && !is_active && !is_clicked))
+ return 0;
+
+ /* calculate contextual position on click */
+ win->popup.active_con = win->popup.con_count;
+ if (is_clicked) {
+ body.x = ctx->input.mouse.pos.x;
+ body.y = ctx->input.mouse.pos.y;
+ } else {
+ body.x = popup->bounds.x;
+ body.y = popup->bounds.y;
+ }
+ body.w = size.x;
+ body.h = size.y;
+
+ /* start nonblocking contextual popup */
+ ret = nk_nonblock_begin(ctx, flags|NK_WINDOW_NO_SCROLLBAR, body,
+ null_rect, NK_PANEL_CONTEXTUAL);
+ if (ret) win->popup.type = NK_PANEL_CONTEXTUAL;
+ else {
+ win->popup.active_con = 0;
+ if (win->popup.win)
+ win->popup.win->flags = 0;
+ }
+ return ret;
+}
+
+NK_API int
+nk_contextual_item_text(struct nk_context *ctx, const char *text, int len,
+ nk_flags alignment)
+{
+ struct nk_window *win;
+ const struct nk_input *in;
+ const struct nk_style *style;
+
+ struct nk_rect bounds;
+ enum nk_widget_layout_states state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ style = &ctx->style;
+ state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
+ if (!state) return nk_false;
+
+ in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds,
+ text, len, alignment, NK_BUTTON_DEFAULT, &style->contextual_button, in, style->font)) {
+ nk_contextual_close(ctx);
+ return nk_true;
+ }
+ return nk_false;
+}
+
+NK_API int nk_contextual_item_label(struct nk_context *ctx, const char *label, nk_flags align)
+{return nk_contextual_item_text(ctx, label, nk_strlen(label), align);}
+
+NK_API int
+nk_contextual_item_image_text(struct nk_context *ctx, struct nk_image img,
+ const char *text, int len, nk_flags align)
+{
+ struct nk_window *win;
+ const struct nk_input *in;
+ const struct nk_style *style;
+
+ struct nk_rect bounds;
+ enum nk_widget_layout_states state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ style = &ctx->style;
+ state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
+ if (!state) return nk_false;
+
+ in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer, bounds,
+ img, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)){
+ nk_contextual_close(ctx);
+ return nk_true;
+ }
+ return nk_false;
+}
+
+NK_API int nk_contextual_item_image_label(struct nk_context *ctx, struct nk_image img,
+ const char *label, nk_flags align)
+{return nk_contextual_item_image_text(ctx, img, label, nk_strlen(label), align);}
+
+NK_API int
+nk_contextual_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type symbol,
+ const char *text, int len, nk_flags align)
+{
+ struct nk_window *win;
+ const struct nk_input *in;
+ const struct nk_style *style;
+
+ struct nk_rect bounds;
+ enum nk_widget_layout_states state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ style = &ctx->style;
+ state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding);
+ if (!state) return nk_false;
+
+ in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds,
+ symbol, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)) {
+ nk_contextual_close(ctx);
+ return nk_true;
+ }
+ return nk_false;
+}
+
+NK_API int nk_contextual_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type symbol,
+ const char *text, nk_flags align)
+{return nk_contextual_item_symbol_text(ctx, symbol, text, nk_strlen(text), align);}
+
+NK_API void
+nk_contextual_close(struct nk_context *ctx)
+{
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout) return;
+ nk_popup_close(ctx);
+}
+
+NK_API void
+nk_contextual_end(struct nk_context *ctx)
+{
+ struct nk_window *popup;
+ struct nk_panel *panel;
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !ctx->current) return;
+
+ popup = ctx->current;
+ panel = popup->layout;
+ NK_ASSERT(popup->parent);
+ NK_ASSERT(panel->type & NK_PANEL_SET_POPUP);
+ if (panel->flags & NK_WINDOW_DYNAMIC) {
+ /* Close behavior
+ This is a bit of a hack solution since we do not know before we end our popup
+ how big it will be. We therefore do not directly know when a
+ click outside the non-blocking popup must close it at that direct frame.
+ Instead it will be closed in the next frame.*/
+ struct nk_rect body = {0,0,0,0};
+ if (panel->at_y < (panel->bounds.y + panel->bounds.h)) {
+ struct nk_vec2 padding = nk_panel_get_padding(&ctx->style, panel->type);
+ body = panel->bounds;
+ body.y = (panel->at_y + panel->footer_height + panel->border + padding.y + panel->row.height);
+ body.h = (panel->bounds.y + panel->bounds.h) - body.y;
+ }
+ {int pressed = nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT);
+ int in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body);
+ if (pressed && in_body)
+ popup->flags |= NK_WINDOW_HIDDEN;
+ }
+ }
+ if (popup->flags & NK_WINDOW_HIDDEN)
+ popup->seq = 0;
+ nk_popup_end(ctx);
+ return;
+}
+/* -------------------------------------------------------------
+ *
+ * COMBO
+ *
+ * --------------------------------------------------------------*/
+NK_INTERN int
+nk_combo_begin(struct nk_context *ctx, struct nk_window *win,
+ struct nk_vec2 size, int is_clicked, struct nk_rect header)
+{
+ struct nk_window *popup;
+ int is_open = 0;
+ int is_active = 0;
+ struct nk_rect body;
+ nk_hash hash;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ popup = win->popup.win;
+ body.x = header.x;
+ body.w = size.x;
+ body.y = header.y + header.h-ctx->style.window.combo_border;
+ body.h = size.y;
+
+ hash = win->popup.combo_count++;
+ is_open = (popup) ? nk_true:nk_false;
+ is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_COMBO);
+ if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
+ (!is_open && !is_active && !is_clicked)) return 0;
+ if (!nk_nonblock_begin(ctx, 0, body,
+ (is_clicked && is_open)?nk_rect(0,0,0,0):header, NK_PANEL_COMBO)) return 0;
+
+ win->popup.type = NK_PANEL_COMBO;
+ win->popup.name = hash;
+ return 1;
+}
+
+NK_API int
+nk_combo_begin_text(struct nk_context *ctx, const char *selected, int len,
+ struct nk_vec2 size)
+{
+ const struct nk_input *in;
+ struct nk_window *win;
+ struct nk_style *style;
+
+ enum nk_widget_layout_states s;
+ int is_clicked = nk_false;
+ struct nk_rect header;
+ const struct nk_style_item *background;
+ struct nk_text text;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(selected);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout || !selected)
+ return 0;
+
+ win = ctx->current;
+ style = &ctx->style;
+ s = nk_widget(&header, ctx);
+ if (s == NK_WIDGET_INVALID)
+ return 0;
+
+ in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
+ if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
+ is_clicked = nk_true;
+
+ /* draw combo box header background and border */
+ if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
+ background = &style->combo.active;
+ text.text = style->combo.label_active;
+ } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
+ background = &style->combo.hover;
+ text.text = style->combo.label_hover;
+ } else {
+ background = &style->combo.normal;
+ text.text = style->combo.label_normal;
+ }
+ if (background->type == NK_STYLE_ITEM_IMAGE) {
+ text.background = nk_rgba(0,0,0,0);
+ nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
+ } else {
+ text.background = background->data.color;
+ nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
+ nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
+ }
+ {
+ /* print currently selected text item */
+ struct nk_rect label;
+ struct nk_rect button;
+ struct nk_rect content;
+
+ enum nk_symbol_type sym;
+ if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
+ sym = style->combo.sym_hover;
+ else if (is_clicked)
+ sym = style->combo.sym_active;
+ else sym = style->combo.sym_normal;
+
+ /* calculate button */
+ button.w = header.h - 2 * style->combo.button_padding.y;
+ button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
+ button.y = header.y + style->combo.button_padding.y;
+ button.h = button.w;
+
+ content.x = button.x + style->combo.button.padding.x;
+ content.y = button.y + style->combo.button.padding.y;
+ content.w = button.w - 2 * style->combo.button.padding.x;
+ content.h = button.h - 2 * style->combo.button.padding.y;
+
+ /* draw selected label */
+ text.padding = nk_vec2(0,0);
+ label.x = header.x + style->combo.content_padding.x;
+ label.y = header.y + style->combo.content_padding.y;
+ label.w = button.x - (style->combo.content_padding.x + style->combo.spacing.x) - label.x;;
+ label.h = header.h - 2 * style->combo.content_padding.y;
+ nk_widget_text(&win->buffer, label, selected, len, &text,
+ NK_TEXT_LEFT, ctx->style.font);
+
+ /* draw open/close button */
+ nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
+ &ctx->style.combo.button, sym, style->font);
+ }
+ return nk_combo_begin(ctx, win, size, is_clicked, header);
+}
+
+NK_API int nk_combo_begin_label(struct nk_context *ctx, const char *selected, struct nk_vec2 size)
+{return nk_combo_begin_text(ctx, selected, nk_strlen(selected), size);}
+
+NK_API int
+nk_combo_begin_color(struct nk_context *ctx, struct nk_color color, struct nk_vec2 size)
+{
+ struct nk_window *win;
+ struct nk_style *style;
+ const struct nk_input *in;
+
+ struct nk_rect header;
+ int is_clicked = nk_false;
+ enum nk_widget_layout_states s;
+ const struct nk_style_item *background;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ style = &ctx->style;
+ s = nk_widget(&header, ctx);
+ if (s == NK_WIDGET_INVALID)
+ return 0;
+
+ in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
+ if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
+ is_clicked = nk_true;
+
+ /* draw combo box header background and border */
+ if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED)
+ background = &style->combo.active;
+ else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
+ background = &style->combo.hover;
+ else background = &style->combo.normal;
+
+ if (background->type == NK_STYLE_ITEM_IMAGE) {
+ nk_draw_image(&win->buffer, header, &background->data.image,nk_white);
+ } else {
+ nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
+ nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
+ }
+ {
+ struct nk_rect content;
+ struct nk_rect button;
+ struct nk_rect bounds;
+
+ enum nk_symbol_type sym;
+ if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
+ sym = style->combo.sym_hover;
+ else if (is_clicked)
+ sym = style->combo.sym_active;
+ else sym = style->combo.sym_normal;
+
+ /* calculate button */
+ button.w = header.h - 2 * style->combo.button_padding.y;
+ button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
+ button.y = header.y + style->combo.button_padding.y;
+ button.h = button.w;
+
+ content.x = button.x + style->combo.button.padding.x;
+ content.y = button.y + style->combo.button.padding.y;
+ content.w = button.w - 2 * style->combo.button.padding.x;
+ content.h = button.h - 2 * style->combo.button.padding.y;
+
+ /* draw color */
+ bounds.h = header.h - 4 * style->combo.content_padding.y;
+ bounds.y = header.y + 2 * style->combo.content_padding.y;
+ bounds.x = header.x + 2 * style->combo.content_padding.x;
+ bounds.w = (button.x - (style->combo.content_padding.x + style->combo.spacing.x)) - bounds.x;
+ nk_fill_rect(&win->buffer, bounds, 0, color);
+
+ /* draw open/close button */
+ nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
+ &ctx->style.combo.button, sym, style->font);
+ }
+ return nk_combo_begin(ctx, win, size, is_clicked, header);
+}
+
+NK_API int
+nk_combo_begin_symbol(struct nk_context *ctx, enum nk_symbol_type symbol, struct nk_vec2 size)
+{
+ struct nk_window *win;
+ struct nk_style *style;
+ const struct nk_input *in;
+
+ struct nk_rect header;
+ int is_clicked = nk_false;
+ enum nk_widget_layout_states s;
+ const struct nk_style_item *background;
+ struct nk_color sym_background;
+ struct nk_color symbol_color;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ style = &ctx->style;
+ s = nk_widget(&header, ctx);
+ if (s == NK_WIDGET_INVALID)
+ return 0;
+
+ in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
+ if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
+ is_clicked = nk_true;
+
+ /* draw combo box header background and border */
+ if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
+ background = &style->combo.active;
+ symbol_color = style->combo.symbol_active;
+ } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
+ background = &style->combo.hover;
+ symbol_color = style->combo.symbol_hover;
+ } else {
+ background = &style->combo.normal;
+ symbol_color = style->combo.symbol_hover;
+ }
+
+ if (background->type == NK_STYLE_ITEM_IMAGE) {
+ sym_background = nk_rgba(0,0,0,0);
+ nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
+ } else {
+ sym_background = background->data.color;
+ nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
+ nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
+ }
+ {
+ struct nk_rect bounds = {0,0,0,0};
+ struct nk_rect content;
+ struct nk_rect button;
+
+ enum nk_symbol_type sym;
+ if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
+ sym = style->combo.sym_hover;
+ else if (is_clicked)
+ sym = style->combo.sym_active;
+ else sym = style->combo.sym_normal;
+
+ /* calculate button */
+ button.w = header.h - 2 * style->combo.button_padding.y;
+ button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
+ button.y = header.y + style->combo.button_padding.y;
+ button.h = button.w;
+
+ content.x = button.x + style->combo.button.padding.x;
+ content.y = button.y + style->combo.button.padding.y;
+ content.w = button.w - 2 * style->combo.button.padding.x;
+ content.h = button.h - 2 * style->combo.button.padding.y;
+
+ /* draw symbol */
+ bounds.h = header.h - 2 * style->combo.content_padding.y;
+ bounds.y = header.y + style->combo.content_padding.y;
+ bounds.x = header.x + style->combo.content_padding.x;
+ bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
+ nk_draw_symbol(&win->buffer, symbol, bounds, sym_background, symbol_color,
+ 1.0f, style->font);
+
+ /* draw open/close button */
+ nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
+ &ctx->style.combo.button, sym, style->font);
+ }
+ return nk_combo_begin(ctx, win, size, is_clicked, header);
+}
+
+NK_API int
+nk_combo_begin_symbol_text(struct nk_context *ctx, const char *selected, int len,
+ enum nk_symbol_type symbol, struct nk_vec2 size)
+{
+ struct nk_window *win;
+ struct nk_style *style;
+ struct nk_input *in;
+
+ struct nk_rect header;
+ int is_clicked = nk_false;
+ enum nk_widget_layout_states s;
+ const struct nk_style_item *background;
+ struct nk_color symbol_color;
+ struct nk_text text;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ style = &ctx->style;
+ s = nk_widget(&header, ctx);
+ if (!s) return 0;
+
+ in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
+ if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
+ is_clicked = nk_true;
+
+ /* draw combo box header background and border */
+ if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
+ background = &style->combo.active;
+ symbol_color = style->combo.symbol_active;
+ text.text = style->combo.label_active;
+ } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
+ background = &style->combo.hover;
+ symbol_color = style->combo.symbol_hover;
+ text.text = style->combo.label_hover;
+ } else {
+ background = &style->combo.normal;
+ symbol_color = style->combo.symbol_normal;
+ text.text = style->combo.label_normal;
+ }
+ if (background->type == NK_STYLE_ITEM_IMAGE) {
+ text.background = nk_rgba(0,0,0,0);
+ nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
+ } else {
+ text.background = background->data.color;
+ nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
+ nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
+ }
+ {
+ struct nk_rect content;
+ struct nk_rect button;
+ struct nk_rect label;
+ struct nk_rect image;
+
+ enum nk_symbol_type sym;
+ if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
+ sym = style->combo.sym_hover;
+ else if (is_clicked)
+ sym = style->combo.sym_active;
+ else sym = style->combo.sym_normal;
+
+ /* calculate button */
+ button.w = header.h - 2 * style->combo.button_padding.y;
+ button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
+ button.y = header.y + style->combo.button_padding.y;
+ button.h = button.w;
+
+ content.x = button.x + style->combo.button.padding.x;
+ content.y = button.y + style->combo.button.padding.y;
+ content.w = button.w - 2 * style->combo.button.padding.x;
+ content.h = button.h - 2 * style->combo.button.padding.y;
+ nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
+ &ctx->style.combo.button, sym, style->font);
+
+ /* draw symbol */
+ image.x = header.x + style->combo.content_padding.x;
+ image.y = header.y + style->combo.content_padding.y;
+ image.h = header.h - 2 * style->combo.content_padding.y;
+ image.w = image.h;
+ nk_draw_symbol(&win->buffer, symbol, image, text.background, symbol_color,
+ 1.0f, style->font);
+
+ /* draw label */
+ text.padding = nk_vec2(0,0);
+ label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
+ label.y = header.y + style->combo.content_padding.y;
+ label.w = (button.x - style->combo.content_padding.x) - label.x;
+ label.h = header.h - 2 * style->combo.content_padding.y;
+ nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
+ }
+ return nk_combo_begin(ctx, win, size, is_clicked, header);
+}
+
+NK_API int
+nk_combo_begin_image(struct nk_context *ctx, struct nk_image img, struct nk_vec2 size)
+{
+ struct nk_window *win;
+ struct nk_style *style;
+ const struct nk_input *in;
+
+ struct nk_rect header;
+ int is_clicked = nk_false;
+ enum nk_widget_layout_states s;
+ const struct nk_style_item *background;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ style = &ctx->style;
+ s = nk_widget(&header, ctx);
+ if (s == NK_WIDGET_INVALID)
+ return 0;
+
+ in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
+ if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
+ is_clicked = nk_true;
+
+ /* draw combo box header background and border */
+ if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED)
+ background = &style->combo.active;
+ else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
+ background = &style->combo.hover;
+ else background = &style->combo.normal;
+
+ if (background->type == NK_STYLE_ITEM_IMAGE) {
+ nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
+ } else {
+ nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
+ nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
+ }
+ {
+ struct nk_rect bounds = {0,0,0,0};
+ struct nk_rect content;
+ struct nk_rect button;
+
+ enum nk_symbol_type sym;
+ if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
+ sym = style->combo.sym_hover;
+ else if (is_clicked)
+ sym = style->combo.sym_active;
+ else sym = style->combo.sym_normal;
+
+ /* calculate button */
+ button.w = header.h - 2 * style->combo.button_padding.y;
+ button.x = (header.x + header.w - header.h) - style->combo.button_padding.y;
+ button.y = header.y + style->combo.button_padding.y;
+ button.h = button.w;
+
+ content.x = button.x + style->combo.button.padding.x;
+ content.y = button.y + style->combo.button.padding.y;
+ content.w = button.w - 2 * style->combo.button.padding.x;
+ content.h = button.h - 2 * style->combo.button.padding.y;
+
+ /* draw image */
+ bounds.h = header.h - 2 * style->combo.content_padding.y;
+ bounds.y = header.y + style->combo.content_padding.y;
+ bounds.x = header.x + style->combo.content_padding.x;
+ bounds.w = (button.x - style->combo.content_padding.y) - bounds.x;
+ nk_draw_image(&win->buffer, bounds, &img, nk_white);
+
+ /* draw open/close button */
+ nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state,
+ &ctx->style.combo.button, sym, style->font);
+ }
+ return nk_combo_begin(ctx, win, size, is_clicked, header);
+}
+
+NK_API int
+nk_combo_begin_image_text(struct nk_context *ctx, const char *selected, int len,
+ struct nk_image img, struct nk_vec2 size)
+{
+ struct nk_window *win;
+ struct nk_style *style;
+ struct nk_input *in;
+
+ struct nk_rect header;
+ int is_clicked = nk_false;
+ enum nk_widget_layout_states s;
+ const struct nk_style_item *background;
+ struct nk_text text;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ style = &ctx->style;
+ s = nk_widget(&header, ctx);
+ if (!s) return 0;
+
+ in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_ROM)? 0: &ctx->input;
+ if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT))
+ is_clicked = nk_true;
+
+ /* draw combo box header background and border */
+ if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) {
+ background = &style->combo.active;
+ text.text = style->combo.label_active;
+ } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) {
+ background = &style->combo.hover;
+ text.text = style->combo.label_hover;
+ } else {
+ background = &style->combo.normal;
+ text.text = style->combo.label_normal;
+ }
+ if (background->type == NK_STYLE_ITEM_IMAGE) {
+ text.background = nk_rgba(0,0,0,0);
+ nk_draw_image(&win->buffer, header, &background->data.image, nk_white);
+ } else {
+ text.background = background->data.color;
+ nk_fill_rect(&win->buffer, header, style->combo.rounding, background->data.color);
+ nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, style->combo.border_color);
+ }
+ {
+ struct nk_rect content;
+ struct nk_rect button;
+ struct nk_rect label;
+ struct nk_rect image;
+
+ enum nk_symbol_type sym;
+ if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER)
+ sym = style->combo.sym_hover;
+ else if (is_clicked)
+ sym = style->combo.sym_active;
+ else sym = style->combo.sym_normal;
+
+ /* calculate button */
+ button.w = header.h - 2 * style->combo.button_padding.y;
+ button.x = (header.x + header.w - header.h) - style->combo.button_padding.x;
+ button.y = header.y + style->combo.button_padding.y;
+ button.h = button.w;
+
+ content.x = button.x + style->combo.button.padding.x;
+ content.y = button.y + style->combo.button.padding.y;
+ content.w = button.w - 2 * style->combo.button.padding.x;
+ content.h = button.h - 2 * style->combo.button.padding.y;
+ nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state,
+ &ctx->style.combo.button, sym, style->font);
+
+ /* draw image */
+ image.x = header.x + style->combo.content_padding.x;
+ image.y = header.y + style->combo.content_padding.y;
+ image.h = header.h - 2 * style->combo.content_padding.y;
+ image.w = image.h;
+ nk_draw_image(&win->buffer, image, &img, nk_white);
+
+ /* draw label */
+ text.padding = nk_vec2(0,0);
+ label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x;
+ label.y = header.y + style->combo.content_padding.y;
+ label.w = (button.x - style->combo.content_padding.x) - label.x;
+ label.h = header.h - 2 * style->combo.content_padding.y;
+ nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font);
+ }
+ return nk_combo_begin(ctx, win, size, is_clicked, header);
+}
+
+NK_API int nk_combo_begin_symbol_label(struct nk_context *ctx,
+ const char *selected, enum nk_symbol_type type, struct nk_vec2 size)
+{return nk_combo_begin_symbol_text(ctx, selected, nk_strlen(selected), type, size);}
+
+NK_API int nk_combo_begin_image_label(struct nk_context *ctx,
+ const char *selected, struct nk_image img, struct nk_vec2 size)
+{return nk_combo_begin_image_text(ctx, selected, nk_strlen(selected), img, size);}
+
+NK_API int nk_combo_item_text(struct nk_context *ctx, const char *text, int len,nk_flags align)
+{return nk_contextual_item_text(ctx, text, len, align);}
+
+NK_API int nk_combo_item_label(struct nk_context *ctx, const char *label, nk_flags align)
+{return nk_contextual_item_label(ctx, label, align);}
+
+NK_API int nk_combo_item_image_text(struct nk_context *ctx, struct nk_image img, const char *text,
+ int len, nk_flags alignment)
+{return nk_contextual_item_image_text(ctx, img, text, len, alignment);}
+
+NK_API int nk_combo_item_image_label(struct nk_context *ctx, struct nk_image img,
+ const char *text, nk_flags alignment)
+{return nk_contextual_item_image_label(ctx, img, text, alignment);}
+
+NK_API int nk_combo_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym,
+ const char *text, int len, nk_flags alignment)
+{return nk_contextual_item_symbol_text(ctx, sym, text, len, alignment);}
+
+NK_API int nk_combo_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym,
+ const char *label, nk_flags alignment)
+{return nk_contextual_item_symbol_label(ctx, sym, label, alignment);}
+
+NK_API void nk_combo_end(struct nk_context *ctx)
+{nk_contextual_end(ctx);}
+
+NK_API void nk_combo_close(struct nk_context *ctx)
+{nk_contextual_close(ctx);}
+
+NK_API int
+nk_combo(struct nk_context *ctx, const char **items, int count,
+ int selected, int item_height, struct nk_vec2 size)
+{
+ int i = 0;
+ int max_height;
+ struct nk_vec2 item_spacing;
+ struct nk_vec2 window_padding;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(items);
+ NK_ASSERT(ctx->current);
+ if (!ctx || !items ||!count)
+ return selected;
+
+ item_spacing = ctx->style.window.spacing;
+ window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
+ max_height = count * item_height + count * (int)item_spacing.y;
+ max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
+ size.y = NK_MIN(size.y, (float)max_height);
+ if (nk_combo_begin_label(ctx, items[selected], size)) {
+ nk_layout_row_dynamic(ctx, (float)item_height, 1);
+ for (i = 0; i < count; ++i) {
+ if (nk_combo_item_label(ctx, items[i], NK_TEXT_LEFT))
+ selected = i;
+ }
+ nk_combo_end(ctx);
+ }
+ return selected;
+}
+
+NK_API int
+nk_combo_separator(struct nk_context *ctx, const char *items_separated_by_separator,
+ int separator, int selected, int count, int item_height, struct nk_vec2 size)
+{
+ int i;
+ int max_height;
+ struct nk_vec2 item_spacing;
+ struct nk_vec2 window_padding;
+ const char *current_item;
+ const char *iter;
+ int length = 0;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(items_separated_by_separator);
+ if (!ctx || !items_separated_by_separator)
+ return selected;
+
+ /* calculate popup window */
+ item_spacing = ctx->style.window.spacing;
+ window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
+ max_height = count * item_height + count * (int)item_spacing.y;
+ max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
+ size.y = NK_MIN(size.y, (float)max_height);
+
+ /* find selected item */
+ current_item = items_separated_by_separator;
+ for (i = 0; i < count; ++i) {
+ iter = current_item;
+ while (*iter && *iter != separator) iter++;
+ length = (int)(iter - current_item);
+ if (i == selected) break;
+ current_item = iter + 1;
+ }
+
+ if (nk_combo_begin_text(ctx, current_item, length, size)) {
+ current_item = items_separated_by_separator;
+ nk_layout_row_dynamic(ctx, (float)item_height, 1);
+ for (i = 0; i < count; ++i) {
+ iter = current_item;
+ while (*iter && *iter != separator) iter++;
+ length = (int)(iter - current_item);
+ if (nk_combo_item_text(ctx, current_item, length, NK_TEXT_LEFT))
+ selected = i;
+ current_item = current_item + length + 1;
+ }
+ nk_combo_end(ctx);
+ }
+ return selected;
+}
+
+NK_API int
+nk_combo_string(struct nk_context *ctx, const char *items_separated_by_zeros,
+ int selected, int count, int item_height, struct nk_vec2 size)
+{return nk_combo_separator(ctx, items_separated_by_zeros, '\0', selected, count, item_height, size);}
+
+NK_API int
+nk_combo_callback(struct nk_context *ctx, void(*item_getter)(void*, int, const char**),
+ void *userdata, int selected, int count, int item_height, struct nk_vec2 size)
+{
+ int i;
+ int max_height;
+ struct nk_vec2 item_spacing;
+ struct nk_vec2 window_padding;
+ const char *item;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(item_getter);
+ if (!ctx || !item_getter)
+ return selected;
+
+ /* calculate popup window */
+ item_spacing = ctx->style.window.spacing;
+ window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type);
+ max_height = count * item_height + count * (int)item_spacing.y;
+ max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2;
+ size.y = NK_MIN(size.y, (float)max_height);
+
+ item_getter(userdata, selected, &item);
+ if (nk_combo_begin_label(ctx, item, size)) {
+ nk_layout_row_dynamic(ctx, (float)item_height, 1);
+ for (i = 0; i < count; ++i) {
+ item_getter(userdata, i, &item);
+ if (nk_combo_item_label(ctx, item, NK_TEXT_LEFT))
+ selected = i;
+ }
+ nk_combo_end(ctx);
+ }
+ return selected;
+}
+
+NK_API void nk_combobox(struct nk_context *ctx, const char **items, int count,
+ int *selected, int item_height, struct nk_vec2 size)
+{*selected = nk_combo(ctx, items, count, *selected, item_height, size);}
+
+NK_API void nk_combobox_string(struct nk_context *ctx, const char *items_separated_by_zeros,
+ int *selected, int count, int item_height, struct nk_vec2 size)
+{*selected = nk_combo_string(ctx, items_separated_by_zeros, *selected, count, item_height, size);}
+
+NK_API void nk_combobox_separator(struct nk_context *ctx, const char *items_separated_by_separator,
+ int separator,int *selected, int count, int item_height, struct nk_vec2 size)
+{*selected = nk_combo_separator(ctx, items_separated_by_separator, separator,
+ *selected, count, item_height, size);}
+
+NK_API void nk_combobox_callback(struct nk_context *ctx,
+ void(*item_getter)(void* data, int id, const char **out_text),
+ void *userdata, int *selected, int count, int item_height, struct nk_vec2 size)
+{*selected = nk_combo_callback(ctx, item_getter, userdata, *selected, count, item_height, size);}
+
+/*
+ * -------------------------------------------------------------
+ *
+ * MENU
+ *
+ * --------------------------------------------------------------
+ */
+NK_INTERN int
+nk_menu_begin(struct nk_context *ctx, struct nk_window *win,
+ const char *id, int is_clicked, struct nk_rect header, struct nk_vec2 size)
+{
+ int is_open = 0;
+ int is_active = 0;
+ struct nk_rect body;
+ struct nk_window *popup;
+ nk_hash hash = nk_murmur_hash(id, (int)nk_strlen(id), NK_PANEL_MENU);
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ body.x = header.x;
+ body.w = size.x;
+ body.y = header.y + header.h;
+ body.h = size.y;
+
+ popup = win->popup.win;
+ is_open = popup ? nk_true : nk_false;
+ is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_MENU);
+ if ((is_clicked && is_open && !is_active) || (is_open && !is_active) ||
+ (!is_open && !is_active && !is_clicked)) return 0;
+ if (!nk_nonblock_begin(ctx, NK_WINDOW_NO_SCROLLBAR, body, header, NK_PANEL_MENU))
+ return 0;
+
+ win->popup.type = NK_PANEL_MENU;
+ win->popup.name = hash;
+ return 1;
+}
+
+NK_API int
+nk_menu_begin_text(struct nk_context *ctx, const char *title, int len,
+ nk_flags align, struct nk_vec2 size)
+{
+ struct nk_window *win;
+ const struct nk_input *in;
+ struct nk_rect header;
+ int is_clicked = nk_false;
+ nk_flags state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ state = nk_widget(&header, ctx);
+ if (!state) return 0;
+ in = (state == NK_WIDGET_ROM || win->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, header,
+ title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
+ is_clicked = nk_true;
+ return nk_menu_begin(ctx, win, title, is_clicked, header, size);
+}
+
+NK_API int nk_menu_begin_label(struct nk_context *ctx,
+ const char *text, nk_flags align, struct nk_vec2 size)
+{return nk_menu_begin_text(ctx, text, nk_strlen(text), align, size);}
+
+NK_API int
+nk_menu_begin_image(struct nk_context *ctx, const char *id, struct nk_image img,
+ struct nk_vec2 size)
+{
+ struct nk_window *win;
+ struct nk_rect header;
+ const struct nk_input *in;
+ int is_clicked = nk_false;
+ nk_flags state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ state = nk_widget(&header, ctx);
+ if (!state) return 0;
+ in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ if (nk_do_button_image(&ctx->last_widget_state, &win->buffer, header,
+ img, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in))
+ is_clicked = nk_true;
+ return nk_menu_begin(ctx, win, id, is_clicked, header, size);
+}
+
+NK_API int
+nk_menu_begin_symbol(struct nk_context *ctx, const char *id,
+ enum nk_symbol_type sym, struct nk_vec2 size)
+{
+ struct nk_window *win;
+ const struct nk_input *in;
+ struct nk_rect header;
+ int is_clicked = nk_false;
+ nk_flags state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ state = nk_widget(&header, ctx);
+ if (!state) return 0;
+ in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ if (nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, header,
+ sym, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font))
+ is_clicked = nk_true;
+ return nk_menu_begin(ctx, win, id, is_clicked, header, size);
+}
+
+NK_API int
+nk_menu_begin_image_text(struct nk_context *ctx, const char *title, int len,
+ nk_flags align, struct nk_image img, struct nk_vec2 size)
+{
+ struct nk_window *win;
+ struct nk_rect header;
+ const struct nk_input *in;
+ int is_clicked = nk_false;
+ nk_flags state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ state = nk_widget(&header, ctx);
+ if (!state) return 0;
+ in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer,
+ header, img, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
+ ctx->style.font, in))
+ is_clicked = nk_true;
+ return nk_menu_begin(ctx, win, title, is_clicked, header, size);
+}
+
+NK_API int nk_menu_begin_image_label(struct nk_context *ctx,
+ const char *title, nk_flags align, struct nk_image img, struct nk_vec2 size)
+{return nk_menu_begin_image_text(ctx, title, nk_strlen(title), align, img, size);}
+
+NK_API int
+nk_menu_begin_symbol_text(struct nk_context *ctx, const char *title, int len,
+ nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size)
+{
+ struct nk_window *win;
+ struct nk_rect header;
+ const struct nk_input *in;
+ int is_clicked = nk_false;
+ nk_flags state;
+
+ NK_ASSERT(ctx);
+ NK_ASSERT(ctx->current);
+ NK_ASSERT(ctx->current->layout);
+ if (!ctx || !ctx->current || !ctx->current->layout)
+ return 0;
+
+ win = ctx->current;
+ state = nk_widget(&header, ctx);
+ if (!state) return 0;
+
+ in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input;
+ if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer,
+ header, sym, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button,
+ ctx->style.font, in)) is_clicked = nk_true;
+ return nk_menu_begin(ctx, win, title, is_clicked, header, size);
+}
+
+NK_API int nk_menu_begin_symbol_label(struct nk_context *ctx,
+ const char *title, nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size )
+{return nk_menu_begin_symbol_text(ctx, title, nk_strlen(title), align,sym,size);}
+
+NK_API int nk_menu_item_text(struct nk_context *ctx, const char *title, int len, nk_flags align)
+{return nk_contextual_item_text(ctx, title, len, align);}
+
+NK_API int nk_menu_item_label(struct nk_context *ctx, const char *label, nk_flags align)
+{return nk_contextual_item_label(ctx, label, align);}
+
+NK_API int nk_menu_item_image_label(struct nk_context *ctx, struct nk_image img,
+ const char *label, nk_flags align)
+{return nk_contextual_item_image_label(ctx, img, label, align);}
+
+NK_API int nk_menu_item_image_text(struct nk_context *ctx, struct nk_image img,
+ const char *text, int len, nk_flags align)
+{return nk_contextual_item_image_text(ctx, img, text, len, align);}
+
+NK_API int nk_menu_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym,
+ const char *text, int len, nk_flags align)
+{return nk_contextual_item_symbol_text(ctx, sym, text, len, align);}
+
+NK_API int nk_menu_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym,
+ const char *label, nk_flags align)
+{return nk_contextual_item_symbol_label(ctx, sym, label, align);}
+
+NK_API void nk_menu_close(struct nk_context *ctx)
+{nk_contextual_close(ctx);}
+
+NK_API void
+nk_menu_end(struct nk_context *ctx)
+{nk_contextual_end(ctx);}
+
+#endif /* NK_IMPLEMENTATION */
+
+/*
+/// ## License
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~none
+/// ------------------------------------------------------------------------------
+/// This software is available under 2 licenses -- choose whichever you prefer.
+/// ------------------------------------------------------------------------------
+/// ALTERNATIVE A - MIT License
+/// Copyright (c) 2016-2018 Micha Mettke
+/// 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
+/// AUTHORS OR COPYRIGHT HOLDERS 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.
+/// ------------------------------------------------------------------------------
+/// ALTERNATIVE B - Public Domain (www.unlicense.org)
+/// This is free and unencumbered software released into the public domain.
+/// Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
+/// software, either in source code form or as a compiled binary, for any purpose,
+/// commercial or non-commercial, and by any means.
+/// In jurisdictions that recognize copyright laws, the author or authors of this
+/// software dedicate any and all copyright interest in the software to the public
+/// domain. We make this dedication for the benefit of the public at large and to
+/// the detriment of our heirs and successors. We intend this dedication to be an
+/// overt act of relinquishment in perpetuity of all present and future rights to
+/// this software under copyright law.
+/// 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
+/// AUTHORS 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.
+/// ------------------------------------------------------------------------------
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/// ## Changelog
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~none
+/// [date][x.yy.zz]-[description]
+/// -[date]: date on which the change has been pushed
+/// -[x.yy.zz]: Numerical version string representation. Each version number on the right
+/// resets back to zero if version on the left is incremented.
+/// - [x]: Major version with API and library breaking
+/// - [yy]: Minor version with non-breaking API and library changes
+/// - [zz]: Bug fix version with no direct changes to API
+///
+/// - 2018/02/23 (3.00.6) - Fixed slider dragging behavior
+/// - 2018/01/31 (3.00.5) - Fixed overcalculation of cursor data in font baking process
+/// - 2018/01/31 (3.00.4) - Removed name collision with stb_truetype
+/// - 2018/01/28 (3.00.3) - Fixed panel window border drawing bug
+/// - 2018/01/12 (3.00.2) - Added `nk_group_begin_titled` for separed group identifier and title
+/// - 2018/01/07 (3.00.1) - Started to change documentation style
+/// - 2018/01/05 (3.00.0) - BREAKING CHANGE: The previous color picker API was broken
+/// because of conversions between float and byte color representation.
+/// Color pickers now use floating point values to represent
+/// HSV values. To get back the old behavior I added some additional
+/// color conversion functions to cast between nk_color and
+/// nk_colorf.
+/// - 2017/12/23 (2.00.7) - Fixed small warning
+/// - 2017/12/23 (2.00.7) - Fixed nk_edit_buffer behavior if activated to allow input
+/// - 2017/12/23 (2.00.7) - Fixed modifyable progressbar dragging visuals and input behavior
+/// - 2017/12/04 (2.00.6) - Added formated string tooltip widget
+/// - 2017/11/18 (2.00.5) - Fixed window becoming hidden with flag NK_WINDOW_NO_INPUT
+/// - 2017/11/15 (2.00.4) - Fixed font merging
+/// - 2017/11/07 (2.00.3) - Fixed window size and position modifier functions
+/// - 2017/09/14 (2.00.2) - Fixed nk_edit_buffer and nk_edit_focus behavior
+/// - 2017/09/14 (2.00.1) - Fixed window closing behavior
+/// - 2017/09/14 (2.00.0) - BREAKING CHANGE: Modifing window position and size funtions now
+/// require the name of the window and must happen outside the window
+/// building process (between function call nk_begin and nk_end).
+/// - 2017/09/11 (1.40.9) - Fixed window background flag if background window is declared last
+/// - 2017/08/27 (1.40.8) - Fixed `nk_item_is_any_active` for hidden windows
+/// - 2017/08/27 (1.40.7) - Fixed window background flag
+/// - 2017/07/07 (1.40.6) - Fixed missing clipping rect check for hovering/clicked
+/// query for widgets
+/// - 2017/07/07 (1.40.5) - Fixed drawing bug for vertex output for lines and stroked
+/// and filled rectangles
+/// - 2017/07/07 (1.40.4) - Fixed bug in nk_convert trying to add windows that are in
+/// process of being destroyed.
+/// - 2017/07/07 (1.40.3) - Fixed table internal bug caused by storing table size in
+/// window instead of directly in table.
+/// - 2017/06/30 (1.40.2) - Removed unneeded semicolon in C++ NK_ALIGNOF macro
+/// - 2017/06/30 (1.40.1) - Fixed drawing lines smaller or equal zero
+/// - 2017/06/08 (1.40.0) - Removed the breaking part of last commit. Auto layout now only
+/// comes in effect if you pass in zero was row height argument
+/// - 2017/06/08 (1.40.0) - BREAKING CHANGE: while not directly API breaking it will change
+/// how layouting works. From now there will be an internal minimum
+/// row height derived from font height. If you need a row smaller than
+/// that you can directly set it by `nk_layout_set_min_row_height` and
+/// reset the value back by calling `nk_layout_reset_min_row_height.
+/// - 2017/06/08 (1.39.1) - Fixed property text edit handling bug caused by past `nk_widget` fix
+/// - 2017/06/08 (1.39.0) - Added function to retrieve window space without calling a nk_layout_xxx function
+/// - 2017/06/06 (1.38.5) - Fixed `nk_convert` return flag for command buffer
+/// - 2017/05/23 (1.38.4) - Fixed activation behavior for widgets partially clipped
+/// - 2017/05/10 (1.38.3) - Fixed wrong min window size mouse scaling over boundries
+/// - 2017/05/09 (1.38.2) - Fixed vertical scrollbar drawing with not enough space
+/// - 2017/05/09 (1.38.1) - Fixed scaler dragging behavior if window size hits minimum size
+/// - 2017/05/06 (1.38.0) - Added platform double-click support
+/// - 2017/04/20 (1.37.1) - Fixed key repeat found inside glfw demo backends
+/// - 2017/04/20 (1.37.0) - Extended properties with selection and clipbard support
+/// - 2017/04/20 (1.36.2) - Fixed #405 overlapping rows with zero padding and spacing
+/// - 2017/04/09 (1.36.1) - Fixed #403 with another widget float error
+/// - 2017/04/09 (1.36.0) - Added window `NK_WINDOW_NO_INPUT` and `NK_WINDOW_NOT_INTERACTIVE` flags
+/// - 2017/04/09 (1.35.3) - Fixed buffer heap corruption
+/// - 2017/03/25 (1.35.2) - Fixed popup overlapping for `NK_WINDOW_BACKGROUND` windows
+/// - 2017/03/25 (1.35.1) - Fixed windows closing behavior
+/// - 2017/03/18 (1.35.0) - Added horizontal scroll requested in #377
+/// - 2017/03/18 (1.34.3) - Fixed long window header titles
+/// - 2017/03/04 (1.34.2) - Fixed text edit filtering
+/// - 2017/03/04 (1.34.1) - Fixed group closable flag
+/// - 2017/02/25 (1.34.0) - Added custom draw command for better language binding support
+/// - 2017/01/24 (1.33.0) - Added programatic way of remove edit focus
+/// - 2017/01/24 (1.32.3) - Fixed wrong define for basic type definitions for windows
+/// - 2017/01/21 (1.32.2) - Fixed input capture from hidden or closed windows
+/// - 2017/01/21 (1.32.1) - Fixed slider behavior and drawing
+/// - 2017/01/13 (1.32.0) - Added flag to put scaler into the bottom left corner
+/// - 2017/01/13 (1.31.0) - Added additional row layouting method to combine both
+/// dynamic and static widgets.
+/// - 2016/12/31 (1.30.0) - Extended scrollbar offset from 16-bit to 32-bit
+/// - 2016/12/31 (1.29.2)- Fixed closing window bug of minimized windows
+/// - 2016/12/03 (1.29.1)- Fixed wrapped text with no seperator and C89 error
+/// - 2016/12/03 (1.29.0) - Changed text wrapping to process words not characters
+/// - 2016/11/22 (1.28.6)- Fixed window minimized closing bug
+/// - 2016/11/19 (1.28.5)- Fixed abstract combo box closing behavior
+/// - 2016/11/19 (1.28.4)- Fixed tooltip flickering
+/// - 2016/11/19 (1.28.3)- Fixed memory leak caused by popup repeated closing
+/// - 2016/11/18 (1.28.2)- Fixed memory leak caused by popup panel allocation
+/// - 2016/11/10 (1.28.1)- Fixed some warnings and C++ error
+/// - 2016/11/10 (1.28.0)- Added additional `nk_button` versions which allows to directly
+/// pass in a style struct to change buttons visual.
+/// - 2016/11/10 (1.27.0)- Added additional 'nk_tree' versions to support external state
+/// storage. Just like last the `nk_group` commit the main
+/// advantage is that you optionally can minimize nuklears runtime
+/// memory consumption or handle hash collisions.
+/// - 2016/11/09 (1.26.0)- Added additional `nk_group` version to support external scrollbar
+/// offset storage. Main advantage is that you can externalize
+/// the memory management for the offset. It could also be helpful
+/// if you have a hash collision in `nk_group_begin` but really
+/// want the name. In addition I added `nk_list_view` which allows
+/// to draw big lists inside a group without actually having to
+/// commit the whole list to nuklear (issue #269).
+/// - 2016/10/30 (1.25.1)- Fixed clipping rectangle bug inside `nk_draw_list`
+/// - 2016/10/29 (1.25.0)- Pulled `nk_panel` memory management into nuklear and out of
+/// the hands of the user. From now on users don't have to care
+/// about panels unless they care about some information. If you
+/// still need the panel just call `nk_window_get_panel`.
+/// - 2016/10/21 (1.24.0)- Changed widget border drawing to stroked rectangle from filled
+/// rectangle for less overdraw and widget background transparency.
+/// - 2016/10/18 (1.23.0)- Added `nk_edit_focus` for manually edit widget focus control
+/// - 2016/09/29 (1.22.7)- Fixed deduction of basic type in non `<stdint.h>` compilation
+/// - 2016/09/29 (1.22.6)- Fixed edit widget UTF-8 text cursor drawing bug
+/// - 2016/09/28 (1.22.5)- Fixed edit widget UTF-8 text appending/inserting/removing
+/// - 2016/09/28 (1.22.4)- Fixed drawing bug inside edit widgets which offset all text
+/// text in every edit widget if one of them is scrolled.
+/// - 2016/09/28 (1.22.3)- Fixed small bug in edit widgets if not active. The wrong
+/// text length is passed. It should have been in bytes but
+/// was passed as glyphes.
+/// - 2016/09/20 (1.22.2)- Fixed color button size calculation
+/// - 2016/09/20 (1.22.1)- Fixed some `nk_vsnprintf` behavior bugs and removed
+/// `<stdio.h>` again from `NK_INCLUDE_STANDARD_VARARGS`.
+/// - 2016/09/18 (1.22.0)- C89 does not support vsnprintf only C99 and newer as well
+/// as C++11 and newer. In addition to use vsnprintf you have
+/// to include <stdio.h>. So just defining `NK_INCLUDE_STD_VAR_ARGS`
+/// is not enough. That behavior is now fixed. By default if
+/// both varargs as well as stdio is selected I try to use
+/// vsnprintf if not possible I will revert to vsprintf. If
+/// varargs but not stdio was defined I will use my own function.
+/// - 2016/09/15 (1.21.2)- Fixed panel `close` behavior for deeper panel levels
+/// - 2016/09/15 (1.21.1)- Fixed C++ errors and wrong argument to `nk_panel_get_xxxx`
+/// - 2016/09/13 (1.21.0) - !BREAKING! Fixed nonblocking popup behavior in menu, combo,
+/// and contextual which prevented closing in y-direction if
+/// popup did not reach max height.
+/// In addition the height parameter was changed into vec2
+/// for width and height to have more control over the popup size.
+/// - 2016/09/13 (1.20.3) - Cleaned up and extended type selection
+/// - 2016/09/13 (1.20.2)- Fixed slider behavior hopefully for the last time. This time
+/// all calculation are correct so no more hackery.
+/// - 2016/09/13 (1.20.1)- Internal change to divide window/panel flags into panel flags and types.
+/// Suprisinly spend years in C and still happened to confuse types
+/// with flags. Probably something to take note.
+/// - 2016/09/08 (1.20.0)- Added additional helper function to make it easier to just
+/// take the produced buffers from `nk_convert` and unplug the
+/// iteration process from `nk_context`. So now you can
+/// just use the vertex,element and command buffer + two pointer
+/// inside the command buffer retrieved by calls `nk__draw_begin`
+/// and `nk__draw_end` and macro `nk_draw_foreach_bounded`.
+/// - 2016/09/08 (1.19.0)- Added additional asserts to make sure every `nk_xxx_begin` call
+/// for windows, popups, combobox, menu and contextual is guarded by
+/// `if` condition and does not produce false drawing output.
+/// - 2016/09/08 (1.18.0)- Changed confusing name for `NK_SYMBOL_RECT_FILLED`, `NK_SYMBOL_RECT`
+/// to hopefully easier to understand `NK_SYMBOL_RECT_FILLED` and
+/// `NK_SYMBOL_RECT_OUTLINE`.
+/// - 2016/09/08 (1.17.0)- Changed confusing name for `NK_SYMBOL_CIRLCE_FILLED`, `NK_SYMBOL_CIRCLE`
+/// to hopefully easier to understand `NK_SYMBOL_CIRCLE_FILLED` and
+/// `NK_SYMBOL_CIRCLE_OUTLINE`.
+/// - 2016/09/08 (1.16.0)- Added additional checks to select correct types if `NK_INCLUDE_FIXED_TYPES`
+/// is not defined by supporting the biggest compiler GCC, clang and MSVC.
+/// - 2016/09/07 (1.15.3)- Fixed `NK_INCLUDE_COMMAND_USERDATA` define to not cause an error
+/// - 2016/09/04 (1.15.2)- Fixed wrong combobox height calculation
+/// - 2016/09/03 (1.15.1)- Fixed gaps inside combo boxes in OpenGL
+/// - 2016/09/02 (1.15.0) - Changed nuklear to not have any default vertex layout and
+/// instead made it user provided. The range of types to convert
+/// to is quite limited at the moment, but I would be more than
+/// happy to accept PRs to add additional.
+/// - 2016/08/30 (1.14.2) - Removed unused variables
+/// - 2016/08/30 (1.14.1) - Fixed C++ build errors
+/// - 2016/08/30 (1.14.0) - Removed mouse dragging from SDL demo since it does not work correctly
+/// - 2016/08/30 (1.13.4) - Tweaked some default styling variables
+/// - 2016/08/30 (1.13.3) - Hopefully fixed drawing bug in slider, in general I would
+/// refrain from using slider with a big number of steps.
+/// - 2016/08/30 (1.13.2) - Fixed close and minimize button which would fire even if the
+/// window was in Read Only Mode.
+/// - 2016/08/30 (1.13.1) - Fixed popup panel padding handling which was previously just
+/// a hack for combo box and menu.
+/// - 2016/08/30 (1.13.0) - Removed `NK_WINDOW_DYNAMIC` flag from public API since
+/// it is bugged and causes issues in window selection.
+/// - 2016/08/30 (1.12.0) - Removed scaler size. The size of the scaler is now
+/// determined by the scrollbar size
+/// - 2016/08/30 (1.11.2) - Fixed some drawing bugs caused by changes from 1.11
+/// - 2016/08/30 (1.11.1) - Fixed overlapping minimized window selection
+/// - 2016/08/30 (1.11.0) - Removed some internal complexity and overly complex code
+/// handling panel padding and panel border.
+/// - 2016/08/29 (1.10.0) - Added additional height parameter to `nk_combobox_xxx`
+/// - 2016/08/29 (1.10.0) - Fixed drawing bug in dynamic popups
+/// - 2016/08/29 (1.10.0) - Added experimental mouse scrolling to popups, menus and comboboxes
+/// - 2016/08/26 (1.10.0) - Added window name string prepresentation to account for
+/// hash collisions. Currently limited to NK_WINDOW_MAX_NAME
+/// which in term can be redefined if not big enough.
+/// - 2016/08/26 (1.10.0) - Added stacks for temporary style/UI changes in code
+/// - 2016/08/25 (1.10.0) - Changed `nk_input_is_key_pressed` and 'nk_input_is_key_released'
+/// to account for key press and release happening in one frame.
+/// - 2016/08/25 (1.10.0) - Added additional nk_edit flag to directly jump to the end on activate
+/// - 2016/08/17 (1.09.6)- Removed invalid check for value zero in nk_propertyx
+/// - 2016/08/16 (1.09.5)- Fixed ROM mode for deeper levels of popup windows parents.
+/// - 2016/08/15 (1.09.4)- Editbox are now still active if enter was pressed with flag
+/// `NK_EDIT_SIG_ENTER`. Main reasoning is to be able to keep
+/// typing after commiting.
+/// - 2016/08/15 (1.09.4)- Removed redundant code
+/// - 2016/08/15 (1.09.4)- Fixed negative numbers in `nk_strtoi` and remove unused variable
+/// - 2016/08/15 (1.09.3)- Fixed `NK_WINDOW_BACKGROUND` flag behavior to select a background
+/// window only as selected by hovering and not by clicking.
+/// - 2016/08/14 (1.09.2)- Fixed a bug in font atlas which caused wrong loading
+/// of glyphes for font with multiple ranges.
+/// - 2016/08/12 (1.09.1)- Added additional function to check if window is currently
+/// hidden and therefore not visible.
+/// - 2016/08/12 (1.09.1)- nk_window_is_closed now queries the correct flag `NK_WINDOW_CLOSED`
+/// instead of the old flag `NK_WINDOW_HIDDEN`
+/// - 2016/08/09 (1.09.0) - Added additional double version to nk_property and changed
+/// the underlying implementation to not cast to float and instead
+/// work directly on the given values.
+/// - 2016/08/09 (1.08.0) - Added additional define to overwrite library internal
+/// floating pointer number to string conversion for additional
+/// precision.
+/// - 2016/08/09 (1.08.0) - Added additional define to overwrite library internal
+/// string to floating point number conversion for additional
+/// precision.
+/// - 2016/08/08 (1.07.2)- Fixed compiling error without define NK_INCLUDE_FIXED_TYPE
+/// - 2016/08/08 (1.07.1)- Fixed possible floating point error inside `nk_widget` leading
+/// to wrong wiget width calculation which results in widgets falsly
+/// becomming tagged as not inside window and cannot be accessed.
+/// - 2016/08/08 (1.07.0) - Nuklear now differentiates between hiding a window (NK_WINDOW_HIDDEN) and
+/// closing a window (NK_WINDOW_CLOSED). A window can be hidden/shown
+/// by using `nk_window_show` and closed by either clicking the close
+/// icon in a window or by calling `nk_window_close`. Only closed
+/// windows get removed at the end of the frame while hidden windows
+/// remain.
+/// - 2016/08/08 (1.06.0) - Added `nk_edit_string_zero_terminated` as a second option to
+/// `nk_edit_string` which takes, edits and outputs a '\0' terminated string.
+/// - 2016/08/08 (1.05.4)- Fixed scrollbar auto hiding behavior
+/// - 2016/08/08 (1.05.3)- Fixed wrong panel padding selection in `nk_layout_widget_space`
+/// - 2016/08/07 (1.05.2)- Fixed old bug in dynamic immediate mode layout API, calculating
+/// wrong item spacing and panel width.
+///- 2016/08/07 (1.05.1)- Hopefully finally fixed combobox popup drawing bug
+///- 2016/08/07 (1.05.0) - Split varargs away from NK_INCLUDE_STANDARD_IO into own
+/// define NK_INCLUDE_STANDARD_VARARGS to allow more fine
+/// grained controlled over library includes.
+/// - 2016/08/06 (1.04.5)- Changed memset calls to NK_MEMSET
+/// - 2016/08/04 (1.04.4)- Fixed fast window scaling behavior
+/// - 2016/08/04 (1.04.3)- Fixed window scaling, movement bug which appears if you
+/// move/scale a window and another window is behind it.
+/// If you are fast enough then the window behind gets activated
+/// and the operation is blocked. I now require activating
+/// by hovering only if mouse is not pressed.
+/// - 2016/08/04 (1.04.2)- Fixed changing fonts
+/// - 2016/08/03 (1.04.1)- Fixed `NK_WINDOW_BACKGROUND` behavior
+/// - 2016/08/03 (1.04.0) - Added color parameter to `nk_draw_image`
+/// - 2016/08/03 (1.04.0) - Added additional window padding style attributes for
+/// sub windows (combo, menu, ...)
+/// - 2016/08/03 (1.04.0) - Added functions to show/hide software cursor
+/// - 2016/08/03 (1.04.0) - Added `NK_WINDOW_BACKGROUND` flag to force a window
+/// to be always in the background of the screen
+/// - 2016/08/03 (1.03.2)- Removed invalid assert macro for NK_RGB color picker
+/// - 2016/08/01 (1.03.1)- Added helper macros into header include guard
+/// - 2016/07/29 (1.03.0) - Moved the window/table pool into the header part to
+/// simplify memory management by removing the need to
+/// allocate the pool.
+/// - 2016/07/29 (1.02.0) - Added auto scrollbar hiding window flag which if enabled
+/// will hide the window scrollbar after NK_SCROLLBAR_HIDING_TIMEOUT
+/// seconds without window interaction. To make it work
+/// you have to also set a delta time inside the `nk_context`.
+/// - 2016/07/25 (1.01.1) - Fixed small panel and panel border drawing bugs
+/// - 2016/07/15 (1.01.0) - Added software cursor to `nk_style` and `nk_context`
+/// - 2016/07/15 (1.01.0) - Added const correctness to `nk_buffer_push' data argument
+/// - 2016/07/15 (1.01.0) - Removed internal font baking API and simplified
+/// font atlas memory management by converting pointer
+/// arrays for fonts and font configurations to lists.
+/// - 2016/07/15 (1.00.0) - Changed button API to use context dependend button
+/// behavior instead of passing it for every function call.
+/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///
+/// ## Gallery
+/// ![Figure [blue]: Feature overview with blue color styling](https://cloud.githubusercontent.com/assets/8057201/13538240/acd96876-e249-11e5-9547-5ac0b19667a0.png)
+/// ![Figure [red]: Feature overview with red color styling](https://cloud.githubusercontent.com/assets/8057201/13538243/b04acd4c-e249-11e5-8fd2-ad7744a5b446.png)
+/// ![Figure [widgets]: Widget overview](https://cloud.githubusercontent.com/assets/8057201/11282359/3325e3c6-8eff-11e5-86cb-cf02b0596087.png)
+/// ![Figure [blackwhite]: Black and white](https://cloud.githubusercontent.com/assets/8057201/11033668/59ab5d04-86e5-11e5-8091-c56f16411565.png)
+/// ![Figure [filexp]: File explorer](https://cloud.githubusercontent.com/assets/8057201/10718115/02a9ba08-7b6b-11e5-950f-adacdd637739.png)
+/// ![Figure [opengl]: OpenGL Editor](https://cloud.githubusercontent.com/assets/8057201/12779619/2a20d72c-ca69-11e5-95fe-4edecf820d5c.png)
+/// ![Figure [nodedit]: Node Editor](https://cloud.githubusercontent.com/assets/8057201/9976995/e81ac04a-5ef7-11e5-872b-acd54fbeee03.gif)
+/// ![Figure [skinning]: Using skinning in Nuklear](https://cloud.githubusercontent.com/assets/8057201/15991632/76494854-30b8-11e6-9555-a69840d0d50b.png)
+/// ![Figure [bf]: Heavy modified version](https://cloud.githubusercontent.com/assets/8057201/14902576/339926a8-0d9c-11e6-9fee-a8b73af04473.png)
+///
+/// ## Credits
+/// Developed by Micha Mettke and every direct or indirect github contributor. <br /><br />
+///
+/// Embeds [stb_texedit](https://github.com/nothings/stb/blob/master/stb_textedit.h), [stb_truetype](https://github.com/nothings/stb/blob/master/stb_truetype.h) and [stb_rectpack](https://github.com/nothings/stb/blob/master/stb_rect_pack.h) by Sean Barret (public domain) <br />
+/// Uses [stddoc.c](https://github.com/r-lyeh/stddoc.c) from r-lyeh@github.com for documentation generation <br /><br />
+/// Embeds ProggyClean.ttf font by Tristan Grimmer (MIT license). <br />
+///
+/// Big thank you to Omar Cornut (ocornut@github) for his [imgui library](https://github.com/ocornut/imgui) and
+/// giving me the inspiration for this library, Casey Muratori for handmade hero
+/// and his original immediate mode graphical user interface idea and Sean
+/// Barret for his amazing single header libraries which restored my faith
+/// in libraries and brought me to create some of my own.
+///
+*/
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/nuklear_btgui_gl2.h b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/nuklear_btgui_gl2.h
new file mode 100644
index 0000000000..a89dae4db7
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/nuklear_btgui_gl2.h
@@ -0,0 +1,386 @@
+/*
+ * Nuklear - v1.00 - public domain
+ * no warrenty implied; use at your own risk.
+ * authored from 2015-2016 by Micha Mettke
+ */
+/*
+ * ==============================================================
+ *
+ * API
+ *
+ * ===============================================================
+ */
+#ifndef NK_BTGUI_GL2_H_
+#define NK_BTGUI_GL2_H_
+
+enum nk_btgui_init_state{
+ NK_BTGUI3_DEFAULT = 0,
+ NK_BTGUI3_INSTALL_CALLBACKS
+};
+
+struct nk_btgui_vertex {
+ float position[2];
+ float uv[2];
+ nk_byte col[4];
+};
+
+NK_API struct nk_context* nk_btgui_init(b3gDefaultOpenGLWindow *win, enum nk_btgui_init_state);
+NK_API void nk_btgui_font_stash_begin(struct nk_font_atlas **atlas);
+NK_API void nk_btgui_font_stash_end(void);
+
+NK_API void nk_btgui_update_mouse_pos(int x, int y);
+NK_API void nk_btgui_update_mouse_state(int left_button_state, int middle_button_state, int right_button_state);
+
+NK_API void nk_btgui_new_frame(void);
+NK_API void nk_btgui_render(enum nk_anti_aliasing , int max_vertex_buffer, int max_element_buffer);
+NK_API void nk_btgui_shutdown(void);
+
+NK_API void nk_btgui_char_callback(b3gDefaultOpenGLWindow *win, unsigned int codepoint);
+NK_API void nk_btgui_scroll_callback(b3gDefaultOpenGLWindow *win, double xoff, double yoff);
+
+#endif
+
+/*
+ * ==============================================================
+ *
+ * IMPLEMENTATION
+ *
+ * ===============================================================
+ */
+#ifdef NK_BTGUI_GL2_IMPLEMENTATION
+
+#ifndef NK_BTGUI_TEXT_MAX
+#define NK_BTGUI_TEXT_MAX 256
+#endif
+
+struct nk_btgui_device {
+ struct nk_buffer cmds;
+ struct nk_draw_null_texture null;
+ GLuint font_tex;
+};
+
+static struct nk_btgui {
+ b3gDefaultOpenGLWindow *win;
+ int width, height;
+ int display_width, display_height;
+ struct nk_btgui_device ogl;
+ struct nk_context ctx;
+ struct nk_font_atlas atlas;
+ struct nk_vec2 fb_scale;
+ unsigned int text[NK_BTGUI_TEXT_MAX];
+ int text_len;
+ float scroll;
+
+ int left_button_state;
+ int middle_button_state;
+ int right_button_state;
+
+ int mouse_pos[2];
+} btgui;
+
+NK_INTERN void
+nk_btgui_device_upload_atlas(const void *image, int width, int height)
+{
+ struct nk_btgui_device *dev = &btgui.ogl;
+ glGenTextures(1, &dev->font_tex);
+ glBindTexture(GL_TEXTURE_2D, dev->font_tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, image);
+ assert(glGetError() == GL_NO_ERROR);
+}
+
+NK_API void
+nk_btgui_update_mouse_state(int left_button_state, int middle_button_state, int right_button_state)
+{
+ btgui.left_button_state = left_button_state;
+ btgui.middle_button_state = middle_button_state;
+ btgui.right_button_state = right_button_state;
+}
+
+NK_API void
+nk_btgui_update_mouse_pos(int x, int y)
+{
+ btgui.mouse_pos[0] = x;
+ btgui.mouse_pos[1] = y;
+}
+
+
+NK_API void
+nk_btgui_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer)
+{
+ /* setup global state */
+ struct nk_btgui_device *dev = &btgui.ogl;
+ glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT|GL_TRANSFORM_BIT);
+ assert(glGetError() == GL_NO_ERROR);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_SCISSOR_TEST);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ /* setup viewport/project */
+ glViewport(0,0,(GLsizei)btgui.display_width,(GLsizei)btgui.display_height);
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0.0f, btgui.width, btgui.height, 0.0f, -1.0f, 1.0f);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+ {
+ GLsizei vs = sizeof(struct nk_btgui_vertex);
+ size_t vp = offsetof(struct nk_btgui_vertex, position);
+ size_t vt = offsetof(struct nk_btgui_vertex, uv);
+ size_t vc = offsetof(struct nk_btgui_vertex, col);
+
+ /* convert from command queue into draw list and draw to screen */
+ const struct nk_draw_command *cmd;
+ const nk_draw_index *offset = NULL;
+ struct nk_buffer vbuf, ebuf;
+
+ /* fill converting configuration */
+ struct nk_convert_config config;
+ static const struct nk_draw_vertex_layout_element vertex_layout[] = {
+ {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_btgui_vertex, position)},
+ {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_btgui_vertex, uv)},
+ {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_btgui_vertex, col)},
+ {NK_VERTEX_LAYOUT_END}
+ };
+ NK_MEMSET(&config, 0, sizeof(config));
+ config.vertex_layout = vertex_layout;
+ config.vertex_size = sizeof(struct nk_btgui_vertex);
+ config.vertex_alignment = NK_ALIGNOF(struct nk_btgui_vertex);
+ config.null = dev->null;
+ config.circle_segment_count = 22;
+ config.curve_segment_count = 22;
+ config.arc_segment_count = 22;
+ config.global_alpha = 1.0f;
+ config.shape_AA = AA;
+ config.line_AA = AA;
+
+
+ /* convert shapes into vertexes */
+ nk_buffer_init_default(&vbuf);
+ nk_buffer_init_default(&ebuf);
+ nk_convert(&btgui.ctx, &dev->cmds, &vbuf, &ebuf, &config);
+
+ /* setup vertex buffer pointer */
+ {const void *vertices = nk_buffer_memory_const(&vbuf);
+ glVertexPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vp));
+ glTexCoordPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vt));
+ glColorPointer(4, GL_UNSIGNED_BYTE, vs, (const void*)((const nk_byte*)vertices + vc));}
+
+ /* iterate over and execute each draw command */
+ offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf);
+ nk_draw_foreach(cmd, &btgui.ctx, &dev->cmds)
+ {
+ if (!cmd->elem_count) continue;
+ glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
+ glScissor(
+ (GLint)(cmd->clip_rect.x * btgui.fb_scale.x),
+ (GLint)((btgui.height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * btgui.fb_scale.y),
+ (GLint)(cmd->clip_rect.w * btgui.fb_scale.x),
+ (GLint)(cmd->clip_rect.h * btgui.fb_scale.y));
+ glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
+ offset += cmd->elem_count;
+ }
+ nk_clear(&btgui.ctx);
+ nk_buffer_free(&vbuf);
+ nk_buffer_free(&ebuf);
+ }
+ assert(glGetError() == GL_NO_ERROR);
+
+ /* default OpenGL state */
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ assert(glGetError() == GL_NO_ERROR);
+
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glPopAttrib();
+ assert(glGetError() == GL_NO_ERROR);
+}
+
+#if 0 // @todo
+NK_API void
+nk_btgui_char_callback(b3gDefaultOpenGLWindow *win, unsigned int codepoint)
+{
+ (void)win;
+ if (btgui.text_len < NK_BTGUI_TEXT_MAX)
+ btgui.text[btgui.text_len++] = codepoint;
+}
+
+NK_API void
+nk_gflw3_scroll_callback(b3gDefaultOpenGLWindow *win, double xoff, double yoff)
+{
+ (void)win; (void)xoff;
+ btgui.scroll += (float)yoff;
+}
+
+static void
+nk_btgui_clipbard_paste(nk_handle usr, struct nk_text_edit *edit)
+{
+ const char *text = btguiGetClipboardString(btgui.win);
+ if (text) nk_textedit_paste(edit, text, nk_strlen(text));
+ (void)usr;
+}
+
+static void
+nk_btgui_clipbard_copy(nk_handle usr, const char *text, int len)
+{
+ char *str = 0;
+ (void)usr;
+ if (!len) return;
+ str = (char*)malloc((size_t)len+1);
+ if (!str) return;
+ memcpy(str, text, (size_t)len);
+ str[len] = '\0';
+ btguiSetClipboardString(btgui.win, str);
+ free(str);
+}
+#endif
+
+NK_API struct nk_context*
+nk_btgui_init(b3gDefaultOpenGLWindow *win, enum nk_btgui_init_state init_state)
+{
+ btgui.win = win;
+ if (init_state == NK_BTGUI3_INSTALL_CALLBACKS) {
+ //btguiSetScrollCallback(win, nk_gflw3_scroll_callback);
+ //btguiSetCharCallback(win, nk_btgui_char_callback);
+ }
+
+ nk_init_default(&btgui.ctx, 0);
+ //btgui.ctx.clip.copy = nk_btgui_clipbard_copy;
+ //btgui.ctx.clip.paste = nk_btgui_clipbard_paste;
+ //btgui.ctx.clip.userdata = nk_handle_ptr(0);
+ nk_buffer_init_default(&btgui.ogl.cmds);
+ return &btgui.ctx;
+}
+
+NK_API void
+nk_btgui_font_stash_begin(struct nk_font_atlas **atlas)
+{
+ nk_font_atlas_init_default(&btgui.atlas);
+ nk_font_atlas_begin(&btgui.atlas);
+ *atlas = &btgui.atlas;
+}
+
+NK_API void
+nk_btgui_font_stash_end(void)
+{
+ const void *image; int w, h;
+ image = nk_font_atlas_bake(&btgui.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
+ nk_btgui_device_upload_atlas(image, w, h);
+ nk_font_atlas_end(&btgui.atlas, nk_handle_id((int)btgui.ogl.font_tex), &btgui.ogl.null);
+ if (btgui.atlas.default_font)
+ nk_style_set_font(&btgui.ctx, &btgui.atlas.default_font->handle);
+}
+
+NK_API void
+nk_btgui_new_frame(void)
+{
+ int i;
+ //double x, y;
+ struct nk_context *ctx = &btgui.ctx;
+ b3gDefaultOpenGLWindow *win = btgui.win;
+
+ btgui.width = win->getWidth();
+ btgui.height = win->getHeight();
+
+ float fbscale = 1.0;
+#ifdef __APPLE__
+ //fbscale = win->getRetinaScale();
+#endif
+ btgui.display_width = fbscale * btgui.width;
+ btgui.display_height = fbscale * btgui.height;
+
+ btgui.fb_scale.x = (float)btgui.display_width/(float)btgui.width;
+ btgui.fb_scale.y = (float)btgui.display_height/(float)btgui.height;
+
+ // HACK
+ btgui.fb_scale.x = 1.0;
+ btgui.fb_scale.y = 1.0;
+
+
+ nk_input_begin(ctx);
+#if 0
+ for (i = 0; i < btgui.text_len; ++i)
+ nk_input_unicode(ctx, btgui.text[i]);
+
+ nk_input_key(ctx, NK_KEY_DEL, btguiGetKey(win, BTGUI_KEY_DELETE) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_ENTER, btguiGetKey(win, BTGUI_KEY_ENTER) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_TAB, btguiGetKey(win, BTGUI_KEY_TAB) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_BACKSPACE, btguiGetKey(win, BTGUI_KEY_BACKSPACE) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_UP, btguiGetKey(win, BTGUI_KEY_UP) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_DOWN, btguiGetKey(win, BTGUI_KEY_DOWN) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_TEXT_START, btguiGetKey(win, BTGUI_KEY_HOME) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_TEXT_END, btguiGetKey(win, BTGUI_KEY_END) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_SHIFT, btguiGetKey(win, BTGUI_KEY_LEFT_SHIFT) == BTGUI_PRESS||
+ btguiGetKey(win, BTGUI_KEY_RIGHT_SHIFT) == BTGUI_PRESS);
+
+ if (btguiGetKey(win, BTGUI_KEY_LEFT_CONTROL) == BTGUI_PRESS ||
+ btguiGetKey(win, BTGUI_KEY_RIGHT_CONTROL)) {
+ nk_input_key(ctx, NK_KEY_COPY, btguiGetKey(win, BTGUI_KEY_C) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_PASTE, btguiGetKey(win, BTGUI_KEY_P) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_CUT, btguiGetKey(win, BTGUI_KEY_X) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_TEXT_UNDO, btguiGetKey(win, BTGUI_KEY_Z) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_TEXT_REDO, btguiGetKey(win, BTGUI_KEY_R) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, btguiGetKey(win, BTGUI_KEY_LEFT) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, btguiGetKey(win, BTGUI_KEY_RIGHT) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_TEXT_LINE_START, btguiGetKey(win, BTGUI_KEY_B) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_TEXT_LINE_END, btguiGetKey(win, BTGUI_KEY_E) == BTGUI_PRESS);
+ } else {
+ nk_input_key(ctx, NK_KEY_LEFT, btguiGetKey(win, BTGUI_KEY_LEFT) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_RIGHT, btguiGetKey(win, BTGUI_KEY_RIGHT) == BTGUI_PRESS);
+ nk_input_key(ctx, NK_KEY_COPY, 0);
+ nk_input_key(ctx, NK_KEY_PASTE, 0);
+ nk_input_key(ctx, NK_KEY_CUT, 0);
+ nk_input_key(ctx, NK_KEY_SHIFT, 0);
+ }
+
+ btguiGetCursorPos(win, &x, &y);
+ nk_input_motion(ctx, (int)x, (int)y);
+ nk_input_button(ctx, NK_BUTTON_LEFT, (int)x, (int)y, btguiGetMouseButton(win, BTGUI_MOUSE_BUTTON_LEFT) == BTGUI_PRESS);
+ nk_input_button(ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, btguiGetMouseButton(win, BTGUI_MOUSE_BUTTON_MIDDLE) == BTGUI_PRESS);
+ nk_input_button(ctx, NK_BUTTON_RIGHT, (int)x, (int)y, btguiGetMouseButton(win, BTGUI_MOUSE_BUTTON_RIGHT) == BTGUI_PRESS);
+ nk_input_scroll(ctx, btgui.scroll);
+#endif
+ nk_input_motion(ctx, btgui.mouse_pos[0], btgui.mouse_pos[1]);
+ nk_input_button(ctx, NK_BUTTON_LEFT, btgui.mouse_pos[0], btgui.mouse_pos[1], btgui.left_button_state);
+ nk_input_button(ctx, NK_BUTTON_MIDDLE, btgui.mouse_pos[0], btgui.mouse_pos[1], btgui.middle_button_state);
+ nk_input_button(ctx, NK_BUTTON_RIGHT, btgui.mouse_pos[0], btgui.mouse_pos[1], btgui.right_button_state);
+ nk_input_end(&btgui.ctx);
+ btgui.text_len = 0;
+ btgui.scroll = 0;
+}
+
+NK_API
+void nk_btgui_shutdown(void)
+{
+ struct nk_btgui_device *dev = &btgui.ogl;
+ nk_font_atlas_clear(&btgui.atlas);
+ nk_free(&btgui.ctx);
+ glDeleteTextures(1, &dev->font_tex);
+ nk_buffer_free(&dev->cmds);
+ memset(&btgui, 0, sizeof(btgui));
+}
+
+#endif
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/premake4.lua b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/premake4.lua
new file mode 100644
index 0000000000..caccd7cde7
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/premake4.lua
@@ -0,0 +1,87 @@
+newoption {
+ trigger = "with-gtk3nfd",
+ description = "Build with nativefiledialog support. GTK3 required(Linux only)"
+}
+
+sources = {
+ "main.cc",
+ "exr-io.cc",
+ "../../deps/miniz/miniz.c"
+}
+
+-- premake4.lua
+solution "EXRViewSolution"
+ configurations { "Release", "Debug" }
+
+ platforms { "native", "x64", "x32" }
+
+
+ projectRootDir = os.getcwd() .. "/"
+ dofile ("findOpenGLGlewGlut.lua")
+ initOpenGL()
+ initGlew()
+
+ -- A project defines one build target
+ project "exrview"
+ kind "ConsoleApp"
+ language "C++"
+ files { sources }
+
+ includedirs { "./", "../../", "../../deps/miniz" }
+
+ if os.is("Windows") then
+ defines { "USE_NATIVEFILEDIALOG" }
+ files{
+ "OpenGLWindow/Win32OpenGLWindow.cpp",
+ "OpenGLWindow/Win32OpenGLWindow.h",
+ "OpenGLWindow/Win32Window.cpp",
+ "OpenGLWindow/Win32Window.h",
+ }
+ includedirs { "./ThirdPartyLibs/nativefiledialog/src/include/" }
+ files {
+ "ThirdPartyLibs/nativefiledialog/src/nfd_common.c",
+ "ThirdPartyLibs/nativefiledialog/src/nfd_win.cpp"
+ }
+ end
+ if os.is("Linux") then
+ files {
+ "OpenGLWindow/X11OpenGLWindow.cpp",
+ "OpenGLWindow/X11OpenGLWindows.h"
+ }
+ links {"X11", "pthread", "dl"}
+
+ if _OPTIONS["with-gtk3nfd"] then -- NFD + GTK3
+ defines { "USE_NATIVEFILEDIALOG" }
+ includedirs { "./ThirdPartyLibs/nativefiledialog/src/include/" }
+ buildoptions { "`pkg-config --cflags gtk+-3.0`" }
+ linkoptions { "`pkg-config --libs gtk+-3.0`" }
+ files {
+ "ThirdPartyLibs/nativefiledialog/src/nfd_common.c",
+ "ThirdPartyLibs/nativefiledialog/src/nfd_gtk.c"
+ }
+ end
+
+ end
+ if os.is("MacOSX") then
+ defines { "USE_NATIVEFILEDIALOG" }
+ links {"Cocoa.framework"}
+ files {
+ "OpenGLWindow/MacOpenGLWindow.h",
+ "OpenGLWindow/MacOpenGLWindow.mm",
+ }
+ includedirs { "./ThirdPartyLibs/nativefiledialog/src/include/" }
+ files {
+ "ThirdPartyLibs/nativefiledialog/src/nfd_common.c",
+ "ThirdPartyLibs/nativefiledialog/src/nfd_cocoa.m"
+ }
+ end
+
+ configuration "Debug"
+ defines { "DEBUG" } -- -DDEBUG
+ flags { "Symbols" }
+ targetname "exrview_debug"
+
+ configuration "Release"
+ -- defines { "NDEBUG" } -- -NDEBUG
+ flags { "Symbols", "Optimize" }
+ targetname "exrview"
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/screenshots/exrview.png b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/screenshots/exrview.png
new file mode 100644
index 0000000000..67bec21c24
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/screenshots/exrview.png
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/shader.frag b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/shader.frag
new file mode 100644
index 0000000000..2ad28caef8
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/shader.frag
@@ -0,0 +1,12 @@
+varying vec2 texcoord;
+
+uniform sampler2D tex;
+
+uniform float intensity_scale;
+uniform float gamma;
+
+void main()
+{
+ vec4 rgba = texture2D(tex, texcoord);
+ gl_FragColor = vec4(pow(intensity_scale * rgba.rgb, vec3(1.0 / gamma)), 1.0);
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/exrview/shader.vert b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/shader.vert
new file mode 100644
index 0000000000..e0f91b3ab4
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/exrview/shader.vert
@@ -0,0 +1,12 @@
+#version 110
+
+attribute vec2 in_position;
+attribute vec2 in_texcoord;
+
+varying vec2 texcoord;
+
+void main()
+{
+ gl_Position = vec4(in_position, 0.0, 1.0);
+ texcoord = in_texcoord;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/ldr2exr/Makefile b/graphics/asymptote/cudareflect/tinyexr/examples/ldr2exr/Makefile
new file mode 100644
index 0000000000..5ae4ee63be
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/ldr2exr/Makefile
@@ -0,0 +1,3 @@
+all:
+ gcc -O2 -c -I../../deps/miniz ../../deps/miniz/miniz.c
+ g++ -O2 -o ldr2exr -I../common -I../../ -I../../deps/miniz ldr2exr.cc ../../tinyexr.cc miniz.o
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/ldr2exr/ldr2exr.cc b/graphics/asymptote/cudareflect/tinyexr/examples/ldr2exr/ldr2exr.cc
new file mode 100644
index 0000000000..63e0c8a736
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/ldr2exr/ldr2exr.cc
@@ -0,0 +1,85 @@
+#include <cstdio>
+#include <cstdlib>
+#include <vector>
+
+#define STB_IMAGE_IMPLEMENTATION
+#include "stb_image.h"
+
+#include "tinyexr.h"
+
+int main(int argc, char** argv)
+{
+ if (argc < 3) {
+ printf("Usage: ldr2exr input.[png|bmp|tga|jpg|...] output.exr\n");
+ printf(" NOTE: Supported LDR image format = stb_image can load.\n");
+ printf(" NOTE: Input pixel value [0, 255] is mapped to [0.0, 1.0] in output EXR file.\n");
+ printf(" NOTE: Only supports RGB pixel format.\n");
+
+ exit(-1);
+ }
+
+ int width, height;
+ int n;
+ unsigned char *rgb = stbi_load(argv[1], &width, &height, &n, 0);
+ if (!rgb || n != 3) {
+ return -1;
+ }
+
+ EXRHeader header;
+ InitEXRHeader(&header);
+
+ EXRImage image;
+ InitEXRImage(&image);
+
+ image.num_channels = 3;
+
+ std::vector<float> images[3];
+ images[0].resize(width * height);
+ images[1].resize(width * height);
+ images[2].resize(width * height);
+
+ for (int i = 0; i < width * height; i++) {
+ images[0][i] = rgb[3*i+0] / 255.0f;
+ images[1][i] = rgb[3*i+1] / 255.0f;
+ images[2][i] = rgb[3*i+2] / 255.0f;
+ }
+
+ float* image_ptr[3];
+ image_ptr[0] = &(images[2].at(0)); // B
+ image_ptr[1] = &(images[1].at(0)); // G
+ image_ptr[2] = &(images[0].at(0)); // R
+
+ image.images = (unsigned char**)image_ptr;
+ image.width = width;
+ image.height = height;
+
+ header.num_channels = 3;
+ header.channels = (EXRChannelInfo *)malloc(sizeof(EXRChannelInfo) * header.num_channels);
+ // Must be BGR(A) order, since most of EXR viewers expect this channel order.
+ strncpy(header.channels[0].name, "B", 255); header.channels[0].name[strlen("B")] = '\0';
+ strncpy(header.channels[1].name, "G", 255); header.channels[1].name[strlen("G")] = '\0';
+ strncpy(header.channels[2].name, "R", 255); header.channels[2].name[strlen("R")] = '\0';
+
+ header.pixel_types = (int *)malloc(sizeof(int) * header.num_channels);
+ header.requested_pixel_types = (int *)malloc(sizeof(int) * header.num_channels);
+ for (int i = 0; i < header.num_channels; i++) {
+ header.pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image
+ header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_HALF; // pixel type of output image to be stored in .EXR
+ }
+
+ const char* err;
+ int ret = SaveEXRImageToFile(&image, &header, argv[2], &err);
+ if (ret != TINYEXR_SUCCESS) {
+ fprintf(stderr, "Save EXR err: %s\n", err);
+ return ret;
+ }
+ printf("Saved exr file. [ %s ] \n", argv[2]);
+
+ free(rgb);
+
+ free(header.channels);
+ free(header.pixel_types);
+ free(header.requested_pixel_types);
+
+ return 0;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/Makefile b/graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/Makefile
new file mode 100644
index 0000000000..eacf84b5f2
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/Makefile
@@ -0,0 +1,3 @@
+all:
+ clang -O2 -c -I../../deps/miniz ../../deps/miniz/miniz.c
+ clang++ -O2 -g -fsanitize=address -I../common -I../../ -I../../deps/miniz -o normalmap main.cc miniz.o
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/README.md b/graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/README.md
new file mode 100644
index 0000000000..4cbf4b5304
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/README.md
@@ -0,0 +1,13 @@
+# Normal map generation tool
+
+Load bump or vector displacement map and convert it to normal map.
+(For vector displacement map, it generates approximated normal map)
+
+
+## TODO
+
+* [ ] Mip map generation with normal map prefiltering
+
+## Licenses
+
+* cxxopts.hpp : Copyright (c) 2014, 2015, 2016, 2017 Jarryd Beck. MIT license.
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/main.cc b/graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/main.cc
new file mode 100644
index 0000000000..6571739ff3
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/nornalmap/main.cc
@@ -0,0 +1,267 @@
+#define TINYEXR_IMPLEMENTATION
+#include "tinyexr.h"
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+#endif
+
+#define STB_IMAGE_RESIZE_IMPLEMENTATION
+#include "stb_image_resize.h"
+
+#define STB_IMAGE_WRITE_IMPLEMENTATION
+#include "stb_image_write.h"
+
+#include "cxxopts.hpp"
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+namespace {
+
+static void vnormalize(float v[3]) {
+ const float d2 = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
+ if (d2 > 1.0e-6f) {
+ const float inv_d = 1.0f / std::sqrt(d2);
+ v[0] *= inv_d;
+ v[1] *= inv_d;
+ v[2] *= inv_d;
+ }
+ return;
+}
+
+
+template<typename T>
+static inline T clamp(const T v, const T min_v, const T max_v)
+{
+ return std::max(min_v, std::min(max_v, v));
+}
+
+//
+// Compute gradient from scalar field.
+// dx = (x + 1, y ) - (x, y)
+// dy = (x , y + 1) - (x, y)
+//
+// TODO(syoyo): Use central difference with texel filtering.
+//
+static void Gradient(
+ const std::vector<float> &src,
+ const size_t width,
+ const size_t height,
+ const size_t x, const size_t y,
+ const float bumpness,
+ float dir[3])
+{
+ const size_t x1 = clamp(x + 1, size_t(0), width - 1);
+ const size_t y1 = clamp(y + 1, size_t(0), height - 1);
+
+
+ float v00 = src[y * width + x];
+ float v01 = src[y * width + x1];
+ float v11 = src[y1 * width + x];
+
+
+ float dx = bumpness * (v01 - v00);
+ float dy = bumpness * (v11 - v00);
+
+ dir[0] = dx;
+ dir[1] = dy;
+ dir[2] = 0.0f;
+
+}
+
+///
+/// Convert image(bump map for single channel, vector displacement map for 3 channels input) to normal map.
+/// @param[in] base Base value fo
+///
+///
+static void ToNormalMap(
+ const std::vector<float> &src,
+ const size_t width,
+ const size_t height,
+ const size_t channels,
+ const float strength,
+ std::vector<float> *dst)
+{
+ assert((channels == 1) || (channels == 3) || (channels == 4));
+
+ dst->resize(width * height * 3);
+
+ if (channels == 1) {
+ // bump map
+ for (size_t y = 0; y < height; y++) {
+ for (size_t x = 0; x < width; x++) {
+ float d[3];
+ Gradient(src, width, height, x, y, strength, d);
+
+ (*dst)[3 * (y * width + x) + 0] = d[0];
+ (*dst)[3 * (y * width + x) + 1] = d[1];
+ (*dst)[3 * (y * width + x) + 2] = d[2];
+
+ }
+ }
+
+ } else {
+ // vector displacement map
+
+ for (size_t y = 0; y < height; y++) {
+ for (size_t x = 0; x < width; x++) {
+
+ float v[3];
+ v[0] = src[channels * (y * width + x) + 0];
+ v[1] = src[channels * (y * width + x) + 1];
+ v[2] = src[channels * (y * width + x) + 2];
+
+ v[0] *= strength;
+ v[1] *= strength;
+ v[2] *= strength;
+
+ // Add (0, 0, 1)
+ v[2] += 1.0f;
+
+ // TODO(syoyo): Add option to not normalize.
+ vnormalize(v);
+
+ (*dst)[3 * (y * width + x) + 0] = 0.5f * v[0] + 0.5f;
+ (*dst)[3 * (y * width + x) + 1] = 0.5f * v[1] + 0.5f;
+ (*dst)[3 * (y * width + x) + 2] = 0.5f * v[2] + 0.5f;
+
+ }
+ }
+
+ }
+
+}
+
+inline unsigned char ftouc(float f)
+{
+ int i = static_cast<int>(f * 255.0f);
+ if (i > 255) i = 255;
+ if (i < 0) i = 0;
+
+ return static_cast<unsigned char>(i);
+}
+
+bool SaveImage(const char* filename, const float* rgb, int width, int height) {
+
+ std::vector<unsigned char> dst(width * height * 3);
+
+ for (size_t i = 0; i < width * height; i++) {
+ dst[i * 3 + 0] = ftouc(rgb[i * 3 + 0]);
+ dst[i * 3 + 1] = ftouc(rgb[i * 3 + 1]);
+ dst[i * 3 + 2] = ftouc(rgb[i * 3 + 2]);
+ }
+
+ int ret = stbi_write_png(filename, width, height, 3, static_cast<const void*>(dst.data()), width * 3);
+
+ return (ret > 0);
+}
+
+std::string GetFileExtension(const std::string &filename) {
+ if (filename.find_last_of(".") != std::string::npos)
+ return filename.substr(filename.find_last_of(".") + 1);
+ return "";
+}
+
+} // namespace
+
+int main(int argc, char **argv)
+{
+ cxxopts::Options options("normalmap", "help");
+ options.add_options()
+ ("s,strength", "Strength(scaling) for normal value", cxxopts::value<float>())
+ ("i,input", "Input filename", cxxopts::value<std::string>())
+ ("o,output", "Output filename", cxxopts::value<std::string>())
+ ("r,resize", "Resize image. 0.5 = 50%%, 0.1 = 10%%", cxxopts::value<float>())
+ ;
+
+ auto result = options.parse(argc, argv);
+
+ if (result.count("input") == 0) {
+ std::cerr << "input filename missing" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ if (result.count("output") == 0) {
+ std::cerr << "output filename missing" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ float strength = 1.0f;
+ if (result.count("strength")) {
+ strength = result["strength"].as<float>();
+ }
+
+ float resize = 1.0f;
+ if (result.count("resize")) {
+ resize = result["resize"].as<float>();
+ }
+
+ std::string input_filename = result["input"].as<std::string>();
+ std::string output_filename = result["output"].as<std::string>();
+
+ std::vector<float> src;
+ size_t src_width;
+ size_t src_height;
+
+ {
+ float *rgba = nullptr;
+ int width, height;
+ const char *err = nullptr;
+ int ret = LoadEXR(&rgba, &width, &height, input_filename.c_str(), &err);
+ if (TINYEXR_SUCCESS != ret) {
+ std::cerr << "Failed to load EXR file [" << input_filename << "] code = " << ret << std::endl;
+ if (err) {
+ std::cerr << err << std::endl;
+ FreeEXRErrorMessage(err);
+ }
+
+ return EXIT_FAILURE;
+ }
+
+ std::cout << "loaded EXR. width x height = " << width << "x" << height << std::endl;
+ src.resize(size_t(width * height * 3));
+
+ // ignore alpha for now
+ for (size_t i = 0; i < size_t(width * height); i++) {
+ src[3 * i + 0] = rgba[4 * i + 0];
+ src[3 * i + 1] = rgba[4 * i + 1];
+ src[3 * i + 2] = rgba[4 * i + 2];
+ }
+
+ src_width = size_t(width);
+ src_height = size_t(height);
+
+ free(rgba);
+ }
+
+ std::cout << "strength = " << strength << std::endl;
+
+ std::vector<float> dst;
+ ToNormalMap(src, src_width, src_height, 3, strength, &dst);
+
+
+ std::string ext = GetFileExtension(output_filename);
+ if ((ext.compare("png") == 0) ||
+ (ext.compare("PNG") == 0)) {
+ // Save as LDR image.
+ // Do not apply sRGB conversion for PNG(LDR) image.
+ if (!SaveImage(output_filename.c_str(), dst.data(), int(src_width), int(src_height))) {
+ std::cerr << "Failed to write a file : " << output_filename << std::endl;
+ return EXIT_FAILURE;
+ }
+ } else {
+ // assume EXR.
+ float *rgba = nullptr;
+ int width, height;
+ int ret = SaveEXR(dst.data(), int(src_width), int(src_height), /* component */3, /* fp16 */0, output_filename.c_str(), nullptr);
+ if (TINYEXR_SUCCESS != ret) {
+ std::cerr << "Failed to save EXR file [" << input_filename << "] code = " << ret << std::endl;
+ return EXIT_FAILURE;
+ }
+ }
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/resize/Makefile b/graphics/asymptote/cudareflect/tinyexr/examples/resize/Makefile
new file mode 100644
index 0000000000..423b221406
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/resize/Makefile
@@ -0,0 +1,3 @@
+all:
+ clang -g -O2 -c -I../../deps/miniz ../../deps/miniz/miniz.c
+ clang++ -fsanitize=undefined -O2 -o exrresize -I../common -I../../ -I../../deps/miniz resize.cc ../../tinyexr.cc miniz.o
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/resize/resize.cc b/graphics/asymptote/cudareflect/tinyexr/examples/resize/resize.cc
new file mode 100644
index 0000000000..c78d9a8790
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/resize/resize.cc
@@ -0,0 +1,46 @@
+#include <cstdio>
+#include <cstdlib>
+#include <vector>
+
+#define STB_IMAGE_RESIZE_IMPLEMENTATION
+#include "stb_image_resize.h"
+
+#include "tinyexr.h"
+
+int main(int argc, char** argv)
+{
+ if (argc < 5) {
+ printf("Usage: exrresize input.exr output.exr dst_width dst_height.\n");
+ printf(" Only supports RGB or RGBA EXR input.\n");
+ exit(-1);
+ }
+
+ int dst_width = atoi(argv[3]);
+ int dst_height = atoi(argv[4]);
+
+ int width, height;
+ float* rgba;
+ const char* err;
+
+ {
+ int ret = LoadEXR(&rgba, &width, &height, argv[1], &err);
+ if (ret != TINYEXR_SUCCESS) {
+ printf("err: %s\n", err);
+ return -1;
+ }
+ }
+
+ std::vector<float> buf(dst_width * dst_height * 4);
+ int ret = stbir_resize_float(rgba, width, height, width*4*sizeof(float), &buf.at(0), dst_width, dst_height,dst_width*4*sizeof(float), 4);
+ assert(ret != 0);
+
+ ret = SaveEXR(buf.data(), dst_width, dst_height, 4, /*fp16*/0, argv[2], &err);
+ if (ret != TINYEXR_SUCCESS) {
+ if (err) {
+ fprintf(stderr, "err: %s\n", err);
+ FreeEXRErrorMessage(err);
+ }
+ }
+
+ return (ret == TINYEXR_SUCCESS);
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/rgbe2exr/Makefile b/graphics/asymptote/cudareflect/tinyexr/examples/rgbe2exr/Makefile
new file mode 100644
index 0000000000..32b5afd84e
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/rgbe2exr/Makefile
@@ -0,0 +1,3 @@
+all:
+ gcc -O2 -c -I../../deps/miniz ../../deps/miniz/miniz.c
+ g++ -O2 -o rgbe2exr -I../common -I../../ -I../../deps/miniz rgbe2exr.cc ../../tinyexr.cc miniz.o
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/rgbe2exr/rgbe2exr.cc b/graphics/asymptote/cudareflect/tinyexr/examples/rgbe2exr/rgbe2exr.cc
new file mode 100644
index 0000000000..c0da5a6d60
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/rgbe2exr/rgbe2exr.cc
@@ -0,0 +1,81 @@
+#include <cstdio>
+#include <cstdlib>
+#include <vector>
+
+#define STB_IMAGE_IMPLEMENTATION
+#include "stb_image.h"
+
+#include "tinyexr.h"
+
+int main(int argc, char** argv)
+{
+ if (argc < 3) {
+ printf("Usage: rgbe2exr input.hdr output.exr\n");
+ exit(-1);
+ }
+
+ int width, height;
+ int n;
+ float *rgb = stbi_loadf(argv[1], &width, &height, &n, 0);
+ if (!rgb || n != 3) {
+ return -1;
+ }
+
+ EXRHeader header;
+ InitEXRHeader(&header);
+
+ EXRImage image;
+ InitEXRImage(&image);
+
+ image.num_channels = 3;
+
+ std::vector<float> images[3];
+ images[0].resize(width * height);
+ images[1].resize(width * height);
+ images[2].resize(width * height);
+
+ for (int i = 0; i < width * height; i++) {
+ images[0][i] = rgb[3*i+0];
+ images[1][i] = rgb[3*i+1];
+ images[2][i] = rgb[3*i+2];
+ }
+
+ float* image_ptr[3];
+ image_ptr[0] = &(images[2].at(0)); // B
+ image_ptr[1] = &(images[1].at(0)); // G
+ image_ptr[2] = &(images[0].at(0)); // R
+
+ image.images = (unsigned char**)image_ptr;
+ image.width = width;
+ image.height = height;
+
+ header.num_channels = 3;
+ header.channels = (EXRChannelInfo *)malloc(sizeof(EXRChannelInfo) * header.num_channels);
+ // Must be BGR(A) order, since most of EXR viewers expect this channel order.
+ strncpy(header.channels[0].name, "B", 255); header.channels[0].name[strlen("B")] = '\0';
+ strncpy(header.channels[1].name, "G", 255); header.channels[1].name[strlen("G")] = '\0';
+ strncpy(header.channels[2].name, "R", 255); header.channels[2].name[strlen("R")] = '\0';
+
+ header.pixel_types = (int *)malloc(sizeof(int) * header.num_channels);
+ header.requested_pixel_types = (int *)malloc(sizeof(int) * header.num_channels);
+ for (int i = 0; i < header.num_channels; i++) {
+ header.pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image
+ header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_HALF; // pixel type of output image to be stored in .EXR
+ }
+
+ const char* err;
+ int ret = SaveEXRImageToFile(&image, &header, argv[2], &err);
+ if (ret != TINYEXR_SUCCESS) {
+ fprintf(stderr, "Save EXR err: %s\n", err);
+ return ret;
+ }
+ printf("Saved exr file. [ %s ] \n", argv[2]);
+
+ free(rgb);
+
+ free(header.channels);
+ free(header.pixel_types);
+ free(header.requested_pixel_types);
+
+ return 0;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/Makefile b/graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/Makefile
new file mode 100644
index 0000000000..0dc31f69d0
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/Makefile
@@ -0,0 +1,3 @@
+all:
+ gcc -O2 -I../../deps/miniz -c ../../deps/miniz/miniz.c
+ g++ -std=c++11 -O2 -o testmapgen -I../common -I../../ -I../../deps/miniz testmapgen.cc ../../tinyexr.cc miniz.o
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/README.md b/graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/README.md
new file mode 100644
index 0000000000..0b5fe97d5d
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/README.md
@@ -0,0 +1,15 @@
+# Test EXR image map gen
+
+Generate test EXR images for envmap test, composition test, etc.
+
+* white(R=1, G=1, B=1)
+* white10(R=10, G=10, B=10)
+* white100(R=100, G=100, B=100)
+
+
+## TODO
+
+* [ ] red(R=1, G=0, B=0)
+* [ ] green(R=0, G=1, B=0)
+* [ ] blue(R=0, G=0, B=1)
+* [ ] longlat test image
diff --git a/graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/testmapgen.cc b/graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/testmapgen.cc
new file mode 100644
index 0000000000..79514652a6
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/examples/testmapgen/testmapgen.cc
@@ -0,0 +1,86 @@
+#include <cstdio>
+#include <cstdlib>
+#include <vector>
+#include <iostream>
+
+#include "tinyexr.h"
+
+static void GenerateWhite1(size_t width, size_t height)
+{
+ std::vector<float> rgb;
+ rgb.resize(width * height * 3);
+
+ for (size_t i = 0; i < width * height * 3; i++) {
+ rgb[i] = 1.0f;
+ }
+
+ const char *err = nullptr;
+ int ret = SaveEXR(rgb.data(), int(width), int(height), /* channels */3, /* fp16? */0, "white1.exr", &err);
+ if (!ret) {
+ if (err) {
+ std::cerr << err << std::endl;
+ FreeEXRErrorMessage(err);
+ }
+ std::cerr << "failed to write white.exr" << std::endl;
+ }
+}
+
+static void GenerateWhite10(size_t width, size_t height)
+{
+ std::vector<float> rgb;
+ rgb.resize(width * height * 3);
+
+ for (size_t i = 0; i < width * height * 3; i++) {
+ rgb[i] = 10.0f;
+ }
+
+ const char *err = nullptr;
+ int ret = SaveEXR(rgb.data(), int(width), int(height), /* channels */3, /* fp16? */0, "white10.exr", &err);
+ if (!ret) {
+ if (err) {
+ std::cerr << err << std::endl;
+ FreeEXRErrorMessage(err);
+ }
+ std::cerr << "failed to write white10.exr" << std::endl;
+ }
+}
+
+static void GenerateWhite100(size_t width, size_t height)
+{
+ std::vector<float> rgb;
+ rgb.resize(width * height * 3);
+
+ for (size_t i = 0; i < width * height * 3; i++) {
+ rgb[i] = 100.0f;
+ }
+
+ const char *err = nullptr;
+ int ret = SaveEXR(rgb.data(), int(width), int(height), /* channels */3, /* fp16? */0, "white100.exr", &err);
+ if (!ret) {
+ if (err) {
+ std::cerr << err << std::endl;
+ FreeEXRErrorMessage(err);
+ }
+ std::cerr << "failed to write white100.exr" << std::endl;
+ }
+}
+
+int main(int argc, char** argv)
+{
+ int width = 512;
+ int height = 512;
+
+ if (argc > 2) {
+ width = std::min(1, atoi(argv[2]));
+ }
+
+ if (argc > 3) {
+ height = std::min(1, atoi(argv[3]));
+ }
+
+ GenerateWhite1(width, height);
+ GenerateWhite10(width, height);
+ GenerateWhite100(width, height);
+
+ return EXIT_SUCCESS;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/experimental/js/Makefile b/graphics/asymptote/cudareflect/tinyexr/experimental/js/Makefile
new file mode 100644
index 0000000000..4f83f29a74
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/experimental/js/Makefile
@@ -0,0 +1,2 @@
+all:
+ ./compile_to_js.sh
diff --git a/graphics/asymptote/cudareflect/tinyexr/experimental/js/README.md b/graphics/asymptote/cudareflect/tinyexr/experimental/js/README.md
new file mode 100644
index 0000000000..9132541327
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/experimental/js/README.md
@@ -0,0 +1,38 @@
+# Experimental JavaScript port of TinyEXR
+
+Using Emscripten.
+
+## How to compile
+
+edit `compile_to_js.sh`, then
+
+```
+./compile_to_js.sh
+```
+
+## How to run test
+
+Requires node.js
+
+```
+$ node test.js
+```
+
+## How to run a browser example
+
+Edit EXR file in `index.html`
+Copy a EXR file to this directory(default = asakusa.exr).
+(NOTE: Chrome does not allow reading a file from parent path(e.g. `../../asakusa.exr`).
+
+Launch http server, e.g.,
+
+```
+$ python3 -m http.server
+```
+
+Open `http://localhost:8000` with an browser.
+
+## TODO
+
+* [x] Write HTML5 Canvas drawing JS code from Float32Array(
+* [ ] Pollish JS API.
diff --git a/graphics/asymptote/cudareflect/tinyexr/experimental/js/binding.cc b/graphics/asymptote/cudareflect/tinyexr/experimental/js/binding.cc
new file mode 100644
index 0000000000..4f6856848b
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/experimental/js/binding.cc
@@ -0,0 +1,79 @@
+#include <vector>
+
+#include <emscripten/bind.h>
+
+#define TINYEXR_IMPLEMENTATION
+#include "tinyexr.h"
+
+using namespace emscripten;
+
+///
+/// Simple C++ wrapper class for Emscripten
+///
+class EXRLoader {
+ public:
+ ///
+ /// `binary` is the buffer for EXR binary(e.g. buffer read by fs.readFileSync)
+ /// std::string can be used as UInt8Array in JS layer.
+ ///
+ EXRLoader(const std::string &binary) {
+ const float *ptr = reinterpret_cast<const float *>(binary.data());
+
+ float *rgba = nullptr;
+ width_ = -1;
+ height_ = -1;
+ const char *err = nullptr;
+
+ error_.clear();
+
+ result_ = LoadEXRFromMemory(
+ &rgba, &width_, &height_,
+ reinterpret_cast<const unsigned char *>(binary.data()), binary.size(),
+ &err);
+
+ if (TINYEXR_SUCCESS == result_) {
+ image_.resize(size_t(width_ * height_ * 4));
+ memcpy(image_.data(), rgba, sizeof(float) * size_t(width_ * height_ * 4));
+ free(rgba);
+ } else {
+ if (err) {
+ error_ = std::string(err);
+ }
+ }
+ }
+ ~EXRLoader() {}
+
+ // Return as memory views
+ emscripten::val getBytes() const {
+ return emscripten::val(
+ emscripten::typed_memory_view(image_.size(), image_.data()));
+ }
+
+ bool ok() const { return (TINYEXR_SUCCESS == result_); }
+
+ const std::string error() const { return error_; }
+
+ int width() const { return width_; }
+
+ int height() const { return height_; }
+
+ private:
+ std::vector<float> image_; // RGBA
+ int width_;
+ int height_;
+ int result_;
+ std::string error_;
+};
+
+// Register STL
+EMSCRIPTEN_BINDINGS(stl_wrappters) { register_vector<float>("VectorFloat"); }
+
+EMSCRIPTEN_BINDINGS(tinyexr_module) {
+ class_<EXRLoader>("EXRLoader")
+ .constructor<const std::string &>()
+ .function("getBytes", &EXRLoader::getBytes)
+ .function("ok", &EXRLoader::ok)
+ .function("error", &EXRLoader::error)
+ .function("width", &EXRLoader::width)
+ .function("height", &EXRLoader::height);
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/experimental/js/compile_to_js.sh b/graphics/asymptote/cudareflect/tinyexr/experimental/js/compile_to_js.sh
new file mode 100755
index 0000000000..dc750844bf
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/experimental/js/compile_to_js.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+EMCC=em++
+MINIZ='-I../../deps/miniz/ ../../deps/miniz/miniz.c'
+
+# Export EXR loader/saver function to JS.
+# TODO: export more functions
+# DEMANGLE_SUPPORT=1
+#${EMCC} -std=c++11 --bind -O2 -I../../ binding.cc ${MINIZ} --memory-init-file 0 -s TOTAL_MEMORY=67108864 -s DEMANGLE_SUPPORT=1 -s EXPORTED_FUNCTIONS="['_ParseEXRHeaderFromMemory', '_LoadEXRFromMemory']" -o tinyexr.js
+${EMCC} --bind -Os -I../../ binding.cc ${MINIZ} --memory-init-file 0 -s TOTAL_MEMORY=67108864 -o tinyexr.js
diff --git a/graphics/asymptote/cudareflect/tinyexr/experimental/js/index.html b/graphics/asymptote/cudareflect/tinyexr/experimental/js/index.html
new file mode 100644
index 0000000000..d46e342d0e
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/experimental/js/index.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
+ <title>TinyEXR to Canvas</title>
+ <script src="tinyexr.js"></script>
+ <style>
+ </style>
+</head>
+<body>
+ <canvas id="imgCanvas"></canvas>
+</body>
+<script>
+ let canvas = document.getElementById('imgCanvas');
+ let ctx = canvas.getContext('2d');
+
+ fetch("./asakusa.exr").then(response => {
+ return response.arrayBuffer();
+ }).then(arrayBuffer => {
+
+ // let exrImg = parseExr(arrayBuffer);
+ let data = new Uint8Array(arrayBuffer);
+ let exrImg = new Module.EXRLoader(data);
+
+ canvas.width = exrImg.width();
+ canvas.height = exrImg.height();
+
+ let imageArray = exrImg.getBytes().map(num => {
+ // Convert values to 0-255 range and apply gamma curve
+ return Math.pow(num, 0.44) * 256;
+ });
+
+ let image8Array = new Uint8ClampedArray(imageArray);
+ let imageData = new ImageData(image8Array, exrImg.width(), exrImg.height());
+ ctx.putImageData(imageData, 0, 0);
+
+ });
+</script>
+</html>
diff --git a/graphics/asymptote/cudareflect/tinyexr/experimental/js/test.js b/graphics/asymptote/cudareflect/tinyexr/experimental/js/test.js
new file mode 100644
index 0000000000..f91d4592ca
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/experimental/js/test.js
@@ -0,0 +1,21 @@
+var fs = require('fs');
+var tinyexr = require('./tinyexr.js')
+
+var data = new Uint8Array(fs.readFileSync("../../asakusa.exr"))
+console.log(data.length)
+
+var instance = new tinyexr.EXRLoader(data);
+
+console.log(instance.ok())
+console.log(instance.width())
+console.log(instance.height())
+
+var image = instance.getBytes()
+console.log(image[0])
+console.log(image[1])
+console.log(image[2])
+console.log(image[3])
+console.log(image[4])
+console.log(image[5])
+console.log(image[6])
+console.log(image[7])
diff --git a/graphics/asymptote/cudareflect/tinyexr/jni/Android.mk b/graphics/asymptote/cudareflect/tinyexr/jni/Android.mk
new file mode 100644
index 0000000000..f2268a06fd
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/jni/Android.mk
@@ -0,0 +1,12 @@
+# A simple test for the minimal standard C++ library
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := tinyexr
+LOCAL_SRC_FILES := ../tinyexr.cc
+
+LOCAL_C_INCLUDES := ../
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/graphics/asymptote/cudareflect/tinyexr/jni/Application.mk b/graphics/asymptote/cudareflect/tinyexr/jni/Application.mk
new file mode 100644
index 0000000000..e5d3191944
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/jni/Application.mk
@@ -0,0 +1,2 @@
+APP_ABI := all
+APP_STL := stlport_static
diff --git a/graphics/asymptote/cudareflect/tinyexr/jni/Makefile b/graphics/asymptote/cudareflect/tinyexr/jni/Makefile
new file mode 100644
index 0000000000..86fd1e55c8
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/jni/Makefile
@@ -0,0 +1,8 @@
+ifeq ($(ANDROID_HOME),)
+NDK ?= $(ANDROID_NDK)
+else
+NDK ?= $(lastword $(sort $(wildcard $(dir $(ANDROID_HOME))/android-ndk*)))
+endif
+
+all:
+ $(NDK)/ndk-build V=1
diff --git a/graphics/asymptote/cudareflect/tinyexr/jni/README.md b/graphics/asymptote/cudareflect/tinyexr/jni/README.md
new file mode 100644
index 0000000000..b3f95d5e34
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/jni/README.md
@@ -0,0 +1,4 @@
+# Android NDK
+
+Test script to build `tinyexr` with Android NDK r10.
+Just checks compilation on Android NDK.
diff --git a/graphics/asymptote/cudareflect/tinyexr/kuroga.py b/graphics/asymptote/cudareflect/tinyexr/kuroga.py
new file mode 100644
index 0000000000..2c41a08ab3
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/kuroga.py
@@ -0,0 +1,312 @@
+#!/usr/bin/env python
+
+#
+# Kuroga, single python file meta-build system for ninja
+# https://github.com/lighttransport/kuroga
+#
+# Requirements: python 2.6 or 2.7
+#
+# Usage: $ python kuroga.py input.py
+#
+
+import imp
+import re
+import textwrap
+import glob
+import os
+import sys
+
+# gcc preset
+def add_gnu_rule(ninja):
+ ninja.rule('gnucxx', description='CXX $out',
+ command='$gnucxx -MMD -MF $out.d $gnudefines $gnuincludes $gnucxxflags -c $in -o $out',
+ depfile='$out.d', deps='gcc')
+ ninja.rule('gnucc', description='CC $out',
+ command='$gnucc -MMD -MF $out.d $gnudefines $gnuincludes $gnucflags -c $in -o $out',
+ depfile='$out.d', deps='gcc')
+ ninja.rule('gnulink', description='LINK $out', pool='link_pool',
+ command='$gnuld -o $out $in $libs $gnuldflags')
+ ninja.rule('gnuar', description='AR $out', pool='link_pool',
+ command='$gnuar rsc $out $in')
+ ninja.rule('gnustamp', description='STAMP $out', command='touch $out')
+ ninja.newline()
+
+ ninja.variable('gnucxx', 'g++')
+ ninja.variable('gnucc', 'gcc')
+ ninja.variable('gnuld', '$gnucxx')
+ ninja.variable('gnuar', 'ar')
+ ninja.newline()
+
+# clang preset
+def add_clang_rule(ninja):
+ ninja.rule('clangcxx', description='CXX $out',
+ command='$clangcxx -MMD -MF $out.d $clangdefines $clangincludes $clangcxxflags -c $in -o $out',
+ depfile='$out.d', deps='gcc')
+ ninja.rule('clangcc', description='CC $out',
+ command='$clangcc -MMD -MF $out.d $clangdefines $clangincludes $clangcflags -c $in -o $out',
+ depfile='$out.d', deps='gcc')
+ ninja.rule('clanglink', description='LINK $out', pool='link_pool',
+ command='$clangld -o $out $in $libs $gnuldflags')
+ ninja.rule('clangar', description='AR $out', pool='link_pool',
+ command='$clangar rsc $out $in')
+ ninja.rule('clangstamp', description='STAMP $out', command='touch $out')
+ ninja.newline()
+
+ ninja.variable('clangcxx', 'clang++')
+ ninja.variable('clangcc', 'clang')
+ ninja.variable('clangld', '$clangcxx')
+ ninja.variable('clangar', 'ar')
+ ninja.newline()
+
+# msvc preset
+def add_msvc_rule(ninja):
+ ninja.rule('msvccxx', description='CXX $out',
+ command='$msvccxx /TP /showIncludes $msvcdefines $msvcincludes $msvccxxflags -c $in /Fo$out',
+ depfile='$out.d', deps='msvc')
+ ninja.rule('msvccc', description='CC $out',
+ command='$msvccc /TC /showIncludes $msvcdefines $msvcincludes $msvccflags -c $in /Fo$out',
+ depfile='$out.d', deps='msvc')
+ ninja.rule('msvclink', description='LINK $out', pool='link_pool',
+ command='$msvcld $msvcldflags $in $libs /OUT:$out')
+ ninja.rule('msvcar', description='AR $out', pool='link_pool',
+ command='$msvcar $in /OUT:$out')
+ #ninja.rule('msvcstamp', description='STAMP $out', command='touch $out')
+ ninja.newline()
+
+ ninja.variable('msvccxx', 'cl.exe')
+ ninja.variable('msvccc', 'cl.exe')
+ ninja.variable('msvcld', 'link.exe')
+ ninja.variable('msvcar', 'lib.exe')
+ ninja.newline()
+
+# -- from ninja_syntax.py --
+def escape_path(word):
+ return word.replace('$ ', '$$ ').replace(' ', '$ ').replace(':', '$:')
+
+class Writer(object):
+ def __init__(self, output, width=78):
+ self.output = output
+ self.width = width
+
+ def newline(self):
+ self.output.write('\n')
+
+ def comment(self, text, has_path=False):
+ for line in textwrap.wrap(text, self.width - 2, break_long_words=False,
+ break_on_hyphens=False):
+ self.output.write('# ' + line + '\n')
+
+ def variable(self, key, value, indent=0):
+ if value is None:
+ return
+ if isinstance(value, list):
+ value = ' '.join(filter(None, value)) # Filter out empty strings.
+ self._line('%s = %s' % (key, value), indent)
+
+ def pool(self, name, depth):
+ self._line('pool %s' % name)
+ self.variable('depth', depth, indent=1)
+
+ def rule(self, name, command, description=None, depfile=None,
+ generator=False, pool=None, restat=False, rspfile=None,
+ rspfile_content=None, deps=None):
+ self._line('rule %s' % name)
+ self.variable('command', command, indent=1)
+ if description:
+ self.variable('description', description, indent=1)
+ if depfile:
+ self.variable('depfile', depfile, indent=1)
+ if generator:
+ self.variable('generator', '1', indent=1)
+ if pool:
+ self.variable('pool', pool, indent=1)
+ if restat:
+ self.variable('restat', '1', indent=1)
+ if rspfile:
+ self.variable('rspfile', rspfile, indent=1)
+ if rspfile_content:
+ self.variable('rspfile_content', rspfile_content, indent=1)
+ if deps:
+ self.variable('deps', deps, indent=1)
+
+ def build(self, outputs, rule, inputs=None, implicit=None, order_only=None,
+ variables=None):
+ outputs = as_list(outputs)
+ out_outputs = [escape_path(x) for x in outputs]
+ all_inputs = [escape_path(x) for x in as_list(inputs)]
+
+ if implicit:
+ implicit = [escape_path(x) for x in as_list(implicit)]
+ all_inputs.append('|')
+ all_inputs.extend(implicit)
+ if order_only:
+ order_only = [escape_path(x) for x in as_list(order_only)]
+ all_inputs.append('||')
+ all_inputs.extend(order_only)
+
+ self._line('build %s: %s' % (' '.join(out_outputs),
+ ' '.join([rule] + all_inputs)))
+
+ if variables:
+ if isinstance(variables, dict):
+ iterator = iter(variables.items())
+ else:
+ iterator = iter(variables)
+
+ for key, val in iterator:
+ self.variable(key, val, indent=1)
+
+ return outputs
+
+ def include(self, path):
+ self._line('include %s' % path)
+
+ def subninja(self, path):
+ self._line('subninja %s' % path)
+
+ def default(self, paths):
+ self._line('default %s' % ' '.join(as_list(paths)))
+
+ def _count_dollars_before_index(self, s, i):
+ """Returns the number of '$' characters right in front of s[i]."""
+ dollar_count = 0
+ dollar_index = i - 1
+ while dollar_index > 0 and s[dollar_index] == '$':
+ dollar_count += 1
+ dollar_index -= 1
+ return dollar_count
+
+ def _line(self, text, indent=0):
+ """Write 'text' word-wrapped at self.width characters."""
+ leading_space = ' ' * indent
+ while len(leading_space) + len(text) > self.width:
+ # The text is too wide; wrap if possible.
+
+ # Find the rightmost space that would obey our width constraint and
+ # that's not an escaped space.
+ available_space = self.width - len(leading_space) - len(' $')
+ space = available_space
+ while True:
+ space = text.rfind(' ', 0, space)
+ if (space < 0 or
+ self._count_dollars_before_index(text, space) % 2 == 0):
+ break
+
+ if space < 0:
+ # No such space; just use the first unescaped space we can find.
+ space = available_space - 1
+ while True:
+ space = text.find(' ', space + 1)
+ if (space < 0 or
+ self._count_dollars_before_index(text, space) % 2 == 0):
+ break
+ if space < 0:
+ # Give up on breaking.
+ break
+
+ self.output.write(leading_space + text[0:space] + ' $\n')
+ text = text[space+1:]
+
+ # Subsequent lines are continuations, so indent them.
+ leading_space = ' ' * (indent+2)
+
+ self.output.write(leading_space + text + '\n')
+
+ def close(self):
+ self.output.close()
+
+
+def as_list(input):
+ if input is None:
+ return []
+ if isinstance(input, list):
+ return input
+ return [input]
+
+# -- end from ninja_syntax.py --
+
+def gen(ninja, toolchain, config):
+
+ ninja.variable('ninja_required_version', '1.4')
+ ninja.newline()
+
+ if hasattr(config, "builddir"):
+ builddir = config.builddir[toolchain]
+ ninja.variable(toolchain + 'builddir', builddir)
+ else:
+ builddir = ''
+
+ ninja.variable(toolchain + 'defines', config.defines[toolchain] or [])
+ ninja.variable(toolchain + 'includes', config.includes[toolchain] or [])
+ ninja.variable(toolchain + 'cflags', config.cflags[toolchain] or [])
+ ninja.variable(toolchain + 'cxxflags', config.cxxflags[toolchain] or [])
+ ninja.variable(toolchain + 'ldflags', config.ldflags[toolchain] or [])
+ ninja.newline()
+
+ if hasattr(config, "link_pool_depth"):
+ ninja.pool('link_pool', depth=config.link_pool_depth)
+ else:
+ ninja.pool('link_pool', depth=4)
+ ninja.newline()
+
+ # Add default toolchain(gnu, clang and msvc)
+ add_gnu_rule(ninja)
+ add_clang_rule(ninja)
+ add_msvc_rule(ninja)
+
+ obj_files = []
+
+ cc = toolchain + 'cc'
+ cxx = toolchain + 'cxx'
+ link = toolchain + 'link'
+ ar = toolchain + 'ar'
+
+ if hasattr(config, "cxx_files"):
+ for src in config.cxx_files:
+ srcfile = src
+ obj = os.path.splitext(srcfile)[0] + '.o'
+ obj = os.path.join(builddir, obj);
+ obj_files.append(obj)
+ ninja.build(obj, cxx, srcfile)
+ ninja.newline()
+
+ if hasattr(config, "c_files"):
+ for src in config.c_files:
+ srcfile = src
+ obj = os.path.splitext(srcfile)[0] + '.o'
+ obj = os.path.join(builddir, obj);
+ obj_files.append(obj)
+ ninja.build(obj, cc, srcfile)
+ ninja.newline()
+
+ targetlist = []
+ if hasattr(config, "exe"):
+ ninja.build(config.exe, link, obj_files)
+ targetlist.append(config.exe)
+
+ if hasattr(config, "staticlib"):
+ ninja.build(config.staticlib, ar, obj_files)
+ targetlist.append(config.staticlib)
+
+ ninja.build('all', 'phony', targetlist)
+ ninja.newline()
+
+ ninja.default('all')
+
+def main():
+ if len(sys.argv) < 2:
+ print("Usage: python kuroga.py config.py")
+ sys.exit(1)
+
+ config = imp.load_source("config", sys.argv[1])
+
+ f = open('build.ninja', 'w')
+ ninja = Writer(f)
+
+ if hasattr(config, "register_toolchain"):
+ config.register_toolchain(ninja)
+
+ gen(ninja, config.toolchain, config)
+ f.close()
+
+main()
diff --git a/graphics/asymptote/cudareflect/tinyexr/premake4.lua b/graphics/asymptote/cudareflect/tinyexr/premake4.lua
new file mode 100644
index 0000000000..7470417960
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/premake4.lua
@@ -0,0 +1,55 @@
+newoption {
+ trigger = "with-zfp",
+ description = "Build with ZFP support."
+}
+
+sources = {
+ "tinyexr.h",
+ "test_tinyexr.cc",
+ }
+
+zfp_sources = {
+ "./deps/ZFP/src/*.c"
+}
+
+miniz_sources = {
+ "./deps/miniz/miniz.c"
+}
+
+-- premake4.lua
+solution "TinyEXRSolution"
+ configurations { "Release", "Debug" }
+
+ if (os.is("windows")) then
+ platforms { "x32", "x64" }
+ else
+ platforms { "native", "x32", "x64" }
+ end
+
+ if _OPTIONS["with-zfp"] then
+ includedirs { "./deps/ZFP/inc" }
+ defines { "TINYEXR_USE_ZFP=1" }
+ files { zfp_sources }
+ end
+
+ if _OPTIONS["with-miniz"] then
+ includedirs { "./deps/miniz" }
+ defines { "TINYEXR_USE_MINIZ=1" }
+ files { miniz_sources }
+ end
+
+ -- A project defines one build target
+ project "tinyexrtest"
+ kind "ConsoleApp"
+ language "C++"
+ files { sources }
+
+ configuration "Debug"
+ defines { "DEBUG" } -- -DDEBUG
+ flags { "Symbols" }
+ targetname "test_tinyexr_debug"
+
+ configuration "Release"
+ -- defines { "NDEBUG" } -- -NDEBUG
+ flags { "Symbols", "Optimize" }
+ targetname "test_tinyexr"
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/CMakeLists.txt b/graphics/asymptote/cudareflect/tinyexr/test/CMakeLists.txt
new file mode 100644
index 0000000000..4a28914486
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/CMakeLists.txt
@@ -0,0 +1,23 @@
+project(tinyexr)
+cmake_minimum_required(VERSION 2.8)
+
+set(tinyexr-Source
+ ${CMAKE_CURRENT_SOURCE_DIR}/../tinyexr.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/../tinyexr.h
+ )
+
+add_library(tinyexr
+ ${tinyexr-Source}
+ )
+
+#Installation
+#install ( TARGETS
+# tinyexr
+# DESTINATION
+# lib
+# )
+#install ( FILES
+# tinyexr.h
+# DESTINATION
+# include
+# )
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/c-binding/Makefile b/graphics/asymptote/cudareflect/tinyexr/test/c-binding/Makefile
new file mode 100644
index 0000000000..66b3371838
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/c-binding/Makefile
@@ -0,0 +1,5 @@
+all:
+ gcc -c -I../../deps/miniz ../../deps/miniz/miniz.c
+ g++ -c -I../../ -I../../deps/miniz ../../tinyexr.cc
+ gcc -c -I../../ test.c
+ gcc test.o tinyexr.o miniz.o -lstdc++
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/c-binding/test.c b/graphics/asymptote/cudareflect/tinyexr/test/c-binding/test.c
new file mode 100644
index 0000000000..3c7f4436f4
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/c-binding/test.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <tinyexr.h>
+
+int main(int argc, char** argv)
+{
+ float *rgba;
+ const char* err;
+ int width;
+ int height;
+
+ if (argc < 2) {
+ return EXIT_FAILURE;
+ }
+
+ int ret = LoadEXR(&rgba, &width, &height, argv[1], &err);
+
+ return ret;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/exrcat/exrcat.cpp b/graphics/asymptote/cudareflect/tinyexr/test/exrcat/exrcat.cpp
new file mode 100644
index 0000000000..bccfc5f815
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/exrcat/exrcat.cpp
@@ -0,0 +1,127 @@
+// https://gist.github.com/mmp/ba384e1f509e2e38d5df#file-exrcat-cpp
+
+#include "tinyexr/tinyexr.h"
+#include "tinyexr/tinyexr.cc"
+#include <stdio.h>
+#include <assert.h>
+#include <vector>
+#include <ImfInputFile.h>
+#include <ImfRgbaFile.h>
+#include <ImfChannelList.h>
+#include <ImfFrameBuffer.h>
+#include <half.h>
+using namespace Imf;
+using namespace Imath;
+
+#if 0
+void
+SaveAsPFM(const char* filename, int width, int height, float* data)
+{
+ FILE* fp = fopen(filename, "wb");
+ if (!fp) {
+ fprintf(stderr, "failed to write a PFM file.\n");
+ return;
+ }
+
+ fprintf(fp, "PF\n");
+ fprintf(fp, "%d %d\n", width, height);
+ fprintf(fp, "-1\n"); // -1: little endian, 1: big endian
+
+ // RGBA -> RGB
+ std::vector<float> rgb(width*height*3);
+
+ for (size_t i = 0; i < width * height; i++) {
+ rgb[3*i+0] = data[4*i+0];
+ rgb[3*i+1] = data[4*i+1];
+ rgb[3*i+2] = data[4*i+2];
+ }
+
+ fwrite(&rgb.at(0), sizeof(float), width * height * 3, fp);
+
+ fclose(fp);
+}
+#endif
+
+static float *OpenExrLoad(const char *name, int *width, int *height) {
+ try {
+ RgbaInputFile file (name);
+ Box2i dw = file.dataWindow();
+ *width = dw.max.x - dw.min.x + 1;
+ *height = dw.max.y - dw.min.y + 1;
+ std::vector<Rgba> pixels(*width * *height);
+ file.setFrameBuffer(&pixels[0] - dw.min.x - dw.min.y * *width, 1, *width);
+ file.readPixels(dw.min.y, dw.max.y);
+
+ printf("OpenExr\n datawindow: (%d %d) - (%d %d)\n", dw.min.x, dw.min.y,
+ dw.max.x, dw.max.y);
+ printf(" line order %s\n", (file.lineOrder() == INCREASING_Y) ?
+ "increasing y" : ((file.lineOrder() == DECREASING_Y) ? "decreasing y"
+ : "random y"));
+ printf(" compression: ");
+ switch (file.compression()) {
+ case NO_COMPRESSION: printf("none"); break;
+ case RLE_COMPRESSION: printf("RLE"); break;
+ case ZIPS_COMPRESSION: printf("zip"); break;
+ case ZIP_COMPRESSION: printf("zips"); break;
+ case PIZ_COMPRESSION: printf("piz"); break;
+ case PXR24_COMPRESSION: printf("pxr24"); break;
+ case B44_COMPRESSION: printf("b44"); break;
+ case B44A_COMPRESSION: printf("b44a"); break;
+ default: printf("unknown!");
+ }
+ printf("\n");
+
+ printf(" channels: ");
+ RgbaChannels channels = file.channels();
+ if (channels & WRITE_R) printf("R");
+ if (channels & WRITE_G) printf("G");
+ if (channels & WRITE_B) printf("B");
+ if (channels & WRITE_A) printf("A");
+ if (channels & WRITE_Y) printf("Y");
+ if (channels & WRITE_C) printf("C");
+ printf("\n");
+
+ float *ret = new float[4 * *width * *height];
+ for (int i = 0; i < *width * *height; ++i) {
+ ret[4*i] = pixels[i].r;
+ ret[4*i+1] = pixels[i].g;
+ ret[4*i+2] = pixels[i].b;
+ ret[4*i+3] = pixels[i].a;
+ }
+ return ret;
+ } catch (const std::exception &e) {
+ return NULL;
+ }
+}
+
+int main(int argc, char *argv[]) {
+ if (argc != 2) {
+ fprintf(stderr, "usage: exrcat <file.exr>\n");
+ return 1;
+ }
+
+ int ow, oh;
+ float *orgb = OpenExrLoad(argv[1], &ow, &oh);
+
+ //SaveAsPFM("out.pfm", ow, oh, orgb);
+
+ int tw, th;
+ float *trgb;
+ const char *err;
+ if (LoadEXR(&trgb, &tw, &th, argv[1], &err) != 0) {
+ fprintf(stderr, "exrcat: %s %s\n", argv[1], err);
+ return 1;
+ }
+
+ assert(ow == tw && oh == th);
+ int o = 0;
+ for (int y = 0; y < th; ++y) {
+ for (int x = 0; x < tw; ++x, ++o) {
+ printf("(%d, %d): %f %f %f %f - %f %f %f %f\n", x, y,
+ orgb[4*o], orgb[4*o+1], orgb[4*o+2], orgb[4*o+3],
+ trgb[4*o], trgb[4*o+1], trgb[4*o+2], trgb[4*o+3]);
+ }
+ }
+
+ return 0;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/exrwrite/exrwritetest.cpp b/graphics/asymptote/cudareflect/tinyexr/test/exrwrite/exrwritetest.cpp
new file mode 100644
index 0000000000..fdcfce6e8e
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/exrwrite/exrwritetest.cpp
@@ -0,0 +1,132 @@
+// https://gist.github.com/mmp/21ea8ac6d7f682b6252b
+
+#include "tinyexr/tinyexr.h"
+#include "tinyexr/tinyexr.cc"
+#include <stdio.h>
+#include <assert.h>
+#include <vector>
+#include <algorithm>
+#include <ImfInputFile.h>
+#include <ImfRgbaFile.h>
+#include <ImfChannelList.h>
+#include <ImfFrameBuffer.h>
+#include <half.h>
+using namespace Imf;
+using namespace Imath;
+
+static float *OpenExrLoad(const char *name, int *width, int *height) {
+ try {
+ RgbaInputFile file (name);
+ Box2i dw = file.dataWindow();
+ *width = dw.max.x - dw.min.x + 1;
+ *height = dw.max.y - dw.min.y + 1;
+ std::vector<Rgba> pixels(*width * *height);
+ file.setFrameBuffer(&pixels[0] - dw.min.x - dw.min.y * *width, 1, *width);
+ file.readPixels(dw.min.y, dw.max.y);
+
+ printf("OpenExr\n datawindow: (%d %d) - (%d %d)\n", dw.min.x, dw.min.y,
+ dw.max.x, dw.max.y);
+ printf(" line order %s\n", (file.lineOrder() == INCREASING_Y) ?
+ "increasing y" : ((file.lineOrder() == DECREASING_Y) ? "decreasing y"
+ : "random y"));
+ printf(" compression: ");
+ switch (file.compression()) {
+ case NO_COMPRESSION: printf("none"); break;
+ case RLE_COMPRESSION: printf("RLE"); break;
+ case ZIPS_COMPRESSION: printf("zip"); break;
+ case ZIP_COMPRESSION: printf("zips"); break;
+ case PIZ_COMPRESSION: printf("piz"); break;
+ case PXR24_COMPRESSION: printf("pxr24"); break;
+ case B44_COMPRESSION: printf("b44"); break;
+ case B44A_COMPRESSION: printf("b44a"); break;
+ default: printf("unknown!");
+ }
+ printf("\n");
+
+ printf(" channels: ");
+ RgbaChannels channels = file.channels();
+ if (channels & WRITE_R) printf("R");
+ if (channels & WRITE_G) printf("G");
+ if (channels & WRITE_B) printf("B");
+ if (channels & WRITE_A) printf("A");
+ if (channels & WRITE_Y) printf("Y");
+ if (channels & WRITE_C) printf("C");
+ printf("\n");
+
+ float *ret = new float[4 * *width * *height];
+ for (int i = 0; i < *width * *height; ++i) {
+ ret[4*i] = pixels[i].r;
+ ret[4*i+1] = pixels[i].g;
+ ret[4*i+2] = pixels[i].b;
+ ret[4*i+3] = pixels[i].a;
+ }
+ return ret;
+ } catch (const std::exception &e) {
+ return NULL;
+ }
+}
+
+static void WriteImageEXR(const char *name, float *rgba,
+ int xRes, int yRes) {
+ Rgba *hrgba = new Rgba[xRes * yRes];
+ for (int i = 0; i < xRes * yRes; ++i)
+ hrgba[i] = Rgba(rgba[4*i], rgba[4*i+1], rgba[4*i+2], rgba[4*i+3]);
+
+ Box2i displayWindow(V2i(0,0), V2i(xRes-1, yRes-1));
+ Box2i dataWindow(V2i(0, 0), V2i(xRes - 1, yRes - 1));
+
+ try {
+ RgbaOutputFile file(name, displayWindow, dataWindow, WRITE_RGBA);
+ file.setFrameBuffer(hrgba, 1, xRes);
+ file.writePixels(yRes);
+ }
+ catch (const std::exception &e) {
+ fprintf(stderr, "Unable to write image file \"%s\": %s", name,
+ e.what());
+ }
+
+ delete[] hrgba;
+}
+
+
+int main(int argc, char *argv[]) {
+ if (argc != 3) {
+ fprintf(stderr, "usage: exrwritetest <tinyexr-filename.exr> <openexr-filename.exr>\n");
+ return 1;
+ }
+
+ int w = 1;
+ int h = 2;
+ float *rgba = new float[4 * w * h];
+ for (int i = 0; i < 4 * w * h; ++i) {
+ rgba[i] = drand48();
+ }
+
+ WriteImageEXR(argv[2], rgba, w, h);
+ const char *err;
+ SaveEXR(rgba, w, h, argv[1], /* fp16 */1, &err);
+
+ int ow, oh;
+ float *orgba = OpenExrLoad(argv[2], &ow, &oh);
+
+ int tw, th;
+ float *trgba;
+ if (LoadEXR(&trgba, &tw, &th, argv[1], &err) != 0) {
+ fprintf(stderr, "exrwritetest: %s %s\n", argv[2], err);
+ return 1;
+ }
+
+ int offset = 0;
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x)
+ for (int c = 0; c < 4; ++c, ++offset)
+ if (orgba[offset] != trgba[offset])
+ fprintf(stderr, "Mismatch at (%d,%d), component %d: "
+ "orig %g, OpenEXR %g (err %g), tinyexr %g (err %g)\n",
+ x, y, c, rgba[offset],
+ orgba[offset], fabsf(rgba[offset] - orgba[offset]),
+ trgba[offset], fabsf(rgba[offset] - trgba[offset]));
+ }
+
+ return 0;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/Makefile b/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/Makefile
new file mode 100644
index 0000000000..e17a9517f6
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/Makefile
@@ -0,0 +1,13 @@
+ISSUE_63_FLAGS=-O1 -g -fsanitize=address,bool,float-cast-overflow,integer-divide-by-zero,return,returns-nonnull-attribute,shift-exponent,signed-integer-overflow,unreachable,vla-bound -fno-sanitize-recover=all -funsigned-char
+
+all: miniz
+ clang++ -std=c++11 -o fuzz_62 -I../../ -I../../deps/miniz -g -fsanitize=address fuzz.cc /usr/lib/llvm-5.0/lib/libFuzzer.a libminiz.a
+ clang++ -std=c++11 -o fuzz_63 -I../../ -I../../deps/miniz ${ISSUE_63_FLAGS} fuzz.cc /usr/lib/llvm-5.0/lib/libFuzzer.a libminiz.a
+
+miniz:
+ clang -c -I../../deps/miniz -g ../../deps/miniz/miniz.c
+ llvm-ar rc libminiz.a miniz.o
+
+t:
+ ./fuzz_62 issue-62-tinyexr_memcpy_heap-buffer-overflow
+ ./fuzz_63 issue-63-tinyexr_signed-integer-overflow
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/README.md b/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/README.md
new file mode 100644
index 0000000000..616b62e2cb
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/README.md
@@ -0,0 +1,16 @@
+# Test with libFuzzer
+
+## Requirements
+
+Ubuntu 16.04 + apt installed clang 5.0 libFuzzer.
+
+## Compile and run
+
+```
+$ make
+$ make t
+```
+
+## TODO
+
+* Move to use Catch unit test framework
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/fuzz.cc b/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/fuzz.cc
new file mode 100644
index 0000000000..6de8637e34
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/fuzz.cc
@@ -0,0 +1,29 @@
+#include <stdint.h>
+#include <stddef.h>
+#define TINYEXR_IMPLEMENTATION
+#include "tinyexr.h"
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ EXRVersion exr_version;
+ EXRImage exr_image;
+ EXRHeader exr_header;
+ int ret = ParseEXRVersionFromMemory(&exr_version, data, size);
+ if (ret != TINYEXR_SUCCESS) {
+ return 0;
+ }
+ InitEXRHeader(&exr_header);
+ ret = ParseEXRHeaderFromMemory(&exr_header, &exr_version, data, size, NULL);
+ if (ret != TINYEXR_SUCCESS) {
+ FreeEXRHeader(&exr_header);
+ return 0;
+ }
+ InitEXRImage(&exr_image);
+ ret = LoadEXRImageFromMemory(&exr_image, &exr_header, data, size, NULL);
+ if (ret != TINYEXR_SUCCESS) {
+ FreeEXRHeader(&exr_header);
+ FreeEXRImage(&exr_image);
+ return 0;
+ }
+ FreeEXRHeader(&exr_header);
+ FreeEXRImage(&exr_image);
+ return 0;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-62-tinyexr_memcpy_heap-buffer-overflow b/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-62-tinyexr_memcpy_heap-buffer-overflow
new file mode 100644
index 0000000000..c9c65b9df4
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-62-tinyexr_memcpy_heap-buffer-overflow
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-63-tinyexr_signed-integer-overflow b/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-63-tinyexr_signed-integer-overflow
new file mode 100644
index 0000000000..2169c501b2
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-63-tinyexr_signed-integer-overflow
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-77-heap-buffer-overflow b/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-77-heap-buffer-overflow
new file mode 100644
index 0000000000..fc326baf43
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/fuzzer/issue-77-heap-buffer-overflow
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/issues/160/README.md b/graphics/asymptote/cudareflect/tinyexr/test/issues/160/README.md
new file mode 100644
index 0000000000..9077773e8d
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/issues/160/README.md
@@ -0,0 +1 @@
+Reproducible script for issue #160(PIZ huffman decode issue)
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/issues/160/main.py b/graphics/asymptote/cudareflect/tinyexr/test/issues/160/main.py
new file mode 100644
index 0000000000..5fd77c5e17
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/issues/160/main.py
@@ -0,0 +1,57 @@
+import OpenEXR
+import Imath
+import numpy as np
+import simpleimageio as sio
+
+width = 420
+height = 32
+border_left = 0
+border_right = 420 - 80
+num_splats = 10000
+
+red = np.zeros((height, width), dtype=np.float32)
+green = np.zeros((height, width), dtype=np.float32)
+blue = np.zeros((height, width), dtype=np.float32)
+
+# splat random color values
+rng = np.random.default_rng()
+row = rng.integers(low=0, high=height, size=num_splats)
+col = rng.integers(low=border_left, high=border_right, size=num_splats)
+
+# if any of the three channels has a fixed value, the problem goes away!
+red[row, col] = rng.random(num_splats)
+green[row, col] = rng.random(num_splats)
+blue[row, col] = rng.random(num_splats)
+
+# add a bunch of test pixels
+red[-8, -10] = 1
+green[-8, -10] = 1
+blue[-8, -10] = 1
+
+red[-4, -8] = 1
+green[-4, -8] = 1
+blue[-4, -8] = 1
+
+red[-4, -2] = 1
+green[-4, -2] = 1
+blue[-4, -2] = 1
+
+red[-2, -3] = 0 # setting this to anything other than 0 fixes the problem
+green[-2, -3] = 1
+blue[-2, -3] = 1
+
+# fill in all of the black region with 0-red color
+# red[:,border_right:] = 0
+# green[:,border_right:] = 1
+# blue[:,border_right:] = 1
+
+# write PIZ compressed via OpenEXR
+header = OpenEXR.Header(width, height)
+header['compression'] = Imath.Compression(Imath.Compression.PIZ_COMPRESSION)
+exr = OpenEXR.OutputFile("gen.exr", header)
+exr.writePixels({'R': red.tobytes(), 'G': green.tobytes(), 'B': blue.tobytes()})
+exr.close()
+
+# read back in via tinyexr (used internally by simpleimageio)
+tinyresult = sio.read("gen.exr")
+sio.write("test2.exr", tinyresult)
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/issues/160/requirements.txt b/graphics/asymptote/cudareflect/tinyexr/test/issues/160/requirements.txt
new file mode 100644
index 0000000000..cb3f878071
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/issues/160/requirements.txt
@@ -0,0 +1,3 @@
+OpenEXR
+numpy
+simpleimageio
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/Makefile b/graphics/asymptote/cudareflect/tinyexr/test/unit/Makefile
new file mode 100644
index 0000000000..0757dda879
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/Makefile
@@ -0,0 +1,21 @@
+.PHONY: clean
+
+CC = clang
+CXX = clang++
+CXXFLAGS = -fsanitize=address,undefined -g -O2 -std=c++11 -I ../../deps/miniz
+CFLAGS = -fsanitize=address,undefined -g -O2 -I ../../deps/miniz
+
+all: tester
+
+miniz.o:
+ $(CC) -c $(CFLAGS) ../../deps/miniz/miniz.c
+
+tester: tester.cc ../../tinyexr.h miniz.o
+ $(CXX) $(CXXFLAGS) -o tester tester.cc miniz.o
+
+check: tester
+ ./tester
+
+clean:
+ rm -rf tester miniz.o
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/README.md b/graphics/asymptote/cudareflect/tinyexr/test/unit/README.md
new file mode 100644
index 0000000000..8e3327275e
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/README.md
@@ -0,0 +1,30 @@
+# Build&Test
+
+## Prepare
+
+Clone `https://github.com/openexr/openexr-images` to `../../../` directory.
+(Or edit path to openexr-images in `tester.cc`)
+
+## Use makefile
+
+ $ make check
+
+## Use ninja + kuroga
+
+Assume
+
+* ninja 1.4+
+* python 2.6+
+
+Are installed.
+
+### Linux/MacOSX
+
+ $ python kuroga.py config-posix.py
+ $ ninja
+
+### Windows
+
+ > python kuroga.py config-msvc.py
+ > vcbuild.bat
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/catch.hpp b/graphics/asymptote/cudareflect/tinyexr/test/unit/catch.hpp
new file mode 100644
index 0000000000..2a7146a7f9
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/catch.hpp
@@ -0,0 +1,10445 @@
+/*
+ * Catch v1.4.0
+ * Generated: 2016-03-15 07:23:12.623111
+ * ----------------------------------------------------------
+ * This file has been merged from multiple headers. Please don't edit it directly
+ * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
+#define TWOBLUECUBES_CATCH_HPP_INCLUDED
+
+#ifdef __clang__
+# pragma clang system_header
+#elif defined __GNUC__
+# pragma GCC system_header
+#endif
+
+// #included from: internal/catch_suppress_warnings.h
+
+#ifdef __clang__
+# ifdef __ICC // icpc defines the __clang__ macro
+# pragma warning(push)
+# pragma warning(disable: 161 1682)
+# else // __ICC
+# pragma clang diagnostic ignored "-Wglobal-constructors"
+# pragma clang diagnostic ignored "-Wvariadic-macros"
+# pragma clang diagnostic ignored "-Wc99-extensions"
+# pragma clang diagnostic ignored "-Wunused-variable"
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wpadded"
+# pragma clang diagnostic ignored "-Wc++98-compat"
+# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+# pragma clang diagnostic ignored "-Wswitch-enum"
+# pragma clang diagnostic ignored "-Wcovered-switch-default"
+# endif
+#elif defined __GNUC__
+# pragma GCC diagnostic ignored "-Wvariadic-macros"
+# pragma GCC diagnostic ignored "-Wunused-variable"
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wpadded"
+#endif
+#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
+# define CATCH_IMPL
+#endif
+
+#ifdef CATCH_IMPL
+# ifndef CLARA_CONFIG_MAIN
+# define CLARA_CONFIG_MAIN_NOT_DEFINED
+# define CLARA_CONFIG_MAIN
+# endif
+#endif
+
+// #included from: internal/catch_notimplemented_exception.h
+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
+
+// #included from: catch_common.h
+#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
+
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
+#ifdef CATCH_CONFIG_COUNTER
+# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
+#else
+# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
+#endif
+
+#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
+#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
+
+#include <sstream>
+#include <stdexcept>
+#include <algorithm>
+
+// #included from: catch_compiler_capabilities.h
+#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
+
+// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
+// The following features are defined:
+//
+// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
+// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
+// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
+// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
+// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
+// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
+// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
+// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
+
+// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
+
+// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
+// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
+// ****************
+// Note to maintainers: if new toggles are added please document them
+// in configuration.md, too
+// ****************
+
+// In general each macro has a _NO_<feature name> form
+// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
+// Many features, at point of detection, define an _INTERNAL_ macro, so they
+// can be combined, en-mass, with the _NO_ forms later.
+
+// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
+
+#if defined(__cplusplus) && __cplusplus >= 201103L
+# define CATCH_CPP11_OR_GREATER
+#endif
+
+#ifdef __clang__
+
+# if __has_feature(cxx_nullptr)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# endif
+
+# if __has_feature(cxx_noexcept)
+# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# endif
+
+# if defined(CATCH_CPP11_OR_GREATER)
+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
+# endif
+
+#endif // __clang__
+
+////////////////////////////////////////////////////////////////////////////////
+// Borland
+#ifdef __BORLANDC__
+
+#endif // __BORLANDC__
+
+////////////////////////////////////////////////////////////////////////////////
+// EDG
+#ifdef __EDG_VERSION__
+
+#endif // __EDG_VERSION__
+
+////////////////////////////////////////////////////////////////////////////////
+// Digital Mars
+#ifdef __DMC__
+
+#endif // __DMC__
+
+////////////////////////////////////////////////////////////////////////////////
+// GCC
+#ifdef __GNUC__
+
+# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# endif
+
+# if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER)
+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" )
+# endif
+
+// - otherwise more recent versions define __cplusplus >= 201103L
+// and will get picked up below
+
+#endif // __GNUC__
+
+////////////////////////////////////////////////////////////////////////////////
+// Visual C++
+#ifdef _MSC_VER
+
+#if (_MSC_VER >= 1600)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
+#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#endif
+
+#endif // _MSC_VER
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Use variadic macros if the compiler supports them
+#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
+ ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
+ ( defined __GNUC__ && __GNUC__ >= 3 ) || \
+ ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
+
+#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+
+#endif
+
+// Use __COUNTER__ if the compiler supports it
+#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
+ ( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \
+ ( defined __clang__ && __clang_major__ >= 3 )
+
+#define CATCH_INTERNAL_CONFIG_COUNTER
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// C++ language feature support
+
+// catch all support for C++11
+#if defined(CATCH_CPP11_OR_GREATER)
+
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
+# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
+# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+# endif
+
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
+# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
+# endif
+
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
+# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
+# endif
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
+# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+# endif
+
+#endif // __cplusplus >= 201103L
+
+// Now set the actual defines based on the above + anything the user has configured
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_NULLPTR
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_NOEXCEPT
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_GENERATED_METHODS
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_IS_ENUM
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_TUPLE
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
+# define CATCH_CONFIG_VARIADIC_MACROS
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_LONG_LONG
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_OVERRIDE
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_UNIQUE_PTR
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
+# define CATCH_CONFIG_COUNTER
+#endif
+
+#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
+#endif
+
+// noexcept support:
+#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
+# define CATCH_NOEXCEPT noexcept
+# define CATCH_NOEXCEPT_IS(x) noexcept(x)
+#else
+# define CATCH_NOEXCEPT throw()
+# define CATCH_NOEXCEPT_IS(x)
+#endif
+
+// nullptr support
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+# define CATCH_NULL nullptr
+#else
+# define CATCH_NULL NULL
+#endif
+
+// override support
+#ifdef CATCH_CONFIG_CPP11_OVERRIDE
+# define CATCH_OVERRIDE override
+#else
+# define CATCH_OVERRIDE
+#endif
+
+// unique_ptr support
+#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
+# define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
+#else
+# define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
+#endif
+
+namespace Catch {
+
+ struct IConfig;
+
+ struct CaseSensitive { enum Choice {
+ Yes,
+ No
+ }; };
+
+ class NonCopyable {
+#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ NonCopyable( NonCopyable const& ) = delete;
+ NonCopyable( NonCopyable && ) = delete;
+ NonCopyable& operator = ( NonCopyable const& ) = delete;
+ NonCopyable& operator = ( NonCopyable && ) = delete;
+#else
+ NonCopyable( NonCopyable const& info );
+ NonCopyable& operator = ( NonCopyable const& );
+#endif
+
+ protected:
+ NonCopyable() {}
+ virtual ~NonCopyable();
+ };
+
+ class SafeBool {
+ public:
+ typedef void (SafeBool::*type)() const;
+
+ static type makeSafe( bool value ) {
+ return value ? &SafeBool::trueValue : 0;
+ }
+ private:
+ void trueValue() const {}
+ };
+
+ template<typename ContainerT>
+ inline void deleteAll( ContainerT& container ) {
+ typename ContainerT::const_iterator it = container.begin();
+ typename ContainerT::const_iterator itEnd = container.end();
+ for(; it != itEnd; ++it )
+ delete *it;
+ }
+ template<typename AssociativeContainerT>
+ inline void deleteAllValues( AssociativeContainerT& container ) {
+ typename AssociativeContainerT::const_iterator it = container.begin();
+ typename AssociativeContainerT::const_iterator itEnd = container.end();
+ for(; it != itEnd; ++it )
+ delete it->second;
+ }
+
+ bool startsWith( std::string const& s, std::string const& prefix );
+ bool endsWith( std::string const& s, std::string const& suffix );
+ bool contains( std::string const& s, std::string const& infix );
+ void toLowerInPlace( std::string& s );
+ std::string toLower( std::string const& s );
+ std::string trim( std::string const& str );
+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
+
+ struct pluralise {
+ pluralise( std::size_t count, std::string const& label );
+
+ friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
+
+ std::size_t m_count;
+ std::string m_label;
+ };
+
+ struct SourceLineInfo {
+
+ SourceLineInfo();
+ SourceLineInfo( char const* _file, std::size_t _line );
+ SourceLineInfo( SourceLineInfo const& other );
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ SourceLineInfo( SourceLineInfo && ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo && ) = default;
+# endif
+ bool empty() const;
+ bool operator == ( SourceLineInfo const& other ) const;
+ bool operator < ( SourceLineInfo const& other ) const;
+
+ std::string file;
+ std::size_t line;
+ };
+
+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
+
+ // This is just here to avoid compiler warnings with macro constants and boolean literals
+ inline bool isTrue( bool value ){ return value; }
+ inline bool alwaysTrue() { return true; }
+ inline bool alwaysFalse() { return false; }
+
+ void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
+
+ void seedRng( IConfig const& config );
+ unsigned int rngSeed();
+
+ // Use this in variadic streaming macros to allow
+ // >> +StreamEndStop
+ // as well as
+ // >> stuff +StreamEndStop
+ struct StreamEndStop {
+ std::string operator+() {
+ return std::string();
+ }
+ };
+ template<typename T>
+ T const& operator + ( T const& value, StreamEndStop ) {
+ return value;
+ }
+}
+
+#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
+#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
+
+#include <ostream>
+
+namespace Catch {
+
+ class NotImplementedException : public std::exception
+ {
+ public:
+ NotImplementedException( SourceLineInfo const& lineInfo );
+ NotImplementedException( NotImplementedException const& ) {}
+
+ virtual ~NotImplementedException() CATCH_NOEXCEPT {}
+
+ virtual const char* what() const CATCH_NOEXCEPT;
+
+ private:
+ std::string m_what;
+ SourceLineInfo m_lineInfo;
+ };
+
+} // end namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
+
+// #included from: internal/catch_context.h
+#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
+
+// #included from: catch_interfaces_generators.h
+#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct IGeneratorInfo {
+ virtual ~IGeneratorInfo();
+ virtual bool moveNext() = 0;
+ virtual std::size_t getCurrentIndex() const = 0;
+ };
+
+ struct IGeneratorsForTest {
+ virtual ~IGeneratorsForTest();
+
+ virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
+ virtual bool moveNext() = 0;
+ };
+
+ IGeneratorsForTest* createGeneratorsForTest();
+
+} // end namespace Catch
+
+// #included from: catch_ptr.hpp
+#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+ // An intrusive reference counting smart pointer.
+ // T must implement addRef() and release() methods
+ // typically implementing the IShared interface
+ template<typename T>
+ class Ptr {
+ public:
+ Ptr() : m_p( CATCH_NULL ){}
+ Ptr( T* p ) : m_p( p ){
+ if( m_p )
+ m_p->addRef();
+ }
+ Ptr( Ptr const& other ) : m_p( other.m_p ){
+ if( m_p )
+ m_p->addRef();
+ }
+ ~Ptr(){
+ if( m_p )
+ m_p->release();
+ }
+ void reset() {
+ if( m_p )
+ m_p->release();
+ m_p = CATCH_NULL;
+ }
+ Ptr& operator = ( T* p ){
+ Ptr temp( p );
+ swap( temp );
+ return *this;
+ }
+ Ptr& operator = ( Ptr const& other ){
+ Ptr temp( other );
+ swap( temp );
+ return *this;
+ }
+ void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
+ T* get() const{ return m_p; }
+ T& operator*() const { return *m_p; }
+ T* operator->() const { return m_p; }
+ bool operator !() const { return m_p == CATCH_NULL; }
+ operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }
+
+ private:
+ T* m_p;
+ };
+
+ struct IShared : NonCopyable {
+ virtual ~IShared();
+ virtual void addRef() const = 0;
+ virtual void release() const = 0;
+ };
+
+ template<typename T = IShared>
+ struct SharedImpl : T {
+
+ SharedImpl() : m_rc( 0 ){}
+
+ virtual void addRef() const {
+ ++m_rc;
+ }
+ virtual void release() const {
+ if( --m_rc == 0 )
+ delete this;
+ }
+
+ mutable unsigned int m_rc;
+ };
+
+} // end namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include <memory>
+#include <vector>
+#include <stdlib.h>
+
+namespace Catch {
+
+ class TestCase;
+ class Stream;
+ struct IResultCapture;
+ struct IRunner;
+ struct IGeneratorsForTest;
+ struct IConfig;
+
+ struct IContext
+ {
+ virtual ~IContext();
+
+ virtual IResultCapture* getResultCapture() = 0;
+ virtual IRunner* getRunner() = 0;
+ virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
+ virtual bool advanceGeneratorsForCurrentTest() = 0;
+ virtual Ptr<IConfig const> getConfig() const = 0;
+ };
+
+ struct IMutableContext : IContext
+ {
+ virtual ~IMutableContext();
+ virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
+ virtual void setRunner( IRunner* runner ) = 0;
+ virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
+ };
+
+ IContext& getCurrentContext();
+ IMutableContext& getCurrentMutableContext();
+ void cleanUpContext();
+ Stream createStream( std::string const& streamName );
+
+}
+
+// #included from: internal/catch_test_registry.hpp
+#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
+
+// #included from: catch_interfaces_testcase.h
+#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
+
+#include <vector>
+
+namespace Catch {
+
+ class TestSpec;
+
+ struct ITestCase : IShared {
+ virtual void invoke () const = 0;
+ protected:
+ virtual ~ITestCase();
+ };
+
+ class TestCase;
+ struct IConfig;
+
+ struct ITestCaseRegistry {
+ virtual ~ITestCaseRegistry();
+ virtual std::vector<TestCase> const& getAllTests() const = 0;
+ virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
+ };
+
+ bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
+ std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
+ std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
+
+}
+
+namespace Catch {
+
+template<typename C>
+class MethodTestCase : public SharedImpl<ITestCase> {
+
+public:
+ MethodTestCase( void (C::*method)() ) : m_method( method ) {}
+
+ virtual void invoke() const {
+ C obj;
+ (obj.*m_method)();
+ }
+
+private:
+ virtual ~MethodTestCase() {}
+
+ void (C::*m_method)();
+};
+
+typedef void(*TestFunction)();
+
+struct NameAndDesc {
+ NameAndDesc( const char* _name = "", const char* _description= "" )
+ : name( _name ), description( _description )
+ {}
+
+ const char* name;
+ const char* description;
+};
+
+void registerTestCase
+ ( ITestCase* testCase,
+ char const* className,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo );
+
+struct AutoReg {
+
+ AutoReg
+ ( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc );
+
+ template<typename C>
+ AutoReg
+ ( void (C::*method)(),
+ char const* className,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo ) {
+
+ registerTestCase
+ ( new MethodTestCase<C>( method ),
+ className,
+ nameAndDesc,
+ lineInfo );
+ }
+
+ ~AutoReg();
+
+private:
+ AutoReg( AutoReg const& );
+ void operator= ( AutoReg const& );
+};
+
+void registerTestCaseFunction
+ ( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc );
+
+} // end namespace Catch
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
+ static void TestName(); \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
+ static void TestName()
+ #define INTERNAL_CATCH_TESTCASE( ... ) \
+ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
+ namespace{ \
+ struct TestName : ClassName{ \
+ void test(); \
+ }; \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
+ } \
+ void TestName::test()
+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
+ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
+ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
+
+#else
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
+ static void TestName(); \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
+ static void TestName()
+ #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
+ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
+ namespace{ \
+ struct TestCaseName : ClassName{ \
+ void test(); \
+ }; \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
+ } \
+ void TestCaseName::test()
+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
+ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
+ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
+#endif
+
+// #included from: internal/catch_capture.hpp
+#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
+
+// #included from: catch_result_builder.h
+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
+
+// #included from: catch_result_type.h
+#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
+
+namespace Catch {
+
+ // ResultWas::OfType enum
+ struct ResultWas { enum OfType {
+ Unknown = -1,
+ Ok = 0,
+ Info = 1,
+ Warning = 2,
+
+ FailureBit = 0x10,
+
+ ExpressionFailed = FailureBit | 1,
+ ExplicitFailure = FailureBit | 2,
+
+ Exception = 0x100 | FailureBit,
+
+ ThrewException = Exception | 1,
+ DidntThrowException = Exception | 2,
+
+ FatalErrorCondition = 0x200 | FailureBit
+
+ }; };
+
+ inline bool isOk( ResultWas::OfType resultType ) {
+ return ( resultType & ResultWas::FailureBit ) == 0;
+ }
+ inline bool isJustInfo( int flags ) {
+ return flags == ResultWas::Info;
+ }
+
+ // ResultDisposition::Flags enum
+ struct ResultDisposition { enum Flags {
+ Normal = 0x01,
+
+ ContinueOnFailure = 0x02, // Failures fail test, but execution continues
+ FalseTest = 0x04, // Prefix expression with !
+ SuppressFail = 0x08 // Failures are reported but do not fail the test
+ }; };
+
+ inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
+ return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
+ }
+
+ inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
+ inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
+ inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
+
+} // end namespace Catch
+
+// #included from: catch_assertionresult.h
+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct AssertionInfo
+ {
+ AssertionInfo() {}
+ AssertionInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ std::string const& _capturedExpression,
+ ResultDisposition::Flags _resultDisposition );
+
+ std::string macroName;
+ SourceLineInfo lineInfo;
+ std::string capturedExpression;
+ ResultDisposition::Flags resultDisposition;
+ };
+
+ struct AssertionResultData
+ {
+ AssertionResultData() : resultType( ResultWas::Unknown ) {}
+
+ std::string reconstructedExpression;
+ std::string message;
+ ResultWas::OfType resultType;
+ };
+
+ class AssertionResult {
+ public:
+ AssertionResult();
+ AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
+ ~AssertionResult();
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ AssertionResult( AssertionResult const& ) = default;
+ AssertionResult( AssertionResult && ) = default;
+ AssertionResult& operator = ( AssertionResult const& ) = default;
+ AssertionResult& operator = ( AssertionResult && ) = default;
+# endif
+
+ bool isOk() const;
+ bool succeeded() const;
+ ResultWas::OfType getResultType() const;
+ bool hasExpression() const;
+ bool hasMessage() const;
+ std::string getExpression() const;
+ std::string getExpressionInMacro() const;
+ bool hasExpandedExpression() const;
+ std::string getExpandedExpression() const;
+ std::string getMessage() const;
+ SourceLineInfo getSourceInfo() const;
+ std::string getTestMacroName() const;
+
+ protected:
+ AssertionInfo m_info;
+ AssertionResultData m_resultData;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_matchers.hpp
+#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
+
+namespace Catch {
+namespace Matchers {
+ namespace Impl {
+
+ namespace Generic {
+ template<typename ExpressionT> class AllOf;
+ template<typename ExpressionT> class AnyOf;
+ template<typename ExpressionT> class Not;
+ }
+
+ template<typename ExpressionT>
+ struct Matcher : SharedImpl<IShared>
+ {
+ typedef ExpressionT ExpressionType;
+
+ virtual ~Matcher() {}
+ virtual Ptr<Matcher> clone() const = 0;
+ virtual bool match( ExpressionT const& expr ) const = 0;
+ virtual std::string toString() const = 0;
+
+ Generic::AllOf<ExpressionT> operator && ( Matcher<ExpressionT> const& other ) const;
+ Generic::AnyOf<ExpressionT> operator || ( Matcher<ExpressionT> const& other ) const;
+ Generic::Not<ExpressionT> operator ! () const;
+ };
+
+ template<typename DerivedT, typename ExpressionT>
+ struct MatcherImpl : Matcher<ExpressionT> {
+
+ virtual Ptr<Matcher<ExpressionT> > clone() const {
+ return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
+ }
+ };
+
+ namespace Generic {
+ template<typename ExpressionT>
+ class Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {
+ public:
+ explicit Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
+ Not( Not const& other ) : m_matcher( other.m_matcher ) {}
+
+ virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {
+ return !m_matcher->match( expr );
+ }
+
+ virtual std::string toString() const CATCH_OVERRIDE {
+ return "not " + m_matcher->toString();
+ }
+ private:
+ Ptr< Matcher<ExpressionT> > m_matcher;
+ };
+
+ template<typename ExpressionT>
+ class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
+ public:
+
+ AllOf() {}
+ AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
+
+ AllOf& add( Matcher<ExpressionT> const& matcher ) {
+ m_matchers.push_back( matcher.clone() );
+ return *this;
+ }
+ virtual bool match( ExpressionT const& expr ) const
+ {
+ for( std::size_t i = 0; i < m_matchers.size(); ++i )
+ if( !m_matchers[i]->match( expr ) )
+ return false;
+ return true;
+ }
+ virtual std::string toString() const {
+ std::ostringstream oss;
+ oss << "( ";
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if( i != 0 )
+ oss << " and ";
+ oss << m_matchers[i]->toString();
+ }
+ oss << " )";
+ return oss.str();
+ }
+
+ AllOf operator && ( Matcher<ExpressionT> const& other ) const {
+ AllOf allOfExpr( *this );
+ allOfExpr.add( other );
+ return allOfExpr;
+ }
+
+ private:
+ std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
+ };
+
+ template<typename ExpressionT>
+ class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
+ public:
+
+ AnyOf() {}
+ AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
+
+ AnyOf& add( Matcher<ExpressionT> const& matcher ) {
+ m_matchers.push_back( matcher.clone() );
+ return *this;
+ }
+ virtual bool match( ExpressionT const& expr ) const
+ {
+ for( std::size_t i = 0; i < m_matchers.size(); ++i )
+ if( m_matchers[i]->match( expr ) )
+ return true;
+ return false;
+ }
+ virtual std::string toString() const {
+ std::ostringstream oss;
+ oss << "( ";
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if( i != 0 )
+ oss << " or ";
+ oss << m_matchers[i]->toString();
+ }
+ oss << " )";
+ return oss.str();
+ }
+
+ AnyOf operator || ( Matcher<ExpressionT> const& other ) const {
+ AnyOf anyOfExpr( *this );
+ anyOfExpr.add( other );
+ return anyOfExpr;
+ }
+
+ private:
+ std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
+ };
+
+ } // namespace Generic
+
+ template<typename ExpressionT>
+ Generic::AllOf<ExpressionT> Matcher<ExpressionT>::operator && ( Matcher<ExpressionT> const& other ) const {
+ Generic::AllOf<ExpressionT> allOfExpr;
+ allOfExpr.add( *this );
+ allOfExpr.add( other );
+ return allOfExpr;
+ }
+
+ template<typename ExpressionT>
+ Generic::AnyOf<ExpressionT> Matcher<ExpressionT>::operator || ( Matcher<ExpressionT> const& other ) const {
+ Generic::AnyOf<ExpressionT> anyOfExpr;
+ anyOfExpr.add( *this );
+ anyOfExpr.add( other );
+ return anyOfExpr;
+ }
+
+ template<typename ExpressionT>
+ Generic::Not<ExpressionT> Matcher<ExpressionT>::operator ! () const {
+ return Generic::Not<ExpressionT>( *this );
+ }
+
+ namespace StdString {
+
+ inline std::string makeString( std::string const& str ) { return str; }
+ inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
+
+ struct CasedString
+ {
+ CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
+ : m_caseSensitivity( caseSensitivity ),
+ m_str( adjustString( str ) )
+ {}
+ std::string adjustString( std::string const& str ) const {
+ return m_caseSensitivity == CaseSensitive::No
+ ? toLower( str )
+ : str;
+
+ }
+ std::string toStringSuffix() const
+ {
+ return m_caseSensitivity == CaseSensitive::No
+ ? " (case insensitive)"
+ : "";
+ }
+ CaseSensitive::Choice m_caseSensitivity;
+ std::string m_str;
+ };
+
+ struct Equals : MatcherImpl<Equals, std::string> {
+ Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
+ : m_data( str, caseSensitivity )
+ {}
+ Equals( Equals const& other ) : m_data( other.m_data ){}
+
+ virtual ~Equals();
+
+ virtual bool match( std::string const& expr ) const {
+ return m_data.m_str == m_data.adjustString( expr );;
+ }
+ virtual std::string toString() const {
+ return "equals: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ }
+
+ CasedString m_data;
+ };
+
+ struct Contains : MatcherImpl<Contains, std::string> {
+ Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
+ : m_data( substr, caseSensitivity ){}
+ Contains( Contains const& other ) : m_data( other.m_data ){}
+
+ virtual ~Contains();
+
+ virtual bool match( std::string const& expr ) const {
+ return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
+ }
+ virtual std::string toString() const {
+ return "contains: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ }
+
+ CasedString m_data;
+ };
+
+ struct StartsWith : MatcherImpl<StartsWith, std::string> {
+ StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
+ : m_data( substr, caseSensitivity ){}
+
+ StartsWith( StartsWith const& other ) : m_data( other.m_data ){}
+
+ virtual ~StartsWith();
+
+ virtual bool match( std::string const& expr ) const {
+ return startsWith( m_data.adjustString( expr ), m_data.m_str );
+ }
+ virtual std::string toString() const {
+ return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ }
+
+ CasedString m_data;
+ };
+
+ struct EndsWith : MatcherImpl<EndsWith, std::string> {
+ EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
+ : m_data( substr, caseSensitivity ){}
+ EndsWith( EndsWith const& other ) : m_data( other.m_data ){}
+
+ virtual ~EndsWith();
+
+ virtual bool match( std::string const& expr ) const {
+ return endsWith( m_data.adjustString( expr ), m_data.m_str );
+ }
+ virtual std::string toString() const {
+ return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ }
+
+ CasedString m_data;
+ };
+ } // namespace StdString
+ } // namespace Impl
+
+ // The following functions create the actual matcher objects.
+ // This allows the types to be inferred
+ template<typename ExpressionT>
+ inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {
+ return Impl::Generic::Not<ExpressionT>( m );
+ }
+
+ template<typename ExpressionT>
+ inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2 ) {
+ return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2,
+ Impl::Matcher<ExpressionT> const& m3 ) {
+ return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2 ) {
+ return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2,
+ Impl::Matcher<ExpressionT> const& m3 ) {
+ return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
+ }
+
+ inline Impl::StdString::Equals Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
+ return Impl::StdString::Equals( str, caseSensitivity );
+ }
+ inline Impl::StdString::Equals Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
+ return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity );
+ }
+ inline Impl::StdString::Contains Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
+ return Impl::StdString::Contains( substr, caseSensitivity );
+ }
+ inline Impl::StdString::Contains Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
+ return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity );
+ }
+ inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
+ return Impl::StdString::StartsWith( substr );
+ }
+ inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
+ return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
+ }
+ inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
+ return Impl::StdString::EndsWith( substr );
+ }
+ inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
+ return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
+ }
+
+} // namespace Matchers
+
+using namespace Matchers;
+
+} // namespace Catch
+
+namespace Catch {
+
+ struct TestFailureException{};
+
+ template<typename T> class ExpressionLhs;
+
+ struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
+
+ struct CopyableStream {
+ CopyableStream() {}
+ CopyableStream( CopyableStream const& other ) {
+ oss << other.oss.str();
+ }
+ CopyableStream& operator=( CopyableStream const& other ) {
+ oss.str("");
+ oss << other.oss.str();
+ return *this;
+ }
+ std::ostringstream oss;
+ };
+
+ class ResultBuilder {
+ public:
+ ResultBuilder( char const* macroName,
+ SourceLineInfo const& lineInfo,
+ char const* capturedExpression,
+ ResultDisposition::Flags resultDisposition,
+ char const* secondArg = "" );
+
+ template<typename T>
+ ExpressionLhs<T const&> operator <= ( T const& operand );
+ ExpressionLhs<bool> operator <= ( bool value );
+
+ template<typename T>
+ ResultBuilder& operator << ( T const& value ) {
+ m_stream.oss << value;
+ return *this;
+ }
+
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
+
+ ResultBuilder& setResultType( ResultWas::OfType result );
+ ResultBuilder& setResultType( bool result );
+ ResultBuilder& setLhs( std::string const& lhs );
+ ResultBuilder& setRhs( std::string const& rhs );
+ ResultBuilder& setOp( std::string const& op );
+
+ void endExpression();
+
+ std::string reconstructExpression() const;
+ AssertionResult build() const;
+
+ void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
+ void captureResult( ResultWas::OfType resultType );
+ void captureExpression();
+ void captureExpectedException( std::string const& expectedMessage );
+ void captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher );
+ void handleResult( AssertionResult const& result );
+ void react();
+ bool shouldDebugBreak() const;
+ bool allowThrows() const;
+
+ private:
+ AssertionInfo m_assertionInfo;
+ AssertionResultData m_data;
+ struct ExprComponents {
+ ExprComponents() : testFalse( false ) {}
+ bool testFalse;
+ std::string lhs, rhs, op;
+ } m_exprComponents;
+ CopyableStream m_stream;
+
+ bool m_shouldDebugBreak;
+ bool m_shouldThrow;
+ };
+
+} // namespace Catch
+
+// Include after due to circular dependency:
+// #included from: catch_expression_lhs.hpp
+#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
+
+// #included from: catch_evaluate.hpp
+#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
+#endif
+
+#include <cstddef>
+
+namespace Catch {
+namespace Internal {
+
+ enum Operator {
+ IsEqualTo,
+ IsNotEqualTo,
+ IsLessThan,
+ IsGreaterThan,
+ IsLessThanOrEqualTo,
+ IsGreaterThanOrEqualTo
+ };
+
+ template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
+ template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
+ template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
+ template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
+ template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
+ template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
+ template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
+
+ template<typename T>
+ inline T& opCast(T const& t) { return const_cast<T&>(t); }
+
+// nullptr_t support based on pull request #154 from Konstantin Baumann
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+ inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
+#endif // CATCH_CONFIG_CPP11_NULLPTR
+
+ // So the compare overloads can be operator agnostic we convey the operator as a template
+ // enum, which is used to specialise an Evaluator for doing the comparison.
+ template<typename T1, typename T2, Operator Op>
+ class Evaluator{};
+
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs) {
+ return bool( opCast( lhs ) == opCast( rhs ) );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsNotEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) != opCast( rhs ) );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsLessThan> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) < opCast( rhs ) );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsGreaterThan> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) > opCast( rhs ) );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) >= opCast( rhs ) );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return bool( opCast( lhs ) <= opCast( rhs ) );
+ }
+ };
+
+ template<Operator Op, typename T1, typename T2>
+ bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
+ return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
+ }
+
+ // This level of indirection allows us to specialise for integer types
+ // to avoid signed/ unsigned warnings
+
+ // "base" overload
+ template<Operator Op, typename T1, typename T2>
+ bool compare( T1 const& lhs, T2 const& rhs ) {
+ return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
+ }
+
+ // unsigned X to int
+ template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+
+ // unsigned X to long
+ template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+
+ // int to unsigned X
+ template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+
+ // long to unsigned X
+ template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+
+ // pointer to long (when comparing against NULL)
+ template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+ }
+
+ // pointer to int (when comparing against NULL)
+ template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+ }
+
+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
+ // long long to unsigned X
+ template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+
+ // unsigned long long to X
+ template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+ }
+
+ // pointer to long long (when comparing against NULL)
+ template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+ }
+#endif // CATCH_CONFIG_CPP11_LONG_LONG
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+ // pointer to nullptr_t (when comparing against nullptr)
+ template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
+ }
+#endif // CATCH_CONFIG_CPP11_NULLPTR
+
+} // end of namespace Internal
+} // end of namespace Catch
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+// #included from: catch_tostring.h
+#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
+
+#include <sstream>
+#include <iomanip>
+#include <limits>
+#include <vector>
+#include <cstddef>
+
+#ifdef __OBJC__
+// #included from: catch_objc_arc.hpp
+#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
+
+#import <Foundation/Foundation.h>
+
+#ifdef __has_feature
+#define CATCH_ARC_ENABLED __has_feature(objc_arc)
+#else
+#define CATCH_ARC_ENABLED 0
+#endif
+
+void arcSafeRelease( NSObject* obj );
+id performOptionalSelector( id obj, SEL sel );
+
+#if !CATCH_ARC_ENABLED
+inline void arcSafeRelease( NSObject* obj ) {
+ [obj release];
+}
+inline id performOptionalSelector( id obj, SEL sel ) {
+ if( [obj respondsToSelector: sel] )
+ return [obj performSelector: sel];
+ return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED
+#define CATCH_ARC_STRONG
+#else
+inline void arcSafeRelease( NSObject* ){}
+inline id performOptionalSelector( id obj, SEL sel ) {
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
+#endif
+ if( [obj respondsToSelector: sel] )
+ return [obj performSelector: sel];
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+ return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
+#define CATCH_ARC_STRONG __strong
+#endif
+
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_TUPLE
+#include <tuple>
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_IS_ENUM
+#include <type_traits>
+#endif
+
+namespace Catch {
+
+// Why we're here.
+template<typename T>
+std::string toString( T const& value );
+
+// Built in overloads
+
+std::string toString( std::string const& value );
+std::string toString( std::wstring const& value );
+std::string toString( const char* const value );
+std::string toString( char* const value );
+std::string toString( const wchar_t* const value );
+std::string toString( wchar_t* const value );
+std::string toString( int value );
+std::string toString( unsigned long value );
+std::string toString( unsigned int value );
+std::string toString( const double value );
+std::string toString( const float value );
+std::string toString( bool value );
+std::string toString( char value );
+std::string toString( signed char value );
+std::string toString( unsigned char value );
+
+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
+std::string toString( long long value );
+std::string toString( unsigned long long value );
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+std::string toString( std::nullptr_t );
+#endif
+
+#ifdef __OBJC__
+ std::string toString( NSString const * const& nsstring );
+ std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
+ std::string toString( NSObject* const& nsObject );
+#endif
+
+namespace Detail {
+
+ extern const std::string unprintableString;
+
+ struct BorgType {
+ template<typename T> BorgType( T const& );
+ };
+
+ struct TrueType { char sizer[1]; };
+ struct FalseType { char sizer[2]; };
+
+ TrueType& testStreamable( std::ostream& );
+ FalseType testStreamable( FalseType );
+
+ FalseType operator<<( std::ostream const&, BorgType const& );
+
+ template<typename T>
+ struct IsStreamInsertable {
+ static std::ostream &s;
+ static T const&t;
+ enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
+ };
+
+#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
+ template<typename T,
+ bool IsEnum = std::is_enum<T>::value
+ >
+ struct EnumStringMaker
+ {
+ static std::string convert( T const& ) { return unprintableString; }
+ };
+
+ template<typename T>
+ struct EnumStringMaker<T,true>
+ {
+ static std::string convert( T const& v )
+ {
+ return ::Catch::toString(
+ static_cast<typename std::underlying_type<T>::type>(v)
+ );
+ }
+ };
+#endif
+ template<bool C>
+ struct StringMakerBase {
+#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
+ template<typename T>
+ static std::string convert( T const& v )
+ {
+ return EnumStringMaker<T>::convert( v );
+ }
+#else
+ template<typename T>
+ static std::string convert( T const& ) { return unprintableString; }
+#endif
+ };
+
+ template<>
+ struct StringMakerBase<true> {
+ template<typename T>
+ static std::string convert( T const& _value ) {
+ std::ostringstream oss;
+ oss << _value;
+ return oss.str();
+ }
+ };
+
+ std::string rawMemoryToString( const void *object, std::size_t size );
+
+ template<typename T>
+ inline std::string rawMemoryToString( const T& object ) {
+ return rawMemoryToString( &object, sizeof(object) );
+ }
+
+} // end namespace Detail
+
+template<typename T>
+struct StringMaker :
+ Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
+
+template<typename T>
+struct StringMaker<T*> {
+ template<typename U>
+ static std::string convert( U* p ) {
+ if( !p )
+ return "NULL";
+ else
+ return Detail::rawMemoryToString( p );
+ }
+};
+
+template<typename R, typename C>
+struct StringMaker<R C::*> {
+ static std::string convert( R C::* p ) {
+ if( !p )
+ return "NULL";
+ else
+ return Detail::rawMemoryToString( p );
+ }
+};
+
+namespace Detail {
+ template<typename InputIterator>
+ std::string rangeToString( InputIterator first, InputIterator last );
+}
+
+//template<typename T, typename Allocator>
+//struct StringMaker<std::vector<T, Allocator> > {
+// static std::string convert( std::vector<T,Allocator> const& v ) {
+// return Detail::rangeToString( v.begin(), v.end() );
+// }
+//};
+
+template<typename T, typename Allocator>
+std::string toString( std::vector<T,Allocator> const& v ) {
+ return Detail::rangeToString( v.begin(), v.end() );
+}
+
+#ifdef CATCH_CONFIG_CPP11_TUPLE
+
+// toString for tuples
+namespace TupleDetail {
+ template<
+ typename Tuple,
+ std::size_t N = 0,
+ bool = (N < std::tuple_size<Tuple>::value)
+ >
+ struct ElementPrinter {
+ static void print( const Tuple& tuple, std::ostream& os )
+ {
+ os << ( N ? ", " : " " )
+ << Catch::toString(std::get<N>(tuple));
+ ElementPrinter<Tuple,N+1>::print(tuple,os);
+ }
+ };
+
+ template<
+ typename Tuple,
+ std::size_t N
+ >
+ struct ElementPrinter<Tuple,N,false> {
+ static void print( const Tuple&, std::ostream& ) {}
+ };
+
+}
+
+template<typename ...Types>
+struct StringMaker<std::tuple<Types...>> {
+
+ static std::string convert( const std::tuple<Types...>& tuple )
+ {
+ std::ostringstream os;
+ os << '{';
+ TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
+ os << " }";
+ return os.str();
+ }
+};
+#endif // CATCH_CONFIG_CPP11_TUPLE
+
+namespace Detail {
+ template<typename T>
+ std::string makeString( T const& value ) {
+ return StringMaker<T>::convert( value );
+ }
+} // end namespace Detail
+
+/// \brief converts any type to a string
+///
+/// The default template forwards on to ostringstream - except when an
+/// ostringstream overload does not exist - in which case it attempts to detect
+/// that and writes {?}.
+/// Overload (not specialise) this template for custom typs that you don't want
+/// to provide an ostream overload for.
+template<typename T>
+std::string toString( T const& value ) {
+ return StringMaker<T>::convert( value );
+}
+
+ namespace Detail {
+ template<typename InputIterator>
+ std::string rangeToString( InputIterator first, InputIterator last ) {
+ std::ostringstream oss;
+ oss << "{ ";
+ if( first != last ) {
+ oss << Catch::toString( *first );
+ for( ++first ; first != last ; ++first )
+ oss << ", " << Catch::toString( *first );
+ }
+ oss << " }";
+ return oss.str();
+ }
+}
+
+} // end namespace Catch
+
+namespace Catch {
+
+// Wraps the LHS of an expression and captures the operator and RHS (if any) -
+// wrapping them all in a ResultBuilder object
+template<typename T>
+class ExpressionLhs {
+ ExpressionLhs& operator = ( ExpressionLhs const& );
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
+# endif
+
+public:
+ ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ ExpressionLhs( ExpressionLhs const& ) = default;
+ ExpressionLhs( ExpressionLhs && ) = default;
+# endif
+
+ template<typename RhsT>
+ ResultBuilder& operator == ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator != ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsNotEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator < ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsLessThan>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator > ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsGreaterThan>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator <= ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator >= ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
+ }
+
+ ResultBuilder& operator == ( bool rhs ) {
+ return captureExpression<Internal::IsEqualTo>( rhs );
+ }
+
+ ResultBuilder& operator != ( bool rhs ) {
+ return captureExpression<Internal::IsNotEqualTo>( rhs );
+ }
+
+ void endExpression() {
+ bool value = m_lhs ? true : false;
+ m_rb
+ .setLhs( Catch::toString( value ) )
+ .setResultType( value )
+ .endExpression();
+ }
+
+ // Only simple binary expressions are allowed on the LHS.
+ // If more complex compositions are required then place the sub expression in parentheses
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
+
+private:
+ template<Internal::Operator Op, typename RhsT>
+ ResultBuilder& captureExpression( RhsT const& rhs ) {
+ return m_rb
+ .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
+ .setLhs( Catch::toString( m_lhs ) )
+ .setRhs( Catch::toString( rhs ) )
+ .setOp( Internal::OperatorTraits<Op>::getName() );
+ }
+
+private:
+ ResultBuilder& m_rb;
+ T m_lhs;
+};
+
+} // end namespace Catch
+
+
+namespace Catch {
+
+ template<typename T>
+ inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
+ return ExpressionLhs<T const&>( *this, operand );
+ }
+
+ inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
+ return ExpressionLhs<bool>( *this, value );
+ }
+
+} // namespace Catch
+
+// #included from: catch_message.h
+#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct MessageInfo {
+ MessageInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ ResultWas::OfType _type );
+
+ std::string macroName;
+ SourceLineInfo lineInfo;
+ ResultWas::OfType type;
+ std::string message;
+ unsigned int sequence;
+
+ bool operator == ( MessageInfo const& other ) const {
+ return sequence == other.sequence;
+ }
+ bool operator < ( MessageInfo const& other ) const {
+ return sequence < other.sequence;
+ }
+ private:
+ static unsigned int globalCount;
+ };
+
+ struct MessageBuilder {
+ MessageBuilder( std::string const& macroName,
+ SourceLineInfo const& lineInfo,
+ ResultWas::OfType type )
+ : m_info( macroName, lineInfo, type )
+ {}
+
+ template<typename T>
+ MessageBuilder& operator << ( T const& value ) {
+ m_stream << value;
+ return *this;
+ }
+
+ MessageInfo m_info;
+ std::ostringstream m_stream;
+ };
+
+ class ScopedMessage {
+ public:
+ ScopedMessage( MessageBuilder const& builder );
+ ScopedMessage( ScopedMessage const& other );
+ ~ScopedMessage();
+
+ MessageInfo m_info;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_interfaces_capture.h
+#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ class TestCase;
+ class AssertionResult;
+ struct AssertionInfo;
+ struct SectionInfo;
+ struct SectionEndInfo;
+ struct MessageInfo;
+ class ScopedMessageBuilder;
+ struct Counts;
+
+ struct IResultCapture {
+
+ virtual ~IResultCapture();
+
+ virtual void assertionEnded( AssertionResult const& result ) = 0;
+ virtual bool sectionStarted( SectionInfo const& sectionInfo,
+ Counts& assertions ) = 0;
+ virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
+ virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
+ virtual void pushScopedMessage( MessageInfo const& message ) = 0;
+ virtual void popScopedMessage( MessageInfo const& message ) = 0;
+
+ virtual std::string getCurrentTestName() const = 0;
+ virtual const AssertionResult* getLastResult() const = 0;
+
+ virtual void handleFatalErrorCondition( std::string const& message ) = 0;
+ };
+
+ IResultCapture& getResultCapture();
+}
+
+// #included from: catch_debugger.h
+#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
+
+// #included from: catch_platform.h
+#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
+
+#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
+#define CATCH_PLATFORM_MAC
+#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
+#define CATCH_PLATFORM_IPHONE
+#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
+#define CATCH_PLATFORM_WINDOWS
+#endif
+
+#include <string>
+
+namespace Catch{
+
+ bool isDebuggerActive();
+ void writeToDebugConsole( std::string const& text );
+}
+
+#ifdef CATCH_PLATFORM_MAC
+
+ // The following code snippet based on:
+ // http://cocoawithlove.com/2008/03/break-into-debugger.html
+ #ifdef DEBUG
+ #if defined(__ppc64__) || defined(__ppc__)
+ #define CATCH_BREAK_INTO_DEBUGGER() \
+ if( Catch::isDebuggerActive() ) { \
+ __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
+ : : : "memory","r0","r3","r4" ); \
+ }
+ #else
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
+ #endif
+ #endif
+
+#elif defined(_MSC_VER)
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
+#elif defined(__MINGW32__)
+ extern "C" __declspec(dllimport) void __stdcall DebugBreak();
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
+#endif
+
+#ifndef CATCH_BREAK_INTO_DEBUGGER
+#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
+#endif
+
+// #included from: catch_interfaces_runner.h
+#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
+
+namespace Catch {
+ class TestCase;
+
+ struct IRunner {
+ virtual ~IRunner();
+ virtual bool aborting() const = 0;
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// In the event of a failure works out if the debugger needs to be invoked
+// and/or an exception thrown and takes appropriate action.
+// This needs to be done as a macro so the debugger will stop in the user
+// source code rather than in Catch library code
+#define INTERNAL_CATCH_REACT( resultBuilder ) \
+ if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
+ resultBuilder.react();
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ try { \
+ CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+ ( __catchResult <= expr ).endExpression(); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::isTrue( false && static_cast<bool>(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
+ INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
+ if( Catch::getResultCapture().getLastResult()->succeeded() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
+ INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
+ if( !Catch::getResultCapture().getLastResult()->succeeded() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
+ if( __catchResult.allowThrows() ) \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
+ } \
+ catch( ... ) { \
+ __catchResult.captureExpectedException( matcher ); \
+ } \
+ else \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ if( __catchResult.allowThrows() ) \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
+ } \
+ catch( exceptionType ) { \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition ); \
+ } \
+ else \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+ __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
+ __catchResult.captureResult( messageType ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+#else
+ #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+ __catchResult << log + ::Catch::StreamEndStop(); \
+ __catchResult.captureResult( messageType ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_INFO( log, macroName ) \
+ Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
+ try { \
+ std::string matcherAsString = (matcher).toString(); \
+ __catchResult \
+ .setLhs( Catch::toString( arg ) ) \
+ .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
+ .setOp( "matches" ) \
+ .setResultType( (matcher).match( arg ) ); \
+ __catchResult.captureExpression(); \
+ } catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+// #included from: internal/catch_section.h
+#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
+
+// #included from: catch_section_info.h
+#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
+
+// #included from: catch_totals.hpp
+#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
+
+#include <cstddef>
+
+namespace Catch {
+
+ struct Counts {
+ Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
+
+ Counts operator - ( Counts const& other ) const {
+ Counts diff;
+ diff.passed = passed - other.passed;
+ diff.failed = failed - other.failed;
+ diff.failedButOk = failedButOk - other.failedButOk;
+ return diff;
+ }
+ Counts& operator += ( Counts const& other ) {
+ passed += other.passed;
+ failed += other.failed;
+ failedButOk += other.failedButOk;
+ return *this;
+ }
+
+ std::size_t total() const {
+ return passed + failed + failedButOk;
+ }
+ bool allPassed() const {
+ return failed == 0 && failedButOk == 0;
+ }
+ bool allOk() const {
+ return failed == 0;
+ }
+
+ std::size_t passed;
+ std::size_t failed;
+ std::size_t failedButOk;
+ };
+
+ struct Totals {
+
+ Totals operator - ( Totals const& other ) const {
+ Totals diff;
+ diff.assertions = assertions - other.assertions;
+ diff.testCases = testCases - other.testCases;
+ return diff;
+ }
+
+ Totals delta( Totals const& prevTotals ) const {
+ Totals diff = *this - prevTotals;
+ if( diff.assertions.failed > 0 )
+ ++diff.testCases.failed;
+ else if( diff.assertions.failedButOk > 0 )
+ ++diff.testCases.failedButOk;
+ else
+ ++diff.testCases.passed;
+ return diff;
+ }
+
+ Totals& operator += ( Totals const& other ) {
+ assertions += other.assertions;
+ testCases += other.testCases;
+ return *this;
+ }
+
+ Counts assertions;
+ Counts testCases;
+ };
+}
+
+namespace Catch {
+
+ struct SectionInfo {
+ SectionInfo
+ ( SourceLineInfo const& _lineInfo,
+ std::string const& _name,
+ std::string const& _description = std::string() );
+
+ std::string name;
+ std::string description;
+ SourceLineInfo lineInfo;
+ };
+
+ struct SectionEndInfo {
+ SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
+ : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
+ {}
+
+ SectionInfo sectionInfo;
+ Counts prevAssertions;
+ double durationInSeconds;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_timer.h
+#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
+
+#ifdef CATCH_PLATFORM_WINDOWS
+typedef unsigned long long uint64_t;
+#else
+#include <stdint.h>
+#endif
+
+namespace Catch {
+
+ class Timer {
+ public:
+ Timer() : m_ticks( 0 ) {}
+ void start();
+ unsigned int getElapsedMicroseconds() const;
+ unsigned int getElapsedMilliseconds() const;
+ double getElapsedSeconds() const;
+
+ private:
+ uint64_t m_ticks;
+ };
+
+} // namespace Catch
+
+#include <string>
+
+namespace Catch {
+
+ class Section : NonCopyable {
+ public:
+ Section( SectionInfo const& info );
+ ~Section();
+
+ // This indicates whether the section should be executed or not
+ operator bool() const;
+
+ private:
+ SectionInfo m_info;
+
+ std::string m_name;
+ Counts m_assertions;
+ bool m_sectionIncluded;
+ Timer m_timer;
+ };
+
+} // end namespace Catch
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define INTERNAL_CATCH_SECTION( ... ) \
+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
+#else
+ #define INTERNAL_CATCH_SECTION( name, desc ) \
+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
+#endif
+
+// #included from: internal/catch_generators.hpp
+#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
+
+#include <iterator>
+#include <vector>
+#include <string>
+#include <stdlib.h>
+
+namespace Catch {
+
+template<typename T>
+struct IGenerator {
+ virtual ~IGenerator() {}
+ virtual T getValue( std::size_t index ) const = 0;
+ virtual std::size_t size () const = 0;
+};
+
+template<typename T>
+class BetweenGenerator : public IGenerator<T> {
+public:
+ BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
+
+ virtual T getValue( std::size_t index ) const {
+ return m_from+static_cast<int>( index );
+ }
+
+ virtual std::size_t size() const {
+ return static_cast<std::size_t>( 1+m_to-m_from );
+ }
+
+private:
+
+ T m_from;
+ T m_to;
+};
+
+template<typename T>
+class ValuesGenerator : public IGenerator<T> {
+public:
+ ValuesGenerator(){}
+
+ void add( T value ) {
+ m_values.push_back( value );
+ }
+
+ virtual T getValue( std::size_t index ) const {
+ return m_values[index];
+ }
+
+ virtual std::size_t size() const {
+ return m_values.size();
+ }
+
+private:
+ std::vector<T> m_values;
+};
+
+template<typename T>
+class CompositeGenerator {
+public:
+ CompositeGenerator() : m_totalSize( 0 ) {}
+
+ // *** Move semantics, similar to auto_ptr ***
+ CompositeGenerator( CompositeGenerator& other )
+ : m_fileInfo( other.m_fileInfo ),
+ m_totalSize( 0 )
+ {
+ move( other );
+ }
+
+ CompositeGenerator& setFileInfo( const char* fileInfo ) {
+ m_fileInfo = fileInfo;
+ return *this;
+ }
+
+ ~CompositeGenerator() {
+ deleteAll( m_composed );
+ }
+
+ operator T () const {
+ size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
+
+ typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
+ typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
+ for( size_t index = 0; it != itEnd; ++it )
+ {
+ const IGenerator<T>* generator = *it;
+ if( overallIndex >= index && overallIndex < index + generator->size() )
+ {
+ return generator->getValue( overallIndex-index );
+ }
+ index += generator->size();
+ }
+ CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
+ return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
+ }
+
+ void add( const IGenerator<T>* generator ) {
+ m_totalSize += generator->size();
+ m_composed.push_back( generator );
+ }
+
+ CompositeGenerator& then( CompositeGenerator& other ) {
+ move( other );
+ return *this;
+ }
+
+ CompositeGenerator& then( T value ) {
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( value );
+ add( valuesGen );
+ return *this;
+ }
+
+private:
+
+ void move( CompositeGenerator& other ) {
+ std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
+ m_totalSize += other.m_totalSize;
+ other.m_composed.clear();
+ }
+
+ std::vector<const IGenerator<T>*> m_composed;
+ std::string m_fileInfo;
+ size_t m_totalSize;
+};
+
+namespace Generators
+{
+ template<typename T>
+ CompositeGenerator<T> between( T from, T to ) {
+ CompositeGenerator<T> generators;
+ generators.add( new BetweenGenerator<T>( from, to ) );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2 ) {
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2, T val3 ){
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ valuesGen->add( val3 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ valuesGen->add( val3 );
+ valuesGen->add( val4 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+} // end namespace Generators
+
+using namespace Generators;
+
+} // end namespace Catch
+
+#define INTERNAL_CATCH_LINESTR2( line ) #line
+#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
+
+#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
+
+// #included from: internal/catch_interfaces_exception.h
+#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
+
+#include <string>
+#include <vector>
+
+// #included from: catch_interfaces_registry_hub.h
+#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ class TestCase;
+ struct ITestCaseRegistry;
+ struct IExceptionTranslatorRegistry;
+ struct IExceptionTranslator;
+ struct IReporterRegistry;
+ struct IReporterFactory;
+
+ struct IRegistryHub {
+ virtual ~IRegistryHub();
+
+ virtual IReporterRegistry const& getReporterRegistry() const = 0;
+ virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
+ virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
+ };
+
+ struct IMutableRegistryHub {
+ virtual ~IMutableRegistryHub();
+ virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;
+ virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
+ virtual void registerTest( TestCase const& testInfo ) = 0;
+ virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
+ };
+
+ IRegistryHub& getRegistryHub();
+ IMutableRegistryHub& getMutableRegistryHub();
+ void cleanUp();
+ std::string translateActiveException();
+
+}
+
+namespace Catch {
+
+ typedef std::string(*exceptionTranslateFunction)();
+
+ struct IExceptionTranslator;
+ typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
+
+ struct IExceptionTranslator {
+ virtual ~IExceptionTranslator();
+ virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
+ };
+
+ struct IExceptionTranslatorRegistry {
+ virtual ~IExceptionTranslatorRegistry();
+
+ virtual std::string translateActiveException() const = 0;
+ };
+
+ class ExceptionTranslatorRegistrar {
+ template<typename T>
+ class ExceptionTranslator : public IExceptionTranslator {
+ public:
+
+ ExceptionTranslator( std::string(*translateFunction)( T& ) )
+ : m_translateFunction( translateFunction )
+ {}
+
+ virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
+ try {
+ if( it == itEnd )
+ throw;
+ else
+ return (*it)->translate( it+1, itEnd );
+ }
+ catch( T& ex ) {
+ return m_translateFunction( ex );
+ }
+ }
+
+ protected:
+ std::string(*m_translateFunction)( T& );
+ };
+
+ public:
+ template<typename T>
+ ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
+ getMutableRegistryHub().registerTranslator
+ ( new ExceptionTranslator<T>( translateFunction ) );
+ }
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
+ static std::string translatorName( signature ); \
+ namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
+ static std::string translatorName( signature )
+
+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
+
+// #included from: internal/catch_approx.hpp
+#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
+
+#include <cmath>
+#include <limits>
+
+namespace Catch {
+namespace Detail {
+
+ class Approx {
+ public:
+ explicit Approx ( double value )
+ : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
+ m_scale( 1.0 ),
+ m_value( value )
+ {}
+
+ Approx( Approx const& other )
+ : m_epsilon( other.m_epsilon ),
+ m_scale( other.m_scale ),
+ m_value( other.m_value )
+ {}
+
+ static Approx custom() {
+ return Approx( 0 );
+ }
+
+ Approx operator()( double value ) {
+ Approx approx( value );
+ approx.epsilon( m_epsilon );
+ approx.scale( m_scale );
+ return approx;
+ }
+
+ friend bool operator == ( double lhs, Approx const& rhs ) {
+ // Thanks to Richard Harris for his help refining this formula
+ return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
+ }
+
+ friend bool operator == ( Approx const& lhs, double rhs ) {
+ return operator==( rhs, lhs );
+ }
+
+ friend bool operator != ( double lhs, Approx const& rhs ) {
+ return !operator==( lhs, rhs );
+ }
+
+ friend bool operator != ( Approx const& lhs, double rhs ) {
+ return !operator==( rhs, lhs );
+ }
+
+ Approx& epsilon( double newEpsilon ) {
+ m_epsilon = newEpsilon;
+ return *this;
+ }
+
+ Approx& scale( double newScale ) {
+ m_scale = newScale;
+ return *this;
+ }
+
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << "Approx( " << Catch::toString( m_value ) << " )";
+ return oss.str();
+ }
+
+ private:
+ double m_epsilon;
+ double m_scale;
+ double m_value;
+ };
+}
+
+template<>
+inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
+ return value.toString();
+}
+
+} // end namespace Catch
+
+// #included from: internal/catch_interfaces_tag_alias_registry.h
+#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
+
+// #included from: catch_tag_alias.h
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct TagAlias {
+ TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
+
+ std::string tag;
+ SourceLineInfo lineInfo;
+ };
+
+ struct RegistrarForTagAliases {
+ RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
+ };
+
+} // end namespace Catch
+
+#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
+// #included from: catch_option.hpp
+#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
+
+namespace Catch {
+
+ // An optional type
+ template<typename T>
+ class Option {
+ public:
+ Option() : nullableValue( CATCH_NULL ) {}
+ Option( T const& _value )
+ : nullableValue( new( storage ) T( _value ) )
+ {}
+ Option( Option const& _other )
+ : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )
+ {}
+
+ ~Option() {
+ reset();
+ }
+
+ Option& operator= ( Option const& _other ) {
+ if( &_other != this ) {
+ reset();
+ if( _other )
+ nullableValue = new( storage ) T( *_other );
+ }
+ return *this;
+ }
+ Option& operator = ( T const& _value ) {
+ reset();
+ nullableValue = new( storage ) T( _value );
+ return *this;
+ }
+
+ void reset() {
+ if( nullableValue )
+ nullableValue->~T();
+ nullableValue = CATCH_NULL;
+ }
+
+ T& operator*() { return *nullableValue; }
+ T const& operator*() const { return *nullableValue; }
+ T* operator->() { return nullableValue; }
+ const T* operator->() const { return nullableValue; }
+
+ T valueOr( T const& defaultValue ) const {
+ return nullableValue ? *nullableValue : defaultValue;
+ }
+
+ bool some() const { return nullableValue != CATCH_NULL; }
+ bool none() const { return nullableValue == CATCH_NULL; }
+
+ bool operator !() const { return nullableValue == CATCH_NULL; }
+ operator SafeBool::type() const {
+ return SafeBool::makeSafe( some() );
+ }
+
+ private:
+ T* nullableValue;
+ char storage[sizeof(T)];
+ };
+
+} // end namespace Catch
+
+namespace Catch {
+
+ struct ITagAliasRegistry {
+ virtual ~ITagAliasRegistry();
+ virtual Option<TagAlias> find( std::string const& alias ) const = 0;
+ virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
+
+ static ITagAliasRegistry const& get();
+ };
+
+} // end namespace Catch
+
+// These files are included here so the single_include script doesn't put them
+// in the conditionally compiled sections
+// #included from: internal/catch_test_case_info.h
+#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
+
+#include <string>
+#include <set>
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+ struct ITestCase;
+
+ struct TestCaseInfo {
+ enum SpecialProperties{
+ None = 0,
+ IsHidden = 1 << 1,
+ ShouldFail = 1 << 2,
+ MayFail = 1 << 3,
+ Throws = 1 << 4
+ };
+
+ TestCaseInfo( std::string const& _name,
+ std::string const& _className,
+ std::string const& _description,
+ std::set<std::string> const& _tags,
+ SourceLineInfo const& _lineInfo );
+
+ TestCaseInfo( TestCaseInfo const& other );
+
+ friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );
+
+ bool isHidden() const;
+ bool throws() const;
+ bool okToFail() const;
+ bool expectedToFail() const;
+
+ std::string name;
+ std::string className;
+ std::string description;
+ std::set<std::string> tags;
+ std::set<std::string> lcaseTags;
+ std::string tagsAsString;
+ SourceLineInfo lineInfo;
+ SpecialProperties properties;
+ };
+
+ class TestCase : public TestCaseInfo {
+ public:
+
+ TestCase( ITestCase* testCase, TestCaseInfo const& info );
+ TestCase( TestCase const& other );
+
+ TestCase withName( std::string const& _newName ) const;
+
+ void invoke() const;
+
+ TestCaseInfo const& getTestCaseInfo() const;
+
+ void swap( TestCase& other );
+ bool operator == ( TestCase const& other ) const;
+ bool operator < ( TestCase const& other ) const;
+ TestCase& operator = ( TestCase const& other );
+
+ private:
+ Ptr<ITestCase> test;
+ };
+
+ TestCase makeTestCase( ITestCase* testCase,
+ std::string const& className,
+ std::string const& name,
+ std::string const& description,
+ SourceLineInfo const& lineInfo );
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+
+#ifdef __OBJC__
+// #included from: internal/catch_objc.hpp
+#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
+
+#import <objc/runtime.h>
+
+#include <string>
+
+// NB. Any general catch headers included here must be included
+// in catch.hpp first to make sure they are included by the single
+// header for non obj-usage
+
+///////////////////////////////////////////////////////////////////////////////
+// This protocol is really only here for (self) documenting purposes, since
+// all its methods are optional.
+@protocol OcFixture
+
+@optional
+
+-(void) setUp;
+-(void) tearDown;
+
+@end
+
+namespace Catch {
+
+ class OcMethod : public SharedImpl<ITestCase> {
+
+ public:
+ OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
+
+ virtual void invoke() const {
+ id obj = [[m_cls alloc] init];
+
+ performOptionalSelector( obj, @selector(setUp) );
+ performOptionalSelector( obj, m_sel );
+ performOptionalSelector( obj, @selector(tearDown) );
+
+ arcSafeRelease( obj );
+ }
+ private:
+ virtual ~OcMethod() {}
+
+ Class m_cls;
+ SEL m_sel;
+ };
+
+ namespace Detail{
+
+ inline std::string getAnnotation( Class cls,
+ std::string const& annotationName,
+ std::string const& testCaseName ) {
+ NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
+ SEL sel = NSSelectorFromString( selStr );
+ arcSafeRelease( selStr );
+ id value = performOptionalSelector( cls, sel );
+ if( value )
+ return [(NSString*)value UTF8String];
+ return "";
+ }
+ }
+
+ inline size_t registerTestMethods() {
+ size_t noTestMethods = 0;
+ int noClasses = objc_getClassList( CATCH_NULL, 0 );
+
+ Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
+ objc_getClassList( classes, noClasses );
+
+ for( int c = 0; c < noClasses; c++ ) {
+ Class cls = classes[c];
+ {
+ u_int count;
+ Method* methods = class_copyMethodList( cls, &count );
+ for( u_int m = 0; m < count ; m++ ) {
+ SEL selector = method_getName(methods[m]);
+ std::string methodName = sel_getName(selector);
+ if( startsWith( methodName, "Catch_TestCase_" ) ) {
+ std::string testCaseName = methodName.substr( 15 );
+ std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
+ std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
+ const char* className = class_getName( cls );
+
+ getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
+ noTestMethods++;
+ }
+ }
+ free(methods);
+ }
+ }
+ return noTestMethods;
+ }
+
+ namespace Matchers {
+ namespace Impl {
+ namespace NSStringMatchers {
+
+ template<typename MatcherT>
+ struct StringHolder : MatcherImpl<MatcherT, NSString*>{
+ StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
+ StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
+ StringHolder() {
+ arcSafeRelease( m_substr );
+ }
+
+ NSString* m_substr;
+ };
+
+ struct Equals : StringHolder<Equals> {
+ Equals( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str isEqualToString:m_substr];
+ }
+
+ virtual std::string toString() const {
+ return "equals string: " + Catch::toString( m_substr );
+ }
+ };
+
+ struct Contains : StringHolder<Contains> {
+ Contains( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location != NSNotFound;
+ }
+
+ virtual std::string toString() const {
+ return "contains string: " + Catch::toString( m_substr );
+ }
+ };
+
+ struct StartsWith : StringHolder<StartsWith> {
+ StartsWith( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location == 0;
+ }
+
+ virtual std::string toString() const {
+ return "starts with: " + Catch::toString( m_substr );
+ }
+ };
+ struct EndsWith : StringHolder<EndsWith> {
+ EndsWith( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location == [str length] - [m_substr length];
+ }
+
+ virtual std::string toString() const {
+ return "ends with: " + Catch::toString( m_substr );
+ }
+ };
+
+ } // namespace NSStringMatchers
+ } // namespace Impl
+
+ inline Impl::NSStringMatchers::Equals
+ Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
+
+ inline Impl::NSStringMatchers::Contains
+ Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
+
+ inline Impl::NSStringMatchers::StartsWith
+ StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
+
+ inline Impl::NSStringMatchers::EndsWith
+ EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
+
+ } // namespace Matchers
+
+ using namespace Matchers;
+
+} // namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define OC_TEST_CASE( name, desc )\
++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
+{\
+return @ name; \
+}\
++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
+{ \
+return @ desc; \
+} \
+-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
+
+#endif
+
+#ifdef CATCH_IMPL
+// #included from: internal/catch_impl.hpp
+#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
+
+// Collect all the implementation files together here
+// These are the equivalent of what would usually be cpp files
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wweak-vtables"
+#endif
+
+// #included from: ../catch_session.hpp
+#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
+
+// #included from: internal/catch_commandline.hpp
+#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
+
+// #included from: catch_config.hpp
+#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
+
+// #included from: catch_test_spec_parser.hpp
+#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+// #included from: catch_test_spec.hpp
+#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+// #included from: catch_wildcard_pattern.hpp
+#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED
+
+namespace Catch
+{
+ class WildcardPattern {
+ enum WildcardPosition {
+ NoWildcard = 0,
+ WildcardAtStart = 1,
+ WildcardAtEnd = 2,
+ WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
+ };
+
+ public:
+
+ WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )
+ : m_caseSensitivity( caseSensitivity ),
+ m_wildcard( NoWildcard ),
+ m_pattern( adjustCase( pattern ) )
+ {
+ if( startsWith( m_pattern, "*" ) ) {
+ m_pattern = m_pattern.substr( 1 );
+ m_wildcard = WildcardAtStart;
+ }
+ if( endsWith( m_pattern, "*" ) ) {
+ m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
+ m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
+ }
+ }
+ virtual ~WildcardPattern();
+ virtual bool matches( std::string const& str ) const {
+ switch( m_wildcard ) {
+ case NoWildcard:
+ return m_pattern == adjustCase( str );
+ case WildcardAtStart:
+ return endsWith( adjustCase( str ), m_pattern );
+ case WildcardAtEnd:
+ return startsWith( adjustCase( str ), m_pattern );
+ case WildcardAtBothEnds:
+ return contains( adjustCase( str ), m_pattern );
+ }
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunreachable-code"
+#endif
+ throw std::logic_error( "Unknown enum" );
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+ }
+ private:
+ std::string adjustCase( std::string const& str ) const {
+ return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
+ }
+ CaseSensitive::Choice m_caseSensitivity;
+ WildcardPosition m_wildcard;
+ std::string m_pattern;
+ };
+}
+
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+ class TestSpec {
+ struct Pattern : SharedImpl<> {
+ virtual ~Pattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const = 0;
+ };
+ class NamePattern : public Pattern {
+ public:
+ NamePattern( std::string const& name )
+ : m_wildcardPattern( toLower( name ), CaseSensitive::No )
+ {}
+ virtual ~NamePattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const {
+ return m_wildcardPattern.matches( toLower( testCase.name ) );
+ }
+ private:
+ WildcardPattern m_wildcardPattern;
+ };
+
+ class TagPattern : public Pattern {
+ public:
+ TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
+ virtual ~TagPattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const {
+ return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
+ }
+ private:
+ std::string m_tag;
+ };
+
+ class ExcludedPattern : public Pattern {
+ public:
+ ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
+ virtual ~ExcludedPattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
+ private:
+ Ptr<Pattern> m_underlyingPattern;
+ };
+
+ struct Filter {
+ std::vector<Ptr<Pattern> > m_patterns;
+
+ bool matches( TestCaseInfo const& testCase ) const {
+ // All patterns in a filter must match for the filter to be a match
+ for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
+ if( !(*it)->matches( testCase ) )
+ return false;
+ return true;
+ }
+ };
+
+ public:
+ bool hasFilters() const {
+ return !m_filters.empty();
+ }
+ bool matches( TestCaseInfo const& testCase ) const {
+ // A TestSpec matches if any filter matches
+ for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
+ if( it->matches( testCase ) )
+ return true;
+ return false;
+ }
+
+ private:
+ std::vector<Filter> m_filters;
+
+ friend class TestSpecParser;
+ };
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+namespace Catch {
+
+ class TestSpecParser {
+ enum Mode{ None, Name, QuotedName, Tag };
+ Mode m_mode;
+ bool m_exclusion;
+ std::size_t m_start, m_pos;
+ std::string m_arg;
+ TestSpec::Filter m_currentFilter;
+ TestSpec m_testSpec;
+ ITagAliasRegistry const* m_tagAliases;
+
+ public:
+ TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
+
+ TestSpecParser& parse( std::string const& arg ) {
+ m_mode = None;
+ m_exclusion = false;
+ m_start = std::string::npos;
+ m_arg = m_tagAliases->expandAliases( arg );
+ for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
+ visitChar( m_arg[m_pos] );
+ if( m_mode == Name )
+ addPattern<TestSpec::NamePattern>();
+ return *this;
+ }
+ TestSpec testSpec() {
+ addFilter();
+ return m_testSpec;
+ }
+ private:
+ void visitChar( char c ) {
+ if( m_mode == None ) {
+ switch( c ) {
+ case ' ': return;
+ case '~': m_exclusion = true; return;
+ case '[': return startNewMode( Tag, ++m_pos );
+ case '"': return startNewMode( QuotedName, ++m_pos );
+ default: startNewMode( Name, m_pos ); break;
+ }
+ }
+ if( m_mode == Name ) {
+ if( c == ',' ) {
+ addPattern<TestSpec::NamePattern>();
+ addFilter();
+ }
+ else if( c == '[' ) {
+ if( subString() == "exclude:" )
+ m_exclusion = true;
+ else
+ addPattern<TestSpec::NamePattern>();
+ startNewMode( Tag, ++m_pos );
+ }
+ }
+ else if( m_mode == QuotedName && c == '"' )
+ addPattern<TestSpec::NamePattern>();
+ else if( m_mode == Tag && c == ']' )
+ addPattern<TestSpec::TagPattern>();
+ }
+ void startNewMode( Mode mode, std::size_t start ) {
+ m_mode = mode;
+ m_start = start;
+ }
+ std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
+ template<typename T>
+ void addPattern() {
+ std::string token = subString();
+ if( startsWith( token, "exclude:" ) ) {
+ m_exclusion = true;
+ token = token.substr( 8 );
+ }
+ if( !token.empty() ) {
+ Ptr<TestSpec::Pattern> pattern = new T( token );
+ if( m_exclusion )
+ pattern = new TestSpec::ExcludedPattern( pattern );
+ m_currentFilter.m_patterns.push_back( pattern );
+ }
+ m_exclusion = false;
+ m_mode = None;
+ }
+ void addFilter() {
+ if( !m_currentFilter.m_patterns.empty() ) {
+ m_testSpec.m_filters.push_back( m_currentFilter );
+ m_currentFilter = TestSpec::Filter();
+ }
+ }
+ };
+ inline TestSpec parseTestSpec( std::string const& arg ) {
+ return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
+ }
+
+} // namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// #included from: catch_interfaces_config.h
+#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+ struct Verbosity { enum Level {
+ NoOutput = 0,
+ Quiet,
+ Normal
+ }; };
+
+ struct WarnAbout { enum What {
+ Nothing = 0x00,
+ NoAssertions = 0x01
+ }; };
+
+ struct ShowDurations { enum OrNot {
+ DefaultForReporter,
+ Always,
+ Never
+ }; };
+ struct RunTests { enum InWhatOrder {
+ InDeclarationOrder,
+ InLexicographicalOrder,
+ InRandomOrder
+ }; };
+ struct UseColour { enum YesOrNo {
+ Auto,
+ Yes,
+ No
+ }; };
+
+ class TestSpec;
+
+ struct IConfig : IShared {
+
+ virtual ~IConfig();
+
+ virtual bool allowThrows() const = 0;
+ virtual std::ostream& stream() const = 0;
+ virtual std::string name() const = 0;
+ virtual bool includeSuccessfulResults() const = 0;
+ virtual bool shouldDebugBreak() const = 0;
+ virtual bool warnAboutMissingAssertions() const = 0;
+ virtual int abortAfter() const = 0;
+ virtual bool showInvisibles() const = 0;
+ virtual ShowDurations::OrNot showDurations() const = 0;
+ virtual TestSpec const& testSpec() const = 0;
+ virtual RunTests::InWhatOrder runOrder() const = 0;
+ virtual unsigned int rngSeed() const = 0;
+ virtual UseColour::YesOrNo useColour() const = 0;
+ };
+}
+
+// #included from: catch_stream.h
+#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
+
+// #included from: catch_streambuf.h
+#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
+
+#include <streambuf>
+
+namespace Catch {
+
+ class StreamBufBase : public std::streambuf {
+ public:
+ virtual ~StreamBufBase() CATCH_NOEXCEPT;
+ };
+}
+
+#include <streambuf>
+#include <ostream>
+#include <fstream>
+
+namespace Catch {
+
+ std::ostream& cout();
+ std::ostream& cerr();
+
+ struct IStream {
+ virtual ~IStream() CATCH_NOEXCEPT;
+ virtual std::ostream& stream() const = 0;
+ };
+
+ class FileStream : public IStream {
+ mutable std::ofstream m_ofs;
+ public:
+ FileStream( std::string const& filename );
+ virtual ~FileStream() CATCH_NOEXCEPT;
+ public: // IStream
+ virtual std::ostream& stream() const CATCH_OVERRIDE;
+ };
+
+ class CoutStream : public IStream {
+ mutable std::ostream m_os;
+ public:
+ CoutStream();
+ virtual ~CoutStream() CATCH_NOEXCEPT;
+
+ public: // IStream
+ virtual std::ostream& stream() const CATCH_OVERRIDE;
+ };
+
+ class DebugOutStream : public IStream {
+ std::auto_ptr<StreamBufBase> m_streamBuf;
+ mutable std::ostream m_os;
+ public:
+ DebugOutStream();
+ virtual ~DebugOutStream() CATCH_NOEXCEPT;
+
+ public: // IStream
+ virtual std::ostream& stream() const CATCH_OVERRIDE;
+ };
+}
+
+#include <memory>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <ctime>
+
+#ifndef CATCH_CONFIG_CONSOLE_WIDTH
+#define CATCH_CONFIG_CONSOLE_WIDTH 80
+#endif
+
+namespace Catch {
+
+ struct ConfigData {
+
+ ConfigData()
+ : listTests( false ),
+ listTags( false ),
+ listReporters( false ),
+ listTestNamesOnly( false ),
+ showSuccessfulTests( false ),
+ shouldDebugBreak( false ),
+ noThrow( false ),
+ showHelp( false ),
+ showInvisibles( false ),
+ filenamesAsTags( false ),
+ abortAfter( -1 ),
+ rngSeed( 0 ),
+ verbosity( Verbosity::Normal ),
+ warnings( WarnAbout::Nothing ),
+ showDurations( ShowDurations::DefaultForReporter ),
+ runOrder( RunTests::InDeclarationOrder ),
+ useColour( UseColour::Auto )
+ {}
+
+ bool listTests;
+ bool listTags;
+ bool listReporters;
+ bool listTestNamesOnly;
+
+ bool showSuccessfulTests;
+ bool shouldDebugBreak;
+ bool noThrow;
+ bool showHelp;
+ bool showInvisibles;
+ bool filenamesAsTags;
+
+ int abortAfter;
+ unsigned int rngSeed;
+
+ Verbosity::Level verbosity;
+ WarnAbout::What warnings;
+ ShowDurations::OrNot showDurations;
+ RunTests::InWhatOrder runOrder;
+ UseColour::YesOrNo useColour;
+
+ std::string outputFilename;
+ std::string name;
+ std::string processName;
+
+ std::vector<std::string> reporterNames;
+ std::vector<std::string> testsOrTags;
+ };
+
+ class Config : public SharedImpl<IConfig> {
+ private:
+ Config( Config const& other );
+ Config& operator = ( Config const& other );
+ virtual void dummy();
+ public:
+
+ Config()
+ {}
+
+ Config( ConfigData const& data )
+ : m_data( data ),
+ m_stream( openStream() )
+ {
+ if( !data.testsOrTags.empty() ) {
+ TestSpecParser parser( ITagAliasRegistry::get() );
+ for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
+ parser.parse( data.testsOrTags[i] );
+ m_testSpec = parser.testSpec();
+ }
+ }
+
+ virtual ~Config() {
+ }
+
+ std::string const& getFilename() const {
+ return m_data.outputFilename ;
+ }
+
+ bool listTests() const { return m_data.listTests; }
+ bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
+ bool listTags() const { return m_data.listTags; }
+ bool listReporters() const { return m_data.listReporters; }
+
+ std::string getProcessName() const { return m_data.processName; }
+
+ bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
+
+ std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
+
+ int abortAfter() const { return m_data.abortAfter; }
+
+ TestSpec const& testSpec() const { return m_testSpec; }
+
+ bool showHelp() const { return m_data.showHelp; }
+ bool showInvisibles() const { return m_data.showInvisibles; }
+
+ // IConfig interface
+ virtual bool allowThrows() const { return !m_data.noThrow; }
+ virtual std::ostream& stream() const { return m_stream->stream(); }
+ virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
+ virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
+ virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
+ virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
+ virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
+ virtual unsigned int rngSeed() const { return m_data.rngSeed; }
+ virtual UseColour::YesOrNo useColour() const { return m_data.useColour; }
+
+ private:
+
+ IStream const* openStream() {
+ if( m_data.outputFilename.empty() )
+ return new CoutStream();
+ else if( m_data.outputFilename[0] == '%' ) {
+ if( m_data.outputFilename == "%debug" )
+ return new DebugOutStream();
+ else
+ throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename );
+ }
+ else
+ return new FileStream( m_data.outputFilename );
+ }
+ ConfigData m_data;
+
+ std::auto_ptr<IStream const> m_stream;
+ TestSpec m_testSpec;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_clara.h
+#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
+
+// Use Catch's value for console width (store Clara's off to the side, if present)
+#ifdef CLARA_CONFIG_CONSOLE_WIDTH
+#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
+#undef CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
+
+// Declare Clara inside the Catch namespace
+#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
+// #included from: ../external/clara.h
+
+// Version 0.0.1.1
+
+// Only use header guard if we are not using an outer namespace
+#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
+
+#ifndef STITCH_CLARA_OPEN_NAMESPACE
+#define TWOBLUECUBES_CLARA_H_INCLUDED
+#define STITCH_CLARA_OPEN_NAMESPACE
+#define STITCH_CLARA_CLOSE_NAMESPACE
+#else
+#define STITCH_CLARA_CLOSE_NAMESPACE }
+#endif
+
+#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
+
+// ----------- #included from tbc_text_format.h -----------
+
+// Only use header guard if we are not using an outer namespace
+#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
+#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+#define TBC_TEXT_FORMAT_H_INCLUDED
+#endif
+
+#include <string>
+#include <vector>
+#include <sstream>
+#include <algorithm>
+
+// Use optional outer namespace
+#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
+#endif
+
+namespace Tbc {
+
+#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
+ const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ struct TextAttributes {
+ TextAttributes()
+ : initialIndent( std::string::npos ),
+ indent( 0 ),
+ width( consoleWidth-1 ),
+ tabChar( '\t' )
+ {}
+
+ TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
+ TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
+ TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
+ TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
+
+ std::size_t initialIndent; // indent of first line, or npos
+ std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
+ std::size_t width; // maximum width of text, including indent. Longer text will wrap
+ char tabChar; // If this char is seen the indent is changed to current pos
+ };
+
+ class Text {
+ public:
+ Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
+ : attr( _attr )
+ {
+ std::string wrappableChars = " [({.,/|\\-";
+ std::size_t indent = _attr.initialIndent != std::string::npos
+ ? _attr.initialIndent
+ : _attr.indent;
+ std::string remainder = _str;
+
+ while( !remainder.empty() ) {
+ if( lines.size() >= 1000 ) {
+ lines.push_back( "... message truncated due to excessive size" );
+ return;
+ }
+ std::size_t tabPos = std::string::npos;
+ std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
+ std::size_t pos = remainder.find_first_of( '\n' );
+ if( pos <= width ) {
+ width = pos;
+ }
+ pos = remainder.find_last_of( _attr.tabChar, width );
+ if( pos != std::string::npos ) {
+ tabPos = pos;
+ if( remainder[width] == '\n' )
+ width--;
+ remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
+ }
+
+ if( width == remainder.size() ) {
+ spliceLine( indent, remainder, width );
+ }
+ else if( remainder[width] == '\n' ) {
+ spliceLine( indent, remainder, width );
+ if( width <= 1 || remainder.size() != 1 )
+ remainder = remainder.substr( 1 );
+ indent = _attr.indent;
+ }
+ else {
+ pos = remainder.find_last_of( wrappableChars, width );
+ if( pos != std::string::npos && pos > 0 ) {
+ spliceLine( indent, remainder, pos );
+ if( remainder[0] == ' ' )
+ remainder = remainder.substr( 1 );
+ }
+ else {
+ spliceLine( indent, remainder, width-1 );
+ lines.back() += "-";
+ }
+ if( lines.size() == 1 )
+ indent = _attr.indent;
+ if( tabPos != std::string::npos )
+ indent += tabPos;
+ }
+ }
+ }
+
+ void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
+ lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
+ _remainder = _remainder.substr( _pos );
+ }
+
+ typedef std::vector<std::string>::const_iterator const_iterator;
+
+ const_iterator begin() const { return lines.begin(); }
+ const_iterator end() const { return lines.end(); }
+ std::string const& last() const { return lines.back(); }
+ std::size_t size() const { return lines.size(); }
+ std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << *this;
+ return oss.str();
+ }
+
+ inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
+ for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
+ it != itEnd; ++it ) {
+ if( it != _text.begin() )
+ _stream << "\n";
+ _stream << *it;
+ }
+ return _stream;
+ }
+
+ private:
+ std::string str;
+ TextAttributes attr;
+ std::vector<std::string> lines;
+ };
+
+} // end namespace Tbc
+
+#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+} // end outer namespace
+#endif
+
+#endif // TBC_TEXT_FORMAT_H_INCLUDED
+
+// ----------- end of #include from tbc_text_format.h -----------
+// ........... back in clara.h
+
+#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
+
+// ----------- #included from clara_compilers.h -----------
+
+#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
+#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
+
+// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
+// The following features are defined:
+//
+// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported?
+// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
+// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
+// CLARA_CONFIG_CPP11_OVERRIDE : is override supported?
+// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
+
+// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
+
+// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported?
+
+// In general each macro has a _NO_<feature name> form
+// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
+// Many features, at point of detection, define an _INTERNAL_ macro, so they
+// can be combined, en-mass, with the _NO_ forms later.
+
+// All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11
+
+#ifdef __clang__
+
+#if __has_feature(cxx_nullptr)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+#if __has_feature(cxx_noexcept)
+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#endif
+
+#endif // __clang__
+
+////////////////////////////////////////////////////////////////////////////////
+// GCC
+#ifdef __GNUC__
+
+#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+// - otherwise more recent versions define __cplusplus >= 201103L
+// and will get picked up below
+
+#endif // __GNUC__
+
+////////////////////////////////////////////////////////////////////////////////
+// Visual C++
+#ifdef _MSC_VER
+
+#if (_MSC_VER >= 1600)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#endif
+
+#endif // _MSC_VER
+
+////////////////////////////////////////////////////////////////////////////////
+// C++ language feature support
+
+// catch all support for C++11
+#if defined(__cplusplus) && __cplusplus >= 201103L
+
+#define CLARA_CPP11_OR_GREATER
+
+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#endif
+
+#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#endif
+
+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)
+#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE
+#endif
+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
+#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+#endif // __cplusplus >= 201103L
+
+// Now set the actual defines based on the above + anything the user has configured
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_NULLPTR
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_NOEXCEPT
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_GENERATED_METHODS
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_OVERRIDE
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+// noexcept support:
+#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)
+#define CLARA_NOEXCEPT noexcept
+# define CLARA_NOEXCEPT_IS(x) noexcept(x)
+#else
+#define CLARA_NOEXCEPT throw()
+# define CLARA_NOEXCEPT_IS(x)
+#endif
+
+// nullptr support
+#ifdef CLARA_CONFIG_CPP11_NULLPTR
+#define CLARA_NULL nullptr
+#else
+#define CLARA_NULL NULL
+#endif
+
+// override support
+#ifdef CLARA_CONFIG_CPP11_OVERRIDE
+#define CLARA_OVERRIDE override
+#else
+#define CLARA_OVERRIDE
+#endif
+
+// unique_ptr support
+#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR
+# define CLARA_AUTO_PTR( T ) std::unique_ptr<T>
+#else
+# define CLARA_AUTO_PTR( T ) std::auto_ptr<T>
+#endif
+
+#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
+
+// ----------- end of #include from clara_compilers.h -----------
+// ........... back in clara.h
+
+#include <map>
+#include <stdexcept>
+#include <memory>
+
+// Use optional outer namespace
+#ifdef STITCH_CLARA_OPEN_NAMESPACE
+STITCH_CLARA_OPEN_NAMESPACE
+#endif
+
+namespace Clara {
+
+ struct UnpositionalTag {};
+
+ extern UnpositionalTag _;
+
+#ifdef CLARA_CONFIG_MAIN
+ UnpositionalTag _;
+#endif
+
+ namespace Detail {
+
+#ifdef CLARA_CONSOLE_WIDTH
+ const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ // Use this to try and stop compiler from warning about unreachable code
+ inline bool isTrue( bool value ) { return value; }
+
+ using namespace Tbc;
+
+ inline bool startsWith( std::string const& str, std::string const& prefix ) {
+ return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
+ }
+
+ template<typename T> struct RemoveConstRef{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
+
+ template<typename T> struct IsBool { static const bool value = false; };
+ template<> struct IsBool<bool> { static const bool value = true; };
+
+ template<typename T>
+ void convertInto( std::string const& _source, T& _dest ) {
+ std::stringstream ss;
+ ss << _source;
+ ss >> _dest;
+ if( ss.fail() )
+ throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
+ }
+ inline void convertInto( std::string const& _source, std::string& _dest ) {
+ _dest = _source;
+ }
+ inline void convertInto( std::string const& _source, bool& _dest ) {
+ std::string sourceLC = _source;
+ std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
+ if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
+ _dest = true;
+ else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
+ _dest = false;
+ else
+ throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
+ }
+ inline void convertInto( bool _source, bool& _dest ) {
+ _dest = _source;
+ }
+ template<typename T>
+ inline void convertInto( bool, T& ) {
+ if( isTrue( true ) )
+ throw std::runtime_error( "Invalid conversion" );
+ }
+
+ template<typename ConfigT>
+ struct IArgFunction {
+ virtual ~IArgFunction() {}
+#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS
+ IArgFunction() = default;
+ IArgFunction( IArgFunction const& ) = default;
+#endif
+ virtual void set( ConfigT& config, std::string const& value ) const = 0;
+ virtual void setFlag( ConfigT& config ) const = 0;
+ virtual bool takesArg() const = 0;
+ virtual IArgFunction* clone() const = 0;
+ };
+
+ template<typename ConfigT>
+ class BoundArgFunction {
+ public:
+ BoundArgFunction() : functionObj( CLARA_NULL ) {}
+ BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
+ BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}
+ BoundArgFunction& operator = ( BoundArgFunction const& other ) {
+ IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;
+ delete functionObj;
+ functionObj = newFunctionObj;
+ return *this;
+ }
+ ~BoundArgFunction() { delete functionObj; }
+
+ void set( ConfigT& config, std::string const& value ) const {
+ functionObj->set( config, value );
+ }
+ void setFlag( ConfigT& config ) const {
+ functionObj->setFlag( config );
+ }
+ bool takesArg() const { return functionObj->takesArg(); }
+
+ bool isSet() const {
+ return functionObj != CLARA_NULL;
+ }
+ private:
+ IArgFunction<ConfigT>* functionObj;
+ };
+
+ template<typename C>
+ struct NullBinder : IArgFunction<C>{
+ virtual void set( C&, std::string const& ) const {}
+ virtual void setFlag( C& ) const {}
+ virtual bool takesArg() const { return true; }
+ virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
+ };
+
+ template<typename C, typename M>
+ struct BoundDataMember : IArgFunction<C>{
+ BoundDataMember( M C::* _member ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ convertInto( stringValue, p.*member );
+ }
+ virtual void setFlag( C& p ) const {
+ convertInto( true, p.*member );
+ }
+ virtual bool takesArg() const { return !IsBool<M>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
+ M C::* member;
+ };
+ template<typename C, typename M>
+ struct BoundUnaryMethod : IArgFunction<C>{
+ BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ typename RemoveConstRef<M>::type value;
+ convertInto( stringValue, value );
+ (p.*member)( value );
+ }
+ virtual void setFlag( C& p ) const {
+ typename RemoveConstRef<M>::type value;
+ convertInto( true, value );
+ (p.*member)( value );
+ }
+ virtual bool takesArg() const { return !IsBool<M>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
+ void (C::*member)( M );
+ };
+ template<typename C>
+ struct BoundNullaryMethod : IArgFunction<C>{
+ BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ bool value;
+ convertInto( stringValue, value );
+ if( value )
+ (p.*member)();
+ }
+ virtual void setFlag( C& p ) const {
+ (p.*member)();
+ }
+ virtual bool takesArg() const { return false; }
+ virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
+ void (C::*member)();
+ };
+
+ template<typename C>
+ struct BoundUnaryFunction : IArgFunction<C>{
+ BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
+ virtual void set( C& obj, std::string const& stringValue ) const {
+ bool value;
+ convertInto( stringValue, value );
+ if( value )
+ function( obj );
+ }
+ virtual void setFlag( C& p ) const {
+ function( p );
+ }
+ virtual bool takesArg() const { return false; }
+ virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
+ void (*function)( C& );
+ };
+
+ template<typename C, typename T>
+ struct BoundBinaryFunction : IArgFunction<C>{
+ BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
+ virtual void set( C& obj, std::string const& stringValue ) const {
+ typename RemoveConstRef<T>::type value;
+ convertInto( stringValue, value );
+ function( obj, value );
+ }
+ virtual void setFlag( C& obj ) const {
+ typename RemoveConstRef<T>::type value;
+ convertInto( true, value );
+ function( obj, value );
+ }
+ virtual bool takesArg() const { return !IsBool<T>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
+ void (*function)( C&, T );
+ };
+
+ } // namespace Detail
+
+ struct Parser {
+ Parser() : separators( " \t=:" ) {}
+
+ struct Token {
+ enum Type { Positional, ShortOpt, LongOpt };
+ Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
+ Type type;
+ std::string data;
+ };
+
+ void parseIntoTokens( int argc, char const* const argv[], std::vector<Parser::Token>& tokens ) const {
+ const std::string doubleDash = "--";
+ for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
+ parseIntoTokens( argv[i] , tokens);
+ }
+ void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
+ while( !arg.empty() ) {
+ Parser::Token token( Parser::Token::Positional, arg );
+ arg = "";
+ if( token.data[0] == '-' ) {
+ if( token.data.size() > 1 && token.data[1] == '-' ) {
+ token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
+ }
+ else {
+ token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
+ if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
+ arg = "-" + token.data.substr( 1 );
+ token.data = token.data.substr( 0, 1 );
+ }
+ }
+ }
+ if( token.type != Parser::Token::Positional ) {
+ std::size_t pos = token.data.find_first_of( separators );
+ if( pos != std::string::npos ) {
+ arg = token.data.substr( pos+1 );
+ token.data = token.data.substr( 0, pos );
+ }
+ }
+ tokens.push_back( token );
+ }
+ }
+ std::string separators;
+ };
+
+ template<typename ConfigT>
+ struct CommonArgProperties {
+ CommonArgProperties() {}
+ CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
+
+ Detail::BoundArgFunction<ConfigT> boundField;
+ std::string description;
+ std::string detail;
+ std::string placeholder; // Only value if boundField takes an arg
+
+ bool takesArg() const {
+ return !placeholder.empty();
+ }
+ void validate() const {
+ if( !boundField.isSet() )
+ throw std::logic_error( "option not bound" );
+ }
+ };
+ struct OptionArgProperties {
+ std::vector<std::string> shortNames;
+ std::string longName;
+
+ bool hasShortName( std::string const& shortName ) const {
+ return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
+ }
+ bool hasLongName( std::string const& _longName ) const {
+ return _longName == longName;
+ }
+ };
+ struct PositionalArgProperties {
+ PositionalArgProperties() : position( -1 ) {}
+ int position; // -1 means non-positional (floating)
+
+ bool isFixedPositional() const {
+ return position != -1;
+ }
+ };
+
+ template<typename ConfigT>
+ class CommandLine {
+
+ struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
+ Arg() {}
+ Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
+
+ using CommonArgProperties<ConfigT>::placeholder; // !TBD
+
+ std::string dbgName() const {
+ if( !longName.empty() )
+ return "--" + longName;
+ if( !shortNames.empty() )
+ return "-" + shortNames[0];
+ return "positional args";
+ }
+ std::string commands() const {
+ std::ostringstream oss;
+ bool first = true;
+ std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
+ for(; it != itEnd; ++it ) {
+ if( first )
+ first = false;
+ else
+ oss << ", ";
+ oss << "-" << *it;
+ }
+ if( !longName.empty() ) {
+ if( !first )
+ oss << ", ";
+ oss << "--" << longName;
+ }
+ if( !placeholder.empty() )
+ oss << " <" << placeholder << ">";
+ return oss.str();
+ }
+ };
+
+ typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;
+
+ friend void addOptName( Arg& arg, std::string const& optName )
+ {
+ if( optName.empty() )
+ return;
+ if( Detail::startsWith( optName, "--" ) ) {
+ if( !arg.longName.empty() )
+ throw std::logic_error( "Only one long opt may be specified. '"
+ + arg.longName
+ + "' already specified, now attempting to add '"
+ + optName + "'" );
+ arg.longName = optName.substr( 2 );
+ }
+ else if( Detail::startsWith( optName, "-" ) )
+ arg.shortNames.push_back( optName.substr( 1 ) );
+ else
+ throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
+ }
+ friend void setPositionalArg( Arg& arg, int position )
+ {
+ arg.position = position;
+ }
+
+ class ArgBuilder {
+ public:
+ ArgBuilder( Arg* arg ) : m_arg( arg ) {}
+
+ // Bind a non-boolean data member (requires placeholder string)
+ template<typename C, typename M>
+ void bind( M C::* field, std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
+ m_arg->placeholder = placeholder;
+ }
+ // Bind a boolean data member (no placeholder required)
+ template<typename C>
+ void bind( bool C::* field ) {
+ m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
+ }
+
+ // Bind a method taking a single, non-boolean argument (requires a placeholder string)
+ template<typename C, typename M>
+ void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
+ m_arg->placeholder = placeholder;
+ }
+
+ // Bind a method taking a single, boolean argument (no placeholder string required)
+ template<typename C>
+ void bind( void (C::* unaryMethod)( bool ) ) {
+ m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
+ }
+
+ // Bind a method that takes no arguments (will be called if opt is present)
+ template<typename C>
+ void bind( void (C::* nullaryMethod)() ) {
+ m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
+ }
+
+ // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
+ template<typename C>
+ void bind( void (* unaryFunction)( C& ) ) {
+ m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
+ }
+
+ // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
+ template<typename C, typename T>
+ void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
+ m_arg->placeholder = placeholder;
+ }
+
+ ArgBuilder& describe( std::string const& description ) {
+ m_arg->description = description;
+ return *this;
+ }
+ ArgBuilder& detail( std::string const& detail ) {
+ m_arg->detail = detail;
+ return *this;
+ }
+
+ protected:
+ Arg* m_arg;
+ };
+
+ class OptBuilder : public ArgBuilder {
+ public:
+ OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
+ OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
+
+ OptBuilder& operator[]( std::string const& optName ) {
+ addOptName( *ArgBuilder::m_arg, optName );
+ return *this;
+ }
+ };
+
+ public:
+
+ CommandLine()
+ : m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
+ m_highestSpecifiedArgPosition( 0 ),
+ m_throwOnUnrecognisedTokens( false )
+ {}
+ CommandLine( CommandLine const& other )
+ : m_boundProcessName( other.m_boundProcessName ),
+ m_options ( other.m_options ),
+ m_positionalArgs( other.m_positionalArgs ),
+ m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
+ m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
+ {
+ if( other.m_floatingArg.get() )
+ m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
+ }
+
+ CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
+ m_throwOnUnrecognisedTokens = shouldThrow;
+ return *this;
+ }
+
+ OptBuilder operator[]( std::string const& optName ) {
+ m_options.push_back( Arg() );
+ addOptName( m_options.back(), optName );
+ OptBuilder builder( &m_options.back() );
+ return builder;
+ }
+
+ ArgBuilder operator[]( int position ) {
+ m_positionalArgs.insert( std::make_pair( position, Arg() ) );
+ if( position > m_highestSpecifiedArgPosition )
+ m_highestSpecifiedArgPosition = position;
+ setPositionalArg( m_positionalArgs[position], position );
+ ArgBuilder builder( &m_positionalArgs[position] );
+ return builder;
+ }
+
+ // Invoke this with the _ instance
+ ArgBuilder operator[]( UnpositionalTag ) {
+ if( m_floatingArg.get() )
+ throw std::logic_error( "Only one unpositional argument can be added" );
+ m_floatingArg.reset( new Arg() );
+ ArgBuilder builder( m_floatingArg.get() );
+ return builder;
+ }
+
+ template<typename C, typename M>
+ void bindProcessName( M C::* field ) {
+ m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
+ }
+ template<typename C, typename M>
+ void bindProcessName( void (C::*_unaryMethod)( M ) ) {
+ m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
+ }
+
+ void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
+ typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
+ std::size_t maxWidth = 0;
+ for( it = itBegin; it != itEnd; ++it )
+ maxWidth = (std::max)( maxWidth, it->commands().size() );
+
+ for( it = itBegin; it != itEnd; ++it ) {
+ Detail::Text usage( it->commands(), Detail::TextAttributes()
+ .setWidth( maxWidth+indent )
+ .setIndent( indent ) );
+ Detail::Text desc( it->description, Detail::TextAttributes()
+ .setWidth( width - maxWidth - 3 ) );
+
+ for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
+ std::string usageCol = i < usage.size() ? usage[i] : "";
+ os << usageCol;
+
+ if( i < desc.size() && !desc[i].empty() )
+ os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
+ << desc[i];
+ os << "\n";
+ }
+ }
+ }
+ std::string optUsage() const {
+ std::ostringstream oss;
+ optUsage( oss );
+ return oss.str();
+ }
+
+ void argSynopsis( std::ostream& os ) const {
+ for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
+ if( i > 1 )
+ os << " ";
+ typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
+ if( it != m_positionalArgs.end() )
+ os << "<" << it->second.placeholder << ">";
+ else if( m_floatingArg.get() )
+ os << "<" << m_floatingArg->placeholder << ">";
+ else
+ throw std::logic_error( "non consecutive positional arguments with no floating args" );
+ }
+ // !TBD No indication of mandatory args
+ if( m_floatingArg.get() ) {
+ if( m_highestSpecifiedArgPosition > 1 )
+ os << " ";
+ os << "[<" << m_floatingArg->placeholder << "> ...]";
+ }
+ }
+ std::string argSynopsis() const {
+ std::ostringstream oss;
+ argSynopsis( oss );
+ return oss.str();
+ }
+
+ void usage( std::ostream& os, std::string const& procName ) const {
+ validate();
+ os << "usage:\n " << procName << " ";
+ argSynopsis( os );
+ if( !m_options.empty() ) {
+ os << " [options]\n\nwhere options are: \n";
+ optUsage( os, 2 );
+ }
+ os << "\n";
+ }
+ std::string usage( std::string const& procName ) const {
+ std::ostringstream oss;
+ usage( oss, procName );
+ return oss.str();
+ }
+
+ ConfigT parse( int argc, char const* const argv[] ) const {
+ ConfigT config;
+ parseInto( argc, argv, config );
+ return config;
+ }
+
+ std::vector<Parser::Token> parseInto( int argc, char const* argv[], ConfigT& config ) const {
+ std::string processName = argv[0];
+ std::size_t lastSlash = processName.find_last_of( "/\\" );
+ if( lastSlash != std::string::npos )
+ processName = processName.substr( lastSlash+1 );
+ m_boundProcessName.set( config, processName );
+ std::vector<Parser::Token> tokens;
+ Parser parser;
+ parser.parseIntoTokens( argc, argv, tokens );
+ return populate( tokens, config );
+ }
+
+ std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ validate();
+ std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
+ unusedTokens = populateFixedArgs( unusedTokens, config );
+ unusedTokens = populateFloatingArgs( unusedTokens, config );
+ return unusedTokens;
+ }
+
+ std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ std::vector<Parser::Token> unusedTokens;
+ std::vector<std::string> errors;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
+ for(; it != itEnd; ++it ) {
+ Arg const& arg = *it;
+
+ try {
+ if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
+ ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
+ if( arg.takesArg() ) {
+ if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
+ errors.push_back( "Expected argument to option: " + token.data );
+ else
+ arg.boundField.set( config, tokens[++i].data );
+ }
+ else {
+ arg.boundField.setFlag( config );
+ }
+ break;
+ }
+ }
+ catch( std::exception& ex ) {
+ errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
+ }
+ }
+ if( it == itEnd ) {
+ if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
+ unusedTokens.push_back( token );
+ else if( errors.empty() && m_throwOnUnrecognisedTokens )
+ errors.push_back( "unrecognised option: " + token.data );
+ }
+ }
+ if( !errors.empty() ) {
+ std::ostringstream oss;
+ for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
+ it != itEnd;
+ ++it ) {
+ if( it != errors.begin() )
+ oss << "\n";
+ oss << *it;
+ }
+ throw std::runtime_error( oss.str() );
+ }
+ return unusedTokens;
+ }
+ std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ std::vector<Parser::Token> unusedTokens;
+ int position = 1;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
+ if( it != m_positionalArgs.end() )
+ it->second.boundField.set( config, token.data );
+ else
+ unusedTokens.push_back( token );
+ if( token.type == Parser::Token::Positional )
+ position++;
+ }
+ return unusedTokens;
+ }
+ std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ if( !m_floatingArg.get() )
+ return tokens;
+ std::vector<Parser::Token> unusedTokens;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ if( token.type == Parser::Token::Positional )
+ m_floatingArg->boundField.set( config, token.data );
+ else
+ unusedTokens.push_back( token );
+ }
+ return unusedTokens;
+ }
+
+ void validate() const
+ {
+ if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
+ throw std::logic_error( "No options or arguments specified" );
+
+ for( typename std::vector<Arg>::const_iterator it = m_options.begin(),
+ itEnd = m_options.end();
+ it != itEnd; ++it )
+ it->validate();
+ }
+
+ private:
+ Detail::BoundArgFunction<ConfigT> m_boundProcessName;
+ std::vector<Arg> m_options;
+ std::map<int, Arg> m_positionalArgs;
+ ArgAutoPtr m_floatingArg;
+ int m_highestSpecifiedArgPosition;
+ bool m_throwOnUnrecognisedTokens;
+ };
+
+} // end namespace Clara
+
+STITCH_CLARA_CLOSE_NAMESPACE
+#undef STITCH_CLARA_OPEN_NAMESPACE
+#undef STITCH_CLARA_CLOSE_NAMESPACE
+
+#endif // TWOBLUECUBES_CLARA_H_INCLUDED
+#undef STITCH_CLARA_OPEN_NAMESPACE
+
+// Restore Clara's value for console width, if present
+#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+
+#include <fstream>
+
+namespace Catch {
+
+ inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
+ inline void abortAfterX( ConfigData& config, int x ) {
+ if( x < 1 )
+ throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
+ config.abortAfter = x;
+ }
+ inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
+ inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
+
+ inline void addWarning( ConfigData& config, std::string const& _warning ) {
+ if( _warning == "NoAssertions" )
+ config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
+ else
+ throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
+ }
+ inline void setOrder( ConfigData& config, std::string const& order ) {
+ if( startsWith( "declared", order ) )
+ config.runOrder = RunTests::InDeclarationOrder;
+ else if( startsWith( "lexical", order ) )
+ config.runOrder = RunTests::InLexicographicalOrder;
+ else if( startsWith( "random", order ) )
+ config.runOrder = RunTests::InRandomOrder;
+ else
+ throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
+ }
+ inline void setRngSeed( ConfigData& config, std::string const& seed ) {
+ if( seed == "time" ) {
+ config.rngSeed = static_cast<unsigned int>( std::time(0) );
+ }
+ else {
+ std::stringstream ss;
+ ss << seed;
+ ss >> config.rngSeed;
+ if( ss.fail() )
+ throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
+ }
+ }
+ inline void setVerbosity( ConfigData& config, int level ) {
+ // !TBD: accept strings?
+ config.verbosity = static_cast<Verbosity::Level>( level );
+ }
+ inline void setShowDurations( ConfigData& config, bool _showDurations ) {
+ config.showDurations = _showDurations
+ ? ShowDurations::Always
+ : ShowDurations::Never;
+ }
+ inline void setUseColour( ConfigData& config, std::string const& value ) {
+ std::string mode = toLower( value );
+
+ if( mode == "yes" )
+ config.useColour = UseColour::Yes;
+ else if( mode == "no" )
+ config.useColour = UseColour::No;
+ else if( mode == "auto" )
+ config.useColour = UseColour::Auto;
+ else
+ throw std::runtime_error( "colour mode must be one of: auto, yes or no" );
+ }
+ inline void forceColour( ConfigData& config ) {
+ config.useColour = UseColour::Yes;
+ }
+ inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
+ std::ifstream f( _filename.c_str() );
+ if( !f.is_open() )
+ throw std::domain_error( "Unable to load input file: " + _filename );
+
+ std::string line;
+ while( std::getline( f, line ) ) {
+ line = trim(line);
+ if( !line.empty() && !startsWith( line, "#" ) )
+ addTestOrTags( config, "\"" + line + "\"," );
+ }
+ }
+
+ inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
+
+ using namespace Clara;
+ CommandLine<ConfigData> cli;
+
+ cli.bindProcessName( &ConfigData::processName );
+
+ cli["-?"]["-h"]["--help"]
+ .describe( "display usage information" )
+ .bind( &ConfigData::showHelp );
+
+ cli["-l"]["--list-tests"]
+ .describe( "list all/matching test cases" )
+ .bind( &ConfigData::listTests );
+
+ cli["-t"]["--list-tags"]
+ .describe( "list all/matching tags" )
+ .bind( &ConfigData::listTags );
+
+ cli["-s"]["--success"]
+ .describe( "include successful tests in output" )
+ .bind( &ConfigData::showSuccessfulTests );
+
+ cli["-b"]["--break"]
+ .describe( "break into debugger on failure" )
+ .bind( &ConfigData::shouldDebugBreak );
+
+ cli["-e"]["--nothrow"]
+ .describe( "skip exception tests" )
+ .bind( &ConfigData::noThrow );
+
+ cli["-i"]["--invisibles"]
+ .describe( "show invisibles (tabs, newlines)" )
+ .bind( &ConfigData::showInvisibles );
+
+ cli["-o"]["--out"]
+ .describe( "output filename" )
+ .bind( &ConfigData::outputFilename, "filename" );
+
+ cli["-r"]["--reporter"]
+// .placeholder( "name[:filename]" )
+ .describe( "reporter to use (defaults to console)" )
+ .bind( &addReporterName, "name" );
+
+ cli["-n"]["--name"]
+ .describe( "suite name" )
+ .bind( &ConfigData::name, "name" );
+
+ cli["-a"]["--abort"]
+ .describe( "abort at first failure" )
+ .bind( &abortAfterFirst );
+
+ cli["-x"]["--abortx"]
+ .describe( "abort after x failures" )
+ .bind( &abortAfterX, "no. failures" );
+
+ cli["-w"]["--warn"]
+ .describe( "enable warnings" )
+ .bind( &addWarning, "warning name" );
+
+// - needs updating if reinstated
+// cli.into( &setVerbosity )
+// .describe( "level of verbosity (0=no output)" )
+// .shortOpt( "v")
+// .longOpt( "verbosity" )
+// .placeholder( "level" );
+
+ cli[_]
+ .describe( "which test or tests to use" )
+ .bind( &addTestOrTags, "test name, pattern or tags" );
+
+ cli["-d"]["--durations"]
+ .describe( "show test durations" )
+ .bind( &setShowDurations, "yes|no" );
+
+ cli["-f"]["--input-file"]
+ .describe( "load test names to run from a file" )
+ .bind( &loadTestNamesFromFile, "filename" );
+
+ cli["-#"]["--filenames-as-tags"]
+ .describe( "adds a tag for the filename" )
+ .bind( &ConfigData::filenamesAsTags );
+
+ // Less common commands which don't have a short form
+ cli["--list-test-names-only"]
+ .describe( "list all/matching test cases names only" )
+ .bind( &ConfigData::listTestNamesOnly );
+
+ cli["--list-reporters"]
+ .describe( "list all reporters" )
+ .bind( &ConfigData::listReporters );
+
+ cli["--order"]
+ .describe( "test case order (defaults to decl)" )
+ .bind( &setOrder, "decl|lex|rand" );
+
+ cli["--rng-seed"]
+ .describe( "set a specific seed for random numbers" )
+ .bind( &setRngSeed, "'time'|number" );
+
+ cli["--force-colour"]
+ .describe( "force colourised output (deprecated)" )
+ .bind( &forceColour );
+
+ cli["--use-colour"]
+ .describe( "should output be colourised" )
+ .bind( &setUseColour, "yes|no" );
+
+ return cli;
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_list.hpp
+#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
+
+// #included from: catch_text.h
+#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
+
+#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
+
+#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
+// #included from: ../external/tbc_text_format.h
+// Only use header guard if we are not using an outer namespace
+#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
+# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+# endif
+# else
+# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
+# endif
+#endif
+#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+#include <string>
+#include <vector>
+#include <sstream>
+
+// Use optional outer namespace
+#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
+#endif
+
+namespace Tbc {
+
+#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
+ const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ struct TextAttributes {
+ TextAttributes()
+ : initialIndent( std::string::npos ),
+ indent( 0 ),
+ width( consoleWidth-1 ),
+ tabChar( '\t' )
+ {}
+
+ TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
+ TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
+ TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
+ TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
+
+ std::size_t initialIndent; // indent of first line, or npos
+ std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
+ std::size_t width; // maximum width of text, including indent. Longer text will wrap
+ char tabChar; // If this char is seen the indent is changed to current pos
+ };
+
+ class Text {
+ public:
+ Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
+ : attr( _attr )
+ {
+ std::string wrappableChars = " [({.,/|\\-";
+ std::size_t indent = _attr.initialIndent != std::string::npos
+ ? _attr.initialIndent
+ : _attr.indent;
+ std::string remainder = _str;
+
+ while( !remainder.empty() ) {
+ if( lines.size() >= 1000 ) {
+ lines.push_back( "... message truncated due to excessive size" );
+ return;
+ }
+ std::size_t tabPos = std::string::npos;
+ std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
+ std::size_t pos = remainder.find_first_of( '\n' );
+ if( pos <= width ) {
+ width = pos;
+ }
+ pos = remainder.find_last_of( _attr.tabChar, width );
+ if( pos != std::string::npos ) {
+ tabPos = pos;
+ if( remainder[width] == '\n' )
+ width--;
+ remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
+ }
+
+ if( width == remainder.size() ) {
+ spliceLine( indent, remainder, width );
+ }
+ else if( remainder[width] == '\n' ) {
+ spliceLine( indent, remainder, width );
+ if( width <= 1 || remainder.size() != 1 )
+ remainder = remainder.substr( 1 );
+ indent = _attr.indent;
+ }
+ else {
+ pos = remainder.find_last_of( wrappableChars, width );
+ if( pos != std::string::npos && pos > 0 ) {
+ spliceLine( indent, remainder, pos );
+ if( remainder[0] == ' ' )
+ remainder = remainder.substr( 1 );
+ }
+ else {
+ spliceLine( indent, remainder, width-1 );
+ lines.back() += "-";
+ }
+ if( lines.size() == 1 )
+ indent = _attr.indent;
+ if( tabPos != std::string::npos )
+ indent += tabPos;
+ }
+ }
+ }
+
+ void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
+ lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
+ _remainder = _remainder.substr( _pos );
+ }
+
+ typedef std::vector<std::string>::const_iterator const_iterator;
+
+ const_iterator begin() const { return lines.begin(); }
+ const_iterator end() const { return lines.end(); }
+ std::string const& last() const { return lines.back(); }
+ std::size_t size() const { return lines.size(); }
+ std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << *this;
+ return oss.str();
+ }
+
+ inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
+ for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
+ it != itEnd; ++it ) {
+ if( it != _text.begin() )
+ _stream << "\n";
+ _stream << *it;
+ }
+ return _stream;
+ }
+
+ private:
+ std::string str;
+ TextAttributes attr;
+ std::vector<std::string> lines;
+ };
+
+} // end namespace Tbc
+
+#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+} // end outer namespace
+#endif
+
+#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+
+namespace Catch {
+ using Tbc::Text;
+ using Tbc::TextAttributes;
+}
+
+// #included from: catch_console_colour.hpp
+#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
+
+namespace Catch {
+
+ struct Colour {
+ enum Code {
+ None = 0,
+
+ White,
+ Red,
+ Green,
+ Blue,
+ Cyan,
+ Yellow,
+ Grey,
+
+ Bright = 0x10,
+
+ BrightRed = Bright | Red,
+ BrightGreen = Bright | Green,
+ LightGrey = Bright | Grey,
+ BrightWhite = Bright | White,
+
+ // By intention
+ FileName = LightGrey,
+ Warning = Yellow,
+ ResultError = BrightRed,
+ ResultSuccess = BrightGreen,
+ ResultExpectedFailure = Warning,
+
+ Error = BrightRed,
+ Success = Green,
+
+ OriginalExpression = Cyan,
+ ReconstructedExpression = Yellow,
+
+ SecondaryText = LightGrey,
+ Headers = White
+ };
+
+ // Use constructed object for RAII guard
+ Colour( Code _colourCode );
+ Colour( Colour const& other );
+ ~Colour();
+
+ // Use static method for one-shot changes
+ static void use( Code _colourCode );
+
+ private:
+ bool m_moved;
+ };
+
+ inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
+
+} // end namespace Catch
+
+// #included from: catch_interfaces_reporter.h
+#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
+
+#include <string>
+#include <ostream>
+#include <map>
+#include <assert.h>
+
+namespace Catch
+{
+ struct ReporterConfig {
+ explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
+ : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
+
+ ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
+ : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
+
+ std::ostream& stream() const { return *m_stream; }
+ Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
+
+ private:
+ std::ostream* m_stream;
+ Ptr<IConfig const> m_fullConfig;
+ };
+
+ struct ReporterPreferences {
+ ReporterPreferences()
+ : shouldRedirectStdOut( false )
+ {}
+
+ bool shouldRedirectStdOut;
+ };
+
+ template<typename T>
+ struct LazyStat : Option<T> {
+ LazyStat() : used( false ) {}
+ LazyStat& operator=( T const& _value ) {
+ Option<T>::operator=( _value );
+ used = false;
+ return *this;
+ }
+ void reset() {
+ Option<T>::reset();
+ used = false;
+ }
+ bool used;
+ };
+
+ struct TestRunInfo {
+ TestRunInfo( std::string const& _name ) : name( _name ) {}
+ std::string name;
+ };
+ struct GroupInfo {
+ GroupInfo( std::string const& _name,
+ std::size_t _groupIndex,
+ std::size_t _groupsCount )
+ : name( _name ),
+ groupIndex( _groupIndex ),
+ groupsCounts( _groupsCount )
+ {}
+
+ std::string name;
+ std::size_t groupIndex;
+ std::size_t groupsCounts;
+ };
+
+ struct AssertionStats {
+ AssertionStats( AssertionResult const& _assertionResult,
+ std::vector<MessageInfo> const& _infoMessages,
+ Totals const& _totals )
+ : assertionResult( _assertionResult ),
+ infoMessages( _infoMessages ),
+ totals( _totals )
+ {
+ if( assertionResult.hasMessage() ) {
+ // Copy message into messages list.
+ // !TBD This should have been done earlier, somewhere
+ MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
+ builder << assertionResult.getMessage();
+ builder.m_info.message = builder.m_stream.str();
+
+ infoMessages.push_back( builder.m_info );
+ }
+ }
+ virtual ~AssertionStats();
+
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ AssertionStats( AssertionStats const& ) = default;
+ AssertionStats( AssertionStats && ) = default;
+ AssertionStats& operator = ( AssertionStats const& ) = default;
+ AssertionStats& operator = ( AssertionStats && ) = default;
+# endif
+
+ AssertionResult assertionResult;
+ std::vector<MessageInfo> infoMessages;
+ Totals totals;
+ };
+
+ struct SectionStats {
+ SectionStats( SectionInfo const& _sectionInfo,
+ Counts const& _assertions,
+ double _durationInSeconds,
+ bool _missingAssertions )
+ : sectionInfo( _sectionInfo ),
+ assertions( _assertions ),
+ durationInSeconds( _durationInSeconds ),
+ missingAssertions( _missingAssertions )
+ {}
+ virtual ~SectionStats();
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ SectionStats( SectionStats const& ) = default;
+ SectionStats( SectionStats && ) = default;
+ SectionStats& operator = ( SectionStats const& ) = default;
+ SectionStats& operator = ( SectionStats && ) = default;
+# endif
+
+ SectionInfo sectionInfo;
+ Counts assertions;
+ double durationInSeconds;
+ bool missingAssertions;
+ };
+
+ struct TestCaseStats {
+ TestCaseStats( TestCaseInfo const& _testInfo,
+ Totals const& _totals,
+ std::string const& _stdOut,
+ std::string const& _stdErr,
+ bool _aborting )
+ : testInfo( _testInfo ),
+ totals( _totals ),
+ stdOut( _stdOut ),
+ stdErr( _stdErr ),
+ aborting( _aborting )
+ {}
+ virtual ~TestCaseStats();
+
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ TestCaseStats( TestCaseStats const& ) = default;
+ TestCaseStats( TestCaseStats && ) = default;
+ TestCaseStats& operator = ( TestCaseStats const& ) = default;
+ TestCaseStats& operator = ( TestCaseStats && ) = default;
+# endif
+
+ TestCaseInfo testInfo;
+ Totals totals;
+ std::string stdOut;
+ std::string stdErr;
+ bool aborting;
+ };
+
+ struct TestGroupStats {
+ TestGroupStats( GroupInfo const& _groupInfo,
+ Totals const& _totals,
+ bool _aborting )
+ : groupInfo( _groupInfo ),
+ totals( _totals ),
+ aborting( _aborting )
+ {}
+ TestGroupStats( GroupInfo const& _groupInfo )
+ : groupInfo( _groupInfo ),
+ aborting( false )
+ {}
+ virtual ~TestGroupStats();
+
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ TestGroupStats( TestGroupStats const& ) = default;
+ TestGroupStats( TestGroupStats && ) = default;
+ TestGroupStats& operator = ( TestGroupStats const& ) = default;
+ TestGroupStats& operator = ( TestGroupStats && ) = default;
+# endif
+
+ GroupInfo groupInfo;
+ Totals totals;
+ bool aborting;
+ };
+
+ struct TestRunStats {
+ TestRunStats( TestRunInfo const& _runInfo,
+ Totals const& _totals,
+ bool _aborting )
+ : runInfo( _runInfo ),
+ totals( _totals ),
+ aborting( _aborting )
+ {}
+ virtual ~TestRunStats();
+
+# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ TestRunStats( TestRunStats const& _other )
+ : runInfo( _other.runInfo ),
+ totals( _other.totals ),
+ aborting( _other.aborting )
+ {}
+# else
+ TestRunStats( TestRunStats const& ) = default;
+ TestRunStats( TestRunStats && ) = default;
+ TestRunStats& operator = ( TestRunStats const& ) = default;
+ TestRunStats& operator = ( TestRunStats && ) = default;
+# endif
+
+ TestRunInfo runInfo;
+ Totals totals;
+ bool aborting;
+ };
+
+ struct IStreamingReporter : IShared {
+ virtual ~IStreamingReporter();
+
+ // Implementing class must also provide the following static method:
+ // static std::string getDescription();
+
+ virtual ReporterPreferences getPreferences() const = 0;
+
+ virtual void noMatchingTestCases( std::string const& spec ) = 0;
+
+ virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
+
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
+
+ virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
+
+ // The return value indicates if the messages buffer should be cleared:
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
+
+ virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
+ virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
+
+ virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
+ };
+
+ struct IReporterFactory : IShared {
+ virtual ~IReporterFactory();
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
+ virtual std::string getDescription() const = 0;
+ };
+
+ struct IReporterRegistry {
+ typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
+ typedef std::vector<Ptr<IReporterFactory> > Listeners;
+
+ virtual ~IReporterRegistry();
+ virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
+ virtual FactoryMap const& getFactories() const = 0;
+ virtual Listeners const& getListeners() const = 0;
+ };
+
+ Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
+
+}
+
+#include <limits>
+#include <algorithm>
+
+namespace Catch {
+
+ inline std::size_t listTests( Config const& config ) {
+
+ TestSpec testSpec = config.testSpec();
+ if( config.testSpec().hasFilters() )
+ Catch::cout() << "Matching test cases:\n";
+ else {
+ Catch::cout() << "All available test cases:\n";
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ }
+
+ std::size_t matchedTests = 0;
+ TextAttributes nameAttr, tagsAttr;
+ nameAttr.setInitialIndent( 2 ).setIndent( 4 );
+ tagsAttr.setIndent( 6 );
+
+ std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ matchedTests++;
+ TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
+ Colour::Code colour = testCaseInfo.isHidden()
+ ? Colour::SecondaryText
+ : Colour::None;
+ Colour colourGuard( colour );
+
+ Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
+ if( !testCaseInfo.tags.empty() )
+ Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
+ }
+
+ if( !config.testSpec().hasFilters() )
+ Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
+ else
+ Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
+ return matchedTests;
+ }
+
+ inline std::size_t listTestsNamesOnly( Config const& config ) {
+ TestSpec testSpec = config.testSpec();
+ if( !config.testSpec().hasFilters() )
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ std::size_t matchedTests = 0;
+ std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ matchedTests++;
+ TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
+ Catch::cout() << testCaseInfo.name << std::endl;
+ }
+ return matchedTests;
+ }
+
+ struct TagInfo {
+ TagInfo() : count ( 0 ) {}
+ void add( std::string const& spelling ) {
+ ++count;
+ spellings.insert( spelling );
+ }
+ std::string all() const {
+ std::string out;
+ for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
+ it != itEnd;
+ ++it )
+ out += "[" + *it + "]";
+ return out;
+ }
+ std::set<std::string> spellings;
+ std::size_t count;
+ };
+
+ inline std::size_t listTags( Config const& config ) {
+ TestSpec testSpec = config.testSpec();
+ if( config.testSpec().hasFilters() )
+ Catch::cout() << "Tags for matching test cases:\n";
+ else {
+ Catch::cout() << "All available tags:\n";
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ }
+
+ std::map<std::string, TagInfo> tagCounts;
+
+ std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
+ tagItEnd = it->getTestCaseInfo().tags.end();
+ tagIt != tagItEnd;
+ ++tagIt ) {
+ std::string tagName = *tagIt;
+ std::string lcaseTagName = toLower( tagName );
+ std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
+ if( countIt == tagCounts.end() )
+ countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
+ countIt->second.add( tagName );
+ }
+ }
+
+ for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
+ countItEnd = tagCounts.end();
+ countIt != countItEnd;
+ ++countIt ) {
+ std::ostringstream oss;
+ oss << " " << std::setw(2) << countIt->second.count << " ";
+ Text wrapper( countIt->second.all(), TextAttributes()
+ .setInitialIndent( 0 )
+ .setIndent( oss.str().size() )
+ .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
+ Catch::cout() << oss.str() << wrapper << "\n";
+ }
+ Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
+ return tagCounts.size();
+ }
+
+ inline std::size_t listReporters( Config const& /*config*/ ) {
+ Catch::cout() << "Available reporters:\n";
+ IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
+ IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
+ std::size_t maxNameLen = 0;
+ for(it = itBegin; it != itEnd; ++it )
+ maxNameLen = (std::max)( maxNameLen, it->first.size() );
+
+ for(it = itBegin; it != itEnd; ++it ) {
+ Text wrapper( it->second->getDescription(), TextAttributes()
+ .setInitialIndent( 0 )
+ .setIndent( 7+maxNameLen )
+ .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
+ Catch::cout() << " "
+ << it->first
+ << ":"
+ << std::string( maxNameLen - it->first.size() + 2, ' ' )
+ << wrapper << "\n";
+ }
+ Catch::cout() << std::endl;
+ return factories.size();
+ }
+
+ inline Option<std::size_t> list( Config const& config ) {
+ Option<std::size_t> listedCount;
+ if( config.listTests() )
+ listedCount = listedCount.valueOr(0) + listTests( config );
+ if( config.listTestNamesOnly() )
+ listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
+ if( config.listTags() )
+ listedCount = listedCount.valueOr(0) + listTags( config );
+ if( config.listReporters() )
+ listedCount = listedCount.valueOr(0) + listReporters( config );
+ return listedCount;
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_run_context.hpp
+#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
+
+// #included from: catch_test_case_tracker.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
+
+#include <map>
+#include <string>
+#include <assert.h>
+#include <vector>
+
+namespace Catch {
+namespace TestCaseTracking {
+
+ struct ITracker : SharedImpl<> {
+ virtual ~ITracker();
+
+ // static queries
+ virtual std::string name() const = 0;
+
+ // dynamic queries
+ virtual bool isComplete() const = 0; // Successfully completed or failed
+ virtual bool isSuccessfullyCompleted() const = 0;
+ virtual bool isOpen() const = 0; // Started but not complete
+ virtual bool hasChildren() const = 0;
+
+ virtual ITracker& parent() = 0;
+
+ // actions
+ virtual void close() = 0; // Successfully complete
+ virtual void fail() = 0;
+ virtual void markAsNeedingAnotherRun() = 0;
+
+ virtual void addChild( Ptr<ITracker> const& child ) = 0;
+ virtual ITracker* findChild( std::string const& name ) = 0;
+ virtual void openChild() = 0;
+ };
+
+ class TrackerContext {
+
+ enum RunState {
+ NotStarted,
+ Executing,
+ CompletedCycle
+ };
+
+ Ptr<ITracker> m_rootTracker;
+ ITracker* m_currentTracker;
+ RunState m_runState;
+
+ public:
+
+ static TrackerContext& instance() {
+ static TrackerContext s_instance;
+ return s_instance;
+ }
+
+ TrackerContext()
+ : m_currentTracker( CATCH_NULL ),
+ m_runState( NotStarted )
+ {}
+
+ ITracker& startRun();
+
+ void endRun() {
+ m_rootTracker.reset();
+ m_currentTracker = CATCH_NULL;
+ m_runState = NotStarted;
+ }
+
+ void startCycle() {
+ m_currentTracker = m_rootTracker.get();
+ m_runState = Executing;
+ }
+ void completeCycle() {
+ m_runState = CompletedCycle;
+ }
+
+ bool completedCycle() const {
+ return m_runState == CompletedCycle;
+ }
+ ITracker& currentTracker() {
+ return *m_currentTracker;
+ }
+ void setCurrentTracker( ITracker* tracker ) {
+ m_currentTracker = tracker;
+ }
+ };
+
+ class TrackerBase : public ITracker {
+ protected:
+ enum CycleState {
+ NotStarted,
+ Executing,
+ ExecutingChildren,
+ NeedsAnotherRun,
+ CompletedSuccessfully,
+ Failed
+ };
+ class TrackerHasName {
+ std::string m_name;
+ public:
+ TrackerHasName( std::string const& name ) : m_name( name ) {}
+ bool operator ()( Ptr<ITracker> const& tracker ) {
+ return tracker->name() == m_name;
+ }
+ };
+ typedef std::vector<Ptr<ITracker> > Children;
+ std::string m_name;
+ TrackerContext& m_ctx;
+ ITracker* m_parent;
+ Children m_children;
+ CycleState m_runState;
+ public:
+ TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent )
+ : m_name( name ),
+ m_ctx( ctx ),
+ m_parent( parent ),
+ m_runState( NotStarted )
+ {}
+ virtual ~TrackerBase();
+
+ virtual std::string name() const CATCH_OVERRIDE {
+ return m_name;
+ }
+ virtual bool isComplete() const CATCH_OVERRIDE {
+ return m_runState == CompletedSuccessfully || m_runState == Failed;
+ }
+ virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {
+ return m_runState == CompletedSuccessfully;
+ }
+ virtual bool isOpen() const CATCH_OVERRIDE {
+ return m_runState != NotStarted && !isComplete();
+ }
+ virtual bool hasChildren() const CATCH_OVERRIDE {
+ return !m_children.empty();
+ }
+
+ virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {
+ m_children.push_back( child );
+ }
+
+ virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE {
+ Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );
+ return( it != m_children.end() )
+ ? it->get()
+ : CATCH_NULL;
+ }
+ virtual ITracker& parent() CATCH_OVERRIDE {
+ assert( m_parent ); // Should always be non-null except for root
+ return *m_parent;
+ }
+
+ virtual void openChild() CATCH_OVERRIDE {
+ if( m_runState != ExecutingChildren ) {
+ m_runState = ExecutingChildren;
+ if( m_parent )
+ m_parent->openChild();
+ }
+ }
+ void open() {
+ m_runState = Executing;
+ moveToThis();
+ if( m_parent )
+ m_parent->openChild();
+ }
+
+ virtual void close() CATCH_OVERRIDE {
+
+ // Close any still open children (e.g. generators)
+ while( &m_ctx.currentTracker() != this )
+ m_ctx.currentTracker().close();
+
+ switch( m_runState ) {
+ case NotStarted:
+ case CompletedSuccessfully:
+ case Failed:
+ throw std::logic_error( "Illogical state" );
+
+ case NeedsAnotherRun:
+ break;;
+
+ case Executing:
+ m_runState = CompletedSuccessfully;
+ break;
+ case ExecutingChildren:
+ if( m_children.empty() || m_children.back()->isComplete() )
+ m_runState = CompletedSuccessfully;
+ break;
+
+ default:
+ throw std::logic_error( "Unexpected state" );
+ }
+ moveToParent();
+ m_ctx.completeCycle();
+ }
+ virtual void fail() CATCH_OVERRIDE {
+ m_runState = Failed;
+ if( m_parent )
+ m_parent->markAsNeedingAnotherRun();
+ moveToParent();
+ m_ctx.completeCycle();
+ }
+ virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {
+ m_runState = NeedsAnotherRun;
+ }
+ private:
+ void moveToParent() {
+ assert( m_parent );
+ m_ctx.setCurrentTracker( m_parent );
+ }
+ void moveToThis() {
+ m_ctx.setCurrentTracker( this );
+ }
+ };
+
+ class SectionTracker : public TrackerBase {
+ public:
+ SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent )
+ : TrackerBase( name, ctx, parent )
+ {}
+ virtual ~SectionTracker();
+
+ static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
+ SectionTracker* section = CATCH_NULL;
+
+ ITracker& currentTracker = ctx.currentTracker();
+ if( ITracker* childTracker = currentTracker.findChild( name ) ) {
+ section = dynamic_cast<SectionTracker*>( childTracker );
+ assert( section );
+ }
+ else {
+ section = new SectionTracker( name, ctx, &currentTracker );
+ currentTracker.addChild( section );
+ }
+ if( !ctx.completedCycle() && !section->isComplete() ) {
+
+ section->open();
+ }
+ return *section;
+ }
+ };
+
+ class IndexTracker : public TrackerBase {
+ int m_size;
+ int m_index;
+ public:
+ IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size )
+ : TrackerBase( name, ctx, parent ),
+ m_size( size ),
+ m_index( -1 )
+ {}
+ virtual ~IndexTracker();
+
+ static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {
+ IndexTracker* tracker = CATCH_NULL;
+
+ ITracker& currentTracker = ctx.currentTracker();
+ if( ITracker* childTracker = currentTracker.findChild( name ) ) {
+ tracker = dynamic_cast<IndexTracker*>( childTracker );
+ assert( tracker );
+ }
+ else {
+ tracker = new IndexTracker( name, ctx, &currentTracker, size );
+ currentTracker.addChild( tracker );
+ }
+
+ if( !ctx.completedCycle() && !tracker->isComplete() ) {
+ if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
+ tracker->moveNext();
+ tracker->open();
+ }
+
+ return *tracker;
+ }
+
+ int index() const { return m_index; }
+
+ void moveNext() {
+ m_index++;
+ m_children.clear();
+ }
+
+ virtual void close() CATCH_OVERRIDE {
+ TrackerBase::close();
+ if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
+ m_runState = Executing;
+ }
+ };
+
+ inline ITracker& TrackerContext::startRun() {
+ m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL );
+ m_currentTracker = CATCH_NULL;
+ m_runState = Executing;
+ return *m_rootTracker;
+ }
+
+} // namespace TestCaseTracking
+
+using TestCaseTracking::ITracker;
+using TestCaseTracking::TrackerContext;
+using TestCaseTracking::SectionTracker;
+using TestCaseTracking::IndexTracker;
+
+} // namespace Catch
+
+// #included from: catch_fatal_condition.hpp
+#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
+
+namespace Catch {
+
+ // Report the error condition then exit the process
+ inline void fatal( std::string const& message, int exitCode ) {
+ IContext& context = Catch::getCurrentContext();
+ IResultCapture* resultCapture = context.getResultCapture();
+ resultCapture->handleFatalErrorCondition( message );
+
+ if( Catch::alwaysTrue() ) // avoids "no return" warnings
+ exit( exitCode );
+ }
+
+} // namespace Catch
+
+#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
+
+namespace Catch {
+
+ struct FatalConditionHandler {
+ void reset() {}
+ };
+
+} // namespace Catch
+
+#else // Not Windows - assumed to be POSIX compatible //////////////////////////
+
+#include <signal.h>
+
+namespace Catch {
+
+ struct SignalDefs { int id; const char* name; };
+ extern SignalDefs signalDefs[];
+ SignalDefs signalDefs[] = {
+ { SIGINT, "SIGINT - Terminal interrupt signal" },
+ { SIGILL, "SIGILL - Illegal instruction signal" },
+ { SIGFPE, "SIGFPE - Floating point error signal" },
+ { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
+ { SIGTERM, "SIGTERM - Termination request signal" },
+ { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
+ };
+
+ struct FatalConditionHandler {
+
+ static void handleSignal( int sig ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ if( sig == signalDefs[i].id )
+ fatal( signalDefs[i].name, -sig );
+ fatal( "<unknown signal>", -sig );
+ }
+
+ FatalConditionHandler() : m_isSet( true ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ signal( signalDefs[i].id, handleSignal );
+ }
+ ~FatalConditionHandler() {
+ reset();
+ }
+ void reset() {
+ if( m_isSet ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ signal( signalDefs[i].id, SIG_DFL );
+ m_isSet = false;
+ }
+ }
+
+ bool m_isSet;
+ };
+
+} // namespace Catch
+
+#endif // not Windows
+
+#include <set>
+#include <string>
+
+namespace Catch {
+
+ class StreamRedirect {
+
+ public:
+ StreamRedirect( std::ostream& stream, std::string& targetString )
+ : m_stream( stream ),
+ m_prevBuf( stream.rdbuf() ),
+ m_targetString( targetString )
+ {
+ stream.rdbuf( m_oss.rdbuf() );
+ }
+
+ ~StreamRedirect() {
+ m_targetString += m_oss.str();
+ m_stream.rdbuf( m_prevBuf );
+ }
+
+ private:
+ std::ostream& m_stream;
+ std::streambuf* m_prevBuf;
+ std::ostringstream m_oss;
+ std::string& m_targetString;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class RunContext : public IResultCapture, public IRunner {
+
+ RunContext( RunContext const& );
+ void operator =( RunContext const& );
+
+ public:
+
+ explicit RunContext( Ptr<IConfig const> const& _config, Ptr<IStreamingReporter> const& reporter )
+ : m_runInfo( _config->name() ),
+ m_context( getCurrentMutableContext() ),
+ m_activeTestCase( CATCH_NULL ),
+ m_config( _config ),
+ m_reporter( reporter )
+ {
+ m_context.setRunner( this );
+ m_context.setConfig( m_config );
+ m_context.setResultCapture( this );
+ m_reporter->testRunStarting( m_runInfo );
+ }
+
+ virtual ~RunContext() {
+ m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
+ }
+
+ void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
+ m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
+ }
+ void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
+ m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
+ }
+
+ Totals runTest( TestCase const& testCase ) {
+ Totals prevTotals = m_totals;
+
+ std::string redirectedCout;
+ std::string redirectedCerr;
+
+ TestCaseInfo testInfo = testCase.getTestCaseInfo();
+
+ m_reporter->testCaseStarting( testInfo );
+
+ m_activeTestCase = &testCase;
+
+ do {
+ m_trackerContext.startRun();
+ do {
+ m_trackerContext.startCycle();
+ m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name );
+ runCurrentTest( redirectedCout, redirectedCerr );
+ }
+ while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
+ }
+ // !TBD: deprecated - this will be replaced by indexed trackers
+ while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
+
+ Totals deltaTotals = m_totals.delta( prevTotals );
+ if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {
+ deltaTotals.assertions.failed++;
+ deltaTotals.testCases.passed--;
+ deltaTotals.testCases.failed++;
+ }
+ m_totals.testCases += deltaTotals.testCases;
+ m_reporter->testCaseEnded( TestCaseStats( testInfo,
+ deltaTotals,
+ redirectedCout,
+ redirectedCerr,
+ aborting() ) );
+
+ m_activeTestCase = CATCH_NULL;
+ m_testCaseTracker = CATCH_NULL;
+
+ return deltaTotals;
+ }
+
+ Ptr<IConfig const> config() const {
+ return m_config;
+ }
+
+ private: // IResultCapture
+
+ virtual void assertionEnded( AssertionResult const& result ) {
+ if( result.getResultType() == ResultWas::Ok ) {
+ m_totals.assertions.passed++;
+ }
+ else if( !result.isOk() ) {
+ m_totals.assertions.failed++;
+ }
+
+ if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
+ m_messages.clear();
+
+ // Reset working state
+ m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
+ m_lastResult = result;
+ }
+
+ virtual bool sectionStarted (
+ SectionInfo const& sectionInfo,
+ Counts& assertions
+ )
+ {
+ std::ostringstream oss;
+ oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
+
+ ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() );
+ if( !sectionTracker.isOpen() )
+ return false;
+ m_activeSections.push_back( &sectionTracker );
+
+ m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
+
+ m_reporter->sectionStarting( sectionInfo );
+
+ assertions = m_totals.assertions;
+
+ return true;
+ }
+ bool testForMissingAssertions( Counts& assertions ) {
+ if( assertions.total() != 0 )
+ return false;
+ if( !m_config->warnAboutMissingAssertions() )
+ return false;
+ if( m_trackerContext.currentTracker().hasChildren() )
+ return false;
+ m_totals.assertions.failed++;
+ assertions.failed++;
+ return true;
+ }
+
+ virtual void sectionEnded( SectionEndInfo const& endInfo ) {
+ Counts assertions = m_totals.assertions - endInfo.prevAssertions;
+ bool missingAssertions = testForMissingAssertions( assertions );
+
+ if( !m_activeSections.empty() ) {
+ m_activeSections.back()->close();
+ m_activeSections.pop_back();
+ }
+
+ m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
+ m_messages.clear();
+ }
+
+ virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {
+ if( m_unfinishedSections.empty() )
+ m_activeSections.back()->fail();
+ else
+ m_activeSections.back()->close();
+ m_activeSections.pop_back();
+
+ m_unfinishedSections.push_back( endInfo );
+ }
+
+ virtual void pushScopedMessage( MessageInfo const& message ) {
+ m_messages.push_back( message );
+ }
+
+ virtual void popScopedMessage( MessageInfo const& message ) {
+ m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
+ }
+
+ virtual std::string getCurrentTestName() const {
+ return m_activeTestCase
+ ? m_activeTestCase->getTestCaseInfo().name
+ : "";
+ }
+
+ virtual const AssertionResult* getLastResult() const {
+ return &m_lastResult;
+ }
+
+ virtual void handleFatalErrorCondition( std::string const& message ) {
+ ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
+ resultBuilder.setResultType( ResultWas::FatalErrorCondition );
+ resultBuilder << message;
+ resultBuilder.captureExpression();
+
+ handleUnfinishedSections();
+
+ // Recreate section for test case (as we will lose the one that was in scope)
+ TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+ SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
+
+ Counts assertions;
+ assertions.failed = 1;
+ SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
+ m_reporter->sectionEnded( testCaseSectionStats );
+
+ TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
+
+ Totals deltaTotals;
+ deltaTotals.testCases.failed = 1;
+ m_reporter->testCaseEnded( TestCaseStats( testInfo,
+ deltaTotals,
+ "",
+ "",
+ false ) );
+ m_totals.testCases.failed++;
+ testGroupEnded( "", m_totals, 1, 1 );
+ m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
+ }
+
+ public:
+ // !TBD We need to do this another way!
+ bool aborting() const {
+ return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
+ }
+
+ private:
+
+ void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
+ TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+ SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
+ m_reporter->sectionStarting( testCaseSection );
+ Counts prevAssertions = m_totals.assertions;
+ double duration = 0;
+ try {
+ m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
+
+ seedRng( *m_config );
+
+ Timer timer;
+ timer.start();
+ if( m_reporter->getPreferences().shouldRedirectStdOut ) {
+ StreamRedirect coutRedir( Catch::cout(), redirectedCout );
+ StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
+ invokeActiveTestCase();
+ }
+ else {
+ invokeActiveTestCase();
+ }
+ duration = timer.getElapsedSeconds();
+ }
+ catch( TestFailureException& ) {
+ // This just means the test was aborted due to failure
+ }
+ catch(...) {
+ makeUnexpectedResultBuilder().useActiveException();
+ }
+ m_testCaseTracker->close();
+ handleUnfinishedSections();
+ m_messages.clear();
+
+ Counts assertions = m_totals.assertions - prevAssertions;
+ bool missingAssertions = testForMissingAssertions( assertions );
+
+ if( testCaseInfo.okToFail() ) {
+ std::swap( assertions.failedButOk, assertions.failed );
+ m_totals.assertions.failed -= assertions.failedButOk;
+ m_totals.assertions.failedButOk += assertions.failedButOk;
+ }
+
+ SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
+ m_reporter->sectionEnded( testCaseSectionStats );
+ }
+
+ void invokeActiveTestCase() {
+ FatalConditionHandler fatalConditionHandler; // Handle signals
+ m_activeTestCase->invoke();
+ fatalConditionHandler.reset();
+ }
+
+ private:
+
+ ResultBuilder makeUnexpectedResultBuilder() const {
+ return ResultBuilder( m_lastAssertionInfo.macroName.c_str(),
+ m_lastAssertionInfo.lineInfo,
+ m_lastAssertionInfo.capturedExpression.c_str(),
+ m_lastAssertionInfo.resultDisposition );
+ }
+
+ void handleUnfinishedSections() {
+ // If sections ended prematurely due to an exception we stored their
+ // infos here so we can tear them down outside the unwind process.
+ for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
+ itEnd = m_unfinishedSections.rend();
+ it != itEnd;
+ ++it )
+ sectionEnded( *it );
+ m_unfinishedSections.clear();
+ }
+
+ TestRunInfo m_runInfo;
+ IMutableContext& m_context;
+ TestCase const* m_activeTestCase;
+ ITracker* m_testCaseTracker;
+ ITracker* m_currentSectionTracker;
+ AssertionResult m_lastResult;
+
+ Ptr<IConfig const> m_config;
+ Totals m_totals;
+ Ptr<IStreamingReporter> m_reporter;
+ std::vector<MessageInfo> m_messages;
+ AssertionInfo m_lastAssertionInfo;
+ std::vector<SectionEndInfo> m_unfinishedSections;
+ std::vector<ITracker*> m_activeSections;
+ TrackerContext m_trackerContext;
+ };
+
+ IResultCapture& getResultCapture() {
+ if( IResultCapture* capture = getCurrentContext().getResultCapture() )
+ return *capture;
+ else
+ throw std::logic_error( "No result capture instance" );
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_version.h
+#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
+
+namespace Catch {
+
+ // Versioning information
+ struct Version {
+ Version( unsigned int _majorVersion,
+ unsigned int _minorVersion,
+ unsigned int _patchNumber,
+ std::string const& _branchName,
+ unsigned int _buildNumber );
+
+ unsigned int const majorVersion;
+ unsigned int const minorVersion;
+ unsigned int const patchNumber;
+
+ // buildNumber is only used if branchName is not null
+ std::string const branchName;
+ unsigned int const buildNumber;
+
+ friend std::ostream& operator << ( std::ostream& os, Version const& version );
+
+ private:
+ void operator=( Version const& );
+ };
+
+ extern Version libraryVersion;
+}
+
+#include <fstream>
+#include <stdlib.h>
+#include <limits>
+
+namespace Catch {
+
+ Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {
+ Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
+ if( !reporter ) {
+ std::ostringstream oss;
+ oss << "No reporter registered with name: '" << reporterName << "'";
+ throw std::domain_error( oss.str() );
+ }
+ return reporter;
+ }
+
+ Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
+ std::vector<std::string> reporters = config->getReporterNames();
+ if( reporters.empty() )
+ reporters.push_back( "console" );
+
+ Ptr<IStreamingReporter> reporter;
+ for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
+ it != itEnd;
+ ++it )
+ reporter = addReporter( reporter, createReporter( *it, config ) );
+ return reporter;
+ }
+ Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
+ IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
+ for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
+ it != itEnd;
+ ++it )
+ reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
+ return reporters;
+ }
+
+ Totals runTests( Ptr<Config> const& config ) {
+
+ Ptr<IConfig const> iconfig = config.get();
+
+ Ptr<IStreamingReporter> reporter = makeReporter( config );
+ reporter = addListeners( iconfig, reporter );
+
+ RunContext context( iconfig, reporter );
+
+ Totals totals;
+
+ context.testGroupStarting( config->name(), 1, 1 );
+
+ TestSpec testSpec = config->testSpec();
+ if( !testSpec.hasFilters() )
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
+
+ std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
+ for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
+ it != itEnd;
+ ++it ) {
+ if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
+ totals += context.runTest( *it );
+ else
+ reporter->skipTest( *it );
+ }
+
+ context.testGroupEnded( iconfig->name(), totals, 1, 1 );
+ return totals;
+ }
+
+ void applyFilenamesAsTags( IConfig const& config ) {
+ std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
+ for(std::size_t i = 0; i < tests.size(); ++i ) {
+ TestCase& test = const_cast<TestCase&>( tests[i] );
+ std::set<std::string> tags = test.tags;
+
+ std::string filename = test.lineInfo.file;
+ std::string::size_type lastSlash = filename.find_last_of( "\\/" );
+ if( lastSlash != std::string::npos )
+ filename = filename.substr( lastSlash+1 );
+
+ std::string::size_type lastDot = filename.find_last_of( "." );
+ if( lastDot != std::string::npos )
+ filename = filename.substr( 0, lastDot );
+
+ tags.insert( "#" + filename );
+ setTags( test, tags );
+ }
+ }
+
+ class Session : NonCopyable {
+ static bool alreadyInstantiated;
+
+ public:
+
+ struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
+
+ Session()
+ : m_cli( makeCommandLineParser() ) {
+ if( alreadyInstantiated ) {
+ std::string msg = "Only one instance of Catch::Session can ever be used";
+ Catch::cerr() << msg << std::endl;
+ throw std::logic_error( msg );
+ }
+ alreadyInstantiated = true;
+ }
+ ~Session() {
+ Catch::cleanUp();
+ }
+
+ void showHelp( std::string const& processName ) {
+ Catch::cout() << "\nCatch v" << libraryVersion << "\n";
+
+ m_cli.usage( Catch::cout(), processName );
+ Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
+ }
+
+ int applyCommandLine( int argc, char const* argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
+ try {
+ m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
+ m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
+ if( m_configData.showHelp )
+ showHelp( m_configData.processName );
+ m_config.reset();
+ }
+ catch( std::exception& ex ) {
+ {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr()
+ << "\nError(s) in input:\n"
+ << Text( ex.what(), TextAttributes().setIndent(2) )
+ << "\n\n";
+ }
+ m_cli.usage( Catch::cout(), m_configData.processName );
+ return (std::numeric_limits<int>::max)();
+ }
+ return 0;
+ }
+
+ void useConfigData( ConfigData const& _configData ) {
+ m_configData = _configData;
+ m_config.reset();
+ }
+
+ int run( int argc, char const* argv[] ) {
+
+ int returnCode = applyCommandLine( argc, argv );
+ if( returnCode == 0 )
+ returnCode = run();
+ return returnCode;
+ }
+ int run( int argc, char* argv[] ) {
+ return run( argc, const_cast<char const**>( argv ) );
+ }
+
+ int run() {
+ if( m_configData.showHelp )
+ return 0;
+
+ try
+ {
+ config(); // Force config to be constructed
+
+ seedRng( *m_config );
+
+ if( m_configData.filenamesAsTags )
+ applyFilenamesAsTags( *m_config );
+
+ // Handle list request
+ if( Option<std::size_t> listed = list( config() ) )
+ return static_cast<int>( *listed );
+
+ return static_cast<int>( runTests( m_config ).assertions.failed );
+ }
+ catch( std::exception& ex ) {
+ Catch::cerr() << ex.what() << std::endl;
+ return (std::numeric_limits<int>::max)();
+ }
+ }
+
+ Clara::CommandLine<ConfigData> const& cli() const {
+ return m_cli;
+ }
+ std::vector<Clara::Parser::Token> const& unusedTokens() const {
+ return m_unusedTokens;
+ }
+ ConfigData& configData() {
+ return m_configData;
+ }
+ Config& config() {
+ if( !m_config )
+ m_config = new Config( m_configData );
+ return *m_config;
+ }
+ private:
+ Clara::CommandLine<ConfigData> m_cli;
+ std::vector<Clara::Parser::Token> m_unusedTokens;
+ ConfigData m_configData;
+ Ptr<Config> m_config;
+ };
+
+ bool Session::alreadyInstantiated = false;
+
+} // end namespace Catch
+
+// #included from: catch_registry_hub.hpp
+#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
+
+// #included from: catch_test_case_registry_impl.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
+
+#include <vector>
+#include <set>
+#include <sstream>
+#include <iostream>
+#include <algorithm>
+
+namespace Catch {
+
+ struct LexSort {
+ bool operator() (TestCase i,TestCase j) const { return (i<j);}
+ };
+ struct RandomNumberGenerator {
+ int operator()( int n ) const { return std::rand() % n; }
+ };
+
+ inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
+
+ std::vector<TestCase> sorted = unsortedTestCases;
+
+ switch( config.runOrder() ) {
+ case RunTests::InLexicographicalOrder:
+ std::sort( sorted.begin(), sorted.end(), LexSort() );
+ break;
+ case RunTests::InRandomOrder:
+ {
+ seedRng( config );
+
+ RandomNumberGenerator rng;
+ std::random_shuffle( sorted.begin(), sorted.end(), rng );
+ }
+ break;
+ case RunTests::InDeclarationOrder:
+ // already in declaration order
+ break;
+ }
+ return sorted;
+ }
+ bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
+ return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
+ }
+
+ void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
+ std::set<TestCase> seenFunctions;
+ for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();
+ it != itEnd;
+ ++it ) {
+ std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
+ if( !prev.second ){
+ Catch::cerr()
+ << Colour( Colour::Red )
+ << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
+ << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
+ << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
+ exit(1);
+ }
+ }
+ }
+
+ std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
+ std::vector<TestCase> filtered;
+ filtered.reserve( testCases.size() );
+ for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
+ it != itEnd;
+ ++it )
+ if( matchTest( *it, testSpec, config ) )
+ filtered.push_back( *it );
+ return filtered;
+ }
+ std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
+ return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
+ }
+
+ class TestRegistry : public ITestCaseRegistry {
+ public:
+ TestRegistry()
+ : m_currentSortOrder( RunTests::InDeclarationOrder ),
+ m_unnamedCount( 0 )
+ {}
+ virtual ~TestRegistry();
+
+ virtual void registerTest( TestCase const& testCase ) {
+ std::string name = testCase.getTestCaseInfo().name;
+ if( name == "" ) {
+ std::ostringstream oss;
+ oss << "Anonymous test case " << ++m_unnamedCount;
+ return registerTest( testCase.withName( oss.str() ) );
+ }
+ m_functions.push_back( testCase );
+ }
+
+ virtual std::vector<TestCase> const& getAllTests() const {
+ return m_functions;
+ }
+ virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {
+ if( m_sortedFunctions.empty() )
+ enforceNoDuplicateTestCases( m_functions );
+
+ if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
+ m_sortedFunctions = sortTests( config, m_functions );
+ m_currentSortOrder = config.runOrder();
+ }
+ return m_sortedFunctions;
+ }
+
+ private:
+ std::vector<TestCase> m_functions;
+ mutable RunTests::InWhatOrder m_currentSortOrder;
+ mutable std::vector<TestCase> m_sortedFunctions;
+ size_t m_unnamedCount;
+ std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class FreeFunctionTestCase : public SharedImpl<ITestCase> {
+ public:
+
+ FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
+
+ virtual void invoke() const {
+ m_fun();
+ }
+
+ private:
+ virtual ~FreeFunctionTestCase();
+
+ TestFunction m_fun;
+ };
+
+ inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
+ std::string className = classOrQualifiedMethodName;
+ if( startsWith( className, "&" ) )
+ {
+ std::size_t lastColons = className.rfind( "::" );
+ std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
+ if( penultimateColons == std::string::npos )
+ penultimateColons = 1;
+ className = className.substr( penultimateColons, lastColons-penultimateColons );
+ }
+ return className;
+ }
+
+ void registerTestCase
+ ( ITestCase* testCase,
+ char const* classOrQualifiedMethodName,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo ) {
+
+ getMutableRegistryHub().registerTest
+ ( makeTestCase
+ ( testCase,
+ extractClassName( classOrQualifiedMethodName ),
+ nameAndDesc.name,
+ nameAndDesc.description,
+ lineInfo ) );
+ }
+ void registerTestCaseFunction
+ ( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc ) {
+ registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ AutoReg::AutoReg
+ ( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc ) {
+ registerTestCaseFunction( function, lineInfo, nameAndDesc );
+ }
+
+ AutoReg::~AutoReg() {}
+
+} // end namespace Catch
+
+// #included from: catch_reporter_registry.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
+
+#include <map>
+
+namespace Catch {
+
+ class ReporterRegistry : public IReporterRegistry {
+
+ public:
+
+ virtual ~ReporterRegistry() CATCH_OVERRIDE {}
+
+ virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
+ FactoryMap::const_iterator it = m_factories.find( name );
+ if( it == m_factories.end() )
+ return CATCH_NULL;
+ return it->second->create( ReporterConfig( config ) );
+ }
+
+ void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {
+ m_factories.insert( std::make_pair( name, factory ) );
+ }
+ void registerListener( Ptr<IReporterFactory> const& factory ) {
+ m_listeners.push_back( factory );
+ }
+
+ virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {
+ return m_factories;
+ }
+ virtual Listeners const& getListeners() const CATCH_OVERRIDE {
+ return m_listeners;
+ }
+
+ private:
+ FactoryMap m_factories;
+ Listeners m_listeners;
+ };
+}
+
+// #included from: catch_exception_translator_registry.hpp
+#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
+
+#ifdef __OBJC__
+#import "Foundation/Foundation.h"
+#endif
+
+namespace Catch {
+
+ class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
+ public:
+ ~ExceptionTranslatorRegistry() {
+ deleteAll( m_translators );
+ }
+
+ virtual void registerTranslator( const IExceptionTranslator* translator ) {
+ m_translators.push_back( translator );
+ }
+
+ virtual std::string translateActiveException() const {
+ try {
+#ifdef __OBJC__
+ // In Objective-C try objective-c exceptions first
+ @try {
+ return tryTranslators();
+ }
+ @catch (NSException *exception) {
+ return Catch::toString( [exception description] );
+ }
+#else
+ return tryTranslators();
+#endif
+ }
+ catch( TestFailureException& ) {
+ throw;
+ }
+ catch( std::exception& ex ) {
+ return ex.what();
+ }
+ catch( std::string& msg ) {
+ return msg;
+ }
+ catch( const char* msg ) {
+ return msg;
+ }
+ catch(...) {
+ return "Unknown exception";
+ }
+ }
+
+ std::string tryTranslators() const {
+ if( m_translators.empty() )
+ throw;
+ else
+ return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
+ }
+
+ private:
+ std::vector<const IExceptionTranslator*> m_translators;
+ };
+}
+
+namespace Catch {
+
+ namespace {
+
+ class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
+
+ RegistryHub( RegistryHub const& );
+ void operator=( RegistryHub const& );
+
+ public: // IRegistryHub
+ RegistryHub() {
+ }
+ virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {
+ return m_reporterRegistry;
+ }
+ virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {
+ return m_testCaseRegistry;
+ }
+ virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
+ return m_exceptionTranslatorRegistry;
+ }
+
+ public: // IMutableRegistryHub
+ virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
+ m_reporterRegistry.registerReporter( name, factory );
+ }
+ virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
+ m_reporterRegistry.registerListener( factory );
+ }
+ virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {
+ m_testCaseRegistry.registerTest( testInfo );
+ }
+ virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
+ m_exceptionTranslatorRegistry.registerTranslator( translator );
+ }
+
+ private:
+ TestRegistry m_testCaseRegistry;
+ ReporterRegistry m_reporterRegistry;
+ ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
+ };
+
+ // Single, global, instance
+ inline RegistryHub*& getTheRegistryHub() {
+ static RegistryHub* theRegistryHub = CATCH_NULL;
+ if( !theRegistryHub )
+ theRegistryHub = new RegistryHub();
+ return theRegistryHub;
+ }
+ }
+
+ IRegistryHub& getRegistryHub() {
+ return *getTheRegistryHub();
+ }
+ IMutableRegistryHub& getMutableRegistryHub() {
+ return *getTheRegistryHub();
+ }
+ void cleanUp() {
+ delete getTheRegistryHub();
+ getTheRegistryHub() = CATCH_NULL;
+ cleanUpContext();
+ }
+ std::string translateActiveException() {
+ return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_notimplemented_exception.hpp
+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
+
+#include <ostream>
+
+namespace Catch {
+
+ NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
+ : m_lineInfo( lineInfo ) {
+ std::ostringstream oss;
+ oss << lineInfo << ": function ";
+ oss << "not implemented";
+ m_what = oss.str();
+ }
+
+ const char* NotImplementedException::what() const CATCH_NOEXCEPT {
+ return m_what.c_str();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_context_impl.hpp
+#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
+
+// #included from: catch_stream.hpp
+#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
+
+#include <stdexcept>
+#include <cstdio>
+#include <iostream>
+
+namespace Catch {
+
+ template<typename WriterF, size_t bufferSize=256>
+ class StreamBufImpl : public StreamBufBase {
+ char data[bufferSize];
+ WriterF m_writer;
+
+ public:
+ StreamBufImpl() {
+ setp( data, data + sizeof(data) );
+ }
+
+ ~StreamBufImpl() CATCH_NOEXCEPT {
+ sync();
+ }
+
+ private:
+ int overflow( int c ) {
+ sync();
+
+ if( c != EOF ) {
+ if( pbase() == epptr() )
+ m_writer( std::string( 1, static_cast<char>( c ) ) );
+ else
+ sputc( static_cast<char>( c ) );
+ }
+ return 0;
+ }
+
+ int sync() {
+ if( pbase() != pptr() ) {
+ m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
+ setp( pbase(), epptr() );
+ }
+ return 0;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ FileStream::FileStream( std::string const& filename ) {
+ m_ofs.open( filename.c_str() );
+ if( m_ofs.fail() ) {
+ std::ostringstream oss;
+ oss << "Unable to open file: '" << filename << "'";
+ throw std::domain_error( oss.str() );
+ }
+ }
+
+ std::ostream& FileStream::stream() const {
+ return m_ofs;
+ }
+
+ struct OutputDebugWriter {
+
+ void operator()( std::string const&str ) {
+ writeToDebugConsole( str );
+ }
+ };
+
+ DebugOutStream::DebugOutStream()
+ : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
+ m_os( m_streamBuf.get() )
+ {}
+
+ std::ostream& DebugOutStream::stream() const {
+ return m_os;
+ }
+
+ // Store the streambuf from cout up-front because
+ // cout may get redirected when running tests
+ CoutStream::CoutStream()
+ : m_os( Catch::cout().rdbuf() )
+ {}
+
+ std::ostream& CoutStream::stream() const {
+ return m_os;
+ }
+
+#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
+ std::ostream& cout() {
+ return std::cout;
+ }
+ std::ostream& cerr() {
+ return std::cerr;
+ }
+#endif
+}
+
+namespace Catch {
+
+ class Context : public IMutableContext {
+
+ Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
+ Context( Context const& );
+ void operator=( Context const& );
+
+ public: // IContext
+ virtual IResultCapture* getResultCapture() {
+ return m_resultCapture;
+ }
+ virtual IRunner* getRunner() {
+ return m_runner;
+ }
+ virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
+ return getGeneratorsForCurrentTest()
+ .getGeneratorInfo( fileInfo, totalSize )
+ .getCurrentIndex();
+ }
+ virtual bool advanceGeneratorsForCurrentTest() {
+ IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
+ return generators && generators->moveNext();
+ }
+
+ virtual Ptr<IConfig const> getConfig() const {
+ return m_config;
+ }
+
+ public: // IMutableContext
+ virtual void setResultCapture( IResultCapture* resultCapture ) {
+ m_resultCapture = resultCapture;
+ }
+ virtual void setRunner( IRunner* runner ) {
+ m_runner = runner;
+ }
+ virtual void setConfig( Ptr<IConfig const> const& config ) {
+ m_config = config;
+ }
+
+ friend IMutableContext& getCurrentMutableContext();
+
+ private:
+ IGeneratorsForTest* findGeneratorsForCurrentTest() {
+ std::string testName = getResultCapture()->getCurrentTestName();
+
+ std::map<std::string, IGeneratorsForTest*>::const_iterator it =
+ m_generatorsByTestName.find( testName );
+ return it != m_generatorsByTestName.end()
+ ? it->second
+ : CATCH_NULL;
+ }
+
+ IGeneratorsForTest& getGeneratorsForCurrentTest() {
+ IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
+ if( !generators ) {
+ std::string testName = getResultCapture()->getCurrentTestName();
+ generators = createGeneratorsForTest();
+ m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
+ }
+ return *generators;
+ }
+
+ private:
+ Ptr<IConfig const> m_config;
+ IRunner* m_runner;
+ IResultCapture* m_resultCapture;
+ std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
+ };
+
+ namespace {
+ Context* currentContext = CATCH_NULL;
+ }
+ IMutableContext& getCurrentMutableContext() {
+ if( !currentContext )
+ currentContext = new Context();
+ return *currentContext;
+ }
+ IContext& getCurrentContext() {
+ return getCurrentMutableContext();
+ }
+
+ void cleanUpContext() {
+ delete currentContext;
+ currentContext = CATCH_NULL;
+ }
+}
+
+// #included from: catch_console_colour_impl.hpp
+#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
+
+namespace Catch {
+ namespace {
+
+ struct IColourImpl {
+ virtual ~IColourImpl() {}
+ virtual void use( Colour::Code _colourCode ) = 0;
+ };
+
+ struct NoColourImpl : IColourImpl {
+ void use( Colour::Code ) {}
+
+ static IColourImpl* instance() {
+ static NoColourImpl s_instance;
+ return &s_instance;
+ }
+ };
+
+ } // anon namespace
+} // namespace Catch
+
+#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
+# ifdef CATCH_PLATFORM_WINDOWS
+# define CATCH_CONFIG_COLOUR_WINDOWS
+# else
+# define CATCH_CONFIG_COLOUR_ANSI
+# endif
+#endif
+
+#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+#ifdef __AFXDLL
+#include <AfxWin.h>
+#else
+#include <windows.h>
+#endif
+
+namespace Catch {
+namespace {
+
+ class Win32ColourImpl : public IColourImpl {
+ public:
+ Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
+ {
+ CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
+ GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
+ originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
+ originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
+ }
+
+ virtual void use( Colour::Code _colourCode ) {
+ switch( _colourCode ) {
+ case Colour::None: return setTextAttribute( originalForegroundAttributes );
+ case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+ case Colour::Red: return setTextAttribute( FOREGROUND_RED );
+ case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
+ case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
+ case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
+ case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
+ case Colour::Grey: return setTextAttribute( 0 );
+
+ case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
+ case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
+ case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
+ case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+
+ case Colour::Bright: throw std::logic_error( "not a colour" );
+ }
+ }
+
+ private:
+ void setTextAttribute( WORD _textAttribute ) {
+ SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
+ }
+ HANDLE stdoutHandle;
+ WORD originalForegroundAttributes;
+ WORD originalBackgroundAttributes;
+ };
+
+ IColourImpl* platformColourInstance() {
+ static Win32ColourImpl s_instance;
+
+ Ptr<IConfig const> config = getCurrentContext().getConfig();
+ UseColour::YesOrNo colourMode = config
+ ? config->useColour()
+ : UseColour::Auto;
+ if( colourMode == UseColour::Auto )
+ colourMode = !isDebuggerActive()
+ ? UseColour::Yes
+ : UseColour::No;
+ return colourMode == UseColour::Yes
+ ? &s_instance
+ : NoColourImpl::instance();
+ }
+
+} // end anon namespace
+} // end namespace Catch
+
+#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
+
+#include <unistd.h>
+
+namespace Catch {
+namespace {
+
+ // use POSIX/ ANSI console terminal codes
+ // Thanks to Adam Strzelecki for original contribution
+ // (http://github.com/nanoant)
+ // https://github.com/philsquared/Catch/pull/131
+ class PosixColourImpl : public IColourImpl {
+ public:
+ virtual void use( Colour::Code _colourCode ) {
+ switch( _colourCode ) {
+ case Colour::None:
+ case Colour::White: return setColour( "[0m" );
+ case Colour::Red: return setColour( "[0;31m" );
+ case Colour::Green: return setColour( "[0;32m" );
+ case Colour::Blue: return setColour( "[0:34m" );
+ case Colour::Cyan: return setColour( "[0;36m" );
+ case Colour::Yellow: return setColour( "[0;33m" );
+ case Colour::Grey: return setColour( "[1;30m" );
+
+ case Colour::LightGrey: return setColour( "[0;37m" );
+ case Colour::BrightRed: return setColour( "[1;31m" );
+ case Colour::BrightGreen: return setColour( "[1;32m" );
+ case Colour::BrightWhite: return setColour( "[1;37m" );
+
+ case Colour::Bright: throw std::logic_error( "not a colour" );
+ }
+ }
+ static IColourImpl* instance() {
+ static PosixColourImpl s_instance;
+ return &s_instance;
+ }
+
+ private:
+ void setColour( const char* _escapeCode ) {
+ Catch::cout() << '\033' << _escapeCode;
+ }
+ };
+
+ IColourImpl* platformColourInstance() {
+ Ptr<IConfig const> config = getCurrentContext().getConfig();
+ UseColour::YesOrNo colourMode = config
+ ? config->useColour()
+ : UseColour::Auto;
+ if( colourMode == UseColour::Auto )
+ colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )
+ ? UseColour::Yes
+ : UseColour::No;
+ return colourMode == UseColour::Yes
+ ? PosixColourImpl::instance()
+ : NoColourImpl::instance();
+ }
+
+} // end anon namespace
+} // end namespace Catch
+
+#else // not Windows or ANSI ///////////////////////////////////////////////
+
+namespace Catch {
+
+ static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
+
+} // end namespace Catch
+
+#endif // Windows/ ANSI/ None
+
+namespace Catch {
+
+ Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
+ Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
+ Colour::~Colour(){ if( !m_moved ) use( None ); }
+
+ void Colour::use( Code _colourCode ) {
+ static IColourImpl* impl = platformColourInstance();
+ impl->use( _colourCode );
+ }
+
+} // end namespace Catch
+
+// #included from: catch_generators_impl.hpp
+#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
+
+#include <vector>
+#include <string>
+#include <map>
+
+namespace Catch {
+
+ struct GeneratorInfo : IGeneratorInfo {
+
+ GeneratorInfo( std::size_t size )
+ : m_size( size ),
+ m_currentIndex( 0 )
+ {}
+
+ bool moveNext() {
+ if( ++m_currentIndex == m_size ) {
+ m_currentIndex = 0;
+ return false;
+ }
+ return true;
+ }
+
+ std::size_t getCurrentIndex() const {
+ return m_currentIndex;
+ }
+
+ std::size_t m_size;
+ std::size_t m_currentIndex;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class GeneratorsForTest : public IGeneratorsForTest {
+
+ public:
+ ~GeneratorsForTest() {
+ deleteAll( m_generatorsInOrder );
+ }
+
+ IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
+ std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
+ if( it == m_generatorsByName.end() ) {
+ IGeneratorInfo* info = new GeneratorInfo( size );
+ m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
+ m_generatorsInOrder.push_back( info );
+ return *info;
+ }
+ return *it->second;
+ }
+
+ bool moveNext() {
+ std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
+ std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
+ for(; it != itEnd; ++it ) {
+ if( (*it)->moveNext() )
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ std::map<std::string, IGeneratorInfo*> m_generatorsByName;
+ std::vector<IGeneratorInfo*> m_generatorsInOrder;
+ };
+
+ IGeneratorsForTest* createGeneratorsForTest()
+ {
+ return new GeneratorsForTest();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_assertionresult.hpp
+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
+
+namespace Catch {
+
+ AssertionInfo::AssertionInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ std::string const& _capturedExpression,
+ ResultDisposition::Flags _resultDisposition )
+ : macroName( _macroName ),
+ lineInfo( _lineInfo ),
+ capturedExpression( _capturedExpression ),
+ resultDisposition( _resultDisposition )
+ {}
+
+ AssertionResult::AssertionResult() {}
+
+ AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
+ : m_info( info ),
+ m_resultData( data )
+ {}
+
+ AssertionResult::~AssertionResult() {}
+
+ // Result was a success
+ bool AssertionResult::succeeded() const {
+ return Catch::isOk( m_resultData.resultType );
+ }
+
+ // Result was a success, or failure is suppressed
+ bool AssertionResult::isOk() const {
+ return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
+ }
+
+ ResultWas::OfType AssertionResult::getResultType() const {
+ return m_resultData.resultType;
+ }
+
+ bool AssertionResult::hasExpression() const {
+ return !m_info.capturedExpression.empty();
+ }
+
+ bool AssertionResult::hasMessage() const {
+ return !m_resultData.message.empty();
+ }
+
+ std::string AssertionResult::getExpression() const {
+ if( isFalseTest( m_info.resultDisposition ) )
+ return "!" + m_info.capturedExpression;
+ else
+ return m_info.capturedExpression;
+ }
+ std::string AssertionResult::getExpressionInMacro() const {
+ if( m_info.macroName.empty() )
+ return m_info.capturedExpression;
+ else
+ return m_info.macroName + "( " + m_info.capturedExpression + " )";
+ }
+
+ bool AssertionResult::hasExpandedExpression() const {
+ return hasExpression() && getExpandedExpression() != getExpression();
+ }
+
+ std::string AssertionResult::getExpandedExpression() const {
+ return m_resultData.reconstructedExpression;
+ }
+
+ std::string AssertionResult::getMessage() const {
+ return m_resultData.message;
+ }
+ SourceLineInfo AssertionResult::getSourceInfo() const {
+ return m_info.lineInfo;
+ }
+
+ std::string AssertionResult::getTestMacroName() const {
+ return m_info.macroName;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_test_case_info.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
+
+namespace Catch {
+
+ inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
+ if( startsWith( tag, "." ) ||
+ tag == "hide" ||
+ tag == "!hide" )
+ return TestCaseInfo::IsHidden;
+ else if( tag == "!throws" )
+ return TestCaseInfo::Throws;
+ else if( tag == "!shouldfail" )
+ return TestCaseInfo::ShouldFail;
+ else if( tag == "!mayfail" )
+ return TestCaseInfo::MayFail;
+ else
+ return TestCaseInfo::None;
+ }
+ inline bool isReservedTag( std::string const& tag ) {
+ return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
+ }
+ inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
+ if( isReservedTag( tag ) ) {
+ {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr()
+ << "Tag name [" << tag << "] not allowed.\n"
+ << "Tag names starting with non alpha-numeric characters are reserved\n";
+ }
+ {
+ Colour colourGuard( Colour::FileName );
+ Catch::cerr() << _lineInfo << std::endl;
+ }
+ exit(1);
+ }
+ }
+
+ TestCase makeTestCase( ITestCase* _testCase,
+ std::string const& _className,
+ std::string const& _name,
+ std::string const& _descOrTags,
+ SourceLineInfo const& _lineInfo )
+ {
+ bool isHidden( startsWith( _name, "./" ) ); // Legacy support
+
+ // Parse out tags
+ std::set<std::string> tags;
+ std::string desc, tag;
+ bool inTag = false;
+ for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
+ char c = _descOrTags[i];
+ if( !inTag ) {
+ if( c == '[' )
+ inTag = true;
+ else
+ desc += c;
+ }
+ else {
+ if( c == ']' ) {
+ TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
+ if( prop == TestCaseInfo::IsHidden )
+ isHidden = true;
+ else if( prop == TestCaseInfo::None )
+ enforceNotReservedTag( tag, _lineInfo );
+
+ tags.insert( tag );
+ tag.clear();
+ inTag = false;
+ }
+ else
+ tag += c;
+ }
+ }
+ if( isHidden ) {
+ tags.insert( "hide" );
+ tags.insert( "." );
+ }
+
+ TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
+ return TestCase( _testCase, info );
+ }
+
+ void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )
+ {
+ testCaseInfo.tags = tags;
+ testCaseInfo.lcaseTags.clear();
+
+ std::ostringstream oss;
+ for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
+ oss << "[" << *it << "]";
+ std::string lcaseTag = toLower( *it );
+ testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
+ testCaseInfo.lcaseTags.insert( lcaseTag );
+ }
+ testCaseInfo.tagsAsString = oss.str();
+ }
+
+ TestCaseInfo::TestCaseInfo( std::string const& _name,
+ std::string const& _className,
+ std::string const& _description,
+ std::set<std::string> const& _tags,
+ SourceLineInfo const& _lineInfo )
+ : name( _name ),
+ className( _className ),
+ description( _description ),
+ lineInfo( _lineInfo ),
+ properties( None )
+ {
+ setTags( *this, _tags );
+ }
+
+ TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
+ : name( other.name ),
+ className( other.className ),
+ description( other.description ),
+ tags( other.tags ),
+ lcaseTags( other.lcaseTags ),
+ tagsAsString( other.tagsAsString ),
+ lineInfo( other.lineInfo ),
+ properties( other.properties )
+ {}
+
+ bool TestCaseInfo::isHidden() const {
+ return ( properties & IsHidden ) != 0;
+ }
+ bool TestCaseInfo::throws() const {
+ return ( properties & Throws ) != 0;
+ }
+ bool TestCaseInfo::okToFail() const {
+ return ( properties & (ShouldFail | MayFail ) ) != 0;
+ }
+ bool TestCaseInfo::expectedToFail() const {
+ return ( properties & (ShouldFail ) ) != 0;
+ }
+
+ TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
+
+ TestCase::TestCase( TestCase const& other )
+ : TestCaseInfo( other ),
+ test( other.test )
+ {}
+
+ TestCase TestCase::withName( std::string const& _newName ) const {
+ TestCase other( *this );
+ other.name = _newName;
+ return other;
+ }
+
+ void TestCase::swap( TestCase& other ) {
+ test.swap( other.test );
+ name.swap( other.name );
+ className.swap( other.className );
+ description.swap( other.description );
+ tags.swap( other.tags );
+ lcaseTags.swap( other.lcaseTags );
+ tagsAsString.swap( other.tagsAsString );
+ std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
+ std::swap( lineInfo, other.lineInfo );
+ }
+
+ void TestCase::invoke() const {
+ test->invoke();
+ }
+
+ bool TestCase::operator == ( TestCase const& other ) const {
+ return test.get() == other.test.get() &&
+ name == other.name &&
+ className == other.className;
+ }
+
+ bool TestCase::operator < ( TestCase const& other ) const {
+ return name < other.name;
+ }
+ TestCase& TestCase::operator = ( TestCase const& other ) {
+ TestCase temp( other );
+ swap( temp );
+ return *this;
+ }
+
+ TestCaseInfo const& TestCase::getTestCaseInfo() const
+ {
+ return *this;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_version.hpp
+#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
+
+namespace Catch {
+
+ Version::Version
+ ( unsigned int _majorVersion,
+ unsigned int _minorVersion,
+ unsigned int _patchNumber,
+ std::string const& _branchName,
+ unsigned int _buildNumber )
+ : majorVersion( _majorVersion ),
+ minorVersion( _minorVersion ),
+ patchNumber( _patchNumber ),
+ branchName( _branchName ),
+ buildNumber( _buildNumber )
+ {}
+
+ std::ostream& operator << ( std::ostream& os, Version const& version ) {
+ os << version.majorVersion << "."
+ << version.minorVersion << "."
+ << version.patchNumber;
+
+ if( !version.branchName.empty() ) {
+ os << "-" << version.branchName
+ << "." << version.buildNumber;
+ }
+ return os;
+ }
+
+ Version libraryVersion( 1, 4, 0, "", 0 );
+
+}
+
+// #included from: catch_message.hpp
+#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
+
+namespace Catch {
+
+ MessageInfo::MessageInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ ResultWas::OfType _type )
+ : macroName( _macroName ),
+ lineInfo( _lineInfo ),
+ type( _type ),
+ sequence( ++globalCount )
+ {}
+
+ // This may need protecting if threading support is added
+ unsigned int MessageInfo::globalCount = 0;
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ ScopedMessage::ScopedMessage( MessageBuilder const& builder )
+ : m_info( builder.m_info )
+ {
+ m_info.message = builder.m_stream.str();
+ getResultCapture().pushScopedMessage( m_info );
+ }
+ ScopedMessage::ScopedMessage( ScopedMessage const& other )
+ : m_info( other.m_info )
+ {}
+
+ ScopedMessage::~ScopedMessage() {
+ getResultCapture().popScopedMessage( m_info );
+ }
+
+} // end namespace Catch
+
+// #included from: catch_legacy_reporter_adapter.hpp
+#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
+
+// #included from: catch_legacy_reporter_adapter.h
+#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
+
+namespace Catch
+{
+ // Deprecated
+ struct IReporter : IShared {
+ virtual ~IReporter();
+
+ virtual bool shouldRedirectStdout() const = 0;
+
+ virtual void StartTesting() = 0;
+ virtual void EndTesting( Totals const& totals ) = 0;
+ virtual void StartGroup( std::string const& groupName ) = 0;
+ virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
+ virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
+ virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
+ virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
+ virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
+ virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
+ virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
+ virtual void Aborted() = 0;
+ virtual void Result( AssertionResult const& result ) = 0;
+ };
+
+ class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
+ {
+ public:
+ LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
+ virtual ~LegacyReporterAdapter();
+
+ virtual ReporterPreferences getPreferences() const;
+ virtual void noMatchingTestCases( std::string const& );
+ virtual void testRunStarting( TestRunInfo const& );
+ virtual void testGroupStarting( GroupInfo const& groupInfo );
+ virtual void testCaseStarting( TestCaseInfo const& testInfo );
+ virtual void sectionStarting( SectionInfo const& sectionInfo );
+ virtual void assertionStarting( AssertionInfo const& );
+ virtual bool assertionEnded( AssertionStats const& assertionStats );
+ virtual void sectionEnded( SectionStats const& sectionStats );
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats );
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats );
+ virtual void testRunEnded( TestRunStats const& testRunStats );
+ virtual void skipTest( TestCaseInfo const& );
+
+ private:
+ Ptr<IReporter> m_legacyReporter;
+ };
+}
+
+namespace Catch
+{
+ LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
+ : m_legacyReporter( legacyReporter )
+ {}
+ LegacyReporterAdapter::~LegacyReporterAdapter() {}
+
+ ReporterPreferences LegacyReporterAdapter::getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
+ return prefs;
+ }
+
+ void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
+ void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
+ m_legacyReporter->StartTesting();
+ }
+ void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
+ m_legacyReporter->StartGroup( groupInfo.name );
+ }
+ void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
+ m_legacyReporter->StartTestCase( testInfo );
+ }
+ void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
+ m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
+ }
+ void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
+ // Not on legacy interface
+ }
+
+ bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
+ if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
+ for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
+ it != itEnd;
+ ++it ) {
+ if( it->type == ResultWas::Info ) {
+ ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
+ rb << it->message;
+ rb.setResultType( ResultWas::Info );
+ AssertionResult result = rb.build();
+ m_legacyReporter->Result( result );
+ }
+ }
+ }
+ m_legacyReporter->Result( assertionStats.assertionResult );
+ return true;
+ }
+ void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
+ if( sectionStats.missingAssertions )
+ m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
+ m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
+ }
+ void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
+ m_legacyReporter->EndTestCase
+ ( testCaseStats.testInfo,
+ testCaseStats.totals,
+ testCaseStats.stdOut,
+ testCaseStats.stdErr );
+ }
+ void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
+ if( testGroupStats.aborting )
+ m_legacyReporter->Aborted();
+ m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
+ }
+ void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
+ m_legacyReporter->EndTesting( testRunStats.totals );
+ }
+ void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
+ }
+}
+
+// #included from: catch_timer.hpp
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++11-long-long"
+#endif
+
+#ifdef CATCH_PLATFORM_WINDOWS
+#include <windows.h>
+#else
+#include <sys/time.h>
+#endif
+
+namespace Catch {
+
+ namespace {
+#ifdef CATCH_PLATFORM_WINDOWS
+ uint64_t getCurrentTicks() {
+ static uint64_t hz=0, hzo=0;
+ if (!hz) {
+ QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
+ QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
+ }
+ uint64_t t;
+ QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
+ return ((t-hzo)*1000000)/hz;
+ }
+#else
+ uint64_t getCurrentTicks() {
+ timeval t;
+ gettimeofday(&t,CATCH_NULL);
+ return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
+ }
+#endif
+ }
+
+ void Timer::start() {
+ m_ticks = getCurrentTicks();
+ }
+ unsigned int Timer::getElapsedMicroseconds() const {
+ return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
+ }
+ unsigned int Timer::getElapsedMilliseconds() const {
+ return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
+ }
+ double Timer::getElapsedSeconds() const {
+ return getElapsedMicroseconds()/1000000.0;
+ }
+
+} // namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+// #included from: catch_common.hpp
+#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
+
+namespace Catch {
+
+ bool startsWith( std::string const& s, std::string const& prefix ) {
+ return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
+ }
+ bool endsWith( std::string const& s, std::string const& suffix ) {
+ return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
+ }
+ bool contains( std::string const& s, std::string const& infix ) {
+ return s.find( infix ) != std::string::npos;
+ }
+ void toLowerInPlace( std::string& s ) {
+ std::transform( s.begin(), s.end(), s.begin(), ::tolower );
+ }
+ std::string toLower( std::string const& s ) {
+ std::string lc = s;
+ toLowerInPlace( lc );
+ return lc;
+ }
+ std::string trim( std::string const& str ) {
+ static char const* whitespaceChars = "\n\r\t ";
+ std::string::size_type start = str.find_first_not_of( whitespaceChars );
+ std::string::size_type end = str.find_last_not_of( whitespaceChars );
+
+ return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
+ }
+
+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
+ bool replaced = false;
+ std::size_t i = str.find( replaceThis );
+ while( i != std::string::npos ) {
+ replaced = true;
+ str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
+ if( i < str.size()-withThis.size() )
+ i = str.find( replaceThis, i+withThis.size() );
+ else
+ i = std::string::npos;
+ }
+ return replaced;
+ }
+
+ pluralise::pluralise( std::size_t count, std::string const& label )
+ : m_count( count ),
+ m_label( label )
+ {}
+
+ std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
+ os << pluraliser.m_count << " " << pluraliser.m_label;
+ if( pluraliser.m_count != 1 )
+ os << "s";
+ return os;
+ }
+
+ SourceLineInfo::SourceLineInfo() : line( 0 ){}
+ SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
+ : file( _file ),
+ line( _line )
+ {}
+ SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
+ : file( other.file ),
+ line( other.line )
+ {}
+ bool SourceLineInfo::empty() const {
+ return file.empty();
+ }
+ bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
+ return line == other.line && file == other.file;
+ }
+ bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
+ return line < other.line || ( line == other.line && file < other.file );
+ }
+
+ void seedRng( IConfig const& config ) {
+ if( config.rngSeed() != 0 )
+ std::srand( config.rngSeed() );
+ }
+ unsigned int rngSeed() {
+ return getCurrentContext().getConfig()->rngSeed();
+ }
+
+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
+#ifndef __GNUG__
+ os << info.file << "(" << info.line << ")";
+#else
+ os << info.file << ":" << info.line;
+#endif
+ return os;
+ }
+
+ void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
+ std::ostringstream oss;
+ oss << locationInfo << ": Internal Catch error: '" << message << "'";
+ if( alwaysTrue() )
+ throw std::logic_error( oss.str() );
+ }
+}
+
+// #included from: catch_section.hpp
+#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
+
+namespace Catch {
+
+ SectionInfo::SectionInfo
+ ( SourceLineInfo const& _lineInfo,
+ std::string const& _name,
+ std::string const& _description )
+ : name( _name ),
+ description( _description ),
+ lineInfo( _lineInfo )
+ {}
+
+ Section::Section( SectionInfo const& info )
+ : m_info( info ),
+ m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
+ {
+ m_timer.start();
+ }
+
+ Section::~Section() {
+ if( m_sectionIncluded ) {
+ SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
+ if( std::uncaught_exception() )
+ getResultCapture().sectionEndedEarly( endInfo );
+ else
+ getResultCapture().sectionEnded( endInfo );
+ }
+ }
+
+ // This indicates whether the section should be executed or not
+ Section::operator bool() const {
+ return m_sectionIncluded;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_debugger.hpp
+#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
+
+#include <iostream>
+
+#ifdef CATCH_PLATFORM_MAC
+
+ #include <assert.h>
+ #include <stdbool.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <sys/sysctl.h>
+
+ namespace Catch{
+
+ // The following function is taken directly from the following technical note:
+ // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
+
+ // Returns true if the current process is being debugged (either
+ // running under the debugger or has a debugger attached post facto).
+ bool isDebuggerActive(){
+
+ int mib[4];
+ struct kinfo_proc info;
+ size_t size;
+
+ // Initialize the flags so that, if sysctl fails for some bizarre
+ // reason, we get a predictable result.
+
+ info.kp_proc.p_flag = 0;
+
+ // Initialize mib, which tells sysctl the info we want, in this case
+ // we're looking for information about a specific process ID.
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = getpid();
+
+ // Call sysctl.
+
+ size = sizeof(info);
+ if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
+ Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
+ return false;
+ }
+
+ // We're being debugged if the P_TRACED flag is set.
+
+ return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
+ }
+ } // namespace Catch
+
+#elif defined(_MSC_VER)
+ extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+ namespace Catch {
+ bool isDebuggerActive() {
+ return IsDebuggerPresent() != 0;
+ }
+ }
+#elif defined(__MINGW32__)
+ extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+ namespace Catch {
+ bool isDebuggerActive() {
+ return IsDebuggerPresent() != 0;
+ }
+ }
+#else
+ namespace Catch {
+ inline bool isDebuggerActive() { return false; }
+ }
+#endif // Platform
+
+#ifdef CATCH_PLATFORM_WINDOWS
+ extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
+ namespace Catch {
+ void writeToDebugConsole( std::string const& text ) {
+ ::OutputDebugStringA( text.c_str() );
+ }
+ }
+#else
+ namespace Catch {
+ void writeToDebugConsole( std::string const& text ) {
+ // !TBD: Need a version for Mac/ XCode and other IDEs
+ Catch::cout() << text;
+ }
+ }
+#endif // Platform
+
+// #included from: catch_tostring.hpp
+#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
+
+namespace Catch {
+
+namespace Detail {
+
+ const std::string unprintableString = "{?}";
+
+ namespace {
+ const int hexThreshold = 255;
+
+ struct Endianness {
+ enum Arch { Big, Little };
+
+ static Arch which() {
+ union _{
+ int asInt;
+ char asChar[sizeof (int)];
+ } u;
+
+ u.asInt = 1;
+ return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
+ }
+ };
+ }
+
+ std::string rawMemoryToString( const void *object, std::size_t size )
+ {
+ // Reverse order for little endian architectures
+ int i = 0, end = static_cast<int>( size ), inc = 1;
+ if( Endianness::which() == Endianness::Little ) {
+ i = end-1;
+ end = inc = -1;
+ }
+
+ unsigned char const *bytes = static_cast<unsigned char const *>(object);
+ std::ostringstream os;
+ os << "0x" << std::setfill('0') << std::hex;
+ for( ; i != end; i += inc )
+ os << std::setw(2) << static_cast<unsigned>(bytes[i]);
+ return os.str();
+ }
+}
+
+std::string toString( std::string const& value ) {
+ std::string s = value;
+ if( getCurrentContext().getConfig()->showInvisibles() ) {
+ for(size_t i = 0; i < s.size(); ++i ) {
+ std::string subs;
+ switch( s[i] ) {
+ case '\n': subs = "\\n"; break;
+ case '\t': subs = "\\t"; break;
+ default: break;
+ }
+ if( !subs.empty() ) {
+ s = s.substr( 0, i ) + subs + s.substr( i+1 );
+ ++i;
+ }
+ }
+ }
+ return "\"" + s + "\"";
+}
+std::string toString( std::wstring const& value ) {
+
+ std::string s;
+ s.reserve( value.size() );
+ for(size_t i = 0; i < value.size(); ++i )
+ s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
+ return Catch::toString( s );
+}
+
+std::string toString( const char* const value ) {
+ return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
+}
+
+std::string toString( char* const value ) {
+ return Catch::toString( static_cast<const char*>( value ) );
+}
+
+std::string toString( const wchar_t* const value )
+{
+ return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
+}
+
+std::string toString( wchar_t* const value )
+{
+ return Catch::toString( static_cast<const wchar_t*>( value ) );
+}
+
+std::string toString( int value ) {
+ std::ostringstream oss;
+ oss << value;
+ if( value > Detail::hexThreshold )
+ oss << " (0x" << std::hex << value << ")";
+ return oss.str();
+}
+
+std::string toString( unsigned long value ) {
+ std::ostringstream oss;
+ oss << value;
+ if( value > Detail::hexThreshold )
+ oss << " (0x" << std::hex << value << ")";
+ return oss.str();
+}
+
+std::string toString( unsigned int value ) {
+ return Catch::toString( static_cast<unsigned long>( value ) );
+}
+
+template<typename T>
+std::string fpToString( T value, int precision ) {
+ std::ostringstream oss;
+ oss << std::setprecision( precision )
+ << std::fixed
+ << value;
+ std::string d = oss.str();
+ std::size_t i = d.find_last_not_of( '0' );
+ if( i != std::string::npos && i != d.size()-1 ) {
+ if( d[i] == '.' )
+ i++;
+ d = d.substr( 0, i+1 );
+ }
+ return d;
+}
+
+std::string toString( const double value ) {
+ return fpToString( value, 10 );
+}
+std::string toString( const float value ) {
+ return fpToString( value, 5 ) + "f";
+}
+
+std::string toString( bool value ) {
+ return value ? "true" : "false";
+}
+
+std::string toString( char value ) {
+ return value < ' '
+ ? toString( static_cast<unsigned int>( value ) )
+ : Detail::makeString( value );
+}
+
+std::string toString( signed char value ) {
+ return toString( static_cast<char>( value ) );
+}
+
+std::string toString( unsigned char value ) {
+ return toString( static_cast<char>( value ) );
+}
+
+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
+std::string toString( long long value ) {
+ std::ostringstream oss;
+ oss << value;
+ if( value > Detail::hexThreshold )
+ oss << " (0x" << std::hex << value << ")";
+ return oss.str();
+}
+std::string toString( unsigned long long value ) {
+ std::ostringstream oss;
+ oss << value;
+ if( value > Detail::hexThreshold )
+ oss << " (0x" << std::hex << value << ")";
+ return oss.str();
+}
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+std::string toString( std::nullptr_t ) {
+ return "nullptr";
+}
+#endif
+
+#ifdef __OBJC__
+ std::string toString( NSString const * const& nsstring ) {
+ if( !nsstring )
+ return "nil";
+ return "@" + toString([nsstring UTF8String]);
+ }
+ std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
+ if( !nsstring )
+ return "nil";
+ return "@" + toString([nsstring UTF8String]);
+ }
+ std::string toString( NSObject* const& nsObject ) {
+ return toString( [nsObject description] );
+ }
+#endif
+
+} // end namespace Catch
+
+// #included from: catch_result_builder.hpp
+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
+
+namespace Catch {
+
+ std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) {
+ return secondArg.empty() || secondArg == "\"\""
+ ? capturedExpression
+ : capturedExpression + ", " + secondArg;
+ }
+ ResultBuilder::ResultBuilder( char const* macroName,
+ SourceLineInfo const& lineInfo,
+ char const* capturedExpression,
+ ResultDisposition::Flags resultDisposition,
+ char const* secondArg )
+ : m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ),
+ m_shouldDebugBreak( false ),
+ m_shouldThrow( false )
+ {}
+
+ ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
+ m_data.resultType = result;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setResultType( bool result ) {
+ m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
+ m_exprComponents.lhs = lhs;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
+ m_exprComponents.rhs = rhs;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
+ m_exprComponents.op = op;
+ return *this;
+ }
+
+ void ResultBuilder::endExpression() {
+ m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
+ captureExpression();
+ }
+
+ void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
+ m_assertionInfo.resultDisposition = resultDisposition;
+ m_stream.oss << Catch::translateActiveException();
+ captureResult( ResultWas::ThrewException );
+ }
+
+ void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
+ setResultType( resultType );
+ captureExpression();
+ }
+ void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
+ if( expectedMessage.empty() )
+ captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );
+ else
+ captureExpectedException( Matchers::Equals( expectedMessage ) );
+ }
+
+ void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
+
+ assert( m_exprComponents.testFalse == false );
+ AssertionResultData data = m_data;
+ data.resultType = ResultWas::Ok;
+ data.reconstructedExpression = m_assertionInfo.capturedExpression;
+
+ std::string actualMessage = Catch::translateActiveException();
+ if( !matcher.match( actualMessage ) ) {
+ data.resultType = ResultWas::ExpressionFailed;
+ data.reconstructedExpression = actualMessage;
+ }
+ AssertionResult result( m_assertionInfo, data );
+ handleResult( result );
+ }
+
+ void ResultBuilder::captureExpression() {
+ AssertionResult result = build();
+ handleResult( result );
+ }
+ void ResultBuilder::handleResult( AssertionResult const& result )
+ {
+ getResultCapture().assertionEnded( result );
+
+ if( !result.isOk() ) {
+ if( getCurrentContext().getConfig()->shouldDebugBreak() )
+ m_shouldDebugBreak = true;
+ if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
+ m_shouldThrow = true;
+ }
+ }
+ void ResultBuilder::react() {
+ if( m_shouldThrow )
+ throw Catch::TestFailureException();
+ }
+
+ bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
+ bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
+
+ AssertionResult ResultBuilder::build() const
+ {
+ assert( m_data.resultType != ResultWas::Unknown );
+
+ AssertionResultData data = m_data;
+
+ // Flip bool results if testFalse is set
+ if( m_exprComponents.testFalse ) {
+ if( data.resultType == ResultWas::Ok )
+ data.resultType = ResultWas::ExpressionFailed;
+ else if( data.resultType == ResultWas::ExpressionFailed )
+ data.resultType = ResultWas::Ok;
+ }
+
+ data.message = m_stream.oss.str();
+ data.reconstructedExpression = reconstructExpression();
+ if( m_exprComponents.testFalse ) {
+ if( m_exprComponents.op == "" )
+ data.reconstructedExpression = "!" + data.reconstructedExpression;
+ else
+ data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
+ }
+ return AssertionResult( m_assertionInfo, data );
+ }
+ std::string ResultBuilder::reconstructExpression() const {
+ if( m_exprComponents.op == "" )
+ return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
+ else if( m_exprComponents.op == "matches" )
+ return m_exprComponents.lhs + " " + m_exprComponents.rhs;
+ else if( m_exprComponents.op != "!" ) {
+ if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
+ m_exprComponents.lhs.find("\n") == std::string::npos &&
+ m_exprComponents.rhs.find("\n") == std::string::npos )
+ return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
+ else
+ return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
+ }
+ else
+ return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
+ }
+
+} // end namespace Catch
+
+// #included from: catch_tag_alias_registry.hpp
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
+
+// #included from: catch_tag_alias_registry.h
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
+
+#include <map>
+
+namespace Catch {
+
+ class TagAliasRegistry : public ITagAliasRegistry {
+ public:
+ virtual ~TagAliasRegistry();
+ virtual Option<TagAlias> find( std::string const& alias ) const;
+ virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
+ void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
+ static TagAliasRegistry& get();
+
+ private:
+ std::map<std::string, TagAlias> m_registry;
+ };
+
+} // end namespace Catch
+
+#include <map>
+#include <iostream>
+
+namespace Catch {
+
+ TagAliasRegistry::~TagAliasRegistry() {}
+
+ Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
+ std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
+ if( it != m_registry.end() )
+ return it->second;
+ else
+ return Option<TagAlias>();
+ }
+
+ std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
+ std::string expandedTestSpec = unexpandedTestSpec;
+ for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
+ it != itEnd;
+ ++it ) {
+ std::size_t pos = expandedTestSpec.find( it->first );
+ if( pos != std::string::npos ) {
+ expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
+ it->second.tag +
+ expandedTestSpec.substr( pos + it->first.size() );
+ }
+ }
+ return expandedTestSpec;
+ }
+
+ void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
+
+ if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
+ std::ostringstream oss;
+ oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
+ throw std::domain_error( oss.str().c_str() );
+ }
+ if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
+ std::ostringstream oss;
+ oss << "error: tag alias, \"" << alias << "\" already registered.\n"
+ << "\tFirst seen at " << find(alias)->lineInfo << "\n"
+ << "\tRedefined at " << lineInfo;
+ throw std::domain_error( oss.str().c_str() );
+ }
+ }
+
+ TagAliasRegistry& TagAliasRegistry::get() {
+ static TagAliasRegistry instance;
+ return instance;
+
+ }
+
+ ITagAliasRegistry::~ITagAliasRegistry() {}
+ ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
+
+ RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
+ try {
+ TagAliasRegistry::get().add( alias, tag, lineInfo );
+ }
+ catch( std::exception& ex ) {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr() << ex.what() << std::endl;
+ exit(1);
+ }
+ }
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_multi.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
+
+namespace Catch {
+
+class MultipleReporters : public SharedImpl<IStreamingReporter> {
+ typedef std::vector<Ptr<IStreamingReporter> > Reporters;
+ Reporters m_reporters;
+
+public:
+ void add( Ptr<IStreamingReporter> const& reporter ) {
+ m_reporters.push_back( reporter );
+ }
+
+public: // IStreamingReporter
+
+ virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
+ return m_reporters[0]->getPreferences();
+ }
+
+ virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->noMatchingTestCases( spec );
+ }
+
+ virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testRunStarting( testRunInfo );
+ }
+
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testGroupStarting( groupInfo );
+ }
+
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testCaseStarting( testInfo );
+ }
+
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->sectionStarting( sectionInfo );
+ }
+
+ virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->assertionStarting( assertionInfo );
+ }
+
+ // The return value indicates if the messages buffer should be cleared:
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
+ bool clearBuffer = false;
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ clearBuffer |= (*it)->assertionEnded( assertionStats );
+ return clearBuffer;
+ }
+
+ virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->sectionEnded( sectionStats );
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testCaseEnded( testCaseStats );
+ }
+
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testGroupEnded( testGroupStats );
+ }
+
+ virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testRunEnded( testRunStats );
+ }
+
+ virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->skipTest( testInfo );
+ }
+};
+
+Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
+ Ptr<IStreamingReporter> resultingReporter;
+
+ if( existingReporter ) {
+ MultipleReporters* multi = dynamic_cast<MultipleReporters*>( existingReporter.get() );
+ if( !multi ) {
+ multi = new MultipleReporters;
+ resultingReporter = Ptr<IStreamingReporter>( multi );
+ if( existingReporter )
+ multi->add( existingReporter );
+ }
+ else
+ resultingReporter = existingReporter;
+ multi->add( additionalReporter );
+ }
+ else
+ resultingReporter = additionalReporter;
+
+ return resultingReporter;
+}
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_xml.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
+
+// #included from: catch_reporter_bases.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
+
+#include <cstring>
+
+namespace Catch {
+
+ struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
+
+ StreamingReporterBase( ReporterConfig const& _config )
+ : m_config( _config.fullConfig() ),
+ stream( _config.stream() )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = false;
+ }
+
+ virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
+ return m_reporterPrefs;
+ }
+
+ virtual ~StreamingReporterBase() CATCH_OVERRIDE;
+
+ virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}
+
+ virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {
+ currentTestRunInfo = _testRunInfo;
+ }
+ virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {
+ currentGroupInfo = _groupInfo;
+ }
+
+ virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {
+ currentTestCaseInfo = _testInfo;
+ }
+ virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
+ m_sectionStack.push_back( _sectionInfo );
+ }
+
+ virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE {
+ m_sectionStack.pop_back();
+ }
+ virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE {
+ currentTestCaseInfo.reset();
+ }
+ virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE {
+ currentGroupInfo.reset();
+ }
+ virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE {
+ currentTestCaseInfo.reset();
+ currentGroupInfo.reset();
+ currentTestRunInfo.reset();
+ }
+
+ virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {
+ // Don't do anything with this by default.
+ // It can optionally be overridden in the derived class.
+ }
+
+ Ptr<IConfig const> m_config;
+ std::ostream& stream;
+
+ LazyStat<TestRunInfo> currentTestRunInfo;
+ LazyStat<GroupInfo> currentGroupInfo;
+ LazyStat<TestCaseInfo> currentTestCaseInfo;
+
+ std::vector<SectionInfo> m_sectionStack;
+ ReporterPreferences m_reporterPrefs;
+ };
+
+ struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
+ template<typename T, typename ChildNodeT>
+ struct Node : SharedImpl<> {
+ explicit Node( T const& _value ) : value( _value ) {}
+ virtual ~Node() {}
+
+ typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
+ T value;
+ ChildNodes children;
+ };
+ struct SectionNode : SharedImpl<> {
+ explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
+ virtual ~SectionNode();
+
+ bool operator == ( SectionNode const& other ) const {
+ return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
+ }
+ bool operator == ( Ptr<SectionNode> const& other ) const {
+ return operator==( *other );
+ }
+
+ SectionStats stats;
+ typedef std::vector<Ptr<SectionNode> > ChildSections;
+ typedef std::vector<AssertionStats> Assertions;
+ ChildSections childSections;
+ Assertions assertions;
+ std::string stdOut;
+ std::string stdErr;
+ };
+
+ struct BySectionInfo {
+ BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
+ BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
+ bool operator() ( Ptr<SectionNode> const& node ) const {
+ return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
+ }
+ private:
+ void operator=( BySectionInfo const& );
+ SectionInfo const& m_other;
+ };
+
+ typedef Node<TestCaseStats, SectionNode> TestCaseNode;
+ typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
+ typedef Node<TestRunStats, TestGroupNode> TestRunNode;
+
+ CumulativeReporterBase( ReporterConfig const& _config )
+ : m_config( _config.fullConfig() ),
+ stream( _config.stream() )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = false;
+ }
+ ~CumulativeReporterBase();
+
+ virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
+ return m_reporterPrefs;
+ }
+
+ virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}
+ virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}
+
+ virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}
+
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
+ SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
+ Ptr<SectionNode> node;
+ if( m_sectionStack.empty() ) {
+ if( !m_rootSection )
+ m_rootSection = new SectionNode( incompleteStats );
+ node = m_rootSection;
+ }
+ else {
+ SectionNode& parentNode = *m_sectionStack.back();
+ SectionNode::ChildSections::const_iterator it =
+ std::find_if( parentNode.childSections.begin(),
+ parentNode.childSections.end(),
+ BySectionInfo( sectionInfo ) );
+ if( it == parentNode.childSections.end() ) {
+ node = new SectionNode( incompleteStats );
+ parentNode.childSections.push_back( node );
+ }
+ else
+ node = *it;
+ }
+ m_sectionStack.push_back( node );
+ m_deepestSection = node;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) {
+ assert( !m_sectionStack.empty() );
+ SectionNode& sectionNode = *m_sectionStack.back();
+ sectionNode.assertions.push_back( assertionStats );
+ return true;
+ }
+ virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
+ assert( !m_sectionStack.empty() );
+ SectionNode& node = *m_sectionStack.back();
+ node.stats = sectionStats;
+ m_sectionStack.pop_back();
+ }
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+ Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
+ assert( m_sectionStack.size() == 0 );
+ node->children.push_back( m_rootSection );
+ m_testCases.push_back( node );
+ m_rootSection.reset();
+
+ assert( m_deepestSection );
+ m_deepestSection->stdOut = testCaseStats.stdOut;
+ m_deepestSection->stdErr = testCaseStats.stdErr;
+ }
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+ Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
+ node->children.swap( m_testCases );
+ m_testGroups.push_back( node );
+ }
+ virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
+ Ptr<TestRunNode> node = new TestRunNode( testRunStats );
+ node->children.swap( m_testGroups );
+ m_testRuns.push_back( node );
+ testRunEndedCumulative();
+ }
+ virtual void testRunEndedCumulative() = 0;
+
+ virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
+
+ Ptr<IConfig const> m_config;
+ std::ostream& stream;
+ std::vector<AssertionStats> m_assertions;
+ std::vector<std::vector<Ptr<SectionNode> > > m_sections;
+ std::vector<Ptr<TestCaseNode> > m_testCases;
+ std::vector<Ptr<TestGroupNode> > m_testGroups;
+
+ std::vector<Ptr<TestRunNode> > m_testRuns;
+
+ Ptr<SectionNode> m_rootSection;
+ Ptr<SectionNode> m_deepestSection;
+ std::vector<Ptr<SectionNode> > m_sectionStack;
+ ReporterPreferences m_reporterPrefs;
+
+ };
+
+ template<char C>
+ char const* getLineOfChars() {
+ static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
+ if( !*line ) {
+ memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
+ line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
+ }
+ return line;
+ }
+
+ struct TestEventListenerBase : StreamingReporterBase {
+ TestEventListenerBase( ReporterConfig const& _config )
+ : StreamingReporterBase( _config )
+ {}
+
+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
+ virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {
+ return false;
+ }
+ };
+
+} // end namespace Catch
+
+// #included from: ../internal/catch_reporter_registrars.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
+
+namespace Catch {
+
+ template<typename T>
+ class LegacyReporterRegistrar {
+
+ class ReporterFactory : public IReporterFactory {
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+ return new LegacyReporterAdapter( new T( config ) );
+ }
+
+ virtual std::string getDescription() const {
+ return T::getDescription();
+ }
+ };
+
+ public:
+
+ LegacyReporterRegistrar( std::string const& name ) {
+ getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
+ }
+ };
+
+ template<typename T>
+ class ReporterRegistrar {
+
+ class ReporterFactory : public SharedImpl<IReporterFactory> {
+
+ // *** Please Note ***:
+ // - If you end up here looking at a compiler error because it's trying to register
+ // your custom reporter class be aware that the native reporter interface has changed
+ // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
+ // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
+ // However please consider updating to the new interface as the old one is now
+ // deprecated and will probably be removed quite soon!
+ // Please contact me via github if you have any questions at all about this.
+ // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
+ // no idea who is actually using custom reporters at all (possibly no-one!).
+ // The new interface is designed to minimise exposure to interface changes in the future.
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+ return new T( config );
+ }
+
+ virtual std::string getDescription() const {
+ return T::getDescription();
+ }
+ };
+
+ public:
+
+ ReporterRegistrar( std::string const& name ) {
+ getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
+ }
+ };
+
+ template<typename T>
+ class ListenerRegistrar {
+
+ class ListenerFactory : public SharedImpl<IReporterFactory> {
+
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+ return new T( config );
+ }
+ virtual std::string getDescription() const {
+ return "";
+ }
+ };
+
+ public:
+
+ ListenerRegistrar() {
+ getMutableRegistryHub().registerListener( new ListenerFactory() );
+ }
+ };
+}
+
+#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
+ namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
+
+#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
+ namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
+
+#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
+ namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
+
+// #included from: ../internal/catch_xmlwriter.hpp
+#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
+
+#include <sstream>
+#include <string>
+#include <vector>
+#include <iomanip>
+
+namespace Catch {
+
+ class XmlEncode {
+ public:
+ enum ForWhat { ForTextNodes, ForAttributes };
+
+ XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
+ : m_str( str ),
+ m_forWhat( forWhat )
+ {}
+
+ void encodeTo( std::ostream& os ) const {
+
+ // Apostrophe escaping not necessary if we always use " to write attributes
+ // (see: http://www.w3.org/TR/xml/#syntax)
+
+ for( std::size_t i = 0; i < m_str.size(); ++ i ) {
+ char c = m_str[i];
+ switch( c ) {
+ case '<': os << "&lt;"; break;
+ case '&': os << "&amp;"; break;
+
+ case '>':
+ // See: http://www.w3.org/TR/xml/#syntax
+ if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
+ os << "&gt;";
+ else
+ os << c;
+ break;
+
+ case '\"':
+ if( m_forWhat == ForAttributes )
+ os << "&quot;";
+ else
+ os << c;
+ break;
+
+ default:
+ // Escape control chars - based on contribution by @espenalb in PR #465
+ if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
+ os << "&#x" << std::uppercase << std::hex << static_cast<int>( c );
+ else
+ os << c;
+ }
+ }
+ }
+
+ friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
+ xmlEncode.encodeTo( os );
+ return os;
+ }
+
+ private:
+ std::string m_str;
+ ForWhat m_forWhat;
+ };
+
+ class XmlWriter {
+ public:
+
+ class ScopedElement {
+ public:
+ ScopedElement( XmlWriter* writer )
+ : m_writer( writer )
+ {}
+
+ ScopedElement( ScopedElement const& other )
+ : m_writer( other.m_writer ){
+ other.m_writer = CATCH_NULL;
+ }
+
+ ~ScopedElement() {
+ if( m_writer )
+ m_writer->endElement();
+ }
+
+ ScopedElement& writeText( std::string const& text, bool indent = true ) {
+ m_writer->writeText( text, indent );
+ return *this;
+ }
+
+ template<typename T>
+ ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
+ m_writer->writeAttribute( name, attribute );
+ return *this;
+ }
+
+ private:
+ mutable XmlWriter* m_writer;
+ };
+
+ XmlWriter()
+ : m_tagIsOpen( false ),
+ m_needsNewline( false ),
+ m_os( &Catch::cout() )
+ {}
+
+ XmlWriter( std::ostream& os )
+ : m_tagIsOpen( false ),
+ m_needsNewline( false ),
+ m_os( &os )
+ {}
+
+ ~XmlWriter() {
+ while( !m_tags.empty() )
+ endElement();
+ }
+
+ XmlWriter& startElement( std::string const& name ) {
+ ensureTagClosed();
+ newlineIfNecessary();
+ stream() << m_indent << "<" << name;
+ m_tags.push_back( name );
+ m_indent += " ";
+ m_tagIsOpen = true;
+ return *this;
+ }
+
+ ScopedElement scopedElement( std::string const& name ) {
+ ScopedElement scoped( this );
+ startElement( name );
+ return scoped;
+ }
+
+ XmlWriter& endElement() {
+ newlineIfNecessary();
+ m_indent = m_indent.substr( 0, m_indent.size()-2 );
+ if( m_tagIsOpen ) {
+ stream() << "/>\n";
+ m_tagIsOpen = false;
+ }
+ else {
+ stream() << m_indent << "</" << m_tags.back() << ">\n";
+ }
+ m_tags.pop_back();
+ return *this;
+ }
+
+ XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
+ if( !name.empty() && !attribute.empty() )
+ stream() << " " << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << "\"";
+ return *this;
+ }
+
+ XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
+ stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
+ return *this;
+ }
+
+ template<typename T>
+ XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
+ std::ostringstream oss;
+ oss << attribute;
+ return writeAttribute( name, oss.str() );
+ }
+
+ XmlWriter& writeText( std::string const& text, bool indent = true ) {
+ if( !text.empty() ){
+ bool tagWasOpen = m_tagIsOpen;
+ ensureTagClosed();
+ if( tagWasOpen && indent )
+ stream() << m_indent;
+ stream() << XmlEncode( text );
+ m_needsNewline = true;
+ }
+ return *this;
+ }
+
+ XmlWriter& writeComment( std::string const& text ) {
+ ensureTagClosed();
+ stream() << m_indent << "<!--" << text << "-->";
+ m_needsNewline = true;
+ return *this;
+ }
+
+ XmlWriter& writeBlankLine() {
+ ensureTagClosed();
+ stream() << "\n";
+ return *this;
+ }
+
+ void setStream( std::ostream& os ) {
+ m_os = &os;
+ }
+
+ private:
+ XmlWriter( XmlWriter const& );
+ void operator=( XmlWriter const& );
+
+ std::ostream& stream() {
+ return *m_os;
+ }
+
+ void ensureTagClosed() {
+ if( m_tagIsOpen ) {
+ stream() << ">\n";
+ m_tagIsOpen = false;
+ }
+ }
+
+ void newlineIfNecessary() {
+ if( m_needsNewline ) {
+ stream() << "\n";
+ m_needsNewline = false;
+ }
+ }
+
+ bool m_tagIsOpen;
+ bool m_needsNewline;
+ std::vector<std::string> m_tags;
+ std::string m_indent;
+ std::ostream* m_os;
+ };
+
+}
+// #included from: catch_reenable_warnings.h
+
+#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
+
+#ifdef __clang__
+# ifdef __ICC // icpc defines the __clang__ macro
+# pragma warning(pop)
+# else
+# pragma clang diagnostic pop
+# endif
+#elif defined __GNUC__
+# pragma GCC diagnostic pop
+#endif
+
+
+namespace Catch {
+ class XmlReporter : public StreamingReporterBase {
+ public:
+ XmlReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config ),
+ m_sectionDepth( 0 )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = true;
+ }
+
+ virtual ~XmlReporter() CATCH_OVERRIDE;
+
+ static std::string getDescription() {
+ return "Reports test results as an XML document";
+ }
+
+ public: // StreamingReporterBase
+
+ virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
+ StreamingReporterBase::noMatchingTestCases( s );
+ }
+
+ virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
+ StreamingReporterBase::testRunStarting( testInfo );
+ m_xml.setStream( stream );
+ m_xml.startElement( "Catch" );
+ if( !m_config->name().empty() )
+ m_xml.writeAttribute( "name", m_config->name() );
+ }
+
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
+ StreamingReporterBase::testGroupStarting( groupInfo );
+ m_xml.startElement( "Group" )
+ .writeAttribute( "name", groupInfo.name );
+ }
+
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
+ StreamingReporterBase::testCaseStarting(testInfo);
+ m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ m_testCaseTimer.start();
+ }
+
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
+ StreamingReporterBase::sectionStarting( sectionInfo );
+ if( m_sectionDepth++ > 0 ) {
+ m_xml.startElement( "Section" )
+ .writeAttribute( "name", trim( sectionInfo.name ) )
+ .writeAttribute( "description", sectionInfo.description );
+ }
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
+ const AssertionResult& assertionResult = assertionStats.assertionResult;
+
+ // Print any info messages in <Info> tags.
+ if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
+ for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
+ it != itEnd;
+ ++it ) {
+ if( it->type == ResultWas::Info ) {
+ m_xml.scopedElement( "Info" )
+ .writeText( it->message );
+ } else if ( it->type == ResultWas::Warning ) {
+ m_xml.scopedElement( "Warning" )
+ .writeText( it->message );
+ }
+ }
+ }
+
+ // Drop out if result was successful but we're not printing them.
+ if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
+ return true;
+
+ // Print the expression if there is one.
+ if( assertionResult.hasExpression() ) {
+ m_xml.startElement( "Expression" )
+ .writeAttribute( "success", assertionResult.succeeded() )
+ .writeAttribute( "type", assertionResult.getTestMacroName() )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line );
+
+ m_xml.scopedElement( "Original" )
+ .writeText( assertionResult.getExpression() );
+ m_xml.scopedElement( "Expanded" )
+ .writeText( assertionResult.getExpandedExpression() );
+ }
+
+ // And... Print a result applicable to each result type.
+ switch( assertionResult.getResultType() ) {
+ case ResultWas::ThrewException:
+ m_xml.scopedElement( "Exception" )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::FatalErrorCondition:
+ m_xml.scopedElement( "Fatal Error Condition" )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::Info:
+ m_xml.scopedElement( "Info" )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::Warning:
+ // Warning will already have been written
+ break;
+ case ResultWas::ExplicitFailure:
+ m_xml.scopedElement( "Failure" )
+ .writeText( assertionResult.getMessage() );
+ break;
+ default:
+ break;
+ }
+
+ if( assertionResult.hasExpression() )
+ m_xml.endElement();
+
+ return true;
+ }
+
+ virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::sectionEnded( sectionStats );
+ if( --m_sectionDepth > 0 ) {
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
+ e.writeAttribute( "successes", sectionStats.assertions.passed );
+ e.writeAttribute( "failures", sectionStats.assertions.failed );
+ e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
+
+ m_xml.endElement();
+ }
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::testCaseEnded( testCaseStats );
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
+ e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
+
+ m_xml.endElement();
+ }
+
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::testGroupEnded( testGroupStats );
+ // TODO: Check testGroupStats.aborting and act accordingly.
+ m_xml.scopedElement( "OverallResults" )
+ .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
+ .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
+ .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
+ m_xml.endElement();
+ }
+
+ virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::testRunEnded( testRunStats );
+ m_xml.scopedElement( "OverallResults" )
+ .writeAttribute( "successes", testRunStats.totals.assertions.passed )
+ .writeAttribute( "failures", testRunStats.totals.assertions.failed )
+ .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
+ m_xml.endElement();
+ }
+
+ private:
+ Timer m_testCaseTimer;
+ XmlWriter m_xml;
+ int m_sectionDepth;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_junit.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
+
+#include <assert.h>
+
+namespace Catch {
+
+ class JunitReporter : public CumulativeReporterBase {
+ public:
+ JunitReporter( ReporterConfig const& _config )
+ : CumulativeReporterBase( _config ),
+ xml( _config.stream() )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = true;
+ }
+
+ virtual ~JunitReporter() CATCH_OVERRIDE;
+
+ static std::string getDescription() {
+ return "Reports test results in an XML format that looks like Ant's junitreport target";
+ }
+
+ virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {}
+
+ virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {
+ CumulativeReporterBase::testRunStarting( runInfo );
+ xml.startElement( "testsuites" );
+ }
+
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
+ suiteTimer.start();
+ stdOutForSuite.str("");
+ stdErrForSuite.str("");
+ unexpectedExceptions = 0;
+ CumulativeReporterBase::testGroupStarting( groupInfo );
+ }
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
+ if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
+ unexpectedExceptions++;
+ return CumulativeReporterBase::assertionEnded( assertionStats );
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+ stdOutForSuite << testCaseStats.stdOut;
+ stdErrForSuite << testCaseStats.stdErr;
+ CumulativeReporterBase::testCaseEnded( testCaseStats );
+ }
+
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+ double suiteTime = suiteTimer.getElapsedSeconds();
+ CumulativeReporterBase::testGroupEnded( testGroupStats );
+ writeGroup( *m_testGroups.back(), suiteTime );
+ }
+
+ virtual void testRunEndedCumulative() CATCH_OVERRIDE {
+ xml.endElement();
+ }
+
+ void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
+ XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
+ TestGroupStats const& stats = groupNode.value;
+ xml.writeAttribute( "name", stats.groupInfo.name );
+ xml.writeAttribute( "errors", unexpectedExceptions );
+ xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
+ xml.writeAttribute( "tests", stats.totals.assertions.total() );
+ xml.writeAttribute( "hostname", "tbd" ); // !TBD
+ if( m_config->showDurations() == ShowDurations::Never )
+ xml.writeAttribute( "time", "" );
+ else
+ xml.writeAttribute( "time", suiteTime );
+ xml.writeAttribute( "timestamp", "tbd" ); // !TBD
+
+ // Write test cases
+ for( TestGroupNode::ChildNodes::const_iterator
+ it = groupNode.children.begin(), itEnd = groupNode.children.end();
+ it != itEnd;
+ ++it )
+ writeTestCase( **it );
+
+ xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
+ xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
+ }
+
+ void writeTestCase( TestCaseNode const& testCaseNode ) {
+ TestCaseStats const& stats = testCaseNode.value;
+
+ // All test cases have exactly one section - which represents the
+ // test case itself. That section may have 0-n nested sections
+ assert( testCaseNode.children.size() == 1 );
+ SectionNode const& rootSection = *testCaseNode.children.front();
+
+ std::string className = stats.testInfo.className;
+
+ if( className.empty() ) {
+ if( rootSection.childSections.empty() )
+ className = "global";
+ }
+ writeSection( className, "", rootSection );
+ }
+
+ void writeSection( std::string const& className,
+ std::string const& rootName,
+ SectionNode const& sectionNode ) {
+ std::string name = trim( sectionNode.stats.sectionInfo.name );
+ if( !rootName.empty() )
+ name = rootName + "/" + name;
+
+ if( !sectionNode.assertions.empty() ||
+ !sectionNode.stdOut.empty() ||
+ !sectionNode.stdErr.empty() ) {
+ XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
+ if( className.empty() ) {
+ xml.writeAttribute( "classname", name );
+ xml.writeAttribute( "name", "root" );
+ }
+ else {
+ xml.writeAttribute( "classname", className );
+ xml.writeAttribute( "name", name );
+ }
+ xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
+
+ writeAssertions( sectionNode );
+
+ if( !sectionNode.stdOut.empty() )
+ xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
+ if( !sectionNode.stdErr.empty() )
+ xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
+ }
+ for( SectionNode::ChildSections::const_iterator
+ it = sectionNode.childSections.begin(),
+ itEnd = sectionNode.childSections.end();
+ it != itEnd;
+ ++it )
+ if( className.empty() )
+ writeSection( name, "", **it );
+ else
+ writeSection( className, name, **it );
+ }
+
+ void writeAssertions( SectionNode const& sectionNode ) {
+ for( SectionNode::Assertions::const_iterator
+ it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
+ it != itEnd;
+ ++it )
+ writeAssertion( *it );
+ }
+ void writeAssertion( AssertionStats const& stats ) {
+ AssertionResult const& result = stats.assertionResult;
+ if( !result.isOk() ) {
+ std::string elementName;
+ switch( result.getResultType() ) {
+ case ResultWas::ThrewException:
+ case ResultWas::FatalErrorCondition:
+ elementName = "error";
+ break;
+ case ResultWas::ExplicitFailure:
+ elementName = "failure";
+ break;
+ case ResultWas::ExpressionFailed:
+ elementName = "failure";
+ break;
+ case ResultWas::DidntThrowException:
+ elementName = "failure";
+ break;
+
+ // We should never see these here:
+ case ResultWas::Info:
+ case ResultWas::Warning:
+ case ResultWas::Ok:
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ elementName = "internalError";
+ break;
+ }
+
+ XmlWriter::ScopedElement e = xml.scopedElement( elementName );
+
+ xml.writeAttribute( "message", result.getExpandedExpression() );
+ xml.writeAttribute( "type", result.getTestMacroName() );
+
+ std::ostringstream oss;
+ if( !result.getMessage().empty() )
+ oss << result.getMessage() << "\n";
+ for( std::vector<MessageInfo>::const_iterator
+ it = stats.infoMessages.begin(),
+ itEnd = stats.infoMessages.end();
+ it != itEnd;
+ ++it )
+ if( it->type == ResultWas::Info )
+ oss << it->message << "\n";
+
+ oss << "at " << result.getSourceInfo();
+ xml.writeText( oss.str(), false );
+ }
+ }
+
+ XmlWriter xml;
+ Timer suiteTimer;
+ std::ostringstream stdOutForSuite;
+ std::ostringstream stdErrForSuite;
+ unsigned int unexpectedExceptions;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_console.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
+
+namespace Catch {
+
+ struct ConsoleReporter : StreamingReporterBase {
+ ConsoleReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config ),
+ m_headerPrinted( false )
+ {}
+
+ virtual ~ConsoleReporter() CATCH_OVERRIDE;
+ static std::string getDescription() {
+ return "Reports test results as plain lines of text";
+ }
+
+ virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
+ stream << "No test cases matched '" << spec << "'" << std::endl;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
+ }
+
+ virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
+ AssertionResult const& result = _assertionStats.assertionResult;
+
+ bool printInfoMessages = true;
+
+ // Drop out if result was successful and we're not printing those
+ if( !m_config->includeSuccessfulResults() && result.isOk() ) {
+ if( result.getResultType() != ResultWas::Warning )
+ return false;
+ printInfoMessages = false;
+ }
+
+ lazyPrint();
+
+ AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
+ printer.print();
+ stream << std::endl;
+ return true;
+ }
+
+ virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
+ m_headerPrinted = false;
+ StreamingReporterBase::sectionStarting( _sectionInfo );
+ }
+ virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {
+ if( _sectionStats.missingAssertions ) {
+ lazyPrint();
+ Colour colour( Colour::ResultError );
+ if( m_sectionStack.size() > 1 )
+ stream << "\nNo assertions in section";
+ else
+ stream << "\nNo assertions in test case";
+ stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
+ }
+ if( m_headerPrinted ) {
+ if( m_config->showDurations() == ShowDurations::Always )
+ stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
+ m_headerPrinted = false;
+ }
+ else {
+ if( m_config->showDurations() == ShowDurations::Always )
+ stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
+ }
+ StreamingReporterBase::sectionEnded( _sectionStats );
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::testCaseEnded( _testCaseStats );
+ m_headerPrinted = false;
+ }
+ virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {
+ if( currentGroupInfo.used ) {
+ printSummaryDivider();
+ stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
+ printTotals( _testGroupStats.totals );
+ stream << "\n" << std::endl;
+ }
+ StreamingReporterBase::testGroupEnded( _testGroupStats );
+ }
+ virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {
+ printTotalsDivider( _testRunStats.totals );
+ printTotals( _testRunStats.totals );
+ stream << std::endl;
+ StreamingReporterBase::testRunEnded( _testRunStats );
+ }
+
+ private:
+
+ class AssertionPrinter {
+ void operator= ( AssertionPrinter const& );
+ public:
+ AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
+ : stream( _stream ),
+ stats( _stats ),
+ result( _stats.assertionResult ),
+ colour( Colour::None ),
+ message( result.getMessage() ),
+ messages( _stats.infoMessages ),
+ printInfoMessages( _printInfoMessages )
+ {
+ switch( result.getResultType() ) {
+ case ResultWas::Ok:
+ colour = Colour::Success;
+ passOrFail = "PASSED";
+ //if( result.hasMessage() )
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "with messages";
+ break;
+ case ResultWas::ExpressionFailed:
+ if( result.isOk() ) {
+ colour = Colour::Success;
+ passOrFail = "FAILED - but was ok";
+ }
+ else {
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ }
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "with messages";
+ break;
+ case ResultWas::ThrewException:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "due to unexpected exception with message";
+ break;
+ case ResultWas::FatalErrorCondition:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "due to a fatal error condition";
+ break;
+ case ResultWas::DidntThrowException:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "because no exception was thrown where one was expected";
+ break;
+ case ResultWas::Info:
+ messageLabel = "info";
+ break;
+ case ResultWas::Warning:
+ messageLabel = "warning";
+ break;
+ case ResultWas::ExplicitFailure:
+ passOrFail = "FAILED";
+ colour = Colour::Error;
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "explicitly with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "explicitly with messages";
+ break;
+ // These cases are here to prevent compiler warnings
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ passOrFail = "** internal error **";
+ colour = Colour::Error;
+ break;
+ }
+ }
+
+ void print() const {
+ printSourceInfo();
+ if( stats.totals.assertions.total() > 0 ) {
+ if( result.isOk() )
+ stream << "\n";
+ printResultType();
+ printOriginalExpression();
+ printReconstructedExpression();
+ }
+ else {
+ stream << "\n";
+ }
+ printMessage();
+ }
+
+ private:
+ void printResultType() const {
+ if( !passOrFail.empty() ) {
+ Colour colourGuard( colour );
+ stream << passOrFail << ":\n";
+ }
+ }
+ void printOriginalExpression() const {
+ if( result.hasExpression() ) {
+ Colour colourGuard( Colour::OriginalExpression );
+ stream << " ";
+ stream << result.getExpressionInMacro();
+ stream << "\n";
+ }
+ }
+ void printReconstructedExpression() const {
+ if( result.hasExpandedExpression() ) {
+ stream << "with expansion:\n";
+ Colour colourGuard( Colour::ReconstructedExpression );
+ stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
+ }
+ }
+ void printMessage() const {
+ if( !messageLabel.empty() )
+ stream << messageLabel << ":" << "\n";
+ for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
+ it != itEnd;
+ ++it ) {
+ // If this assertion is a warning ignore any INFO messages
+ if( printInfoMessages || it->type != ResultWas::Info )
+ stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
+ }
+ }
+ void printSourceInfo() const {
+ Colour colourGuard( Colour::FileName );
+ stream << result.getSourceInfo() << ": ";
+ }
+
+ std::ostream& stream;
+ AssertionStats const& stats;
+ AssertionResult const& result;
+ Colour::Code colour;
+ std::string passOrFail;
+ std::string messageLabel;
+ std::string message;
+ std::vector<MessageInfo> messages;
+ bool printInfoMessages;
+ };
+
+ void lazyPrint() {
+
+ if( !currentTestRunInfo.used )
+ lazyPrintRunInfo();
+ if( !currentGroupInfo.used )
+ lazyPrintGroupInfo();
+
+ if( !m_headerPrinted ) {
+ printTestCaseAndSectionHeader();
+ m_headerPrinted = true;
+ }
+ }
+ void lazyPrintRunInfo() {
+ stream << "\n" << getLineOfChars<'~'>() << "\n";
+ Colour colour( Colour::SecondaryText );
+ stream << currentTestRunInfo->name
+ << " is a Catch v" << libraryVersion << " host application.\n"
+ << "Run with -? for options\n\n";
+
+ if( m_config->rngSeed() != 0 )
+ stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
+
+ currentTestRunInfo.used = true;
+ }
+ void lazyPrintGroupInfo() {
+ if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
+ printClosedHeader( "Group: " + currentGroupInfo->name );
+ currentGroupInfo.used = true;
+ }
+ }
+ void printTestCaseAndSectionHeader() {
+ assert( !m_sectionStack.empty() );
+ printOpenHeader( currentTestCaseInfo->name );
+
+ if( m_sectionStack.size() > 1 ) {
+ Colour colourGuard( Colour::Headers );
+
+ std::vector<SectionInfo>::const_iterator
+ it = m_sectionStack.begin()+1, // Skip first section (test case)
+ itEnd = m_sectionStack.end();
+ for( ; it != itEnd; ++it )
+ printHeaderString( it->name, 2 );
+ }
+
+ SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
+
+ if( !lineInfo.empty() ){
+ stream << getLineOfChars<'-'>() << "\n";
+ Colour colourGuard( Colour::FileName );
+ stream << lineInfo << "\n";
+ }
+ stream << getLineOfChars<'.'>() << "\n" << std::endl;
+ }
+
+ void printClosedHeader( std::string const& _name ) {
+ printOpenHeader( _name );
+ stream << getLineOfChars<'.'>() << "\n";
+ }
+ void printOpenHeader( std::string const& _name ) {
+ stream << getLineOfChars<'-'>() << "\n";
+ {
+ Colour colourGuard( Colour::Headers );
+ printHeaderString( _name );
+ }
+ }
+
+ // if string has a : in first line will set indent to follow it on
+ // subsequent lines
+ void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
+ std::size_t i = _string.find( ": " );
+ if( i != std::string::npos )
+ i+=2;
+ else
+ i = 0;
+ stream << Text( _string, TextAttributes()
+ .setIndent( indent+i)
+ .setInitialIndent( indent ) ) << "\n";
+ }
+
+ struct SummaryColumn {
+
+ SummaryColumn( std::string const& _label, Colour::Code _colour )
+ : label( _label ),
+ colour( _colour )
+ {}
+ SummaryColumn addRow( std::size_t count ) {
+ std::ostringstream oss;
+ oss << count;
+ std::string row = oss.str();
+ for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
+ while( it->size() < row.size() )
+ *it = " " + *it;
+ while( it->size() > row.size() )
+ row = " " + row;
+ }
+ rows.push_back( row );
+ return *this;
+ }
+
+ std::string label;
+ Colour::Code colour;
+ std::vector<std::string> rows;
+
+ };
+
+ void printTotals( Totals const& totals ) {
+ if( totals.testCases.total() == 0 ) {
+ stream << Colour( Colour::Warning ) << "No tests ran\n";
+ }
+ else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
+ stream << Colour( Colour::ResultSuccess ) << "All tests passed";
+ stream << " ("
+ << pluralise( totals.assertions.passed, "assertion" ) << " in "
+ << pluralise( totals.testCases.passed, "test case" ) << ")"
+ << "\n";
+ }
+ else {
+
+ std::vector<SummaryColumn> columns;
+ columns.push_back( SummaryColumn( "", Colour::None )
+ .addRow( totals.testCases.total() )
+ .addRow( totals.assertions.total() ) );
+ columns.push_back( SummaryColumn( "passed", Colour::Success )
+ .addRow( totals.testCases.passed )
+ .addRow( totals.assertions.passed ) );
+ columns.push_back( SummaryColumn( "failed", Colour::ResultError )
+ .addRow( totals.testCases.failed )
+ .addRow( totals.assertions.failed ) );
+ columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
+ .addRow( totals.testCases.failedButOk )
+ .addRow( totals.assertions.failedButOk ) );
+
+ printSummaryRow( "test cases", columns, 0 );
+ printSummaryRow( "assertions", columns, 1 );
+ }
+ }
+ void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
+ for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
+ std::string value = it->rows[row];
+ if( it->label.empty() ) {
+ stream << label << ": ";
+ if( value != "0" )
+ stream << value;
+ else
+ stream << Colour( Colour::Warning ) << "- none -";
+ }
+ else if( value != "0" ) {
+ stream << Colour( Colour::LightGrey ) << " | ";
+ stream << Colour( it->colour )
+ << value << " " << it->label;
+ }
+ }
+ stream << "\n";
+ }
+
+ static std::size_t makeRatio( std::size_t number, std::size_t total ) {
+ std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
+ return ( ratio == 0 && number > 0 ) ? 1 : ratio;
+ }
+ static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
+ if( i > j && i > k )
+ return i;
+ else if( j > k )
+ return j;
+ else
+ return k;
+ }
+
+ void printTotalsDivider( Totals const& totals ) {
+ if( totals.testCases.total() > 0 ) {
+ std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
+ std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
+ std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
+ while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
+ findMax( failedRatio, failedButOkRatio, passedRatio )++;
+ while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
+ findMax( failedRatio, failedButOkRatio, passedRatio )--;
+
+ stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
+ stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
+ if( totals.testCases.allPassed() )
+ stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
+ else
+ stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
+ }
+ else {
+ stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
+ }
+ stream << "\n";
+ }
+ void printSummaryDivider() {
+ stream << getLineOfChars<'-'>() << "\n";
+ }
+
+ private:
+ bool m_headerPrinted;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_compact.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
+
+namespace Catch {
+
+ struct CompactReporter : StreamingReporterBase {
+
+ CompactReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config )
+ {}
+
+ virtual ~CompactReporter();
+
+ static std::string getDescription() {
+ return "Reports test results on a single line, suitable for IDEs";
+ }
+
+ virtual ReporterPreferences getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = false;
+ return prefs;
+ }
+
+ virtual void noMatchingTestCases( std::string const& spec ) {
+ stream << "No test cases matched '" << spec << "'" << std::endl;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) {
+ }
+
+ virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
+ AssertionResult const& result = _assertionStats.assertionResult;
+
+ bool printInfoMessages = true;
+
+ // Drop out if result was successful and we're not printing those
+ if( !m_config->includeSuccessfulResults() && result.isOk() ) {
+ if( result.getResultType() != ResultWas::Warning )
+ return false;
+ printInfoMessages = false;
+ }
+
+ AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
+ printer.print();
+
+ stream << std::endl;
+ return true;
+ }
+
+ virtual void testRunEnded( TestRunStats const& _testRunStats ) {
+ printTotals( _testRunStats.totals );
+ stream << "\n" << std::endl;
+ StreamingReporterBase::testRunEnded( _testRunStats );
+ }
+
+ private:
+ class AssertionPrinter {
+ void operator= ( AssertionPrinter const& );
+ public:
+ AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
+ : stream( _stream )
+ , stats( _stats )
+ , result( _stats.assertionResult )
+ , messages( _stats.infoMessages )
+ , itMessage( _stats.infoMessages.begin() )
+ , printInfoMessages( _printInfoMessages )
+ {}
+
+ void print() {
+ printSourceInfo();
+
+ itMessage = messages.begin();
+
+ switch( result.getResultType() ) {
+ case ResultWas::Ok:
+ printResultType( Colour::ResultSuccess, passedString() );
+ printOriginalExpression();
+ printReconstructedExpression();
+ if ( ! result.hasExpression() )
+ printRemainingMessages( Colour::None );
+ else
+ printRemainingMessages();
+ break;
+ case ResultWas::ExpressionFailed:
+ if( result.isOk() )
+ printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
+ else
+ printResultType( Colour::Error, failedString() );
+ printOriginalExpression();
+ printReconstructedExpression();
+ printRemainingMessages();
+ break;
+ case ResultWas::ThrewException:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "unexpected exception with message:" );
+ printMessage();
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::FatalErrorCondition:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "fatal error condition with message:" );
+ printMessage();
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::DidntThrowException:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "expected exception, got none" );
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::Info:
+ printResultType( Colour::None, "info" );
+ printMessage();
+ printRemainingMessages();
+ break;
+ case ResultWas::Warning:
+ printResultType( Colour::None, "warning" );
+ printMessage();
+ printRemainingMessages();
+ break;
+ case ResultWas::ExplicitFailure:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "explicitly" );
+ printRemainingMessages( Colour::None );
+ break;
+ // These cases are here to prevent compiler warnings
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ printResultType( Colour::Error, "** internal error **" );
+ break;
+ }
+ }
+
+ private:
+ // Colour::LightGrey
+
+ static Colour::Code dimColour() { return Colour::FileName; }
+
+#ifdef CATCH_PLATFORM_MAC
+ static const char* failedString() { return "FAILED"; }
+ static const char* passedString() { return "PASSED"; }
+#else
+ static const char* failedString() { return "failed"; }
+ static const char* passedString() { return "passed"; }
+#endif
+
+ void printSourceInfo() const {
+ Colour colourGuard( Colour::FileName );
+ stream << result.getSourceInfo() << ":";
+ }
+
+ void printResultType( Colour::Code colour, std::string passOrFail ) const {
+ if( !passOrFail.empty() ) {
+ {
+ Colour colourGuard( colour );
+ stream << " " << passOrFail;
+ }
+ stream << ":";
+ }
+ }
+
+ void printIssue( std::string issue ) const {
+ stream << " " << issue;
+ }
+
+ void printExpressionWas() {
+ if( result.hasExpression() ) {
+ stream << ";";
+ {
+ Colour colour( dimColour() );
+ stream << " expression was:";
+ }
+ printOriginalExpression();
+ }
+ }
+
+ void printOriginalExpression() const {
+ if( result.hasExpression() ) {
+ stream << " " << result.getExpression();
+ }
+ }
+
+ void printReconstructedExpression() const {
+ if( result.hasExpandedExpression() ) {
+ {
+ Colour colour( dimColour() );
+ stream << " for: ";
+ }
+ stream << result.getExpandedExpression();
+ }
+ }
+
+ void printMessage() {
+ if ( itMessage != messages.end() ) {
+ stream << " '" << itMessage->message << "'";
+ ++itMessage;
+ }
+ }
+
+ void printRemainingMessages( Colour::Code colour = dimColour() ) {
+ if ( itMessage == messages.end() )
+ return;
+
+ // using messages.end() directly yields compilation error:
+ std::vector<MessageInfo>::const_iterator itEnd = messages.end();
+ const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
+
+ {
+ Colour colourGuard( colour );
+ stream << " with " << pluralise( N, "message" ) << ":";
+ }
+
+ for(; itMessage != itEnd; ) {
+ // If this assertion is a warning ignore any INFO messages
+ if( printInfoMessages || itMessage->type != ResultWas::Info ) {
+ stream << " '" << itMessage->message << "'";
+ if ( ++itMessage != itEnd ) {
+ Colour colourGuard( dimColour() );
+ stream << " and";
+ }
+ }
+ }
+ }
+
+ private:
+ std::ostream& stream;
+ AssertionStats const& stats;
+ AssertionResult const& result;
+ std::vector<MessageInfo> messages;
+ std::vector<MessageInfo>::const_iterator itMessage;
+ bool printInfoMessages;
+ };
+
+ // Colour, message variants:
+ // - white: No tests ran.
+ // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
+ // - white: Passed [both/all] N test cases (no assertions).
+ // - red: Failed N tests cases, failed M assertions.
+ // - green: Passed [both/all] N tests cases with M assertions.
+
+ std::string bothOrAll( std::size_t count ) const {
+ return count == 1 ? "" : count == 2 ? "both " : "all " ;
+ }
+
+ void printTotals( const Totals& totals ) const {
+ if( totals.testCases.total() == 0 ) {
+ stream << "No tests ran.";
+ }
+ else if( totals.testCases.failed == totals.testCases.total() ) {
+ Colour colour( Colour::ResultError );
+ const std::string qualify_assertions_failed =
+ totals.assertions.failed == totals.assertions.total() ?
+ bothOrAll( totals.assertions.failed ) : "";
+ stream <<
+ "Failed " << bothOrAll( totals.testCases.failed )
+ << pluralise( totals.testCases.failed, "test case" ) << ", "
+ "failed " << qualify_assertions_failed <<
+ pluralise( totals.assertions.failed, "assertion" ) << ".";
+ }
+ else if( totals.assertions.total() == 0 ) {
+ stream <<
+ "Passed " << bothOrAll( totals.testCases.total() )
+ << pluralise( totals.testCases.total(), "test case" )
+ << " (no assertions).";
+ }
+ else if( totals.assertions.failed ) {
+ Colour colour( Colour::ResultError );
+ stream <<
+ "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
+ "failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
+ }
+ else {
+ Colour colour( Colour::ResultSuccess );
+ stream <<
+ "Passed " << bothOrAll( totals.testCases.passed )
+ << pluralise( totals.testCases.passed, "test case" ) <<
+ " with " << pluralise( totals.assertions.passed, "assertion" ) << ".";
+ }
+ }
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
+
+} // end namespace Catch
+
+namespace Catch {
+ // These are all here to avoid warnings about not having any out of line
+ // virtual methods
+ NonCopyable::~NonCopyable() {}
+ IShared::~IShared() {}
+ IStream::~IStream() CATCH_NOEXCEPT {}
+ FileStream::~FileStream() CATCH_NOEXCEPT {}
+ CoutStream::~CoutStream() CATCH_NOEXCEPT {}
+ DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
+ StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
+ IContext::~IContext() {}
+ IResultCapture::~IResultCapture() {}
+ ITestCase::~ITestCase() {}
+ ITestCaseRegistry::~ITestCaseRegistry() {}
+ IRegistryHub::~IRegistryHub() {}
+ IMutableRegistryHub::~IMutableRegistryHub() {}
+ IExceptionTranslator::~IExceptionTranslator() {}
+ IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
+ IReporter::~IReporter() {}
+ IReporterFactory::~IReporterFactory() {}
+ IReporterRegistry::~IReporterRegistry() {}
+ IStreamingReporter::~IStreamingReporter() {}
+ AssertionStats::~AssertionStats() {}
+ SectionStats::~SectionStats() {}
+ TestCaseStats::~TestCaseStats() {}
+ TestGroupStats::~TestGroupStats() {}
+ TestRunStats::~TestRunStats() {}
+ CumulativeReporterBase::SectionNode::~SectionNode() {}
+ CumulativeReporterBase::~CumulativeReporterBase() {}
+
+ StreamingReporterBase::~StreamingReporterBase() {}
+ ConsoleReporter::~ConsoleReporter() {}
+ CompactReporter::~CompactReporter() {}
+ IRunner::~IRunner() {}
+ IMutableContext::~IMutableContext() {}
+ IConfig::~IConfig() {}
+ XmlReporter::~XmlReporter() {}
+ JunitReporter::~JunitReporter() {}
+ TestRegistry::~TestRegistry() {}
+ FreeFunctionTestCase::~FreeFunctionTestCase() {}
+ IGeneratorInfo::~IGeneratorInfo() {}
+ IGeneratorsForTest::~IGeneratorsForTest() {}
+ WildcardPattern::~WildcardPattern() {}
+ TestSpec::Pattern::~Pattern() {}
+ TestSpec::NamePattern::~NamePattern() {}
+ TestSpec::TagPattern::~TagPattern() {}
+ TestSpec::ExcludedPattern::~ExcludedPattern() {}
+
+ Matchers::Impl::StdString::Equals::~Equals() {}
+ Matchers::Impl::StdString::Contains::~Contains() {}
+ Matchers::Impl::StdString::StartsWith::~StartsWith() {}
+ Matchers::Impl::StdString::EndsWith::~EndsWith() {}
+
+ void Config::dummy() {}
+
+ namespace TestCaseTracking {
+ ITracker::~ITracker() {}
+ TrackerBase::~TrackerBase() {}
+ SectionTracker::~SectionTracker() {}
+ IndexTracker::~IndexTracker() {}
+ }
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#endif
+
+#ifdef CATCH_CONFIG_MAIN
+// #included from: internal/catch_default_main.hpp
+#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
+
+#ifndef __OBJC__
+
+// Standard C/C++ main entry point
+int main (int argc, char * argv[]) {
+ return Catch::Session().run( argc, argv );
+}
+
+#else // __OBJC__
+
+// Objective-C entry point
+int main (int argc, char * const argv[]) {
+#if !CATCH_ARC_ENABLED
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+#endif
+
+ Catch::registerTestMethods();
+ int result = Catch::Session().run( argc, (char* const*)argv );
+
+#if !CATCH_ARC_ENABLED
+ [pool drain];
+#endif
+
+ return result;
+}
+
+#endif // __OBJC__
+
+#endif
+
+#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
+# undef CLARA_CONFIG_MAIN
+#endif
+
+//////
+
+// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
+#ifdef CATCH_CONFIG_PREFIX_ALL
+
+#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
+#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
+
+#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" )
+#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
+#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" )
+#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
+
+#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
+#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
+#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
+#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
+#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
+
+#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
+#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
+#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" )
+#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
+
+#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
+#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
+
+#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
+#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
+#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
+#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
+#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+ #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+ #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+ #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
+ #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+ #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
+ #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
+#else
+ #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
+ #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
+ #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
+ #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
+ #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
+ #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
+ #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
+#endif
+#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
+
+#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
+#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
+
+#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
+
+// "BDD-style" convenience wrappers
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+#else
+#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
+#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
+#endif
+#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" )
+#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" )
+#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
+#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" )
+#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
+
+// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
+#else
+
+#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
+#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
+
+#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" )
+#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
+#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" )
+#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
+
+#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
+#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
+#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
+#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
+#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
+
+#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" )
+#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
+#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" )
+#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
+
+#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
+#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
+
+#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
+#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
+#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
+#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
+#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+ #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+ #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+ #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
+ #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+ #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
+ #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
+#else
+ #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
+ #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
+ #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
+ #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )
+ #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
+ #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
+ #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
+#endif
+#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
+
+#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
+#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
+
+#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
+
+#endif
+
+#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
+
+// "BDD-style" convenience wrappers
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+#else
+#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
+#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
+#endif
+#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" )
+#define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" )
+#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
+#define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" )
+#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" )
+
+using Catch::Detail::Approx;
+
+#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/config-msvc.py b/graphics/asymptote/cudareflect/tinyexr/test/unit/config-msvc.py
new file mode 100644
index 0000000000..a7771defd1
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/config-msvc.py
@@ -0,0 +1,52 @@
+exe = "tester.exe"
+
+toolchain = "msvc"
+
+# optional
+link_pool_depth = 1
+
+# optional
+builddir = {
+ "gnu" : "build"
+ , "msvc" : "build"
+ , "clang" : "build"
+ }
+
+includes = {
+ "gnu" : [ "-I." ]
+ , "msvc" : [ "/I." ]
+ , "clang" : [ "-I." ]
+ }
+
+defines = {
+ "gnu" : [ "-DEXAMPLE=1" ]
+ , "msvc" : [ "/DEXAMPLE=1" ]
+ , "clang" : [ "-DEXAMPLE=1" ]
+ }
+
+cflags = {
+ "gnu" : [ "-O2", "-g" ]
+ , "msvc" : [ "/O2" ]
+ , "clang" : [ "-O2", "-g" ]
+ }
+
+cxxflags = {
+ "gnu" : [ "-O2", "-g" ]
+ , "msvc" : [ "/O2", "/W4", "/EHsc"]
+ , "clang" : [ "-O2", "-g", "-fsanitize=address" ]
+ }
+
+ldflags = {
+ "gnu" : [ ]
+ , "msvc" : [ ]
+ , "clang" : [ "-fsanitize=address" ]
+ }
+
+# optionsl
+cxx_files = [ "tester.cc" ]
+c_files = [ ]
+
+# You can register your own toolchain through register_toolchain function
+def register_toolchain(ninja):
+ pass
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/config-posix.py b/graphics/asymptote/cudareflect/tinyexr/test/unit/config-posix.py
new file mode 100644
index 0000000000..29cc4d5518
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/config-posix.py
@@ -0,0 +1,53 @@
+exe = "tester"
+
+# "gnu" or "clang"
+toolchain = "gnu"
+
+# optional
+link_pool_depth = 1
+
+# optional
+builddir = {
+ "gnu" : "build"
+ , "msvc" : "build"
+ , "clang" : "build"
+ }
+
+includes = {
+ "gnu" : [ "-I." ]
+ , "msvc" : [ "/I." ]
+ , "clang" : [ "-I." ]
+ }
+
+defines = {
+ "gnu" : [ ]
+ , "msvc" : [ ]
+ , "clang" : [ ]
+ }
+
+cflags = {
+ "gnu" : [ "-O2", "-g" ]
+ , "msvc" : [ "/O2" ]
+ , "clang" : [ "-O2", "-g" ]
+ }
+
+# Warn as much as possible: http://qiita.com/MitsutakaTakeda/items/6b9966f890cc9b944d75
+cxxflags = {
+ "gnu" : [ "-O2", "-g", "-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-declarations -Wmissing-include-dirs -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused", "-fsanitize=address" ]
+ , "msvc" : [ "/O2", "/W4" ]
+ , "clang" : [ "-O2", "-g", "-Werror -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic", "-fsanitize=address" ]
+ }
+
+ldflags = {
+ "gnu" : [ "-fsanitize=address" ]
+ , "msvc" : [ ]
+ , "clang" : [ "-fsanitize=address" ]
+ }
+
+cxx_files = [ "tester.cc" ]
+c_files = [ ]
+
+# You can register your own toolchain through register_toolchain function
+def register_toolchain(ninja):
+ pass
+
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/kuroga.py b/graphics/asymptote/cudareflect/tinyexr/test/unit/kuroga.py
new file mode 100755
index 0000000000..56d3f863dd
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/kuroga.py
@@ -0,0 +1,312 @@
+#!/usr/bin/env python
+
+#
+# Kuroga, single python file meta-build system for ninja
+# https://github.com/lighttransport/kuroga
+#
+# Requirements: python 2.6 or 2.7
+#
+# Usage: $ python kuroga.py input.py
+#
+
+import imp
+import re
+import textwrap
+import glob
+import os
+import sys
+
+# gcc preset
+def add_gnu_rule(ninja):
+ ninja.rule('gnucxx', description='CXX $out',
+ command='$gnucxx -MMD -MF $out.d $gnudefines $gnuincludes $gnucxxflags -c $in -o $out',
+ depfile='$out.d', deps='gcc')
+ ninja.rule('gnucc', description='CC $out',
+ command='$gnucc -MMD -MF $out.d $gnudefines $gnuincludes $gnucflags -c $in -o $out',
+ depfile='$out.d', deps='gcc')
+ ninja.rule('gnulink', description='LINK $out', pool='link_pool',
+ command='$gnuld -o $out $in $libs $gnuldflags')
+ ninja.rule('gnuar', description='AR $out', pool='link_pool',
+ command='$gnuar rsc $out $in')
+ ninja.rule('gnustamp', description='STAMP $out', command='touch $out')
+ ninja.newline()
+
+ ninja.variable('gnucxx', 'g++')
+ ninja.variable('gnucc', 'gcc')
+ ninja.variable('gnuld', '$gnucxx')
+ ninja.variable('gnuar', 'ar')
+ ninja.newline()
+
+# clang preset
+def add_clang_rule(ninja):
+ ninja.rule('clangcxx', description='CXX $out',
+ command='$clangcxx -MMD -MF $out.d $clangdefines $clangincludes $clangcxxflags -c $in -o $out',
+ depfile='$out.d', deps='gcc')
+ ninja.rule('clangcc', description='CC $out',
+ command='$clangcc -MMD -MF $out.d $clangdefines $clangincludes $clangcflags -c $in -o $out',
+ depfile='$out.d', deps='gcc')
+ ninja.rule('clanglink', description='LINK $out', pool='link_pool',
+ command='$clangld -o $out $in $libs $clangldflags')
+ ninja.rule('clangar', description='AR $out', pool='link_pool',
+ command='$clangar rsc $out $in')
+ ninja.rule('clangstamp', description='STAMP $out', command='touch $out')
+ ninja.newline()
+
+ ninja.variable('clangcxx', 'clang++')
+ ninja.variable('clangcc', 'clang')
+ ninja.variable('clangld', '$clangcxx')
+ ninja.variable('clangar', 'ar')
+ ninja.newline()
+
+# msvc preset
+def add_msvc_rule(ninja):
+ ninja.rule('msvccxx', description='CXX $out',
+ command='$msvccxx /TP /showIncludes $msvcdefines $msvcincludes $msvccxxflags -c $in /Fo$out',
+ depfile='$out.d', deps='msvc')
+ ninja.rule('msvccc', description='CC $out',
+ command='$msvccc /TC /showIncludes $msvcdefines $msvcincludes $msvccflags -c $in /Fo$out',
+ depfile='$out.d', deps='msvc')
+ ninja.rule('msvclink', description='LINK $out', pool='link_pool',
+ command='$msvcld $msvcldflags $in $libs /OUT:$out')
+ ninja.rule('msvcar', description='AR $out', pool='link_pool',
+ command='$msvcar $in /OUT:$out')
+ #ninja.rule('msvcstamp', description='STAMP $out', command='touch $out')
+ ninja.newline()
+
+ ninja.variable('msvccxx', 'cl.exe')
+ ninja.variable('msvccc', 'cl.exe')
+ ninja.variable('msvcld', 'link.exe')
+ ninja.variable('msvcar', 'lib.exe')
+ ninja.newline()
+
+# -- from ninja_syntax.py --
+def escape_path(word):
+ return word.replace('$ ', '$$ ').replace(' ', '$ ').replace(':', '$:')
+
+class Writer(object):
+ def __init__(self, output, width=78):
+ self.output = output
+ self.width = width
+
+ def newline(self):
+ self.output.write('\n')
+
+ def comment(self, text, has_path=False):
+ for line in textwrap.wrap(text, self.width - 2, break_long_words=False,
+ break_on_hyphens=False):
+ self.output.write('# ' + line + '\n')
+
+ def variable(self, key, value, indent=0):
+ if value is None:
+ return
+ if isinstance(value, list):
+ value = ' '.join(filter(None, value)) # Filter out empty strings.
+ self._line('%s = %s' % (key, value), indent)
+
+ def pool(self, name, depth):
+ self._line('pool %s' % name)
+ self.variable('depth', depth, indent=1)
+
+ def rule(self, name, command, description=None, depfile=None,
+ generator=False, pool=None, restat=False, rspfile=None,
+ rspfile_content=None, deps=None):
+ self._line('rule %s' % name)
+ self.variable('command', command, indent=1)
+ if description:
+ self.variable('description', description, indent=1)
+ if depfile:
+ self.variable('depfile', depfile, indent=1)
+ if generator:
+ self.variable('generator', '1', indent=1)
+ if pool:
+ self.variable('pool', pool, indent=1)
+ if restat:
+ self.variable('restat', '1', indent=1)
+ if rspfile:
+ self.variable('rspfile', rspfile, indent=1)
+ if rspfile_content:
+ self.variable('rspfile_content', rspfile_content, indent=1)
+ if deps:
+ self.variable('deps', deps, indent=1)
+
+ def build(self, outputs, rule, inputs=None, implicit=None, order_only=None,
+ variables=None):
+ outputs = as_list(outputs)
+ out_outputs = [escape_path(x) for x in outputs]
+ all_inputs = [escape_path(x) for x in as_list(inputs)]
+
+ if implicit:
+ implicit = [escape_path(x) for x in as_list(implicit)]
+ all_inputs.append('|')
+ all_inputs.extend(implicit)
+ if order_only:
+ order_only = [escape_path(x) for x in as_list(order_only)]
+ all_inputs.append('||')
+ all_inputs.extend(order_only)
+
+ self._line('build %s: %s' % (' '.join(out_outputs),
+ ' '.join([rule] + all_inputs)))
+
+ if variables:
+ if isinstance(variables, dict):
+ iterator = iter(variables.items())
+ else:
+ iterator = iter(variables)
+
+ for key, val in iterator:
+ self.variable(key, val, indent=1)
+
+ return outputs
+
+ def include(self, path):
+ self._line('include %s' % path)
+
+ def subninja(self, path):
+ self._line('subninja %s' % path)
+
+ def default(self, paths):
+ self._line('default %s' % ' '.join(as_list(paths)))
+
+ def _count_dollars_before_index(self, s, i):
+ """Returns the number of '$' characters right in front of s[i]."""
+ dollar_count = 0
+ dollar_index = i - 1
+ while dollar_index > 0 and s[dollar_index] == '$':
+ dollar_count += 1
+ dollar_index -= 1
+ return dollar_count
+
+ def _line(self, text, indent=0):
+ """Write 'text' word-wrapped at self.width characters."""
+ leading_space = ' ' * indent
+ while len(leading_space) + len(text) > self.width:
+ # The text is too wide; wrap if possible.
+
+ # Find the rightmost space that would obey our width constraint and
+ # that's not an escaped space.
+ available_space = self.width - len(leading_space) - len(' $')
+ space = available_space
+ while True:
+ space = text.rfind(' ', 0, space)
+ if (space < 0 or
+ self._count_dollars_before_index(text, space) % 2 == 0):
+ break
+
+ if space < 0:
+ # No such space; just use the first unescaped space we can find.
+ space = available_space - 1
+ while True:
+ space = text.find(' ', space + 1)
+ if (space < 0 or
+ self._count_dollars_before_index(text, space) % 2 == 0):
+ break
+ if space < 0:
+ # Give up on breaking.
+ break
+
+ self.output.write(leading_space + text[0:space] + ' $\n')
+ text = text[space+1:]
+
+ # Subsequent lines are continuations, so indent them.
+ leading_space = ' ' * (indent+2)
+
+ self.output.write(leading_space + text + '\n')
+
+ def close(self):
+ self.output.close()
+
+
+def as_list(input):
+ if input is None:
+ return []
+ if isinstance(input, list):
+ return input
+ return [input]
+
+# -- end from ninja_syntax.py --
+
+def gen(ninja, toolchain, config):
+
+ ninja.variable('ninja_required_version', '1.4')
+ ninja.newline()
+
+ if hasattr(config, "builddir"):
+ builddir = config.builddir[toolchain]
+ ninja.variable(toolchain + 'builddir', builddir)
+ else:
+ builddir = ''
+
+ ninja.variable(toolchain + 'defines', config.defines[toolchain] or [])
+ ninja.variable(toolchain + 'includes', config.includes[toolchain] or [])
+ ninja.variable(toolchain + 'cflags', config.cflags[toolchain] or [])
+ ninja.variable(toolchain + 'cxxflags', config.cxxflags[toolchain] or [])
+ ninja.variable(toolchain + 'ldflags', config.ldflags[toolchain] or [])
+ ninja.newline()
+
+ if hasattr(config, "link_pool_depth"):
+ ninja.pool('link_pool', depth=config.link_pool_depth)
+ else:
+ ninja.pool('link_pool', depth=4)
+ ninja.newline()
+
+ # Add default toolchain(gnu, clang and msvc)
+ add_gnu_rule(ninja)
+ add_clang_rule(ninja)
+ add_msvc_rule(ninja)
+
+ obj_files = []
+
+ cc = toolchain + 'cc'
+ cxx = toolchain + 'cxx'
+ link = toolchain + 'link'
+ ar = toolchain + 'ar'
+
+ if hasattr(config, "cxx_files"):
+ for src in config.cxx_files:
+ srcfile = src
+ obj = os.path.splitext(srcfile)[0] + '.o'
+ obj = os.path.join(builddir, obj);
+ obj_files.append(obj)
+ ninja.build(obj, cxx, srcfile)
+ ninja.newline()
+
+ if hasattr(config, "c_files"):
+ for src in config.c_files:
+ srcfile = src
+ obj = os.path.splitext(srcfile)[0] + '.o'
+ obj = os.path.join(builddir, obj);
+ obj_files.append(obj)
+ ninja.build(obj, cc, srcfile)
+ ninja.newline()
+
+ targetlist = []
+ if hasattr(config, "exe"):
+ ninja.build(config.exe, link, obj_files)
+ targetlist.append(config.exe)
+
+ if hasattr(config, "staticlib"):
+ ninja.build(config.staticlib, ar, obj_files)
+ targetlist.append(config.staticlib)
+
+ ninja.build('all', 'phony', targetlist)
+ ninja.newline()
+
+ ninja.default('all')
+
+def main():
+ if len(sys.argv) < 2:
+ print("Usage: python kuroga.py config.py")
+ sys.exit(1)
+
+ config = imp.load_source("config", sys.argv[1])
+
+ f = open('build.ninja', 'w')
+ ninja = Writer(f)
+
+ if hasattr(config, "register_toolchain"):
+ config.register_toolchain(ninja)
+
+ gen(ninja, config.toolchain, config)
+ f.close()
+
+main()
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/2by2.exr b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/2by2.exr
new file mode 100644
index 0000000000..5cc69a90c1
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/2by2.exr
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/flaga.exr b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/flaga.exr
new file mode 100644
index 0000000000..baafcbf976
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/flaga.exr
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/issue-160-piz-decode.exr b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/issue-160-piz-decode.exr
new file mode 100644
index 0000000000..0190859ebf
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/issue-160-piz-decode.exr
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/piz-bug-issue-100.exr b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/piz-bug-issue-100.exr
new file mode 100644
index 0000000000..6be0d2d8f2
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/piz-bug-issue-100.exr
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-1383755b301e5f505b2198dc0508918b537fdf48bbfc6deeffe268822e6f6cd6 b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-1383755b301e5f505b2198dc0508918b537fdf48bbfc6deeffe268822e6f6cd6
new file mode 100644
index 0000000000..53d737ff9a
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-1383755b301e5f505b2198dc0508918b537fdf48bbfc6deeffe268822e6f6cd6
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-24322747c47e87a10e4407528b779a1a763a48135384909b3d1010bbba1d4c28_min b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-24322747c47e87a10e4407528b779a1a763a48135384909b3d1010bbba1d4c28_min
new file mode 100644
index 0000000000..bdd036c97c
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-24322747c47e87a10e4407528b779a1a763a48135384909b3d1010bbba1d4c28_min
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-255456016cca60ddb5c5ed6898182e13739bf687b17d1411e97bb60ad95e7a84_min b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-255456016cca60ddb5c5ed6898182e13739bf687b17d1411e97bb60ad95e7a84_min
new file mode 100644
index 0000000000..81a2321162
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-255456016cca60ddb5c5ed6898182e13739bf687b17d1411e97bb60ad95e7a84_min
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-360c3b0555cb979ca108f2d178cf8a80959cfeabaa4ec1d310d062fa653a8c6b_min b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-360c3b0555cb979ca108f2d178cf8a80959cfeabaa4ec1d310d062fa653a8c6b_min
new file mode 100644
index 0000000000..b2543d3109
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-360c3b0555cb979ca108f2d178cf8a80959cfeabaa4ec1d310d062fa653a8c6b_min
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-3f1f642c3356fd8e8d2a0787613ec09a56572b3a1e38c9629b6db9e8dead1117_min b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-3f1f642c3356fd8e8d2a0787613ec09a56572b3a1e38c9629b6db9e8dead1117_min
new file mode 100644
index 0000000000..5f844b157b
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-3f1f642c3356fd8e8d2a0787613ec09a56572b3a1e38c9629b6db9e8dead1117_min
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-5ace655ef080932dcc7e4abc9eab1d4f82c845453464993dfa3eb6c5822a1621 b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-5ace655ef080932dcc7e4abc9eab1d4f82c845453464993dfa3eb6c5822a1621
new file mode 100644
index 0000000000..ddafb67aad
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-5ace655ef080932dcc7e4abc9eab1d4f82c845453464993dfa3eb6c5822a1621
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-5b66774a7498c635334ad386be0c3b359951738ac47f14878a3346d1c6ea0fe5_min b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-5b66774a7498c635334ad386be0c3b359951738ac47f14878a3346d1c6ea0fe5_min
new file mode 100644
index 0000000000..eb74f48f44
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-5b66774a7498c635334ad386be0c3b359951738ac47f14878a3346d1c6ea0fe5_min
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-d5c9c893e559277a3320c196523095b94db93985620ac338d037487e0e613047_min b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-d5c9c893e559277a3320c196523095b94db93985620ac338d037487e0e613047_min
new file mode 100644
index 0000000000..d01d059e99
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-d5c9c893e559277a3320c196523095b94db93985620ac338d037487e0e613047_min
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-df76d1f27adb8927a1446a603028272140905c168a336128465a1162ec7af270.mini b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-df76d1f27adb8927a1446a603028272140905c168a336128465a1162ec7af270.mini
new file mode 100644
index 0000000000..d07b822737
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-df76d1f27adb8927a1446a603028272140905c168a336128465a1162ec7af270.mini
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-e7fa6404daa861369d2172fe68e08f9d38c0989f57da7bcfb510bab67e19ca9f b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-e7fa6404daa861369d2172fe68e08f9d38c0989f57da7bcfb510bab67e19ca9f
new file mode 100644
index 0000000000..fef3948e19
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-e7fa6404daa861369d2172fe68e08f9d38c0989f57da7bcfb510bab67e19ca9f
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-eedff3a9e99eb1c0fd3a3b0989e7c44c0a69f04f10b23e5264f362a4773f4397_min b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-eedff3a9e99eb1c0fd3a3b0989e7c44c0a69f04f10b23e5264f362a4773f4397_min
new file mode 100644
index 0000000000..a5168f80dc
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-eedff3a9e99eb1c0fd3a3b0989e7c44c0a69f04f10b23e5264f362a4773f4397_min
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-efe9007bfdcbbe8a1569bf01fa9acadb8261ead49cb83f6e91fcdc4dae2e99a3_min b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-efe9007bfdcbbe8a1569bf01fa9acadb8261ead49cb83f6e91fcdc4dae2e99a3_min
new file mode 100644
index 0000000000..58184850d2
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/poc-efe9007bfdcbbe8a1569bf01fa9acadb8261ead49cb83f6e91fcdc4dae2e99a3_min
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/tiled_half_1x1_alpha.exr b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/tiled_half_1x1_alpha.exr
new file mode 100644
index 0000000000..1933c14e8a
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/regression/tiled_half_1x1_alpha.exr
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/tester.cc b/graphics/asymptote/cudareflect/tinyexr/test/unit/tester.cc
new file mode 100644
index 0000000000..5fc722dd20
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/tester.cc
@@ -0,0 +1,1714 @@
+// Assume this file is encoded in UTF-8
+#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do
+ // this in one cpp file
+
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
+#include "catch.hpp"
+
+#ifdef _WIN32
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+#include <windows.h>
+#endif
+
+#define TINYEXR_IMPLEMENTATION
+#include "../../tinyexr.h"
+
+// uncomment it to write out memory-saved images to files
+//#define DUMP_IMAGES
+
+// path to https://github.com/openexr/openexr-images
+// TODO(syoyo): Read openexr-images path from command argument.
+const char* kOpenEXRImagePath = "../../../openexr-images/";
+
+std::string GetPath(const char* basename) {
+ std::string s;
+ s = std::string(kOpenEXRImagePath) + std::string(basename);
+ return s;
+}
+
+// simply dumping to build folder
+std::string GetDumpPath(const char* basename) {
+ std::string s = basename;
+ size_t index = s.find_last_of("/\\");
+
+ if (index != std::string::npos && index + 1 < s.size()) {
+ s = s.substr(index + 1);
+ }
+ //return "dump/" + s;
+ return s;
+}
+
+// https://stackoverflow.com/questions/148403/utf8-to-from-wide-char-conversion-in-stl/148665#148665
+std::wstring UTF8_to_wchar(const char* in) {
+ std::wstring out;
+ unsigned int codepoint;
+ while (*in != 0) {
+ unsigned char ch = static_cast<unsigned char>(*in);
+ if (ch <= 0x7f)
+ codepoint = ch;
+ else if (ch <= 0xbf)
+ codepoint = (codepoint << 6) | (ch & 0x3f);
+ else if (ch <= 0xdf)
+ codepoint = ch & 0x1f;
+ else if (ch <= 0xef)
+ codepoint = ch & 0x0f;
+ else
+ codepoint = ch & 0x07;
+ ++in;
+ if (((*in & 0xc0) != 0x80) && (codepoint <= 0x10ffff)) {
+ if (sizeof(wchar_t) > 2)
+ out.append(1, static_cast<wchar_t>(codepoint));
+ else if (codepoint > 0xffff) {
+ out.append(1, static_cast<wchar_t>(0xd800 + (codepoint >> 10)));
+ out.append(1, static_cast<wchar_t>(0xdc00 + (codepoint & 0x03ff)));
+ } else if (codepoint < 0xd800 || codepoint >= 0xe000)
+ out.append(1, static_cast<wchar_t>(codepoint));
+ }
+ }
+ return out;
+}
+
+#ifdef DUMP_IMAGES
+// return true if success
+static bool WriteMemoryToFile(const char *filename, const unsigned char* memory, size_t size)
+{
+ std::cout << "Saving:" << std::string(filename) << std::endl;
+ FILE *fp = NULL;
+#ifdef _WIN32
+#if defined(_MSC_VER) || defined(__MINGW32__) // MSVC, MinGW gcc or clang
+ errno_t errcode =
+ _wfopen_s(&fp, UTF8_to_wchar(filename).c_str(), L"wb");
+ if (errcode != 0) return false;
+#else
+ // Unknown compiler
+ fp = fopen(filename, "wb");
+#endif
+#else
+ fp = fopen(filename, "wb");
+#endif
+ if (!fp) return false;
+
+ size_t written_size = 0;
+ if (size && memory) {
+ written_size = fwrite(memory, 1, size, fp);
+ }
+
+ fclose(fp);
+
+ return written_size == size;
+}
+#endif
+
+// some helper funcs
+static bool operator == (const EXRBox2i& a, const EXRBox2i& b)
+{
+ return a.min_x == b.min_x && a.min_y == b.min_y &&
+ a.max_x == b.max_x && a.max_y == b.max_y;
+}
+
+static int GetWidth(const EXRBox2i& box)
+{
+ return box.max_x - box.min_x + 1;
+}
+
+static int GetHeight(const EXRBox2i& box)
+{
+ return box.max_y - box.min_y + 1;
+}
+
+static void CompareHeaders(const EXRHeader& header1, const EXRHeader& header2)
+{
+#if 0
+ printf("header1.dataWindow = %d, %d, %d, %d\n", header1.data_window.min_x,
+ header1.data_window.min_y, header1.data_window.max_x, header1.data_window.max_y);
+ printf("header2.dataWindow = %d, %d, %d, %d\n", header2.data_window.min_x,
+ header2.data_window.min_y, header2.data_window.max_x, header2.data_window.max_y);
+#endif
+ REQUIRE(header1.compression_type == header2.compression_type);
+ REQUIRE(header1.num_channels == header2.num_channels);
+ REQUIRE(GetWidth(header1.data_window) == GetWidth(header2.data_window));
+ REQUIRE(GetHeight(header1.data_window) == GetHeight(header2.data_window));
+ //REQUIRE(header1.display_window == header2.display_window);
+ //REQUIRE(header1.screen_window_width == header2.screen_window_width);
+ //REQUIRE(header1.pixel_aspect_ratio == header2.pixel_aspect_ratio);
+ REQUIRE(header1.tiled == header2.tiled);
+ REQUIRE(header1.tile_size_x == header2.tile_size_x);
+ REQUIRE(header1.tile_size_y == header2.tile_size_y);
+ REQUIRE(header1.tile_level_mode == header2.tile_level_mode);
+ REQUIRE(header1.tile_rounding_mode == header2.tile_rounding_mode);
+
+ REQUIRE(header1.non_image == header2.non_image);
+
+ REQUIRE(0 == strcmp(header1.name, header2.name));
+
+ for (int c = 0; c < header1.num_channels; c++)
+ {
+ REQUIRE(header1.pixel_types[c] == header2.pixel_types[c]); // assume no conversion
+ REQUIRE(0 == strcmp(header1.channels[c].name, header2.channels[c].name));
+ REQUIRE(header1.channels[c].pixel_type == header2.pixel_types[c]);
+ //REQUIRE(header1.channels[c].p_linear == header2.channels[c].p_linear);
+ //REQUIRE(header1.channels[c].x_sampling == header2.channels[c].x_sampling);
+ //REQUIRE(header1.channels[c].y_sampling == header2.channels[c].y_sampling);
+ }
+}
+
+static void CompareImages(const EXRImage& image1, const EXRImage& image2)
+{
+ bool tiles_ok = image1.tiles && image2.tiles || image1.tiles == NULL && image2.tiles == NULL;
+ REQUIRE(true == tiles_ok);
+ bool images_ok = image1.images && image2.images || image1.images == NULL && image2.images == NULL;
+ REQUIRE(true == images_ok);
+ REQUIRE(image1.num_channels == image2.num_channels);
+
+ const EXRImage* level_image1 = &image1;
+ const EXRImage* level_image2 = &image2;
+ while(level_image1 && level_image2)
+ {
+ REQUIRE(level_image1->level_x == level_image2->level_x);
+ REQUIRE(level_image1->level_y == level_image2->level_y);
+ REQUIRE(level_image1->width == level_image2->width);
+ REQUIRE(level_image1->height == level_image2->height);
+ REQUIRE(level_image1->num_tiles == level_image2->num_tiles);
+ level_image1 = level_image1->next_level;
+ level_image2 = level_image2->next_level;
+ bool levels_ok = level_image1 && level_image2 || level_image1 == NULL && level_image2 == NULL;
+ REQUIRE(true == levels_ok);
+ }
+}
+
+TEST_CASE("asakusa", "[Load]") {
+ EXRVersion exr_version;
+ EXRImage exr_image;
+ InitEXRImage(&exr_image);
+ EXRHeader exr_header;
+ InitEXRHeader(&exr_header);
+ const char* err = NULL;
+ int ret = ParseEXRVersionFromFile(&exr_version, "../../asakusa.exr");
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ ret = ParseEXRHeaderFromFile(&exr_header, &exr_version, "../../asakusa.exr",
+ &err);
+ REQUIRE(NULL == err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ FreeEXRImage(&exr_image);
+ FreeEXRHeader(&exr_header);
+}
+
+TEST_CASE("utf8filename", "[Load]") {
+ EXRVersion exr_version;
+
+ EXRHeader exr_header;
+ InitEXRHeader(&exr_header);
+ const char* err = NULL;
+
+#ifdef _WIN32
+
+#if defined(_MSC_VER)
+ // Include UTF-16LE encoded string
+ const wchar_t* wfilename =
+#include "win32-filelist-utf16le.inc"
+ ;
+
+ // convert to char*
+ // https://stackoverflow.com/questions/12637779/how-to-convert-const-wchar-to-const-char/12637971
+
+ FILE* fp;
+ errno_t errcode = _wfopen_s(&fp, wfilename, L"rb");
+
+ REQUIRE(0 == errcode);
+
+ char filename[1024];
+ int charlen = 1000;
+
+ int strlen = WideCharToMultiByte(65001 /* UTF8 */, 0, wfilename, -1, filename,
+ (int)charlen, NULL, NULL);
+
+ REQUIRE(strlen == 27);
+#else
+ // MinGW or clang.
+ // At least clang cannot feed UTF-16LE source code, so provide UTF-8 encoded
+ // file path
+ const char* utf8filename =
+#include "win32-filelist-utf8.inc"
+ ;
+
+ // to wchar_t
+ const std::wstring wfilename = UTF8_to_wchar(utf8filename);
+
+ FILE* fp;
+ errno_t errcode = _wfopen_s(&fp, wfilename.c_str(), L"rb");
+
+ REQUIRE(0 == errcode);
+
+ char filename[1024];
+ int charlen = 1000;
+
+ // wchar_t to multibyte char
+ int strlen = WideCharToMultiByte(65001 /* UTF8 */, 0, wfilename.c_str(), -1,
+ filename, (int)charlen, NULL, NULL);
+
+ REQUIRE(strlen == 27);
+
+#endif
+
+#else
+ // Assume this source code is compiled with UTF-8(UNICODE)
+ const char* filename = "./regression/日本語.exr";
+#endif
+
+ int ret = ParseEXRVersionFromFile(&exr_version, filename);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ ret = ParseEXRHeaderFromFile(&exr_header, &exr_version, filename, &err);
+ REQUIRE(NULL == err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ FreeEXRHeader(&exr_header);
+}
+
+TEST_CASE("ScanLines", "[Load]") {
+ std::vector<std::string> inputs;
+ inputs.push_back("ScanLines/Blobbies.exr");
+ inputs.push_back("ScanLines/CandleGlass.exr");
+ // inputs.push_back("ScanLines/Cannon.exr"); // Cannon.exr will fail since it
+ // uses b44 compression which is not yet supported on TinyEXR.
+ inputs.push_back("ScanLines/Desk.exr");
+ inputs.push_back("ScanLines/MtTamWest.exr");
+ inputs.push_back("ScanLines/PrismsLenses.exr");
+ inputs.push_back("ScanLines/StillLife.exr");
+ inputs.push_back("ScanLines/Tree.exr");
+
+ for (size_t i = 0; i < inputs.size(); i++) {
+ EXRVersion exr_version;
+ std::string filepath = GetPath(inputs[i].c_str());
+ std::cout << "Loading" << filepath << std::endl;
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(false == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ ret = LoadEXRImageFromFile(&image, &header, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ FreeEXRHeader(&header);
+ FreeEXRImage(&image);
+ }
+}
+
+TEST_CASE("Chromaticities", "[Load]") {
+ std::vector<std::string> inputs;
+ inputs.push_back("Chromaticities/Rec709.exr");
+ inputs.push_back("Chromaticities/Rec709_YC.exr");
+ inputs.push_back("Chromaticities/XYZ.exr");
+ inputs.push_back("Chromaticities/XYZ_YC.exr");
+
+ for (size_t i = 0; i < inputs.size(); i++) {
+ EXRVersion exr_version;
+ std::string filepath = GetPath(inputs[i].c_str());
+ std::cout << "Loading" << filepath << std::endl;
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(false == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ ret = LoadEXRImageFromFile(&image, &header, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ FreeEXRHeader(&header);
+ FreeEXRImage(&image);
+ }
+}
+
+TEST_CASE("TestImages", "[Load]") {
+ std::vector<std::string> inputs;
+ inputs.push_back("TestImages/AllHalfValues.exr");
+ inputs.push_back("TestImages/BrightRings.exr");
+ inputs.push_back("TestImages/BrightRingsNanInf.exr");
+ // inputs.push_back("TestImages/GammaChart.exr"); // disable since this uses
+ // pxr24 compression
+ // inputs.push_back("TestImages/GrayRampsDiagonal.exr"); // pxr24
+ // inputs.push_back("TestImages/GrayRampsHorizontal.exr"); // pxr24
+ // inputs.push_back("TestImages/RgbRampsDiagonal.exr"); // pxr24
+ // inputs.push_back("TestImages/SquaresSwirls.exr"); // pxr24
+ inputs.push_back("TestImages/WideColorGamut.exr");
+ // inputs.push_back("TestImages/WideFloatRange.exr"); // pxr24
+
+ for (size_t i = 0; i < inputs.size(); i++) {
+ EXRVersion exr_version;
+ std::string filepath = GetPath(inputs[i].c_str());
+ std::cout << "Loading" << filepath << std::endl;
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(false == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ ret = LoadEXRImageFromFile(&image, &header, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ FreeEXRHeader(&header);
+ FreeEXRImage(&image);
+ }
+}
+
+TEST_CASE("LuminanceChroma", "[Load]") {
+ std::vector<std::string> inputs;
+ // inputs.push_back("LuminanceChroma/CrissyField.exr"); // b44
+ // inputs.push_back("LuminanceChroma/Flowers.exr"); // b44
+ // inputs.push_back("LuminanceChroma/Garden.exr"); // tiled
+ inputs.push_back("LuminanceChroma/MtTamNorth.exr");
+ inputs.push_back("LuminanceChroma/StarField.exr");
+
+ for (size_t i = 0; i < inputs.size(); i++) {
+ EXRVersion exr_version;
+ std::string filepath = GetPath(inputs[i].c_str());
+ std::cout << "Loading" << filepath << std::endl;
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(false == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ ret = LoadEXRImageFromFile(&image, &header, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ FreeEXRHeader(&header);
+ FreeEXRImage(&image);
+ }
+}
+
+TEST_CASE("DisplayWindow", "[Load]") {
+ std::vector<std::string> inputs;
+ inputs.push_back("DisplayWindow/t01.exr");
+ inputs.push_back("DisplayWindow/t02.exr");
+ inputs.push_back("DisplayWindow/t03.exr");
+ inputs.push_back("DisplayWindow/t04.exr");
+ inputs.push_back("DisplayWindow/t05.exr");
+ inputs.push_back("DisplayWindow/t06.exr");
+ inputs.push_back("DisplayWindow/t07.exr");
+ inputs.push_back("DisplayWindow/t08.exr");
+ inputs.push_back("DisplayWindow/t09.exr");
+ inputs.push_back("DisplayWindow/t10.exr");
+ inputs.push_back("DisplayWindow/t11.exr");
+ inputs.push_back("DisplayWindow/t12.exr");
+ inputs.push_back("DisplayWindow/t13.exr");
+ inputs.push_back("DisplayWindow/t14.exr");
+ inputs.push_back("DisplayWindow/t15.exr");
+ inputs.push_back("DisplayWindow/t16.exr");
+
+ for (size_t i = 0; i < inputs.size(); i++) {
+ EXRVersion exr_version;
+ std::string filepath = GetPath(inputs[i].c_str());
+ std::cout << "Loading" << filepath << std::endl;
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(false == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ ret = LoadEXRImageFromFile(&image, &header, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ FreeEXRHeader(&header);
+ FreeEXRImage(&image);
+ }
+}
+
+TEST_CASE("Tiles/GoldenGate.exr", "[Version]") {
+ EXRVersion exr_version;
+ std::string filepath = GetPath("Tiles/GoldenGate.exr");
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(true == exr_version.tiled);
+}
+
+TEST_CASE("Tiles/GoldenGate.exr|Load", "[Load]") {
+ EXRVersion exr_version;
+ std::string filepath = GetPath("Tiles/GoldenGate.exr");
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(true == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(1 == header.tiled);
+ REQUIRE(TINYEXR_TILE_ONE_LEVEL == header.tile_level_mode);
+ REQUIRE(128 == header.tile_size_x);
+ REQUIRE(128 == header.tile_size_y);
+
+ ret = LoadEXRImageFromFile(&image, &header, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(NULL != image.tiles);
+ REQUIRE(0 == image.level_x);
+ REQUIRE(0 == image.level_y);
+ REQUIRE(1 == EXRNumLevels(&image));
+
+ FreeEXRHeader(&header);
+ FreeEXRImage(&image);
+}
+
+TEST_CASE("LuminanceChroma/Garden.exr|Load", "[Load]") {
+ EXRVersion exr_version;
+ std::string filepath = GetPath("LuminanceChroma/Garden.exr");
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(true == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ ret = LoadEXRImageFromFile(&image, &header, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ FreeEXRHeader(&header);
+ FreeEXRImage(&image);
+}
+
+TEST_CASE("Tiles/Ocean.exr", "[Load]") {
+ EXRVersion exr_version;
+ std::string filepath = GetPath("Tiles/Ocean.exr");
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(true == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ ret = LoadEXRImageFromFile(&image, &header, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ FreeEXRHeader(&header);
+ FreeEXRImage(&image);
+}
+
+TEST_CASE("MultiResolution/Bonita.exr", "[Load]") {
+ EXRVersion exr_version;
+ std::string filepath = GetPath("MultiResolution/Bonita.exr");
+ std::cout << "Loading" << filepath << std::endl;
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(true == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(1 == header.tiled);
+ REQUIRE(TINYEXR_TILE_MIPMAP_LEVELS == header.tile_level_mode);
+ REQUIRE(TINYEXR_TILE_ROUND_DOWN == header.tile_rounding_mode);
+
+ ret = LoadEXRImageFromFile(&image, &header, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(10 == EXRNumLevels(&image));
+
+ FreeEXRHeader(&header);
+ FreeEXRImage(&image);
+}
+
+TEST_CASE("MultiResolution/Kapaa.exr", "[Load]") {
+ EXRVersion exr_version;
+ std::string filepath = GetPath("MultiResolution/Kapaa.exr");
+ std::cout << "Loading" << filepath << std::endl;
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(true == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(1 == header.tiled);
+ REQUIRE(TINYEXR_TILE_RIPMAP_LEVELS == header.tile_level_mode);
+ REQUIRE(TINYEXR_TILE_ROUND_UP == header.tile_rounding_mode);
+ REQUIRE(64 == header.tile_size_x);
+ REQUIRE(64 == header.tile_size_y);
+
+ ret = LoadEXRImageFromFile(&image, &header, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(11*11 == EXRNumLevels(&image));
+
+ FreeEXRHeader(&header);
+ FreeEXRImage(&image);
+}
+
+TEST_CASE("Saving ScanLines", "[Save]") {
+ std::vector<std::string> inputs;
+ inputs.push_back("ScanLines/Blobbies.exr");
+ inputs.push_back("ScanLines/CandleGlass.exr");
+ // inputs.push_back("ScanLines/Cannon.exr"); // Cannon.exr will fail since it
+ // uses b44 compression which is not yet supported on TinyEXR.
+ inputs.push_back("ScanLines/Desk.exr");
+ inputs.push_back("ScanLines/MtTamWest.exr");
+ inputs.push_back("ScanLines/PrismsLenses.exr");
+ inputs.push_back("ScanLines/StillLife.exr");
+ inputs.push_back("ScanLines/Tree.exr");
+
+ for (size_t i = 0; i < inputs.size(); i++) {
+ std::string filepath = GetPath(inputs[i].c_str());
+ std::cout << "Input:" << filepath << std::endl;
+
+ EXRVersion version1;
+ int ret = ParseEXRVersionFromFile(&version1, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ EXRHeader header1;
+ EXRImage image1;
+ unsigned char *data = NULL;
+ size_t data_size;
+ // loading from file
+ {
+ InitEXRHeader(&header1);
+ InitEXRImage(&image1);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header1, &version1, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ ret = LoadEXRImageFromFile(&image1, &header1, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ }
+ // saving to memory
+ {
+ const char* err = NULL;
+ data_size = SaveEXRImageToMemory(&image1, &header1, &data, &err);
+ REQUIRE(0 != data_size);
+ //FreeEXRHeader(&header);
+#ifdef DUMP_IMAGES
+ bool ret = WriteMemoryToFile(GetDumpPath(inputs[i].c_str()).c_str(), data, data_size);
+ REQUIRE(true == ret);
+#endif
+ }
+ // loading back from memory
+ {
+ EXRVersion version2;
+ {
+ int ret = ParseEXRVersionFromMemory(&version2, data, data_size);
+ REQUIRE(0 == ret);
+ }
+ EXRHeader header2;
+ {
+ const char* err = NULL;
+ InitEXRHeader(&header2);
+ int ret = ParseEXRHeaderFromMemory(&header2, &version2, data, data_size, &err);
+ REQUIRE(0 == ret);
+ }
+ EXRImage image2;
+ {
+ const char* err = NULL;
+ InitEXRImage(&image2);
+ int ret = LoadEXRImageFromMemory(&image2, &header2, data, data_size, &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ free(data);
+ }
+
+ CompareHeaders(header1, header2);
+ CompareImages(image1, image2);
+
+ FreeEXRImage(&image2);
+ FreeEXRHeader(&header2);
+ }
+
+ FreeEXRHeader(&header1);
+ FreeEXRImage(&image1);
+ }
+}
+
+TEST_CASE("Saving MultiResolution", "[Save]") {
+ //std::string filepath = GetPath("MultiResolution/Bonita.exr");
+ //std::cout << "Load-save-reload:" << filepath << std::endl;
+
+ std::vector<std::string> inputs;
+ inputs.push_back("MultiResolution/Bonita.exr");
+ inputs.push_back("MultiResolution/Kapaa.exr");
+
+ for (size_t i = 0; i < inputs.size(); i++) {
+ std::string filepath = GetPath(inputs[i].c_str());
+ std::cout << "Input:" << filepath << std::endl;
+
+ EXRVersion version1;
+ int ret = ParseEXRVersionFromFile(&version1, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ EXRHeader header1;
+ EXRImage image1;
+ unsigned char *data = NULL;
+ size_t data_size;
+ // loading from file
+ {
+ InitEXRHeader(&header1);
+ InitEXRImage(&image1);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header1, &version1, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ ret = LoadEXRImageFromFile(&image1, &header1, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ }
+ // saving to memory
+ {
+ const char* err = NULL;
+ data_size = SaveEXRImageToMemory(&image1, &header1, &data, &err);
+ REQUIRE(0 != data_size);
+#ifdef DUMP_IMAGES
+ bool ret = WriteMemoryToFile(GetDumpPath(inputs[i].c_str()).c_str(), data, data_size);
+ REQUIRE(true == ret);
+#endif
+ }
+ // loading back from memory
+ {
+ EXRVersion version2;
+ {
+ int ret = ParseEXRVersionFromMemory(&version2, data, data_size);
+ REQUIRE(0 == ret);
+ }
+ EXRHeader header2;
+ {
+ const char* err = NULL;
+ InitEXRHeader(&header2);
+ int ret = ParseEXRHeaderFromMemory(&header2, &version2, data, data_size, &err);
+ REQUIRE(0 == ret);
+ }
+ EXRImage image2;
+ {
+ const char* err = NULL;
+ InitEXRImage(&image2);
+ int ret = LoadEXRImageFromMemory(&image2, &header2, data, data_size, &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ free(data);
+ }
+
+ CompareHeaders(header1, header2);
+ CompareImages(image1, image2);
+
+ FreeEXRImage(&image2);
+ FreeEXRHeader(&header2);
+ }
+ FreeEXRHeader(&header1);
+ FreeEXRImage(&image1);
+ }
+}
+
+TEST_CASE("Saving multipart", "[Save]") {
+
+ std::vector<std::string> inputs;
+ inputs.push_back("Beachball/multipart.0001.exr");
+
+ for (size_t i = 0; i < inputs.size(); i++) {
+ std::string filepath = GetPath(inputs[i].c_str());
+ std::cout << "Input:" << filepath << std::endl;
+
+ EXRVersion version1;
+ {
+ int ret = ParseEXRVersionFromFile(&version1, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(true == version1.multipart);
+ }
+
+ EXRHeader** headers1; // list of EXRHeader pointers.
+ int num_headers1;
+ {
+ const char* err = NULL;
+ int ret = ParseEXRMultipartHeaderFromFile(&headers1, &num_headers1,
+ &version1, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ }
+
+ unsigned char *data = NULL;
+ size_t data_size;
+
+ std::vector<EXRImage> images1(num_headers1);
+ // loading from file
+ {
+ const char* err = NULL;
+ for (int j = 0; j < num_headers1; j++) {
+ InitEXRImage(&images1[j]);
+ }
+ int ret = LoadEXRMultipartImageFromFile(&images1[0], const_cast<const EXRHeader**>(headers1),
+ static_cast<unsigned int>(num_headers1), filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ }
+ // saving to memory
+ {
+ const char* err = NULL;
+ data_size = SaveEXRMultipartImageToMemory(&images1[0],
+ const_cast<const EXRHeader**>(headers1), static_cast<unsigned int>(num_headers1), &data, &err);
+ REQUIRE(0 != data_size);
+ #ifdef DUMP_IMAGES
+ bool ret = WriteMemoryToFile(GetDumpPath(inputs[i].c_str()).c_str(), data, data_size);
+ REQUIRE(true == ret);
+ #endif
+ }
+ // loading back from memory
+ {
+ EXRVersion version2;
+ {
+ int ret = ParseEXRVersionFromMemory(&version2, data, data_size);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(true == version2.multipart);
+ }
+ EXRHeader** headers2;
+ int num_headers2;
+ {
+ const char* err = NULL;
+ int ret = ParseEXRMultipartHeaderFromMemory(&headers2, &num_headers2, &version2,
+ data, data_size, &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ }
+ REQUIRE(num_headers1 == num_headers2);
+
+ std::vector<EXRImage> images2(num_headers2);
+ {
+ for (int j = 0; j < num_headers2; j++) {
+ InitEXRImage(&images2[j]);
+ }
+ const char* err = NULL;
+ int ret = LoadEXRMultipartImageFromMemory(&images2[0], const_cast<const EXRHeader**>(headers2),
+ static_cast<unsigned int>(num_headers2),
+ data, data_size, &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ free(data);
+ }
+
+ for (int j = 0; j < num_headers2; j++) {
+ CompareHeaders(*headers1[j], *headers2[j]);
+ }
+ for (int j = 0; j < num_headers2; j++) {
+ CompareImages(images1[j], images2[j]);
+ }
+
+ for (int j = 0; j < num_headers2; j++) {
+ FreeEXRImage(&images2[j]);
+ FreeEXRHeader(headers2[j]);
+ free(headers2[j]);
+ }
+ free(headers2);
+ }
+
+ for (int j = 0; j < num_headers1; j++) {
+ FreeEXRImage(&images1[j]);
+ FreeEXRHeader(headers1[j]);
+ free(headers1[j]);
+ }
+ free(headers1);
+ }
+}
+
+TEST_CASE("Saving multipart|Combine", "[Save]") {
+
+ std::vector<std::string> inputs;
+ inputs.push_back("MultiResolution/Kapaa.exr"); // tiled, ripmap
+ inputs.push_back("Tiles/GoldenGate.exr"); // tiled, one level
+ inputs.push_back("ScanLines/Desk.exr"); // scanline
+ inputs.push_back("MultiResolution/PeriodicPattern.exr"); // tiled, mipmap
+
+ const char* dstName = "multipart.collection.exr";
+
+ unsigned num_headers1 = inputs.size();
+ std::vector<EXRHeader> headers1(num_headers1);
+ std::vector<EXRImage> images1(num_headers1);
+ // collecting images
+ for (size_t i = 0; i < num_headers1; i++) {
+ std::string filepath = GetPath(inputs[i].c_str());
+ std::cout << "Input:" << filepath << std::endl;
+
+ EXRVersion version1;
+ {
+ int ret = ParseEXRVersionFromFile(&version1, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(false == version1.multipart);
+ }
+ {
+ InitEXRHeader(&headers1[i]);
+ const char* err = NULL;
+ int ret = ParseEXRHeaderFromFile(&headers1[i], &version1, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ }
+ {
+ InitEXRImage(&images1[i]);
+ const char* err = NULL;
+ int ret = LoadEXRImageFromFile(&images1[i], &headers1[i], filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ }
+ }
+
+ unsigned char *data = NULL;
+ size_t data_size;
+ // saving collection to memory as multipart
+ {
+ std::vector<EXRHeader*> pheaders1(num_headers1);
+ for(unsigned i = 0; i < num_headers1; ++i) pheaders1[i] = &headers1[i];
+ for (size_t i = 0; i < num_headers1; i++) {
+ EXRSetNameAttr(pheaders1[i], inputs[i].c_str());
+ }
+ const char* err = NULL;
+ data_size = SaveEXRMultipartImageToMemory(&images1[0],
+ const_cast<const EXRHeader**>(&pheaders1[0]),
+ static_cast<unsigned int>(num_headers1),
+ &data, &err);
+ REQUIRE(0 != data_size);
+#ifdef DUMP_IMAGES
+ bool ret = WriteMemoryToFile(GetDumpPath(dstName).c_str(), data, data_size);
+ REQUIRE(true == ret);
+#endif
+ }
+ // loading back from memory
+ {
+ EXRVersion version2;
+ {
+ int ret = ParseEXRVersionFromMemory(&version2, data, data_size);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(true == version2.multipart);
+ }
+ EXRHeader** headers2;
+ int num_headers2;
+ {
+ const char* err = NULL;
+ int ret = ParseEXRMultipartHeaderFromMemory(&headers2, &num_headers2, &version2,
+ data, data_size, &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ }
+ REQUIRE(num_headers1 == num_headers2);
+
+ std::vector<EXRImage> images2(num_headers2);
+ {
+ for (int j = 0; j < num_headers2; j++) {
+ InitEXRImage(&images2[j]);
+ }
+ const char* err = NULL;
+ int ret = LoadEXRMultipartImageFromMemory(&images2[0], const_cast<const EXRHeader**>(headers2),
+ static_cast<unsigned int>(num_headers2),
+ data, data_size, &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ free(data);
+ }
+
+ for (int j = 0; j < num_headers2; j++) {
+ CompareHeaders(headers1[j], *headers2[j]);
+ }
+ for (int j = 0; j < num_headers2; j++) {
+ CompareImages(images1[j], images2[j]);
+ }
+
+ for (int j = 0; j < num_headers2; j++) {
+ FreeEXRImage(&images2[j]);
+ FreeEXRHeader(headers2[j]);
+ free(headers2[j]);
+ }
+ free(headers2);
+ }
+
+ for (int i = 0; i < num_headers1; i++) {
+ FreeEXRImage(&images1[i]);
+ FreeEXRHeader(&headers1[i]);
+ }
+}
+
+#if 0 // Spirals.exr uses pxr24 compression
+TEST_CASE("Tiles/Spirals.exr", "[Load]") {
+ EXRVersion exr_version;
+ std::string filepath = GetPath("Tiles/Spirals.exr");
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(true == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+
+ ret= LoadEXRImageFromFile(&image, &header, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ FreeEXRHeader(&header);
+ FreeEXRImage(&image);
+}
+#endif
+
+TEST_CASE("Beachball/multipart.0001.exr", "[Version]") {
+ EXRVersion exr_version;
+ std::string filepath = GetPath("Beachball/multipart.0001.exr");
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(true == exr_version.multipart);
+
+ EXRHeader* headers;
+}
+
+TEST_CASE("Beachball/multipart.0001.exr|Load", "[Load]") {
+ EXRVersion exr_version;
+ std::string filepath = GetPath("Beachball/multipart.0001.exr");
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(true == exr_version.multipart);
+
+ EXRHeader** exr_headers; // list of EXRHeader pointers.
+ int num_exr_headers;
+ const char* err;
+
+ ret = ParseEXRMultipartHeaderFromFile(&exr_headers, &num_exr_headers,
+ &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ REQUIRE(10 == num_exr_headers);
+
+ std::vector<EXRImage> images(static_cast<size_t>(num_exr_headers));
+ for (int i = 0; i < num_exr_headers; i++) {
+ InitEXRImage(&images[static_cast<size_t>(i)]);
+ }
+
+ ret = LoadEXRMultipartImageFromFile(
+ &images.at(0), const_cast<const EXRHeader**>(exr_headers),
+ static_cast<unsigned int>(num_exr_headers), filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ for (int i = 0; i < num_exr_headers; i++) {
+ FreeEXRImage(&images.at(static_cast<size_t>(i)));
+ }
+
+ for (int i = 0; i < num_exr_headers; i++) {
+ FreeEXRHeader(exr_headers[static_cast<size_t>(i)]); // free content
+ free(exr_headers[static_cast<size_t>(i)]); // free pointer
+ }
+ free(exr_headers);
+}
+
+TEST_CASE("Beachbal multiparts", "[Load]") {
+ int num = 8;
+ char buf[1024];
+ for (int i = 0; i < num + 1; i++) {
+ sprintf(buf, "Beachball/multipart.%04d.exr", i);
+ EXRVersion exr_version;
+ std::string filepath = GetPath(buf);
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+
+ if (i == 0) { // multipart.0000.exr does not exist.
+ REQUIRE(TINYEXR_ERROR_CANT_OPEN_FILE == ret);
+ continue;
+ }
+
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(true == exr_version.multipart);
+
+ EXRHeader** exr_headers; // list of EXRHeader pointers.
+ int num_exr_headers;
+ const char* err;
+
+ ret = ParseEXRMultipartHeaderFromFile(&exr_headers, &num_exr_headers,
+ &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ REQUIRE(10 == num_exr_headers);
+
+ std::vector<EXRImage> images(static_cast<size_t>(num_exr_headers));
+ for (int j = 0; j < num_exr_headers; j++) {
+ InitEXRImage(&images[static_cast<size_t>(j)]);
+ }
+
+ ret = LoadEXRMultipartImageFromFile(
+ &images.at(0), const_cast<const EXRHeader**>(exr_headers),
+ static_cast<unsigned int>(num_exr_headers), filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ for (int j = 0; j < num_exr_headers; j++) {
+ FreeEXRImage(&images.at(static_cast<size_t>(j)));
+ }
+
+ for (int j = 0; j < num_exr_headers; j++) {
+ FreeEXRHeader(exr_headers[static_cast<size_t>(j)]);
+ free(exr_headers[static_cast<size_t>(j)]);
+ }
+ free(exr_headers);
+ }
+}
+
+TEST_CASE("Beachbal singleparts", "[Load]") {
+ int num = 8;
+ char buf[1024];
+ for (int i = 0; i < num + 1; i++) {
+ sprintf(buf, "Beachball/singlepart.%04d.exr", i);
+ EXRVersion exr_version;
+ std::string filepath = GetPath(buf);
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+
+ if (i == 0) { // multipart.0000.exr does not exist.
+ REQUIRE(TINYEXR_ERROR_CANT_OPEN_FILE == ret);
+ continue;
+ }
+
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(false == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ memset(&version, 0, sizeof(EXRVersion));
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ ret = LoadEXRImageFromFile(&image, &header, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ REQUIRE(image.tiles == NULL);
+ REQUIRE(image.images);
+
+ FreeEXRHeader(&header);
+ FreeEXRImage(&image);
+ }
+}
+
+TEST_CASE("ParseEXRVersionFromMemory invalid input", "[Parse]") {
+ int ret = ParseEXRVersionFromMemory(NULL, NULL, 0);
+ REQUIRE(ret == TINYEXR_ERROR_INVALID_ARGUMENT);
+
+ {
+ EXRVersion version;
+ memset(&version, 0, sizeof(EXRVersion));
+ ret = ParseEXRVersionFromMemory(&version, NULL, 0);
+ REQUIRE(ret == TINYEXR_ERROR_INVALID_ARGUMENT);
+ }
+
+ {
+ EXRVersion version;
+ memset(&version, 0, sizeof(EXRVersion));
+ std::vector<unsigned char> buf(128);
+ ret = ParseEXRVersionFromMemory(&version, buf.data(), 0);
+ REQUIRE(ret == TINYEXR_ERROR_INVALID_DATA);
+ }
+
+ {
+ EXRVersion version;
+ memset(&version, 0, sizeof(EXRVersion));
+ std::vector<unsigned char> buf(4);
+ ret = ParseEXRVersionFromMemory(
+ &version, buf.data(), 1); // size is less than version header size
+ REQUIRE(ret == TINYEXR_ERROR_INVALID_DATA);
+ }
+
+ {
+ EXRVersion version;
+ memset(&version, 0, sizeof(EXRVersion));
+ std::vector<unsigned char> buf(8, 0); // invalid magic number
+ ret = ParseEXRVersionFromMemory(&version, buf.data(), 8);
+ REQUIRE(ret == TINYEXR_ERROR_INVALID_MAGIC_NUMBER);
+ }
+}
+
+TEST_CASE("ParseEXRHeaderFromMemory invalid input", "[Parse]") {
+ {
+ int ret = ParseEXRHeaderFromMemory(NULL, NULL, NULL, 0, NULL);
+ REQUIRE(ret == TINYEXR_ERROR_INVALID_ARGUMENT);
+ }
+
+ {
+ EXRHeader header;
+ InitEXRHeader(&header);
+ EXRVersion version;
+ memset(&version, 0, sizeof(EXRVersion));
+
+ int ret = ParseEXRHeaderFromMemory(&header, &version, NULL, 0, NULL);
+ REQUIRE(ret == TINYEXR_ERROR_INVALID_ARGUMENT);
+ FreeEXRHeader(&header);
+ }
+
+ {
+ EXRHeader header;
+ InitEXRHeader(&header);
+ EXRVersion version;
+ memset(&version, 0, sizeof(EXRVersion));
+ std::vector<unsigned char> buf(128);
+
+ int ret = ParseEXRHeaderFromMemory(&header, &version, buf.data(), 0, NULL);
+ REQUIRE(ret == TINYEXR_ERROR_INVALID_DATA);
+ FreeEXRHeader(&header);
+ }
+
+ {
+ EXRHeader header;
+ InitEXRHeader(&header);
+ EXRVersion version;
+ memset(&version, 0, sizeof(EXRVersion));
+ std::vector<unsigned char> buf(128, 0);
+
+ int ret =
+ ParseEXRHeaderFromMemory(&header, &version, buf.data(), 128, NULL);
+ REQUIRE(ret == TINYEXR_ERROR_INVALID_HEADER);
+ FreeEXRHeader(&header);
+ }
+}
+
+TEST_CASE("Compressed is smaller than uncompressed", "[Issue40]") {
+ EXRHeader header;
+ InitEXRHeader(&header);
+
+ header.compression_type = TINYEXR_COMPRESSIONTYPE_ZIP;
+
+ EXRImage image;
+ InitEXRImage(&image);
+
+ image.num_channels = 3;
+
+ float const images[3][1] = {
+ {1.0f},
+ {0.0f},
+ {0.0f},
+ };
+
+ float const* const image_ptr[3] = {
+ images[2],
+ images[1],
+ images[0],
+ };
+
+ image.images = const_cast<unsigned char**>(reinterpret_cast<const unsigned char*const *>(image_ptr));
+ image.width = 1;
+ image.height = 1;
+
+ header.num_channels = 3;
+ header.channels =
+ static_cast<EXRChannelInfo*>(malloc(sizeof(EXRChannelInfo) * static_cast<size_t>(header.num_channels)));
+ // Must be BGR(A) order, since most of EXR viewers expect this channel order.
+ strncpy(header.channels[0].name, "B", 255);
+ header.channels[0].name[strlen("B")] = '\0';
+ strncpy(header.channels[1].name, "G", 255);
+ header.channels[1].name[strlen("G")] = '\0';
+ strncpy(header.channels[2].name, "R", 255);
+ header.channels[2].name[strlen("R")] = '\0';
+
+ header.pixel_types = static_cast<int*>(malloc(sizeof(int) * static_cast<size_t>(header.num_channels)));
+ header.requested_pixel_types =
+ static_cast<int*>(malloc(sizeof(int) * static_cast<size_t>(header.num_channels)));
+ for (int i = 0; i < header.num_channels; i++) {
+ header.pixel_types[i] =
+ TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image
+ header.requested_pixel_types[i] =
+ TINYEXR_PIXELTYPE_FLOAT; // pixel type of output image to be stored in
+ // .EXR
+ }
+
+ const char* err;
+ int const ret = SaveEXRImageToFile(&image, &header, "issue40.exr", &err);
+ REQUIRE(ret == TINYEXR_SUCCESS);
+
+ free(header.channels);
+ free(header.requested_pixel_types);
+ free(header.pixel_types);
+}
+
+// TEST_CASE("Regression: Issue54", "[fuzzing]") {
+// EXRVersion exr_version;
+// std::string filepath =
+// "./regression/poc-360c3b0555cb979ca108f2d178cf8a80959cfeabaa4ec1d310d062fa653a8c6b_min";
+// int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+// REQUIRE(TINYEXR_SUCCESS == ret);
+// REQUIRE(false == exr_version.tiled);
+// REQUIRE(false == exr_version.non_image);
+// REQUIRE(false == exr_version.multipart);
+//
+// EXRVersion version;
+// EXRHeader header;
+// EXRImage image;
+// InitEXRHeader(&header);
+// InitEXRImage(&image);
+//
+// const char* err;
+// ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+// REQUIRE(TINYEXR_SUCCESS == ret);
+//
+// ret = LoadEXRImageFromFile(&image, &header, filepath.c_str(), &err);
+// REQUIRE(TINYEXR_SUCCESS == ret);
+//
+// FreeEXRHeader(&header);
+// FreeEXRImage(&image);
+//}
+
+TEST_CASE("Regression: Issue50", "[fuzzing]") {
+ EXRVersion exr_version;
+ std::string filepath =
+ "./regression/"
+ "poc-eedff3a9e99eb1c0fd3a3b0989e7c44c0a69f04f10b23e5264f362a4773f4397_"
+ "min";
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(false == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err = nullptr;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == false);
+ if (ret) {
+ FreeEXRErrorMessage(err);
+ }
+
+ FreeEXRHeader(&header);
+ // FreeEXRImage(&image);
+}
+
+TEST_CASE("Regression: Issue57", "[fuzzing]") {
+ EXRVersion exr_version;
+ std::string filepath =
+ "./regression/"
+ "poc-df76d1f27adb8927a1446a603028272140905c168a336128465a1162ec7af270."
+ "mini";
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(false == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err = nullptr;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == false);
+ if (err) {
+ FreeEXRErrorMessage(err);
+ }
+
+ FreeEXRHeader(&header);
+ // FreeEXRImage(&image);
+}
+
+TEST_CASE("Regression: Issue56", "[fuzzing]") {
+ EXRVersion exr_version;
+ std::string filepath =
+ "./regression/"
+ "poc-1383755b301e5f505b2198dc0508918b537fdf48bbfc6deeffe268822e6f6cd6";
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(false == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err = nullptr;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == false);
+ if (err) {
+ FreeEXRErrorMessage(err);
+ }
+
+ FreeEXRHeader(&header);
+ // FreeEXRImage(&image);
+}
+
+TEST_CASE("Regression: Issue61", "[fuzzing]") {
+ EXRVersion exr_version;
+ std::string filepath =
+ "./regression/"
+ "poc-3f1f642c3356fd8e8d2a0787613ec09a56572b3a1e38c9629b6db9e8dead1117_"
+ "min";
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(false == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err = nullptr;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == false);
+ if (err) {
+ FreeEXRErrorMessage(err);
+ }
+
+ FreeEXRHeader(&header);
+ // FreeEXRImage(&image);
+}
+
+TEST_CASE("Regression: Issue60", "[fuzzing]") {
+ EXRVersion exr_version;
+ std::string filepath =
+ "./regression/"
+ "poc-5b66774a7498c635334ad386be0c3b359951738ac47f14878a3346d1c6ea0fe5_"
+ "min";
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(false == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err = nullptr;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == false);
+ if (err) {
+ FreeEXRErrorMessage(err);
+ }
+
+ FreeEXRHeader(&header);
+ // FreeEXRImage(&image);
+}
+
+TEST_CASE("Regression: Issue71", "[issue71]") {
+ std::string filepath = "./regression/2by2.exr";
+
+ const char* err;
+ int width, height;
+ float* image;
+ int ret = LoadEXR(&image, &width, &height, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(2 == width);
+ REQUIRE(2 == height);
+
+ REQUIRE(0.0f == Approx(image[8]));
+ REQUIRE(0.447021f == Approx(image[9]));
+ REQUIRE(1.0f == Approx(image[10]));
+ REQUIRE(0.250977f == Approx(image[11]));
+ REQUIRE(0.0f == Approx(image[12]));
+ REQUIRE(0.0f == Approx(image[13]));
+ REQUIRE(0.0f == Approx(image[14]));
+ REQUIRE(1.0f == Approx(image[15]));
+
+ free(image);
+}
+
+// LoadEXRLoadFromMemory fails to load tiled image.
+TEST_CASE("Regression: Issue93", "[issue93]") {
+ std::string filepath = GetPath("Tiles/GoldenGate.exr");
+
+ std::ifstream f(filepath.c_str(), std::ifstream::binary);
+ REQUIRE(f.good());
+
+ f.seekg(0, f.end);
+ size_t sz = static_cast<size_t>(f.tellg());
+ f.seekg(0, f.beg);
+
+ REQUIRE(sz > 16);
+
+ std::vector<unsigned char> data;
+
+ data.resize(sz);
+ f.read(reinterpret_cast<char*>(&data.at(0)),
+ static_cast<std::streamsize>(sz));
+ f.close();
+
+ const char* err;
+ int width, height;
+ float* image;
+ int ret = LoadEXRFromMemory(&image, &width, &height, data.data(), data.size(),
+ &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ std::cout << "val = " << image[0] << ", " << image[1] << ", " << image[2]
+ << ", " << image[3] << std::endl;
+
+ REQUIRE(0.0612183 == Approx(image[0]));
+ REQUIRE(0.0892334 == Approx(image[1]));
+ REQUIRE(0.271973 == Approx(image[2]));
+
+ free(image);
+}
+
+// PIZ decompress bug(issue 100)
+TEST_CASE("Regression: Issue100", "[issue100]") {
+ std::string filepath = "./regression/piz-bug-issue-100.exr";
+
+ std::ifstream f(filepath.c_str(), std::ifstream::binary);
+ REQUIRE(f.good());
+
+ f.seekg(0, f.end);
+ size_t sz = static_cast<size_t>(f.tellg());
+ f.seekg(0, f.beg);
+
+ REQUIRE(sz > 16);
+
+ std::vector<unsigned char> data;
+
+ data.resize(sz);
+ f.read(reinterpret_cast<char*>(&data.at(0)),
+ static_cast<std::streamsize>(sz));
+ f.close();
+
+ const char* err = nullptr;
+ int width, height;
+ float* image;
+ int ret = LoadEXRFromMemory(&image, &width, &height, data.data(), data.size(),
+ &err);
+ if (err) {
+ std::cerr << "issue100 err " << err << std::endl;
+ FreeEXRErrorMessage(err);
+ }
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(35 == width);
+ REQUIRE(1 == height);
+
+ // pixel should be white.
+
+ std::cout << "pixel[0] = " << image[0] << ", " << image[1] << ", " << image[2]
+ << ", " << image[3] << std::endl;
+ std::cout << "pixel[34] = " << image[4 * 34 + 0] << ", " << image[4 * 34 + 1]
+ << ", " << image[4 * 34 + 2] << ", " << image[4 * 34 + 3]
+ << std::endl;
+
+ REQUIRE(0.0 == Approx(image[0]));
+ REQUIRE(0.0 == Approx(image[1]));
+ REQUIRE(0.0 == Approx(image[2]));
+ REQUIRE(0.0 == Approx(image[3]));
+
+ REQUIRE(1.0 == Approx(image[4 * 34 + 0]));
+ REQUIRE(1.0 == Approx(image[4 * 34 + 1]));
+ REQUIRE(1.0 == Approx(image[4 * 34 + 2]));
+ REQUIRE(1.0 == Approx(image[4 * 34 + 3]));
+
+ free(image);
+}
+
+TEST_CASE("Regression: Issue53|Channels", "[issue53]") {
+ EXRVersion exr_version;
+ std::string filepath = "./regression/flaga.exr";
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+
+ const char* err = nullptr;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ std::vector<std::string> layer_names;
+ tinyexr::GetLayers(header, layer_names);
+
+ REQUIRE(2 == layer_names.size());
+
+ std::vector<tinyexr::LayerChannel> channels;
+ tinyexr::ChannelsInLayer(header, "", channels);
+ REQUIRE(8 == channels.size());
+
+ channels.clear();
+ tinyexr::ChannelsInLayer(header, "Warstwa 3", channels);
+ REQUIRE(0 == channels.size());
+
+ channels.clear();
+ tinyexr::ChannelsInLayer(header, "Warstwa 1", channels);
+ REQUIRE(4 == channels.size());
+
+ FreeEXRHeader(&header);
+
+ if (err) {
+ FreeEXRErrorMessage(err);
+ }
+}
+
+TEST_CASE("Regression: Issue53|Image", "[issue53]") {
+ std::string filepath = "./regression/flaga.exr";
+
+ const char* err = nullptr;
+ const char** layer_names = nullptr;
+ int num_layers = 0;
+ int ret = EXRLayers(filepath.c_str(), &layer_names, &num_layers, &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(2 == num_layers);
+ for (int i = 0; i < num_layers; i++) {
+ free(reinterpret_cast<void*>(const_cast<char*>(layer_names[i])));
+ }
+ free(layer_names);
+
+ int width, height;
+ float* image;
+ ret = LoadEXRWithLayer(&image, &width, &height, filepath.c_str(), NULL, &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ free(image);
+ if (err) {
+ FreeEXRErrorMessage(err);
+ }
+
+ ret = LoadEXRWithLayer(&image, &width, &height, filepath.c_str(), "Warstwa 1",
+ &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ free(image);
+ if (err) {
+ FreeEXRErrorMessage(err);
+ }
+}
+
+TEST_CASE("Regression: Issue53|Image|Missing Layer", "[issue53]") {
+ std::string filepath = GetPath("MultiView/Impact.exr");
+
+ const char* err = nullptr;
+ int width, height;
+ float* image = nullptr;
+ int ret = LoadEXRWithLayer(&image, &width, &height, filepath.c_str(),
+ "Warstwa", &err);
+ REQUIRE(TINYEXR_ERROR_LAYER_NOT_FOUND == ret);
+ if (image) {
+ free(image);
+ }
+ if (err) {
+ FreeEXRErrorMessage(err);
+ }
+}
+
+TEST_CASE("Regression: PR150|Read|1x1 1xhalf", "[pr150]") {
+ std::string filepath = "./regression/tiled_half_1x1_alpha.exr";
+
+ EXRVersion exr_version;
+ std::cout << "Loading" << filepath << std::endl;
+ int ret = ParseEXRVersionFromFile(&exr_version, filepath.c_str());
+ REQUIRE(TINYEXR_SUCCESS == ret);
+ REQUIRE(true == exr_version.tiled);
+ REQUIRE(false == exr_version.non_image);
+ REQUIRE(false == exr_version.multipart);
+
+ EXRVersion version;
+ EXRHeader header;
+ EXRImage image;
+ InitEXRHeader(&header);
+ InitEXRImage(&image);
+
+ const char* err;
+ ret = ParseEXRHeaderFromFile(&header, &exr_version, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ ret = LoadEXRImageFromFile(&image, &header, filepath.c_str(), &err);
+ REQUIRE(TINYEXR_SUCCESS == ret);
+
+ FreeEXRHeader(&header);
+ FreeEXRImage(&image);
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/vcbuild.bat b/graphics/asymptote/cudareflect/tinyexr/test/unit/vcbuild.bat
new file mode 100644
index 0000000000..e8646735e9
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/vcbuild.bat
@@ -0,0 +1,4 @@
+chcp 437
+python kuroga.py config-msvc.py
+call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64
+ninja
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/win32-filelist-utf16le.inc b/graphics/asymptote/cudareflect/tinyexr/test/unit/win32-filelist-utf16le.inc
new file mode 100644
index 0000000000..b784ce8c94
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/win32-filelist-utf16le.inc
Binary files differ
diff --git a/graphics/asymptote/cudareflect/tinyexr/test/unit/win32-filelist-utf8.inc b/graphics/asymptote/cudareflect/tinyexr/test/unit/win32-filelist-utf8.inc
new file mode 100644
index 0000000000..a2b9366d57
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test/unit/win32-filelist-utf8.inc
@@ -0,0 +1 @@
+u8"./regression/日本語.exr"
diff --git a/graphics/asymptote/cudareflect/tinyexr/test_tinyexr.cc b/graphics/asymptote/cudareflect/tinyexr/test_tinyexr.cc
new file mode 100644
index 0000000000..07a38a4769
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/test_tinyexr.cc
@@ -0,0 +1,469 @@
+#if defined(_WIN32)
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#include <tchar.h>
+#include <windows.h>
+#endif
+
+#include <cstdio>
+#include <cstdlib>
+#include <iostream>
+#include <vector>
+
+// Uncomment if you want to use system provided zlib.
+// #define TINYEXR_USE_MINIZ (0)
+// #include <zlib.h>
+
+#define TINYEXR_IMPLEMENTATION
+#include "tinyexr.h"
+
+#ifdef __clang__
+#if __has_warning("-Wzero-as-null-pointer-constant")
+#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
+#endif
+#endif
+
+#define SIMPLE_API_EXAMPLE
+//#define TEST_ZFP_COMPRESSION
+
+#ifdef SIMPLE_API_EXAMPLE
+
+#if 0
+static void
+SaveAsPFM(const char* filename, int width, int height, float* data)
+{
+#ifdef _WIN32
+ FILE* fp = NULL;
+ fopen_s(&fp, filename, "wb");
+#else
+ FILE* fp = fopen(filename, "wb");
+#endif
+ if (!fp) {
+ fprintf(stderr, "failed to write a PFM file.\n");
+ return;
+ }
+
+ fprintf(fp, "PF\n");
+ fprintf(fp, "%d %d\n", width, height);
+ fprintf(fp, "-1\n"); // -1: little endian, 1: big endian
+
+ // RGBA -> RGB
+ std::vector<float> rgb(static_cast<size_t>(width*height*3));
+
+ for (size_t i = 0; i < static_cast<size_t>(width * height); i++) {
+ rgb[3*i+0] = data[4*i+0];
+ rgb[3*i+1] = data[4*i+1];
+ rgb[3*i+2] = data[4*i+2];
+ }
+
+ fwrite(&rgb.at(0), sizeof(float), static_cast<size_t>(width * height * 3), fp);
+
+ fclose(fp);
+}
+#endif
+
+#else
+
+static const char* GetPixelType(int id) {
+ if (id == TINYEXR_PIXELTYPE_HALF) {
+ return "HALF";
+ } else if (id == TINYEXR_PIXELTYPE_FLOAT) {
+ return "FLOAT";
+ } else if (id == TINYEXR_PIXELTYPE_UINT) {
+ return "UINT";
+ }
+
+ return "???";
+}
+
+// Simple tile -> scanline converter. Assumes FLOAT pixel type for all channels.
+static void TiledImageToScanlineImage(EXRImage* src, const EXRHeader* header) {
+ assert(header->data_window.max_x - header->data_window.min_x + 1 >= 0);
+ assert(header->data_window.max_y - header->data_window.min_y + 1 >= 0);
+ size_t data_width =
+ static_cast<size_t>(header->data_window.max_x - header->data_window.min_x + 1);
+ size_t data_height =
+ static_cast<size_t>(header->data_window.max_y - header->data_window.min_y + 1);
+
+ src->images = static_cast<unsigned char**>(
+ malloc(sizeof(float*) * static_cast<size_t>(header->num_channels)));
+ for (size_t c = 0; c < static_cast<size_t>(header->num_channels); c++) {
+ assert(header->pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT);
+ src->images[c] = static_cast<unsigned char*>(
+ malloc(sizeof(float) * data_width * data_height));
+ memset(src->images[c], 0, sizeof(float) * data_width * data_height);
+ }
+
+ for (size_t tile_idx = 0; tile_idx < static_cast<size_t>(src->num_tiles);
+ tile_idx++) {
+ size_t sx = static_cast<size_t>(src->tiles[tile_idx].offset_x *
+ header->tile_size_x);
+ size_t sy = static_cast<size_t>(src->tiles[tile_idx].offset_y *
+ header->tile_size_y);
+ size_t ex = static_cast<size_t>(src->tiles[tile_idx].offset_x *
+ header->tile_size_x +
+ src->tiles[tile_idx].width);
+ size_t ey = static_cast<size_t>(src->tiles[tile_idx].offset_y *
+ header->tile_size_y +
+ src->tiles[tile_idx].height);
+
+ for (size_t c = 0; c < static_cast<size_t>(header->num_channels); c++) {
+ float* dst_image = reinterpret_cast<float*>(src->images[c]);
+ const float* src_image =
+ reinterpret_cast<const float*>(src->tiles[tile_idx].images[c]);
+ for (size_t y = 0; y < static_cast<size_t>(ey - sy); y++) {
+ for (size_t x = 0; x < static_cast<size_t>(ex - sx); x++) {
+ dst_image[(y + sy) * data_width + (x + sx)] =
+ src_image[y * static_cast<size_t>(header->tile_size_x) + x];
+ }
+ }
+ }
+ }
+}
+#endif
+
+#if defined(_WIN32)
+
+#if defined(__MINGW32__)
+// __wgetmainargs is not defined in windows.h
+extern "C" int __wgetmainargs(int*, wchar_t***, wchar_t***, int, int*);
+#endif
+
+// https://gist.github.com/trueroad/fb4d0c3f67285bf66804
+namespace {
+std::vector<char> utf16_to_utf8(const wchar_t* wc) {
+ int size = WideCharToMultiByte(CP_UTF8, 0, wc, -1, NULL, 0, NULL, NULL);
+ std::vector<char> retval(size);
+ if (size) {
+ WideCharToMultiByte(CP_UTF8, 0, wc, -1, retval.data(), retval.size(), NULL,
+ NULL);
+ } else
+ retval.push_back('\0');
+ return retval;
+}
+} // namespace
+#endif
+
+static int test_main(int argc, char** argv);
+
+#if defined(_WIN32)
+#if defined(__MINGW32__)
+int main() {
+ wchar_t** wargv;
+ wchar_t** wenpv;
+ int argc = 0, si = 0;
+ __wgetmainargs(&argc, &wargv, &wenpv, 1, &si);
+
+ std::vector<std::vector<char> > argv_vvc(argc);
+ std::vector<char*> argv_vc(argc);
+
+ for (int i = 0; i < argc; i++) {
+ argv_vvc.at(i) = utf16_to_utf8(wargv[i]);
+ argv_vc.at(i) = argv_vvc.at(i).data();
+ }
+
+ // TODO(syoyo): envp
+
+ return test_main(argc, argv_vc.data());
+}
+#else // Assume MSVC
+int _tmain(int argc, _TCHAR** wargv) {
+ std::vector<std::vector<char> > argv_vvc(argc);
+ std::vector<char*> argv_vc(argc);
+
+ for (int i = 0; i < argc; i++) {
+#if defined(UNICODE) || defined(_UNICODE)
+ argv_vvc.at(i) = utf16_to_utf8(wargv[i]);
+#else
+ size_t slen = _tcslen(wargv[i]);
+ std::vector<char> buf(slen + 1);
+ memcpy(buf.data(), wargv[i], slen);
+ buf[slen] = '\0';
+ argv_vvc.at(i) = buf;
+#endif
+
+ argv_vc.at(i) = argv_vvc.at(i).data();
+ }
+
+ return test_main(argc, argv_vc.data());
+}
+#endif
+#else
+int main(int argc, char** argv) { return test_main(argc, argv); }
+#endif
+
+int test_main(int argc, char** argv) {
+ const char* outfilename = "output_test.exr";
+ const char* err = NULL;
+
+ if (argc < 2) {
+ fprintf(stderr, "Needs input.exr.\n");
+ exit(-1);
+ }
+
+ if (argc > 2) {
+ outfilename = argv[2];
+ }
+
+ const char* input_filename = argv[1];
+
+#ifdef SIMPLE_API_EXAMPLE
+ (void)outfilename;
+ int width, height;
+ float* image;
+
+ int ret = IsEXR(input_filename);
+ if (ret != TINYEXR_SUCCESS) {
+ fprintf(stderr, "Header err. code %d\n", ret);
+ exit(-1);
+ }
+
+ ret = LoadEXR(&image, &width, &height, input_filename, &err);
+ if (ret != TINYEXR_SUCCESS) {
+ if (err) {
+ fprintf(stderr, "Load EXR err: %s(code %d)\n", err, ret);
+ } else {
+ fprintf(stderr, "Load EXR err: code = %d\n", ret);
+ }
+ FreeEXRErrorMessage(err);
+ return ret;
+ }
+ // SaveAsPFM("output.pfm", width, height, image);
+ ret = SaveEXR(image, width, height, 4 /* =RGBA*/,
+ 1 /* = save as fp16 format */, "output.exr", &err);
+ if (ret != TINYEXR_SUCCESS) {
+ if (err) {
+ fprintf(stderr, "Save EXR err: %s(code %d)\n", err, ret);
+ } else {
+ fprintf(stderr, "Failed to save EXR image. code = %d\n", ret);
+ }
+ }
+ free(image);
+
+ std::cout << "Wrote output.exr." << std::endl;
+#else
+
+ EXRVersion exr_version;
+
+ int ret = ParseEXRVersionFromFile(&exr_version, input_filename);
+ if (ret != 0) {
+ fprintf(stderr, "Invalid EXR file: %s\n", input_filename);
+ return -1;
+ }
+
+ printf(
+ "version: tiled = %d, long_name = %d, non_image = %d, multipart = %d\n",
+ exr_version.tiled, exr_version.long_name, exr_version.non_image,
+ exr_version.multipart);
+
+ if (exr_version.multipart) {
+ EXRHeader** exr_headers; // list of EXRHeader pointers.
+ int num_exr_headers;
+
+ ret = ParseEXRMultipartHeaderFromFile(&exr_headers, &num_exr_headers,
+ &exr_version, argv[1], &err);
+ if (ret != 0) {
+ fprintf(stderr, "Parse EXR err: %s\n", err);
+ return ret;
+ }
+
+ printf("num parts = %d\n", num_exr_headers);
+
+ for (size_t i = 0; i < static_cast<size_t>(num_exr_headers); i++) {
+ const EXRHeader& exr_header = *(exr_headers[i]);
+
+ printf("Part: %lu\n", static_cast<unsigned long>(i));
+
+ printf("dataWindow = %d, %d, %d, %d\n", exr_header.data_window.min_x,
+ exr_header.data_window.min_y, exr_header.data_window.max_x,
+ exr_header.data_window.max_y);
+ printf("displayWindow = %d, %d, %d, %d\n", exr_header.display_window.min_x,
+ exr_header.display_window.min_y, exr_header.display_window.max_x,
+ exr_header.display_window.max_y);
+ printf("screenWindowCenter = %f, %f\n",
+ static_cast<double>(exr_header.screen_window_center[0]),
+ static_cast<double>(exr_header.screen_window_center[1]));
+ printf("screenWindowWidth = %f\n",
+ static_cast<double>(exr_header.screen_window_width));
+ printf("pixelAspectRatio = %f\n",
+ static_cast<double>(exr_header.pixel_aspect_ratio));
+ printf("lineOrder = %d\n", exr_header.line_order);
+
+ if (exr_header.num_custom_attributes > 0) {
+ printf("# of custom attributes = %d\n",
+ exr_header.num_custom_attributes);
+ for (int a = 0; a < exr_header.num_custom_attributes; a++) {
+ printf(" [%d] name = %s, type = %s, size = %d\n", a,
+ exr_header.custom_attributes[a].name,
+ exr_header.custom_attributes[a].type,
+ exr_header.custom_attributes[a].size);
+ // if (strcmp(exr_header.custom_attributes[i].type, "float") == 0) {
+ // printf(" value = %f\n", *reinterpret_cast<float
+ // *>(exr_header.custom_attributes[i].value));
+ //}
+ }
+ }
+ }
+
+ std::vector<EXRImage> images(static_cast<size_t>(num_exr_headers));
+ for (size_t i = 0; i < static_cast<size_t>(num_exr_headers); i++) {
+ InitEXRImage(&images[i]);
+ }
+
+ ret = LoadEXRMultipartImageFromFile(
+ &images.at(0), const_cast<const EXRHeader**>(exr_headers),
+ static_cast<unsigned int>(num_exr_headers), input_filename, &err);
+ if (ret != 0) {
+ fprintf(stderr, "Load EXR err: %s\n", err);
+ FreeEXRErrorMessage(err);
+ return ret;
+ }
+
+ printf("Loaded %d part images\n", num_exr_headers);
+ printf(
+ "There is no saving feature for multi-part images, thus just exit an "
+ "application...\n");
+
+ for (size_t i = 0; i < static_cast<size_t>(num_exr_headers); i++) {
+ FreeEXRImage(&images.at(i));
+ }
+
+ for (size_t i = 0; i < static_cast<size_t>(num_exr_headers); i++) {
+ FreeEXRHeader(exr_headers[i]);
+ free(exr_headers[i]);
+ }
+ free(exr_headers);
+
+ } else { // single-part EXR
+
+ EXRHeader exr_header;
+ InitEXRHeader(&exr_header);
+
+ ret =
+ ParseEXRHeaderFromFile(&exr_header, &exr_version, input_filename, &err);
+ if (ret != 0) {
+ fprintf(stderr, "Parse single-part EXR err: %s\n", err);
+ FreeEXRErrorMessage(err);
+ return ret;
+ }
+
+ printf("dataWindow = %d, %d, %d, %d\n", exr_header.data_window.min_x,
+ exr_header.data_window.min_y, exr_header.data_window.max_x,
+ exr_header.data_window.max_y);
+ printf("displayWindow = %d, %d, %d, %d\n", exr_header.display_window.min_x,
+ exr_header.display_window.min_y, exr_header.display_window.max_x,
+ exr_header.display_window.max_y);
+ printf("screenWindowCenter = %f, %f\n",
+ static_cast<double>(exr_header.screen_window_center[0]),
+ static_cast<double>(exr_header.screen_window_center[1]));
+ printf("screenWindowWidth = %f\n",
+ static_cast<double>(exr_header.screen_window_width));
+ printf("pixelAspectRatio = %f\n",
+ static_cast<double>(exr_header.pixel_aspect_ratio));
+ printf("lineOrder = %d\n", exr_header.line_order);
+
+ if (exr_header.num_custom_attributes > 0) {
+ printf("# of custom attributes = %d\n", exr_header.num_custom_attributes);
+ for (int i = 0; i < exr_header.num_custom_attributes; i++) {
+ printf(" [%d] name = %s, type = %s, size = %d\n", i,
+ exr_header.custom_attributes[i].name,
+ exr_header.custom_attributes[i].type,
+ exr_header.custom_attributes[i].size);
+ // if (strcmp(exr_header.custom_attributes[i].type, "float") == 0) {
+ // printf(" value = %f\n", *reinterpret_cast<float
+ // *>(exr_header.custom_attributes[i].value));
+ //}
+ }
+ }
+
+ // Read HALF channel as FLOAT.
+ for (int i = 0; i < exr_header.num_channels; i++) {
+ if (exr_header.pixel_types[i] == TINYEXR_PIXELTYPE_HALF) {
+ exr_header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
+ }
+ }
+
+ EXRImage exr_image;
+ InitEXRImage(&exr_image);
+
+ ret = LoadEXRImageFromFile(&exr_image, &exr_header, input_filename, &err);
+ if (ret != 0) {
+ fprintf(stderr, "Load EXR err: %s\n", err);
+ FreeEXRHeader(&exr_header);
+ FreeEXRErrorMessage(err);
+ return ret;
+ }
+
+ printf("EXR: %d x %d\n", exr_image.width, exr_image.height);
+
+ for (int i = 0; i < exr_header.num_channels; i++) {
+ printf("pixelType[%d]: %s\n", i, GetPixelType(exr_header.pixel_types[i]));
+ printf("chan[%d] = %s\n", i, exr_header.channels[i].name);
+ printf("requestedPixelType[%d]: %s\n", i,
+ GetPixelType(exr_header.requested_pixel_types[i]));
+ }
+
+#if 0 // example to write custom attribute
+ int version_minor = 3;
+ exr_header.num_custom_attributes = 1;
+ exr_header.custom_attributes = reinterpret_cast<EXRAttribute *>(malloc(sizeof(EXRAttribute) * exr_header.custom_attributes));
+ strcpy(exr_header.custom_attributes[0].name, "tinyexr_version_minor");
+ exr_header.custom_attributes[0].name[strlen("tinyexr_version_minor")] = '\0';
+ strcpy(exr_header.custom_attributes[0].type, "int");
+ exr_header.custom_attributes[0].type[strlen("int")] = '\0';
+ exr_header.custom_attributes[0].size = sizeof(int);
+ exr_header.custom_attributes[0].value = (unsigned char*)malloc(sizeof(int));
+ memcpy(exr_header.custom_attributes[0].value, &version_minor, sizeof(int));
+#endif
+
+ if (exr_header.tiled) {
+ TiledImageToScanlineImage(&exr_image, &exr_header);
+ }
+
+ exr_header.compression_type = TINYEXR_COMPRESSIONTYPE_NONE;
+
+#ifdef TEST_ZFP_COMPRESSION
+ // Assume input image is FLOAT pixel type.
+ for (int i = 0; i < exr_header.num_channels; i++) {
+ exr_header.channels[i].pixel_type = TINYEXR_PIXELTYPE_FLOAT;
+ exr_header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
+ }
+
+ unsigned char zfp_compression_type = TINYEXR_ZFP_COMPRESSIONTYPE_RATE;
+ double zfp_compression_rate = 4;
+ exr_header.num_custom_attributes = 2;
+ strcpy(exr_header.custom_attributes[0].name, "zfpCompressionType");
+ exr_header.custom_attributes[0].name[strlen("zfpCompressionType")] = '\0';
+ exr_header.custom_attributes[0].size = 1;
+ exr_header.custom_attributes[0].value =
+ (unsigned char*)malloc(sizeof(unsigned char));
+ exr_header.custom_attributes[0].value[0] = zfp_compression_type;
+
+ strcpy(exr_header.custom_attributes[1].name, "zfpCompressionRate");
+ exr_header.custom_attributes[1].name[strlen("zfpCompressionRate")] = '\0';
+ exr_header.custom_attributes[1].size = sizeof(double);
+ exr_header.custom_attributes[1].value =
+ (unsigned char*)malloc(sizeof(double));
+ memcpy(exr_header.custom_attributes[1].value, &zfp_compression_rate,
+ sizeof(double));
+ exr_header.compression_type = TINYEXR_COMPRESSIONTYPE_ZFP;
+#endif
+
+ ret = SaveEXRImageToFile(&exr_image, &exr_header, outfilename, &err);
+ if (ret != 0) {
+ fprintf(stderr, "Save EXR err: %s\n", err);
+ FreeEXRHeader(&exr_header);
+ FreeEXRErrorMessage(err);
+ return ret;
+ }
+ printf("Saved exr file. [ %s ] \n", outfilename);
+
+ FreeEXRHeader(&exr_header);
+ FreeEXRImage(&exr_image);
+ }
+#endif
+
+ return ret;
+}
diff --git a/graphics/asymptote/cudareflect/tinyexr/tinyexr.cc b/graphics/asymptote/cudareflect/tinyexr/tinyexr.cc
new file mode 100644
index 0000000000..fef8f66c98
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/tinyexr.cc
@@ -0,0 +1,8 @@
+#if defined(_WIN32)
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#endif
+
+#define TINYEXR_IMPLEMENTATION
+#include "tinyexr.h"
diff --git a/graphics/asymptote/cudareflect/tinyexr/tinyexr.h b/graphics/asymptote/cudareflect/tinyexr/tinyexr.h
new file mode 100644
index 0000000000..a5e868b99a
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/tinyexr.h
@@ -0,0 +1,8535 @@
+#ifndef TINYEXR_H_
+#define TINYEXR_H_
+/*
+Copyright (c) 2014 - 2021, Syoyo Fujita and many contributors.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the Syoyo Fujita nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// TinyEXR contains some OpenEXR code, which is licensed under ------------
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+// End of OpenEXR license -------------------------------------------------
+
+
+//
+//
+// Do this:
+// #define TINYEXR_IMPLEMENTATION
+// before you include this file in *one* C or C++ file to create the
+// implementation.
+//
+// // i.e. it should look like this:
+// #include ...
+// #include ...
+// #include ...
+// #define TINYEXR_IMPLEMENTATION
+// #include "tinyexr.h"
+//
+//
+
+#ifdef __CYGWIN__
+extern "C" char *strdup (const char *) __malloc_like __result_use_check;
+extern "C" size_t strnlen (const char *, size_t);
+#endif
+
+#include <stddef.h> // for size_t
+#include <stdint.h> // guess stdint.h is available(C99)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
+ defined(__i386) || defined(__i486__) || defined(__i486) || \
+ defined(i386) || defined(__ia64__) || defined(__x86_64__)
+#define TINYEXR_X86_OR_X64_CPU 1
+#else
+#define TINYEXR_X86_OR_X64_CPU 0
+#endif
+
+#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || TINYEXR_X86_OR_X64_CPU
+#define TINYEXR_LITTLE_ENDIAN 1
+#else
+#define TINYEXR_LITTLE_ENDIAN 0
+#endif
+
+// Use miniz or not to decode ZIP format pixel. Linking with zlib
+// required if this flas is 0.
+#ifndef TINYEXR_USE_MINIZ
+#define TINYEXR_USE_MINIZ (1)
+#endif
+
+// Disable PIZ comporession when applying cpplint.
+#ifndef TINYEXR_USE_PIZ
+#define TINYEXR_USE_PIZ (1)
+#endif
+
+#ifndef TINYEXR_USE_ZFP
+#define TINYEXR_USE_ZFP (0) // TinyEXR extension.
+// http://computation.llnl.gov/projects/floating-point-compression
+#endif
+
+#ifndef TINYEXR_USE_THREAD
+#define TINYEXR_USE_THREAD (0) // No threaded loading.
+// http://computation.llnl.gov/projects/floating-point-compression
+#endif
+
+#ifndef TINYEXR_USE_OPENMP
+#ifdef _OPENMP
+#define TINYEXR_USE_OPENMP (1)
+#else
+#define TINYEXR_USE_OPENMP (0)
+#endif
+#endif
+
+#define TINYEXR_SUCCESS (0)
+#define TINYEXR_ERROR_INVALID_MAGIC_NUMBER (-1)
+#define TINYEXR_ERROR_INVALID_EXR_VERSION (-2)
+#define TINYEXR_ERROR_INVALID_ARGUMENT (-3)
+#define TINYEXR_ERROR_INVALID_DATA (-4)
+#define TINYEXR_ERROR_INVALID_FILE (-5)
+#define TINYEXR_ERROR_INVALID_PARAMETER (-6)
+#define TINYEXR_ERROR_CANT_OPEN_FILE (-7)
+#define TINYEXR_ERROR_UNSUPPORTED_FORMAT (-8)
+#define TINYEXR_ERROR_INVALID_HEADER (-9)
+#define TINYEXR_ERROR_UNSUPPORTED_FEATURE (-10)
+#define TINYEXR_ERROR_CANT_WRITE_FILE (-11)
+#define TINYEXR_ERROR_SERIALZATION_FAILED (-12)
+#define TINYEXR_ERROR_LAYER_NOT_FOUND (-13)
+
+// @note { OpenEXR file format: http://www.openexr.com/openexrfilelayout.pdf }
+
+// pixel type: possible values are: UINT = 0 HALF = 1 FLOAT = 2
+#define TINYEXR_PIXELTYPE_UINT (0)
+#define TINYEXR_PIXELTYPE_HALF (1)
+#define TINYEXR_PIXELTYPE_FLOAT (2)
+
+#define TINYEXR_MAX_HEADER_ATTRIBUTES (1024)
+#define TINYEXR_MAX_CUSTOM_ATTRIBUTES (128)
+
+#define TINYEXR_COMPRESSIONTYPE_NONE (0)
+#define TINYEXR_COMPRESSIONTYPE_RLE (1)
+#define TINYEXR_COMPRESSIONTYPE_ZIPS (2)
+#define TINYEXR_COMPRESSIONTYPE_ZIP (3)
+#define TINYEXR_COMPRESSIONTYPE_PIZ (4)
+#define TINYEXR_COMPRESSIONTYPE_ZFP (128) // TinyEXR extension
+
+#define TINYEXR_ZFP_COMPRESSIONTYPE_RATE (0)
+#define TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION (1)
+#define TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY (2)
+
+#define TINYEXR_TILE_ONE_LEVEL (0)
+#define TINYEXR_TILE_MIPMAP_LEVELS (1)
+#define TINYEXR_TILE_RIPMAP_LEVELS (2)
+
+#define TINYEXR_TILE_ROUND_DOWN (0)
+#define TINYEXR_TILE_ROUND_UP (1)
+
+typedef struct _EXRVersion {
+ int version; // this must be 2
+ // tile format image;
+ // not zero for only a single-part "normal" tiled file (according to spec.)
+ int tiled;
+ int long_name; // long name attribute
+ // deep image(EXR 2.0);
+ // for a multi-part file, indicates that at least one part is of type deep* (according to spec.)
+ int non_image;
+ int multipart; // multi-part(EXR 2.0)
+} EXRVersion;
+
+typedef struct _EXRAttribute {
+ char name[256]; // name and type are up to 255 chars long.
+ char type[256];
+ unsigned char *value; // uint8_t*
+ int size;
+ int pad0;
+} EXRAttribute;
+
+typedef struct _EXRChannelInfo {
+ char name[256]; // less than 255 bytes long
+ int pixel_type;
+ int x_sampling;
+ int y_sampling;
+ unsigned char p_linear;
+ unsigned char pad[3];
+} EXRChannelInfo;
+
+typedef struct _EXRTile {
+ int offset_x;
+ int offset_y;
+ int level_x;
+ int level_y;
+
+ int width; // actual width in a tile.
+ int height; // actual height int a tile.
+
+ unsigned char **images; // image[channels][pixels]
+} EXRTile;
+
+typedef struct _EXRBox2i {
+ int min_x;
+ int min_y;
+ int max_x;
+ int max_y;
+} EXRBox2i;
+
+typedef struct _EXRHeader {
+ float pixel_aspect_ratio;
+ int line_order;
+ EXRBox2i data_window;
+ EXRBox2i display_window;
+ float screen_window_center[2];
+ float screen_window_width;
+
+ int chunk_count;
+
+ // Properties for tiled format(`tiledesc`).
+ int tiled;
+ int tile_size_x;
+ int tile_size_y;
+ int tile_level_mode;
+ int tile_rounding_mode;
+
+ int long_name;
+ // for a single-part file, agree with the version field bit 11
+ // for a multi-part file, it is consistent with the type of part
+ int non_image;
+ int multipart;
+ unsigned int header_len;
+
+ // Custom attributes(exludes required attributes(e.g. `channels`,
+ // `compression`, etc)
+ int num_custom_attributes;
+ EXRAttribute *custom_attributes; // array of EXRAttribute. size =
+ // `num_custom_attributes`.
+
+ EXRChannelInfo *channels; // [num_channels]
+
+ int *pixel_types; // Loaded pixel type(TINYEXR_PIXELTYPE_*) of `images` for
+ // each channel. This is overwritten with `requested_pixel_types` when
+ // loading.
+ int num_channels;
+
+ int compression_type; // compression type(TINYEXR_COMPRESSIONTYPE_*)
+ int *requested_pixel_types; // Filled initially by
+ // ParseEXRHeaderFrom(Meomory|File), then users
+ // can edit it(only valid for HALF pixel type
+ // channel)
+ // name attribute required for multipart files;
+ // must be unique and non empty (according to spec.);
+ // use EXRSetNameAttr for setting value;
+ // max 255 character allowed - excluding terminating zero
+ char name[256];
+} EXRHeader;
+
+typedef struct _EXRMultiPartHeader {
+ int num_headers;
+ EXRHeader *headers;
+
+} EXRMultiPartHeader;
+
+typedef struct _EXRImage {
+ EXRTile *tiles; // Tiled pixel data. The application must reconstruct image
+ // from tiles manually. NULL if scanline format.
+ struct _EXRImage* next_level; // NULL if scanline format or image is the last level.
+ int level_x; // x level index
+ int level_y; // y level index
+
+ unsigned char **images; // image[channels][pixels]. NULL if tiled format.
+
+ int width;
+ int height;
+ int num_channels;
+
+ // Properties for tile format.
+ int num_tiles;
+
+} EXRImage;
+
+typedef struct _EXRMultiPartImage {
+ int num_images;
+ EXRImage *images;
+
+} EXRMultiPartImage;
+
+typedef struct _DeepImage {
+ const char **channel_names;
+ float ***image; // image[channels][scanlines][samples]
+ int **offset_table; // offset_table[scanline][offsets]
+ int num_channels;
+ int width;
+ int height;
+ int pad0;
+} DeepImage;
+
+// @deprecated { For backward compatibility. Not recommended to use. }
+// Loads single-frame OpenEXR image. Assume EXR image contains A(single channel
+// alpha) or RGB(A) channels.
+// Application must free image data as returned by `out_rgba`
+// Result image format is: float x RGBA x width x hight
+// Returns negative value and may set error string in `err` when there's an
+// error
+extern int LoadEXR(float **out_rgba, int *width, int *height,
+ const char *filename, const char **err);
+
+// Loads single-frame OpenEXR image by specifying layer name. Assume EXR image
+// contains A(single channel alpha) or RGB(A) channels. Application must free
+// image data as returned by `out_rgba` Result image format is: float x RGBA x
+// width x hight Returns negative value and may set error string in `err` when
+// there's an error When the specified layer name is not found in the EXR file,
+// the function will return `TINYEXR_ERROR_LAYER_NOT_FOUND`.
+extern int LoadEXRWithLayer(float **out_rgba, int *width, int *height,
+ const char *filename, const char *layer_name,
+ const char **err);
+
+//
+// Get layer infos from EXR file.
+//
+// @param[out] layer_names List of layer names. Application must free memory
+// after using this.
+// @param[out] num_layers The number of layers
+// @param[out] err Error string(will be filled when the function returns error
+// code). Free it using FreeEXRErrorMessage after using this value.
+//
+// @return TINYEXR_SUCCEES upon success.
+//
+extern int EXRLayers(const char *filename, const char **layer_names[],
+ int *num_layers, const char **err);
+
+// @deprecated { to be removed. }
+// Simple wrapper API for ParseEXRHeaderFromFile.
+// checking given file is a EXR file(by just look up header)
+// @return TINYEXR_SUCCEES for EXR image, TINYEXR_ERROR_INVALID_HEADER for
+// others
+extern int IsEXR(const char *filename);
+
+// @deprecated { to be removed. }
+// Saves single-frame OpenEXR image. Assume EXR image contains RGB(A) channels.
+// components must be 1(Grayscale), 3(RGB) or 4(RGBA).
+// Input image format is: `float x width x height`, or `float x RGB(A) x width x
+// hight`
+// Save image as fp16(HALF) format when `save_as_fp16` is positive non-zero
+// value.
+// Save image as fp32(FLOAT) format when `save_as_fp16` is 0.
+// Use ZIP compression by default.
+// Returns negative value and may set error string in `err` when there's an
+// error
+extern int SaveEXR(const float *data, const int width, const int height,
+ const int components, const int save_as_fp16,
+ const char *filename, const char **err);
+
+// Returns the number of resolution levels of the image (including the base)
+extern int EXRNumLevels(const EXRImage* exr_image);
+
+// Initialize EXRHeader struct
+extern void InitEXRHeader(EXRHeader *exr_header);
+
+// Set name attribute of EXRHeader struct (it makes a copy)
+extern void EXRSetNameAttr(EXRHeader *exr_header, const char* name);
+
+// Initialize EXRImage struct
+extern void InitEXRImage(EXRImage *exr_image);
+
+// Frees internal data of EXRHeader struct
+extern int FreeEXRHeader(EXRHeader *exr_header);
+
+// Frees internal data of EXRImage struct
+extern int FreeEXRImage(EXRImage *exr_image);
+
+// Frees error message
+extern void FreeEXRErrorMessage(const char *msg);
+
+// Parse EXR version header of a file.
+extern int ParseEXRVersionFromFile(EXRVersion *version, const char *filename);
+
+// Parse EXR version header from memory-mapped EXR data.
+extern int ParseEXRVersionFromMemory(EXRVersion *version,
+ const unsigned char *memory, size_t size);
+
+// Parse single-part OpenEXR header from a file and initialize `EXRHeader`.
+// When there was an error message, Application must free `err` with
+// FreeEXRErrorMessage()
+extern int ParseEXRHeaderFromFile(EXRHeader *header, const EXRVersion *version,
+ const char *filename, const char **err);
+
+// Parse single-part OpenEXR header from a memory and initialize `EXRHeader`.
+// When there was an error message, Application must free `err` with
+// FreeEXRErrorMessage()
+extern int ParseEXRHeaderFromMemory(EXRHeader *header,
+ const EXRVersion *version,
+ const unsigned char *memory, size_t size,
+ const char **err);
+
+// Parse multi-part OpenEXR headers from a file and initialize `EXRHeader*`
+// array.
+// When there was an error message, Application must free `err` with
+// FreeEXRErrorMessage()
+extern int ParseEXRMultipartHeaderFromFile(EXRHeader ***headers,
+ int *num_headers,
+ const EXRVersion *version,
+ const char *filename,
+ const char **err);
+
+// Parse multi-part OpenEXR headers from a memory and initialize `EXRHeader*`
+// array
+// When there was an error message, Application must free `err` with
+// FreeEXRErrorMessage()
+extern int ParseEXRMultipartHeaderFromMemory(EXRHeader ***headers,
+ int *num_headers,
+ const EXRVersion *version,
+ const unsigned char *memory,
+ size_t size, const char **err);
+
+// Loads single-part OpenEXR image from a file.
+// Application must setup `ParseEXRHeaderFromFile` before calling this function.
+// Application can free EXRImage using `FreeEXRImage`
+// Returns negative value and may set error string in `err` when there's an
+// error
+// When there was an error message, Application must free `err` with
+// FreeEXRErrorMessage()
+extern int LoadEXRImageFromFile(EXRImage *image, const EXRHeader *header,
+ const char *filename, const char **err);
+
+// Loads single-part OpenEXR image from a memory.
+// Application must setup `EXRHeader` with
+// `ParseEXRHeaderFromMemory` before calling this function.
+// Application can free EXRImage using `FreeEXRImage`
+// Returns negative value and may set error string in `err` when there's an
+// error
+// When there was an error message, Application must free `err` with
+// FreeEXRErrorMessage()
+extern int LoadEXRImageFromMemory(EXRImage *image, const EXRHeader *header,
+ const unsigned char *memory,
+ const size_t size, const char **err);
+
+// Loads multi-part OpenEXR image from a file.
+// Application must setup `ParseEXRMultipartHeaderFromFile` before calling this
+// function.
+// Application can free EXRImage using `FreeEXRImage`
+// Returns negative value and may set error string in `err` when there's an
+// error
+// When there was an error message, Application must free `err` with
+// FreeEXRErrorMessage()
+extern int LoadEXRMultipartImageFromFile(EXRImage *images,
+ const EXRHeader **headers,
+ unsigned int num_parts,
+ const char *filename,
+ const char **err);
+
+// Loads multi-part OpenEXR image from a memory.
+// Application must setup `EXRHeader*` array with
+// `ParseEXRMultipartHeaderFromMemory` before calling this function.
+// Application can free EXRImage using `FreeEXRImage`
+// Returns negative value and may set error string in `err` when there's an
+// error
+// When there was an error message, Application must free `err` with
+// FreeEXRErrorMessage()
+extern int LoadEXRMultipartImageFromMemory(EXRImage *images,
+ const EXRHeader **headers,
+ unsigned int num_parts,
+ const unsigned char *memory,
+ const size_t size, const char **err);
+
+// Saves multi-channel, single-frame OpenEXR image to a file.
+// Returns negative value and may set error string in `err` when there's an
+// error
+// When there was an error message, Application must free `err` with
+// FreeEXRErrorMessage()
+extern int SaveEXRImageToFile(const EXRImage *image,
+ const EXRHeader *exr_header, const char *filename,
+ const char **err);
+
+// Saves multi-channel, single-frame OpenEXR image to a memory.
+// Image is compressed using EXRImage.compression value.
+// Return the number of bytes if success.
+// Return zero and will set error string in `err` when there's an
+// error.
+// When there was an error message, Application must free `err` with
+// FreeEXRErrorMessage()
+extern size_t SaveEXRImageToMemory(const EXRImage *image,
+ const EXRHeader *exr_header,
+ unsigned char **memory, const char **err);
+
+// Saves multi-channel, multi-frame OpenEXR image to a memory.
+// Image is compressed using EXRImage.compression value.
+// File global attributes (eg. display_window) must be set in the first header.
+// Returns negative value and may set error string in `err` when there's an
+// error
+// When there was an error message, Application must free `err` with
+// FreeEXRErrorMessage()
+extern int SaveEXRMultipartImageToFile(const EXRImage *images,
+ const EXRHeader **exr_headers,
+ unsigned int num_parts,
+ const char *filename, const char **err);
+
+// Saves multi-channel, multi-frame OpenEXR image to a memory.
+// Image is compressed using EXRImage.compression value.
+// File global attributes (eg. display_window) must be set in the first header.
+// Return the number of bytes if success.
+// Return zero and will set error string in `err` when there's an
+// error.
+// When there was an error message, Application must free `err` with
+// FreeEXRErrorMessage()
+extern size_t SaveEXRMultipartImageToMemory(const EXRImage *images,
+ const EXRHeader **exr_headers,
+ unsigned int num_parts,
+ unsigned char **memory, const char **err);
+// Loads single-frame OpenEXR deep image.
+// Application must free memory of variables in DeepImage(image, offset_table)
+// Returns negative value and may set error string in `err` when there's an
+// error
+// When there was an error message, Application must free `err` with
+// FreeEXRErrorMessage()
+extern int LoadDeepEXR(DeepImage *out_image, const char *filename,
+ const char **err);
+
+// NOT YET IMPLEMENTED:
+// Saves single-frame OpenEXR deep image.
+// Returns negative value and may set error string in `err` when there's an
+// error
+// extern int SaveDeepEXR(const DeepImage *in_image, const char *filename,
+// const char **err);
+
+// NOT YET IMPLEMENTED:
+// Loads multi-part OpenEXR deep image.
+// Application must free memory of variables in DeepImage(image, offset_table)
+// extern int LoadMultiPartDeepEXR(DeepImage **out_image, int num_parts, const
+// char *filename,
+// const char **err);
+
+// For emscripten.
+// Loads single-frame OpenEXR image from memory. Assume EXR image contains
+// RGB(A) channels.
+// Returns negative value and may set error string in `err` when there's an
+// error
+// When there was an error message, Application must free `err` with
+// FreeEXRErrorMessage()
+extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
+ const unsigned char *memory, size_t size,
+ const char **err);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // TINYEXR_H_
+
+#ifdef TINYEXR_IMPLEMENTATION
+#ifndef TINYEXR_IMPLEMENTATION_DEFINED
+#define TINYEXR_IMPLEMENTATION_DEFINED
+
+#ifdef _WIN32
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#include <windows.h> // for UTF-8
+
+#endif
+
+#include <algorithm>
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <sstream>
+
+// #include <iostream> // debug
+
+#include <limits>
+#include <string>
+#include <vector>
+#include <set>
+
+// https://stackoverflow.com/questions/5047971/how-do-i-check-for-c11-support
+#if __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER >= 1900)
+#define TINYEXR_HAS_CXX11 (1)
+// C++11
+#include <cstdint>
+
+#if TINYEXR_USE_THREAD
+#include <atomic>
+#include <thread>
+#endif
+
+#endif // __cplusplus > 199711L
+
+#if TINYEXR_USE_OPENMP
+#include <omp.h>
+#endif
+
+#if TINYEXR_USE_MINIZ
+#include <miniz.h>
+#else
+// Issue #46. Please include your own zlib-compatible API header before
+// including `tinyexr.h`
+//#include "zlib.h"
+#endif
+
+#if TINYEXR_USE_ZFP
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Weverything"
+#endif
+
+#include "zfp.h"
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#endif
+
+namespace tinyexr {
+
+#if __cplusplus > 199711L
+// C++11
+typedef uint64_t tinyexr_uint64;
+typedef int64_t tinyexr_int64;
+#else
+// Although `long long` is not a standard type pre C++11, assume it is defined
+// as a compiler's extension.
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++11-long-long"
+#endif
+typedef unsigned long long tinyexr_uint64;
+typedef long long tinyexr_int64;
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+#endif
+
+// static bool IsBigEndian(void) {
+// union {
+// unsigned int i;
+// char c[4];
+// } bint = {0x01020304};
+//
+// return bint.c[0] == 1;
+//}
+
+static void SetErrorMessage(const std::string &msg, const char **err) {
+ if (err) {
+#ifdef _WIN32
+ (*err) = _strdup(msg.c_str());
+#else
+ (*err) = strdup(msg.c_str());
+#endif
+ }
+}
+
+static const int kEXRVersionSize = 8;
+
+static void cpy2(unsigned short *dst_val, const unsigned short *src_val) {
+ unsigned char *dst = reinterpret_cast<unsigned char *>(dst_val);
+ const unsigned char *src = reinterpret_cast<const unsigned char *>(src_val);
+
+ dst[0] = src[0];
+ dst[1] = src[1];
+}
+
+static void swap2(unsigned short *val) {
+#ifdef TINYEXR_LITTLE_ENDIAN
+ (void)val;
+#else
+ unsigned short tmp = *val;
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[1];
+ dst[1] = src[0];
+#endif
+}
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-function"
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+static void cpy4(int *dst_val, const int *src_val) {
+ unsigned char *dst = reinterpret_cast<unsigned char *>(dst_val);
+ const unsigned char *src = reinterpret_cast<const unsigned char *>(src_val);
+
+ dst[0] = src[0];
+ dst[1] = src[1];
+ dst[2] = src[2];
+ dst[3] = src[3];
+}
+
+static void cpy4(unsigned int *dst_val, const unsigned int *src_val) {
+ unsigned char *dst = reinterpret_cast<unsigned char *>(dst_val);
+ const unsigned char *src = reinterpret_cast<const unsigned char *>(src_val);
+
+ dst[0] = src[0];
+ dst[1] = src[1];
+ dst[2] = src[2];
+ dst[3] = src[3];
+}
+
+static void cpy4(float *dst_val, const float *src_val) {
+ unsigned char *dst = reinterpret_cast<unsigned char *>(dst_val);
+ const unsigned char *src = reinterpret_cast<const unsigned char *>(src_val);
+
+ dst[0] = src[0];
+ dst[1] = src[1];
+ dst[2] = src[2];
+ dst[3] = src[3];
+}
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
+static void swap4(unsigned int *val) {
+#ifdef TINYEXR_LITTLE_ENDIAN
+ (void)val;
+#else
+ unsigned int tmp = *val;
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[3];
+ dst[1] = src[2];
+ dst[2] = src[1];
+ dst[3] = src[0];
+#endif
+}
+
+static void swap4(int *val) {
+#ifdef TINYEXR_LITTLE_ENDIAN
+ (void)val;
+#else
+ int tmp = *val;
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[3];
+ dst[1] = src[2];
+ dst[2] = src[1];
+ dst[3] = src[0];
+#endif
+}
+
+static void swap4(float *val) {
+#ifdef TINYEXR_LITTLE_ENDIAN
+ (void)val;
+#else
+ float tmp = *val;
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[3];
+ dst[1] = src[2];
+ dst[2] = src[1];
+ dst[3] = src[0];
+#endif
+}
+
+#if 0
+static void cpy8(tinyexr::tinyexr_uint64 *dst_val, const tinyexr::tinyexr_uint64 *src_val) {
+ unsigned char *dst = reinterpret_cast<unsigned char *>(dst_val);
+ const unsigned char *src = reinterpret_cast<const unsigned char *>(src_val);
+
+ dst[0] = src[0];
+ dst[1] = src[1];
+ dst[2] = src[2];
+ dst[3] = src[3];
+ dst[4] = src[4];
+ dst[5] = src[5];
+ dst[6] = src[6];
+ dst[7] = src[7];
+}
+#endif
+
+static void swap8(tinyexr::tinyexr_uint64 *val) {
+#ifdef TINYEXR_LITTLE_ENDIAN
+ (void)val;
+#else
+ tinyexr::tinyexr_uint64 tmp = (*val);
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[7];
+ dst[1] = src[6];
+ dst[2] = src[5];
+ dst[3] = src[4];
+ dst[4] = src[3];
+ dst[5] = src[2];
+ dst[6] = src[1];
+ dst[7] = src[0];
+#endif
+}
+
+// https://gist.github.com/rygorous/2156668
+union FP32 {
+ unsigned int u;
+ float f;
+ struct {
+#if TINYEXR_LITTLE_ENDIAN
+ unsigned int Mantissa : 23;
+ unsigned int Exponent : 8;
+ unsigned int Sign : 1;
+#else
+ unsigned int Sign : 1;
+ unsigned int Exponent : 8;
+ unsigned int Mantissa : 23;
+#endif
+ } s;
+};
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+union FP16 {
+ unsigned short u;
+ struct {
+#if TINYEXR_LITTLE_ENDIAN
+ unsigned int Mantissa : 10;
+ unsigned int Exponent : 5;
+ unsigned int Sign : 1;
+#else
+ unsigned int Sign : 1;
+ unsigned int Exponent : 5;
+ unsigned int Mantissa : 10;
+#endif
+ } s;
+};
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+static FP32 half_to_float(FP16 h) {
+ static const FP32 magic = {113 << 23};
+ static const unsigned int shifted_exp = 0x7c00
+ << 13; // exponent mask after shift
+ FP32 o;
+
+ o.u = (h.u & 0x7fffU) << 13U; // exponent/mantissa bits
+ unsigned int exp_ = shifted_exp & o.u; // just the exponent
+ o.u += (127 - 15) << 23; // exponent adjust
+
+ // handle exponent special cases
+ if (exp_ == shifted_exp) // Inf/NaN?
+ o.u += (128 - 16) << 23; // extra exp adjust
+ else if (exp_ == 0) // Zero/Denormal?
+ {
+ o.u += 1 << 23; // extra exp adjust
+ o.f -= magic.f; // renormalize
+ }
+
+ o.u |= (h.u & 0x8000U) << 16U; // sign bit
+ return o;
+}
+
+static FP16 float_to_half_full(FP32 f) {
+ FP16 o = {0};
+
+ // Based on ISPC reference code (with minor modifications)
+ if (f.s.Exponent == 0) // Signed zero/denormal (which will underflow)
+ o.s.Exponent = 0;
+ else if (f.s.Exponent == 255) // Inf or NaN (all exponent bits set)
+ {
+ o.s.Exponent = 31;
+ o.s.Mantissa = f.s.Mantissa ? 0x200 : 0; // NaN->qNaN and Inf->Inf
+ } else // Normalized number
+ {
+ // Exponent unbias the single, then bias the halfp
+ int newexp = f.s.Exponent - 127 + 15;
+ if (newexp >= 31) // Overflow, return signed infinity
+ o.s.Exponent = 31;
+ else if (newexp <= 0) // Underflow
+ {
+ if ((14 - newexp) <= 24) // Mantissa might be non-zero
+ {
+ unsigned int mant = f.s.Mantissa | 0x800000; // Hidden 1 bit
+ o.s.Mantissa = mant >> (14 - newexp);
+ if ((mant >> (13 - newexp)) & 1) // Check for rounding
+ o.u++; // Round, might overflow into exp bit, but this is OK
+ }
+ } else {
+ o.s.Exponent = static_cast<unsigned int>(newexp);
+ o.s.Mantissa = f.s.Mantissa >> 13;
+ if (f.s.Mantissa & 0x1000) // Check for rounding
+ o.u++; // Round, might overflow to inf, this is OK
+ }
+ }
+
+ o.s.Sign = f.s.Sign;
+ return o;
+}
+
+// NOTE: From OpenEXR code
+// #define IMF_INCREASING_Y 0
+// #define IMF_DECREASING_Y 1
+// #define IMF_RAMDOM_Y 2
+//
+// #define IMF_NO_COMPRESSION 0
+// #define IMF_RLE_COMPRESSION 1
+// #define IMF_ZIPS_COMPRESSION 2
+// #define IMF_ZIP_COMPRESSION 3
+// #define IMF_PIZ_COMPRESSION 4
+// #define IMF_PXR24_COMPRESSION 5
+// #define IMF_B44_COMPRESSION 6
+// #define IMF_B44A_COMPRESSION 7
+
+#ifdef __clang__
+#pragma clang diagnostic push
+
+#if __has_warning("-Wzero-as-null-pointer-constant")
+#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
+#endif
+
+#endif
+
+static const char *ReadString(std::string *s, const char *ptr, size_t len) {
+ // Read untile NULL(\0).
+ const char *p = ptr;
+ const char *q = ptr;
+ while ((size_t(q - ptr) < len) && (*q) != 0) {
+ q++;
+ }
+
+ if (size_t(q - ptr) >= len) {
+ (*s).clear();
+ return NULL;
+ }
+
+ (*s) = std::string(p, q);
+
+ return q + 1; // skip '\0'
+}
+
+static bool ReadAttribute(std::string *name, std::string *type,
+ std::vector<unsigned char> *data, size_t *marker_size,
+ const char *marker, size_t size) {
+ size_t name_len = strnlen(marker, size);
+ if (name_len == size) {
+ // String does not have a terminating character.
+ return false;
+ }
+ *name = std::string(marker, name_len);
+
+ marker += name_len + 1;
+ size -= name_len + 1;
+
+ size_t type_len = strnlen(marker, size);
+ if (type_len == size) {
+ return false;
+ }
+ *type = std::string(marker, type_len);
+
+ marker += type_len + 1;
+ size -= type_len + 1;
+
+ if (size < sizeof(uint32_t)) {
+ return false;
+ }
+
+ uint32_t data_len;
+ memcpy(&data_len, marker, sizeof(uint32_t));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
+
+ if (data_len == 0) {
+ if ((*type).compare("string") == 0) {
+ // Accept empty string attribute.
+
+ marker += sizeof(uint32_t);
+ size -= sizeof(uint32_t);
+
+ *marker_size = name_len + 1 + type_len + 1 + sizeof(uint32_t);
+
+ data->resize(1);
+ (*data)[0] = '\0';
+
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ marker += sizeof(uint32_t);
+ size -= sizeof(uint32_t);
+
+ if (size < data_len) {
+ return false;
+ }
+
+ data->resize(static_cast<size_t>(data_len));
+ memcpy(&data->at(0), marker, static_cast<size_t>(data_len));
+
+ *marker_size = name_len + 1 + type_len + 1 + sizeof(uint32_t) + data_len;
+ return true;
+}
+
+static void WriteAttributeToMemory(std::vector<unsigned char> *out,
+ const char *name, const char *type,
+ const unsigned char *data, int len) {
+ out->insert(out->end(), name, name + strlen(name) + 1);
+ out->insert(out->end(), type, type + strlen(type) + 1);
+
+ int outLen = len;
+ tinyexr::swap4(&outLen);
+ out->insert(out->end(), reinterpret_cast<unsigned char *>(&outLen),
+ reinterpret_cast<unsigned char *>(&outLen) + sizeof(int));
+ out->insert(out->end(), data, data + len);
+}
+
+typedef struct {
+ std::string name; // less than 255 bytes long
+ int pixel_type;
+ int requested_pixel_type;
+ int x_sampling;
+ int y_sampling;
+ unsigned char p_linear;
+ unsigned char pad[3];
+} ChannelInfo;
+
+typedef struct {
+ int min_x;
+ int min_y;
+ int max_x;
+ int max_y;
+} Box2iInfo;
+
+struct HeaderInfo {
+ std::vector<tinyexr::ChannelInfo> channels;
+ std::vector<EXRAttribute> attributes;
+
+ Box2iInfo data_window;
+ int line_order;
+ Box2iInfo display_window;
+ float screen_window_center[2];
+ float screen_window_width;
+ float pixel_aspect_ratio;
+
+ int chunk_count;
+
+ // Tiled format
+ int tiled; // Non-zero if the part is tiled.
+ int tile_size_x;
+ int tile_size_y;
+ int tile_level_mode;
+ int tile_rounding_mode;
+
+ unsigned int header_len;
+
+ int compression_type;
+
+ // required for multi-part or non-image files
+ std::string name;
+ // required for multi-part or non-image files
+ std::string type;
+
+ void clear() {
+ channels.clear();
+ attributes.clear();
+
+ data_window.min_x = 0;
+ data_window.min_y = 0;
+ data_window.max_x = 0;
+ data_window.max_y = 0;
+ line_order = 0;
+ display_window.min_x = 0;
+ display_window.min_y = 0;
+ display_window.max_x = 0;
+ display_window.max_y = 0;
+ screen_window_center[0] = 0.0f;
+ screen_window_center[1] = 0.0f;
+ screen_window_width = 0.0f;
+ pixel_aspect_ratio = 0.0f;
+
+ chunk_count = 0;
+
+ // Tiled format
+ tiled = 0;
+ tile_size_x = 0;
+ tile_size_y = 0;
+ tile_level_mode = 0;
+ tile_rounding_mode = 0;
+
+ header_len = 0;
+ compression_type = 0;
+
+ name.clear();
+ type.clear();
+ }
+};
+
+static bool ReadChannelInfo(std::vector<ChannelInfo> &channels,
+ const std::vector<unsigned char> &data) {
+ const char *p = reinterpret_cast<const char *>(&data.at(0));
+
+ for (;;) {
+ if ((*p) == 0) {
+ break;
+ }
+ ChannelInfo info;
+
+ tinyexr_int64 data_len = static_cast<tinyexr_int64>(data.size()) -
+ (p - reinterpret_cast<const char *>(data.data()));
+ if (data_len < 0) {
+ return false;
+ }
+
+ p = ReadString(&info.name, p, size_t(data_len));
+ if ((p == NULL) && (info.name.empty())) {
+ // Buffer overrun. Issue #51.
+ return false;
+ }
+
+ const unsigned char *data_end =
+ reinterpret_cast<const unsigned char *>(p) + 16;
+ if (data_end >= (data.data() + data.size())) {
+ return false;
+ }
+
+ memcpy(&info.pixel_type, p, sizeof(int));
+ p += 4;
+ info.p_linear = static_cast<unsigned char>(p[0]); // uchar
+ p += 1 + 3; // reserved: uchar[3]
+ memcpy(&info.x_sampling, p, sizeof(int)); // int
+ p += 4;
+ memcpy(&info.y_sampling, p, sizeof(int)); // int
+ p += 4;
+
+ tinyexr::swap4(&info.pixel_type);
+ tinyexr::swap4(&info.x_sampling);
+ tinyexr::swap4(&info.y_sampling);
+
+ channels.push_back(info);
+ }
+
+ return true;
+}
+
+static void WriteChannelInfo(std::vector<unsigned char> &data,
+ const std::vector<ChannelInfo> &channels) {
+ size_t sz = 0;
+
+ // Calculate total size.
+ for (size_t c = 0; c < channels.size(); c++) {
+ sz += channels[c].name.length() + 1; // +1 for \0
+ sz += 16; // 4 * int
+ }
+ data.resize(sz + 1);
+
+ unsigned char *p = &data.at(0);
+
+ for (size_t c = 0; c < channels.size(); c++) {
+ memcpy(p, channels[c].name.c_str(), channels[c].name.length());
+ p += channels[c].name.length();
+ (*p) = '\0';
+ p++;
+
+ int pixel_type = channels[c].requested_pixel_type;
+ int x_sampling = channels[c].x_sampling;
+ int y_sampling = channels[c].y_sampling;
+ tinyexr::swap4(&pixel_type);
+ tinyexr::swap4(&x_sampling);
+ tinyexr::swap4(&y_sampling);
+
+ memcpy(p, &pixel_type, sizeof(int));
+ p += sizeof(int);
+
+ (*p) = channels[c].p_linear;
+ p += 4;
+
+ memcpy(p, &x_sampling, sizeof(int));
+ p += sizeof(int);
+
+ memcpy(p, &y_sampling, sizeof(int));
+ p += sizeof(int);
+ }
+
+ (*p) = '\0';
+}
+
+static void CompressZip(unsigned char *dst,
+ tinyexr::tinyexr_uint64 &compressedSize,
+ const unsigned char *src, unsigned long src_size) {
+ std::vector<unsigned char> tmpBuf(src_size);
+
+ //
+ // Apply EXR-specific? postprocess. Grabbed from OpenEXR's
+ // ImfZipCompressor.cpp
+ //
+
+ //
+ // Reorder the pixel data.
+ //
+
+ const char *srcPtr = reinterpret_cast<const char *>(src);
+
+ {
+ char *t1 = reinterpret_cast<char *>(&tmpBuf.at(0));
+ char *t2 = reinterpret_cast<char *>(&tmpBuf.at(0)) + (src_size + 1) / 2;
+ const char *stop = srcPtr + src_size;
+
+ for (;;) {
+ if (srcPtr < stop)
+ *(t1++) = *(srcPtr++);
+ else
+ break;
+
+ if (srcPtr < stop)
+ *(t2++) = *(srcPtr++);
+ else
+ break;
+ }
+ }
+
+ //
+ // Predictor.
+ //
+
+ {
+ unsigned char *t = &tmpBuf.at(0) + 1;
+ unsigned char *stop = &tmpBuf.at(0) + src_size;
+ int p = t[-1];
+
+ while (t < stop) {
+ int d = int(t[0]) - p + (128 + 256);
+ p = t[0];
+ t[0] = static_cast<unsigned char>(d);
+ ++t;
+ }
+ }
+
+#if TINYEXR_USE_MINIZ
+ //
+ // Compress the data using miniz
+ //
+
+ mz_ulong outSize = mz_compressBound(src_size);
+ int ret = mz_compress(
+ dst, &outSize, static_cast<const unsigned char *>(&tmpBuf.at(0)),
+ src_size);
+ assert(ret == MZ_OK);
+ (void)ret;
+
+ compressedSize = outSize;
+#else
+ uLong outSize = compressBound(static_cast<uLong>(src_size));
+ int ret = compress(dst, &outSize, static_cast<const Bytef *>(&tmpBuf.at(0)),
+ src_size);
+ assert(ret == Z_OK);
+
+ compressedSize = outSize;
+#endif
+
+ // Use uncompressed data when compressed data is larger than uncompressed.
+ // (Issue 40)
+ if (compressedSize >= src_size) {
+ compressedSize = src_size;
+ memcpy(dst, src, src_size);
+ }
+}
+
+static bool DecompressZip(unsigned char *dst,
+ unsigned long *uncompressed_size /* inout */,
+ const unsigned char *src, unsigned long src_size) {
+ if ((*uncompressed_size) == src_size) {
+ // Data is not compressed(Issue 40).
+ memcpy(dst, src, src_size);
+ return true;
+ }
+ std::vector<unsigned char> tmpBuf(*uncompressed_size);
+
+#if TINYEXR_USE_MINIZ
+ int ret =
+ mz_uncompress(&tmpBuf.at(0), uncompressed_size, src, src_size);
+ if (MZ_OK != ret) {
+ return false;
+ }
+#else
+ int ret = uncompress(&tmpBuf.at(0), uncompressed_size, src, src_size);
+ if (Z_OK != ret) {
+ return false;
+ }
+#endif
+
+ //
+ // Apply EXR-specific? postprocess. Grabbed from OpenEXR's
+ // ImfZipCompressor.cpp
+ //
+
+ // Predictor.
+ {
+ unsigned char *t = &tmpBuf.at(0) + 1;
+ unsigned char *stop = &tmpBuf.at(0) + (*uncompressed_size);
+
+ while (t < stop) {
+ int d = int(t[-1]) + int(t[0]) - 128;
+ t[0] = static_cast<unsigned char>(d);
+ ++t;
+ }
+ }
+
+ // Reorder the pixel data.
+ {
+ const char *t1 = reinterpret_cast<const char *>(&tmpBuf.at(0));
+ const char *t2 = reinterpret_cast<const char *>(&tmpBuf.at(0)) +
+ (*uncompressed_size + 1) / 2;
+ char *s = reinterpret_cast<char *>(dst);
+ char *stop = s + (*uncompressed_size);
+
+ for (;;) {
+ if (s < stop)
+ *(s++) = *(t1++);
+ else
+ break;
+
+ if (s < stop)
+ *(s++) = *(t2++);
+ else
+ break;
+ }
+ }
+
+ return true;
+}
+
+// RLE code from OpenEXR --------------------------------------
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wsign-conversion"
+#if __has_warning("-Wextra-semi-stmt")
+#pragma clang diagnostic ignored "-Wextra-semi-stmt"
+#endif
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4204) // nonstandard extension used : non-constant
+ // aggregate initializer (also supported by GNU
+ // C and C99, so no big deal)
+#pragma warning(disable : 4244) // 'initializing': conversion from '__int64' to
+ // 'int', possible loss of data
+#pragma warning(disable : 4267) // 'argument': conversion from '__int64' to
+ // 'int', possible loss of data
+#pragma warning(disable : 4996) // 'strdup': The POSIX name for this item is
+ // deprecated. Instead, use the ISO C and C++
+ // conformant name: _strdup.
+#endif
+
+const int MIN_RUN_LENGTH = 3;
+const int MAX_RUN_LENGTH = 127;
+
+//
+// Compress an array of bytes, using run-length encoding,
+// and return the length of the compressed data.
+//
+
+static int rleCompress(int inLength, const char in[], signed char out[]) {
+ const char *inEnd = in + inLength;
+ const char *runStart = in;
+ const char *runEnd = in + 1;
+ signed char *outWrite = out;
+
+ while (runStart < inEnd) {
+ while (runEnd < inEnd && *runStart == *runEnd &&
+ runEnd - runStart - 1 < MAX_RUN_LENGTH) {
+ ++runEnd;
+ }
+
+ if (runEnd - runStart >= MIN_RUN_LENGTH) {
+ //
+ // Compressible run
+ //
+
+ *outWrite++ = static_cast<char>(runEnd - runStart) - 1;
+ *outWrite++ = *(reinterpret_cast<const signed char *>(runStart));
+ runStart = runEnd;
+ } else {
+ //
+ // Uncompressable run
+ //
+
+ while (runEnd < inEnd &&
+ ((runEnd + 1 >= inEnd || *runEnd != *(runEnd + 1)) ||
+ (runEnd + 2 >= inEnd || *(runEnd + 1) != *(runEnd + 2))) &&
+ runEnd - runStart < MAX_RUN_LENGTH) {
+ ++runEnd;
+ }
+
+ *outWrite++ = static_cast<char>(runStart - runEnd);
+
+ while (runStart < runEnd) {
+ *outWrite++ = *(reinterpret_cast<const signed char *>(runStart++));
+ }
+ }
+
+ ++runEnd;
+ }
+
+ return static_cast<int>(outWrite - out);
+}
+
+//
+// Uncompress an array of bytes compressed with rleCompress().
+// Returns the length of the oncompressed data, or 0 if the
+// length of the uncompressed data would be more than maxLength.
+//
+
+static int rleUncompress(int inLength, int maxLength, const signed char in[],
+ char out[]) {
+ char *outStart = out;
+
+ while (inLength > 0) {
+ if (*in < 0) {
+ int count = -(static_cast<int>(*in++));
+ inLength -= count + 1;
+
+ // Fixes #116: Add bounds check to in buffer.
+ if ((0 > (maxLength -= count)) || (inLength < 0)) return 0;
+
+ memcpy(out, in, count);
+ out += count;
+ in += count;
+ } else {
+ int count = *in++;
+ inLength -= 2;
+
+ if (0 > (maxLength -= count + 1)) return 0;
+
+ memset(out, *reinterpret_cast<const char *>(in), count + 1);
+ out += count + 1;
+
+ in++;
+ }
+ }
+
+ return static_cast<int>(out - outStart);
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// End of RLE code from OpenEXR -----------------------------------
+
+static void CompressRle(unsigned char *dst,
+ tinyexr::tinyexr_uint64 &compressedSize,
+ const unsigned char *src, unsigned long src_size) {
+ std::vector<unsigned char> tmpBuf(src_size);
+
+ //
+ // Apply EXR-specific? postprocess. Grabbed from OpenEXR's
+ // ImfRleCompressor.cpp
+ //
+
+ //
+ // Reorder the pixel data.
+ //
+
+ const char *srcPtr = reinterpret_cast<const char *>(src);
+
+ {
+ char *t1 = reinterpret_cast<char *>(&tmpBuf.at(0));
+ char *t2 = reinterpret_cast<char *>(&tmpBuf.at(0)) + (src_size + 1) / 2;
+ const char *stop = srcPtr + src_size;
+
+ for (;;) {
+ if (srcPtr < stop)
+ *(t1++) = *(srcPtr++);
+ else
+ break;
+
+ if (srcPtr < stop)
+ *(t2++) = *(srcPtr++);
+ else
+ break;
+ }
+ }
+
+ //
+ // Predictor.
+ //
+
+ {
+ unsigned char *t = &tmpBuf.at(0) + 1;
+ unsigned char *stop = &tmpBuf.at(0) + src_size;
+ int p = t[-1];
+
+ while (t < stop) {
+ int d = int(t[0]) - p + (128 + 256);
+ p = t[0];
+ t[0] = static_cast<unsigned char>(d);
+ ++t;
+ }
+ }
+
+ // outSize will be (srcSiz * 3) / 2 at max.
+ int outSize = rleCompress(static_cast<int>(src_size),
+ reinterpret_cast<const char *>(&tmpBuf.at(0)),
+ reinterpret_cast<signed char *>(dst));
+ assert(outSize > 0);
+
+ compressedSize = static_cast<tinyexr::tinyexr_uint64>(outSize);
+
+ // Use uncompressed data when compressed data is larger than uncompressed.
+ // (Issue 40)
+ if (compressedSize >= src_size) {
+ compressedSize = src_size;
+ memcpy(dst, src, src_size);
+ }
+}
+
+static bool DecompressRle(unsigned char *dst,
+ const unsigned long uncompressed_size,
+ const unsigned char *src, unsigned long src_size) {
+ if (uncompressed_size == src_size) {
+ // Data is not compressed(Issue 40).
+ memcpy(dst, src, src_size);
+ return true;
+ }
+
+ // Workaround for issue #112.
+ // TODO(syoyo): Add more robust out-of-bounds check in `rleUncompress`.
+ if (src_size <= 2) {
+ return false;
+ }
+
+ std::vector<unsigned char> tmpBuf(uncompressed_size);
+
+ int ret = rleUncompress(static_cast<int>(src_size),
+ static_cast<int>(uncompressed_size),
+ reinterpret_cast<const signed char *>(src),
+ reinterpret_cast<char *>(&tmpBuf.at(0)));
+ if (ret != static_cast<int>(uncompressed_size)) {
+ return false;
+ }
+
+ //
+ // Apply EXR-specific? postprocess. Grabbed from OpenEXR's
+ // ImfRleCompressor.cpp
+ //
+
+ // Predictor.
+ {
+ unsigned char *t = &tmpBuf.at(0) + 1;
+ unsigned char *stop = &tmpBuf.at(0) + uncompressed_size;
+
+ while (t < stop) {
+ int d = int(t[-1]) + int(t[0]) - 128;
+ t[0] = static_cast<unsigned char>(d);
+ ++t;
+ }
+ }
+
+ // Reorder the pixel data.
+ {
+ const char *t1 = reinterpret_cast<const char *>(&tmpBuf.at(0));
+ const char *t2 = reinterpret_cast<const char *>(&tmpBuf.at(0)) +
+ (uncompressed_size + 1) / 2;
+ char *s = reinterpret_cast<char *>(dst);
+ char *stop = s + uncompressed_size;
+
+ for (;;) {
+ if (s < stop)
+ *(s++) = *(t1++);
+ else
+ break;
+
+ if (s < stop)
+ *(s++) = *(t2++);
+ else
+ break;
+ }
+ }
+
+ return true;
+}
+
+#if TINYEXR_USE_PIZ
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++11-long-long"
+#pragma clang diagnostic ignored "-Wold-style-cast"
+#pragma clang diagnostic ignored "-Wpadded"
+#pragma clang diagnostic ignored "-Wsign-conversion"
+#pragma clang diagnostic ignored "-Wc++11-extensions"
+#pragma clang diagnostic ignored "-Wconversion"
+#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+
+#if __has_warning("-Wcast-qual")
+#pragma clang diagnostic ignored "-Wcast-qual"
+#endif
+
+#if __has_warning("-Wextra-semi-stmt")
+#pragma clang diagnostic ignored "-Wextra-semi-stmt"
+#endif
+
+#endif
+
+//
+// PIZ compress/uncompress, based on OpenEXR's ImfPizCompressor.cpp
+//
+// -----------------------------------------------------------------
+// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC)
+// (3 clause BSD license)
+//
+
+struct PIZChannelData {
+ unsigned short *start;
+ unsigned short *end;
+ int nx;
+ int ny;
+ int ys;
+ int size;
+};
+
+//-----------------------------------------------------------------------------
+//
+// 16-bit Haar Wavelet encoding and decoding
+//
+// The source code in this file is derived from the encoding
+// and decoding routines written by Christian Rouet for his
+// PIZ image file format.
+//
+//-----------------------------------------------------------------------------
+
+//
+// Wavelet basis functions without modulo arithmetic; they produce
+// the best compression ratios when the wavelet-transformed data are
+// Huffman-encoded, but the wavelet transform works only for 14-bit
+// data (untransformed data values must be less than (1 << 14)).
+//
+
+inline void wenc14(unsigned short a, unsigned short b, unsigned short &l,
+ unsigned short &h) {
+ short as = static_cast<short>(a);
+ short bs = static_cast<short>(b);
+
+ short ms = (as + bs) >> 1;
+ short ds = as - bs;
+
+ l = static_cast<unsigned short>(ms);
+ h = static_cast<unsigned short>(ds);
+}
+
+inline void wdec14(unsigned short l, unsigned short h, unsigned short &a,
+ unsigned short &b) {
+ short ls = static_cast<short>(l);
+ short hs = static_cast<short>(h);
+
+ int hi = hs;
+ int ai = ls + (hi & 1) + (hi >> 1);
+
+ short as = static_cast<short>(ai);
+ short bs = static_cast<short>(ai - hi);
+
+ a = static_cast<unsigned short>(as);
+ b = static_cast<unsigned short>(bs);
+}
+
+//
+// Wavelet basis functions with modulo arithmetic; they work with full
+// 16-bit data, but Huffman-encoding the wavelet-transformed data doesn't
+// compress the data quite as well.
+//
+
+const int NBITS = 16;
+const int A_OFFSET = 1 << (NBITS - 1);
+const int M_OFFSET = 1 << (NBITS - 1);
+const int MOD_MASK = (1 << NBITS) - 1;
+
+inline void wenc16(unsigned short a, unsigned short b, unsigned short &l,
+ unsigned short &h) {
+ int ao = (a + A_OFFSET) & MOD_MASK;
+ int m = ((ao + b) >> 1);
+ int d = ao - b;
+
+ if (d < 0) m = (m + M_OFFSET) & MOD_MASK;
+
+ d &= MOD_MASK;
+
+ l = static_cast<unsigned short>(m);
+ h = static_cast<unsigned short>(d);
+}
+
+inline void wdec16(unsigned short l, unsigned short h, unsigned short &a,
+ unsigned short &b) {
+ int m = l;
+ int d = h;
+ int bb = (m - (d >> 1)) & MOD_MASK;
+ int aa = (d + bb - A_OFFSET) & MOD_MASK;
+ b = static_cast<unsigned short>(bb);
+ a = static_cast<unsigned short>(aa);
+}
+
+//
+// 2D Wavelet encoding:
+//
+
+static void wav2Encode(
+ unsigned short *in, // io: values are transformed in place
+ int nx, // i : x size
+ int ox, // i : x offset
+ int ny, // i : y size
+ int oy, // i : y offset
+ unsigned short mx) // i : maximum in[x][y] value
+{
+ bool w14 = (mx < (1 << 14));
+ int n = (nx > ny) ? ny : nx;
+ int p = 1; // == 1 << level
+ int p2 = 2; // == 1 << (level+1)
+
+ //
+ // Hierarchical loop on smaller dimension n
+ //
+
+ while (p2 <= n) {
+ unsigned short *py = in;
+ unsigned short *ey = in + oy * (ny - p2);
+ int oy1 = oy * p;
+ int oy2 = oy * p2;
+ int ox1 = ox * p;
+ int ox2 = ox * p2;
+ unsigned short i00, i01, i10, i11;
+
+ //
+ // Y loop
+ //
+
+ for (; py <= ey; py += oy2) {
+ unsigned short *px = py;
+ unsigned short *ex = py + ox * (nx - p2);
+
+ //
+ // X loop
+ //
+
+ for (; px <= ex; px += ox2) {
+ unsigned short *p01 = px + ox1;
+ unsigned short *p10 = px + oy1;
+ unsigned short *p11 = p10 + ox1;
+
+ //
+ // 2D wavelet encoding
+ //
+
+ if (w14) {
+ wenc14(*px, *p01, i00, i01);
+ wenc14(*p10, *p11, i10, i11);
+ wenc14(i00, i10, *px, *p10);
+ wenc14(i01, i11, *p01, *p11);
+ } else {
+ wenc16(*px, *p01, i00, i01);
+ wenc16(*p10, *p11, i10, i11);
+ wenc16(i00, i10, *px, *p10);
+ wenc16(i01, i11, *p01, *p11);
+ }
+ }
+
+ //
+ // Encode (1D) odd column (still in Y loop)
+ //
+
+ if (nx & p) {
+ unsigned short *p10 = px + oy1;
+
+ if (w14)
+ wenc14(*px, *p10, i00, *p10);
+ else
+ wenc16(*px, *p10, i00, *p10);
+
+ *px = i00;
+ }
+ }
+
+ //
+ // Encode (1D) odd line (must loop in X)
+ //
+
+ if (ny & p) {
+ unsigned short *px = py;
+ unsigned short *ex = py + ox * (nx - p2);
+
+ for (; px <= ex; px += ox2) {
+ unsigned short *p01 = px + ox1;
+
+ if (w14)
+ wenc14(*px, *p01, i00, *p01);
+ else
+ wenc16(*px, *p01, i00, *p01);
+
+ *px = i00;
+ }
+ }
+
+ //
+ // Next level
+ //
+
+ p = p2;
+ p2 <<= 1;
+ }
+}
+
+//
+// 2D Wavelet decoding:
+//
+
+static void wav2Decode(
+ unsigned short *in, // io: values are transformed in place
+ int nx, // i : x size
+ int ox, // i : x offset
+ int ny, // i : y size
+ int oy, // i : y offset
+ unsigned short mx) // i : maximum in[x][y] value
+{
+ bool w14 = (mx < (1 << 14));
+ int n = (nx > ny) ? ny : nx;
+ int p = 1;
+ int p2;
+
+ //
+ // Search max level
+ //
+
+ while (p <= n) p <<= 1;
+
+ p >>= 1;
+ p2 = p;
+ p >>= 1;
+
+ //
+ // Hierarchical loop on smaller dimension n
+ //
+
+ while (p >= 1) {
+ unsigned short *py = in;
+ unsigned short *ey = in + oy * (ny - p2);
+ int oy1 = oy * p;
+ int oy2 = oy * p2;
+ int ox1 = ox * p;
+ int ox2 = ox * p2;
+ unsigned short i00, i01, i10, i11;
+
+ //
+ // Y loop
+ //
+
+ for (; py <= ey; py += oy2) {
+ unsigned short *px = py;
+ unsigned short *ex = py + ox * (nx - p2);
+
+ //
+ // X loop
+ //
+
+ for (; px <= ex; px += ox2) {
+ unsigned short *p01 = px + ox1;
+ unsigned short *p10 = px + oy1;
+ unsigned short *p11 = p10 + ox1;
+
+ //
+ // 2D wavelet decoding
+ //
+
+ if (w14) {
+ wdec14(*px, *p10, i00, i10);
+ wdec14(*p01, *p11, i01, i11);
+ wdec14(i00, i01, *px, *p01);
+ wdec14(i10, i11, *p10, *p11);
+ } else {
+ wdec16(*px, *p10, i00, i10);
+ wdec16(*p01, *p11, i01, i11);
+ wdec16(i00, i01, *px, *p01);
+ wdec16(i10, i11, *p10, *p11);
+ }
+ }
+
+ //
+ // Decode (1D) odd column (still in Y loop)
+ //
+
+ if (nx & p) {
+ unsigned short *p10 = px + oy1;
+
+ if (w14)
+ wdec14(*px, *p10, i00, *p10);
+ else
+ wdec16(*px, *p10, i00, *p10);
+
+ *px = i00;
+ }
+ }
+
+ //
+ // Decode (1D) odd line (must loop in X)
+ //
+
+ if (ny & p) {
+ unsigned short *px = py;
+ unsigned short *ex = py + ox * (nx - p2);
+
+ for (; px <= ex; px += ox2) {
+ unsigned short *p01 = px + ox1;
+
+ if (w14)
+ wdec14(*px, *p01, i00, *p01);
+ else
+ wdec16(*px, *p01, i00, *p01);
+
+ *px = i00;
+ }
+ }
+
+ //
+ // Next level
+ //
+
+ p2 = p;
+ p >>= 1;
+ }
+}
+
+//-----------------------------------------------------------------------------
+//
+// 16-bit Huffman compression and decompression.
+//
+// The source code in this file is derived from the 8-bit
+// Huffman compression and decompression routines written
+// by Christian Rouet for his PIZ image file format.
+//
+//-----------------------------------------------------------------------------
+
+// Adds some modification for tinyexr.
+
+const int HUF_ENCBITS = 16; // literal (value) bit length
+const int HUF_DECBITS = 14; // decoding bit size (>= 8)
+
+const int HUF_ENCSIZE = (1 << HUF_ENCBITS) + 1; // encoding table size
+const int HUF_DECSIZE = 1 << HUF_DECBITS; // decoding table size
+const int HUF_DECMASK = HUF_DECSIZE - 1;
+
+struct HufDec { // short code long code
+ //-------------------------------
+ unsigned int len : 8; // code length 0
+ unsigned int lit : 24; // lit p size
+ unsigned int *p; // 0 lits
+};
+
+inline long long hufLength(long long code) { return code & 63; }
+
+inline long long hufCode(long long code) { return code >> 6; }
+
+inline void outputBits(int nBits, long long bits, long long &c, int &lc,
+ char *&out) {
+ c <<= nBits;
+ lc += nBits;
+
+ c |= bits;
+
+ while (lc >= 8) *out++ = static_cast<char>((c >> (lc -= 8)));
+}
+
+inline long long getBits(int nBits, long long &c, int &lc, const char *&in) {
+ while (lc < nBits) {
+ c = (c << 8) | *(reinterpret_cast<const unsigned char *>(in++));
+ lc += 8;
+ }
+
+ lc -= nBits;
+ return (c >> lc) & ((1 << nBits) - 1);
+}
+
+//
+// ENCODING TABLE BUILDING & (UN)PACKING
+//
+
+//
+// Build a "canonical" Huffman code table:
+// - for each (uncompressed) symbol, hcode contains the length
+// of the corresponding code (in the compressed data)
+// - canonical codes are computed and stored in hcode
+// - the rules for constructing canonical codes are as follows:
+// * shorter codes (if filled with zeroes to the right)
+// have a numerically higher value than longer codes
+// * for codes with the same length, numerical values
+// increase with numerical symbol values
+// - because the canonical code table can be constructed from
+// symbol lengths alone, the code table can be transmitted
+// without sending the actual code values
+// - see http://www.compressconsult.com/huffman/
+//
+
+static void hufCanonicalCodeTable(long long hcode[HUF_ENCSIZE]) {
+ long long n[59];
+
+ //
+ // For each i from 0 through 58, count the
+ // number of different codes of length i, and
+ // store the count in n[i].
+ //
+
+ for (int i = 0; i <= 58; ++i) n[i] = 0;
+
+ for (int i = 0; i < HUF_ENCSIZE; ++i) n[hcode[i]] += 1;
+
+ //
+ // For each i from 58 through 1, compute the
+ // numerically lowest code with length i, and
+ // store that code in n[i].
+ //
+
+ long long c = 0;
+
+ for (int i = 58; i > 0; --i) {
+ long long nc = ((c + n[i]) >> 1);
+ n[i] = c;
+ c = nc;
+ }
+
+ //
+ // hcode[i] contains the length, l, of the
+ // code for symbol i. Assign the next available
+ // code of length l to the symbol and store both
+ // l and the code in hcode[i].
+ //
+
+ for (int i = 0; i < HUF_ENCSIZE; ++i) {
+ int l = static_cast<int>(hcode[i]);
+
+ if (l > 0) hcode[i] = l | (n[l]++ << 6);
+ }
+}
+
+//
+// Compute Huffman codes (based on frq input) and store them in frq:
+// - code structure is : [63:lsb - 6:msb] | [5-0: bit length];
+// - max code length is 58 bits;
+// - codes outside the range [im-iM] have a null length (unused values);
+// - original frequencies are destroyed;
+// - encoding tables are used by hufEncode() and hufBuildDecTable();
+//
+
+struct FHeapCompare {
+ bool operator()(long long *a, long long *b) { return *a > *b; }
+};
+
+static void hufBuildEncTable(
+ long long *frq, // io: input frequencies [HUF_ENCSIZE], output table
+ int *im, // o: min frq index
+ int *iM) // o: max frq index
+{
+ //
+ // This function assumes that when it is called, array frq
+ // indicates the frequency of all possible symbols in the data
+ // that are to be Huffman-encoded. (frq[i] contains the number
+ // of occurrences of symbol i in the data.)
+ //
+ // The loop below does three things:
+ //
+ // 1) Finds the minimum and maximum indices that point
+ // to non-zero entries in frq:
+ //
+ // frq[im] != 0, and frq[i] == 0 for all i < im
+ // frq[iM] != 0, and frq[i] == 0 for all i > iM
+ //
+ // 2) Fills array fHeap with pointers to all non-zero
+ // entries in frq.
+ //
+ // 3) Initializes array hlink such that hlink[i] == i
+ // for all array entries.
+ //
+
+ std::vector<int> hlink(HUF_ENCSIZE);
+ std::vector<long long *> fHeap(HUF_ENCSIZE);
+
+ *im = 0;
+
+ while (!frq[*im]) (*im)++;
+
+ int nf = 0;
+
+ for (int i = *im; i < HUF_ENCSIZE; i++) {
+ hlink[i] = i;
+
+ if (frq[i]) {
+ fHeap[nf] = &frq[i];
+ nf++;
+ *iM = i;
+ }
+ }
+
+ //
+ // Add a pseudo-symbol, with a frequency count of 1, to frq;
+ // adjust the fHeap and hlink array accordingly. Function
+ // hufEncode() uses the pseudo-symbol for run-length encoding.
+ //
+
+ (*iM)++;
+ frq[*iM] = 1;
+ fHeap[nf] = &frq[*iM];
+ nf++;
+
+ //
+ // Build an array, scode, such that scode[i] contains the number
+ // of bits assigned to symbol i. Conceptually this is done by
+ // constructing a tree whose leaves are the symbols with non-zero
+ // frequency:
+ //
+ // Make a heap that contains all symbols with a non-zero frequency,
+ // with the least frequent symbol on top.
+ //
+ // Repeat until only one symbol is left on the heap:
+ //
+ // Take the two least frequent symbols off the top of the heap.
+ // Create a new node that has first two nodes as children, and
+ // whose frequency is the sum of the frequencies of the first
+ // two nodes. Put the new node back into the heap.
+ //
+ // The last node left on the heap is the root of the tree. For each
+ // leaf node, the distance between the root and the leaf is the length
+ // of the code for the corresponding symbol.
+ //
+ // The loop below doesn't actually build the tree; instead we compute
+ // the distances of the leaves from the root on the fly. When a new
+ // node is added to the heap, then that node's descendants are linked
+ // into a single linear list that starts at the new node, and the code
+ // lengths of the descendants (that is, their distance from the root
+ // of the tree) are incremented by one.
+ //
+
+ std::make_heap(&fHeap[0], &fHeap[nf], FHeapCompare());
+
+ std::vector<long long> scode(HUF_ENCSIZE);
+ memset(scode.data(), 0, sizeof(long long) * HUF_ENCSIZE);
+
+ while (nf > 1) {
+ //
+ // Find the indices, mm and m, of the two smallest non-zero frq
+ // values in fHeap, add the smallest frq to the second-smallest
+ // frq, and remove the smallest frq value from fHeap.
+ //
+
+ int mm = fHeap[0] - frq;
+ std::pop_heap(&fHeap[0], &fHeap[nf], FHeapCompare());
+ --nf;
+
+ int m = fHeap[0] - frq;
+ std::pop_heap(&fHeap[0], &fHeap[nf], FHeapCompare());
+
+ frq[m] += frq[mm];
+ std::push_heap(&fHeap[0], &fHeap[nf], FHeapCompare());
+
+ //
+ // The entries in scode are linked into lists with the
+ // entries in hlink serving as "next" pointers and with
+ // the end of a list marked by hlink[j] == j.
+ //
+ // Traverse the lists that start at scode[m] and scode[mm].
+ // For each element visited, increment the length of the
+ // corresponding code by one bit. (If we visit scode[j]
+ // during the traversal, then the code for symbol j becomes
+ // one bit longer.)
+ //
+ // Merge the lists that start at scode[m] and scode[mm]
+ // into a single list that starts at scode[m].
+ //
+
+ //
+ // Add a bit to all codes in the first list.
+ //
+
+ for (int j = m;; j = hlink[j]) {
+ scode[j]++;
+
+ assert(scode[j] <= 58);
+
+ if (hlink[j] == j) {
+ //
+ // Merge the two lists.
+ //
+
+ hlink[j] = mm;
+ break;
+ }
+ }
+
+ //
+ // Add a bit to all codes in the second list
+ //
+
+ for (int j = mm;; j = hlink[j]) {
+ scode[j]++;
+
+ assert(scode[j] <= 58);
+
+ if (hlink[j] == j) break;
+ }
+ }
+
+ //
+ // Build a canonical Huffman code table, replacing the code
+ // lengths in scode with (code, code length) pairs. Copy the
+ // code table from scode into frq.
+ //
+
+ hufCanonicalCodeTable(scode.data());
+ memcpy(frq, scode.data(), sizeof(long long) * HUF_ENCSIZE);
+}
+
+//
+// Pack an encoding table:
+// - only code lengths, not actual codes, are stored
+// - runs of zeroes are compressed as follows:
+//
+// unpacked packed
+// --------------------------------
+// 1 zero 0 (6 bits)
+// 2 zeroes 59
+// 3 zeroes 60
+// 4 zeroes 61
+// 5 zeroes 62
+// n zeroes (6 or more) 63 n-6 (6 + 8 bits)
+//
+
+const int SHORT_ZEROCODE_RUN = 59;
+const int LONG_ZEROCODE_RUN = 63;
+const int SHORTEST_LONG_RUN = 2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN;
+const int LONGEST_LONG_RUN = 255 + SHORTEST_LONG_RUN;
+
+static void hufPackEncTable(
+ const long long *hcode, // i : encoding table [HUF_ENCSIZE]
+ int im, // i : min hcode index
+ int iM, // i : max hcode index
+ char **pcode) // o: ptr to packed table (updated)
+{
+ char *p = *pcode;
+ long long c = 0;
+ int lc = 0;
+
+ for (; im <= iM; im++) {
+ int l = hufLength(hcode[im]);
+
+ if (l == 0) {
+ int zerun = 1;
+
+ while ((im < iM) && (zerun < LONGEST_LONG_RUN)) {
+ if (hufLength(hcode[im + 1]) > 0) break;
+ im++;
+ zerun++;
+ }
+
+ if (zerun >= 2) {
+ if (zerun >= SHORTEST_LONG_RUN) {
+ outputBits(6, LONG_ZEROCODE_RUN, c, lc, p);
+ outputBits(8, zerun - SHORTEST_LONG_RUN, c, lc, p);
+ } else {
+ outputBits(6, SHORT_ZEROCODE_RUN + zerun - 2, c, lc, p);
+ }
+ continue;
+ }
+ }
+
+ outputBits(6, l, c, lc, p);
+ }
+
+ if (lc > 0) *p++ = (unsigned char)(c << (8 - lc));
+
+ *pcode = p;
+}
+
+//
+// Unpack an encoding table packed by hufPackEncTable():
+//
+
+static bool hufUnpackEncTable(
+ const char **pcode, // io: ptr to packed table (updated)
+ int ni, // i : input size (in bytes)
+ int im, // i : min hcode index
+ int iM, // i : max hcode index
+ long long *hcode) // o: encoding table [HUF_ENCSIZE]
+{
+ memset(hcode, 0, sizeof(long long) * HUF_ENCSIZE);
+
+ const char *p = *pcode;
+ long long c = 0;
+ int lc = 0;
+
+ for (; im <= iM; im++) {
+ if (p - *pcode >= ni) {
+ return false;
+ }
+
+ long long l = hcode[im] = getBits(6, c, lc, p); // code length
+
+ if (l == (long long)LONG_ZEROCODE_RUN) {
+ if (p - *pcode > ni) {
+ return false;
+ }
+
+ int zerun = getBits(8, c, lc, p) + SHORTEST_LONG_RUN;
+
+ if (im + zerun > iM + 1) {
+ return false;
+ }
+
+ while (zerun--) hcode[im++] = 0;
+
+ im--;
+ } else if (l >= (long long)SHORT_ZEROCODE_RUN) {
+ int zerun = l - SHORT_ZEROCODE_RUN + 2;
+
+ if (im + zerun > iM + 1) {
+ return false;
+ }
+
+ while (zerun--) hcode[im++] = 0;
+
+ im--;
+ }
+ }
+
+ *pcode = const_cast<char *>(p);
+
+ hufCanonicalCodeTable(hcode);
+
+ return true;
+}
+
+//
+// DECODING TABLE BUILDING
+//
+
+//
+// Clear a newly allocated decoding table so that it contains only zeroes.
+//
+
+static void hufClearDecTable(HufDec *hdecod) // io: (allocated by caller)
+// decoding table [HUF_DECSIZE]
+{
+ for (int i = 0; i < HUF_DECSIZE; i++) {
+ hdecod[i].len = 0;
+ hdecod[i].lit = 0;
+ hdecod[i].p = NULL;
+ }
+ // memset(hdecod, 0, sizeof(HufDec) * HUF_DECSIZE);
+}
+
+//
+// Build a decoding hash table based on the encoding table hcode:
+// - short codes (<= HUF_DECBITS) are resolved with a single table access;
+// - long code entry allocations are not optimized, because long codes are
+// unfrequent;
+// - decoding tables are used by hufDecode();
+//
+
+static bool hufBuildDecTable(const long long *hcode, // i : encoding table
+ int im, // i : min index in hcode
+ int iM, // i : max index in hcode
+ HufDec *hdecod) // o: (allocated by caller)
+// decoding table [HUF_DECSIZE]
+{
+ //
+ // Init hashtable & loop on all codes.
+ // Assumes that hufClearDecTable(hdecod) has already been called.
+ //
+
+ for (; im <= iM; im++) {
+ long long c = hufCode(hcode[im]);
+ int l = hufLength(hcode[im]);
+
+ if (c >> l) {
+ //
+ // Error: c is supposed to be an l-bit code,
+ // but c contains a value that is greater
+ // than the largest l-bit number.
+ //
+
+ // invalidTableEntry();
+ return false;
+ }
+
+ if (l > HUF_DECBITS) {
+ //
+ // Long code: add a secondary entry
+ //
+
+ HufDec *pl = hdecod + (c >> (l - HUF_DECBITS));
+
+ if (pl->len) {
+ //
+ // Error: a short code has already
+ // been stored in table entry *pl.
+ //
+
+ // invalidTableEntry();
+ return false;
+ }
+
+ pl->lit++;
+
+ if (pl->p) {
+ unsigned int *p = pl->p;
+ pl->p = new unsigned int[pl->lit];
+
+ for (int i = 0; i < pl->lit - 1; ++i) pl->p[i] = p[i];
+
+ delete[] p;
+ } else {
+ pl->p = new unsigned int[1];
+ }
+
+ pl->p[pl->lit - 1] = im;
+ } else if (l) {
+ //
+ // Short code: init all primary entries
+ //
+
+ HufDec *pl = hdecod + (c << (HUF_DECBITS - l));
+
+ for (long long i = 1ULL << (HUF_DECBITS - l); i > 0; i--, pl++) {
+ if (pl->len || pl->p) {
+ //
+ // Error: a short code or a long code has
+ // already been stored in table entry *pl.
+ //
+
+ // invalidTableEntry();
+ return false;
+ }
+
+ pl->len = l;
+ pl->lit = im;
+ }
+ }
+ }
+
+ return true;
+}
+
+//
+// Free the long code entries of a decoding table built by hufBuildDecTable()
+//
+
+static void hufFreeDecTable(HufDec *hdecod) // io: Decoding table
+{
+ for (int i = 0; i < HUF_DECSIZE; i++) {
+ if (hdecod[i].p) {
+ delete[] hdecod[i].p;
+ hdecod[i].p = 0;
+ }
+ }
+}
+
+//
+// ENCODING
+//
+
+inline void outputCode(long long code, long long &c, int &lc, char *&out) {
+ outputBits(hufLength(code), hufCode(code), c, lc, out);
+}
+
+inline void sendCode(long long sCode, int runCount, long long runCode,
+ long long &c, int &lc, char *&out) {
+ //
+ // Output a run of runCount instances of the symbol sCount.
+ // Output the symbols explicitly, or if that is shorter, output
+ // the sCode symbol once followed by a runCode symbol and runCount
+ // expressed as an 8-bit number.
+ //
+
+ if (hufLength(sCode) + hufLength(runCode) + 8 < hufLength(sCode) * runCount) {
+ outputCode(sCode, c, lc, out);
+ outputCode(runCode, c, lc, out);
+ outputBits(8, runCount, c, lc, out);
+ } else {
+ while (runCount-- >= 0) outputCode(sCode, c, lc, out);
+ }
+}
+
+//
+// Encode (compress) ni values based on the Huffman encoding table hcode:
+//
+
+static int hufEncode // return: output size (in bits)
+ (const long long *hcode, // i : encoding table
+ const unsigned short *in, // i : uncompressed input buffer
+ const int ni, // i : input buffer size (in bytes)
+ int rlc, // i : rl code
+ char *out) // o: compressed output buffer
+{
+ char *outStart = out;
+ long long c = 0; // bits not yet written to out
+ int lc = 0; // number of valid bits in c (LSB)
+ int s = in[0];
+ int cs = 0;
+
+ //
+ // Loop on input values
+ //
+
+ for (int i = 1; i < ni; i++) {
+ //
+ // Count same values or send code
+ //
+
+ if (s == in[i] && cs < 255) {
+ cs++;
+ } else {
+ sendCode(hcode[s], cs, hcode[rlc], c, lc, out);
+ cs = 0;
+ }
+
+ s = in[i];
+ }
+
+ //
+ // Send remaining code
+ //
+
+ sendCode(hcode[s], cs, hcode[rlc], c, lc, out);
+
+ if (lc) *out = (c << (8 - lc)) & 0xff;
+
+ return (out - outStart) * 8 + lc;
+}
+
+//
+// DECODING
+//
+
+//
+// In order to force the compiler to inline them,
+// getChar() and getCode() are implemented as macros
+// instead of "inline" functions.
+//
+
+#define getChar(c, lc, in) \
+ { \
+ c = (c << 8) | *(unsigned char *)(in++); \
+ lc += 8; \
+ }
+
+#if 0
+#define getCode(po, rlc, c, lc, in, out, ob, oe) \
+ { \
+ if (po == rlc) { \
+ if (lc < 8) getChar(c, lc, in); \
+ \
+ lc -= 8; \
+ \
+ unsigned char cs = (c >> lc); \
+ \
+ if (out + cs > oe) return false; \
+ \
+ /* TinyEXR issue 78 */ \
+ unsigned short s = out[-1]; \
+ \
+ while (cs-- > 0) *out++ = s; \
+ } else if (out < oe) { \
+ *out++ = po; \
+ } else { \
+ return false; \
+ } \
+ }
+#else
+static bool getCode(int po, int rlc, long long &c, int &lc, const char *&in,
+ const char *in_end, unsigned short *&out,
+ const unsigned short *ob, const unsigned short *oe) {
+ (void)ob;
+ if (po == rlc) {
+ if (lc < 8) {
+ /* TinyEXR issue 78 */
+ /* TinyEXR issue 160. in + 1 -> in */
+ if (in >= in_end) {
+ return false;
+ }
+
+ getChar(c, lc, in);
+ }
+
+ lc -= 8;
+
+ unsigned char cs = (c >> lc);
+
+ if (out + cs > oe) return false;
+
+ // Bounds check for safety
+ // Issue 100.
+ if ((out - 1) < ob) return false;
+ unsigned short s = out[-1];
+
+ while (cs-- > 0) *out++ = s;
+ } else if (out < oe) {
+ *out++ = po;
+ } else {
+ return false;
+ }
+ return true;
+}
+#endif
+
+//
+// Decode (uncompress) ni bits based on encoding & decoding tables:
+//
+
+static bool hufDecode(const long long *hcode, // i : encoding table
+ const HufDec *hdecod, // i : decoding table
+ const char *in, // i : compressed input buffer
+ int ni, // i : input size (in bits)
+ int rlc, // i : run-length code
+ int no, // i : expected output size (in bytes)
+ unsigned short *out) // o: uncompressed output buffer
+{
+ long long c = 0;
+ int lc = 0;
+ unsigned short *outb = out; // begin
+ unsigned short *oe = out + no; // end
+ const char *ie = in + (ni + 7) / 8; // input byte size
+
+ //
+ // Loop on input bytes
+ //
+
+ while (in < ie) {
+ getChar(c, lc, in);
+
+ //
+ // Access decoding table
+ //
+
+ while (lc >= HUF_DECBITS) {
+ const HufDec pl = hdecod[(c >> (lc - HUF_DECBITS)) & HUF_DECMASK];
+
+ if (pl.len) {
+ //
+ // Get short code
+ //
+
+ lc -= pl.len;
+ // std::cout << "lit = " << pl.lit << std::endl;
+ // std::cout << "rlc = " << rlc << std::endl;
+ // std::cout << "c = " << c << std::endl;
+ // std::cout << "lc = " << lc << std::endl;
+ // std::cout << "in = " << in << std::endl;
+ // std::cout << "out = " << out << std::endl;
+ // std::cout << "oe = " << oe << std::endl;
+ if (!getCode(pl.lit, rlc, c, lc, in, ie, out, outb, oe)) {
+ return false;
+ }
+ } else {
+ if (!pl.p) {
+ return false;
+ }
+ // invalidCode(); // wrong code
+
+ //
+ // Search long code
+ //
+
+ int j;
+
+ for (j = 0; j < pl.lit; j++) {
+ int l = hufLength(hcode[pl.p[j]]);
+
+ while (lc < l && in < ie) // get more bits
+ getChar(c, lc, in);
+
+ if (lc >= l) {
+ if (hufCode(hcode[pl.p[j]]) ==
+ ((c >> (lc - l)) & (((long long)(1) << l) - 1))) {
+ //
+ // Found : get long code
+ //
+
+ lc -= l;
+ if (!getCode(pl.p[j], rlc, c, lc, in, ie, out, outb, oe)) {
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
+ if (j == pl.lit) {
+ return false;
+ // invalidCode(); // Not found
+ }
+ }
+ }
+ }
+
+ //
+ // Get remaining (short) codes
+ //
+
+ int i = (8 - ni) & 7;
+ c >>= i;
+ lc -= i;
+
+ while (lc > 0) {
+ const HufDec pl = hdecod[(c << (HUF_DECBITS - lc)) & HUF_DECMASK];
+
+ if (pl.len) {
+ lc -= pl.len;
+ if (!getCode(pl.lit, rlc, c, lc, in, ie, out, outb, oe)) {
+ return false;
+ }
+ } else {
+ return false;
+ // invalidCode(); // wrong (long) code
+ }
+ }
+
+ if (out - outb != no) {
+ return false;
+ }
+ // notEnoughData ();
+
+ return true;
+}
+
+static void countFrequencies(std::vector<long long> &freq,
+ const unsigned short data[/*n*/], int n) {
+ for (int i = 0; i < HUF_ENCSIZE; ++i) freq[i] = 0;
+
+ for (int i = 0; i < n; ++i) ++freq[data[i]];
+}
+
+static void writeUInt(char buf[4], unsigned int i) {
+ unsigned char *b = (unsigned char *)buf;
+
+ b[0] = i;
+ b[1] = i >> 8;
+ b[2] = i >> 16;
+ b[3] = i >> 24;
+}
+
+static unsigned int readUInt(const char buf[4]) {
+ const unsigned char *b = (const unsigned char *)buf;
+
+ return (b[0] & 0x000000ff) | ((b[1] << 8) & 0x0000ff00) |
+ ((b[2] << 16) & 0x00ff0000) | ((b[3] << 24) & 0xff000000);
+}
+
+//
+// EXTERNAL INTERFACE
+//
+
+static int hufCompress(const unsigned short raw[], int nRaw,
+ char compressed[]) {
+ if (nRaw == 0) return 0;
+
+ std::vector<long long> freq(HUF_ENCSIZE);
+
+ countFrequencies(freq, raw, nRaw);
+
+ int im = 0;
+ int iM = 0;
+ hufBuildEncTable(freq.data(), &im, &iM);
+
+ char *tableStart = compressed + 20;
+ char *tableEnd = tableStart;
+ hufPackEncTable(freq.data(), im, iM, &tableEnd);
+ int tableLength = tableEnd - tableStart;
+
+ char *dataStart = tableEnd;
+ int nBits = hufEncode(freq.data(), raw, nRaw, iM, dataStart);
+ int data_length = (nBits + 7) / 8;
+
+ writeUInt(compressed, im);
+ writeUInt(compressed + 4, iM);
+ writeUInt(compressed + 8, tableLength);
+ writeUInt(compressed + 12, nBits);
+ writeUInt(compressed + 16, 0); // room for future extensions
+
+ return dataStart + data_length - compressed;
+}
+
+static bool hufUncompress(const char compressed[], int nCompressed,
+ std::vector<unsigned short> *raw) {
+ if (nCompressed == 0) {
+ if (raw->size() != 0) return false;
+
+ return false;
+ }
+
+ int im = readUInt(compressed);
+ int iM = readUInt(compressed + 4);
+ // int tableLength = readUInt (compressed + 8);
+ int nBits = readUInt(compressed + 12);
+
+ if (im < 0 || im >= HUF_ENCSIZE || iM < 0 || iM >= HUF_ENCSIZE) return false;
+
+ const char *ptr = compressed + 20;
+
+ //
+ // Fast decoder needs at least 2x64-bits of compressed data, and
+ // needs to be run-able on this platform. Otherwise, fall back
+ // to the original decoder
+ //
+
+ // if (FastHufDecoder::enabled() && nBits > 128)
+ //{
+ // FastHufDecoder fhd (ptr, nCompressed - (ptr - compressed), im, iM, iM);
+ // fhd.decode ((unsigned char*)ptr, nBits, raw, nRaw);
+ //}
+ // else
+ {
+ std::vector<long long> freq(HUF_ENCSIZE);
+ std::vector<HufDec> hdec(HUF_DECSIZE);
+
+ hufClearDecTable(&hdec.at(0));
+
+ hufUnpackEncTable(&ptr, nCompressed - (ptr - compressed), im, iM,
+ &freq.at(0));
+
+ {
+ if (nBits > 8 * (nCompressed - (ptr - compressed))) {
+ return false;
+ }
+
+ hufBuildDecTable(&freq.at(0), im, iM, &hdec.at(0));
+ hufDecode(&freq.at(0), &hdec.at(0), ptr, nBits, iM, raw->size(),
+ raw->data());
+ }
+ // catch (...)
+ //{
+ // hufFreeDecTable (hdec);
+ // throw;
+ //}
+
+ hufFreeDecTable(&hdec.at(0));
+ }
+
+ return true;
+}
+
+//
+// Functions to compress the range of values in the pixel data
+//
+
+const int USHORT_RANGE = (1 << 16);
+const int BITMAP_SIZE = (USHORT_RANGE >> 3);
+
+static void bitmapFromData(const unsigned short data[/*nData*/], int nData,
+ unsigned char bitmap[BITMAP_SIZE],
+ unsigned short &minNonZero,
+ unsigned short &maxNonZero) {
+ for (int i = 0; i < BITMAP_SIZE; ++i) bitmap[i] = 0;
+
+ for (int i = 0; i < nData; ++i) bitmap[data[i] >> 3] |= (1 << (data[i] & 7));
+
+ bitmap[0] &= ~1; // zero is not explicitly stored in
+ // the bitmap; we assume that the
+ // data always contain zeroes
+ minNonZero = BITMAP_SIZE - 1;
+ maxNonZero = 0;
+
+ for (int i = 0; i < BITMAP_SIZE; ++i) {
+ if (bitmap[i]) {
+ if (minNonZero > i) minNonZero = i;
+ if (maxNonZero < i) maxNonZero = i;
+ }
+ }
+}
+
+static unsigned short forwardLutFromBitmap(
+ const unsigned char bitmap[BITMAP_SIZE], unsigned short lut[USHORT_RANGE]) {
+ int k = 0;
+
+ for (int i = 0; i < USHORT_RANGE; ++i) {
+ if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7))))
+ lut[i] = k++;
+ else
+ lut[i] = 0;
+ }
+
+ return k - 1; // maximum value stored in lut[],
+} // i.e. number of ones in bitmap minus 1
+
+static unsigned short reverseLutFromBitmap(
+ const unsigned char bitmap[BITMAP_SIZE], unsigned short lut[USHORT_RANGE]) {
+ int k = 0;
+
+ for (int i = 0; i < USHORT_RANGE; ++i) {
+ if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7)))) lut[k++] = i;
+ }
+
+ int n = k - 1;
+
+ while (k < USHORT_RANGE) lut[k++] = 0;
+
+ return n; // maximum k where lut[k] is non-zero,
+} // i.e. number of ones in bitmap minus 1
+
+static void applyLut(const unsigned short lut[USHORT_RANGE],
+ unsigned short data[/*nData*/], int nData) {
+ for (int i = 0; i < nData; ++i) data[i] = lut[data[i]];
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif // __clang__
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+static bool CompressPiz(unsigned char *outPtr, unsigned int *outSize,
+ const unsigned char *inPtr, size_t inSize,
+ const std::vector<ChannelInfo> &channelInfo,
+ int data_width, int num_lines) {
+ std::vector<unsigned char> bitmap(BITMAP_SIZE);
+ unsigned short minNonZero;
+ unsigned short maxNonZero;
+
+#if !TINYEXR_LITTLE_ENDIAN
+ // @todo { PIZ compression on BigEndian architecture. }
+ assert(0);
+ return false;
+#endif
+
+ // Assume `inSize` is multiple of 2 or 4.
+ std::vector<unsigned short> tmpBuffer(inSize / sizeof(unsigned short));
+
+ std::vector<PIZChannelData> channelData(channelInfo.size());
+ unsigned short *tmpBufferEnd = &tmpBuffer.at(0);
+
+ for (size_t c = 0; c < channelData.size(); c++) {
+ PIZChannelData &cd = channelData[c];
+
+ cd.start = tmpBufferEnd;
+ cd.end = cd.start;
+
+ cd.nx = data_width;
+ cd.ny = num_lines;
+ // cd.ys = c.channel().ySampling;
+
+ size_t pixelSize = sizeof(int); // UINT and FLOAT
+ if (channelInfo[c].requested_pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ pixelSize = sizeof(short);
+ }
+
+ cd.size = static_cast<int>(pixelSize / sizeof(short));
+
+ tmpBufferEnd += cd.nx * cd.ny * cd.size;
+ }
+
+ const unsigned char *ptr = inPtr;
+ for (int y = 0; y < num_lines; ++y) {
+ for (size_t i = 0; i < channelData.size(); ++i) {
+ PIZChannelData &cd = channelData[i];
+
+ // if (modp (y, cd.ys) != 0)
+ // continue;
+
+ size_t n = static_cast<size_t>(cd.nx * cd.size);
+ memcpy(cd.end, ptr, n * sizeof(unsigned short));
+ ptr += n * sizeof(unsigned short);
+ cd.end += n;
+ }
+ }
+
+ bitmapFromData(&tmpBuffer.at(0), static_cast<int>(tmpBuffer.size()),
+ bitmap.data(), minNonZero, maxNonZero);
+
+ std::vector<unsigned short> lut(USHORT_RANGE);
+ unsigned short maxValue = forwardLutFromBitmap(bitmap.data(), lut.data());
+ applyLut(lut.data(), &tmpBuffer.at(0), static_cast<int>(tmpBuffer.size()));
+
+ //
+ // Store range compression info in _outBuffer
+ //
+
+ char *buf = reinterpret_cast<char *>(outPtr);
+
+ memcpy(buf, &minNonZero, sizeof(unsigned short));
+ buf += sizeof(unsigned short);
+ memcpy(buf, &maxNonZero, sizeof(unsigned short));
+ buf += sizeof(unsigned short);
+
+ if (minNonZero <= maxNonZero) {
+ memcpy(buf, reinterpret_cast<char *>(&bitmap[0] + minNonZero),
+ maxNonZero - minNonZero + 1);
+ buf += maxNonZero - minNonZero + 1;
+ }
+
+ //
+ // Apply wavelet encoding
+ //
+
+ for (size_t i = 0; i < channelData.size(); ++i) {
+ PIZChannelData &cd = channelData[i];
+
+ for (int j = 0; j < cd.size; ++j) {
+ wav2Encode(cd.start + j, cd.nx, cd.size, cd.ny, cd.nx * cd.size,
+ maxValue);
+ }
+ }
+
+ //
+ // Apply Huffman encoding; append the result to _outBuffer
+ //
+
+ // length header(4byte), then huff data. Initialize length header with zero,
+ // then later fill it by `length`.
+ char *lengthPtr = buf;
+ int zero = 0;
+ memcpy(buf, &zero, sizeof(int));
+ buf += sizeof(int);
+
+ int length =
+ hufCompress(&tmpBuffer.at(0), static_cast<int>(tmpBuffer.size()), buf);
+ memcpy(lengthPtr, &length, sizeof(int));
+
+ (*outSize) = static_cast<unsigned int>(
+ (reinterpret_cast<unsigned char *>(buf) - outPtr) +
+ static_cast<unsigned int>(length));
+
+ // Use uncompressed data when compressed data is larger than uncompressed.
+ // (Issue 40)
+ if ((*outSize) >= inSize) {
+ (*outSize) = static_cast<unsigned int>(inSize);
+ memcpy(outPtr, inPtr, inSize);
+ }
+ return true;
+}
+
+static bool DecompressPiz(unsigned char *outPtr, const unsigned char *inPtr,
+ size_t tmpBufSizeInBytes, size_t inLen, int num_channels,
+ const EXRChannelInfo *channels, int data_width,
+ int num_lines) {
+ if (inLen == tmpBufSizeInBytes) {
+ // Data is not compressed(Issue 40).
+ memcpy(outPtr, inPtr, inLen);
+ return true;
+ }
+
+ std::vector<unsigned char> bitmap(BITMAP_SIZE);
+ unsigned short minNonZero;
+ unsigned short maxNonZero;
+
+#if !TINYEXR_LITTLE_ENDIAN
+ // @todo { PIZ compression on BigEndian architecture. }
+ assert(0);
+ return false;
+#endif
+
+ memset(bitmap.data(), 0, BITMAP_SIZE);
+
+ const unsigned char *ptr = inPtr;
+ // minNonZero = *(reinterpret_cast<const unsigned short *>(ptr));
+ tinyexr::cpy2(&minNonZero, reinterpret_cast<const unsigned short *>(ptr));
+ // maxNonZero = *(reinterpret_cast<const unsigned short *>(ptr + 2));
+ tinyexr::cpy2(&maxNonZero, reinterpret_cast<const unsigned short *>(ptr + 2));
+ ptr += 4;
+
+ if (maxNonZero >= BITMAP_SIZE) {
+ return false;
+ }
+
+ if (minNonZero <= maxNonZero) {
+ memcpy(reinterpret_cast<char *>(&bitmap[0] + minNonZero), ptr,
+ maxNonZero - minNonZero + 1);
+ ptr += maxNonZero - minNonZero + 1;
+ }
+
+ std::vector<unsigned short> lut(USHORT_RANGE);
+ memset(lut.data(), 0, sizeof(unsigned short) * USHORT_RANGE);
+ unsigned short maxValue = reverseLutFromBitmap(bitmap.data(), lut.data());
+
+ //
+ // Huffman decoding
+ //
+
+ int length;
+
+ // length = *(reinterpret_cast<const int *>(ptr));
+ tinyexr::cpy4(&length, reinterpret_cast<const int *>(ptr));
+ ptr += sizeof(int);
+
+ if (size_t((ptr - inPtr) + length) > inLen) {
+ return false;
+ }
+
+ std::vector<unsigned short> tmpBuffer(tmpBufSizeInBytes / sizeof(unsigned short));
+ hufUncompress(reinterpret_cast<const char *>(ptr), length, &tmpBuffer);
+
+ //
+ // Wavelet decoding
+ //
+
+ std::vector<PIZChannelData> channelData(static_cast<size_t>(num_channels));
+
+ unsigned short *tmpBufferEnd = &tmpBuffer.at(0);
+
+ for (size_t i = 0; i < static_cast<size_t>(num_channels); ++i) {
+ const EXRChannelInfo &chan = channels[i];
+
+ size_t pixelSize = sizeof(int); // UINT and FLOAT
+ if (chan.pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ pixelSize = sizeof(short);
+ }
+
+ channelData[i].start = tmpBufferEnd;
+ channelData[i].end = channelData[i].start;
+ channelData[i].nx = data_width;
+ channelData[i].ny = num_lines;
+ // channelData[i].ys = 1;
+ channelData[i].size = static_cast<int>(pixelSize / sizeof(short));
+
+ tmpBufferEnd += channelData[i].nx * channelData[i].ny * channelData[i].size;
+ }
+
+ for (size_t i = 0; i < channelData.size(); ++i) {
+ PIZChannelData &cd = channelData[i];
+
+ for (int j = 0; j < cd.size; ++j) {
+ wav2Decode(cd.start + j, cd.nx, cd.size, cd.ny, cd.nx * cd.size,
+ maxValue);
+ }
+ }
+
+ //
+ // Expand the pixel data to their original range
+ //
+
+ applyLut(lut.data(), &tmpBuffer.at(0), static_cast<int>(tmpBufSizeInBytes / sizeof(unsigned short)));
+
+ for (int y = 0; y < num_lines; y++) {
+ for (size_t i = 0; i < channelData.size(); ++i) {
+ PIZChannelData &cd = channelData[i];
+
+ // if (modp (y, cd.ys) != 0)
+ // continue;
+
+ size_t n = static_cast<size_t>(cd.nx * cd.size);
+ memcpy(outPtr, cd.end, static_cast<size_t>(n * sizeof(unsigned short)));
+ outPtr += n * sizeof(unsigned short);
+ cd.end += n;
+ }
+ }
+
+ return true;
+}
+#endif // TINYEXR_USE_PIZ
+
+#if TINYEXR_USE_ZFP
+
+struct ZFPCompressionParam {
+ double rate;
+ unsigned int precision;
+ unsigned int __pad0;
+ double tolerance;
+ int type; // TINYEXR_ZFP_COMPRESSIONTYPE_*
+ unsigned int __pad1;
+
+ ZFPCompressionParam() {
+ type = TINYEXR_ZFP_COMPRESSIONTYPE_RATE;
+ rate = 2.0;
+ precision = 0;
+ tolerance = 0.0;
+ }
+};
+
+static bool FindZFPCompressionParam(ZFPCompressionParam *param,
+ const EXRAttribute *attributes,
+ int num_attributes, std::string *err) {
+ bool foundType = false;
+
+ for (int i = 0; i < num_attributes; i++) {
+ if ((strcmp(attributes[i].name, "zfpCompressionType") == 0)) {
+ if (attributes[i].size == 1) {
+ param->type = static_cast<int>(attributes[i].value[0]);
+ foundType = true;
+ break;
+ } else {
+ if (err) {
+ (*err) +=
+ "zfpCompressionType attribute must be uchar(1 byte) type.\n";
+ }
+ return false;
+ }
+ }
+ }
+
+ if (!foundType) {
+ if (err) {
+ (*err) += "`zfpCompressionType` attribute not found.\n";
+ }
+ return false;
+ }
+
+ if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) {
+ for (int i = 0; i < num_attributes; i++) {
+ if ((strcmp(attributes[i].name, "zfpCompressionRate") == 0) &&
+ (attributes[i].size == 8)) {
+ param->rate = *(reinterpret_cast<double *>(attributes[i].value));
+ return true;
+ }
+ }
+
+ if (err) {
+ (*err) += "`zfpCompressionRate` attribute not found.\n";
+ }
+
+ } else if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
+ for (int i = 0; i < num_attributes; i++) {
+ if ((strcmp(attributes[i].name, "zfpCompressionPrecision") == 0) &&
+ (attributes[i].size == 4)) {
+ param->rate = *(reinterpret_cast<int *>(attributes[i].value));
+ return true;
+ }
+ }
+
+ if (err) {
+ (*err) += "`zfpCompressionPrecision` attribute not found.\n";
+ }
+
+ } else if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
+ for (int i = 0; i < num_attributes; i++) {
+ if ((strcmp(attributes[i].name, "zfpCompressionTolerance") == 0) &&
+ (attributes[i].size == 8)) {
+ param->tolerance = *(reinterpret_cast<double *>(attributes[i].value));
+ return true;
+ }
+ }
+
+ if (err) {
+ (*err) += "`zfpCompressionTolerance` attribute not found.\n";
+ }
+ } else {
+ if (err) {
+ (*err) += "Unknown value specified for `zfpCompressionType`.\n";
+ }
+ }
+
+ return false;
+}
+
+// Assume pixel format is FLOAT for all channels.
+static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines,
+ size_t num_channels, const unsigned char *src,
+ unsigned long src_size,
+ const ZFPCompressionParam &param) {
+ size_t uncompressed_size =
+ size_t(dst_width) * size_t(dst_num_lines) * num_channels;
+
+ if (uncompressed_size == src_size) {
+ // Data is not compressed(Issue 40).
+ memcpy(dst, src, src_size);
+ }
+
+ zfp_stream *zfp = NULL;
+ zfp_field *field = NULL;
+
+ assert((dst_width % 4) == 0);
+ assert((dst_num_lines % 4) == 0);
+
+ if ((size_t(dst_width) & 3U) || (size_t(dst_num_lines) & 3U)) {
+ return false;
+ }
+
+ field =
+ zfp_field_2d(reinterpret_cast<void *>(const_cast<unsigned char *>(src)),
+ zfp_type_float, static_cast<unsigned int>(dst_width),
+ static_cast<unsigned int>(dst_num_lines) *
+ static_cast<unsigned int>(num_channels));
+ zfp = zfp_stream_open(NULL);
+
+ if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) {
+ zfp_stream_set_rate(zfp, param.rate, zfp_type_float, /* dimension */ 2,
+ /* write random access */ 0);
+ } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
+ zfp_stream_set_precision(zfp, param.precision);
+ } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
+ zfp_stream_set_accuracy(zfp, param.tolerance);
+ } else {
+ assert(0);
+ }
+
+ size_t buf_size = zfp_stream_maximum_size(zfp, field);
+ std::vector<unsigned char> buf(buf_size);
+ memcpy(&buf.at(0), src, src_size);
+
+ bitstream *stream = stream_open(&buf.at(0), buf_size);
+ zfp_stream_set_bit_stream(zfp, stream);
+ zfp_stream_rewind(zfp);
+
+ size_t image_size = size_t(dst_width) * size_t(dst_num_lines);
+
+ for (size_t c = 0; c < size_t(num_channels); c++) {
+ // decompress 4x4 pixel block.
+ for (size_t y = 0; y < size_t(dst_num_lines); y += 4) {
+ for (size_t x = 0; x < size_t(dst_width); x += 4) {
+ float fblock[16];
+ zfp_decode_block_float_2(zfp, fblock);
+ for (size_t j = 0; j < 4; j++) {
+ for (size_t i = 0; i < 4; i++) {
+ dst[c * image_size + ((y + j) * size_t(dst_width) + (x + i))] =
+ fblock[j * 4 + i];
+ }
+ }
+ }
+ }
+ }
+
+ zfp_field_free(field);
+ zfp_stream_close(zfp);
+ stream_close(stream);
+
+ return true;
+}
+
+// Assume pixel format is FLOAT for all channels.
+static bool CompressZfp(std::vector<unsigned char> *outBuf,
+ unsigned int *outSize, const float *inPtr, int width,
+ int num_lines, int num_channels,
+ const ZFPCompressionParam &param) {
+ zfp_stream *zfp = NULL;
+ zfp_field *field = NULL;
+
+ assert((width % 4) == 0);
+ assert((num_lines % 4) == 0);
+
+ if ((size_t(width) & 3U) || (size_t(num_lines) & 3U)) {
+ return false;
+ }
+
+ // create input array.
+ field = zfp_field_2d(reinterpret_cast<void *>(const_cast<float *>(inPtr)),
+ zfp_type_float, static_cast<unsigned int>(width),
+ static_cast<unsigned int>(num_lines * num_channels));
+
+ zfp = zfp_stream_open(NULL);
+
+ if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) {
+ zfp_stream_set_rate(zfp, param.rate, zfp_type_float, 2, 0);
+ } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
+ zfp_stream_set_precision(zfp, param.precision);
+ } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
+ zfp_stream_set_accuracy(zfp, param.tolerance);
+ } else {
+ assert(0);
+ }
+
+ size_t buf_size = zfp_stream_maximum_size(zfp, field);
+
+ outBuf->resize(buf_size);
+
+ bitstream *stream = stream_open(&outBuf->at(0), buf_size);
+ zfp_stream_set_bit_stream(zfp, stream);
+ zfp_field_free(field);
+
+ size_t image_size = size_t(width) * size_t(num_lines);
+
+ for (size_t c = 0; c < size_t(num_channels); c++) {
+ // compress 4x4 pixel block.
+ for (size_t y = 0; y < size_t(num_lines); y += 4) {
+ for (size_t x = 0; x < size_t(width); x += 4) {
+ float fblock[16];
+ for (size_t j = 0; j < 4; j++) {
+ for (size_t i = 0; i < 4; i++) {
+ fblock[j * 4 + i] =
+ inPtr[c * image_size + ((y + j) * size_t(width) + (x + i))];
+ }
+ }
+ zfp_encode_block_float_2(zfp, fblock);
+ }
+ }
+ }
+
+ zfp_stream_flush(zfp);
+ (*outSize) = static_cast<unsigned int>(zfp_stream_compressed_size(zfp));
+
+ zfp_stream_close(zfp);
+
+ return true;
+}
+
+#endif
+
+//
+// -----------------------------------------------------------------
+//
+
+// heuristics
+#define TINYEXR_DIMENSION_THRESHOLD (1024 * 8192)
+
+// TODO(syoyo): Refactor function arguments.
+static bool DecodePixelData(/* out */ unsigned char **out_images,
+ const int *requested_pixel_types,
+ const unsigned char *data_ptr, size_t data_len,
+ int compression_type, int line_order, int width,
+ int height, int x_stride, int y, int line_no,
+ int num_lines, size_t pixel_data_size,
+ size_t num_attributes,
+ const EXRAttribute *attributes, size_t num_channels,
+ const EXRChannelInfo *channels,
+ const std::vector<size_t> &channel_offset_list) {
+ if (compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) { // PIZ
+#if TINYEXR_USE_PIZ
+ if ((width == 0) || (num_lines == 0) || (pixel_data_size == 0)) {
+ // Invalid input #90
+ return false;
+ }
+
+ // Allocate original data size.
+ std::vector<unsigned char> outBuf(static_cast<size_t>(
+ static_cast<size_t>(width * num_lines) * pixel_data_size));
+ size_t tmpBufLen = outBuf.size();
+
+ bool ret = tinyexr::DecompressPiz(
+ reinterpret_cast<unsigned char *>(&outBuf.at(0)), data_ptr, tmpBufLen,
+ data_len, static_cast<int>(num_channels), channels, width, num_lines);
+
+ if (!ret) {
+ return false;
+ }
+
+ // For PIZ_COMPRESSION:
+ // pixel sample data for channel 0 for scanline 0
+ // pixel sample data for channel 1 for scanline 0
+ // pixel sample data for channel ... for scanline 0
+ // pixel sample data for channel n for scanline 0
+ // pixel sample data for channel 0 for scanline 1
+ // pixel sample data for channel 1 for scanline 1
+ // pixel sample data for channel ... for scanline 1
+ // pixel sample data for channel n for scanline 1
+ // ...
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const unsigned short *line_ptr = reinterpret_cast<unsigned short *>(
+ &outBuf.at(v * pixel_data_size * static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ FP16 hf;
+
+ // hf.u = line_ptr[u];
+ // use `cpy` to avoid unaligned memory access when compiler's
+ // optimization is on.
+ tinyexr::cpy2(&(hf.u), line_ptr + u);
+
+ tinyexr::swap2(reinterpret_cast<unsigned short *>(&hf.u));
+
+ if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) {
+ unsigned short *image =
+ reinterpret_cast<unsigned short **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += static_cast<size_t>(
+ (height - 1 - (line_no + static_cast<int>(v)))) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = hf.u;
+ } else { // HALF -> FLOAT
+ FP32 f32 = half_to_float(hf);
+ float *image = reinterpret_cast<float **>(out_images)[c];
+ size_t offset = 0;
+ if (line_order == 0) {
+ offset = (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ offset = static_cast<size_t>(
+ (height - 1 - (line_no + static_cast<int>(v)))) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ image += offset;
+ *image = f32.f;
+ }
+ }
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) {
+ assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_UINT);
+
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const unsigned int *line_ptr = reinterpret_cast<unsigned int *>(
+ &outBuf.at(v * pixel_data_size * static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ unsigned int val;
+ // val = line_ptr[u];
+ tinyexr::cpy4(&val, line_ptr + u);
+
+ tinyexr::swap4(&val);
+
+ unsigned int *image =
+ reinterpret_cast<unsigned int **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += static_cast<size_t>(
+ (height - 1 - (line_no + static_cast<int>(v)))) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = val;
+ }
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT);
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const float *line_ptr = reinterpret_cast<float *>(&outBuf.at(
+ v * pixel_data_size * static_cast<size_t>(x_stride) +
+ channel_offset_list[c] * static_cast<size_t>(x_stride)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ float val;
+ // val = line_ptr[u];
+ tinyexr::cpy4(&val, line_ptr + u);
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+
+ float *image = reinterpret_cast<float **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += static_cast<size_t>(
+ (height - 1 - (line_no + static_cast<int>(v)))) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = val;
+ }
+ }
+ } else {
+ assert(0);
+ }
+ }
+#else
+ assert(0 && "PIZ is enabled in this build");
+ return false;
+#endif
+
+ } else if (compression_type == TINYEXR_COMPRESSIONTYPE_ZIPS ||
+ compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) {
+ // Allocate original data size.
+ std::vector<unsigned char> outBuf(static_cast<size_t>(width) *
+ static_cast<size_t>(num_lines) *
+ pixel_data_size);
+
+ unsigned long dstLen = static_cast<unsigned long>(outBuf.size());
+ assert(dstLen > 0);
+ if (!tinyexr::DecompressZip(
+ reinterpret_cast<unsigned char *>(&outBuf.at(0)), &dstLen, data_ptr,
+ static_cast<unsigned long>(data_len))) {
+ return false;
+ }
+
+ // For ZIP_COMPRESSION:
+ // pixel sample data for channel 0 for scanline 0
+ // pixel sample data for channel 1 for scanline 0
+ // pixel sample data for channel ... for scanline 0
+ // pixel sample data for channel n for scanline 0
+ // pixel sample data for channel 0 for scanline 1
+ // pixel sample data for channel 1 for scanline 1
+ // pixel sample data for channel ... for scanline 1
+ // pixel sample data for channel n for scanline 1
+ // ...
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const unsigned short *line_ptr = reinterpret_cast<unsigned short *>(
+ &outBuf.at(v * static_cast<size_t>(pixel_data_size) *
+ static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ tinyexr::FP16 hf;
+
+ // hf.u = line_ptr[u];
+ tinyexr::cpy2(&(hf.u), line_ptr + u);
+
+ tinyexr::swap2(reinterpret_cast<unsigned short *>(&hf.u));
+
+ if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) {
+ unsigned short *image =
+ reinterpret_cast<unsigned short **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = hf.u;
+ } else { // HALF -> FLOAT
+ tinyexr::FP32 f32 = half_to_float(hf);
+ float *image = reinterpret_cast<float **>(out_images)[c];
+ size_t offset = 0;
+ if (line_order == 0) {
+ offset = (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ offset = (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ image += offset;
+
+ *image = f32.f;
+ }
+ }
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) {
+ assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_UINT);
+
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const unsigned int *line_ptr = reinterpret_cast<unsigned int *>(
+ &outBuf.at(v * pixel_data_size * static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ unsigned int val;
+ // val = line_ptr[u];
+ tinyexr::cpy4(&val, line_ptr + u);
+
+ tinyexr::swap4(&val);
+
+ unsigned int *image =
+ reinterpret_cast<unsigned int **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = val;
+ }
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT);
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const float *line_ptr = reinterpret_cast<float *>(
+ &outBuf.at(v * pixel_data_size * static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ float val;
+ // val = line_ptr[u];
+ tinyexr::cpy4(&val, line_ptr + u);
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+
+ float *image = reinterpret_cast<float **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = val;
+ }
+ }
+ } else {
+ assert(0);
+ return false;
+ }
+ }
+ } else if (compression_type == TINYEXR_COMPRESSIONTYPE_RLE) {
+ // Allocate original data size.
+ std::vector<unsigned char> outBuf(static_cast<size_t>(width) *
+ static_cast<size_t>(num_lines) *
+ pixel_data_size);
+
+ unsigned long dstLen = static_cast<unsigned long>(outBuf.size());
+ if (dstLen == 0) {
+ return false;
+ }
+
+ if (!tinyexr::DecompressRle(
+ reinterpret_cast<unsigned char *>(&outBuf.at(0)), dstLen, data_ptr,
+ static_cast<unsigned long>(data_len))) {
+ return false;
+ }
+
+ // For RLE_COMPRESSION:
+ // pixel sample data for channel 0 for scanline 0
+ // pixel sample data for channel 1 for scanline 0
+ // pixel sample data for channel ... for scanline 0
+ // pixel sample data for channel n for scanline 0
+ // pixel sample data for channel 0 for scanline 1
+ // pixel sample data for channel 1 for scanline 1
+ // pixel sample data for channel ... for scanline 1
+ // pixel sample data for channel n for scanline 1
+ // ...
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const unsigned short *line_ptr = reinterpret_cast<unsigned short *>(
+ &outBuf.at(v * static_cast<size_t>(pixel_data_size) *
+ static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ tinyexr::FP16 hf;
+
+ // hf.u = line_ptr[u];
+ tinyexr::cpy2(&(hf.u), line_ptr + u);
+
+ tinyexr::swap2(reinterpret_cast<unsigned short *>(&hf.u));
+
+ if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) {
+ unsigned short *image =
+ reinterpret_cast<unsigned short **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = hf.u;
+ } else { // HALF -> FLOAT
+ tinyexr::FP32 f32 = half_to_float(hf);
+ float *image = reinterpret_cast<float **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = f32.f;
+ }
+ }
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) {
+ assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_UINT);
+
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const unsigned int *line_ptr = reinterpret_cast<unsigned int *>(
+ &outBuf.at(v * pixel_data_size * static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ unsigned int val;
+ // val = line_ptr[u];
+ tinyexr::cpy4(&val, line_ptr + u);
+
+ tinyexr::swap4(&val);
+
+ unsigned int *image =
+ reinterpret_cast<unsigned int **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = val;
+ }
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT);
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const float *line_ptr = reinterpret_cast<float *>(
+ &outBuf.at(v * pixel_data_size * static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ float val;
+ // val = line_ptr[u];
+ tinyexr::cpy4(&val, line_ptr + u);
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+
+ float *image = reinterpret_cast<float **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = val;
+ }
+ }
+ } else {
+ assert(0);
+ return false;
+ }
+ }
+ } else if (compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
+#if TINYEXR_USE_ZFP
+ tinyexr::ZFPCompressionParam zfp_compression_param;
+ std::string e;
+ if (!tinyexr::FindZFPCompressionParam(&zfp_compression_param, attributes,
+ int(num_attributes), &e)) {
+ // This code path should not be reachable.
+ assert(0);
+ return false;
+ }
+
+ // Allocate original data size.
+ std::vector<unsigned char> outBuf(static_cast<size_t>(width) *
+ static_cast<size_t>(num_lines) *
+ pixel_data_size);
+
+ unsigned long dstLen = outBuf.size();
+ assert(dstLen > 0);
+ tinyexr::DecompressZfp(reinterpret_cast<float *>(&outBuf.at(0)), width,
+ num_lines, num_channels, data_ptr,
+ static_cast<unsigned long>(data_len),
+ zfp_compression_param);
+
+ // For ZFP_COMPRESSION:
+ // pixel sample data for channel 0 for scanline 0
+ // pixel sample data for channel 1 for scanline 0
+ // pixel sample data for channel ... for scanline 0
+ // pixel sample data for channel n for scanline 0
+ // pixel sample data for channel 0 for scanline 1
+ // pixel sample data for channel 1 for scanline 1
+ // pixel sample data for channel ... for scanline 1
+ // pixel sample data for channel n for scanline 1
+ // ...
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+ assert(channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT);
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT);
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const float *line_ptr = reinterpret_cast<float *>(
+ &outBuf.at(v * pixel_data_size * static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ float val;
+ tinyexr::cpy4(&val, line_ptr + u);
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+
+ float *image = reinterpret_cast<float **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = val;
+ }
+ }
+ } else {
+ assert(0);
+ return false;
+ }
+ }
+#else
+ (void)attributes;
+ (void)num_attributes;
+ (void)num_channels;
+ assert(0);
+ return false;
+#endif
+ } else if (compression_type == TINYEXR_COMPRESSIONTYPE_NONE) {
+ for (size_t c = 0; c < num_channels; c++) {
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ const unsigned short *line_ptr =
+ reinterpret_cast<const unsigned short *>(
+ data_ptr + v * pixel_data_size * size_t(width) +
+ channel_offset_list[c] * static_cast<size_t>(width));
+
+ if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) {
+ unsigned short *outLine =
+ reinterpret_cast<unsigned short *>(out_images[c]);
+ if (line_order == 0) {
+ outLine += (size_t(y) + v) * size_t(x_stride);
+ } else {
+ outLine +=
+ (size_t(height) - 1 - (size_t(y) + v)) * size_t(x_stride);
+ }
+
+ for (int u = 0; u < width; u++) {
+ tinyexr::FP16 hf;
+
+ // hf.u = line_ptr[u];
+ tinyexr::cpy2(&(hf.u), line_ptr + u);
+
+ tinyexr::swap2(reinterpret_cast<unsigned short *>(&hf.u));
+
+ outLine[u] = hf.u;
+ }
+ } else if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) {
+ float *outLine = reinterpret_cast<float *>(out_images[c]);
+ if (line_order == 0) {
+ outLine += (size_t(y) + v) * size_t(x_stride);
+ } else {
+ outLine +=
+ (size_t(height) - 1 - (size_t(y) + v)) * size_t(x_stride);
+ }
+
+ if (reinterpret_cast<const unsigned char *>(line_ptr + width) >
+ (data_ptr + data_len)) {
+ // Insufficient data size
+ return false;
+ }
+
+ for (int u = 0; u < width; u++) {
+ tinyexr::FP16 hf;
+
+ // address may not be aliged. use byte-wise copy for safety.#76
+ // hf.u = line_ptr[u];
+ tinyexr::cpy2(&(hf.u), line_ptr + u);
+
+ tinyexr::swap2(reinterpret_cast<unsigned short *>(&hf.u));
+
+ tinyexr::FP32 f32 = half_to_float(hf);
+
+ outLine[u] = f32.f;
+ }
+ } else {
+ assert(0);
+ return false;
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ const float *line_ptr = reinterpret_cast<const float *>(
+ data_ptr + v * pixel_data_size * size_t(width) +
+ channel_offset_list[c] * static_cast<size_t>(width));
+
+ float *outLine = reinterpret_cast<float *>(out_images[c]);
+ if (line_order == 0) {
+ outLine += (size_t(y) + v) * size_t(x_stride);
+ } else {
+ outLine +=
+ (size_t(height) - 1 - (size_t(y) + v)) * size_t(x_stride);
+ }
+
+ if (reinterpret_cast<const unsigned char *>(line_ptr + width) >
+ (data_ptr + data_len)) {
+ // Insufficient data size
+ return false;
+ }
+
+ for (int u = 0; u < width; u++) {
+ float val;
+ tinyexr::cpy4(&val, line_ptr + u);
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+
+ outLine[u] = val;
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) {
+ const unsigned int *line_ptr = reinterpret_cast<const unsigned int *>(
+ data_ptr + v * pixel_data_size * size_t(width) +
+ channel_offset_list[c] * static_cast<size_t>(width));
+
+ unsigned int *outLine =
+ reinterpret_cast<unsigned int *>(out_images[c]);
+ if (line_order == 0) {
+ outLine += (size_t(y) + v) * size_t(x_stride);
+ } else {
+ outLine +=
+ (size_t(height) - 1 - (size_t(y) + v)) * size_t(x_stride);
+ }
+
+ for (int u = 0; u < width; u++) {
+ if (reinterpret_cast<const unsigned char *>(line_ptr + u) >=
+ (data_ptr + data_len)) {
+ // Corrupsed data?
+ return false;
+ }
+
+ unsigned int val;
+ tinyexr::cpy4(&val, line_ptr + u);
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+
+ outLine[u] = val;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+static bool DecodeTiledPixelData(
+ unsigned char **out_images, int *width, int *height,
+ const int *requested_pixel_types, const unsigned char *data_ptr,
+ size_t data_len, int compression_type, int line_order, int data_width,
+ int data_height, int tile_offset_x, int tile_offset_y, int tile_size_x,
+ int tile_size_y, size_t pixel_data_size, size_t num_attributes,
+ const EXRAttribute *attributes, size_t num_channels,
+ const EXRChannelInfo *channels,
+ const std::vector<size_t> &channel_offset_list) {
+ // Here, data_width and data_height are the dimensions of the current (sub)level.
+ if (tile_size_x * tile_offset_x > data_width ||
+ tile_size_y * tile_offset_y > data_height) {
+ return false;
+ }
+
+ // Compute actual image size in a tile.
+ if ((tile_offset_x + 1) * tile_size_x >= data_width) {
+ (*width) = data_width - (tile_offset_x * tile_size_x);
+ } else {
+ (*width) = tile_size_x;
+ }
+
+ if ((tile_offset_y + 1) * tile_size_y >= data_height) {
+ (*height) = data_height - (tile_offset_y * tile_size_y);
+ } else {
+ (*height) = tile_size_y;
+ }
+
+ // Image size = tile size.
+ return DecodePixelData(out_images, requested_pixel_types, data_ptr, data_len,
+ compression_type, line_order, (*width), tile_size_y,
+ /* stride */ tile_size_x, /* y */ 0, /* line_no */ 0,
+ (*height), pixel_data_size, num_attributes, attributes,
+ num_channels, channels, channel_offset_list);
+}
+
+static bool ComputeChannelLayout(std::vector<size_t> *channel_offset_list,
+ int *pixel_data_size, size_t *channel_offset,
+ int num_channels,
+ const EXRChannelInfo *channels) {
+ channel_offset_list->resize(static_cast<size_t>(num_channels));
+
+ (*pixel_data_size) = 0;
+ (*channel_offset) = 0;
+
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+ (*channel_offset_list)[c] = (*channel_offset);
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ (*pixel_data_size) += sizeof(unsigned short);
+ (*channel_offset) += sizeof(unsigned short);
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ (*pixel_data_size) += sizeof(float);
+ (*channel_offset) += sizeof(float);
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) {
+ (*pixel_data_size) += sizeof(unsigned int);
+ (*channel_offset) += sizeof(unsigned int);
+ } else {
+ // ???
+ return false;
+ }
+ }
+ return true;
+}
+
+static unsigned char **AllocateImage(int num_channels,
+ const EXRChannelInfo *channels,
+ const int *requested_pixel_types,
+ int data_width, int data_height) {
+ unsigned char **images =
+ reinterpret_cast<unsigned char **>(static_cast<float **>(
+ malloc(sizeof(float *) * static_cast<size_t>(num_channels))));
+
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+ size_t data_len =
+ static_cast<size_t>(data_width) * static_cast<size_t>(data_height);
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ // pixel_data_size += sizeof(unsigned short);
+ // channel_offset += sizeof(unsigned short);
+ // Alloc internal image for half type.
+ if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) {
+ images[c] =
+ reinterpret_cast<unsigned char *>(static_cast<unsigned short *>(
+ malloc(sizeof(unsigned short) * data_len)));
+ } else if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) {
+ images[c] = reinterpret_cast<unsigned char *>(
+ static_cast<float *>(malloc(sizeof(float) * data_len)));
+ } else {
+ assert(0);
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ // pixel_data_size += sizeof(float);
+ // channel_offset += sizeof(float);
+ images[c] = reinterpret_cast<unsigned char *>(
+ static_cast<float *>(malloc(sizeof(float) * data_len)));
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) {
+ // pixel_data_size += sizeof(unsigned int);
+ // channel_offset += sizeof(unsigned int);
+ images[c] = reinterpret_cast<unsigned char *>(
+ static_cast<unsigned int *>(malloc(sizeof(unsigned int) * data_len)));
+ } else {
+ assert(0);
+ }
+ }
+
+ return images;
+}
+
+#ifdef _WIN32
+static inline std::wstring UTF8ToWchar(const std::string &str) {
+ int wstr_size =
+ MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), NULL, 0);
+ std::wstring wstr(wstr_size, 0);
+ MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), &wstr[0],
+ (int)wstr.size());
+ return wstr;
+}
+#endif
+
+
+static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
+ const EXRVersion *version, std::string *err,
+ const unsigned char *buf, size_t size) {
+ const char *marker = reinterpret_cast<const char *>(&buf[0]);
+
+ if (empty_header) {
+ (*empty_header) = false;
+ }
+
+ if (version->multipart) {
+ if (size > 0 && marker[0] == '\0') {
+ // End of header list.
+ if (empty_header) {
+ (*empty_header) = true;
+ }
+ return TINYEXR_SUCCESS;
+ }
+ }
+
+ // According to the spec, the header of every OpenEXR file must contain at
+ // least the following attributes:
+ //
+ // channels chlist
+ // compression compression
+ // dataWindow box2i
+ // displayWindow box2i
+ // lineOrder lineOrder
+ // pixelAspectRatio float
+ // screenWindowCenter v2f
+ // screenWindowWidth float
+ bool has_channels = false;
+ bool has_compression = false;
+ bool has_data_window = false;
+ bool has_display_window = false;
+ bool has_line_order = false;
+ bool has_pixel_aspect_ratio = false;
+ bool has_screen_window_center = false;
+ bool has_screen_window_width = false;
+ bool has_name = false;
+ bool has_type = false;
+
+ info->name.clear();
+ info->type.clear();
+
+ info->data_window.min_x = 0;
+ info->data_window.min_y = 0;
+ info->data_window.max_x = 0;
+ info->data_window.max_y = 0;
+ info->line_order = 0; // @fixme
+ info->display_window.min_x = 0;
+ info->display_window.min_y = 0;
+ info->display_window.max_x = 0;
+ info->display_window.max_y = 0;
+ info->screen_window_center[0] = 0.0f;
+ info->screen_window_center[1] = 0.0f;
+ info->screen_window_width = -1.0f;
+ info->pixel_aspect_ratio = -1.0f;
+
+ info->tiled = 0;
+ info->tile_size_x = -1;
+ info->tile_size_y = -1;
+ info->tile_level_mode = -1;
+ info->tile_rounding_mode = -1;
+
+ info->attributes.clear();
+
+ // Read attributes
+ size_t orig_size = size;
+ for (size_t nattr = 0; nattr < TINYEXR_MAX_HEADER_ATTRIBUTES; nattr++) {
+ if (0 == size) {
+ if (err) {
+ (*err) += "Insufficient data size for attributes.\n";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ } else if (marker[0] == '\0') {
+ size--;
+ break;
+ }
+
+ std::string attr_name;
+ std::string attr_type;
+ std::vector<unsigned char> data;
+ size_t marker_size;
+ if (!tinyexr::ReadAttribute(&attr_name, &attr_type, &data, &marker_size,
+ marker, size)) {
+ if (err) {
+ (*err) += "Failed to read attribute.\n";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ marker += marker_size;
+ size -= marker_size;
+
+ // For a multipart file, the version field 9th bit is 0.
+ if ((version->tiled || version->multipart || version->non_image) && attr_name.compare("tiles") == 0) {
+ unsigned int x_size, y_size;
+ unsigned char tile_mode;
+ assert(data.size() == 9);
+ memcpy(&x_size, &data.at(0), sizeof(int));
+ memcpy(&y_size, &data.at(4), sizeof(int));
+ tile_mode = data[8];
+ tinyexr::swap4(&x_size);
+ tinyexr::swap4(&y_size);
+
+ if (x_size > static_cast<unsigned int>(std::numeric_limits<int>::max()) ||
+ y_size > static_cast<unsigned int>(std::numeric_limits<int>::max())) {
+ if (err) {
+ (*err) = "Tile sizes were invalid.";
+ }
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+ }
+
+ info->tile_size_x = static_cast<int>(x_size);
+ info->tile_size_y = static_cast<int>(y_size);
+
+ // mode = levelMode + roundingMode * 16
+ info->tile_level_mode = tile_mode & 0x3;
+ info->tile_rounding_mode = (tile_mode >> 4) & 0x1;
+ info->tiled = 1;
+ } else if (attr_name.compare("compression") == 0) {
+ bool ok = false;
+ if (data[0] < TINYEXR_COMPRESSIONTYPE_PIZ) {
+ ok = true;
+ }
+
+ if (data[0] == TINYEXR_COMPRESSIONTYPE_PIZ) {
+#if TINYEXR_USE_PIZ
+ ok = true;
+#else
+ if (err) {
+ (*err) = "PIZ compression is not supported.";
+ }
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+#endif
+ }
+
+ if (data[0] == TINYEXR_COMPRESSIONTYPE_ZFP) {
+#if TINYEXR_USE_ZFP
+ ok = true;
+#else
+ if (err) {
+ (*err) = "ZFP compression is not supported.";
+ }
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+#endif
+ }
+
+ if (!ok) {
+ if (err) {
+ (*err) = "Unknown compression type.";
+ }
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+ }
+
+ info->compression_type = static_cast<int>(data[0]);
+ has_compression = true;
+
+ } else if (attr_name.compare("channels") == 0) {
+ // name: zero-terminated string, from 1 to 255 bytes long
+ // pixel type: int, possible values are: UINT = 0 HALF = 1 FLOAT = 2
+ // pLinear: unsigned char, possible values are 0 and 1
+ // reserved: three chars, should be zero
+ // xSampling: int
+ // ySampling: int
+
+ if (!ReadChannelInfo(info->channels, data)) {
+ if (err) {
+ (*err) += "Failed to parse channel info.\n";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ if (info->channels.size() < 1) {
+ if (err) {
+ (*err) += "# of channels is zero.\n";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ has_channels = true;
+
+ } else if (attr_name.compare("dataWindow") == 0) {
+ if (data.size() >= 16) {
+ memcpy(&info->data_window.min_x, &data.at(0), sizeof(int));
+ memcpy(&info->data_window.min_y, &data.at(4), sizeof(int));
+ memcpy(&info->data_window.max_x, &data.at(8), sizeof(int));
+ memcpy(&info->data_window.max_y, &data.at(12), sizeof(int));
+ tinyexr::swap4(&info->data_window.min_x);
+ tinyexr::swap4(&info->data_window.min_y);
+ tinyexr::swap4(&info->data_window.max_x);
+ tinyexr::swap4(&info->data_window.max_y);
+ has_data_window = true;
+ }
+ } else if (attr_name.compare("displayWindow") == 0) {
+ if (data.size() >= 16) {
+ memcpy(&info->display_window.min_x, &data.at(0), sizeof(int));
+ memcpy(&info->display_window.min_y, &data.at(4), sizeof(int));
+ memcpy(&info->display_window.max_x, &data.at(8), sizeof(int));
+ memcpy(&info->display_window.max_y, &data.at(12), sizeof(int));
+ tinyexr::swap4(&info->display_window.min_x);
+ tinyexr::swap4(&info->display_window.min_y);
+ tinyexr::swap4(&info->display_window.max_x);
+ tinyexr::swap4(&info->display_window.max_y);
+
+ has_display_window = true;
+ }
+ } else if (attr_name.compare("lineOrder") == 0) {
+ if (data.size() >= 1) {
+ info->line_order = static_cast<int>(data[0]);
+ has_line_order = true;
+ }
+ } else if (attr_name.compare("pixelAspectRatio") == 0) {
+ if (data.size() >= sizeof(float)) {
+ memcpy(&info->pixel_aspect_ratio, &data.at(0), sizeof(float));
+ tinyexr::swap4(&info->pixel_aspect_ratio);
+ has_pixel_aspect_ratio = true;
+ }
+ } else if (attr_name.compare("screenWindowCenter") == 0) {
+ if (data.size() >= 8) {
+ memcpy(&info->screen_window_center[0], &data.at(0), sizeof(float));
+ memcpy(&info->screen_window_center[1], &data.at(4), sizeof(float));
+ tinyexr::swap4(&info->screen_window_center[0]);
+ tinyexr::swap4(&info->screen_window_center[1]);
+ has_screen_window_center = true;
+ }
+ } else if (attr_name.compare("screenWindowWidth") == 0) {
+ if (data.size() >= sizeof(float)) {
+ memcpy(&info->screen_window_width, &data.at(0), sizeof(float));
+ tinyexr::swap4(&info->screen_window_width);
+
+ has_screen_window_width = true;
+ }
+ } else if (attr_name.compare("chunkCount") == 0) {
+ if (data.size() >= sizeof(int)) {
+ memcpy(&info->chunk_count, &data.at(0), sizeof(int));
+ tinyexr::swap4(&info->chunk_count);
+ }
+ } else if (attr_name.compare("name") == 0) {
+ if (!data.empty() && data[0]) {
+ data.push_back(0);
+ size_t len = strlen(reinterpret_cast<const char*>(&data[0]));
+ info->name.resize(len);
+ info->name.assign(reinterpret_cast<const char*>(&data[0]), len);
+ has_name = true;
+ }
+ } else if (attr_name.compare("type") == 0) {
+ if (!data.empty() && data[0]) {
+ data.push_back(0);
+ size_t len = strlen(reinterpret_cast<const char*>(&data[0]));
+ info->type.resize(len);
+ info->type.assign(reinterpret_cast<const char*>(&data[0]), len);
+ has_type = true;
+ }
+ } else {
+ // Custom attribute(up to TINYEXR_MAX_CUSTOM_ATTRIBUTES)
+ if (info->attributes.size() < TINYEXR_MAX_CUSTOM_ATTRIBUTES) {
+ EXRAttribute attrib;
+#ifdef _MSC_VER
+ strncpy_s(attrib.name, attr_name.c_str(), 255);
+ strncpy_s(attrib.type, attr_type.c_str(), 255);
+#else
+ strncpy(attrib.name, attr_name.c_str(), 255);
+ strncpy(attrib.type, attr_type.c_str(), 255);
+#endif
+ attrib.name[255] = '\0';
+ attrib.type[255] = '\0';
+ attrib.size = static_cast<int>(data.size());
+ attrib.value = static_cast<unsigned char *>(malloc(data.size()));
+ memcpy(reinterpret_cast<char *>(attrib.value), &data.at(0),
+ data.size());
+ info->attributes.push_back(attrib);
+ }
+ }
+ }
+
+ // Check if required attributes exist
+ {
+ std::stringstream ss_err;
+
+ if (!has_compression) {
+ ss_err << "\"compression\" attribute not found in the header."
+ << std::endl;
+ }
+
+ if (!has_channels) {
+ ss_err << "\"channels\" attribute not found in the header." << std::endl;
+ }
+
+ if (!has_line_order) {
+ ss_err << "\"lineOrder\" attribute not found in the header." << std::endl;
+ }
+
+ if (!has_display_window) {
+ ss_err << "\"displayWindow\" attribute not found in the header."
+ << std::endl;
+ }
+
+ if (!has_data_window) {
+ ss_err << "\"dataWindow\" attribute not found in the header or invalid."
+ << std::endl;
+ }
+
+ if (!has_pixel_aspect_ratio) {
+ ss_err << "\"pixelAspectRatio\" attribute not found in the header."
+ << std::endl;
+ }
+
+ if (!has_screen_window_width) {
+ ss_err << "\"screenWindowWidth\" attribute not found in the header."
+ << std::endl;
+ }
+
+ if (!has_screen_window_center) {
+ ss_err << "\"screenWindowCenter\" attribute not found in the header."
+ << std::endl;
+ }
+
+ if (version->multipart || version->non_image) {
+ if (!has_name) {
+ ss_err << "\"name\" attribute not found in the header."
+ << std::endl;
+ }
+ if (!has_type) {
+ ss_err << "\"type\" attribute not found in the header."
+ << std::endl;
+ }
+ }
+
+ if (!(ss_err.str().empty())) {
+ if (err) {
+ (*err) += ss_err.str();
+ }
+ return TINYEXR_ERROR_INVALID_HEADER;
+ }
+ }
+
+ info->header_len = static_cast<unsigned int>(orig_size - size);
+
+ return TINYEXR_SUCCESS;
+}
+
+// C++ HeaderInfo to C EXRHeader conversion.
+static void ConvertHeader(EXRHeader *exr_header, const HeaderInfo &info) {
+ exr_header->pixel_aspect_ratio = info.pixel_aspect_ratio;
+ exr_header->screen_window_center[0] = info.screen_window_center[0];
+ exr_header->screen_window_center[1] = info.screen_window_center[1];
+ exr_header->screen_window_width = info.screen_window_width;
+ exr_header->chunk_count = info.chunk_count;
+ exr_header->display_window.min_x = info.display_window.min_x;
+ exr_header->display_window.min_y = info.display_window.min_y;
+ exr_header->display_window.max_x = info.display_window.max_x;
+ exr_header->display_window.max_y = info.display_window.max_y;
+ exr_header->data_window.min_x = info.data_window.min_x;
+ exr_header->data_window.min_y = info.data_window.min_y;
+ exr_header->data_window.max_x = info.data_window.max_x;
+ exr_header->data_window.max_y = info.data_window.max_y;
+ exr_header->line_order = info.line_order;
+ exr_header->compression_type = info.compression_type;
+ exr_header->tiled = info.tiled;
+ exr_header->tile_size_x = info.tile_size_x;
+ exr_header->tile_size_y = info.tile_size_y;
+ exr_header->tile_level_mode = info.tile_level_mode;
+ exr_header->tile_rounding_mode = info.tile_rounding_mode;
+
+ EXRSetNameAttr(exr_header, info.name.c_str());
+
+ if (!info.type.empty()) {
+ if (info.type == "scanlineimage") {
+ assert(!exr_header->tiled);
+ } else if (info.type == "tiledimage") {
+ assert(exr_header->tiled);
+ } else if (info.type == "deeptile") {
+ exr_header->non_image = 1;
+ assert(exr_header->tiled);
+ } else if (info.type == "deepscanline") {
+ exr_header->non_image = 1;
+ assert(!exr_header->tiled);
+ } else {
+ assert(false);
+ }
+ }
+
+ exr_header->num_channels = static_cast<int>(info.channels.size());
+
+ exr_header->channels = static_cast<EXRChannelInfo *>(malloc(
+ sizeof(EXRChannelInfo) * static_cast<size_t>(exr_header->num_channels)));
+ for (size_t c = 0; c < static_cast<size_t>(exr_header->num_channels); c++) {
+#ifdef _MSC_VER
+ strncpy_s(exr_header->channels[c].name, info.channels[c].name.c_str(), 255);
+#else
+ strncpy(exr_header->channels[c].name, info.channels[c].name.c_str(), 255);
+#endif
+ // manually add '\0' for safety.
+ exr_header->channels[c].name[255] = '\0';
+
+ exr_header->channels[c].pixel_type = info.channels[c].pixel_type;
+ exr_header->channels[c].p_linear = info.channels[c].p_linear;
+ exr_header->channels[c].x_sampling = info.channels[c].x_sampling;
+ exr_header->channels[c].y_sampling = info.channels[c].y_sampling;
+ }
+
+ exr_header->pixel_types = static_cast<int *>(
+ malloc(sizeof(int) * static_cast<size_t>(exr_header->num_channels)));
+ for (size_t c = 0; c < static_cast<size_t>(exr_header->num_channels); c++) {
+ exr_header->pixel_types[c] = info.channels[c].pixel_type;
+ }
+
+ // Initially fill with values of `pixel_types`
+ exr_header->requested_pixel_types = static_cast<int *>(
+ malloc(sizeof(int) * static_cast<size_t>(exr_header->num_channels)));
+ for (size_t c = 0; c < static_cast<size_t>(exr_header->num_channels); c++) {
+ exr_header->requested_pixel_types[c] = info.channels[c].pixel_type;
+ }
+
+ exr_header->num_custom_attributes = static_cast<int>(info.attributes.size());
+
+ if (exr_header->num_custom_attributes > 0) {
+ // TODO(syoyo): Report warning when # of attributes exceeds
+ // `TINYEXR_MAX_CUSTOM_ATTRIBUTES`
+ if (exr_header->num_custom_attributes > TINYEXR_MAX_CUSTOM_ATTRIBUTES) {
+ exr_header->num_custom_attributes = TINYEXR_MAX_CUSTOM_ATTRIBUTES;
+ }
+
+ exr_header->custom_attributes = static_cast<EXRAttribute *>(malloc(
+ sizeof(EXRAttribute) * size_t(exr_header->num_custom_attributes)));
+
+ for (size_t i = 0; i < info.attributes.size(); i++) {
+ memcpy(exr_header->custom_attributes[i].name, info.attributes[i].name,
+ 256);
+ memcpy(exr_header->custom_attributes[i].type, info.attributes[i].type,
+ 256);
+ exr_header->custom_attributes[i].size = info.attributes[i].size;
+ // Just copy pointer
+ exr_header->custom_attributes[i].value = info.attributes[i].value;
+ }
+
+ } else {
+ exr_header->custom_attributes = NULL;
+ }
+
+ exr_header->header_len = info.header_len;
+}
+
+struct OffsetData {
+ OffsetData() : num_x_levels(0), num_y_levels(0) {}
+ std::vector<std::vector<std::vector <tinyexr::tinyexr_uint64> > > offsets;
+ int num_x_levels;
+ int num_y_levels;
+};
+
+int LevelIndex(int lx, int ly, int tile_level_mode, int num_x_levels) {
+ switch (tile_level_mode) {
+ case TINYEXR_TILE_ONE_LEVEL:
+ return 0;
+
+ case TINYEXR_TILE_MIPMAP_LEVELS:
+ return lx;
+
+ case TINYEXR_TILE_RIPMAP_LEVELS:
+ return lx + ly * num_x_levels;
+
+ default:
+ assert(false);
+ }
+ return 0;
+}
+
+static int LevelSize(int toplevel_size, int level, int tile_rounding_mode) {
+ assert(level >= 0);
+
+ int b = (int)(1u << (unsigned)level);
+ int level_size = toplevel_size / b;
+
+ if (tile_rounding_mode == TINYEXR_TILE_ROUND_UP && level_size * b < toplevel_size)
+ level_size += 1;
+
+ return std::max(level_size, 1);
+}
+
+static int DecodeTiledLevel(EXRImage* exr_image, const EXRHeader* exr_header,
+ const OffsetData& offset_data,
+ const std::vector<size_t>& channel_offset_list,
+ int pixel_data_size,
+ const unsigned char* head, const size_t size,
+ std::string* err) {
+ int num_channels = exr_header->num_channels;
+
+ int level_index = LevelIndex(exr_image->level_x, exr_image->level_y, exr_header->tile_level_mode, offset_data.num_x_levels);
+ int num_y_tiles = (int)offset_data.offsets[level_index].size();
+ assert(num_y_tiles);
+ int num_x_tiles = (int)offset_data.offsets[level_index][0].size();
+ assert(num_x_tiles);
+ int num_tiles = num_x_tiles * num_y_tiles;
+
+ int err_code = TINYEXR_SUCCESS;
+
+ enum {
+ EF_SUCCESS = 0,
+ EF_INVALID_DATA = 1,
+ EF_INSUFFICIENT_DATA = 2,
+ EF_FAILED_TO_DECODE = 4
+ };
+#if TINYEXR_HAS_CXX11 && (TINYEXR_USE_THREAD > 0)
+ std::atomic<unsigned> error_flag(EF_SUCCESS);
+#else
+ unsigned error_flag(EF_SUCCESS);
+#endif
+
+ // Although the spec says : "...the data window is subdivided into an array of smaller rectangles...",
+ // the IlmImf library allows the dimensions of the tile to be larger (or equal) than the dimensions of the data window.
+#if 0
+ if ((exr_header->tile_size_x > exr_image->width || exr_header->tile_size_y > exr_image->height) &&
+ exr_image->level_x == 0 && exr_image->level_y == 0) {
+ if (err) {
+ (*err) += "Failed to decode tile data.\n";
+ }
+ err_code = TINYEXR_ERROR_INVALID_DATA;
+ }
+#endif
+ exr_image->tiles = static_cast<EXRTile*>(
+ calloc(sizeof(EXRTile), static_cast<size_t>(num_tiles)));
+
+#if TINYEXR_HAS_CXX11 && (TINYEXR_USE_THREAD > 0)
+ std::vector<std::thread> workers;
+ std::atomic<int> tile_count(0);
+
+ int num_threads = std::max(1, int(std::thread::hardware_concurrency()));
+ if (num_threads > int(num_tiles)) {
+ num_threads = int(num_tiles);
+ }
+
+ for (int t = 0; t < num_threads; t++) {
+ workers.emplace_back(std::thread([&]()
+ {
+ int tile_idx = 0;
+ while ((tile_idx = tile_count++) < num_tiles) {
+
+#else
+#if TINYEXR_USE_OPENMP
+#pragma omp parallel for
+#endif
+ for (int tile_idx = 0; tile_idx < num_tiles; tile_idx++) {
+#endif
+ // Allocate memory for each tile.
+ exr_image->tiles[tile_idx].images = tinyexr::AllocateImage(
+ num_channels, exr_header->channels,
+ exr_header->requested_pixel_types, exr_header->tile_size_x,
+ exr_header->tile_size_y);
+
+ int x_tile = tile_idx % num_x_tiles;
+ int y_tile = tile_idx / num_x_tiles;
+ // 16 byte: tile coordinates
+ // 4 byte : data size
+ // ~ : data(uncompressed or compressed)
+ tinyexr::tinyexr_uint64 offset = offset_data.offsets[level_index][y_tile][x_tile];
+ if (offset + sizeof(int) * 5 > size) {
+ // Insufficient data size.
+ error_flag |= EF_INSUFFICIENT_DATA;
+ continue;
+ }
+
+ size_t data_size =
+ size_t(size - (offset + sizeof(int) * 5));
+ const unsigned char* data_ptr =
+ reinterpret_cast<const unsigned char*>(head + offset);
+
+ int tile_coordinates[4];
+ memcpy(tile_coordinates, data_ptr, sizeof(int) * 4);
+ tinyexr::swap4(&tile_coordinates[0]);
+ tinyexr::swap4(&tile_coordinates[1]);
+ tinyexr::swap4(&tile_coordinates[2]);
+ tinyexr::swap4(&tile_coordinates[3]);
+
+ if (tile_coordinates[2] != exr_image->level_x) {
+ // Invalid data.
+ error_flag |= EF_INVALID_DATA;
+ continue;
+ }
+ if (tile_coordinates[3] != exr_image->level_y) {
+ // Invalid data.
+ error_flag |= EF_INVALID_DATA;
+ continue;
+ }
+
+ int data_len;
+ memcpy(&data_len, data_ptr + 16,
+ sizeof(int)); // 16 = sizeof(tile_coordinates)
+ tinyexr::swap4(&data_len);
+
+ if (data_len < 2 || size_t(data_len) > data_size) {
+ // Insufficient data size.
+ error_flag |= EF_INSUFFICIENT_DATA;
+ continue;
+ }
+
+ // Move to data addr: 20 = 16 + 4;
+ data_ptr += 20;
+ bool ret = tinyexr::DecodeTiledPixelData(
+ exr_image->tiles[tile_idx].images,
+ &(exr_image->tiles[tile_idx].width),
+ &(exr_image->tiles[tile_idx].height),
+ exr_header->requested_pixel_types, data_ptr,
+ static_cast<size_t>(data_len), exr_header->compression_type,
+ exr_header->line_order,
+ exr_image->width, exr_image->height,
+ tile_coordinates[0], tile_coordinates[1], exr_header->tile_size_x,
+ exr_header->tile_size_y, static_cast<size_t>(pixel_data_size),
+ static_cast<size_t>(exr_header->num_custom_attributes),
+ exr_header->custom_attributes,
+ static_cast<size_t>(exr_header->num_channels),
+ exr_header->channels, channel_offset_list);
+
+ if (!ret) {
+ // Failed to decode tile data.
+ error_flag |= EF_FAILED_TO_DECODE;
+ }
+
+ exr_image->tiles[tile_idx].offset_x = tile_coordinates[0];
+ exr_image->tiles[tile_idx].offset_y = tile_coordinates[1];
+ exr_image->tiles[tile_idx].level_x = tile_coordinates[2];
+ exr_image->tiles[tile_idx].level_y = tile_coordinates[3];
+
+#if TINYEXR_HAS_CXX11 && (TINYEXR_USE_THREAD > 0)
+ }
+ }));
+ } // num_thread loop
+
+ for (auto& t : workers) {
+ t.join();
+ }
+
+#else
+ } // parallel for
+#endif
+
+ // Even in the event of an error, the reserved memory may be freed.
+ exr_image->num_channels = num_channels;
+ exr_image->num_tiles = static_cast<int>(num_tiles);
+
+ if (error_flag) err_code = TINYEXR_ERROR_INVALID_DATA;
+ if (err) {
+ if (error_flag & EF_INSUFFICIENT_DATA) {
+ (*err) += "Insufficient data length.\n";
+ }
+ if (error_flag & EF_FAILED_TO_DECODE) {
+ (*err) += "Failed to decode tile data.\n";
+ }
+ }
+ return err_code;
+}
+
+static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
+ const OffsetData& offset_data,
+ const unsigned char *head, const size_t size,
+ std::string *err) {
+ int num_channels = exr_header->num_channels;
+
+ int num_scanline_blocks = 1;
+ if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) {
+ num_scanline_blocks = 16;
+ } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
+ num_scanline_blocks = 32;
+ } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
+ num_scanline_blocks = 16;
+
+#if TINYEXR_USE_ZFP
+ tinyexr::ZFPCompressionParam zfp_compression_param;
+ if (!FindZFPCompressionParam(&zfp_compression_param,
+ exr_header->custom_attributes,
+ int(exr_header->num_custom_attributes), err)) {
+ return TINYEXR_ERROR_INVALID_HEADER;
+ }
+#endif
+ }
+
+ if (exr_header->data_window.max_x < exr_header->data_window.min_x ||
+ exr_header->data_window.max_y < exr_header->data_window.min_y) {
+ if (err) {
+ (*err) += "Invalid data window.\n";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ int data_width =
+ exr_header->data_window.max_x - exr_header->data_window.min_x + 1;
+ int data_height =
+ exr_header->data_window.max_y - exr_header->data_window.min_y + 1;
+
+ // Do not allow too large data_width and data_height. header invalid?
+ {
+ if ((data_width > TINYEXR_DIMENSION_THRESHOLD) || (data_height > TINYEXR_DIMENSION_THRESHOLD)) {
+ if (err) {
+ std::stringstream ss;
+ ss << "data_with or data_height too large. data_width: " << data_width
+ << ", "
+ << "data_height = " << data_height << std::endl;
+ (*err) += ss.str();
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ if (exr_header->tiled) {
+ if ((exr_header->tile_size_x > TINYEXR_DIMENSION_THRESHOLD) || (exr_header->tile_size_y > TINYEXR_DIMENSION_THRESHOLD)) {
+ if (err) {
+ std::stringstream ss;
+ ss << "tile with or tile height too large. tile width: " << exr_header->tile_size_x
+ << ", "
+ << "tile height = " << exr_header->tile_size_y << std::endl;
+ (*err) += ss.str();
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ }
+ }
+
+ const std::vector<tinyexr::tinyexr_uint64>& offsets = offset_data.offsets[0][0];
+ size_t num_blocks = offsets.size();
+
+ std::vector<size_t> channel_offset_list;
+ int pixel_data_size = 0;
+ size_t channel_offset = 0;
+ if (!tinyexr::ComputeChannelLayout(&channel_offset_list, &pixel_data_size,
+ &channel_offset, num_channels,
+ exr_header->channels)) {
+ if (err) {
+ (*err) += "Failed to compute channel layout.\n";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+#if TINYEXR_HAS_CXX11 && (TINYEXR_USE_THREAD > 0)
+ std::atomic<bool> invalid_data(false);
+#else
+ bool invalid_data(false);
+#endif
+
+ if (exr_header->tiled) {
+ // value check
+ if (exr_header->tile_size_x < 0) {
+ if (err) {
+ std::stringstream ss;
+ ss << "Invalid tile size x : " << exr_header->tile_size_x << "\n";
+ (*err) += ss.str();
+ }
+ return TINYEXR_ERROR_INVALID_HEADER;
+ }
+
+ if (exr_header->tile_size_y < 0) {
+ if (err) {
+ std::stringstream ss;
+ ss << "Invalid tile size y : " << exr_header->tile_size_y << "\n";
+ (*err) += ss.str();
+ }
+ return TINYEXR_ERROR_INVALID_HEADER;
+ }
+ if (exr_header->tile_level_mode != TINYEXR_TILE_RIPMAP_LEVELS) {
+ EXRImage* level_image = NULL;
+ for (int level = 0; level < offset_data.num_x_levels; ++level) {
+ if (!level_image) {
+ level_image = exr_image;
+ } else {
+ level_image->next_level = new EXRImage;
+ InitEXRImage(level_image->next_level);
+ level_image = level_image->next_level;
+ }
+ level_image->width =
+ LevelSize(exr_header->data_window.max_x - exr_header->data_window.min_x + 1, level, exr_header->tile_rounding_mode);
+ level_image->height =
+ LevelSize(exr_header->data_window.max_y - exr_header->data_window.min_y + 1, level, exr_header->tile_rounding_mode);
+ level_image->level_x = level;
+ level_image->level_y = level;
+
+ int ret = DecodeTiledLevel(level_image, exr_header,
+ offset_data,
+ channel_offset_list,
+ pixel_data_size,
+ head, size,
+ err);
+ if (ret != TINYEXR_SUCCESS) return ret;
+ }
+ } else {
+ EXRImage* level_image = NULL;
+ for (int level_y = 0; level_y < offset_data.num_y_levels; ++level_y)
+ for (int level_x = 0; level_x < offset_data.num_x_levels; ++level_x) {
+ if (!level_image) {
+ level_image = exr_image;
+ } else {
+ level_image->next_level = new EXRImage;
+ InitEXRImage(level_image->next_level);
+ level_image = level_image->next_level;
+ }
+
+ level_image->width =
+ LevelSize(exr_header->data_window.max_x - exr_header->data_window.min_x + 1, level_x, exr_header->tile_rounding_mode);
+ level_image->height =
+ LevelSize(exr_header->data_window.max_y - exr_header->data_window.min_y + 1, level_y, exr_header->tile_rounding_mode);
+ level_image->level_x = level_x;
+ level_image->level_y = level_y;
+
+ int ret = DecodeTiledLevel(level_image, exr_header,
+ offset_data,
+ channel_offset_list,
+ pixel_data_size,
+ head, size,
+ err);
+ if (ret != TINYEXR_SUCCESS) return ret;
+ }
+ }
+ } else { // scanline format
+ // Don't allow too large image(256GB * pixel_data_size or more). Workaround
+ // for #104.
+ size_t total_data_len =
+ size_t(data_width) * size_t(data_height) * size_t(num_channels);
+ const bool total_data_len_overflown =
+ sizeof(void *) == 8 ? (total_data_len >= 0x4000000000) : false;
+ if ((total_data_len == 0) || total_data_len_overflown) {
+ if (err) {
+ std::stringstream ss;
+ ss << "Image data size is zero or too large: width = " << data_width
+ << ", height = " << data_height << ", channels = " << num_channels
+ << std::endl;
+ (*err) += ss.str();
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ exr_image->images = tinyexr::AllocateImage(
+ num_channels, exr_header->channels, exr_header->requested_pixel_types,
+ data_width, data_height);
+
+#if TINYEXR_HAS_CXX11 && (TINYEXR_USE_THREAD > 0)
+ std::vector<std::thread> workers;
+ std::atomic<int> y_count(0);
+
+ int num_threads = std::max(1, int(std::thread::hardware_concurrency()));
+ if (num_threads > int(num_blocks)) {
+ num_threads = int(num_blocks);
+ }
+
+ for (int t = 0; t < num_threads; t++) {
+ workers.emplace_back(std::thread([&]() {
+ int y = 0;
+ while ((y = y_count++) < int(num_blocks)) {
+
+#else
+
+#if TINYEXR_USE_OPENMP
+#pragma omp parallel for
+#endif
+ for (int y = 0; y < static_cast<int>(num_blocks); y++) {
+
+#endif
+ size_t y_idx = static_cast<size_t>(y);
+
+ if (offsets[y_idx] + sizeof(int) * 2 > size) {
+ invalid_data = true;
+ } else {
+ // 4 byte: scan line
+ // 4 byte: data size
+ // ~ : pixel data(uncompressed or compressed)
+ size_t data_size =
+ size_t(size - (offsets[y_idx] + sizeof(int) * 2));
+ const unsigned char *data_ptr =
+ reinterpret_cast<const unsigned char *>(head + offsets[y_idx]);
+
+ int line_no;
+ memcpy(&line_no, data_ptr, sizeof(int));
+ int data_len;
+ memcpy(&data_len, data_ptr + 4, sizeof(int));
+ tinyexr::swap4(&line_no);
+ tinyexr::swap4(&data_len);
+
+ if (size_t(data_len) > data_size) {
+ invalid_data = true;
+
+ } else if ((line_no > (2 << 20)) || (line_no < -(2 << 20))) {
+ // Too large value. Assume this is invalid
+ // 2**20 = 1048576 = heuristic value.
+ invalid_data = true;
+ } else if (data_len == 0) {
+ // TODO(syoyo): May be ok to raise the threshold for example
+ // `data_len < 4`
+ invalid_data = true;
+ } else {
+ // line_no may be negative.
+ int end_line_no = (std::min)(line_no + num_scanline_blocks,
+ (exr_header->data_window.max_y + 1));
+
+ int num_lines = end_line_no - line_no;
+
+ if (num_lines <= 0) {
+ invalid_data = true;
+ } else {
+ // Move to data addr: 8 = 4 + 4;
+ data_ptr += 8;
+
+ // Adjust line_no with data_window.bmin.y
+
+ // overflow check
+ tinyexr_int64 lno =
+ static_cast<tinyexr_int64>(line_no) -
+ static_cast<tinyexr_int64>(exr_header->data_window.min_y);
+ if (lno > std::numeric_limits<int>::max()) {
+ line_no = -1; // invalid
+ } else if (lno < -std::numeric_limits<int>::max()) {
+ line_no = -1; // invalid
+ } else {
+ line_no -= exr_header->data_window.min_y;
+ }
+
+ if (line_no < 0) {
+ invalid_data = true;
+ } else {
+ if (!tinyexr::DecodePixelData(
+ exr_image->images, exr_header->requested_pixel_types,
+ data_ptr, static_cast<size_t>(data_len),
+ exr_header->compression_type, exr_header->line_order,
+ data_width, data_height, data_width, y, line_no,
+ num_lines, static_cast<size_t>(pixel_data_size),
+ static_cast<size_t>(
+ exr_header->num_custom_attributes),
+ exr_header->custom_attributes,
+ static_cast<size_t>(exr_header->num_channels),
+ exr_header->channels, channel_offset_list)) {
+ invalid_data = true;
+ }
+ }
+ }
+ }
+ }
+
+#if TINYEXR_HAS_CXX11 && (TINYEXR_USE_THREAD > 0)
+ }
+ }));
+ }
+
+ for (auto &t : workers) {
+ t.join();
+ }
+#else
+ } // omp parallel
+#endif
+ }
+
+ if (invalid_data) {
+ if (err) {
+ (*err) += "Invalid data found when decoding pixels.\n";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ // Overwrite `pixel_type` with `requested_pixel_type`.
+ {
+ for (int c = 0; c < exr_header->num_channels; c++) {
+ exr_header->pixel_types[c] = exr_header->requested_pixel_types[c];
+ }
+ }
+
+ {
+ exr_image->num_channels = num_channels;
+
+ exr_image->width = data_width;
+ exr_image->height = data_height;
+ }
+
+ return TINYEXR_SUCCESS;
+}
+
+static bool ReconstructLineOffsets(
+ std::vector<tinyexr::tinyexr_uint64> *offsets, size_t n,
+ const unsigned char *head, const unsigned char *marker, const size_t size) {
+ assert(head < marker);
+ assert(offsets->size() == n);
+
+ for (size_t i = 0; i < n; i++) {
+ size_t offset = static_cast<size_t>(marker - head);
+ // Offset should not exceed whole EXR file/data size.
+ if ((offset + sizeof(tinyexr::tinyexr_uint64)) >= size) {
+ return false;
+ }
+
+ int y;
+ unsigned int data_len;
+
+ memcpy(&y, marker, sizeof(int));
+ memcpy(&data_len, marker + 4, sizeof(unsigned int));
+
+ if (data_len >= size) {
+ return false;
+ }
+
+ tinyexr::swap4(&y);
+ tinyexr::swap4(&data_len);
+
+ (*offsets)[i] = offset;
+
+ marker += data_len + 8; // 8 = 4 bytes(y) + 4 bytes(data_len)
+ }
+
+ return true;
+}
+
+
+static int FloorLog2(unsigned x) {
+ //
+ // For x > 0, floorLog2(y) returns floor(log(x)/log(2)).
+ //
+ int y = 0;
+ while (x > 1) {
+ y += 1;
+ x >>= 1u;
+ }
+ return y;
+}
+
+
+static int CeilLog2(unsigned x) {
+ //
+ // For x > 0, ceilLog2(y) returns ceil(log(x)/log(2)).
+ //
+ int y = 0;
+ int r = 0;
+ while (x > 1) {
+ if (x & 1)
+ r = 1;
+
+ y += 1;
+ x >>= 1u;
+ }
+ return y + r;
+}
+
+static int RoundLog2(int x, int tile_rounding_mode) {
+ return (tile_rounding_mode == TINYEXR_TILE_ROUND_DOWN) ? FloorLog2(static_cast<unsigned>(x)) : CeilLog2(static_cast<unsigned>(x));
+}
+
+static int CalculateNumXLevels(const EXRHeader* exr_header) {
+ int min_x = exr_header->data_window.min_x;
+ int max_x = exr_header->data_window.max_x;
+ int min_y = exr_header->data_window.min_y;
+ int max_y = exr_header->data_window.max_y;
+
+ int num = 0;
+ switch (exr_header->tile_level_mode) {
+ case TINYEXR_TILE_ONE_LEVEL:
+
+ num = 1;
+ break;
+
+ case TINYEXR_TILE_MIPMAP_LEVELS:
+
+ {
+ int w = max_x - min_x + 1;
+ int h = max_y - min_y + 1;
+ num = RoundLog2(std::max(w, h), exr_header->tile_rounding_mode) + 1;
+ }
+ break;
+
+ case TINYEXR_TILE_RIPMAP_LEVELS:
+
+ {
+ int w = max_x - min_x + 1;
+ num = RoundLog2(w, exr_header->tile_rounding_mode) + 1;
+ }
+ break;
+
+ default:
+
+ assert(false);
+ }
+
+ return num;
+}
+
+static int CalculateNumYLevels(const EXRHeader* exr_header) {
+ int min_x = exr_header->data_window.min_x;
+ int max_x = exr_header->data_window.max_x;
+ int min_y = exr_header->data_window.min_y;
+ int max_y = exr_header->data_window.max_y;
+ int num = 0;
+
+ switch (exr_header->tile_level_mode) {
+ case TINYEXR_TILE_ONE_LEVEL:
+
+ num = 1;
+ break;
+
+ case TINYEXR_TILE_MIPMAP_LEVELS:
+
+ {
+ int w = max_x - min_x + 1;
+ int h = max_y - min_y + 1;
+ num = RoundLog2(std::max(w, h), exr_header->tile_rounding_mode) + 1;
+ }
+ break;
+
+ case TINYEXR_TILE_RIPMAP_LEVELS:
+
+ {
+ int h = max_y - min_y + 1;
+ num = RoundLog2(h, exr_header->tile_rounding_mode) + 1;
+ }
+ break;
+
+ default:
+
+ assert(false);
+ }
+
+ return num;
+}
+
+static void CalculateNumTiles(std::vector<int>& numTiles,
+ int toplevel_size,
+ int size,
+ int tile_rounding_mode) {
+ for (unsigned i = 0; i < numTiles.size(); i++) {
+ int l = LevelSize(toplevel_size, i, tile_rounding_mode);
+ assert(l <= std::numeric_limits<int>::max() - size + 1);
+
+ numTiles[i] = (l + size - 1) / size;
+ }
+}
+
+static void PrecalculateTileInfo(std::vector<int>& num_x_tiles,
+ std::vector<int>& num_y_tiles,
+ const EXRHeader* exr_header) {
+ int min_x = exr_header->data_window.min_x;
+ int max_x = exr_header->data_window.max_x;
+ int min_y = exr_header->data_window.min_y;
+ int max_y = exr_header->data_window.max_y;
+
+ int num_x_levels = CalculateNumXLevels(exr_header);
+ int num_y_levels = CalculateNumYLevels(exr_header);
+
+ num_x_tiles.resize(num_x_levels);
+ num_y_tiles.resize(num_y_levels);
+
+ CalculateNumTiles(num_x_tiles,
+ max_x - min_x + 1,
+ exr_header->tile_size_x,
+ exr_header->tile_rounding_mode);
+
+ CalculateNumTiles(num_y_tiles,
+ max_y - min_y + 1,
+ exr_header->tile_size_y,
+ exr_header->tile_rounding_mode);
+}
+
+static void InitSingleResolutionOffsets(OffsetData& offset_data, size_t num_blocks) {
+ offset_data.offsets.resize(1);
+ offset_data.offsets[0].resize(1);
+ offset_data.offsets[0][0].resize(num_blocks);
+ offset_data.num_x_levels = 1;
+ offset_data.num_y_levels = 1;
+}
+
+// Return sum of tile blocks.
+static int InitTileOffsets(OffsetData& offset_data,
+ const EXRHeader* exr_header,
+ const std::vector<int>& num_x_tiles,
+ const std::vector<int>& num_y_tiles) {
+ int num_tile_blocks = 0;
+ offset_data.num_x_levels = static_cast<int>(num_x_tiles.size());
+ offset_data.num_y_levels = static_cast<int>(num_y_tiles.size());
+ switch (exr_header->tile_level_mode) {
+ case TINYEXR_TILE_ONE_LEVEL:
+ case TINYEXR_TILE_MIPMAP_LEVELS:
+ assert(offset_data.num_x_levels == offset_data.num_y_levels);
+ offset_data.offsets.resize(offset_data.num_x_levels);
+
+ for (unsigned int l = 0; l < offset_data.offsets.size(); ++l) {
+ offset_data.offsets[l].resize(num_y_tiles[l]);
+
+ for (unsigned int dy = 0; dy < offset_data.offsets[l].size(); ++dy) {
+ offset_data.offsets[l][dy].resize(num_x_tiles[l]);
+ num_tile_blocks += num_x_tiles[l];
+ }
+ }
+ break;
+
+ case TINYEXR_TILE_RIPMAP_LEVELS:
+
+ offset_data.offsets.resize(static_cast<size_t>(offset_data.num_x_levels) * static_cast<size_t>(offset_data.num_y_levels));
+
+ for (int ly = 0; ly < offset_data.num_y_levels; ++ly) {
+ for (int lx = 0; lx < offset_data.num_x_levels; ++lx) {
+ int l = ly * offset_data.num_x_levels + lx;
+ offset_data.offsets[l].resize(num_y_tiles[ly]);
+
+ for (size_t dy = 0; dy < offset_data.offsets[l].size(); ++dy) {
+ offset_data.offsets[l][dy].resize(num_x_tiles[lx]);
+ num_tile_blocks += num_x_tiles[lx];
+ }
+ }
+ }
+ break;
+
+ default:
+ assert(false);
+ }
+ return num_tile_blocks;
+}
+
+static bool IsAnyOffsetsAreInvalid(const OffsetData& offset_data) {
+ for (unsigned int l = 0; l < offset_data.offsets.size(); ++l)
+ for (unsigned int dy = 0; dy < offset_data.offsets[l].size(); ++dy)
+ for (unsigned int dx = 0; dx < offset_data.offsets[l][dy].size(); ++dx)
+ if (reinterpret_cast<const tinyexr::tinyexr_int64&>(offset_data.offsets[l][dy][dx]) <= 0)
+ return true;
+
+ return false;
+}
+
+static bool isValidTile(const EXRHeader* exr_header,
+ const OffsetData& offset_data,
+ int dx, int dy, int lx, int ly) {
+ if (lx < 0 || ly < 0 || dx < 0 || dy < 0) return false;
+ int num_x_levels = offset_data.num_x_levels;
+ int num_y_levels = offset_data.num_y_levels;
+ switch (exr_header->tile_level_mode) {
+ case TINYEXR_TILE_ONE_LEVEL:
+
+ if (lx == 0 &&
+ ly == 0 &&
+ offset_data.offsets.size() > 0 &&
+ offset_data.offsets[0].size() > static_cast<size_t>(dy) &&
+ offset_data.offsets[0][dy].size() > static_cast<size_t>(dx)) {
+ return true;
+ }
+
+ break;
+
+ case TINYEXR_TILE_MIPMAP_LEVELS:
+
+ if (lx < num_x_levels &&
+ ly < num_y_levels &&
+ offset_data.offsets.size() > static_cast<size_t>(lx) &&
+ offset_data.offsets[lx].size() > static_cast<size_t>(dy) &&
+ offset_data.offsets[lx][dy].size() > static_cast<size_t>(dx)) {
+ return true;
+ }
+
+ break;
+
+ case TINYEXR_TILE_RIPMAP_LEVELS:
+ {
+ size_t idx = static_cast<size_t>(lx) + static_cast<size_t>(ly)* static_cast<size_t>(num_x_levels);
+ if (lx < num_x_levels &&
+ ly < num_y_levels &&
+ (offset_data.offsets.size() > idx) &&
+ offset_data.offsets[idx].size() > static_cast<size_t>(dy) &&
+ offset_data.offsets[idx][dy].size() > static_cast<size_t>(dx)) {
+ return true;
+ }
+ }
+
+ break;
+
+ default:
+
+ return false;
+ }
+
+ return false;
+}
+
+static void ReconstructTileOffsets(OffsetData& offset_data,
+ const EXRHeader* exr_header,
+ const unsigned char* head, const unsigned char* marker, const size_t /*size*/,
+ bool isMultiPartFile,
+ bool isDeep) {
+ int numXLevels = offset_data.num_x_levels;
+ for (unsigned int l = 0; l < offset_data.offsets.size(); ++l) {
+ for (unsigned int dy = 0; dy < offset_data.offsets[l].size(); ++dy) {
+ for (unsigned int dx = 0; dx < offset_data.offsets[l][dy].size(); ++dx) {
+ tinyexr::tinyexr_uint64 tileOffset = marker - head;
+
+ if (isMultiPartFile) {
+ //int partNumber;
+ marker += sizeof(int);
+ }
+
+ int tileX;
+ memcpy(&tileX, marker, sizeof(int));
+ tinyexr::swap4(&tileX);
+ marker += sizeof(int);
+
+ int tileY;
+ memcpy(&tileY, marker, sizeof(int));
+ tinyexr::swap4(&tileY);
+ marker += sizeof(int);
+
+ int levelX;
+ memcpy(&levelX, marker, sizeof(int));
+ tinyexr::swap4(&levelX);
+ marker += sizeof(int);
+
+ int levelY;
+ memcpy(&levelY, marker, sizeof(int));
+ tinyexr::swap4(&levelY);
+ marker += sizeof(int);
+
+ if (isDeep) {
+ tinyexr::tinyexr_int64 packed_offset_table_size;
+ memcpy(&packed_offset_table_size, marker, sizeof(tinyexr::tinyexr_int64));
+ tinyexr::swap8(reinterpret_cast<tinyexr::tinyexr_uint64*>(&packed_offset_table_size));
+ marker += sizeof(tinyexr::tinyexr_int64);
+
+ tinyexr::tinyexr_int64 packed_sample_size;
+ memcpy(&packed_sample_size, marker, sizeof(tinyexr::tinyexr_int64));
+ tinyexr::swap8(reinterpret_cast<tinyexr::tinyexr_uint64*>(&packed_sample_size));
+ marker += sizeof(tinyexr::tinyexr_int64);
+
+ // next Int64 is unpacked sample size - skip that too
+ marker += packed_offset_table_size + packed_sample_size + 8;
+
+ } else {
+
+ int dataSize;
+ memcpy(&dataSize, marker, sizeof(int));
+ tinyexr::swap4(&dataSize);
+ marker += sizeof(int);
+ marker += dataSize;
+ }
+
+ if (!isValidTile(exr_header, offset_data,
+ tileX, tileY, levelX, levelY))
+ return;
+
+ int level_idx = LevelIndex(levelX, levelY, exr_header->tile_level_mode, numXLevels);
+ offset_data.offsets[level_idx][tileY][tileX] = tileOffset;
+ }
+ }
+ }
+}
+
+// marker output is also
+static int ReadOffsets(OffsetData& offset_data,
+ const unsigned char* head,
+ const unsigned char*& marker,
+ const size_t size,
+ const char** err) {
+ for (unsigned int l = 0; l < offset_data.offsets.size(); ++l) {
+ for (unsigned int dy = 0; dy < offset_data.offsets[l].size(); ++dy) {
+ for (unsigned int dx = 0; dx < offset_data.offsets[l][dy].size(); ++dx) {
+ tinyexr::tinyexr_uint64 offset;
+ if ((marker + sizeof(tinyexr_uint64)) >= (head + size)) {
+ tinyexr::SetErrorMessage("Insufficient data size in offset table.", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ memcpy(&offset, marker, sizeof(tinyexr::tinyexr_uint64));
+ tinyexr::swap8(&offset);
+ if (offset >= size) {
+ tinyexr::SetErrorMessage("Invalid offset value in DecodeEXRImage.", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ marker += sizeof(tinyexr::tinyexr_uint64); // = 8
+ offset_data.offsets[l][dy][dx] = offset;
+ }
+ }
+ }
+ return TINYEXR_SUCCESS;
+}
+
+static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header,
+ const unsigned char *head,
+ const unsigned char *marker, const size_t size,
+ const char **err) {
+ if (exr_image == NULL || exr_header == NULL || head == NULL ||
+ marker == NULL || (size <= tinyexr::kEXRVersionSize)) {
+ tinyexr::SetErrorMessage("Invalid argument for DecodeEXRImage().", err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ int num_scanline_blocks = 1;
+ if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) {
+ num_scanline_blocks = 16;
+ } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
+ num_scanline_blocks = 32;
+ } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
+ num_scanline_blocks = 16;
+ }
+
+ if (exr_header->data_window.max_x < exr_header->data_window.min_x ||
+ exr_header->data_window.max_x - exr_header->data_window.min_x ==
+ std::numeric_limits<int>::max()) {
+ // Issue 63
+ tinyexr::SetErrorMessage("Invalid data width value", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ int data_width =
+ exr_header->data_window.max_x - exr_header->data_window.min_x + 1;
+
+ if (exr_header->data_window.max_y < exr_header->data_window.min_y ||
+ exr_header->data_window.max_y - exr_header->data_window.min_y ==
+ std::numeric_limits<int>::max()) {
+ tinyexr::SetErrorMessage("Invalid data height value", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ int data_height =
+ exr_header->data_window.max_y - exr_header->data_window.min_y + 1;
+
+ // Do not allow too large data_width and data_height. header invalid?
+ {
+ if (data_width > TINYEXR_DIMENSION_THRESHOLD) {
+ tinyexr::SetErrorMessage("data width too large.", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ if (data_height > TINYEXR_DIMENSION_THRESHOLD) {
+ tinyexr::SetErrorMessage("data height too large.", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ }
+
+ if (exr_header->tiled) {
+ if (exr_header->tile_size_x > TINYEXR_DIMENSION_THRESHOLD) {
+ tinyexr::SetErrorMessage("tile width too large.", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ if (exr_header->tile_size_y > TINYEXR_DIMENSION_THRESHOLD) {
+ tinyexr::SetErrorMessage("tile height too large.", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ }
+
+ // Read offset tables.
+ OffsetData offset_data;
+ size_t num_blocks = 0;
+ // For a multi-resolution image, the size of the offset table will be calculated from the other attributes of the header.
+ // If chunk_count > 0 then chunk_count must be equal to the calculated tile count.
+ if (exr_header->tiled) {
+ {
+ std::vector<int> num_x_tiles, num_y_tiles;
+ PrecalculateTileInfo(num_x_tiles, num_y_tiles, exr_header);
+ num_blocks = InitTileOffsets(offset_data, exr_header, num_x_tiles, num_y_tiles);
+ if (exr_header->chunk_count > 0) {
+ if (exr_header->chunk_count != static_cast<int>(num_blocks)) {
+ tinyexr::SetErrorMessage("Invalid offset table size.", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ }
+ }
+
+ int ret = ReadOffsets(offset_data, head, marker, size, err);
+ if (ret != TINYEXR_SUCCESS) return ret;
+ if (IsAnyOffsetsAreInvalid(offset_data)) {
+ ReconstructTileOffsets(offset_data, exr_header,
+ head, marker, size,
+ exr_header->multipart, exr_header->non_image);
+ }
+ } else if (exr_header->chunk_count > 0) {
+ // Use `chunkCount` attribute.
+ num_blocks = static_cast<size_t>(exr_header->chunk_count);
+ InitSingleResolutionOffsets(offset_data, num_blocks);
+ } else {
+ num_blocks = static_cast<size_t>(data_height) /
+ static_cast<size_t>(num_scanline_blocks);
+ if (num_blocks * static_cast<size_t>(num_scanline_blocks) <
+ static_cast<size_t>(data_height)) {
+ num_blocks++;
+ }
+
+ InitSingleResolutionOffsets(offset_data, num_blocks);
+ }
+
+ if (!exr_header->tiled) {
+ std::vector<tinyexr::tinyexr_uint64>& offsets = offset_data.offsets[0][0];
+ for (size_t y = 0; y < num_blocks; y++) {
+ tinyexr::tinyexr_uint64 offset;
+ // Issue #81
+ if ((marker + sizeof(tinyexr_uint64)) >= (head + size)) {
+ tinyexr::SetErrorMessage("Insufficient data size in offset table.", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ memcpy(&offset, marker, sizeof(tinyexr::tinyexr_uint64));
+ tinyexr::swap8(&offset);
+ if (offset >= size) {
+ tinyexr::SetErrorMessage("Invalid offset value in DecodeEXRImage.", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ marker += sizeof(tinyexr::tinyexr_uint64); // = 8
+ offsets[y] = offset;
+ }
+
+ // If line offsets are invalid, we try to reconstruct it.
+ // See OpenEXR/IlmImf/ImfScanLineInputFile.cpp::readLineOffsets() for details.
+ for (size_t y = 0; y < num_blocks; y++) {
+ if (offsets[y] <= 0) {
+ // TODO(syoyo) Report as warning?
+ // if (err) {
+ // stringstream ss;
+ // ss << "Incomplete lineOffsets." << std::endl;
+ // (*err) += ss.str();
+ //}
+ bool ret =
+ ReconstructLineOffsets(&offsets, num_blocks, head, marker, size);
+ if (ret) {
+ // OK
+ break;
+ } else {
+ tinyexr::SetErrorMessage(
+ "Cannot reconstruct lineOffset table in DecodeEXRImage.", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ }
+ }
+ }
+
+ {
+ std::string e;
+ int ret = DecodeChunk(exr_image, exr_header, offset_data, head, size, &e);
+
+ if (ret != TINYEXR_SUCCESS) {
+ if (!e.empty()) {
+ tinyexr::SetErrorMessage(e, err);
+ }
+
+#if 1
+ FreeEXRImage(exr_image);
+#else
+ // release memory(if exists)
+ if ((exr_header->num_channels > 0) && exr_image && exr_image->images) {
+ for (size_t c = 0; c < size_t(exr_header->num_channels); c++) {
+ if (exr_image->images[c]) {
+ free(exr_image->images[c]);
+ exr_image->images[c] = NULL;
+ }
+ }
+ free(exr_image->images);
+ exr_image->images = NULL;
+ }
+#endif
+ }
+
+ return ret;
+ }
+}
+
+static void GetLayers(const EXRHeader &exr_header,
+ std::vector<std::string> &layer_names) {
+ // Naive implementation
+ // Group channels by layers
+ // go over all channel names, split by periods
+ // collect unique names
+ layer_names.clear();
+ for (int c = 0; c < exr_header.num_channels; c++) {
+ std::string full_name(exr_header.channels[c].name);
+ const size_t pos = full_name.find_last_of('.');
+ if (pos != std::string::npos && pos != 0 && pos + 1 < full_name.size()) {
+ full_name.erase(pos);
+ if (std::find(layer_names.begin(), layer_names.end(), full_name) ==
+ layer_names.end())
+ layer_names.push_back(full_name);
+ }
+ }
+}
+
+struct LayerChannel {
+ explicit LayerChannel(size_t i, std::string n) : index(i), name(n) {}
+ size_t index;
+ std::string name;
+};
+
+static void ChannelsInLayer(const EXRHeader &exr_header,
+ const std::string &layer_name,
+ std::vector<LayerChannel> &channels) {
+ channels.clear();
+ for (int c = 0; c < exr_header.num_channels; c++) {
+ std::string ch_name(exr_header.channels[c].name);
+ if (layer_name.empty()) {
+ const size_t pos = ch_name.find_last_of('.');
+ if (pos != std::string::npos && pos < ch_name.size()) {
+ ch_name = ch_name.substr(pos + 1);
+ }
+ } else {
+ const size_t pos = ch_name.find(layer_name + '.');
+ if (pos == std::string::npos) continue;
+ if (pos == 0) {
+ ch_name = ch_name.substr(layer_name.size() + 1);
+ }
+ }
+ LayerChannel ch(size_t(c), ch_name);
+ channels.push_back(ch);
+ }
+}
+
+} // namespace tinyexr
+
+int EXRLayers(const char *filename, const char **layer_names[], int *num_layers,
+ const char **err) {
+ EXRVersion exr_version;
+ EXRHeader exr_header;
+ InitEXRHeader(&exr_header);
+
+ {
+ int ret = ParseEXRVersionFromFile(&exr_version, filename);
+ if (ret != TINYEXR_SUCCESS) {
+ tinyexr::SetErrorMessage("Invalid EXR header.", err);
+ return ret;
+ }
+
+ if (exr_version.multipart || exr_version.non_image) {
+ tinyexr::SetErrorMessage(
+ "Loading multipart or DeepImage is not supported in LoadEXR() API",
+ err);
+ return TINYEXR_ERROR_INVALID_DATA; // @fixme.
+ }
+ }
+
+ int ret = ParseEXRHeaderFromFile(&exr_header, &exr_version, filename, err);
+ if (ret != TINYEXR_SUCCESS) {
+ FreeEXRHeader(&exr_header);
+ return ret;
+ }
+
+ std::vector<std::string> layer_vec;
+ tinyexr::GetLayers(exr_header, layer_vec);
+
+ (*num_layers) = int(layer_vec.size());
+ (*layer_names) = static_cast<const char **>(
+ malloc(sizeof(const char *) * static_cast<size_t>(layer_vec.size())));
+ for (size_t c = 0; c < static_cast<size_t>(layer_vec.size()); c++) {
+#ifdef _MSC_VER
+ (*layer_names)[c] = _strdup(layer_vec[c].c_str());
+#else
+ (*layer_names)[c] = strdup(layer_vec[c].c_str());
+#endif
+ }
+
+ FreeEXRHeader(&exr_header);
+ return TINYEXR_SUCCESS;
+}
+
+int LoadEXR(float **out_rgba, int *width, int *height, const char *filename,
+ const char **err) {
+ return LoadEXRWithLayer(out_rgba, width, height, filename,
+ /* layername */ NULL, err);
+}
+
+int LoadEXRWithLayer(float **out_rgba, int *width, int *height,
+ const char *filename, const char *layername,
+ const char **err) {
+ if (out_rgba == NULL) {
+ tinyexr::SetErrorMessage("Invalid argument for LoadEXR()", err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ EXRVersion exr_version;
+ EXRImage exr_image;
+ EXRHeader exr_header;
+ InitEXRHeader(&exr_header);
+ InitEXRImage(&exr_image);
+
+ {
+ int ret = ParseEXRVersionFromFile(&exr_version, filename);
+ if (ret != TINYEXR_SUCCESS) {
+ std::stringstream ss;
+ ss << "Failed to open EXR file or read version info from EXR file. code("
+ << ret << ")";
+ tinyexr::SetErrorMessage(ss.str(), err);
+ return ret;
+ }
+
+ if (exr_version.multipart || exr_version.non_image) {
+ tinyexr::SetErrorMessage(
+ "Loading multipart or DeepImage is not supported in LoadEXR() API",
+ err);
+ return TINYEXR_ERROR_INVALID_DATA; // @fixme.
+ }
+ }
+
+ {
+ int ret = ParseEXRHeaderFromFile(&exr_header, &exr_version, filename, err);
+ if (ret != TINYEXR_SUCCESS) {
+ FreeEXRHeader(&exr_header);
+ return ret;
+ }
+ }
+
+ // Read HALF channel as FLOAT.
+ for (int i = 0; i < exr_header.num_channels; i++) {
+ if (exr_header.pixel_types[i] == TINYEXR_PIXELTYPE_HALF) {
+ exr_header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
+ }
+ }
+
+ // TODO: Probably limit loading to layers (channels) selected by layer index
+ {
+ int ret = LoadEXRImageFromFile(&exr_image, &exr_header, filename, err);
+ if (ret != TINYEXR_SUCCESS) {
+ FreeEXRHeader(&exr_header);
+ return ret;
+ }
+ }
+
+ // RGBA
+ int idxR = -1;
+ int idxG = -1;
+ int idxB = -1;
+ int idxA = -1;
+
+ std::vector<std::string> layer_names;
+ tinyexr::GetLayers(exr_header, layer_names);
+
+ std::vector<tinyexr::LayerChannel> channels;
+ tinyexr::ChannelsInLayer(
+ exr_header, layername == NULL ? "" : std::string(layername), channels);
+
+ if (channels.size() < 1) {
+ tinyexr::SetErrorMessage("Layer Not Found", err);
+ FreeEXRHeader(&exr_header);
+ FreeEXRImage(&exr_image);
+ return TINYEXR_ERROR_LAYER_NOT_FOUND;
+ }
+
+ size_t ch_count = channels.size() < 4 ? channels.size() : 4;
+ for (size_t c = 0; c < ch_count; c++) {
+ const tinyexr::LayerChannel &ch = channels[c];
+
+ if (ch.name == "R") {
+ idxR = int(ch.index);
+ } else if (ch.name == "G") {
+ idxG = int(ch.index);
+ } else if (ch.name == "B") {
+ idxB = int(ch.index);
+ } else if (ch.name == "A") {
+ idxA = int(ch.index);
+ }
+ }
+
+ if (channels.size() == 1) {
+ int chIdx = int(channels.front().index);
+ // Grayscale channel only.
+
+ (*out_rgba) = reinterpret_cast<float *>(
+ malloc(4 * sizeof(float) * static_cast<size_t>(exr_image.width) *
+ static_cast<size_t>(exr_image.height)));
+
+ if (exr_header.tiled) {
+ for (int it = 0; it < exr_image.num_tiles; it++) {
+ for (int j = 0; j < exr_header.tile_size_y; j++) {
+ for (int i = 0; i < exr_header.tile_size_x; i++) {
+ const int ii = exr_image.tiles[it].offset_x *
+ static_cast<int>(exr_header.tile_size_x) +
+ i;
+ const int jj = exr_image.tiles[it].offset_y *
+ static_cast<int>(exr_header.tile_size_y) +
+ j;
+ const int idx = ii + jj * static_cast<int>(exr_image.width);
+
+ // out of region check.
+ if (ii >= exr_image.width) {
+ continue;
+ }
+ if (jj >= exr_image.height) {
+ continue;
+ }
+ const int srcIdx = i + j * exr_header.tile_size_x;
+ unsigned char **src = exr_image.tiles[it].images;
+ (*out_rgba)[4 * idx + 0] =
+ reinterpret_cast<float **>(src)[chIdx][srcIdx];
+ (*out_rgba)[4 * idx + 1] =
+ reinterpret_cast<float **>(src)[chIdx][srcIdx];
+ (*out_rgba)[4 * idx + 2] =
+ reinterpret_cast<float **>(src)[chIdx][srcIdx];
+ (*out_rgba)[4 * idx + 3] =
+ reinterpret_cast<float **>(src)[chIdx][srcIdx];
+ }
+ }
+ }
+ } else {
+ for (int i = 0; i < exr_image.width * exr_image.height; i++) {
+ const float val =
+ reinterpret_cast<float **>(exr_image.images)[chIdx][i];
+ (*out_rgba)[4 * i + 0] = val;
+ (*out_rgba)[4 * i + 1] = val;
+ (*out_rgba)[4 * i + 2] = val;
+ (*out_rgba)[4 * i + 3] = val;
+ }
+ }
+ } else {
+ // Assume RGB(A)
+
+ if (idxR == -1) {
+ tinyexr::SetErrorMessage("R channel not found", err);
+
+ FreeEXRHeader(&exr_header);
+ FreeEXRImage(&exr_image);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ if (idxG == -1) {
+ tinyexr::SetErrorMessage("G channel not found", err);
+ FreeEXRHeader(&exr_header);
+ FreeEXRImage(&exr_image);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ if (idxB == -1) {
+ tinyexr::SetErrorMessage("B channel not found", err);
+ FreeEXRHeader(&exr_header);
+ FreeEXRImage(&exr_image);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ (*out_rgba) = reinterpret_cast<float *>(
+ malloc(4 * sizeof(float) * static_cast<size_t>(exr_image.width) *
+ static_cast<size_t>(exr_image.height)));
+ if (exr_header.tiled) {
+ for (int it = 0; it < exr_image.num_tiles; it++) {
+ for (int j = 0; j < exr_header.tile_size_y; j++) {
+ for (int i = 0; i < exr_header.tile_size_x; i++) {
+ const int ii =
+ exr_image.tiles[it].offset_x * exr_header.tile_size_x + i;
+ const int jj =
+ exr_image.tiles[it].offset_y * exr_header.tile_size_y + j;
+ const int idx = ii + jj * exr_image.width;
+
+ // out of region check.
+ if (ii >= exr_image.width) {
+ continue;
+ }
+ if (jj >= exr_image.height) {
+ continue;
+ }
+ const int srcIdx = i + j * exr_header.tile_size_x;
+ unsigned char **src = exr_image.tiles[it].images;
+ (*out_rgba)[4 * idx + 0] =
+ reinterpret_cast<float **>(src)[idxR][srcIdx];
+ (*out_rgba)[4 * idx + 1] =
+ reinterpret_cast<float **>(src)[idxG][srcIdx];
+ (*out_rgba)[4 * idx + 2] =
+ reinterpret_cast<float **>(src)[idxB][srcIdx];
+ if (idxA != -1) {
+ (*out_rgba)[4 * idx + 3] =
+ reinterpret_cast<float **>(src)[idxA][srcIdx];
+ } else {
+ (*out_rgba)[4 * idx + 3] = 1.0;
+ }
+ }
+ }
+ }
+ } else {
+ for (int i = 0; i < exr_image.width * exr_image.height; i++) {
+ (*out_rgba)[4 * i + 0] =
+ reinterpret_cast<float **>(exr_image.images)[idxR][i];
+ (*out_rgba)[4 * i + 1] =
+ reinterpret_cast<float **>(exr_image.images)[idxG][i];
+ (*out_rgba)[4 * i + 2] =
+ reinterpret_cast<float **>(exr_image.images)[idxB][i];
+ if (idxA != -1) {
+ (*out_rgba)[4 * i + 3] =
+ reinterpret_cast<float **>(exr_image.images)[idxA][i];
+ } else {
+ (*out_rgba)[4 * i + 3] = 1.0;
+ }
+ }
+ }
+ }
+
+ (*width) = exr_image.width;
+ (*height) = exr_image.height;
+
+ FreeEXRHeader(&exr_header);
+ FreeEXRImage(&exr_image);
+
+ return TINYEXR_SUCCESS;
+}
+
+int IsEXR(const char *filename) {
+ EXRVersion exr_version;
+
+ int ret = ParseEXRVersionFromFile(&exr_version, filename);
+ if (ret != TINYEXR_SUCCESS) {
+ return ret;
+ }
+
+ return TINYEXR_SUCCESS;
+}
+
+int ParseEXRHeaderFromMemory(EXRHeader *exr_header, const EXRVersion *version,
+ const unsigned char *memory, size_t size,
+ const char **err) {
+ if (memory == NULL || exr_header == NULL) {
+ tinyexr::SetErrorMessage(
+ "Invalid argument. `memory` or `exr_header` argument is null in "
+ "ParseEXRHeaderFromMemory()",
+ err);
+
+ // Invalid argument
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (size < tinyexr::kEXRVersionSize) {
+ tinyexr::SetErrorMessage("Insufficient header/data size.\n", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ const unsigned char *marker = memory + tinyexr::kEXRVersionSize;
+ size_t marker_size = size - tinyexr::kEXRVersionSize;
+
+ tinyexr::HeaderInfo info;
+ info.clear();
+
+ std::string err_str;
+ int ret = ParseEXRHeader(&info, NULL, version, &err_str, marker, marker_size);
+
+ if (ret != TINYEXR_SUCCESS) {
+ if (err && !err_str.empty()) {
+ tinyexr::SetErrorMessage(err_str, err);
+ }
+ }
+
+ ConvertHeader(exr_header, info);
+
+ exr_header->multipart = version->multipart ? 1 : 0;
+ exr_header->non_image = version->non_image ? 1 : 0;
+
+ return ret;
+}
+
+int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
+ const unsigned char *memory, size_t size,
+ const char **err) {
+ if (out_rgba == NULL || memory == NULL) {
+ tinyexr::SetErrorMessage("Invalid argument for LoadEXRFromMemory", err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ EXRVersion exr_version;
+ EXRImage exr_image;
+ EXRHeader exr_header;
+
+ InitEXRHeader(&exr_header);
+
+ int ret = ParseEXRVersionFromMemory(&exr_version, memory, size);
+ if (ret != TINYEXR_SUCCESS) {
+ std::stringstream ss;
+ ss << "Failed to parse EXR version. code(" << ret << ")";
+ tinyexr::SetErrorMessage(ss.str(), err);
+ return ret;
+ }
+
+ ret = ParseEXRHeaderFromMemory(&exr_header, &exr_version, memory, size, err);
+ if (ret != TINYEXR_SUCCESS) {
+ return ret;
+ }
+
+ // Read HALF channel as FLOAT.
+ for (int i = 0; i < exr_header.num_channels; i++) {
+ if (exr_header.pixel_types[i] == TINYEXR_PIXELTYPE_HALF) {
+ exr_header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
+ }
+ }
+
+ InitEXRImage(&exr_image);
+ ret = LoadEXRImageFromMemory(&exr_image, &exr_header, memory, size, err);
+ if (ret != TINYEXR_SUCCESS) {
+ return ret;
+ }
+
+ // RGBA
+ int idxR = -1;
+ int idxG = -1;
+ int idxB = -1;
+ int idxA = -1;
+ for (int c = 0; c < exr_header.num_channels; c++) {
+ if (strcmp(exr_header.channels[c].name, "R") == 0) {
+ idxR = c;
+ } else if (strcmp(exr_header.channels[c].name, "G") == 0) {
+ idxG = c;
+ } else if (strcmp(exr_header.channels[c].name, "B") == 0) {
+ idxB = c;
+ } else if (strcmp(exr_header.channels[c].name, "A") == 0) {
+ idxA = c;
+ }
+ }
+
+ // TODO(syoyo): Refactor removing same code as used in LoadEXR().
+ if (exr_header.num_channels == 1) {
+ // Grayscale channel only.
+
+ (*out_rgba) = reinterpret_cast<float *>(
+ malloc(4 * sizeof(float) * static_cast<size_t>(exr_image.width) *
+ static_cast<size_t>(exr_image.height)));
+
+ if (exr_header.tiled) {
+ for (int it = 0; it < exr_image.num_tiles; it++) {
+ for (int j = 0; j < exr_header.tile_size_y; j++) {
+ for (int i = 0; i < exr_header.tile_size_x; i++) {
+ const int ii =
+ exr_image.tiles[it].offset_x * exr_header.tile_size_x + i;
+ const int jj =
+ exr_image.tiles[it].offset_y * exr_header.tile_size_y + j;
+ const int idx = ii + jj * exr_image.width;
+
+ // out of region check.
+ if (ii >= exr_image.width) {
+ continue;
+ }
+ if (jj >= exr_image.height) {
+ continue;
+ }
+ const int srcIdx = i + j * exr_header.tile_size_x;
+ unsigned char **src = exr_image.tiles[it].images;
+ (*out_rgba)[4 * idx + 0] =
+ reinterpret_cast<float **>(src)[0][srcIdx];
+ (*out_rgba)[4 * idx + 1] =
+ reinterpret_cast<float **>(src)[0][srcIdx];
+ (*out_rgba)[4 * idx + 2] =
+ reinterpret_cast<float **>(src)[0][srcIdx];
+ (*out_rgba)[4 * idx + 3] =
+ reinterpret_cast<float **>(src)[0][srcIdx];
+ }
+ }
+ }
+ } else {
+ for (int i = 0; i < exr_image.width * exr_image.height; i++) {
+ const float val = reinterpret_cast<float **>(exr_image.images)[0][i];
+ (*out_rgba)[4 * i + 0] = val;
+ (*out_rgba)[4 * i + 1] = val;
+ (*out_rgba)[4 * i + 2] = val;
+ (*out_rgba)[4 * i + 3] = val;
+ }
+ }
+
+ } else {
+ // TODO(syoyo): Support non RGBA image.
+
+ if (idxR == -1) {
+ tinyexr::SetErrorMessage("R channel not found", err);
+
+ // @todo { free exr_image }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ if (idxG == -1) {
+ tinyexr::SetErrorMessage("G channel not found", err);
+ // @todo { free exr_image }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ if (idxB == -1) {
+ tinyexr::SetErrorMessage("B channel not found", err);
+ // @todo { free exr_image }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ (*out_rgba) = reinterpret_cast<float *>(
+ malloc(4 * sizeof(float) * static_cast<size_t>(exr_image.width) *
+ static_cast<size_t>(exr_image.height)));
+
+ if (exr_header.tiled) {
+ for (int it = 0; it < exr_image.num_tiles; it++) {
+ for (int j = 0; j < exr_header.tile_size_y; j++)
+ for (int i = 0; i < exr_header.tile_size_x; i++) {
+ const int ii =
+ exr_image.tiles[it].offset_x * exr_header.tile_size_x + i;
+ const int jj =
+ exr_image.tiles[it].offset_y * exr_header.tile_size_y + j;
+ const int idx = ii + jj * exr_image.width;
+
+ // out of region check.
+ if (ii >= exr_image.width) {
+ continue;
+ }
+ if (jj >= exr_image.height) {
+ continue;
+ }
+ const int srcIdx = i + j * exr_header.tile_size_x;
+ unsigned char **src = exr_image.tiles[it].images;
+ (*out_rgba)[4 * idx + 0] =
+ reinterpret_cast<float **>(src)[idxR][srcIdx];
+ (*out_rgba)[4 * idx + 1] =
+ reinterpret_cast<float **>(src)[idxG][srcIdx];
+ (*out_rgba)[4 * idx + 2] =
+ reinterpret_cast<float **>(src)[idxB][srcIdx];
+ if (idxA != -1) {
+ (*out_rgba)[4 * idx + 3] =
+ reinterpret_cast<float **>(src)[idxA][srcIdx];
+ } else {
+ (*out_rgba)[4 * idx + 3] = 1.0;
+ }
+ }
+ }
+ } else {
+ for (int i = 0; i < exr_image.width * exr_image.height; i++) {
+ (*out_rgba)[4 * i + 0] =
+ reinterpret_cast<float **>(exr_image.images)[idxR][i];
+ (*out_rgba)[4 * i + 1] =
+ reinterpret_cast<float **>(exr_image.images)[idxG][i];
+ (*out_rgba)[4 * i + 2] =
+ reinterpret_cast<float **>(exr_image.images)[idxB][i];
+ if (idxA != -1) {
+ (*out_rgba)[4 * i + 3] =
+ reinterpret_cast<float **>(exr_image.images)[idxA][i];
+ } else {
+ (*out_rgba)[4 * i + 3] = 1.0;
+ }
+ }
+ }
+ }
+
+ (*width) = exr_image.width;
+ (*height) = exr_image.height;
+
+ FreeEXRHeader(&exr_header);
+ FreeEXRImage(&exr_image);
+
+ return TINYEXR_SUCCESS;
+}
+
+int LoadEXRImageFromFile(EXRImage *exr_image, const EXRHeader *exr_header,
+ const char *filename, const char **err) {
+ if (exr_image == NULL) {
+ tinyexr::SetErrorMessage("Invalid argument for LoadEXRImageFromFile", err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ FILE *fp = NULL;
+#ifdef _WIN32
+#if defined(_MSC_VER) || (defined(MINGW_HAS_SECURE_API) && MINGW_HAS_SECURE_API) // MSVC, MinGW GCC, or Clang.
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ // TODO(syoyo): return wfopen_s erro code
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+#else
+ // Unknown compiler or MinGW without MINGW_HAS_SECURE_API.
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
+#endif
+ if (!fp) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+
+ size_t filesize;
+ // Compute size
+ fseek(fp, 0, SEEK_END);
+ filesize = static_cast<size_t>(ftell(fp));
+ fseek(fp, 0, SEEK_SET);
+
+ if (filesize < 16) {
+ tinyexr::SetErrorMessage("File size too short " + std::string(filename),
+ err);
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
+
+ std::vector<unsigned char> buf(filesize); // @todo { use mmap }
+ {
+ size_t ret;
+ ret = fread(&buf[0], 1, filesize, fp);
+ assert(ret == filesize);
+ fclose(fp);
+ (void)ret;
+ }
+
+ return LoadEXRImageFromMemory(exr_image, exr_header, &buf.at(0), filesize,
+ err);
+}
+
+int LoadEXRImageFromMemory(EXRImage *exr_image, const EXRHeader *exr_header,
+ const unsigned char *memory, const size_t size,
+ const char **err) {
+ if (exr_image == NULL || memory == NULL ||
+ (size < tinyexr::kEXRVersionSize)) {
+ tinyexr::SetErrorMessage("Invalid argument for LoadEXRImageFromMemory",
+ err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (exr_header->header_len == 0) {
+ tinyexr::SetErrorMessage("EXRHeader variable is not initialized.", err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ const unsigned char *head = memory;
+ const unsigned char *marker = reinterpret_cast<const unsigned char *>(
+ memory + exr_header->header_len +
+ 8); // +8 for magic number + version header.
+ return tinyexr::DecodeEXRImage(exr_image, exr_header, head, marker, size,
+ err);
+}
+
+namespace tinyexr
+{
+
+// out_data must be allocated initially with the block-header size
+// of the current image(-part) type
+static bool EncodePixelData(/* out */ std::vector<unsigned char>& out_data,
+ const unsigned char* const* images,
+ int compression_type,
+ int /*line_order*/,
+ int width, // for tiled : tile.width
+ int /*height*/, // for tiled : header.tile_size_y
+ int x_stride, // for tiled : header.tile_size_x
+ int line_no, // for tiled : 0
+ int num_lines, // for tiled : tile.height
+ size_t pixel_data_size,
+ const std::vector<ChannelInfo>& channels,
+ const std::vector<size_t>& channel_offset_list,
+ const void* compression_param = 0) // zfp compression param
+{
+ size_t buf_size = static_cast<size_t>(width) *
+ static_cast<size_t>(num_lines) *
+ static_cast<size_t>(pixel_data_size);
+ //int last2bit = (buf_size & 3);
+ // buf_size must be multiple of four
+ //if(last2bit) buf_size += 4 - last2bit;
+ std::vector<unsigned char> buf(buf_size);
+
+ size_t start_y = static_cast<size_t>(line_no);
+ for (size_t c = 0; c < channels.size(); c++) {
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ if (channels[c].requested_pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ for (int y = 0; y < num_lines; y++) {
+ // Assume increasing Y
+ float *line_ptr = reinterpret_cast<float *>(&buf.at(
+ static_cast<size_t>(pixel_data_size * y * width) +
+ channel_offset_list[c] *
+ static_cast<size_t>(width)));
+ for (int x = 0; x < width; x++) {
+ tinyexr::FP16 h16;
+ h16.u = reinterpret_cast<const unsigned short * const *>(
+ images)[c][(y + start_y) * x_stride + x];
+
+ tinyexr::FP32 f32 = half_to_float(h16);
+
+ tinyexr::swap4(&f32.f);
+
+ // line_ptr[x] = f32.f;
+ tinyexr::cpy4(line_ptr + x, &(f32.f));
+ }
+ }
+ } else if (channels[c].requested_pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ for (int y = 0; y < num_lines; y++) {
+ // Assume increasing Y
+ unsigned short *line_ptr = reinterpret_cast<unsigned short *>(
+ &buf.at(static_cast<size_t>(pixel_data_size * y *
+ width) +
+ channel_offset_list[c] *
+ static_cast<size_t>(width)));
+ for (int x = 0; x < width; x++) {
+ unsigned short val = reinterpret_cast<const unsigned short * const *>(
+ images)[c][(y + start_y) * x_stride + x];
+
+ tinyexr::swap2(&val);
+
+ // line_ptr[x] = val;
+ tinyexr::cpy2(line_ptr + x, &val);
+ }
+ }
+ } else {
+ assert(0);
+ }
+
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ if (channels[c].requested_pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ for (int y = 0; y < num_lines; y++) {
+ // Assume increasing Y
+ unsigned short *line_ptr = reinterpret_cast<unsigned short *>(
+ &buf.at(static_cast<size_t>(pixel_data_size * y *
+ width) +
+ channel_offset_list[c] *
+ static_cast<size_t>(width)));
+ for (int x = 0; x < width; x++) {
+ tinyexr::FP32 f32;
+ f32.f = reinterpret_cast<const float * const *>(
+ images)[c][(y + start_y) * x_stride + x];
+
+ tinyexr::FP16 h16;
+ h16 = float_to_half_full(f32);
+
+ tinyexr::swap2(reinterpret_cast<unsigned short *>(&h16.u));
+
+ // line_ptr[x] = h16.u;
+ tinyexr::cpy2(line_ptr + x, &(h16.u));
+ }
+ }
+ } else if (channels[c].requested_pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ for (int y = 0; y < num_lines; y++) {
+ // Assume increasing Y
+ float *line_ptr = reinterpret_cast<float *>(&buf.at(
+ static_cast<size_t>(pixel_data_size * y * width) +
+ channel_offset_list[c] *
+ static_cast<size_t>(width)));
+ for (int x = 0; x < width; x++) {
+ float val = reinterpret_cast<const float * const *>(
+ images)[c][(y + start_y) * x_stride + x];
+
+ tinyexr::swap4(&val);
+
+ // line_ptr[x] = val;
+ tinyexr::cpy4(line_ptr + x, &val);
+ }
+ }
+ } else {
+ assert(0);
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) {
+ for (int y = 0; y < num_lines; y++) {
+ // Assume increasing Y
+ unsigned int *line_ptr = reinterpret_cast<unsigned int *>(&buf.at(
+ static_cast<size_t>(pixel_data_size * y * width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (int x = 0; x < width; x++) {
+ unsigned int val = reinterpret_cast<const unsigned int * const *>(
+ images)[c][(y + start_y) * x_stride + x];
+
+ tinyexr::swap4(&val);
+
+ // line_ptr[x] = val;
+ tinyexr::cpy4(line_ptr + x, &val);
+ }
+ }
+ }
+ }
+
+ if (compression_type == TINYEXR_COMPRESSIONTYPE_NONE) {
+ // 4 byte: scan line
+ // 4 byte: data size
+ // ~ : pixel data(uncompressed)
+ out_data.insert(out_data.end(), buf.begin(), buf.end());
+
+ } else if ((compression_type == TINYEXR_COMPRESSIONTYPE_ZIPS) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_ZIP)) {
+#if TINYEXR_USE_MINIZ
+ std::vector<unsigned char> block(mz_compressBound(
+ static_cast<unsigned long>(buf.size())));
+#else
+ std::vector<unsigned char> block(
+ compressBound(static_cast<uLong>(buf.size())));
+#endif
+ tinyexr::tinyexr_uint64 outSize = block.size();
+
+ tinyexr::CompressZip(&block.at(0), outSize,
+ reinterpret_cast<const unsigned char *>(&buf.at(0)),
+ static_cast<unsigned long>(buf.size()));
+
+ // 4 byte: scan line
+ // 4 byte: data size
+ // ~ : pixel data(compressed)
+ unsigned int data_len = static_cast<unsigned int>(outSize); // truncate
+
+ out_data.insert(out_data.end(), block.begin(), block.begin() + data_len);
+
+ } else if (compression_type == TINYEXR_COMPRESSIONTYPE_RLE) {
+ // (buf.size() * 3) / 2 would be enough.
+ std::vector<unsigned char> block((buf.size() * 3) / 2);
+
+ tinyexr::tinyexr_uint64 outSize = block.size();
+
+ tinyexr::CompressRle(&block.at(0), outSize,
+ reinterpret_cast<const unsigned char *>(&buf.at(0)),
+ static_cast<unsigned long>(buf.size()));
+
+ // 4 byte: scan line
+ // 4 byte: data size
+ // ~ : pixel data(compressed)
+ unsigned int data_len = static_cast<unsigned int>(outSize); // truncate
+ out_data.insert(out_data.end(), block.begin(), block.begin() + data_len);
+
+ } else if (compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
+#if TINYEXR_USE_PIZ
+ unsigned int bufLen = 512 + // Avoid buffer overflow
+ 8192 + static_cast<unsigned int>(
+ 2 * static_cast<unsigned int>(
+ buf.size())); // @fixme { compute good bound. }
+ std::vector<unsigned char> block(bufLen);
+ unsigned int outSize = static_cast<unsigned int>(block.size());
+
+ CompressPiz(&block.at(0), &outSize,
+ reinterpret_cast<const unsigned char *>(&buf.at(0)),
+ buf.size(), channels, width, num_lines);
+
+ // 4 byte: scan line
+ // 4 byte: data size
+ // ~ : pixel data(compressed)
+ unsigned int data_len = outSize;
+ out_data.insert(out_data.end(), block.begin(), block.begin() + data_len);
+
+#else
+ assert(0);
+#endif
+ } else if (compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
+#if TINYEXR_USE_ZFP
+ const ZFPCompressionParam* zfp_compression_param = reinterpret_cast<const ZFPCompressionParam*>(compression_param);
+ std::vector<unsigned char> block;
+ unsigned int outSize;
+
+ tinyexr::CompressZfp(
+ &block, &outSize, reinterpret_cast<const float *>(&buf.at(0)),
+ width, num_lines, static_cast<int>(channels.size()), *zfp_compression_param);
+
+ // 4 byte: scan line
+ // 4 byte: data size
+ // ~ : pixel data(compressed)
+ unsigned int data_len = outSize;
+ out_data.insert(out_data.end(), block.begin(), block.begin() + data_len);
+
+#else
+ (void)compression_param;
+ assert(0);
+#endif
+ } else {
+ assert(0);
+ return false;
+ }
+
+ return true;
+}
+
+static int EncodeTiledLevel(const EXRImage* level_image, const EXRHeader* exr_header,
+ const std::vector<tinyexr::ChannelInfo>& channels,
+ std::vector<std::vector<unsigned char> >& data_list,
+ size_t start_index, // for data_list
+ int num_x_tiles, int num_y_tiles,
+ const std::vector<size_t>& channel_offset_list,
+ int pixel_data_size,
+ const void* compression_param, // must be set if zfp compression is enabled
+ std::string* err) {
+ int num_tiles = num_x_tiles * num_y_tiles;
+ assert(num_tiles == level_image->num_tiles);
+
+ if ((exr_header->tile_size_x > level_image->width || exr_header->tile_size_y > level_image->height) &&
+ level_image->level_x == 0 && level_image->level_y == 0) {
+ if (err) {
+ (*err) += "Failed to encode tile data.\n";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+
+#if TINYEXR_HAS_CXX11 && (TINYEXR_USE_THREAD > 0)
+ std::atomic<bool> invalid_data(false);
+#else
+ bool invalid_data(false);
+#endif
+
+#if TINYEXR_HAS_CXX11 && (TINYEXR_USE_THREAD > 0)
+ std::vector<std::thread> workers;
+ std::atomic<int> tile_count(0);
+
+ int num_threads = std::max(1, int(std::thread::hardware_concurrency()));
+ if (num_threads > int(num_tiles)) {
+ num_threads = int(num_tiles);
+ }
+
+ for (int t = 0; t < num_threads; t++) {
+ workers.emplace_back(std::thread([&]() {
+ int i = 0;
+ while ((i = tile_count++) < num_tiles) {
+
+#else
+ // Use signed int since some OpenMP compiler doesn't allow unsigned type for
+ // `parallel for`
+#if TINYEXR_USE_OPENMP
+#pragma omp parallel for
+#endif
+ for (int i = 0; i < num_tiles; i++) {
+
+#endif
+ size_t tile_idx = static_cast<size_t>(i);
+ size_t data_idx = tile_idx + start_index;
+
+ int x_tile = i % num_x_tiles;
+ int y_tile = i / num_x_tiles;
+
+ EXRTile& tile = level_image->tiles[tile_idx];
+
+ const unsigned char* const* images =
+ static_cast<const unsigned char* const*>(tile.images);
+
+ data_list[data_idx].resize(5*sizeof(int));
+ size_t data_header_size = data_list[data_idx].size();
+ bool ret = EncodePixelData(data_list[data_idx],
+ images,
+ exr_header->compression_type,
+ 0, // increasing y
+ tile.width,
+ exr_header->tile_size_y,
+ exr_header->tile_size_x,
+ 0,
+ tile.height,
+ pixel_data_size,
+ channels,
+ channel_offset_list,
+ compression_param);
+ if (!ret) {
+ invalid_data = true;
+ continue;
+ }
+ assert(data_list[data_idx].size() > data_header_size);
+ int data_len = static_cast<int>(data_list[data_idx].size() - data_header_size);
+ //tileX, tileY, levelX, levelY // pixel_data_size(int)
+ memcpy(&data_list[data_idx][0], &x_tile, sizeof(int));
+ memcpy(&data_list[data_idx][4], &y_tile, sizeof(int));
+ memcpy(&data_list[data_idx][8], &level_image->level_x, sizeof(int));
+ memcpy(&data_list[data_idx][12], &level_image->level_y, sizeof(int));
+ memcpy(&data_list[data_idx][16], &data_len, sizeof(int));
+
+ swap4(reinterpret_cast<int*>(&data_list[data_idx][0]));
+ swap4(reinterpret_cast<int*>(&data_list[data_idx][4]));
+ swap4(reinterpret_cast<int*>(&data_list[data_idx][8]));
+ swap4(reinterpret_cast<int*>(&data_list[data_idx][12]));
+ swap4(reinterpret_cast<int*>(&data_list[data_idx][16]));
+
+#if TINYEXR_HAS_CXX11 && (TINYEXR_USE_THREAD > 0)
+ }
+}));
+ }
+
+ for (auto &t : workers) {
+ t.join();
+ }
+#else
+ } // omp parallel
+#endif
+
+ if (invalid_data) {
+ if (err) {
+ (*err) += "Failed to encode tile data.\n";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ return TINYEXR_SUCCESS;
+}
+
+static int NumScanlines(int compression_type) {
+ int num_scanlines = 1;
+ if (compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) {
+ num_scanlines = 16;
+ } else if (compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
+ num_scanlines = 32;
+ } else if (compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
+ num_scanlines = 16;
+ }
+ return num_scanlines;
+}
+
+static int EncodeChunk(const EXRImage* exr_image, const EXRHeader* exr_header,
+ const std::vector<ChannelInfo>& channels,
+ int num_blocks,
+ tinyexr_uint64 chunk_offset, // starting offset of current chunk
+ bool is_multipart,
+ OffsetData& offset_data, // output block offsets, must be initialized
+ std::vector<std::vector<unsigned char> >& data_list, // output
+ tinyexr_uint64& total_size, // output: ending offset of current chunk
+ std::string* err) {
+ int num_scanlines = NumScanlines(exr_header->compression_type);
+
+ data_list.resize(num_blocks);
+
+ std::vector<size_t> channel_offset_list(
+ static_cast<size_t>(exr_header->num_channels));
+
+ int pixel_data_size = 0;
+ {
+ size_t channel_offset = 0;
+ for (size_t c = 0; c < static_cast<size_t>(exr_header->num_channels); c++) {
+ channel_offset_list[c] = channel_offset;
+ if (channels[c].requested_pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ pixel_data_size += sizeof(unsigned short);
+ channel_offset += sizeof(unsigned short);
+ } else if (channels[c].requested_pixel_type ==
+ TINYEXR_PIXELTYPE_FLOAT) {
+ pixel_data_size += sizeof(float);
+ channel_offset += sizeof(float);
+ } else if (channels[c].requested_pixel_type == TINYEXR_PIXELTYPE_UINT) {
+ pixel_data_size += sizeof(unsigned int);
+ channel_offset += sizeof(unsigned int);
+ } else {
+ assert(0);
+ }
+ }
+ }
+
+ const void* compression_param = 0;
+#if TINYEXR_USE_ZFP
+ tinyexr::ZFPCompressionParam zfp_compression_param;
+
+ // Use ZFP compression parameter from custom attributes(if such a parameter
+ // exists)
+ {
+ std::string e;
+ bool ret = tinyexr::FindZFPCompressionParam(
+ &zfp_compression_param, exr_header->custom_attributes,
+ exr_header->num_custom_attributes, &e);
+
+ if (!ret) {
+ // Use predefined compression parameter.
+ zfp_compression_param.type = 0;
+ zfp_compression_param.rate = 2;
+ }
+ compression_param = &zfp_compression_param;
+ }
+#endif
+
+ tinyexr_uint64 offset = chunk_offset;
+ tinyexr_uint64 doffset = is_multipart ? 4u : 0u;
+
+ if (exr_image->tiles) {
+ const EXRImage* level_image = exr_image;
+ size_t block_idx = 0;
+ tinyexr::tinyexr_uint64 block_data_size = 0;
+ int num_levels = (exr_header->tile_level_mode != TINYEXR_TILE_RIPMAP_LEVELS) ?
+ offset_data.num_x_levels : (offset_data.num_x_levels * offset_data.num_y_levels);
+ for (int level_index = 0; level_index < num_levels; ++level_index) {
+ if (!level_image) {
+ if (err) {
+ (*err) += "Invalid number of tiled levels for EncodeChunk\n";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ int level_index_from_image = LevelIndex(level_image->level_x, level_image->level_y,
+ exr_header->tile_level_mode, offset_data.num_x_levels);
+ if (level_index_from_image != level_index) {
+ if (err) {
+ (*err) += "Incorrect level ordering in tiled image\n";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ int num_y_tiles = (int)offset_data.offsets[level_index].size();
+ assert(num_y_tiles);
+ int num_x_tiles = (int)offset_data.offsets[level_index][0].size();
+ assert(num_x_tiles);
+
+ std::string e;
+ int ret = EncodeTiledLevel(level_image,
+ exr_header,
+ channels,
+ data_list,
+ block_idx,
+ num_x_tiles,
+ num_y_tiles,
+ channel_offset_list,
+ pixel_data_size,
+ compression_param,
+ &e);
+ if (ret != TINYEXR_SUCCESS) {
+ if (!e.empty() && err) {
+ (*err) += e;
+ }
+ return ret;
+ }
+
+ for (size_t j = 0; j < static_cast<size_t>(num_y_tiles); ++j)
+ for (size_t i = 0; i < static_cast<size_t>(num_x_tiles); ++i) {
+ offset_data.offsets[level_index][j][i] = offset;
+ swap8(reinterpret_cast<tinyexr_uint64*>(&offset_data.offsets[level_index][j][i]));
+ offset += data_list[block_idx].size() + doffset;
+ block_data_size += data_list[block_idx].size();
+ ++block_idx;
+ }
+ level_image = level_image->next_level;
+ }
+ assert(static_cast<int>(block_idx) == num_blocks);
+ total_size = offset;
+ } else { // scanlines
+ std::vector<tinyexr::tinyexr_uint64>& offsets = offset_data.offsets[0][0];
+
+#if TINYEXR_HAS_CXX11 && (TINYEXR_USE_THREAD > 0)
+ std::atomic<bool> invalid_data(false);
+ std::vector<std::thread> workers;
+ std::atomic<int> block_count(0);
+
+ int num_threads = std::min(std::max(1, int(std::thread::hardware_concurrency())), num_blocks);
+
+ for (int t = 0; t < num_threads; t++) {
+ workers.emplace_back(std::thread([&]() {
+ int i = 0;
+ while ((i = block_count++) < num_blocks) {
+
+#else
+ bool invalid_data(false);
+#if TINYEXR_USE_OPENMP
+#pragma omp parallel for
+#endif
+ for (int i = 0; i < num_blocks; i++) {
+
+#endif
+ int start_y = num_scanlines * i;
+ int end_Y = (std::min)(num_scanlines * (i + 1), exr_image->height);
+ int num_lines = end_Y - start_y;
+
+ const unsigned char* const* images =
+ static_cast<const unsigned char* const*>(exr_image->images);
+
+ data_list[i].resize(2*sizeof(int));
+ size_t data_header_size = data_list[i].size();
+
+ bool ret = EncodePixelData(data_list[i],
+ images,
+ exr_header->compression_type,
+ 0, // increasing y
+ exr_image->width,
+ exr_image->height,
+ exr_image->width,
+ start_y,
+ num_lines,
+ pixel_data_size,
+ channels,
+ channel_offset_list,
+ compression_param);
+ if (!ret) {
+ invalid_data = true;
+ continue; // "break" cannot be used with OpenMP
+ }
+ assert(data_list[i].size() > data_header_size);
+ int data_len = static_cast<int>(data_list[i].size() - data_header_size);
+ memcpy(&data_list[i][0], &start_y, sizeof(int));
+ memcpy(&data_list[i][4], &data_len, sizeof(int));
+
+ swap4(reinterpret_cast<int*>(&data_list[i][0]));
+ swap4(reinterpret_cast<int*>(&data_list[i][4]));
+#if TINYEXR_HAS_CXX11 && (TINYEXR_USE_THREAD > 0)
+ }
+ }));
+ }
+
+ for (auto &t : workers) {
+ t.join();
+ }
+#else
+ } // omp parallel
+#endif
+
+ if (invalid_data) {
+ if (err) {
+ (*err) += "Failed to encode scanline data.\n";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ for (size_t i = 0; i < static_cast<size_t>(num_blocks); i++) {
+ offsets[i] = offset;
+ tinyexr::swap8(reinterpret_cast<tinyexr::tinyexr_uint64 *>(&offsets[i]));
+ offset += data_list[i].size() + doffset;
+ }
+
+ total_size = static_cast<size_t>(offset);
+ }
+ return TINYEXR_SUCCESS;
+}
+
+// can save a single or multi-part image (no deep* formats)
+static size_t SaveEXRNPartImageToMemory(const EXRImage* exr_images,
+ const EXRHeader** exr_headers,
+ unsigned int num_parts,
+ unsigned char** memory_out, const char** err) {
+ if (exr_images == NULL || exr_headers == NULL || num_parts == 0 ||
+ memory_out == NULL) {
+ SetErrorMessage("Invalid argument for SaveEXRNPartImageToMemory",
+ err);
+ return 0;
+ }
+ {
+ for (unsigned int i = 0; i < num_parts; ++i) {
+ if (exr_headers[i]->compression_type < 0) {
+ SetErrorMessage("Invalid argument for SaveEXRNPartImageToMemory",
+ err);
+ return 0;
+ }
+#if !TINYEXR_USE_PIZ
+ if (exr_headers[i]->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
+ SetErrorMessage("PIZ compression is not supported in this build",
+ err);
+ return 0;
+ }
+#endif
+#if !TINYEXR_USE_ZFP
+ if (exr_headers[i]->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
+ SetErrorMessage("ZFP compression is not supported in this build",
+ err);
+ return 0;
+ }
+#else
+ for (int c = 0; c < exr_header->num_channels; ++c) {
+ if (exr_headers[i]->requested_pixel_types[c] != TINYEXR_PIXELTYPE_FLOAT) {
+ SetErrorMessage("Pixel type must be FLOAT for ZFP compression",
+ err);
+ return 0;
+ }
+ }
+#endif
+ }
+ }
+
+ std::vector<unsigned char> memory;
+
+ // Header
+ {
+ const char header[] = { 0x76, 0x2f, 0x31, 0x01 };
+ memory.insert(memory.end(), header, header + 4);
+ }
+
+ // Version
+ // using value from the first header
+ int long_name = exr_headers[0]->long_name;
+ {
+ char marker[] = { 2, 0, 0, 0 };
+ /* @todo
+ if (exr_header->non_image) {
+ marker[1] |= 0x8;
+ }
+ */
+ // tiled
+ if (num_parts == 1 && exr_images[0].tiles) {
+ marker[1] |= 0x2;
+ }
+ // long_name
+ if (long_name) {
+ marker[1] |= 0x4;
+ }
+ // multipart
+ if (num_parts > 1) {
+ marker[1] |= 0x10;
+ }
+ memory.insert(memory.end(), marker, marker + 4);
+ }
+
+ int total_chunk_count = 0;
+ std::vector<int> chunk_count(num_parts);
+ std::vector<OffsetData> offset_data(num_parts);
+ for (unsigned int i = 0; i < num_parts; ++i) {
+ if (!exr_images[i].tiles) {
+ int num_scanlines = NumScanlines(exr_headers[i]->compression_type);
+ chunk_count[i] =
+ (exr_images[i].height + num_scanlines - 1) / num_scanlines;
+ InitSingleResolutionOffsets(offset_data[i], chunk_count[i]);
+ total_chunk_count += chunk_count[i];
+ } else {
+ {
+ std::vector<int> num_x_tiles, num_y_tiles;
+ PrecalculateTileInfo(num_x_tiles, num_y_tiles, exr_headers[i]);
+ chunk_count[i] =
+ InitTileOffsets(offset_data[i], exr_headers[i], num_x_tiles, num_y_tiles);
+ total_chunk_count += chunk_count[i];
+ }
+ }
+ }
+ // Write attributes to memory buffer.
+ std::vector< std::vector<tinyexr::ChannelInfo> > channels(num_parts);
+ {
+ std::set<std::string> partnames;
+ for (unsigned int i = 0; i < num_parts; ++i) {
+ //channels
+ {
+ std::vector<unsigned char> data;
+
+ for (int c = 0; c < exr_headers[i]->num_channels; c++) {
+ tinyexr::ChannelInfo info;
+ info.p_linear = 0;
+ info.pixel_type = exr_headers[i]->pixel_types[c];
+ info.requested_pixel_type = exr_headers[i]->requested_pixel_types[c];
+ info.x_sampling = 1;
+ info.y_sampling = 1;
+ info.name = std::string(exr_headers[i]->channels[c].name);
+ channels[i].push_back(info);
+ }
+
+ tinyexr::WriteChannelInfo(data, channels[i]);
+
+ tinyexr::WriteAttributeToMemory(&memory, "channels", "chlist", &data.at(0),
+ static_cast<int>(data.size()));
+ }
+
+ {
+ int comp = exr_headers[i]->compression_type;
+ swap4(&comp);
+ WriteAttributeToMemory(
+ &memory, "compression", "compression",
+ reinterpret_cast<const unsigned char*>(&comp), 1);
+ }
+
+ {
+ int data[4] = { 0, 0, exr_images[i].width - 1, exr_images[i].height - 1 };
+ swap4(&data[0]);
+ swap4(&data[1]);
+ swap4(&data[2]);
+ swap4(&data[3]);
+ WriteAttributeToMemory(
+ &memory, "dataWindow", "box2i",
+ reinterpret_cast<const unsigned char*>(data), sizeof(int) * 4);
+
+ int data0[4] = { 0, 0, exr_images[0].width - 1, exr_images[0].height - 1 };
+ swap4(&data0[0]);
+ swap4(&data0[1]);
+ swap4(&data0[2]);
+ swap4(&data0[3]);
+ // Note: must be the same across parts (currently, using value from the first header)
+ WriteAttributeToMemory(
+ &memory, "displayWindow", "box2i",
+ reinterpret_cast<const unsigned char*>(data0), sizeof(int) * 4);
+ }
+
+ {
+ unsigned char line_order = 0; // @fixme { read line_order from EXRHeader }
+ WriteAttributeToMemory(&memory, "lineOrder", "lineOrder",
+ &line_order, 1);
+ }
+
+ {
+ // Note: must be the same across parts
+ float aspectRatio = 1.0f;
+ swap4(&aspectRatio);
+ WriteAttributeToMemory(
+ &memory, "pixelAspectRatio", "float",
+ reinterpret_cast<const unsigned char*>(&aspectRatio), sizeof(float));
+ }
+
+ {
+ float center[2] = { 0.0f, 0.0f };
+ swap4(&center[0]);
+ swap4(&center[1]);
+ WriteAttributeToMemory(
+ &memory, "screenWindowCenter", "v2f",
+ reinterpret_cast<const unsigned char*>(center), 2 * sizeof(float));
+ }
+
+ {
+ float w = 1.0f;
+ swap4(&w);
+ WriteAttributeToMemory(&memory, "screenWindowWidth", "float",
+ reinterpret_cast<const unsigned char*>(&w),
+ sizeof(float));
+ }
+
+ if (exr_images[i].tiles) {
+ unsigned char tile_mode = static_cast<unsigned char>(exr_headers[i]->tile_level_mode & 0x3);
+ if (exr_headers[i]->tile_rounding_mode) tile_mode |= (1u << 4u);
+ //unsigned char data[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ unsigned int datai[3] = { 0, 0, 0 };
+ unsigned char* data = reinterpret_cast<unsigned char*>(&datai[0]);
+ datai[0] = static_cast<unsigned int>(exr_headers[i]->tile_size_x);
+ datai[1] = static_cast<unsigned int>(exr_headers[i]->tile_size_y);
+ data[8] = tile_mode;
+ swap4(reinterpret_cast<unsigned int*>(&data[0]));
+ swap4(reinterpret_cast<unsigned int*>(&data[4]));
+ WriteAttributeToMemory(
+ &memory, "tiles", "tiledesc",
+ reinterpret_cast<const unsigned char*>(data), 9);
+ }
+
+ // must be present for multi-part files - according to spec.
+ if (num_parts > 1) {
+ // name
+ {
+ size_t len = 0;
+ if ((len = strlen(exr_headers[i]->name)) > 0) {
+ partnames.emplace(exr_headers[i]->name);
+ if (partnames.size() != i + 1) {
+ SetErrorMessage("'name' attributes must be unique for a multi-part file", err);
+ return 0;
+ }
+ WriteAttributeToMemory(
+ &memory, "name", "string",
+ reinterpret_cast<const unsigned char*>(exr_headers[i]->name),
+ static_cast<int>(len));
+ } else {
+ SetErrorMessage("Invalid 'name' attribute for a multi-part file", err);
+ return 0;
+ }
+ }
+ // type
+ {
+ const char* type = "scanlineimage";
+ if (exr_images[i].tiles) type = "tiledimage";
+ WriteAttributeToMemory(
+ &memory, "type", "string",
+ reinterpret_cast<const unsigned char*>(type),
+ static_cast<int>(strlen(type)));
+ }
+ // chunkCount
+ {
+ WriteAttributeToMemory(
+ &memory, "chunkCount", "int",
+ reinterpret_cast<const unsigned char*>(&chunk_count[i]),
+ 4);
+ }
+ }
+
+ // Custom attributes
+ if (exr_headers[i]->num_custom_attributes > 0) {
+ for (int j = 0; j < exr_headers[i]->num_custom_attributes; j++) {
+ tinyexr::WriteAttributeToMemory(
+ &memory, exr_headers[i]->custom_attributes[j].name,
+ exr_headers[i]->custom_attributes[j].type,
+ reinterpret_cast<const unsigned char*>(
+ exr_headers[i]->custom_attributes[j].value),
+ exr_headers[i]->custom_attributes[j].size);
+ }
+ }
+
+ { // end of header
+ memory.push_back(0);
+ }
+ }
+ }
+ if (num_parts > 1) {
+ // end of header list
+ memory.push_back(0);
+ }
+
+ tinyexr_uint64 chunk_offset = memory.size() + size_t(total_chunk_count) * sizeof(tinyexr_uint64);
+
+ tinyexr_uint64 total_size = 0;
+ std::vector< std::vector< std::vector<unsigned char> > > data_lists(num_parts);
+ for (unsigned int i = 0; i < num_parts; ++i) {
+ std::string e;
+ int ret = EncodeChunk(&exr_images[i], exr_headers[i],
+ channels[i],
+ chunk_count[i],
+ // starting offset of current chunk after part-number
+ chunk_offset,
+ num_parts > 1,
+ offset_data[i], // output: block offsets, must be initialized
+ data_lists[i], // output
+ total_size, // output
+ &e);
+ if (ret != TINYEXR_SUCCESS) {
+ if (!e.empty()) {
+ tinyexr::SetErrorMessage(e, err);
+ }
+ return 0;
+ }
+ chunk_offset = total_size;
+ }
+
+ // Allocating required memory
+ if (total_size == 0) { // something went wrong
+ tinyexr::SetErrorMessage("Output memory size is zero", err);
+ return 0;
+ }
+ (*memory_out) = static_cast<unsigned char*>(malloc(total_size));
+
+ // Writing header
+ memcpy((*memory_out), &memory[0], memory.size());
+ unsigned char* memory_ptr = *memory_out + memory.size();
+ size_t sum = memory.size();
+
+ // Writing offset data for chunks
+ for (unsigned int i = 0; i < num_parts; ++i) {
+ if (exr_images[i].tiles) {
+ const EXRImage* level_image = &exr_images[i];
+ int num_levels = (exr_headers[i]->tile_level_mode != TINYEXR_TILE_RIPMAP_LEVELS) ?
+ offset_data[i].num_x_levels : (offset_data[i].num_x_levels * offset_data[i].num_y_levels);
+ for (int level_index = 0; level_index < num_levels; ++level_index) {
+ for (size_t j = 0; j < offset_data[i].offsets[level_index].size(); ++j) {
+ size_t num_bytes = sizeof(tinyexr_uint64) * offset_data[i].offsets[level_index][j].size();
+ sum += num_bytes;
+ assert(sum <= total_size);
+ memcpy(memory_ptr,
+ reinterpret_cast<unsigned char*>(&offset_data[i].offsets[level_index][j][0]),
+ num_bytes);
+ memory_ptr += num_bytes;
+ }
+ level_image = level_image->next_level;
+ }
+ } else {
+ size_t num_bytes = sizeof(tinyexr::tinyexr_uint64) * static_cast<size_t>(chunk_count[i]);
+ sum += num_bytes;
+ assert(sum <= total_size);
+ std::vector<tinyexr::tinyexr_uint64>& offsets = offset_data[i].offsets[0][0];
+ memcpy(memory_ptr, reinterpret_cast<unsigned char*>(&offsets[0]), num_bytes);
+ memory_ptr += num_bytes;
+ }
+ }
+
+ // Writing chunk data
+ for (unsigned int i = 0; i < num_parts; ++i) {
+ for (size_t j = 0; j < static_cast<size_t>(chunk_count[i]); ++j) {
+ if (num_parts > 1) {
+ sum += 4;
+ assert(sum <= total_size);
+ unsigned int part_number = i;
+ swap4(&part_number);
+ memcpy(memory_ptr, &part_number, 4);
+ memory_ptr += 4;
+ }
+ sum += data_lists[i][j].size();
+ assert(sum <= total_size);
+ memcpy(memory_ptr, &data_lists[i][j][0], data_lists[i][j].size());
+ memory_ptr += data_lists[i][j].size();
+ }
+ }
+ assert(sum == total_size);
+ return total_size; // OK
+}
+
+} // tinyexr
+
+size_t SaveEXRImageToMemory(const EXRImage* exr_image,
+ const EXRHeader* exr_header,
+ unsigned char** memory_out, const char** err) {
+ return tinyexr::SaveEXRNPartImageToMemory(exr_image, &exr_header, 1, memory_out, err);
+}
+
+int SaveEXRImageToFile(const EXRImage *exr_image, const EXRHeader *exr_header,
+ const char *filename, const char **err) {
+ if (exr_image == NULL || filename == NULL ||
+ exr_header->compression_type < 0) {
+ tinyexr::SetErrorMessage("Invalid argument for SaveEXRImageToFile", err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+#if !TINYEXR_USE_PIZ
+ if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
+ tinyexr::SetErrorMessage("PIZ compression is not supported in this build",
+ err);
+ return TINYEXR_ERROR_UNSUPPORTED_FEATURE;
+ }
+#endif
+
+#if !TINYEXR_USE_ZFP
+ if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
+ tinyexr::SetErrorMessage("ZFP compression is not supported in this build",
+ err);
+ return TINYEXR_ERROR_UNSUPPORTED_FEATURE;
+ }
+#endif
+
+ FILE *fp = NULL;
+#ifdef _WIN32
+#if defined(_MSC_VER) || (defined(MINGW_HAS_SECURE_API) && MINGW_HAS_SECURE_API) // MSVC, MinGW GCC, or Clang
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"wb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot write a file: " + std::string(filename),
+ err);
+ return TINYEXR_ERROR_CANT_WRITE_FILE;
+ }
+#else
+ // Unknown compiler or MinGW without MINGW_HAS_SECURE_API.
+ fp = fopen(filename, "wb");
+#endif
+#else
+ fp = fopen(filename, "wb");
+#endif
+ if (!fp) {
+ tinyexr::SetErrorMessage("Cannot write a file: " + std::string(filename),
+ err);
+ return TINYEXR_ERROR_CANT_WRITE_FILE;
+ }
+
+ unsigned char *mem = NULL;
+ size_t mem_size = SaveEXRImageToMemory(exr_image, exr_header, &mem, err);
+ if (mem_size == 0) {
+ return TINYEXR_ERROR_SERIALZATION_FAILED;
+ }
+
+ size_t written_size = 0;
+ if ((mem_size > 0) && mem) {
+ written_size = fwrite(mem, 1, mem_size, fp);
+ }
+ free(mem);
+
+ fclose(fp);
+
+ if (written_size != mem_size) {
+ tinyexr::SetErrorMessage("Cannot write a file", err);
+ return TINYEXR_ERROR_CANT_WRITE_FILE;
+ }
+
+ return TINYEXR_SUCCESS;
+}
+
+size_t SaveEXRMultipartImageToMemory(const EXRImage* exr_images,
+ const EXRHeader** exr_headers,
+ unsigned int num_parts,
+ unsigned char** memory_out, const char** err) {
+ if (exr_images == NULL || exr_headers == NULL || num_parts < 2 ||
+ memory_out == NULL) {
+ tinyexr::SetErrorMessage("Invalid argument for SaveEXRNPartImageToMemory",
+ err);
+ return 0;
+ }
+ return tinyexr::SaveEXRNPartImageToMemory(exr_images, exr_headers, num_parts, memory_out, err);
+}
+
+int SaveEXRMultipartImageToFile(const EXRImage* exr_images,
+ const EXRHeader** exr_headers,
+ unsigned int num_parts,
+ const char* filename,
+ const char** err) {
+ if (exr_images == NULL || exr_headers == NULL || num_parts < 2) {
+ tinyexr::SetErrorMessage("Invalid argument for SaveEXRMultipartImageToFile",
+ err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ FILE *fp = NULL;
+#ifdef _WIN32
+#if defined(_MSC_VER) || (defined(MINGW_HAS_SECURE_API) && MINGW_HAS_SECURE_API) // MSVC, MinGW GCC, or Clang.
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"wb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot write a file: " + std::string(filename),
+ err);
+ return TINYEXR_ERROR_CANT_WRITE_FILE;
+ }
+#else
+ // Unknown compiler or MinGW without MINGW_HAS_SECURE_API.
+ fp = fopen(filename, "wb");
+#endif
+#else
+ fp = fopen(filename, "wb");
+#endif
+ if (!fp) {
+ tinyexr::SetErrorMessage("Cannot write a file: " + std::string(filename),
+ err);
+ return TINYEXR_ERROR_CANT_WRITE_FILE;
+ }
+
+ unsigned char *mem = NULL;
+ size_t mem_size = SaveEXRMultipartImageToMemory(exr_images, exr_headers, num_parts, &mem, err);
+ if (mem_size == 0) {
+ return TINYEXR_ERROR_SERIALZATION_FAILED;
+ }
+
+ size_t written_size = 0;
+ if ((mem_size > 0) && mem) {
+ written_size = fwrite(mem, 1, mem_size, fp);
+ }
+ free(mem);
+
+ fclose(fp);
+
+ if (written_size != mem_size) {
+ tinyexr::SetErrorMessage("Cannot write a file", err);
+ return TINYEXR_ERROR_CANT_WRITE_FILE;
+ }
+
+ return TINYEXR_SUCCESS;
+}
+
+int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) {
+ if (deep_image == NULL) {
+ tinyexr::SetErrorMessage("Invalid argument for LoadDeepEXR", err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+#ifdef _WIN32
+ FILE *fp = NULL;
+#if defined(_MSC_VER) || (defined(MINGW_HAS_SECURE_API) && MINGW_HAS_SECURE_API) // MSVC, MinGW GCC, or Clang.
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read a file " + std::string(filename),
+ err);
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+#else
+ // Unknown compiler or MinGW without MINGW_HAS_SECURE_API.
+ fp = fopen(filename, "rb");
+#endif
+ if (!fp) {
+ tinyexr::SetErrorMessage("Cannot read a file " + std::string(filename),
+ err);
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+#else
+ FILE *fp = fopen(filename, "rb");
+ if (!fp) {
+ tinyexr::SetErrorMessage("Cannot read a file " + std::string(filename),
+ err);
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+#endif
+
+ size_t filesize;
+ // Compute size
+ fseek(fp, 0, SEEK_END);
+ filesize = static_cast<size_t>(ftell(fp));
+ fseek(fp, 0, SEEK_SET);
+
+ if (filesize == 0) {
+ fclose(fp);
+ tinyexr::SetErrorMessage("File size is zero : " + std::string(filename),
+ err);
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
+
+ std::vector<char> buf(filesize); // @todo { use mmap }
+ {
+ size_t ret;
+ ret = fread(&buf[0], 1, filesize, fp);
+ assert(ret == filesize);
+ (void)ret;
+ }
+ fclose(fp);
+
+ const char *head = &buf[0];
+ const char *marker = &buf[0];
+
+ // Header check.
+ {
+ const char header[] = {0x76, 0x2f, 0x31, 0x01};
+
+ if (memcmp(marker, header, 4) != 0) {
+ tinyexr::SetErrorMessage("Invalid magic number", err);
+ return TINYEXR_ERROR_INVALID_MAGIC_NUMBER;
+ }
+ marker += 4;
+ }
+
+ // Version, scanline.
+ {
+ // ver 2.0, scanline, deep bit on(0x800)
+ // must be [2, 0, 0, 0]
+ if (marker[0] != 2 || marker[1] != 8 || marker[2] != 0 || marker[3] != 0) {
+ tinyexr::SetErrorMessage("Unsupported version or scanline", err);
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+ }
+
+ marker += 4;
+ }
+
+ int dx = -1;
+ int dy = -1;
+ int dw = -1;
+ int dh = -1;
+ int num_scanline_blocks = 1; // 16 for ZIP compression.
+ int compression_type = -1;
+ int num_channels = -1;
+ std::vector<tinyexr::ChannelInfo> channels;
+
+ // Read attributes
+ size_t size = filesize - tinyexr::kEXRVersionSize;
+ for (;;) {
+ if (0 == size) {
+ return TINYEXR_ERROR_INVALID_DATA;
+ } else if (marker[0] == '\0') {
+ marker++;
+ size--;
+ break;
+ }
+
+ std::string attr_name;
+ std::string attr_type;
+ std::vector<unsigned char> data;
+ size_t marker_size;
+ if (!tinyexr::ReadAttribute(&attr_name, &attr_type, &data, &marker_size,
+ marker, size)) {
+ std::stringstream ss;
+ ss << "Failed to parse attribute\n";
+ tinyexr::SetErrorMessage(ss.str(), err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ marker += marker_size;
+ size -= marker_size;
+
+ if (attr_name.compare("compression") == 0) {
+ compression_type = data[0];
+ if (compression_type > TINYEXR_COMPRESSIONTYPE_PIZ) {
+ std::stringstream ss;
+ ss << "Unsupported compression type : " << compression_type;
+ tinyexr::SetErrorMessage(ss.str(), err);
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+ }
+
+ if (compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) {
+ num_scanline_blocks = 16;
+ }
+
+ } else if (attr_name.compare("channels") == 0) {
+ // name: zero-terminated string, from 1 to 255 bytes long
+ // pixel type: int, possible values are: UINT = 0 HALF = 1 FLOAT = 2
+ // pLinear: unsigned char, possible values are 0 and 1
+ // reserved: three chars, should be zero
+ // xSampling: int
+ // ySampling: int
+
+ if (!tinyexr::ReadChannelInfo(channels, data)) {
+ tinyexr::SetErrorMessage("Failed to parse channel info", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ num_channels = static_cast<int>(channels.size());
+
+ if (num_channels < 1) {
+ tinyexr::SetErrorMessage("Invalid channels format", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ } else if (attr_name.compare("dataWindow") == 0) {
+ memcpy(&dx, &data.at(0), sizeof(int));
+ memcpy(&dy, &data.at(4), sizeof(int));
+ memcpy(&dw, &data.at(8), sizeof(int));
+ memcpy(&dh, &data.at(12), sizeof(int));
+ tinyexr::swap4(&dx);
+ tinyexr::swap4(&dy);
+ tinyexr::swap4(&dw);
+ tinyexr::swap4(&dh);
+
+ } else if (attr_name.compare("displayWindow") == 0) {
+ int x;
+ int y;
+ int w;
+ int h;
+ memcpy(&x, &data.at(0), sizeof(int));
+ memcpy(&y, &data.at(4), sizeof(int));
+ memcpy(&w, &data.at(8), sizeof(int));
+ memcpy(&h, &data.at(12), sizeof(int));
+ tinyexr::swap4(&x);
+ tinyexr::swap4(&y);
+ tinyexr::swap4(&w);
+ tinyexr::swap4(&h);
+ }
+ }
+
+ assert(dx >= 0);
+ assert(dy >= 0);
+ assert(dw >= 0);
+ assert(dh >= 0);
+ assert(num_channels >= 1);
+
+ int data_width = dw - dx + 1;
+ int data_height = dh - dy + 1;
+
+ // Read offset tables.
+ int num_blocks = data_height / num_scanline_blocks;
+ if (num_blocks * num_scanline_blocks < data_height) {
+ num_blocks++;
+ }
+
+ std::vector<tinyexr::tinyexr_int64> offsets(static_cast<size_t>(num_blocks));
+
+ for (size_t y = 0; y < static_cast<size_t>(num_blocks); y++) {
+ tinyexr::tinyexr_int64 offset;
+ memcpy(&offset, marker, sizeof(tinyexr::tinyexr_int64));
+ tinyexr::swap8(reinterpret_cast<tinyexr::tinyexr_uint64 *>(&offset));
+ marker += sizeof(tinyexr::tinyexr_int64); // = 8
+ offsets[y] = offset;
+ }
+
+#if TINYEXR_USE_PIZ
+ if ((compression_type == TINYEXR_COMPRESSIONTYPE_NONE) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_RLE) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_ZIPS) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_PIZ)) {
+#else
+ if ((compression_type == TINYEXR_COMPRESSIONTYPE_NONE) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_RLE) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_ZIPS) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_ZIP)) {
+#endif
+ // OK
+ } else {
+ tinyexr::SetErrorMessage("Unsupported compression format", err);
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+ }
+
+ deep_image->image = static_cast<float ***>(
+ malloc(sizeof(float **) * static_cast<size_t>(num_channels)));
+ for (int c = 0; c < num_channels; c++) {
+ deep_image->image[c] = static_cast<float **>(
+ malloc(sizeof(float *) * static_cast<size_t>(data_height)));
+ for (int y = 0; y < data_height; y++) {
+ }
+ }
+
+ deep_image->offset_table = static_cast<int **>(
+ malloc(sizeof(int *) * static_cast<size_t>(data_height)));
+ for (int y = 0; y < data_height; y++) {
+ deep_image->offset_table[y] = static_cast<int *>(
+ malloc(sizeof(int) * static_cast<size_t>(data_width)));
+ }
+
+ for (size_t y = 0; y < static_cast<size_t>(num_blocks); y++) {
+ const unsigned char *data_ptr =
+ reinterpret_cast<const unsigned char *>(head + offsets[y]);
+
+ // int: y coordinate
+ // int64: packed size of pixel offset table
+ // int64: packed size of sample data
+ // int64: unpacked size of sample data
+ // compressed pixel offset table
+ // compressed sample data
+ int line_no;
+ tinyexr::tinyexr_int64 packedOffsetTableSize;
+ tinyexr::tinyexr_int64 packedSampleDataSize;
+ tinyexr::tinyexr_int64 unpackedSampleDataSize;
+ memcpy(&line_no, data_ptr, sizeof(int));
+ memcpy(&packedOffsetTableSize, data_ptr + 4,
+ sizeof(tinyexr::tinyexr_int64));
+ memcpy(&packedSampleDataSize, data_ptr + 12,
+ sizeof(tinyexr::tinyexr_int64));
+ memcpy(&unpackedSampleDataSize, data_ptr + 20,
+ sizeof(tinyexr::tinyexr_int64));
+
+ tinyexr::swap4(&line_no);
+ tinyexr::swap8(
+ reinterpret_cast<tinyexr::tinyexr_uint64 *>(&packedOffsetTableSize));
+ tinyexr::swap8(
+ reinterpret_cast<tinyexr::tinyexr_uint64 *>(&packedSampleDataSize));
+ tinyexr::swap8(
+ reinterpret_cast<tinyexr::tinyexr_uint64 *>(&unpackedSampleDataSize));
+
+ std::vector<int> pixelOffsetTable(static_cast<size_t>(data_width));
+
+ // decode pixel offset table.
+ {
+ unsigned long dstLen =
+ static_cast<unsigned long>(pixelOffsetTable.size() * sizeof(int));
+ if (!tinyexr::DecompressZip(
+ reinterpret_cast<unsigned char *>(&pixelOffsetTable.at(0)),
+ &dstLen, data_ptr + 28,
+ static_cast<unsigned long>(packedOffsetTableSize))) {
+ return false;
+ }
+
+ assert(dstLen == pixelOffsetTable.size() * sizeof(int));
+ for (size_t i = 0; i < static_cast<size_t>(data_width); i++) {
+ deep_image->offset_table[y][i] = pixelOffsetTable[i];
+ }
+ }
+
+ std::vector<unsigned char> sample_data(
+ static_cast<size_t>(unpackedSampleDataSize));
+
+ // decode sample data.
+ {
+ unsigned long dstLen = static_cast<unsigned long>(unpackedSampleDataSize);
+ if (dstLen) {
+ if (!tinyexr::DecompressZip(
+ reinterpret_cast<unsigned char *>(&sample_data.at(0)), &dstLen,
+ data_ptr + 28 + packedOffsetTableSize,
+ static_cast<unsigned long>(packedSampleDataSize))) {
+ return false;
+ }
+ assert(dstLen == static_cast<unsigned long>(unpackedSampleDataSize));
+ }
+ }
+
+ // decode sample
+ int sampleSize = -1;
+ std::vector<int> channel_offset_list(static_cast<size_t>(num_channels));
+ {
+ int channel_offset = 0;
+ for (size_t i = 0; i < static_cast<size_t>(num_channels); i++) {
+ channel_offset_list[i] = channel_offset;
+ if (channels[i].pixel_type == TINYEXR_PIXELTYPE_UINT) { // UINT
+ channel_offset += 4;
+ } else if (channels[i].pixel_type == TINYEXR_PIXELTYPE_HALF) { // half
+ channel_offset += 2;
+ } else if (channels[i].pixel_type ==
+ TINYEXR_PIXELTYPE_FLOAT) { // float
+ channel_offset += 4;
+ } else {
+ assert(0);
+ }
+ }
+ sampleSize = channel_offset;
+ }
+ assert(sampleSize >= 2);
+
+ assert(static_cast<size_t>(
+ pixelOffsetTable[static_cast<size_t>(data_width - 1)] *
+ sampleSize) == sample_data.size());
+ int samples_per_line = static_cast<int>(sample_data.size()) / sampleSize;
+
+ //
+ // Alloc memory
+ //
+
+ //
+ // pixel data is stored as image[channels][pixel_samples]
+ //
+ {
+ tinyexr::tinyexr_uint64 data_offset = 0;
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+ deep_image->image[c][y] = static_cast<float *>(
+ malloc(sizeof(float) * static_cast<size_t>(samples_per_line)));
+
+ if (channels[c].pixel_type == 0) { // UINT
+ for (size_t x = 0; x < static_cast<size_t>(samples_per_line); x++) {
+ unsigned int ui;
+ unsigned int *src_ptr = reinterpret_cast<unsigned int *>(
+ &sample_data.at(size_t(data_offset) + x * sizeof(int)));
+ tinyexr::cpy4(&ui, src_ptr);
+ deep_image->image[c][y][x] = static_cast<float>(ui); // @fixme
+ }
+ data_offset +=
+ sizeof(unsigned int) * static_cast<size_t>(samples_per_line);
+ } else if (channels[c].pixel_type == 1) { // half
+ for (size_t x = 0; x < static_cast<size_t>(samples_per_line); x++) {
+ tinyexr::FP16 f16;
+ const unsigned short *src_ptr = reinterpret_cast<unsigned short *>(
+ &sample_data.at(size_t(data_offset) + x * sizeof(short)));
+ tinyexr::cpy2(&(f16.u), src_ptr);
+ tinyexr::FP32 f32 = half_to_float(f16);
+ deep_image->image[c][y][x] = f32.f;
+ }
+ data_offset += sizeof(short) * static_cast<size_t>(samples_per_line);
+ } else { // float
+ for (size_t x = 0; x < static_cast<size_t>(samples_per_line); x++) {
+ float f;
+ const float *src_ptr = reinterpret_cast<float *>(
+ &sample_data.at(size_t(data_offset) + x * sizeof(float)));
+ tinyexr::cpy4(&f, src_ptr);
+ deep_image->image[c][y][x] = f;
+ }
+ data_offset += sizeof(float) * static_cast<size_t>(samples_per_line);
+ }
+ }
+ }
+ } // y
+
+ deep_image->width = data_width;
+ deep_image->height = data_height;
+
+ deep_image->channel_names = static_cast<const char **>(
+ malloc(sizeof(const char *) * static_cast<size_t>(num_channels)));
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+#ifdef _WIN32
+ deep_image->channel_names[c] = _strdup(channels[c].name.c_str());
+#else
+ deep_image->channel_names[c] = strdup(channels[c].name.c_str());
+#endif
+ }
+ deep_image->num_channels = num_channels;
+
+ return TINYEXR_SUCCESS;
+}
+
+void InitEXRImage(EXRImage *exr_image) {
+ if (exr_image == NULL) {
+ return;
+ }
+
+ exr_image->width = 0;
+ exr_image->height = 0;
+ exr_image->num_channels = 0;
+
+ exr_image->images = NULL;
+ exr_image->tiles = NULL;
+ exr_image->next_level = NULL;
+ exr_image->level_x = 0;
+ exr_image->level_y = 0;
+
+ exr_image->num_tiles = 0;
+}
+
+void FreeEXRErrorMessage(const char *msg) {
+ if (msg) {
+ free(reinterpret_cast<void *>(const_cast<char *>(msg)));
+ }
+ return;
+}
+
+void InitEXRHeader(EXRHeader *exr_header) {
+ if (exr_header == NULL) {
+ return;
+ }
+
+ memset(exr_header, 0, sizeof(EXRHeader));
+}
+
+int FreeEXRHeader(EXRHeader *exr_header) {
+ if (exr_header == NULL) {
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (exr_header->channels) {
+ free(exr_header->channels);
+ }
+
+ if (exr_header->pixel_types) {
+ free(exr_header->pixel_types);
+ }
+
+ if (exr_header->requested_pixel_types) {
+ free(exr_header->requested_pixel_types);
+ }
+
+ for (int i = 0; i < exr_header->num_custom_attributes; i++) {
+ if (exr_header->custom_attributes[i].value) {
+ free(exr_header->custom_attributes[i].value);
+ }
+ }
+
+ if (exr_header->custom_attributes) {
+ free(exr_header->custom_attributes);
+ }
+
+ EXRSetNameAttr(exr_header, NULL);
+
+ return TINYEXR_SUCCESS;
+}
+
+void EXRSetNameAttr(EXRHeader* exr_header, const char* name) {
+ if (exr_header == NULL) {
+ return;
+ }
+ memset(exr_header->name, 0, 256);
+ if (name != NULL) {
+ size_t len = std::min(strlen(name), (size_t)255);
+ if (len) {
+ memcpy(exr_header->name, name, len);
+ }
+ }
+}
+
+int EXRNumLevels(const EXRImage* exr_image) {
+ if (exr_image == NULL) return 0;
+ if(exr_image->images) return 1; // scanlines
+ int levels = 1;
+ const EXRImage* level_image = exr_image;
+ while((level_image = level_image->next_level)) ++levels;
+ return levels;
+}
+
+int FreeEXRImage(EXRImage *exr_image) {
+ if (exr_image == NULL) {
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (exr_image->next_level) {
+ FreeEXRImage(exr_image->next_level);
+ delete exr_image->next_level;
+ }
+
+ for (int i = 0; i < exr_image->num_channels; i++) {
+ if (exr_image->images && exr_image->images[i]) {
+ free(exr_image->images[i]);
+ }
+ }
+
+ if (exr_image->images) {
+ free(exr_image->images);
+ }
+
+ if (exr_image->tiles) {
+ for (int tid = 0; tid < exr_image->num_tiles; tid++) {
+ for (int i = 0; i < exr_image->num_channels; i++) {
+ if (exr_image->tiles[tid].images && exr_image->tiles[tid].images[i]) {
+ free(exr_image->tiles[tid].images[i]);
+ }
+ }
+ if (exr_image->tiles[tid].images) {
+ free(exr_image->tiles[tid].images);
+ }
+ }
+ free(exr_image->tiles);
+ }
+
+ return TINYEXR_SUCCESS;
+}
+
+int ParseEXRHeaderFromFile(EXRHeader *exr_header, const EXRVersion *exr_version,
+ const char *filename, const char **err) {
+ if (exr_header == NULL || exr_version == NULL || filename == NULL) {
+ tinyexr::SetErrorMessage("Invalid argument for ParseEXRHeaderFromFile",
+ err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ FILE *fp = NULL;
+#ifdef _WIN32
+#if defined(_MSC_VER) || (defined(MINGW_HAS_SECURE_API) && MINGW_HAS_SECURE_API) // MSVC, MinGW GCC, or Clang.
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
+#else
+ // Unknown compiler or MinGW without MINGW_HAS_SECURE_API.
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
+#endif
+ if (!fp) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+
+ size_t filesize;
+ // Compute size
+ fseek(fp, 0, SEEK_END);
+ filesize = static_cast<size_t>(ftell(fp));
+ fseek(fp, 0, SEEK_SET);
+
+ std::vector<unsigned char> buf(filesize); // @todo { use mmap }
+ {
+ size_t ret;
+ ret = fread(&buf[0], 1, filesize, fp);
+ assert(ret == filesize);
+ fclose(fp);
+
+ if (ret != filesize) {
+ tinyexr::SetErrorMessage("fread() error on " + std::string(filename),
+ err);
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
+ }
+
+ return ParseEXRHeaderFromMemory(exr_header, exr_version, &buf.at(0), filesize,
+ err);
+}
+
+int ParseEXRMultipartHeaderFromMemory(EXRHeader ***exr_headers,
+ int *num_headers,
+ const EXRVersion *exr_version,
+ const unsigned char *memory, size_t size,
+ const char **err) {
+ if (memory == NULL || exr_headers == NULL || num_headers == NULL ||
+ exr_version == NULL) {
+ // Invalid argument
+ tinyexr::SetErrorMessage(
+ "Invalid argument for ParseEXRMultipartHeaderFromMemory", err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (size < tinyexr::kEXRVersionSize) {
+ tinyexr::SetErrorMessage("Data size too short", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ const unsigned char *marker = memory + tinyexr::kEXRVersionSize;
+ size_t marker_size = size - tinyexr::kEXRVersionSize;
+
+ std::vector<tinyexr::HeaderInfo> infos;
+
+ for (;;) {
+ tinyexr::HeaderInfo info;
+ info.clear();
+
+ std::string err_str;
+ bool empty_header = false;
+ int ret = ParseEXRHeader(&info, &empty_header, exr_version, &err_str,
+ marker, marker_size);
+
+ if (ret != TINYEXR_SUCCESS) {
+ tinyexr::SetErrorMessage(err_str, err);
+ return ret;
+ }
+
+ if (empty_header) {
+ marker += 1; // skip '\0'
+ break;
+ }
+
+ // `chunkCount` must exist in the header.
+ if (info.chunk_count == 0) {
+ tinyexr::SetErrorMessage(
+ "`chunkCount' attribute is not found in the header.", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ infos.push_back(info);
+
+ // move to next header.
+ marker += info.header_len;
+ size -= info.header_len;
+ }
+
+ // allocate memory for EXRHeader and create array of EXRHeader pointers.
+ (*exr_headers) =
+ static_cast<EXRHeader **>(malloc(sizeof(EXRHeader *) * infos.size()));
+ for (size_t i = 0; i < infos.size(); i++) {
+ EXRHeader *exr_header = static_cast<EXRHeader *>(malloc(sizeof(EXRHeader)));
+ memset(exr_header, 0, sizeof(EXRHeader));
+
+ ConvertHeader(exr_header, infos[i]);
+
+ exr_header->multipart = exr_version->multipart ? 1 : 0;
+
+ (*exr_headers)[i] = exr_header;
+ }
+
+ (*num_headers) = static_cast<int>(infos.size());
+
+ return TINYEXR_SUCCESS;
+}
+
+int ParseEXRMultipartHeaderFromFile(EXRHeader ***exr_headers, int *num_headers,
+ const EXRVersion *exr_version,
+ const char *filename, const char **err) {
+ if (exr_headers == NULL || num_headers == NULL || exr_version == NULL ||
+ filename == NULL) {
+ tinyexr::SetErrorMessage(
+ "Invalid argument for ParseEXRMultipartHeaderFromFile()", err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ FILE *fp = NULL;
+#ifdef _WIN32
+#if defined(_MSC_VER) || (defined(MINGW_HAS_SECURE_API) && MINGW_HAS_SECURE_API) // MSVC, MinGW GCC, or Clang.
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
+#else
+ // Unknown compiler or MinGW without MINGW_HAS_SECURE_API.
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
+#endif
+ if (!fp) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+
+ size_t filesize;
+ // Compute size
+ fseek(fp, 0, SEEK_END);
+ filesize = static_cast<size_t>(ftell(fp));
+ fseek(fp, 0, SEEK_SET);
+
+ std::vector<unsigned char> buf(filesize); // @todo { use mmap }
+ {
+ size_t ret;
+ ret = fread(&buf[0], 1, filesize, fp);
+ assert(ret == filesize);
+ fclose(fp);
+
+ if (ret != filesize) {
+ tinyexr::SetErrorMessage("`fread' error. file may be corrupted.", err);
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
+ }
+
+ return ParseEXRMultipartHeaderFromMemory(
+ exr_headers, num_headers, exr_version, &buf.at(0), filesize, err);
+}
+
+int ParseEXRVersionFromMemory(EXRVersion *version, const unsigned char *memory,
+ size_t size) {
+ if (version == NULL || memory == NULL) {
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (size < tinyexr::kEXRVersionSize) {
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ const unsigned char *marker = memory;
+
+ // Header check.
+ {
+ const char header[] = {0x76, 0x2f, 0x31, 0x01};
+
+ if (memcmp(marker, header, 4) != 0) {
+ return TINYEXR_ERROR_INVALID_MAGIC_NUMBER;
+ }
+ marker += 4;
+ }
+
+ version->tiled = false;
+ version->long_name = false;
+ version->non_image = false;
+ version->multipart = false;
+
+ // Parse version header.
+ {
+ // must be 2
+ if (marker[0] != 2) {
+ return TINYEXR_ERROR_INVALID_EXR_VERSION;
+ }
+
+ if (version == NULL) {
+ return TINYEXR_SUCCESS; // May OK
+ }
+
+ version->version = 2;
+
+ if (marker[1] & 0x2) { // 9th bit
+ version->tiled = true;
+ }
+ if (marker[1] & 0x4) { // 10th bit
+ version->long_name = true;
+ }
+ if (marker[1] & 0x8) { // 11th bit
+ version->non_image = true; // (deep image)
+ }
+ if (marker[1] & 0x10) { // 12th bit
+ version->multipart = true;
+ }
+ }
+
+ return TINYEXR_SUCCESS;
+}
+
+int ParseEXRVersionFromFile(EXRVersion *version, const char *filename) {
+ if (filename == NULL) {
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ FILE *fp = NULL;
+#ifdef _WIN32
+#if defined(_MSC_VER) || (defined(MINGW_HAS_SECURE_API) && MINGW_HAS_SECURE_API) // MSVC, MinGW GCC, or Clang.
+ errno_t err = _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (err != 0) {
+ // TODO(syoyo): return wfopen_s erro code
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+#else
+ // Unknown compiler or MinGW without MINGW_HAS_SECURE_API.
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
+#endif
+ if (!fp) {
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+
+ size_t file_size;
+ // Compute size
+ fseek(fp, 0, SEEK_END);
+ file_size = static_cast<size_t>(ftell(fp));
+ fseek(fp, 0, SEEK_SET);
+
+ if (file_size < tinyexr::kEXRVersionSize) {
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
+
+ unsigned char buf[tinyexr::kEXRVersionSize];
+ size_t ret = fread(&buf[0], 1, tinyexr::kEXRVersionSize, fp);
+ fclose(fp);
+
+ if (ret != tinyexr::kEXRVersionSize) {
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
+
+ return ParseEXRVersionFromMemory(version, buf, tinyexr::kEXRVersionSize);
+}
+
+int LoadEXRMultipartImageFromMemory(EXRImage *exr_images,
+ const EXRHeader **exr_headers,
+ unsigned int num_parts,
+ const unsigned char *memory,
+ const size_t size, const char **err) {
+ if (exr_images == NULL || exr_headers == NULL || num_parts == 0 ||
+ memory == NULL || (size <= tinyexr::kEXRVersionSize)) {
+ tinyexr::SetErrorMessage(
+ "Invalid argument for LoadEXRMultipartImageFromMemory()", err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ // compute total header size.
+ size_t total_header_size = 0;
+ for (unsigned int i = 0; i < num_parts; i++) {
+ if (exr_headers[i]->header_len == 0) {
+ tinyexr::SetErrorMessage("EXRHeader variable is not initialized.", err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ total_header_size += exr_headers[i]->header_len;
+ }
+
+ const char *marker = reinterpret_cast<const char *>(
+ memory + total_header_size + 4 +
+ 4); // +8 for magic number and version header.
+
+ marker += 1; // Skip empty header.
+
+ // NOTE 1:
+ // In multipart image, There is 'part number' before chunk data.
+ // 4 byte : part number
+ // 4+ : chunk
+ //
+ // NOTE 2:
+ // EXR spec says 'part number' is 'unsigned long' but actually this is
+ // 'unsigned int(4 bytes)' in OpenEXR implementation...
+ // http://www.openexr.com/openexrfilelayout.pdf
+
+ // Load chunk offset table.
+ std::vector<tinyexr::OffsetData> chunk_offset_table_list;
+ chunk_offset_table_list.reserve(num_parts);
+ for (size_t i = 0; i < static_cast<size_t>(num_parts); i++) {
+ chunk_offset_table_list.resize(chunk_offset_table_list.size() + 1);
+ tinyexr::OffsetData& offset_data = chunk_offset_table_list.back();
+ if (!exr_headers[i]->tiled || exr_headers[i]->tile_level_mode == TINYEXR_TILE_ONE_LEVEL) {
+ tinyexr::InitSingleResolutionOffsets(offset_data, exr_headers[i]->chunk_count);
+ std::vector<tinyexr::tinyexr_uint64>& offset_table = offset_data.offsets[0][0];
+
+ for (size_t c = 0; c < offset_table.size(); c++) {
+ tinyexr::tinyexr_uint64 offset;
+ memcpy(&offset, marker, 8);
+ tinyexr::swap8(&offset);
+
+ if (offset >= size) {
+ tinyexr::SetErrorMessage("Invalid offset size in EXR header chunks.",
+ err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ offset_table[c] = offset + 4; // +4 to skip 'part number'
+ marker += 8;
+ }
+ } else {
+ {
+ std::vector<int> num_x_tiles, num_y_tiles;
+ tinyexr::PrecalculateTileInfo(num_x_tiles, num_y_tiles, exr_headers[i]);
+ int num_blocks = InitTileOffsets(offset_data, exr_headers[i], num_x_tiles, num_y_tiles);
+ if (num_blocks != exr_headers[i]->chunk_count) {
+ tinyexr::SetErrorMessage("Invalid offset table size.", err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ }
+ for (unsigned int l = 0; l < offset_data.offsets.size(); ++l) {
+ for (unsigned int dy = 0; dy < offset_data.offsets[l].size(); ++dy) {
+ for (unsigned int dx = 0; dx < offset_data.offsets[l][dy].size(); ++dx) {
+ tinyexr::tinyexr_uint64 offset;
+ memcpy(&offset, marker, sizeof(tinyexr::tinyexr_uint64));
+ tinyexr::swap8(&offset);
+ if (offset >= size) {
+ tinyexr::SetErrorMessage("Invalid offset size in EXR header chunks.",
+ err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ offset_data.offsets[l][dy][dx] = offset + 4; // +4 to skip 'part number'
+ marker += sizeof(tinyexr::tinyexr_uint64); // = 8
+ }
+ }
+ }
+ }
+ }
+
+ // Decode image.
+ for (size_t i = 0; i < static_cast<size_t>(num_parts); i++) {
+ tinyexr::OffsetData &offset_data = chunk_offset_table_list[i];
+
+ // First check 'part number' is identitical to 'i'
+ for (unsigned int l = 0; l < offset_data.offsets.size(); ++l)
+ for (unsigned int dy = 0; dy < offset_data.offsets[l].size(); ++dy)
+ for (unsigned int dx = 0; dx < offset_data.offsets[l][dy].size(); ++dx) {
+
+ const unsigned char *part_number_addr =
+ memory + offset_data.offsets[l][dy][dx] - 4; // -4 to move to 'part number' field.
+ unsigned int part_no;
+ memcpy(&part_no, part_number_addr, sizeof(unsigned int)); // 4
+ tinyexr::swap4(&part_no);
+
+ if (part_no != i) {
+ tinyexr::SetErrorMessage("Invalid `part number' in EXR header chunks.",
+ err);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ }
+
+ std::string e;
+ int ret = tinyexr::DecodeChunk(&exr_images[i], exr_headers[i], offset_data,
+ memory, size, &e);
+ if (ret != TINYEXR_SUCCESS) {
+ if (!e.empty()) {
+ tinyexr::SetErrorMessage(e, err);
+ }
+ return ret;
+ }
+ }
+
+ return TINYEXR_SUCCESS;
+}
+
+int LoadEXRMultipartImageFromFile(EXRImage *exr_images,
+ const EXRHeader **exr_headers,
+ unsigned int num_parts, const char *filename,
+ const char **err) {
+ if (exr_images == NULL || exr_headers == NULL || num_parts == 0) {
+ tinyexr::SetErrorMessage(
+ "Invalid argument for LoadEXRMultipartImageFromFile", err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ FILE *fp = NULL;
+#ifdef _WIN32
+#if defined(_MSC_VER) || (defined(MINGW_HAS_SECURE_API) && MINGW_HAS_SECURE_API) // MSVC, MinGW GCC, or Clang.
+ errno_t errcode =
+ _wfopen_s(&fp, tinyexr::UTF8ToWchar(filename).c_str(), L"rb");
+ if (errcode != 0) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+#else
+ // Unknown compiler or MinGW without MINGW_HAS_SECURE_API.
+ fp = fopen(filename, "rb");
+#endif
+#else
+ fp = fopen(filename, "rb");
+#endif
+ if (!fp) {
+ tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err);
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+
+ size_t filesize;
+ // Compute size
+ fseek(fp, 0, SEEK_END);
+ filesize = static_cast<size_t>(ftell(fp));
+ fseek(fp, 0, SEEK_SET);
+
+ std::vector<unsigned char> buf(filesize); // @todo { use mmap }
+ {
+ size_t ret;
+ ret = fread(&buf[0], 1, filesize, fp);
+ assert(ret == filesize);
+ fclose(fp);
+ (void)ret;
+ }
+
+ return LoadEXRMultipartImageFromMemory(exr_images, exr_headers, num_parts,
+ &buf.at(0), filesize, err);
+}
+
+int SaveEXR(const float *data, int width, int height, int components,
+ const int save_as_fp16, const char *outfilename, const char **err) {
+ if ((components == 1) || components == 3 || components == 4) {
+ // OK
+ } else {
+ std::stringstream ss;
+ ss << "Unsupported component value : " << components << std::endl;
+
+ tinyexr::SetErrorMessage(ss.str(), err);
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ EXRHeader header;
+ InitEXRHeader(&header);
+
+ if ((width < 16) && (height < 16)) {
+ // No compression for small image.
+ header.compression_type = TINYEXR_COMPRESSIONTYPE_NONE;
+ } else {
+ header.compression_type = TINYEXR_COMPRESSIONTYPE_ZIP;
+ }
+
+ EXRImage image;
+ InitEXRImage(&image);
+
+ image.num_channels = components;
+
+ std::vector<float> images[4];
+
+ if (components == 1) {
+ images[0].resize(static_cast<size_t>(width * height));
+ memcpy(images[0].data(), data, sizeof(float) * size_t(width * height));
+ } else {
+ images[0].resize(static_cast<size_t>(width * height));
+ images[1].resize(static_cast<size_t>(width * height));
+ images[2].resize(static_cast<size_t>(width * height));
+ images[3].resize(static_cast<size_t>(width * height));
+
+ // Split RGB(A)RGB(A)RGB(A)... into R, G and B(and A) layers
+ for (size_t i = 0; i < static_cast<size_t>(width * height); i++) {
+ images[0][i] = data[static_cast<size_t>(components) * i + 0];
+ images[1][i] = data[static_cast<size_t>(components) * i + 1];
+ images[2][i] = data[static_cast<size_t>(components) * i + 2];
+ if (components == 4) {
+ images[3][i] = data[static_cast<size_t>(components) * i + 3];
+ }
+ }
+ }
+
+ float *image_ptr[4] = {0, 0, 0, 0};
+ if (components == 4) {
+ image_ptr[0] = &(images[3].at(0)); // A
+ image_ptr[1] = &(images[2].at(0)); // B
+ image_ptr[2] = &(images[1].at(0)); // G
+ image_ptr[3] = &(images[0].at(0)); // R
+ } else if (components == 3) {
+ image_ptr[0] = &(images[2].at(0)); // B
+ image_ptr[1] = &(images[1].at(0)); // G
+ image_ptr[2] = &(images[0].at(0)); // R
+ } else if (components == 1) {
+ image_ptr[0] = &(images[0].at(0)); // A
+ }
+
+ image.images = reinterpret_cast<unsigned char **>(image_ptr);
+ image.width = width;
+ image.height = height;
+
+ header.num_channels = components;
+ header.channels = static_cast<EXRChannelInfo *>(malloc(
+ sizeof(EXRChannelInfo) * static_cast<size_t>(header.num_channels)));
+ // Must be (A)BGR order, since most of EXR viewers expect this channel order.
+ if (components == 4) {
+#ifdef _MSC_VER
+ strncpy_s(header.channels[0].name, "A", 255);
+ strncpy_s(header.channels[1].name, "B", 255);
+ strncpy_s(header.channels[2].name, "G", 255);
+ strncpy_s(header.channels[3].name, "R", 255);
+#else
+ strncpy(header.channels[0].name, "A", 255);
+ strncpy(header.channels[1].name, "B", 255);
+ strncpy(header.channels[2].name, "G", 255);
+ strncpy(header.channels[3].name, "R", 255);
+#endif
+ header.channels[0].name[strlen("A")] = '\0';
+ header.channels[1].name[strlen("B")] = '\0';
+ header.channels[2].name[strlen("G")] = '\0';
+ header.channels[3].name[strlen("R")] = '\0';
+ } else if (components == 3) {
+#ifdef _MSC_VER
+ strncpy_s(header.channels[0].name, "B", 255);
+ strncpy_s(header.channels[1].name, "G", 255);
+ strncpy_s(header.channels[2].name, "R", 255);
+#else
+ strncpy(header.channels[0].name, "B", 255);
+ strncpy(header.channels[1].name, "G", 255);
+ strncpy(header.channels[2].name, "R", 255);
+#endif
+ header.channels[0].name[strlen("B")] = '\0';
+ header.channels[1].name[strlen("G")] = '\0';
+ header.channels[2].name[strlen("R")] = '\0';
+ } else {
+#ifdef _MSC_VER
+ strncpy_s(header.channels[0].name, "A", 255);
+#else
+ strncpy(header.channels[0].name, "A", 255);
+#endif
+ header.channels[0].name[strlen("A")] = '\0';
+ }
+
+ header.pixel_types = static_cast<int *>(
+ malloc(sizeof(int) * static_cast<size_t>(header.num_channels)));
+ header.requested_pixel_types = static_cast<int *>(
+ malloc(sizeof(int) * static_cast<size_t>(header.num_channels)));
+ for (int i = 0; i < header.num_channels; i++) {
+ header.pixel_types[i] =
+ TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image
+
+ if (save_as_fp16 > 0) {
+ header.requested_pixel_types[i] =
+ TINYEXR_PIXELTYPE_HALF; // save with half(fp16) pixel format
+ } else {
+ header.requested_pixel_types[i] =
+ TINYEXR_PIXELTYPE_FLOAT; // save with float(fp32) pixel format(i.e.
+ // no precision reduction)
+ }
+ }
+
+ int ret = SaveEXRImageToFile(&image, &header, outfilename, err);
+ if (ret != TINYEXR_SUCCESS) {
+ return ret;
+ }
+
+ free(header.channels);
+ free(header.pixel_types);
+ free(header.requested_pixel_types);
+
+ return ret;
+}
+
+#ifdef __clang__
+// zero-as-null-ppinter-constant
+#pragma clang diagnostic pop
+#endif
+
+#endif // TINYEXR_IMPLEMENTATION_DEFINED
+#endif // TINYEXR_IMPLEMENTATION
diff --git a/graphics/asymptote/cudareflect/tinyexr/vcbuild.bat b/graphics/asymptote/cudareflect/tinyexr/vcbuild.bat
new file mode 100644
index 0000000000..c465052f2b
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/vcbuild.bat
@@ -0,0 +1,11 @@
+rem Run
+rem
+rem > python.py kuroga.py config-msvc.py
+rem
+rem before to generate build.ninja
+rem
+
+chcp 437
+rem call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64
+call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64
+ninja
diff --git a/graphics/asymptote/cudareflect/tinyexr/vcsetup2019.bat b/graphics/asymptote/cudareflect/tinyexr/vcsetup2019.bat
new file mode 100644
index 0000000000..799f6da780
--- /dev/null
+++ b/graphics/asymptote/cudareflect/tinyexr/vcsetup2019.bat
@@ -0,0 +1,4 @@
+rmdir /q /s build
+mkdir build
+
+cmake.exe -G "Visual Studio 16 2019" -A x64 -Bbuild .
diff --git a/graphics/asymptote/cudareflect/utils.cuh b/graphics/asymptote/cudareflect/utils.cuh
new file mode 100644
index 0000000000..2e563ad3d5
--- /dev/null
+++ b/graphics/asymptote/cudareflect/utils.cuh
@@ -0,0 +1,84 @@
+#pragma once
+
+#ifndef __INTELLISENSE__
+#ifndef KERNEL_ARGS
+#define KERNEL_ARGS(blk,thrdsz) <<<blk,thrdsz>>>
+#endif
+#else
+#define KERNEL_ARGS(blk,thrdsz)
+#define __CUDACC__
+#include <device_functions.h>
+#endif
+
+#include <cuda.h>
+#include <cuda_runtime.h>
+
+#define GLM_FORCE_CUDA
+#include <glm/glm.hpp>
+
+__device__ constexpr float PI = 3.141592654;
+__device__ constexpr float HALFPI = 0.5*PI;
+__device__ constexpr float TAU = 2.0*PI;
+__device__ constexpr float PI_RECR = 1.0/PI;
+
+__device__
+inline glm::vec2 to_sphcoord(glm::vec3 const& vec)
+{
+ return glm::vec2(
+ atan2f(-vec.y, -vec.x) + PI,
+ acosf(vec.z)
+ );
+}
+
+__device__
+inline glm::vec3 from_sphcoord(float const& phi, float const& theta)
+{
+ return glm::vec3(
+ __sinf(theta) * __cosf(phi),
+ __sinf(theta) * __sinf(phi),
+ __cosf(theta));
+}
+
+__device__
+inline glm::vec3 from_sphcoord(float const& phi, float const& cosTheta, float const& sinTheta)
+{
+ return glm::vec3(
+ sinTheta * __cosf(phi),
+ sinTheta * __sinf(phi),
+ cosTheta);
+}
+
+__device__
+inline glm::vec3 angleToBasis(glm::mat3 const& normalOrthBasis, float const& phi, float const& theta)
+{
+ // angle relative to (N1, N2, N) basis is (sin(phi)cos(theta), sin(phi)sin(theta), cos(phi)).
+ // perform a change of basis
+
+ glm::vec3 base_vec = from_sphcoord(phi, theta);
+
+ // representation of the matrix
+
+ // return M*base_vec;
+ // M is the matrix
+ // \begin{pmatrix}
+ // -\sin(\phi) & \cos(\theta)\cos(\phi) & \sin(\theta)\cos(\phi) \\
+ // \cos(\phi) & \cos(\theta)\sin(\phi) & \sin(\theta)\sin(\phi) \\
+ // 0 & -\sin(\theta) & \cos(\theta)
+ // \end{pmatrix}
+
+ // ( N1 N2 N) column
+ return normalOrthBasis * base_vec;
+}
+
+struct Vec3Utility
+{
+ __device__ static glm::vec3 init()
+ {
+ return glm::vec3(0.0f);
+ }
+
+ __device__ static float abs2(glm::vec3 v)
+ {
+ return v.x * v.x + v.y * v.y + v.z * v.z;
+ }
+};
diff --git a/graphics/asymptote/dec.cc b/graphics/asymptote/dec.cc
index bcf842b40d..84ccb937ce 100644
--- a/graphics/asymptote/dec.cc
+++ b/graphics/asymptote/dec.cc
@@ -16,6 +16,7 @@
#include "exp.h"
#include "modifier.h"
#include "runtime.h"
+#include "locate.h"
#include "parser.h"
namespace absyntax {
@@ -33,7 +34,7 @@ trans::tyEntry *ty::transAsTyEntry(coenv &e, record *where)
void nameTy::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "nameTy",indent);
+ prettyname(out, "nameTy",indent, getPos());
id->prettyprint(out, indent+1);
}
@@ -48,6 +49,10 @@ trans::tyEntry *nameTy::transAsTyEntry(coenv &e, record *)
return id->tyEntryTrans(e);
}
+nameTy::operator string() const
+{
+ return static_cast<string>(id->getName());
+}
void dimensions::prettyprint(ostream &out, Int indent)
{
@@ -74,7 +79,7 @@ types::array *dimensions::truetype(types::ty *base)
void arrayTy::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "arrayTy",indent);
+ prettyname(out, "arrayTy",indent, getPos());
cell->prettyprint(out, indent+1);
dims->prettyprint(out, indent+1);
@@ -110,6 +115,17 @@ types::ty *arrayTy::trans(coenv &e, bool tacit)
return t;
}
+arrayTy::operator string() const
+{
+ stringstream ss;
+ ss << static_cast<string>(*cell);
+ for (size_t i = 0; i < dims->size(); i++)
+ {
+ ss << "[]";
+ }
+ return ss.str();
+}
+
tyEntryTy::tyEntryTy(position pos, types::ty *t)
: ty(pos), ent(new trans::tyEntry(t, 0, 0, position()))
{
@@ -125,6 +141,10 @@ types::ty *tyEntryTy::trans(coenv &, bool) {
return ent->t;
}
+tyEntryTy::operator string() const
+{
+ return "<unknown-type>";
+}
vm::lambda *runnable::transAsCodelet(coenv &e)
{
@@ -143,7 +163,7 @@ void block::prettystms(ostream &out, Int indent)
void block::prettyprint(ostream &out, Int indent)
{
- prettyname(out,"block",indent);
+ prettyname(out,"block",indent,getPos());
prettystms(out, indent+1);
}
@@ -224,10 +244,18 @@ vardec *block::asVardec()
return var;
}
+void block::createSymMap(AsymptoteLsp::SymbolContext* symContext) {
+#ifdef HAVE_LSP
+ for (auto const& p : stms)
+ {
+ p->createSymMap(symContext);
+ }
+#endif
+}
void dec::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "dec", indent);
+ prettyname(out, "dec", indent, getPos());
}
@@ -300,7 +328,7 @@ permission modifierList::getPermission()
void modifiedRunnable::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "modifierRunnable",indent);
+ prettyname(out, "modifierRunnable",indent, getPos());
mods->prettyprint(out, indent+1);
body->prettyprint(out, indent+1);
@@ -364,8 +392,52 @@ void decidstart::addOps(types::ty *base, coenv &e, record *r)
}
}
+void decidstart::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ std::string name(static_cast<std::string>(getName()));
+ AsymptoteLsp::posInFile pos(getPos().LineColumn());
+ if (auto decCtx=dynamic_cast<AsymptoteLsp::AddDeclContexts*>(symContext))
+ {
+ decCtx->additionalDecs.emplace(std::piecewise_construct,
+ std::forward_as_tuple(name), std::forward_as_tuple(name, pos));
+ }
+ else
+ {
+ symContext->symMap.varDec[name] = AsymptoteLsp::SymbolInfo(name, pos);
+ }
+#endif
+}
+
+void decidstart::createSymMapWType(AsymptoteLsp::SymbolContext* symContext, absyntax::ty* base)
+{
+#ifdef HAVE_LSP
+ std::string name(static_cast<std::string>(getName()));
+ AsymptoteLsp::posInFile pos(getPos().LineColumn());
+ if (auto decCtx=dynamic_cast<AsymptoteLsp::AddDeclContexts*>(symContext))
+ {
+ if (base == nullptr)
+ {
+ decCtx->additionalDecs.emplace(std::piecewise_construct, std::forward_as_tuple(name),
+ std::forward_as_tuple(name, pos));
+ }
+ else
+ {
+ decCtx->additionalDecs.emplace(std::piecewise_construct, std::forward_as_tuple(name),
+ std::forward_as_tuple(name, static_cast<std::string>(*base), pos));
+ }
+ }
+ else
+ {
+ symContext->symMap.varDec[name] = base == nullptr ?
+ AsymptoteLsp::SymbolInfo(name, pos) :
+ AsymptoteLsp::SymbolInfo(name, static_cast<std::string>(*base), pos);
+ }
+#endif
+}
+
-void fundecidstart::prettyprint(ostream &out, Int indent)
+ void fundecidstart::prettyprint(ostream &out, Int indent)
{
prettyindent(out, indent);
out << "fundecidstart '" << id << "'\n";
@@ -412,7 +484,7 @@ void fundecidstart::addOps(types::ty *base, coenv &e, record *r)
void decid::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "decid",indent);
+ prettyname(out, "decid",indent, getPos());
start->prettyprint(out, indent+1);
if (init)
@@ -556,10 +628,32 @@ void decid::transAsTypedefField(coenv &e, trans::tyEntry *base, record *r)
addTypeWithPermission(e, r, ent, start->getName());
}
+void decid::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ start->createSymMap(symContext);
+ if (init)
+ {
+ init->createSymMap(symContext);
+ }
+#endif
+}
+
+void decid::createSymMapWType(AsymptoteLsp::SymbolContext* symContext, absyntax::ty* base)
+{
+#ifdef HAVE_LSP
+ start->createSymMapWType(symContext, base);
+ if (init)
+ {
+ init->createSymMap(symContext);
+ }
+#endif
+}
+
void decidlist::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "decidlist",indent);
+ prettyname(out, "decidlist",indent, getPos());
for (list<decid *>::iterator p = decs.begin(); p != decs.end(); ++p)
(*p)->prettyprint(out, indent+1);
@@ -577,10 +671,28 @@ void decidlist::transAsTypedefField(coenv &e, trans::tyEntry *base, record *r)
(*p)->transAsTypedefField(e, base, r);
}
+void decidlist::createSymMap(AsymptoteLsp::SymbolContext* symContext) {
+#ifdef HAVE_LSP
+ for (auto const& p : decs)
+ {
+ p->createSymMap(symContext);
+ }
+#endif
+}
+
+void decidlist::createSymMapWType(AsymptoteLsp::SymbolContext* symContext, absyntax::ty* base) {
+#ifdef HAVE_LSP
+ for (auto const& p : decs)
+ {
+ p->createSymMapWType(symContext, base);
+ }
+#endif
+}
+
-void vardec::prettyprint(ostream &out, Int indent)
+ void vardec::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "vardec",indent);
+ prettyname(out, "vardec",indent, getPos());
base->prettyprint(out, indent+1);
decs->prettyprint(out, indent+1);
@@ -608,6 +720,13 @@ types::ty *vardec::singleGetType(coenv &e)
return did->getStart()->getType(base->trans(e), e);
}
+void vardec::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ decs->createSymMapWType(symContext, base);
+#endif
+}
+
// Helper class for imports. This essentially evaluates to the run::loadModule
// function. However, that function returns different types of records
@@ -622,7 +741,7 @@ public:
: exp(pos) {ft=new function(imp,primString());}
void prettyprint(ostream &out, Int indent) {
- prettyname(out, "loadModuleExp", indent);
+ prettyname(out, "loadModuleExp", indent, getPos());
}
types::ty *trans(coenv &) {
@@ -700,6 +819,34 @@ void idpair::transAsUnravel(coenv &e, record *r,
}
}
+void idpair::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ if (valid)
+ {
+ string fullSrc(settings::locateFile(src, true));
+ if (not AsymptoteLsp::isVirtualFile((std::string)(fullSrc.c_str())))
+ {
+ if (not fullSrc.empty())
+ {
+ symContext->addEmptyExtRef((std::string)(fullSrc.c_str()));
+ }
+
+ // add (dest, source) to reference map.
+ auto s = symContext->extRefs.fileIdPair.emplace(dest, (std::string) fullSrc.c_str());
+ auto it=std::get<0>(s);
+ auto success=std::get<1>(s);
+ if (not success)
+ {
+ it->second = (std::string)(fullSrc.c_str());
+ }
+
+ symContext->extRefs.addAccessVal(static_cast<std::string>(dest));
+ }
+ }
+#endif
+}
+
void idpairlist::prettyprint(ostream &out, Int indent)
{
@@ -726,18 +873,35 @@ void idpairlist::transAsUnravel(coenv &e, record *r,
(*p)->transAsUnravel(e,r,source,qualifier);
}
-idpairlist * const WILDCARD = 0;
+void idpairlist::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ for (auto& idp : base)
+ {
+ idp->createSymMap(symContext);
+ }
+#endif
+}
+
+ idpairlist * const WILDCARD = 0;
void accessdec::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "accessdec", indent);
+ prettyname(out, "accessdec", indent, getPos());
base->prettyprint(out, indent+1);
}
+void accessdec::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ base->createSymMap(symContext);
+#endif
+}
+
void fromdec::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "fromdec", indent);
+ prettyname(out, "fromdec", indent, getPos());
fields->prettyprint(out, indent+1);
}
@@ -758,7 +922,7 @@ void fromdec::transAsField(coenv &e, record *r)
void unraveldec::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "unraveldec", indent);
+ prettyname(out, "unraveldec", indent, getPos());
id->prettyprint(out, indent+1);
idpairlist *f=this->fields;
if(f) f->prettyprint(out, indent+1);
@@ -776,6 +940,17 @@ fromdec::qualifier unraveldec::getQualifier(coenv &e, record *)
return qualifier(qt,id->getVarEntry(e));
}
+void unraveldec::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ std::string fileName = static_cast<std::string>(id->getName());
+ if (not AsymptoteLsp::isVirtualFile(fileName))
+ {
+ symContext->extRefs.addUnravelVal(fileName);
+ }
+#endif
+}
+
void fromaccessdec::prettyprint(ostream &out, Int indent)
{
prettyindent(out, indent);
@@ -799,12 +974,41 @@ fromdec::qualifier fromaccessdec::getQualifier(coenv &e, record *r)
return qualifier(0,0);
}
+void fromaccessdec::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ // filename is id;
+ std::string idStr(id);
+ symContext->extRefs.addEmptyExtRef(idStr);
+
+ auto* f=this->fields;
+ if (f)
+ {
+ // add [dest] -> [src, filename] to fromAccessDecls;
+ f->processListFn(
+ [&symContext, &idStr](symbol const& src, symbol const& dest)
+ {
+ std::string srcId(src);
+ std::string destId(dest);
+ symContext->extRefs.addFromAccessVal(idStr, srcId, destId);
+ });
+ }
+#endif
+}
+
void importdec::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "importdec", indent);
+ prettyname(out, "importdec", indent, getPos());
base.prettyprint(out, indent+1);
}
+void importdec::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ base.createSymMap(symContext);
+#endif
+}
+
void includedec::prettyprint(ostream &out, Int indent)
{
prettyindent(out, indent);
@@ -828,10 +1032,22 @@ void includedec::transAsField(coenv &e, record *r)
ast->transAsField(e, r);
}
+void includedec::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ std::string fullname((std::string) settings::locateFile(filename, true).c_str());
+ if (not AsymptoteLsp::isVirtualFile(fullname))
+ {
+ symContext->addEmptyExtRef(fullname);
+ symContext->extRefs.includeVals.emplace(fullname);
+ }
+#endif
+}
+
void typedec::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "typedec",indent);
+ prettyname(out, "typedec",indent, getPos());
body->prettyprint(out, indent+1);
}
@@ -895,6 +1111,24 @@ void recorddec::transAsField(coenv &e, record *parent)
addPostRecordEnvironment(e, r, parent);
}
+void recorddec::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ auto* newCtx = symContext->newContext(getPos().LineColumn());
+ auto* structTyInfo = symContext->newTypeDec<AsymptoteLsp::StructDecs>(
+ static_cast<std::string>(id), getPos().LineColumn());
+ if (structTyInfo != nullptr)
+ {
+ structTyInfo->ctx = newCtx;
+ body->createSymMap(newCtx);
+ }
+ else
+ {
+ cerr << "Cannot create new struct context" << endl;
+ }
+#endif
+}
+
runnable *autoplainRunnable() {
// Abstract syntax for the code:
// private import plain;
diff --git a/graphics/asymptote/dec.h b/graphics/asymptote/dec.h
index 1aae5a8fb6..5a8f8cdd0b 100644
--- a/graphics/asymptote/dec.h
+++ b/graphics/asymptote/dec.h
@@ -62,6 +62,11 @@ public:
virtual types::ty *trans(coenv &e, bool tacit = false) = 0;
virtual trans::tyEntry *transAsTyEntry(coenv &e, record *where);
+
+ virtual operator string() const = 0;
+#ifdef USEGC
+ operator std::string() const { return mem::stdString(this->operator string()); }
+#endif
};
class nameTy : public ty {
@@ -74,10 +79,12 @@ public:
nameTy(name *id)
: ty(id->getPos()), id(id) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- types::ty *trans(coenv &e, bool tacit = false);
- trans::tyEntry *transAsTyEntry(coenv &e, record *where);
+ types::ty *trans(coenv &e, bool tacit = false) override;
+ trans::tyEntry *transAsTyEntry(coenv &e, record *where) override;
+
+ virtual operator string() const override;
};
class dimensions : public absyn {
@@ -109,11 +116,13 @@ public:
arrayTy(name *id, dimensions *dims)
: ty(dims->getPos()), cell(new nameTy(id)), dims(dims) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
+
+ void addOps(coenv &e, record *r) override;
- void addOps(coenv &e, record *r);
+ types::ty *trans(coenv &e, bool tacit = false) override;
- types::ty *trans(coenv &e, bool tacit = false);
+ operator string() const override;
};
// Similar to varEntryExp, this helper class always translates to the same fixed
@@ -126,12 +135,13 @@ public:
tyEntryTy(position pos, types::ty *t);
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- types::ty *trans(coenv &e, bool tacit = false);
- trans::tyEntry *transAsTyEntry(coenv &, record *) {
+ types::ty *trans(coenv &e, bool tacit = false) override;
+ trans::tyEntry *transAsTyEntry(coenv &, record *) override {
return ent;
}
+ operator string() const override;
};
// Runnable is anything that can be executed by the program, including
@@ -208,11 +218,11 @@ public:
stms.push_back(r);
}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void trans(coenv &e);
+ void trans(coenv &e) override;
- void transAsField(coenv &e, record *r);
+ void transAsField(coenv &e, record *r) override;
void transAsRecordBody(coenv &e, record *r);
@@ -233,7 +243,9 @@ public:
// }
//
// is not guaranteed to return.
- bool returns();
+ bool returns() override;
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
class modifierList : public absyn {
@@ -307,7 +319,7 @@ public:
decidstart(position pos, symbol id, dimensions *dims = 0)
: absyn(pos), id(id), dims(dims) {}
- virtual void prettyprint(ostream &out, Int indent);
+ virtual void prettyprint(ostream &out, Int indent) override;
virtual types::ty *getType(types::ty *base, coenv &, bool = false);
virtual trans::tyEntry *getTyEntry(trans::tyEntry *base, coenv &e,
@@ -319,6 +331,9 @@ public:
virtual symbol getName()
{ return id; }
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
+ void createSymMapWType(AsymptoteLsp::SymbolContext* symContext, absyntax::ty* base);
};
// Forward declaration.
@@ -352,7 +367,7 @@ public:
decid(position pos, decidstart *start, varinit *init = 0)
: absyn(pos), start(start), init(init) {}
- virtual void prettyprint(ostream &out, Int indent);
+ virtual void prettyprint(ostream &out, Int indent) override;
virtual void transAsField(coenv &e, record *r, types::ty *base);
@@ -360,6 +375,9 @@ public:
virtual void transAsTypedefField(coenv &e, trans::tyEntry *base, record *r);
decidstart *getStart() { return start; }
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
+ void createSymMapWType(AsymptoteLsp::SymbolContext* symContext, absyntax::ty* base);
};
class decidlist : public absyn {
@@ -375,7 +393,7 @@ public:
decs.push_back(p);
}
- virtual void prettyprint(ostream &out, Int indent);
+ virtual void prettyprint(ostream &out, Int indent) override;
virtual void transAsField(coenv &e, record *r, types::ty *base);
@@ -390,6 +408,9 @@ public:
else
return 0;
}
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
+ void createSymMapWType(AsymptoteLsp::SymbolContext* symContext, absyntax::ty* base);
};
class dec : public runnable {
@@ -397,10 +418,10 @@ public:
dec(position pos)
: runnable(pos) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
// Declarations can be public or private.
- bool allowPermissions()
+ bool allowPermissions() override
{ return true; }
};
@@ -420,9 +441,9 @@ public:
{
decs->add(di);
}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void transAsField(coenv &e, record *r)
+ void transAsField(coenv &e, record *r) override
{
base->addOps(e, r);
decs->transAsField(e, r, base->trans(e));
@@ -438,6 +459,8 @@ public:
// If the vardec encodes a single declaration, return the type of that
// declaration (otherwise 0).
types::ty *singleGetType(coenv& e);
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
struct idpair : public absyn {
@@ -462,7 +485,7 @@ struct idpair : public absyn {
}
}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
// Translates as: access src as dest;
void transAsAccess(coenv &e, record *r);
@@ -471,6 +494,8 @@ struct idpair : public absyn {
// where _ is the qualifier record with source as its fields and types.
void transAsUnravel(coenv &e, record *r,
protoenv &source, varEntry *qualifier);
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
struct idpairlist : public gc {
@@ -486,6 +511,17 @@ struct idpairlist : public gc {
void transAsUnravel(coenv &e, record *r,
protoenv &source, varEntry *qualifier);
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext);
+
+ template<typename TFn>
+ void processListFn(TFn const& fn)
+ {
+ for (auto* idp : base)
+ {
+ fn(idp->src, idp->dest);
+ }
+ }
};
extern idpairlist * const WILDCARD;
@@ -498,11 +534,13 @@ public:
accessdec(position pos, idpairlist *base)
: dec(pos), base(base) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void transAsField(coenv &e, record *r) {
+ void transAsField(coenv &e, record *r) override {
base->transAsAccess(e,r);
}
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
// Abstract base class for
@@ -542,9 +580,9 @@ public:
fromdec(position pos, idpairlist *fields)
: dec(pos), fields(fields) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void transAsField(coenv &e, record *r);
+ void transAsField(coenv &e, record *r) override;
};
// An unravel declaration dumps fields and types of a record into the local
@@ -552,12 +590,14 @@ public:
class unraveldec : public fromdec {
name *id;
- qualifier getQualifier(coenv &e, record *);
+ qualifier getQualifier(coenv &e, record *) override;
public:
unraveldec(position pos, name *id, idpairlist *fields)
: fromdec(pos, fields), id(id) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
// A fromaccess declaration dumps fields and types of a module into the local
@@ -565,12 +605,14 @@ public:
class fromaccessdec : public fromdec {
symbol id;
- qualifier getQualifier(coenv &e, record *r);
+ qualifier getQualifier(coenv &e, record *r) override;
public:
fromaccessdec(position pos, symbol id, idpairlist *fields)
: fromdec(pos, fields), id(id) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
// An import declaration dumps fields and types of a module into the local
@@ -587,15 +629,17 @@ public:
base.add(new unraveldec(pos, new simpleName(pos, id->dest), WILDCARD));
}
- void trans(coenv &e) {
+ void trans(coenv &e) override {
base.trans(e);
}
- void transAsField(coenv &e, record *r) {
+ void transAsField(coenv &e, record *r) override {
base.transAsField(e, r);
}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
// Parses the file given, and translates the resulting runnables as if they
@@ -609,10 +653,12 @@ public:
includedec(position pos, symbol id)
: dec(pos), filename(id) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
void loadFailed(coenv &e);
- void transAsField(coenv &e, record *r);
+ void transAsField(coenv &e, record *r) override;
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
// Types defined from others in typedef.
@@ -646,9 +692,11 @@ public:
virtual ~recorddec()
{}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void transAsField(coenv &e, record *parent);
+ void transAsField(coenv &e, record *parent) override;
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
// Returns a runnable that facilitates the autoplain feature.
@@ -659,4 +707,3 @@ void addVar(coenv &e, record *r, varEntry *v, symbol id);
} // namespace absyntax
#endif
-
diff --git a/graphics/asymptote/doc/CAD.pdf b/graphics/asymptote/doc/CAD.pdf
index f55807bb30..14d1114072 100644
--- a/graphics/asymptote/doc/CAD.pdf
+++ b/graphics/asymptote/doc/CAD.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/FAQ/asy-faq.info b/graphics/asymptote/doc/FAQ/asy-faq.info
index c651d23349..9293c651c7 100644
--- a/graphics/asymptote/doc/FAQ/asy-faq.info
+++ b/graphics/asymptote/doc/FAQ/asy-faq.info
@@ -10,7 +10,7 @@ END-INFO-DIR-ENTRY
File: asy-faq.info, Node: Top, Next: Question 1.1, Up: (dir)
ASYMPTOTE FREQUENTLY ASKED QUESTIONS
- 2021-03-15
+ 2021-12-27
This is the list of Frequently Asked Questions about Asymptote (asy).
diff --git a/graphics/asymptote/doc/Makefile.in b/graphics/asymptote/doc/Makefile.in
index 8888df0145..f819f7dfbb 100644
--- a/graphics/asymptote/doc/Makefile.in
+++ b/graphics/asymptote/doc/Makefile.in
@@ -32,7 +32,7 @@ manpage: $(MANFILES)
man: $(DOCFILES) manpage
cd png && $(MAKE) asymptote.info
-faq:
+faq:
cd FAQ && $(MAKE) faq
%.eps: %.asy
@@ -65,7 +65,7 @@ asymptote.dvi: $(SOURCE) $(ASYFILES:.asy=.eps) latexusage.pdf
asymptote.pdf: $(SOURCE) $(ASYFILES:.asy=.pdf) latexusage.pdf
-$(TEXI2DVI) --pdf asymptote.texi
-CAD.pdf: CAD.tex CAD1.eps
+CAD.pdf: CAD.tex CAD1.eps
pdflatex CAD
pdflatex CAD
pdflatex CAD
@@ -80,10 +80,10 @@ asyRefCard.pdf: asyRefCard.tex
clean: FORCE
-rm -f asy-latex.{aux,idx,ins,log,toc}
-rm -f $(ASYFILES:.asy=.pdf)
- -rm -f *.eps latexusage.{dvi,eps,pdf,log,aux,*.eps} latexusage-* \
+ -rm -f *.eps latexusage.{dvi,eps,pdf,log,aux,out,*.eps} latexusage-* \
latexusage.pre
-rm -f \
- {asymptote,asymptote_}.{aux,cp,cps,dvi,fn,info,ky,log,pg,toc,tp,vr}
+ {asymptote,asymptote_}.{aux,cp,cps,dvi,fn,info,ky,log,pg,toc,tp,vr}
-rm -f asymptote_.texi
-rm -f {CAD,TeXShopAndAsymptote,asyRefCard}.{aux,dvi,log,toc}
-rm -f options asy.1
@@ -116,7 +116,7 @@ uninstall-all:
-rm -f $(addprefix $(docdir)/,$(DOCFILES))
distclean: FORCE clean
- -rm -f version.texi Makefile
+ -rm -f version.texi Makefile
-rm -f $(DOCFILES)
cd png && $(MAKE) distclean
cd FAQ && $(MAKE) distclean
diff --git a/graphics/asymptote/doc/TeXShopAndAsymptote.pdf b/graphics/asymptote/doc/TeXShopAndAsymptote.pdf
index 50759d15e8..bc39562057 100644
--- a/graphics/asymptote/doc/TeXShopAndAsymptote.pdf
+++ b/graphics/asymptote/doc/TeXShopAndAsymptote.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/asy-latex.pdf b/graphics/asymptote/doc/asy-latex.pdf
index 953b91a2a0..b0b693c1ab 100644
--- a/graphics/asymptote/doc/asy-latex.pdf
+++ b/graphics/asymptote/doc/asy-latex.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/asy.1 b/graphics/asymptote/doc/asy.1
index 4ad758ce37..71166fa234 100644
--- a/graphics/asymptote/doc/asy.1
+++ b/graphics/asymptote/doc/asy.1
@@ -31,6 +31,9 @@ in the user's home directory using the long form:
For a complete
description, see the Info files.
.TP
+.B \-GPUindexing
+Compute indexing partial sums on GPU [true].
+.TP
.B \-V,\-View
View output; command-line only.
.TP
@@ -103,12 +106,12 @@ Default output file precision [7].
.B \-divisor n
Garbage collect using purge(divisor=n) [2].
.TP
+.B \-dvisvgmMultipleFiles
+dvisvgm supports multiple files [false].
+.TP
.B \-embed
Embed rendered preview image [true].
.TP
-.B \-envmap
-Enable environment map image-based lighting (Experimental) [false].
-.TP
.B \-exitonEOF
Exit interactive mode on EOF [true].
.TP
@@ -136,9 +139,18 @@ Show summary of options; command-line only.
.B \-historylines n
Retain n lines of history [1000].
.TP
+.B \-ibl
+Enable environment map image-based lighting [false].
+.TP
.B \-iconify
Iconify rendering window [false].
.TP
+.B \-image string
+Environment image name [snowyField].
+.TP
+.B \-imageDir string
+Environment image library directory [ibl].
+.TP
.B \-inlineimage
Generate inline embedded image [false].
.TP
@@ -172,6 +184,12 @@ Use a local interactive history file [false].
.B \-loop
Loop 3D animations [false].
.TP
+.B \-lossy
+Use single precision for V3D reals [false].
+.TP
+.B \-lsp
+Special interactive mode for lsp-rpc [false].
+.TP
.B \-m,\-mask
Mask fpu exceptions; command-line only.
.TP
@@ -215,7 +233,10 @@ Delay before attempting initial pdf reload [750000].
Initial 3D rendering screen position [(0,0)].
.TP
.B \-prc
-Embed 3D PRC graphics in PDF output [true].
+Embed 3D PRC graphics in PDF output [false].
+.TP
+.B \-prerender resolution
+Prerender V3D objects (0 implies vector output) [0].
.TP
.B \-prompt string
Prompt [> ].
@@ -304,9 +325,15 @@ Wait for child processes to finish before exiting [false].
.B \-warn string
Enable warning; command-line only.
.TP
+.B \-webgl2
+Use webgl2 if available [false].
+.TP
.B \-where
Show where listed variables are declared [false].
.TP
+.B \-wsl
+Set to WSL mode when running asy inside WSL. [false].
+.TP
.B \-xasy
Special interactive mode for xasy [false].
.TP
diff --git a/graphics/asymptote/doc/asyRefCard.pdf b/graphics/asymptote/doc/asyRefCard.pdf
index 697d5a67b8..91f0963562 100644
--- a/graphics/asymptote/doc/asyRefCard.pdf
+++ b/graphics/asymptote/doc/asyRefCard.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/asymptote.pdf b/graphics/asymptote/doc/asymptote.pdf
index 26289f9316..2344714227 100644
--- a/graphics/asymptote/doc/asymptote.pdf
+++ b/graphics/asymptote/doc/asymptote.pdf
Binary files differ
diff --git a/graphics/asymptote/doc/asymptote.texi b/graphics/asymptote/doc/asymptote.texi
index 76d9a9f6db..bd9784f470 100644
--- a/graphics/asymptote/doc/asymptote.texi
+++ b/graphics/asymptote/doc/asymptote.texi
@@ -10,9 +10,9 @@
This file documents @code{Asymptote}, version @value{VERSION}.
@url{https://asymptote.sourceforge.io}
-
-Copyright @copyright{} 2004-20 Andy Hammerlindl, John Bowman, and Tom Prince.
-
+
+Copyright @copyright{} 2004-21 Andy Hammerlindl, John Bowman, and Tom Prince.
+
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the @acronym{GNU} Lesser General Public License (see the
@@ -20,7 +20,7 @@ file LICENSE in the top-level source directory).
@end quotation
@end copying
-
+
@dircategory Languages
@direntry
* asymptote: (asymptote/asymptote). Vector graphics language.
@@ -31,20 +31,20 @@ file LICENSE in the top-level source directory).
@subtitle For version @value{VERSION}
@sp 1
@center @image{./logo}
-
+
@page
@vskip 0pt plus 1filll
@insertcopying
-
+
@end titlepage
-
+
@c So the toc is printed at the start.
@contents
-
+
@ifnottex
@node Top, Description, (dir), (dir)
@top Asymptote
-
+
@insertcopying
@end ifnottex
@@ -60,6 +60,8 @@ file LICENSE in the top-level source directory).
* Options:: Command-line options
* Interactive mode:: Typing @code{Asymptote} commands interactively
* GUI:: Graphical user interface
+* Command-Line Interface:: Remote command-line interface
+* Language server protocol:: Help when writing code
* PostScript to Asymptote:: @code{Asymptote} backend to @code{pstoedit}
* Help:: Where to get help and submit bug reports
* Debugger:: Squish those bugs!
@@ -72,7 +74,7 @@ file LICENSE in the top-level source directory).
Installation
* UNIX binary distributions:: Prebuilt @code{UNIX} binaries
-* MacOS X binary distributions:: Prebuilt @code{MacOS X} binaries
+* MacOS X binary distributions:: Prebuilt @code{MacOS X} binaries
* Microsoft Windows:: Prebuilt @code{Microsoft Windows} binary
* Configuring:: Configuring @code{Asymptote} for your system
* Search paths:: Where @code{Asymptote} looks for your files
@@ -192,13 +194,16 @@ Labels and equations are typeset with @code{LaTeX}, for overall document
consistency, yielding the same high-quality level of typesetting that
@code{LaTeX} provides for scientific text. By default it produces
@code{PostScript} output, but it can also generate @code{PDF},
-@code{SVG}, @code{WebGL}, @code{PRC}, and any format that the
+@code{SVG}, @code{WebGL}, @code{V3D}, @code{PRC}, and any format that the
@code{ImageMagick} package can produce. You can even try it out in your
Web browser without installing it, using the @code{Asymptote Web
-Application}:
+Application}
@url{http://asymptote.ualberta.ca}
-
+
+It is also possible to send remote commands to this server via the
+curl utility (@pxref{Command-Line Interface}).
+
A major advantage of @code{Asymptote} over other graphics packages is
that it is a high-level programming language, as opposed to just a graphics
program: it can therefore exploit the best features of the script
@@ -213,7 +218,7 @@ simple @code{Asymptote} graphics commands (@pxref{Drawing commands}).
@code{Asymptote} is mathematically oriented (e.g.@ one can
use complex multiplication to rotate a vector) and uses
-@code{LaTeX} to do the
+@code{LaTeX} to do the
typesetting of labels. This is an important feature for scientific
applications. It was inspired by an earlier drawing program (with a weaker
syntax and capabilities) called @code{MetaPost}.
@@ -242,7 +247,7 @@ sacrificing portability;
@item the power of a script-based language coupled to the convenience of
a @acronym{GUI};
-@item customization using its own C++-like graphics programming language;
+@item customization using its own C++-like graphics programming language;
@item sensible defaults for graphical features, with the ability to override;
@@ -292,7 +297,7 @@ A quick reference card for @code{Asymptote} is available at
@menu
* UNIX binary distributions:: Prebuilt @code{UNIX} binaries
-* MacOS X binary distributions:: Prebuilt @code{MacOS X} binaries
+* MacOS X binary distributions:: Prebuilt @code{MacOS X} binaries
* Microsoft Windows:: Prebuilt @code{Microsoft Windows} binary
* Configuring:: Configuring @code{Asymptote} for your system
* Search paths:: Where @code{Asymptote} looks for your files
@@ -387,11 +392,11 @@ You will also need to install @code{GPL Ghostscript} version 9.52 or
later from @url{http://downloads.ghostscript.com/public}.
To view @code{PostScript} output, you can install the
-program @code{gsview} available from
-@url{http://www.cs.wisc.edu/~ghost/gsview/}.
+program @code{Sumatra PDF} available from
+@url{https://www.sumatrapdfreader.org/}.
The @code{ImageMagick} package from
-@url{https://www.imagemagick.org/script/binary-releases.php}
+@url{https://www.imagemagick.org/script/binary-releases.php}
@noindent
is required to support output formats other than @acronym{HTML},
@@ -401,7 +406,7 @@ required if you wish to try out the graphical user interface (@pxref{GUI}).
@noindent
Example code will be installed by default in the @code{examples}
-subdirectory of the installation directory (by default,
+subdirectory of the installation directory (by default,
@code{C:\Program Files\Asymptote}).
@node Configuring, Search paths, Microsoft Windows, Installation
@@ -468,14 +473,14 @@ Windows} registry. The @code{gs} setting specifies the location of the
@noindent
@cindex @code{htmlviewer}
@cindex @code{absolute}
-The configuration variable @code{htmlviewer} specifies the
+The configuration variable @code{htmlviewer} specifies the
browser to use to display 3D @code{WebGL} output.
The default setting is @code{google-chrome} under @code{UNIX} and
@code{cmd} under @code{Microsoft Windows}. Note that @code{Internet Explorer}
does not support @code{WebGL}; @code{Microsoft Windows} users should set their
default html browser to @code{chrome} or @code{microsoft-edge}.
By default, 2D and 3D @code{HTML} images expand to the enclosing canvas;
-this can be disabled by setting the configuation variable @code{absolute}
+this can be disabled by setting the configuration variable @code{absolute}
to @code{true}.
On @code{UNIX} systems, to support automatic document
@@ -560,9 +565,9 @@ ASYMPTOTE_PSVIEWER="C:\Program Files\Ghostgum\gsview\gsview32.exe";
under @code{Microsoft Windows XP}:
@enumerate
@item Click on the @code{Start} button;
-@item Right-click on @code{My Computer};
+@item Right-click on @code{My Computer};
@item Choose @code{View system information};
-@item Click the @code{Advanced} tab;
+@item Click the @code{Advanced} tab;
@item Click the @code{Environment Variables} button.
@end enumerate
@@ -692,7 +697,7 @@ If you don't want to install @code{Asymptote} system wide, just make
sure the compiled binary @code{asy} and @acronym{GUI} script @code{xasy} are in
your path and set the configuration variable @code{dir} to point
to the directory @code{base} (in the top level directory of the
-@code{Asymptote} source code).
+@code{Asymptote} source code).
@node Editing modes, Git, Compiling from UNIX source, Installation
@section Editing modes
@@ -725,7 +730,7 @@ package @code{two-mode-mode}:
@end quotation
@noindent
Once installed, you can use the hybrid mode @code{lasy-mode} to edit a
-LaTeX file containing embedded @code{Asymptote} code (@pxref{LaTeX usage}).
+LaTeX file containing embedded @code{Asymptote} code (@pxref{LaTeX usage}).
This mode can be enabled within @code{latex-mode}
with the key sequence @code{M-x lasy-mode <RET>}.
On @code{UNIX} systems, additional keywords will be generated from
@@ -909,7 +914,7 @@ However, it is often inconvenient to work directly in
The next example produces identical output to the previous example, by
scaling the line @code{(0,0)--(1,1)} to fit a rectangle of width
@code{100.5 bp} and height @code{100.5 bp} (the extra @code{0.5bp}
-accounts for the line width):
+accounts for the line width):
@verbatim
size(100.5,100.5);
draw((0,0)--(1,1));
@@ -948,7 +953,7 @@ To make the user coordinates represent multiples of exactly @code{1cm}:
@verbatim
unitsize(1cm);
draw(unitsquare);
-@end verbatim
+@end verbatim
@noindent
@node Labels, Paths, Figure size, Tutorial
@@ -966,11 +971,11 @@ coordinate, and an optional alignment direction:
@cindex @code{E}
@cindex @code{W}
@cindex @code{S}
-@code{Asymptote} uses the standard compass directions @code{E=(1,0)},
+@code{Asymptote} uses the standard compass directions @code{E=(1,0)},
@code{N=(0,1)}, @code{NE=unit(N+E)}, and @code{ENE=unit(E+NE)}, etc.,
which along with the directions @code{up}, @code{down}, @code{right},
and @code{left} are defined as pairs in the @code{Asymptote} base
-module @code{plain} (a user who has a local variable named @code{E}
+module @code{plain} (a user who has a local variable named @code{E}
may access the compass direction @code{E} by prefixing it with the name
of the module where it is defined: @code{plain.E}).
@@ -1100,7 +1105,7 @@ currentpicture).
@node draw, fill, Drawing commands, Drawing commands
@section draw
@cindex @code{draw}
-@verbatim
+@verbatim
void draw(picture pic=currentpicture, Label L="", path g,
align align=NoAlign, pen p=currentpen,
arrowbar arrow=None, arrowbar bar=None, margin margin=NoMargin,
@@ -1111,10 +1116,10 @@ Draw the path @code{g} on the picture @code{pic} using pen @code{p}
for drawing, with optional drawing attributes (Label @code{L},
explicit label alignment @code{align},
arrows and bars @code{arrow} and @code{bar}, margins @code{margin},
-legend, and markers @code{marker}). Only one parameter, the path, is
+legend, and markers @code{marker}). Only one parameter, the path, is
required. For convenience, the arguments @code{arrow} and @code{bar} may be
specified in either order. The argument @code{legend} is a Label to
-use in constructing an optional legend entry.
+use in constructing an optional legend entry.
@cindex @code{None}
@cindex @code{BeginBar}
@@ -1158,7 +1163,7 @@ The possible values of @code{arrow} are @code{None}, @code{Blank}
(which draws no arrows or path), @code{BeginArrow}, @code{MidArrow},
@code{EndArrow} (or equivalently @code{Arrow}),
and @code{Arrows} (which draws an arrow at both ends of the path).
-All of the arrow specifiers except for @code{None} and @code{Blank}
+All of the arrow specifiers except for @code{None} and @code{Blank}
may be given the optional arguments arrowhead @code{arrowhead} (one of
the predefined arrowhead styles @code{DefaultHead}, @code{SimpleHead},
@code{HookHead}, @code{TeXHead}),
@@ -1191,7 +1196,7 @@ curved arrows: @code{BeginArcArrow}, @code{EndArcArrow} (or equivalently
@cindex @code{TrueMargin}
Margins can be used to shrink the visible portion of a path by
@code{labelmargin(p)} to avoid overlap with other drawn objects.
-Typical values of @code{margin}
+Typical values of @code{margin}
are @code{NoMargin}, @code{BeginMargin}, @code{EndMargin} (or
equivalently @code{Margin}), and @code{Margins} (which leaves a margin
at both ends of the path). One may use
@@ -1223,7 +1228,7 @@ frame legend(picture pic=currentpicture, int perline=1,
real xmargin=legendmargin, real ymargin=xmargin,
real linelength=legendlinelength,
real hskip=legendhskip, real vskip=legendvskip,
- real maxwidth=0, real maxheight=0,
+ real maxwidth=0, real maxheight=0,
bool hstretch=false, bool vstretch=false, pen p=currentpen);
@end verbatim
@noindent
@@ -1266,7 +1271,7 @@ void dot(picture pic=currentpicture, Label L, pen p=currentpen,
If the variable @code{Label} is given as the @code{Label}
argument to the third routine, the @code{format} argument will be
used to format a string based on the dot location (here @code{defaultformat}
-is @code{"$%.4g$"}).
+is @code{"$%.4g$"}).
The fourth routine draws a dot at every point of a pair array @code{z}.
One can also draw a dot at every node of a path:
@verbatim
@@ -1296,7 +1301,7 @@ void fill(picture pic=currentpicture, path g, pen p=currentpen);
@end verbatim
Fill the interior region bounded by the cyclic path @code{g} on the picture
-@code{pic}, using the pen @code{p}.
+@code{pic}, using the pen @code{p}.
@cindex @code{filldraw}
There is also a convenient @code{filldraw} command, which fills the path
@@ -1369,7 +1374,7 @@ and @code{b}. An example of axial shading is provided in the example file
@cindex @code{radialshade}
Radial gradient shading varying smoothly from
@code{pena} on the circle with center @code{a} and radius @code{ra} to
-@code{penb} on the circle with center @code{b} and radius @code{rb}
+@code{penb} on the circle with center @code{b} and radius @code{rb}
is similar:
@verbatim
void radialshade(picture pic=currentpicture, path g, bool stroke=false,
@@ -1437,7 +1442,7 @@ void draw(picture pic=currentpicture, pen fillrule=currentpen, path[] g,
Illustrations of tensor product and Coons shading are provided in the
example files @code{@uref{https://asymptote.sourceforge.io/gallery/tensor.pdf,,tensor}@uref{https://asymptote.sourceforge.io/gallery/tensor.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/Coons.pdf,,Coons}@uref{https://asymptote.sourceforge.io/gallery/Coons.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/BezierPatch.pdf,,BezierPatch}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/BezierPatch.asy,,.asy}},
and @code{@uref{https://asymptote.sourceforge.io/gallery/rainbow.pdf,,rainbow}@uref{https://asymptote.sourceforge.io/gallery/rainbow.asy,,.asy}}.
-
+
@cindex Function shading
@cindex function shading
@cindex @code{functionshade}
@@ -1466,7 +1471,7 @@ void unfill(picture pic=currentpicture, path g);
@section clip
@cindex @code{clip}
@cindex @code{stroke}
-@verbatim
+@verbatim
void clip(picture pic=currentpicture, path g, stroke=false,
pen fillrule=currentpen);
@end verbatim
@@ -1512,7 +1517,7 @@ Label Label(Label L, align align=NoAlign,
pen p=nullpen, embed embed=L.embed, filltype filltype=NoFill);
@end verbatim
The text of a Label can be scaled, slanted, rotated, or shifted by
-multiplying it on the left by an affine transform (@pxref{Transforms}).
+multiplying it on the left by an affine transform (@pxref{Transforms}).
For example, @code{rotate(45)*xscale(2)*L} first scales @code{L} in the
@math{x} direction and then rotates it counterclockwise by 45
degrees. The final position of a Label can also be shifted by a
@@ -1537,7 +1542,7 @@ rotate with (picture-transformed) vector @code{z}.
@cindex @code{Slant}
only shift, rotate, slant, and reflect with embedding picture;
-@item Scale
+@item Scale
@cindex @code{Scale}
shift, rotate, slant, reflect, and scale with embedding picture.
@@ -1609,7 +1614,7 @@ layer();
@end verbatim
@cindex @code{baseline}
-The @code{string baseline(string s, string template="\strut")}
+The @code{string baseline(string s, string template="\strut")}
function can be used to enlarge the bounding box of labels to match a
given template, so that their baselines will be typeset on a
horizontal line. See @code{@uref{https://asymptote.sourceforge.io/gallery/Pythagoras.svg,,Pythagoras}@uref{https://asymptote.sourceforge.io/gallery/Pythagoras.asy,,.asy}} for an example.
@@ -1628,7 +1633,7 @@ frame pack(pair align=2S ... object inset[]);
To draw or fill a box (or ellipse or other path) around a Label and
return the bounding object, use one of the routines
@verbatim
-object draw(picture pic=currentpicture, Label L, envelope e,
+object draw(picture pic=currentpicture, Label L, envelope e,
real xmargin=0, real ymargin=xmargin, pen p=currentpen,
filltype filltype=NoFill, bool above=true);
object draw(picture pic=currentpicture, Label L, envelope e, pair position,
@@ -1638,7 +1643,7 @@ object draw(picture pic=currentpicture, Label L, envelope e, pair position,
@noindent
Here @code{envelope} is a boundary-drawing routine such as @code{box},
@code{roundbox}, or @code{ellipse} defined in @code{plain_boxes.asy}
-(@pxref{envelope}).
+(@pxref{envelope}).
@cindex @code{texpath}
The function @code{path[] texpath(Label L)} returns the path array that
@@ -1661,7 +1666,7 @@ Each interior node of a cubic spline may be given a
direction prefix or suffix @code{@{dir@}}: the direction of the pair
@code{dir} specifies the direction of the incoming or outgoing tangent,
respectively, to the curve at that node. Exterior nodes may be
-given direction specifiers only on their interior side.
+given direction specifiers only on their interior side.
A cubic spline between the node @math{z_0}, with postcontrol point
@math{c_0}, and the node @math{z_1}, with precontrol point @math{c_1},
@@ -1696,7 +1701,7 @@ The Bezier curve constructed in this manner has the following properties:
@item It is entirely contained in the convex hull of the given four points.
-@item It starts heading from the first endpoint to the first control point
+@item It starts heading from the first endpoint to the first control point
and finishes heading from the second control point to the second endpoint.
@end itemize
@@ -1714,7 +1719,7 @@ monograph, The MetaFontbook, Chapter 14.
The user can still customize the guide (or path) by specifying
direction, tension, and curl values.
-The higher the tension, the straighter the curve is, and the more
+The higher the tension, the straighter the curve is, and the more
it approximates a straight line.
@cindex @code{tension}
@cindex @code{and}
@@ -1786,7 +1791,7 @@ should coincide with the first node of the second path).
@end menu
Here is a short introductory example to the @code{Asymptote} programming
-language that highlights the similarity of its control structures
+language that highlights the similarity of its control structures
with those of C, C++, and Java:
@cindex declaration
@cindex assignment
@@ -1898,7 +1903,7 @@ floating-point type on the architecture. The implicit initializer for
reals is @code{0.0}. Real numbers have precision
@code{realEpsilon}, with @code{realDigits} significant digits.
The smallest positive real number is @code{realMin} and the largest
-positive real number is @code{realMax}.
+positive real number is @code{realMax}.
The variables @code{inf} and @code{nan}, along with the function
@code{bool isnan(real x)} are useful when floating-point exceptions
are masked with the @code{-mask} command-line option (the default in
@@ -1943,7 +1948,7 @@ The function @code{abs2(pair z)} returns @math{|@code{z}|^2};
@item real angle(pair z, bool warn=true)
@cindex @code{angle}
-returns the angle of @code{z} in radians in the interval
+returns the angle of @code{z} in radians in the interval
[-@code{pi},@code{pi}] or @code{0} if @code{warn} is @code{false} and
@code{z=(0,0)} (rather than producing an error);
@@ -1991,7 +1996,7 @@ returns a positive (negative) value if @code{a--b--c--cycle} is oriented
counterclockwise (clockwise) or zero if all three points are colinear.
Equivalently, a positive (negative) value is returned if
@code{c} lies to the left (right) of the line through @code{a} and @code{b}
-or zero if @code{c} lies on this line.
+or zero if @code{c} lies on this line.
The value returned can be expressed in terms of the 2D scalar cross product
as @code{cross(a-c,b-c)}, which is the determinant
@verbatim
@@ -1999,7 +2004,7 @@ as @code{cross(a-c,b-c)}, which is the determinant
|b.x b.y 1|
|c.x c.y 1|
@end verbatim
-
+
@cindex @code{incircle}
@item real incircle(pair a, pair b, pair c, pair d);
returns a positive (negative) value if @code{d} lies inside (outside)
@@ -2013,11 +2018,11 @@ The value returned is the determinant
|d.x d.y d.x^2+d.y^2 1|
@end verbatim
-@item pair minbound(pair z, pair w)
+@item pair minbound(pair z, pair w)
@cindex @code{minbound}
returns @code{(min(z.x,w.x),min(z.y,w.y))};
-@item pair maxbound(pair z, pair w)
+@item pair maxbound(pair z, pair w)
@cindex @code{maxbound}
returns @code{(max(z.x,w.x),max(z.y,w.y))}.
@@ -2027,7 +2032,7 @@ returns @code{(max(z.x,w.x),max(z.y,w.y))}.
@cindex @code{triple}
an ordered triple of real components @code{(x,y,z)} used for
three-dimensional drawings. The respective components of a triple
-@code{v} can read as @code{v.x}, @code{v.y}, and @code{v.z}.
+@code{v} can read as @code{v.x}, @code{v.y}, and @code{v.z}.
The implicit initializer for triples is @code{(0.0,0.0,0.0)}.
Here are the built-in functions for triples:
@@ -2102,7 +2107,7 @@ returns the dot product @code{u.x*v.x+u.y*v.y+u.z*v.z};
@item triple cross(triple u, triple v)
@cindex @code{cross}
-returns the cross product
+returns the cross product
@code{(u.y*v.z-u.z*v.y,u.z*v.x-u.x*v.z,u.x*v.y-v.x*u.y)};
@@ -2125,7 +2130,7 @@ Strings delimited by double quotes (@code{"}) are subject to the
following mappings to allow the use of double quotes in @TeX{} (e.g.@ for
using the @code{babel} package, @pxref{babel}):
-@itemize @bullet
+@itemize @bullet
@item \" maps to "
@item \\ maps to \\
@end itemize
@@ -2134,7 +2139,7 @@ using the @code{babel} package, @pxref{babel}):
Strings delimited by single quotes (@code{'}) have the same mappings as
character strings in ANSI @code{C}:
-@itemize @bullet
+@itemize @bullet
@item \' maps to '
@item \" maps to "
@item \? maps to ?
@@ -2178,7 +2183,7 @@ returns the string formed by inserting string @code{t} at position
@cindex @code{erase}
@item string erase(string s, int pos, int n)
-returns the string formed by erasing the string of length @code{n}
+returns the string formed by erasing the string of length @code{n}
(if @code{n}=-1, to the end of the string @code{s}) at
position @code{pos} in @code{s};
@@ -2192,7 +2197,7 @@ string @code{s});
@item string reverse(string s)
returns the string formed by reversing string @code{s};
-@item string replace(string s, string before, string after)
+@item string replace(string s, string before, string after)
@cindex @code{replace}
returns a string with all occurrences of the string @code{before} in the
string @code{s} changed to the string @code{after};
@@ -2275,7 +2280,7 @@ format used by the @code{UNIX} @code{date} command;
returns the time measured in seconds after the Epoch (Thu Jan 01
00:00:00 UTC 1970) as determined by the ANSI C routine @code{strptime}
according to the string @code{format} using the current locale, or the
-current time if @code{t} is the empty string.
+current time if @code{t} is the empty string.
Note that the @code{"%Z"} extension to the POSIX @code{strptime}
specification is ignored by the current GNU C Library. If an error occurs, the
value -1 is returned. Here are some examples:
@@ -2319,7 +2324,7 @@ file, line number, and @code{s} is printed;
@cindex @code{assert}
@item void assert(bool b, string s="")
aborts execution with an error message constructed from @code{s} if
-@code{b=false};
+@code{b=false};
@cindex @code{exit}
@item void exit()
@@ -2353,7 +2358,7 @@ As in C/C++, complicated types may be abbreviated with @code{typedef}
@item path
@cindex @code{path}
-a cubic spline resolved into a fixed path.
+a cubic spline resolved into a fixed path.
The implicit initializer for paths is @code{nullpath}.
@cindex @code{circle}
@@ -2390,7 +2395,7 @@ path arc(pair c, real r, real angle1, real angle2, bool direction);
Here the direction can be specified as CCW (counter-clockwise) or CW
(clockwise). For convenience, an arc centered at @code{c} from pair
@code{z1} to @code{z2} (assuming @code{|z2-c|=|z1-c|}) in the may also
-be constructed with
+be constructed with
@verbatim
path arc(pair c, explicit pair z1, explicit pair z2,
bool direction=CCW)
@@ -2475,7 +2480,7 @@ endpoint of @code{p}.
@cindex @code{dir}
@item pair dir(path p, int t, int sign=0, bool normalize=true);
-If @code{sign < 0}, return the direction (as a pair) of the incoming tangent
+If @code{sign < 0}, return the direction (as a pair) of the incoming tangent
to path @code{p} at node @code{t}; if @code{sign > 0}, return the
direction of the outgoing tangent. If @code{sign=0}, the mean of these
two directions is returned.
@@ -2562,22 +2567,22 @@ returns a path running backwards along @code{p}.
@cindex @code{subpath}
@item path subpath(path p, int a, int b);
returns the subpath of @code{p} running from node @code{a} to node @code{b}.
-If @code{a} < @code{b}, the direction of the subpath is reversed.
+If @code{a} > @code{b}, the direction of the subpath is reversed.
@item path subpath(path p, real a, real b);
returns the subpath of @code{p} running from path time @code{a} to path
-time @code{b}, in the sense of @code{point(path, real)}. If @code{a} <
+time @code{b}, in the sense of @code{point(path, real)}. If @code{a} >
@code{b}, the direction of the subpath is reversed.
@cindex @code{intersect}
@item real[] intersect(path p, path q, real fuzz=-1);
If @code{p} and @code{q} have at least one intersection point, return a
real array of length 2 containing the times representing the respective
-path times along @code{p} and @code{q}, in the sense of
+path times along @code{p} and @code{q}, in the sense of
@code{point(path, real)}, for one such intersection point (as chosen by
-the algorithm described on page 137 of @code{The MetaFontbook}).
-The computations are performed to the absolute error specified by @code{fuzz},
-or if @code{fuzz < 0}, to machine precision. If the paths do not
+the algorithm described on page 137 of @code{The MetaFontbook}).
+The computations are performed to the absolute error specified by @code{fuzz},
+or if @code{fuzz < 0}, to machine precision. If the paths do not
intersect, return a real array of length 0.
@cindex @code{intersections}
@@ -2628,7 +2633,7 @@ returns an array containing all intersection points of the paths
@cindex @code{whatever}
@cindex @code{extension}
@item pair extension(pair P, pair Q, pair p, pair q);
-returns the intersection point of the extensions of the line segments
+returns the intersection point of the extensions of the line segments
@code{P--Q} and @code{p--q}, or if the lines are parallel,
@code{(infinity,infinity)}.
@@ -2658,13 +2663,13 @@ cutbefore} command.
@item slice lastcut(path p, path knife);
equivalent to @code{cut(p,knife,-1);}
@cindex @code{MetaPost cutafter}
-Note that @code{lastcut.before} plays the role of the
+Note that @code{lastcut.before} plays the role of the
@code{MetaPost cutafter} command.
@cindex @code{buildcycle}
@item path buildcycle(... path[] p);
This returns the path surrounding a region bounded by a list of two or more
-consecutively intersecting paths, following the behaviour of the
+consecutively intersecting paths, following the behaviour of the
@code{MetaPost buildcycle} command.
@cindex @code{min}
@@ -2692,7 +2697,7 @@ according to @code{fillrule}.
@item bool inside(path p, pair z, pen fillrule=currentpen);
returns @code{true} iff the point @code{z} lies inside or on the edge of
the region bounded by the cyclic path @code{p} according to the fill
-rule @code{fillrule} (@pxref{fillrule}).
+rule @code{fillrule} (@pxref{fillrule}).
@cindex @code{inside}
@item int inside(path p, path q, pen fillrule=currentpen);
@@ -2899,7 +2904,7 @@ the colorspace of pen @code{p} as a string (@code{"gray"}, @code{"rgb"},
The function @code{real[] colors(pen)} returns the color components of a pen.
The functions @code{pen gray(pen)}, @code{pen rgb(pen)}, and
@code{pen cmyk(pen)} return new pens obtained by converting their
-arguments to the respective color spaces.
+arguments to the respective color spaces.
@cindex @code{colorless}
The function @code{colorless(pen=currentpen)} returns a copy of its argument
with the color attributes stripped (to avoid color mixing).
@@ -2963,7 +2968,7 @@ hsv q=p;
write(q.h,q.s,q.v); // 180 0.5 0.75
@end verbatim
-@item Line types are specified with the function
+@item Line types are specified with the function
@code{pen linetype(real[] a, real offset=0, bool scale=true, bool adjust=true)},
@cindex @code{solid}
@cindex @code{dashed}
@@ -3001,7 +3006,7 @@ The default line type is @code{solid}; this may be changed with
@cindex @code{scale}
@cindex @code{adjust}
The line type of a pen can be determined with the functions
-@code{real[] linetype(pen p=currentpen)},
+@code{real[] linetype(pen p=currentpen)},
@code{real offset(pen p)}, @code{bool scale(pen p)}, and
@code{bool adjust(pen p)}.
@@ -3029,7 +3034,7 @@ pen p=red+0.5;
@cindex @code{extendcap}
@cindex @code{defaultpen}
@item A pen with a specific @code{PostScript} line cap is returned on
-calling @code{linecap} with an integer argument:
+calling @code{linecap} with an integer argument:
@verbatim
pen squarecap=linecap(0);
pen roundcap=linecap(1);
@@ -3124,8 +3129,8 @@ available from
@url{http://mirror.ctan.org/macros/latex/contrib/type1cm/}
@end quotation
and included in recent @code{LaTeX} distributions). The font size and line
-skip of a pen can be examined with the routines
-@code{real fontsize(pen p=currentpen)} and
+skip of a pen can be examined with the routines
+@code{real fontsize(pen p=currentpen)} and
@code{real lineskip(pen p=currentpen)}, respectively.
@cindex font
@@ -3135,7 +3140,7 @@ skip of a pen can be examined with the routines
by calling the function @code{pen font(string encoding, string family,
string series, string shape)}. The default setting,
@code{font("OT1","cmr","m","n")}, corresponds to 12pt Computer Modern Roman;
-this may be changed with @code{defaultpen(pen)}.
+this may be changed with @code{defaultpen(pen)}.
The font setting of a pen is returned by
@code{string font(pen p=currentpen)}.
@@ -3228,7 +3233,7 @@ formats can be produced from the resulting @acronym{PDF} file with the
@code{ImageMagick} @code{convert} program.
Labels are always drawn with an @code{opacity} of 1.
A simple example of transparent filling is provided in the example file
-@code{@uref{https://asymptote.sourceforge.io/gallery/transparency.svg,,transparency}@uref{https://asymptote.sourceforge.io/gallery/transparency.asy,,.asy}}.
+@code{@uref{https://asymptote.sourceforge.io/gallery/transparency.svg,,transparency}@uref{https://asymptote.sourceforge.io/gallery/transparency.asy,,.asy}}.
@cindex patterns
@cindex tilings
@@ -3244,7 +3249,7 @@ void add(string name, picture pic, pair lb=0, pair rt=0);
To @code{fill} or @code{draw} using pattern @code{name}, use
the pen @code{pattern("name")}. For example, rectangular tilings
-can be constructed using the routines
+can be constructed using the routines
@code{picture tile(real Hx=5mm, real Hy=0, pen p=currentpen,
filltype filltype=NoFill)},
@code{picture checker(real Hx=5mm, real Hy=0, pen p=currentpen)}, and
@@ -3338,7 +3343,7 @@ attributes to their initial values.
@cindex @code{transform}
@code{Asymptote} makes extensive use of affine transforms. A pair
-@code{(x,y)} is transformed by the transform
+@code{(x,y)} is transformed by the transform
@code{t=(t.x,t.y,t.xx,t.xy,t.yx,t.yy)} to @code{(x',y')}, where
@verbatim
x' = t.x + t.xx * x + t.xy * y
@@ -3461,7 +3466,7 @@ path ellipse(frame f, Label L="", real xmargin=0,
@item picture
@cindex @code{picture}
Pictures are high-level structures (@pxref{Structures}) defined in
-the module @code{plain} that provide canvases for drawing in user coordinates.
+the module @code{plain} that provide canvases for drawing in user coordinates.
The default picture is called @code{currentpicture}. A new picture
can be created like this:
@verbatim
@@ -3498,7 +3503,7 @@ no more than @code{y}.
@cindex @code{IgnoreAspect}
If @code{keepAspect} is set to @code{IgnoreAspect} or @code{false},
the picture will be scaled in both directions so that the final width
-is @code{x} and the height is @code{y}.
+is @code{x} and the height is @code{y}.
To make the user coordinates of picture @code{pic}
represent multiples of @code{x} units in the @math{x} direction and
@@ -3561,7 +3566,7 @@ previous @code{shipout} commands have been executed.
The default page orientation is @code{Portrait}; this may be modified
by changing the variable @code{orientation}. To output in landscape
mode, simply set the variable @code{orientation=Landscape} or issue
-the command
+the command
@verbatim
shipout(Landscape);
@end verbatim
@@ -3615,7 +3620,7 @@ Fill the interior and draw the boundary.
@code{pen drawpen=nullpen)}
@cindex @code{nullpen}
If @code{fillpen} is @code{nullpen}, fill with the drawing pen;
-otherwise fill with pen @code{fillpen}.
+otherwise fill with pen @code{fillpen}.
If @code{drawpen} is @code{nullpen}, draw the boundary with @code{fillpen};
otherwise with @code{drawpen}. An optional margin of
@code{xmargin} and @code{ymargin} can be specified.
@@ -3626,7 +3631,7 @@ Fill the interior.
@cindex @code{nullpen}
@item Fill(real xmargin=0, real ymargin=xmargin, pen p=nullpen)
-If @code{p} is @code{nullpen}, fill with the drawing pen;
+If @code{p} is @code{nullpen}, fill with the drawing pen;
otherwise fill with pen @code{p}. An optional margin of
@code{xmargin} and @code{ymargin} can be specified.
@@ -3639,7 +3644,7 @@ Draw only the boundary.
@cindex @code{Draw}
@item Draw(real xmargin=0, real ymargin=xmargin, pen p=nullpen)
-If @code{p} is @code{nullpen}, draw the boundary with the drawing pen;
+If @code{p} is @code{nullpen}, draw the boundary with the drawing pen;
otherwise draw with pen @code{p}. An optional margin of
@code{xmargin} and @code{ymargin} can be specified.
@@ -3671,7 +3676,7 @@ margin and output the resulting frame, use the command:
shipout(bbox(0.25cm));
@end verbatim
A @code{picture} may be fit to a frame with the background color
-pen @code{p}, using the function @code{bbox(p,Fill)}.
+pen @code{p}, using the function @code{bbox(p,Fill)}.
@cindex @code{pad}
To pad a picture to a precise size in both directions, fit the picture
@@ -3681,12 +3686,12 @@ frame pad(picture pic=currentpicture, real xsize=pic.xsize,
real ysize=pic.ysize, filltype filltype=NoFill);
@end verbatim
-The functions
+The functions
@verbatim
pair min(picture pic, user=false);
pair max(picture pic, user=false);
pair size(picture pic, user=false);
-@end verbatim
+@end verbatim
calculate the bounds that picture @code{pic} would
have if it were currently fit to a frame using its default size specification.
If @code{user} is @code{false} the returned value is in
@@ -3724,7 +3729,7 @@ void add(picture dest, picture src, bool group=true,
@end verbatim
@noindent
The first example adds @code{src} to @code{currentpicture}; the second
-one adds @code{src} to @code{dest}.
+one adds @code{src} to @code{dest}.
The @code{group} option specifies whether or not the graphical user
interface should treat all of the elements of @code{src}
as a single entity (@pxref{GUI}), @code{filltype} requests optional
@@ -3836,9 +3841,9 @@ The routine
@verbatim
void usepackage(string s, string options="");
@end verbatim
-provides a convenient abbreviation for
+provides a convenient abbreviation for
@verbatim
-texpreamble("\usepackage["+options+"]{"+s+"}");
+texpreamble("\usepackage["+options+"]{"+s+"}");
@end verbatim
@noindent
that can be used for importing @code{LaTeX} packages.
@@ -3967,7 +3972,7 @@ write(fout); // Writes a new line
write(fout,"List: ",1,2,3); // Writes "List: 1 2 3"
@end verbatim
@noindent
-
+
@cindex binary format
@cindex single precision
@cindex double precision
@@ -3989,7 +3994,7 @@ or to read the entire file into a string.
The virtual member functions
@code{file singlereal(bool b=true)} and @code{file singleint(bool b=true)}
be used to change the precision of real and integer I/O
-operations, respectively, for an @acronym{XDR} or binary file @code{f}.
+operations, respectively, for an @acronym{XDR} or binary file @code{f}.
Similarly, the function @code{file signedint(bool b=true)}
can be used to modify the signedness of integer reads and writes for
an @acronym{XDR} or binary file @code{f}.
@@ -4017,7 +4022,7 @@ One can test a file for end-of-file with the boolean function @code{eof(file)},
end-of-line with @code{eol(file)}, and for I/O errors with @code{error(file)}.
One can flush the output buffers with @code{flush(file)}, clear a
previous I/O error with @code{clear(file)}, and close the file with
-@code{close(file)}. The function
+@code{close(file)}. The function
@code{int precision(file file=stdout, int digits=0)}
sets the number of digits of output precision for @code{file} to @code{digits},
provided @code{digits} is nonzero, and returns the previous
@@ -4074,10 +4079,10 @@ string readline(string prompt="", string name="", bool tabcompletion=false);
void saveline(string name, string value, bool store=true);
@end verbatim
Here, @code{readline} prompts the user with the default value
-formatted according to @code{prompt}, while @code{saveline}
+formatted according to @code{prompt}, while @code{saveline}
is used to save the string @code{value} in a local history named
@code{name}, optionally storing the local history in a file
-@code{".asy_history_"+name}.
+@code{".asy_history_"+name}.
@cindex @code{history}
The routine @code{history(string name, int n=1)} can be used to look up
@@ -4111,7 +4116,7 @@ int animate(string args="", string file="", string format="");
@noindent
call the @code{ImageMagick} commands @code{convert} and @code{animate},
respectively, with the arguments @code{args} and the file name constructed
-from the strings @code{file} and @code{format}.
+from the strings @code{file} and @code{format}.
@node Variable initializers, Structures, Files, Programming
@section Variable initializers
@@ -4220,7 +4225,7 @@ only inside the structure where they are defined) or @code{private}
(readable and writable only inside the structure). In a structure definition,
the keyword @code{this} can be used as an expression to refer to the enclosing
structure. Any code at the
-top-level scope within the structure is executed on initialization.
+top-level scope within the structure is executed on initialization.
Variables hold references to structures. That is, in the example:
@verbatim
@@ -4255,7 +4260,7 @@ T foo;
@noindent
Here, @code{new T} produces a new instance of the class, which
causes @code{Tcount} to be incremented, tracking the
-number of instances produced. The declarations @code{T foo=new T} and
+number of instances produced. The declarations @code{T foo=new T} and
@code{T foo} are equivalent: the second form implicitly creates a new
instance of @code{T}.
That is, after the definition of a structure @code{T}, a variable of
@@ -4328,7 +4333,7 @@ Creating a new Person is a chore; it takes three lines to create a new instance
and to initialize its fields (that's still considerably less effort than
creating a new person in real life, though).
-We can reduce the work by defining a constructor function
+We can reduce the work by defining a constructor function
@code{Person(string,string)}:
@verbatim
struct Person {
@@ -4413,13 +4418,13 @@ the corresponding fields since the last call to @code{cputime()}. The
function
@verbatim
void write(file file=stdout, string s="", cputime c,
- string format=cputimeformat, suffix suffix=none);
+ string format=cputimeformat, suffix suffix=none);
@end verbatim
@noindent
-displays the incremental user cputime followed by ``u'',
-the incremental system cputime followed by ``s'',
+displays the incremental user cputime followed by ``u'',
+the incremental system cputime followed by ``s'',
the total user cputime followed by ``U'', and
-the total system cputime followed by ``S''.
+the total system cputime followed by ``S''.
@cindex inheritance
@cindex virtual functions
@@ -4434,7 +4439,7 @@ struct parent {
}
void write(parent p) {write(p.x);}
-
+
struct child {
parent parent;
real y=3;
@@ -4445,7 +4450,7 @@ struct child {
}
parent operator cast(child child) {return child.parent;}
-
+
parent p=parent(1);
child c=child(2);
@@ -4485,7 +4490,7 @@ converted to real values before dividing and a real quotient is
returned (since this is typically what is intended; otherwise
one can use the function @code{int quotient(int x, int y)}, which returns
greatest integer less than or equal to @code{x/y}). In all other cases both
-operands are promoted to the same type, which will also be the
+operands are promoted to the same type, which will also be the
type of the result:
@table @code
@cindex @code{+}
@@ -4509,7 +4514,7 @@ integer division, we decided to reciprocate and use their comment
symbol for integer division in @code{Asymptote}!
@cindex @code{%}
@item %
-modulo; the result always has the same sign as the divisor.
+modulo; the result always has the same sign as the divisor.
In particular, this makes @code{q*(p # q)+p % q == p} for all
integers @code{p} and nonzero integers @code{q}.
@cindex @code{^}
@@ -4602,7 +4607,7 @@ length bits).
@cindex @code{--}
As in C, each of the arithmetic operators @code{+}, @code{-}, @code{*},
-@code{/}, @code{#}, @code{%}, and @code{^} can be used as a self operator.
+@code{/}, @code{#}, @code{%}, and @code{^} can be used as a self operator.
The prefix operators @code{++} (increment by one) and @code{--} (decrement
by one) are also defined.
For example,
@@ -4623,7 +4628,7 @@ int j=i=i+1;
@cindex postfix operators
However, postfix operators like @code{i++} and @code{i--} are not defined
(because of the inherent ambiguities that would arise with the @code{--}
-path-joining operator). In the rare instances where @code{i++}
+path-joining operator). In the rare instances where @code{i++}
and @code{i--} are really needed, one can substitute the expressions
@code{(++i-1)} and @code{(--i+1)}, respectively.
@@ -4668,7 +4673,7 @@ write("g=",g);
@section Implicit scaling
@cindex implicit scaling
-If a numeric literal is in front of certain types of expressions, then the two
+If a numeric literal is in front of certain types of expressions, then the two
are multiplied:
@verbatim
int x=2;
@@ -4714,9 +4719,9 @@ This produces the output
* Mathematical functions:: Standard libm functions
@end menu
-@code{Asymptote} functions are treated as variables with a signature
-(non-function variables have null signatures). Variables with the
-same name are allowed, so long as they have distinct signatures.
+@code{Asymptote} functions are treated as variables with a signature
+(non-function variables have null signatures). Variables with the
+same name are allowed, so long as they have distinct signatures.
Function arguments are passed by value. To pass an argument by
reference, simply enclose it in a structure (@pxref{Structures}).
@@ -4727,7 +4732,7 @@ Here are some significant features of @code{Asymptote} functions:
@item Variables with signatures (functions) and without signatures
(nonfunction variables) are distinct:
@verbatim
-int x, x();
+int x, x();
x=5;
x=new int() {return 17;};
x=x(); // calls x() and puts the result, 17, in the scalar x
@@ -4735,7 +4740,7 @@ x=x(); // calls x() and puts the result, 17, in the scalar x
@item Traditional function definitions are allowed:
@verbatim
-int sqr(int x)
+int sqr(int x)
{
return x*x;
}
@@ -4766,7 +4771,7 @@ intop addby7=adder(7);
write(addby7(1)); // Writes 8.
@end verbatim
-@item
+@item
@cindex overloading functions
One may redefine a function @code{f}, even for calls to @code{f} in previously
declared functions, by assigning another (anonymous or named)
@@ -4776,26 +4781,26 @@ version of @code{f}, as illustrated in this example:
@verbatim
void f() {
write("hi");
-}
-
+}
+
void g() {
f();
-}
-
-g(); // writes "hi"
-
-f=new void() {write("bye");};
+}
+
+g(); // writes "hi"
+
+f=new void() {write("bye");};
-g(); // writes "bye"
-
-void f() {write("overloaded");};
+g(); // writes "bye"
+
+void f() {write("overloaded");};
f(); // writes "overloaded"
-g(); // writes "bye"
+g(); // writes "bye"
@end verbatim
@cindex function declarations
-@item Anonymous functions can be used to redefine a function variable
+@item Anonymous functions can be used to redefine a function variable
that has been declared (and implicitly initialized to the null function)
but not yet explicitly defined:
@verbatim
@@ -4818,7 +4823,7 @@ g(true); // Writes true, then writes false.
@code{Asymptote} is the only language we know of that treats functions
as variables, but allows overloading by distinguishing variables
-based on their signatures.
+based on their signatures.
@cindex @code{libsigsegv}
@cindex stack overflow
@@ -4863,7 +4868,7 @@ functions with multiple arguments easier. Unlike in the C and C++
languages, an assignment in a function argument is interpreted as an
assignment to a parameter of the same name in the function signature,
@emph{not within the local scope}. The command-line option @code{-d}
-may be used to check @code{Asymptote} code for cases where a
+may be used to check @code{Asymptote} code for cases where a
named argument may be mistaken for a local assignment.
When matching arguments to signatures, first all of the keywords are
@@ -4875,9 +4880,9 @@ int f(int x, int y) {
}
write(f(4,x=3));
@end verbatim
-@noindent
+@noindent
outputs 34, as @code{x} is already matched when we try to match the
-unnamed argument @code{4}, so it gets matched to the next item, @code{y}.
+unnamed argument @code{4}, so it gets matched to the next item, @code{y}.
For the rare occasions where it is desirable to assign a value to
local variable within a function argument (generally @emph{not} a good
@@ -4942,7 +4947,7 @@ number of arguments:
@verbatim
// This function sums its arguments.
int sum(... int[] nums) {
- int total=0;
+ int total=0;
for(int i=0; i < nums.length; ++i)
total += nums[i];
return total;
@@ -4962,8 +4967,8 @@ subtract(10,1,2); // returns 7
subtract(10); // returns 10
subtract(); // illegal
@end verbatim
-
-@cindex packing
+
+@cindex packing
Putting an argument into a rest array is called @emph{packing}.
One can give an explicit list of arguments for the rest
argument, so @code{subtract} could alternatively be implemented as
@@ -4972,7 +4977,7 @@ int subtract(int start ... int[] subs) {
return start - sum(... subs);
}
@end verbatim
-
+
One can even combine normal arguments with rest arguments:
@verbatim
sum(1,2,3 ... new int[] {4,5,6}); // returns 21
@@ -5078,7 +5083,7 @@ real(real) functions @code{sin}, @code{cos}, @code{tan}, @code{asin},
@code{acos}, @code{atan}, @code{exp}, @code{log}, @code{pow10},
@code{log10}, @code{sinh}, @code{cosh}, @code{tanh}, @code{asinh},
@code{acosh}, @code{atanh}, @code{sqrt}, @code{cbrt}, @code{fabs}, @code{expm1},
-@code{log1p}, as well as the identity function @code{identity}.
+@code{log1p}, as well as the identity function @code{identity}.
@code{Asymptote} also defines the order @code{n} Bessel functions of
the first kind @code{Jn(int n, real)} and second kind
@code{Yn(int n, real)}, as well as the gamma function @code{gamma},
@@ -5114,7 +5119,7 @@ their usual definitions in that they all return an int value rather than
a real (since that is normally what one wants).
The functions @code{Floor}, @code{Ceil}, and @code{Round} are
respectively similar, except that if the result cannot be converted
-to a valid int, they return @code{intMax}
+to a valid int, they return @code{intMax}
for positive arguments and @code{intMin} for negative arguments,
rather than generating an integer overflow.
We also define a function @code{sgn}, which returns the sign of its
@@ -5180,15 +5185,15 @@ also defined.
When configured with the @acronym{GNU} Scientific Library (GSL), available from
@url{https://www.gnu.org/software/gsl/},
@code{Asymptote} contains an internal module @code{gsl} that
-defines the airy functions @code{Ai(real)},
+defines the airy functions @code{Ai(real)},
@code{Bi(real)}, @code{Ai_deriv(real)}, @code{Bi_deriv(real)},
@code{zero_Ai(int)}, @code{zero_Bi(int)},
@code{zero_Ai_deriv(int)}, @code{zero_Bi_deriv(int)}, the Bessel functions
@code{I(int, real)}, @code{K(int, real)}, @code{j(int, real)},
@code{y(int, real)}, @code{i_scaled(int, real)}, @code{k_scaled(int, real)},
@code{J(real, real)}, @code{Y(real, real)}, @code{I(real, real)},
-@code{K(real, real)}, @code{zero_J(real, int)}, the elliptic functions
-@code{F(real, real)}, @code{E(real, real)}, and @code{P(real, real)},
+@code{K(real, real)}, @code{zero_J(real, int)}, the elliptic functions
+@code{F(real, real)}, @code{E(real, real)}, and @code{P(real, real)},
the Jacobi elliptic functions @code{real[] sncndn(real,real)},
the exponential/trigonometric integrals @code{Ei}, @code{Si}, and @code{Ci},
the Legendre polynomials @code{Pl(int, real)}, and the Riemann zeta
@@ -5208,7 +5213,7 @@ write(Si(1.0));
Use Newton-Raphson iteration to solve for a root of a real-valued
differentiable function @code{f}, given its derivative @code{fprime} and
an initial guess @code{x}. Diagnostics for
-each iteration are printed if @code{verbose=true}.
+each iteration are printed if @code{verbose=true}.
If the iteration fails after the maximum allowed number of loops
(@code{iterations}), @code{realMax} is returned.
@@ -5244,12 +5249,12 @@ By default, attempts to access or assign to an array element using a negative
index generates an error. Reading an array element with an index
beyond the length of the array also generates an error; however,
assignment to an element beyond the length of the array causes the
-array to be resized to accommodate the new element.
+array to be resized to accommodate the new element.
One can also index an array @code{A} with an integer array @code{B}:
the array @code{A[B]} is formed by indexing array @code{A} with
successive elements of array @code{B}.
A convenient Java-style shorthand exists for iterating over all elements of an
-array; see @ref{array iteration}.
+array; see @ref{array iteration}.
The declaration
@verbatim
@@ -5273,7 +5278,7 @@ real[] A={0,1,2};
@end verbatim
Array assignment in @code{Asymptote} does a shallow copy: only
-the pointer is copied (if one copy if modified, the other will be too).
+the pointer is copied (if one copy if modified, the other will be too).
The @code{copy} function listed below provides a deep copy of an array.
@cindex @code{length}
@@ -5294,7 +5299,7 @@ Every array @code{A} of type @code{T[]} has the virtual members
@item @code{void append(T[] a)},
@item @code{T pop()},
@item @code{void insert(int i ... T[] x)},
-@item @code{void delete(int i, int j=i)},
+@item @code{void delete(int i, int j=i)},
@item @code{void delete()}, and
@item @code{bool initialized(int n)}.
@end itemize
@@ -5347,7 +5352,7 @@ real a,A[];
@end verbatim
@noindent
This declares @code{a} to be @code{real} and implicitly declares @code{A} to
-be of type @code{real[]}.
+be of type @code{real[]}.
In the following list of built-in array functions, @code{T} represents a
generic type. Note that the internal functions @code{alias}, @code{array},
@@ -5367,7 +5372,7 @@ returns a new array of type @code{T[]} initialized with @code{list} (a comma
delimited list of elements);
@item new T[n]
-returns a new array of @code{n} elements of type @code{T[]}.
+returns a new array of @code{n} elements of type @code{T[]}.
These @code{n} array elements are not initialized unless they are arrays
themselves (in which case they are each initialized to empty arrays);
@@ -5387,6 +5392,10 @@ a null array);
if @code{m >= n} returns an array @code{@{n,n+1,...,m@}} (otherwise
returns a null array);
+@item int[] sequence(int n, int m, int skip)
+if @code{m >= n} returns an array @code{@{n,n+1,...,m@}} skipping by
+@code{skip} (otherwise returns a null array);
+
@item T[] sequence(T f(int), int n)
if @code{n >= 1} returns the sequence @code{@{f_i :i=0,1,...n-1@}} given a
function @code{T f(int)} and integer @code{int n} (otherwise returns a
@@ -5424,7 +5433,7 @@ if @code{n >= 1} returns a uniform partition of @code{[a,b]} into
@item int find(bool[] a, int n=1)
returns the index of the @code{n}th @code{true} value in the boolean array
@code{a} or -1 if not found. If @code{n} is negative, search backwards
-from the end of the array for the @code{-n}th value;
+from the end of the array for the @code{-n}th value;
@cindex @code{findall}
@item int[] findall(bool[] a)
@@ -5585,13 +5594,13 @@ is an @math{n} vector and @math{L} is the @math{n \times n} matrix
@end verbatim
For Dirichlet boundary conditions (denoted here by @code{u[-1]} and
@code{u[n]}), replace @code{f[0]} by @code{f[0]-a[0]u[-1]} and
-@code{f[n-1]-c[n-1]u[n]}; then set @code{a[0]=c[n-1]=0};
+@code{f[n-1]-c[n-1]u[n]}; then set @code{a[0]=c[n-1]=0};
@cindex @code{solve}
@item real[] solve(real[][] a, real[] b, bool warn=true)
Solve the linear equation @math{@code{a}x=@code{b}} by LU decomposition
and return the solution @math{x}, where @code{a} is an
-@math{n \times n} matrix and @code{b} is an array of length @math{n}.
+@math{n \times n} matrix and @code{b} is an array of length @math{n}.
For example:
@verbatim
import math;
@@ -5606,7 +5615,7 @@ write(a*x);
If @code{a} is a singular matrix and @code{warn} is @code{false}, return an
empty array.
If the matrix @code{a} is tridiagonal, the routine @code{tridiagonal} provides
-a more efficient algorithm (@pxref{tridiagonal});
+a more efficient algorithm (@pxref{tridiagonal});
@anchor{solve}
@cindex @code{solve}
@@ -5656,7 +5665,7 @@ real[] b={3,2};
@end verbatim
@noindent
then @code{a == b} and @code{a >= 2} both evaluate to the vector
-@code{@{false, true@}}.
+@code{@{false, true@}}.
@cindex @code{all}
To test whether all components of @code{a} and @code{b} agree,
use the boolean function @code{all(a == b)}. One can also use conditionals like
@@ -5680,7 +5689,7 @@ real[] A=fin;
@cindex line mode
@noindent
reads real values into @code{A} until the end-of-file is reached (or an
-I/O error occurs).
+I/O error occurs).
The virtual members @code{dimension}, @code{line}, @code{csv},
@code{word}, and @code{read} of a file are useful for reading arrays.
@@ -5716,7 +5725,7 @@ real[] A=fin;
@cindex @code{dimension}
To restrict the number of values read, use the @code{file dimension(int)}
-function:
+function:
@verbatim
file fin=input("test.txt");
real[] A=fin.dimension(10);
@@ -5847,13 +5856,13 @@ cells.
@cindex casts
@cindex implicit casts
@cindex @code{explicit}
-
+
@code{Asymptote} implicitly casts @code{int} to @code{real}, @code{int} to
@code{pair}, @code{real} to @code{pair}, @code{pair} to @code{path},
@code{pair} to @code{guide}, @code{path} to @code{guide}, @code{guide}
to @code{path}, @code{real} to @code{pen},
-@code{pair[]} to @code{guide[]}, @code{pair[]} to @code{path[]},
-@code{path} to @code{path[]}, and @code{guide} to @code{path[]},
+@code{pair[]} to @code{guide[]}, @code{pair[]} to @code{path[]},
+@code{path} to @code{path[]}, and @code{guide} to @code{path[]},
along with various three-dimensional casts defined in module @code{three}.
Implicit casts are automatically attempted on assignment and when
trying to match function calls with possible function
@@ -5868,7 +5877,7 @@ write(f(0));
@end verbatim
@cindex explicit casts
-Other conversions, say @code{real} to @code{int} or
+Other conversions, say @code{real} to @code{int} or
@code{real} to @code{string}, require an explicit cast:
@verbatim
int i=(int) 2.5;
@@ -5946,7 +5955,7 @@ would with a structure.
@cindex @code{from}
Often, one wants to use module functions without having to specify
-the module name. The code
+the module name. The code
@verbatim
from graph access axes;
@end verbatim
@@ -5970,21 +5979,21 @@ from graph access *;
Similarly, one can add the non-private fields and types of a structure
to the local environment with the @code{unravel} keyword:
@verbatim
-struct matrix {
- real a,b,c,d;
-}
-
-real det(matrix m) {
- unravel m;
- return a*d-b*c;
-}
+struct matrix {
+ real a,b,c,d;
+}
+
+real det(matrix m) {
+ unravel m;
+ return a*d-b*c;
+}
@end verbatim
Alternatively, one can unravel selective fields:
@verbatim
-real det(matrix m) {
+real det(matrix m) {
from m unravel a,b,c as C,d;
- return a*d-b*C;
-}
+ return a*d-b*C;
+}
@end verbatim
@cindex @code{import}
@@ -6085,11 +6094,11 @@ value, however) contained in the string @code{s} with:
void eval(string s, bool embedded=false);
@end verbatim
It is not necessary to terminate the string @code{s} with a semicolon.
-If @code{embedded} is @code{true}, the string will be evaluated
+If @code{embedded} is @code{true}, the string will be evaluated
at the top level of the current environment.
If @code{embedded} is @code{false} (the default), the string
will be evaluated in an independent environment, sharing the same
-@code{settings} module (@pxref{settings}).
+@code{settings} module (@pxref{settings}).
@cindex @code{quote}
One can evaluate arbitrary @code{Asymptote} code (which may
@@ -6133,7 +6142,7 @@ Imported global functions and variables are also listed if
@section Static
@cindex @code{static}
-Static qualifiers allocate the memory address of a variable in a higher
+Static qualifiers allocate the memory address of a variable in a higher
enclosing level.
For a function body, the variable is allocated in the block where the
@@ -6150,7 +6159,7 @@ struct s {
@noindent
there is one instance of the variable @code{c} for each
-object @code{s} (as opposed to each call of @code{count}).
+object @code{s} (as opposed to each call of @code{count}).
Similarly, in
@verbatim
@@ -6179,7 +6188,7 @@ struct A {
}
@end verbatim
-@noindent
+@noindent
creates one object @code{z} for each object of type @code{A} created.
In this example,
@@ -6327,7 +6336,7 @@ External @code{Asymptote} code can be included with
@end verbatim
@noindent
so that @code{latexmk} will recognize when the code is changed. Note that
-@code{latemk} requires @code{perl}, available from @url{https://www.perl.org/}.
+@code{latemk} requires @code{perl}, available from @url{https://www.perl.org/}.
@cindex @code{width}
@cindex @code{height}
@@ -6346,7 +6355,7 @@ attachments, using the @code{attach} option and the @code{attachfile2}
(or older @code{attachfile}) @code{LaTeX} package.
The @code{inline} option generates
inline @code{LaTeX} code instead of @acronym{EPS} or @acronym{PDF}
-files. This makes 2D LaTeX symbols visible to the
+files. This makes 2D LaTeX symbols visible to the
@code{\begin@{asy@}...\end@{asy@}} environment. In this mode,
Asymptote correctly aligns 2D LaTeX symbols defined outside of
@code{\begin@{asy@}...\end@{asy@}}, but treats their size as zero; an
@@ -6469,29 +6478,29 @@ returns the four complex roots of the quartic equation
@math{ax^4+bx^3+cx^2+dx+e=0}.
@cindex @code{time}
-@item real time(path g, real x, int n=0)
+@item real time(path g, real x, int n=0, real fuzz=-1)
returns the @code{n}th intersection time of path @code{g} with the vertical
line through x.
@cindex @code{time}
-@item real time(path g, explicit pair z, int n=0)
+@item real time(path g, explicit pair z, int n=0, real fuzz=-1)
returns the @code{n}th intersection time of path @code{g} with the horizontal
line through @code{(0,z.y)}.
@cindex @code{value}
-@item real value(path g, real x, int n=0)
+@item real value(path g, real x, int n=0, real fuzz=-1)
returns the @code{n}th @code{y} value of @code{g} at @code{x}.
@cindex @code{value}
-@item real value(path g, explicit pair z, int n=0)
+@item real value(path g, explicit pair z, int n=0, real fuzz=-1)
returns the @code{n}th @code{x} value of @code{g} at @code{y=z.y}.
@cindex @code{slope}
-@item real slope(path g, real x, int n=0)
+@item real slope(path g, real x, int n=0, real fuzz=-1)
returns the @code{n}th slope of @code{g} at @code{x}.
@cindex @code{slope}
-@item real slope(path g, explicit pair z, int n=0)
+@item real slope(path g, explicit pair z, int n=0, real fuzz=-1)
returns the @code{n}th slope of @code{g} at @code{y=z.y}.
@cindex @code{segment}
@@ -6570,7 +6579,7 @@ and @code{leastsquares}.
This module implements @code{PostScript} tiling patterns and includes
several convenient pattern generation routines.
-@node markers, tree, patterns, Base modules
+@node markers, map, patterns, Base modules
@section @code{markers}
@cindex @code{markers}
This module implements specialized routines for marking paths and angles.
@@ -6653,7 +6662,7 @@ write(M.lookup("a"));
write(M.lookup("y"));
@end verbatim
-@node tree, binarytree, markers, Base modules
+@node tree, binarytree, map, Base modules
@section @code{tree}
@cindex @code{tree}
This module implements an example of a dynamic binary search tree.
@@ -6724,7 +6733,7 @@ one must then execute the command @code{texhash}.
The example @code{@uref{https://asymptote.sourceforge.io/gallery/animations/pdfmovie.pdf,,pdfmovie}@uref{https://asymptote.sourceforge.io/gallery/animations/pdfmovie.asy,,.asy}} in the @code{animations}
directory, along with the slide presentations @code{@uref{https://asymptote.sourceforge.io/gallery/animations/slidemovies.pdf,,slidemovies}@uref{https://asymptote.sourceforge.io/gallery/animations/slidemovies.asy,,.asy}}
and @code{@uref{https://asymptote.sourceforge.io/intro.pdf,,intro}}, illustrate the use of embedded @acronym{PDF} movies.
-The examples @code{inlinemovie.tex} and @code{inlinemovie3.tex}
+The examples @code{inlinemovie.tex} and @code{inlinemovie3.tex}
show how to generate and embed @acronym{PDF} movies directly within a
@code{LaTeX} file (@pxref{LaTeX usage}).
The member function
@@ -6743,7 +6752,7 @@ as described here:
@section @code{embed}
@cindex @code{embed}
This module provides an interface to the @code{LaTeX} package
-(included with @code{MikTeX})
+(included with @code{MikTeX})
@quotation
@url{http://mirror.ctan.org/macros/latex/contrib/media9}
@end quotation
@@ -6753,11 +6762,11 @@ for embedding movies, sounds, and 3D objects into a @acronym{PDF} document.
@cindex @code{external}
A more portable method for embedding movie files, which should work on any
platform and does not require the @code{media9} package, is provided
-by using the @code{external} module instead of @code{embed}.
+by using the @code{external} module instead of @code{embed}.
Examples of the above two interfaces is provided in the file
@code{embeddedmovie.asy} in the @code{animations} subdirectory of the
-examples directory and in
+examples directory and in
@code{@uref{https://asymptote.sourceforge.io/gallery/animations/externalmovie.pdf,,externalmovie}@uref{https://asymptote.sourceforge.io/gallery/animations/externalmovie.asy,,.asy}}.
For a higher quality embedded movie generated directly by
@code{Asymptote}, use the @code{animate} module along with the
@@ -6792,7 +6801,7 @@ linear equations and therefore does not have the notion of a
provides a useful replacement for a common use of @code{whatever}: finding the
intersection point of the lines through @code{P}, @code{Q} and
@code{p}, @code{q}. For less common occurrences of @code{whatever}, one
-can use the built-in explicit linear equation solver @code{solve} instead.
+can use the built-in explicit linear equation solver @code{solve} instead.
@node babel, labelpath, MetaPost, Base modules
@section @code{babel}
@@ -6807,7 +6816,7 @@ babel("german");
@node labelpath, labelpath3, babel, Base modules
@section @code{labelpath}
@cindex @code{labelpath}
-This module uses the @code{PSTricks} @code{pstextpath} macro to fit labels
+This module uses the @code{PSTricks} @code{pstextpath} macro to fit labels
along a path (properly kerned, as illustrated in the example file
@code{@uref{https://asymptote.sourceforge.io/gallery/curvedlabel.svg,,curvedlabel}@uref{https://asymptote.sourceforge.io/gallery/curvedlabel.asy,,.asy}}), using the command
@verbatim
@@ -6849,7 +6858,7 @@ Currently, annotations are only implemented for the @code{latex}
@cindex @code{CAD}
This module, contributed by Mark Henning, provides basic pen
definitions and measurement functions for simple 2D CAD drawings
-according to DIN 15. It is documented separately, in the file
+according to DIN 15. It is documented separately, in the file
@code{CAD.pdf}.
@node graph, palette, CAD, Base modules
@@ -6860,7 +6869,7 @@ This module implements two-dimensional linear and logarithmic graphs,
including automatic scale and tick selection (with the ability to
override manually). A graph is a @code{guide} (that can be drawn with
the draw command, with an optional legend) constructed with one of
-the following routines:
+the following routines:
@itemize
@item
@@ -6878,13 +6887,13 @@ Returns a graph using the scaling information for picture @code{pic}
[@code{T}(@code{a}),@code{T}(@code{b})], sampling at @code{n} points
evenly spaced in [@code{a},@code{b}], optionally restricted by the
bool3 function @code{cond} on [@code{a},@code{b}]. If @code{cond} is:
-@itemize @bullet
+@itemize @bullet
@item @code{true}, the point is added to the existing guide;
@item @code{default}, the point is added to a new guide;
@item @code{false}, the point is omitted and a new guide is begun.
@end itemize
The points are connected using the interpolation specified by @code{join}:
-@itemize @bullet
+@itemize @bullet
@cindex @code{operator --}
@cindex @code{Straight}
@@ -6892,7 +6901,7 @@ The points are connected using the interpolation specified by @code{join}:
@code{Straight} is also accepted);
@cindex @code{operator ..}
-@cindex @code{Spline}
+@cindex @code{Spline}
@item @code{operator ..} (piecewise Bezier cubic spline interpolation;
the abbreviation @code{Spline} is also accepted);
@@ -6982,7 +6991,7 @@ guide polargraph(picture pic=currentpicture, real f(real), real a,
@end verbatim
Returns a polar-coordinate graph using the scaling information for
-picture @code{pic} of the function @code{f} on the interval
+picture @code{pic} of the function @code{f} on the interval
[@code{a},@code{b}], sampling at @code{n} evenly spaced points, with
the given interpolation type.
@@ -7009,7 +7018,7 @@ An axis can be drawn on a picture with one of the following commands:
@item
@verbatim
void xaxis(picture pic=currentpicture, Label L="", axis axis=YZero,
- real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
ticks ticks=NoTicks, arrowbar arrow=None, bool above=false);
@end verbatim
@@ -7019,7 +7028,7 @@ Label @code{L}. The relative label location along the axis (a real number from
[0,1]) defaults to 1 (@pxref{Label}), so that the label is drawn at the
end of the axis. An infinite value of @code{xmin}
or @code{xmax} specifies that the corresponding axis limit will be
-automatically determined from the picture limits.
+automatically determined from the picture limits.
The optional @code{arrow} argument takes the same values as in the
@code{draw} command (@pxref{arrows}). The axis is drawn before any
existing objects in @code{pic} unless @code{above=true}.
@@ -7079,10 +7088,10 @@ YZero=YZero();
@cindex @code{LeftTicks}
@cindex @code{RightTicks}
@cindex @code{Ticks}
-The default tick option is @code{NoTicks}.
+The default tick option is @code{NoTicks}.
The options @code{LeftTicks}, @code{RightTicks}, or @code{Ticks} can be
used to draw ticks on the left, right, or both sides of the path,
-relative to the direction in which the path is drawn.
+relative to the direction in which the path is drawn.
These tick routines accept a number of optional arguments:
@verbatim
ticks LeftTicks(Label format="", ticklabel ticklabel=null,
@@ -7167,8 +7176,8 @@ It is also possible to specify custom tick locations with
arrays @code{Ticks} and (optionally) @code{ticks} containing the
locations of the major and minor ticks, respectively:
@verbatim
-ticks LeftTicks(Label format="", ticklabel ticklabel=null,
- bool beginlabel=true, bool endlabel=true,
+ticks LeftTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
real[] Ticks, real[] ticks=new real[],
real Size=0, real size=0, bool extend=false,
pen pTick=nullpen, pen ptick=nullpen)
@@ -7188,7 +7197,7 @@ a Label @code{L} that is autorotated unless @code{autorotate=false}.
The relative location of the label (a real number from
[0,1]) defaults to 1 (@pxref{Label}). An infinite value of @code{ymin}
or @code{ymax} specifies that the corresponding axis limit will be
-automatically determined from the picture limits.
+automatically determined from the picture limits.
The optional @code{arrow} argument takes the same values as in the
@code{draw} command (@pxref{arrows}). The axis is drawn before any
existing objects in @code{pic} unless @code{above=true}.
@@ -7212,11 +7221,11 @@ dimensions of the picture, unless @code{extend}=false.
Request a left axis.
@cindex @code{Right}
-@item Right(bool extend=false)
+@item Right(bool extend=false)
Request a right axis.
@cindex @code{LeftRight}
-@item LeftRight(bool extend=false)
+@item LeftRight(bool extend=false)
Request a left and right axis.
@end table
@@ -7224,7 +7233,7 @@ Request a left and right axis.
@item
@cindex @code{xequals}
@cindex @code{yequals}
-For convenience, the functions
+For convenience, the functions
@verbatim
void xequals(picture pic=currentpicture, Label L="", real x,
bool extend=false, real ymin=-infinity, real ymax=infinity,
@@ -7241,16 +7250,16 @@ void yequals(picture pic=currentpicture, Label L="", real y,
can be respectively used to call @code{yaxis} and
@code{xaxis} with the appropriate axis types @code{XEquals(x,extend)} and
@code{YEquals(y,extend)}. This is the recommended way of drawing vertical
-or horizontal lines and axes at arbitrary locations.
+or horizontal lines and axes at arbitrary locations.
@item
-@verbatim
+@verbatim
void axes(picture pic=currentpicture, Label xlabel="", Label ylabel="",
bool extend=true,
pair min=(-infinity,-infinity), pair max=(infinity,infinity),
pen p=currentpen, arrowbar arrow=None, bool above=false);
@end verbatim
-This convenience routine draws both @math{x} and @math{y} axes
+This convenience routine draws both @math{x} and @math{y} axes
on picture @code{pic} from @code{min} to @code{max},
with optional labels @code{xlabel} and @code{ylabel}
and any arrows specified by @code{arrow}. The axes are drawn on top of
@@ -7265,9 +7274,9 @@ void axis(picture pic=currentpicture, Label L="", path g,
@end verbatim
This routine can be used to draw on picture @code{pic} a general axis
-based on an arbitrary path @code{g}, using pen @code{p}.
+based on an arbitrary path @code{g}, using pen @code{p}.
One can optionally label the axis with Label @code{L} and add an arrow
-@code{arrow}. The tick type is given by @code{ticks}.
+@code{arrow}. The tick type is given by @code{ticks}.
The optional integer array @code{divisor} specifies what tick divisors
to try in the attempt to produce uncrowded tick labels. A @code{true}
value for the flag @code{opposite} identifies an unlabelled secondary
@@ -7387,7 +7396,7 @@ the tick labels on the @math{y} axis.
using frame alignment and data markers. In the left-hand graph, the
markers, constructed with
@verbatim
-marker marker(path g, markroutine markroutine=marknodes,
+marker marker(path g, markroutine markroutine=marknodes,
pen p=currentpen, filltype filltype=NoFill,
bool above=true);
@end verbatim
@@ -7398,12 +7407,12 @@ below each node. Any frame can be converted to a marker, using
marker marker(frame f, markroutine markroutine=marknodes,
bool above=true);
@end verbatim
-In the right-hand graph, the unit @math{n}-sided regular polygon
-@code{polygon(int n)} and the unit @math{n}-point cyclic cross
+In the right-hand graph, the unit @math{n}-sided regular polygon
+@code{polygon(int n)} and the unit @math{n}-point cyclic cross
@code{cross(int n, bool round=true, real r=0)} (where @code{r} is an
optional ``inner'' radius) are used to build a custom marker frame.
@anchor{markuniform}
-Here @code{markuniform(bool centered=false, int n, bool rotated=false)}
+Here @code{markuniform(bool centered=false, int n, bool rotated=false)}
adds this frame at @code{n} uniformly spaced points along the arclength
of the path, optionally rotated by the angle of the local tangent to the path
(if centered is true, the frames will be centered within @code{n} evenly
@@ -7420,13 +7429,13 @@ marker[] Mark={
marker(scale(circlescale)*unitcircle),
marker(polygon(3)),marker(polygon(4)),
marker(polygon(5)),marker(invert*polygon(3)),
- marker(cross(4)),marker(cross(6))
+ marker(cross(4)),marker(cross(6)),marker(diamond),marker(plus);
};
marker[] MarkFill={
marker(scale(circlescale)*unitcircle,Fill),marker(polygon(3),Fill),
marker(polygon(4),Fill),marker(polygon(5),Fill),
- marker(invert*polygon(3),Fill)
+ marker(invert*polygon(3),Fill),marker(diamond,Fill)
};
@end verbatim
@@ -7464,25 +7473,25 @@ positive and negative extents of the error are assumed to be equal.
@sp 1
@center @image{./monthaxis}
-@item The next example draws a graph of a parametrized curve.
+@item The next example draws a graph of a parametrized curve.
@cindex parametrized curve
@cindex cropping graphs
@cindex @code{xlimits}
@cindex @code{ylimits}
@cindex @code{limits}
@cindex @code{crop}
-The calls to
+The calls to
@verbatim
xlimits(picture pic=currentpicture, real min=-infinity,
real max=infinity, bool crop=NoCrop);
-@end verbatim
+@end verbatim
@noindent
and the analogous function @code{ylimits} can be uncommented
to set the respective axes limits for picture @code{pic} to the
specified @code{min} and @code{max} values. Alternatively, the function
@verbatim
void limits(picture pic=currentpicture, pair min, pair max, bool crop=NoCrop);
-@end verbatim
+@end verbatim
can be used to limit the axes to the box having opposite vertices at
the given pairs). Existing objects in picture @code{pic} will be cropped to lie
within the given limits if @code{crop}=@code{Crop}. The function
@@ -7492,6 +7501,19 @@ graph limits.
@sp 1
@center @image{./parametricgraph}
+@cindex @code{graphwithderiv}
+The function
+@verbatim
+guide graphwithderiv(pair f(real), pair fprime(real), real a, real b,
+ int n=ngraph#10);
+@end verbatim
+can be used to construct the graph of the parametric function @code{f}
+on @code{[a,b]} with the control points of the @code{n} Bezier
+segments determined by the specified derivative @code{fprime}:
+@verbatiminclude graphwithderiv.asy
+@sp 1
+@center @image{./graphwithderiv}
+
@cindex scaled graph
The next example illustrates how one can extract a common axis scaling
factor.
@@ -7607,7 +7629,7 @@ A secondary logarithmic @math{y} axis can be drawn like this:
@center @image{./histogram}
@item Here is an example of reading column data in from a file and a
-least-squares fit, using the @code{stats} module.
+least-squares fit, using the @code{stats} module.
@cindex @code{leastsquares}
@verbatiminclude leastsquares.asy
@sp 1
@@ -7691,7 +7713,7 @@ a linearly scaled intensity.
a full color wheel palette;
@cindex @code{Gradient}
-@item pen[] Gradient(int NColors=256 ... pen[] p)
+@item pen[] Gradient(int NColors=256 ... pen[] p)
a palette varying linearly over the specified array of pens, using
NColors in each interpolation interval;
@@ -7729,7 +7751,7 @@ the argument @code{range}, which can be @code{Full}, @code{Automatic},
or an explicit range @code{Range(real min, real max)}.
Here @code{Full} specifies a range varying from the
minimum to maximum values of the function over the sampling interval,
-while @code{Automatic} selects "nice" limits.
+while @code{Automatic} selects "nice" limits.
The example @code{@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/imagecontour.svg,,imagecontour}@uref{https://asymptote.sourceforge.io/gallery/2Dgraphs/imagecontour.asy,,.asy}} illustrates how level sets
(contour lines) can be drawn on a color density plot (@pxref{contour}).
@@ -7859,7 +7881,7 @@ and then distorted into a saddle:
@noindent
Module @code{three} provides constructors for converting two-dimensional
-paths to three-dimensional ones, and vice-versa:
+paths to three-dimensional ones, and vice-versa:
@cindex @code{path3}
@cindex @code{path}
@verbatim
@@ -7906,7 +7928,7 @@ Here material is a structure defined in @code{three_light.asy}:
struct material {
pen[] p; // diffusepen,emissivepen,specularpen
real opacity;
- real shininess;
+ real shininess;
real metallic;
real fresnel0;
}
@@ -7960,16 +7982,32 @@ other formats. One can request a completely transparent background for
3D @code{WebGL} images with
@code{currentlight.background=black+opacity(0.0);}
+@cindex image-based lighting
+@cindex @code{surface}
+@cindex @code{ibl}
+Asymptote also supports image-based lighting with the setting
+@code{settings.ibl=true}. This uses pre-rendered @acronym{EXR} images from
+the directory specified by @code{-imageDir} (which defaults to @code{ibl})
+or, for @code{WebGL} rendering, the @acronym{URL} specified by
+@code{-imageURL} (which defaults to
+@url{https://vectorgraphics.gitlab.io/asymptote/ibl}).
+Additional rendered images can be generated on an @code{NVIDIA} @acronym{GPU}
+using the @code{reflect} program in the @code{cudareflect} subdirectory
+of the @code{Asymptote} source directory.
+
Sample Bezier surfaces are
contained in the example files @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/BezierSurface.html,,BezierSurface}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/BezierSurface.asy,,.asy}}, @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/teapot.html,,teapot}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/teapot.asy,,.asy}},
-and @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.html,,parametricsurface}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.asy,,.asy}}. The structure @code{render} contains
-specialized rendering options documented at the beginning of module
-@code{three}.
+@code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/teapotIBL.html,,teapotIBL}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/teapotIBL.asy,,.asy}},
+and
+@code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.html,,parametricsurface}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/parametricsurface.asy,,.asy}}.
+
+The structure @code{render} contains specialized rendering options
+documented at the beginning of module @code{three}.
@cindex patch-dependent colors
@cindex vertex-dependent colors
The examples
-@code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/elevation.html,,elevation}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/elevation.asy,,.asy}} and @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/sphericalharmonic.html,,sphericalharmonic}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/sphericalharmonic.asy,,.asy}}
+@code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/elevation.html,,elevation}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/elevation.asy,,.asy}} and @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/sphericalharmonic.html,,sphericalharmonic}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/sphericalharmonic.asy,,.asy}}
illustrate how to draw a surface with patch-dependent colors.
The examples @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/vertexshading.html,,vertexshading}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/vertexshading.asy,,.asy}} and @code{@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/smoothelevation.html,,smoothelevation}@uref{https://asymptote.sourceforge.io/gallery/3Dgraphs/smoothelevation.asy,,.asy}} illustrate
vertex-dependent colors, which are supported by
@@ -8021,7 +8059,7 @@ into subregions bounded by cyclic paths of length @code{4} or less.
A more efficient routine also exists for drawing tessellations
composed of many 3D triangles, with specified vertices, and optional
-normals or vertex colors:
+normals or vertex colors:
@cindex @code{draw}
@cindex @code{triangles}
@cindex @code{tessellation}
@@ -8049,7 +8087,7 @@ constructed with
tube tube(path3 p, real width, render render=defaultrender);
@end verbatim
@noindent
-this returns a tube structure representing a tube of diameter @code{width}
+this returns a tube structure representing a tube of diameter @code{width}
centered approximately on @code{g}. The tube structure consists of a
surface @code{s} and the actual tube center, path3 @code{center}.
Drawing thick lines as tubes can be slow to render,
@@ -8060,10 +8098,10 @@ of the resolution). By default, mesh and contour lines in three-dimensions
are always drawn thin, unless an explicit line width is given in the pen
parameter or the setting @code{thin} is set to @code{false}. The pens
@code{thin()} and @code{thick()} defined in @code{plain_pens.asy} can
-also be used to override these defaults for specific draw commands.
+also be used to override these defaults for specific draw commands.
@noindent
-There are five choices for viewing 3D @code{Asymptote} output:
+There are six choices for viewing 3D @code{Asymptote} output:
@enumerate
@cindex @code{OpenGL}
@@ -8133,17 +8171,15 @@ The keyboard shortcuts are:
@cindex @code{mobile browser}
@item Generate @code{WebGL} interactive vector graphics
output with the the command-line option and @code{-f html}
-(or the setting @code{outformat="html"}). The resulting
+(or the setting @code{outformat="html"}). The resulting
3D @acronym{HTML} file can then be viewed directly in any modern desktop or
mobile browser, or even embedded within another web page:
@verbatim
-<div>
-<object data="logo3.html"
- style="width:210;height:140;position:relative;top:0;left:0;">
-</object>
-</div>
+<iframe src="logo3.html" width="210" height="140" frameborder="0">
+</iframe>
@end verbatim
+@cindex @code{absolute}
Normally, @code{WebGL} files generated by @code{Asymptote} are
dynamically remeshed to fit the browser window dimensions.
However, the setting @code{absolute=true} can be used to force the image to be
@@ -8185,22 +8221,22 @@ generates unwanted black stripes in the output, try setting the
horizontal and vertical components of @code{maxtiles} to something
less than your screen dimensions. The tile size is also limited by the
setting @code{maxviewport}, which restricts the maximum width and
-height of the viewport. On @code{UNIX} systems some graphics
-drivers support batch mode (@code{-noV}) rendering in an
-iconified window; this can be enabled with the setting @code{iconify=true}.
+height of the viewport. Some graphics drivers support batch mode
+(@code{-noV}) rendering in an iconified window; this can be enabled
+with the setting @code{iconify=true}.
@cindex @code{prc}
@cindex @code{views}
@item Embed the 3D @acronym{PRC} format in a @acronym{PDF} file
and view the resulting @acronym{PDF} file with
-version @code{9.0} or later of @code{Adobe Reader}.
-In addition to the default @code{settings.prc=true}, this requires
-@code{settings.outformat="pdf"}, which can be specified by the command
-line option @code{-f pdf}, put in the @code{Asymptote} configuration
+version @code{9.0} or later of @code{Adobe Reader}.
+This requires @code{settings.outformat="pdf"} and @code{settings.prc=true},
+which can be specified by the command-line options @code{-f pdf}
+and @code{-f prc}, put in the @code{Asymptote} configuration
file (@pxref{configuration file}), or specified in the script before
module @code{three} (or @code{graph3}) is imported.
The @code{media9} LaTeX package is also required (@pxref{embed}).
-The example @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/100d.html,,100d}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/pdb.asy,,.asy}} illustrates
+The example @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/100d.html,,100d}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/pdb.asy,,.asy}} illustrates
how one can generate a list of predefined views (see @code{100d.views}).
A stationary preview image with a resolution of @code{n} pixels per
@code{bp} can be embedded with the setting @code{render=n}; this allows
@@ -8214,10 +8250,23 @@ required, specify @code{settings.outformat="prc"}.
The @acronym{PRC} specification is available from
@url{https://web.archive.org/web/20081204104459/http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/API_References/PRCReference/PRC_Format_Specification/}
+@cindex @code{v3d}
+@item Output a @code{V3D} portable compressed binary file for viewing with an
+external viewer or conversion to an alternate 3D format with the Python
+@code{pyv3d} library. The @code{V3D} specification and the
+@code{pyv3d} library are available at
+@url{https://gitlab.com/vectorgraphics/v3d}.
+A @code{V3D} file @code{file.v3d} may be imported and viewed by
+Asymptote with the @code{v3d} module:
+@verbatim
+import v3d;
+importv3d("file.v3d");
+@end verbatim
+
@item Project the scene to a two-dimensional vector (@acronym{EPS} or
-@acronym{PDF}) format with @code{render=0}. Only limited hidden surface
-removal facilities are currently available with this approach
-(@pxref{PostScript3D}).
+@acronym{PDF}) format with @code{render=0}. Only limited support for
+hidden surface removal, lighting, and transparency is available with
+this approach (@pxref{PostScript3D}).
@end enumerate
@@ -8235,7 +8284,7 @@ void size3(picture pic=currentpicture, real x, real y=x, real z=y,
@cindex @code{viewportmargin}
@cindex @code{viewportsize}
A simplex linear programming problem is then solved to
-produce a 3D version of a frame (actually implemented as a 3D picture).
+produce a 3D version of a frame (actually implemented as a 3D picture).
The result is then fit with another application of deferred drawing
to the viewport dimensions corresponding to the usual two-dimensional
picture @code{size} parameters. The global pair @code{viewportmargin}
@@ -8321,7 +8370,7 @@ path3[] unitbox=box(O,(1,1,1));
three-dimensional paths @code{unitsquare3} and @code{unitcircle3},
along with the surfaces @code{unitdisk}, @code{unitplane}, @code{unitcube},
@code{unitcylinder}, @code{unitcone}, @code{unitsolidcone},
-@code{unitfrustum(real t1, real t2)}, @code{unitsphere}, and
+@code{unitfrustum(real t1, real t2)}, @code{unitsphere}, and
@code{unithemisphere}.
@noindent
@@ -8361,23 +8410,23 @@ infinitely far away in the direction @code{unit(camera)}, orienting the camera
so that, if possible, the vector @code{up} points upwards. Parallel
lines are projected to parallel lines. The bounding volume is expanded
to include @code{target} if @code{showtarget=true}.
-If @code{center=true}, the target will be adjusted to the center of the
-bounding volume.
+If @code{center=true}, the target will be adjusted to the center of the
+bounding volume.
@item orthographic(real x, real y, real z, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ @ real zoom=1, pair viewportshift=0, bool showtarget=true, @*@ @ @ @ @ @ @ @ @ @ @ @ @ bool center=false)
-This is equivalent to
-@verbatim
+This is equivalent to
+@verbatim
orthographic((x,y,z),up,target,zoom,viewportshift,showtarget,center)
@end verbatim
The routine
@cindex @code{camera}
-@verbatim
+@verbatim
triple camera(real alpha, real beta);
@end verbatim
can be used to compute the camera position with the @math{x} axis below
the horizontal at angle @code{alpha}, the @math{y} axis below the horizontal
-at angle @code{beta}, and the @math{z} axis up.
+at angle @code{beta}, and the @math{z} axis up.
@cindex @code{autoadjust}
@item perspective(triple camera, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ real zoom=1, real angle=0, pair viewportshift=0, @*@ @ @ @ @ @ @ @ @ @ @ @ bool showtarget=true, bool autoadjust=true, @*@ @ @ @ @ @ @ @ @ @ @ @ bool center=autoadjust)
@@ -8386,18 +8435,15 @@ at angle @code{beta}, and the @math{z} axis up.
This projects from three to two dimensions, taking account of
perspective, as seen from the location @code{camera} looking at @code{target},
orienting the camera so that, if possible, the vector @code{up} points upwards.
-If @code{render=0}, projection of three-dimensional cubic Bezier splines
-is implemented by approximating a two-dimensional nonuniform rational B-spline
-(@acronym{NURBS}) with a two-dimensional Bezier curve containing
-additional nodes and control points. If @code{autoadjust=true},
+If @code{autoadjust=true},
the camera will automatically be adjusted to lie outside the bounding volume
for all possible interactive rotations about @code{target}.
-If @code{center=true}, the target will be adjusted to the center of the
-bounding volume.
+If @code{center=true}, the target will be adjusted to the center of the
+bounding volume.
@item perspective(real x, real y, real z, triple up=Z, triple target=O, @*@ @ @ @ @ @ @ @ @ @ @ @ real zoom=1, real angle=0, pair viewportshift=0, @*@ @ @ @ @ @ @ @ @ @ @ @ bool showtarget=true, bool autoadjust=true, @*@ @ @ @ @ @ @ @ @ @ @ @ bool center=autoadjust)
-This is equivalent to
-@verbatim
+This is equivalent to
+@verbatim
perspective((x,y,z),up,target,zoom,angle,viewportshift,showtarget,
autoadjust,center)
@end verbatim
@@ -8436,7 +8482,7 @@ adds to picture @code{dest} an array of views of picture @code{src}
using the layout projection[][] @code{views}. The default layout
@code{SixViewsUS} aligns the projection @code{FrontView} below
@code{TopView} and above @code{BottomView}, to the right of
-@code{LeftView} and left of @code{RightView} and @code{BackView}.
+@code{LeftView} and left of @code{RightView} and @code{BackView}.
The predefined layouts are:
@cindex @code{ThreeViewsUS}
@cindex @code{SixViewsUS}
@@ -8472,7 +8518,7 @@ with @code{project(triple, projection P=currentprojection)} or
It is occasionally useful to be able to invert a projection, sending
a pair @code{z} onto the plane perpendicular to @code{normal} and passing
-through @code{point}:
+through @code{point}:
@cindex @code{invert}
@verbatim
triple invert(pair z, triple normal, triple point,
@@ -8480,7 +8526,7 @@ triple invert(pair z, triple normal, triple point,
@end verbatim
@noindent
A pair @code{z} on the projection plane can be inverted to a triple
-with the routine
+with the routine
@verbatim
triple invert(pair z, projection P=currentprojection);
@end verbatim
@@ -8514,7 +8560,7 @@ scales by @code{z} in the @math{z} direction;
scales by @code{s} in the @math{x}, @math{y}, and @math{z} directions;
@item scale(real x, real y, real z)
@cindex @code{scale}
-scales by @code{x} in the @math{x} direction,
+scales by @code{x} in the @math{x} direction,
by @code{y} in the @math{y} direction, and by @code{z} in the @math{z}
direction;
@cindex @code{rotate}
@@ -8589,7 +8635,7 @@ surface extrude(path p, triple axis=Z);
surface extrude(Label L, triple axis=Z);
@end verbatim
@noindent
-return the surface obtained by extruding path @code{p} or
+return the surface obtained by extruding path @code{p} or
Label @code{L} along @code{axis}.
@cindex @code{length}
@@ -8618,7 +8664,7 @@ Three-dimensional versions of the path functions @code{length},
@code{arclength}, @code{arctime}, @code{reverse}, @code{subpath},
@code{intersect}, @code{intersections}, @code{intersectionpoint},
@code{intersectionpoints}, @code{min}, @code{max}, @code{cyclic}, and
-@code{straight} are also defined.
+@code{straight} are also defined.
The routine
@cindex @code{intersections}
@@ -8635,7 +8681,7 @@ real[][] intersections(path3 p, surface s, real fuzz=-1);
@noindent
returns all (unless there are infinitely many) intersection times of a
path @code{p} with a surface @code{s} as a sorted array of real arrays
-of length 3, and
+of length 3, and
@cindex @code{intersectionpoints}
@verbatim
triple[] intersectionpoints(path3 p, surface s, real fuzz=-1);
@@ -8661,7 +8707,7 @@ which is the determinant
The result is negative (positive) if @code{a}, @code{b}, @code{c} appear in
counterclockwise (clockwise) order when viewed from @code{d} or zero
if all four points are coplanar.
-
+
The routine
@cindex @code{insphere}
@verbatim
@@ -8704,7 +8750,7 @@ Here is an example showing all five guide3 connectors:
@cindex @code{HookHead3}
@cindex @code{TeXHead3}
Three-dimensional versions of bars or arrows can be drawn with one of
-the specifiers @code{None}, @code{Blank},
+the specifiers @code{None}, @code{Blank},
@code{BeginBar3}, @code{EndBar3} (or equivalently @code{Bar3}), @code{Bars3},
@code{BeginArrow3}, @code{MidArrow3},
@code{EndArrow3} (or equivalently @code{Arrow3}), @code{Arrows3},
@@ -8720,7 +8766,7 @@ space and aligned according to the initial viewpoint (or an optionally
specified @code{normal} vector) are also defined:
@code{DefaultHead2(triple normal=O)}, @code{HookHead2(triple normal=O)},
@code{TeXHead2(triple normal=O)}. These are illustrated in the example
-@code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/arrows3.html,,arrows3}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/arrows3.asy,,.asy}}.
+@code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/arrows3.html,,arrows3}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/arrows3.asy,,.asy}}.
@cindex @code{NoMargin3}
@cindex @code{BeginMargin3}
@@ -8782,7 +8828,7 @@ implemented using a binary space partition and picture clipping.
A planar path is first converted to a structure @code{face} derived from
@code{picture}. A @code{face} may be given to a two-dimensional drawing
routine in place of any @code{picture} argument. An array of such faces
-may then be drawn, removing hidden surfaces:
+may then be drawn, removing hidden surfaces:
@verbatim
void add(picture pic=currentpicture, face[] faces,
projection P=currentprojection);
@@ -8831,7 +8877,7 @@ Analogous routines @code{yaxis} and @code{zaxis} can be used to draw
There is also a routine for drawing all three axis:
@verbatim
void axes3(picture pic=currentpicture,
- Label xlabel="", Label ylabel="", Label zlabel="",
+ Label xlabel="", Label ylabel="", Label zlabel="",
bool extend=false,
triple min=(-infinity,-infinity,-infinity),
triple max=(infinity,infinity,infinity),
@@ -8895,7 +8941,7 @@ One can also place ticks along a general three-dimensional axis:
@cindex @code{Spline}
@cindex parametric surface
Surface plots of matrices and functions over the region
-@code{box(a,b)} in the @math{XY} plane are also implemented:
+@code{box(a,b)} in the @math{XY} plane are also implemented:
@verbatim
surface surface(real[][] f, pair a, pair b, bool[][] cond={});
surface surface(real[][] f, pair a, pair b, splinetype xsplinetype,
@@ -8958,7 +9004,7 @@ as illustrated in the examples @code{@uref{https://asymptote.sourceforge.io/gall
This module, contributed by Philippe Ivaldi, can be used for drawing
3D grids. Here is an example (further examples can be found in
-@code{grid3.asy} and at @url{http://www.piprime.fr/files/asymptote/grid3/}):
+@code{grid3.asy} and at @url{http://www.piprime.fr/files/asymptote/grid3/}):
@verbatiminclude grid3xyz.asy
@sp 1
@center @image{./grid3xyz}
@@ -9009,7 +9055,7 @@ applying the transformation @code{T(t)} at @code{point(g,t)}.
The parameter @code{corner} controls the number of elementary tubes at
the angular points of @code{g}. A nonzero value of @code{relstep}
specifies a fixed relative time step (in the sense of
-@code{relpoint(g,t)}) to use in constructing elementary tubes along @code{g}.
+@code{relpoint(g,t)}) to use in constructing elementary tubes along @code{g}.
The type @code{coloredpath} is a generalization of @code{path} to
which a @code{path} can be cast:
@cindex @code{coloredpath}
@@ -9098,14 +9144,14 @@ is given by @code{block.size}.
A frame containing the block is returned by
@verbatim
frame block.draw(pen p=currentpen);
-@end verbatim
+@end verbatim
@cindex @code{block.draw}
The following block generation routines accept a Label, string, or
frame for their object argument:
@table @dfn
-@item rectangular block with an optional header (and padding @code{dx} around header and body):
+@item rectangular block with an optional header (and padding @code{dx} around header and body):
@cindex @code{rectangle}
@verbatim
block rectangle(object header, object body, pair center=(0,0),
@@ -9164,7 +9210,7 @@ block roundrectangle(object body, pair center=(0,0),
block bevel(object body, pair center=(0,0), pen fillpen=invisible,
pen drawpen=currentpen, real dh=5, real dw=5,
real minwidth=minblockwidth, real minheight=minblockheight);
-@end verbatim
+@end verbatim
@end table
@@ -9229,7 +9275,7 @@ To construct contours for an array of values @code{f} specified at
irregularly positioned points @code{z}, use the routine
@verbatim
guide[][] contour(pair[] z, real[] f, real[] c, interpolate join=operator --);
-@end verbatim
+@end verbatim
@noindent
The contours themselves can be drawn with one of the routines
@verbatim
@@ -9295,20 +9341,20 @@ Its usage is illustrated in the example file @code{@uref{https://asymptote.sourc
@cindex @code{smoothcontour3}
This module, written by Charles Staats, draws implicitly defined surfaces
with smooth appearance.
-The purpose of this module is similar to that of @code{contour3}: given
-a real-valued function @math{f(x,y,z)}, construct the surface described by
-the equation @math{f(x,y,z) = 0}. The @code{smoothcontour3} module generally produces
-nicer results than @code{contour3}, but takes longer to compile. Additionally, the
+The purpose of this module is similar to that of @code{contour3}: given
+a real-valued function @math{f(x,y,z)}, construct the surface described by
+the equation @math{f(x,y,z) = 0}. The @code{smoothcontour3} module generally produces
+nicer results than @code{contour3}, but takes longer to compile. Additionally, the
algorithm assumes that the function and the surface are both smooth; if they are not,
then @code{contour3} may be a better choice.
To construct the null surface of a function @code{f(triple)} or @code{ff(real,real,real)}
over @code{box(a,b)}, use the routine
-@cindex @code{implicitsurface}
+@cindex @code{implicitsurface}
@verbatim
-surface implicitsurface(real f(triple)=null,
+surface implicitsurface(real f(triple)=null,
real ff(real,real,real)=null,
- triple a,
+ triple a,
triple b,
int n=nmesh,
bool keyword overlapedges=false,
@@ -9324,7 +9370,7 @@ an artifact that can cause the renderer to ``see through'' the
boundary between patches. Although
it defaults to @code{false}, it should usually be set to @code{true}.
The example @code{@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/genustwo.html,,genustwo}@uref{https://asymptote.sourceforge.io/gallery/3Dwebgl/genustwo.asy,,.asy}} illustrates the use of this function.
-Additional examples, together with a more in-depth explanation of
+Additional examples, together with a more in-depth explanation of
the module's usage and pitfalls, are available at
@url{https://github.com/charlesstaats/smoothcontour3}.
@@ -9335,7 +9381,7 @@ To draw a slope field for the differential equation @math{dy/dx=f(x,y)} (or
@math{dy/dx=f(x)}), use:
@verbatim
picture slopefield(real f(real,real), pair a, pair b,
- int nx=nmesh, int ny=nx,
+ int nx=nmesh, int ny=nx,
real tickfactor=0.5, pen p=currentpen,
arrowbar arrow=None);
@end verbatim
@@ -9358,7 +9404,7 @@ path curve(pair c, real f(real,real), pair a, pair b);
takes a point (@code{c}) and a slope field-defining function @code{f}
and returns, as a path, the curve passing through that point. The points
@code{a} and @code{b} represent the rectangular boundaries over which
-the curve is interpolated.
+the curve is interpolated.
Both @code{slopefield} and @code{curve} alternatively accept a function
@code{real f(real)} that depends on @math{x} only, as seen in this example:
@@ -9422,7 +9468,7 @@ batchMask=false;
interactiveMask=true;
@end verbatim
Command-line options override these defaults. Most configuration
-variables may also be changed at runtime.
+variables may also be changed at runtime.
@cindex @code{dvipsOptions}
@cindex @code{hyperrefOptions}
@cindex @code{convertOptions}
@@ -9450,7 +9496,7 @@ settings.autoplain=true;
@noindent
at the beginning of the configuration file, it can contain arbitrary
@code{Asymptote} code.
-
+
@cindex @code{convert}
@cindex @code{output}
@cindex @code{format}
@@ -9473,7 +9519,7 @@ The default output format is @acronym{EPS} for the (default)
@code{latex} and @code{tex} tex engine and @acronym{PDF} for the
@code{pdflatex}, @code{xelatex}, @code{context}, @code{luatex}, and
@code{lualatex} tex engines. Alternative output formats may be
-produced using the @code{-f} option (or @code{outformat} setting).
+produced using the @code{-f} option (or @code{outformat} setting).
@cindex @code{SVG}
@cindex @code{dvisvgm}
@@ -9511,7 +9557,7 @@ asy -o - venn | convert -alpha Off -density 144x144 -geometry 50%x eps:- venn.ti
@cindex @code{safe}
@cindex @code{system}
If the option @code{-nosafe} is given, @code{Asymptote} runs
-in unsafe mode. This enables the @code{int system(string s)} and
+in unsafe mode. This enables the @code{int system(string s)} and
@code{int system(string[] s)} calls, allowing one
to execute arbitrary shell commands. The default mode, @code{-safe},
disables this call.
@@ -9535,7 +9581,7 @@ The @code{-c} (@code{command}) option may be used to execute arbitrary
necessary to terminate the string with a semicolon. Multiple @code{-c}
options are executed in the order they are given. For example
@verbatim
-asy -c 2+2 -c "sin(1)" -c "size(100); draw(unitsquare)"
+asy -c 2+2 -c "sin(1)" -c "size(100); draw(unitsquare)"
@end verbatim
@noindent
produces the output
@@ -9550,7 +9596,7 @@ and draws a unitsquare of size @code{100}.
The @code{-u} (@code{user}) option may be used to specify arbitrary
@code{Asymptote} settings on the command line as a string. It is not
necessary to terminate the string with a semicolon. Multiple @code{-u}
-options are executed in the order they are given. Command-line code like
+options are executed in the order they are given. Command-line code like
@code{-u x=sqrt(2)} can be executed within a module like this:
@verbatim
real x;
@@ -9611,7 +9657,7 @@ instead. In either case, the expression can be referred to using the symbol
> currentpicture
<picture currentpicture>
> %.size(200,0)
->
+>
@end verbatim
@cindex @code{operator answer}
@@ -9636,7 +9682,7 @@ changes to the settings module (@pxref{settings}), the current directory
(@pxref{cd}), and breakpoints (@pxref{Debugger});
@cindex @code{input}
@item input FILE
-does an interactive reset, followed by the command
+does an interactive reset, followed by the command
@code{include FILE}. If the file name @code{FILE} contains
nonalphanumeric characters, enclose it with quotation marks.
A trailing semi-colon followed by optional @code{Asymptote} commands may
@@ -9671,7 +9717,7 @@ The file @code{asymptote.py} in the @code{Asymptote} system directory
provides an alternative way of entering @code{Asymptote} commands
interactively, coupled with the full power of @code{Python}. Copy this
file to your @code{Python path} and then execute from within
-@code{Python 3} the commands
+@code{Python 3} the commands
@verbatim
from asymptote import *
g=asy()
@@ -9683,7 +9729,7 @@ g.clip("unitcircle")
g.label("\"$O$\", (0,0), SW")
@end verbatim
-@node GUI, PostScript to Asymptote, Interactive mode, Top
+@node GUI, Command-Line Interface, Interactive mode, Top
@chapter Graphical User Interface
@cindex graphical user interface
@cindex @acronym{GUI}
@@ -9739,7 +9785,7 @@ the alt or shift keys is held and zoom while the control key is held.
In translate mode, an object can be dragged coarsely with the mouse
or positioned finely with the arrow keys while holding down the mouse button.
-Deconstruction of compound objects (such as arrows) can be prevented
+Deconstruction of compound objects (such as arrows) can be prevented
by enclosing them within the commands
@verbatim
void begingroup(picture pic=currentpicture);
@@ -9750,10 +9796,105 @@ together on adding them to a picture. However, the elements of a frame
added to another frame are not grouped together by default: their
elements will be individually deconstructed (@pxref{add}).
-@node PostScript to Asymptote, Help, GUI, Top
+@node Command-Line Interface, PostScript to Asymptote, GUI, Top
+@chapter Command-Line Interface
+@cindex command-line interface
+
+@code{Asymptote} code may be sent to the
+@url{http://asymptote.ualberta.ca} server directly from the command
+line, specifying any options directly in the @acronym{URL}:
+
+@itemize @bullet
+
+@item SVG output:
+
+@code{curl --data-binary 'import venn;' 'asymptote.ualberta.ca:10007?f=svg' | display -}
+
+@item HTML output:
+
+@code{curl --data-binary @@/usr/local/share/doc/asymptote/examples/Klein.asy 'asymptote.ualberta.ca:10007' -o Klein.html}
+
+@item V3D output:
+
+@code{curl --data-binary 'import teapot;' 'asymptote.ualberta.ca:10007?f=v3d' -o teapot.v3d}
+
+@item PDF output with rendered bitmap at 2 pixels per bp:
+
+@code{curl --data-binary 'import teapot;' 'asymptote.ualberta.ca:10007?f=pdf' -o teapot.pdf}
+
+@item PDF output with rendered bitmap at 4 pixels per bp:
+
+@code{curl --data-binary 'import teapot;' 'asymptote.ualberta.ca:10007?f=pdf&render=4' -o teapot.pdf}
+
+@item PRC output:
+
+@code{curl --data-binary 'import teapot;' 'asymptote.ualberta.ca:10007?f=pdf&prc' -o teapot.pdf}
+
+@item PRC output with rendered preview bitmap at 4 pixels per bp:
+
+@code{curl --data-binary 'import teapot;' 'asymptote.ualberta.ca:10007?f=pdf&prc&render=4' -o teapot.pdf}
+
+@end itemize
+
+The source code for the command-line interface is available at
+@url{https://github.com/vectorgraphics/asymptote-http-server}.
+
+@node Language server protocol, PostScript to Asymptote, Command-Line Interface, Top
+@chapter Language server protocol
+@cindex @acronym{LSP}
+@cindex language server protocol
+
+Under @code{UNIX} and @code{MacOS X}, @code{Asymptote} supports features of the
+@uref{https://en.wikipedia.org/wiki/Language_Server_Protocol,Language
+Server Protocol (@acronym{LSP})}, including function signature and variable matching.
+Under @code{MSWindows}, @code{Asymptote} currently supports
+@acronym{LSP} only when compiled within the @code{Windows Subsystem for Linux}.
+
+@code{Emacs} users can enable the @code{Asymptote}
+language server protocol by installing @code{lsp-mode} using the
+following procedure:
+
+@itemize @bullet
+
+@item Add to the @code{.emacs} initialization file:
+@verbatim
+(require 'package)
+(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
+(package-initialize)
+@end verbatim
+
+@item Launch emacs and execute
+@verbatim
+M-x package-refresh-contents
+M-x package-install
+@end verbatim
+and select @code{lsp-mode}.
+
+@item Add to the @code{.emacs} initialization file:
+@verbatim
+(require 'lsp-mode)
+(add-to-list 'lsp-language-id-configuration '(asy-mode . "asymptote"))
+
+(lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection '("asy" "-lsp"))
+ :activation-fn (lsp-activate-on "asymptote")
+ :major-modes '(asy-mode)
+ :server-id 'asyls
+ )
+ )
+@end verbatim
+
+@item Launch emacs and execute
+@verbatim
+M-x lsp
+@end verbatim
+
+@end itemize
+
+@node PostScript to Asymptote, Help, Command-Line Interface, Top
@chapter @code{PostScript} to @code{Asymptote}
@cindex @code{pstoedit}
-The excellent @code{PostScript} editor @code{pstoedit} (version 3.50 or later;
+The excellent @code{PostScript} editor @code{pstoedit} (version 3.50 or later;
available from @url{https://sourceforge.net/projects/pstoedit/}) includes an
@code{Asymptote} backend. Unlike virtually all other @code{pstoedit}
backends, this driver includes native clipping, even-odd fill rule,
@@ -9784,7 +9925,7 @@ A list of frequently asked questions (@acronym{FAQ}) is maintained at
@noindent
Questions on installing and using @code{Asymptote} that are not
addressed in the @acronym{FAQ} should be sent to the
-@code{Asymptote} forum:
+@code{Asymptote} forum:
@quotation
@url{https://sourceforge.net/p/asymptote/discussion/409349}
@end quotation
@@ -9830,7 +9971,7 @@ check bugs with Status @code{Closed} and recent lines in
user-generated @code{Asymptote} stack overflows (@pxref{stack overflow})
from true segmentation faults (due to internal C++ programming errors;
please submit the @code{Asymptote} code that generates such segmentation
-faults along with your bug report).
+faults along with your bug report).
@node Debugger, Credits, Help, Top
@chapter Debugger
@@ -9935,10 +10076,10 @@ void breakpoint(code s=quote{});
Financial support for the development of @code{Asymptote} was generously
provided by the Natural Sciences and Engineering Research Council of
-Canada, the Pacific Institute for Mathematical Sciences, and the
+Canada, the Pacific Institute for Mathematical Sciences, and the
University of Alberta Faculty of Science.
-
-We also would like to acknowledge the previous work of John D. Hobby,
+
+We also would like to acknowledge the previous work of John D. Hobby,
author of the program @code{MetaPost} that inspired the development of
@code{Asymptote}, and Donald E. Knuth, author of @TeX{} and
@code{MetaFont} (on which @code{MetaPost} is based).
@@ -9949,15 +10090,18 @@ contributors include Orest Shardt, Jesse Frohlich, Michail Vidiassov,
Charles Staats, Philippe Ivaldi, Olivier Guib@'e, Radoslav Marinov,
Jeff Samuelson, Chris Savage, Jacques Pienaar, Mark Henning, Steve Melenchuk,
Martin Wiebusch, Stefan Knorr, and Supakorn ``Jamie'' Rassameemasmuang.
-Pedram Emami developed the @code{Asymptote Web Application} at
-@url{http://asymptote.ualberta.ca}.
+Pedram Emami developed the @code{Asymptote Web Application}
+hosted at @url{http://asymptote.ualberta.ca}:
+
+@url{https://github.com/vectorgraphics/asymptote-http-server}
+
@node Index, , Credits, Top
@unnumbered Index
-
+
@printindex cp
-
+
@bye
@c LocalWords: randMax Gaussrand asy cindex indices resized LaTeX TK latin au
@@ -10124,7 +10268,7 @@ Pedram Emami developed the @code{Asymptote Web Application} at
@c LocalWords: bb llx 2S 100pt 3t bezier2 bool3 x0 angle1 angle2 z1
@c LocalWords: z2 before' struct X11 x11colors type1cm 12pt OT1 5mm
@c LocalWords: cmr12 x' y' xsize ysize 25cm s1 s2 neighbourhood u''
-@c LocalWords: s'' 3x 5x 3y 602e 2x 2y 3sin 10cm 204e addby7 10x
+@c LocalWords: s'' 3x 5x 3y 602e 2x 2y 3sin 10cm 204e addby7 10x 's
@c LocalWords: only'' pow10 log10 expm1 log1p atan2 0pt 1filll 's '
@c LocalWords: x1 x2 graph2d attachfile2 n0 P0 n1 P1 markers1 3D 2D
@c LocalWords: interpolate1 markers2 inlinemovie3 media9 U3D T2A 5E
@@ -10147,39 +10291,41 @@ Pedram Emami developed the @code{Asymptote Web Application} at
@c LocalWords: slopefield1 144x144 1filll 'load 'asy 'lasy 'auto 4g
@c LocalWords: libgs 'load 'asy 'lasy 'auto 5bp 1cm 2S 100pt 3t 5mm
@c LocalWords: bracedefaultratio incircle 12pt 25cm 3x 5x 3y 602e '
-@c LocalWords: 2x 2y 3sin 10cm 204e 10x 5E offaxis 'load 'lasy '
+@c LocalWords: 2x 2y 3sin 10cm 204e 10x 5E offaxis 'load 'lasy ' 3D
@c LocalWords: 5cm 2N 2E 2n 100d 5z 5y 5unit dvisvgmOptions 144x144
@c LocalWords: 4g texengines coplanar 0pt 1filll 's 3D 2D 'load 5bp
@c LocalWords: insphere cospherical 5unit luatex lualatex 'asy 1cm
@c LocalWords: 'lasy 'auto 4g 2S 100pt 3t 12pt 5mm 25cm 3x 5x 3y 2x
-@c LocalWords: 602e 2y 3sin 10cm 204e 10x
-@c LocalWords: unnormalized 5E 5cm 2N 2E 2n 100d 5z 5y 0pt 1filll
+@c LocalWords: 602e 2y 3sin 10cm 204e 10x 0pt 1filll 2D DCMAKE CXX
+@c LocalWords: unnormalized 5E 5cm 2N 2E 2n 100d 5z 5y 0pt 1filll '
@c LocalWords: 5unit 144x144 aligndir smoothcontour3 's 3D 2D cmake
@c LocalWords: 'load 'asy 'lasy 'auto 5bp 1cm 4g 2S 100pt 3t nan 3x
-@c LocalWords: 12pt 5mm 25cm 5x 3y 602e 2x 2y 3sin 10cm 204e 10x
-@c LocalWords: 5E 5cm 2N 2E 2n 100d 5z 5y nz
+@c LocalWords: 12pt 5mm 25cm 5x 3y 602e 2x 2y 3sin 10cm 204e 10x 4g
+@c LocalWords: 5E 5cm 2N 2E 2n 100d 5z 5y nz fcommon 'load 'asy 5bp
@c LocalWords: 5unit Staats implicitsurface overlapedges maxdepth '
@c LocalWords: through'' genustwo 144x144 0pt 1filll 's 3D 2D 'load
@c LocalWords: 'asy 'lasy 'auto 5bp 1cm 4g 2S 100pt 3t 12pt 5mm 3x
-@c LocalWords: 25cm 5x 3y 602e 2x 2y 3sin 10cm 204e 10x
-@c LocalWords: 5E 5cm 2N 2E 2n 100d 5z 5y 5unit 144x144
+@c LocalWords: 25cm 5x 3y 602e 2x 2y 3sin 10cm 204e 10x 'lasy 'auto
+@c LocalWords: 5E 5cm 2N 2E 2n 100d 5z 5y 5unit 144x144 1cm newpage
@c LocalWords: Frohlich codequoteundirected center 0pt 1filll 's 3D
@c LocalWords: acknowledgments Colors 2D Color WebGL uref x86 dnf
@c LocalWords: htmlviewer asygl CPPFLAGS 'load 'asy 'lasy 'auto 5bp
@c LocalWords: 1cm labeling dotfilltype 4g color colors centered 2S
@c LocalWords: 100pt 3t forcemath gray colorless miter 12pt 5mm 3x
@c LocalWords: zeroTransform 25cm Python3 popcount bitreverse 5x 3y
-@c LocalWords: 602e 2x 2y 3sin 10cm 204e 10x
-@c LocalWords: findall ax 5a centers 5E 5cm 2N 2E 2n HTML5 html
+@c LocalWords: 602e 2x 2y 3sin 10cm 204e 10x 2S 100pt 3t 12pt 5mm
+@c LocalWords: findall ax 5a centers 5E 5cm 2N 2E 2n HTML5 html 3x
@c LocalWords: logo3 remeshed css 42kB 100d 5z 5y 5unit colored Qt5
@c LocalWords: behavior beveled usetriangles htmlviewerOptions cson
@c LocalWords: 144x144 pyqt5 numpy pip3 PyQt5 rsvg librsvg2 1filll
@c LocalWords: librsvg Supakorn Jamie'' Rassameemasmuang 2D Docdir
-@c LocalWords: microsoft configuation 'load 'asy 'lasy 'auto dep 4g
+@c LocalWords: microsoft 'load 'asy 'lasy 'auto dep 4g isometry 5x
@c LocalWords: 5bp 1cm BezierPatch 2S 100pt 3t abs2 12pt cp1251 5mm
-@c LocalWords: anttor fontenc inputenc 25cm noglobalread 3x
-@c LocalWords: 5x 3y 602e 2x 2y 3sin 10cm 204e 10x
-@c LocalWords: mapArray 5a parameterized mapTemplate 5E 2N
+@c LocalWords: anttor fontenc inputenc 25cm noglobalread 3x 25cm 3y
+@c LocalWords: 5x 3y 602e 2x 2y 3sin 10cm 204e 10x libcurl 602e 2x
+@c LocalWords: mapArray 5a parameterized mapTemplate 5E 2N 2y 3sin
@c LocalWords: 5cm freshnel0 fresnel0 PBR prethree specularfactor
-@c LocalWords: renderers 2E ESC AsyGL 48kB 2n 100d 5z 5y 5unit
-@c LocalWords: unicode 144x144 Pedram Emami
+@c LocalWords: renderers 2E ESC AsyGL 48kB 2n 100d 5z 5y 5unit 10cm
+@c LocalWords: unicode 144x144 Pedram Emami 204e 10x Ai Ai Ai Ai Ai
+@c LocalWords: Ai Ai Ai 5a 5E 5cm 2N 2E devicepixelratio 48kB 2n 5z
+@c LocalWords: 100d 5y 5unit 144x144
diff --git a/graphics/asymptote/doc/graphwithderiv.asy b/graphics/asymptote/doc/graphwithderiv.asy
new file mode 100644
index 0000000000..2dfd1da02d
--- /dev/null
+++ b/graphics/asymptote/doc/graphwithderiv.asy
@@ -0,0 +1,11 @@
+unitsize(2cm);
+import graph;
+pair F(real t) {
+ return (1.3*t,-4.5*t^2+3.0*t+1.0);
+}
+pair Fprime(real t) {
+ return (1.3,-9.0*t+3.0);
+}
+path g=graphwithderiv(F,Fprime,0,0.9,4);
+dot(g,red);
+draw(g,arrow=Arrow(TeXHead));
diff --git a/graphics/asymptote/doc/latexusage.tex b/graphics/asymptote/doc/latexusage.tex
index 07b0e56a35..9701a25af9 100644
--- a/graphics/asymptote/doc/latexusage.tex
+++ b/graphics/asymptote/doc/latexusage.tex
@@ -21,6 +21,7 @@
\begin{asydef}
// Global Asymptote definitions can be put here.
+settings.prc=true;
import three;
usepackage("bm");
texpreamble("\def\V#1{\bm{#1}}");
diff --git a/graphics/asymptote/doc/legend.asy b/graphics/asymptote/doc/legend.asy
index b00cdd14e6..246c787c83 100644
--- a/graphics/asymptote/doc/legend.asy
+++ b/graphics/asymptote/doc/legend.asy
@@ -4,7 +4,7 @@ size(8cm,6cm,IgnoreAspect);
typedef real realfcn(real);
realfcn F(real p) {
return new real(real x) {return sin(p*x);};
-};
+}
for(int i=1; i < 5; ++i)
draw(graph(F(i*pi),0,1),Pen(i),
diff --git a/graphics/asymptote/doc/ocg.sty b/graphics/asymptote/doc/ocg.sty
deleted file mode 100644
index 87da828a8d..0000000000
--- a/graphics/asymptote/doc/ocg.sty
+++ /dev/null
@@ -1,130 +0,0 @@
-%% Copyright (C) 2007 by Michael Ritzert <michael.ritz...@gmail.com>
-%% Spurious spaces removed by John Bowman [2009/06/01].
-%% Global macros to find the number of a PDF OCG object from its LaTeX
-%% reference contributed by Paul Gaborit [2012/09/13].
-
-\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{ocg}[2012/09/13]
-
-\RequirePackage{ifpdf}
-\ifpdf
-\else
- \PackageWarningNoLine{ocg}{%
- Loading aborted, because pdfTeX is not running in PDF mode%
- }%
- \expandafter\endinput
-\fi
-
-\DeclareOption*{}\ProcessOptions*\relax %allow anything as option for the moment
-
-%testing for correct pdfTeX version
-%TODO: find out minimum required version!
-\ifnum\pdftexversion<120
- \PackageError{ocg}{%
- pdfeTeX, version >= 1.20, required%
- }{%
- Install a newer version!%
- }%
-\fi
-
-% Next OCG id -- TODO: autogenerate. but keep possibility to reopen an OCG.
-\newcount\@ocg@num\@ocg@num=0
-
-\gdef\@ocg@layersnames{}
-
-% called from the aux file
-\def\@ocg@makeknown#1#2#3{% #1: OCG name, #2: OC id, #3: on/off
- \@ifundefined{OCG#2}{%
- \message{OCG#2}
- \expandafter\gdef\csname OCG#2\endcsname{#1}%
- \immediate\pdfobj{<< /Type /OCG /Name (#1) >>}% new ocg
- \xdef\@ocg@curocg{\the\pdflastobj\space 0 R}% reference to id
- \expandafter\xdef\csname OCGpdfobj#2\endcsname{\@ocg@curocg}
- \xdef\@ocg@ocgs{\@ocg@ocgs\space\@ocg@curocg}% list of all OCGs in "first defined" order
- \ifnum#3=1 %on
- \xdef\@ocg@ocgson{\@ocg@ocgson\space\@ocg@curocg}% list of all default-on OCGs
- \else%
- \xdef\@ocg@ocgsoff{\@ocg@ocgsoff\space\@ocg@curocg}% list of all default-off OCGs
- \fi%
- \xdef\@ocg@layersnames{%
- \@ocg@layersnames\space/OC#2\space\@ocg@curocg% name-to-id mapping
- }%
- }{%
- \message{OCG#2 reopened}
- % layer reopened
- }
-}
-
-\AtBeginDocument{%
- % the auxfile has been read if available. register the OCGs in the page resources.
- \@ocg@addresource
- \let\@ocg@makeknown\@gobble
-}
-
-% set page resources to include the layers defined in the aux file
-\def\@ocg@addresource{%
- \immediate\pdfobj{<<\@ocg@layersnames\space>>}%
- \xdef\@ocg@namesobj{\the\pdflastobj\space 0 R}%
- % append to pageresources
- \begingroup
- \edef\x{\endgroup
- \pdfpageresources{%
- \the\pdfpageresources
- /Properties \@ocg@namesobj%
- }%
- }%
- \x
-}
-
-\newcount\@ocg@@ocgs
-\pdfobj reserveobjnum
-\@ocg@@ocgs=\pdflastobj
-
-\newcount\@ocg@@layersconfig
-\pdfobj reserveobjnum
-\@ocg@@layersconfig=\pdflastobj
-
-\pdfcatalog{%
- /OCProperties <<
- /OCGs \the\@ocg@@ocgs\space0 R\space
- /D \the\@ocg@@layersconfig\space0 R\space
- >>%
-}
-\def\@ocg@ocgs{}
-\def\@ocg@ocgson{}
-\def\@ocg@ocgsoff{}
-\AtEndDocument{%
- \immediate\pdfobj useobjnum \@ocg@@ocgs {%
- [\@ocg@ocgs\space]%
- }%
- \immediate\pdfobj useobjnum \@ocg@@layersconfig {%
- <<
- /Order [\@ocg@ocgs\space]
- /ON [\@ocg@ocgson\space]
- /OFF [\@ocg@ocgsoff\space]
- >>%
- }%
-}%
-
-% schedule a OCG for creation on the next pdflatex run (via the auxfile)
-\def\@ocg@newocg#1#2#3{% #1:name, #2:num, #3:on
- \if@filesw%
- \immediate\write\@auxout{%
- \string\@ocg@makeknown{#1}{#2}{#3}%
- }%
- \fi%
-}
-
-% TODO: Are nested OCGs allowed?
-\newenvironment{ocg}[3]{%
- \@ocg@newocg{#1}{#2}{#3}%
- \gdef\@ocg@curnum{#2}%
- \pdfliteral{/OC /OC\@ocg@curnum\space BDC}%
- \message{/OC\@ocg@curnum}%
- \ignorespaces
-}{%
- \pdfliteral{EMC}%
- %\unskip%
- %\endgroup%
- \ignorespacesafterend
-}
diff --git a/graphics/asymptote/doc/png/asymptote.info b/graphics/asymptote/doc/png/asymptote.info
index 89903f6910..8e61eb0a97 100644
--- a/graphics/asymptote/doc/png/asymptote.info
+++ b/graphics/asymptote/doc/png/asymptote.info
@@ -1,11 +1,11 @@
-This is asymptote.info, produced by makeinfo version 6.6 from
+This is asymptote.info, produced by makeinfo version 6.7 from
asymptote.texi.
-This file documents 'Asymptote', version 2.70.
+This file documents 'Asymptote', version 2.72.
<https://asymptote.sourceforge.io>
- Copyright (C) 2004-20 Andy Hammerlindl, John Bowman, and Tom Prince.
+ Copyright (C) 2004-21 Andy Hammerlindl, John Bowman, and Tom Prince.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Lesser General Public License
@@ -22,11 +22,11 @@ File: asymptote.info, Node: Top, Next: Description, Prev: (dir), Up: (dir)
Asymptote
*********
-This file documents 'Asymptote', version 2.70.
+This file documents 'Asymptote', version 2.72.
<https://asymptote.sourceforge.io>
- Copyright (C) 2004-20 Andy Hammerlindl, John Bowman, and Tom Prince.
+ Copyright (C) 2004-21 Andy Hammerlindl, John Bowman, and Tom Prince.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Lesser General Public License
@@ -45,6 +45,8 @@ This file documents 'Asymptote', version 2.70.
* Options:: Command-line options
* Interactive mode:: Typing 'Asymptote' commands interactively
* GUI:: Graphical user interface
+* Command-Line Interface:: Remote command-line interface
+* Language server protocol:: Help when writing code
* PostScript to Asymptote:: 'Asymptote' backend to 'pstoedit'
* Help:: Where to get help and submit bug reports
* Debugger:: Squish those bugs!
@@ -175,12 +177,15 @@ drawing. Labels and equations are typeset with 'LaTeX', for overall
document consistency, yielding the same high-quality level of
typesetting that 'LaTeX' provides for scientific text. By default it
produces 'PostScript' output, but it can also generate 'PDF', 'SVG',
-'WebGL', 'PRC', and any format that the 'ImageMagick' package can
+'WebGL', 'V3D', 'PRC', and any format that the 'ImageMagick' package can
produce. You can even try it out in your Web browser without installing
-it, using the 'Asymptote Web Application':
+it, using the 'Asymptote Web Application'
<http://asymptote.ualberta.ca>
+ It is also possible to send remote commands to this server via the
+curl utility (*note Command-Line Interface::).
+
A major advantage of 'Asymptote' over other graphics packages is that
it is a high-level programming language, as opposed to just a graphics
program: it can therefore exploit the best features of the script
@@ -342,8 +347,8 @@ required to typeset labels. You will also need to install 'GPL
Ghostscript' version 9.52 or later from
<http://downloads.ghostscript.com/public>.
- To view 'PostScript' output, you can install the program 'gsview'
-available from <http://www.cs.wisc.edu/~ghost/gsview/>.
+ To view 'PostScript' output, you can install the program 'Sumatra
+PDF' available from <https://www.sumatrapdfreader.org/>.
The 'ImageMagick' package from
<https://www.imagemagick.org/script/binary-releases.php>
@@ -406,7 +411,7 @@ display 3D 'WebGL' output. The default setting is 'google-chrome' under
Explorer' does not support 'WebGL'; 'Microsoft Windows' users should set
their default html browser to 'chrome' or 'microsoft-edge'. By default,
2D and 3D 'HTML' images expand to the enclosing canvas; this can be
-disabled by setting the configuation variable 'absolute' to 'true'.
+disabled by setting the configuration variable 'absolute' to 'true'.
On 'UNIX' systems, to support automatic document reloading of 'PDF'
files in 'Adobe Reader', we recommend copying the file 'reload.js' from
@@ -971,7 +976,7 @@ frame legend(picture pic=currentpicture, int perline=1,
real xmargin=legendmargin, real ymargin=xmargin,
real linelength=legendlinelength,
real hskip=legendhskip, real vskip=legendvskip,
- real maxwidth=0, real maxheight=0,
+ real maxwidth=0, real maxheight=0,
bool hstretch=false, bool vstretch=false, pen p=currentpen);
Here 'xmargin' and 'ymargin' specify the surrounding x and y margins,
'perline' specifies the number of entries per line (default 1; 0 means
@@ -1257,7 +1262,7 @@ packed together into single frame with the routine
frame pack(pair align=2S ... object inset[]);
To draw or fill a box (or ellipse or other path) around a Label and
return the bounding object, use one of the routines
-object draw(picture pic=currentpicture, Label L, envelope e,
+object draw(picture pic=currentpicture, Label L, envelope e,
real xmargin=0, real ymargin=xmargin, pen p=currentpen,
filltype filltype=NoFill, bool above=true);
object draw(picture pic=currentpicture, Label L, envelope e, pair position,
@@ -2016,11 +2021,11 @@ File: asymptote.info, Node: Paths and guides, Next: Pens, Prev: Data types,
'path subpath(path p, int a, int b);'
returns the subpath of 'p' running from node 'a' to node 'b'.
- If 'a' < 'b', the direction of the subpath is reversed.
+ If 'a' > 'b', the direction of the subpath is reversed.
'path subpath(path p, real a, real b);'
returns the subpath of 'p' running from path time 'a' to path
- time 'b', in the sense of 'point(path, real)'. If 'a' < 'b',
+ time 'b', in the sense of 'point(path, real)'. If 'a' > 'b',
the direction of the subpath is reversed.
'real[] intersect(path p, path q, real fuzz=-1);'
@@ -3018,7 +3023,7 @@ File: asymptote.info, Node: Frames and pictures, Next: Files, Prev: Transform
The routine
void usepackage(string s, string options="");
provides a convenient abbreviation for
- texpreamble("\usepackage["+options+"]{"+s+"}");
+ texpreamble("\usepackage["+options+"]{"+s+"}");
that can be used for importing 'LaTeX' packages.

@@ -3436,7 +3441,7 @@ For convenience, the incremental fields 'change.user', 'change.system',
and 'change.clock' indicate the change in the corresponding fields since
the last call to 'cputime()'. The function
void write(file file=stdout, string s="", cputime c,
- string format=cputimeformat, suffix suffix=none);
+ string format=cputimeformat, suffix suffix=none);
displays the incremental user cputime followed by "u", the incremental
system cputime followed by "s", the total user cputime followed by "U",
and the total system cputime followed by "S".
@@ -3451,7 +3456,7 @@ struct parent {
}
void write(parent p) {write(p.x);}
-
+
struct child {
parent parent;
real y=3;
@@ -3462,7 +3467,7 @@ struct child {
}
parent operator cast(child child) {return child.parent;}
-
+
parent p=parent(1);
child c=child(2);
@@ -3683,13 +3688,13 @@ reference, simply enclose it in a structure (*note Structures::).
1. Variables with signatures (functions) and without signatures
(nonfunction variables) are distinct:
- int x, x();
+ int x, x();
x=5;
x=new int() {return 17;};
x=x(); // calls x() and puts the result, 17, in the scalar x
2. Traditional function definitions are allowed:
- int sqr(int x)
+ int sqr(int x)
{
return x*x;
}
@@ -3721,22 +3726,22 @@ reference, simply enclose it in a structure (*note Structures::).
version of 'f', as illustrated in this example:
void f() {
write("hi");
- }
-
+ }
+
void g() {
f();
- }
-
- g(); // writes "hi"
-
- f=new void() {write("bye");};
+ }
+
+ g(); // writes "hi"
+
+ f=new void() {write("bye");};
- g(); // writes "bye"
-
- void f() {write("overloaded");};
+ g(); // writes "bye"
+
+ void f() {write("overloaded");};
f(); // writes "overloaded"
- g(); // writes "bye"
+ g(); // writes "bye"
6. Anonymous functions can be used to redefine a function variable
that has been declared (and implicitly initialized to the null
@@ -3855,7 +3860,7 @@ Rest arguments allow one to write functions that take a variable number
of arguments:
// This function sums its arguments.
int sum(... int[] nums) {
- int total=0;
+ int total=0;
for(int i=0; i < nums.length; ++i)
total += nums[i];
return total;
@@ -4145,6 +4150,10 @@ of type 'T[]'.
if 'm >= n' returns an array '{n,n+1,...,m}' (otherwise returns a
null array);
+'int[] sequence(int n, int m, int skip)'
+ if 'm >= n' returns an array '{n,n+1,...,m}' skipping by 'skip'
+ (otherwise returns a null array);
+
'T[] sequence(T f(int), int n)'
if 'n >= 1' returns the sequence '{f_i :i=0,1,...n-1}' given a
function 'T f(int)' and integer 'int n' (otherwise returns a null
@@ -4606,19 +4615,19 @@ from graph access *;
Similarly, one can add the non-private fields and types of a
structure to the local environment with the 'unravel' keyword:
-struct matrix {
- real a,b,c,d;
-}
-
-real det(matrix m) {
- unravel m;
- return a*d-b*c;
-}
+struct matrix {
+ real a,b,c,d;
+}
+
+real det(matrix m) {
+ unravel m;
+ return a*d-b*c;
+}
Alternatively, one can unravel selective fields:
-real det(matrix m) {
+real det(matrix m) {
from m unravel a,b,c as C,d;
- return a*d-b*C;
-}
+ return a*d-b*C;
+}
The command
import graph;
@@ -4927,6 +4936,7 @@ labels might not show up in DVI viewers that cannot handle raw
\begin{asydef}
// Global Asymptote definitions can be put here.
+settings.prc=true;
import three;
usepackage("bm");
texpreamble("\def\V#1{\bm{#1}}");
@@ -5127,24 +5137,24 @@ functions such as
returns the four complex roots of the quartic equation
ax^4+bx^3+cx^2+dx+e=0.
-'real time(path g, real x, int n=0)'
+'real time(path g, real x, int n=0, real fuzz=-1)'
returns the 'n'th intersection time of path 'g' with the vertical
line through x.
-'real time(path g, explicit pair z, int n=0)'
+'real time(path g, explicit pair z, int n=0, real fuzz=-1)'
returns the 'n'th intersection time of path 'g' with the horizontal
line through '(0,z.y)'.
-'real value(path g, real x, int n=0)'
+'real value(path g, real x, int n=0, real fuzz=-1)'
returns the 'n'th 'y' value of 'g' at 'x'.
-'real value(path g, explicit pair z, int n=0)'
+'real value(path g, explicit pair z, int n=0, real fuzz=-1)'
returns the 'n'th 'x' value of 'g' at 'y=z.y'.
-'real slope(path g, real x, int n=0)'
+'real slope(path g, real x, int n=0, real fuzz=-1)'
returns the 'n'th slope of 'g' at 'x'.
-'real slope(path g, explicit pair z, int n=0)'
+'real slope(path g, explicit pair z, int n=0, real fuzz=-1)'
returns the 'n'th slope of 'g' at 'y=z.y'.
int[][] segment(bool[] b) returns the indices of consecutive
@@ -5223,7 +5233,7 @@ This module implements 'PostScript' tiling patterns and includes several
convenient pattern generation routines.

-File: asymptote.info, Node: markers, Next: tree, Prev: patterns, Up: Base modules
+File: asymptote.info, Node: markers, Next: map, Prev: patterns, Up: Base modules
8.9 'markers'
=============
@@ -5290,7 +5300,7 @@ write(M.lookup("a"));
write(M.lookup("y"));

-File: asymptote.info, Node: tree, Next: binarytree, Prev: markers, Up: Base modules
+File: asymptote.info, Node: tree, Next: binarytree, Prev: map, Up: Base modules
8.11 'tree'
===========
@@ -5617,7 +5627,7 @@ following routines:
An axis can be drawn on a picture with one of the following commands:
* void xaxis(picture pic=currentpicture, Label L="", axis axis=YZero,
- real xmin=-infinity, real xmax=infinity, pen p=currentpen,
+ real xmin=-infinity, real xmax=infinity, pen p=currentpen,
ticks ticks=NoTicks, arrowbar arrow=None, bool above=false);
Draw an x axis on picture 'pic' from x='xmin' to x='xmax' using pen
@@ -5746,8 +5756,8 @@ following routines:
'LeftTicks', 'RightTicks', and 'Ticks' by passing explicit real
arrays 'Ticks' and (optionally) 'ticks' containing the locations of
the major and minor ticks, respectively:
- ticks LeftTicks(Label format="", ticklabel ticklabel=null,
- bool beginlabel=true, bool endlabel=true,
+ ticks LeftTicks(Label format="", ticklabel ticklabel=null,
+ bool beginlabel=true, bool endlabel=true,
real[] Ticks, real[] ticks=new real[],
real Size=0, real size=0, bool extend=false,
pen pTick=nullpen, pen ptick=nullpen)
@@ -5940,7 +5950,7 @@ following routines:
typedef real realfcn(real);
realfcn F(real p) {
return new real(real x) {return sin(p*x);};
- };
+ }
for(int i=1; i < 5; ++i)
draw(graph(F(i*pi),0,1),Pen(i),
@@ -5992,7 +6002,7 @@ following routines:
5. The next example draws two graphs of an array of coordinate pairs,
using frame alignment and data markers. In the left-hand graph,
the markers, constructed with
- marker marker(path g, markroutine markroutine=marknodes,
+ marker marker(path g, markroutine markroutine=marknodes,
pen p=currentpen, filltype filltype=NoFill,
bool above=true);
using the path 'unitcircle' (*note filltype::), are drawn below
@@ -6018,13 +6028,13 @@ following routines:
marker(scale(circlescale)*unitcircle),
marker(polygon(3)),marker(polygon(4)),
marker(polygon(5)),marker(invert*polygon(3)),
- marker(cross(4)),marker(cross(6))
+ marker(cross(4)),marker(cross(6)),marker(diamond),marker(plus);
};
marker[] MarkFill={
marker(scale(circlescale)*unitcircle,Fill),marker(polygon(3),Fill),
marker(polygon(4),Fill),marker(polygon(5),Fill),
- marker(invert*polygon(3),Fill)
+ marker(invert*polygon(3),Fill),marker(diamond,Fill)
};
The example also illustrates the 'errorbar' routines:
@@ -6179,6 +6189,26 @@ following routines:
[./parametricgraph]
+ The function
+ guide graphwithderiv(pair f(real), pair fprime(real), real a, real b,
+ int n=ngraph#10);
+ can be used to construct the graph of the parametric function 'f'
+ on '[a,b]' with the control points of the 'n' Bezier segments
+ determined by the specified derivative 'fprime':
+ unitsize(2cm);
+ import graph;
+ pair F(real t) {
+ return (1.3*t,-4.5*t^2+3.0*t+1.0);
+ }
+ pair Fprime(real t) {
+ return (1.3,-9.0*t+3.0);
+ }
+ path g=graphwithderiv(F,Fprime,0,0.9,4);
+ dot(g,red);
+ draw(g,arrow=Arrow(TeXHead));
+
+ [./graphwithderiv]
+
The next example illustrates how one can extract a common axis
scaling factor.
import graph;
@@ -6392,7 +6422,7 @@ following routines:
real[][] a=in;
a=transpose(a);
real[] t=a[0], susceptible=a[1], infectious=a[2], dead=a[3], larvae=a[4];
- real[] susceptibleM=a[5], exposed=a[6],infectiousM=a[7];
+ real[] susceptibleM=a[5], exposed=a[6], infectiousM=a[7];
scale(true);
@@ -6410,7 +6440,6 @@ following routines:
add(secondary);
label(shift(5mm*N)*"Proportion of crows",point(NW),E);
-
[./secondaryaxis]
@@ -6861,7 +6890,7 @@ model tree. Here material is a structure defined in 'three_light.asy':
struct material {
pen[] p; // diffusepen,emissivepen,specularpen
real opacity;
- real shininess;
+ real shininess;
real metallic;
real fresnel0;
}
@@ -6895,10 +6924,20 @@ transparent for all other formats. One can request a completely
transparent background for 3D 'WebGL' images with
'currentlight.background=black+opacity(0.0);'
+ Asymptote also supports image-based lighting with the setting
+'settings.ibl=true'. This uses pre-rendered EXR images from the
+directory specified by '-imageDir' (which defaults to 'ibl') or, for
+'WebGL' rendering, the URL specified by '-imageURL' (which defaults to
+<https://vectorgraphics.gitlab.io/asymptote/ibl>). Additional rendered
+images can be generated on an 'NVIDIA' GPU using the 'reflect' program
+in the 'cudareflect' subdirectory of the 'Asymptote' source directory.
+
Sample Bezier surfaces are contained in the example files
-'BezierSurface.asy', 'teapot.asy', and 'parametricsurface.asy'. The
-structure 'render' contains specialized rendering options documented at
-the beginning of module 'three'.
+'BezierSurface.asy', 'teapot.asy', 'teapotIBL.asy', and
+'parametricsurface.asy'.
+
+ The structure 'render' contains specialized rendering options
+documented at the beginning of module 'three'.
The examples 'elevation.asy' and 'sphericalharmonic.asy' illustrate
how to draw a surface with patch-dependent colors. The examples
@@ -6963,7 +7002,7 @@ given in the pen parameter or the setting 'thin' is set to 'false'. The
pens 'thin()' and 'thick()' defined in 'plain_pens.asy' can also be used
to override these defaults for specific draw commands.
-There are five choices for viewing 3D 'Asymptote' output:
+There are six choices for viewing 3D 'Asymptote' output:
1. Use the native 'Asymptote' adaptive 'OpenGL'-based renderer (with
the command-line option '-V' and the default settings
@@ -7019,11 +7058,8 @@ There are five choices for viewing 3D 'Asymptote' output:
'outformat="html"'). The resulting 3D HTML file can then be viewed
directly in any modern desktop or mobile browser, or even embedded
within another web page:
- <div>
- <object data="logo3.html"
- style="width:210;height:140;position:relative;top:0;left:0;">
- </object>
- </div>
+ <iframe src="logo3.html" width="210" height="140" frameborder="0">
+ </iframe>
Normally, 'WebGL' files generated by 'Asymptote' are dynamically
remeshed to fit the browser window dimensions. However, the
@@ -7059,34 +7095,44 @@ There are five choices for viewing 3D 'Asymptote' output:
setting the horizontal and vertical components of 'maxtiles' to
something less than your screen dimensions. The tile size is also
limited by the setting 'maxviewport', which restricts the maximum
- width and height of the viewport. On 'UNIX' systems some graphics
- drivers support batch mode ('-noV') rendering in an iconified
- window; this can be enabled with the setting 'iconify=true'.
+ width and height of the viewport. Some graphics drivers support
+ batch mode ('-noV') rendering in an iconified window; this can be
+ enabled with the setting 'iconify=true'.
4. Embed the 3D PRC format in a PDF file and view the resulting PDF
- file with version '9.0' or later of 'Adobe Reader'. In addition to
- the default 'settings.prc=true', this requires
- 'settings.outformat="pdf"', which can be specified by the command
- line option '-f pdf', put in the 'Asymptote' configuration file
- (*note configuration file::), or specified in the script before
- module 'three' (or 'graph3') is imported. The 'media9' LaTeX
- package is also required (*note embed::). The example '100d.asy'
- illustrates how one can generate a list of predefined views (see
- '100d.views'). A stationary preview image with a resolution of 'n'
- pixels per 'bp' can be embedded with the setting 'render=n'; this
- allows the file to be viewed with other 'PDF' viewers.
- Alternatively, the file 'externalprc.tex' illustrates how the
- resulting PRC and rendered image files can be extracted and
- processed in a separate 'LaTeX' file. However, see *note LaTeX
- usage:: for an easier way to embed three-dimensional 'Asymptote'
- pictures within 'LaTeX'. For specialized applications where only
- the raw PRC file is required, specify 'settings.outformat="prc"'.
- The PRC specification is available from
+ file with version '9.0' or later of 'Adobe Reader'. This requires
+ 'settings.outformat="pdf"' and 'settings.prc=true', which can be
+ specified by the command-line options '-f pdf' and '-f prc', put in
+ the 'Asymptote' configuration file (*note configuration file::), or
+ specified in the script before module 'three' (or 'graph3') is
+ imported. The 'media9' LaTeX package is also required (*note
+ embed::). The example '100d.asy' illustrates how one can generate
+ a list of predefined views (see '100d.views'). A stationary
+ preview image with a resolution of 'n' pixels per 'bp' can be
+ embedded with the setting 'render=n'; this allows the file to be
+ viewed with other 'PDF' viewers. Alternatively, the file
+ 'externalprc.tex' illustrates how the resulting PRC and rendered
+ image files can be extracted and processed in a separate 'LaTeX'
+ file. However, see *note LaTeX usage:: for an easier way to embed
+ three-dimensional 'Asymptote' pictures within 'LaTeX'. For
+ specialized applications where only the raw PRC file is required,
+ specify 'settings.outformat="prc"'. The PRC specification is
+ available from
<https://web.archive.org/web/20081204104459/http://livedocs.adobe.com/acrobat_sdk/9/Acrobat9_HTMLHelp/API_References/PRCReference/PRC_Format_Specification/>
- 5. Project the scene to a two-dimensional vector (EPS or PDF) format
- with 'render=0'. Only limited hidden surface removal facilities
- are currently available with this approach (*note PostScript3D::).
+ 5. Output a 'V3D' portable compressed binary file for viewing with an
+ external viewer or conversion to an alternate 3D format with the
+ Python 'pyv3d' library. The 'V3D' specification and the 'pyv3d'
+ library are available at <https://gitlab.com/vectorgraphics/v3d>.
+ A 'V3D' file 'file.v3d' may be imported and viewed by Asymptote
+ with the 'v3d' module:
+ import v3d;
+ importv3d("file.v3d");
+
+ 6. Project the scene to a two-dimensional vector (EPS or PDF) format
+ with 'render=0'. Only limited support for hidden surface removal,
+ lighting, and transparency is available with this approach (*note
+ PostScript3D::).
Automatic picture sizing in three dimensions is accomplished with
double deferred drawing. The maximal desired dimensions of the scene in
@@ -7196,11 +7242,7 @@ These projections to two dimensions are predefined:
This projects from three to two dimensions, taking account of
perspective, as seen from the location 'camera' looking at
'target', orienting the camera so that, if possible, the vector
- 'up' points upwards. If 'render=0', projection of
- three-dimensional cubic Bezier splines is implemented by
- approximating a two-dimensional nonuniform rational B-spline
- (NURBS) with a two-dimensional Bezier curve containing additional
- nodes and control points. If 'autoadjust=true', the camera will
+ 'up' points upwards. If 'autoadjust=true', the camera will
automatically be adjusted to lie outside the bounding volume for
all possible interactive rotations about 'target'. If
'center=true', the target will be adjusted to the center of the
@@ -7499,7 +7541,7 @@ Analogous routines 'yaxis' and 'zaxis' can be used to draw y and z axes
in three dimensions. There is also a routine for drawing all three
axis:
void axes3(picture pic=currentpicture,
- Label xlabel="", Label ylabel="", Label zlabel="",
+ Label xlabel="", Label ylabel="", Label zlabel="",
bool extend=false,
triple min=(-infinity,-infinity,-infinity),
triple max=(infinity,infinity,infinity),
@@ -8087,9 +8129,9 @@ not, then 'contour3' may be a better choice.
To construct the null surface of a function 'f(triple)' or
'ff(real,real,real)' over 'box(a,b)', use the routine
-surface implicitsurface(real f(triple)=null,
+surface implicitsurface(real f(triple)=null,
real ff(real,real,real)=null,
- triple a,
+ triple a,
triple b,
int n=nmesh,
bool keyword overlapedges=false,
@@ -8115,7 +8157,7 @@ File: asymptote.info, Node: slopefield, Next: ode, Prev: smoothcontour3, Up:
To draw a slope field for the differential equation dy/dx=f(x,y) (or
dy/dx=f(x)), use:
picture slopefield(real f(real,real), pair a, pair b,
- int nx=nmesh, int ny=nx,
+ int nx=nmesh, int ny=nx,
real tickfactor=0.5, pen p=currentpen,
arrowbar arrow=None);
Here, the points 'a' and 'b' are the lower left and upper right corners
@@ -8170,6 +8212,7 @@ Usage: ../asy [options] [file ...]
Options (negate by replacing - with -no):
+-GPUindexing Compute indexing partial sums on GPU [true]
-V,-View View output; command-line only
-absolute Use absolute WebGL dimensions [false]
-a,-align C|B|T|Z Center, Bottom, Top, or Zero page alignment [C]
@@ -8194,8 +8237,8 @@ Options (negate by replacing - with -no):
-devicepixelratio n Ratio of physical to logical pixels [1]
-digits n Default output file precision [7]
-divisor n Garbage collect using purge(divisor=n) [2]
+-dvisvgmMultipleFiles dvisvgm supports multiple files [false]
-embed Embed rendered preview image [true]
--envmap Enable environment map image-based lighting (Experimental) [false]
-exitonEOF Exit interactive mode on EOF [true]
-fitscreen Fit rendered image to screen [true]
-framedelay ms Additional frame delay [0]
@@ -8205,7 +8248,10 @@ Options (negate by replacing - with -no):
-gray Convert all colors to grayscale [false]
-h,-help Show summary of options; command-line only
-historylines n Retain n lines of history [1000]
+-ibl Enable environment map image-based lighting [false]
-iconify Iconify rendering window [false]
+-image string Environment image name [snowyField]
+-imageDir string Environment image library directory [ibl]
-inlineimage Generate inline embedded image [false]
-inlinetex Generate inline TeX code [false]
-interactiveMask Mask fpu exceptions in interactive mode [true]
@@ -8217,6 +8263,8 @@ Options (negate by replacing - with -no):
-l,-listvariables List available global functions and variables [false]
-localhistory Use a local interactive history file [false]
-loop Loop 3D animations [false]
+-lossy Use single precision for V3D reals [false]
+-lsp Special interactive mode for lsp-rpc [false]
-m,-mask Mask fpu exceptions; command-line only
-maxtile pair Maximum rendering tile size [(1024,768)]
-maxviewport pair Maximum viewport size [(0,0)]
@@ -8231,7 +8279,8 @@ Options (negate by replacing - with -no):
-pdfreload Automatically reload document in pdfviewer [false]
-pdfreloaddelay usec Delay before attempting initial pdf reload [750000]
-position pair Initial 3D rendering screen position [(0,0)]
--prc Embed 3D PRC graphics in PDF output [true]
+-prc Embed 3D PRC graphics in PDF output [false]
+-prerender resolution Prerender V3D objects (0 implies vector output) [0]
-prompt string Prompt [> ]
-prompt2 string Continuation prompt for multiline input [..]
-q,-quiet Suppress welcome text and noninteractive stdout [false]
@@ -8261,7 +8310,9 @@ Options (negate by replacing - with -no):
-viewportmargin pair Horizontal and vertical 3D viewport margin [(0.5,0.5)]
-wait Wait for child processes to finish before exiting [false]
-warn string Enable warning; command-line only
+-webgl2 Use webgl2 if available [false]
-where Show where listed variables are declared [false]
+-wsl Set to WSL mode when running asy inside WSL. [false]
-xasy Special interactive mode for xasy [false]
-zoomPinchCap limit WebGL maximum zoom pinch [100]
-zoomPinchFactor n WebGL zoom pinch sensitivity [10]
@@ -8357,7 +8408,7 @@ value '(0,0)' species center alignment.
'Asymptote' code on the command line as a string. It is not necessary
to terminate the string with a semicolon. Multiple '-c' options are
executed in the order they are given. For example
-asy -c 2+2 -c "sin(1)" -c "size(100); draw(unitsquare)"
+asy -c 2+2 -c "sin(1)" -c "size(100); draw(unitsquare)"
produces the output
4
0.841470984807897
@@ -8423,7 +8474,7 @@ using the symbol '%' in the next line input at the prompt. For example:
> currentpicture
<picture currentpicture>
> %.size(200,0)
->
+>
The '%' symbol, when used as a variable, is shorthand for the
identifier 'operator answer', which is set by the prompt after each
@@ -8476,7 +8527,7 @@ g.clip("unitcircle")
g.label("\"$O$\", (0,0), SW")

-File: asymptote.info, Node: GUI, Next: PostScript to Asymptote, Prev: Interactive mode, Up: Top
+File: asymptote.info, Node: GUI, Next: Command-Line Interface, Prev: Interactive mode, Up: Top
11 Graphical User Interface
***************************
@@ -8536,9 +8587,99 @@ added to another frame are not grouped together by default: their
elements will be individually deconstructed (*note add::).

-File: asymptote.info, Node: PostScript to Asymptote, Next: Help, Prev: GUI, Up: Top
+File: asymptote.info, Node: Command-Line Interface, Next: PostScript to Asymptote, Prev: GUI, Up: Top
+
+12 Command-Line Interface
+*************************
-12 'PostScript' to 'Asymptote'
+'Asymptote' code may be sent to the <http://asymptote.ualberta.ca>
+server directly from the command line, specifying any options directly
+in the URL:
+
+ * SVG output:
+
+ 'curl --data-binary 'import venn;'
+ 'asymptote.ualberta.ca:10007?f=svg' | display -'
+
+ * HTML output:
+
+ 'curl --data-binary
+ @/usr/local/share/doc/asymptote/examples/Klein.asy
+ 'asymptote.ualberta.ca:10007' -o Klein.html'
+
+ * V3D output:
+
+ 'curl --data-binary 'import teapot;'
+ 'asymptote.ualberta.ca:10007?f=v3d' -o teapot.v3d'
+
+ * PDF output with rendered bitmap at 2 pixels per bp:
+
+ 'curl --data-binary 'import teapot;'
+ 'asymptote.ualberta.ca:10007?f=pdf' -o teapot.pdf'
+
+ * PDF output with rendered bitmap at 4 pixels per bp:
+
+ 'curl --data-binary 'import teapot;'
+ 'asymptote.ualberta.ca:10007?f=pdf&render=4' -o teapot.pdf'
+
+ * PRC output:
+
+ 'curl --data-binary 'import teapot;'
+ 'asymptote.ualberta.ca:10007?f=pdf&prc' -o teapot.pdf'
+
+ * PRC output with rendered preview bitmap at 4 pixels per bp:
+
+ 'curl --data-binary 'import teapot;'
+ 'asymptote.ualberta.ca:10007?f=pdf&prc&render=4' -o teapot.pdf'
+
+ The source code for the command-line interface is available at
+<https://github.com/vectorgraphics/asymptote-http-server>.
+
+
+File: asymptote.info, Node: Language server protocol, Next: PostScript to Asymptote, Prev: Command-Line Interface, Up: Top
+
+13 Language server protocol
+***************************
+
+Under 'UNIX' and 'MacOS X', 'Asymptote' supports features of the
+Language Server Protocol (LSP)
+(https://en.wikipedia.org/wiki/Language_Server_Protocol), including
+function signature and variable matching. Under 'MSWindows',
+'Asymptote' currently supports LSP only when compiled within the
+'Windows Subsystem for Linux'.
+
+ 'Emacs' users can enable the 'Asymptote' language server protocol by
+installing 'lsp-mode' using the following procedure:
+
+ * Add to the '.emacs' initialization file:
+ (require 'package)
+ (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
+ (package-initialize)
+
+ * Launch emacs and execute
+ M-x package-refresh-contents
+ M-x package-install
+ and select 'lsp-mode'.
+
+ * Add to the '.emacs' initialization file:
+ (require 'lsp-mode)
+ (add-to-list 'lsp-language-id-configuration '(asy-mode . "asymptote"))
+
+ (lsp-register-client
+ (make-lsp-client :new-connection (lsp-stdio-connection '("asy" "-lsp"))
+ :activation-fn (lsp-activate-on "asymptote")
+ :major-modes '(asy-mode)
+ :server-id 'asyls
+ )
+ )
+
+ * Launch emacs and execute
+ M-x lsp
+
+
+File: asymptote.info, Node: PostScript to Asymptote, Next: Help, Prev: Command-Line Interface, Up: Top
+
+14 'PostScript' to 'Asymptote'
******************************
The excellent 'PostScript' editor 'pstoedit' (version 3.50 or later;
@@ -8557,7 +8698,7 @@ If the line widths aren't quite correct, try giving 'pstoedit' the

File: asymptote.info, Node: Help, Next: Debugger, Prev: PostScript to Asymptote, Up: Top
-13 Help
+15 Help
*******
A list of frequently asked questions (FAQ) is maintained at
@@ -8591,7 +8732,7 @@ generates such segmentation faults along with your bug report).

File: asymptote.info, Node: Debugger, Next: Credits, Prev: Help, Up: Top
-14 Debugger
+16 Debugger
***********
Asymptote now includes a line-based (as opposed to code-based) debugger
@@ -8657,7 +8798,7 @@ void breakpoint(code s=quote{});

File: asymptote.info, Node: Credits, Next: Index, Prev: Debugger, Up: Top
-15 Acknowledgments
+17 Acknowledgments
******************
Financial support for the development of 'Asymptote' was generously
@@ -8673,11 +8814,13 @@ author of the program 'MetaPost' that inspired the development of
The authors of 'Asymptote' are Andy Hammerlindl, John Bowman, and Tom
Prince. Sean Healy designed the 'Asymptote' logo. Other contributors
include Orest Shardt, Jesse Frohlich, Michail Vidiassov, Charles Staats,
-Philippe Ivaldi, Olivier Guibe', Radoslav Marinov, Jeff Samuelson, Chris
+Philippe Ivaldi, Olivier Guibé, Radoslav Marinov, Jeff Samuelson, Chris
Savage, Jacques Pienaar, Mark Henning, Steve Melenchuk, Martin Wiebusch,
Stefan Knorr, and Supakorn "Jamie" Rassameemasmuang. Pedram Emami
-developed the 'Asymptote Web Application' at
-<http://asymptote.ualberta.ca>.
+developed the 'Asymptote Web Application' hosted at
+<http://asymptote.ualberta.ca>:
+
+ <https://github.com/vectorgraphics/asymptote-http-server>

File: asymptote.info, Node: Index, Prev: Credits, Up: Top
@@ -8727,9 +8870,9 @@ Index
* ---: Bezier curves. (line 84)
* -=: Self & prefix operators.
(line 6)
-* -c: Options. (line 195)
-* -l: Options. (line 214)
-* -u: Options. (line 205)
+* -c: Options. (line 204)
+* -l: Options. (line 223)
+* -u: Options. (line 214)
* -V: Configuring. (line 6)
* -V <1>: Drawing in batch mode.
(line 16)
@@ -8742,7 +8885,7 @@ Index
* 2D graphs: graph. (line 6)
* 3D graphs: graph3. (line 6)
* 3D grids: grid3. (line 6)
-* 3D PostScript: three. (line 639)
+* 3D PostScript: three. (line 652)
* :: Arithmetic & logical.
(line 61)
* ::: Bezier curves. (line 70)
@@ -8779,9 +8922,10 @@ Index
* abs2: Data types. (line 65)
* abs2 <1>: Data types. (line 144)
* absolute: Configuring. (line 43)
+* absolute <1>: three. (line 241)
* accel: Paths and guides. (line 126)
* accel <1>: Paths and guides. (line 132)
-* accel <2>: three. (line 540)
+* accel <2>: three. (line 553)
* access: Import. (line 6)
* access <1>: Import. (line 45)
* acknowledgments: Credits. (line 6)
@@ -8795,8 +8939,8 @@ Index
(line 217)
* add <1>: Frames and pictures.
(line 231)
-* add <2>: three. (line 312)
-* addViews: three. (line 433)
+* add <2>: three. (line 329)
+* addViews: three. (line 446)
* adjust: Pens. (line 123)
* Ai: Mathematical functions.
(line 48)
@@ -8805,10 +8949,10 @@ Index
* Ai_deriv: Mathematical functions.
(line 48)
* alias: Structures. (line 62)
-* alias <1>: Arrays. (line 179)
+* alias <1>: Arrays. (line 183)
* Align: label. (line 12)
-* aligndir: Options. (line 187)
-* all: Arrays. (line 338)
+* aligndir: Options. (line 196)
+* all: Arrays. (line 341)
* Allow: Pens. (line 363)
* and: Bezier curves. (line 56)
* AND: Arithmetic & logical.
@@ -8820,22 +8964,22 @@ Index
* animation: animation. (line 6)
* animation <1>: animation. (line 6)
* annotate: annotate. (line 6)
-* antialias: three. (line 254)
-* antialias <1>: Options. (line 157)
+* antialias: three. (line 261)
+* antialias <1>: Options. (line 166)
* append: Files. (line 38)
* append <1>: Arrays. (line 39)
* arc: Paths and guides. (line 24)
* Arc: Paths and guides. (line 37)
-* arc <1>: three. (line 323)
+* arc <1>: three. (line 340)
* ArcArrow: draw. (line 26)
-* ArcArrow3: three. (line 606)
+* ArcArrow3: three. (line 619)
* ArcArrows: draw. (line 26)
-* ArcArrows3: three. (line 606)
+* ArcArrows3: three. (line 619)
* arclength: Paths and guides. (line 153)
-* arclength <1>: three. (line 540)
+* arclength <1>: three. (line 553)
* arcpoint: Paths and guides. (line 163)
* arctime: Paths and guides. (line 157)
-* arctime <1>: three. (line 540)
+* arctime <1>: three. (line 553)
* arguments: Default arguments. (line 6)
* arithmetic operators: Arithmetic & logical.
(line 6)
@@ -8849,10 +8993,10 @@ Index
* arrow keys: Drawing in interactive mode.
(line 11)
* arrow keys <1>: GUI usage. (line 6)
-* Arrow3: three. (line 606)
+* Arrow3: three. (line 619)
* arrows: draw. (line 26)
* Arrows: draw. (line 26)
-* Arrows3: three. (line 606)
+* Arrows3: three. (line 619)
* as: Import. (line 67)
* ascii: Data types. (line 309)
* ascii <1>: Data types. (line 309)
@@ -8875,7 +9019,7 @@ Index
* Asymptote Web Application: Description. (line 6)
* asymptote.sty: LaTeX usage. (line 6)
* asymptote.xml: Editing modes. (line 48)
-* ASYMPTOTE_CONFIG: Options. (line 128)
+* ASYMPTOTE_CONFIG: Options. (line 137)
* atan: Mathematical functions.
(line 6)
* aTan: Mathematical functions.
@@ -8889,13 +9033,13 @@ Index
(line 276)
* attach <1>: LaTeX usage. (line 50)
* attach <2>: graph. (line 406)
-* autoadjust: three. (line 398)
-* autoimport: Options. (line 124)
-* automatic scaling: graph. (line 690)
-* automatic scaling <1>: graph. (line 690)
+* autoadjust: three. (line 415)
+* autoimport: Options. (line 133)
+* automatic scaling: graph. (line 710)
+* automatic scaling <1>: graph. (line 710)
* axialshade: fill. (line 43)
-* axis: graph. (line 905)
-* axis <1>: graph. (line 988)
+* axis: graph. (line 924)
+* axis <1>: graph. (line 1007)
* axis <2>: graph3. (line 66)
* axis <3>: graph3. (line 82)
* azimuth: Data types. (line 154)
@@ -8904,11 +9048,11 @@ Index
* background <1>: three. (line 97)
* background color: Frames and pictures.
(line 180)
-* BackView: three. (line 426)
+* BackView: three. (line 439)
* Bar: draw. (line 19)
-* Bar3: three. (line 606)
+* Bar3: three. (line 619)
* Bars: draw. (line 19)
-* Bars3: three. (line 606)
+* Bars3: three. (line 619)
* barsize: draw. (line 19)
* base modules: Base modules. (line 6)
* basealign: Pens. (line 181)
@@ -8917,30 +9061,30 @@ Index
(line 6)
* beep: Data types. (line 382)
* BeginArcArrow: draw. (line 26)
-* BeginArcArrow3: three. (line 606)
+* BeginArcArrow3: three. (line 619)
* BeginArrow: draw. (line 26)
-* BeginArrow3: three. (line 606)
+* BeginArrow3: three. (line 619)
* BeginBar: draw. (line 19)
-* BeginBar3: three. (line 606)
+* BeginBar3: three. (line 619)
* BeginDotMargin: draw. (line 42)
-* BeginDotMargin3: three. (line 622)
+* BeginDotMargin3: three. (line 635)
* BeginMargin: draw. (line 42)
-* BeginMargin3: three. (line 622)
+* BeginMargin3: three. (line 635)
* BeginPenMargin: draw. (line 42)
-* BeginPenMargin2: three. (line 622)
-* BeginPenMargin3: three. (line 622)
+* BeginPenMargin2: three. (line 635)
+* BeginPenMargin3: three. (line 635)
* BeginPoint: label. (line 55)
* Bessel: Mathematical functions.
(line 48)
* bevel: flowchart. (line 72)
* beveljoin: Pens. (line 149)
* Bezier curves: Bezier curves. (line 6)
-* Bezier patch: three. (line 118)
-* Bezier triangle: three. (line 118)
-* bezulate: three. (line 136)
+* Bezier patch: three. (line 128)
+* Bezier triangle: three. (line 128)
+* bezulate: three. (line 146)
* Bi: Mathematical functions.
(line 48)
-* Billboard: three. (line 510)
+* Billboard: three. (line 523)
* binary: Files. (line 80)
* binary format: Files. (line 80)
* binary operators: Arithmetic & logical.
@@ -8948,7 +9092,7 @@ Index
* binarytree: binarytree. (line 6)
* Bi_deriv: Mathematical functions.
(line 48)
-* black stripes: three. (line 254)
+* black stripes: three. (line 261)
* Blank: draw. (line 26)
* block.bottom: flowchart. (line 19)
* block.bottomleft: flowchart. (line 19)
@@ -8967,7 +9111,7 @@ Index
(line 6)
* Bottom: graph. (line 132)
* BottomTop: graph. (line 138)
-* BottomView: three. (line 426)
+* BottomView: three. (line 439)
* bounding box: Frames and pictures.
(line 180)
* Bounds: graph3. (line 21)
@@ -8975,15 +9119,15 @@ Index
(line 25)
* box <1>: Frames and pictures.
(line 130)
-* box <2>: three. (line 345)
-* box <3>: three. (line 347)
+* box <2>: three. (line 362)
+* box <3>: three. (line 364)
* bp: Drawing in batch mode.
(line 23)
* brace: Paths and guides. (line 51)
* break: Programming. (line 48)
* breakpoints: Debugger. (line 21)
* brick: Pens. (line 285)
-* broken axis: graph. (line 801)
+* broken axis: graph. (line 821)
* bug reports: Help. (line 19)
* buildcycle: Paths and guides. (line 270)
* Button-1: GUI. (line 6)
@@ -8994,7 +9138,7 @@ Index
* CAD: CAD. (line 6)
* calculateTransform: Frames and pictures.
(line 118)
-* camera: three. (line 392)
+* camera: three. (line 409)
* casts: Casts. (line 6)
* cbrt: Mathematical functions.
(line 6)
@@ -9002,7 +9146,7 @@ Index
* ceil: Mathematical functions.
(line 26)
* Center: label. (line 60)
-* center: three. (line 375)
+* center: three. (line 392)
* checker: Pens. (line 285)
* Chinese: Pens. (line 244)
* choose: Mathematical functions.
@@ -9011,7 +9155,7 @@ Index
(line 48)
* circle: Paths and guides. (line 10)
* Circle: Paths and guides. (line 18)
-* circle <1>: three. (line 319)
+* circle <1>: three. (line 336)
* circle <2>: flowchart. (line 61)
* circlebarframe: markers. (line 18)
* CJK: Pens. (line 244)
@@ -9034,26 +9178,28 @@ Index
* colorless: Pens. (line 57)
* colors: Pens. (line 54)
* comma: Files. (line 65)
-* comma-separated-value mode: Arrays. (line 370)
+* comma-separated-value mode: Arrays. (line 374)
+* command-line interface: Command-Line Interface.
+ (line 6)
* command-line options: Configuring. (line 91)
* command-line options <1>: Options. (line 6)
* comment character: Files. (line 16)
* compass directions: Labels. (line 18)
* Compiling from UNIX source: Compiling from UNIX source.
(line 6)
-* complement: Arrays. (line 145)
-* concat: Arrays. (line 175)
+* complement: Arrays. (line 149)
+* concat: Arrays. (line 179)
* conditional: Programming. (line 26)
* conditional <1>: Arithmetic & logical.
(line 61)
* config: Configuring. (line 74)
-* config <1>: Options. (line 128)
+* config <1>: Options. (line 137)
* configuration file: Configuring. (line 20)
-* configuration file <1>: Options. (line 128)
+* configuration file <1>: Options. (line 137)
* configuring: Configuring. (line 6)
* conj: Data types. (line 62)
* constructors: Structures. (line 91)
-* context: Options. (line 157)
+* context: Options. (line 166)
* continue: Programming. (line 48)
* continue <1>: Debugger. (line 31)
* contour: contour. (line 6)
@@ -9064,10 +9210,10 @@ Index
* convert: Configuring. (line 74)
* convert <1>: Files. (line 159)
* convert <2>: animation. (line 6)
-* convert <3>: Options. (line 157)
-* convertOptions: Options. (line 143)
+* convert <3>: Options. (line 166)
+* convertOptions: Options. (line 152)
* Coons shading: fill. (line 78)
-* copy: Arrays. (line 172)
+* copy: Arrays. (line 176)
* cos: Mathematical functions.
(line 6)
* Cos: Mathematical functions.
@@ -9082,16 +9228,16 @@ Index
* cross <2>: graph. (line 480)
* crossframe: markers. (line 22)
* crosshatch: Pens. (line 302)
-* csv: Arrays. (line 370)
+* csv: Arrays. (line 374)
* CTZ: Arithmetic & logical.
(line 68)
-* cubicroots: Arrays. (line 327)
+* cubicroots: Arrays. (line 331)
* curl: Bezier curves. (line 66)
* curl <1>: three. (line 6)
* curlSpecifier: Paths and guides. (line 408)
* currentlight: three. (line 76)
* currentpen: Pens. (line 6)
-* currentprojection: three. (line 423)
+* currentprojection: three. (line 436)
* curve: slopefield. (line 20)
* custom axis types: graph. (line 141)
* custom mark routine: graph. (line 577)
@@ -9103,7 +9249,7 @@ Index
* cyclic: Paths and guides. (line 85)
* cyclic <1>: Paths and guides. (line 376)
* cyclic <2>: Arrays. (line 39)
-* cyclic <3>: three. (line 540)
+* cyclic <3>: three. (line 553)
* Cyrillic: Pens. (line 237)
* dashdotted: Pens. (line 102)
* dashed: Pens. (line 102)
@@ -9117,7 +9263,7 @@ Index
* default arguments: Default arguments. (line 6)
* defaultformat: graph. (line 175)
* DefaultHead: draw. (line 26)
-* DefaultHead3: three. (line 606)
+* DefaultHead3: three. (line 619)
* defaultpen: Pens. (line 49)
* defaultpen <1>: Pens. (line 122)
* defaultpen <2>: Pens. (line 127)
@@ -9135,17 +9281,17 @@ Index
* delete: Files. (line 154)
* delete <1>: Arrays. (line 39)
* description: Description. (line 6)
-* devicepixelratio: three. (line 174)
-* diagonal: Arrays. (line 312)
+* devicepixelratio: three. (line 184)
+* diagonal: Arrays. (line 316)
* diamond: flowchart. (line 54)
* diffuse: three. (line 76)
* diffusepen: three. (line 66)
-* dimension: Arrays. (line 375)
+* dimension: Arrays. (line 379)
* dir: Search paths. (line 9)
* dir <1>: Data types. (line 90)
* dir <2>: Data types. (line 181)
* dir <3>: Paths and guides. (line 109)
-* dir <4>: three. (line 540)
+* dir <4>: three. (line 553)
* direction specifier: Bezier curves. (line 6)
* directory: Files. (line 26)
* dirSpecifier: Paths and guides. (line 390)
@@ -9157,14 +9303,14 @@ Index
* dot: draw. (line 83)
* dot <1>: Data types. (line 103)
* dot <2>: Data types. (line 194)
-* dot <3>: Arrays. (line 267)
-* dot <4>: Arrays. (line 270)
+* dot <3>: Arrays. (line 271)
+* dot <4>: Arrays. (line 274)
* DotMargin: draw. (line 42)
-* DotMargin3: three. (line 622)
+* DotMargin3: three. (line 635)
* DotMargins: draw. (line 42)
-* DotMargins3: three. (line 622)
+* DotMargins3: three. (line 635)
* dotted: Pens. (line 102)
-* double deferred drawing: three. (line 297)
+* double deferred drawing: three. (line 314)
* double precision: Files. (line 80)
* draw: Drawing commands. (line 34)
* draw <1>: draw. (line 6)
@@ -9172,15 +9318,15 @@ Index
* draw <2>: draw. (line 113)
* Draw <1>: Frames and pictures.
(line 160)
-* draw <3>: three. (line 144)
+* draw <3>: three. (line 154)
* drawing commands: Drawing commands. (line 6)
* drawline: math. (line 9)
* drawtree: drawtree. (line 6)
* dvips: Configuring. (line 74)
-* dvipsOptions: Options. (line 143)
+* dvipsOptions: Options. (line 152)
* dvisvgm: Configuring. (line 74)
-* dvisvgm <1>: Options. (line 162)
-* dvisvgmOptions: Options. (line 143)
+* dvisvgm <1>: Options. (line 171)
+* dvisvgmOptions: Options. (line 152)
* E: Labels. (line 18)
* E <1>: Mathematical functions.
(line 48)
@@ -9195,34 +9341,34 @@ Index
* else: Programming. (line 26)
* emacs: Editing modes. (line 6)
* embed: embed. (line 6)
-* Embedded: three. (line 510)
+* Embedded: three. (line 523)
* emissivepen: three. (line 66)
* empty: Frames and pictures.
(line 7)
* EndArcArrow: draw. (line 26)
-* EndArcArrow3: three. (line 606)
+* EndArcArrow3: three. (line 619)
* EndArrow: draw. (line 26)
-* EndArrow3: three. (line 606)
+* EndArrow3: three. (line 619)
* EndBar: draw. (line 19)
-* EndBar3: three. (line 606)
+* EndBar3: three. (line 619)
* EndDotMargin: draw. (line 42)
-* EndDotMargin3: three. (line 622)
+* EndDotMargin3: three. (line 635)
* endl: Files. (line 65)
* EndMargin: draw. (line 42)
-* EndMargin3: three. (line 622)
+* EndMargin3: three. (line 635)
* EndPenMargin: draw. (line 42)
-* EndPenMargin2: three. (line 622)
-* EndPenMargin3: three. (line 622)
+* EndPenMargin2: three. (line 635)
+* EndPenMargin3: three. (line 635)
* EndPoint: label. (line 55)
* envelope: Frames and pictures.
(line 25)
* environment variables: Configuring. (line 95)
* eof: Files. (line 97)
-* eof <1>: Arrays. (line 352)
+* eof <1>: Arrays. (line 356)
* eol: Files. (line 97)
-* eol <1>: Arrays. (line 352)
+* eol <1>: Arrays. (line 356)
* EPS: label. (line 78)
-* EPS <1>: Options. (line 157)
+* EPS <1>: Options. (line 166)
* erase: Drawing in interactive mode.
(line 11)
* erase <1>: Data types. (line 257)
@@ -9259,20 +9405,20 @@ Index
* extension: Paths and guides. (line 246)
* extension <1>: MetaPost. (line 10)
* external: embed. (line 11)
-* extrude: three. (line 534)
+* extrude: three. (line 547)
* F: Mathematical functions.
(line 48)
* fabs: Mathematical functions.
(line 6)
-* face: three. (line 646)
+* face: three. (line 659)
* factorial: Mathematical functions.
(line 39)
* Fedora: UNIX binary distributions.
(line 15)
* feynman: feynman. (line 6)
-* fft: Arrays. (line 245)
-* fft <1>: Arrays. (line 259)
-* fft <2>: Arrays. (line 263)
+* fft: Arrays. (line 249)
+* fft <1>: Arrays. (line 263)
+* fft <2>: Arrays. (line 267)
* FFTW: Compiling from UNIX source.
(line 62)
* file: Files. (line 6)
@@ -9290,12 +9436,12 @@ Index
* filloutside: fill. (line 27)
* fillrule: Pens. (line 164)
* find: Data types. (line 242)
-* find <1>: Arrays. (line 154)
-* findall: Arrays. (line 159)
+* find <1>: Arrays. (line 158)
+* findall: Arrays. (line 163)
* firstcut: Paths and guides. (line 262)
* fit: Frames and pictures.
(line 113)
-* fit3: three. (line 310)
+* fit3: three. (line 327)
* fixedscaling: Frames and pictures.
(line 81)
* floor: Mathematical functions.
@@ -9313,13 +9459,13 @@ Index
* fontsize: Pens. (line 192)
* for: Programming. (line 26)
* format: Data types. (line 290)
-* format <1>: Options. (line 157)
+* format <1>: Options. (line 166)
* forum: Help. (line 6)
* frame: Frames and pictures.
(line 7)
* freshnel0: three. (line 66)
* from: Import. (line 16)
-* FrontView: three. (line 426)
+* FrontView: three. (line 439)
* function declarations: Functions. (line 79)
* Function shading: fill. (line 100)
* function shading: fill. (line 100)
@@ -9340,8 +9486,8 @@ Index
* git: Git. (line 6)
* globalwrite: Files. (line 40)
* globalwrite <1>: Files. (line 154)
-* glOptions: three. (line 254)
-* glOptions <1>: Options. (line 143)
+* glOptions: three. (line 261)
+* glOptions <1>: Options. (line 152)
* GNU Scientific Library: Mathematical functions.
(line 48)
* gouraudshade: fill. (line 63)
@@ -9350,20 +9496,21 @@ Index
* graph: graph. (line 6)
* graph3: graph3. (line 6)
* graphic: label. (line 78)
-* graphic <1>: Options. (line 162)
+* graphic <1>: Options. (line 171)
* graphical user interface: GUI. (line 6)
+* graphwithderiv: graph. (line 670)
* gray: Pens. (line 25)
* grayscale: Pens. (line 25)
* Grayscale: palette. (line 9)
* grid: Pens. (line 285)
-* grid <1>: graph. (line 746)
+* grid <1>: graph. (line 766)
* grid3: grid3. (line 6)
* gs: Configuring. (line 20)
* GSL: Compiling from UNIX source.
(line 62)
* gsl: Mathematical functions.
(line 48)
-* gsOptions: Options. (line 143)
+* gsOptions: Options. (line 152)
* GUI: GUI. (line 6)
* GUI installation: GUI installation. (line 6)
* GUI usage: GUI usage. (line 6)
@@ -9381,38 +9528,40 @@ Index
* hex <1>: Pens. (line 64)
* hexadecimal: Data types. (line 306)
* hexadecimal <1>: Pens. (line 62)
-* hidden surface removal: three. (line 646)
+* hidden surface removal: three. (line 659)
* histogram: Mathematical functions.
(line 39)
* history: Files. (line 147)
* history <1>: Interactive mode. (line 54)
* historylines: Interactive mode. (line 57)
* HookHead: draw. (line 26)
-* HookHead3: three. (line 606)
+* HookHead3: three. (line 619)
* Horizontal: flowchart. (line 77)
-* HTML5: three. (line 223)
+* HTML5: three. (line 233)
* htmlviewer: Configuring. (line 20)
* htmlviewer <1>: Configuring. (line 43)
-* htmlviewerOptions: Options. (line 143)
-* hyperrefOptions: Options. (line 143)
+* htmlviewerOptions: Options. (line 152)
+* hyperrefOptions: Options. (line 152)
* hypot: Mathematical functions.
(line 6)
* I: Mathematical functions.
(line 48)
-* iconify: three. (line 254)
+* ibl: three. (line 104)
+* iconify: three. (line 261)
* identity: Transforms. (line 24)
* identity <1>: Mathematical functions.
(line 6)
-* identity <2>: Arrays. (line 309)
-* identity4: three. (line 478)
+* identity <2>: Arrays. (line 313)
+* identity4: three. (line 491)
* if: Programming. (line 26)
* IgnoreAspect: Frames and pictures.
(line 63)
* image: palette. (line 33)
* image <1>: palette. (line 58)
+* image-based lighting: three. (line 104)
* ImageMagick: Configuring. (line 74)
* ImageMagick <1>: animation. (line 6)
-* ImageMagick <2>: Options. (line 157)
+* ImageMagick <2>: Options. (line 166)
* images: palette. (line 6)
* implicit casts: Casts. (line 6)
* implicit linear solver: MetaPost. (line 10)
@@ -9441,7 +9590,7 @@ Index
* inside: Paths and guides. (line 294)
* inside <1>: Paths and guides. (line 299)
* inside <2>: Paths and guides. (line 305)
-* insphere: three. (line 569)
+* insphere: three. (line 582)
* inst: Debugger. (line 35)
* installation: Installation. (line 6)
* int: Data types. (line 30)
@@ -9460,23 +9609,23 @@ Index
* interpolate: interpolate. (line 6)
* intersect: Paths and guides. (line 195)
* intersect <1>: math. (line 13)
-* intersect <2>: three. (line 540)
+* intersect <2>: three. (line 553)
* intersectionpoint: Paths and guides. (line 238)
* intersectionpoint <1>: math. (line 17)
-* intersectionpoint <2>: three. (line 540)
+* intersectionpoint <2>: three. (line 553)
* intersectionpoints: Paths and guides. (line 242)
-* intersectionpoints <1>: three. (line 540)
-* intersectionpoints <2>: three. (line 553)
+* intersectionpoints <1>: three. (line 553)
+* intersectionpoints <2>: three. (line 566)
* intersections: Paths and guides. (line 206)
* intersections <1>: Paths and guides. (line 213)
-* intersections <2>: three. (line 540)
-* intersections <3>: three. (line 546)
+* intersections <2>: three. (line 553)
+* intersections <3>: three. (line 559)
* InTicks: graph3. (line 35)
* intMax: Data types. (line 30)
* intMin: Data types. (line 30)
* inverse: Transforms. (line 16)
-* inverse <1>: Arrays. (line 315)
-* invert: three. (line 468)
+* inverse <1>: Arrays. (line 319)
+* invert: three. (line 481)
* invisible: Pens. (line 43)
* isnan: Data types. (line 35)
* i_scaled: Mathematical functions.
@@ -9495,7 +9644,7 @@ Index
* keepAspect <1>: Frames and pictures.
(line 63)
* keepAspect <2>: LaTeX usage. (line 50)
-* keyboard bindings:: three. (line 201)
+* keyboard bindings:: three. (line 211)
* keys: Arrays. (line 39)
* keyword: Named arguments. (line 37)
* keyword-only: Named arguments. (line 37)
@@ -9508,7 +9657,7 @@ Index
* label <1>: label. (line 6)
* Label <1>: label. (line 14)
* Label <2>: graph. (line 330)
-* label <2>: three. (line 504)
+* label <2>: three. (line 517)
* labelpath: labelpath. (line 6)
* labelpath3: labelpath3. (line 6)
* labelx: graph. (line 330)
@@ -9516,9 +9665,11 @@ Index
* Landscape: Frames and pictures.
(line 104)
* language context: Pens. (line 235)
+* language server protocol: Language server protocol.
+ (line 6)
* lastcut: Paths and guides. (line 266)
* lasy-mode: Editing modes. (line 6)
-* latex: Options. (line 157)
+* latex: Options. (line 166)
* LaTeX NFSS fonts: Pens. (line 206)
* LaTeX usage: LaTeX usage. (line 6)
* latexmk: LaTeX usage. (line 30)
@@ -9526,13 +9677,13 @@ Index
* latticeshade: fill. (line 32)
* layer: Drawing commands. (line 16)
* leastsquares: stats. (line 6)
-* leastsquares <1>: graph. (line 929)
+* leastsquares <1>: graph. (line 948)
* Left: graph. (line 269)
* LeftRight: graph. (line 275)
* LeftSide: label. (line 60)
* LeftTicks: graph. (line 160)
* LeftTicks <1>: graph. (line 233)
-* LeftView: three. (line 426)
+* LeftView: three. (line 439)
* legend: Drawing commands. (line 34)
* legend <1>: draw. (line 65)
* legend <2>: graph. (line 424)
@@ -9544,22 +9695,22 @@ Index
* length <3>: Paths and guides. (line 76)
* length <4>: Paths and guides. (line 373)
* length <5>: Arrays. (line 39)
-* length <6>: three. (line 540)
+* length <6>: three. (line 553)
* letter: Configuring. (line 68)
* lexorder: math. (line 63)
* lexorder <1>: math. (line 66)
* libcurl: Import. (line 94)
-* libgs: Options. (line 162)
+* libgs: Options. (line 171)
* libm routines: Mathematical functions.
(line 6)
* libsigsegv: Functions. (line 100)
* libsigsegv <1>: Help. (line 27)
* light: three. (line 76)
* limits: graph. (line 639)
-* line: Arrays. (line 352)
-* line <1>: Arrays. (line 356)
-* line mode: Arrays. (line 352)
-* Linear: graph. (line 690)
+* line: Arrays. (line 356)
+* line <1>: Arrays. (line 360)
+* line mode: Arrays. (line 356)
+* Linear: graph. (line 710)
* linecap: Pens. (line 139)
* linejoin: Pens. (line 149)
* lineskip: Pens. (line 192)
@@ -9568,37 +9719,39 @@ Index
* locale: Data types. (line 316)
* log: Mathematical functions.
(line 6)
-* Log: graph. (line 690)
-* log-log graph: graph. (line 724)
+* Log: graph. (line 710)
+* log-log graph: graph. (line 744)
* log10: Mathematical functions.
(line 6)
* log1p: Mathematical functions.
(line 6)
-* log2 graph: graph. (line 780)
-* logarithmic graph: graph. (line 724)
+* log2 graph: graph. (line 800)
+* logarithmic graph: graph. (line 744)
* logical operators: Arithmetic & logical.
(line 6)
* longdashdotted: Pens. (line 102)
* longdashed: Pens. (line 102)
* longitude: Data types. (line 169)
* loop: Programming. (line 26)
-* lualatex: Options. (line 157)
-* luatex: Options. (line 157)
+* LSP: Language server protocol.
+ (line 6)
+* lualatex: Options. (line 166)
+* luatex: Options. (line 166)
* MacOS X binary distributions: MacOS X binary distributions.
(line 6)
* MacOS X configuration: Compiling from UNIX source.
(line 48)
* makepen: Pens. (line 338)
-* map: Arrays. (line 131)
-* map <1>: Arrays. (line 136)
+* map: Arrays. (line 135)
+* map <1>: Arrays. (line 140)
* map <2>: map. (line 6)
* Margin: draw. (line 42)
* Margin <1>: draw. (line 42)
-* Margin3: three. (line 622)
-* Margin3 <1>: three. (line 622)
+* Margin3: three. (line 635)
+* Margin3 <1>: three. (line 635)
* Margins: draw. (line 42)
-* margins: three. (line 303)
-* Margins3: three. (line 622)
+* margins: three. (line 320)
+* Margins3: three. (line 635)
* mark: graph. (line 480)
* markangle: markers. (line 35)
* marker: graph. (line 480)
@@ -9613,14 +9766,14 @@ Index
* max: Paths and guides. (line 279)
* max <1>: Frames and pictures.
(line 7)
-* max <2>: Arrays. (line 226)
-* max <3>: Arrays. (line 236)
-* max <4>: three. (line 540)
+* max <2>: Arrays. (line 230)
+* max <3>: Arrays. (line 240)
+* max <4>: three. (line 553)
* maxbound: Data types. (line 134)
* maxbound <1>: Data types. (line 205)
-* maxtile: three. (line 254)
+* maxtile: three. (line 261)
* maxtimes: Paths and guides. (line 233)
-* maxviewport: three. (line 254)
+* maxviewport: three. (line 261)
* metallic: three. (line 66)
* MetaPost: MetaPost. (line 6)
* MetaPost ... : Bezier curves. (line 70)
@@ -9630,17 +9783,17 @@ Index
* MetaPost whatever: MetaPost. (line 10)
* Microsoft Windows: Microsoft Windows. (line 6)
* MidArcArrow: draw. (line 26)
-* MidArcArrow3: three. (line 606)
+* MidArcArrow3: three. (line 619)
* MidArrow: draw. (line 26)
-* MidArrow3: three. (line 606)
+* MidArrow3: three. (line 619)
* MidPoint: label. (line 55)
* midpoint: Paths and guides. (line 180)
* min: Paths and guides. (line 275)
* min <1>: Frames and pictures.
(line 7)
-* min <2>: Arrays. (line 221)
-* min <3>: Arrays. (line 231)
-* min <4>: three. (line 540)
+* min <2>: Arrays. (line 225)
+* min <3>: Arrays. (line 235)
+* min <4>: three. (line 553)
* minbound: Data types. (line 131)
* minbound <1>: Data types. (line 202)
* minipage: label. (line 116)
@@ -9649,16 +9802,16 @@ Index
* miterlimit: Pens. (line 159)
* mktemp: Files. (line 48)
* mm: Figure size. (line 18)
-* mobile browser: three. (line 223)
+* mobile browser: three. (line 233)
* mode: Files. (line 80)
* mode <1>: Files. (line 93)
* monotonic: graph. (line 36)
* mouse: GUI. (line 6)
-* mouse bindings: three. (line 182)
+* mouse bindings: three. (line 192)
* mouse wheel: GUI usage. (line 6)
* Move: Pens. (line 375)
* MoveQuiet: Pens. (line 381)
-* multisample: three. (line 174)
+* multisample: three. (line 184)
* N: Labels. (line 18)
* name: Files. (line 93)
* named arguments: Named arguments. (line 6)
@@ -9684,12 +9837,12 @@ Index
* noglobalread <1>: Files. (line 40)
* nolight: three. (line 76)
* NoMargin: draw. (line 42)
-* NoMargin3: three. (line 622)
+* NoMargin3: three. (line 635)
* None: draw. (line 19)
* None <1>: draw. (line 26)
* none: Files. (line 65)
-* normal: three. (line 526)
-* nosafe: Options. (line 182)
+* normal: three. (line 539)
+* nosafe: Options. (line 191)
* NOT: Arithmetic & logical.
(line 68)
* notaknot: graph. (line 36)
@@ -9701,23 +9854,23 @@ Index
(line 140)
* nullpen <2>: Frames and pictures.
(line 149)
-* NURBS: three. (line 402)
-* O: three. (line 315)
+* NURBS: three. (line 419)
+* O: three. (line 332)
* obj: obj. (line 6)
-* oblique: three. (line 358)
-* obliqueX: three. (line 365)
-* obliqueY: three. (line 371)
-* obliqueZ: three. (line 358)
+* oblique: three. (line 375)
+* obliqueX: three. (line 382)
+* obliqueY: three. (line 388)
+* obliqueZ: three. (line 375)
* ode: ode. (line 6)
* offset: Pens. (line 123)
-* offset <1>: Options. (line 187)
+* offset <1>: Options. (line 196)
* OmitTick: graph. (line 223)
* OmitTickInterval: graph. (line 223)
* OmitTickIntervals: graph. (line 223)
* opacity: Pens. (line 254)
* opacity <1>: three. (line 66)
* open: Files. (line 12)
-* OpenGL: three. (line 174)
+* OpenGL: three. (line 184)
* operator: User-defined operators.
(line 6)
* operator +(...string[] a).: Data types. (line 284)
@@ -9734,15 +9887,15 @@ Index
* OR: Arithmetic & logical.
(line 68)
* orient: Data types. (line 108)
-* orient <1>: three. (line 557)
+* orient <1>: three. (line 570)
* orientation: Frames and pictures.
(line 104)
-* orthographic: three. (line 375)
-* outformat: three. (line 174)
+* orthographic: three. (line 392)
+* outformat: three. (line 184)
* outprefix: Frames and pictures.
(line 91)
* output: Files. (line 38)
-* output <1>: Options. (line 157)
+* output <1>: Options. (line 166)
* OutTicks: graph3. (line 35)
* overloading functions: Functions. (line 55)
* overwrite: Pens. (line 360)
@@ -9754,7 +9907,7 @@ Index
(line 186)
* pair: Figure size. (line 6)
* pair <1>: Data types. (line 46)
-* pairs: Arrays. (line 241)
+* pairs: Arrays. (line 245)
* paperheight: Configuring. (line 68)
* papertype: Configuring. (line 68)
* paperwidth: Configuring. (line 68)
@@ -9763,7 +9916,7 @@ Index
* parametrized curve: graph. (line 639)
* partialsum: math. (line 49)
* partialsum <1>: math. (line 52)
-* patch-dependent colors: three. (line 109)
+* patch-dependent colors: three. (line 119)
* path: Paths. (line 6)
* path <1>: Paths and guides. (line 7)
* path <2>: three. (line 42)
@@ -9775,38 +9928,38 @@ Index
* patterns: Pens. (line 271)
* patterns <1>: patterns. (line 6)
* PBR: three. (line 74)
-* PDF: Options. (line 157)
-* pdflatex: Options. (line 157)
-* pdfreloadOptions: Options. (line 143)
+* PDF: Options. (line 166)
+* pdflatex: Options. (line 166)
+* pdfreloadOptions: Options. (line 152)
* pdfviewer: Configuring. (line 20)
-* pdfviewerOptions: Options. (line 143)
+* pdfviewerOptions: Options. (line 152)
* pen: Pens. (line 6)
* PenMargin: draw. (line 42)
-* PenMargin2: three. (line 622)
-* PenMargin3: three. (line 622)
+* PenMargin2: three. (line 635)
+* PenMargin3: three. (line 635)
* PenMargins: draw. (line 42)
-* PenMargins2: three. (line 622)
-* PenMargins3: three. (line 622)
+* PenMargins2: three. (line 635)
+* PenMargins3: three. (line 635)
* periodic: graph. (line 36)
* perl: LaTeX usage. (line 30)
* perpendicular: geometry. (line 6)
-* perspective: three. (line 402)
+* perspective: three. (line 419)
* physically based rendering: three. (line 74)
* picture: Frames and pictures.
(line 39)
* picture alignment: Frames and pictures.
(line 231)
* piecewisestraight: Paths and guides. (line 92)
-* pixel: three. (line 629)
+* pixel: three. (line 642)
* Pl: Mathematical functions.
(line 48)
* plain: plain. (line 6)
-* planar: three. (line 118)
-* plane: three. (line 341)
-* planeproject: three. (line 523)
+* planar: three. (line 128)
+* plane: three. (line 358)
+* planeproject: three. (line 536)
* point: Paths and guides. (line 95)
* point <1>: Paths and guides. (line 379)
-* point <2>: three. (line 540)
+* point <2>: three. (line 553)
* polar: Data types. (line 149)
* polargraph: graph. (line 88)
* polygon: graph. (line 480)
@@ -9814,9 +9967,9 @@ Index
* Portrait: Frames and pictures.
(line 104)
* position: three. (line 76)
-* position <1>: three. (line 174)
+* position <1>: three. (line 184)
* postcontrol: Paths and guides. (line 146)
-* postcontrol <1>: three. (line 540)
+* postcontrol <1>: three. (line 553)
* postfix operators: Self & prefix operators.
(line 19)
* postscript: Frames and pictures.
@@ -9825,10 +9978,10 @@ Index
* PostScript subpath: Paths. (line 23)
* pow10: Mathematical functions.
(line 6)
-* prc: three. (line 272)
+* prc: three. (line 279)
* precision: Files. (line 97)
* precontrol: Paths and guides. (line 139)
-* precontrol <1>: three. (line 540)
+* precontrol <1>: three. (line 553)
* prefix operators: Self & prefix operators.
(line 6)
* private: Structures. (line 6)
@@ -9836,15 +9989,15 @@ Index
* pstoedit: PostScript to Asymptote.
(line 6)
* psviewer: Configuring. (line 20)
-* psviewerOptions: Options. (line 143)
+* psviewerOptions: Options. (line 152)
* pt: Figure size. (line 18)
* public: Structures. (line 6)
* push: Arrays. (line 39)
* Python usage: Interactive mode. (line 72)
-* quadraticroots: Arrays. (line 318)
-* quadraticroots <1>: Arrays. (line 323)
+* quadraticroots: Arrays. (line 322)
+* quadraticroots <1>: Arrays. (line 327)
* quarticroots: math. (line 22)
-* quick reference: Description. (line 88)
+* quick reference: Description. (line 91)
* quit: Drawing in interactive mode.
(line 11)
* quit <1>: Interactive mode. (line 54)
@@ -9860,15 +10013,15 @@ Index
* radians: Mathematical functions.
(line 17)
* radius: Paths and guides. (line 135)
-* radius <1>: three. (line 540)
+* radius <1>: three. (line 553)
* Rainbow: palette. (line 12)
* rand: Mathematical functions.
(line 39)
* randMax: Mathematical functions.
(line 39)
-* read: Arrays. (line 392)
+* read: Arrays. (line 396)
* reading: Files. (line 12)
-* reading string arrays: Arrays. (line 362)
+* reading string arrays: Arrays. (line 366)
* readline: Files. (line 139)
* real: Data types. (line 35)
* realDigits: Data types. (line 35)
@@ -9878,7 +10031,7 @@ Index
* realmult: Data types. (line 100)
* rectangle: flowchart. (line 34)
* recursion: Functions. (line 100)
-* reference: Description. (line 88)
+* reference: Description. (line 91)
* reflect: Transforms. (line 42)
* Relative: label. (line 50)
* Relative <1>: label. (line 60)
@@ -9888,8 +10041,8 @@ Index
(line 6)
* rename: Files. (line 156)
* render: three. (line 46)
-* render <1>: three. (line 174)
-* render <2>: Options. (line 157)
+* render <1>: three. (line 184)
+* render <2>: Options. (line 166)
* replace: Data types. (line 270)
* resetdefaultpen: Pens. (line 387)
* rest arguments: Rest arguments. (line 6)
@@ -9900,8 +10053,8 @@ Index
* reverse: Data types. (line 266)
* reverse <1>: Paths and guides. (line 183)
* reverse <2>: Paths and guides. (line 382)
-* reverse <3>: Arrays. (line 141)
-* reverse <4>: three. (line 540)
+* reverse <3>: Arrays. (line 145)
+* reverse <4>: three. (line 553)
* rewind: Files. (line 97)
* rfind: Data types. (line 247)
* rgb: Pens. (line 30)
@@ -9913,9 +10066,9 @@ Index
* RightSide: label. (line 60)
* RightTicks: graph. (line 160)
* RightTicks <1>: graph. (line 233)
-* RightView: three. (line 426)
+* RightView: three. (line 439)
* Rotate: label. (line 36)
-* rotate: three. (line 494)
+* rotate: three. (line 507)
* Rotate(pair z): label. (line 39)
* round: Mathematical functions.
(line 26)
@@ -9928,7 +10081,7 @@ Index
* runtime imports: Import. (line 102)
* Russian: Pens. (line 237)
* S: Labels. (line 18)
-* safe: Options. (line 182)
+* safe: Options. (line 191)
* save: Frames and pictures.
(line 288)
* saveline: Files. (line 139)
@@ -9936,21 +10089,21 @@ Index
* scale: Pens. (line 123)
* scale <1>: Transforms. (line 34)
* scale <2>: Transforms. (line 36)
-* scale <3>: graph. (line 690)
-* Scale <1>: graph. (line 707)
-* scale <4>: three. (line 493)
-* scale3: three. (line 491)
-* scaled graph: graph. (line 670)
+* scale <3>: graph. (line 710)
+* Scale <1>: graph. (line 727)
+* scale <4>: three. (line 506)
+* scale3: three. (line 504)
+* scaled graph: graph. (line 690)
* scientific graph: graph. (line 387)
* scroll: Files. (line 113)
-* search: Arrays. (line 162)
-* search <1>: Arrays. (line 168)
+* search: Arrays. (line 166)
+* search <1>: Arrays. (line 172)
* search paths: Search paths. (line 6)
* Seascape: Frames and pictures.
(line 110)
-* secondary axis: graph. (line 833)
-* secondaryX: graph. (line 833)
-* secondaryY: graph. (line 833)
+* secondary axis: graph. (line 853)
+* secondaryX: graph. (line 853)
+* secondaryY: graph. (line 853)
* seconds: Data types. (line 330)
* seek: Files. (line 97)
* seekeof: Files. (line 97)
@@ -9960,7 +10113,7 @@ Index
(line 6)
* sequence: Arrays. (line 118)
* settings: Configuring. (line 20)
-* settings <1>: Options. (line 128)
+* settings <1>: Options. (line 137)
* sgn: Mathematical functions.
(line 26)
* shading: fill. (line 32)
@@ -9968,12 +10121,12 @@ Index
* shift: Transforms. (line 26)
* shift <1>: Transforms. (line 28)
* shift <2>: Transforms. (line 46)
-* shift <3>: three. (line 483)
+* shift <3>: three. (line 496)
* shiftless: Transforms. (line 46)
* shininess: three. (line 66)
* shipout: Frames and pictures.
(line 91)
-* showtarget: three. (line 375)
+* showtarget: three. (line 392)
* Si: Mathematical functions.
(line 48)
* signedint: Files. (line 80)
@@ -9993,9 +10146,9 @@ Index
* singlereal <1>: Files. (line 93)
* sinh: Mathematical functions.
(line 6)
-* SixViews: three. (line 441)
-* SixViewsFR: three. (line 441)
-* SixViewsUS: three. (line 441)
+* SixViews: three. (line 454)
+* SixViewsFR: three. (line 454)
+* SixViewsUS: three. (line 454)
* size: Figure size. (line 6)
* size <1>: Paths and guides. (line 81)
* size <2>: Paths and guides. (line 370)
@@ -10003,9 +10156,9 @@ Index
(line 48)
* size <4>: Frames and pictures.
(line 74)
-* size <5>: three. (line 540)
-* size <6>: Options. (line 157)
-* size3: three. (line 300)
+* size <5>: three. (line 553)
+* size <6>: Options. (line 166)
+* size3: three. (line 317)
* Slant: label. (line 42)
* slant: Transforms. (line 38)
* sleep: Data types. (line 376)
@@ -10021,11 +10174,11 @@ Index
(line 48)
* solid: Pens. (line 102)
* solids: solids. (line 6)
-* solve: Arrays. (line 287)
-* solve <1>: Arrays. (line 303)
-* sort: Arrays. (line 182)
-* sort <1>: Arrays. (line 186)
-* sort <2>: Arrays. (line 201)
+* solve: Arrays. (line 291)
+* solve <1>: Arrays. (line 307)
+* sort: Arrays. (line 186)
+* sort <1>: Arrays. (line 190)
+* sort <2>: Arrays. (line 205)
* specular: three. (line 76)
* specularfactor: three. (line 76)
* specularpen: three. (line 66)
@@ -10049,7 +10202,7 @@ Index
* stop: Debugger. (line 10)
* straight: Paths and guides. (line 88)
* Straight: graph. (line 30)
-* straight <1>: three. (line 540)
+* straight <1>: three. (line 553)
* strftime: Data types. (line 321)
* strftime <1>: Data types. (line 346)
* string: Data types. (line 208)
@@ -10061,21 +10214,22 @@ Index
* struct: Structures. (line 6)
* structures: Structures. (line 6)
* subpath: Paths and guides. (line 186)
-* subpath <1>: three. (line 540)
+* subpath <1>: three. (line 553)
* subpictures: Frames and pictures.
(line 113)
* substr: Data types. (line 262)
-* sum: Arrays. (line 216)
+* sum: Arrays. (line 220)
* superpath: Paths. (line 23)
* Suppress: Pens. (line 367)
* SuppressQuiet: Pens. (line 371)
* surface: three. (line 46)
-* surface <1>: three. (line 118)
-* surface <2>: three. (line 132)
-* surface <3>: graph3. (line 99)
-* SVG: Options. (line 162)
+* surface <1>: three. (line 104)
+* surface <2>: three. (line 128)
+* surface <3>: three. (line 142)
+* surface <4>: graph3. (line 99)
+* SVG: Options. (line 171)
* system: Data types. (line 354)
-* system <1>: Options. (line 182)
+* system <1>: Options. (line 191)
* syzygy: syzygy. (line 6)
* tab: Files. (line 65)
* tab completion: Drawing in interactive mode.
@@ -10086,22 +10240,22 @@ Index
(line 20)
* tanh: Mathematical functions.
(line 6)
-* target: three. (line 375)
+* target: three. (line 392)
* tell: Files. (line 97)
* tension: Bezier curves. (line 56)
* tension <1>: three. (line 6)
* tensionSpecifier: Paths and guides. (line 402)
* tensor product shading: fill. (line 78)
* tensorshade: fill. (line 78)
-* tessellation: three. (line 144)
+* tessellation: three. (line 154)
* tex: Frames and pictures.
(line 305)
-* tex <1>: Options. (line 157)
+* tex <1>: Options. (line 166)
* TeX fonts: Pens. (line 213)
* TeX string: Data types. (line 208)
* texcommand: Configuring. (line 74)
* TeXHead: draw. (line 26)
-* TeXHead3: three. (line 606)
+* TeXHead3: three. (line 619)
* texpath: Configuring. (line 74)
* texpath <1>: label. (line 113)
* texpreamble: Frames and pictures.
@@ -10111,13 +10265,13 @@ Index
* textbook graph: graph. (line 360)
* tgz: UNIX binary distributions.
(line 6)
-* thick: three. (line 156)
-* thin: three. (line 156)
+* thick: three. (line 166)
+* thin: three. (line 166)
* this: Structures. (line 6)
* three: three. (line 6)
-* ThreeViews: three. (line 441)
-* ThreeViewsFR: three. (line 441)
-* ThreeViewsUS: three. (line 441)
+* ThreeViews: three. (line 454)
+* ThreeViewsFR: three. (line 454)
+* ThreeViewsUS: three. (line 454)
* tick: graph. (line 330)
* ticks: graph. (line 160)
* Ticks: graph. (line 160)
@@ -10132,28 +10286,28 @@ Index
* times: Paths and guides. (line 220)
* times <1>: Paths and guides. (line 224)
* Top: graph. (line 135)
-* TopView: three. (line 426)
+* TopView: three. (line 439)
* trace: Debugger. (line 50)
* trailingzero: graph. (line 175)
* transform: Transforms. (line 6)
-* transform <1>: three. (line 515)
-* transform3: three. (line 478)
+* transform <1>: three. (line 528)
+* transform3: three. (line 491)
* transparency: Pens. (line 254)
* transparent: three. (line 97)
-* transpose: Arrays. (line 208)
-* transpose <1>: Arrays. (line 211)
+* transpose: Arrays. (line 212)
+* transpose <1>: Arrays. (line 215)
* tree: tree. (line 6)
* trembling: trembling. (line 6)
* triangle: geometry. (line 6)
-* triangles: three. (line 144)
+* triangles: three. (line 154)
* triangulate: contour. (line 149)
-* tridiagonal: Arrays. (line 274)
+* tridiagonal: Arrays. (line 278)
* trigonometric integrals: Mathematical functions.
(line 48)
* triple: Data types. (line 137)
* TrueMargin: draw. (line 42)
-* TrueMargin3: three. (line 622)
-* tube: three. (line 156)
+* TrueMargin3: three. (line 635)
+* tube: three. (line 166)
* tube <1>: tube. (line 6)
* tutorial: Tutorial. (line 6)
* type1cm: Pens. (line 192)
@@ -10167,16 +10321,16 @@ Index
(line 165)
* UnFill <2>: Frames and pictures.
(line 168)
-* uniform: Arrays. (line 150)
+* uniform: Arrays. (line 154)
* uninstall: Uninstall. (line 6)
* unique: math. (line 59)
* unit: Data types. (line 83)
* unit <1>: Data types. (line 174)
* unitbox: Paths. (line 44)
-* unitbox <1>: three. (line 347)
+* unitbox <1>: three. (line 364)
* unitcircle: Paths. (line 17)
* unitcircle <1>: Paths. (line 17)
-* unitcircle <2>: three. (line 315)
+* unitcircle <2>: three. (line 332)
* unitrand: Mathematical functions.
(line 39)
* unitsize: Figure size. (line 39)
@@ -10186,7 +10340,7 @@ Index
(line 6)
* unpacking: Rest arguments. (line 39)
* unravel: Import. (line 29)
-* up: three. (line 375)
+* up: three. (line 392)
* update: Files. (line 38)
* UpsideDown: Frames and pictures.
(line 104)
@@ -10199,47 +10353,48 @@ Index
* user-defined operators: User-defined operators.
(line 6)
* usleep: Data types. (line 379)
+* v3d: three. (line 300)
* value: math. (line 34)
* value <1>: math. (line 37)
* var: Variable initializers.
(line 55)
* variable initializers: Variable initializers.
(line 6)
-* vectorfield: graph. (line 1004)
-* vectorfield <1>: graph. (line 1043)
+* vectorfield: graph. (line 1023)
+* vectorfield <1>: graph. (line 1062)
* vectorfield3: graph3. (line 157)
-* vectorization: Arrays. (line 331)
+* vectorization: Arrays. (line 335)
* verbatim: Frames and pictures.
(line 297)
-* vertex-dependent colors: three. (line 109)
+* vertex-dependent colors: three. (line 119)
* Vertical: flowchart. (line 77)
* Viewport: three. (line 76)
* viewportheight: LaTeX usage. (line 50)
-* viewportmargin: three. (line 303)
-* viewportsize: three. (line 303)
+* viewportmargin: three. (line 320)
+* viewportsize: three. (line 320)
* viewportwidth: LaTeX usage. (line 50)
-* views: three. (line 272)
+* views: three. (line 279)
* vim: Editing modes. (line 32)
* virtual functions: Structures. (line 182)
* void: Data types. (line 10)
* W: Labels. (line 18)
-* WebGL: three. (line 223)
+* WebGL: three. (line 233)
* whatever: Paths and guides. (line 246)
* Wheel: palette. (line 22)
* wheel mouse: GUI. (line 6)
* while: Programming. (line 48)
* White: three. (line 76)
-* white-space string delimiter mode: Arrays. (line 362)
+* white-space string delimiter mode: Arrays. (line 366)
* width: LaTeX usage. (line 50)
* windingnumber: Paths and guides. (line 283)
-* word: Arrays. (line 362)
+* word: Arrays. (line 366)
* write: Files. (line 57)
-* write <1>: Arrays. (line 401)
-* X: three. (line 315)
+* write <1>: Arrays. (line 405)
+* X: three. (line 332)
* xasy: GUI. (line 6)
* xaxis3: graph3. (line 7)
* xdr: Files. (line 80)
-* xelatex: Options. (line 157)
+* xelatex: Options. (line 166)
* XEquals: graph. (line 265)
* xequals: graph. (line 278)
* xlimits: graph. (line 639)
@@ -10248,10 +10403,10 @@ Index
* xpart: Data types. (line 94)
* xpart <1>: Data types. (line 185)
* xscale: Transforms. (line 30)
-* xscale3: three. (line 485)
+* xscale3: three. (line 498)
* xtick: graph. (line 330)
-* XY: three. (line 500)
-* XY <1>: three. (line 515)
+* XY: three. (line 513)
+* XY <1>: three. (line 528)
* XYEquals: graph3. (line 21)
* XYZero: graph3. (line 21)
* XZEquals: graph3. (line 21)
@@ -10261,7 +10416,7 @@ Index
(line 6)
* Y <1>: Mathematical functions.
(line 48)
-* Y <2>: three. (line 315)
+* Y <2>: three. (line 332)
* yaxis3: graph3. (line 7)
* YEquals: graph. (line 128)
* yequals: graph. (line 278)
@@ -10269,14 +10424,14 @@ Index
* ypart: Data types. (line 97)
* ypart <1>: Data types. (line 188)
* yscale: Transforms. (line 32)
-* yscale3: three. (line 487)
+* yscale3: three. (line 500)
* ytick: graph. (line 330)
-* YX: three. (line 515)
-* YZ: three. (line 515)
+* YX: three. (line 528)
+* YZ: three. (line 528)
* YZEquals: graph3. (line 21)
* YZero: graph. (line 123)
* YZZero: graph3. (line 21)
-* Z: three. (line 315)
+* Z: three. (line 332)
* zaxis3: graph3. (line 7)
* zeroTransform: Transforms. (line 44)
* zerowinding: Pens. (line 164)
@@ -10293,158 +10448,165 @@ Index
* zeta: Mathematical functions.
(line 48)
* zpart: Data types. (line 191)
-* zscale3: three. (line 489)
-* ZX: three. (line 515)
-* ZX <1>: three. (line 515)
-* ZY: three. (line 515)
+* zscale3: three. (line 502)
+* ZX: three. (line 528)
+* ZX <1>: three. (line 528)
+* ZY: three. (line 528)

Tag Table:
Node: Top570
-Node: Description7200
-Node: Installation11286
-Node: UNIX binary distributions12332
-Node: MacOS X binary distributions13455
-Node: Microsoft Windows14043
-Node: Configuring15250
-Node: Search paths19862
-Node: Compiling from UNIX source20870
-Node: Editing modes24021
-Node: Git26443
-Node: Uninstall26950
-Node: Tutorial27296
-Node: Drawing in batch mode28143
-Node: Drawing in interactive mode29019
-Node: Figure size30051
-Node: Labels31646
-Node: Paths32474
-Ref: unitcircle33090
-Node: Drawing commands34988
-Node: draw36796
-Ref: arrows37978
-Node: fill43494
-Ref: gradient shading44540
-Node: clip49154
-Node: label49903
-Ref: Label50503
-Node: Bezier curves56361
-Node: Programming60261
-Ref: array iteration62014
-Node: Data types62181
-Ref: format72949
-Node: Paths and guides77395
-Ref: circle77649
-Ref: extension87349
-Node: Pens94159
-Ref: fillrule101850
-Ref: basealign102754
-Ref: transparency106436
-Ref: makepen110030
-Ref: overwrite110914
-Node: Transforms112128
-Node: Frames and pictures114067
-Ref: envelope115225
-Ref: size116318
-Ref: unitsize117305
-Ref: shipout118378
-Ref: filltype120729
-Ref: add124142
-Ref: add about125084
-Ref: tex128114
-Node: Files129010
-Ref: cd130067
-Ref: scroll134969
-Node: Variable initializers137887
-Node: Structures140604
-Node: Operators148182
-Node: Arithmetic & logical148496
-Node: Self & prefix operators150866
-Node: User-defined operators151660
-Node: Implicit scaling152573
-Node: Functions153136
-Ref: stack overflow156278
-Node: Default arguments156560
-Node: Named arguments157316
-Node: Rest arguments159886
-Node: Mathematical functions163008
-Node: Arrays167665
-Ref: sort174954
-Ref: tridiagonal177865
-Ref: solve179096
-Node: Slices183236
-Node: Casts187144
-Node: Import189414
-Node: Static194995
-Node: LaTeX usage197881
-Node: Base modules204376
-Node: plain206853
-Node: simplex207527
-Node: math207800
-Node: interpolate210383
-Node: geometry210662
-Node: trembling211256
-Node: stats211525
-Node: patterns211784
-Node: markers212019
-Node: map213878
-Node: tree214302
-Node: binarytree214486
-Node: drawtree215153
-Node: syzygy215354
-Node: feynman215628
-Node: roundedpath215902
-Node: animation216184
-Ref: animate216605
-Node: embed217717
-Node: slide218671
-Node: MetaPost219002
-Node: babel219718
-Node: labelpath219950
-Node: labelpath3220770
-Node: annotate221081
-Node: CAD221551
-Node: graph221861
-Ref: ticks229021
-Ref: pathmarkers242746
-Ref: marker243217
-Ref: markuniform243571
-Ref: errorbars245379
-Ref: automatic scaling249858
-Node: palette261573
-Ref: images261691
-Ref: image265865
-Ref: logimage266386
-Ref: penimage267492
-Ref: penfunctionimage267755
-Node: three268527
-Ref: PostScript3D298054
-Node: obj299792
-Node: graph3300041
-Ref: GaussianSurface305324
-Node: grid3306474
-Node: solids307259
-Node: tube308251
-Node: flowchart310481
-Node: contour315124
-Node: contour3320439
-Node: smoothcontour3320751
-Node: slopefield322472
-Node: ode323962
-Node: Options324219
-Ref: configuration file331127
-Ref: settings331127
-Ref: texengines332391
-Ref: convert332391
-Node: Interactive mode335835
-Ref: history337985
-Node: GUI339288
-Node: GUI installation339839
-Node: GUI usage340572
-Node: PostScript to Asymptote341635
-Node: Help342394
-Node: Debugger344068
-Node: Credits345824
-Node: Index346932
+Node: Description7317
+Node: Installation11527
+Node: UNIX binary distributions12573
+Node: MacOS X binary distributions13696
+Node: Microsoft Windows14284
+Node: Configuring15492
+Node: Search paths20105
+Node: Compiling from UNIX source21113
+Node: Editing modes24264
+Node: Git26686
+Node: Uninstall27193
+Node: Tutorial27539
+Node: Drawing in batch mode28386
+Node: Drawing in interactive mode29262
+Node: Figure size30294
+Node: Labels31889
+Node: Paths32717
+Ref: unitcircle33333
+Node: Drawing commands35231
+Node: draw37039
+Ref: arrows38221
+Node: fill43736
+Ref: gradient shading44782
+Node: clip49396
+Node: label50145
+Ref: Label50745
+Node: Bezier curves56602
+Node: Programming60502
+Ref: array iteration62255
+Node: Data types62422
+Ref: format73190
+Node: Paths and guides77636
+Ref: circle77890
+Ref: extension87590
+Node: Pens94400
+Ref: fillrule102091
+Ref: basealign102995
+Ref: transparency106677
+Ref: makepen110271
+Ref: overwrite111155
+Node: Transforms112369
+Node: Frames and pictures114308
+Ref: envelope115466
+Ref: size116559
+Ref: unitsize117546
+Ref: shipout118619
+Ref: filltype120970
+Ref: add124383
+Ref: add about125325
+Ref: tex128355
+Node: Files129250
+Ref: cd130307
+Ref: scroll135209
+Node: Variable initializers138127
+Node: Structures140844
+Node: Operators148417
+Node: Arithmetic & logical148731
+Node: Self & prefix operators151101
+Node: User-defined operators151895
+Node: Implicit scaling152808
+Node: Functions153371
+Ref: stack overflow156488
+Node: Default arguments156770
+Node: Named arguments157526
+Node: Rest arguments160096
+Node: Mathematical functions163217
+Node: Arrays167874
+Ref: sort175313
+Ref: tridiagonal178224
+Ref: solve179455
+Node: Slices183595
+Node: Casts187503
+Node: Import189773
+Node: Static195343
+Node: LaTeX usage198229
+Node: Base modules204743
+Node: plain207220
+Node: simplex207894
+Node: math208167
+Node: interpolate210834
+Node: geometry211113
+Node: trembling211707
+Node: stats211976
+Node: patterns212235
+Node: markers212470
+Node: map214328
+Node: tree214752
+Node: binarytree214932
+Node: drawtree215599
+Node: syzygy215800
+Node: feynman216074
+Node: roundedpath216348
+Node: animation216630
+Ref: animate217051
+Node: embed218163
+Node: slide219117
+Node: MetaPost219448
+Node: babel220164
+Node: labelpath220396
+Node: labelpath3221216
+Node: annotate221527
+Node: CAD221997
+Node: graph222307
+Ref: ticks229466
+Ref: pathmarkers243188
+Ref: marker243658
+Ref: markuniform244012
+Ref: errorbars245871
+Ref: automatic scaling251000
+Node: palette262710
+Ref: images262828
+Ref: image267002
+Ref: logimage267523
+Ref: penimage268629
+Ref: penfunctionimage268892
+Node: three269664
+Ref: PostScript3D299799
+Node: obj301537
+Node: graph3301786
+Ref: GaussianSurface307068
+Node: grid3308218
+Node: solids309003
+Node: tube309995
+Node: flowchart312225
+Node: contour316868
+Node: contour3322183
+Node: smoothcontour3322495
+Node: slopefield324214
+Node: ode325703
+Node: Options325960
+Ref: configuration file333448
+Ref: settings333448
+Ref: texengines334712
+Ref: convert334712
+Node: Interactive mode338155
+Ref: history340304
+Node: GUI341607
+Node: GUI installation342157
+Node: GUI usage342890
+Node: Command-Line Interface343953
+Node: Language server protocol345395
+Node: PostScript to Asymptote346820
+Node: Help347598
+Node: Debugger349272
+Node: Credits351028
+Node: Index352205

End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/graphics/asymptote/doc/secondaryaxis.asy b/graphics/asymptote/doc/secondaryaxis.asy
index 85143f7ace..b611eb4ed2 100644
--- a/graphics/asymptote/doc/secondaryaxis.asy
+++ b/graphics/asymptote/doc/secondaryaxis.asy
@@ -11,7 +11,7 @@ string[] columnlabel=in;
real[][] a=in;
a=transpose(a);
real[] t=a[0], susceptible=a[1], infectious=a[2], dead=a[3], larvae=a[4];
-real[] susceptibleM=a[5], exposed=a[6],infectiousM=a[7];
+real[] susceptibleM=a[5], exposed=a[6], infectiousM=a[7];
scale(true);
@@ -29,4 +29,3 @@ picture secondary=secondaryY(new void(picture pic) {
add(secondary);
label(shift(5mm*N)*"Proportion of crows",point(NW),E);
-
diff --git a/graphics/asymptote/drawelement.h b/graphics/asymptote/drawelement.h
index f561d2786d..178d433726 100644
--- a/graphics/asymptote/drawelement.h
+++ b/graphics/asymptote/drawelement.h
@@ -18,13 +18,14 @@
#include "texfile.h"
#include "prcfile.h"
#include "jsfile.h"
+#include "v3dfile.h"
#include "glrender.h"
#include "arrayop.h"
#include "material.h"
namespace camp {
-static const double pixel=1.0; // Adaptive rendering constant.
+static const double pixelResolution=1.0; // Adaptive rendering constant.
enum Interaction {EMBEDDED=0,BILLBOARD};
@@ -147,6 +148,15 @@ typedef mem::list<bbox> bboxlist;
typedef mem::map<CONST string,unsigned> groupmap;
typedef mem::vector<groupmap> groupsmap;
+typedef mem::map<CONST triple, int> centerMap;
+
+inline bool operator < (const triple& a, const triple& b) {
+ return a.getx() < b.getx() ||
+ (a.getx() == b.getx() &&
+ (a.gety() < b.gety() ||
+ (a.gety() == b.gety() &&
+ (a.getz() < b.getz()))));
+}
class drawElement : public gc
{
@@ -158,10 +168,9 @@ public:
virtual ~drawElement() {}
- static mem::vector<triple> center;
+ static mem::vector<triple> centers;
+ static centerMap centermap;
static size_t centerIndex;
- static triple lastcenter;
- static size_t lastcenterIndex;
static pen lastpen;
static const triple zero;
@@ -240,8 +249,8 @@ public:
return false;
}
- // Output to a JS file
- virtual bool write(jsfile *out) {
+ // Output to a WebGL or v3d file
+ virtual bool write(abs3Doutfile *out) {
return false;
}
@@ -256,12 +265,13 @@ public:
virtual void meshinit() {}
size_t centerindex(const triple& center) {
- if(drawElement::center.empty() || center != drawElement::lastcenter) {
- drawElement::lastcenter=center;
- drawElement::center.push_back(center);
- drawElement::lastcenterIndex=drawElement::center.size();
+ centerMap::iterator p=centermap.find(center);
+ if(p != centermap.end()) centerIndex=p->second;
+ else {
+ centers.push_back(center);
+ centermap[center]=centerIndex=centers.size();
}
- return drawElement::lastcenterIndex;
+ return centerIndex;
}
// Transform as part of a picture.
@@ -452,11 +462,9 @@ public:
};
#ifdef HAVE_LIBGLM
-void setcolors(bool colors,
- const prc::RGBAColour& diffuse,
- const prc::RGBAColour& emissive,
+void setcolors(const prc::RGBAColour& diffuse, const prc::RGBAColour& emissive,
const prc::RGBAColour& specular, double shininess,
- double metallic, double fresnel0, jsfile *out=NULL);
+ double metallic, double fresnel0, abs3Doutfile *out=NULL);
#endif
diff --git a/graphics/asymptote/drawlabel.cc b/graphics/asymptote/drawlabel.cc
index afeeeb5673..491ec4f8d0 100644
--- a/graphics/asymptote/drawlabel.cc
+++ b/graphics/asymptote/drawlabel.cc
@@ -240,9 +240,8 @@ void drawLabelPath::bounds(bbox& b, iopipestream& tex, boxvector&, bboxlist&)
bool drawLabelPath::write(texfile *out, const bbox&)
{
- bbox b=Box;
- double Hoffset=getSetting<bool>("inlinetex") ? b.right : b.left;
- b.shift(pair(-Hoffset,-b.bottom));
+ double Hoffset=getSetting<bool>("inlinetex") ? Box.right : Box.left;
+ Box=Box.shift(pair(-Hoffset,-Box.bottom));
checkbounds();
if(drawLabel::pentype.invisible()) return true;
diff --git a/graphics/asymptote/drawlayer.h b/graphics/asymptote/drawlayer.h
index 3b5b3ddeb2..e784fa1a5c 100644
--- a/graphics/asymptote/drawlayer.h
+++ b/graphics/asymptote/drawlayer.h
@@ -21,19 +21,35 @@ public:
bool islayer() {return true;}
};
-class drawNewPage : public drawLayer {
+class drawBBox : public drawLayer {
+protected:
+ bbox box;
public:
- drawNewPage() {}
+ drawBBox() : box() {}
+ drawBBox(const bbox& box) : box(box) {}
+
+ bool islayer() {return false;}
+ virtual ~drawBBox() {}
+
+ bool write(texfile *out, const bbox& b) {
+ out->BBox(box.empty ? b : box);
+ return true;
+ }
+};
+
+class drawNewPage : public drawBBox {
+public:
+ drawNewPage() : drawBBox() {}
+ drawNewPage(const bbox& box) : drawBBox(box) {}
virtual ~drawNewPage() {}
+ bool islayer() {return true;}
bool islabel() {return true;}
bool isnewpage() {return true;}
- bool write(texfile *out, const bbox&) {
- out->verbatimline(settings::latex(out->texengine) ? "\\newpage" :
- settings::context(out->texengine) ? "}\\page\\hbox{%" :
- "\\eject");
+ bool write(texfile *out, const bbox& b) {
+ out->newpage(box.empty ? b : box);
return true;
}
};
@@ -41,5 +57,7 @@ public:
}
GC_DECLARE_PTRFREE(camp::drawLayer);
+GC_DECLARE_PTRFREE(camp::drawBBox);
+GC_DECLARE_PTRFREE(camp::drawNewPage);
#endif
diff --git a/graphics/asymptote/drawpath3.cc b/graphics/asymptote/drawpath3.cc
index 088d2705db..20543e2eda 100644
--- a/graphics/asymptote/drawpath3.cc
+++ b/graphics/asymptote/drawpath3.cc
@@ -36,7 +36,7 @@ bool drawPath3::write(prcfile *out, unsigned int *, double, groupsmap&)
return true;
}
-bool drawPath3::write(jsfile *out)
+bool drawPath3::write(abs3Doutfile *out)
{
#ifdef HAVE_LIBGLM
if(invisible)
@@ -47,7 +47,7 @@ bool drawPath3::write(jsfile *out)
drawElement::centerIndex=centerIndex;
} else drawElement::centerIndex=0;
- setcolors(false,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+ setcolors(diffuse,emissive,specular,shininess,metallic,fresnel0,out);
if(straight)
out->addCurve(g.point((Int) 0),g.point((Int) 1),Min,Max);
@@ -64,7 +64,7 @@ void drawPath3::render(double size2, const triple& b, const triple& B,
#ifdef HAVE_GL
if(invisible) return;
- setcolors(false,diffuse,emissive,specular,shininess,metallic,fresnel0);
+ setcolors(diffuse,emissive,specular,shininess,metallic,fresnel0);
setMaterial(material1Data,drawMaterial1);
@@ -222,14 +222,14 @@ bool drawPixel::write(prcfile *out, unsigned int *, double, groupsmap&)
return true;
}
-bool drawPixel::write(jsfile *out)
+bool drawPixel::write(abs3Doutfile *out)
{
#ifdef HAVE_LIBGLM
if(invisible)
return true;
RGBAColour Black(0.0,0.0,0.0,color.A);
- setcolors(false,color,color,Black,1.0,0.0,0.04,out);
+ setcolors(color,color,Black,1.0,0.0,0.04,out);
out->addPixel(v,width,Min,Max);
#endif
@@ -243,7 +243,7 @@ void drawPixel::render(double size2, const triple& b, const triple& B,
if(invisible) return;
RGBAColour Black(0.0,0.0,0.0,color.A);
- setcolors(false,color,color,Black,1.0,0.0,0.04);
+ setcolors(color,color,Black,1.0,0.0,0.04);
setMaterial(material0Data,drawMaterial0);
diff --git a/graphics/asymptote/drawpath3.h b/graphics/asymptote/drawpath3.h
index 3209493bf2..c4153909ba 100644
--- a/graphics/asymptote/drawpath3.h
+++ b/graphics/asymptote/drawpath3.h
@@ -105,7 +105,7 @@ public:
}
bool write(prcfile *out, unsigned int *, double, groupsmap&);
- bool write(jsfile *out);
+ bool write(abs3Doutfile *out);
void render(double, const triple&, const triple&, double,
bool remesh);
@@ -234,7 +234,7 @@ public:
double perspective, bool remesh);
bool write(prcfile *out, unsigned int *, double, groupsmap&);
- bool write(jsfile *out);
+ bool write(abs3Doutfile *out);
drawElement *transformed(const double* t);
};
diff --git a/graphics/asymptote/drawsurface.cc b/graphics/asymptote/drawsurface.cc
index b491f20b0d..ac87bdb586 100644
--- a/graphics/asymptote/drawsurface.cc
+++ b/graphics/asymptote/drawsurface.cc
@@ -23,11 +23,9 @@ using namespace prc;
namespace camp {
-mem::vector<triple> drawElement::center;
+mem::vector<triple> drawElement::centers;
size_t drawElement::centerIndex=0;
-triple drawElement::lastcenter=0;
-size_t drawElement::lastcenterIndex=0;
-
+centerMap drawElement::centermap;
const triple drawElement::zero;
using vm::array;
@@ -53,27 +51,25 @@ void storecolor(GLfloat *colors, int i, const RGBAColour& p)
colors[i+3]=p.A;
}
-void setcolors(bool colors,
- const RGBAColour& diffuse,
- const RGBAColour& emissive,
+void setcolors(const RGBAColour& diffuse, const RGBAColour& emissive,
const RGBAColour& specular, double shininess,
- double metallic, double fresnel0, jsfile *out)
+ double metallic, double fresnel0, abs3Doutfile *out)
{
Material m=Material(glm::vec4(diffuse.R,diffuse.G,diffuse.B,diffuse.A),
glm::vec4(emissive.R,emissive.G,emissive.B,emissive.A),
glm::vec4(specular.R,specular.G,specular.B,specular.A),
shininess,metallic,fresnel0);
- MaterialMap::iterator p=materialMap.find(m);
+ auto p=materialMap.find(m);
if(p != materialMap.end()) materialIndex=p->second;
else {
- materialIndex=material.size();
+ materialIndex=materials.size();
if(materialIndex >= nmaterials)
nmaterials=min(Maxmaterials,2*nmaterials);
- material.push_back(m);
+ materials.push_back(m);
materialMap[m]=materialIndex;
if(out)
- out->addMaterial(materialIndex);
+ out->addMaterial(m);
}
}
@@ -220,25 +216,39 @@ bool drawBezierPatch::write(prcfile *out, unsigned int *, double, groupsmap&)
return true;
}
-bool drawBezierPatch::write(jsfile *out)
+bool drawBezierPatch::write(abs3Doutfile *out)
{
#ifdef HAVE_LIBGLM
if(invisible || primitive)
return true;
+ setcolors(diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+
if(billboard) {
meshinit();
drawElement::centerIndex=centerIndex;
} else drawElement::centerIndex=0;
- setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
-
out->precision(digits);
if(straight) {
triple Controls[]={controls[0],controls[12],controls[15],controls[3]};
- out->addPatch(Controls,4,Min,Max,colors,4);
- } else
- out->addPatch(controls,16,Min,Max,colors,4);
+ out->addStraightPatch(Controls,Min,Max,colors);
+ } else {
+ double prerender=renderResolution();
+ if(prerender) {
+ GLfloat c[16];
+ if(colors)
+ for(size_t i=0; i < 4; ++i)
+ storecolor(c,4*i,colors[i]);
+ S.init(prerender,colors ? c : NULL);
+ S.render(controls,straight,c);
+ drawTriangles dt(S.data,center,colors,diffuse,emissive,specular,opacity,
+ shininess,metallic,fresnel0,interaction,invisible,
+ Min,Max);
+ dt.write(out);
+ } else
+ out->addPatch(controls,Min,Max,colors);
+ }
out->precision(getSetting<Int>("digits"));
#endif
@@ -253,7 +263,7 @@ void drawBezierPatch::render(double size2, const triple& b, const triple& B,
transparent=colors ? colors[0].A+colors[1].A+colors[2].A+colors[3].A < 4.0 :
diffuse.A < 1.0;
- setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0);
+ setcolors(diffuse,emissive,specular,shininess,metallic,fresnel0);
if(transparent)
setMaterial(transparentData,drawTransparent);
@@ -466,25 +476,40 @@ bool drawBezierTriangle::write(prcfile *out, unsigned int *, double,
return true;
}
-bool drawBezierTriangle::write(jsfile *out)
+bool drawBezierTriangle::write(abs3Doutfile *out)
{
#ifdef HAVE_LIBGLM
+
if(invisible || primitive)
return true;
+ setcolors(diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+
if(billboard) {
meshinit();
drawElement::centerIndex=centerIndex;
} else drawElement::centerIndex=0;
- setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
-
out->precision(digits);
if(straight) {
triple Controls[]={controls[0],controls[6],controls[9]};
- out->addPatch(Controls,3,Min,Max,colors,3);
- } else
- out->addPatch(controls,10,Min,Max,colors,3);
+ out->addStraightBezierTriangle(Controls,Min,Max,colors);
+ } else {
+ double prerender=renderResolution();
+ if(prerender) {
+ GLfloat c[16];
+ if(colors)
+ for(size_t i=0; i < 4; ++i)
+ storecolor(c,4*i,colors[i]);
+ S.init(prerender,colors ? c : NULL);
+ S.render(controls,straight,c);
+ drawTriangles dt(S.data,center,colors,diffuse,emissive,specular,opacity,
+ shininess,metallic,fresnel0,interaction,invisible,
+ Min,Max);
+ dt.write(out);
+ } else
+ out->addBezierTriangle(controls,Min,Max,colors);
+ }
out->precision(getSetting<Int>("digits"));
#endif
@@ -499,7 +524,7 @@ void drawBezierTriangle::render(double size2, const triple& b, const triple& B,
transparent=colors ? colors[0].A+colors[1].A+colors[2].A < 3.0 :
diffuse.A < 1.0;
- setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0);
+ setcolors(diffuse,emissive,specular,shininess,metallic,fresnel0);
if(transparent)
setMaterial(transparentData,drawTransparent);
@@ -531,15 +556,14 @@ void drawBezierTriangle::render(double size2, const triple& b, const triple& B,
triple Controls0[10];
if(billboard) {
Controls=Controls0;
- for(size_t i=0; i < 10; i++) {
+ for(size_t i=0; i < 10; i++)
Controls[i]=BB.transform(controls[i]);
- }
} else {
- Controls=controls;
if(!remesh && S.Onscreen) { // Fully onscreen; no need to re-render
S.append();
return;
}
+ Controls=controls;
}
double s=perspective ? Min.getz()*perspective : 1.0; // Move to glrender
@@ -767,7 +791,7 @@ bool drawSphere::write(prcfile *out, unsigned int *, double, groupsmap&)
return true;
}
-bool drawSphere::write(jsfile *out)
+bool drawSphere::write(abs3Doutfile *out)
{
#ifdef HAVE_LIBGLM
if(invisible)
@@ -775,7 +799,7 @@ bool drawSphere::write(jsfile *out)
drawElement::centerIndex=0;
- setcolors(false,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+ setcolors(diffuse,emissive,specular,shininess,metallic,fresnel0,out);
triple O,E;
P(E,1.0,0.0,0.0);
@@ -784,7 +808,7 @@ bool drawSphere::write(jsfile *out)
double r=length(X);
if(half)
- out->addSphere(O,r,half,X.polar(false),X.azimuth(false));
+ out->addHemisphere(O,r,X.polar(false),X.azimuth(false));
else
out->addSphere(O,r);
@@ -805,7 +829,7 @@ bool drawCylinder::write(prcfile *out, unsigned int *, double, groupsmap&)
return true;
}
-bool drawCylinder::write(jsfile *out)
+bool drawCylinder::write(abs3Doutfile *out)
{
#ifdef HAVE_LIBGLM
if(invisible)
@@ -813,7 +837,7 @@ bool drawCylinder::write(jsfile *out)
drawElement::centerIndex=0;
- setcolors(false,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+ setcolors(diffuse,emissive,specular,shininess,metallic,fresnel0,out);
triple E,H,O;
P(E,1.0,0.0,0.0);
@@ -843,7 +867,7 @@ bool drawDisk::write(prcfile *out, unsigned int *, double, groupsmap&)
return true;
}
-bool drawDisk::write(jsfile *out)
+bool drawDisk::write(abs3Doutfile *out)
{
#ifdef HAVE_LIBGLM
if(invisible)
@@ -851,7 +875,7 @@ bool drawDisk::write(jsfile *out)
drawElement::centerIndex=0;
- setcolors(false,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+ setcolors(diffuse,emissive,specular,shininess,metallic,fresnel0,out);
triple E,H,O;
P(E,1.0,0.0,0.0);
@@ -867,7 +891,7 @@ bool drawDisk::write(jsfile *out)
return true;
}
-bool drawTube::write(jsfile *out)
+bool drawTube::write(abs3Doutfile *out)
{
#ifdef HAVE_LIBGLM
if(invisible)
@@ -875,7 +899,7 @@ bool drawTube::write(jsfile *out)
drawElement::centerIndex=0;
- setcolors(false,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+ setcolors(diffuse,emissive,specular,shininess,metallic,fresnel0,out);
bbox3 b;
b.add(T*m);
@@ -959,14 +983,18 @@ bool drawTriangles::write(prcfile *out, unsigned int *, double, groupsmap&)
return true;
}
-bool drawTriangles::write(jsfile *out)
+bool drawTriangles::write(abs3Doutfile *out)
{
#ifdef HAVE_LIBGLM
if(invisible)
return true;
- setcolors(nC,diffuse,emissive,specular,shininess,metallic,fresnel0,out);
+ if(billboard) {
+ meshinit();
+ drawElement::centerIndex=centerIndex;
+ } else drawElement::centerIndex=0;
+ setcolors(diffuse,emissive,specular,shininess,metallic,fresnel0,out);
out->addTriangles(nP,P,nN,N,nC,C,nI,PI,NI,CI,Min,Max);
#endif
return true;
@@ -978,30 +1006,48 @@ void drawTriangles::render(double size2, const triple& b,
{
#ifdef HAVE_GL
if(invisible) return;
-
transparent=diffuse.A < 1.0;
- if(bbox2(Min,Max).offscreen()) { // Fully offscreen
- R.Onscreen=false;
- R.data.clear();
- R.transparent=transparent;
- R.notRendered();
- return;
- }
-
- setcolors(nC,diffuse,emissive,specular,shininess,metallic,fresnel0);
+ setcolors(diffuse,emissive,specular,shininess,metallic,fresnel0);
if(transparent)
setMaterial(transparentData,drawTransparent);
else
setMaterial(triangleData,drawTriangle);
- if(!remesh && R.Onscreen) { // Fully onscreen; no need to re-render
- R.append();
+ bool offscreen;
+ if(billboard) {
+ drawElement::centerIndex=centerIndex;
+ BB.init(center);
+ offscreen=bbox2(Min,Max,BB).offscreen();
+ } else
+ offscreen=bbox2(Min,Max).offscreen();
+
+ if(offscreen) { // Fully offscreen
+ R.Onscreen=false;
+ R.data.clear();
+ R.transparent=transparent;
+ R.notRendered();
return;
}
- R.queue(nP,P,nN,N,nC,C,nI,PI,NI,CI,transparent);
+ triple *P0;
+ if(billboard) {
+ P0=new triple [nP];
+ for(size_t i=0; i < nP; i++)
+ P0[i]=BB.transform(P[i]);
+ } else {
+ if(!remesh && R.Onscreen) { // Fully onscreen; no need to re-render
+ R.append();
+ return;
+ }
+ P0=P;
+ }
+
+ R.queue(nP,P0,nN,N,nC,C,nI,PI,NI,CI,transparent);
+
+ if(billboard)
+ delete [] P0;
#endif
}
diff --git a/graphics/asymptote/drawsurface.h b/graphics/asymptote/drawsurface.h
index 9a8010a8d0..9ece42a818 100644
--- a/graphics/asymptote/drawsurface.h
+++ b/graphics/asymptote/drawsurface.h
@@ -40,9 +40,9 @@ protected:
double metallic;
double fresnel0;
bool invisible;
+ size_t centerIndex;
Interaction interaction;
bool billboard;
- size_t centerIndex;
triple Min,Max;
int digits;
@@ -68,7 +68,7 @@ public:
centerIndex=0;
}
- drawSurface(const vm::array& g, size_t ncontrols, triple center,
+ drawSurface(const vm::array& g, size_t ncontrols, const triple& center,
bool straight, const vm::array&p, double opacity,
double shininess, double metallic, double fresnel0,
const vm::array &pens, Interaction interaction, int digits,
@@ -125,6 +125,19 @@ public:
center=t*s->center;
}
+ double renderResolution() {
+ double prerender=settings::getSetting<double>("prerender");
+ if(prerender <= 0.0) return 0.0;
+ prerender=1.0/prerender;
+ double perspective=gl::orthographic ? 0.0 : 1.0/gl::zmax;
+ double s=perspective ? Min.getz()*perspective : 1.0; // Move to glrender
+ triple b(gl::xmin,gl::ymin,gl::zmin);
+ triple B(gl::xmax,gl::ymax,gl::zmax);
+ pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety()));
+ pair size2(gl::fullWidth,gl::fullHeight);
+ return prerender*size3.length()/size2.length();
+ }
+
virtual ~drawSurface() {}
bool is3D() {return true;}
@@ -132,11 +145,11 @@ public:
class drawBezierPatch : public drawSurface {
public:
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
BezierPatch S;
#endif
- drawBezierPatch(const vm::array& g, triple center, bool straight,
+ drawBezierPatch(const vm::array& g, const triple& center, bool straight,
const vm::array&p, double opacity, double shininess,
double metallic, double fresnel0, const vm::array &pens,
Interaction interaction, int digits, bool primitive) :
@@ -157,7 +170,7 @@ public:
}
bool write(prcfile *out, unsigned int *, double, groupsmap&);
- bool write(jsfile *out);
+ bool write(abs3Doutfile *out);
void render(double, const triple& b, const triple& B,
double perspective, bool remesh);
@@ -166,11 +179,11 @@ public:
class drawBezierTriangle : public drawSurface {
public:
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
BezierTriangle S;
#endif
- drawBezierTriangle(const vm::array& g, triple center, bool straight,
+ drawBezierTriangle(const vm::array& g, const triple& center, bool straight,
const vm::array&p, double opacity, double shininess,
double metallic, double fresnel0, const vm::array &pens,
Interaction interaction, int digits, bool primitive) :
@@ -191,7 +204,7 @@ public:
}
bool write(prcfile *out, unsigned int *, double, groupsmap&);
- bool write(jsfile *out);
+ bool write(abs3Doutfile *out);
void render(double, const triple& b, const triple& B,
double perspective, bool remesh);
@@ -382,11 +395,11 @@ public:
virtual void P(triple& t, double x, double y, double z);
- virtual bool write(prcfile *out, unsigned int *, double, groupsmap&) {
+ virtual bool write(prcfile *out, unsigned int *, double, groupsmap&) override {
return true;
}
- virtual bool write(jsfile *out) {return true;}
+ virtual bool write(abs3Doutfile *out) override {return true;}
virtual void transformedbounds(const double*, bbox3&) {}
virtual void transformedratio(const double*, pair&,
@@ -409,7 +422,7 @@ public:
void P(triple& t, double x, double y, double z);
bool write(prcfile *out, unsigned int *, double, groupsmap&);
- bool write(jsfile *out);
+ bool write(abs3Doutfile *out);
drawElement *transformed(const double* t) {
return new drawSphere(t,this);
@@ -428,10 +441,10 @@ public:
drawCylinder(const double* t, const drawCylinder *s) :
drawPRC(t,s), core(s->core) {}
- bool write(prcfile *out, unsigned int *, double, groupsmap&);
- bool write(jsfile *out);
+ bool write(prcfile *out, unsigned int *, double, groupsmap&) override;
+ bool write(abs3Doutfile *out) override;
- drawElement *transformed(const double* t) {
+ drawElement *transformed(const double* t) override {
return new drawCylinder(t,this);
}
};
@@ -446,10 +459,10 @@ public:
drawDisk(const double* t, const drawDisk *s) :
drawPRC(t,s) {}
- bool write(prcfile *out, unsigned int *, double, groupsmap&);
- bool write(jsfile *out);
+ bool write(prcfile *out, unsigned int *, double, groupsmap&) override;
+ bool write(abs3Doutfile *out) override;
- drawElement *transformed(const double* t) {
+ drawElement *transformed(const double* t) override {
return new drawDisk(t,this);
}
};
@@ -483,9 +496,9 @@ public:
g[i]=t*s->g[i];
}
- bool write(jsfile *out);
+ bool write(abs3Doutfile *out) override;
- drawElement *transformed(const double* t) {
+ drawElement *transformed(const double* t) override {
return new drawTube(t,this);
}
};
@@ -493,19 +506,24 @@ public:
class drawBaseTriangles : public drawElement {
protected:
-#ifdef HAVE_GL
+#ifdef HAVE_LIBGLM
Triangles R;
bool transparent;
#endif
+public:
+ bool billboard;
size_t nP;
triple* P;
+ triple center;
size_t nN;
triple* N;
size_t nI;
size_t Ni;
uint32_t (*PI)[3];
uint32_t (*NI)[3];
+ size_t centerIndex;
+ Interaction interaction;
triple Min,Max;
@@ -513,8 +531,21 @@ protected:
static const string outofrange;
public:
+ void init() {
+#ifdef HAVE_LIBOSMESA
+ billboard=false;
+#else
+ billboard=interaction == BILLBOARD;
+#endif
+ centerIndex=0;
+ }
+
drawBaseTriangles(const vm::array& v, const vm::array& vi,
- const vm::array& n, const vm::array& ni) {
+ const triple& center,
+ const vm::array& n, const vm::array& ni,
+ Interaction interaction) : center(center),
+ interaction(interaction) {
+ init();
nP=checkArray(&v);
P=new(UseGC) triple[nP];
for(size_t i=0; i < nP; ++i)
@@ -560,8 +591,45 @@ public:
} else Ni=0;
}
+#ifdef HAVE_LIBGLM
+ drawBaseTriangles(const vertexBuffer& vb, const triple& center,
+ Interaction interaction, bool isColor,
+ const triple& Min, const triple& Max) :
+ transparent(false),
+ nP(isColor ? vb.Vertices.size() : vb.vertices.size()), center(center),
+ nN(nP), nI(vb.indices.size()/3), Ni(0),
+ interaction(interaction), Min(Min), Max(Max) {
+ init();
+ assert(vb.indices.size() % 3 == 0);
+ P=new(UseGC) triple[nP];
+ N=new(UseGC) triple[nN];
+ if(!isColor) {
+ for (size_t i=0; i < vb.vertices.size(); ++i) {
+ P[i]=triple(vb.vertices[i].position[0], vb.vertices[i].position[1], vb.vertices[i].position[2]);
+ N[i]=triple(vb.vertices[i].normal[0], vb.vertices[i].normal[1], vb.vertices[i].normal[2]);
+ }
+ }
+ else {
+ for (size_t i=0; i < vb.Vertices.size(); ++i) {
+ P[i]=triple(vb.Vertices[i].position[0], vb.Vertices[i].position[1], vb.Vertices[i].position[2]);
+ N[i]=triple(vb.Vertices[i].normal[0], vb.Vertices[i].normal[1], vb.Vertices[i].normal[2]);
+ }
+ }
+
+ PI=new(UseGC) uint32_t[nI][3];
+ for (size_t i=0; i < nI; ++i) {
+ PI[i][0]=vb.indices[3 * i];
+ PI[i][1]=vb.indices[3 * i + 1];
+ PI[i][2]=vb.indices[3 * i + 2];
+ }
+ NI=PI;
+ }
+#endif
+
drawBaseTriangles(const double* t, const drawBaseTriangles *s) :
- drawElement(s->KEY), nP(s->nP), nN(s->nN), nI(s->nI), Ni(s->Ni) {
+ drawElement(s->KEY),
+ nP(s->nP), nN(s->nN), nI(s->nI), Ni(s->Ni), interaction(s->interaction) {
+ init();
P=new(UseGC) triple[nP];
for(size_t i=0; i < nP; i++)
P[i]=t*s->P[i];
@@ -574,6 +642,8 @@ public:
PIi[j]=sPIi[j];
}
+ center=t*s->center;
+
if(nN) {
N=new(UseGC) triple[nN];
if(t == NULL) {
@@ -609,6 +679,11 @@ public:
void ratio(const double* t, pair &b, double (*m)(double, double),
double fuzz, bool &first);
+ void meshinit() {
+ if(billboard)
+ centerIndex=centerindex(center);
+ }
+
virtual ~drawBaseTriangles() {}
drawElement *transformed(const double* t) {
@@ -633,13 +708,14 @@ class drawTriangles : public drawBaseTriangles {
bool invisible;
public:
- drawTriangles(const vm::array& v, const vm::array& vi,
+ drawTriangles(const vm::array& v, const vm::array& vi, const triple& center,
const vm::array& n, const vm::array& ni,
const vm::array&p, double opacity, double shininess,
double metallic, double fresnel0,
- const vm::array& c, const vm::array& ci) :
- drawBaseTriangles(v,vi,n,ni), opacity(opacity), shininess(shininess),
- metallic(metallic), fresnel0(fresnel0) {
+ const vm::array& c, const vm::array& ci,
+ Interaction interaction) :
+ drawBaseTriangles(v,vi,center,n,ni,interaction), opacity(opacity),
+ shininess(shininess), metallic(metallic), fresnel0(fresnel0) {
if(checkArray(&p) != 3)
reportError(need3pens);
@@ -680,6 +756,36 @@ public:
specular=rgba(vm::read<camp::pen>(p,2));
}
+#ifdef HAVE_LIBGLM
+ drawTriangles(vertexBuffer const& vb, const triple &center, bool isColor,
+ prc::RGBAColour diffuse,
+ prc::RGBAColour emissive,
+ prc::RGBAColour specular,
+ double opacity,
+ double shininess,
+ double metallic,
+ double fresnel0, Interaction interaction,
+ bool invisible,
+ const triple& Min, const triple& Max) :
+ drawBaseTriangles(vb,center,interaction,isColor,Min,Max),
+ nC(isColor ? vb.Vertices.size() : 0), C(nullptr),
+ CI(isColor ? PI : nullptr),
+ Ci(isColor ? Ni : 0),
+ diffuse(diffuse), emissive(emissive), specular(specular),
+ opacity(opacity), shininess(shininess),
+ metallic(metallic), fresnel0(fresnel0), invisible(invisible) {
+ if(isColor) {
+ C=new(UseGC) prc::RGBAColour[nC];
+ for(size_t i=0; i < nC; ++i) {
+ C[i].Set(vb.Vertices[i].color[0],
+ vb.Vertices[i].color[1],
+ vb.Vertices[i].color[2],
+ vb.Vertices[i].color[3]);
+ }
+ }
+ }
+#endif
+
drawTriangles(const double* t, const drawTriangles *s) :
drawBaseTriangles(t,s), nC(s->nC),
diffuse(s->diffuse), emissive(s->emissive),
@@ -707,7 +813,7 @@ public:
double perspective, bool remesh);
bool write(prcfile *out, unsigned int *, double, groupsmap&);
- bool write(jsfile *out);
+ bool write(abs3Doutfile *out);
drawElement *transformed(const double* t) {
return new drawTriangles(t,this);
diff --git a/graphics/asymptote/errormsg.cc b/graphics/asymptote/errormsg.cc
index afa307283b..637f6ae50f 100644
--- a/graphics/asymptote/errormsg.cc
+++ b/graphics/asymptote/errormsg.cc
@@ -27,7 +27,7 @@ ostream& operator<< (ostream& out, const position& pos)
string filename=pos.file->name();
if(filename != "-" && !settings::getSetting<bool>("quiet")) {
- std::ifstream fin(pos.file->name().c_str());
+ std::ifstream fin(filename.c_str());
string s;
size_t count=pos.line;
while(count > 0 && getline(fin,s)) {
diff --git a/graphics/asymptote/errormsg.h b/graphics/asymptote/errormsg.h
index 180c2309f7..eb03faa5cb 100644
--- a/graphics/asymptote/errormsg.h
+++ b/graphics/asymptote/errormsg.h
@@ -9,15 +9,17 @@
#define ERRORMSG_H
#include <iostream>
+#include <exception>
#include "common.h"
#include "settings.h"
+#include "symbolmaps.h"
using std::ostream;
-struct handled_error {}; // Exception to process next file.
-struct interrupted {}; // Exception to interrupt execution.
-struct quit {}; // Exception to quit current operation.
-struct eof {}; // Exception to exit interactive mode.
+struct handled_error : std::exception {}; // Exception to process next file.
+struct interrupted : std::exception {}; // Exception to interrupt execution.
+struct quit : std::exception {}; // Exception to quit current operation.
+struct eof : std::exception {}; // Exception to exit interactive mode.
class fileinfo : public gc {
string filename;
@@ -81,21 +83,24 @@ public:
}
}
- string filename() const
- {
+ string filename() const {
return file ? file->name() : "";
}
- size_t Line() const
- {
+ size_t Line() const {
return line;
}
- size_t Column() const
- {
+ size_t Column() const {
return column;
}
+ position shift(unsigned int offset) const {
+ position P=*this;
+ P.line -= offset;
+ return P;
+ }
+
std::pair<size_t,size_t>LineColumn() const {
return std::pair<size_t,size_t>(line,column);
}
@@ -119,6 +124,21 @@ public:
friend ostream& operator << (ostream& out, const position& pos);
+ typedef std::pair<size_t, size_t> posInFile;
+ typedef std::pair<std::string, posInFile> filePos;
+
+ explicit operator AsymptoteLsp::filePos()
+ {
+ return std::make_pair((std::string) file->name().c_str(),LineColumn());
+ }
+
+ void print(ostream& out) const
+ {
+ if (file) {
+ out << file->name() << ":" << line << "." << column;
+ }
+ }
+
// Write out just the module name and line number.
void printTerse(ostream& out) const
{
diff --git a/graphics/asymptote/examples/1overx.asy b/graphics/asymptote/examples/1overx.asy
index 9bbbf282ac..dfaa049efb 100644
--- a/graphics/asymptote/examples/1overx.asy
+++ b/graphics/asymptote/examples/1overx.asy
@@ -1,16 +1,11 @@
import graph;
size(200,IgnoreAspect);
-real f(real x) {return 1/x;};
+real f(real x) {return 1/x;}
bool3 branch(real x)
{
- static int lastsign=0;
- if(x == 0) return false;
- int sign=sgn(x);
- bool b=lastsign == 0 || sign == lastsign;
- lastsign=sign;
- return b ? true : default;
+ return x != 0;
}
draw(graph(f,-1,1,branch));
diff --git a/graphics/asymptote/examples/NURBSsurface.asy b/graphics/asymptote/examples/NURBSsurface.asy
index 4bfafefbc3..c537e5df15 100644
--- a/graphics/asymptote/examples/NURBSsurface.asy
+++ b/graphics/asymptote/examples/NURBSsurface.asy
@@ -59,7 +59,7 @@ draw(P,uknot,vknot,new pen[] {red,green,blue,magenta});
// udegree=3, vdegree=3, nu=4, nv=4;
real[] uknot={0,0,0,0,1,1,1,1};
real[] vknot={0,0,0,0,1,1,1,1};
-triple[][] P=scale3(20)*octant1.P;
+triple[][] P=scale3(20)*octant1x.P;
// Optional weights:
real[][] weights=array(P.length,array(P[0].length,1.0));
diff --git a/graphics/asymptote/examples/alignedaxis.asy b/graphics/asymptote/examples/alignedaxis.asy
index 542dcb9bc6..d32c389a74 100644
--- a/graphics/asymptote/examples/alignedaxis.asy
+++ b/graphics/asymptote/examples/alignedaxis.asy
@@ -91,7 +91,7 @@ real Aerr2(real x){return Aerr(x,0.75);}
draw(pic2p,graph(pic2p,Aerr2,1e-4,1),black+1.2);
ylimits(pic2p,-5,95);
-yaxis(pic2p,"phase (deg)",LeftRight,RightTicks(new real[] {0,45.1,90}));
+yaxis(pic2p,"phase (deg)",LeftRight,RightTicks(new real[] {0,50,90}));
xaxis(pic2p,"$f/f_\mathrm{Ny}$",BottomTop,LeftTicks(N=5));
yequals(pic2p,0,Dotted);
yequals(pic2p,45,Dotted);
diff --git a/graphics/asymptote/examples/layers.asy b/graphics/asymptote/examples/layers.asy
index 4fe745f6a3..3d80b31fb7 100644
--- a/graphics/asymptote/examples/layers.asy
+++ b/graphics/asymptote/examples/layers.asy
@@ -1,4 +1,4 @@
-usepackage("ocg");
+usepackage("ocgx2");
settings.tex="pdflatex";
size(0,150);
diff --git a/graphics/asymptote/examples/markregular.asy b/graphics/asymptote/examples/markregular.asy
index ea08b95223..8c3a51040b 100644
--- a/graphics/asymptote/examples/markregular.asy
+++ b/graphics/asymptote/examples/markregular.asy
@@ -7,11 +7,11 @@ real ymin=-2,ymax=10;
real f(real x) {return x^2;}
-marker cross=marker(scale(4)*rotate(45)*cross(4),
+marker mark=marker(scale(4)*plus,
markuniform(new pair(real t) {return Scale((t,f(t)));},
xmin,xmax,round(2*(xmax-xmin))),1bp+red);
-draw(graph(f,xmin,xmax,n=400),linewidth(1bp),cross);
+draw(graph(f,xmin,xmax,n=400),linewidth(1bp),mark);
ylimits(-2.5,10,Crop);
diff --git a/graphics/asymptote/examples/orthocenter.asy b/graphics/asymptote/examples/orthocenter.asy
index a7caaf1412..69ae5376b5 100644
--- a/graphics/asymptote/examples/orthocenter.asy
+++ b/graphics/asymptote/examples/orthocenter.asy
@@ -2,8 +2,7 @@ import geometry;
import math;
size(7cm,0);
-
-if(!settings.xasy && settings.outformat != "svg") settings.tex="pdflatex";
+settings.tex="pdflatex";
real theta=degrees(asin(0.5/sqrt(7)));
diff --git a/graphics/asymptote/examples/spectrum.asy b/graphics/asymptote/examples/spectrum.asy
index 95c5f8a0d1..c6837ec781 100644
--- a/graphics/asymptote/examples/spectrum.asy
+++ b/graphics/asymptote/examples/spectrum.asy
@@ -1,5 +1,5 @@
import graph;
-usepackage("ocg");
+usepackage("ocgx2");
settings.tex="pdflatex";
// Dan Bruton algorithm
diff --git a/graphics/asymptote/examples/strokepath.asy b/graphics/asymptote/examples/strokepath.asy
index c857150ec5..5e5b2b9a96 100644
--- a/graphics/asymptote/examples/strokepath.asy
+++ b/graphics/asymptote/examples/strokepath.asy
@@ -5,7 +5,6 @@ frame f;
// Equivalent to draw(f,g,p):
fill(f,strokepath(g,p),red);
shipout("strokepathframe",f);
-shipped=false;
size(400);
diff --git a/graphics/asymptote/examples/teapot.asy b/graphics/asymptote/examples/teapot.asy
index f3328151fd..847ffd234d 100644
--- a/graphics/asymptote/examples/teapot.asy
+++ b/graphics/asymptote/examples/teapot.asy
@@ -1,204 +1,232 @@
import three;
-import settings;
size(20cm);
currentprojection=perspective(250,-250,250);
currentlight=Viewport;
-triple[][][] Q=
+triple[][][] Q={
{
- {
{(39.68504,0,68.0315),(37.91339,0,71.75197),(40.74803,0,71.75197),(42.51969,0,68.0315)},
{(39.68504,-22.22362,68.0315),(37.91339,-21.2315,71.75197),(40.74803,-22.8189,71.75197),(42.51969,-23.81102,68.0315)},
{(22.22362,-39.68504,68.0315),(21.2315,-37.91339,71.75197),(22.8189,-40.74803,71.75197),(23.81102,-42.51969,68.0315)},
{(0,-39.68504,68.0315),(0,-37.91339,71.75197),(0,-40.74803,71.75197),(0,-42.51969,68.0315)}
- },
- {
+ },
+ {
{(0,-39.68504,68.0315),(0,-37.91339,71.75197),(0,-40.74803,71.75197),(0,-42.51969,68.0315)},
{(-22.22362,-39.68504,68.0315),(-21.2315,-37.91339,71.75197),(-22.8189,-40.74803,71.75197),(-23.81102,-42.51969,68.0315)},
{(-39.68504,-22.22362,68.0315),(-37.91339,-21.2315,71.75197),(-40.74803,-22.8189,71.75197),(-42.51969,-23.81102,68.0315)},
{(-39.68504,0,68.0315),(-37.91339,0,71.75197),(-40.74803,0,71.75197),(-42.51969,0,68.0315)}
- },
- {
+ },
+ {
{(-39.68504,0,68.0315),(-37.91339,0,71.75197),(-40.74803,0,71.75197),(-42.51969,0,68.0315)},
{(-39.68504,22.22362,68.0315),(-37.91339,21.2315,71.75197),(-40.74803,22.8189,71.75197),(-42.51969,23.81102,68.0315)},
{(-22.22362,39.68504,68.0315),(-21.2315,37.91339,71.75197),(-22.8189,40.74803,71.75197),(-23.81102,42.51969,68.0315)},
{(0,39.68504,68.0315),(0,37.91339,71.75197),(0,40.74803,71.75197),(0,42.51969,68.0315)}
- },
- {
+ },
+ {
{(0,39.68504,68.0315),(0,37.91339,71.75197),(0,40.74803,71.75197),(0,42.51969,68.0315)},
{(22.22362,39.68504,68.0315),(21.2315,37.91339,71.75197),(22.8189,40.74803,71.75197),(23.81102,42.51969,68.0315)},
{(39.68504,22.22362,68.0315),(37.91339,21.2315,71.75197),(40.74803,22.8189,71.75197),(42.51969,23.81102,68.0315)},
{(39.68504,0,68.0315),(37.91339,0,71.75197),(40.74803,0,71.75197),(42.51969,0,68.0315)}
- },
- {
+ },
+ {
{(42.51969,0,68.0315),(49.60629,0,53.1496),(56.69291,0,38.26771),(56.69291,0,25.51181)},
{(42.51969,-23.81102,68.0315),(49.60629,-27.77952,53.1496),(56.69291,-31.74803,38.26771),(56.69291,-31.74803,25.51181)},
{(23.81102,-42.51969,68.0315),(27.77952,-49.60629,53.1496),(31.74803,-56.69291,38.26771),(31.74803,-56.69291,25.51181)},
{(0,-42.51969,68.0315),(0,-49.60629,53.1496),(0,-56.69291,38.26771),(0,-56.69291,25.51181)}
- },
- {
+ },
+ {
{(0,-42.51969,68.0315),(0,-49.60629,53.1496),(0,-56.69291,38.26771),(0,-56.69291,25.51181)},
{(-23.81102,-42.51969,68.0315),(-27.77952,-49.60629,53.1496),(-31.74803,-56.69291,38.26771),(-31.74803,-56.69291,25.51181)},
{(-42.51969,-23.81102,68.0315),(-49.60629,-27.77952,53.1496),(-56.69291,-31.74803,38.26771),(-56.69291,-31.74803,25.51181)},
{(-42.51969,0,68.0315),(-49.60629,0,53.1496),(-56.69291,0,38.26771),(-56.69291,0,25.51181)}
- },
- {
+ },
+ {
{(-42.51969,0,68.0315),(-49.60629,0,53.1496),(-56.69291,0,38.26771),(-56.69291,0,25.51181)},
{(-42.51969,23.81102,68.0315),(-49.60629,27.77952,53.1496),(-56.69291,31.74803,38.26771),(-56.69291,31.74803,25.51181)},
{(-23.81102,42.51969,68.0315),(-27.77952,49.60629,53.1496),(-31.74803,56.69291,38.26771),(-31.74803,56.69291,25.51181)},
{(0,42.51969,68.0315),(0,49.60629,53.1496),(0,56.69291,38.26771),(0,56.69291,25.51181)}
- },
- {
+ },
+ {
{(0,42.51969,68.0315),(0,49.60629,53.1496),(0,56.69291,38.26771),(0,56.69291,25.51181)},
{(23.81102,42.51969,68.0315),(27.77952,49.60629,53.1496),(31.74803,56.69291,38.26771),(31.74803,56.69291,25.51181)},
{(42.51969,23.81102,68.0315),(49.60629,27.77952,53.1496),(56.69291,31.74803,38.26771),(56.69291,31.74803,25.51181)},
{(42.51969,0,68.0315),(49.60629,0,53.1496),(56.69291,0,38.26771),(56.69291,0,25.51181)}
- },
- {
+ },
+ {
{(56.69291,0,25.51181),(56.69291,0,12.7559),(42.51969,0,6.377957),(42.51969,0,4.251961)},
{(56.69291,-31.74803,25.51181),(56.69291,-31.74803,12.7559),(42.51969,-23.81102,6.377957),(42.51969,-23.81102,4.251961)},
{(31.74803,-56.69291,25.51181),(31.74803,-56.69291,12.7559),(23.81102,-42.51969,6.377957),(23.81102,-42.51969,4.251961)},
{(0,-56.69291,25.51181),(0,-56.69291,12.7559),(0,-42.51969,6.377957),(0,-42.51969,4.251961)}
- },
- {
+ },
+ {
{(0,-56.69291,25.51181),(0,-56.69291,12.7559),(0,-42.51969,6.377957),(0,-42.51969,4.251961)},
{(-31.74803,-56.69291,25.51181),(-31.74803,-56.69291,12.7559),(-23.81102,-42.51969,6.377957),(-23.81102,-42.51969,4.251961)},
{(-56.69291,-31.74803,25.51181),(-56.69291,-31.74803,12.7559),(-42.51969,-23.81102,6.377957),(-42.51969,-23.81102,4.251961)},
{(-56.69291,0,25.51181),(-56.69291,0,12.7559),(-42.51969,0,6.377957),(-42.51969,0,4.251961)}
- },
- {
+ },
+ {
{(-56.69291,0,25.51181),(-56.69291,0,12.7559),(-42.51969,0,6.377957),(-42.51969,0,4.251961)},
{(-56.69291,31.74803,25.51181),(-56.69291,31.74803,12.7559),(-42.51969,23.81102,6.377957),(-42.51969,23.81102,4.251961)},
{(-31.74803,56.69291,25.51181),(-31.74803,56.69291,12.7559),(-23.81102,42.51969,6.377957),(-23.81102,42.51969,4.251961)},
{(0,56.69291,25.51181),(0,56.69291,12.7559),(0,42.51969,6.377957),(0,42.51969,4.251961)}
- },
- {
+ },
+ {
{(0,56.69291,25.51181),(0,56.69291,12.7559),(0,42.51969,6.377957),(0,42.51969,4.251961)},
{(31.74803,56.69291,25.51181),(31.74803,56.69291,12.7559),(23.81102,42.51969,6.377957),(23.81102,42.51969,4.251961)},
{(56.69291,31.74803,25.51181),(56.69291,31.74803,12.7559),(42.51969,23.81102,6.377957),(42.51969,23.81102,4.251961)},
{(56.69291,0,25.51181),(56.69291,0,12.7559),(42.51969,0,6.377957),(42.51969,0,4.251961)}
- },
- {
+ },
+ {
{(-45.35433,0,57.40157),(-65.19685,0,57.40157),(-76.53543,0,57.40157),(-76.53543,0,51.02362)},
{(-45.35433,-8.503932,57.40157),(-65.19685,-8.503932,57.40157),(-76.53543,-8.503932,57.40157),(-76.53543,-8.503932,51.02362)},
{(-42.51969,-8.503932,63.77952),(-70.86614,-8.503932,63.77952),(-85.03937,-8.503932,63.77952),(-85.03937,-8.503932,51.02362)},
{(-42.51969,0,63.77952),(-70.86614,0,63.77952),(-85.03937,0,63.77952),(-85.03937,0,51.02362)}
- },
- {
+ },
+ {
{(-42.51969,0,63.77952),(-70.86614,0,63.77952),(-85.03937,0,63.77952),(-85.03937,0,51.02362)},
{(-42.51969,8.503932,63.77952),(-70.86614,8.503932,63.77952),(-85.03937,8.503932,63.77952),(-85.03937,8.503932,51.02362)},
{(-45.35433,8.503932,57.40157),(-65.19685,8.503932,57.40157),(-76.53543,8.503932,57.40157),(-76.53543,8.503932,51.02362)},
{(-45.35433,0,57.40157),(-65.19685,0,57.40157),(-76.53543,0,57.40157),(-76.53543,0,51.02362)}
- },
- {
+ },
+ {
{(-76.53543,0,51.02362),(-76.53543,0,44.64566),(-70.86614,0,31.88976),(-56.69291,0,25.51181)},
{(-76.53543,-8.503932,51.02362),(-76.53543,-8.503932,44.64566),(-70.86614,-8.503932,31.88976),(-56.69291,-8.503932,25.51181)},
{(-85.03937,-8.503932,51.02362),(-85.03937,-8.503932,38.26771),(-75.11811,-8.503932,26.5748),(-53.85826,-8.503932,17.00787)},
{(-85.03937,0,51.02362),(-85.03937,0,38.26771),(-75.11811,0,26.5748),(-53.85826,0,17.00787)}
- },
- {
+ },
+ {
{(-85.03937,0,51.02362),(-85.03937,0,38.26771),(-75.11811,0,26.5748),(-53.85826,0,17.00787)},
{(-85.03937,8.503932,51.02362),(-85.03937,8.503932,38.26771),(-75.11811,8.503932,26.5748),(-53.85826,8.503932,17.00787)},
{(-76.53543,8.503932,51.02362),(-76.53543,8.503932,44.64566),(-70.86614,8.503932,31.88976),(-56.69291,8.503932,25.51181)},
{(-76.53543,0,51.02362),(-76.53543,0,44.64566),(-70.86614,0,31.88976),(-56.69291,0,25.51181)}
- },
- {
+ },
+ {
{(48.18897,0,40.3937),(73.70078,0,40.3937),(65.19685,0,59.52755),(76.53543,0,68.0315)},
{(48.18897,-18.70866,40.3937),(73.70078,-18.70866,40.3937),(65.19685,-7.086619,59.52755),(76.53543,-7.086619,68.0315)},
{(48.18897,-18.70866,17.00787),(87.87401,-18.70866,23.38582),(68.0315,-7.086619,57.40157),(93.5433,-7.086619,68.0315)},
{(48.18897,0,17.00787),(87.87401,0,23.38582),(68.0315,0,57.40157),(93.5433,0,68.0315)}
- },
- {
+ },
+ {
{(48.18897,0,17.00787),(87.87401,0,23.38582),(68.0315,0,57.40157),(93.5433,0,68.0315)},
{(48.18897,18.70866,17.00787),(87.87401,18.70866,23.38582),(68.0315,7.086619,57.40157),(93.5433,7.086619,68.0315)},
{(48.18897,18.70866,40.3937),(73.70078,18.70866,40.3937),(65.19685,7.086619,59.52755),(76.53543,7.086619,68.0315)},
{(48.18897,0,40.3937),(73.70078,0,40.3937),(65.19685,0,59.52755),(76.53543,0,68.0315)}
- },
- {
+ },
+ {
{(76.53543,0,68.0315),(79.37007,0,70.15748),(82.20472,0,70.15748),(79.37007,0,68.0315)},
{(76.53543,-7.086619,68.0315),(79.37007,-7.086619,70.15748),(82.20472,-4.251961,70.15748),(79.37007,-4.251961,68.0315)},
{(93.5433,-7.086619,68.0315),(99.92125,-7.086619,70.68897),(97.79527,-4.251961,71.22047),(90.70866,-4.251961,68.0315)},
{(93.5433,0,68.0315),(99.92125,0,70.68897),(97.79527,0,71.22047),(90.70866,0,68.0315)}
- },
- {
+ },
+ {
{(93.5433,0,68.0315),(99.92125,0,70.68897),(97.79527,0,71.22047),(90.70866,0,68.0315)},
{(93.5433,7.086619,68.0315),(99.92125,7.086619,70.68897),(97.79527,4.251961,71.22047),(90.70866,4.251961,68.0315)},
{(76.53543,7.086619,68.0315),(79.37007,7.086619,70.15748),(82.20472,4.251961,70.15748),(79.37007,4.251961,68.0315)},
{(76.53543,0,68.0315),(79.37007,0,70.15748),(82.20472,0,70.15748),(79.37007,0,68.0315)}
- },
- {
+ },
+ {
+ {(5.669294,0,76.53543),(11.33858,0,72.28346),(36.85039,0,72.28346),(36.85039,0,68.0315)},
+ {(5.669294,-3.174809,76.53543),(11.33858,-6.349609,72.28346),(36.85039,-20.63622,72.28346),(36.85039,-20.63622,68.0315)},
+ {(3.174809,-5.669294,76.53543),(6.349609,-11.33858,72.28346),(20.63622,-36.85039,72.28346),(20.63622,-36.85039,68.0315)},
+ {(0,-5.669294,76.53543),(0,-11.33858,72.28346),(0,-36.85039,72.28346),(0,-36.85039,68.0315)}
+ },
+ {
+ {(0,-5.669294,76.53543),(0,-11.33858,72.28346),(0,-36.85039,72.28346),(0,-36.85039,68.0315)},
+ {(-3.174809,-5.669294,76.53543),(-6.349609,-11.33858,72.28346),(-20.63622,-36.85039,72.28346),(-20.63622,-36.85039,68.0315)},
+ {(-5.669294,-3.174809,76.53543),(-11.33858,-6.349609,72.28346),(-36.85039,-20.63622,72.28346),(-36.85039,-20.63622,68.0315)},
+ {(-5.669294,0,76.53543),(-11.33858,0,72.28346),(-36.85039,0,72.28346),(-36.85039,0,68.0315)},
+ },
+ {
+ {(-5.669294,0,76.53543),(-11.33858,0,72.28346),(-36.85039,0,72.28346),(-36.85039,0,68.0315)},
+ {(-5.669294,3.174809,76.53543),(-11.33858,6.349609,72.28346),(-36.85039,20.63622,72.28346),(-36.85039,20.63622,68.0315)},
+ {(-3.174809,5.669294,76.53543),(-6.349609,11.33858,72.28346),(-20.63622,36.85039,72.28346),(-20.63622,36.85039,68.0315)},
+ {(0,5.669294,76.53543),(0,11.33858,72.28346),(0,36.85039,72.28346),(0,36.85039,68.0315)}
+ },
+ {
+ {(0,5.669294,76.53543),(0,11.33858,72.28346),(0,36.85039,72.28346),(0,36.85039,68.0315)},
+ {(3.174809,5.669294,76.53543),(6.349609,11.33858,72.28346),(20.63622,36.85039,72.28346),(20.63622,36.85039,68.0315)},
+ {(5.669294,3.174809,76.53543),(11.33858,6.349609,72.28346),(36.85039,20.63622,72.28346),(36.85039,20.63622,68.0315)},
+ {(5.669294,0,76.53543),(11.33858,0,72.28346),(36.85039,0,72.28346),(36.85039,0,68.0315)}
+ }
+};
+
+triple[][][] Q0={
+ {
{(0,0,89.29133),(22.67716,0,89.29133),(0,0,80.7874),(5.669294,0,76.53543)},
{(0,0,89.29133),(22.67716,-12.7559,89.29133),(0,0,80.7874),(5.669294,-3.174809,76.53543)},
{(0,0,89.29133),(12.7559,-22.67716,89.29133),(0,0,80.7874),(3.174809,-5.669294,76.53543)},
{(0,0,89.29133),(0,-22.67716,89.29133),(0,0,80.7874),(0,-5.669294,76.53543)}
- },
- {
+ },
+ {
{(0,0,89.29133),(0,-22.67716,89.29133),(0,0,80.7874),(0,-5.669294,76.53543)},
{(0,0,89.29133),(-12.7559,-22.67716,89.29133),(0,0,80.7874),(-3.174809,-5.669294,76.53543)},
{(0,0,89.29133),(-22.67716,-12.7559,89.29133),(0,0,80.7874),(-5.669294,-3.174809,76.53543)},
{(0,0,89.29133),(-22.67716,0,89.29133),(0,0,80.7874),(-5.669294,0,76.53543)}
- },
- {
+ },
+ {
{(0,0,89.29133),(-22.67716,0,89.29133),(0,0,80.7874),(-5.669294,0,76.53543)},
{(0,0,89.29133),(-22.67716,12.7559,89.29133),(0,0,80.7874),(-5.669294,3.174809,76.53543)},
{(0,0,89.29133),(-12.7559,22.67716,89.29133),(0,0,80.7874),(-3.174809,5.669294,76.53543)},
{(0,0,89.29133),(0,22.67716,89.29133),(0,0,80.7874),(0,5.669294,76.53543)}
- },
- {
+ },
+ {
{(0,0,89.29133),(0,22.67716,89.29133),(0,0,80.7874),(0,5.669294,76.53543)},
{(0,0,89.29133),(12.7559,22.67716,89.29133),(0,0,80.7874),(3.174809,5.669294,76.53543)},
{(0,0,89.29133),(22.67716,12.7559,89.29133),(0,0,80.7874),(5.669294,3.174809,76.53543)},
{(0,0,89.29133),(22.67716,0,89.29133),(0,0,80.7874),(5.669294,0,76.53543)}
- },
- {
- {(5.669294,0,76.53543),(11.33858,0,72.28346),(36.85039,0,72.28346),(36.85039,0,68.0315)},
- {(5.669294,-3.174809,76.53543),(11.33858,-6.349609,72.28346),(36.85039,-20.63622,72.28346),(36.85039,-20.63622,68.0315)},
- {(3.174809,-5.669294,76.53543),(6.349609,-11.33858,72.28346),(20.63622,-36.85039,72.28346),(20.63622,-36.85039,68.0315)},
- {(0,-5.669294,76.53543),(0,-11.33858,72.28346),(0,-36.85039,72.28346),(0,-36.85039,68.0315)}
- },
- {
- {(0,-5.669294,76.53543),(0,-11.33858,72.28346),(0,-36.85039,72.28346),(0,-36.85039,68.0315)},
- {(-3.174809,-5.669294,76.53543),(-6.349609,-11.33858,72.28346),(-20.63622,-36.85039,72.28346),(-20.63622,-36.85039,68.0315)},
- {(-5.669294,-3.174809,76.53543),(-11.33858,-6.349609,72.28346),(-36.85039,-20.63622,72.28346),(-36.85039,-20.63622,68.0315)},
- {(-5.669294,0,76.53543),(-11.33858,0,72.28346),(-36.85039,0,72.28346),(-36.85039,0,68.0315)},
- },
- {
- {(-5.669294,0,76.53543),(-11.33858,0,72.28346),(-36.85039,0,72.28346),(-36.85039,0,68.0315)},
- {(-5.669294,3.174809,76.53543),(-11.33858,6.349609,72.28346),(-36.85039,20.63622,72.28346),(-36.85039,20.63622,68.0315)},
- {(-3.174809,5.669294,76.53543),(-6.349609,11.33858,72.28346),(-20.63622,36.85039,72.28346),(-20.63622,36.85039,68.0315)},
- {(0,5.669294,76.53543),(0,11.33858,72.28346),(0,36.85039,72.28346),(0,36.85039,68.0315)}
- },
- {
- {(0,5.669294,76.53543),(0,11.33858,72.28346),(0,36.85039,72.28346),(0,36.85039,68.0315)},
- {(3.174809,5.669294,76.53543),(6.349609,11.33858,72.28346),(20.63622,36.85039,72.28346),(20.63622,36.85039,68.0315)},
- {(5.669294,3.174809,76.53543),(11.33858,6.349609,72.28346),(36.85039,20.63622,72.28346),(36.85039,20.63622,68.0315)},
- {(5.669294,0,76.53543),(11.33858,0,72.28346),(36.85039,0,72.28346),(36.85039,0,68.0315)},
- },
- {
+ },
+ {
{(0,0,0),(40.3937,0,0),(42.51969,0,2.12598),(42.51969,0,4.251961)},
{(0,0,0),(40.3937,22.62047,0),(42.51969,23.81102,2.12598),(42.51969,23.81102,4.251961)},
{(0,0,0),(22.62047,40.3937,0),(23.81102,42.51969,2.12598),(23.81102,42.51969,4.251961)},
{(0,0,0),(0,40.3937,0),(0,42.51969,2.12598),(0,42.51969,4.251961)}
- },
- {
+ },
+ {
{(0,0,0),(0,40.3937,0),(0,42.51969,2.12598),(0,42.51969,4.251961)},
{(0,0,0),(-22.62047,40.3937,0),(-23.81102,42.51969,2.12598),(-23.81102,42.51969,4.251961)},
{(0,0,0),(-40.3937,22.62047,0),(-42.51969,23.81102,2.12598),(-42.51969,23.81102,4.251961)},
{(0,0,0),(-40.3937,0,0),(-42.51969,0,2.12598),(-42.51969,0,4.251961)}
- },
- {
+ },
+ {
{(0,0,0),(-40.3937,0,0),(-42.51969,0,2.12598),(-42.51969,0,4.251961)},
{(0,0,0),(-40.3937,-22.62047,0),(-42.51969,-23.81102,2.12598),(-42.51969,-23.81102,4.251961)},
{(0,0,0),(-22.62047,-40.3937,0),(-23.81102,-42.51969,2.12598),(-23.81102,-42.51969,4.251961)},
{(0,0,0),(0,-40.3937,0),(0,-42.51969,2.12598),(0,-42.51969,4.251961)}
- },
- {
+ },
+ {
{(0,0,0),(0,-40.3937,0),(0,-42.51969,2.12598),(0,-42.51969,4.251961)},
{(0,0,0),(22.62047,-40.3937,0),(23.81102,-42.51969,2.12598),(23.81102,-42.51969,4.251961)},
{(0,0,0),(40.3937,-22.62047,0),(42.51969,-23.81102,2.12598),(42.51969,-23.81102,4.251961)},
{(0,0,0),(40.3937,0,0),(42.51969,0,2.12598),(42.51969,0,4.251961)}
- }
- };
+ }
+};
+
+surface regularize(triple[][] P, real fraction=0.02)
+{
+ triple[][][] B=hsplit(P,fraction);
+ triple[][] T=B[0];
+ surface s=surface(T[0][0]..controls T[0][1] and T[0][2]..
+ T[0][3]..controls T[1][3] and T[2][3]..
+ T[3][3]..controls T[3][2] and T[3][1]..cycle);
+ s.append(surface(patch(B[1])));
+ return s;
+}
+
+surface S=surface(Q);
+for(triple[][] q : Q0)
+ S.append(regularize(q));
+
+pen color;
+real metallic;
+
+if(settings.ibl) {
+ color=white;
+ metallic=1;
+} else {
+ color=blue;
+ metallic=0;
+}
-draw(surface(Q),material(blue, shininess=0.85, metallic=0),render(compression=Low));
+draw(S,material(color,shininess=0.85,metallic=metallic),
+ render(compression=Single));
diff --git a/graphics/asymptote/examples/teapotIBL.asy b/graphics/asymptote/examples/teapotIBL.asy
new file mode 100644
index 0000000000..bd6afe3110
--- /dev/null
+++ b/graphics/asymptote/examples/teapotIBL.asy
@@ -0,0 +1,2 @@
+settings.ibl=true;
+import teapot;
diff --git a/graphics/asymptote/examples/transparency.asy b/graphics/asymptote/examples/transparency.asy
index 36e741d294..a01a87a454 100644
--- a/graphics/asymptote/examples/transparency.asy
+++ b/graphics/asymptote/examples/transparency.asy
@@ -1,8 +1,5 @@
size(0,150);
-if(settings.outformat == "")
- settings.outformat="pdf";
-
begingroup();
fill(shift(1.5dir(120))*unitcircle,green+opacity(0.75));
fill(shift(1.5dir(60))*unitcircle,red+opacity(0.75));
diff --git a/graphics/asymptote/examples/workcone.asy b/graphics/asymptote/examples/workcone.asy
index 594758bba6..da7629c773 100644
--- a/graphics/asymptote/examples/workcone.asy
+++ b/graphics/asymptote/examples/workcone.asy
@@ -20,7 +20,7 @@ render render=render(compression=0,merge=true);
draw(scale(x1,x1,-s1)*shift(-Z)*unitcone,lightblue+opacity(0.5),render);
-path3 p=(x2,0,s2)--(x,0,s+0.005);
+path3 p=(x2,0,s2)--(x,0,s);
revolution a=revolution(p,Z);
draw(surface(a),lightblue+opacity(0.5),render);
diff --git a/graphics/asymptote/exp.cc b/graphics/asymptote/exp.cc
index dbf6886ecb..48a5c000f2 100644
--- a/graphics/asymptote/exp.cc
+++ b/graphics/asymptote/exp.cc
@@ -32,12 +32,13 @@ using namespace types;
using namespace trans;
using vm::inst;
using mem::vector;
-
+using mem::stdString;
+using vm::getPos;
#if 0
void exp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "exp",indent);
+ prettyname(out, "exp",indent, getPos());
}
#endif
@@ -132,7 +133,7 @@ tempExp::tempExp(coenv &e, varinit *v, types::ty *t)
}
void tempExp::prettyprint(ostream &out, Int indent) {
- prettyname(out, "tempExp", indent);
+ prettyname(out, "tempExp", indent, getPos());
}
types::ty *tempExp::trans(coenv &e) {
@@ -147,7 +148,7 @@ varEntryExp::varEntryExp(position pos, types::ty *t, vm::bltin f)
: exp(pos), v(new trans::varEntry(t, new bltinAccess(f), 0, position())) {}
void varEntryExp::prettyprint(ostream &out, Int indent) {
- prettyname(out, "varEntryExp", indent);
+ prettyname(out, "varEntryExp", indent, getPos());
}
types::ty *varEntryExp::getType(coenv &) {
@@ -181,11 +182,35 @@ void varEntryExp::transCall(coenv &e, types::ty *target) {
void nameExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "nameExp",indent);
+ prettyname(out, "nameExp",indent, getPos());
value->prettyprint(out, indent+1);
}
+void nameExp::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ AsymptoteLsp::SymbolLit accessedName(value->getLit());
+ position basePos = getPos();
+ AsymptoteLsp::filePos castedPos = dynamic_cast<qualifiedName*>(value) ?
+ std::make_pair(stdString(basePos.filename()),
+ std::make_pair(basePos.Line(), basePos.Column() + 1)) :
+ static_cast<AsymptoteLsp::filePos>(basePos);
+
+ auto varUsageIt = symContext->symMap.varUsage.find(accessedName);
+ if (varUsageIt == symContext->symMap.varUsage.end())
+ {
+ symContext->symMap.varUsage.emplace(accessedName, castedPos);
+ }
+ else
+ {
+ varUsageIt->second.add(castedPos);
+ }
+
+ symContext->symMap.usageByLines.emplace_back(castedPos.second, accessedName);
+#endif
+}
+
void fieldExp::pseudoName::prettyprint(ostream &out, Int indent)
{
@@ -334,15 +359,15 @@ void subscriptExp::transWrite(coenv &e, types::ty *t, exp *value)
void slice::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "slice", indent);
+ prettyname(out, "slice", indent, getPos());
if (left)
left->prettyprint(out, indent+1);
else
- prettyname(out, "left omitted", indent+1);
+ prettyname(out, "left omitted", indent+1, getPos());
if (right)
right->prettyprint(out, indent+1);
else
- prettyname(out, "right omitted", indent+1);
+ prettyname(out, "right omitted", indent+1, getPos());
}
void slice::trans(coenv &e)
@@ -360,7 +385,7 @@ void slice::trans(coenv &e)
void sliceExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "sliceExp", indent);
+ prettyname(out, "sliceExp", indent, getPos());
set->prettyprint(out, indent+1);
index->prettyprint(out, indent+1);
}
@@ -402,7 +427,7 @@ void sliceExp::transWrite(coenv &e, types::ty *t, exp *value)
void thisExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "thisExp", indent);
+ prettyname(out, "thisExp", indent, getPos());
}
types::ty *thisExp::trans(coenv &e)
@@ -421,7 +446,7 @@ types::ty *thisExp::getType(coenv &e)
void equalityExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "equalityExp", indent);
+ prettyname(out, "equalityExp", indent, getPos());
callExp::prettyprint(out, indent+1);
}
@@ -550,7 +575,7 @@ void scaleExp::prettyprint(ostream &out, Int indent)
{
exp *left=getLeft(); exp *right=getRight();
- prettyname(out, "scaleExp",indent);
+ prettyname(out, "scaleExp",indent, getPos());
left->prettyprint(out, indent+1);
right->prettyprint(out, indent+1);
}
@@ -635,7 +660,7 @@ types::ty *booleanExp::trans(coenv &e)
void newPictureExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "newPictureExp",indent);
+ prettyname(out, "newPictureExp",indent, getPos());
}
types::ty *newPictureExp::trans(coenv &e)
@@ -647,7 +672,7 @@ types::ty *newPictureExp::trans(coenv &e)
void cycleExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "cycleExp",indent);
+ prettyname(out, "cycleExp",indent, getPos());
}
types::ty *cycleExp::trans(coenv &e)
@@ -659,7 +684,7 @@ types::ty *cycleExp::trans(coenv &e)
void nullPathExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "nullPathExp",indent);
+ prettyname(out, "nullPathExp",indent, getPos());
}
types::ty *nullPathExp::trans(coenv &e)
@@ -671,7 +696,7 @@ types::ty *nullPathExp::trans(coenv &e)
void nullExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "nullExp",indent);
+ prettyname(out, "nullExp",indent, getPos());
}
types::ty *nullExp::trans(coenv &)
@@ -684,7 +709,7 @@ types::ty *nullExp::trans(coenv &)
void quoteExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "quoteExp", indent);
+ prettyname(out, "quoteExp", indent, getPos());
value->prettyprint(out, indent+1);
}
@@ -697,7 +722,7 @@ types::ty *quoteExp::trans(coenv &e)
void explist::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "explist",indent);
+ prettyname(out, "explist",indent, getPos());
for (expvector::iterator p = exps.begin();
p != exps.end(); ++p)
(*p)->prettyprint(out, indent+1);
@@ -715,17 +740,34 @@ void argument::prettyprint(ostream &out, Int indent)
val->prettyprint(out, indent+1);
}
+void argument::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ val->createSymMap(symContext);
+#endif
+}
+
void arglist::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "arglist",indent);
+ prettyname(out, "arglist",indent, getPos());
for (argvector::iterator p = args.begin();
p != args.end(); ++p)
p->prettyprint(out, indent+1);
}
+void arglist::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ for (auto& p: args)
+ {
+ p.createSymMap(symContext);
+ }
+#endif
+}
+
void callExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "callExp",indent);
+ prettyname(out, "callExp",indent, getPos());
callee->prettyprint(out, indent+1);
args->prettyprint(out, indent+1);
@@ -745,8 +787,11 @@ signature *callExp::argTypes(coenv &e, bool *searchable)
if(string(args->args[i].name) == "KEY") {
stringExp *s=dynamic_cast<stringExp*>(args->args[i].val);
if(s) {
- if(getPos().filename() == processData().fileName)
- processData().xkey[getPos().LineColumn()]=Strdup(s->getString());
+ if(getPos().filename() == processData().fileName) {
+ processDataStruct *P=&processData();
+ P->xkey[getPos().shift(P->xmapCount).LineColumn()]=
+ Strdup(s->getString());
+ }
args->args.erase(args->args.begin()+i);
--n;
if(i == n) break;
@@ -1036,10 +1081,83 @@ bool callExp::resolved(coenv &e) {
return cachedApp || cachedVarEntry;
}
+void callExp::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ callee->createSymMap(symContext);
+ args->createSymMap(symContext);
+
+ if (auto col=getColorInformation())
+ {
+ auto const& v=col.value();
+ auto const& colVal=std::get<0>(v);
+ auto const& alpha=std::get<1>(v);
+ auto const& beginArgPos=std::get<2>(v);
+ auto const& lastArgPos=std::get<3>(v);
+ if (alpha.has_value())
+ {
+
+ auto const& red=std::get<0>(colVal);
+ auto const& green=std::get<1>(colVal);
+ auto const& blue=std::get<2>(colVal);
+ std::tuple<double, double, double, double> rgba(red, green, blue, alpha.value());
+
+ symContext->addRGBAColor(rgba, beginArgPos, lastArgPos);
+ }
+ else
+ {
+ symContext->addRGBColor(colVal, beginArgPos, lastArgPos);
+ }
+ }
+#endif
+}
+
+
+optional<std::tuple<callExp::colorInfo, optional<double>, AsymptoteLsp::posInFile, AsymptoteLsp::posInFile>>
+callExp::getColorInformation()
+{
+#ifdef HAVE_LSP
+ if (auto* namedCallee = dynamic_cast<nameExp*>(callee))
+ {
+ std::string calleeName = static_cast<std::string>(namedCallee->getName());
+ std::vector<double> colors;
+
+ auto getLineColumn = [&argsval = args->args](int const& idx)
+ {
+ return argsval[idx].val->getPos().LineColumn();
+ };
+
+ if (calleeName == "rgb" || calleeName == "rgba")
+ {
+ for (auto const& expVec : args->args)
+ {
+ if (auto* valExp=dynamic_cast<realExp*>(expVec.val))
+ {
+ colors.push_back(valExp->getValue<double>());
+ } else if (auto* valExpI=dynamic_cast<intExp*>(expVec.val))
+ {
+ colors.push_back(valExpI->getValue<double>());
+ }
+ }
+ }
+ if (calleeName == "rgb" && colors.size() == 3)
+ {
+ callExp::colorInfo col(colors[0], colors[1], colors[2]);
+ return std::make_tuple(col, optional<double>(), callee->getPos().LineColumn(), getLineColumn(2));
+ }
+ else if (calleeName == "rgba" && colors.size() == 4)
+ {
+ callExp::colorInfo col(colors[0], colors[1], colors[2]);
+ return std::make_tuple(col, optional<double>(colors[3]), callee->getPos().LineColumn(), getLineColumn(3));
+ }
+ }
+#endif
+ return nullopt;
+}
void pairExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "pairExp",indent);
+ prettyname(out, "pairExp",indent, getPos());
x->prettyprint(out, indent+1);
y->prettyprint(out, indent+1);
@@ -1057,7 +1175,7 @@ types::ty *pairExp::trans(coenv &e)
void tripleExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "tripleExp",indent);
+ prettyname(out, "tripleExp",indent, getPos());
x->prettyprint(out, indent+1);
y->prettyprint(out, indent+1);
@@ -1077,7 +1195,7 @@ types::ty *tripleExp::trans(coenv &e)
void transformExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "transformExp",indent);
+ prettyname(out, "transformExp",indent, getPos());
x->prettyprint(out, indent+1);
y->prettyprint(out, indent+1);
@@ -1103,7 +1221,7 @@ types::ty *transformExp::trans(coenv &e)
void castExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "castExp",indent);
+ prettyname(out, "castExp",indent, getPos());
target->prettyprint(out, indent+1);
castee->prettyprint(out, indent+1);
@@ -1152,10 +1270,17 @@ types::ty *castExp::getType(coenv &e)
return target->trans(e, true);
}
+void castExp::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ castee->createSymMap(symContext);
+#endif
+}
+
void conditionalExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "conditionalExp",indent);
+ prettyname(out, "conditionalExp",indent, getPos());
test->prettyprint(out, indent+1);
onTrue->prettyprint(out, indent+1);
@@ -1269,7 +1394,7 @@ types::ty *conditionalExp::getType(coenv &e)
void orExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "orExp", indent);
+ prettyname(out, "orExp", indent, getPos());
left->prettyprint(out, indent+1);
right->prettyprint(out, indent+1);
@@ -1305,7 +1430,7 @@ void orExp::transConditionalJump(coenv &e, bool cond, label dest)
void andExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "andExp", indent);
+ prettyname(out, "andExp", indent, getPos());
left->prettyprint(out, indent+1);
right->prettyprint(out, indent+1);
@@ -1340,7 +1465,7 @@ void andExp::transConditionalJump(coenv &e, bool cond, label dest)
void joinExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "joinExp",indent);
+ prettyname(out, "joinExp",indent, getPos());
callee->prettyprint(out, indent+1);
args->prettyprint(out, indent+1);
@@ -1374,7 +1499,7 @@ types::ty *specExp::getType(coenv &e)
void assignExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "assignExp",indent);
+ prettyname(out, "assignExp",indent, getPos());
dest->prettyprint(out, indent+1);
value->prettyprint(out, indent+1);
@@ -1431,6 +1556,14 @@ types::ty *assignExp::getType(coenv &e)
return t ? t : primError();
}
+void assignExp::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ dest->createSymMap(symContext);
+ value->createSymMap(symContext);
+#endif
+}
+
void selfExp::prettyprint(ostream &out, Int indent)
{
@@ -1493,4 +1626,3 @@ types::ty *postfixExp::trans(coenv &)
} // namespace absyntax
-
diff --git a/graphics/asymptote/exp.h b/graphics/asymptote/exp.h
index 562e229965..d1a60e96dd 100644
--- a/graphics/asymptote/exp.h
+++ b/graphics/asymptote/exp.h
@@ -237,14 +237,15 @@ public:
nameExp(position pos, string s)
: exp(pos), value(new simpleName(pos, symbol::trans(s))) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
- symbol getName()
+ symbol getName() override
{
return value->getName();
}
- void transAsType(coenv &e, types::ty *target) {
+ void transAsType(coenv &e, types::ty *target) override {
value->varTrans(trans::READ, e, target);
// After translation, the cached type is no longer needed and should be
@@ -254,7 +255,7 @@ public:
ct=0;
}
- types::ty *trans(coenv &e) {
+ types::ty *trans(coenv &e) override {
types::ty *t=cgetType(e);
if (t->kind == types::ty_error) {
em.error(getPos());
@@ -272,32 +273,32 @@ public:
}
}
- types::ty *getType(coenv &e) {
+ types::ty *getType(coenv &e) override {
types::ty *t=value->varGetType(e);
return t ? t : types::primError();
}
- trans::varEntry *getCallee(coenv &e, types::signature *sig) {
+ trans::varEntry *getCallee(coenv &e, types::signature *sig) override {
#ifdef DEBUG_GETAPP
cout << "nameExp" << endl;
#endif
return value->getCallee(e, sig);
}
- void transWrite(coenv &e, types::ty *target, exp *newValue) {
+ void transWrite(coenv &e, types::ty *target, exp *newValue) override {
newValue->transToType(e, target);
this->value->varTrans(trans::WRITE, e, target);
ct=0; // See note in transAsType.
}
- void transCall(coenv &e, types::ty *target) {
+ void transCall(coenv &e, types::ty *target) override {
value->varTrans(trans::CALL, e, target);
ct=0; // See note in transAsType.
}
- exp *evaluate(coenv &, types::ty *) {
+ exp *evaluate(coenv &, types::ty *) override {
// Names have no side-effects.
return this;
}
@@ -363,9 +364,15 @@ class fieldExp : public nameExp {
void print(ostream& out) const {
out << "<exp>";
}
- symbol getName() {
+
+ symbol getName() const {
return object->getName();
}
+
+ AsymptoteLsp::SymbolLit getLit() const
+ {
+ return AsymptoteLsp::SymbolLit(static_cast<std::string>(object->getName()));
+ }
};
// Try to get this into qualifiedName somehow.
@@ -513,6 +520,13 @@ public:
types::ty *trans(coenv &e);
types::ty *getType(coenv &) { return types::primInt(); }
+
+ template<typename T>
+ [[nodiscard]]
+ T getValue() const
+ {
+ return static_cast<T>(value);
+ }
};
class realExp : public literalExp {
@@ -527,6 +541,13 @@ public:
types::ty *trans(coenv &e);
types::ty *getType(coenv &) { return types::primReal(); }
+
+ template<typename T>
+ [[nodiscard]]
+ T getValue() const
+ {
+ return static_cast<T>(value);
+ }
};
@@ -656,6 +677,7 @@ struct argument {
#endif
void prettyprint(ostream &out, Int indent);
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext);
};
class arglist : public gc {
@@ -725,6 +747,8 @@ public:
virtual argument& getRest() {
return rest;
}
+
+ virtual void createSymMap(AsymptoteLsp::SymbolContext* symContext);
};
// callExp has a global cache of resolved overloaded functions. This clears
@@ -796,10 +820,20 @@ public:
args->add(arg3);
}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
- types::ty *trans(coenv &e);
- types::ty *getType(coenv &e);
+ using colorInfo = std::tuple<double, double, double>;
+
+ /**
+ * @return nullopt if callExp is not a color, pair<color, nullopt> if color is RGB,
+ * and pair<color, alpha> if color is RGBA.
+ */
+ optional<std::tuple<colorInfo, optional<double>,
+ AsymptoteLsp::posInFile, AsymptoteLsp::posInFile>> getColorInformation();
+
+ types::ty *trans(coenv &e) override;
+ types::ty *getType(coenv &e) override;
// Returns true if the function call resolves uniquely without error. Used
// in implementing the special == and != operators for functions.
@@ -862,10 +896,12 @@ public:
castExp(position pos, ty *target, exp *castee)
: exp(pos), target(target), castee(castee) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- types::ty *trans(coenv &e);
- types::ty *getType(coenv &e);
+ types::ty *trans(coenv &e) override;
+ types::ty *getType(coenv &e) override;
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
class nullaryExp : public callExp {
@@ -956,10 +992,16 @@ public:
andOrExp(position pos, exp *left, symbol op, exp *right)
: exp(pos), left(left), op(op), right(right) {}
- virtual types::ty *trans(coenv &e) = 0;
- virtual types::ty *getType(coenv &) {
+ virtual types::ty *trans(coenv &e) override = 0;
+ virtual types::ty *getType(coenv &) override {
return types::primBoolean();
}
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override
+ {
+ left->createSymMap(symContext);
+ right->createSymMap(symContext);
+ }
};
class orExp : public andOrExp {
@@ -1034,20 +1076,22 @@ public:
assignExp(position pos, exp *dest, exp *value)
: exp(pos), dest(dest), value(value) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
// Don't write the result of an assignment to the prompt.
- bool writtenToPrompt() { return false; }
+ bool writtenToPrompt() override { return false; }
- void transAsType(coenv &e, types::ty *target);
- types::ty *trans(coenv &e);
- types::ty *getType(coenv &e);
+ void transAsType(coenv &e, types::ty *target) override;
+ types::ty *trans(coenv &e) override;
+ types::ty *getType(coenv &e) override;
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
class selfExp : public assignExp {
symbol op;
- exp *ultimateValue(exp *dest) {
+ exp *ultimateValue(exp *dest) override {
return new binaryExp(getPos(), dest, op, value);
}
@@ -1055,9 +1099,9 @@ public:
selfExp(position pos, exp *dest, symbol op, exp *value)
: assignExp(pos, dest, value), op(op) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void transAsType(coenv &e, types::ty *target);
+ void transAsType(coenv &e, types::ty *target) override;
};
class prefixExp : public exp {
@@ -1068,15 +1112,15 @@ public:
prefixExp(position pos, exp *dest, symbol op)
: exp(pos), dest(dest), op(op) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- bool scalable() { return false; }
+ bool scalable() override { return false; }
// Don't write the result to the prompt.
- bool writtenToPrompt() { return false; }
+ bool writtenToPrompt() override { return false; }
- types::ty *trans(coenv &e);
- types::ty *getType(coenv &e);
+ types::ty *trans(coenv &e) override;
+ types::ty *getType(coenv &e) override;
};
// Postfix expresions are illegal. This is caught here as we can give a
diff --git a/graphics/asymptote/fftw++.cc b/graphics/asymptote/fftw++.cc
index 7c1095f930..18071492e3 100644
--- a/graphics/asymptote/fftw++.cc
+++ b/graphics/asymptote/fftw++.cc
@@ -58,7 +58,7 @@ fftw_plan Planner(fftw *F, Complex *in, Complex *out)
LoadWisdom();
fftw::effort |= FFTW_WISDOM_ONLY;
fftw_plan plan=F->Plan(in,out);
- fftw::effort &= !FFTW_WISDOM_ONLY;
+ fftw::effort &= ~FFTW_WISDOM_ONLY;
if(!plan) {
plan=F->Plan(in,out);
SaveWisdom();
diff --git a/graphics/asymptote/fftw++.h b/graphics/asymptote/fftw++.h
index 467387d34f..bf4102e06d 100644
--- a/graphics/asymptote/fftw++.h
+++ b/graphics/asymptote/fftw++.h
@@ -20,7 +20,7 @@
#ifndef __fftwpp_h__
#define __fftwpp_h__ 1
-#define __FFTWPP_H_VERSION__ 2.08
+#define __FFTWPP_H_VERSION__ 2.10
#include <cstdlib>
#include <fstream>
@@ -28,6 +28,7 @@
#include <fftw3.h>
#include <cerrno>
#include <map>
+#include <typeinfo>
#ifndef _OPENMP
#ifndef FFTWPP_SINGLE_THREAD
@@ -122,9 +123,10 @@ public:
ThreadBase(unsigned int threads) : threads(threads) {}
void Threads(unsigned int nthreads) {threads=nthreads;}
unsigned int Threads() {return threads;}
+ unsigned int Innerthreads() {return innerthreads;}
- void multithread(unsigned int nx) {
- if(nx >= threads) {
+ void multithread(unsigned int n) {
+ if(n >= threads) {
innerthreads=1;
} else {
innerthreads=threads;
@@ -177,7 +179,7 @@ public:
static const char *oddshift;
- // Inplace shift of Fourier origin to (nx/2,0) for even nx.
+ // In-place shift of Fourier origin to (nx/2,0) for even nx.
static void Shift(Complex *data, unsigned int nx, unsigned int ny,
unsigned int threads) {
unsigned int nyp=ny/2+1;
@@ -216,7 +218,7 @@ public:
}
}
- // Inplace shift of Fourier origin to (nx/2,ny/2,0) for even nx and ny.
+ // In-place shift of Fourier origin to (nx/2,ny/2,0) for even nx and ny.
static void Shift(Complex *data, unsigned int nx, unsigned int ny,
unsigned int nz, unsigned int threads) {
unsigned int nzp=nz/2+1;
@@ -306,21 +308,30 @@ public:
plan=planT;
fft(in,out);
unsigned int N=1;
+ unsigned int ndoubles=doubles/2;
for(;;) {
double t0=utils::totalseconds();
threads=1;
plan=plan1;
- for(unsigned int i=0; i < N; ++i)
+ for(unsigned int i=0; i < N; ++i) {
+ for(unsigned int i=0; i < ndoubles; ++i) out[i]=i;
fft(in,out);
+ }
double t1=utils::totalseconds();
threads=Threads;
plan=planT;
- for(unsigned int i=0; i < N; ++i)
+ for(unsigned int i=0; i < N; ++i) {
+ for(unsigned int i=0; i < ndoubles; ++i) out[i]=i;
fft(in,out);
+ }
double t=utils::totalseconds();
S.add(t1-t0);
ST.add(t-t1);
- if(S.mean() < 100.0/CLOCKS_PER_SEC) N *= 2;
+ if(S.mean() < 100.0/CLOCKS_PER_SEC) {
+ N *= 2;
+ S.clear();
+ ST.clear();
+ }
if(S.count() >= 10) {
double error=S.stdev();
double diff=ST.mean()-S.mean();
@@ -365,7 +376,10 @@ public:
threaddata data;
unsigned int Threads=threads;
+
if(threads > 1) data=lookup(inplace,threads);
+ else data=threaddata(1,0.0,0.0);
+
threads=data.threads > 0 ? data.threads : 1;
planThreads(threads);
plan=(*planner)(this,in,out);
@@ -386,6 +400,10 @@ public:
}
if(alloc) Array::deleteAlign(in,(doubles+1)/2);
+#ifdef FFTWPP_VERBOSE
+ if(threads > 1)
+ std::cout << "Using " << threads << " threads." << std::endl;
+#endif
return data;
}
@@ -513,12 +531,12 @@ public:
exit(1);
}
plan=NULL;
+ if(!out) out=in;
+ inplace=(out==in);
if(rows == 0 || cols == 0) return;
size /= sizeof(double);
length *= size;
- if(!out) out=in;
- inplace=(out==in);
fftw::planThreads(threads);
fftw_iodim dims[3];
@@ -702,8 +720,10 @@ public:
threaddata S1=Setup(in,out);
fftw_plan planT1=plan;
+ threads=S1.threads;
+ bool hermitian=typeid(I) == typeid(double) || typeid(O) == typeid(double);
- if(fftw::maxthreads > 1) {
+ if(fftw::maxthreads > 1 && (!hermitian || ostride*(nx/2+1) < idist)) {
if(Threads > 1) {
T=std::min(M,Threads);
Q=T > 0 ? M/T : 0;
@@ -727,7 +747,6 @@ public:
Q=M;
R=0;
plan=planT1;
- threads=S1.threads;
} else { // Do the multi-threading ourselves
fftw_destroy_plan(planT1);
threads=ST.threads;
@@ -810,11 +829,16 @@ public:
// mfft1d Forward(n,-1,M,stride,dist,in,out);
// Forward.fft(in,out);
//
+// mfft1d Forward(n,-1,M,istride,ostride,idist,odist,in,out);
+// Forward.fft(in,out);
+//
// In-place usage:
//
// mfft1d Forward(n,-1,M,stride,dist);
// Forward.fft(in);
//
+//
+//
// Notes:
// stride is the spacing between the elements of each Complex vector;
// dist is the spacing between the first elements of the vectors.
@@ -824,7 +848,14 @@ class mfft1d : public fftwblock<fftw_complex,fftw_complex>,
public Threadtable<keytype3,keyless3> {
static Table threadtable;
public:
- mfft1d(unsigned int nx, int sign, unsigned int M=1, size_t stride=1,
+ mfft1d(unsigned int nx, int sign, unsigned int M=1,
+ Complex *in=NULL, Complex *out=NULL,
+ unsigned int threads=maxthreads) :
+ fftw(2*((nx-1)+(M-1)*nx+1),sign,threads,nx),
+ fftwblock<fftw_complex,fftw_complex>
+ (nx,M,1,1,nx,nx,in,out,threads) {}
+
+ mfft1d(unsigned int nx, int sign, unsigned int M, size_t stride=1,
size_t dist=0, Complex *in=NULL, Complex *out=NULL,
unsigned int threads=maxthreads) :
fftw(2*((nx-1)*stride+(M-1)*Dist(nx,stride,dist)+1),sign,threads,nx),
@@ -833,7 +864,7 @@ public:
mfft1d(unsigned int nx, int sign, unsigned int M,
size_t istride, size_t ostride, size_t idist, size_t odist,
- Complex *in=NULL, Complex *out=NULL, unsigned int threads=maxthreads):
+ Complex *in, Complex *out, unsigned int threads=maxthreads):
fftw(std::max(2*((nx-1)*istride+(M-1)*Dist(nx,istride,idist)+1),
2*((nx-1)*ostride+(M-1)*Dist(nx,ostride,odist)+1)),sign,
threads, nx),
diff --git a/graphics/asymptote/fftw++asy.cc b/graphics/asymptote/fftw++asy.cc
index 7d52933e50..458c6b07ee 100644
--- a/graphics/asymptote/fftw++asy.cc
+++ b/graphics/asymptote/fftw++asy.cc
@@ -6,4 +6,6 @@
#include "fftw++.h"
#include "fftw++.cc"
+extern "C" double __log_finite(double x) {return log(x);}
+
#endif
diff --git a/graphics/asymptote/fileio.cc b/graphics/asymptote/fileio.cc
index 0fb16e7ab5..441a9590ec 100644
--- a/graphics/asymptote/fileio.cc
+++ b/graphics/asymptote/fileio.cc
@@ -27,7 +27,7 @@ void ifile::open()
} else {
if(mode & std::ios::out)
name=outpath(name);
- else {
+ if(mode & std::ios::in) {
#ifdef HAVE_LIBCURL
if(parser::isURL(name)) {
parser::readURL(buf,name);
diff --git a/graphics/asymptote/fileio.h b/graphics/asymptote/fileio.h
index de7090b4cb..d601f176d8 100644
--- a/graphics/asymptote/fileio.h
+++ b/graphics/asymptote/fileio.h
@@ -11,6 +11,7 @@
#include <fstream>
#include <iostream>
#include <sstream>
+#include <zlib.h>
#include "common.h"
@@ -40,13 +41,13 @@ namespace camp {
extern string tab;
extern string newline;
-enum Mode {NOMODE,INPUT,OUTPUT,UPDATE,BINPUT,BOUTPUT,BUPDATE,XINPUT,XOUTPUT,
- XUPDATE,OPIPE};
+enum Mode {NOMODE,INPUT,OUTPUT,UPDATE,BINPUT,BOUTPUT,BUPDATE,XINPUT,XINPUTGZ,
+ XOUTPUT,XUPDATE,OPIPE};
static const string FileModes[]=
{"none","input","output","output(update)",
"input(binary)","output(binary)","output(binary,update)",
- "input(xdr)","output(xdr)","output(xdr,update)","output(pipe)"};
+ "input(xdr)","input(xdrgz)","output(xdr)","output(xdr,update)","output(pipe)"};
extern FILE *pipeout;
@@ -221,9 +222,11 @@ public:
val=T();
}
+#if COMPACT
void setDefault(Int& val) {
val=vm::Undefined;
}
+#endif
template<class T>
void read(T& val) {
@@ -644,21 +647,21 @@ public:
class ixfile : public file {
protected:
- xdr::ioxstream *fstream;
+ xdr::ixstream *fstream;
xdr::xios::open_mode mode;
public:
ixfile(const string& name, bool check=true, Mode type=XINPUT,
xdr::xios::open_mode mode=xdr::xios::in) :
file(name,check,type,true), fstream(NULL), mode(mode) {}
- void open() {
+ void open() override {
name=locatefile(inpath(name));
- fstream=new xdr::ioxstream(name.c_str(),mode);
+ fstream=new xdr::ixstream(name.c_str(),mode);
index=processData().ixfile.add(fstream);
if(check) Check();
}
- void close() {
+ void close() override {
if(fstream) {
fstream->close();
closed=true;
@@ -670,26 +673,26 @@ public:
~ixfile() {close();}
- bool eof() {return fstream ? fstream->eof() : true;}
- bool error() {return fstream ? fstream->fail() : true;}
+ bool eof() override {return fstream ? fstream->eof() : true;}
+ bool error() override {return fstream ? fstream->fail() : true;}
- void clear() {if(fstream) fstream->clear();}
+ void clear() override {if(fstream) fstream->clear();}
- void seek(Int pos, bool begin=true) {
+ void seek(Int pos, bool begin=true) override {
if(!standard && fstream) {
clear();
fstream->seek(pos,begin ? xdr::xios::beg : xdr::xios::end);
}
}
- size_t tell() {
+ size_t tell() override {
if(fstream)
return fstream->tell();
else
return 0;
}
- void Read(Int& val) {
+ void Read(Int& val) override {
if(signedint) {
if(singleint) {int ival=0; *fstream >> ival; val=ival;}
else {val=0; *fstream >> val;}
@@ -698,20 +701,20 @@ public:
else {unsignedInt ival=0; *fstream >> ival; val=Intcast(ival);}
}
}
- void Read(double& val) {
+ void Read(double& val) override {
if(singlereal) {float fval=0.0; *fstream >> fval; val=fval;}
else {
val=0.0;
*fstream >> val;
}
}
- void Read(pair& val) {
+ void Read(pair& val) override {
double x,y;
Read(x);
Read(y);
val=pair(x,y);
}
- void Read(triple& val) {
+ void Read(triple& val) override {
double x,y,z;
Read(x);
Read(y);
@@ -720,35 +723,93 @@ public:
}
};
+class igzxfile : public ixfile {
+protected:
+ std::vector<char> readData;
+ size_t const readSize;
+ gzFile gzfile;
+public:
+ igzxfile(const string& name, bool check=true, Mode type=XINPUT,
+ xdr::xios::open_mode mode=xdr::xios::in, size_t readSize=32768) :
+ ixfile(name,check,type,mode), readSize(readSize){}
+
+ bool error() override {return !gzfile;}
+
+ void open() override {
+ name=locatefile(inpath(name));
+ gzfile=gzopen(name.c_str(),"rb");
+ Check();
+
+ while(!gzeof(gzfile)) {
+ std::vector<char> tmpBuf(readSize);
+ auto filSz = gzread(gzfile,tmpBuf.data(),readSize);
+ std::copy(tmpBuf.begin(),tmpBuf.begin()+filSz,std::back_inserter(readData));
+ }
+ gzclose(gzfile);
+
+ fstream=new xdr::memixstream(readData);
+ index=processData().ixfile.add(fstream);
+ }
+
+ void close() override {
+ closeFile();
+ }
+
+ ~igzxfile() override {closeFile();}
+
+
+protected:
+ void closeFile()
+ {
+ if(fstream) {
+ fstream->close();
+ closed=true;
+ delete fstream;
+ processData().ixfile.remove(index);
+ }
+ }
+};
+
class ioxfile : public ixfile {
public:
- ioxfile(const string& name) : ixfile(outpath(name),true,XUPDATE,
- xdr::xios::out) {}
+ ioxfile(const string& name) :
+ ixfile(outpath(name),true,XUPDATE,xdr::xios::out) {}
- void flush() {if(fstream) fstream->flush();}
+ void open() override {
+ name=locatefile(inpath(name));
+ ioxfstreamRef=new xdr::ioxstream(name.c_str(),mode);
+ fstream=static_cast<xdr::ixstream*>(ioxfstreamRef);
+ index=processData().ixfile.add(fstream);
+ if(check) Check();
+ }
- void write(Int val) {
+ void flush() override {if(fstream) ioxfstreamRef->flush();}
+
+ void write(Int val) override{
if(signedint) {
- if(singleint) *fstream << intcast(val);
- else *fstream << val;
+ if(singleint) *ioxfstreamRef << intcast(val);
+ else *ioxfstreamRef << val;
} else {
- if(singleint) *fstream << unsignedcast(val);
- else *fstream << unsignedIntcast(val);
+ if(singleint) *ioxfstreamRef << unsignedcast(val);
+ else *ioxfstreamRef << unsignedIntcast(val);
}
}
- void write(double val) {
- if(singlereal) *fstream << (float) val;
- else *fstream << val;
+ void write(double val) override {
+ if(singlereal) *ioxfstreamRef << (float) val;
+ else *ioxfstreamRef << val;
}
- void write(const pair& val) {
+ void write(const pair& val) override {
write(val.getx());
write(val.gety());
}
- void write(const triple& val) {
+ void write(const triple& val) override {
write(val.getx());
write(val.gety());
write(val.getz());
}
+
+private:
+ xdr::ioxstream* ioxfstreamRef;
};
class oxfile : public file {
diff --git a/graphics/asymptote/fundec.cc b/graphics/asymptote/fundec.cc
index 706e83c48e..2a91623825 100644
--- a/graphics/asymptote/fundec.cc
+++ b/graphics/asymptote/fundec.cc
@@ -22,7 +22,7 @@ varinit *Default=new definit(nullPos);
void formal::prettyprint(ostream &out, Int indent)
{
- prettyname(out, keywordOnly ? "formal (keyword only)" : "formal", indent);
+ prettyname(out, keywordOnly ? "formal (keyword only)" : "formal", indent, getPos());
base->prettyprint(out, indent+1);
if (start) start->prettyprint(out, indent+1);
@@ -56,7 +56,7 @@ void formal::addOps(coenv &e, record *r) {
void formals::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "formals",indent);
+ prettyname(out, "formals",indent, getPos());
for (list<formal *>::iterator p = fields.begin(); p != fields.end(); ++p)
(*p)->prettyprint(out, indent+1);
@@ -125,7 +125,7 @@ public:
: exp(pos), dest(dest), value(value) {}
void prettyprint(ostream &out, Int indent) {
- prettyname(out, "basicAssignExp", indent);
+ prettyname(out, "basicAssignExp", indent, getPos());
}
types::ty *getType(coenv &) {
@@ -179,6 +179,26 @@ void formal::transAsVar(coenv &e, Int index) {
}
}
+void formal::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ if (start)
+ {
+ start->createSymMap(symContext);
+ }
+#endif
+}
+
+#ifdef HAVE_LSP
+std::pair<std::string, optional<std::string>> formal::fnInfo() const
+{
+ std::string typeName(static_cast<std::string>(*base));
+ return start != nullptr ?
+ std::make_pair(typeName, boost::make_optional(static_cast<std::string>(start->getName()))) :
+ std::make_pair(typeName, nullopt);
+}
+#endif
+
void formals::trans(coenv &e)
{
Int index = 0;
@@ -194,6 +214,37 @@ void formals::trans(coenv &e)
}
}
+void formals::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ for (auto& field: fields)
+ {
+ field->createSymMap(symContext);
+ }
+
+ if (rest)
+ {
+ rest->createSymMap(symContext);
+ }
+#endif
+}
+
+void formals::addArgumentsToFnInfo(AsymptoteLsp::FunctionInfo& fnInfo)
+{
+#ifdef HAVE_LSP
+ for (auto const& field: fields)
+ {
+ fnInfo.arguments.emplace_back(field->fnInfo());
+ }
+
+ if (rest)
+ {
+ fnInfo.restArgs=rest->fnInfo();
+ }
+ // handle rest case as well
+#endif
+}
+
void fundef::prettyprint(ostream &out, Int indent)
{
result->prettyprint(out, indent+1);
@@ -218,6 +269,14 @@ function *fundef::transTypeAndAddOps(coenv &e, record *r, bool tacit) {
return ft;
}
+void fundef::addArgumentsToFnInfo(AsymptoteLsp::FunctionInfo& fnInfo)
+{
+#ifdef HAVE_LSP
+ params->addArgumentsToFnInfo(fnInfo);
+ // handle rest case as well
+#endif
+}
+
varinit *fundef::makeVarInit(function *ft) {
struct initializer : public varinit {
fundef *f;
@@ -227,7 +286,7 @@ varinit *fundef::makeVarInit(function *ft) {
: varinit(f->getPos()), f(f), ft(ft) {}
void prettyprint(ostream &out, Int indent) {
- prettyname(out, "initializer", indent);
+ prettyname(out, "initializer", indent, getPos());
}
void transToType(coenv &e, types::ty *target) {
@@ -294,6 +353,15 @@ types::ty *fundef::trans(coenv &e) {
return ft;
}
+void fundef::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ auto* declCtx(symContext->newContext<AsymptoteLsp::AddDeclContexts>(getPos().LineColumn()));
+ params->createSymMap(declCtx);
+ body->createSymMap(declCtx);
+#endif
+}
+
void fundec::prettyprint(ostream &out, Int indent)
{
prettyindent(out, indent);
@@ -315,4 +383,15 @@ void fundec::transAsField(coenv &e, record *r)
createVar(getPos(), e, r, id, ft, fun.makeVarInit(ft));
}
+void fundec::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ AsymptoteLsp::FunctionInfo& fnInfo=symContext->symMap.addFunDef(static_cast<std::string>(id),
+ getPos().LineColumn(),
+ static_cast<std::string>(*fun.result));
+ fun.addArgumentsToFnInfo(fnInfo);
+ fun.createSymMap(symContext);
+#endif
+}
+
} // namespace absyntax
diff --git a/graphics/asymptote/fundec.h b/graphics/asymptote/fundec.h
index ab6e3fec50..5d715fd59b 100644
--- a/graphics/asymptote/fundec.h
+++ b/graphics/asymptote/fundec.h
@@ -27,7 +27,7 @@ public:
: absyn(pos), base(base), start(start), Explicit(Explicit),
defval(defval), keywordOnly(keywordOnly) {}
- virtual void prettyprint(ostream &out, Int indent);
+ virtual void prettyprint(ostream &out, Int indent) override;
// Build the corresponding types::formal to put into a signature.
types::formal trans(coenv &e, bool encodeDefVal, bool tacit=false);
@@ -55,6 +55,9 @@ public:
bool isKeywordOnly() {
return keywordOnly;
}
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
+ std::pair<std::string, optional<std::string>> fnInfo() const;
};
class formals : public absyn {
@@ -74,7 +77,7 @@ public:
virtual ~formals() {}
- virtual void prettyprint(ostream &out, Int indent);
+ virtual void prettyprint(ostream &out, Int indent) override;
virtual void add(formal *f) {
if (f->isKeywordOnly()) {
@@ -122,6 +125,9 @@ public:
// Add the formal parameters to the environment to prepare for the
// function body's translation.
virtual void trans(coenv &e);
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
+ void addArgumentsToFnInfo(AsymptoteLsp::FunctionInfo& fnInfo);
};
class fundef : public exp {
@@ -139,17 +145,20 @@ public:
fundef(position pos, ty *result, formals *params, stm *body)
: exp(pos), result(result), params(params), body(body), id() {}
- virtual void prettyprint(ostream &out, Int indent);
+ virtual void prettyprint(ostream &out, Int indent) override;
varinit *makeVarInit(types::function *ft);
virtual void baseTrans(coenv &e, types::function *ft);
- virtual types::ty *trans(coenv &e);
+ virtual types::ty *trans(coenv &e) override;
virtual types::function *transType(coenv &e, bool tacit);
virtual types::function *transTypeAndAddOps(coenv &e, record *r, bool tacit);
- virtual types::ty *getType(coenv &e) {
+ virtual types::ty *getType(coenv &e) override {
return transType(e, true);
}
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
+ void addArgumentsToFnInfo(AsymptoteLsp::FunctionInfo& fnInfo);
};
class fundec : public dec {
@@ -161,11 +170,13 @@ public:
: dec(pos), id(id), fun(pos, result, params, body)
{ fun.id = id; }
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
+
+ void trans(coenv &e) override;
- void trans(coenv &e);
+ void transAsField(coenv &e, record *r) override;
- void transAsField(coenv &e, record *r);
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
} // namespace absyntax
diff --git a/graphics/asymptote/generate_enums.py b/graphics/asymptote/generate_enums.py
new file mode 100755
index 0000000000..07f2d77231
--- /dev/null
+++ b/graphics/asymptote/generate_enums.py
@@ -0,0 +1,183 @@
+#!/usr/bin/env python3
+
+# A script to generate enums in different languages from a CSV file.
+# A CSV File contains
+# enum1, 0
+# enum2, ..
+# ...
+# enumn, n
+# where 0,...,n are numbers.
+#
+# Written by Supakorn "Jamie" Rassameemasmuang <jamievlin@outlook.com>
+
+from typing import List, Tuple, Any, Union
+from datetime import datetime
+import io
+import argparse
+import sys
+import re
+
+def cleanComment(s):
+ return re.sub(r' *#',' ',s)
+
+def parse_args():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-language', '--language', type=str, required=True)
+ parser.add_argument('-o', '--output', type=str, required=True)
+ parser.add_argument('-i', '--input', type=str, required=True)
+ parser.add_argument('-name', '--name', type=str, required=True)
+ parser.add_argument('-xopt', '--xopt', type=str, nargs='*')
+ return parser.parse_args()
+
+
+def create_enums(filename: str) -> List[Union[Tuple[str, int, str], Tuple[str, int]]]:
+ final_list=[]
+ with io.open(filename,newline='') as rawfile:
+ for line in rawfile.readlines():
+ if line.startswith('#') or line.strip() == '':
+ continue
+ raw_line=line.strip().split(',')
+ raw_str, raw_number=raw_line[0:2]
+ comment=None
+ if len(raw_line)>=3:
+ comment=raw_line[-1]
+ final_list.append((raw_str.strip(), int(raw_number.strip()),comment))
+ else:
+ final_list.append((raw_str.strip(), int(raw_number.strip())))
+ return final_list
+
+
+def generate_enum_cpp(outname, enums, name, comment=None, *args, **kwargs):
+ with io.open(outname, 'w') as fil:
+ fil.write('// Enum class for {0}\n'.format(name))
+ if comment is not None:
+ fil.write('// {0}\n'.format(comment))
+ fil.write('// Generated at {0}\n\n'.format(datetime.now()))
+ if 'namespace' in kwargs:
+ fil.write('namespace {0}\n'.format(kwargs['namespace']))
+ fil.write('{\n')
+
+ fil.write('enum {0} : uint32_t\n'.format(name))
+ fil.write('{\n')
+
+ for enumTxt, enumNum, *ar in enums:
+ fil.write('{0}={1},\n'.format(enumTxt, enumNum))
+ if len(ar) > 0:
+ comment=cleanComment(ar[-1])
+ if comment is not None:
+ fil.write('// {0}\n\n'.format(comment.strip()))
+
+ fil.write('};\n\n')
+
+ if 'namespace' in kwargs:
+ fil.write('}} // namespace {0}\n'.format(kwargs['namespace']))
+ fil.write('// End of File\n')
+
+
+def generate_enum_java(outname, enums, name, comment=None, *args, **kwargs):
+ with io.open(outname, 'w') as fil:
+ fil.write('// Enum class for {0}\n'.format(name))
+ if comment is not None:
+ fil.write('// {0}\n'.format(comment))
+ fil.write('// Generated at {0}\n\n'.format(datetime.now()))
+
+ if 'package' in kwargs:
+ fil.write('package {0};\n'.format(kwargs['package']))
+ fil.write('\n')
+
+ fil.write('public enum {0} {{\n'.format(name))
+
+ spaces = kwargs.get('spaces', 4)
+ spaces_tab=' '*spaces
+
+ for i in range(len(enums)):
+ enumTxt, enumNum, *ar = enums[i]
+ endsep=',' if i < len(enums) - 1 else ';'
+ fil.write('{2}{0}({1}){3}\n'.format(enumTxt,enumNum,spaces_tab,endsep))
+ if len(ar) > 0:
+ comment=cleanComment(ar[-1])
+ if comment is not None:
+ fil.write('// {0}\n\n'.format(comment.strip()))
+
+ out_lines=[
+ '',
+ '{0}(int value) {{'.format(name),
+ '{0}this.value=value;'.format(spaces_tab),
+ '}',
+ 'public String toString() {',
+ '{0}return Integer.toString(value);'.format(spaces_tab),
+ '}',
+ 'private int value;']
+
+ for line in out_lines:
+ fil.write(spaces_tab)
+ fil.write(line)
+ fil.write('\n')
+ fil.write('};\n\n')
+ fil.write('// End of File\n')
+
+
+def generate_enum_asy(outname, enums, name, comment=None, *args, **kwargs):
+ with io.open(outname, 'w') as fil:
+ fil.write('// Enum class for {0}\n'.format(name))
+ if comment is not None:
+ fil.write('// {0}\n'.format(comment))
+ fil.write('// Generated at {0}\n\n'.format(datetime.now()))
+
+ fil.write('struct {0}\n'.format(name))
+ fil.write('{\n')
+
+ for enumTxt, enumNum, *ar in enums:
+ fil.write(' int {0}={1};\n'.format(enumTxt, enumNum))
+ if len(ar) > 0:
+ comment=cleanComment(ar[-1])
+ if comment is not None:
+ fil.write('// {0}\n\n'.format(comment.strip()))
+ fil.write('};\n\n')
+ fil.write('{0} {0};'.format(name))
+
+ fil.write('// End of File\n')
+
+
+def generate_enum_py(outname, enums, name, comment=None, *args, **kwargs):
+ with io.open(outname, 'w') as fil:
+ fil.write('#!/usr/bin/env python3\n')
+ fil.write('# Enum class for {0}\n'.format(name))
+ if comment is not None:
+ fil.write('""" {0} """\n'.format(comment))
+ fil.write('# Generated at {0}\n\n'.format(datetime.now()))
+ fil.write('class {0}:\n'.format(name))
+ for enumTxt, enumNum, *ar in enums:
+ fil.write(' {0}_{2}={1}\n'.format(name, enumNum, enumTxt))
+ if len(ar) > 0:
+ comment=cleanComment(ar[-1])
+ if comment is not None:
+ fil.write(' # {0}\n\n'.format(comment.strip()))
+ fil.write('# End of File\n')
+
+
+def main():
+ arg = parse_args()
+ if arg.language in {'python', 'py'}:
+ fn = generate_enum_py
+ elif arg.language in {'cxx', 'c++', 'cpp'}:
+ fn = generate_enum_cpp
+ elif arg.language in {'asy', 'asymptote'}:
+ fn = generate_enum_asy
+ elif arg.language in {'java'}:
+ fn = generate_enum_java
+ else:
+ return 1
+
+ custom_args = dict()
+ if arg.xopt is not None:
+ for xopt in arg.xopt:
+ key, val = xopt.split('=')
+ custom_args[key] = val
+
+ enums = create_enums(arg.input)
+ fn(arg.output, enums, arg.name, 'AUTO-GENERATED from '+arg.input, **custom_args)
+
+
+if __name__ == '__main__':
+ sys.exit(main() or 0)
diff --git a/graphics/asymptote/glrender.cc b/graphics/asymptote/glrender.cc
index 822039d934..ad297939bf 100644
--- a/graphics/asymptote/glrender.cc
+++ b/graphics/asymptote/glrender.cc
@@ -26,6 +26,10 @@
#include "interact.h"
#include "fpu.h"
+extern uint32_t CLZ(uint32_t a);
+
+bool GPUindexing;
+
namespace gl {
#ifdef HAVE_PTHREAD
pthread_t mainthread;
@@ -36,6 +40,7 @@ pthread_t mainthread;
#include "tr.h"
#ifdef HAVE_LIBGLUT
+
#ifdef __MSDOS__
#ifndef FGAPI
#define FGAPI GLUTAPI
@@ -46,15 +51,16 @@ pthread_t mainthread;
#endif
#define GLUT_BUILDING_LIB
-#endif // HAVE_LIBGLUT
-#ifdef HAVE_LIBGLUT
#ifdef FREEGLUT
#include <GL/freeglut_ext.h>
#endif
-#endif
+
+#endif // HAVE_LIBGLUT
#include "shaders.h"
+#include "GLTextures.h"
+#include "EXRFiles.h"
#ifdef HAVE_LIBOPENIMAGEIO
#include <OpenImageIO/imageio.h>
@@ -63,26 +69,33 @@ pthread_t mainthread;
using settings::locateFile;
using utils::seconds;
+#endif // HAVE_GL
+
+#ifdef HAVE_LIBGLM
+
namespace camp {
Billboard BB;
GLint pixelShader;
GLint materialShader;
GLint colorShader;
+GLint generalShader;
+GLint countShader;
GLint transparentShader;
+GLint blendShader;
+GLint zeroShader;
+GLint preSumShader;
+GLint partialSumShader;
+GLint postSumShader;
-vertexBuffer material0Data(GL_POINTS);
-vertexBuffer material1Data(GL_LINES);
-vertexBuffer materialData;
-vertexBuffer colorData;
-vertexBuffer transparentData;
-vertexBuffer triangleData;
+GLuint countBuffer;
+GLuint offsetBuffer;
+GLuint sumBuffer;
+GLuint fragmentBuffer;
-const size_t Nbuffer=10000;
-const size_t nbuffer=1000;
}
-#endif /* HAVE_GL */
+#endif
#ifdef HAVE_LIBGLM
using camp::Material;
@@ -92,20 +105,58 @@ using camp::nmaterials;
using camp::MaterialMap;
namespace camp {
-std::vector<Material> material;
+bool initSSBO;
+GLuint maxFragments;
+
+vertexBuffer material0Data(GL_POINTS);
+vertexBuffer material1Data(GL_LINES);
+vertexBuffer materialData;
+vertexBuffer colorData;
+vertexBuffer transparentData;
+vertexBuffer triangleData;
+
+const size_t Nbuffer=10000;
+const size_t nbuffer=1000;
+
+std::vector<Material> materials;
MaterialMap materialMap;
size_t materialIndex;
size_t Maxmaterials;
size_t Nmaterials=1;
size_t nmaterials=48;
+
+void clearCenters()
+{
+ camp::drawElement::centers.clear();
+ camp::drawElement::centermap.clear();
+}
+
+void clearMaterials()
+{
+ materials.clear();
+ materials.reserve(nmaterials);
+ materialMap.clear();
+
+ material0Data.partial=false;
+ material1Data.partial=false;
+ materialData.partial=false;
+ colorData.partial=false;
+ triangleData.partial=false;
+ transparentData.partial=false;
+}
+
}
extern void exitHandler(int);
namespace gl {
+GLint processors;
+GLint steps;
+
bool outlinemode=false;
+bool ibl=false;
bool glthread=false;
bool glupdate=false;
bool glexit=false;
@@ -130,11 +181,13 @@ bool firstFit;
bool queueExport=false;
bool readyAfterExport=false;
bool remesh;
+bool copied;
int Mode;
double Aspect;
bool View;
+bool ViewExport;
int Oldpid;
string Prefix;
const picture* Picture;
@@ -168,7 +221,8 @@ static const double pi=acos(-1.0);
static const double degrees=180.0/pi;
static const double radians=1.0/degrees;
-double *Background;
+double Background[4];
+
size_t Nlights=1; // Maximum number of lights compiled in shader
size_t nlights; // Actual number of lights
size_t nlights0;
@@ -183,6 +237,8 @@ double lastzoom;
GLint lastshader=-1;
+bool format3dWait=false;
+
using glm::dvec3;
using glm::dmat3;
using glm::mat3;
@@ -331,7 +387,9 @@ void home(bool webgl=false)
#endif
#endif
dviewMat=dmat4(1.0);
+#ifndef HAVE_SSBO
dView=value_ptr(dviewMat);
+#endif
viewMat=mat4(dviewMat);
drotateMat=dmat4(1.0);
@@ -363,38 +421,65 @@ int window;
using utils::statistics;
statistics S;
+GLint shaderProg,shaderProgColor;
-#ifdef HAVE_LIBOPENIMAGEIO
-GLuint envMapBuf;
+GLTexture2<float,GL_FLOAT> IBLbrdfTex;
+GLTexture2<float,GL_FLOAT> irradiance;
+GLTexture3<float,GL_FLOAT> reflTextures;
+
+GLTexture2<float,GL_FLOAT> fromEXR(string const& EXRFile, GLTexturesFmt const& fmt, GLint const& textureNumber)
+{
+ camp::IEXRFile fil(EXRFile);
+ return GLTexture2<float,GL_FLOAT> {fil.getData(),fil.size(),textureNumber,fmt};
+}
-GLuint initHDR() {
- GLuint tex;
- glGenTextures(1, &tex);
+GLTexture3<float,GL_FLOAT> fromEXR3(
+ mem::vector<string> const& EXRFiles, GLTexturesFmt const& fmt, GLint const& textureNumber)
+{
+ // 3d reflectance textures
+ std::vector<float> data;
+ size_t count=EXRFiles.size();
+ int wi=0, ht=0;
- auto imagein = OIIO::ImageInput::open(locateFile("res/studio006.hdr").c_str());
- OIIO::ImageSpec const& imspec = imagein->spec();
+ for (string const& EXRFile : EXRFiles)
+ {
+ camp::IEXRFile fil3(EXRFile);
+ std::tie(wi,ht)=fil3.size();
+ size_t imSize=4*wi*ht;
+ std::copy(fil3.getData(),fil3.getData()+imSize,std::back_inserter(data));
+ }
- // uses GL_TEXTURE1 for now.
- glActiveTexture(GL_TEXTURE1);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ return GLTexture3<float,GL_FLOAT> {data.data(),std::tuple<int,int,int>(wi,ht,count),textureNumber,fmt};
+}
- glBindTexture(GL_TEXTURE_2D, tex);
- std::vector<float> pixels(imspec.width*imspec.height*3);
- imagein->read_image(pixels.data());
+void initIBL()
+{
+ GLTexturesFmt fmt;
+ fmt.internalFmt=GL_RGB16F;
+ string imageDir=locateFile(getSetting<string>("imageDir"))+"/";
+ string imagePath=imageDir+getSetting<string>("image")+"/";
+ irradiance=fromEXR(imagePath+"diffuse.exr",fmt,1);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imspec.width, imspec.height, 0,
- GL_RGB, GL_FLOAT, pixels.data());
+ GLTexturesFmt fmtRefl;
+ fmtRefl.internalFmt=GL_RG16F;
+ IBLbrdfTex=fromEXR(imageDir+"refl.exr",fmtRefl,2);
- glGenerateMipmap(GL_TEXTURE_2D);
- imagein->close();
+ GLTexturesFmt fmt3;
+ fmt3.internalFmt=GL_RGB16F;
+ fmt3.wrapS=GL_REPEAT;
+ fmt3.wrapR=GL_CLAMP_TO_EDGE;
+ fmt3.wrapT=GL_CLAMP_TO_EDGE;
- glActiveTexture(GL_TEXTURE0);
- return tex;
-}
+ mem::vector<string> files;
+ mem::string prefix=imagePath+"refl";
+ for(unsigned int i=0; i <= 10; ++i) {
+ mem::stringstream mss;
+ mss << prefix << i << ".exr";
+ files.emplace_back(mss.str());
+ }
-#endif
-GLint shaderProg,shaderProgColor;
+ reflTextures=fromEXR3(files,fmt3,3);
+}
void *glrenderWrapper(void *a);
@@ -426,58 +511,144 @@ void wait(pthread_cond_t& signal, pthread_mutex_t& lock)
}
#endif
+void noShaders()
+{
+ cerr << "GLSL shaders not found." << endl;
+ exit(-1);
+}
+
void initShaders()
{
Nlights=nlights == 0 ? 0 : max(Nlights,nlights);
Nmaterials=max(Nmaterials,nmaterials);
shaderProg=glCreateProgram();
- string vs=locateFile("shaders/vertex.glsl");
- string fs=locateFile("shaders/fragment.glsl");
- if(vs.empty() || fs.empty()) {
- cerr << "GLSL shaders not found." << endl;
- exit(-1);
- }
+ string zero=locateFile("shaders/count0.glsl");
+ string vertex=locateFile("shaders/vertex.glsl");
+ string fragment=locateFile("shaders/fragment.glsl");
+ string blend=locateFile("shaders/blend.glsl");
+ string screen=locateFile("shaders/screen.glsl");
+ string pre=locateFile("shaders/presum.glsl");
+ string partial=locateFile("shaders/partialsum.glsl");
+ string post=locateFile("shaders/postsum.glsl");
+
+ if(vertex.empty() || fragment.empty() || blend.empty() || screen.empty() ||
+ zero.empty() || pre.empty() || partial.empty() || post.empty())
+ noShaders();
+
+ std::vector<ShaderfileModePair> shaders(1);
std::vector<std::string> shaderParams;
-#if HAVE_LIBOPENIMAGEIO
- if (getSetting<bool>("envmap")) {
- shaderParams.push_back("ENABLE_TEXTURE");
- envMapBuf=initHDR();
+ if(ibl) {
+ shaderParams.push_back("USE_IBL");
+ initIBL();
}
+
+#ifdef HAVE_SSBO
+ if(GPUindexing) {
+ shaders[0]=ShaderfileModePair(pre.c_str(),GL_COMPUTE_SHADER);
+ GLuint rc=compileAndLinkShader(shaders,shaderParams,true);
+ if(rc == 0)
+ GPUindexing=false; // Compute shaders are unavailable.
+ else {
+ camp::preSumShader=rc;
+
+ ostringstream s;
+ s << "PROCESSORS " << processors << "u" << endl;
+ shaderParams.push_back(s.str().c_str());
+ shaders[0]=ShaderfileModePair(partial.c_str(),GL_COMPUTE_SHADER);
+ camp::partialSumShader=compileAndLinkShader(shaders,shaderParams,true);
+ shaderParams.pop_back();
+
+ shaders[0]=ShaderfileModePair(post.c_str(),GL_COMPUTE_SHADER);
+ camp::postSumShader=compileAndLinkShader(shaders,shaderParams,true);
+ }
+ }
+#endif
+ string count=locateFile(GPUindexing ? "shaders/offset.glsl" :
+ "shaders/count.glsl");
+ if(count.empty())
+ noShaders();
+
+ shaders.push_back(ShaderfileModePair());
+
+ shaders[0]=ShaderfileModePair(vertex.c_str(),GL_VERTEX_SHADER);
+
+#ifdef HAVE_SSBO
+ shaders[1]=ShaderfileModePair(count.c_str(),GL_FRAGMENT_SHADER);
+ camp::countShader=compileAndLinkShader(shaders,shaderParams);
+ shaderParams.push_back("HAVE_SSBO");
#endif
- std::vector<ShaderfileModePair> shaders;
- shaders.push_back(ShaderfileModePair(vs.c_str(),GL_VERTEX_SHADER));
- shaders.push_back(ShaderfileModePair(fs.c_str(),GL_FRAGMENT_SHADER));
+ shaders[1]=ShaderfileModePair(fragment.c_str(),GL_FRAGMENT_SHADER);
+ shaderParams.push_back("MATERIAL");
if(orthographic)
shaderParams.push_back("ORTHOGRAPHIC");
+ ostringstream lights,materials;
+ lights << "Nlights " << Nlights << endl;
+ shaderParams.push_back(lights.str().c_str());
+ materials << "Nmaterials " << Nmaterials << endl;
+ shaderParams.push_back(materials.str().c_str());
+
shaderParams.push_back("WIDTH");
- camp::pixelShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
- shaderParams);
+ camp::pixelShader=compileAndLinkShader(shaders,shaderParams);
shaderParams.pop_back();
shaderParams.push_back("NORMAL");
- camp::materialShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
- shaderParams);
+ camp::materialShader=compileAndLinkShader(shaders,shaderParams);
shaderParams.push_back("COLOR");
- camp::colorShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
- shaderParams);
+ camp::colorShader=compileAndLinkShader(shaders,shaderParams);
+
+ shaderParams.push_back("GENERAL");
+ if(Mode == 2)
+ shaderParams.push_back("WIREFRAME");
+ camp::generalShader=compileAndLinkShader(shaders,shaderParams);
+
shaderParams.push_back("TRANSPARENT");
- camp::transparentShader=compileAndLinkShader(shaders,Nlights,Nmaterials,
- shaderParams);
+ camp::transparentShader=compileAndLinkShader(shaders,shaderParams);
+ shaderParams.clear();
+#ifdef HAVE_SSBO
+ shaders[0]=ShaderfileModePair(screen.c_str(),GL_VERTEX_SHADER);
+
+ if(GPUindexing)
+ shaderParams.push_back("GPUINDEXING");
+ else {
+ shaders[1]=ShaderfileModePair(zero.c_str(),GL_FRAGMENT_SHADER);
+ camp::zeroShader=compileAndLinkShader(shaders,shaderParams);
+ }
+
+ shaders[1]=ShaderfileModePair(blend.c_str(),GL_FRAGMENT_SHADER);
+ camp::blendShader=compileAndLinkShader(shaders,shaderParams);
+#endif
}
void deleteShaders()
{
+#ifdef HAVE_SSBO
+ glDeleteProgram(camp::blendShader);
+ if(GPUindexing) {
+ glDeleteProgram(camp::preSumShader);
+ glDeleteProgram(camp::partialSumShader);
+ glDeleteProgram(camp::postSumShader);
+ } else
+ glDeleteProgram(camp::zeroShader);
+ glDeleteProgram(camp::countShader);
+#endif
glDeleteProgram(camp::transparentShader);
+ glDeleteProgram(camp::generalShader);
glDeleteProgram(camp::colorShader);
glDeleteProgram(camp::materialShader);
glDeleteProgram(camp::pixelShader);
}
+struct Fragment
+{
+ glm::vec4 color;
+ glm::vec4 depth; // Pad depth to a glm::vec4
+};
+
void setBuffers()
{
GLuint vao;
@@ -489,6 +660,14 @@ void setBuffers()
camp::colorData.Reserve();
camp::triangleData.Reserve();
camp::transparentData.Reserve();
+
+#ifdef HAVE_SSBO
+ glGenBuffers(1, &camp::countBuffer);
+ glGenBuffers(1, &camp::offsetBuffer);
+ if(GPUindexing)
+ glGenBuffers(1, &camp::sumBuffer);
+ glGenBuffers(1, &camp::fragmentBuffer);
+#endif
}
void drawscene(int Width, int Height)
@@ -500,6 +679,9 @@ void drawscene(int Width, int Height)
endwait(initSignal,initLock);
first=false;
}
+
+ if(format3dWait)
+ wait(initSignal,initLock);
#endif
if((nlights == 0 && Nlights > 0) || nlights > Nlights ||
@@ -518,7 +700,7 @@ void drawscene(int Width, int Height)
double size2=hypot(Width,Height);
if(remesh)
- camp::drawElement::center.clear();
+ camp::clearCenters();
Picture->render(size2,m,M,perspective,remesh);
@@ -526,24 +708,30 @@ void drawscene(int Width, int Height)
}
// Return x divided by y rounded up to the nearest integer.
-int Quotient(int x, int y)
+int ceilquotient(int x, int y)
{
return (x+y-1)/y;
}
+bool exporting=false;
+
void Export()
{
+ size_t ndata=3*fullWidth*fullHeight;
+ if(ndata == 0) return;
glReadBuffer(GL_BACK_LEFT);
glPixelStorei(GL_PACK_ALIGNMENT,1);
glFinish();
+ exporting=true;
try {
- size_t ndata=3*fullWidth*fullHeight;
unsigned char *data=new unsigned char[ndata];
if(data) {
TRcontext *tr=trNew();
- int width=Quotient(fullWidth,Quotient(fullWidth,min(maxTileWidth,Width)));
- int height=Quotient(fullHeight,Quotient(fullHeight,
- min(maxTileHeight,Height)));
+ int width=ceilquotient(fullWidth,
+ ceilquotient(fullWidth,min(maxTileWidth,Width)));
+ int height=ceilquotient(fullHeight,
+ ceilquotient(fullHeight,
+ min(maxTileHeight,Height)));
if(settings::verbose > 1)
cout << "Exporting " << Prefix << " as " << fullWidth << "x"
<< fullHeight << " image" << " using tiles of size "
@@ -579,11 +767,11 @@ void Export()
transform(0.0,0.0,w,0.0,0.0,h),
antialias);
pic.append(Image);
- pic.shipout(NULL,Prefix,Format,false,View);
+ pic.shipout(NULL,Prefix,Format,false,ViewExport);
delete Image;
delete[] data;
}
- } catch(handled_error) {
+ } catch(handled_error const&) {
} catch(std::bad_alloc&) {
outOfMemory();
}
@@ -602,6 +790,7 @@ void Export()
}
#endif
#endif
+ exporting=false;
}
void nodisplay()
@@ -657,23 +846,27 @@ void quit()
void mode()
{
remesh=true;
+ camp::initSSBO=true;
+ ++Mode;
+ if(Mode > 2) Mode=0;
+
switch(Mode) {
case 0: // regular
outlinemode=false;
+ ibl=getSetting<bool>("ibl");
nlights=nlights0;
lastshader=-1;
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
- ++Mode;
break;
case 1: // outline
outlinemode=true;
- nlights=0;
+ ibl=false;
+ nlights=0; // Force shader recompilation
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
- ++Mode;
break;
case 2: // wireframe
outlinemode=false;
- Mode=0;
+ Nlights=1; // Force shader recompilation
break;
}
#ifdef HAVE_LIBGLUT
@@ -709,6 +902,7 @@ void reshape0(int width, int height)
setProjection();
glViewport(0,0,Width,Height);
+ camp::initSSBO=true;
}
void windowposition(int& x, int& y, int width=Width, int height=Height)
@@ -859,8 +1053,9 @@ void display()
if(s > 0.0) {
double rate=1.0/s;
S.add(rate);
- cout << "FPS=" << rate << "\t" << S.mean() << " +/- " << S.stdev()
- << endl;
+ if(framecount % 20 == 0)
+ cout << "FPS=" << rate << "\t" << S.mean() << " +/- " << S.stdev()
+ << endl;
}
}
++framecount;
@@ -908,7 +1103,9 @@ void update()
dviewMat=translate(translate(dmat4(1.0),dvec3(cx,cy,cz))*drotateMat,
dvec3(0,0,-cz));
+#ifndef HAVE_SSBO
dView=value_ptr(dviewMat);
+#endif
viewMat=mat4(dviewMat);
setProjection();
@@ -1480,6 +1677,7 @@ void init()
int argc=cmd.size();
#ifndef __APPLE__
+ glutInitContextVersion(4,0);
glutInitContextProfile(GLUT_CORE_PROFILE);
#endif
@@ -1505,10 +1703,24 @@ void init_osmesa()
exit(-1);
}
- ctx = OSMesaCreateContextExt(OSMESA_RGBA,16,0,0,NULL);
+ const int attribs[]={
+ OSMESA_FORMAT,OSMESA_RGBA,
+ OSMESA_DEPTH_BITS,16,
+ OSMESA_STENCIL_BITS,0,
+ OSMESA_ACCUM_BITS,0,
+ OSMESA_PROFILE,OSMESA_CORE_PROFILE,
+ OSMESA_CONTEXT_MAJOR_VERSION,4,
+ OSMESA_CONTEXT_MINOR_VERSION,3,
+ 0,0
+ };
+
+ ctx=OSMesaCreateContextAttribs(attribs,NULL);
if(!ctx) {
- cerr << "OSMesaCreateContext failed." << endl;
- exit(-1);
+ ctx=OSMesaCreateContextExt(OSMESA_RGBA,16,0,0,NULL);
+ if(!ctx) {
+ cerr << "OSMesaCreateContextExt failed." << endl;
+ exit(-1);
+ }
}
if(!OSMesaMakeCurrent(ctx,osmesa_buffer,GL_UNSIGNED_BYTE,
@@ -1534,6 +1746,12 @@ void init_osmesa()
#endif /* HAVE_GL */
+// Return ceil(log2(n)) where n is a 32 bit unsigned integer.
+uint32_t ceillog2(uint32_t n)
+{
+ return 32-CLZ(n-1);
+}
+
// angle=0 means orthographic.
void glrender(const string& prefix, const picture *pic, const string& format,
double width, double height, double angle, double zoom,
@@ -1544,6 +1762,12 @@ void glrender(const string& prefix, const picture *pic, const string& format,
{
Iconify=getSetting<bool>("iconify");
+#if defined(HAVE_COMPUTE_SHADER) && !defined(HAVE_LIBOSMESA)
+ GPUindexing=getSetting<bool>("GPUindexing");
+#else
+ GPUindexing=false;
+#endif
+
if(zoom == 0.0) zoom=1.0;
Prefix=prefix;
@@ -1561,7 +1785,8 @@ void glrender(const string& prefix, const picture *pic, const string& format,
Oldpid=oldpid;
Shift=shift/zoom;
Margin=margin;
- Background=background;
+ for(size_t i=0; i < 4; ++i)
+ Background[i]=background[i];
Xmin=m.getx();
Xmax=M.getx();
@@ -1574,7 +1799,6 @@ void glrender(const string& prefix, const picture *pic, const string& format,
H=orthographic ? 0.0 : -tan(0.5*Angle)*zmax;
ignorezoom=false;
- Mode=0;
Xfactor=Yfactor=1.0;
pair maxtile=getSetting<pair>("maxtile");
@@ -1583,7 +1807,9 @@ void glrender(const string& prefix, const picture *pic, const string& format,
if(maxTileWidth <= 0) maxTileWidth=1024;
if(maxTileHeight <= 0) maxTileHeight=768;
- bool webgl=Format == "html";
+ bool v3d=format == "v3d";
+ bool webgl=format == "html";
+ bool format3d=webgl || v3d;
#ifdef HAVE_GL
#ifdef HAVE_PTHREAD
@@ -1607,7 +1833,7 @@ void glrender(const string& prefix, const picture *pic, const string& format,
}
#else
if(glinitialize) {
- if(!webgl) init();
+ if(!format3d) init();
Fitscreen=1;
}
#endif
@@ -1619,7 +1845,7 @@ void glrender(const string& prefix, const picture *pic, const string& format,
getSetting<bool>("animating")))) {
antialias=getSetting<Int>("antialias") > 1;
double expand;
- if(webgl)
+ if(format3d)
expand=1.0;
else {
expand=getSetting<double>("render");
@@ -1651,7 +1877,7 @@ void glrender(const string& prefix, const picture *pic, const string& format,
fullWidth=(int) ceil(expand*width);
fullHeight=(int) ceil(expand*height);
- if(webgl) {
+ if(format3d) {
Width=fullWidth;
Height=fullHeight;
} else {
@@ -1664,9 +1890,14 @@ void glrender(const string& prefix, const picture *pic, const string& format,
Height=min((int) (ceil(Width/Aspect)),screenHeight);
}
- home(webgl);
+ home(format3d);
setProjection();
- if(webgl) return;
+ if(format3d) {
+ remesh=true;
+ return;
+ }
+
+ camp::maxFragments=0;
ArcballFactor=1+8.0*hypot(Margin.getx(),Margin.gety())/hypot(Width,Height);
@@ -1701,7 +1932,10 @@ void glrender(const string& prefix, const picture *pic, const string& format,
#endif
#endif
- camp::clearMaterialBuffer();
+ if(glthread && format3d)
+ format3dWait=true;
+
+ camp::clearMaterials();
#ifndef HAVE_LIBOSMESA
@@ -1786,23 +2020,54 @@ void glrender(const string& prefix, const picture *pic, const string& format,
GLint val;
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE,&val);
+
+ if(GPUindexing) {
+ glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS,&processors);
+ if(processors <= 1)
+ GPUindexing=false;
+ else
+ steps=ceillog2(processors);
+ }
+
Maxmaterials=val/sizeof(Material);
if(nmaterials > Maxmaterials) nmaterials=Maxmaterials;
if(glinitialize) {
glinitialize=false;
+
+ char *GLSL_VERSION=(char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
+ GLSLversion=(int) (100*atof(GLSL_VERSION)+0.5);
+
+ if(GLSLversion < 130) {
+ cerr << "Unsupported GLSL version: " << GLSL_VERSION << "." << endl;
+ exit(-1);
+ }
+
+ if(settings::verbose > 2) {
+ cout << "GLSL version " << GLSL_VERSION;
+#ifdef HAVE_SSBO
+ cout << " with SSBO";
+#ifdef HAVE_COMPUTE_SHADER
+ cout << " and compute shader";
+#endif
+ cout << " support";
+#endif
+ cout << endl;
+ }
+
int result = glewInit();
- if (result != GLEW_OK) {
+ if(result != GLEW_OK) {
cerr << "GLEW initialization error." << endl;
exit(-1);
}
+ ibl=getSetting<bool>("ibl");
initShaders();
setBuffers();
}
- glClearColor(Background[0],Background[1],Background[2],Background[3]);
+ glClearColor(background[0],background[1],background[2],background[3]);
#ifdef HAVE_LIBGLUT
#ifndef HAVE_LIBOSMESA
@@ -1818,13 +2083,19 @@ void glrender(const string& prefix, const picture *pic, const string& format,
#endif
#endif
- glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
+ glEnable(GL_TEXTURE_3D);
+#ifndef HAVE_SSBO
+ glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+#endif
+
+ Mode=2;
mode();
+ ViewExport=View;
#ifdef HAVE_LIBOSMESA
View=false;
#endif
@@ -1905,6 +2176,125 @@ void registerBuffer(const std::vector<T>& buffervector, GLuint& bufferIndex,
}
}
+void clearCount()
+{
+ glUseProgram(zeroShader);
+ glUniform1ui(glGetUniformLocation(zeroShader,"width"),gl::Width);
+ gl::lastshader=zeroShader;
+ fpu_trap(false); // Work around FE_INVALID
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ fpu_trap(settings::trap());
+ glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
+}
+
+void refreshBuffers()
+{
+ GLuint zero=0;
+ GLuint fragments=0;
+ GLuint pixels=gl::Width*gl::Height;
+
+ if(initSSBO) {
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::offsetBuffer);
+ glBufferData(GL_SHADER_STORAGE_BUFFER,(1+pixels)*sizeof(GLuint),NULL,
+ GL_DYNAMIC_DRAW);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER,1,camp::offsetBuffer);
+ glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8UI,GL_RED_INTEGER,
+ GL_UNSIGNED_BYTE,&zero);
+
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::countBuffer);
+ glBufferData(GL_SHADER_STORAGE_BUFFER,pixels*sizeof(GLuint),NULL,
+ GL_DYNAMIC_DRAW);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER,2,camp::countBuffer);
+ glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8UI,GL_RED_INTEGER,
+ GL_UNSIGNED_BYTE,&zero);
+
+ if(GPUindexing) {
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::sumBuffer);
+ glBufferData(GL_SHADER_STORAGE_BUFFER,gl::processors*sizeof(GLuint),NULL,
+ GL_DYNAMIC_DRAW);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER,0,camp::sumBuffer);
+ }
+
+ initSSBO=false;
+ }
+
+ if(GPUindexing) {
+ if(gl::exporting) {
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER,1,camp::offsetBuffer);
+ glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8UI,GL_RED_INTEGER,
+ GL_UNSIGNED_BYTE,&zero);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER,0,camp::sumBuffer);
+ }
+ }
+
+ // Determine the fragment offsets
+ drawBuffer(material0Data,countShader); // TODO: Account for pixel width
+ drawBuffer(material1Data,countShader);
+ drawBuffer(materialData,countShader);
+ drawBuffer(colorData,countShader,true);
+ drawBuffer(triangleData,countShader,true);
+
+ glDepthMask(GL_FALSE); // Don't write to depth buffer
+ glDisable(GL_MULTISAMPLE);
+ drawBuffer(transparentData,countShader,true);
+ glEnable(GL_MULTISAMPLE);
+ glDepthMask(GL_TRUE); // Write to depth buffer
+
+ if(GPUindexing) { // Compute partial sums directly on the GPU
+ glUseProgram(preSumShader);
+ glUniform1ui(glGetUniformLocation(preSumShader,"elements"),pixels);
+ glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
+ glDispatchCompute(gl::processors,1,1);
+
+ glUseProgram(partialSumShader);
+ glUniform1ui(glGetUniformLocation(partialSumShader,"elements"),pixels);
+ glUniform1ui(glGetUniformLocation(partialSumShader,"steps"),gl::steps);
+
+ glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
+ glDispatchCompute(1,1,1);
+
+ glUseProgram(postSumShader);
+ glUniform1ui(glGetUniformLocation(postSumShader,"elements"),pixels);
+
+ glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
+ glGetBufferSubData(GL_SHADER_STORAGE_BUFFER,0,sizeof(GLuint),&fragments);
+ } else { // Compute partial sums on the CPU
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::countBuffer);
+ GLuint *countm1=(GLuint *) (glMapBuffer(GL_SHADER_STORAGE_BUFFER,GL_READ_ONLY))-1;
+
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::offsetBuffer);
+ GLuint *offset=(GLuint *) glMapBuffer(GL_SHADER_STORAGE_BUFFER,GL_WRITE_ONLY);
+ size_t Offset=0;
+ offset[0]=0;
+ for(size_t i=1; i < pixels; ++i)
+ offset[i]=Offset += countm1[i];
+ fragments=offset[pixels-1]+countm1[pixels];
+
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::offsetBuffer);
+ glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
+
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::countBuffer);
+ glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
+
+ clearCount();
+ }
+
+ if(fragments > maxFragments) {
+ // Initialize the alpha buffer
+ maxFragments=11*fragments/10;
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::fragmentBuffer);
+ glBufferData(GL_SHADER_STORAGE_BUFFER,maxFragments*sizeof(gl::Fragment),
+ NULL,GL_DYNAMIC_DRAW);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER,3,camp::fragmentBuffer);
+
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::sumBuffer);
+ }
+
+ if(GPUindexing)
+ glDispatchCompute(gl::processors,1,1);
+ gl::lastshader=-1;
+}
+
void setUniforms(vertexBuffer& data, GLint shader)
{
bool normal=shader != pixelShader;
@@ -1913,7 +2303,10 @@ void setUniforms(vertexBuffer& data, GLint shader)
glUseProgram(shader);
gl::lastshader=shader;
- glUniform1i(glGetUniformLocation(shader,"nlights"),gl::nlights);
+#ifdef HAVE_SSBO
+ glUniform1ui(glGetUniformLocation(shader,"width"),gl::Width);
+#endif
+ glUniform1ui(glGetUniformLocation(shader,"nlights"),gl::nlights);
for(size_t i=0; i < gl::nlights; ++i) {
triple Lighti=gl::Lights[i];
@@ -1929,21 +2322,17 @@ void setUniforms(vertexBuffer& data, GLint shader)
(GLfloat) gl::Diffuse[i4+2]);
}
-#if HAVE_LIBOPENIMAGEIO
- // textures
- if (settings::getSetting<bool>("envmap")) {
- glActiveTexture(GL_TEXTURE1);
- glBindBuffer(GL_TEXTURE_2D, gl::envMapBuf);
- glUniform1i(glGetUniformLocation(shader, "environmentMap"), 1);
- glActiveTexture(GL_TEXTURE0);
+ if (settings::getSetting<bool>("ibl")) {
+ gl::IBLbrdfTex.setUniform(glGetUniformLocation(shader,"reflBRDFSampler"));
+ gl::irradiance.setUniform(glGetUniformLocation(shader,"diffuseSampler"));
+ gl::reflTextures.setUniform(glGetUniformLocation(shader,"reflImgSampler"));
}
-#endif
}
GLuint binding=0;
GLint blockindex=glGetUniformBlockIndex(shader,"MaterialBuffer");
glUniformBlockBinding(shader,blockindex,binding);
- bool copy=gl::remesh || data.partial || !data.rendered;
+ bool copy=(gl::remesh || data.partial || !data.rendered) && !gl::copied;
registerBuffer(data.materials,data.materialsBuffer,copy,GL_UNIFORM_BUFFER);
glBindBufferBase(GL_UNIFORM_BUFFER,binding,data.materialsBuffer);
@@ -1957,19 +2346,18 @@ void setUniforms(vertexBuffer& data, GLint shader)
value_ptr(gl::normMat));
}
-void drawBuffer(vertexBuffer& data, GLint shader)
+void drawBuffer(vertexBuffer& data, GLint shader, bool color)
{
if(data.indices.empty()) return;
bool normal=shader != pixelShader;
- bool color=shader == colorShader || shader == transparentShader;
const size_t size=sizeof(GLfloat);
const size_t intsize=sizeof(GLint);
const size_t bytestride=color ? sizeof(VertexData) :
(normal ? sizeof(vertexData) : sizeof(vertexData0));
- bool copy=gl::remesh || data.partial || !data.rendered;
+ bool copy=(gl::remesh || data.partial || !data.rendered) && !gl::copied;
if(color) registerBuffer(data.Vertices,data.VerticesBuffer,copy);
else if(normal) registerBuffer(data.vertices,data.verticesBuffer,copy);
else registerBuffer(data.vertices0,data.vertices0Buffer,copy);
@@ -1999,7 +2387,7 @@ void drawBuffer(vertexBuffer& data, GLint shader)
glEnableVertexAttribArray(materialAttrib);
if(color) {
- glVertexAttribPointer(colorAttrib,4,GL_UNSIGNED_BYTE,GL_TRUE,bytestride,
+ glVertexAttribPointer(colorAttrib,4,GL_FLOAT,GL_FALSE,bytestride,
(void *) (6*size+intsize));
glEnableVertexAttribArray(colorAttrib);
}
@@ -2018,7 +2406,6 @@ void drawBuffer(vertexBuffer& data, GLint shader)
glDisableVertexAttribArray(colorAttrib);
glBindBuffer(GL_UNIFORM_BUFFER,0);
-
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
}
@@ -2043,50 +2430,74 @@ void drawMaterial()
void drawColor()
{
- drawBuffer(colorData,colorShader);
+ drawBuffer(colorData,colorShader,true);
colorData.clear();
}
void drawTriangle()
{
- drawBuffer(triangleData,transparentShader);
- triangleData.rendered=false; // Force copying of sorted triangles to GPU.
+ drawBuffer(triangleData,generalShader,true);
triangleData.clear();
}
+void aBufferTransparency()
+{
+ // Collect transparent fragments
+ glDepthMask(GL_FALSE); // Disregard depth
+ drawBuffer(transparentData,transparentShader,true);
+ glDepthMask(GL_TRUE); // Respect depth
+
+ // Blend transparent fragments
+ glDisable(GL_DEPTH_TEST);
+ glUseProgram(blendShader);
+ glUniform1ui(glGetUniformLocation(blendShader,"width"),gl::Width);
+ glUniform4f(glGetUniformLocation(blendShader,"background"),
+ gl::Background[0],gl::Background[1],gl::Background[2],
+ gl::Background[3]);
+ gl::lastshader=blendShader;
+ fpu_trap(false); // Work around FE_INVALID
+ glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ fpu_trap(settings::trap());
+ transparentData.clear();
+ glEnable(GL_DEPTH_TEST);
+}
+
void drawTransparent()
{
+#ifdef HAVE_SSBO
+ glDisable(GL_MULTISAMPLE);
+ aBufferTransparency();
+ glEnable(GL_MULTISAMPLE);
+#else
sortTriangles();
- glDepthMask(GL_FALSE); // Enable transparency
- drawBuffer(transparentData,transparentShader);
- transparentData.rendered=false; // Force copying of sorted triangles to GPU.
- glDepthMask(GL_TRUE); // Disable transparency
+ transparentData.rendered=false; // Force copying of sorted triangles to GPU
+ glDepthMask(GL_FALSE); // Don't write to depth buffer
+ drawBuffer(transparentData,transparentShader,true);
+ glDepthMask(GL_TRUE); // Write to depth buffer
transparentData.clear();
+#endif
}
void drawBuffers()
{
+ gl::copied=false;
+ bool transparent=!transparentData.indices.empty();
+#ifdef HAVE_SSBO
+ if(transparent) {
+ refreshBuffers();
+ gl::copied=true;
+ }
+#endif
+
drawMaterial0();
drawMaterial1();
drawMaterial();
drawColor();
drawTriangle();
- drawTransparent();
-}
-void clearMaterialBuffer()
-{
- material.clear();
- material.reserve(nmaterials);
- materialMap.clear();
- materialIndex=0;
-
- material0Data.partial=false;
- material1Data.partial=false;
- materialData.partial=false;
- colorData.partial=false;
- triangleData.partial=false;
- transparentData.partial=false;
+ if(transparent)
+ drawTransparent();
}
void setMaterial(vertexBuffer& data, draw_t *draw)
@@ -2102,7 +2513,7 @@ void setMaterial(vertexBuffer& data, draw_t *draw)
for(size_t i=size0; i < materialIndex; ++i)
data.materialTable[i]=-1;
data.materialTable[materialIndex]=data.materials.size();
- data.materials.push_back(material[materialIndex]);
+ data.materials.push_back(materials[materialIndex]);
}
materialIndex=data.materialTable[materialIndex];
}
diff --git a/graphics/asymptote/glrender.h b/graphics/asymptote/glrender.h
index 44da4fe612..7f4529c50b 100644
--- a/graphics/asymptote/glrender.h
+++ b/graphics/asymptote/glrender.h
@@ -71,6 +71,11 @@ typedef unsigned int GLuint;
typedef int GLint;
typedef float GLfloat;
typedef double GLdouble;
+typedef unsigned char GLubyte;
+typedef unsigned int GLenum;
+#define GL_POINTS 0x0000
+#define GL_LINES 0x0001
+#define GL_TRIANGLES 0x0004
#endif
#ifdef HAVE_LIBGLM
@@ -122,7 +127,7 @@ extern camp::pair Margin;
extern camp::triple *Lights;
extern size_t nlights;
extern double *Diffuse;
-extern double *Background;
+extern double Background[4];
struct projection
{
@@ -162,6 +167,8 @@ extern const double *dView;
extern double BBT[9];
+extern bool format3dWait;
+
}
namespace camp {
@@ -191,13 +198,10 @@ extern Billboard BB;
#ifdef HAVE_LIBGLM
typedef mem::map<CONST Material,size_t> MaterialMap;
-extern std::vector<Material> material;
+extern std::vector<Material> materials;
extern MaterialMap materialMap;
extern size_t materialIndex;
extern int MaterialIndex;
-#endif
-
-#ifdef HAVE_GL
extern const size_t Nbuffer; // Initial size of 2D dynamic buffers
extern const size_t nbuffer; // Initial size of 0D & 1D dynamic buffers
@@ -226,7 +230,7 @@ public:
GLfloat position[3];
GLfloat normal[3];
GLint material;
- GLubyte color[4];
+ GLfloat color[4];
VertexData() {};
VertexData(const triple& v, const triple& n) {
position[0]=v.getx();
@@ -245,10 +249,10 @@ public:
normal[1]=n.gety();
normal[2]=n.getz();
material=MaterialIndex;
- color[0]=(int)(bytescale*c[0]);
- color[1]=(int)(bytescale*c[1]);
- color[2]=(int)(bytescale*c[2]);
- color[3]=(int)(bytescale*c[3]);
+ color[0]=c[0];
+ color[1]=c[1];
+ color[2]=c[2];
+ color[3]=c[3];
}
};
@@ -256,7 +260,7 @@ class vertexData0 {
public:
GLfloat position[3];
GLfloat width;
- GLint material;
+ GLint material;
vertexData0() {};
vertexData0(const triple& v, double width) : width(width) {
position[0]=v.getx();
@@ -387,9 +391,11 @@ extern vertexBuffer colorData; // colored Bezier patches & triangles
extern vertexBuffer triangleData; // opaque indexed triangles
extern vertexBuffer transparentData; // transparent patches & triangles
-void drawBuffer(vertexBuffer& data, GLint shader);
+void drawBuffer(vertexBuffer& data, GLint shader, bool color=false);
void drawBuffers();
-void clearMaterialBuffer();
+
+void clearMaterials();
+void clearCenters();
typedef void draw_t();
void setMaterial(vertexBuffer& data, draw_t *draw);
diff --git a/graphics/asymptote/impdatum.cc b/graphics/asymptote/impdatum.cc
index af074c8540..9a4d09d1bf 100644
--- a/graphics/asymptote/impdatum.cc
+++ b/graphics/asymptote/impdatum.cc
@@ -38,7 +38,7 @@ public:
void prettyprint(ostream &out, Int indent)
{
- absyntax::prettyname(out, "errorExp", indent);
+ absyntax::prettyname(out, "errorExp", indent, getPos());
}
void complain() {
diff --git a/graphics/asymptote/index.html b/graphics/asymptote/index.html
new file mode 100644
index 0000000000..f3127e4de3
--- /dev/null
+++ b/graphics/asymptote/index.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<html lang=en>
+<head>
+<meta charset=utf-8>
+<title>Asymptote Source Code</title>
+</head>
+<body>
+</body>
+</html>
diff --git a/graphics/asymptote/interact.cc b/graphics/asymptote/interact.cc
index ad472942d5..7cb6d80a7e 100644
--- a/graphics/asymptote/interact.cc
+++ b/graphics/asymptote/interact.cc
@@ -174,10 +174,14 @@ string simpleline(string prompt) {
free(line);
return s;
} else {
- cout << endl;
+#if defined(HAVE_READLINE) && defined(HAVE_LIBCURSES)
if(!tty || getSetting<bool>("exitonEOF"))
- throw eof();
- return "\n";
+#endif
+ {
+ cout << endl;
+ throw eof();
+ }
+ return "";
}
}
diff --git a/graphics/asymptote/jsfile.cc b/graphics/asymptote/jsfile.cc
index 605d2108b4..b04c90f63e 100644
--- a/graphics/asymptote/jsfile.cc
+++ b/graphics/asymptote/jsfile.cc
@@ -8,6 +8,32 @@ using namespace settings;
namespace camp {
+jsfile::jsfile() : finished(false), fileName("")
+{
+
+}
+
+jsfile::jsfile(string name) : finished(false), fileName(name)
+{
+ open(name);
+}
+
+jsfile::~jsfile()
+{
+ if (!finished)
+ {
+ finish(fileName);
+ }
+}
+
+void jsfile::close()
+{
+ if (!finished)
+ {
+ finish(fileName);
+ }
+}
+
void jsfile::copy(string name, bool header)
{
std::ifstream fin(locateFile(name).c_str());
@@ -68,6 +94,7 @@ void jsfile::svgtohtml(string prefix)
out << "<body>" << newl << newl;
copy(locateFile(auxname(prefix,"svg")),true);
footer(name);
+ finished=true;
}
#ifdef HAVE_LIBGLM
@@ -92,33 +119,48 @@ void jsfile::open(string name)
out.precision(getSetting<Int>("digits"));
+ bool ibl=getSetting<bool>("ibl");
+ bool webgl2=ibl || getSetting<bool>("webgl2");
+ if(ibl)
+ out << "<script src=\"https://vectorgraphics.gitlab.io/asymptote/ibl/tinyexr.js\">"
+ << newl << "</script>" << newl;
+
if(getSetting<bool>("offline")) {
out << "<script>" << newl;
copy(locateFile(AsyGL));
out << newl << "</script>" << newl;
- } else {
+ } else
out << "<script" << newl << "src=\""
<< getSetting<string>("asygl") << "\">" << newl << "</script>" << newl;
- }
+
out << newl << "<script>" << newl;
out << newl
<< "canvasWidth=" << gl::fullWidth << ";" << newl
- << "canvasHeight=" << gl::fullHeight << ";" << newl
+ << "canvasHeight=" << gl::fullHeight << ";" << newl << newl
+ << "webgl2=" << std::boolalpha << webgl2 << ";"
+ << newl
+ << "ibl=" << std::boolalpha << ibl << ";"
+ << newl
<< "absolute=" << std::boolalpha << getSetting<bool>("absolute") << ";"
- << newl << newl
- << "b=[" << gl::xmin << "," << gl::ymin << "," << gl::zmin << "];"
+ << newl;
+ if(ibl) {
+ out << "imageURL=\"" << getSetting<string>("imageURL")+"/\";" << newl;
+ out << "image=\"" << getSetting<string>("image") << "\";" << newl << newl;
+ }
+ out << newl
+ << "minBound=[" << gl::xmin << "," << gl::ymin << "," << gl::zmin << "];"
<< newl
- << "B=[" << gl::xmax << "," << gl::ymax << "," << gl::zmax << "];"
+ << "maxBound=[" << gl::xmax << "," << gl::ymax << "," << gl::zmax << "];"
<< newl
<< "orthographic=" << gl::orthographic << ";"
<< newl
- << "angle=" << gl::Angle << ";"
+ << "angleOfView=" << gl::Angle << ";"
<< newl
- << "Zoom0=" << gl::Zoom0 << ";" << newl
- << "viewportmargin=" << gl::Margin << ";" << newl;
- if(gl::Shift != pair(0.0,0.0))
- out << "viewportshift=" << gl::Shift*gl::Zoom0 << ";" << newl;
- out << "zoomFactor=" << getSetting<double>("zoomfactor") << ";" << newl
+ << "initialZoom=" << gl::Zoom0 << ";" << newl;
+ if(gl::Shift != pair(0.0,0.0))
+ out << "viewportShift=" << gl::Shift*gl::Zoom0 << ";" << newl;
+ out << "viewportMargin=" << gl::Margin << ";" << newl << newl
+ << "zoomFactor=" << getSetting<double>("zoomfactor") << ";" << newl
<< "zoomPinchFactor=" << getSetting<double>("zoomPinchFactor") << ";"
<< newl
<< "zoomPinchCap=" << getSetting<double>("zoomPinchCap") << ";" << newl
@@ -133,31 +175,27 @@ void jsfile::open(string name)
for(size_t i=0; i < gl::nlights; ++i) {
size_t i4=4*i;
out << "new Light(" << newl
- << "direction=" << gl::Lights[i] << "," << newl
- << "color=[" << gl::Diffuse[i4] << "," << gl::Diffuse[i4+1] << ","
+ << gl::Lights[i] << "," << newl
+ << "[" << gl::Diffuse[i4] << "," << gl::Diffuse[i4+1] << ","
<< gl::Diffuse[i4+2] << "])," << newl;
}
out << "];" << newl << newl;
out << "Background=[" << gl::Background[0] << "," << gl::Background[1] << ","
<< gl::Background[2] << "," << gl::Background[3] << "];"
- << newl;
+ << newl << newl;
- size_t nmaterials=material.size();
- out << "Materials=[";
- for(size_t i=0; i < nmaterials; ++i)
- out << "new Material(" << newl
- << material[i]
- << ")," << newl;
- out << "];" << newl << newl;
+ camp::clearCenters();
+ camp::clearMaterials();
}
void jsfile::finish(string name)
{
- size_t ncenters=drawElement::center.size();
+ finished=true;
+ size_t ncenters=drawElement::centers.size();
if(ncenters > 0) {
out << "Centers=[";
for(size_t i=0; i < ncenters; ++i)
- out << newl << drawElement::center[i] << ",";
+ out << newl << drawElement::centers[i] << ",";
out << newl << "];" << newl;
}
out << "</script>"
@@ -165,7 +203,7 @@ void jsfile::finish(string name)
<< newl << newl << "<body style=\"overflow: hidden;\" onload=\"webGLStart();\">"
<< newl << "<canvas id=\"Asymptote\" width=\""
<< gl::fullWidth << "\" height=\"" << gl::fullHeight
- << "\" style=\"border: none;\">"
+ << "\" style=\"border: none; cursor: pointer;\">"
<< newl << "</canvas>";
footer(name);
}
@@ -181,22 +219,17 @@ void jsfile::addIndices(const uint32_t *I)
out << "[" << I[0] << "," << I[1] << "," << I[2] << "]";
}
-bool distinct(const uint32_t *I, const uint32_t *J)
+void jsfile::addRawPatch(triple const* controls, size_t n,
+ const triple& Min, const triple& Max,
+ const prc::RGBAColour *c, size_t nc)
{
- return I[0] != J[0] || I[1] != J[1] || I[2] != J[2];
-}
-
-void jsfile::addPatch(triple const* controls, size_t n,
- const triple& Min, const triple& Max,
- const prc::RGBAColour *c, size_t nc)
-{
- out << "P.push(new BezierPatch([" << newl;
+ out << "patch([" << newl;
size_t last=n-1;
for(size_t i=0; i < last; ++i)
out << controls[i] << "," << newl;
out << controls[last] << newl << "],"
<< drawElement::centerIndex << "," << materialIndex << ","
- << Min << "," << Max;
+ << newl << Min << "," << newl << Max;
if(c) {
out << ",[" << newl;
for(size_t i=0; i < nc; ++i) {
@@ -205,45 +238,46 @@ void jsfile::addPatch(triple const* controls, size_t n,
}
out << "]";
}
- out << "));" << newl << newl;
+ out << ");" << newl << newl;
}
void jsfile::addCurve(const triple& z0, const triple& c0,
const triple& c1, const triple& z1,
const triple& Min, const triple& Max)
{
- out << "P.push(new BezierCurve([" << newl;
+ out << "curve([" << newl;
out << z0 << "," << newl
<< c0 << "," << newl
<< c1 << "," << newl
<< z1 << newl << "],"
<< drawElement::centerIndex << "," << materialIndex << ","
- << Min << "," << Max << "));" << newl << newl;
+ << newl << Min << "," << newl << Max << ");" << newl << newl;
}
void jsfile::addCurve(const triple& z0, const triple& z1,
const triple& Min, const triple& Max)
{
- out << "P.push(new BezierCurve([" << newl;
+ out << "curve([" << newl;
out << z0 << "," << newl
<< z1 << newl << "],"
<< drawElement::centerIndex << "," << materialIndex << ","
- << Min << "," << Max << "));" << newl << newl;
+ << newl << Min << "," << newl << Max << ");" << newl << newl;
}
void jsfile::addPixel(const triple& z0, double width,
const triple& Min, const triple& Max)
{
- out << "P.push(new Pixel(" << newl;
+ out << "pixel(" << newl;
out << z0 << "," << width << "," << newl
- << materialIndex << "," << Min << "," << Max << "));" << newl << newl;
+ << materialIndex << "," << newl << Min << "," << newl << Max << ");"
+ << newl << newl;
}
-void jsfile::addMaterial(size_t index)
+void jsfile::addMaterial(Material const& material)
{
- out << "Materials.push(new Material(" << newl
- << material[index]
- << "));" << newl << newl;
+ out << "material(" << newl
+ << material
+ << ");" << newl << newl;
}
void jsfile::addTriangles(size_t nP, const triple* P, size_t nN,
@@ -281,18 +315,24 @@ void jsfile::addTriangles(size_t nP, const triple* P, size_t nN,
}
out << "]);" << newl;
}
- out << "P.push(new Triangles("
- << materialIndex << "," << newl
- << Min << "," << Max << "));" << newl << newl;
+ out << "triangles("
+ << drawElement::centerIndex << "," << materialIndex << "," << newl
+ << newl << Min << "," << newl << Max << ");" << newl << newl;
}
-void jsfile::addSphere(const triple& center, double radius, bool half,
- const double& polar, const double& azimuth)
+void jsfile::addSphere(const triple& center, double radius)
{
out << "sphere(" << center << "," << radius << ","
- << drawElement::centerIndex << "," << materialIndex;
- if(half)
- out << "," << newl << "[" << polar << "," << azimuth << "]";
+ << drawElement::centerIndex << "," << materialIndex
+ << ");" << newl << newl;
+}
+
+void jsfile::addHemisphere(const triple& center, double radius,
+ const double& polar, const double& azimuth)
+{
+ out << "sphere(" << center << "," << radius << ","
+ << drawElement::centerIndex << "," << materialIndex
+ << "," << newl << "[" << polar << "," << azimuth << "]";
out << ");" << newl << newl;
}
@@ -328,8 +368,38 @@ void jsfile::addTube(const triple *g, double width,
<< g[3] << newl << "],"
<< width << ","
<< drawElement::centerIndex << "," << materialIndex << ","
- << Min << "," << Max << "," << core <<");" << newl << newl;
+ << newl << Min << "," << newl << Max << "," << core <<");"
+ << newl << newl;
}
+
+void jsfile::addPatch(triple const* controls,
+ triple const& Min, triple const& Max,
+ prc::RGBAColour const* c)
+{
+ addRawPatch(controls,16,Min,Max,c,4);
+}
+
+void jsfile::addStraightPatch(triple const* controls,
+ triple const& Min, triple const& Max,
+ prc::RGBAColour const* c)
+{
+ addRawPatch(controls,4,Min,Max,c,4);
+}
+
+void jsfile::addBezierTriangle(triple const* controls,
+ triple const& Min, triple const& Max,
+ prc::RGBAColour const* c)
+{
+ addRawPatch(controls,10,Min,Max,c,3);
+}
+
+void jsfile::addStraightBezierTriangle(triple const* controls,
+ triple const& Min, triple const& Max,
+ prc::RGBAColour const* c)
+{
+ addRawPatch(controls,3,Min,Max,c,3);
+}
+
#endif
}
diff --git a/graphics/asymptote/jsfile.h b/graphics/asymptote/jsfile.h
index af54721361..430655d4ac 100644
--- a/graphics/asymptote/jsfile.h
+++ b/graphics/asymptote/jsfile.h
@@ -6,63 +6,92 @@
#include "triple.h"
#include "locate.h"
#include "prcfile.h"
+#include "abs3doutfile.h"
namespace camp {
-class jsfile {
+class jsfile : public abs3Doutfile {
jsofstream out;
public:
- jsfile() {}
- ~jsfile() {}
+ jsfile();
+ jsfile(string name);
+ ~jsfile();
- void copy(string name, bool header=false);
+ void close() override;
+
+ void addCurve(const triple& z0, const triple& c0,
+ const triple& c1, const triple& z1,
+ const triple& Min, const triple& Max) override;
+
+ void addCurve(const triple& z0, const triple& z1,
+ const triple& Min, const triple& Max) override;
+
+ void addPixel(const triple& z0, double width,
+ const triple& Min, const triple& Max) override;
+ void addTriangles(size_t nP, const triple* P, size_t nN, const triple* N,
+ size_t nC, const prc::RGBAColour* C, size_t nI,
+ const uint32_t (*PI)[3], const uint32_t (*NI)[3],
+ const uint32_t (*CI)[3],
+ const triple& Min, const triple& Max) override;
+
+ void addCylinder(const triple& center, double radius, double height,
+ const double& polar, const double& azimuth,
+ bool core) override;
+ void addDisk(const triple& center, double radius,
+ const double& polar, const double& azimuth) override;
+ void addTube(const triple *g, double width,
+ const triple& Min, const triple& Max, bool core) override;
+
+ void addMaterial(Material const& mat) override;
+
+ void addSphere(triple const& center, double radius) override;
+
+ void addHemisphere(triple const& center, double radius, double const& polar, double const& azimuth) override;
+
+ void addPatch(triple const* controls, triple const& Min, triple const& Max, prc::RGBAColour const* c) override;
+
+ void
+ addStraightPatch(triple const* controls, triple const& Min, triple const& Max, prc::RGBAColour const* c) override;
+
+ void
+ addBezierTriangle(triple const* control, triple const& Min, triple const& Max, prc::RGBAColour const* c) override;
+
+ void addStraightBezierTriangle(triple const* controls, triple const& Min, triple const& Max,
+ prc::RGBAColour const* c) override;
+
+
+ void svgtohtml(string name);
+#ifdef HAVE_LIBGLM
+ void precision(int digits) override {out.precision(digits);}
+#endif
+
+protected:
+ void copy(string name, bool header=false);
void header(string name);
void meta(string name, bool scalable=true);
void finish(string name);
void footer(string name);
- void svgtohtml(string name);
-#ifdef HAVE_LIBGLM
- void precision(int digits) {out.precision(digits);}
+#ifdef HAVE_LIBGLM
void open(string name);
void comment(string name);
void addColor(const prc::RGBAColour& c);
void addIndices(const uint32_t *I);
- void addPatch(const triple* controls, size_t n, const triple& Min,
+ void addRawPatch(const triple* controls, size_t n, const triple& Min,
const triple& Max, const prc::RGBAColour *colors, size_t nc);
-
- void addCurve(const triple& z0, const triple& c0,
- const triple& c1, const triple& z1,
- const triple& Min, const triple& Max);
-
- void addCurve(const triple& z0, const triple& z1,
- const triple& Min, const triple& Max);
-
- void addPixel(const triple& z0, double width,
- const triple& Min, const triple& Max);
-
- void addMaterial(size_t index);
-
- void addTriangles(size_t nP, const triple* P, size_t nN, const triple* N,
- size_t nC, const prc::RGBAColour* C, size_t nI,
- const uint32_t (*PI)[3], const uint32_t (*NI)[3],
- const uint32_t (*CI)[3],
- const triple& Min, const triple& Max);
void addSphere(const triple& center, double radius, bool half=false,
const double& polar=0.0, const double& azimuth=0.0);
- void addCylinder(const triple& center, double radius, double height,
- const double& polar, const double& azimuth,
- bool core=false);
- void addDisk(const triple& center, double radius,
- const double& polar=0.0, const double& azimuth=0.0);
- void addTube(const triple *g, double width,
- const triple& Min, const triple& Max, bool core=false);
+
+
+private:
+ bool finished;
+ string fileName;
#endif
};
diff --git a/graphics/asymptote/lspserv.cc b/graphics/asymptote/lspserv.cc
new file mode 100644
index 0000000000..3ad469d99b
--- /dev/null
+++ b/graphics/asymptote/lspserv.cc
@@ -0,0 +1,741 @@
+//
+// Created by Supakorn on 5/13/2021.
+//
+
+#include "common.h"
+
+#ifdef HAVE_LSP
+
+#include "lspserv.h"
+
+#include <LibLsp/JsonRpc/stream.h>
+
+#include <string>
+#include <cstdlib>
+#include <vector>
+#include <memory>
+#include <queue>
+
+#include <thread>
+
+#include "dec.h"
+#include "process.h"
+#include "locate.h"
+
+#define GC_THREADS
+
+#include "gc.h"
+
+#define REGISTER_REQ_FN(typ, fn) remoteEndPoint->registerHandler(\
+ [this](typ::request const& req) { return this->fn(req); });
+#define REGISTER_NOTIF_FN(typ, handler) remoteEndPoint->registerHandler(\
+ [this](typ::notify& notif) { this->handler(notif); });
+
+namespace AsymptoteLsp
+{
+ using std::unique_ptr;
+ using std::shared_ptr;
+ using absyntax::block;
+ using Level=lsp::Log::Level;
+
+ class SearchPathAddition
+ {
+ public:
+ SearchPathAddition(mem::string const& dir)
+ {
+ settings::searchPath.push_back(dir);
+ }
+
+ SearchPathAddition(SearchPathAddition const&) = delete;
+ SearchPathAddition& operator=(SearchPathAddition const&) = delete;
+
+ SearchPathAddition(SearchPathAddition&&) = delete;
+ SearchPathAddition& operator=(SearchPathAddition&&) = delete;
+
+ ~SearchPathAddition()
+ {
+ settings::searchPath.pop_back();
+ }
+ };
+
+std::string wslDos2Unix(std::string const& dosPath)
+ {
+ bool isDrivePath=false;
+ char drive;
+ if (dosPath.length() >= 3)
+ {
+ if (dosPath[0] == '/' and dosPath[2] == ':')
+ {
+ isDrivePath=true;
+ drive=dosPath[1];
+ }
+ }
+
+ if (isDrivePath)
+ {
+ std::stringstream sstream;
+ sstream << "/mnt/" << (char) tolower(drive) << dosPath.substr(3);
+ return sstream.str();
+ } else
+ {
+ return std::string(dosPath);
+ }
+ }
+
+std::string wslUnix2Dos(std::string const& unixPath)
+ {
+ bool isMntPath=false;
+ char drive;
+
+ char actPath[PATH_MAX];
+ (void) realpath(unixPath.c_str(), actPath);
+ std::string fullPath(actPath);
+
+ if (fullPath.length() >= 7) // /mnt/
+ {
+ if (fullPath.find("/mnt/") == 0)
+ {
+ isMntPath=true;
+ drive=fullPath[5];
+ }
+ }
+
+ if (isMntPath)
+ {
+ std::stringstream sstream;
+ sstream << "/" << (char) tolower(drive) << ":" << fullPath.substr(6);
+ return sstream.str();
+ } else
+ {
+ return std::string(fullPath);
+ }
+ }
+
+ TextDocumentHover::Either fromString(std::string const& str)
+ {
+ auto strobj=std::make_pair(boost::make_optional(str), optional<lsMarkedString>());
+ std::vector<decltype(strobj)> vec{strobj};
+ return std::make_pair(vec, nullopt);
+ }
+
+ TextDocumentHover::Either fromMarkedStr(lsMarkedString const& markedString)
+ {
+ auto strobj=std::make_pair((optional<std::string>) nullopt, make_optional(markedString));
+ std::vector<decltype(strobj)> vec{strobj};
+ return std::make_pair(vec, nullopt);
+ }
+
+ TextDocumentHover::Either fromMarkedStr(std::vector<std::string> const& stringList, std::string const& language)
+ {
+ std::vector<std::pair<optional<std::string>, optional<lsMarkedString>>> vec;
+ std::transform(stringList.begin(), stringList.end(), std::back_inserter(vec),
+ [&language](std::string const& str)
+ {
+ lsMarkedString lms;
+ lms.language=language;
+ lms.value=str;
+ return std::make_pair((optional<std::string>) nullopt, make_optional(lms));
+ });
+
+ return std::make_pair(vec, nullopt);
+ }
+
+ TextDocumentHover::Either fromMarkedStr(std::string const& str, std::string const& language)
+ {
+ lsMarkedString lms;
+ lms.language=language;
+ lms.value=str;
+ return fromMarkedStr(lms);
+ }
+
+ std::string getDocIdentifierRawPath(lsTextDocumentIdentifier const& textDocIdentifier)
+ {
+ lsDocumentUri fileUri(textDocIdentifier.uri);
+ std::string rawPath=settings::getSetting<bool>("wsl") ?
+ wslDos2Unix(fileUri.GetRawPath()) : std::string(fileUri.GetRawPath());
+ return static_cast<std::string>(rawPath);
+ }
+
+ void AsymptoteLspServer::generateMissingTrees(std::string const& inputFile)
+ {
+ using extRefMap=std::unordered_map<std::string, SymbolContext*>;
+ //using extRefMapLoc = std::pair<extRefMap*, std::string>;
+ std::queue<extRefMap::iterator> procList;
+ std::unordered_set<std::string> processing;
+
+ processing.emplace(inputFile);
+ SymbolContext* ctx=symmapContextsPtr->at(inputFile).get();
+
+ for (auto const& locPair : ctx->getEmptyRefs())
+ {
+ procList.emplace(locPair);
+ }
+
+ // standard BFS algorithm
+ while (not procList.empty())
+ {
+ auto it=procList.front();
+ procList.pop();
+
+ std::string filename(it->first);
+ processing.emplace(filename);
+
+ auto mapIt=symmapContextsPtr->find(filename);
+ if (mapIt != symmapContextsPtr->end())
+ {
+ it->second=mapIt->second.get();
+ }
+ else
+ {
+ block* blk=ifile(mem::string(filename.c_str())).getTree();
+ auto s=symmapContextsPtr->emplace(
+ filename,
+ make_unique<SymbolContext>(posInFile(1, 1), filename));
+ auto fit=std::get<0>(s);
+
+ if(blk == nullptr)
+ {
+ // dead end. file cannot be parsed. no new paths.
+ continue;
+ }
+
+ blk->createSymMap(fit->second.get()); // parse symbol from there.
+ // set plain.asy to plain
+ if (plainCtx != nullptr)
+ {
+ fit->second->extRefs.extFileRefs[plainFile]=plainCtx;
+ }
+
+ // also parse its neighbors
+ for (auto const& sit : fit->second->getEmptyRefs())
+ {
+ if (processing.find(sit->first) == processing.end())
+ {
+ procList.emplace(sit);
+ }
+ else
+ {
+ // import cycles detected!
+ logWarning("Import cycles detected!");
+ }
+ }
+ it->second=fit->second.get();
+ }
+ }
+ }
+
+ void LspLog::log(Level level, std::string&& msg)
+ {
+ if ((uint32_t)Level::WARNING + settings::verbose >= (uint32_t)level || level == Level::ALL)
+ {
+ cerr << msg << std::endl;
+ }
+ }
+
+ void LspLog::log(Level level, std::wstring&& msg)
+ {
+ if ((uint32_t)Level::WARNING + settings::verbose >= (uint32_t)level || level == Level::ALL)
+ {
+ std::wcerr << msg << std::endl;
+ }
+ }
+
+ void LspLog::log(Level level, const std::string& msg)
+ {
+ if ((uint32_t)Level::WARNING + settings::verbose >= (uint32_t)level || level == Level::ALL)
+ {
+ cerr << msg << std::endl;
+ }
+ }
+
+ void LspLog::log(Level level, const std::wstring& msg)
+ {
+ if ((uint32_t)Level::WARNING + settings::verbose >= (uint32_t)level || level == Level::ALL)
+ {
+ std::wcerr << msg << std::endl;
+ }
+ }
+
+ AsymptoteLspServer::AsymptoteLspServer(
+ shared_ptr<lsp::ProtocolJsonHandler> const& jsonHandler,
+ shared_ptr<GenericEndpoint> const& endpoint, LspLog& log) :
+ internalREP(make_unique<RemoteEndPoint>(jsonHandler, endpoint, log)), remoteEndPoint(internalREP.get()),
+ pjh(jsonHandler), ep(endpoint), _log(log)
+ {
+ initializeRequestFn();
+ initializeNotifyFn();
+ }
+
+ AsymptoteLspServer::AsymptoteLspServer(
+ RemoteEndPoint* remoteEndPt,
+ shared_ptr<lsp::ProtocolJsonHandler> const& jsonHandler,
+ shared_ptr<GenericEndpoint> const& endpoint, LspLog& log) :
+ internalREP(nullptr), remoteEndPoint(remoteEndPt),
+ pjh(jsonHandler), ep(endpoint), _log(log)
+ {
+ initializeRequestFn();
+ initializeNotifyFn();
+ }
+
+ void AsymptoteLspServer::initializeRequestFn()
+ {
+ REGISTER_REQ_FN(td_initialize, handleInitailizeRequest);
+ REGISTER_REQ_FN(td_hover, handleHoverRequest);
+ REGISTER_REQ_FN(td_shutdown, handleShutdownRequest);
+ REGISTER_REQ_FN(td_definition, handleDefnRequest);
+ REGISTER_REQ_FN(td_documentColor, handleDocColorRequest);
+ REGISTER_REQ_FN(td_colorPresentation, handleColorPresRequest);
+ }
+
+ void AsymptoteLspServer::initializeNotifyFn()
+ {
+ REGISTER_NOTIF_FN(Notify_InitializedNotification, onInitialized);
+ REGISTER_NOTIF_FN(Notify_TextDocumentDidChange, onChange);
+ REGISTER_NOTIF_FN(Notify_TextDocumentDidOpen, onOpen);
+ REGISTER_NOTIF_FN(Notify_TextDocumentDidSave, onSave);
+ REGISTER_NOTIF_FN(Notify_TextDocumentDidClose, onClose);
+ REGISTER_NOTIF_FN(Notify_Exit, onExit);
+ }
+
+//#pragma region notifications
+
+ void AsymptoteLspServer::onInitialized(Notify_InitializedNotification::notify& notify)
+ {
+ logInfo("server initalized notification");
+ }
+
+ void AsymptoteLspServer::onExit(Notify_Exit::notify& notify)
+ {
+ logInfo("server exit notification");
+ serverClosed.notify(make_unique<bool>(true));
+ }
+
+ void AsymptoteLspServer::onChange(Notify_TextDocumentDidChange::notify& notify)
+ {
+ logInfo("text change notification");
+
+ auto& fileChange = notify.params.contentChanges;
+ if (not fileChange.empty())
+ {
+ bool updatable = true;
+ block* codeBlk;
+ try
+ {
+ codeBlk=istring(mem::string(fileChange[0].text.c_str())).getTree();
+ }
+ catch (handled_error const&)
+ {
+ updatable = false;
+ }
+
+ if (updatable)
+ {
+ std::string rawPath=getDocIdentifierRawPath(notify.params.textDocument.AsTextDocumentIdentifier());
+ std::istringstream iss(fileChange[0].text);
+ updateFileContentsTable(rawPath, iss);
+ reloadFileRaw(codeBlk, rawPath);
+ }
+ }
+
+ logInfo("changed text data");
+ }
+
+ void AsymptoteLspServer::onOpen(Notify_TextDocumentDidOpen::notify& notify)
+ {
+ logInfo("onOpen notification");
+ lsDocumentUri fileUri(notify.params.textDocument.uri);
+ reloadFile(fileUri.GetRawPath());
+ }
+
+ void AsymptoteLspServer::onSave(Notify_TextDocumentDidSave::notify& notify)
+ {
+ logInfo("onSave notification");
+ lsDocumentUri fileUri(notify.params.textDocument.uri);
+ reloadFile(fileUri.GetRawPath());
+ }
+
+ void AsymptoteLspServer::onClose(Notify_TextDocumentDidClose::notify& notify)
+ {
+ logInfo("onClose notification");
+ }
+
+//#pragma endregion
+
+//#pragma region requests
+ td_initialize::response AsymptoteLspServer::handleInitailizeRequest(td_initialize::request const& req)
+ {
+ clearVariables();
+
+ symmapContextsPtr=make_unique<SymContextFilemap>();
+ fileContentsPtr=make_unique<
+ std::remove_reference<decltype(*fileContentsPtr)>::type>();
+ plainFile=settings::locateFile("plain", true).c_str();
+ plainCtx=reloadFileRaw(plainFile, false);
+ generateMissingTrees(plainFile);
+
+ td_initialize::response rsp;
+ rsp.id=req.id;
+ rsp.result.capabilities.hoverProvider=true;
+
+ lsTextDocumentSyncOptions tdso;
+ tdso.openClose=true;
+ tdso.change=lsTextDocumentSyncKind::Full;
+ lsSaveOptions so;
+ so.includeText=true;
+ tdso.save=so;
+ rsp.result.capabilities.textDocumentSync=opt_right<lsTextDocumentSyncKind>(tdso);
+ rsp.result.capabilities.definitionProvider=std::make_pair(true, nullopt);
+ rsp.result.capabilities.colorProvider=std::make_pair(true, nullopt);
+ return rsp;
+ }
+
+ SymbolContext* AsymptoteLspServer::fromRawPath(lsTextDocumentIdentifier const& identifier)
+ {
+ std::string rawPath=getDocIdentifierRawPath(identifier);
+ auto fileSymIt=symmapContextsPtr->find(rawPath);
+
+ return fileSymIt != symmapContextsPtr->end() ? fileSymIt->second.get() : nullptr;
+ }
+
+ td_hover::response AsymptoteLspServer::handleHoverRequest(td_hover::request const& req)
+ {
+ td_hover::response rsp;
+ SymbolContext* fileSymPtr=fromRawPath(req.params.textDocument);
+ std::vector<std::pair<optional<std::string>, optional<lsMarkedString>>> nullVec;
+
+ if (!fileSymPtr)
+ {
+ rsp.result.contents.first=nullVec;
+ return rsp;
+ }
+
+ auto s=fileSymPtr->searchSymbol(fromLsPosition(req.params.position));
+ auto st=std::get<0>(s);
+ auto ctx=std::get<1>(s);
+
+ if (not st.has_value())
+ {
+ rsp.result.contents.first=nullVec;
+ return rsp;
+ }
+
+ auto v=st.value();
+ auto symText=std::get<0>(v);
+ auto startPos=std::get<1>(v);
+ auto endPos=std::get<2>(v);
+
+ rsp.result.range=make_optional(lsRange(toLsPosition(startPos), toLsPosition(endPos)));
+
+ auto typ=ctx->searchLitSignature(symText);
+ std::list<std::string> endResultList;
+ if (typ.has_value())
+ {
+ endResultList.push_back(typ.value());
+ }
+ endResultList.splice(endResultList.end(), ctx->searchLitFuncSignature(symText));
+
+ std::vector<std::string> endResult;
+ std::copy(endResultList.begin(), endResultList.end(), std::back_inserter(endResult));
+
+ rsp.result.contents=endResult.empty() ?
+ fromMarkedStr("<decl-unknown> " + symText.name + ";") :
+ fromMarkedStr(endResult);
+ return rsp;
+ }
+
+ td_documentColor::response AsymptoteLspServer::handleDocColorRequest(td_documentColor::request const& req)
+ {
+ td_documentColor::response rsp;
+
+ if (SymbolContext* fileSymPtr=fromRawPath(req.params.textDocument))
+ {
+ logInfo("Got Document color request.");
+ auto& colorsInfo = fileSymPtr->colorInformation;
+ for (auto const& colorPtr : colorsInfo)
+ {
+ ColorInformation cif;
+
+ cif.color = static_cast<TextDocument::Color>(*colorPtr);
+ cif.range.start=toLsPosition(colorPtr->rangeBegin);
+
+ auto s=colorPtr->lastArgPosition;
+ auto& line=std::get<0>(s);
+ auto& colm=std::get<1>(s);
+ size_t offset = 0;
+ size_t lineOffset = 0;
+
+ auto& strLines = fileContentsPtr->at(getDocIdentifierRawPath(req.params.textDocument));
+ char ch=strLines[line + lineOffset + 1][colm - 1 + offset];
+
+ while (
+ ch != ')' and ch != ';'
+ and line + lineOffset <= strLines.size()
+ )
+ {
+ ++offset;
+ if (offset > strLines[line+lineOffset-1].size())
+ {
+ ++lineOffset;
+ offset = 0;
+ }
+ if (line+lineOffset <= strLines.size())
+ {
+ ch=strLines[line + lineOffset - 1][colm - 1 + offset];
+ }
+ }
+
+ if (ch != ')' or line + lineOffset > strLines.size())
+ {
+ continue;
+ }
+
+ cif.range.end=toLsPosition(make_pair(line+lineOffset, colm+offset+1));
+ rsp.result.emplace_back(cif);
+ }
+ }
+
+ return rsp;
+ }
+
+ td_colorPresentation::response AsymptoteLspServer::handleColorPresRequest(td_colorPresentation::request const& req)
+ {
+ td_colorPresentation::response rsp;
+
+ if (SymbolContext* fileSymPtr=fromRawPath(req.params.textDocument))
+ {
+ logInfo("Got color presentation request.");
+ ColorPresentation clp;
+
+ for (auto& colPtr : fileSymPtr->colorInformation)
+ {
+ auto& incomingColor = req.params.color;
+ std::ostringstream ssargs;
+ std::ostringstream labelargs;
+
+ bool opaque=std::fabs(incomingColor.alpha - 1) < std::numeric_limits<double>::epsilon();
+ std::string fnName = opaque ? "rgb" : "rgba";
+
+ labelargs << std::setprecision(3) << incomingColor.red << "," << incomingColor.green << "," <<
+ incomingColor.blue;
+ ssargs << incomingColor.red << "," << incomingColor.green << "," <<
+ incomingColor.blue;
+ if (!opaque)
+ {
+ ssargs << "," << incomingColor.alpha;
+ labelargs << "," << incomingColor.alpha;
+ }
+ std::ostringstream ss;
+ ss << fnName << "(" << ssargs.str() << ")";
+ clp.textEdit.newText = ss.str();
+
+ std::ostringstream lss;
+ lss << fnName << "(" << labelargs.str() << ")";
+ clp.label = lss.str();
+
+ if (colPtr->rangeBegin == fromLsPosition(req.params.range.start))
+ {
+ clp.textEdit.range = req.params.range;
+ rsp.result.emplace_back(std::move(clp));
+ break;
+ }
+ }
+ }
+ return rsp;
+ }
+
+ td_shutdown::response AsymptoteLspServer::handleShutdownRequest(td_shutdown::request const& req)
+ {
+ logInfo("got shut down request");
+ td_shutdown::response rsp;
+ JsonNull nullrsp;
+ lsp::Any anyrsp;
+ anyrsp.Set(nullrsp);
+ rsp.result = make_optional<lsp::Any>(std::move(anyrsp));
+
+ serverClosed.notify(make_unique<bool>(true));
+ return rsp;
+ }
+
+ td_definition::response AsymptoteLspServer::handleDefnRequest(td_definition::request const& req)
+ {
+ td_definition::response rsp;
+ std::list<posRangeInFile> posRanges;
+ if (SymbolContext* fileSymPtr=fromRawPath(req.params.textDocument))
+ {
+ posInFile pos = fromLsPosition(req.params.position);
+ auto s=fileSymPtr->searchSymbol(pos);
+ auto st=std::get<0>(s);
+ auto ctx=std::get<1>(s);
+ if (st.has_value())
+ {
+ optional<posRangeInFile> posRange=ctx->searchLitPosition(std::get<0>(st.value()), pos);
+ if (posRange.has_value())
+ {
+ posRanges.push_back(posRange.value());
+ }
+
+ posRanges.splice(posRanges.begin(), ctx->searchLitFuncPositions(std::get<0>(st.value()), pos));
+ }
+ }
+ rsp.result.first=boost::make_optional(std::vector<lsLocation>());
+ std::transform(
+ posRanges.begin(), posRanges.end(), std::back_inserter(rsp.result.first.value()),
+ [](posRangeInFile const& posRange)
+ {
+ auto& fil=std::get<0>(posRange);
+ auto& posBegin=std::get<1>(posRange);
+ auto& posEnd=std::get<2>(posRange);
+ lsRange rng(toLsPosition(posBegin), toLsPosition(posEnd));
+
+ std::string filReturn(
+ settings::getSetting<bool>("wsl") ? static_cast<std::string>(wslUnix2Dos(fil)) : fil);
+
+ lsDocumentUri uri(filReturn);
+ return lsLocation(uri, rng);
+ });
+ return rsp;
+ }
+
+//#pragma endregion
+ void AsymptoteLspServer::reloadFile(std::string const& filename)
+ {
+ std::string rawPath=settings::getSetting<bool>("wsl") ? wslDos2Unix(filename) : std::string(filename);
+ reloadFileRaw(static_cast<std::string>(rawPath));
+ }
+
+ void AsymptoteLspServer::updateFileContentsTable(std::string const& filename)
+ {
+ std::ifstream fil(filename, std::ifstream::in);
+ return updateFileContentsTable(filename, fil);
+ }
+
+ void AsymptoteLspServer::updateFileContentsTable(std::string const& filename, std::istream& in)
+ {
+ auto& fileContents = *fileContentsPtr;
+ fileContents[filename].clear();
+
+ std::string line;
+ while (std::getline(in, line))
+ {
+ fileContents[filename].emplace_back(line);
+ }
+ }
+
+ SymbolContext* AsymptoteLspServer::reloadFileRaw(block* blk, std::string const& rawPath, bool const& fillTree)
+ {
+ if (blk != nullptr)
+ {
+ SearchPathAddition sp(stripFile(string(rawPath.c_str())));
+ auto it=symmapContextsPtr->find(rawPath);
+ if (it != symmapContextsPtr->end())
+ {
+ *(it->second)=SymbolContext(posInFile(1, 1), rawPath);
+ }
+ else
+ {
+ auto s = symmapContextsPtr->emplace(
+ rawPath, make_unique<SymbolContext>(posInFile(1, 1), rawPath));
+ it=std::get<0>(s);
+ }
+
+ SymbolContext* newPtr=it->second.get();
+
+ cerr << rawPath << endl;
+
+ blk->createSymMap(newPtr);
+
+ if (plainCtx != nullptr)
+ {
+ it->second->extRefs.extFileRefs[plainFile]=plainCtx;
+ }
+ else if (rawPath == plainFile)
+ {
+ it->second->extRefs.extFileRefs[plainFile]=newPtr;
+ }
+
+ if (fillTree)
+ {
+ generateMissingTrees(rawPath);
+ }
+ return it->second.get();
+ }
+ else
+ {
+ return nullptr;
+ }
+ }
+
+ SymbolContext* AsymptoteLspServer::reloadFileRaw(std::string const& rawPath, bool const& fillTree)
+ {
+ updateFileContentsTable(rawPath);
+ block* blk=ifile(mem::string(rawPath.c_str())).getTree();
+ return reloadFileRaw(blk, rawPath, fillTree);
+ }
+
+ void AsymptoteLspServer::start()
+ {
+ return startIO(cin, cout);
+ }
+
+ AsymptoteLspServer::~AsymptoteLspServer()
+ {
+ }
+
+ void AsymptoteLspServer::startIO(std::istream& in, std::ostream& out)
+ {
+ auto inPtr=make_shared<AsymptoteLsp::istream>(in);
+ auto outPtr=make_shared<AsymptoteLsp::ostream>(out);
+ remoteEndPoint->startProcessingMessages(inPtr,outPtr);
+ serverClosed.wait();
+ }
+
+ void AsymptoteLspServer::log(lsp::Log::Level const& level, std::string const& message)
+ {
+ _log.log(level, message);
+ }
+
+ void AsymptoteLspServer::logError(std::string const& message)
+ {
+ log(lsp::Log::Level::SEVERE, message);
+ }
+
+ void AsymptoteLspServer::logWarning(std::string const& message)
+ {
+ log(lsp::Log::Level::WARNING, message);
+ }
+
+ void AsymptoteLspServer::logInfo(std::string const& message)
+ {
+ log(lsp::Log::Level::INFO, message);
+ }
+
+ void AsymptoteLspServer::clearVariables()
+ {
+ }
+
+ // TCP Asymptote Server
+
+ TCPAsymptoteLSPServer::TCPAsymptoteLSPServer(
+ std::string const& addr, std::string const& port, shared_ptr<lsp::ProtocolJsonHandler> const& jsonHandler,
+ shared_ptr<GenericEndpoint> const& endpoint, LspLog& log) :
+ lsp::TcpServer(addr, port, jsonHandler, endpoint, log),
+ AsymptoteLspServer(&point, jsonHandler, endpoint, log)
+ {
+ }
+
+ TCPAsymptoteLSPServer::~TCPAsymptoteLSPServer()
+ {
+ logInfo("Destroying server...");
+ this->stop();
+ }
+
+
+ void TCPAsymptoteLSPServer::start()
+ {
+ std::thread([this]() {this->run();}).detach();
+ serverClosed.wait();
+ logInfo("Got server closed notification.");
+ }
+}
+
+#endif
diff --git a/graphics/asymptote/lspserv.h b/graphics/asymptote/lspserv.h
new file mode 100644
index 0000000000..74a21659a3
--- /dev/null
+++ b/graphics/asymptote/lspserv.h
@@ -0,0 +1,188 @@
+#pragma once
+#include "common.h"
+#include "symbolmaps.h"
+
+#include "LibLsp/lsp/ProtocolJsonHandler.h"
+#include "LibLsp/lsp/AbsolutePath.h"
+
+#include "LibLsp/JsonRpc/Endpoint.h"
+#include "LibLsp/JsonRpc/TcpServer.h"
+#include "LibLsp/JsonRpc/Condition.h"
+
+// header for requests
+#include "LibLsp/lsp/textDocument/hover.h"
+#include "LibLsp/lsp/general/initialize.h"
+#include "LibLsp/lsp/general/shutdown.h"
+#include "LibLsp/lsp/textDocument/declaration_definition.h"
+#include "LibLsp/lsp/textDocument/colorPresentation.h"
+
+//header for notifs
+#include "LibLsp/lsp/general/exit.h"
+#include "LibLsp/lsp/general/initialized.h"
+#include "LibLsp/lsp/textDocument/did_open.h"
+#include "LibLsp/lsp/textDocument/did_change.h"
+#include "LibLsp/lsp/textDocument/did_save.h"
+#include "LibLsp/lsp/textDocument/did_close.h"
+
+//everything else
+#include <functional>
+#include <cctype>
+#include <unordered_map>
+#include "LibLsp/JsonRpc/stream.h"
+
+namespace absyntax
+{
+ class block;
+}
+
+namespace AsymptoteLsp
+{
+ class istream : public lsp::base_istream<std::istream>
+ {
+ public:
+ istream(std::istream& ist) : lsp::base_istream<std::istream>(ist)
+ {
+ }
+
+ std::string what() override
+ {
+ return "AsymptoteLSP_istream";
+ }
+ };
+
+ class ostream : public lsp::base_ostream<std::ostream>
+ {
+ public:
+ ostream(std::ostream& ost) : lsp::base_ostream<std::ostream>(ost)
+ {
+ }
+
+ std::string what() override
+ {
+ return "AsymptoteLSP_ostream";
+ }
+ };
+
+ template<typename TLeft, typename TRight>
+ inline optional<std::pair<optional<TLeft>, optional<TRight>>> opt_left(TLeft const& opt)
+ {
+ return boost::make_optional(std::make_pair(optional<TLeft>(opt), optional<TRight>()));
+ }
+
+ template<typename TLeft, typename TRight>
+ inline optional<std::pair<optional<TLeft>, optional<TRight>>> opt_right(TRight const& opt)
+ {
+ return boost::make_optional(std::make_pair(optional<TLeft>(), optional<TRight>(opt)));
+ }
+
+ TextDocumentHover::Either fromString(std::string const &str);
+ TextDocumentHover::Either fromMarkedStr(lsMarkedString const& markedString);
+ TextDocumentHover::Either fromMarkedStr(std::string const& str, std::string const& language="asymptote");
+ TextDocumentHover::Either fromMarkedStr(std::vector<std::string> const& stringList,
+ std::string const& language="asymptote");
+
+ std::string wslDos2Unix(std::string const& dosPath);
+ std::string wslUnix2Dos(std::string const& unixPath);
+ std::string getDocIdentifierRawPath(lsTextDocumentIdentifier const&);
+
+ typedef std::unordered_map<std::string, std::unique_ptr<SymbolContext>> SymContextFilemap;
+
+ class LspLog: public lsp::Log
+ {
+ public:
+ void log(Level level, std::string&& msg) override;
+ void log(Level level, const std::string& msg) override;
+ void log(Level level, std::wstring&& msg) override;
+ void log(Level level, const std::wstring& msg) override;
+ };
+
+
+ class AsymptoteLspServer
+ {
+ public:
+ AsymptoteLspServer(shared_ptr<lsp::ProtocolJsonHandler> const& jsonHandler,
+ shared_ptr<GenericEndpoint> const& endpoint, LspLog& log);
+ AsymptoteLspServer(RemoteEndPoint* remoteEndPt,
+ shared_ptr<lsp::ProtocolJsonHandler> const& jsonHandler,
+ shared_ptr<GenericEndpoint> const& endpoint, LspLog& log);
+ virtual ~AsymptoteLspServer();
+
+ // copy constructors + copy assignment op
+ AsymptoteLspServer(AsymptoteLspServer& sv) = delete;
+ AsymptoteLspServer& operator=(AsymptoteLspServer const& sv) = delete;
+
+ // move constructors and move assignment op
+ AsymptoteLspServer(AsymptoteLspServer&& sv) = delete;
+ AsymptoteLspServer& operator=(AsymptoteLspServer&& sv) = delete;
+
+ virtual void start();
+ void startIO(std::istream& in=cin, std::ostream& out=cout);
+
+ protected:
+ td_hover::response handleHoverRequest(td_hover::request const&);
+ virtual td_initialize::response handleInitailizeRequest(td_initialize::request const&);
+ virtual td_shutdown::response handleShutdownRequest(td_shutdown::request const&);
+ td_definition::response handleDefnRequest(td_definition::request const&);
+ td_documentColor::response handleDocColorRequest(td_documentColor::request const&);
+ td_colorPresentation::response handleColorPresRequest(td_colorPresentation::request const&);
+
+
+ virtual void onInitialized(Notify_InitializedNotification::notify& notify);
+ virtual void onExit(Notify_Exit::notify& notify);
+ void onChange(Notify_TextDocumentDidChange::notify& notify);
+ void onOpen(Notify_TextDocumentDidOpen::notify& notify);
+ void onSave(Notify_TextDocumentDidSave::notify& notify);
+ void onClose(Notify_TextDocumentDidClose::notify& notify);
+
+ void generateMissingTrees(std::string const& inputFile);
+
+ void initializeRequestFn();
+ void initializeNotifyFn();
+
+ void reloadFile(std::string const&);
+ void updateFileContentsTable(std::string const& filename);
+ void updateFileContentsTable(std::string const& filename, std::istream& in);
+
+ // logging functions
+ void log(lsp::Log::Level const& level, std::string const& message);
+ void logInfo(std::string const& message);
+ void logWarning(std::string const& message);
+ void logError(std::string const& message);
+
+ SymbolContext* reloadFileRaw(std::string const&, bool const& fillTree=true);
+ SymbolContext* fromRawPath(lsTextDocumentIdentifier const& identifier);
+ SymbolContext* reloadFileRaw(absyntax::block* blk, std::string const& rawPath, bool const& fillTree=true);
+ virtual void clearVariables();
+ Condition<bool> serverClosed;
+
+ private:
+ unique_ptr<RemoteEndPoint> internalREP;
+ protected:
+ // [owned, ptr]
+ RemoteEndPoint* const remoteEndPoint;
+
+ private:
+ shared_ptr<lsp::ProtocolJsonHandler> pjh;
+ shared_ptr<GenericEndpoint> ep;
+ SymbolContext* plainCtx=NULL;
+ LspLog& _log;
+
+ unique_ptr<SymContextFilemap> symmapContextsPtr;
+ unique_ptr<unordered_map<std::string, std::vector<std::string>>> fileContentsPtr;
+ std::string plainFile;
+ };
+
+ class TCPAsymptoteLSPServer : public lsp::TcpServer, public AsymptoteLspServer
+ {
+ public:
+ TCPAsymptoteLSPServer(
+ std::string const& addr, std::string const& port,
+ shared_ptr<lsp::ProtocolJsonHandler> const& jsonHandler,
+ shared_ptr<GenericEndpoint> const& endpoint, LspLog& log);
+ ~TCPAsymptoteLSPServer() override;
+
+ protected:
+ void start() override;
+ Condition<bool> serverInitialized;
+ };
+}
diff --git a/graphics/asymptote/main.cc b/graphics/asymptote/main.cc
index e4eb1dc590..4359111829 100644
--- a/graphics/asymptote/main.cc
+++ b/graphics/asymptote/main.cc
@@ -44,6 +44,10 @@
#include "interact.h"
#include "fileio.h"
+#ifdef HAVE_LSP
+#include "lspserv.h"
+#endif
+
#include "stack.h"
using namespace settings;
@@ -87,7 +91,7 @@ int sigsegv_handler (void *, int emergency)
}
#endif
-void setsignal(RETSIGTYPE (*handler)(int))
+void setsignal(void (*handler)(int))
{
#ifdef HAVE_LIBSIGSEGV
char mystack[16384];
@@ -126,6 +130,11 @@ struct Args
Args(int argc, char **argv) : argc(argc), argv(argv) {}
};
+int returnCode()
+{
+ return em.processStatus() || interact::interactive ? 0 : 1;
+}
+
void *asymain(void *A)
{
setsignal(signalHandler);
@@ -134,11 +143,32 @@ void *asymain(void *A)
if(interactive) {
Signal(SIGINT,interruptHandler);
- processPrompt();
+#ifdef HAVE_LSP
+ if (getSetting<bool>("lsp")) {
+ AsymptoteLsp::LspLog log;
+ auto jsonHandler=std::make_shared<lsp::ProtocolJsonHandler>();
+ auto endpoint=std::make_shared<GenericEndpoint>(log);
+
+ unique_ptr<AsymptoteLsp::AsymptoteLspServer> asylsp;
+
+ if(getSetting<string>("lspport") != "") {
+ asylsp=make_unique<AsymptoteLsp::TCPAsymptoteLSPServer>(
+ (std::string)getSetting<string>("lsphost").c_str(),
+ (std::string)getSetting<string>("lspport").c_str(),
+ jsonHandler, endpoint, log);
+ } else {
+ asylsp=make_unique<AsymptoteLsp::AsymptoteLspServer>(jsonHandler,
+ endpoint,
+ log);
+ }
+ asylsp->start();
+ } else
+#endif
+ processPrompt();
} else if (getSetting<bool>("listvariables") && numArgs()==0) {
try {
doUnrestrictedList();
- } catch(handled_error) {
+ } catch(handled_error const&) {
em.statusError();
}
} else {
@@ -155,7 +185,7 @@ void *asymain(void *A)
processFile("-",true);
try {
setOptions(args->argc,args->argv);
- } catch(handled_error) {
+ } catch(handled_error const&) {
em.statusError();
}
if(inpipe < 0) break;
@@ -166,7 +196,7 @@ void *asymain(void *A)
try {
if(ind < n-1)
setOptions(args->argc,args->argv);
- } catch(handled_error) {
+ } catch(handled_error const&) {
em.statusError();
}
}
@@ -193,12 +223,12 @@ void *asymain(void *A)
}
#endif
#endif
- exit(em.processStatus() || interact::interactive ? 0 : 1);
+ exit(returnCode());
}
void exitHandler(int)
{
- exit(0);
+ exit(returnCode());
}
int main(int argc, char *argv[])
@@ -211,7 +241,7 @@ int main(int argc, char *argv[])
try {
setOptions(argc,argv);
- } catch(handled_error) {
+ } catch(handled_error const&) {
em.statusError();
}
@@ -256,4 +286,3 @@ GC_API void GC_CALL GC_throw_bad_alloc() {
std::bad_alloc();
}
#endif
-
diff --git a/graphics/asymptote/makeUnique.h b/graphics/asymptote/makeUnique.h
new file mode 100644
index 0000000000..6bf84bbf43
--- /dev/null
+++ b/graphics/asymptote/makeUnique.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#include <cstddef>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+#if __cplusplus < 201402L
+
+namespace utils {
+template<class T> struct _Unique_if {
+ typedef std::unique_ptr<T> _Single_object;
+};
+
+template<class T> struct _Unique_if<T[]> {
+ typedef std::unique_ptr<T[]> _Unknown_bound;
+};
+
+template<class T, size_t N> struct _Unique_if<T[N]> {
+ typedef void _Known_bound;
+};
+
+template<class T, class... Args>
+typename _Unique_if<T>::_Single_object
+make_unique(Args&&... args) {
+ return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+
+template<class T>
+typename _Unique_if<T>::_Unknown_bound
+make_unique(size_t n) {
+ typedef typename std::remove_extent<T>::type U;
+ return std::unique_ptr<T>(new U[n]());
+}
+
+template<class T, class... Args>
+typename _Unique_if<T>::_Known_bound
+make_unique(Args&&...) = delete;
+}
+using utils::make_unique;
+#else
+using std::make_unique;
+#endif
diff --git a/graphics/asymptote/material.h b/graphics/asymptote/material.h
index f16f421e52..65ba2cf8a9 100644
--- a/graphics/asymptote/material.h
+++ b/graphics/asymptote/material.h
@@ -11,6 +11,17 @@
#include <glm/glm.hpp>
+namespace glm {
+
+inline ostream& operator << (ostream& out, const glm::vec4& v)
+{
+ out << "[" << v[0] << "," << v[1] << "," << v[2] << "," << v[3]
+ << "]";
+ return out;
+}
+
+}
+
namespace camp {
inline bool operator < (const glm::vec4& m1, const glm::vec4& m2) {
@@ -23,18 +34,11 @@ inline bool operator < (const glm::vec4& m1, const glm::vec4& m2) {
(m1[3] < m2[3]))))));
}
-inline glm::vec4 GLparameters(GLfloat shininess, GLfloat metallic,
- GLfloat fresnel0) {
+inline glm::vec4 GLparameters(float shininess, float metallic,
+ float fresnel0) {
return glm::vec4(shininess,metallic,fresnel0,0.0);
}
-inline ostream& operator << (ostream& out, const glm::vec4& v)
-{
- out << "[" << v[0] << "," << v[1] << "," << v[2] << "," << v[3]
- << "]";
- return out;
-}
-
struct Material {
public:
glm::vec4 diffuse,emissive,specular;
@@ -80,6 +84,15 @@ public:
return out;
}
+ friend jsofstream& operator << (jsofstream& out, const Material& m) {
+ out << m.diffuse << "," << newl
+ << m.emissive << "," << newl
+ << m.specular << "," << newl
+ << m.parameters[0] << "," << newl
+ << m.parameters[1] << "," << newl
+ << m.parameters[2] << newl;
+ return out;
+ }
};
extern size_t Nmaterials; // Number of materials compiled in shader
diff --git a/graphics/asymptote/memory.h b/graphics/asymptote/memory.h
index a201f5bd4f..8e878ef712 100644
--- a/graphics/asymptote/memory.h
+++ b/graphics/asymptote/memory.h
@@ -187,6 +187,7 @@ typedef std::basic_ostringstream<char,std::char_traits<char>,
typedef std::basic_stringbuf<char,std::char_traits<char>,
gc_allocator<char> > stringbuf;
inline void compact(int x) {GC_set_dont_expand(x);}
+inline std::string stdString(string s) {return std::string(s.c_str());}
#else
inline void compact(int x) {}
typedef std::string string;
@@ -194,6 +195,7 @@ typedef std::stringstream stringstream;
typedef std::istringstream istringstream;
typedef std::ostringstream ostringstream;
typedef std::stringbuf stringbuf;
+inline std::string stdString(string s) {return s;}
#endif // USEGC
} // namespace mem
diff --git a/graphics/asymptote/name.cc b/graphics/asymptote/name.cc
index d16e6e1e93..04e3552c68 100644
--- a/graphics/asymptote/name.cc
+++ b/graphics/asymptote/name.cc
@@ -145,6 +145,10 @@ void simpleName::prettyprint(ostream &out, Int indent)
out << "simpleName '" << id << "'\n";
}
+AsymptoteLsp::SymbolLit simpleName::getLit() const
+{
+ return AsymptoteLsp::SymbolLit(static_cast<std::string>(id));
+}
record *qualifiedName::castToRecord(types::ty *t, bool tacit)
{
@@ -323,4 +327,19 @@ void qualifiedName::prettyprint(ostream &out, Int indent)
qualifier->prettyprint(out, indent+1);
}
+AsymptoteLsp::SymbolLit qualifiedName::getLit() const
+{
+ std::vector<std::string> accessors;
+ name const* currentScope = this->qualifier;
+
+ while (auto* qn = dynamic_cast<qualifiedName const*>(currentScope))
+ {
+ accessors.push_back(static_cast<std::string>(qn->getName()));
+ currentScope = qn->qualifier;
+ }
+ accessors.push_back(static_cast<std::string>(currentScope->getName()));
+
+ return AsymptoteLsp::SymbolLit(static_cast<std::string>(id), std::move(accessors));
+}
+
} // namespace absyntax
diff --git a/graphics/asymptote/name.h b/graphics/asymptote/name.h
index 46596a344a..0684b21f62 100644
--- a/graphics/asymptote/name.h
+++ b/graphics/asymptote/name.h
@@ -87,7 +87,11 @@ public:
out << "<base name>";
}
- virtual symbol getName() = 0;
+ [[nodiscard]]
+ virtual symbol getName() const = 0;
+
+ [[nodiscard]]
+ virtual AsymptoteLsp::SymbolLit getLit() const = 0;
};
inline ostream& operator<< (ostream& out, const name& n) {
@@ -102,25 +106,30 @@ public:
simpleName(position pos, symbol id)
: name(pos), id(id) {}
- trans::varEntry *getVarEntry(coenv &e);
+ trans::varEntry *getVarEntry(coenv &e) override;
// As a variable:
- void varTrans(action act, coenv &e, types::ty *target);
- types::ty *varGetType(coenv &);
- trans::varEntry *getCallee(coenv &e, types::signature *sig);
+ void varTrans(action act, coenv &e, types::ty *target) override;
+ types::ty *varGetType(coenv &) override;
+ trans::varEntry *getCallee(coenv &e, types::signature *sig) override;
// As a type:
- types::ty *typeTrans(coenv &e, bool tacit = false);
- virtual trans::tyEntry *tyEntryTrans(coenv &e);
- trans::frame *tyFrameTrans(coenv &e);
+ types::ty *typeTrans(coenv &e, bool tacit = false) override;
+ virtual trans::tyEntry *tyEntryTrans(coenv &e) override;
+ trans::frame *tyFrameTrans(coenv &e) override;
- void prettyprint(ostream &out, Int indent);
- void print(ostream& out) const {
+ void prettyprint(ostream &out, Int indent) override;
+ void print(ostream& out) const override {
out << id;
}
- symbol getName() {
+
+ [[nodiscard]]
+ symbol getName() const override {
return id;
}
+
+ [[nodiscard]]
+ AsymptoteLsp::SymbolLit getLit() const override;
};
@@ -144,25 +153,30 @@ public:
qualifiedName(position pos, name *qualifier, symbol id)
: name(pos), qualifier(qualifier), id(id) {}
- trans::varEntry *getVarEntry(coenv &e);
+ trans::varEntry *getVarEntry(coenv &e) override;
// As a variable:
- void varTrans(action act, coenv &, types::ty *target);
- types::ty *varGetType(coenv &);
- trans::varEntry *getCallee(coenv &e, types::signature *sig);
+ void varTrans(action act, coenv &, types::ty *target) override;
+ types::ty *varGetType(coenv &) override;
+ trans::varEntry *getCallee(coenv &e, types::signature *sig) override;
// As a type:
- types::ty *typeTrans(coenv &e, bool tacit = false);
- trans::tyEntry *tyEntryTrans(coenv &e);
- trans::frame *tyFrameTrans(coenv &e);
+ types::ty *typeTrans(coenv &e, bool tacit = false) override;
+ trans::tyEntry *tyEntryTrans(coenv &e) override;
+ trans::frame *tyFrameTrans(coenv &e) override;
- void prettyprint(ostream &out, Int indent);
- void print(ostream& out) const {
+ void prettyprint(ostream &out, Int indent) override;
+ void print(ostream& out) const override {
out << *qualifier << "." << id;
}
- symbol getName() {
+
+ [[nodiscard]]
+ symbol getName() const override {
return id;
}
+
+ [[nodiscard]]
+ AsymptoteLsp::SymbolLit getLit() const override;
};
} // namespace absyntax
diff --git a/graphics/asymptote/newexp.cc b/graphics/asymptote/newexp.cc
index 62154a5e0d..c124293928 100644
--- a/graphics/asymptote/newexp.cc
+++ b/graphics/asymptote/newexp.cc
@@ -31,7 +31,7 @@ void printFrame(frame *f) {
}
void newRecordExp::prettyprint(ostream &out, Int indent) {
- prettyname(out, "newRecordExp", indent);
+ prettyname(out, "newRecordExp", indent, getPos());
}
bool newRecordExp::encodeLevel(position pos, coenv &e, trans::tyEntry *ent)
@@ -113,7 +113,7 @@ types::ty *newRecordExp::getType(coenv &e)
void newArrayExp::prettyprint(ostream &out, Int indent)
{
- prettyname(out,"newArrayExp",indent);
+ prettyname(out,"newArrayExp",indent, getPos());
celltype->prettyprint(out, indent+1);
if (dimexps) dimexps->prettyprint(out, indent+1);
diff --git a/graphics/asymptote/pair.h b/graphics/asymptote/pair.h
index b37b778ecb..d9003839ab 100644
--- a/graphics/asymptote/pair.h
+++ b/graphics/asymptote/pair.h
@@ -21,6 +21,7 @@
#include "common.h"
#include "angle.h"
+#include "xstream.h"
namespace camp {
@@ -231,6 +232,14 @@ public:
return out;
}
+#ifdef HAVE_RPC_RPC_H
+ friend xdr::oxstream& operator << (xdr::oxstream& out, pair const& v)
+ {
+ out << v.x << v.y;
+ return out;
+ }
+#endif
+
friend class box;
};
diff --git a/graphics/asymptote/parser.cc b/graphics/asymptote/parser.cc
index cdc8d81c68..31df6f44fa 100644
--- a/graphics/asymptote/parser.cc
+++ b/graphics/asymptote/parser.cc
@@ -28,7 +28,7 @@
// The lexical analysis and parsing functions used by parseFile.
void setlexer(size_t (*input) (char* bif, size_t max_size), string filename);
-extern bool yyparse(void);
+extern int yyparse(void);
extern int yydebug;
extern int yy_flex_debug;
extern bool lexerEOF();
diff --git a/graphics/asymptote/pen.h b/graphics/asymptote/pen.h
index d2894cc01d..e26f3e5843 100644
--- a/graphics/asymptote/pen.h
+++ b/graphics/asymptote/pen.h
@@ -136,14 +136,18 @@ inline bool operator == (const Transparency& a, const Transparency& b) {
extern const char* BlendMode[];
extern const Int nBlendMode;
-const double bytescale=256.0*(1.0-DBL_EPSILON);
-
-// Map [0,1] to [0,255]
+// Map [0,1] to [0,255] uniformly, with 0.5 mapping to 128.
inline unsigned int byte(double r)
{
if(r < 0.0) r=0.0;
- else if(r > 1.0) r=1.0;
- return (int)(bytescale*r);
+ unsigned int c=(unsigned int)(r*256);
+ return c < 255 ? c : 255;
+}
+
+inline double byteinv(unsigned char i)
+{
+ if(i == 255) return 1.0;
+ return i/256.0;
}
class pen;
diff --git a/graphics/asymptote/picture.cc b/graphics/asymptote/picture.cc
index aaab64a7c6..c0d7934f30 100644
--- a/graphics/asymptote/picture.cc
+++ b/graphics/asymptote/picture.cc
@@ -253,14 +253,15 @@ bool picture::havepng()
return false;
}
-bool picture::havenewpage()
+unsigned int picture::pagecount()
{
+ unsigned int c=1;
for(nodelist::iterator p=nodes.begin(); p != nodes.end(); ++p) {
assert(*p);
if((*p)->isnewpage())
- return true;
+ ++c;
}
- return false;
+ return c;
}
bbox picture::bounds()
@@ -358,6 +359,7 @@ void texinit()
bool context=settings::context(getSetting<string>("tex"));
string dir=stripFile(outname());
+ dir=dir.substr(0,dir.length()-1);
string logname;
if(!context) logname=dir;
logname += "texput.log";
@@ -371,11 +373,16 @@ void texinit()
mem::vector<string> cmd;
cmd.push_back(texprogram());
+ string oldPath;
if(context) {
+ if(!dir.empty()) {
+ oldPath=getPath();
+ setPath(dir.c_str());
+ }
cmd.push_back("--pipe");
} else {
if(!dir.empty())
- cmd.push_back("-output-directory="+dir.substr(0,dir.length()-1));
+ cmd.push_back("-output-directory="+dir);
string jobname="texput";
if(getSetting<bool>("inlineimage") || getSetting<bool>("inlinetex")) {
string name=stripDir(stripExt((outname())));
@@ -411,13 +418,19 @@ int opentex(const string& texname, const string& prefix, bool dvi)
cmd.push_back(texprogram());
if(dvi)
cmd.push_back("-output-format=dvi");
+ string dir=stripFile(texname);
+ dir=dir.substr(0,dir.length()-1);
+ string oldPath;
if(context) {
+ if(!dir.empty()) {
+ oldPath=getPath();
+ setPath(dir.c_str());
+ }
cmd.push_back("--nonstopmode");
cmd.push_back(texname);
} else {
- string dir=stripFile(texname);
if(!dir.empty())
- cmd.push_back("-output-directory="+dir.substr(0,dir.length()-1));
+ cmd.push_back("-output-directory="+dir);
cmd.push_back("\\nonstopmode\\input");
cmd.push_back(stripDir(texname));
}
@@ -432,11 +445,19 @@ int opentex(const string& texname, const string& prefix, bool dvi)
System(cmd,0);
}
}
+ if(context && !oldPath.empty())
+ setPath(oldPath.c_str());
return status;
}
-void dvisvgmCommand(mem::vector<string>& cmd, const string &in, const string& out)
+string dvisvgmCommand(mem::vector<string>& cmd, const string& outname)
{
+ string dir=stripFile(outname);
+ string oldPath;
+ if(!dir.empty()) {
+ oldPath=getPath();
+ setPath(dir.c_str());
+ }
cmd.push_back(getSetting<string>("dvisvgm"));
cmd.push_back("-n");
cmd.push_back("-v3");
@@ -445,8 +466,10 @@ void dvisvgmCommand(mem::vector<string>& cmd, const string &in, const string& ou
cmd.push_back("--libgs="+libgs);
// cmd.push_back("--optimize"); // Requires dvisvgm > 2.9.1
push_split(cmd,getSetting<string>("dvisvgmOptions"));
- cmd.push_back("-o"+out);
- cmd.push_back(in);
+ string outfile=stripDir(outname);
+ if(!outfile.empty())
+ cmd.push_back("-o"+outfile);
+ return oldPath;
}
bool picture::texprocess(const string& texname, const string& outname,
@@ -470,16 +493,14 @@ bool picture::texprocess(const string& texname, const string& outname,
mem::vector<string> cmd;
if(svg) {
- dvisvgmCommand(cmd,dviname,outname);
- ostringstream buf;
- bbox B=svgbbox(b,bboxshift);
- buf << "--bbox="
- << B.left << "bp "
- << B.bottom << "bp "
- << B.right << "bp "
- << B.top << "bp";
- cmd.push_back(buf.str());
+ string name=deconstruct ? buildname(prefix+"_%1p","svg") : outname;
+ string oldPath=dvisvgmCommand(cmd,name);
+ cmd.push_back(stripDir(dviname));
+ if(deconstruct)
+ cmd.push_back("-p1-");
status=System(cmd,0,true,"dvisvgm");
+ if(!oldPath.empty())
+ setPath(oldPath.c_str());
if(!keep)
unlink(dviname.c_str());
} else {
@@ -508,7 +529,7 @@ bool picture::texprocess(const string& texname, const string& outname,
cmd.push_back("-Pdownload35");
cmd.push_back("-D600");
cmd.push_back("-O"+String(hoffset)+"bp,"+String(voffset)+"bp");
- bool ps=havenewpage();
+ bool ps=pagecount() > 1;
if(ps)
cmd.push_back("-T"+String(getSetting<double>("paperwidth"))+"bp,"+
String(paperHeight)+"bp");
@@ -546,8 +567,7 @@ bool picture::texprocess(const string& texname, const string& outname,
}
if (first && s.find("%%BoundingBox:") == 0) {
- bbox box=b;
- box.shift(bboxshift);
+ bbox box=b.shift(bboxshift);
if(verbose > 2) BoundingBox(cout,box);
fout.BoundingBox(box);
first=false;
@@ -587,6 +607,9 @@ bool picture::texprocess(const string& texname, const string& outname,
unlink(auxname(prefix,"aux").c_str());
unlink(auxname(prefix,"log").c_str());
unlink(auxname(prefix,"out").c_str());
+ string dir=stripFile(prefix);
+ unlink((dir+"texput.log").c_str());
+ unlink((dir+"texput.aux").c_str());
if(settings::context(texengine)) {
unlink(auxname(prefix,"top").c_str());
unlink(auxname(prefix,"tua").c_str());
@@ -701,25 +724,51 @@ bool picture::reloadPDF(const string& Viewer, const string& outname) const
return true;
}
-int picture::epstosvg(const string& epsname, const string& outname)
-{
- mem::vector<string> cmd;
- dvisvgmCommand(cmd,epsname,outname);
- cmd.push_back("-E");
- int status=System(cmd,0,true,"dvisvgm");
- if(!getSetting<bool>("keep"))
- unlink(epsname.c_str());
- return status;
-}
-
-int picture::pdftosvg(const string& pdfname, const string& outname)
+int picture::epstosvg(const string& epsname, const string& outname,
+ unsigned int pages)
{
- mem::vector<string> cmd;
- dvisvgmCommand(cmd,pdfname,outname);
- cmd.push_back("--pdf");
- int status=System(cmd,0,true,"dvisvgm");
- if(status == 0 && !getSetting<bool>("keep"))
- unlink(pdfname.c_str());
+ string oldPath;
+ int status=0;
+ if(deconstruct && getSetting<bool>("dvisvgmMultipleFiles")) {
+ mem::vector<string> cmd;
+ oldPath=dvisvgmCommand(cmd,stripFile(outname));
+ for(unsigned i=1; i <= pages; ++i) {
+ ostringstream buf;
+ buf << epsname << i << ".ps";
+ cmd.push_back(buf.str());
+ }
+ cmd.push_back("-E");
+ status=System(cmd,0,true,"dvisvgm");
+ for(unsigned i=1; i <= pages; ++i) {
+ ostringstream buf;
+ buf << epsname << i << ".ps";
+ if(!getSetting<bool>("keep"))
+ unlink(buf.str().c_str());
+ }
+ if(!oldPath.empty())
+ setPath(oldPath.c_str());
+ } else {
+ string outprefix=stripExt(outname);
+ for(unsigned i=1; i <= pages; ++i) {
+ mem::vector<string> cmd;
+ ostringstream out;
+ out << outprefix;
+ if(deconstruct)
+ out << "_" << i;
+ out << ".svg";
+ oldPath=dvisvgmCommand(cmd,out.str());
+ ostringstream buf;
+ buf << epsname << i << ".ps";
+ cmd.push_back(buf.str());
+ cmd.push_back("-E");
+ status=System(cmd,0,true,"dvisvgm");
+ if(!getSetting<bool>("keep"))
+ unlink(buf.str().c_str());
+ if(!oldPath.empty())
+ setPath(oldPath.c_str());
+ if(status != 0) break;
+ }
+ }
return status;
}
@@ -761,17 +810,11 @@ bool picture::postprocess(const string& prename, const string& outname,
} else status=epstopdf(prename,outname);
} else if(epsformat) {
if(svg) {
- bool haveShading=pdf && havepng();
- if(!haveShading)
- status=pdftosvg(prename,outname);
- if(haveShading || status != 0) {
- // Dvisvgm version < 2.4 doesn't support --pdf
- // Dvisvgm --pdf doesn't support shading
- string psname=stripExt(prename)+".ps";
- status=pdftoeps(prename,psname,false);
- if(status != 0) return false;
- status=epstosvg(psname,outname);
- }
+ string psname=stripExt(prename);
+ status=pdftoeps(prename,psname+"%d.ps",false);
+ if(status != 0) return false;
+ status=epstosvg(stripDir(psname),outname,pagecount());
+ if(status != 0) return false;
epsformat=false;
} else
status=pdftoeps(prename,outname);
@@ -818,7 +861,7 @@ bool picture::postprocess(const string& prename, const string& outname,
}
if(status != 0) return false;
- if(verbose > 0)
+ if(verbose > 0 && !deconstruct)
cout << "Wrote " << outname << endl;
return display(outname,outputformat,wait,view,epsformat);
@@ -922,11 +965,14 @@ bool picture::shipout(picture *preamble, const string& Prefix,
}
bool svgformat=outputformat == "svg";
+ bool png=outputformat == "png";
string texengine=getSetting<string>("tex");
+
string texengineSave;
- if(!empty && svgformat && texengine == "latex" && havepng()) {
+ if(!empty && !deconstruct && svgformat && texengine == "latex"
+ && havepng()) {
texengineSave=texengine;
Setting("tex")=texengine="pdflatex";
}
@@ -955,7 +1001,7 @@ bool picture::shipout(picture *preamble, const string& Prefix,
bool Labels=labels || TeXmode;
- if(outputformat == "png" && (b.right-b.left < 1.0 || b.top-b.bottom < 1.0))
+ if(png && (b.right-b.left < 1.0 || b.top-b.bottom < 1.0))
empty=true;
if(empty && !Labels) { // Output a null file
@@ -970,7 +1016,8 @@ bool picture::shipout(picture *preamble, const string& Prefix,
epsformat,false);
}
- Labels |= svg;
+ if(svg || png)
+ Labels=true;
if(Labels)
prefix=cleanpath(prefix);
@@ -1003,8 +1050,7 @@ bool picture::shipout(picture *preamble, const string& Prefix,
bboxshift +=
pair((aligndir.getx()+0.5)*xexcess,(aligndir.gety()+0.5)*yexcess);
}
- } else if(svg)
- bboxshift += pair(-b.left,b.top);
+ }
bool status=true;
@@ -1013,8 +1059,10 @@ bool picture::shipout(picture *preamble, const string& Prefix,
if(Labels) {
texname=TeXmode ? buildname(prefix,"tex") : auxname(prefix,"tex");
- tex=dvi ? new svgtexfile(texname,b) : new texfile(texname,b);
- tex->prologue();
+ tex=dvi ?
+ new svgtexfile(texname,b,false,deconstruct) :
+ new texfile(texname,b);
+ tex->prologue(deconstruct);
}
nodelist::iterator layerp=nodes.begin();
@@ -1038,7 +1086,7 @@ bool picture::shipout(picture *preamble, const string& Prefix,
if(pdf) pdfname=buildname(buf.str(),"pdf");
} else {
psname=epsname;
- bshift.shift(bboxshift);
+ bshift=bshift.shift(bboxshift);
}
files.push_back(psname);
if(pdf) files.push_back(pdfname);
@@ -1291,6 +1339,8 @@ bool picture::shipout3(const string& prefix, const string& format,
if(getSetting<bool>("interrupt"))
return true;
+ if(width <= 0 || height <= 0) return false;
+
bool webgl=format == "html";
#ifndef HAVE_LIBGLM
@@ -1342,7 +1392,10 @@ bool picture::shipout3(const string& prefix, const string& format,
#endif
#endif
- if(!webgl) {
+ bool v3d=format == "v3d";
+ bool format3d=webgl || v3d;
+
+ if(!format3d) {
#ifdef HAVE_GL
if(glthread && !offscreen) {
#ifdef HAVE_PTHREAD
@@ -1402,18 +1455,44 @@ bool picture::shipout3(const string& prefix, const string& format,
glrender(prefix,pic,outputformat,width,height,angle,zoom,m,M,shift,margin,t,
background,nlights,lights,diffuse,specular,View,oldpid);
- if(webgl) {
- jsfile js;
+ if(format3d) {
string name=buildname(prefix,format);
- js.open(name);
+ abs3Doutfile *fileObj=nullptr;
+
+ if(webgl)
+ fileObj=new jsfile(name);
+ else if(v3d)
+#ifdef HAVE_RPC_RPC_H
+ fileObj=new gzv3dfile(name,getSetting<bool>("lossy") ||
+ getSetting<double>("prerender") > 0.0);
+#else
+ {
+ ostringstream buf;
+ buf << name << ": XDR write support not enabled";
+ reportError(buf);
+ }
+#endif
- for(nodelist::iterator p=pic->nodes.begin(); p != pic->nodes.end(); ++p) {
- assert(*p);
- (*p)->write(&js);
+ if(fileObj) {
+ for (auto& p : pic->nodes) {
+ assert(p);
+ p->write(fileObj);
+ }
+
+ fileObj->close();
+ delete fileObj;
}
- js.finish(name);
- if(View)
+
+ if(webgl && View)
htmlView(name);
+
+#ifdef HAVE_GL
+ if(format3dWait) {
+ gl::format3dWait=false;
+ endwait(initSignal,initLock);
+ }
+#endif
+
return true;
}
#endif
diff --git a/graphics/asymptote/picture.h b/graphics/asymptote/picture.h
index 91ef54260b..61b3bd8c4f 100644
--- a/graphics/asymptote/picture.h
+++ b/graphics/asymptote/picture.h
@@ -28,14 +28,16 @@ private:
bboxlist bboxstack;
groupsmap groups;
unsigned billboard;
+ bool deconstruct;
public:
bbox3 b3; // 3D bounding box
typedef mem::list<drawElement*> nodelist;
nodelist nodes;
- picture() : labels(false), lastnumber(0), lastnumber3(0), T(identity),
- billboard(0) {}
+ picture(bool deconstruct=false) :
+ labels(false), lastnumber(0), lastnumber3(0), T(identity), billboard(0),
+ deconstruct(deconstruct) {}
// Destroy all of the owned picture objects.
~picture();
@@ -56,7 +58,8 @@ public:
bool havelabels();
bool have3D();
bool havepng();
- bool havenewpage();
+
+ unsigned int pagecount();
bbox bounds();
bbox3 bounds3();
@@ -64,9 +67,8 @@ public:
// Compute bounds on ratio (x,y)/z for 3d picture (not cached).
pair ratio(double (*m)(double, double));
- int epstosvg(const string& epsname, const string& outname);
- int pdftosvg(const string& pdfname, const string& outname);
-
+ int epstosvg(const string& epsname, const string& outname,
+ unsigned int pages);
int epstopdf(const string& epsname, const string& pdfname);
int pdftoeps(const string& pdfname, const string& epsname, bool eps=true);
diff --git a/graphics/asymptote/prc/oPRCFile.h b/graphics/asymptote/prc/oPRCFile.h
index d0bbdc1ea6..4a1ef84282 100644
--- a/graphics/asymptote/prc/oPRCFile.h
+++ b/graphics/asymptote/prc/oPRCFile.h
@@ -39,6 +39,7 @@
#include "PRC.h"
#include "PRCbitStream.h"
#include "writePRC.h"
+#include "xstream.h"
namespace prc {
@@ -46,7 +47,7 @@ class oPRCFile;
class PRCFileStructure;
// Map [0,1] to [0,255]
-inline uint8_t byte(double r)
+inline uint8_t byte(double r)
{
if(r < 0.0) r=0.0;
else if(r > 1.0) r=1.0;
@@ -61,7 +62,7 @@ struct RGBAColour
R(r), G(g), B(b), A(a) {}
double R,G,B,A;
- void Set(double r, double g, double b, double a=1.0)
+ void Set(double r, double g, double b, double a=1.0)
{
R = r; G = g; B = b; A = a;
}
@@ -83,11 +84,20 @@ struct RGBAColour
return (B<c.B);
return (A<c.A);
}
+
friend RGBAColour operator * (const RGBAColour& a, const double d)
{ return RGBAColour(a.R*d,a.G*d,a.B*d,a.A*d); }
friend RGBAColour operator * (const double d, const RGBAColour& a)
{ return RGBAColour(a.R*d,a.G*d,a.B*d,a.A*d); }
+#ifdef HAVE_RPC_RPC_H
+ friend xdr::oxstream& operator<<(xdr::oxstream& out, RGBAColour const& col)
+ {
+ out << (float) col.R << (float) col.G << (float) col.B << (float) col.A;
+ return out;
+ }
+#endif
+
};
typedef std::map<RGBAColour,uint32_t> PRCcolourMap;
@@ -200,7 +210,7 @@ typedef std::map<PRCmaterial,uint32_t> PRCmaterialMap;
struct PRCpicture
{
- PRCpicture() :
+ PRCpicture() :
data(NULL), format(KEPRCPicture_BITMAP_RGB_BYTE),
width(0), height(0), size(0) {}
PRCpicture(const uint8_t* pic, EPRCPictureDataFormat picf,
@@ -290,7 +300,7 @@ typedef std::map<PRCmaterialgeneric,uint32_t> PRCmaterialgenericMap;
struct PRCtexturedefinition
{
- PRCtexturedefinition() :
+ PRCtexturedefinition() :
picture_index(m1), picture_replace(false), picture_repeat(false) {}
PRCtexturedefinition(uint32_t picindex, bool picreplace=false, bool picrepeat=false) :
picture_index(picindex), picture_replace(picreplace), picture_repeat(picrepeat) {}
@@ -320,7 +330,7 @@ typedef std::map<PRCtexturedefinition,uint32_t> PRCtexturedefinitionMap;
struct PRCtextureapplication
{
- PRCtextureapplication() :
+ PRCtextureapplication() :
material_generic_index(m1), texture_definition_index(m1) {}
PRCtextureapplication(uint32_t matindex, uint32_t texindex) :
material_generic_index(matindex), texture_definition_index(texindex) {}
@@ -345,7 +355,7 @@ typedef std::map<PRCtextureapplication,uint32_t> PRCtextureapplicationMap;
struct PRCstyle
{
- PRCstyle() :
+ PRCstyle() :
line_width(0), alpha(1), is_material(false), color_material_index(m1) {}
PRCstyle(double linewidth, double alph, bool ismat, uint32_t colindex=m1) :
line_width(linewidth), alpha(alph), is_material(ismat), color_material_index(colindex) {}
@@ -390,7 +400,7 @@ typedef std::vector<PRCtessquad> PRCtessquadList;
/*
struct PRCtesstriangle // textured triangle
{
- PRCtesstriangle() :
+ PRCtesstriangle() :
style(m1) {}
PRCVector3d vertices[3];
// PRCVector3d normals[3];
@@ -459,9 +469,9 @@ public:
class PRCgroup
{
public:
- PRCgroup() :
+ PRCgroup() :
product_occurrence(NULL), parent_product_occurrence(NULL), part_definition(NULL), parent_part_definition(NULL), transform(NULL) {}
- PRCgroup(const std::string& name) :
+ PRCgroup(const std::string& name) :
product_occurrence(NULL), parent_product_occurrence(NULL), part_definition(NULL), parent_part_definition(NULL), transform(NULL), name(name) {}
PRCProductOccurrence *product_occurrence, *parent_product_occurrence;
PRCPartDefinition *part_definition, *parent_part_definition;
@@ -717,7 +727,7 @@ class oPRCFile
std::string lastgroupname;
std::vector<std::string> lastgroupnames;
std::string calculate_unique_name(const ContentPRCBase *prc_entity,const ContentPRCBase *prc_occurence);
-
+
bool finish();
uint32_t getSize();
@@ -793,7 +803,7 @@ template<class V>
else
return createTriangleMesh(nP, P, nI, PI, style, nN, N, NI, nT, T, TI, nC, C, CI, 0, NULL, NULL, ca);
}
-
+
template<class V>
uint32_t createTriangleMesh(uint32_t nP, const V P[], uint32_t nI, const uint32_t PI[][3], const uint32_t style_index,
uint32_t nN, const V N[], const uint32_t NI[][3],
@@ -939,7 +949,7 @@ uint32_t nN, const V N[], const uint32_t NI[][3],
#define PRCCARTRANSFORM const double origin[3], const double x_axis[3], const double y_axis[3], double scale
#define PRCGENTRANSFORM const double* t=NULL
#define PRCNOMATERIALINDEX m1
-
+
#define ADDWIRE(curvtype) \
PRCgroup &group = findGroup(); \
group.wires.push_back(PRCwire()); \
@@ -975,7 +985,7 @@ inline bool isid(const double* t)
t[8]==0 && t[9]==0 && t[10]==1 && t[11]==0 &&
t[12]==0 && t[13]==0 && t[14]==0 && t[15]==1);
}
-
+
#define SETTRANSF \
if(t&&!isid(t)) \
face.transform = new PRCGeneralTransformation3d(t); \
@@ -1007,7 +1017,7 @@ inline bool isid(const double* t)
{ useLines(tess_index,addLineMaterial(c,w),origin, x_axis, y_axis, scale); }
// void addTriangle(const double P[][3], const double T[][2], uint32_t style_index);
-
+
template<class V>
void addLine(uint32_t n, const V P[], const RGBAColour &c, double w=1.0)
{
@@ -1179,7 +1189,7 @@ void addPatch(const V cP[], const PRCmaterial &m)
}
}
-template<class V>
+template<class V>
void addSurface(uint32_t dU, uint32_t dV, uint32_t nU, uint32_t nV,
const V cP[], const double *kU,
const double *kV, const PRCmaterial &m,
diff --git a/graphics/asymptote/predicates.cc b/graphics/asymptote/predicates.cc
index 0b0a6aff86..27a21de29a 100644
--- a/graphics/asymptote/predicates.cc
+++ b/graphics/asymptote/predicates.cc
@@ -363,7 +363,7 @@
Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2)
/* 2^(-p), where p=DBL_MANT_DIG. Used to estimate roundoff errors. */
-static const REAL epsilon=0.5*DBL_EPSILON;
+static const REAL epsilon=0.5*DBL_EPSILON;
/* 2^ceiling(p/2) + 1. Used to split floats in half. */
static const REAL splitter=sqrt((DBL_MANT_DIG % 2 ? 2.0 : 1.0)/epsilon)+1.0;
@@ -373,7 +373,7 @@ const REAL resulterrbound=(3.0 + 8.0 * epsilon) * epsilon;
const REAL ccwerrboundA=(3.0 + 16.0 * epsilon) * epsilon;
const REAL ccwerrboundB=(2.0 + 12.0 * epsilon) * epsilon;
const REAL ccwerrboundC=(9.0 + 64.0 * epsilon) * epsilon * epsilon;
-const REAL o3derrboundA=(7.0 + 56.0 * epsilon) * epsilon;
+const REAL o3derrboundA=(7.0 + 56.0 * epsilon) * epsilon;
const REAL o3derrboundB=(3.0 + 28.0 * epsilon) * epsilon;
const REAL o3derrboundC=(26.0 + 288.0 * epsilon) * epsilon * epsilon;
const REAL iccerrboundA=(10.0 + 96.0 * epsilon) * epsilon;
@@ -663,7 +663,7 @@ static float uniformfloatrand()
/* */
/*****************************************************************************/
-static int fast_expansion_sum_zeroelim(int elen, const REAL *e,
+static int fast_expansion_sum_zeroelim(int elen, const REAL *e,
int flen, const REAL *f, REAL *h)
/* h cannot be e or f. */
{
@@ -998,7 +998,7 @@ REAL orient2d(const REAL ax, const REAL ay, const REAL bx, const REAL by,
REAL pa[]={ax,ay};
REAL pb[]={bx,by};
REAL pc[]={cx,cy};
-
+
orient = orient2dadapt(pa, pb, pc, detsum);
FPU_RESTORE;
return orient;
@@ -1033,7 +1033,7 @@ REAL orient2d(const REAL ax, const REAL ay, const REAL bx, const REAL by,
/* */
/*****************************************************************************/
-static REAL orient3dadapt(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd,
+static REAL orient3dadapt(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd,
REAL permanent)
{
INEXACT REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz;
@@ -1463,7 +1463,7 @@ REAL orient3d(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd)
adxbdy = adx * bdy;
bdxady = bdx * ady;
- det = adz * (bdxcdy - cdxbdy)
+ det = adz * (bdxcdy - cdxbdy)
+ bdz * (cdxady - adxcdy)
+ cdz * (adxbdy - bdxady);
@@ -1507,7 +1507,7 @@ REAL orient3d(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd)
/* */
/*****************************************************************************/
-static REAL incircleadapt(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd,
+static REAL incircleadapt(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd,
REAL permanent)
{
INEXACT REAL adx, bdx, cdx, ady, bdy, cdy;
@@ -2089,7 +2089,7 @@ REAL incircle(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd)
REAL inc;
FPU_ROUND_DOUBLE;
-
+
adx = pa[0] - pd[0];
bdx = pb[0] - pd[0];
cdx = pc[0] - pd[0];
@@ -2138,7 +2138,7 @@ REAL incircle(REAL ax, REAL ay, REAL bx, REAL by, REAL cx, REAL cy, REAL dx,
REAL inc;
FPU_ROUND_DOUBLE;
-
+
adx = ax - dx;
bdx = bx - dx;
cdx = cx - dx;
@@ -2175,7 +2175,7 @@ REAL incircle(REAL ax, REAL ay, REAL bx, REAL by, REAL cx, REAL cy, REAL dx,
REAL pb[]={bx,by};
REAL pc[]={cx,cy};
REAL pd[]={dx,dy};
-
+
inc = incircleadapt(pa, pb, pc, pd, permanent);
FPU_RESTORE;
return inc;
@@ -2460,7 +2460,7 @@ static REAL insphereexact(const REAL *pa, const REAL *pb, const REAL *pc, const
return deter[deterlen - 1];
}
-static REAL insphereadapt(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd, const REAL *pe,
+static REAL insphereadapt(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd, const REAL *pe,
REAL permanent)
{
INEXACT REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez;
diff --git a/graphics/asymptote/process.cc b/graphics/asymptote/process.cc
index acfd2f5e7f..9c3d2d313f 100644
--- a/graphics/asymptote/process.cc
+++ b/graphics/asymptote/process.cc
@@ -16,7 +16,7 @@
#include "program.h"
#include "interact.h"
#include "envcompleter.h"
-#include "parser.h"
+
#include "fileio.h"
#include "stack.h"
@@ -136,7 +136,7 @@ public:
: runnable(base->getPos()), base(base) {}
void prettyprint(ostream &out, Int indent) {
- absyntax::prettyname(out, "interactiveRunnable", indent);
+ absyntax::prettyname(out, "interactiveRunnable", indent, base->getPos());
base->prettyprint(out, indent+1);
}
@@ -151,10 +151,7 @@ public:
}
};
-enum transMode {
- TRANS_INTERACTIVE,
- TRANS_NORMAL
-};
+
// How to run a runnable in runnable-at-a-time mode.
@@ -187,165 +184,122 @@ void runAutoplain(coenv &e, istack &s) {
runRunnable(r,e,s);
}
-// Abstract base class for the core object being run in line-at-a-time mode, it
-// may be a block of code, file, or interactive prompt.
-struct icore {
- virtual ~icore() {}
-
- virtual void doParse() = 0;
- virtual void doList() = 0;
-
-public:
+// icore
- // preRun and postRun are the optional activities that take place before and
- // after running the code specified. They can be overridden by a derived
- // class that wishes different behaviour.
- virtual void preRun(coenv &e, istack &s) {
- if(getSetting<bool>("autoplain"))
- runAutoplain(e,s);
- }
- virtual void run(coenv &e, istack &s, transMode tm=TRANS_NORMAL) = 0;
+// preRun and postRun are the optional activities that take place before and
+// after running the code specified. They can be overridden by a derived
+// class that wishes different behaviour.
+void icore::preRun(coenv &e, istack &s) {
+ if(getSetting<bool>("autoplain"))
+ runAutoplain(e,s);
+}
- virtual void postRun(coenv &, istack &s) {
- run::exitFunction(&s);
- }
+void icore::postRun(coenv &, istack &s) {
+ run::exitFunction(&s);
+}
- virtual void doRun(bool purge=false, transMode tm=TRANS_NORMAL) {
- em.sync();
- if(em.errors())
- return;
+void icore::doRun(bool purge, transMode tm) {
+ em.sync();
+ if(em.errors())
+ return;
- try {
- if(purge) run::purge();
+ try {
+ if(purge) run::purge();
- penv pe;
- env base_env(pe.ge());
- coder base_coder(nullPos, "icore::doRun");
- coenv e(base_coder,base_env);
+ penv pe;
+ env base_env(pe.ge());
+ coder base_coder(nullPos, "icore::doRun");
+ coenv e(base_coder,base_env);
- vm::interactiveStack s;
- s.setInitMap(pe.ge().getInitMap());
- s.setEnvironment(&e);
+ vm::interactiveStack s;
+ s.setInitMap(pe.ge().getInitMap());
+ s.setEnvironment(&e);
- preRun(e,s);
+ preRun(e,s);
- if(purge) run::purge();
+ if(purge) run::purge();
- // Now that everything is set up, run the core.
- run(e,s,tm);
+ // Now that everything is set up, run the core.
+ run(e,s,tm);
- postRun(e,s);
+ postRun(e,s);
- } catch(std::bad_alloc&) {
- outOfMemory();
- } catch(quit) {
- // Exception to quit running the current code. Nothing more to do.
- } catch(handled_error) {
- em.statusError();
- }
+ } catch(std::bad_alloc&) {
+ outOfMemory();
+ } catch(quit const&) {
+ // Exception to quit running the current code. Nothing more to do.
+ } catch(handled_error const&) {
+ em.statusError();
+ }
- run::cleanup();
+ run::cleanup();
- em.clear();
- }
+ em.clear();
+}
- virtual void process(bool purge=false) {
- if (!interactive && getSetting<bool>("parseonly"))
- doParse();
- else if (getSetting<bool>("listvariables"))
- doList();
- else
- doRun(purge);
- }
-};
-// Abstract base class for one-time processing of an abstract syntax tree.
-class itree : public icore {
- string name;
+void icore::process(bool purge) {
+ if (!interactive && getSetting<bool>("parseonly"))
+ doParse();
+ else if (getSetting<bool>("listvariables"))
+ doList();
+ else
+ doRun(purge);
+}
- block *cachedTree;
-public:
- itree(string name="<unnamed>")
- : name(name), cachedTree(0) {}
+itree::itree(string name) : name(name), cachedTree(0) { }
- // Build the tree, possibly throwing a handled_error if it cannot be built.
- virtual block *buildTree() = 0;
- virtual block *getTree() {
- if (cachedTree==0) {
- try {
- cachedTree=buildTree();
- } catch(handled_error) {
- em.statusError();
- return 0;
- }
+block *itree::getTree() {
+ if (cachedTree==0) {
+ try {
+ cachedTree=buildTree();
+ } catch(handled_error const&) {
+ em.statusError();
+ return 0;
}
- return cachedTree;
}
+ return cachedTree;
+}
- virtual string getName() {
- return name;
- }
+string itree::getName() {
+ return name;
+}
- void doParse() {
- block *tree=getTree();
- em.sync();
- if(tree && !em.errors())
- tree->prettyprint(cout, 0);
- }
+void itree::doParse() {
+ block *tree=getTree();
+ em.sync();
+ if(tree && !em.errors())
+ tree->prettyprint(cout, 0);
+}
- void doList() {
- block *tree=getTree();
- if (tree) {
- penv pe;
- record *r=tree->transAsFile(pe.ge(), symbol::trans(getName()));
- r->e.list(r);
- }
+void itree::doList() {
+ block *tree=getTree();
+ if (tree) {
+ penv pe;
+ record *r=tree->transAsFile(pe.ge(), symbol::trans(getName()));
+ r->e.list(r);
}
+}
- void run(coenv &e, istack &s, transMode tm=TRANS_NORMAL) {
- block *tree=getTree();
- if (tree) {
- for(mem::list<runnable *>::iterator r=tree->stms.begin();
- r != tree->stms.end(); ++r) {
- processData().fileName=(*r)->getPos().filename();
- if(!em.errors() || getSetting<bool>("debug"))
- runRunnable(*r,e,s,tm);
- }
+void itree::run(coenv &e, istack &s, transMode tm) {
+ block *tree=getTree();
+ if (tree) {
+ for(mem::list<runnable *>::iterator r=tree->stms.begin();
+ r != tree->stms.end(); ++r) {
+ processData().fileName=(*r)->getPos().filename();
+ if(!em.errors() || getSetting<bool>("debug"))
+ runRunnable(*r,e,s,tm);
}
}
+}
- void doExec(transMode tm=TRANS_NORMAL) {
- // Don't prepare an environment to run the code if there isn't any code.
- if (getTree())
- icore::doRun(false,tm);
- }
-};
-
-class icode : public itree {
- block *tree;
-
-public:
- icode(block *tree, string name="<unnamed>")
- : itree(name), tree(tree) {}
-
- block *buildTree() {
- return tree;
- }
-};
-
-class istring : public itree {
- string str;
-
-public:
- istring(const string& str, string name="<eval>")
- : itree(name), str(str) {}
-
- block *buildTree() {
- return parser::parseString(str, getName());
- }
-};
+void itree::doExec(transMode tm) {
+ // Don't prepare an environment to run the code if there isn't any code.
+ if (getTree())
+ icore::doRun(false,tm);
+}
void printGreeting(bool interactive) {
if(!getSetting<bool>("quiet")) {
@@ -356,53 +310,46 @@ void printGreeting(bool interactive) {
}
}
-class ifile : public itree {
- string filename;
- string outname;
- string outname_save;
+ifile::ifile(const string& filename)
+ : itree(filename),
+ filename(filename),
+ outname(stripDir(stripExt(string(filename == "-" ? settings::outname() : filename), suffix))) {}
-public:
- ifile(const string& filename)
- : itree(filename),
- filename(filename),
- outname(stripDir(stripExt(string(filename == "-" ? settings::outname() : filename), suffix))) {}
+block *ifile::buildTree() {
+ return !filename.empty() ? parser::parseFile(filename,"Loading") : 0;
+}
- block *buildTree() {
- return !filename.empty() ? parser::parseFile(filename,"Loading") : 0;
- }
+void ifile::preRun(coenv& e, istack& s) {
+ outname_save=getSetting<string>("outname");
+ if(stripDir(outname_save).empty())
+ Setting("outname")=outname_save+outname;
- void preRun(coenv& e, istack& s) {
- outname_save=getSetting<string>("outname");
- if(stripDir(outname_save).empty())
- Setting("outname")=outname_save+outname;
+ itree::preRun(e, s);
+}
- itree::preRun(e, s);
- }
+void ifile::postRun(coenv &e, istack& s) {
+ itree::postRun(e, s);
- void postRun(coenv &e, istack& s) {
- itree::postRun(e, s);
+ Setting("outname")=outname_save;
+}
- Setting("outname")=outname_save;
+void ifile::process(bool purge) {
+ if(verbose > 1) printGreeting(false);
+ try {
+ init();
+ } catch(handled_error const&) {
}
- void process(bool purge=false) {
- if(verbose > 1) printGreeting(false);
- try {
- init();
- } catch(handled_error) {
- }
-
- if (verbose >= 1)
- cout << "Processing " << outname << endl;
+ if (verbose >= 1)
+ cout << "Processing " << outname << endl;
- try {
- icore::process(purge);
- }
- catch(handled_error) {
- em.statusError();
- }
+ try {
+ icore::process(purge);
}
-};
+ catch(handled_error const&) {
+ em.statusError();
+ }
+}
// Add a semi-colon terminator, if one is not there.
string terminateLine(const string line) {
@@ -783,7 +730,6 @@ class iprompt : public icore {
// Continue taking input until a termination command is received from xasy.
block *parseXasyLine(string line) {
-
#ifdef __MSDOS__
const string EOT="\x04\r\n";
#else
@@ -823,7 +769,7 @@ class iprompt : public icore {
run::updateFunction(&s);
uptodate=false;
- } catch(handled_error) {
+ } catch(handled_error const&) {
vm::indebugger=false;
} catch(interrupted&) {
// Turn off the interrupted flag.
@@ -873,7 +819,7 @@ public:
interact::init_interactive();
try {
setPath("",true);
- } catch(handled_error) {
+ } catch(handled_error const&) {
}
do {
@@ -975,11 +921,11 @@ public:
} catch(std::bad_alloc&) {
// TODO: give calling application useful message.
cerr << "out of memory" << endl;
- } catch (quit) {
+ } catch (quit const&) {
// I'm not sure whether this counts as successfully running the code or
// not.
cerr << "quit exception" << endl;
- } catch (handled_error) {
+ } catch (handled_error const&) {
// Normally, this is the result of an error that changes the return code
// of the free-standing asymptote program.
// An error should probably be reported to the application calling the
diff --git a/graphics/asymptote/process.h b/graphics/asymptote/process.h
index 3f3e739089..e076c39dfb 100644
--- a/graphics/asymptote/process.h
+++ b/graphics/asymptote/process.h
@@ -17,7 +17,9 @@
#include "pipestream.h"
#include "callable.h"
#include "pen.h"
+#include "dec.h"
#include "transform.h"
+#include "parser.h"
#ifdef HAVE_RPC_RPC_H
#include "xstream.h"
@@ -107,15 +109,16 @@ struct processDataStruct {
string KEY;
xkey_t xkey;
xmap_t xmap;
+ unsigned int xmapCount;
terminator<std::ofstream> ofile;
terminator<std::fstream> ifile;
#ifdef HAVE_RPC_RPC_H
- terminator<xdr::ioxstream> ixfile;
+ terminator<xdr::ixstream> ixfile;
terminator<xdr::oxstream> oxfile;
#endif
- processDataStruct() {
+ processDataStruct() : xmapCount(0) {
atExitFunction=NULL;
atUpdateFunction=NULL;
atBreakpointFunction=NULL;
@@ -125,6 +128,82 @@ struct processDataStruct {
};
+enum transMode {
+ TRANS_INTERACTIVE,
+ TRANS_NORMAL
+};
+
+// Abstract base class for the core object being run in line-at-a-time mode, it
+// may be a block of code, file, or interactive prompt.
+struct icore {
+ virtual ~icore() {}
+ virtual void doParse() = 0;
+ virtual void doList() = 0;
+
+public:
+ virtual void preRun(trans::coenv &e, istack &s);
+ virtual void run(trans::coenv &e, istack &s, transMode tm=TRANS_NORMAL) = 0;
+ virtual void postRun(trans::coenv &, istack &s);
+ virtual void doRun(bool purge=false, transMode tm=TRANS_NORMAL);
+ virtual void process(bool purge=false);
+};
+
+// Abstract base class for one-time processing of an abstract syntax tree.
+class itree : public icore {
+ string name;
+ absyntax::block *cachedTree;
+public:
+ itree(string name="<unnamed>");
+ virtual absyntax::block *buildTree() = 0;
+
+ // Build the tree, possibly throwing a handled_error if it cannot be built.
+ virtual absyntax::block *getTree();
+ virtual string getName();
+
+ void doParse();
+ void doList();
+ void run(trans::coenv &e, istack &s, transMode tm=TRANS_NORMAL);
+ void doExec(transMode tm=TRANS_NORMAL);
+};
+
+class ifile : public itree {
+ string filename;
+ string outname;
+ string outname_save;
+
+public:
+ ifile(const string& filename);
+ absyntax::block *buildTree();
+
+ void preRun(trans::coenv& e, istack& s);
+ void postRun(trans::coenv &e, istack& s);
+ void process(bool purge=false);
+};
+
+class icode : public itree {
+ absyntax::block *tree;
+
+public:
+ icode(absyntax::block *tree, string name="<unnamed>")
+ : itree(name), tree(tree) {}
+
+ absyntax::block *buildTree() {
+ return tree;
+ }
+};
+
+class istring : public itree {
+ string str;
+
+public:
+ istring(const string& str, string name="<eval>")
+ : itree(name), str(str) {}
+
+ absyntax::block *buildTree() {
+ return parser::parseString(str, getName());
+ }
+};
+
processDataStruct &processData();
#endif
diff --git a/graphics/asymptote/psfile.cc b/graphics/asymptote/psfile.cc
index 73fe53eb74..3a13b37225 100644
--- a/graphics/asymptote/psfile.cc
+++ b/graphics/asymptote/psfile.cc
@@ -203,6 +203,14 @@ void psfile::setcolor(const pen& p, const string& begin="",
}
}
+bool psfile::istargetfmt(string outputformat)
+{
+ return
+ outputformat == "pdf" || outputformat == "html" ||
+ outputformat == "svg" || outputformat == "png" ||
+ outputformat == "v3d";
+}
+
void psfile::setopacity(const pen& p)
{
if(p.blend() != lastpen.blend()) {
@@ -211,8 +219,7 @@ void psfile::setopacity(const pen& p)
string outputformat=settings::getSetting<string>("outformat");
if(p.opacity() != lastpen.opacity() &&
- (pdf || outputformat == "pdf" || outputformat == "html" ||
- outputformat == "svg")) {
+ ((pdftex() && outputformat == "") || istargetfmt(outputformat))) {
*out << p.opacity() << " .setfillconstantalpha" << newl
<< p.opacity() << " .setstrokeconstantalpha" << newl;
}
diff --git a/graphics/asymptote/psfile.h b/graphics/asymptote/psfile.h
index 2c6ac2dd5a..98e5574b8d 100644
--- a/graphics/asymptote/psfile.h
+++ b/graphics/asymptote/psfile.h
@@ -137,9 +137,13 @@ protected:
std::ostream *out;
public:
+ bool pdftex() {return settings::pdf(settings::getSetting<string>("tex"));}
+
psfile(const string& filename, bool pdfformat);
- psfile() {pdf=settings::pdf(settings::getSetting<string>("tex"));}
+ psfile() {pdf=pdftex();}
+
+ bool istargetfmt(string outputformat);
virtual ~psfile();
diff --git a/graphics/asymptote/revision.cc b/graphics/asymptote/revision.cc
index 4773f607a2..fbdccf7c1b 100644
--- a/graphics/asymptote/revision.cc
+++ b/graphics/asymptote/revision.cc
@@ -1,2 +1,2 @@
-const char *REVISION="2.70";
-const char *AsyGLVersion="1.00";
+const char *REVISION="2.72";
+const char *AsyGLVersion="1.01";
diff --git a/graphics/asymptote/runfile.cc b/graphics/asymptote/runfile.cc
index 72ead073b2..c9b2554da8 100644
--- a/graphics/asymptote/runfile.cc
+++ b/graphics/asymptote/runfile.cc
@@ -123,11 +123,14 @@ void gen_runfile3(stack *Stack)
string name=vm::pop<string>(Stack,emptystring);
#line 45 "runfile.in"
file *f=NULL;
- if(mode == "binary") {
+ if(mode == "binary")
f=new ibfile(name,check);
- } else if(mode == "xdr") {
+ else if(mode == "xdr" || mode == "xdrgz") {
#ifdef HAVE_RPC_RPC_H
- f=new ixfile(name,check);
+ if(mode == "xdr")
+ f=new ixfile(name,check);
+ else if(mode == "xdrgz")
+ f=new igzxfile(name,check);
#else
ostringstream buf;
buf << name << ": XDR read support not enabled";
@@ -135,7 +138,7 @@ void gen_runfile3(stack *Stack)
#endif
} else if(mode == "") {
char c=comment.empty() ? (char) 0 : comment[0];
- f=new ifile(name,c,check);
+ f=new camp::ifile(name,c,check);
} else {
f=NULL;
ostringstream buf;
@@ -147,7 +150,7 @@ void gen_runfile3(stack *Stack)
{Stack->push<file*>(f); return;}
}
-#line 71 "runfile.in"
+#line 74 "runfile.in"
// file* output(string name=emptystring, bool update=false, string comment=commentchar, string mode=emptystring);
void gen_runfile4(stack *Stack)
{
@@ -155,7 +158,7 @@ void gen_runfile4(stack *Stack)
string comment=vm::pop<string>(Stack,commentchar);
bool update=vm::pop<bool>(Stack,false);
string name=vm::pop<string>(Stack,emptystring);
-#line 73 "runfile.in"
+#line 76 "runfile.in"
file *f=NULL;
if(mode == "pipe") {
f=new opipe(name);
@@ -190,152 +193,152 @@ void gen_runfile4(stack *Stack)
{Stack->push<file*>(f); return;}
}
-#line 108 "runfile.in"
+#line 111 "runfile.in"
// bool eof(file *f);
void gen_runfile5(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 109 "runfile.in"
+#line 112 "runfile.in"
{Stack->push<bool>(f->eof()); return;}
}
-#line 113 "runfile.in"
+#line 116 "runfile.in"
// bool eol(file *f);
void gen_runfile6(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 114 "runfile.in"
+#line 117 "runfile.in"
{Stack->push<bool>(f->eol()); return;}
}
-#line 118 "runfile.in"
+#line 121 "runfile.in"
// bool error(file *f);
void gen_runfile7(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 119 "runfile.in"
+#line 122 "runfile.in"
{Stack->push<bool>(f->error()); return;}
}
-#line 123 "runfile.in"
+#line 126 "runfile.in"
// void clear(file *f);
void gen_runfile8(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 124 "runfile.in"
+#line 127 "runfile.in"
f->clear();
}
-#line 128 "runfile.in"
+#line 131 "runfile.in"
// void close(file *f);
void gen_runfile9(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 129 "runfile.in"
+#line 132 "runfile.in"
f->close();
}
-#line 133 "runfile.in"
+#line 136 "runfile.in"
// Int precision(file *f=NULL, Int digits=0);
void gen_runfile10(stack *Stack)
{
Int digits=vm::pop<Int>(Stack,0);
file * f=vm::pop<file *>(Stack,NULL);
-#line 134 "runfile.in"
+#line 137 "runfile.in"
if(f == 0) f=&camp::Stdout;
{Stack->push<Int>(f->precision(digits)); return;}
}
-#line 139 "runfile.in"
+#line 142 "runfile.in"
// void flush(file *f);
void gen_runfile11(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 140 "runfile.in"
+#line 143 "runfile.in"
f->flush();
}
-#line 144 "runfile.in"
+#line 147 "runfile.in"
// string getc(file *f);
void gen_runfile12(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 145 "runfile.in"
+#line 148 "runfile.in"
char c=0;
if(f->isOpen()) f->read(c);
{Stack->push<string>(string(1,c)); return;}
}
-#line 151 "runfile.in"
+#line 154 "runfile.in"
// Int tell(file *f);
void gen_runfile13(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 152 "runfile.in"
+#line 155 "runfile.in"
{Stack->push<Int>(f->tell()); return;}
}
-#line 156 "runfile.in"
+#line 159 "runfile.in"
// void seek(file *f, Int pos);
void gen_runfile14(stack *Stack)
{
Int pos=vm::pop<Int>(Stack);
file * f=vm::pop<file *>(Stack);
-#line 157 "runfile.in"
+#line 160 "runfile.in"
f->seek(pos,pos >= 0);
}
-#line 161 "runfile.in"
+#line 164 "runfile.in"
// void seekeof(file *f);
void gen_runfile15(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 162 "runfile.in"
+#line 165 "runfile.in"
f->seek(0,false);
}
-#line 166 "runfile.in"
+#line 169 "runfile.in"
void namePart(stack *Stack)
{
file f=vm::pop<file>(Stack);
-#line 167 "runfile.in"
+#line 170 "runfile.in"
{Stack->push<string>(f.filename()); return;}
}
-#line 171 "runfile.in"
+#line 174 "runfile.in"
void modePart(stack *Stack)
{
file f=vm::pop<file>(Stack);
-#line 172 "runfile.in"
+#line 175 "runfile.in"
{Stack->push<string>(f.FileMode()); return;}
}
// Set file dimensions
-#line 177 "runfile.in"
+#line 180 "runfile.in"
void dimensionSetHelper(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
Int nz=vm::pop<Int>(Stack,-1);
Int ny=vm::pop<Int>(Stack,-1);
Int nx=vm::pop<Int>(Stack,-1);
-#line 178 "runfile.in"
+#line 181 "runfile.in"
f->dimension(nx,ny,nz);
{Stack->push<file*>(f); return;}
}
-#line 183 "runfile.in"
+#line 186 "runfile.in"
void dimensionSet(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 184 "runfile.in"
+#line 187 "runfile.in"
{Stack->push<callable*>(new thunk(new bfunc(dimensionSetHelper),f)); return;}
}
-#line 188 "runfile.in"
+#line 191 "runfile.in"
void dimensionPart(stack *Stack)
{
file f=vm::pop<file>(Stack);
-#line 189 "runfile.in"
+#line 192 "runfile.in"
array *a=new array(3);
(*a)[0]=f.Nx();
(*a)[1]=f.Ny();
@@ -344,174 +347,174 @@ void dimensionPart(stack *Stack)
}
// Set file f to read arrays in line-at-a-time mode
-#line 198 "runfile.in"
+#line 201 "runfile.in"
void lineSetHelper(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
bool b=vm::pop<bool>(Stack,true);
-#line 199 "runfile.in"
+#line 202 "runfile.in"
f->LineMode(b);
{Stack->push<file*>(f); return;}
}
-#line 204 "runfile.in"
+#line 207 "runfile.in"
void lineSet(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 205 "runfile.in"
+#line 208 "runfile.in"
{Stack->push<callable*>(new thunk(new bfunc(lineSetHelper),f)); return;}
}
-#line 209 "runfile.in"
+#line 212 "runfile.in"
void linePart(stack *Stack)
{
file f=vm::pop<file>(Stack);
-#line 210 "runfile.in"
+#line 213 "runfile.in"
{Stack->push<bool>(f.LineMode()); return;}
}
// Set file to read comma-separated values
-#line 215 "runfile.in"
+#line 218 "runfile.in"
void csvSetHelper(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
bool b=vm::pop<bool>(Stack,true);
-#line 216 "runfile.in"
+#line 219 "runfile.in"
f->CSVMode(b);
{Stack->push<file*>(f); return;}
}
-#line 221 "runfile.in"
+#line 224 "runfile.in"
void csvSet(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 222 "runfile.in"
+#line 225 "runfile.in"
{Stack->push<callable*>(new thunk(new bfunc(csvSetHelper),f)); return;}
}
-#line 226 "runfile.in"
+#line 229 "runfile.in"
void csvPart(stack *Stack)
{
file f=vm::pop<file>(Stack);
-#line 227 "runfile.in"
+#line 230 "runfile.in"
{Stack->push<bool>(f.CSVMode()); return;}
}
// Set file to read whitespace-separated values
-#line 232 "runfile.in"
+#line 235 "runfile.in"
void wordSetHelper(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
bool b=vm::pop<bool>(Stack,true);
-#line 233 "runfile.in"
+#line 236 "runfile.in"
f->WordMode(b);
{Stack->push<file*>(f); return;}
}
-#line 238 "runfile.in"
+#line 241 "runfile.in"
void wordSet(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 239 "runfile.in"
+#line 242 "runfile.in"
{Stack->push<callable*>(new thunk(new bfunc(wordSetHelper),f)); return;}
}
-#line 243 "runfile.in"
+#line 246 "runfile.in"
void wordPart(stack *Stack)
{
file f=vm::pop<file>(Stack);
-#line 244 "runfile.in"
+#line 247 "runfile.in"
{Stack->push<bool>(f.WordMode()); return;}
}
// Set file to read/write single precision real XDR values.
-#line 249 "runfile.in"
+#line 252 "runfile.in"
void singlerealSetHelper(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
bool b=vm::pop<bool>(Stack,true);
-#line 250 "runfile.in"
+#line 253 "runfile.in"
f->SingleReal(b);
{Stack->push<file*>(f); return;}
}
-#line 255 "runfile.in"
+#line 258 "runfile.in"
void singlerealSet(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 256 "runfile.in"
+#line 259 "runfile.in"
{Stack->push<callable*>(new thunk(new bfunc(singlerealSetHelper),f)); return;}
}
-#line 260 "runfile.in"
+#line 263 "runfile.in"
void singlerealPart(stack *Stack)
{
file f=vm::pop<file>(Stack);
-#line 261 "runfile.in"
+#line 264 "runfile.in"
{Stack->push<bool>(f.SingleReal()); return;}
}
// Set file to read/write single precision int XDR values.
-#line 266 "runfile.in"
+#line 269 "runfile.in"
void singleintSetHelper(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
bool b=vm::pop<bool>(Stack,true);
-#line 267 "runfile.in"
+#line 270 "runfile.in"
f->SingleInt(b);
{Stack->push<file*>(f); return;}
}
-#line 272 "runfile.in"
+#line 275 "runfile.in"
void singleintSet(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 273 "runfile.in"
+#line 276 "runfile.in"
{Stack->push<callable*>(new thunk(new bfunc(singleintSetHelper),f)); return;}
}
-#line 277 "runfile.in"
+#line 280 "runfile.in"
void singleintPart(stack *Stack)
{
file f=vm::pop<file>(Stack);
-#line 278 "runfile.in"
+#line 281 "runfile.in"
{Stack->push<bool>(f.SingleInt()); return;}
}
// Set file to read/write signed int XDR values.
-#line 283 "runfile.in"
+#line 286 "runfile.in"
void signedintSetHelper(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
bool b=vm::pop<bool>(Stack,true);
-#line 284 "runfile.in"
+#line 287 "runfile.in"
f->SignedInt(b);
{Stack->push<file*>(f); return;}
}
-#line 289 "runfile.in"
+#line 292 "runfile.in"
void signedintSet(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 290 "runfile.in"
+#line 293 "runfile.in"
{Stack->push<callable*>(new thunk(new bfunc(signedintSetHelper),f)); return;}
}
-#line 294 "runfile.in"
+#line 297 "runfile.in"
void signedintPart(stack *Stack)
{
file f=vm::pop<file>(Stack);
-#line 295 "runfile.in"
+#line 298 "runfile.in"
{Stack->push<bool>(f.SignedInt()); return;}
}
// Set file to read an arrayi (i int sizes followed by an i-dimensional array)
-#line 300 "runfile.in"
+#line 303 "runfile.in"
void readSetHelper(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
Int i=vm::pop<Int>(Stack);
-#line 301 "runfile.in"
+#line 304 "runfile.in"
switch(i) {
case 1:
f->dimension(-2);
@@ -532,21 +535,21 @@ void readSetHelper(stack *Stack)
{Stack->push<file*>(f); return;}
}
-#line 322 "runfile.in"
+#line 325 "runfile.in"
void readSet(stack *Stack)
{
file * f=vm::pop<file *>(Stack);
-#line 323 "runfile.in"
+#line 326 "runfile.in"
{Stack->push<callable*>(new thunk(new bfunc(readSetHelper),f)); return;}
}
// Delete file named s.
-#line 328 "runfile.in"
+#line 331 "runfile.in"
// Int delete(string s);
void gen_runfile41(stack *Stack)
{
string s=vm::pop<string>(Stack);
-#line 329 "runfile.in"
+#line 332 "runfile.in"
s=outpath(s);
Int rc=unlink(s.c_str());
if(rc == 0 && verbose > 0)
@@ -555,13 +558,13 @@ void gen_runfile41(stack *Stack)
}
// Rename file "from" to file "to".
-#line 338 "runfile.in"
+#line 341 "runfile.in"
// Int rename(string from, string to);
void gen_runfile42(stack *Stack)
{
string to=vm::pop<string>(Stack);
string from=vm::pop<string>(Stack);
-#line 339 "runfile.in"
+#line 342 "runfile.in"
from=outpath(from);
to=outpath(to);
Int rc=rename(from.c_str(),to.c_str());
@@ -571,12 +574,12 @@ void gen_runfile42(stack *Stack)
}
// Create a uniquely named temporary file.
-#line 349 "runfile.in"
+#line 352 "runfile.in"
// string mktemp(string s);
void gen_runfile43(stack *Stack)
{
string s=vm::pop<string>(Stack);
-#line 350 "runfile.in"
+#line 353 "runfile.in"
char *S=StrdupMalloc(s+"XXXXXX");
int fd=mkstemp(S);
if(fd < 0) {
@@ -603,85 +606,85 @@ void gen_runfile_venv(venv &ve)
REGISTER_BLTIN(run::nullFile,"nullFile");
#line 43 "runfile.in"
addFunc(ve, run::gen_runfile3, primFile(), SYM(input), formal(primString(), SYM(name), true, false), formal(primBoolean(), SYM(check), true, false), formal(primString(), SYM(comment), true, false), formal(primString(), SYM(mode), true, false));
-#line 71 "runfile.in"
+#line 74 "runfile.in"
addFunc(ve, run::gen_runfile4, primFile(), SYM(output), formal(primString(), SYM(name), true, false), formal(primBoolean(), SYM(update), true, false), formal(primString(), SYM(comment), true, false), formal(primString(), SYM(mode), true, false));
-#line 108 "runfile.in"
+#line 111 "runfile.in"
addFunc(ve, run::gen_runfile5, primBoolean(), SYM(eof), formal(primFile(), SYM(f), false, false));
-#line 113 "runfile.in"
+#line 116 "runfile.in"
addFunc(ve, run::gen_runfile6, primBoolean(), SYM(eol), formal(primFile(), SYM(f), false, false));
-#line 118 "runfile.in"
+#line 121 "runfile.in"
addFunc(ve, run::gen_runfile7, primBoolean(), SYM(error), formal(primFile(), SYM(f), false, false));
-#line 123 "runfile.in"
+#line 126 "runfile.in"
addFunc(ve, run::gen_runfile8, primVoid(), SYM(clear), formal(primFile(), SYM(f), false, false));
-#line 128 "runfile.in"
+#line 131 "runfile.in"
addFunc(ve, run::gen_runfile9, primVoid(), SYM(close), formal(primFile(), SYM(f), false, false));
-#line 133 "runfile.in"
+#line 136 "runfile.in"
addFunc(ve, run::gen_runfile10, primInt(), SYM(precision), formal(primFile(), SYM(f), true, false), formal(primInt(), SYM(digits), true, false));
-#line 139 "runfile.in"
+#line 142 "runfile.in"
addFunc(ve, run::gen_runfile11, primVoid(), SYM(flush), formal(primFile(), SYM(f), false, false));
-#line 144 "runfile.in"
+#line 147 "runfile.in"
addFunc(ve, run::gen_runfile12, primString(), SYM(getc), formal(primFile(), SYM(f), false, false));
-#line 151 "runfile.in"
+#line 154 "runfile.in"
addFunc(ve, run::gen_runfile13, primInt(), SYM(tell), formal(primFile(), SYM(f), false, false));
-#line 156 "runfile.in"
+#line 159 "runfile.in"
addFunc(ve, run::gen_runfile14, primVoid(), SYM(seek), formal(primFile(), SYM(f), false, false), formal(primInt(), SYM(pos), false, false));
-#line 161 "runfile.in"
+#line 164 "runfile.in"
addFunc(ve, run::gen_runfile15, primVoid(), SYM(seekeof), formal(primFile(), SYM(f), false, false));
-#line 166 "runfile.in"
+#line 169 "runfile.in"
REGISTER_BLTIN(run::namePart,"namePart");
-#line 171 "runfile.in"
+#line 174 "runfile.in"
REGISTER_BLTIN(run::modePart,"modePart");
-#line 176 "runfile.in"
+#line 179 "runfile.in"
REGISTER_BLTIN(run::dimensionSetHelper,"dimensionSetHelper");
-#line 183 "runfile.in"
+#line 186 "runfile.in"
REGISTER_BLTIN(run::dimensionSet,"dimensionSet");
-#line 188 "runfile.in"
+#line 191 "runfile.in"
REGISTER_BLTIN(run::dimensionPart,"dimensionPart");
-#line 197 "runfile.in"
+#line 200 "runfile.in"
REGISTER_BLTIN(run::lineSetHelper,"lineSetHelper");
-#line 204 "runfile.in"
+#line 207 "runfile.in"
REGISTER_BLTIN(run::lineSet,"lineSet");
-#line 209 "runfile.in"
+#line 212 "runfile.in"
REGISTER_BLTIN(run::linePart,"linePart");
-#line 214 "runfile.in"
+#line 217 "runfile.in"
REGISTER_BLTIN(run::csvSetHelper,"csvSetHelper");
-#line 221 "runfile.in"
+#line 224 "runfile.in"
REGISTER_BLTIN(run::csvSet,"csvSet");
-#line 226 "runfile.in"
+#line 229 "runfile.in"
REGISTER_BLTIN(run::csvPart,"csvPart");
-#line 231 "runfile.in"
+#line 234 "runfile.in"
REGISTER_BLTIN(run::wordSetHelper,"wordSetHelper");
-#line 238 "runfile.in"
+#line 241 "runfile.in"
REGISTER_BLTIN(run::wordSet,"wordSet");
-#line 243 "runfile.in"
+#line 246 "runfile.in"
REGISTER_BLTIN(run::wordPart,"wordPart");
-#line 248 "runfile.in"
+#line 251 "runfile.in"
REGISTER_BLTIN(run::singlerealSetHelper,"singlerealSetHelper");
-#line 255 "runfile.in"
+#line 258 "runfile.in"
REGISTER_BLTIN(run::singlerealSet,"singlerealSet");
-#line 260 "runfile.in"
+#line 263 "runfile.in"
REGISTER_BLTIN(run::singlerealPart,"singlerealPart");
-#line 265 "runfile.in"
+#line 268 "runfile.in"
REGISTER_BLTIN(run::singleintSetHelper,"singleintSetHelper");
-#line 272 "runfile.in"
+#line 275 "runfile.in"
REGISTER_BLTIN(run::singleintSet,"singleintSet");
-#line 277 "runfile.in"
+#line 280 "runfile.in"
REGISTER_BLTIN(run::singleintPart,"singleintPart");
-#line 282 "runfile.in"
+#line 285 "runfile.in"
REGISTER_BLTIN(run::signedintSetHelper,"signedintSetHelper");
-#line 289 "runfile.in"
+#line 292 "runfile.in"
REGISTER_BLTIN(run::signedintSet,"signedintSet");
-#line 294 "runfile.in"
+#line 297 "runfile.in"
REGISTER_BLTIN(run::signedintPart,"signedintPart");
-#line 299 "runfile.in"
+#line 302 "runfile.in"
REGISTER_BLTIN(run::readSetHelper,"readSetHelper");
-#line 322 "runfile.in"
+#line 325 "runfile.in"
REGISTER_BLTIN(run::readSet,"readSet");
-#line 327 "runfile.in"
+#line 330 "runfile.in"
addFunc(ve, run::gen_runfile41, primInt(), SYM(delete), formal(primString(), SYM(s), false, false));
-#line 337 "runfile.in"
+#line 340 "runfile.in"
addFunc(ve, run::gen_runfile42, primInt(), SYM(rename), formal(primString(), SYM(from), false, false), formal(primString(), SYM(to), false, false));
-#line 348 "runfile.in"
+#line 351 "runfile.in"
addFunc(ve, run::gen_runfile43, primString(), SYM(mktemp), formal(primString(), SYM(s), false, false));
}
diff --git a/graphics/asymptote/runfile.in b/graphics/asymptote/runfile.in
index da08d523ef..1a6835b7b2 100644
--- a/graphics/asymptote/runfile.in
+++ b/graphics/asymptote/runfile.in
@@ -44,11 +44,14 @@ file* input(string name=emptystring, bool check=true,
string comment=commentchar, string mode=emptystring)
{
file *f=NULL;
- if(mode == "binary") {
+ if(mode == "binary")
f=new ibfile(name,check);
- } else if(mode == "xdr") {
+ else if(mode == "xdr" || mode == "xdrgz") {
#ifdef HAVE_RPC_RPC_H
- f=new ixfile(name,check);
+ if(mode == "xdr")
+ f=new ixfile(name,check);
+ else if(mode == "xdrgz")
+ f=new igzxfile(name,check);
#else
ostringstream buf;
buf << name << ": XDR read support not enabled";
@@ -56,7 +59,7 @@ file* input(string name=emptystring, bool check=true,
#endif
} else if(mode == "") {
char c=comment.empty() ? (char) 0 : comment[0];
- f=new ifile(name,c,check);
+ f=new camp::ifile(name,c,check);
} else {
f=NULL;
ostringstream buf;
diff --git a/graphics/asymptote/runlabel.cc b/graphics/asymptote/runlabel.cc
index 5781426305..7611a05eb9 100644
--- a/graphics/asymptote/runlabel.cc
+++ b/graphics/asymptote/runlabel.cc
@@ -188,7 +188,7 @@ array *readpath(const string& psname, bool keep,
PP->push(P);
while(!buf.eof()) {
- char c;
+ char c='>';
buf >> c;
if(c == '>') break;
diff --git a/graphics/asymptote/runlabel.in b/graphics/asymptote/runlabel.in
index 632f68df55..4a6a157d08 100644
--- a/graphics/asymptote/runlabel.in
+++ b/graphics/asymptote/runlabel.in
@@ -142,7 +142,7 @@ array *readpath(const string& psname, bool keep,
PP->push(P);
while(!buf.eof()) {
- char c;
+ char c='>';
buf >> c;
if(c == '>') break;
diff --git a/graphics/asymptote/runpicture.cc b/graphics/asymptote/runpicture.cc
index d2fe06bc26..a85946c710 100644
--- a/graphics/asymptote/runpicture.cc
+++ b/graphics/asymptote/runpicture.cc
@@ -722,12 +722,12 @@ void gen_runpicture42(stack *Stack)
picture *result=new picture;
unsigned level=0;
- picture::nodelist::iterator p;
xmap_t xmap=processData().xmap;
transform Tinv=inverse(T);
- for(p = f->nodes.begin(); p != f->nodes.end(); ++p) {
+ for(picture::nodelist::iterator p=f->nodes.begin(); p != f->nodes.end();
+ ++p) {
transform t=getTransform(xmap,p);
bool Delete=(t == ZeroTransform);
if(!Delete && !t.isIdentity()) t=T*t*Tinv;
@@ -758,12 +758,14 @@ void gen_runpicture42(stack *Stack)
group->append(e);
result->add(*group);
}
+ delete group;
}
result->shipout(preamble,prefix,format,wait,view);
+ delete result;
}
-#line 468 "runpicture.in"
+#line 470 "runpicture.in"
// void shipout3(string prefix, picture *f, string format=emptystring, real width, real height, real angle, real zoom, triple m, triple M, pair shift, pair margin, realarray2 *t, realarray *background, triplearray *lights, realarray2 *diffuse, realarray2 *specular, bool view=true);
void gen_runpicture43(stack *Stack)
{
@@ -784,7 +786,7 @@ void gen_runpicture43(stack *Stack)
string format=vm::pop<string>(Stack,emptystring);
picture * f=vm::pop<picture *>(Stack);
string prefix=vm::pop<string>(Stack);
-#line 473 "runpicture.in"
+#line 475 "runpicture.in"
size_t n=checkArrays(lights,diffuse);
checkEqual(n,checkArray(specular));
@@ -804,25 +806,26 @@ void gen_runpicture43(stack *Stack)
delete[] T;
}
-#line 493 "runpicture.in"
+#line 495 "runpicture.in"
// void shipout3(string prefix, picture *f, string format=defaultformat3);
void gen_runpicture44(stack *Stack)
{
string format=vm::pop<string>(Stack,defaultformat3);
picture * f=vm::pop<picture *>(Stack);
string prefix=vm::pop<string>(Stack);
-#line 494 "runpicture.in"
+#line 496 "runpicture.in"
f->shipout3(prefix,format);
}
-#line 498 "runpicture.in"
+#line 500 "runpicture.in"
// void xmap(string key, transform t=identity);
void gen_runpicture45(stack *Stack)
{
transform t=vm::pop<transform>(Stack,identity);
string key=vm::pop<string>(Stack);
-#line 499 "runpicture.in"
- xmap_t &xmap=processData().xmap;
+#line 501 "runpicture.in"
+ processDataStruct *P=&processData();
+ xmap_t &xmap=P->xmap;
xmap_t::iterator p=xmap.find(key);
if(p != xmap.end())
p->second.push_back(t);
@@ -831,17 +834,19 @@ void gen_runpicture45(stack *Stack)
v->push_back(t);
xmap[key]=*v;
}
+ P->xmapCount++;
}
-#line 511 "runpicture.in"
+#line 515 "runpicture.in"
// void deconstruct(picture *f, picture *preamble=NULL, transform T=identity);
void gen_runpicture46(stack *Stack)
{
transform T=vm::pop<transform>(Stack,identity);
picture * preamble=vm::pop<picture *>(Stack,NULL);
picture * f=vm::pop<picture *>(Stack);
-#line 512 "runpicture.in"
+#line 516 "runpicture.in"
unsigned level=0;
+ bool first=pdf(getSetting<string>("tex"));
string prefix=outname();
const string xformat="svg";
@@ -855,9 +860,9 @@ void gen_runpicture46(stack *Stack)
xmap_t xmap=processData().xmap;
transform Tinv=inverse(T);
- for(picture::nodelist::iterator p=f->nodes.begin();;) {
- if(p == f->nodes.end()) break;
+ picture *F=new picture(true);
+ for(picture::nodelist::iterator p=f->nodes.begin(); p != f->nodes.end();) {
picture *group=new picture;
transform t=getTransform(xmap,p);
bool Delete=(t == ZeroTransform);
@@ -892,6 +897,7 @@ void gen_runpicture46(stack *Stack)
}
}
}
+
if(p != f->nodes.end()) {
if(!Delete) {
drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
@@ -899,11 +905,19 @@ void gen_runpicture46(stack *Stack)
bbox b=group->bounds();
if(!b.empty && b.right > b.left && b.top > b.bottom) {
if((*p)->endclip()) clip=true;
- ostringstream buf;
- buf << prefix << "_" << arg;
- string outname=buildname(buf.str(),xformat);
- group->shipout(preamble,outname,xformat,false,false);
- fprintf(pipeout,"KEY=%s%d\n",e->KEY.c_str(),clip || f->havepng());
+
+ if(first)
+ first=false;
+ else
+ F->append(new drawNewPage(b));
+
+ F->append(new drawBBox(b));
+
+ for(picture::nodelist::iterator g=group->nodes.begin();
+ !(g == group->nodes.end()); ++g)
+ F->append(*g);
+
+ fprintf(pipeout,"KEY=%s%d\n",e->KEY.c_str(),clip);
const char *oldlocale=setlocale(LC_NUMERIC,NULL);
bool override=oldlocale && strcmp(oldlocale,"C") != 0;
@@ -922,20 +936,29 @@ void gen_runpicture46(stack *Stack)
fflush(pipeout);
++arg;
}
+ } else {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ fprintf(pipeout,"KEY=%s2\n",e->KEY.c_str());
+ fprintf(pipeout,"0 0 0 0\n");
}
+
++p;
}
+ delete group;
}
+ string outname=buildname(prefix,xformat);
+ F->shipout(preamble,outname,xformat,false,false);
fprintf(pipeout,"%s\n",Done.c_str());
fflush(pipeout);
+ delete F;
}
// Three-dimensional picture and surface operations
// Bezier curve
-#line 607 "runpicture.in"
+#line 630 "runpicture.in"
// void _draw(picture *f, path3 g, triple center=Zero, penarray *p, real opacity, real shininess, real metallic, real fresnel0, Int interaction=0);
void gen_runpicture47(stack *Stack)
{
@@ -948,7 +971,7 @@ void gen_runpicture47(stack *Stack)
triple center=vm::pop<triple>(Stack,Zero);
path3 g=vm::pop<path3>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 610 "runpicture.in"
+#line 633 "runpicture.in"
size_t n=g.size();
for(unsigned int i=0; i < n; ++i)
f->append(new drawPath3(g.subpath((Int) i,Int(i+1)),center,*p,opacity,
@@ -957,7 +980,7 @@ void gen_runpicture47(stack *Stack)
}
// Bezier patch
-#line 619 "runpicture.in"
+#line 642 "runpicture.in"
// void draw(picture *f, triplearray2 *P, triple center, bool straight, penarray *p, real opacity, real shininess, real metallic, real fresnel0, penarray *colors, Int interaction, Int digits, bool primitive=false);
void gen_runpicture48(stack *Stack)
{
@@ -974,7 +997,7 @@ void gen_runpicture48(stack *Stack)
triple center=vm::pop<triple>(Stack);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 623 "runpicture.in"
+#line 646 "runpicture.in"
f->append(new drawBezierPatch(*P,center,straight,*p,opacity,shininess,
metallic,fresnel0,*colors,
(Interaction) intcast(interaction),
@@ -982,7 +1005,7 @@ void gen_runpicture48(stack *Stack)
}
// Bezier triangle
-#line 631 "runpicture.in"
+#line 654 "runpicture.in"
// void drawbeziertriangle(picture *f, triplearray2 *P, triple center, bool straight, penarray *p, real opacity, real shininess, real metallic, real fresnel0, penarray *colors, Int interaction, Int digits, bool primitive=false);
void gen_runpicture49(stack *Stack)
{
@@ -999,7 +1022,7 @@ void gen_runpicture49(stack *Stack)
triple center=vm::pop<triple>(Stack);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 636 "runpicture.in"
+#line 659 "runpicture.in"
f->append(new drawBezierTriangle(*P,center,straight,*p,opacity,shininess,
metallic,fresnel0,*colors,
(Interaction) intcast(interaction),
@@ -1007,7 +1030,7 @@ void gen_runpicture49(stack *Stack)
}
// General NURBS curve
-#line 644 "runpicture.in"
+#line 667 "runpicture.in"
// void draw(picture *f, triplearray *P, realarray *knot, realarray *weights=emptyarray, pen p);
void gen_runpicture50(stack *Stack)
{
@@ -1016,12 +1039,12 @@ void gen_runpicture50(stack *Stack)
realarray * knot=vm::pop<realarray *>(Stack);
triplearray * P=vm::pop<triplearray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 646 "runpicture.in"
+#line 669 "runpicture.in"
f->append(new drawNurbsPath3(*P,knot,weights,p));
}
// General NURBS surface
-#line 651 "runpicture.in"
+#line 674 "runpicture.in"
// void draw(picture *f, triplearray2 *P, realarray *uknot, realarray *vknot, realarray2 *weights=emptyarray, penarray *p, real opacity, real shininess,real metallic, real fresnel0, penarray *colors);
void gen_runpicture51(stack *Stack)
{
@@ -1036,13 +1059,13 @@ void gen_runpicture51(stack *Stack)
realarray * uknot=vm::pop<realarray *>(Stack);
triplearray2 * P=vm::pop<triplearray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 654 "runpicture.in"
+#line 677 "runpicture.in"
f->append(new drawNurbs(*P,uknot,vknot,weights,*p,opacity,shininess,
metallic,fresnel0,*colors));
}
// Sphere primitive
-#line 660 "runpicture.in"
+#line 683 "runpicture.in"
// void drawSphere(picture *f, realarray2 *t, bool half=false, penarray *p, real opacity, real shininess, real metallic, real fresnel0, Int type);
void gen_runpicture52(stack *Stack)
{
@@ -1055,13 +1078,13 @@ void gen_runpicture52(stack *Stack)
bool half=vm::pop<bool>(Stack,false);
realarray2 * t=vm::pop<realarray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 663 "runpicture.in"
+#line 686 "runpicture.in"
f->append(new drawSphere(*t,half,*p,opacity,shininess,metallic,fresnel0,
intcast(type)));
}
// Cylinder primitive
-#line 669 "runpicture.in"
+#line 692 "runpicture.in"
// void drawCylinder(picture *f, realarray2 *t, penarray *p, real opacity, real shininess, real metallic, real fresnel0, bool core=false);
void gen_runpicture53(stack *Stack)
{
@@ -1073,12 +1096,12 @@ void gen_runpicture53(stack *Stack)
penarray * p=vm::pop<penarray *>(Stack);
realarray2 * t=vm::pop<realarray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 672 "runpicture.in"
+#line 695 "runpicture.in"
f->append(new drawCylinder(*t,*p,opacity,shininess,metallic,fresnel0,core));
}
// Disk primitive
-#line 677 "runpicture.in"
+#line 700 "runpicture.in"
// void drawDisk(picture *f, realarray2 *t, penarray *p, real opacity, real shininess, real metallic, real fresnel0);
void gen_runpicture54(stack *Stack)
{
@@ -1089,12 +1112,12 @@ void gen_runpicture54(stack *Stack)
penarray * p=vm::pop<penarray *>(Stack);
realarray2 * t=vm::pop<realarray2 *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 679 "runpicture.in"
+#line 702 "runpicture.in"
f->append(new drawDisk(*t,*p,opacity,shininess,metallic,fresnel0));
}
// Tube primitive
-#line 684 "runpicture.in"
+#line 707 "runpicture.in"
// void drawTube(picture *f, triplearray *g, real width, penarray *p, real opacity, real shininess, real metallic, real fresnel0, triple min, triple max, bool core=false);
void gen_runpicture55(stack *Stack)
{
@@ -1109,13 +1132,13 @@ void gen_runpicture55(stack *Stack)
real width=vm::pop<real>(Stack);
triplearray * g=vm::pop<triplearray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 687 "runpicture.in"
+#line 710 "runpicture.in"
f->append(new drawTube(*g,width,*p,opacity,shininess,metallic,fresnel0,
min,max,core));
}
// Draw pixel
-#line 693 "runpicture.in"
+#line 716 "runpicture.in"
// void drawpixel(picture *f, triple v, pen p, real width=1.0);
void gen_runpicture56(stack *Stack)
{
@@ -1123,15 +1146,16 @@ void gen_runpicture56(stack *Stack)
pen p=vm::pop<pen>(Stack);
triple v=vm::pop<triple>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 694 "runpicture.in"
+#line 717 "runpicture.in"
f->append(new drawPixel(v,p,width));
}
// Draw triangles
-#line 699 "runpicture.in"
-// void draw(picture *f, triplearray *v, Intarray2 *vi, triplearray *n, Intarray2 *ni, penarray *p, real opacity, real shininess, real metallic, real fresnel0, penarray *c=emptyarray, Intarray2 *ci=emptyarray);
+#line 722 "runpicture.in"
+// void draw(picture *f, triplearray *v, Intarray2 *vi, triple center=Zero, triplearray *n, Intarray2 *ni, penarray *p, real opacity, real shininess, real metallic, real fresnel0, penarray *c=emptyarray, Intarray2 *ci=emptyarray, Int interaction);
void gen_runpicture57(stack *Stack)
{
+ Int interaction=vm::pop<Int>(Stack);
Intarray2 * ci=vm::pop<Intarray2 *>(Stack,emptyarray);
penarray * c=vm::pop<penarray *>(Stack,emptyarray);
real fresnel0=vm::pop<real>(Stack);
@@ -1141,66 +1165,68 @@ void gen_runpicture57(stack *Stack)
penarray * p=vm::pop<penarray *>(Stack);
Intarray2 * ni=vm::pop<Intarray2 *>(Stack);
triplearray * n=vm::pop<triplearray *>(Stack);
+ triple center=vm::pop<triple>(Stack,Zero);
Intarray2 * vi=vm::pop<Intarray2 *>(Stack);
triplearray * v=vm::pop<triplearray *>(Stack);
picture * f=vm::pop<picture *>(Stack);
-#line 704 "runpicture.in"
- f->append(new drawTriangles(*v,*vi,*n,*ni,*p,opacity,shininess,metallic,
- fresnel0,*c,*ci));
+#line 727 "runpicture.in"
+ f->append(new drawTriangles(*v,*vi,center,*n,*ni,*p,opacity,shininess,
+ metallic,fresnel0,*c,*ci,
+ (Interaction) intcast(interaction)));
}
-#line 709 "runpicture.in"
+#line 733 "runpicture.in"
// triple min3(picture *f);
void gen_runpicture58(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 710 "runpicture.in"
+#line 734 "runpicture.in"
{Stack->push<triple>(f->bounds3().Min()); return;}
}
-#line 714 "runpicture.in"
+#line 738 "runpicture.in"
// triple max3(picture *f);
void gen_runpicture59(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 715 "runpicture.in"
+#line 739 "runpicture.in"
{Stack->push<triple>(f->bounds3().Max()); return;}
}
-#line 719 "runpicture.in"
+#line 743 "runpicture.in"
// triple size3(picture *f);
void gen_runpicture60(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 720 "runpicture.in"
+#line 744 "runpicture.in"
bbox3 b=f->bounds3();
{Stack->push<triple>(b.Max()-b.Min()); return;}
}
-#line 725 "runpicture.in"
+#line 749 "runpicture.in"
// pair minratio(picture *f);
void gen_runpicture61(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 726 "runpicture.in"
+#line 750 "runpicture.in"
{Stack->push<pair>(f->ratio(::min)); return;}
}
-#line 730 "runpicture.in"
+#line 754 "runpicture.in"
// pair maxratio(picture *f);
void gen_runpicture62(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 731 "runpicture.in"
+#line 755 "runpicture.in"
{Stack->push<pair>(f->ratio(::max)); return;}
}
-#line 735 "runpicture.in"
+#line 759 "runpicture.in"
// bool is3D(picture *f);
void gen_runpicture63(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
-#line 736 "runpicture.in"
+#line 760 "runpicture.in"
{Stack->push<bool>(f->have3D()); return;}
}
@@ -1296,47 +1322,47 @@ void gen_runpicture_venv(venv &ve)
addFunc(ve, run::gen_runpicture41, primBoolean(), SYM(pdf));
#line 419 "runpicture.in"
addFunc(ve, run::gen_runpicture42, primVoid(), SYM(_shipout), formal(primString(), SYM(prefix), true, false), formal(primPicture(), SYM(f), false, false), formal(primPicture(), SYM(preamble), true, false), formal(primString(), SYM(format), true, false), formal(primBoolean(), SYM(wait), true, false), formal(primBoolean(), SYM(view), true, false), formal(primTransform(), SYM(t), true, false));
-#line 468 "runpicture.in"
+#line 470 "runpicture.in"
addFunc(ve, run::gen_runpicture43, primVoid(), SYM(shipout3), formal(primString(), SYM(prefix), false, false), formal(primPicture(), SYM(f), false, false), formal(primString(), SYM(format), true, false), formal(primReal(), SYM(width), false, false), formal(primReal(), SYM(height), false, false), formal(primReal(), SYM(angle), false, false), formal(primReal(), SYM(zoom), false, false), formal(primTriple(), SYM(m), false, false), formal(primTriple(), SYM(m), false, false), formal(primPair(), SYM(shift), false, false), formal(primPair(), SYM(margin), false, false), formal(realArray2(), SYM(t), false, false), formal(realArray(), SYM(background), false, false), formal(tripleArray(), SYM(lights), false, false), formal(realArray2(), SYM(diffuse), false, false), formal(realArray2(), SYM(specular), false, false), formal(primBoolean(), SYM(view), true, false));
-#line 493 "runpicture.in"
+#line 495 "runpicture.in"
addFunc(ve, run::gen_runpicture44, primVoid(), SYM(shipout3), formal(primString(), SYM(prefix), false, false), formal(primPicture(), SYM(f), false, false), formal(primString(), SYM(format), true, false));
-#line 498 "runpicture.in"
+#line 500 "runpicture.in"
addFunc(ve, run::gen_runpicture45, primVoid(), SYM(xmap), formal(primString(), SYM(key), false, false), formal(primTransform(), SYM(t), true, false));
-#line 511 "runpicture.in"
+#line 515 "runpicture.in"
addFunc(ve, run::gen_runpicture46, primVoid(), SYM(deconstruct), formal(primPicture(), SYM(f), false, false), formal(primPicture(), SYM(preamble), true, false), formal(primTransform(), SYM(t), true, false));
-#line 603 "runpicture.in"
+#line 626 "runpicture.in"
addFunc(ve, run::gen_runpicture47, primVoid(), SYM(_draw), formal(primPicture(), SYM(f), false, false), formal(primPath3(), SYM(g), false, false), formal(primTriple(), SYM(center), true, false), formal(penArray(), SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primInt(), SYM(interaction), true, false));
-#line 618 "runpicture.in"
+#line 641 "runpicture.in"
addFunc(ve, run::gen_runpicture48, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(center), false, false), formal(primBoolean(), SYM(straight), false, false), formal(penArray(), SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(penArray(), SYM(colors), false, false), formal(primInt(), SYM(interaction), false, false), formal(primInt(), SYM(digits), false, false), formal(primBoolean(), SYM(primitive), true, false));
-#line 630 "runpicture.in"
+#line 653 "runpicture.in"
addFunc(ve, run::gen_runpicture49, primVoid(), SYM(drawbeziertriangle), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(primTriple(), SYM(center), false, false), formal(primBoolean(), SYM(straight), false, false), formal(penArray(), SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(penArray(), SYM(colors), false, false), formal(primInt(), SYM(interaction), false, false), formal(primInt(), SYM(digits), false, false), formal(primBoolean(), SYM(primitive), true, false));
-#line 643 "runpicture.in"
+#line 666 "runpicture.in"
addFunc(ve, run::gen_runpicture50, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray(), SYM(p), false, false), formal(realArray(), SYM(knot), false, false), formal(realArray(), SYM(weights), true, false), formal(primPen(), SYM(p), false, false));
-#line 650 "runpicture.in"
+#line 673 "runpicture.in"
addFunc(ve, run::gen_runpicture51, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray2(), SYM(p), false, false), formal(realArray(), SYM(uknot), false, false), formal(realArray(), SYM(vknot), false, false), formal(realArray2(), SYM(weights), true, false), formal(penArray(), SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(penArray(), SYM(colors), false, false));
-#line 659 "runpicture.in"
+#line 682 "runpicture.in"
addFunc(ve, run::gen_runpicture52, primVoid(), SYM(drawSphere), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(primBoolean(), SYM(half), true, false), formal(penArray(), SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primInt(), SYM(type), false, false));
-#line 668 "runpicture.in"
+#line 691 "runpicture.in"
addFunc(ve, run::gen_runpicture53, primVoid(), SYM(drawCylinder), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(penArray(), SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primBoolean(), SYM(core), true, false));
-#line 676 "runpicture.in"
+#line 699 "runpicture.in"
addFunc(ve, run::gen_runpicture54, primVoid(), SYM(drawDisk), formal(primPicture(), SYM(f), false, false), formal(realArray2(), SYM(t), false, false), formal(penArray(), SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false));
-#line 683 "runpicture.in"
+#line 706 "runpicture.in"
addFunc(ve, run::gen_runpicture55, primVoid(), SYM(drawTube), formal(primPicture(), SYM(f), false, false), formal(tripleArray(), SYM(g), false, false), formal(primReal(), SYM(width), false, false), formal(penArray(), SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(primTriple(), SYM(min), false, false), formal(primTriple(), SYM(max), false, false), formal(primBoolean(), SYM(core), true, false));
-#line 692 "runpicture.in"
+#line 715 "runpicture.in"
addFunc(ve, run::gen_runpicture56, primVoid(), SYM(drawpixel), formal(primPicture(), SYM(f), false, false), formal(primTriple(), SYM(v), false, false), formal(primPen(), SYM(p), false, false), formal(primReal(), SYM(width), true, false));
-#line 698 "runpicture.in"
- addFunc(ve, run::gen_runpicture57, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray(), SYM(v), false, false), formal(IntArray2(), SYM(vi), false, false), formal(tripleArray(), SYM(n), false, false), formal(IntArray2(), SYM(ni), false, false), formal(penArray(), SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(penArray(), SYM(c), true, false), formal(IntArray2(), SYM(ci), true, false));
-#line 709 "runpicture.in"
+#line 721 "runpicture.in"
+ addFunc(ve, run::gen_runpicture57, primVoid(), SYM(draw), formal(primPicture(), SYM(f), false, false), formal(tripleArray(), SYM(v), false, false), formal(IntArray2(), SYM(vi), false, false), formal(primTriple(), SYM(center), true, false), formal(tripleArray(), SYM(n), false, false), formal(IntArray2(), SYM(ni), false, false), formal(penArray(), SYM(p), false, false), formal(primReal(), SYM(opacity), false, false), formal(primReal(), SYM(shininess), false, false), formal(primReal(), SYM(metallic), false, false), formal(primReal(), SYM(fresnel0), false, false), formal(penArray(), SYM(c), true, false), formal(IntArray2(), SYM(ci), true, false), formal(primInt(), SYM(interaction), false, false));
+#line 733 "runpicture.in"
addFunc(ve, run::gen_runpicture58, primTriple(), SYM(min3), formal(primPicture(), SYM(f), false, false));
-#line 714 "runpicture.in"
+#line 738 "runpicture.in"
addFunc(ve, run::gen_runpicture59, primTriple(), SYM(max3), formal(primPicture(), SYM(f), false, false));
-#line 719 "runpicture.in"
+#line 743 "runpicture.in"
addFunc(ve, run::gen_runpicture60, primTriple(), SYM(size3), formal(primPicture(), SYM(f), false, false));
-#line 725 "runpicture.in"
+#line 749 "runpicture.in"
addFunc(ve, run::gen_runpicture61, primPair(), SYM(minratio), formal(primPicture(), SYM(f), false, false));
-#line 730 "runpicture.in"
+#line 754 "runpicture.in"
addFunc(ve, run::gen_runpicture62, primPair(), SYM(maxratio), formal(primPicture(), SYM(f), false, false));
-#line 735 "runpicture.in"
+#line 759 "runpicture.in"
addFunc(ve, run::gen_runpicture63, primBoolean(), SYM(is3D), formal(primPicture(), SYM(f), false, false));
}
diff --git a/graphics/asymptote/runpicture.in b/graphics/asymptote/runpicture.in
index ac5bdbc28e..e782d2ed77 100644
--- a/graphics/asymptote/runpicture.in
+++ b/graphics/asymptote/runpicture.in
@@ -424,12 +424,12 @@ void _shipout(string prefix=emptystring, picture *f, picture *preamble=NULL,
picture *result=new picture;
unsigned level=0;
- picture::nodelist::iterator p;
xmap_t xmap=processData().xmap;
transform Tinv=inverse(T);
- for(p = f->nodes.begin(); p != f->nodes.end(); ++p) {
+ for(picture::nodelist::iterator p=f->nodes.begin(); p != f->nodes.end();
+ ++p) {
transform t=getTransform(xmap,p);
bool Delete=(t == ZeroTransform);
if(!Delete && !t.isIdentity()) t=T*t*Tinv;
@@ -460,9 +460,11 @@ void _shipout(string prefix=emptystring, picture *f, picture *preamble=NULL,
group->append(e);
result->add(*group);
}
+ delete group;
}
result->shipout(preamble,prefix,format,wait,view);
+ delete result;
}
void shipout3(string prefix, picture *f, string format=emptystring,
@@ -497,7 +499,8 @@ void shipout3(string prefix, picture *f, string format=defaultformat3)
void xmap(string key, transform t=identity)
{
- xmap_t &xmap=processData().xmap;
+ processDataStruct *P=&processData();
+ xmap_t &xmap=P->xmap;
xmap_t::iterator p=xmap.find(key);
if(p != xmap.end())
p->second.push_back(t);
@@ -506,11 +509,13 @@ void xmap(string key, transform t=identity)
v->push_back(t);
xmap[key]=*v;
}
+ P->xmapCount++;
}
void deconstruct(picture *f, picture *preamble=NULL, transform T=identity)
{
unsigned level=0;
+ bool first=pdf(getSetting<string>("tex"));
string prefix=outname();
const string xformat="svg";
@@ -524,9 +529,9 @@ void deconstruct(picture *f, picture *preamble=NULL, transform T=identity)
xmap_t xmap=processData().xmap;
transform Tinv=inverse(T);
- for(picture::nodelist::iterator p=f->nodes.begin();;) {
- if(p == f->nodes.end()) break;
+ picture *F=new picture(true);
+ for(picture::nodelist::iterator p=f->nodes.begin(); p != f->nodes.end();) {
picture *group=new picture;
transform t=getTransform(xmap,p);
bool Delete=(t == ZeroTransform);
@@ -561,6 +566,7 @@ void deconstruct(picture *f, picture *preamble=NULL, transform T=identity)
}
}
}
+
if(p != f->nodes.end()) {
if(!Delete) {
drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
@@ -568,11 +574,19 @@ void deconstruct(picture *f, picture *preamble=NULL, transform T=identity)
bbox b=group->bounds();
if(!b.empty && b.right > b.left && b.top > b.bottom) {
if((*p)->endclip()) clip=true;
- ostringstream buf;
- buf << prefix << "_" << arg;
- string outname=buildname(buf.str(),xformat);
- group->shipout(preamble,outname,xformat,false,false);
- fprintf(pipeout,"KEY=%s%d\n",e->KEY.c_str(),clip || f->havepng());
+
+ if(first)
+ first=false;
+ else
+ F->append(new drawNewPage(b));
+
+ F->append(new drawBBox(b));
+
+ for(picture::nodelist::iterator g=group->nodes.begin();
+ !(g == group->nodes.end()); ++g)
+ F->append(*g);
+
+ fprintf(pipeout,"KEY=%s%d\n",e->KEY.c_str(),clip);
const char *oldlocale=setlocale(LC_NUMERIC,NULL);
bool override=oldlocale && strcmp(oldlocale,"C") != 0;
@@ -591,13 +605,22 @@ void deconstruct(picture *f, picture *preamble=NULL, transform T=identity)
fflush(pipeout);
++arg;
}
+ } else {
+ drawElement *e=t.isIdentity() ? *p : (*p)->transformed(t);
+ fprintf(pipeout,"KEY=%s2\n",e->KEY.c_str());
+ fprintf(pipeout,"0 0 0 0\n");
}
+
++p;
}
+ delete group;
}
+ string outname=buildname(prefix,xformat);
+ F->shipout(preamble,outname,xformat,false,false);
fprintf(pipeout,"%s\n",Done.c_str());
fflush(pipeout);
+ delete F;
}
@@ -696,14 +719,15 @@ void drawpixel(picture *f, triple v, pen p, real width=1.0)
}
// Draw triangles
-void draw(picture *f, triplearray *v, Intarray2 *vi,
+void draw(picture *f, triplearray *v, Intarray2 *vi, triple center=Zero,
triplearray *n, Intarray2 *ni,
penarray *p, real opacity, real shininess,
real metallic, real fresnel0,
- penarray *c=emptyarray, Intarray2 *ci=emptyarray)
+ penarray *c=emptyarray, Intarray2 *ci=emptyarray, Int interaction)
{
- f->append(new drawTriangles(*v,*vi,*n,*ni,*p,opacity,shininess,metallic,
- fresnel0,*c,*ci));
+ f->append(new drawTriangles(*v,*vi,center,*n,*ni,*p,opacity,shininess,
+ metallic,fresnel0,*c,*ci,
+ (Interaction) intcast(interaction)));
}
triple min3(picture *f)
diff --git a/graphics/asymptote/runtime.cc b/graphics/asymptote/runtime.cc
index 40f52a54bd..5b6e9ea730 100644
--- a/graphics/asymptote/runtime.cc
+++ b/graphics/asymptote/runtime.cc
@@ -224,7 +224,8 @@ void writestring(stack *s)
}
}
-string toplocation() {
+string toplocation()
+{
ostringstream buf;
position& topPos=processData().topPos;
buf << topPos.Line() << "." << topPos.Column();
@@ -253,54 +254,54 @@ void unused(void *)
namespace run {
// Initializers
-#line 225 "runtime.in"
+#line 226 "runtime.in"
void IntZero(stack *Stack)
{
-#line 226 "runtime.in"
+#line 227 "runtime.in"
{Stack->push<Int>(0); return;}
}
-#line 231 "runtime.in"
+#line 232 "runtime.in"
void realZero(stack *Stack)
{
-#line 232 "runtime.in"
+#line 233 "runtime.in"
{Stack->push<real>(0.0); return;}
}
-#line 236 "runtime.in"
+#line 237 "runtime.in"
void boolFalse(stack *Stack)
{
-#line 237 "runtime.in"
+#line 238 "runtime.in"
{Stack->push<bool>(false); return;}
}
-#line 241 "runtime.in"
+#line 242 "runtime.in"
// bool isnan(real x);
void gen_runtime3(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 242 "runtime.in"
+#line 243 "runtime.in"
{Stack->push<bool>(std::isnan(x)); return;}
}
-#line 246 "runtime.in"
+#line 247 "runtime.in"
void pushNullArray(stack *Stack)
{
-#line 247 "runtime.in"
+#line 248 "runtime.in"
{Stack->push<array*>(0); return;}
}
-#line 251 "runtime.in"
+#line 252 "runtime.in"
void pushNullRecord(stack *Stack)
{
-#line 252 "runtime.in"
+#line 253 "runtime.in"
{Stack->push<frame*>(0); return;}
}
-#line 256 "runtime.in"
+#line 257 "runtime.in"
void pushNullFunction(stack *Stack)
{
-#line 257 "runtime.in"
+#line 258 "runtime.in"
{Stack->push(nullfunc::instance()); return;}
}
@@ -309,222 +310,222 @@ void pushNullFunction(stack *Stack)
// Put the default value token on the stack (in place of an argument when
// making a function call).
-#line 266 "runtime.in"
+#line 267 "runtime.in"
void pushDefault(stack *Stack)
{
-#line 267 "runtime.in"
+#line 268 "runtime.in"
{Stack->push(Default); return;}
}
// Test if the value on the stack is the default value token.
-#line 273 "runtime.in"
+#line 274 "runtime.in"
void isDefault(stack *Stack)
{
item i=vm::pop(Stack);
-#line 274 "runtime.in"
+#line 275 "runtime.in"
{Stack->push<bool>(isdefault(i)); return;}
}
// Casts
-#line 280 "runtime.in"
+#line 281 "runtime.in"
void pairToGuide(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 281 "runtime.in"
+#line 282 "runtime.in"
{Stack->push<guide*>(new pairguide(z)); return;}
}
-#line 286 "runtime.in"
+#line 287 "runtime.in"
void pathToGuide(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 287 "runtime.in"
+#line 288 "runtime.in"
{Stack->push<guide*>(new pathguide(p)); return;}
}
-#line 291 "runtime.in"
+#line 292 "runtime.in"
void guideToPath(stack *Stack)
{
guide * g=vm::pop<guide *>(Stack);
-#line 292 "runtime.in"
+#line 293 "runtime.in"
{Stack->push<path>(g->solve()); return;}
}
// Pen operations
-#line 298 "runtime.in"
+#line 299 "runtime.in"
void newPen(stack *Stack)
{
-#line 299 "runtime.in"
+#line 300 "runtime.in"
{Stack->push<pen>(pen()); return;}
}
-#line 304 "runtime.in"
+#line 305 "runtime.in"
// bool ==(pen a, pen b);
void gen_runtime13(stack *Stack)
{
pen b=vm::pop<pen>(Stack);
pen a=vm::pop<pen>(Stack);
-#line 305 "runtime.in"
+#line 306 "runtime.in"
{Stack->push<bool>(a == b); return;}
}
-#line 309 "runtime.in"
+#line 310 "runtime.in"
// bool !=(pen a, pen b);
void gen_runtime14(stack *Stack)
{
pen b=vm::pop<pen>(Stack);
pen a=vm::pop<pen>(Stack);
-#line 310 "runtime.in"
+#line 311 "runtime.in"
{Stack->push<bool>(a != b); return;}
}
-#line 314 "runtime.in"
+#line 315 "runtime.in"
// pen +(pen a, pen b);
void gen_runtime15(stack *Stack)
{
pen b=vm::pop<pen>(Stack);
pen a=vm::pop<pen>(Stack);
-#line 315 "runtime.in"
+#line 316 "runtime.in"
{Stack->push<pen>(a+b); return;}
}
-#line 319 "runtime.in"
+#line 320 "runtime.in"
// pen *(real a, pen b);
void gen_runtime16(stack *Stack)
{
pen b=vm::pop<pen>(Stack);
real a=vm::pop<real>(Stack);
-#line 320 "runtime.in"
+#line 321 "runtime.in"
{Stack->push<pen>(a*b); return;}
}
-#line 324 "runtime.in"
+#line 325 "runtime.in"
// pen *(pen a, real b);
void gen_runtime17(stack *Stack)
{
real b=vm::pop<real>(Stack);
pen a=vm::pop<pen>(Stack);
-#line 325 "runtime.in"
+#line 326 "runtime.in"
{Stack->push<pen>(b*a); return;}
}
-#line 329 "runtime.in"
+#line 330 "runtime.in"
// pair max(pen p);
void gen_runtime18(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 330 "runtime.in"
+#line 331 "runtime.in"
{Stack->push<pair>(p.bounds().Max()); return;}
}
-#line 334 "runtime.in"
+#line 335 "runtime.in"
// pair min(pen p);
void gen_runtime19(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 335 "runtime.in"
+#line 336 "runtime.in"
{Stack->push<pair>(p.bounds().Min()); return;}
}
// Reset the meaning of pen default attributes.
-#line 340 "runtime.in"
+#line 341 "runtime.in"
// void resetdefaultpen();
void gen_runtime20(stack *)
{
-#line 341 "runtime.in"
+#line 342 "runtime.in"
processData().defaultpen=camp::pen::initialpen();
}
-#line 345 "runtime.in"
+#line 346 "runtime.in"
// void defaultpen(pen p);
void gen_runtime21(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 346 "runtime.in"
+#line 347 "runtime.in"
processData().defaultpen=pen(resolvepen,p);
}
-#line 350 "runtime.in"
+#line 351 "runtime.in"
// pen defaultpen();
void gen_runtime22(stack *Stack)
{
-#line 351 "runtime.in"
+#line 352 "runtime.in"
{Stack->push<pen>(processData().defaultpen); return;}
}
-#line 355 "runtime.in"
+#line 356 "runtime.in"
// bool invisible(pen p);
void gen_runtime23(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 356 "runtime.in"
+#line 357 "runtime.in"
{Stack->push<bool>(p.invisible()); return;}
}
-#line 360 "runtime.in"
+#line 361 "runtime.in"
// pen invisible();
void gen_runtime24(stack *Stack)
{
-#line 361 "runtime.in"
+#line 362 "runtime.in"
{Stack->push<pen>(pen(invisiblepen)); return;}
}
-#line 365 "runtime.in"
+#line 366 "runtime.in"
// pen gray(pen p);
void gen_runtime25(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 366 "runtime.in"
+#line 367 "runtime.in"
p.togrey();
{Stack->push<pen>(p); return;}
}
-#line 371 "runtime.in"
+#line 372 "runtime.in"
// pen rgb(pen p);
void gen_runtime26(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 372 "runtime.in"
+#line 373 "runtime.in"
p.torgb();
{Stack->push<pen>(p); return;}
}
-#line 377 "runtime.in"
+#line 378 "runtime.in"
// pen cmyk(pen p);
void gen_runtime27(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 378 "runtime.in"
+#line 379 "runtime.in"
p.tocmyk();
{Stack->push<pen>(p); return;}
}
-#line 383 "runtime.in"
+#line 384 "runtime.in"
// pen interp(pen a, pen b, real t);
void gen_runtime28(stack *Stack)
{
real t=vm::pop<real>(Stack);
pen b=vm::pop<pen>(Stack);
pen a=vm::pop<pen>(Stack);
-#line 384 "runtime.in"
+#line 385 "runtime.in"
{Stack->push<pen>(interpolate(a,b,t)); return;}
}
-#line 388 "runtime.in"
+#line 389 "runtime.in"
// pen rgb(real r, real g, real b);
void gen_runtime29(stack *Stack)
{
real b=vm::pop<real>(Stack);
real g=vm::pop<real>(Stack);
real r=vm::pop<real>(Stack);
-#line 389 "runtime.in"
+#line 390 "runtime.in"
{Stack->push<pen>(pen(r,g,b)); return;}
}
-#line 393 "runtime.in"
+#line 394 "runtime.in"
// pen cmyk(real c, real m, real y, real k);
void gen_runtime30(stack *Stack)
{
@@ -532,25 +533,25 @@ void gen_runtime30(stack *Stack)
real y=vm::pop<real>(Stack);
real m=vm::pop<real>(Stack);
real c=vm::pop<real>(Stack);
-#line 394 "runtime.in"
+#line 395 "runtime.in"
{Stack->push<pen>(pen(c,m,y,k)); return;}
}
-#line 398 "runtime.in"
+#line 399 "runtime.in"
// pen gray(real gray);
void gen_runtime31(stack *Stack)
{
real gray=vm::pop<real>(Stack);
-#line 399 "runtime.in"
+#line 400 "runtime.in"
{Stack->push<pen>(pen(gray)); return;}
}
-#line 403 "runtime.in"
+#line 404 "runtime.in"
// realarray* colors(pen p);
void gen_runtime32(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 404 "runtime.in"
+#line 405 "runtime.in"
size_t n=ColorComponents[p.colorspace()];
array *a=new array(n);
@@ -577,78 +578,87 @@ void gen_runtime32(stack *Stack)
{Stack->push<realarray*>(a); return;}
}
-#line 431 "runtime.in"
+#line 432 "runtime.in"
// string hex(pen p);
void gen_runtime33(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 432 "runtime.in"
+#line 433 "runtime.in"
{Stack->push<string>(p.hex()); return;}
}
-#line 436 "runtime.in"
+#line 437 "runtime.in"
// Int byte(real x);
void gen_runtime34(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 437 "runtime.in"
+#line 438 "runtime.in"
{Stack->push<Int>(camp::byte(x)); return;}
}
-#line 441 "runtime.in"
-// string colorspace(pen p);
+#line 442 "runtime.in"
+// real byteinv(Int x);
void gen_runtime35(stack *Stack)
{
+ Int x=vm::pop<Int>(Stack);
+#line 443 "runtime.in"
+ {Stack->push<real>(x >= 0 ? camp::byteinv(x) : 0.0); return;}
+}
+
+#line 447 "runtime.in"
+// string colorspace(pen p);
+void gen_runtime36(stack *Stack)
+{
pen p=vm::pop<pen>(Stack);
-#line 442 "runtime.in"
+#line 448 "runtime.in"
string s=ColorDeviceSuffix[p.colorspace()];
std::transform(s.begin(),s.end(),s.begin(),tolower);
{Stack->push<string>(s); return;}
}
-#line 448 "runtime.in"
+#line 454 "runtime.in"
// pen pattern(string *s);
-void gen_runtime36(stack *Stack)
+void gen_runtime37(stack *Stack)
{
string * s=vm::pop<string *>(Stack);
-#line 449 "runtime.in"
+#line 455 "runtime.in"
{Stack->push<pen>(pen(setpattern,*s)); return;}
}
-#line 453 "runtime.in"
+#line 459 "runtime.in"
// string pattern(pen p);
-void gen_runtime37(stack *Stack)
+void gen_runtime38(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 454 "runtime.in"
+#line 460 "runtime.in"
{Stack->push<string>(p.fillpattern()); return;}
}
-#line 458 "runtime.in"
+#line 464 "runtime.in"
// pen fillrule(Int n);
-void gen_runtime38(stack *Stack)
+void gen_runtime39(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 459 "runtime.in"
+#line 465 "runtime.in"
{Stack->push<pen>(pen(n >= 0 && n < nFill ? (FillRule) n : DEFFILL)); return;}
}
-#line 463 "runtime.in"
+#line 469 "runtime.in"
// Int fillrule(pen p);
-void gen_runtime39(stack *Stack)
+void gen_runtime40(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 464 "runtime.in"
+#line 470 "runtime.in"
{Stack->push<Int>(p.Fillrule()); return;}
}
-#line 468 "runtime.in"
+#line 474 "runtime.in"
// pen opacity(real opacity=1.0, string blend=defaulttransparency);
-void gen_runtime40(stack *Stack)
+void gen_runtime41(stack *Stack)
{
string blend=vm::pop<string>(Stack,defaulttransparency);
real opacity=vm::pop<real>(Stack,1.0);
-#line 469 "runtime.in"
+#line 475 "runtime.in"
for(Int i=0; i < nBlendMode; ++i)
if(blend == BlendMode[i]) {Stack->push<pen>(pen(Transparency(blend,opacity))); return;}
@@ -657,33 +667,33 @@ void gen_runtime40(stack *Stack)
error(buf);
}
-#line 478 "runtime.in"
+#line 484 "runtime.in"
// real opacity(pen p);
-void gen_runtime41(stack *Stack)
+void gen_runtime42(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 479 "runtime.in"
+#line 485 "runtime.in"
{Stack->push<real>(p.opacity()); return;}
}
-#line 483 "runtime.in"
+#line 489 "runtime.in"
// string blend(pen p);
-void gen_runtime42(stack *Stack)
+void gen_runtime43(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 484 "runtime.in"
+#line 490 "runtime.in"
{Stack->push<string>(p.blend()); return;}
}
-#line 488 "runtime.in"
+#line 494 "runtime.in"
// pen linetype(realarray *pattern, real offset=0, bool scale=true, bool adjust=true);
-void gen_runtime43(stack *Stack)
+void gen_runtime44(stack *Stack)
{
bool adjust=vm::pop<bool>(Stack,true);
bool scale=vm::pop<bool>(Stack,true);
real offset=vm::pop<real>(Stack,0);
realarray * pattern=vm::pop<realarray *>(Stack);
-#line 490 "runtime.in"
+#line 496 "runtime.in"
size_t size=checkArray(pattern);
array *a=new array(size);
for(size_t i=0; i < size; ++i)
@@ -692,272 +702,272 @@ void gen_runtime43(stack *Stack)
{Stack->push<pen>(pen(LineType(*a,offset,scale,adjust))); return;}
}
-#line 499 "runtime.in"
+#line 505 "runtime.in"
// realarray* linetype(pen p=CURRENTPEN);
-void gen_runtime44(stack *Stack)
+void gen_runtime45(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 500 "runtime.in"
+#line 506 "runtime.in"
array a=p.linetype()->pattern;
{Stack->push<realarray*>(copyArray(&a)); return;}
}
-#line 505 "runtime.in"
+#line 511 "runtime.in"
// real offset(pen p);
-void gen_runtime45(stack *Stack)
+void gen_runtime46(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 506 "runtime.in"
+#line 512 "runtime.in"
{Stack->push<real>(p.linetype()->offset); return;}
}
-#line 510 "runtime.in"
+#line 516 "runtime.in"
// bool scale(pen p);
-void gen_runtime46(stack *Stack)
+void gen_runtime47(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 511 "runtime.in"
+#line 517 "runtime.in"
{Stack->push<bool>(p.linetype()->scale); return;}
}
-#line 515 "runtime.in"
+#line 521 "runtime.in"
// bool adjust(pen p);
-void gen_runtime47(stack *Stack)
+void gen_runtime48(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 516 "runtime.in"
+#line 522 "runtime.in"
{Stack->push<bool>(p.linetype()->adjust); return;}
}
-#line 520 "runtime.in"
+#line 526 "runtime.in"
// pen adjust(pen p, real arclength, bool cyclic);
-void gen_runtime48(stack *Stack)
+void gen_runtime49(stack *Stack)
{
bool cyclic=vm::pop<bool>(Stack);
real arclength=vm::pop<real>(Stack);
pen p=vm::pop<pen>(Stack);
-#line 521 "runtime.in"
+#line 527 "runtime.in"
{Stack->push<pen>(adjustdash(p,arclength,cyclic)); return;}
}
-#line 525 "runtime.in"
+#line 531 "runtime.in"
// pen linecap(Int n);
-void gen_runtime49(stack *Stack)
+void gen_runtime50(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 526 "runtime.in"
+#line 532 "runtime.in"
{Stack->push<pen>(pen(setlinecap,n >= 0 && n < nCap ? n : DEFCAP)); return;}
}
-#line 530 "runtime.in"
+#line 536 "runtime.in"
// Int linecap(pen p=CURRENTPEN);
-void gen_runtime50(stack *Stack)
+void gen_runtime51(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 531 "runtime.in"
+#line 537 "runtime.in"
{Stack->push<Int>(p.cap()); return;}
}
-#line 535 "runtime.in"
+#line 541 "runtime.in"
// pen linejoin(Int n);
-void gen_runtime51(stack *Stack)
+void gen_runtime52(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 536 "runtime.in"
+#line 542 "runtime.in"
{Stack->push<pen>(pen(setlinejoin,n >= 0 && n < nJoin ? n : DEFJOIN)); return;}
}
-#line 540 "runtime.in"
+#line 546 "runtime.in"
// Int linejoin(pen p=CURRENTPEN);
-void gen_runtime52(stack *Stack)
+void gen_runtime53(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 541 "runtime.in"
+#line 547 "runtime.in"
{Stack->push<Int>(p.join()); return;}
}
-#line 545 "runtime.in"
+#line 551 "runtime.in"
// pen miterlimit(real x);
-void gen_runtime53(stack *Stack)
+void gen_runtime54(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 546 "runtime.in"
+#line 552 "runtime.in"
{Stack->push<pen>(pen(setmiterlimit,x >= 1.0 ? x : DEFJOIN)); return;}
}
-#line 550 "runtime.in"
+#line 556 "runtime.in"
// real miterlimit(pen p=CURRENTPEN);
-void gen_runtime54(stack *Stack)
+void gen_runtime55(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 551 "runtime.in"
+#line 557 "runtime.in"
{Stack->push<real>(p.miter()); return;}
}
-#line 555 "runtime.in"
+#line 561 "runtime.in"
// pen linewidth(real x);
-void gen_runtime55(stack *Stack)
+void gen_runtime56(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 556 "runtime.in"
+#line 562 "runtime.in"
{Stack->push<pen>(pen(setlinewidth,x >= 0.0 ? x : DEFWIDTH)); return;}
}
-#line 560 "runtime.in"
+#line 566 "runtime.in"
// real linewidth(pen p=CURRENTPEN);
-void gen_runtime56(stack *Stack)
+void gen_runtime57(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 561 "runtime.in"
+#line 567 "runtime.in"
{Stack->push<real>(p.width()); return;}
}
-#line 565 "runtime.in"
+#line 571 "runtime.in"
// pen fontcommand(string *s);
-void gen_runtime57(stack *Stack)
+void gen_runtime58(stack *Stack)
{
string * s=vm::pop<string *>(Stack);
-#line 566 "runtime.in"
+#line 572 "runtime.in"
{Stack->push<pen>(pen(setfont,*s)); return;}
}
-#line 570 "runtime.in"
+#line 576 "runtime.in"
// string font(pen p=CURRENTPEN);
-void gen_runtime58(stack *Stack)
+void gen_runtime59(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 571 "runtime.in"
+#line 577 "runtime.in"
{Stack->push<string>(p.Font()); return;}
}
-#line 575 "runtime.in"
+#line 581 "runtime.in"
// pen fontsize(real size, real lineskip);
-void gen_runtime59(stack *Stack)
+void gen_runtime60(stack *Stack)
{
real lineskip=vm::pop<real>(Stack);
real size=vm::pop<real>(Stack);
-#line 576 "runtime.in"
+#line 582 "runtime.in"
{Stack->push<pen>(pen(setfontsize,size > 0.0 ? size : 0.0,
lineskip > 0.0 ? lineskip : 0.0)); return;}
}
-#line 581 "runtime.in"
+#line 587 "runtime.in"
// real fontsize(pen p=CURRENTPEN);
-void gen_runtime60(stack *Stack)
+void gen_runtime61(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 582 "runtime.in"
+#line 588 "runtime.in"
{Stack->push<real>(p.size()); return;}
}
-#line 586 "runtime.in"
+#line 592 "runtime.in"
// real lineskip(pen p=CURRENTPEN);
-void gen_runtime61(stack *Stack)
+void gen_runtime62(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 587 "runtime.in"
+#line 593 "runtime.in"
{Stack->push<real>(p.Lineskip()); return;}
}
-#line 591 "runtime.in"
+#line 597 "runtime.in"
// pen overwrite(Int n);
-void gen_runtime62(stack *Stack)
+void gen_runtime63(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 592 "runtime.in"
+#line 598 "runtime.in"
{Stack->push<pen>(pen(setoverwrite,n >= 0 && n < nOverwrite ? (overwrite_t) n :
DEFWRITE)); return;}
}
-#line 597 "runtime.in"
+#line 603 "runtime.in"
// Int overwrite(pen p=CURRENTPEN);
-void gen_runtime63(stack *Stack)
+void gen_runtime64(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 598 "runtime.in"
+#line 604 "runtime.in"
{Stack->push<Int>(p.Overwrite()); return;}
}
-#line 602 "runtime.in"
+#line 608 "runtime.in"
// pen basealign(Int n);
-void gen_runtime64(stack *Stack)
+void gen_runtime65(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
-#line 603 "runtime.in"
+#line 609 "runtime.in"
{Stack->push<pen>(pen(n >= 0 && n < nBaseLine ? (BaseLine) n : DEFBASE)); return;}
}
-#line 607 "runtime.in"
+#line 613 "runtime.in"
// Int basealign(pen p=CURRENTPEN);
-void gen_runtime65(stack *Stack)
+void gen_runtime66(stack *Stack)
{
pen p=vm::pop<pen>(Stack,CURRENTPEN);
-#line 608 "runtime.in"
+#line 614 "runtime.in"
{Stack->push<Int>(p.Baseline()); return;}
}
-#line 612 "runtime.in"
+#line 618 "runtime.in"
// transform transform(pen p);
-void gen_runtime66(stack *Stack)
+void gen_runtime67(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 613 "runtime.in"
+#line 619 "runtime.in"
{Stack->push<transform>(p.getTransform()); return;}
}
-#line 617 "runtime.in"
+#line 623 "runtime.in"
// path nib(pen p);
-void gen_runtime67(stack *Stack)
+void gen_runtime68(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 618 "runtime.in"
+#line 624 "runtime.in"
{Stack->push<path>(p.Path()); return;}
}
-#line 622 "runtime.in"
+#line 628 "runtime.in"
// pen makepen(path p);
-void gen_runtime68(stack *Stack)
+void gen_runtime69(stack *Stack)
{
path p=vm::pop<path>(Stack);
-#line 623 "runtime.in"
+#line 629 "runtime.in"
{Stack->push<pen>(pen(p)); return;}
}
-#line 627 "runtime.in"
+#line 633 "runtime.in"
// pen colorless(pen p);
-void gen_runtime69(stack *Stack)
+void gen_runtime70(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
-#line 628 "runtime.in"
+#line 634 "runtime.in"
p.colorless();
{Stack->push<pen>(p); return;}
}
// Interactive mode
-#line 634 "runtime.in"
+#line 640 "runtime.in"
// bool interactive();
-void gen_runtime70(stack *Stack)
+void gen_runtime71(stack *Stack)
{
-#line 635 "runtime.in"
+#line 641 "runtime.in"
{Stack->push<bool>(interact::interactive); return;}
}
-#line 640 "runtime.in"
+#line 646 "runtime.in"
// bool uptodate();
-void gen_runtime71(stack *Stack)
+void gen_runtime72(stack *Stack)
{
-#line 641 "runtime.in"
+#line 647 "runtime.in"
{Stack->push<bool>(interact::uptodate); return;}
}
// System commands
-#line 647 "runtime.in"
+#line 653 "runtime.in"
// Int system(stringarray *s);
-void gen_runtime72(stack *Stack)
+void gen_runtime73(stack *Stack)
{
stringarray * s=vm::pop<stringarray *>(Stack);
-#line 648 "runtime.in"
+#line 654 "runtime.in"
if(safe) error("system() call disabled; override with option -nosafe");
size_t size=checkArray(s);
if(size == 0) {Stack->push<Int>(0); return;}
@@ -967,57 +977,57 @@ void gen_runtime72(stack *Stack)
{Stack->push<Int>(System(cmd)); return;}
}
-#line 659 "runtime.in"
+#line 665 "runtime.in"
// bool view();
-void gen_runtime73(stack *Stack)
+void gen_runtime74(stack *Stack)
{
-#line 660 "runtime.in"
+#line 666 "runtime.in"
{Stack->push<bool>(view()); return;}
}
-#line 664 "runtime.in"
+#line 670 "runtime.in"
// string asydir();
-void gen_runtime74(stack *Stack)
+void gen_runtime75(stack *Stack)
{
-#line 665 "runtime.in"
+#line 671 "runtime.in"
{Stack->push<string>(systemDir); return;}
}
-#line 669 "runtime.in"
+#line 675 "runtime.in"
// string locale(string s=emptystring);
-void gen_runtime75(stack *Stack)
+void gen_runtime76(stack *Stack)
{
string s=vm::pop<string>(Stack,emptystring);
-#line 670 "runtime.in"
+#line 676 "runtime.in"
char *L=setlocale(LC_ALL,s.empty() ? NULL : s.c_str());
{Stack->push<string>(L != NULL ? string(L) : ""); return;}
}
-#line 675 "runtime.in"
+#line 681 "runtime.in"
// void abort(string s=emptystring);
-void gen_runtime76(stack *Stack)
+void gen_runtime77(stack *Stack)
{
string s=vm::pop<string>(Stack,emptystring);
-#line 676 "runtime.in"
+#line 682 "runtime.in"
if(s.empty()) throw handled_error();
error(s.c_str());
}
-#line 681 "runtime.in"
+#line 687 "runtime.in"
// void exit();
-void gen_runtime77(stack *)
+void gen_runtime78(stack *)
{
-#line 682 "runtime.in"
+#line 688 "runtime.in"
throw quit();
}
-#line 686 "runtime.in"
+#line 692 "runtime.in"
// void assert(bool b, string s=emptystring);
-void gen_runtime78(stack *Stack)
+void gen_runtime79(stack *Stack)
{
string s=vm::pop<string>(Stack,emptystring);
bool b=vm::pop<bool>(Stack);
-#line 687 "runtime.in"
+#line 693 "runtime.in"
flush(cout);
if(!b) {
ostringstream buf;
@@ -1027,34 +1037,34 @@ void gen_runtime78(stack *Stack)
}
}
-#line 697 "runtime.in"
+#line 703 "runtime.in"
// void sleep(Int seconds);
-void gen_runtime79(stack *Stack)
+void gen_runtime80(stack *Stack)
{
Int seconds=vm::pop<Int>(Stack);
-#line 698 "runtime.in"
+#line 704 "runtime.in"
if(seconds <= 0) return;
sleep(seconds);
}
-#line 703 "runtime.in"
+#line 709 "runtime.in"
// void usleep(Int microseconds);
-void gen_runtime80(stack *Stack)
+void gen_runtime81(stack *Stack)
{
Int microseconds=vm::pop<Int>(Stack);
-#line 704 "runtime.in"
+#line 710 "runtime.in"
if(microseconds <= 0) return;
usleep((unsigned long) microseconds);
}
-#line 709 "runtime.in"
+#line 715 "runtime.in"
// void _eval(string *s, bool embedded, bool interactiveWrite=false);
-void gen_runtime81(stack *Stack)
+void gen_runtime82(stack *Stack)
{
bool interactiveWrite=vm::pop<bool>(Stack,false);
bool embedded=vm::pop<bool>(Stack);
string * s=vm::pop<string *>(Stack);
-#line 710 "runtime.in"
+#line 716 "runtime.in"
if(embedded) {
trans::coenv *e=Stack->getEnvironment();
vm::interactiveStack *is=dynamic_cast<vm::interactiveStack *>(Stack);
@@ -1066,13 +1076,13 @@ void gen_runtime81(stack *Stack)
runString(*s,interactiveWrite);
}
-#line 722 "runtime.in"
+#line 728 "runtime.in"
// void _eval(runnable *s, bool embedded);
-void gen_runtime82(stack *Stack)
+void gen_runtime83(stack *Stack)
{
bool embedded=vm::pop<bool>(Stack);
runnable * s=vm::pop<runnable *>(Stack);
-#line 723 "runtime.in"
+#line 729 "runtime.in"
absyntax::block *ast=new absyntax::block(s->getPos(), false);
ast->add(s);
@@ -1087,59 +1097,51 @@ void gen_runtime82(stack *Stack)
runCode(ast);
}
-#line 738 "runtime.in"
+#line 744 "runtime.in"
// string xasyKEY();
-void gen_runtime83(stack *Stack)
+void gen_runtime84(stack *Stack)
{
-#line 739 "runtime.in"
- processDataStruct *P=&processData();
- xkey_t *xkey=&P->xkey;
- xkey_t::iterator p=xkey->find(P->topPos.LineColumn());
- {Stack->push<string>(p != xkey->end() ? p->second+" 1" : toplocation()+" 0"); return;}
+#line 745 "runtime.in"
+ processDataStruct& P=processData();
+ xkey_t& xkey=P.xkey;
+ xkey_t::iterator p=xkey.find(P.topPos.LineColumn());
+ {Stack->push<string>(p != xkey.end() ? p->second+" 1" : toplocation()+" 0"); return;}
}
-#line 745 "runtime.in"
+#line 751 "runtime.in"
// void xasyKEY(string *s);
-void gen_runtime84(stack *Stack)
+void gen_runtime85(stack *Stack)
{
string * s=vm::pop<string *>(Stack);
-#line 746 "runtime.in"
+#line 752 "runtime.in"
processData().KEY=*s;
}
-#line 749 "runtime.in"
-// string toplocation();
-void gen_runtime85(stack *Stack)
-{
-#line 750 "runtime.in"
- {Stack->push<string>(toplocation()); return;}
-}
-
-#line 753 "runtime.in"
+#line 755 "runtime.in"
// string location();
void gen_runtime86(stack *Stack)
{
-#line 754 "runtime.in"
+#line 756 "runtime.in"
ostringstream buf;
buf << getPos();
{Stack->push<string>(buf.str()); return;}
}
// Wrapper for the stack::load() method.
-#line 760 "runtime.in"
+#line 762 "runtime.in"
void loadModule(stack *Stack)
{
string * index=vm::pop<string *>(Stack);
-#line 761 "runtime.in"
+#line 763 "runtime.in"
Stack->load(*index);
}
-#line 765 "runtime.in"
+#line 767 "runtime.in"
// string cd(string s=emptystring);
void gen_runtime88(stack *Stack)
{
string s=vm::pop<string>(Stack,emptystring);
-#line 766 "runtime.in"
+#line 768 "runtime.in"
if(!globalread()) readDisabled();
if(!s.empty() && !globalwrite()) {
string outname=settings::outname();
@@ -1149,13 +1151,13 @@ void gen_runtime88(stack *Stack)
{Stack->push<string>(setPath(s.c_str())); return;}
}
-#line 776 "runtime.in"
+#line 778 "runtime.in"
// void list(string *s, bool imports=false);
void gen_runtime89(stack *Stack)
{
bool imports=vm::pop<bool>(Stack,false);
string * s=vm::pop<string *>(Stack);
-#line 777 "runtime.in"
+#line 779 "runtime.in"
if(*s == "-") return;
trans::genv ge;
symbol name=symbol::trans(*s);
@@ -1165,18 +1167,18 @@ void gen_runtime89(stack *Stack)
// Guide operations
-#line 787 "runtime.in"
+#line 789 "runtime.in"
void nullGuide(stack *Stack)
{
-#line 788 "runtime.in"
+#line 790 "runtime.in"
{Stack->push<guide*>(new pathguide(path())); return;}
}
-#line 793 "runtime.in"
+#line 795 "runtime.in"
void dotsGuide(stack *Stack)
{
guidearray * a=vm::pop<guidearray *>(Stack);
-#line 794 "runtime.in"
+#line 796 "runtime.in"
guidevector v;
size_t size=checkArray(a);
for (size_t i=0; i < size; ++i)
@@ -1185,11 +1187,11 @@ void dotsGuide(stack *Stack)
{Stack->push<guide*>(new multiguide(v)); return;}
}
-#line 803 "runtime.in"
+#line 805 "runtime.in"
void dashesGuide(stack *Stack)
{
guidearray * a=vm::pop<guidearray *>(Stack);
-#line 804 "runtime.in"
+#line 806 "runtime.in"
static camp::curlSpec curly;
static camp::specguide curlout(&curly, camp::OUT);
static camp::specguide curlin(&curly, camp::IN);
@@ -1215,179 +1217,179 @@ void dashesGuide(stack *Stack)
{Stack->push<guide*>(new multiguide(v)); return;}
}
-#line 830 "runtime.in"
+#line 832 "runtime.in"
void newCycleToken(stack *Stack)
{
-#line 831 "runtime.in"
+#line 833 "runtime.in"
{Stack->push<cycleToken>(cycleToken()); return;}
}
-#line 835 "runtime.in"
+#line 837 "runtime.in"
// guide* operator cast(cycleToken tok);
void gen_runtime94(stack *Stack)
{
cycleToken tok=vm::pop<cycleToken>(Stack);
-#line 836 "runtime.in"
+#line 838 "runtime.in"
// Avoid unused variable warning messages.
unused(&tok);
{Stack->push<guide*>(new cycletokguide()); return;}
}
-#line 842 "runtime.in"
+#line 844 "runtime.in"
// guide* operator spec(pair z, Int p);
void gen_runtime95(stack *Stack)
{
Int p=vm::pop<Int>(Stack);
pair z=vm::pop<pair>(Stack);
-#line 843 "runtime.in"
+#line 845 "runtime.in"
camp::side d=(camp::side) p;
camp::dirSpec *sp=new camp::dirSpec(z);
{Stack->push<guide*>(new specguide(sp,d)); return;}
}
-#line 850 "runtime.in"
+#line 852 "runtime.in"
// curlSpecifier operator curl(real gamma, Int p);
void gen_runtime96(stack *Stack)
{
Int p=vm::pop<Int>(Stack);
real gamma=vm::pop<real>(Stack);
-#line 851 "runtime.in"
+#line 853 "runtime.in"
camp::side s=(camp::side) p;
{Stack->push<curlSpecifier>(curlSpecifier(gamma,s)); return;}
}
-#line 856 "runtime.in"
+#line 858 "runtime.in"
void curlSpecifierValuePart(stack *Stack)
{
curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
-#line 857 "runtime.in"
+#line 859 "runtime.in"
{Stack->push<real>(spec.getValue()); return;}
}
-#line 861 "runtime.in"
+#line 863 "runtime.in"
void curlSpecifierSidePart(stack *Stack)
{
curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
-#line 862 "runtime.in"
+#line 864 "runtime.in"
{Stack->push<Int>(spec.getSide()); return;}
}
-#line 866 "runtime.in"
+#line 868 "runtime.in"
// guide* operator cast(curlSpecifier spec);
void gen_runtime99(stack *Stack)
{
curlSpecifier spec=vm::pop<curlSpecifier>(Stack);
-#line 867 "runtime.in"
+#line 869 "runtime.in"
{Stack->push<guide*>(new specguide(spec)); return;}
}
-#line 871 "runtime.in"
+#line 873 "runtime.in"
// tensionSpecifier operator tension(real tout, real tin, bool atleast);
void gen_runtime100(stack *Stack)
{
bool atleast=vm::pop<bool>(Stack);
real tin=vm::pop<real>(Stack);
real tout=vm::pop<real>(Stack);
-#line 872 "runtime.in"
+#line 874 "runtime.in"
{Stack->push<tensionSpecifier>(tensionSpecifier(tout, tin, atleast)); return;}
}
-#line 876 "runtime.in"
+#line 878 "runtime.in"
void tensionSpecifierOutPart(stack *Stack)
{
tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
-#line 877 "runtime.in"
+#line 879 "runtime.in"
{Stack->push<real>(t.getOut()); return;}
}
-#line 881 "runtime.in"
+#line 883 "runtime.in"
void tensionSpecifierInPart(stack *Stack)
{
tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
-#line 882 "runtime.in"
+#line 884 "runtime.in"
{Stack->push<real>(t.getIn()); return;}
}
-#line 886 "runtime.in"
+#line 888 "runtime.in"
void tensionSpecifierAtleastPart(stack *Stack)
{
tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
-#line 887 "runtime.in"
+#line 889 "runtime.in"
{Stack->push<bool>(t.getAtleast()); return;}
}
-#line 891 "runtime.in"
+#line 893 "runtime.in"
// guide* operator cast(tensionSpecifier t);
void gen_runtime104(stack *Stack)
{
tensionSpecifier t=vm::pop<tensionSpecifier>(Stack);
-#line 892 "runtime.in"
+#line 894 "runtime.in"
{Stack->push<guide*>(new tensionguide(t)); return;}
}
-#line 896 "runtime.in"
+#line 898 "runtime.in"
// guide* operator controls(pair zout, pair zin);
void gen_runtime105(stack *Stack)
{
pair zin=vm::pop<pair>(Stack);
pair zout=vm::pop<pair>(Stack);
-#line 897 "runtime.in"
+#line 899 "runtime.in"
{Stack->push<guide*>(new controlguide(zout, zin)); return;}
}
-#line 901 "runtime.in"
+#line 903 "runtime.in"
// Int size(guide *g);
void gen_runtime106(stack *Stack)
{
guide * g=vm::pop<guide *>(Stack);
-#line 902 "runtime.in"
+#line 904 "runtime.in"
flatguide f;
g->flatten(f,false);
{Stack->push<Int>(f.size()); return;}
}
-#line 908 "runtime.in"
+#line 910 "runtime.in"
// Int length(guide *g);
void gen_runtime107(stack *Stack)
{
guide * g=vm::pop<guide *>(Stack);
-#line 909 "runtime.in"
+#line 911 "runtime.in"
flatguide f;
g->flatten(f,false);
{Stack->push<Int>(g->cyclic() ? f.size() : f.size()-1); return;}
}
-#line 915 "runtime.in"
+#line 917 "runtime.in"
// bool cyclic(guide *g);
void gen_runtime108(stack *Stack)
{
guide * g=vm::pop<guide *>(Stack);
-#line 916 "runtime.in"
+#line 918 "runtime.in"
flatguide f;
g->flatten(f,false);
{Stack->push<bool>(g->cyclic()); return;}
}
-#line 922 "runtime.in"
+#line 924 "runtime.in"
// pair point(guide *g, Int t);
void gen_runtime109(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
guide * g=vm::pop<guide *>(Stack);
-#line 923 "runtime.in"
+#line 925 "runtime.in"
flatguide f;
g->flatten(f,false);
{Stack->push<pair>(f.Nodes(adjustedIndex(t,f.size(),g->cyclic())).z); return;}
}
-#line 929 "runtime.in"
+#line 931 "runtime.in"
// pairarray* dirSpecifier(guide *g, Int t);
void gen_runtime110(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
guide * g=vm::pop<guide *>(Stack);
-#line 930 "runtime.in"
+#line 932 "runtime.in"
flatguide f;
g->flatten(f,false);
Int n=f.size();
@@ -1398,13 +1400,13 @@ void gen_runtime110(stack *Stack)
{Stack->push<pairarray*>(c); return;}
}
-#line 941 "runtime.in"
+#line 943 "runtime.in"
// pairarray* controlSpecifier(guide *g, Int t);
void gen_runtime111(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
guide * g=vm::pop<guide *>(Stack);
-#line 942 "runtime.in"
+#line 944 "runtime.in"
flatguide f;
g->flatten(f,false);
Int n=f.size();
@@ -1420,13 +1422,13 @@ void gen_runtime111(stack *Stack)
} else {Stack->push<pairarray*>(new array(0)); return;}
}
-#line 958 "runtime.in"
+#line 960 "runtime.in"
// tensionSpecifier tensionSpecifier(guide *g, Int t);
void gen_runtime112(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
guide * g=vm::pop<guide *>(Stack);
-#line 959 "runtime.in"
+#line 961 "runtime.in"
flatguide f;
g->flatten(f,false);
Int n=f.size();
@@ -1435,13 +1437,13 @@ void gen_runtime112(stack *Stack)
{Stack->push<tensionSpecifier>(tensionSpecifier(curr.tout.val,f.Nodes(t+1).tin.val,curr.tout.atleast)); return;}
}
-#line 968 "runtime.in"
+#line 970 "runtime.in"
// realarray* curlSpecifier(guide *g, Int t);
void gen_runtime113(stack *Stack)
{
Int t=vm::pop<Int>(Stack);
guide * g=vm::pop<guide *>(Stack);
-#line 969 "runtime.in"
+#line 971 "runtime.in"
flatguide f;
g->flatten(f,false);
Int n=f.size();
@@ -1454,12 +1456,12 @@ void gen_runtime113(stack *Stack)
{Stack->push<realarray*>(c); return;}
}
-#line 982 "runtime.in"
+#line 984 "runtime.in"
// guide* reverse(guide *g);
void gen_runtime114(stack *Stack)
{
guide * g=vm::pop<guide *>(Stack);
-#line 983 "runtime.in"
+#line 985 "runtime.in"
flatguide f;
g->flatten(f,false);
if(f.precyclic())
@@ -1510,11 +1512,11 @@ void gen_runtime114(stack *Stack)
{Stack->push<guide*>(new multiguide(v)); return;}
}
-#line 1035 "runtime.in"
+#line 1037 "runtime.in"
// realarray* _cputime();
void gen_runtime115(stack *Stack)
{
-#line 1036 "runtime.in"
+#line 1038 "runtime.in"
static const real ticktime=1.0/sysconf(_SC_CLK_TCK);
struct tms buf;
@@ -1530,103 +1532,103 @@ void gen_runtime115(stack *Stack)
// Transforms
-#line 1052 "runtime.in"
+#line 1054 "runtime.in"
// bool ==(transform a, transform b);
void gen_runtime116(stack *Stack)
{
transform b=vm::pop<transform>(Stack);
transform a=vm::pop<transform>(Stack);
-#line 1053 "runtime.in"
+#line 1055 "runtime.in"
{Stack->push<bool>(a == b); return;}
}
-#line 1058 "runtime.in"
+#line 1060 "runtime.in"
// bool !=(transform a, transform b);
void gen_runtime117(stack *Stack)
{
transform b=vm::pop<transform>(Stack);
transform a=vm::pop<transform>(Stack);
-#line 1059 "runtime.in"
+#line 1061 "runtime.in"
{Stack->push<bool>(a != b); return;}
}
-#line 1063 "runtime.in"
+#line 1065 "runtime.in"
// transform +(transform a, transform b);
void gen_runtime118(stack *Stack)
{
transform b=vm::pop<transform>(Stack);
transform a=vm::pop<transform>(Stack);
-#line 1064 "runtime.in"
+#line 1066 "runtime.in"
{Stack->push<transform>(a+b); return;}
}
-#line 1068 "runtime.in"
+#line 1070 "runtime.in"
// transform *(transform a, transform b);
void gen_runtime119(stack *Stack)
{
transform b=vm::pop<transform>(Stack);
transform a=vm::pop<transform>(Stack);
-#line 1069 "runtime.in"
+#line 1071 "runtime.in"
{Stack->push<transform>(a*b); return;}
}
-#line 1073 "runtime.in"
+#line 1075 "runtime.in"
// pair *(transform t, pair z);
void gen_runtime120(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
transform t=vm::pop<transform>(Stack);
-#line 1074 "runtime.in"
+#line 1076 "runtime.in"
{Stack->push<pair>(t*z); return;}
}
-#line 1078 "runtime.in"
+#line 1080 "runtime.in"
// path *(transform t, path g);
void gen_runtime121(stack *Stack)
{
path g=vm::pop<path>(Stack);
transform t=vm::pop<transform>(Stack);
-#line 1079 "runtime.in"
+#line 1081 "runtime.in"
{Stack->push<path>(transformed(t,g)); return;}
}
-#line 1083 "runtime.in"
+#line 1085 "runtime.in"
// pen *(transform t, pen p);
void gen_runtime122(stack *Stack)
{
pen p=vm::pop<pen>(Stack);
transform t=vm::pop<transform>(Stack);
-#line 1084 "runtime.in"
+#line 1086 "runtime.in"
{Stack->push<pen>(transformed(t,p)); return;}
}
-#line 1088 "runtime.in"
+#line 1090 "runtime.in"
// picture* *(transform t, picture *f);
void gen_runtime123(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
transform t=vm::pop<transform>(Stack);
-#line 1089 "runtime.in"
+#line 1091 "runtime.in"
{Stack->push<picture*>(transformed(t,f)); return;}
}
-#line 1093 "runtime.in"
+#line 1095 "runtime.in"
// picture* *(realarray2 *t, picture *f);
void gen_runtime124(stack *Stack)
{
picture * f=vm::pop<picture *>(Stack);
realarray2 * t=vm::pop<realarray2 *>(Stack);
-#line 1094 "runtime.in"
+#line 1096 "runtime.in"
{Stack->push<picture*>(transformed(*t,f)); return;}
}
-#line 1098 "runtime.in"
+#line 1100 "runtime.in"
// transform ^(transform t, Int n);
void gen_runtime125(stack *Stack)
{
Int n=vm::pop<Int>(Stack);
transform t=vm::pop<transform>(Stack);
-#line 1099 "runtime.in"
+#line 1101 "runtime.in"
transform T;
if(n < 0) {
n=-n;
@@ -1636,55 +1638,55 @@ void gen_runtime125(stack *Stack)
{Stack->push<transform>(T); return;}
}
-#line 1109 "runtime.in"
+#line 1111 "runtime.in"
void transformXPart(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 1110 "runtime.in"
+#line 1112 "runtime.in"
{Stack->push<real>(t.getx()); return;}
}
-#line 1114 "runtime.in"
+#line 1116 "runtime.in"
void transformYPart(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 1115 "runtime.in"
+#line 1117 "runtime.in"
{Stack->push<real>(t.gety()); return;}
}
-#line 1119 "runtime.in"
+#line 1121 "runtime.in"
void transformXXPart(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 1120 "runtime.in"
+#line 1122 "runtime.in"
{Stack->push<real>(t.getxx()); return;}
}
-#line 1124 "runtime.in"
+#line 1126 "runtime.in"
void transformXYPart(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 1125 "runtime.in"
+#line 1127 "runtime.in"
{Stack->push<real>(t.getxy()); return;}
}
-#line 1129 "runtime.in"
+#line 1131 "runtime.in"
void transformYXPart(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 1130 "runtime.in"
+#line 1132 "runtime.in"
{Stack->push<real>(t.getyx()); return;}
}
-#line 1134 "runtime.in"
+#line 1136 "runtime.in"
void transformYYPart(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 1135 "runtime.in"
+#line 1137 "runtime.in"
{Stack->push<real>(t.getyy()); return;}
}
-#line 1139 "runtime.in"
+#line 1141 "runtime.in"
void real6ToTransform(stack *Stack)
{
real yy=vm::pop<real>(Stack);
@@ -1693,136 +1695,136 @@ void real6ToTransform(stack *Stack)
real xx=vm::pop<real>(Stack);
real y=vm::pop<real>(Stack);
real x=vm::pop<real>(Stack);
-#line 1141 "runtime.in"
+#line 1143 "runtime.in"
{Stack->push<transform>(transform(x,y,xx,xy,yx,yy)); return;}
}
-#line 1145 "runtime.in"
+#line 1147 "runtime.in"
// transform shift(transform t);
void gen_runtime133(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 1146 "runtime.in"
+#line 1148 "runtime.in"
{Stack->push<transform>(transform(t.getx(),t.gety(),0,0,0,0)); return;}
}
-#line 1150 "runtime.in"
+#line 1152 "runtime.in"
// transform shiftless(transform t);
void gen_runtime134(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 1151 "runtime.in"
+#line 1153 "runtime.in"
{Stack->push<transform>(transform(0,0,t.getxx(),t.getxy(),t.getyx(),t.getyy())); return;}
}
-#line 1155 "runtime.in"
+#line 1157 "runtime.in"
// transform identity();
void transformIdentity(stack *Stack)
{
-#line 1156 "runtime.in"
+#line 1158 "runtime.in"
{Stack->push<transform>(identity); return;}
}
-#line 1160 "runtime.in"
+#line 1162 "runtime.in"
// transform inverse(transform t);
void gen_runtime136(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 1161 "runtime.in"
+#line 1163 "runtime.in"
{Stack->push<transform>(inverse(t)); return;}
}
-#line 1165 "runtime.in"
+#line 1167 "runtime.in"
// transform shift(pair z);
void gen_runtime137(stack *Stack)
{
pair z=vm::pop<pair>(Stack);
-#line 1166 "runtime.in"
+#line 1168 "runtime.in"
{Stack->push<transform>(shift(z)); return;}
}
-#line 1170 "runtime.in"
+#line 1172 "runtime.in"
// transform shift(real x, real y);
void gen_runtime138(stack *Stack)
{
real y=vm::pop<real>(Stack);
real x=vm::pop<real>(Stack);
-#line 1171 "runtime.in"
+#line 1173 "runtime.in"
{Stack->push<transform>(shift(pair(x,y))); return;}
}
-#line 1175 "runtime.in"
+#line 1177 "runtime.in"
// transform xscale(real x);
void gen_runtime139(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 1176 "runtime.in"
+#line 1178 "runtime.in"
{Stack->push<transform>(xscale(x)); return;}
}
-#line 1180 "runtime.in"
+#line 1182 "runtime.in"
// transform yscale(real y);
void gen_runtime140(stack *Stack)
{
real y=vm::pop<real>(Stack);
-#line 1181 "runtime.in"
+#line 1183 "runtime.in"
{Stack->push<transform>(yscale(y)); return;}
}
-#line 1185 "runtime.in"
+#line 1187 "runtime.in"
// transform scale(real x);
void gen_runtime141(stack *Stack)
{
real x=vm::pop<real>(Stack);
-#line 1186 "runtime.in"
+#line 1188 "runtime.in"
{Stack->push<transform>(scale(x)); return;}
}
-#line 1190 "runtime.in"
+#line 1192 "runtime.in"
// transform scale(real x, real y);
void gen_runtime142(stack *Stack)
{
real y=vm::pop<real>(Stack);
real x=vm::pop<real>(Stack);
-#line 1191 "runtime.in"
+#line 1193 "runtime.in"
{Stack->push<transform>(scale(x,y)); return;}
}
-#line 1195 "runtime.in"
+#line 1197 "runtime.in"
// transform slant(real s);
void gen_runtime143(stack *Stack)
{
real s=vm::pop<real>(Stack);
-#line 1196 "runtime.in"
+#line 1198 "runtime.in"
{Stack->push<transform>(slant(s)); return;}
}
-#line 1200 "runtime.in"
+#line 1202 "runtime.in"
// transform rotate(real angle, pair z=0);
void gen_runtime144(stack *Stack)
{
pair z=vm::pop<pair>(Stack,0);
real angle=vm::pop<real>(Stack);
-#line 1201 "runtime.in"
+#line 1203 "runtime.in"
{Stack->push<transform>(rotatearound(z,radians(angle))); return;}
}
-#line 1205 "runtime.in"
+#line 1207 "runtime.in"
// transform reflect(pair a, pair b);
void gen_runtime145(stack *Stack)
{
pair b=vm::pop<pair>(Stack);
pair a=vm::pop<pair>(Stack);
-#line 1206 "runtime.in"
+#line 1208 "runtime.in"
{Stack->push<transform>(reflectabout(a,b)); return;}
}
-#line 1210 "runtime.in"
+#line 1212 "runtime.in"
// bool isometry(transform t);
void gen_runtime146(stack *Stack)
{
transform t=vm::pop<transform>(Stack);
-#line 1211 "runtime.in"
+#line 1213 "runtime.in"
{Stack->push<bool>(t.isIsometry()); return;}
}
@@ -1832,299 +1834,299 @@ namespace trans {
void gen_runtime_venv(venv &ve)
{
-#line 223 "runtime.in"
+#line 224 "runtime.in"
REGISTER_BLTIN(run::IntZero,"IntZero");
-#line 231 "runtime.in"
+#line 232 "runtime.in"
REGISTER_BLTIN(run::realZero,"realZero");
-#line 236 "runtime.in"
+#line 237 "runtime.in"
REGISTER_BLTIN(run::boolFalse,"boolFalse");
-#line 241 "runtime.in"
+#line 242 "runtime.in"
addFunc(ve, run::gen_runtime3, primBoolean(), SYM(isnan), formal(primReal(), SYM(x), false, false));
-#line 246 "runtime.in"
+#line 247 "runtime.in"
REGISTER_BLTIN(run::pushNullArray,"pushNullArray");
-#line 251 "runtime.in"
+#line 252 "runtime.in"
REGISTER_BLTIN(run::pushNullRecord,"pushNullRecord");
-#line 256 "runtime.in"
+#line 257 "runtime.in"
REGISTER_BLTIN(run::pushNullFunction,"pushNullFunction");
-#line 261 "runtime.in"
+#line 262 "runtime.in"
REGISTER_BLTIN(run::pushDefault,"pushDefault");
-#line 271 "runtime.in"
+#line 272 "runtime.in"
REGISTER_BLTIN(run::isDefault,"isDefault");
-#line 278 "runtime.in"
+#line 279 "runtime.in"
REGISTER_BLTIN(run::pairToGuide,"pairToGuide");
-#line 286 "runtime.in"
+#line 287 "runtime.in"
REGISTER_BLTIN(run::pathToGuide,"pathToGuide");
-#line 291 "runtime.in"
+#line 292 "runtime.in"
REGISTER_BLTIN(run::guideToPath,"guideToPath");
-#line 296 "runtime.in"
+#line 297 "runtime.in"
REGISTER_BLTIN(run::newPen,"newPen");
-#line 304 "runtime.in"
+#line 305 "runtime.in"
addFunc(ve, run::gen_runtime13, primBoolean(), SYM_EQ, formal(primPen(), SYM(a), false, false), formal(primPen(), SYM(b), false, false));
-#line 309 "runtime.in"
+#line 310 "runtime.in"
addFunc(ve, run::gen_runtime14, primBoolean(), SYM_NEQ, formal(primPen(), SYM(a), false, false), formal(primPen(), SYM(b), false, false));
-#line 314 "runtime.in"
+#line 315 "runtime.in"
addFunc(ve, run::gen_runtime15, primPen(), SYM_PLUS, formal(primPen(), SYM(a), false, false), formal(primPen(), SYM(b), false, false));
-#line 319 "runtime.in"
+#line 320 "runtime.in"
addFunc(ve, run::gen_runtime16, primPen(), SYM_TIMES, formal(primReal(), SYM(a), false, false), formal(primPen(), SYM(b), false, false));
-#line 324 "runtime.in"
+#line 325 "runtime.in"
addFunc(ve, run::gen_runtime17, primPen(), SYM_TIMES, formal(primPen(), SYM(a), false, false), formal(primReal(), SYM(b), false, false));
-#line 329 "runtime.in"
+#line 330 "runtime.in"
addFunc(ve, run::gen_runtime18, primPair(), SYM(max), formal(primPen(), SYM(p), false, false));
-#line 334 "runtime.in"
+#line 335 "runtime.in"
addFunc(ve, run::gen_runtime19, primPair(), SYM(min), formal(primPen(), SYM(p), false, false));
-#line 339 "runtime.in"
+#line 340 "runtime.in"
addFunc(ve, run::gen_runtime20, primVoid(), SYM(resetdefaultpen));
-#line 345 "runtime.in"
+#line 346 "runtime.in"
addFunc(ve, run::gen_runtime21, primVoid(), SYM(defaultpen), formal(primPen(), SYM(p), false, false));
-#line 350 "runtime.in"
+#line 351 "runtime.in"
addFunc(ve, run::gen_runtime22, primPen(), SYM(defaultpen));
-#line 355 "runtime.in"
+#line 356 "runtime.in"
addFunc(ve, run::gen_runtime23, primBoolean(), SYM(invisible), formal(primPen(), SYM(p), false, false));
-#line 360 "runtime.in"
+#line 361 "runtime.in"
addFunc(ve, run::gen_runtime24, primPen(), SYM(invisible));
-#line 365 "runtime.in"
+#line 366 "runtime.in"
addFunc(ve, run::gen_runtime25, primPen(), SYM(gray), formal(primPen(), SYM(p), false, false));
-#line 371 "runtime.in"
+#line 372 "runtime.in"
addFunc(ve, run::gen_runtime26, primPen(), SYM(rgb), formal(primPen(), SYM(p), false, false));
-#line 377 "runtime.in"
+#line 378 "runtime.in"
addFunc(ve, run::gen_runtime27, primPen(), SYM(cmyk), formal(primPen(), SYM(p), false, false));
-#line 383 "runtime.in"
+#line 384 "runtime.in"
addFunc(ve, run::gen_runtime28, primPen(), SYM(interp), formal(primPen(), SYM(a), false, false), formal(primPen(), SYM(b), false, false), formal(primReal(), SYM(t), false, false));
-#line 388 "runtime.in"
+#line 389 "runtime.in"
addFunc(ve, run::gen_runtime29, primPen(), SYM(rgb), formal(primReal(), SYM(r), false, false), formal(primReal(), SYM(g), false, false), formal(primReal(), SYM(b), false, false));
-#line 393 "runtime.in"
+#line 394 "runtime.in"
addFunc(ve, run::gen_runtime30, primPen(), SYM(cmyk), formal(primReal(), SYM(c), false, false), formal(primReal(), SYM(m), false, false), formal(primReal(), SYM(y), false, false), formal(primReal(), SYM(k), false, false));
-#line 398 "runtime.in"
+#line 399 "runtime.in"
addFunc(ve, run::gen_runtime31, primPen(), SYM(gray), formal(primReal(), SYM(gray), false, false));
-#line 403 "runtime.in"
+#line 404 "runtime.in"
addFunc(ve, run::gen_runtime32, realArray(), SYM(colors), formal(primPen(), SYM(p), false, false));
-#line 431 "runtime.in"
+#line 432 "runtime.in"
addFunc(ve, run::gen_runtime33, primString(), SYM(hex), formal(primPen(), SYM(p), false, false));
-#line 436 "runtime.in"
+#line 437 "runtime.in"
addFunc(ve, run::gen_runtime34, primInt(), SYM(byte), formal(primReal(), SYM(x), false, false));
-#line 441 "runtime.in"
- addFunc(ve, run::gen_runtime35, primString(), SYM(colorspace), formal(primPen(), SYM(p), false, false));
-#line 448 "runtime.in"
- addFunc(ve, run::gen_runtime36, primPen(), SYM(pattern), formal(primString(), SYM(s), false, false));
-#line 453 "runtime.in"
- addFunc(ve, run::gen_runtime37, primString(), SYM(pattern), formal(primPen(), SYM(p), false, false));
-#line 458 "runtime.in"
- addFunc(ve, run::gen_runtime38, primPen(), SYM(fillrule), formal(primInt(), SYM(n), false, false));
-#line 463 "runtime.in"
- addFunc(ve, run::gen_runtime39, primInt(), SYM(fillrule), formal(primPen(), SYM(p), false, false));
-#line 468 "runtime.in"
- addFunc(ve, run::gen_runtime40, primPen(), SYM(opacity), formal(primReal(), SYM(opacity), true, false), formal(primString(), SYM(blend), true, false));
-#line 478 "runtime.in"
- addFunc(ve, run::gen_runtime41, primReal(), SYM(opacity), formal(primPen(), SYM(p), false, false));
-#line 483 "runtime.in"
- addFunc(ve, run::gen_runtime42, primString(), SYM(blend), formal(primPen(), SYM(p), false, false));
-#line 488 "runtime.in"
- addFunc(ve, run::gen_runtime43, primPen(), SYM(linetype), formal(realArray(), SYM(pattern), false, false), formal(primReal(), SYM(offset), true, false), formal(primBoolean(), SYM(scale), true, false), formal(primBoolean(), SYM(adjust), true, false));
-#line 499 "runtime.in"
- addFunc(ve, run::gen_runtime44, realArray(), SYM(linetype), formal(primPen(), SYM(p), true, false));
+#line 442 "runtime.in"
+ addFunc(ve, run::gen_runtime35, primReal(), SYM(byteinv), formal(primInt(), SYM(x), false, false));
+#line 447 "runtime.in"
+ addFunc(ve, run::gen_runtime36, primString(), SYM(colorspace), formal(primPen(), SYM(p), false, false));
+#line 454 "runtime.in"
+ addFunc(ve, run::gen_runtime37, primPen(), SYM(pattern), formal(primString(), SYM(s), false, false));
+#line 459 "runtime.in"
+ addFunc(ve, run::gen_runtime38, primString(), SYM(pattern), formal(primPen(), SYM(p), false, false));
+#line 464 "runtime.in"
+ addFunc(ve, run::gen_runtime39, primPen(), SYM(fillrule), formal(primInt(), SYM(n), false, false));
+#line 469 "runtime.in"
+ addFunc(ve, run::gen_runtime40, primInt(), SYM(fillrule), formal(primPen(), SYM(p), false, false));
+#line 474 "runtime.in"
+ addFunc(ve, run::gen_runtime41, primPen(), SYM(opacity), formal(primReal(), SYM(opacity), true, false), formal(primString(), SYM(blend), true, false));
+#line 484 "runtime.in"
+ addFunc(ve, run::gen_runtime42, primReal(), SYM(opacity), formal(primPen(), SYM(p), false, false));
+#line 489 "runtime.in"
+ addFunc(ve, run::gen_runtime43, primString(), SYM(blend), formal(primPen(), SYM(p), false, false));
+#line 494 "runtime.in"
+ addFunc(ve, run::gen_runtime44, primPen(), SYM(linetype), formal(realArray(), SYM(pattern), false, false), formal(primReal(), SYM(offset), true, false), formal(primBoolean(), SYM(scale), true, false), formal(primBoolean(), SYM(adjust), true, false));
#line 505 "runtime.in"
- addFunc(ve, run::gen_runtime45, primReal(), SYM(offset), formal(primPen(), SYM(p), false, false));
-#line 510 "runtime.in"
- addFunc(ve, run::gen_runtime46, primBoolean(), SYM(scale), formal(primPen(), SYM(p), false, false));
-#line 515 "runtime.in"
- addFunc(ve, run::gen_runtime47, primBoolean(), SYM(adjust), formal(primPen(), SYM(p), false, false));
-#line 520 "runtime.in"
- addFunc(ve, run::gen_runtime48, primPen(), SYM(adjust), formal(primPen(), SYM(p), false, false), formal(primReal(), SYM(arclength), false, false), formal(primBoolean(), SYM(cyclic), false, false));
-#line 525 "runtime.in"
- addFunc(ve, run::gen_runtime49, primPen(), SYM(linecap), formal(primInt(), SYM(n), false, false));
-#line 530 "runtime.in"
- addFunc(ve, run::gen_runtime50, primInt(), SYM(linecap), formal(primPen(), SYM(p), true, false));
-#line 535 "runtime.in"
- addFunc(ve, run::gen_runtime51, primPen(), SYM(linejoin), formal(primInt(), SYM(n), false, false));
-#line 540 "runtime.in"
- addFunc(ve, run::gen_runtime52, primInt(), SYM(linejoin), formal(primPen(), SYM(p), true, false));
-#line 545 "runtime.in"
- addFunc(ve, run::gen_runtime53, primPen(), SYM(miterlimit), formal(primReal(), SYM(x), false, false));
-#line 550 "runtime.in"
- addFunc(ve, run::gen_runtime54, primReal(), SYM(miterlimit), formal(primPen(), SYM(p), true, false));
-#line 555 "runtime.in"
- addFunc(ve, run::gen_runtime55, primPen(), SYM(linewidth), formal(primReal(), SYM(x), false, false));
-#line 560 "runtime.in"
- addFunc(ve, run::gen_runtime56, primReal(), SYM(linewidth), formal(primPen(), SYM(p), true, false));
-#line 565 "runtime.in"
- addFunc(ve, run::gen_runtime57, primPen(), SYM(fontcommand), formal(primString(), SYM(s), false, false));
-#line 570 "runtime.in"
- addFunc(ve, run::gen_runtime58, primString(), SYM(font), formal(primPen(), SYM(p), true, false));
-#line 575 "runtime.in"
- addFunc(ve, run::gen_runtime59, primPen(), SYM(fontsize), formal(primReal(), SYM(size), false, false), formal(primReal(), SYM(lineskip), false, false));
+ addFunc(ve, run::gen_runtime45, realArray(), SYM(linetype), formal(primPen(), SYM(p), true, false));
+#line 511 "runtime.in"
+ addFunc(ve, run::gen_runtime46, primReal(), SYM(offset), formal(primPen(), SYM(p), false, false));
+#line 516 "runtime.in"
+ addFunc(ve, run::gen_runtime47, primBoolean(), SYM(scale), formal(primPen(), SYM(p), false, false));
+#line 521 "runtime.in"
+ addFunc(ve, run::gen_runtime48, primBoolean(), SYM(adjust), formal(primPen(), SYM(p), false, false));
+#line 526 "runtime.in"
+ addFunc(ve, run::gen_runtime49, primPen(), SYM(adjust), formal(primPen(), SYM(p), false, false), formal(primReal(), SYM(arclength), false, false), formal(primBoolean(), SYM(cyclic), false, false));
+#line 531 "runtime.in"
+ addFunc(ve, run::gen_runtime50, primPen(), SYM(linecap), formal(primInt(), SYM(n), false, false));
+#line 536 "runtime.in"
+ addFunc(ve, run::gen_runtime51, primInt(), SYM(linecap), formal(primPen(), SYM(p), true, false));
+#line 541 "runtime.in"
+ addFunc(ve, run::gen_runtime52, primPen(), SYM(linejoin), formal(primInt(), SYM(n), false, false));
+#line 546 "runtime.in"
+ addFunc(ve, run::gen_runtime53, primInt(), SYM(linejoin), formal(primPen(), SYM(p), true, false));
+#line 551 "runtime.in"
+ addFunc(ve, run::gen_runtime54, primPen(), SYM(miterlimit), formal(primReal(), SYM(x), false, false));
+#line 556 "runtime.in"
+ addFunc(ve, run::gen_runtime55, primReal(), SYM(miterlimit), formal(primPen(), SYM(p), true, false));
+#line 561 "runtime.in"
+ addFunc(ve, run::gen_runtime56, primPen(), SYM(linewidth), formal(primReal(), SYM(x), false, false));
+#line 566 "runtime.in"
+ addFunc(ve, run::gen_runtime57, primReal(), SYM(linewidth), formal(primPen(), SYM(p), true, false));
+#line 571 "runtime.in"
+ addFunc(ve, run::gen_runtime58, primPen(), SYM(fontcommand), formal(primString(), SYM(s), false, false));
+#line 576 "runtime.in"
+ addFunc(ve, run::gen_runtime59, primString(), SYM(font), formal(primPen(), SYM(p), true, false));
#line 581 "runtime.in"
- addFunc(ve, run::gen_runtime60, primReal(), SYM(fontsize), formal(primPen(), SYM(p), true, false));
-#line 586 "runtime.in"
- addFunc(ve, run::gen_runtime61, primReal(), SYM(lineskip), formal(primPen(), SYM(p), true, false));
-#line 591 "runtime.in"
- addFunc(ve, run::gen_runtime62, primPen(), SYM(overwrite), formal(primInt(), SYM(n), false, false));
+ addFunc(ve, run::gen_runtime60, primPen(), SYM(fontsize), formal(primReal(), SYM(size), false, false), formal(primReal(), SYM(lineskip), false, false));
+#line 587 "runtime.in"
+ addFunc(ve, run::gen_runtime61, primReal(), SYM(fontsize), formal(primPen(), SYM(p), true, false));
+#line 592 "runtime.in"
+ addFunc(ve, run::gen_runtime62, primReal(), SYM(lineskip), formal(primPen(), SYM(p), true, false));
#line 597 "runtime.in"
- addFunc(ve, run::gen_runtime63, primInt(), SYM(overwrite), formal(primPen(), SYM(p), true, false));
-#line 602 "runtime.in"
- addFunc(ve, run::gen_runtime64, primPen(), SYM(basealign), formal(primInt(), SYM(n), false, false));
-#line 607 "runtime.in"
- addFunc(ve, run::gen_runtime65, primInt(), SYM(basealign), formal(primPen(), SYM(p), true, false));
-#line 612 "runtime.in"
- addFunc(ve, run::gen_runtime66, primTransform(), SYM(transform), formal(primPen(), SYM(p), false, false));
-#line 617 "runtime.in"
- addFunc(ve, run::gen_runtime67, primPath(), SYM(nib), formal(primPen(), SYM(p), false, false));
-#line 622 "runtime.in"
- addFunc(ve, run::gen_runtime68, primPen(), SYM(makepen), formal(primPath(), SYM(p), false, false));
-#line 627 "runtime.in"
- addFunc(ve, run::gen_runtime69, primPen(), SYM(colorless), formal(primPen(), SYM(p), false, false));
+ addFunc(ve, run::gen_runtime63, primPen(), SYM(overwrite), formal(primInt(), SYM(n), false, false));
+#line 603 "runtime.in"
+ addFunc(ve, run::gen_runtime64, primInt(), SYM(overwrite), formal(primPen(), SYM(p), true, false));
+#line 608 "runtime.in"
+ addFunc(ve, run::gen_runtime65, primPen(), SYM(basealign), formal(primInt(), SYM(n), false, false));
+#line 613 "runtime.in"
+ addFunc(ve, run::gen_runtime66, primInt(), SYM(basealign), formal(primPen(), SYM(p), true, false));
+#line 618 "runtime.in"
+ addFunc(ve, run::gen_runtime67, primTransform(), SYM(transform), formal(primPen(), SYM(p), false, false));
+#line 623 "runtime.in"
+ addFunc(ve, run::gen_runtime68, primPath(), SYM(nib), formal(primPen(), SYM(p), false, false));
+#line 628 "runtime.in"
+ addFunc(ve, run::gen_runtime69, primPen(), SYM(makepen), formal(primPath(), SYM(p), false, false));
#line 633 "runtime.in"
- addFunc(ve, run::gen_runtime70, primBoolean(), SYM(interactive));
-#line 640 "runtime.in"
- addFunc(ve, run::gen_runtime71, primBoolean(), SYM(uptodate));
-#line 645 "runtime.in"
- addFunc(ve, run::gen_runtime72, primInt(), SYM(system), formal(stringArray(), SYM(s), false, false));
-#line 659 "runtime.in"
- addFunc(ve, run::gen_runtime73, primBoolean(), SYM(view));
-#line 664 "runtime.in"
- addFunc(ve, run::gen_runtime74, primString(), SYM(asydir));
-#line 669 "runtime.in"
- addFunc(ve, run::gen_runtime75, primString(), SYM(locale), formal(primString(), SYM(s), true, false));
+ addFunc(ve, run::gen_runtime70, primPen(), SYM(colorless), formal(primPen(), SYM(p), false, false));
+#line 639 "runtime.in"
+ addFunc(ve, run::gen_runtime71, primBoolean(), SYM(interactive));
+#line 646 "runtime.in"
+ addFunc(ve, run::gen_runtime72, primBoolean(), SYM(uptodate));
+#line 651 "runtime.in"
+ addFunc(ve, run::gen_runtime73, primInt(), SYM(system), formal(stringArray(), SYM(s), false, false));
+#line 665 "runtime.in"
+ addFunc(ve, run::gen_runtime74, primBoolean(), SYM(view));
+#line 670 "runtime.in"
+ addFunc(ve, run::gen_runtime75, primString(), SYM(asydir));
#line 675 "runtime.in"
- addFunc(ve, run::gen_runtime76, primVoid(), SYM(abort), formal(primString(), SYM(s), true, false));
+ addFunc(ve, run::gen_runtime76, primString(), SYM(locale), formal(primString(), SYM(s), true, false));
#line 681 "runtime.in"
- addFunc(ve, run::gen_runtime77, primVoid(), SYM(exit));
-#line 686 "runtime.in"
- addFunc(ve, run::gen_runtime78, primVoid(), SYM(assert), formal(primBoolean(), SYM(b), false, false), formal(primString(), SYM(s), true, false));
-#line 697 "runtime.in"
- addFunc(ve, run::gen_runtime79, primVoid(), SYM(sleep), formal(primInt(), SYM(seconds), false, false));
+ addFunc(ve, run::gen_runtime77, primVoid(), SYM(abort), formal(primString(), SYM(s), true, false));
+#line 687 "runtime.in"
+ addFunc(ve, run::gen_runtime78, primVoid(), SYM(exit));
+#line 692 "runtime.in"
+ addFunc(ve, run::gen_runtime79, primVoid(), SYM(assert), formal(primBoolean(), SYM(b), false, false), formal(primString(), SYM(s), true, false));
#line 703 "runtime.in"
- addFunc(ve, run::gen_runtime80, primVoid(), SYM(usleep), formal(primInt(), SYM(microseconds), false, false));
+ addFunc(ve, run::gen_runtime80, primVoid(), SYM(sleep), formal(primInt(), SYM(seconds), false, false));
#line 709 "runtime.in"
- addFunc(ve, run::gen_runtime81, primVoid(), SYM(_eval), formal(primString(), SYM(s), false, false), formal(primBoolean(), SYM(embedded), false, false), formal(primBoolean(), SYM(interactivewrite), true, false));
-#line 722 "runtime.in"
- addFunc(ve, run::gen_runtime82, primVoid(), SYM(_eval), formal(primCode(), SYM(s), false, false), formal(primBoolean(), SYM(embedded), false, false));
-#line 738 "runtime.in"
- addFunc(ve, run::gen_runtime83, primString(), SYM(xasyKEY));
-#line 745 "runtime.in"
- addFunc(ve, run::gen_runtime84, primVoid(), SYM(xasyKEY), formal(primString(), SYM(s), false, false));
-#line 749 "runtime.in"
- addFunc(ve, run::gen_runtime85, primString(), SYM(toplocation));
-#line 753 "runtime.in"
+ addFunc(ve, run::gen_runtime81, primVoid(), SYM(usleep), formal(primInt(), SYM(microseconds), false, false));
+#line 715 "runtime.in"
+ addFunc(ve, run::gen_runtime82, primVoid(), SYM(_eval), formal(primString(), SYM(s), false, false), formal(primBoolean(), SYM(embedded), false, false), formal(primBoolean(), SYM(interactivewrite), true, false));
+#line 728 "runtime.in"
+ addFunc(ve, run::gen_runtime83, primVoid(), SYM(_eval), formal(primCode(), SYM(s), false, false), formal(primBoolean(), SYM(embedded), false, false));
+#line 744 "runtime.in"
+ addFunc(ve, run::gen_runtime84, primString(), SYM(xasyKEY));
+#line 751 "runtime.in"
+ addFunc(ve, run::gen_runtime85, primVoid(), SYM(xasyKEY), formal(primString(), SYM(s), false, false));
+#line 755 "runtime.in"
addFunc(ve, run::gen_runtime86, primString(), SYM(location));
-#line 759 "runtime.in"
+#line 761 "runtime.in"
REGISTER_BLTIN(run::loadModule,"loadModule");
-#line 765 "runtime.in"
+#line 767 "runtime.in"
addFunc(ve, run::gen_runtime88, primString(), SYM(cd), formal(primString(), SYM(s), true, false));
-#line 776 "runtime.in"
+#line 778 "runtime.in"
addFunc(ve, run::gen_runtime89, primVoid(), SYM(list), formal(primString(), SYM(s), false, false), formal(primBoolean(), SYM(imports), true, false));
-#line 785 "runtime.in"
+#line 787 "runtime.in"
REGISTER_BLTIN(run::nullGuide,"nullGuide");
-#line 793 "runtime.in"
+#line 795 "runtime.in"
REGISTER_BLTIN(run::dotsGuide,"dotsGuide");
-#line 803 "runtime.in"
+#line 805 "runtime.in"
REGISTER_BLTIN(run::dashesGuide,"dashesGuide");
-#line 830 "runtime.in"
+#line 832 "runtime.in"
REGISTER_BLTIN(run::newCycleToken,"newCycleToken");
-#line 835 "runtime.in"
+#line 837 "runtime.in"
addFunc(ve, run::gen_runtime94, primGuide(), symbol::trans("operator cast"), formal(primCycleToken(), SYM(tok), false, false));
-#line 842 "runtime.in"
+#line 844 "runtime.in"
addFunc(ve, run::gen_runtime95, primGuide(), symbol::trans("operator spec"), formal(primPair(), SYM(z), false, false), formal(primInt(), SYM(p), false, false));
-#line 850 "runtime.in"
+#line 852 "runtime.in"
addFunc(ve, run::gen_runtime96, primCurlSpecifier(), SYM_CURL, formal(primReal(), SYM(gamma), false, false), formal(primInt(), SYM(p), false, false));
-#line 856 "runtime.in"
+#line 858 "runtime.in"
REGISTER_BLTIN(run::curlSpecifierValuePart,"curlSpecifierValuePart");
-#line 861 "runtime.in"
+#line 863 "runtime.in"
REGISTER_BLTIN(run::curlSpecifierSidePart,"curlSpecifierSidePart");
-#line 866 "runtime.in"
+#line 868 "runtime.in"
addFunc(ve, run::gen_runtime99, primGuide(), symbol::trans("operator cast"), formal(primCurlSpecifier(), SYM(spec), false, false));
-#line 871 "runtime.in"
+#line 873 "runtime.in"
addFunc(ve, run::gen_runtime100, primTensionSpecifier(), SYM_TENSION, formal(primReal(), SYM(tout), false, false), formal(primReal(), SYM(tin), false, false), formal(primBoolean(), SYM(atleast), false, false));
-#line 876 "runtime.in"
+#line 878 "runtime.in"
REGISTER_BLTIN(run::tensionSpecifierOutPart,"tensionSpecifierOutPart");
-#line 881 "runtime.in"
+#line 883 "runtime.in"
REGISTER_BLTIN(run::tensionSpecifierInPart,"tensionSpecifierInPart");
-#line 886 "runtime.in"
+#line 888 "runtime.in"
REGISTER_BLTIN(run::tensionSpecifierAtleastPart,"tensionSpecifierAtleastPart");
-#line 891 "runtime.in"
+#line 893 "runtime.in"
addFunc(ve, run::gen_runtime104, primGuide(), symbol::trans("operator cast"), formal(primTensionSpecifier(), SYM(t), false, false));
-#line 896 "runtime.in"
+#line 898 "runtime.in"
addFunc(ve, run::gen_runtime105, primGuide(), SYM_CONTROLS, formal(primPair(), SYM(zout), false, false), formal(primPair(), SYM(zin), false, false));
-#line 901 "runtime.in"
+#line 903 "runtime.in"
addFunc(ve, run::gen_runtime106, primInt(), SYM(size), formal(primGuide(), SYM(g), false, false));
-#line 908 "runtime.in"
+#line 910 "runtime.in"
addFunc(ve, run::gen_runtime107, primInt(), SYM(length), formal(primGuide(), SYM(g), false, false));
-#line 915 "runtime.in"
+#line 917 "runtime.in"
addFunc(ve, run::gen_runtime108, primBoolean(), SYM(cyclic), formal(primGuide(), SYM(g), false, false));
-#line 922 "runtime.in"
+#line 924 "runtime.in"
addFunc(ve, run::gen_runtime109, primPair(), SYM(point), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
-#line 929 "runtime.in"
+#line 931 "runtime.in"
addFunc(ve, run::gen_runtime110, pairArray(), SYM(dirSpecifier), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
-#line 941 "runtime.in"
+#line 943 "runtime.in"
addFunc(ve, run::gen_runtime111, pairArray(), SYM(controlSpecifier), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
-#line 958 "runtime.in"
+#line 960 "runtime.in"
addFunc(ve, run::gen_runtime112, primTensionSpecifier(), SYM(tensionSpecifier), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
-#line 968 "runtime.in"
+#line 970 "runtime.in"
addFunc(ve, run::gen_runtime113, realArray(), SYM(curlSpecifier), formal(primGuide(), SYM(g), false, false), formal(primInt(), SYM(t), false, false));
-#line 982 "runtime.in"
+#line 984 "runtime.in"
addFunc(ve, run::gen_runtime114, primGuide(), SYM(reverse), formal(primGuide(), SYM(g), false, false));
-#line 1035 "runtime.in"
+#line 1037 "runtime.in"
addFunc(ve, run::gen_runtime115, realArray(), SYM(_cputime));
-#line 1050 "runtime.in"
+#line 1052 "runtime.in"
addFunc(ve, run::gen_runtime116, primBoolean(), SYM_EQ, formal(primTransform(), SYM(a), false, false), formal(primTransform(), SYM(b), false, false));
-#line 1058 "runtime.in"
+#line 1060 "runtime.in"
addFunc(ve, run::gen_runtime117, primBoolean(), SYM_NEQ, formal(primTransform(), SYM(a), false, false), formal(primTransform(), SYM(b), false, false));
-#line 1063 "runtime.in"
+#line 1065 "runtime.in"
addFunc(ve, run::gen_runtime118, primTransform(), SYM_PLUS, formal(primTransform(), SYM(a), false, false), formal(primTransform(), SYM(b), false, false));
-#line 1068 "runtime.in"
+#line 1070 "runtime.in"
addFunc(ve, run::gen_runtime119, primTransform(), SYM_TIMES, formal(primTransform(), SYM(a), false, false), formal(primTransform(), SYM(b), false, false));
-#line 1073 "runtime.in"
+#line 1075 "runtime.in"
addFunc(ve, run::gen_runtime120, primPair(), SYM_TIMES, formal(primTransform(), SYM(t), false, false), formal(primPair(), SYM(z), false, false));
-#line 1078 "runtime.in"
+#line 1080 "runtime.in"
addFunc(ve, run::gen_runtime121, primPath(), SYM_TIMES, formal(primTransform(), SYM(t), false, false), formal(primPath(), SYM(g), false, false));
-#line 1083 "runtime.in"
+#line 1085 "runtime.in"
addFunc(ve, run::gen_runtime122, primPen(), SYM_TIMES, formal(primTransform(), SYM(t), false, false), formal(primPen(), SYM(p), false, false));
-#line 1088 "runtime.in"
+#line 1090 "runtime.in"
addFunc(ve, run::gen_runtime123, primPicture(), SYM_TIMES, formal(primTransform(), SYM(t), false, false), formal(primPicture(), SYM(f), false, false));
-#line 1093 "runtime.in"
+#line 1095 "runtime.in"
addFunc(ve, run::gen_runtime124, primPicture(), SYM_TIMES, formal(realArray2(), SYM(t), false, false), formal(primPicture(), SYM(f), false, false));
-#line 1098 "runtime.in"
+#line 1100 "runtime.in"
addFunc(ve, run::gen_runtime125, primTransform(), SYM_CARET, formal(primTransform(), SYM(t), false, false), formal(primInt(), SYM(n), false, false));
-#line 1109 "runtime.in"
+#line 1111 "runtime.in"
REGISTER_BLTIN(run::transformXPart,"transformXPart");
-#line 1114 "runtime.in"
+#line 1116 "runtime.in"
REGISTER_BLTIN(run::transformYPart,"transformYPart");
-#line 1119 "runtime.in"
+#line 1121 "runtime.in"
REGISTER_BLTIN(run::transformXXPart,"transformXXPart");
-#line 1124 "runtime.in"
+#line 1126 "runtime.in"
REGISTER_BLTIN(run::transformXYPart,"transformXYPart");
-#line 1129 "runtime.in"
+#line 1131 "runtime.in"
REGISTER_BLTIN(run::transformYXPart,"transformYXPart");
-#line 1134 "runtime.in"
+#line 1136 "runtime.in"
REGISTER_BLTIN(run::transformYYPart,"transformYYPart");
-#line 1139 "runtime.in"
+#line 1141 "runtime.in"
REGISTER_BLTIN(run::real6ToTransform,"real6ToTransform");
-#line 1145 "runtime.in"
+#line 1147 "runtime.in"
addFunc(ve, run::gen_runtime133, primTransform(), SYM(shift), formal(primTransform(), SYM(t), false, false));
-#line 1150 "runtime.in"
+#line 1152 "runtime.in"
addFunc(ve, run::gen_runtime134, primTransform(), SYM(shiftless), formal(primTransform(), SYM(t), false, false));
-#line 1155 "runtime.in"
+#line 1157 "runtime.in"
addFunc(ve, run::transformIdentity, primTransform(), SYM(identity));
-#line 1160 "runtime.in"
+#line 1162 "runtime.in"
addFunc(ve, run::gen_runtime136, primTransform(), SYM(inverse), formal(primTransform(), SYM(t), false, false));
-#line 1165 "runtime.in"
+#line 1167 "runtime.in"
addFunc(ve, run::gen_runtime137, primTransform(), SYM(shift), formal(primPair(), SYM(z), false, false));
-#line 1170 "runtime.in"
+#line 1172 "runtime.in"
addFunc(ve, run::gen_runtime138, primTransform(), SYM(shift), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
-#line 1175 "runtime.in"
+#line 1177 "runtime.in"
addFunc(ve, run::gen_runtime139, primTransform(), SYM(xscale), formal(primReal(), SYM(x), false, false));
-#line 1180 "runtime.in"
+#line 1182 "runtime.in"
addFunc(ve, run::gen_runtime140, primTransform(), SYM(yscale), formal(primReal(), SYM(y), false, false));
-#line 1185 "runtime.in"
+#line 1187 "runtime.in"
addFunc(ve, run::gen_runtime141, primTransform(), SYM(scale), formal(primReal(), SYM(x), false, false));
-#line 1190 "runtime.in"
+#line 1192 "runtime.in"
addFunc(ve, run::gen_runtime142, primTransform(), SYM(scale), formal(primReal(), SYM(x), false, false), formal(primReal(), SYM(y), false, false));
-#line 1195 "runtime.in"
+#line 1197 "runtime.in"
addFunc(ve, run::gen_runtime143, primTransform(), SYM(slant), formal(primReal(), SYM(s), false, false));
-#line 1200 "runtime.in"
+#line 1202 "runtime.in"
addFunc(ve, run::gen_runtime144, primTransform(), SYM(rotate), formal(primReal(), SYM(angle), false, false), formal(primPair(), SYM(z), true, false));
-#line 1205 "runtime.in"
+#line 1207 "runtime.in"
addFunc(ve, run::gen_runtime145, primTransform(), SYM(reflect), formal(primPair(), SYM(a), false, false), formal(primPair(), SYM(b), false, false));
-#line 1210 "runtime.in"
+#line 1212 "runtime.in"
addFunc(ve, run::gen_runtime146, primBoolean(), SYM(isometry), formal(primTransform(), SYM(t), false, false));
}
diff --git a/graphics/asymptote/runtime.in b/graphics/asymptote/runtime.in
index 27cde40074..1f67200f5d 100644
--- a/graphics/asymptote/runtime.in
+++ b/graphics/asymptote/runtime.in
@@ -199,7 +199,8 @@ void writestring(stack *s)
}
}
-string toplocation() {
+string toplocation()
+{
ostringstream buf;
position& topPos=processData().topPos;
buf << topPos.Line() << "." << topPos.Column();
@@ -438,6 +439,11 @@ Int byte(real x)
return camp::byte(x);
}
+real byteinv(Int x)
+{
+ return x >= 0 ? camp::byteinv(x) : 0.0;
+}
+
string colorspace(pen p)
{
string s=ColorDeviceSuffix[p.colorspace()];
@@ -736,20 +742,16 @@ void _eval(runnable *s, bool embedded)
}
string xasyKEY() {
- processDataStruct *P=&processData();
- xkey_t *xkey=&P->xkey;
- xkey_t::iterator p=xkey->find(P->topPos.LineColumn());
- return p != xkey->end() ? p->second+" 1" : toplocation()+" 0";
+ processDataStruct& P=processData();
+ xkey_t& xkey=P.xkey;
+ xkey_t::iterator p=xkey.find(P.topPos.LineColumn());
+ return p != xkey.end() ? p->second+" 1" : toplocation()+" 0";
}
void xasyKEY(string *s) {
processData().KEY=*s;
}
-string toplocation() {
- return toplocation();
-}
-
string location() {
ostringstream buf;
buf << getPos();
diff --git a/graphics/asymptote/runtime.pl b/graphics/asymptote/runtime.pl
index 5724b40f8e..4a694c60bc 100755
--- a/graphics/asymptote/runtime.pl
+++ b/graphics/asymptote/runtime.pl
@@ -5,7 +5,7 @@
#
# Generate the runtime functions used by the vm::stack machine.
#
-#####
+#####
$prefix = shift(@ARGV);
if (not $prefix) {
@@ -57,7 +57,7 @@ sub read_types {
# Skip blank lines.
next if /^\s*$/;
- my ($type,$code) =
+ my ($type,$code) =
m|(\w*(?:\s*\*)?)
\s*=>\s*
(.*)
@@ -101,7 +101,7 @@ sub asy_params {
my $filename = shift;
my $line = shift;
for (@params) {
- my ($explicit, $type, $name, $default) =
+ my ($explicit, $type, $name, $default) =
m|^\s*
(explicit)*\s*(\w*(?:\s*\*)?)
\s*
@@ -111,8 +111,8 @@ sub asy_params {
assoc_error($filename, $line, $type);
}
$_ = "formal(" . $type_map{$type} . ", " .
- symbolize(lc($name)) . ", " .
- ($default ? "true" : "false") . ", " .
+ symbolize(lc($name)) . ", " .
+ ($default ? "true" : "false") . ", " .
($explicit ? "true" : "false") . ")";
}
return @params;
@@ -121,7 +121,7 @@ sub asy_params {
sub c_params {
my @params = @_;
for (@params) {
- my ($explicit, $type, $name, $default, $value) =
+ my ($explicit, $type, $name, $default, $value) =
m|^\s*
(explicit)*\s*(\w*(?:\s*\*)?)
\s*
@@ -138,6 +138,9 @@ open STDIN, "<$prefix.in" or die "can't open input file $prefix.in";
open BASE, "<runtimebase.in" or die "can't open runtimebase.in";
open STDOUT, ">$prefix.cc" or die "can't open output file $prefix.cc";
+binmode STDIN, ":unix:crlf";
+binmode BASE, ":unix:crlf";
+
my $autogenerated=
"/***** Autogenerated from $prefix.in; changes will be overwritten *****/\n\n";
@@ -192,7 +195,7 @@ push @header, "namespace run {\n";
my $count = 0;
while (<>) {
- my ($comments,$type,$name,$cname,$params,$code) =
+ my ($comments,$type,$name,$cname,$params,$code) =
m|^((?:\s*//[^\n]*\n)*) # comment lines
\s*
(\w*(?:\s*\*)?) # return type
@@ -210,9 +213,9 @@ while (<>) {
if($cname) {push @header, "void $cname(vm::stack *);\n";}
else {$cname="gen_$prefix${count}";} # Unique C++ function name
-
+
clean_type($type);
-
+
my @params = split m/,\s*/, $params;
# Build addFunc call for asymptote
@@ -223,7 +226,7 @@ while (<>) {
}
my @asy_params = asy_params($params, "$prefix.in", $source_line);
push @builtin, "#line $source_line \"$prefix.in\"\n"
- . " addFunc(ve, run::" . $cname
+ . " addFunc(ve, run::" . $cname
. ", " . $type_map{$type}
. ", " . symbolize($name)
. ( @params ? ", " . join(", ",@asy_params)
@@ -260,7 +263,7 @@ while (<>) {
print ")\n{\n$args";
print "#line $source_line \"$prefix.in\"";
print "$code}\n\n";
-
+
$source_line -= $ncomments+$nprototype;
$source_line += ($_ =~ tr/\n//);
++$count;
diff --git a/graphics/asymptote/settings.cc b/graphics/asymptote/settings.cc
index d3f8958470..ce5a5f8f47 100644
--- a/graphics/asymptote/settings.cc
+++ b/graphics/asymptote/settings.cc
@@ -224,6 +224,7 @@ char *argv0;
// The verbosity setting, a global variable.
Int verbose;
+bool quiet=false;
// Conserve memory at the expense of speed.
bool compact;
@@ -945,10 +946,12 @@ struct versionOption : public option {
bool glm=false;
bool gl=false;
+ bool ssbo=false;
bool gsl=false;
bool fftw3=false;
bool xdr=false;
bool curl=false;
+ bool lsp=false;
bool readline=false;
bool editline=false;
bool sigsegv=false;
@@ -962,6 +965,10 @@ struct versionOption : public option {
gl=true;
#endif
+#ifdef HAVE_SSBO
+ ssbo=true;
+#endif
+
#ifdef HAVE_LIBGSL
gsl=true;
#endif
@@ -978,6 +985,10 @@ struct versionOption : public option {
curl=true;
#endif
+#ifdef HAVE_LSP
+ lsp=true;
+#endif
+
#ifdef HAVE_LIBCURSES
#ifdef HAVE_LIBREADLINE
readline=true;
@@ -1002,10 +1013,12 @@ struct versionOption : public option {
#else
feature("OpenGL 3D OpenGL rendering",gl);
#endif
+ feature("SSBO GLSL shader storage buffer objects",ssbo);
feature("GSL GNU Scientific Library (special functions)",gsl);
feature("FFTW3 Fast Fourier transforms",fftw3);
- feature("XDR external data representation (portable binary file format)",xdr);
+ feature("XDR external data representation (portable binary file format for V3D)",xdr);
feature("CURL URL support",curl);
+ feature("lsp language server protocol",lsp);
feature("Readline interactive history and editing",readline);
if(!readline)
feature("Editline interactive editing (if Readline is unavailable)",editline);
@@ -1202,15 +1215,16 @@ void initSettings() {
addOption(new boolSetting("svgemulation", 0,
"Emulate unimplemented SVG shading", true));
addOption(new boolSetting("prc", 0,
- "Embed 3D PRC graphics in PDF output", true));
+ "Embed 3D PRC graphics in PDF output", false));
addOption(new boolSetting("toolbar", 0,
"Show 3D toolbar in PDF output", true));
addOption(new boolSetting("axes3", 0,
"Show 3D axes in PDF output", true));
- addOption(new boolSetting("envmap", 0,
- "Enable environment map image-based lighting (Experimental)", false));
-
-
+ addOption(new boolSetting("ibl", 0,
+ "Enable environment map image-based lighting", false));
+ addOption(new stringSetting("image", 0,"string","Environment image name","snowyField"));
+ addOption(new stringSetting("imageDir", 0,"string","Environment image library directory","ibl"));
+ addOption(new stringSetting("imageURL", 0,"string","Environment image library URL","https://vectorgraphics.gitlab.io/asymptote/ibl"));
addOption(new realSetting("render", 0, "n",
"Render 3D graphics using n pixels per bp (-1=auto)",
havegl ? -1.0 : 0.0));
@@ -1222,6 +1236,9 @@ void initSettings() {
addOption(new boolSetting("twosided", 0,
"Use two-sided 3D lighting model for rendering",
true));
+ addOption(new boolSetting("GPUindexing", 0,
+ "Compute indexing partial sums on GPU", true));
+
addOption(new pairSetting("position", 0, "pair",
"Initial 3D rendering screen position"));
addOption(new pairSetting("maxviewport", 0, "pair",
@@ -1229,6 +1246,8 @@ void initSettings() {
addOption(new pairSetting("viewportmargin", 0, "pair",
"Horizontal and vertical 3D viewport margin",
pair(0.5,0.5)));
+ addOption(new boolSetting("webgl2", 0,
+ "Use webgl2 if available", false));
addOption(new boolSetting("absolute", 0,
"Use absolute WebGL dimensions", false));
addOption(new pairSetting("maxtile", 0, "pair",
@@ -1293,6 +1312,10 @@ void initSettings() {
"Show translated virtual machine code"));
addOption(new boolSetting("tabcompletion", 0,
"Interactive prompt auto-completion", true));
+ addOption(new realSetting("prerender", 0, "resolution",
+ "Prerender V3D objects (0 implies vector output)", 0));
+ addOption(new boolSetting("lossy", 0,
+ "Use single precision for V3D reals", false));
addOption(new boolSetting("listvariables", 'l',
"List available global functions and variables"));
addOption(new boolSetting("where", 0,
@@ -1342,6 +1365,10 @@ void initSettings() {
"Input code over multiple lines at the prompt"));
addOption(new boolSetting("xasy", 0,
"Special interactive mode for xasy"));
+ addOption(new boolSetting("lsp", 0, "Special interactive mode for lsp-rpc"));
+ addOption(new boolSetting("wsl", 0, "Set to WSL mode when running asy inside WSL."));
+ addOption(new envSetting("lspport", ""));
+ addOption(new envSetting("lsphost", "127.0.0.1"));
addOption(new boolSetting("wait", 0,
"Wait for child processes to finish before exiting"));
@@ -1412,6 +1439,8 @@ void initSettings() {
addOption(new stringSetting("dvipsOptions", 0, "string", ""));
addOption(new stringSetting("dvisvgmOptions", 0, "string", ""));
+ addOption(new boolSetting("dvisvgmMultipleFiles", 0,
+ "dvisvgm supports multiple files", false));
addOption(new stringSetting("convertOptions", 0, "string", ""));
addOption(new stringSetting("gsOptions", 0, "string", ""));
addOption(new stringSetting("htmlviewerOptions", 0, "string", ""));
@@ -1456,9 +1485,15 @@ char *getArg(int n) { return argList[n]; }
void setInteractive()
{
+ bool xasy=getSetting<bool>("xasy");
+ if(xasy && getSetting<Int>("outpipe") < 0) {
+ cerr << "Missing outpipe." << endl;
+ exit(-1);
+ }
+
if(numArgs() == 0 && !getSetting<bool>("listvariables") &&
getSetting<string>("command").empty() &&
- (isatty(STDIN_FILENO) || getSetting<Int>("xasy")))
+ (isatty(STDIN_FILENO) || xasy || getSetting<Int>("lsp")))
interact::interactive=true;
if(getSetting<bool>("localhistory"))
@@ -1468,7 +1503,7 @@ void setInteractive()
cerr << "failed to create directory "+initdir+"." << endl;
historyname=initdir+"/history";
}
- if(verbose > 1)
+ if(!quiet && verbose > 1)
cerr << "Using history " << historyname << endl;
}
@@ -1543,7 +1578,7 @@ void initDir() {
umask(mask);
#endif
if(access(initdir.c_str(),F_OK) == 0) {
- if(verbose > 1)
+ if(!quiet && verbose > 1)
cerr << "Using configuration directory " << initdir << endl;
}
}
@@ -1683,6 +1718,17 @@ const char *endpicture(const string& texengine)
return "\\endpicture%";
}
+// TeX macro to begin new page.
+const char *newpage(const string& texengine)
+{
+ if(latex(texengine))
+ return "\\newpage";
+ else if(context(texengine))
+ return "}\\page\\hbox{%";
+ else
+ return "\\eject";
+}
+
// Begin TeX special command.
const char *beginspecial(const string& texengine)
{
@@ -1756,9 +1802,12 @@ void setOptions(int argc, char *argv[])
// Build settings module.
initSettings();
- // Read command-line options initially to obtain config, dir, sysdir, verbose.
+ // Read command-line options initially to obtain config, dir, sysdir,
+ // verbose, and quiet.
getOptions(argc,argv);
+ quiet=getSetting<bool>("quiet");
+
// Make configuration and history directory
initDir();
@@ -1773,7 +1822,7 @@ void setOptions(int argc, char *argv[])
if(!filename.empty()) {
string file=locateFile(filename);
if(!file.empty()) {
- if(Verbose > 1)
+ if(!quiet && Verbose > 1)
cerr << "Loading " << filename << " from " << file << endl;
doConfig(file);
}
diff --git a/graphics/asymptote/settings.h b/graphics/asymptote/settings.h
index 6ff7a5de4b..6d55aae962 100644
--- a/graphics/asymptote/settings.h
+++ b/graphics/asymptote/settings.h
@@ -105,6 +105,7 @@ bool context(const string& texengine);
string nativeformat();
string defaultformat();
+const char *newpage(const string& texengine);
const char *beginlabel(const string& texengine);
const char *endlabel(const string& texengine);
const char *rawpostscript(const string& texengine);
diff --git a/graphics/asymptote/shaders.cc b/graphics/asymptote/shaders.cc
index a9c038c229..55bd17a889 100644
--- a/graphics/asymptote/shaders.cc
+++ b/graphics/asymptote/shaders.cc
@@ -13,9 +13,11 @@
#include "shaders.h"
+int GLSLversion;
+
GLuint compileAndLinkShader(std::vector<ShaderfileModePair> const& shaders,
- size_t Nlights, size_t NMaterials,
- std::vector<std::string> const& defineflags)
+ std::vector<std::string> const& defineflags,
+ bool compute)
{
GLuint shader = glCreateProgram();
std::vector<GLuint> compiledShaders;
@@ -23,7 +25,8 @@ GLuint compileAndLinkShader(std::vector<ShaderfileModePair> const& shaders,
size_t n=shaders.size();
for(size_t i=0; i < n; ++i) {
GLint newshader=createShaderFile(shaders[i].first,shaders[i].second,
- Nlights,NMaterials,defineflags);
+ defineflags,compute);
+ if(compute && newshader == 0) return 0;
glAttachShader(shader,newshader);
compiledShaders.push_back(newshader);
}
@@ -44,17 +47,19 @@ GLuint compileAndLinkShader(std::vector<ShaderfileModePair> const& shaders,
return shader;
}
-GLuint createShaders(GLchar const* src, int shaderType,
- std::string const& filename)
+GLuint createShader(const std::string& src, int shaderType,
+ const std::string& filename, bool compute)
{
+ const GLchar *source=src.c_str();
GLuint shader=glCreateShader(shaderType);
- glShaderSource(shader, 1, &src, NULL);
+ glShaderSource(shader, 1, &source, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(status != GL_TRUE) {
+ if(compute) return 0;
GLint length;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
@@ -64,50 +69,50 @@ GLuint createShaders(GLchar const* src, int shaderType,
glGetShaderInfoLog(shader, length, &length, msg.data());
size_t n=msg.size();
- for(size_t i=0; i < n; ++i) {
+ for(size_t i=0; i < n; ++i)
std::cerr << msg[i];
- }
std::cerr << std::endl << "GL Compile error" << std::endl;
- std::cerr << src << std::endl;
- throw 1;
+ std::stringstream s(src);
+ std::string line;
+ unsigned int k=0;
+ while(getline(s,line))
+ std::cerr << ++k << ": " << line << std::endl;
+ exit(-1);
}
return shader;
}
-GLuint createShaderFile(std::string file, int shaderType, size_t Nlights,
- size_t Nmaterials,
- std::vector<std::string> const& defineflags)
+GLuint createShaderFile(std::string file, int shaderType,
+ std::vector<std::string> const& defineflags,
+ bool compute)
{
std::ifstream shaderFile;
shaderFile.open(file.c_str());
std::stringstream shaderSrc;
-#ifdef __APPLE__
-#define GLSL_VERSION "410"
-#else
-#define GLSL_VERSION "130"
+ shaderSrc << "#version " << GLSLversion << "\n";
+#ifndef __APPLE__
+ shaderSrc << "#extension GL_ARB_uniform_buffer_object : enable" << "\n";
+#ifdef HAVE_SSBO
+ shaderSrc << "#extension GL_ARB_shader_storage_buffer_object : enable" << "\n";
+ if(compute)
+ shaderSrc << "#extension GL_ARB_compute_shader : enable" << "\n";
+#endif
#endif
-
- shaderSrc << "#version " << GLSL_VERSION << "\n";
- shaderSrc << "#extension GL_ARB_uniform_buffer_object : enable"
- << "\n";
size_t n=defineflags.size();
- for(size_t i=0; i < n; ++i) {
+ for(size_t i=0; i < n; ++i)
shaderSrc << "#define " << defineflags[i] << "\n";
- }
-
- shaderSrc << "#define Nlights " << Nlights << "\n";
- shaderSrc << "const int Nmaterials=" << Nmaterials << ";\n";
if(shaderFile) {
shaderSrc << shaderFile.rdbuf();
shaderFile.close();
} else {
- throw 1;
+ std::cerr << "Cannot read from shader file " << file << std::endl;
+ exit(-1);
}
- return createShaders(shaderSrc.str().data(), shaderType, file);
+ return createShader(shaderSrc.str(),shaderType,file,compute);
}
#endif
diff --git a/graphics/asymptote/shaders.h b/graphics/asymptote/shaders.h
index be2441a66b..9c0a946dc4 100644
--- a/graphics/asymptote/shaders.h
+++ b/graphics/asymptote/shaders.h
@@ -18,18 +18,20 @@
#include <string>
+extern int GLSLversion;
+
typedef std::pair<std::string, int> ShaderfileModePair;
GLuint compileAndLinkShader(
- std::vector<ShaderfileModePair> const& shaders, size_t NLights,
- size_t NMaterials, std::vector<std::string> const& defineflags);
+ std::vector<ShaderfileModePair> const& shaders,
+ std::vector<std::string> const& defineflags, bool compute=false);
-GLuint createShaders(GLchar const *src, int shaderType,
- std::string const& filename);
+GLuint createShaders(const std::string& src, int shaderType,
+ std::string const& filename, bool compute=false);
-GLuint createShaderFile(std::string file, int shaderType, size_t Nlights,
- size_t Nmaterials,
- std::vector<std::string> const& constflags);
+GLuint createShaderFile(std::string file, int shaderType,
+ std::vector<std::string> const& constflags,
+ bool compute=false);
enum attrib {positionAttrib=0,normalAttrib,materialAttrib,colorAttrib,
widthAttrib};
diff --git a/graphics/asymptote/stack.cc b/graphics/asymptote/stack.cc
index a854a9d9ef..7c0d8a9195 100644
--- a/graphics/asymptote/stack.cc
+++ b/graphics/asymptote/stack.cc
@@ -336,8 +336,10 @@ void stack::runWithOrWithoutClosure(lambda *l, vars_t vars, vars_t parent)
/* start the new function */
program::label ip = l->code->begin();
- position& topPos=processData().topPos;
- string& fileName=processData().fileName;
+ processDataStruct& P=processData();
+ position& topPos=P.topPos;
+ string& fileName=P.fileName;
+ unsigned int offset=P.xmapCount;
try {
for (;;) {
@@ -345,7 +347,7 @@ void stack::runWithOrWithoutClosure(lambda *l, vars_t vars, vars_t parent)
curPos = i.pos;
if(curPos.filename() == fileName)
- topPos=curPos;
+ topPos=curPos.shift(offset);
#ifdef PROFILE
prof.recordInstruction();
diff --git a/graphics/asymptote/statistics.h b/graphics/asymptote/statistics.h
index f3c87c18d9..a8cca39bf4 100644
--- a/graphics/asymptote/statistics.h
+++ b/graphics/asymptote/statistics.h
@@ -1,8 +1,6 @@
#ifndef __statistics_h__
#define __statistics_h__ 1
-#include <math.h>
-
namespace utils {
class statistics {
@@ -11,7 +9,8 @@ class statistics {
double varL;
double varH;
public:
- statistics() : N(0), A(0.0), varL(0.0), varH(0.0) {}
+ statistics() {clear();}
+ void clear() {N=0; A=varL=varH=0.0;}
double count() {return N;}
double mean() {return A;}
void add(double t) {
diff --git a/graphics/asymptote/stm.cc b/graphics/asymptote/stm.cc
index 8cd74a0c34..17461a01d2 100644
--- a/graphics/asymptote/stm.cc
+++ b/graphics/asymptote/stm.cc
@@ -25,27 +25,33 @@ using namespace types;
void stm::prettyprint(ostream &out, Int indent)
{
- prettyname(out,"stm",indent);
+ prettyname(out,"stm",indent, getPos());
}
void emptyStm::prettyprint(ostream &out, Int indent)
{
- prettyname(out,"emptyStm",indent);
+ prettyname(out,"emptyStm",indent, getPos());
}
void blockStm::prettyprint(ostream &out, Int indent)
{
- prettyname(out,"blockStm",indent);
+ prettyname(out,"blockStm",indent, getPos());
base->prettyprint(out, indent+1);
}
+void blockStm::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ base->createSymMap(symContext->newContext(getPos().LineColumn()));
+#endif
+}
void expStm::prettyprint(ostream &out, Int indent)
{
- prettyname(out,"expStm",indent);
+ prettyname(out,"expStm",indent, getPos());
body->prettyprint(out, indent+1);
}
@@ -170,10 +176,16 @@ void expStm::interactiveTrans(coenv &e)
baseExpTrans(e, body);
}
+void expStm::createSymMap(AsymptoteLsp::SymbolContext* symContext) {
+#ifdef HAVE_LSP
+ body->createSymMap(symContext);
+#endif
+}
+
void ifStm::prettyprint(ostream &out, Int indent)
{
- prettyname(out,"ifStm",indent);
+ prettyname(out,"ifStm",indent, getPos());
test->prettyprint(out, indent+1);
onTrue->prettyprint(out, indent+1);
@@ -204,6 +216,19 @@ void ifStm::trans(coenv &e)
e.c.defLabel(end);
}
+ void ifStm::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+ {
+#ifdef HAVE_LSP
+ test->createSymMap(symContext);
+ onTrue->createSymMap(symContext);
+
+ if (onFalse)
+ {
+ onFalse->createSymMap(symContext);
+ }
+#endif
+ }
+
void transLoopBody(coenv &e, stm *body) {
// The semantics of the language are defined so that any variable declared
@@ -251,7 +276,7 @@ void transLoopBody(coenv &e, stm *body) {
void whileStm::prettyprint(ostream &out, Int indent)
{
- prettyname(out,"whileStm",indent);
+ prettyname(out,"whileStm",indent, getPos());
test->prettyprint(out, indent+1);
body->prettyprint(out, indent+1);
@@ -273,10 +298,29 @@ void whileStm::trans(coenv &e)
e.c.popLoop();
}
+void whileStm::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ // while (<xyz>) { <body> }
+ // the <xyz> part belongs in the main context as the while statement,
+ // as it cannot declare new variables and only knows the symbols from that context.
-void doStm::prettyprint(ostream &out, Int indent)
+ test->createSymMap(symContext);
+
+ // for the body part, { <body> } are encapsulated in
+ // the blockStm, while <body> are direct statements.
+ // If the while block does not use { <body> }, then the body
+ // can be considered the same context as it cannot declare new variables and again, can
+ // only uses the variable already known before this while statement.
+
+ body->createSymMap(symContext);
+#endif
+}
+
+
+ void doStm::prettyprint(ostream &out, Int indent)
{
- prettyname(out,"doStm",indent);
+ prettyname(out,"doStm",indent, getPos());
body->prettyprint(out, indent+1);
test->prettyprint(out, indent+1);
@@ -301,10 +345,18 @@ void doStm::trans(coenv &e)
e.c.popLoop();
}
+void doStm::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ body->createSymMap(symContext);
+ test->createSymMap(symContext);
+#endif
+}
+
void forStm::prettyprint(ostream &out, Int indent)
{
- prettyname(out,"forStm",indent);
+ prettyname(out,"forStm",indent, getPos());
if (init) init->prettyprint(out, indent+1);
if (test) test->prettyprint(out, indent+1);
@@ -343,6 +395,28 @@ void forStm::trans(coenv &e)
e.e.endScope();
}
+void forStm::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ AsymptoteLsp::SymbolContext* ctx(symContext);
+ if (init)
+ {
+ auto* declCtx(symContext->newContext(getPos().LineColumn()));
+ init->createSymMap(declCtx);
+ ctx = declCtx;
+ }
+ if (test)
+ {
+ test->createSymMap(ctx);
+ }
+ if (update)
+ {
+ update->createSymMap(ctx);
+ }
+ body->createSymMap(ctx);
+#endif
+}
+
void extendedForStm::prettyprint(ostream &out, Int indent)
{
prettyindent(out, indent);
@@ -421,10 +495,31 @@ void extendedForStm::trans(coenv &e) {
new blockStm(pos, &b)).trans(e);
}
+void extendedForStm::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ auto* declCtx(symContext->newContext(getPos().LineColumn()));
+
+ std::string varName(var);
+
+ // FIXME: How do we get the position of the actual variable name?
+ // Right now, we only get the starting position of the type declaration
+ declCtx->symMap.varDec.emplace(std::piecewise_construct,
+ std::forward_as_tuple(varName),
+ std::forward_as_tuple(
+ varName,
+ static_cast<std::string>(*start),
+ start->getPos().LineColumn()
+ ));
+ set->createSymMap(symContext);
+ body->createSymMap(declCtx);
+#endif
+}
+
void breakStm::prettyprint(ostream &out, Int indent)
{
- prettyname(out,"breakStm",indent);
+ prettyname(out,"breakStm",indent, getPos());
}
void breakStm::trans(coenv &e)
@@ -438,7 +533,7 @@ void breakStm::trans(coenv &e)
void continueStm::prettyprint(ostream &out, Int indent)
{
- prettyname(out,"continueStm",indent);
+ prettyname(out,"continueStm",indent, getPos());
}
void continueStm::trans(coenv &e)
@@ -452,7 +547,7 @@ void continueStm::trans(coenv &e)
void returnStm::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "returnStm",indent);
+ prettyname(out, "returnStm",indent, getPos());
if (value)
value->prettyprint(out, indent+1);
@@ -485,10 +580,20 @@ void returnStm::trans(coenv &e)
e.c.encode(inst::ret);
}
+void returnStm::createSymMap(AsymptoteLsp::SymbolContext* symContext)
+{
+#ifdef HAVE_LSP
+ if (value)
+ {
+ value->createSymMap(symContext);
+ }
+#endif
+}
+
void stmExpList::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "stmExpList",indent);
+ prettyname(out, "stmExpList",indent, getPos());
for (mem::list<stm *>::iterator p = stms.begin(); p != stms.end(); ++p)
(*p)->prettyprint(out, indent+1);
diff --git a/graphics/asymptote/stm.h b/graphics/asymptote/stm.h
index 3f8d426014..3ce488985d 100644
--- a/graphics/asymptote/stm.h
+++ b/graphics/asymptote/stm.h
@@ -57,18 +57,19 @@ public:
blockStm(position pos, block *base)
: stm(pos), base(base) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void trans(coenv &e) {
+ void trans(coenv &e) override {
return base->trans(e);
}
// A block is guaranteed to return iff its last statement is
// guaranteed to return.
- bool returns() {
+ bool returns() override {
return base->returns();
}
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
// A statement that consist of a single expression to evaluate.
@@ -79,14 +80,15 @@ public:
expStm(position pos, exp *body)
: stm(pos), body(body) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void trans(coenv &e);
+ void trans(coenv &e) override;
// Should be called when running an expStm at the interactive prompt.
// The code will "write" the value of the expression at the prompt if
// possible.
- void interactiveTrans(coenv &e);
+ void interactiveTrans(coenv &e) override;
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
class ifStm : public stm {
@@ -98,17 +100,19 @@ public:
ifStm(position pos, exp *test, stm* onTrue, stm* onFalse = 0)
: stm(pos), test(test), onTrue(onTrue), onFalse(onFalse) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void trans(coenv &e);
+ void trans(coenv &e) override;
// An if statement is guaranteed to return iff both its pieces are
// guaranteed to return.
- bool returns() {
+ bool returns() override {
if (onTrue == 0 || onFalse == 0)
return false;
return onTrue->returns() && onFalse->returns();
}
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
class whileStm : public stm {
@@ -119,9 +123,12 @@ public:
whileStm(position pos, exp *test, stm *body)
: stm(pos), test(test), body(body) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void trans(coenv &e);
+
+ void trans(coenv &e) override;
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
class doStm : public stm {
@@ -132,9 +139,11 @@ public:
doStm(position pos, stm *body, exp *test)
: stm(pos), body(body), test(test) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void trans(coenv &e);
+ void trans(coenv &e) override;
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
class forStm : public stm {
@@ -147,9 +156,11 @@ public:
forStm(position pos, runnable *init, exp *test, runnable *update, stm *body)
: stm(pos), init(init), test(test), update(update), body(body) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void trans(coenv &e);
+ void trans(coenv &e) override;
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
class extendedForStm : public stm {
@@ -163,9 +174,11 @@ public:
extendedForStm(position pos, ty *start, symbol var, exp *set, stm *body)
: stm(pos), start(start), var(var), set(set), body(body) {}
- void prettyprint(ostream &out, Int indent);
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
- void trans(coenv &e);
+ void prettyprint(ostream &out, Int indent) override;
+
+ void trans(coenv &e) override;
};
@@ -174,9 +187,9 @@ public:
breakStm(position pos)
: stm(pos) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void trans(coenv &e);
+ void trans(coenv &e) override;
};
class continueStm : public stm {
@@ -184,9 +197,9 @@ public:
continueStm(position pos)
: stm(pos) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void trans(coenv &e);
+ void trans(coenv &e) override;
};
class returnStm : public stm {
@@ -196,14 +209,16 @@ public:
returnStm(position pos, exp *value = 0)
: stm(pos), value(value) {}
- void prettyprint(ostream &out, Int indent);
+ void prettyprint(ostream &out, Int indent) override;
- void trans(coenv &e);
+ void trans(coenv &e) override;
// A return statement is, of course, guaranteed to return.
- bool returns() {
+ bool returns() override {
return true;
}
+
+ void createSymMap(AsymptoteLsp::SymbolContext* symContext) override;
};
diff --git a/graphics/asymptote/symbol.cc b/graphics/asymptote/symbol.cc
index 512a6ab77d..df3673c715 100644
--- a/graphics/asymptote/symbol.cc
+++ b/graphics/asymptote/symbol.cc
@@ -324,6 +324,13 @@ symbol::operator string () const {
return (string)r.s;
}
+#ifdef USEGC
+symbol::operator std::string () const {
+ symbolRecord &r = recordByHashplus(this->hashplus);
+ return (std::string)r.s;
+}
+#endif
+
ostream& operator<< (ostream& out, const symbol sym)
{
symbolRecord &r = recordByHashplus(sym.hashplus);
diff --git a/graphics/asymptote/symbol.h b/graphics/asymptote/symbol.h
index 4386a510aa..b16d311934 100644
--- a/graphics/asymptote/symbol.h
+++ b/graphics/asymptote/symbol.h
@@ -29,6 +29,7 @@ struct GCInit {
GC_set_free_space_divisor(2);
mem::compact(0);
GC_INIT();
+ GC_allow_register_threads();
#endif
// Put the symbol table into a state where symbols can be translated.
@@ -112,6 +113,10 @@ struct symbol {
operator string () const;
+#ifdef USEGC
+ explicit operator std::string() const;
+#endif
+
friend ostream& operator<< (ostream& out, const symbol sym);
};
diff --git a/graphics/asymptote/symbolmaps.cc b/graphics/asymptote/symbolmaps.cc
new file mode 100644
index 0000000000..27c073e70b
--- /dev/null
+++ b/graphics/asymptote/symbolmaps.cc
@@ -0,0 +1,828 @@
+#include "common.h"
+
+#ifdef HAVE_LSP
+
+#include "symbolmaps.h"
+#include "locate.h"
+#include <unordered_map>
+
+namespace AsymptoteLsp
+{
+ [[nodiscard]]
+ bool isVirtualFile(std::string const& filename)
+ {
+ bool isSettings=filename=="settings";
+#ifdef HAVE_LIBGSL
+ bool isGSL=filename=="gsl" and settings::getSetting<bool>("gsl");
+#else
+ bool isGSL=false;
+#endif
+ return isSettings || isGSL;
+ }
+
+ std::string getPlainFile()
+ {
+ return std::string((std::string) settings::locateFile("plain", true).c_str());
+ }
+
+ positions::positions(filePos const& positionInFile)
+ {
+ add(positionInFile);
+ }
+
+ void positions::add(const filePos &positionInFile)
+ {
+ auto fileLoc=pos.find(positionInFile.first);
+ if (fileLoc == pos.end())
+ {
+ pos.emplace(positionInFile.first, std::vector<posInFile>{positionInFile.second});
+ } else
+ {
+ fileLoc->second.push_back(positionInFile.second);
+ }
+ }
+
+ ostream& operator <<(std::ostream& os, const SymbolMaps& sym)
+ {
+ os << "var decs:" << endl;
+ for (auto const& s : sym.varDec)
+ {
+ auto const& key=std::get<0>(s);
+ auto const& value=std::get<1>(s);
+ os << key << " " << value.pos.first << ":" << value.pos.second << endl;
+ }
+ return os;
+ }
+
+ optional<fullSymPosRangeInFile> SymbolMaps::searchSymbol(posInFile const& inputPos)
+ {
+ // FIXME: can be optimized by binary search.
+ for (auto const& s : usageByLines)
+ {
+ auto const& pos=std::get<0>(s);
+ auto const& syLit=std::get<1>(s);
+ size_t endCharacter = pos.second + syLit.name.length() - 1;
+ bool posMatches =
+ pos.first == inputPos.first and
+ pos.second <= inputPos.second and
+ inputPos.second <= endCharacter;
+ bool isOperator = syLit.name.find("operator ") == 0;
+ if (posMatches and !isOperator)
+ {
+ posInFile endPos(pos.first, endCharacter + 1);
+ return boost::make_optional(std::make_tuple(syLit, pos, endPos));
+ }
+ }
+ return nullopt;
+ }
+
+ FunctionInfo& SymbolMaps::addFunDef(
+ std::string const& funcName, posInFile const& position, std::string const& returnType)
+ {
+ auto fit=std::get<0>(funDec.emplace(std::piecewise_construct,
+ std::forward_as_tuple(funcName), std::forward_as_tuple()));
+
+ fit->second.emplace_back(funcName, position, returnType);
+ return fit->second.back();
+ }
+
+ std::pair<optional<fullSymPosRangeInFile>, SymbolContext*> SymbolContext::searchSymbol(posInFile const& inputPos)
+ {
+ auto currCtxSym = symMap.searchSymbol(inputPos);
+ if (currCtxSym.has_value())
+ {
+ return make_pair(currCtxSym, this);
+ }
+ // else, not found in currCtx;
+ for (auto& subContext : subContexts)
+ {
+ if (!posLt(inputPos, subContext->contextLoc))
+ {
+ auto v=subContext->searchSymbol(inputPos);
+ auto subCtxSym=std::get<0>(v);;
+ auto ctx=std::get<1>(v);
+ if (subCtxSym.has_value())
+ {
+ return make_pair(subCtxSym, ctx);
+ }
+ }
+ }
+ return make_pair(nullopt, nullptr);
+ }
+
+ SymbolInfo const* SymbolContext::searchVarRaw(std::string const& symbol) const
+ {
+ // local variable declarations
+ auto pt = symMap.varDec.find(symbol);
+ if (pt != symMap.varDec.end())
+ {
+ return &pt->second;
+ }
+
+ // otherwise, search parent.
+ return parent != nullptr ? parent->searchVarRaw(symbol) : nullptr;
+ }
+
+ optional<posRangeInFile> SymbolContext::searchVarDecl(
+ std::string const& symbol, optional<posInFile> const& position)
+ {
+ auto pt = symMap.varDec.find(symbol);
+ if (pt != symMap.varDec.end())
+ {
+ auto line = std::get<0>(pt->second.pos);
+ auto ch = std::get<1>(pt->second.pos);
+ if ((not position.has_value()) or (!posLt(position.value(), pt->second.pos)))
+ {
+ return std::make_tuple(getFileName().value_or(""),
+ pt->second.pos, std::make_pair(line, ch + symbol.length()));
+ }
+ }
+
+ auto ptFn = symMap.funDec.find(symbol);
+ if (ptFn != symMap.funDec.end() and !ptFn->second.empty())
+ {
+ // FIXME: Right now, we have no way of knowing the exact position of the
+ // start of where the function name is. As an example, we do not know
+ // where the exact position of
+ // real testFunction(...) { ...
+ // ^
+ auto ptValue = ptFn->second[0];
+ if ((not position.has_value()) or (!posLt(position.value(), ptValue.pos)))
+ {
+ return std::make_tuple(getFileName().value_or(""), ptValue.pos, ptValue.pos);
+ }
+ }
+
+ // otherwise, search parent.
+ return parent != nullptr ? parent->searchVarDecl(symbol, position) : nullopt;
+ }
+
+ void SymbolContext::addPlainFile()
+ {
+ std::string plainFile = getPlainFile();
+ addEmptyExtRef(plainFile);
+ }
+
+ SymbolContext::SymbolContext(posInFile loc):
+ fileLoc(nullopt), contextLoc(std::move(loc)), parent(nullptr)
+ {
+ addPlainFile();
+ }
+
+ SymbolContext::SymbolContext(posInFile loc, std::string filename):
+ fileLoc(std::move(filename)), contextLoc(std::move(loc)), parent(nullptr)
+ {
+ addPlainFile();
+ }
+
+ optional<posRangeInFile>
+ SymbolContext::searchVarDeclFull(std::string const& symbol, optional<posInFile> const& position)
+ {
+ std::unordered_set<SymbolContext*> searched;
+ std::unordered_set<std::string> symbolSearch { symbol };
+
+ auto returnVal = _searchVarFull<posRangeInFile>(
+ searched, symbolSearch,
+ [&position](SymbolContext* ctx, std::string const& sym)
+ {
+ return ctx->searchVarDecl(sym, position);
+ },
+ [](SymbolContext* ctx, std::string const& sym)
+ {
+ return ctx->searchVarDecl(sym);
+ },
+ fnFromDeclCreateTrav);
+ if (returnVal.has_value())
+ {
+ return returnVal;
+ }
+
+ return _searchVarFull<posRangeInFile>(
+ symbol,
+ [](SymbolContext* ctx, std::string const& sym) -> optional<posRangeInFile>
+ {
+ for (auto const& unravelVal : ctx->extRefs.unraveledVals)
+ {
+ if (auto* pctx=ctx->searchStructCtxFull(unravelVal))
+ {
+ auto retVal = pctx->searchVarDecl(sym);
+ if (retVal.has_value())
+ {
+ return retVal;
+ }
+ }
+ }
+ return nullopt;
+ });
+ }
+
+ std::list<ExternalRefs::extRefMap::iterator> SymbolContext::getEmptyRefs()
+ {
+ std::list<ExternalRefs::extRefMap::iterator> finalList;
+
+ for (auto it = extRefs.extFileRefs.begin(); it != extRefs.extFileRefs.end(); it++)
+ {
+ if (it->second == nullptr)
+ {
+ // cerr << it->first << endl;
+ finalList.emplace_back(it);
+ }
+ }
+
+ for (auto& ctx : subContexts)
+ {
+ finalList.splice(finalList.end(), ctx->getEmptyRefs());
+ }
+
+ return finalList;
+ }
+
+ optional<std::string> SymbolContext::getFileName() const
+ {
+ if (fileLoc.has_value())
+ {
+ return fileLoc;
+ }
+ else
+ {
+ return parent == nullptr ? fileLoc : parent->getFileName();
+ }
+ }
+
+ optional<std::string> SymbolContext::searchVarSignatureFull(std::string const& symbol)
+ {
+ std::unordered_set<SymbolContext*> searched;
+ auto retVal = _searchVarFull<std::string>(
+ symbol,
+ [](SymbolContext const* ctx, std::string const& sym) -> optional<std::string>
+ {
+ if (auto const* info = ctx->searchVarRaw(sym))
+ {
+ return info->signature();
+ }
+ return nullopt;
+ },
+ fnFromDeclCreateTrav);
+
+ if (retVal.has_value())
+ {
+ return retVal;
+ }
+
+ // else,
+ // search every unravel values possible (not only here, but also in every includes + unravels as well).
+ // If an unravel value match a struct, then see if symbol matches the struct. If yes, return otherwise skip.
+
+ return _searchVarFull<std::string>(
+ symbol,
+ [](SymbolContext* ctx, std::string const& sym) -> optional<std::string>
+ {
+ if (SymbolInfo* info=ctx->searchVarUnravelStructRaw(sym))
+ {
+ return info->signature();
+ }
+ return nullopt;
+ });
+ }
+
+ SymbolInfo* SymbolContext::searchVarUnravelStructRaw(std::string const& symbol)
+ {
+ return searchVarUnravelStructRaw(symbol, nullopt);
+ }
+
+ SymbolInfo* SymbolContext::searchVarUnravelStructRaw(std::string const& symbol, optional<posInFile> const& position)
+ {
+ for (auto const& unravelVal : extRefs.unraveledVals)
+ {
+ if (auto* ctx=searchStructCtxFull(unravelVal))
+ {
+ // ctx points to a struct.
+ auto it=ctx->symMap.varDec.find(symbol);
+ if (it != ctx->symMap.varDec.end())
+ {
+ if (((not position.has_value()) or (!posLt(position.value(), it->second.pos))))
+ {
+ return &it->second;
+ }
+ }
+ }
+ }
+ return parent != nullptr ? parent->searchVarUnravelStructRaw(symbol) : nullptr;
+ }
+
+ std::list<std::string> SymbolContext::searchFuncUnravelStruct(std::string const& symbol)
+ {
+ std::list<std::string> finalList;
+
+ for (auto const& unravelVal : extRefs.unraveledVals)
+ {
+ if (auto* ctx=searchStructCtxFull(unravelVal))
+ {
+ // ctx points to a struct.
+ auto it=ctx->symMap.funDec.find(symbol);
+ if (it != ctx->symMap.funDec.end() and not it->second.empty())
+ {
+ std::transform(
+ it->second.begin(), it->second.end(), std::back_inserter(finalList),
+ [](FunctionInfo const& fnInfo)
+ {
+ return fnInfo.signature();
+ });
+ }
+ }
+ }
+ if (parent != nullptr)
+ {
+ finalList.splice(finalList.end(), parent->searchFuncUnravelStruct(symbol));
+ }
+ return finalList;
+ }
+
+
+ std::list<std::string> SymbolContext::searchFuncSignature(std::string const& symbol)
+ {
+ std::list<std::string> funcSigs;
+ auto pt = symMap.funDec.find(symbol);
+ if (pt != symMap.funDec.end())
+ {
+ std::transform(pt->second.begin(), pt->second.end(),
+ std::back_inserter(funcSigs),
+ [](FunctionInfo const& fnInfo) {
+ return fnInfo.signature();
+ });
+ }
+
+ if (parent != nullptr)
+ {
+ funcSigs.splice(funcSigs.end(), parent->searchFuncSignature(symbol));
+ }
+ return funcSigs;
+ }
+
+ std::list<std::string> SymbolContext::searchFuncSignatureFull(std::string const& symbol)
+ {
+ auto base_list = _searchAllVarFull<std::string>(
+ symbol, std::mem_fn(&SymbolContext::searchFuncSignature), fnFromDeclCreateTrav);
+
+ base_list.splice(base_list.end(), _searchAllVarFull<std::string>(
+ symbol, std::mem_fn(&SymbolContext::searchFuncUnravelStruct)));
+ return base_list;
+ }
+
+ optional<SymbolContext*> SymbolContext::searchStructContext(std::string const& tyVal) const
+ {
+ auto stCtx = symMap.typeDecs.find(tyVal);
+ if (stCtx != symMap.typeDecs.end())
+ {
+ if (auto* stDec = dynamic_cast<StructDecs*>(stCtx->second.get()))
+ {
+ return make_optional(stDec->ctx);
+ }
+ }
+
+ return parent != nullptr ? parent->searchStructContext(tyVal) : nullopt;
+ };
+
+ optional<std::string> SymbolContext::searchLitSignature(SymbolLit const& symbol)
+ {
+ if (symbol.scopes.empty())
+ {
+ return searchVarSignatureFull(symbol.name);
+ }
+ else
+ {
+ auto ctx=std::get<0>(searchLitContext(symbol));
+ auto isStruct=std::get<1>(searchLitContext(symbol));
+ if (ctx)
+ {
+ if (isStruct)
+ {
+ // ctx is a struct declaration. should not search beyond this struct.
+ auto varDec=ctx->symMap.varDec.find(symbol.name);
+ return varDec != ctx->symMap.varDec.end() ?
+ optional<std::string>(varDec->second.signature()) : nullopt;
+ }
+ else
+ {
+ return ctx->searchVarSignatureFull(symbol.name);
+ }
+ }
+ }
+
+ return nullopt;
+ }
+
+ std::list<std::string> SymbolContext::searchLitFuncSignature(SymbolLit const& symbol)
+ {
+ std::list<std::string> signatures;
+ if (symbol.scopes.empty())
+ {
+ signatures.splice(signatures.end(), searchFuncSignatureFull(symbol.name));
+ }
+ else
+ {
+ auto ctx=std::get<0>(searchLitContext(symbol));
+ auto isStruct=std::get<1>(searchLitContext(symbol));
+ if (ctx)
+ {
+ if (isStruct)
+ {
+ // ctx is a struct declaration. should not search beyond this struct.
+ auto fnDecs=ctx->symMap.funDec.find(symbol.name);
+ if (fnDecs != ctx->symMap.funDec.end())
+ {
+ std::transform(
+ fnDecs->second.begin(), fnDecs->second.end(),
+ std::back_inserter(signatures),
+ [&scopes=symbol.scopes](FunctionInfo const& fnInf)
+ {
+ return fnInf.signature(scopes);
+ });
+ }
+ }
+ else
+ {
+ signatures.splice(signatures.end(), searchFuncSignatureFull(symbol.name));
+ }
+ }
+ }
+
+ return signatures;
+ }
+
+ optional<posRangeInFile> SymbolContext::searchLitPosition(
+ SymbolLit const& symbol,
+ optional<posInFile> const& position)
+ {
+ if (symbol.scopes.empty())
+ {
+ return searchVarDeclFull(symbol.name, position);
+ }
+ else
+ {
+ auto ctx=std::get<0>(searchLitContext(symbol));
+ auto isStruct=std::get<1>(searchLitContext(symbol));
+ if (ctx) // ctx is a struct declaration. should not search beyond this struct.
+ {
+ if (isStruct)
+ {
+ auto varDec=ctx->symMap.varDec.find(symbol.name);
+ if (varDec != ctx->symMap.varDec.end())
+ {
+ auto line=std::get<0>(varDec->second.pos);
+ auto ch=std::get<1>(varDec->second.pos);
+ return std::make_tuple(ctx->getFileName().value_or(""),
+ varDec->second.pos, std::make_pair(line, ch + symbol.name.length()));
+ }
+ }
+ else
+ {
+ return searchVarDeclFull(symbol.name, position);
+ }
+ }
+ return nullopt;
+ }
+ }
+
+ std::list<posRangeInFile>
+ SymbolContext::searchLitFuncPositions(SymbolLit const& symbol, optional<posInFile> const& position)
+ {
+ if (symbol.scopes.empty())
+ {
+ return searchFuncDeclsFull(symbol.name, position);
+ }
+ else
+ {
+ std::list<posRangeInFile> fnDecls;
+ auto v=searchLitContext(symbol);
+ auto ctx=std::get<0>(v);
+ auto isStruct=std::get<1>(v);
+ if (ctx) // ctx is a struct declaration. should not search beyond this struct.
+ {
+ if (isStruct)
+ {
+ auto fnDec=ctx->symMap.funDec.find(symbol.name);
+ if (fnDec != ctx->symMap.funDec.end())
+ {
+ for (auto const& ptValue : fnDec->second)
+ {
+ fnDecls.emplace_back(getFileName().value_or(""), ptValue.pos, ptValue.pos);
+ }
+ }
+ }
+ else
+ {
+ return searchFuncDeclsFull(symbol.name, position);
+ }
+ }
+ return fnDecls;
+ }
+ }
+
+ SymbolContext* SymbolContext::searchStructCtxFull(std::string const& symbol)
+ {
+ std::unordered_set<SymbolContext*> searched;
+ optional<std::string> tyInfo=_searchVarFull<std::string, std::string>(
+ symbol,
+ [](SymbolContext const* ctx, std::string const& sym) -> optional<std::string>
+ {
+ if (auto const* info = ctx->searchVarRaw(sym))
+ {
+ return info->type;
+ }
+ return nullopt;
+ },
+ fnFromDeclCreateTrav);
+
+
+ if (not tyInfo.has_value())
+ {
+ return nullptr;
+ }
+
+ return _searchVarFull<SymbolContext*>(
+ tyInfo.value(), std::mem_fn(&SymbolContext::searchStructContext)).value_or(nullptr);
+ }
+
+ optional<SymbolContext*> SymbolContext::searchAccessDecls(std::string const& accessVal)
+ {
+ // fileIdPair includes accessVals
+
+ auto src=extRefs.fileIdPair.find(accessVal);
+ if (src != extRefs.fileIdPair.end())
+ {
+ std::string& fileSrc=src->second;
+ auto ctxMap=extRefs.extFileRefs.find(fileSrc);
+ if (ctxMap != extRefs.extFileRefs.end() && ctxMap->second != nullptr)
+ {
+ return ctxMap->second;
+ }
+ }
+
+ return parent != nullptr ? parent->searchAccessDecls(accessVal) : nullopt;
+ }
+
+ /**
+ * Fully search context for source structs or source file in access
+ * @param symbol Symbol to search
+ * @return pair of <code>[context, isStruct]</code>, where <code>isStruct</code> is true
+ * if the <code>context</code> is a struct, and false if the context is a file from access declaration.
+ * If context is nullptr, <code>isStruct</code>'s return does not have defined behavior.
+ */
+ std::pair<SymbolContext*, bool> SymbolContext::searchLitContext(SymbolLit const& symbol)
+ {
+ if (symbol.scopes.empty())
+ {
+ // if the symbol is empty, then we can access every variable, not just those in the struct context
+ // and hence should be treated as "not a struct", even if the variable is accessed in the struct.
+ // for example,
+ // int z; struct St { int x; int y=x+z; }
+ // here, x and z can be accessed in the struct context.
+ return std::make_pair(this, false);
+ }
+ else
+ {
+ std::vector<std::string> scopes(symbol.scopes);
+ bool isStruct=false;
+
+ // search in struct
+ auto* ctx=searchStructCtxFull(scopes.back());
+ if (ctx)
+ {
+ isStruct = true;
+ scopes.pop_back();
+ }
+ else
+ {
+ // search in access declarations
+ ctx =_searchVarFull<SymbolContext*>(
+ scopes.back(), std::mem_fn(&SymbolContext::searchAccessDecls)).value_or(nullptr);
+
+ if (ctx)
+ {
+ scopes.pop_back();
+ }
+ }
+
+ for (auto it = scopes.rbegin(); it != scopes.rend() and ctx != nullptr; it++)
+ {
+ // FIXME: Impelemnt scope searching
+ // example:
+ // varx.vary.varz => go into varx's type context (struct or external file), repeat.
+ // struct and extfile handled very differently
+
+ // get next variable declaration loc.
+ // assumes struct, hence we do not search entire workspace
+ SymbolContext* newCtx=nullptr;
+
+ auto locVarDec = ctx->symMap.varDec.find(*it);
+ if (locVarDec != ctx->symMap.varDec.end() and locVarDec->second.type.has_value())
+ {
+ newCtx = ctx->_searchVarFull<SymbolContext*>(
+ locVarDec->second.type.value(), std::mem_fn(&SymbolContext::searchStructContext)
+ ).value_or(nullptr);
+ }
+
+ // here, we searched for a struct context and did not find anything.
+ // If we are in a struct context, we hit a dead end.
+ // otherwise, we search for access declaration contexts.
+ if (newCtx == nullptr)
+ {
+ if (isStruct)
+ {
+ return make_pair(nullptr, false);
+ }
+ else
+ {
+ ctx =_searchVarFull<SymbolContext*>(
+ *it, std::mem_fn(&SymbolContext::searchAccessDecls)).value_or(nullptr);
+ }
+ }
+ else
+ {
+ isStruct = true;
+ }
+
+ ctx = newCtx;
+ }
+ return make_pair(ctx, isStruct);
+ }
+ }
+
+ std::unordered_set<std::string> SymbolContext::createTraverseSet()
+ {
+ std::unordered_set<std::string> traverseSet(extRefs.includeVals);
+ traverseSet.emplace(getPlainFile());
+ for (auto const& unravelVal : extRefs.unraveledVals)
+ {
+ auto it = extRefs.fileIdPair.find(unravelVal);
+ if (it != extRefs.fileIdPair.end())
+ {
+ traverseSet.emplace(it->second);
+ }
+ }
+ return traverseSet;
+ }
+
+ SymbolContext* SymbolContext::getExternalRef(std::string const& symbol)
+ {
+ auto symRef = extRefs.extFileRefs.find(symbol);
+ if (symRef != extRefs.extFileRefs.end())
+ {
+ return symRef->second;
+ }
+
+ return parent != nullptr ? parent->getExternalRef(symbol) : nullptr;
+ }
+
+ std::list<posRangeInFile> SymbolContext::searchFuncDecls(std::string const& symbol)
+ {
+ return searchFuncDecls(symbol, nullopt);
+ }
+
+ std::list<posRangeInFile>
+ SymbolContext::searchFuncDecls(std::string const& symbol, optional<posInFile> const& position)
+ {
+ std::list<posRangeInFile> funcDecls;
+ auto pt = symMap.funDec.find(symbol);
+ if (pt != symMap.funDec.end())
+ {
+ for (auto const& fnInfo : pt->second)
+ {
+ if ((not position.has_value()) or (!posLt(position.value(), fnInfo.pos)))
+ {
+ funcDecls.emplace_back(getFileName().value_or(""), fnInfo.pos, fnInfo.pos);
+ }
+ }
+ }
+
+ if (parent != nullptr)
+ {
+ funcDecls.splice(funcDecls.end(), parent->searchFuncDecls(symbol, position));
+ }
+ return funcDecls;
+ }
+
+ std::list<posRangeInFile>
+ SymbolContext::searchFuncDeclsFull(std::string const& symbol, optional<posInFile> const& position)
+ {
+ std::unordered_set<SymbolContext*> searched;
+ auto retVal = _searchAllVarFull<posRangeInFile>(
+ searched,
+ std::unordered_set<std::string> { symbol },
+ [&position](SymbolContext* ctx, std::string const& symbol)
+ {
+ return ctx->searchFuncDecls(symbol, position);
+ },
+ [](SymbolContext* ctx, std::string const& symbol)
+ {
+ return ctx->searchFuncDecls(symbol);
+ },
+ fnFromDeclCreateTrav);
+
+ auto retValStruct =_searchAllVarFull<posRangeInFile>(
+ symbol,
+ [](SymbolContext* ctx, std::string const& sym) -> std::list<posRangeInFile>
+ {
+ std::list<posRangeInFile> finalList;
+ for (auto const& unravelVal : ctx->extRefs.unraveledVals)
+ {
+ if (auto* pctx=ctx->searchStructCtxFull(unravelVal))
+ {
+ finalList.splice(finalList.end(), pctx->searchFuncDecls(sym));
+ }
+ }
+ return finalList;
+ });
+ retVal.splice(retVal.end(), std::move(retValStruct));
+ return retVal;
+ }
+
+ optional<posRangeInFile> AddDeclContexts::searchVarDecl(
+ std::string const& symbol, optional<posInFile> const& position)
+ {
+ auto pt = additionalDecs.find(symbol);
+ if (pt != additionalDecs.end())
+ {
+ auto line=std::get<0>(pt->second.pos);
+ auto ch=std::get<1>(pt->second.pos);
+ if ((not position.has_value()) or (!posLt(position.value(), pt->second.pos)))
+ {
+ return std::make_tuple(getFileName().value_or(""),
+ pt->second.pos,
+ std::make_pair(line, ch + symbol.length()));
+ }
+ }
+
+ return SymbolContext::searchVarDecl(symbol, position);
+ }
+
+ SymbolInfo const* AddDeclContexts::searchVarRaw(std::string const& symbol) const
+ {
+ auto pt = additionalDecs.find(symbol);
+ return pt != additionalDecs.end() ? &pt->second : SymbolContext::searchVarRaw(symbol);
+ }
+
+ bool SymbolInfo::operator==(SymbolInfo const& sym) const
+ {
+ return name==sym.name and type==sym.type and pos == sym.pos;
+ }
+
+ std::string SymbolInfo::signature() const
+ {
+ return type.value_or("<decl-unknown>") + " " + name + ";";
+ }
+
+ std::string FunctionInfo::signature() const
+ {
+ return signature(std::vector<std::string>());
+ }
+
+ std::string FunctionInfo::signature(std::vector<std::string> const& scopes) const
+ {
+ std::stringstream ss;
+ ss << returnType << " ";
+ for (auto it=scopes.crbegin(); it!=scopes.crend(); it++)
+ {
+ ss << *it << ".";
+ }
+ ss << name << "(";
+ for (auto it = arguments.begin(); it != arguments.end(); it++)
+ {
+ auto const& argtype=std::get<0>(*it);
+ auto const& argname=std::get<1>(*it);
+ ss << argtype;
+ if (argname.has_value())
+ {
+ ss << " " << argname.value();
+ }
+
+ if (std::next(it) != arguments.end())
+ {
+ ss << ",";
+ }
+
+ if (std::next(it) != arguments.end() or restArgs.has_value())
+ {
+ ss << " ";
+ }
+ }
+
+ if (restArgs.has_value())
+ {
+ auto const& v=restArgs.value();
+ auto const& argtype=std::get<0>(v);
+ auto const& argname=std::get<1>(v);
+ ss << "... " << argtype;
+
+ if (argname.has_value())
+ {
+ ss << " " << argname.value();
+ }
+ }
+ ss << ");";
+ return ss.str();
+ }
+}
+
+#endif
diff --git a/graphics/asymptote/symbolmaps.h b/graphics/asymptote/symbolmaps.h
new file mode 100644
index 0000000000..964899e0b6
--- /dev/null
+++ b/graphics/asymptote/symbolmaps.h
@@ -0,0 +1,945 @@
+#pragma once
+
+#include <unordered_map>
+#include <unordered_set>
+#include <tuple>
+#include <utility>
+
+#include "common.h"
+#include "makeUnique.h"
+
+#include "LibLsp/lsp/lsPosition.h"
+#include "LibLsp/lsp/textDocument/documentColor.h"
+
+#ifndef boost
+#define nullopt boost::none
+#endif
+
+namespace AsymptoteLsp
+{
+ struct SymbolLit
+ {
+ std::string name;
+ std::vector<std::string> scopes;
+
+ SymbolLit(std::string symName) :
+ name(std::move(symName))
+ {
+ }
+
+ SymbolLit(std::string symName, std::vector<std::string> scope) :
+ name(std::move(symName)), scopes(std::move(scope))
+ {
+ }
+
+ ~SymbolLit() = default;
+
+ SymbolLit(SymbolLit const& sym) :
+ name(sym.name), scopes(sym.scopes)
+ {
+ }
+
+ SymbolLit& operator=(SymbolLit const& sym)
+ {
+ name = sym.name;
+ scopes = sym.scopes;
+ return *this;
+ }
+
+ SymbolLit(SymbolLit&& sym) noexcept :
+ name(std::move(sym.name)), scopes(std::move(sym.scopes))
+ {
+ }
+
+ SymbolLit& operator=(SymbolLit&& sym) noexcept
+ {
+ name = std::move(sym.name);
+ scopes = std::move(sym.scopes);
+ return *this;
+ }
+
+ bool operator==(SymbolLit const& other) const
+ {
+ return name == other.name and scopes == other.scopes;
+ }
+
+ bool matchesRaw(std::string const& sym) const
+ {
+ return name == sym;
+ }
+ };
+} // namespace AsymptoteLsp
+
+namespace std
+{
+ using AsymptoteLsp::SymbolLit;
+
+ template<>
+ struct hash<SymbolLit>
+ {
+ std::size_t operator()(SymbolLit const& sym) const
+ {
+ size_t final_hash = 0;
+ final_hash ^= hash<std::string>()(sym.name);
+ for (auto const& accessor : sym.scopes)
+ {
+ final_hash = (final_hash << 1) ^ hash<std::string>()(accessor);
+ }
+ return final_hash;
+ }
+ };
+} // namespace std
+
+namespace AsymptoteLsp
+{
+ using std::unordered_map;
+ struct SymbolContext;
+
+ typedef std::pair<std::string, SymbolContext*> contextedSymbol;
+ typedef std::pair<size_t, size_t> posInFile;
+ typedef std::pair<std::string, posInFile> filePos;
+ typedef std::tuple<std::string, posInFile, posInFile> posRangeInFile;
+ typedef std::tuple<SymbolLit, posInFile, posInFile> fullSymPosRangeInFile;
+
+
+ // NOTE: lsPosition is zero-indexed, while all Asymptote positions (incl this struct) is 1-indexed.
+ inline posInFile fromLsPosition(lsPosition const& inPos)
+ {
+ return std::make_pair(inPos.line + 1, inPos.character + 1);
+ }
+
+ inline lsPosition toLsPosition(posInFile const& inPos)
+ {
+ return lsPosition(inPos.first - 1, inPos.second - 1);
+ }
+
+ inline bool posLt(posInFile const& p1, posInFile const& p2)
+ {
+ return (p1.first < p2.first) or ((p1.first == p2.first) and (p1.second < p2.second));
+ }
+
+ std::string getPlainFile();
+ bool isVirtualFile(std::string const& filename);
+
+ // filename to positions
+ struct positions
+ {
+ std::unordered_map<std::string, std::vector<posInFile>> pos;
+
+ positions() = default;
+ explicit positions(filePos const& positionInFile);
+ void add(filePos const& positionInFile);
+ };
+
+
+ struct SymbolInfo
+ {
+ std::string name;
+ optional<std::string> type;
+ posInFile pos;
+
+ SymbolInfo() : type(nullopt), pos(1, 1) {}
+
+ SymbolInfo(std::string inName, posInFile position):
+ name(std::move(inName)), type(nullopt), pos(std::move(position)) {}
+
+ SymbolInfo(std::string inName, std::string inType, posInFile position):
+ name(std::move(inName)), type(std::move(inType)), pos(std::move(position)) {}
+
+ SymbolInfo(SymbolInfo const& symInfo) = default;
+
+ SymbolInfo& operator=(SymbolInfo const& symInfo) noexcept = default;
+
+ SymbolInfo(SymbolInfo&& symInfo) noexcept :
+ name(std::move(symInfo.name)), type(std::move(symInfo.type)), pos(std::move(symInfo.pos))
+ {
+ }
+
+ SymbolInfo& operator=(SymbolInfo&& symInfo) noexcept
+ {
+ name = std::move(symInfo.name);
+ type = std::move(symInfo.type);
+ pos = std::move(symInfo.pos);
+ return *this;
+ }
+
+ virtual ~SymbolInfo() = default;
+
+ bool operator==(SymbolInfo const& sym) const;
+
+ [[nodiscard]]
+ virtual std::string signature() const;
+ };
+
+ struct FunctionInfo: SymbolInfo
+ {
+ std::string returnType;
+ using typeName = std::pair<std::string, optional<std::string>>;
+ std::vector<typeName> arguments;
+ optional<typeName> restArgs;
+
+ FunctionInfo(std::string name, posInFile pos, std::string returnTyp):
+ SymbolInfo(std::move(name), std::move(pos)),
+ returnType(std::move(returnTyp)),
+ arguments(), restArgs(nullopt) {}
+
+ ~FunctionInfo() override = default;
+
+ [[nodiscard]]
+ std::string signature() const override;
+
+ [[nodiscard]]
+ std::string signature(std::vector<std::string> const& scopes) const;
+ };
+
+
+ struct TypeDec
+ {
+ posInFile position;
+ std::string typeName;
+
+ TypeDec(): position(1, 1) {}
+ virtual ~TypeDec() = default;
+
+ TypeDec(posInFile pos, std::string typName):
+ position(std::move(pos)), typeName(std::move(typName))
+ {
+ }
+
+ TypeDec(TypeDec const& typDec) = default;
+ TypeDec& operator= (TypeDec const& typDec) = default;
+
+ TypeDec(TypeDec&& typDec) noexcept = default;
+ TypeDec& operator= (TypeDec&& typDec) = default;
+
+ [[nodiscard]]
+ virtual unique_ptr<TypeDec> clone() const
+ {
+ return make_unique<TypeDec>(*this);
+ }
+ };
+
+ struct TypedefDec : public TypeDec
+ {
+ std::string destName;
+ };
+
+ struct SymColorInfo
+ {
+ posInFile rangeBegin;
+ posInFile rangeEnd;
+
+ using RGBColor = std::tuple<double, double, double>;
+ using RGBAColor = std::tuple<double, double, double, double>;
+ void setLastArgPos(posInFile lastArgPos) { lastArgPosition = std::move(lastArgPos); }
+
+ SymColorInfo() = default;
+ virtual ~SymColorInfo() = default;
+ SymColorInfo(SymColorInfo const& col) = default;
+ SymColorInfo& operator=(SymColorInfo const& col) = default;
+
+ SymColorInfo(SymColorInfo&& col) noexcept = default;
+ SymColorInfo& operator=(SymColorInfo&& col) noexcept = default;
+
+
+
+ [[nodiscard]]
+ virtual RGBColor getRGBColor() const = 0;
+
+ [[nodiscard]]
+ virtual double getAlpha() const
+ {
+ return 1;
+ }
+
+ [[nodiscard]]
+ RGBAColor getRGBAColor() const
+ {
+ RGBColor c=getRGBColor();
+ auto const& red=std::get<0>(c);
+ auto const& green=std::get<1>(c);
+ auto const& blue=std::get<2>(c);
+ return RGBAColor(red,green,blue,getAlpha());
+ }
+
+ explicit operator TextDocument::Color() const
+ {
+ TextDocument::Color col;
+ RGBAColor c=getRGBAColor();
+ col.red=std::get<0>(c);
+ col.green=std::get<1>(c);
+ col.blue=std::get<2>(c);
+ col.alpha=std::get<3>(c);
+ return col;
+ }
+
+ [[nodiscard]]
+ virtual unique_ptr<SymColorInfo> clone() const = 0;
+
+ public:
+ posInFile lastArgPosition;
+ };
+
+ struct RGBSymColorInfo : SymColorInfo
+ {
+ double red, green, blue;
+
+ RGBSymColorInfo(): SymColorInfo(), red(0), green(0), blue(0) {}
+ RGBSymColorInfo(double redVal, double greenVal, double blueVal):
+ SymColorInfo(),
+ red(redVal), green(greenVal), blue(blueVal)
+ {
+ }
+
+ RGBSymColorInfo(RGBSymColorInfo const& col) = default;
+ RGBSymColorInfo& operator=(RGBSymColorInfo const& col) = default;
+
+ [[nodiscard]]
+ RGBColor getRGBColor() const override
+ {
+ return RGBColor(red, green, blue);
+ }
+
+ [[nodiscard]]
+ unique_ptr<SymColorInfo> clone() const override
+ {
+ return unique_ptr<SymColorInfo>(new RGBSymColorInfo(*this));
+ }
+ };
+
+ struct RGBASymColorInfo : RGBSymColorInfo
+ {
+ double alpha;
+
+ RGBASymColorInfo(): RGBSymColorInfo(), alpha(1) {}
+ RGBASymColorInfo(double redVal, double greenVal, double blueVal, double alphaVal):
+ RGBSymColorInfo(redVal, greenVal, blueVal), alpha(alphaVal)
+ {
+ }
+
+ [[nodiscard]]
+ double getAlpha() const override
+ {
+ return alpha;
+ }
+
+ [[nodiscard]]
+ unique_ptr<SymColorInfo> clone() const override
+ {
+ return unique_ptr<SymColorInfo>(new RGBASymColorInfo(*this));
+ }
+ };
+
+ struct StructDecs : public TypeDec
+ {
+ SymbolContext* ctx;
+
+ StructDecs(): TypeDec(), ctx(nullptr) {}
+ ~StructDecs() override = default;
+
+ StructDecs(posInFile pos, std::string typName) :
+ TypeDec(std::move(pos), std::move(typName)), ctx(nullptr)
+ {
+ }
+
+ StructDecs(posInFile pos, std::string typName, SymbolContext* ctx) :
+ TypeDec(std::move(pos), std::move(typName)), ctx(ctx)
+ {
+ }
+
+ [[nodiscard]]
+ unique_ptr<TypeDec> clone() const override
+ {
+ return std::unique_ptr<TypeDec>(new StructDecs(*this));
+ }
+ };
+
+ struct SymbolMaps
+ {
+ unordered_map <std::string, SymbolInfo> varDec;
+ unordered_map <std::string, std::vector<FunctionInfo>> funDec;
+ // can refer to other files
+ unordered_map <SymbolLit, positions> varUsage;
+ unordered_map <std::string, unique_ptr<TypeDec>> typeDecs;
+
+ // python equivalent of dict[str, list[tuple(pos, sym)]]
+ // filename -> list[(position, symbol)]
+
+ std::vector<std::pair<posInFile, SymbolLit>> usageByLines;
+
+ SymbolMaps() = default;
+ ~SymbolMaps() = default;
+
+ SymbolMaps(SymbolMaps const& symMap) :
+ varDec(symMap.varDec), funDec(symMap.funDec), varUsage(symMap.varUsage), typeDecs(),
+ usageByLines(symMap.usageByLines)
+ {
+ for(auto const& t : symMap.typeDecs)
+ {
+ auto const& ty=std::get<0>(t);
+ auto const& tyDec=std::get<1>(t);
+ typeDecs.emplace(ty, tyDec != nullptr ? tyDec->clone() : nullptr);
+ }
+ }
+
+ SymbolMaps& operator=(SymbolMaps const& symMap)
+ {
+ varDec = symMap.varDec;
+ funDec = symMap.funDec;
+ varUsage = symMap.varUsage;
+ usageByLines = symMap.usageByLines;
+
+ typeDecs.clear();
+ for(auto const& t : symMap.typeDecs)
+ {
+ auto const& ty=std::get<0>(t);
+ auto const& tyDec=std::get<1>(t);
+ typeDecs.emplace(ty, tyDec != nullptr ? tyDec->clone() : nullptr);
+ }
+ return *this;
+ }
+
+ SymbolMaps(SymbolMaps&& symMap) noexcept:
+ varDec(std::move(symMap.varDec)), funDec(std::move(symMap.funDec)), varUsage(std::move(symMap.varUsage)),
+ typeDecs(std::move(symMap.typeDecs)), usageByLines(std::move(symMap.usageByLines))
+ {
+ }
+
+ SymbolMaps& operator=(SymbolMaps&& symMap) noexcept
+ {
+ varDec = std::move(symMap.varDec);
+ funDec = std::move(symMap.funDec);
+ varUsage = std::move(symMap.varUsage);
+ usageByLines = std::move(symMap.usageByLines);
+ typeDecs = std::move(symMap.typeDecs);
+
+ return *this;
+ }
+
+ inline void clear()
+ {
+ varDec.clear();
+ funDec.clear();
+ varUsage.clear();
+ usageByLines.clear();
+ typeDecs.clear();
+ }
+ optional<fullSymPosRangeInFile> searchSymbol(posInFile const& inputPos);
+ FunctionInfo& addFunDef(std::string const& funcName, posInFile const& position, std::string const& returnType);
+
+ private:
+ friend ostream& operator<<(std::ostream& os, const SymbolMaps& sym);
+ };
+
+ struct ExternalRefs
+ {
+
+ // file interactions
+ // access -> (file, id)
+ // unravel -> id
+ // include -> file
+ // import = acccess + unravel
+
+ using extRefMap = std::unordered_map<std::string, SymbolContext*>;
+ extRefMap extFileRefs;
+ std::unordered_map<std::string, std::string> fileIdPair;
+ std::unordered_set<std::string> includeVals;
+ std::unordered_set<std::string> unraveledVals;
+ std::unordered_set<std::string> accessVals;
+ std::unordered_map<std::string, std::pair<std::string, std::string>> fromAccessVals;
+
+ ExternalRefs() = default;
+ virtual ~ExternalRefs() = default;
+
+ ExternalRefs(ExternalRefs const& exRef) = default;
+ ExternalRefs& operator=(ExternalRefs const& exRef) = default;
+
+ ExternalRefs(ExternalRefs&& exRef) noexcept = default;
+ ExternalRefs& operator=(ExternalRefs&& exRef) noexcept = default;
+
+
+ void clear()
+ {
+ extFileRefs.clear();
+ fileIdPair.clear();
+ includeVals.clear();
+ unraveledVals.clear();
+ accessVals.clear();
+ fromAccessVals.clear();
+ }
+
+ bool addEmptyExtRef(std::string const& fileName)
+ {
+ auto success=std::get<1>(extFileRefs.emplace(fileName, nullptr));
+ return success;
+ }
+
+ bool addAccessVal(std::string const& symbol)
+ {
+ auto success=std::get<1>(accessVals.emplace(symbol));
+ return success;
+ }
+
+ bool addUnravelVal(std::string const& symbol)
+ {
+ auto success=std::get<1>(unraveledVals.emplace(symbol));
+ return success;
+ }
+
+ bool addFromAccessVal(std::string const& fileName, std::string const& symbolSrc, std::string const& symbolDest)
+ {
+ auto success=std::get<1>(fromAccessVals.emplace(symbolDest, make_pair(symbolSrc, fileName)));
+ return success;
+ }
+ };
+
+
+ struct SymbolContext
+ {
+ optional<std::string> fileLoc;
+ posInFile contextLoc;
+ SymbolContext* parent;
+ SymbolMaps symMap;
+
+ // file interactions
+ // access -> (file, id)
+ // unravel -> id
+ // include -> file
+ // import = acccess + unravel
+
+ ExternalRefs extRefs;
+
+ std::vector<std::unique_ptr<SymColorInfo>> colorInformation;
+ std::vector<std::unique_ptr<SymbolContext>> subContexts;
+
+ SymbolContext():
+ parent(nullptr)
+ {
+ }
+
+ virtual ~SymbolContext() = default;
+
+ explicit SymbolContext(posInFile loc);
+ explicit SymbolContext(posInFile loc, std::string filename);
+
+ SymbolContext(posInFile loc, SymbolContext* contextParent):
+ fileLoc(nullopt), contextLoc(std::move(loc)), parent(contextParent)
+ {
+ }
+
+ template<typename T=SymbolContext, typename=std::enable_if<std::is_base_of<SymbolContext, T>::value>>
+ T* newContext(posInFile const& loc)
+ {
+ subContexts.emplace_back(make_unique<T>(loc, this));
+ return static_cast<T*>(subContexts.back().get());
+ }
+
+ template<typename T=TypeDec, typename=std::enable_if<std::is_base_of<TypeDec, T>::value>>
+ T* newTypeDec(std::string const& tyName, posInFile const& loc)
+ {
+ auto s=symMap.typeDecs.emplace(tyName, make_unique<T>(loc, tyName));
+ auto it=std::get<0>(s);
+ auto succ=std::get<1>(s);
+ return succ ? static_cast<T*>(it->second.get()) : static_cast<T*>(nullptr);
+ }
+
+ SymbolContext(SymbolContext const& symCtx) :
+ fileLoc(symCtx.fileLoc), contextLoc(symCtx.contextLoc),
+ parent(symCtx.parent), symMap(symCtx.symMap),
+ extRefs(symCtx.extRefs)
+ {
+ for (auto& ctx : symCtx.subContexts)
+ {
+ subContexts.push_back(make_unique<SymbolContext>(*ctx));
+ }
+
+ for (auto& col : symCtx.colorInformation)
+ {
+ colorInformation.emplace_back(col != nullptr ? col->clone() : nullptr);
+ }
+ }
+
+ SymbolContext& operator= (SymbolContext const& symCtx)
+ {
+ fileLoc = symCtx.fileLoc;
+ contextLoc = symCtx.contextLoc;
+ parent = symCtx.parent;
+ symMap = symCtx.symMap;
+ extRefs = symCtx.extRefs;
+
+ subContexts.clear();
+ for (auto& ctx : symCtx.subContexts)
+ {
+ subContexts.push_back(make_unique<SymbolContext>(*ctx));
+ }
+
+ colorInformation.clear();
+ for (auto& col : symCtx.colorInformation)
+ {
+ colorInformation.emplace_back(col != nullptr ? col->clone() : nullptr);
+ }
+
+ return *this;
+ }
+
+ SymbolContext(SymbolContext&& symCtx) noexcept :
+ fileLoc(std::move(symCtx.fileLoc)), contextLoc(std::move(symCtx.contextLoc)),
+ parent(symCtx.parent), symMap(std::move(symCtx.symMap)),
+ extRefs(std::move(symCtx.extRefs)),
+ colorInformation(std::move(symCtx.colorInformation)), subContexts(std::move(symCtx.subContexts))
+ {
+ }
+
+ SymbolContext& operator= (SymbolContext&& symCtx) noexcept
+ {
+ fileLoc = std::move(symCtx.fileLoc);
+ contextLoc = std::move(symCtx.contextLoc);
+ parent = symCtx.parent;
+ symMap = std::move(symCtx.symMap);
+ extRefs = std::move(symCtx.extRefs);
+ colorInformation = std::move(symCtx.colorInformation);
+ subContexts = std::move(symCtx.subContexts);
+ return *this;
+ }
+
+ // [file, start, end]
+ virtual std::pair<optional<fullSymPosRangeInFile>, SymbolContext*> searchSymbol(posInFile const& inputPos);
+
+
+
+ // declarations
+ optional<posRangeInFile> searchVarDecl(std::string const& symbol)
+ {
+ return searchVarDecl(symbol, nullopt);
+ }
+ virtual optional<posRangeInFile> searchVarDecl(std::string const& symbol,
+ optional<posInFile> const& position);
+ virtual optional<posRangeInFile> searchVarDeclFull(std::string const& symbol,
+ optional<posInFile> const& position=nullopt);
+ virtual SymbolInfo const* searchVarRaw(std::string const& symbol) const;
+
+ std::list<posRangeInFile> searchFuncDecls(std::string const& symbol);
+ virtual std::list<posRangeInFile> searchFuncDecls(
+ std::string const& symbol, optional<posInFile> const& position);
+ std::list<posRangeInFile> searchFuncDeclsFull(std::string const& symbol,
+ optional<posInFile> const& position=nullopt);
+
+ // variable signatures
+ optional<std::string> searchVarSignatureFull(std::string const& symbol);
+ virtual std::list<std::string> searchFuncSignature(std::string const& symbol);
+ virtual std::list<std::string> searchFuncSignatureFull(std::string const& symbol);
+
+ optional<std::string> searchLitSignature(SymbolLit const& symbol);
+ std::list<std::string> searchLitFuncSignature(SymbolLit const& symbol);
+
+ optional<posRangeInFile> searchLitPosition(
+ SymbolLit const& symbol, optional<posInFile> const& position=nullopt);
+ std::list<posRangeInFile> searchLitFuncPositions(
+ SymbolLit const& symbol, optional<posInFile> const& position=nullopt);
+
+ virtual std::list<ExternalRefs::extRefMap::iterator> getEmptyRefs();
+
+ optional<std::string> getFileName() const;
+
+ SymbolContext* getParent()
+ {
+ return parent == nullptr ? this : parent->getParent();
+ }
+
+ bool addEmptyExtRef(std::string const& fileName)
+ {
+ return extRefs.addEmptyExtRef(fileName);
+ }
+
+ void reset(std::string const& newFile)
+ {
+ fileLoc = newFile;
+ contextLoc = std::make_pair(1,1);
+ clear();
+ }
+
+ void clear()
+ {
+ parent = nullptr;
+ symMap.clear();
+ extRefs.clear();
+ clearColorInformation();
+ subContexts.clear();
+ }
+
+ void clearColorInformation()
+ {
+ colorInformation.clear();
+ }
+
+
+ void addRGBColor(
+ std::tuple<double, double, double> const& c,
+ posInFile const& posBegin,
+ posInFile const& lastArgs)
+ {
+ auto const& red=std::get<0>(c);
+ auto const& green=std::get<1>(c);
+ auto const& blue=std::get<2>(c);
+ colorInformation.emplace_back(make_unique<RGBSymColorInfo>(red,green,blue));
+ auto const& ptr=colorInformation.back();
+ ptr->rangeBegin = posBegin;
+ ptr->setLastArgPos(lastArgs);
+ }
+
+ void addRGBAColor(
+ std::tuple<double, double, double, double> const& c,
+ posInFile const& posBegin,
+ posInFile const& lastArgs)
+ {
+ auto const& red=std::get<0>(c);
+ auto const& green=std::get<1>(c);
+ auto const& blue=std::get<2>(c);
+ auto const& alpha=std::get<3>(c);
+ colorInformation.emplace_back(make_unique<RGBASymColorInfo>(red,green,blue,alpha));
+ auto const& ptr=colorInformation.back();
+ ptr->rangeBegin = posBegin;
+ ptr->setLastArgPos(lastArgs);
+ }
+
+ protected:
+ using SymCtxSet = std::unordered_set<SymbolContext*>;
+
+ // search var full
+
+ template<
+ typename TArg,
+ template<typename...> class TMapTraverse=std::unordered_map,
+ template<typename...> class TContainerArg=std::unordered_set
+ >
+ using SymbolArgContainer = TMapTraverse<std::string, TContainerArg<TArg>>;
+
+ template<
+ typename TArg,
+ template<typename...> class TMapTraverse=std::unordered_map,
+ template<typename...> class TContainerArg=std::unordered_set,
+ template<typename...> class TArgContainer=std::unordered_set
+ >
+ using FnCreateSymbolArgContainer =
+ std::function<SymbolArgContainer<TArg, TMapTraverse, TContainerArg>(SymbolContext*, TArgContainer<TArg> const&)>;
+
+ template<typename TArg>
+ SymbolArgContainer<TArg> defaultCreateTraverse(std::unordered_set<TArg> const& searchSet)
+ {
+ SymbolArgContainer<TArg> retVal;
+ for (auto const& traverseVal : createTraverseSet())
+ {
+ retVal.emplace(traverseVal, searchSet);
+ }
+ return retVal;
+ }
+
+ SymbolArgContainer<std::string> fromDeclCreateTraverse(std::unordered_set<std::string> const& symbols)
+ {
+ // base
+ SymbolArgContainer<std::string> base=defaultCreateTraverse(symbols);
+
+ for (auto const& sym : symbols)
+ {
+ auto aliasSearch = extRefs.fromAccessVals.find(sym);
+ if (aliasSearch != extRefs.fromAccessVals.end())
+ {
+ // there's an alias to dest -> [src, ctx].
+ auto const& src=std::get<0>(aliasSearch->second);
+ auto const& fileName=std::get<1>(aliasSearch->second);
+
+ auto baseTrav = base.find(fileName);
+ if (baseTrav == base.end())
+ {
+ base.emplace(fileName, std::unordered_set<std::string> { src });
+ }
+ else
+ {
+ baseTrav->second.emplace(src);
+ }
+ }
+ }
+
+ return base;
+ }
+
+ FnCreateSymbolArgContainer<std::string> const fnFromDeclCreateTrav =
+ std::mem_fn(&SymbolContext::fromDeclCreateTraverse);
+
+ template<typename TRet, typename TArg, typename TFn>
+ optional<TRet> _searchVarFull(
+ TArg init, TFn const& fnLocalPredicate,
+ FnCreateSymbolArgContainer<TArg> const& fnCreateTraverse=
+ std::mem_fn(&SymbolContext::defaultCreateTraverse<TArg>))
+ {
+ std::unordered_set<SymbolContext*> searched;
+ std::unordered_set<TArg> initSet { init };
+ return _searchVarFull<TRet, TArg, TFn, TFn>(
+ searched, initSet, fnLocalPredicate, fnLocalPredicate, fnCreateTraverse);
+ }
+
+ template<typename TRet, typename TArg, typename TFn, typename TFn2>
+ optional<TRet> _searchVarFull(
+ std::unordered_set<SymbolContext*>& searched,
+ std::unordered_set<TArg> const& searchArgs,
+ TFn const& fnLocalPredicate, TFn2 const& fnLocalPredicateFirst,
+ FnCreateSymbolArgContainer<TArg> const& fnCreateTraverse)
+ {
+ auto p=searched.emplace(getParent());
+ auto const& notSearched=std::get<1>(p);
+ if (not notSearched)
+ {
+ // a loop in the search path. Stop now.
+ return nullopt;
+ }
+
+ // local search first
+ for (TArg const& arg : searchArgs)
+ {
+ optional<TRet> returnVal=fnLocalPredicateFirst(this, arg);
+ if (returnVal.has_value())
+ {
+ return returnVal;
+ }
+ }
+
+ return searchVarExt<TRet, TArg, TFn>(searched, searchArgs, fnLocalPredicate, fnCreateTraverse);
+ }
+
+ template<typename TRet, typename TArg, typename TFn>
+ optional<TRet> searchVarExt(
+ std::unordered_set<SymbolContext*>& searched,
+ std::unordered_set<TArg> const& searchArgs,
+ TFn const& fnLocalPredicate,
+ FnCreateSymbolArgContainer<TArg> const& fnCreateTraverse)
+ {
+ using travType = std::pair<std::string, std::unordered_set<TArg>>;
+ for (travType const travArg : fnCreateTraverse(this, searchArgs))
+ {
+ std::string const traverseVal = travArg.first;
+ std::unordered_set<TArg> const argSet = travArg.second;
+ if (traverseVal == getFileName())
+ {
+ continue;
+ }
+
+ if (SymbolContext* ref=getExternalRef(traverseVal))
+ {
+ optional<TRet> returnValF = ref->_searchVarFull<TRet, TArg, TFn, TFn>(
+ searched, argSet,
+ fnLocalPredicate, fnLocalPredicate,
+ fnCreateTraverse);
+ if (returnValF.has_value())
+ {
+ return returnValF;
+ }
+ }
+ }
+ return nullopt;
+ }
+
+ // search all var full
+
+ template<typename TRet, typename TArg, typename TFn>
+ std::list<TRet> _searchAllVarFull(
+ TArg init,
+ TFn const& fnLocalPredicate,
+ FnCreateSymbolArgContainer<TArg> const& fnCreateTraverse=
+ std::mem_fn(&SymbolContext::defaultCreateTraverse<TArg>))
+ {
+ std::unordered_set<SymbolContext*> searched;
+ std::unordered_set<TArg> initSet { init };
+ return _searchAllVarFull<TRet, TArg, TFn, TFn>(
+ searched, initSet, fnLocalPredicate, fnLocalPredicate, fnCreateTraverse);
+ }
+
+ template<typename TRet, typename TArg, typename TFn, typename TFn2>
+ std::list<TRet> _searchAllVarFull(
+ std::unordered_set<SymbolContext*>& searched,
+ std::unordered_set<TArg> const& searchArgs,
+ TFn const& fnLocalPredicate, TFn2 const& fnLocalPredicateFirst,
+ FnCreateSymbolArgContainer<TArg> const& fnCreateTraverse)
+ {
+ auto p=searched.emplace(getParent());
+ auto const& notSearched=std::get<1>(p);
+ if (not notSearched)
+ {
+ // a loop in the search path. Stop now.
+ return std::list<TRet>();
+ }
+
+ std::list<TRet> returnVal;
+ // local search first
+ for (TArg const& arg : searchArgs)
+ {
+ returnVal.splice(returnVal.end(), fnLocalPredicateFirst(this, arg));
+ }
+ returnVal.splice(returnVal.end(), searchAllVarExt<TRet, TArg, TFn>(
+ searched, searchArgs, fnLocalPredicate, fnCreateTraverse));
+ return returnVal;
+ }
+
+ template<typename TRet, typename TArg, typename TFn>
+ std::list<TRet> searchAllVarExt(
+ std::unordered_set<SymbolContext*>& searched,
+ std::unordered_set<TArg> const& searchArgs,
+ TFn const& fnLocalPredicate,
+ FnCreateSymbolArgContainer<TArg> const& fnCreateTraverse)
+ {
+ using travType = std::pair<std::string, std::unordered_set<TArg>>;
+ std::list<TRet> finalList;
+ for (travType const travArg : fnCreateTraverse(this, searchArgs))
+ {
+ std::string const traverseVal = travArg.first;
+ std::unordered_set<TArg> const argSet = travArg.second;
+ if (traverseVal == getFileName())
+ {
+ continue;
+ }
+
+ if (SymbolContext* ref=getExternalRef(traverseVal))
+ {
+ auto returnValF=ref->_searchAllVarFull<TRet, TArg, TFn, TFn>(
+ searched, argSet,
+ fnLocalPredicate, fnLocalPredicate,
+ fnCreateTraverse);
+
+ finalList.splice(finalList.end(), std::move(returnValF));
+ }
+ }
+ return finalList;
+ }
+
+ virtual optional<SymbolContext*> searchStructContext(std::string const& tyVal) const;
+ SymbolContext* searchStructCtxFull(std::string const&);
+
+ optional<SymbolContext*> searchAccessDecls(std::string const&);
+ virtual std::pair<SymbolContext*, bool> searchLitContext(SymbolLit const& symbol);
+
+ virtual std::unordered_set<std::string> createTraverseSet();
+
+ virtual SymbolContext* getExternalRef(std::string const&);
+ std::list<std::string> searchFuncUnravelStruct(std::string const& symbol);
+
+ SymbolInfo* searchVarUnravelStructRaw(std::string const& symbol);
+ SymbolInfo* searchVarUnravelStructRaw(std::string const& symbol, optional<posInFile> const& position);
+
+ void addPlainFile();
+ };
+
+ struct AddDeclContexts: SymbolContext
+ {
+ unordered_map <std::string, SymbolInfo> additionalDecs;
+ AddDeclContexts(): SymbolContext() {}
+
+ explicit AddDeclContexts(posInFile loc):
+ SymbolContext(loc) {}
+
+ AddDeclContexts(posInFile loc, SymbolContext* contextParent):
+ SymbolContext(loc, contextParent) {}
+
+ ~AddDeclContexts() override = default;
+ optional<posRangeInFile> searchVarDecl(std::string const& symbol, optional<posInFile> const& position) override;
+ SymbolInfo const* searchVarRaw(std::string const& symbol) const override;
+ };
+}
diff --git a/graphics/asymptote/testv3d.asy b/graphics/asymptote/testv3d.asy
new file mode 100644
index 0000000000..ab558f7fd4
--- /dev/null
+++ b/graphics/asymptote/testv3d.asy
@@ -0,0 +1,202 @@
+triple[][][] Q0={
+ {
+ {(39.68504,0,68.0315),(37.91339,0,71.75197),(40.74803,0,71.75197),(42.51969,0,68.0315)},
+ {(39.68504,-22.22362,68.0315),(37.91339,-21.2315,71.75197),(40.74803,-22.8189,71.75197),(42.51969,-23.81102,68.0315)},
+ {(22.22362,-39.68504,68.0315),(21.2315,-37.91339,71.75197),(22.8189,-40.74803,71.75197),(23.81102,-42.51969,68.0315)},
+ {(0,-39.68504,68.0315),(0,-37.91339,71.75197),(0,-40.74803,71.75197),(0,-42.51969,68.0315)}
+ },{
+ {(0,-39.68504,68.0315),(0,-37.91339,71.75197),(0,-40.74803,71.75197),(0,-42.51969,68.0315)},
+ {(-22.22362,-39.68504,68.0315),(-21.2315,-37.91339,71.75197),(-22.8189,-40.74803,71.75197),(-23.81102,-42.51969,68.0315)},
+ {(-39.68504,-22.22362,68.0315),(-37.91339,-21.2315,71.75197),(-40.74803,-22.8189,71.75197),(-42.51969,-23.81102,68.0315)},
+ {(-39.68504,0,68.0315),(-37.91339,0,71.75197),(-40.74803,0,71.75197),(-42.51969,0,68.0315)}
+ },{
+ {(-39.68504,0,68.0315),(-37.91339,0,71.75197),(-40.74803,0,71.75197),(-42.51969,0,68.0315)},
+ {(-39.68504,22.22362,68.0315),(-37.91339,21.2315,71.75197),(-40.74803,22.8189,71.75197),(-42.51969,23.81102,68.0315)},
+ {(-22.22362,39.68504,68.0315),(-21.2315,37.91339,71.75197),(-22.8189,40.74803,71.75197),(-23.81102,42.51969,68.0315)},
+ {(0,39.68504,68.0315),(0,37.91339,71.75197),(0,40.74803,71.75197),(0,42.51969,68.0315)}
+ },{
+ {(0,39.68504,68.0315),(0,37.91339,71.75197),(0,40.74803,71.75197),(0,42.51969,68.0315)},
+ {(22.22362,39.68504,68.0315),(21.2315,37.91339,71.75197),(22.8189,40.74803,71.75197),(23.81102,42.51969,68.0315)},
+ {(39.68504,22.22362,68.0315),(37.91339,21.2315,71.75197),(40.74803,22.8189,71.75197),(42.51969,23.81102,68.0315)},
+ {(39.68504,0,68.0315),(37.91339,0,71.75197),(40.74803,0,71.75197),(42.51969,0,68.0315)}
+ },{
+ {(42.51969,0,68.0315),(49.60629,0,53.1496),(56.69291,0,38.26771),(56.69291,0,25.51181)},
+ {(42.51969,-23.81102,68.0315),(49.60629,-27.77952,53.1496),(56.69291,-31.74803,38.26771),(56.69291,-31.74803,25.51181)},
+ {(23.81102,-42.51969,68.0315),(27.77952,-49.60629,53.1496),(31.74803,-56.69291,38.26771),(31.74803,-56.69291,25.51181)},
+ {(0,-42.51969,68.0315),(0,-49.60629,53.1496),(0,-56.69291,38.26771),(0,-56.69291,25.51181)}
+ },{
+ {(0,-42.51969,68.0315),(0,-49.60629,53.1496),(0,-56.69291,38.26771),(0,-56.69291,25.51181)},
+ {(-23.81102,-42.51969,68.0315),(-27.77952,-49.60629,53.1496),(-31.74803,-56.69291,38.26771),(-31.74803,-56.69291,25.51181)},
+ {(-42.51969,-23.81102,68.0315),(-49.60629,-27.77952,53.1496),(-56.69291,-31.74803,38.26771),(-56.69291,-31.74803,25.51181)},
+ {(-42.51969,0,68.0315),(-49.60629,0,53.1496),(-56.69291,0,38.26771),(-56.69291,0,25.51181)}
+ },{
+ {(-42.51969,0,68.0315),(-49.60629,0,53.1496),(-56.69291,0,38.26771),(-56.69291,0,25.51181)},
+ {(-42.51969,23.81102,68.0315),(-49.60629,27.77952,53.1496),(-56.69291,31.74803,38.26771),(-56.69291,31.74803,25.51181)},
+ {(-23.81102,42.51969,68.0315),(-27.77952,49.60629,53.1496),(-31.74803,56.69291,38.26771),(-31.74803,56.69291,25.51181)},
+ {(0,42.51969,68.0315),(0,49.60629,53.1496),(0,56.69291,38.26771),(0,56.69291,25.51181)}
+ },{
+ {(0,42.51969,68.0315),(0,49.60629,53.1496),(0,56.69291,38.26771),(0,56.69291,25.51181)},
+ {(23.81102,42.51969,68.0315),(27.77952,49.60629,53.1496),(31.74803,56.69291,38.26771),(31.74803,56.69291,25.51181)},
+ {(42.51969,23.81102,68.0315),(49.60629,27.77952,53.1496),(56.69291,31.74803,38.26771),(56.69291,31.74803,25.51181)},
+ {(42.51969,0,68.0315),(49.60629,0,53.1496),(56.69291,0,38.26771),(56.69291,0,25.51181)}
+ },{
+ {(56.69291,0,25.51181),(56.69291,0,12.7559),(42.51969,0,6.377957),(42.51969,0,4.251961)},
+ {(56.69291,-31.74803,25.51181),(56.69291,-31.74803,12.7559),(42.51969,-23.81102,6.377957),(42.51969,-23.81102,4.251961)},
+ {(31.74803,-56.69291,25.51181),(31.74803,-56.69291,12.7559),(23.81102,-42.51969,6.377957),(23.81102,-42.51969,4.251961)},
+ {(0,-56.69291,25.51181),(0,-56.69291,12.7559),(0,-42.51969,6.377957),(0,-42.51969,4.251961)}
+ },{
+ {(0,-56.69291,25.51181),(0,-56.69291,12.7559),(0,-42.51969,6.377957),(0,-42.51969,4.251961)},
+ {(-31.74803,-56.69291,25.51181),(-31.74803,-56.69291,12.7559),(-23.81102,-42.51969,6.377957),(-23.81102,-42.51969,4.251961)},
+ {(-56.69291,-31.74803,25.51181),(-56.69291,-31.74803,12.7559),(-42.51969,-23.81102,6.377957),(-42.51969,-23.81102,4.251961)},
+ {(-56.69291,0,25.51181),(-56.69291,0,12.7559),(-42.51969,0,6.377957),(-42.51969,0,4.251961)}
+ },{
+ {(-56.69291,0,25.51181),(-56.69291,0,12.7559),(-42.51969,0,6.377957),(-42.51969,0,4.251961)},
+ {(-56.69291,31.74803,25.51181),(-56.69291,31.74803,12.7559),(-42.51969,23.81102,6.377957),(-42.51969,23.81102,4.251961)},
+ {(-31.74803,56.69291,25.51181),(-31.74803,56.69291,12.7559),(-23.81102,42.51969,6.377957),(-23.81102,42.51969,4.251961)},
+ {(0,56.69291,25.51181),(0,56.69291,12.7559),(0,42.51969,6.377957),(0,42.51969,4.251961)}
+ },{
+ {(0,56.69291,25.51181),(0,56.69291,12.7559),(0,42.51969,6.377957),(0,42.51969,4.251961)},
+ {(31.74803,56.69291,25.51181),(31.74803,56.69291,12.7559),(23.81102,42.51969,6.377957),(23.81102,42.51969,4.251961)},
+ {(56.69291,31.74803,25.51181),(56.69291,31.74803,12.7559),(42.51969,23.81102,6.377957),(42.51969,23.81102,4.251961)},
+ {(56.69291,0,25.51181),(56.69291,0,12.7559),(42.51969,0,6.377957),(42.51969,0,4.251961)}
+ },{
+ {(-45.35433,0,57.40157),(-65.19685,0,57.40157),(-76.53543,0,57.40157),(-76.53543,0,51.02362)},
+ {(-45.35433,-8.503932,57.40157),(-65.19685,-8.503932,57.40157),(-76.53543,-8.503932,57.40157),(-76.53543,-8.503932,51.02362)},
+ {(-42.51969,-8.503932,63.77952),(-70.86614,-8.503932,63.77952),(-85.03937,-8.503932,63.77952),(-85.03937,-8.503932,51.02362)},
+ {(-42.51969,0,63.77952),(-70.86614,0,63.77952),(-85.03937,0,63.77952),(-85.03937,0,51.02362)}
+ },{
+ {(-42.51969,0,63.77952),(-70.86614,0,63.77952),(-85.03937,0,63.77952),(-85.03937,0,51.02362)},
+ {(-42.51969,8.503932,63.77952),(-70.86614,8.503932,63.77952),(-85.03937,8.503932,63.77952),(-85.03937,8.503932,51.02362)},
+ {(-45.35433,8.503932,57.40157),(-65.19685,8.503932,57.40157),(-76.53543,8.503932,57.40157),(-76.53543,8.503932,51.02362)},
+ {(-45.35433,0,57.40157),(-65.19685,0,57.40157),(-76.53543,0,57.40157),(-76.53543,0,51.02362)}
+ },{
+ {(-76.53543,0,51.02362),(-76.53543,0,44.64566),(-70.86614,0,31.88976),(-56.69291,0,25.51181)},
+ {(-76.53543,-8.503932,51.02362),(-76.53543,-8.503932,44.64566),(-70.86614,-8.503932,31.88976),(-56.69291,-8.503932,25.51181)},
+ {(-85.03937,-8.503932,51.02362),(-85.03937,-8.503932,38.26771),(-75.11811,-8.503932,26.5748),(-53.85826,-8.503932,17.00787)},
+ {(-85.03937,0,51.02362),(-85.03937,0,38.26771),(-75.11811,0,26.5748),(-53.85826,0,17.00787)}
+ },{
+ {(-85.03937,0,51.02362),(-85.03937,0,38.26771),(-75.11811,0,26.5748),(-53.85826,0,17.00787)},
+ {(-85.03937,8.503932,51.02362),(-85.03937,8.503932,38.26771),(-75.11811,8.503932,26.5748),(-53.85826,8.503932,17.00787)},
+ {(-76.53543,8.503932,51.02362),(-76.53543,8.503932,44.64566),(-70.86614,8.503932,31.88976),(-56.69291,8.503932,25.51181)},
+ {(-76.53543,0,51.02362),(-76.53543,0,44.64566),(-70.86614,0,31.88976),(-56.69291,0,25.51181)}
+ },{
+ {(48.18897,0,40.3937),(73.70078,0,40.3937),(65.19685,0,59.52755),(76.53543,0,68.0315)},
+ {(48.18897,-18.70866,40.3937),(73.70078,-18.70866,40.3937),(65.19685,-7.086619,59.52755),(76.53543,-7.086619,68.0315)},
+ {(48.18897,-18.70866,17.00787),(87.87401,-18.70866,23.38582),(68.0315,-7.086619,57.40157),(93.5433,-7.086619,68.0315)},
+ {(48.18897,0,17.00787),(87.87401,0,23.38582),(68.0315,0,57.40157),(93.5433,0,68.0315)}
+ },{
+ {(48.18897,0,17.00787),(87.87401,0,23.38582),(68.0315,0,57.40157),(93.5433,0,68.0315)},
+ {(48.18897,18.70866,17.00787),(87.87401,18.70866,23.38582),(68.0315,7.086619,57.40157),(93.5433,7.086619,68.0315)},
+ {(48.18897,18.70866,40.3937),(73.70078,18.70866,40.3937),(65.19685,7.086619,59.52755),(76.53543,7.086619,68.0315)},
+ {(48.18897,0,40.3937),(73.70078,0,40.3937),(65.19685,0,59.52755),(76.53543,0,68.0315)}
+ },{
+ {(76.53543,0,68.0315),(79.37007,0,70.15748),(82.20472,0,70.15748),(79.37007,0,68.0315)},
+ {(76.53543,-7.086619,68.0315),(79.37007,-7.086619,70.15748),(82.20472,-4.251961,70.15748),(79.37007,-4.251961,68.0315)},
+ {(93.5433,-7.086619,68.0315),(99.92125,-7.086619,70.68897),(97.79527,-4.251961,71.22047),(90.70866,-4.251961,68.0315)},
+ {(93.5433,0,68.0315),(99.92125,0,70.68897),(97.79527,0,71.22047),(90.70866,0,68.0315)}
+ },{
+ {(93.5433,0,68.0315),(99.92125,0,70.68897),(97.79527,0,71.22047),(90.70866,0,68.0315)},
+ {(93.5433,7.086619,68.0315),(99.92125,7.086619,70.68897),(97.79527,4.251961,71.22047),(90.70866,4.251961,68.0315)},
+ {(76.53543,7.086619,68.0315),(79.37007,7.086619,70.15748),(82.20472,4.251961,70.15748),(79.37007,4.251961,68.0315)},
+ {(76.53543,0,68.0315),(79.37007,0,70.15748),(82.20472,0,70.15748),(79.37007,0,68.0315)}
+ },{
+ {(0,0,89.29133),(22.67716,0,89.29133),(0,0,80.7874),(5.669294,0,76.53543)},
+ {(0,0,89.29133),(22.67716,-12.7559,89.29133),(0,0,80.7874),(5.669294,-3.174809,76.53543)},
+ {(0,0,89.29133),(12.7559,-22.67716,89.29133),(0,0,80.7874),(3.174809,-5.669294,76.53543)},
+ {(0,0,89.29133),(0,-22.67716,89.29133),(0,0,80.7874),(0,-5.669294,76.53543)}
+ },{
+ {(0,0,89.29133),(0,-22.67716,89.29133),(0,0,80.7874),(0,-5.669294,76.53543)},
+ {(0,0,89.29133),(-12.7559,-22.67716,89.29133),(0,0,80.7874),(-3.174809,-5.669294,76.53543)},
+ {(0,0,89.29133),(-22.67716,-12.7559,89.29133),(0,0,80.7874),(-5.669294,-3.174809,76.53543)},
+ {(0,0,89.29133),(-22.67716,0,89.29133),(0,0,80.7874),(-5.669294,0,76.53543)}
+ },{
+ {(0,0,89.29133),(-22.67716,0,89.29133),(0,0,80.7874),(-5.669294,0,76.53543)},
+ {(0,0,89.29133),(-22.67716,12.7559,89.29133),(0,0,80.7874),(-5.669294,3.174809,76.53543)},
+ {(0,0,89.29133),(-12.7559,22.67716,89.29133),(0,0,80.7874),(-3.174809,5.669294,76.53543)},
+ {(0,0,89.29133),(0,22.67716,89.29133),(0,0,80.7874),(0,5.669294,76.53543)}
+ },{
+ {(0,0,89.29133),(0,22.67716,89.29133),(0,0,80.7874),(0,5.669294,76.53543)},
+ {(0,0,89.29133),(12.7559,22.67716,89.29133),(0,0,80.7874),(3.174809,5.669294,76.53543)},
+ {(0,0,89.29133),(22.67716,12.7559,89.29133),(0,0,80.7874),(5.669294,3.174809,76.53543)},
+ {(0,0,89.29133),(22.67716,0,89.29133),(0,0,80.7874),(5.669294,0,76.53543)}
+ },{
+ {(5.669294,0,76.53543),(11.33858,0,72.28346),(36.85039,0,72.28346),(36.85039,0,68.0315)},
+ {(5.669294,-3.174809,76.53543),(11.33858,-6.349609,72.28346),(36.85039,-20.63622,72.28346),(36.85039,-20.63622,68.0315)},
+ {(3.174809,-5.669294,76.53543),(6.349609,-11.33858,72.28346),(20.63622,-36.85039,72.28346),(20.63622,-36.85039,68.0315)},
+ {(0,-5.669294,76.53543),(0,-11.33858,72.28346),(0,-36.85039,72.28346),(0,-36.85039,68.0315)}
+ },{
+ {(0,-5.669294,76.53543),(0,-11.33858,72.28346),(0,-36.85039,72.28346),(0,-36.85039,68.0315)},
+ {(-3.174809,-5.669294,76.53543),(-6.349609,-11.33858,72.28346),(-20.63622,-36.85039,72.28346),(-20.63622,-36.85039,68.0315)},
+ {(-5.669294,-3.174809,76.53543),(-11.33858,-6.349609,72.28346),(-36.85039,-20.63622,72.28346),(-36.85039,-20.63622,68.0315)},
+ {(-5.669294,0,76.53543),(-11.33858,0,72.28346),(-36.85039,0,72.28346),(-36.85039,0,68.0315)},
+ },{
+ {(-5.669294,0,76.53543),(-11.33858,0,72.28346),(-36.85039,0,72.28346),(-36.85039,0,68.0315)},
+ {(-5.669294,3.174809,76.53543),(-11.33858,6.349609,72.28346),(-36.85039,20.63622,72.28346),(-36.85039,20.63622,68.0315)},
+ {(-3.174809,5.669294,76.53543),(-6.349609,11.33858,72.28346),(-20.63622,36.85039,72.28346),(-20.63622,36.85039,68.0315)},
+ {(0,5.669294,76.53543),(0,11.33858,72.28346),(0,36.85039,72.28346),(0,36.85039,68.0315)}
+ },{
+ {(0,5.669294,76.53543),(0,11.33858,72.28346),(0,36.85039,72.28346),(0,36.85039,68.0315)},
+ {(3.174809,5.669294,76.53543),(6.349609,11.33858,72.28346),(20.63622,36.85039,72.28346),(20.63622,36.85039,68.0315)},
+ {(5.669294,3.174809,76.53543),(11.33858,6.349609,72.28346),(36.85039,20.63622,72.28346),(36.85039,20.63622,68.0315)},
+ {(5.669294,0,76.53543),(11.33858,0,72.28346),(36.85039,0,72.28346),(36.85039,0,68.0315)},
+ },{
+ {(0,0,0),(40.3937,0,0),(42.51969,0,2.12598),(42.51969,0,4.251961)},
+ {(0,0,0),(40.3937,22.62047,0),(42.51969,23.81102,2.12598),(42.51969,23.81102,4.251961)},
+ {(0,0,0),(22.62047,40.3937,0),(23.81102,42.51969,2.12598),(23.81102,42.51969,4.251961)},
+ {(0,0,0),(0,40.3937,0),(0,42.51969,2.12598),(0,42.51969,4.251961)}
+ },{
+ {(0,0,0),(0,40.3937,0),(0,42.51969,2.12598),(0,42.51969,4.251961)},
+ {(0,0,0),(-22.62047,40.3937,0),(-23.81102,42.51969,2.12598),(-23.81102,42.51969,4.251961)},
+ {(0,0,0),(-40.3937,22.62047,0),(-42.51969,23.81102,2.12598),(-42.51969,23.81102,4.251961)},
+ {(0,0,0),(-40.3937,0,0),(-42.51969,0,2.12598),(-42.51969,0,4.251961)}
+ },{
+ {(0,0,0),(-40.3937,0,0),(-42.51969,0,2.12598),(-42.51969,0,4.251961)},
+ {(0,0,0),(-40.3937,-22.62047,0),(-42.51969,-23.81102,2.12598),(-42.51969,-23.81102,4.251961)},
+ {(0,0,0),(-22.62047,-40.3937,0),(-23.81102,-42.51969,2.12598),(-23.81102,-42.51969,4.251961)},
+ {(0,0,0),(0,-40.3937,0),(0,-42.51969,2.12598),(0,-42.51969,4.251961)}
+ },{
+ {(0,0,0),(0,-40.3937,0),(0,-42.51969,2.12598),(0,-42.51969,4.251961)},
+ {(0,0,0),(22.62047,-40.3937,0),(23.81102,-42.51969,2.12598),(23.81102,-42.51969,4.251961)},
+ {(0,0,0),(40.3937,-22.62047,0),(42.51969,-23.81102,2.12598),(42.51969,-23.81102,4.251961)},
+ {(0,0,0),(40.3937,0,0),(42.51969,0,2.12598),(42.51969,0,4.251961)}
+ }
+};
+
+triple[][][] Q=copy(Q0);
+
+void writev3d(string prefix) {
+ file fout=output(prefix+".v3d",mode="xdr");
+ // write(fout,"V3D");
+ for(triple[][] q : Q) {
+ for(int i=0; i < 4; ++i)
+ for(int j=0; j < 4; ++j)
+ write(fout,q);
+ }
+ close(fout);
+}
+
+triple[][][] P;
+
+void readv3d(string prefix) {
+ file fin=input(prefix+".v3d",mode="xdr");
+ // string signature=getc(fin)+getc(fin)+getc(fin);
+ // write(signature);
+ triple[][] q=new triple[4][4];
+ fin.dimension(4,4);
+ while(true) {
+ q=fin;
+ if(eof(fin)) break;
+ P.push(copy(q));
+ }
+}
+
+writev3d("test");
+readv3d("test");
+
+
+import three;
+size(20cm);
+
+currentprojection=perspective(250,-250,250);
+currentlight=Viewport;
+draw(surface(P),blue,render(compression=Low));
diff --git a/graphics/asymptote/texfile.cc b/graphics/asymptote/texfile.cc
index b872095e1d..d10ed379d0 100644
--- a/graphics/asymptote/texfile.cc
+++ b/graphics/asymptote/texfile.cc
@@ -24,6 +24,7 @@ texfile::texfile(const string& texname, const bbox& box, bool pipe)
: box(box)
{
texengine=getSetting<string>("tex");
+ pdf=settings::pdf(texengine);
inlinetex=getSetting<bool>("inlinetex");
Hoffset=inlinetex ? box.right : box.left;
out=new ofstream(texname.c_str());
@@ -60,7 +61,7 @@ void texfile::miniprologue()
} else *out << "\\nopagenumbers" << newl;
}
-void texfile::prologue()
+void texfile::prologue(bool deconstruct)
{
if(inlinetex) {
string prename=buildname(settings::outname(),"pre");
@@ -77,7 +78,7 @@ void texfile::prologue()
*out << "\\definepapersize[asy][width=" << width << "bp,height="
<< height << "bp]" << newl
<< "\\setuppapersize[asy][asy]" << newl;
- } else if(settings::pdf(texengine)) {
+ } else if(pdf) {
if(width > 0)
*out << "\\pdfpagewidth=" << width << "bp" << newl;
*out << "\\ifx\\pdfhorigin\\undefined" << newl
@@ -104,7 +105,7 @@ void texfile::prologue()
*out << "\\pagestyle{empty}" << newl
<< "\\textheight=" << height+18.0 << "bp" << newl
<< "\\textwidth=" << width+18.0 << "bp" << newl;
- if(settings::pdf(texengine))
+ if(pdf)
*out << "\\parindent=0pt" << newl
<< "\\oddsidemargin=0pt" << newl
<< "\\evensidemargin=\\oddsidemargin" << newl
@@ -126,9 +127,13 @@ void texfile::prologue()
<< "\\starttext\\hbox{%" << newl;
} else {
*out << "\\footline={}" << newl;
- if(settings::pdf(texengine)) {
- *out << "\\hoffset=-20pt" << newl
- << "\\voffset=0pt" << newl;
+ if(pdf) {
+ if(settings::lua(texengine))
+ *out << "\\hoffset=-92bp" << newl
+ << "\\voffset=-1in" << newl;
+ else
+ *out << "\\hoffset=-20pt" << newl
+ << "\\voffset=0pt" << newl;
} else {
*out << "\\hoffset=36.6pt" << newl
<< "\\voffset=54.0pt" << newl;
@@ -136,8 +141,8 @@ void texfile::prologue()
}
}
}
-
- beginpage();
+ if(!deconstruct)
+ beginpage();
}
void texfile::beginlayer(const string& psname, bool postscript)
@@ -149,7 +154,6 @@ void texfile::beginlayer(const string& psname, bool postscript)
else {
*out << "{\\catcode`\"=12%" << newl
<< "\\includegraphics";
- bool pdf=settings::pdf(texengine);
string name=stripExt(psname);
if(inlinetex) {
size_t pos=name.rfind("-");
@@ -248,13 +252,18 @@ void texfile::beginpicture(const bbox& b)
verbatimline("%");
}
-void texfile::endpicture(const bbox& b)
+void texfile::endpicture(const bbox& b, bool newPage)
{
verbatimline(settings::endpicture(texengine));
- verbatim("\\kern");
- double width=b.right-b.left;
- write(-width*ps2tex);
- verbatimline("pt%");
+ if(newPage) {
+ texfile::newpage(b);
+ BBox(b);
+ } else {
+ verbatim("\\kern");
+ double width=b.right-b.left;
+ write(-width*ps2tex);
+ verbatimline("pt%");
+ }
}
void texfile::gsave(bool)
@@ -281,6 +290,11 @@ void texfile::endspecial()
*out << settings::endspecial() << newl;
}
+void texfile::special(const string& s)
+{
+ *out << "\\special{" << s << "}%" << newl;
+}
+
void texfile::beginraw()
{
*out << "\\ASYraw{" << newl;
@@ -294,7 +308,7 @@ void texfile::endraw()
void texfile::put(const string& label, const transform& T, const pair& z,
const pair& align)
{
- double sign=settings::pdf(texengine) ? 1.0 : -1.0;
+ double sign=pdf ? 1.0 : -1.0;
if(label.empty()) return;
diff --git a/graphics/asymptote/texfile.h b/graphics/asymptote/texfile.h
index 0c16fc91f1..41a2378093 100644
--- a/graphics/asymptote/texfile.h
+++ b/graphics/asymptote/texfile.h
@@ -127,9 +127,11 @@ void texdefines(T& out, mem::list<string>& preamble=processData().TeXpreamble,
bool latex=settings::latex(texengine);
bool inlinetex=settings::getSetting<bool>("inlinetex");
if(pipe || !inlinetex) {
+ bool lua=settings::lua(texengine);
if(latex) {
- if(texengine == "lualatex") {
- out << "\\ifx\\pdfpagewidth\\undefined\\let\\pdfpagewidth\\paperwidth"
+ if(lua) {
+ out << "\\edef\\pdfpageattr{\\pdfvariable pageattr}" << newl
+ << "\\ifx\\pdfpagewidth\\undefined\\let\\pdfpagewidth\\paperwidth"
<< "\\fi" << newl
<< "\\ifx\\pdfpageheight\\undefined\\let\\pdfpageheight"
<< "\\paperheight"
@@ -141,6 +143,15 @@ void texdefines(T& out, mem::list<string>& preamble=processData().TeXpreamble,
<< "\\usepackage{graphicx}" << newl
<< "\\let\\paperwidth\\paperwidthsave" << newl;
}
+ } else {
+ if(lua) {
+ out << "\\edef\\pdfpageattr{\\pdfvariable pageattr}" << newl
+ << "\\ifx\\pdfpagewidth\\undefined\\let\\pdfpagewidth\\pagewidth"
+ << "\\fi" << newl
+ << "\\ifx\\pdfpageheight\\undefined\\let\\pdfpageheight"
+ << "\\pageheight"
+ << "\\fi" << newl;
+ }
}
texpreamble(out,preamble,pipe);
}
@@ -216,6 +227,7 @@ protected:
bool inlinetex;
double Hoffset;
int level;
+ bool pdf;
public:
string texengine;
@@ -223,7 +235,7 @@ public:
texfile(const string& texname, const bbox& box, bool pipe=false);
virtual ~texfile();
- void prologue();
+ void prologue(bool deconstruct=false);
virtual void beginpage() {}
void epilogue(bool pipe=false);
@@ -242,6 +254,8 @@ public:
void endspecial();
+ void special(const string &s);
+
void beginraw();
void endraw();
@@ -252,8 +266,34 @@ public:
bool toplevel() {return level == 0;}
- void beginpicture(const bbox& b);
- void endpicture(const bbox& b);
+ virtual void beginpicture(const bbox& b);
+ void endpicture(const bbox& b, bool newPage=false);
+
+ virtual void newpage(const bbox&) {
+ verbatimline(settings::newpage(texengine));
+ }
+
+ void BBox(const bbox& b) {
+ bbox B=b.shift(pair(-hoffset(),-voffset()));
+ if(pdf) {
+ if(settings::xe(texengine))
+ *out << "\\special{pdf: put @thispage <</MediaBox [" << B << "]>>}%"
+ << newl;
+ else
+ if(settings::context(texengine)) {
+ double width=B.right-B.left;
+ double height=B.top-B.bottom;
+ *out << "\\definepapersize[asy]["
+ << "width=" << width << "bp,"
+ << "height=" << height << "bp]%" << newl
+ << "\\setuppapersize[asy][asy]%" << newl
+ << "\\setuplayout["
+ << "backspace=" << -B.left << "bp,"
+ << "topspace=" << B.top-(box.top-box.bottom) << "bp]%" << newl;
+ } else
+ *out << "\\pdfpageattr{/MediaBox [" << B << "]}%" << newl;
+ }
+ }
void writepair(pair z) {
*out << z;
@@ -271,6 +311,8 @@ public:
void beginlayer(const string& psname, bool postscript);
void endlayer();
+
+ virtual void Offset(const bbox& box, bool special=false) {};
};
class svgtexfile : public texfile {
@@ -282,20 +324,56 @@ class svgtexfile : public texfile {
bool inspecial;
static string nl;
pair offset;
+ bool first;
+ bool deconstruct;
public:
- svgtexfile(const string& texname, const bbox& box, bool pipe=false) :
- texfile(texname,box,pipe) {
- clipcount=0;
- gradientcount=0;
- gouraudcount=0;
- tensorcount=0;
+ svgtexfile(const string& texname, const bbox& box, bool pipe=false,
+ bool deconstruct=false) :
+ texfile(texname,box,pipe), deconstruct(deconstruct) {
inspecial=false;
*out << "\\catcode`\\%=12" << newl
<< "\\def\\percent{%}" << newl
<< "\\catcode`\\%=14" << newl;
+ first=true;
+ Offset(box);
+ }
+
+ void Offset(const bbox& b, bool special=false) {
+ box=b;
+ if(special) {
+ texfile::beginpicture(b);
+ pair bboxshift=pair(-2*b.left,b.top-b.bottom);
+ bbox b0=svgbbox(b,bboxshift);
+ *out << "\\special{dvisvgm:bbox f "
+ << b0.left << "bp "
+ << b0.bottom << "bp "
+ << b0.right << "bp "
+ << b0.top << "bp}%" << newl;
+ }
+
+ Hoffset=inlinetex ? box.right : box.left;
offset=pair(box.left,box.top);
+ clipstack=mem::stack<size_t>();
+ clipcount=0;
+ gradientcount=0;
+ gouraudcount=0;
+ tensorcount=0;
+ }
+
+ void beginpicture(const bbox& b) {
+ Offset(b,true);
+ }
+
+ void newpage(const bbox& b) {
+ if(deconstruct) {
+ if(first)
+ first=false;
+ else
+ endpicture(b,true);
+ beginpicture(b);
+ }
}
void writeclip(path p, bool newPath=true) {
@@ -317,7 +395,6 @@ public:
void beginspecial(bool def=false);
void endspecial();
- // Prevent unwanted page breaks.
void beginpage() {
beginpicture(box);
}
diff --git a/graphics/asymptote/tinyexr.cc b/graphics/asymptote/tinyexr.cc
new file mode 100644
index 0000000000..c23ec679ef
--- /dev/null
+++ b/graphics/asymptote/tinyexr.cc
@@ -0,0 +1,14 @@
+/**
+* @file tinyexr.cc
+* @brief An implementation object file for tinyexr mandated by the repository.
+*
+* On Windows, use vcpkg to install zlib instead of nuget. On Linux, this should work naturally
+*/
+
+#include <zlib.h>
+
+#define TINYEXR_IMPLEMENTATION
+#define TINYEXR_USE_MINIZ 0
+#define TINYEXR_USE_THREAD 1
+
+#include "cudareflect/tinyexr/tinyexr.h" \ No newline at end of file
diff --git a/graphics/asymptote/triple.h b/graphics/asymptote/triple.h
index f2dfb61af6..c1639ceedd 100644
--- a/graphics/asymptote/triple.h
+++ b/graphics/asymptote/triple.h
@@ -18,6 +18,7 @@
#include "common.h"
#include "angle.h"
#include "pair.h"
+#include "xstream.h"
namespace camp {
@@ -327,6 +328,15 @@ public:
return out;
}
+
+#ifdef HAVE_RPC_RPC_H
+ friend xdr::oxstream& operator << (xdr::oxstream& out, triple const& v)
+ {
+ out << v.x << v.y << v.z;
+ return out;
+ }
+#endif
+
};
triple expi(double theta, double phi);
diff --git a/graphics/asymptote/v3dfile.cc b/graphics/asymptote/v3dfile.cc
new file mode 100644
index 0000000000..d8eebab50c
--- /dev/null
+++ b/graphics/asymptote/v3dfile.cc
@@ -0,0 +1,353 @@
+/*
+ * v3dfile.cc
+ * V3D Export class
+ *
+ * Supakorn "Jamie" Rassameemasmuang <jamievlin@outlook.com> and
+ * John C. Bowman
+ */
+
+#include "v3dfile.h"
+
+#ifdef HAVE_RPC_RPC_H
+
+#include "drawelement.h"
+#include "makeUnique.h"
+
+namespace camp
+{
+
+using settings::getSetting;
+
+void v3dfile::writeInit()
+{
+ uint32_t doubleprecision = !singleprecision;
+ getXDRFile() << v3dVersion << doubleprecision;
+ addHeaders();
+
+ camp::clearCenters();
+ camp::clearMaterials();
+}
+
+void v3dfile::addHeaders()
+{
+ getXDRFile() << v3dtypes::header;
+ std::vector<std::unique_ptr<AHeader>> headers;
+
+ headers.emplace_back(make_unique<Uint32Header>(v3dheadertypes::canvasWidth, gl::fullWidth));
+ headers.emplace_back(make_unique<Uint32Header>(v3dheadertypes::canvasHeight, gl::fullHeight));
+ headers.emplace_back(make_unique<Uint32Header>(v3dheadertypes::absolute, getSetting<bool>("absolute")));
+ headers.emplace_back(make_unique<TripleHeader>(v3dheadertypes::minBound, triple(gl::xmin, gl::ymin, gl::zmin)));
+ headers.emplace_back(make_unique<TripleHeader>(v3dheadertypes::maxBound, triple(gl::xmax, gl::ymax, gl::zmax)));
+ headers.emplace_back(make_unique<Uint32Header>(v3dheadertypes::orthographic, gl::orthographic));
+ headers.emplace_back(make_unique<DoubleHeader>(v3dheadertypes::angleOfView, gl::Angle));
+ headers.emplace_back(make_unique<DoubleHeader>(v3dheadertypes::initialZoom, gl::Zoom0));
+ if(gl::Shift != pair(0.0,0.0))
+ headers.emplace_back(make_unique<PairHeader>(v3dheadertypes::viewportShift, gl::Shift*gl::Zoom0));
+ headers.emplace_back(make_unique<PairHeader>(v3dheadertypes::viewportMargin, gl::Margin));
+
+ for(size_t i=0; i < gl::nlights; ++i) {
+ size_t i4=4*i;
+ headers.emplace_back(make_unique<LightHeader>(
+ gl::Lights[i],
+ prc::RGBAColour(gl::Diffuse[i4], gl::Diffuse[i4+1], gl::Diffuse[i4+2], 1.0)
+ ));
+ }
+
+ headers.emplace_back(make_unique<RGBAHeader>(
+ v3dheadertypes::background,
+ prc::RGBAColour(gl::Background[0],gl::Background[1],gl::Background[2],gl::Background[3])));
+
+ headers.emplace_back(make_unique<DoubleHeader>(v3dheadertypes::zoomFactor, getSetting<double>("zoomfactor")));
+ headers.emplace_back(make_unique<DoubleHeader>(
+ v3dheadertypes::zoomPinchFactor, getSetting<double>("zoomPinchFactor")));
+ headers.emplace_back(make_unique<DoubleHeader>(
+ v3dheadertypes::zoomPinchCap, getSetting<double>("zoomPinchCap")));
+ headers.emplace_back(make_unique<DoubleHeader>(v3dheadertypes::zoomStep, getSetting<double>("zoomstep")));
+ headers.emplace_back(make_unique<DoubleHeader>(
+ v3dheadertypes::shiftHoldDistance, getSetting<double>("shiftHoldDistance")));
+ headers.emplace_back(make_unique<DoubleHeader>(
+ v3dheadertypes::shiftWaitTime, getSetting<double>("shiftWaitTime")));
+ headers.emplace_back(make_unique<DoubleHeader>(
+ v3dheadertypes::vibrateTime, getSetting<double>("vibrateTime")));
+
+ getXDRFile() << (uint32_t) headers.size();
+ for(const auto& header : headers) {
+ getXDRFile() << header->ty << header->getWordSize(singleprecision);
+ header->writeContent(getXDRFile());
+ }
+}
+
+void v3dfile::addCenters()
+{
+ getXDRFile() << v3dtypes::centers;
+ size_t nelem=drawElement::centers.size();
+ getXDRFile() << (uint32_t) nelem;
+ if(nelem > 0)
+ addTriples(drawElement::centers.data(), nelem);
+}
+
+void v3dfile::addTriples(triple const* triples, size_t n)
+{
+ for(size_t i=0; i < n; ++i)
+ getXDRFile() << triples[i];
+}
+
+void v3dfile::addColors(prc::RGBAColour const* col, size_t nc)
+{
+ for(size_t i=0; i < nc; ++i)
+ getXDRFile() << col[i];
+}
+
+
+void v3dfile::addPatch(triple const* controls, triple const& Min,
+ triple const& Max, prc::RGBAColour const* c)
+{
+ getXDRFile() << (c ? v3dtypes::bezierPatchColor : v3dtypes::bezierPatch);
+ addTriples(controls,16);
+ addCenterIndexMat();
+
+ if(c)
+ addColors(c,4);
+}
+
+void v3dfile::addStraightPatch(triple const* controls, triple const& Min,
+ triple const& Max, prc::RGBAColour const* c)
+{
+ getXDRFile() << (c ? v3dtypes::quadColor : v3dtypes::quad);
+ addTriples(controls,4);
+ addCenterIndexMat();
+
+ if(c)
+ addColors(c,4);
+}
+
+void v3dfile::addBezierTriangle(triple const* controls, triple const& Min,
+ triple const& Max, prc::RGBAColour const* c)
+{
+ getXDRFile() << (c ? v3dtypes::bezierTriangleColor : v3dtypes::bezierTriangle);
+ addTriples(controls,10);
+ addCenterIndexMat();
+
+ if(c)
+ addColors(c,3);
+}
+
+void v3dfile::addStraightBezierTriangle(triple const* controls, triple const& Min,
+ triple const& Max, prc::RGBAColour const* c)
+{
+ getXDRFile() << (c ? v3dtypes::triangleColor : v3dtypes::triangle);
+ addTriples(controls,3);
+ addCenterIndexMat();
+
+ if(c)
+ addColors(c,3);
+}
+
+void v3dfile::addMaterial(Material const& mat)
+{
+ getXDRFile() << v3dtypes::material;
+ addvec4(mat.diffuse);
+ addvec4(mat.emissive);
+ addvec4(mat.specular);
+ glm::vec4 vec=mat.parameters;
+ getXDRFile() << static_cast<float>(vec.x) << static_cast<float>(vec.y)
+ << static_cast<float>(vec.z);
+}
+
+void v3dfile::addCenterIndexMat()
+{
+ getXDRFile() << (uint32_t) drawElement::centerIndex << (uint32_t) materialIndex;
+}
+
+void v3dfile::addvec4(glm::vec4 const& vec)
+{
+ getXDRFile() << static_cast<float>(vec.x) << static_cast<float>(vec.y)
+ << static_cast<float>(vec.z) << static_cast<float>(vec.w);
+}
+
+void v3dfile::addHemisphere(triple const& center, double radius, double const& polar, double const& azimuth)
+{
+ getXDRFile() << v3dtypes::halfSphere << center << radius;
+ addCenterIndexMat();
+ getXDRFile() << polar << azimuth;
+}
+
+void v3dfile::addSphere(triple const& center, double radius)
+{
+ getXDRFile() << v3dtypes::sphere << center << radius;
+ addCenterIndexMat();
+}
+
+void
+v3dfile::addCylinder(triple const& center, double radius, double height, double const& polar, double const& azimuth,
+ bool core)
+{
+ getXDRFile() << v3dtypes::cylinder << center << radius << height;
+ addCenterIndexMat();
+ getXDRFile() << polar << azimuth << core;
+}
+
+void v3dfile::addDisk(triple const& center, double radius, double const& polar, double const& azimuth)
+{
+ getXDRFile() << v3dtypes::disk << center << radius;
+ addCenterIndexMat();
+ getXDRFile() << polar << azimuth;
+}
+
+void v3dfile::addTube(triple const* g, double width, triple const& Min, triple const& Max, bool core)
+{
+ getXDRFile() << v3dtypes::tube;
+ for(int i=0; i < 4; ++i)
+ getXDRFile() << g[i];
+ getXDRFile() << width;
+ addCenterIndexMat();
+ getXDRFile() << core;
+}
+
+void v3dfile::addTriangles(size_t nP, triple const* P, size_t nN, triple const* N, size_t nC, prc::RGBAColour const* C,
+ size_t nI, uint32_t const (* PI)[3], uint32_t const (* NI)[3], uint32_t const (* CI)[3],
+ triple const& Min, triple const& Max)
+{
+ getXDRFile() << v3dtypes::triangles;
+ getXDRFile() << (uint32_t) nI;
+
+ getXDRFile() << (uint32_t) nP;
+ addTriples(P,nP);
+
+ getXDRFile() << (uint32_t) nN;
+ addTriples(N,nN);
+
+ bool explicitNI=true;
+ for(size_t i=0; i < nI; ++i) {
+ const uint32_t *PIi=PI[i];
+ const uint32_t *NIi=NI[i];
+ if(!distinct(NIi,PIi)) {
+ explicitNI=false;
+ break;
+ }
+ }
+ getXDRFile() << (uint32_t) explicitNI;
+
+ getXDRFile() << (uint32_t) nC;
+ bool explicitCI=true;
+ if(nC) {
+ addColors(C,nC);
+ for(size_t i=0; i < nI; ++i) {
+ const uint32_t *PIi=PI[i];
+ const uint32_t *CIi=CI[i];
+ if(!distinct(CIi,PIi)) {
+ explicitNI=false;
+ break;
+ }
+ }
+ getXDRFile() << (uint32_t) explicitCI;
+ }
+
+ for(size_t i=0; i < nI; ++i) {
+ const uint32_t *PIi=PI[i];
+ const uint32_t *NIi=NI[i];
+ addIndices(PIi);
+ if(explicitNI)
+ addIndices(NIi);
+ if(nC) {
+ const uint32_t *CIi=CI[i];
+ if(explicitCI)
+ addIndices(CIi);
+ }
+ }
+
+ addCenterIndexMat();
+}
+
+void v3dfile::addIndices(uint32_t const* v)
+{
+ getXDRFile() << v[0] << v[1] << v[2];
+}
+
+void v3dfile::addCurve(triple const& z0, triple const& c0, triple const& c1, triple const& z1, triple const& Min,
+ triple const& Max)
+{
+ getXDRFile() << v3dtypes::curve << z0 << c0 << c1 << z1;
+ addCenterIndexMat();
+
+}
+
+void v3dfile::addCurve(triple const& z0, triple const& z1, triple const& Min, triple const& Max)
+{
+ getXDRFile() << v3dtypes::line << z0 << z1;
+ addCenterIndexMat();
+}
+
+void v3dfile::addPixel(triple const& z0, double width, triple const& Min, triple const& Max)
+{
+ getXDRFile() << v3dtypes::pixel << z0 << width;
+ getXDRFile() << (uint32_t) materialIndex;
+}
+
+void v3dfile::finalize()
+{
+ if(!finalized) {
+ addCenters();
+ finalized=true;
+ }
+}
+
+// gzv3dfile
+
+xdr::oxstream& gzv3dfile::getXDRFile()
+{
+ return memxdrfile;
+}
+
+gzv3dfile::gzv3dfile(string const& name, bool singleprecision): v3dfile(singleprecision), memxdrfile(singleprecision), name(name), destroyed(false)
+{
+ writeInit();
+}
+
+gzv3dfile::~gzv3dfile()
+{
+ close();
+}
+
+void gzv3dfile::close()
+{
+ if(!destroyed) {
+ finalize();
+ memxdrfile.close();
+ gzFile file=gzopen(name.c_str(), "wb9");
+ gzwrite(file,data(),length());
+ gzclose(file);
+ if(settings::verbose > 0)
+ cout << "Wrote " << name << endl;
+ destroyed=true;
+ }
+}
+
+char const* gzv3dfile::data() const
+{
+ return memxdrfile.stream();
+}
+
+size_t const& gzv3dfile::length() const
+{
+ return memxdrfile.getLength();
+}
+
+uint32_t LightHeader::getWordSize(bool singleprecision) const
+{
+ return (singleprecision ? 1 : 2)*3+3;
+}
+
+void LightHeader::writeContent(xdr::oxstream& ox) const
+{
+ ox << direction << (float) color.R << (float) color.G << (float) color.B;
+}
+
+LightHeader::LightHeader(triple const& direction, prc::RGBAColour const& color) :
+ AHeader(v3dheadertypes::light), direction(direction), color(color)
+{
+}
+
+} //namespace camp
+
+#endif
diff --git a/graphics/asymptote/v3dfile.h b/graphics/asymptote/v3dfile.h
new file mode 100644
index 0000000000..3120be7716
--- /dev/null
+++ b/graphics/asymptote/v3dfile.h
@@ -0,0 +1,176 @@
+/*
+ * v3dfile.h
+ * Header file for v3d export and types
+ *
+ * Supakorn "Jamie" Rassameemasmuang <jamievlin@outlook.com> and
+ * John C. Bowman
+ */
+
+#ifndef V3DFILE_H
+#define V3DFILE_H
+
+#include <prc/oPRCFile.h>
+#include <zlib.h>
+
+#include "common.h"
+
+#ifdef HAVE_RPC_RPC_H
+
+#include "abs3doutfile.h"
+#include "xstream.h"
+#include "triple.h"
+#include "material.h"
+#include "glrender.h"
+#define transform transform_
+#include "v3dtypes.h"
+#undef transform
+#include "v3dheadertypes.h"
+
+namespace camp
+{
+
+class AHeader
+{
+public:
+ v3dheadertypes ty;
+
+ AHeader(v3dheadertypes const& ty) : ty(ty) {}
+ virtual ~AHeader() = default;
+ virtual uint32_t getWordSize(bool singleprecision) const = 0;
+ virtual void writeContent(xdr::oxstream& ox) const = 0;
+};
+
+template<typename T, uint32_t realWords, uint32_t floatWords=0>
+class SingleObjectHeader : public AHeader
+{
+public:
+ SingleObjectHeader(v3dheadertypes const& ty, T const& ob) : AHeader(ty), obj(ob)
+ {
+ }
+ ~SingleObjectHeader() override = default;
+
+protected:
+ uint32_t getWordSize(bool singleprecision) const override
+ {
+ return (singleprecision ? 1 : 2)*realWords+floatWords;
+ }
+
+ void writeContent(xdr::oxstream &ox) const override
+ {
+ ox << obj;
+ }
+
+private:
+ T obj;
+};
+
+using open_mode=xdr::xios::open_mode;
+using TripleHeader=SingleObjectHeader<triple,3>;
+using PairHeader=SingleObjectHeader<pair,2>;
+using DoubleHeader=SingleObjectHeader<double,1>;
+using Uint32Header=SingleObjectHeader<uint32_t,0,1>;
+using RGBAHeader=SingleObjectHeader<prc::RGBAColour,0,4>;
+
+const unsigned int v3dVersion=1;
+
+class LightHeader : public AHeader
+{
+public:
+ LightHeader(triple const& direction, prc::RGBAColour const& color);
+ ~LightHeader() override=default;
+
+protected:
+ [[nodiscard]]
+ uint32_t getWordSize(bool singleprecision) const override;
+ void writeContent(xdr::oxstream &ox) const override;
+
+private:
+ triple direction;
+ prc::RGBAColour color;
+};
+
+class v3dfile : public abs3Doutfile {
+private:
+ bool finalized;
+public:
+ v3dfile(bool singleprecision=false) : abs3Doutfile(singleprecision),
+ finalized(false) {}
+ void writeInit();
+ void finalize();
+
+ void addPatch(triple const* controls, triple const& Min, triple const& Max, prc::RGBAColour const* c) override;
+ void addStraightPatch(
+ triple const* controls, triple const& Min, triple const& Max, prc::RGBAColour const* c) override;
+ void addBezierTriangle(
+ triple const* control, triple const& Min, triple const& Max, prc::RGBAColour const* c) override;
+ void addStraightBezierTriangle(
+ triple const* controls, triple const& Min, triple const& Max, prc::RGBAColour const* c) override;
+
+
+ void addMaterial(Material const& mat) override;
+
+ void addSphere(triple const& center, double radius) override;
+ void addHemisphere(triple const& center, double radius, double const& polar, double const& azimuth) override;
+
+ void addCylinder(triple const& center, double radius, double height,
+ double const& polar, const double& azimuth,
+ bool core) override;
+ void addDisk(triple const& center, double radius,
+ double const& polar, const double& azimuth) override;
+ void addTube(const triple *g, double width,
+ const triple& Min, const triple& Max, bool core) override;
+
+ void addTriangles(size_t nP, const triple* P, size_t nN,
+ const triple* N, size_t nC, const prc::RGBAColour* C,
+ size_t nI, const uint32_t (*PI)[3],
+ const uint32_t (*NI)[3], const uint32_t (*CI)[3],
+ const triple& Min, const triple& Max) override;
+
+ void addCurve(triple const& z0, triple const& c0, triple const& c1, triple const& z1, triple const& Min,
+ triple const& Max) override;
+
+ void addCurve(triple const& z0, triple const& z1, triple const& Min, triple const& Max) override;
+
+ void addPixel(triple const& z0, double width, triple const& Min, triple const& Max) override;
+
+ void precision(int digits) override {}
+
+
+protected:
+ void addvec4(glm::vec4 const& vec);
+ void addCenterIndexMat();
+ void addIndices(uint32_t const* trip);
+ void addTriples(triple const* triples, size_t n);
+ void addColors(prc::RGBAColour const* col, size_t nc);
+
+ void addHeaders();
+ void addCenters();
+
+ virtual xdr::oxstream& getXDRFile() = 0;
+};
+
+class gzv3dfile : public v3dfile {
+public:
+ gzv3dfile(string const& name, bool singleprecision=false);
+ ~gzv3dfile() override;
+
+protected:
+ xdr::oxstream& getXDRFile() override;
+
+ [[nodiscard]]
+ char const* data() const;
+
+ [[nodiscard]]
+ size_t const& length() const;
+
+private:
+ xdr::memoxstream memxdrfile;
+ string name;
+ bool destroyed;
+ void close() override;
+};
+
+} //namespace camp
+#endif
+
+#endif
diff --git a/graphics/asymptote/v3dheadertypes.csv b/graphics/asymptote/v3dheadertypes.csv
new file mode 100644
index 0000000000..b1e1a39ebc
--- /dev/null
+++ b/graphics/asymptote/v3dheadertypes.csv
@@ -0,0 +1,19 @@
+canvasWidth,1,UINT # Canvas width
+canvasHeight,2,UINT # Canvas height
+absolute,3,BOOL # true: absolute size; false: scale to canvas
+minBound,4,TRIPLE # Scene minimum bounding box corners
+maxBound,5,TRIPLE # Scene maximum bounding box corners
+orthographic,6,BOOL # true: orthographic; false: perspective
+angleOfView,7,REAL # Field of view angle
+initialZoom,8,REAL # Initial zoom
+viewportShift,9,PAIR # Viewport shift (for perspective projection)
+viewportMargin,10,PAIR # Margin around viewport
+light,11,TRIPLE,RGB # Direction and color of each point light source
+background,12,RGBA # Background color
+zoomFactor,13,REAL # Zoom base factor
+zoomPinchFactor,14,REAL # Zoom pinch factor
+zoomPinchCap,15,REAL # Zoom pinch limit
+zoomStep,16,REAL # Zoom power step
+shiftHoldDistance,17,REAL # Shift-mode maximum hold distance (pixels)
+shiftWaitTime,18,REAL # Shift-mode hold time (milliseconds)
+vibrateTime,19,REAL # Shift-mode vibrate time (milliseconds)
diff --git a/graphics/asymptote/v3dheadertypes.h b/graphics/asymptote/v3dheadertypes.h
new file mode 100644
index 0000000000..e27fa68c1f
--- /dev/null
+++ b/graphics/asymptote/v3dheadertypes.h
@@ -0,0 +1,69 @@
+// Enum class for v3dheadertypes
+// AUTO-GENERATED from v3dheadertypes.csv
+// Generated at 2021-12-27 12:44:53.701402
+
+namespace camp
+{
+enum v3dheadertypes : uint32_t
+{
+canvasWidth=1,
+// UINT Canvas width
+
+canvasHeight=2,
+// UINT Canvas height
+
+absolute=3,
+// BOOL true: absolute size; false: scale to canvas
+
+minBound=4,
+// TRIPLE Scene minimum bounding box corners
+
+maxBound=5,
+// TRIPLE Scene maximum bounding box corners
+
+orthographic=6,
+// BOOL true: orthographic; false: perspective
+
+angleOfView=7,
+// REAL Field of view angle
+
+initialZoom=8,
+// REAL Initial zoom
+
+viewportShift=9,
+// PAIR Viewport shift (for perspective projection)
+
+viewportMargin=10,
+// PAIR Margin around viewport
+
+light=11,
+// RGB Direction and color of each point light source
+
+background=12,
+// RGBA Background color
+
+zoomFactor=13,
+// REAL Zoom base factor
+
+zoomPinchFactor=14,
+// REAL Zoom pinch factor
+
+zoomPinchCap=15,
+// REAL Zoom pinch limit
+
+zoomStep=16,
+// REAL Zoom power step
+
+shiftHoldDistance=17,
+// REAL Shift-mode maximum hold distance (pixels)
+
+shiftWaitTime=18,
+// REAL Shift-mode hold time (milliseconds)
+
+vibrateTime=19,
+// REAL Shift-mode vibrate time (milliseconds)
+
+};
+
+} // namespace camp
+// End of File
diff --git a/graphics/asymptote/v3dheadertypes.py b/graphics/asymptote/v3dheadertypes.py
new file mode 100644
index 0000000000..a74f63fc4b
--- /dev/null
+++ b/graphics/asymptote/v3dheadertypes.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python3
+# Enum class for v3dheadertypes
+""" AUTO-GENERATED from v3dheadertypes.csv """
+# Generated at 2021-12-27 12:46:04.819978
+
+class v3dheadertypes:
+ v3dheadertypes_canvasWidth=1
+ # UINT Canvas width
+
+ v3dheadertypes_canvasHeight=2
+ # UINT Canvas height
+
+ v3dheadertypes_absolute=3
+ # BOOL true: absolute size; false: scale to canvas
+
+ v3dheadertypes_minBound=4
+ # TRIPLE Scene minimum bounding box corners
+
+ v3dheadertypes_maxBound=5
+ # TRIPLE Scene maximum bounding box corners
+
+ v3dheadertypes_orthographic=6
+ # BOOL true: orthographic; false: perspective
+
+ v3dheadertypes_angleOfView=7
+ # REAL Field of view angle
+
+ v3dheadertypes_initialZoom=8
+ # REAL Initial zoom
+
+ v3dheadertypes_viewportShift=9
+ # PAIR Viewport shift (for perspective projection)
+
+ v3dheadertypes_viewportMargin=10
+ # PAIR Margin around viewport
+
+ v3dheadertypes_light=11
+ # RGB Direction and color of each point light source
+
+ v3dheadertypes_background=12
+ # RGBA Background color
+
+ v3dheadertypes_zoomFactor=13
+ # REAL Zoom base factor
+
+ v3dheadertypes_zoomPinchFactor=14
+ # REAL Zoom pinch factor
+
+ v3dheadertypes_zoomPinchCap=15
+ # REAL Zoom pinch limit
+
+ v3dheadertypes_zoomStep=16
+ # REAL Zoom power step
+
+ v3dheadertypes_shiftHoldDistance=17
+ # REAL Shift-mode maximum hold distance (pixels)
+
+ v3dheadertypes_shiftWaitTime=18
+ # REAL Shift-mode hold time (milliseconds)
+
+ v3dheadertypes_vibrateTime=19
+ # REAL Shift-mode vibrate time (milliseconds)
+
+# End of File
diff --git a/graphics/asymptote/v3dtypes.csv b/graphics/asymptote/v3dtypes.csv
new file mode 100644
index 0000000000..87f132525d
--- /dev/null
+++ b/graphics/asymptote/v3dtypes.csv
@@ -0,0 +1,38 @@
+material,1
+transform,2
+element,3
+centers,4
+header,5
+
+line,64
+triangle,65
+quad,66
+
+curve,128
+bezierTriangle,129
+bezierPatch,130
+
+lineColor,192
+triangleColor,193
+quadColor,194
+
+curveColor,256
+bezierTriangleColor,257
+bezierPatchColor,258
+
+triangles,512
+
+disk,1024
+cylinder,1025
+tube,1026
+sphere,1027
+halfSphere,1028
+
+animation,2048
+
+#open2DPolygon,3136
+#closed2DPolygon,3137
+#open2DCurve,3200
+#closed2DCurve,3201
+
+pixel,4096
diff --git a/graphics/asymptote/v3dtypes.h b/graphics/asymptote/v3dtypes.h
new file mode 100644
index 0000000000..883d5c0499
--- /dev/null
+++ b/graphics/asymptote/v3dtypes.h
@@ -0,0 +1,37 @@
+// Enum class for v3dtypes
+// AUTO-GENERATED from v3dtypes.csv
+// Generated at 2021-12-27 12:44:53.701233
+
+namespace camp
+{
+enum v3dtypes : uint32_t
+{
+material=1,
+transform=2,
+element=3,
+centers=4,
+header=5,
+line=64,
+triangle=65,
+quad=66,
+curve=128,
+bezierTriangle=129,
+bezierPatch=130,
+lineColor=192,
+triangleColor=193,
+quadColor=194,
+curveColor=256,
+bezierTriangleColor=257,
+bezierPatchColor=258,
+triangles=512,
+disk=1024,
+cylinder=1025,
+tube=1026,
+sphere=1027,
+halfSphere=1028,
+animation=2048,
+pixel=4096,
+};
+
+} // namespace camp
+// End of File
diff --git a/graphics/asymptote/v3dtypes.py b/graphics/asymptote/v3dtypes.py
new file mode 100644
index 0000000000..dcf83decf3
--- /dev/null
+++ b/graphics/asymptote/v3dtypes.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+# Enum class for v3dtypes
+""" AUTO-GENERATED from v3dtypes.csv """
+# Generated at 2021-12-27 12:46:04.824592
+
+class v3dtypes:
+ v3dtypes_material=1
+ v3dtypes_transform=2
+ v3dtypes_element=3
+ v3dtypes_centers=4
+ v3dtypes_header=5
+ v3dtypes_line=64
+ v3dtypes_triangle=65
+ v3dtypes_quad=66
+ v3dtypes_curve=128
+ v3dtypes_bezierTriangle=129
+ v3dtypes_bezierPatch=130
+ v3dtypes_lineColor=192
+ v3dtypes_triangleColor=193
+ v3dtypes_quadColor=194
+ v3dtypes_curveColor=256
+ v3dtypes_bezierTriangleColor=257
+ v3dtypes_bezierPatchColor=258
+ v3dtypes_triangles=512
+ v3dtypes_disk=1024
+ v3dtypes_cylinder=1025
+ v3dtypes_tube=1026
+ v3dtypes_sphere=1027
+ v3dtypes_halfSphere=1028
+ v3dtypes_animation=2048
+ v3dtypes_pixel=4096
+# End of File
diff --git a/graphics/asymptote/varinit.cc b/graphics/asymptote/varinit.cc
index 347b5960c7..140564689a 100644
--- a/graphics/asymptote/varinit.cc
+++ b/graphics/asymptote/varinit.cc
@@ -21,7 +21,7 @@ using namespace trans;
void definit::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "definit",indent);
+ prettyname(out, "definit",indent, getPos());
}
void definit::transToType(coenv &e, types::ty *target)
@@ -30,7 +30,7 @@ void definit::transToType(coenv &e, types::ty *target)
access *a=e.e.lookupInitializer(target);
if (a)
- a->encode(CALL, getPos(), e.c);
+ a->encode(action::CALL, getPos(), e.c);
else {
em.error(getPos());
em << "no default initializer for type '" << *target << "'";
@@ -40,7 +40,7 @@ void definit::transToType(coenv &e, types::ty *target)
void arrayinit::prettyprint(ostream &out, Int indent)
{
- prettyname(out, "arrayinit",indent);
+ prettyname(out, "arrayinit",indent, getPos());
for (mem::list<varinit *>::iterator p = inits.begin(); p != inits.end(); ++p)
(*p)->prettyprint(out, indent+2);
diff --git a/graphics/asymptote/webgl/fragment.glsl b/graphics/asymptote/webgl/fragment.glsl
index de9ab75dac..10d830ee0e 100644
--- a/graphics/asymptote/webgl/fragment.glsl
+++ b/graphics/asymptote/webgl/fragment.glsl
@@ -1,13 +1,45 @@
+#ifdef WEBGL2
+#define IN in
+out vec4 outValue;
+#define OUTVALUE outValue
+#else
+#define IN varying
+#define OUTVALUE gl_FragColor
+#endif
+
+#ifdef WEBGL2
+flat in int MaterialIndex;
+
+struct Material {
+ vec4 diffuse,emissive,specular;
+ vec4 parameters;
+};
+
+uniform Material Materials[Nmaterials];
+
+vec4 diffuse;
+vec3 specular;
+float roughness,metallic,fresnel0;
+vec4 emissive;
+
+#ifdef COLOR
+in vec4 Color;
+#endif
+
+#else
+IN vec4 diffuse;
+IN vec3 specular;
+IN float roughness,metallic,fresnel0;
+IN vec4 emissive;
+#endif
+
#ifdef NORMAL
+
#ifndef ORTHOGRAPHIC
-varying vec3 ViewPosition;
+IN vec3 ViewPosition;
#endif
-varying vec3 Normal;
-varying vec4 diffuse;
-varying vec3 specular;
-varying float roughness,metallic,fresnel0;
+IN vec3 Normal;
-float Roughness2;
vec3 normal;
struct Light {
@@ -17,6 +49,54 @@ struct Light {
uniform Light Lights[Nlights];
+#ifdef USE_IBL
+uniform sampler2D reflBRDFSampler;
+uniform sampler2D diffuseSampler;
+uniform sampler2D reflImgSampler;
+
+const float pi=acos(-1.0);
+const float piInv=1.0/pi;
+const float twopi=2.0*pi;
+const float twopiInv=1.0/twopi;
+
+// (x,y,z) -> (r,theta,phi);
+// theta -> [0,pi]: colatitude
+// phi -> [-pi,pi]: longitude
+vec3 cart2sphere(vec3 cart)
+{
+ float x=cart.x;
+ float y=cart.z;
+ float z=cart.y;
+
+ float r=length(cart);
+ float theta=r > 0.0 ? acos(z/r) : 0.0;
+ float phi=atan(y,x);
+
+ return vec3(r,theta,phi);
+}
+
+vec2 normalizedAngle(vec3 cartVec)
+{
+ vec3 sphericalVec=cart2sphere(cartVec);
+ sphericalVec.y=sphericalVec.y*piInv;
+ sphericalVec.z=0.75-sphericalVec.z*twopiInv;
+ return sphericalVec.zy;
+}
+
+vec3 IBLColor(vec3 viewDir)
+{
+ vec3 IBLDiffuse=diffuse.rgb*texture(diffuseSampler,normalizedAngle(normal)).rgb;
+ vec3 reflectVec=normalize(reflect(-viewDir,normal));
+ vec2 reflCoord=normalizedAngle(reflectVec);
+ vec3 IBLRefl=textureLod(reflImgSampler,reflCoord,roughness*ROUGHNESS_STEP_COUNT).rgb;
+ vec2 IBLbrdf=texture(reflBRDFSampler,vec2(dot(normal,viewDir),roughness)).rg;
+ float specularMultiplier=fresnel0*IBLbrdf.x+IBLbrdf.y;
+ vec3 dielectric=IBLDiffuse+specularMultiplier*IBLRefl;
+ vec3 metal=diffuse.rgb*IBLRefl;
+ return mix(dielectric,metal,metallic);
+}
+#else
+float Roughness2;
float NDF_TRG(vec3 h)
{
float ndoth=max(dot(normal,h),0.0);
@@ -24,7 +104,7 @@ float NDF_TRG(vec3 h)
float denom=ndoth*ndoth*(alpha2-1.0)+1.0;
return denom != 0.0 ? alpha2/(denom*denom) : 0.0;
}
-
+
float GGX_Geom(vec3 v)
{
float ndotv=max(dot(v,normal),0.0);
@@ -32,45 +112,82 @@ float GGX_Geom(vec3 v)
float k=0.125*ap*ap;
return ndotv/((ndotv*(1.0-k))+k);
}
-
+
float Geom(vec3 v, vec3 l)
{
return GGX_Geom(v)*GGX_Geom(l);
}
-
+
float Fresnel(vec3 h, vec3 v, float fresnel0)
{
float a=1.0-max(dot(h,v),0.0);
float b=a*a;
return fresnel0+(1.0-fresnel0)*b*b*a;
}
-
+
// physical based shading using UE4 model.
vec3 BRDF(vec3 viewDirection, vec3 lightDirection)
{
vec3 lambertian=diffuse.rgb;
vec3 h=normalize(lightDirection+viewDirection);
-
+
float omegain=max(dot(viewDirection,normal),0.0);
- float omegali=max(dot(lightDirection,normal),0.0);
-
+ float omegaln=max(dot(lightDirection,normal),0.0);
+
float D=NDF_TRG(h);
float G=Geom(viewDirection,lightDirection);
float F=Fresnel(h,viewDirection,fresnel0);
-
- float denom=4.0*omegain*omegali;
+
+ float denom=4.0*omegain*omegaln;
float rawReflectance=denom > 0.0 ? (D*G)/denom : 0.0;
-
+
vec3 dielectric=mix(lambertian,rawReflectance*specular,F);
vec3 metal=rawReflectance*diffuse.rgb;
-
+
return mix(dielectric,metal,metallic);
}
#endif
-varying vec4 emissive;
-
+
+#endif
+
void main(void)
{
+#ifdef WEBGL2
+#ifdef NORMAL
+ Material m;
+#ifdef TRANSPARENT
+ m=Materials[abs(MaterialIndex)-1];
+ emissive=m.emissive;
+ if(MaterialIndex >= 0)
+ diffuse=m.diffuse;
+ else {
+ diffuse=Color;
+#if nlights == 0
+ emissive += Color;
+#endif
+ }
+#else
+ m=Materials[MaterialIndex];
+ emissive=m.emissive;
+#ifdef COLOR
+ diffuse=Color;
+#if nlights == 0
+ emissive += Color;
+#endif
+#else
+ diffuse=m.diffuse;
+#endif // COLOR
+#endif // TRANSPARENT
+ specular=m.specular.rgb;
+ vec4 parameters=m.parameters;
+ roughness=1.0-parameters[0];
+ metallic=parameters[1];
+ fresnel0=parameters[2];
+#else
+ emissive=Materials[MaterialIndex].emissive;
+#endif // NORMAL
+#endif // WEBGL2
+
#if defined(NORMAL) && nlights > 0
normal=normalize(Normal);
normal=gl_FrontFacing ? normal : -normal;
@@ -79,8 +196,13 @@ void main(void)
#else
vec3 viewDir=-normalize(ViewPosition);
#endif
+
+vec3 color;
+#ifdef USE_IBL
+ color=IBLColor(viewDir);
+#else
Roughness2=roughness*roughness;
- vec3 color=emissive.rgb;
+ color=emissive.rgb;
for(int i=0; i < nlights; ++i) {
Light Li=Lights[i];
vec3 L=Li.direction;
@@ -88,8 +210,9 @@ void main(void)
vec3 radiance=cosTheta*Li.color;
color += BRDF(viewDir,L)*radiance;
}
- gl_FragColor=vec4(color,diffuse.a);
+#endif
+ OUTVALUE=vec4(color,diffuse.a);
#else
- gl_FragColor=emissive;
+ OUTVALUE=emissive;
#endif
}
diff --git a/graphics/asymptote/webgl/gl.js b/graphics/asymptote/webgl/gl.js
index f05312dec5..a42ef6ab36 100644
--- a/graphics/asymptote/webgl/gl.js
+++ b/graphics/asymptote/webgl/gl.js
@@ -4,26 +4,32 @@ let Lights=[]; // Array of lights
let Centers=[]; // Array of billboard centers
let Background=[1,1,1,1]; // Background color
-let canvasWidth,canvasHeight;
-let canvasWidth0,canvasHeight0; // Initial values
-
-let absolute=false;
+let canvasWidth,canvasHeight; // Canvas width, height
+
+let absolute=false; // true: absolute size; false: scale to canvas
+let ibl=false;
+let imageURL;
+let image;
+
+let minBound,maxBound; // Scene min,max bounding box corners (3-tuples)
+let orthographic; // true: orthographic; false: perspective
+let angleOfView; // Field of view angle
+let initialZoom; // Initial zoom
+let viewportShift=[0,0]; // Viewport shift (for perspective projection)
+let viewportMargin; // Margin around viewport (2-tuple)
+let webgl2=false;
+
+let zoomFactor; // Zoom base factor
+let zoomPinchFactor; // Zoom pinch factor
+let zoomPinchCap; // Zoom pinch limit
+let zoomStep; // Zoom power step
+
+let shiftHoldDistance; // Shift-mode maximum hold distance (pixels)
+let shiftWaitTime; // Shift-mode hold time (milliseconds)
+let vibrateTime; // Shift-mode vibrate time (milliseconds)
-let b,B; // Scene min,max bounding box corners (3-tuples)
-let angle; // Field of view angle
-let Zoom0; // Initial zoom
+let canvasWidth0,canvasHeight0; // Initial values
let zoom0; // Adjusted initial zoom
-let viewportmargin; // Margin around viewport (2-tuple)
-let viewportshift=[0,0]; // Viewport shift (for perspective projection)
-
-let zoomFactor;
-let zoomPinchFactor;
-let zoomPinchCap;
-let zoomStep;
-
-let shiftHoldDistance;
-let shiftWaitTime;
-let vibrateTime;
let embedded; // Is image embedded within another window?
@@ -31,7 +37,7 @@ let canvas; // Rendering canvas
let gl; // WebGL rendering context
let alpha; // Is background opaque?
-let offscreen; // Offscreen rendering canvas for embedded images
+let offscreen2; // Offscreen rendering canvas for embedded images
let context; // 2D context for copying embedded offscreen images
let nlights=0; // Number of lights compiled in shader
@@ -42,21 +48,20 @@ let maxMaterials; // Limit on number of materials allowed in shader
let halfCanvasWidth,halfCanvasHeight;
-let pixel=0.75; // Adaptive rendering constant.
-let zoomRemeshFactor=1.5; // Zoom factor before remeshing
-let FillFactor=0.1;
+const pixelResolution=0.75; // Adaptive rendering constant.
+const zoomRemeshFactor=1.5; // Zoom factor before remeshing
+const FillFactor=0.1;
+const windowTrim=10;
+const third=1/3;
+
let Zoom;
+let lastZoom;
let maxViewportWidth;
let maxViewportHeight;
-const windowTrim=10;
-
-let lastZoom;
let H; // maximum camera view half-height
-let third=1/3;
-
let rotMat=mat4.create();
let projMat=mat4.create(); // projection matrix
let viewMat=mat4.create(); // view matrix
@@ -94,6 +99,24 @@ let Normals=[];
let Colors=[];
let Indices=[];
+let IBLReflMap=null;
+let IBLDiffuseMap=null;
+let IBLbdrfMap=null;
+
+function IBLReady()
+{
+ return IBLReflMap !== null && IBLDiffuseMap !== null && IBLbdrfMap !== null;
+}
+
+function SetIBL()
+{
+ if(!embedded)
+ deleteShaders();
+ initShaders(ibl);
+}
+
+let roughnessStepCount=8;
+
class Material {
constructor(diffuse,emissive,specular,shininess,metallic,fresnel0) {
this.diffuse=diffuse;
@@ -135,16 +158,26 @@ class Light {
}
}
-function initShaders()
+function initShaders(ibl=false)
{
let maxUniforms=gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS);
maxMaterials=Math.floor((maxUniforms-14)/4);
Nmaterials=Math.min(Math.max(Nmaterials,Materials.length),maxMaterials);
- pixelShader=initShader(["WIDTH"]);
- materialShader=initShader(["NORMAL"]);
- colorShader=initShader(["NORMAL","COLOR"]);
- transparentShader=initShader(["NORMAL","COLOR","TRANSPARENT"]);
+ pixelOpt=["WIDTH"];
+ materialOpt=["NORMAL"];
+ colorOpt=["NORMAL","COLOR"];
+ transparentOpt=["NORMAL","COLOR","TRANSPARENT"];
+
+ if(ibl) {
+ materialOpt.push('USE_IBL');
+ transparentOpt.push('USE_IBL');
+ }
+
+ pixelShader=initShader(pixelOpt);
+ materialShader=initShader(materialOpt);
+ colorShader=initShader(colorOpt);
+ transparentShader=initShader(transparentOpt);
}
function deleteShaders()
@@ -155,14 +188,9 @@ function deleteShaders()
gl.deleteProgram(pixelShader);
}
-function noGL() {
- if (!gl)
- alert("Could not initialize WebGL");
-}
-
function saveAttributes()
{
- let a=window.top.document.asygl[alpha];
+ let a=window.top.document.asygl2[alpha];
a.gl=gl;
a.nlights=Lights.length;
@@ -177,7 +205,7 @@ function saveAttributes()
function restoreAttributes()
{
- let a=window.top.document.asygl[alpha];
+ let a=window.top.document.asygl2[alpha];
gl=a.gl;
nlights=a.nlights;
@@ -192,6 +220,20 @@ function restoreAttributes()
let indexExt;
+function webGL(canvas,alpha) {
+ let gl;
+ if(ibl) webgl2=true;
+ if(webgl2) gl=canvas.getContext("webgl2",{alpha: alpha});
+ if(!gl) {
+ webgl2=false;
+ ibl=false;
+ gl=canvas.getContext("webgl",{alpha: alpha});
+ }
+ if(!gl)
+ alert("Could not initialize WebGL");
+ return gl;
+}
+
function initGL()
{
alpha=Background[3] < 1;
@@ -199,21 +241,20 @@ function initGL()
if(embedded) {
let p=window.top.document;
- if(p.asygl == null)
- p.asygl=Array(2);
-
+ if(p.asygl2 == null)
+ p.asygl2=Array(2);
+
context=canvas.getContext("2d");
- offscreen=p.offscreen;
- if(!offscreen) {
- offscreen=p.createElement("canvas");
- p.offscreen=offscreen;
+ offscreen2=p.offscreen2;
+ if(!offscreen2) {
+ offscreen2=p.createElement("canvas");
+ p.offscreen2=offscreen2;
}
- if(!p.asygl[alpha] || !p.asygl[alpha].gl) {
- gl=offscreen.getContext("webgl",{alpha:alpha});
- if(!gl) noGL();
+ if(!p.asygl2[alpha] || !p.asygl2[alpha].gl) {
+ gl=webGL(offscreen2,alpha);
initShaders();
- p.asygl[alpha]={};
+ p.asygl2[alpha]={};
saveAttributes();
} else {
restoreAttributes();
@@ -224,8 +265,7 @@ function initGL()
}
}
} else {
- gl=canvas.getContext("webgl",{alpha:alpha});
- if(!gl) noGL();
+ gl=webGL(canvas,alpha);
initShaders();
}
@@ -242,23 +282,53 @@ function initGL()
function getShader(gl,shaderScript,type,options=[])
{
- let str=`#version 100
+ let version=webgl2 ? '300 es' : '100';
+ let defines=Array(...options)
+ let macros=[
+ ['nlights',wireframe == 0 ? Lights.length : 0],
+ ['Nmaterials',Nmaterials]
+ ]
+
+ let consts=[
+ ['int','Nlights',Math.max(Lights.length,1)]
+ ]
+
+ let addenum=`
#ifdef GL_FRAGMENT_PRECISION_HIGH
- precision highp float;
+precision highp float;
#else
- precision mediump float;
+precision mediump float;
#endif
- #define nlights ${wireframe == 0 ? Lights.length : 0}\n
- const int Nlights=${Math.max(Lights.length,1)};\n
- #define Nmaterials ${Nmaterials}\n`;
+ `
+
+ let extensions=[];
+
+ if(webgl2)
+ defines.push('WEBGL2');
+
+ if(ibl)
+ macros.push(['ROUGHNESS_STEP_COUNT',roughnessStepCount.toFixed(2)]);
if(orthographic)
- str += `#define ORTHOGRAPHIC\n`;
+ defines.push('ORTHOGRAPHIC');
+
+ macros_str=macros.map(macro => `#define ${macro[0]} ${macro[1]}`).join('\n')
+ define_str=defines.map(define => `#define ${define}`).join('\n');
+ const_str=consts.map(const_val => `const ${const_val[0]} ${const_val[1]}=${const_val[2]};`).join('\n')
+ ext_str=extensions.map(ext => `#extension ${ext}: enable`).join('\n')
+
+ shaderSrc=`#version ${version}
+${ext_str}
+${define_str}
+${const_str}
+${macros_str}
- options.forEach(s => str += `#define `+s+`\n`);
+${addenum}
+${shaderScript}
+ `;
let shader=gl.createShader(type);
- gl.shaderSource(shader,str+shaderScript);
+ gl.shaderSource(shader,shaderSrc);
gl.compileShader(shader);
if(!gl.getShaderParameter(shader,gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
@@ -284,26 +354,39 @@ function registerBuffer(buffervector,bufferIndex,copy,type=gl.ARRAY_BUFFER)
function drawBuffer(data,shader,indices=data.indices)
{
if(data.indices.length == 0) return;
-
+
let normal=shader != pixelShader;
setUniforms(data,shader);
+ if(IBLDiffuseMap != null) {
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D,IBLbdrfMap);
+ gl.uniform1i(gl.getUniformLocation(shader,'reflBRDFSampler'),0);
+
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D,IBLDiffuseMap);
+ gl.uniform1i(gl.getUniformLocation(shader,'diffuseSampler'),1);
+
+ gl.activeTexture(gl.TEXTURE2);
+ gl.bindTexture(gl.TEXTURE_2D,IBLReflMap);
+ gl.uniform1i(gl.getUniformLocation(shader,'reflImgSampler'),2);
+ }
let copy=remesh || data.partial || !data.rendered;
data.verticesBuffer=registerBuffer(new Float32Array(data.vertices),
data.verticesBuffer,copy);
gl.vertexAttribPointer(positionAttribute,3,gl.FLOAT,false,
normal ? 24 : 16,0);
- if(normal && Lights.length > 0)
- gl.vertexAttribPointer(normalAttribute,3,gl.FLOAT,false,24,12);
- else if(pixel)
+ if(normal) {
+ if(Lights.length > 0)
+ gl.vertexAttribPointer(normalAttribute,3,gl.FLOAT,false,24,12);
+ } else
gl.vertexAttribPointer(widthAttribute,1,gl.FLOAT,false,16,12);
data.materialsBuffer=registerBuffer(new Int16Array(data.materialIndices),
data.materialsBuffer,copy);
gl.vertexAttribPointer(materialAttribute,1,gl.SHORT,false,2,0);
-
if(shader == colorShader || shader == transparentShader) {
data.colorsBuffer=registerBuffer(new Uint8Array(data.colors),
data.colorsBuffer,copy);
@@ -348,7 +431,7 @@ class vertexBuffer {
this.materialTable=[];
}
- // material vertex
+ // material vertex
vertex(v,n) {
this.vertices.push(v[0]);
this.vertices.push(v[1]);
@@ -376,7 +459,7 @@ class vertexBuffer {
return this.nvertices++;
}
- // material vertex with width and without normal
+ // material vertex with width and without normal
vertex0(v,width) {
this.vertices.push(v[0]);
this.vertices.push(v[1]);
@@ -386,7 +469,7 @@ class vertexBuffer {
return this.nvertices++;
}
- // indexed colored vertex
+ // indexed colored vertex
iVertex(i,v,n,c=[0,0,0,0]) {
let i6=6*i;
this.vertices[i6]=v[0];
@@ -542,12 +625,13 @@ class Geometry {
P[i]=this.T(p[i]);
}
- let s=orthographic ? 1 : this.Min[2]/B[2];
- let res=pixel*Math.hypot(s*(viewParam.xmax-viewParam.xmin),
- s*(viewParam.ymax-viewParam.ymin))/size2;
+ let s=orthographic ? 1 : this.Min[2]/maxBound[2];
+ let res=pixelResolution*
+ Math.hypot(s*(viewParam.xmax-viewParam.xmin),
+ s*(viewParam.ymax-viewParam.ymin))/size2;
this.res2=res*res;
this.Epsilon=FillFactor*res;
-
+
this.data.clear();
this.notRendered();
this.Onscreen=true;
@@ -568,10 +652,11 @@ class BezierPatch extends Geometry {
constructor(controlpoints,CenterIndex,MaterialIndex,Min,Max,color) {
super();
this.controlpoints=controlpoints;
+ this.CenterIndex=CenterIndex;
+ this.MaterialIndex=MaterialIndex;
this.Min=Min;
this.Max=Max;
this.color=color;
- this.CenterIndex=CenterIndex;
let n=controlpoints.length;
if(color) {
let sum=color[0][3]+color[1][3]+color[2][3];
@@ -579,7 +664,6 @@ class BezierPatch extends Geometry {
sum+color[3][3] < 1020 : sum < 765;
} else
this.transparent=Materials[MaterialIndex].diffuse[3] < 1;
- this.MaterialIndex=MaterialIndex;
this.vertex=this.transparent ? this.data.Vertex.bind(this.data) :
this.data.vertex.bind(this.data);
@@ -703,7 +787,7 @@ class BezierPatch extends Geometry {
if(p.length == 10) return this.process3(p);
if(p.length == 3) return this.processTriangle(p);
if(p.length == 4) return this.processQuad(p);
-
+
if(wireframe == 1) {
this.curve(p,0,4,8,12);
this.curve(p,12,13,14,15);
@@ -801,7 +885,7 @@ class BezierPatch extends Geometry {
this.data.indices.push(I1);
this.data.indices.push(I2);
}
- }
+ }
if(!this.offscreen([P0,P2,P3])) {
if(wireframe == 0) {
this.data.indices.push(I0);
@@ -819,11 +903,11 @@ class BezierPatch extends Geometry {
if(this.offscreen(p)) return;
/* Control points are indexed as follows:
-
+
Coordinate
+-----
Index
-
+
03 13 23 33
+-----+-----+-----+
|3 |7 |11 |15
@@ -841,7 +925,7 @@ class BezierPatch extends Geometry {
0 4 8 12
*/
-
+
let p0=p[0];
let p3=p[3];
let p12=p[12];
@@ -1060,7 +1144,7 @@ class BezierPatch extends Geometry {
P refers to a corner
m refers to a midpoint
s refers to a subpatch
-
+
m2
+--------+--------+
|P3 | P2|
@@ -1170,7 +1254,7 @@ class BezierPatch extends Geometry {
}
else m2=s2[3];
}
-
+
let m3=[0.5*(P3[0]+P0[0]),
0.5*(P3[1]+P0[1]),
0.5*(P3[2]+P0[2])];
@@ -1181,7 +1265,7 @@ class BezierPatch extends Geometry {
}
else m3=s3[0];
}
-
+
if(C0) {
let c0=Array(4);
let c1=Array(4);
@@ -1239,9 +1323,9 @@ class BezierPatch extends Geometry {
let p9=p[9];
let n0=this.normal(p9,p[5],p[2],p0,p[1],p[3],p6);
- let n1=this.normal(p0,p[1],p[3],p6,p[7],p[8],p9);
+ let n1=this.normal(p0,p[1],p[3],p6,p[7],p[8],p9);
let n2=this.normal(p6,p[7],p[8],p9,p[5],p[2],p0);
-
+
if(this.color) {
let c0=this.color[0];
let c1=this.color[1];
@@ -1250,7 +1334,7 @@ class BezierPatch extends Geometry {
let i0=this.data.Vertex(p0,n0,c0);
let i1=this.data.Vertex(p6,n1,c1);
let i2=this.data.Vertex(p9,n2,c2);
-
+
this.Render3(p,i0,i1,i2,p0,p6,p9,false,false,false,c0,c1,c2);
} else {
@@ -1336,7 +1420,7 @@ class BezierPatch extends Geometry {
003 p2 300
P0 P1
*/
-
+
// Subdivide triangle:
let l003=p[0];
@@ -1470,7 +1554,7 @@ class BezierPatch extends Geometry {
let n0=this.normal(l300,r012,r021,r030,u201,u102,l030);
let n1=this.normal(r030,u201,u102,l030,l120,l210,l300);
let n2=this.normal(l030,l120,l210,l300,r012,r021,r030);
-
+
let e=this.Epsilon;
// A kludge to remove subdivision cracks, only applied the first time
@@ -1519,11 +1603,11 @@ class BezierPatch extends Geometry {
c1[i]=0.5*(C2[i]+C0[i]);
c2[i]=0.5*(C0[i]+C1[i]);
}
-
+
let i0=this.data.Vertex(m0,n0,c0);
let i1=this.data.Vertex(m1,n1,c1);
let i2=this.data.Vertex(m2,n2,c2);
-
+
this.Render3(l,I0,i2,i1,P0,m2,m1,false,flat1,flat2,C0,c2,c1);
this.Render3(r,i2,I1,i0,m2,P1,m0,flat0,false,flat2,c2,C1,c0);
this.Render3(u,i1,i0,I2,m1,m0,P2,flat0,flat1,false,c1,c0,C2);
@@ -1532,7 +1616,7 @@ class BezierPatch extends Geometry {
let i0=this.vertex(m0,n0);
let i1=this.vertex(m1,n1);
let i2=this.vertex(m2,n2);
-
+
this.Render3(l,I0,i2,i1,P0,m2,m1,false,flat1,flat2);
this.Render3(r,i2,I1,i0,m2,P1,m0,flat0,false,flat2);
this.Render3(u,i1,i0,I2,m1,m0,P2,flat0,flat1,false);
@@ -1590,11 +1674,11 @@ class BezierPatch extends Geometry {
let p=[3*(p1[0]-p0[0]),3*(p1[1]-p0[1]),3*(p1[2]-p0[2])];
if(abs2(p) > this.epsilon)
return p;
-
+
p=bezierPP(p0,p1,p2);
if(abs2(p) > this.epsilon)
return p;
-
+
return bezierPPP(p0,p1,p2,p3);
}
@@ -1603,7 +1687,7 @@ class BezierPatch extends Geometry {
let d1=this.differential(p0,p4,p5,p6);
return [d0[0]+d1[0],d0[1]+d1[1],d0[2]+d1[2]];
}
-
+
normal(left3,left2,left1,middle,right1,right2,right3) {
let ux=3*(right1[0]-middle[0]);
let uy=3*(right1[1]-middle[1]);
@@ -1662,10 +1746,10 @@ class BezierCurve extends Geometry {
constructor(controlpoints,CenterIndex,MaterialIndex,Min,Max) {
super();
this.controlpoints=controlpoints;
- this.Min=Min;
- this.Max=Max;
this.CenterIndex=CenterIndex;
this.MaterialIndex=MaterialIndex;
+ this.Min=Min;
+ this.Max=Max;
}
setMaterialIndex() {
@@ -1693,14 +1777,14 @@ class BezierCurve extends Geometry {
let n0=this.normal(bezierP(p0,p1),bezierPP(p0,p1,p2));
let n1=this.normal(bezierP(p2,p3),bezierPP(p3,p2,p1));
-
+
let i0=this.data.vertex(p0,n0);
let i3=this.data.vertex(p3,n1);
-
+
this.Render(p,i0,i3);
if(this.data.indices.length > 0) this.append();
}
-
+
append() {
material1Data.append(this.data);
}
@@ -1729,13 +1813,13 @@ class BezierCurve extends Geometry {
let m3=[0.5*(m0[0]+m1[0]),0.5*(m0[1]+m1[1]),0.5*(m0[2]+m1[2])];
let m4=[0.5*(m1[0]+m2[0]),0.5*(m1[1]+m2[1]),0.5*(m1[2]+m2[2])];
let m5=[0.5*(m3[0]+m4[0]),0.5*(m3[1]+m4[1]),0.5*(m3[2]+m4[2])];
-
+
let s0=[p0,m0,m3,m5];
let s1=[m5,m4,m2,p3];
-
+
let n0=this.normal(bezierPh(p0,p1,p2,p3),bezierPPh(p0,p1,p2,p3));
let i0=this.data.vertex(m5,n0);
-
+
this.Render(s0,I0,i0);
this.Render(s1,i0,I1);
}
@@ -1769,7 +1853,7 @@ class Pixel extends Geometry {
this.data.indices.push(this.data.vertex0(this.controlpoint,this.width));
this.append();
}
-
+
append() {
material0Data.append(this.data);
}
@@ -1780,13 +1864,14 @@ class Pixel extends Geometry {
}
class Triangles extends Geometry {
- constructor(MaterialIndex,Min,Max) {
+ constructor(CenterIndex,MaterialIndex,Min,Max) {
super();
- this.CenterIndex=0;
+ this.CenterIndex=CenterIndex;
this.MaterialIndex=MaterialIndex;
this.Min=Min;
this.Max=Max;
- this.Positions=Positions;
+
+ this.controlpoints=Positions;
this.Normals=Normals;
this.Colors=Colors;
this.Indices=Indices;
@@ -1794,9 +1879,9 @@ class Triangles extends Geometry {
Normals=[];
Colors=[];
Indices=[];
- this.transparent=Materials[MaterialIndex].diffuse[3] < 1;
+ this.transparent=Materials[this.MaterialIndex].diffuse[3] < 1;
}
-
+
setMaterialIndex() {
if(this.transparent)
this.setMaterial(transparentData,drawTransparent);
@@ -1805,6 +1890,7 @@ class Triangles extends Geometry {
}
process(p) {
+ this.data.vertices=new Array(6*p.length);
// Override materialIndex to encode color vs material
materialIndex=this.Colors.length > 0 ?
-1-materialIndex : 1+materialIndex;
@@ -1812,9 +1898,9 @@ class Triangles extends Geometry {
for(let i=0, n=this.Indices.length; i < n; ++i) {
let index=this.Indices[i];
let PI=index[0];
- let P0=this.Positions[PI[0]];
- let P1=this.Positions[PI[1]];
- let P2=this.Positions[PI[2]];
+ let P0=p[PI[0]];
+ let P1=p[PI[1]];
+ let P2=p[PI[2]];
if(!this.offscreen([P0,P1,P2])) {
let NI=index.length > 1 ? index[1] : PI;
if(!NI || NI.length == 0) NI=PI;
@@ -1853,7 +1939,7 @@ class Triangles extends Geometry {
}
}
}
- this.data.nvertices=this.Positions.length;
+ this.data.nvertices=p.length;
if(this.data.indices.length > 0) this.append();
}
@@ -1873,18 +1959,18 @@ class Triangles extends Geometry {
}
-function redraw()
+function redrawScene()
{
initProjection();
setProjection();
remesh=true;
- draw();
+ drawScene();
}
function home()
{
mat4.identity(rotMat);
- redraw();
+ redrawScene();
}
let positionAttribute=0;
@@ -1907,9 +1993,8 @@ function initShader(options=[])
gl.bindAttribLocation(shader,colorAttribute,"color");
gl.bindAttribLocation(shader,widthAttribute,"width");
gl.linkProgram(shader);
- if (!gl.getProgramParameter(shader,gl.LINK_STATUS)) {
+ if(!gl.getProgramParameter(shader,gl.LINK_STATUS))
alert("Could not initialize shaders");
- }
return shader;
}
@@ -1999,7 +2084,7 @@ function bezierPPh(a,b,c,d)
}
/**
- * Return the maximum distance squared of points c0 and c1 from
+ * Return the maximum distance squared of points c0 and c1 from
* the respective internal control points of z0--z1.
*/
function Straightness(z0,c0,c1,z1)
@@ -2044,8 +2129,8 @@ function maxbound(v) {
* Perform a change of basis
* @param {*} out Out Matrix
* @param {*} mat Matrix
- *
- * Compute the matrix (translMatrix) * mat * (translMatrix)^{-1}
+ *
+ * Compute the matrix (translMatrix) * mat * (translMatrix)^{-1}
*/
function COBTarget(out,mat)
@@ -2161,7 +2246,7 @@ function shiftScene(lastX,lastY,rawX,rawY)
function panScene(lastX,lastY,rawX,rawY)
{
- if (orthographic) {
+ if(orthographic) {
shiftScene(lastX,lastY,rawX,rawY);
} else {
center.x += (rawX-lastX)*(viewParam.xmax-viewParam.xmin);
@@ -2178,13 +2263,13 @@ function updateViewMatrix()
mat4.multiply(projViewMat,projMat,viewMat);
}
-function capzoom()
+function capzoom()
{
let maxzoom=Math.sqrt(Number.MAX_VALUE);
let minzoom=1/maxzoom;
if(Zoom <= minzoom) Zoom=minzoom;
if(Zoom >= maxzoom) Zoom=maxzoom;
-
+
if(zoomRemeshFactor*Zoom < lastZoom || Zoom > zoomRemeshFactor*lastZoom) {
remesh=true;
lastZoom=Zoom;
@@ -2227,9 +2312,9 @@ function arcball(oldmouse,newmouse)
/**
* Mouse Drag Zoom
* @param {*} lastX unused
- * @param {*} lastY
+ * @param {*} lastY
* @param {*} rawX unused
- * @param {*} rawY
+ * @param {*} rawY
*/
function zoomScene(lastX,lastY,rawX,rawY)
{
@@ -2273,7 +2358,7 @@ function processDrag(newX,newY,mode,factor=1)
lastMouseY=newY;
setProjection();
- draw();
+ drawScene();
}
let zoomEnabled=0;
@@ -2324,10 +2409,10 @@ function handleKey(event)
if(wireframe != 2) {
if(!embedded)
deleteShaders();
- initShaders();
+ initShaders(ibl);
}
remesh=true;
- draw();
+ drawScene();
break;
case '+':
case '=':
@@ -2346,7 +2431,7 @@ function handleKey(event)
if(axis.length > 0) {
mat4.rotate(rotMat,rotMat,0.1,axis);
updateViewMatrix();
- draw();
+ drawScene();
}
}
@@ -2354,14 +2439,14 @@ function setZoom()
{
capzoom();
setProjection();
- draw();
+ drawScene();
}
function handleMouseWheel(event)
{
event.preventDefault();
-
- if (event.deltaY < 0) {
+
+ if(event.deltaY < 0) {
Zoom *= zoomFactor;
} else {
Zoom /= zoomFactor;
@@ -2439,7 +2524,7 @@ function handleTouchMove(event)
pinchStart=distance;
swipe=rotate=zooming=false;
setProjection();
- draw();
+ drawScene();
}
}
@@ -2498,7 +2583,7 @@ function drawTransparent()
}
if(indices.length > 0) {
transformVertices(transparentData.vertices);
-
+
let n=indices.length/3;
let triangles=Array(n).fill().map((_,i)=>i);
@@ -2513,7 +2598,7 @@ function drawTransparent()
IB=indices[b3+1];
IC=indices[b3+2];
- return zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic] <
+ return zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic] <
zbuffer[IA]+zbuffer[IB]+zbuffer[IC] ? -1 : 1;
});
@@ -2544,13 +2629,14 @@ function drawBuffers()
drawColor();
drawTriangle();
drawTransparent();
+ requestAnimationFrame(drawBuffers);
}
-function draw()
+function drawScene()
{
if(embedded) {
- offscreen.width=canvasWidth;
- offscreen.height=canvasHeight;
+ offscreen2.width=canvasWidth;
+ offscreen2.height=canvasHeight;
setViewport();
}
@@ -2564,7 +2650,7 @@ function draw()
if(embedded) {
context.clearRect(0,0,canvasWidth,canvasHeight);
- context.drawImage(offscreen,0,0);
+ context.drawImage(offscreen2,0,0);
}
if(wireframe == 0) remesh=false;
@@ -2574,26 +2660,26 @@ function setDimensions(width,height,X,Y)
{
let Aspect=width/height;
let zoominv=1/Zoom;
- let xshift=(X/width+viewportshift[0])*Zoom;
- let yshift=(Y/height+viewportshift[1])*Zoom;
+ let xshift=(X/width+viewportShift[0])*Zoom;
+ let yshift=(Y/height+viewportShift[1])*Zoom;
- if (orthographic) {
- let xsize=B[0]-b[0];
- let ysize=B[1]-b[1];
- if (xsize < ysize*Aspect) {
+ if(orthographic) {
+ let xsize=maxBound[0]-minBound[0];
+ let ysize=maxBound[1]-minBound[1];
+ if(xsize < ysize*Aspect) {
let r=0.5*ysize*Aspect*zoominv;
let X0=2*r*xshift;
let Y0=ysize*zoominv*yshift;
viewParam.xmin=-r-X0;
viewParam.xmax=r-X0;
- viewParam.ymin=b[1]*zoominv-Y0;
- viewParam.ymax=B[1]*zoominv-Y0;
+ viewParam.ymin=minBound[1]*zoominv-Y0;
+ viewParam.ymax=maxBound[1]*zoominv-Y0;
} else {
let r=0.5*xsize/(Aspect*Zoom);
let X0=xsize*zoominv*xshift;
let Y0=2*r*yshift;
- viewParam.xmin=b[0]*zoominv-X0;
- viewParam.xmax=B[0]*zoominv-X0;
+ viewParam.xmin=minBound[0]*zoominv-X0;
+ viewParam.xmax=maxBound[0]*zoominv-X0;
viewParam.ymin=-r-Y0;
viewParam.ymax=r-Y0;
}
@@ -2621,14 +2707,14 @@ function setProjection()
function initProjection()
{
- H=-Math.tan(0.5*angle)*B[2];
+ H=-Math.tan(0.5*angleOfView)*maxBound[2];
center.x=center.y=0;
- center.z=0.5*(b[2]+B[2]);
+ center.z=0.5*(minBound[2]+maxBound[2]);
lastZoom=Zoom=zoom0;
- viewParam.zmin=b[2];
- viewParam.zmax=B[2];
+ viewParam.zmin=minBound[2];
+ viewParam.zmax=maxBound[2];
shift.x=shift.y=0;
}
@@ -2645,13 +2731,13 @@ function setViewport()
function setCanvas()
{
if(embedded) {
- canvas.width=offscreen.width=canvasWidth;
- canvas.height=offscreen.height=canvasHeight;
+ canvas.width=offscreen2.width=canvasWidth;
+ canvas.height=offscreen2.height=canvasHeight;
}
size2=Math.hypot(canvasWidth,canvasHeight);
halfCanvasWidth=0.5*canvas.width;
halfCanvasHeight=0.5*canvas.height;
- ArcballFactor=1+8*Math.hypot(viewportmargin[0],viewportmargin[1])/size2;
+ ArcballFactor=1+8*Math.hypot(viewportMargin[0],viewportMargin[1])/size2;
}
function setsize(w,h)
@@ -2674,9 +2760,9 @@ function setsize(w,h)
remesh=true;
}
-function resize()
+function resize()
{
- zoom0=Zoom0;
+ zoom0=initialZoom;
if(absolute && !embedded) {
canvasWidth=canvasWidth0*window.devicePixelRatio;
@@ -2696,20 +2782,20 @@ function resize()
let maxViewportWidth=window.innerWidth;
let maxViewportHeight=window.innerHeight;
- viewportshift[0] /= zoom0;
- viewportshift[1] /= zoom0;
+ viewportShift[0] /= zoom0;
+ viewportShift[1] /= zoom0;
setsize(canvasWidth,canvasHeight);
- redraw();
+ redrawScene();
}
-function expand()
+function expand()
{
Zoom *= zoomFactor;
setZoom();
}
-function shrink()
+function shrink()
{
Zoom /= zoomFactor;
setZoom();
@@ -2746,13 +2832,41 @@ class Align {
};
}
-function Tcorners(T,m,M) {
+function Tcorners(T,m,M)
+{
let v=[T(m),T([m[0],m[1],M[2]]),T([m[0],M[1],m[2]]),
T([m[0],M[1],M[2]]),T([M[0],m[1],m[2]]),
T([M[0],m[1],M[2]]),T([M[0],M[1],m[2]]),T(M)];
return [minbound(v),maxbound(v)];
}
+function material(diffuse,emissive,specular,shininess,metallic,fresnel0)
+{
+ Materials.push(new Material(diffuse,emissive,specular,shininess,metallic,
+ fresnel0));
+}
+
+function patch(controlpoints,CenterIndex,MaterialIndex,Min,Max,color)
+{
+ P.push(new BezierPatch(controlpoints,CenterIndex,MaterialIndex,Min,Max,
+ color));
+}
+
+function curve(controlpoints,CenterIndex,MaterialIndex,Min,Max)
+{
+ P.push(new BezierCurve(controlpoints,CenterIndex,MaterialIndex,Min,Max));
+}
+
+function pixel(controlpoint,width,MaterialIndex,Min,Max)
+{
+ P.push(new Pixel(controlpoint,width,MaterialIndex,Min,Max));
+}
+
+function triangles(CenterIndex,MaterialIndex,Min,Max)
+{
+ P.push(new Triangles(CenterIndex,MaterialIndex,Min,Max));
+}
+
// draw a sphere of radius r about center
// (or optionally a hemisphere symmetric about direction dir)
function sphere(center,r,CenterIndex,MaterialIndex,dir)
@@ -3097,6 +3211,87 @@ function tube(v,w,CenterIndex,MaterialIndex,Min,Max,core)
P.push(new BezierCurve(v,CenterIndex,MaterialIndex,Min,Max));
}
+async function getReq(req)
+{
+ return (await fetch(req)).arrayBuffer();
+}
+
+function rgb(image) {
+ return image.getBytes().filter((element,index) => {return index%4 != 3;});
+}
+
+function createTexture(image, textureNumber, fmt=gl.RGB16F)
+{
+ let width=image.width()
+ let height=image.height()
+ let tex=gl.createTexture();
+ gl.activeTexture(gl.TEXTURE0+textureNumber);
+ gl.bindTexture(gl.TEXTURE_2D,tex);
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT,1);
+ gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);
+ gl.texImage2D(gl.TEXTURE_2D,0,fmt,width,height,
+ 0,gl.RGB,gl.FLOAT,rgb(image));
+ return tex;
+}
+
+async function initIBL()
+{
+ let imagePath=imageURL+image+'/';
+
+ function sleep(ms) {
+ return new Promise(resolve => setTimeout(resolve, ms));
+ }
+
+ while(true) { // Wait for EXRLoader to become available.
+ if(Module.EXRLoader)
+ break;
+ await sleep(0);
+ }
+
+ promises=[
+ getReq(imageURL+'refl.exr').then(obj => {
+ let img=new Module.EXRLoader(obj);
+ IBLbdrfMap=createTexture(img,0);
+ }),
+ getReq(imagePath+'diffuse.exr').then(obj => {
+ let img=new Module.EXRLoader(obj);
+ IBLDiffuseMap=createTexture(img,1);
+ })
+ ]
+
+ refl_promise=[]
+
+ refl_promise.push(
+ getReq(imagePath+'refl0.exr')
+ );
+ for(let i=1; i <= roughnessStepCount; ++i) {
+ refl_promise.push(
+ getReq(imagePath+'refl'+i+'w.exr'))
+ }
+
+ finished_promise=Promise.all(refl_promise).then(reflMaps => {
+ let tex=gl.createTexture();
+ gl.activeTexture(gl.TEXTURE0+2);
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT,1);
+ gl.bindTexture(gl.TEXTURE_2D,tex);
+ gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAX_LEVEL,reflMaps.length-1)
+ gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR_MIPMAP_LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);
+ gl.texParameterf(gl.TEXTURE_2D,gl.TEXTURE_MIN_LOD,0.0);
+ gl.texParameterf(gl.TEXTURE_2D,gl.TEXTURE_MAX_LOD,roughnessStepCount);
+ for(let j=0; j < reflMaps.length; ++j) {
+ let img=new Module.EXRLoader(reflMaps[j]);
+ gl.texImage2D(gl.TEXTURE_2D,j,gl.RGB16F,img.width(),img.height(),
+ 0,gl.RGB,gl.FLOAT,rgb(img));
+ }
+ IBLReflMap=tex;
+ });
+
+ promises.push(finished_promise);
+ await Promise.all(promises);
+}
+
function webGLStart()
{
canvas=document.getElementById("Asymptote");
@@ -3132,4 +3327,7 @@ function webGLStart()
resize();
window.addEventListener("resize",resize,false);
+
+ if(ibl)
+ initIBL().then(SetIBL).then(redrawScene);
}
diff --git a/graphics/asymptote/webgl/license b/graphics/asymptote/webgl/license
index f1169e9d3f..ed529615c7 100644
--- a/graphics/asymptote/webgl/license
+++ b/graphics/asymptote/webgl/license
@@ -1,6 +1,6 @@
/*@license
AsyGL: Render Bezier patches and triangles via subdivision with WebGL.
- Copyright 2019-2020: John C. Bowman and Supakorn "Jamie" Rassameemasmuang
+ Copyright 2019-2021: John C. Bowman and Supakorn "Jamie" Rassameemasmuang
University of Alberta
This program is free software; you can redistribute it and/or modify
diff --git a/graphics/asymptote/webgl/vertex.glsl b/graphics/asymptote/webgl/vertex.glsl
index bf55fc0042..91b15463f1 100644
--- a/graphics/asymptote/webgl/vertex.glsl
+++ b/graphics/asymptote/webgl/vertex.glsl
@@ -1,13 +1,43 @@
-attribute vec3 position;
+#ifdef WEBGL2
+#define IN in
+#define OUT out
+#else
+#define IN attribute
+#define OUT varying
+#endif
+
+IN vec3 position;
#ifdef WIDTH
-attribute float width;
+IN float width;
#endif
#ifdef NORMAL
-attribute vec3 normal;
+IN vec3 normal;
#endif
-attribute float materialIndex;
+
+IN float materialIndex;
+
+#ifdef WEBGL2
+flat out int MaterialIndex;
#ifdef COLOR
-attribute vec4 color;
+OUT vec4 Color;
+#endif
+
+#else
+OUT vec4 diffuse;
+OUT vec3 specular;
+OUT float roughness,metallic,fresnel0;
+OUT vec4 emissive;
+
+struct Material {
+ vec4 diffuse,emissive,specular;
+ vec4 parameters;
+};
+
+uniform Material Materials[Nmaterials];
+#endif
+
+#ifdef COLOR
+IN vec4 color;
#endif
uniform mat3 normMat;
@@ -16,39 +46,37 @@ uniform mat4 projViewMat;
#ifdef NORMAL
#ifndef ORTHOGRAPHIC
-varying vec3 ViewPosition;
+OUT vec3 ViewPosition;
#endif
-varying vec3 Normal;
+OUT vec3 Normal;
#endif
-varying vec4 diffuse;
-varying vec3 specular;
-varying float roughness,metallic,fresnel0;
-varying vec4 emissive;
-
-struct Material {
- vec4 diffuse,emissive,specular;
- vec4 parameters;
-};
-
-uniform Material Materials[Nmaterials];
void main(void)
{
vec4 v=vec4(position,1.0);
gl_Position=projViewMat*v;
+
#ifdef NORMAL
#ifndef ORTHOGRAPHIC
ViewPosition=(viewMat*v).xyz;
-#endif
+#endif
Normal=normalize(normal*normMat);
-
+#endif
+
+#ifdef WEBGL2
+ MaterialIndex=int(materialIndex);
+#ifdef COLOR
+ Color=color;
+#endif
+#else
+#ifdef NORMAL
Material m;
#ifdef TRANSPARENT
m=Materials[int(abs(materialIndex))-1];
emissive=m.emissive;
- if(materialIndex >= 0.0) {
+ if(materialIndex >= 0.0)
diffuse=m.diffuse;
- } else {
+ else {
diffuse=color;
#if nlights == 0
emissive += color;
@@ -64,8 +92,8 @@ void main(void)
#endif
#else
diffuse=m.diffuse;
-#endif
-#endif
+#endif // COLOR
+#endif // TRANSPARENT
specular=m.specular.rgb;
vec4 parameters=m.parameters;
roughness=1.0-parameters[0];
@@ -73,7 +101,9 @@ void main(void)
fresnel0=parameters[2];
#else
emissive=Materials[int(materialIndex)].emissive;
-#endif
+#endif // NORMAL
+#endif // WEBGL2
+
#ifdef WIDTH
gl_PointSize=width;
#endif
diff --git a/graphics/asymptote/xstream.h b/graphics/asymptote/xstream.h
index b7947ee3e9..5069ac9f8c 100644
--- a/graphics/asymptote/xstream.h
+++ b/graphics/asymptote/xstream.h
@@ -24,6 +24,8 @@
#endif
#include <cstdio>
+#include <vector>
+#include <algorithm>
#include <sys/types.h>
#include <rpc/types.h>
@@ -39,6 +41,7 @@
#define u_long unsigned long
extern "C" int fseeko(FILE *, off_t, int);
extern "C" off_t ftello(FILE *);
+extern "C" FILE *open_memstream(char **, size_t *);
#endif
#ifdef __APPLE__
@@ -98,7 +101,7 @@ protected:
FILE *buf;
public:
virtual ~xstream() {}
- xstream() {buf=NULL;}
+ xstream() : xios(), buf(nullptr) {}
void precision(int) {}
@@ -121,27 +124,33 @@ public:
{if(!xdr_##N(&xdro, &x)) set(badbit); return *this;}
class ixstream : virtual public xstream {
+private:
+ bool singleprecision;
protected:
XDR xdri;
public:
- void open(const char *filename, open_mode=in) {
+ ixstream(bool singleprecision=false): singleprecision(singleprecision) {}
+
+ virtual void open(const char *filename, open_mode=in) {
clear();
buf=fopen(filename,"r");
if(buf) xdrstdio_create(&xdri,buf,XDR_DECODE);
else set(badbit);
}
- void close() {
+ virtual void close() {
+ closeFile();
+ }
+
+ void closeFile() {
if(buf) {
#ifndef _CRAY
xdr_destroy(&xdri);
#endif
fclose(buf);
- buf=NULL;
+ buf=nullptr;
}
}
-
- ixstream() {}
ixstream(const char *filename) {open(filename);}
ixstream(const char *filename, open_mode mode) {open(filename,mode);}
virtual ~ixstream() {close();}
@@ -162,27 +171,47 @@ public:
IXSTREAM(unsigned char,u_char);
#endif
IXSTREAM(float,float);
- IXSTREAM(double,double);
+
+ ixstream& operator >> (double& x)
+ {
+ if(singleprecision) {
+ float f;
+ *this >> f;
+ x=(double) f;
+ } else
+ if(!xdr_double(&xdri, &x)) set(eofbit);
+ return *this;
+ }
ixstream& operator >> (xbyte& x) {
- x=fgetc(buf);
- if(x.byte() == EOF) set(eofbit);
+ int c=fgetc(buf);
+ if(c != EOF) x=c;
+ else set(eofbit);
return *this;
}
};
class oxstream : virtual public xstream {
+private:
+ bool singleprecision;
protected:
XDR xdro;
public:
- void open(const char *filename, open_mode mode=trunc) {
+ oxstream(bool singleprecision=false) : singleprecision(singleprecision) {}
+
+ virtual void open(const char *filename, open_mode mode=trunc) {
clear();
buf=fopen(filename,(mode & app) ? "a" : "w");
if(buf) xdrstdio_create(&xdro,buf,XDR_ENCODE);
else set(badbit);
}
- void close() {
+ virtual void close()
+ {
+ closefile();
+ }
+
+ void closefile() {
if(buf) {
#ifndef _CRAY
xdr_destroy(&xdro);
@@ -192,10 +221,12 @@ public:
}
}
- oxstream() {}
- oxstream(const char *filename) {open(filename);}
- oxstream(const char *filename, open_mode mode) {open(filename,mode);}
- virtual ~oxstream() {close();}
+ oxstream(const char *filename, bool singleprecision=false): singleprecision(singleprecision) {open(filename);}
+ oxstream(const char *filename, open_mode mode, bool singleprecision=false): singleprecision(singleprecision)
+ {
+ open(filename,mode);
+ }
+ virtual ~oxstream() {closefile();}
oxstream& flush() {if(buf) fflush(buf); return *this;}
@@ -215,7 +246,14 @@ public:
OXSTREAM(unsigned char,u_char);
#endif
OXSTREAM(float,float);
- OXSTREAM(double,double);
+
+ oxstream& operator << (double x) {
+ if(singleprecision)
+ *this << (float) x;
+ else
+ if(!xdr_double(&xdro, &x)) set(badbit);
+ return *this;
+ }
oxstream& operator << (xbyte x) {
if(fputc(x.byte(),buf) == EOF) set(badbit);
@@ -223,9 +261,74 @@ public:
}
};
+class memoxstream : public oxstream
+{
+private:
+ char* baseBuf;
+ size_t len;
+
+public:
+ memoxstream(bool singleprecision=false) :
+ oxstream(singleprecision), baseBuf(nullptr), len(0)
+ {
+ clear();
+ buf=open_memstream(&baseBuf,&len);
+ if(buf)
+ xdrstdio_create(&xdro,buf,XDR_ENCODE);
+ else
+ set(badbit);
+ }
+
+ ~memoxstream() override
+ {
+ closefile();
+ free(baseBuf);
+ }
+
+ [[nodiscard]]
+ char const* stream() const
+ {
+ return baseBuf;
+ }
+
+ [[nodiscard]]
+ size_t const& getLength() const
+ {
+ return len;
+ }
+};
+
+class memixstream: public ixstream
+{
+public:
+ memixstream(char* data, size_t length, bool singleprecision=false) : ixstream(singleprecision)
+ {
+ xdrmem_create(&xdri,data,length,XDR_DECODE);
+ }
+
+ explicit memixstream(std::vector<char>& data, bool singleprecision=false) :
+ memixstream(data.data(), data.size(), singleprecision)
+ {
+ }
+
+ ~memixstream() override
+ {
+ xdr_destroy(&xdri);
+ }
+
+ void close() override
+ {
+ xdr_destroy(&xdri);
+ }
+
+ void open(const char *filename, open_mode = in) override
+ {
+ }
+};
+
class ioxstream : public ixstream, public oxstream {
public:
- void open(const char *filename, open_mode mode=out) {
+ void open(const char *filename, open_mode mode=out) override {
clear();
if(mode & app)
buf=fopen(filename,"a+");
@@ -243,7 +346,7 @@ public:
} else set(badbit);
}
- void close() {
+ void close() override {
if(buf) {
#ifndef _CRAY
xdr_destroy(&xdri);
diff --git a/info/kaytannollista-latexia/README.md b/info/kaytannollista-latexia/README.md
new file mode 100644
index 0000000000..37a7b60035
--- /dev/null
+++ b/info/kaytannollista-latexia/README.md
@@ -0,0 +1,153 @@
+Käytännöllistä Latexia
+======================
+
+**Latex-ladontajärjestelmän opas**
+
+English summary: *Käytännöllistä Latexia* is a Finnish practical manual
+for [Latex](https://en.wikipedia.org/wiki/LaTeX) typesetting system. The
+manual covers most of the topics that a typical document author needs.
+So it can be useful guide for beginners as well as reference manual for
+advanced users.
+
+
+Esittely
+--------
+
+*Käytännöllistä Latexia* on nykyaikainen suomenkielinen opas
+[Latex](https://fi.wikipedia.org/wiki/LaTeX)-ladontajärjestelmän
+käyttäjälle. Se auttaa alkuun pääsyssä ja esittelee merkintäkielen
+perusasiat. Opas sisältää käytännönläheiset ohjeet esimerkiksi
+dokumentin sivu-, fontti- ja kieliasetusten tekemiseen. Se sisältää
+teknisiä ohjeita ja typografisia vinkkejä tavallisimpiin
+tekstidokumentin kirjoittamisen tarpeisiin. Oppaan avulla pitäisi
+pärjätä niin hyvin, että makropakettien ohjeita tarvitsee lukea vain
+harvoin.
+
+Edellisessä kappaleessa mainostettu nykyaikaisuus tarkoittaa esimerkiksi
+sitä, että tässä oppaassa keskitytään Open Type -fontteihin,
+Unicode-merkistöön ja PDF-tiedostoihin. Latexin vanha fonttitekniikka
+sivuutetaan, eikä merkistörajoitusten kanssa enää kamppailla. Oppaan
+ohjeet siis sopivat nykyaikaiselle tietokoneen käyttäjälle.
+
+
+Saatavuus
+---------
+
+Oppaasta on saatavilla valmiiksi ladottu PDF-tiedosto Githubissa
+[julkaisusivulla](https://github.com/tlikonen/latex-opas/releases). Myös
+Latex-lähdetiedostot ovat saatavilla Githubissa osoitteessa
+<<https://github.com/tlikonen/latex-opas>>.
+
+
+Versionumerointi
+----------------
+
+Oppaan versionumerot tulevat julkaisuajan vuosiluvusta sekä
+mahdollisesti kuukaudesta ja päivästä. Vuoden ensimmäinen tai ainoa
+julkaisu saa versionumeronsa pelkästä vuosiluvusta, esimerkiksi versio
+”2022”. Jos samana vuonna julkaistaan oppaasta uusi versio, lisätään
+versionumeroon kyseisen kuukauden numero, esimerkiksi versio ”2022.4”
+(huhtikuu 2022). Saman kuun aikana toinen julkaisu saa versionumeroonsa
+vielä päivänkin numeron, esimerkiksi ”2022.4.15” (15. huhtikuuta 2022).
+
+
+Tekijänoikeus ja lisenssi
+-------------------------
+
+Tekijä: Teemu Likonen <<tlikonen@iki.fi>>
+
+OpenPGP-avain: [6965F03973F0D4CA22B9410F0F2CAE0E07608462][PGP]
+
+[PGP]: http://www.iki.fi/tlikonen/pgp-key.asc
+
+Lisenssi: *Creative Commons Nimeä-JaaSamoin 4.0 Kansainvälinen* (CC
+BY-SA 4.0). Lisenssi antaa sinulle luvan kopioida ja levittää tätä
+teosta tai sen osia missä tahansa välineessä ja muodossa. Sisältöä saa
+muokata, ja sen pohjalta saa luoda uusia teoksia mihin tahansa
+tarkoitukseen, myös kaupallisesti. Ehdot ovat seuraavat:
+
+ - Sinun on mainittava tekijä(t) asianmukaisesti, tarjottava linkki
+ [lisenssin koko tekstiin][CC] sekä mainittava, mikäli olet tehnyt
+ muutoksia.
+ - Jos muokkaat teosta tai luot sen pohjalta uuden teoksen, sinun on
+ jaettava muutoksiasi samalla lisenssillä kuin alkuperäistä teosta.
+ - Et saa asettaa sellaisia oikeudellisia ehtoja tai teknisiä estoja,
+ jotka estävät muita tekemästä asioita, jotka tämä lisenssi sallii.
+
+[CC]: https://creativecommons.org/licenses/by-sa/4.0/legalcode.fi
+
+
+Kääntäminen ja asentaminen
+--------------------------
+
+Oppaan Latex-lähdetiedostojen kääntäminen eli latominen PDF-dokumentiksi
+vaatii useita Latexin makropaketteja ja pari fonttia. Latexin
+jakelukokonaisuus [Texlive](https://tug.org/texlive/) sisältää kaiken
+tarvittavan. Esimerkiksi [Debian](https://www.debian.org) Linux
+-käyttöjärjestelmässä asennuspaketti `texlive-full` asentaa koko
+Texliven.
+
+Oppaan voi latoa julkaisupaketin ja asennettujen tiedostojen avulla tai
+versionhallinnan tiedostojen pohjalta.
+
+
+### Julkaisupaketti
+
+Oppaan julkaisupaketin lähdetiedostot voi latoa PDF-tiedostoksi
+komennoilla `lualatex` ja `biber`. Komennot täytyy suorittaa seuraavassa
+järjestyksessä:
+
+ lualatex -shell-escape kaytannollista-latexia
+ biber kaytannollista-latexia
+ lualatex -shell-escape kaytannollista-latexia
+ lualatex -shell-escape kaytannollista-latexia
+
+
+### Versionhallinta (Git)
+
+Git-versionhallintajärjestelmässä säilytettävä opas sisältää tiedoston
+`Makefile`, joka puolestaan sisältää kääntämisohjeet `make`-komennolle.
+PDF-tiedoston saa ladottua yhdellä komennolla:
+
+ make
+
+Kääntämisessä syntyneen PDF-tiedoston voi siirtää haluamaansa paikkaan
+käyttöä varten. Oppaan voi myös asentaa Texin standardiin
+hakemistorakenteeseen, josta muut ohjelmat voivat sen löytää. Se tehdään
+seuraavalla komennolla:
+
+ make install
+
+Edellisen asennuskomennon voi suorittaa ilman erillistä
+kääntämisvaihettakin, koska ennen asentamista se varmistaa, että
+tarvittavat tiedostot on käännetty. Asennuskohde on käyttäjän
+kotihakemistossa eli polussa `$HOME/texmf`. Kohteeseen asentuu paitsi
+oppaan PDF-tiedosto myös Latexin lähdetiedostot ja tämä käsillä oleva
+`README.md`. Asentamisen jälkeen esimerkiksi Texliveen sisältyvä komento
+`texdoc` osaa löytää ja avata oppaan, kun komennolle antaa argumentiksi
+joitakin oppaan nimen kirjaimia, esimerkiksi `texdoc kaytannoll`.
+
+Asennus poistetaan komennolla `make uninstall`. Komento tosin säilyttää
+polun `$HOME/texmf`, koska siellä voi edelleen sijaita muita Texiin ja
+Latexiin liittyviä tiedostoja.
+
+Kääntämishakemiston voi siivota alla olevilla komennoilla. Ensin
+mainittu komento poistaa useimmat väliaikaistiedostot mutta säilyttää
+oppaan PDF:n ja muut julkaisuun vaadittavat tiedostot. Jälkimmäinen
+poistaa kaikki syntyneet tiedostot.
+
+ make clean
+ make distclean
+
+
+Puutteita ja suunnitelmia
+-------------------------
+
+ - Lisätään Muuta tekniikkaa -luku, jonka sisällöksi esimerkiksi:
+ päiväykset ja kellonajat (datetime2), textpos-paketti, omien
+ makropakettien ja dokumenttiluokkien tekeminen.
+ - Marginaalihuomautusluvussa voisi mainita `\marginpar`-komennon
+ puutteet ja vaihtoehdon `marginnote`.
+ - Mahdollisesti käsitellään wrapfig-paketti.
+ - Uusi `fi-x-school`-tavutuskaava.
+ - Mittojen käsittelyn yhteydessä voisi käsitellä calc-paketin.
diff --git a/info/kaytannollista-latexia/kaytannollista-latexia.pdf b/info/kaytannollista-latexia/kaytannollista-latexia.pdf
new file mode 100644
index 0000000000..aa204101a9
--- /dev/null
+++ b/info/kaytannollista-latexia/kaytannollista-latexia.pdf
Binary files differ
diff --git a/info/kaytannollista-latexia/kaytannollista-latexia.tex b/info/kaytannollista-latexia/kaytannollista-latexia.tex
new file mode 100644
index 0000000000..f983d70bd0
--- /dev/null
+++ b/info/kaytannollista-latexia/kaytannollista-latexia.tex
@@ -0,0 +1,504 @@
+% Tekijä: Teemu Likonen <tlikonen@iki.fi>
+% Lisenssi: Creative Commons Nimeä-JaaSamoin 4.0 Kansainvälinen (CC BY-SA 4.0)
+% https://creativecommons.org/licenses/by-sa/4.0/legalcode.fi
+
+\documentclass[fleqn]{book}
+\usepackage{geometry}
+\usepackage{fontspec}
+\usepackage{polyglossia}
+\usepackage{amsmath}
+\usepackage[math-style=ISO]{unicode-math}
+\usepackage[finnish,showseconds=false]{datetime2}
+\usepackage{ragged2e}
+\usepackage[hang,bottom,norule]{footmisc}
+\usepackage[clearempty]{titlesec}
+\usepackage{titletoc}
+\usepackage{graphicx}
+\usepackage{xcolor}
+\usepackage{floatrow}
+\usepackage{caption}
+\usepackage{fancyvrb}
+\usepackage{tabularx}
+\usepackage{booktabs}
+\usepackage{multirow}
+\usepackage[normalem]{ulem}
+\usepackage[makeindex, splitindex]{indextools}
+% \usepackage{ifthen}
+\usepackage{chngcntr}
+\usepackage{realscripts}
+\usepackage{csquotes}
+\usepackage[style=authoryear, dashed=false, maxbibnames=99]{biblatex}
+\usepackage{tikz}
+\usepackage{totcount}
+\usepackage{nowidow} \setnowidow \setnoclub
+%\usepackage{showhyphens}
+\usepackage{hanging}
+\usepackage{lettrine}
+\usepackage{multicol}
+\usepackage{textpos}
+\usepackage[unicode,hyperfootnotes=false]{hyperref}
+\usepackage[shortcuts]{extdash}
+
+\geometry{ a5paper, twoside, hscale=.72, vscale=.77, hmarginratio=17:28,
+ vmarginratio=20:32, footskip=12mm, footnotesep=13bp,
+ marginparwidth=50bp, marginparsep=10bp }
+
+% \geometry{ papersize={158mm, 220mm}, layout=a5paper, layoutoffset={5mm,
+% 5mm}, showcrop }
+
+\urlstyle{sf}
+\newcommand{\kulmaurl}[1]
+{\href{#1}{\guilsinglleft\nolinkurl{#1}\guilsinglright}}
+\newcommand{\kulmasp}[1]
+{\href{mailto:#1}{\guilsinglleft\nolinkurl{#1}\guilsinglright}}
+
+\input{versio}
+
+\newcommand{\otsikko}{Käytännöllistä Latexia}
+\newcommand{\alaotsikko}{Latex-ladontajärjestelmän opas}
+\newcommand{\tekija}{Teemu Likonen}
+\newcommand{\tekijat}{Teemu Likonen \kulmasp{tlikonen@iki.fi}}
+
+\hypersetup{ hidelinks, bookmarksnumbered,
+ pdfinfo={
+ Title={\otsikko},
+ Subject={\alaotsikko, versio \versio},
+ Author={\tekija},
+ Keywords={Latex, tekstinvalmistus, ladonta, tekstinkäsittely,
+ oppaat, atk-ohjelmat, kirjoittaminen, typografia}
+ }
+}
+
+\setdefaultlanguage{finnish}
+\setotherlanguage{english}
+\newcommand{\englishfont}{}
+\newcommand{\englanti}[1]{\textenglish{#1}}
+\newcommand{\englantik}[1]{\textenglish{\emph{#1}}}
+
+\defaultfontfeatures[\ttfamily]{Ligatures={TeXReset, NoCommon}}
+\usepackage[oldstyle,semibold,ScaleSF=MatchLowercase,StretchTT=.8]
+{libertinus-otf}
+\newcommand{\erikoisfontti}{\rmfamily}
+\newcommand{\viivastofontti}{\rmfamily}
+
+\renewcommand{\scriptsize}{\fontsize{7bp}{7bp}\selectfont}
+\renewcommand{\footnotesize}{\fontsize{8bp}{9bp}\selectfont}
+\renewcommand{\small}{\fontsize{9bp}{10bp}\selectfont}
+\renewcommand{\normalsize}{\fontsize{10.5bp}{13bp}\selectfont}
+\renewcommand{\large}{\fontsize{13bp}{15bp}\selectfont}
+\renewcommand{\Large}{\fontsize{16bp}{18bp}\selectfont}
+\renewcommand{\LARGE}{\fontsize{20bp}{22bp}\selectfont}
+\renewcommand{\huge}{\fontsize{24bp}{26bp}\selectfont}
+\linespread{1}
+\normalsize
+
+\newcommand{\gemenanum}{\addfontfeatures{Numbers=Lowercase}}
+\newcommand{\versaalinum}{\addfontfeatures{Numbers=Uppercase}}
+\newcommand{\murtoluku}[2]{{\addfontfeatures{Fractions=On}#1/#2}}
+
+\setlength{\emergencystretch}{1em}
+
+\setlength{\parindent}{1em}
+\setlength{\bibhang}{\parindent}
+\setlength{\bibitemsep}{.5ex plus .1ex minus .1ex}
+\newlength{\sisennys}\setlength{\sisennys}{1.8em}
+\setlength{\parskip}{0em}
+\setlength{\footnotemargin}{.8em}
+\setlength{\floatsep}{2ex plus 1ex minus .5ex}
+\setlength{\textfloatsep}{4ex plus 1ex minus .5ex}
+\setlength{\multicolsep}{0bp}
+
+\renewcommand{\topfraction}{.75}
+\renewcommand{\floatpagefraction}{.7}
+
+\addbibresource{kirjallisuutta.bib}
+\nocite{*}
+\renewcommand{\bibfont}{\RaggedRight}
+
+\DeclareDelimFormat[bib]{nametitledelim}{\addcolon\space}
+\DeclareDelimFormat[bib]{multinamedelim}{\space--\space}
+\DeclareDelimFormat[bib]{finalnamedelim}{\space--\space}
+\DeclareDelimFormat[textcite,parencite]{finalnamedelim}{\space\&\space}
+\DeclareFieldFormat{url}{Saatavissa: \kulmaurl{#1}}
+\DeclareNameAlias{sortname}{family-given}
+\DeclareNameAlias{default}{family-given}
+\DefineBibliographyStrings{finnish}{andothers = {ym.}}
+
+\DeclareNewFloatType{esimerkki}{name=Esimerkki, within=chapter}
+
+\indexsetup{level=\section*, toclevel=section, noclearpage}
+
+\makeindex[name=paketit, title={Paketit}, columns=2, columnsep=1em]
+\makeindex[name=komennot, title={Komennot}, columns=2, columnsep=1em]
+\makeindex[name=ymparistot, title={Ympäristöt}, columns=2, columnsep=1em]
+\makeindex[name=mitat, title={Mitat}, columns=2, columnsep=1em]
+\makeindex[name=laskurit, title={Laskurit}, columns=2, columnsep=1em]
+\makeindex[name=dokumenttiluokat, title={Dokumenttiluokat}, columns=2,
+columnsep=1em]
+
+\renewcommand{\theFancyVerbLine}
+{\sffamily\versaalinum\fontsize{6bp}{7bp}\selectfont\arabic{FancyVerbLine}}
+
+\DefineVerbatimEnvironment{koodilohko}{Verbatim}{ fontsize=\small,
+ gobble=0, frame=single, framesep=.4em, numbers=left, numbersep=.3em,
+ xleftmargin=0em, xrightmargin=0mm, baselinestretch=1 }
+
+\DefineVerbatimEnvironment{koodilohkosis}{Verbatim}{
+ fontsize=\small, gobble=0, frame=none, numbers=none,
+ numbersep=0em, xleftmargin=\sisennys, xrightmargin=0mm,
+ baselinestretch=1, samepage=true }
+
+\newcommand{\seurausnuoli}{\textcolor[gray]{.5}{⇒}}
+
+\newenvironment{tulos}{%
+ \begin{textblock*}{1cm}(-2em,3bp)
+ \small\seurausnuoli
+ \end{textblock*}
+ \begin{minipage}{\linewidth}
+ \linespread{1}\erikoisfontti\small
+ }{%
+ \end{minipage}
+ \par\addvspace{\baselineskip}
+}
+
+\newenvironment{tulossis}{%
+ \begin{list}{}{
+ \setlength{\leftmargin}{\sisennys}
+ \erikoisfontti\small
+ }\item[\seurausnuoli]}{%
+ \end{list}}
+
+\floatsetup{ style=plain, font={small}, justification=raggedright,
+ margins=raggedright, captionskip=0ex, capposition=bottom }
+
+\floatsetup[table]{ style=plain, captionskip=2ex }
+\floatsetup[figure]{ style=plain, captionskip=2ex }
+
+\captionsetup{ font={small, sf}, labelfont={bf}, textfont={},
+ textformat=period, margin=.5em, justification=RaggedRight,
+ singlelinecheck=off }
+
+\newcommand{\leijutlk}[2]{%
+ \begin{table*}
+ \floatbox{table}{\versaalinum #1}{#2}
+ \end{table*}}
+
+\newcommand{\leijukuva}[2]{%
+ \begin{figure*}
+ \floatbox{figure}{#1}{#2}
+ \end{figure*}}
+
+\newenvironment{nluetelma}{%
+ \begin{list}{\arabic{enumi}.}{
+ \usecounter{enumi}
+ \setlength{\leftmargin}{1.3em}
+ \setlength{\labelsep}{.3em}
+ \setlength{\itemsep}{.2ex plus .2ex}
+ \setlength{\parsep}{0em}
+ \setlength{\topsep}{.2ex plus .2ex}
+ \RaggedRight
+ }}{\end{list}}
+
+\newenvironment{maaritelma}[1]{%
+ \begin{list}{}{
+ \setlength{\leftmargin}{\parindent}
+ \setlength{\labelwidth}{\parindent}
+ \setlength{\listparindent}{\parindent}
+ \setlength{\labelsep}{1em}
+ \setlength{\itemindent}{1em}
+ \setlength{\itemsep}{.2ex plus .2ex}
+ \setlength{\parsep}{0em}
+ \setlength{\topsep}{.2ex plus .2ex}
+ \renewcommand{\makelabel}[1]{#1}
+ }}{\end{list}}
+
+\newcolumntype{L}{>{\RaggedRight\arraybackslash}X}
+
+\definecolor{tavu}{rgb}{1,0,0}
+\definecolor{apuviiva}{gray}{.4}
+\definecolor{mittanuoli}{rgb}{1,0,0}
+
+\definecolor{luokka}{rgb}{0,.3,.3}
+\definecolor{komento}{rgb}{0,0,.5}
+\definecolor{mkomento}{rgb}{.4,0,.4}
+\definecolor{ymparisto}{rgb}{0,.3,0}
+\definecolor{mymparisto}{rgb}{.4,0,.4}
+\definecolor{mitta}{rgb}{.4,0,0}
+\definecolor{laskuri}{rgb}{.4,0,.4}
+\definecolor{paketti}{rgb}{.35,.35,0}
+
+\newcommand{\keno}{\textbackslash}
+\newcommand{\marginaali}[1]{\marginpar{\RaggedRight\footnotesize #1}}
+
+\newcommand{\koodi}[1]{\texttt{#1}}
+% \newcommand{\koodimargin}[1]{\marginaali{\koodi{#1}}}
+\newcommand{\koodimargin}[1]{}
+\newcommand{\koodim}[1]{\koodi{#1}\koodimargin{#1}}
+\newcommand{\koodil}[1]{\enquote{\texttt{#1}}}
+
+\newcommand{\luokkax}[1]{\textcolor{luokka}{\textsf{#1}}}
+\newcommand{\luokkai}[1]{\index[dokumenttiluokat]{#1@\luokkax{#1}}}
+\newcommand{\luokka}[1]{\luokkax{#1}\luokkai{#1}}
+% \newcommand{\luokkamargin}[1]{\marginaali{\luokkax{#1}}}
+\newcommand{\luokkamargin}[1]{}
+\newcommand{\luokkam}[1]{\luokka{#1}\luokkamargin{#1}}
+\newcommand{\luokkactan}[1]{\luokka{#1}\avctan{#1}}
+
+\newcommand{\komentox}[1]{\textcolor{komento}{\koodi{\keno #1}}}
+\newcommand{\komentoi}[1]{\index[komennot]{#1@\komentox{#1}}}
+\newcommand{\komento}[1]{\komentox{#1}\komentoi{#1}}
+\newcommand{\komentojatko}[1]{\katk\textcolor{komento}{\koodi{#1}}}
+\newcommand{\komentoarg}[1]{\komentojatko{\{#1\}}}
+\newcommand{\komentoargv}[1]{\komentojatko{[#1]}}
+% \newcommand{\komentomargin}[1]{\marginaali{\komentox{#1}}}
+\newcommand{\komentomargin}[1]{}
+\newcommand{\komentom}[1]{\komento{#1}\komentomargin{#1}}
+
+\newcommand{\mkomentox}[1]{\textcolor{mkomento}{\koodi{\keno #1}}}
+\newcommand{\mkomentoi}[1]{\index[komennot]{#1@\mkomentox{#1}}}
+\newcommand{\mkomento}[1]{\mkomentox{#1}\mkomentoi{#1}}
+\newcommand{\mkomentojatko}[1]{\katk\textcolor{mkomento}{\koodi{#1}}}
+\newcommand{\mkomentoarg}[1]{\mkomentojatko{\{#1\}}}
+\newcommand{\mkomentoargv}[1]{\mkomentojatko{[#1]}}
+
+\newcommand{\ymparistox}[1]{\textcolor{ymparisto}{\koodi{#1}}}
+\newcommand{\ymparistoi}[1]{\index[ymparistot]{#1@\ymparistox{#1}}}
+\newcommand{\ymparisto}[1]{\ymparistox{#1}\ymparistoi{#1}}
+% \newcommand{\ymparistomargin}[1]{\marginaali{\ymparistox{#1}}}
+\newcommand{\ymparistomargin}[1]{}
+\newcommand{\ymparistom}[1]{\ymparisto{#1}\ymparistomargin{#1}}
+
+\newcommand{\mymparistox}[1]{\textcolor{mymparisto}{\koodi{#1}}}
+\newcommand{\mymparistoi}[1]{\index[ymparistot]{#1@\mymparistox{#1}}}
+\newcommand{\mymparisto}[1]{\mymparistox{#1}\mymparistoi{#1}}
+
+\newcommand{\mittax}[1]{\textcolor{mitta}{\koodi{\keno #1}}}
+\newcommand{\mittai}[1]{\index[mitat]{#1@\mittax{#1}}}
+\newcommand{\mitta}[1]{\mittax{#1}\mittai{#1}}
+% \newcommand{\mittamargin}[1]{\marginaali{\mittax{#1}}}
+\newcommand{\mittamargin}[1]{}
+\newcommand{\mittam}[1]{\mitta{#1}\mittamargin{#1}}
+
+\newcommand{\laskurix}[1]{\textcolor{laskuri}{\koodi{#1}}}
+\newcommand{\laskurii}[1]{\index[laskurit]{#1@\laskurix{#1}}}
+\newcommand{\laskuri}[1]{\laskurix{#1}\laskurii{#1}}
+% \newcommand{\laskurimargin}[1]{\marginaali{\laskurix{#1}}}
+\newcommand{\laskurimargin}[1]{}
+\newcommand{\laskurim}[1]{\laskuri{#1}\laskurimargin{#1}}
+
+\newcommand{\pakettix}[1]{\textcolor{paketti}{\textsf{#1}}}
+\newcommand{\pakettii}[1]{\index[paketit]{#1@\pakettix{#1}}}
+\newcommand{\paketti}[1]{\pakettix{#1}\pakettii{#1}}
+% \newcommand{\pakettimargin}[1]{\marginaali{\pakettix{#1}}}
+\newcommand{\pakettimargin}[1]{}
+\newcommand{\pakettim}[1]{\paketti{#1}\pakettimargin{#1}}
+\newcommand{\pakettictan}[1]{\paketti{#1}\avctan{#1}}
+
+\newcommand{\tavukohta}{\textcolor{tavu}{\raisebox{-.2ex}{\rule{.6bp}{2ex}}}}
+\newcommand{\uctunnus}[1]{\textsc{\englanti{#1}}}
+\newcommand{\avctan}[1]{\footnote{\url{https://www.ctan.org/pkg/#1}}}
+
+\newcommand{\ots}[1]{{\sffamily\bfseries #1}}
+\newcommand{\otsrivi}[1]{{\sffamily #1}}
+\newcommand{\katk}{\discretionary{}{}{}}
+
+\addto{\captionsfinnish}{
+ \renewcommand{\contentsname}{Sisällys}
+}
+
+\newcommand{\otsikkotyyli}{ \raggedright \sffamily \bfseries }
+
+\titleformat{\chapter}
+[display]
+{\Large\bfseries}
+{\chaptertitlename\hspace{.3em}\thechapter}
+{1.5ex}
+{\otsikkotyyli\huge}[]
+\titlespacing*{\chapter}{0em}{*13}{*8}
+
+\titleformat{\section}
+{\otsikkotyyli\large}
+{\thesection}
+{.8em}
+{}[]
+\titlespacing*{\section}{0pt}{*4}{*2}
+
+\titleformat{\subsection}
+{\otsikkotyyli\normalsize}
+{\thesubsection}
+{.8em}
+{}[]
+\titlespacing*{\subsection}{0bp}{*2}{*1}
+
+\titleformat{\subsubsection}
+{\otsikkotyyli\mdseries\scshape\normalsize}
+{\thesubsubsection}
+{.8em}
+{}[]
+\titlespacing*{\subsubsection}{0bp}{*2}{*1}
+
+\titlecontents{chapter}
+[8mm]
+{\addvspace{1.5ex}\rmfamily\bfseries\large}
+{\contentslabel{8mm}}
+{\hspace{-8mm}}
+{\small\titlerule[0bp]\contentspage}
+[\addvspace{.5ex}]
+
+\titlecontents{section}
+[8mm]
+{\addvspace{.5ex}\rmfamily\normalsize}
+{\contentslabel{8mm}}
+{}
+{~\small\titlerule*[3mm]{.}\contentspage}
+[\addvspace{.2ex}]
+
+\titlecontents{subsection}
+[18mm]
+{\rmfamily\small}
+{\contentslabel{10mm}}
+{}
+{~\small\titlerule*[3mm]{.}\contentspage}
+[]
+
+\titlecontents*{subsubsection}
+[18mm]
+{\rmfamily\footnotesize}
+{\thecontentslabel. }
+{}
+{ (\thecontentspage)}
+[ -- ][.]
+
+\regtotcounter{chapter}
+
+\begin{document}
+\rmfamily % Pienversaali ei toimi leipätekstissä ilman tätä.
+
+\input{tavutusvihjeet}
+
+\pagestyle{empty}
+
+\newgeometry{top=1cm, bottom=1.8cm, hmargin=1.3cm}
+
+% \newgeometry{ top=1cm, bottom=1.8cm, hmargin=1.3cm, papersize={158mm,
+% 220mm}, layout=a5paper, layoutoffset={5mm, 5mm}, showcrop }
+
+\pdfbookmark[0]{Nimiö}{sivu/nimiö}
+\DTMsetstyle{finnish-numeric}
+
+\vspace*{.2\textheight}
+
+{
+
+ \setlength{\parindent}{0pt}
+
+ \fontsize{16bp}{16bp}\rmfamily \tekija
+
+ \fontsize{52bp}{52bp}\sffamily\bfseries%
+ \hspace{-3bp}%
+ {\addfontfeatures{LetterSpace=-4} Käytännöllistä}
+
+ \fontsize{65bp}{65bp}\selectfont%
+ \hspace{-5bp}%
+ \LaTeX{}ia
+
+}
+
+\vfill
+
+{
+
+ \raggedleft
+ \alaotsikko \\
+ Versio \versio
+
+}
+
+\clearpage
+\restoregeometry
+\pdfbookmark[0]{Tekijänoikeus}{sivu/tekijänoikeus}
+
+\null\vfill
+
+{
+ \setlength{\parindent}{0em}
+ \setlength{\parskip}{1.2ex plus .1ex}
+
+ \section*{\otsikko}
+
+ \textsc{Tekijä:} \tekijat
+
+ \textsc{Versio:} \versio
+
+ \textsc{Päiväys:} \DTMtoday{} kello \DTMcurrenttime{} (ensijulkaisu:
+ 26.12.2021)
+
+ \textsc{Saatavissa:} \url{https://github.com/tlikonen/latex-opas}
+
+ \textsc{Lisenssi:} \emph{Creative Commons Nimeä-Jaa\-Samoin 4.0
+ Kansainvälinen} (\textsc{cc by-sa} 4.0). Lisenssi antaa sinulle
+ luvan kopioida ja levittää tätä teosta tai sen osia missä tahansa
+ välineessä ja muodossa. Sisältöä saa muokata, ja sen pohjalta saa
+ luoda uusia teoksia mihin tahansa tarkoitukseen, myös kaupallisesti.
+ Ehdot ovat seuraavat:
+
+ \begin{list}{\textbullet}{
+ \setlength{\leftmargin}{1em}
+ \setlength{\topsep}{0ex}
+ \setlength{\partopsep}{0ex}
+ \setlength{\itemsep}{0ex}
+ }
+ \item Sinun on mainittava tekijä(t) asianmukaisesti, tarjottava linkki
+ lisenssin koko tekstiin (ks. alla) sekä mainittava, mikäli olet
+ tehnyt muutoksia.
+ \item Jos muokkaat teosta tai luot sen pohjalta uuden teoksen, sinun on
+ jaettava muutoksiasi samalla lisenssillä kuin alkuperäistä teosta.
+ \item Et saa asettaa sellaisia oikeudellisia ehtoja tai teknisiä
+ estoja, jotka estävät muita tekemästä asioita, jotka tämä lisenssi
+ sallii.
+ \end{list}
+
+ Lisenssin koko teksti: \\
+ \url{https://creativecommons.org/licenses/by-sa/4.0/legalcode.fi}
+
+}
+
+\cleardoublepage
+
+\pagestyle{plain}
+\pdfbookmark[0]{Sisällys}{sivu/sisällys}
+\setcounter{tocdepth}{3}
+\tableofcontents
+
+\setcounter{secnumdepth}{-1}
+\input{luku-esipuhe}
+\setcounter{secnumdepth}{2}
+\input{luku-valmistautuminen}
+\input{luku-merkintakieli}
+\input{luku-asetukset}
+\input{luku-rakenne}
+\input{luku-erikoiset}
+\setcounter{secnumdepth}{-1}
+
+\chapter{Kirjallisuutta}
+\label{luku/kirjallisuutta}
+
+\printbibliography[heading=none]
+
+\chapter{Asiahakemistot}
+\label{luku/asiahakemisto}
+
+\printindex[dokumenttiluokat]
+\indexprologue{\noindent Tekstitilan ja matematiikkatilan komennot on
+ ladottu eri väreillä: \komentox{teksti} ja \mkomentox{matematiikka}.}
+\printindex[komennot]
+\printindex[laskurit]
+\printindex[mitat]
+\printindex[paketit]
+\newpage
+\indexprologue{\noindent Tekstitilan ja matematiikkatilan ympäristöt on
+ ladottu eri väreillä: \ymparistox{teksti} ja
+ \mymparistox{matematiikka}.}
+\printindex[ymparistot]
+
+\end{document}
diff --git a/info/kaytannollista-latexia/kirjallisuutta.bib b/info/kaytannollista-latexia/kirjallisuutta.bib
new file mode 100644
index 0000000000..0b193a5841
--- /dev/null
+++ b/info/kaytannollista-latexia/kirjallisuutta.bib
@@ -0,0 +1,78 @@
+@book{unoffref,
+ author = {Berry, Karl and Gilmore, Stephen and Martinsen, Torsten},
+ title = {Latex 2e: An unofficial reference manual},
+ note = {October 2018},
+ date = 2018,
+ url = {https://latexref.xyz/},
+ langid = {british}
+}
+
+@book{kirjtyypit,
+ author = {Itkonen, Markus},
+ title = {Kirjaintyypit ja tyyli},
+ date = 2015,
+ publisher = {\textsc{rps}-yhtiöt}
+}
+
+@book{typokk,
+ author = {Itkonen, Markus},
+ title = {Typo\-grafian käsikirja},
+ edition = 5,
+ date = 2019,
+ origdate = 2003,
+ publisher = {Typoteekki. Graafinen suunnittelu Markus Itkonen Oy}
+}
+
+@book{lyhyt2e,
+ author = {Oetiker, Tobias and Partl, Hubert and Hyna, Irene and
+ Schlegl, Elisabeth and Hell\-gren, Timo},
+ title = {Pitkänpuoleinen johdanto Latex 2ε:n käyttöön},
+ subtitle = {Eli opi Latex 2ε 133 minuutissa},
+ note = {Versio 4.17fi},
+ date = 2005,
+ url = {https://www.ctan.org/pkg/lshort-finnish},
+ langid = {finnish}
+}
+
+@book{lshort,
+ author = {Oetiker, Tobias and Partl, Hubert and Hyna, Irene and
+ Schlegl, Elisabeth},
+ title = {The Not So Short Introduction to Latex 2ε},
+ subtitle = {Or Latex 2ε in 139 minutes},
+ note = {Version 6.2},
+ date = 2018,
+ url = {https://www.ctan.org/pkg/lshort-english},
+ langid = {british}
+}
+
+@book{kt_oik,
+ author = {Kankaanpää, Salli and Heikkilä, Elina and Korhonen, Riitta
+ and Maamies, Sari and Piehl, Aino and Eronen, Riitta and
+ Hyvärinen, Riitta and Kolehmainen, Taru and Mikkonen, Pirjo
+ and Moilanen, Raija and Pyhälahti, Minna and Räsänen, Matti
+ and Vaula, Sari and Vihonen, Inkaliisa and Wihuri, Elina},
+ title = {Kielitoimiston oikein\-kir\-joi\-tus\-opas},
+ edition = 13,
+ date = 2017,
+ series = {Kotimaisten kielten keskuksen julkaisuja 177},
+ publisher = {Kotimaisten kielten keskus}
+}
+
+@online{ctan,
+ title = {Comprehensive TeX Archive Network},
+ shorttitle = {\textsc{ctan}},
+ url = {https://www.ctan.org/},
+ date = {1992/},
+}
+
+@article{tuhoajana,
+ author = {Korpela, Jukka K.},
+ title = {Tietokone typografian tuhoajana},
+ journaltitle = {Skrolli},
+ journalsubtitle ={Tietokonekulttuurin erikoislehti},
+ date = 2015,
+ volume = 2015,
+ number = 3,
+ pages = {10-14},
+ url = {https://www.skrolli.fi/numerot/2015-3/}
+}
diff --git a/info/kaytannollista-latexia/luku-asetukset.tex b/info/kaytannollista-latexia/luku-asetukset.tex
new file mode 100644
index 0000000000..0f136267c2
--- /dev/null
+++ b/info/kaytannollista-latexia/luku-asetukset.tex
@@ -0,0 +1,2952 @@
+% Tekijä: Teemu Likonen <tlikonen@iki.fi>
+% Lisenssi: Creative Commons Nimeä-JaaSamoin 4.0 Kansainvälinen (CC BY-SA 4.0)
+% https://creativecommons.org/licenses/by-sa/4.0/legalcode.fi
+
+\chapter{Asetukset}
+
+Dokumentin yleiset asetukset koostuvat Latexissa dokumenttiluokan
+valinnasta, sivun koon ja marginaalien määrittelystä, fonttien
+määrittelystä sekä kieliasetuksista. Näitä kaikkia käsitellään tässä
+luvussa.
+
+Kirjoittajan ei tarvitse tehdä kaikkia dokumentin asetuksia kerralla. On
+ehkä jopa suotavaakin keskittyä aluksi lähinnä dokumentin sisällön ja
+rakenteen suunnitteluun ja tuottamiseen. Ulkoasuun kyllä ehtii tulla
+kirjoittamisen aikana monenlaisia ajatuksia, joita ei olisi välttämättä
+alussa osannut huomioida. Kirjoittamaan pääsee hyvinkin yksinkertaisen
+dokumenttirungon avulla (esimerkki \ref{esim/ensimmäinen},
+s.~\pageref{esim/ensimmäinen}), mutta tässä luvussa käsitellään
+asetusten määrittelyä ja mahdollisuuksia melko perusteellisesti.
+
+\section{Dokumenttiluokat}
+\label{luku/dokumenttiluokat}
+
+Latexin lähdedokumenttien alussa on aina samankaltainen rivi, joka
+määrittelee käytettävän dokumenttiluokan ja mahdollisesti dokumentin
+perusasetuksia. Dokumenttiluokka määritellään komennolla
+\komento{documentclass} ja sen argumentiksi annetaan dokumenttiluokan
+nimi. Valinnaisilla argumenteilla vaikutetaan asetuksiin.
+
+\komentoi{documentclass}
+\luokkai{article}
+\begin{koodilohkosis}
+\documentclass[a4paper, 12pt]{article}
+\end{koodilohkosis}
+
+\noindent
+Dokumenttiluokka on eräänlainen pohjadokumentti eli ominaisuuksien ja
+asetusten kokoelma, jonka varaan oma dokumentti kirjoitetaan. Eri
+dokumenttiluokat sisältävät erilaisia ominaisuuksia ja erilaiset
+oletusasetukset. Edellä olevassa esimerkissä käytettiin
+\luokka{article}\-/ luokkaa, joka on yleiskäyttöinen luokka monenlaisten
+dokumenttien kirjoittamiseen. Seuraavissa alaluvuissa käsitellään
+tavallisimpia dokumenttiluokkia ja niiden asetuksia.
+
+% Dokumenttiluokkia voi tehdä itsekin, ja sitä aihetta käsitellään
+% luvussa X.Y.
+
+\subsection{Perusdokumenttiluokat}
+\label{luku/perusdokumenttiluokat}
+
+Muutama dokumenttiluokka kuuluu Latexin perusvalikoimaan, eli ne ovat
+aina saatavilla ja asennettuna, kun itse Latexkin on. Niitä kutsutaan
+välillä standardeiksi dokumenttiluokiksi, ja ne ovat ikään kuin
+muuttumattomia perusluokkia, joiden varaan on turvallista rakentaa omia
+dokumentteja tai muita dokumenttiluokkia. Muita dokumenttiluokkia
+kehitetään Latexin perusosien ulkopuolella, ja niiden ominaisuudet
+voivat muuttua ja kehittyä nopeammin ajan myötä.
+
+Normaalit paperisivuihin perustuvat dokumentit tehdään luokkien
+\luokkam{article}, \luokkam{report} tai \luokkam{book} avulla. Ne ovat
+keskenään hyvin samanlaisia, mutta niiden oletusasetukset poikkeavat
+toisistaan. Karkeasti jaoteltuna \luokka{article}\-/ luokka on
+tarkoitettu lyhyehköille artikkeleille ja yleiseksi perustaksi
+monenlaisille dokumenteille. Sen sijaan \luokka{report} ja \luokka{book}
+on tarkoitettu laajoihin dokumentteihin, ja niissä on kirjatypografian
+piirteitä.
+
+Suurin edellä mainittujen perusluokkien ero on otsikoinnissa ja
+dokumentin jäsentämisessä: \luokka{report} ja \luokka{book} sisältävät
+suuret pääluvut (\komento{chapter}) eli otsikot, jotka alkavat tyhjältä
+sivulta; \luokka{article} ei sisällä samanlaisia päälukuja vaan
+ainoastaan tavalliset leipätekstin mukana kulkevat väliotsikot
+(\komento{section}, \komento{subsection} jne.). Tekstin jäsentämistä
+käsitellään luvussa \ref{luku/jäsennys} ja otsikointia tarkemmin luvussa
+\ref{luku/otsikot}.
+
+Toinen ero perusluokkien välillä on se, että vain \luokka{book}\-/
+luokka sisältää komennot \komento{frontmatter}, \komento{mainmatter} ja
+\komento{backmatter}, joita voi käyttää ilmaisemaan tietokirjan
+erityyppiset osat: esittely\-/, sisältö\-/{} ja liitesivut. Näitä
+käsitellään luvussa \ref{luku/frontmainbackmatter}. Lisäksi
+\luokka{report}\-/ luokka sisältää ympäristön \ymparisto{abstract}, joka
+on tarkoitettu tekstin tiivistelmäosan tekemiseen; \luokka{book}\-/
+luokassa sitä ei ole.
+
+Muut erot koskevat lähinnä oletusasetuksia, mutta asetukset ovat
+tietenkin muutettavissa, eivätkä ne siten ole määräävä tekijä
+valittaessa luokkien \luokka{article}, \luokka{report} ja \luokka{book}
+välillä. Dokumenttiluokkien asetuksia käsitellään seuraavassa
+alaluvussa.
+
+Muita perusdokumenttiluokkia ovat \luokkam{letter} ja \luokka{slides}.
+Nimensä mukaisesti \luokka{letter} on kirjeiden kirjoittamista varten.
+Se sisältää kirjeen tyypilliseen rakenteeseen liittyviä komentoja ja
+soveltuu varsinkin tarpeisiin, joissa täytyy automaattisesti tuottaa
+samanmuotoisia kirjeitä usealle vastaanottajalle. Sama
+Latex\-/dokumentti voi sisältää useita kirjeitä, ja sivunumerointi ja
+alaviitteiden numerointi alkaa joka kirjeessä alusta -- kuten on
+tietysti toivottavaa. \luokka{letter}\-/ luokkaa käsitellään tarkemmin
+luvussa \ref{luku/kirjeet}.
+
+Piirtoheittimien läpinäkyvien kalvojen ja sen kaltaisten dokumenttien
+tekemiseen on dokumenttiluokka \luokkam{slides}. Piirtoheittimet ovat
+jääneet menneisyyteen, ja nykyään jokseenkin vastaavanlainen rooli on
+esitysgrafiikkaohjelmilla, joilla tehdään diaesityksiä esimerkiksi
+esitelmien havaintomateriaaliksi. \luokka{slides}\-/ luokkaa ei varmaan
+tarvita enää mihinkään, mutta esitysgrafiikkaan on olemassa erittäin
+monipuolinen luokka \luokka{beamer}, jonka perusasioita käsitellään
+luvussa \ref{luku/esitysgrafiikka}.
+
+\subsection{Perusdokumenttiluokkien asetukset}
+\label{luku/perusdokumenttiluokat-asetukset}
+
+Taulukkoon \ref{tlk/luokkavalitsimet} on koottu perusdokumenttiluokkien
+valitsimet. Sivun koko asetetaan valitsimilla \koodi{a4\-paper} (210 ×
+297 mm), \koodimargin{*paper} \koodi{a5\-paper} (148 × 210 mm),
+\koodi{b5\-paper} (176 × 250 mm), \koodi{execu\-tive\-paper} (7,25 ×
+10,5 tuumaa), \koodi{legal\-paper} (8,5 × 14 tuumaa) tai
+\koodi{letter\-paper} (8,5 × 11 tuumaa). Latexin oletuksena on
+\koodi{letterpaper}, mutta oletusta voi olla muutettu Latexin
+jakelupaketissa. Varminta on aina itse kirjoittaa haluttu sivukoko
+dokumentin asetuksiin.
+
+\leijutlk{
+ \ttfamily
+ \begin{tabular}{llll}
+ \toprule
+ a4paper & landscape & openright & 10pt \\
+ a5paper & final & openany & 11pt \\
+ b5paper & draft & onecolumn & 12pt \\
+ executivepaper & oneside & twocolumn & titlepage \\
+ legalpaper & twoside & fleqn & notitlepage \\
+ letterpaper & openbib & leqno & clock \\
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Perusdokumenttiluokkien valitsimet}
+ \label{tlk/luokkavalitsimet}
+}
+
+Sivu on oletuksena pystyasennossa, mutta valitsin \koodim{landscape}
+asettaa sen vaaka\-/asentoon. Tämä asetus koskee dokumentin kaikkia
+sivuja, mutta jos haluaa asettaa vain yksittäisiä sivuja
+vaaka\-/asentoon, täytyy käyttää \pakettictan{pdflscape}\-/ pakettia ja
+sen tarjoamaa ympäristöä.
+
+Sivun koon ja muitakin mittoja voi määritellä monipuolisemmin
+\paketti{geometry}\-/paketin toimintojen avulla (luku
+\ref{luku/sivuasetukset}). Jos sitä pakettia käyttää, ei näitä
+dokumenttiluokan sivukokoasetuksia tarvita välttämättä lainkaan.
+
+Leipätekstin fontin koon voi määrittää valitsimilla \koodim{10pt},
+\koodim{11pt} ja \koodim{12pt}, joista ensin mainittu on oletus. Lyhenne
+pt tarkoittaa typografista pistemittaa, joita käsitellään luvussa
+\ref{luku/mitat}. Nämä asetukset vaikuttavat myös sivun marginaaleihin,
+koska fontin koko vaikuttaa tekstiriville mahtuvien merkkien määrään ja
+Latex pyrkii pitämään rivit sopivan mittaisina lukemisen kannalta.
+
+Vain kolme eri fonttikokoa leipätekstille on kovin vähän ja peräisin
+ajalta, jolloin Latexin fontit olivat pikseligrafiikkaa eli muodostuivat
+erillisistä kuvapisteistä. Nykyaikana fontit ovat vektorigrafiikkaa eli
+matemaattisten kaavojen avulla muodostettavia kuvia, ja ne voi venyttää
+mihin kokoon tahansa. Sen vuoksi nämä dokumenttiluokkien
+fonttikokovalitsimet eivät ole kovin tarpeellisia eivätkä riitä kaikkiin
+tarpeisiin nykyaikana. Voi niitä silti käyttää, jos niiden avulla saa
+halutun lopputuloksen. Fontteja käsitellään tarkemmin luvussa
+\ref{luku/kirjaintyypit}.
+
+Dokumentista voi latoa luonnosversion käyttämällä dokumenttiluokan
+valitsinta \koodim{draft}. Luonnoksena ladottuun dokumenttiin tulevat
+merkityksi (musta suorakulmio) ainakin tekstipalstan yli pursuavat
+rivit, mikä voi auttaa tekstikappaleiden ulkoasun korjailussa (luku
+\ref{luku/kappale}). Eri paketit voivat hyödyntää \koodi{draft}\-/
+valitsinta omalla tavallaan eli muuttaa toimintaansa sen perusteella.
+Esimerkiksi grafiikkaan liittyvä paketti \paketti{graphicx} (luku
+\ref{luku/grafiikka}) jättää luonnosversiosta kuvat pois, ja niiden
+paikalla on vain suorakulmio. Pdf\-/tiedoston ristiviitteistä huolehtiva
+\paketti{hyperref}\-/paketti jättää pdf:n sisäiset ristiviitteet ja
+sisällysluettelon tekemättä (luku \ref{luku/ristiviitteet}). Latominen
+voi nopeutua huomattavasti.
+
+Lopullinen ladontatila on \koodim{final}, joka tarkoittaa, että
+dokumenttiin ladotaan kaikki sisältö ja ominaisuudet niin kuin se on
+tarkoitettu julkaistavaksi. Tätä valitsinta ei tarvitse käyttää, koska
+se on oletustila.
+
+Sivujen yksipuolisuus (\koodim{oneside}) ja kaksipuolisuus
+(\koodim{twoside}) ovat asetuksia, jotka vaikuttavat sivun marginaalien
+asetuksiin ja mahdollisesti uuden pääluvun (\komento{chapter})
+aloitukseen. Oletus on yksipuolinen dokumentti kaikissa muissa
+perusdokumenttiluokissa paitsi \luokka{book}\-/ luokassa, jonka oletus
+on kaksipuolinen.
+
+Yksipuolisessa dokumentissa kaikkien sivujen marginaalit ovat
+lähtökohtaisesti samanlaisia ja asetuksissa puhutaan esimerkiksi
+vasemmasta (\englanti{left}) ja oikeasta (\englanti{right})
+marginaalista. Kaksipuolisessa dokumentissa sivut ajatellaan pareittain:
+kaksi sivua muodostaa kirjan aukeaman, jonka vasemmalla puolella on
+parillinen sivunumero ja oikealla pariton. Marginaalien asetuksissa
+puhutaan sisämarginaaleista (\englanti{inner}) ja ulkomarginaaleista
+(\englanti{outer}). Sisämarginaalit ovat oletuksena pienemmät, koska
+niitä on aukeamalla aina kaksi vierekkäin. Ulkomarginaaleissa on tilaa
+marginaalihuomautuksille (luku \ref{luku/marginaalihuomautukset}).
+Marginaaleja ja muita sivun asetuksia käsitellään tarkemmin luvussa
+\ref{luku/sivuasetukset}.
+
+Jos dokumentti on määritetty kaksipuoliseksi (\koodi{twoside}), voidaan
+\koodim{open\-right}\-/ valitsimella määrittää pääluvut
+(\komento{chapter}) alkamaan aina oikeanpuoleiselta sivulta. Se onkin
+oletus dokumenttiluokassa \luokka{book}. Valitsin \koodim{open\-any}
+asettaa pääluvut alkamaan miltä tahansa seuraavalta sivulta.
+
+Valitsin \koodim{open\-bib} liittyy automaattiseen lähdeluettelon
+muotoiluun. Jos tämä valitsin on mukana, automaattisessa lähdeluettelon
+muotoilussa lisätään rivinvaihtoja lähdemerkinnän eri osien kuten
+teoksen tekijöiden ja teoksen nimen jälkeen. Lähdemerkintöjä ja
+lähdeluettelon laatimista käsitellään luvussa \ref{luku/lähteet}.
+
+Matemaattisten kaavojen ladontaan liittyvässä \ymparisto{equation}\-/
+ympäristössä kaavat ladotaan normaalisti vaakasuunnassa sivun keskelle.
+Dokumenttiluokan valitsinta \koodim{fleqn} käyttämällä kaavat ladotaan
+kuitenkin sivun vasempaan reunaan. Kaavojen numerot sijoitetaan
+oletuksena sivun oikeaan reunaan, mutta valitsimella \koodim{leqno} ne
+saa ladottua sivun vasempaan reunaan. Matematiikkatilaa käsitellään
+luvussa \ref{luku/matematiikka}.
+
+Kansisivun tai dokumentin perustietojen esitystapaan vaikutetaan
+valitsimilla \koodim{title\-page} ja \koodim{no\-title\-page}. Latexissa
+on yksinkertaiset komennot dokumentin perustietojen eli pääotsikon,
+tekijöiden nimien ja päiväyksen latomiseen (luku
+\ref{luku/dokumentin-perustiedot}), ja näillä valitsimilla vaikutetaan
+siihen, ladotaanko perustiedot omalle sivulleen (\koodi{title\-page})
+vaiko ensimmäisen sisältösivun alkuun (\koodi{no\-title\-page}).
+Oletus\-asetus vaihtelee eri dokumenttiluokissa.
+
+Oletuksena sivun tekstit ladotaan yhdelle palstalle
+(\koodim{onecolumn}), mutta valitsimella \koodim{twocolumn} teksti
+ladotaan kahdelle palstalle. Nämä valitsimet vaikuttavat myös sivun
+marginaaleihin. Latexin perusosat eivät hallitse useampaa kuin kaksi
+palstaa, mutta \paketti{multicol}\-/paketin avulla saa enemmänkin.
+Palstoja käsitellään luvussa \ref{luku/palstat}.
+
+Dokumenttiluokassa \luokka{slides} toimii \koodim{clock}\-/ valitsin,
+joka latoo kellonajan piirtoheitinkalvon loppuun \komento{note}\-/
+komennon yhteydessä. Tämä valitsin kuulunee samaan paikkaan kuin
+piirtoheittimet ja \luokka{slides}\-/luokkakin: kierrätykseen tai
+kaatopaikalle.
+
+\subsection{Muita dokumenttiluokkia}
+
+Kuka tahansa voi tehdä ja julkaista omia dokumenttiluokkia, ja niinpä
+perusdokumenttiluokkien lisäksi onkin saatavilla monenlaisia luokkia.
+Tässä käsitellään vain joitakin.
+
+Luokka \luokka{memoir} on Latexin \luokka{book}\-/luokkaan perustuva,
+ominaisuuksiltaan laajennettu luokka, joka sopii yleiskäyttöön. Tähän
+luokkaan on sisällytetty monia dokumentin rakenteeseen ja ulkoasuun
+liittyviä toimintoja, joihin yleensä tarvitaan erillisiä paketteja
+tai muuten lisäkoodia. Sen sijaan, että ratkoisi dokumentin rakenteen ja
+asettelun kysymyksiä erillisten pakettien avulla, saattaisi olla
+helpompaa lukea (lähes) pelkästään vain \luokka{memoir}\-/ luokan
+ohjekirjaa ja toteuttaa asiat yhtenäisen järjestelmän avulla.
+
+\luokka{beamer}\-/luokka on monipuolinen ja huippuunsa viritetty luokka
+esitysgrafiikan eli diaesitysten tekemiseen. Se on eräänlainen Latexin
+vastine esimerkiksi \englanti{Libreoffice Impress}\-/{} ja
+\englanti{Microsoft Powerpoint} \=/ohjelmille.
+
+Pienempiin, rajattuihin erityistarpeisiin on olemassa useita luokkia.
+Esimerkiksi yksisivuisten taitettavien lehtisten kuten tapahtuman
+käsiohjelmien tekemiseen soveltuu \luokka{leaflet}\-/luokka.
+\textsc{cd}\-/levyjen kansia voi tehdä \luokka{cd}\-/luokan avulla.
+Kuvitettuja seinäkalentereita vartenkin on tehty oma luokkansa,
+\luokka{wallcalendar}. Kitaran tablatuureja eli otelautakuvaan
+perustuvia nuotteja voi tehdä \luokka{guitartabs}\-/ luokan avulla.
+
+Kaikenlaista on siis olemassa. Saatavilla oleviin dokumenttiluokkiin voi
+tutustua esimerkiksi \englanti{Comprehensive Tex Archive Network}
+(\textsc{ctan}) \=/verkkosivun avulla.%
+\footnote{\url{https://www.ctan.org/topic/class}}
+
+\section{Sivu}
+\label{luku/sivuasetukset}
+
+Latex\-/dokumentit muodostuvat aina peräkkäisistä sivuista, eli
+taustalla kummittelee paperiarkkeihin perustuva julkaisumuoto, vaikka
+dokumenttia ei varsinaisesti tulostettaisi tai painettaisi paperille.
+Tämän vuoksi melkein aina täytyy määrittää sivun asetukset kuten
+paperikoko ja marginaalit. Ne tehdään \pakettim{geometry}\-/ paketin
+avulla, jota käsitellään luvussa \ref{luku/sivun-mitat}. Joskus halutaan
+muokata sivun ylä- tai alatunnistetta eli verrattain pysyviä
+tunnistetietoja, jotka toistuvat joka sivulla ylä- tai alareunassa.
+Niiden muokkaamiseen käytetään \paketti{fancyhdr}\-/ pakettia, jonka
+ohjeita on luvussa \ref{luku/ylä-ala-tunnisteet}.
+
+\subsection{Sivun koko ja marginaalit}
+\label{luku/sivun-mitat}
+
+Paperin eli sivun kokoon ja marginaaleihin pääsee vaikuttamaan
+\pakettictan{geometry}\-/ paketin avulla. Halutut asetukset voi kertoa
+paketin lataamisen yhteydessä. Seuraavassa esimerkissä asetetaan
+paperikoko (\koodi{a4\-paper} eli \textsc{a4}-koko), ylä- ja
+alamarginaalin pituus (\koodi{top}, \koodi{bottom}) sekä vasemman ja
+oikean marginaalin pituus (\koodi{left}, \koodi{right}).
+
+\komentoi{usepackage}
+\begin{koodilohkosis}
+\usepackage[a4paper, top=20mm, bottom=30mm,
+ left=20mm, right=20mm]{geometry}
+\end{koodilohkosis}
+
+\noindent
+Vaihtoehtoisesti asetukset voi ilmaista erikseen \komentom{geometry}\-/
+komennon avulla seuraavalla tavalla:
+
+\komentoi{usepackage}
+\komentoi{geometry}
+\begin{koodilohkosis}
+\usepackage{geometry}
+\geometry{a4paper, top=20mm, bottom=30mm, left=20mm, right=20mm}
+\end{koodilohkosis}
+
+\noindent
+Mikäli myöhemmin dokumentissa täytyy vaihtaa sivun asettelua, käytetään
+komentoa \komentom{newgeometry}. Alkuperäiset asetukset palautetaan
+komennolla \komentom{restoregeometry}.
+
+\komentoi{newgeometry}
+\komentoi{restoregeometry}
+\begin{koodilohkosis}
+\newgeometry{top=…, bottom=…, …} % Uudet asetukset.
+\restoregeometry % Palautetaan alkuperäiset asetukset.
+\end{koodilohkosis}
+
+\noindent
+Valmiiksi määriteltyjä standardipaperikokoja on useita.
+\textsc{iso}\-/standardin mukaiset koot \textsc{a0}--\textsc{a6}
+valitaan valitsimilla kuten \koodimargin{*paper} \koodi{a3paper},
+\koodi{a4paper} tai \koodi{a5paper}. Samoin käytetään myös kokoja
+\textsc{b0}--\textsc{b6} ja \textsc{c0}--\textsc{c6}, esimerkiksi
+\koodi{b2paper} tai \koodi{c6paper}. Lisäksi on valittavissa useita
+japanilaisia ja yhdysvaltalaisia standardeja käyttämällä valitsimia
+kuten \koodi{b0j}--\koodi{b6j}, \koodi{ansi\-a\-paper} tai
+\koodi{letter\-paper}.
+
+Mikäli standardit koot eivät riitä, voi sivun mitat määrittää vapaasti
+\koodim{paper\-size}\-/ valitsimella, jolle annetaan arvoksi leveys- ja
+korkeusmitta.
+
+\komentoi{geometry}
+\begin{koodilohkosis}
+\geometry{papersize={10cm, 16cm}}
+\end{koodilohkosis}
+
+\noindent
+Sivu on oletuksena pystyasennossa (\koodim{portrait}), mutta sen voi
+asettaa vaaka\-/asentoon valitsimella \koodim{landscape}. Tämä asetus on
+voimassa koko dokumentin ajan. Jos haluaa asettaa vain yksittäisiä
+sivuja vaaka\-/asentoon, täytyy käyttää \pakettictan{pdflscape}\-/
+pakettia ja sen tarjoamaa ympäristöä.
+
+Sivun asetusten suunnittelussa voi olla avuksi valitsin
+\koodim{show\-frame}, joka piirtää viivat marginaalien kohdalle ja
+merkitsee myös ylä- ja alatunnisteiden sekä marginaalihuomautusten
+rajoja.
+
+Taulukkoon \ref{tlk/sivun-marginaalit} on koottu tärkeimpiä valitsimia
+marginaalien mittojen asettamiseksi. Valitsimille annetaan arvoksi Texin
+mittayksikkö, jotka ovat taulukossa \ref{tlk/mittayksiköt}
+(s.~\pageref{tlk/mittayksiköt}). Kaksipuolisessa
+\koodimargin{twoside=\katk true} \koodimargin{twoside=\katk false}
+asettelussa (\koodi{twoside=\katk true}) sivut muodostavat aukeaman eli
+on erikseen vasemmanpuoleinen ja oikeanpuoleinen sivu. Tällöin vasen ja
+oikea marginaali vuorottelevat, ja niitä on havainnollisempaa kutsua
+sisä- ja ulkomarginaaliksi. Marginaalien määrittelyssä voi käyttää
+valitsimen \koodi{left} sijasta valitsinta \koodi{inner}, ja vastaavasti
+\koodi{right}\-/ valitsin voidaan korvata \koodi{outer}\-/ valitsimella.
+Teknisesti näillä ei ole mitään eroa, mutta nimet ovat ihmisille
+havainnollisempia.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[3]{\koodi{#1} & \koodi{#2} & #3 \\}
+ \begin{tabular}{lll}
+ \toprule
+ \multicolumn{2}{l}{\ots{Valitsin}} & \ots{Merkitys} \\
+ \midrule
+ \rivi{left}{inner}{vasen marginaali tai sisämarginaali}
+ \rivi{right}{outer}{oikea marginaali tai ulkomarginaali}
+ \rivi{top}{}{ylämarginaali}
+ \rivi{bottom}{}{alamarginaali}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{\paketti{geometry}\-/paketin valitsimia sivun marginaalien
+ määrittelemiseen}
+ \label{tlk/sivun-marginaalit}
+}
+
+Sivun tekstialueen koon ja marginaalit voi määrittää myös
+suhteellisesti. Voisi esimerkiksi määrittää, että leveyssuunnassa
+tekstialue täyttää 0,7\=/kertaisesti (70\,\%) sivun leveyden ja loput
+jää marginaaleille. Marginaalien keskinäiset suhteetkin voi ilmaista
+suhdelukuna: esimerkiksi vasemman (sisä) ja oikean (ulko) marginaalin
+suhde voisi olla 2:3. Suhteellisessa tavassa ei tarvitse ottaa kantaa
+sivun kokoon eikä muihinkaan varsinaisiin mittoihin, vaan samat
+tekstialueen ja marginaalien suhteet säilyvät, vaikka sivukokoa
+muuttaisikin. Suhteellisia mittoja koskevia valitsimia on koottu
+taulukkoon \ref{tlk/sivun-marginaalit-suhd}.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\koodi{#1} & #2 \\}
+ \begin{tabular}{ll}
+ \toprule
+ \ots{Valitsin} & \ots{Merkitys} \\
+ \midrule
+ \rivi{hscale}{tekstialueen osuus sivun leveydestä}
+ \rivi{vscale}{tekstialueen osuus sivun korkeudesta}
+ \rivi{hmarginratio}{vasemman (sisä) ja oikean (ulko) marginaalin suhde}
+ \rivi{vmarginratio}{ylä- ja alamarginaalin suhde}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{\paketti{geometry}\-/paketin valitsimia sivun tekstitilan ja
+ marginaalien suhteiden määrittämiseen. Osuudet (\koodi{*scale})
+ ilmaistaan prosenttikertoimella (esim. \koodi{0.7}). Suhteet
+ (\koodi{*marginratio}) ilmaistaan suhdelukuna (esim. \koodi{2:3})}
+ \label{tlk/sivun-marginaalit-suhd}
+}
+
+Klassisessa kirjatypografiassa, jossa teksti ladotaan yhdelle palstalle,
+marginaalien suuruusjärjestys on suurimmasta pienimpään seuraavanlainen:
+ala-, ulko-, ylä- ja sisämarginaali. Suhdeluvut samassa järjestyksessä:
+32, 28, 20, 17. \paketti{geometry}\-/paketin valitsimilla tämä
+ilmaistaan seuraavasti:
+
+\komentoi{geometry}
+\begin{koodilohkosis}
+\geometry{hmarginratio=17:28, vmarginratio=20:32}
+\end{koodilohkosis}
+
+\noindent
+Klassisia suhteita ei nykyaikana yleensä noudateta kovin tarkasti, mutta
+niistä kannattaa ymmärtää yleinen ajatus. Alamarginaalin pitäisi olla
+hieman suurempi kuin ylämarginaali, koska muuten tekstialue tuntuu
+pudonneen sivulla alas. Alamarginaalissa (alatunnisteessa) on yleensä
+sivunumero. Kirjan sivuja katsotaan pareittain eli aukeamina, joten
+sisämarginaaleja on kaksi vierekkäin. Siksi sisämarginaalit yksittäin
+ajateltuna ovat pienemmät kuin ulkomarginaalit. Lisäksi ulkomarginaaleja
+voidaan käyttää huomautusten kirjoittamiseen, mikä on melko yleinen
+käytäntö tietokirjoissa.
+
+Marginaalihuomautukset (luku \ref{luku/marginaalihuomautukset})
+sijaitsevat oletuksena sivujen ulkomarginaalissa tai oikeanpuoleisessa
+marginaalissa. Huomautuspalstan leveys asetetaan valitsimella
+\koodim{marginparwidth}, ja palstan etäisyys sivun varsinaisesta
+tekstialueesta määritellään valitsimella \koodim{marginparsep}. Kumpikin
+valitsin tarvitsee argumentiksi mitan. Jos haluaa vaihtaa huomautukset
+sivun vastakkaiseen marginaaliin, lisätään mukaan valitsin
+\koodi{reversemarginpar}.
+
+Perus Latex osaa latoa tekstin yhdelle tai kahdelle palstalle, ja
+\paketti{geometry}\-/ paketin valitsimella \koodim{onecolumn} tai
+\koodim{twocolumn} asetetaan, kumpi tila on oletuksena päällä.
+Useampikin palsta on mahdollista paketin avulla. Valitsimen
+\koodim{columnsep} avulla asetetaan palstojen välinen etäisyys.
+Käytännössä tämä valitsin on asettaa mitan \mitta{columnsep}, jota voi
+muokata myös komennolla \komento{setlength}, kuten muitakin mittoja
+(luku \ref{luku/mitat}). Tarkempaa tietoa palstoista on luvussa
+\ref{luku/palstat}.
+
+\subsection{Sivun mittoja}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\mitta{#1} & #2 \\}
+ \begin{tabular}{ll}
+ \toprule
+ \ots{Mitta} & \ots {Merkitys} \\
+ \midrule
+ \rivi{paperwidth}{paperin eli sivun leveys}
+ \rivi{paperheight}{paperin eli sivun korkeus}
+ \rivi{textwidth}{tekstialueen leveys}
+ \rivi{columnwidth}{nykyisen palstan leveys}
+ \rivi{linewidth}{nykyisen rivin leveys}
+ \rivi{textheight}{tekstialueen korkeus}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Sivun mittoja}
+ \label{tlk/sivun-mittoja}
+}
+
+Sivun kokoasetusten määrittämisen jälkeenkin voi olla tarpeen viitata
+joihinkin sivun mittoihin. Usein esimerkiksi halutaan piirtää sivun
+tekstialueen levyinen tai siihen suhteutettu taulukko tai kuva. Silloin
+on kätevää käyttää mittaa, jonka arvona on juuri tekstialueen leveys.
+Tärkeimmät sivun mitat on koottu taulukkoon \ref{tlk/sivun-mittoja},
+mutta perusteellisemmin niitä käsitellään \pakettictan{geometry}\-/
+paketin ohjekirjassa.
+
+Taulukossa \ref{tlk/sivun-mittoja} mainittu mitta \mitta{linewidth}
+eroaa tekstialueen (\mitta{textwidth}) tai palstan (\mitta{columnwidth})
+leveysmitasta esimerkiksi silloin, kun tekstikappaletta on sisennetty.
+Kappaleiden ensimmäinen rivi voi olla sisennetty, ja sen vuoksi rivi ei
+ole täysilevyinen. Muutkin sisennykset kuten lohkolainaukset tai
+luetelmat vaikuttavat rivin leveysmittaan. Sisennysasiat liittyvät
+tekstikappaleiden muotoiluun, jota käsitellään
+luvussa~\ref{luku/kappale}. Luetelmia puolestaan käsitellään
+luvussa~\ref{luku/luetelmat}.
+
+\subsection{Leikkuuvarat}
+
+Sivu voi olla ulkoisesti erikokoinen kuin sisäisesti. On siis
+mahdollista asettaa sivu esimerkiksi \textsc{a4}\-/kokoiseksi ja
+käsitellä marginaalit ja muut sivun mitat \textsc{a4}-koon mukaan, mutta
+ulkoisesti tai fyysisesti sivu onkin osana suurempaa sivua tai
+paperiarkkia. Tällaista tarvitaan ainakin silloin, kun halutaan
+merkitä leikkuuvarat dokumentin painamista varten.
+
+Painokoneen paperiarkkien leikkauskohta ei välttämättä osu täsmälleen
+samaan kohtaan pdf\-/tiedoston sivun reunan kanssa, ja siksi
+dokumentissa reunaan saakka yltävät kuvat asetetaan varmuuden vuoksi
+hieman ylikokoiseksi. Sivun reunaan saakka aiotut kuvat siis yltävät
+lähde-pdf:ssä pari millimetriä varsinaisen sivualueen ulkopuolelle eli
+leikkuuvaran puolelle. Tällä varmistetaan, että painamisen jälkeen
+leikatuissa paperiarkeissa kuva varmasti yltää reunaan saakka.
+
+Jos dokumenttiin tarvitaan sivun ulkopuoliset leikkuuvarat, määritellään
+dokumentin ulommaiset mitat edelleen samalla tavalla kuin
+tavallisestikin eli esimerkiksi valitsimella \koodi{paper\-size} (luku
+\ref{luku/sivun-mitat}). \koodimargin{layout} \koodimargin{layout\-size}
+Sen sijaan sivun sisäiset mitat täytyy määritellä toisella tavalla,
+käyttämällä valitsinta \koodi{lay\-out} tai \koodi{layout\-size}.
+
+\begin{esimerkki*}
+ \komentoi{geometry}
+\begin{koodilohko}
+\geometry{
+ papersize={220mm, 307mm},
+ layout=a4paper, % tai: layoutsize={210mm, 297mm}
+ layoutoffset={5mm, 5mm},
+ showcrop
+}
+\end{koodilohko}
+ \caption{Sivun ulkoisten ja sisäisten mittojen sekä leikkuvaarojen
+ määrittäminen}
+ \label{esim/leikkuuvarat}
+\end{esimerkki*}
+
+Esimerkissä \ref{esim/leikkuuvarat} käytetään sisäisesti \textsc{a4}\-/
+kokoista (210 × 297~mm) sivua, mutta sivulle on määritetty joka puolelle
+5\,mm:n leikkuuvarat. Niinpä ulkoisesti sivu on 10\,mm leveämpi ja
+korkeampi, eli ulkoiset mitat ovat 220 × 307~mm. Valitsimella
+\koodi{layout\-offset} asetetaan sisäisen sivun etäisyys ulkoisen sivun
+vasemmasta ylänurkasta. Esimerkissä on mukana myös valitsin
+\koodi{show\-crop}, joka merkitsee sisäisen ja ulkoisen sivun rajakohdan
+eli leikkuuvaran rajan. Merkinnät näkyvät vain sivun nurkissa
+leikkuuvaran puolella, joten ne eivät päädy lopulliseen
+painotuotteeseen.
+
+\subsection{Ylä- ja alatunnisteet}
+\label{luku/ylä-ala-tunnisteet}
+
+\paketti{geometry}\-/paketin asetuksiin kuuluu pari valitsinta, joilla
+vaikutetaan ylä- ja alatunnisteiden mittoihin. Valitsimella \koodi{head}
+ilmaistaan ylätunnisteen korkeus ja valitsimella \koodi{headsep} sen
+etäisyys sivun tekstipalstasta. Alatunnisteen peruslinjan etäisyys
+tekstipalstasta säädetään valitsimella \koodi{footskip}. Taulukkoon
+\ref{tlk/ylä-ala-tunnistemitat} on koottu näiden valitsimien merkitys,
+ja seuraavassa on niiden käyttämisestä esimerkki. Mukana on myös
+valitsin \koodi{show\-frame}, joka piirtää sivulle apuviivoja. Se auttaa
+sivun mittojen suunnittelussa.
+
+\komentoi{geometry}
+\begin{koodilohkosis}
+\geometry{head=24bp, headsep=8bp, footskip=12mm, showframe}
+\end{koodilohkosis}
+
+\leijutlk{
+ \begin{tabular}{ll}
+ \toprule
+ \ots{Valitsin} & \ots{Merkitys} \\
+ \midrule
+ \koodi{head} & ylätunnisteen korkeusmitta \\
+ \koodi{headsep} & ylätunnisteen etäisyys tekstipalstasta \\
+ \koodi{footskip} & alatunnisteen peruslinjan etäisyys tekstipalstasta \\
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{\paketti{geometry}\-/paketin valitsimet ylä- ja
+ alatunnisteiden mittojen asettamiseen}
+ \label{tlk/ylä-ala-tunnistemitat}
+}
+
+\noindent
+Latexin perusosat eivät sisällä kovin kummoista keinovalikoimaa ylä- ja
+alatunnisteiden muokkaamiseen, mutta pari hyödyllistä sivutyyliä on
+kuitenkin mukana. Ylä- ja alatunnisteet määräytyvät sivutyylin
+perusteella, ja haluttu tyyli asetetaan voimaan komennolla
+\komentom{pagestyle}:
+
+\komentoi{pagestyle}
+\begin{koodilohkosis}
+\pagestyle{plain}
+\end{koodilohkosis}
+
+\noindent
+Edellä mainittu sivutyyli \koodim{plain} latoo alatunnisteeseen
+sivunumeron. Se on yleensä oletustyyli. Sivunumero on peräisin
+laskurista \laskuri{page} ja sen arvon tulostavasta komennosta
+\komento{thepage} (luku \ref{luku/laskurit}). Toinen hyödyllinen tyyli
+on \koodim{empty}, joka nimensä mukaisesti tarkoittaa tyhjää, eli ylä-
+eikä alatunnisteeseen ei ladota mitään.
+
+Yksittäiselle sivulle voi asettaa muusta dokumentista poikkeavan
+sivutyylin komennolla \komentom{thispagestyle}. Komento siis vaikuttaa
+vain sillä hetkellä ladottavan sivun tyyliin, ja sen jälkeen palataan
+taas voimassa olevaan tyyliin, joka on aiemmin määritelty komennolla
+\komento{pagestyle}.
+
+\komentoi{thispagestyle}
+\begin{koodilohkosis}
+\thispagestyle{empty}
+\end{koodilohkosis}
+
+\noindent
+Sivutyyli \koodim{headings} latoo ylätunnisteeseen aukeaman
+vasemmanpuoleisille sivuille esimerkiksi kirjan pääluvun nimen ja
+oikeanpuoleisille sivuille meneillään olevan alaluvun nimen. Mainitut
+lukujen nimet tulevat sivun sisäreunaan; ulkoreunaan ladotaan
+sivunumero.
+
+Teknisesti ja sisäisesti tämä on toteutettu siten, että pääluvun
+aloittava otsikkokomento (esim. \komento{chapter}) automaattisesti
+määrittelee joka kerta uudelleen komennon \komento{leftmark}, niin että
+se sisältää pääluvun nimen. Sivuja ladottaessa Latex sitten latoo
+ylätunnisteeseen sen, mitä \komento{leftmark}\-/komento sattuu
+tulostamaan. Vastaavasti alaluvun otsikkokomento (esim.
+\komento{section}) määrittelee uudelleen komennon \komento{rightmark},
+niin että se sisältää alaluvun nimen. Tämän komennon tulostama teksti
+ladotaan aukeaman oikeanpuoleisille sivuille.
+
+Jos haluaa itse vaikuttaa ylätunnisteen tekstiin, voi käyttää sivutyyliä
+\koodim{myheadings} sekä komentoa \komento{markboth}, jolla määritellään
+aukeaman vasemmanpuoleisen ja oikeanpuoleisen sivun ylätunnisteen
+teksti. Tämä komento on tarkoitettu suoritettavaksi päälukujen
+yhteydessä. Komennolla \komento{markright} määritellään pelkästään
+oikeanpuoleisen sivun teksti, ja komento on tarkoitettu suoritettavaksi
+aina alalukujen yhteydessä.
+
+\komentoi{markboth}
+\komentoi{markright}
+\begin{koodilohkosis}
+\markboth{vasen}{oikea} % määrittelee: \leftmark ja \rightmark
+\markright{oikea} % määrittelee: \rightmark
+\end{koodilohkosis}
+
+\noindent
+Sivunumeroinnin tyyliin voi vaikuttaa esimerkiksi komennolla
+\komento{pagenumbering}, jonka argumentiksi annetaan numerointityylin
+nimi. Ne on koottu taulukkoon \ref{tlk/sivu-numerointityylit}.
+
+\komentoi{pagenumbering}
+\begin{koodilohkosis}
+\pagenumbering{roman}
+\end{koodilohkosis}
+
+\noindent
+Edellä mainittu komento määrittelee käytännössä uudelleen komennon
+\komento{thepage}, joka on tarkoitettu juuri sivunumerolaskurin
+latomiseen. Lisätietoa sivunumeroista ja muista laskureista on luvussa
+\ref{luku/laskurit}.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\koodi{#1} & #2 \\}
+ \begin{tabular}{ll}
+ \toprule
+ \ots{Tyyli} & \ots{Merkitys} \\
+ \midrule
+ \rivi{arabic}{arabialaiset luvut: 1, 2, 3\dots}
+ \rivi{roman}{roomalaiset luvut: i, ii, iii\dots}
+ \rivi{Roman}{roomalaiset luvut: I, II, III\dots}
+ \rivi{alph}{kirjaimet: a, b, c\dots\ (vain 1--26)}
+ \rivi{Alph}{kirjaimet: A, B, C\dots\ (vain 1--26)}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Sivunumerointityylit \komento{pagenumbering}\-/ komennon
+ argumentiksi}
+ \label{tlk/sivu-numerointityylit}
+}
+
+Monipuolisemmin ylä- ja alatunnisteita voi muokata paketin
+\pakettictan{fancyhdr} toimintojen avulla. Silloin sivutyylinä voi olla
+myös \koodim{fancy}:
+
+\komentoi{usepackage}
+\komentoi{pagestyle}
+\begin{koodilohkosis}
+\usepackage{fancyhdr}
+\pagestyle{fancy}
+\end{koodilohkosis}
+
+\noindent
+Kun käytössä on sivutyyli \koodi{fancy}, voi ylä- ja alatunnisteiden
+sisällön asettaa vapaasti komennolla \komentom{fancyhf}. Komennon
+argumenttien merkitys on seuraavanlainen:
+
+\komentoi{fancyhf}
+\begin{koodilohkosis}
+\fancyhf[paikka]{sisältö}
+\end{koodilohkosis}
+
+\noindent
+Valinnainen argumentti \koodi{paikka} kertoo, mihin paikkaan tai
+paikkoihin \koodi{sisältö} sijoitetaan. Vaihtoehtoina on ylä- tai
+alatunniste, pariton tai parillinen sivu, sivun vasen reuna, keskiosa
+tai oikea reuna. Nämä vaihtoehdot ja niitä vastaavat valitsimet on
+koottu taulukkoon \ref{tlk/fancyhf-paikat}. Saman komennon avulla voi
+määrittää useitakin paikkoja, kun ne erottaa pilkulla, esimerkiksi
+seuraavalla tavalla:
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\koodi{#1} & #2 \\}
+ \begin{tabular}{cl}
+ \toprule
+ \ots{Valitsin} & \ots{Merkitys} \\
+ \midrule
+ \rivi{H}{ylätunniste (header)}
+ \rivi{F}{alatunniste (footer)}
+ \rivi{E}{parillinen sivu, vasen (even)}
+ \rivi{O}{pariton sivu, oikea (odd)}
+ \rivi{L}{sivun vasen reuna (left)}
+ \rivi{C}{sivun keskelle (center)}
+ \rivi{R}{sivun oikea reuna (right)}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{\komento{fancyhf}\-/ komennon valitsimia ylä- tai
+ alatunnisteen paikan määrittämiseen}
+ \label{tlk/fancyhf-paikat}
+}
+
+\komentoi{fancyhf}
+\begin{koodilohkosis}
+\fancyhf{} % Tyhjennetään ylä- ja alatunnisteet.
+\fancyhf[HEL,HOR]{\thepage}
+\end{koodilohkosis}
+
+\noindent
+Edellä mainittu komento sijoittaa sivunumeron (\komento{thepage})
+ylätunnisteeseen (\koodi{H}) parillisten sivujen (\koodi{E}) vasempaan
+reunaan (\koodi{L}) ja parittomien sivujen (\koodi{O}) oikeaan reunaan
+(\koodi{R}). Käytännössä siis aukeaman ulkoreunoihin ladotaan
+sivunumerot. Seuraava esimerkki sijoittaa ajatusviivoilla (\==)
+reunustetun sivunumeron kaikille sivuille alatunnisteeseen (\koodi{F})
+sivun keskelle (\koodi{C}):
+
+\komentoi{fancyhf}
+\komentoi{thepage}
+\begin{koodilohkosis}
+\fancyhf[FC]{-- \thepage\ --}
+\end{koodilohkosis}
+
+\noindent
+Paketin \paketti{fancyhdr} avulla voi myös määritellä Latexin
+sivutyylejä toisenlaiseksi tai luoda kokonaan omia sivutyylejä. Nämä
+tehdään komennolla \komentom{fancypagestyle}, jonka ensimmäinen
+argumentti on sivutyylin nimi ja toinen argumentti on sivutyylin
+määritelmä. Määritelmä sisältää tarvittavat \komento{fancyhf}\-/
+komennot, joilla ylä- ja alatunnisteet määritellään.
+
+Seuraava esimerkki tekee Latexin \koodi{plain}\-/ sivutyylistä saman
+kuin \koodi{fancy}\-/tyylin, eli sekin noudattaa \komento{fancyhf}\-/
+komennolla määriteltyjä ylä- ja alatunnisteita:
+
+\komentoi{fancypagestyle}
+\begin{koodilohkosis}
+\fancypagestyle{plain}{}
+\end{koodilohkosis}
+
+\noindent
+Seuraava esimerkki määrittelee kokonaan oman sivutyylin:
+
+\komentoi{fancypagestyle}
+\komentoi{fancyhf}
+\begin{koodilohkosis}
+\fancypagestyle{omatyyli}{
+ \fancyhf{}
+ \fancyhf[FEL,FOR]{\thepage}
+}
+\end{koodilohkosis}
+
+\noindent
+Ylä- ja alatunniste voidaan erottaa tekstipalstasta vaakasuuntaisella
+viivalla, jonka leveyttä on mahdollista muuttaa määrittelemällä
+uudelleen komennot \komentom{headrulewidth} ja \komentom{footrulewidth}.
+Komennon määritelmäksi kirjoitetaan Texin mitta. Seuraavassa esimerkissä
+asetetaan yhden typografisen pisteen (1\,bp) levyiset viivat. Mitan
+voisi asettaa myös nollaksi (0\,bp), jolloin erotinviiva katoaa kokonaan
+näkyvistä.
+
+\komentoi{renewcommand}
+\komentoi{headrulewidth}
+\komentoi{footrulewidth}
+\begin{koodilohkosis}
+\renewcommand{\headrulewidth}{1bp} % ylätunnisteen erotinviiva
+\renewcommand{\footrulewidth}{1bp} % alatunnisteen erotinviiva
+\end{koodilohkosis}
+
+\noindent
+Mikäli haluaa omiin ylätunnisteisiin esimerkiksi päälukujen ja
+alalukujen nimiä, täytyy tunnisteisiin sisällyttää aiemmin kuvatut
+\komentom{leftmark}- ja \komentom{rightmark}\-/komennot. Ensin mainittu
+sisältää pääluvun nimen ja jälkimmäinen alaluvun nimen.
+
+\komentoi{fancyhf}
+\komentoi{leftmark}
+\komentoi{rightmark}
+\begin{koodilohkosis}
+\fancyhf[HEL]{\leftmark}
+\fancyhf[HOR]{\rightmark}
+\end{koodilohkosis}
+
+\noindent
+Latex latoo pää- ja alalukujen nimet oletuksena versaalikirjaimilla eli
+isoilla kirjaimilla. Jos ne haluaa johonkin toiseen muotoon, täytyy itse
+määritellä uudelleen komennot \komentom{chaptermark},
+\komentom{sectionmark} tai \komentom{subsectionmark} (vain kaksi näistä)
+ja käyttää määritelmässä komentoja \komento{markboth} ja
+\komento{markright}. Esimerkkiin \ref{esim/fancyhdr-koko} on koottu
+varsin kokonaisvaltainen koodi omien ylä- ja alatunnisteiden
+toteutukseen.
+
+\begin{esimerkki*}
+ \komentoi{documentclass}
+ \luokkai{book}
+ \komentoi{usepackage}
+ \pakettii{fancyhdr}
+ \komentoi{fancypagestyle}
+ \komentoi{fancyhf}
+ \komentoi{renewcommand}
+ \komentoi{headrulewidth}
+ \komentoi{footrulewidth}
+ \komentoi{leftmark}
+ \komentoi{rightmark}
+ \komentoi{thepage}
+ \komentoi{pagestyle}
+ \komentoi{chaptermark}
+ \komentoi{markboth}
+ \komentoi{chaptername}
+ \komentoi{thechapter}
+ \komentoi{sectionmark}
+ \komentoi{thesection}
+
+\begin{koodilohko}
+\documentclass{book}
+\usepackage{fancyhdr}
+
+% Päälukujen (\chapter) aloitussivu käyttää plain-sivutyyliä.
+% Tässä määritellään se uudestaan.
+\fancypagestyle{plain}{
+ \fancyhf{}
+ \fancyhf[FC]{-- \thepage\ --}
+ \renewcommand{\headrulewidth}{0bp}
+ \renewcommand{\footrulewidth}{0bp}
+}
+
+% fancy-sivutyylin asetukset:
+\fancyhf{}
+\fancyhf[HEL]{\leftmark}
+\fancyhf[HOR]{\rightmark}
+\fancyhf[FC]{-- \thepage\ --}
+\renewcommand{\headrulewidth}{1bp}
+\renewcommand{\footrulewidth}{0bp}
+
+\begin{document}
+
+\pagestyle{fancy}
+
+% Päälukujen (\chapter) yhteydessä komento \markboth{…}{…} määrittää
+% sekä \leftmark- että \rightmark-komennot. Tässä jälkimmäinen
+% määritellään tyhjäksi.
+\renewcommand{\chaptermark}[1]{%
+ \markboth{\chaptername\ \thechapter: #1}{}}
+
+% Alalukujen (\section) yhteydessä komento \markright{…} määrittää
+% vain \rightmark-komennon.
+\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}}
+\end{koodilohko}
+ \caption{Omien ylä- ja alatunnisteiden toteuttaminen}
+ \label{esim/fancyhdr-koko}
+\end{esimerkki*}
+
+\section{Pdf-tiedosto}
+\label{luku/pdf-asetukset}
+
+Pdf-tiedostot voivat sisältää metatietoja kuten dokumentin nimen,
+aiheen, tekijän ja päiväyksen. Tiedostoille voi määrittää myös erilaisia
+asetuksia kuten ristiviitteiden ja linkkien ulkoasun tai sisäisen
+sisällysluettelon ominaisuuksia. Pdf\-/tiedoston asetukset toteutetaan
+\pakettictan{hyperref}\-/ paketin avulla. Paketti neuvotaan lataamaan
+muiden pakettien jälkeen, koska se lisää ominaisuuksia muihin
+komentoihin. Paketin voisi ladata esimerkiksi seuraavalla tavalla:
+
+\komentoi{usepackage}
+\pakettii{hyperref}
+\begin{koodilohkosis}
+% Muiden \usepackage-komentojen jälkeen.
+\usepackage[unicode]{hyperref}
+\end{koodilohkosis}
+
+\noindent
+Esimerkissä käytetty valitsin \koodi{unicode} aiheuttaa sen, että pdf\-/
+tiedoston sisäisissä merkkijonoissa käytetään Unicode\-/ merkistöä ja
+sen \textsc{utf\=/8}\-/ koodausta. Ilman tätä valitsinta Lualatex\-/
+kääntäjän kanssa pdf\-/ tiedoston sisäinen sisällysluettelon merkistö ei
+näy välttämättä oikein.
+
+\paketti{hyperref}\-/ paketin asetuksia voi määritellä valitsimien
+avulla \komento{usepackage}\-/ komennon yhteydessä mutta myös
+erillisellä \komentom{hypersetup}\-/ komennolla. Komennolle annetaan
+yksi argumentti, joka sisältää pilkuilla erotettuna erilaisia valitsimia
+ja niiden arvoja.
+
+\begin{esimerkki*}
+\begin{koodilohko}
+\hypersetup{
+ hidelinks, bookmarksopen, bookmarksnumbered,
+ pdfinfo={
+ Title={Laatikollinen lateksia},
+ Subject={Opas lateksiin ja liisteriin},
+ Author={Lauri Liisteri}
+ }
+}
+\end{koodilohko}
+ \caption{\komento{hypersetup}\-/ komennolla asetetaan
+ \paketti{hyperref}\-/ paketin asetuksia, esimerkiksi pdf:n
+ metatietoja}
+ \label{esim/hypersetup}
+\end{esimerkki*}
+
+Esimerkissä \ref{esim/hypersetup} valitsin \koodi{hidelinks} saa aikaan
+sen, että pdf:ssä olevia linkkejä ja ristiviitteitä ei merkitä millään
+tavalla. Oletuksena linkit kehystetään eri väreillä riippuen linkin
+tyypistä. Valitsin \koodi{bookmarksopen} näyttää pdf:n sisällysluettelon
+kokonaan avattuna. Oletuksena alaluvut on piilotettuna, ja ne joutuu
+avaamaan napsauttamalla hiirellä ylemmäntasoisen otsikon
+avauspainiketta. Valitsin \koodi{bookmarksnumbered} näyttää pdf:n
+sisällysluettelossa lukujen numeroinnin (kuten 1.1, 1.2, 2.1 tms.).
+Valitsimella \koodi{pdfinfo} määritellään pdf:n metatietoja kuten
+otsikko, aihe ja tekijä mutta omiakin metatietoja voi lisätä. Paljon
+muitakin asetuksia on olemassa, ja niistä voi lukea lisää
+\paketti{hyperref}\-/ paketin ohjekirjasta.
+
+Pdf\-/ tiedoston sisäiseen sisällysluetteloon tulevat automaattisesti
+mukaan samat otsikot (luku \ref{luku/otsikot}) kuin ladottavaan
+sisällysluetteloonkin (luku \ref{luku/sisällysluettelo}). Pdf\-/
+tiedoston luetteloon voi kuitenkin itse lisäillä omia otsikoita, jotka
+eivät näy missään muualla. Se tehdään \paketti{hyperref}\-/ paketin
+komennolla \komentom{pdfbookmark}:
+
+\komentoi{pdfbookmark}
+\begin{koodilohkosis}
+\pdfbookmark[taso]{Teksti}{tunniste}
+\end{koodilohkosis}
+
+\noindent
+Komennon valinnainen argumentti \koodi{taso} on kokonaisluku, joka
+tarkoittaa otsikon tasoa. Se on samankaltainen tasonumero kuin
+otsikkotasojen taulukossa \ref{tlk/otsikkotasot}
+(s.~\pageref{tlk/otsikkotasot}). Argumentti \koodi{Teksti} on pdf:n
+sisällysluettelomerkinnän teksti, ja \koodi{tunniste} on mikä tahansa
+yksilöllinen tekstimuotoinen tunniste kyseiselle luettelomerkinnälle.
+Tunniste ei näy missään, mutta pdf tarvitsee sisäiseen toimintaansa
+jonkin yksilöllisen tunnisteen.
+
+\section{Fontit}
+\label{luku/kirjaintyypit}
+
+Fontit ja niiden asettaminen on Latexissa melko monimutkainen
+kokonaisuus, koska fonteilla on paljon ominaisuuksia ja niihin
+vaikutetaan monilla eri asetuksilla ja abstraktiotasoilla. Aika monta
+asiaa pitää ymmärtää, jotta voi tehokkaasti työskennellä Latexin
+fonttien kanssa.
+
+Fontti jo itsessään on moniselitteinen käsite, joka vaatii typografiassa
+usein täsmentäviä ilmauksia. Sana \emph{fontti} voi tarkoittaa
+kokonaista kirjainperhettä eli yhteensopivien kirjainleikkausten
+muodostamaa kokonaisuutta. Samaan kirjainperheeseen kuuluu yleensä
+ainakin neljä eri leikkausta: tavallinen, \textit{kursiivi},
+\textbf{lihavoitu} ja \textbf{\textit{lihavoitu kursiivi}}. Joihinkin
+perheisiin kuuluu leikkauksia paljon enemmänkin, kuten useita eri
+vahvuuksia. Joissakin puheissa sana \emph{fontti} tarkoittaa vain yhtä
+kirjainleikkausta, ja silloin koko perheeseen viitataan ehkä sanalla
+fonttiperhe.
+
+Tässä oppaassa käytetään \emph{fontti}\-/sanaa yleisnimityksenä Latexin
+kirjaintyyppeihin liittyville asetuksille. Se tarkoittaa kirjainperhettä
+tai siihen kuuluvaa yksittäistä leikkausta sekä asetuksia, jotka
+liittyvät niihin. Silloin kun merkitystä pitää täsmentää, käytetään
+suomenkielisiä nimiä kirjainperhe ja kirjainleikkaus. Sen sijaan sana
+\emph{kirjasin} on jätetty kokonaan pois. Se tarkoittaa vanhassa
+metalliladonnassa ja mekaanisissa kirjoituskoneissa metallisen
+ladontakappaleen eli kirjakkeen päähän valettua kirjaimen tai muun
+merkin kohokuviota, joka painaa mustejäljen paperille.
+
+Kuten Latexissa yleensäkin myös fonttien kanssa kannattaa käyttää
+korkean abstraktiotason komentoja, jotka piilottavat yksityiskohdat ja
+teknisen toteutuksen. Latexin fonttitoiminnot on suunniteltu juuri
+siihen: matalan tason fonttiasetukset määritellään mieluiten vain kerran
+dokumentin esittelyosassa, ja sen jälkeen käytetään pelkästään korkean
+tason komentoja.
+
+Latexin fonttitekniikka rakentuu eri\-/ikäisistä kerroksista ja
+tekniikoista. Fontteja on aikoinaan tehty
+\englanti{Metafont}\avctan{metafont}\-/ nimisellä kielellä, jolla
+kuvataan merkkien muodot. \englanti{Metafont} on myös tietokoneohjelma,
+joka tuottaa kuvauskielen perusteella bittikarttafontteja eli
+pikseleistä koostuvia fontteja. On käytetty myös kehittyneempää
+\englanti{Metapost}\avctan{metapost}\-/ kuvauskieltä ja \=/ohjelmaa,
+joilla on tuotettu vektorigrafiikkafontteja \textsc{eps}- eli
+\englanti{Encapsulated Post Script} \=/muodossa ja muutettu niitä
+edelleen \englanti{Post Script Type~1} \=/fonteiksi. Myöhemmin mukaan
+ovat tulleet nykyaikaiset \englanti{True Type}- ja \englanti{Open Type}
+\=/fontit, ja niihin tämä opas keskittyy.
+
+\subsection{Fonttien määrittäminen}
+\label{luku/fontin-valinta}
+
+Latexin fonttien perustoiminnot rakentuvat kolmen erityyppisen
+kirjainperheen varaan:
+
+\begin{nluetelma}
+\item peruskirjainperhe eli dokumentin pääasiallinen kirjainperhe, joka
+ on kirjatypografiassa usein antiikva eli pääteviivallinen
+ (\englanti{serif, roman})%
+ \footnote{Antiikva (lat. \emph{antiquus} 'vanha') perustuu antiikin
+ Roomassa käytettyihin kirjainmuotoihin. Niissä on pääteviivat, ja
+ viivojen vahvuus vaihtelee.}
+\item groteski eli pääteviivaton (\englanti{sans serif, gothic})%
+ \footnote{Groteskiin (ransk. \emph{grotesque} 'kummallinen') kuuluu
+ pääteviivojen puuttumisen lisäksi lähes tasavahvuiset kirjainten
+ viivat. Tämän oppaan groteskifontissa on kuitenkin selvästi
+ antiikvamaiset kaksivahvuiset viivat, joten se on eräänlainen
+ antiikvan ja groteskin välimuoto.}
+\item tasalevyinen kirjoituskoneen kaltainen perhe
+ (\englanti{type\-writer, mono\-spaced, tele\-type}).
+\end{nluetelma}
+
+\noindent
+Kuvassa \ref{kuva/kirjainperhetyypit} ovat tässä oppaassa käytetyt kolme
+eri kirjainperhettä. Leipätekstissä käytetään antiikvaa, otsikoissa ja
+kuvateksteissä groteskia ja koodiesimerkeissä tasalevyistä.
+Kirjoituskoneen kaltainen tasalevyinen kirjainperhe on tässä tapauksessa
+tyypiltään antiikva eli pääteviivallinen, mutta se voisi olla muutakin.
+Tasalevyisyys on sen kirjainperheen tärkein määrittävä tekijä Latexin
+asetusten näkökulmasta.
+
+\leijukuva{
+ {\rmfamily\addfontfeatures{ScaleAgain=5}Amf}
+ \hfill
+ {\sffamily\addfontfeatures{Scale=5}Amf}
+ \hfill
+ {\ttfamily\addfontfeatures{FakeStretch=1, Scale=4.5}Amf}
+}{
+ \caption{Vasemmalla pääteviivallinen, keskellä pääteviivaton ja
+ oikealla tasalevyinen pääteviivallinen kirjainperhe}
+ \label{kuva/kirjainperhetyypit}
+}
+
+Joidenkin fonttien käyttöönottoon on tehty oma pakettinsa, joten
+sellaiset fontit voi ladata dokumentin esittelyosassa komennolla
+\komento{usepackage}. Fonttikohtaisia paketteja on olemassa
+varsinkin vanhalle fonttitekniikalle (\englanti{Metafont, Post Script
+ Type~1}) mutta myös matematiikkatilan fonttiasetuksille (luku
+\ref{luku/matematiikka-fontit}) ja joillekin
+kir\-jain\-perhe\-koko\-nai\-suuk\-sille.
+
+Latexissa pisimmälle ''tuotteistettu'' kokonaisuus taitaa olla
+Libertinus\-/ kirjainperhe, joka sisältää antiikvan, groteskin ja
+tasalevyisen kirjainperheen sekä matematiikkatilan symboleita.
+Libertinus\-/ kirjainperheet saa käyttöön lataamalla paketti
+\pakettictan{libertinus}:
+
+\komentoi{usepackage}
+\pakettii{libertinus}
+\begin{koodilohkosis}
+\usepackage{libertinus}
+\end{koodilohkosis}
+
+\noindent
+Valmiita paketteja on kuitenkin vain harvoille fonteille, ja
+käytännössä lähes aina \englanti{True Type}- ja \englanti{Open Type}
+\=/muodossa olevat fontit otetaan käyttöön \paketti{fontspec}\-/paketin
+komennoilla seuraavan esimerkin mukaisesti:
+
+\komentoi{setmainfont}
+\komentoi{setsansfont}
+\komentoi{setmonofont}
+\begin{koodilohkosis}
+\setmainfont{TeX Gyre Termes}[Scale=1]
+\setsansfont{TeX Gyre Heros} [Scale=MatchLowercase]
+\setmonofont{TeX Gyre Cursor}[Scale=MatchLowercase]
+\end{koodilohkosis}
+
+\noindent
+Edellisessä esimerkissä \englanti{TeX Gyre Termes, Heros} ja
+\englanti{Cursor} ovat kirjainperheiden nimiä. Fonttitiedostojen
+tulee olla asennettuna käyttöjärjestelmän normaalien käytäntöjen
+mukaisesti tai Latex\-/jakelun käytäntöjen mukaisesti.
+
+Kirjainperheiden käyttöönoton yhteydessä voi määritellä lukuisia
+asetuksia kuten ligatuureja, gemenanumeroita, optisia kokoja ja muita
+fontin ominaisuuksia. Edellisessä esimerkissä käytetään vain
+\koodi{Scale}\-/ valitsinta, jolla fontin voi skaalata haluttuun kokoon.
+
+Peruskirjainperheen (\komentom{setmainfont}) skaalaukseksi asetetaan
+\koodi{Scale=1}, eli sille ei tehdä mitään, ja koko valitsimen voisi
+jättää pois. Sen sijaan kahdella muulla kirjainperheellä
+(\komentom{setsansfont}, \komentom{setmonofont}) käytetään
+kerroinasetusta \koodi{MatchLowercase}, joka skaalaa fontin siten, että
+gemenakirjaimet eli pienet kirjaimet ovat yhtä korkeita kuin
+peruskirjainperheessä. Mikäli skaalausasetus \koodi{MatchLowercase} ei
+tuota ihan toivottua tulosta, voi kirjainperheen skaalausta hienosäätää
+vielä \koodi{Scale\-Again}\-/ valitsimella seuraavalla tavalla:
+
+\komentoi{setmonofont}
+\begin{koodilohkosis}
+\setmonofont{TeX Gyre Cursor}
+[Scale=MatchLowercase, ScaleAgain=.97]
+\end{koodilohkosis}
+
+\noindent
+Kirjainperheen määrittelyn yhteydessä ei yleensä tarvitse antaa kuin
+kirjainperheen nimi, sillä \paketti{fontspec}\-/paketti ja kääntäjät
+osaavat automaattisesti ladata perheeseen sisältyviä eri
+fonttitiedostoja kuten pystyasentoisen leikkauksen, kursiivin ja
+lihavoinnin. On kuitenkin mahdollista määritellä kirjainperheeseen
+kuuluvia leikkausten nimiä tai fonttitiedostoja erikseen. Tällainen on
+tarpeen esimerkiksi silloin, kun kirjainperhe sisältää useita eri
+vahvuuksia ja halutaan itse määritellä, mikä niistä tulee
+perusvahvuudeksi ja mikä lihavoiduksi.
+
+Esimerkki \ref{esim/fontit-leik-omin} selventää, kuinka kirjainperheen
+eri leikkausten nimet tai fonttitiedostot määritellään. Kullekin
+leikkaukselle voi määrittää myös omat asetuksensa \koodi{Fea\-tures}\-/
+loppuisella valitsimella. Samaa asiaa havainnollistetaan myös
+konkreettisemmin esimerkissä \ref{esim/fontit-leik-omin-käyt}.
+Leikkauksen nimessä voi käyttää tähteä (\koodi{*}), joka korvautuu
+kirjainperheen nimellä (\englanti{Macklin Text}).
+
+\begin{esimerkki*}
+ \komentoi{setmainfont}
+\begin{koodilohko}
+\setmainfont{…}[
+ UprightFont={…}, UprightFeatures={…},
+ ItalicFont={…}, ItalicFeatures={…},
+ BoldFont={…}, BoldFeatures={…},
+ BoldItalicFont={…}, BoldItalicFeatures={…},
+ SlantedFont={…}, SlantedFeatures={…},
+ BoldSlantedFont={…}, BoldSlantedFeatures={…},
+ SmallCapsFont={…}, SmallCapsFeatures={…}]
+\end{koodilohko}
+ \caption{Kirjainperheeseen sisältyvien leikkausten nimien ja
+ kirjainleikkauskohtaisten ominaisuuksien määrittely}
+ \label{esim/fontit-leik-omin}
+\end{esimerkki*}
+
+\begin{esimerkki*}
+ \komentoi{setmainfont}
+\begin{koodilohko}
+\setmainfont{Macklin Text}[
+ UprightFont = {* Light},
+ ItalicFont = {* Light Italic},
+ BoldFont = {* Medium},
+ BoldItalicFont = {* Medium Italic}]
+\end{koodilohko}
+ \caption{Eri leikkausten nimien määrittely \englanti{Macklin Text}
+ \=/kirjainperheelle. Leikkauksen nimessä tähti (\koodi{*}) korvautuu
+ automaattisesti koko perheen nimellä}
+ \label{esim/fontit-leik-omin-käyt}
+\end{esimerkki*}
+
+Jos edellä kuvatut kolme kirjainperhettä (\komento{setmainfont},
+\komento{setsansfont} ja \komento{setmonofont}) eivät riitä, on
+\paketti{fontspec}\-/paketissa komennot lisäperheiden ja \=/leikkausten
+määrittämiseen. Uusi perhe määritellään seu\-raa\-vasti:
+
+\komentoi{newfontfamily}
+\begin{koodilohkosis}
+\newfontfamily{\hienoperhe}{TeX Gyre Schola}[…]
+\end{koodilohkosis}
+
+\noindent
+Komento \komento{newfontfamily} toimii samalla tavalla kuin aiemmin
+esitellyt \komento{setmainfont} ym. komennot, mutta lisäksi
+ensimmäisellä argumentilla nimetään komento, jolla kirjainperhe otetaan
+käyttöön. Edellisessä esimerkissä luodaan komento
+\komentox{hieno\-perhe}, joka kytkee päälle \englanti{TeX Gyre Schola}
+\=/nimisen kirjainperheen.
+
+Jos ei tarvita kokonaista perhettä vaan yksi leikkaus riittää, käytetään
+komentoa \komento{newfontface}. Seuraavassa esimerkissä määriteltävä
+komento \komentox{hieno\-leikkaus} ottaa käyttöön lihavoidun (bold)
+kirjainleikkauksen perheestä \englanti{TeX Gyre Schola}.
+
+\komentoi{newfontface}
+\begin{koodilohkosis}
+\newfontface{\hienoleikkaus}{TeX Gyre Schola Bold}[…]
+\end{koodilohkosis}
+
+\subsection{Fontin koko ja rivikorkeus}
+
+Fonttien koot on tapana valita ja ilmaista typografisen pistemitan
+avulla. Esimerkiksi 10--12 pistettä on tyypillinen leipätekstin
+oletuskoko tekstinkäsittelyohjelmissa. Piste on typografiassa
+mittayksikkö, jonka pituus on määritelty eri tavoin eri aikoina ja eri
+kulttuureissa.
+
+Myös Latexissa fonttien koot voi määritellä pistemittojen avulla. Niitä
+ja muitakin Latexin mittayksiköitä käsitellään tarkemmin luvussa
+\ref{luku/mitat}. Fonteissa oletusmittayksikkönä on vanha
+pica\-/järjestelmän piste, jonka pituus on noin 0,3515 millimetriä. Sen
+lyhenne Latexissa on~\emph{pt}. Tämän oppaan esimerkeissä käytetään
+kuitenkin Post Script \=/standardin mukaista, julkaisuohjelmiin
+vakiintunutta uudempaa pica\-/pistettä, joka on hieman edellistä
+pidempi: noin 0,3528 millimetriä. Latexissa sen lyhenne on~\emph{bp}.
+Ero näiden kahden pistemitan välillä on hyvin pieni, tavallisilla
+fonttiko'oilla käytännössä merkityksetön.
+
+Kirjainleikkauksen koko mitataan merkistön ylimmän ja alimman kohdan
+välillä, esimerkiksi k\=/kirjaimen ylimmän pisteen ja y\=/kirjaimen
+alimman pisteen välillä. Lisäksi mittaan luetaan mukaan merkistön ylä-
+ja alapuolella oleva pieni tyhjä tila, jonka fontin suunnittelija on
+määritellyt.
+
+Matalalla tasolla fonttien kokoon vaikuttaa Latexissa eräs yllättävä
+asia. Nimittäin dokumenttiluokalle (luku \ref{luku/dokumenttiluokat})
+voi antaa valitsimen, jolla fontin koko asetetaan. Vaihtoehtoja on
+Latexin normaaleissa dokumenttiluokissa vain kolme: \koodi{10pt}
+(oletus), \koodi{11pt} ja \koodi{12pt}. Dokumenttiluokan kokoasetus
+vaikuttaa myös sivun marginaaleihin, koska Latex pyrkii pitämään rivin
+merkkimäärän lukijalle sopivana: yhdelle riville ei kannata latoa ihan
+mahdottomasti merkkejä, koska rivin seuraaminen vaatii enemmän
+keskittymistä.
+
+Fontin koon määrittäminen dokumenttiluokan valitsimella ehkä kuuluu jo
+vähän menneisyyteen, mutta voi sitä edelleen käyttää, jos se riittää ja
+sillä saa halutun lopputuloksen. Yleensä lienee järkevää jättää
+dokumenttiluokan fonttiasetus oletukseksi (\koodi{10pt}) ja käyttää koon
+asettamiseen luvuissa \ref{luku/fontti-suhteellinen} ja
+\ref{luku/fontti-absoluuttinen} kerrottuja tapoja. Sivun marginaalien ja
+muiden mittojen määrittämiseen on ohjeita luvussa
+\ref{luku/sivuasetukset}.
+
+Fonttiasetuksiin kuuluu fontin koon lisäksi toinenkin mitta: rivikorkeus
+(\mitta{baselineskip}). Se on peräkkäisten rivien peruslinjojen välinen
+etäisyys. Fontin koko ja rivikorkeus määritellään samanaikaisesti, koska
+ne ovat saman \komentom{fontsize}\-/ komennon argumentteja. Esimerkki:
+
+\komentoi{fontsize}
+\komentoi{selectfont}
+\begin{koodilohkosis}
+\fontsize{10bp}{12bp} \selectfont
+\end{koodilohkosis}
+
+\noindent
+Ensimmäinen argumentti on fontin kokomitta ja toinen on rivikorkeus.
+Mittayksiköt voivat olla mitä tahansa Texin mittoja, ja oletuksena
+käytetään pt\-/pistemittaa, jos yksikköä ei ole mainittu. Komento
+\komentom{selectfont} on mukana, koska vasta sen myötä matalan tason
+fonttikomennot tulevat voimaan. Korkean tason fonttikomennot (luku
+\ref{luku/fontit-korkea}) suorittavat sen automaattisesti.
+
+Rivikorkeus on vähintään sama kuin fontin koko, mutta yleensä se
+asetetaan pari pistettä suuremmaksi, jotta rivit eivät olisi liian
+lähellä toisiaan. Esimerkissä \ref{esim/rivikorkeus} on kaksi erilaista
+\komento{fontsize}\-/komentoa ja ladottu lopputulos.
+
+\begin{esimerkki*}
+ \komentoi{fontsize}
+ \komentoi{selectfont}
+
+\begin{koodilohko}
+\fontsize{8bp}{11bp}\selectfont Tässä on pienehkö leipätekstin
+fonttikoko ja suhteellisen suuri rivikorkeus. Pitkät rivit vaativat
+suuremman rivikorkeuden kuin lyhyet rivit.
+
+\fontsize{16bp}{17bp}\selectfont Tässä on melko suuri fontti ja
+suhteellisen pieni rivikorkeus. Suuri fontti ja lyhyet rivit eivät
+tarvitse kovin suurta rivikorkeutta.
+\end{koodilohko}
+ \begin{tulos}
+ \fontsize{8bp}{11bp}\selectfont Tässä on pienehkö leipätekstin
+ fonttikoko ja suhteellisen suuri rivikorkeus. Pitkät rivit vaativat
+ suuremman rivikorkeuden kuin lyhyet rivit.
+
+ \fontsize{16bp}{17bp}\selectfont Tässä on melko suuri fontti ja
+ suhteellisen pieni rivikorkeus. Suuri fontti ja lyhyet rivit eivät
+ tarvitse kovin suurta rivikorkeutta.
+ \end{tulos}
+ \caption{Fontin koon ja rivikorkeuden asettaminen ja vaikutus}
+ \label{esim/rivikorkeus}
+\end{esimerkki*}
+
+Toinen tekstirivien peruslinjojen väliseen etäisyyteen vaikuttava asetus
+on \komento{baselinestretch}. Se on desimaalilukukerroin, jolla nykyinen
+rivikorkeus kerrotaan. Kerroin asetetaan helpoimmin komennolla
+\komento{linespread}.\footnote{Toinen tapa: \koodi{\keno
+ renewcommand\{\keno baselinestretch\}\{kerroin\}}}
+
+\komentoi{fontsize}
+\komentoi{linespread}
+\komentoi{selectfont}
+\begin{koodilohkosis}
+\fontsize{10bp}{12bp} \linespread{1.3} \selectfont
+\end{koodilohkosis}
+
+\noindent
+Edellä oleva esimerkki asettaa fontin kooksi 10 pistettä ja
+rivikorkeudeksi 12 pistettä. \komento{linespread}\-/ komennolla asetetun
+kertoimen vuoksi rivien peruslinjojen väliseksi etäisyydeksi tulee
+lopulta 1,3 kertaa 12 pistettä eli 15,6 pistettä. Ei ole väliä, kummassa
+järjestyksessä \komento{fontsize}- ja \komento{linespread}\-/ komennot
+annetaan. Asetukset tulevat voimaan vasta \komento{selectfont}\-/
+komennon jälkeen.
+
+Käytännössä \komento{linespread} sopii rivikorkeuden yleistason
+hienosäätöön esimerkiksi dokumentin esittelyosassa. Tilannekohtainen
+rivikorkeus on parasta asettaa \komento{fontsize}\-/komennolla.
+
+\subsection{Kirjainperheen ja -leikkauksen valitseminen}
+\label{luku/fontit-korkea}
+
+Latexissa on joukko korkean tason fonttikomentoja, jotka on tarkoitettu
+käytettäväksi sen jälkeen, kun matalan tason asetukset on kerran
+määritetty. Taulukossa \ref{tlk/fonttimallikomennot} on komennot
+kirjainperheen ja kirjainleikkauksen valintaan. Joka rivillä ensin
+mainittu komento (esim. \komento{rmfamily}) vaikuttaa tekstiin, joka
+tulee komennon jälkeen. Vaikutusalue rajoittuu nykyisen ympäristön (luku
+\ref{luku/ympäristöt}) sisään tai aaltosulkeilla (luku
+\ref{luku/aaltosulkeet}) rajatun alueen sisään. Rivillä toisena olevalle
+komennolle (esim. \komentox{textrm}) annetaan yksi argumentti, ja
+komennon vaikutus koskee vain argumenttina olevaa tekstiä.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[4]{%
+ \komento{#1} & \komento{#2}\komentoarg{\dots} & #3 & #4 \\}
+ \begin{tabular}{llll}
+ \toprule
+ \multicolumn{2}{l}{\ots{Komento}}
+ & \multicolumn{2}{l}{\ots{Merkitys}} \\
+
+ \midrule
+ \rivi {rmfamily} {textrm} {\rmfamily perhe}
+ {perus, yl. antiikva, serif, roman}
+ \rivi {sffamily} {textsf} {\sffamily perhe}
+ {groteski, sans serif, gothic}
+ \rivi {ttfamily} {texttt} {\ttfamily perhe}
+ {tasalevyinen, typewriter}
+
+ \midrule
+ \rivi {mdseries} {textmd} {\mdseries leikkaus}
+ {tavallinen vahvuus, medium}
+ \rivi {bfseries} {textbf} {\bfseries leikkaus}
+ {lihavoitu, bold}
+
+ \midrule
+ \rivi {upshape} {textup} {\upshape leikkaus}
+ {pystyasento, tavallinen}
+ \rivi {itshape} {textit} {\itshape leikkaus}
+ {kursiivi, italic}
+ \rivi {slshape} {textsl} {\slshape leikkaus}
+ {kalteva, slanted, oblique}
+ \rivi {scshape} {textsc} {\scshape leikkaus}
+ {pienversaali, kapiteeli, small caps}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Komennot kirjainperheen ja kirjainleikkauksen valintaan.
+ Perustila on \komento{rmfamily}, \komento{mdseries} ja
+ \komento{upshape}}
+ \label{tlk/fonttimallikomennot}
+}
+
+Taulukossa on ensimmäisillä riveillä kirjainperhekomennot (3\,kpl),
+jotka vaihtavat koko perheen kaikkine leikkauksineen. Niiden jälkeen
+tulevat kirjainleikkauskomennot, jotka valitsevat toisen leikkauksen
+samasta perheestä. Kirjainleikkauksen asetukset jaetaan kahteen ryhmään:
+\englantik{series} 'sarja' ja \englantik{shape} 'muoto'. Kummastakin
+ryhmästä on valittuna aina yksi ominaisuus, eli samanaikaisesti voi olla
+voimassa esimerkiksi \komento{bfseries} (\textbf{lihavoitu}) ja
+\komento{itshape} (\textit{kursiivi}), ja tuloksena on \textbf{\itshape
+ lihavoitua kursiivia}.
+
+Useimmissa fonteissa kursiivileikkaus (\komento{itshape}) ja kalteva
+leikkaus (\komento{slshape}) tuottavat saman lopputuloksen, mutta
+käsitteellisesti ne ovat eri asia. Kursiivi on aina muodoltaan erilainen
+leikkaus, joka hieman mukailee käsialakirjoitusta, joskaan kirjaimia ei
+ole sidottu toisiinsa. Sen sijaan kalteva leikkaus on tavallisen eli
+pystyasentoisen leikkauksen kallistettu versio. Kallistus voi olla
+kirjainmuotoilijan piirtämä leikkaus, tai kallistus on voitu toteuttaa
+mekaanisesti. Kallistuksen voi tehdä myös Latexissa (luku
+\ref{luku/fontit-venytys}).
+
+Komennot fontin koon valintaan ovat taulukossa
+\ref{tlk/fonttikokokomennot}. Taulukko kertoo myös, mitä fontin
+pistekokoa (pt) mikäkin komento tarkoittaa oletuksena. Oletus riippuu
+Latexin dokumenttiluokkien (luku \ref{luku/perusdokumenttiluokat})
+fonttikokovalitsimista \koodi{10pt}, \koodi{11pt} ja \koodi{12pt}.
+
+\leijutlk{
+ \begin{tabular}{lr@{}lr@{}lr@{}l}
+ \toprule
+ \ots{Komento}
+ & \multicolumn{2}{c}{\ots{10pt}}
+ & \multicolumn{2}{c}{\ots{11pt}}
+ & \multicolumn{2}{c}{\ots{12pt}} \\
+ \midrule
+ \komento{tiny} & 5 && 6 && 6 \\
+ \komento{scriptsize} & 7 && 8 && 8 \\
+ \komento{footnotesize} & 8 && 9 && 10 \\
+ \komento{small} & 9 && 10 && 10&,95 \\
+ \komento{normalsize} & 10 && 10&,95 & 12 \\
+ \komento{large} & 12 && 12 && 14&,4 \\
+ \komento{Large} & 14&,4 & 14&,4 & 17&,28 \\
+ \komento{LARGE} & 17&,28 & 17&,28 & 20&,74 \\
+ \komento{huge} & 20&,74 & 20&,74 & 24&,88 \\
+ \komento{Huge} & 24&,88 & 24&,88 & 24&,88 \\
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Fonttien oletuspistekoot dokumenttiluokkien valitsimilla
+ \koodi{10pt}, \koodi{11pt} ja \koodi{12pt}}
+ \label{tlk/fonttikokokomennot}
+}
+
+\ymparistoi{rmfamily}
+\ymparistoi{sffamily}
+\ymparistoi{ttfamily}
+\ymparistoi{mdseries}
+\ymparistoi{bfseries}
+\ymparistoi{upshape}
+\ymparistoi{itshape}
+\ymparistoi{slshape}
+\ymparistoi{scshape}
+\ymparistoi{tiny}
+\ymparistoi{scriptsize}
+\ymparistoi{footnotesize}
+\ymparistoi{small}
+\ymparistoi{normalsize}
+\ymparistoi{large}
+\ymparistoi{Large}
+\ymparistoi{LARGE}
+\ymparistoi{huge}
+\ymparistoi{Huge}%
+
+Kaikille korkean tason fonttikomennoille on olemassa myös samanniminen
+ympäristönsä, esimerkiksi \ymparisto{rmfamily}, \ymparisto{bfseries},
+\ymparisto{itshape} tai \ymparisto{small}. Seuraavassa esimerkissä on
+kaksi fontteihin vaikuttavaa ympäristöä sisäkkäin.
+
+\ymparistoi{footnotesize}
+\ymparistoi{scshape}
+\begin{koodilohkosis}
+\begin{footnotesize}
+ \begin{scshape}
+ Tämä teksti on pientä pienversaalia.
+ \end{scshape}
+\end{footnotesize}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \begin{footnotesize}
+ \begin{scshape}
+ Tämä teksti on pientä pienversaalia.
+ \end{scshape}
+ \end{footnotesize}
+\end{tulossis}
+
+\subsection{Fonttikoon määrittely suhteellisesti}
+\label{luku/fontti-suhteellinen}
+
+Dokumentin fonttien koot on helpointa määrittää siten, että asettaa
+ensin peruskirjainperheen koon ja antaa muiden fonttien määräytyä
+suhteessa siihen. Esimerkki \ref{esim/fontti-suhteellinen} selventää,
+kuinka se tapahtuu. Alussa otetaan käyttöön dokumenttiluokka
+\luokka{article} ja annetaan sille valitsin \koodi{10pt}, joka määrittää
+fonttikooksi 10 pistettä. Se on dokumenttiluokan oletusasetus, jota ei
+tarvitsisi edes kirjoittaa näkyviin. Esimerkin toisella rivillä otetaan
+\paketti{fontspec}\-/paketti käyttöön.
+
+Peruskirjainperheen (rivi~4) koko skaalataan 1,4\-/kertaiseksi, eli
+pistekooksi tulee 1,4 kertaa 10 pistettä eli 14 pistettä (pt).
+Normaalikokoinen peruskirjainperhe on ainoa, jonka pistekoko tiedetään.
+Kaikkien muiden koot täytyisi selvittää laskemalla.
+
+Groteski eli pääteviivaton kirjainperhe (rivi~5) ja tasalevyinen perhe
+(rivi~6) skaalataan samankorkuiseksi kuin perusperhe. Vertailukohtana
+ovat gemenat eli pienaakkoset (\koodi{MatchLowercase}). Näiden kahden
+kirjainperheen pistekokoa ei tiedetä. Se ei välttämättä ole sama kuin
+perusfontissa, koska fonttien pistekoko mitataan ylimmän ja alimman
+kohdan välillä ja koska fonttien mittasuhteet ovat erilaisia.
+
+\begin{esimerkki*}
+ \komentoi{documentclass}
+ \komentoi{usepackage}
+ \pakettii{fontspec}
+ \komentoi{setmainfont}
+ \komentoi{setsansfont}
+ \komentoi{setmonofont}
+ \komentoi{linespread}
+ \luokkai{article}
+
+\begin{koodilohko}
+\documentclass[10pt]{article} % 10pt on oletus
+\usepackage{fontspec}
+
+\setmainfont{TeX Gyre Termes}[Scale=1.4]
+\setsansfont{TeX Gyre Heros} [Scale=MatchLowercase]
+\setmonofont{TeX Gyre Cursor}[Scale=MatchLowercase]
+\linespread{1.45}
+\end{koodilohko}
+ \caption{Fonttikokojen määrittäminen suhteessa peruskirjainperheeseen}
+ \label{esim/fontti-suhteellinen}
+\end{esimerkki*}
+
+Viimeisellä rivillä oleva \komento{linespread}\-/ komento on tärkeä. Se
+asettaa rivikorkeuden kertoimeksi 1,45. Kertoimen täytyy olla vähintään
+yhtä suuri kuin peruskirjainperheen skaalauskerroin (1,4), jotta
+rivivälit ovat riittävän suuret. Näiden asetusten jälkeen dokumentissa
+käytetään korkeamman tason komentoja fonttien valintaan, esimerkiksi
+fonttikoon valintakomentoja \komento{small}, \komento{normalsize},
+\komento{large} (taulukko \ref{tlk/fonttikokokomennot}).
+
+Edellä kuvatussa suhteellisessa kirjainperheiden koon määrittelyssä on
+sellainen ongelma tai kummallisuus, että Latex koko ajan luulee, että
+peruskirjainperhe on normaalikokoisena 10 pistettä (pt). Latexin matalan
+tason fonttikomennot eivät tiedä kirjainperheen skaalauskertoimesta, ja
+siksi esimerkiksi komentojen
+
+\komentoi{fontsize}
+\komentoi{selectfont}
+\begin{koodilohkosis}
+\fontsize{10bp}{12bp} \selectfont
+\end{koodilohkosis}
+
+\noindent
+tuloksena ei todellisuudessa ole 10 pisteen (bp) fontti, vaan mukaan
+lasketaan myös kirjainperheen skaalauskerroin. Tämän vuoksi
+\komento{fontsize}\-/ komennon käyttö menee aika oudoksi. Argumenttina
+annettu kokomitta ei pidä paikkaansa.
+
+Jos korkean tason fonttikokokomentojen (taulukko
+\ref{tlk/fonttikokokomennot}) lisäksi tarvitaan jotakin muuta kokoa,
+voisi mahdollisesti \komento{fontsize}\-/ komennon sijasta käyttää
+\paketti{fontspec}\-/paketin tarjoamaa komentoa ja tilanteeseen sopivaa
+skaalauskerrointa esimerkiksi seuraavalla tavalla:
+
+\komentomargin{addfontfeatures}
+\komentoi{addfontfeatures}
+\begin{koodilohkosis}
+{\addfontfeatures{Scale=3.2} Poikkeuksellisen isoa tekstiä}
+\end{koodilohkosis}
+
+\noindent
+Jos edellä mainitut kummallisuudet eivät häiritse eikä ole tarvetta
+määritellä fontteja tarkasti tietyn pistekoon mukaiseksi, on
+suhteellinen määrittelytapa todella helppo. Kaikki dokumentin fontit
+määräytyvät perusfontin skaalauskertoimen kautta. Tämä tapa sopii hyvin
+varsinkin dokumentin sisällön kirjoittamisvaiheeseen, jossa ehkä
+halutaan vain nopeasti asettaa dokumentti suurin piirtein järkevän
+näköiseksi. Myöhemmin voi määrittää koot tarkemmin niin sanotun
+absoluuttisen menetelmän avulla, jota käsitellään seuraavassa
+alaluvussa.
+
+\subsection{Fonttikoon määrittely absoluuttisesti}
+\label{luku/fontti-absoluuttinen}
+
+Absoluuttinen fonttien koonmääritystapa tarkoittaa sitä, että koot
+asetetaan tietyn kokoiseksi käyttämällä esimerkiksi pistemittoja ja että
+kirjaimet myös päätyvät lopulliseen dokumenttiin juuri sen kokoisena.
+Tämä tapa on myös teknisesti eheä, eli Latexin eri osat ovat samaa
+mieltä siitä, minkäkokoisesta fontista on kyse. Näin ei ollut
+suhteellisen tavan kanssa (luku \ref{luku/fontti-suhteellinen}).
+
+Joskus oppilaitoksen, yhtiön tai muun julkaisijan ohjeissa määritellään
+tarkasti, mitä fontteja käytetään ja mikä on leipätekstin ja otsikoiden
+fonttikoko. Silloin tarvitaan tässä luvussa kuvattua tapaa fonttien
+asettamiseen.
+
+\begin{esimerkki*}
+ \komentoi{documentclass}
+ \komentoi{usepackage}
+ \pakettii{fontspec}
+ \komentoi{setmainfont}
+ \komentoi{setsansfont}
+ \komentoi{setmonofont}
+ \komentoi{newfontfamily}
+ \komentoi{linespread}
+ \komentoi{renewcommand}
+ \komentoi{footnotesize}
+ \komentoi{small}
+ \komentoi{normalsize}
+ \komentoi{large}
+ \komentoi{Large}
+
+\begin{koodilohko}
+\documentclass{article}
+\usepackage{fontspec}
+
+% Leipätekstiin samankokoiset fontit
+\setmainfont{TeX Gyre Termes}
+\setsansfont{TeX Gyre Heros} [Scale=MatchLowercase]
+\setmonofont{TeX Gyre Cursor}[Scale=MatchLowercase]
+
+% Muualle sans ja mono ilman skaalausta
+\newfontfamily{\sffamilyabs}{TeX Gyre Heros}
+\newfontfamily{\ttfamilyabs}{TeX Gyre Cursor}
+
+\linespread{1} % ei välttämättä tarvita
+
+% Kaikki tarvittavat fonttikoot ja komennot
+\renewcommand{\footnotesize}{\fontsize{10bp}{12bp}\selectfont}
+\renewcommand{\small} {\fontsize{12bp}{14bp}\selectfont}
+\renewcommand{\normalsize} {\fontsize{14bp}{17bp}\selectfont}
+\renewcommand{\large} {\fontsize{17bp}{19bp}\selectfont}
+\renewcommand{\Large} {\fontsize{20bp}{22bp}\selectfont}
+
+\normalsize % jotta tulee heti voimaan eikä vasta tekstiosassa
+\end{koodilohko}
+ \caption{Fonttikokojen määrittäminen pistekoon avulla}
+ \label{esim/fontti-absoluuttinen}
+\end{esimerkki*}
+
+Esimerkistä \ref{esim/fontti-absoluuttinen} selviää perusajatus.
+Peruskirjainperhe (rivi~5) otetaan käyttöön ilman skaalausta
+(\koodi{Scale=1}), minkä vuoksi koon voi jatkossa asettaa täsmälleen
+kohdalleen \komento{fontsize}\-/komennolla. Samaa ei tehdä groteskin
+eikä tasalevyisen fontin kanssa (rivit 6--7), vaan käytetään skaalausta
+\koodi{MatchLowercase}, jotta tekstikappaleessa kaikki kirjainperheet
+näyttävät samankokoisilta. Tässä menetetään mahdollisuus määrittää
+näiden kirjainperheiden koko täsmällisesti pistemitan avulla. Jos siihen
+on tarvetta esimerkiksi otsikoissa, voidaan käyttää rivien 10--11
+komentoja. Niillä luodaan uudet kirjainperheet, jotka ovat käytännössä
+samoja mutta ilman skaalausta.
+
+Uusien skaalaamattomien kirjainperheiden komentojen nimiksi on valittu
+\komentox{sf\-fam\-i\-ly\-abs} ja \komentox{tt\-fam\-i\-ly\-abs} (vrt.
+\komento{sffamily} ja \komento{ttfamily}, taulukko
+\ref{tlk/fonttimallikomennot}), ja näillä komennoilla kirjainperheet
+kytketään päälle. Jos esimerkiksi jonkin julkaisun vaatimuksiin kuuluu,
+että otsikossa täytyy olla 20 pisteen lihavoitu TeX Gyre Heros
+\=/kirjainleikkaus, voi esimerkissä \ref{esim/fontti-absoluuttinen}
+olevien asetusten pohjalta antaa otsikon ulkoasun (luku
+\ref{luku/otsikot-ulkoasu}) määrittelyn yhteydessä seuraavat komennot:
+
+\komentoi{Large}
+\komentoi{bfseries}
+\begin{koodilohkosis}
+\sffamilyabs\Large\bfseries
+\end{koodilohkosis}
+
+\noindent
+Esimerkin \ref{esim/fontti-absoluuttinen} riveillä 16--20 määritellään
+uudelleen Latexin korkean tason komennot, joilla fonttikoot asetetaan.
+Oletusarvot tulevat dokumenttiluokasta (luku
+\ref{luku/dokumenttiluokat}), mutta jos ne eivät ole sopivia, täytyy
+vähintäänkin määritellä komento \komento{normalsize} mutta sen lisäksi
+kaikki ne koot, joita omassa dokumentissa tarvitaan. Tässä esimerkissä
+normaali koko asetetaan 14 pisteen kokoiseksi.
+
+Jokaiselle fonttikoolle määritetään riveillä 16--20 myös oma
+rivikorkeus, ja se on tarkoitus asettaa sopivaksi juuri kyseiselle
+koolle. Rivikorkeuteen vaikuttaa myös kerroin \komento{baselinestretch},
+joka asetetaan komennolla \komento{linespread}. Sitä ei välttämättä
+tarvitse käyttää, koska kirjainperheitä ei ole skaalattu ja koska
+rivikorkeus asetetaan aina \komento{fontsize}\-/komennolla.
+\komento{linespread} on kuitenkin kätevä komento rivikorkeuden
+säätämiseen yleisesti kaikkialla.
+
+Fonttikokojen määrittelyn lopuksi rivillä 22 suoritetaan komento
+\komento{normalsize}, jotta se tulee heti voimaan. Dokumentin
+esittelyosassa voidaan käyttää fonttikokoon viittaavia mittayksiköitä
+\emph{em} ja \emph{ex}, ja ne viittaavat nyt tähän kokoon.
+\komento{normalsize}\-/ komento suoritetaan kyllä myöhemmin
+automaattisesti dokumentin tekstiosan eli \ymparistox{document}\-/
+ympäristön alussa.
+
+Edellä kuvatun absoluuttisen koonmääritystavan etuna on se, että
+kirjoittaja hallitsee fonttien kokoa ja rivikorkeuksia tarkasti ja että
+julkaisuun saadaan juuri ne mitat, jotka halutaan tai vaaditaan. Tapa on
+myös teknisesti eheä eli toimii Latexin sisäisen logiikan näkökulmasta
+oikein. Haittana voi pitää sitä, että kaikki koot täytyy määritellä
+erikseen.
+
+\subsection{Fonttien oletusasetuksia}
+\label{luku/fontit-oletusasetukset}
+
+Oletuksena Latex\-/dokumentin peruskirjainperheessä
+(\komentom{setmainfont}) ja pääteviivattomassa kirjainperheessä
+(\komentom{setsansfont}) ovat päällä muun muassa seuraavat asetukset:%
+
+\begin{koodilohkosis}
+Ligatures={TeX, Common}
+HyphenChar=-
+\end{koodilohkosis}
+
+\noindent
+\koodi{TeX}\-/ligatuurit tarkoittavat lainausmerkkien ja ajatusviivojen
+tuottamiseen tarkoitettuja Texin merkintätapoja kuten \koodi{''} ja
+\koodi{\==}, joita käsitellään luvuissa \ref{luku/lainausmerkit} ja
+\ref{luku/yhdys-ajatus-miinus}. Ne eivät ole varsinaisia luonnollisen
+kielen eivätkä typografisia ligatuureja vaan kuuluvat ainoastaan
+Tex\-/kielen merkintätapoihin. \koodi{Common}\-/ ligatuurit sen sijaan
+ovat oikeita typografisia ligatuureja kuten fi, ff ja fl, ja niitä
+käsitellään tarkemmin luvussa \ref{luku/typo-liga}. Molemmat edellä
+mainitut ligatuurityypit saa pois päältä seuraavalla asetuksella:
+
+\begin{koodilohkosis}
+Ligatures={TeXReset, NoCommon}
+\end{koodilohkosis}
+
+\noindent
+Valitsin \koodi{Hyphen\-Char} asettaa tavutusmerkin kyseiselle
+kirjainperheelle. Oletuksena se on yhdysmerkki (\=/), mutta merkin
+vaihtaminen toimii vain Xelatex\-/kääntäjän kanssa, ei esimerkiksi
+Lualatexilla. Sen sijaan kaikilla kääntäjillä tavutuksen voi kytkeä
+kirjainperheeltä pois, kun antaa arvoksi \koodi{None}. Tavutusta
+käsitellään perusteellisemmin luvussa \ref{luku/tavutus}.
+
+Tasalevyinen kirjainperhe (\komentom{setmonofont}) toimii oletuksena
+hieman eri tavalla. Niissä muun muassa ei ole lainausmerkkien ja
+ajatusviivojen kirjoittamiseen tarkoitetut Tex\-/ligatuurit päällä.
+Oletusasetuksia ovat muun muassa seuraavat:
+
+\begin{koodilohkosis}
+Ligatures=Common
+HyphenChar=None
+\end{koodilohkosis}
+
+\noindent
+Yleensä tasalevyisestä kirjainperheestä kannattaa kytkeä typografiset
+ligatuurit pois päältä asetuksella \koodi{Liga\-tures=\katk No\-Common}.
+Tasalevyisen fontin ajatukseen nimenomaan kuuluu, että merkit ovat
+samanlevyisiä eikä yhden merkin tilaan sovi sulloa useampaa kirjainta.
+
+Oletuksena tavutus on kytketty pois päältä tasalevyiseltä
+kirjainperheeltä, koska sitä käytetään tavallisesti tietokoneisiin
+liittyvien koodien tai vastaavien ilmausten latomiseen, eikä niitä
+haluta yleensä tavuttaa. Tavutuksen saa kuitenkin päälle Xelatexissa
+määrittämällä tavutusmerkiksi esimerkiksi yhdysmerkin
+(\koodi{Hyphen\-Char=-}) tai kaikilla kääntäjillä poistamalla
+tasalevyisen kirjainperheen oletusasetukset ennen sen määrittelyä
+seuraavasti:
+
+\komentoi{defaultfontfeatures}
+\komentoi{ttfamily}
+\komentoi{setmonofont}
+\begin{koodilohkosis}
+\defaultfontfeatures[\ttfamily]{}
+\setmonofont{…}[…]
+\end{koodilohkosis}
+
+\noindent
+Komennolla \komentom{defaultfontfeatures} voi asettaa (joidenkin)
+kirjainperheiden oletusasetukset, kun komennon suorittaa ennen
+kirjainperheiden määrittelyä.
+
+\komentoi{defaultfontfeatures}
+\komentoi{rmfamily}
+\komentoi{sffamily}
+\begin{koodilohkosis}
+\defaultfontfeatures[\rmfamily,\sffamily]{Ligatures={TeX, Common},
+ Numbers=Lowercase}
+\end{koodilohkosis}
+
+\noindent
+Komennon valinnaisella argumentilla voi rajata, mitä kirjainperheitä
+oletusasetukset koskevat. Valinnaiseen argumenttiin kirjoitetaan yksi
+tai useampia pilkulla erotettuja komentoja, joilla kirjainperheet
+kytketään päälle: \komento{rmfamily}, \komento{sffamily},
+\komento{ttfamily} (taulukko \ref{tlk/fonttimallikomennot},
+s.~\pageref{tlk/fonttimallikomennot}) tai komennolla
+\komento{newfontfamily} määritelty fonttikomento (luku
+\ref{luku/fontin-valinta}).
+
+\subsection{Typografiset ligatuurit}
+\label{luku/typo-liga}
+
+Typografiset ligatuurit ovat fontissa olevia yhdistelmämerkkejä, joissa
+on typografisista syistä yhdistetty kaksi tai useampia kirjaimia yhteen
+merkkiin.%
+\footnote{Typografisten ligatuurien lisäksi on olemassa myös
+ luonnollisten kielten ligatuureja, jotka muodostavat kieleen kuuluvan
+ kirjaimen, kuten æ norjan kielessä. Niillä on jokin luonnolliseen
+ kieleen liittyvä merkitys, eikä eri merkkejä ei ole yhdistetty
+ typografisista syistä.} Tällaisia ligatuureja käytettiin jo
+metalliladonnassa, eli samassa metallikirjakkeessa saattoi olla enemmän
+kuin yksi kirjain.
+
+Typografisten ligatuurien tarkoituksena on tuottaa tyylikkäämpi
+lopputulos kuin saataisiin erillisten kirjainten avulla. Syynä on
+esimerkiksi se, että erilliset peräkkäiset kirjaimet eivät ole aina
+keskenään yhteensopivia. Kirjainten välistys voi olla ongelmallista:
+sopivalle etäisyydelle asetettaessa kirjainten osat voivat mennä
+rumannäköisesti päällekkäin. Riippuu fontista, mitkä ligatuurit ovat
+tarpeellisia ja mitkä ligatuurimerkit on ylipäätään toteutettu fontin
+merkistöön. Tavallisia antiikvojen ligatuureja ovat fi, ff, ffi, fl,
+ffl, fj ja ffj, mutta jotkin fontit sisältävät muitakin. Kuvaan
+\ref{kuva/ligatuurit} on koottu esimerkkejä.
+
+\leijukuva{
+ \erikoisfontti
+ \addfontfeatures{Scale=3.4, Ligatures={Common, Historic,
+ Discretionary}}
+ fi ff ffi fl ffl fj ffj Th st ct
+}{
+ \caption{Tavalliset f\=/alkuiset typografiset ligatuurit, vähän
+ harvinaisempi Th sekä historialliset ligatuurit st ja ct}
+ \label{kuva/ligatuurit}
+}
+
+Latex hoitaa tavallisten typografisten ligatuurien latomisen
+automaattisesti, eli lähdedokumenttiin ei kannata kirjoittaa
+Unicode\-/merkistön typografisia ligatuurimerkkejä (esimerkiksi
+\uctunnus{u+fb01 latin small ligature fi}) vaan ihan tavallisia
+erillisiä kirjaimia. \englanti{Open Type} \=/fontin suunnittelija on
+päättänyt meidän puolestamme, mitkä kirjainyhdistelmät on parasta latoa
+ligatuurin avulla, ja oletusasetuksilla Latex noudattaa niitä ohjeita.
+
+Jos kuitenkin yksittäisen ligatuurin muodostumisen haluaa estää, voi
+kirjainten väliin kirjoittaa komennon \komentom{textcompwordmark}, joka
+tekee näkymättömän, juuri tähän tarkoitukseen olevan merkin
+\uctunnus{u+200c zero width non-joiner}.
+
+\komentoi{textcompwordmark}
+\begin{koodilohkosis}
+fi f\textcompwordmark i
+\end{koodilohkosis}
+
+\begin{tulossis}
+ fi f\textcompwordmark i
+\end{tulossis}
+
+\noindent
+Mikäli tavallisia ligatuureja ei halua käyttöön lainkaan, on parasta
+valita jo kirjainperheen tai \=/leikkauksen käyttöönotossa asetus
+\koodi{Liga\-tures=\katk No\-Com\-mon}. Väliaikaisesti fontin asetuksiin
+voi vaikuttaa komennolla \komentom{addfontfeatures}, joka sekin on
+\paketti{fontspec}\-/pakettiin sisältyvä komento.
+
+\komentoi{addfontfeatures}
+\begin{koodilohkosis}
+{\addfontfeatures{Ligatures=NoCommon} fi fl}
+\end{koodilohkosis}
+
+\noindent
+Tavallisten ligatuurien lisäksi \englanti{Open Type} \=/fontit voivat
+sisältää myös harvinaisempia ligatuureja, jotka täytyy erikseen kytkeä
+päälle. Niiden tarkoituksena on esimerkiksi erityinen koristeellisuus
+tai historiallisen kirjoitustavan jäljittely. Harvinaisia ligatuureja ei
+ole tarkoitus käyttää joka tilanteessa vaan ainoastaan erityisestä
+syystä. Kuvassa \ref{kuva/ligatuurit} ja tässäkin tekstikappaleessa
+olevat {%
+ \newcommand{\hlig}[1]{{\erikoisfontti
+ \addfontfeatures{Ligatures=Historic}#1}}%
+ \hlig{st}- ja \hlig{ct}\-/ligatuurit%
+} on saatu fontin asetuksella \koodi{Liga\-tures=\katk His\-toric}.
+Joissakin fonteissa sama tehdään asetuksella \koodi{Liga\-tures=\katk
+ Discretionary}. Useitakin ligatuurityyppejä voi kytkeä päälle
+samanaikaisesti:
+
+\begin{koodilohkosis}
+Ligatures={TeX, Required, Common, Historic, Discretionary,
+ Contextual}
+\end{koodilohkosis}
+
+\noindent
+Tuskin mikään fontti sisältää kaikkia ligatuurityyppejä, eikä se ole
+tarkoituskaan. Jotkin ligatuurit kuuluvat vain tiettyyn typografian
+aikakauteen tai kirjaintyyliin. Open Type \=/fontin ominaisuuksia voi
+selvittää käyttöjärjestelmän komentotulkissa komennolla \koodi{otfinfo}.
+Komennon argumentiksi annetaan muun muassa fonttitiedoston nimi.
+
+\subsection{Numeroiden muoto}
+\label{luku/fontit-numerot}
+
+Varsinkin kirjatypografiassa on tavallista käyttää pääasiassa
+gemenanumeroita ({\gemenanum 1967}) eikä versaalinumeroita
+({\versaalinum 1967}), koska gemenanumerot sopivat leipätekstin
+gemenakirjainten kanssa paremmin yhteen. Versaalinumerot puolestaan
+erottuvat paremmin ja sopivat esimerkiksi taulukoihin, joissa on paljon
+lukuja. Näihin asetuksiin vaikutetaan fontin asetuksella
+\koodi{Numbers}. Tosin kaikissa fonteissa ei gemenanumeroita edes ole.
+
+\begin{koodilohkosis}
+Numbers=Lowercase % gemenanumerot
+Numbers=Uppercase % versaalinumerot (oletus)
+\end{koodilohkosis}
+
+\noindent
+Jotkin koodi\-/ilmaukset sisältävät versaalikirjaimia ja numeroita
+sekaisin. Gemenanumerot eivät kuitenkaan sovi yhteen versaalikirjainten
+kanssa, koska merkkien kokoero on häiritsevän suuri. Ei siis näin:
+RJ45, R2D2. Gemenanumeroiden kanssa täytyy käyttää pienversaalia eli
+kapiteelia: \textsc{rj45}, \textsc{r2d2}. Toinen vaihtoehto on käyttää
+pelkästään versaaleja: {\versaalinum RJ45, R2D2}.
+
+Silloin kun käytetään numeroita teknisten koodien ilmaisemiseen, voi
+olla tarpeen merkitä numero nolla poikkiviivalla
+({\addfontfeatures{Numbers={Uppercase, SlashedZero}} 0}), jottei se
+sekoitu O\=/kirjaimeen. Nollaan saadaan poikkiviiva seuraavalla
+asetuksella, jos vain fontissa on tämä ominaisuus:
+
+\begin{koodilohkosis}
+Numbers=SlashedZero
+\end{koodilohkosis}
+
+\noindent
+Kun numeroita ladotaan taulukkoon, voidaan haluta käyttää tasalevyisiä
+numeroita, jotta ne sijoittuvat allekkain samalle linjalle. Joissakin
+fonteissa on tarjolla tavallisten vaihtelevan levyisten numeroiden
+lisäksi myös tasalevyiset. Numeroiden leveyteen vaikutetaan seuraavilla
+asetuksilla:
+
+\begin{koodilohkosis}
+Numbers=Monospaced % tasalevyiset numerot
+Numbers=Proportional % vaihtelevan levyiset numerot (oletus)
+\end{koodilohkosis}
+
+\subsection{Välistykset: harvennus ja tiivistys}
+\label{luku/fontit-välistys}
+
+Fontin kanssa käytettäviä sanavälejä voi säätää \koodim{Word\-Space}\-/
+valitsimella, jonka arvoksi annetaan desimaalilukukerroin eli suhdeluku
+normaaliin verrattuna. Arvona voi olla myös kolme eri kerrointa, jolloin
+mukana on lisäksi sanavälin venymisen rajat. Tämä asetus on tehtävä
+kirjainperheen tai \=/leikkauksen määrittelyn yhteydessä, eli se ei
+toimi esimerkiksi \komento{addfontfeatures}\-/ komennon kanssa. Katso
+tietoa sanaväleistä myös luvusta \ref{luku/sanaväli} tai
+tekstikappaleiden latomista käsittelevästä luvusta \ref{luku/kappale}.
+\noclub[2]
+
+Fonttiasetusten valitsimella \koodim{Letter\-Space} säädetään merkkien
+välistystä eli niiden välistä tyhjää tilaa. Arvoksi annetaan
+positiivinen tai negatiivinen prosenttiluku, joka ilmaisee alkuperäiseen
+lisättävän osuuden. Asetus \koodi{Letter\-Space=\katk 6} tuottaa siis
+kuusi prosenttia leveämmät merkkien välit. Välistyksen tiivistäminen ja
+harvennuksen typografiaa käsitellään luvussa
+\ref{luku/korostus-harvennus}, mutta seuraavassa on esimerkki, kuinka ne
+teknisesti toteutetaan:
+
+\komentoi{scshape}
+\komentoi{addfontfeatures}
+\begin{koodilohkosis}
+\scshape {\addfontfeatures{LetterSpace=-2} tiivistys} \\
+normaali \\ {\addfontfeatures{LetterSpace=6} harvennus}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \scshape {\addfontfeatures{LetterSpace=-2} tiivistys} \\
+ normaali \\ {\addfontfeatures{LetterSpace=6} harvennus}
+\end{tulossis}
+
+\noindent
+Jos esimerkiksi harvennuksen haluaa automaattisesti mukaan
+kirjainperheeseen kuuluvaan pienversaaliin, käytetään valitsinta
+\koodi{Small\-Caps\-Features}:
+
+\komentoi{setmainfont}
+\begin{koodilohkosis}
+\setmainfont{…}[SmallCapsFeatures={LetterSpace=6}]
+\end{koodilohkosis}
+
+\subsection{Keinotekoinen venytys, lihavointi ja kallistus}
+\label{luku/fontit-venytys}
+
+Valitsimella \koodim{Fake\-Stretch} voi venyttää tai kutistaa merkkejä
+leveyssuunnassa. Arvoksi annetaan desimaalilukukerroin, joka on
+suhdeluku alkuperäiseen leveyteen nähden. Seuraavassa havainnollistava
+esimerkki:
+
+\komentoi{addfontfeatures}
+\begin{koodilohkosis}
+esimerkki \\
+{\addfontfeatures{FakeStretch=1.3} esimerkki}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ esimerkki \\
+ {\addfontfeatures{FakeStretch=1.3} esimerkki}
+\end{tulossis}
+
+\noindent
+Kirjainleikkauksen leventäminen tekee tekstistä samalla lihavampaa,
+koska kirjainten viivat tulevat vahvemmiksi leveyssuunnassa.
+Korkeussuunnassa vahvuus säilyy ennallaan, joten kirjainten
+viivakontrasti muuttuu. Kirjainleikkauksen kutistaminen vaikuttaa
+lihavuuteen päinvastaisesti. Tällainen mekaaninen fontin
+''korjaileminen'' ei välttämättä tuota typografisesti kovin hyvää jälkeä
+mutta voi sopia lievästi käytettynä esimerkiksi otsikoihin. Tämän oppaan
+tasalevyistä kirjainperhettä on hieman kutistettu, koska alkuperäinen on
+kohtuuttoman leveä ({\ttfamily\addfontfeatures{FakeStretch=1}
+ esimerkki}) verrattuna muiden kirjainperheiden leveyteen.
+
+Jos kirjainperheeseen ei sisälly sopivaa lihavoitua tai kaltevaa
+leikkausta, voi sellaiset koettaa tehdä myös keinotekoisesti
+\koodim{Fake\-Bold}- ja \koodim{Fake\-Slant}\-/ valitsimien avulla.
+Niille annetaan arvoksi desimaalilukukerroin. Valitettavasti
+\koodi{Fake\-Bold} toimii vain Xelatex\-/kääntäjän kanssa.
+
+\komentoi{addfontfeatures}
+\begin{koodilohkosis}
+pysty {\addfontfeatures{FakeSlant=.2} kalteva}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ pysty {\addfontfeatures{FakeSlant=.2} kalteva}
+\end{tulossis}
+
+\noindent
+Mekaanisen lihavoinnin tai kallistuksen saa osaksi kirjainperhettä, kun
+asettaa kirjainperheen määrittelyn yhteydessä halutun kirjainleikkauksen
+valitsimella \koodi{Bold\-Font} tai \koodi{Slanted\-Font} ja määrittää
+niille erityisiä ominaisuuksia valitsimella \koodi{Bold\-Fea\-tures} tai
+\koodi{Slanted\-Fea\-tures}. Seuraava esimerkki asettaa dokumentin
+perusfontille kaltevan leikkauksen. Tämän jälkeen komento
+\komento{slshape} valitsee \textsl{kaltevan} leikkauksen, joka on siis
+eri asia kuin \textit{kursiivi} (\komento{itshape}).
+
+\komentoi{setmainfont}
+\begin{koodilohkosis}
+\setmainfont{…}[
+ SlantedFont={…}, % tähän pystyasentoinen leikkaus
+ SlantedFeatures={FakeSlant=.2}]
+\end{koodilohkosis}
+
+\subsection{Keinotekoinen pienversaali}
+\label{luku/fontit-keinopienversaali}
+
+Moniin fontteihin ei sisälly lainkaan pienversaalia. Jos sellaisen silti
+haluaa omaan korostusvalikoimaan, voi yrittää pienentää
+versaalikirjaimet sopivaan kokoon. Seuraavassa esimerkissä versaaleja
+ensin pienennetään ja sitten venytetään hieman leveyssuunnassa. Lisäksi
+merkkivälejä harvennetaan lievästi. Käytännössä versaaleja pienentämällä
+ei saada tyylikästä pienversaalia aikaan, koska merkkien viivoista tulee
+liian ohuita.
+
+\komentoi{textsc}
+\komentoi{addfontfeatures}
+\begin{koodilohkosis}
+\textsc{pienversaali} oikea \\
+{\addfontfeatures{ScaleAgain=.68, FakeStretch=1.17, LetterSpace=4}
+ PIENVERSAALI} keinotekoinen
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \textsc{pienversaali} oikea \\
+ {\addfontfeatures{ScaleAgain=.68, FakeStretch=1.17, LetterSpace=4}
+ PIENVERSAALI} keinotekoinen
+\end{tulossis}
+
+\subsection{Matematiikkatilan fontti}
+\label{luku/matematiikka-fontit}
+
+Latexin matematiikkatilan (luku \ref{luku/matematiikka}) fontti
+asetetaan eri tavalla kuin normaalin tilan eli tekstitilan fontit.
+Matematiikkatilaa varten tarvitaan paketti \pakettictan{unicode-math},
+joka täytyy ladata muiden matematiikkaan tai fontteihin liittyvien
+pakettien jälkeen. Paketti tuo komennon \komento{setmathfont}, joka on
+matematiikkatilan vastine luvussa \ref{luku/fontin-valinta} esitellyille
+fontinmäärittelykomennoille \komento{setmainfont}, \komento{setsansfont}
+ja \komento{setmonofont}.
+
+\pakettii{fontspec}
+\pakettii{unicode-math}
+\komentoi{setmainfont}
+\komentoi{setmathfont}
+\begin{koodilohkosis}
+\usepackage{fontspec}
+\usepackage{unicode-math}
+\setmainfont{TeX Gyre Pagella} % tekstitilan perusfontti
+\setmathfont{TeX Gyre Pagella Math} % matematiikkatilan fontti
+\end{koodilohkosis}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[3]{\koodi{#1} & \koodi{#2} & \koodi{#3} \\}
+
+ \begin{tabular}{lll}
+ \toprule
+ \ots{Yleistyyli} & \ots{Lihavointi} & \ots{Pääteviivaton} \\
+ \midrule
+ \rivi{math-style=ISO} {bold-style=ISO} {sans-style=upright}
+ \rivi{math-style=TeX} {bold-style=TeX} {sans-style=italic}
+ \rivi{math-style=french} {bold-style=upright}{sans-style=literal}
+ \rivi{math-style=upright}{}{}
+ \rivi{math-style=literal}{}{}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Matematiikkatilan tyyliasetuksia (\paketti{unicode-math}\-/
+ paketti)}
+ \label{tlk/unicode-math-style}
+}
+
+\noindent
+Paketin \paketti{unicode-math} lataamisen yhteydessä voi
+\komento{usepackage}\-/ komennon valinnaisen argumentin avulla vaikuttaa
+matematiikkatilassa käytettyihin kirjainleikkauksiin. Argumenttiin
+sopivia valitsimia ovat \koodi{math-style}, \koodi{bold-style} ja
+\koodi{sans-style}, ja niille sopivia arvoja on koottu taulukkoon
+\ref{tlk/unicode-math-style}. Asetukset vaikuttavat esimerkiksi siihen,
+mitä kirjainleikkausta käytetään, kun ladotaan matematiikkatilan
+latinalaisia tai kreikkalaisia kirjaimia.
+
+\begin{koodilohkosis}
+\usepackage[math-style=ISO]{unicode-math}
+\end{koodilohkosis}
+
+\noindent
+Matematiikkatilan fontiksi ei kelpaa mikä tahansa, koska tarvittavien
+matemaattisten symbolien täytyy sisältyä \englanti{Open Type} \=/fontin
+merkkivalikoimaan. Tukea ei ehkä ole, jos sitä ei fontille erikseen
+mainosteta. Fonttitiedoston ominaisuuksia voi tutkia esimerkiksi
+käyttöjärjestelmän komentotulkissa \koodi{otfinfo}\-/ komennolla:
+
+\begin{koodilohkosis}
+otfinfo -s texgyrepagella-math.otf
+\end{koodilohkosis}
+
+\noindent
+Tex Live \=/jakelun mukana tulee muutama \englanti{Open Type}
+\=/kirjainperhe, joihin kuuluvat myös matematiikan symbolit. Tällaisia
+kirjainperheitä ovat ainakin Libertinus sekä eri TeX Gyre \-/perheet.
+Koko Libertinus\-/ perheen voi ottaa käyttöön hyvin yksinkertaisesti:
+ladataan vain paketti \paketti{libertinus}, joka määrittää kerralla
+antiikvan, groteskin, tasalevyisen ja matematiikkafontin. Myös
+tavallisten fontinmäärityskomentojen käyttö on mahdollista.
+
+\begin{esimerkki*}
+ \komentoi{setmathfont}
+
+\begin{koodilohko}
+\setmathfont{Libertinus Math Regular}
+\setmathfont{TeX Gyre Bonum Math}
+\setmathfont{TeX Gyre Dejavu Math}
+\setmathfont{TeX Gyre Pagella Math}
+\setmathfont{TeX Gyre Schola Math}
+\setmathfont{TeX Gyre Termes Math}
+\end{koodilohko}
+
+ \caption{Matematiikan symboleja sisältäviä vapaita fontteja. Komento
+ \komento{setmathfont} sisältyy pakettiin \paketti{unicode-math}}
+ \label{esim/matematiikka-fontteja}
+\end{esimerkki*}
+
+Esimerkissä \ref{esim/matematiikka-fontteja} on komentoja joidenkin
+matematiikkafonttien lataamiseen. Lähes aina on järkevää käyttää
+asetusta \koodi{Scale=\katk MatchLowercase}, joka asettaa fontin
+samankokoiseksi kuin vastaava peruskirjainperhe.
+
+\begin{koodilohkosis}
+\setmathfont{TeX Gyre Pagella Math}[Scale=MatchLowercase]
+\end{koodilohkosis}
+
+\section{Kieli}
+\label{luku/kieliasetukset}
+
+Melkein aina Latex\-/dokumenttiin täytyy ladata kielipaketti ja sen
+mukana asetukset tiettyjä kieliä varten. Kieliasetukset sisältävät
+ainakin tavutussäännöt (luku \ref{luku/tavutus}) sekä kielelle
+mukautettuja nimiä dokumentin eri osille. Esimerkiksi sisällysluettelon
+ja kirjallisuusluettelon otsikot tulevat kieliasetuksista, samoin
+leijuvien taulukoiden ja kuvien nimet ''\tablename'' ja ''\figurename''.
+Myös muita asetuksia tai komentoja saattaa tulla kieliasetusten mukana,
+mutta ne vaihtelevat eri kielissä.
+
+Kielipaketteja on kaksi -- \pakettictan{babel} ja
+\pakettictan{polyglossia} \==, ja kirjoittajan täytyy valita niistä
+jompikumpi. Pakettien historia ja kehitys on suunnilleen
+seuraavanlainen: \paketti{babel} on paljon vanhempi, ja monet vanhat
+oppaat ja esimerkit käsittelevät pelkästään sitä. Kun Latex siirtyi
+Unicode\-/aikaan Xelatex\-/kääntäjän ja \paketti{fontspec}\-/paketin
+myötä, \paketti{babel} ei pysynyt kehityksessä mukana. Syntyi
+\paketti{polyglossia}, joka hallitsee Unicoden sekä muitakin kuin
+latinalaiseen kirjaimistoon perustuvia kieliä ja kirjoitusjärjestelmiä.
+\paketti{babel}\-/paketin kehitys ei kuitenkaan pysähtynyt, ja nykyään
+myös se toimii Unicode\-/merkistön kanssa ainakin latinalaiseen
+kirjaimistoon perustuvien kielten osalta.
+
+Suomen kielen kannalta on aika lailla sama, kumpaa kielipakettia
+käyttää. Meidän näkökulmastamme ''erikoisemmat'' kielet ja
+kirjoitusjärjestelmät voivat vaatia \paketti{polyglossia}\-/paketin sekä
+Lualatex\-/{} tai Xelatex\-/kääntäjän käyttöä. \paketti{babel} sisältää
+enemmän ominaisuuksia, esimerkiksi omien komentojen ja muiden viritysten
+tekemiseen; \paketti{polyglossia} on yksinkertaisempi paketti, jonka
+kehitys tuntuisi keskittyvän vain ydintehtävään.
+
+Seuraavissa alaluvuissa käsitellään kummankin kielipaketin tärkeimmät
+toiminnot eli kielen valintaan liittyvät asiat. Yleinen ajatus on se,
+että Latex\-/dokumentin esittelyosassa ladataan kielipaketti ja
+määritellään dokumentin pääasiallinen kieli ja mahdolliset muut kielet.
+Jos dokumentin tekstiosa sisältää muita kuin pääasiallista kieltä,
+täytyy käyttää erityisiä komentoja tai ympäristöjä, joilla kerrotaan
+Latexille, mistä kielestä on kyse.
+
+\subsection{Polyglossia}
+
+Kielipaketti \paketti{polyglossia} on tyypillinen valinta, jos halutaan
+varmistaa, että Unicode\-/merkistöä (\textsc{utf\=/8}\-/merkistökoodaus)
+voi käyttää vapaasti. Samalla se tarkoittaa, että kääntäjän on oltava
+Lualatex tai Xelatex. Kielipaketin käyttöönotto dokumentin
+esittelyosassa näyttää seuraavanlaiselta:
+
+\komentoi{usepackage}
+\komentoi{setdefaultlanguage}
+\komentoi{setotherlanguage}
+\pakettii{polyglossia}
+\begin{koodilohkosis}
+\usepackage{polyglossia}
+\setdefaultlanguage{finnish}
+\setotherlanguage{english}
+\setotherlanguage{greek}
+\end{koodilohkosis}
+
+\noindent
+Eri kielillä on erilaisia valinnaisia asetuksia, jotka täytyy selvittää
+\paketti{polyglossia}\-/paketin ohjekirjasta. Asetukset liittyvät
+esimerkiksi kielen kirjoitusjärjestelmän alueelliseen tai
+historialliseen vaihteluun. Yleinen moniin kieliin sopiva valitsin on
+\koodi{babel\-short\-hands}, joka lisää erilaisia, lähinnä tavutukseen
+liittyviä komentoja (luku \ref{luku/tavutus}). Suomen kielen voisi siis
+ottaa käyttöön myös seuraavalla tavalla:
+
+\komentoi{setdefaultlanguage}
+\begin{koodilohkosis}
+\setdefaultlanguage[babelshorthands]{finnish}
+\end{koodilohkosis}
+
+\noindent
+Dokumentin tekstiosa käyttää kieltä, joka määriteltiin komennolla
+\komento{setdefaultlanguage}. Muita dokumentin esittelyosassa
+määriteltyjä kieliä voi käyttää väliaikaisesti komennolla, joka alkaa
+kirjaimilla \komentox{text} ja jatkuu kielen nimellä, esimerkiksi
+\komento{textenglish} tai \komento{textgreek}.
+
+\komentoi{textenglish}
+\begin{koodilohkosis}
+Englannin sana \textenglish{shorthand} tarkoittaa 'pikakirjoitusta'.
+\end{koodilohkosis}
+
+\noindent
+Toinen vaihtoehto on käyttää kielen nimen mukaista ympäristöä:
+
+\begin{koodilohkosis}
+\begin{greek}
+ ...
+\end{greek}
+\end{koodilohkosis}
+
+\noindent
+Tietynkieliseksi merkitty teksti voi näyttää ladotussa dokumentissa ihan
+samalta kuin muukin teksti. Tavutuksessa kuitenkin käytetään eri
+kielissä eri asetuksia, ja joissakin kielissä voi olla myös pieniä
+typografisia yksityiskohtia eri tavalla.
+
+Kirjoittaja voi määritellä eri kielille eri fontin. Oletuksena käytetään
+peruskirjainperhettä, mikä samalla tarkoittaa, että kielen vaihtuessa
+pois oletuskielestä suoritetaan \komento{rmfamily}\-/komento (taulukko
+\ref{tlk/fonttimallikomennot}, s.~\pageref{tlk/fonttimallikomennot}).
+Tätä havainnollistaa seuraava esimerkki, jossa \komento{textenglish}\-/
+komennon vaikutuksen ajaksi tulee käyttöön perusfontti
+\komento{rmfamily} eikä ympärillä oleva pääteviivaton
+\komento{sffamily}.
+
+\komentoi{sffamily}
+\komentoi{textenglish}
+\begin{koodilohkosis}
+\sffamily
+pääteviivaton \textenglish{main font} pääteviivaton
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \sffamily pääteviivaton {\rmfamily main font} pääteviivaton
+\end{tulossis}
+
+\noindent
+Erikielisten tekstikatkelmien fonttiin voi vaikuttaa määrittelemällä
+komennon, jonka nimessä on ensin kielen nimi ja lopuksi sana
+\koodi{font}, esimerkiksi \komento{englishfont} tai \komento{greekfont}.
+Komennon määritelmään kirjoitetaan yleensä kirjainperheeseen tai
+\=/leikkaukseen vaikuttavia komentoja.
+
+Seuraavassa esimerkissä \komento{englishfont}\-/ komento määritellään
+tyhjäksi, mikä saa aikaan sen, että englanninkieliseksi merkitty teksti
+ei muuta fonttia millään tavalla vaan käytetään samaa kirjainperhettä
+kuin muutenkin siinä kohdassa dokumenttia.
+
+\begin{koodilohkosis}
+\newcommand{\englishfont}{}
+\end{koodilohkosis}
+
+\noindent
+Mikäli haluaa jollekin kielelle kokonaan eri kirjainperheen, kannattaa
+käyttää \paketti{fontspec}\-/paketin komentoa \komento{newfontfamily}
+(luku \ref{luku/fontin-valinta}) ja määritellä kielen fonttikomennot
+sillä. Tällainen on tarpeen ainakin silloin, kun dokumentin
+peruskirjainperhe ei sisällä kyseisen kielen kirjaimia.
+
+\komentoi{newfontfamily}
+\begin{koodilohkosis}
+\newfontfamily{\greekfont}{GFS Artemisia}[Scale=MatchLowercase]
+\end{koodilohkosis}
+
+% Seuraat eivät tunnu toimivan:
+
+% \newfontfamily{\greekfontsf}{GFS Neohellenic} [Scale=MatchLowercase]
+% \newfontfamily{\greekfonttt}{DejaVu Sans Mono}[Scale=MatchLowercase]
+%
+% Edellisen esimerkin \koodi{fontsf}\-/loppuinen komento tarkoittaa
+% pääteviivatonta kirjainperhettä ja \koodi{fonttt}\-/loppuinen
+% tasalevyistä perhettä.
+
+% \textenglish{englantia \textsf{englantia} englantia}
+
+\subsection{Babel}
+
+Vanha kunnon \paketti{babel} toimii useiden eri Latex\-/kääntäjien
+kanssa. Dokumentit kirjoitettiin ennen kahdeksanbittisillä merkistöillä
+(kuten \textsc{iso-8859\=/1}), jotka sisältävät vain reilut kaksisataa
+merkkiä%
+\footnote{Teknisesti kahdeksanbittiset merkistöt sisältävät
+ 2\textsuperscript8 eli 256 merkkipaikkaa, mutta osa merkeistä on
+ teknisiä ohjauskoodeja, jotka eivät liity ihmiskieliin.} %
+ja soveltuvat rajallisen kielijoukon kirjoittamiseen. Nykyään
+\paketti{babel} toimii myös Unicode\-/merkistön ja \textsc{utf\=/8}\-/
+merkistökoodauksen kanssa ainakin latinalaiseen kirjaimistoon
+perustuvien kielten osalta.
+
+Kieliasetukset otetaan käyttöön \paketti{babel}\-/paketissa seuraavan
+esimerkin tavoin. Paketin valinnaiseen argumenttiin kirjoitetaan
+ladattavien kielten nimet ja viimeisenä mainitaan se kieli, joka
+halutaan pääasialliseksi kieleksi.
+
+\komentoi{usepackage}
+\pakettii{babel}
+\begin{koodilohkosis}
+\usepackage[english,greek,finnish]{babel}
+\end{koodilohkosis}
+
+\noindent
+Pääasiallisen kielen voi valita myös \koodi{main}\-/valitsimella:
+
+\komentoi{usepackage}
+\pakettii{babel}
+\begin{koodilohkosis}
+\usepackage[main=finnish,english,greek]{babel}
+\end{koodilohkosis}
+
+\noindent
+Dokumentin tekstissä yksittäiset vieraskieliset sanat tai ilmaukset
+merkitään komennolla \komento{foreignlanguage}. Komennon ensimmäinen
+argumentti on kielen nimi ja toinen on sillä kielellä ladottava teksti.
+
+\komentoi{foreignlanguage}
+\begin{koodilohkosis}
+Englannin sana \foreignlanguage{english}{shorthand} tarkoittaa
+'pikakirjoitusta'.
+\end{koodilohkosis}
+
+\noindent
+Komennon sijasta voi käyttää ympäristöä \ymparisto{otherlanguage}, joka
+vaihtaa kieltä ympäristön ajaksi.
+
+\ymparistoi{otherlanguage}
+\begin{koodilohkosis}
+\begin{otherlanguage}{greek}
+ ...
+\end{otherlanguage}
+\end{koodilohkosis}
+
+\noindent
+Kielen vaihtamista voi helpottaa \komento{babeltags}\-/ komennolla, joka
+määrittelee lyhempiä komentoja ja ympäristöjä kielen vaihtamiseen.
+Komentoa käytetään seuraavan esimerkin tavoin. Sen jälkeen voi käyttää
+englanninkielisen tekstin merkitsemiseen komentoa \komentox{text\-eng}
+tai ympäristöä \ymparistox{eng}.
+
+\komentoi{babeltags}
+\begin{koodilohkosis}
+\babeltags{eng = english}
+\end{koodilohkosis}
+
+\noindent
+Oletuskieli voidaan vaihtaa kesken dokumentin komennolla
+\komento{selectlanguage}. Komennon argumentiksi annetaan kielen nimi,
+esimerkiksi seuraavalla tavalla:
+
+\komentoi{selectlanguage}
+\begin{koodilohkosis}
+\selectlanguage{english}
+\end{koodilohkosis}
+
+\noindent
+Eri kielille on mahdollista asettaa eri kirjainperheet
+\komento{babelfont}\-/ komennolla. Tämä komento korvaa
+\paketti{fontspec}\-/ paketin fontinvalintakomennot (luku
+\ref{luku/fontin-valinta}) ja muodostaa uuden korkeamman tason komennon,
+joka sisältää myös kielen. Jos siis käyttää komentoa
+\komento{babelfont}, ei saa samanaikaisesti käyttää komentoja
+\komento{setmainfont}, \komento{setsansfont} eikä \komento{setmonofont}.
+
+Oman dokumentin kirjainperheet voitaisiin määrittää
+\komento{babelfont}\-/ komennolla esimerkin \ref{esim/babelfont} tavoin.
+Ensin esimerkissä määritellään peruskirjainperhe (\koodi{rm}),
+pääteviivaton perhe (\koodi{sf}) ja tasalevyinen perhe (\koodi{tt}). Sen
+jälkeen määritellään kreikan kielessä (\koodi{greek}) käytettävä
+peruskirjainperhe ja pääteviivaton perhe.
+
+\begin{esimerkki*}
+ \komentoi{babelfont}
+
+\begin{koodilohko}
+\babelfont{rm}{TeX Gyre Termes}
+\babelfont{sf}[Scale=MatchLowercase]{TeX Gyre Heros}
+\babelfont{tt}[Scale=MatchLowercase]{TeX Gyre Cursor}
+
+\babelfont[greek]{rm}[Scale=MatchLowercase]{GFS Artemisia}
+\babelfont[greek]{sf}[Scale=MatchLowercase]{GFS Neohellenic}
+\end{koodilohko}
+ \caption{\komento{babelfont}\-/komennon käyttö dokumentin
+ kirjainperheiden valintaan ja kielikohtaisten kirjainperheiden
+ valintaan}
+ \label{esim/babelfont}
+\end{esimerkki*}
+
+Esimerkissä ennen fontin nimeä (esim. TeX Gyre Heros) oleva valinnainen
+argumentti on sama kuin \paketti{fontspec}\-/paketin
+fontinvalintakomennoissa. Sen avulla määritellään kyseisen
+kirjainperheen asetuksia. Lisätietoa voi lukea fontteja käsittelevästä
+luvusta \ref{luku/kirjaintyypit} ja \pakettictan{fontspec}\-/ paketin
+ohjekirjasta.
+
+\section{Tavutus}
+\label{luku/tavutus}
+
+Tex tavuttaa eli katkaisee sanoja automaattisesti rivien lopussa, jotta
+se saa tekstikappaleet näyttämään tasapainoisilta. Lähtökohtaisesti
+tavutus määräytyy kielikohtaisten tavutussääntöjen ja \=/asetusten
+perusteella, mutta kirjoittaja voi tehdä poikkeuksia kirjoittamalla
+tavutusvihjeitä. Käytännössä tavutusvihjeitä tarvitaan välillä.
+
+Kielen valintaa ja yleisiä kieliasetuksia käsitellään tarkemmin luvussa
+\ref{luku/kieliasetukset}, mutta mainitaan tässäkin, että suomen kieli
+ja sen mukainen tavutus saadaan päälle, kun dokumentin esittelyosaan
+kirjoittaa seuraavat komennot:
+
+\komentoi{usepackage}
+\komentoi{setdefaultlanguage}
+\pakettii{polyglossia}
+\begin{koodilohkosis}
+\usepackage{polyglossia}
+\setdefaultlanguage{finnish}
+\end{koodilohkosis}
+
+\noindent
+Tavutusta käsitellään tässä yhteydessä lähinnä
+\paketti{polyglossia}\-/kielipaketin näkökulmasta. Toinen kielipaketti
+\paketti{babel} toimii joissakin tavutukseen liittyvissä asioissa eri
+tavalla, ja pakettien eroja mainitaan tekstin lomassa.
+
+\subsection{Yleiset tavutussäännöt}
+
+Texin automaattinen tavutus ei perustu varsinaiseen sanojen eikä
+taivutusmuotojen tunnistamiseen vaan yksinkertaisiin kirjainpohjaisiin
+sääntöihin. Säännöt pyrkivät kuvaamaan kielen tavujen rakenteen ja
+huomioimaan myös typografiaan liittyviä suosituksia.
+
+Automaattinen tavutus auttaa paljon, mutta se ei yksinään riitä, koska
+se tekee välillä virheitä tai tuottaa muuten suositusten vastaista
+jälkeä. Kirjoittajan täytyy auttaa välillä eli kirjoittaa
+tavutusvihjeitä. Yksi tapa tavutusvihjeiden kirjoittamiseen on
+\komento{hyphenation}\-/ komento, jolla määritellään yksittäisten
+sanojen tavutuskohdat kaikkialla dokumentissa. Seuraava esimerkki
+selventää komennon käyttöä:
+
+\komentoi{hyphenation}
+\begin{koodilohkosis}
+\hyphenation{
+ ala-indek-si alku-osa
+ nimen-omaan
+ typo-gra-fi-nen
+}
+\end{koodilohkosis}
+
+\noindent
+Komennon perään aaltosulkeiden sisään kirjoitetaan sanoja, jotka
+erotetaan toisistaan sanaväleillä. Sanoihin kirjoitetaan yhdysmerkki
+niihin kohtiin, joista sanan katkaiseminen on sallittua. Jos sanassa
+itsessään on yhdysmerkki, sen tavutusta ei voi käsitellä tällä
+komennolla. Luvussa \ref{luku/tavutuksen-merkit} kerrotaan muita tapoja.
+
+\komento{hyphenation}\-/komennon voi sijoittaa dokumentin esittelyosaan
+tai tekstiosaan, mutta sijainti vaikuttaa sen toimintaan. Jos komennon
+sijoittaa dokumentin esittelyosaan ennen kuin mitään kieltä on ladattu
+tai valittu, se vaikuttaa kaikkien sanojen tavutukseen kielestä
+riippumatta. Jos komennon sijoittaa dokumentin tekstiosaan eli kielen
+valitsemisen jälkeen, se vaikuttaa vain kyseisen kielen eli yleensä
+dokumentin pääasiallisen kielen tavutukseen.
+
+\subsection{Yksittäisten sanojen tavutus}
+\label{luku/tavutuksen-merkit}
+
+Tietyt sanassa mukana olevat merkit kytkevät muut tavutussäännöt pois
+päältä ja muuttavat sanan tavutuksen yksilölliseksi. Jos sanassa on
+mukana yksikin tavutusvihje (\komento{-}), yhdysmerkki (\koodi{\=/}),
+lyhyt ajatusviiva (\mbox{\koodi{--}}) tai pitkä ajatusviiva
+(\mbox{\koodi{---}}), sana katkaistaan vain näiden kohdalta
+(\koodi{\keno\=/}) tai jälkeen.%
+\footnote{\paketti{polyglossia}\-/kielipaketti ja Tex toimivat tekstissä
+ kuvatulla tavalla. Sen sijaan \paketti{babel}\-/paketti määrittelee
+ ainakin suomen kielelle tavutusvihjeen (\komento{-}) siten, että se
+ sallii sanan tavutuksen muistakin kohdista kuin tavutusvihjeen
+ kohdalta. Tavutusvihjeen molemmin puolin sanan osat tavutetaan
+ yleisten sääntöjen mukaisesti, ellei tavutuksen estäviä merkkejä kuten
+ yhdysmerkkejä tai ajatusviivoja ole. \paketti{babel}\-/paketissa on
+ myös tavutusvihje \koodi{\textquotedbl\textbar}, joka estää tavutuksen
+ muualta.}
+
+Myös Unicoden ajatusviivamerkit \uctunnus{u+2013 en dash} ja
+\uctunnus{u+2014 em dash} toimivat, mutta ne käyttäytyvät tavutuksen
+kannalta eri tavalla Lualatex\-/{} ja Xelatex\-/kääntäjillä.
+Yhteensopivuussyistä kannattanee välttää Unicoden ajatusviivoja
+Latex\-/lähdetiedostossa.
+
+\leijutlk{
+ \begin{tabular}{lll}
+ \toprule
+ \ots{Lähde}
+ & \ots{Tavutus}
+ & \ots{Merkitys} \\
+ \midrule
+ \koodi{matkustaa}
+ & mat\tavukohta kus\tavukohta taa
+ & tavutus kaikista kohdista \\
+ \koodi{matkus\komento{-}taa}
+ & matkus\tavukohta taa
+ & vain tavutusvihjeen kohdalta \\
+ \koodi{matka-aika}
+ & matka-\tavukohta aika
+ & vain yhdysmerkin jälkeen \\
+ \koodi{matka-ai\komento{-}ka}
+ & matka-\tavukohta ai\tavukohta ka
+ & vain yhdysmerkki ja tavutusvihje \\
+ \koodi{Oulu--Rovaniemi}
+ & Oulu--\tavukohta Rovaniemi
+ & vain ajatusviivan jälkeen \\
+ \koodi{Oulu--Rova\komento{-}niemi}
+ & Oulu--\tavukohta Rova\tavukohta niemi
+ & vain ajatusviiva ja tavutusvihje \\
+ \koodi{matka-}
+ & matka-
+ & ei tavutuskohtia \\
+ \koodi{-aika}
+ & -\tavukohta aika
+ & vain yhdysmerkin jälkeen \\
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Tavutusvihjeen, yhdysmerkin ja ajatusviivan vaikutus
+ tavutukseen}
+ \label{tlk/tex-tavutus}
+}
+
+Taulukossa \ref{tlk/tex-tavutus} on esimerkkejä tavutusvihjeiden,
+yhdysmerkin ja ajatusviivan vaikutuksesta. Ensimmäisessä sarakkeessa on
+esimerkkisana siinä muodossa kuin se kirjoitetaan lähdetiedostoon.
+Toisessa sarakkeessa on ladottu sana, johon on pystyviivalla merkittynä
+mahdolliset tavutuskohdat.
+
+Taulukon viimeinen rivi paljastaa suomen kielen kannalta ongelmallisen
+tilanteen. Esimerkiksi ilmauksessa \emph{matkasuunnitelma ja
+ \mbox{-aika}} ei riviä saa katkaista sanassa \emph{\mbox{-aika}}
+olevan yhdysmerkin jälkeen, koska rivin loppuun jäisi yksinäinen
+yhdysmerkki. Latexin peruskeinoilla sana täytyy laittaa näkymättömään
+laatikkoon, joka pitää merkit yhdessä: \komento{mbox}\komentoarg{-aika}.
+Toinen vaihtoehto on sitovan yhdysmerkin käyttö, jota käsitellään
+seuraavassa alaluvussa.
+
+\subsection{Tavutuksen sallivia ja sitovia merkkejä}
+\label{luku/tavutus-sallivat-sitovat}
+
+Unicode\-/merkistön sitova yhdysmerkki \uctunnus{u+2011 non\-/breaking
+ hyphen} näkyy tavallisena yhdysmerkkinä, mutta se estää sanan
+katkaisemisen yhdysmerkin vierestä. \uctunnus{u+2011}\-/merkkiä voi siis
+käyttää, mutta se ei ole aina toiminut luotettavasti ja yhdenmukaisesti
+eri kääntäjissä. Yhteensopivuussyistä voi olla järkevää käyttää muita
+vaihtoehtoja sitovalle yhdysmerkille.
+
+Paketti \pakettictan{extdash} tuo uusia komentoja ja mahdollisuuksia
+tavutuksen hallintaan. Komennot ovat sellaisia kuin \komento{Hyphdash}
+ja \komento{Endash}, mutta niille on saatavilla myös lyhemmät muodot,
+jos paketin lataa käyttämällä \koodi{short\-cuts}\-/ valitsinta.
+
+\komentoi{usepackage}
+\pakettii{extdash}
+\begin{koodilohkosis}
+\usepackage[shortcuts]{extdash}
+\end{koodilohkosis}
+
+\noindent
+Paketti sisältää kaksi lisävaihtoehtoa kolmelle viivavälimerkille
+eli yhdysmerkille, lyhyelle ajatusviivalle ja pitkälle ajatusviivalle.
+Kun Texin viivavälimerkit (luku \ref{luku/tavutuksen-merkit}) aina
+estävät tavutuksen muualta kuin välimerkin jälkeen,
+\paketti{extdash}\-/paketin perusvaihtoehdot sallivat tavutuksen
+muualtakin. Lisäksi kaikille kolmelle viivavälimerkille on sitova
+versio, joka estää tavutuksen välimerkin jälkeen (mutta sallii muualta).
+
+Taulukossa \ref{tlk/extdash} ovat \paketti{extdash}\-/paketin tärkeimmät
+komennot ja niiden merkitykset. Taulukossa \ref{tlk/extdash-vertailu}
+vertaillaan \paketti{extdash}\-/paketin komentoja Texin vastaaviin.
+
+\leijutlk{
+ \begin{tabular}{ll}
+ \toprule
+ \ots{Komento} & \ots{Merkitys} \\
+ \midrule
+ \komento{-/} & tavutuksen salliva yhdysmerkki \\
+ \komento{=/} & sitova, tavutuksen salliva yhdysmerkki \\
+ \komento{--} & tavutuksen salliva lyhyt ajatusviiva \\
+ \komento{==} & sitova, tavutuksen salliva lyhyt ajatusviiva \\
+ \komento{---} & tavutuksen salliva pitkä ajatusviiva \\
+ \komento{===} & sitova, tavutuksen salliva pitkä ajatusviiva \\
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{\paketti{extdash}-paketin komentoja}
+ \label{tlk/extdash}
+}
+
+\leijutlk{
+ \begin{tabular}{llll}
+ \toprule
+ \ots{Lähde} & \ots{Tavutus}
+ & \ots{Lähde} & \ots{Tavutus} \\
+ \cmidrule(r){1-2}
+ \cmidrule(l){3-4}
+ \koodi{matka-aika}
+ & matka-\tavukohta aika
+ & \koodi{Oulu--Rovaniemi}
+ & Oulu--\tavukohta Rovaniemi \\
+ \koodi{matka\komento{-/}aika}
+ & mat\tavukohta ka-\tavukohta ai\tavukohta ka
+ & \koodi{Oulu\komento{--}Rovaniemi}
+ & Ou\tavukohta lu--\tavukohta Ro\tavukohta va\tavukohta
+ nie\tavukohta mi \\
+ \koodi{matka\komento{=/}aika}
+ & mat\tavukohta ka-ai\tavukohta ka
+ & \koodi{Oulu\komento{==}Rovaniemi}
+ & Ou\tavukohta lu--Ro\tavukohta va\tavukohta
+ nie\tavukohta mi \\
+ \koodi{matka-}
+ & matka-
+ & \koodi{-aika}
+ & -\tavukohta aika \\
+ \koodi{matka\komento{-/}}
+ & mat\tavukohta ka-
+ & \koodi{\komento{=/}aika}
+ & -ai\tavukohta ka \\
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Texin ja \paketti{extdash}-paketin komentojen vertailua}
+ \label{tlk/extdash-vertailu}
+}
+
+On tärkeää huomioida, että \paketti{extdash}\-/paketin komennot ovat
+todellakin normaaleja komentoja. Se tarkoittaa, että komennon jälkeiset
+sanavälit syödään pois. Tämä asia saattaa unohtua seuraavanlaisessa
+tilanteessa, jossa käytetään tavutuksen sallivaa yhdysmerkkikomentoa:
+
+\komentoi{-/}
+\begin{koodilohkosis}
+matka\-/ ja aika\-/arvio
+\end{koodilohkosis}
+
+\begin{tulossis}
+ matka\-/ ja aika\-/arvio
+\end{tulossis}
+
+\noindent
+Ensimmäisen yhdysmerkkikomennon jälkeinen sanaväli hävisi, ja syntyi
+virheellinen sana \emph{matka-ja}. Sanavälin saa säilymään, kun
+kirjoittaa komennon perään aaltosuljeparin tai kenoviivan ja sanavälin.
+
+\komentoi{-/}
+\begin{koodilohkosis}
+matka\-/{} ja aika\-/arvio \\
+matka\-/\ ja aika\-/arvio
+\end{koodilohkosis}
+
+\begin{tulossis}
+ matka\-/{} ja aika\-/arvio \\
+ matka\-/\ ja aika\-/arvio
+\end{tulossis}
+
+\subsection{Tavutus sanan reunasta}
+
+Asetukset \komento{lefthyphenmin}\komentojatko{~N} ja
+\komento{righthyphenmin}\komentojatko{~N} vaikuttavat tavutukseen sanan
+reunoissa. Argumentti \koodi{N} on positiivinen kokonaisluku, ja se
+määrittelee, kuinka monta merkkiä vähintään sanan vasemmasta tai
+oikeasta reunasta pidetään yhdessä. Oletusarvot ovat kielikohtaisia ja
+määritellään \paketti{polyglossia}\-/{} ja \paketti{babel}\-/paketeissa.
+Suomen kielessä kumpikin asetus on kaksi (2) merkkiä.
+
+Nämä asetukset alustetaan kielikohtaisiin oletusarvoihin aina, kun
+kieliasetukset tulevat voimaan. Näin on esimerkiksi dokumentin
+aloittavan \ymparistox{document}\-/ ympäristön alussa ja aina kielen
+vaihtuessa. Jos asetuksia haluaa muuttaa, täytyy omat muutokset tehdä
+aina edellä mainittujen asioiden jälkeen. Toisaalta vielä kätevämpää on
+sisällyttää omat asetukset kielikohtaisiin alustuskomentoihin. Sillä
+tavoin omat asetukset tulevat voimaan automaattisesti kielen vaihtuessa.
+
+\komentoi{addto}
+\komentoi{captionsfinnish}
+\komentoi{lefthyphenmin}
+\komentoi{righthyphenmin}
+\begin{koodilohkosis}
+\addto{\captionsfinnish}{
+ \lefthyphenmin 3
+ \righthyphenmin 3
+}
+\end{koodilohkosis}
+
+\noindent
+Edellisessä esimerkissä oleva komento \komento{addto} on
+\paketti{polyglossia}\-/{} ja \paketti{babel}\-/ paketin ominaisuus,
+jolla lisätään omia komentoja kielikohtaisiin asetuksiin. Tässä
+esimerkissä käsitellään suomen kielen asetuksia
+(\komento{captionsfinnish}). Komento täytyy suorittaa lähdedokumentin
+esittelyosassa.
+
+\subsection{Muita tavutusasetuksia ja -vinkkejä}
+\label{luku/tavutus-muut}
+
+Aiemmin mainittu \paketti{extdash}\-/paketti sisältää tavutuksen
+hallintaan liittyviä välimerkkejä, mutta sellaisia on myös
+kielipaketeissa \paketti{polyglossia} ja \paketti{babel}. Kielipakettien
+englanninkielisissä ohjekirjoissa niitä kutsutaan nimellä
+\englantik{short\-hands}.
+
+\paketti{babel}\-/paketti tuo suomen kieleen sitovan, tavutuksen
+sallivan yhdysmerkin \koodi{\textquotedbl\=/}, joka toimii samoin kuin
+\paketti{extdash}\-/paketin komento \komento{=/}. Lisäksi on
+tavutusvihje (\koodi{\textquotedbl\textquotedbl}), joka ei tee
+yhdysmerkkiä tavutuskohtaan. Sitä voi käyttää joidenkin teknisten
+ilmausten tavutusvihjeenä, jotta ilmaus säilyy täsmälleen samanlaisena
+myös rivien katkaisemisessa. \paketti{babel}\-/paketin toiminnot
+vaihtelevat eri kielten välillä.
+
+\paketti{polyglossia}\-/pakettiin saa samat lisätoiminnot ja eräitä
+muitakin, kun paketin lataa käyttämällä valitsinta
+\koodi{babel\-short\-hands}. Edellä mainittujen ''Baabelin lyhenteiden''
+lisäksi tulee yhdysmerkki \koodi{\textquotedbl\textasciitilde}, joka on
+sitova ja samalla kaiken tavutuksen estävä yhdysmerkki. Tälle merkille
+ei ole vastinetta \paketti{extdash}\-/paketissa. Pari muutakin
+lainausmerkillä alkavaa, tavutukseen liittyvää merkkiä on mukana.
+
+Varsinainen tavutuksen peruskomento on \komentom{discretionary}, joka
+mahdollistaa omanlaisten tavutuskohtien määrittelyn. Komento
+kirjoitetaan sanassa juuri siihen kohtaan, johon tavutuskohta halutaan.
+Komennolle annetaan kolme argumenttia järjestyksessä seuraavasti:
+
+\begin{nluetelma}
+\item katkaisutilanteessa rivin loppuun ladottavat merkit
+\item katkaisutilanteessa seuraavan rivin alkuun ladottavat merkit
+\item katkaisemattomaan sanaan ladottavat merkit.
+\end{nluetelma}
+
+\noindent
+Normaali tavutuskohta sanaan \emph{tavu} määriteltäisiin alla olevan
+esimerkin tavoin:
+
+\komentoi{discretionary}
+\begin{koodilohkosis}
+ta\discretionary{-}{}{}vu
+\end{koodilohkosis}
+
+\noindent
+Edellisessä esimerkissä komennon ensimmäinen argumentti on yhdysmerkki,
+koska rivin loppuun tietenkin halutaan yhdysmerkki silloin, kun sana
+katkaistaan tästä kohdasta. Toinen argumentti on tyhjä, koska seuraavan
+rivin alkuun ei kirjoiteta suomen kielessä mitään ylimääräistä. Myös
+kolmas argumentti on tyhjä, koska katkaisemattomaan sanaan ei haluta
+mitään merkkiä tavujen väliin.
+
+\komento{discretionary}\-/komennolla voi luoda myös tavutuskohtia,
+joihin ei ilmesty yhdysmerkkiä eikä mitään muutakaan merkkiä
+katkaisutilanteessa. Se saadaan aikaan jättämällä kaikki argumentit
+tyhjäksi. Tällainen sopii tavutusvihjeeksi teknisiin ilmauksiin, joihin
+ei selvyyden vuoksi haluta mitään ylimääräisiä merkkejä edes sanan
+katkaisutilanteessa.
+
+\komentoi{discretionary}
+\begin{koodilohkosis}
+\discretionary{}{}{}
+\end{koodilohkosis}
+
+\noindent
+Joissakin kielissä sanan katkaiseminen yhdysmerkin kohdalta vaatii, että
+rivin loppuun kirjoitetaan yksi yhdysmerkki ja seuraavan rivin alkuun
+toinen. Näin ilmaistaan, että sanassa on pysyvä yhdysmerkki eikä vain
+väliaikaisesti katkaisun merkkinä. Tällaisia kieliä varten saattaa
+kielipaketissa (tai muualla) olla omat yhdysmerkkitoiminnot, mutta
+edellä kuvatun tavutuskohdan saa myös seuraavalla tavalla:
+
+\komentoi{discretionary}
+\begin{koodilohkosis}
+\discretionary{-}{-}{-}
+\end{koodilohkosis}
+
+\noindent
+Tavutuksen suunnittelussa ja tutkimisessa voi auttaa
+\pakettictan{showhyphens}\-/ paketti, jonka lataamalla kaikki
+tavutuskohdat tulevat näkyviin. Dokumentin kaikkien sanojen
+tavutuskohtiin piirretään ohut punainen pystyviiva. Tämä paketti
+hyödyntää Lualatex\-/kääntäjän ominaisuuksia, eikä se siis toimi muiden
+kääntäjien kanssa.
+
+\subsection{Suomen kielen tavutus}
+
+Texin kirjainyhdistelmiin perustuvat säännöt eivät yksinään riitä suomen
+kieleen, ja esimerkiksi yhdyssanojen rajakohdat tuottavat usein
+ongelmia. Sana \emph{alku\-osa} katkaistaan sääntöjen mukaan kohdista
+\emph{al-kuo-sa}. Se on kyllä oikein tavurakenteen kannalta mutta
+käytännössä ongelmallinen. Tässä ei ole kyse \emph{uo}\-/diftongista,
+vaan yhdyssanan rajalla on myös tavutuskohta (\emph{al-ku-o-sa}).
+Lisäksi sanaa ei saa katkaista siten, että siitä jää yksittäinen kirjain
+eri riville (\emph{o-sa}).
+
+Parasta olisi katkaista suomen kielen yhdyssanat vain yhdysosien välistä
+(\emph{alku-osa}). Muualtakin voi katkaista (\emph{al-ku-osa}), kunhan
+sanasta eikä sen yhdysosasta ei jää yksittäinen kirjain eri riville.
+Mielellään ei katkaista myöskään kahden vokaalin välistä, jos ne
+kuuluvat samaan sanaan (\emph{kau-emmin}). Joskus halutaan välttää myös
+niin sanottuja orpotavuja eli sitä, että tekstikappaleen viimeiselle
+riville jää vain yksi tavu.
+
+Käytännössä siis suomenkielinen teksti ja hyvä typografia vaativat
+välillä tavutusvihjeiden kirjoittamista. Yhdyssanojen osien väliin
+tarvitaan tavutusvihje silloin, kun jälkimmäinen osa alkaa vokaalilla
+tai useammalla kuin yhdellä konsonantilla. Joitakin tällaisia tapauksia
+Tex osaa tavuttaa oikein ilman tavutusvihjeitäkin, mutta etukäteen sitä
+ei tiedä, ellei ole kokemusta.
+
+\komentoi{-}
+\begin{koodilohkosis}
+alku\-osa pusku\-traktori
+\end{koodilohkosis}
+
+\noindent
+Yhdysmerkin tai ajatusviivan sisältävät pitkät yhdyssanat voivat vaatia
+tavutuskohtien lisäämistä, koska Texin yhdysmerkki ja ajatusviivat
+estävät tavutuksen muualta kuin näiden merkkien jälkeen. Ilman
+tavutuskohtien lisäämistä Texillä ei ehkä ole riittävästi vaihtoehtoja
+tekstikappaleen rivittämiseen. Voi syntyä liian suuria sanavälejä, tai
+joistakin riveistä tulee ylipitkiä, eli ne yltävät marginaalin puolelle.
+
+Tavutuskohtia voi lisätä sopiviin kohtiin omilla tavutusvihjeillä
+(\komento{-}). Vaihtoehtoisesti kaikki yleisten tavutussääntöjen
+mukaiset tavutuskohdat saa käyttöön \paketti{extdash}\-/paketin
+komennoilla (taulukko \ref{tlk/extdash}). Seuraavassa esimerkissä on
+tavutuksen hallintaa sanalle \emph{Molo\-tov--Ribben\-trop-sopi\-mus}:
+
+\komentoi{-}
+\komentoi{--}
+\komentoi{-/}
+\begin{koodilohkosis}
+Molo\-tov--Ribben\-trop-sopi\-mus % tavutusvihjeet
+Molotov\--Ribben\-trop\-/sopimus % tavutuksen sallivat välimerkit
+\end{koodilohkosis}
+
+\noindent
+\komento{discretionary}\-/komentoa (luku \ref{luku/tavutus-muut}) voi
+hyödyntää suomen kielen sanoissa silloin, kun niissä on heittomerkki
+erottamassa kahta tavurajan molemmin puolin olevaa samaa vokaalia,
+esimerkiksi sanoissa \emph{vaa'an} ja \emph{liu'uttaa}. Normaalisti Tex
+ei katkaise heittomerkin kohdalta lainkaan, eikä se olisi suomen
+kielessä suositeltavaakaan, koska vokaalien välistä ei mielellään
+katkaista sanaa. Jos tavutuksen kuitenkin haluaa myös heittomerkin
+kohdalle, täytyy huolehtia, että tavutustilanteessa heittomerkki poistuu
+ja sen paikalle tulee yhdysmerkki rivin loppuun. Sanan \emph{vaa'an}
+voisi siis kirjoittaa seuraavalla tavalla:
+
+\komentoi{discretionary}
+\begin{koodilohkosis}
+vaa\discretionary{-}{}{'}an
+\end{koodilohkosis}
+
+\noindent
+Komennon kolmas argumentti on heittomerkki, koska se pitää latoa
+tavurajalle silloin, kun sanaa ei katkaista tästä kohdasta. Mikäli
+tällaisia tarvitsee paljon, on järkevää määritellä sitä varten
+yksinkertaisempi komento, jota sitten käytetään sanoissa heittomerkin
+sijasta.
+
+\komentoi{discretionary}
+\begin{koodilohkosis}
+\newcommand{\hm}{\discretionary{-}{}{'}}
+vaa\hm an
+\end{koodilohkosis}
+
+\noindent
+Suomen kielessä käytetään heittomerkkiä myös taivutuspäätteen, liitteen
+tai johtimen edellä silloin, kun sanavartalon kirjoitusasu päättyy
+konsonanttiin mutta ääntöasu vokaaliin, esimerkiksi \emph{show'ssa}.
+Näissä tilanteissa ei ole kyse tavurajasta vaan morfeemirajasta eli
+merkityksellisten osien rajakohdasta. Tavurajakin voi sattua samaan
+paikkaan, mutta tavutettaessa heittomerkki säilyy: \emph{show'-hun}.%
+\footnote{Asiaa ei yleensä mainita kielenhuolto\-/oppaissa. Tieto
+ perustuu Kielikello\-/lehden 2/2006 artikkeliin:
+ \kulmaurl{https://www.kielikello.fi/-/lainausmerkit-}. Viittauspäivä
+ 6.7.2020.} Mikäli tällainen tavutuskohta halutaan mukaan, käytetään
+sanassa tavallista tavutusvihjettä: \koodi{show'}\komento{-}\koodi{hun}.
+Mieluummin ei kuitenkaan katkaista sanoja heittomerkin kohdalta.
+
+\subsection{Tavutus pois päältä}
+
+Tavutuksen voi kytkeä kokonaan pois päältä \paketti{polyglossia}\-/
+kielipaketin komennolla \komentom{disablehyphenation}. Tavutuksen saa
+takaisin päälle komennolla \komento{enablehyphenation}.
+
+Toinen vaihtoehto on käyttää fontin asetusta \koodi{Hyphen\-Char=\katk
+ None} kirjainperheen määrittelyn yhteydessä. Oletuksena tavutus on
+pois päältä tasalevyisestä fontista, eli esimerkiksi \komento{texttt}\-/
+komennon argumenttina olevaa tekstiä ei tavuteta. Fontteja ja niiden
+asetuksia käsitellään luvussa \ref{luku/kirjaintyypit}.
+
+Käytännössä tavutus menee pois päältä myös silloin, kun tekstikappaleet
+tasaa vain vasempaan reunaan eli tekee oikealle liehureunan komennolla
+\komento{raggedright}. Tekstikappaleiden tasaamista ja palstan muotoa
+käsitellään luvussa \ref{luku/kappaleen-tasaus}.
diff --git a/info/kaytannollista-latexia/luku-erikoiset.tex b/info/kaytannollista-latexia/luku-erikoiset.tex
new file mode 100644
index 0000000000..5807e21d8f
--- /dev/null
+++ b/info/kaytannollista-latexia/luku-erikoiset.tex
@@ -0,0 +1,589 @@
+% Tekijä: Teemu Likonen <tlikonen@iki.fi>
+% Lisenssi: Creative Commons Nimeä-JaaSamoin 4.0 Kansainvälinen (CC BY-SA 4.0)
+% https://creativecommons.org/licenses/by-sa/4.0/legalcode.fi
+
+\chapter{Erikoisdokumentit}
+
+Kaikki dokumentit ja painotuotteet eivät ole samanlaista tekstivirtaa,
+joka koostuu jäsennellystä rakenteesta, väliotsikoista ynnä muusta
+sellaisesta. Tässä luvussa käsitellään dokumentteja, jotka vaativat
+osittain toisenlaista tekniikkaa kuin luvussa \ref{luku/rakenne} on
+käsitelty.
+
+\section{Esitysgrafiikka}
+\label{luku/esitysgrafiikka}
+
+Esitelmien ja muiden puhe\-/ esitysten tukena käytetään usein
+esitysgrafiikkaohjelmia kuten \englanti{Microsoft Powerpointia} tai
+\englanti{Libreoffice Impressiä}. Myös Latex sopii esitysgrafiikan
+tekemiseen, ja se voi olla osaavissa käsissä jopa kaikkein nopein ja
+typografisesti tyylikkäin työkalu esitysdiojen tuottamiseen.
+
+Latexin tunnetuin ja monipuolisin esitysgrafiikkajärjestelmä on
+\luokkactan{beamer}, joka on oma dokumenttiluokkansa. Sen ohjekirjassa
+on reilu kaksisataa sivua, joten tässä oppaassa voidaan esitellä vain
+perusasioita, joilla pääsee alkuun.
+
+\begin{esimerkki*}
+ \komentoi{author}
+ \komentoi{date}
+ \komentoi{documentclass}
+ \komentoi{institute}
+ \komentoi{item}
+ \komentoi{maketitle}
+ \komentoi{pause}
+ \komentoi{section}
+ \komentoi{setdefaultlanguage}
+ \komentoi{title}
+ \komentoi{usepackage}
+ \luokkai{beamer}
+ \pakettii{hyperref}
+ \pakettii{polyglossia}
+ \ymparistoi{enumerate}
+ \ymparistoi{frame}
+
+\begin{koodilohko}
+\documentclass[aspectratio=169,t]{beamer}
+\usepackage{polyglossia} \setdefaultlanguage{finnish}
+\usepackage{hyperref}
+
+\title{Esitysgrafiikkaa Latexilla}
+\author{Teppo Tekijä}
+\institute{Ladontatieteiden tiedekunta}
+\date{13.9.2021}
+
+\begin{document}
+
+\section{Otsikkodia}
+
+\begin{frame}
+ \maketitle
+\end{frame}
+
+\section{Ensimmäinen väliotsikko}
+
+\begin{frame}{Pääotsikko}{Alaotsikko}
+
+ \pause Seuraavassa luetellaan jotakin: \pause
+
+ \begin{enumerate}
+ \item ensimmäinen \pause
+ \item toinen \pause
+ \item kolmas
+ \end{enumerate}
+
+\end{frame}
+
+\section{Toinen väliotsikko}
+
+\begin{frame}[c]
+
+ Sisältö on keskitetty pystysuunnassa.
+
+\end{frame}
+
+\end{document}
+\end{koodilohko}
+
+ \caption{\luokka{beamer}\-/ dokumenttiluokan avulla tehdyn
+ diaesityksen runko}
+ \label{esim/beamer-runko}
+\end{esimerkki*}
+
+\subsection{Diaesityksen rakentaminen}
+
+Esimerkissä \ref{esim/beamer-runko} on kokonainen Latexin lähdetiedosto
+ja diaesityksen runko. Dokumenttiluokan \luokka{beamer} lataamisen
+yhteydessä (rivi~1) määritellään valitsimella \koodi{aspectratio}, mitkä
+ovat diojen mittasuhteet. Tässä esimerkissä arvoksi annetaan
+\koodi{169}, joka tarkoittaa leveyden ja korkeuden suhdetta 16:9.
+Oletusarvo on \koodi{43} eli kuvasuhde 4:3. Muita mahdollisia arvoja
+ovat esimerkiksi \koodi{1610} (16:10) ja \koodi{54} (5:4).
+
+Esimerkin ensimmäisellä rivillä oleva toinen valitsin \koodi{t} tulee
+englannin kielen sanasta \englantik{top}, ja tässä se tarkoittaa, että
+diojen sisältö sijoitetaan dian yläreunaan. Oletusasetus on \koodi{c}
+(\englanti{center}), joka keskittää dian sisällön pystysuunnassa. Tämän
+asetuksen voi muuttaa kuhunkin diaan käyttämällä \ymparisto{frame}\-/
+ympäristön valinnaista argumenttia, kuten esimerkin rivillä 34 on tehty.
+
+Riveillä 5--8 määritellään dokumentin perustiedot normaaliin tapaan
+(\ref{luku/dokumentin-perustiedot}), mutta lisänä perus Latexiin on
+\komento{institute}\-/ komento, jolla voi määritellä tekijän edustaman
+laitoksen. Nämä perustiedot ladotaan näkyviin vasta
+\komento{maketitle}\-/ komennolla, joka on esimerkin rivillä~15.
+
+Jokainen yksittäinen sivu eli dia täytyy kirjoittaa \ymparisto{frame}\-/
+ympäristön sisään. Ympäristö siis aloittaa aina puhtaan sivun.
+Ympäristön alussa voi olla aaltosulkeissa sivun pääotsikko ja toisissa
+aaltosulkeissa alaotsikko. Esimerkin rivillä 20 on tehty juuri näin.
+Toisen tai molemmat otsikot voi jättää poiskin.
+
+Sivun eli \ymparisto{frame}\-/ ympäristön sisällä voi olla tavallista
+tekstiä ja käyttää suunnilleen normaaleja Latexin komentoja. Esimerkissä
+\ref{esim/beamer-runko} on käytetty muutaman kerran \komento{pause}\-/
+komentoa, joka tekee esitykseen tauon. Käytännössä se jakaa sivun
+sisällön erillisiksi pdf\-/ sivuiksi, ja siten sisällön voi paljastaa
+yleisölle vaihe vaiheelta. Esimerkin riveillä 24--28 käytetään luetelmaa
+eli \ymparisto{enumerate}. Se toimii suunnilleen samoin kuin perus
+Latexin vastaava ympäristö (luku \ref{luku/luetelma-perus}), mutta
+\luokka{beamer}\-/ versiossa on hieman enemmän ominaisuuksia.
+
+Tästä esimerkistä puuttuu hyödyllinen \ymparisto{block}\-/ ympäristö,
+jolla saa dian sisälle pienen väliotsikon ja siihen kuuluvan
+tekstikokonaisuuden. Otsikon teksti annetaan ympäristön argumentissa:
+
+\ymparistoi{block}
+\begin{koodilohkosis}
+\begin{block}{Väliotsikko}
+ ...
+\end{block}
+\end{koodilohkosis}
+
+\noindent
+Otsikkokomennot \komento{chapter}, \komento{section},
+\komento{subsection} ym. täytyy kirjoittaa \ymparisto{frame}\-/
+ympäristöjen ulkopuolelle. \luokka{beamer}\-/ luokassa otsikkokomennot
+eivät lado mitään itse dokumenttiin, vaan ne ainoastaan muodostavat
+pdf\-/ tiedoston sisällysluettelon. Tosin sisällysluettelon kaltaista
+rakennetietoa on mahdollista saada näkyviin itse diojen reunoillekin.
+Niiden tarkoituksena on helpottaa esimerkiksi pitkän diaesityksen
+seuraamista ja jäsentämistä. Näistä ominaisuuksista voi lukea lisää
+\luokka{beamer}\-/ luokan ohjekirjasta.
+
+Tämän luvun ohjeilla saa rakennettua selkeitä perussisältöisiä
+diaesityksiä. Dioihin voi lisätä kuvatiedostoja tai vektorigrafiikkaa
+normaalin Latexin tavoin eli luvun \ref{luku/grafiikka} ohjeilla.
+Palstoja ei kuitenkaan kannata toteuttaa luvun \ref{luku/palstat}
+keinoilla vaan \luokka{beamer}\-/ luokan oman \ymparisto{columns}\-/
+ympäristön avulla. Siihen ja kaikkeen muuhunkin saa apua
+dokumenttiluokan omasta ohjekirjasta.
+
+\subsection{Ulkoasuteemat}
+
+\luokka{beamer}\-/ dokumenttiluokka sisältää valmiita ulkoasuteemoja eli
+ulkoasuun vaikuttavia asetusten kokonaisuuksia. Käyttämällä valmista
+teemaa saa helposti käyttöönsä jonkun henkilön suunnitteleman tyylikkään
+kokonaisuuden.
+
+Korkeimman tason teemojen valintakomento on \komento{usetheme}. Sillä
+valitaan teema, joka voi määritellä vähän kaikkea diaesityksen ulkoasuun
+liittyvää: fontit, värit, sisällön asettelua ja dian reunoille
+ladottavaa lisätietoa. Alemmantasoisilla teemakomennoilla valitaan vain
+vain jonkin pienemmän osa\-/alueen teema. Esimerkiksi komennoilla
+\komento{usecolortheme} ja \komento{usefonttheme} valitaan vain väri-
+tai fonttiteema.
+
+Fontit tai kirjainperheet sinänsä määritellään ja otetaan käyttöön
+samalla tavalla kuin Latexissa muutenkin (luku
+\ref{luku/kirjaintyypit}), mutta teema voi määritellä, mitä
+kirjainperhettä tai \=/leikkausta käytetään esimerkiksi diojen
+otsikoissa tai muissa tilanteisssa. Näiden asetusten muuttaminen voi
+vaatia \luokka{beamer}\-/ luokan omia komentoja, joista annetaan tietoa
+luvussa \ref{luku/beamer-asetuksia}.
+
+Alemmantasoisia teemakomentoja ovat myös \komento{useinnertheme} ja
+\komento{useoutertheme}. Niillä vaikutetaan erilaisiin diojen
+sisältöelementtien (\englanti{inner}) ulkoasuun ja dian reunoille
+(\englanti{outer}) ladottavaan lisätietoon.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\midrule \komento{#1} & #2 \\}
+ \providecommand{\teema}{}
+ \renewcommand{\teema}[2][,]{\mbox{\koodi{#2}#1}}
+
+ \begin{tabularx}{\linewidth}{lL}
+ \toprule
+ \ots{Komento} & \ots{Valmiita teemoja} \\
+ \rivi{usetheme}{
+ \teema{default}
+ \teema{boxes}
+ \teema{Bergen}
+ \teema{Boadilla}
+ \teema{Madrid}
+ \teema{AnnArbor}
+ \teema{CambridgeUS}
+ \teema{EastLansing}
+ \teema{Pittsburgh}
+ \teema{Rochester}
+ \teema{Antibes}
+ \teema{JuanLesPins}
+ \teema{Montpellier}
+ \teema{Berkeley}
+ \teema{PaloAlto}
+ \teema{Goettingen}
+ \teema{Marburg}
+ \teema{Hannover}
+ \teema{Berlin}
+ \teema{Ilmenau}
+ \teema{Dresden}
+ \teema{Darmstadt}
+ \teema{Frankfurt}
+ \teema{Singapore}
+ \teema{Szeged}
+ \teema{Copenhagen}
+ \teema{Luebeck}
+ \teema{Malmoe}
+ \teema[]{Warsaw}
+ }
+
+ \rivi{usecolortheme}{
+ \teema{default}
+ \teema{structure}
+ \teema{sidebartab}
+ \teema{albatross}
+ \teema{beetle}
+ \teema{crane}
+ \teema{dove}
+ \teema{fly}
+ \teema{monarca}
+ \teema{seagull}
+ \teema{wolverine}
+ \teema{beaver}
+ \teema{spruce}
+ \teema{lily}
+ \teema{orchid}
+ \teema{rose}
+ \teema{whale}
+ \teema{seahorse}
+ \teema{dolphin}
+ \teema[]{seahorse}
+ }
+
+ \rivi{usefonttheme}{
+ \teema{default}
+ \teema{serif}
+ \teema{structurebold}
+ \teema{structureitalicserif}
+ \teema[]{structuresmallcapsserif}
+ }
+
+ \rivi{useinnertheme}{
+ \teema{default}
+ \teema{circles}
+ \teema{rectangles}
+ \teema{rounded}
+ \teema[]{inmargin}
+ }
+
+ \rivi{useoutertheme}{
+ \teema{default}
+ \teema{infolines}
+ \teema{miniframes}
+ \teema{smoothbars}
+ \teema{sidebar}
+ \teema{split}
+ \teema{shadow}
+ \teema{tree}
+ \teema[]{smoothtree}
+ }
+ \bottomrule
+ \end{tabularx}
+}{
+ \caption{\luokka{beamer}\-/ luokan teemanvalintakomennot ja valmiita
+ teemoja}
+ \label{tlk/usetheme}
+}
+
+Taulukkoon \ref{tlk/usetheme} on koottu \luokka{beamer}\-/ luokan
+teemakomennot ja valmiita teemoja. Taulukon ensimmäisessä sarakkeessa
+ovat teeman valintakomennot ja toisessa sarakkeessa teemojen nimiä,
+joita voi antaa komennolle argumentiksi. Ensimmäisenä mainittu
+\koodi{default}\-/ teema on käytössä oletuksena. Teemat otetaan käyttöön
+kirjoittamalla lähdedokumentin esittelyosaan teemakomentoja, esimerkiksi
+seuraavalla tavalla:
+
+\komentoi{usetheme}
+\komentoi{usecolortheme}
+\komentoi{usefonttheme}
+\begin{koodilohkosis}
+\usetheme{Bergen}
+\usecolortheme{albatross}
+\usefonttheme{serif}
+\end{koodilohkosis}
+
+\noindent
+Teemanvalintakomennoille voi antaa hakasulkeissa valinnaisen argumentin,
+joka sijoitetaan ensimmäiseksi eli ennen pakollista teeman nimeä.
+Valinnaisen argumentin avulla määritetään kyseisen teeman asetuksia, jos
+teema sellaisia tukee. Asetukset ovat täysin teemakohtaisia, ja niistä
+voi lukea lisää dokumenttiluokan ohjekirjasta. Seuraavassa on
+yleisluontoinen esimerkki:
+
+\komentoi{usetheme}
+\komentoi{useoutertheme}
+\begin{koodilohkosis}
+\usetheme[valitsin]{teeman nimi}
+\useoutertheme[valitsin=arvo]{teeman nimi}
+\end{koodilohkosis}
+
+\noindent
+Fonttiteema \koodi{serif} vaihtaa koko diaesityksen kirjainperheeksi
+antiikvan. Oletuksena olevaa groteskia (\englanti{sans serif}) ei siis
+käytetä enää missään. \koodi{serif}\-/ teema sisältää kuitenkin muutaman
+valitsimen, jolla tähän voi tehdä pieniä hyödyllisiä poikkeuksia.
+Valitsimia on koottu taulukkoon \ref{tlk/beamer-serif-teema}, ja niitä
+voi antaa useampia kerralla. Seuraava esimerkki asettaa groteskin
+suuriin elementteihin eli otsikoihin ja pieniin elementteihin eli dian
+reunojen mahdollisiin lisätietoihin. Muualla käytetään antiikvaa.
+
+\komentoi{usefonttheme}
+\begin{koodilohkosis}
+\usefonttheme[stillsansseriflarge, stillsansserifsmall]{serif}
+\end{koodilohkosis}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\koodi{#1} & #2 \\}
+
+ \begin{tabularx}{\linewidth}{lL}
+ \toprule
+ \ots{Valitsin} & \ots{Merkitys} \\
+ \midrule
+ \rivi{stillsansseriflarge}{suuret elementit eli otsikot käyttävät
+ groteskifonttia}
+ \rivi{stillsansserifsmall}{pienet elementit kuten dian reuna\-/
+ alueiden lisätiedot käyttävät groteskia}
+ \rivi{stillsansseriftext}{normaali teksti groteskilla}
+ \rivi{stillsansserifmath}{matematiikkatilassa groteski}
+ \bottomrule
+ \end{tabularx}
+}{
+ \caption{\luokka{beamer}\-/ luokan \koodi{serif}\-/ fonttiteeman
+ asetusvalitsimia}
+ \label{tlk/beamer-serif-teema}
+}
+
+\subsection{Muita asetuksia}
+\label{luku/beamer-asetuksia}
+
+Jos haluaa vaikuttaa \luokka{beamer}\-/ dokumenttien otsikoiden tai
+muiden rakenteellisten osien fontteihin ja väreihin, täytyy käyttää
+dokumenttiluokan omia komentoja. Niiden käyttöä neuvotaan tässä
+alaluvussa. Sen sijaan diojen sisällä väliaikaiset kirjaintyypin tai
+\=/leikkauksen muutokset tehdään samalla tavalla kuin Latexissa
+muutenkin. Fonttien tekniikkaa käsitellään luvussa
+\ref{luku/kirjaintyypit} ja tekstin korostamisen typografiaa luvussa
+\ref{luku/korostus}.
+
+\luokka{beamer}\-/ luokan erityisten tekstielementtien kuten otsikoiden
+fonttiin voi vaikuttaa komennolla \komento{setbeamerfont}. Sen
+ensimmäinen argumentti on tekstielementin nimi ja toinen argumentti
+sisältää fonttiasetukset. Esimerkiksi seuraava komento muuttaa
+aloitusdian (\komento{maketitle}) otsikon kirjainperheen ja
+\=/leikkauksen:
+
+\komentoi{setbeamerfont}
+\begin{koodilohkosis}
+\setbeamerfont{title}{family=\rmfamily, series=\bfseries,
+ shape=\itshape, size=\Huge}
+\end{koodilohkosis}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\koodi{#1} & #2 \\}
+
+ \begin{tabular}{ll}
+ \toprule
+ \ots{Tekstielementti} & \ots{Merkitys} \\
+ \midrule
+ \rivi{title}{aloitusdian otsikko (\komento{maketitle})}
+ \rivi{frametitle}{diojen otsikot}
+ \rivi{framesubtitle}{diojen alaotsikot}
+ \rivi{blocktitle}{\ymparisto{block}\-/ ympäristön otsikot}
+ \rivi{normal text}{normaali teksti diojen sisällä}
+ \rivi{footnote}{alaviitteet}
+ \rivi{item}{luetelmien luetelmamerkit}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{\luokka{beamer}\-/ luokan tekstielementtejä. Elementtien
+ nimiä käytetään esimerkiksi komentojen \komento{setbeamerfont} ja
+ \komento{setbeamercolor} kanssa}
+ \label{tlk/beamer-tekstielementtejä}
+}
+
+\noindent
+Aloitusdian otsikko on tekstielementti nimeltä \koodi{title}, ja siksi
+se oli edellisen komennon ensimmäisenä argumenttina. Muita oleellisia
+tekstielementtejä on koottu taulukkoon
+\ref{tlk/beamer-tekstielementtejä}.
+
+Tekstielementtien väreihin vaikutetaan komennolla
+\komento{setbeamerfont}, joka toimii lähes samalla tavalla kuin edellä
+esitelty \komento{setbeamerfont}. Värin asettamisessa käytetään
+valitsimia \koodi{fg} ja \koodi{bg}, joista ensin mainittu vaihtaa
+varsinaisen värin (\englanti{foreground}) ja jälkimmäinen taustavärin
+(\englanti{background}). Seuraavassa esimerkissä vaihdetaan diojen
+otsikon teksti valkeaksi ja tausta siniseksi:
+
+\komentoi{setbeamercolor}
+\begin{koodilohkosis}
+\setbeamercolor{frametitle}{fg=white, bg=blue}
+\end{koodilohkosis}
+
+\noindent
+Värien nimien täytyy olla ennalta määriteltyjä. Perusvärit on määritelty
+valmiiksi, mutta lisää värejä voi määritellä ohjeilla, joita kerrotaan
+luvussa \ref{luku/korostus-värit}.
+
+Oletuksena luetelmaympäristöt \ymparisto{itemize} ja
+\ymparisto{enumerate} latovat luetelmamerkit eri värillä kuin normaalin
+tekstin. Väri riippuu käytetystä väriteemasta (\komento{usecolortheme}).
+Jos haluaa, että luetelmamerkit ovat samalla värillä kuin normaali
+teksti, kannattaa käyttää seuraavan esimerkin komentoa:
+
+\komentoi{setbeamercolor}
+\begin{koodilohkosis}
+\setbeamercolor{item}{parent={normal text}}
+\end{koodilohkosis}
+
+\noindent
+Edellisessä esimerkissä viitataan \koodi{item}\-/ nimiseen
+tekstielementtiin, joka tarkoittaa luetelmamerkkejä. Valitsin
+\koodi{parent} tarkoittaa, että väri peritään toiselta
+tekstielementiltä, tässä tapauksessa normaalilta tekstiltä
+(\koodi{\englanti{normal text}}). Toki tässäkin voi käyttää valitsimia
+\koodi{fg} ja~\koodi{bg}.
+
+Normaalin tekstin (\koodi{normal text}) taustaväri tarkoittaa koko dian
+tekstialueen taustaväriä. Seuraavassa on käytännön esimerkki, joka
+muuttaa diojen otsikon taustan kirkkaan vihreäksi (70\,\%) ja
+tekstialueen taustan vaalean vihreäksi (30\,\%).
+
+\komentoi{setbeamercolor}
+\begin{koodilohkosis}
+\setbeamercolor{frametitle} {fg=black, bg=green!90}
+\setbeamercolor{normal text}{fg=black, bg=green!30}
+\end{koodilohkosis}
+
+\noindent
+Numeroimattomien luetelmien eli \ymparisto{itemize}\-/ ympäristön
+luetelmamerkki on \luokka{beamer}\-/ dokumenttiluokassa oletuksena
+kolmionmuotoinen, mutta asetusta voi muuttaa komennolla
+\komento{setbeamertemplate}. Tällä komennolla tehdään sekalaisia diojen
+asetuksia, joista annetaan tässä yhteydessä vain pari esimerkkiä.
+Luetelmamerkki vaihdetaan seuraavan esimerkin komennoilla.
+
+\komentoi{setbeamertemplate}
+\begin{koodilohkosis}
+\setbeamertemplate{itemize item}[circle] % perustaso
+\setbeamertemplate{itemize subitem}[square] % toinen taso
+\setbeamertemplate{itemize subsubitem}[triangle] % kolmas taso
+\end{koodilohkosis}
+
+\noindent
+Vielä monipuolisemmin voi luetelmamerkkeihin vaikuttaa, kun vaihtaa
+hakasulkeissa olevan argumentin tilalle aaltosulkeet. Tällaiseen
+argumenttiin voi kirjoittaa suunnilleen mitä hyvänsä Latex\-/ komentoja,
+joilla luetelmamerkki tuotetaan. Seuraavassa esimerkissä tätä voimakasta
+komentomuotoa käytetään maltillisesti pelkästään ajatusviivan
+tuottamiseen.
+
+\komentoi{setbeamertemplate}
+\begin{koodilohkosis}
+\setbeamertemplate{itemize item}{--}
+\end{koodilohkosis}
+
+\noindent
+Samalla \komento{setbeamertemplate}\-/ komennolla voi asettaa myös
+diojen oikeaan alareunaan ladottaviin navigointisymboleihin. Tässä
+yhteydessä ei käsitellä niitä sen syvällisemmin, mutta
+navigointisymbolien poistaminen onnistuu helposti seuraavalla
+komennolla:
+
+\komentoi{setbeamertemplate}
+\begin{koodilohkosis}
+\setbeamertemplate{navigation symbols}{}
+\end{koodilohkosis}
+
+\section{Kirjeet}
+\label{luku/kirjeet}
+
+Latexin \luokka{letter}\-/ dokumenttiluokka on tarkoitettu kirjeiden
+latomiseen. Tyylillisesti se soveltuu ehkä paremmin virallisiin
+kirjeisiin kuin henkilökohtaisiin. Myös joukkojakelukirjeiden tekemiseen
+se voi olla käytännöllinen, koska tietokoneohjelman avulla voi helposti
+tuottaa Latex\-/ koodia eli lähes samanlaisia kirjeitä eri
+vastaanottajille.
+
+\begin{esimerkki*}
+ \komentoi{address}
+ \komentoi{cc}
+ \komentoi{closing}
+ \komentoi{documentclass}
+ \komentoi{encl}
+ \komentoi{makelabels}
+ \komentoi{opening}
+ \komentoi{ps}
+ \komentoi{signature}
+ \komentoi{usepackage}
+ \luokkai{letter}
+ \ymparistoi{letter}
+
+\begin{koodilohko}
+\documentclass{letter}
+\usepackage[a4paper]{geometry}
+\usepackage{polyglossia}
+\setdefaultlanguage{finnish}
+
+\address{Liisa Lähettäjä \\ Katuosoite 1 \\ 00000 Kaupunki}
+\signature{Liisa Lähettäjä}
+
+\makelabels
+
+\begin{document}
+
+\begin{letter}{Virpi Vastaanottaja \\ Tiennimi 3 \\ 99999 Kunta}
+
+ \opening{Hei!}
+
+ Tässä kirjeessä ei ole kovin mielenkiintoista sisältöä, mutta tähän
+ kohtaan se kirjoitettaisiin.
+
+ \closing{Terveisin}
+
+ \ps{Jk. Tässä on kirjeen jälkikirjoitus.}
+
+ \cc{Mauno Muuhenkilö}
+ \encl{lippu, lappu, paperi}
+
+\end{letter}
+
+\end{document}
+\end{koodilohko}
+
+ \caption{Latexin \luokka{letter}\-/ dokumenttiluokka on tarkoitettu
+ kirjeiden latomiseen}
+ \label{esim/letter}
+\end{esimerkki*}
+
+Esimerkissä \ref{esim/letter} on yhden kirjeen runko ja oleelliset
+komennot. Dokumentin esittelyosassa olevalla \komento{address}\-/
+komennolla määritellään lähettäjän nimi ja osoitetiedot. Ne ladotaan
+jokaisen kirjeen alkuun. Myös komennolla \komento{signature} ilmaistaan
+lähettäjän nimi, tarkemmin allekirjoitus, joka ladotaan kirjeen loppuun.
+Komento \komento{makelabels} aiheuttaa sen, että kaikkien kirjeiden
+jälkeen ladotaan sivu (tai useampia), jossa ovat kaikkien
+vastaanottajien osoitetiedot. Tämä on tarkoitettu osoitetarrojen
+tulostamiseen.
+
+Varsinainen kirjeen sisältö toteutetaan \ymparisto{letter}\-/ ympäristön
+avulla. Ympäristölle annetaan yksi argumentti, jossa on kyseisen kirjeen
+vastaanottajan nimi ja osoitetiedot. Itse kirje alkaa
+\komento{opening}\-/ komennolla, jolla ilmaistaan tervehdys tai muu
+kirjeen aloitussanat.
+
+Kirjeen lopussa \komento{closing}\-/ komennolla on sopivaa ilmaista
+lopputoivotus tai muu vastaava. Lähettäjän nimi ladotaan sen jälkeen
+automaattisesti, jos lähettäjä on ilmaistu aiemmin
+\komento{signature}\-/ komennolla. Mahdollisen jälkikirjoituksen voi
+ilmaista komennolla \komento{ps}, kirjeen jakelutietoja komennolla
+\komento{cc} ja liitteet komennolla \komento{encl}.
+
+Yksi Latex\-/ lähdedokumentti voi sisältää useita \ymparisto{letter}\-/
+ympäristöjä, ja jokainen niistä muodostaa erillisen, uudelta sivulta
+alkavan kirjeen. Kaikkiin kirjeisiin ladotaan sama lähettäjä, ellei
+lähettäjätietoja välillä vaihda \komento{address}\-/\ ja
+\komento{signature}\-/ komennoilla.
diff --git a/info/kaytannollista-latexia/luku-esipuhe.tex b/info/kaytannollista-latexia/luku-esipuhe.tex
new file mode 100644
index 0000000000..f21b8cd4d8
--- /dev/null
+++ b/info/kaytannollista-latexia/luku-esipuhe.tex
@@ -0,0 +1,47 @@
+% Tekijä: Teemu Likonen <tlikonen@iki.fi>
+% Lisenssi: Creative Commons Nimeä-JaaSamoin 4.0 Kansainvälinen (CC BY-SA 4.0)
+% https://creativecommons.org/licenses/by-sa/4.0/legalcode.fi
+
+\chapter{Esipuhe}
+
+Tex ja Latex kehitettiin alun perin parantamaan tietokoneavusteista
+tekstin latomista. Ohjelmat syntyivät 1970\-/ luvun lopulla ja 1980\-/
+luvun alkupuolella eli ajalla, jolloin tietokoneilla ei vielä kovin
+hyvin osattu tuottaa laadukasta typografiaa ja painotuotteita. Texin
+alkuperäinen luoja on Donald Knuth, ja Latexin kehitti Leslie Lamport.
+
+Texin ja Latexin myötä tietokonetypografia parani: tekstieditorin ja
+merkintäkielen avulla kirjoittaja pystyi varsin helposti tuottamaan
+hyvää jälkeä niin kuin typografian ja ladonnan ammattilaiset aikoinaan.
+Varsinkin akateemisten tekstien tuottamisessa Latex sai vankan
+jalansijan. Kirjoittaja keskittyy lähinnä sisältöön, ja
+tietokoneohjelmat hoitavat taittamisen eli ulkoasun suunnittelun (Latex)
+ja lopullisen dokumentin latomisen (Tex). Typografinen ammattitaito on
+ohjelmoitu sisään näihin tietokoneohjelmiin.
+
+Sitten tulivat tekstinkäsittelyohjelmat, taitto\-/ ohjelmat ja uusi
+käsite \textsc{wy\-si\-wyg} eli \englantik{what you see is what you
+ get}. Suoraan tietokoneen ruudulta eli graafisesta tietokoneohjelmasta
+näki lopullisen painotuotteen sellaisenaan. Mikä sen helpompaa? Jokainen
+kirjoittaja oli nyt samassa hetkessä myös latoja, joka heittelee
+kirjakkeita tietokoneen ruudulle peräkkäin: sanoiksi, riveiksi,
+palstoiksi ja lopulta valmiiksi dokumentiksi. Tekstien parissa
+työskentely helpottui, mutta typografiaa tämä kehitys ei parantanut,
+koska yhä useammat kirjoittajat saivat vastuulleen myös ulkoasun
+suunnittelun ja lopullisten dokumenttien valmistuksen. Vuosisatojen
+aikana kehittynyt typografinen osaaminen ei enää sisältynyt
+tietokoneohjelmaan.
+
+Tässä tilanteessa olemme edelleenkin: lähes jokainen kirjoittaja vastaa
+itse niin sisällöstä kuin typografiastakin eli lopullisesta ulkoasusta.
+Jokainen voi olla tekstinsä julkaisija. Visuaalisten
+tekstinkäsittely\-/\ ja taitto\-/ ohjelmien yleistyminen ei kuitenkaan
+lopettanut Latexin tarinaa. Latexin kehitys ei jäänyt 1980\-/ luvulle,
+vaan sen ympärillä tapahtuu jatkuvasti edelleenkin. Esimerkiksi
+nykyaikainen fonttitekniikka ja tietokoneiden laajat merkistöt ovat myös
+Latexin käyttäjän arkipäivää.
+
+Jos siis typografia, laadukkaat julkaisut ja niihin liittyvä tekniikka
+kiinnostavat, on Latexilla varmasti paljon annettavaa nykyajan
+kirjoittajalle. Toivottavasti tästä oppaasta on apua tutustumismatkassa
+-- ja sen jälkeenkin. Tervetuloa mukaan!
diff --git a/info/kaytannollista-latexia/luku-merkintakieli.tex b/info/kaytannollista-latexia/luku-merkintakieli.tex
new file mode 100644
index 0000000000..faebb7087b
--- /dev/null
+++ b/info/kaytannollista-latexia/luku-merkintakieli.tex
@@ -0,0 +1,2235 @@
+% Tekijä: Teemu Likonen <tlikonen@iki.fi>
+% Lisenssi: Creative Commons Nimeä-JaaSamoin 4.0 Kansainvälinen (CC BY-SA 4.0)
+% https://creativecommons.org/licenses/by-sa/4.0/legalcode.fi
+
+\chapter{Merkintäkieli ja perustekniikka}
+
+Latex on merkintäkieli, mikä tarkoittaa, että se sisältää omat tapansa
+dokumentin rakenteen ja sisällön kuvaamiseen. Kaikkea ei kirjoiteta
+lähdedokumenttiin sellaisenaan, vaan täytyy käyttää tiettyjä kielen
+sääntöjen mukaisia merkintätapoja tai komentoja. Tässä luvussa
+käsitellään merkintäkielen perusasioita, joita on tarpeen ymmärtää ennen
+kuin tehokkaasti toimia Latexin parissa. Kaikkea ei tarvitse päntätä
+kerralla muistiin, mutta tänne on hyvä palata välillä kertaamaan
+perustekniikkaa.
+
+\section{Merkistö}
+
+Latex\-/dokumenttiin voi kirjoittaa tekstiä Unicode\-/merkistöllä ja sen
+\textsc{utf}\=/8\-/koodauksella, jos kääntäjänä on Unicoden osaava
+ohjelma kuten Lualatex tai Xelatex. Pääasiassa siis merkit kirjoitetaan
+sellaisenaan lähdedokumenttiin, mutta on kuitenkin kaikenlaisia
+poikkeuksia, ja niitä käsitellään tässä alaluvussa.
+
+\subsection{Varatut erikoismerkit}
+
+Muutamalla merkillä on perus Latexissa erikoismerkitys, eikä niitä voi
+käyttää normaalilla tavalla. Merkit ovat seuraavat:
+
+\begin{koodilohkosis}
+% $ ^ _ # & { } ~ \
+\end{koodilohkosis}
+
+\noindent
+Useimmat näistä merkeistä voi suojata erikoismerkitykseltään
+kirjoittamalla niiden eteen kenoviivan (\koodi{\keno}). Tildeä
+(\textasciitilde), sirkumfleksia (\textasciicircum) eikä kenoviivaa
+itseään ei voi suojata pelkän kenoviivan avulla, koska kenoviivan kanssa
+ne muodostavat eräitä muita komentoja. Taulukossa
+\ref{tlk/merkkien-suojaus} on koottuna, kuinka edellä mainitut
+erikoismerkit suojataan eli saadaan ladottua dokumenttiin sellaisenaan.
+
+\leijutlk{
+ \begin{tabular}{cll}
+ \toprule
+ \ots{Merkki} & \multicolumn{2}{l}{\ots{Kirjoittaminen}} \\
+ \midrule
+ \koodi{\%} & \komento{\%} \\
+ \koodi{\$} & \komento{\$} & \komento{textdollar} \\
+ \koodi{\^{}} & \komento{\^{}}\komentoarg{} & \komento{textasciicircum} \\
+ \koodi{\_} & \komento{\_} & \komento{textunderscore} \\
+ \koodi{\#} & \komento{\#} \\
+ \koodi{\&} & \komento{\&} \\
+ \koodi{\{} & \komento{\{} & \komento{textbraceleft} \\
+ \koodi{\}} & \komento{\}} & \komento{textbraceright} \\
+ \koodi{\~{}} & \komento{\~{}}\komentoarg{} & \komento{textasciitilde} \\
+ \koodi{\keno} && \komento{textbackslash} \\
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Varattujen erikoismerkkien kirjoittaminen}
+ \label{tlk/merkkien-suojaus}
+}
+
+Jotkin paketit määrittelevät muitakin erikoismerkkejä. Esimerkiksi
+kieliasetuksiin (luku \ref{luku/kieliasetukset}) liittyvät
+\paketti{polyglossia}\-/{} ja \paketti{babel}\-/paketit voivat
+määritellä pari lainausmerkillä (\koodi{\textquotedbl}) alkavaa,
+tavutuksen hallintaan liittyvää komentoa tai erikoismerkkiä.
+
+\subsection{Sanaväli}
+\label{luku/sanaväli}
+
+Välilyönti, sarkainmerkki ja yksi rivinvaihto ovat kaikki tavallisia
+sanavälejä Latex\-/dokumentissa, ja näillä kolmella on sama merkitys.
+Esimerkiksi rivin lopussa oleva rivinvaihto tarkoittaa samaa kuin
+sanojen välissä oleva välilyönti. Välilyöntejä ja sarkainmerkkejä voi
+kirjoittaa useita peräkkäin, mutta ne ovat sama asia kuin yksi väli.
+
+\begin{koodilohkosis}
+Nämä kaikki
+ ovat vain
+sanoja peräkkäin ja kuuluvat
+ samaan kappaleeseen.
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Nämä kaikki ovat vain sanoja peräkkäin ja kuuluvat samaan
+ kappaleeseen.
+\end{tulossis}
+
+\noindent
+Sanavälien leveys ei ole vakio. Silloin kun tekstipalsta tasataan
+molemmista reunoista -- kuten tämänkin oppaan leipätekstissä \==,
+rivillä olevia sanavälejä venytetään sopivasti, jotta tekstipalstan
+molemmat reunat saadaan tasaiseksi.
+
+Sanavälit eivät kuitenkaan veny loputtomasti, ainakaan
+oletusasetuksilla, koska kovin suuret sanavälit olisivat
+tekstikappaleessa rumia. Jos sanaväleille haluaa antaa
+''hätätilanteissa'' lisää venymisvaraa, täytyy käyttää mittaa
+\mittam{emergencystretch}, jota käsitellään tarkemmin tekstikappaleiden
+yhteydessä luvussa \ref{luku/kappale}. Mittoihin liittyvää tekniikkaa
+käsitellään puolestaan luvussa \ref{luku/mitat}.
+
+Matalatasoinen sanavälejä ja niiden venymistä säätelevä mitta on
+\mittam{spaceskip}, johon voi asettaa haluamansa leveyden ja mahdolliset
+venymisen rajat. Tätä mittaa ei ole suositeltavaa käyttää tavallisen
+tekstin kanssa, mutta se sopii tilanteisiin, joihin tarvitaan hyvin
+poikkeukselliset sanavälit.
+
+\komentoi{setlength}
+\mittai{spaceskip}
+\begin{koodilohkosis}
+\setlength{\spaceskip}{0.8em plus 0.3em minus 0.2em}
+\end{koodilohkosis}
+
+\noindent
+Myös kirjainperheelle voi asettaa oman sanavälikertoimensa fontin
+asetusten \koodi{Word\-Space}\-/valitsimella. Tätä asetusta käsitellään
+fonttien yhteydessä luvussa \ref{luku/fontit-välistys}.
+
+\subsection{Rivinvaihto lähdedokumentissa}
+\label{luku/rivinvaihtomerkit}
+
+Kuten edellä todettiin, lähdedokumentissa olevat rivinvaihdot tulkitaan
+vain sanaväleiksi eivätkä ne vaihda riviä lopullisessa dokumentissa. Jos
+ladottuun dokumenttiin tarvitaan rivinvaihto, kirjoitetaan
+lähdedokumenttiin kaksi kenoviivaa (\komentom{\keno}). Tätä komentoa
+käsitellään tarkemmin tekstikappaleiden yhteydessä luvussa
+\ref{luku/rivinvaihtokomennot}.
+
+On kuitenkin mahdollista saada myös lähdedokumentin rivinvaihdot
+toteutumaan automaattisesti ladotussa tekstissä. Sellainen tila
+kytketään päälle komennolla \komentom{obeycr}; normaaliin tilaan
+palataan taas komennolla \komentom{restorecr}. Näistä komennoista voi
+olla hyötyä väliaikaisesti ja erityistilanteissa, mutta pysyväksi koko
+dokumentin tilaksi \komento{obeycr} ei yleensä sovi.
+
+\subsection{Kappaleen vaihtuminen}
+\label{luku/kappaleen-vaihtuminen}
+
+Tyhjä rivi tarkoittaa kappaleen vaihtumista. Rivi on tyhjä silloin, kun
+se ei sisällä mitään muuta kuin rivinvaihdon tai kun se sisältää vain
+välilyöntejä tai sarkainmerkkejä ja lopuksi rivinvaihdon. Tyhjiä rivejä
+voi olla useita peräkkäin, mutta ne tarkoittavat samaa kuin yksi tyhjä
+rivi. Uuden tekstikappaleen voi aloittaa myös komennolla \komento{par}.
+
+\begin{koodilohkosis}
+Nämä rivit kuuluvat
+samaan kappaleeseen.
+
+Tässä on toinen tekstikappale.
+Nyt ei oteta kantaa siihen, miten
+rivit ja kappaleet muotoillaan.
+\end{koodilohkosis}
+
+\noindent
+Ladotuissa teksteissä uuden tekstikappaleen alkaminen ilmaistaan usein
+sisennetyllä rivillä, mutta sisennyksiä eikä muitakaan muotoiluja ei
+tehdä tekstieditorissa välien avulla. Kappaleiden muotoiluun on omat
+keinonsa, ja niistä käsitellään luvussa \ref{luku/kappale}.
+
+\subsection{Kommentit ja muistiinpanot}
+
+Latex\-/dokumentissa prosentin merkki (\koodi{\%}) on kommenttimerkki,
+jonka jälkeisen rivinosan kääntäjä jättää huomioimatta. Merkki on
+tarkoitettu kirjoittajan omien kommenttien ja muistiinpanojen
+kirjoittamiseen.
+
+\begin{koodilohkosis}
+% Nyt ei tosin ole
+% mitään kommentoitavaa.
+\end{koodilohkosis}
+
+\noindent
+Kommenttimerkki vaikuttaa kääntäjään myös siten, että se syö kaikki
+välilyönnit ja sarkainmerkit, jotka tulevat kyseisen kommentin jälkeen.
+Tämän vuoksi kommenttimerkin avulla voi yhdistää eri riveillä olevan
+tekstin. Seuraava esimerkki tuottaa ladottuna ehjän sanan \emph{Latex}:
+
+\begin{koodilohkosis}
+La% Nämä rivit
+ t% yhdistyvät.
+ ex
+\end{koodilohkosis}
+
+\begin{tulossis}
+ La% Nämä rivit
+ t% yhdistyvät.
+ ex
+\end{tulossis}
+
+\subsection{Aaltosulkeet}
+\label{luku/aaltosulkeet}
+
+Aaltosulkeet \mbox{\koodi{\{\}}} muodostavat eräänlaisen näkymättömän
+ympäristön, jonka sisällä voi olla väliaikaisesti voimassa erilaiset
+asetukset kuin ulkopuolella. Aaltosulkeiden sisällä suoritetut komennot,
+uusien komentojen määrittelyt (luku \ref{luku/komennot}) tai asetetut
+mittojen arvot (luku \ref{luku/mitat}) ovat voimassa vain kyseisen
+ympäristön sisäpuolella. Seuraavassa esimerkissä aaltosulkeilla rajataan
+kursivointikomennon \komento{itshape} vaikutusaluetta.
+
+\begin{koodilohkosis}
+tavallinen {\itshape kursiivi} tavallinen
+\end{koodilohkosis}
+
+\begin{tulossis}
+ tavallinen {\itshape kursiivi} tavallinen
+\end{tulossis}
+
+\subsection{Sitova välilyönti}
+
+Sitova välilyönti on samanlainen tyhjä merkki kuin tavallinenkin
+välilyönti, mutta rivinvaihtoa ei sallita sen kohdalta. Sitovalla
+välilyönnillä kannattaa estää esimerkiksi pienistä osista koostuvan
+ilmauksen hajoaminen eri riveille (esimerkki: \emph{osa~5}). Latexissa
+sitova välilyönti saadaan joko tildemerkillä (\koodi{\textasciitilde})
+tai nimenomaan siihen tarkoitetulla merkillä, jonka Unicode\-/tunnus on
+\uctunnus{u+00a0 no-break space}.
+
+Nämä kaksi eri merkkiä, tilde ja \uctunnus{u+00a0}, toimivat hieman eri
+tavoin. Molemmat estävät rivinvaihdon, mutta tildemerkki sallii välin
+venymisen samalla tavalla kuin tavallinenkin sanaväli sallii (luku
+\ref{luku/sanaväli}). Sen sijaan merkki \uctunnus{u+00a0} on
+vakiolevyinen eikä siis veny muiden sanavälien tapaan. Merkkiä
+\uctunnus{u+00a0} täytyy käyttää ainakin vuorosanaviivan (\==) ja sitä
+seuraavan sanan välissä, koska se väli ei saa venyä.
+
+\subsection{Ohuke}
+\label{luku/ohuke}
+
+Ohuke on tavallista sanaväliä kapeampi väli, ja se tehdään
+komennolla~\komentom{,} (kenoviiva ja pilkku). Ohukkeen leveys Latexissa
+on \murtoluku{1}{6} typografisen neliön leveydestä eli em-mitasta (luku
+\ref{luku/mitat}). Ohuke on tasalevyinen ja sitova, eli se ei veny
+muiden sanavälien tapaan, ja se estää rivinvaihdon. Siksi ohuke sopii
+esimerkiksi pitkien lukujen ja puhelinnumeroiden ryhmittelyyn paremmin
+kun sanaväli.
+
+\komentoi{,}
+\begin{koodilohkosis}
+12\,750\,000
+J.\,R.\,R. Tolkien
+\end{koodilohkosis}
+
+\noindent
+Myös henkilön etunimen alkukirjainten välissä voi käyttää ohuketta, jos
+tavallinen sanaväli vie kirjaimet turhan kauas toisistaan. Sukunimi
+erotetaan kuitenkin aina sanavälillä. Joskus myös päiväyksissä käytetään
+ohuketta järjestysluvun pisteiden jälkeen. Taulukossa \ref{tlk/ohuke}
+vertaillaan sanaväliä, ohuketta ja yhteen kirjoittamista.
+
+\leijutlk{
+ \komentoi{,}
+ \begin{tabular}{lrll}
+ \toprule
+ & \ots{Luku} & \ots{Päiväys} & \ots{Nimi} \\
+ \midrule
+ \otsrivi{Sanaväli} & 12 750 000 & \sout{9. 5. 2020} & J. R. R. Tolkien \\
+ \otsrivi{Ohuke} & 12\,750\,000 & 9.\,5.\,2020 & J.\,R.\,R. Tolkien \\
+ \otsrivi{Yhteen} & 12750000 & 9.5.2020 & \sout{J.R.R. Tolkien} \\
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Sanavälin, ohukkeen ja yhteen kirjoittamisen vertailu. Suomen
+ kielen vastaiset kirjoitusasut on viivattu yli}
+ \label{tlk/ohuke}
+}
+
+\subsection{Lainausmerkit ja heittomerkki}
+\label{luku/lainausmerkit}
+
+Suomalaisessa näppäinasettelussa \textsc{shift} eli vaihtonäppäin ja 2
+tuottaa yleislainausmerkin eli niin sanotun \textsc{ascii}\-/
+lainausmerkin (\textquotedbl), mutta se ei taida olla minkään kielen
+varsinainen lainausmerkki. On siis syytä käyttää oikeita
+lainausmerkkejä, ja se käy Latexissa varsin helposti.
+
+Eri kielissä lainausmerkkikäytännöt ovat erilaiset. Suomen kielessä
+käytetään ''tällaisia'' lainausmerkkejä ja joskus >>tällaisia>>
+kulmalainausmerkkejä. Jos lainauksen sisään tarvitaan lainaus, täytyy
+sisempi lainaus kirjoittaa 'tällaisten' puolilainausmerkkien avulla.
+Yksittäin käytettynä se on nimeltään heittomerkki. Englannin kielessä
+lainauksen alussa ja lopussa on erilainen merkki, ja ``tässä'' siitä
+esimerkki. Samoin on puolilainausmerkin kohdalla: `näin'.
+
+Latexissa voi käyttää Unicode\-/merkistöä ja lähdedokumenttiin voi
+kirjoittaa suoraan ne lainausmerkit, jotka halutaan ladottavaksi, mutta
+edellä mainituille merkeille on myös omat merkintätapansa.
+Näppäimistöltä kirjoitettava yleisheittomerkki (\koodim{'}) tuottaa
+ladottuna automaattisesti oikean kaarevan heittomerkin ('). Kun
+kirjoittaa kaksi heittomerkkiä peräkkäin (\koodim{''}), on
+lopputuloksena yksi kaareva lainausmerkki (''). Kahdella suurempi kuin
+\=/merkillä (\koodim{>>}) saadaan kulmalainausmerkki~(>>).
+
+\begin{koodilohkosis}
+''Lainaus, jonka 'sisällä' on lainaus.'' \\
+>>Lainaus, jonka 'sisällä' on lainaus.>>
+\end{koodilohkosis}
+
+\begin{tulossis}
+ ''Lainaus, jonka 'sisällä' on lainaus.'' \\
+ >>Lainaus, jonka 'sisällä' on lainaus.>>
+\end{tulossis}
+
+\noindent
+Yllä mainitut riittävät suomen kieleen, mutta englantia ja muita kieliä
+varten tarvitaan myös toisinpäin oleva merkki (``), joka tehdään
+kahdella gravisaksentilla (\koodim{``}). Vastaava puolilainausmerkki (`)
+tehdään yhdellä aksentilla (\koodim{`}). Joissakin kielissä käytetään
+erilaisia kulmalainausmerkkejä lainauksen alussa ja lopussa. Vasemmalle
+osoittava merkki (<<) tehdään kahdella pienempi kuin \=/merkillä
+(\koodim{<<}).
+
+Joskus todella halutaan latoa yleislainausmerkki (\textquotedbl) tai
+yleisheittomerkki (\textquotesingle). Ne saadaan komennoilla
+\komentom{textquotedbl} ja \komentom{textquotesingle}. Yksittäinen
+gravisaksentti (\`{}) tehdään komennolla \komento{`}\komentoarg{}.
+Lainausmerkkien merkintätapoja ja komentoja on koottu taulukkoon
+\ref{tlk/erikoismerkit-lainaus}
+(s.~\pageref{tlk/erikoismerkit-lainaus}). Toisaalta kielikohtaiset
+asetukset (luku \ref{luku/kieliasetukset}) voivat tuoda mukanaan myös
+kielikohtaisia keinoja lainausmerkkien kirjoittamiseen.
+
+Edellä kuvatut Latexin omat lainausmerkkien merkintätavat (\koodi{''},
+\koodi{>>} ym.) eli niin sanotut Tex\-/ligatuurit voi kytkeä päälle ja
+pois päältä \paketti{fontspec}\-/pakettiin kuuluvien asetusten avulla.
+Fonteissa on yleensä oletuksena päällä Tex\-/ligatuurit eli asetus
+\koodi{Liga\-tures=\katk TeX}, mutta sen saa poistettua asetuksella
+\koodi{Liga\-tures=\katk TeX\-Reset}. Asetusta muutetaan kirjainperheen
+määrittelyn yhteydessä tai väliaikaisesti komennolla
+\komento{addfontfeatures}.
+
+\komentoi{addfontfeatures}
+\begin{koodilohkosis}
+{\addfontfeatures{Ligatures=TeXReset} `` '' >> '}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ {\addfontfeatures{Ligatures=TeXReset} `` '' >> '}
+\end{tulossis}
+
+\noindent
+Tasalevyisessä fontissa Tex\-/ligatuurit eivät ole päällä oletuksena,
+joten yksittäisissä sanoissa tai lyhyissä ilmauksissa voi estää
+Tex\-/ligatuurit esimerkiksi komennolla \komento{texttt}. Samalla
+tietysti fonttikin vaihtuu. Fontteja käsitellään tarkemmin luvussa
+\ref{luku/kirjaintyypit}.
+
+\komentoi{texttt}
+\begin{koodilohkosis}
+\texttt{`` '' >> '}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \texttt{`` '' >> '}
+\end{tulossis}
+
+\noindent
+Paketti \pakettictan{csquotes} sisältää lainausmerkkeihin liittyviä
+komentoja ja kielikohtaista logiikkaa. Paketissa olevan
+\komentom{enquote}\-/ komennon avulla voi jättää paketin huoleksi, miten
+aloittava ja lopettava lainausmerkki tai ulommat ja sisemmät
+lainausmerkit kirjoitetaan missäkin kielessä. Kielipaketti
+\paketti{polyglossia} tai \paketti{babel} täytyy olla ladattuna.
+
+\komentoi{usepackage}
+\pakettii{polyglossia}
+\pakettii{csquotes}
+\komentoi{setdefaultlanguage}
+\komentoi{enquote}
+\begin{koodilohkosis}
+\usepackage{polyglossia} \setdefaultlanguage{finnish}
+\usepackage[autostyle=true]{csquotes}
+% ...
+\enquote{Lainauksen \enquote{sisällä} lainaus.}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \enquote{Lainauksen \enquote{sisällä} lainaus.}
+\end{tulossis}
+
+\subsection{Yhdysmerkki, ajatusviiva ja miinusmerkki}
+\label{luku/yhdys-ajatus-miinus}
+
+Yhdyssanan osien välissä käytettävä yhdysmerkki on Latexissa tavallinen
+näppäimistöltä saatava yleisyhdysmerkki (\=/). Merkillä on vaikutusta
+myös sanan tavutukseen, josta on tarkempaa tietoa luvussa
+\ref{luku/tavutus}.
+
+Ajatusviivaa tarvitaan esimerkiksi äärikohtien (27--29,
+Oulu--Rova\-niemi), luetelmien, vuorosanojen ja virkkeen irrallisen
+lisäysten merkitseminen. Suomen kielessä käytetään yleensä vain lyhyttä
+ajatusviivaa \mbox{(--)}, joka tehdään Latexissa kahdella peräkkäisellä
+yhdysmerkillä (\koodim{--}). Pitkä ajatusviiva \mbox{(---)} tehdään
+kolmella yhdysmerkillä (\koodim{---}). Ajatusviivat vaikuttavat sanan
+tavutukseen samoin kuin yhdysmerkki.
+
+\begin{koodilohkosis}
+Oulu--Rovaniemi-yhteys
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Oulu--Rovaniemi-yhteys
+\end{tulossis}
+
+\noindent
+Myös Unicoden ajatusviivamerkit \uctunnus{u+2013 en dash} ja
+\uctunnus{u+2014 em dash} toimivat, mutta tavutuksen kannalta ne
+käyttäytyvät eri tavoin Lualatex\-/\ ja Xelatex\-/kääntäjillä.
+Yhteensopivuussyistä on parasta tehdä ajatusviivat Latexin omilla
+merkintätavoilla eikä Unicode\-/merkeillä.
+
+Silloin kun todella täytyy latoa kaksi tai kolme peräkkäistä
+yhdysmerkkiä, voi käyttää tasalevyistä fonttia
+(\komento{texttt}\komentoarg{--}), joka oletuksena kytkee pois Latexin
+ajatusviivatoiminnon. Saman asetuksen saa kyllä mihin tahansa fonttiin,
+kun poistaa fontista niin sanotut Tex\-/ligatuurit asetuksella
+\koodi{Liga\-tures=\katk TeX\-Reset}. Väliaikaisesti asetus tehdään
+seuraavasti:
+
+\komentoi{addfontfeatures}
+\begin{koodilohkosis}
+{\addfontfeatures{Ligatures=TeXReset} -- ---}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ {\addfontfeatures{Ligatures=TeXReset} -- ---}
+\end{tulossis}
+
+\noindent
+Miinusmerkille (−) ei Latexissa ole erityistä merkintätapaa muuten kuin
+matematiikkatilassa (luku \ref{luku/matematiikka}). Tavallisessa
+tekstitilassa lyhyttä ajatusviivaa voi ja saa käyttää myös
+miinusmerkkinä, mutta vielä parempi olisi käyttää varsinaista Unicoden
+miinusmerkkiä \uctunnus{u+2212 minus sign}, koska se on fonteissa
+suunniteltu typografisesti yhteensopivaksi muiden matemaattisten
+merkkien kanssa.
+
+\subsection{Kolme pistettä eli ellipsi}
+
+Ajatuksen katkeamista ja muuta sellaista ilmaisevalle kolmelle pisteelle
+eli ellipsille (\ldots) on oma merkkinsä, ja fontissa se saattaa näyttää
+hieman erilaiselta kuin kolme peräkkäistä pistemerkkiä. Tyypillisesti
+ellipsimerkissä pisteet ovat hieman harvemmassa ja erottuvat toisistaan
+paremmin kuin kolmena erillisenä merkkinä ladotut pisteet. Ellipsi
+tehdään Latexissa komennoilla \komentom{dots}, \komento{ldots},
+\komento{textellipsis} tai Unicode\-/merkillä \uctunnus{u+2026
+ horizontal ellipsis}.
+
+\subsection{Ylä- ja alaindeksi}
+\label{luku/ylä-alaindeksit}
+
+Yläindeksit (a\textsuperscript{2}) tehdään komennolla
+\komentom{textsuperscript} ja alaindeksit (a\textsubscript{2})
+komennolla \komentom{textsubscript}. Oletusasetuksilla Latex toteuttaa
+indeksit mekaanisesti pienentämällä fonttia ja sijoittamalla pienennetyn
+tekstin alas peruslinjan tuntumaan tai ylös gemenalinjan yläpuolelle.%
+\footnote{Katso typografinen viivasto, kuva \ref{kuva/kirjainmitat}
+ sivulla \pageref{kuva/kirjainmitat}.} Lopputulos ei ole typografisesti
+välttämättä kovin hyvä, koska fontin pienentäminen ohentaa samalla
+merkkien viivoja ja ohuimmat hiusviivat voivat lähes kadota.
+
+\englanti{Open Type} \=/fontit sisältävät usein tuen oikeille ylä- ja
+alaindekseille, jotka fontin suunnittelija on toteuttanut. Niitä
+kannattaa käyttää, koska suunnittelija tuntee oman fonttinsa ja saa
+todennäköisesti parempaa jälkeä kuin Latex mekaanisesti. \englanti{Open
+ Type} \=/fonttien indeksit on kätevintä ottaa käyttöön
+\pakettictan{realscripts}\-/ paketin avulla.
+
+Paketti \paketti{realscripts} määrittelee uudelleen Latexin ylä- ja
+alaindeksikomennot, niin että ne ensisijaisesti pyrkivät käyttämään
+\englanti{Open Type} \=/fontin ominaisuutta. Jos käytössä oleva fontti
+ei sisällä haluttujen merkkien ylä- tai alaindeksiä,
+\paketti{realscripts}\-/ paketin komennot käyttävät automaattisesti
+Latexin mekaanista keinoa. Paketti määrittelee pari muutakin hyödyllistä
+komentoa, muun muassa tähdelliset versiot edellä mainituista:
+\komento{textsuperscript*} ja \komento{textsubscript*}. Nämä komennot
+toteuttavat aina mekaanisen ylä- tai alaindeksin eli toimivat kuten
+Latexin alkuperäiset komennot.
+
+\leijutlk{
+ \gemenanum
+ \begin{tabular}{lll}
+ \toprule
+ \ots{Komento}
+ & \ots{\englanti{Open Type}}
+ & \ots{Mekaaninen} \\
+ \midrule
+ \komento{textsuperscript}
+ & \Large x\textsuperscript{ab36}
+ & \Large x\textsuperscript*{ab36} \\
+ \midrule
+ \komento{textsubscript}
+ & \Large H\textsubscript{2}SO\textsubscript{4}
+ & \Large H\textsubscript*{2}SO\textsubscript*{4} \\
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Ylä- ja alaindeksien vertailua. Oikeat Open Type \=/fonttien
+ indeksit saadaan \paketti{realscripts}\-/ paketin avulla. Mekaaninen
+ toteutus perustuu fontin pienentämiseen}
+ \label{tlk/indeksien-vertailu}
+}
+
+Taulukossa \ref{tlk/indeksien-vertailu} vertaillaan oikeita ja
+mekaanisia ylä- ja alaindeksejä. Taulukon esimerkit paljastavat, että
+lopputuloksessa on eroa. Mekaaninen ylä- ja alaindeksitoiminto jättää
+merkit turhan suurikoisiksi mutta saattaa silti ohentaa merkkien viivoja
+liian paljon. Se ei myöskään ymmärrä poistaa gemenanumeroita (3624)
+käytöstä vaan latoo ne sellaisenaan suunnilleen oikeaan paikkaan.
+
+Ylä- ja alaindeksejä käytettäessä on siis syytä ladata
+\paketti{realscripts}\-/ paketti ja käyttää indeksit hallitsevaa
+\englanti{Open Type} \=/fonttia. Fonttien ominaisuuksia voi tutkia
+käyttöjärjestelmän komentotulkissa komennolla \koodi{otfinfo}. Toisaalta
+fonttiin sisältyviä ylä- ja alaindeksejä voi myös kirjoittaa
+Unicode\-/merkistön avulla sellaisenaan. Lopputulos on sama.
+
+\subsection{Tavutusvihje}
+
+Komento \komentom{-} on tavutusvihje, joka neuvoo tavutusalgoritmia
+katkaisemaan sanan tästä kohdasta. Samalla se voi estää sanan
+katkaisemisen muista kohdista.
+
+\begin{koodilohkosis}
+tavutus\-algo\-ritmi
+\end{koodilohkosis}
+
+\noindent
+Myös sanassa olevat yhdysmerkit ja ajatusviivat vaikuttavat sanan
+tavuttamiseen. Perusteellisemmin tavutusta ja sen asetuksia käsitellään
+luvussa \ref{luku/tavutus}.
+
+\subsection{Tarkkeet ja erikoismerkit}
+\label{luku/tarkkeet}
+
+Latexissa on useita komentoja tarkkeellisten kirjainten
+(\'a\,\v{s}\,\c{c}\,\~o) kirjoittamiseen sekä muille merkeille, joita ei
+ehkä ihan helposti saa suoraan näppäimistöltä. Komentoja on koottu
+taulukoihin \ref{tlk/tarkkeet}, \ref{tlk/erikoismerkit-lainaus} ja
+\ref{tlk/erikoismerkit-muut}. Taulukon tarkekomennoissa on käytetty
+a\=/kirjainta esimerkkinä, mutta tarke voi liittyä muihinkin kirjaimiin.
+Merkit voi kirjoittaa Latex\-/lähdedokumenttiin myös sellaisenaan, eli
+näiden komentojen käyttö ei ole välttämätöntä.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[4][]{{\erikoisfontti #3}
+ & \komento{#2}\komentojatko{#1} & #4}
+ \begin{tabular}{*{2}{cll}}
+ \toprule
+ \multicolumn{2}{l}{\ots{Merkki}}
+ & \ots{Merkitys}
+ & \multicolumn{2}{l}{\ots{Merkki}}
+ & \ots{Merkitys} \\
+ \cmidrule(r){1-3}
+ \cmidrule(l){4-6}
+ \rivi[a]{`}{\`a}{gravis}
+ & \rivi{O}{\O}{poikkiviiva-O} \\
+ \rivi[a]{'}{\'a}{akuutti}
+ & \rivi{o}{\o}{poikkiviiva-o} \\
+ \rivi[a]{\^{}}{\^a}{sirkumfleksi}
+ & \rivi{DJ}{\DJ}{poikkiviiva-D} \\
+ \rivi[a]{\~{}}{\~a}{tilde}
+ & \rivi{dj}{\dj}{poikkiviiva-d} \\
+ \rivi[a]{\textquotedbl}{\"a}{treema}
+ & \rivi{DH}{\DH}{versaali-eth} \\
+ \rivi[ a]{H}{\H a}{kaksoisakuutti}
+ & \rivi{dh}{\dh}{gemena-eth} \\
+ \rivi[ a]{r}{\r a}{yläympyrä}
+ & \rivi{NG}{\NG}{versaali-äng} \\
+ \rivi[ a]{v}{\v a}{hattu}
+ & \rivi{ng}{\ng}{gemena-äng} \\
+ \rivi[ a]{u}{\u a}{lyhyysmerkki}
+ & \rivi{SS}{\SS}{versaali kaksois-s} \\
+ \rivi[a]{=}{\=a}{pituusmerkki}
+ & \rivi{ss}{\ss}{gemena kaksois-s} \\
+ \rivi[ a]{b}{\b a}{alaviiva}
+ & \rivi{TH}{\TH}{versaali thorn} \\
+ \rivi[ a]{c}{\c a}{sedilji}
+ & \rivi{th}{\th}{gemena thorn} \\
+ \rivi[a]{.}{\.a}{yläpiste}
+ & \rivi{i}{\i}{pisteetön i} \\
+ \rivi[ a]{d}{\d a}{alapiste}
+ & \rivi{j}{\j}{pisteetön j} \\
+ \rivi[ a]{k}{\k a}{ogonek}
+ & \rivi{AE}{\AE}{AE-ligatuuri} \\
+ % \rivi{t\{ae\}}{\t{ae}}{sidontakaari}
+ &&& \rivi{ae}{\ae}{ae-ligatuuri} \\
+ \rivi{L}{\L}{poikkiviiva-L}
+ & \rivi{OE}{\OE}{OE-ligatuuri} \\
+ \rivi{l}{\l}{poikkiviiva-l}
+ & \rivi{oe}{\oe}{oe-ligatuuri} \\
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Komentoja tarkkeellisten ja muiden kirjainten
+ kirjoittamiseen}
+ \label{tlk/tarkkeet}
+}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[4][]{{\erikoisfontti #2} & \komento{#3} #1 & #4 \\}
+ \begin{tabular}{cll}
+ \toprule
+ \multicolumn{2}{l}{\ots{Merkki ja komennot}} & \ots{Merkitys} \\
+ \midrule
+ \rivi[\koodi{`{}`}]{\textquotedblleft}{textquotedblleft}
+ {vasen lainausmerkki}
+ \rivi[\koodi{'{}'}]{\textquotedblright}{textquotedblright}
+ {oikea lainausmerkki}
+ \rivi{\textquotedbl}{textquotedbl}{yleislainausmerkki (\textsc{ascii})}
+ \rivi[\komento{lq} \koodi{`}]{\textquoteleft}{textquoteleft}
+ {vasen puolilainausmerkki}
+ \rivi[\komento{rq} \koodi{'}]{\textquoteright}{textquoteright}
+ {oikea puolilainausmerkki, heittomerkki}
+ \rivi{\textquotesingle}{textquotesingle}
+ {yleispuolilainausmerkki ja -heittomerkki (\textsc{ascii})}
+ \rivi[\koodi{<{}<}]{\guillemotleft}{guillemotleft}
+ {vasen kulmalainausmerkki}
+ \rivi[\koodi{>{}>}]{\guillemotright}{guillemotright}
+ {oikea kulmalainausmerkki}
+ \rivi{\guilsinglleft}{guilsinglleft}{vasen kulmapuolilainausmerkki}
+ \rivi{\guilsinglright}{guilsinglright}
+ {oikea kulmapuolilainausmerkki}
+ \rivi{\quotedblbase}{quotedblbase}{rivinalinen lainausmerkki}
+ \rivi{\quotesinglbase}{quotesinglbase}{rivinalinen puolilainausmerkki}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Komentoja lainausmerkkien kirjoittamiseen}
+ \label{tlk/erikoismerkit-lainaus}
+}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[4][]{{\erikoisfontti #2} & \komento{#3} #1 & #4 \\}
+ \providecommand{\textbigcirclekorvike}{}
+ \renewcommand{\textbigcirclekorvike}{%
+ \begin{tikzpicture}
+ \draw (0,0) circle [radius=.65ex];
+ \end{tikzpicture}}
+
+ \begin{tabular}{cll}
+ \toprule
+ \multicolumn{2}{l}{\ots{Merkki ja komennot}} & \ots{Merkitys} \\
+ \midrule
+ \rivi[\koodi{--}]{\textendash}{textendash}{lyhyt ajatusviiva}
+ \rivi[\koodi{---}]{\textemdash}{textemdash}{pitkä ajatusviiva}
+ \rivi[\koodi{!`}]{\textexclamdown}{textexclamdown}{yläsalainen huutomerkki}
+ \rivi[\koodi{?`}]{\textquestiondown}{textquestiondown}
+ {ylösalainen kysymysmerkki}
+ \rivi{\textgreater}{textgreater}{suurempi kuin -merkki}
+ \rivi{\textless}{textless}{pienempi kuin -merkki}
+ \rivi[\komento{ldots} \komento{dots}]{\ldots}{textellipsis}
+ {kolme pistettä, ellipsi}
+ \rivi{\texteuro}{texteuro}{euron merkki}
+ \rivi[\komento{pounds}]{\pounds}{textsterling}{punnan merkki}
+ \rivi[\komento{\$}]{\textdollar}{textdollar}{dollarin merkki}
+ \rivi[\komento{S}]{\S}{textsection}{pykälän merkki}
+ \rivi[\komento{P}]{\P}{textparagraph}{kappaleen merkki}
+ \rivi[\komento{copyright}]{\copyright}{textcopyright}{tekijänoikeusmerkki}
+ \rivi{\textregistered}{textregistered}{rekisteröity tavaramerkki}
+ \rivi{\texttrademark}{texttrademark}{tavaramerkki}
+ \rivi[\komento{dag}]{\dag}{textdagger}{risti}
+ \rivi[\komento{ddag}]{\ddag}{textdaggerdbl}{kaksoisristi}
+ \rivi[\komento{\^{}}\komentoarg{}]
+ {\textasciicircum}{textasciicircum}{sirkumfleksi}
+ \rivi[\komento{\~{}}\komentoarg{}]
+ {\textasciitilde}{textasciitilde}{tilde}
+ \rivi{\textasteriskcentered}{textasteriskcentered}
+ {rivinkeskinen asteriski, tähti}
+ \rivi{\textbackslash}{textbackslash}{kenoviiva}
+ \rivi{\textbar}{textbar}{pystyviiva}
+ \rivi{\textbardbl}{textbardbl}{kaksoispystyviiva}
+ \rivi[\komento{\{}]{\textbraceleft}{textbraceleft}{vasen aaltosulje}
+ \rivi[\komento{\}}]{\textbraceright}{textbraceright}{oikea aaltosulje}
+ \rivi{\textbullet}{textbullet}{luetelmaympyrä}
+ \rivi{\textbigcirclekorvike}{textbigcircle}{suuri ympyrä}
+ % \rivi{\textcircled{a}}{textcircled\{\ldots\}}{ympyröity merkki}
+ \rivi{\textleftarrow}{textleftarrow}{nuoli vasemmalle}
+ \rivi{\textrightarrow}{textrightarrow}{nuoli oikealle}
+ \rivi{\textordfeminine}{textordfeminine}
+ {feminiininen järjestysluvun merkki}
+ \rivi{\textordmasculine}{textordmasculine}
+ {maskuliininen järjestysluvun merkki}
+ \rivi{\textperiodcentered}{textperiodcentered}{rivinkeskinen piste}
+ \rivi[\komento{\_}]{\textunderscore}{textunderscore}{alaviiva}
+ \rivi{\textvisiblespace}{textvisiblespace}{näkyvä välilyönti}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Komentoja erikoismerkkien kirjoittamiseen}
+ \label{tlk/erikoismerkit-muut}
+}
+
+Tarke- ja erikoismerkkikomentojen lisäksi on olemassa sekalaisia muita
+komentoja erikoisempien asioiden latomiseen. \marginaali{\TeX}
+\marginaali{\LaTeX} Ladontajärjestelmän logojen kirjoittamiseen on
+komennot \komento{TeX} ja \komento{LaTeX}. Suorakulmioita voi tehdä
+\komento{rule}\-/ komennolla, jolle annetaan argumenteiksi ainakin kaksi
+mittaa: leveys ja korkeus. Myös yksi hakasulkeissa annettu valinnainen
+argumentti on mahdollinen. Sekin on mitta ja ilmaisee, kuinka paljon
+suorakulmiota nostetaan tekstin peruslinjasta. Negatiivinen mitta laskee
+suorakulmiota alaspäin. Latexin mittoja ja mittayksiköitä käsitellään
+luvussa \ref{luku/mitat}.
+
+\komentoi{rule}
+\begin{koodilohkosis}
+\rule{1ex}{1ex} abc \rule{3em}{.5bp} abc \rule[1ex]{3em}{.5bp}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \rule{1ex}{1ex} abc \rule{3em}{.5bp} abc \rule[1ex]{3em}{.5bp}
+\end{tulossis}
+
+\noindent
+Komento \komento{strut} latoo näkymättömän, leveydettömän merkin, jonka
+korkeus on rivikorkeuden eli mitan \mitta{baselineskip} mukainen.
+Komentoa voi tarvita joskus esimerkiksi laatikoiden sisällä (luku
+\ref{luku/laatikot}).
+
+Käytännössä \komento{strut}\-/ komento hyödyntää sisäisesti
+\komento{rule}\-/ komentoa ja latoo sen avulla leveydettömän
+suorakulmion. Tarkemmin sanottuna korkeus eli tekstin peruslinjan
+yläpuolinen osa on 0,7 kertaa \mitta{baselineskip}\-/ mitta ja syvyys
+eli peruslinjan alapuolinen osa on 0,3 kertaa \mitta{baselineskip}.
+
+\komentoi{rule}
+\mittai{baselineskip}
+\begin{koodilohkosis}
+\rule[-0.3\baselineskip]{0bp}{\baselineskip}
+\end{koodilohkosis}
+
+\section{Komennot}
+\label{luku/komennot}
+
+Latexin komennot alkavat kenoviivalla (\koodi{\textbackslash}), jonka
+jälkeen tulee komennon nimi. Nimi koostuu yleensä pienistä tai isoista
+kirjaimista, mutta komento voi koostua myös muista merkeistä.
+
+Komennot voivat ottaa vastaan argumentteja eli lisätietoa, jota komento
+käsittelee ja tarvitsee toimintaansa. Jotkin argumentit voivat olla
+pakollisia ja jotkin valinnaisia. Pakolliset kirjoitetaan
+aaltosulkeisiin \koodi{\{}\ldots\koodi{\}} ja valinnaiset hakasulkeisiin
+\koodi{[}\ldots\koodi{]}.
+
+\begin{koodilohkosis}
+\komento
+\komento{argu}{mentteja}
+\komento[valinnainen]{argu}{mentteja}
+\end{koodilohkosis}
+
+\noindent
+Jos pakolliseen argumenttiin haluaa sisällyttää aaltosulkeen, täytyy sen
+eteen kirjoittaa kenoviiva \komento{\{}~\komento{\}}, tai voi myös
+käyttää taulukossa \ref{tlk/erikoismerkit-muut} mainittuja komentoja
+aaltosulkeiden tuottamiseen. Sama pätee aaltosulkeiden latomiseen
+muutenkin.
+
+Hakasulkeet sen sijaan ladotaan tekstiin normaalisti, eikä niiden kanssa
+käytetä kenoviivaa. Poikkeustilanne on komennon valinnaisen argumentin
+sisällä, koska valinnainen argumentti jo sinänsä kirjoitetaan
+hakasulkeiden sisään. Hakasulkeita ei voi suojata kenoviivalla, koska
+\komento{[} ja \komento{]} ovat jo muuhun tarkoitettuja komentoja:
+niillä luodaan matematiikkatilassa (luku \ref{luku/matematiikka}) oleva
+tekstilohko. Valinnaisen argumentin sisään saa hakasulkeen, kun sen
+kirjoittaa aaltosulkeiden sisään. Esimerkiksi komennon
+\komentox{komento}\komentoargv{\{]\}} valinnaiseksi argumentiksi tulee
+lopulta yksi \koodi{]}-merkki.
+
+Komennon yhteydessä sanavälejä käsitellään hieman poikkeuksellisesti.
+Esimerkiksi komennon nimen perässä olevat sanavälit syödään pois, jos
+komennolle ei anneta yhtään argumenttia. Seuraavassa esimerkissä sana
+\emph{Latex} ladotaan ehjänä, jos vain \komentox{komento} itsessään ei
+kirjoita mitään eikä vaikuta tekstin latomiseen.
+
+\begin{koodilohkosis}
+La\komento tex
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Latex
+\end{tulossis}
+
+\noindent
+Jos täytyy saada komennon nimen jälkeinen sanaväli näkyviin, täytyy
+kirjoittaa komennon nimen perään aaltosulkeet
+(\komentox{komento}\komentoarg{}) tai kenoviiva
+(\komentox{komento}\komentojatko{\keno}).
+
+Komennon nimen ja argumenttien välissä voi olla sanavälejä, ja ne kaikki
+syödään pois. Komennon ja sen argumentit voi siis kirjoittaa vaikka
+seuraavalla tavalla:
+
+\begin{koodilohkosis}
+\komento [valinnainen]
+ {argu-} {mentteja}
+\end{koodilohkosis}
+
+\subsection{Omat komennot ja abstrahointi}
+\label{luku/komennot-abst}
+
+Omien komentojen tärkein tarkoitus on merkintätapojen abstrahointi eli
+teknisen toteutuksen ja yksityiskohtien piilottaminen. Sopiva
+abstrahointi helpottaa lähdedokumentin käsittelemistä.
+
+Esimerkiksi jos kirjoittaa Latexia käsittelevää kirjaa, kannattaa heti
+aluksi luoda komento, jolla merkitään kaikki Latexin komennot. Komennon
+nimi voisi olla vaikka \komentox{komento}, ja sen voisi määritellä
+siten, että se lisää automaattisesti komennon nimen alkuun kenoviivan
+(\keno) ja latoo koko ilmauksen tasalevyisellä kirjainperheellä.
+Seuraavassa on esimerkki tällaisen komennon määrittelemisestä ja
+käytöstä:
+
+\komentoi{newcommand}
+\komentoi{texttt}
+\komentoi{textbackslash}
+\begin{koodilohkosis}
+\newcommand{\komento}[1]{\texttt{\textbackslash #1}}
+
+Komennolla \komento{section} tehdään otsikoita.
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Komennolla \texttt{\textbackslash section} tehdään otsikoita.
+\end{tulossis}
+
+\noindent
+Edellä mainitun komennon määritelmään voi olla tarpeen lisätä myöhemmin
+muitakin asioita. Latexin komentojen nimet ovat suunnilleen englantia,
+ja jos nimen tavuttaa, täytyisi se tehdä englannin sääntöjen mukaisesti.
+Esimerkkinä olleen \komentox{komento}\-/ komennon määritelmässä voisi
+siis vaihtaa myös kielen komennolla \komento{textenglish}.%
+\footnote{Lisätietoa kieliasetuksista voi lukea luvusta
+ \ref{luku/kieliasetukset}.}
+
+Jos ollaan kirjoittamassa laajaa tietoteosta, Latex\-/ komennot halutaan
+ehkä lisätä automaattisesti kirjan lopussa olevaan asiahakemistoon (ks.
+s.~\pageref{luku/asiahakemisto}). Niinpä komennon määritelmään lisätään
+vielä sitäkin varten komento \komento{index}.%
+\footnote{Asiahakemistoja käsitellään luvussa \ref{luku/asiasanat}.}
+Lopulta Latex\-/ komentojen merkitsemiseen tarkoitettu
+\komentox{komento} määriteltäisiin seuraavalla tavalla:
+
+\komentoi{newcommand}
+\komentoi{textbackslash}
+\komentoi{texttt}
+\komentoi{textenglish}
+\komentoi{index}
+\begin{koodilohkosis}
+\newcommand{\komento}[1]{%
+ \texttt{\textbackslash\textenglish{#1}}%
+ \index[komennot]{#1@\texttt{\textbackslash #1}}}
+\end{koodilohkosis}
+
+% Asiahakemistot-luvussa on viittaus tähän lukuun ja maininta
+% \index-komennon sisällyttämisestä toisen komennon määritelmään.
+
+\noindent
+Näin oma \komentox{komento} ilmaisee tiiviisti ja havainnollisesti
+tarkoituksen eli sen, että kyseessä on Latex\-/ komento. Se piilottaa
+monimutkaisen teknisen toteutuksen eli fontin ja kielen vaihtamiseen
+sekä asiahakemistoon liittyvät toiminnot. Lisäksi komennon teknistä
+toteutusta on helppoa muuttaa myöhemmin, koska komennon määrittely on
+vain yhdessä paikassa lähdedokumentin alussa.
+
+\subsection{Komentojen määrittely}
+\label{luku/komennot-määrittely}
+
+Komentojen määrittelyyn on kolme erilaista komentoa, ja niille kaikille
+annetaan samanlaiset argumentit. Komennot ovat seuraavat:
+
+\komentoi{newcommand}
+\komentoi{renewcommand}
+\komentoi{providecommand}
+\begin{koodilohkosis}
+\newcommand {\nimi}[n][oletus]{määritelmä}
+\renewcommand {\nimi}[n][oletus]{määritelmä}
+\providecommand {\nimi}[n][oletus]{määritelmä}
+\end{koodilohkosis}
+
+\noindent
+Ensimmäinen pakollinen argumentti on komennon nimi (\komentox{nimi}), ja
+se voi koostua vain kirjaimista. Komento \komentom{newcommand}
+määrittelee uuden komennon. Mikäli komento on jo olemassa, annetaan
+virheilmoitus. Toinen komento \komentom{renewcommand} määrittelee
+olemassa olevan komennon uudelleen. Se antaa virheilmoituksen, jos
+komentoa ei ollut olemassa. Kolmas komento \komentom{providecommand}
+puolestaan määrittelee uuden komennon vain siinä tapauksessa, että
+sellaista ei ollut ennen olemassa. Se ei anna virheilmoitusta.
+
+Komentojen toinen pakollinen argumentti \koodi{määritelmä} sisältää
+komennon määritelmän eli mitä tahansa tekstiä tai komentoja.
+Suoritusvaiheessa komento ikään kuin vaihdetaan sen määritelmäksi.
+
+\komentoi{newcommand}
+\begin{koodilohkosis}
+\newcommand{\komento}{Minua komennettiin!}
+\komento
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Minua komennettiin!
+\end{tulossis}
+
+\noindent
+Komentojen ensimmäinen valinnainen argumentti \koodi{n} on luku, joka
+kertoo, kuinka monta argumenttia määriteltävä komento käsittelee.
+Määritelmässä voi käyttää parametreja \koodi{\#1}, \koodi{\#2},
+\koodi{\#3} jne., ja ne korvautuvat komennon suoritusvaiheessa
+ensimmäisellä, toisella, kolmannella jne. argumentilla.
+
+\komentoi{newcommand}
+\begin{koodilohkosis}
+\newcommand{\komento}[2]{Sanoit #1 ja #2!}
+\komento{hip}{hei}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Sanoit hip ja hei!
+\end{tulossis}
+
+\noindent
+Toinen valinnainen argumentti \koodi{oletus} -- jos se on mukana --
+kertoo, että määriteltävän komennon ensimmäinen argumentti on
+valinnainen ja että tämä on sen oletusarvo. Oletusarvoa käytetään
+silloin, kun valinnaista argumenttia ei ole annettu.
+
+\komentoi{newcommand}
+\begin{koodilohkosis}
+\newcommand{\komento}[3][tyyppi]{Hei #1, sanoit #2 ja #3!}
+\komento{hip}{hei} \\
+\komento[Leslie]{hip}{hei}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Hei tyyppi, sanoit hip ja hei! \\
+ Hei Leslie, sanoit hip ja hei!
+\end{tulossis}
+
+\noindent
+Joskus yhden komennon määritelmä sisältää komennon
+\komento{renewcommand}, joka sitten määrittelee uudelleen jonkin toisen
+komennon. Silloin parametrit \koodi{\#1}, \koodi{\#2} jne. on
+tarkoitettu ensimmäisen eli uloimman kerroksen käsiteltäväksi. Sisempi
+kerros käyttää parametreja \koodi{\#\#1}, \koodi{\#\#2} jne.
+
+Kaikista kolmesta komentojen määrittelykomennosta on olemassa
+tähdellinen versio eli sellainen, jonka komennon nimen lopussa on tähti
+(\koodi{*}). Latexin komennoissa on tapana, että tähdellinen versio --
+jos sellainen on olemassa -- tarjoaa samaan asiaan jonkin toisenlaisen
+näkökulman.
+
+\komentoi{newcommand*}
+\komentoi{renewcommand*}
+\komentoi{providecommand*}
+\begin{koodilohkosis}
+\newcommand* {\nimi}[n][oletus]{määritelmä}
+\renewcommand* {\nimi}[n][oletus]{määritelmä}
+\providecommand* {\nimi}[n][oletus]{määritelmä}
+\end{koodilohkosis}
+
+\noindent
+Komentojen määrittelyssä tähdelliset versiot toimivat muuten samalla
+tavalla, mutta ne antavat virheilmoituksen, jos komennolle annetut
+argumentit sisältävät enemmän kuin yhden tekstikappaleen. Niinpä
+esimerkin \ref{esim/newcommand} koodi tuottaa käännettäessä virheen.
+
+\begin{esimerkki*}
+ \komentoi{newcommand*}
+\begin{koodilohko}
+\newcommand*{\komento}[1]{Teksti: #1}
+
+\komento{
+ Ensimmäinen tekstikappale.
+
+ Toinen tekstikappale.
+}
+\end{koodilohko}
+ \caption{\komento{newcommand*}\-/ komennolla määritelty komento ei
+ salli argumentteja, joissa on useita tekstikappaleita. Tämä
+ esimerkki tuottaa käännettäessä virheilmoituksen}
+ \label{esim/newcommand}
+\end{esimerkki*}
+
+\komento{newcommand*}\-/komennolla määritelty \komentox{komento} ei siis
+suostu ottamaan vastaan argumentteja, jotka sisältävät kappaleen
+vaihtumisen eli enemmän kuin yhden tekstikappaleen. Tämä voi olla
+hyödyllinen suojausominaisuus.
+
+\subsection{Kestävät ja hauraat komennot}
+\label{luku/komennot-hauraat}
+
+Kaikki Latex\-/ komennot ovat joko kestäviä (\englanti{robust}) tai
+hauraita (\englanti{fragile}). Tällä ei ole yleensä käytännön
+merkitystä, mutta hauraat komennot eivät välttämättä toimi toisen
+komennon argumentissa.
+
+Hauraita komentoja ovat sellaiset, jotka sisältävät tietoa, jota Latex
+kirjoittaa väliaikaistiedostoon ja lukee sieltä takaisin. Kyse on
+esimerkiksi sisällysluetteloon tai muihin automaattisiin luetteloihin
+kirjoitettavasta tiedosta. Hauraita ovat myös rivinvaihdot ja
+valinnaisia argumentteja eli hakasulkeissa annettavia argumentteja
+sisältävät komennot.
+
+Käytännössä ongelmia aiheuttavat esimerkiksi otsikkokomennot
+(\komento{section} ym.) sekä kuvatekstikomento \komento{caption}. Näiden
+argumenttina oleva teksti (ja mahdolliset komennot) kirjoitetaan
+tiedostoon ja ladataan sieltä myöhemmin takaisin. Hauraat komennot eivät
+toimi edellä mainittujen komentojen argumentissa, ja lähdetiedoston
+kääntäminen johtaa virheilmoitukseen. Ongelman voi ainakin joskus
+korjata kirjoittamalla hauraan komennon eteen komennon
+\komento{protect}.
+
+\subsection{Muita vinkkejä}
+
+Komennon viimeistä argumenttia ei välttämättä tarvitse kirjoittaa
+aaltosulkeisiin, jos argumentiksi halutaan vain yksi merkki. Tällaisessa
+tilanteessa komento poimii argumentiksi seuraavan merkin, joka ei ole
+sanaväli.
+
+\komentoi{newcommand}
+\begin{koodilohkosis}
+\newcommand{\x}[1]{Argumentti: <#1>}
+\x abc \\
+\x.abc
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Argumentti: <a>bc \\
+ Argumentti: <.>abc
+\end{tulossis}
+
+\noindent
+Mikäli argumenttina on kenoviivalla alkava komento, sitäkään ei tarvitse
+kirjoittaa aaltosulkeisiin. Latex\-/koodin lukemisen kannalta tällainen
+ei välttämättä ole hyvä käytäntö, koska joskus voi hämärtyä, onko kyse
+kahdesta peräkkäisestä komennosta vai onko toinen komento vain
+argumenttina toiselle.
+
+\komentoi{newcommand}
+\begin{koodilohkosis}
+\newcommand{\x}[1]{Argumentti: <#1>}
+\newcommand{\yyy}{abc}
+\x\yyy
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Argumentti: <abc>
+\end{tulossis}
+
+\noindent
+Tätä merkintätapaa esiintyy jokin verran komentojen määrittelyssä, niin
+että jätetään \komento{newcommand}\-/komennon ensimmäisenä argumenttina
+oleva komennon nimi ilman aaltosulkeita.
+
+\komentoi{newcommand}
+\begin{koodilohkosis}
+\newcommand\yyy{abc}
+\end{koodilohkosis}
+
+\noindent
+Komennon määrittelyssä on välillä hyötyä \komentom{ignorespaces}\-/
+komennosta, joka jättää sanavälit huomioimatta komennon jälkeen. Ilman
+tätä komentoa tulisi seuraavassa esimerkissä sanojen väliin yksi
+välilyönti.
+
+\komentoi{newcommand}
+\komentoi{ignorespaces}
+\begin{koodilohkosis}
+\newcommand{\komento}[1]{#1\ignorespaces}
+\komento{yhdys} sana
+\end{koodilohkosis}
+
+\begin{tulossis}
+ yhdyssana
+\end{tulossis}
+
+\begin{esimerkki*}
+ \komentoi{newcommand}
+ \komentoi{renewcommand}
+\begin{koodilohko}
+\newcommand{\komento}{alkuperäinen}
+\komento
+{%
+ \renewcommand{\komento}{\textit{muutettu}}
+ \komento
+}
+\komento
+\end{koodilohko}
+\begin{tulos}
+ alkuperäinen \textit{muutettu} alkuperäinen
+\end{tulos}
+\caption{Aaltosulkeilla voi rajata komennon määrittelyn
+ vaikutusaluetta}
+\label{esim/aaltosulkeet-rajaaminen}
+\end{esimerkki*}
+
+\noindent
+Aaltosulkeilla (luku \ref{luku/aaltosulkeet}) voi rajata
+komentomäärittelyn vaikutusaluetta. Esimerkin
+\ref{esim/aaltosulkeet-rajaaminen} alussa asetetaan \komentox{komento}
+tiettyyn alkuperäismääritelmään. Aaltosulkeiden sisällä se määritellään
+väliaikaisesti uudestaan. Aaltosulkeilla rajatun ympäristön jälkeen
+komennon uusi määritelmä lakkaa ja komento palautuu alkuperäiseksi.
+
+Monimutkaisiin komentoihin voidaan tarvita ehtorakenteita. Ne saa
+toteutettua \pakettictan{ifthen}\-/ paketin tarjoaman
+\komentom{ifthenelse}\-/ komennon avulla. Se on ohjelmointikielistä
+tuttu ehtorakenne: jos annettu ehtolauseke on tosi, käsitellään
+then\-/haara; muussa tapauksessa käsitellään else-haara.
+
+\section{Ympäristöt}
+\label{luku/ympäristöt}
+
+Ympäristöt ovat rakenteita, joilla on aloittava \komentom{begin}\-/
+komento ja lopettava \komentom{end}\-/ komento sekä nimi. Ympäristöjen
+ajatuksena on, että jokin ominaisuus tai jotkin toiminnot ovat voimassa
+vain ympäristön sisällä ja asiat palautuvat ennalleen ympäristön
+jälkeen. Tässä mielessä ne toimivat samalla tavalla kuin aaltosulkeet
+(luku \ref{luku/aaltosulkeet}). Jos esimerkiksi fonttiasetusta (luku
+\ref{luku/kirjaintyypit}) muuttaa ympäristön sisäpuolella, asetus
+palautuu ympäristön jälkeen samaksi kuin se oli ennen ympäristön alkua.
+Samoin ympäristön sisällä määritellyt komennot ovat voimassa vain
+kyseisessä ympäristössä.
+
+\komentoi{begin}
+\komentoi{end}
+\begin{koodilohkosis}
+\begin{nimi}
+ % ympäristön
+ % vaikutusalue
+\end{nimi}
+\end{koodilohkosis}
+
+\noindent
+Yleisin ympäristö on nimeltään \ymparistom{document}, jonka sisään koko
+dokumentin sisältö kirjoitetaan. Muita ympäristöjä käytetään
+tavallisesta leipätekstistä poikkeavien rakenteiden ilmaisemiseen,
+esimerkiksi luetelmiin ja taulukoihin (luvut \ref{luku/luetelmat} ja
+\ref{luku/taulukot}). Ympäristöjä voi tehdä itsekin mihin hyvänsä
+tarkoitukseen. Niitä määritellään seuraavilla komennoilla:
+
+\komentoi{newenvironment}
+\komentoi{renewenvironment}
+\begin{koodilohkosis}
+\newenvironment {nimi}[n][oletus]{aloitus}{lopetus}
+\renewenvironment {nimi}[n][oletus]{aloitus}{lopetus}
+\end{koodilohkosis}
+
+\noindent
+Komento \komentom{newenvironment} määrittelee uuden ympäristön. Se antaa
+virheilmoituksen, jos samanniminen ympäristö on jo olemassa. Komento
+\komentom{renewenvironment} puolestaan määrittelee uudelleen ympäristön,
+joka on jo olemassa. Se antaa virheilmoituksen, jos ympäristöä ei
+ollutkaan olemassa.
+
+Argumentit ovat lähes samanlaiset kuin komentojen määrittelyssä (luku
+\ref{luku/komennot-määrittely}). Ympäristöjen määrittelykomennoilla on
+kolme pakollista argumenttia: ensimmäinen on ympäristön nimi, toinen on
+ympäristön aloitusmääritelmä (\koodi{aloitus}) ja kolmas on
+lopetusmääritelmä (\koodi{lopetus}).
+
+\komentoi{newenvironment}
+\komentoi{begin}
+\komentoi{end}
+\begin{koodilohkosis}
+\newenvironment{ymp}{Tästä se alkaa.}{Tähän se päättyy.}
+
+\begin{ymp}
+ Ympäristön sisältöä.
+\end{ymp}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Tästä se alkaa. Ympäristön sisältöä. Tähän se päättyy.
+\end{tulossis}
+
+\noindent
+Tavallisesti ympäristön aloitusmääritelmään kirjoitetaan jonkin toisen
+ympäristön aloituskomento sekä mahdollisesti suoritetaan joitakin
+asetuskomentoja. Vastaavasti lopetusmääritelmässä lopetetaan ympäristö
+eli palataan normaaliin tilaan. Tarkoituksena on abstrahoida jokin
+monimutkaisempi kokonaisuus eli tehdä uusi helppokäyttöinen ympäristö, joka
+piilottaa teknisen toteutuksen.
+
+\komentoi{newenvironment}
+\komentoi{begin}
+\komentoi{end}
+\begin{koodilohkosis}
+\newenvironment{ymp}
+{\begin{mahtavuus}
+ \omia\hienoja\asetuksia}
+ {\end{mahtavuus}}
+\end{koodilohkosis}
+
+\noindent
+Omille ympäristölle voi määritellä argumentteja samalla tavalla kuin
+komennoillekin. Ensimmäinen valinnainen argumentti \koodi{n} on luku
+joka kertoo, kuinka monta argumenttia määriteltävä ympäristö käsittelee.
+Ympäristön aloitusmääritelmässä voi argumentteihin viitata parametreilla
+\koodi{\#1}, \koodi{\#2}, \koodi{\#3} jne.
+
+Jos toinen valinnainen argumentti \koodi{oletus} on mukana, se
+ilmaisee, että määriteltävän ympäristön ensimmäinen argumentti on
+valinnainen ja että tämä on sen oletusarvo. Oletusta käytetään silloin,
+kun valinnaista argumenttia ei ole annettu. Argumentit annetaan
+ympäristön aloittavan \komento{begin}\-/ komennon yhteydessä.
+
+\komentoi{begin}
+\komentoi{end}
+\begin{koodilohkosis}
+\begin{ymp}[valinnainen]{argu}{mentteja}
+ % ympäristön
+ % vaikutusalue
+\end{ymp}
+\end{koodilohkosis}
+
+\noindent
+Ympäristön määrittelykomennoille on myös tähdelliset versiot
+\komentom{newenvironment*} ja \komentom{renewenvironment*}. Ne toimivat
+samoin kuin edellä kuvatut tavallisetkin komentoversiot, mutta ne eivät
+salli, että määritellylle ympäristölle annetut argumentit sisältävät
+enemmän kuin yhden tekstikappaleen. Toiminta on siis sama kuin
+komentojenkin määrittelyn tähdellisissä versioissa (luku
+\ref{luku/komennot-määrittely}).
+
+\komentoi{newenvironment*}
+\komentoi{renewenvironment*}
+\begin{koodilohkosis}
+\newenvironment* {nimi}[n][oletus]{aloitus}{lopetus}
+\renewenvironment* {nimi}[n][oletus]{aloitus}{lopetus}
+\end{koodilohkosis}
+
+\begin{esimerkki*}
+ \komentoi{newenvironment}
+ \komentoi{ignorespaces}
+ \komentoi{ignorespacesafterend}
+ \komentoi{begin}
+ \komentoi{end}
+
+\begin{koodilohko}
+\newenvironment{ymp}
+{Yhdys\ignorespaces}
+{esi\ignorespacesafterend}
+
+\begin{ymp}
+ sana% Kommentti poistaa seuraavan sanavälin.
+\end{ymp} merkki.
+\end{koodilohko}
+\begin{tulos}
+ Yhdyssanaesimerkki.
+\end{tulos}
+\caption{Sanavälien käyttäytyminen ympäristöjen yhteydessä. Komennoilla
+ \komento{ignorespaces} ja \komento{ignorespacesafterend} voi poistaa
+ seuraavat sanavälit}
+\label{esim/ignorespacesafterend}
+\end{esimerkki*}
+
+\noindent
+Joskus ympäristöjen määrittelyyn on hyödyllistä sisällyttää komento
+\komentom{ignorespaces}, joka jättää huomioimatta tämän komennon
+jälkeiset sanavälit. Toinen hyödyllinen on
+\komentom{ignorespacesafterend}, joka jättää huomioimatta ympäristön
+lopettavan \komento{end}\-/ komennon jälkeiset sanavälit. Esimerkki
+\ref{esim/ignorespacesafterend} selventää näiden toimintaa.
+
+\section{Mitat}
+\label{luku/mitat}
+
+\subsection{Mittayksiköt}
+
+Koska typografia on pitkälti teksti- ja muiden elementtien sijoittelua,
+tarvitaan sitä varten mittavälineitä. Niinpä Texissäkin on pituusmittoja
+(engl. \emph{length}) ja useita pituuden mittayksiköitä. Taulukkoon
+\ref{tlk/mittayksiköt} on koottu mittayksiköiden lyhenteet ja
+merkitykset. Teknisesti on samantekevää, mitä yksiköitä käyttää, sillä
+ne ovat vain välineitä pituuden ilmaisemiseen. Sisäisesti Tex käyttää
+sp-yksikköä, joka ilmaisee samalla mittojen tarkkuuden: pienin jakamaton
+mitta on 1\,sp (5,36\,nm).
+
+\leijutlk{
+ \begin{tabular}{ll}
+ \toprule
+ \ots{Lyh.} & \ots{Merkitys} \\
+ \midrule
+ bp & piste uudessa pica-järjestelmässä, 1/72 tuumaa, 0,3528 mm \\
+ pt & piste vanhassa pica-järjestelmässä, 1/72,27 tuumaa, 0,3515 mm \\
+ pc & pica eli 12 pt-pistettä \\
+ sp & 1/65536 pt-pistettä (5,36\,nm), Texin sisäisesti käyttämä yksikkö \\
+ dd & piste Didot-järjestelmässä, 0,376 mm \\
+ cc & cicero eli 12 dd-pistettä \\
+ mm & millimetri \\
+ cm & senttimetri \\
+ in & tuuma, 25,4 mm \\
+ ex & nykyisen fontin x-korkeus, perus- ja gemenalinjan etäisyys \\
+ em & typografisen neliön sivun pituus, sama kuin fontin koko \\
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Texin mittayksiköiden lyhenteet ja merkitykset}
+ \label{tlk/mittayksiköt}
+}
+
+Usein tietyt yksiköt ovat vakiintuneet tiettyihin tilanteisiin.
+Esimerkiksi fonttien kokoja ja rivikorkeuksia on tapana mitata
+pistemittojen avulla. Nykyään käytetään lähinnä bp\-/yksikön mukaista
+pistettä, joka tuli käyttöön Post Script \=/standardin myötä vuonna 1984
+ja jota käytetään julkaisuohjelmissa. Sivun mittoja kuten leveyttä,
+korkeutta ja marginaaleja ilmaistaan tavallisesti metrijärjestelmän
+avulla eli senttimetreissä tai millimetreissä.
+
+Latexin mittojen mittaluvuissa desimaalierottimena on piste, ja
+mittayksikön lyhenne kirjoitetaan kiinni mittalukuun. Seuraavassa
+esimerkissä tehdään vaakasuuntaisia ja pystysuuntaisia välejä
+komennoilla \komentom{hspace} ja \komentom{vspace}:
+
+\komentoi{hspace}
+\komentoi{vspace}
+\begin{koodilohkosis}
+Sanat\hspace{1.2cm}hassusti
+\vspace{2mm}
+
+\hspace{1.75em}erillään.
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Sanat\hspace{1.2cm}hassusti \nopagebreak
+ \vspace{2mm}
+
+ \hspace{1.75em}erillään.
+\end{tulossis}
+
+\subsection{Mittakomennot ja typografinen viivasto}
+
+Mittoja tallennetaan eräänlaisiin muuttujiin, jotka näyttävät päällepäin
+komennoilta eli niiden alussa on kenoviiva (\koodi{\keno}) ja sitten
+kirjaimista koostuva nimi. Esimerkiksi mitta \mitta{textwidth} on
+tekstialueen leveys nykyisellä sivulla. Komentomaisesta ulkoasustaan
+huolimatta mittoja ei voi suorittaa komentoina; ne sopivat vain komennon
+argumentiksi, silloin kun tarvitaan mitta.
+
+Uusia mittoja luodaan komennolla \komentom{newlength} ja olemassa olevia
+mittoja asetetaan esimerkiksi komennoilla \komentom{setlength} ja
+\komentom{addtolength}. Omien mittoja on tarpeen luoda silloin, kun
+halutaan määritellä tietynsuuruinen mitta, jota käytetään Latex\-/
+koodissa useita kertoja.
+
+\komentoi{newlength}
+\komentoi{setlength}
+\komentoi{addtolength}
+\begin{koodilohkosis}
+\newlength{\omamitta} % Luodaan mitta.
+\setlength{\omamitta}{2.3em} % Asetetaan mitta.
+\addtolength{\omamitta}{1em} % Lisätään mittaan.
+\addtolength{\omamitta}{-1em} % Vähennetään mitasta.
+\end{koodilohkosis}
+
+\noindent
+Näin luotuja mittoja voi käyttää mittayksiköiden tavoin, eli niille voi
+asettaa eteen kertoimen. Esimerkiksi seuraava \komento{hspace}\-/
+komento luo vaakasuuntaisen välin, jonka pituus on 0,7 kertaa
+\mittax{omamitta}:
+
+\komentoi{hspace}
+\begin{koodilohkosis}
+\hspace{0.7\omamitta}
+\end{koodilohkosis}
+
+\noindent
+Koska vaakasuuntaisten välien tekeminen on typografiassa varsin
+tavallista, on niitä varten olemassa omia komentoja. Typografisen neliön
+levyisen (1\,em) välin voi tehdä komennolla \komentom{quad}. Sen
+puolikkaan (\murtoluku{1}{2}\,em) saa komennolla \komentom{enspace}.
+Ohuke eli \murtoluku{1}{6}\,em-väli tehdään \komentom{,}\-/ komennolla,
+josta on tarkempaa tietoa luvussa \ref{luku/ohuke}.
+
+\leijukuva{
+ \begin{tikzpicture}
+ [viiva/.style={line width=.7bp, densely dotted, color=apuviiva},
+ nuoli/.style={<->, line width=1bp, color=mittanuoli}, xscale=1.1,
+ yscale=1.9, baseline=0pt]
+
+ \node at (.04,.25) {\fontsize{120bp}{120bp}\viivastofontti p};
+
+ \draw [viiva] (-1,.98) rectangle (1,-.5);
+ \draw [viiva] (1,.98) -- (2.25,.98);
+ \draw [viiva] (-1,.02) -- (2.25,.02);
+ \draw [viiva] (1,-.5) -- (2.25,-.5);
+
+ \draw [nuoli] (1.2,.02) -- (1.2,.98);
+ \node at (1.9,.5) [color=mittanuoli] {korkeus};
+
+ \draw [nuoli] (1.2,.02) -- (1.2,-.5);
+ \node at (1.9,-.25) [color=mittanuoli] {syvyys};
+
+ \draw [nuoli] (-1,1.1) -- (1,1.1);
+ \node at (0,1.25) [color=mittanuoli] {leveys};
+
+ \node at (3.13,1.64) {ylälinja};
+ \node at (3.13,1.44) {versaalilinja};
+ \node at (3.13,.98) {gemenalinja};
+ \node at (3.13,.02) {peruslinja};
+ \node at (3.13,-.5) {alalinja};
+
+ \node at (6.52,.74) {\fontsize{120bp}{120bp}\viivastofontti H};
+
+ \draw [viiva] (5.05,1.47) rectangle (7.95,.02);
+ \draw [viiva] (5.05,.02) -- (4,.02);
+ \draw [viiva] (5.05,1.47) -- (4,1.47);
+ \draw [viiva] (7.95,1.62) -- (4,1.62);
+ \draw [viiva] (7.95,.98) -- (4,.98);
+
+ \draw [nuoli] (4.86,.02) -- (4.86,1.47);
+ \node at (4.1,.5) [color=mittanuoli] {korkeus};
+
+ \draw [nuoli] (5.05,-.1) -- (7.95,-.1);
+ \node at (6.5,-.3) [color=mittanuoli] {leveys};
+ \end{tikzpicture}
+}{
+ \caption{Kirjainten mitat ja typografinen viivasto}
+ \label{kuva/kirjainmitat}
+}
+
+Latex sisältää myös komennot mittojen poimimiseen kirjaimista tai muista
+merkeistä. Mittoja on kolme: leveys (\englanti{width}), korkeus
+(\englanti{height}) ja syvyys (\englanti{depth}). Leveys on merkin
+viemä tila leveyssuunnassa. Korkeus tarkoittaa merkin korkeutta
+peruslinjan yläpuolella, ja syvyys on merkin korkeus peruslinjan
+alapuolella. Kuva \ref{kuva/kirjainmitat} havainnollistaa näitä kolmea
+mittaa sekä typografista viivastoa.
+
+Gemenalinja sijaitsee gemenakirjainten eli pienaakkosten korkeudella.
+Peruslinjan ja gemenalinjan etäisyys on fontin x\=/korkeus (1\,ex).
+Optisen vaikutelman vuoksi gemenalinja ei tarkoita ehdotonta
+gemenakirjainten ylintä kohtaa. Esimerkiksi p\=/kirjaimen yläpääte ja
+silmukan yläkaari voivat yltää hieman gemenalinjan yläpuolelle ja
+silmukan alakaari peruslinjan alapuolelle. Fonttien suunnittelijat
+tekevät tällaisia optisia korjauksia, jotta kirjainten hahmot näyttävät
+yhtä korkeilta ja tasapainoisilta yhdessä.
+
+Versaalilinja sijaitsee versaalikirjainten eli suuraakkosten
+korkeudella. Jotkin kirjaimet voivat yltää hieman versaalilinjan
+yläpuolellekin. Esimerkiksi joidenkin fonttien Hk\=/kirjaimia
+vertailemalla näkee, että k\=/kirjaimen yläpääte yltää H\=/kirjaimen eli
+versaalilinjan yläpuolelle, ylälinjan tuntumaan. Myös tarkemerkit (luku
+\ref{luku/tarkkeet}) voivat sijaita versaalilinjan yläpuolella.
+
+Merkkien leveyden, korkeuden ja syvyyden voi mitata seuraavan esimerkin
+komennoilla. Esimerkin ensimmäisellä rivillä luodaan uudet mitat
+\mittax{leveys}, \mittax{korkeus} ja \mittax{syvyys}, joihin sitten
+tallennetaan merkkien mitat.
+
+\komentoi{newlength}
+\komentoi{settowidth}
+\komentoi{settoheight}
+\komentoi{settodepth}
+\begin{koodilohkosis}
+\newlength{\leveys} \newlength{\korkeus} \newlength{\syvyys}
+\settowidth{\leveys}{abc} % merkkien ”abc” leveys
+\settoheight{\korkeus}{H} % merkin ”H” korkeus
+\settodepth{\syvyys}{p} % merkin ”p” syvyys
+\end{koodilohkosis}
+
+\noindent
+Mitat saa näkyviin kirjoittamalla mitan eteen komennon \komentom{the}.
+Näin mitan pituus ladotaan dokumenttiin. Yksikkönä on typografinen piste
+(pt).
+
+\komentoi{the}
+\begin{koodilohkosis}
+Leveys: \the\leveys, korkeus: \the\korkeus, syvyys: \the\syvyys.
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Leveys: 14.62865pt, korkeus: 6.81897pt, syvyys: 2.4662pt.
+\end{tulossis}
+
+\noindent
+Aiemmin mainituista optisista korjauksista johtuu, että gemenakirjaimet
+eivät ole välttämättä täsmälleen samankorkuisia. Gemena\=/x asettuu
+perus- ja gemenalinjojen väliin, mutta gemena\=/o voi yltää aavistuksen
+verran linjojen ylä- ja alapuolelle. Ihmisen silmään ne näyttävät yhtä
+korkeilta.
+
+\subsection{Venyvät mitat ja välit}
+\label{luku/venyvät-mitat}
+
+Edellä on puhuttu vain kiinteistä mitoista, mutta Latex tuntee myös
+venyvät mitat. Niiden ajatuksena on, että Latexille voi antaa luvan
+kutistaa tai venyttää mittaa tietyissä rajoissa. Venyviä mittoja
+käytettään usein pystysuuntaisissa väleissä, esimerkiksi väliotsikon
+edellä ja jälkeen tai tekstikappaleiden välissä. Latex pystyy latomaan
+sivut yleensä paremman näköiseksi, kun sille antaa venyvien mittojen
+avulla hieman säätövaraa. Alla on esimerkki venyvän kappalevälin
+(\mitta{parskip}) määrittämisestä. Samalla asetetaan kappaleen
+ensimmäisen rivin sisennys (\mitta{parindent}) nollaan (\koodi{0em}).
+
+\komentoi{setlength}
+\mittai{parskip}
+\mittai{parindent}
+\begin{koodilohkosis}
+\setlength{\parskip}{2ex plus 0.2ex minus 0.1ex}
+\setlength{\parindent}{0em}
+\end{koodilohkosis}
+
+\noindent
+Venyvissä mitoissa mainitaan ensin normaali pituus ja sitten sanoilla
+\koodi{plus} ja \koodi{minus} ilmaistaan, kuinka paljon mitta voi venyä
+tai kutistua. Molempia ei välttämättä tarvitse antaa.
+
+Venyvät mitat voivat sisältää ''äärettömän'' mittayksikön \koodi{fill},
+joka antaa luvan venyttää mittaa niin, että kaikki käytettävissä oleva
+tila täyttyy. Äärettömän mittayksikön kanssa mittaluku ilmaisee
+suhdeluvun muihin äärettömiin mittoihin. Seuraava esimerkki
+havainnollistaa asiaa:
+
+\komentoi{hspace}
+\begin{koodilohkosis}
+x\hspace{0mm plus 1fill}x\hspace{0mm plus 2fill}x
+\end{koodilohkosis}
+
+\begin{tulossis}
+ x\hspace{0mm plus 1fill}x\hspace{0mm plus 2fill}x
+\end{tulossis}
+
+\noindent
+Edellisen esimerkin mittojen luonnollinen pituus on nolla (\koodi{0mm}),
+mutta \koodi{plus} ja \koodi{fill} \=/mitan vuoksi ne voivat venyä ja
+täyttää koko käytettävissä olevan tilan. Ensin mainitulla on suhdeluku 1
+(\koodi{1fill}) ja jälkimmäisellä suhdeluku 2 (\koodi{2fill}), joten
+jälkimmäinen väli on kaksinkertainen ensimmäiseen verrattuna. Saman
+äärettömästi venyvän mitan ja suhdeluvut voi ilmaista myös
+\komento{stretch}\-/ mittakomennon avulla seuraavasti:
+
+\komentoi{hspace}
+\komentoi{stretch}
+\begin{koodilohkosis}
+x\hspace{\stretch{1}}x\hspace{\stretch{2}}x
+\end{koodilohkosis}
+
+\begin{tulossis}
+ x\hspace{\stretch{1}}x\hspace{\stretch{2}}x
+\end{tulossis}
+
+\noindent
+Äärettömästi venyvälle, koko tilan täyttävälle mittayksikölle on itse
+asiassa kolme eri versiota: \koodi{fil}, \koodi{fill} ja \koodi{filll}.
+Niiden erona on tärkeysjärjestys. Ensin mainittu \koodi{fil} on vähiten
+tärkeä, ja viimeinen eli \koodi{filll} on tärkein. Jos samassa
+yhteydessä käytetään eri tärkeysasteisia yksiköitä, ylemmäntasoiset
+mitätöivät alemmantasoiset.
+
+\komentoi{hspace}
+\begin{koodilohkosis}
+x\hspace{0mm plus 1filll}x\hspace{0mm plus 1fill}x
+\end{koodilohkosis}
+
+\begin{tulossis}
+ x\hspace{0mm plus 1filll}x\hspace{0mm plus 1fill}x
+\end{tulossis}
+
+\noindent
+Edellisessä esimerkissä ensimmäinen venyvä mitta \koodi{1filll} mitätöi
+jälkimmäisen \koodi{1fill} kokonaan. Yleensä lienee parasta käyttää
+keskimmäistä (\koodi{fill}), mutta eri tärkeysasteille voi olla käyttöä
+esimerkiksi paketin koodissa: \koodi{fil} sallii, että kirjoittaja
+tai muu koodi syrjäyttää asetuksen; \koodi{filll} on ehdoton sääntö,
+joka syrjäyttää muut.
+
+Käytännöllisyyssyistä äärettömästi venyvä pituus \koodi{0mm plus 1fill}
+on jo valmiiksi asetettu mittaan \mittam{fill}. Sitä on kätevää käyttää
+esimerkiksi vaaka- ja pystysuuntaisia välejä latovien komentojen
+\komento{hspace} ja \komento{vspace} kanssa:
+
+\komentoi{hspace}
+\komentoi{vspace}
+\mittai{fill}
+\begin{koodilohkosis}
+\hspace{\fill} % ääretön vaakasuuntainen väli
+\vspace{\fill} % ääretön pystysuuntainen väli
+\end{koodilohkosis}
+
+\noindent
+Edellisen esimerkin komennoista on olemassa vieläkin lyhemmät versiot.
+Vaakasuuntainen ääretön väli syntyy myös komennolla \komento{hfill} ja
+pystysuuntainen väli komennolla \komento{vfill}. Seuraavassa toistetaan
+eräs aiempi esimerkki yksinkertaisemmalla tavalla:
+
+\komentoi{hfill}
+\begin{koodilohkosis}
+x\hfill x\hfill\hfill x
+\end{koodilohkosis}
+
+\begin{tulossis}
+ x\hfill x\hfill\hfill x
+\end{tulossis}
+
+\section{Laskurit}
+\label{luku/laskurit}
+
+Laskureiden avulla Latex pitää kirjaa esimerkiksi sivunumeroista,
+lukujen ja alalukujen sekä kuvien ja muiden elementtien numeroinnista.
+Esimerkiksi nyt olemme pääluvun~\arabic{chapter}
+alaluvussa~\arabic{section}, ja mainitut luvut tulevat Latexin
+laskureista automaattisesti.
+
+\leijutlk{
+ \laskurii{part}
+ \laskurii{paragraph}
+ \laskurii{figure}
+ \laskurii{enumi}
+ \laskurii{chapter}
+ \laskurii{subparagraph}
+ \laskurii{table}
+ \laskurii{enumii}
+ \laskurii{section}
+ \laskurii{page}
+ \laskurii{footnote}
+ \laskurii{enumiii}
+ \laskurii{subsection}
+ \laskurii{equation}
+ \laskurii{mpfootnote}
+ \laskurii{enumiv}
+ \laskurii{subsubsection}
+
+ \begin{tabular}{llll}
+ \toprule
+ \laskuri{part} & \laskuri{paragraph}
+ & \laskuri{figure} & \laskuri{enumi} \\
+ \laskuri{chapter} & \laskuri{subparagraph}
+ & \laskuri{table} & \laskuri{enumii} \\
+ \laskuri{section} & \laskuri{page}
+ & \laskuri{footnote} & \laskuri{enumiii} \\
+ \laskuri{subsection} & \laskuri{equation}
+ & \laskuri{mpfootnote} & \laskuri{enumiv} \\
+ \laskuri{subsubsection} \\
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Latexin laskurit}
+ \label{tlk/latexin-laskurit}
+}
+
+Taulukossa \ref{tlk/latexin-laskurit} ovat Latexin perus laskurit. Monet
+niistä ovat otsikoiden numerointia varten (\englanti{\laskuri{part},
+ \laskuri{chapter}, \laskuri{section}, \laskuri{paragraph}}).
+Sivunumeroita varten on \laskuri{page}\-/laskuri ja matemaattisten
+kaavojen numerointiin \laskuri{equation}\-/laskuri. Leijuvista kuvista
+ja taulukoista (luku \ref{luku/leijuosat}) pidetään kirjaa laskureissa
+\laskuri{figure} ja \laskuri{table}, ja alaviitteiden (luku
+\ref{luku/alaviitteet}) numerointi on laskureissa \laskuri{footnote} ja
+\laskuri{mpfootnote}. Numeroidut luetelmat (luku \ref{luku/luetelmat})
+käsitellään \laskurix{enum}\-/alkuisten laskureiden avulla siten, että
+perustasolla käytetään laskuria \laskuri{enumi}, ja jos sen
+luetelmakohta sisältää toisen numeroidun luetelman, käytetään siinä
+laskuria \laskuri{enumii}, sen sisällä laskuria \laskuri{enumiii} jne.
+
+Edellä mainituista laskureista ei tarvitse yleensä itse huolehtia, sillä
+ne ovat vain tekniikkaa, joka toimii korkeamman tason toimintojen
+taustalla. Joskus on kuitenkin käyttöä myös omille laskureille. Seuraava
+esimerkki esittelee laskureiden käsittelyn peruskomennot. Niissä
+käytetään laskuria nimeltä \laskurix{oma}. Laskurien nimet koostuvat
+pelkistä kirjaimista, eikä niiden alussa ole kenoviivaa niin kuin
+komentojen ja mittojen alussa.
+
+\komentoi{newcounter}
+\komentoi{setcounter}
+\komentoi{addtocounter}
+\begin{koodilohkosis}
+\newcounter{oma} % Luodaan uusi laskuri ”oma”.
+\setcounter{oma}{3} % Asetetaan laskurin arvoksi 3.
+\addtocounter{oma}{1} % Lisätään laskurin arvoon 1.
+\addtocounter{oma}{-1} % Vähennetään laskurin arvosta 1.
+\end{koodilohkosis}
+
+\noindent
+Laskuri on sisäisesti kokonaisluku, mutta sen arvon voi latoa eri
+muodoissa: arabialaisena tai roomalaisena lukuna, kirjaimena tai
+symbolien sarjana. Taulukossa \ref{tlk/laskurien-latominen} ovat komennot
+laskurin arvon latomiseen. Komennon argumentiksi annetaan laskurin nimi.
+Laskurin voi latoa kirjainmuodossa, jos sen arvo on 1--26; symbolit
+toimivat vain lukualueella 1--9.
+
+\leijutlk{
+ \begin{tabular}{ll}
+ \toprule
+ \ots{Komento} & \ots{Merkitys} \\
+ \midrule
+ \komento{arabic} & arabialainen luku: 1, 2, 3\ldots \\
+ \komento{roman} & roomalainen luku: i, ii, iii\ldots \\
+ \komento{Roman} & roomalainen luku: I, II, III\ldots \\
+ \komento{alph} & kirjain: a, b, c\ldots\ (vain 1--26) \\
+ \komento{Alph} & kirjain: A, B, C\ldots\ (vain 1--26) \\
+ \komento{fnsymbol} & symboli:
+ \textasteriskcentered
+ \textdagger
+ \textdaggerdbl\S\P\ldots\ (vain 1--9) \\
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Komennot laskurien arvon latomiseen}
+ \label{tlk/laskurien-latominen}
+}
+
+Taulukon \ref{tlk/laskurien-latominen} komentojen lisäksi laskuriin
+liittyvän arvon voi latoa komennolla, joka alkaa kirjaimilla
+\komentox{the} ja jatkuu laskurin nimellä. Esimerkiksi komento
+\komento{thepage} latoo sivunumeron eli tekee käytännössä saman asian
+kuin komento \komento{arabic}\komentoarg{page}. Aina nämä eivät
+kuitenkaan ole sama asia, ja \komentox{the}\-/alkuinen komento voi olla
+määritelty toisellakin tavalla. Esimerkiksi tämän oppaan leijuvat
+taulukot numeroidaan laskurilla \laskuri{table}, mutta komento
+\komento{thetable} latoo ensin pääluvun ja sen perään pisteen ja
+taulukon numeron. Viimeisin taulukko on numeroltaan \thetable{} eli
+pääluvun~\arabic{chapter} taulukko~\arabic{table}.
+
+Jos laskurin arvoa tarvitaan Latexin teknisessä tilanteessa eikä
+tarkoituksena ole latoa sitä näkyviin itse dokumenttiin, täytyy käyttää
+komentoa \komento{value}. Seuraava esimerkki luo laskurin nimeltä
+\laskurix{mitta}, jonka arvoa (3) käytetään \komento{hspace}\-/ komennon
+argumenttina mitan ilmaisemiseen (3\,em).
+
+\komentoi{newcounter}
+\komentoi{setcounter}
+\komentoi{hspace}
+\komentoi{value}
+\begin{koodilohkosis}
+\newcounter{mitta}
+\setcounter{mitta}{3}
+x\hspace{\value{mitta}em}x
+\end{koodilohkosis}
+
+\begin{tulossis}
+ x\hspace{3em}x
+\end{tulossis}
+
+\subsection{Hierarkkiset laskurit}
+\label{luku/hierarkkiset-laskurit}
+
+Laskurit voivat olla hierarkkisia ja riippuvaisia toisista laskureista:
+kun yhden laskurin arvo kasvaa, nollautuu jokin toinen laskuri
+automaattisesti. Tällaista toimintoa käytetään dokumentin lukujen eli
+otsikoiden numeroinnissa. Kirjan pääluvun~1 alaluvut ovat esimerkiksi
+1.1, 1.2, 1.3 jne. Kun alkaa seuraava pääluku~2, nollautuu alaluvun
+laskuri, jotta saadaan oikein numeroidut alaluvut 2.1, 2.2, 2.3 jne.
+Latex huolehtii lukujen numeroinnista automaattisesti, mutta omille
+laskureille täytyy määritellä riippuvuussuhteet itse. Seuraavassa
+esimerkissä luodaan oma laskuri, joka nollautuu automaattisesti aina,
+kun sivu vaihtuu eli laskurin \laskuri{page} arvo kasvaa.
+
+\komentoi{newcounter}
+\begin{koodilohkosis}
+\newcounter{oma}[page]
+\end{koodilohkosis}
+
+\noindent
+Ylemmän tason laskureita ei kannata kasvattaa komennolla
+\komento{addtocounter}, koska se vain muuttaa laskurin arvoa mutta ei
+huolehdi alemman tason laskurien nollaamisesta. Hierarkkisten laskurien
+kasvattamiseen on seuraavat kaksi komentoa:
+
+\komentoi{stepcounter}
+\komentoi{refstepcounter}
+\begin{koodilohkosis}
+\stepcounter{laskuri}
+\refstepcounter{laskuri}
+\end{koodilohkosis}
+
+\noindent
+Edellä mainitut komennot kasvattavat argumenttina annetun laskurin arvoa
+yhdellä ja nollaavat siitä riippuvaiset alemman tason laskurit.
+Jälkimmäinen komento \komento{refstepcounter} asettaa lisäksi
+ristiviitteen numeron, joten tämän komennon jälkeen mahdollisesti tuleva
+\komento{label}\-/ komento luo ristiviitekohteen. Kun tähän kohtaan
+viitataan muualta käyttämällä \komento{ref}\-/ komentoa, viitteessä
+näkyy laskurin numero tai oikeastaan \komentox{thelaskuri}\-/ komennon
+latoma teksti. Ristiviitteitä käsitellään tarkemmin luvussa
+\ref{luku/ristiviitteet}.
+
+Paketti \pakettictan{chngcntr} helpottaa hierarkkisten laskurien
+muuttamista jälkikäteen. Paketin komentojen avulla voi jälkikäteen
+asettaa jonkin laskurin riippuvaiseksi toisesta laskurista tai poistaa
+riippuvuuden.
+
+\komentoi{newcounter}
+\komentoi{counterwithin}
+\komentoi{counterwithout}
+\begin{koodilohkosis}
+\newcounter{oma} % Luodaan laskuri ”oma”.
+\counterwithin {oma}{page} % Asetetaan riippuvuus page-laskurista.
+\counterwithout{oma}{page} % Poistetaan riippuvuus.
+\end{koodilohkosis}
+
+\noindent
+Edellä mainitut \paketti{chngcntr}\-/paketin komennot määrittelevät
+uudelleen myös \komentox{the\-oma}\-/ komennon, jolla \laskurix{oma}\-/
+laskurin arvon voi latoa. Se latoo mukaan myös ylemmäntasoisen laskurin
+arvon. Jos tätä \komentox{the}\-/ alkuista komentoa ei halua määritellä
+uudelleen, täytyy käyttää tähdellisiä komennon versioita:
+\komento{counterwithin*} ja \komento{counterwithout*}. Laskuriin
+liittyvän \komentox{the}\-/ komennon voi aina itsekin määritellä
+haluamansa laiseksi komennolla \komento{renewcommand} (luku
+\ref{luku/komennot-määrittely}), esimerkiksi seuraavalla tavalla:
+
+\komentoi{renewcommand}
+\komentoi{arabic}
+\komentoi{alph}
+\laskurii{page}
+\begin{koodilohkosis}
+\renewcommand{\theoma}{\arabic{page}/\alph{oma}}
+\end{koodilohkosis}
+
+\subsection{Kokonaislaskurit}
+
+Latex ei tiedä etukäteen, mihin arvoon laskurit lopulta yltävät. Se vain
+latoo sivuja peräkkäin eikä tiedä mitään tulevasta. Sen vuoksi
+esimerkiksi dokumentin sivumäärää ei voi ihan yksinkertaisella
+komennolla latoa dokumentin alkusivuille.
+
+Tekninen vastaus tämäntyyppisiin ongelmiin löytyy ristiviitteistä (luku
+\ref{luku/ristiviitteet}). Ne toimivat sisäisesti niin, että dokumentin
+ensimmäisellä kääntökerralla kirjoitetaan väliaikaistiedostoon muistiin
+tarpeellisia asioita ja seuraavalla kääntökerralla hyödynnetään
+väliaikaistiedostoa. Dokumentin sivumäärän ja viimeisen sivunumeron
+tallentamiseen on olemassa paketti \pakettictan{totpages}, joka lisää
+viimeiselle sivulle automaattisesti ristiviitteen nimeltä
+\koodi{Tot\-Pages}. Sivumäärän ja viimeisen sivun numeron voi latoa
+komennoilla \komento{ref} ja \komento{pageref}. Esimerkki
+\ref{esim/totpages} havainnollistaa niiden käyttöä.
+
+\begin{esimerkki*}
+ \luokkai{article}
+ \komentoi{documentclass}
+ \komentoi{usepackage}
+ \pakettii{totpages}
+ \komentoi{ref}
+ \komentoi{pageref}
+ \komentoi{addtocounter}
+ \laskurii{page}
+ \komentoi{newpage}
+
+\begin{koodilohko}
+\documentclass{article}
+\usepackage{totpages}
+
+\begin{document}
+Sivumäärä: \ref{TotPages}. Viimeinen sivu: \pageref{TotPages}.
+
+\addtocounter{page}{10} % Sivunumerot 11, 12, 13...
+\newpage Jotain... \newpage ...sisältöä.
+\end{document}
+\end{koodilohko}
+ \caption{Dokumentin sivumäärän ja viimeisen sivun numeron latominen}
+ \label{esim/totpages}
+\end{esimerkki*}
+
+Muunlaisten kokonaislaskurien toteuttamiseen voi käyttää
+\pakettictan{totcount}\-/ pakettia. Se tarjoaa komennon, jolla
+rekisteröidään olemassa oleva laskuri kokonaislaskuriksi. Lisäksi on
+komento, jolla ladotaan tai palautetaan laskurin lopullinen arvo.
+
+\komentoi{newcounter}
+\komentoi{regtotcounter}
+\komentoi{addtocounter}
+\komentoi{total}
+\komentoi{totvalue}
+\begin{koodilohkosis}
+\newcounter{oma} % Luodaan laskuri ”oma”.
+\regtotcounter{oma} % Rekisteröidään ”oma” kokonaislaskuriksi.
+\addtocounter{oma}{1} % Kasvatetaan laskurin arvoa.
+\total{oma} % Ladotaan laskurin lopullinen arvo.
+\totvalue{oma} % Palautetaan laskurin lopullinen arvo.
+\end{koodilohkosis}
+
+\noindent
+Edellä olevan esimerkin viimeistä komentoa \komento{totvalue} ei käytetä
+laskurin arvon latomiseen itse dokumenttiin vaan sitä käytetään
+teknisissä yhteyksissä kuten toisen Latex\-/komennon argumenttina.
+
+Myös Latexin valmiita laskureita voi rekisteröidä kokonaislaskureiksi.
+Tässä oppaassa on yhteensä \total{chapter} numeroitua päälukua, ja
+mainittu lukumäärä saatiin laskettua seuraavasti:
+
+\komentoi{regtotcounter}
+\komentoi{total}
+\laskurii{chapter}
+\begin{koodilohkosis}
+\regtotcounter{chapter} % Sijoitetaan dokumentin esittelyosaan.
+\total{chapter} % Latoo päälukujen (chapter) lukumäärän.
+\end{koodilohkosis}
+
+\section{Laatikot}
+\label{luku/laatikot}
+
+Tex ajattelee ladottavan tekstin ja muun sisällön laatikoina eli
+suorakulmioina, joilla on leveys ja korkeus. Esimerkiksi kirjaimet ovat
+teknisesti laatikoita, joita ladotaan peräkkäin. Samoin monet valmiit
+ympäristöt luovat laatikon, joka sisältää jotakin ja vie tietyn verran
+tilaa sivulta.
+
+Dokumentin kirjoittajalle on välillä hyötyä luoda omia laatikoita, koska
+laatikko toimii yhtenä kokonaisuutena, jonka reunoja muut elementit ja
+latomiskoneisto kunnioittavat.
+
+\subsection{Pienet laatikot}
+\label{luku/laatikot-pienet}
+
+Yksinkertainen peruslaatikko tehdään \komento{mbox}\-/ komennolla, joka
+latoo argumenttina annetun tekstin näkymättömän laatikon sisään. Näin
+luotu laatikko pysyy koossa, eli sen sisältämiä sanoja ei esimerkiksi
+tavuteta. Komento sopiikin hyvin tavutuksen estämiseen yksittäisessä
+tilanteessa.
+
+Toinen laatikkokomento \komento{makebox} toimii samalla tavalla kuin
+\komento{mbox} mutta hyväksyy yhden tai kaksi valinnaista argumenttia.
+Komentojen muoto on seuraava:
+
+\komentoi{makebox}
+\begin{koodilohkosis}
+\makebox[leveys]{teksti}
+\makebox[leveys][sijainti]{teksti}
+\end{koodilohkosis}
+
+\noindent
+Argumentti \koodi{leveys} on laatikon leveysmitta ja \koodi{sijainti} on
+kirjainkoodi, joka ilmaisee laatikon sisällön vaakasuuntaisen
+sijoittelun. Kirjain \koodi{c} (\englanti{center}) keskittää sisällön,
+\koodi{l} (\englanti{left}) tasaa sisällön vasemmalle, \koodi{r}
+(\englanti{right}) tasaa sisällön oikealle ja \koodi{s}
+(\englanti{stretch}) tasaa sisällön molemmista reunoista eli venyttää
+laatikon sisäisiä sanavälejä sopivasti.
+
+\komentoi{makebox}
+\begin{koodilohkosis}
+\makebox[12em][s]{Laatikossa on tilaa.}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \makebox[12em][s]{Laatikossa on tilaa.}
+\end{tulossis}
+
+\noindent
+\komento{makebox}\-/ komennon \koodi{leveys}\-/ argumentissa voi käyttää
+apuna mittoja \mitta{width} (leveys), \mitta{height} (korkeus),
+\mitta{depth} (syvyys) ja \mitta{totalheight} (kokonaiskorkeus:
+\mitta{height} + \mitta{depth}), jotka määräytyvät laatikon sisällön
+luontaisten mittojen perusteella. Kuvassa \ref{kuva/kirjainmitat}
+(s.~\pageref{kuva/kirjainmitat}) oleva typografinen viivasto
+havainnollistaa näitä mittoja.
+
+Seuraava esimerkki latoo laatikon, jonka leveys on 1,5\-/ kertainen
+sisällön luontaiseen leveyteen nähden, ja keskittää tekstin. Pystyviivat
+ovat mukana rajojen hahmottamisen vuoksi.
+
+\komentoi{makebox}
+\mittai{width}
+\begin{koodilohkosis}
+|\makebox[1.5\width][c]{Keskitetty}|
+\end{koodilohkosis}
+
+\begin{tulossis}
+ |\makebox[1.5\width][c]{Keskitetty}|
+\end{tulossis}
+
+\noindent
+Laatikkokomento \komento{fbox} toimii kuten \komento{mbox} mutta piirtää
+laatikolle myös näkyvät kehykset. Komento \komento{framebox} on
+puolestaan kehyksellinen versio \komento{makebox}\-/ komennosta.
+Kehysviivan leveyden voi asettaa mitan \mitta{fboxrule} avulla, ja
+kehysviivan etäisyys sisällöstä määritellään mitassa \mitta{fboxsep}.
+
+\komentoi{fbox}
+\komentoi{framebox}
+\komentoi{setlength}
+\mittai{fboxrule}
+\mittai{fboxsep}
+\mittai{width}
+\begin{koodilohkosis}
+\setlength{\fboxsep}{3bp}
+\setlength{\fboxrule}{.5bp}
+\framebox[1.2\width][c]{Laatikossa \fbox{laatikko}}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \setlength{\fboxsep}{3bp}
+ \setlength{\fboxrule}{.5bp}
+ \framebox[1.2\width][c]{Laatikossa \fbox{laatikko}}
+\end{tulossis}
+
+\noindent
+Värillisten laatikoiden ja kehysten tekemistä neuvotaan luvussa
+\ref{luku/korostus-värit}, joka käsittelee väriasioita muutenkin.
+
+Tekstiä sisältävien laatikoiden korkeus vaihtelee kirjainten ja muiden
+merkkien muodon mukaan. Esimerkiksi kirjainten ala- ja yläpidennykset
+kasvattavat laatikon kokoa gemenalinjan yläpuolelle tai peruslinjan
+alapuolelle. Seuraavasta esimerkistä voi vertailla tekstilaatikoiden
+muodostumista:
+
+\komentoi{setlength}
+\komentoi{fbox}
+\mittai{fboxsep}
+\begin{koodilohkosis}
+\setlength{\fboxsep}{0bp}
+\fbox{sana} \fbox{kirja} \fbox{×}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \setlength{\fboxsep}{0bp}
+ \fbox{sana} \fbox{kirja} \fbox{×}
+\end{tulossis}
+
+\noindent
+Edellisen esimerkin kaltaisissa tilanteissa voi olla tarpeen käyttää
+laatikon sisällä komentoa \komento{strut}. Se latoo näkymättömän,
+leveydettömän merkin, jonka korkeus on rivikorkeuden mukainen (mitta
+\mitta{baselineskip}).
+
+\komentoi{setlength}
+\komentoi{fbox}
+\komentoi{strut}
+\mittai{fboxsep}
+\begin{koodilohkosis}
+\setlength{\fboxsep}{0bp}
+\fbox{\strut sana} \fbox{\strut kirja} \fbox{\strut ×}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \setlength{\fboxsep}{0bp}
+ \fbox{\strut sana} \fbox{\strut kirja} \fbox{\strut ×}
+\end{tulossis}
+
+\subsection{Suuret laatikot}
+\label{luku/laatikot-isot}
+
+Jos laatikon täytyy sisältää useita tekstikappaleita tai muuta
+pystysuuntaista sisältöä, tarvitaan esimerkiksi \komento{parbox}\-/
+komentoa. Se tarvitsee ainakin kaksi argumenttia: laatikon leveyden ja
+sisällön.
+
+\komentoi{parbox}
+\begin{koodilohkosis}
+\parbox{leveys}{sisältö}
+\end{koodilohkosis}
+
+\noindent
+\komento{parbox}\-/ laatikon sisällä teksti ladotaan samoin kuin teksti
+normaalistikin eli rivit katkaistaan sanavälien kohdalta ja
+mahdollisesti tavutuskohdista. Muutkin tekstikappaleen asetukset
+pätevät, ja asetukset voi määrittää haluamikseen laatikon sisällä.
+Lisätietoa tekstikappaleista on luvussa \ref{luku/kappale}.
+
+Komento \komento{parbox} hyväksyy myös yhden, kaksi tai kolme
+valinnaista argumenttia. Niillä määritellään laatikon pystysuuntainen
+sijoittelu ympäristöönsä nähden, laatikon korkeus ja laatikon sisällön
+pystysuuntainen sijoittelu. Valinnaiset argumentit toimivat seuraavasti:
+
+\komentoi{parbox}
+\begin{koodilohkosis}
+\parbox[sijainti]{leveys}{sisältö}
+\parbox[sijainti][korkeus]{leveys}{sisältö}
+\parbox[sijainti][korkeus][sisäsijainti]{leveys}{sisältö}
+\end{koodilohkosis}
+
+\noindent
+Argumentti \koodi{sijainti} on kirjain \koodi{c} (\englanti{center},
+keskilinja), \koodi{t} (\englanti{top}, ylälinja) tai \koodi{b}
+(\englanti{bottom}, alalinja). Näillä määritetään, miten laatikko
+sijoitetaan pystysuunnassa suhteessa tekstiin. Seuraava esimerkki
+havainnollistaa ensimmäisen valinnaisen argumentin toimintaa. Laatikon
+sisällä on rivinvaihtokomentoja (\komento{\keno}) ja kolme tekstiriviä.
+
+\komentoi{parbox}
+\begin{koodilohkosis}
+abc \parbox[c]{1em}{1 \\ 2 \\ 3}
+abc \parbox[t]{1em}{1 \\ 2 \\ 3}
+abc \parbox[b]{1em}{1 \\ 2 \\ 3} abc
+\end{koodilohkosis}
+
+\begin{tulossis}
+ abc \parbox[c]{1em}{1 \\ 2 \\ 3}
+ abc \parbox[t]{1em}{1 \\ 2 \\ 3}
+ abc \parbox[b]{1em}{1 \\ 2 \\ 3} abc
+\end{tulossis}
+
+\noindent
+Komennon toinen valinnainen argumentti \koodi{korkeus} määrittää
+laatikon korkeuden. Oletuksena korkeus määräytyy sisällön korkeuden
+mukaan, mutta tällä argumentilla korkeus asetetaan kiinteästi. Se voi
+olla hyödyllistä varsinkin silloin, kun sisältö halutaan tasata laatikon
+sisällä ylös, keskelle tai alas.
+
+Kolmas valinnainen argumentti \koodi{sisäsijainti} nimittäin asettaa
+laatikon sisällön pystysuuntaisen tasauksen. Argumentiksi annetaan
+kirjain \koodi{c} (\englanti{center}, keskelle), \koodi{t}
+(\englanti{top}, ylös), \koodi{b} (\englanti{bottom}, alas) tai
+\koodi{s} (\englanti{stretch}, ylös ja alas). Viimeksi mainittu eli ylös
+ja alas tasaaminen vaatii, että laatikon sisällä on venyviä
+pystysuuntaisia välejä. Niitä käsitellään luvussa
+\ref{luku/venyvät-mitat}.
+
+Ympäristö \ymparisto{minipage} vastaa toiminnallisesti
+\komento{parbox}\-/ komentoa. Se hyväksyy täsmälleen samat argumentit.
+Erona on se, että \ymparisto{minipage}\-/ ympäristön sisällä voi käyttää
+laatikon omia alaviitteitä (luku \ref{luku/alaviitteet}), jotka ladotaan
+laatikon alaosaan.
+
+\ymparistoi{minipage}
+\begin{koodilohkosis}
+\begin{minipage}[sijainti][korkeus][sisäsijainti]{leveys}
+ ...
+\end{minipage}
+\end{koodilohkosis}
+
+\subsection{Laatikoiden siirtely}
+
+Komennolla \komento{raisebox} voi latoa laatikon tekstin ylemmäs tai
+alemmas kuin se normaalisti sijoittuisi. Komennon ensimmäinen argumentti
+on etäisyysmitta, kuinka paljon ylemmäs teksti ladotaan. Negatiivinen
+mitta vie tekstin alemmas. Toinen argumentti on laatikon teksti.
+
+\komentoi{raisebox}
+\begin{koodilohkosis}
+\raisebox{etäisyysmitta}{teksti}
+\end{koodilohkosis}
+
+\noindent
+Argumentissa \koodi{etäisyysmitta} voi käyttää apuna mittoja
+\mitta{width}, \mitta{height}, \mitta{depth} ja \mitta{totalheight},
+joiden merkitys on sama kuin \komento{makebox}\-/ komennolla (luku
+\ref{luku/laatikot-pienet}). \komento{raisebox}\-/ komennolle voi antaa
+yhden tai kaksi valinnaista argumenttia, joilla määritellään laatikolle
+uusi korkeus ja syvyys. Molemmat ovat mittoja, ja ne korvaavat siirretyn
+laatikon tekstin luonnollisen korkeuden ja syvyyden. Komennon argumentit
+annetaan seuraavasti:
+
+\komentoi{raisebox}
+\begin{koodilohkosis}
+\raisebox{etäisyysmitta}[korkeus]{teksti}
+\raisebox{etäisyysmitta}[korkeus][syvyys]{teksti}
+\end{koodilohkosis}
+
+\noindent
+Grafiikkaan kuten kuviin ja väreihin erikoistunut paketti
+\paketti{graphicx} sisältää hyödyllisiä laatikkokomentoja:
+\komento{scalebox}, \komento{resizebox} ja \komento{rotatebox}. Komento
+\komento{scalebox} skaalaa tekstin eri kokoiseksi vaaka- tai
+pystysuunnassa.
+
+\komentoi{scalebox}
+\begin{koodilohkosis}
+\scalebox{vaakaskaalaus}[pystyskaalaus]{teksti}
+\end{koodilohkosis}
+
+\noindent
+Argumentit \koodi{vaakaskaalaus} ja \koodi{pystyskaalaus} ovat
+kertoimia. Pystysuuntainen skaalausargumentti on valinnainen: jos sen
+jättää pois, pystysuuntainen skaalaus on samansuuruinen kuin
+vaakasuuntainen. Negatiivisella kertoimella voi kääntää tekstin
+toisinpäin.
+
+\komentoi{scalebox}
+\begin{koodilohkosis}
+\scalebox{2}[1]{leveä} \scalebox{-1}[1]{käännetty}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \scalebox{2}[1]{leveä} \scalebox{-1}[1]{käännetty}
+\end{tulossis}
+
+\noindent
+Samantapainen skaalaustoiminto saadaan myös komennolla
+\komento{resizebox}. Sen argumentiksi ei anneta kertoimia vaan mittoja,
+eli teksti skaalataan annettuihin mittoihin.
+
+\komentoi{resizebox}
+\komentoi{resizebox*}
+\begin{koodilohkosis}
+\resizebox {vaakamitta}{pystymitta}{teksti}
+\resizebox*{vaakamitta}{pystymitta}{teksti}
+\end{koodilohkosis}
+
+\noindent
+Komennon \komentoi{resizebox} normaali versio käsittelee
+\koodi{pystymitta}\-/ argumentin siten, että se tulee olemaan tekstin
+korkeus eli kirjainten peruslinjan yläpuolinen osa. Komennon
+\komentoi{resizebox*} tähdellinen versio puolestaan toimii siten, että
+pystymitta on tekstin kokonaiskorkeus eli peruslinjan yläpuolinen osa
+(korkeus) ja alapuolinen osa (syvyys) yhdessä. Kuva
+\ref{kuva/kirjainmitat} (s.~\pageref{kuva/kirjainmitat}) havainnollistaa
+asiaa. \komento{resizebox}\-/ komennon argumenteissa voi käyttää apuna
+mittoja \mitta{width}, \mitta{height}, \mitta{depth} ja
+\mitta{totalheight} samoin kuin \komento{makebox}\-/ komennossa (luku
+\ref{luku/laatikot-pienet}).
+
+Laatikoiden pyörittely käy \komento{rotatebox}\-/ komennolla. Sen
+argumentiksi täytyy antaa ainakin kääntökulma asteina ja käännettävä
+teksti.
+
+\komentoi{rotatebox}
+\begin{koodilohkosis}
+\rotatebox[asetuksia]{kääntökulma}{teksti}
+\end{koodilohkosis}
+
+\noindent
+Valinnainen argumentti \koodi{asetuksia} voi sisältää asetusvalitsimia
+ja niiden arvoja. Tärkein valitsin on \koodi{origin}, jolla määritetään
+käännettävän tekstin kääntöpiste. Valitsimen arvoksi annetaan yksi tai
+kaksi seuraavista kirjaimista: \koodi{c} (\englanti{center}, keski),
+\koodi{l} (\englanti{left}, vasen), \koodi{r} (\englanti{right}, oikea),
+\koodi{t} (\englanti{top}, ylä), \koodi{b} (\englanti{bottom}, ala) tai
+\koodi{B} (\englanti{baseline}, peruslinja).
+
+\komentoi{rotatebox}
+\begin{koodilohkosis}
+\rotatebox[origin=l] {25}{ylämäki}
+\rotatebox[origin=r]{-25}{alamäki}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \rotatebox[origin=l] {25}{ylämäki}
+ \rotatebox[origin=r]{-25}{alamäki}
+\end{tulossis}
+
+\noindent
+\komento{rotatebox}\-/ komennon valinnaisen argumentin valitsin
+\koodi{units} määrittelee käytetyn kulmayksikön. Valitsimelle annetaan
+arvoksi täysympyrän yksikkömäärä, ja oletusasetus on \koodi{units=\katk
+ 360}. Jos haluaa käyttää radiaaneja, sopiva asetus on
+\koodi{units=\katk 6.283185} (2π\,rad).
diff --git a/info/kaytannollista-latexia/luku-rakenne.tex b/info/kaytannollista-latexia/luku-rakenne.tex
new file mode 100644
index 0000000000..3d55ec708f
--- /dev/null
+++ b/info/kaytannollista-latexia/luku-rakenne.tex
@@ -0,0 +1,7903 @@
+% Tekijä: Teemu Likonen <tlikonen@iki.fi>
+% Lisenssi: Creative Commons Nimeä-JaaSamoin 4.0 Kansainvälinen (CC BY-SA 4.0)
+% https://creativecommons.org/licenses/by-sa/4.0/legalcode.fi
+
+\chapter{Rakenne ja sisältö}
+\label{luku/rakenne}
+
+Tämä luku on oppaan kaikista luvuista kenties käytännönläheisin. Luku
+keskittyy asioihin, joita kirjoittaja miettii erityisesti dokumentin
+sisällön kirjoitusvaiheessa. Kirjoittaja tekee esimerkiksi valintoja
+otsikoinnin ja muun jäsentämisen osalta. Hän miettii tiedon esittämistä
+paitsi tekstin avulla myös esimerkiksi luetelmien, kuvien ja taulukoiden
+avulla. Kirjoittaja tekee myös typografisia valintoja tekstin muotoilun
+ja korostuskeinojen näkökulmasta. Edellä mainittuja ja muitakin
+dokumentin rakenteen ja sisällön asioita käsitellään niin tekniikan kuin
+typografiankin näkökulmasta.
+
+\section{Tekstikappaleet}
+\label{luku/kappale}
+
+Tekstikappale on tekstin osa, jonka pitäisi käsitellä suunnilleen yhtä
+asiakokonaisuutta. Se voi olla esimerkiksi yksi aihe, näkökulma,
+ajankohta tai henkilö. Tekstin seuraava kappale käsittelee jotakin
+toista aihetta, näkökulmaa tms. Kappaleen vaihtuminen on lukijalle
+merkki siitä, että tekstin sisällössäkin jokin muuttuu.
+
+Latexin lähdetiedostoissa kappaleen vaihtuminen ilmaistaan
+kirjoittamalla kappaleiden väliin vähintään yksi tyhjä rivi. Tätä
+merkintäkielen piirrettä käsitellään myös luvussa
+\ref{luku/kappaleen-vaihtuminen}. Kappale vaihtuu myös komennolla
+\komentom{par}, joka sopii käytettäväksi esimerkiksi komentojen
+määrittelyssä (luku \ref{luku/komennot}), kun halutaan varmistaa
+kappaleen vaihtuminen tietyssä kohdassa.
+
+Ladotuissa teksteissä kuten kirjoissa ja lehdissä kappaleen vaihtuminen
+ilmaistaan melkein aina siten, että uuden kappaleen ensimmäinen rivi
+sisennetään hieman. Niin on tässäkin oppaassa. Toisinaan tekstikappaleet
+erotetaan pystysuuntaisella välillä, ja silloin kappaleiden ensimmäistä
+riviä ei sisennetä. Kappaleiden välejä, sisennyksiä, rivien tasaamista
+ja muita asetuksia käsitellään seuraavissa alaluvuissa.
+
+Monissa kappaleisiin liittyvissä asetuksissa tarvitaan Texin mittoja ja
+mittayksiköitä. Mittoihin liittyvää tekniikkaa käsitellään tarkemmin
+luvussa \ref{luku/mitat}, joka on syytä tuntea ennen tämän alaluvun
+lukemista.
+
+\subsection{Tasaaminen ja palstan muoto}
+\label{luku/kappaleen-tasaus}
+
+Perusdokumenttiluokissa (luku \ref{luku/perusdokumenttiluokat})
+tekstikappaleet tasataan oletuksena palstan molempiin reunoihin, ja tätä
+palstan muotoa kutsutaan tasapalstaksi. Se tarkoittaa samalla sitä, että
+rivillä olevia sanavälejä venytetään sopivasti, jotta jokainen rivi
+näyttäisi yhtä pitkältä ja palstan molemmat reunat tasaiselta.
+
+Käytännössä sanavälien venymiselle on määritelty yläraja, jonka yli
+niitä ei venytetä. Ylärajan tarkoituksena on estää liian suuret ja rumat
+sanavälit. Rajoitus on sinänsä järkevä, mutta se voi myös johtaa siihen,
+että Tex ei saa tasattua kaikkia tekstikappaleita palstan oikeasta
+reunasta: jotkin rivit yltävät palstan reunan yli; jotkin rivit jäävät
+vajaaksi. Näin käy usein varsinkin suomen kielessä, jonka sanat ovat
+usein pitkiä ja riveillä on vähänlaisesti sanavälejä. Suomen kielessä
+sanavälien venymisen yläraja on usein tarpeellista asettaa oletusarvoa
+suuremmaksi. Se tehdään mitan \mittam{emergencystretch} avulla,
+esimerkiksi seuraavasti:
+
+\komentoi{setlength}
+\mittai{emergencystretch}
+\begin{koodilohkosis}
+\setlength{\emergencystretch}{1em}
+\end{koodilohkosis}
+
+\noindent
+Kaikenlaiset kappaleiden latomiseen liittyvät tekniset rajoitukset voi
+poistaa tai asettaa hyvin suuriksi komennolla \komentom{sloppy}. Komento
+asettaa muun muassa sanavälien venymisen ylärajaksi 3\,em. Tämän
+komennon käyttö ei ole kovin suositeltavaa, koska sillä on muitakin
+seurauksia ja se voi vaikuttaa myös sellaisiin kappaleisiin, jotka
+muuten saataisiin ladottua nätisti. Parempi on asettaa vain mitta
+\mitta{emergencystretch} riittävän suureksi. Sanavälien venymiseen ja
+kappaleiden tasaiseen latomiseen liittyvät asetukset voi palauttaa
+oletusarvoihin komennolla \komentom{fussy}.
+
+Hyvin tavallista on tasata teksti pelkästään vasempaan reunaan, jolloin
+rivien pituudet vaihtelevat ja oikealla on niin sanottu liehureuna.
+Oikea liehureuna sopii pitkiin teksteihin yhtä hyvin kuin tasapalstakin,
+mutta se on parempi valinta erityisesti silloin, kun palsta on kapea.
+Nimittäin kapealla palstalla venyviä sanavälejä on käytettävissä hyvin
+vähän ja oikean reunan tasaaminen vaatii sanavälien venyttämistä joskus
+kohtuuttoman paljon. Tekstiin jää rumia aukkoja.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[3]{\komento{#1} & \ymparisto{#2} & #3 \\}
+ \begin{tabular}{lll}
+ \toprule
+ \ots{Komento} & \ots{Ympäristö} & \ots{Merkitys} \\
+ \midrule
+ \rivi{raggedright}{flushleft}{vasen tasaus, oikea liehu}
+ \rivi{raggedleft}{flushright}{oikea tasaus, vasen liehu}
+ \rivi{centering}{center}{keskitetty}
+ \midrule
+ \rivi{RaggedRight}{FlushLeft}
+ {vasen tasaus, oikea liehu, tavutus (\paketti{ragged2e})}
+ \rivi{RaggedLeft}{FlushRight}
+ {oikea tasaus, vasen liehu, tavutus (\paketti{ragged2e})}
+ \rivi{Centering}{Center}{keskitetty, tavutus (\paketti{ragged2e})}
+ \rivi{justifying}{justify}{tasapalsta, tavutus (\paketti{ragged2e})}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Tekstikappaleen tasaamiseen ja palstan muotoon vaikuttavat
+ komennot ja ympäristöt. Osa sisältyy \paketti{ragged2e}\-/pakettiin}
+ \label{tlk/kappaleen-tasauskomennot}
+}
+
+Kappaleiden tasaamiseen ja palstan muotoon vaikuttavia komentoja ja
+ympäristöjä on koottu taulukkoon \ref{tlk/kappaleen-tasauskomennot}.
+Taulukossa on mainittu ensin Latexin omat komennot ja sitten
+\pakettictan{ragged2e}\-/ paketin vastaavat. Latexin omat komennot
+estävät sanojen tavuttamisen, kun taas \paketti{ragged2e}\-/ paketin
+komennot sallivat tavutuksen normaalisti.
+
+\subsection{Pystysuuntaiset välit}
+\label{luku/pystysuuntaiset-välit}
+
+Kappaleiden väliin ladottava pystysuuntainen tyhjä tila asetetaan mitan
+\mittam{parskip} avulla. Se on oletuksena nolla, mutta pientä venymistä
+kuitenkin sallitaan, eli joissakin tilanteissa kappaleiden väliin
+voidaan latoa pieni tyhjä tila. Jos tyhjää tilaa ei haluta missään
+tilanteessa, asetetaan mitta vain nollaksi:
+
+\komentoi{setlength}
+\mittai{parskip}
+\begin{koodilohkosis}
+\setlength{\parskip}{0ex}
+\end{koodilohkosis}
+
+\noindent
+Seuraava esimerkkikomento asettaa kappaleväliksi 1,3\,ex. Lisäksi se
+sallii kappalevälin venyä 0,2\,ex:n verran tai kutistua 0,1\,ex:n
+verran.
+
+\komentoi{setlength}
+\mittai{parskip}
+\begin{koodilohkosis}
+\setlength{\parskip}{1.3ex plus .2ex minus .1ex}
+\end{koodilohkosis}
+
+\noindent
+Silloin kun kappaleet ladotaan erilleen toisistaan, on yleensä hyvä
+sallia kappalevälin venyä tai kutistua hieman, koska venyvät
+pystysuuntaiset välit antavat Texille paremmat mahdollisuudet latoa
+hyvännäköisiä sivuja. Venyvien välien avulla esimerkiksi sivun
+tekstialueen ylä- ja alareunat saadaan aina samalle kohdalle. Toisaalta
+myös liian suuret ja toisistaan liiaksi poikkeavat kappalevälit voivat
+olla rumannäköisiä.
+
+Tavallista kappaleväliä suurempien pystysuuntaisten välien tekemiseen on
+olemassa kolme valmista komentoa: suurimmasta pienimpään ne ovat
+\komentom{bigskip}, \komentom{medskip} ja \komentom{smallskip}. Ne
+sopivat käytettäväksi yksittäisiin tilainteisiin, joissa normaali
+kappaleväli on liian vähän. Jos sivunvaihto osuu näiden komentojen
+kohdalle, mitään väliä ei ladota sivun loppuun eikä seuraavan alkuun.
+
+Edellä mainittujen komentojen latoman välin suuruuteen voi vaikuttaa
+mittojen \mitta{bigskipamount}, \mitta{medskipamount} ja
+\mitta{smallskipamount} avulla. Seuraavassa on esimerkkikomennot
+mittojen määrittelemiseen ja samalla niiden oletusarvot:
+
+\komentoi{setlength}
+\mittai{bigskipamount}
+\mittai{medskipamount}
+\mittai{smallskipamount}
+\begin{koodilohkosis}
+\setlength{\bigskipamount} {12pt plus 4pt minus 4pt}
+\setlength{\medskipamount} {6pt plus 2pt minus 2pt}
+\setlength{\smallskipamount}{3pt plus 1pt minus 1pt}
+\end{koodilohkosis}
+
+\noindent
+Komentojen \komento{bigskip}, \komento{medskip} ja \komento{smallskip}
+sijasta voi käyttää myös komentoja \komentom{bigbreak},
+\komentom{medbreak} tai \komentom{smallbreak}. Nämä toimivat lähes
+samalla tavalla, mutta niihin sisältyy myös sivunvaihtovihje. Toisin
+sanoen ne vaikuttavat ladonta\-/algoritmiin siten, että komennon
+kohdalla todennäköisyys sivun vaihtumiselle kasvaa suhteessa muihin
+kohtiin. Sivu voi edelleen vaihtua muustakin kohdasta, jos algoritmi
+löytää omasta mielestään vielä paremman paikan.
+
+Pystysuuntaisten välien yleiskomento on \komentom{vspace}, jolle
+annetaan argumentiksi välin suuruus ja mahdolliset venymisen rajat.
+Tämäkin komento jättää välin latomatta, jos se sattuu sivunvaihdon
+kohdalle. Sen sijaan tähdellinen versio \komentom{vspace*} latoo välin
+joka tapauksessa, vaikka se olisi sivun lopussa tai alussa.
+
+\komentoi{vspace}
+\begin{koodilohkosis}
+Tekstikappale.
+\vspace{5ex plus 1ex minus .5ex}
+
+Toinen tekstikappale.
+\end{koodilohkosis}
+
+\noindent
+Komento \komentom{addvspace} toimii lähes samoin kuin \komento{vspace},
+mutta se huomioi mahdolliset peräkkäiset \komento{addvspace}\-/ komennot
+ja varmistaa, että vain suurin väli toteutuu. Jos siis useita
+\komento{addvspace}\-/ komentoja sattuu peräkkäin, niiden määrittämiä
+välejä ei ladota peräkkäin vaan ainoastaan suurin niistä ladotaan.
+Seuraava esimerkki latoo kappaleiden väliin 2\,ex:n suuruisen
+pystysuuntaisen välin:
+
+\komentoi{addvspace}
+\begin{koodilohkosis}
+Tekstikappale.
+
+\addvspace{1ex} \addvspace{2ex} \addvspace{.5ex}
+Toinen tekstikappale.
+\end{koodilohkosis}
+
+\noindent
+Jos edellisessä esimerkissä olisi käytetty \komento{vspace}\-/ komentoa,
+pystysuuntaisen välin suuruus olisi 3,5\,ex, joka on välien
+yhteenlaskettu suuruus.
+
+\komento{addvspace}\-/komento soveltuu hyvin komentojen ja ympäristöjen
+määrittelyyn (luvut \ref{luku/komennot} ja \ref{luku/ympäristöt}).
+Esimerkiksi itse määritellyn ympäristön alussa ja lopussa voi
+\komento{addvspace}\-/ komennolla varmistaa tietynsuuruisen välin, mutta
+jos sama tai muu vastaava ympäristö on dokumentissa kahdesti peräkkäin,
+huomioidaan pystysuuntainen väli vain kerran eli suurimman välin mukaan.
+Jotkin Latexin valmiit ympäristöt tekevät juuri näin eli käyttävät
+\komento{addvspace}\-/komentoa välien asettamiseen.
+
+Sivun alueella äärettömästi venyvän pystysuuntaisen välin saa komennolla
+\komentom{vfill}. Mitan luonnollinen arvo on nolla, mutta se voi venyä
+niin, että se täyttää kaiken tyhjän tilan sivulla. \komento{vfill}\-/
+komento tarkoittaa käytännössä samaa kuin
+\komento{vspace}\komentoarg{0mm plus 1fill} \=/komento. Texin venyviä
+mittoja ja välejä käsitellään tarkemmin luvussa
+\ref{luku/venyvät-mitat}.
+
+\subsection{Ensimmäisen rivin sisennys}
+\label{luku/ensimmäisen-rivin-sisennys}
+
+Kirjojen ja lehtien typografiassa kappaleen ensimmäinen rivi on tapana
+sisentää merkiksi siitä, että alkaa uusi kappale. Sisennys on lukijalle
+merkki siitä, että tekstin sisällössä siirrytään seuraavaan asiaan.
+Oletusasetuksilla Latex latoo sisennyksen automaattisesti kappaleen
+alkuun mutta ei kuitenkaan otsikoiden jälkeen.
+
+Ensimmäisen rivin sisennyksen suuruus asetetaan mitan \mittam{parindent}
+avulla, esimerkiksi seuraavan esimerkin mukaisesti. Sopiva mittayksikkö
+tähän tarkoitukseen on \emph{em}, koska se viittaa suoraan nykyisen
+fontin kokoon.
+
+\komentoi{setlength}
+\mittai{parindent}
+\begin{koodilohkosis}
+\setlength{\parindent}{1em}
+\end{koodilohkosis}
+
+\noindent
+Edellä mainittu mitta pitäisi asettaa nollaan silloin, kun kappaleiden
+välissä on tyhjää tilaa. Pystysuuntainen välihän jo sinänsä ilmaisee,
+että kappale vaihtuu.
+
+\komentoi{setlength}
+\mittai{parskip}
+\mittai{parindent}
+\begin{koodilohkosis}
+\setlength{\parskip}{1.3ex plus .2ex minus .1ex}
+\setlength{\parindent}{0em} % Ei sisennystä.
+\end{koodilohkosis}
+
+\noindent
+\mitta{parindent}\-/ mitan levyisen välin voi tehdä mihin tahansa
+komennolla \komentom{indent}. Tätä komentoa ei tavallisesti tarvita,
+koska kappaleet alkavat automaattisesti sen suuruisella sisennyksellä.
+Tarpeellisempi komento on sen vastakohta \komentom{noindent}, joka
+voidaan kirjoittaa kappaleen alkuun estämään kyseisen kappaleen
+ensimmäisen rivin sisentäminen.
+
+\komentoi{noindent}
+\begin{koodilohkosis}
+\noindent
+Tämän tekstikappaleen ensimmäistä riviä ei sisennetä.
+\end{koodilohkosis}
+
+\noindent
+Suomenkielisissä julkaisuissa on tavallista, että leipätekstin
+kappaleessa ei ole sisennystä, jos sitä ennen on pystysuuntainen väli.
+Tällainen tilanne on aina otsikoiden jälkeen mutta myös kokonaan
+sisennetyn tekstikappaleen jälkeen tai kuvan, taulukon, luetelman tai
+muun vastaavan osan jälkeen, jos nämä ovat osa tekstivirtaa eivätkä
+leijuvia osia (luku \ref{luku/leijuosat}). Käytäntöön on joskus
+poikkeuksia suomenkielisessäkin typografiassa, mutta eri kielten välillä
+käytäntö voi vaihdella enemmänkin.
+
+Latex estää sisennyksen automaattisesti otsikoiden jälkeen mutta latoo
+sisennyksen kuitenkin kaikkien muiden elementtien ja pystysuuntaisen
+välin jälkeen. Jos sisennys halutaan estää, pitäisi kyseiset kappaleet
+aloittaa aina \komento{noindent}\-/komennolla.
+
+Toinen vaihtoehto on käyttää \pakettictan{noindentafter}\-/ pakettia ja
+määritellä sen tarjoaman komennon avulla, minkä ympäristöjen jälkeen ei
+haluta sisennystä. Seuraava esimerkki poistaa sisennyksen aina
+\ymparisto{list}- ja \ymparisto{tabular}\-/ ympäristöjen jälkeen (luvut
+\ref{luku/list-ympäristö} ja \ref{luku/taulukot}).
+
+\komentoi{NoIndentAfterEnv}
+\ymparistoi{list}
+\ymparistoi{tabular}
+\begin{koodilohkosis}
+\NoIndentAfterEnv{list}
+\NoIndentAfterEnv{tabular}
+\end{koodilohkosis}
+
+\noindent
+Tosin \paketti{noindentafter}\-/ paketti ei ole aina toiminut
+luotettavasti yhdessä \paketti{polyglossia}\-/ kielipaketin kanssa. Jos
+sisennyksen poistaminen ei tahdo toimia, kyse voi olla juuri tästä.
+
+Kolmas keino kappaleen ensimmäisen rivin sisennyksen estämiseksi jonkin
+ympäristön jälkeen on se, että aloittaa tekstikappaleen heti ympäristön
+lopettavan \komento{end}\-/ komennon jälkeen -- ilman tyhjää riviä.
+
+\subsection{Riippuva sisennys}
+\label{luku/riippuva-sisennys}
+
+Riippuva sisennys tarkoittaa tekstikappaleen muotoa, jossa sisennetään
+kappaleen muita rivejä mutta ei ensimmäistä. Riippuvaa sisennystä
+käytetään esimerkiksi kirjallisuus\-/{} ja lähdeluetteloissa, joissa on
+tarpeellista saada henkilön nimi tai muu lähdemerkinnän hakusana
+erottumaan selvästi vasemmassa reunassa. Tämän oppaan lopussa sivulla
+\pageref{luku/kirjallisuutta} on esimerkki lähdemerkinnöistä.
+
+Myös virallisten asiakirjojen muotoilussa käytetään riippuvaa
+sisennystä. Niissä kappaleen ensimmäinen rivi voi sisältää otsikon, joka
+on tasattu vasempaan marginaaliin. Otsikon perässä on sarkainhyppy
+tekstikappaleen sisennyksen tasalle, ja kappaleen muut rivit on
+sisennettynä samalla tasolle.
+
+\begin{esimerkki*}
+ \komentoi{hangpara}
+ \pakettii{hanging}
+ \komentoi{,}
+
+\begin{koodilohko}
+\hangpara{2cm}{1}Tässä tekstikappaleessa on riippuva sisennys. Kappale
+alkaa yhdellä sisentämättömällä rivillä, ja kappaleen seuraavat rivit
+on sisennetty 2\,cm. Ei ole kovin vaikeaa.
+\end{koodilohko}
+ \begin{tulos}
+ \hangpara{2cm}{1}Tässä tekstikappaleessa on riippuva sisennys. Kappale
+ alkaa yhdellä sisentämättömällä rivillä, ja kappaleen seuraavat rivit
+ on sisennetty 2\,cm. Ei ole kovin vaikeaa.
+ \end{tulos}
+ \caption{Riippuva sisennys \paketti{hanging}\-/ paketin ja sen
+ \komento{hangpara}\-/ komennon avulla}
+ \label{esim/riippuva-sis-hangpara}
+\end{esimerkki*}
+
+Helpoin tapa riippuvien sisennysten toteuttamiseen lienee
+\pakettictan{hanging}\-/ paketin käyttö. Paketti tuo uuden komennon
+\komentom{hangpara}, jonka käyttöä esimerkki
+\ref{esim/riippuva-sis-hangpara} selventää. Komennon ensimmäinen
+argumentti on sisennyksen mitta ja toinen argumentti (positiivinen
+kokonaisluku) määrittää, kuinka monta riviä kappaleen alusta jätetään
+sisentämättä. Jos taas toinen argumentti on negatiivinen luku, luvun
+itseisarvo määrittää, kuinka monta riviä kappaleen alusta sisennetään.
+
+Komennon \komento{hangpara} vaihtoehtona on ympäristö
+\ymparistom{hangparas}, jonka sisällä kaikki kappaleet sisennetään
+riippuvalla tyylillä samojen asetusten mukaisesti. Ympäristön
+aloituskomennolle annetaan samat argumentit kuin \komento{hangpara}\-/
+komennollekin.
+
+\ymparistoi{hangparas}
+\begin{koodilohkosis}
+\begin{hangparas}{2cm}{1}
+ ...
+\end{hangparas}
+\end{koodilohkosis}
+
+\begin{esimerkki*}
+ \komentoi{hangpara}
+ \komentoi{makebox}
+ \komentoi{,}
+
+\begin{koodilohko}
+\hangpara{2cm}{1}\makebox[2cm][l]{Otsikko}Tässä tekstikappaleessa on
+riippuva sisennys. Kappale alkaa yhdellä sisentämättömällä rivillä,
+joka sisältää näkymättömässä 2\,cm leveässä laatikossa olevan otsikon.
+Kappaleen muut rivit on sisennetty 2\,cm.
+\end{koodilohko}
+ \begin{tulos}
+ \hangpara{2cm}{1}\makebox[2cm][l]{Otsikko}Tässä tekstikappaleessa on
+ riippuva sisennys. Kappale alkaa yhdellä sisentämättömällä rivillä,
+ joka sisältää näkymättömässä 2\,cm leveässä laatikossa olevan otsikon.
+ Kappaleen muut rivit on sisennetty 2\,cm.
+ \end{tulos}
+ \caption{Asiakirjan tyylisten tekstikappaleiden toteutus}
+ \label{esim/riippuva-sis-asiakirja}
+\end{esimerkki*}
+
+\noindent
+Asiakirjan tyylisen otsikon saa toteutettua \komento{makebox}\-/
+komennon avulla esimerkin \ref{esim/riippuva-sis-asiakirja} tavoin.
+Komento latoo näkymättömän laatikon, jonka leveys määritellään
+sisennyksen levyiseksi ja jonka sisään kirjoitetaan otsikko. Jos
+asiakirjatyylisiä tekstikappaleita tarvitaan useita, kannattaa
+määritellä sarkainleveyttä ja sisennystä varten oma mitta ja
+tekstikappaleen kirjoittamista varten oma komento. Seuraavassa on siitä
+esimerkki:
+
+\komentoi{newlength}
+\komentoi{setlength}
+\komentoi{newcommand}
+\komentoi{makebox}
+\komentoi{par}
+\komentoi{hangpara}
+\komentoi{ignorespaces}
+\begin{koodilohkosis}
+\newlength{\sarkain}
+\setlength{\sarkain}{2.3cm}
+\newcommand{\kappale}[1][]{\par\hangpara{2\sarkain}{1}%
+ \makebox[2\sarkain][l]{\ignorespaces #1}\ignorespaces}
+\end{koodilohkosis}
+
+\noindent
+Tämän jälkeen voi komennolla \komentox{kappale} aloittaa asiakirjan
+sisennetyn tekstikappaleen. Komennolle voi antaa hakasulkeissa
+valinnaisen argumentin, joka on kappaleen otsikko. \komento{makebox}\-/
+komentoa ja muita laatikoita käsitellään tarkemmin luvussa
+\ref{luku/laatikot}.
+
+\begin{esimerkki*}
+ \ymparistoi{list}
+ \komentoi{setlength}
+ \mittai{leftmargin}
+ \mittai{itemindent}
+ \komentoi{item}
+ \komentoi{,}
+
+\begin{koodilohko}
+\begin{list}{}{
+ \setlength{\leftmargin}{2cm}
+ \setlength{\itemindent}{-2cm}
+ }
+\item Tässä tekstikappaleessa on riippuva sisennys. Kappale alkaa
+ yhdellä sisentämättömällä rivillä, ja kappaleen muut rivit on
+ sisennetty 2\,cm.
+\end{list}
+\end{koodilohko}
+ \caption{Riippuvan sisennyksen toteuttaminen \ymparisto{list}\-/
+ ympäristön avulla}
+ \label{esim/riippuva-sis-list}
+\end{esimerkki*}
+
+Riippuvan sisennyksen voi toteuttaa myös \ymparisto{list}\-/ ympäristön
+avulla. Se on tarkoitettu luetelmien tekemiseen, mutta sopivilla
+asetuksilla yksi ''luetelman'' kohta on riippuvasti sisennetty kappale.
+Tarkemmin \ymparisto{list}\-/ ympäristöä käsitellään luetelmien
+yhteydessä luvussa \ref{luku/list-ympäristö}, mutta oheisessa
+esimerkissä \ref{esim/riippuva-sis-list} on sopivat asetukset riippuvan
+sisennyksen toteuttamiseen. Kappale alkaa \komento{item}\-/ komennolla,
+koska kyseessä on ikään kuin luetelman kohta.
+
+\subsection{Vasen ja oikea sisennys sekä lohkolainaukset}
+\label{luku/lohkolainaukset}
+
+Dokumentteihin tarvitaan välillä kokonaisia sisennettyjä
+tekstikappaleita, koska leipätekstin ohessa halutaan näyttää
+muuntyyppistä sisältöä. Kyse voi olla teksti- tai kuvaesimerkeistä,
+esimerkiksi muualta lainatusta tekstistä. Tässä oppaassa käytetään
+paljon sisennettyjä tekstikappaleita Latex\-/koodien esimerkkeihin.
+
+Kokonaan sisennettyjä tekstikappaleita kutsutaan lohkolainauksiksi,
+koska ne ovat lainauksia, jotka käsittävät kokonaisen tekstilohkon.
+Lainausmerkkejä ei tarvitse käyttää, koska lainaus ilmaistaan
+typografisin keinoin. Sisennyksen lisäksi varsin yleistä on käyttää
+hieman pienempää kirjainleikkausta ja riviväliä kuin leipätekstissä.
+Joskus vasemman reunan sisennyksen lisäksi sisennetään myös oikeasta
+reunasta.
+
+Latexissa on tavallisille lohkolainauksille kolme erilaista ympäristöä:
+\ymparisto{quotation}, \ymparisto{quote} ja \ymparisto{verse}. Kaksi
+ensin mainittua on tarkoitettu normaalilla tavalla juoksevalle
+tekstille, kun taas kolmas on tarkoitettu runon säkeiden ja säkeistöjen
+latomiseen.
+
+\ymparistom{quotation}\-/ ympäristö sisentää tekstikappaleiden
+ensimmäisen rivin 1,5\,em:n verran, eikä kappaleiden välissä ole
+pystysuuntaista tilaa. \ymparistom{quote}\-/ ympäristö ei sisennä
+kappaleiden ensimmäistä riviä, ja se puolestaan erottaa kappaleet
+toisistaan pystysuuntaisen tilan avulla. \ymparisto{verse}\-/ ympäristöä
+käytetään siten, että lähdedokumentissa runon säkeet lopetetaan
+rivinvaihtokomentoon (\komento{\keno}), lukuun ottamatta säkeistön
+viimeistä säettä. Säkeistöt erotetaan toisistaan tyhjällä rivillä, kuten
+Latexissa tekstikappaleet muutenkin. Lopputuloksena on useimpiin
+runoihin sopiva ladontatapa, jossa säkeistöjen vasen reuna on samalla
+tasolla, oikealla on liehureuna ja säkeistöjen välissä on
+pystysuuntaista tilaa.
+
+Jos Latexin valmiit lohkolainausympäristöt eivät tuota haluttua
+lopputulosta, voi sisennetyt tekstikappaleet toteuttaa myös luetelmien
+tekemiseen tarkoitetun \ymparisto{list}\-/ ympäristön avulla (luku
+\ref{luku/list-ympäristö}). Sopivilla asetuksilla ''luetelma'' sisältää
+ihan tavallisen näköisiä tekstikappaleita, jotka vain on sisennetty
+vasemmalta tai oikealta tai molemmista reunoista.
+
+\begin{esimerkki*}
+ \ymparistoi{list}
+ \komentoi{setlength}
+ \mittai{leftmargin}
+ \mittai{rightmargin}
+ \mittai{itemindent}
+ \mittai{listparindent}
+ \mittai{parindent}
+ \mittai{parsep}
+ \mittai{topsep}
+ \mittai{partopsep}
+ \komentoi{item}
+ \komentoi{linespread}
+ \komentoi{small}
+
+\begin{koodilohko}
+\newenvironment{lohkolainaus}{%
+ \begin{list}{}{
+ \setlength{\leftmargin}{1cm}
+ \setlength{\rightmargin}{1cm}
+ \setlength{\itemindent}{0bp}
+ \setlength{\listparindent}{\parindent}
+ \setlength{\parsep}{\parskip}
+ \setlength{\topsep}{1em}
+ \setlength{\partopsep}{0bp}
+ }
+ \item\linespread{1}\small
+ }{\end{list}}
+\end{koodilohko}
+ \caption{Lohkolainausten eli tekstikappaleen vasemman ja oikean
+ sisennyksen toteutus \ymparisto{list}\-/ ympäristön avulla.
+ Esimerkkikoodi määrittelee uuden ympäristön nimeltä
+ \ymparistox{lohkolainaus}}
+ \label{esim/vasen-oikea-sisennys}
+\end{esimerkki*}
+
+Esimerkistä \ref{esim/vasen-oikea-sisennys} selviää, kuinka
+\ymparisto{list}\-/ ympäristöä voi käyttää sisennyksen toteuttamiseen.
+Esimerkki määrittelee uuden ympäristön nimeltä
+\ymparistox{lohkolainaus}, jota voi hyödyntää myöhemmin dokumentissa.
+
+\begin{koodilohkosis}
+\begin{lohkolainaus}
+ Tämä tekstikappale on sisennetty vasemmalta ja oikealta. Lisäksi
+ kirjainleikkaus on hieman pienempi (\small) kuin leipätekstissä.
+\end{lohkolainaus}
+\end{koodilohkosis}
+
+\noindent
+Omien ympäristöjen määrittelyä käsitellään tarkemmin luvussa
+\ref{luku/ympäristöt}. Esimerkin \ref{esim/vasen-oikea-sisennys} rivillä
+11 oleva \komento{item}\-/ komento on pakollinen, koska se aloittaa
+\ymparisto{list}\-/ ympäristöön kuuluvan luetelman kohdan. Sen perässä
+olevat komennot \komento{linespread} ja \komento{small} sen sijaan ovat
+vapaaehtoisia. Ne ovat mukana siksi, että on varsin tavallista latoa
+lohkolainaukset pienemmällä rivivälillä (rivikorkeudella) ja pienemmällä
+kirjainleikkauksella kuin leipäteksti.
+
+\subsection{Rivinvaihtokomennot}
+\label{luku/rivinvaihtokomennot}
+
+Latex\-/lähdedokumentissa olevat rivinvaihdot tulkitaan sanaväleiksi
+siinä missä välilyönnitkin, eli ne rivinvaihdot eivät päädy ladottuun
+dokumenttiin (luvut \ref{luku/sanaväli} ja
+\ref{luku/rivinvaihtomerkit}). Sen sijaan ladottuun dokumenttiin saadaan
+rivinvaihto käyttämällä komentoa \komentom{\keno} eli kaksi kenoviivaa.
+Komennon ei tarvitse sijaita lähdedokumentissa rivin lopussa.
+
+\komentoi{\keno}
+\begin{koodilohkosis}
+ensimmäinen \\ toinen \\
+kolmas
+\end{koodilohkosis}
+
+\begin{tulossis}
+ ensimmäinen \\* toinen \\* kolmas
+\end{tulossis}
+
+\noindent
+Rivinvaihtokomennolle voi antaa hakasulkeissa valinnaisen argumentin,
+joka ilmaisee rivien väliin ladottavan ylimääräisen pystysuuntaisen
+tilan. Argumentin on siis oltava mitta (luku \ref{luku/mitat}).
+
+\komentoi{\keno}
+\begin{koodilohkosis}
+ensimmäinen \\ toinen \\[1.3ex] kolmas
+\end{koodilohkosis}
+
+\begin{tulossis}
+ ensimmäinen \\* toinen \\*[1.3ex] kolmas
+\end{tulossis}
+
+\noindent
+Komennosta on olemassa tähtiversio \komentom{\keno *}, joka edellisten
+ominaisuuksien lisäksi estää sivun vaihtumisen tämän rivinvaihdon
+kohdalla. Myös tähtiversiolle voi antaa valinnaiseksi argumentiksi
+mitan. Sen merkitys on sama kuin komennon normaalilla versiollakin.
+
+Rivin voi vaihtaa myös komennolla \komentom{newline}, mutta tämä komento
+ei hyväksy valinnaista argumenttia eikä siitä ole tähdellistä versiota.
+Komennot \komento{newline} ja \komento{\keno} käyttäytyvät eri tavoin
+taulukoissa, joita käsitellään luvussa \ref{luku/taulukot}.
+
+\subsection{Lesket ja orvot}
+
+Leski- ja orporivit tarkoittavat typografiassa rumannäköisiä yksinäisiä
+rivejä. Leskirivi (\englanti{widow}) on tekstikappaleen viimeinen rivi,
+joka on yksinään sivun tai palstan yläreunassa. Orporivi
+(\englanti{orphan}) puolestaan on tekstikappaleen ensimmäinen rivi, joka
+on yksin sivun tai palstan alareunassa. Molemmat voivat näyttää
+ikävältä, mutta yleensä orporivejä ei pidetä kovin vakavana virheenä;
+leskien välttämisessä ollaan enemmän tosissaan.
+
+Ulkoasun lisäksi lesket ja orvot voivat olla ikäviä myös lukemisen
+kannalta. Kun tekstikappale vaihtuu, lukija pitää pienen tauon ja
+valmistautuu uuteen kappaleeseen. Sivun tai palstan olisi sopivaa
+vaihtua samassa kohdassa eli tekstikappaleiden välissä, mutta leski- ja
+orporivit aiheuttavat kaksi taukoa melkein peräkkäin: sekä kappaleiden
+välissä että sivun tai palstan vaihtumisen kohdalla.
+
+Latexissa leski- tai orporivit lienee käytännöllisintä estää
+\pakettictan{nowidow}\-/ paketin avulla. Paketin lataamisen jälkeen
+käytetään komentoa \komentom{setnowidow}, joka estää leskirivit eli
+pitää tekstikappaleen lopusta vähintään kaksi riviä yhdessä sivun tai
+palstan yläreunassa. Komennolle voi antaa hakasulkeissa valinnaisen
+argumentin (kokonaisluvun), joka ilmaisee, kuinka monta riviä täytyy
+vähintään pysyä yhdessä. Vastaavasti orporivit estetään komennolla
+\komentom{setnoclub}, joka toimii samalla tavalla. Molemmat komennot
+vaikuttavat koko dokumenttiin eli kaikkiin tekstikappaleisiin.
+
+\komentoi{usepackage}
+\pakettii{nowidow}
+\komentoi{setnowidow}
+\komentoi{setnoclub}
+\begin{koodilohkosis}
+\usepackage{nowidow}
+\setnowidow % leskirivien esto
+\setnoclub % orporivien esto
+\end{koodilohkosis}
+
+\noindent
+Paketti \paketti{nowidow} määrittelee myös komennot \komentom{nowidow}
+ja \komentom{noclub}, joilla voi vaikuttaa yksittäisen tekstikappaleen
+leski- ja orporiveihin. Nämä komennot täytyy sijoittaa tekstikappaleen
+loppuun, ja myös niille voi antaa hakasulkeissa valinnaiseksi
+argumentiksi luvun, joka kertoo yhdessä pidettävien rivien määrän.
+
+Jos ei halua tai voi käyttää \paketti{nowidow}\-/pakettia, voi leski- ja
+orporivit estää myös Texin matalan tason toimintojen avulla.
+Ladonta\-/algoritmi käyttää leski- ja orporiveissä sisäisesti
+haitallisuusarvoa tai sakkoarvoa (\englanti{penalty}), ja jos lesket ja
+orvot halutaan estää, määritellään niiden haitallisuusarvo
+mahdollisimman korkeaksi. Käytännössä arvo 10\,000 tarkoittaa samaa kuin
+ääretön, eli silloin lesken tai orvon haitallisuus on niin suuri, että
+sellaisia ei sallita.
+
+\komentoi{widowpenalty}
+\komentoi{clubpenalty}
+\begin{koodilohkosis}
+\widowpenalty 10000 % leskirivien esto
+\clubpenalty 10000 % orporivien esto
+\end{koodilohkosis}
+
+\noindent
+Leskien ja orpojen haitallisuusarvoiksi voi kokeilla hieman pienempiäkin
+lukuja. Silloin leski- tai orporivit voidaan sallia joissakin
+tilanteissa, jos ladonta\-/algoritmi ei löydä parempaakaan ratkaisua.
+
+Orvoksi kutsutaan myös tavua, joka jää yksin kappaleen viimeiselle
+riville. Se on häiritsevän näköinen ainakin silloin, kun tavu on
+kapeampi kuin seuraavan kappaleen ensimmäisen rivin sisennys.
+Orpotavujen estämiseen ei taida olla automaattisia keinoja, mutta
+kappaleen sanamäärää ja sanajärjestystä muuttamalla voi tietenkin
+vaikuttaa rivien latomiseen. Kappaleen viimeiseen sanaan voi kirjoittaa
+myös tavutusvihjeitä (\komento{-}) mutta jättää vihje pois ennen
+viimeistä tavua. Näin estetään lyhyen orpotavun muodostuminen.
+Tavutusvihjeitä ja muita tavutuksen asetuksia käsitellään
+luvussa~\ref{luku/tavutus}.
+
+\subsection{Marginaalihuomautukset}
+\label{luku/marginaalihuomautukset}
+
+Klassisessa kirjatypografiassa -- jota tämäkin opas suunnilleen
+noudattaa -- on aukeaman ulkoreunoissa melko suuret marginaalit. Niitä
+voidaan käyttää eräänlaisina apupalstoina, joihin voi kirjoittaa
+lyhyehköjä huomautuksia ja lisätietoa.
+
+Marginaalihuomautukset tehdään komennolla \komentom{marginpar}, jonka
+argumentiksi annetaan marginaaliin tuleva teksti. Marginaalin teksti
+ladotaan vasempaan tai oikeaan marginaaliin riippuen siitä, kumpi on
+aukeaman ulkoreunassa. Yksipuolisilla sivuilla teksti ladotaan
+oletuksena oikeaan marginaaliin. Mikäli sivu on kaksipalstaisessa
+tilassa (luku \ref{luku/palstat}), marginaalihuomautus ladotaan
+lähempänä olevaan marginaaliin.
+
+\komentoi{marginpar}
+\begin{koodilohkosis}
+Tämä on leipätekstin tekstikappale,
+\marginpar{Tämä ladotaan marginaaliin.}
+joka ladotaan sivun normaalille tekstialueelle.
+\end{koodilohkosis}
+
+% Miten valinnainen argumentti toimii? \marginpar[left]{right}
+
+\noindent
+Yleensä marginaalihuomautukset ladotaan erilaisella kirjainleikkauksella
+kuin leipäteksti, jotta ne erottuvat toisistaan. Jos leipätekstissä
+käytetään antiikvaa, voisi marginaalissa käyttää esimerkiksi pienempää
+groteskia. Tämän toteutusta varten kannattaa määritellä uusi komento,
+vaikkapa nimellä \komentox{huomautus}, jota käyttämällä
+marginaalihuomautukset saa helposti yhdenmukaiseksi. Seuraavassa on
+esimerkki tällaisen komennon määrittelystä:
+
+\komentoi{newcommand}
+\komentoi{marginpar}
+\komentoi{sffamily}
+\komentoi{scriptsize}
+\komentoi{RaggedRight}
+\begin{koodilohkosis}
+\newcommand{\huomautus}[1]{%
+ \marginpar{\sffamily\scriptsize\RaggedRight #1}}
+\end{koodilohkosis}
+
+\noindent
+Omien komentojen määrittelyä käsitellään tarkemmin luvussa
+\ref{luku/komennot} ja fonttiasetuksia luvussa~\ref{luku/kirjaintyypit}.
+Edellä olevassa komennon määrittelyssä on mukana myös palstan muotoon
+vaikuttava komento \komento{RaggedRight}, josta on lisätietoa luvussa
+\ref{luku/kappaleen-tasaus}.
+
+Tämän \marginpar{\sffamily \linespread{1} \scriptsize \RaggedRight Tässä
+ on pienellä groteskilla ladottu huomautus.} tekstikappaleen vieressä
+on esimerkki edellä mainitun tyylisestä marginaalihuomautuksesta.
+Kirjainleikkauksen on syytä olla selvästi pienempi ja riittävän
+erilainen kuin leipätekstissä, jotta huomautus ei häiritse liikaa
+leipätekstin lukemista. \noclub[3]
+
+Sivun marginaalissa olevan huomautuspalstan leveys voidaan määrittää
+sivun asetusten yhteydessä. Asetuksia hoitavan \paketti{geometry}\-/
+paketin valitsimella \koodi{marginparwidth} asetetaan palstan leveys ja
+valitsimella \koodi{marginparsep} palstan etäisyys leipätekstistä.
+Valitsimella \koodi{reversemarginpar} siirretään marginaalihuomautukset
+päinvastaiseen marginaaliin. Näitä ja muitakin sivun asetuksia
+käsitellään luvussa~\ref{luku/sivuasetukset}.
+
+Asetuksia voi muuttaa myös kesken dokumentin. Mitta
+\mitta{marginparwidth} määrittää marginaalihuomautuspalstan leveyden ja
+mitta \mitta{marginparsep} sen etäisyyden leipätekstistä. Lisäksi on
+mitta \mitta{marginparpush}, jolla asetetaan peräkkäisten
+marginaalihuomautusten vähimmäisetäisyys toisistaan. Seuraavassa on
+esimerkki näiden mittojen asettamisesta:
+
+\komentoi{setlength}
+\mittai{marginparwidth}
+\mittai{marginparsep}
+\mittai{marginparpush}
+\begin{koodilohkosis}
+\setlength{\marginparwidth}{50bp}
+\setlength{\marginparsep}{10bp}
+\setlength{\marginparpush}{6bp}
+\end{koodilohkosis}
+
+\noindent
+Kesken dokumentin komennolla \komentom{reversemarginpar} voidaan vaihtaa
+marginaalihuomautukset vastakkaiseen marginaaliin ja komennolla
+\komentom{normalmarginpar} palautetaan oletusasetukset.
+
+\subsection{Anfangit eli suurikokoiset alkukirjaimet}
+
+\lettrine[lines=3, loversize=.06, lhang=.02, findent=-5bp, nindent=4bp,
+slope=4bp]{A}{nfangit} ovat suurikokoisia tekstin alkukirjaimia.
+Tyypillisesti kirjaimen korkeus on kahdesta viiteen riviä ja se
+upotetaan kappaleen sisään, mutta joskus se sijoitetaan kokonaan
+marginaalin puolelle tai yltää normaalin tekstirivin yläpuolelle.
+Anfangikirjain voidaan latoa erilaisella kirjainleikkauksella kuin
+leipäteksti. Esimerkiksi vanhassa ja vanhantyylisessä typografiassa
+anfangiin voi sopia erityisen koristeellinen kirjain.
+
+\smallskip
+
+\lettrine[lines=2, lhang=1, nindent=0bp]{E\hspace{1.5bp}}{dellä
+ olevaan}, tähän ja seuraavaan tekstikappaleeseen anfangit sopivat
+huonosti, eikä niitä tavallisesti käytetä kirjan alalukujen alussa eikä
+väliotsikon jälkeen. Tässä ne ovatkin vain esimerkin vuoksi. Anfangien
+käytön varsinainen tarkoitus on osoittaa tekstin alkamiskohta
+esimerkiksi artikkelin alussa tai kirjan päälukujen alussa. Varsinkin
+aikakauslehden artikkelit sisältävät monenlaisia visuaalisia elementtejä
+kuten pää- ja alaotsikon, erillisen johdantokappaleen eli ingressin,
+kuvia ja tietolaatikoita. Anfangin avulla katse löytää artikkelin alun
+helposti.
+
+\lettrine[lines=1, loversize=.1, lhang=.02, findent=1.5bp]{K}{appaleen
+ aloittava sana} tai pidempikin ilmaus ladotaan joskus lihavoidulla
+kirjainleikkauksella tai pienversaalilla, kuten näissä esimerkeissä on
+tehty. Tällainen kappaleen aloitus voi toimia hieman otsikon tavoin tai
+sitten muuten vain ilmaisee uuden luvun alkamista.
+
+Latexissa anfangien tekemistä varten on paketti \pakettictan{lettrine},
+joka tarjoaa käyttöön samannimisen komennon. Jokainen anfangi on
+erilainen, ja siksi \komentom{lettrine}\-/ komentokin sisältää useita
+asetuksia anfangin ulkoasun hienosäätöön. Komentoa käytetään seuraavalla
+tavalla:
+
+\komentoi{lettrine}
+\begin{koodilohkosis}
+\lettrine[lines=3, loversize=.06, lhang=.02, findent=-5bp,
+ nindent=4bp, slope=4bp]{A}{nfangi} aloittaa tämän tekstikappaleen.
+\end{koodilohkosis}
+
+\noindent
+Edellä oleva esimerkki tekee kolmerivisen upotetun A\-/anfangin, jonka
+perässä oleva sanan osa ''nfangi'' ladotaan pienversaalilla.
+Valitsimella \koodi{lover\-size} kasvatetaan hieman anfangikirjaimen
+kokoa, ja \koodi{lhang}\-/ valitsimella siirretään kirjainta hieman
+vasemmalle marginaalin puolelle. Valitsin \koodi{findent} määrittää
+anfangikirjaimen rinnalla olevien rivien sisennyksen määrän suhteessa
+kirjaimeen. \koodi{nindent} määrittää toisen ja sitä seuraavien rivien
+sisennyksen suhteessa ensimmäiseen riviin, ja \koodi{slope} määrittää
+sisennysportaan, joka kertautuu joka rivillä kolmannesta rivistä alkaen.
+Näillä asetuksilla saadaan A\-/kirjaimen viistoa reunaa mukailevat
+rivien alut.
+
+Ennen \paketti{lettrine}\-/paketin käyttämistä kannattaa lukea paketin
+ohjekirjasta tietoa \komento{lettrine}\-/ komennon valitsimista ja myös
+teknisistä rajoituksista. Anfangit eivät toimi Latexissa teknisesti joka
+paikassa -- ja typografisesti vielä harvemmassa.
+
+\section{Tekstin korostaminen}
+\label{luku/korostus}
+
+Tekstin yksittäisten sanojen korostukset toteutetaan tavallisimmin
+siten, että käytetään leipätekstin kirjainperheestä jotakin poikkeavaa
+kirjainleikkausta, esimerkiksi \textit{kursiivia},
+\textsl{kallistettua}, \textbf{lihavoitua} tai \textsc{pienversaalia}.
+Joskus vaihdetaan koko kirjainperhe toiseksi, esimerkiksi ladotaan
+\textrm{antiikvan} sekaan \textsf{groteskia} tai \texttt{tasalevyistä}.
+
+Korostukset siis liittyvät läheisesti fonttien valintaan ja asetuksiin,
+ja siksi korostusten teknistä toteuttamista ja Latex\-/komentoja
+käsitellään pääasiassa fonttien yhteydessä luvussa
+\ref{luku/fontit-korkea}. Siellä muun muassa neuvotaan, kuinka
+kirjainperheet ja niiden eri kirjainleikkaukset valitaan. Sen sijaan nyt
+käsillä olevassa luvussa keskitytään tekstin korostamisen typografisiin
+käytäntöihin ja suosituksiin. Joitakin uusia komentojakin esitellään.
+
+Tekstissä sanoja korostetaan siksi, että halutaan niiden erottuvan
+ympäristöstään. Tärkeän avainsanan pitää ehkä erottua tekstipalstasta
+niin, että sen huomaa nopeasti tekstiä silmäilemällä. Se voi helpottaa
+tiedon löytämistä.
+
+Sanoja tai ilmauksia korostetaan toisinaan myös siksi, että ne eivät ole
+kielen sanoja tavallisessa merkityksessään vaan lainauksia kielestä tai
+toisesta tekstityypistä. Ihmiskieltä käsittelevissä teksteissä on
+tavallista kursivoida sanat silloin, kun viitataan itse sanoihin eikä
+varsinaisesti käytetä kyseisiä sanoja. Sanoihin ja muuhun kieliainekseen
+viitatessa voi tosin käyttää myös lainausmerkkejä. Tietotekniikan
+koodikielen esimerkit ladotaan usein leipätekstistä poikkeavalla
+fontilla, jotta käy selväksi, että kyse on koodikielisestä lainauksesta.
+Tällöin hyvin tavallista on tasalevyisen fontin käyttö, koska se
+jäljittelee tekstieditorien ja komentotulkkia suorittavien
+pääteohjelmien fonttia.
+
+Sopivan korostustavan valinnassa on olennaista saavuttaa riittävä
+kontrasti ympäröivään tekstiin. Liian lievä muutos ei erotu; toisaalta
+liian räikeä muutos voi olla häiritsevä. Yhteensopivat korostuskeinot
+saadaankin lähes aina saman kirjainperheen sisältä, eri leikkauksia
+käyttämällä.
+
+\subsection{Kursiivi, kallistus ja lihavointi}
+\label{luku/peruskorostukset}
+
+Antiikvatyyppisen kirjainleikkauksen korostamiseen sopii yleensä
+parhaiten saman perheen \textit{kursiivi} (\komentom{textit}).
+Lihavointi toimii huonommin antiikvan kanssa, koska pelkkä merkkien
+viivojen vahvistaminen ei tuo riittävää kontrastia.
+
+\begin{tulossis}
+ \rmfamily Antiikvaperheen \textit{kursiivileikkaus} tuo yleensä
+ voimakkaan muotokontrastin ja on tyylillisesti yhteensopiva
+ korostuskeino. Sen sijaan \textbf{lihavointi} erottuu antiikvassa
+ huonommin.
+\end{tulossis}
+
+\noindent
+\textbf{Lihavointi} (\komentom{textbf}) toimii huomattavasti paremmin
+groteskityyppisen kirjainperheen kanssa, koska lihavoitu leikkaus on
+usein selvästi vahvempi normaaliin verrattuna. Groteskin kursiivi sen
+sijaan ei monesti edes ole varsinainen kursiivileikkaus vaan pelkkä
+lievä kallistus (\komentom{textsl}). Sellainen ei välttämättä tuo
+riittävää muotokontrastia.\footnote{Joissakin niin sanotuissa
+ humanistisissa groteskiperheissä on mukana ihan käyttökelpoinen ja
+ selvästi erottuva kursiivileikkaus.}
+
+\begin{tulossis}
+ \sffamily Groteskia on tavallista korostaa \textbf{lihavoinnilla} eli
+ leikkauksella, joka on selvästi tavallista vahvempi. Sen sijaan
+ \textit{kursiivi} tai \textsl{kallistus} ei kaikissa groteskiperheissä
+ erotu riittävästi.
+\end{tulossis}
+
+\noindent
+Joissakin kirjainperheissä on mukana useita erivahvuisia leikkauksia.
+Silloin täytyy valita käyttöön riittävästi toisistaan poikkeavat
+vahvuudet. Esimerkiksi kaksi vierekkäistä vahvuutta eivät välttämättä
+poikkea toisistaan riittävästi, eikä selvää vahvuuskontrastia synny.
+
+Mikäli leipätekstissä käytetään sulkeita ja niiden sisällä kursivoitua
+ilmausta (\textit{kuten tässä}), ei itse suljemerkkejä pidä kursivoida,
+koska ne kuuluvat ulompaan tekstiin. Jos sulkeiden ulkopuolellakin on
+voimassa kursivointi, voi itse sulkeetkin kursivoida.
+
+Latexissa kursiivin voi toteuttaa myös komennolla \komentom{emph}, joka
+huomioi ympärillä olevan korostustilan. Tavallisesti komento kursivoi
+argumentiksi annetun tekstin, mutta jos kursivointi on jo päällä
+komennon ympärillä, se latookin argumentiksi annetun tekstin
+tavallisella pystyasentoisella kirjainleikkauksella. Komennon ajatuksena
+on, että voidaan samalla komennolla korostaa sekä pystyasentoisen
+tekstin että kursiivin keskellä, eikä tarvitse välittää tai tietää,
+kumpi leikkaus on voimassa.
+
+\komentoi{emph}
+\begin{koodilohkosis}
+tavallinen \emph{korostettu} tavallinen \\
+\emph{korostettu \emph{kaksoiskorostettu} korostettu}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ tavallinen \emph{korostettu} tavallinen \\
+ \emph{korostettu \emph{kaksoiskorostettu} korostettu}
+\end{tulossis}
+
+\subsection{Pienversaali eli kapiteeli}
+\label{luku/korostus-pienversaali}
+
+Melko rauhallinen typografinen keino on \textsc{pienversaali} eli
+kapiteeli (\komentom{textsc}), jonka kirjaimet näyttävät
+versaalikirjaimilta mutta ovat suunnilleen gemenakirjainten eli pienten
+kirjainten korkuisia. Pienversaali on fonttiin sisältyvä erillinen
+kirjainmuotoilijan piirtämä leikkaus, eli se ei ole tietokoneen
+mekaanisesti pienentämä versio versaalikirjaimista. Jos fonttiin ei
+sisälly pienversaalia ja sellaisen silti haluaa omaan
+keinovalikoimaansa, voi yrittää vähemmän tyylikästä mekaanista
+toteutusta luvussa \ref{luku/fontit-keinopienversaali} kerrotuilla
+asetuksilla. Luvuissa \ref{luku/fontit-välistys} ja
+\ref{luku/korostus-harvennus} puolestaan käsitellään merkkivälien
+{\scshape\addfontfeatures{LetterSpace=6} harvennusta}, joka voi
+maltillisesti käytettynä sopia pienversaaleihin.
+
+Korostustarkoituksessa pienversaalia käytetään esimerkiksi pienissä
+väliotsikoissa, koska sen avulla syntyy selvä muotokontrasti
+leipätekstin kanssa. Toisinaan tekstikappaleen ensimmäisiä sanoja
+ladotaan pienversaalilla, jolloin se toimii otsikon kaltaisessa
+tehtävässä. Myös kirjallisuus\-/{} ja lähdeluetteloissa käytetään
+välillä pienversaalia tekijöiden nimissä, koska se helpottaa nimen
+mukaan aakkostetun luettelon silmäilyä.
+
+Pienversaalia käytetään toisinaan versaalikirjainten sijasta. Silloin
+tarkoituksena ei ole tekstin korostamiseen vaan päinvastoin häiritsevän
+korostuksen välttäminen. Esimerkiksi versaalikirjaimiset lyhenteet (SPR,
+HTML) voivat paljon käytettynä erottua leipätekstistä ikävän selvästi,
+eikä tekstipalsta näytä tasaiselta. Pienversaalit sulautuvat muuhun
+tekstiin paremmin (\textsc{spr}, \textsc{html}).
+
+Typografisesta estetiikasta juontuu sekin, että pienversaali on sopiva
+pari gemenanumeroiden kanssa erilaisiin teknisiin koodeihin ja muihin
+ilmauksiin, jotka koostuvat kirjaimista ja numeroista. Sen sijaan
+versaalikirjaimia ja gemenanumeroita ei sovi käyttää yhdessä, koska
+merkkien kokoero on häiritsevän suuri. Kuten seuraavista esimerkeistä
+näkyy, versaalit ovat joskus miltei kaksinkertaisia gemenanumeroihin
+verrattuna, ja muutenkin gemenanumerot asettuvat keskimäärin eri
+korkeustasolle.
+
+\begin{tulossis}
+ \begin{tabular}[t]{@{}lll}
+ Väärin:
+ & {\gemenanum ISO-8859-1}
+ & {\gemenanum 2012 a.D.} \\[1ex]
+ Oikein:
+ & {\gemenanum\scshape iso-8859-1}
+ & {\gemenanum\scshape 2012 a.d.} \\[1ex]
+ Oikein:
+ & {\versaalinum ISO-8859-1}
+ & {\versaalinum 2012 A.D.} \\
+ \end{tabular}
+\end{tulossis}
+
+\noindent
+Fontin näkökulmasta gemenanumerot ovat erillinen ominaisuus, jonka
+fontin suunnittelija on toteuttanut. Ominaisuuden käyttöönottoa ja muita
+numeroihin liittyviä fonttiasetuksia käsitellään luvussa
+\ref{luku/fontit-numerot}.
+
+\subsection{Alleviivaus ja yliviivaus}
+
+Alleviivaus on käsin kirjoitetun tekstin ja mekaanisten
+kirjoituskoneiden korostuskeino, mutta nykyajan typografiaan se ei
+oikeastaan sovi. Alleviivaus nimittäin vaikeuttaa kirjainhahmojen
+tunnistamista ja hidastaa lukemista. Parempia korostuskeinoja ovat
+esimerkiksi kursiivi ja lihavointi. Alleviivaus voi kuitenkin joskus
+olla kätevä keino ohjata lukijan huomio tiettyyn kohtaan esimerkiksi
+pidemmässä esimerkkitekstissä.
+
+Latexin oma alleviivauskomento \komentom{underline} piirtää viivan
+tekstin tai muun argumentiksi annetun sisällön alapuolelle. Komennon
+huono puoli on, että erilliset alleviivaukset eivät välttämättä osu
+samalle korkeudelle. Seuraavassa esimerkissä toisen sanan alleviivaus on
+alempana j- ja y\=/kirjainten alapidennyksen vuoksi.
+
+\komentoi{underline}
+\begin{koodilohkosis}
+\underline{kone}, \underline{öljy}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \underline{kone}, \underline{öljy}
+\end{tulossis}
+
+\noindent
+Toinen \komento{underline}\-/ komennon ongelma on, että se estää sanojen
+tavuttamisen ja muutenkin tekstin katkaisemisen rivin lopussa. Komennon
+argumentiksi annettua tekstiä ei katkaista edes sanavälien kohdalta.
+Komennon hyvä puoli on, että se toimii myös matematiikkatilassa
+(luku~\ref{luku/matematiikka}).
+
+Käytännössä alleviivaukset on parempi toteuttaa esimerkiksi paketin
+\pakettictan{ulem} avulla. Tavallisen alleviivauksen lisäksi se sisältää
+kaksoisalleviivauksen, aaltoviivat, pisteviivat ja erilaisia
+ylikirjoitusmerkintöjä. Taulukkoon \ref{tlk/ulem} on koottu paketin
+sisältämiä komentoja.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\komento{#1} & #2}
+ % \setlength{\ULdepth}{.2ex}
+ \begin{tabular}{llll}
+ \toprule
+ \ots{Komento}
+ & \ots{Merkitys} & \ots{Komento} & \ots{Merkitys} \\
+ \cmidrule(r){1-2}
+ \cmidrule(l){3-4}
+ \rivi{uline}{\uline{alleviivaus}}
+ & \rivi{uuline}{\uuline{kaksoisalleviivaus}} \\
+ \rivi{uwave}{\uwave{aaltoviiva}}
+ & \rivi{sout}{\sout{yliviivaus}} \\
+ \rivi{dashuline}{\dashuline{katkoviiva}}
+ & \rivi{xout}{\xout{poisto}} \\
+ \rivi{dotuline}{\dotuline{pisteviiva}} \\
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Alleviivaus- ja ylikirjoitusmerkintöjä \paketti{ulem}\-/
+ paketin komentojen avulla}
+ \label{tlk/ulem}
+}
+
+Oletuksena \paketti{ulem}\-/ paketti määrittelee Latexin
+\komento{emph}\-/ korostuskomennon (luku \ref{luku/peruskorostukset})
+uudelleen siten, että komento tuottaa kursiivin sijasta alleviivattua
+tekstiä. Ajatuksena lienee se, että paketin avulla voi helposti muuttaa
+typografisen peruskorostusten eli kursiivin tilalle kirjoituskoneen
+korostustavan eli alleviivauksen. Käytännössä tällaista tuskin halutaan
+koskaan, ja onneksi paketin lataamisen yhteydessä voi käyttää valitsinta
+\koodi{nor\-mal\-em}, joka estää Latexin komentojen uudelleen
+määrittelyn.
+
+\pakettii{ulem}
+\komentoi{usepackage}
+\begin{koodilohkosis}
+\usepackage[normalem]{ulem}
+\end{koodilohkosis}
+
+\noindent
+Paketin \paketti{ulem} myötä on käytettävissä mitta \mitta{ULdepth},
+joka on alleviivauksen etäisyys tekstin peruslinjasta. Mitta asetetaan
+\komento{setlength}\-/ komennolla (luku \ref{luku/mitat}). Viivan
+paksuus puolestaan sisältyy komennon \komento{ULthickness} määritelmään,
+ja komennon voi halutessaan määritellä uudestaan. Seuraavassa on näistä
+esimerkki:
+
+\komentoi{setlength}
+\mittai{ULdepth}
+\komentoi{renewcommand}
+\komentoi{ULthickness}
+\komentoi{uline}
+\begin{koodilohkosis}
+\setlength{\ULdepth}{.2ex} % viivan etäisyys
+\renewcommand{\ULthickness}{.1ex} % viivan paksuus
+\uline{kone}, \uline{öljy}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \setlength{\ULdepth}{.2ex}
+ \renewcommand{\ULthickness}{.1ex}
+ \uline{kone}, \uline{öljy}
+\end{tulossis}
+
+\noindent
+Toinen paketti alleviivausten ja yliviivausten tekemiseen on
+\pakettictan{soul}. Se ei sisällä erikoisempia korostustapoja kuten
+aalto- ja katkoviivoja, mutta viivan etäisyyden ja paksuuden
+määrittämiseen on hieman kätevämmät komennot.
+
+Tekstin alleviivauksen lisäksi on olemassa pari komentoa, joilla saa
+ladottua pelkän viivan ilman tekstiä. Komento \komento{hrulefill} latoo
+kaiken tilan täyttävän alaviivan ja komento \komento{dotfill} kaiken
+tilan täyttävän pisteviivan. Myös \komento{rule}\-/ komento voi soveltua
+alaviivojen toteuttamiseen. Komentoa käsitellään erikoismerkkien
+yhteydessä luvussa \ref{luku/tarkkeet}.
+
+\komentoi{hrulefill}
+\komentoi{dotfill}
+\komentoi{rule}
+\begin{koodilohkosis}
+abc \hrulefill\ abc \dotfill\ abc \rule[-.3ex]{5em}{.4bp} abc
+\end{koodilohkosis}
+
+\begin{tulossis}
+ abc \hrulefill\ abc \dotfill\ abc \rule[-.3ex]{5em}{.4bp} abc
+\end{tulossis}
+
+\subsection{Harvennus ja tiivistys}
+\label{luku/korostus-harvennus}
+
+Merkkivälien harventaminen on tyyli- tai korostuskeino, joka juontuu
+antiikin roomalaisten kiveen hakatuista teksteistä. Historiansa vuoksi
+harvennus sopii luontevimmin antiikvan eli pääteviivallisen
+kirjainperheen versaali\-/\ tai pienversaalikirjainten (luku
+\ref{luku/korostus-pienversaali}) kanssa. Antiikin aikana
+gemenakirjaimet eivät olleet vielä käytössä. Tässä alaluvussa
+keskitytään harventamisen ja tiivistämisen typografiaan; teknisiä
+ohjeita on luvussa \ref{luku/fontit-välistys}.
+
+\komentoi{large}
+\komentoi{addfontfeatures}
+\begin{koodilohkosis}
+\large TAVALLINEN \\
+{\addfontfeatures{LetterSpace=10} KLASSINEN HARVENNUS}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \large
+ TAVALLINEN \\
+ {\addfontfeatures{LetterSpace=10} KLASSINEN HARVENNUS}
+\end{tulossis}
+
+\noindent
+Klassisesti eli antiikin tyyliin harvennetut (n.~10\,\%)
+versaalikirjaimet voivat sopia joihinkin otsikoihin. Sen sijaan
+pienversaalit lievästi {\addfontfeatures{LetterSpace=6}
+ \textsc{harvennettuna}} (esim.~6\,\%) voivat olla tyylikäs
+tehostuskeino leipätekstiin.
+
+Edellisiä esimerkkejä suurempi harvennus on huomiota herättävä
+korostus\-/\ tai tehokeino, joka voi sopia yksittäisiin sanoihin
+leipätekstin ulkopuolella. Jos kirjaimet ovat hyvinkin kaukana
+toisistaan, täytyy sanan ympärillä olla runsaasti tyhjää tilaa, jotta
+sanahahmo pysyy visuaalisesti koossa.
+
+\komentoi{sffamily}
+\komentoi{bfseries}
+\komentoi{addfontfeatures}
+\begin{koodilohkosis}
+{\sffamily\bfseries\addfontfeatures{LetterSpace=40} SEIS!}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ {\sffamily\bfseries\addfontfeatures{LetterSpace=40} SEIS!}
+\end{tulossis}
+
+\noindent
+Merkkivälien tiivistäminen on joskus tarpeen suurikokoisissa otsikoissa.
+Fontin merkkivälit on ehkä suunniteltu ensisijaisesti pienten kokojen
+ehdoilla, ja siksi reilusti suuremmilla fonttiko'oilla välit voivat olla
+häiritsevän suuria. Erityisesti tämä pätee groteskiin eli
+pääteviivattomaan kirjainperheeseen, kuten kuva
+\ref{kuva/otsikon-tiivistys} osoittaa. Antiikvat eivät yleensä siedä
+tiivistämistä, koska kirjainten pääteviivat asettuvat helposti
+päällekkäin.
+
+\leijukuva{
+ \sffamily\fontsize{50bp}{50bp}\selectfont
+ Tavallinen \\
+ \addfontfeatures{LetterSpace=-5} Tiivistetty
+}{
+ \caption{Otsikoiden merkkivälien tiivistäminen voi olla tarpeen
+ suurikokoisen groteskin kanssa -- varsinkin jos lihavointi ei ole
+ käytössä}
+ \label{kuva/otsikon-tiivistys}
+}
+
+\subsection{Tietokonekoodi ja tasalevyinen kirjainperhe}
+
+Tietokonekoodi tai muu vastaava tekninen, koneelle syötettävä tai koneen
+tulostama koodi on tapana esittää \texttt{tasalevyisellä} fontilla.
+Kyseessä on ikään kuin lainaus toisenlaisesta tekstityypistä, joka ei
+ole luonnollista kieltä lainkaan.
+
+Tasalevyinen kirjainperhe määritellään fonttiasetusten yhteydessä (luku
+\ref{luku/fontin-valinta}) ja valitaan käyttöön esimerkiksi komennolla
+\komentom{texttt}. Tasalevyisellä fontilla ladottava teksti on
+tavallisesti tietokonekoodia, joten sille on asetettu hieman
+toisenlaiset oletusasetukset kuin muille kirjainperheille. Oletuksena
+tekstiä ei tavuteta, ja esimerkiksi \komento{texttt}\-/ komennon
+argumentiksi annettu teksti katkaistaan vain sanavälien ja yhdysmerkkien
+kohdalta. Myös niin sanotut Tex\-/ligatuurit (esim. \koodi{''}
+ja~\koodi{--}) on kytketty pois päältä. Fonttien oletusasetuksia ja
+niiden muuttamista käsitellään luvussa
+\ref{luku/fontit-oletusasetukset}. Tex\-/ligatuureja eli Texin
+merkintätapoja lainausmerkeille ja ajatusviivoille käsitellään luvuissa
+\ref{luku/lainausmerkit} ja \ref{luku/yhdys-ajatus-miinus}.
+
+Toinen vaihtoehto tasalevyisen tekstin tuottamiseen on
+\komentom{verb}\-/ komento. Komennon nimi on lyhennetty englannin kielen
+sanasta \englantik{verbatim}, joka tarkoittaa 'kirjaimellisesti' tai
+'sananmukaisesti'. Niin se juuri toimiikin, eli \keno{verb}\-/
+komennolle annettu argumentti tulkitaan kirjaimellisesti.
+Tex\-/järjestelmän omat merkintätavat kuten kenoviivalla (\koodi{\keno})
+alkavat komennot eivät toimi tämän komennon argumentissa.
+
+\komento{verb}\-/ komennon argumentti täytyy ilmaista tavallisesta
+poikkeavalla tavalla. Välittömästi komennon nimen jälkeen tuleva merkki
+on oleva argumentin aloitus- ja lopetusmerkki. Niiden välissä oleva
+teksti tulkitaan kirjaimellisesti ja ladotaan tasalevyisellä
+kirjainperheellä. Seuraavassa on tästä kaksi esimerkkiä:
+
+\komentoi{verb}
+\begin{koodilohkosis}
+\verb.tasalevyinen. % aloitus- ja lopetusmerkkinä piste
+\verb|tasalevyinen| % aloitus- ja lopetusmerkkinä pystyviiva
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \verb.tasalevyinen.
+ \verb|tasalevyinen|
+\end{tulossis}
+
+\noindent
+Yksittäisiä sanoja pidempien tietokonekoodien latomiseen on olemassa
+\ymparistom{verbatim}\-/ ympäristö, jonka sisällä kaikki teksti
+tulkitaan kirjaimellisesti -- myös välilyönnit ja rivinvaihdot.
+
+\ymparistoi{verbatim}
+\begin{koodilohkosis}
+\begin{verbatim}
+tieto- kone-
+ koodia
+\end{verbatim}
+\end{koodilohkosis}
+
+\begin{tulossis}
+\begin{verbatim}
+tieto- kone-
+ koodia
+\end{verbatim}
+\end{tulossis}
+
+\noindent
+Paljon monipuolisemman ympäristön tarjoaa paketti
+\pakettictan{fancyvrb}. Sen mukana tuleva \ymparistom{Verbatim}\-/
+ympäristö ymmärtää monenlaisia asetuksia, joilla vaikutetaan
+tietokonekoodin latomiseen. Koodiin saa mukaan esimerkiksi rivinumerot,
+tai sen voi latoa kehyksen sisään. Myös koodin sisennykseen, fontin
+kokoon ja väreihin voi vaikuttaa.
+
+\subsection{Verkko-osoitteet}
+
+Verkko\-/osoitteiden eli internetin linkkien latominen voi olla
+pienoinen typografinen ongelma: osoitteet ovat pitkiä, eivätkä ne
+sisällä välilyöntejä, joista ne voisi luontevasti katkaista rivin
+vaihtumisen kohdalla. Tavuviivojen lisääminen rivin loppuun voi olla
+ongelmallista, koska kyse on teknisestä merkkijonosta, joka pitäisi
+tulkita kirjaimellisesti.
+
+Parasta olisi latoa verkko\-/osoitteet leipäteksti ulkopuolelle,
+esimerkiksi sivun alareunaan alaviitteeksi (luku
+\ref{luku/alaviitteet}). Tällä tavoin pitkät ja joskus rumat osoitteet
+eivät häiritse leipätekstin lukemista mutta ovat silti lukijan
+saatavilla.
+
+Latexissa verkko\-/osoitteet kannattaa toteuttaa siihen tarkoitetun
+paketin avulla. Paketti \pakettictan{hyperref} sisältää toimintoja
+paitsi verkko\-/ osoitteiden latomiseen mutta myös pdf\-/tiedoston
+asetusten ja ristiviitteiden hallintaan (luku \ref{luku/pdf-asetukset}).
+Paketin avulla valmiin pdf\-/ tiedoston verkkolinkit toimivat, eli
+pdf\-/lukijassa linkkiä napsauttamalla pitäisi avautua verkkoselain ja
+linkin osoittama sivu.
+
+Paketin käyttämisen typografinen hyöty on se, että rivin vaihdon
+kohdalle sattuvat verkko\-/ osoitteet katkaistaan automaattisesti
+luontevista kohdista eli vain tiettyjen välimerkkien jälkeen.
+Tavuviivoja ei lisätä rivin loppuun. Myös typografiset ligatuurit (luku
+\ref{luku/typo-liga}) kytketään pois päältä.
+
+\paketti{hyperref}\-/paketin ohjekirja neuvoo lataamaan paketin
+viimeisenä eli muiden pakettien lataamisen jälkeen, koska se
+muokkaa joidenkin muualla määriteltyjen komentojen ominaisuuksia.
+
+\komentoi{usepackage}
+\pakettii{hyperref}
+\komentoi{hypersetup}
+\komentoi{urlstyle}
+\begin{koodilohkosis}
+\usepackage{hyperref} % paketin lataaminen
+\hypersetup{hidelinks} % linkeistä pois kehykset
+\urlstyle{same} % linkkien fontti
+\end{koodilohkosis}
+
+\noindent
+Edellisen esimerkin komennolla \komentom{hypersetup} vaikutetaan
+paketin asetuksiin. Oletuksena esimerkiksi linkkien ympärille
+ladotaan värilliset kehykset, mutta valitsin \koodi{hide\-links} poistaa
+ne. Valitsimella \koodi{url\-color} voisi vaihtaa verkko\-/osoitteiden
+kehyksen väriä.
+
+Esimerkin seuraava komento \komentom{urlstyle} määrittää, mitä
+kirjainperhettä käytetään verkko\-/ osoitteiden latomiseen. Komennon
+argumentti \koodi{same} tarkoittaa, että käytetään samaa kirjainperhettä
+kuin ympärillä olevassa tekstissä. Tietty kiinteä kirjainperhe valitaan
+\komento{urlstyle}\-/ komennon argumentilla \koodi{rm} (antiikva,
+roman), \koodi{sf} (groteski, sans serif) tai \koodi{tt} (tasalevyinen).
+Oletusasetus on tasalevyinen kirjainperhe.
+
+Verkko\-/ osoitteiden ilmaisemisen peruskomento on \komentom{href},
+jolle annetaan kaksi pakollista argumenttia: ensimmäinen on varsinainen
+osoite ja toinen on dokumenttiin ladottava teksti. Linkin teksti voi
+siis olla mitä hyvänsä tekstiä, ja pdf\-/ lukijassa tekstiä
+napsauttamalla linkin osoittama sivusto avautuu.
+
+\komentoi{href}
+\begin{koodilohkosis}
+\href{https://www.ctan.org/}{CTAN-sivusto}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \href{https://www.ctan.org/}{CTAN-sivusto}
+\end{tulossis}
+
+\noindent
+Kun halutaan latoa dokumenttiin itse verkko\-/osoite, käytetään komentoa
+\komento{url}, \komentomargin{url} joka osaa katkaista osoitteet
+järkevällä tavalla rivin lopussa. Komennolle annetaan vain yksi
+argumentti, verkko\-/osoite.
+
+\komentoi{url}
+\begin{koodilohkosis}
+\url{https://www.ctan.org/}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \url{https://www.ctan.org/}
+\end{tulossis}
+
+\noindent
+Joskus dokumenttiin voidaan tarvita verkko\-/osoite, joka ei ole
+pdf\-/dokumentissa napsautettava linkki. Silloin käytetään komentoa
+\komentom{nolinkurl}. Tämän komennon argumenttina oleva verkko\-/osoite
+ainoastaan ladotaan osoitteiden tavoin.
+
+Linkkinä toimivien sähköpostiosoitteiden latominen vaatii
+\komento{href}- ja \komento{nolinkurl}\-/ komentojen yhdistämistä.
+Linkin alkuun täytyy lisätä sana \koodi{mailto:}, mutta tuota sanaa
+tuskin halutaan näkyviin itse dokumenttiin. Niinpä sähköpostiosoite
+kannattaa kirjoittaa seuraavalla tavalla:
+
+\komentoi{href}
+\komentoi{nolinkurl}
+\begin{koodilohkosis}
+\href{mailto:tunnus@osoite.net}{\nolinkurl{tunnus@osoite.net}}
+\end{koodilohkosis}
+
+\noindent
+Osoite pitää siis kirjoittaa kaksi kertaa: itse linkkiä varten ja
+dokumenttiin ladottavaa tekstiä varten. Omaa työtä kannattaa helpottaa
+määrittelemällä sähköpostiosoitteita varten oma komento, esimerkiksi
+seuraavalla tavalla:
+
+\komentoi{newcommand}
+\komentoi{href}
+\komentoi{nolinkurl}
+\begin{koodilohkosis}
+\newcommand{\sposti}[1]{\href{mailto:#1}{\nolinkurl{#1}}}
+\end{koodilohkosis}
+
+\subsection{Värit}
+\label{luku/korostus-värit}
+
+Eri värien käyttö voi sopia tekstin erilaisten osien korostamiseen.
+Esimerkiksi otsikot, taulukot tai leijuvat osat saa erottumaan
+selvemmin, kun niiden toteutuksessa käyttää värejä. Sen sijaan
+leipätekstin sisällä värejä täytynee käyttää hillitysti, sillä värikäs
+tekstipalsta näyttää rauhattomalta ja voi hidastaa lukemista.
+
+Latexiin saa värit \pakettictan{xcolor}\-/ paketin
+avulla.\footnote{Toinen vaihtoehto on yksinkertaisempi väripaketti
+ \paketti{color}, joka sisältää värien käsittelyn perustoiminnot.} Se
+tarjoaa muun muassa komentoja, joilla tekstin väriä, tekstin taustaväriä
+tai sivun taustaväriä voi muuttaa. Lisäksi se sisältää värien
+sekoittamiseen ja muuntamiseen liittyvää tekniikkaa. Paketin komentojen
+avulla voi myös värittää taulukoiden (luku \ref{luku/taulukot}) rivit
+vuorottelevin värein.
+
+Omassa dokumentissa käytettävät värit on hyvä määritellä alussa.
+Määrittely tarkoittaa sitä, että annetaan väreille nimet -- esimerkiksi
+käyttötarkoituksen mukaan -- ja myöhemmin lähdedokumentissa viitataan
+väreihin käyttämällä alussa määriteltyjä nimiä. Näin väri on määritelty
+yhdessä paikassa ja sen muuttaminen on myöhemmin helppoa. On kyllä
+mahdollista käyttää värejä ilman etukäteismäärittelyäkin.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[3]{\koodi{#1} & #2 & \koodi{#3}
+ & \textcolor[#1]{#3}{\rule{.9em}{.9em}} \\}
+ \begin{tabular}{llll}
+ \toprule
+ \ots{Malli}
+ & \ots{Parametrit}
+ & \multicolumn{2}{l}{\ots{Esimerkki}} \\
+ \midrule
+ \rivi{rgb}{punainen, vihreä, sininen}{1,.7,.3}
+ \rivi{HTML}{punainen, vihreä, sininen}{33aaf3}
+ \rivi{cmyk}{syaani, magenta, keltainen, musta}{.1,1,.5,0}
+ \rivi{hsb}{sävy, kylläisyys, kirkkaus}{.2,1,.6}
+ \rivi{gray}{harmaa}{.55}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Erilaisia värimalleja ja niiden parametreja
+ \paketti{xcolor}\-/ paketissa}
+ \label{tlk/värimalleja}
+}
+
+Omat värit määritellään komennolla \komentom{definecolor}. Se tarvitsee
+kolme argumenttia: värin nimen, värimallin ja värikoodin. Komennon
+argumenttien rakenteesta on seuraavassa esimerkki:
+
+\komentoi{definecolor}
+\begin{koodilohkosis}
+\definecolor{nimi}{välimalli}{parametrit}
+\end{koodilohkosis}
+
+\noindent
+Komennon argumentti \koodi{nimi} on kirjoittajan itse valitsema nimi,
+ja se voi liittyä esimerkiksi värin käyttötarkoitukseen (''nuoli'') tai
+värin yleiseen nimeen (''keltainen''). Argumentti \koodi{väri\-malli}
+tarkoittaa värin ilmaisemisen tapaa. Niitä on useita erilaisia, mutta
+yleisimmät on koottu taulukkoon \ref{tlk/värimalleja}. Eri malleilla on
+eri määrä parametreja, joilla ilmaistaan värin ominaisuuksia. Kunkin
+parametrin arvo on yleensä desimaaliluku 0\==1, mutta \koodi{HTML}\-/
+värimallissa parametrit ilmaistaan yhtenä kolmen kaksinumeroisen
+heksadesimaaliluvun sarjana \textsc{html}\-/ merkintäkielen tavoin.
+Värin parametrit kirjoitetaan komennon argumenttiin
+\koodi{para\-metrit} ja ne erotetaan toisistaan pilkulla. Taulukon
+\ref{tlk/värimalleja} Esimerkki\-/sarakkeessa on parametrien antamisesta
+esimerkki. Muista värimalleista voi lukea \paketti{xcolor}\-/ paketin
+ohjekirjasta.
+
+Kun värit on määritelty, niitä voi käyttää eri komentojen yhteydessä.
+Tekstin väri vaihdetaan toiseksi komennolla \komentom{color}, josta on
+kaksi erilaista versiota. Komento vaihtaa värin pysyvästi nykyisen
+ympäristön (luku \ref{luku/ympäristöt}) tai aaltosulkeilla (luku
+\ref{luku/aaltosulkeet}) rajatun alueen sisällä.
+
+\komentoi{color}
+\begin{koodilohkosis}
+\color{nimi} % väriksi ennalta määritelty ”nimi”
+\color[värimalli]{parametrit} % värimallin ja parametrien avulla
+\end{koodilohkosis}
+
+\noindent
+Toinen vaihtoehto on käyttää komentoa \komentom{textcolor}, jolle
+annetaan edelliseen verrattuna vielä yksi argumentti lisää. Argumenttina
+on teksti, johon värin halutaan vaikuttavan. Vaikutusalueena on siis
+vain kyseinen teksti.
+
+\komentoi{textcolor}
+\begin{koodilohkosis}
+\textcolor{nimi}{teksti}
+\textcolor[värimalli]{parametrit}{teksti}
+\end{koodilohkosis}
+
+\noindent
+Tekstin taustaväri vaihdetaan komennoilla \komentom{colorbox} ja
+\komentom{fcolorbox}. Komennot luovat ikään kuin laatikon, jonka sisällä
+taustaväri on voimassa. Ensin mainittu komento vahtaa vain taustavärin,
+ja jälkimäinen sisältää lisäksi värillisen kehyksen, eli sille
+määritellään kaksi väriä.
+
+\begin{koodilohkosis}
+\colorbox{nimi}{teksti} % taustaväriksi ennalta määritelty ”nimi”
+\colorbox[värimalli]{parametrit}{teksti}
+\fcolorbox{nimi(kehys)}{nimi(tausta)}{teksti}
+\fcolorbox[värimalli]{parametrit(kehys)}{parametrit(tausta)}{teksti}
+\end{koodilohkosis}
+
+\noindent
+Kehystetyn laatikon kehysviivan leveys on mitassa \mittam{fboxrule} ja
+kehyksen etäisyys sisällöstä mitassa \mitta{fboxsep}. Seuraavassa on
+esimerkki useiden edellä mainittujen komentojen käytöstä. Tästä tuskin
+kannattaa ottaa mallia vakavaan typografiseen työhön.
+
+\komentoi{colorbox}
+\komentoi{color}
+\komentoi{definecolor}
+\komentoi{fcolorbox}
+\komentoi{setlength}
+\komentoi{textcolor}
+\mittai{fboxrule}
+\mittai{fboxsep}
+\begin{koodilohkosis}
+\definecolor{pun}{rgb}{1,.2,.2}
+\setlength{\fboxrule}{2bp} \setlength{\fboxsep}{1bp}
+\fcolorbox[gray]{.4}{.2}{\color[gray]{1}Tekstiä}
+\textcolor{pun}{voi korostaa} \colorbox{pun}{väreillä}.
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \definecolor{pun}{rgb}{1,.2,.2}
+ \setlength{\fboxrule}{2bp} \setlength{\fboxsep}{1bp}
+ \fcolorbox[gray]{.4}{.2}{\color[gray]{1}Tekstiä}
+ \textcolor{pun}{voi korostaa} \colorbox{pun}{väreillä}.
+\end{tulossis}
+
+\noindent
+Sivulle voi määrittää taustavärin komennolla \komentom{pagecolor}.
+Taustäväri vaihtuu nykyiselle ja seuraaville sivuille, kunnes väri
+vaihdetaan toiseksi tai poistetaan. Komennolle annetaan samanlaiset
+argumentit kuin muillekin värikomennoille. Komento
+\komentom{nopagecolor} poistaa taustavärin kokonaan eli palauttaa
+taustan oletustilaan.
+
+\komentoi{pagecolor}
+\komentoi{nopagecolor}
+\begin{koodilohkosis}
+\pagecolor{nimi} % sivun taustaväriksi ennalta määritelty ”nimi”
+\pagecolor[värimalli]{parametrit}
+\nopagecolor
+\end{koodilohkosis}
+
+\section{Sivunvaihdot ja sivujen tasaaminen}
+\label{luku/sivunvaihdot}
+
+Kirjoittajan ei normaalisti tarvitse huolehtia sivun vaihtumisesta
+lainkaan, vaan järjestelmä pyrkii latomaan hyvännäköisiä sivuja
+automaattisesti. Välillä tietenkin halutaan aloittaa jokin uusi aihe
+puhtaalta sivulta, ja sitä varten Latexissa on muutama komento.
+Mainittakoon kuitenkin heti aluksi, että otsikoiden yhteyteen saa
+sivunvaihdon kätevimmin keinoilla, jotka neuvotaan otsikoiden yhteydessä
+luvussa \ref{luku/otsikot-ulkoasu}.
+
+Komento \komentom{clearpage} vaihtaa sivua, eli komennon jälkeinen
+dokumentin osa alkaa aina puhtaalta sivulta. Lähes samanlainen komento
+on \komentom{cleardoublepage}, joka kaksipuolisessa dokumentissa
+aloittaa uuden sisällön aina parittomilta sivuilta. Jos seuraavana ei
+satu olemaan pariton sivu, komento tekee väliin tyhjän sivun. Tätä
+ominaisuutta on käytetty tässä oppaassa: pääluvut alkavat aina
+oikeanpuoleiselta eli parittomalta sivulta.
+
+\komento{cleardoublepage}\-/komennon aiheuttamalle tyhjälle sivulle
+saatetaan kuitenkin latoa ylä- ja alatunnisteet, jos sellaiset on
+määritelty (luku \ref{luku/ylä-ala-tunnisteet}). Täysin tyhjän sivun saa
+käyttämällä apuna pakettia \pakettictan{titlesec} ja sen valitsinta
+\koodi{clear\-empty}:
+
+\komentoi{usepackage}
+\pakettii{titlesec}
+\begin{koodilohkosis}
+\usepackage[clearempty]{titlesec}
+\end{koodilohkosis}
+
+\noindent
+Edellä mainittu \paketti{titlesec}\-/ paketti sisältää monenlaisia
+toimintoja otsikoiden muotoiluun, joten sitä käsitellään tarkemmin
+otsikoiden yhteydessä luvussa \ref{luku/otsikot-ulkoasu}.
+
+Komennoilla \komento{clearpage} ja \komento{cleardoublepage} on lisäksi
+sellainen ominaisuus, että ne pakottavat aiemmin määritellyt leijuvat
+osat (luku \ref{luku/leijuosat}) ladottavaksi ennen uutta puhdasta
+sivua.
+
+Hieman toisenlainen sivunvaihtokomento on \komentom{newpage}. Se sallii
+aiempien leijuvien osien latomisen myös sivunvaihdon jälkeen.
+\komento{newpage} eroaa edellisistä sivuvaihtokomennoista myös siten,
+että kaksipalstaisessa tilassa (luku \ref{luku/palstat}) se aloittaa
+vain uuden palstan, ei välttämättä uutta sivua.
+
+Sivunvaihdon todennäköisyyteen tietyssä kohdassa voi vaikuttaa
+komennoilla \komentom{pagebreak} ja \komentom{nopagebreak}. Kummallekin
+voi antaa hakasulkeissa valinnaisen argumentin, joka on luku 0\==4.
+Nolla tarkoittaa pienintä todennäköisyyttä sivunvaihdolle
+(\komento{pagebreak}\komentoargv{0}) tai sen välttämiselle
+(\komento{nopagebreak}\komentoargv{0}). Luku neljä (joka on oletusarvo)
+tarkoittaa, että sivunvaihto pakotetaan tai estetään siinä kohdassa.
+Näiden komentojen tarkoitus on kertoa ladonta\-/ algoritmille vihje,
+kuinka toivottavaa sivunvaihto on tietyssä kohdassa. Jos ei käytä
+suurinta arvoa neljä~(4), algoritmi voi löytää omasta mielestään
+paremmankin sivunvaihtokohdan.
+
+\komentoi{pagebreak}
+\komentoi{nopagebreak}
+\begin{koodilohkosis}
+\pagebreak[3] % Lisätään sivunvaihdon todennäköisyyttä.
+\nopagebreak % Estetään sivunvaihto (oletusarvo 4).
+\end{koodilohkosis}
+
+\noindent
+Jos \komento{pagebreak}\-/ komentoa käyttää tekstikappaleen sisällä,
+sivunvaihto ei välttämättä satu juuri komennon kohdalle. Sivu vaihdetaan
+kohdalle osuvan rivin lopussa.
+
+Oletuksena Latex pyrkii latomaan kaikkien sivujen ylä- ja alareunan
+tasaiseksi. Toisin sanoen se saattaa venyttää tai kutistaa sivulla
+olevia pystysuuntaisia välejä niin, että kaikki sivut näyttävät yhtä
+korkeilta. Tämä tila voidaan asettaa päälle komennolla
+\komentom{flushbottom}, mutta se on jo oletuksena päällä ainakin Latexin
+perusdokumenttiluokissa.
+
+Vaihtoehtoinen tila asetetaan komennolla \komentom{raggedbottom}.
+Komennon seurauksena sivujen alareunoja ei tasata. Toisin sanoen sivun
+pystysuuntaisiin väleihin ei kosketa, joten eri sivujen alareunat voivat
+sattua eri korkeudelle.
+
+Dokumentin viimeistelyvaiheessa sivujen hienosäätöön sopinee komento
+\komentom{enlargethispage}, jolla voi muuttaa käsillä olevan sivun
+korkeutta, käytännössä \mitta{textheight}\-/mittaa. Komennolle annetaan
+argumentiksi positiivinen tai negatiivinen mitta. Seuraavassa on
+esimerkkejä:
+
+\komentoi{enlargethispage}
+\mittai{baselineskip}
+\begin{koodilohkosis}
+\enlargethispage{12bp} % 12 pistettä korkemmaksi
+\enlargethispage{-4bp} % 4 pistettä matalammaksi
+\enlargethispage{\baselineskip} % yksi tekstirivi lisää
+\end{koodilohkosis}
+
+\noindent
+Komennon tähtiversio \komentom{enlargethispage*} pyrkii lisäksi
+tiivistämään sivun sisältöä pystysuunnassa niin paljon kuin mahdollista.
+Sen tyypillisin käyttötarkoitus lienee se, että sivulle pyritään
+mahduttamaan yksi ylimääräinen rivi. Tämäntyyppinen sivujen hienosäätö
+kannattaa tehdä vasta viimeisenä eli siinä vaiheessa, kun kaikki sisältö
+on valmiina ja muu typografinen asettelu tehty.
+
+\section{Jäsennys}
+\label{luku/jäsennys}
+
+Tekstin jäsentäminen tarkoittaa sisällön järjestystä ja sen jakamista
+sopiviin kokonaisuuksiin. Esimerkiksi laaja teos voi koostua osista,
+osien sisäisistä pääluvuista ja niiden alaluvuista. Eri luvut ilmaistaan
+eritasoisilla otsikoilla. Varsinaisten sisältölukujen jälkeen teoksessa
+voi olla erilaisia liite- tai luettelosivuja, esimerkiksi lähdeluettelo
+ja asiahakemisto. Toisaalta lyhyempi artikkeli sisältää ehkä vain yhden-
+tai kahdentasoisia otsikoita -- muuta ei tarvita. Tässä alaluvussa
+käsitellään juuri tämäntyyppisiä asioita eli tekstikappaletta suurempien
+kokonaisuuksien jäsentämistä.
+
+\subsection{Perustiedot, kansisivu ja tiivistelmä}
+\label{luku/dokumentin-perustiedot}
+
+Latexissa on yksinkertainen toiminto dokumentin perustietojen latomiseen
+dokumentin alkuun, mahdollisesti erilliselle kansisivulle. Perustietoja
+ovat teoksen nimi, tekijä ja päiväys. Lähdedokumentin alussa perustiedot
+ilmaistaan seuraavilla komennoilla:
+
+\komentoi{title}
+\komentoi{author}
+\komentoi{date}
+\komentoi{and}
+\komentoi{today}
+\begin{koodilohkosis}
+\title{Tieteellistä tiedettä} % teoksen nimi
+\author{Timo Tiedemies \and Tuija Tutkija} % tekijöiden nimet
+\date{\today} % päiväys
+\end{koodilohkosis}
+
+\noindent
+Edellisen esimerkin komentojen argumentissa voi käyttää komentoa
+\komento{thanks}, joka on tarkoitettu kiitosten osoittamiseen.
+Komennolle annetaan argumentiksi lyhyehkö teksti eli kiitosviesti, joka
+tulisi näkymään sivulla alaviitteessä.
+
+Komennot eivät itse vielä lado mitään tekstiä dokumenttiin. Ne vain
+tallentavat perustiedot muistiin mahdollista myöhempää käyttöä varten.
+Komennolla \komentom{maketitle} voi latoa kaikki edellä mainitut tiedot.
+Ne voivat näkyä ensimmäisen sisältösivun alussa tai erillisellä
+kansisivulla; se riippuu dokumenttiluokan asetuksista ja valitsimista
+\koodi{titlepage} ja \koodi{notitlepage}. Se, kumpi asetus on oletuksena
+päällä, vaihtelee eri dokumenttiluokissa. Dokumenttiluokkia ja niiden
+asetuksia käsitellään tarkemmin luvussa \ref{luku/dokumenttiluokat}.
+Yksittäiset perustiedot saa ladottua seuraavilla komennoilla:
+\komento{thetitle}, \komento{theauthor} ja \komento{thedate}.
+
+Perustietokomentoihin \komento{title}, \komento{author} ja
+\komento{date} ei ole tarkoitus sisällyttää kovin monimutkaisia
+muotoilukomentoja. Jos haluaa vaikuttaa perustietojen ulkoasuun,
+kannattaa käyttää siihen tarkoitettua pakettia \pakettictan{titling}.
+Toisaalta mikään ei estä muotoilemasta oman dokumentin perustietoja
+ilman Latexin valmiita keinoja.
+
+Hyödyllisiä ympäristöjä dokumentin alussa käytettäväksi voivat olla
+\ymparistom{titlepage} ja \ymparistom{abstract}. Ensin mainittu luo
+tyhjän sivun kansisivun toteuttamiseen. Se myös aloittaa sivunumeroinnin
+alusta eli asettaa uudelleen \laskuri{page}\-/ laskurin arvon.
+\ymparisto{abstract}\-/ ympäristö on tarkoitettu tieteellisen artikkelin
+tiivistelmän kirjoittamiseen. Molempien edellä mainittujen ympäristöjen
+käyttö on vapaaehtoista. Kansisivun ja artikkelin tiivistelmän voi aivan
+hyvin toteuttaa ilman näitäkin.
+
+Teoksen kansisivu -- jos sellainen on -- kannattanee lisätä pdf\-/
+tiedoston sisäiseen sisällysluetteloon, jotta lukija voi helposti palata
+alkuun myös luettelon kautta. Normaaliin ladottavaan sisällysluetteloon
+tuskin koskaan merkitään kansisivua. Pdf:n sisällysluetteloon saa oman
+merkinnän esimerkiksi seuraavalla komennolla:
+
+\komentoi{pdfbookmark}
+\begin{koodilohkosis}
+\pdfbookmark[0]{Kansi}{sivu/kansi}
+\end{koodilohkosis}
+
+\noindent
+Edellä mainittu komento \komento{pdfbookmark} täytyy sijoittaa Latex\-/
+lähdedokumentissa nimenomaan kansisivulle, koska
+sisällysluettelomerkintä on samalla linkki kyseiseen kohtaan
+dokumentissa. Komento kuuluu \paketti{hyperref}\-/ pakettiin, ja sitä
+käsitellään tarkemmin pdf:n asetusten yhteydessä luvussa
+\ref{luku/pdf-asetukset}.
+
+\subsection{Otsikointi}
+\label{luku/otsikot}
+
+Otsikoiden tehtävänä on tietenkin jakaa sisältö mielekkäisiin osiin ja
+ilmaista tekstikokonaisuuksien aihe. Ne auttavat lukijaa ennakoimaan,
+mitä on tulossa. Otsikot havainnollistavat myös asioiden
+hierarkkisuutta: ylemmäntasoiset otsikot nimeävät yläkäsitteitä tai
+laajempia kokonaisuuksia, alemmantasoiset otsikot alakäsitteitä ja
+pienempiä kokonaisuuksia.
+
+Jos kirjoittaa Latexilla vähänkään otsikoita, kannattaa ladata mukaan
+paketti \paketti{hyperref}. Se huolehtii, että Latexiin merkityt otsikot
+tuodaan mukaan pdf\-/ tiedoston sisäiseen sisällysluetteloon ja että
+dokumenttiin mahdollisesti ladottavassa sisällysluettelossa otsikot ovat
+automaattisesti myös linkkejä, joilla voi hypätä kyseiseen lukuun.
+Pdf\-/ tiedoston selailu on näin mukavampaa. \paketti{hyperref}\-/
+pakettia ja pdf\-/ tiedoston ominaisuuksia käsitellään tarkemmin luvussa
+\ref{luku/pdf-asetukset}.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[4]{\komento{#1} & #2 & #3 & #4 \\}
+ \begin{tabular}{lccl}
+ \toprule
+ \multirow{2}{*}{\ots{Komento}}
+ & \ots{Taso}
+ & \ots{Taso}
+ & \multirow{2}{*}{\ots{Merkitys}} \\
+ & (\luokka{article}) & (\luokka{book}, \luokka{report}) \\
+ \midrule
+ \rivi{part}{0}{-1}{teoksen osa}
+ \rivi{chapter}{}{0}{pääluku}
+ \rivi{section}{1}{1}{otsikko 1, luku}
+ \rivi{subsection}{2}{2}{otsikko 2, alaluku}
+ \rivi{subsubsection}{3}{3}{otsikko 3, alaluvun alaluku}
+ \rivi{paragraph}{4}{4}{kappaleotsikko 1}
+ \rivi{subparagraph}{5}{5}{kappaleotsikko 2}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Otsikointikomennot ja niitä vastaavat tasot Latexin
+ otsikkohierarkiassa. Dokumenttiluokassa \luokka{article} ei ole
+ päälukuja (\komento{chapter})}
+ \label{tlk/otsikkotasot}
+}
+
+Latexissa eri otsikoiden tasoille on omat komentonsa, jotka on koottu
+taulukkoon \ref{tlk/otsikkotasot} -- suurimmasta otsikosta pienimpään.
+Ylin otsikkotaso on teoksen osa, ja sitä merkitään komennolla
+\komentom{part}. Tämän komennon käyttö on vapaaehtoista, mutta sillä on
+voi osoittaa laajan teoksen osia. Osat numeroidaan oletuksena
+roomalaisilla järjestysluvuilla: ''\partname~I'', ''\partname~II'',
+''\partname~III'' jne. Ne eivät vaikuta alemmantasoisten otsikoiden
+numerointiin, eli osan vaihtuminen ei oletusasetuksilla nollaa
+alemmantasoisten lukujen laskuria.
+
+Otsikkotaso \komentom{chapter} tarkoittaa kirjan päälukua, joka alkaa
+oletuksena puhtaalta sivulta. Otsikkoa ennen siis suoritetaan
+automaattisesti sivunvaihtokomento \komento{clearpage} tai
+\komento{cleardoublepage} (luku \ref{luku/sivunvaihdot}).
+\komento{chapter}\-/ tasoiset otsikot saavat oletuksena numeroinnin
+''\chaptername~1'', ''\chaptername~2'', ''\chaptername~3'' jne.
+Dokumenttiluokassa \luokka{article} ei tätä otsikkotasoa ole lainkaan.
+
+Seuraavat otsikkotasot \komentom{section}, \komentom{subsection} ja
+\komentom{subsubsection} ovat tavallisimpia tekstin väliotsikoita. Nekin
+saavat oletuksena numeroinnin, jossa pisteellä erotetaan mahdolliset
+alaluvut: 1.1, 1.2, 1.2.1, 1.2.2 yms.
+
+Otsikoinnissa on tärkeää säilyttää suora hierarkkinen suhde
+otsikkotasojen välillä: alemmantasoista otsikkoa ei saa käyttää ennen
+kuin on ensin ollut yhtä astetta ylempi otsikkotaso. Täytyy siis olla
+ensin \komento{section} ennen kuin voi olla \komento{subsection}. Muuten
+otsikoiden numerointi ei toimi oikein. Poikkeus on \komento{part}, jota
+ei välttämättä tarvitse käyttää.
+
+Otsikkotasot \komentom{paragraph} ja \komentom{subparagraph} eivät ole
+ihan perinteisiä otsikoita, vaan ne ladotaan tekstikappaleen alkuun.
+Nekin kyllä erottuvat leipätekstistä ja voivat toimia otsikon
+kaltaisessa tehtävässä. Oletuksena kappaleotsikoita ei numeroida eivätkä
+ne tule mukaan sisällysluetteloon. Oletusasetuksia on kuitenkin
+mahdollista muuttaa, ja tarvittaessa \komento{paragraph} ja
+\komento{subparagraph} voivat toimia normaaleina otsikoina tason
+\komento{subsubsection} jälkeen. Kovin syvää otsikkorakennetta ei
+yleensä suositeta, koska lukijan voi olla vaikeaa hahmottaa monitasoisia
+kokonaisuuksia.
+
+Otsikkokomennoille annetaan tyypillisesti vain yksi argumentti, joka on
+kyseisen otsikon teksti. Otsikkoon ei ole tarkoitus kirjoittaa kovin
+monimutkaisia fontti- eikä muotoilukomentoja, vaan mieluiten ainoastaan
+otsikon teksti. Typografinen muotoilu tehdään muilla keinoilla, joita
+esitellään alaluvussa \ref{luku/otsikot-ulkoasu}. Yksinkertaiset
+korostuskomennot ja tavutusvihjeet (\komento{-}) kuitenkin toimivat
+yleensä. Hauraiden komentojen (luku \ref{luku/komennot-hauraat}) eteen
+täytyy kirjoitaa komento \komento{protect}.
+
+\komentoi{section}
+\begin{koodilohkosis}
+\section{Tämä teksti on otsikko}
+\end{koodilohkosis}
+
+\noindent
+Otsikko tulee automaattisesti mukaan teoksen sisällysluetteloon, jos
+sellainen on olemassa (luku \ref{luku/sisällysluettelo}). Otsikko näkyy
+myös pdf\-/ tiedoston sisällysluettelossa, jos vain
+\paketti{hyperref}\-/ paketti on käytössä (luku
+\ref{luku/pdf-asetukset}). Lisäksi otsikon tekstiä voi käyttää
+ristiviittauksissa (luku~\ref{luku/ristiviitteet}).
+
+Otsikkokomennoille voi antaa yhden valinnaisen argumentin, jolla
+ilmaistaan otsikosta lyhempi tai yksinkertaisempi versio. Tällöin
+sisällysluettelossa ja ristiviitteissä näytetään lyhempi otsikko ja
+tekstiin ladotaan varsinainen otsikko. Tätä ominaisuutta on syytä
+hyödyntää myös silloin, kun varsinainen otsikko sisältää otsikkotekstin
+lisäksi muotoilukomentoja. Silloin valinnaiseen argumenttiin
+kirjoitetaan vain puhdasta tekstiä sisältävä versio otsikosta.
+
+\komentoi{section}
+\begin{koodilohkosis}
+\section[Lyhyt otsikko]{Tämä tässä on pitkä otsikko}
+\end{koodilohkosis}
+
+\noindent
+Kaikille otsikkokomennoille on olemassa myös niin sanottu tähtiversio
+eli komentovaihtoehto, jonka nimen lopussa on tähti: \komento{part*},
+\komento{chapter*}, \komento{section*}, \komento{subsection*},
+\komento{subsubsection*}, \komento{paragraph*}, \komento{subparagraph*}.
+Nämä vaihtoehdot latovat otsikon, jolla ei ole numerointia ja jota ei
+lisätä sisällysluetteloon.
+
+Pelkän otsikon numeroinnin poistamiseen ei ehkä kannata käyttää näitä
+tähtiversioita, koska yleensä otsikko kuitenkin halutaan
+sisällysluetteloon. Otsikoiden numeroinnin saa pois muilla keinoilla,
+jotka neuvotaan luvussa \ref{luku/otsikot-numerointi}.
+
+Jos kuitenkin jostain syystä haluaa käyttää tähdellistä otsikkokomentoa
+ja haluaa otsikon myös sisällysluetteloon, täytyy se tehdä seuraavalla
+tavalla:
+
+\komentoi{section*}
+\komentoi{addcontentsline}
+\komentoi{phantomsection}
+\begin{koodilohkosis}
+\section*{Tässäpä numeroimaton otsikko}
+\phantomsection
+\addcontentsline{toc}{section}{Tässäpä numeroimaton otsikko}
+\end{koodilohkosis}
+
+\noindent
+Edellä olevan esimerkin komento \komentom{addcontentsline} lisää
+merkinnän sisällysluetteloon. Komennon ensimmäinen argumentti on
+\koodi{toc} (\englanti{table of contents}), joka on sisällysluetteloiden
+tekemisessä tarvittavan väliaikaistiedoston pääte. Esimerkissä lisättävä
+sisällysluettelon merkintä on tasoltaan \koodi{section} eli vastaa muita
+\komento{section}\-/ komennolla syntyviä sisällysluettelon kohtia.
+Komento \komentom{phantomsection} kuuluu \paketti{hyperref}\-/
+pakettiin, ja se lisää pdf\-/ tiedostoon näkymättömän ankkurin tähän
+kohtaan dokumentissa. Sitä tarvitaan, jotta sisällysluettelon merkintä
+viittaisi oikealle sivulle ja toimisi myös linkkinä, joka tuo juuri
+tähän kohtaan.
+
+\subsection{Otsikoiden numerointi}
+\label{luku/otsikot-numerointi}
+
+Oletusasetuksilla Latex numeroi otsikot (\komento{chapter},
+\komento{section} jne.) automaattisesti, mutta kirjoittaja voi vaikuttaa
+numerointiin monella tavalla, kuten siihen, mihin otsikkotasoon saakka
+numerointi yltää ja millä tyylillä otsikoiden numerot ylipäätään
+ladotaan.
+
+Laskuri \laskurim{secnumdepth} on tarkoitettu kirjoittajan
+asetettavaksi, ja sillä määritetään, mihin otsikkotasoon saakka otsikot
+numeroidaan. Tasonumerot ovat taulukossa \ref{tlk/otsikkotasot}.
+Seuraava esimerkki määrittelee, että vain tasoon~1 (\komento{section})
+saakka otsikot numeroidaan. Alemmantasoiset otsikot
+(\komento{subsection} ym.) eivät saa numeroa.
+
+\komentoi{setcounter}
+\laskurii{secnumdepth}
+\begin{koodilohkosis}
+\setcounter{secnumdepth}{1}
+\end{koodilohkosis}
+
+\noindent
+Asetusta voi muuttaa kesken dokumentin. Muuttaminen voi olla mielekästä
+esimerkiksi laajan teoksen lopussa, jossa on mahdollisesti
+lähdeluettelo, asiahakemistoja tai liitteitä, joille ei ehkä haluta
+samanlaista otsikkonumerointia kuin varsinaisille sisältöluvuille.
+
+Latexin otsikoiden numerointi noudattaa yleistä tietokirjallisuuden
+käytäntöä, eli numeroinnissa käytetään arabialaisia numeroita ja eri
+tasoja ilmaisevat numerot erotetaan toisistaan pisteellä: 1.1, 1.2,
+1.2.1, 1.2.2 jne. Sisäisesti Latex käyttää laskureita, joilla on sama
+nimi kuin vastaavalla otsikointikomennolla: \laskuri{part},
+\laskuri{chapter}, \laskuri{section}, \laskuri{subsection},
+\laskuri{subsubsection}, \laskuri{paragraph}, \laskuri{subparagraph}.
+
+Laskureiden toimintaan voi perehtyä tarkemmin luvun \ref{luku/laskurit}
+avulla, mutta kerrataan tässä yhteydessä yksi asia. Laskurin arvon voi
+latoa dokumenttiin käyttämällä komentoa, joka alkaa kirjaimilla
+\komentox{the} ja jatkuu laskurin nimellä. Niin otsikkokomennot juuri
+tekevät: esimerkiksi \komento{section}\-/ otsikon kohdalla suoritetaan
+automaattisesti \komento{thesection}, joka tuottaa otsikon numeron.
+Vastaavasti \komento{subsection}\-/ komento latoo numeron käyttämällä
+komentoa \komento{thesubsection} jne.
+
+Kirjoittaja voi halutessaan määritellä nämä laskurin latomiskomennot
+uudelleen. Jos esimerkiksi teoksen osat (\komento{part}) halutaan
+ilmaista arabialaisin numeroin eikä roomalaisin (kuten on oletus),
+tehdään se seuraavan esimerkin mukaisesti. Esimerkissä käytettävä
+komento \komento{arabic} latoo laskurin arvon arabialaisilla numeroilla.
+
+\komentoi{renewcommand}
+\komentoi{thepart}
+\laskurii{part}
+\komentoi{arabic}
+\begin{koodilohkosis}
+\renewcommand{\thepart}{\arabic{part}}
+\end{koodilohkosis}
+
+\noindent
+Joskus ehkä halutaan, että otsikoissa eri tasojen numeroita ei eroteta
+toisistaan pisteellä (2.1) vaan yhdysmerkillä tai ajatusviivalla
+(2\==1). Tällainen asetus saadaan määrittelemällä alemmantasoisten
+laskurien latomiskomennot uudelleen, esimerkiksi seuraavasti:%
+\footnote{Parempi olisi ehkä käyttää sitovaa ajatusviivaa, jonka saa
+ \paketti{extdash}\-/ paketin \komento{==}\-/ komennolla. Katso
+ lisätietoa luvusta \ref{luku/tavutus-sallivat-sitovat}.}
+
+\komentoi{renewcommand}
+\komentoi{thesection}
+\komentoi{thesubsection}
+\komentoi{thesubsubsection}
+\laskurii{subsection}
+\laskurii{subsubsection}
+\komentoi{arabic}
+\begin{koodilohkosis}
+\renewcommand{\thesubsection}{\thesection--\arabic{subsection}}
+\renewcommand{\thesubsubsection}{%
+ \thesubsection--\arabic{subsubsection}}
+\end{koodilohkosis}
+
+\noindent
+Otsikkonumeroinnin poistamista ei pidä toteuttaa siten, että määrittelee
+edellä mainitut \komentox{the}\-/ alkuiset komennot tyhjäksi. Numerointi
+poistetaan laskurin \laskuri{secnumdepth} avulla määrittämällä sen arvo
+tarpeeksi pieneksi. Sekin on syytä muistaa, että nämä \komentox{the}\-/
+alkuiset komennot on tarkoitettu vain laskurien arvon latomiseen.
+Komennon määritelmään ei pidä kirjoittaa typografiseen muotoiluun
+liittyviä komentoja. Otsikoiden ulkoasuun vaikutetaan muilla keinoilla.
+
+\subsection{Otsikoiden ulkoasu}
+\label{luku/otsikot-ulkoasu}
+
+Otsikoiden typografiaan eli esimerkiksi kirjainperheen ja \=/leikkauksen
+valintaan ja välistyksiin on kätevintä käyttää \pakettictan{titlesec}\-/
+pakettia. Perus Latexissakin on kyllä otsikoiden muotoiluun tarkoitettu
+komento \komentox{@startsection}, mutta sen käyttö on hankalampaa eikä
+se toimi kaikilla otsikkotasoilla. Perus Latexin keinoihin voi tutustua
+esimerkiksi epävirallisen Latex\-/ hakuteoksen \textcite{unoffref}
+avulla. Tässä oppaassa sen sijaan keskitytään \paketti{titlesec}\-/
+pakettiin.
+
+Otsikoiden perusmuotoilu on helpointa toteuttaa
+\komentom{titleformat*}\-/ komennon avulla. Sille annetaan argumentiksi
+otsikkokomennon nimi ja sitä vastaavat muotoilukomennot. Seuraava
+esimerkki vaihtaa otsikoihin groteskin kirjainperheen
+(\komento{sffamily}) ja hieman toisistaan poikkeavan kirjainleikkauksen.
+
+\komentoi{titleformat*}
+\komentoi{section}
+\komentoi{subsection}
+\komentoi{subsubsection}
+\komentoi{sffamily}
+\komentoi{large}
+\komentoi{Large}
+\komentoi{normalsize}
+\komentoi{bfseries}
+\komentoi{itshape}
+\begin{koodilohkosis}
+\titleformat*{\section} {\sffamily\bfseries\Large}
+\titleformat*{\subsection} {\sffamily\bfseries\itshape\large}
+\titleformat*{\subsubsection}{\sffamily\bfseries\normalsize}
+\end{koodilohkosis}
+
+\noindent
+Monipuolisemmat muotoiluasetukset saa toteutettua komennon tähdettömällä
+versiolla \komentom{titleformat}. Tämän komentoversion monista
+argumenteista ja ominaisuuksista kannattaa lukea \paketti{titlesec}\-/
+paketin ohjekirjasta, mutta esimerkistä \ref{esim/titleformat}
+selvinnevät perustoiminnot.
+
+\begin{esimerkki*}
+ \komentoi{titleformat}
+ \komentoi{section}
+ \komentoi{sffamily}
+ \komentoi{bfseries}
+ \komentoi{Large}
+ \komentoi{raggedright}
+ \komentoi{thesection}
+
+\begin{koodilohko}
+\titleformat{\section} % otsikkotaso: \section
+[hang] % muoto: riippuva sisennys
+{\sffamily\bfseries\Large % ulkoasukomentoja
+ \raggedright}
+{\thesection} % numerointi
+{.8em} % numeroinnin ja otsikkotekstin väli (mitta)
+{} % koodia ennen otsikkotekstiä
+[] % koodia otsikon jälkeen
+\end{koodilohko}
+ \caption{Otsikoiden ulkoasuun voi vaikuttaa monipuolisesti
+ \komento{titleformat}\-/ komennolla, joka kuuluu \paketti{titlesec}\-/
+ pakettiin}
+ \label{esim/titleformat}
+\end{esimerkki*}
+
+Luvun numeroinnin (1.1, 1.2 jne.) tyyliin voi vaikuttaa komennolla
+\komentom{titlelabel}. Komento suoritetaan yleensä vain kerran, ja se
+vaikuttaa kaikentasoisiin otsikoihin. Tätä komentoa ei tarvita, jos
+käyttää edellä mainittua ''tähdetöntä'' \komento{titleformat}\-/
+komentoa, koska se sisältää jo toiminnot myös lukujen numeroinnin
+asetuksiin.
+
+\komentoi{titlelabel}
+\komentoi{hspace}
+\begin{koodilohkosis}
+\titlelabel{\thetitle\hspace{1em}}
+\end{koodilohkosis}
+
+\noindent
+Edellä olevan komennon argumentissa käytetty komento \komentox{thetitle}
+on tarkoitettu vain tämän komennon ja \paketti{titlesec}\-/ paketin
+sisäiseen käyttöön. Se latoo kyseisen luvun numeron, olipa otsikkotaso
+mikä hyvänsä. Sen perään esimerkissä asetetaan 1\,em:n suuruinen väli
+\komento{hspace}\-/ komennolla.
+
+Otsikoiden yhteydessä ladottavaan sisennykseen ja pystysuuntaiseen
+väliin vaikutetaan komennolla \komentom{titlespacing*}. Sille annetaan
+argumentiksi otsikkokomennon nimi ja halutut mitat järjestyksessä vasen
+sisennys, yläpuolinen väli ja alapuolinen väli.
+
+\komentoi{titlespacing*}
+\komentoi{section}
+\begin{koodilohkosis}
+\titlespacing*{\section}{0mm}{3ex plus 2bp minus 1bp}{2ex plus 1bp}
+\end{koodilohkosis}
+
+\noindent
+Pystysuuntaiset mitat on yleensä hyvä asettaa venyviksi (luku
+\ref{luku/venyvät-mitat}), jotta Tex saa pelivaraa sivujen latomiseen.
+Otsikon yläpuolella pitäisi olla isompi väli kuin alapuolella, koska
+otsikko kuuluu kiinteämmin sitä seuraavaan tekstiin. Pystysuuntaisten
+välien määrittämisessä voi käyttää *\=/lyhennettä, joka tarkoittaa
+oletuksena ex\-/mittayksikköä ja sallii hieman venymistä.
+
+\komentoi{titlespacing*}
+\komentoi{section}
+\begin{koodilohkosis}
+\titlespacing*{\section}{0mm}{*3}{*2}
+\end{koodilohkosis}
+
+\noindent
+Tähdellinen \komento{titlespacing*}\-/ komento poistaa otsikon jälkeen
+tulevasta tekstikappaleesta ensimmäisen rivin sisennyksen (luku
+\ref{luku/ensimmäisen-rivin-sisennys}). Tähdetön komentoversio
+\komentom{titlespacing} sen sijaan säilyttää kappaleen sisennyksen. Sitä
+ei liene tarvetta käyttää koskaan, sillä otsikoiden jälkeen tulevaa
+tekstikappaletta ei kuulu sisentää.
+
+Teoksen osien (\komento{part}) vaihtuessa sivulle ladotaan oletuksena
+teksti kuten ''\partname~I'', ''\partname~II'' jne. Mainittu sana
+''\partname'' tulee suomen kieliasetuksista ja komennosta
+\komentom{partname}. Kaikkien kielten asetukset nimittäin määrittelevät
+komennon \komento{partname} siten, että se sisältää ja latoo kyseiseen
+kieleen sopivan ilmauksen. Vastaavasti päälukujen (\komento{chapter})
+yhteydessä ladotaan suomen kieliasetuksilla ilmaus ''\chaptername~1'',
+''\chaptername~2'' jne. Sana ''\chaptername'' tulee komennosta
+\komentom{chaptername}.
+
+Jos omassa dokumentissa haluaa kutsua teoksen osia tai päälukuja
+joksikin muuksi, voi määritellä edellä mainitut komennot uudelleen.
+Seuraavassa esimerkissä voisi olla jokin romaani, jossa teoksen osat
+ovat ''kausia'' ja pääluvut ovat ''päiviä''.
+
+\komentoi{addto}
+\komentoi{captionsfinnish}
+\komentoi{renewcommand}
+\komentoi{partname}
+\komentoi{chaptername}
+\begin{koodilohkosis}
+\addto{\captionsfinnish}{
+ \renewcommand{\partname}{Kausi}
+ \renewcommand{\chaptername}{Päivä}
+}
+\end{koodilohkosis}
+
+\noindent
+Tässä \komento{renewcommand}\-/ komennot sijoitettiin \komento{addto}\-/
+komennon sisään, sen toiseen argumenttiin. Komento \komento{addto}
+täytyy suorittaa lähdedokumentin esittelyosassa, ja tässä se lisää uusia
+komentoja suomen kielen asetuksiin (\komento{captionsfinnish}), niin
+että ne tulevat voimaan samalla kun suomen kieliasetuksetkin.
+\komento{addto} kuuluu \paketti{polyglossia}\-/\ ja \paketti{babel}\-/
+paketteihin, joita käsitellään tarkemmin kieliasetusten yhteydessä
+luvussa \ref{luku/kieliasetukset}.
+
+Otsikoiden yhteyteen saa automaattisen sivunvaihdon määrittämällä
+komennon, jonka nimen alussa on otsikkokomennon nimi ja lopussa sana
+\koodi{break}. Tavallisin lienee \komentom{sectionbreak}. Komennon
+määritelmään kirjoitetaan jokin sivuvaihtokomento kuten
+\komento{clearpage}. Sivunvaihtokomentoja käsitellään tarkemmin luvussa
+\ref{luku/sivunvaihdot}.
+
+\komentoi{newcommand}
+\komentoi{sectionbreak}
+\komentoi{clearpage}
+\begin{koodilohkosis}
+\newcommand{\sectionbreak}{\clearpage}
+\end{koodilohkosis}
+
+\subsection{Esittely, pääluvut, liitteet ja luettelot}
+\label{luku/frontmainbackmatter}
+
+Dokumenttiluokassa \luokka{book} (luku \ref{luku/perusdokumenttiluokat})
+on käytettävissä kolme lisäkomentoa dokumentin erilaisten osien
+ilmaisemiseen: \komento{frontmatter}, \komento{mainmatter} ja
+\komento{backmatter}. Niillä jaetaan laaja teos esittelysivuihin,
+varsinaisiin sisältölukuihin ja loppuosaan kuten liitesivuihin ja
+erilaisiin luetteloihin. Lisäksi muissakin dokumenttiluokissa on komento
+\komento{appendix}, jolla voi aloittaa liitesivuja sisältävän osan
+dokumentissa. Näiden komentojen käyttö on vapaaehtoista. Luvussa
+\ref{luku/tyypillinen-tietokirja} käsitellään tyypillisen suomalaisen
+tietokirjan rakennetta ja teknistä toteuttamista.
+
+Dokumentin alkuun voi kirjoittaa komennon \komentom{frontmatter}, joka
+asettaa sivunumeroiden tyyliksi roomalaiset numerot (i, ii, iii jne.) ja
+poistaa pääluvuilta (\komento{chapter}) numeroinnin. Tässä osassa ovat
+teoksen kansi ja perustiedot, sisällysluettelo, tietokirjan tai
+tutkimuksen tiivistelmä ja mahdollisesti teoksen esipuhe tai muu
+vastaava esittelyteksti, joka ei ole vielä varsinaista sisältöä.
+
+Jos dokumentissa käytetään \komento{frontmatter}\-/ komentoa, täytynee
+varsinaisten sisältölukujen alkuun kirjoittaa komento
+\komentom{mainmatter}, joka nollaa sivunumerolaskurin, asettaa
+numeroinnin tyyliksi arabialaiset numerot (1, 2, 3 jne.) ja kytkee
+päälle lukujen numeroinnin. Sen jälkeen ensimmäinen \komento{chapter}\-/
+komennolla tehty luku on siis ''\chaptername~1''.
+
+Sisältösivujen lopussa voi olla komento \komentom{appendix}. Se
+ensinnäkin nollaa \luokka{book}- ja \luokka{report}\-/ luokissa
+päälukujen laskurin \laskuri{chapter}. Sen sijaan \luokka{article}\-/
+luokassa se nollaa \laskuri{section}\-/ laskurin. Sen lisäksi
+\komento{appendix}\-/ komento muuttaa lukujen numerointityyliksi
+kirjaimet (A, B, C jne.) ja päälukujen nimeksi ''\appendixname'', joka
+tulee komennosta \komento{appendixname}. Näin teoksen lopussa
+\komento{appendix}\-/ komennon jälkeen pääluvut tulevat nimetyksi
+uudella tavalla: ''\appendixname~A'', ''\appendixname~B'' jne.
+
+Sisältösivujen ja mahdollisten liitteiden jälkeen voi olla hyödyllistä
+käyttää komentoa \komentom{backmatter}, joka lopettaa päälukujen
+numeroinnin kokonaan. Tähän osaan voisi sijoittaa ainakin asiahakemistot
+sekä kirjallisuus\-/\ tai lähdeluettelon.
+
+\subsection{Tyypillinen tietokirjan rakenne}
+\label{luku/tyypillinen-tietokirja}
+
+Latexin komennot \komento{frontmatter} ja \komento{mainmatter} (luku
+\ref{luku/frontmainbackmatter}) eivät ihan vastaa suomalaista
+tietokirjojen käytäntöä. Suomessa teoksen alun sivunumeroita ei ole
+tapana ilmaista roomalaisilla numeroilla eikä sivunumerointia nollata
+sisältölukujen alkaessa. Esimerkkiin \ref{esim/tietokirjojen-rakenne} on
+koottu varsin tyypillinen suomalainen tietokirjojen rakenne. Esimerkissä
+ei käytetä lainkaan komentoja \komento{frontmatter},
+\komento{mainmatter} eikä \komento{backmatter}, vaan lukujen
+numerointiin vaikutetaan suoraan asettamalla laskuriin
+\laskuri{secnumdepth} sopiva arvo. Tätä laskuria käsitellään otsikoiden
+yhteydessä luvussa \ref{luku/otsikot-numerointi}.
+
+\begin{esimerkki*}
+ \komentoi{documentclass}
+ \luokkai{book}
+ \komentoi{pagestyle}
+ \komentoi{cleardoublepage}
+ \komentoi{setcounter}
+ \laskurii{tocdepth}
+ \laskurii{secnumdepth}
+ \komentoi{tableofcontents}
+ \komentoi{chapter}
+ \komentoi{appendix}
+ \komentoi{printbibliography}
+ \komentoi{printindex}
+ \ymparistoi{document}
+
+\begin{koodilohko}
+\documentclass{book}
+
+\begin{document}
+
+\pagestyle{empty} % sivunumerot pois näkyvistä
+% nimiösivu yms.
+
+\cleardoublepage
+\setcounter{tocdepth}{2} % sisällysluettelon syvyys
+\pagestyle{plain} % sivunumerot näkyviin
+\tableofcontents % sisällysluettelo
+
+\setcounter{secnumdepth}{-1} % lukujen numerointi pois
+
+\chapter{Esipuhe}
+% esipuheen teksti
+
+\setcounter{secnumdepth}{2} % aloitetaan lukujen numerointi
+
+\chapter{Ensimmäinen pääluku}
+% ...
+\chapter{Toinen pääluku}
+% ...
+
+% mahdollisesti liitteet
+\appendix
+\chapter{Tärkeä liite}
+% ...
+\chapter{Tosi tärkeä liite}
+% ...
+
+% Kirjallisuusluettelot, asiahakemistot yms.
+\setcounter{secnumdepth}{-1} % lukujen numerointi pois
+
+\chapter{Kirjallisuutta}
+\printbibliography
+
+\chapter{Asiahakemisto}
+\printindex
+
+\end{document}
+\end{koodilohko}
+ \caption{Tyypillinen suomalainen tietokirjojen rakenne sekä sivujen ja
+ lukujen numerointikäytännöt}
+ \label{esim/tietokirjojen-rakenne}
+\end{esimerkki*}
+
+Suomalaisissa kirjoissa sivunumeroinnin laskuri alkaa ensimmäiseltä
+sivulta, johon on painettu jotakin, yleensä pelkkä teoksen nimi tai
+kirjailijan nimi. Sivu~1 ei ole vielä kirjan kansi, koska kirjapainossa
+kannet lisätään ikään kuin tekijöiden työn ympärille. Aikakauslehdissä
+kansi on kuitenkin sivu~1.
+
+Sivunumerot tulevat näkyviin hieman vaihtelevasti: joskus sivunumerot
+näytetään sisällysluettelon alusta saakka; joskus ne näytetään vasta
+sisällysluettelon jälkeen esipuheessa; joskus esipuhe on ennen
+sisällysluetteloa ja sivunumerot näkyvät esipuheen alusta saakka.
+Esimerkissä \ref{esim/tietokirjojen-rakenne} sivutyyli \koodi{plain}
+kytketään päälle sisällysluettelon alkaessa, eli sivunumerotkin alkavat
+sen myötä näkyä. Sivutyylejä ja muita ylä- ja alatunnisteisiin liittyviä
+asioita käsitellään tarkemmin luvussa \ref{luku/ylä-ala-tunnisteet}.
+
+Mikäli haluaa, että sisällysluettelossa ei vielä näytetä sivunumeroita,
+joutuu dokumenttiluokissa \luokka{book} ja \luokka{report} käyttämään
+vähän epätavallista keinoa halutun lopputuloksen saavuttamiseksi.
+Sellainen neuvotaan sisällysluettelon käsittelyn yhteydessä esimerkissä
+\ref{esim/sisällysluettelo-empty}.
+
+\section{Sisällysluettelo}
+\label{luku/sisällysluettelo}
+
+Dokumentin sisällysluettelo syntyy helposti yhdellä komennolla:
+\komentom{tableofcontents}. Otsikkokomennoilla (luku \ref{luku/otsikot})
+tehdyt otsikot tulevat automaattisesti sisällysluetteloon. Jos käytössä
+on paketti \paketti{hyperref} (luku \ref{luku/pdf-asetukset}),
+sisällysluettelon otsikot ovat myös linkkejä, jotka vievät kyseiseen
+kohtaan dokumentissa. Oletuksena syntyvä sisällysluettelo on tyyliltään
+neutraali, ja se sopinee sellaisenaan useimpiin töihin. Ulkoasua voi
+kyllä muokatakin varsin helposti.
+
+\komentoi{tableofcontents}
+\begin{koodilohkosis}
+% Ladotaan sisällysluettelo tähän kohtaan.
+\tableofcontents
+\end{koodilohkosis}
+
+\noindent
+Laskurin \laskurim{tocdepth} avulla kirjoittaja voi määritellä, mihin
+tasoon saakka sisällysluettelossa näytetään otsikoita. Esimerkiksi
+jonkin kuvitteellisen romaanin (dokumenttiluokka \luokka{book})
+sisällysluettelossa voisi näyttää ainoastaan osat (\komento{part}) ja
+pääluvut (\komento{chapter}) asettamalla laskurin arvoksi nolla. Arvo
+nolla viittaa nimenomaan \komento{chapter}\-/ tasoisiin otsikoihin.
+Otsikoiden tasonumerot voi tarkistaa taulukosta \ref{tlk/otsikkotasot}
+(s.~\pageref{tlk/otsikkotasot}).
+
+\komentoi{setcounter}
+\laskurii{tocdepth}
+\begin{koodilohkosis}
+\setcounter{tocdepth}{0}
+\end{koodilohkosis}
+
+\noindent
+Sisällysluettelolle ladotaan automaattisesti otsikko, joka tulee
+komennosta \komentom{contentsname}. Komento on määritelty
+kieliasetuksissa, ja se latoo suomen kielessä sanan ''Sisältö'' tai
+''Sisällys''.%
+\footnote{Se, kumpi otsikko on käytössä, riippuu kielipakettien
+ \paketti{polyglossia} ja \paketti{babel} versiosta. Vuonna 2020
+ kumpaankin kielipakettiin on muutettu otsikoksi ''Sisällys'', joka on
+ selvästi yleisin sisällysluettelon otsikko.} Jos otsikkoon ei ole
+tyytyväinen, voi lähdedokumentin esittelyosassa \komento{addto}\-/
+komennon avulla muuttaa kieliasetuksia. Seuraavassa esimerkissä
+muutetaan sisällysluettelon otsikko suomen kielen osalta:
+
+\komentoi{addto}
+\komentoi{captionsfinnish}
+\komentoi{renewcommand}
+\komentoi{contentsname}
+\begin{koodilohkosis}
+\addto{\captionsfinnish}{
+ \renewcommand{\contentsname}{Sisällysluettelo}
+}
+\end{koodilohkosis}
+
+\noindent
+Dokumenttiluokissa \luokka{book} ja \luokka{report} (luku
+\ref{luku/perusdokumenttiluokat}) on sellainen ominaisuus tai
+kummallisuus, että sisällysluettelon alkusivulla suoritetaan
+automaattisesti komento \komento{thispagestyle}\komentoarg{plain}. Tämän
+vuoksi sisällysluettelon ensimmäinen sivu on aina \koodi{plain}\-/
+tyylinen eli alatunnisteessa näkyy sivunumero, vaikka ennen
+sisällysluetteloa olisikin asettanut sivutyyliksi jonkin muun.
+Monisivuisen sisällysluettelon seuraavilla sivuilla sen sijaan
+noudatetaan aiemmin \komento{pagestyle}\-/ komennolla asetettua
+sivutyyliä.
+
+\begin{esimerkki*}
+ \komentoi{pagestyle}
+ \komentoi{renewcommand}
+ \komentoi{thispagestyle}
+ \komentoi{tableofcontents}
+
+\begin{koodilohko}
+\pagestyle{empty}
+{
+ \renewcommand{\thispagestyle}[1]{} % tyhjä määritelmä
+ \tableofcontents
+}
+\end{koodilohko}
+ \caption{Sisällysluettelon sivutyylin muuttaminen kokonaan
+ \koodi{empty}\-/ tyyliseksi. Komento \komento{thispagestyle} pitää
+ määritellä väliaikaisesti uudestaan dokumenttiluokissa \luokka{report}
+ ja \luokka{book}}
+ \label{esim/sisällysluettelo-empty}
+\end{esimerkki*}
+
+Jotta edellä mainitusta kummallisuudesta pääsisi eroon, täytyy
+määritellä väliaikaisesti \komento{thispagestyle}\-/ komento
+toisenlaiseksi. Väliaikainen komennon määrittely saadaan aikaan
+aaltosulkeilla (luku \ref{luku/aaltosulkeet}), joiden sisään komennon
+uudelleen määrittely ja sisällysluettelon latomiskomento sijoitetaan.
+Esimerkistä \ref{esim/sisällysluettelo-empty} selviää, miten se tehdään.
+Tässä esimerkissä komennon määritelmä jätettiin tyhjäksi, koska sen ei
+haluta tekevän mitään. Näin ollen aiemmin annettu \komento{pagestyle}\-/
+komento vaikuttaa koko sisällysluetteloon.
+
+Normaalit otsikot tulevat mukaan sisällysluetteloon itsestään, mutta
+joskus voi joutua lisäämään luetteloon kohtia myös keinotekoisesti. Se
+tehdään komennolla \komentom{addcontentsline}, jonka käytöstä on
+esimerkki luvussa \ref{luku/otsikot}. Pelkkään pdf\-/ tiedoston
+sisäiseen sisällysluetteloon voi lisätä kohtia komennolla
+\komentom{pdfbookmark}, joka kuuluu \paketti{hyperref}\-/ pakettiin.
+Tätä komentoa käsitellään luvussa \ref{luku/pdf-asetukset}.
+
+\begin{esimerkki*}
+ \komentoi{addvspace}
+ \komentoi{bfseries}
+ \komentoi{contentslabel}
+ \komentoi{contentspage}
+ \komentoi{hspace}
+ \komentoi{large}
+ \komentoi{normalsize}
+ \komentoi{rmfamily}
+ \komentoi{small}
+ \komentoi{titlecontents}
+ \komentoi{titlerule*}
+ \komentoi{titlerule}
+
+\begin{koodilohko}
+\titlecontents{chapter} % otsikon taso: chapter
+[8mm] % vasen sisennys (mitta)
+{\addvspace{1.5ex}\rmfamily\bfseries\large} % yläpuolinen koodi
+{\contentslabel{8mm}} % numeroitu kohta
+{\hspace{-8mm}} % numeroimaton kohta
+{\small\titlerule[0bp]\contentspage} % pisteviiva (pois) ja sivunumero
+[\addvspace{.5ex}] % alapuolinen koodi
+
+\titlecontents{section} % otsikon taso: section
+[8mm] % vasen sisennys (mitta)
+{\addvspace{.5ex}\rmfamily\normalsize} % yläpuolinen koodi
+{\contentslabel{8mm}} % numeroitu kohta
+{} % numeroimaton kohta
+{~\small\titlerule*[3mm]{.}\contentspage} % pisteviiva ja sivunumero
+[\addvspace{.2ex}] % alapuolinen koodi
+
+\titlecontents{subsection} % otsikon taso: subsection
+[18mm] % vasen sisennys (mitta)
+{\rmfamily\small} % yläpuolinen koodi
+{\contentslabel{10mm}} % numeroitu kohta
+{} % numeroimaton kohta
+{~\small\titlerule*[3mm]{.}\contentspage} % pisteviiva ja sivunumero
+[] % alapuolinen koodi
+\end{koodilohko}
+ \caption{Sisällysluettelon ulkoasua muokataan \komento{titlecontents}\-/
+ komennolla, joka on peräisin \paketti{titletoc}\-/ paketista}
+ \label{esim/titlecontents}
+\end{esimerkki*}
+
+Sisällysluettelon ulkoasun muokkaamista varten on paketti
+\pakettictan{titletoc}, jonka tärkeimmän komennon
+(\komentom{titlecontents}) käyttöä esitellään esimerkissä
+\ref{esim/titlecontents}. Komennolla voi muokata paitsi
+sisällysluettelon kohtia mutta myös leijuvien osien (luku
+\ref{luku/leijuosat}) kuten kuvien ja taulukoiden luetteloita.
+
+Esimerkistä selviää, miten \komento{titlecontents}\-/ komennolla
+määritellään luettelokohdan vasemman sisennyksen mitta, yläpuolinen ja
+alapuolinen väli (\komento{addvspace}, luku
+\ref{luku/pystysuuntaiset-välit}), mahdolliset kirjainperheeseen ja
+\=/leikkaukseen vaikuttavat komennot kuten \komento{rmfamily},
+\komento{bfseries} ja \komento{large} (luku \ref{luku/fontit-korkea}).
+
+\komento{titlecontents}\-/ komennon argumenteissa käytetään jonkin
+verran muita komentoja, jotka on tarkoitettu nimenomaan tämän komennon
+argumentteihin. Komento \komento{contentslabel} latoo kyseisen otsikon
+numeron (1.2, 1.3 tms.) tietynlevyiseen tilaan ja sisennystason
+vasemmalle puolelle (ns. riippuva sisennys). Komento
+\komento{contentspage} latoo sivunumeron. Komennolla \komento{titlerule}
+voi tehdä katsetta ohjaavan viivan tai pisteviivan otsikkotekstin ja
+sivunumeron väliin.
+
+Paketin \paketti{titletoc} ohjekirjassa on paljon muitakin
+toimintoja ja esimerkkejä sisällysluetteloiden ehostamiseen. Ohjeisiin
+kannattaa tutustua, mikäli kaipaa erikoisempia sisällysluettelomalleja.
+
+\section{Luetelmat}
+\label{luku/luetelmat}
+
+Latexissa on helppokäyttöiset ympäristöt kolmelle erilaiselle luetelman
+perustyypille: numeroimaton (\ymparisto{itemize}), numeroitu
+(\ymparisto{enumerate}) ja määritelmäluetelma (\ymparisto{description}).
+Ne riittänevät perustarpeisiin ja ovat hieman myös muokattavissa
+typografisesti. Luetelmien perusympäristöjä käsitellään luvussa
+\ref{luku/luetelma-perus}.
+
+Perusluetelmien lisäksi on olemassa yleinen luetelmien rakenteluun
+tarkoitettu ympäristö \ymparisto{list}, jolla voi toteuttaa suunnilleen
+mitä tahansa luetelmiin tai tekstikappaleisiin liittyviä rakenteita.
+Teknisesti \ymparisto{list}\-/ ympäristö sisältää kaikki tarvittavat
+luetelmiin liittyvät ominaisuudet, joten kirjoittaja voi aivan hyvin
+käyttää pelkästään sitä. Ympäristöä käsitellään luvussa
+\ref{luku/list-ympäristö}.
+
+\subsection{Perusympäristöt}
+\label{luku/luetelma-perus}
+
+Ympäristö \ymparistom{itemize} tekee numeroimattoman luetelman, jonka
+jokainen kohta merkitään samanlaisella merkillä, esimerkiksi
+luetelmaympyrällä~(\textbullet). \ymparistom{enumerate} puolestaan on
+numeroitu luetelma, eli luetelman kohdat saavat järjestysnumeron tai
+muun järjestystä ilmaisevan merkinnän kuten kirjaimen tai roomalaisen
+numeron. Ympäristö \ymparistom{description} luo määritelmäluetelman,
+jossa luetellaan käsitteitä ja niiden määritelmiä. Tämä on käytännössä
+sama kuin tekstikappaleen riippuva sisennys (luku
+\ref{luku/riippuva-sisennys}), jossa kappale alkaa määriteltävällä
+ilmauksella.
+
+Luetelmien perusrakenne on samanlainen: luetelmaympäristön sisällä
+käytetään \komentom{item}\-/ komentoa, joka aloittaa uuden
+luetelmakohdan. Komennolle ei tarvitse antaa argumenttia: se vain
+aloittaa uuden luetelmakohdan. Seuraavassa on esimerkki
+\ymparisto{itemize}\-/ ympäristöstä, mutta \ymparisto{enumerate}\-/
+ympäristöäkin käytetään samalla tavalla:
+
+\ymparistoi{itemize}
+\komentoi{item}
+\begin{koodilohkosis}
+\begin{itemize}
+\item Luetelman ensimmäinen kohta.
+\item Toinen kohta heti perään.
+\item Kolmaskin kohta on tarpeen.
+\end{itemize}
+\end{koodilohkosis}
+
+\noindent
+\komento{item}\-/ komennolle voi antaa hakasulkeissa valinnaisen
+argumentin. Silloin ei ladota tavanomaista luetelmamerkkiä vaan
+argumentin sisältämä teksti tai koodi.
+
+\komentoi{item}
+\begin{koodilohkosis}
+\item[--] Tässä kohdassa onkin ajatusviiva (--).
+\end{koodilohkosis}
+
+\begin{esimerkki*}
+ \ymparistoi{description}
+ \komentoi{item}
+
+\begin{koodilohko}
+\begin{description}
+\item[Tex] Tekstidokumenttien ladontaan erikoistunut ohjelmointikieli.
+\item[Latex] Dokumenttien kirjoittajille tarkoitettu merkintäkieli.
+\item[Lualatex] Latex-muotoisten lähdedokumenttien kääntäjäohjelma.
+ Sisältää Lua-nimisen ohjelmointikielen.
+\end{description}
+\end{koodilohko}
+
+ \begin{tulos}
+ \begin{description}
+ \item[Tex] Tekstidokumenttien ladontaan erikoistunut ohjelmointikieli.
+ \item[Latex] Dokumenttien kirjoittajille tarkoitettu merkintäkieli.
+ \item[Lualatex] Latex-muotoisten lähdedokumenttien kääntäjäohjelma.
+ Sisältää Lua-nimi\-sen ohjelmointikielen.
+ \end{description}
+ \end{tulos}
+ \caption{Käsitteiden määritelmiä ja sen kaltaisia luetelmia voi
+ toteuttaa \ymparisto{description}\-/ ympäristön avulla. Käsitteet
+ kirjoitetaan \komento{item}\-/ komennon valinnaiseen argumenttiin}
+ \label{esim/description}
+\end{esimerkki*}
+
+\noindent
+Komennon valinnaista argumenttia hyödynnetään varsinkin
+\ymparisto{description}\-/ ympäristössä, jossa luetellaan sanoja tai
+käsitteitä ja niiden määritelmiä. Esimerkistä \ref{esim/description}
+selviää, kuinka määriteltävät käsitteet ilmaistaan \komento{item}\-/
+komennon valinnaisessa argumentissa.
+
+Edellä mainittuja luetelmaympäristöjä voi kirjoittaa sisäkkäin: yksi
+luetelman kohta (\komento{item}) voi siis aloittaa uuden
+luetelmaympäristön. Latex osaa käsitellä neljä sisäkkäistä luetelmaa.
+
+Latex sisentää sisäkkäiset luetelmat automaattisesti loogisella tavalla
+ja vaihtaa eri tasoilla luetelmakohtien merkkiä tai numerointitapaa.
+Esimerkiksi ulommaisin \ymparisto{itemize}\-/ ympäristö käyttää
+luetelmaympyrää~(\textbullet), mutta sen sisällä oleva käyttää
+ajatusviivaa~(\==). Ulommaisin \ymparisto{enumerate}\-/ ympäristö
+käyttää arabialaisia numeroita (1, 2, 3 jne.) mutta sen sisällä oleva
+kirjaimia (a, b, c jne.).
+
+\begin{esimerkki*}
+ \komentoi{renewcommand}
+ \komentoi{labelitemi}
+ \komentoi{labelitemii}
+ \komentoi{labelitemiii}
+ \komentoi{labelitemiv}
+ \komentoi{textbullet}
+ \komentoi{normalfont}
+ \komentoi{bfseries}
+ \komentoi{textendash}
+ \komentoi{textasteriskcentered}
+ \komentoi{textperiodcentered}
+ \komentoi{labelenumi}
+ \komentoi{labelenumii}
+ \komentoi{labelenumiii}
+ \komentoi{labelenumiv}
+ \komentoi{arabic}
+ \komentoi{alph}
+ \komentoi{Alph}
+ \komentoi{roman}
+ \laskurii{enumi}
+ \laskurii{enumii}
+ \laskurii{enumiii}
+ \laskurii{enumiv}
+
+\begin{koodilohko}
+% itemize-ympäristön luetelmamerkki
+\renewcommand{\labelitemi} {\textbullet} % ulommainen luetelma
+\renewcommand{\labelitemii} {\normalfont\bfseries\textendash}
+\renewcommand{\labelitemiii}{\textasteriskcentered}
+\renewcommand{\labelitemiv} {\textperiodcentered}
+
+% enumerate-ympäristön numerointitapa
+\renewcommand{\labelenumi} {\arabic{enumi}.} % ulommainen luetelma
+\renewcommand{\labelenumii} {(\alph{enumii})}
+\renewcommand{\labelenumiii}{\roman{enumiii}.}
+\renewcommand{\labelenumiv} {\Alph{enumiv}.}
+\end{koodilohko}
+ \caption{Luetelmamerkkien ja numerointitapojen muuttaminen
+ \ymparisto{itemize}\-/\ ja \ymparisto{enumerate}\-/ ympäristöissä.
+ Esimerkissä näkyvät oletusarvot}
+ \label{esim/labelitem-labelenum}
+\end{esimerkki*}
+
+Luetelmamerkit ja luetelmien numerointitavat ovat kirjoittajan
+muutettavissa. Ympäristössä \ymparisto{itemize} luetelmamerkit tulevat
+komennosta, joka alkaa sanoilla \komentox{label\-item} ja jatkuu
+luetelman tasoa ilmaisevalla roomalaisella numerolla
+\koodi{i}\==\koodi{iv}. Komennot voi määritellä uudelleen haluamallaan
+tavalla, kuten esimerkki \ref{esim/labelitem-labelenum} osoittaa.
+
+\ymparisto{enumerate}\-/ ympäristössä numeroidut kohdat tulevat
+komennosta, joka alkaa sanoilla \komentox{label\-enum} ja jatkuu
+luetelman tasoa ilmaisevalla roomalaisella numerolla
+\koodi{i}\==\koodi{iv}. Numeroidussa luetelmassa käytetään laskureita
+\laskuri{enumi}, \laskuri{enumii}, \laskuri{enumiii} ja
+\laskuri{enumiv}, joten luetelmakohtien täytyy latoa näiden laskurien
+arvo jossakin muodossa. Esimerkki \ref{esim/labelitem-labelenum}
+selventää asiaa.
+
+Numeroiduista luetelmakohdista huolehtivat laskurit nollataan
+automaattisesti aina ympäristön alussa. Joskus voi kuitenkin olla
+tarpeen aloittaa luetelmakohdat jostain muusta kuin luvusta~1,
+kirjaimesta~\textit{a} tms. Silloin kirjoittajan täytyy asettaa laskuri
+haluamaansa arvoon \ymparisto{enumerate}\-/ ympäristön sisällä. Seuraava
+esimerkki asettaa uloimman luetelman \laskuri{enumi}\-/ laskurin
+arvoon~3, joten ensimmäiseksi luetelmakohdaksi tulee~4.
+
+\ymparistoi{enumerate}
+\komentoi{setcounter}
+\komentoi{item}
+\laskurii{enumi}
+\begin{koodilohkosis}
+\begin{enumerate}
+ \setcounter{enumi}{3}
+\item Tämä on luetelmakohta numero 4.
+\end{enumerate}
+\end{koodilohkosis}
+
+\noindent
+Kirjoittaja voi vaikuttaa myös luetelmakohtien sisennykseen ja
+pystysuuntaisiin väleihin. Sisennykseen vaikuttavat mitat alkavat
+sanoilla \mittax{leftmargin} ja jatkuvat roomalaisella numerolla
+\koodi{i}\==\koodi{iv}, joka ilmaisee luetelman tasoa. Ulommaisen
+luetelman sisennys ilmaistaan suhteessa sivun tekstialueen reunaan;
+sisempien luetelmien sisennys ilmaistaan suhteessa edellisen tason
+sisennykseen. Oletuksena Latexin sisennykset ovat melko suuria, joten
+niitä on usein tarpeen pienentää, esimerkiksi seuraavan esimerkin
+mukaisesti:
+
+\komentoi{setlength}
+\mittai{leftmargini}
+\mittai{leftmarginii}
+\mittai{leftmarginiii}
+\mittai{leftmarginiv}
+\begin{koodilohkosis}
+\setlength{\leftmargini} {1.5em} % ulommainen luetelma
+\setlength{\leftmarginii} {1.5em}
+\setlength{\leftmarginiii}{1.5em}
+\setlength{\leftmarginiv} {1.5em}
+\end{koodilohkosis}
+
+\noindent
+Edellä olevat sisennysasetukset toimivat ympäristöissä
+\ymparisto{itemize}, \ymparisto{enumerate} ja \ymparisto{description}.
+Mainituissa ympäristöissä voi säätää pystysuuntaisia välejä kolmen
+seuraavassa esimerkissä mainitun mitan avulla. Mittojen sijainti
+luetelmassa on nähtävissä kuvassa \ref{kuva/list-mitat}
+(s.~\pageref{kuva/list-mitat}). Seuraavat komennot on syytä sijoittaa
+luetelmaympäristön sisään heti \komento{begin}\-/ komennon jälkeen.
+
+\komentoi{setlength}
+\mittai{parsep}
+\mittai{itemsep}
+\mittai{parskip}
+\begin{koodilohkosis}
+\setlength{\parsep} {0bp} % kappaleiden väli
+\setlength{\itemsep}{3bp} % luetelmakohtien väli
+\setlength{\parskip}{1.2ex} % väli luetelman alussa ja lopussa
+\end{koodilohkosis}
+
+\subsection{Omat luetelmat (list)}
+\label{luku/list-ympäristö}
+
+Ympäristö \ymparistom{list} on yleistyökalu, joka soveltuu moniin
+asioihin: se on tarkoitettu erilaisten luetelmien rakentamiseen, mutta
+sen avulla muotoilla mitä tahansa tekstikappaleita. Esimerkiksi luvussa
+\ref{luku/luetelma-perus} käsitellyt luetelmat voi toteuttaa myös
+\ymparisto{list}\-/ ympäristön avulla -- samoin luvuissa
+\ref{luku/riippuva-sisennys} ja \ref{luku/lohkolainaukset} käsitellyt
+riippuvat sisennykset ja lohkolainaukset.
+
+Tyypillisesti \ymparisto{list}\-/ ympäristöä ei käytetä dokumentin
+kirjoittamisessa sellaisenaan, vaan kirjoittaja määrittelee oman
+helppokäyttöisen luetelma\-/\ tai muun ympäristön, ja
+\ymparisto{list}\-/ ympäristöä hyödynnetään ympäristön
+määrittelemisessä. Omien ympäristöjen tekemistä käsitellään tarkemmin
+luvussa \ref{luku/ympäristöt}, mutta tämänkin alaluvun loppupuolella on
+esimerkki, joka liittyy nimenomaan \ymparisto{list}\-/ ympäristöön.
+
+Seuraavassa on esimerkki \ymparisto{list}\-/ ympäristön rakenteesta. Se
+muistuttaa luvussa \ref{luku/luetelma-perus} käsiteltyjä perusluetelmia,
+mutta lisäksi sille täytyy antaa kaksi argumenttia. Niiden avulla
+vaikutetaan luetelman asetuksiin.
+
+\begin{koodilohkosis}
+\begin{list}{merkki}{asetukset}
+\item ...
+\end{list}
+\end{koodilohkosis}
+
+\noindent
+Edellisen esimerkin argumentti \koodi{merk\-ki} sisältää tekstiä tai
+koodia, jonka muodostaa luetelmakohdan merkin. Numeroimattomassa
+luetelmassa siihen voi laittaa esimerkiksi luetelmaympyrän eli komennon
+\komento{textbullet} tai ajatusviivan (\koodi{--}). Numeroidussa
+luetelmassa siihen kirjoitetaan komento, joka latoo jonkin laskurin
+arvon.
+
+\ymparisto{list}\-/ ympäristön toinen argumentti \koodi{ase\-tuk\-set}
+sisältää mitä hyvänsä koodia, jolla vaikutetaan ympäristön asetuksiin.
+Tyypillisesti siinä määritellään käytettävä luetelmalaskuri sekä
+asetetaan luetelman ulkoasuun vaikuttavat mitat sopivaksi. Mahdollisesti
+siinä myös määritellään luetelmamerkkien latomiseen vaikuttava komento
+\komento{makelabel}.
+
+\begin{esimerkki*}
+ \ymparistoi{list}
+ \komentoi{arabic}
+ \komentoi{setlength}
+ \komentoi{usecounter}
+ \mittai{leftmargin}
+ \mittai{itemsep}
+ \mittai{parsep}
+ \laskurii{enumi}
+
+\begin{koodilohko}
+\begin{list}{\arabic{enumi})}{
+ \usecounter{enumi} % käytetään enumi-laskuria
+ \setlength{\leftmargin}{1.5em} % vasen sisennys
+ \setlength{\itemsep}{.2ex} % luetelmakohtien väli
+ \setlength{\parsep}{0ex} % luetelmakappaleiden väli
+ }
+\item Luetelman ensimmäinen kohta.
+\item Tässä on vielä toinen
+\item ja kolmas kohta.
+\end{list}
+\end{koodilohko}
+ \begin{tulos}
+ \begin{list}{\arabic{enumi})}{
+ \usecounter{enumi} % käytetään enumi-laskuria
+ \setlength{\leftmargin}{1.5em} % vasen sisennys
+ \setlength{\itemsep}{.2ex} % luetelmakohtien väli
+ \setlength{\parsep}{0ex} % luetelmakappaleiden väli
+ }
+ \item Luetelman ensimmäinen kohta.
+ \item Tässä on vielä toinen
+ \item ja kolmas kohta.
+ \end{list}
+ \end{tulos}
+ \caption{\ymparisto{list}\-/ ympäristön argumenttien avulla vaikutetaan
+ luetelmakohtien merkintätapaan ja mittoihin}
+ \label{esim/list-perus}
+\end{esimerkki*}
+
+Esimerkissä \ref{esim/list-perus} on yksinkertainen numeroitu luetelma,
+joka hyödyntää olemassa olevaa \laskuri{enumi}\-/ laskuria (luku
+\ref{luku/luetelma-perus}). Laskurin arvo ladotaan arabialaisilla
+numeroilla (\komento{arabic}). Laskurin \laskuri{enumi} sijasta voi
+käyttää mitä tahansa omaakin laskuria, kunhan luo sen etukäteen
+komennolla \komento{newcounter} (luku \ref{luku/laskurit}). Esimerkissä
+asetetaan myös eräitä luetelman sisäisiä mittoja, joista on lisätietoa
+myöhemmin tässä alaluvussa sekä kuvassa \ref{kuva/list-mitat}.
+
+\begin{esimerkki*}
+ \ymparistoi{list}
+ \komentoi{renewcommand}
+ \komentoi{makelabel}
+ \komentoi{textsc}
+ \komentoi{setlength}
+ \komentoi{item}
+ \mittai{leftmargin}
+ \mittai{labelwidth}
+ \mittai{labelsep}
+ \mittai{itemindent}
+ \mittai{itemsep}
+
+\begin{koodilohko}
+\begin{list}{}{
+ \renewcommand{\makelabel}[1]{\textsc{#1:}}
+ \setlength{\leftmargin}{1.5em}
+ \setlength{\labelwidth}{1.5em}
+ \setlength{\itemindent}{1em}
+ \setlength{\labelsep}{1em}
+ \setlength{\itemsep}{.2ex}
+ }
+\item[Tex] Tekstidokumenttien ladontaan erikoistunut ohjelmointikieli.
+\item[Latex] Dokumenttien kirjoittajille tarkoitettu merkintäkieli.
+\item[Lualatex] Latex-muotoisten lähdedokumenttien kääntäjäohjelma.
+ Sisältää Lua-nimi\-sen ohjelmointikielen.
+\end{list}
+\end{koodilohko}
+ \begin{tulos}
+ \begin{list}{}{
+ \renewcommand{\makelabel}[1]{\textsc{#1:}}
+ \setlength{\leftmargin}{1.5em}
+ \setlength{\labelwidth}{1.5em}
+ \setlength{\itemindent}{1em}
+ \setlength{\labelsep}{1em}
+ \setlength{\itemsep}{.2ex}
+ }
+ \item[Tex] Tekstidokumenttien ladontaan erikoistunut ohjelmointikieli.
+ \item[Latex] Dokumenttien kirjoittajille tarkoitettu merkintäkieli.
+ \item[Lualatex] Latex-muotoisten lähdedokumenttien kääntäjäohjelma.
+ Sisältää Lua-nimi\-sen ohjelmointikielen.
+ \end{list}
+ \end{tulos}
+ \caption{Määritelmäluetelmien tekeminen \ymparisto{list}\-/ ympäristön
+ avulla. Sisäisesti komento \komento{makelabel} huolehtii
+ luetelmamerkkien eli tässä käsitteiden nimien latomisesta}
+ \label{esim/list-makelabel}
+\end{esimerkki*}
+
+Luetelmamerkit \ymparisto{list}\-/ ympäristö latoo siten, että se
+suorittaa aina komennon \komento{makelabel} ja antaa sille argumentiksi
+kulloisenkin luetelmamerkin eli \ymparisto{list}\-/ ympäristön
+ensimmäisenä argumenttina annetun tekstin tai \komento{item}\-/ komennon
+valinnaisena argumenttina olevan tekstin. Luetelmamerkki ladotaan sille
+varatun alueen oikeaan reunaan. Oletuksena \komento{makelabel}\-/
+komento toimii ikään kuin se olisi määritelty seuraavalla tavalla:
+
+\komentoi{renewcommand}
+\komentoi{makelabel}
+\komentoi{hfill}
+\begin{koodilohkosis}
+\renewcommand{\makelabel}[1]{\hfill #1}
+\end{koodilohkosis}
+
+\noindent
+Kirjoittaja voi määritellä \komento{makelabel}\-/ komennon uudelleen
+sellaiseksi kuin haluaa. Se on tarpeen esimerkiksi silloin, kun täytyy
+latoa kaikki luetelmamerkit eri fontilla kuin muu teksti. Varsinkin
+määritelmäluetelmissa (luku \ref{luku/luetelma-perus}), joissa
+luetellaan käsitteitä ja niiden määritelmiä, on usein hyödyllistä, että
+käsitteet erottuvat muusta tekstistä selvästi. Esimerkki
+\ref{esim/list-makelabel} selventää tätä asiaa.
+
+\leijukuva{
+ \begin{tikzpicture}
+ [x=.01\textwidth, y=.01\textwidth, line width=1bp, rounded corners=2bp]
+
+ \newcommand{\kpl}[1]{\draw (15,#1) -- ++(70,0) -- ++(0,15)
+ -- ++(-60,0) -- ++(0,-5) -- ++(-10,0) -- cycle}
+ \newcommand{\nuoli}[2]{\draw [color=mittanuoli, <->] (#1) -- (#2)}
+ \newcommand{\kyltti}[2]{\draw (#1) node [anchor=west] {#2}}
+
+ \newcommand{\katko}[2]{\draw [color=apuviiva, densely dotted, line
+ width=.7bp] (#1) -- (#2)}
+
+ \katko{0,10}{0,110};
+ \katko{100,10}{100,110};
+
+ \kpl{80};
+ \kpl{55};
+ \kpl{25};
+
+ \draw (0,10) rectangle ++(100,-7);
+ \node at (50,6) {alapuolinen teksti};
+
+ \draw (0,110) rectangle ++(100,7);
+ \node at (50,113) {yläpuolinen teksti};
+
+ \nuoli{50,110}{50,95};
+ \kyltti{51,102.5}{\mitta{topsep} + \mitta{parskip} (+ \mitta{partopsep})};
+
+ % Ylin kappale
+ \node at (50,87) {luetelmakohta 1};
+ \draw (5,91) rectangle ++(15,4);
+ \katko{5,98}{5,95};
+ \katko{20,98}{20,95};
+ \katko{25,98}{25,95};
+ \nuoli{5,98}{20,98}; \kyltti{2,102}{\mitta{labelwidth}};
+ \nuoli{20,98}{25,98}; \kyltti{20,102}{\mitta{labelsep}};
+ \katko{25,90}{25,87};
+ \nuoli{15,87}{25,87}; \kyltti{15,84}{\mitta{itemindent}};
+
+ \nuoli{50,70}{50,80};
+ \kyltti{51,75}{\mitta{parsep}};
+
+ % Keskimmäinen kappale
+ \node at (50,62) {toinen tekstikappale};
+ \nuoli{0,57}{15,57};
+ \kyltti{0,52}{\mitta{leftmargin}};
+ \nuoli{85,57}{100,57};
+ \kyltti{82,52}{\mitta{rightmargin}};
+ \katko{15,70}{15,65};
+ \nuoli{15,70}{25,70};
+ \kyltti{13,74}{\mitta{listparindent}};
+
+ \nuoli{50,40}{50,55};
+ \kyltti{51,47}{\mitta{itemsep} + \mitta{parsep}};
+
+ % Alin kappale
+ \node at (50,32) {luetelmakohta 2};
+ \draw (5,36) rectangle ++(15,4);
+
+ \nuoli{50,25}{50,10};
+ \kyltti{51,17.5}{\mitta{topsep} + \mitta{parskip} (+ \mitta{partopsep})};
+ \end{tikzpicture}
+}{
+ \caption{Luetelmien tekemiseen tarkoitetun \ymparisto{list}\-/
+ ympäristön mitat}
+ \label{kuva/list-mitat}
+}
+
+Luetelmiin liittyviä mittoja on useita, ja ne voi asettaa sopiviin
+arvoihin \ymparisto{list}\-/ ympäristön toisen argumentin sisällä.
+Mittojen sijainnit on koottu kuvaan \ref{kuva/list-mitat}, ja
+seuraavassa on lisätietoa niiden merkityksestä.
+
+\begin{maaritelma}{\mitta{#1}}
+\item [parskip] Pystysuuntainen mitta ja väli, joka ei liity pelkästään
+ \ymparisto{list}\-/ ympäristöön vaan on yleinen tekstikappaleiden
+ välinen etäisyysmitta (luku \ref{luku/pystysuuntaiset-välit}). Mitta
+ on vaikuttaa kuitenkin myös \ymparisto{list}\-/ ympäristöön, ja sen
+ voi määritellä väliaikaisesti uudelleen ympäristön yhteydessä.
+\item [topsep] Pystysuuntainen väli, joka ladotaan ennen ja jälkeen
+ \ymparisto{list}\-/ ympäristön, yhdessä mittojen \mitta{parskip} ja
+ \mitta{partopsep} kanssa.
+\item [partopsep] Pystysuuntainen väli, joka lisätään
+ \ymparisto{list}\-/ ympäristöä ennen ja sen jälkeen silloin, kun
+ ympäristö aloittaa uuden tekstikappaleen eli sitä ennen on tyhjä rivi.
+\item [parsep] Pystysuuntainen väli, joka tulee luetelman sisällä
+ kaikkien luetelmakohtien väliin sekä saman luetelmakohdan eri
+ tekstikappaleiden väliin.
+\item [itemsep] Pystysuuntainen väli, joka tulee luetelman sisällä
+ luetelmakohtien väliin.
+\item [leftmargin] Luetelman kappaleiden vasen sisennys.
+\item [rightmargin] Luetelman kappaleiden oikea sisennys. Oletusarvo on
+ nolla.
+\item [labelwidth] Luetelmamerkin leveys. Merkki ladotaan oletuksena
+ tämän alueen oikeaan reunaan, mutta se riippuu \komento{makelabel}\-/
+ komennon on määrittelystä. Jos luetelmamerkki on leveämpi kuin
+ \mitta{labelwidth}\-/ mitta, luetelman teksti siirtyy oikealle siten,
+ että merkki mahtuu kokonaan. Luetelmamerkin alueen vasen reuna
+ sijaitsee kohdassa, jonka voi laskea seuraavasta kaavasta:
+ \mitta{leftmargin} − \mitta{labelwidth} + \mitta{itemindent} −
+ \mitta{labelsep}. Mikäli haluaa, että luetelmamerkin vasen reuna on
+ sisennyksen nollakohdassa, täytyy edellä mainitut mitat asettaa siten,
+ että mittojen yhteistulos on nolla. Esimerkissä
+ \ref{esim/list-makelabel} on tehty juuri näin.
+\item [labelsep] Vaakasuuntainen väli luetelmamerkin jälkeen, ennen
+ luetelman sisältötekstiä. Oletusarvo on 0,5\,em.
+\item [itemindent] Ylimääräinen luetelmakohtien ensimmäisen rivin
+ sisennys. Tätä voi tarvita, kun haluaa säätää luetelmamerkin vasemman
+ reunan tiettyyn kohtaa. Katso mitta \mitta{labelwidth} edellä.
+ Oletusarvo on nolla.
+\item [listparindent] Luetelmakohtien toisen ja sitä seuraavien
+ tekstikappaleiden ensimmäisen rivin sisennys. Oletusarvo on nolla.
+\end{maaritelma}
+
+\noindent
+Kun on lopulta saanut \ymparisto{list}\-/ ympäristön asetukset
+kohdalleen ja luetelmat ovat sellaisia kuin pitääkin, on varmaankin hyvä
+aika luoda oma ympäristö, joka piilottaa asetukset yhden
+ympäristömäärittelyn sisään. Omaa ympäristöä on sitten helppoa käyttää
+useitakin kertoja omassa lähdedokumentissa.
+
+\begin{esimerkki*}
+ \komentoi{newenvironment}
+ \komentoi{setlength}
+ \komentoi{textbullet}
+ \mittai{itemsep}
+ \mittai{labelsep}
+ \mittai{leftmargin}
+ \mittai{parsep}
+ \ymparistoi{list}
+
+\begin{koodilohko}
+\newenvironment{numeroimaton}[1][\textbullet]{%
+ \begin{list}{#1}{
+ \setlength{\leftmargin}{1.1em}
+ \setlength{\labelsep}{.2em}
+ \setlength{\itemsep}{.4ex plus .1ex}
+ \setlength{\parsep}{.2ex}
+ }
+ }{\end{list}}
+\end{koodilohko}
+ \caption{Oman numeroimattoman luetelman tekeminen \ymparisto{list}\-/
+ ympäristön avulla}
+ \label{esim/list-oma-numeroimaton}
+\end{esimerkki*}
+
+\begin{esimerkki*}
+ \komentoi{arabic}
+ \komentoi{bfseries}
+ \komentoi{hfill}
+ \komentoi{large}
+ \komentoi{makelabel}
+ \komentoi{newenvironment}
+ \komentoi{renewcommand}
+ \komentoi{setcounter}
+ \komentoi{setlength}
+ \komentoi{usecounter}
+ \laskurii{enumi}
+ \mittai{itemsep}
+ \mittai{labelsep}
+ \mittai{leftmargin}
+ \mittai{parsep}
+ \ymparistoi{list}
+
+\begin{koodilohko}
+\newenvironment{numeroitu}[1][0]{%
+ \begin{list}{\arabic{enumi}.}{
+ \usecounter{enumi}
+ \setcounter{enumi}{#1}
+ \renewcommand{\makelabel}[1]{\hfill\bfseries\large ##1}
+ \setlength{\leftmargin}{2em}
+ \setlength{\labelsep}{.5em}
+ \setlength{\itemsep}{.4ex plus .1ex}
+ \setlength{\parsep}{.2ex}
+ }
+ }{\end{list}}
+\end{koodilohko}
+ \caption{Oman numeroidun luetelman tekeminen \ymparisto{list}\-/
+ ympäristön avulla}
+ \label{esim/list-oma-numeroitu}
+\end{esimerkki*}
+
+Esimerkissä \ref{esim/list-oma-numeroimaton} on vinkkejä oman
+numeroimattoman luetelman tekemiseen. Luetelma on nimeltään
+\ymparistox{numeroimaton}, ja sille voi antaa hakasulkeissa valinnaisen
+argumentin, jolla valitaan luetelmamerkki. Oletuksena se on
+luetelmaympyrä (\komento{textbullet}).
+
+Esimerkki \ref{esim/list-oma-numeroitu} tekee numeroidun ympäristön
+nimeltä \ymparistox{numeroitu}. Tälle ympäristölle voi antaa valinnaisen
+argumentin, jolla ilmaistaan numerointilaskurin alkukohta. Oletuksena se
+on nolla, eli luetelmakohtien numerointi alkaa luvusta~1. Tämä ympäristö
+määrittelee myös \komento{makelabel}\-/ komennon siten, että
+luetelmanumerot ladotaan lihavoituna (\komento{bfseries}) ja suuremmalla
+fontilla (\komento{large}). Numerot myös tasataan luetelmamerkille
+varatun tilan oikeaan reunaan (\komento{hfill}). Huomaa, että parametri
+\koodi{\#1} kuuluu \ymparistox{numeroitu}\-/ ympäristön määritelmään ja
+parametri \koodi{\#\#1} kuuluu sisempään, \komento{renewcommand}\-/
+komennolla tehtävään määritelmään. Katso lisätietoa komentojen
+määrittelyä käsittelevästä luvusta \ref{luku/komennot-määrittely}.
+
+\section{Taulukot}
+\label{luku/taulukot}
+
+Taulukoiden tekemiseen on perus Latexissa kaksi ympäristöä
+\ymparisto{tabular} ja \ymparisto{tabular*}, joskin jälkimmäisen tilalle
+sopii yleensä paremmin \paketti{tabularx}\-/ paketin ympäristö
+\ymparisto{tabularx}. Ennen varsinaista taulukoiden tekniikkaa
+käsitellään kuitenkin niiden sijoittamista ja typografiaa.
+
+Taulukon voi sijoittaa dokumenttiin eri tavoin. Yksi mahdollisuus on
+sijoittaa taulukot normaalin tekstivirran mukaan omiksi
+tekstikappaleikseen. Pieni pystysuuntainen väli on silloin tarpeen ennen
+ja jälkeen taulukon. Jos tekstikappaleiden välissä ei ole normaalisti
+ole väliä (\mitta{parskip}\-/ mitta), täytyy sellainen lisätä käsin.
+Pystysuuntaisia välejä käsitellään luvussa
+\ref{luku/pystysuuntaiset-välit}. Taulukolle tulee oletuksena sama
+sisennys kuin tekstikappaleiden ensimmäisellä rivillä on eli mitta
+\mitta{parindent} (luku \ref{luku/ensimmäisen-rivin-sisennys}). Jos
+sisennyksen haluaa pois, täytyy käyttää komentoa \komento{noindent}.
+
+Toinen tyypillinen vaihtoehto on sijoittaa taulukko vaakasuunnassa sivun
+keskelle, jolloin se erottuu muusta tekstistä vielä selvemmin. Tämän voi
+toteuttaa kirjoittamalla taulukkoympäristö \ymparisto{center}\-/
+ympäristön sisään (\ref{luku/kappaleen-tasaus}).
+
+Kolmas vaihtoehto on tehdä taulukosta leijuva eli antaa Latexin
+sijoittaa se sopivaan paikkaan. Samalla taulukolle annetaan kuvateksti
+ja yksilöllinen tunniste, niin että siihen voi viitata tekstistä.
+Leijuvia osia ja ristiviitteitä käsitellään luvuissa
+\ref{luku/leijuosat} ja \ref{luku/ristiviitteet}.
+
+Taulukkojen ulkoasua ja helppolukuisuutta käsittelevät ohjeet yleensä
+neuvovat, että pystyviivoja ei pitäisi juuri käyttää. Ne häiritsevät
+vasemmalta oikealle lukemista ja vaikeuttavat katseen tarkentamista
+solujen sisältöön. Tavallinen sarakkeiden välinen tyhjä tila on yleensä
+riittävä erottamaan solut toisistaan.
+
+Se on hyvä yleisohje, mutta sitä tuskin kannattaa pitää ihan ehdottomana
+sääntönä. Joskus on tarpeen jakaa sarakkeet mielekkäisiin ryhmiin ja
+nimenomaan ohjata katsetta pystysuunnassa tiettyjä sarakkeita pitkin.
+Katseen ei välttämättä haluta lipsuvan tietyn kohdan yli, ja pystyviiva
+sopii hyvin siihen tarkoitukseen. Tämän luvun esimerkeissä käytetään
+paljon vaaka- ja pystyviivoja, jotta lukija hahmottaa helposti, miten
+esimerkkikoodin solut ovat yhteydessä ladottuun taulukkoon. Käytännössä
+viivoja ei kannata käyttää niin paljon, vaan pari vaakaviivaa yleensä
+riittää.
+
+\subsection{Perustoiminnot}
+
+Taulukoiden perusympäristö on \ymparisto{tabular}, jonka rakenne on
+seuraava:
+
+\komentoi{\keno}
+\ymparistoi{tabular}
+\begin{koodilohkosis}
+\begin{tabular}[sijainti]{sarakkeet}
+ solu 1 & solu 2 \\
+ solu 3 & solu 4 \\
+\end{tabular}
+\end{koodilohkosis}
+
+\noindent
+Ympäristön valinnainen argumentti \koodi{sijainti} määrittelee
+taulukkoympäristön sijainnin pystysuunnassa, jos se on samassa
+kappaleessa muun tekstin kanssa. Oletusarvo on \koodi{c}
+(\englanti{center}), joka tarkoittaa, että pystysuunnassa taulukon
+peruslinja on sen keskellä. Muut vaihtoehdot ovat \koodi{t}
+(\englanti{top}), eli taulukon peruslinja on yläreunassa, ja \koodi{b}
+(\englanti{bottom}), eli taulukon peruslinja on sen alareunassa.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\koodi{#1} & #2 \\}
+ \begin{tabular}{ll}
+ \toprule
+ \ots{Tyyppi} & \ots{Merkitys} \\
+ \midrule
+ \rivi{l}{vasemmalle tasattu sarake (\englanti{left})}
+ \rivi{c}{keskitetty sarake (\englanti{center})}
+ \rivi{r}{oikealle tasattu sarake (\englanti{right})}
+ \rivi{p\{m\}}{sarake, jonka leveys on mitta \koodi{m}}
+ \midrule
+ \rivi{|}{sarakkeiden välissä pystyviiva}
+ \rivi{@\{…\}}{sarakkeiden välissä olevaa tekstiä tai komentoja}
+ \rivi{*\{n\}\{s\}}{toistetaan \koodi{n} kertaa sarakkeet \koodi{s}}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Taulukoiden saraketyyppien ja sarakkeiden välien määrittely}
+ \label{tlk/taulukko-sarakemerkit}
+}
+
+Ensimmäinen pakollinen argumentti \koodi{sarakkeet} määrittelee
+taulukon sarakkeiden määrän ja tyypin. Ne ilmaistaan tietyillä
+kirjaimilla tai muilla merkeillä, jotka on koottu taulukkoon
+\ref{tlk/taulukko-sarakemerkit}. Taulukon neljä ensimmäistä tyyppiä
+\koodi{lcrp} määrittelevät, millaisesta sarakkeesta on kyse. Syntyvässä
+taulukossa tulee olemaan niin monta saraketta kuin näitä on ympäristön
+\koodi{sarakkeet}\-/ argumentissa. Kolme ensin mainittua luovat
+sarakkeen, jonka leveys määräytyy sarakkeen leveimmän solun perusteella.
+Neljäs eli saraketyyppi \koodi{p} tarvitsee aaltosulkeissa argumentiksi
+mitan (luku \ref{luku/mitat}), ja sillä ilmaistaan sarakkeen kiinteä
+leveys. Tässä saraketyypissä teksti tasataan solun molemmista reunoista
+eli sanavälit voivat venyä.
+
+Merkit \koodi{|} ja \koodi{@} voi sijoittaa edellä mainittujen
+saraketyyppien väliin tai ennen ensimmäistä saraketta tai viimeisen
+sarakkeen jälkeen. Ensin mainittu tekee sarakkeiden väliin pystyviivan.
+Viiva yltää taulukon kaikille riveille, mutta komennolla
+\komento{multicolumn} voi tehdä rivikohtaisia poikkeuksia. Tätä komentoa
+käsitellään myöhemmin. Merkki \koodi{@} tarvitsee argumentin
+aaltosulkeissa. Se voi olla mitä hyvänsä tekstiä tai komentoja, jotka
+halutaan suorittaa joka rivillä sarakkeiden välissä.
+
+Sarakemerkki \koodi{*} on vain keino toistaa tiettyjä sarakemäärityksiä
+useamman kerran. Se tarvitsee aaltosulkeissa kaksi argumenttia:
+ensimmäinen on luku, ja toinen sisältää mitä hyvänsä edellä mainittuja
+saraketyyppejä. Nämä sarakkeet toistuvat luvun ilmaiseman määrän.
+Esimerkiksi \koodi{*\{3\}\{rl|\}} tarkoittaa samaa kuin
+\koodi{rl|rl|rl|}.
+
+\begin{esimerkki*}
+ \komentoi{\keno}
+ \komentoi{arraystretch}
+ \komentoi{cline}
+ \komentoi{hline}
+ \komentoi{hspace}
+ \komentoi{renewcommand}
+ \ymparistoi{tabular}
+
+\begin{koodilohko}
+\begin{tabular}{|l@{\hspace{4em}}r|c|}
+ \hline
+ Vasen & Oikea & Keskitetty \\[.5ex]
+ \hline
+ 16 & 32 & 11732 \\
+ \cline{1-2}
+ 71 & 87235 & 2 \\
+ \cline{3-3}
+ 1235 & 238 & 982 \\
+ \hline
+\end{tabular}
+\end{koodilohko}
+
+ \begin{tulos}
+ \versaalinum
+ \renewcommand{\arraystretch}{1.3}
+ \begin{tabular}{|l@{\hspace{4em}}r|c|}
+ \hline
+ Vasen & Oikea & Keskitetty \\[.5ex]
+ \hline
+ 16 & 32 & 11732 \\
+ \cline{1-2}
+ 71 & 87235 & 2 \\
+ \cline{3-3}
+ 1235 & 238 & 982 \\
+ \hline
+ \end{tabular}
+ \end{tulos}
+
+ \caption{Taulukoiden erilaisia saraketyyppejä ja viivoja}
+ \label{esim/taulukkomäärityksiä}
+\end{esimerkki*}
+
+Esimerkki \ref{esim/taulukkomäärityksiä} havainnollistaa taulukon
+ominaisuuksia ja eri saraketyyppejä. Sitä tuskin kannattaa pitää
+typografisena esimerkkinä, mutta tarkoituksena on osoittaa eri
+saraketyyppien toiminta käytännössä. Sarakkeiden välissä on yleensä
+pystyviiva, mutta yhdessä välissä on \koodi{@\{\dots\}}\=/ merkeillä
+määritelty komento \komento{hspace}, jolla tehdään poikkeuksellisen
+leveä (4\,em) tyhjä tila sarakkeiden väliin.
+
+Rivillä olevat peräkkäiset solut erotetaan toisistaan \koodi{\&}\=/
+merkillä, ja taulukon rivi täytyy päättää aina \komento{\keno}\=/
+komentoon. Tälle rivinvaihtokomennolle voi antaa hakasulkeissa yhden
+argumentin. Se on mitta ja tarkoittaa, kuinka paljon ylimääräistä
+pystysuuntaista tyhjää tilaa halutaan rivin jälkeen, esimerkiksi
+\komento{\keno}\komentoargv{.5ex}.
+
+Vaakasuuntainen, koko taulukon levyinen viiva tehdään komennolla
+\komento{hline} ja määrämittaisia viivoja komennolla \komento{cline}.
+Tälle komennolle täytyy antaa yksi argumentti, joka sisältää kaksi
+yhdysmerkillä erotettua lukua. Luvuilla ilmaistaan, mistä sarakkeesta
+mihin sarakkeeseen viiva yltää.
+
+\subsection{Asetuksia}
+
+Taulukon rivit saatetaan latoa oletuksena vähän liian lähelle toisiaan
+-- varsinkin jos käytetään vaakaviivoja. Sen korjaamiseksi on
+taulukoille olemassa oma rivivälikerroin, joka on komennossa
+\komentom{arraystretch}. Kerroin on desimaaliluku, jolla normaali
+rivikorkeus kerrotaan taulukoiden sisällä. Sopiva kerroin lienee yleensä
+1\==1,3. Oletusarvo on~1. Kerroinkomennon voi määritellä milloin hyvänsä
+uudelleen, ja se tehdään seuraavan esimerkin mukaisesti:
+
+\komentoi{renewcommand}
+\komentoi{arraystretch}
+\begin{koodilohkosis}
+\renewcommand{\arraystretch}{1.3}
+\end{koodilohkosis}
+
+\noindent
+Sarakkeiden määrittelyssä voi kirjoittaa useita pystyviivoja eli
+\koodi{|}\=/ merkkejä peräkkäin. Silloin pystyviivoja ladotaan
+taulukkoon useita vierekkäin. Viivojen väliseen etäisyyteen voi
+vaikuttaa mitan \mittam{doublerulesep} avulla. Sen oletusarvo on 2\,pt.
+Kaikkien viivoja paksuus puolestaan on mitassa \mittam{arrayrulewidth},
+jonka oletusarvo on 0,4\,pt.
+
+Jos sarakkeiden välissä ei ole \koodi{@}\=/ merkillä tehtyjä
+poikkeuksia, ladotaan joka solun vasempaan ja oikeaan reunaan väli, joka
+on määritelty mitassa \mittam{tabcolsep}. Tämän mitan suuruinen väli
+siis ladotaan kerran taulukon vasempaan ja oikeaan reunaan ja kaksi
+kertaa jokaisen sarakkeen väliin. Oletusarvo on 6\,pt. Seuraavassa on
+koonti edellä mainittujen mittojen asettamisesta ja niiden oletusarvot.
+
+\komentoi{setlength}
+\mittai{doublerulesep}
+\mittai{arrayrulewidth}
+\mittai{tabcolsep}
+\begin{koodilohkosis}
+\setlength{\doublerulesep}{2pt}
+\setlength{\arrayrulewidth}{.4pt}
+\setlength{\tabcolsep}{6pt}
+\end{koodilohkosis}
+
+\noindent
+Sarakemääritelmässä voi \koodi{@}\=/ merkillä säätää sarakkeiden välit
+täysin haluamansa laiseksi. Esimerkiksi merkeillä \koodi{@\{\}}
+sarakeväli poistetaan kokonaan. Jos \koodi{@\{\dots\}}\=/ määrittelyyn
+halutaan mukaan normaali sarakkeiden pystyviiva, täytyy käyttää komentoa
+\komento{vline}, esimerkiksi seuraavasti:
+
+\komentoi{\keno}
+\komentoi{hspace}
+\komentoi{vline}
+\ymparistoi{tabular}
+\begin{koodilohkosis}
+\begin{tabular}{|l@{\hspace{1em}\vline\hspace{1em}}l|}
+ ensimmäinen & toinen \\
+\end{tabular}
+\end{koodilohkosis}
+
+\subsection{Poikkeuksellisia sarakkeita ja rivejä}
+
+Taulukkoympäristön argumenteissa määritellään taulukon sarakkeiden määrä
+tyypit, mutta siihen on mahdollista tehdä yksittäisiä poikkeuksia
+taulukon sisällä. Sarakekohtaiset poikkeukset tehdään komennolla
+\komentom{multicolumn} ja rivikohtaiset poikkeukset komennolla
+\komentom{multirow}, joka kuuluu pakettiin \pakettictan{multirow}.
+
+\begin{esimerkki*}
+ \komentoi{\keno}
+ \komentoi{multicolumn}
+ \ymparistoi{tabular}
+
+\begin{koodilohko}
+\begin{tabular}{|r@{}l|}
+ \multicolumn{2}{l}{Tulokset} \\
+ \hline
+ 425 & ,34 \\
+ 4 & ,021 \\
+ 32 & \\
+ 0 & ,75 \\
+ \hline
+\end{tabular}
+\end{koodilohko}
+
+ \begin{tulos}
+ \renewcommand{\arraystretch}{1.2}
+ \versaalinum
+ \begin{tabular}{|r@{}l|}
+ \multicolumn{2}{l}{Tulokset} \\
+ \hline
+ 425 & ,34 \\
+ 4 & ,021 \\
+ 32 & \\
+ 0 & ,75 \\
+ \hline
+ \end{tabular}
+ \end{tulos}
+
+ \caption{Desimaalilukujen tasaaminen pilkun kohdalta, ja
+ poikkeuksellisten sarakkeiden tekeminen \komento{multicolumn}\-/
+ komennolla}
+ \label{esim/taulukko-desimaalipilkku}
+\end{esimerkki*}
+
+Esimerkissä \ref{esim/taulukko-desimaalipilkku} on taulukoitu lukuja,
+jotka halutaan latoa samaan linjaan desimaalipilkun kohdalta.
+Tasaamisessa hyödynnetään kahden sarakkeen rajakohtaa: luvun
+kokonaislukuosa ja desimaaliosa tasataan tätä rajakohtaa vasten --
+toinen oikealle~(\koodi{r}), toinen vasemmalle~(\koodi{l}). Sarakeväli
+on poistettu tästä kohdasta kokonaan \koodi{@\{\}}\=/ merkeillä.
+
+Esimerkkitaulukon otsikko ''Tulokset'' halutaan kuitenkin sijoittaa
+desimaalilukujen koko leveydelle eli kahden sarakkeen päälle. Lisäksi
+otsikkoriviltä halutaan poistaa pystyviivat, jotka muutoin ladotaan
+taulukon reunoille. Näihin asioihin tarvitaan komentoa
+\komento{multicolumn}, joka on tarkoitettu poikkeuksellisten
+sarakemääritysten tekemiseen. Komentoa käytetään seuraavasti:
+
+\komentoi{multicolumn}
+\begin{koodilohkosis}
+\multicolumn{n}{sarakkeet}{teksti}
+\end{koodilohkosis}
+
+\noindent
+Komennon \komento{multicolumn} voi sijoittaa mihin hyvänsä taulukon
+soluun. Komennon ensimmäinen argumentti \koodi{n} on luku ja ilmaisee,
+kuinka monen sarakkeen alueeseen vaikutetaan. Toinen argumentti
+\koodi{sarak\-keet} sisältää uuden sarakemäärittelyn tälle alueelle, ja
+se tehdään taulukon \ref{tlk/taulukko-sarakemerkit} merkkien avulla.
+Kolmas argumentti on teksti, joka ladotaan tähän uudella tavalla
+määriteltyyn alueeseen.
+
+Edellä on käsitelty vain soluja, joissa on yksirivinen teksti, mutta
+tietyissä tilanteissa yhteen soluun voidaan latoa useampia rivejä.
+Saraketyyppi~\koodi{p} (taulukko \ref{tlk/taulukko-sarakemerkit}) on
+leveydeltään kiinteä, ja jos solun sisältö ei mahdu kyseiseen tilaan, se
+pyritään jakamaan useammalle riville. Sanoja mahdollisesti katkaistaan
+tavurajojen kohdalta. Myös \komentom{newline}\-/ komennolla voi vaihtaa
+riviä yksittäisen solun sisällä. Sekin toimii vain kiinteäleveyksisillä
+\koodi{p}\-/ tyypin sarakkeilla.
+
+Seuraavassa on esimerkki, kuinka yhden solun sisältö voi jakautua
+kahdelle riville. Teknisessä mielessä taulukkorivien määrä ei kuitenkaan
+kasva, vaan muihin saman taulukkorivin soluihin tulee tyhjää tilaa.
+
+\komentoi{\keno}
+\komentoi{hline}
+\ymparistoi{tabular}
+\begin{koodilohkosis}
+\begin{tabular}{|l|p{6.5em}|l|}
+ \hline solu & Tämä ei mahdu yhdelle riville. & solu \\ \hline
+\end{tabular}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \renewcommand{\arraystretch}{1.2}
+ \begin{tabular}{|l|p{6.5em}|l|}
+ \hline solu & Tämä ei mahdu yhdelle riville. & solu \\ \hline
+ \end{tabular}
+\end{tulossis}
+
+\noindent
+Joskus puolestaan halutaan, että yksi solu levittäytyy useamman rivin
+alueelle verrattuna taulukon muihin riveihin. Tämän toteutukseen
+tarvitaan \pakettim{multirow}\-/ pakettia ja sen \komentom{multirow}\-/
+komentoa. Komennon pakolliset argumentit ovat seuraavat:
+
+\komentoi{multirow}
+\begin{koodilohkosis}
+\multirow{n}{leveys}{teksti}
+\end{koodilohkosis}
+
+\noindent
+Ensimmäinen argumentti \koodi{n} on luku, joka ilmaisee, kuinka monen
+rivin alueelle solu levitetään. Toinen argumentti \koodi{leveys} on
+tekstin leveyttä ilmaiseva mitta. Argumentiksi voi kirjoittaa pelkän
+tähden (\koodi{*}), jolloin käytetään tekstin luonnollista leveyttä.
+Kolmas argumentti on teksti, joka ladotaan tähän pystysuunnassa
+laajennettuun soluun.
+
+Komennolla on myös valinnaisia argumentteja, jotka ilmaistaan
+hakasulkeiden avulla. Tässä niistä tärkeimmät:
+
+\komentoi{multirow}
+\begin{koodilohkosis}
+\multirow[sijainti]{n}{leveys}[pysty]{teksti}
+\end{koodilohkosis}
+
+\noindent
+Edellisen esimerkin valinnainen argumentti \koodi{sijainti} on kirjain,
+jolla ilmaistaan solun sisällön pystysuuntainen asemointi ylös, keskelle
+tai alas: \koodi{t} (\englanti{top}), \koodi{c} (\englanti{center},
+oletus) tai \koodi{b} (\englanti{bottom}). Valinnainen argumentti
+\koodi{pysty} on mitta, jolla hienosäädetään solun sisällön sijaintia
+pystysuunnassa. Positiivinen mitta siirtää sisältöä ylöspäin,
+negatiivinen alaspäin.
+
+Komennon muista mahdollisuuksista kannattaa lukea \paketti{multirow}\-/
+paketin ohjekirjasta. Esimerkki \ref{esim/taulukko-multirow}
+havainnollistaa komennon peruskäyttöä. \komento{multirow}\-/ komento
+kirjoitetaan siihen soluun, josta monirivinen solu alkaa. Sen
+alapuolelta täytyy jättää riittävä määrä soluja tyhjäksi.
+
+\begin{esimerkki*}
+ \komentoi{\keno}
+ \komentoi{cline}
+ \komentoi{hline}
+ \komentoi{multirow}
+ \ymparistoi{tabular}
+
+\begin{koodilohko}
+\begin{tabular}{|l|l|l|}
+ \hline
+ \multirow{2}{*}{kaksirivinen solu} & tavallisia & soluja \\
+ \cline{2-3}
+ & kahdella & rivillä \\
+ \hline
+\end{tabular}
+\end{koodilohko}
+
+ \begin{tulos}
+ \renewcommand{\arraystretch}{1.3}
+ \begin{tabular}{|l|l|l|}
+ \hline
+ \multirow{2}{*}[-1bp]{kaksirivinen solu} & tavallisia & soluja \\
+ \cline{2-3}
+ & kahdella & rivillä \\
+ \hline
+ \end{tabular}
+ \end{tulos}
+
+ \caption{\paketti{multirow}\-/ paketin \komento{multirow}\-/
+ komennolla voi levittää yhden solun useamman rivin alueelle}
+ \label{esim/taulukko-multirow}
+\end{esimerkki*}
+
+\subsection{Kiinteälevyiset taulukot}
+
+Latexin toinen taulukkoympäristö \ymparistom{tabular*} toimii muuten
+samalla tavalla kuin \ymparisto{tabular}, mutta se tarvitsee yhden
+argumentin lisää, taulukon leveysmitan:
+
+\ymparistoi{tabular*}
+\begin{koodilohkosis}
+\begin{tabular*}{leveys}[sijainti]{sarakkeet}
+ ...
+\end{tabular*}
+\end{koodilohkosis}
+
+\noindent
+Valitettavasti taulukon leveysmittaa voi hyödyntää vain rajallisesti. Se
+vaikuttaa taulukon leveyteen silloin, kun sarakkeiden välit on
+määritelty venyviksi käyttämällä seuraavaa sarakevälin määritystä:
+
+\komentoi{extracolsep}
+\mittai{fill}
+\begin{koodilohkosis}
+@{\extracolsep{\fill}}
+\end{koodilohkosis}
+
+\noindent
+Edellisestä on tärkeää huomata, että sarakkeiden leveydet eivät veny
+vaan ainoastaan niiden välissä oleva tyhjä tila. Usein olisi kuitenkin
+hyödyllisempää, että joidenkin sarakkeiden leveys olisi venyvä ja ne
+mukautuisivat koko taulukon leveyteen. Tämä ominaisuus saadaan
+\pakettictan{tabularx}\-/ paketin avulla. Se määrittelee uuden
+taulukkoympäristön \ymparistom{tabularx}, joka on käytännössä parempi
+versio \ymparisto{tabular*}\-/ ympäristöstä. Sen käyttö on samanlaista:
+
+\ymparistoi{tabularx}
+\begin{koodilohkosis}
+\begin{tabularx}{leveys}[sijainti]{sarakkeet}
+ ...
+\end{tabularx}
+\end{koodilohkosis}
+
+\noindent
+Ympäristö \ymparisto{tabularx} sisältää yhden uuden
+saraketyypin:~\koodi{X} (vrt. taulukko
+\ref{tlk/taulukko-sarakemerkit}). Tämä saraketyyppi toimii kuten
+tyyppi~\koodi{p}, mutta sille ei anneta argumentiksi mittaa, vaan sen
+leveys on äärettömästi venyvä. Tämäntyyppiset sarakkeet täyttävät siis
+kaiken vapaana olevan tilan, ja jos niitä on useita, ne ovat oletuksena
+keskenään yhtä leveitä. Tämä ilmenee seuraavasta esimerkistä:
+
+\komentoi{hline}
+\mittai{linewidth}
+\ymparistoi{tabularx}
+\begin{koodilohkosis}
+\begin{tabularx}{\linewidth}{|l|X|X|}
+ \hline luonnollinen & venyvä & venyvä \\ \hline
+\end{tabularx}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \renewcommand{\arraystretch}{1.2}
+ \begin{tabularx}{\linewidth}{|l|X|X|}
+ \hline luonnollinen & venyvä & venyvä \\ \hline
+ \end{tabularx}
+\end{tulossis}
+
+\noindent
+Saraketyypissä \koodi{X} teksti tasataan oletuksena solujen
+molemmista reunoista, mutta siihen on mahdollista vaikuttaa
+sijoittamalla sarakemäärittelyssä \koodi{>}\=/ merkki ja sen
+aaltosulkeissa olevat argumentit ennen \koodi{X}\=/ merkkiä.
+Argumentiksi kirjoitetaan sopivia asetuskomentoja. Seuraava
+sarakemäärittely tekee vasemmalle tasatun \koodi{X}\=/ sarakkeen:
+
+\komentoi{raggedright}
+\komentoi{arraybackslash}
+\begin{koodilohkosis}
+>{\raggedright\arraybackslash}X
+\end{koodilohkosis}
+
+\noindent
+Sarakkeen solujen tasaaminen vasemmalle tulee komennon
+\komento{raggedright} vaikutuksesta (luku \ref{luku/kappaleen-tasaus}).
+Sen perään tarvitaan myös komento \komento{arraybackslash}, koska
+\komento{raggedright} määrittelee \komento{\keno}\=/ rivinvaihtokomennon
+uudelleen tavalla, joka on ristiriidassa taulukon rivien lopussa
+tarvittavan vastaavan komennon kanssa. \komento{arraybackslash}
+palauttaa määritelmän sellaiseksi, että se toimii taulukossa.
+
+\paketti{tabularx}\-/ paketin myötä voi määritellä omiakin
+saraketyyppejä. Hyödyllisiä tyyppejä voisivat olla esimerkiksi
+\koodi{LCR}, jotka toimisivat lähes samoin kuin perus Latexin
+saraketyypit \koodi{lcr} (taulukko \ref{tlk/taulukko-sarakemerkit})
+mutta olisivat kuitenkin leveydeltään venyviä. Omia saraketyyppejä
+tehdään komennolla \komentom{newcolumntype}, ja edellä mainitut tyypit
+voisi määritellä seuraavasti:
+
+\komentoi{arraybackslash}
+\komentoi{centering}
+\komentoi{newcolumntype}
+\komentoi{raggedleft}
+\komentoi{raggedright}
+\begin{koodilohkosis}
+\newcolumntype{L}{>{\raggedright\arraybackslash}X}
+\newcolumntype{C}{>{\centering\arraybackslash}X}
+\newcolumntype{R}{>{\raggedleft\arraybackslash}X}
+\end{koodilohkosis}
+
+\noindent
+Mitä hyvänsä saraketyyppejä voi tehdä vastaavalla tavalla. Esimerkiksi
+taulukon ensimmäiseen, otsikoita ilmaisevaan saraketyyppiin \koodi{O}
+voitaisiin laittaa fonttikomento, jotta koko sarake ladotaan
+automaattisesti eri kirjainleikkauksella kuin muu taulukko.
+
+\komentoi{newcolumntype}
+\komentoi{bfseries}
+\begin{koodilohkosis}
+\newcolumntype{O}{>{\bfseries}l} % lihavoitu otsikkosarake
+\end{koodilohkosis}
+
+\noindent
+Ympäristön \ymparisto{tabularx} käyttöön liittyy tiettyjä rajoituksia:
+sitä ei voi käyttää normaalisti omien ympäristöjen määrittelyssä (luku
+\ref{luku/ympäristöt}). Esimerkiksi seuraava ympäristön määrittely ei
+käytännössä toimi:
+
+\komentoi{newenvironment}
+\ymparistoi{tabularx}
+\mittai{linewidth}
+\begin{koodilohkosis}
+\newenvironment{omataulukko}[1]
+{\begin{tabularx}{\linewidth}{#1}}
+{\end{tabularx}}
+\end{koodilohkosis}
+
+\noindent
+Edellä mainitun puutteen saa korjattua käyttämällä oman ympäristön
+määrittelyssä \ymparisto{tabularx}\-/ ympäristön aloitukseen komentoa
+\komentom{tabularx} ja lopetukseen komentoa \komentom{endtabularx}. Ei
+siis käytetä normaaleja aloitus\-/\ ja lopetuskomentoja \komento{begin}
+ja \komento{end}.
+
+\komentoi{newenvironment}
+\komentoi{tabularx}
+\komentoi{endtabularx}
+\mittai{linewidth}
+\begin{koodilohkosis}
+\newenvironment{omataulukko}[1]
+{\tabularx{\linewidth}{#1}}
+{\endtabularx}
+\end{koodilohkosis}
+
+\subsection{Muita paketteja}
+
+\paketti{tabularx}\-/ paketin kanssa samankaltainen on paketti
+\pakettictan{tabulary}, jossa on joitakin erilaisia ominaisuuksia. Se
+muun muassa sisältää valmiiksi uudet saraketyypit \koodi{LCRJ}.
+
+Edellä esitellyt taulukkoympäristöt ladotaan aina kokonaisena eli vain
+yhden sivun alueelle. Useammalle sivulle jakautuvia taulukoita voi tehdä
+\pakettictan{longtable}\-/ paketin taulukkoympäristön
+\ymparistom{longtable} avulla. Sitä voi käyttää kuten
+\ymparisto{tabular}\-/ ympäristöä, mutta lisäksi se sisältää komentoja,
+joiden avulla saa joka sivulla toistumaan automaattisesti tietyt
+otsikkorivit tai yhteenvetorivit. Toinen mahdollisuus yli sivurajan
+yltävien taulukon kaltaisten rakenteiden tekemiseen ovat sarkaimet,
+joita käsitellään luvussa \ref{luku/sarkaimet}.
+
+Hyödyllinen taulukoiden apupaketti on \pakettictan{booktabs}, jonka
+avulla saa tyylikkäämpiä ja erilaisia vaakaviivoja. Paketin komennot
+\komento{toprule}, \komento{midrule}, \komento{bottomrule} ja
+\komento{cmidrule} piirtävät rivien väliin erilaisia viivoja ja
+huolehtivat myös niiden ylä- ja alapuolisesta välistä paremmin kuin
+Latexin omat viivakomennot.
+
+Taulukon rivien taustan voi värittää \pakettictan{xcolor}\-/ paketin
+(luku \ref{luku/korostus-värit}) komentojen avulla. Varsinkin leveiden
+taulukoiden lukemista voi helpottaa, jos rivien eri taustavärit
+vuorottelevat. Tarkemmat tiedot selviävät paketin ohjekirjasta, mutta
+seuraavan esimerkin avulla ominaisuutta pääsee kokeilemaan:
+
+\komentoi{rowcolors}
+\komentoi{usepackage}
+\pakettii{xcolor}
+\begin{koodilohkosis}
+\usepackage[table]{xcolor} % lähdedokumentin esittelyosaan
+\rowcolors{1}{blue!10}{red!10} % ennen taulukkoympäristöjä
+\end{koodilohkosis}
+
+\section{Sarkaimet}
+\label{luku/sarkaimet}
+
+Sarkaimet ovat ennalta määritettyjä vaakasuuntaisia sisennys\-/\ tai
+tasauskohtia. Niitä voi hyödyntää tekstin tasaamisessa tiettyihin
+kohtiin rivillä. Suomenkielisissä asiakirjoissa sarkainkohdat ovat 23
+millimetrin välein, mutta jos ei ole kirjoittamassa virallista
+asiakirjaa, voi kirjoittaja määrittää sarkainkohdat niin kuin haluaa.
+
+Ajatus sarkaimista on vanha, sillä mekaanisissa kirjoituskoneissakin oli
+sarkainnäppäin (\englanti{tab, tabular}), joka siirsi telaa eteenpäin
+seuraavaan sarkainkohtaan. Se helpotti tekstirivien tasaamista tiettyyn
+kohtaan ja sen myötä taulukoiden kirjoittamista.
+
+Latexissa on taulukoita varten omatkin ympäristönsä (luku
+\ref{luku/taulukot}), mutta jos ei tarvitse varsinaista taulukkoa vaan
+ainoastaan yksittäisiä tasauskohtia, voi olla kätevämpää käyttää
+\ymparisto{tabbing}\-/ sarkainympäristöä tai rakentaa sisennykset
+näkymättömien laatikoiden avulla. Näitä käsitellään seuraavissa
+alaluvuissa.
+
+\subsection{Sarkainympäristö}
+
+Sarkaimet voi toteuttaa niitä varten tehdyn ympäristön eli
+\ymparisto{tabbing}\-/ ympäristön avulla. Esimerkki
+\ref{esim/tabbing-perus} havainnollistaa ympäristön peruskäyttöä.
+Rivillä~2 asetetaan kaikki sarkainkohdat eli tehdään vaakasuuntaisia
+välejä \komento{hspace}\-/ komennolla ja merkitään sarkainkohdat
+\komento{=}\=/ komennoilla. Tämän rivin lopussa on komento
+\komento{kill}, joka hylkää rivin eli jättää sen latomatta. Seuraavien
+rivien lopussa on aina \komento{\keno}\-/ komento -- paitsi viimeisellä
+rivillä ennen ympäristön lopetuskomentoa. Rivin sisällä seuraavaan
+sarkainkohtaan hypätään \komento{>}\-/ komennolla.
+
+\begin{esimerkki*}
+ \ymparistoi{tabbing}
+ \komentoi{hspace}
+ \komentoi{kill}
+ \komentoi{=}
+ \komentoi{>}
+
+\begin{koodilohko}
+\begin{tabbing}
+ \hspace{23mm} \= \hspace{23mm} \= \hspace{23mm} \= \kill
+ Tässä \> on \\
+ \> eri \> tavoin \\
+ \>\> sisennettyä \\
+ \>\>\> tekstiä.
+\end{tabbing}
+\end{koodilohko}
+
+ \begin{tulos}
+ \begin{tabbing}
+ \hspace{23mm} \= \hspace{23mm} \= \hspace{23mm} \= \kill
+ Tässä \> on \\
+ \> eri \> tavoin \\
+ \>\> sisennettyä \\
+ \>\>\> tekstiä.
+ \end{tabbing}
+ \end{tulos}
+ \caption{Sarkainkohtien määrittely ja käyttö \ymparisto{tabbing}\-/
+ ympäristössä}
+ \label{esim/tabbing-perus}
+\end{esimerkki*}
+
+\ymparisto{tabbing}\-/ ympäristön sisällä on käytettävissä muutama
+muukin erikoiskomento, joilla vaikutetaan sarkainten käsittelyyn.
+Seuraavassa kerrotaan ympäristön kaikkien erityiskomentojen merkitys, ja
+esimerkissä \ref{esim/tabbing-erikois} havainnollistetaan joidenkin
+komentojen käyttöä.
+
+\begin{maaritelma}{\komento{#1}}
+\item [\keno] Rivinvaihto, joka täytyy kirjoittaa jokaisen rivin
+ loppuun, lukuun ottamatta viimeistä riviä ennen ympäristön
+ lopetuskomentoa (\komento{end}).
+\item [kill] Rivinvaihto, joka hylkää kyseisen rivin. Tämä on
+ käyttökelpoinen sarkainkohtien määrittelyrivillä, jota itsessään ei
+ ehkä haluta latoa näkyviin.
+\item [=] Sarkainkohdan määrittäminen komennon kohdalle.
+\item [>] Hyppää seuraavaan sarkainkohtaan nykyisellä rivillä.
+\item [+] Siirtää seuraavan rivin aloituskohtaa yhden sarkaimen verran
+ oikealle siitä, missä se oli ennestään.
+\item [-] Siirtää seuraavan rivin aloituskohtaa yhden sarkaimen verran
+ vasemmalle siitä, missä se oli ennestään.
+\item [<] Siirtää nykyisen rivin aloituskohdan yhden sarkaimen verran
+ vasemmalla. Tätä komentoa voi käyttää vain rivin alussa ja vain
+ silloin, kun rivin aloituskohtaa on sisennetty aiemmin \komento{+}\-/
+ komennolla. Tämä komento ei muuta pysyvästi rivin aloituskohdan
+ asetusta, joka on tehty komennolla \komento{+} tai \komento{-}.
+\item ['] Latoo komentoa edeltävän tekstin nykyisen sarkainkohdan
+ vasemmalle puolelle ja tasaa tekstin oikeasta reunasta. Tekstin oikean
+ reunan ja sarkainkohdan väliin tulee mitan \mitta{tabbingsep}
+ suuruinen väli.
+\item [`] Tasaa komennon jälkeisen tekstin sivun oikeaan reunaan.
+\item [pushtabs] Tallentaa nykyiset sarkainkohdat muistiin. Tämän
+ jälkeen sarkainasetuksia voi muuttaa ja alkuperäiset asetukset
+ palauttaa \komento{poptabs}\-/ komennolla.
+\item [poptabs] Palauttaa aiemmin \komento{pushtabs}\-/ komennolla
+ tallennetut sarkainkohdat käyttöön.
+\item [a'] Latoo akuuttiaksentin (\'a) seuraavaan kirjaimeen. Vastaa
+ \komento{'}\-/ komentoa \ymparisto{tabbing}\-/ ympäristön ulkopuolella
+ (taulukko \ref{tlk/tarkkeet}, s.~\pageref{tlk/tarkkeet}).
+\item [a`] Latoo gravisaksentin (\`a) seuraavaan kirjaimeen. Vastaa
+ \komento{`}\-/ komentoa \ymparisto{tabbing}\-/ ympäristön
+ ulkopuolella.
+\item [a=] Latoo pituusmerkin (\=a) seuraavaan kirjaimeen. Vastaa
+ \komento{=}\-/ komentoa \ymparisto{tabbing}\-/ ympäristön
+ ulkopuolella.
+\end{maaritelma}
+
+\begin{esimerkki*}
+ \komentoi{'}
+ \komentoi{+}
+ \komentoi{-}
+ \komentoi{<}
+ \komentoi{=}
+ \komentoi{>}
+ \komentoi{`}
+ \komentoi{a'}
+ \komentoi{a`}
+ \komentoi{a=}
+ \komentoi{hspace}
+ \komentoi{kill}
+ \komentoi{setlength}
+ \mittai{tabbingsep}
+ \ymparistoi{tabbing}
+
+\begin{koodilohko}
+\setlength{\tabbingsep}{0mm}
+\begin{tabbing}
+ \hspace{23mm} \= \hspace{23mm} \= \hspace{23mm} \= \kill
+ tässäpä \> kaikki \> eri \> sarkainkohdat \+ \\
+ valmiiksi sisennetty \+ \\
+ vielä enemmän sisennetty \- \\
+ vähemmän sisennetty \>\> oikealle\' \\
+ \< poikkeuksellisesti sisennetty vähemmän \` täysin oikealla \\
+ paluu aiempaan sisennystasoon ja tarkkeita: \a'{a}\a`{a}\a={a}
+\end{tabbing}
+\end{koodilohko}
+
+ \begin{tulos}
+ \setlength{\tabbingsep}{0mm}
+ \begin{tabbing}
+ \hspace{23mm} \= \hspace{23mm} \= \hspace{23mm} \= \kill
+ tässäpä \> kaikki \> eri \> sarkainkohdat \+ \\
+ valmiiksi sisennetty \+ \\
+ vielä enemmän sisennetty \- \\
+ vähemmän sisennetty \>\> oikealle\' \\
+ \< poikkeuksellisesti sisennetty vähemmän \` täysin oikealla \\
+ paluu aiempaan sisennystasoon ja tarkkeita: \a'{a}\a`{a}\a={a}
+ \end{tabbing}
+ \end{tulos}
+
+ \caption{Erikoisempia sarkaintoimintoja \ymparisto{tabbing}\-/
+ ympäristössä}
+ \label{esim/tabbing-erikois}
+\end{esimerkki*}
+
+\subsection{Laatikkototeutus}
+
+Sarkainkohtia sisältävän rivin voi varsin helposti toteuttaa laatikoiden
+(luku \ref{luku/laatikot}) avulla. Varsinkin \komento{makebox}\-/
+komento soveltuu hyvin, koska laatikolla ei ole reunaviivoja ja laatikon
+leveyden ja sisällön tasauksen voi asettaa. Seuraavassa esimerkissä
+määritetään sarkainten leveysmitta \mittax{sarkainleveys} ja komento
+\komentox{sarkain}, jolla tekstiä voi kirjoittaa tietyn levyiseen
+laatikkoon.
+
+\komentoi{newlength}
+\komentoi{setlength}
+\komentoi{newcommand}
+\komentoi{makebox}
+\komentoi{ignorespaces}
+\begin{koodilohkosis}
+ \newlength{\sarkainleveys}
+ \setlength{\sarkainleveys}{23mm}
+ \newcommand{\sarkain}[3][l]{%
+ \makebox[#2\sarkainleveys][#1]{#3}\ignorespaces}
+\end{koodilohkosis}
+
+\noindent
+Näin määritelty \komentox{sarkain}\-/ komento tarvitsee ainakin kaksi
+argumenttia: ensimmäinen argumentti on kerroin, kuinka monen sarkaimen
+levyinen laatikko tehdään; toinen argumentti on teksti, joka ladotaan
+tähän laatikkoon. Ennen pakollisia argumentteja voi antaa myös
+valinnaisen argumentin hakasulkeissa: se on laatikon sisällön tasaus, ja
+oletus on vasempaan reunaan. Katso lisätietoa \komento{makebox}\-/
+komennon argumenteista luvusta \ref{luku/laatikot-pienet}. Esimerkki
+\ref{esim/sarkain-laatikot} havainnollistaa sarkainten toteuttamista
+laatikoiden avulla.
+
+\begin{esimerkki*}
+ \komentoi{newlength}
+ \komentoi{setlength}
+ \komentoi{newcommand}
+ \komentoi{makebox}
+ \komentoi{ignorespaces}
+ \komentoi{noindent}
+
+\begin{koodilohko}
+\newlength{\sarkainleveys}
+\setlength{\sarkainleveys}{23mm}
+\newcommand{\sarkain}[3][l]{%
+ \makebox[#2\sarkainleveys][#1]{#3}\ignorespaces}
+
+\noindent
+\sarkain{1}{ensin} \sarkain{1}{kaikki} \sarkain{1}{eri} sarkainkohdat \\
+\sarkain{1}{} sarkaimen verran sisennetty rivi \\
+\sarkain{2}{jotain tekstiä} \sarkain[r]{1}{oikealle} \\
+\sarkain{1}{} \sarkain[c]{2}{keskitetty}
+\end{koodilohko}
+
+ \begin{tulos}
+ \newlength{\sarkainleveys}
+ \setlength{\sarkainleveys}{23mm}
+ \newcommand{\sarkain}[3][l]{%
+ \makebox[#2\sarkainleveys][#1]{#3}\ignorespaces}
+
+ \noindent
+ \sarkain{1}{ensin} \sarkain{1}{kaikki} \sarkain{1}{eri} sarkainkohdat \\
+ \sarkain{1}{} sarkaimen verran sisennetty rivi \\
+ \sarkain{2}{jotain tekstiä} \sarkain[r]{1}{oikealle} \\
+ \sarkain{1}{} \sarkain[c]{2}{keskitetty}
+ \end{tulos}
+
+ \caption{Sarkainten toteutus laatikoiden avulla}
+ \label{esim/sarkain-laatikot}
+\end{esimerkki*}
+
+\section{Leijuvat osat}
+\label{luku/leijuosat}
+
+Leijuvat osat ovat sellaisia dokumentin osia -- käytännössä
+ympäristöjä~--, joita ei ladota normaalin leipätekstin sekaan tiettyyn
+kohtaan. Ne ''leijuvat'' irrallaan muusta tekstivirrasta, ja Latex
+huolehtii niiden sijoittelusta. Leijuvilla osilla on yleensä kuvateksti,
+jonka alussa on sen tyyppi ja numero, esimerkiksi ''\figurename~1'' tai
+''\tablename\ 4.2''. Näiden perässä on varsinainen kuvateksti, joka
+kertoo kyseisen leijuvan osan sisällöstä tai merkityksestä.
+Leipätekstistä usein viitataan leijuviin osiin käyttämällä ilmauksia
+kuten ''kuvassa~1''. Näissä hyödynnetään Latexin ristiviittaustoimintoja
+(luku \ref{luku/ristiviitteet}).
+
+Perus Latex sisältää kaksi erityyppistä leijuvaa osaa, kuvat ja taulukot
+(luku \ref{luku/leijuosat-latex}), mutta \pakettim{floatrow}\-/ paketin
+avulla niitä voi tehdä muitakin (luku \ref{luku/leijuosat-omat}).
+Esimerkiksi tässä oppaassa on käytössä myös tyyppi ''Esimerkki'', jota
+käytetään leijuvien Latex\-/ koodiesimerkkien toteuttamiseen.
+
+Koska Latex huolehtii leijuvien osien sijoittamisesta, niiden lopullinen
+järjestyskin voi hieman poiketa siitä, miten ne ovat Latex\-/
+lähdedokumentissa. Tosin samantyyppiset leijuvat osat, esimerkiksi
+kuvat, ladotaan aina siinä järjestyksessä kuin ne ovat
+lähdedokumentissa. Sen sijaan erityyppiset leijuvat osat saatetaan latoa
+eri järjestyksessä: esimerkiksi jokin taulukko saatetaan latoa ennen
+tiettyä kuvaa, vaikka ne olisivat lähdedokumentissa päinvastaisessa
+järjestyksessä. Latex pyrkii latomaan hyvännäköisiä sivuja, ja leijuvien
+osien sijoittelulla se voi vaikuttaa asiaan.
+
+\subsection{Leijuvat taulukot ja kuvat}
+\label{luku/leijuosat-latex}
+
+Käytännössä leijuvat osat ovat ympäristöjä, joiden sijoittelusta vastaa
+Latex eikä kirjoittaja. Tosin kirjoittajakin voi hieman vaikuttaa
+asiaan, ja tätä käsitellään luvussa \ref{luku/leijuosat-sijoittelu}.
+Ympäristö \ymparistom{table} on tarkoitettu taulukoille, ja ympäristö
+\ymparistom{figure} on kuville. Esimerkistä \ref{esim/leijuosat-perus}
+ilmenee leijuvan taulukon toteuttamisen perusasiat. Muuntyyppiset
+leijuvat osat tehdään samalla tavalla, ympäristö on vain eri.
+
+\begin{esimerkki*}
+ \komentoi{arraystretch}
+ \komentoi{caption}
+ \komentoi{hline}
+ \komentoi{renewcommand}
+ \ymparistoi{center}
+ \ymparistoi{table}
+ \ymparistoi{tabular}
+
+\begin{koodilohko}
+\begin{table}
+ \begin{center}
+ \renewcommand{\arraystretch}{1.3}
+ \begin{tabular}{ll}
+ Upeita & Lukuja \\
+ \hline
+ 324 & 33 \\
+ 2 & 49 \\
+ \hline
+ \end{tabular}
+ \end{center}
+ \caption{Upea kuvateksti.}
+\end{table}
+\end{koodilohko}
+
+ \caption{Leijuvan taulukon toteuttaminen \ymparisto{table}\-/
+ ympäristön avulla. Varsinainen taulukko syntyy ympäristön
+ \ymparisto{tabular} avulla}
+ \label{esim/leijuosat-perus}
+\end{esimerkki*}
+
+Latex sinänsä ei ota kantaa siihen, mitä leijuva ympäristö sisältää, eli
+\ymparisto{table}\-/ ympäristön sisällä ei tarvitse olla
+taulukkoympäristöä (luku \ref{luku/taulukot}), eikä
+\ymparisto{figure}\-/ ympäristön sisällä ole pakko olla kuvaa (luku
+\ref{luku/grafiikka}). Valitut ympäristöt vaikuttavat kuitenkin
+kuvatekstiin: \ymparisto{table}\-/ ympäristön kuvatekstiin tulee suomen
+kieliasetuksilla sana ''\tablename'', ja \ymparisto{figure}\-/
+ympäristössä se on ''\figurename''. Nimet tulevat komennoista
+\komento{tablename} ja \komento{figurename}, jotka kirjoittaja voi
+määrittää uudelleen. Se kannattaa tehdä dokumentin esittelyosassa
+seuraavalla tavalla:
+
+\komentoi{addto}
+\komentoi{captionsfinnish}
+\komentoi{figurename}
+\komentoi{tablename}
+\begin{koodilohkosis}
+\addto{\captionsfinnish}{
+ \renewcommand{\tablename}{Taulukko}
+ \renewcommand{\figurename}{Kuva}
+}
+\end{koodilohkosis}
+
+\noindent
+Edellä käytettiin \komento{addto}\-/ komentoa, joka kuuluu
+kielipaketteihin \paketti{polyglossia} ja \paketti{babel}. Sillä
+lisätään omia komentoja tietyn kielen asetuksiin, tässä suomen
+kieliasetuksiin (\komento{captionsfinnish}). Kieliasetuksia käsitellään
+tarkemmin luvussa \ref{luku/kieliasetukset}.
+
+Kuvatekstit tehdään komennolla \komentom{caption}, joka sijoitetaan
+leijuvan ympäristön sisälle, kuten esimerkissä
+\ref{esim/leijuosat-perus} on tehty. Komennolle annetaan yksi argumentti
+eli haluttu kuvateksti. Siihen ei pidä kirjoittaa leijuvan osan tyyppiä
+eikä numeroa (esim. ''\tablename~3''), sillä nämä Latex tekee
+automaattisesti. \komento{caption}\-/ komennolle voi antaa myös
+valinnaisen argumentin, jolla ilmaistaan kuvatekstistä lyhempi versio:
+
+\komentoi{caption}
+\begin{koodilohkosis}
+\caption[lyhyt kuvateksti]{varsinainen pitkä kuvateksti}
+\end{koodilohkosis}
+
+\noindent
+Varsinainen (pitkä) kuvateksti ladotaan aina leijuvan osan yhteyteen ja
+lyhempää versiota käytetään mahdollisesti luettelossa (luku
+\ref{luku/leijuosat-luettelot}) ja ristiviitteissä. Kuvatekstin eli
+\komento{caption}\-/ komennon jälkeen leijuvaan ympäristöön lisätään
+usein yksilöllinen tunniste ristiviittausta varten. Se tehdään
+\komento{label}\-/ komennolla, jota käsitellään ristiviitteiden
+yhteydessä luvussa \ref{luku/ristiviitteet}.
+
+Leijuvista ympäristöistä on olemassa myös tähdelliset versiot,
+\ymparistom{table*} ja \ymparistom{figure*}. Ympäristöjen eri versioilla
+on merkitystä vain kaksipalstaisessa tilassa (luku \ref{luku/palstat}),
+jossa normaaliversio (esim. \ymparisto{table}) ladotaan yhden palstan
+sisään ja tähdellinen versio (esim. \ymparisto{table*}) sijoitetaan
+palstojen ulkopuolelle, koko sivun tilaan.
+
+\subsection{Muut leijuvat osat}
+\label{luku/leijuosat-omat}
+
+Omia, itse nimettyjä leijuvia osia tehdään \pakettictan{floatrow}\-/
+paketin avustuksella. Se sisältää komennon on
+\komentom{DeclareNewFloatType}, jonka argumentit ovat seuraavanlaiset:
+
+\komentoi{DeclareNewFloatType}
+\begin{koodilohkosis}
+\DeclareNewFloatType{tyyppi}{valitsimet}
+\end{koodilohkosis}
+
+\noindent
+Komennon ensimmäinen argumentti \koodi{tyyppi} on leijuvan osan tyyppi
+ja käytännössä myös ympäristön nimi. Jos tyypiksi antaa sanan
+\koodi{esimerkki}, syntyy leijuvat ympäristöt \ymparistox{esimerkki} ja
+\ymparistox{esimerkki*}. Argumentin \koodi{valitsimet} avulla voi
+vaikuttaa tarkemmin leijuvan osan ominaisuuksiin. Mahdolliset valitsimet
+on koottu taulukkoon \ref{tlk/declarenewfloat}. Eri valitsimet erotetaan
+toisistaan pilkulla, eli komentoa käytetään esimerkin
+\ref{esim/declarenewfloat} tavoin.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\koodi{\englanti{#1}} & #2 \\}
+ \begin{tabular}{ll}
+ \toprule
+ \ots{Valitsin} & \ots{Merkitys} \\
+ \midrule
+ \rivi{name}{kuvateksteissä näkyvä tyyppi}
+ \rivi{placement}{sijoitteluasetukset}
+ \rivi{fileext}{väliaikaistiedoston pääte}
+ \rivi{within}{ylemmäntasoinen laskuri}
+ % \rivi{relatedcapstyle}{??}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{\komento{DeclareNewFloatType}\-/ komennon valitsimia, joilla
+ vaikutetaan leijuvan osan ominaisuuksiin. Komento kuuluu
+ \paketti{floatrow}\-/ pakettiin}
+ \label{tlk/declarenewfloat}
+}
+
+\begin{esimerkki*}
+\komentoi{DeclareNewFloatType}
+
+\begin{koodilohko}
+\DeclareNewFloatType{esimerkki}{
+ name=Esimerkki,
+ placement=tbp,
+ fileext=loesim,
+ within=chapter
+}
+\end{koodilohko}
+
+\caption{\komento{DeclareNewFloatType}\-/ komennon käyttö. Komento
+ kuuluu \paketti{floatrow}\-/ pakettiin}
+\label{esim/declarenewfloat}
+\end{esimerkki*}
+
+Valitsimen \koodi{name} arvo näkyy kuvateksteissä leijuvan osan
+tyyppinä. Valitsimella \koodi{placement} tehdään sijoitteluasetuksia,
+joita käsitellään luvussa \ref{luku/leijuosat-sijoittelu}. Käytännössä
+ne ovat tiettyjä kirjaimia, joilla vaikutetaan leijuvan osan
+sijoitteluun. Oletusarvo on \koodi{tbp}.
+
+Valitsin \koodi{file\-ext} on tiedoston pääte. Leijuvien osien
+luetteloita tehtäessä Latex käyttää väliaikaistiedostoa, ja sen päätteen
+voi valita tällä valitsimella. Luetteloissa on tapana käyttää
+tiedostopäätettä, joka alkaa kirjaimilla \koodi{lo} (\englanti{list
+ of}). Latexin omissa leijuvissa osissa päätteet ovat \koodi{lot}
+(\englanti{list of tables}) ja \koodi{lof} (\englanti{list of figures}).
+Oletuksena omille leijuville osille tulee päätteeksi \koodi{lo}, jonka
+perässä on osan tyyppi.
+
+Valitsimen \koodi{within} avulla vaikutetaan leijuvien osien numeroinnin
+riippuvuuteen muista laskureista. Oletuksena leijuvan osan laskuri ei
+ole riippuvainen muista laskureista eli osat numeroidaan dokumentin
+alusta saakka yhdellä luvulla. Arvoksi voi antaa myös Latexin laskurin
+nimen: mielekkäitä arvoja ovat esimerkiksi \laskuri{chapter} ja
+\laskuri{section}. Vaikutus on se, että leijuvan osan laskuri on
+riippuvainen näistä laskureista ja nollautuu aina, kun toisen laskurin
+arvo kasvaa. Lisäksi kuvateksteissä näkyy kaksiosainen numerointi (4.1,
+4.2, 4.3 jne.), jossa ensimmäinen luku on ylemmäntasoisen laskurin arvo
+-- esimerkiksi kirjan pääluvun numero -- ja toinen on leijuvan osan
+laskurin arvo. Tällaisia hierarkkisia laskureita käsitellään tarkemmin
+luvussa \ref{luku/hierarkkiset-laskurit}. Leijuvan osan numeroinnin
+ulkoasun muokkaamista käsitellään luvussa \ref{luku/leijuosat-ulkoasu}.
+
+\subsection{Leijuvien osien luettelot}
+\label{luku/leijuosat-luettelot}
+
+Dokumentin leijuvista osista voi latoa automaattisesti luetteloita:
+komennolla \komentom{listoftables} syntyy taulukkoluettelo ja komennolla
+\komentom{listoffigures} kuvaluettelo. Omien leijuvien osien (luku
+\ref{luku/leijuosat-omat}) luettelo tehdään \paketti{floatrow}\-/
+paketin komennolla \komento{listof}, jolle annetaan argumentiksi
+leijuvan osan tyyppi sekä luettelon otsikko.
+
+\komentoi{listoftables}
+\komentoi{listoffigures}
+\komentoi{listof}
+\begin{koodilohkosis}
+\listoftables % taulukkoluettelo (table)
+\listoffigures % kuvaluettelo (figure)
+\listof{esimerkki}{Esimerkit} % luettelo esimerkki-tyyppisistä osista
+\end{koodilohkosis}
+
+\noindent
+Leijuvien osien luettelot muistuttavat sisällysluetteloita (luku
+\ref{luku/sisällysluettelo}), eli niille tulee automaattisesti otsikko
+kuten ''\listtablename'' tai ''\listfigurename'' ja automaattisesti
+sisältö eli kaikki \komento{caption}\-/ komennolla ilmaistut (lyhyet)
+kuvatekstit sekä tietysti sivunumerot.
+
+\begin{esimerkki*}
+ \komentoi{addvspace}
+ \komentoi{contentslabel}
+ \komentoi{contentspage}
+ \komentoi{rmfamily}
+ \komentoi{small}
+ \komentoi{titlecontents}
+ \komentoi{titlerule*}
+
+\begin{koodilohko}
+\titlecontents{table} % tyyppi: table
+[8mm] % vasen sisennys (mitta)
+{\addvspace{3bp}\rmfamily\small} % yläpuolinen koodi
+{\contentslabel{8mm}} % numeroitu kohta
+{} % numeroimaton kohta
+{~\small\titlerule*[3mm]{.}\contentspage} % pisteviiva ja sivunumero
+[] % alapuolinen koodi
+\end{koodilohko}
+ \caption{Leijuvien osien ulkoasua muokataan \komento{titlecontents}\-/
+ komennolla, joka on peräisin \paketti{titletoc}\-/ paketista}
+ \label{esim/leijuosat-titlecontents}
+\end{esimerkki*}
+
+Leijuvien osien luettelojen ulkoasua voi muokata samalla tavalla kuin
+sisällysluetteloidenkin: käytetään pakettia \pakettictan{titletoc} ja
+määritellään sen \komento{titlecontents}\-/ komennolla luettelokohtien
+ulkoasu. Esimerkistä \ref{esim/leijuosat-titlecontents} selvinnee
+perusajatus, ja lisätietoa on sisällysluetteloita käsittelevässä luvussa
+\ref{luku/sisällysluettelo} sekä tietysti paketin ohjekirjassa.
+
+Latexin omien leijuvien osien luetteloiden otsikot tulevat
+kieliasetuksista ja komennoista \komento{listtablename} ja
+\komento{listfigurename}, jotka kirjoittaja voi määritellä uudestaan.
+Järkevää on tehdä se lähdedokumentin esittelyosassa ja käyttää
+\komento{addto}\-/ komentoa, jolla asetukset lisätään tietyn kielen
+asetuksiin.
+
+\komentoi{addto}
+\komentoi{captionsfinnish}
+\komentoi{listfigurename}
+\komentoi{listtablename}
+\begin{koodilohkosis}
+\addto{\captionsfinnish}{
+ \renewcommand{\listtablename}{Omat taulukot}
+ \renewcommand{\listfigurename}{Omat kuvat}
+}
+\end{koodilohkosis}
+
+\noindent
+Luetteloihin saa lisättyä omia rivejä samoilla keinoilla kuin
+sisällysluetteloihinkin eli komennolla \komento{addcontentsline}.
+Komennon ensimmäinen argumentti on luettelon tyyppiä vastaavan tiedoston
+pääte. Tyyppi \koodi{lot} (\englanti{list of tables}) on taulukoille ja
+tyyppi \koodi{lof} (\englanti{list of figures}) on kuville. Omilla
+leijuvilla osilla (luku \ref{luku/leijuosat-omat}) se on jotakin muuta
+ja valitaan osan määrittelyn yhteydessä.
+
+\komentoi{addcontentsline}
+\begin{koodilohkosis}
+\addcontentsline{lot}{table}{Ylimääräinen taulukko}
+\addcontentsline{lof}{figure}{Ylimääräinen kuva}
+\end{koodilohkosis}
+
+\noindent
+Komennon toinen argumentti tarkoittaa luettelomerkinnän tasoa (vrt.
+otsikkotasot). Leijuvien osien luetteloissa on vain yksi taso, ja siihen
+kirjoitetaan kyseisen leijuvan osan tyyppi eli ympäristön nimi,
+esimerkiksi \ymparisto{table} tai \ymparisto{figure}. Komennon kolmas
+argumentti on luetteloon lisättävä merkintä.
+
+\subsection{Sijoittelu sivulle}
+\label{luku/leijuosat-sijoittelu}
+
+Latex sijoittaa leijuvat osat yleensä sivun yläosaan, joskus alaosaan
+tai omalle sivulleen, jossa ei ole leipätekstiä lainkaan. Yksittäisen
+ympäristön sijoitteluun voi vaikuttaa valinnaisen argumentin avulla:
+
+\ymparistoi{figure}
+\begin{koodilohkosis}
+\begin{figure}[sijainti]
+ ...
+\end{figure}
+\end{koodilohkosis}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\koodi{#1} & #2 \\}
+ \begin{tabular}{cl}
+ \toprule
+ \ots{Valitsin} & \ots{Merkitys} \\
+ \midrule
+ \rivi{t}{sivun yläosaan (\englanti{top})}
+ \rivi{b}{sivun alaosaan (\englanti{bottom})}
+ \rivi{p}{leijuvien osien sivulle (\englanti{page})}
+ \rivi{h}{mieluiten tähän kohtaan (\englanti{here})}
+ \rivi{H}{ehdottomasti tähän kohtaan (\englanti{here},
+ \paketti{floatrow})}
+ \rivi{!}{ei huomioida tiettyjä sijoittelurajoituksia}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Leijuvien osien sijoitteluun voi vaikuttaa ympäristön
+ valinnaisen argumentin avulla. Valitsin \koodi{H} on
+ \paketti{floatrow}\-/ paketin ominaisuus}
+ \label{tlk/leijuosat-sijoittelukirjaimet}
+}
+
+\noindent
+Valinnainen argumentti \koodi{sijainti} on tietty merkki tai merkkien
+yhdistelmä, jolla vaikutetaan leijuvan osan sijoitteluun. Taulukossa
+\ref{tlk/leijuosat-sijoittelukirjaimet} ovat mahdolliset vaihtoehdot.
+Oletusarvo on \koodi{tbp}, eli sen mukaan leijuva osa pyritään
+sijoittamaan ensisijaisesti sivun yläosaan (\koodi{t}) mutta
+mahdollisesti myös alaosaan (\koodi{b}) tai omalle sivulleen (\koodi{p})
+muiden leijuvien osien kanssa.
+
+Vaihtoehto \koodi{h} pyrkii latomaan leijuvan osan siihen kohtaan kuin
+se on lähdetiedostossa. Se on kuitenkin vain ehdotus eikä useinkaan
+toteudu: Latex lisää automaattisesti aina \koodi{h}\=/ valitsimen perään
+\koodi{t}:n eli sivun yläosaan sijoittamisen. Latex käyttää sitä, jos se
+saa sillä tavoin omasta mielestään paremman lopputuloksen. Lataamalla
+paketin \pakettictan{floatrow} voi käyttää myös myös valitsinta
+\koodi{H}. Se tarkoittaa ehdotonta vaatimusta, että juuri tähän kohtaan
+leijuva osa pitää sijoittaa. Tätä valitsinta ei voi yhdistää muiden
+valitsimien kanssa.
+
+Valitsinta \koodi{!} käytetään yhdessä edellä mainittujen valitsimien
+\koodi{tbp} kanssa. Se poistaa tietyt sijoitteluun vaikuttavat säännöt
+tai rajoitukset. Niitä käsitellään seuraavaksi.
+
+Leijuvien osien automaattisessa sijoittelussa vaikuttaa kymmenen
+erilaista parametria, joihin kirjoittaja voi vaikuttaa: kolme laskuria,
+kolme mittaa ja neljä komentoa. Joillekin asetuksille on olemassa
+rinnakkainen versio, jota käytetään kahden palstan tilassa (luku
+\ref{luku/palstat}). Ne koskevat leijuvien ympäristöjen tähdellisiä
+versiota, kuten \ymparisto{table*} ja \ymparisto{figure*}, eli
+tilannetta, jossa leijuva osa ei ole palstojen sisällä, vaan koko sivun
+leveys on käytettävissä.
+
+Seuraavat kolme laskuria vaikuttavat sivulle ladottavien leijuvien osien
+enimmäismäärään. Ne koskevat tilannetta, jossa sivulla on myös
+tavallista leipätekstiä tai muuta sisältöä. Laskureille asetetaan uusi
+arvo komennolla \komento{setcounter} (luku \ref{luku/laskurit}). Näiden
+laskurien vaikutuksen voi poistaa kokonaan käyttämällä leijuvan
+ympäristön valitsinta \koodi{!} (taulukko
+\ref{tlk/leijuosat-sijoittelukirjaimet}).
+
+\begin{maaritelma}{\laskuri{#1}}
+\item [topnumber] Sivun yläosaan sijoitettavien leijuvien osien
+ enimmäismäärä. Oletusarvo on~2. Kahden palstan tilassa käytetään
+ laskuria \laskuri{dbltopnumber}.
+\item [bottomnumber] Sivun alaosaan sijoitettavien leijuvien osien
+ enimmäismäärä. Oletusarvo on~1. Kahden palstan tilassa leijuvia osia
+ ei sijoiteta sivun alaosaan täysilevyisenä.
+\item [totalnumber] Samalla sivulla olevien leijuvien osien
+ enimmäismäärä, kun sivulla on myös tavallista leipätekstiä. Oletusarvo
+ on~3.
+\end{maaritelma}
+
+\noindent
+Seuraavat kolme mittaa vaikuttavat leijuvien osien pystysuuntaisiin
+väleihin. Mitat asetetaan komennolla \komento{setlength} (luku
+\ref{luku/mitat}).
+
+\begin{maaritelma}{\mitta{#1}}
+\item [floatsep] Samalla sivulla kahden peräkkäisen leijuvan osan
+ pystysuuntainen väli. Oletusarvo on venyvä mitta \koodi{12pt plus 2pt
+ minus 2pt}. Kahden palstan tilassa käytetään mittaa
+ \mitta{dblfloatsep}.
+\item [textfloatsep] Leijuvan osan ja leipätekstin välinen
+ pystysuuntainen väli. Oletusarvo on venyvä mitta \koodi{20pt plus 2pt
+ minus 4pt}. Kahden palstan tilassa käytetään mittaa
+ \mitta{dbltextfloatsep}.
+\item [intextsep] Pystysuuntainen väli leipätekstin ja leijuvan osan
+ välissä silloin, kun leijuva osa sijoitetaan tekstivirran sekaan. Tämä
+ koskee sijoitteluasetuksia \koodi{h} ja \koodi{H} (taulukko
+ \ref{tlk/leijuosat-sijoittelukirjaimet}). Oletusarvo vaihtelee
+ dokumenttiluokan fonttikokoasetusten (luku
+ \ref{luku/perusdokumenttiluokat-asetukset}) perusteella. Jos
+ dokumenttiluokan valitsin on \koodi{10pt} (oletus) tai \koodi{11pt},
+ oletusmitta on \koodi{12pt plus 2pt minus 2pt}. Dokumenttiluokan
+ valitsimella \koodi{12pt} oletus on \koodi{14pt plus 4pt minus 4pt}.
+\end{maaritelma}
+
+\noindent
+Seuraavat neljä komentoa sisältävät pelkän desimaaliluvun 0\==1. Luku
+kertoo leijuvien osien tai leipätekstin viemän suhteellisen tilan
+samalla sivulla. Komennot määritellään uudelleen komennolla
+\komento{renewcommand} (luku \ref{luku/komennot-määrittely}). Näiden
+vaikutuksen voi poistaa kokonaan leijuvan ympäristön valitsimella
+\koodi{!} (taulukko \ref{tlk/leijuosat-sijoittelukirjaimet}).
+
+\begin{maaritelma}{\komento{#1}}
+\item [topfraction] Sivun yläosaan sijoitettavien leijuvien osien viemä
+ enimmäistila suhteessa sivun tekstialueen korkeuteen. Oletusarvo
+ on~\koodi{0.7}, mikä tarkoittaa, että leijuvat osat voivat viedä
+ korkeintaan 0,7\=/ kertaisesti (70\,\%) sivulla olevan pystysuuntaisen
+ tilan. Kahden palstan tilassa käytetään komentoa
+ \komento{dbltopfraction}.
+\item [bottomfraction] Sivun alaosaan sijoitettavien leijuvien osien
+ viemä enimmäistila suhteessa sivun tekstialueen korkeuteen. Oletusarvo
+ on~\koodi{0.3} (30\,\%). Kahden palstan tilassa leijuvia osia ei
+ koskaan sijoiteta sivun alaosaan.
+\item [textfraction] Leipätekstin vähimmäistila sivulla, kun samalla
+ sivulla on myös leijuvia osia. Oletusarvo on \koodi{0.2} (20\,\%).
+\item [floatpagefraction] Omalle sivulleen sijoitettavien leijuvien
+ osien vähimmäistila sivun tekstialueen korkeudesta. Toisin sanoen
+ leijuvien osien täytyy viedä vähintään tämän verran tilaa sivulta,
+ ennen kuin ne sijoitetaan omalle sivulleen, jossa ei ole leipätekstiä
+ lainkaan. Oletusarvo on~\koodi{0.5} (50\,\%). Kahden palstan tilassa
+ käytetään komentoa \komento{dblfloatpagefraction}.
+\end{maaritelma}
+
+\noindent
+Sivunvaihtokomennot \komento{clearpage} ja \komento{cleardoublepage}
+(luku \ref{luku/sivunvaihdot}) pakottavat kaikki aiemmin
+lähdetiedostossa olleet leijuvat osat ladottavaksi. Osanvaihtokomento
+\komento{part} ja otsikkokomento \komento{chapter} (luku
+\ref{luku/otsikot}) tekevät saman automaattisesti joissakin
+dokumenttiluokissa.
+
+Paketin \pakettictan{placeins} avulla voi tehdä omiakin rajakohtia,
+jonka yli leijuvat osat eivät voi siirtyä. Paketin komennolla
+\komento{FloatBarrier} tehdään raja kyseiseen kohtaan lähdedokumentissa.
+Jos paketin lataamisessa antaa argumentin \koodi{section}, asetetaan
+tällainen raja automaattisesti \komento{section}\-/ tasoisille
+otsikoille.
+
+\komentoi{usepackage}
+\pakettii{placeins}
+\begin{koodilohkosis}
+\usepackage[section]{placeins}
+\end{koodilohkosis}
+
+\subsection{Ulkoasu}
+\label{luku/leijuosat-ulkoasu}
+
+Leijuvan osan sisäisen asettelun, ulkoasun ja muun typografian
+hallintaan ja muokkaamiseen tarvitaan yleensä paketteja
+\pakettictan{floatrow} ja \pakettictan{caption}. Jälkimmäisen avulla
+muokataan kuvatekstin fonttia ja rivitystä, ja sitä käsitellään
+myöhemmin tässä alaluvussa.
+
+Paketti \paketti{floatrow} tarjoaa runsaasti mahdollisuuksia leijuvien
+osien sijoitteluun: osat voi kehystää laatikolla, kuvatekstin voi
+sijoittaa ylös, alas tai sivulle, useita leijuvia osia voi sijoittaa
+vierekkäin ym. Tässä oppaassa käsitellään ainoastaan peruskäyttöä.
+
+Jotta \paketti{floatrow}\-/ paketin ominaisuudet saisi käyttöönsä,
+täytyy leijuvat osat toteuttaa sen oman \komento{floatbox}\-/ komennon
+avulla. Komento sijoitetaan leijuvan ympäristön sisään. Sen
+argumenteiksi annetaan ainakin leijuvan osan tyyppi, kuvatekstikomento
+ja varsinainen leijuva sisältö. Seuraavassa esimerkissä käytetään
+\ymparisto{table}\-/ ympäristöä, mutta muut tyypit toimivat samalla
+tavalla.
+
+\komentoi{floatbox}
+\ymparistoi{table}
+\begin{koodilohkosis}
+\begin{table}
+ \floatbox{table}[leveys]{kuvatekstit}{sisältö}
+\end{table}
+\end{koodilohkosis}
+
+\begin{esimerkki*}
+ \komentoi{caption}
+ \komentoi{floatbox}
+ \komentoi{label}
+ \mittai{FBwidth}
+ \ymparistoi{table}
+ \ymparistoi{tabular}
+
+\begin{koodilohko}
+\begin{table}
+ \floatbox{table}[\FBwidth]{
+ \caption{Upea taulukko} % kuvateksti
+ \label{tlk/upea-taulukko} % tunniste ristiviittausta varten
+ }{
+ \begin{tabular}{ll}
+ jotain & soluja \\
+ esimerkin & vuoksi \\
+ \end{tabular}
+ }
+\end{table}
+\end{koodilohko}
+ \caption{\komento{floatbox}\-/ komennon peruskäyttö}
+ \label{esim/floatbox-perus}
+\end{esimerkki*}
+
+\noindent
+Valinnaisen argumentin \koodi{leveys} voi jättää poiskin, jolloin
+leijuva osa varaa itselleen sivun leveyden verran tilaan. Argumentiksi
+on joskus hyödyllistä antaa mitta \mitta{FBwidth}, joka on leijuvan osan
+sisällön levyinen. Käyttämällä tätä mittaa kuvatekstit rivitetään vain
+sisällön levyiseksi. Esimerkki \ref{esim/floatbox-perus} selventää,
+miten \komento{floatbox}\-/ komento toimii käytännössä.
+
+Yksi leijuva ympäristö voi sisältää rinnakkain useampia taulukoita,
+kuvia tms., joilla jokaisella on oma kuvatekstinstä. Se tehdään
+ympäristöllä \ymparisto{floatrow}, jonka valinnainen argumentti
+ilmaisee, kuinka monta kuvaa tms. ladotaan rinnakkain. Oletusarvo on~2.
+Ympäristön sisällä täytyy olla yhtä monta \komento{floatbox}\-/
+komentoa. Seuraavasta esimerkistä selviää perusajatus kahden taulukon
+latomiseksi rinnakkain:
+
+\komentoi{caption}
+\komentoi{floatbox}
+\mittai{FBwidth}
+\ymparistoi{floatrow}
+\ymparistoi{table}
+\begin{koodilohkosis}
+\begin{table}
+ \begin{floatrow}[2] % kaksi rinnakkain
+ \floatbox{table}[\FBwidth]{\caption{Vasen}}{…}
+ \floatbox{table}[\FBwidth]{\caption{Oikea}}{…}
+ \end{floatrow}
+\end{table}
+\end{koodilohkosis}
+
+\noindent
+Kun leijuvat osat on toteutettu \komento{floatbox}\-/ komennon avulla,
+voi niiden ulkoasuun vaikuttaa komennolla \komento{floatsetup}. Sille
+annetaan ainakin yksi argumentti, joka voi sisältää useita pilkulla
+toisistaan erotettuja valitsimia ja niiden arvoja.
+
+\komentoi{floatsetup}
+\begin{koodilohkosis}
+\floatsetup[tyyppi]{valitsimet}
+\end{koodilohkosis}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\koodi{#1} & #2 \\}
+ \begin{tabularx}{\linewidth}{lL}
+ \toprule
+ \ots{Valitsin} & \ots{Merkitys ja vaihtoehtoja} \\
+ \midrule
+
+ \rivi{style}{tyyli: \koodi{plain}, \koodi{ruled}, \koodi{boxed} ym.}
+
+ \rivi{capposition}{kuvatekstin sijainti: \koodi{top}, \koodi{bottom}
+ ym.}
+
+ \rivi{captionskip}{kuvatekstin etäisyys sisällöstä (mitta)}
+
+ \rivi{font}{fonttiasetukset: \koodi{rm}, \koodi{sf}, \koodi{tt},
+ \koodi{md}, \koodi{bf}, \koodi{up}, \koodi{it}, \koodi{sl},
+ \koodi{sc}, \koodi{scriptsize}, \koodi{footnotesize},
+ \koodi{small}, \koodi{normalsize}, \koodi{large}, \koodi{Large}}
+
+ \rivi{margins}{leijuvan osan sijainti: \koodi{centering},
+ \koodi{raggedright}, \koodi{raggedleft} ym.}
+
+ \rivi{justification}{sisällön tasaus: \koodi{justified},
+ \koodi{centering}, \koodi{raggedright}, \koodi{raggedleft},
+ \koodi{RaggedRight} (\paketti{ragged2e}), \koodi{RaggedLeft}
+ (\paketti{ragged2e})}
+
+ \bottomrule
+ \end{tabularx}
+}{
+ \caption{Muutama \komento{floatsetup}\-/ komennon valitsin, joilla
+ vaikutetaan leijuvien osien ulkoasuun. Osa tarvitsee paketin
+ \paketti{ragged2e}}
+ \label{tlk/floatsetup-valitsimia}
+}
+
+\noindent
+Valinnainen argumentti \koodi{tyyppi} on leijuvan osan tyyppi,
+esimerkiksi \ymparisto{table} tai \ymparisto{figure}. Jos se on annettu,
+asetukset vaikuttavat vain kyseiseen tyyppiin; muuten asetukset koskevat
+kaikentyyppisiä leijuvia osia. Asetukset tehdään erilaisten valitsimien
+avulla, joista muutama on koottu taulukkoon
+\ref{tlk/floatsetup-valitsimia}.
+
+Valitsin \koodi{font} asettaa leijuvan ympäristön fontin mutta ei
+vaikuta kuvatekstiin. Fonttiasetukset ovat käytännössä avainsanoja,
+jotka vastaavat lähes samannimisiä fonttikomentoja. Niitä käsitellään
+luvussa \ref{luku/fontit-korkea}. Omiakin fonttien avainsanoja voi luoda
+komennolla \komento{DeclareFloatFont}. Valitsimen \koodi{justification}
+arvoksi annetaan myös tietty sana, joka vastaava samannimisiä palstan
+tasauskomentoja (luku \ref{luku/kappaleen-tasaus}). Käytännössä leijuvan
+osan asetukset voisivat näyttää vaikka seuraavanlaiselta:
+
+\komentoi{floatsetup}
+\begin{koodilohkosis}
+\floatsetup{ style=plain, capposition=bottom, font={sf, small},
+ justification=centering, captionskip=2ex }
+\floatsetup[figure]{ style=boxed }
+\end{koodilohkosis}
+
+\noindent
+Kuvatekstien fonttia ja rivittämistä hallitaan \pakettictan{caption}\-/
+paketin avulla. Tärkein komento on \komento{captionsetup}, joka yleensä
+sijoitetaan dokumentin esittelyosaan tai muuten alkuun, koska silloin se
+vaikuttaa koko dokumentissa. Komennon voi sijoittaa myös esimerkiksi
+yksittäisen leijuvan ympäristön sisään, jolloin se vaikuttaa vain
+kyseisessä ympäristössä.
+
+\komentoi{captionsetup}
+\begin{koodilohkosis}
+\captionsetup[tyyppi]{valitsimet}
+\end{koodilohkosis}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\koodi{#1} & #2 \\}
+ \begin{tabularx}{\linewidth}{lL}
+ \toprule
+ \ots{Valitsin} & \ots{Merkitys ja vaihtoehtoja} \\
+ \midrule
+
+ \rivi{font}{kuvatekstin fontti: \koodi{normalfont}, \koodi{rm},
+ \koodi{sf}, \koodi{tt}, \koodi{md}, \koodi{bf}, \koodi{up},
+ \koodi{it}, \koodi{sl}, \koodi{sc}, \koodi{scriptsize},
+ \koodi{footnotesize}, \koodi{small}, \koodi{normalsize},
+ \koodi{large}, \koodi{Large}}
+
+ \rivi{labelfont}{leijuvan osan tyypin ja numeroinnin fontti}
+
+ \rivi{textfont}{varsinaisen kuvatekstin fontti}
+
+ \rivi{format}{kappaleen tyyppi, tavallinen \koodi{plain} vai
+ riippuva \koodi{hang}}
+
+ \rivi{indentation}{sisennysmitta kuvatekstin toisesta rivistä
+ alkaen}
+
+ \rivi{labelformat}{leijuvan osan tyypin muoto: \koodi{default},
+ \koodi{empty}, \koodi{simple}, \koodi{brace}, \koodi{parens}}
+
+ \rivi{labelsep}{leijuvan osan tyypin erotinmerkki: \koodi{none},
+ \koodi{colon}, \koodi{period}, \koodi{space}, \koodi{quad},
+ \koodi{newline}, \koodi{endash}}
+
+ \rivi{textformat}{kuvatekstin lopetusmerkki: \koodi{simple},
+ \koodi{period}}
+
+ \rivi{justification}{kuvatekstin tasaus: \koodi{justified},
+ \koodi{centering}, \koodi{centerlast}, \koodi{centerfirst},
+ \koodi{raggedright}, \koodi{RaggedRight} (\paketti{ragged2e}),
+ \koodi{raggedleft}}
+
+ \rivi{singlelinecheck}{yksirivisten kuvatekstien poikkeuksellinen
+ tasaus: \koodi{true} (oletus), \koodi{false}}
+
+ \rivi{margin}{kuvatekstin marginaalit: yksi mitta tai kaksi pilkulla
+ erotettua mittaa (vasen ja oikea marginaali)}
+
+ \rivi{width}{kuvatekstikappaleen leveys (mitta)}
+
+ \bottomrule
+ \end{tabularx}
+}{
+ \caption{Tärkeimpiä \komento{captionsetup}\-/ komennon valitsimia}
+ \label{tlk/captionsetup-valitsimia}
+}
+
+\noindent
+Komennon valinnainen argumentti \koodi{tyyppi} on leijuvan osan tyyppi,
+esimerkiksi \ymparisto{table} tai \ymparisto{figure}, johon halutaan
+vaikuttaa. Jos sen jättää pois, asetukset vaikuttavat kaikkien leijuvien
+osien kuvateksteihin. Pakollinen argumentti on \koodi{valitsimet},
+johon kirjoitetaan valitsimia eli avainsanoja ja niiden arvoja.
+Tärkeimpiä valitsimia on koottu taulukkoon
+\ref{tlk/captionsetup-valitsimia}. Käytännössä komento voisi näyttää
+esimerkiksi seuraavanlaiselta:
+
+\komentoi{captionsetup}
+\begin{koodilohkosis}
+\captionsetup{ font={small, sf}, labelfont={bf}, textfont={},
+ textformat=period, margin={.5em,0em}, justification=raggedright,
+ singlelinecheck=false }
+\end{koodilohkosis}
+
+\noindent
+Oletuksena Latex käsittelee yksiriviset kuvatekstit poikkeuksellisella
+tavalla eli keskittää ne. Sen vuoksi tasausvalitsin
+\koodi{justification} ei vaikuta yksirivisiin kuvateksteihin. Tämän
+poikkeuksen saa pois päältä käyttämällä asetusta
+\koodi{singlelinecheck=\katk false}, jolloin sama
+\koodi{justification} pätee yhtä lailla niin yksi- kuin monirivisiinkin
+kuvateksteihin.
+
+\begin{esimerkki*}
+ \ymparistoi{table}
+ \komentoi{caption}
+ \komentoi{ContinuedFloat}
+
+\begin{koodilohko}
+\begin{table} % kokonaisuuden 1. leijuva ympäristö
+ \caption{Hieno taulukko}
+ ...
+\end{table}
+...
+\begin{table} % kokonaisuuden 2. leijuva ympäristö
+ \ContinuedFloat % sama numerointi kuin edelliselle
+ \caption{Hieno taulukko (jatkuu)}
+ ...
+\end{table}
+\end{koodilohko}
+
+ \caption{Usealle leijuvalle osalle saa saman numeroinin käyttämällä
+ komentoa \komento{ContinuedFloat}}
+ \label{esim/continuedfloat}
+\end{esimerkki*}
+
+Joskus halutaan, että useampi taulukko, kuva tai muu leijuva osa
+muodostavat kokonaisuuden, jolla on sama numero, esimerkiksi
+''\tablename~3''. Ajatuksena on, että sama sisältö on jakautunut
+useampaan osaan. Se onnistuu sijoittamalla \paketti{caption}\-/ paketin
+komento \komento{ContinuedFloat} ensimmäisen jälkeisiin leijuviin
+ympäristöihin. Komento pitäisi sijoittaa heti ympäristön alkuun.
+Esimerkki \ref{esim/continuedfloat} havainnollistaa sen käyttöä.
+
+Kuvatekstissä oleva leijuvan osan numero tulee laskurista, ja
+erityyppisellä osilla on oma laskurinsa. Laskurin nimi on sama kuin
+vastaavan leijuvan ympäristön nimi, eli esimerkiksi \ymparisto{table}\-/
+ympäristöt numeroidaan laskurin \laskuri{table} avulla.
+
+Käytännössä laskurien arvo ladotaan \komentox{the}\-/ alkuisella
+komennolla, jonka perässä on laskurin nimi, esimerkiksi
+\komento{thetable}. Oletuksena nämä komennot latovat laskurin
+arabialaisilla numeroilla. Jos laskuri on riippuvainen teoksen
+pääluvuista (\komento{chapter}), ladotaan ensin pääluvun numero,
+erotinpiste ja leijuvan osan numero: 2.1, 2.2, 2.3 jne.
+
+Kirjoittaja voi määritellä laskurien latomiskomennon haluamallaan
+tavalla. Seuraavassa esimerkissä leijuville kuville (\ymparisto{figure})
+määritellään numerointitapa, jossa on pääluvun numero, ajatusviiva (\==)
+ja leijuvan kuvan numero:
+
+\komentoi{arabic}
+\komentoi{renewcommand}
+\komentoi{thechapter}
+\komentoi{thefigure}
+\laskurii{figure}
+\begin{koodilohkosis}
+\renewcommand{\thefigure}{\thechapter--\arabic{figure}}
+\end{koodilohkosis}
+
+\section{Ristiviittaukset}
+\label{luku/ristiviitteet}
+
+Ristiviittaukset tarkoittavat dokumentin sisäisiä viittauksia eli
+viittauksia toisiin kohtiin samassa dokumentissa. Lukijalle ne ilmenevät
+ilmauksina kuten ''luvussa 4.2'' tai ''kuvassa~5''. Kirjoittajan ei
+kuitenkaan kannata naputella luvun numeroa (esim. ''4.2'') käsin
+lähdedokumenttiin, koska lukujen järjestys ja numerointi voi muuttua
+kirjoittamisen edetessä. Joutuisi korjaamaan muuttuneet numerot
+mahdollisesti useitakin kertoja ennen kuin työ on valmis.
+
+Latex osaa numeroida dokumentin otsikot (luvut) ja leijuvat osat
+automaattisesti, eli se tietää, minkä numeron mikäkin dokumentin osa
+saa. Niinpä Latex osaa myös -- kirjoittajan pienellä avustuksella --
+ylläpitää ajantasaisia ristiviittauksia dokumentin eri osiin. Teknisesti
+tämä toteutetaan siten, että otsikoille ja leijuville osille annetaan
+yksilöllinen tunniste ja viittaamisessa käytetään samoja tunnisteita.
+Tunnisteet annetaan \komento{label}\-/ komennolla, joka sijoitetaan heti
+otsikkokomennon (\komento{section}, \komento{subsection} ym.) tai
+leijuvan osan kuvatekstikomennon (\komento{caption}) jälkeen:
+
+\komentoi{section}
+\komentoi{label}
+\begin{koodilohkosis}
+\section{Jokin otsikko}
+\label{tunniste}
+\end{koodilohkosis}
+
+\noindent
+\komento{label}\-/ komennon argumentti \koodi{tunniste} voi olla
+suunnilleen mitä tahansa tekstiä. Sen täytyy olla yksilöllinen, eli sama
+tunniste ei saa olla käytössä missään toisessa \komento{label}\-/
+komennossa. Jos sama tunniste sattuu olemaan useassa paikassa, vain
+viimeinen jää käytännössä voimaan.
+
+Järkevää on kirjoittaa tunnisteeseen sana tai sanoja, jotka kertovat
+jotakin kyseisen osan sisällöstä. Hyödyllistä voi olla myös kirjoittaa
+tunnisteen tieto, onko kyse luvusta, taulukosta, kuvasta vai muusta
+leijuvasta osasta, koska erityyppiset osat voivat käsitellä samaa
+aihetta. Seuraavassa on esimerkkejä \komento{label}\-/ komennoista:
+
+\komentoi{label}
+\begin{koodilohkosis}
+\label{luku/fonttien-valinta} % otsikkokomennon jälkeen
+\label{taulukko/fonttikomentoja} % taulukon \caption-komennon jälkeen
+\label{kuva/kirjainleikkauksia} % kuvan \caption-komennon jälkeen
+\end{koodilohkosis}
+
+\noindent
+Ristiviittauksissa vähimmällä vaivalla selviää, kun muistaa kaksi asiaa:
+1)~kirjoittaa \komento{label}\-/ komentoja vain niihin kohtiin, joihin
+täytyy viitata muualta, 2)~valitsee tunnisteet siten, ettei niitä
+tarvitse muuttaa enää sen jälkeen, kun ne on kerran valinnut.
+
+Tavallisimmat ristiviittaukset tehdään \komento{ref}\-/ komennolla,
+jonka argumentiksi annetaan sama tunniste kuin jossakin dokumentin
+\komento{label}\-/ komennossa. Latex latoo \komento{ref}\-/ komentojen
+kohdalle kyseisen luvun tai leijuvan osan numeron. Toinen tarpeellinen
+ristiviittauskomento on \komento{pageref}, joka kääntämisvaiheessa
+korvautuu kyseisen kohteen sivunumerolla. Näitä voi hyödyntää
+lähdedokumentissa esimerkiksi seuraavasti:
+
+\komentoi{ref}
+\komentoi{pageref}
+\begin{koodilohkosis}
+Katso taulukko \ref{taulukko/fonttimallikomennot} sivulla
+\pageref{taulukko/fonttimallikomennot}.
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Katso taulukko \ref{tlk/fonttimallikomennot} sivulla
+ \pageref{tlk/fonttimallikomennot}.
+\end{tulossis}
+
+\noindent
+Jos ladattuna on paketti \paketti{hyperref} (luku
+\ref{luku/pdf-asetukset}), on ristiviittauksiin käytettävissä myös
+komento \komento{nameref}. Sillekin annetaan argumentiksi jokin
+\komento{label}\-/ komennolla määritetty tunniste, ja kääntämisvaiheessa
+komennon tilalle ladotaan kyseisen kohteen teksti eli otsikko tai
+kuvateksti. Ristiviittauksissa ladotaan otsikon tai kuvatekstin lyhempi
+versio, jos sellainen on annettu. Otsikkokomentojen ja
+kuvatekstikomennon argumentteja käsitellään luvuissa \ref{luku/otsikot}
+(\nameref{luku/otsikot}) ja \ref{luku/leijuosat-latex}
+(\nameref{luku/leijuosat-latex}).
+
+Ristiviittaukset vaativat, että Latex\-/ lähdedokumentti käännetään
+kahdesti. Ensimmäisellä kääntämiskerralla \komento{label}\-/ komennolla
+mainittujen kohteiden tiedot kirjoitetaan muistiin väliaikaistiedostoon.
+Toisella kääntämiskerralla hyödynnetään väliaikaistiedostoa ja
+\komento{ref}-, \komento{pageref}\-/\ ja \komento{nameref}\-/ komentojen
+tilalle ladotaan viittauskohteen oikeat tiedot.
+
+\section{Alaviitteet}
+\label{luku/alaviitteet}
+
+Alaviitteet ovat sivun alareunassa olevia numeroituja tai muulla tavalla
+merkittyjä huomautuksia. Niihin viitataan sanojen tai virkkeiden perässä
+olevalla yläindeksinumerolla, \=/kirjaimella tai
+\=/symbolilla.\footnote{Tässä on esimerkki alaviitteestä.} Alaviitteiden
+tarkoituksena on lisätä tekstiin lähes huomaamaton lisätieto, joka ei
+häiritse lukemista. Se sopii esimerkiksi lisätietoihin, joilla ei ole
+kovin suurta merkitystä tai jotka sopivat huonosti ladottavaksi
+leipätekstiin. Joskus myös tiedonlähteet ilmaistaan alaviitteiden
+avulla.\footcites[162]{kt_oik}[127--128]{typokk}
+
+Alaviite tehdään komennolla \komento{footnote}, jonka argumentiksi
+kirjoitetaan alaviitteeseen tuleva teksti. Oletuksena Latex latoo
+komennon paikalle yläindeksinumeron, joka tulee automaattisesti
+kasvavasta laskurista \laskuri{footnote}. Komennolle voi antaa myös
+valinnaisen argumentin, joka on kyseisen alaviitteen numero. Tässä
+tapauksessa komento ei kasvata \laskuri{footnote}\-/ laskuria.
+
+\komentoi{footnote}
+\begin{koodilohkosis}
+\footnote{Alaviitteen teksti.}
+\footnote[numero]{Alaviitteen teksti.}
+\end{koodilohkosis}
+
+\noindent
+Itse alaviite ladotaan samalla kirjaintyypillä kuin leipätekstikin mutta
+pienempänä: sen koko tulee komennosta \komento{footnotesize} (luku
+\ref{luku/fontit-korkea}). Samalle sivulle voi sattua useampikin
+alaviite, ja ne erotetaan leipätekstistä pienellä pystysuuntaisella
+välillä sekä oletuksena myös lyhyellä vaakaviivalla. Jos alaviitteen
+tekee leijuvaan osaan (luku \ref{luku/leijuosat}) tai
+\ymparisto{minipage}\-/ ympäristöön (luku \ref{luku/laatikot-isot}), se
+merkitään oletuksena kirjaimen avulla, ja alaviitteen teksti ladotaan
+kyseisen osan alapuolelle.
+
+\komento{footnote}\-/ komennon toiminnan voi jakaa kahteen erilliseen
+osaan komentojen \komento{footnotemark} ja \komento{footnotetext}
+avulla. Ensin mainittu komento latoo pelkän yläindeksinumeron, joka
+tulee alaviitelaskurista. Komento ei lado varsinaista alaviitettä.
+Jälkimmäinen komento puolestaan latoo pelkän alaviitteen. Kummallekin
+komennolle voi antaa valinnaisen argumentin, jolla ilmaistaan kyseisen
+alaviitteen numero.
+
+\komentoi{footnotemark}
+\komentoi{footnotetext}
+\begin{koodilohkosis}
+\footnotemark[numero] % yläindeksinumero
+\footnotetext[numero]{Alaviitteen teksti.} % alaviite
+\end{koodilohkosis}
+
+\noindent
+Alaviitteiden numerointi on laskurissa \laskuri{footnote}, mutta sen
+arvo ladotaan komennon \komento{thefootnote} avulla. Tämän komennon
+määritelmässä on oletuksena komento
+\komento{arabic}\komentoarg{footnote}, eli laskuri ladotaan
+arabialaisilla numeroilla. Kirjoittaja voi kuitenkin määritellä komennon
+uudestaan. Seuraavassa esimerkissä määritellään komento siten, että
+alaviitteet ilmaistaan symbolien avulla:
+
+\komentoi{renewcommand}
+\komentoi{thefootnote}
+\komentoi{fnsymbol}
+\laskurii{footnote}
+\begin{koodilohkosis}
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+\end{koodilohkosis}
+
+\noindent
+Laskurien symboliesitys toimii vain lukualueella 1\==9, joten samaan
+dokumenttiin ei mahdu kovin monta alaviitettä, ellei laskuria nollaa
+välillä. Laskurin voi määritellä riippuvaiseksi toisesta laskurista,
+jolloin se nollautuu itsestään, kun toisen laskurin arvo kasvaa.
+Esimerkiksi dokumenttiluokassa \luokka{book} alaviitteiden laskuri
+nollautuu oletuksena aina päälukujen (\komento{chapter}) vaihtuessa.
+Joskus voi olla tarpeen tehdä alaviitteiden laskuri sivukohtaiseksi eli
+riippuvaiseksi \laskuri{page}\-/ laskurista. Sen voi toteuttaa
+\paketti{chngcntr}\-/ paketin ja \komento{counterwithin*}\-/ komennon
+(luku \ref{luku/hierarkkiset-laskurit}) avulla seuraavan esimerkin
+mukaisesti. Toinen vaihtoehto on paketti \paketti{footmisc} ja valitsin
+\koodi{perpage}, jota käsitellään myöhemmin tässä luvussa.
+
+\komentoi{counterwithin}
+\laskurii{footnote}
+\laskurii{page}
+\begin{koodilohkosis}
+\counterwithin*{footnote}{page}
+\end{koodilohkosis}
+
+\noindent
+Edellisissä esimerkeissä on käsitelty koko dokumentin alaviitelaskuria
+\laskuri{footnote}, mutta leijuvissa osissa ja \ymparisto{minipage}\-/
+ympäristöissä (luku \ref{luku/laatikot-isot}) alaviitteet numeroidaan
+laskurin \laskuri{mpfootnote} avulla. Tämän laskurin arvo ladotaan
+käytännössä komennolla \komento{thempfootnote}, jonka kirjoittaja voi
+määritellä uudelleen tarpeen mukaan. Laskureihin liittyvää tekniikkaa
+käsitellään tarkemmin luvussa \ref{luku/laskurit}.
+
+Leipäteksti ja alaviitteet erotetaan pystysuuntaisella välillä, jonka
+voi asettaa sivun asetusten yhteydessä (luku \ref{luku/sivuasetukset}).
+Asetus on \paketti{geometry}\-/ paketin valitsin \koodi{footnotesep},
+jota käytetään esimerkiksi \komento{geometry}\-/ komennon kanssa:
+
+\komentoi{geometry}
+\begin{koodilohkosis}
+\geometry{ footnotesep=14bp }
+\end{koodilohkosis}
+
+\noindent
+Välin täytyy olla ainakin niin suuri, ettei lukija sekoita alaviitteitä
+leipätekstin kappaleeseen. Ehkä riittävä väli on noin yhden
+rivikorkeuden verran tai vähän enemmän. Sopivan välin suuruus voi
+riippua siitäkin, erotetaanko leipäteksti ja alaviitteet toisistaan myös
+vaakaviivalla.
+
+Muunlaiset alaviitteisiin vaikuttavat asetukset täytyy tehdä paketin
+\pakettictan{footmisc} avustuksella. Sen avulla voi esimerkiksi poistaa
+alaviitteiden erotinviivan ja muotoilla alaviitekappaleita. Paketin
+lataamisen yhteydessä voi antaa useita pilkulla erotettuja valitsimia,
+joita on koottu taulukkoon \ref{tlk/footmisc-valitsimet}. Erotinviiva
+poistetaan paketin valitsimella \koodi{norule}. Samalla pystysuuntainen
+väli hieman kasvaa.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\koodi{#1} & #2 \\}
+ \begin{tabular}{ll}
+ \toprule
+ \ots{Valitsin} & \ots{Merkitys} \\
+ \midrule
+ \rivi{norule}{vaakasuuntainen erotinviiva pois}
+ \rivi{perpage}{numerointi sivukohtaiseksi}
+ \rivi{bottom}{alaviite aina sivun alareunaan}
+ \rivi{hang}{luetelmatyyppiset alaviitteet, riippuva sisennys}
+ \rivi{multiple}{useat peräkkäiset yläindeksinumerot}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{\paketti{footmisc}\-/ paketin asetusten avulla muotoillaan
+ alaviitteitä}
+ \label{tlk/footmisc-valitsimet}
+}
+
+\pakettii{footmisc}
+\komentoi{usepackage}
+\begin{koodilohkosis}
+\usepackage[norule]{footmisc}
+\end{koodilohkosis}
+
+\noindent
+Valitsin \koodi{perpage} numeroi alaviitteet sivukohtaisesti, eli niiden
+laskuri nollautuu aina sivun vaihtuessa. Valitsin \koodi{bottom}
+pakottaa alaviitteen aina sivun alareunaan. Oletusasetuksilla alaviite
+voi sijoittua joskus ylemmäksi, jos sivun alaosaan ladotaan leijuva osa
+tai jos sivun alareunan tasaaminen on pois päältä
+(\komento{raggedbottom}, luku \ref{luku/sivunvaihdot}).
+
+Oletuksena alaviitekappaleet ladotaan samalla tavalla kuin
+tekstikappaleet oletuksena muutenkin: alaviitteen ensimmäinen rivi on
+sisennetty ja sen alussa on alaviitteen numero. Seuraavia rivejä ei
+sisennetä. Tällainen asetus sopii hyvin pitkien alaviitetekstien
+latomiseen. Usein ne ovat kuitenkin lyhyitä, ja silloin voi sopia
+paremmin luetelmatyyppiset alaviitekappaleet (riippuva sisennys), joissa
+alaviitteen numero on omalla alueellaan ja varsinainen alaviiteteksti on
+sisennetty. Tällainen asetus tehdään \paketti{footmisc}\-/ paketin
+valitsimella \koodi{hang}. Sisennyksen suuruuteen voi vaikuttaa mitan
+\mitta{footnotemargin} avulla:
+
+\komentoi{setlength}
+\komentoi{usepackage}
+\mittai{footnotemargin}
+\pakettii{footmisc}
+\begin{koodilohkosis}
+\usepackage[hang]{footmisc}
+\setlength{\footnotemargin}{1.5em}
+\end{koodilohkosis}
+
+\noindent
+Valitsin \koodi{multiple} mahdollistaa peräkkäisten
+\komento{footnote}\-/ komentojen kirjoittamisen helposti. Peräkkäin
+olevien yläindeksinumeroiden väliin ladotaan automaattisesti pilkku,
+kuten seuraava esimerkki osoittaa:
+
+\komentoi{footnote}
+\begin{koodilohkosis}
+sana\footnote{…}\footnote{…}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ sana\textsuperscript{7}%
+ \textsuperscript*{,}%
+ \textsuperscript{8}
+\end{tulossis}
+
+\noindent
+Toisaalta yläindeksiin voi sijoittaa pilkun tai muuta tekstiä käsinkin
+komennolla \komento{textsuperscript} (luku \ref{luku/ylä-alaindeksit}).
+\koodi{multiple}\-/ valitsin vaatii toimiakseen tietyn
+\paketti{hyperref}\-/ paketin valitsimen, joka käsitellään seuraavaksi.
+
+Jos ladattuna on \paketti{hyperref}\-/ paketti (luku
+\ref{luku/pdf-asetukset}), alaviitteisiin liittyvistä
+yläindeksinumeroista tulee myös hiirellä napsautettavia linkkejä. Tästä
+ominaisuudesta on harvoin mitään hyötyä, koska alaviite on melkein aina
+samalla sivulla. Linkkitoiminto myös häiritsee \paketti{footmisc}\-/
+paketin \koodi{multiple}\-/ valitsimen toimintaa. Alaviitteiden linkit
+voi kytkeä pois \paketti{hyperref}\-/ paketin lataamisen yhteydessä
+seuraavalla asetuksella:
+
+\komentoi{usepackage}
+\pakettii{hyperref}
+\begin{koodilohkosis}
+\usepackage[hyperfootnotes=false]{hyperref}
+\end{koodilohkosis}
+
+\noindent
+\paketti{footmisc}\-/ paketti sisältää muitakin toimintoja alaviitteiden
+ulkoasun säätämiseen. Lisätietoa saa paketin ohjekirjasta.
+
+\section{Palstat}
+\label{luku/palstat}
+
+Latexissa on perustoiminnot usean palstan käsittelyyn, mutta mihinkään
+sanoma- tai aikakauslehden kaltaiseen monipuoliseen tekstin, kuvien ja
+muiden osien sommitteluun se ei kykene. Verrattain yksinkertaiset
+monipalstaiset tekstit kuitenkin onnistuvat Latexissakin varsin
+mukavasti.
+
+Perus Latexissa on kaksi palstoihin liittyvää tilaa: normaali eli yhden
+palstan tila sekä kahden palstan tila, joka täytyy erikseen kytkeä
+päälle. Tätä tilaa käsitellään luvussa \ref{luku/kahden-palstan-tila}.
+Toinen palstojen toteuttamisen vaihtoehto on paketti
+\paketti{multicol}. Sen kanssa käytetään Latexin yhden palstan tilaa ja
+erityistä palstaympäristöä \ymparisto{multicols}. Ympäristön sisällä
+teksti rivitetään kahdelle tai useammalle palstalle. Tätä vaihtoehtoa
+käsitellään luvussa \ref{luku/multicol}.
+
+\subsection{Kahden palstan tila}
+\label{luku/kahden-palstan-tila}
+
+Perus Latexin yhden tai kahden palstan tilan voi valita jo
+dokumenttiluokan (luku \ref{luku/perusdokumenttiluokat-asetukset})
+lataamisen yhteydessä tai sivun asetuksissa (luku
+\ref{luku/sivuasetukset}) käyttämällä valitsinta \koodi{onecolumn}
+(oletus) tai \koodi{twocolumn}. Dokumentin keskellä tilaa voi vaihtaa
+komennoilla \komento{onecolumn} ja \komento{twocolumn}. Kumpikin komento
+aloittaa uuden sivun, jossa valittu tila on voimassa. Komennolle
+\komento{twocolumn} voi antaa hakasulkeissa valinnaisen argumentin,
+jolla ilmaistaan sivun alkuun ladottava koko sivun levyinen sisältö:
+
+\komentoi{twocolumn}
+\begin{koodilohkosis}
+\twocolumn[yksipalstaista sisältöä]
+\end{koodilohkosis}
+
+\noindent
+\komento{twocolumn}\-/ komennon valinnainen argumentti mahdollistaa sen,
+että sivun alkuun voi sijoittaa esimerkiksi koko sivun levyisen otsikon,
+kuvan tai muun osan. Sen jälkeen lähes kaikki sisältö on ladotaan
+kahdelle palstalle, eli teksti täyttää ensin vasemmanpuoleisen palstan
+ja sen jälkeen oikeanpuoleisen.
+
+Leijuvat osat (luku \ref{luku/leijuosat}) ja ympäristöt kuten
+\ymparisto{table} ja \ymparisto{figure} sijoitetaan palstan sisään, eli
+niiden sisältö täytyy suunnitella yhden palstan levyiseksi. Ympäristöjen
+tähdelliset versiot kuten \ymparisto{table*} ja \ymparisto{figure*}
+ladotaan koko sivun levyisenä sivun yläosaan tai kokonaan omalle
+sivulleen, jossa on vain leijuvia osia. Leijuvien osien sijoitteluun
+kahden palstan tilassa voi vaikuttaa tiettyjen laskurien, mittojen ja
+komentojen avulla. Näitä käsitellään luvussa
+\ref{luku/leijuosat-sijoittelu}.
+
+Palstojen välissä olevan tyhjän tilan leveys on mitassa
+\mitta{columnsep}, ja sen voi asettaa haluamakseen
+\komento{setlength}\-/ komennolla tai \paketti{geometry}\-/ paketin
+asetuksista (luku \ref{luku/sivun-mitat}). Oletusasetus on 35\,pt.
+Palstojen väliin saa myös pystyviivan, jonka leveys on mitassa
+\mitta{columnseprule}. Sen oletusarvo on nolla, eli pystyviivaa ei
+ladota.
+
+\komentoi{setlength}
+\mittai{columnsep}
+\mittai{columnseprule}
+\begin{koodilohkosis}
+\setlength{\columnsep}{6mm} % palstojen väli
+\setlength{\columnseprule}{.2mm} % pystyviivan leveys
+\end{koodilohkosis}
+
+\noindent
+Latex laskee automaattisesti palstan leveyden ja asettaa sen mittaan
+\mitta{columnwidth}. Tätä mittaa ei siis tarvitse eikä pidä itse
+asettaa, mutta sitä voi hyödyntää esimerkiksi taulukoiden tai kuvien
+sovittamisessa koko palstan levyiseksi. Käytännössä kahden palstan
+tilassa palstan leveys on mittojen \mitta{textwidth} ja
+\mitta{columnsep} erotus jaettuna kahdella. Tilannekohtainen rivin
+pituus on mitassa \mitta{linewidth}.
+
+\subsection{Palstaympäristö}
+\label{luku/multicol}
+
+Perus Latex osaa vain yhden ja kahden palstan tilan, ja ne ovat voimassa
+koko sivulla. Paketti \pakettictan{multicol} tuo käyttöön myös
+ympäristön \ymparisto{multicols}, jonka sisällä tietty palstamäärä on
+voimassa. Ympäristön avulla samallakin sivulla voi olla eri tavoin
+palstoitettua sisältöä. Esimerkki \ref{esim/multicols} havainnollistaa
+ympäristön käyttöä ja ladottua lopputulosta. Oleelliset tiedot ovat
+seuraavat:
+
+\ymparistoi{multicols}
+\begin{koodilohkosis}
+\begin{multicols}{palstamäärä}
+ ...
+\end{multicols}
+\end{koodilohkosis}
+
+\noindent
+Argumentti \koodi{palstamäärä} on kokonaisluku, joka ilmaisee, kuinka
+monelle palstalle ympäristön sisältö ladotaan. Palstojen korkeus
+pyritään tasaamaan automaattisesti, niin että kaikki palstat ovat yhtä
+korkeita. Käytännössä palstaympäristön viimeisen sivun viimeinen palsta
+jää hieman vajaaksi, mutta se on normaalia muutenkin. Jos käyttää
+ympäristön tähtiversiota \ymparisto{multicols*}, ei viimeisen sivun
+palstojen korkeuksia tasata, vaan ensin täytetään vasemmanpuoleinen
+palsta kokonaan, sitten seuraava jne.
+
+\begin{esimerkki*}
+ \ymparistoi{multicols}
+ \komentoi{noindent}
+
+\begin{koodilohko}
+\begin{multicols}{3} % kolme palstaa
+ \noindent Jukolan talo, eteläisessä Hämeessä, seisoo erään mäen
+ pohjoisella rinteellä, liki Toukolan kylää. Sen läheisin ympäristö on
+ kivinen tanner, mutta alempana alkaa pellot, joissa, ennenkuin talo
+ oli häviöön mennyt, aaltoili teräinen vilja. Peltojen alla on niittu,
+ apilaäyräinen, halkileikkaama monipolvisen ojan; ja runsaasti antoi se
+ heiniä, ennenkuin joutui laitumeksi kylän karjalle. Muutoin on talolla
+ avaria metsiä, soita ja erämaita, jotka, tämän tilustan ensimmäisen
+ perustajan oivallisen toiminnan kautta, olivat langenneet sille osaksi
+ jo ison jaon käydessä entisinä aikoina.
+\end{multicols}
+\end{koodilohko}
+ \begin{tulos}
+ \footnotesize
+ \setlength{\columnsep}{1em}
+ \setlength{\multicolsep}{0bp}
+ \begin{multicols}{3}
+ \noindent Jukolan talo, eteläisessä Hämeessä, seisoo erään mäen
+ pohjoisella rinteellä, liki Toukolan kylää. Sen läheisin ympäristö
+ on kivinen tanner, mutta alempana alkaa pellot, joissa, ennenkuin
+ talo oli häviöön mennyt, aaltoili teräinen vilja. Peltojen alla on
+ niittu, api\-la\-äyräi\-nen, halkileikkaama monipolvisen ojan; ja
+ runsaasti antoi se heiniä, ennenkuin joutui laitumeksi kylän
+ karjalle. Muutoin on talolla avaria metsiä, soita ja erämaita,
+ jotka, tämän tilustan ensimmäisen perustajan oivallisen toiminnan
+ kautta, olivat langenneet sille osaksi jo ison jaon käydessä
+ entisinä aikoina.
+ \end{multicols}
+ \end{tulos}
+
+ \caption{Palstojen toteutus \paketti{multicol}\-/ paketin
+ \ymparisto{multicols}\-/ ympäristön avulla. Teksti on Aleksis Kiven
+ \emph{Seitsemän veljestä} \=/romaanin alusta}
+ \label{esim/multicols}
+\end{esimerkki*}
+
+Ympäristölle voi antaa hakasulkeissa valinnaisen argumentin, joka voi
+sisältää mitä tahansa tekstiä tai koodia. Se on tarkoitettu otsikolle
+(\komento{section} ym.) tai muulle sisällölle, joka ladotaan ennen
+palstoja ja jonka täytyy päätyä samalle sivulle kuin palstasisällön
+alku.
+
+\ymparistoi{multicols}
+\begin{koodilohkosis}
+\begin{multicols}{palstamäärä}
+ [tekstiä tai koodia ennen palstoja]
+ ...
+\end{multicols}
+\end{koodilohkosis}
+
+\noindent
+Ennen palstaympäristöä ja sen jälkeen ladotaan mitan \mitta{multicolsep}
+suuruinen pystysuuntainen väli. Väliä ei kuitenkaan ladota, jos se
+sattuu sivunvaihdon kohdalle. Palstojen välissä oleva tyhjä tila
+asetetaan mitan \mitta{columnsep} avulla, ja väliin mahdollisesti
+ladottavan pystyviivan leveys on mitassa \mitta{columnseprule}. Tämän
+mitan oletusarvo on nolla, eli pystyviivaa ei ladota.
+
+\komentoi{setlength}
+\mittai{multicolsep}
+\mittai{columnsep}
+\mittai{columnseprule}
+\begin{koodilohkosis}
+\setlength{\multicolsep}{.5ex plus .2ex} % väli ennen ja jälkeen
+\setlength{\columnsep}{6mm} % palstojen väli
+\setlength{\columnseprule}{.2mm} % pystyviivan leveys
+\end{koodilohkosis}
+
+\noindent
+Oletuksena palstojen alareuna pyritään joka sivulla pitämään tarkasti
+samalla tasolla. Tämä toteutuu siten, että palstoilla olevia
+pystysuuntaisia välejä voidaan venyttää, jotta niiden viimeiset rivit
+saataisiin samalle tasolle. Tämä on yhdenmukainen sivujen
+tasaamiskäytännön kanssa, jota käsitellään luvussa
+\ref{luku/sivunvaihdot}. Palstojen alareunan tasaamisen ja
+pystysuuntaisten välien venyttämisen saa pois komennolla
+\komento{raggedcolumns}. Oletustilaan palataan komennolla
+\komento{flushcolumns}. Palstanvaihdon voi pakottaa tiettyyn kohtaan
+komennolla \komento{columnbreak}. Jos komento sijaitsee tekstikappaleen
+sisällä, palsta vaihtuu nykyisen rivin lopussa.
+
+Leijuvat osat (luku \ref{luku/leijuosat}) toimivat
+\ymparisto{multicols}\-/ ympäristössä hieman toisin kuin muualla.
+Leijuvien ympäristöjen tähdellisiä versioita kuten \ymparisto{table*} ja
+\ymparisto{figure*} ei koskaan ladota samalle sivulle kuin missä ne
+esiintyvät. Ensimmäinen mahdollinen paikka on seuraavan sivun yläosassa.
+
+Leijuvien osien sijoitteluun vaikuttavat tavalliset yhden palstan tilan
+asetukset kuten laskuri \laskuri{topnumber}, mitta \mitta{floatsep} ja
+komento \komento{topfraction}. \ymparisto{multicols}\-/ ympäristössä ei
+käytetä \koodi{dbl}\-/ alkuisia kahden palstan tilan laskureita, mittoja
+eikä komentoja, kuten \laskuri{dbltopnumber}, \mitta{dblfloatsep} ja
+\komento{dbltopfraction}. Lisätietoa leijuvien osien sijoittelusta on
+luvussa \ref{luku/leijuosat-sijoittelu}.
+
+\section{Lähdeluettelo ja lähdeviitteet}
+\label{luku/lähteet}
+
+Lähdeluettelossa mainittuihin teoksiin on tapana viitata muualta
+tekstistä, ja Latex osaa auttaa viittausten hallinnassa. Ajatus on se,
+että lähdeluettelo laaditaan tiettyjen komentojen avulla niin, että
+jokainen lähdeteos saa yksilöllisen tunnisteen. Muualta tekstistä
+viitataan lähdeteoksiin käyttämällä samoja tunnisteita, ja Latex osaa
+automaattisesti poimia lähdeluettelosta esimerkiksi teoksen tekijöiden
+nimet ja vuosiluvun.
+
+Lähdeviittauksiin ja lähdemerkintöihin on useita käytäntöjä, jotka
+vaihtelevat eri ammatti\-/\ ja tieteenaloilla, oppilaitoksilla tai
+julkaisijoilla. Tässä yhteydessä käsitellään melko vakiintuneita
+suomalaisia käytäntöjä, jotka kuvataan \emph{Kielitoimiston
+ oikeinkirjoitusoppaassa} \parencite{kt_oik}. Samalla käsitellään
+joitakin asetuksia, joilla kukin voi muokata viittausten ulkoasua omiin
+tarpeisiin sopivaksi.
+
+Latex sisältää lähdeluetteloiden ja \=/viittausten perustoiminnot, mutta
+niiden avulla ei saa yleisen suomalaisen käytännön mukaisia
+lähdeviittauksia. Siksi usein tarvitaan avuksi paketti, jolla
+viittausten ja lähdeluettelon ulkoasuun voi vaikuttaa. Ensin käsiteltävä
+paketti \paketti{natbib} (luku \ref{luku/natbib}) soveltuu
+perustarpeisiin ja lienee sopivin valinta useimmille kirjoittajille.
+Laajoja tieteellisiä teoksia kirjoittavan kannattanee opetella
+käyttämään monipuolista \paketti{biblatex}\-/pakettia (luku
+\ref{luku/biblatex}) ja ylläpitää yhteistä lähdeteosten tietokantaa,
+josta tarvittavat teokset poimitaan kunkin dokumentin lähdeluetteloon
+automaattisesti.
+
+\subsection{Peruskäyttöön (natbib)}
+\label{luku/natbib}
+
+Paketti \pakettictan{natbib} laajentaa Latexin lähdeviittausten
+perustoimintoja sen verran, että lähteisiin voidaan viitata teoksen
+tekijöiden nimen ja vuosiluvun avulla. Seuraava esimerkki
+havainnollistaa paketin käyttöönottoa ja asetuksia.
+
+\komentoi{usepackage}
+\pakettii{natbib}
+\komentoi{setcitestyle}
+\begin{koodilohkosis}
+\usepackage{natbib}
+\setcitestyle{authoryear,aysep={},notesep={: }}
+\end{koodilohkosis}
+
+\noindent
+Edellisessä esimerkissä viittaustyyli valitaan \komento{setcitestyle}\-/
+komennon argumentissa valitsimella \koodi{author\-year}
+(tekijä\--vuosi). Valitsimella \koodi{aysep} määritetään, mikä
+välimerkki ladotaan tekijän nimen ja vuosiluvun väliin. Tässä se
+jätetään tyhjäksi \koodi{\{\}}. \koodi{note\-sep}\-/ valitsimella
+asetetaan merkit, jotka ladotaan vuosiluvun ja sitä seuraavan
+huomautuksen kuten sivunumeroiden väliin; tässä tapauksessa määritettiin
+kaksoispiste ja väli \koodi{\{:~\}}, mutta pilkkukin on yleinen
+käytäntö. \komento{setcitestyle}\-/ komennon valitsimet erotetaan
+toisistaan pilkulla, eikä erotinpilkkujen ympärillä saa olla
+välilyöntejä. Lopputuloksena lähdemerkinnät näyttävät esimerkiksi
+seuraavanlaisilta:
+
+\komentoi{citet*}
+\begin{koodilohkosis}
+\citet*[27--29]{johdatus} % Viittaus teokseen ”johdatus”.
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Meikäläinen \& Teikäläinen (2020: 27--29)
+\end{tulossis}
+
+\noindent
+Lähdeluettelo kirjoitetaan \ymparistom{thebibliography}\-/ ympäristön ja
+\komentom{bibitem}\-/ komentojen avulla esimerkin
+\ref{esim/thebibliography} tavoin. Ympäristön aloittavan komennon
+(rivi~1) yhteydessä on argumentti \koodi{00}, jolla ei ole tässä
+yhteydessä merkitystä. Jos lähdeviittauksen tyylinä olisi
+\koodi{numbers} (eikä \koodi{author\-year}), lähdeluettelon teokset
+numeroitaisiin, ja silloin \ymparisto{thebibliography}\-/ ympäristön
+argumentti ilmaisee, kuinka leveän sisennyksen numeroidut teokset
+tarvitsevat. Argumentiksi voi kirjoittaa mitä tahansa merkkejä, ja Latex
+mittaa niiden leveyden. Kannattaa kirjoittaa leveitä numeroita kuten
+nollia (\koodi{0}) niin monta kappaletta kuin on numeroita suurimmassa
+lähdemerkinnän luvussa. Yksi nolla riittää, jos lähteitä on 1\==9
+kappaletta, kaksi jos lähteitä on kaksinumeroinen määrä eli 10\==99
+kappaletta jne.
+
+\begin{esimerkki*}
+ \ymparistoi{thebibliography}
+ \komentoi{bibitem}
+
+\begin{koodilohko}
+\begin{thebibliography}{00}
+
+\bibitem[Meikäläinen ym.(2020)Meikäläinen \& Teikäläinen]{johdatus}
+ Meikäläinen, Matti \& Teikäläinen, Teija (2020): Johdatus alkeiden
+ perusteisiin. Toinen painos. Kustantaja Oy.
+
+\bibitem[Itkonen(2019)]{typografia} Itkonen, Markus (2019): Typografian
+ käsikirja. Viides, tarkistettu painos. Typoteekki. Graafinen
+ suunnittelu Markus Itkonen Oy.
+
+\end{thebibliography}
+\end{koodilohko}
+ \caption{Lähdeluettelon kirjoittaminen \ymparisto{thebibliography}\-/
+ ympäristön ja \komento{bibitem}\-/ komentojen avulla.}
+ \label{esim/thebibliography}
+\end{esimerkki*}
+
+Komennolla \komento{bibitem} tehdään varsinaiset teosmerkinnät. Samalla
+määritetään teoksen yksilöllinen tunniste ja mitä tietoja
+lähdeviittauksissa näytetään. Yleinen muoto on seuraavanlainen:
+
+\komentoi{bibitem}
+\begin{koodilohkosis}
+\bibitem[lyhyt(vuosi)pitkä]{tunniste} Lähdeluettelon tekstit.
+\end{koodilohkosis}
+
+\noindent
+Valinnaisen argumentin aluksi kirjoitetaan lähdeviittauksen lyhyt
+merkintä, joka tulisi näkymään lähdeviittauksissa esimerkiksi muodossa
+''Meikäläinen ym.''. Heti sen perään kirjoitetaan sulkeissa teoksen
+vuosiluku ja sen perään vapaavalintainen lähdeviittauksen pitkä
+merkintä, joka näkyisi esimerkiksi tekstinä ''Meikäläinen \&
+Teikäläinen''. Vuosiluvun sulkeiden ympärillä ei saa olla välilyöntejä.
+
+Komennon pakollinen argumentti on kyseisen lähdeteoksen yksilöllinen
+tunniste, jonka avulla kyseiseen teokseen viitataan. Komennon
+argumenttien jälkeen kirjoitetaan samaan tekstikappaleeseen teksti, joka
+tulee näkymään lähdeluettelossa.
+
+Lähdeteoksiin viittaamiseen on useita eri komentoja, jotka eroavat
+toisistaan siinä, mitä tietoa lähdeviittauksessa näytetään ja onko
+lähdeviittaus tai sen osa sulkeissa vai ei. Taulukossa
+\ref{tlk/natbib-cite} on joitakin \paketti{natbib}\-/paketin
+viittauskomentoja sekä esimerkki viittauksen ulkoasusta. Kuviteltu
+esimerkkiteos on peräisin esimerkistä \ref{esim/thebibliography}.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\komento{#1}\komentoarg{\dots} & #2 \\}
+ \begin{tabular}{ll}
+ \toprule
+ \ots{Komento} & \ots{Esimerkki} \\
+ \midrule
+ \rivi{citet}{Meikäläinen ym. (2020)}
+ \rivi{citet*}{Meikäläinen \& Teikäläinen (2020)}
+ \rivi{citep}{(Meikäläinen ym. 2020)}
+ \rivi{citep*}{(Meikäläinen \& Teikäläinen 2020)}
+ \rivi{citealt}{Meikäläinen ym. 2020}
+ \rivi{citealt*}{Meikäläinen \& Teikäläinen 2020}
+ \rivi{citeauthor}{Meikäläinen ym.}
+ \rivi{citeauthor*}{Meikäläinen \& Teikäläinen}
+ \rivi{citeyear}{2020}
+ \rivi{citeyearpar}{(2020)}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{\paketti{natbib}\-/paketin lähdeviittauskomentoja}
+ \label{tlk/natbib-cite}
+}
+
+Lähdeluettelon ulkoasuun voi vaikuttaa mittojen \mittam{bibhang} ja
+\mittam{bibsep} avulla. Ensin mainittu on lähdemerkinnän vaakasuuntaisen
+riippuvan sisennyksen suuruus, ja jälkimmäinen on lähdemerkintöjen
+välinen pystysuuntainen tila. Mitat asetetaan \komento{setlength}\-/
+komennolla (luku \ref{luku/mitat}):
+
+\komentoi{setlength}
+\mittai{parindent}
+\mittai{bibhang}
+\mittai{bibsep}
+\begin{koodilohkosis}
+\setlength{\parindent}{1.1em} % tekstikappaleiden 1. rivin sisennys
+\setlength{\bibhang}{\parindent}
+\setlength{\bibsep}{.5ex plus .1ex minus .1ex}
+\end{koodilohkosis}
+
+\noindent
+Lähdemerkintöjen fonttiin voi vaikuttaa määrittelemällä uudelleen
+komennon \komentom{bibfont} ja sijoittamalla halutut fontti- tai muut
+komennot kyseisen komennon määritelmään.
+
+\komentoi{renewcommand}
+\komentoi{bibfont}
+\begin{koodilohkosis}
+\renewcommand{\bibfont}{\sffamily\small}
+\end{koodilohkosis}
+
+\noindent
+Oletuksena \ymparisto{thebibliography}\-/ ympäristö latoo
+lähdeluettelolle otsikon, ja otsikon teksti määräytyy kieliasetusten
+(luku \ref{luku/kieliasetukset}) ja dokumenttiluokan perusteella (luku
+\ref{luku/dokumenttiluokat}). Suomenkielisen lähdeluettelon otsikon voi
+määrittää dokumentin esittelyosassa seuraavan esimerkin tavoin.
+Esimerkissä hyödynnetään \komento{addto}\-/ komentoa, joka sisältyy
+\paketti{polyglossia}\-/{} ja \paketti{babel}\-/ paketteihin.
+
+\komentoi{addto}
+\komentoi{captionsfinnish}
+\komentoi{renewcommand}
+\komentoi{refname}
+\komentoi{bibname}
+\luokkai{article}
+\luokkai{book}
+\luokkai{report}
+\begin{koodilohkosis}
+\addto{\captionsfinnish}{%
+ \renewcommand{\refname}{Lähteet} % article-dokumenttiluokka
+ \renewcommand{\bibname}{Lähteet} % report- ja book-luokat
+}
+\end{koodilohkosis}
+
+\noindent
+On myös mahdollista määritellä koko komentosarja, joka suoritetaan
+lähdeluettelon otsikoinnin yhteydessä. Se tehdään määrittelemällä
+uudelleen komento \komentom{bibsection}.
+
+\komentoi{renewcommand}
+\komentoi{bibsection}
+\komentoi{setcounter}
+\laskurii{secnumdepth}
+\komentoi{section}
+\begin{koodilohkosis}
+\renewcommand{\bibsection}{%
+ \setcounter{secnumdepth}{-1}
+ \section{Lähteet}
+}
+\end{koodilohkosis}
+
+\noindent
+Edellisessä esimerkissä komennolla \komento{setcounter} määritetään,
+mille otsikkotasolle dokumentin otsikoiden eli lukujen numerointi yltää.
+Pieni arvo \mbox{(\koodi{-1})} käytännössä tarkoittaa, että seuraaviin
+otsikoihin ei tule numerointia; lähdeluettelon otsikkoon ei numerointia
+välttämättä haluta. Komento \komento{section} tekee itse otsikon.
+
+Jos ei halua, että \ymparisto{thebibliography}\-/ ympäristö tekee
+otsikon automaattisesti, voi \komento{bibsection}\-/ komennon määrittää
+tyhjäksi.
+
+\komentoi{renewcommand}
+\komentoi{bibsection}
+\begin{koodilohkosis}
+\renewcommand{\bibsection}{}
+\end{koodilohkosis}
+
+\noindent
+Tässä alaluvussa on käsitelty lähdeluettelon ja lähdeviitteiden
+tekemistä \paketti{natbib}\-/paketin toimintojen avulla. Paketti
+sisältää muitakin ominaisuuksia, joihin kannattaa tutustua paketin
+ohjekirjan avulla. On muun muassa mahdollista tehdä lähdeteoksista
+tietokanta Bibtex\-/järjestelmän avulla. Jos kuitenkin siihen suuntaan
+haluaa edetä, ei kannata käyttää \paketti{natbib}\-/pakettia eikä
+Bibtexiä vaan monipuolisempaa pakettia \paketti{biblatex}, jota
+käsitellään seuraavassa alaluvussa.
+
+\subsection{Vaativaan käyttöön (biblatex)}
+\label{luku/biblatex}
+
+Suurten lähde- ja kirjallisuusluetteloiden ylläpito voi olla aika
+työlästä: pitää jatkuvasti varmistaa, että kaikki viitatut teokset ovat
+luettelossa ja että luettelo on pilkulleen yhdenmukainen. Paketti
+\pakettictan{biblatex} on vastaus sellaisiin tarpeisiin.
+
+Ajatuksena on, että kaikki tiedonlähteet ja kirjallisuus kirjoitetaan
+tietokantaan, josta \paketti{biblatex}\-/paketin komennot hakevat tiedot
+automaattisesti. Kirjoittaja tai työryhmä voi ylläpitää yhtä
+kirjallisuustietokantaa, joka voi olla saatavilla oman laitoksen
+verkkopalvelimella tai julkisella verkkosivullakin. Dokumentin tekstissä
+viitataan teoksiin yksilöllisen tunnisteen avulla, ja pelkän viittauksen
+perusteella oikeat teokset ilmestyvät lähdeluetteloon automaattisesti
+aakkosjärjestyksessä ja yhdenmukaisessa muodossa. Yhtään tiedonlähdettä
+ei tarvitse kirjoittaa lopulliseen lähdeluetteloon käsin.
+
+\paketti{biblatex}\-/paketin käyttö vaatii hieman opettelua -- varsinkin
+jos on tarve muokata lähdeluettelon ja lähdeviittausten ulkoasua.
+Muutaman tiedonlähteen ylläpito on todennäköisesti paljon helpompaa ja
+nopeampaa niillä keinoilla, jotka on kuvattu luvussa \ref{luku/natbib}
+(\paketti{natbib}). Sen sijaan laajoja tieteellisiä artikkeleita
+kirjoittaville \paketti{biblatex} voi olla suuri apu, koska
+artikkeleissa on yleensä paljon lähteitä ja useissakin artikkeleissa
+viitataan yleensä samoihin lähteisiin.
+
+\subsubsection{Teostietokanta}
+
+Lähdeteosten tietokanta on erillinen tekstitiedosto, joka tavallisesti
+nimetään \koodi{bib}\-/päätteiseksi, esimerkiksi \koodi{teokset.bib}.
+Tiedosto koostuu \koodi{@}\=/merkillä ja teostyypin nimellä alkavista
+tietueista, joiden yleinen muoto on seuraavanlainen:
+
+\begin{koodilohkosis}
+@teostyyppi{tunniste,
+ author = {...},
+ title = "..."
+}
+\end{koodilohkosis}
+
+\noindent
+Teostyypin nimen jälkeen aaltosulkeiden sisään kirjoitetaan teoksen
+kaikki tiedot. Ne alkavat teoksen yksilöllisellä tunnisteella, jota
+käytetään lähdeviittauksissa. Tunnisteen jälkeen tulevat muut kentät.
+Eri kentät kuten \koodi{author} ja \koodi{title} erotetaan toisistaan
+pilkulla. Kentän nimi ja sen sisältö erotetaan toisistaan
+yhtäsuuruusmerkillä (\koodi{=}), ja kentän sisältö kirjoitetaan
+aaltosulkeiden tai lainausmerkkien sisään, kuten edellinen esimerkki
+näyttää.
+
+\begin{esimerkki*}
+\begin{koodilohko}
+@book{itkonen_typogr,
+ author = {Itkonen, Markus},
+ title = {Typografian käsikirja},
+ date = {2019},
+ edition = {5},
+ publisher = {Typoteekki. Graafinen suunnittelu Markus Itkonen Oy}
+}
+
+@incollection{likonen_teams,
+ author = {Likonen, Teemu and Riskilä, Kaisa},
+ title = {Verkkoyhteistyö Teams-ympäristössä},
+ editor = {Tammi, Tuomo and Horila, Mikko},
+ booktitle = {Oppimis- ja toimintaympäristöjen kehittäminen
+ harjoittelukouluissa II},
+ booksubtitle = {Tilat ja tekniikka pedagogisen kehittämisen tukena},
+ publisher = {E-norssi. Opettajankouluttajien yhteistyöverkosto},
+ date = {2020},
+ pages = {85-92},
+ url = {http://www.enorssi.fi/oppimisymparistojulkaisu2020/}
+}
+
+@article{likonen_tietokanta,
+ author = {Likonen, Teemu},
+ title = {Tietoa kantaan ja takaisin},
+ journaltitle = {Skrolli},
+ journalsubtitle = {Tietokonekulttuurin erikoislehti},
+ date = {2015},
+ volume = {2015},
+ number = {4},
+ pages = {52-55},
+ url = {https://skrolli.fi/numerot/2015-4/}
+}
+
+@online{ctan,
+ title = {Comprehensive TeX Archive Network},
+ shorttitle = {CTAN},
+ date = {1992/},
+ url = {https://www.ctan.org/}
+}
+\end{koodilohko}
+ \caption{Lähdeteosten tietokantatiedosto}
+ \label{esim/bib-tiedosto}
+\end{esimerkki*}
+
+Todellista käyttöä vastaava tietokanta tai sen osa on esimerkissä
+\ref{esim/bib-tiedosto}, jossa on neljä erityyppistä teostietuetta:
+\koodim{book}, \koodi{incollection}, \koodi{article} ja \koodi{online}.
+Ensin mainittu teostyyppi \koodi{book} sopii tavallisille kirjoille,
+joissa tietyt tekijät (\koodi{author}) vastaavat suunnilleen koko
+teoksen sisällöstä ja teoksella on jokin julkaisijataho
+(\koodi{publisher}).
+
+Teostyyppi \koodim{incollection} tarkoittaa esimerkiksi
+artikkelikokoelmaa, jonka yksittäiseen artikkeliin (\koodi{title}) ja
+sen kirjoittajaan (\koodi{author}) on tarkoitus viitata. Voidaan mainita
+myös artikkelin alku- ja loppusivut (\koodi{pages}). Kokoelmalla on
+toimittaja (\koodi{editor}) ja yhteinen nimi (\koodi{book\-title}).
+
+Tyyppi \koodim{article} sopii säännöllisesti julkaistavan aikakaus- tai
+muun lehden artikkeleihin. Viittauskohteena on yksittäinen artikkeli ja
+sen kirjoittaja. Julkaisutiedoissa mainitaan lehden nimi
+(\koodi{jour\-nal\-title}), julkaisukausi (\koodi{vol\-ume}), kauteen
+kuuluvan julkaisun järjestysnumero (\koodi{num\-ber}) sekä mahdollisesti
+artikkelin sivut (\koodi{pages}).
+
+Verkkolähteiden merkitsemiseen sopii \koodim{online}\-/ teostyyppi,
+joissa on tavanomaisten kenttien lisäksi ainakin verkko\-/osoite eli
+\koodi{url}\-/kenttä ja mahdollisesti viittauspäivä (\koodi{url\-date})
+osoittamassa, milloin viitatut tiedot olivat saatavilla.
+
+Teostyyppejä ja teoksiin liittyviä tietokenttiä on olemassa paljon
+muitakin. Niiden merkitystä ja käyttöä neuvotaan tarkemmin
+\paketti{biblatex}\-/paketin ohjeissa. Seuraavassa on kuitenkin pari
+huomiota tietokannan ja kenttien kieliopillisista asioista.
+
+Tietueissa joidenkin kenttien sisältö voi koostua useasta osasta kuten
+saman teoksen eri tekijöistä. Eri tekijöiden nimet erotetaan
+\koodi{author}- ja \koodi{editor}\-/kentissä toisistaan
+\koodi{and}\-/sanalla. Oletuksena \paketti{biblatex} katsoo, että
+tekijät ovat henkilöitä, ja käsittelee esimerkiksi etu- ja sukunimet
+tietyllä tavalla: jos mukana on pilkku, sitä ennen on sukunimi, ja
+etunimet tulevat pilkun jälkeen; jos pilkkua ei ole, etunimet ovat
+ensin, ja sukunimi on lopussa.
+
+Jos kuitenkin teoksen tekijänä on yritys tai yhteisö, täytyy sen nimi
+kirjoittaa kokonaan aaltosulkeisiin, jottei sitä tulkittaisi
+henkilönnimeksi. Tällaisten aaltosulkeiden sisällä voi käyttää
+\koodi{and}\-/ sanaa normaalisti, eikä sitä tulkita eri tekijöiden
+erottimeksi. Seuraavassa on näistä esimerkit:
+
+\begin{koodilohkosis}
+author = {Meikäläinen, Matti and Teikäläinen, Teija}
+author = {{Org. of Latex and Typography} and Meikäläinen, Matti}
+\end{koodilohkosis}
+
+\noindent
+Muunkinlaisia useasta osasta koostuvia kenttiä on olemassa.
+Asiasanakentän (\koodi{keywords}) eri sanat erotetaan toisistaan
+pilkulla, ja sivunumeroissa (\koodi{pages}) voi olla myös lukualueita,
+jotka ilmaistaan yhdysmerkillä~\mbox{(\koodi{-})}.
+
+\begin{koodilohkosis}
+keywords = {eri, sanoja, peräkkäin}
+pages = {15-19}
+\end{koodilohkosis}
+
+\noindent
+Teostietokantaan voi määrittää vakiosisältöisiä muuttujia käyttämällä
+\koodi{@string}\-/ rakennetta. Vakioihin voi sitten viitata
+teostietueiden kentistä esimerkin \ref{esim/bib-muuttujat} tavoin.
+Vakiot ovat hyödyllisiä silloin, kun sama kentän sisältö toistuu useissa
+teoksissa, kuten tässä esimerkissä sama tekijä (\koodi{author}) ja
+aikakauslehden nimi (\koodi{jour\-nal\-title}). Vakioita voi yhdistää
+saman kentän muuhun sisältöön käyttämällä \koodi{\#}\=/merkkiä, kuten
+esimerkin rivillä 13 on tehty.
+
+\begin{esimerkki*}
+\begin{koodilohko}
+@string{
+ oma = {Meikäläinen, Matti},
+ lehti = {Hienon hieno aikakauslehti}
+}
+
+@article{hieno_artikkeli,
+ author = oma,
+ journaltitle = lehti,
+ ...
+}
+
+@article{toinen_artikkeli,
+ author = oma # { and Teikäläinen, Teija},
+ journaltitle = lehti,
+ ...
+}
+\end{koodilohko}
+ \caption{Muuttujien käyttö ja \koodi{@string}\-/rakenne}
+ \label{esim/bib-muuttujat}
+\end{esimerkki*}
+
+\subsubsection{Käyttöönotto}
+
+\paketti{biblatex}\-/paketti otetaan käyttöön esimerkin
+\ref{esim/biblatex-käyttöönotto} rivien avulla. Mukana ovat myös paketit
+\paketti{polyglossia} ja \paketti{csquotes}. Jälkimmäinen sisältää
+lainausmerkkien käyttöön liittyvää logiikkaa (luku
+\ref{luku/lainausmerkit}), jota ilman \paketti{biblatex} ei saa eri
+kielten erilaisia lainausmerkkejä oikein vaan käyttää pelkästään
+amerikkalaisia (``~'').
+
+\begin{esimerkki*}
+ \komentoi{usepackage}
+ \pakettii{polyglossia}
+ \pakettii{csquotes}
+ \pakettii{biblatex}
+
+\begin{koodilohko}
+% Polyglossia tai babel on ladattava ennen biblatexia.
+\usepackage{polyglossia}
+
+% Kielikohtaiset lainausmerkit oikein csquoten avulla.
+\usepackage{csquotes}
+
+\usepackage[style=authoryear]{biblatex}
+\end{koodilohko}
+ \caption{\paketti{biblatex}\-/ paketin käyttöönotto ja asetuksia}
+ \label{esim/biblatex-käyttöönotto}
+\end{esimerkki*}
+
+Paketin asetuksissa käytetään valitsinta \koodi{style} ja sen asetusta
+\koodi{author\-year}, joka asettaa lähdeviittausten ja lähdeluettelon
+tyyliksi tekijän ja vuosiluvun. Se on yleinen käytäntö suomenkielisissä
+teksteissä. Vastaavia tyylejä ovat myös \koodi{author\-year-comp},
+\koodi{author\-year-ibid} ja \koodi{author\-year-icomp}, jotka lisäksi
+tiivistävät peräkkäisiä lähdeviittauksia, jos teoksen tekijä on sama.
+
+Numerointiin tai kirjainlyhenteisiin perustuvat lähdeluettelo\-/{} ja
+viittaustyylit ovat nimeltään \koodi{nu\-mer\-ic} ja
+\koodi{al\-pha\-bet\-ic}. Muitakin tyylejä on olemassa, mutta tämän
+oppaan esimerkeissä käsitellään tekijä--vuosi-tyyliä.
+
+Paketin omien lähdeluettelo\-/{} ja viittaustyylien lisäksi
+Latex\-/jakelupaketissa on todennäköisesti mukana myös ulkopuolisten
+tahojen tekemiä tyylejä. Tyylikokonaisuus nimeltä
+\pakettictan{biblatex-ext} laajentaa \paketti{biblatex}\-/ paketin
+tavallisten tyylien ominaisuuksia. Laajennettujen tyylien käyttäminen ei
+vaadi erillisen paketin lataamista, vaan tyylin saa käyttöön
+yksinkertaisesti vain kirjoittamalla sen nimen
+\paketti{biblatex}\-/paketin lataamisen yhteydessä. Laajennetut tyylit
+alkavat kirjaimilla \mbox{\koodi{ext-},} esimerkiksi
+\koodi{ext-author\-year} tai \koodi{ext-author\-year-comp}.
+
+Esimerkin \ref{esim/biblatex-käyttöönotto} komentojen lisäksi täytyy
+komennolla \komento{addbibresource} nimetä kaikki käyttöön otettavat
+teostietokantatiedostot. Komentoja ja tiedostoja voi olla useampiakin,
+ja tietokanta voi olla myös verkko\-/osoitteen takana oleva tiedosto.
+\komento{addbibresource}\-/ komennot täytyy kirjoittaa Latex\-/
+dokumentin esittelyosaan.
+
+\komentoi{addbibresource}
+\begin{koodilohkosis}
+\addbibresource{teokset.bib}
+\addbibresource{~/texmf/omat_kirjoitukset.bib}
+\addbibresource[location=remote]{http://osoite.netissä/yhteiset.bib}
+\end{koodilohkosis}
+
+\noindent
+Lähdeluettelo ladotaan dokumenttiin komennolla
+\komento{printbibliography}. Komennolle voi antaa valinnaisen
+argumentin, jonka valitsimilla vaikutetaan esimerkiksi lähdeluettelon
+otsikon tekstiin tai poistetaan automaattinen otsikointi kokonaan. On
+myös olemassa erilaisia lähdeteosten rajaamisvalitsimia, joiden avulla
+voi määrittää, mitä teoksia kyseiseen luetteloon halutaan. Näin voidaan
+esimerkiksi rajata painetut lähteet yhteen luetteloon, julkaisemattomat
+toiseen ja verkkolähteet kolmanteen.
+
+\komentoi{printbibliography}
+\begin{koodilohkosis}
+\printbibliography
+\printbibliography[title={Lähteet}]
+\printbibliography[heading=none, % Ei automaattista otsikkoa,
+ type=online] % ja rajataan vain online-tyyppisiin.
+\end{koodilohkosis}
+
+\noindent
+Lähdeluetteloon tulevat mukaan vain ne teokset, joihin on viitattu.
+Mitään ei siis näy, jos ei ole lähdeviittauksia. Seuraavassa alaluvussa
+käsitellään lähdeviittauskomentoja ja myös ''näkymätöntä''
+viittauskomentoa, jolla teoksia saadaan mukaan luetteloon ilman näkyvää
+viittausta.
+
+\subsubsection{Lähdeviittaukset}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\komento{#1}\komentoarg{\dots} & #2 \\}
+ \begin{tabular}{ll}
+ \toprule
+ \ots{Komento} & \ots{Esimerkki} \\
+ \midrule
+ \rivi{cite}{Meikäläinen 2020}
+ \rivi{textcite}{Meikäläinen (2020)}
+ \rivi{parencite}{(Meikäläinen 2020)}
+ \rivi{citeauthor}{Meikäläinen}
+ \rivi{citeyear}{2020}
+ \rivi{citetitle}{[teoksen nimi]}
+ \rivi{footcite}{Meikäläinen 2020 [alaviitteessä]}
+ \rivi{nocite}{[näkymätön viittaus]}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{\paketti{biblatex}\-/paketin lähdeviittauskomentoja}
+ \label{tlk/biblatex-cite}
+}
+
+Taulukkoon \ref{tlk/biblatex-cite} on koottu tavallisimpia
+\paketti{biblatex}\-/paketin viittauskomentoja. Komennoille voi antaa
+valinnaisen argumentin, jolla kerrotaan täsmentävää tietoa
+lähdeviittauksesta. Yleensä se on viitattavan teoksen sivunumero.
+Viittaus näkyy dokumentissa esimerkiksi seuraavalla tavalla:
+
+\komentoi{textcite}
+\begin{koodilohkosis}
+\textcite[27--29]{johdatus} % Viittaus teokseen ”johdatus”.
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Meikäläinen ja Teikäläinen (2020, s. 27--29)
+\end{tulossis}
+
+\noindent
+Jos halutaan sisällyttää lähdeluetteloon teoksia, joihin ei ole
+välttämättä viitattu, käytetään dokumentissa kerran ''näkymätöntä''
+viittauskomentoa \komento{nocite}. Sille annetaan argumentiksi
+tunnisteet niistä teoksista, jotka halutaan mukaan luetteloon.
+Argumentti~\koodi{*} (tähti) valitsee kaikki teokset.
+
+\komentoi{nocite}
+\begin{koodilohkosis}
+\nocite{meikäläinen, teikäläinen} % Nämä teokset mukaan.
+\nocite{*} % Kaikki mukaan.
+\end{koodilohkosis}
+
+\subsubsection{Lähdetiedostojen kääntäminen}
+
+Latexin kääntäjäohjelmat Lualatex tai Xelatex eivät yksinään riitä,
+sillä teostietokanta ei ole tavallinen Latex\-/muotoinen tiedosto.
+Tarvitaan myös Latex\-/jakelun mukana tulevaa komentoa \koodi{biber},
+joka käsittelee teostietokantaan liittyviä tiedostoja. Lopulta
+Latex\-/kääntäjääkin täytyy kutsua kaksi kolme kertaa, jotta kaikki
+ristiviitteet saadaan kuntoon. Komentojen suoritusjärjestys on
+seuraavanlainen:
+
+\begin{koodilohkosis}
+lualatex teksti.tex
+biber teksti.bcf
+lualatex teksti.tex
+lualatex teksti.tex
+\end{koodilohkosis}
+
+\noindent
+Edellisen esimerkin komennoissa voi tiedoston nimistä jättää päätteet
+pois (\koodi{.tex}, \koodi{.bcf}). \koodi{lualatex}\-/ ohjelman paikalla
+voi olla myös \koodi{xelatex}. Kääntäminen on vielä helpompaa, kun
+käyttää \koodi{latexmk}\-/ ohjelmaa (luku \ref{luku/latexmk}), joka osaa
+automaattisesti suorittaa myös \koodi{biber}\-/ ohjelman ja tarvittavat
+uudelleen kääntämiset. Yksi komento riittää:
+
+\begin{koodilohkosis}
+latexmk -lualatex teksti.tex % tai: -xelatex
+\end{koodilohkosis}
+
+\subsubsection{Lähdeluettelon mittoja}
+
+Lähdeluettelon ulkoasuun voi vaikuttaa muutaman eri mitan avulla, joista
+esitellään tässä yhteydessä vain osa. Lähdemerkinnän riippuvan
+sisennyksen suuruus määräytyy mitan \mittam{bibhang} avulla. Yleensä
+lienee sopivaa asettaa se samaksi kuin tekstikappaleiden ensimmäisen
+rivin sisennys \mitta{parindent}.
+
+\komentoi{setlength}
+\mittai{parindent}
+\mittai{bibhang}
+\begin{koodilohkosis}
+\setlength{\parindent}{1.1em} % tekstikappaleiden 1. rivin sisennys
+\setlength{\bibhang}{\parindent}
+\end{koodilohkosis}
+
+\noindent
+Mitta \mitta{bibitemsep} on lähdemerkintöjen välinen pystysuuntainen
+tila. \mittamargin{bibitemsep} Sen avulla voi harventaa lähdeluetteloa,
+jolloin lähdemerkinnät erottuvat paremmin toisistaan. Mitan
+\mittam{bibnamesep} avulla voi tehdä suuremman pystysuuntaisen välin
+lähdemerkintöjen väliin silloin, kun teoksen tekijä vaihtuu
+(\koodi{author} tai \koodi{editor}). Toisin sanoen tämän mitan avulla
+voi ryhmitellä saman tekijän teokset tiiviimmin yhteen ja jättää väliä
+seuraavan tekijän teoksiin. Vastaavanlainen mitta on
+\mittam{bibinitsep}, jota käytetään silloin, kun lähdemerkinnän
+aloittava kirjain vaihtuu. Tämän avulla voi ryhmitellä lähdemerkinnät
+aakkosittain eli tehdä suuremman välin aina lähdemerkinnän alkukirjaimen
+vaihtuessa.
+
+\komentoi{setlength}
+\mittai{bibitemsep}
+\mittai{bibnamesep}
+\mittai{bibinitsep}
+\begin{koodilohkosis}
+\setlength{\bibitemsep}{.5ex plus .1ex minus .1ex}
+\setlength{\bibnamesep}{1em plus .2ex minus .1ex}
+\setlength{\bibinitsep}{2em plus .2ex minus .1ex}
+\end{koodilohkosis}
+
+\subsubsection{Muita asetuksia}
+
+Lähdemerkintöjen fonttiin voi vaikuttaa määrittelemällä uudelleen
+komennon \komentom{bibfont} ja sijoittamalla halutut fontti- tai muut
+komennot kyseisen komennon määritelmään.
+
+\komentoi{renewcommand}
+\komentoi{bibfont}
+\begin{koodilohkosis}
+\renewcommand{\bibfont}{\sffamily\small}
+\end{koodilohkosis}
+
+\noindent
+Lähdemerkinnät itsessään muodostetaan automaattisesti tiettyjen
+tyyliasetusten perusteella. Omiakin tyylejä voi tehdä, mutta yleensä
+riittää vain yksittäisen asetusten muuttaminen. Niistä käsitellään tässä
+yhteydessä muutama. Asetusten muuttamiseen tarvitaan yleensä
+\paketti{biblatex}\-/ paketin omia asetuskomentoja.
+
+Lähdeluettelon nimet näkyvät oletusasetuksilla siten, että teoksen
+ensimmäisen tekijän sukunimi mainitaan ensin (luettelon
+aakkosjärjestyksen vuoksi) mutta saman teoksen muiden tekijöiden etunimi
+mainitaan ensin. Tekijöiden nimet näkyvät siis seuraavalla tavalla:
+''Meikäläinen, Matti ja Teija Teikäläinen''. Suomessa on kuitenkin
+tapana kirjoittaa kaikki nimet samalla tavalla ja mainita sukunimi aina
+ensin. Tämä saadaan toteutettua seuraavilla komennolla:
+
+\komentoi{DeclareNameAlias}
+\begin{koodilohkosis}
+\DeclareNameAlias{default} {family-given}
+\DeclareNameAlias{sortname}{family-given}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Meikäläinen, Matti ja Teikäläinen, Teija (2020). --~--
+\end{tulossis}
+
+\noindent
+Saman teoksen eri tekijöiden nimet erotetaan oletuksena toisistaan
+pilkuilla paitsi kahden viimeisen nimen välissä on \textit{ja}-sana.
+Usein on kuitenkin tapana käyttää \&\=/merkkiä ainakin lähdeluettelossa.
+Seuraavat esimerkkikomennot asettavat lähdeluettelon kaikkien nimien
+erottimeksi \&\=/merkin.
+
+\komentoi{DeclareDelimFormat}
+\begin{koodilohkosis}
+\DeclareDelimFormat[bib]{multinamedelim}{\space\&\space}
+\DeclareDelimFormat[bib]{finalnamedelim}{\space\&\space}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Meikäläinen, Matti \& Teikäläinen, Teija \& Tutkija, Tuija (2020).
+ --~--
+\end{tulossis}
+
+\noindent
+Erotinmerkkiasetuksen nimi \koodi{multi\-name\-delim} tarkoittaa muiden
+kuin kahden viimeisen tekijän nimen välissä olevaa erotinta. Kahden
+viimeisen nimen erotin määritellään asetuksella
+\koodi{final\-name\-delim}.
+
+Edellisten esimerkkikomentojen valinnainen argumentti \koodi{bib}
+tarkoittaa, että vaikutetaan vain lähdeluetteloon. Argumentti voi olla
+myös esimerkiksi \koodi{cite}, \koodi{textcite} tai \koodi{parencite},
+jolloin vaikutetaan samannimisillä komennoilla tehtyihin
+lähdeviittauksiin: \komento{cite}, \komento{textcite} ja
+\komento{parencite}. Katso lähdeviittauskomennot taulukosta
+\ref{tlk/biblatex-cite}. Seuraava esimerkki vaihtaa
+\komento{parencite}\-/ komentoon asetuksen, niin että kahden viimeisen
+henkilön nimen väliin ladotaan \&\=/merkki. Oletuksena viittauksissa
+käytetään \textit{ja}\-/sanaa.
+
+\komentoi{DeclareDelimFormat}
+\begin{koodilohkosis}
+\DeclareDelimFormat[parencite]{finalnamedelim}{\space\&\space}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ (Meikäläinen, Teikäläinen \& Tutkija 2020)
+\end{tulossis}
+
+\noindent
+Useiden saman teoksen tekijöiden luettelot lyhennetään automaattisesti
+esimerkiksi muotoon ''Meikäläinen et~al.'', ja lyhentämisen säännöt
+määritellään tiettyjen \koodi{max}- ja \koodi{min}\-/alkuisten paketin
+valitsimien avulla. Lähdeluettelossa teoksen tekijäluetteloon
+vaikutetaan valitsimilla \koodi{max\-bib\-names} ja
+\koodi{min\-bib\-names}, kun taas lähdeviittausten tekijäluetteloon
+vaikutetaan valitsimilla \koodi{max\-cite\-names} ja
+\koodi{min\-cite\-names}. Asetukset toimivat siten, että jos
+enimmäismäärä (max) ylittyy, typistetään tekijäluettelo vähimmäismäärään
+(min) ja lisätään ilmaus ''et al.'' tms.
+
+Tekijäluetteloa ei kuitenkaan välttämättä lyhennetä, jos luettelosta
+tulisi täsmälleen samanlainen kuin jollakin toisella teoksella. Tähän
+asiaan puolestaan vaikutetaan valitsimella \koodi{unique\-list}, joka on
+oletuksena päällä viittaustyylissä \koodi{author\-year}.
+
+\komentoi{usepackage}
+\pakettii{biblatex}
+\begin{koodilohkosis}
+\usepackage[style=authoryear, maxbibnames=99, minbibnames=3,
+ maxcitenames=3, mincitenames=1, uniquelist=true]{biblatex}
+\end{koodilohkosis}
+
+\noindent
+Kun halutaan näyttää lähdeluettelossa vain tekijän etunimen alkukirjain
+eikä koko etunimeä, käytetään paketin valitsinta \koodi{given\-inits}.
+
+\komentoi{usepackage}
+\pakettii{biblatex}
+\begin{koodilohkosis}
+\usepackage[…, giveninits]{biblatex}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Meikäläinen, M. (2020). -- --
+\end{tulossis}
+
+\noindent
+Lähdeluettelossa näytetään teoksen tekijän nimen kohdalla ajatusviiva,
+jos tekijä on sama kuin luettelon edelliselläkin teoksella. Mikäli tätä
+(sinänsä yleistä) käytäntöä ei haluta, täytyy käyttää paketin asetusta
+\koodi{dash\-ed=\katk false}.
+
+\komentoi{usepackage}
+\pakettii{biblatex}
+\begin{koodilohkosis}
+\usepackage[…, dashed=false]{biblatex}
+\end{koodilohkosis}
+
+\noindent
+Joskus on tapana latoa lähdeluettelossa tekijöiden nimet esimerkiksi
+pienversaalilla, jotta ne erottuvat luettelosta paremmin. Tällainen
+muutos vaatii, että lähdeluettelon latomisen yhteydessä määritellään
+uudelleen henkilön nimiin liittyvät latomiskomennot
+\komento{mkbibnamefamily}, \komento{mkbibnamegiven},
+\komento{mkbibnameprefix} ja \komento{mkbibnamesuffix}. Se saadaan
+automaattiseksi seuraavilla komennoilla:
+
+\komentoi{AtBeginBibliography}
+\komentoi{mkbibnamefamily}
+\komentoi{mkbibnamegiven}
+\komentoi{mkbibnameprefix}
+\komentoi{mkbibnamesuffix}
+\begin{koodilohkosis}
+\AtBeginBibliography{%
+ \renewcommand{\mkbibnamefamily}[1]{\textsc{#1}}
+ \renewcommand{\mkbibnamegiven} [1]{\textsc{#1}}
+ \renewcommand{\mkbibnameprefix}[1]{\textsc{#1}}
+ \renewcommand{\mkbibnamesuffix}[1]{\textsc{#1}}
+}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \textsc{Meikäläinen}, \textsc{Matti} \& \textsc{Teikäläinen},
+ \textsc{Teija} (2020). -- --
+\end{tulossis}
+
+\noindent
+Lähdeluettelon eri osien erottimena on yleensä piste. Joskus kuitenkin
+tekijöiden nimien ja vuosiluvun jälkeen halutaan kaksoispiste. Se
+saadaan toteutettua seuraavalla komennolla:
+
+\komentoi{DeclareDelimFormat}
+\begin{koodilohkosis}
+\DeclareDelimFormat[bib]{nametitledelim}{\addcolon\space}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Meikäläinen, Matti (2020): -- --
+\end{tulossis}
+
+\noindent
+Oletuksena \paketti{biblatex} kursivoi \koodi{book}\-/ tyyppisten
+teosten nimen (\koodi{title}). Sen sijaan artikkelikokoelmissa
+(\koodi{incollection}) ja aikakauslehdissä (\koodi{article})
+kursivoidaan julkaistun kokoelman nimi (\koodi{book\-title}) ja
+aikakauslehden nimi (\koodi{jour\-nal\-title}). Näissä teostyypeissä
+viitatun artikkelin nimi (\koodi{title}) kirjoitetaan lainausmerkkeihin.
+Käytäntö tuntuu järkevältä, sillä kursivoituna on aina julkaistu
+kokonainen teos eikä sen osa. Käytännössähän tiedonlähde joudutaan
+hakemaan teoksen nimen perusteella. Joku voi silti haluta muuttaa näiden
+ulkoasua ja esimerkiksi kursivoida aina viittauksen kohteena olevan
+artikkelin. Seuraavassa on esimerkkikomennot edellä mainittujen
+lähdeluettelon kenttien muuttamiseen.
+
+\komentoi{DeclareFieldFormat}
+\begin{koodilohkosis}
+\DeclareFieldFormat[article,incollection]{title}{\emph{#1}}
+\DeclareFieldFormat[article]{journaltitle}{#1}
+\DeclareFieldFormat[incollection]{booktitle}{#1}
+\end{koodilohkosis}
+
+\noindent
+Edellä olevissa esimerkkikomennoissa on valinnaisena argumenttina ne
+teostyypit, joihin halutaan vaikuttaa. Jos valinnaisen argumentin jättää
+pois, vaikutetaan kaikkiin teostyyppeihin, ellei tarkempaa
+teostyyppikohtaista määritelmää ole olemassa. Ensimmäinen pakollinen
+argumentti on kentän nimi teostietokannassa, ja toinen pakollinen
+argumentti on sisältö, joka ladotaan lähdemerkintään kyseisen tiedon
+kohdalle. Teostietokannasta tulevan kentän sisältö on parametrissa
+\koodi{\#1}.
+
+Mikäli haluaa jonkin teoksen tiedon lainausmerkkeihin tai sulkeisiin,
+kannattaa käyttää komentoa \komento{mkbibquote} tai
+\komento{mkbibparens}. Ne ymmärtävät ottaa huomioon eri kielten
+lainausmerkkikäytännöt ja mahdolliset sisäkkäiset sulkeet.
+
+\komentoi{DeclareFieldFormat}
+\komentoi{mkbibquote}
+\begin{koodilohkosis}
+\DeclareFieldFormat[incollection]{booktitle}{\mkbibquote{#1}}
+\end{koodilohkosis}
+
+\noindent
+Oletuksena teoksen vuosiluku tai muu päiväys ladotaan lähdeluetteloon
+sulkeissa. Joissakin lähdeluettelokäytännöissä sulkeita ei kuitenkaan
+ole, joten seuraavaksi käsitellään keino sulkeiden poistamiseen.
+Tavallisessa \paketti{biblatex}\-/paketin lähdeluettelotyylissä
+\koodi{author\-year} ei ole omaa asetusta teoksen päiväyksen ulkoasun
+muuttamiseen, mutta jos käyttää tyyliä \koodi{ext-author\-year} (tms.),
+sekin puute korjaantuu, ja voi käyttää \koodi{bib\-label\-date}\-/
+asetusta.
+
+\komentoi{usepackage}
+\pakettii{biblatex}
+\komentoi{DeclareFieldFormat}
+\begin{koodilohkosis}
+\usepackage[style=ext-authoryear]{biblatex}
+
+\DeclareFieldFormat{biblabeldate}{#1}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Meikäläinen, Matti 2020. -- --
+\end{tulossis}
+
+\noindent
+Artikkelikokoelmissa (teostyyppi \koodi{incollection}) mainitaan
+oletuksena kokoelman nimi ja toimittajat seuraavassa muodossa:
+''Teoksessa: \textit{Hieno artikkelikokoelma.} Toim. Kirjailija,
+Kaisa''. Ensin siis mainitaan julkaisun nimi ja sen jälkeen toimittajien
+nimet. Suomessa on tapana kirjoittaa nämä tiedot toisinpäin ja laittaa
+toimittajarooli sulkeisiin. Tällaiset asetukset saa käyttämällä tyyliä
+\koodi{ext-author\-year} (tms.), paketin asetusta
+\koodi{in\-name\-before\-title=\katk true} ja seuraavia komentoja:
+
+\komentoi{usepackage}
+\pakettii{biblatex}
+\komentoi{DeclareFieldFormat}
+\komentoi{DeclareDelimFormat}
+\komentoi{mkbibparens}
+\begin{koodilohkosis}
+\usepackage[style=ext-authoryear, innamebeforetitle=true]{biblatex}
+
+\DeclareFieldFormat{editortype}{\mkbibparens{#1}}
+\DeclareDelimFormat{editortypedelim}{\addspace}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ -- -- Teoksessa: Kirjailija, Kaisa (toim.). \textit{Hieno
+ artikkelikokoelma}. -- --
+\end{tulossis}
+
+\noindent
+Lähdeviittauksissa vuosiluvun ja sivunumeroiden välissä käytetään
+toisinaan pilkkua ja toisinaan kaksoispistettä. Sivunumeroiden
+yhteydessä voi olla lyhenne ''s.'' tai se voidaan jättää pois.
+Seuraavilla komennoilla vaikutetaan näihin asetuksiin:
+
+\komentoi{DeclareFieldFormat}
+\komentoi{DeclareDelimFormat}
+\komentoi{textcite}
+\begin{koodilohkosis}
+\DeclareFieldFormat{postnote}{#1} % Lyhenne ”s.” pois.
+\DeclareDelimFormat{postnotedelim}{\addcolon\space} % Kaksoispiste.
+
+\textcite[15--16]{tunniste} toteaa artikkelissaan -- --
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Meikäläinen (2020: 15--16) toteaa artikkelissaan -- --
+\end{tulossis}
+
+\noindent
+Kun saman teoksen usean tekijän luettelo lyhennetään, käytetään
+oletuksena latinankielistä ilmausta pois jäävien nimien tilalla:
+''Meikäläinen et al.''. Ilmauksen voi muuttaa suomenkieliseksi
+seuraavalla komennolla:
+
+\komentoi{DefineBibliographyStrings}
+\begin{koodilohkosis}
+\DefineBibliographyStrings{finnish}{
+ andothers = {ym.},
+}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Meikäläinen ym. (2020)
+\end{tulossis}
+
+\noindent
+\pakettictan{biblatex}\-/ paketti sisältää valtavan paljon asetuksia ja
+mahdollisuuksia lähdeluettelon ja \=/viitteiden ulkoasun säätämiseen.
+Esimerkiksi komennolla \komento{DeclareBibliographyDriver} voi ottaa
+täysin haltuun, miten tietty teostyyppi ladotaan lähdeluetteloon.
+Komennolla \komento{DeclareSortingTemplate} voi määritellä omia
+aakkostustapoja. Lisätietoa saa paketin ohjekirjasta.
+
+\section{Asiahakemistot}
+\label{luku/asiasanat}
+
+Asiahakemistot ovat asiasanojen eli tärkeiden käsitteiden tai
+henkilöiden luetteloita, ja ne ovat yleensä tietokirjan viimeisillä
+sivuilla. Kunkin hakemiston asiasanat ovat aakkosjärjestyksessä, ja
+jokaisen sanan perässä luetellaan sivunumerot, joilla kyseistä asiaa
+käsitellään. Asiahakemistojen tarkoituksena on helpottaa tiedon
+löytämistä. Tämän oppaan luku \enquote{\nameref{luku/asiahakemisto}}
+alkaa sivulta \pageref{luku/asiahakemisto}.
+
+Latex tarvitsee asiahakemistojen tekemiseen paketin. Niitä tehty
+useampia, mutta parhaita taitavat olla \pakettictan{indextools} ja
+\pakettictan{imakeidx}. Ne ovat käytännössä lähes sama paketti:
+\paketti{indextools} perustuu \paketti{imakeidx}\-/ pakettiin ja korjaa
+joitakin sen puutteita.
+
+\begin{esimerkki*}
+ \komentoi{documentclass}
+ \komentoi{index}
+ \komentoi{makeindex}
+ \komentoi{printindex}
+ \komentoi{usepackage}
+ \luokkai{article}
+ \pakettii{indextools}
+ \ymparistoi{document}
+
+\begin{koodilohko}
+\documentclass{article}
+\usepackage{indextools}
+\makeindex
+
+\begin{document}
+
+\index{erilaisia} \index{asiasanoja}
+
+...
+
+\printindex
+
+\end{document}
+\end{koodilohko}
+ \caption{Asiahakemistojen toteutuksen perusteet}
+ \label{esim/asiasanat-perus}
+\end{esimerkki*}
+
+Asiahakemiston toteutuksen perusajatus on yksinkertainen: Lähdetiedoston
+alussa komennolla \komento{makeindex} määritellään asiahakemistot.
+Dokumentin sisältösivuilla \komento{index}\-/ komennolla lisätään
+haluttuja asiasanoja hakemistoihin. Dokumentin lopussa komennolla
+\komento{printindex} ladotaan varsinaiset hakemistot. Näitä komentoja
+käsitellään tarkemmin erillisissä alaluvuissa, mutta esimerkissä
+\ref{esim/asiasanat-perus} ovat perusasiat tiiviisti.
+
+\subsection{Asiahakemistojen määrittely}
+\label{luku/asiasanat-määrittely}
+
+Ennen asiasanojen ja \=/hakemistojen käyttöä täytyy hakemistot
+määritellä. Yksinkertaisimmillaan määrittelyksi riittää pelkkä yksi
+\komento{makeindex}\-/ komento lähdedokumentin esittelyosassa, kuten
+esimerkissä \ref{esim/asiasanat-perus} on tehty. Jos haluaa vaikuttaa
+asetuksiin tai jos dokumenttiin tarvitaan useampia asiahakemistoja,
+täytyy tietää \komento{makeindex}\-/ komennosta enemmän. Tässä luvussa
+käsitellään \komento{makeindex}\-/ komennon muita ominaisuuksia
+pakettien \paketti{indextools} ja \paketti{imakeidx} näkökulmasta.
+Komennolla vaikutetaan yksittäisen hakemiston ominaisuuksiin. Yleisiä,
+kaikkien hakemistojen latomiseen liittyviä asetuksia käsitellään luvussa
+\ref{luku/asiasanat-asetukset}.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\koodi{#1} & #2 \\}
+ \begin{tabularx}{\linewidth}{lL}
+ \toprule
+ \ots{Valitsin} & \ots{Merkitys} \\
+ \midrule
+ \rivi{name}{asiahakemiston tekninen nimi}
+ \rivi{title}{asiahakemistolle ladottava otsikko}
+ \rivi{intoc}{sisällysluetteloon lisääminen}
+ \rivi{columns}{asiahakemiston sarakkeiden lukumäärä}
+ \rivi{columnsep}{asiahakemiston sarakkeiden väli (mitta)}
+ \rivi{columnseprule}{pystyviiva sarakkeiden väliin}
+ \rivi{program}{asiahakemiston tekemisestä vastaava ohjelma:
+ \koodi{makeindex} (oletus), \koodi{xindy} ym.}
+ \rivi{options}{ohjelman komentorivin valitsimia}
+ \bottomrule
+ \end{tabularx}
+}{
+ \caption{\komento{makeindex}\-/ komennon valitsimia}
+ \label{tlk/makeindex-valitsimia}
+}
+
+\komento{makeindex}\-/ komennolle voi antaa yhden valinnaisen
+argumentin, joka voi sisältää useita pilkulla toisistaan erotettuja
+valitsimia ja niiden arvoja. Valitsimia on koottu taulukkoon
+\ref{tlk/makeindex-valitsimia}.
+
+Valitsin \koodi{name} on asiahakemiston tekninen nimi, jota käytetään
+Latexissa sisäisesti. Valitsinta ei tarvitse käyttää, jos tarvitaan vain
+yksi asiahakemisto. Tällöin nimeksi tulee sama kuin Latex\-/
+lähdedokumentin eli tiedoston nimi. Jos asiahakemistoja tarvitaan
+useita, on järkevää nimetä jokainen erikseen \koodi{name}\-/ valitsimen
+avulla. Seuraavassa esimerkissä määritellään kolme eri hakemistoa, jotka
+voisivat olla Latexin komennoille, mitoille ja laskureille:
+
+\komentoi{makeindex}
+\begin{koodilohkosis}
+\makeindex[name=komennot, title=Komennot, columns=2, intoc]
+\makeindex[name=mitat, title=Mitat, columns=2, intoc]
+\makeindex[name=laskurit, title=Laskurit, columns=2, intoc]
+\end{koodilohkosis}
+
+\noindent
+\komento{makeindex}\-/ komennon valitsin \koodi{title} antaa otsikon
+hakemistolle, joka ladotaan \komento{printindex}\-/ komennolla (luku
+\ref{luku/asiasanat-asetukset}). Jos \koodi{title}\-/ valitsinta ei ole
+annettu, otsikko tulee komennosta \komento{indexname}, joka puolestaan
+määräytyy kieliasetusten perusteella (luku \ref{luku/kieliasetukset}).
+Se on \paketti{polyglossia}\-/ kielipaketissa suomen kieliasetuksilla
+''\indexname''.
+
+Jos valitsin \koodi{intoc} on mukana, kyseinen asiahakemisto eli sen
+otsikko lisätään myös sisällysluetteloon. Valitsimella \koodi{columns}
+asetetaan hakemiston sarakkeiden lukumäärää ja valitsimella
+\koodi{columnsep} mitta, joka on sarakkeiden välinen tyhjä tila.
+Sarakkeiden väliin saa pystyviivan antamalla valitsimen
+\koodi{columnseprule}. Teknisesti sarakkeet toteutetaan
+\paketti{multicol}\-/ paketin avulla, joten sen paketin mitat ovat
+käytettävissä myös asiahakemistojen latomisessa. Katso lisätietoa
+sarakkeista ja \paketti{multicol}\-/ paketista luvusta
+\ref{luku/multicol}.
+
+Asiahakemiston järjestelystä vastaa erillinen tietokoneohjelma, joka
+suoritetaan automaattisesti lähdedokumentin kääntämisen yhteydessä.
+Ohjelmalle on olemassa pari vaihtoehtoa, ja sen voi valita valitsimella
+\koodi{program}. Tärkeimmät vaihtoehdot ovat
+\koodi{makeindex}\footnote{\koodi{program=\katk makeindex} on
+ oletusasetus, mutta yleisen oletusasetuksen voi vaihtaa paketin
+ lataamisen yhteydessä. Katso luku \ref{luku/asiasanat-asetukset}.} ja
+\koodi{xindy}, joka käytännössä suorittaa \koodi{texindy}\-/ nimisen
+ohjelman. Näillä ohjelmilla on omat ohjekirjansa, joita pääsee lukemaan
+GNU/\katk Linux\-/ järjestelmissä \koodi{man}\-/ komennolla. Jos käyttää
+vaihtoehtoa \koodi{program=\katk xindy}, täytyy Latexin kääntäjälle
+(\koodi{lualatex} tai \koodi{xelatex}) antaa komentorivivalitsin
+\koodi{\=/shell-escape}, joka kytkee päälle erään
+lisäominaisuuden.\footnote{Lisätietoa \koodi{tex}\-/ komennon
+ ohjekirjasta, komennolla \koodi{man tex}.}
+
+Valitsimella \koodi{options} annetaan edellä mainitulle ohjelmalle
+komentorivivalitsimet. Tätä tarvitaan lähinnä silloin, kun kirjoittaja
+on tehnyt oman tyylitiedoston tai muita erikoisempia asetuksia
+asiahakemistolle. Varsinkin \koodi{xindy} on monipuolinen ohjelma, jonka
+toimintaan voi vaikuttaa monella tavalla. Lisätietoa saa
+\koodi{makeindex}\-/{} ja \koodi{xindy}\-/ ohjelmien ohjekirjoista.
+
+\subsection{Asiasanojen lisääminen}
+\label{luku/asiasanat-lisääminen}
+
+Asiasanat lisätään komennolla \komento{index}, joka sijoitetaan
+lähdedokumentissa juuri siihen kohtaan, jossa kyseistä asiaa
+käsitellään. Komento itsessään ei lado mitään; se vain kirjaa asiasanan
+ja sivunumeron muistiin. Komentoa käytetään esimerkiksi seuraavalla
+tavalla:
+
+\komentoi{index}
+\begin{koodilohkosis}
+Yhteen \index{kirjainperhe} kirjainperheeseen kuuluu tavallisesti
+useita \index{kirjainleikkaus} leikkauksia.
+\end{koodilohkosis}
+
+\noindent
+\komento{index}\-/ komennolle voi antaa yhden valinnaisen argumentin.
+Sitä tarvitaan silloin, kun asiasana halutaan lisätä tiettyyn,
+määrittelyn yhteydessä \koodi{name}\-/ valitsimella nimettyyn
+hakemistoon (luku \ref{luku/asiasanat-määrittely}). Jos esimerkiksi
+dokumentissa on määritelty asiahakemisto
+\komento{makeindex}\komentoargv{name=\katk henkilöt}, lisättäisiin
+asiasana kyseiseen hakemistoon seuraavasti:
+
+\begin{koodilohkosis}
+\index[henkilöt]{Waltari, Mika}
+\end{koodilohkosis}
+
+\noindent
+Tämän luvun muissa esimerkeissä ei yleensä käytetä \komento{index}\-/
+komennon valinnaista argumenttia. Argumentti on kuitenkin tarpeen aina,
+kun halutaan lisätä asiasanoja tiettyyn, määrittelyn yhteydessä
+nimettyyn hakemistoon.
+
+Asiahakemistot aakkostetaan automaattisesti, mutta yksittäisten sanojen
+aakkostustapaan voi vaikuttaa käyttämällä \koodi{@}\=/ merkkiä
+\komento{index}\-/ komennon argumentissa. Ennen \koodi{@}\=/ merkkiä on
+asiasana siinä muodossa kuin se aakkostetaan; \koodi{@}\=/ merkin
+jälkeen annetaan asiasana siinä muodossa kuin se ladotaan
+asiahakemistoon.
+
+Seuraavassa esimerkissä asiahakemistoon lisätään kolme eri henkilöä,
+joiden sukunimet ovat joko Vuori tai Wuori. Kaikki nimet aakkostetaan
+nimen Vuori mukaisesti, eli \emph{v} ja \emph{w} katsotaan aakkostuksen
+kannalta samaksi kirjaimeksi. Tämä on tavallinen käytäntö suomalaisten
+sanojen ja nimien aakkostuksessa.
+
+\komentoi{index}
+\begin{koodilohkosis}
+\index{Vuori, Lauri}
+\index{Vuori, Anita@Wuori, Anita}
+\index{Vuori, Yrjö@Wuori, Yrjö}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ Wuori, Anita, \arabic{page} \\*
+ Vuori, Lauri, \arabic{page} \\*
+ Wuori, Yrjö, \arabic{page}
+\end{tulossis}
+
+\noindent
+Edellä mainittua aakkostustoimintoa tarvitaan myös silloin, kun
+hakemiston sanojen latomisessa käytetään Latex\-/ komentoja eli asiasana
+ei ole pelkkää tekstiä. Seuraavassa esimerkissä asiahakemistoon lisätään
+Latex\-/ komento \komento{textbullet}. Se aakkostetaan sanan
+''\englanti{textbullet}'' mukaan mutta hakemistoon se ladotaan
+tasalevyisellä fontilla (\komento{texttt}) ja alkuun lisätään kenoviiva
+(\komento{textbackslash}).
+
+\komentoi{index}
+\komentoi{texttt}
+\komentoi{textbackslash}
+\begin{koodilohkosis}
+\index{textbullet@\texttt{\textbackslash textbullet}}
+\end{koodilohkosis}
+
+\noindent
+Käytännössä \komento{index}\-/ komentoja ei kannata aina kirjoittaa
+lähdedokumenttiin sellaisenaan, vaan komennon voi sisällyttää jonkin
+toisen komennon määritelmään. Tästä on esimerkki luvussa
+\ref{luku/komennot-abst}.
+
+Asiasanat voi järjestää hakemistoon hierarkkisesti eli aihepiirien
+mukaisesti. Se toteutetaan \komento{index}\-/ komennon argumentissa
+\koodi{!}\=/ merkin avulla, jolla erotetaan ylemmäntasoiset käsitteet
+alemmantasoisista. Seuraava esimerkki lisää asiahakemistoon sanan
+''fontit'' ja sen alle kaksi asiasanaa sivunumeroineen:
+
+\komentoi{index}
+\begin{koodilohkosis}
+\index{fontit!kirjainperhe}
+\index{fontit!kirjainleikkaus}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ fontit \\*
+ \makebox[\sisennys]{}kirjainleikkaus, \arabic{page} \\*
+ \makebox[\sisennys]{}kirjainperhe, \arabic{page}
+\end{tulossis}
+
+\noindent
+Asiasanahierarkiassa voi olla korkeintaan kolme tasoa, ja tasot
+erotetaan toisistaan \koodi{!}\=/ merkillä. Jokainen \koodi{!}\=/
+merkillä erotettu osa voi sisältää \koodi{@}\=/ merkin, jolla voi
+vaikuttaa sanan aakkostamiseen: ensin mainitaan hakusanasta
+aakkostamisessa käytetty versio ja \koodi{@}\=/ merkin jälkeen annetaan
+hakemistoon ladottava versio.
+
+Kirjoittaja voi vaikuttaa asiasanojen sivunumeroiden latomiseen
+käyttämällä \komento{index}\-/ komennon argumentissa asiasanan perässä
+\koodi{|}\=/ merkkiä ja antamalla sen jälkeen komennon nimen.
+Seuraavassa esimerkissä asiasanan sivunumero ladotaan kursiivilla:
+
+\komentoi{index}
+\begin{koodilohkosis}
+\index{asiasana|textit}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ asiasana, \textit{\arabic{page}}
+\end{tulossis}
+
+\noindent
+\komento{index}\-/ komennon argumenttiin ei kirjoiteta varsinaista
+komentoa (\komento{textit}) vaan ainoastaan komennon nimi \koodi{|}\=/
+merkin jälkeen. Komento voi olla mikä hyvänsä ja sen pitäisi hyväksyä
+ainakin yksi argumentti: sivunumero. Asiahakemistoissa on joskus tapana
+merkitä asiasanan pääasiallinen käsittelysivu eri tavalla, esimerkiksi
+kursiivilla tai lihavoinnilla, ja tämä \koodi{|}\=/ ominaisuus sopii
+siihen.
+
+Yksi hyödyllinen käyttökohde \koodi{|}\=/ ominaisuudelle on viittaus
+toiseen asiasanaan. On määritelty jo valmiiksi komennot \komento{see} ja
+\komento{seealso}, joita voi käyttää \komento{index}\-/ komennossa
+seuraavasti:
+
+\komentoi{index}
+\begin{koodilohkosis}
+\index{fontit}
+\index{kirjainleikkaus|see{fontit}}
+\index{kirjainperhe|seealso{fontit}}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ fontit, \arabic{page} \\*
+ kirjainleikkaus, \textit{\seename} fontit \\*
+ kirjainperhe, \textit{\alsoname} fontit
+\end{tulossis}
+
+\noindent
+Molemmat komennot hyväksyvät kaksi argumenttia, mutta edellisessä
+esimerkissä annettiin vain yksi: \koodi{fontit}. Viimeiseksi
+argumentiksi tulee automaattisesti aina sivunumero, mutta nämä komennot
+jättävät sen huomioimatta. Sivunumeroa ei haluta näkyviin, koska
+tarkoitus on vain lisätä asiahakemistoon viittaus toiseen
+asiasanaan.
+
+Suomen kieliasetuksilla edellä mainitut komennot latovat kursivoidun
+ilmauksen \textit{\seename} tai \textit{\alsoname}. Kielikohtaisen
+määritelmän voi muuttaa kielipaketteihin \paketti{polyglossia} ja
+\paketti{babel} kuuluvan \komento{addto}\-/ komennon avulla. Seuraavassa
+esimerkissä vaikutetaan suomen kieliasetuksiin
+(\komento{captionsfinnish}). Komennot täytyy sijoittaa dokumentin
+esittelyosaan:
+
+\komentoi{addto}
+\komentoi{captionsfinnish}
+\komentoi{renewcommand}
+\komentoi{seename}
+\komentoi{alsoname}
+\begin{koodilohkosis}
+\addto{\captionsfinnish}{
+ \renewcommand{\seename}{katso}
+ \renewcommand{\alsoname}{katso myös}
+}
+\end{koodilohkosis}
+
+\noindent
+Toisaalta kirjoittaja voi määritellä ihan oman komentonsa
+asiasanaviittausten tekemiseen. Oman komennon avulla lopputulokseen voi
+vaikuttaa enemmän. Esimerkissä \ref{esim/see-katso-komento} määritellään
+komento \komentox{katso}, jolla voi toteuttaa viittauksia toisiin
+asiasanoihin. Komento hyväksyy kaksi argumenttia mutta jälkimmäinen eli
+sivunumero jätetään käsittelemättä.
+
+\begin{esimerkki*}
+ \komentoi{newcommand}
+ \komentoi{textrightarrow}
+ \komentoi{index}
+
+\begin{koodilohko}
+\newcommand{\katso}[2]{\textrightarrow{} #1}
+
+% Seuraavat komennot tarvitaan vain kerran dokumentissa, koska ne vain
+% viittaavat toisiin asiasanoihin.
+\index{kirjainleikkaus|katso{fontit}}
+\index{kirjainperhe|katso{fontit}}
+
+% Seuraavassa on esimerkki varsinaisista asiasanoista. Komennot
+% sijoitetaan paikkoihin, joissa aihetta käsitellään.
+\index{fontit!kirjainleikkaus}
+\index{fontit!kirjainperhe}
+\end{koodilohko}
+
+\begin{tulos}
+ fontit \\*
+ \makebox[\sisennys]{}kirjainleikkaus, \arabic{page} \\*
+ \makebox[\sisennys]{}kirjainperhe, \arabic{page} \\*
+ kirjainleikkaus, \textrightarrow{} fontit \\*
+ kirjainperhe, \textrightarrow{} fontit
+\end{tulos}
+
+\caption{Oman \komentox{katso}\-/ komennon määrittely. Komennon nimeä
+ käytetään \komento{index}\-/ komennon argumentissa ja sillä viitataan
+ toisiin asiasanoihin}
+\label{esim/see-katso-komento}
+\end{esimerkki*}
+
+Tavallisesti \komento{index} kirjaa muistiin vain sen sivun, jolla
+komento esiintyy. Jos komento esiintyy usealla peräkkäisellä sivulla,
+hakemistoon ladotaan automaattisesti sivualue, esimerkiksi 53--55.
+
+Aina ei kuitenkaan ole mielekästä ilmaista aiheen käsittelyä
+yksittäisten \komento{index}\-/ komentojen avulla. Toisinaan voi olla
+sopivampaa määrittää aiheen käsittelyn alku- ja loppukohta. Alkukohta
+ilmaistaan \komento{index}\-/ komennon argumentissa merkkien \koodi{|(}
+avulla ja loppukohta merkkien \koodi{|)} avulla. Jos aloitus ja lopetus
+sattuvat samalle sivulle, hakemistoon ladotaan vain yksi sivunumero.
+Muussa tapauksessa ladotaan sivualue. Seuraavassa on esimerkki aiheen
+käsittelyn alun ja lopun merkitsemiseen:
+
+\komentoi{index}
+\begin{koodilohkosis}
+\index{asiasana|(} % aiheen käsittely alkaa
+...
+\index{asiasana|)} % aiheen käsittely loppuu
+\end{koodilohkosis}
+
+\begin{tulossis}
+ asiasana, 53--55
+\end{tulossis}
+
+\noindent
+Edellä mainittujen aloitusmerkkien \koodi{|(} perään voi kirjoittaa
+komennon nimen, jos haluaa vaikuttaa sivunumeroiden latomiseen. Tätä
+käsiteltiin jo edellä, mutta seuraavassa on käytännön esimerkki:
+
+\komentoi{index}
+\begin{koodilohkosis}
+\index{asiasana|(textit} % aiheen käsittely alkaa
+...
+\index{asiasana|)} % aiheen käsittely loppuu
+\end{koodilohkosis}
+
+\begin{tulossis}
+ asiasana, \textit{53--55}
+\end{tulossis}
+
+\noindent
+Jos itse asiasanaan täytyy sisällyttää edellä mainittuja
+\komento{index}\-/ komennon erikoismerkkejä (\koodi{@!|}), pitää niiden
+eteen kirjoittaa yleislainausmerkki (\koodi{\textquotedbl}). Se estää
+seuraavan merkin tulkitsemisen \komento{index}\-/ komennon
+erikoismerkiksi.
+
+\subsection{Hakemiston latominen ja asetukset}
+\label{luku/asiasanat-asetukset}
+
+Hakemistot ladotaan komennolla \komento{printindex}. Tyypillisesti
+komento sijaitsee dokumentin lopussa eli lähinnä artikkelin tai
+tietokirjan viimeisillä sivuilla. Jos komennon suorittaa ilman
+argumentteja, se latoo oletushakemiston eli sen, jolle ei ole annettu
+teknistä nimeä \komento{makeindex}\-/ komennon \koodi{name}\-/
+valitsimella (luku \ref{luku/asiasanat-määrittely}). Komennolle voi
+antaa hakasulkeissa yhden valinnaisen argumentin, joka ilmaisee
+ladottavan hakemiston teknisen nimen, esimerkiksi:
+
+\komentoi{printindex}
+\begin{koodilohkosis}
+\printindex % Latoo nimeämättömän hakemiston.
+\printindex[henkilöt] % Latoo hakemiston nimeltä ”henkilöt”.
+\end{koodilohkosis}
+
+\noindent
+Luvussa luku \ref{luku/asiasanat-määrittely} käsitellään yksittäisten
+hakemistojen asetuksia, mutta \komento{indexsetup}\-/ komennolla voi
+määrittää kaikkia hakemistoja koskevia yleisempiä asetuksia. Komennolle
+annetaan yksi argumentti, joka voi sisältää useita pilkuilla erotettuja
+valitsimia ja niiden arvoja. Valitsimia on koottu taulukkoon
+\ref{tlk/indexsetup-valitsimia}, ja seuraavassa on käytännön esimerkki:
+
+\begin{koodilohkosis}
+\indexsetup{level=\section*, noclearpage}
+\end{koodilohkosis}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\koodi{#1} & #2 \\}
+ \begin{tabularx}{\linewidth}{lL}
+ \toprule
+ \ots{Valitsin} & \ots{Merkitys ja vaihtoehtoja} \\
+ \midrule
+ \rivi{level}{Hakemistojen otsikkokomento: \komento{chapter*},
+ \komento{chapter}, \komento{section*}, \komento{section} ym.}
+ \rivi{toclevel}{Hakemiston taso sisällysluettelossa:
+ \koodi{chapter}, \koodi{section} ym.}
+ \rivi{noclearpage}{Ei automaattista sivunvaihtoa hakemistojen
+ alussa.}
+ \rivi{firstpagestyle}{Hakemiston ensimmäisen sivun sivutyyli:
+ \koodi{plain}, \koodi{empty} ym.}
+ \bottomrule
+ \end{tabularx}
+}{
+ \caption{\komento{indexsetup}\-/ komennon valitsimia, joilla
+ vaikutetaan kaikkien asiahakemistojen latomiseen}
+ \label{tlk/indexsetup-valitsimia}
+}
+
+\noindent
+Valitsimen \koodi{level} arvoksi annetaan tyypillisesti otsikkokomento,
+joka suoritetaan kunkin hakemiston alussa. Itse otsikon tekstin voi
+määritellä \komento{makeindex}\-/ komennon \koodi{title}\-/ valitsimella
+kullekin hakemistolle erikseen. \koodi{level}\-/ valitsimelle oletusarvo
+on dokumenttiluokkakohtainen korkein otsikkotaso eli \komento{chapter*}
+tai \komento{section*}. Jos arvoksi antaa tähdettömän otsikkokomennon
+kuten \komento{chapter}, se luo automaattisesti merkinnän
+sisällysluetteloon. Silloin ei kannata käyttää \komento{makeindex}\-/
+komennon \koodi{intoc}\-/ valitsinta.
+
+Käytännössä \koodi{level}\-/ valitsimen arvoksi voi antaa minkä hyvänsä
+komennon, joka hyväksyy yhden argumentin eli kyseisen hakemiston
+otsikkotekstin. Kirjoittaja voi siis asettaa tähän oman komentonsa,
+jonka määritelmässä mahdollisesti suoritetaan muutakin kuin pelkkä
+otsikkokomento. \koodi{toclevel}\-/ valitsimella ilmaistaan hakemistojen
+taso sisällysluettelossa. Valitsimen arvoksi annetaan otsikkokomentojen
+nimi kuten \koodi{section} tai \koodi{subsection}.
+
+Oletuksena jokaisen asiahakemiston alussa suoritetaan sivunvaihtokomento
+\komento{clearpage}. Käyttämällä valitsinta \koodi{noclearpage} estetään
+automaattinen sivunvaihto. Valitsimella \koodi{firstpagestyle} asetetaan
+kunkin asiahakemiston ensimmäisen sivun sivutyyli (luku
+\ref{luku/ylä-ala-tunnisteet}). Oletusarvo on \koodi{plain} eli
+tavallinen, oletuksena pelkän sivunumeron sisältävä sivutyyli. Tämä
+valitsin ei ole käytössä, jos ladattuna on paketti \paketti{fancyhdr}.
+
+Ennen \komento{printindex}\-/ komentoa voi käyttää komentoa
+\komento{indexprologue}, jolla määritetään johdantoteksti asiahakemiston
+alkuun. Komento vaikuttaa seuraavaksi ladottavaan asiahakemistoon, eli
+se kannattaa sijoittaa juuri ennen \komento{printindex}\-/ komentoa.
+Komentoa käytetään seuraavasti:
+
+\komentoi{indexprologue}
+\begin{koodilohkosis}
+\indexprologue[väli]{teksti}
+\end{koodilohkosis}
+
+\noindent
+Pakollinen argumentti \koodi{teksti} on hakemiston johdannoksi
+tarkoitettu teksti. Valinnainen argumentti \koodi{väli} on tarkoitettu
+komennolle, joka latoo pystysuuntaisen välin johdantotekstin jälkeen,
+ennen asiasanojen luetteloa. Oletuksena väliksi tulee komennon
+\komento{bigskip} latoma väli, mutta muunlaisen välin saa kirjoittamalla
+valinnaiseen argumenttiin esimerkiksi \komento{vspace}\-/ komennon ja
+sen argumentiksi halutun mitan.
+
+Asiahakemistopaketin -- \paketti{indextools} tai \paketti{imakeidx} --
+lataamisen yhteydessä voi määrittää asetuksia tiettyjen valitsimien
+avulla. \komento{usepackage}\-/ komennon valinnaiseen argumenttiin
+kirjoittaa useita valitsimia, ja ne erotetaan toisistaan pilkulla.
+Mahdollisia valitsimia on useita, mutta tässä oppaassa käsitellään vain
+pari tärkeintä.
+
+Esimerkiksi valitsin \koodi{xindy}, aiheuttaa sen, että
+\komento{makeindex}\-/ komennoilla määritetyille asiahakemistoille tulee
+oletuksena asetus \koodi{program=\katk xindy}. Muutoin oletus on
+\koodi{program=\katk makeindex} (luku \ref{luku/asiasanat-määrittely}).
+
+\komentoi{usepackage}
+\pakettii{indextools}
+\begin{koodilohkosis}
+\usepackage[xindy]{indextools}
+\end{koodilohkosis}
+
+\noindent
+Jos omassa dokumentissa tarvitaan useita asiahakemistoja, saatetaan
+joskus tarvita valitsinta \koodi{splitindex}. Se kiertää erästä Latexin
+tiedostojen käsittelyn puutetta. Nimittäin Latex ei voi kääntämisen
+yhteydessä kirjoittaa kovin moneen tiedostoon, ja jokainen asiahakemisto
+tarvitsisi omansa. Rajoitukset saattavat tulla vastaan useiden
+asiahakemistojen käsittelyssä.
+
+Käyttämällä valitsinta \koodi{splitindex} kierretään edellä mainittua
+rajoitusta siten, että ensin kaikki asiahakemistot kirjoitetaan yhteen
+väliaikaistiedostoon ja myöhemmin ne erotetaan automaattisesti
+toisistaan suorittamalla \koodi{splitindex}\-/ niminen ohjelma. Tämän
+valitsimen käyttö vaatii, että Latexin kääntäjäohjelmalle
+(\koodi{lualatex} tai \koodi{xelatex}) annetaan komentorivivalitsin
+\koodi{\=/shell-escape}.
+
+\section{Kuvat}
+\label{luku/grafiikka}
+
+Perus Latex ei pysty juuri minkäänlaiseen kuvien eli tietokonegrafiikan
+käsittelyyn, mutta avuksi on tehty monipuolisia paketteja. Niiden
+voidaan esimerkiksi ladata ja latoa kuvatiedostoja sekä piirtää
+vektorigrafiikkakuvia Latex\-/ komentojen avulla.
+
+\subsection{Kuvatiedostot}
+
+Paketti \pakettictan{graphicx} sisältää toiminnot kuvatiedostojen
+käsittelyyn sekä tekstin tai muun sisällön kääntelyyn ja skaalaamisen.
+Kuvatiedostojen peruskäyttö sujuu komennolla \komento{includegraphics}
+seuraavasti:
+
+\komentoi{includegraphics}
+\begin{koodilohkosis}
+\includegraphics[width=6cm]{kuvatiedosto.jpg}
+\end{koodilohkosis}
+
+\noindent
+Tällä tavoin lisätty kuvatiedosto käyttäytyy tekstikappaleessa kuin mikä
+tahansa kirjain. Edellisen esimerkin pakollisessa argumentissa oleva
+\koodi{kuvatiedosto.\katk jpg} on tiedoston nimi. Se voi sisältää myös
+hakemistopolun, jos tiedosto ei sijaitse samassa hakemistossa Latex\-/
+lähdetiedostojen kanssa. Kaikki käyttöjärjestelmän hyväksymät
+tiedostonnimet eivät Latexissa toimi, vaan kannattaa jättää välilyönnit
+pois ja pitäytyä suppeassa latinalaisessa merkkivalikoimassa.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{\koodi{#1} & #2 \\}
+ \begin{tabularx}{\linewidth}{lL}
+ \toprule
+ \ots{Valitsin} & \ots{Merkitys} \\
+ \midrule
+ \rivi{width}{leveysmitta}
+ \rivi{height}{korkeusmitta}
+ \rivi{angle}{kääntökulma asteina}
+ \rivi{origin}{kääntämisen keskipiste:
+ \koodi{c} (keskikohta),
+ \koodi{l} (vasen),
+ \koodi{r} (oikea),
+ \koodi{t} (ylä),
+ \koodi{b} (ala),
+ \koodi{B} (rivin peruslinja)
+ }
+
+ \rivi{trim}{reunojen siirto: vasen, ala, oikea, ylä}
+ \rivi{clip}{leikkaminen reunojen ulkopuolelta}
+ \bottomrule
+ \end{tabularx}
+}{
+ \caption{\komento{includegraphics}\-/ komennon valinnaiseen
+ argumenttiin sopivia valitsimia}
+ \label{tlk/includegraphics-valitsimia}
+}
+
+\komento{includegraphics}\-/ komennon valinnaiseen argumenttiin voi
+kirjoittaa monenlaisia pilkulla toisistaan erotettuja valitsimia ja
+niiden arvoja. Joitakin valitsimia on koottu taulukkoon
+\ref{tlk/includegraphics-valitsimia}. Tavallisimpia ovat varmaankin
+\koodi{width} ja \koodi{height}, joilla määritetään, minkä levyisenä tai
+korkuisena kuva halutaan latoa. Näistä voi asettaa vain jommankumman, ja
+toinen mitta määräytyy alkuperäiskuvan mittasuhteiden perusteella.
+Asettamalla sekä leveyden että korkeuden kuva skaalataan juuri kyseisiin
+mittoihin.
+
+Kuvan kääntämisessä käytetään \koodi{angle}\-/ valitsinta ja astelukua.
+Kuva kääntyy \koodi{origin}\-/ valitsimella määritetyn pisteen kautta,
+ja valitsimen arvoksi annetaan taulukossa
+\ref{tlk/includegraphics-valitsimia} mainittuja kirjaimia tai niiden
+yhdistelmiä. Esimerkiksi \koodi{origin=\katk lt} tarkoittaa vasenta
+(\koodi{l}) ylänurkkaa (\koodi{t}).
+
+Kuvaa voi rajata sivuilta käyttämällä yhdessä valitsimia \koodi{trim} ja
+\koodi{clip}. \koodi{trim}\-/ valitsimen arvoksi annetaan neljä
+välilyönnillä erotettua mittaa, joiden järjestys on seuraava: vasen,
+ala, oikea, ylä. Tämä valitsin vain siirtää kuvan reunojen sijaintia,
+mutta kun mukaan ottaa valitsimen \koodi{clip}, kuvasta myös leikataan
+reunojen ulkopuolinen alue pois. Seuraavassa esimerkissä kuvaa leikataan
+vasemmalta 1\,mm, alhaalta 2\,mm, oikealta 3\,mm ja ylhäältä 4\,mm.
+Kuvan lopulliseksi leveydeksi tulee 40\,mm.
+
+\komentoi{includegraphics}
+\begin{koodilohkosis}
+\includegraphics[width=40mm,
+ clip, trim={1mm 2mm 3mm 4mm}]{kuvatiedosto.jpg}
+\end{koodilohkosis}
+
+\subsection{Vektorigrafiikka}
+
+Paketti \pakettictan{tikz} tuo Latexiin monipuolisen apukielen, jolla
+kirjoittaja voi piirtää vektorigrafiikkaa. Paketin taustalla toimii
+toinen paketti ja grafiikkajärjestelmä \paketti{pgf} eli
+\englantik{portable graphics format}, mutta kirjoittajan ei yleensä
+tarvitse välittää taustalla olevasta matalan tason tekniikasta.
+
+Tässä oppaassa käsitellään vain joitakin \paketti{tikz}\-/ paketin
+perustoimintoja. Paketin omassa ohjekirjassa on yli 1\,300 sivua, eli
+valtavan paljon hienoja ominaisuuksia jää lukijan itse selvitettäväksi.
+Runsasta sivumäärää ei kannata säikähtää: ei opasta tarvitse kokonaan
+lukea, ja alkupuolella teksti johdattelee lukijaa eteenpäin helppojen ja
+käytännöllisten esimerkkien avulla.
+
+Vektorigrafiikkaan erikoistunut kieli ja komennot toimivat ympäristön
+\ymparisto{tikzpicture} sisällä. Se ei ole mikä tahansa Latexin tekstiä
+ja merkintätapoja sisältävä ympäristö, vaan se on tarkoitettu vain
+piirtokomennoille, joilla on oma, muusta Latexista hieman poikkeava
+kielioppinsa. Seuraavassa on pieni esimerkki:
+
+\ymparistoi{tikzpicture}
+\komentoi{draw}
+\begin{koodilohkosis}
+\begin{tikzpicture}[x=1mm, y=1mm]
+ \draw (0,0) -- (25,5) -- (50,0) -- cycle;
+ \draw (25,0) -- (25,5);
+\end{tikzpicture}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \begin{tikzpicture}[x=1mm, y=1mm]
+ \draw (0,0) -- (25,5) -- (50,0) -- cycle;
+ \draw (25,0) -- (25,5);
+ \end{tikzpicture}
+\end{tulossis}
+
+\noindent
+Edellisessä esimerkissä ympäristön alussa määritellään hakasulkeissa
+perusasetuksia. Tässä asetetaan x- ja y\=/ akselien suuntaiset
+yksikkömitat 1\,mm:n pituiseksi. Piirtokomentojen koordinaatit käyttävät
+sen jälkeen näitä yksiköitä. Jos yksiköitä ei määritellä, käytetään
+oletusyksikköä, joka on 10\,mm. On myös mahdollista antaa
+piirtokomentojen koordinaateissa suoraan Latexin mittayksiköt,
+esimerkiksi \koodi{(25mm,5mm)} tai \koodi{(10bp,20bp)}, jolloin
+koordinaatit tulevat juuri näiden mittojen mukaiseksi. Piirustusalustan
+origo eli koordinaatti (0,~0) sijaitsee vasemmassa alanurkassa, ja
+koordinaatisto kasvaa ylös ja oikealle.
+
+Edellä olleessa esimerkissä piirretään komennolla \komento{draw}
+viivakuvio, jonka välipisteiden kordinaatit ilmaistaan sulkeissa.
+Lopussa oleva \koodi{cycle} piirtää viivan takaisin saman
+\komento{draw}\-/ komennon alkupisteeseen. Tätä kokonaisuutta kutsutaan
+poluksi, ja sen lopussa täytyy olla puolipiste
+(\koodi{;}).\footnote{Polkujen luomisen peruskomento on \komento{path},
+ joka ei piirrä mitään, ellei sille anna valinnaista argumenttia
+ \koodi{draw}. Komento \komento{draw} on itse asiassa sama kuin
+ \komento{path}\komentoargv{draw}.} Esimerkissä on toinenkin polku eli
+toinen \komento{draw}\-/ komento piirtää pystyviivan suuren kolmion
+keskelle ja jakaa sen kahdeksi pienemmäksi kolmioksi.
+
+Koordinaatit voi ilmaista suhteessa polun edelliseen pisteeseen
+lisäämällä koordinaatin eteen kaksi plusmerkkiä. Seuraavassa esimerkissä
+havainnollistetaan sitä. Kuvion (polun) neljä ensimmäistä pistettä
+ilmaistaan x- ja y\=/ koordinaateilla mutta viimeinen piste ilmaistaan
+kulman (25°) ja pituuden (8) avulla.
+
+\ymparistoi{tikzpicture}
+\komentoi{draw}
+\begin{koodilohkosis}
+\begin{tikzpicture}[x=1mm, y=1mm]
+ \draw (0,0) -- ++(0,5) -- ++(10,0) -- ++(0,-5) -- ++(25:8);
+\end{tikzpicture}
+\end{koodilohkosis}
+
+\begin{tulossis}
+ \begin{tikzpicture}[x=1mm, y=1mm]
+ \draw (0,0) -- ++(0,5) -- ++(10,0) -- ++(0,-5) -- ++(25:8);
+ \end{tikzpicture}
+\end{tulossis}
+
+\noindent
+Viivojen lisäksi on olemassa komentoja muillekin geometrisille
+peruskuvioille. Esimerkissä \ref{esim/tikz-kuvioita} piirretään
+suorakulmio, ympyrä, ellipsi, sektorin kaari (0--90°) ja taivutettu
+viiva. Viimeksi mainittu (rivi~6) sisältää alkupisteen, kaksi
+näkymätöntä ohjauspistettä (\koodi{controls}, \koodi{and}), joiden
+suuntaan viivaa taivutetaan, sekä loppupisteen.
+
+\begin{esimerkki*}
+ \ymparistoi{tikzpicture}
+ \komentoi{draw}
+
+\begin{koodilohko}
+\begin{tikzpicture}[x=1mm, y=1mm]
+ \draw (0,0) rectangle (10,5);
+ \draw (20,2.5) circle [radius=2.5];
+ \draw (35,2.5) ellipse [x radius=4, y radius=2, rotate=30];
+ \draw (55,0) arc [start angle=0, end angle=90, radius=5];
+ \draw (65,0) .. controls (75,7) and (80,7) .. (80,0);
+\end{tikzpicture}
+\end{koodilohko}
+
+ \begin{tulos}
+ \begin{tikzpicture}[x=1mm, y=1mm]
+ \draw (0,0) rectangle (10,5);
+ \draw (20,2.5) circle [radius=2.5];
+ \draw (35,2.5) ellipse [x radius=4, y radius=2, rotate=30];
+ \draw (55,0) arc [start angle=0, end angle=90, radius=5];
+ \draw (65,0) .. controls (75,7) and (80,7) .. (80,0);
+ \end{tikzpicture}
+ \end{tulos}
+
+ \caption{Erilaisia geometrisia kuvioita: suorakulmio, ympyrä, ellipsi,
+ ympyrän kaari ja taivutettu viiva}
+ \label{esim/tikz-kuvioita}
+\end{esimerkki*}
+
+Kuten esimerkki \ref{esim/tikz-kuvioita} osoittaa, piirtokomennoille voi
+antaa hakasulkeissa lisätietoja. Mahdollisuuksia on valtavan paljon:
+esimerkiksi värit, viivojen paksuus, nuolenkärjet ja kulmien pyöristys
+ilmaistaan tällaisten listätietojen avulla. Esimerkki
+\ref{esim/tikz-asetuksia} havainnollistaa tavallisimpia valinnaisia
+argumentteja. Värivalitsimien \koodi{draw} ja \koodi{fill} arvoksi voi
+antaa mitä hyvänsä nimettyjä värejä, joita käsitellään tarkemmin luvussa
+\ref{luku/korostus-värit}.
+
+\begin{esimerkki*}
+ \ymparistoi{tikzpicture}
+ \komentoi{draw}
+
+\begin{koodilohko}
+\begin{tikzpicture}[x=1mm, y=1mm,
+ nuoli/.style={line width=1bp, draw=red}]
+
+ % Nuolia
+ \draw [nuoli, ->] (0,0) -- (10,5);
+ \draw [nuoli, <<-, draw=blue] (10,0) -- (20,5);
+ \draw [nuoli, <->] (20,0) -- (30,5);
+
+ % Täytetty nelikulmio, viivan paksuus ja kulmien pyöristys
+ \draw [draw=black, fill=yellow, line width=1.5bp, rounded
+ corners=3bp] (40,0) -- ++(3,5) -- ++(20,0) -- ++(3,-5) -- cycle;
+\end{tikzpicture}
+\end{koodilohko}
+
+ \begin{tulos}
+ \begin{tikzpicture}[x=1mm, y=1mm,
+ nuoli/.style={line width=1bp, draw=red}]
+
+ % Nuolia
+ \draw [nuoli, ->] (0,0) -- (10,5);
+ \draw [nuoli, <<-, draw=blue] (10,0) -- (20,5);
+ \draw [nuoli, <->] (20,0) -- (30,5);
+
+ % Täytetty nelikulmio, viivan paksuus ja kulmien pyöristys
+ \draw [draw=black, fill=yellow, line width=1.5bp, rounded
+ corners=3bp] (40,0) -- ++(3,5) -- ++(20,0) -- ++(3,-5) -- cycle;
+ \end{tikzpicture}
+ \end{tulos}
+
+\caption{Erilaisia piirtokomentojen argumentteja: nuolenkärjet, värit,
+ viivan paksuus ja kulmien pyöristys}
+\label{esim/tikz-asetuksia}
+\end{esimerkki*}
+
+Esimerkissä \ref{esim/tikz-asetuksia} olevan \ymparisto{tikzpicture}\-/
+ympäristön valinnaisessa argumentissa määritellään rivillä~2 oma
+tyyliasetus nimeltä \koodi{nuoli}. Asetukseen kuuluu viivan leveys
+(\koodi{line width}) ja väri (\koodi{draw}). Näin määriteltyä
+\koodi{nuoli}\-/ tyyliä käytetään rivien 5\==7 \komento{draw}\-/
+komennoissa. Tällä tavoin omia tyylejä määrittelemällä säästää
+todennäköisesti aikaa ja vaivaa, koska tyyliasetuksia voi sen jälkeen
+muuttaa yhdestä paikasta.
+
+Usein tarvittavat \komento{draw}\-/ polut ja komentosarjat kannattanee
+piilottaa omien komentojen sisään. Kirjoittaja voi siis tehdä
+\komento{newcommand}\-/komennolla (luku \ref{luku/komennot}) ja muilla
+vastaavilla omia, mahdollisesti kokeamman tason piirtokomentoja, jotka
+piirtävät usein tarvittavia kuvan osia.
+
+\begin{esimerkki*}
+ \ymparistoi{tikzpicture}
+ \komentoi{node}
+
+\begin{koodilohko}
+\begin{tikzpicture}[x=1mm, y=1mm]
+ \node at (0,0) [draw=red, rectangle, rounded corners=3bp] {vasen};
+ \node [color=blue] at (20,0) {keski};
+ \node at (40,0) [draw, circle, inner sep=0bp, fill=yellow] {oikea};
+\end{tikzpicture}
+\end{koodilohko}
+
+ \begin{tulos}
+ \begin{tikzpicture}[x=1mm, y=1mm]
+ \node at (0,0) [draw=red, rectangle, rounded corners=3bp] {vasen};
+ \node [color=blue] at (20,0) {keski};
+ \node at (40,0) [draw, circle, inner sep=0bp, fill=yellow] {oikea};
+ \end{tikzpicture}
+ \end{tulos}
+
+ \caption{Tekstiä tai muuta sisältäviä solmuja tehdään
+ \komento{node}\-/ komennolla}
+ \label{esim/tikz-solmut}
+\end{esimerkki*}
+
+Kuvaan voi sisällyttää myös tekstiä tai muuta Latexin sisältöä. Se
+tapahtuu helpoimmin komennolla \komento{node}, joka tekee niin sanottuja
+solmuja. Komento tarvitsee ainakin solmun sijaintikoordinaatit ja
+ladottavan sisällön. Esimerkissä \ref{esim/tikz-solmut} on kolme
+erityyppistä solmua.
+
+Kuten esimerkistä näkyy, laatikolle voi määrittää kehykset ja niiden
+värin, (\koodi{draw}), täyttövärin (\koodi{fill}), sisällön värin
+(\koodi{color}), kehyksen kulmien pyöristyksen (\koodi{\englanti{rounded
+ corners}}) ja sisäisen tyhjän tilan suuruuden (\koodi{inner sep}).
+Kaikenlaista muutakin voi tehdä valinnaiseen argumenttiin
+sisällytettävien valitsimien avulla, mutta niistä täytyy lukea lisää
+paketin omasta ohjekirjasta.
+
+\begin{esimerkki*}
+ \ymparistoi{tikzpicture}
+ \komentoi{node}
+ \komentoi{draw}
+
+\begin{koodilohkosis}
+\begin{tikzpicture}[x=1mm, y=1mm]
+ \node (ympyrä) at (0,0) [draw, circle] {vasen};
+ \node (suorakulmio) at (20,0) [draw, rectangle] {oikea};
+ \draw [->, shorten >=1mm] (ympyrä) to [out=45, in=135] (suorakulmio);
+\end{tikzpicture}
+\end{koodilohkosis}
+
+ \begin{tulossis}
+ \begin{tikzpicture}[x=1mm, y=1mm]
+ \node (ympyrä) at (0,0) [draw, circle] {vasen};
+ \node (suorakulmio) at (20,0) [draw, rectangle] {oikea};
+ \draw [->, shorten >=1mm] (ympyrä) to [out=45, in=135] (suorakulmio);
+ \end{tikzpicture}
+ \end{tulossis}
+
+ \caption{Solmujen nimeäminen ja kytkeminen viivan avulla}
+ \label{esim/tikz-solmujen-yhdistäminen}
+\end{esimerkki*}
+
+Solmulle voi määrittää yksilöllisen nimen, jota voi sitten käyttää
+esimerkiksi viivojen piirtämiseen solmujen välille. Viivojen
+piirtämisessä \komento{draw}\-/ komennon koordinaattien sijasta
+käytetäänkin solmulle annettua nimeä. Tätä havainnollistetaan
+esimerkissä \ref{esim/tikz-solmujen-yhdistäminen}, jossa esitellään myös
+\komento{draw}\-/ komennon \koodi{to}\-/ operaatio. Se mahdollistaa
+solmujen välisen viivan lähtö- ja tulokulman valinnan valitsimilla
+\koodi{out} ja \koodi{in}. Esimerkissä myös lyhennetään nuolta
+loppupäästä käyttämällä valitsinta \koodil{shorten~>}.
+
+Tämän alaluvun ohjeiden avulla pääsee aika mukavasti alkuun
+\paketti{tikz}\-/ paketin käytössä ja saa toteutettua tavallisimmat
+vektorigrafiikkakuviot. Paketin omaan ohjekirjaan kannattaa silti
+tutustua, sillä \ymparisto{tikzpicture}\-/ ympäristön mahdollisuudet
+ovat valtavat.
+
+\section{Matematiikka}
+\label{luku/matematiikka}
+
+Latexin matematiikkatila on suunniteltu matemaattisten kaavojen
+latomiseen eli matematiikan syntaksia varten. Matematiikkatila on aivan
+oma todellisuutensa, joka ei pintapuolisesti tarkastellessa tunnu
+noudattavan samoja sääntöjä kuin tekstitila.
+
+Matematiikkatilassa ovat voimassa eri komennot, eri fontit, erilainen
+merkkien käyttäytyminen ja erilaiset välistykset. Tässä luvussa
+käsitellään matematiikkatilan käyttöä ja matemaattisen syntaksin
+kirjoittamista. Fonttiasetuksia käsitellään luvussa
+\ref{luku/matematiikka-fontit}.
+
+\subsection{Matematiikkatilan käyttö}
+\label{luku/matematiikka-käyttö}
+
+Matematiikkatila voidaan kytkeä päälle joko tavallisen tekstitilassa
+toimivan rivin sisällä tai omassa tekstikappaleessaan. Tekstirivillä
+matemaattinen teksti lisätään komentojen \komento{(} ja \komento{)}
+väliin, kahden \koodi{\$}\-/ merkin väliin tai ympäristön
+\ymparisto{math} sisälle. Seuraavassa on esimerkki kaikista kolmesta:
+
+\begin{koodilohkosis}
+Kaava \( y = 2x + 3 \) on suoran yhtälö.
+Kaava $ y = 2x + 3 $ on suoran yhtälö.
+Kaava \begin{math} y = 2x + 3 \end{math} on suoran yhtälö.
+\end{koodilohkosis}
+
+\begin{tulossis}
+Kaava \( y = 2x + 3 \) on suoran yhtälö.
+Kaava $ y = 2x + 3 $ on suoran yhtälö.
+Kaava \begin{math} y = 2x + 3 \end{math} on suoran yhtälö.
+\end{tulossis}
+
+\noindent
+Kuten edellä olevasta esimerkistä näkyy, matematiikkatilassa kirjaimet
+ladotaan kursiivilla. Tavalliset lähdetiedostoon kirjoitetut kirjaimet
+on tarkoitettu muuttujiksi kuten tässä esimerkissä $x$ ja $y$.
+
+Jos matemaattiset kaavat ovat pitkiä tai vievät pystysuuntaista tilaa
+enemmän kuin tavallisen rivikorkeuden verran, on parasta latoa ne omaksi
+kappaleekseen. Se toteutetaan esimerkiksi kirjoittamalla kaavat
+ympäristön \ymparisto{displaymath} sisään tai komentojen \komento{[} ja
+\komento{]} väliin. Molemmat toimivat samalla tavalla.
+
+\komentoi{[}
+\komentoi{]}
+\mkomentoi{left}
+\mkomentoi{right}
+\mkomentoi{frac}
+\begin{koodilohkosis}
+\[ \left(\frac{1}{x}\right)^2 = \frac{1}{x^2} \]
+\end{koodilohkosis}
+\[ \left(\frac{1}{x}\right)^2 = \frac{1}{x^2} \]
+
+\noindent
+Ympäristö \ymparisto{equation} toimii muuten samalla tavalla, mutta se
+latoo kaavan viereen myös järjestysnumeron ristiviittauksia varten.
+Ympäristön sisälle voi kirjoittaa \komento{label}\-/ komennon, jonka
+argumentissa annetaan kaavalle yksilöllinen tunniste. Tekstistä voi
+viitata kaavaan \komento{ref}\-/ komennolla, jonka argumenttina on
+kaavan tunniste. Ristiviittauksista on tarkempaa tietoa luvussa
+\ref{luku/ristiviitteet}.
+
+Kaavojen numerot tulevat laskurista \laskuri{equation}, ja numeron
+latomiseen voi vaikuttaa määrittelemällä uudelleen komennon
+\komento{theequation}. Seuraavassa esimerkissä kaavan numeroon asetetaan
+ensiksi \komento{section}\-/ tasoisen otsikon numero, piste erottimeksi
+ja lopuksi kyseisen kaavan numero.
+
+\komentoi{renewcommand}
+\komentoi{theequation}
+\komentoi{thesection}
+\komentoi{arabic}
+\laskurii{equation}
+\begin{koodilohkosis}
+\renewcommand{\theequation}{\thesection.\arabic{equation}}
+\end{koodilohkosis}
+
+\noindent
+Latexin lähdedokumentissa matematiikkatilassa kaiken täytyy sisältyä
+yhteen kappaleeseen eli tyhjiä rivejä ei sallita. Matemaattiset kaavat
+ladotaan oletuksena sivun keskelle, mutta jos asettaa Latexin
+dokumenttiluokalle (luku \ref{luku/perusdokumenttiluokat}) valitsimen
+\koodi{fleqn}, ne ladotaan sivun vasempaan reunaan. Kaavojen numerot
+ladotaan oletuksena sivun oikeaan reunaan, mutta vasemmalle ne saa
+käyttämällä dokumenttiluokan valitsinta \koodi{leqno}.
+
+Matematiikkaympäristössä on käytettävissä taulukkoympäristö
+\mymparisto{array}, joka toimii pitkälti samalla tavalla kuin
+tekstitilan taulukotkin (luku \ref{luku/taulukot}). Pelkästään
+matematiikkatilassa toimiva \mymparisto{array}\-/ ympäristö mahdollistaa
+useiden kaavarivien latomisen ja kohdistamisen vaakasuunnassa tietylle
+kohdalle. Esimerkiksi yhtälöt on mielekästä sijoittaa samalle tasalle
+yhtäsuuruusmerkin kohdalta.
+
+\mymparistoi{array}
+\begin{koodilohkosis}
+\[ \begin{array}{r@{~}l}
+ 4x - 2 &= 6 \\
+ x &= 2 \\
+ \end{array} \]
+\end{koodilohkosis}
+\[ \begin{array}{r@{~}l}
+ 4x - 2 &= 6 \\
+ x &= 2 \\
+ \end{array} \]
+
+\noindent
+Pidemmälle kehitettyjä matematiikkaympäristöjä on paketissa
+\pakettictan{amsmath}. Esimerkiksi \mymparisto{align}\-/\ ja
+\mymparisto{align*}\-/ ympäristöt pystyvät tasaamaan allekkaiset kaavat
+tietystä kohdasta, eikä taulukon sarakkeita tarvitse erikseen
+määritellä. Tasauskohta ilmaistaan lähdedokumentissa \koodi{\&}\-/
+merkillä normaalien taulukoiden tavoin. Ympäristön tähtiversio
+\mymparisto{align*} ei lado kaavan numeroa mukaan. Edellä olleen
+yhtälöesimerkin voi toteuttaa yksinkertaisemmin seuraavasti:
+
+\mymparistoi{align*}
+\begin{koodilohkosis}
+\begin{align*}
+ 4x - 2 &= 6 \\
+ x &= 2
+\end{align*}
+\end{koodilohkosis}
+
+\noindent
+Paketti \paketti{amsmath} sisältää paljon muitakin hyödyllisiä
+ympäristöjä ja komentoja matematiikan latomiseen. Paketin ohjekirjaan on
+erittäin suositeltavaa tutustua.
+
+\subsection{Matematiikkatilan kielioppia}
+
+Matematiikan kirjoittaminen Latexissa on tehty varsin luonnolliseksi.
+Esimerkiksi tavalliset operaattorit ja kokonaisluvut kirjoitetaan
+näppäimistöltä sellaisenaan, ja jos desimaalierottimena on piste, sekin
+syötetään näppäimistöltä suoraan. Suomessa käytetään desimaalierottimena
+kuitenkin pilkkua, joka toimii Latexin matematiikkatilassa välimerkkinä:
+sen jälkeen ladotaan pieni väli. Suomalaisen desimaalierottimen saa
+kirjoittamalla pilkun ympärille aaltosulkeet.
+
+\mkomentoi{pi}
+\mkomentoi{approx}
+\begin{koodilohkosis}
+\[ \pi \approx 3{,}142 \]
+\end{koodilohkosis}
+\[ \pi \approx 3{,}142 \]
+
+\noindent
+Toinen vaihtoehto pilkun käyttämiseen desimaalierottimana on ladata
+paketti \pakettictan{icomma}. Paketti määrittelee matematiikkatilan
+pilkun toimimaan jokseenkin älykkäästi: jos lähdetiedostossa on pilkun
+jälkeen väli, pilkku ladotaan välimerkkinä; jos väliä ei ole, pilkku
+katsotaan desimaalierottimeksi.
+
+Plus-, jako- ja yhtäsuuruusmerkki sekä pienempi kuin ja suurempi kuin
+\=/merkit ($+ : / = \; < \; >$) kirjoitetaan näppäimistöltä
+sellaisenaan. Miinusmerkki ($-$) kirjoitetaan yhdysmerkin (\koodi{-})
+avulla, eli se ladotaan dokumenttiin Unicode\-/ merkistön miinusmerkkinä
+\uctunnus{u+2212 minus sign}. Kertomerkit voi kirjoittaa
+lähdedokumenttiin sellaisenaan mutta myös komennolla \mkomento{cdot}
+($\cdot$) tai \mkomento{times} ($\times$).
+
+Pienet sulkeetkin voi kirjoittaa näppäimistöltä suoraan, mutta
+matematiikassa tarvitaan usein erikokoisia, tilanteeseen mukautuvia
+sulkeita. Ne tehdään komentojen \mkomento{left} (vasen) ja
+\mkomento{right} (oikea) avulla. Komentojen jälkeen kirjoitetaan haluttu
+suljemerkki, esimerkiksi \mkomento{left}\mkomentojatko{(} ja
+\mkomento{right}\mkomentojatko{)}. Itseisarvoa merkitsevät pystyviivat
+tehdään samoilla komennoilla, mutta suljemerkkien tilalle kirjoitetaan
+pystyviiva~(\koodi{|}).
+
+\mkomentoi{left}
+\mkomentoi{right}
+\mkomentoi{frac}
+\begin{koodilohkosis}
+\[ \left| a + \left( \frac{b}{c \left( d-1 \right)} \right) \right| \]
+\end{koodilohkosis}
+\[ \left| a + \left( \frac{b}{c \left( d-1 \right)} \right) \right| \]
+
+\noindent
+Komentoja \mkomento{left} ja \mkomento{right} täytyy käyttää pareittain,
+jotta Latex osaa latoa oikeankokoiset sulkeet. Jos ei halua
+suljemerkille paria, kirjoitetaan toisen suljekomennon ''sulkeeksi''
+piste. Seuraavassa esimerkissä ladotaan vasemmalle aaltosulje
+(\mkomento{left}\mkomentojatko{\keno\{}) mutta oikealle ei mitään
+(\mkomento{right}\mkomentojatko{.}).
+
+\mkomentoi{left}
+\mkomentoi{right}
+\mymparistoi{array}
+\begin{koodilohkosis}
+\[ \left\{ \begin{array}{r@{~}l}
+ x &= 4 \\
+ y &= -2 \\
+ \end{array} \right. \]
+\end{koodilohkosis}
+\[ \left\{ \begin{array}{l@{~}l}
+ x &= 4 \\
+ y &= -2 \\
+ \end{array} \right. \]
+
+\noindent
+Matematiikkatilan ylä- ja alaindeksit toteutetaan sirkumfleksin
+(\koodi{\^{}}) ja alaviivan (\koodi{\_}) avulla. Välittömästä merkin
+jälkeen oleva merkki ladotaan ylä- tai alaindeksiksi, ja jos indeksi
+sisältää enemmän kuin yhden merkin, kirjoitetaan kokonaisuus
+aaltosulkeisiin. Joidenkin matemaattisten operaattorikomentojen
+yhteydessä indeksit ladotaan poikkeuksellisella tavalla, esimerkiksi
+kokonaan operaattorin ylä- tai alapuolelle.
+
+\mkomentoi{sum}
+\mkomentoi{int}
+\mkomentoi{lim}
+\mkomentoi{to}
+\mkomentoi{infty}
+\mkomentoi{qquad}
+\begin{koodilohkosis}
+\[ x^{n-1} \qquad x_i \qquad \sum_{i=1}^n \qquad
+ \int_0^\infty \qquad \lim_{n \to \infty} \]
+\end{koodilohkosis}
+\[ x^{n-1} \qquad x_i \qquad \sum_{i=1}^n \qquad
+ \int_0^\infty \qquad \lim_{n \to \infty} \]
+
+\noindent
+Lausekkeen osia voi ryhmitellä ylä- tai alapuolisella aaltosulkeella,
+jotka tehdään komennoilla \mkomento{overbrace} ja \mkomento{underbrace}.
+Jos näiden komentojen jälkeen käyttää ylä- tai alaindeksiä, se ladotaan
+sulkeen keskelle. Seuraavassa on esimerkki:
+
+\mkomentoi{overbrace}
+\mkomentoi{underbrace}
+\begin{koodilohkosis}
+\[ \overbrace{3x + x}^{4x} - \underbrace{5y - 2y}_{3y} = 4x - 3y \]
+\end{koodilohkosis}
+\[ \overbrace{3x + x}^{4x} - \underbrace{5y - 2y}_{3y} = 4x - 3y \]
+
+\noindent
+Muuttujien, funktion nimien tai muiden symbolien jäljessä oleva
+$'$\=/merkki tehdään yleisheittomerkin (\koodi{'}) avulla.
+Matematiikassa se voi tarkoittaa esimerkiksi funktion
+derivaattafunktiota, ja Unicode\-/ merkistössä merkin tunnus
+\uctunnus{u+2032 prime}.
+
+\mkomentoi{quad}
+\begin{koodilohkosis}
+\[ f(x) = 3x^2 - 2x \quad f'(x) = 6x - 2 \]
+\end{koodilohkosis}
+\[ f(x) = 3x^2 - 2x \quad f'(x) = 6x - 2 \]
+
+\noindent
+Murtoluvuille ja murtoviivan latomiseen on komento \mkomento{frac},
+jolle annetaan kaksi argumenttia: osoittaja ja nimittäjä. Neliö- ja muut
+juuret tehdään \mkomento{sqrt}\-/ komennolla, jolle annetaan ainakin
+yksi argumentti. Komennolle voi antaa hakasulkeissa toisenkin
+argumentin, joka ilmaisee juuriluvun. Seuraavassa on esimerkki
+murtoluvun, neliöjuuren ja kuutiojuuren toteuttamisesta:
+
+\mkomentoi{frac}
+\mkomentoi{sqrt}
+\mkomentoi{quad}
+\begin{koodilohkosis}
+\[ \frac{1}{3x + 1} \quad \sqrt{9} = \sqrt[3]{27} \]
+\end{koodilohkosis}
+\[ \frac{1}{3x + 1} \quad \sqrt{9} = \sqrt[3]{27} \]
+
+\noindent
+Vektorien nimien latomiseen eli merkkien yläpuoliselle nuolelle on oma
+komento \mkomento{vec}, joka toimii yhden kirjaimen kanssa. Kahden
+merkin mittaiseen nuoleen tarvitaan komentoa \mkomento{overrightarrow}
+(tai \mkomento{overleftarrow}).
+
+\mkomentoi{vec}
+\mkomentoi{overrightarrow}
+\mkomentoi{quad}
+\begin{koodilohkosis}
+\[ \vec{a} \quad \overrightarrow{AB} \]
+\end{koodilohkosis}
+\[ \vec{a} \quad \overrightarrow{AB} \]
+
+\noindent
+Matriisit voi toteuttaa luvussa \ref{luku/matematiikka-käyttö} esitellyn
+\mymparisto{array}\-/ ympäristön avulla, mutta kätevämpää on käyttää
+\paketti{amsmath}\-/ paketin ympäristöjä. Kullekin erilaiselle
+suljetyypille on oma ympäristönsä: \mymparisto{matrix},
+\mymparisto{pmatrix}~$(\,)$, \mymparisto{bmatrix}~$[\,]$,
+\mymparisto{Bmatrix}~$\{\,\}$, \mymparisto{vmatrix}~$|$ ja
+\mymparisto{Vmatrix}~$\|$. Ympäristön sisällä matriisin rivin solut
+erotetaan toisistaan samoin kuin taulukoissakin eli \koodi{\&}\=/
+merkillä ja rivinvaihto tehdään \mkomento{\keno}\=/ komennolla.
+Seuraavassa on esimerkki kahdesta eri ympäristöstä:
+
+\mymparistoi{matrix}
+\mymparistoi{bmatrix}
+\mkomentoi{qquad}
+\begin{koodilohkosis}
+\[ \begin{matrix} 1 & 2 \\ 3 & 4 \\ \end{matrix} \qquad
+ \begin{bmatrix}
+ 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \\
+ \end{bmatrix} \]
+\end{koodilohkosis}
+\[ \begin{matrix} 1 & 2 \\ 3 & 4 \\ \end{matrix} \qquad
+ \begin{bmatrix}
+ 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \\
+ \end{bmatrix} \]
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[3]{\mkomento{#1} & $#2$ & #3 \\}
+
+ \begin{tabular}{lll}
+ \toprule
+ \ots{Komento}
+ & \ots{Esimerkki}
+ & \ots{Merkitys} \\
+ \midrule
+ \rivi{mathrm}{\mathrm{ABC~abc}}{antiikva, serif, roman}
+ \rivi{mathsf}{\mathsf{ABC~abc}}{groteski, sans serif, gothic}
+ \rivi{mathtt}{\mathtt{ABC~abc}}{tasalevyinen, typewriter}
+ \rivi{mathcal}{\mathcal{ABC}}{kalligrafinen}
+ \midrule
+ \rivi{mathbf}{\mathbf{ABC~abc}}{lihavoitu, bold}
+ \rivi{mathit}{\mathit{ABC~abc}}{kursiivi, italic}
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Tekstin latominen matematiikkatilassa vaatii erityisen
+ komennon}
+ \label{tlk/matem-teksti}
+}
+
+\noindent
+Kuten on jo todettu, tavalliset kirjaimet on matematiikkatilassa
+tarkoitettu muuttujien nimiksi. Kun täytyy latoa varsinaista tekstiä --
+tekstitilan tavoin -- täytyy käyttää erityisiä komentoja. Taulukkoon
+\ref{tlk/matem-teksti} on koottu matematiikkatilan
+tekstinlatomiskomentoja. Komentojen argumenttina oleva teksti ladotaan
+kuin tekstitilassa.
+
+Vaakasuuntaisten välien tekemiseen on matematiikkatilassa muutama
+komento. Komento \mkomento{quad} latoo typografisen neliön (1\,em)
+levyisen välin. Se on sama kuin nykyisen fontin koko. Komento
+\mkomento{qquad} latoo 2\,em:n levyisen välin. Pienempiä välejä saa
+komennoilla \mkomento{,} (\murtoluku{3}{18}\,em), \mkomento{:}
+(\murtoluku{4}{18}\,em) ja \mkomento{;} (\murtoluku{5}{18}\,em). Komento
+\mkomento{!} puolestaan tuottaa negatiivisen välin, jonka mitta on
+−\murtoluku{3}{18}\,em. Negatiivista väliä voi käyttää liian suuren
+välin pienentämiseen.
+
+\subsection{Erikoismerkkejä}
+
+Matematiikkatilassa voi käyttää Unicode\-/ merkistöä, eli monet
+matemaattiset symbolit voi kirjoittaa lähdedokumenttiin sellaisenaan.
+Voi silti olla helpompaa käyttää erityisiä komentoja sellaisten
+kirjainten ja symbolien kirjoittamiseen, joita ei ihan helposti pysty
+tuottamaan näppäimistöltä tai tekstieditorin toimintojen avulla.
+Matematiikkatilan erikoismerkkejä on koottu oheisiin taulukoihin
+(\ref{tlk/matem-kreikk}--). Lisää symboleja on paketeissa
+\pakettictan{latexsym} ja \pakettictan{amsmath}.
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{$#1$ & \mkomento{#2}}
+
+ \begin{tabular}{*{4}{cl}}
+ \toprule
+
+ \rivi{\alpha}{alpha}
+ & \rivi{\Alpha}{Alpha}
+ & \rivi{\beta}{beta}
+ & \rivi{\Beta}{Beta} \\
+
+ \rivi{\gamma}{gamma}
+ & \rivi{\Gamma}{Gamma}
+ & \rivi{\delta}{delta}
+ & \rivi{\Delta}{Delta} \\
+
+ \rivi{\epsilon}{epsilon}
+ & \rivi{\varepsilon}{varepsilon}
+ & \rivi{\Epsilon}{Epsilon}
+ & \rivi{\zeta}{zeta} \\
+
+ \rivi{\Zeta}{Zeta}
+ & \rivi{\eta}{eta}
+ & \rivi{\Eta}{Eta}
+ & \rivi{\theta}{theta} \\
+
+ \rivi{\vartheta}{vartheta}
+ & \rivi{\Theta}{Theta}
+ & \rivi{\iota}{iota}
+ & \rivi{\Iota}{Iota} \\
+
+ \rivi{\kappa}{kappa}
+ & \rivi{\Kappa}{Kappa}
+ & \rivi{\lambda}{lambda}
+ & \rivi{\Lambda}{Lambda} \\
+
+ \rivi{\mu}{mu}
+ & \rivi{\Mu}{Mu}
+ & \rivi{\nu}{nu}
+ & \rivi{\Nu}{Nu} \\
+
+ \rivi{\xi}{xi}
+ & \rivi{\Xi}{Xi}
+ & \rivi{\pi}{pi}
+ & \rivi{\varpi}{varpi} \\
+
+ \rivi{\Pi}{Pi}
+ & \rivi{\rho}{rho}
+ & \rivi{\varrho}{varrho}
+ & \rivi{\Rho}{Rho} \\
+
+ \rivi{\sigma}{sigma}
+ & \rivi{\varsigma}{varsigma}
+ & \rivi{\Sigma}{Sigma}
+ & \rivi{\tau}{tau} \\
+
+ \rivi{\Tau}{Tau}
+ & \rivi{\upsilon}{upsilon}
+ & \rivi{\Upsilon}{Upsilon}
+ & \rivi{\phi}{phi} \\
+
+ \rivi{\varphi}{varphi}
+ & \rivi{\Phi}{Phi}
+ & \rivi{\chi}{chi}
+ & \rivi{\Chi}{Chi} \\
+
+ \rivi{\psi}{psi}
+ & \rivi{\Psi}{Psi}
+ & \rivi{\omega}{omega}
+ & \rivi{\Omega}{Omega} \\
+
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Kreikkalaisten kirjainten latominen matematiikkatilassa}
+ \label{tlk/matem-kreikk}
+}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[3][a]{$#2{#1}$ & \mkomento{#3}\mkomentoarg{#1}}
+
+ \begin{tabular}{*{3}{cl}}
+ \toprule
+
+ \rivi{\grave}{grave}
+ & \rivi{\ddot}{ddot}
+ & \rivi{\hat}{hat} \\
+
+ \rivi{\acute}{acute}
+ & \rivi{\check}{check}
+ & \rivi[aaa]{\widehat}{widehat} \\
+
+ \rivi{\breve}{breve}
+ & \rivi{\dot}{dot}
+ & \rivi{\tilde}{tilde} \\
+
+ \rivi{\bar}{bar}
+ & \rivi{\mathring}{mathring}
+ & \rivi[aaa]{\widetilde}{widetilde} \\
+
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Matematiikkatilan tarkekomentoja}
+ \label{tlk/matem-tarkkeita}
+}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[3][AB]{$#2{#1}$ & \mkomento{#3}\mkomentoarg{#1}}
+ \renewcommand{\arraystretch}{1.5}
+
+ \begin{tabular}{*{2}{cl}}
+ \toprule
+
+ \rivi{\overrightarrow}{overrightarrow}
+ & \rivi{\overleftarrow}{overleftarrow} \\
+
+ \rivi{\underrightarrow}{underrightarrow}
+ & \rivi{\underleftarrow}{underleftarrow} \\
+
+ \rivi{\overleftrightarrow}{overleftrightarrow}
+ & \rivi{\underleftrightarrow}{underleftrightarrow} \\
+
+ \rivi{\overline}{overline}
+ & \rivi{\underline}{underline} \\
+
+ \rivi[abc]{\overbrace}{overbrace}
+ & \rivi[abc]{\underbrace}{underbrace} \\
+
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Ylä- ja alamerkintöjä}
+ \label{tlk/matem-yla-ala-merk}
+}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{$#1$ & \mkomento{#2}}
+
+ \begin{tabular}{*{4}{cl}}
+ \toprule
+
+ $<$
+ & \koodi{<}
+ & $>$
+ & \koodi{>}
+ & $=$
+ & \koodi{=}
+ & $:$
+ & \koodi{:} \\
+
+ $\leq$
+ & \mkomento{leq} \mkomento{le}
+ & $\geq$
+ & \mkomento{geq} \mkomento{ge}
+ & \rivi{\ll}{ll}
+ & \rivi{\gg}{gg} \\
+
+ \rivi{\equiv}{equiv}
+ & \rivi{\doteq}{doteq}
+ & \rivi{\prec}{prec}
+ & \rivi{\preceq}{preceq} \\
+
+ \rivi{\succ}{succ}
+ & \rivi{\succeq}{succeq}
+ & \rivi{\sim}{sim}
+ & \rivi{\simeq}{simeq} \\
+
+ \rivi{\subset}{subset}
+ & \rivi{\subseteq}{subseteq}
+ & \rivi{\supset}{supset}
+ & \rivi{\supseteq}{supseteq} \\
+
+ \rivi{\approx}{approx}
+ & \rivi{\cong}{cong}
+ & \rivi{\sqsubset}{sqsubset}
+ & \rivi{\sqsubseteq}{sqsubseteq} \\
+
+ \rivi{\sqsupset}{sqsupset}
+ & \rivi{\sqsupseteq}{sqsupseteq}
+ & \rivi{\bowtie}{bowtie}
+ & \rivi{\in}{in} \\
+
+ \rivi{\ni}{ni}
+ & \rivi{\propto}{propto}
+ & \rivi{\vdash}{vdash}
+ & \rivi{\dashv}{dashv} \\
+
+ \rivi{\models}{models}
+ & \rivi{\mid}{mid}
+ & \rivi{\parallel}{parallel}
+ & \rivi{\perp}{perp} \\
+
+ \rivi{\smile}{smile}
+ & \rivi{\frown}{frown}
+ & \rivi{\asymp}{asymp}
+ & \rivi{\notin}{notin} \\
+
+ $\neq$
+ & \mkomento{neq} \mkomento{ne} \\
+
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Relaatioita. Negaation saa kirjoittamalla komennon eteen
+ \mkomento{not}}
+ \label{tlk/matem-relaatioita}
+}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{$#1$ & \mkomento{#2}}
+ \renewcommand{\arraystretch}{1.1}
+
+ \begin{tabular}{*{4}{cl}}
+ \toprule
+
+ $+$
+ & \koodi{+}
+ & $-$
+ & \koodi{-}
+ & \rivi{\pm}{pm}
+ & \rivi{\mp}{mp} \\
+
+ \rivi{\cdot}{cdot}
+ & \rivi{\div}{div}
+ & \rivi{\times}{times}
+ & \rivi{\setminus}{setminus} \\
+
+ \rivi{\cup}{cup}
+ & \rivi{\cap}{cap}
+ & \rivi{\sqcup}{sqcup}
+ & \rivi{\sqcap}{sqcap} \\
+
+ \rivi{\vee}{vee}
+ & \rivi{\wedge}{wedge}
+ & \rivi{\oplus}{oplus}
+ & \rivi{\ominus}{ominus} \\
+
+ \rivi{\odot}{odot}
+ & \rivi{\oslash}{oslash}
+ & \rivi{\uplus}{uplus}
+ & \rivi{\otimes}{otimes} \\
+
+ \rivi{\sum}{sum}
+ & \rivi{\prod}{prod}
+ & \rivi{\coprod}{coprod}
+ & \rivi{\int}{int} \\
+
+ \rivi{\oint}{oint}
+ & \rivi{\bigoplus}{bigoplus}
+ & \rivi{\bigotimes}{bigotimes}
+ & \rivi{\bigodot}{bigodot} \\
+
+ \rivi{\bigvee}{bigvee}
+ & \rivi{\bigwedge}{bigwedge}
+ & \rivi{\bigcup}{bigcup}
+ & \rivi{\bigcap}{bigcap} \\
+
+ \rivi{\biguplus}{biguplus}
+ & \rivi{\bigsqcup}{bigsqcup} \\
+
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Operaattoreita}
+ \label{tlk/matem-operaattoreita}
+}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{$#1$ & \mkomento{#2}}
+
+ \begin{tabular}{*{2}{cl}}
+ \toprule
+
+ \rivi{\leftarrow}{leftarrow}
+ & \rivi{\rightarrow}{rightarrow} \\
+
+ \rivi{\longleftarrow}{longleftarrow}
+ & \rivi{\longrightarrow}{longrightarrow} \\
+
+ \rivi{\leftrightarrow}{leftrightarrow}
+ & \rivi{\longleftrightarrow}{longleftrightarrow} \\
+
+ \rivi{\Leftarrow}{Leftarrow}
+ & \rivi{\Rightarrow}{Rightarrow} \\
+
+ \rivi{\Longleftarrow}{Longleftarrow}
+ & \rivi{\Longrightarrow}{Longrightarrow} \\
+
+ \rivi{\Leftrightarrow}{Leftrightarrow}
+ & \rivi{\Longleftrightarrow}{Longleftrightarrow} \\
+
+ \rivi{\mapsto}{mapsto}
+ & \rivi{\longmapsto}{longmapsto} \\
+
+ \rivi{\hookleftarrow}{hookleftarrow}
+ & \rivi{\hookrightarrow}{hookrightarrow} \\
+
+ \rivi{\leftharpoonup}{leftharpoonup}
+ & \rivi{\rightharpoonup}{rightharpoonup} \\
+
+ \rivi{\leftharpoondown}{leftharpoondown}
+ & \rivi{\rightharpoondown}{rightharpoondown} \\
+
+ \rivi{\rightleftharpoons}{rightleftharpoons}
+ & \rivi{\iff}{iff} \\
+
+ \rivi{\uparrow}{uparrow}
+ & \rivi{\downarrow}{downarrow} \\
+
+ \rivi{\updownarrow}{updownarrow}
+ & \rivi{\Updownarrow}{Updownarrow} \\
+
+ \rivi{\Uparrow}{Uparrow}
+ & \rivi{\Downarrow}{Downarrow} \\
+
+ \rivi{\nearrow}{nearrow}
+ & \rivi{\searrow}{searrow} \\
+
+ \rivi{\swarrow}{swarrow}
+ & \rivi{\nwarrow}{nwarrow} \\
+
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Nuolia}
+ \label{tlk/matem-nuolia}
+}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{$#1$ & \mkomento{#2}}
+
+ \begin{tabular}{*{4}{cl}}
+ \toprule
+
+ \rivi{\langle}{langle}
+ & \rivi{\rangle}{rangle}
+ & \rivi{\lfloor}{lfloor}
+ & \rivi{\rfloor}{rfloor} \\
+
+ \rivi{\rceil}{rceil}
+ & \rivi{\lceil}{lceil}
+ & $|$
+ & \koodi{|} \mkomento{vert}
+ & $\|$
+ & \mkomentox{|} \mkomento{Vert} \\
+
+ \rivi{\lgroup}{lgroup}
+ & \rivi{\rgroup}{rgroup}
+ & \rivi{\lmoustache}{lmoustache}
+ & \rivi{\rmoustache}{rmoustache} \\
+
+ $/$
+ & \koodi{/}
+ & \rivi{\backslash}{backslash} \\
+
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Sulkeita ja erotinmerkkejä}
+ \label{tlk/matem-erottimia}
+}
+
+\leijutlk{
+ \providecommand{\rivi}{}
+ \renewcommand{\rivi}[2]{$#1$ & \mkomento{#2}}
+
+ \begin{tabular}{*{3}{cl}}
+ \toprule
+
+ $\neg$
+ & \mkomento{neg} \mkomento{lnot}
+ & \rivi{\angle}{angle}
+ & \rivi{\emptyset}{emptyset} \\
+
+ \rivi{\infty}{infty}
+ & $'$
+ & \koodi{'}
+ & \rivi{\prime}{prime} \\
+
+ \rivi{\forall}{forall}
+ & \rivi{\exists}{exists}
+ & \rivi{\wr}{wr} \\
+
+ \rivi{\bot}{bot}
+ & \rivi{\top}{top}
+ & \rivi{\surd}{surd} \\
+
+ \rivi{\dots}{dots}
+ & \rivi{\cdots}{cdots}
+ & \rivi{\vdots}{vdots} \\
+
+ \rivi{\ddots}{ddots}
+ & \rivi{\triangle}{triangle}
+ & \rivi{\triangleleft}{triangleleft} \\
+
+ \rivi{\triangleright}{triangleright}
+ & \rivi{\nabla}{nabla}
+ & \rivi{\star}{star} \\
+
+ \rivi{\ast}{ast}
+ & \rivi{\circ}{circ}
+ & \rivi{\bigcirc}{bigcirc} \\
+
+ \rivi{\bullet}{bullet}
+ & \begin{tikzpicture} % \diamond puuttuu fontista
+ \draw [rotate=45] (0,0) rectangle (.5ex,.5ex);
+ \end{tikzpicture}
+ & \mkomento{diamond}
+ & \rivi{\amalg}{amalg} \\
+
+ \rivi{\bigtriangleup}{bigtriangleup}
+ & \rivi{\bigtriangledown}{bigtriangledown}
+ & \rivi{\dagger}{dagger} \\
+
+ \rivi{\ddagger}{ddagger}
+ & \rivi{\diamondsuit}{diamondsuit}
+ & \rivi{\heartsuit}{heartsuit} \\
+
+ \rivi{\clubsuit}{clubsuit}
+ & \rivi{\spadesuit}{spadesuit}
+ & \rivi{\flat}{flat} \\
+
+ \rivi{\natural}{natural}
+ & \rivi{\sharp}{sharp}
+ & \rivi{\hbar}{hbar} \\
+
+ \rivi{\imath}{imath}
+ & \rivi{\jmath}{jmath}
+ & \rivi{\ell}{ell} \\
+
+ \rivi{\Re}{Re}
+ & \rivi{\Im}{Im}
+ & \rivi{\aleph}{aleph} \\
+
+ \rivi{\wp}{wp} \\
+
+ \bottomrule
+ \end{tabular}
+}{
+ \caption{Sekalaisia symboleja}
+ \label{tlk/matem-sekalaisia}
+}
diff --git a/info/kaytannollista-latexia/luku-valmistautuminen.tex b/info/kaytannollista-latexia/luku-valmistautuminen.tex
new file mode 100644
index 0000000000..5913cf0c88
--- /dev/null
+++ b/info/kaytannollista-latexia/luku-valmistautuminen.tex
@@ -0,0 +1,430 @@
+% Tekijä: Teemu Likonen <tlikonen@iki.fi>
+% Lisenssi: Creative Commons Nimeä-JaaSamoin 4.0 Kansainvälinen (CC BY-SA 4.0)
+% https://creativecommons.org/licenses/by-sa/4.0/legalcode.fi
+
+\chapter{Valmistautuminen}
+
+Tämän pääluvun tarkoituksena on johdatella uudet ihmiset Latexin pariin.
+Tämän luettuasi sinun pitäisi olla valmis aloittamaan Latexin käyttö ja
+opiskelemaan sen tekniikkaa eteenpäin. Jos taas olet jo tottunut
+kääntämään Latex\-/ lähdetiedostoja, voit aivan hyvin hypätä tämän luvun
+yli tai ehkä vain silmäillä tekstiä lisävinkkien toivossa.
+
+\section{Käsitteet ja nimet}
+
+Latex ja sen ympärille rakentuneet ohjelmistot ovat aika monimutkainen
+kokonaisuus, johon kuuluu eri\-/ikäisiä ja abstraktiotasoltaan erilaisia
+osia. Mukaan kuuluu tietenkin konkreettisia tietokoneohjelmia, jotka
+tekevät konkreettisia, ennalta määriteltyjä asioita. Mukaan kuuluu
+kuitenkin myös ihmisten luomia abstrakteja käsitteitä, jotka ovat
+vaikeammin määriteltävissä.
+
+Internetissä näkyy silloin tällöin termi- ja käsitekeskusteluja, jossa
+ihmetellään, mihin mikäkin Latexiin liittyvä palikka kuuluu
+käsitteellisesti. Millainen suhde joillakin uudemmilla osilla on
+vanhempiin? Oikeiden termien ja käsitteiden osaamisesta on hyötyä
+ainakin silloin, kun pyytää verkossa apua suurelta yleisöltä.
+Viestintähän aina vaatii, että puhutaan suunnilleen samaa kieltä, joten
+seuraavaksi selvennetään hieman Latexiin liittyviä peruskäsitteitä.
+
+\subsection{Tex ja Latex}
+
+Tex on tekstin ladontaan erikoistunut ohjelmointikieli. Kielen avulla
+voidaan antaa ladontaohjeita ja ilmaista muuta siihen liittyvää
+logiikkaa. Ohjelmointikielellä kirjoitettujen ohjeiden perusteella
+tietokoneohjelma osaa latoa tekstidokumentin ihmisten luettavaksi.
+Niinpä Tex on myös tietokoneohjelma (\koodi{tex}), joka osaa lukea
+Tex\-/ ohjelmointikieltä sisältävän tekstitiedoston ja tuottaa sen
+perusteella valmiin julkaistavan dokumentin. Yleensä Tex\-/
+ohjelmointikieltä ei kuitenkaan käytetä suoraan tekstidokumenttien
+toteuttamiseen. Ohjelmointikieltä kirjoittavat tavallisimmin vain ne,
+jotka haluavat kehittää itse ladontajärjestelmää paremmaksi muita
+ihmisiä varten.
+
+Latex toimii korkeammalla abstraktiotasolla kuin Tex. Se on laaja
+kokoelma toimintoja, jotka piilottavat monimutkaiset tekniset
+yksityiskohdat ja tarjoavat ihmisille varsin helppokäyttöisen
+merkintäkielen, jolla omat tekstidokumentit voi toteuttaa. Latex\-/
+merkintäkielen kirjoittaminen ei ole ohjelmointia, vaan se on oman
+dokumentin sisällön, rakenteen ja ulkoasun kuvailua tietynlaisten
+merkintätapojen avulla.
+
+Latex\-/ merkintäkielellä kuvatut dokumentit välitetään
+tietokoneohjelmalle jatkokäsiteltäväksi. Niinpä Latex on myös
+tietokoneohjelma (\koodi{latex}, \koodi{pdflatex}), jolla
+merkintäkielinen lähdetiedosto käännetään julkaistavaksi dvi- tai pdf\-/
+dokumentiksi.%
+\footnote{\textsc{dvi} = device independent file format; \textsc{pdf} =
+ portable document format.}
+
+Latex\-/ järjestelmästä käytetään tällä hetkellä versiota Latex~2ε, joka
+julkaistiin jo vuonna 1994 ja johon ilmestyy pieniä parannuksia
+vuosittain. Perusosat ovat kuitenkin varsin muuttumattomia. Varsinainen
+kiinnostava kehitys tapahtuukin esimerkiksi Latexin kääntäjissä
+(Lualatex ja Xelatex) sekä eri tekijöiden dokumenttiluokissa (luku
+\ref{luku/dokumenttiluokat}) ja laajennuspaketeissa. Viimeksi mainitut
+laajentavat perus\-/ Latexia tuomalla niihin lisää helppokäyttöisiä
+toimintoja.
+
+\subsection{Lualatex ja Xelatex}
+
+Nykyaikana Latex\-/ dokumentteja ei juuri käännetä alkuperäisillä
+kääntäjillä (\koodi{latex}, \koodi{pdflatex}, \koodi{tex}) vaan
+kehittyneemmillä kääntäjäohjelmilla.%
+\footnote{Englannin kielellä Latexin kääntäjiä on tapana kutsua
+ yleisnimellä \englantik{engine} 'kone, moottori'.} Niistä tärkeimmät
+ovat Lualatex ja Xelatex.%
+\footnote{Tietokoneohjelmat \koodi{lualatex} ja \koodi{luatex} sekä
+ \koodi{xelatex} ja \koodi{xetex}.} Ne muun muassa osaavat lukea
+Unicode\-/ merkistöllä kirjoitettuja lähdedokumentteja ja käyttää
+nykyaikaisia \englanti{True Type}- ja \englanti{Open Type} \=/fontteja,
+mitä alkuperäinen Latex ja Tex eivät osaa.
+
+Lualatexilla ja Xelatexilla ei ole ohjelmien käyttäjän kannalta
+suurtakaan eroa -- ei välttämättä mitään näkyvää eroa. Miksi sitten on
+olemassa kaksi, ulkoisesti lähes samanlaista kääntäjää? Tärkein syy
+taitaa olla se, että Xelatex tehtiin ensin. Tarkoituksena oli saada
+Unicode\-/ merkistön tuki ja fonttiasiat ajan tasalle. Myöhemmin jotkut
+ajattelivat, että Lua\-/ ohjelmointikieli täytyy saada mukaan. Sillä on
+merkitystä joillekuille laajennuspakettien tekijöille. Lua\-/ kielen
+sisällyttäminen oikeastaan pakotti kirjoittamaan koko homman uusiksi.
+Toteutuksissa on muitakin sisäisiä eroja. Xelatex oli pitkään suositumpi
+ja paremmin tuettu eri laajennuspaketeissa, mutta erot ovat sittemmin
+tasoittuneet.
+
+Latex\-/ kokeilun alkutaipaleella voi vaikka arpoa kolikon avulla,
+kumpaa kääntäjää käyttää, sillä niiden erot eivät ihan helposti tule
+esiin. Jotkin harvat laajennuspaketit eivät toimi Lualatexissa, kun taas
+toiset eivät toimi Xelatexissa. Joskus saattaa jopa tulla vastaan
+yksittäinen, kehityksestä ehkä jälkeen jäänyt paketti, joka ei toimi
+kummassakaan vaan ainoastaan perinteisillä kääntäjillä (\koodi{latex},
+\koodi{pdflatex}).
+
+Joissakin tilanteissa eri kääntäjien tekemissä pdf\-/ dokumenteissa
+näkyy pieniä eroja. Ainakin yksittäisissä fonttien asetuksissa ja
+joidenkin Unicode\-/ merkkien käsittelyssä on eroja. Tämänkin oppaan
+tekstissä mainitaan pari pientä ominaisuutta, jotka toimivat vain
+toisella kääntäjällä: toiset Lualatexilla, toiset Xelatexilla. Itse
+oppaan lähdetiedostot kääntyvät ja toimivat yhtä lailla molemmilla.
+
+\subsection{Latex yläkäsitteenä}
+
+Jotta kaikki olisi mahdollisimman sekavaa, ''Latex'' toimii myös
+yleisnimityksenä tälle kaikelle. Se esiintyy ilmauksissa kuten
+''Toteutin dokumentin Latexilla'' tai ''Tämä artikkeli on tehty
+Latexilla''. Ilmaukset sitten tarkoittavat suunnilleen seuraavanlaista:
+Henkilöllä on asennettuna tietokoneelle Latex\-/ jakelukokonaisuus
+(kuten Tex Live). Hän on kirjoittanut tekstieditorilla (kuten
+\textsc{gnu} Emacsilla) tekstitiedoston, jossa on dokumentin sisältö ja
+Latex\-/ merkintäkielisiä komentoja mutta ehkä myös joitakin Tex\-/
+komentoja. Sitten hän on kääntänyt eli ladotuttanut tekstitiedostonsa
+pdf\-/ tiedostoksi Latex\-/ ladontaohjelman jollakin toteutuksella kuten
+Lualatexilla tai Xelatexilla.
+
+Meille taitaa riittää vain Latexista puhuminen, mutta siitäkin on
+mainittava vielä yksi asia. Latexin harrastajat tykkäävät käyttää
+dokumenttiensa leipätekstissä ladontajärjestelmän logoja kuten \TeX{} ja
+\LaTeX{}. Usein teksteissä näkyy myös logojen pohjalta mukailtuja
+kirjoitusasuja TeX ja LaTeX.
+
+Kielenhuoltajien suositusten mukaan logojen eikä erikoisten
+kIRjoiTusAsuJen paikka ei ole asiatyylisten tekstilajien leipätekstissä.
+Nimet ovat osa kielen järjestelmää ja käyttäytyvät normaalissa tekstissä
+sen mukaisesti. Niinpä tässä oppaassa käytetään erisnimiä kielenhuollon
+normien mukaisesti, esimerkiksi Tex ja Latex. Koodi ja komennot ovat
+siinä muodossa kuin ne tietokoneelle annetaan, esimerkiksi
+\koodi{lualatex}. Tasalevyinen, kirjoituskonetyylinen fontti on merkkinä
+siitä, että kyse on tietokonekoodista.
+
+\section{Asentaminen tietokoneelle}
+\label{luku/asentaminen}
+
+Latex pitää tietysti asentaa tietokoneelle, jotta sitä voisi käyttää.
+Miten edellisessä luvussa kuvattu sekava kokonaisuus saadaan ehjänä
+omalle tietokoneelle? Onneksi muut ovat jo ratkaisseet sen ongelman.
+
+Tavallisin tapa Latexin käyttöönottoon on jonkin Latexin jakelupaketin
+asentaminen. Jakelupaketti sisältää Latexin perusosien lisäksi paljon
+laajennuspaketteja ja niiden ohjekirjoja. Kaikkea ei koskaan tarvitse,
+mutta kun yllättävä tarve tulee tai lukee vinkkejä verkkokeskusteluista,
+on mukavaa huomata, että paketti olikin itsellä jo valmiina. Siksi
+suosittelen kokonaisen jakelupaketin asentamista.
+
+\textsc{gnu}/Linuxissa ja muissa Unix\-/ tyyppisissä
+käyttöjärjestelmissä käytetään yleensä Tex Live \=/nimistä jakelua. Se
+on todennäköisesti saatavilla käyttöjärjestelmäjakelun
+pakettivarastoista. Esimerkiksi Debianiin%
+\footnote{\url{https://www.debian.org/}} ja sen kaltaisiin järjestelmiin
+on asennuspaketti ''texlive-full'', joka asentaa kaiken helposti ja
+kerralla.
+
+Windows\-/ käyttöjärjestelmälle on saatavilla Tex Liven lisäksi Miktex
+ja Protext. Mac \textsc{os} \=/käyttöjärjestelmän kanssa käytettäneen
+yleensä Mactex\-/ nimistä jakelua.
+
+\section{Apuohjelmia}
+
+\subsection{Tekstieditori}
+
+Omien dokumenttien ja Latex\-/ merkintäkielen kirjoittamiseen kannattaa
+käyttää kunnollista tekstieditoria, koska se on tärkein työkalu ja sen
+kanssa ollaan eniten tekemisissä. Pyri löytämään sellainen editori, joka
+osaa värjätä tekstiä Latexin tai Texin tekstipiirteiden mukaisesti.
+Väreillä ei sinänsä ole merkitystä, mutta editorin laadusta se yleensä
+kertoo paljon. Jos editori tuntee erilaisten ohjelmointi\-/{} ja
+merkintäkielten luonnetta ja osaa merkitä kielen avainsanoja
+havainnollisilla väreillä, se todennäköisesti on tehty tehokkaaseen
+ohjelmointiin ja muuhun vastaavaan työskentelyyn. Ihan yksinkertaisiin
+editoreihin ei tuollaisia ominaisuuksia yleensä tehdä.
+
+\subsection{Pdf-katselin}
+
+Latex\-/ kääntäjät eli \=/moottorit kuten Lualatex ja Xelatex tuottavat
+pdf\-/ tiedoston, ja niiden katselemiseen tarvitaan tietenkin oma
+ohjelmansa. Sellaisia on saatavilla paljon erilaisia, ja melkein mikä
+tahansa kelpaa, mutta yksi tietty ominaisuus olisi toivottavaa olla:
+muuttuneen pdf\-/ tiedoston automaattinen lataaminen.
+
+Välillä työskentely on sitä, että tehdään Latex\-/ dokumenttiin pieni
+muutos, käännetään se ja katsotaan pdf:ää. Lopputulos ei ehkä ihan
+miellytä. Muokataan tekstiä tai asetuksia vähän, käännetään ja
+katsotaan, miltä ladottu pdf nyt näyttää.
+
+On suuri apu, jos pdf\-/ katselimessa ei tarvitse joka kerta valikoiden
+kautta avata samaa tiedostoa uudelleen, vaan ohjelma itse huomaa, että
+jo avattu tiedosto muuttui tiedostojärjestelmässä, ja lataa sen
+automaattisesti uudelleen. Jotkin pdf\-/ ohjelmat osaavat tämän. Jotkin
+ohjelmat eivät ihan osaa mutta osaavat sentään yhdellä
+näppäinpainalluksella avata saman pdf:n uudelleen
+tiedostojärjestelmästä.
+
+Hyvän tekstieditorin ja pdf\-/ katselimen kanssa työskentely on sujuvaa.
+Parhaimmillaan editorissa tietty näppäinkomento tallentaa ja kääntää
+dokumentin, ja pian pdf\-/ katselin lataa muuttuneen pdf:n
+automaattisesti näkyviin. Sekä editorin että pdf\-/ katselimen voi pitää
+samanaikaisesti esillä.
+
+\subsection{Latexmk}
+\label{luku/latexmk}
+
+Erinomaisen hyödyllinen apuohjelma on Latexmk, koska se helpottaa
+dokumenttien kääntämistä ja muutakin työskentelyä. Varsin usein Latex\-/
+dokumentit täytyy kääntää useita kertoja ennen kuin pdf\-/ tiedosto on
+valmis. Tämä johtuu siitä, että dokumentit sisältävät usein
+ristiviitteitä eli viittauksia dokumentin toisiin osiin. Latex ei saa
+ristiviitteitä kohdalleen yhdellä kääntämisellä, vaan ensin se
+kirjoittaa viittausten kohteet muistiin väliaikaistiedostoon ja
+seuraavilla kääntökerroilla käyttää väliaikaistiedostoa apunaan.
+
+Tavallinenkin Latexin kääntäjä kyllä huomauttaa tietokoneen käyttäjää,
+kun uusintakäännös on tarpeen, mutta Latexmk\-/ ohjelma käynnistää
+uusintakäännöksen itse, aina kun se on tarpeellista. Alla ovat
+esimerkkikomennot Latex\-/ dokumentin kääntämiseen Lualatexilla ja
+Xelatexilla.
+
+\begin{koodilohkosis}
+latexmk -lualatex teksti.tex
+latexmk -xelatex teksti.tex
+\end{koodilohkosis}
+
+\noindent
+Työskentelyä erityisen paljon helpottava valitsin on \koodi{\=/pvc}. Kun
+tuo valitsin on mukana komennossa, Latexmk jää tarkkailemaan annettua
+Latex\-/ tiedostoa, ja kun se huomaa tiedoston muuttuneen, se kääntää
+tiedoston automaattisesti uudelleen. Kirjoittajan ei siis tarvitse muuta
+kuin tallentaa tiedosto tekstieditorista, ja tarkkailutilassa oleva
+Latexmk kääntää sen aina itsestään.
+
+Muitakin hyödyllisiä toimintoja on mukana. Seuraavista esimerkeistä
+ensimmäinen komento poistaa kääntämisen aikana luodut
+väliaikaistiedostot,%
+\footnote{Kääntäjän luomien väliaikaistiedostojen nimien päätteitä:
+ \koodi{log}, \koodi{aux}, \koodi{out} ym.} ja jälkimmäinen komento
+poistaa kaikki luodut tiedostot eli väliaikaistiedostojen lisäksi myös
+valmiin pdf\-/ tiedoston.
+
+\begin{koodilohkosis}
+latexmk -c teksti.tex
+latexmk -C teksti.tex
+\end{koodilohkosis}
+
+\noindent
+Edellisissä esimerkeissä käsitellään lähdetiedostoa nimeltä
+\koodi{teksti.\katk tex}, mutta jos lähdetiedostoa ei anna komennolle
+lainkaan, käännetään kaikki nykyisessä hakemistossa olevat
+\koodi{tex}\-/ päätteiset tiedostot.
+
+Latexmk\-/ ohjelmalle voi tehdä asetustiedoston, johon voi kirjoittaa
+omaan käyttöön sopivat asetukset. Asetustiedosto sijoitetaan
+tiedostojärjestelmässä käyttäjän kotihakemistoon. Esimerkki
+\ref{esim/latexmkrc} näyttää, mitä se voisi ehkä sisältää.
+
+\begin{esimerkki*}
+\begin{koodilohko}
+$pdf_mode = 4; # 4=lualatex, 5=xelatex
+$lualatex = 'lualatex -interaction=nonstopmode -shell-escape %O %S';
+$xelatex = 'xelatex -interaction=nonstopmode -shell-escape %O %S';
+$clean_ext = 'snm nav xdv bbl run.xml';
+$pdf_previewer = 'okular %S';
+\end{koodilohko}
+ \caption{Latexmk\-/ ohjelman asetustiedosto (\koodi{\textasciitilde
+ /.config/\katk latexmk/\katk latexmkrc})}
+ \label{esim/latexmkrc}
+\end{esimerkki*}
+
+Esimerkin ensimmäisen rivin asetus määrittää, miten pdf\-/ tiedostot
+tuotetaan tai mitä kääntäjää käytetään oletuksena. Toisella ja
+kolmannella rivillä määritellään, millä tavoin Lualatex ja Xelatex
+suoritetaan. Tässä esimerkissä oletusasetuksiin on lisätty
+\koodi{-inter\-action=\katk non\-stop\-mode}, joka estää kaiken
+vuorovaikutteisen toiminnan. Asetus on tarpeen ainakin silloin, kun
+kääntäjä käynnistetään toisesta ohjelmasta kuten tekstieditorista eikä
+vuorovaikutus kääntäjän kanssa ole mahdollista. Valitsin
+\koodi{-shell-escape} kytkee päälle ominaisuuden, jota tarvitaan
+joidenkin laajennuspakettien toimintaan.\footnote{Ainakin
+ asiahakemistopaketit \paketti{indextools} ja \paketti{imakeidx}
+ tarvitsevat \koodi{-shell-escape}\-/ toiminnon (luku
+ \ref{luku/asiasanat}).}
+
+Esimerkin \ref{esim/latexmkrc} neljännellä rivillä luetellaan
+kääntämisen aikana syntyvien väliaikaistiedostojen päätteitä. Latexmk\-/
+ohjelma tuntee yleisimmät väliaikaistiedostot (\koodi{log}, \koodi{aux},
+\koodi{out} ym.), mutta tällä asetuksella mukaan voi lisätä
+harvinaisempia, joita se ei tunne. Viides rivi määrittää pdf\-/
+katseluohjelman, joka käynnistetään, kun käytetään valitsimia
+\koodi{\=/pv} tai \koodi{\=/pvc}.
+
+\subsection{Texdoc}
+
+Latexin kirjoittajan täytyy silloin tällöin lukea ohjekirjoja. Vaikka
+Latexin perusosat joskus oppisikin ulkoa, ei voi koskaan muistaa
+kaikkien hyödyllisten laajennuspakettien kaikkia ominaisuuksia.
+
+Tex Live \=/jakelun (luku \ref{luku/asentaminen}) mukana tulee mainio
+komentotulkissa toimiva komento \koodi{texdoc}, jolla voi hakea ja avata
+omaan järjestelmään asennettuja Latex\-/ aiheisia ohjeita. Jos vaikka
+haluaa tutustua esimerkissä \ref{esim/ensimmäinen}
+(s.~\pageref{esim/ensimmäinen}) mainittavaan \paketti{fontspec}\-/
+pakettiin syvällisemmin, tarvitsee vain komentaa \koodi{texdoc
+ fontspec}, ja paketin pdf\-/ muotoinen ohjekirja avautuu.
+
+\section{Lähdetiedostot}
+
+Seuraavassa ovat ohjeet alkuun pääsemiseksi. Luodaan yksinkertainen
+Latex\-/ lähdetiedosto, jota voi käyttää harjoitteluun ja pohjana omille
+töille. Tallenna esimerkin \ref{esim/ensimmäinen} sisältö tekstieditorin
+avulla tiedostoon vaikkapa nimellä \koodi{teksti.\katk tex}. Käännä eli
+lado se pdf\-/ tiedostoksi käyttämällä jotakin seuraavista komennoista
+(valitse yksi):
+
+\begin{koodilohkosis}
+lualatex teksti.tex
+xelatex teksti.tex
+latexmk -lualatex teksti.tex
+latexmk -xelatex teksti.tex
+\end{koodilohkosis}
+
+\noindent
+Tuloksena pitäisi olla tiedosto \koodi{teksti.\katk pdf}, jota voi
+ihailla jollakin pdf\-/ tiedostojen katseluun tarkoitetulla ohjelmalla.
+
+Esimerkin \ref{esim/ensimmäinen} ensimmäisellä rivillä määritellään
+dokumenttiluokka \luokka{article}, joka on tietynlainen sivupohja tai
+asetusten kokoelma, jonka perustalle aletaan rakentaa omaa dokumenttia.
+Luokka \luokka{article} on tyypillinen valinta lyhyehköille teksteille.
+Lisätietoa dokumenttiluokista on luvussa \ref{luku/dokumenttiluokat}.
+
+Riveillä 2--4 käytetään komentoa \komentom{usepackage}, jonka avulla
+otetaan käyttöön sivun asetuksista huolehtiva \paketti{geometry}\-/
+paketti, fonttiasetuksia hoitava \paketti{fontspec}\-/ paketti ja
+kieliasetuksista vastaava \paketti{polyglossia}\-/ paketti. Näitä kolmea
+tarvitaan melkein joka kerta dokumenteissa, ja niihin palataan tarkemmin
+luvuissa \ref{luku/sivuasetukset}, \ref{luku/kirjaintyypit} ja
+\ref{luku/kieliasetukset}.
+
+Seuraavilla riveillä asetetaan kieleksi suomi (\koodi{finnish}) ja
+määritetään oletuksena käytettävä fontti tai oikeastaan kokonainen
+kirjainperhe. \englanti{Latin Modern Roman} \=/kirjainperheen tilalle
+voi toki asettaa jonkin muunkin. Fontin oletuskoko on 10 typografista
+pistettä, mutta tässä esimerkissä se venytetään 1,3\-/ kertaiseksi eli
+13 pisteeseen. Riviväliin liittyvä kerroin asetetaan rivillä 8.
+
+\begin{esimerkki*}
+ \komentoi{begin}
+ \komentoi{documentclass}
+ \komentoi{end}
+ \komentoi{linespread}
+ \komentoi{setdefaultlanguage}
+ \komentoi{setmainfont}
+ \komentoi{usepackage}
+ \luokkai{article}
+ \pakettii{fontspec}
+ \pakettii{geometry}
+ \pakettii{polyglossia}
+ \ymparistoi{document}
+
+\begin{koodilohko}
+\documentclass{article}
+\usepackage[a4paper,top=20mm,bottom=30mm,left=20mm,right=20mm]{geometry}
+\usepackage{fontspec}
+\usepackage{polyglossia}
+
+\setdefaultlanguage{finnish}
+\setmainfont{Latin Modern Roman}[Scale=1.3]
+\linespread{1.4}
+
+\begin{document}
+
+Minun Latex-dokumenttini!
+
+\end{document}
+\end{koodilohko}
+ \caption{Latex\-/ lähdedokumentin runko ja perusasetukset}
+ \label{esim/ensimmäinen}
+\end{esimerkki*}
+
+Dokumentin alkuosaa riville 9 saakka kutsutaan esittelyosaksi
+(\englanti{preamble}). Tässä osassa ladataan tarvittavat paketit ja
+määritetään dokumentin asetuksia ja taustatietoja. Riviltä 10 alkaa
+varsinainen tekstiosa eli dokumentin sivuille ladottava sisältö. Se osa
+kirjoitetaan \ymparistom{document}\-/ ympäristön sisään eli riveillä 10
+ja 14 olevien ympäristön aloitus\-/\ ja lopetuskomentojen väliin
+(\komento{begin}, \komento{end}).
+
+Tällaisen merkintäkielen avulla dokumentit kirjoitetaan. Osa
+merkintäkielen komennoista tulee Latexin perusosasta ja osa tulee
+erikseen ladattavista paketeista (\paketti{geometry},
+\paketti{fontspec}, \paketti{polyglossia} ym.). Komentoja voi luoda
+itsekin.
+
+Myöhempää käyttöä varten voisi olla hyödyllistä tallentaa tämänkaltainen
+pohjadokumentti. Välttyy samojen perusjuttujen kirjoittamiselta, kun voi
+aloittaa työt valmiista dokumenttipohjasta.
+
+Lähdetiedoston nimissä kannattaa pitäytyä melko suppeassa
+merkkivalikoimassa, ja varsinkin välilyöntejä kannattaa välttää.
+Nimittäin kääntämisen aikana Latex ja sen paketit luovat
+väliaikaistiedostoja, joilla sama nimen osa kuin lähdetiedostossa, ja
+näitä tiedostoja saattavat käsitellä monet erilaiset taustalla
+vaikuttavat työkaluohjelmat. Tiedoston nimissä olevat välilyönnit ja
+ehkä muutkin erikoisemmat merkit aiheuttavat ongelmia.
+
+Pitkä lähdedokumentti voi olla mielekästä jakaa useammaksi tiedostoksi.
+Yhteen lähdetiedostoon voi sisällyttää toisen tiedoston käyttämällä
+\komento{input}\-/ komentoa. Komennon argumentiksi annetaan ladattavan
+lähdetiedoston nimi:
+
+\komentoi{input}
+\begin{koodilohkosis}
+\input{toinen.tex}
+\end{koodilohkosis}
+
+\noindent
+Hieman vastaava komento on \komento{include}, joka myös lisää
+automaattisen sivunvaihdon (\komento{clearpage}, luku
+\ref{luku/sivunvaihdot}) komennon kohdalle.
+
+Nyt lienee sopiva aika alkaa opiskella itse Latexia eli merkintäkieltä
+ja kokeilla sen ominaisuuksia itse. Tätä opasta ei tarvitse lukea
+järjestyksessä luku luvulta eteenpäin, vaan eri aiheita voi vapaasti
+opiskella mielenkiinnon ja tarpeiden mukaan. Onnea matkaan!
diff --git a/info/kaytannollista-latexia/tavutusvihjeet.tex b/info/kaytannollista-latexia/tavutusvihjeet.tex
new file mode 100644
index 0000000000..1cd01665d7
--- /dev/null
+++ b/info/kaytannollista-latexia/tavutusvihjeet.tex
@@ -0,0 +1,796 @@
+\hyphenation{
+ab-stract
+abst-ra-hoin-ti
+abst-rak-te-ja
+abst-rak-tio-ta-soil-la
+abst-rak-tio-ta-sol-la
+abst-rak-tio-ta-sol-taan
+abst-rak-tio-ta-son
+add-bib-re-source
+add-con-tents-line
+add-font-fea-tures
+ad-dress
+add-to
+add-to-con-tents
+add-to-counter
+add-to-length
+add-vspace
+akuut-ti-ak-sen-tin
+ala-in-dek-seil-le
+ala-in-dek-se-jä
+ala-in-dek-sien
+ala-in-dek-si-ko-men-not
+ala-in-dek-sik-si
+ala-in-dek-sin
+ala-in-dek-sit
+ala-in-dek-si-toi-min-to
+ala-in-dek-siä
+ala-osaan
+ala-ot-sik-ko
+ala-otsi-kon
+alku-osaa
+angle
+an-tiik-va
+an-tiik-vaa
+an-tiik-vaan
+an-tiik-van
+an-tiik-vas-sa
+an-tiik-vat
+an-tiik-vo-jen
+ap-pendix
+apu-ohjel-ma
+array-back-slash
+array-rule-width
+array-stretch
+ar-ti-cle
+as-pect-ra-tio
+author
+babel
+babel-font
+babel-tags
+back-ground
+back-mat-ter
+base-line-skip
+beamer
+bf-se-ries
+biber
+bib-font
+bib-hang
+bib-init-sep
+bib-item
+bib-item-sep
+bib-latex
+bib-name
+bib-name-sep
+bib-section
+bib-sep
+big-break
+big-skip
+big-skip-amount
+bi-nää-ri-ope-raat-to-rit
+book-marks-num-ber-ed
+book-marks-open
+book-tabs
+bottom-frac-tion
+bottom-number
+bottom-rule
+break
+cap-tion
+cap-tion-setup
+cap-tions-finnish
+cen-ter
+chapter-lists-gaps
+chapter-mark
+chapter-name
+chng-cntr
+cite
+clear-double-page
+clear-page
+cline
+clos-ing
+cmid-rule
+color-box
+column-break
+column-sep
+column-sep-rule
+column-width
+con-tents-label
+con-tents-name
+con-tents-page
+Con-tin-ued-Float
+con-trols
+counter-with-in
+counter-with-out
+cs-quotes
+cycle
+dbl-float-page-frac-tion
+dbl-float-sep
+dbl-text-float-sep
+dbl-top-frac-tion
+dbl-top-number
+De-clare-Bib-li-og-ra-phy-Driv-er
+De-clare-Float-Font
+De-clare-New-Float-Type
+De-clare-Sort-ing-Tem-plate
+de-fault
+default-font-fea-tures
+de-fine-col-or
+de-scrip-tion
+de-si-maa-li-erot-ti-mek-si
+de-si-maa-li-erot-ti-me-na
+de-si-maa-li-osa
+dia-esi-tyk-siä
+dia-esi-tys-ten
+dis-able-hy-phen-ation
+dis-cre-tionary
+dis-play-math
+doc-u-ment
+doc-u-ment-class
+dot-fill
+double-rule-sep
+ed-i-tor
+emer-gen-cy-stretch
+empty
+en-able-hy-phen-ation
+Endash
+end-tab-u-larx
+en-glish-font
+en-large-this-page
+en-space
+enu-mer-ate
+enumi
+enumii
+enumiii
+enumiv
+equa-tion
+erin-omai-sen
+ero-tin-merkki-ase-tuk-sen
+esit-te-ly-osaan
+esit-te-ly-osak-si
+esit-te-ly-osas-sa
+esi-tys-gra-fii-kan
+esi-tys-gra-fiik-kaan
+esi-tys-gra-fiik-ka-ohjel-mil-la
+ext-dash
+false
+fancy-hdr
+fancyhf
+fancy-page-style
+fancy-vrb
+fbox-rule
+fbox-sep
+FB-width
+fcolor-box
+fig-ure
+fig-ure-name
+fig-ures
+first-page-style
+float
+Float-Bar-rier
+float-box
+float-page-frac-tion
+float-row
+float-sep
+float-setup
+flush-bottom
+flush-columns
+font-size
+font-spec
+font-ti-ase-tuk-set
+font-ti-ase-tuk-sia
+font-ti-ase-tuk-siin
+font-ti-ase-tuk-sil-la
+font-ti-ase-tuk-sil-le
+font-ti-ase-tus
+font-ti-ase-tus-ta
+font-ti-ase-tus-ten
+font-ti-asiat
+font-ti-koko-ase-tus-ten
+font-ti-koko-komen-to-jen
+font-ti-komen-to-ja
+foot-misc
+foot-note
+foot-note-mark
+foot-note-sep
+foot-note-text
+foot-rule-width
+foot-skip
+fore-ground
+for-eign-lan-guage
+frame-box
+front-mat-ter
+ge-om-e-try
+graph-icx
+gra-vis-ak-sen-til-la
+gra-vis-ak-sen-tin
+gra-vis-ak-sent-ti
+greek-font
+gro-tes-ki
+gro-tes-kia
+gro-tes-kiin
+gro-tes-kin
+hai-tal-li-suus-arvo
+hai-tal-li-suus-arvoa
+hai-tal-li-suus-ar-voik-si
+ha-luaa
+hang-ing
+hang-para
+hang-paras
+head-ings
+head-rule-width
+head-sep
+hide-links
+hline
+hrule-fill
+hspace
+hyper-ref
+hyper-setup
+Hyph-dash
+hy-phen-ation
+if-then-else
+ig-nore-spaces
+ig-nore-spaces-af-ter-end
+imake-idx
+in-clude
+in-clude-graph-ics
+in-col-lec-tion
+in-dex
+index-name
+index-pro-logue
+index-setup
+index-tools
+in-put
+in-sti-tute
+in-text-sep
+in-toc
+item-indent
+item-ize
+item-sep
+it-seis-arvo
+it-seis-ar-voa
+it-shape
+jul-kai-su-oh-jel-miin
+jul-kai-su-oh-jel-mis-sa
+jus-ti-fi-ca-tion
+kak-si-osai-nen
+kak-sois-alle-vii-vauk-sen
+kap-pa-le-ot-sik-ko
+kap-pa-le-ot-si-koi-ta
+kel-lon-ajan
+ker-roin-ase-tus-ta
+keski-osa
+kie-li-ai-nek-seen
+kie-li-ase-tuk-set
+kie-li-ase-tuk-set-kin
+kie-li-ase-tuk-sia
+kie-li-ase-tuk-siin
+kie-li-ase-tuk-sil-la
+kie-li-ase-tuk-sis-ta
+kie-li-ase-tus-ten
+kie-li-opil-li-sis-ta
+kie-li-op-pin-sa
+kir-jain-yh-dis-tel-mät
+kir-ja-typo-gra-fian
+kir-ja-typo-gra-fias-sa
+kir-joi-tus-asu
+kir-joi-tus-asu-ja
+kir-joi-tus-asu-jen
+kir-joi-tus-asus-sa
+kir-joi-tus-asut
+koko-ase-tus
+koko-ase-tus-ten
+koko-ero
+koko-nais-luku-osa
+ko-men-to-vaih-to-eh-to
+konk-reet-ti-ses-ti
+konk-reet-ti-sia
+koodi-esi-mer-keis-sä
+koodi-esi-merk-kien
+kuva-esi-mer-keis-tä
+käsi-ala-kir-joi-tus-ta
+käsi-ohjel-mien
+käyt-töön-oton
+käyt-töön-otos-sa
+käyt-töön-otto
+käyt-töön-ottoa
+käyt-töön-ot-toon
+kään-täjä-ohjel-mat
+kään-täjä-ohjel-milla
+label
+label-font
+label-format
+label-sep
+label-width
+la-don-ta-oh-jei-ta
+la-don-ta-oh-jel-man
+land-scape
+large
+La-tex-mk
+La-tex-mk-rc
+left-hy-phen-min
+left-margin
+left-mark
+let-ter
+lett-rine
+level
+line
+line-spread
+line-width
+list
+list-fig-ure-name
+list-of
+list-of-fig-ures
+list-of-tables
+list-par-indent
+list-table-name
+lisä-omi-nai-suu-den
+lisä-vaih-to-eh-toa
+lohko-lai-naus-ympä-ris-töt
+long-table
+Lua-latex
+lue-tel-ma-ympy-rä
+lue-tel-ma-ympy-räl-lä
+luku-alueel-la
+luku-aluei-ta
+main-mat-ter
+make-box
+make-index
+make-label
+make-labels
+make-title
+margin-par
+margin-par-push
+margin-par-sep
+margin-par-width
+mark-both
+mark-right
+Match-Low-er-case
+ma-te-ma-tiik-ka-ym-pä-ris-tö-jä
+md-se-ries
+med-break
+med-skip
+med-skip-amount
+mem-oir
+mid-rule
+mini-page
+mit-ta-yk-sik-kö
+mit-ta-yk-si-köi-den
+mit-ta-yk-si-köi-tä
+mit-ta-yk-si-köl-le
+mit-ta-yk-si-kön
+mit-ta-yk-si-köt
+mk-bib-name-fam-i-ly
+mk-bib-name-giv-en
+mk-bib-name-pre-fix
+mk-bib-name-suf-fix
+mk-bib-parens
+mk-bib-quote
+mp-foot-note
+multi-col
+multi-cols
+multi-col-sep
+mul-ti-ple
+multi-row
+muo-toi-lu-ase-tuk-set
+my-head-ings
+mää-rit-te-ly-omi-nai-suut-ta
+name
+name-ref
+new-column-type
+new-com-mand
+new-counter
+new-en-vi-ron-ment
+new-float
+new-font-face
+new-font-fam-i-ly
+new-ge-om-e-try
+new-length
+new-line
+new-page
+ni-men-omaan
+no-cite
+no-clear-page
+no-club
+node
+no-in-dent
+no-indent-after
+no-link-url
+no-new-page
+no-page-break
+no-page-color
+nor-mal
+normal-font
+normal-margin-par
+normal-size
+no-rule
+note
+no-widow
+nuo-li-ak-sen-tit
+nyky-aikai-nen
+nyky-aikai-set
+nyky-aikai-sia
+nyky-aika-na
+nyky-ajan
+näp-päin-aset-te-lus-sa
+obey-cr
+oikein-kir-joi-tus-oppaas-sa
+ole-tus-ar-vo
+ole-tus-ar-voa
+ole-tus-ar-voi-hin
+ole-tus-ar-vot
+ole-tus-ase-tuk-set
+ole-tus-ase-tuk-sia
+ole-tus-ase-tuk-siin
+ole-tus-ase-tuk-sil-la
+ole-tus-ase-tus
+ole-tus-mitta-yk-sik-kö-nä
+ole-tus-yk-sik-kö
+ole-tus-yk-sik-köä
+one-column
+one-side
+on-line
+open-ing
+op-tions
+origin
+otf-info
+other-lan-guage
+over-left-ar-row
+over-right-ar-row
+page
+page-break
+page-color
+page-number-ing
+page-ref
+pages
+page-style
+paper-height
+pa-pe-ri-ar-keis-sa
+pa-pe-ri-ark-kei-hin
+pa-pe-ri-ark-kia
+pa-pe-ri-ark-kien
+paper-width
+para-graph
+par-box
+paren-cite
+par-ent
+par-in-dent
+par-sep
+par-skip
+part-name
+par-top-sep
+pause
+pdf-book-mark
+pdf-info
+pdf-latex
+pdf-lscape
+per-page
+pe-rus-aja-tus
+pe-rus-ase-tuk-set
+pe-rus-ase-tuk-sia
+pe-rus-asiat
+pe-rus-asioi-ta
+pe-rus-osas-ta
+pe-rus-osat
+pe-rus-osien
+pe-rus-osiin
+pe-rus-vaih-to-eh-dot
+pe-rus-ympä-ris-tö
+phan-tom-sec-tion
+pien-aak-ko-set
+pien-aak-kos-ten
+pii-rus-tus-alus-tan
+pik-seli-gra-fiik-kaa
+place-ins
+poly-glos-sia
+por-trait
+print-bib-li-og-ra-phy
+print-index
+pro-gram
+pro-tect
+pro-vide-com-mand
+pub-lish-er
+pys-ty-asen-nos-sa
+pys-ty-asen-toi-sel-la
+pys-ty-asen-toi-sen
+pää-asial-li-nen
+pää-asial-li-sek-si
+pää-asial-li-sen
+pää-asias-sa
+pää-ot-sik-ko
+pääte-oh-jel-mien
+quo-ta-tion
+quote
+ragged-bottom
+ragged-columns
+ragged-left
+ragged-right
+raise-box
+real-scripts
+ref-name
+ref-step-counter
+reg-tot-counter
+re-new-com-mand
+re-new-en-vi-ron-ment
+re-size-box
+re-store-cr
+re-store-ge-om-e-try
+reverse-margin-par
+right-hy-phen-min
+right-margin
+right-mark
+rivin-osan
+rm-fam-i-ly
+ro-tate-box
+rule
+sak-ko-ar-voa
+sa-man-aikai-ses-ti
+sar-kain-ase-tuk-sia
+Scale
+scale-box
+sc-shape
+sec-num-depth
+sec-tion
+sec-tion-break
+sec-tion-mark
+see-also
+select-font
+select-lan-guage
+set-beamer-color
+set-beamer-font
+set-beamer-tem-plate
+set-cite-style
+set-counter
+set-default-lan-guage
+set-length
+set-main-font
+set-math-font
+set-mono-font
+set-no-club
+set-no-widow
+set-sans-font
+set-to-depth
+set-to-height
+set-to-width
+sf-fam-i-ly
+short-en
+show-hy-phens
+sig-na-ture
+si-joit-te-lu-ase-tuk-set
+si-joit-te-lu-ase-tuk-sia
+single-line-check
+sir-kum-flek-si
+sir-kum-flek-sia
+sir-kum-flek-sin
+si-sen-nys-ase-tuk-set
+si-sen-nys-asiat
+si-säl-tö-ele-ment-tien
+sivu-alue
+si-vu-alueel-le
+si-vu-alueen
+si-vu-aluei-den
+sivu-koko-ase-tuk-sia
+skaa-laus-ar-gu-ment-ti
+skaa-laus-ase-tus
+slides
+slope
+sl-shape
+small
+small-break
+small-skip
+small-skip-amount
+space-skip
+split-index
+stable
+step-counter
+still-sans-serif-large
+still-sans-serif-math
+still-sans-serif-small
+still-sans-serif-text
+style
+sub-para-graph
+sub-sec-tion
+sub-section-mark
+sub-sub-sec-tion
+suo-jaus-omi-nai-suus
+suur-aak-kos-ten
+sym-bo-li-esi-tys
+säh-kö-pos-ti-osoi-te
+säh-kö-pos-ti-osoit-tei-den
+säh-kö-pos-ti-osoit-tei-ta
+tab-bing
+tab-bing-sep
+tab-col-sep
+table
+table-name
+table-of-con-tents
+tables
+tabu-lar
+tabu-larx
+tabu-lary
+tau-luk-ko-ympä-ris-tö
+tau-luk-ko-ympä-ris-tön
+tau-luk-ko-ympä-ris-töt
+tau-luk-ko-ympä-ris-töä
+ta-van-omais-ten
+tavu-tus-algo-rit-mia
+teks-ti-alue
+teks-ti-alueen
+teks-ti-aluees-ta
+teks-ti-edi-to-ria
+teks-ti-edi-to-rien
+teks-ti-edi-to-ril-la
+teks-ti-edi-to-rin
+teks-ti-edi-to-ris-sa
+teks-ti-edi-to-ris-sa-kin
+teks-ti-edi-to-ris-ta
+teks-ti-ele-men-til-tä
+teks-ti-ele-men-tin
+teks-ti-ele-ment-te-jä
+teks-ti-ele-ment-ti
+teks-ti-ele-ment-tien
+teks-ti-ele-ment-tiin
+teks-tin-kä-sit-tely-ohjel-mat
+teks-tin-kä-sit-tely-ohjel-mis-sa
+teks-tin-osan
+teks-ti-osa
+teks-ti-osaan
+teks-ti-osan
+teks-ti-osas-sa
+text-back-slash
+text-bullet
+text-cite
+text-color
+text-comp-word-mark
+text-el-lip-sis
+text-en-glish
+text-float-sep
+text-font
+text-frac-tion
+text-greek
+text-height
+text-quote-dbl
+text-quote-single
+text-sub-script
+text-super-script
+text-width
+the-author
+the-bib-li-og-ra-phy
+the-chapter
+the-date
+the-equa-tion
+the-foot-note
+the-mp-foot-note
+the-page
+the-section
+the-sub-section
+the-table
+the-title
+this-page-style
+tie-teen-aloil-la
+tie-to-kone-avus-teis-ta
+tie-to-kone-oh-jel-ma
+tie-to-kone-oh-jel-mal-le
+tie-to-kone-oh-jel-mas-ta
+tie-to-kone-oh-jel-mat
+tie-to-kone-oh-jel-mia
+tii-vis-tel-mä-osan
+tikz-pic-ture
+title
+title-con-tents
+title-for-mat
+title-label
+title-rule
+title-sec
+title-spacing
+title-toc
+toc-depth
+toc-level
+top-frac-tion
+top-number
+top-rule
+top-sep
+total
+total-height
+total-number
+tot-count
+tot-pages
+tot-value
+tt-fam-i-ly
+two-column
+two-side
+ty-po-gra-fia
+ty-po-gra-fiaa
+ty-po-gra-fiaan
+ty-po-gra-fian
+ty-po-gra-fias-sa
+ty-po-gra-fi-seen
+ty-po-gra-fi-sen
+ty-po-gra-fi-se-na
+ty-po-gra-fi-ses-ta
+ty-po-gra-fi-ses-ti
+ty-po-gra-fi-set
+ty-po-gra-fi-sia
+ty-po-gra-fi-sin
+ty-po-gra-fi-sis-ta
+ty-po-gra-fis-ten
+tyy-li-ase-tus
+tyy-li-ase-tus-ten
+tär-keys-as-teil-le
+tär-keys-as-tei-sia
+täys-ym-py-rän
+UL-depth
+ulko-asu
+ulko-asua
+ulko-asun
+ulko-asus-ta
+ulko-asus-taan
+ulko-asu-tee-mo-ja
+ulko-asuun
+UL-thick-ness
+under-line
+Uni-code
+Uni-coden
+url-style
+use-color-theme
+use-counter
+use-font-theme
+use-inner-theme
+use-outer-theme
+use-pack-age
+use-theme
+vaih-to-eh-don
+vaih-to-eh-dot
+vaih-to-eh-to
+vaih-to-eh-toi-ses-ti
+vaih-to-eh-to-ja
+vaih-to-eh-to-na
+vai-ku-tus-alue
+vai-ku-tus-alueena
+vai-ku-tus-aluet-ta
+value
+va-paa-eh-toi-sia
+va-paa-eh-tois-ta
+vas-taan-otta-jal-le
+vas-taan-otta-jil-le
+vek-tori-gra-fiik-kaa
+vek-tori-gra-fiik-ka-font-te-ja
+vek-tori-gra-fiik-ka-ku-viot
+ver-ba-tim
+verse
+vir-he-il-moi-tuk-seen
+vir-he-il-moi-tuk-sen
+vir-he-il-moi-tus
+vir-he-il-moi-tus-ta
+vline
+vol-ume
+vspace
+vä-him-mäis-etäi-syys
+väli-ai-kai-ses-ti
+väli-ai-kais-tie-dos-toa
+väli-ai-kais-tie-dos-to-jen
+väli-ai-kais-tie-dos-ton
+väli-ai-kais-tie-dos-toon
+väli-ai-kais-tie-dos-tot
+väli-ot-si-kois-sa
+väli-ot-si-kois-ta
+väli-ot-si-kon
+väli-ot-si-kot
+vä-ri-asioi-ta
+wall-cal-en-dar
+with-in
+Xe-latex
+yh-dys-osas-ta
+yh-dys-osien
+yh-tä-lö-esi-mer-kin
+yleis-ohje
+yleis-yhdys-merk-ki
+ylä-in-dek-si
+ylä-in-dek-si-nume-roi-den
+ylä-in-dek-si-nume-rois-ta
+ylä-in-dek-si-nume-rol-la
+ylä-in-dek-si-nume-ron
+ylä-in-dek-sit
+ylä-osaan
+ylä-osas-sa
+ään-tö-asu
+}
diff --git a/info/kaytannollista-latexia/versio.tex b/info/kaytannollista-latexia/versio.tex
new file mode 100644
index 0000000000..1f9bae2ceb
--- /dev/null
+++ b/info/kaytannollista-latexia/versio.tex
@@ -0,0 +1 @@
+\newcommand{\versio}{2021.12}
diff --git a/info/mathalphabets/README.md b/info/mathalphabets/README.md
new file mode 100644
index 0000000000..5ccda6a3da
--- /dev/null
+++ b/info/mathalphabets/README.md
@@ -0,0 +1,18 @@
+Abstract
+This is a Chinese introduction to mathematical alphabets including greek alphabets, and latin alphabets in script, calligraphic, fraktur, double stroke and blackboard bold fonts, and Hebrew alphabets. Furthermore, we will give some advice on how to use and pronounce them.
+
+Fonts
+To compile the tex.file, you need to download and install the free fonts such as Fangzhengshusong (方正书宋), Fangzhengkaiti (方正楷体), Fangzhengfangsong (方正仿宋) in GBK code and the non-free fonts such as FangzhengFWzhuzimingchaoD (方正FW筑紫明朝D) and Fangzhengyouhei506L (方正悠黑506L) from http://www.foundertype.com
+
+Versions
+Version 2.2 2021-12-27 Revised some typos.
+Version 2.1 2021-12-25 Improved and expanded the statements about \varepsilon, \varkappa, \vartheta, \varpi, \varrho, \varsigma, \varphi.
+Version 2.0 2021-12-11 Increased the content of Hebrew alphabet and supplied some provocations of some Greek letters.
+Version 1.0 2021-11-29 Finished the first draft.
+
+Contact
+Conden Chao zhaoxy00@126.com
+
+Notice
+Any commercial use is forbidden.
+
diff --git a/info/mathalphabets/mathalphabets.pdf b/info/mathalphabets/mathalphabets.pdf
new file mode 100644
index 0000000000..ef16fad859
--- /dev/null
+++ b/info/mathalphabets/mathalphabets.pdf
Binary files differ
diff --git a/info/mathalphabets/src/maref.bib b/info/mathalphabets/src/maref.bib
new file mode 100644
index 0000000000..baa418c090
--- /dev/null
+++ b/info/mathalphabets/src/maref.bib
@@ -0,0 +1,177 @@
+%% This BibTeX bibliography file was created using BibDesk.
+%% https://bibdesk.sourceforge.io/
+
+%% Created for Conden Chao at 2019-12-10 22:42:23 +0800
+
+
+%% Saved with string encoding Unicode (UTF-8)
+
+@misc{Sllj2021,
+ Addendum = {初稿.},
+ Author = {赵晓玉},
+ Language = {chinese},
+ Title = {数理逻辑: 形式化方法的应用},
+ Type = {Z},
+ Year = {2021}}
+
+@misc{Lsyc2017,
+ Addendum = {初稿.},
+ Author = {赵晓玉},
+ Language = {chinese},
+ Title = {\LaTeX{}中文用户实用手册},
+ Type = {Z},
+ Year = {2017}}
+
+@book{Tcmf1980,
+ Author = {Knuth, D. E.},
+ Location = {California},
+ Publisher = {Stanford University},
+ Title = {The Computer Modern Family of Typefaces},
+ Type = {M},
+ Year = {1980}}
+
+@misc{Imut2009,
+ Author = {Knuth, D. E.},
+ Date = {2009-01},
+ Title = {Important Message to All Users of \TeX{}},
+ Type = {Z/OL},
+ Url = {https://www-cs-faculty.stanford.edu/~knuth/cm.html},
+ Urldate = {2020-09-04},
+ Bdsk-Url-1 = {https://www-cs-faculty.stanford.edu/~knuth/cm.html}}
+
+@misc{Rsrm1991,
+ Author = {R. Smith},
+ Date = {1991-10-27},
+ Title = {Readme},
+ Type = {Z/OL},
+ Url = {https://www.ctan.org/tex-archive/fonts/rsfs},
+ Urldate = {2021-12-11},
+ Bdsk-Url-1 = {https://www.ctan.org/tex-archive/fonts/rsfs}}
+
+@misc{Uams2002,
+ Author = {American~Mathematical~Society},
+ Date = {2002-01},
+ Title = {User's Guide to AMSFonts Version 2.2d},
+ Type = {Z/OL},
+ Url = {https://mirrors.tuna.tsinghua.edu.cn/CTAN/fonts/amsfonts/doc/amsfndoc.pdf},
+ Urldate = {2021-12-11},
+ Bdsk-Url-1 = {https://mirrors.tuna.tsinghua.edu.cn/CTAN/fonts/amsfonts/doc/amsfndoc.pdf}}
+
+@misc{Tnps2006,
+ Author = {Linotype},
+ Location = {GmbH},
+ Publisher = {Linotype},
+ Title = {The New Palatino{\texttrademark} Sans: A Supplement to Palatino Nova Designed by Hermann Zapf},
+ Type = {Z/OL},
+ Url = {http://www.linotype.co.jp/linotype%20volumes/Palatino%20Sans%20Brochure.pdf},
+ Urldate = {2020-09-04},
+ Year = {2006},
+ Bdsk-Url-1 = {http://www.linotype.co.jp/linotype%20volumes/Palatino%20Sans%20Brochure.pdf}}
+
+@misc{Ramf2013,
+ Author = {American~Mathematical~Society},
+ Date = {2013-01-14},
+ Title = {Readme for \texttt{amsfonts} 3.04},
+ Type = {Z/OL},
+ Url = {https://www.ctan.org/tex-archive/fonts/amsfonts},
+ Urldate = {2021-12-11},
+ Bdsk-Url-1 = {https://www.ctan.org/tex-archive/fonts/amsfonts}}
+
+@misc{Tpvd1997,
+ Author = {O. Kummer},
+ Date = {1997-07-08},
+ Title = {The Preview Document},
+ Type = {Z/OL},
+ Url = {https://mirrors.tuna.tsinghua.edu.cn/CTAN/info/symbols/blackboard/blackboard.ps},
+ Urldate = {2021-12-11},
+ Bdsk-Url-1 = {https://mirrors.tuna.tsinghua.edu.cn/CTAN/info/symbols/blackboard/blackboard.ps}}
+
+@misc{Tmap2021,
+ title={The \textsf{mathalpha}, AKA \textsf{mathalfa} Package},
+ author={M. Sharpe},
+ type={Z/OL},
+ date={2021-11-18},
+ url={https://mirrors.tuna.tsinghua.edu.cn/CTAN/macros/latex/contrib/mathalpha/doc/mathalpha-doc.pdf},
+ Urldate = {2021-12-11},
+ Bdsk-Url-1 = {https://mirrors.tuna.tsinghua.edu.cn/CTAN/macros/latex/contrib/mathalpha/doc/mathalpha-doc.pdf}}
+
+@misc{Asfm2006,
+ title={A Survey of Free Math Fonts for \TeX{} and \LaTeX{}},
+ author={Hartke, S. G.},
+ type={Z/OL},
+ date={2006-05-06},
+ url={https://mirrors.tuna.tsinghua.edu.cn/CTAN/info/Free_Math_Font_Survey/en/survey.pdf},
+ Urldate = {2021-12-11},
+ Bdsk-Url-1 = {https://mirrors.tuna.tsinghua.edu.cn/CTANinfo/Free_Math_Font_Survey/en/survey.pdf}}
+
+@misc{Rdme2021,
+ Author = {A. Tsolomitis},
+ Date = {2021-12-09},
+ Title = {Readme},
+ Type = {Z/OL},
+ Url = {https://mirrors.tuna.tsinghua.edu.cn/CTAN/fonts/newcomputermodern/README},
+ Urldate = {2021-12-11},
+ Bdsk-Url-1 = {https://mirrors.tuna.tsinghua.edu.cn/CTAN/fonts/newcomputermodern/README}}
+
+@misc{Arch2020,
+ Author = {E. Gregorio},
+ Date = {2020-03-02},
+ Title = {A Reply to ``What are \TeX{} Codes for Hebrew Letters to Be Used as Math-Mode Symbols?"},
+ Type = {Z/OL},
+ Url = {https://tex.stackexchange.com/a/226850/140814},
+ Urldate = {2021-12-08},
+ Bdsk-Url-1 = {https://tex.stackexchange.com/a/226850/140814}}
+
+@misc{Arhi2021,
+ Author = {D. Carlisle},
+ Date = {2021-08-20},
+ Title = {A Reply to ``How to Invoke Aleph, Beth, Gimel and Daleth Only in the Latin Modern Math Font?"},
+ Type = {Z/OL},
+ Url = {https://tex.stackexchange.com/a/611616/140814},
+ Urldate = {2021-12-08},
+ Bdsk-Url-1 = {https://tex.stackexchange.com/a/611616/140814}}
+
+@misc{Arab2017,
+ Author = {H. Oberdiek},
+ Date = {2017-04-13},
+ Title = {A Reply to ``How to Get Aleph and Beth Symbols in Similar Font?"},
+ Type = {Z/OL},
+ Url = {https://tex.stackexchange.com/a/170494/140814},
+ Urldate = {2021-12-08},
+ Bdsk-Url-1 = {https://tex.stackexchange.com/a/170494/140814}}
+
+@misc{Wwdb2020,
+ Author = {M. Logic},
+ Date = {2020-09-04},
+ Title = {Who Designed the Mathematical Blackboard Bold Letters of \AmS{}, and When?},
+ Type = {Z/OL},
+ Url = {https://tex.stackexchange.com/q/561380/140814},
+ Urldate = {2021-12-08},
+ Bdsk-Url-1 = {https://tex.stackexchange.com/q/561380/140814}}
+
+@misc{Wdvs2020,
+ Author = {E. Gregorio},
+ Date = {2020-01-27},
+ Title = {A Reply to ``What Does the \texttt{\textbackslash var} Prefix Stand for in \texttt{\textbackslash varphi} and \texttt{\textbackslash varepsilon} Etc?"},
+ Type = {Z/OL},
+ Url = {https://tex.stackexchange.com/a/304576/140814},
+ Urldate = {2021-12-25},
+ Bdsk-Url-1 = {https://tex.stackexchange.com/a/304576/140814}}
+
+@misc{Tcpb2020,
+ Author = {C.(赵晓玉) Chao and S. Murugaiah},
+ Date = {2020-09-17},
+ Title = {The \texttt{cmathbb} Package: To Call Mathematical Blackboard Bold Characters Compatible with the Computer Modern Font Family, Version 1.0},
+ Type = {Z/OL},
+ Url = {https://mirrors.tuna.tsinghua.edu.cn/CTAN/fonts/cmathbb/doc/cmathbb.pdf},
+ Urldate = {2021-12-11},
+ Bdsk-Url-1 = {https://mirrors.tuna.tsinghua.edu.cn/CTAN/fonts/cmathbb/doc/cmathbb.pdf}}
+
+@book{Mmil2016,
+ Author = {G. Gr{\"a}tzer},
+ Edition = {5},
+ Location = {Cham, Heidelberg, New York, Dordrecht and London},
+ Publisher = {Springer},
+ Title = {More Math into \LaTeX{}},
+ Type = {M},
+ Year = {2016}}
diff --git a/info/mathalphabets/src/mathalphabets.tex b/info/mathalphabets/src/mathalphabets.tex
new file mode 100644
index 0000000000..b9aa8df301
--- /dev/null
+++ b/info/mathalphabets/src/mathalphabets.tex
@@ -0,0 +1,715 @@
+\documentclass[zihao=5]{ctexart}%[zihao=-4]
+\usepackage[papersize={185mm,260mm},top=22mm,bottom=22mm,left=22mm,right=22mm]{geometry}%185mm×260mm, 上30mm下20mm左22mm右22mm
+\usepackage{amsmath,amsfonts,amssymb,mathrsfs,dsfont,comment}
+\usepackage{longtable}
+\usepackage{graphicx}
+\usepackage{indentfirst} %首行缩进宏包
+%%%行距与段落间距设置%%%%%%%%%%%%%%%%%%%%%%%
+\linespread{1.4}
+\setlength{\parskip}{.3\baselineskip plus 0.2ex minus 0.1ex}%段落间的距离
+\usepackage{enumitem}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+%%%设置中英文混排时中文字体%%%%%%%%%%%%%%%%%%%%
+\setCJKmainfont[ItalicFont={FZKai-Z03}, BoldFont={FZFW ZhuZi MinchoS D}]{FZShuSong-Z01} %主要字体,\it,\bfseries, \rm %LLB+DB
+\setCJKsansfont{FZYouHeiS 506L} %中文非衬线字体,调用命令,\sf
+\setCJKmonofont{FZFangSong-Z02} %中文等距字体,调用命令,\ttfamily
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%定义新字体%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\setCJKfamilyfont{kaiti}{FZKai-Z03}%使用楷体
+\newcommand{\kai}{\CJKfamily{kaiti}}
+\setCJKfamilyfont{fangsong}{FZFangSong-Z02}%使用仿宋
+\newcommand{\fsong}{\CJKfamily{fangsong}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%调用希伯来字母%%%%%%%%%%%%%%%%%%%%%%%%%%
+%\usepackage{fontspec}%mathspec自动调用该宏包;顶端也调用
+\makeatletter
+\let\aleph\relax\let\beth\relax
+\let\gimel\relax\let\daleth\relax
+\newfontfamily\hebfont{NewCM08-Regular.otf}
+\newcommand\aleph{\mathord{\textrm{\hebfont\char"05D0}}}
+\let\alef\aleph
+\newcommand\vet{\mathord{\textrm{\hebfont\char"05D1}}}
+\let\bet\vet
+\let\beth\vet
+\newcommand\gimel{\mathord{\textrm{\hebfont\char"05D2}}}
+\newcommand\dalet{\mathord{\textrm{\hebfont\char"05D3}}}
+\let\daleth\dalet
+\let\daled\dalet
+\newcommand\he{\mathord{\textrm{\hebfont\char"05D4}}}
+\newcommand\vav{\mathord{\textrm{\hebfont\char"05D5}}}
+\let\waw\vav
+\newcommand\zayin{\mathord{\textrm{\hebfont\char"05D6}}}
+\newcommand\het{\mathord{\textrm{\hebfont\char"05D7}}}
+\let\heth\het
+\let\chet\het
+\newcommand\tet{\mathord{\textrm{\hebfont\char"05D8}}}
+\let\teth\tet
+\newcommand\yod{\mathord{\textrm{\hebfont\char"05D9}}}
+\let\jod\yod
+\newcommand\kaf{\mathord{\textrm{\hebfont\char"05DB}}}
+\newcommand\varkaf{\mathord{\textrm{\hebfont\char"05DA}}}
+\newcommand\lamed{\mathord{\textrm{\hebfont\char"05DC}}}
+\newcommand\mem{\mathord{\textrm{\hebfont\char"05DE}}}
+\newcommand\varmem{\mathord{\textrm{\hebfont\char"05DD}}}
+\newcommand\nun{\mathord{\textrm{\hebfont\char"05E0}}}
+\newcommand\varnun{\mathord{\textrm{\hebfont\char"05DF}}}
+\newcommand\samekh{\mathord{\textrm{\hebfont\char"05E1}}}
+\newcommand\ayin{\mathord{\textrm{\hebfont\char"05E2}}}
+\newcommand\pe{\mathord{\textrm{\hebfont\char"05E4}}}
+\newcommand\varpe{\mathord{\textrm{\hebfont\char"05E3}}}
+\newcommand\tsadi{\mathord{\textrm{\hebfont\char"05E6}}}
+\let\sadi\tsadi
+\let\sadhe\tsadi
+\newcommand\vartsadi{\mathord{\textrm{\hebfont\char"05E5}}}
+\let\varsadi\vartsadi
+\let\varsadhe\vartsadi
+\newcommand\qof{\mathord{\textrm{\hebfont\char"05E7}}}
+\let\qoph\qof
+\newcommand\resh{\mathord{\textrm{\hebfont\char"05E8}}}
+\newcommand\shin{\mathord{\textrm{\hebfont\char"05E9}}}
+\let\sheen\shin
+\newcommand\tav{\mathord{\textrm{\hebfont\char"05EA}}}
+\let\taw\tav
+\makeatother
+
+%%%list编号相关%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%enumerate item编号--------------------------------------------
+\renewcommand{\labelenumi}{(\theenumi)} %\labelenumi (1级e-item)
+%\renewcommand{\labelenumii}{({\it\theenumii})}%\labelenumii (2级e-item)
+%设置item缩进值----------------------------------------------------
+%需要enumitem宏包
+\setlist[enumerate]{leftmargin=1.8em}
+\setlist[itemize]{leftmargin=1.1em}%所有级别
+
+%%%画线%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\usepackage{xhfill}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%解决amsthm中openbox与xhill冲突问题%%%%%%
+\let\openbox\relax
+%%%设置定理环境%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\usepackage{amsthm}
+%中文定理与定义格式----------------------------------------------
+\makeatletter
+\newtheoremstyle{mythm}%名字
+{.3\baselineskip plus 0.2ex minus 0.1ex}%上方的空行
+{.3\baselineskip plus 0.2ex minus 0.1ex}%下方的空行
+{\kai }%主体内容,可以在此修改内容字体
+{}%首行缩进:2em
+{}%定理头部字体
+{}%定理头部后的标点 {\bfseries .}
+{1em}%定理头部后的空格
+{{\bfseries\thmname{#1}\thmnumber{#2}}\thmnote{(#3)\!\!}}%定理头部的说明
+\makeatother
+\makeatletter
+\newtheoremstyle{mydefn}%名字
+{.3\baselineskip plus 0.2ex minus 0.1ex}%上方的空行
+{.3\baselineskip plus 0.2ex minus 0.1ex}%下方的空行
+{}%主体内容,可以在此修改内容字体
+{}%首行缩进:2em
+{}%定理头部字体
+{}%定理头部后的标点 {\bfseries .}
+{1em}%定理头部后的空格
+{{\bfseries\thmname{#1}\thmnumber{#2}}\thmnote{(#3)\!\!}}%定理头部的说明
+\makeatother
+%1和2换过来之后,}之后加~,否则交换无效-------------------------
+%%%中文证明环境%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\makeatletter
+\renewenvironment{proof}[1][\proofname]{\par
+ \pushQED{\qed}%
+ \normalfont \topsep0\p@\@plus0\p@\relax %证明环境前后行距
+ \trivlist
+ \item[\hskip\labelsep % 首行缩进则加\indent
+ \bfseries
+ #1\@addpunct{}]\ignorespaces %:为证明后的冒号
+}{%
+ \popQED\endtrivlist\@endpefalse
+}
+\renewcommand{\proofname}{回应} %Proof的名称换为证明
+\makeatother
+%%%修改证明结束符%%%%%%%%%%%%%%%%%%%%%%%%%%
+%\renewcommand{\qedsymbol}{\ensuremath\boxtimes}
+%%%设置定理%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\theoremstyle{mythm}
+\newtheorem{theorem}{定理}
+\newtheorem{lemma}[theorem]{引理}
+\newtheorem{corollary}[theorem]{推论}
+\newtheorem{proposition}[theorem]{命题}
+\newtheorem{exercise}[theorem]{习题}
+\newtheorem{question}[theorem]{疑问}
+\theoremstyle{mydefn}
+\newtheorem{definition}[theorem]{定义}
+\newtheorem{remark}[theorem]{评注}
+\newtheorem{example}[theorem]{示例}
+\newtheorem{material}[theorem]{材料}
+%%%习题编号改为x.%%%%%%%%%%%%%%%%%%%%%%%%%%
+%\renewcommand\thetheorem{1.\arabic{theorem}}%roman,Roman,alph,Alph
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%尾注添加%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\usepackage{endnotes}
+\renewcommand{\notesname}{本文注释}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%设置脚注%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\usepackage[perpage,stable,bottom]{footmisc}
+%perpage使得脚注每页重新编号
+%stable使得标题中可加脚注,但目录中不会出现脚注编号
+%bottom使得每页脚注靠近页面底端
+\setlength{\footnotesep}{0.6\baselineskip}% 脚注与脚注之间行距
+\setlength{\skip\footins}{1\baselineskip plus 06ex minus 0.3ex}% 脚注与正文间距
+%%%%脚注编号带圈儿------------------------------------------
+%\usepackage{pifont}%调用带圈的数字
+%\renewcommand\thefootnote{\ding{\numexpr171+\value{footnote}}}%脚注编号设成带圈数字rm
+
+%%%thanks和footnote格式一致%%%%%%%%%%%%%%%%%%%%%
+\usepackage{scrextend} % KOMA script for footnote marks hung left of the margin
+\newcommand*\footnotetextfrommargin{0em} %distance for footnote text from the margin
+\deffootnote{\footnotetextfrommargin}%use distance from above
+{\parindent}% paragraph indent in footnotes
+{\thefootnotemark\space} %footnote marks followed by a space in footnote
+\deffootnotemark{\normalfont\textsuperscript{\thefootnotemark}} %use footmarktextfont for footnote markers in the text
+\usepackage{xpatch}
+\makeatletter
+% 1. remove all redefinitions about footnotes done by \maketitle and add \titletrue
+\renewcommand\maketitle{\par
+ \begingroup
+ \renewcommand\thefootnote{\@fnsymbol\c@footnote}%
+ \titletrue
+ \if@twocolumn
+ \ifnum \col@number=\@ne
+ \@maketitle
+ \else
+ \twocolumn[\@maketitle]%
+ \fi
+ \else
+ \newpage
+ \global\@topnum\z@% Prevents figures from going at top of page.
+ \@maketitle
+ \fi
+ \thispagestyle{plain}\@thanks
+ \endgroup
+ \setcounter{footnote}{0}%
+ \global\let\thanks\relax
+ \global\let\maketitle\relax
+ \global\let\@maketitle\relax
+ \global\let\@thanks\@empty
+ \global\let\@author\@empty
+ \global\let\@date\@empty
+ \global\let\@title\@empty
+ \global\let\title\relax
+ \global\let\author\relax
+ \global\let\date\relax
+ \global\let\and\relax
+}
+% 2. define a conditional
+\newif\iftitle
+%3. indent at first line
+\xpretocmd{\@makefntext}{\titlefalse}{}{}
+\renewcommand\@makefntext[1]{%
+ \noindent\makebox[3.0em][r]{\@makefnmark}#1}
+\makeatother
+
+%%%脚注编号%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\makeatletter
+%脚注编号带圈儿--------------------------------------------------
+\usepackage{tikz}%需要tikz
+\newcommand*\circled[1]{%
+ \tikz[baseline=(char.base)]\node[shape=circle,draw,inner sep=0.1pt,text depth=0pt,font=\normalfont,minimum size=5.6pt] (char) {#1};}
+\renewcommand\thefootnote{\protect\circled{\arabic{footnote}}}
+%正文脚注编号大小------------------------------------------------
+\def\@makefnmark{\textsuperscript{\tiny\@thefnmark}}%tiny
+%脚注中编号非上标------------------------------------------------
+\let\old@makefntext\@makefntext%
+\long\def\@makefntext#1{%
+ \def\@makefnmark{\raisebox{0.08\baselineskip}{\tiny\@thefnmark}}%
+ \old@makefntext{\space#1}}%
+\makeatother
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%设置页眉页脚%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\usepackage{fancyhdr}%调用宏包
+%%%设置新的plain格式%%%%%%%%%%%%%%%%%%%%%%%%
+\fancypagestyle{plain}{
+ \fancyhf{}
+ \fancyhead{}
+ \fancyfoot{}
+ \renewcommand{\headrulewidth}{0pt}}
+\renewcommand{\headrulewidth}{0pt} % 页眉与正文之间的水平线粗细,默认0.4pt
+%\renewcommand{\footrulewidth}{1pt}
+%\setlength{\topskip}{0mm} %页眉与正文间距离
+\usepackage{lastpage}%可以调用总页数
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%合并表格行列%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\usepackage{multirow}
+
+%%%摘要名称%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\renewcommand{\abstractname}{内容摘要}
+%%%节标题靠左%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\CTEXsetup[format={\Large\bfseries}]{section}
+%%%解决表格标题距内容过近%%%%%%%%%%%%%%%%%%%%%
+\usepackage{caption}
+%将表格、图片标题中英文冒号改成中文冒号-------------------------
+\makeatletter
+\DeclareCaptionLabelSeparator{cncolon}{:}%定义中文冒号形式的分隔符
+\makeatother
+%删除表格、图片标题中冒号----------------------------------------
+\captionsetup{labelsep=quad}%none,colon,period,space,quad,newline,endash
+%%%表格线加粗%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\usepackage{booktabs}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%set space between caption and text (for tables, figurs and so on)
+\setlength{\abovecaptionskip}{.3\baselineskip plus 0.2ex minus 0.1ex}
+\setlength{\belowcaptionskip}{.3\baselineskip plus 0.2ex minus 0.1ex}
+
+%%%设置图编号随章%%%%%%%%%%%%%%%%%%%%%%%%%%
+\renewcommand\thefigure{$\arabic{figure}$\,}
+%默认的图片编号本如此,只是数字后的冒号挨太紧
+
+%%%set space between caption and text (for tables, figurs and so on)
+%\setlength{\abovecaptionskip}{.2\baselineskip plus 1pt minus 3pt}
+%\setlength{\belowcaptionskip}{.2\baselineskip plus 1pt minus 3pt}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%参考文献%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\usepackage[backend = biber, style = caspervector-ay, utf8,
+maxbibnames=999,maxcitenames=999,%引用和列表的文献作者全显示
+sortcites=false,%引用显示按照输入顺序
+sorting = cenyt,%列表显示按照cenyt
+dashed=true,%文献列表作者相同时横线表示
+seconds=true,
+]{biblatex}
+%%%参考文献格式修改%%%%%%%%%%%%%%%%%%%%%%%%%
+\makeatletter
+%列表文献标题设置-------------------------------------------------
+\renewcommand*{\bbx@cepunct}[2]{#2}
+\DeclareFieldFormat*{title}{\bbx@cetext{《{#1}》}{\mkbibemph{#1}}}
+\DeclareFieldFormat*{booktitle}{\bbx@cetext{《{#1}》}{\mkbibemph{#1}}}
+\DeclareFieldFormat*{journaltitle}{\bbx@cetext{《{#1}》}{\mkbibemph{#1}}}
+\DeclareFieldFormat[inbook, inproceedings, incollection, article]
+{title}{\bbx@cetext{《{#1}》}{{#1}}}%\mkbibquote可以使此类title加双引号----
+\DeclareFieldFormat*{volume}{{#1}}%卷号不再斜体;\mkbibbold可以加粗
+%\DeclareFieldFormat*{type}{\mkbibbrackets{\mkbibemph{#1}}}%文献类型C,M,J斜体
+%列表中2个以上作者时,中文后2个加‘和’,英文后2个加‘and’
+\renewcommand*{\finallistdelim}{\bbx@cetext{{和}}{\addspace\bibstring{and}\space}}
+\renewcommand*{\finalnamedelim}{\bbx@cetext{{和}}{\addspace\bibstring{and}\space}}
+%去掉英文文献两个以上作者时最后两个作者之间加的and
+%\renewcommand*{\finallistdelim}{\bbx@cecomma}
+%\renewcommand*{\finalnamedelim}{\bbx@cecomma}%国标
+%列表中姓名显示姓在前---------------------------------------------
+\DeclareNameAlias{default}{family-given}
+%引用显示加括号----------------------------------------------------
+\renewcommand{\cite}{\Parencite}
+%引用显示括号为中括号---------------------------------------------
+\AtEveryCite{%
+ \let\bibopenparen=\bibopenbracket%
+ \let\bibcloseparen=\bibclosebracket}
+%引用显示中文顿号、中文逗号改为英文逗号+英文空格----------------
+\renewcommand{\bbx@cnbcomma}{\addcomma\space}
+\renewcommand{\bbx@cncomma}{\addcomma\space}
+%解决addendum中cite导致的bug-----------------------------------
+\newcommand*{\mkbibcitesafe}{\blx@initunit}
+%%文献列表不显示type-----------------------------------------------
+%\DeclareFieldFormat*{type}{}
+\makeatother
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%去掉列表中年份的括号并在年份前加英文逗号和空格----------------
+\usepackage{xpatch}
+\xpatchbibmacro{date+extradate}{%
+ \printtext[parens]%
+}{%
+ \setunit*{\addcomma\space}%
+ \printtext%
+}{}{}
+%增加列表项间距---------------------------------------------------
+\setlength{\bibitemsep}{.3\baselineskip plus 0.2ex minus 0.1ex}
+%解决列表中带连字符-的姓忽略前缀排序的问题----------------------
+\DeclareNosort{
+ % strip diacritics when sorting names
+ \nosort{type_names}{\regexp{[\x{2bf}\x{2018}]}}
+}
+\DeclareNoinit{
+ % strip diacritics when generating initials from n¥ames
+ \noinit{\regexp{[\x{2bf}\x{2018}]}}
+}
+%导入数据库-------------------------------------------------------
+\addbibresource{maref.bib}
+%编译前把Bibtex引擎(默认bibtex)改为biber -l zh__pinyin:
+%TeXShop-偏好设置-引擎-Bibtex引擎-biber -l zh__pinyin
+%编译顺序xelatex-bibtex-xelatex-xelatex
+%%文献类型及标志代码---------------------------------------------
+%期刊J;普通图书M;会议论文C;学位论文D;报告R;汇编G;报纸N
+%标准S;专利P;档案A;数据库DB;计算机程序CP;电子公告EB;其它Z
+%电子文献:磁带(magnetic)MT;磁盘(disk)DK;光盘(CD-ROM);联机网络CD(online)OL
+%让\cite带[]--------------------------------------------------------
+\renewcommand{\cite}{\parencite}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%定义颜色%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\usepackage{xcolor}%hyperref使用定义颜色不能用color宏包而必须用xcolor宏包
+%\definecolor{ColorName}{rgb}{r,g,b} %这时r/g/b的定义域就在[0-1]。
+\definecolor{thupurple}{RGB}{102,8,116} %这时R/G/B的定义域就在[0-255]
+\definecolor{thucyan}{RGB}{0,75,75}%for example block
+\definecolor{thubrown}{RGB}{150,75,0}%for example block
+%%%添加超链接%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\usepackage[bookmarks=false,colorlinks=true,
+citecolor=black,filecolor=black,linkcolor=black,urlcolor=black
+]{hyperref}
+%hidelinks去掉超链接框
+%%%url字体设置%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%\urlstyle{same}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%使用音标符号%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\usepackage[safe]{tipa}
+
+%%%排版出的代码格式%%%%%%%%%%%%%%%%%%%%%%
+\usepackage{listings}%可以写代码
+%%%代码格式设置-------------------------
+\lstset{ %
+ language=[LaTeX]Tex, % the language of the code
+ basicstyle=\small\ttfamily,% the size of the fonts that are used for the code
+ numbers=none, % where to put the line-numbers, left or right or none
+ numberstyle=\color[RGB]{0,0,0}, % the style that is used for the line-numbers
+ stepnumber=1, % the step between two line-numbers. If it's 1, each line will be numbered
+ numbersep=5pt, % how far the line-numbers are from the code
+ %backgroundcolor=\color[RGB]{249,249,249}, % choose the background color. You must add \usepackage{color}
+ %captionpos=b\centering,%t, top;b,bottom
+ abovecaptionskip=-0.2\baselineskip,
+ belowcaptionskip=0.5\baselineskip,
+ frame=single, % adds a frame around the code
+ framerule=.8pt,
+ %rulecolor=\color[RGB]{1,1,90},
+ frame=tb,
+ %frameround=tttt,%fttt
+ framexleftmargin=0pt,
+ framexrightmargin=0pt,
+ framextopmargin=0pt,
+ framexbottommargin=0pt,
+ commentstyle=\color[RGB]{130,130,130}, % comment style
+ stringstyle=\color[RGB]{130,130,130}, % string literal style
+ aboveskip=.6\baselineskip plus 0.4ex minus 0.2ex,
+ belowskip=.3\baselineskip plus 0.2ex minus 0.1ex,
+ xleftmargin=0pt,
+ xrightmargin=0pt,
+}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% 正文 %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\title{\bfseries 数学字母表}
+\author{赵晓玉\thanks{zhaoxy00@126.com;本文的主要内容亦被写进\cite[第1.1节]{Sllj2021}。}}
+%\date{2021年12月25日}
+\begin{document}
+\maketitle
+
+%%%删除原页眉页脚格式%%%%%%%%%%%%%%%%%%%%%%%
+\pagestyle{fancy}
+\fancypagestyle{plain}{\pagestyle{fancy}}
+%%%设置新页眉页脚格式%%%%%%%%%%%%%%%%%%%%%%%
+\fancyhf{}
+\fancyfoot[C]{\small\thepage/\pageref{LastPage}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{abstract}
+ 无论是数理逻辑,还是哲理逻辑,都与众多数学分支一样,需要使用大量的符号,其中使用最多的就是各种字母。进一步说,使用较多的是希腊(Greek)字母和拉丁(Latin)字母,使用不多的还有希伯来(Hebrew)字母。根据外观特征和线重大小的不同,字母不仅有常规体、罗马体、无衬线体、打印体、直立体、意体、斜体、小大写体、中等体、粗体等,还有手写体、书法体、哥特体、双线体、板粗体等\footnote{其对应英文依次分别为normal font、Roman font、sans serif font、typewritter font、up font、italic font、slant font、samll capital font、medium font、bold font等,script font、calligraphic font、fraktur font、double stroke font、blackboard bold font等。另外,字母的字体远不止这些,这里所列的只是\LaTeX{}中经常出现的。}。对于拉丁字母的前一类,大多数人都比较熟悉,而对于希腊字母、拉丁字母的后一类和希伯来字母,大多数人不太熟悉,所以本文对希腊字母、拉丁字母的后一类和希伯来字母进行简单介绍\footnote{这里不会过多介绍与之相关的\LaTeX{}使用问题。有兴趣了解更多相关内容的读者请见\cite[第19, 21章]{Lsyc2017}或\cite{Mmil2016}。},并对相关使用和具体读法给出一定建议。
+ \par{\bfseries 关键词:}希腊字母;手写体;书法体;哥特体;双线体;板粗体;希伯来字母
+\end{abstract}
+
+\par 希腊字母是由希腊人在腓尼基(Phoenicia)字母基础上增加元音(vowel)字母而来的,已被广泛应用于数学、物理、化学、天文、地理、生物等学科。希腊字母在古希腊时期有很多变体,直到公元前4世纪末方才演变成现在的24个字母。作为符号,希腊字母的大写(uppercase)一般以直立体出现,小写(lowercase)一般以意体出现。\LaTeX{}会提供多种样式的大写和小写希腊字母\footnote{详见\cite{Asfm2006}。},其中最常用的是克努斯于1977--1979年设计的样式\footnote{Knuth, D. E.,1938--至今,美国计算机学家、数学家,\TeX{}系统的发明者;详见\cite[第3, 175--187页]{Tcmf1980}。克努斯后于1992年发布的\TeX{}版本中改进了$\delta$的样式,而其改进后的样式就是现在看到的样式,于此详见\cite{Imut2009}。},而不需调用任何宏包即可使用它们。
+
+{\small\setlength{\LTleft}{0em}\setlength{\LTright}{0em}
+ \begin{longtable}{@{\extracolsep{\fill}}clclll}
+ %@{\extracolsep{\fill}}设置使得后面所有列间距可以伸展到预定义的表格宽度。
+ \caption{希腊字母} %\label{}加在\caption{}的括号中
+ \\\toprule%首页顶线[0.8pt]
+ 样式&命令&样式&命令&希腊文发音&英文发音\\
+ \midrule\endfirsthead%首页表头底线
+ \midrule%跨页表头顶线
+ 样式&命令&样式&命令&希腊文发音&英文发音\\
+ \midrule\endhead%跨页表头底线
+ \midrule\endfoot%跨页底线
+ \bottomrule\endlastfoot%末页底线
+ $\mathrm{A}$&\verb|\mathrm{A}|&$\alpha$&\verb|\alpha|&\textipa{[\textprimstress AlfA]}&\textipa{[\textprimstress \ae lf\textschwa]} \\
+ $\mathrm{B}$&\verb|\mathrm{B}|&$\beta$&\verb|\beta|&\textipa{[\textprimstress vi\textlengthmark tA]}&\textipa{[\textprimstress bI\textlengthmark t\textschwa]}/\textipa{[\textprimstress beIt\textschwa]} \\
+ $\Gamma$&\verb|\Gamma|&$\gamma$&\verb|\gamma|&\textipa{[\textprimstress gAmA]}&\textipa{[\textprimstress g\ae m\textschwa]}\\
+ $\Delta$&\verb|\Delta|&$\delta$&\verb|\delta|&\textipa{[\textprimstress DeltA]}&\textipa{[\textprimstress delt\textschwa]}\\
+ $\mathrm{E}$&\verb|\mathrm{E}|&$\epsilon$&\verb|\epsilon|&\textipa{[\textprimstress epsi\textlengthmark l\textschwa Un]}&\textipa{[\textprimstress epsIl6n]}/\textipa{[ep\textprimstress saIl\textschwa n]}\\
+ $\mathrm{Z}$&\verb|\mathrm{Z}|&$\zeta$&\verb|\zeta|&\textipa{[\textprimstress zi\textlengthmark tA]}&\textipa{[\textprimstress zi\textlengthmark t\textschwa]}/\textipa{[\textprimstress zeIt\textschwa]}\\
+ $\mathrm{H}$&\verb|\mathrm{H}|&$\eta$&\verb|\eta|&\textipa{[\textprimstress i\textlengthmark tA]}&\textipa{[\textprimstress i\textlengthmark t\textschwa]}/\textipa{[\textprimstress eIt\textschwa]}\\
+ $\Theta$&\verb|\Theta|&$\theta$&\verb|\theta|&\textipa{[\textprimstress Ti\textlengthmark tA]}&\textipa{[\textprimstress Ti\textlengthmark t\textschwa]}/\textipa{[\textprimstress TeIt\textschwa]}\\
+ $\mathrm{I}$&\verb|\mathrm{I}|&$\iota$&\verb|\iota|&\textipa{[\textprimstress j\textschwa UtA]}&\textipa{[aI\textprimstress\textschwa Ut\textschwa]}\\
+ $\mathrm{K}$&\verb|\mathrm{K}|&$\kappa$&\verb|\kappa|&\textipa{[\textprimstress kApA]}&\textipa{[\textprimstress k\ae p\textschwa]}\\
+ $\Lambda$&\verb|\Lambda|&$\lambda$&\verb|\lambda|&\textipa{[\textprimstress lAmDA]}&\textipa{[\textprimstress l\ae md\textschwa]}\\
+ $\mathrm{M}$&\verb|\mathrm{M}|&$\mu$&\verb|\mu|&\textipa{[mi\textlengthmark]}&\textipa{[mju\textlengthmark]}\\
+ $\mathrm{N}$&\verb|\mathrm{N}|&$\nu$&\verb|\nu|&\textipa{[ni\textlengthmark]}&\textipa{[nju\textlengthmark]}\\
+ $\Xi$&\verb|\Xi|&$\xi$&\verb|\xi|&\textipa{[ksi\textlengthmark]}&\textipa{[ksaI]}/\textipa{[gzaI]}/\textipa{[zaI]}/\textipa{[saI]}\\
+ $\mathrm{O}$&\verb|\mathrm{O}|&$o$&\verb|o|&\textipa{[\textprimstress \textschwa Umi\textlengthmark kr\textschwa Un]}&\textipa{[\textschwa U\textprimstress maIkr6n]}/\textipa{[\textprimstress 6mikr6n]}\\
+ $\Pi$&\verb|\Pi|&$\pi$&\verb|\pi|&\textipa{[pi\textlengthmark]}&\textipa{[paI]}\\
+ $\mathrm{P}$&\verb|\mathrm{P}|&$\rho$&\verb|\rho|&\textipa{[r\textschwa U]}&\textipa{[r\textschwa U]}\\
+ $\Sigma$&\verb|\Sigma|&$\sigma$&\verb|\sigma|&\textipa{[\textprimstress si\textlengthmark gmA]}&\textipa{[\textprimstress sigm\textschwa]}\\
+ $\mathrm{T}$&\verb|\mathrm{T}|&$\tau$&\verb|\tau|&\textipa{[tAf]}&\textipa{[taU]}/\textipa{[tO\textlengthmark]}\\
+ $\mathrm{Y}$&\verb|\mathrm{Y}|&$\upsilon$&\verb|\upsilon|&\textipa{[\textprimstress i\textlengthmark psi\textlengthmark l\textschwa Un]}&\textipa{[2p\textprimstress sail\textschwa n]}/\textipa{[\textprimstress Upsil6n]}/\textipa{[ju\textlengthmark p\textprimstress sail\textschwa n]}\\
+ $\Phi$&\verb|\Phi|&$\phi$&\verb|\phi|&\textipa{[fi\textlengthmark]}&\textipa{[fai]}\\
+ $\mathrm{X}$&\verb|\mathrm{X}|&$\chi$&\verb|\chi|&\textipa{[hi\textlengthmark]}&\textipa{[kaI]}\\
+ $\Psi$&\verb|\Psi|&$\psi$&\verb|\psi|&\textipa{[psi\textlengthmark]}&\textipa{[psaI]}/\textipa{[saI]}\\
+ $\Omega$&\verb|\Omega|&$\omega$&\verb|\omega|&\textipa{[\textschwa U\textprimstress megA]}&\textipa{[\textprimstress\textschwa UmIg\textschwa]}/\textipa{[\textschwa U\textprimstress meg\textschwa]}/\textipa{[\textschwa U\textprimstress meIg\textschwa]}\\
+ \end{longtable}
+}
+
+\begin{remark}
+ \begin{enumerate}
+ \item 大写的$\mathrm{A,B,E,Z,H,I,K,M,N,O,P,T,Y,X}$与相应的拉丁字母十分相似,因而所用甚少。小写的$o,\upsilon$与拉丁字母$o, u$ 也很相似,因而所用也甚少。
+ \item 在调用~\verb|amsmath|~宏包后,可以获得全部大写希腊字母的斜体:$A,B,E,Z,H,I,K,M,$ $N,O,P,T,Y,X$的命令依次分别是 \verb|A|, \verb|B|, \verb|E|, \verb|Z|, \verb|H|, \verb|I|, \verb|K|, \verb|M|, \verb|N|, \verb|O|, \verb|P|, \verb|T|, \verb|Y|, \verb|X|;而$\varGamma,\varDelta,\varTheta,\varLambda,$ $\varXi,\varPi,\varSigma,\varPhi,\varPsi,\varOmega$的命令依次分别是 \verb|\varGamma|, \verb|\varDelta|, \verb|\varTheta|, \verb|\varLambda|, \verb|\varXi|, \verb|\varPi|, \verb|\varSigma|, \verb|\varPhi|, \verb|\varPsi|, \verb|\varOmega|。在调用~\verb|amssymb|~宏包后(只有$\varkappa$需要),也可以得到部分小写希腊字母的变体\footnote{作为文本的小写simga有两种形式,即$\sigma,\varsigma$,其中后者是尾式(final form),用于单词的结尾;而作为符号的小写sigma,一般采用$\sigma$这种形式。另外,$\varepsilon,\varkappa,\vartheta,\varpi,\varrho,\varphi$仅仅是变体,而非尾式,更多知识详见\cite{Wdvs2020}。}:$\varepsilon,\varkappa,\vartheta,\varpi,\varrho,\varsigma,\varphi$的命令依次分别是 \verb|\varepsilon|, \verb|\varkappa|, \verb|\vartheta|, \verb|\varpi|, \verb|\varrho|, \verb|\varsigma|, \verb|\varphi|。不过,希腊字母大写的斜体和这部分希腊字母小写的变体,除$\vartheta,\varphi$外(并且一般不与$\theta,\phi$同时出现),使用相对较少。
+ \item 可以看到,希腊字母的希腊文发音和英文发音基本都不一样,有的差别甚至很大。对此,建议读者统一采用英文发音以便交流,毕竟当今世界学术交流的主要语言是英文\footnote{这与采用母语发音去读一个人姓名的情况有所不同,毕竟他早已习惯了周围人用母语发音谈及他,而当他听到别人再用别的语言发音谈及他时,他很可能不习惯。当然,如果他本人乐意接受其他语言发音,也未尝不能采用其他语言发音。}。当然,在面对希腊族裔时,也可以统一采用希腊文发音以示尊重。不过,在同种情况下“一会儿用希腊文读$\alpha$一会儿用英文读$\omega$”的混合做法多少有些不可取。
+ \end{enumerate}
+\end{remark}
+
+拉丁字母,与阿拉伯(Arabic)字母、西里尔(Cyrillic)字母并称世界三大字母体系,由罗马人在希腊字母基础上略微改变和逐渐分化而来,直至公元11世纪方才演变成现在的26个字母,所以又称为罗马字母。中文拼音方案采用的就是拉丁字母,西方大部分国家和地区的语言也早已采用拉丁字母。
+
+手写体是指字母外观很像手写出来的一种字体。手写体分正规(formal)手写体和即兴(casual)手写体,二者虽然都带有手写的特征,但是前者相比更为齐整因而也更适合印刷。\LaTeX{}会提供多种样式的手写体大写拉丁字母\footnote{详见\cite{Tmap2021}。},其中最常用的是史密斯于1991年设计的样式,而只需调用~\verb|mathrsfs|~宏包\footnote{Smith, R.;详见\cite{Rsrm1991};rsfs是Ralph Smith's Formal Script的缩写,意为“史密斯设计的正规手写体”。}即可使用它们。
+
+{\small\setlength{\LTleft}{0pt} \setlength{\LTright}{0pt}
+ \begin{longtable}{@{\extracolsep{\fill}}cccccccc}
+ %@{\extracolsep{\fill}}设置使得后面所有列间距可以伸展到预定义的表格宽度。
+ \caption{手写体字母} %\label{}加在\caption{}的括号中
+ \\\toprule%首页顶线
+ 样式&命令&样式&命令&样式&命令&样式&命令\\
+ \midrule\endfirsthead%首页表头底线
+ \midrule%跨页表头顶线
+ 样式&命令&样式&命令&样式&命令&样式&命令\\
+ \midrule\endhead%跨页表头底线
+ \midrule\endfoot%跨页底线
+ \bottomrule\endlastfoot%末页底线
+ $\mathscr{A}$&\verb|\mathscr{A}|&$\mathscr{B}$&\verb|\mathscr{B}|&$\mathscr{C}$&\verb|\mathscr{C}|&$\mathscr{D}$&\verb|\mathscr{D}|\\
+ $\mathscr{E}$&\verb|\mathscr{E}|&$\mathscr{F}$&\verb|\mathscr{F}| &$\mathscr{G}$&\verb|\mathscr{G}|&$\mathscr{H}$&\verb|\mathscr{H}|\\
+ $\mathscr{I}$&\verb|\mathscr{I}|&$\mathscr{J}$&\verb|\mathscr{J}|&$\mathscr{K}$&\verb|\mathscr{K}|&$\mathscr{L}$&\verb|\mathscr{L}| \\
+ $\mathscr{M}$&\verb|\mathscr{M}|&$\mathscr{N}$&\verb|\mathscr{N}|&$\mathscr{O}$&\verb|\mathscr{O}|&$\mathscr{P}$&\verb|\mathscr{P}|\\
+ $\mathscr{Q}$&\verb|\mathscr{Q}|&$\mathscr{R}$&\verb|\mathscr{R}|&$\mathscr{S}$&\verb|\mathscr{S}|&$\mathscr{T}$&\verb|\mathscr{T}|\\
+ $\mathscr{U}$&\verb|\mathscr{U}|&$\mathscr{V}$&\verb|\mathscr{V}|&$\mathscr{W}$&\verb|\mathscr{W}|&$\mathscr{X}$&\verb|\mathscr{X}| \\
+ $\mathscr{Y}$&\verb|\mathscr{Y}|&$\mathscr{Z}$&\verb|\mathscr{Z}|&&&&\\
+ \end{longtable}
+}
+\begin{remark}
+ \begin{enumerate}
+ \item 除$\mathscr{A,B,C,D,E,F,G,H,K,L,P,T,U,X,Y}$外,其他手写体字母或者不够美观,或者难以识别,因而所用甚少。
+ \item 不妨举例说明手写体字母的读法,比如$\mathscr{D}$,用中文可以读作“手写体D”,用英文可以读作“script D”。
+ \end{enumerate}
+\end{remark}
+
+书法体是指字母外观很像专门练过书法的人写出来的一种字体。显然,书法体也是一种手写字体,所以有些\LaTeX{}宏包干脆把书法体和手写体都设置成手写体的外观,如~\verb|mathdesign|、\verb|fourier|~等。\LaTeX{}会提供多种样式的书法体大写拉丁字母\footnote{详见\cite{Tmap2021}。},其中最常用的是克努斯于1977--1979年设计的样式\footnote{详见\cite[第3, 251--269页]{Tcmf1980}。克努斯后于1992年发布的\TeX{}版本中改进了$\mathcal{H,I,T}$的样式,而其改进后的样式就是现在看到的样式,于此详见\cite{Imut2009}。},而只需调用 \verb|amsfonts| 或 \verb|amsmath| 宏包即可使用它们。
+
+{\small\setlength{\LTleft}{0pt} \setlength{\LTright}{0pt}
+ \begin{longtable}{@{\extracolsep{\fill}}cccccccc}
+ %@{\extracolsep{\fill}}设置使得后面所有列间距可以伸展到预定义的表格宽度。
+ \caption{书法体字母} %\label{}加在\caption{}的括号中
+ \\\toprule%首页顶线
+ 样式&命令&样式&命令&样式&命令&样式&命令\\
+ \midrule\endfirsthead%首页表头底线
+ \midrule%跨页表头顶线
+ 样式&命令&样式&命令&样式&命令&样式&命令\\
+ \midrule\endhead%跨页表头底线
+ \midrule\endfoot%跨页底线
+ \bottomrule\endlastfoot%末页底线
+ $\mathcal{A}$&\verb|\mathcal{A}|&$\mathcal{B}$&\verb|\mathcal{B}|&$\mathcal{C}$&\verb|\mathcal{C}|&$\mathcal{D}$&\verb|\mathcal{D}|\\
+ $\mathcal{E}$&\verb|\mathcal{E}|&$\mathcal{F}$&\verb|\mathcal{F}| &$\mathcal{G}$&\verb|\mathcal{G}|&$\mathcal{H}$&\verb|\mathcal{H}|\\
+ $\mathcal{I}$&\verb|\mathcal{I}|&$\mathcal{J}$&\verb|\mathcal{J}|&$\mathcal{K}$&\verb|\mathcal{K}|&$\mathcal{L}$&\verb|\mathcal{L}| \\
+ $\mathcal{M}$&\verb|\mathcal{M}|&$\mathcal{N}$&\verb|\mathcal{N}|&$\mathcal{O}$&\verb|\mathcal{O}|&$\mathcal{P}$&\verb|\mathcal{P}|\\
+ $\mathcal{Q}$&\verb|\mathcal{Q}|&$\mathcal{R}$&\verb|\mathcal{R}|&$\mathcal{S}$&\verb|\mathcal{S}|&$\mathcal{T}$&\verb|\mathcal{T}|\\
+ $\mathcal{U}$&\verb|\mathcal{U}|&$\mathcal{V}$&\verb|\mathcal{V}|&$\mathcal{W}$&\verb|\mathcal{W}|&$\mathcal{X}$&\verb|\mathcal{X}| \\
+ $\mathcal{Y}$&\verb|\mathcal{Y}|&$\mathcal{Z}$&\verb|\mathcal{Z}|&&&&\\
+ \end{longtable}
+}
+\begin{remark}
+ \begin{enumerate}
+ \item 书法体字母整体上比较美观、容易识别,读者可以根据自己喜好和需要选用。
+ \item 不妨举例说明书法体字母的读法,比如$\mathcal{N}$,用中文可以读作“书法体N”,用英文可以读作“calligraphic N”。
+ \end{enumerate}
+\end{remark}
+
+哥特体是指字母笔划相对破碎从而不能连笔书写的字体,而“哥特”对应的德文fraktur正是源自本为破碎之意的拉丁文fract\={u}ra。它的比划除了整体比较粗重外,还带有明显尖角,所以又译为尖角体。\LaTeX{}会提供多种样式的哥特体大写和小写拉丁字母\footnote{详见\cite{Tmap2021}。},其中最常用的是察普夫于1980--1983年设计的样式\footnote{Zapf, H.,1918--2015,德国书法家、字体设计师;详见\cite[第3页]{Uams2002}和\cite[第23页]{Tnps2006}。察普夫后于2009年发布的\texttt{amsfonts}版本中改进了部分字母的样式,而其改进后的样式就是现在看到的样式,于此详见\cite{Ramf2013}。},而只需调用 \verb|amsfonts| 或 \verb|amssymb| 宏包即可使用它们。
+
+{\small\setlength{\LTleft}{0pt} \setlength{\LTright}{0pt}
+ \begin{longtable}{@{\extracolsep{\fill}}cccccccc}
+ %@{\extracolsep{\fill}}设置使得后面所有列间距可以伸展到预定义的表格宽度。
+ \caption{哥特体字母} %\label{}加在\caption{}的括号中
+ \\\toprule%首页顶线
+ 样式&命令&样式&命令&样式&命令&样式&命令\\
+ \midrule\endfirsthead%首页表头底线
+ \midrule%跨页表头顶线
+ 样式&命令&样式&命令&样式&命令&样式&命令\\
+ \midrule\endhead%跨页表头底线
+ \midrule\endfoot%跨页底线
+ \bottomrule\endlastfoot%末页底线
+ $\mathfrak{A}$&\verb|\mathfrak{A}|&$\mathfrak{a}$&\verb|\mathfrak{a}|& $\mathfrak{B}$&\verb|\mathfrak{B}|&$\mathfrak{b}$&\verb|\mathfrak{b}|\\
+ $\mathfrak{C}$&\verb|\mathfrak{C}|&$\mathfrak{c}$&\verb|\mathfrak{c}| & $\mathfrak{D}$&\verb|\mathfrak{D}|&$\mathfrak{d}$&\verb|\mathfrak{d}|\\
+ $\mathfrak{E}$&\verb|\mathfrak{E}|&$\mathfrak{e}$&\verb|\mathfrak{e}|& $\mathfrak{F}$&\verb|\mathfrak{F}|&$\mathfrak{f}$&\verb|\mathfrak{f}|\\
+ $\mathfrak{G}$&\verb|\mathfrak{G}|&$\mathfrak{g}$&\verb|\mathfrak{g}|& $\mathfrak{H}$&\verb|\mathfrak{H}|&$\mathfrak{h}$&\verb|\mathfrak{h}|\\
+ $\mathfrak{I}$&\verb|\mathfrak{I}|&$\mathfrak{i}$&\verb|\mathfrak{i}|& $\mathfrak{J}$&\verb|\mathfrak{J}|&$\mathfrak{j}$&\verb|\mathfrak{j}|\\
+ $\mathfrak{K}$&\verb|\mathfrak{K}|&$\mathfrak{k}$&\verb|\mathfrak{k}|& $\mathfrak{L}$&\verb|\mathfrak{L}|&$\mathfrak{l}$&\verb|\mathfrak{l}|\\
+ $\mathfrak{M}$&\verb|\mathfrak{M}|&$\mathfrak{m}$&\verb|\mathfrak{m}|& $\mathfrak{N}$&\verb|\mathfrak{N}|&$\mathfrak{n}$&\verb|\mathfrak{n}|\\
+ $\mathfrak{O}$&\verb|\mathfrak{O}|&$\mathfrak{o}$&\verb|\mathfrak{o}|& $\mathfrak{P}$&\verb|\mathfrak{P}|&$\mathfrak{p}$&\verb|\mathfrak{p}|\\
+ $\mathfrak{Q}$&\verb|\mathfrak{Q}|&$\mathfrak{q}$&\verb|\mathfrak{q}|& $\mathfrak{R}$&\verb|\mathfrak{R}|&$\mathfrak{r}$&\verb|\mathfrak{r}|\\
+ $\mathfrak{S}$&\verb|\mathfrak{S}|&$\mathfrak{s}$&\verb|\mathfrak{s}|& $\mathfrak{T}$&\verb|\mathfrak{T}|&$\mathfrak{t}$&\verb|\mathfrak{t}|\\
+ $\mathfrak{U}$&\verb|\mathfrak{U}|&$\mathfrak{u}$&\verb|\mathfrak{u}|& $\mathfrak{V}$&\verb|\mathfrak{V}|&$\mathfrak{v}$&\verb|\mathfrak{v}|\\
+ $\mathfrak{W}$&\verb|\mathfrak{W}|&$\mathfrak{w}$&\verb|\mathfrak{w}|& $\mathfrak{X}$&\verb|\mathfrak{X}|&$\mathfrak{x}$&\verb|\mathfrak{x}|\\
+ $\mathfrak{Y}$&\verb|\mathfrak{Y}|&$\mathfrak{y}$&\verb|\mathfrak{y}|& $\mathfrak{Z}$&\verb|\mathfrak{Z}|&$\mathfrak{z}$&\verb|\mathfrak{z}|\\
+ \end{longtable}
+}
+\begin{remark}
+ \begin{enumerate}
+ \item 大写的$\mathfrak{H,I,K,O,Q,V,W,Y,Z}$和小写的$\mathfrak{k,v,w,x,y,z}$,或者貌似其他,或者难以识别,因而所用甚少。
+ \item 不妨举例说明哥特体字母的读法,比如$\mathfrak{F}$,用中文可以读作“哥特体F”,用英文可以读作“fraktur F”。
+ \end{enumerate}
+\end{remark}
+
+双线体是指对字母的部分比划做双线处理的字体。\LaTeX{}会提供多种样式的双线体大写拉丁字母\footnote{详见\cite{Tmap2021}。},其中最常用的是库默尔于1997年设计的样式\footnote{Kummer, O.;详见\cite{Tpvd1997}。},而只需调用 \verb|dsfont| 宏包即可使用它们。
+
+{\small\setlength{\LTleft}{0pt} \setlength{\LTright}{0pt}
+ \begin{longtable}{@{\extracolsep{\fill}}cccccccc}
+ %@{\extracolsep{\fill}}设置使得后面所有列间距可以伸展到预定义的表格宽度。
+ \caption{双线体字母} %\label{}加在\caption{}的括号中
+ \\\toprule%首页顶线
+ 样式&命令&样式&命令&样式&命令&样式&命令\\
+ \midrule\endfirsthead%首页表头底线
+ \midrule%跨页表头顶线
+ 样式&命令&样式&命令&样式&命令&样式&命令\\
+ \midrule\endhead%跨页表头底线
+ \midrule\endfoot%跨页底线
+ \bottomrule\endlastfoot%末页底线
+ $\mathds{A}$&\verb|\mathds{A}|&$\mathds{B}$&\verb|\mathds{B}|&$\mathds{C}$&\verb|\mathds{C}|&$\mathds{D}$&\verb|\mathds{D}|\\
+ $\mathds{E}$&\verb|\mathds{E}|&$\mathds{F}$&\verb|\mathds{F}| &$\mathds{G}$&\verb|\mathds{G}|&$\mathds{H}$&\verb|\mathds{H}|\\
+ $\mathds{I}$&\verb|\mathds{I}|&$\mathds{J}$&\verb|\mathds{J}|&$\mathds{K}$&\verb|\mathds{K}|&$\mathds{L}$&\verb|\mathds{L}| \\
+ $\mathds{M}$&\verb|\mathds{M}|&$\mathds{N}$&\verb|\mathds{N}|&$\mathds{O}$&\verb|\mathds{O}|&$\mathds{P}$&\verb|\mathds{P}|\\
+ $\mathds{Q}$&\verb|\mathds{Q}|&$\mathds{R}$&\verb|\mathds{R}|&$\mathds{S}$&\verb|\mathds{S}|&$\mathds{T}$&\verb|\mathds{T}|\\
+ $\mathds{U}$&\verb|\mathds{U}|&$\mathds{V}$&\verb|\mathds{V}|&$\mathds{W}$&\verb|\mathds{W}|&$\mathds{X}$&\verb|\mathds{X}| \\
+ $\mathds{Y}$&\verb|\mathds{Y}|&$\mathds{Z}$&\verb|\mathds{Z}|&&&&\\
+ \end{longtable}
+}
+\begin{remark}
+ \begin{enumerate}
+ \item 双线体字母整体上线重不均,因而所用甚少。
+ \item 不妨举例说明双线体字母的读法,比如$\mathds{B}$,用中文可以读作“双线体B”,用英文可以读作“double stroke B”。
+ \end{enumerate}
+\end{remark}
+
+板粗体,即通常意义下的空心(hollow)体,是指在黑板上书写字母时所使用的一种粗体,而为了便于在黑板上书写粗体字母就需要对字母的部分比划做双线处理。这样来说,板粗体也是一种双线体,所以有些\LaTeX{}宏包干脆把板粗体和双线体都设置成双线体的外观,如 \verb|mathdesign| 等。\LaTeX{}会提供多种样式的板粗体大写拉丁字母\footnote{详见\cite{Tmap2021}。},其中最常用的是美国数学会(American Mathematical Society)于1979--1990年间创建的样式\footnote{关于具体时间和设计者,目前尚不可考,所以这只是一个粗略时间,详见\cite{Wwdb2020}。对于硬朗内敛、线重较大的英文字体,比如Times等字体,该款板粗体字母比较搭配。而对于柔和外向、线重较小的英文字体,比如\LaTeX{}默认的Computer Modern字体等,赵晓玉于2020年设计的样式(详见\cite{Tcpb2020},只需调用\texttt{cmathbb}宏包即可使用)更为搭配。},而只需调用 \verb|amsfonts| 或 \verb|amssymb| 宏包即可使用它们。
+
+{\small\setlength{\LTleft}{0pt} \setlength{\LTright}{0pt}
+ \begin{longtable}{@{\extracolsep{\fill}}cccccccc}
+ %@{\extracolsep{\fill}}设置使得后面所有列间距可以伸展到预定义的表格宽度。
+ \caption{板粗体字母} %\label{}加在\caption{}的括号中
+ \\\toprule%首页顶线
+ 样式&命令&样式&命令&样式&命令&样式&命令\\
+ \midrule\endfirsthead%首页表头底线
+ \midrule%跨页表头顶线
+ 样式&命令&样式&命令&样式&命令&样式&命令\\
+ \midrule\endhead%跨页表头底线
+ \midrule\endfoot%跨页底线
+ \bottomrule\endlastfoot%末页底线
+ $\mathbb{A}$&\verb|\mathbb{A}|&$\mathbb{B}$&\verb|\mathbb{B}|&$\mathbb{C}$&\verb|\mathbb{C}|&$\mathbb{D}$&\verb|\mathbb{D}|\\
+ $\mathbb{E}$&\verb|\mathbb{E}|&$\mathbb{F}$&\verb|\mathbb{F}| &$\mathbb{G}$&\verb|\mathbb{G}|&$\mathbb{H}$&\verb|\mathbb{H}|\\
+ $\mathbb{I}$&\verb|\mathbb{I}|&$\mathbb{J}$&\verb|\mathbb{J}|&$\mathbb{K}$&\verb|\mathbb{K}|&$\mathbb{L}$&\verb|\mathbb{L}| \\
+ $\mathbb{M}$&\verb|\mathbb{M}|&$\mathbb{N}$&\verb|\mathbb{N}|&$\mathbb{O}$&\verb|\mathbb{O}|&$\mathbb{P}$&\verb|\mathbb{P}|\\
+ $\mathbb{Q}$&\verb|\mathbb{Q}|&$\mathbb{R}$&\verb|\mathbb{R}|&$\mathbb{S}$&\verb|\mathbb{S}|&$\mathbb{T}$&\verb|\mathbb{T}|\\
+ $\mathbb{U}$&\verb|\mathbb{U}|&$\mathbb{V}$&\verb|\mathbb{V}|&$\mathbb{W}$&\verb|\mathbb{W}|&$\mathbb{X}$&\verb|\mathbb{X}| \\
+ $\mathbb{Y}$&\verb|\mathbb{Y}|&$\mathbb{Z}$&\verb|\mathbb{Z}|&&&&\\
+ \end{longtable}
+}
+\begin{remark}
+ \begin{enumerate}
+ \item 板粗体字母整体上比较美观、容易识别,读者可以根据自己喜好和需要选用。
+ \item 不妨举例说明板粗体字母的读法,比如$\mathbb{R}$,用中文可以读作“板粗体R”,用英文可以读作“blackboard bold R”。
+ \end{enumerate}
+\end{remark}
+
+\par 希伯来字母是由希伯来人(早期的犹太人)于公元前3世纪在皇室阿拉姆(Imperial Aramaic)字母基础上方化书写和分化演变而来,所以外观比较方正,而皇室阿拉姆字母则从腓尼基字母发展而来。与其他现代字母体系不同的是,希伯来字母没有大小写之分,共有22个字母,其中5个字母还有尾式,用于单词的结尾。作为符号,希伯来字母一般以直立体出现。\LaTeX{}目前能提供的字母齐全的样式较少,其中比较好的是措勒迈提斯于2019年设计的样式\footnote{Tsolomitis, A.;详见\cite{Rdme2021}。}。
+
+{\small\setlength{\LTleft}{0em} \setlength{\LTright}{0em}
+ \begin{longtable}{@{\extracolsep{\fill}}cccclll}
+ %@{\extracolsep{\fill}}设置使得后面所有列间距可以伸展到预定义的表格宽度。
+ \caption{希伯来字母} %\label{}加在\caption{}的括号中
+ \\\toprule%首页顶线
+ 样式&统一码&尾式&统一码&名称&希伯来文发音&英文发音\\
+ \midrule\endfirsthead%首页表头底线
+ \midrule%跨页表头顶线
+ 样式&统一码&尾式&统一码&名称&希腊文发音&英文发音\\
+ \midrule\endhead%跨页表头底线
+ \midrule\endfoot%跨页底线
+ \bottomrule\endlastfoot%末页底线
+ $\aleph$&\verb|05D0|&&&aleph/alef&\textipa{[A\textlengthmark lef]}&\textipa{[\textprimstress A\textlengthmark lef]}/\textipa{[\textprimstress A\textlengthmark lIf]}/\textipa{[\textprimstress eIl\textschwa f]} \\
+ $\bet$&\verb|05D1|&&&vet/bet/beth&\textipa{[vet]}/\textipa{[bet]}&\textipa{[bet]}/\textipa{[beT]}/\textipa{[beIT]}\\
+ $\gimel$&\verb|05D2|&&&gimel&\textipa{[\textprimstress gi\textlengthmark mel]}&\textipa{[\textprimstress gi\textlengthmark mel]}/\textipa{[\textprimstress gim\textschwa l]}\\
+ $\dalet$&\verb|05D3|&&&dalet/daleth/daled&\textipa{[\textprimstress dA\textlengthmark let]}/\textipa{[\textprimstress dA\textlengthmark led]}&\textipa{[\textprimstress dA\textlengthmark let]}\\
+ $\he$&\verb|05D4|&&&he&\textipa{[he]}/\textipa{[hej]}&\textipa{[hI]}/\textipa{[hi\textlengthmark]}\\
+ $\vav$&\verb|05D5|&&&vav/waw&\textipa{[vA\textlengthmark v]}&\textipa{[v6v]}/\textipa{[vO\textlengthmark v]}/\textipa{[wO\textlengthmark]}\\
+ $\zayin$&\verb|05D6|&&&zayin&\textipa{[\textprimstress za\textlengthmark i\textlengthmark n]}&\textipa{[\textprimstress za\textlengthmark jin]}\\
+ $\het$&\texttt{05D7}&&&het/heth/chet&\textipa{[het]}&\textipa{[het]}/\textipa{[keIT]}\\
+ $\tet$&\verb|05D8|&&&tet/teth&\textipa{[tet]}&\textipa{[tet]}/\textipa{[tes]}\\
+ $\yod$&\verb|05D9|&&&yod/jod&\textipa{[jO\textlengthmark d]}/\textipa{[ju\textlengthmark d]}&\textipa{[jUd]}\\
+ $\kaf$&\verb|05DB|&$\varkaf$&\verb|05DA|&kaf&\textipa{[kA\textlengthmark f]}&\textipa{[kA\textlengthmark f]}\\
+ $\lamed$&\verb|05DC|&&&lamed&\textipa{[\textprimstress lA\textlengthmark med]}&\textipa{[leimd]}/\textipa{[\textprimstress lAmed]}\\%\textipa{[\textprimstress lA\textlengthmark mId]}
+ $\mem$&\verb|05DE|&$\varmem$&\verb|05DD|&mem&\textipa{[mem]}&\textipa{[mem]}\\
+ $\nun$&\verb|05E0|&$\varnun$&\verb|05DF|&nun&\textipa{[nu\textlengthmark n]}&\textipa{[nUn]}\\
+ $\samekh$&\verb|05E1|&&&samekh&\textipa{[\textprimstress sA\textlengthmark meh]}&\textipa{[\textprimstress sA\textlengthmark mek]}/\textipa{[\textprimstress sA\textlengthmark m\textschwa k]}\\
+ $\ayin$&\verb|05E2|&&&ayin&\textipa{[A\textlengthmark ji\textlengthmark n]}/\textipa{[A\textlengthmark i\textlengthmark n]}&\textipa{[\textprimstress A\textlengthmark jin]}/\textipa{[\textprimstress Aji\textlengthmark n]}\\
+ $\pe$&\verb|05E4|&$\varpe$&\verb|05E3|&pe&\textipa{[fe]}/\textipa{[fej]}&\textipa{[peI]}/\textipa{[pe]}\\
+ $\tsadi$&\verb|05E6|&$\vartsadi$&\verb|05E5|&tsadi/sadhe&\textipa{[\textprimstress tsA\textlengthmark di\textlengthmark]}&\textipa{[\textprimstress sA\textlengthmark di\textlengthmark]}\\
+ $\qof$&\verb|05E7|&&&qof/qoph&\textipa{[ku\textlengthmark f]}/\textipa{[kO\textlengthmark f]}&\textipa{[k6f]}\\
+ $\resh$&\verb|05E8|&&&resh&\textipa{[reS]}&\textipa{[reS]}/\textipa{[reIS]}\\
+ $\shin$&\verb|05E9|&&&shin/sheen&\textipa{[Si\textlengthmark n]}/\textipa{[si\textlengthmark n]}&\textipa{[SIn]}/\textipa{[Si\textlengthmark n]}\\
+ $\tav$&\verb|05EA|&&&tav/taw&\textipa{[tA\textlengthmark v]}/\textipa{[tA\textlengthmark f]}&\textipa{[tA\textlengthmark v]}\\
+ \end{longtable}
+}%\multirow{2}{*}{}
+
+\begin{remark}
+ \begin{enumerate}
+ \item 措勒迈提斯设计的样式整体比较美观、容易识别、线重适宜、字母齐全,所以本文推荐并且采用这种方案;它们虽然存在于~\verb|newcomputermodern|~宏包中,但是相应命令没有定义,所以无法直接使用;不妨举例说明如何使用它们,其他字母只需替换相应的统一码(unicode)即可。
+\begin{lstlisting}
+\usepackage{fontspec}
+\makeatletter
+%释放已有命令%%%%%%%%%%%%%%%%%%%%%%%%%
+\let\aleph\relax\let\beth\relax
+\let\gimel\relax\let\daleth\relax
+%调用字体文件%%%%%%%%%%%%%%%%%%%%%%%%%
+\newfontfamily\hebfont{NewCM08-Regular.otf}
+%定义相应字母%%%%%%%%%%%%%%%%%%%%%%%%%
+\newcommand\shin{\mathord{\textrm{\hebfont\char"05E9}}}
+\makeatother
+\end{lstlisting}
+ 本文使用的样式是~\verb|newcomputermodern|~宏包中线重最小的,读者如需线重稍大的,可以将~\verb|NewCM08-Regular.otf|~改为~\verb|NewCM10-Book.otf|,甚至~\verb|NewCM10-Bold.otf|。
+ \item \verb|cjhebrew|~宏包提供的样式整体也容易识别、字母齐全,并且还算美观,不过线重过大;而关于如何使用它们,详见\cite{Arch2020}。
+ \item 除$\aleph,\bet,\gimel,\dalet$外,其他希伯来字母所用甚少,所以一般情况下\LaTeX{}只提供这4个希伯来字母。通常的方案是:第1个希伯来字母不需调用任何宏包,而第2、3、4个希伯来字母则需调用~\verb|amssymb|~宏包;在这种方案下,它们的样式与本文采用的都不一样,不过由于第1个字母和第2、3、4个字母的线重不同,作者并不推荐这种方案。另一种方案是:\verb|lm-math|~宏包也提供有线重适宜、比较美观的这4个希伯来字母;在这种方案下,它们的样式与本文采用的也都不一样,不过在不使用其他希伯来字母的情况下,作者也推荐这种方案;而关于如何调用该宏包中的这4个字母,详见\cite{Arhi2021}。关于其他方案,详见\cite{Arab2017}。
+ \item 可以看到,希腊字母的希伯来文发音和英文发音整体有一定的差别。对此,建议读者统一采用英文发音以便交流,毕竟当今世界学术交流的主要语言是英文。当然,在面对希伯来(犹太)族裔时,也可以统一采用希伯来文发音以示尊重。不过,在同种情况下“一会儿用希伯来文读$\he$一会儿用英文读$\pe$”的混合做法多少有些不可取。
+ \end{enumerate}
+\end{remark}
+
+%阿拉伯字母作为数学符号:https://tex.stackexchange.com/a/366306/140814 (不过线重较大)
+
+%西里尔字母作为数学符号:https://tex.stackexchange.com/a/124746/140814 (线重适宜)
+
+%\small
+%%%打印参考文献%%%%%%%%%%%%%%%%%%%%%%%
+\printbibliography[title = {参考文献}]%heading = bibintoc
+\nocite{*}%未被引用的文献也编译到PDF:若不用加到[]中,在这行把其取消注释就行
+%若出现未被引用文献编号不出现的问题,删除Aux文件再执行一套编译方式即可
+%bibintoc 把参考文献加入目录中; bibnumbered 参考文献列表参与章节编号(同时加入目录)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section*{更新史志}
+\begin{itemize}
+ \item 第2.2版\quad 2021-12-27\quad 更正了个别笔误。
+ \item 第2.1版\quad 2021-12-25\quad 修正并扩充了关~\verb|\varepsilon|, \verb|\varkappa|, \verb|\vartheta|, \verb|\varpi|, \verb|\varrho|, \verb|\varsigma|, \verb|\varphi|~的表述。
+ \item 第2.0版\quad 2021-12-11\quad 增加了希伯来字母的内容,并补充了个别希腊字母的读音。
+ \item 第1.0版\quad 2021-11-29\quad 完成文档初稿。
+\end{itemize}
+
+\end{document}
diff --git a/macros/latex/contrib/codebox/codebox-doc-en.pdf b/macros/latex/contrib/codebox/codebox-doc-en.pdf
index 50fca38b0a..be0b515540 100644
--- a/macros/latex/contrib/codebox/codebox-doc-en.pdf
+++ b/macros/latex/contrib/codebox/codebox-doc-en.pdf
Binary files differ
diff --git a/macros/latex/contrib/codebox/codebox.dtx b/macros/latex/contrib/codebox/codebox.dtx
index fb9168b133..e924279e3b 100644
--- a/macros/latex/contrib/codebox/codebox.dtx
+++ b/macros/latex/contrib/codebox/codebox.dtx
@@ -148,7 +148,7 @@ Copyright and Licence
%</internal>
%<package>\NeedsTeXFormat{LaTeX2e}[2020/10/01]
%<package>\RequirePackage{expl3}
-%<+package>\GetIdInfo$Id: codebox.dtx 1.0.0 2021-12-26 08:00:00 +0800 Nan Geng <nangeng@nwafu.edu.cn> $
+%<+package>\GetIdInfo$Id: codebox.dtx 1.0.1 2021-12-27 08:00:00 +0800 Nan Geng <nangeng@nwafu.edu.cn> $
%<package> {Code Box with tcolorbox and minted/listings.}
%<package>\ProvidesExplPackage{\ExplFileName}
%<package> {\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
@@ -159,7 +159,6 @@ Copyright and Licence
\usepackage{xcolor}
\usepackage{xcolor-material}
\usepackage{codebox}
-\renewcommand{\thecodecounter}{\thesection.\arabic{codecounter}}
\renewcommand*\marg[1]{\{\meta{#1}\}}
\renewcommand*\oarg[1]{[\meta{#1}]}
\renewcommand*\parg[1]{(\meta{#1})}
@@ -181,7 +180,7 @@ Copyright and Licence
%
% \changes{v1.0.0}{2021/12/25}{开始编写模板}
%
-% \CheckSum{309}
+% \CheckSum{286}
% \GetFileId{codebox.sty}
%
% \CharacterTable
@@ -577,23 +576,7 @@ Copyright and Licence
\RequirePackage { xtemplate, l3keys2e, xparse }
% \end{macrocode}
%
-% 检查\LaTeX3 宏包版本
-%
-% \begin{macrocode}
-% \clist_map_inline:nn { xtemplate, l3keys2e }
-% {
-% \@ifpackagelater {#1} { 2020/07/17 }
-% { } { \msg_error:nnn { codebox } { l3-too-old } {#1} }
-% }
-% \msg_new:nnn { codebox } { l3-too-old }
-% {
-% Package~ "#1"~ is~ too~ old. \\\\
-% Please~ update~ an~ up-to-date~ version~ of~ the~ bundles \\
-% "l3kernel"~ and~ "l3packages"~ using~ your~ TeX~ package \\
-% manager~ or~ from~ CTAN.
-% }
-%
-% \end{macrocode}
+% \changes{v1.0.1}{2021/12/26}{删除原\LaTeX3 版本检测代码}
%
% \subsection{载入其它宏包}
%
@@ -636,6 +619,8 @@ Copyright and Licence
\ExplSyntaxOn
% \end{macrocode}
%
+% \changes{v1.0.1}{2021/12/26}{minted2.6发布,删除原补丁代码}
+%
% 载入\pkg{tcolorbox}和\pkg{tikz}附加库
%
% \begin{macrocode}
@@ -728,11 +713,6 @@ Copyright and Licence
colbacktitle=cvgray,
fonttitle=\ttfamily,
coltitle=black,
- % overlay~broken = {
- % \begin{tcbclipinterior}
- % \fill[cvblue] (frame.south~west) rectangle ([xshift=5.0mm]frame.north~west);
- % \end{tcbclipinterior}
- % },
underlay~boxed~title = {
\begin{tcbclipinterior}
\fill[cvblue] (frame.south~west) rectangle ([xshift=5.0mm,yshift=0mm]frame.north~west);
@@ -865,7 +845,9 @@ Copyright and Licence
% \subsection{选项设置用户接口}
%
% \begin{macro}{\codeset}
+%
% 选项设置用户接口。
+%
% \begin{macrocode}
\NewDocumentCommand \codeset { m }
{ \keys_set:nn { codebox } {#1} }
@@ -874,16 +856,8 @@ Copyright and Licence
%
% \subsection{内部函数}
%
-% \begin{macrocode}
-% \bool_if:NTF \l_@@_minted_bool
-% {
-% \tcbuselibrary{minted}
-% }{
-% \tcbuselibrary{listings}
-% }
-% \end{macrocode}
-%
% \begin{macro}{\@@_set_counter_parent:}
+%
% 设置代码编号计数器的父计数器。
%
% \begin{macrocode}
@@ -893,12 +867,14 @@ Copyright and Licence
{
\newcounter{codecounter}[chapter]%
}{
- \newcounter{codecounter}[section]%
+ \newcounter{codecounter}%[section]%
}
}
% \end{macrocode}
% \end{macro}
%
+% \changes{v1.0.1}{2021/12/26}{调整minted style选项为参数实现}
+%
% \begin{macro}{\@@_code_engine_tcbset:}
% 设置代码盒子minted宏包参数。
%
@@ -911,7 +887,6 @@ Copyright and Licence
listing~engine=minted,%
minted~style=#1,
minted~options={%
- % highlightlines={\ifodd\value{lstnumber}\value{lstnumber}\fi},
autogobble,
breaklines,%
fontsize=\tl_use:N \l_@@_code_fontsize_tl,%
@@ -974,6 +949,8 @@ Copyright and Licence
% \end{macrocode}
% \end{macro}
%
+% \changes{v1.0.1}{2021/12/27}{修订代码盒子前多一个逗号的问题}
+%
% \subsection{不计数代码盒子用户接口}
%
% 定义不带底线注释的代码盒子环境\env{codebox}
@@ -984,7 +961,7 @@ Copyright and Licence
\bool_set_false:N \l_@@_comment_bool
\group_begin:
\IfNoValueF{#1}{ \keys_set:nn { codebox } { #1 } }
- \@@_code_engine_tcbset:V \l_@@_code_style_tl,
+ \@@_code_engine_tcbset:V \l_@@_code_style_tl
\@@_comment_tcbset:
\tcbset{lang, title={#2} }%
\tcblisting{}
@@ -1002,7 +979,7 @@ Copyright and Licence
\bool_set_false:N \l_@@_comment_bool
\group_begin:
\IfNoValueF{#1}{ \keys_set:nn { codebox } { #1 } }
- \@@_code_engine_tcbset:V \l_@@_code_style_tl,
+ \@@_code_engine_tcbset:V \l_@@_code_style_tl
\@@_comment_tcbset:
\tcbset{lang, title={#2} }%
\tcblisting{}
@@ -1026,7 +1003,7 @@ Copyright and Licence
\group_begin:
\IfNoValueF{#2}{ \keys_set:nn { codebox } { #2 } }
- \@@_code_engine_tcbset:V \l_@@_code_style_tl,
+ \@@_code_engine_tcbset:V \l_@@_code_style_tl
\@@_comment_tcbset:
\tcbset{
lang,
@@ -1058,7 +1035,7 @@ Copyright and Licence
\bool_set_false:N \l_@@_comment_bool
\group_begin:
\IfNoValueF{#1}{ \keys_set:nn { codebox } { #1 } }
- \@@_code_engine_tcbset:V \l_@@_code_style_tl,
+ \@@_code_engine_tcbset:V \l_@@_code_style_tl
\@@_comment_tcbset:
\tcbset{
cv,
@@ -1087,7 +1064,7 @@ Copyright and Licence
\bool_set_true:N \l_@@_comment_bool
\group_begin:
\IfNoValueF{#1}{ \keys_set:nn { codebox } { #1 } }
- \@@_code_engine_tcbset:V \l_@@_code_style_tl,
+ \@@_code_engine_tcbset:V \l_@@_code_style_tl
\@@_comment_tcbset:
\tcbset{
cv,
@@ -1126,7 +1103,7 @@ Copyright and Licence
\group_begin:
\IfNoValueF{#2}{ \keys_set:nn { codebox } { #2 } }
- \@@_code_engine_tcbset:V \l_@@_code_style_tl,
+ \@@_code_engine_tcbset:V \l_@@_code_style_tl
\@@_comment_tcbset:
\tcbset{
cv,
diff --git a/macros/latex/contrib/codebox/codebox.pdf b/macros/latex/contrib/codebox/codebox.pdf
index 05a15aa348..4e1e51d585 100644
--- a/macros/latex/contrib/codebox/codebox.pdf
+++ b/macros/latex/contrib/codebox/codebox.pdf
Binary files differ
diff --git a/macros/latex/contrib/codebox/hellojava.java b/macros/latex/contrib/codebox/hellojava.java
index 1cf8d2e9bc..1cf8d2e9bc 100755..100644
--- a/macros/latex/contrib/codebox/hellojava.java
+++ b/macros/latex/contrib/codebox/hellojava.java
diff --git a/macros/latex/contrib/diffcoeff/README.txt b/macros/latex/contrib/diffcoeff/README.txt
index 63ec1ff6b6..90fd470143 100644
--- a/macros/latex/contrib/diffcoeff/README.txt
+++ b/macros/latex/contrib/diffcoeff/README.txt
@@ -1,29 +1,32 @@
diffcoeff: a package to ease the writing of a variety
-of differential coefficients (derivatives)
+of differential coefficients
-Andrew Parsloe (ajparsloe@gmail.com) 28 December 2020
+Andrew Parsloe (ajparsloe@gmail.com)
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either
-version 1.3 of this license or (at your option) any later
+version 1.3c of this license or (at your option) any later
version. The latest version of this license is in
http://www.latex-project.org/lppl.txt
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-This is version 3.2 of diffcoeff.sty, and associated files,
-and requires the LaTeX3 bundles l3kernel and l3packages.
-
-Version 3.2 corrects a bug when an ordinary derivative is in
-the differentiand of a partial derivative. Possible negative
-spacing before a differential is also now available.
+This is version 4.0 of diffcoeff.sty, and associated files,
+and requires the LaTeX3 bundles l3kernel and l3packages. The
+package eases the consistent writing of ordinary, partial
+and other derivatives of arbitrary order. Version 4.0 adds a
+package option enabling a space to be inserted by default
+before the differentiand, prevents the inappropriate forming
+of the ligature df when f is the differentiand, adds a diff-
+erential command for \partial, and no longer accepts a brace-
+delimited final optional argument (a relic from v.1).
Manifest
%%%%%%%%
README.txt this document
diffcoeff.sty LaTeX .sty file
+diffcoeff-doc.def definition file of variant forms
+ to be placed with the .sty file
diffcoeff.pdf documentation
diffcoeff.tex LaTeX source of documentation
-diffcoeff-doc.def definition file to be placed
- in same directory as the .pdf
- and .tex files \ No newline at end of file
+
diff --git a/macros/latex/contrib/diffcoeff/diffcoeff-doc.def b/macros/latex/contrib/diffcoeff/diffcoeff-doc.def
index 8b6b415acf..884d41760b 100644
--- a/macros/latex/contrib/diffcoeff/diffcoeff-doc.def
+++ b/macros/latex/contrib/diffcoeff/diffcoeff-doc.def
@@ -18,15 +18,13 @@
\diffdef { up }
{
op-symbol = \mathrm{d},
- op-order-sep = 0 mu ,
- /-op-order-sep = 0 mu
+ op-order-sep = 0 mu
}
\diffdef { Up }
{
op-symbol = \mathrm{D},
- op-order-sep = 0 mu ,
- /-op-order-sep = 0 mu
+ op-order-sep = 0 mu
}
% wrap long vars: (d longvar)
@@ -80,7 +78,6 @@
{
op-symbol = \Delta ,
op-order-sep = 0 mu ,
- /-op-order-sep = 0 mu ,
left-delim = \left ( ,
right-delim = \right ),
subscr-nudge = -6 mu
diff --git a/macros/latex/contrib/diffcoeff/diffcoeff.pdf b/macros/latex/contrib/diffcoeff/diffcoeff.pdf
index f609d1399a..76f4954dd3 100644
--- a/macros/latex/contrib/diffcoeff/diffcoeff.pdf
+++ b/macros/latex/contrib/diffcoeff/diffcoeff.pdf
@@ -10,7 +10,7 @@ endobj
<< /S /GoTo /D (subsection.1.1) >>
endobj
8 0 obj
-(\376\377\0001\000.\0001\000\040\000V\000e\000r\000s\000i\000o\000n\000\040\000c\000o\000m\000p\000a\000r\000i\000s\000o\000n)
+(\376\377\0001\000.\0001\000\040\000P\000a\000c\000k\000a\000g\000e\000\040\000o\000p\000t\000i\000o\000n\000s)
endobj
9 0 obj
<< /S /GoTo /D (section.2) >>
@@ -28,385 +28,438 @@ endobj
<< /S /GoTo /D (subsection.3.1) >>
endobj
20 0 obj
-(\376\377\0003\000.\0001\000\040\000O\000r\000d\000e\000r\000\040\000o\000f\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000t\000i\000o\000n)
+(\376\377\0003\000.\0001\000\040\000S\000p\000a\000c\000i\000n\000g\000\040\000b\000e\000f\000o\000r\000e\000\040\000t\000h\000e\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000n\000d)
endobj
21 0 obj
-<< /S /GoTo /D (subsection.3.2) >>
+<< /S /GoTo /D (subsubsection.3.1.1) >>
endobj
24 0 obj
-(\376\377\0003\000.\0002\000\040\000M\000u\000l\000t\000i\000-\000c\000h\000a\000r\000a\000c\000t\000e\000r\000\040\000v\000a\000r\000i\000a\000b\000l\000e\000s\000\040\000o\000f\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000t\000i\000o\000n)
+(\376\377\0003\000.\0001\000.\0001\000\040\000L\000i\000g\000a\000t\000u\000r\000e\000s\000:\000\040)
endobj
25 0 obj
-<< /S /GoTo /D (subsubsection.3.2.1) >>
+<< /S /GoTo /D (subsubsection.3.1.2) >>
endobj
28 0 obj
-(\376\377\0003\000.\0002\000.\0001\000\040\000M\000i\000n\000u\000t\000i\000a\000e\000\040\000o\000f\000\040\000s\000p\000a\000c\000i\000n\000g)
+(\376\377\0003\000.\0001\000.\0002\000\040\000S\000p\000a\000c\000i\000n\000g\000\040\000c\000o\000m\000m\000a\000n\000d\000s)
endobj
29 0 obj
-<< /S /GoTo /D (subsection.3.3) >>
+<< /S /GoTo /D (subsection.3.2) >>
endobj
32 0 obj
-(\376\377\0003\000.\0003\000\040\000A\000p\000p\000e\000n\000d\000i\000n\000g\000\040\000t\000h\000e\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000n\000d\000:\000\040\000\134\000d\000i\000f\000f\000*)
+(\376\377\0003\000.\0002\000\040\000A\000p\000p\000e\000n\000d\000i\000n\000g\000\040\000t\000h\000e\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000n\000d\000:\000\040\000\134\000d\000i\000f\000f\000*)
endobj
33 0 obj
-<< /S /GoTo /D (subsection.3.4) >>
+<< /S /GoTo /D (subsection.3.3) >>
endobj
36 0 obj
-(\376\377\0003\000.\0004\000\040\000P\000o\000i\000n\000t\000\040\000o\000f\000\040\000e\000v\000a\000l\000u\000a\000t\000i\000o\000n)
+(\376\377\0003\000.\0003\000\040\000P\000o\000i\000n\000t\000\040\000o\000f\000\040\000e\000v\000a\000l\000u\000a\000t\000i\000o\000n)
endobj
37 0 obj
-<< /S /GoTo /D (subsubsection.3.4.1) >>
+<< /S /GoTo /D (subsubsection.3.3.1) >>
endobj
40 0 obj
-(\376\377\0003\000.\0004\000.\0001\000\040\000S\000u\000p\000e\000r\000s\000c\000r\000i\000p\000t\000s)
+(\376\377\0003\000.\0003\000.\0001\000\040\000S\000u\000p\000e\000r\000s\000c\000r\000i\000p\000t\000s)
endobj
41 0 obj
-<< /S /GoTo /D (section.4) >>
+<< /S /GoTo /D (subsection.3.4) >>
endobj
44 0 obj
-(\376\377\0004\000\040\000P\000a\000r\000t\000i\000a\000l\000\040\000d\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s)
+(\376\377\0003\000.\0004\000\040\000O\000r\000d\000e\000r\000\040\000o\000f\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000t\000i\000o\000n)
endobj
45 0 obj
-<< /S /GoTo /D (subsection.4.1) >>
+<< /S /GoTo /D (subsection.3.5) >>
endobj
48 0 obj
-(\376\377\0004\000.\0001\000\040\000V\000a\000r\000i\000a\000b\000l\000e\000s\000\040\000h\000e\000l\000d\000\040\000c\000o\000n\000s\000t\000a\000n\000t)
+(\376\377\0003\000.\0005\000\040\000M\000u\000l\000t\000i\000-\000c\000h\000a\000r\000a\000c\000t\000e\000r\000\040\000v\000a\000r\000i\000a\000b\000l\000e\000s\000\040\000o\000f\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000t\000i\000o\000n)
endobj
49 0 obj
-<< /S /GoTo /D (subsubsection.4.1.1) >>
+<< /S /GoTo /D (section.4) >>
endobj
52 0 obj
-(\376\377\0004\000.\0001\000.\0001\000\040\000T\000e\000x\000t\000-\000s\000t\000y\000l\000e\000\040\000d\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s)
+(\376\377\0004\000\040\000P\000a\000r\000t\000i\000a\000l\000\040\000d\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s)
endobj
53 0 obj
-<< /S /GoTo /D (subsection.4.2) >>
+<< /S /GoTo /D (subsection.4.1) >>
endobj
56 0 obj
-(\376\377\0004\000.\0002\000\040\000A\000p\000p\000e\000n\000d\000i\000n\000g\000\040\000t\000h\000e\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000n\000d)
+(\376\377\0004\000.\0001\000\040\000V\000a\000r\000i\000a\000b\000l\000e\000s\000\040\000h\000e\000l\000d\000\040\000c\000o\000n\000s\000t\000a\000n\000t)
endobj
57 0 obj
-<< /S /GoTo /D (subsection.4.3) >>
+<< /S /GoTo /D (subsubsection.4.1.1) >>
endobj
60 0 obj
-(\376\377\0004\000.\0003\000\040\000I\000t\000e\000r\000a\000t\000e\000d\000\040\000d\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s)
+(\376\377\0004\000.\0001\000.\0001\000\040\000T\000e\000x\000t\000-\000s\000t\000y\000l\000e\000\040\000d\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s)
endobj
61 0 obj
-<< /S /GoTo /D (subsection.4.4) >>
+<< /S /GoTo /D (subsection.4.2) >>
endobj
64 0 obj
-(\376\377\0004\000.\0004\000\040\000M\000i\000x\000e\000d\000\040\000p\000a\000r\000t\000i\000a\000l\000\040\000d\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s)
+(\376\377\0004\000.\0002\000\040\000A\000p\000p\000e\000n\000d\000i\000n\000g\000\040\000t\000h\000e\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000n\000d)
endobj
65 0 obj
-<< /S /GoTo /D (subsubsection.4.4.1) >>
+<< /S /GoTo /D (subsection.4.3) >>
endobj
68 0 obj
-(\376\377\0004\000.\0004\000.\0001\000\040\000M\000i\000n\000u\000t\000i\000a\000e\000\040\000o\000f\000\040\000s\000p\000a\000c\000i\000n\000g\000\040\000\050\000a\000g\000a\000i\000n\000\051)
+(\376\377\0004\000.\0003\000\040\000I\000t\000e\000r\000a\000t\000e\000d\000\040\000d\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s)
endobj
69 0 obj
-<< /S /GoTo /D (subsubsection.4.4.2) >>
+<< /S /GoTo /D (subsection.4.4) >>
endobj
72 0 obj
-(\376\377\0004\000.\0004\000.\0002\000\040\000A\000l\000g\000e\000b\000r\000a\000i\000c\000\040\000o\000r\000d\000e\000r\000s\000\040\000o\000f\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000t\000i\000o\000n)
+(\376\377\0004\000.\0004\000\040\000M\000i\000x\000e\000d\000\040\000p\000a\000r\000t\000i\000a\000l\000\040\000d\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s)
endobj
73 0 obj
-<< /S /GoTo /D (subsubsection.4.4.3) >>
+<< /S /GoTo /D (subsubsection.4.4.1) >>
endobj
76 0 obj
-(\376\377\0004\000.\0004\000.\0003\000\040\000E\000r\000r\000o\000r\000\040\000m\000e\000s\000s\000a\000g\000e\000s)
+(\376\377\0004\000.\0004\000.\0001\000\040\000M\000i\000n\000u\000t\000i\000a\000e\000\040\000o\000f\000\040\000s\000p\000a\000c\000i\000n\000g\000\040\000\050\000a\000g\000a\000i\000n\000\051)
endobj
77 0 obj
-<< /S /GoTo /D (subsubsection.4.4.4) >>
+<< /S /GoTo /D (subsubsection.4.4.2) >>
endobj
80 0 obj
-(\376\377\0004\000.\0004\000.\0004\000\040\000T\000h\000e\000\040\000o\000r\000d\000e\000r\000-\000o\000v\000e\000r\000r\000i\000d\000e\000\040\000o\000p\000t\000i\000o\000n)
+(\376\377\0004\000.\0004\000.\0002\000\040\000A\000l\000g\000e\000b\000r\000a\000i\000c\000\040\000o\000r\000d\000e\000r\000s\000\040\000o\000f\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000t\000i\000o\000n)
endobj
81 0 obj
-<< /S /GoTo /D (subsubsection.4.4.5) >>
+<< /S /GoTo /D (subsubsection.4.4.3) >>
endobj
84 0 obj
-(\376\377\0004\000.\0004\000.\0005\000\040\000C\000o\000m\000m\000a\000\040\000l\000i\000s\000t\000\040\000o\000f\000\040\000v\000a\000r\000i\000a\000b\000l\000e\000s\000\040\000o\000f\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000t\000i\000o\000n)
+(\376\377\0004\000.\0004\000.\0003\000\040\000E\000r\000r\000o\000r\000\040\000m\000e\000s\000s\000a\000g\000e\000s)
endobj
85 0 obj
-<< /S /GoTo /D (subsubsection.4.4.6) >>
+<< /S /GoTo /D (subsubsection.4.4.4) >>
endobj
88 0 obj
-(\376\377\0004\000.\0004\000.\0006\000\040\000O\000v\000e\000r\000k\000i\000l\000l\000\040\000t\000e\000r\000r\000i\000t\000o\000r\000y)
+(\376\377\0004\000.\0004\000.\0004\000\040\000T\000h\000e\000\040\000o\000r\000d\000e\000r\000-\000o\000v\000e\000r\000r\000i\000d\000e\000\040\000o\000p\000t\000i\000o\000n)
endobj
89 0 obj
-<< /S /GoTo /D (subsection.4.5) >>
+<< /S /GoTo /D (subsubsection.4.4.5) >>
endobj
92 0 obj
-(\376\377\0004\000.\0005\000\040\000P\000a\000r\000e\000n\000t\000h\000e\000s\000e\000s\000\040\000a\000r\000o\000u\000n\000d\000\040\000m\000u\000l\000t\000i\000-\000c\000h\000a\000r\000a\000c\000t\000e\000r\000\040\000v\000a\000r\000i\000a\000b\000l\000e\000s)
+(\376\377\0004\000.\0004\000.\0005\000\040\000C\000o\000m\000m\000a\000\040\000l\000i\000s\000t\000\040\000o\000f\000\040\000v\000a\000r\000i\000a\000b\000l\000e\000s\000\040\000o\000f\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000t\000i\000o\000n)
endobj
93 0 obj
-<< /S /GoTo /D (subsection.4.6) >>
+<< /S /GoTo /D (subsubsection.4.4.6) >>
endobj
96 0 obj
-(\376\377\0004\000.\0006\000\040\000J\000a\000c\000o\000b\000i\000a\000n\000s)
+(\376\377\0004\000.\0004\000.\0006\000\040\000O\000v\000e\000r\000k\000i\000l\000l\000\040\000t\000e\000r\000r\000i\000t\000o\000r\000y)
endobj
97 0 obj
-<< /S /GoTo /D (section.5) >>
+<< /S /GoTo /D (subsection.4.5) >>
endobj
100 0 obj
-(\376\377\0005\000\040\000C\000h\000a\000n\000g\000i\000n\000g\000\040\000d\000e\000f\000a\000u\000l\000t\000s\000;\000\040\000v\000a\000r\000i\000a\000n\000t\000\040\000f\000o\000r\000m\000s)
+(\376\377\0004\000.\0005\000\040\000P\000a\000r\000e\000n\000t\000h\000e\000s\000e\000s\000\040\000a\000r\000o\000u\000n\000d\000\040\000m\000u\000l\000t\000i\000-\000c\000h\000a\000r\000a\000c\000t\000e\000r\000\040\000v\000a\000r\000i\000a\000b\000l\000e\000s)
endobj
101 0 obj
-<< /S /GoTo /D (subsection.5.1) >>
+<< /S /GoTo /D (subsection.4.6) >>
endobj
104 0 obj
-(\376\377\0005\000.\0001\000\040\000D\000e\000f\000a\000u\000l\000t\000\040\000v\000a\000l\000u\000e\000s\000:\000\040\000o\000r\000d\000i\000n\000a\000r\000y\000\040\000d\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s)
+(\376\377\0004\000.\0006\000\040\000J\000a\000c\000o\000b\000i\000a\000n\000s)
endobj
105 0 obj
-<< /S /GoTo /D (subsection.5.2) >>
+<< /S /GoTo /D (section.5) >>
endobj
108 0 obj
-(\376\377\0005\000.\0002\000\040\000I\000S\000O\000\040\000d\000e\000f\000a\000u\000l\000t\000s)
+(\376\377\0005\000\040\000C\000h\000a\000n\000g\000i\000n\000g\000\040\000d\000e\000f\000a\000u\000l\000t\000s\000;\000\040\000v\000a\000r\000i\000a\000n\000t\000\040\000f\000o\000r\000m\000s)
endobj
109 0 obj
-<< /S /GoTo /D (subsection.5.3) >>
+<< /S /GoTo /D (subsection.5.1) >>
endobj
112 0 obj
-(\376\377\0005\000.\0003\000\040\000P\000a\000r\000t\000i\000a\000l\000\040\000d\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s)
+(\376\377\0005\000.\0001\000\040\000D\000e\000f\000a\000u\000l\000t\000\040\000v\000a\000l\000u\000e\000s\000:\000\040\000o\000r\000d\000i\000n\000a\000r\000y\000\040\000d\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s)
endobj
113 0 obj
-<< /S /GoTo /D (subsection.5.4) >>
+<< /S /GoTo /D (subsection.5.2) >>
endobj
116 0 obj
-(\376\377\0005\000.\0004\000\040\000S\000e\000t\000t\000i\000n\000g\000\040\000y\000o\000u\000r\000\040\000o\000w\000n\000\040\000d\000e\000f\000a\000u\000l\000t\000s\000:\000\040\000\134\000d\000i\000f\000f\000d\000e\000f)
+(\376\377\0005\000.\0002\000\040\000I\000S\000O\000\040\000d\000e\000f\000a\000u\000l\000t\000s)
endobj
117 0 obj
-<< /S /GoTo /D (subsection.5.5) >>
+<< /S /GoTo /D (subsection.5.3) >>
endobj
120 0 obj
-(\376\377\0005\000.\0005\000\040\000V\000a\000r\000i\000a\000n\000t\000\040\000f\000o\000r\000m\000s)
+(\376\377\0005\000.\0003\000\040\000P\000a\000r\000t\000i\000a\000l\000\040\000d\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s)
endobj
121 0 obj
-<< /S /GoTo /D (subsubsection.5.5.1) >>
+<< /S /GoTo /D (subsection.5.4) >>
endobj
124 0 obj
-(\376\377\0005\000.\0005\000.\0001\000\040\000T\000e\000x\000t\000-\000s\000t\000y\000l\000e\000\040\000a\000n\000d\000\040\000s\000c\000r\000i\000p\000t\000-\000s\000t\000y\000l\000e\000\040\000d\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s)
+(\376\377\0005\000.\0004\000\040\000S\000e\000t\000t\000i\000n\000g\000\040\000y\000o\000u\000r\000\040\000o\000w\000n\000\040\000d\000e\000f\000a\000u\000l\000t\000s\000:\000\040\000\134\000d\000i\000f\000f\000d\000e\000f)
endobj
125 0 obj
-<< /S /GoTo /D (subsubsection.5.5.2) >>
+<< /S /GoTo /D (subsubsection.5.4.1) >>
endobj
128 0 obj
-(\376\377\0005\000.\0005\000.\0002\000\040\000D\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s\000\040\000f\000r\000o\000m\000\040\000D\000,\000\040\000\134\000d\000e\000l\000t\000a\000,\000\040\000\134\000D\000e\000l\000t\000a)
+(\376\377\0005\000.\0004\000.\0001\000\040\000S\000p\000a\000c\000e\000\040\000b\000e\000f\000o\000r\000e\000\040\000t\000h\000e\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000n\000d)
endobj
129 0 obj
-<< /S /GoTo /D (subsection.5.6) >>
+<< /S /GoTo /D (subsection.5.5) >>
endobj
132 0 obj
-(\376\377\0005\000.\0006\000\040\000T\000h\000e\000\040\000.\000d\000e\000f\000\040\000f\000i\000l\000e)
+(\376\377\0005\000.\0005\000\040\000V\000a\000r\000i\000a\000n\000t\000\040\000f\000o\000r\000m\000s)
endobj
133 0 obj
-<< /S /GoTo /D (subsubsection.5.6.1) >>
+<< /S /GoTo /D (subsubsection.5.5.1) >>
endobj
136 0 obj
-(\376\377\0005\000.\0006\000.\0001\000\040\000S\000t\000r\000u\000c\000t\000u\000r\000e\000\040\000o\000f\000\040\000t\000h\000e\000\040\000.\000d\000e\000f\000\040\000f\000i\000l\000e)
+(\376\377\0005\000.\0005\000.\0001\000\040\000T\000e\000x\000t\000-\000s\000t\000y\000l\000e\000\040\000a\000n\000d\000\040\000s\000c\000r\000i\000p\000t\000-\000s\000t\000y\000l\000e\000\040\000d\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s)
endobj
137 0 obj
-<< /S /GoTo /D (subsubsection.5.6.2) >>
+<< /S /GoTo /D (subsubsection.5.5.2) >>
endobj
140 0 obj
-(\376\377\0005\000.\0006\000.\0002\000\040\000d\000i\000f\000f\000c\000o\000e\000f\000f\000.\000d\000e\000f)
+(\376\377\0005\000.\0005\000.\0002\000\040\000D\000e\000r\000i\000v\000a\000t\000i\000v\000e\000s\000\040\000f\000r\000o\000m\000\040\000D\000,\000\040\000\134\000d\000e\000l\000t\000a\000,\000\040\000\134\000D\000e\000l\000t\000a)
endobj
141 0 obj
-<< /S /GoTo /D (section.6) >>
+<< /S /GoTo /D (subsection.5.6) >>
endobj
144 0 obj
-(\376\377\0006\000\040\000D\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000l\000s\000\040\000i\000n\000\040\000i\000n\000t\000e\000g\000r\000a\000l\000s\000,\000\040\000e\000t\000c\000.)
+(\376\377\0005\000.\0006\000\040\000T\000h\000e\000\040\000.\000d\000e\000f\000\040\000f\000i\000l\000e)
endobj
145 0 obj
-<< /S /GoTo /D (subsection.6.1) >>
+<< /S /GoTo /D (subsubsection.5.6.1) >>
endobj
148 0 obj
-(\376\377\0006\000.\0001\000\040\000O\000p\000t\000i\000o\000n\000s)
+(\376\377\0005\000.\0006\000.\0001\000\040\000S\000t\000r\000u\000c\000t\000u\000r\000e\000\040\000o\000f\000\040\000t\000h\000e\000\040\000.\000d\000e\000f\000\040\000f\000i\000l\000e)
endobj
149 0 obj
-<< /S /GoTo /D (subsubsection.6.1.1) >>
+<< /S /GoTo /D (subsubsection.5.6.2) >>
endobj
152 0 obj
-(\376\377\0006\000.\0001\000.\0001\000\040\000S\000p\000a\000c\000i\000n\000g)
+(\376\377\0005\000.\0006\000.\0002\000\040\000d\000i\000f\000f\000c\000o\000e\000f\000f\000.\000d\000e\000f)
endobj
153 0 obj
-<< /S /GoTo /D (section.7) >>
+<< /S /GoTo /D (section.6) >>
endobj
156 0 obj
-(\376\377\0007\000\040\000R\000a\000t\000i\000o\000n\000a\000l\000e)
+(\376\377\0006\000\040\000D\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000l\000s\000\040\000i\000n\000\040\000i\000n\000t\000e\000g\000r\000a\000l\000s\000,\000\040\000e\000t\000c\000.)
endobj
157 0 obj
-<< /S /GoTo /D (subsection.7.1) >>
+<< /S /GoTo /D (subsection.6.1) >>
endobj
160 0 obj
-(\376\377\0007\000.\0001\000\040\000d\000i\000f\000f\000c\000o\000e\000f\000f\000.\000s\000t\000y)
+(\376\377\0006\000.\0001\000\040\000O\000p\000t\000i\000o\000n\000s)
endobj
161 0 obj
-<< /S /GoTo /D (section.8) >>
+<< /S /GoTo /D (subsubsection.6.1.1) >>
endobj
164 0 obj
-(\376\377\0008\000\040\000C\000o\000m\000m\000a\000n\000d\000s)
+(\376\377\0006\000.\0001\000.\0001\000\040\000P\000a\000r\000t\000i\000a\000l\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000l)
endobj
165 0 obj
-<< /S /GoTo /D [166 0 R /Fit] >>
+<< /S /GoTo /D (subsubsection.6.1.2) >>
endobj
-179 0 obj
+168 0 obj
+(\376\377\0006\000.\0001\000.\0002\000\040\000S\000p\000a\000c\000i\000n\000g)
+endobj
+169 0 obj
+<< /S /GoTo /D (section.7) >>
+endobj
+172 0 obj
+(\376\377\0007\000\040\000R\000a\000t\000i\000o\000n\000a\000l\000e)
+endobj
+173 0 obj
+<< /S /GoTo /D (subsection.7.1) >>
+endobj
+176 0 obj
+(\376\377\0007\000.\0001\000\040\000d\000i\000f\000f\000c\000o\000e\000f\000f\000.\000s\000t\000y)
+endobj
+177 0 obj
+<< /S /GoTo /D (section.8) >>
+endobj
+180 0 obj
+(\376\377\0008\000\040\000V\000e\000r\000s\000i\000o\000n\000\040\000c\000o\000m\000p\000a\000r\000i\000s\000o\000n)
+endobj
+181 0 obj
+<< /S /GoTo /D (section.9) >>
+endobj
+184 0 obj
+(\376\377\0009\000\040\000C\000o\000m\000m\000a\000n\000d\000s)
+endobj
+185 0 obj
+<< /S /GoTo /D [186 0 R /Fit] >>
+endobj
+201 0 obj
<<
-/Length 1751
+/Length 1617
/Filter /FlateDecode
>>
stream
-xXے}߯[Ԋƍ 'T\r\CBƔ4&4'] @S"G"xfG_<Ydj]ldiY&PmnWn8Ol<QD[%B|lP? l8tBYk#lݒX'׿IPVe˽ģ+{ýiXYH7]34=9xBk׹FeʸHZ-ȸuUC6zo'Ț˶ n޻6ˮq)y:IZ~tdt*@Jbcou |K1]RYX0ϓڐDj$G0"
-Ml6?vus,MncoTN
-jPS,{ׇ{Mowx μ\M>nL<2eS|
-Y Xjx-\Qw (B\ /ΤGڵl&FMj@+%x2%x\4o;΅yeN|߮q_+IVNVF,Bp1$u0*)T`0r{`+ Q/!\}*pO3.oeZ#4^ ʞ-ʞtsAۓЦfql1z|LTFx.GϛT^rP4|kJk$xbkvѵkIG\.keh Z ~M]nJ_QˉpXnE)e蘴B}gzRi_["O .4l8(X4:x<j .IhjԳv`bZR%0':7tZSlk:'3<AW/Vߙ<]uРQI;ml 3R \fq晬N| }f^Mԯ=خ'NXX/}0ESgykVh`}snf[,%}OgMM4yc
-4O3qh{\ԛ=1[ :0:9ܟnxp?)_T+z,!Ԇµ'-YgGbNe^$p &-sjr\f#,edP*4
-5SU< WOC{߯hcwLRA`Ic6`SF{
+xX[o6~ϯbyاe:tha@YmlHrCRb+K k'|jhc~yK gJFuĵ"2fãe}j.vv^kn/NepF |pVp x/j" ɢdyJ?5#7>/\_mb2(E43 7_¶Y4 CY\# r-BBJ²6`.,mW^:^sٔg T(oŧ<
+,c?6nͫ-;"Ef/mazx 7i)wEFBuum^we(h` WUH$c>4x!0&ܦ5]@Ƴ1&$1Yd:C%p(*=]ޔx.(hFJ̶"NDAVoͫ"P~mаs$EAר@os` \:aa4k
+h+t`Y\`š{VH|&#s#oRpTCLi5B{3
+q kڦ%`QHC;W! I˖V ^N/1Lf*D@xψR5ʇ}n ٷ
+:LJCH| VnJs!|ʹeC(%2g.R=q
+ 2~[m3B$,@$0X<Zӧ }$aC^]4ñtL˦q_I*A(=? kɷT;v 0UU,30
+h|*qKrp6`saS?JK 5S?DqҾZ^AoM
endstream
endobj
-166 0 obj
+186 0 obj
<<
/Type /Page
-/Contents 179 0 R
-/Resources 178 0 R
+/Contents 201 0 R
+/Resources 200 0 R
/MediaBox [0 0 612 792]
-/Parent 196 0 R
-/Annots [ 167 0 R 168 0 R 169 0 R 170 0 R 171 0 R 172 0 R 173 0 R 174 0 R 175 0 R 176 0 R ]
+/Parent 217 0 R
+/Annots [ 187 0 R 188 0 R 189 0 R 190 0 R 191 0 R 192 0 R 193 0 R 194 0 R 195 0 R 196 0 R 197 0 R 198 0 R ]
>>
endobj
-167 0 obj
+187 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [132.772 245.778 212.874 254.735]
+/Rect [132.772 277.449 212.874 286.406]
/A << /S /GoTo /D (section.1) >>
>>
endobj
-168 0 obj
+188 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [147.716 231.886 257.471 242.679]
+/Rect [147.716 263.556 242.832 274.349]
/A << /S /GoTo /D (subsection.1.1) >>
>>
endobj
-169 0 obj
+189 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [132.772 209.968 312.836 220.862]
+/Rect [132.772 241.639 312.836 252.533]
/A << /S /GoTo /D (section.2) >>
>>
endobj
-170 0 obj
+190 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [132.772 188.05 256.552 198.944]
+/Rect [132.772 219.721 256.552 230.615]
/A << /S /GoTo /D (section.3) >>
>>
endobj
-171 0 obj
+191 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [147.716 178.032 273.716 186.888]
+/Rect [147.716 207.766 311.601 218.558]
/A << /S /GoTo /D (subsection.3.1) >>
>>
endobj
-172 0 obj
+192 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [147.716 166.077 357.098 174.933]
-/A << /S /GoTo /D (subsection.3.2) >>
+/Rect [170.63 195.811 252.324 206.603]
+/A << /S /GoTo /D (subsubsection.3.1.1) >>
>>
endobj
-173 0 obj
+193 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [170.63 152.185 290.071 162.978]
-/A << /S /GoTo /D (subsubsection.3.2.1) >>
+/Rect [170.63 183.855 287.58 194.648]
+/A << /S /GoTo /D (subsubsection.3.1.2) >>
>>
endobj
-174 0 obj
+194 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [147.716 140.23 334.1 151.078]
+/Rect [147.716 171.9 334.1 182.748]
+/A << /S /GoTo /D (subsection.3.2) >>
+>>
+endobj
+195 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [147.716 161.882 255.23 170.738]
/A << /S /GoTo /D (subsection.3.3) >>
>>
endobj
-175 0 obj
+196 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [170.63 147.99 258.08 158.783]
+/A << /S /GoTo /D (subsubsection.3.3.1) >>
+>>
+endobj
+197 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [147.716 130.212 255.23 139.067]
+/Rect [147.716 137.972 273.716 146.827]
/A << /S /GoTo /D (subsection.3.4) >>
>>
endobj
-176 0 obj
+198 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [170.63 116.319 258.08 127.112]
-/A << /S /GoTo /D (subsubsection.3.4.1) >>
+/Rect [147.716 126.017 357.098 134.872]
+/A << /S /GoTo /D (subsection.3.5) >>
>>
endobj
-180 0 obj
+202 0 obj
<<
-/D [166 0 R /XYZ 132.768 705.06 null]
+/D [186 0 R /XYZ 132.768 705.06 null]
>>
endobj
-181 0 obj
+203 0 obj
<<
-/D [166 0 R /XYZ 133.768 667.198 null]
+/D [186 0 R /XYZ 133.768 667.198 null]
>>
endobj
-191 0 obj
+212 0 obj
<<
-/D [166 0 R /XYZ 133.768 286.625 null]
+/D [186 0 R /XYZ 133.768 318.296 null]
>>
endobj
-178 0 obj
+200 0 obj
<<
-/Font << /F28 182 0 R /F27 183 0 R /F48 184 0 R /F61 185 0 R /F62 186 0 R /F63 187 0 R /F66 188 0 R /F64 189 0 R /F76 190 0 R /F78 192 0 R /F79 193 0 R /F26 194 0 R /F86 195 0 R >>
+/Font << /F30 204 0 R /F29 205 0 R /F50 206 0 R /F63 207 0 R /F64 208 0 R /F65 209 0 R /F68 210 0 R /F66 211 0 R /F79 213 0 R /F80 214 0 R /F28 215 0 R /F87 216 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-229 0 obj
+253 0 obj
<<
-/Length 1695
+/Length 1848
/Filter /FlateDecode
>>
stream
-xZo6~_GX7=uM[X v(Gma"-ےVN{}hI!}8q$W Ɓnɯ'^$HP".I%"sFQBxaDI:KQD 'd_Gi Wxџ0inV][ %|6£DŽ`deDJ7EUňڀch8>K^BocG 3^XmU.*NF8lǹs<p?J0LՋ|Y
-O™Q/U$QĖJMTplbL6Y|("Pqp񲼹Iy*g8\ڐ;%O*(Hu^Xwץ.Ʊ8x 6|O!}`]6.,gVړfjEw&Y쫋΢]&Ca1UI:M ]:./AlП=s&r ~n7Zv0a]*-fNy44~?Y^¶{gZS, ۫m|X|,THԉҟ㞷 OkmsROSSkIvŐ;cH7s>ŦӗG wm}u&w _FQX梋vgfԉEɿ`&t
-aV'D1BGO!aꆷ=w hlABqH[5SM6A)/R^>9y6 ;GqS@c:S
-ɕLc7 1bZ2qdu \SSfD@si1[X;PCa.>azrz24EfK3\.?-<VZBC;([4Ζ &ZoVq`+<i7YַFSS
+xZrH}W aC)'v+ĕڪdɔ1h=̀Ȓcɋ5\<=OyK/EK6>9kyqs̽Ӆ g"Ąyŧ 0#Ot%, ٷ~R/<Tw݀ޗ
+aΩ^V
+pfi&\p'ub^]uM<rTpnnyy
+u4g lnf0Ebl<)Vy4"0Էi/xIaھ(~ۉ.>;jVs0mAV$@wUX'lYZ#45!^J3lg &w-r;nmIuܘS]iDUEH@AbcC1Aο"Bl٘ր'#耓nU<`O9U{6 6Uzz z|{IIʙ 'CIا
+I(% #TR#Z,-Ac~P
+eZjxtlz>$ #s]ۍx!&;`m^3QG/Q!ppOqehԒ[dr2$,o|l8`QGh񝟏o~$D<Bx0gF 7*U?bnQ@rYX5qD~f]AќVėH"6A(fS AWo!0!%Y
+H"]V~(lLgȿY]DtYUN<)k3A#SDP0vĽ0j"6$ԧSV3m:*c2sl]bL\(]|jb03{Nb܀-qً9m1fvӞV8tI
+SD7#54W4_0`b nXxe6a5t'useڋ53&Iw{``BDv)DGs;Mz,{a
endstream
endobj
-228 0 obj
+252 0 obj
<<
/Type /Page
-/Contents 229 0 R
-/Resources 227 0 R
+/Contents 253 0 R
+/Resources 251 0 R
/MediaBox [0 0 612 792]
-/Parent 196 0 R
-/Annots [ 177 0 R 197 0 R 198 0 R 199 0 R 200 0 R 201 0 R 202 0 R 203 0 R 204 0 R 205 0 R 206 0 R 207 0 R 208 0 R 209 0 R 210 0 R 211 0 R 212 0 R 213 0 R 214 0 R 215 0 R 216 0 R 217 0 R 218 0 R 219 0 R 220 0 R 221 0 R 222 0 R 223 0 R 224 0 R 225 0 R 226 0 R ]
+/Parent 217 0 R
+/Annots [ 199 0 R 218 0 R 219 0 R 220 0 R 221 0 R 222 0 R 223 0 R 224 0 R 225 0 R 226 0 R 227 0 R 228 0 R 229 0 R 230 0 R 231 0 R 232 0 R 233 0 R 234 0 R 235 0 R 236 0 R 237 0 R 238 0 R 239 0 R 240 0 R 241 0 R 242 0 R 243 0 R 244 0 R 245 0 R 246 0 R 247 0 R 248 0 R 249 0 R 250 0 R ]
>>
endobj
-177 0 obj
+199 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -415,7 +468,7 @@ endobj
/A << /S /GoTo /D (section.4) >>
>>
endobj
-197 0 obj
+218 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -424,7 +477,7 @@ endobj
/A << /S /GoTo /D (subsection.4.1) >>
>>
endobj
-198 0 obj
+219 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -433,7 +486,7 @@ endobj
/A << /S /GoTo /D (subsubsection.4.1.1) >>
>>
endobj
-199 0 obj
+220 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -442,7 +495,7 @@ endobj
/A << /S /GoTo /D (subsection.4.2) >>
>>
endobj
-200 0 obj
+221 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -451,7 +504,7 @@ endobj
/A << /S /GoTo /D (subsection.4.3) >>
>>
endobj
-201 0 obj
+222 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -460,7 +513,7 @@ endobj
/A << /S /GoTo /D (subsection.4.4) >>
>>
endobj
-202 0 obj
+223 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -469,7 +522,7 @@ endobj
/A << /S /GoTo /D (subsubsection.4.4.1) >>
>>
endobj
-203 0 obj
+224 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -478,7 +531,7 @@ endobj
/A << /S /GoTo /D (subsubsection.4.4.2) >>
>>
endobj
-204 0 obj
+225 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -487,7 +540,7 @@ endobj
/A << /S /GoTo /D (subsubsection.4.4.3) >>
>>
endobj
-205 0 obj
+226 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -496,7 +549,7 @@ endobj
/A << /S /GoTo /D (subsubsection.4.4.4) >>
>>
endobj
-206 0 obj
+227 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -505,7 +558,7 @@ endobj
/A << /S /GoTo /D (subsubsection.4.4.5) >>
>>
endobj
-207 0 obj
+228 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -514,7 +567,7 @@ endobj
/A << /S /GoTo /D (subsubsection.4.4.6) >>
>>
endobj
-208 0 obj
+229 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -523,7 +576,7 @@ endobj
/A << /S /GoTo /D (subsection.4.5) >>
>>
endobj
-209 0 obj
+230 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -532,7 +585,7 @@ endobj
/A << /S /GoTo /D (subsection.4.6) >>
>>
endobj
-210 0 obj
+231 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -541,7 +594,7 @@ endobj
/A << /S /GoTo /D (section.5) >>
>>
endobj
-211 0 obj
+232 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -550,7 +603,7 @@ endobj
/A << /S /GoTo /D (subsection.5.1) >>
>>
endobj
-212 0 obj
+233 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -559,7 +612,7 @@ endobj
/A << /S /GoTo /D (subsection.5.2) >>
>>
endobj
-213 0 obj
+234 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -568,7 +621,7 @@ endobj
/A << /S /GoTo /D (subsection.5.3) >>
>>
endobj
-214 0 obj
+235 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -577,2231 +630,2827 @@ endobj
/A << /S /GoTo /D (subsection.5.4) >>
>>
endobj
-215 0 obj
+236 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [170.63 417.191 334.626 427.984]
+/A << /S /GoTo /D (subsubsection.5.4.1) >>
+>>
+endobj
+237 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [147.716 419.128 232.509 427.984]
+/Rect [147.716 407.173 232.509 416.029]
/A << /S /GoTo /D (subsection.5.5) >>
>>
endobj
-216 0 obj
+238 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [170.63 405.236 367.781 416.029]
+/Rect [170.63 393.281 367.781 404.073]
/A << /S /GoTo /D (subsubsection.5.5.1) >>
>>
endobj
-217 0 obj
+239 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [170.63 392.727 354.746 404.682]
+/Rect [170.63 380.772 354.746 392.727]
/A << /S /GoTo /D (subsubsection.5.5.2) >>
>>
endobj
-218 0 obj
+240 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [147.716 383.263 230.074 392.118]
+/Rect [147.716 371.308 230.074 380.163]
/A << /S /GoTo /D (subsection.5.6) >>
>>
endobj
-219 0 obj
+241 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [170.63 371.308 314.314 380.163]
+/Rect [170.63 359.352 314.314 368.208]
/A << /S /GoTo /D (subsubsection.5.6.1) >>
>>
endobj
-220 0 obj
+242 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [170.63 359.352 272.498 367.619]
+/Rect [170.63 347.397 272.498 355.664]
/A << /S /GoTo /D (subsubsection.5.6.2) >>
>>
endobj
-221 0 obj
+243 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [132.772 335.497 295.358 346.392]
+/Rect [132.772 323.542 295.358 334.436]
/A << /S /GoTo /D (section.6) >>
>>
endobj
-222 0 obj
+244 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [147.716 323.542 206.994 334.335]
+/Rect [147.716 311.587 206.994 322.38]
/A << /S /GoTo /D (subsection.6.1) >>
>>
endobj
-223 0 obj
+245 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [170.63 311.587 238.265 322.38]
+/Rect [170.63 301.569 284.121 310.425]
/A << /S /GoTo /D (subsubsection.6.1.1) >>
>>
endobj
-224 0 obj
+246 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [170.63 287.677 238.265 298.469]
+/A << /S /GoTo /D (subsubsection.6.1.2) >>
+>>
+endobj
+247 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [132.772 291.606 197.605 300.563]
+/Rect [132.772 267.696 197.605 276.653]
/A << /S /GoTo /D (section.7) >>
>>
endobj
-225 0 obj
+248 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [147.716 277.437 240.618 287.918]
+/Rect [147.716 253.527 240.618 264.007]
/A << /S /GoTo /D (subsection.7.1) >>
>>
endobj
-226 0 obj
+249 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [132.772 257.733 205.625 266.69]
+/Rect [132.772 231.886 247.815 242.78]
/A << /S /GoTo /D (section.8) >>
>>
endobj
-230 0 obj
+250 0 obj
<<
-/D [228 0 R /XYZ 132.768 705.06 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [132.772 211.905 205.625 220.862]
+/A << /S /GoTo /D (section.9) >>
+>>
+endobj
+254 0 obj
+<<
+/D [252 0 R /XYZ 132.768 705.06 null]
>>
endobj
2 0 obj
<<
-/D [228 0 R /XYZ 133.768 243.717 null]
+/D [252 0 R /XYZ 133.768 197.889 null]
>>
endobj
-227 0 obj
+251 0 obj
<<
-/Font << /F79 193 0 R /F26 194 0 R /F86 195 0 R /F78 192 0 R /F87 231 0 R >>
+/Font << /F80 214 0 R /F28 215 0 R /F87 216 0 R /F79 213 0 R /F88 255 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-239 0 obj
+264 0 obj
<<
-/Length 2580
+/Length 1883
/Filter /FlateDecode
>>
stream
-xڭY[ܶ~G-e$Ž
-8O+Y!Zi#J96pF屝/Kjx| 7=/B.qE@pER4vNE,ܽ f2
-J:S\qkCMO(mv4\M Rt<U =vxC)N(x׸UX79H>=}TvopC\
-h>U{}:[]E"  YG$>/iڧKEk, 綻}_56($[NЙS{;+tkc? *g"$}$` :O99!V"SE,( Z:;i,Ʋi֔,nh[
-qA%qGbu֫x27aA7M^jW
-Jv7Mn DPgҜ=
-*;NUC-ePUS%y
-~<*h {PuwE]q=5}()d.?k(pù͟?.Ñ 2`w\]8@v8Z<LzDqL
-Y>
-3!n}ћT乞 zَ -氠5h'R#!kt2tW N2i6u<G
-"AԠ DrEo:uI6Ԋm[ҙas
-p$怒zއ:S=Kvd1jm}IDN]CS'tD/(~^ Rϓ0ǹ8U5@SX"` YϷd2͌OD3VyWuݴFWӜODK}.6d ‡6\ތ[++\I=+
-Dnk~pVM(EIPHBYB*ͭ=f^:ӉvoX
-EAKŹSr5r0ju-7'jAjZ#V
-ߕ-qcH DVm<U֐<4.I
-Ӎ`C3Q>)ߔbOr
-
-RoəJP>_trlP a3 Sct SuS+U\Pn"|S^ГNndq,k+h+2+L747U 2ȥ97D"G/r9 L#fX8_4]ES2uP2 ~rh墧Ҷ1 U&"DtJgsbF8;s.P$<wA"i}VxNYz\`nh:WK-aw2V0h3!d37d
-LB$˨]5r|P5s)tE/"^}=;t7 qz$p"
-~aSNZ"OI2@tع _Ü9\\Zb |KQ;'gPQPvDAcU2s
+xڭXK#ϯPN
+R|dCeiE7kr#wҞ9Ts3F:aQQzjx}ʁ&;$1*wOh"$Ww*&H >A*$!Skm6[nTrw=M5EO)f&XMU͑02nZ!. Թ@Ho#
+;mf{BPM
+)Sp'ckSOg+ H.:./LHqqmOV
+UzξU}"[]Z/g<ht3(l
+數Ȥ;r*Hە=P\Q_䡅oDK Y=pJ {]S3+&r qziQc9WX-Y8_?&sZݿ%Q
endstream
endobj
-238 0 obj
+263 0 obj
<<
/Type /Page
-/Contents 239 0 R
-/Resources 237 0 R
+/Contents 264 0 R
+/Resources 262 0 R
/MediaBox [0 0 612 792]
-/Parent 196 0 R
-/Annots [ 232 0 R 233 0 R 234 0 R 235 0 R ]
+/Parent 217 0 R
+/Annots [ 256 0 R 257 0 R 258 0 R 259 0 R 260 0 R ]
>>
endobj
-232 0 obj
+256 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [308.333 606.657 315.307 615.513]
-/A << /S /GoTo /D (section.5) >>
+/Rect [159.18 531.305 166.154 543.261]
+/A << /S /GoTo /D (section.8) >>
>>
endobj
-233 0 obj
+257 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [271.327 555.138 286.049 565.931]
-/A << /S /GoTo /D (subsection.5.6) >>
+/Rect [332.861 487.47 347.583 499.425]
+/A << /S /GoTo /D (subsection.3.1) >>
>>
endobj
-234 0 obj
+258 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [450.745 274.348 465.468 284.086]
-/A << /S /GoTo /D (subsection.5.4) >>
+/Rect [453.237 435.941 475.708 447.066]
+/A << /S /GoTo /D (subsubsection.6.1.1) >>
>>
endobj
-235 0 obj
+259 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [286.612 116.319 309.084 127.112]
-/A << /S /GoTo /D (subsubsection.5.5.2) >>
+/Rect [357.38 246.478 364.354 257.271]
+/A << /S /GoTo /D (section.5) >>
>>
endobj
-240 0 obj
+260 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [250.227 158.807 264.949 169.599]
+/A << /S /GoTo /D (subsection.3.1) >>
+>>
+endobj
+265 0 obj
+<<
+/D [263 0 R /XYZ 132.768 705.06 null]
+>>
+endobj
+266 0 obj
+<<
+/D [263 0 R /XYZ 133.768 621.377 null]
+>>
+endobj
+268 0 obj
+<<
+/D [263 0 R /XYZ 133.768 565.137 null]
+>>
+endobj
+269 0 obj
+<<
+/D [263 0 R /XYZ 133.768 528.317 null]
+>>
+endobj
+270 0 obj
+<<
+/D [263 0 R /XYZ 133.768 484.481 null]
+>>
+endobj
+272 0 obj
<<
-/D [238 0 R /XYZ 132.768 705.06 null]
+/D [263 0 R /XYZ 133.768 453.154 null]
+>>
+endobj
+273 0 obj
+<<
+/D [263 0 R /XYZ 133.768 432.952 null]
>>
endobj
6 0 obj
<<
-/D [238 0 R /XYZ 133.768 455.52 null]
+/D [263 0 R /XYZ 133.768 369.42 null]
>>
endobj
-241 0 obj
+274 0 obj
<<
-/D [238 0 R /XYZ 133.768 385.195 null]
+/D [263 0 R /XYZ 133.768 318.928 null]
>>
endobj
-242 0 obj
+275 0 obj
<<
-/D [238 0 R /XYZ 133.768 271.98 null]
+/D [263 0 R /XYZ 133.768 243.489 null]
>>
endobj
-244 0 obj
+276 0 obj
<<
-/D [238 0 R /XYZ 133.768 180.456 null]
+/D [263 0 R /XYZ 133.768 155.818 null]
>>
endobj
-237 0 obj
+262 0 obj
<<
-/Font << /F26 194 0 R /F86 195 0 R /F78 192 0 R /F87 231 0 R /F89 243 0 R /F34 245 0 R /F31 246 0 R >>
+/Font << /F87 216 0 R /F28 215 0 R /F80 214 0 R /F89 267 0 R /F36 271 0 R /F79 213 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-250 0 obj
+280 0 obj
<<
-/Length 2926
+/Length 3196
/Filter /FlateDecode
>>
stream
-xZ[ܶ~&RJ4I[hKH;+X;ZKZE{CRi')23~_V|3~~sY,7hWB,ʤI/f_:k&<:SIZ$~QJoÓom/_Ͼ3iJ(]6nn&2뮽 HXFX,K'N+TU̒."Uclq)%gk~Cۇ*XoR0 9l`y$oS*=ei:Y>DΦ7ŰH#Jd{ZZShU ic6?P
-s!loY UC=@Rc$2%붻]}U'ڲ4M-g*zhU}v_>ȹ]Wn2y?J %5t:ۺ)cj⬒oJzhU@w-\ OWn~NٕaZe<aF==Aa9dcU,eAD1r &վxTjég;uyq2K0 nXLVp;-Ðdvt>sEx<*5G>f%x;-yU V7@Fdeum獠]anCsM*1-VU&󜢹3Oi%ic
-wm^zO{#.{eZ ˿n'$~\EDr,L*2X2cI)^
-߼:P?ܐ̛@mە> lQMᱛQn)e%&wE7Fc4n~"›% Qs3nĆ[0O]OE,!6Cm]&if
- t/}:`
-XKJz PW,/X)'1,5$P;j\z5GwY^pG_,- U:p2$m>D6EZϘr*k8P owq p>6po)߬@;Fi"L f3?r8|OHNO=ğdo|2]xi&0T
- }lJJ SHg:4k8
-<58 ]9y[9֪>nb@י~o|{V*rߎ+@G" @ܙ:n-)ОL-L芅LH=ö)(1.X
-e>Q!fh$}3ԛ #GHa:~UH&$/b7ğ7`(ҕfZ?5w۫g+ ϬE`HDj>W*10gGz BPhV/898+Y9˰zB9*3YY1B|ȥqapΌ0dRG[X}}.e)rav-~mUdi/*_fĪ3
-,&TS: Ita9رe&Wh!if;g@8눠2hE\$(. ʳzRN:I#6B:΃|x
-򜼪p^r2 WbS/ɘ"Dó # *+:s86@p }-C$`XTΙa\y=
-ID:)c
-Z8q`8YM=(zw¹ȾZhߏ=_HXjf<БRY-8U
-p\'il2x<{q8P̦aݷXɟ4g@ڳQxdeI{x!-!PԱth@.rJ4X}6"khb@?eҘ(˛na8 -;hGß@@z&\-/}T'է8>/O
-|1!dMqKTgTOٔwnfS1bK]ˊ<Շۀ-#,vHOs]`IWpƎũc
-kwH@ ;.9lY7E?.ڮ'C|b娣30jI&ӣ'pco?ӗ:p%菗C9_VϿ~nv ƛ޷tb' EY-~eH b+ Χ9_rÙHs K}}_a)ֿ9}օx
+xZ[۶~_K`\i&qN/qf"K]N$%N{?\HDiMK; |}EO\5̈́YJT.&Z…\/'?gx3_6-~^7rU<?eysOۧϸPqFrfwe= !,že|qW8W Lvn~
+de&<"ә2{6"7oE]lf@~YMgd:>$<oXWTu b[͖X&0I܋Qjb'ԁ2*+X4*އM.mny6*XV QϿ,Ŷry_[K@Lwj{vu6Z@ޕ^x.|S.jȘ+m)Vr7fn+uqd
+P>ٷ
+IjBÛj
+qѪ\ala~&/I S:H5~Tmw.;2G]&K޽OK(@.e]9"Z:S|[_X^ QlXC ٛy⮨ς]ݱ aMr#g@=J뫷ѕ|kDQA(,W?B'Kli4VWu&l('<5)%#fuާђXkg>;- i->4,'R4kDQ3B1I:E jd +7i.+W0d;&W)H!
+ٓ t\Dzf@i*2+doފg4W;jDi$e%1"Ab(T$uNNr!6uQ<Dt0JK+[dmرl{3`hҨD
+b󼫽WНad0ژ M ȳum4P
+sk"azhDQڐR!\ Ø3bB3W=5 Q飼߇\O}!}yZG-:8b:.EFVB:oBcFrC
+W8% ))Bipm$m]2{\RK9"+#{8&Z'QtQ=
+;*ݗr
+pλ&ޔ!,l سR:gR1KsJJx:#5F>+7eD-b6 4͐4r,4^8,rww L`++y _]xﲵ^d8Ir'3\>J$
+{QGG } 9ΟH4ʎ{qm#*}{HfW5e<*NUdQm<LY`-> P&&D;,7J͟ -(H^4>j E| Gy:%UH>
+@ /τ 59Յ[JrK@֗cבֱ:O!T鞤P芤0ŔK=>K\\O;8KzW{HQˌgOݽjH̾c?t2w3(@0&I*& E@b<.bZirP)`j xf8w,Ai>/{ɄP b
+Bd0V^<bW~ʺ߆ܴ/Vq:w(/h?r
+ZÑ|F$r֢Z9\I2P+Hn%:Q%.PmN5N,m܊p,k`dʙ?%!}jO
+Wł30U톆?2ojI/ASu%/%ѣǿ
endstream
endobj
-249 0 obj
+279 0 obj
<<
/Type /Page
-/Contents 250 0 R
-/Resources 248 0 R
+/Contents 280 0 R
+/Resources 278 0 R
/MediaBox [0 0 612 792]
-/Parent 196 0 R
-/Annots [ 236 0 R 247 0 R ]
+/Parent 217 0 R
+/Annots [ 261 0 R 277 0 R ]
>>
endobj
-236 0 obj
+261 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [464.778 618.436 471.24 630.373]
-/A << /S /GoTo /D (Hfootnote.1) >>
+/Rect [250.227 632.384 264.949 643.177]
+/A << /S /GoTo /D (subsection.5.6) >>
>>
endobj
-247 0 obj
+277 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [452.152 151.613 459.125 163.568]
+/Rect [452.152 337.423 459.125 349.378]
/A << /S /GoTo /D (equation.2.3) >>
>>
endobj
-251 0 obj
+281 0 obj
<<
-/D [249 0 R /XYZ 132.768 705.06 null]
+/D [279 0 R /XYZ 132.768 705.06 null]
>>
endobj
-252 0 obj
+10 0 obj
<<
-/D [249 0 R /XYZ 133.768 667.198 null]
+/D [279 0 R /XYZ 133.768 596.173 null]
>>
endobj
-253 0 obj
+282 0 obj
<<
-/D [249 0 R /XYZ 133.768 615.448 null]
+/D [279 0 R /XYZ 209.644 505.163 null]
>>
endobj
-254 0 obj
+287 0 obj
<<
-/D [249 0 R /XYZ 133.768 583.014 null]
+/D [279 0 R /XYZ 259.126 451.33 null]
>>
endobj
-255 0 obj
+289 0 obj
<<
-/D [249 0 R /XYZ 133.768 551.687 null]
+/D [279 0 R /XYZ 215.27 380.835 null]
>>
endobj
-256 0 obj
+290 0 obj
<<
-/D [249 0 R /XYZ 133.768 507.851 null]
+/D [279 0 R /XYZ 198.191 300.861 null]
>>
endobj
-257 0 obj
+292 0 obj
<<
-/D [249 0 R /XYZ 133.768 467.952 null]
+/D [279 0 R /XYZ 214.009 220.218 null]
>>
endobj
-10 0 obj
+293 0 obj
<<
-/D [249 0 R /XYZ 133.768 408.149 null]
+/D [279 0 R /XYZ 212.073 139.77 null]
>>
endobj
-258 0 obj
+278 0 obj
<<
-/D [249 0 R /XYZ 209.644 317.416 null]
+/Font << /F87 216 0 R /F28 215 0 R /F79 213 0 R /F36 271 0 R /F82 283 0 R /F81 284 0 R /F33 285 0 R /F39 286 0 R /F40 288 0 R /F67 291 0 R >>
+/ProcSet [ /PDF /Text ]
>>
endobj
-262 0 obj
+297 0 obj
<<
-/D [249 0 R /XYZ 259.126 263.583 null]
+/Length 2816
+/Filter /FlateDecode
>>
+stream
+xڵZߏ~߿B})m^MC.@VO$6}Rih!Ioo0曷%(.T5P$wݾ۵vUY ܪUSUnH} xPuru,='{(oWvm'?x(۲ێ}e&,(Ea½ޥ&0HDkzڷ4VP?bSS_!b:jWu]xz=2~~W]۪?5?
+C5ԇ"BTq@ܳ/>}5R7Xpœ8kvC̷2hލDo"_;
+R2)l&`^ )H vQG^Jx$iE9E<H@gS2(6hT 8@H#ey +EpAu\' U"/^%>HŦ{^~T~#|d"á_Dg
+!"ohcf ~,O3ƌ^y81r&RL栦k&hEP0nWG ei16YKbOcr^SN D
+ ѳ &/#f,) q@Q{)#U{W%!9Q Y,2XeSoߧ~8Tw6x6PBmB!^Ny
+D1́3ձ=ˉM} N~)5/7(ܑ>?ҦmNc<ѤOw.u@uPҝy_,Q/B_m\:^ 1rk8cS(Uk4%dSa4D.Pj`I0 z6p֮kKdUo=}B%ru}v ӌ5[ARqCee؏qS6SC`fS5tk.=yޏx7
+zh(e!4 Q*ŝd2ρp*y@K6R$Rιq̶
+V&V|پ Xq רZ3 [_&(\qMGT6QffJMr܌
+tȓ
+03YغK6L򌲷ni.$esyO1&1GOZCí(}2rdz Bo
+r N<DKp>ȏb,| W3YxUڦjt[=Ʊ (X;=bmA^c\b6@9˗~X2=P&_{oÐ%c3vT2gal_o+ÆoVPɂXLF'#ɍE~ zӊÌY,_g"޿.C6M/7D
+4Xշ9;$6SRB7Tt |tܬXjQJ.K$˛ \䳎d]i.#—.m؞6xyxK-LdWRQ{,rzfkȵyg|J5_o0"@> Cukd0+ BAPE.3ܒzN^`vC_3EMs)b!0,E;oAh_fB^4!?34BT_ hs?2Uc eevUZO] UeJǛɥR
+endstream
endobj
-264 0 obj
+296 0 obj
<<
-/D [249 0 R /XYZ 215.27 195.025 null]
+/Type /Page
+/Contents 297 0 R
+/Resources 295 0 R
+/MediaBox [0 0 612 792]
+/Parent 217 0 R
+/Annots [ 294 0 R ]
>>
endobj
-265 0 obj
+294 0 obj
<<
-/D [249 0 R /XYZ 149.011 134.527 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [289.97 372.249 296.944 383.041]
+/A << /S /GoTo /D (section.5) >>
>>
endobj
-248 0 obj
+298 0 obj
+<<
+/D [296 0 R /XYZ 132.768 705.06 null]
+>>
+endobj
+299 0 obj
+<<
+/D [296 0 R /XYZ 297.43 630.183 null]
+>>
+endobj
+300 0 obj
+<<
+/D [296 0 R /XYZ 240.445 539.331 null]
+>>
+endobj
+295 0 obj
<<
-/Font << /F26 194 0 R /F86 195 0 R /F89 243 0 R /F34 245 0 R /F87 231 0 R /F79 193 0 R /F78 192 0 R /F81 259 0 R /F80 260 0 R /F31 246 0 R /F37 261 0 R /F38 263 0 R /F76 190 0 R /F90 266 0 R >>
+/Font << /F28 215 0 R /F33 285 0 R /F36 271 0 R /F89 267 0 R /F82 283 0 R /F71 301 0 R /F40 288 0 R /F91 302 0 R /F39 286 0 R /F81 284 0 R /F87 216 0 R /F83 303 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-270 0 obj
+308 0 obj
<<
-/Length 3365
+/Length 3075
/Filter /FlateDecode
>>
stream
-xZKsW0x]JRκJَWlWy4CICKrV| OAl*E6@wXr ȓ"+r<nlfHrm2!urM~N9lͺ+)e˕:\RJ7]RzwgǃW5]Sݺ=痿^}kF"3'+3ϟ.W&sW/83eKR$Ͽd&,M><3@sdlDƴMr!2x߇ڱ@%3¸"BYa6gQ$G?hA.yL Ü,P\#2&8;!׉
- )V,+0)Ϙ2 .<n)<ό{:j1P΃
- MV#gUY38 ꟬Wl91<6O8HbHAM~qBEh3P+: aU0)ϴcy=ul(&d$bL:^+Qr)lPLqlBi!_Pk.m(ǚ۞"0&+8K,vɕKcN~g-A)dD
-$B?Q!Nʎ/ ?<(u|~J1Z?ê-˦"#{}POu;ۻғM(ʇWMq .=$Mou`RoU0ByX׀t[֕-¤%OrPi*}/$AV݄l&q;ˇTO@0-ob|P24vSSn}_{@
-6J_R[6f ̀<
-,mܑ(FQp
-Zmܞ6х6ݬwPn\Ą/74PmEbq <G'a6}K ᰑy#SuH32[ƣiɇ"7}J=[~I>Ya;_E֢ߊj3M,GXmqb͔a| pTW3l>8b'K9IK!+gLZdϛ4YgP'~f ߉=;בĘdU<Sӊ 
-yRG< /.Wx>vjiM`HH$.'$o|+):Z/0"'WRR4ĕ52@*RӘJsG.K.UM[݃i2)iW˛y+sCBh>Ќ䏟vB3QR0\Nδis,/ U ɕ*^(_ /Y(07)|rWO!O`eXUCCʌ$ۆ/m%.<EJtݮ,} !jh/u34x$_C%X#ӗIXzwhs%x=f-2`ֱg6/qY89;-A  һ#dOu}f014;%#qv.Ľlˏmآn//^:᎚H?U- 4Քm8oj)l}Weö
- YA;OݼkcYic{ E
-Nte+ Y>F!l&$?GJL
-=Xt1y
-e/RQQQQ1N~^k-cQNT` ʙ`<EWJ리EG.V(DNڄ?OM/VۍB1n#po
-\mCj[WMwqM;2;?ʗ9v,8؇\ݙQY[ѭM;R̴O]{I&g-Wg+Rۥt;E۔f+ e"7rG7piT'Ÿ\__|sP@8EᮁxXhAufFqe+5 *+L-K):gb/ B"d)π KIV$ݝwtL#IPy u=
-ٳ4ݥ
-WOeŬsR[ŴK okֻPP~
-ZM(ߔ
-X}Ə__$?;jWjΎn~*{0p[!<_ъH(CeͰv&Yntb'_yDRWWnv~Jw]?UDg[<ޞ&l1ղv&J
-X2GʧO%ouD
+xڭZKoFW iĹY ؃ a$ z49RHtf_=,MNj,x.4BDj-rgsM6T_T6T=^tnMV.J~J򷫟_S> "8aA{fKӶ-|BqSfSq?xLdڧw2m˕.F*q"xz!J0ۛ#]Y"a/NpoY?''DKp¨N>\ʂmxbgv2p)R:hd=!-n=߳/ǺufJUB] QT &
+
+zDO~ i##h==!mR 4(z!KA.DЏw5JhΜvUNx3:m_ʇ2bVvx!~Lx \mP4 b1gg~Ǻ"y>@;r`RPӴ&#fyz$^ǀ%vgm>#>7ª'cb#!'wBE|T@Sn5
+'!{V~ N
+)c nȉ` W!twE#b=T9ƺe&|\.6h9DmHW402!AxjT9<BdgtK\8oaSC8q楦mx1]K)E32)~ $ڌVi#[b\huY=l+H;\i\=d8Ez{ڮ3tpHT I
+yBL:\ވ,w9rC~;.
+RSvtژ+ZUY 3
+`wƎa=6-=g2@JLHG4y0J9x21O
+-F嘕i&[=iM
+Ybjy>w:r&[`O+.Pڎ_OķyǒJPs
endstream
endobj
-269 0 obj
+307 0 obj
<<
/Type /Page
-/Contents 270 0 R
-/Resources 268 0 R
+/Contents 308 0 R
+/Resources 306 0 R
/MediaBox [0 0 612 792]
-/Parent 196 0 R
-/Annots [ 267 0 R ]
+/Parent 217 0 R
+/Annots [ 304 0 R 305 0 R ]
>>
endobj
-267 0 obj
+304 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [320.448 151.349 327.422 162.142]
+/Rect [249.165 501.742 256.138 512.535]
/A << /S /GoTo /D (section.5) >>
>>
endobj
-271 0 obj
-<<
-/D [269 0 R /XYZ 132.768 705.06 null]
->>
-endobj
-272 0 obj
+305 0 obj
<<
-/D [269 0 R /XYZ 197.361 641.096 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [437.926 399.44 444.388 411.93]
+/A << /S /GoTo /D (Hfootnote.1) >>
>>
endobj
-274 0 obj
+309 0 obj
<<
-/D [269 0 R /XYZ 213.179 560.454 null]
+/D [307 0 R /XYZ 132.768 705.06 null]
>>
endobj
-275 0 obj
+14 0 obj
<<
-/D [269 0 R /XYZ 212.073 480.006 null]
+/D [307 0 R /XYZ 133.768 667.198 null]
>>
endobj
-276 0 obj
+18 0 obj
<<
-/D [269 0 R /XYZ 297.43 413.213 null]
+/D [307 0 R /XYZ 133.768 433.327 null]
>>
endobj
-277 0 obj
+312 0 obj
<<
-/D [269 0 R /XYZ 234.772 322.361 null]
+/D [307 0 R /XYZ 149.011 138.182 null]
>>
endobj
-268 0 obj
+306 0 obj
<<
-/Font << /F26 194 0 R /F34 245 0 R /F38 263 0 R /F81 259 0 R /F80 260 0 R /F65 273 0 R /F31 246 0 R /F37 261 0 R /F89 243 0 R /F69 278 0 R /F91 279 0 R /F86 195 0 R >>
+/Font << /F79 213 0 R /F28 215 0 R /F87 216 0 R /F82 283 0 R /F36 271 0 R /F94 310 0 R /F33 285 0 R /F88 255 0 R /F39 286 0 R /F89 267 0 R /F83 303 0 R /F98 311 0 R /F95 313 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-283 0 obj
+320 0 obj
<<
-/Length 2411
+/Length 3028
/Filter /FlateDecode
>>
stream
-xڵXKFϯ!@(ĢO6|H؃m D1I30&Ejzf3Qw_UuDiUzsGB'J[]"T<&K26zZiߺmݖj2o2.*W6* h-eRY{a|Nlb{;<|r5ۦf$\7j-4)"IfNּu@dWx%/D$ ;ld!Tgf}m(MTG>kI&zsO4ɭgn$dD+duwGRI<i5N L h]hhF=~Zx&:&VzFV> OZi"r {Ij fR׋SG^(p x'u\ۺ&iAεNgZWN)[߲i> ,`C^į̻r3uAg=4 VAa_.d9í*574( Tѳo(-|X*}nɺ?6CO[^/w2`~hέ;tݯD h׷7ʎORUu,,x7<|[<*"Nx]* T:Zֺ=g9?tL)щz?XGmo~M
-+ْVN9;#w]~Wu<{) 2x t;tEPaR_@)TLBvZaum
-OUKӒ9Y x( C9
-V>ß|2%,I3TiW}<֝ [Ŏ<\ 6qvqMT!Y=6K ?15)5 G %iwojrٳ$}ͮqj
- yo@e7 !PmgTFQ22XsD[ͥXe*BN# 9bd*&;3Uˢ-_f,qXm@%ڕD8T[`O`O %sJKdOÞO&{(\_Zb贩uO6zG؈j^|"H `1q n[1>t4;y{soAɧB<Og%<m><ryj_rGS[Egfm(ݚznjy'qʌ %CW4o0= f
-BQ5t2>*,k Aa3 J_$ xF_/t\ DC}z{p k.1/7@?2gEŒV6~LMD</yxR
-௄L"s yfTj<fT5=M09ԤK"vX [$
-î] i
+xڽZݏ߿K6 ,[yH}ptc10DSU00ˍϱ(~ћFQ&߯nx(S.FRk]96+xlOw}&S+#-rDon~HHz/IsaǟҨEy=} ,|Si$rF̂\fvX̡gV&ަ6]Dvy\f6\'xm>~ tMLf[aӜjmKi.T[{-2I>x [ŧ}C!뙥p(Qk}H f9 'UmF/|O>t<6ڃM`_TWv}70?oEXl/ V:̈́L7\jmb/PWH.o'⯏ć~Z%E~Ǜp|ڣTra~p0?#dHWDRS2bj|6-Y[z3H"_!I/h :ԉ
+x*/s)t" +?# \DJXzԲ:p ew2mWl=g"BW ^ p{`qGχb3nێXy
+%@cI/CXvM!)]u hNڅy.
+-U̸ZD5ji0(cFrS?4 7=RE:7 ɪlnBUYv
+qb)p4
+sA_?3d!'AHïWbb8gD\!0|
+e'=iiE:S#H E|!R*{7-CW O^;)A^9e>|X5Ah2O5wW|j$ 0
+6 ePRZ ^3`q<B*TE_7OΧ8WWk~Hi0U$]R) MI[e|0O)ӸlHFFSzBa:(u((M@zO!_WdG'?+GVHap+=t7 -)πAqvR'H,W3mK\O" 0\J<XZt=K??m= IMCZf QbX@,۴*Y\Ͼ j׸H\zZ{HSƠo
+" ?Vlǐhgwq8aitĢ*}}N
+5~_^'r
+خ-+N uBH+jn9wPe
+#Yu1a;a_=(8Twk @:݈[*@{BXP
+"n$қU@**L4UD32J'y#5/WDInջ?Ԇq4Xf
+BOd#l
+ރ+sIJ 0s4F"fokr@JFhF! Q60U*0,Aq^R۹nrsi$GTM#M 92OY.Ro._?
endstream
endobj
-282 0 obj
+319 0 obj
<<
/Type /Page
-/Contents 283 0 R
-/Resources 281 0 R
+/Contents 320 0 R
+/Resources 318 0 R
/MediaBox [0 0 612 792]
-/Parent 196 0 R
-/Annots [ 280 0 R ]
+/Parent 324 0 R
+/Annots [ 314 0 R 315 0 R 316 0 R 317 0 R ]
>>
endobj
-280 0 obj
+314 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [340.398 542.939 346.859 555.083]
+/A << /S /GoTo /D (Hfootnote.2) >>
+>>
+endobj
+315 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [471.502 510.3 478.476 521.148]
+/Rect [178.607 430.684 185.581 441.476]
/A << /S /GoTo /D (section.5) >>
>>
endobj
-284 0 obj
+316 0 obj
<<
-/D [282 0 R /XYZ 132.768 705.06 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [250.698 353.533 273.169 365.488]
+/A << /S /GoTo /D (subsubsection.5.4.1) >>
>>
endobj
-14 0 obj
+317 0 obj
<<
-/D [282 0 R /XYZ 133.768 667.198 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [194.935 317.667 201.908 329.622]
+/A << /S /GoTo /D (section.5) >>
>>
endobj
-18 0 obj
+321 0 obj
<<
-/D [282 0 R /XYZ 133.768 429.056 null]
+/D [319 0 R /XYZ 132.768 705.06 null]
>>
endobj
22 0 obj
<<
-/D [282 0 R /XYZ 133.768 185.503 null]
+/D [319 0 R /XYZ 133.768 234.443 null]
>>
endobj
-281 0 obj
+322 0 obj
<<
-/Font << /F78 192 0 R /F26 194 0 R /F86 195 0 R /F81 259 0 R /F34 245 0 R /F37 261 0 R /F31 246 0 R /F80 260 0 R >>
+/D [319 0 R /XYZ 149.011 128.717 null]
+>>
+endobj
+318 0 obj
+<<
+/Font << /F28 215 0 R /F82 283 0 R /F36 271 0 R /F33 285 0 R /F87 216 0 R /F39 286 0 R /F83 303 0 R /F88 255 0 R /F94 310 0 R /F89 267 0 R /F80 214 0 R /F98 311 0 R /F95 313 0 R /F99 323 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-289 0 obj
+327 0 obj
<<
-/Length 2697
+/Length 2180
/Filter /FlateDecode
>>
stream
-xZm۸BߢE _E2C+hK8ŒwȖO/Y!)Ye7;ÙgF^]o4IdMxl"Il%U2ɢ&dVl6PoSWçdۛlX@a I5*28EBt8[+!F&B%ŴQ@*kN\vŠF,h z{-2)DXݻH$D ~Wd/aaZDir^ASr3;QQuvά.hEr uV8h3ZBcL+DQbKdžʒh_ڈz%(ۻO6v4Y)(ȯe [ F%ki _nwVm3A IpAEY3*W`i`:ʃ|4ތFmW+PSh F,.u˶E[MGp3ÚUM5{,(Hž
-mVW-lɂ*s1yGG3"rs$ȠLB=0TFO43+-XyZ1Pjjog2s8 hᮤ#ֹ֚ڻɛki= ly8Z욼nҮ,C8X89'7%ՠ봮ҍAO#Pa@N`!ةgH۪|<n+8 b|U~/.-}#Qgwiq|&סoyaaD wa,("]rl@!`SiYĝ2*S
-t/g2Oz[_E5na>2՛Zm ?ń&cICJ
-v=^ }B+Ӛ0 ckx"qwZ/Cch`&e־>h.{;BƇpeѵ{_to%.ч7D CGѢYžmzǥa^ e{rcj<#hW`;AƝ{@!)= ;
-Rx]g݈*Nǥ~]׌t!K}.%|eA|Y_"$bI>sx5q.~O}Iu<xApO\˺CʧOvjvf i}e]P
-!_.YpepIMQ].`OV]~fs4%2yx Q pcɩ(.Iig6{pypw+ƁZT%41=+;yVz)
-&l*QMV,j(x8!+5
-̪*8u&.RcdvXqH/JEpu=/?
+xYK8PN+o _
+Fj1D2a(dovHu02~!o(XGEGYY톿rUmanb)edڊ_[F+s\mM#:֝6 l/H$JXRĘ(t4l1w[cY-$Ib B;([lXeIe Eđ"=jsfvv{oC<.-jw,Ro~!5)b54I[/Ҿ
+p_;J\(EUIODwlaGb
+ϰywsl3OEffJo~O2; ')X+й+;`ͅO\l*QnŘ\dvdkU~t{:Wnζ~"NnXaӦ5>Jq|C%adfE;M3sJBNk28-9y|cs8Z:DS̩$= #*ԑ:͡`6Qa3\P<S@ bmJhX)AbMtDv8UA/3'I.3YOM(g F֒'ib@O/4lA5pj
+չ6ƝgIxm# }6 Uەso3%qLNKkZ2) b /af5srtccl7 "^˳%ݚ[7_\7玗F|-3"h{F#" ctZ՜oLsaGG1aaƒ"!1uE\^73|1R} #~3<`
+<a,$im8ڢ* JYVOSf*,eYoX7bEz8,ENv&`[K5Ioml!btzFLk9ˎs%.3PqLML22LW $ Q"E,2"SC&q %dbnoyD,.Ӛ%h8V>w}m0o\g{Gh{3;p0aP̔юvL2mڟ^IviUS^G~BT7~7v ~+ϳZ`DV3VptyhN`F`[ؽH\A?*`ޢgMci
+ζ:o
+>S8~][/ϵЮ{32_Ie_?@^.|P@9#UedM:xMQf2R$X!qg3F\P;a#{O<r.(8! >̵Vȯ@̘(y2)
+ ST{^u4iP&D43肄89Os ں)!&GHV/
+Dlw o NTj U.F1s:S$zpTNh;|rљeD}SDC CFbޢLl} o,19gv1I&8:eKCx(\O停I?pL
endstream
endobj
-288 0 obj
+326 0 obj
<<
/Type /Page
-/Contents 289 0 R
-/Resources 287 0 R
+/Contents 327 0 R
+/Resources 325 0 R
/MediaBox [0 0 612 792]
-/Parent 292 0 R
-/Annots [ 285 0 R 286 0 R ]
+/Parent 324 0 R
>>
endobj
-285 0 obj
+328 0 obj
+<<
+/D [326 0 R /XYZ 132.768 705.06 null]
+>>
+endobj
+26 0 obj
+<<
+/D [326 0 R /XYZ 133.768 667.198 null]
+>>
+endobj
+30 0 obj
+<<
+/D [326 0 R /XYZ 133.768 535.813 null]
+>>
+endobj
+325 0 obj
+<<
+/Font << /F80 214 0 R /F28 215 0 R /F87 216 0 R /F100 329 0 R /F39 286 0 R /F33 285 0 R /F79 213 0 R /F36 271 0 R /F81 284 0 R /F82 283 0 R >>
+/ProcSet [ /PDF /Text ]
+>>
+endobj
+335 0 obj
+<<
+/Length 2565
+/Filter /FlateDecode
+>>
+stream
+xYmBD (Y֢ɒ#;ádɫE(r8f>C]G][a"l"jq)Y()RGWytn[˕L]붮wh-oxؑ"4װsKYUTw$;YTLX-]2˚~zfQwl2Y먿zzcѭ0'xp
+RpKl
+͊V\YGWRiBMٵԬ+|pS|b/}:BZt1  ?\S+fZ
+kY ίY#a`PvYC+g{wEVR-׻n]\ q?!FwO$Z 02=>о?uCIBJq+Ŵ}L "MXlL/Jgjl` %3ojO(QCJdA`M. ){zFFԫŰ5\0ngugT(&9$PL=#` J,EJbPں͏fM}3ɼxKzq(PS@&0h~zu:+1gqV>ia:XR@Zӧ,1f3)a?<J*
+_2bR aW$?ם#n6S tww(h-
+)&|. -f&
+(Meȇ|cN0&$6$ ŷW?+LI3Uzwq}G9 B 3 .Rx
+ʊHPO@|55U<N
+;W}rit~Nw:> Lh0݊gYJ1bXRI8T0"I׶,$ԧ)ɖ>]E8z' РǢ,UI3`Y#K݅}g1K!uȯ"
+J9F{ Nk5.#1/P "J{偼n] skۢ¼,}|
+
+;mn}3% ɀ}t5B80'
+,6aA{GBS^ʂYnoQ+9o>\J=}c~&JKT5o;Uߢ$믠j6ಶ9*_R
+zxG{v
+wt?vmowaQpiԔP2L9 21 X_DŽd]KG{i&.%;G76{ƅ9|.Z`tvU.?ۇs]Ow5S8)x
+ugm(S0 u[3n(q3я ^+egG6g7ړt'M:łeKa ]Y
+HiRx4dJ҃Jc`d~GQϿ]7XWݞb xa a
+ S0 7bq ϲ|z^?%Ze\%P<T
+endstream
+endobj
+334 0 obj
+<<
+/Type /Page
+/Contents 335 0 R
+/Resources 333 0 R
+/MediaBox [0 0 612 792]
+/Parent 324 0 R
+/Annots [ 330 0 R 331 0 R 332 0 R ]
+>>
+endobj
+330 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [459.611 506.427 466.584 518.382]
-/A << /S /GoTo /D (equation.2.3) >>
+/Rect [204.399 538.735 211.373 549.528]
+/A << /S /GoTo /D (section.5) >>
>>
endobj
-286 0 obj
+331 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [418.601 382.337 425.575 393.13]
+/Rect [240.479 411.76 246.941 423.697]
+/A << /S /GoTo /D (Hfootnote.3) >>
+>>
+endobj
+332 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [246.783 291.473 253.757 302.266]
/A << /S /GoTo /D (section.5) >>
>>
endobj
-290 0 obj
+336 0 obj
<<
-/D [288 0 R /XYZ 132.768 705.06 null]
+/D [334 0 R /XYZ 132.768 705.06 null]
>>
endobj
-26 0 obj
+34 0 obj
<<
-/D [288 0 R /XYZ 133.768 315.065 null]
+/D [334 0 R /XYZ 133.768 468.45 null]
>>
endobj
-287 0 obj
+337 0 obj
+<<
+/D [334 0 R /XYZ 149.011 176.753 null]
+>>
+endobj
+333 0 obj
<<
-/Font << /F86 195 0 R /F31 246 0 R /F37 261 0 R /F34 245 0 R /F26 194 0 R /F89 243 0 R /F80 260 0 R /F79 193 0 R /F94 291 0 R >>
+/Font << /F28 215 0 R /F89 267 0 R /F87 216 0 R /F33 285 0 R /F39 286 0 R /F36 271 0 R /F81 284 0 R /F79 213 0 R /F88 255 0 R /F40 288 0 R /F94 310 0 R /F82 283 0 R /F98 311 0 R /F95 313 0 R /F99 323 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-297 0 obj
+340 0 obj
<<
-/Length 2689
+/Length 2254
/Filter /FlateDecode
>>
stream
-xYKoWzw~9lA^C @KmB)a'XEMUW?ꫪxuW?]ġiR֪Jj-$[%6Jv!B_T6remY3Qc[kZW_/zǫ?~*NE؂gͶyUEz]L,TVGKWUqgz. ,j|]2i |@Mnǀ WXظSWa]XI=w-z 47k7$kϗFEW>tTL(;n߷EŝiMDyh]VoơOT^:FXs /J&# 푣r~g_M <~CAhoA2Cc#˦Fv"` rS3haoQ{DŽD%d޿}j^2 z׆y&z3Z-D o4t66Pb:%}duОxUH⪪[X%Ea4i2&Ǝa)`) 5 Uy7 d)#LY"i:>qNǩ f5աnvpWi[mP:btu9JDUa"9j=va9LQ׏ I%Y<f섖r`m<=CD[m(Kγm\;}M|h^oOsv{!l C{j歐HԷ׏nh]Tw X K"ld/EnTx"xuE+S^YoWŇj>Wg*s0[oJC$X{Se`<44g8󎐈$ÙLl@f%?ͱY@}fR %J$*#ItHA&)vqO<wE(ahSCm >95Qwb:}ޭ1s}E)J~n$q=uJal
-!A56rEw`ʮHI>AoW:߲\ϗغn)q$D&xnP>?7.=%}LD{,v#bs2;i|[N YJR/)Ij9fiJ ,QYM$ȂpWn@u#qjϹόb|"}0X+y
-@~:(` 䘴YJ76?U\F#csdRhz*$*e΄;fAFbi;\Ky[_ 1,#HWd 8XDŽk7Vx`:<LaKNjH-L'=G-|>Gяj1N*:հxJ)N9s}ɂ ݐB̋#^PEk>QlTTaDgi?GуlIdMtnU閼5p^-?@4AM%K߹K\pdGhy749d7a@ .{*t>l(4@~2Ktuu&bԗOs0Bpst}6Oh[_SH) r]Ϯ(Ys懻z&37y
-׮*_OUu_tlW'b^ O,F:}
-\*
-N\:-fūsz3.aLTs妨|冾^/ 侾Srm^
-ͱ0RUs$syk}ݗ`tI-eꙘ%K[e28lJ%_1+_h.S
-s`t)8kqNڢ`_p)
-7a[/EJ@$n O^Y4M_nΪ%*KbCq>\ WVX8oV+2kV2״Ttە*lZ!ل-fp
+xڵYMo8Wh>Șia
+Ӫϲ_Bلg1Fx4$G1/w׉6iIԯRHtz^͊C×{ج &¥qZ^5mqhbeK)橤JV_2)]·} -׃q2 }YOsu>jp:J"c\ECRMZhߜWEx؊{.wna}#a3frEI~"yOİ̹VKy1=)S̙j|dBÜ26Z2.T̳7o~ygvluuw%s|]͋aH2!&\`
+I-38usz 7+ä0p~I^Y|n흄lj1TM#: - 5*kI >f% <57}*<kIikHnVUa;<ұ04i!#BSv|eDfBVc RP P8Em_b D[!S)wk7G魟:M*ٓ9͕ף¯uI/@ߧ |vVt^[ z{!E;7n">?I;MKĤ(N L߈K|či6Av<,K륔9-$$=kvl,sP{
+23Upfy*nF!sXW#ҐQތ{ ߫u;B%%ufr4j;,1'M/UUѝm1p@PnU:lh٭r)0n~=kޒW/Vr"(?^p-P9Crsnl"3Q0d@lY;?'|K׿>$Q&ׇE,qK,OdH莋%
endstream
endobj
-296 0 obj
+339 0 obj
<<
/Type /Page
-/Contents 297 0 R
-/Resources 295 0 R
+/Contents 340 0 R
+/Resources 338 0 R
/MediaBox [0 0 612 792]
-/Parent 292 0 R
-/Annots [ 293 0 R ]
+/Parent 324 0 R
>>
endobj
-293 0 obj
+341 0 obj
<<
-/Type /Annot
-/Subtype /Link
-/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [234.447 284.257 241.42 295.05]
-/A << /S /GoTo /D (section.5) >>
+/D [339 0 R /XYZ 132.768 705.06 null]
>>
endobj
-298 0 obj
+38 0 obj
<<
-/D [296 0 R /XYZ 132.768 705.06 null]
+/D [339 0 R /XYZ 133.768 667.198 null]
>>
endobj
-30 0 obj
+42 0 obj
<<
-/D [296 0 R /XYZ 133.768 667.198 null]
+/D [339 0 R /XYZ 133.768 490.944 null]
>>
endobj
-34 0 obj
+46 0 obj
<<
-/D [296 0 R /XYZ 133.768 271.313 null]
+/D [339 0 R /XYZ 133.768 218.246 null]
>>
endobj
-295 0 obj
+338 0 obj
<<
-/Font << /F78 192 0 R /F94 291 0 R /F26 194 0 R /F86 195 0 R /F34 245 0 R /F80 260 0 R /F31 246 0 R /F37 261 0 R /F81 259 0 R /F89 243 0 R /F38 263 0 R /F87 231 0 R >>
+/Font << /F80 214 0 R /F28 215 0 R /F87 216 0 R /F33 285 0 R /F39 286 0 R /F36 271 0 R /F40 288 0 R /F82 283 0 R /F81 284 0 R /F79 213 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-301 0 obj
+347 0 obj
<<
-/Length 2739
+/Length 2766
/Filter /FlateDecode
>>
stream
-xZnH}WmiEo$ /32"%s#T_(j;NXl٬:uhYDgHY<^\La"VIȅZ\CĒ ]^a% <Г߭ϗᜧAs0?m.[3ЕFwحjߗryfcD8uyK˺+3/M4R<Lsms ]8\ qXCTuQ-Ibɲ(X 3e{z#N\KtUkZ,އ++3w14¿%7?rve]tڍ*4 VY^keUc51;fAKAW{Q\iMɔѢ,_o7E5 }3
-pEfMUo::?l_o~wea/H_Zu O˸tE$BƎ͚X`k>ZA&iBڽ Q>M2̢2?h/#+nwwfnڝ'O~si?Vi"G-z>\Dd[fwe޸upX&77O,6ש88& ˉxfLȢZ` OR\]e_/~ܿi25> X~Q^)cp9S#Ñs";G}2L!qM}D}zY6 »Pag~9 rb9HQaݧ fH$(Ll")FdX:3DL`K F`5JcohJP
-oInf! n͝-͈ήixs7q}s]jo"]'9wVc%|_0Rr-*
-}=Ç܇|? 2q)OpAGYI) >5[;\m]feI
-<9xv$qm~SBn-1B0f{fLpɲ5""[|t \thQ(
-;0(f,_jFs&GiL/:#aZL|nnL]7ɢeu1! R!WESXi#+%dj;Mzt,o߾|ɿRP
-U9Pu-e 0Bm('
-g=uq"]?-|& @.a 0;Ija4Yp*#C<kIHB|/p
-fҺmK<Np$,F՜JKL5:H*IM0>y&S27Ö~>N
-Dj-`L=LzO@c@C^B<j)MDEfgBC3'6 &UrE~VꐺToãYTbB8FOF
-8ca>~Bj(2FX8yL媩]9ONHi*Ɉy]M^0j,y@eM-wX?aٺXFEMuLS!kԕmՀGfuv E(
-g* wGtfWɜ涮tݔMs[[Cfu?~2(){"FRx88=bZo<_QT?0;6'^{89x!Hmb݂_B`}MejLdJ}SYƒKNXLu5bWO}@S]u:s-&泣:?1NjP8#A>+#]z2NɆaJ1yaQd
+xYݏ۸߿}:-fDR]Wzݷ$@[^ %GX >Lo>b7ūUz}_n^zeIEݭ,K*URn7X?WݾkWQ~!/ʽ-;_o-UXʢ-k뭥uʚFt h'QNnwc9gFyQ߻iŮi (myͣQ
+t=i6W;2ʏGR7 ߏJ‰
+k˦1ţ;;ns0$_]kء=8Hb=QYi'.6ۀ`Z}p+wunVp>%XN/K2c0! '3ߗUEgݽܓe}n|hFn@!zTג?I]YN{_؞,,
+2y?r{#=auVBEu (%42A<Le
+4L&&`uR *e`Zɠo^}
+ЈDT*Ljsz.^mPIWna9RW}/Bf:KgWAM.JMr~3JAűufkAvHȨM.-ems.jy5xЛrōCNgBK4n9:ؼm:lpRL9p
+yK7ARW^>\Si >|Mn}5wp&dN:!?+>EuٰC֏bNe `N4"#w%xTڗ
+_`$yv`Q'Hq|=X`S#FhT9ƙVuz!opA
+x6$Nevs*-6
+*P\XT/=l  ;VޠP<c*68G$5x>R-{q-c\UV5݊
+匳 'ܻA RA&P*t/wH;GK[8dK?wlz1w;Gveh.ρpSSY8\U+=~s\-X#\-STR03zk}<
+@|
+,ζhClf,/vw/jK}I[!C-Ek e * Vx]^\5 ¯O<;XXhRHDEŁ=UԃZ!wt$<qD'PbکqIV( Ψ kPOeFZ[T_ϒ t9E骧:*7Ԏ>v]| K/L즱RK1&LS_L@~r5DQ&RY x>@D⣧ &g_Af3 A6=chϒJ<AIѵtM}e[$,3@bM])8zd-44A//ke<Urc=bZY6ү@SǮX'udCAMǼJC qɧ!e19?`]Q';[<@G-}ǔ6rc>=CT8ZN
+N<g I HrοL
endstream
endobj
-300 0 obj
+346 0 obj
<<
/Type /Page
-/Contents 301 0 R
-/Resources 299 0 R
+/Contents 347 0 R
+/Resources 345 0 R
/MediaBox [0 0 612 792]
-/Parent 292 0 R
-/Annots [ 294 0 R ]
+/Parent 324 0 R
+/Annots [ 342 0 R 343 0 R ]
>>
endobj
-294 0 obj
+342 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [275.18 630.392 282.153 641.184]
-/A << /S /GoTo /D (section.5) >>
+/Rect [459.611 467.143 466.584 479.099]
+/A << /S /GoTo /D (equation.2.3) >>
>>
endobj
-302 0 obj
+343 0 obj
<<
-/D [300 0 R /XYZ 132.768 705.06 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [388.554 338.764 395.527 349.557]
+/A << /S /GoTo /D (section.5) >>
>>
endobj
-38 0 obj
+348 0 obj
<<
-/D [300 0 R /XYZ 133.768 513.659 null]
+/D [346 0 R /XYZ 132.768 705.06 null]
>>
endobj
-42 0 obj
+50 0 obj
<<
-/D [300 0 R /XYZ 133.768 362.848 null]
+/D [346 0 R /XYZ 133.768 244.148 null]
>>
endobj
-299 0 obj
+345 0 obj
<<
-/Font << /F37 261 0 R /F26 194 0 R /F89 243 0 R /F86 195 0 R /F31 246 0 R /F34 245 0 R /F81 259 0 R /F80 260 0 R /F79 193 0 R /F38 263 0 R /F78 192 0 R >>
+/Font << /F28 215 0 R /F87 216 0 R /F89 267 0 R /F33 285 0 R /F36 271 0 R /F39 286 0 R /F81 284 0 R /F79 213 0 R /F82 283 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-307 0 obj
+351 0 obj
<<
-/Length 2522
+/Length 2467
/Filter /FlateDecode
>>
stream
-xڽY[o~R̍A)6B^`HŚ"emΜ$cmpf;#\"BW,2Xu $ 8*
-M$gs)U~&,Rl8ܔ{˶釢iϋz  \frf67: n\3uu3SYXhؔݶIb[-K$+3ɶMY-iX5jY nS- =?b^J/vSjBTao z@3wΪ$*u4r ]橔bZ!~ qK0/KŋnV6t7|qi\̿t j1-{ߖް^4l;nr>H`S#9vݖXBHX౪8II|tteknqbh2&" ~W,k[Ի{r(ݐ|wLTZkv Z]V5RǏI~_ܯ׺uJf+ 7CZnĿLa=Di|T);:gw@bC}[G˳ JujDZő8XV#$fuOʭtY:JMhn ̢6S[0<!F8pw9wi.އp?pӝYBsT?ImVz ĈW?ʓo4x[GR@MHId'4JG24
-Bed򆤯(N_>[4*;Ho8Әw9_ J8xo7$D3rOQ<H-}&j`%<OSIa|*{q=<OY>Փ|j)Tw o<[)$ QgvV2svg@l%SZ n
-i^lyTi%,S"Riԇ,_fi
-95d"@)
-x\Z2|8q[OHbH񰋭%7WOKxI?u;r<39z6Q&ȣ3^TgW(/ dLUx6o0k#~849}ΔB^q94?ʀZZ1?."\$,y?4 vϦR^Zl$
+xڥYMsFW U9a‡SݤjJ.[Ry0 X
+ Eu˶ngߖmbUo=v77Y:rG)5p9Aj"ʆ7o7%X%t<ĻX,|U\fA$ȭ_kѱI7W̞7(Oa9?T.l?hZ}Y4,kkD8,&/z_LcȒ{(>"Kڦ؄Omݡm&݇ƻRELƴ1^i8<jVFZYB^.UK65??@ 6qO!ih=F
+< RuiA45I/'vvG6LJ6cbFV_wV;kf O2"1H
+7;Tc W&T l̙3l'_G1olÔP2( vr_u!FRNRl6Ufh>9'~uuXo]fDWD}CJ'|~>ޜDSBz~TfRLon.J8֗OFRܼ|1^B ǥ̝c8h:Yc_p)LdVl=ߥ%}NЛHx:ps5mD‰" K'z;4,4 jnacّlyRA,Qߪc!ޖĩ}iewexœ=_Q< /R]&RFiH`U^yMpd =ܠʚ!///ڻ?
endstream
endobj
-306 0 obj
+350 0 obj
<<
/Type /Page
-/Contents 307 0 R
-/Resources 305 0 R
+/Contents 351 0 R
+/Resources 349 0 R
/MediaBox [0 0 612 792]
-/Parent 292 0 R
-/Annots [ 303 0 R ]
+/Parent 324 0 R
+/Annots [ 344 0 R ]
>>
endobj
-303 0 obj
+344 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [376.415 316.388 383.389 327.181]
-/A << /S /GoTo /D (section.5) >>
->>
-endobj
-308 0 obj
-<<
-/D [306 0 R /XYZ 132.768 705.06 null]
+/Rect [350.501 617.883 365.223 629.838]
+/A << /S /GoTo /D (subsection.1.1) >>
>>
endobj
-46 0 obj
+352 0 obj
<<
-/D [306 0 R /XYZ 133.768 667.198 null]
+/D [350 0 R /XYZ 132.768 705.06 null]
>>
endobj
-50 0 obj
+54 0 obj
<<
-/D [306 0 R /XYZ 133.768 171.826 null]
+/D [350 0 R /XYZ 133.768 392.402 null]
>>
endobj
-305 0 obj
+349 0 obj
<<
-/Font << /F78 192 0 R /F26 194 0 R /F89 243 0 R /F34 245 0 R /F86 195 0 R /F31 246 0 R /F37 261 0 R /F38 263 0 R /F81 259 0 R /F80 260 0 R /F79 193 0 R >>
+/Font << /F28 215 0 R /F87 216 0 R /F36 271 0 R /F89 267 0 R /F33 285 0 R /F39 286 0 R /F81 284 0 R /F82 283 0 R /F79 213 0 R /F40 288 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-312 0 obj
+357 0 obj
<<
-/Length 2993
+/Length 2537
/Filter /FlateDecode
>>
stream
-xڭZs6~_7 Lss^:}]8-Q'Tl7v EʰkbX|ai&<߿^}F$ge"bf5IeErlnה|J.gޖח?}&G:a+ύH˖'Ilnz][n tv4 -=.}]mû]SH:<_MxZscӢ?喹<KfBu[Y:m,.`Ȩ-Va\.wPzQ-w3#MȊX /MXgf$c܅I8X;G @ZgVPgL(%:1D2ߜ]]dJ8SF^tδɻR(M,f?L/#CfGD!u3!Z\by–@٭;Z~w[e1<S)rXj7ͦ7]Gݮ :ەԇ&/u[mosW4%٪l0)vvs
-vƛPv^*7P9Ks.ʦC/ 0Bx):eVGkp^f,H`|@grۯoK2Em&(7m9chST7 5YrE 3 }p `E[iV ,zC[pk'Vቕq&2X\88|l V1m8zR3ip0$j&!@
-+BÜ,F Z6?φOn+(ch@Hs[<ֻ`'5:}c [u^#` 3R^߂@*{m"I( !-IBTGv^1OǴ8슦- !;2BO$;rD"G3sz0f& '`\/eUGOnĄr쯂 C
-0'}-pG#Bd]U]ه^`+B*܋t:?X.-ȓmؓw_ƩomQaԣG`T v+M@ 2ZwaxGxG_@ף<R{91ee\jiW<!#3ÒUmmx-ʉ4| oC{Pg/F m?򅆢g09+ qֿqa]
-ɮf=B9
-\1~L{l6TY<nM5oOBAGiQUP˧XW󢰸|upF3z( J| 3)˅Tϔ)0\ &Af+侧j+*(2._"iN1GEabOБ1epxYSsXRX,_L, VW;q
-X8q[d[GӤLfYv0fo=\{Z%vG*1+R/@9iEdHs_n4hPE{e3_Ɣ9(mZ/q0 B# Z0Tڒ]`xR9}1 +9р!D` qTV\6HL Z~LsZ&A{!PJ˧>>Q~|znkxY@Ld2H NL%x "wc
-[c`4=]t}E
-!YPSSm_͢xz
-mu)be͟CSX4p
+xڽYo6~_ED(p{m-pw%$ږW7I7ʶm-Ţ9$gf,'9L~׋^l<fU.5eB7XL.wifï^N>?>?\қ<vjzuw9XHTJAďQ$?I)YRR,EC o{q@ ,Fz Lcc^LY8[aRs]}835^
+Ij|=_]^?O0Ĥ")۳5ӹ$FVFPC9|^аW<3$H̴W;x4x/lF8~p .[{=>TgIٜOgk=-^2
+z{MSޔ IR:(]m[rǰnUb=ve*]l ԘJ%ߏXm֨?8틍Ӟ0,i'p5JBe]
+kً32 {%A1s0;v%M,_,<'"
+(湭Sluэy+\:1o|>#^ʥ\Swۨ`^bm`#7>81y&bcxR279Y5>uw
+&Af<B ]L.yݬL:obM-[ L?c9O|d%ɥ"By]܌WզJh[_+:~Er^
+|EddMoT L2r}XzUoS[ׁeV@v<A6KM鹌<*ARcp3:LU'P&hI[7r^qB]zY .Xv/A4MF)Y=j+P"οi9"Z{Cҭl3B?(XJ޶dE]JN[*aM5 jv4H[BϊpcuW6qs֦
+<UDp5\Kɼd$`&icb@,Ի0: o/.9aЭiД#f"8h
+d7
++v jo u8PANfJ<&Ru|nL"q\a|YƦwFb-'ΒU
+.#u7c"X;mY2s?@ Q,wV99$ (fY3a
+3͟Od^u_q.KWO)p/pODh={
+B,IK ?dIU
+硂\6I4XQRNg\pOJ@Xg~GY}U W`F=b /iXe ώˊ)]ڢ 
endstream
endobj
-311 0 obj
+356 0 obj
<<
/Type /Page
-/Contents 312 0 R
-/Resources 310 0 R
+/Contents 357 0 R
+/Resources 355 0 R
/MediaBox [0 0 612 792]
-/Parent 292 0 R
-/Annots [ 304 0 R 309 0 R ]
+/Parent 359 0 R
+/Annots [ 353 0 R 354 0 R ]
>>
endobj
-304 0 obj
+353 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [207.049 604.433 229.521 619.177]
-/A << /S /GoTo /D (subsubsection.5.5.1) >>
+/Rect [346.367 542.025 353.341 552.817]
+/A << /S /GoTo /D (section.5) >>
>>
endobj
-309 0 obj
+354 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [348.989 380.217 355.963 392.172]
-/A << /S /GoTo /D (section.5) >>
+/Rect [162.003 246.776 184.474 261.519]
+/A << /S /GoTo /D (subsubsection.5.5.1) >>
>>
endobj
-313 0 obj
+358 0 obj
<<
-/D [311 0 R /XYZ 132.768 705.06 null]
+/D [356 0 R /XYZ 132.768 705.06 null]
>>
endobj
-54 0 obj
+58 0 obj
<<
-/D [311 0 R /XYZ 133.768 591.746 null]
+/D [356 0 R /XYZ 133.768 361.794 null]
>>
endobj
-58 0 obj
+62 0 obj
<<
-/D [311 0 R /XYZ 133.768 271.229 null]
+/D [356 0 R /XYZ 133.768 233.957 null]
>>
endobj
-310 0 obj
+355 0 obj
<<
-/Font << /F26 194 0 R /F89 243 0 R /F86 195 0 R /F38 263 0 R /F81 259 0 R /F78 192 0 R /F31 246 0 R /F37 261 0 R /F34 245 0 R /F80 260 0 R >>
+/Font << /F87 216 0 R /F33 285 0 R /F39 286 0 R /F40 288 0 R /F36 271 0 R /F81 284 0 R /F82 283 0 R /F28 215 0 R /F80 214 0 R /F89 267 0 R /F79 213 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-316 0 obj
+363 0 obj
<<
-/Length 2734
+/Length 2324
/Filter /FlateDecode
>>
stream
-xڭYY~_p٤ ցl6DHHef6O]4m9^>:HEQx#"MMt(K}bloOKJk?ve}S_{TZk⪻r7MIAUyb*؝iT;>( Aw0Si{y<j[㞷MӦnK'r8JRaVk>]HJZq
-N.ٞ5ʗ聈-xW`Ļ 0a@/
-E&C:-ȆzX9䩲jh
--h?`eߢ+x>|d\Ny$_[^' p
-OY2n A\\TueSƮ:`<NX{`XYTv^Il/4u[m!VI꧕-m'29pJQ1[zmbpDǴ.e|IRadaxs2[2
-cqa=_#4\Z<u?0@0ƑU`|
-e#$M\_zB˘0g^_7xJHh O2 /HQnNjhU|gwJ/K N8 U8J- &'"fp|,ɟawmpEIc
-f "NVpӝOT{05K37gi|D=;O2`zC38b74[\4>c8,x=!?N۠^ <pfr^Ȯ]{~ }t݁LkJe
-.y9BpsG8`, Fն<{hL:@,{`bBEl3Y$BK}ixPnJ/KBٵMͯ
-
-!a4 -tA|| O[8aysC' @Gs I:\O1huc&<G@ss@ܯxXvdQWL
+xڭYs_<X8|Li\s3DIHb;@q&bwv!pF]J. heiE\._e> ݺ8F>0@noybBE/Rܤ_UUZv9K6}X]}eu%fXʆ(@[:T.DԲ
+-OfQNf@UuRB">ӌޯKШ݂0* <=tvzE}>kmQYhd]] sv ;+'T
+og&,{\ퟯ7O8.хNjq燽Pj bG"
+3Ȩ̌Qf_3`0^
+ ]q]=H
+!.E9"!bKyq
+K
+
+K@N:H7"l>_5X)Ĵ9:(D3y& E#d2HLvѻ ! d,g?1@:Lp-?.DwڞnL"m /![ÿ| TJ8l3 {EY\"OrJ#ګbTˆ+F%J}dۀkmn֔h#*.R؞OByn5ĕ$)Q\x-I9dm.)qpoa_0WẮixL]C#vb
+;MIpg7XhA(/k@%^㾸y kc/#0w"|Lq_GDA5@k $|4Ta`^7ыwx%3}^(mVAoO ٩ >>=g7ɷ79Lj? lB
+`"PIZu҃L낃5]ſ" TIBTP6d!<iC,P2 nߜF<eK :
+
endstream
endobj
-315 0 obj
+362 0 obj
<<
/Type /Page
-/Contents 316 0 R
-/Resources 314 0 R
+/Contents 363 0 R
+/Resources 361 0 R
/MediaBox [0 0 612 792]
-/Parent 292 0 R
+/Parent 359 0 R
+/Annots [ 360 0 R ]
>>
endobj
-317 0 obj
+360 0 obj
<<
-/D [315 0 R /XYZ 132.768 705.06 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [318.942 432.236 325.916 444.191]
+/A << /S /GoTo /D (section.5) >>
>>
endobj
-62 0 obj
+364 0 obj
<<
-/D [315 0 R /XYZ 133.768 667.198 null]
+/D [362 0 R /XYZ 132.768 705.06 null]
>>
endobj
66 0 obj
<<
-/D [315 0 R /XYZ 133.768 281.11 null]
+/D [362 0 R /XYZ 133.768 308.911 null]
>>
endobj
-314 0 obj
+361 0 obj
<<
-/Font << /F78 192 0 R /F26 194 0 R /F89 243 0 R /F34 245 0 R /F86 195 0 R /F31 246 0 R /F37 261 0 R /F80 260 0 R /F79 193 0 R >>
+/Font << /F28 215 0 R /F87 216 0 R /F33 285 0 R /F39 286 0 R /F36 271 0 R /F81 284 0 R /F82 283 0 R /F89 267 0 R /F40 288 0 R /F79 213 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-322 0 obj
+367 0 obj
<<
-/Length 2565
+/Length 2324
/Filter /FlateDecode
>>
stream
-xڝYYo~ׯ`ިXlknb/vl
-la]lL"$P$I{'sy$sZ%U!Ba.#+Hh)ldU`$V37Ht 7tT2,DzwFF
-2)KB%#ŷaquyIu2,S1M)ʅLeMWY|ZCz]ųPv\pPcBah V4xwf3<܆'iDV,YϙS@ { I ʋ׮ڂ+ssĂ3Pu&h2>qA&i!v5pԳ9tU_׼q=>4f{1/+=
-TޅODUEW{_jb ս.ɿ~9<6^gU&[J ,uH Gh,Jl8:v8V{o/{+fE ݸv}<L A̫Š6ڎJ,T=~_=Kb#b 9Wm}HJP@-2M57EvRU]YSn9z؛a&=f:H4J.L^9eG%-žL$ά]4LȞm@?[OfJ5s7E&drta覆},GZxrfQXlA|AޔYLy;]Y
-<D,9 W&᝺B 7J>aE͛Fn^0I6#V
-[\6Œ3) !f@^ʴdD)WL_1Su. k
-@R$:z\-}|k -ŧ=Ң玸G@B
-(+ OrA9@n햖}GѸnN]gh g
-1~0Uw\`WOrI*$yIBr>K$G:tO>֧.%jl>Jja E7'nX$׀%$* oo Ūi1Yoh@Cͩ& '\2+un8i+hwj@Ⱥہt&?}A5]Ga}
-?BV(7a<-
-O?WzAۂsVGa'.@n.aAh>O5s;7 DϡGF-Nl$Cc1ӳyO_+Յ֧o=
-tҿmW=mS0;
-=g lZF,}
+xڭYKoFW0@`qf֋Y`,DYD$R }ѤHq09k2O<Uڟn>ܸ""+&JeIeurL/BH~֋r&=Ǿ.w<XW +ӲVɴp#}RdRLn+uTu]>'ς`eA҃kX)\ڴ=<f!]3e(NUX:T?|(`:rnB|)HPt0G*}VNJ.4oϋekmPǺ 3&Hq\)`ؠ^ґ b~pЩmRk~B*OrРjP%c# IeO+m<n~إ]ezh~*
+".%wUo2HbĦ_NvUى_-؛AS؁t%7SBDj_!yt6.fD qD<E0b<Ek7:\3U#wb BcbhpyLTC ME搤 DB;pd+Û?xΡfS0= $\܈9dhMzŴYD
+{\.)1gB~-:"m~GOeǃ`s0>u՚Z ݏȬ=<g `2| bf5cԷ{(r«PcTs=8 q(9/ָ`kq kZT ZSNWb/{G{Q#JS܎=DWٷhqXNx*>+mSCq Dk\\[)hlV=î̲T& 4#'W g"Ϲ4PVf֎
+ª6ȩ -Ga:Fh[h#r&kK$um6ltn3[ xf}|c%0P!a⢶-68&|b/\! (!
+!'gj/9yF^$0p7m=qxzJ4?+ϒ(9o|
endstream
endobj
-321 0 obj
+366 0 obj
<<
/Type /Page
-/Contents 322 0 R
-/Resources 320 0 R
+/Contents 367 0 R
+/Resources 365 0 R
/MediaBox [0 0 612 792]
-/Parent 325 0 R
-/Annots [ 318 0 R 319 0 R ]
+/Parent 359 0 R
>>
endobj
-318 0 obj
+368 0 obj
+<<
+/D [366 0 R /XYZ 132.768 705.06 null]
+>>
+endobj
+70 0 obj
+<<
+/D [366 0 R /XYZ 133.768 667.198 null]
+>>
+endobj
+365 0 obj
+<<
+/Font << /F79 213 0 R /F28 215 0 R /F89 267 0 R /F36 271 0 R /F87 216 0 R /F33 285 0 R /F39 286 0 R /F81 284 0 R >>
+/ProcSet [ /PDF /Text ]
+>>
+endobj
+373 0 obj
+<<
+/Length 2531
+/Filter /FlateDecode
+>>
+stream
+xYKϯO`v7酁ĆǰHvvG$&(Gru7UUWU#]$ndTFȜv6RY/&z'"jR/iat|i˼XLjjIܜuy[ie4O_ttV*&OUe>?B5UʿxF,6˼0JݾI$J IV$F_XW3VxpD>-t
+nW4m-OMQw/bdH5tgU&YheࡴUF%2@WܮN8 `+m|̉*E{]롸Ro.?Eq|+)tqhC&s]2ojx U'ܩ-> "]>Pa<lQ|̏Cx&štGXW{+XJnK̞J ig
+l^ֱ9=>i*2缌ˮfH[dY[&t>h%ɄȟSkݓtʦzŎ駞הu~@62> 6+%(T8ƦC;Vr]Wv;#@LffK\4LءEgQClp#+4/'-S豥דj"fӜ5pF
+{Y+j,XЯZ>6z*S3Bj&TÎ&ˀzB$ "Ϗb.NU'XWWԮ>{n ^s W(wX'HQ:4Q #G8<@:u
+KnVSkL^R?vOd&N
+﯐7㖹 ? [|u0^`A/(raKݮ8e'
+C`K2T ~Ri`0@Gi
+ACQ}={,\K@>o@Vaq@ƉMq@iF@+eh]iTd.2`]vmp6GRT
+n8\)p{a(7Yۅ*
+endstream
+endobj
+372 0 obj
+<<
+/Type /Page
+/Contents 373 0 R
+/Resources 371 0 R
+/MediaBox [0 0 612 792]
+/Parent 359 0 R
+/Annots [ 369 0 R 370 0 R ]
+>>
+endobj
+369 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [362.268 531.006 369.242 541.799]
+/Rect [333.902 384.464 340.876 395.257]
/A << /S /GoTo /D (section.5) >>
>>
endobj
-319 0 obj
+370 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [320.13 519.051 342.602 529.844]
+/Rect [257.555 372.509 280.027 383.302]
/A << /S /GoTo /D (subsubsection.4.4.5) >>
>>
endobj
-323 0 obj
+374 0 obj
<<
-/D [321 0 R /XYZ 132.768 705.06 null]
+/D [372 0 R /XYZ 132.768 705.06 null]
>>
endobj
-70 0 obj
+74 0 obj
<<
-/D [321 0 R /XYZ 133.768 493.842 null]
+/D [372 0 R /XYZ 133.768 667.198 null]
>>
endobj
-74 0 obj
+78 0 obj
<<
-/D [321 0 R /XYZ 133.768 394.988 null]
+/D [372 0 R /XYZ 133.768 266.926 null]
>>
endobj
-320 0 obj
+371 0 obj
<<
-/Font << /F26 194 0 R /F34 245 0 R /F80 260 0 R /F79 193 0 R /F86 195 0 R /F31 246 0 R /F37 261 0 R /F81 259 0 R /F82 324 0 R /F89 243 0 R /F87 231 0 R >>
+/Font << /F80 214 0 R /F28 215 0 R /F89 267 0 R /F87 216 0 R /F36 271 0 R /F33 285 0 R /F81 284 0 R /F39 286 0 R /F82 283 0 R /F83 303 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-329 0 obj
+377 0 obj
<<
-/Length 2928
+/Length 2428
/Filter /FlateDecode
>>
stream
-xZKsWH-"ݚ2iSq-QwPHʶfj{
-t@VNh#}^yUaOoUq_R*zKߒ9 tAnJ qj KX[$@LI !zmVa5mۼCK>_QW2-v
-lt2nTb<&خiJy(YzlRE^\QƨI9J;UᘩU2uSFO&[,Xq
-+K%C憥!)k/cnsW;Iހ|¤cpB1yp&:8m1s|3\R2vIB^b3\ұ? 4u!Tw8)2_atYPkXw2|^i
-t
-2!~뿦L =%0F07} Iṕ>a~I(;4?!9}=30>q@9Ѡ1(!AQ2(ĀQ,(
-/PozW
- J P=Ea%80lZiM^91*Lq q?;㿎I>}
-i֯CW
-:5^"œ 1a
-J8D-0q
-禪2z- Z1>OMiD-۵*7M7gIJџ;(:]]g{H
-tXDOX)pmN uaMfP1-lGSnwCl<0tuAs3)hLˆ4zrJs󄽕e,..G#lvpҸ mY&=+y6;ܓ찶ΪbQk|(@T&> uײ}_sZdRq 0Np V,Hw<0ڗ.MىsYj
-Ҙ=^}{2]肙]&*Ѵǫ5e* hCu'3``T&'Lf^f&1~rmjf;HOR o!rG<W'W{Up}D)`N H-_)=r
+xYYo~輩c7Y 2N x<ܭK1b:tC0Q㫯8|q?qٻ˔/22^\mB)"6 ,6H3r%чmJ*nysw2l+2fPm+e)Ө9P7u}m`ɸMLbRFDE<Y,شrGƺ뜚UjG2~Jl=
+ KeƩ 6ka;(ǥ^VEwcRDrjnh6/]+m|;C9][$7VnJ`l,hrWt4ٙ܃eJQ d8cO/VYWV
+_+FnYmgR{XM5*1%Zg)UVhd΄I^zŅ (/LpY m{KRD
+\ _ˆ1p{AA`"Ckd/^.s
+x9Syr**&?їCkЗ
+H^'T HH߀Hٔ)[Z`{OmMXގP}IʜqGņVX`C_ק\;+(z1'b(rq9Եfc![ezDl- ]f@o gwo-~!TR9DD]NlA4#[Av48'\4 -\31|]A=:"F,RE0a, ĵp?4nC!xJ-^Ñ~1ܣT,P}-ț!/dq6mɦ\&P~*7T p(⹻X>^yzB/)]e:'.==,.ąqq[F? Y]u^b~,U=
+V(
+>``
+MOvjHZBA3)I9b%-5 ontKr,g'{Pӷ
+a8 09X_ K%yL^KԘg)
+ II
endstream
endobj
-328 0 obj
+376 0 obj
<<
/Type /Page
-/Contents 329 0 R
-/Resources 327 0 R
+/Contents 377 0 R
+/Resources 375 0 R
/MediaBox [0 0 612 792]
-/Parent 325 0 R
+/Parent 359 0 R
>>
endobj
-330 0 obj
+378 0 obj
<<
-/D [328 0 R /XYZ 132.768 705.06 null]
+/D [376 0 R /XYZ 132.768 705.06 null]
>>
endobj
-78 0 obj
+82 0 obj
<<
-/D [328 0 R /XYZ 133.768 667.198 null]
+/D [376 0 R /XYZ 133.768 667.198 null]
>>
endobj
-82 0 obj
+86 0 obj
<<
-/D [328 0 R /XYZ 133.768 270.143 null]
+/D [376 0 R /XYZ 133.768 367.371 null]
>>
endobj
-327 0 obj
+375 0 obj
<<
-/Font << /F79 193 0 R /F26 194 0 R /F86 195 0 R /F31 246 0 R /F37 261 0 R /F34 245 0 R /F80 260 0 R /F81 259 0 R /F82 324 0 R /F89 243 0 R >>
+/Font << /F80 214 0 R /F28 215 0 R /F89 267 0 R /F88 255 0 R /F87 216 0 R /F33 285 0 R /F39 286 0 R /F36 271 0 R /F81 284 0 R /F82 283 0 R /F83 303 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-334 0 obj
+384 0 obj
<<
-/Length 2950
+/Length 2499
/Filter /FlateDecode
>>
stream
-xڥioݸ7cDR,
-.6٦hc]@-dIV(X#3R3M1p8KޅB;~yHv.;.%SIKbńwC~<KQUj~_KӘ8jϟ/~Bqx9țj,s@" S\x% Ɍ }yB>I]Xw@zc\mb =,x$ȇ:j*)WFdQ%`*4-*p
-n-*k`*i,ԐF}IX-\m1rO#U*#~hJZ~ PWQ&AŮ4_&+SC`@8pMp͑,
-1/6X_ux"g2 ~tU$-Jf+YSQ֠v(A̢4tS_ߜr*#]iTLWÈ+FcfUc5VD=yGJR;(hcgsxdže5ƚEd n@=n3A~]e[hQ6z:t1Ǒv㑤[y <Á%CBҗ`=*0F'VaXk3 u<.S%w
-N7z]P$ J +.9:wDO gF@q"'hqCjU&L={"]H3z4nIfIӨnh68dīR4- -!7* D1]QxyX{>:1R,Ts1$~1f(6t8%AE=6-K"iZ Z
-V&55@ >Neg, gW˨ɧ1 MJtXo5G&B/}$y2>CEi4mPpn$d(&z#b؛z[!.6Í`p3T@,Au9>}1,6Qi``kas{v jMKji
-A1cv7|Q_rQt^?vz ZOOppx+|y2S_ąGK!K Pz.? ʄd96[8k+/Γ٦<0-";XqShG1v$!
- 8DKEA,"&T۔A$ZA17R4aF<d CsbJa!oyIe:d3,/06"x;eOm%Ydzn5qFw0~xr
- Ojsgmh:4|X(- ]KukdZTƶvvZpXFr`d8 @`ڄԨ+
-
-šoU769F< wԤ-l5$o4 ߰ލI53ivg&ܗ@OŬGwQ$ɔ/"{ђƔEswJ&MC37~St ZiS2V|2#΃{qfImYJcݸ'WUUjz,mR•qS`3ris'+HP')06m
-9~4#V$NjFp)j᪫enVz˓Ԝ4;} ۙ2QDhl~K2hʰ傲 L7RmŲP$8Nuf4B-Q83G'Gۼ
-j׵I*UQj[mEāpK?lR) in+U}gKpX8r|c{}tDLW("=8.py{QE4
-437˥A4fh`9g5L019Jg
+xYKܸ ϯб<MQԦjTC4zk=f%gSaڞMC.->@
+y/bLbiŸpx})d}kwj ODeS*K4aO$K
+T&*+
+<qCle2O36Z1N)rM
+T< ikyD& >÷2VRDHC$@EpQ(5%Rzup,mvm|8Po^=eKaq| LM&IْМ\%@&`ߜ/PАKDunꟓoO hEʸ
+axWe[ҁԦE"ѕl0rkI/A%?qpW$ؿF؝(l"]A* 4h
+ 6R=H XN&
+#$Xaa8:%695xMyOs٣R3f t`weTe3@'*]'6gưBe.d_>=/^=:zT؝Eɠf) ꯾W"MΔs
+Bc#uə
+S+U׊Tb K_LHEGƌhJetyٽ B>ޔ%
+G JʮE 5楈S 5]]@tjwUno. rv!CB" mBxp ѱ!=H􍦱pҥPQ#Mj7TM6K}Qugʊ`[#!>@y[wC HTɖrW NX
+aNBC>/Vo.<f\_HInɝܰKtA#׻ʟ7:ΜA075#=@'PPQn
+Y M?tXīC
+x(Z|%Cs}HirQ$/i` rO`x"XRNOҵBxSssBsnq/
endstream
endobj
-333 0 obj
+383 0 obj
<<
/Type /Page
-/Contents 334 0 R
-/Resources 332 0 R
+/Contents 384 0 R
+/Resources 382 0 R
/MediaBox [0 0 612 792]
-/Parent 325 0 R
-/Annots [ 326 0 R 331 0 R ]
+/Parent 359 0 R
+/Annots [ 379 0 R 380 0 R ]
>>
endobj
-326 0 obj
+379 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [423.762 617.883 430.735 629.838]
+/Rect [423.762 186.566 430.735 198.521]
/A << /S /GoTo /D (equation.2.1) >>
>>
endobj
-331 0 obj
+380 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [371.62 580.609 394.091 592.564]
+/Rect [322.275 148.715 344.746 160.67]
/A << /S /GoTo /D (subsubsection.4.4.1) >>
>>
endobj
-335 0 obj
-<<
-/D [333 0 R /XYZ 132.768 705.06 null]
->>
-endobj
-336 0 obj
+385 0 obj
<<
-/D [333 0 R /XYZ 133.768 596.051 null]
+/D [383 0 R /XYZ 132.768 705.06 null]
>>
endobj
-86 0 obj
+90 0 obj
<<
-/D [333 0 R /XYZ 133.768 420.027 null]
+/D [383 0 R /XYZ 133.768 425.614 null]
>>
endobj
-337 0 obj
+386 0 obj
<<
-/D [333 0 R /XYZ 133.768 299.847 null]
+/D [383 0 R /XYZ 133.768 164.157 null]
>>
endobj
-332 0 obj
+382 0 obj
<<
-/Font << /F26 194 0 R /F86 195 0 R /F79 193 0 R /F89 243 0 R /F31 246 0 R /F37 261 0 R /F34 245 0 R /F80 260 0 R /F81 259 0 R /F82 324 0 R /F87 231 0 R >>
+/Font << /F28 215 0 R /F87 216 0 R /F33 285 0 R /F39 286 0 R /F36 271 0 R /F81 284 0 R /F82 283 0 R /F80 214 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-340 0 obj
+389 0 obj
<<
-/Length 3001
+/Length 2752
/Filter /FlateDecode
>>
stream
-xڽZ[~_hq֌H%(PiS iKZe9Mu\_, |3CUU_^}䫜ZvťdFەV Vwɷ}WZY2t͖uk)u~wO%OlaF+P,)s۞ZItU^hZW⻍ݵm֣3Fs(ڪ۹R3#H}Ҋ9vj9UʾQSi/L4(Hj`NdtdQBozt-3Tmٸ6 2>kv'T4KVB3, &`Ǎ ڄLkqou&{WzY_}V*)vC76y|(N> QGq qypuqp0ڎӵ&xc>^J?mO}Ի}W5OTodw fʲd%;oi'۟X+lefpnF Gzo5[?<c矠3˝N%m6n_Yh|qNxɖl2HMFt a,7#d-+i<Fq>@1lf4bT\2Nw8='0hD *|SLR#NY3ϯ\p/yqŤWtWҠJ03VW߽KWx  6ݮ=iʁąV^XLp1Z)=)Wc-zs(HÙe"V]"@cgB^p&љ02 rE`I
-dgFDE`ܥe28Wp`̷ˢ ψ'W^+=pЦmvxa uБj[]c4Xr޵="1'LkۦEQi6(Gzj!>PRe_~Sݰq馠
-|AS
-)Xq
+xڝYo b̓ddK
+t^Qu)P Wx={<=yb"hi^DR#'\ݬՏg!_T*Qfu[I5V(XoAw<7* lv٬-k
+=/S-?Zm_m_f}I*_&OTmMu՟\&_F"H8mv@٠컢B>m@^7HhD$"Ym\c^la_;YY^oxnk>BzzX+2*/ںMGt\=E7Ԁ9vj :p Q<nZ#-b{rP)}SNyVlj ƢPpar˛bȊ:cW
+#R'o\Z&M}z,@2o.&K8\ 3J&|?WjoVǏgR(<xd+܀m9jŝmy$€bHAHx*TDӕǯ:8\'h[1UqA~!ОZ"D6J\Ψkh]~L:^/w4e# 'RxL2{U:hi\)X`8$q`K":tjVRyv`<DR,\Q:8%Wga+Bch$Ϯ?-,
+
+F
+"Ȯd?֋De 0Oi҈vHuppO;w@1 %2kE΀IHi•;Ĕ0~ Y>-f9jHB;ܹ?LM(xjDT$xۻxe&hl7Uz/)vL2
+hi)<4/ Hm=uqJMW8N .p%a-on O"8vqkjV(.#TN,Q͆}.- ɂiz>̡9t#y3~1zr{="" M6βhB>5Yr6H'aT _V/m5L'W_hC>J;8R+ER.$&-bM [ȈHijK۬>,&xGT5솟3V9 LP9%2@Z3X3+2ǁPl'EEcYV1C܎p^Fq8/jnSޭ'F7ruŷYIuǺ.u}0z,js*I;CD=U/ca.[n^%׫74>H3-"`*{1S:}z
+LZAPz9ԅX I?,EɳK*}yL6;+RúBPݳ ۖ[찅3^]!%U4N6G-x0
+LÂ=L..! "xHÅFc"P8֯:nO)@zk- 7)[3w4rKE⒫%?<knۢ<pSx϶qm qe^Ǫ/]9g'7fB=Jj iE{=
endstream
endobj
-339 0 obj
+388 0 obj
<<
/Type /Page
-/Contents 340 0 R
-/Resources 338 0 R
+/Contents 389 0 R
+/Resources 387 0 R
/MediaBox [0 0 612 792]
-/Parent 325 0 R
+/Parent 393 0 R
+/Annots [ 381 0 R ]
>>
endobj
-341 0 obj
+381 0 obj
<<
-/D [339 0 R /XYZ 132.768 705.06 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [387.746 605.928 410.217 617.883]
+/A << /S /GoTo /D (subsubsection.3.1.2) >>
>>
endobj
-342 0 obj
+390 0 obj
<<
-/D [339 0 R /XYZ 133.768 669.191 null]
+/D [388 0 R /XYZ 132.768 705.06 null]
>>
endobj
-343 0 obj
+94 0 obj
<<
-/D [339 0 R /XYZ 133.768 458.243 null]
+/D [388 0 R /XYZ 133.768 499.17 null]
>>
endobj
-344 0 obj
+391 0 obj
<<
-/D [339 0 R /XYZ 133.768 308.918 null]
+/D [388 0 R /XYZ 133.768 365.934 null]
>>
endobj
-90 0 obj
+392 0 obj
<<
-/D [339 0 R /XYZ 133.768 161.608 null]
+/D [388 0 R /XYZ 133.768 167.073 null]
>>
endobj
-338 0 obj
+387 0 obj
<<
-/Font << /F79 193 0 R /F26 194 0 R /F89 243 0 R /F86 195 0 R /F31 246 0 R /F37 261 0 R /F34 245 0 R /F81 259 0 R /F80 260 0 R /F82 324 0 R /F65 273 0 R /F78 192 0 R >>
+/Font << /F28 215 0 R /F89 267 0 R /F87 216 0 R /F33 285 0 R /F39 286 0 R /F36 271 0 R /F81 284 0 R /F82 283 0 R /F80 214 0 R /F83 303 0 R /F88 255 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-351 0 obj
+396 0 obj
<<
-/Length 2744
+/Length 2688
/Filter /FlateDecode
>>
stream
-xڥYmoF_o
-'4 'V2 TLkJ̼N\ +#ˢR8t&A$ZL lEٻIoI@֡UٿI ^F &O4eEjH pLi3FD~Fx+؁&OXT%jF|/T ԔS"Y󰑬p΂d.‚.U*bxS/ګۖ-Vy[(44{4ݶسm%J[c[^!Rg:V~D"*)oyOEXlhN\p!%2`-%xRpJ&I.'ZF^] 69|3d|߷EJAYž+<}pYUuGS ;V$idhV9RŪ)6/{JA'&1|2Ūl \g64w l͡ZrD}3u
-|"s
-2؎w̝Դ.$2@|w] tuuDU
-4WVNLW~U%/EŌ@
-̕Vpă~ߍO܉j7ℂl1 UcF T +m A SPK!e+{|Z. <mq [7_;sCP!֛Q I6JEx|hE-T)n/
-i˧ fuѶPh\CLP!ӥ2 W==_Dsڕc %wkss\s*&7 Ɇ=Sy*lmgz jg}<Yv8Od.Mt6!PXq> +rIIr!rse@>$9$pwJw4==5
-Guv"ӓU@5WUdLT g0:&daU۲<pL6AAe;"<p[oyf4')Pd RNv+pAXCsi9"Op&bQ2 zy
-M Rҁ?B9h7Aj/L蟍 hs/ %DH;2\E*&\ᄄp[CR?~"0ux=eLi*5YWxTh_' o*3 '?qrԟ*ì
+xڽYmo6_ok#*^(p({wzC)W7q{CavX93̌_7ohxI(v!bD#O*,- [f)ݻ{_/R\ڼŇՁ?&VR}R^#HeΒ$3x &ѬE<Z
+/9" S<HM%ByD[K$fDlKHyB%PGL?cГr܈uJ(OD_T\|EC0:5D<舕>|F˃О
+S xs}m/B+Ax_lǕNj{CY-pSĭ\|/v#FV0%`Jk.\#<iW Wt$ |a?cGȈ<Q.-iIC&D&&zD2)(Sc*ld{ZJ/]E,a%eccTVZ,ڱ?vE2:SJ6uyMt 芎'ohVHoJ}O Pa I=m^-N[߮7bg޶M끋bE7 @Q]#U]0HRV&A4>:bcI,Q _n
+"W wi~ۦAV22A9O`&:QMI>..ɪ-~i~M 9 MR]@*@j-&tx|<<3H7}ܾ*5BE>n"u^,q \&΂5dDS&Or*t8 .QA01 +fL^r$^sx
+#pS_fA ?'±<gpvv`u`
+k
+rwǩ;2h~|"@ Rj+Lg3\vu
+
+c")0#F"v`$EZ;QՎsFņL_uP$pUD.M8zMITrT*DkzAH'Ͽo,P,FS4|mF9F[SA
+9V|H'GǣR.HCl B6DsPDMF5v8z@q`:WD1>QvmqٲVd̬
+ANt^Y򕧃5bxcJ!iΉa\>C?:jJF:/
+t({Kx!ctQ /F0NsmLsbVT0Tzbćިz}1x ?o9S2GE|WW#&ʢ?IWUSO}-obP<f.3kCn8j =
+n<=%P<,dEvBJ_)1TDY4d N3"KiCtJ 0&&Ukp?-x $V#qSL\/+J0hcQw "%ڵ,1IzZ*j^qcB@r6}/Q&@w׮=[->l±W3~V!MEE-,DϜJ a&2}
endstream
endobj
-350 0 obj
+395 0 obj
<<
/Type /Page
-/Contents 351 0 R
-/Resources 349 0 R
+/Contents 396 0 R
+/Resources 394 0 R
/MediaBox [0 0 612 792]
-/Parent 325 0 R
-/Annots [ 345 0 R 346 0 R 347 0 R 348 0 R ]
+/Parent 393 0 R
>>
endobj
-345 0 obj
+397 0 obj
+<<
+/D [395 0 R /XYZ 132.768 705.06 null]
+>>
+endobj
+398 0 obj
+<<
+/D [395 0 R /XYZ 133.768 473.416 null]
+>>
+endobj
+399 0 obj
+<<
+/D [395 0 R /XYZ 133.768 308.959 null]
+>>
+endobj
+98 0 obj
+<<
+/D [395 0 R /XYZ 133.768 161.608 null]
+>>
+endobj
+394 0 obj
+<<
+/Font << /F87 216 0 R /F33 285 0 R /F39 286 0 R /F36 271 0 R /F82 283 0 R /F81 284 0 R /F83 303 0 R /F28 215 0 R /F89 267 0 R /F80 214 0 R /F67 291 0 R /F79 213 0 R >>
+/ProcSet [ /PDF /Text ]
+>>
+endobj
+406 0 obj
+<<
+/Length 2416
+/Filter /FlateDecode
+>>
+stream
+xڽY[~_P湓
+8mH ʕc\Ԯߜ9H-w7>\̙o4臋?]]x(Or+mtIf]dK2:zJY,4~67݇4 ^mˮr"~xw+FB5*x$&ioS#,4I"Ol;&XNeL6R 9MC<Z>W.TI#I̍Re_yFklRɢ{OM0E;_DKc'eL]&
+-ab.%ӉʫT9BT=< ;}"n`%LUK.Q 9dܨǽdk |%d6~"`#M\ /zTNݶjy*ڒGE9!h9~B7 -Ub4"^&!2=Mu06.:,.B`a{Z<jѶ@ueЌOzs{JZ
+។BLmTy(kUԗt%eKIЕ|=/]/?䓜*ˑ:VMܑvIweJ#HP$*7=\PnnŒ;PU6mo@dJW1>pgj>mTc݁ɐ8W7/ݡZudv,nNR] n|
+g7e TUA_w|hzNE)-\+_[1^7~ǍLz)*CB羓'GGKWI]~ӌLnj\&1޴.úRd!fbkF!nJ2nRpںS؁#H;O05hx+tɑ5yU[7S[fX؝!qU/'>ؗ(JV?O)<痿< 190= L"u d&qډāz(@˒
+ G
+Իj+e4Ux(*I.NO!+)6#JAw38a
+$E|b2&UjQcMi9ȶӼFw$
+2T9)#M=`%-&9kTϸ&RPȔ~
+#&R[J*!A%kjQ\+*,5#S?{G9@djSY7,(v5aÇ(-}EmAHU Ї3t' /c[&^"2n}_%hUʳ.qdVA*<lJg譗Ѵmu`:~
+<G <n=_X:
+T4|:J^_f\#O~[W*-KB?Թٶ}D*Q'ЭntˢFONNXJu!Mr Wg
+RR]ŨWRsfYŠX6mDdZt¡4/㌼Cb{sXWu3ߔ
+endstream
+endobj
+405 0 obj
+<<
+/Type /Page
+/Contents 406 0 R
+/Resources 404 0 R
+/MediaBox [0 0 612 792]
+/Parent 393 0 R
+/Annots [ 400 0 R 401 0 R 402 0 R 403 0 R ]
+>>
+endobj
+400 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [236.107 572.512 243.081 584.467]
+/Rect [206.059 548.739 213.033 560.694]
/A << /S /GoTo /D (section.5) >>
>>
endobj
-346 0 obj
+401 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [153.548 298.534 160.522 310.49]
+/Rect [467.627 238.439 474.601 250.395]
/A << /S /GoTo /D (section.2) >>
>>
endobj
-347 0 obj
+402 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [160.574 145.391 167.548 157.328]
+/Rect [160.574 145.168 167.548 157.105]
/A << /S /GoTo /D (table.1) >>
>>
endobj
-348 0 obj
+403 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [472.014 145.391 478.476 157.328]
-/A << /S /GoTo /D (Hfootnote.2) >>
+/Rect [472.014 145.168 478.476 157.105]
+/A << /S /GoTo /D (Hfootnote.4) >>
>>
endobj
-352 0 obj
+407 0 obj
<<
-/D [350 0 R /XYZ 132.768 705.06 null]
+/D [405 0 R /XYZ 132.768 705.06 null]
>>
endobj
-94 0 obj
+102 0 obj
<<
-/D [350 0 R /XYZ 133.768 492.622 null]
+/D [405 0 R /XYZ 133.768 444.855 null]
>>
endobj
-98 0 obj
+106 0 obj
<<
-/D [350 0 R /XYZ 133.768 351.793 null]
+/D [405 0 R /XYZ 133.768 279.743 null]
>>
endobj
-102 0 obj
+110 0 obj
<<
-/D [350 0 R /XYZ 133.768 178.724 null]
+/D [405 0 R /XYZ 133.768 178.501 null]
>>
endobj
-353 0 obj
+408 0 obj
<<
-/D [350 0 R /XYZ 149.011 128.717 null]
+/D [405 0 R /XYZ 149.011 128.717 null]
>>
endobj
-349 0 obj
+404 0 obj
<<
-/Font << /F86 195 0 R /F31 246 0 R /F37 261 0 R /F34 245 0 R /F80 260 0 R /F26 194 0 R /F89 243 0 R /F78 192 0 R /F87 231 0 R /F76 190 0 R /F90 266 0 R >>
+/Font << /F87 216 0 R /F33 285 0 R /F39 286 0 R /F36 271 0 R /F81 284 0 R /F28 215 0 R /F89 267 0 R /F79 213 0 R /F88 255 0 R /F98 311 0 R /F95 313 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-358 0 obj
+413 0 obj
<<
-/Length 3015
+/Length 1948
/Filter /FlateDecode
>>
stream
-xڽZoBo,oJ hK
-E6~(A^^5Zi#i~PZik@_,K 9<yLxw<|{i>wP9%8&ItuCuQZ}T7"xcLZ72KGo~Y r&s<bDZm?o͙r\V} llZF@~P8g҇ =A.]oƪo)&9˵N6B܄ݼJ:3,m6c'Rqc@ [<FJ}E*
-4T֠^ ?ZAṉ̈VJyGjCѐ6Z}'/4QuP'AcH7zUL㾛F+ׂw- Wa}]7aR\ĕd5ѵfNg=#?5# M1vކ|Bg#xV=r;%VሕVG
-CC ,;2
-HŌcr&^ Apw7eb˸:EȢ%S<(н ZQB *9$GhLCfc gVŠsv$ۀÜ?FM0FK|FE3Tq4p=Mݴhz]|voQc:3}ܐIDo89g_b!|@qHZ8(FXc
->v&xVzW  ޤ=A+V:uFyƔK>&0wQXK` =őoVp[|uE'`{y]'?ta'f6(
->pfOʗ=׼t*\TU_cQ\Th+Ad֝0N`ܝAHg,ޜ:Rhac8j`֮8B
-M&FTM-dbKj`uUaۊC(T^xWk_K@Lr{DY5%zs
-otJM> DJ4E-^E) *⋶,S3C-?Ǯ`m̜FKfA ,sl۲#=%뗜`06dU P
-7H<K\X}ng"V0{\ɯJ*nV"IT495<+}zU~a._QL˧& ܄7&XU 7(Ι;賧_@\8%ku,_9],4-}'"V)3!7وifxof?ʽ1b
+xڽYKDϯ g釻f vg̊2nzWgx x bysAR#M\R*f40qe.V]U,"T(>]+lHR\bXMu> -\$zx4,:9#$gLS#/7X@"̤kfv7ʃ>~pIp)@I|৛ m$Ib ib!BA$6Ua"-Kq%N` Sfu;toSyB&Lg|щHꋜT<92Ԟn3IHBlm91V1bfP 2l̤jJL?z"BO@FW0hjO5w0OI$IE좾hwő|q!xy,f]bJ "zZ?<QT{cM+TI)&2rŪ Ȋ8=D^+OsZ ]Yo+T8-!V4l}P=ObYf?p׭ڨF8
+}T)USo"]mtfWz(j$1uilXgUW\]:^EeU%W֟p
+g8΄YӇuӒ66=aL
+G x^As?Zqw\jZeiF^nz4p>&Z hE=Lddg8D8MX5O6s-nP8s Kp3Ξ\SR5rߖ+v6mAr!m
+uM;=I4!JU n>|-j% R-,;5N[mo}iM_W
+Q򔀠f
+hu~KG{{7sX*붯 B)c)H=lj0c8J䔙I7 D&fIH=ggD_nǯs;lzp=!1"
+/bFQ"%>gD*wIGo;!\}[
+61C^UĂsI/>W;ѣgc0˞87^@ɱ stj,6br!) =h—+5$֢+ Pq;* -vE.&/yuӢ;@q4M {2ReH-0 0iZchu~r? :5t}"9``\"JXrP`u`G%g'xs) 8vW _-S^lYh8Bi9Cz@BvpV
endstream
endobj
-357 0 obj
+412 0 obj
<<
/Type /Page
-/Contents 358 0 R
-/Resources 356 0 R
+/Contents 413 0 R
+/Resources 411 0 R
/MediaBox [0 0 612 792]
-/Parent 325 0 R
-/Annots [ 355 0 R ]
+/Parent 393 0 R
+/Annots [ 410 0 R ]
>>
endobj
-355 0 obj
+410 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [195.639 474.974 218.111 485.767]
+/Rect [177.402 208.913 199.873 220.868]
/A << /S /GoTo /D (subsubsection.5.5.1) >>
>>
endobj
-359 0 obj
+414 0 obj
<<
-/D [357 0 R /XYZ 132.768 705.06 null]
+/D [412 0 R /XYZ 132.768 705.06 null]
>>
endobj
-354 0 obj
+409 0 obj
<<
-/D [357 0 R /XYZ 349.35 588.894 null]
+/D [412 0 R /XYZ 263.422 661.719 null]
>>
endobj
-356 0 obj
+411 0 obj
<<
-/Font << /F26 194 0 R /F89 243 0 R /F86 195 0 R /F61 185 0 R /F63 187 0 R /F87 231 0 R /F79 193 0 R /F82 324 0 R /F81 259 0 R /F67 360 0 R /F34 245 0 R /F80 260 0 R >>
+/Font << /F28 215 0 R /F63 207 0 R /F65 209 0 R /F89 267 0 R /F87 216 0 R /F88 255 0 R /F80 214 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-363 0 obj
+417 0 obj
<<
-/Length 2834
+/Length 2595
/Filter /FlateDecode
>>
stream
-xZɎW*w  fo3sPT(SiIPɪ.'. Xlv6_߽}g]
-#ÎKɬwF[&޽v$~vS_{yw0gj8ˊ9}*N"O]=o:c&1B14#py(!PLnQ#lhU}a&ו㡦oU7s}:'lr-R*s&Uk&eh<6婢@ey>C=Uu9Lڏ鑆^^Oee̬)[w}<W,9aLDߡ U53l'̏RQv}
-N>GIZ"4)76;5E<̀ynz#5~9L
- w Ħ:Ѷ;=JEC ǀ|K3b у#j@`7[iSaP̓$LLn`%pV7v>Pu+9r!)lֵx1v=QDʧD
-?G YUMNӅ -E@X
-b\E`m$PS/!q$`D~-U nI0#,9
-rb6j.+4L5@MMZІey=p\Orr"@sW1/ڗ V
-V"xJ L<w+7oN\&K+k4G`5_g?G@Ã3U
-2:gįq{t5iXo8@` %BW< ]]0%Nkni]НR9^DdpT~zįFݠ~b,͕A)Rp
-Jxe&`@r5o- f=
-?`B!mmR4nء?:}˽KRa9 u?<SA!K!|ra9Rpہ>4W#!ͩ]rjN|bd"1S*\1tԳo/H91HDFɰ/@]RLW
-O11NP8k´2‰)}}!릵}]V_s_#QuthTG~C XFls G%Z0厠ʶ|m<'wci|IIsrKSq"+)|+Lh\$8H~d`ֆ5ITZV=i% /sQ_%DN}lj{!.{LNyB_{ǠiL0$is1=z2,&i{jq)/@h܌t}0F&!a`5
-<`f.y5 D&BidCӊ+Ӣ<1si3%xXTLx3?/pLqAâ2^㡯}WQ@PI@ )8p9Ӡ~yiD (B 1b!'r+[@zWp1›ȍ^ ^R^ְޟ3>#JiKpNjHbI*ɬέ<7B%$(^iEQ
-6oG/:[~VzMOmVl!<9>g`a:wsvS(K**4ܰO3NekS ҼL7>o׾y<fmSUENT9&myT88U;kjT}לVND{,~camH|Y[w4%q+N8
-
-wQ#_G :]'ﶃ
-DpNwЗKޒ:KZcڹku[Ѡ=efuݿ*;GK߯n? ϫ
-[Oh+F+ cܷSX_uJz6377]r~J}ڷ:r (AnS_p{qB S*Jz;[%w"V)_2pSop
+xZKpnŘ#I [AmȖ#3S"ۓ H}UEwy䛿
+a6O3Vo6+yo~^U]_]>19͡`՜65}2_kLTVq]rOONec}~6=6{j8/ [hi7y!id&&f*T>|w\bBj%M/p;\v-`<Sj;Gû69m^q˕b?hgQ9g9ldlj]YoafJƙ+8Lv:p([-t3op&f z#T<R1-=+Nag_->c@=
+} d|v j
+Zq_ƏZ
+f%`3`\_:*tNMaiq?bk"̺Ԇѹa˵sB
+O &F(3#iiuA*KF=g,Q%2D,QɈaa^#lRvҟF&
+Fu oq8CW@[G(|
+ńPbgG 42R駟 J]9HH["*LRŏ~fA@h cMVEsd
+5NILACؐWl&$jZ4 $ߠ7#fMOM5ujA|]
+2g7 Gi^EρBۉk|Xnj2Q=:&Н 1S^QPLE6G
+m[+fawygI+}уݫy*d_F _mos,B*(O<K]> uu|ͩh,
endstream
endobj
-362 0 obj
+416 0 obj
<<
/Type /Page
-/Contents 363 0 R
-/Resources 361 0 R
+/Contents 417 0 R
+/Resources 415 0 R
/MediaBox [0 0 612 792]
-/Parent 365 0 R
+/Parent 393 0 R
>>
endobj
-364 0 obj
+418 0 obj
<<
-/D [362 0 R /XYZ 132.768 705.06 null]
+/D [416 0 R /XYZ 132.768 705.06 null]
>>
endobj
-361 0 obj
+415 0 obj
<<
-/Font << /F79 193 0 R /F26 194 0 R /F86 195 0 R /F31 246 0 R /F34 245 0 R /F94 291 0 R /F80 260 0 R /F81 259 0 R >>
+/Font << /F28 215 0 R /F80 214 0 R /F83 303 0 R /F82 283 0 R /F69 419 0 R /F87 216 0 R /F36 271 0 R /F81 284 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-374 0 obj
+423 0 obj
<<
/Length 2815
/Filter /FlateDecode
>>
stream
-xڝY]}=UF >ĕ8J</)U41 @Ļ=J40L60HBҽQpD_E绻Wu,;R)<R-bwUqw60i绿Mocuq8xcW&d7 7n=?q;2}M8ߙ7xHn̉f|A$5mTp=ǹ{R?* B)Eo|noBXwnl+n /Ѹg۪ƫ}9(]Wc:= Kk.صVh)Rjر/xh[Ʋ#K}O;߾擰_&ߧ(V^@%i' *}}Qxёb[ ˑ,1F6"y]n5c`VWX$Q<~Pt!ǐ!d~1S,Hȱ#w끟v=a1n%z*Fj@~w\b-ةM܅䳰QH׸3 |}ǝJ^pY2'3IMh
-`_?
-*.t`'+I|xNjJH0+=ܧΑ$h%i 8ە&I?Lx÷Y5hl%Ʉ< Cn
-!!@!@z/-wwS/:2+sH"|f,0g$)Ċ\xBAV(Fca7 ("I.u*<K\g7QDO3 sOACݨE\K'Of55 CUE$,
-poTp%"_b[DWq[q E_K 鈋UJJAt6$}9 YsNs 36e>gAÖjȬ HiJ.u.&]$Xаq25 O1ŏKr8Ś3蔱.CKz*&I{g[6ů׶("J/_mprO1[B߂wDƭ<l
-<GB^Y1(- P%* ߂"irJ!Q.G0 R+續<牸jG50)@.[39dM3Rp;R.`$^9K?06NDȁl,)m]Bő7|ݻ{Xl&2K|B"c2)8%^&Tԛ/<p^&lᲝǒ/0Pn&%R;/m*DD6$țۢ/ML/-W aM2~ؗt+OwJ$T_U M[ƫxξ:bz,4ZJ~XhDTyi=.aYOw1-9Yp&M}])6hzr ΒYB!gWqDR >weP&<Qk4QfST<] Deuxwz Fk7kK{\,Æ H<։b^7
+xZK-[ ,ddn{Xneeɱ䞝 ?>U,i힞M.ERd|᛿ϟ>:IYj|zXbƚIe6ѱ|z*uq^T~맿 K<|nL[#JJZA}Ƿ~#u6*~VDu ű|e<qb#͛XfBԄõX"Zk𩣲]ԛQHNh DZQV`Hsc}*I;8LS]F~9y*Rя8$L85E(L42<)M~)sqU<"pɤMmRk 6*kx{j!dfGÀ
+H`#ે >ayJH0Rdl,HJЏ0 8TuOQCh| WgY>v1CkB _p 3gPyH8<% 35X TEq1~>14zTemr`|BFs a3^-xM>kғ,V2.AF#L1g/`N#怠ZnXYv*쀕̦&.>}ޗcC/Wgs9,EiG4@]]x"/`M4:bC$F`4K r EGF<*]ՠA-ȹC$i0K>= MU$ :[D\<w骘%'s)? gh*$'{-E<}!g"p^|EƮ !,$8 L( ]1Jm z ^c}рh
+ $xrAi'ɤF΅i\{Y>de`o8 @XW Xr+~)g!~XwA>AY1ߝY75:w7B|GHo8!ĂqH K)q#yz@tVk;'&eȆ|vyۯ{<?ӽwE6Nl"@HB&
+QBd [P$IΓ}_ g2p7=P它
+^]{˸٥taGIWWBQl~. 6,y[NG|ք@e=ڊW%IG~롕C HS4C،<Q\t`=]4vVחc(&7Q\8LqN^\3=PΥ{\ p
+}&11<9*XQȪ򩦪#dH Ja?,BQ{Pq7/C҅j^!&:fU+Gf1 TT/TS,tO}}솛e P
+w&+w+ebX,}Irq$nf
+ 10lWtZgT g(bG Y;]|OA`}q@}r6jQ :[T~ޡ:OTZ⷇o<I+L]Q7G,xl+IgѮN ^[۾%XKX1aWKOz^` _nN:g̢diSzx "rz.z7 ՜]$ R>xO
endstream
endobj
-373 0 obj
+422 0 obj
<<
/Type /Page
-/Contents 374 0 R
-/Resources 372 0 R
+/Contents 423 0 R
+/Resources 421 0 R
/MediaBox [0 0 612 792]
-/Parent 365 0 R
-/Annots [ 366 0 R 367 0 R 368 0 R 369 0 R 370 0 R 371 0 R ]
+/Parent 393 0 R
>>
endobj
-366 0 obj
+424 0 obj
+<<
+/D [422 0 R /XYZ 132.768 705.06 null]
+>>
+endobj
+421 0 obj
+<<
+/Font << /F80 214 0 R /F28 215 0 R /F87 216 0 R /F100 329 0 R /F36 271 0 R /F81 284 0 R /F82 283 0 R /F33 285 0 R >>
+/ProcSet [ /PDF /Text ]
+>>
+endobj
+435 0 obj
+<<
+/Length 2972
+/Filter /FlateDecode
+>>
+stream
+xڝZmܶ_o^o"%#Mm D ֮66ky!w=|q3ÓM&_W*SJTEmޕ+ЦȮ7ٻj.je|om}߿NY%*.!*)+?W#||W_2ξѵptwfi0wR0~&6Vx@2hnn[/7R\5uPQOMf+]*A+VaXZvP„m6]wgeE)oyډٸɏc#a\$}7%K?l}=YzӾ4C'fm:,n݆Yj;?=5;ԴSS 
+SݴzjWU&)h>o~*{8»M`%!mƗ<Зy;]iQf
+L]kYr-vB3w-sD3(cvhh2VU*ҼFؕpqU/^ʛ.s#
+"B%P^2v;~tX,FrvNs;ԡ1~[w&+CgI=(oس:p*b/AU*3puV'J[e݋wd)8-+.Sڀ@eo_Rˬ@T NNxPIJ(%R[$|VaKﻠbBړv#q@~a+p ͰHp4(d.(1z ]NMӵھUs鑜YL1 ,g8'#sN͙JEs(mrsLVbc^^N[
+aId쐛a]ay!nB_z>ycp}
+uڀ&^(jq`6T(
+
+x^_ۻ\"qbGpI/|ċj`xr$CT:|/td LsēZ_PjaE9eĉB3 Seށ!@6m?%2i
+MXH͸*ij%*q:;N`,nЅAa6| (0An znn]YהY/܇G8pva
+LoPssT$ /vn*=~ij KF@fAǗdYJ3DmX[
+ d1qp2fXftEnJcxk𷉻٨჉΀ᅆ<䐼 0btWݖ8gY( '4ޤoB4'K& ˅;?(fy(@0W77'Ο6wɔAKblj[Q;- )`HPŝj\w
+bi m&^1Qǵhd48˱/=s;5#n㎓AnARwIY8A]a\:ns065+u/Gna .zQp uĚfG[^,^s %=YVS%4J˨&Q2pDE\NŽC"F!זa<R% }{֘meK%| ;Z\<LG )י. D'Q7ɒȴUsm,H'(D10OV-̣zRbpƐ0T>(󅕏xF#T>+|#VT_ljKCg:vNf~{7\W>O@ e
+1-O@ [РZ
+ěmTEzhͤGΤRAFLgC.Еk/! /3L4D WnڈҕKO`{ZhQ.O!$- BH܎ RϞ0"Sbr?<}b*d@e]H~ѐ3UyB ^6cAF\ JoWs ~!/FmJ?i/la#L `R+2t(6nC)J$a])2CkT5fpl
+endstream
+endobj
+434 0 obj
+<<
+/Type /Page
+/Contents 435 0 R
+/Resources 433 0 R
+/MediaBox [0 0 612 792]
+/Parent 440 0 R
+/Annots [ 420 0 R 425 0 R 426 0 R 427 0 R 428 0 R 429 0 R 430 0 R 431 0 R 432 0 R ]
+>>
+endobj
+420 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [182.297 416.742 188.759 428.678]
-/A << /S /GoTo /D (Hfootnote.3) >>
+/Rect [182.297 588.092 188.759 600.029]
+/A << /S /GoTo /D (Hfootnote.5) >>
>>
endobj
-367 0 obj
+425 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [311.327 348.996 318.3 359.788]
+/Rect [311.327 520.906 318.3 531.699]
/A << /S /GoTo /D (table.1) >>
>>
endobj
-368 0 obj
+426 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [197.314 337.041 204.288 347.833]
+/Rect [197.314 508.951 204.288 519.744]
/A << /S /GoTo /D (table.2) >>
>>
endobj
-369 0 obj
+427 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [172.388 325.085 179.361 335.878]
+/Rect [172.388 496.996 179.361 507.788]
/A << /S /GoTo /D (table.2) >>
>>
endobj
-370 0 obj
+428 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [149.826 313.13 156.799 323.923]
+/Rect [149.826 485.041 156.799 495.833]
/A << /S /GoTo /D (table.1) >>
>>
endobj
-371 0 obj
+429 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [241.531 145.758 264.002 156.551]
+/Rect [196.484 317.668 218.955 328.461]
/A << /S /GoTo /D (subsubsection.5.5.2) >>
>>
endobj
-375 0 obj
+430 0 obj
<<
-/D [373 0 R /XYZ 132.768 705.06 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [274.839 271.439 281.813 282.232]
+/A << /S /GoTo /D (table.1) >>
>>
endobj
-106 0 obj
+431 0 obj
<<
-/D [373 0 R /XYZ 133.768 497.896 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [169.849 235.573 176.822 246.366]
+/A << /S /GoTo /D (table.3) >>
>>
endobj
-376 0 obj
+432 0 obj
<<
-/D [373 0 R /XYZ 388.179 382.177 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [218.75 225.555 225.724 234.411]
+/A << /S /GoTo /D (table.1) >>
>>
endobj
-377 0 obj
+436 0 obj
<<
-/D [373 0 R /XYZ 149.011 140.627 null]
+/D [434 0 R /XYZ 132.768 705.06 null]
>>
endobj
-372 0 obj
+114 0 obj
+<<
+/D [434 0 R /XYZ 133.768 667.198 null]
+>>
+endobj
+437 0 obj
+<<
+/D [434 0 R /XYZ 388.179 554.087 null]
+>>
+endobj
+118 0 obj
+<<
+/D [434 0 R /XYZ 133.768 304.772 null]
+>>
+endobj
+438 0 obj
<<
-/Font << /F79 193 0 R /F26 194 0 R /F86 195 0 R /F78 192 0 R /F87 231 0 R /F61 185 0 R /F63 187 0 R /F89 243 0 R /F76 190 0 R /F90 266 0 R /F100 378 0 R >>
+/D [434 0 R /XYZ 379.783 280.709 null]
+>>
+endobj
+439 0 obj
+<<
+/D [434 0 R /XYZ 149.011 128.717 null]
+>>
+endobj
+433 0 obj
+<<
+/Font << /F79 213 0 R /F28 215 0 R /F87 216 0 R /F88 255 0 R /F63 207 0 R /F65 209 0 R /F89 267 0 R /F40 288 0 R /F36 271 0 R /F82 283 0 R /F33 285 0 R /F98 311 0 R /F95 313 0 R /F99 323 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-385 0 obj
+444 0 obj
<<
-/Length 2657
+/Length 2756
/Filter /FlateDecode
>>
stream
-xڕYm6B*WQ
-p 8EȒ+Ap(Yj3p34#ݏl rcdGB)f,JeRh[Fb&Bq UQoeM\c w2rL<J`Y*Ivځ$mb&"`bq0ӌ}qoL<>ͣnb$Lho4k,-b~~'@ D g(98ݧxTBg6ѓz*:/s~2b3U|/ÚhO/Kf]γ t:S_Mm@& Y(=$ ^ؼv!)]]W[ptI gn045=ιO~w]ҠsVteYUIJ:痏hp5.-tsU2 =RMn+pҸ!]C*|8DxZwQw'?[o$~:2x<^L4g9|Q,E@2.NB̝s 6Feed:N' Bl3
-/xMuP>cgV'/󎤅 *:~_&V6ڜ؋/JásQעtahg 7Zj(Oc@C xC}j@U~piRʀ.C }([w]uf6pwT ܾ3uߪ)]18Ю£yxu^*{
-Wk%7¿O~-sɚ ZR(B)#D8V;Y0q4F+jTQ.$bP̃\0TφLr)b9KY
-
-pu]GE_2߂
-m}(b#p\ʳl-8Ч [o7,w'yk a o
-}B;<b!cN
-C3C|*YE y mdߙ6 뇷asYqĐ'G5f6{d-A 6Rx慆CWP;: uA]! FMWF<^lF(n`F`xƼ) ޾0 %y2[P6D{;9x`2B|aVA ;S{$
-GJJKHYƧHIps [nё\3l
-+,>IVs6_Tva wsk)d=*!³\',&J|j(Ax؄xG+2!O|Sn
-2M
-H}>-P_K]KPOoPkJc:hI`ЮǠS]>^R3m'k*vCT<6ȃG!-$c٘}ɢ h`2hciZ@4Εjatb=E&?O
-eVqPU\WuퟏVo!H@ɱe ! /˂gEp= -SyĹki*?ֹ[!N 6x-!H$B.T)0+y$*o7--`0
-
+xڽYY~_1yء'Iy1` NX e a!c^-Ѽf䇼,k6=ݻy6NwB1rww &;kP*w?&]b<Yǚ';eCwo[E+&c@:P:/N'eKJHBD튦2ď :Aas%1$^0" #eGiPcN[("W^^&1K "?=詪@-2 _ -DOv04D:scҡ(:Ҵ~7s']2B
+tF!Bd->AOYu)-R'G4/y,+ʂ֒x8VJ?G'ՍdIyoLm܅|hn-\.g%k]MLϮs~'I
+ߢ΋#Ԗ*x٢^Prz0[OqT *< o}Wߘ78Tnɻ?#[J?9F4w 7s<"km|?X)AZ(<s[}οn66mC.oS K~뗭xL ­n+pn|N-, ut:x>,sv~Q>
+14ҀL>V$СQS$@q=ۺ|CZBQk=סhR-qPf  nۧ}qwlh JS֊`A/LV8X n"ۮ?X| 6l|v2qa <H'^>mtP}֒HBnMO݀!!,ul!lI?:}~zRxfܵ(JȎG; ui8PH&Sғ߃~<U~TY#{fG4;QT#g=ie+(ׂ#|ϱ
+P`ipc¸dJDA%C+T]=0LB.7gԩ@n>w W[K\8 [ÃIn~*;P ~qL;V7?r"xHK+ʢPZr\ZK:V&&kE(?<0ҊetzAi:ג4@zȌc.&HjJ j)!/H$#M2¼ZYw*PܣYڸ޴b7Z{1 抡ߺضm [ԿTמʤ
+l%0ܓ JwZg;NH(pee đ 'f@:@vb&*UJXe7if&?]&uEM8Z׽:rČ`
+Fioj\ *On[X,yVXP"+:т]8lGXc7S:TѴ?B qZT1W
+ n?u\!C;0\4>$Qpe7L@$;-z.%-=VE̐A"եQU
+[8
+&apj#'A )GO]щqEVv㡍g2ޕbɚe#?re@4| m:wz援+y,X;lț 1z4C~j4d'sCqۉyCN%\  h0ifM4Pq,/%*F)#<Fs,ƀ&6+ɤkw·G*He^ "͙>
endstream
endobj
-384 0 obj
+443 0 obj
<<
/Type /Page
-/Contents 385 0 R
-/Resources 383 0 R
+/Contents 444 0 R
+/Resources 442 0 R
/MediaBox [0 0 612 792]
-/Parent 365 0 R
-/Annots [ 379 0 R 380 0 R 381 0 R 382 0 R ]
+/Parent 440 0 R
+/Annots [ 441 0 R ]
>>
endobj
-379 0 obj
+441 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [274.839 635.913 281.813 646.705]
-/A << /S /GoTo /D (table.1) >>
+/Rect [238.618 400.794 245.592 411.587]
+/A << /S /GoTo /D (section.2) >>
>>
endobj
-380 0 obj
+445 0 obj
<<
-/Type /Annot
-/Subtype /Link
-/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [169.849 600.047 176.822 610.84]
-/A << /S /GoTo /D (table.3) >>
+/D [443 0 R /XYZ 132.768 705.06 null]
>>
endobj
-381 0 obj
+122 0 obj
<<
-/Type /Annot
-/Subtype /Link
-/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [218.75 590.029 225.724 598.885]
-/A << /S /GoTo /D (table.1) >>
+/D [443 0 R /XYZ 133.768 667.198 null]
>>
endobj
-382 0 obj
+126 0 obj
<<
-/Type /Annot
-/Subtype /Link
-/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [268.665 202.316 275.639 213.109]
-/A << /S /GoTo /D (section.2) >>
+/D [443 0 R /XYZ 133.768 387.85 null]
>>
endobj
-386 0 obj
+446 0 obj
<<
-/D [384 0 R /XYZ 132.768 705.06 null]
+/D [443 0 R /XYZ 329.173 348.622 null]
>>
endobj
-110 0 obj
+442 0 obj
<<
-/D [384 0 R /XYZ 133.768 667.198 null]
+/Font << /F79 213 0 R /F100 329 0 R /F28 215 0 R /F87 216 0 R /F89 267 0 R /F80 214 0 R /F63 207 0 R /F65 209 0 R /F33 285 0 R >>
+/ProcSet [ /PDF /Text ]
>>
endobj
-387 0 obj
+450 0 obj
<<
-/D [384 0 R /XYZ 379.926 647.328 null]
+/Length 2290
+/Filter /FlateDecode
>>
+stream
+xڍYKoϯPNKV `. #hH,S/dz<nV?_Wqo~KקO&l2&<6ZӰIM6OͿ}і&iZ56ʹ骼;qW&QCkBToOh26;UȾO'p`Qp{.{7?_˭S!*#l#ZGlAOw.mqs%د}C_Ɓn[FלTG@U~{QC{Lfg`;x/ں}y8 8XbcRd4 5v]qt3f9_hm\w[ĩ E3)/s&ʂAhtZU( 4mԜI_b~/L.Kt1vaJ  rv02+͆kh `g_9ltdc%zY*ǵd:`Bn08[<4:ATBiQ ,em:6Fȇ=s,ZT)~w8L,snF8d.{yԿqg8;Kp| [F]dBY,:+J`Aa H$hص"Ku=TA+~DAy&nʕa.+H7 2*Li7
+x.dS^ `-e*IAy^B[UT%
+_~>'Fr#ʑ.>\p
+u qf2$\ز\ 7|J5au /[ON`
+nS`({(ԀGJqZ6^l+]0
+u,!ecu u} F; =-1pVN?AV7IFmgpâJ-Cl
+0buVYx
+endstream
endobj
-114 0 obj
+449 0 obj
<<
-/D [384 0 R /XYZ 133.768 480.004 null]
+/Type /Page
+/Contents 450 0 R
+/Resources 448 0 R
+/MediaBox [0 0 612 792]
+/Parent 440 0 R
+/Annots [ 447 0 R ]
>>
endobj
-118 0 obj
+447 0 obj
<<
-/D [384 0 R /XYZ 133.768 189.372 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [293.98 123.847 308.702 134.64]
+/A << /S /GoTo /D (subsection.4.2) >>
>>
endobj
-383 0 obj
+451 0 obj
+<<
+/D [449 0 R /XYZ 132.768 705.06 null]
+>>
+endobj
+452 0 obj
<<
-/Font << /F78 192 0 R /F26 194 0 R /F61 185 0 R /F63 187 0 R /F89 243 0 R /F38 263 0 R /F34 245 0 R /F81 259 0 R /F31 246 0 R /F94 291 0 R /F86 195 0 R >>
+/D [449 0 R /XYZ 133.768 479.907 null]
+>>
+endobj
+130 0 obj
+<<
+/D [449 0 R /XYZ 133.768 334.46 null]
+>>
+endobj
+448 0 obj
+<<
+/Font << /F28 215 0 R /F87 216 0 R /F33 285 0 R /F80 214 0 R /F89 267 0 R /F79 213 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-392 0 obj
+456 0 obj
<<
-/Length 2625
+/Length 2543
/Filter /FlateDecode
>>
stream
-xڵYmoܸ_!KE); Rk|*pҞ pH-brѐg^&I|<K_8{`*X'<7L<Qf"˓*\3Yue\Gv4<[S&O">vn?lR4]#NxЮ솺 aYM=_\ӯqJoKW_ لeW[6gT4neD
-Npo?LS X|aWmSϛrƙYkZu0ۺkں=Ee;ѭn~Mo;O6Ԟ) ]wf/]tyPv
-f29SpLN;vB
-9xzI8s`sFT;Ot,K̉hT[p4PO(f&`ښe߽ly"4`Jj{v-M*mΑnMG^ix2W/̊q!Oܨp)7x+NZ}.""E3
- h?L
-MZF#,@c`+j )@:`HyW71A`}cwYF!%EvKI
- na!wwS;ODa\766,+x?舲ux!`Wn4|B)#!P_j~?!b춏S
-i泹)\w- `7>;Z#o-vzw^aDZu-(!Fљ~~5>@4ƑI at!
- M:`_Ӄ5D KR <_oh]#%j#~ڐDd[󤍆N8Z85T_d0rWR1Qs.Mb0yj5Ҕ: 7к3u+C6^*r~b/L*釓2IHA/;po 2Ձ3XH:M)g)%p T¢8ѧy5N't~ ê |L}9Fx.g. ,q
-0)cD8rx8*'R1?WՉ0;|>wxx4y>yualR)ش:I*=B֪yM18e5Es=w.R.7H:lN>jD 
-b]ۤk~gj&RQU-m/`uéRxHAf0ގ2G֫YP=Qʧb`A0{U_ᜩ {QP/o!_bS
+xڥYKs6Wm-B<G\&v9lv#j!G2aIn48$ǔ4^4 h4_?nVEW߽fB+c҉aB&lu\'"ìnف?M߮_H_$W>^~7RN.fq : fq‰F5w `JXPOU
+8;%~NqG^_}9Hf]35pX?'UPaS`o W6JwZqKo:(ZQ~n&;"Q4KQ-ZIɣ]^2$ѧX'(XuX_&LY9Pn>2}{) ʁ~3-\3<c@T<{ c(ǦηY?a,2QWU.VY%Ϻb&>RnIm$U
+~IDD7-
+P
+>x=}C_Yn< ¨Mݗa(~U"'th1a(8wc0X]Vq3mj ,7bˆ$&؂Xi N,) 7mŌ
+5MnjSv`H
+Ya<̡:&.CU#a0+ۀO>'ݞJ/y(71hj\=n~fƌ
+
+CѵDEs9Cj415t 갞Aj)]
+X0ϵގJyx7+S|a.*W'aOLOڄIF!ԖϚ_0`7:i;ط7ԞP <RbH!tO1ak|cv)Nprߩ8tn]O#FIj5@F$@gXSj㴅TJR_n맵B'K}Z"+!Ǥ]B׷u  TP<NG C?]^fO*6u;\1]4>v§O}؄T#lFt9|V< ;}-)ר?0hCv
+\_V̱=Xbd$O
+F 8/T4yygO$4׃*YKL$=U
endstream
endobj
-391 0 obj
+455 0 obj
<<
/Type /Page
-/Contents 392 0 R
-/Resources 390 0 R
+/Contents 456 0 R
+/Resources 454 0 R
/MediaBox [0 0 612 792]
-/Parent 365 0 R
-/Annots [ 388 0 R 389 0 R ]
+/Parent 440 0 R
+/Annots [ 453 0 R ]
>>
endobj
-388 0 obj
-<<
-/Type /Annot
-/Subtype /Link
-/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [339.026 549.971 353.749 560.764]
-/A << /S /GoTo /D (subsection.4.2) >>
->>
-endobj
-389 0 obj
+453 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [240.507 165.286 246.969 175.286]
-/A << /S /GoTo /D (Hfootnote.4) >>
+/Rect [240.507 268.382 246.969 278.381]
+/A << /S /GoTo /D (Hfootnote.6) >>
>>
endobj
-393 0 obj
+457 0 obj
<<
-/D [391 0 R /XYZ 132.768 705.06 null]
+/D [455 0 R /XYZ 132.768 705.06 null]
>>
endobj
-394 0 obj
+458 0 obj
<<
-/D [391 0 R /XYZ 149.011 128.717 null]
+/D [455 0 R /XYZ 149.011 128.717 null]
>>
endobj
-390 0 obj
+454 0 obj
<<
-/Font << /F86 195 0 R /F26 194 0 R /F89 243 0 R /F31 246 0 R /F37 261 0 R /F38 263 0 R /F34 245 0 R /F81 259 0 R /F87 231 0 R /F80 260 0 R /F76 190 0 R /F90 266 0 R >>
+/Font << /F87 216 0 R /F33 285 0 R /F39 286 0 R /F40 288 0 R /F36 271 0 R /F82 283 0 R /F28 215 0 R /F89 267 0 R /F88 255 0 R /F81 284 0 R /F98 311 0 R /F95 313 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-397 0 obj
+461 0 obj
<<
-/Length 2369
+/Length 2128
/Filter /FlateDecode
>>
stream
-xڵXKoWj`+E&$Y$N&`{ rv zEib{XZrA"YUWL(~͏4Cą`T <U]nV`V$.hM<A?gOq p0ϻx|ORΝ)Y[:)g<n=P{9fHVb:֎,*" eіsscVX p,>fᱩfʖJ;_h);=<'13l_,[Q(_\Zv<Wĝ57ױ]=NmUˡZs-O?"Zw$!A؂겡ASKáfesƯ|+9*}4tP/~XV?ΰ4M\p[F :\ϊqŲɼ cwmy
-]xsCJ!ck6ۜC؊4}iAkk,8*$R$^=* hJG\2Eо")-x#+<SY@HD3I9aյ 8(dnPq|h(<:D4n3q͇L)#\?-ƒa
-]Xs.gnjaawē 3&A7H(} FͷIY!0N%Y$M=a6#T,L$" zo_o8D<bV"aRxs9* ~ɄVѓ#=B^cR`o7ķ8Vx,1l~8&U&L)>#sЈ.3 sxJ`\PR{ԢHdNIL}svF(|dhOe ?Hk]ǩzc{ScT0v䤄|2ZX]1<?%5٧?mm Rnv5{:
->gR|VA2QE| ;z B3Z*M8wvq.ҿ~l J`[KS⋔;I&&
-W0 mEii -? 4u76,;BR{3-mjaJPkؚi83
-bܷWR5N[{>wH>ͼ
-%s(7
-Z&(4ehtHTH(wMoQ\M7^=H4̵E:/S~w~{~W"d4Or< "8/ d~hS|fer7RpJʡ:Js%JsPHGi!4`AH|H'Yp.⻨_JydYI%>," R;3d kΰFE<%|S_]}
+xڥX[o6~ϯ[e bER-[`۾-&K&@%W'1{)Kfi_Ls|iү?^xUTEtxY2n7]lSo]%4M_o2۲y4򎆔1ܺ'2$"ce,W%*Rƻj%Ti%tlhj;+8dq[5j& %.+I#&îǚn #`d')Kl;bͼ`t޻'I$3 ;(` >93Y:L 3 v2+&g5E%Ix(w_ b8+҈G,XeӂG}m`(eѓ;=XӨ_sVer,4zJG`h>!(2s%Tpav H%;
+potyk83LRD/2{K;3hݞ
+*ɲ2F'v#4>/廙ߩh0NsRNT&3I%fO;=TkÊ2fHYķQ0KgѲ
+m Kiks\F>K_GZ<LxpTL,ʝ$Q)5s[ᘹp,p0igzp˲=9HBtCkYn:(u~ᝁZ3hg!(ٺAy9-oۚ7Sp7o}=Xp(Y6gۣ%= j'+Ns7wn]5[h8)0O<ttWim>ʛ.Bj@0DjG0
+KSಂ[yWІHd
+C6Ֆ^1;8_Z g }Y~"^kf>]-YdZ$@?>G^w2z2~jb/cT<=㯡F%X
+"PU
+>IX*$/NVԭţW K FcB:$NN
+iQq6GOҝ.0Pz6+,Ulw\+B8';i1>*-گTm&q~~\[p]! 5 5mF&ۻܸUK8IJK}$d]*M )
+l1B/.sؔdiY~H]S?˺3#)ɸgBY+tlxS g:H, ے]YKȮe0fvRE@J.6G =†K0Z+
+\/T/e/*鳧(gW 7݄
endstream
endobj
-396 0 obj
+460 0 obj
<<
/Type /Page
-/Contents 397 0 R
-/Resources 395 0 R
+/Contents 461 0 R
+/Resources 459 0 R
/MediaBox [0 0 612 792]
-/Parent 365 0 R
+/Parent 440 0 R
>>
endobj
-398 0 obj
+462 0 obj
<<
-/D [396 0 R /XYZ 132.768 705.06 null]
+/D [460 0 R /XYZ 132.768 705.06 null]
>>
endobj
-122 0 obj
+134 0 obj
<<
-/D [396 0 R /XYZ 133.768 259.069 null]
+/D [460 0 R /XYZ 133.768 320.779 null]
>>
endobj
-395 0 obj
+459 0 obj
<<
-/Font << /F26 194 0 R /F89 243 0 R /F86 195 0 R /F31 246 0 R /F37 261 0 R /F38 263 0 R /F34 245 0 R /F81 259 0 R /F80 260 0 R /F79 193 0 R >>
+/Font << /F87 216 0 R /F28 215 0 R /F33 285 0 R /F39 286 0 R /F40 288 0 R /F36 271 0 R /F82 283 0 R /F81 284 0 R /F80 214 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-403 0 obj
+466 0 obj
<<
-/Length 2258
+/Length 2532
/Filter /FlateDecode
>>
stream
-xڝXKs6WfNń&锫vSek#%UVᄏH*vkF44pED)I5.`*!:VV1By1 ]^6*|?ϛO %R b}W )뻦D)SeV6[z[^:ꋶd&л*v}UY7㹸澨vf-f.xւY0-ꮹo^ Ybm|_8qȣvc7:. J%=.I}'aѽDpaaڵPAnT<d*^ۃμw hW~vILJ=yٝ XĬDئA& ;RMȁN("ItD7H{_W  .O4aDDCUps?hcG^z>i2*
-
-YBLw3H|~II"HBjN'DgGS Bb 6jgr
-0tc6̜|dwͺc:@U`L=~'rJ9:`ma_&xfPᓌdbK
-z2|ߍ'7e1@p{p͛3]/chMng!7I
-#M3/ >^< 
-+uYd @$_*C#/Ne"C-[Ԟނ
-,Txi
+xڭY[oF~Ch4 ]xM^m! PZ,b)Q奶93Û4>z.]ݮ \_z*%zu]1ia|!\uziER\9<629ԗ&w)%Slwvm}]gc#?]ƚ&%s87&d^nw_>IZMcÜ]Cy^Xe$-N_F15c$UYזt~ A2+K GHjq0b- a.ך%p?/[1at!ưf]՝_1JyſNk1bvu6mҊ:,rA8 N _" , @JAрeej=ܴ<v4ܠw]Gݖ]Y`V !G
+y0J{3f-HYMڢN '依MI ɹ)X"F~?EpE+~ 8ȶؒKl~aÎUSdy o<iNG"8|ِL9 6uƖ;pk7kTx"RhqӗU.-$r<WZS2:
+
+mcaWdh`$׻sx,<"4,u1 -M9Z6M<Hb,9ԇ>~c)mq\,MT NU
+"ՀrNFt]ϝ,j9*@`"-$ w!!n7 (Wn==, Xb36"~qk{뼜4B9#Ɠ
+ggaFvĚ/t y8Pt,} ' {e$V0%RNRoۺ<N4tXraP2-~|uQG.nbR54DY5hMS Q!yB11)W򎠾$ & xc˛D:.l~%BQά Vt; &Rr)WqqMO!gʎUh"dzV [&[f==Wք+?osB\w:TCfrAό-XgR@4gnJDNG
+hz
+ " Rb&O}+qC ,
+I@-3RHjU~36`S
+j+137v
+J??r~H+UBh }GU8-L!ow'q|A7@%k|Ac }/!@z
endstream
endobj
-402 0 obj
+465 0 obj
<<
/Type /Page
-/Contents 403 0 R
-/Resources 401 0 R
+/Contents 466 0 R
+/Resources 464 0 R
/MediaBox [0 0 612 792]
-/Parent 365 0 R
-/Annots [ 399 0 R ]
+/Parent 440 0 R
+/Annots [ 463 0 R ]
>>
endobj
-399 0 obj
+463 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [187.843 199.361 194.817 211.316]
+/Rect [187.843 277.638 194.817 289.593]
/A << /S /GoTo /D (equation.2.6) >>
>>
endobj
-404 0 obj
+467 0 obj
<<
-/D [402 0 R /XYZ 132.768 705.06 null]
+/D [465 0 R /XYZ 132.768 705.06 null]
>>
endobj
-126 0 obj
+138 0 obj
<<
-/D [402 0 R /XYZ 133.768 513.59 null]
+/D [465 0 R /XYZ 133.768 617.594 null]
>>
endobj
-401 0 obj
+468 0 obj
+<<
+/D [465 0 R /XYZ 133.768 179.029 null]
+>>
+endobj
+464 0 obj
<<
-/Font << /F86 195 0 R /F26 194 0 R /F38 263 0 R /F81 259 0 R /F79 193 0 R /F89 243 0 R /F34 245 0 R /F31 246 0 R /F37 261 0 R /F91 279 0 R >>
+/Font << /F28 215 0 R /F87 216 0 R /F40 288 0 R /F82 283 0 R /F80 214 0 R /F89 267 0 R /F36 271 0 R /F33 285 0 R /F39 286 0 R /F91 302 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-408 0 obj
+472 0 obj
<<
-/Length 2645
+/Length 3008
/Filter /FlateDecode
>>
stream
-xڭYܶ~~2|"Y^l8M 4 lխwFXν$r73_ݭn{c1lu[ *ӆIW7}rsmum.:eWz)"PL)o~ 29e,UX ǼY[4-luȏZ$eU$O4Py-mۮlj"<dhvā=
-b׋ fS-Oۨ3ȣ1_9
-`ȬD+,tKC2L)j;\/=|2
-O[sٜ:">5}}ޫ {ۼ1ɤa 8>Qaxܡ۲KOO&wE-M##E=#`V_Dx#eo'1ez|xk'#p@#`F7,[xkX2mfCR[\:S
-U~ )
-r0H?ԃ K~iN{͓yUP* (W=p~&Ĭއ,U<&<@ȧ{>Gb{R1S&lObA]엡r"ƒ$N-"df0# Y!`|(4o(C-1*. 䦮8,y0r38~l4q#AD)=~BmSɜ -s25 L/l'yVPZ|s̸RҰ'K,E^c{%=Z>=L(Iۅ$`!֬Κ%GЩKD
-hZ`p0umJ
-,xnۛ%P~>{/芊B4ͩ{vcP28m@ |i|CϽ9e)?q(fG}
- 4f1!Ky(GK84@eĹk\QftMu"WMC_똷^K/=D0`MuL;`x(l툌fLR-9jug=@Y,%%HCE2nrۧF|'k"$Gqf |!nTr|4XTwNHN\MB*L@DLFtx<uE oyk~}~"*lghyϡτ!lp C3FxqXC[9% &^Z ~vT?\81<(W|U 9]={j
-կW23&F ;:_A,0`ÄƚY%a;T.L58y ^&ts! {Q6Li)SV# $NX`
+xڝZYo~[(j2 Eڴh XYHk\l(ub93sf9wF֫^}y_~zwy*Ttu[$Wi$S%rCq?m=B3|)כ&w[vzzct/no
+mQEJ8< $ ɽ= eccU FZnq6JjO۵ͣ=~]'I7kLuSi tU2aWc&객DC.%ܯ77tKW5=H
+D'n. a#6|U:He;l@աB)3uz/[l ךfIy\%i>ܲZbljaxxȍ͜Jt
+S_&? [[X'.ly1.O=KDmSO:ܱ ۪Kž tvXv}.ظB/ NI8͂T<VU *Ӛ~ +4|xdV,{i@Z4Q)D%~7ޑz>Χ@x-IJbڲvqBEA=\9ObSDt-XP{T$~fh~Z9G}c5=
+9bA&+ 2UWק~
+8p1K7.1,̭6,Py2&dɢuuᖿ}0jNm/8j%%ݠ9wS~=㘙3Bc
+[B`y/!JKG&#D1gR<ᵴ[ X-s%'ٕύƽqE&G(H; o{.LLb\FEVY=3Mn_gWR y}iD½<e=
+}cTQ'ڍ9B
+#ą;+NXm3:2{eTĒxʭ̪sKٮ pdXjX*˳WME{1 Šm-D`B?Lr'Xq=Ak&Yzh t.jqc3
+S[uRRfƥw`$n\:
+e*ѤkI~slLԠIBGff/c:tx$»
+q@&I60lؐ<,+n] jV"A#k5Iln)^)g>5E0 Ǣ+.>e0oV嚢 Cr"muUXZ4m@u>< AF??i j _, 
endstream
endobj
-407 0 obj
+471 0 obj
<<
/Type /Page
-/Contents 408 0 R
-/Resources 406 0 R
+/Contents 472 0 R
+/Resources 470 0 R
/MediaBox [0 0 612 792]
-/Parent 412 0 R
-/Annots [ 400 0 R 405 0 R ]
+/Parent 475 0 R
+/Annots [ 469 0 R ]
>>
endobj
-400 0 obj
-<<
-/Type /Annot
-/Subtype /Link
-/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [425.009 606.481 431.471 618.418]
-/A << /S /GoTo /D (Hfootnote.5) >>
->>
-endobj
-405 0 obj
+469 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [259.938 444.637 266.912 455.43]
+/Rect [233.082 514.97 240.056 525.763]
/A << /S /GoTo /D (section.2) >>
>>
endobj
-409 0 obj
-<<
-/D [407 0 R /XYZ 132.768 705.06 null]
->>
-endobj
-410 0 obj
-<<
-/D [407 0 R /XYZ 133.768 669.191 null]
->>
-endobj
-130 0 obj
+473 0 obj
<<
-/D [407 0 R /XYZ 133.768 489.925 null]
+/D [471 0 R /XYZ 132.768 705.06 null]
>>
endobj
-411 0 obj
+142 0 obj
<<
-/D [407 0 R /XYZ 149.011 206.325 null]
+/D [471 0 R /XYZ 133.768 560.258 null]
>>
endobj
-406 0 obj
+470 0 obj
<<
-/Font << /F79 193 0 R /F26 194 0 R /F86 195 0 R /F34 245 0 R /F31 246 0 R /F87 231 0 R /F78 192 0 R /F94 291 0 R /F89 243 0 R /F76 190 0 R /F90 266 0 R /F100 378 0 R >>
+/Font << /F87 216 0 R /F28 215 0 R /F79 213 0 R /F100 329 0 R /F89 267 0 R /F80 214 0 R /F102 474 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-416 0 obj
+479 0 obj
<<
-/Length 2668
+/Length 2550
/Filter /FlateDecode
>>
stream
-xڥY[~_"t͈")Jm"i4 <HTccadɑ=R<ż<<<It%WWo&Rfye("~9*mU-=DJR?/@$H|Xnrat|qsk[DHfĬ&2\TpCזF*ݻ:{rͷgJIR0}="C[rSսێ]]s?i.,o+ c_v܎{ǝd'J%\%/M*\|I_0JG{ʏX9{OLn&MSaS9UyvU woOcݵO5=2;$3w0w$>h rasoqѠ-^`^ᰈOA `مH1)Kʥ9h2VE:}y_Pߵ(Gd;Q@-P85`/̓nj;;\57=Jk$i;zgڃ!-ӓRSmE^lg}T&], +KRe{.0$HCZVm w=DmmVSC-zm">cjZ7B߲B>Fu/?8:dBgJ xb!uГ$U"ļhYH 9I^U9
-|.+l5]W Ԫ
-\x#ШRn˳up
-,L&TN0wZcg
-n$*[5-REy,Ɔ6
-AhOT:$4U9U&M<'QEУ`.q&s-<C%S߄8URq}wj<BS{QyLrf/ 2q6l~y꘥u񁧁'(e?IQFl)p
-q~h{H>3nޖm䫵\N_!Z!sD">+0ZdoI]ޤ7k
+xڵY_Od̐")RiS .m66@.Z^ 'K$qw %[{wEїp4$.#pww_}(cY.R2(Ն%RGeK$6~JWnҤy=u4|i,3BeJ(a\gʷ$N1ih;GH3-R3u4cLU?ti9&~x{6[aq;?n"nk8M:^iwjk%8C`<̎k,Xv+&IKT2
+R2>y/
+\V:C&1rƔm[H
+6[#ͧ-() Wt׍)<8!hMƔ0=T^USԧ]j'N [Wi6F :AU[|" ڧ!W0๮z>X;W>[+≲ uJ"n}OX k1禀س5}exTe(C IWqNA8X9#<_U <EޔϗO_ ]`$q9kHE53s)M{|nxSIhЮ$X<}
+4yM0jǐCA7z=}zEU j0ehyWs<_=BshBgS
+|0Hɀ/C^[A6,(&c'G`辂M;MMmY*b_dPh9$NjV1A]u6L]ۅgް-5K\[kOaҶ寛<\nswP*R{ E寚;#XU\@ޤ#4%, da*Ԟĝ:wAv.$}MC_@:tU!@h|֙虓` FVOH@
+#W枸o_=կ |X~/$
+;
+w. UW?@:M_oRV:m]4<أcg/cOT;,gy} TAn^ψ=fg2R'ZzعC8L
+Kц/Æg,*^;$ Ȱ*n=_,i"D#iSw6nMgo.8jV$z'S
+&3={,fu??A]P% (
+G3&Z- BvPB.h1\
endstream
endobj
-415 0 obj
+478 0 obj
<<
/Type /Page
-/Contents 416 0 R
-/Resources 414 0 R
+/Contents 479 0 R
+/Resources 477 0 R
/MediaBox [0 0 612 792]
-/Parent 412 0 R
-/Annots [ 413 0 R ]
+/Parent 475 0 R
+/Annots [ 476 0 R ]
>>
endobj
-413 0 obj
+476 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [201.709 424.824 208.17 434.823]
-/A << /S /GoTo /D (Hfootnote.6) >>
+/Rect [201.709 588.044 208.17 598.043]
+/A << /S /GoTo /D (Hfootnote.7) >>
>>
endobj
-417 0 obj
+480 0 obj
<<
-/D [415 0 R /XYZ 132.768 705.06 null]
+/D [478 0 R /XYZ 132.768 705.06 null]
>>
endobj
-134 0 obj
+146 0 obj
<<
-/D [415 0 R /XYZ 133.768 466.183 null]
+/D [478 0 R /XYZ 133.768 629.402 null]
>>
endobj
-138 0 obj
+150 0 obj
<<
-/D [415 0 R /XYZ 133.768 190.045 null]
+/D [478 0 R /XYZ 133.768 373.909 null]
>>
endobj
-419 0 obj
+481 0 obj
<<
-/D [415 0 R /XYZ 149.011 141.618 null]
+/D [478 0 R /XYZ 149.011 138.185 null]
>>
endobj
-414 0 obj
+477 0 obj
<<
-/Font << /F79 193 0 R /F26 194 0 R /F101 418 0 R /F87 231 0 R /F86 195 0 R /F94 291 0 R /F89 243 0 R /F76 190 0 R /F90 266 0 R /F100 378 0 R >>
+/Font << /F28 215 0 R /F88 255 0 R /F87 216 0 R /F80 214 0 R /F100 329 0 R /F89 267 0 R /F98 311 0 R /F95 313 0 R /F99 323 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-424 0 obj
+487 0 obj
<<
-/Length 2992
+/Length 2585
/Filter /FlateDecode
>>
stream
-xڭZY~_ 6b6ır 1`GFR☤"yi8kO]WxEޤ*Yn%m*gWuBiޮ~~ڜ.߼orn˟썚^VFd(E&_ZqTvkeCYU<yTi;N]x؅()A?g<RJDt q
-{ꩳHۧ=-QdG>:c߅:c~3HJxbF2;zW;r}}U05㦞8:dfȩHIj=وHf._#z)PT/>JGsTS8z5D39,\F(
-ٷͰs`ތ)pڇ7k]_p-;v/\E:V׏_9IAnV\%xƢݨ{|I-ej
-lD\90D=5ힱX"C* B#gtvՎZ&юzYMK,#D4T>Wod>)".t]BxC(ɡ'qYF_tS1u3gE{|ER3e:3Fm$s)u|Ƕ519.cUt*Kq-J\T|X~8:gr >!dvtǩluz Ў]*nQ/"z-?*u@MYD ^ t@(]ѓT0E0>a0XȹY9̷zTFmBNږm7RyCI?y6X-Oe PN7oұĴ\guy:CBmkkv}<;u,-hZQ umQ,%uHusi<KD<z?$}<Mj ⊄\(/?P&TNU G2n`{V Vj 9SgXn甙}yt<b(q.:N"#OϝnB o)*>}QI)WS+Mu)uK^gCX3pu029Kd:Inߐ9vB0%0)!Ě~px#T..s!Rz!O\>^9SSmM/ *|w -2|$Hu/cM~wg wjKFP??
-LN|= a\<<GeA>l(MA=-O<|%ic@0 GqJq
+xڭYmo_E&9m@nWr$_3J+>O9 %7I|{_/x+lE\o.%3Mrm:.CW74*oFUMJ 4Z<Onz5Nk_ro0"8g"7f`M[V-63v>ѳo/d-`d 84\Q$iSVJ ou6,7ٜZx>|I $Y əv:YK`_D@
+ӿV -X򴯊]]GS'..iLgqfveASƤw2|jj|\ؚkˑY-uӀ L~ ~#?ӀƝǾ ^p%MB
+'aWkȄ:-j}(vIvs9 $b
+Y)!o99j$_pA`Y7S
+Jj֑:FU]g [IfQo@ $OKtb632͕%V1
+P 'u&ڢW<݂Vu%} :ջBi tNsQo~ %d]B5>Q
+$sdӣa&\D="%BK
+o^>h[5.Uu}IُɃEed{u@.uy z 3 H׆f*}GG4}N(A&SՕe7c`"yf(F0) JRzs[g!z)N '߃C LAP@ҧ0}-an8($FLj,nRLQ9#)Nي uPk8PC53}DX$Q:-1@uu-dyD"iuYfG
+#wG1öM~C̏W!5s19KM +:.dh {3Zw
+$ Xp`L{/_Ab~𨉽*ޡC?
+lP3}?ւYD`Uhη7UC? lWž0(bk' ^฀ZWrn8jcBiT!
+բ2q{03Yߌp mA('-
endstream
endobj
-423 0 obj
+486 0 obj
<<
/Type /Page
-/Contents 424 0 R
-/Resources 422 0 R
+/Contents 487 0 R
+/Resources 485 0 R
/MediaBox [0 0 612 792]
-/Parent 412 0 R
-/Annots [ 420 0 R 421 0 R ]
+/Parent 475 0 R
+/Annots [ 482 0 R 483 0 R 484 0 R ]
>>
endobj
-420 0 obj
+482 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [454.971 410.245 461.433 422.182]
-/A << /S /GoTo /D (Hfootnote.7) >>
+/Rect [454.971 587.58 461.433 599.517]
+/A << /S /GoTo /D (Hfootnote.8) >>
>>
endobj
-421 0 obj
+483 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [204.392 175.985 210.854 187.922]
-/A << /S /GoTo /D (Hfootnote.8) >>
+/Rect [211.323 351.327 217.785 363.264]
+/A << /S /GoTo /D (Hfootnote.9) >>
>>
endobj
-425 0 obj
+484 0 obj
<<
-/D [423 0 R /XYZ 132.768 705.06 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [372.007 259.222 378.981 270.014]
+/A << /S /GoTo /D (section.5) >>
>>
endobj
-142 0 obj
+488 0 obj
<<
-/D [423 0 R /XYZ 133.768 450.995 null]
+/D [486 0 R /XYZ 132.768 705.06 null]
>>
endobj
-427 0 obj
+154 0 obj
<<
-/D [423 0 R /XYZ 149.011 152.866 null]
+/D [486 0 R /XYZ 133.768 628.33 null]
>>
endobj
-428 0 obj
+158 0 obj
<<
-/D [423 0 R /XYZ 149.011 133.937 null]
+/D [486 0 R /XYZ 133.768 304.51 null]
>>
endobj
-422 0 obj
+490 0 obj
+<<
+/D [486 0 R /XYZ 149.011 152.472 null]
+>>
+endobj
+491 0 obj
+<<
+/D [486 0 R /XYZ 149.011 133.543 null]
+>>
+endobj
+485 0 obj
<<
-/Font << /F86 195 0 R /F26 194 0 R /F87 231 0 R /F89 243 0 R /F78 192 0 R /F34 245 0 R /F31 246 0 R /F47 426 0 R /F82 324 0 R /F37 261 0 R /F91 279 0 R /F76 190 0 R /F90 266 0 R /F100 378 0 R >>
+/Font << /F28 215 0 R /F87 216 0 R /F79 213 0 R /F36 271 0 R /F88 255 0 R /F33 285 0 R /F49 489 0 R /F83 303 0 R /F39 286 0 R /F91 302 0 R /F98 311 0 R /F95 313 0 R /F99 323 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-432 0 obj
+494 0 obj
<<
-/Length 2669
+/Length 2600
/Filter /FlateDecode
>>
stream
-xڭYIϯt! q`!N9 ff[J!Ʌ屖~1oO7pw7R"Z g͜P:6+v'ʒcݵ~|nv2:/;uRƸU.yܪ<x1lRM=LoT>Saa}w:A7҈8]o:v2F0{Ʊ:p-O~)a@T՞h` LI7f2RS Kk7erZؽJ/f"$n=}_n)|)vRs06F\5E'ƉiXhx
-"=LFVJ̋<Yd"OETvR-.eА4%.ƇrV/վ.ۉ.9T} YRǃ
-8$=fZPCIHDFRbJYTB"tr`҂ز{]LM܌p{ NB7$G\ׅ{E# )-{UK{1yt
-)FChڗ`9lw-  [bAbOLs9w'6fŢU.җӭ6".VNPp&~Rjzq5:~?'C{L{2%1sJ̽ af~욦Cq=\l
-Q[uZ).MHM/'u&%sYacWa*Atth_>ŀP)t΃=Pn
-ɶ#Cd:e4`Af=
- jH'T朄l뢫m5 ʥHͼN DPB="O+57Z8yUlm
-[\5rl<CCCVƈC͵RvyOe
-2F0cS;4;Dq3>]DKԜ72Δ
+xڭYKϯ胁iHJec#7 ;
+W:IDzɀcVO!x4238,H@1B]`C"Wʏ0xU}yN&Lnv
+!e?Xww^JQ?r a޴JDgn# 96`q*hH16__<jJQ^b7ƬPv^[w>sL[GDE; tKY rNbw VM+ߝr\׀nӄ$4r{tK@QG8\:~Wy`>2֖8/m=swL T
+|B:sq#1$Y\[zrR>U|hZ$Bڐ[pxۀ\~E@W(GH3G¬'p VC4nS,M|dF !6KZCrG
+^Q ԯE*g4=4J}e<ҩYGvpR?zkL]ȎFL(㉉{%8o܃@yrլ\+W}W9{rR*_r3!l\"LUЧgf6%FxlX!7.<9 k`dm@[~~ˮy`P#D@C[rFX!\L$ϾI/-;*үK&ZU
+6SOG8`9qHxkupЭ5g?%%1@
+\[k Mh&:G}|va89z0r6 =OdJ5Zd|p;dtHc_}8/,,@Lj/ L^2) gz-|%r%b+ROnTUȱĀ:,xXd<d:Y2څIxKY;ZI9<P
+aJSy4q@P8"P.V:ϔrn y, i8S(J+{\D}K(D̃]̫5F.Q—⯷ST /71O.Շef9n6ze73$(-G&K-N(xrh9e\k 5W$%&XmPusw3`YzNZftӮLx{;ѧ|w"K] mCvl5Uu׃_6,
+{2&)?y4Rx.D v;ri0%tzaOY<y=.)< )3"U3Q?k˅>X7_']&ja
+8n1Wf
endstream
endobj
-431 0 obj
+493 0 obj
<<
/Type /Page
-/Contents 432 0 R
-/Resources 430 0 R
+/Contents 494 0 R
+/Resources 492 0 R
/MediaBox [0 0 612 792]
-/Parent 412 0 R
-/Annots [ 429 0 R ]
->>
-endobj
-429 0 obj
-<<
-/Type /Annot
-/Subtype /Link
-/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [386.981 623.957 393.955 634.75]
-/A << /S /GoTo /D (section.5) >>
+/Parent 475 0 R
>>
endobj
-433 0 obj
+495 0 obj
<<
-/D [431 0 R /XYZ 132.768 705.06 null]
+/D [493 0 R /XYZ 132.768 705.06 null]
>>
endobj
-146 0 obj
+162 0 obj
<<
-/D [431 0 R /XYZ 133.768 667.198 null]
+/D [493 0 R /XYZ 133.768 667.198 null]
>>
endobj
-150 0 obj
+166 0 obj
<<
-/D [431 0 R /XYZ 133.768 455.905 null]
+/D [493 0 R /XYZ 133.768 519.08 null]
>>
endobj
-430 0 obj
+492 0 obj
<<
-/Font << /F78 192 0 R /F26 194 0 R /F86 195 0 R /F31 246 0 R /F37 261 0 R /F34 245 0 R /F79 193 0 R /F89 243 0 R /F81 259 0 R /F47 426 0 R >>
+/Font << /F80 214 0 R /F28 215 0 R /F87 216 0 R /F33 285 0 R /F39 286 0 R /F36 271 0 R /F82 283 0 R /F89 267 0 R /F49 489 0 R /F81 284 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-436 0 obj
+498 0 obj
<<
-/Length 2689
+/Length 2484
/Filter /FlateDecode
>>
stream
-xڽYs۸_cG &\Ӧӗ8-AǤ#LHQ2e9k,b]0f/*e"Ks8&41Bf1 \ޔk.C`׺姛ގ&R8⣌[8Ӿ"p oۭ6$ Ȼ09yǔvϋ͊k g4JH8U(28XkºYI(>FqXl;ƱpC绦}#¾@Rɱ|XO"2;hw~MIE1J-Le*}ĖIرHZM0KDY8.C ueu;Z:U>TZ4BJd:eVK$祛ւ)K}i5-]2QA.s5H],r^rb70qX}rKԭ㍖M]y"6R7Aso[T۲X>#6o۫BbJvfX}f%`V`4~e|SξmUWKCusa'IPbZ,4|ۮ٭V%qа/0-/K&Rm[ܕ$T#3iy}g$"Uv Q.EǑRASϙXHyu:~B
-X=)ZHkGLCeJP;\qr-EYocHX=6`)X@_ЧCԴ΄rp `ZiRXgUޭ딷%`ٷ! FO0΋'I3uF6%9>&+)Ð"jDyT{S1@xбU;0>yʢ*:Y'n=Hivkò
-?Cf9NLTf̋HӱVGr( v@"doxvGrwM]*K`B]N4?_W{  BoΟxd%伎˦cE:zX/<yC®uDǜ# AE.|8ܕ }/
-1T7i8u(8
-Oܩ :ϩӱ5Ąߘ1XIć#>synw!= ƕ`"~^4:e!!_7[HWd"`r_^G>M$41h5IRA\r]mQPIt~)^B*&ϧ@{fwTX4ۑqn<jx7  kbk3/e$G(;Xoi3.=j%b-/ѷUEz]]Q/ާ/xtu=UG0A=Be3 SMTSg<Z9CkOP FDEFJ 6%϶^
-2ŒM[X3DwPKGr|s=I@Gt6.n?E ǂ"쁦V3AR<o9?Ɓ{f*o[ow{ݷ
-']Eg}@ȓÑS#L0:qCJ\O
-Q _
-T =8wGwZǯ~J739Ƿ/Azh :hS7,/v9
+xڵYKsW6TY`R٤6N*M\x\I,Ln4HQ2W&'
+Lv)UdݷKZY1`Po\U F|jh1Ew4xȫ= nUYf
+k .1U3`
+U9eCSa!aXOcFЧ^*ƕU00ƙN:+vS_Ƣ-OBǹSnJ3iHҟμ4/&Ẋ/f"s Τ]w8 >؃"yֳ㧏4'/zR )hkV*P A|ll
+Zj4]"imvm!ڢW>o74+3
+B5N:;Bg#){
+(TT BQ.1
+,~Y
+ [/uEID|+}eZ*LDo
+9
+`#hug/]Mp$pʝs?!!<DC~IȁLXOtfC+둯L7.FF}m9:bTP-V4o*<KhK<snqHS0^Dꋿ\(&M0޺\w1`1x>*'H ?!59Hْ䠢@LO
+{':ɜ2k`9;X疃b3zW916BQ [HPA 1 .K
+f/og( &h
+ϤY95Lz}TYEO=E9HiL^CbptF/98%h&q1S$rOɣV)>>a$9ۇ p0#.P!Bc-zt~r(/nn6!AfrC4b1/=3AՍ?a L&g%:<1w&`.?t>}^8c/^xyF|(ӞH/Oor34<D85.<8}GrsȧӮagCSSs7܄Eä:9i
+]1lXٺz8x摚椊B!QeWS`k0>tWy*/g؟ݿ4N4Y&~VL(AZ3ه P_2C-S\_H`
+ y+ ɂ',ud1?0<^!}
+sy@?z7\I=[c@Ե2>Z
endstream
endobj
-435 0 obj
+497 0 obj
<<
/Type /Page
-/Contents 436 0 R
-/Resources 434 0 R
+/Contents 498 0 R
+/Resources 496 0 R
/MediaBox [0 0 612 792]
-/Parent 412 0 R
+/Parent 475 0 R
>>
endobj
-437 0 obj
+499 0 obj
<<
-/D [435 0 R /XYZ 132.768 705.06 null]
+/D [497 0 R /XYZ 132.768 705.06 null]
>>
endobj
-154 0 obj
+170 0 obj
<<
-/D [435 0 R /XYZ 133.768 608.128 null]
+/D [497 0 R /XYZ 133.768 667.198 null]
>>
endobj
-158 0 obj
+174 0 obj
<<
-/D [435 0 R /XYZ 133.768 410.695 null]
+/D [497 0 R /XYZ 133.768 475.521 null]
>>
endobj
-434 0 obj
+496 0 obj
<<
-/Font << /F26 194 0 R /F86 195 0 R /F31 246 0 R /F37 261 0 R /F34 245 0 R /F80 260 0 R /F78 192 0 R /F89 243 0 R /F94 291 0 R /F81 259 0 R /F82 324 0 R >>
+/Font << /F79 213 0 R /F28 215 0 R /F87 216 0 R /F89 267 0 R /F100 329 0 R /F94 310 0 R /F33 285 0 R /F39 286 0 R /F36 271 0 R /F81 284 0 R /F82 283 0 R /F83 303 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-440 0 obj
+502 0 obj
<<
-/Length 2769
+/Length 2638
/Filter /FlateDecode
>>
stream
-xڽYm6֊(RoRp8dQh;ŦLd.{f-kRpgxq]zZ2*$[nQEQfX׿~?{ڧA`7+;v[UI|mDղiz_u"\twAx^a*u!y{:dHlhJLÉw '&Y*aWFFļ1j؇j/pg:mx˦l.7k?<]/tT߉yrP5Oo> TQEɚELNZ;wEljͨ~Ôz6ٱ6geb̡Ȍ.&QeT03s 1(r缱|~죣<ͧ3kT"pPFpjxi]hmD.:.be`+ *"G|MA(  S"sY;VjmNa &Uww܇k&KPO"+aF8'dD^MdžG}%:fҋ*oOp9teЏ{=4y4hܵ^ 8tmM3몮e
-3(rп lj2;+Mb Mص' ;:ogq>AzeHO2QMh:L Jwwl^%
-ZX+zY\`N$'vH@?>dcMDU
-gi9SErb"0LV+xQ.?8<K0c!yی=Çoا2*vO̲[2= 3uq7C5FZQ;D$f4TJ8"-Q'e/"?k#F,|+y'̅ܕ"gG&W_i:^)mv]QM/w5ȢG=+A9K(;
-=5$kw|MZ0G?s #uC"VWVMxɘv#:վ>̜\hIag7<c P˭
-I2GM?\OEQ1bPߛxOqw,˜BK@ B,Hgqd m8)AgS|f'%z<g2JTKI`XQ/*Bל\8
+xڽYێ}Л9Em E
+[;|V/Z$Lq:x@=LA`   t>Q6JRaՖ⮗byC%nĔ3\Eg:H2zhk<4XlNMUҁWІzsO"1k6JRT[1I}Ƀ.Zpz\}g'XH$LױoirskwoiM?>I>~?P& <Oޤ\A#H>Fu3C962[0A' P#VPPy3V+QWIQeW)՛wj %)VwlzX)&%Ow*
+qlRlTDž4nlGFuHD19F;@=,GpO/2%dO>_/ 'j$$ߟ h9AR2ɐupt1ۇ:؍<H>fc{1ۙpOœ sm㛖N&=''*Akj 7x;,2qdD4륃Ȱhw8>W QB{:M&L,@eZIh~*Btz
+A(U鯅8V&a~!P%BE2G-аqVfV~ȿRDI3Lܙ@*QU%dhʉm65Ѭ-=7al7S;@駡BRDN: BC$h!5fmkݱ$&Ώҩ sQB+ZN2Ƒ
+n$bggE1s5itR? 7cgLIFJ| k +HʃX~pÏ Tqď6 G#ּ%VeE~ohzkOkq5-s@tI$U%PׂT`5PN,ؚc'!MeohON9PJ5{!u5|K ^96釪ur!eƹVd-gnC!2EٙF(9<034MLOsnj i8Rydz"Wb.I V 8MΐP"r숻: U˂@W@%)
+'uAJ(CZAOd'm~ENL"YFi90_=[q*{NX-BY;@|Vv2=#O `~׹ˁU; CIh ՘'S5h]H/gt,h؝l/[a\ ~Sb y;n* h*,ktr}%οk;zhDmZ(70R1r-G~
+zDtt~}݉#ox˘wjM]ծ8slIh|>G?rg'Wb/wf<nԿ4˴#U mSs"_`R_RGOaqGF6#-ml6Lh
+C域z$c~NQ9
endstream
endobj
-439 0 obj
+501 0 obj
<<
/Type /Page
-/Contents 440 0 R
-/Resources 438 0 R
+/Contents 502 0 R
+/Resources 500 0 R
/MediaBox [0 0 612 792]
-/Parent 412 0 R
+/Parent 475 0 R
>>
endobj
-441 0 obj
+503 0 obj
<<
-/D [439 0 R /XYZ 132.768 705.06 null]
+/D [501 0 R /XYZ 132.768 705.06 null]
>>
endobj
-438 0 obj
+500 0 obj
<<
-/Font << /F37 261 0 R /F26 194 0 R /F86 195 0 R /F34 245 0 R /F31 246 0 R /F80 260 0 R /F81 259 0 R /F38 263 0 R /F89 243 0 R /F87 231 0 R >>
+/Font << /F94 310 0 R /F28 215 0 R /F87 216 0 R /F36 271 0 R /F33 285 0 R /F39 286 0 R /F81 284 0 R /F82 283 0 R /F40 288 0 R /F89 267 0 R /F88 255 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-445 0 obj
+507 0 obj
<<
-/Length 2472
+/Length 2936
/Filter /FlateDecode
>>
stream
-xڥYOۺ SfDKڙvZ,L߽CIyi.k
-$~
-'\%HT :@u2q>!a}:=i.8, &eH42 {L%@бc(
-b7hׄθ
-,Fw
-|Lt_i?LJ~bf;f7޾ʼNDLX*0:`ȩwx &E5 GA(@aS"$5mWsAX,)E x}EbsMQ@fuu)tY5>C̎Sjk/+;(n37'I1b@;<R>Iˎan+(fEhrgR+*V}Mu?9UAO3=O<@&<VM)꞉7`ջΩke4hb7`i}HXt8\g!?
-łMhzWnPy=Eu{Zgn`Μ6y!_Ӎ8c9\ 6URO @%y Tː8UWZ5.ؤ٨35r:B3ұN=8si>9 CXt. G\ardqxu# 傶La7d*
-֎A2
-}p9JsjBEDU_eBQCwjNTAxx.I*I"#̔]3Q
-H=2Fٵ`W ^EHU-TU݊='g;!&.]j]dZXO!@ɧuR(WQmӦJ= ;JZfu6l~ VJꨒog)L=w<Įҩ^X&<ah$ BV땵t3u7O!,
-hQ:?n&88[]|-4 b1~Cg
-Aztߡ@ /4l_ : ZoQ0tA{
+xڵYݏ۸߿} Ċ(R_4}Z0m%(gwe˫M}pHg~3C'*YKn{2*4_VdqeUq}9%UL޼KIi\h [oN"ZföiY]ͱ/WQ:#;&m<ڮew[hwwqnQ*29CSi1*y|YDvpL;{#{=7(m˄f[7yY!r}v뎮CD&-lzt}ZoPJOpOUz QԖቻv؟8C::9NM<Q@Im羀*8j6QUw[H ׍`WS29},JeA/JsN¤c%@^G^48Fid|}%&N2:w hslFr4:{tcyv[t\SIS<x"=?oZyOXM[ O7BCc|u~s%Glhi(
+|~>4+ѿΤDvpjƠDw۞<u/9 ج\[9\_C.ǀܵ{5b '.ICE5<f2Ǔd1y^(:5t.b쯂^0{;`d_ȐӲ(0qX~-; o-a*\@5ѦA(CXH @*5iF_8s@n7;Y(#@':5pc0}a^Ň\':%ɵCw jWDXjRS=_GW [a<7uKӟnym<ARў{7GeVciٺ&-|{_85_KAz=& \v%EHII
+:T} upp-* 7-^9+GkWk-M~0&Y:&6n4]t.p84kE0BY/-JHXŊ|s׊5p̓7l<0r'
+Jx3{{j,+ulzx ԂcI%Mo_)VU@cP>ٖctwUhAG0C!yB~t} a``@~&\*@r N GHށgT9LPA-a~ks
endstream
endobj
-444 0 obj
+506 0 obj
<<
/Type /Page
-/Contents 445 0 R
-/Resources 443 0 R
+/Contents 507 0 R
+/Resources 505 0 R
/MediaBox [0 0 612 792]
-/Parent 456 0 R
-/Annots [ 442 0 R ]
+/Parent 509 0 R
+/Annots [ 504 0 R ]
>>
endobj
-442 0 obj
+504 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [336.939 506.301 359.41 518.257]
+/Rect [284.75 453.072 307.221 465.027]
/A << /S /GoTo /D (subsubsection.5.5.1) >>
>>
endobj
-446 0 obj
+508 0 obj
<<
-/D [444 0 R /XYZ 132.768 705.06 null]
+/D [506 0 R /XYZ 132.768 705.06 null]
>>
endobj
-162 0 obj
+505 0 obj
<<
-/D [444 0 R /XYZ 133.768 305.541 null]
+/Font << /F94 310 0 R /F28 215 0 R /F87 216 0 R /F36 271 0 R /F33 285 0 R >>
+/ProcSet [ /PDF /Text ]
>>
endobj
-447 0 obj
+515 0 obj
+<<
+/Length 2733
+/Filter /FlateDecode
+>>
+stream
+xڍYIW
+հ6.㓓gA qg6J,uL2I);}Qm{&M?޽}o$jswHEdĦBi+7lRmn"v;МE;ۏUE7;%ExוUY;^8!V)\H' &R^%wwmk/ynدkءevfBe9ܒԻw^yB@y.x/=nv:΅x$r0'`TGھ5|{?Hmkᅾ*,lY{~DR<owftn}pU{Aψ/94s{(dj*.Pw6i;K)ڵOzdimr^eTB)0U ;m9g+'N(/vNDsȵVP"Z6?;ׯ1"@ \<h1ѱiOE*0KJUxM%vJ߁37ǰZJDŎ5=f=3CMMPMBjjv3eސ`[:_2t5&%`f$UU)kElu<ʨsumIϜ\3%hL/ښ'H.L,6;$
+HZ4ړjh4ÃE
+$Ok3aAv;\O
+FyH
+Mv$$%
+whh\b@3)Ʌ ^/-3aF][21bB\vÇms4*Bf#֍Zvx lN (E2~vL0asQ0*҆cҝ[3k1"1c>xb&}e'\ۍM,I_s[׈NB B/ºw<Rr,dWo ;+IDcX^CH {8{GSN^=o2Bw3vt4
+i-B#N'ȇ[aepq@b rׯ"\J)9;8=b >*M}
+gHKߋ!OttM) Q ʯ6BeI1[JM\HC
+; __ƠmټƣVGbU%#KF%,I ]k>+-Kf
+T Zs53_qa$p|#8SuFVݭ
+Jĸ*pcOCྥ#M%3S͉
+n@5NWw ar 80Kɒ
+e6^=y o6zw
+.U3MZ [p{`7-@B Q `3U3u6llHE!0oSEe;FyjJ97]jMEBkWd@/ v \sB[0
+u&7. -7ǴT EZ/*trxw
+`ebJ@i!xSQ)bBc*_EDm
+endstream
+endobj
+514 0 obj
<<
-/D [444 0 R /XYZ 133.768 259.809 null]
+/Type /Page
+/Contents 515 0 R
+/Resources 513 0 R
+/MediaBox [0 0 612 792]
+/Parent 509 0 R
+/Annots [ 510 0 R 511 0 R 512 0 R ]
>>
endobj
-448 0 obj
+510 0 obj
<<
-/D [444 0 R /XYZ 133.768 243.869 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [249.397 449.169 264.12 459.961]
+/A << /S /GoTo /D (subsection.5.4) >>
>>
endobj
-449 0 obj
+511 0 obj
<<
-/D [444 0 R /XYZ 133.768 227.929 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [263.483 285.781 285.955 296.574]
+/A << /S /GoTo /D (subsubsection.5.5.2) >>
>>
endobj
-450 0 obj
+512 0 obj
<<
-/D [444 0 R /XYZ 133.768 211.435 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [218.396 198.11 228.829 210.047]
+/A << /S /GoTo /D (Hfootnote.10) >>
>>
endobj
-451 0 obj
+516 0 obj
<<
-/D [444 0 R /XYZ 133.768 195.495 null]
+/D [514 0 R /XYZ 132.768 705.06 null]
>>
endobj
-452 0 obj
+178 0 obj
<<
-/D [444 0 R /XYZ 133.768 179.555 null]
+/D [514 0 R /XYZ 133.768 667.198 null]
>>
endobj
-453 0 obj
+517 0 obj
<<
-/D [444 0 R /XYZ 133.768 163.615 null]
+/D [514 0 R /XYZ 133.768 593.627 null]
>>
endobj
-454 0 obj
+518 0 obj
<<
-/D [444 0 R /XYZ 133.768 147.674 null]
+/D [514 0 R /XYZ 133.768 573.646 null]
>>
endobj
-455 0 obj
+519 0 obj
<<
-/D [444 0 R /XYZ 133.768 131.734 null]
+/D [514 0 R /XYZ 133.768 448.172 null]
>>
endobj
-443 0 obj
+520 0 obj
+<<
+/D [514 0 R /XYZ 133.768 347.992 null]
+>>
+endobj
+521 0 obj
+<<
+/D [514 0 R /XYZ 133.768 282.792 null]
+>>
+endobj
+522 0 obj
+<<
+/D [514 0 R /XYZ 133.768 262.812 null]
+>>
+endobj
+523 0 obj
+<<
+/D [514 0 R /XYZ 133.768 197.114 null]
+>>
+endobj
+524 0 obj
+<<
+/D [514 0 R /XYZ 133.768 167.226 null]
+>>
+endobj
+525 0 obj
+<<
+/D [514 0 R /XYZ 149.011 132.65 null]
+>>
+endobj
+513 0 obj
<<
-/Font << /F37 261 0 R /F26 194 0 R /F86 195 0 R /F78 192 0 R /F94 291 0 R /F89 243 0 R >>
+/Font << /F79 213 0 R /F28 215 0 R /F87 216 0 R /F88 255 0 R /F89 267 0 R /F36 271 0 R /F33 285 0 R /F98 311 0 R /F95 313 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-459 0 obj
+530 0 obj
<<
-/Length 735
+/Length 1765
/Filter /FlateDecode
>>
stream
-xڵUKo0WpL\4z[R4 MU]`ͅ{x<,X,r&OT)Mc"
-&VD2b=I*""*a:d5-mxPu5g>g4FcgA%1Wh]`0R[X֢/BٸGiRc
-f\)]G"R)bҖڃ@q 0+vd⎔ISSY{mB Kܡ@Bݮ;TK#&rݽ{p˶= r"
+xڥXˎ6+ܝ\)6ȦESbMƒm!ɕLEӜ4XEqn~{EWןo_ݼ6L*bhejso'l?1~yS&mSmWnY۝2/2MЛ-xXU4[5fERǬ/?oI
+?ҝ}YvCӆ)*D5.חY}Vͻ|Z8XdB敟"ڲaڛ`2Fr)L@wM2_N8i״yYg͋"t2>68q_0nXJV #V䝳6Ҩ8^v*õx.Nٵkg+]fwB^޻@uHĎ7F͍YfYHepe" 2)BHM}^CKW@Lql5+B o47Jp @a PZ2H G.҈2>ȋCvzv?\~.Kg`#~ʎ|T.3.T`DScln`kr=`q!Vv`[})ť=^CAELLaB [1.%J
+1Y_K储!&Dq@}E`\3nZ_0YU=;-325}pS@@["
+
+(C&bٳ0F^%A4K0$vABG5vS/ə<v:uvɯ~Ll
endstream
endobj
-458 0 obj
+529 0 obj
<<
/Type /Page
-/Contents 459 0 R
-/Resources 457 0 R
+/Contents 530 0 R
+/Resources 528 0 R
/MediaBox [0 0 612 792]
-/Parent 456 0 R
+/Parent 509 0 R
+/Annots [ 526 0 R 527 0 R ]
>>
endobj
-460 0 obj
+526 0 obj
<<
-/D [458 0 R /XYZ 132.768 705.06 null]
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [402.213 530.212 416.935 542.167]
+/A << /S /GoTo /D (subsection.3.1) >>
>>
endobj
-461 0 obj
+527 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [184.418 474.974 206.89 485.767]
+/A << /S /GoTo /D (subsubsection.6.1.1) >>
+>>
+endobj
+531 0 obj
<<
-/D [458 0 R /XYZ 133.768 649.321 null]
+/D [529 0 R /XYZ 132.768 705.06 null]
>>
endobj
-462 0 obj
+532 0 obj
<<
-/D [458 0 R /XYZ 133.768 632.827 null]
+/D [529 0 R /XYZ 133.768 667.198 null]
>>
endobj
-463 0 obj
+533 0 obj
<<
-/D [458 0 R /XYZ 133.768 573.605 null]
+/D [529 0 R /XYZ 133.768 651.258 null]
>>
endobj
-464 0 obj
+534 0 obj
<<
-/D [458 0 R /XYZ 133.768 557.111 null]
+/D [529 0 R /XYZ 133.768 632.827 null]
>>
endobj
-465 0 obj
+535 0 obj
<<
-/D [458 0 R /XYZ 133.768 529.215 null]
+/D [529 0 R /XYZ 133.768 591.537 null]
>>
endobj
-457 0 obj
+536 0 obj
+<<
+/D [529 0 R /XYZ 133.768 571.557 null]
+>>
+endobj
+537 0 obj
+<<
+/D [529 0 R /XYZ 133.768 529.215 null]
+>>
+endobj
+538 0 obj
+<<
+/D [529 0 R /XYZ 133.768 501.874 null]
+>>
+endobj
+539 0 obj
+<<
+/D [529 0 R /XYZ 133.768 473.978 null]
+>>
+endobj
+182 0 obj
+<<
+/D [529 0 R /XYZ 133.768 409.152 null]
+>>
+endobj
+540 0 obj
+<<
+/D [529 0 R /XYZ 133.768 362.867 null]
+>>
+endobj
+541 0 obj
+<<
+/D [529 0 R /XYZ 133.768 347.481 null]
+>>
+endobj
+542 0 obj
+<<
+/D [529 0 R /XYZ 133.768 331.54 null]
+>>
+endobj
+543 0 obj
+<<
+/D [529 0 R /XYZ 133.768 315.047 null]
+>>
+endobj
+544 0 obj
+<<
+/D [529 0 R /XYZ 133.768 299.106 null]
+>>
+endobj
+545 0 obj
+<<
+/D [529 0 R /XYZ 133.768 271.765 null]
+>>
+endobj
+546 0 obj
+<<
+/D [529 0 R /XYZ 133.768 255.271 null]
+>>
+endobj
+547 0 obj
+<<
+/D [529 0 R /XYZ 133.768 239.331 null]
+>>
+endobj
+548 0 obj
+<<
+/D [529 0 R /XYZ 133.768 223.39 null]
+>>
+endobj
+549 0 obj
+<<
+/D [529 0 R /XYZ 133.768 183.54 null]
+>>
+endobj
+550 0 obj
<<
-/Font << /F94 291 0 R /F26 194 0 R /F89 243 0 R /F86 195 0 R /F37 261 0 R /F31 246 0 R >>
+/D [529 0 R /XYZ 133.768 167.6 null]
+>>
+endobj
+528 0 obj
+<<
+/Font << /F28 215 0 R /F87 216 0 R /F36 271 0 R /F89 267 0 R /F79 213 0 R /F100 329 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-466 0 obj
+553 0 obj
+<<
+/Length 738
+/Filter /FlateDecode
+>>
+stream
+xڵUɎ0Wpu&R}g04K%nf2U=}!O%Kpe(PbCozrSų0Fp$9XFCkŨsHHTY@͡/ڧH.2,
+C@> A] X$rBRJ[%\\B u,8 6RdZӐ~@  
+/y1|*
+!rXU%h4,h|"Z
+XDλ;GTԹ8e z9~.mgyPНԈ5FV&jcuJϟε)NTpg6MfҮ8FCe~;2 v}2)F "{^jxRHL<Մ'Ko&gUqN|$'l99(`9w@/sc,XZʕ?˕[ XYSAߙGt/CCx{=AQ>YK+ֶ́v5Z UZ20!̒Y%:e"qMJ_tPzn^V0'AL͠14nW"ʂ-Nbv Do/k D|2e^ʰl]TB9\ݮ],2&%p\= 8/e
+endstream
+endobj
+552 0 obj
+<<
+/Type /Page
+/Contents 553 0 R
+/Resources 551 0 R
+/MediaBox [0 0 612 792]
+/Parent 509 0 R
+>>
+endobj
+554 0 obj
+<<
+/D [552 0 R /XYZ 132.768 705.06 null]
+>>
+endobj
+555 0 obj
+<<
+/D [552 0 R /XYZ 133.768 648.767 null]
+>>
+endobj
+556 0 obj
+<<
+/D [552 0 R /XYZ 133.768 632.827 null]
+>>
+endobj
+557 0 obj
+<<
+/D [552 0 R /XYZ 133.768 604.932 null]
+>>
+endobj
+551 0 obj
+<<
+/Font << /F100 329 0 R /F28 215 0 R /F89 267 0 R /F87 216 0 R /F39 286 0 R /F33 285 0 R >>
+/ProcSet [ /PDF /Text ]
+>>
+endobj
+558 0 obj
[472.2 555.6 805.6 916.7 1138.9 1277.8]
endobj
-468 0 obj
+560 0 obj
[777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 777.8 777.8 777.8 472.2 666.7 666.7 666.7 638.9 722.2 597.2 569.5 666.7 708.3 277.8 472.2 694.5 541.7 875 708.3 736.1 638.9 736.1 645.8 555.6 680.6 687.5 666.7 944.4 666.7 666.7 611.1 288.9 500 288.9 555.6 666.7 277.8 480.6 516.7 444.5 516.7 444.5 305.6 500 516.7 238.9 266.7 488.9 238.9 794.5 516.7 500 516.7 516.7 341.7 383.3 361.1]
endobj
-469 0 obj
-[531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531 531.3 531.3 531 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3]
-endobj
-471 0 obj
+562 0 obj
[533.6]
endobj
-473 0 obj
-[892.9 339.3 892.9 585.3 892.9 585.3 892.9 892.9 892.9 892.9 892.9 892.9 892.9 1138.9 585.3 585.3 892.9 892.9 892.9 892.9 892.9 892.9 892.9 892.9 892.9 892.9 892.9 892.9 1138.9 1138.9 892.9 892.9 1138.9 1138.9 585.3 585.3 1138.9 1138.9 1138.9 892.9 1138.9 1138.9 708.3 708.3 1138.9 1138.9 1138.9 892.9 329.4 1138.9 769.8 769.8 1015.9 1015.9 0 0 646.8 646.8 769.8 585.3 831.4 831.4 892.9 892.9 708.3 917.6 753.4 620.2 889.5 616.1 818.4 688.5 978.7 646.5 782.2 871.7 791.7 1342.7 935.6 905.8 809.2 935.9 981 702.2 647.8 717.8 719.9 1135.1 818.9 764.4 823.1 769.8 769.8 769.8 769.8 769.8 708.3 708.3 523.8 523.8 523.8 523.8 585.3 585.3 462.3 462.3 339.3 585.3 585.3 708.3 585.3 339.3 938.5 859.1 954.4]
+563 0 obj
+[525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525]
endobj
-474 0 obj
-[525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525]
+564 0 obj
+[531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531 531.3 531.3 531 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3]
endobj
-476 0 obj
+565 0 obj
+[619.8 590.3 590.3 885.4 885.4 531.3 295.1 403.1 885.4 531.3 885.4 826.4 295.1 413.2 413.2 531.3 826.4 295.1 354.2 295.1 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 295.1 295.1 826.4 826.4 826.4 501.8 826.4 795.9 752.1 767.4 811.1 722.6 693.1 833.5 795.9 382.6 545.5 825.4 663.5 972.9 795.9 826.4 722.6 826.4 781.6 590.3 767.4 795.9 795.9 1091 795.9 795.9 649.3 295.1 531.3 295.1 555.6 795.9 295.1 531.3 590.3 472.2 590.3 472.2 324.7 531.3 590.3 295.1 324.7 560.7 295.1 885.4 590.3 531.3 590.3 560.7 414.1 419.1 413.2 590.3 560.7 767.4 560.7 560.7 472.2 531.3 295.1 531.3 555.6 177.1 795.9 795.9 767.4 767.4 811.1 722.6 722.6 833.5 663.5 663.5 663.5 795.9 795.9 795.9 826.4 781.6 781.6 590.3 590.3 590.3 767.4 767.4 795.9 795.9 795.9 649.3 649.3 649.3 889.9 382.6 590.3 520.1 531.3 531.3 472.2 472.2 590.3 472.2 472.2 531.3 295.1 295.1 357.1 590.3 590.3 538.1 531.3 414.1 414.1 419.1 419.1 419.1 413.2 413.2 590.3 590.3 560.7 472.2 472.2 472.2 590.3 295.1 501.8 795.9 795.9 795.9 795.9 795.9 795.9 795.9 958.7 767.4 722.6 722.6 722.6 722.6 382.6 382.6 382.6 382.6 811.1 795.9 826.4 826.4 826.4 826.4 826.4 1076.7 826.4 795.9 795.9 795.9 795.9 795.9 663.5 1180.6 531.3 531.3 531.3 531.3 531.3 531.3 767.4 472.2 472.2 472.2 472.2 472.2 295.1 295.1 295.1 295.1 531.3 590.3 531.3 531.3 531.3 531.3 531.3 826.4 531.3 590.3 590.3 590.3 590.3]
+endobj
+566 0 obj
+[611.1 611.1 611.1 611.1 611.1 611.1 611.1 611.1 611.1 611.1 351.8 351.8 963 935.2 963 578.7 935.2 896.3]
+endobj
+568 0 obj
+[777.8]
+endobj
+570 0 obj
+[892.9 339.3 892.9 585.3 892.9 585.3 892.9 892.9 892.9 892.9 892.9 892.9 892.9 1138.9 585.3 585.3 892.9 892.9 892.9 892.9 892.9 892.9 892.9 892.9 892.9 892.9 892.9 892.9 1138.9 1138.9 892.9 892.9 1138.9 1138.9 585.3 585.3 1138.9 1138.9 1138.9 892.9 1138.9 1138.9 708.3 708.3 1138.9 1138.9 1138.9 892.9 329.4 1138.9 769.8 769.8 1015.9 1015.9 0 0 646.8 646.8 769.8 585.3 831.4 831.4 892.9 892.9 708.3 917.6 753.4 620.2 889.5 616.1 818.4 688.5 978.7 646.5 782.2 871.7 791.7 1342.7 935.6 905.8 809.2 935.9 981 702.2 647.8 717.8 719.9 1135.1 818.9 764.4 823.1 769.8 769.8 769.8 769.8 769.8 708.3 708.3 523.8 523.8 523.8 523.8 585.3 585.3 462.3 462.3 339.3 585.3 585.3 708.3 585.3 339.3 938.5 859.1 954.4]
+endobj
+572 0 obj
[607 473.6 453.6 447.2 638.9 607 830.6 607]
endobj
-477 0 obj
+573 0 obj
[736.1]
endobj
-478 0 obj
+574 0 obj
[680.6 680.6 680.6]
endobj
-479 0 obj
-[619.8 590.3 590.3 885.4 885.4 531.3 295.1 403.1 885.4 531.3 885.4 826.4 295.1 413.2 413.2 531.3 826.4 295.1 354.2 295.1 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 531.3 295.1 295.1 826.4 826.4 826.4 501.8 826.4 795.9 752.1 767.4 811.1 722.6 693.1 833.5 795.9 382.6 545.5 825.4 663.5 972.9 795.9 826.4 722.6 826.4 781.6 590.3 767.4 795.9 795.9 1091 795.9 795.9 649.3 295.1 531.3 295.1 555.6 795.9 295.1 531.3 590.3 472.2 590.3 472.2 324.7 531.3 590.3 295.1 324.7 560.7 295.1 885.4 590.3 531.3 590.3 560.7 414.1 419.1 413.2 590.3 560.7 767.4 560.7 560.7 472.2 531.3 295.1 531.3]
-endobj
-481 0 obj
+576 0 obj
[458.3 458.3 416.7 416.7 472.2 472.2 472.2 472.2 583.3 583.3 472.2 472.2 333.3 555.6 577.8 577.8 597.2 597.2 736.1 736.1 527.8 527.8 583.3 583.3 583.3 583.3 750 750 750 750 1044.4 1044.4 791.7 791.7 583.3 583.3 638.9 638.9 638.9 638.9 805.6 805.6 805.6 805.6 1277.8 1277.8 811.1 811.1 875 875 666.7 666.7 666.7 666.7 666.7 666.7 888.9 888.9 888.9 888.9 888.9 888.9 888.9 666.7 875 875 875 875 611.1 611.1 833.3 1111.1 472.2 555.6 1111.1 1511.1 1111.1 1511.1 1111.1 1511.1 1055.6 944.5 472.2 833.3 833.3 833.3 833.3 833.3 1444.5 1277.8 555.6 1111.1 1111.1 1111.1 1111.1 1111.1 944.5 1277.8 555.6 1000 1444.5 555.6 1000 1444.5 472.2 472.2 527.8 527.8 527.8 527.8 666.7 666.7 1000]
endobj
-482 0 obj
+577 0 obj
[777.8 277.8 777.8 500 777.8 500 777.8 777.8 777.8 777.8 777.8 777.8 777.8 1000 500 500 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 1000 1000 777.8 777.8 1000 1000 500 500 1000 1000 1000 777.8 1000 1000 611.1 611.1 1000 1000 1000 777.8 275 1000 666.7 666.7 888.9 888.9 0 0 555.6 555.6 666.7 500 722.2 722.2 777.8 777.8 611.1 798.5 656.8 526.5 771.4 527.8 718.7 594.9 844.5 544.5 677.8 762 689.7 1200.9 820.5 796.1 695.6 816.7 847.5 605.6 544.6 625.8 612.8 987.8 713.3 668.3 724.7 666.7 666.7 666.7 666.7 666.7 611.1 611.1 444.4 444.4 444.4 444.4 500 500 388.9 388.9 277.8 500 500 611.1 500 277.8 833.3 750 833.3]
endobj
-483 0 obj
+578 0 obj
+[625 833.3 777.8 694.5 666.7 750 722.2 777.8 722.2 777.8 722.2 583.3 555.6 555.6 833.3 833.3 277.8 305.6 500 500 500 500 500 750 444.5 500 722.2 777.8 500 902.8 1013.9 777.8 277.8 277.8 472 833.3 500 833.3 777.8 277.8 388.9 388.9 500 777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 277.8 777.8 472.2 472.2 777.8 750 708.3 722.2 763.9 680.6 652.8 784.7 750 361.1 513.9 777.8 625 916.7 750 777.8 680.6 777.8 736.1 555.6 722.2 750 750 1027.8 750 750 611.1 277.8 472 277.8 500 277.8 277.8 500 555.6 444.5 555.6 444.5 305.6 500 555.6 277.8 305.6 527.8 277.8 833.3 555.6 500 555.6 527.8 391.7 394.5]
+endobj
+579 0 obj
[877 781.7 754 843.3 815.5 877 815.5 877 815.5 677.6 646.9 646.9 970.3 970.3 323.4 354.2 569.4 569.4 569.4 569.4 569.4 843.3 507.9 569.4 815.5 877 569.4 1013.9 1136.9 877 323.4 323.4 538.4 938.5 569.4 938.5 877 323.4 446.4 446.4 569.4 877 323.4 384.9 323.4 569.4 569.4 569.4 569.4 569.4 569.4 569.4 569.4 569.4 569.4 569.4 323.4 323.4 323.4 877]
endobj
-484 0 obj
+580 0 obj
[742.7 647.8 600.1 519.3 476.1 519.8 588.6 544.1 422.8 668.8 677.6 694.6 572.8 519.8 668 592.7 662 526.8 632.9 686.9 713.8 756 719.7 539.7 689.9 950 592.7 439.2 751.4 1138.9 1138.9 1138.9 1138.9 339.3 339.3 585.3 585.3 585.3 585.3 585.3 585.3 585.3 585.3 585.3 585.3 585.3 585.3 339.3 339.3 892.9 585.3 892.9 585.3 610.1 859.1 863.2 819.4 934.1 838.7 724.5 889.4 935.6 506.3 632 959.9 783.7 1089.4 904.9 868.9 727.3 899.7 860.6 701.5 674.8 778.2 674.6 1074.4 936.9 671.5 778.4 462.3 462.3 462.3 1138.9 1138.9 478.2 619.7 502.4 510.5 594.7 542 557.1 557.3 668.8 404.2 472.7 607.3 361.3 1013.7 706.2 563.9 588.9 523.6 530.4 539.2 431.6 675.4 571.4 826.4 647.8 579.4]
endobj
-485 0 obj
-[625 833.3 777.8 694.5 666.7 750 722.2 777.8 722.2 777.8 722.2 583.3 555.6 555.6 833.3 833.3 277.8 305.6 500 500 500 500 500 750 444.5 500 722.2 777.8 500 902.8 1013.9 777.8 277.8 277.8 472 833.3 500 833.3 777.8 277.8 388.9 388.9 500 777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 277.8 777.8 472.2 472.2 777.8 750 708.3 722.2 763.9 680.6 652.8 784.7 750 361.1 513.9 777.8 625 916.7 750 777.8 680.6 777.8 736.1 555.6 722.2 750 750 1027.8 750 750 611.1 277.8 472 277.8 500 277.8 277.8 500 555.6 444.5 555.6 444.5 305.6 500 555.6 277.8 305.6 527.8 277.8 833.3 555.6 500 555.6 527.8 391.7 394.5]
-endobj
-486 0 obj
+581 0 obj
[444.4 405.9 437.5 496.5 469.4 353.9 576.2 583.3 602.6 494 437.5 570 517 571.4 437.2 540.3 595.8 625.7 651.4 622.5 466.3 591.4 828.1 517 362.8 654.2 1000 1000 1000 1000 277.8 277.8 500 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 777.8 500 777.8 500 530.9 750 758.5 714.7 827.9 738.2 643.1 786.3 831.3 439.6 554.5 849.3 680.6 970.1 803.5 762.8 642 790.6 759.3 613.2 584.4 682.8 583.3 944.4 828.5 580.6 682.6 388.9 388.9 388.9 1000 1000 416.7 528.6 429.2 432.8 520.5 465.6 489.6 477 576.2 344.5 411.8 520.6 298.4 878 600.2 484.7 503.1 446.4 451.2 468.8 361.1 572.5 484.7 715.9 571.5 490.3 465.1 322.5 384 636.5 500]
endobj
-487 0 obj
+582 0 obj
[613.3 562.2 587.8 881.7 894.4 511.1 306.7 400.7 817.8 500 817.8 766.7 306.7 408.9 408.9 511.1 766.7 306.7 357.8 306.7 511.1 511.1 511.1 511.1 511.1 511.1 511.1 511.1 511.1 511.1 511.1 306.7 306.7 777.8 766.7 777.8 511.1 766.7 743.4 703.9 715.6 755 678.4 652.8 773.6 743.4 385.5 525 768.9 627.2 896.7 743.4 766.7 678.4 766.7 729.5 562.2 715.6 743.4 743.4 998.9 743.4 743.4 613.3 306.7 500 306.7 555.6 743.4 306.7 511.1 460 460 511.1 460 306.7 460 511.1 306.7 306.7 460 255.5 817.8 562.2 511.1 511.1 460 421.7 408.9 332.2 536.7 460 664.5 463.9 485.6]
endobj
-488 0 obj
-[569.4 569.4 569.4 569.4 569.4 569.4 569.4 569.4 569.4 323.4 323.4 892.9 877 892.9 538.7 877 843.3]
+583 0 obj
+[569.4 569.4 569.4 569.4 569.4 569.4 569.4 569.4 569.4 569.4 323.4 323.4 892.9 877 892.9 538.7 877 843.3]
endobj
-489 0 obj
+584 0 obj
[525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525]
endobj
-490 0 obj
-[500 1000 0 391.7 277.8 305.6 583.3 555.6 555.6 833.3 833.3 500 277.8 373.8 833.3 500 833.3 777.8 277.8 388.9 388.9 500 777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 777.8 777.8 777.8 472.2 777.8 750 708.3 722.2 763.9 680.6 652.8 784.7 750 361.1 513.9 777.8 625 916.7 750 777.8 680.6 777.8 736.1 555.6 722.2 750 750 1027.8 750 750 611.1 277.8 500 277.8 555.6 750 277.8 500 555.6 444.5 555.6 444.5 305.6 500 555.6 277.8 305.6 527.8 277.8 833.3 555.6 500 555.6 527.8 391.7 394.5 388.9 555.6 527.8 722.2 527.8 527.8 444.5 500 277.8 500]
+585 0 obj
+[500 1000 0 391.7 277.8 305.6 583.3 555.6 555.6 833.3 833.3 500 277.8 373.8 833.3 500 833.3 777.8 277.8 388.9 388.9 500 777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 777.8 777.8 777.8 472.2 777.8 750 708.3 722.2 763.9 680.6 652.8 784.7 750 361.1 513.9 777.8 625 916.7 750 777.8 680.6 777.8 736.1 555.6 722.2 750 750 1027.8 750 750 611.1 277.8 500 277.8 555.6 750 277.8 500 555.6 444.5 555.6 444.5 305.6 500 555.6 277.8 305.6 527.8 277.8 833.3 555.6 500 555.6 527.8 391.7 394.5 388.9 555.6 527.8 722.2 527.8 527.8 444.5 500 277.8 500 555.6 166.7 750 750 722.2 722.2 763.9 680.6 680.6 784.7 625 625 625 750 750 750 777.8 736.1 736.1 555.6 555.6 555.6 722.2 722.2 750 750 750 611.1 611.1 611.1 838.9 361.1 555.6 484]
endobj
-491 0 obj
+586 0 obj
[670.8 638.9 638.9 958.3 958.3 575 350 481.5 958.3 575 958.3 894.4 319.5 447.2 447.2 575 894.4 319.5 383.3 319.5 575 575 575 575 575 575 575 575 575 575 575 319.5 319.5 894.4 894.4 894.4 543.1 894.4 869.4 818.1 830.6 881.9 755.6 723.6 904.2 900 436.1 594.5 901.4 691.7 1091.7 900 863.9 786.1 863.9 862.5 638.9 800 884.7 869.4 1188.9 869.4 869.4 702.8 319.5 575 319.5 555.6 869.4 319.5 559 638.9 511.1 638.9 527.1 351.4 575 638.9 319.5 351.4 607 319.5 958.3 638.9 575 638.9 607 473.6 453.6 447.2 638.9 607 830.6 607 607]
endobj
-492 0 obj
+587 0 obj
[656.2 625 625 937.5 937.5 562.5 342.6 462.5 937.5 562.5 937.5 875 312.5 437.5 437.5 562.5 875 312.5 375 312.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 312.5 312.5 894.4 875 894.4 531.2 875 849.5 799.7 812.5 862.3 738.4 707.2 884.2 879.6 419 581 880.7 675.9 1067.2 879.6 844.9 768.5 844.9 839.2 625 782.4 864.6 849.5 1162 849.5 849.5 687.5 312.5 575 312.5 555.6 849.5 312.5 546.9 625 500 625 513.3 343.7 562.5 625 312.5 343.7 593.7 312.5 937.5 625 562.5 625 593.7 459.5 443.7 437.5 625 593.7 812.5 593.7 593.7]
endobj
-493 0 obj
-[611.1 611.1 611.1 611.1 611.1 611.1 611.1 611.1 611.1 351.8 351.8 963 935.2 963 578.7 935.2 896.3]
-endobj
-494 0 obj
+588 0 obj
[856.4 799.4 713.6 685.2 770.7 742.3 799.4 742.3 799.4 742.3 599.6 571 571 856.4 856.4 285.5 314 513.9 513.9 513.9 513.9 513.9 770.7 456.8 513.9 742.3 799.4 513.9 927.8 1042 799.4 285.5 285.5 485.9 856.4 513.9 856.4 799.4 285.5 399.7 399.7 513.9 799.4 285.5 342.6 285.5 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 285.5 285.5 285.5 799.4 485.3 485.3 799.4 770.7 727.9 742.3 785 699.4 670.8 806.5 770.7 371 528.1 799.2 642.3 942 770.7 799.4 699.4 799.4 756.4 571 742.3 770.7 770.7 1056.1 770.7 770.7 628.1 285.5 485.9 285.5 513.9 285.5 285.5 513.9 571 456.8 571]
endobj
-495 0 obj
+589 0 obj
[455.9 416.4 450.6 513.2 481.1 363.8 592.2 599.5 619.2 506.9 450.6 588.2 529.4 587.7 452.4 556.3 611.7 640.8 670.5 639.4 477.1 609.5 852.5 529.4 374.4 671.1 1027.8 1027.8 1027.8 1027.8 285.5 285.5 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 285.5 285.5 799.4 513.9 799.4 513.9 543.7 770.7 777.7 733.6 847.5 756.3 656.2 804.8 850.1 449.3 566.3 870.4 699.4 992.9 821.6 782.1 656.2 810.6 777.6 627.8 599.6 699.1 599.4 970.5 849 596.5 699.2 399.7 399.7 399.7 1027.8 1027.8 424.4 544.5 440.4 444.9 532.5 477.8 498.8 490.1 592.2 351.7 420.1 535.1 306.7 905.5 620 497.5 515.9 459.2 463.7 478.8 371.1 591.4 499.2 736.6 582.6]
endobj
-496 0 obj
+590 0 obj
[525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525]
endobj
-497 0 obj
+591 0 obj
[892.9 840.9 854.6 906.6 776.6 743.7 929.9 924.3 446.3 610.8 925.8 710.8 1121.6 924.3 888.9 808 888.9 886.7 657.4 823.1 908.7 892.9 1221.6 892.9 892.9 723.1 328.7 575 328.7 555.6 892.9 328.7 575.2 657.4 525.9 657.4 543 361.6 591.7 657.4 328.7 361.6 624.6 328.7 986.1 657.4 591.7 657.4 624.6 488.1 466.7 460.2]
endobj
-498 0 obj
+592 0 obj
[599.6 571 571 856.4 856.4 513.9 285.5 387.5 856.4 513.9 856.4 799.4 285.5 399.7 399.7 513.9 799.4 285.5 342.6 285.5 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 513.9 285.5 285.5 799.4 799.4 799.4 485.3 799.4 770.7 727.9 742.3 785 699.4 670.8 806.5 770.7 371 528.1 799.2 642.3 942 770.7 799.4 699.4 799.4 756.4 571 742.3 770.7 770.7 1056.1 770.7 770.7 628.1 285.5 513.9 285.5 555.6 770.7 285.5 513.9 571 456.8 571 457.2 314 513.9 571 285.5 314 542.4 285.5 856.4 571 513.9 571 542.4 402 405.4 399.7 571 542.4 742.3 542.4 542.4]
endobj
-499 0 obj
+593 0 obj
[272 326.4 272 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 272 272 761.6 761.6 761.6 462.4 761.6 734 693.4 707.2 747.8 666.2 639 768.2 734 353.2 503 761.2 611.8 897.2 734 761.6 666.2 761.6 720.6 544 707.2 734 734 1006 734 734 598.4 272 500 272 555.6 734 272 489.6 544 435.2 544 435.2 299.2 489.6 544 272 299.2 516.8 272 816 544 489.6 544 516.8 380.8 386.2 380.8 544 516.8 707.2]
endobj
-500 0 obj
-[525.4 499.3 499.3 749 749 458.6 249.7 321.6 772.1 458.6 772.1 719.9 249.7 354.1 354.1 458.6 719.9 249.7 301.9 249.7 458.6 458.6 458.6 458.6 458.6 458.6 458.6 458.6 458.6 458.6 458.6 249.7 249.7 761.6 719.9 761.6 432.5 719.9 693.3 654.3 667.6 706.6 628.2 602.1 726.3 693.3 327.6 471.5 719.4 576 850 693.3 719.9 628.2 719.9 680.4 510.9 667.6 693.3 693.3 954.5 693.3 693.3 563.1 249.7 500 249.7 555.6 693.3 249.7 458.6 510.9 406.4 510.9 406.4 275.8 458.6 510.9 249.7 275.8 484.7 249.7 772.1 510.9 458.6 510.9 484.7 354.1 359.4 354.1 510.9 484.7 667.6 484.7 484.7]
+594 0 obj
+[525.4 499.3 499.3 749 749 458.6 249.7 321.6 772.1 458.6 772.1 719.9 249.7 354.1 354.1 458.6 719.9 249.7 301.9 249.7 458.6 458.6 458.6 458.6 458.6 458.6 458.6 458.6 458.6 458.6 458.6 249.7 249.7 761.6 719.9 761.6 432.5 719.9 693.3 654.3 667.6 706.6 628.2 602.1 726.3 693.3 327.6 471.5 719.4 576 850 693.3 719.9 628.2 719.9 680.4 510.9 667.6 693.3 693.3 954.5 693.3 693.3 563.1 249.7 500 249.7 555.6 693.3 249.7 458.6 510.9 406.4 510.9 406.4 275.8 458.6 510.9 249.7 275.8 484.7 249.7 772.1 510.9 458.6 510.9 484.7 354.1 359.4 354.1 510.9 484.7 667.6]
endobj
-501 0 obj
+595 0 obj
[514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6]
endobj
-502 0 obj
+596 0 obj
<<
/Length1 1169
/Length2 6544
@@ -2846,7 +3495,7 @@ f?xʲDF(w!U:J4OlJUoPQ4ħ
Zs$x(
endstream
endobj
-503 0 obj
+597 0 obj
<<
/Type /FontDescriptor
/FontName /OIUXCD+esint10
@@ -2859,145 +3508,132 @@ endobj
/StemV 40
/XHeight 431
/CharSet (/acute/ring)
-/FontFile 502 0 R
+/FontFile 596 0 R
>>
endobj
-504 0 obj
+598 0 obj
<<
-/Length1 2580
-/Length2 29291
+/Length1 2625
+/Length2 29678
/Length3 0
-/Length 30801
+/Length 31228
/Filter /FlateDecode
>>
stream
-xڴeT5
-GF&djbio'jb p
-bbS 9 '(?9\p2s
->QZ-tK.ȡScrb]8T-F(*1S55>6kaUdLX-ȧBurLj; eP .ZVra! X{T<{ g0,n c)ut̫U
-Jߙ?ߡ\홎~.Yp.ˁ>Z5&]|Btܸs&{C}E`ƒPs>k#6T
-bՇ w]ÖyᝩXo}U߶P(65Տ/{> Ax*;@@L?wZ_㖉9s r K k,TkhLFR:V+@t;o2T *kjL4Vb P60
-/|}:!>TG4X_3jwX,9~nIX*qh.;3H/pbT=~fϝ -"F%*ؐDt.7D[Fxxf+r$tG+vDj?\SX[?\kb'5.nt|`jhl1/$jЈ Ft O~WNr
-zq;1@GTT{y%iwy |%Fg<?<һvO
-SS! N)MIf
-
-!*5l߅(b$ q+D5.p[",b?gÁtbs!$;}Y;۵] "KRIRIH|jO9mdrEͧ{RN
-ʘV*Xv%jyqB\~d>nPUS|t*79F[SF.A3giod!*8A]ڏ`$;&PdH| ~yƩE29/&n8;=%߃%F"ۨH~(!Wnٮ`XW~.eZh!4 ڏv~%38fOQ"Yj K;1K;"S!-kT̊vӓVsa^S' q{*m!p7̶+eDZanV)\`$c0'Vb&ŘfiUpqzZM@fh" UvA-WJ GJ
-?l})> ;%"T
-7 ^At.IC΁xu[6
-6Ar%Zm4:؝W]/X*X$Lٝ+ā#->(C.aȾE#Duͮ_ 6_#o3𔯛C̖۟6@N+,?6ǥ)=p~N2}j;_ZPǰǤ˔O8))ޯaD
-5׮bϘ*ܳ)-ЍՑO{BP~we~?ޡA:w~1")s>^9J4hY'(Y3]+Q70InV<618I:Д솳2ѩ"q$ݥ{=ꠏbC_6PbNҋ,6]`5,}n@[Q&A(Y:#,#`p<Ѭ)+0ږմ3V/D$Kv#rRzRϠ'^paC$vGoi[ )Gƚ$#[pbŷMZb-~DZ0,C&}EG ?*o1,vS9 _UnP.qR̍
-Y8V EmCPzUw[lBeQƷ]`e_p ^ 2ڵs%qA*QgFi!a1Ysb_-1ufHϻ]KEk'T\5vvS'Mꆓ]r
-O!p)*Z.I9flCfzb'~ıREΟ?M3./4S{.0B+ڿ)LVWO~r)])&w*wtgtӣ7%U zoxN
-
-m]bOy^}d;^91*@۽ހl1 "謫mKx ^?PayJՅQsoƖ0(:6˅1`ZCkԴ,څV'lmlዸ3꺾d$| "G.Ķt.4s mtSɡ{blوIҕ{4s᎕H,slڛIJc/Vz%FWwl'qvmP8eTgS:șg]/W\Ȓ0EؒWy(kM05z3t^OTBXy8
-ϭA'- ԹhM C"n3SAdvD?4XK ~cEtL"Y[*Ka R5m)iqHzP5y$sb# %qD 6S3T ?IX.=!ĆHz3WnW0~s R`ƣU/x~pЩ@ٳMZ=CXyGyՀ DUNPFL /X4`,JPjILjT0 Q{Djh"Z e,Gm@}s
-<׸C,=r42J=@$fQZfȀ:X/u BN'-y2 3O#k 䙐/[̯ד/cqR+?MFu-Są(#j:\4hh1 9pzfyu8YT!%mYت7#S+'X<k֜CqO͒YŽK>ޞǏ
-,E__Y&hH௃ѪlV^wSJ1f G]مFd+8 }i3,f?ܻy p;lH^:ĕ
-);8V ax6 F2^5NTtn5D <:CDISm21u +QQLUDy`X+b^S4o3rܭd !]ycMVv^\V bwh8>j8Sʂp =D^xzy3_+-zVGsbZngp O:?,Ee4O.Tq^3_
-j%K ʹJQtC.sRRnN`)"0W~@Pf5Jis@sM2 .-/~H~0Ti&&fU?D?s$n/@eDcI ȸr?oBwh\ro{D+@H\_;|-8kDqh:M\*lDݟ½+Edn],d(3
-Z47j2pc}}qŻl#5Jrv-=ذyQM^Zm ó=5+C ys𥞬h@8Ϛyټ}$lD{Е4 ߜ_hFqۊIJ|^HTQMZVCҎw1,xqnIK=k&}ZJeX(] `AE+Q?H~y\G.۴VGcYz'ѩ񭫴NAG~(A 7CBK'R-^w k=*}]WS =&b#"  |a{UE+hâ<ո=̌7^[ .B ?4܌e;ׯ*cF{3Δ豶9VZs%9mfV$kdh''QJƳ8(8w{ZoljQ >\IԼZp}hewDGYЖ13< s.pk$KQujgLȕ.a k w78v )cVLwP7-.4nxcĊ"?
-5uCrM2sU-eA/uGmewrQ W&мo:z6hS^jFgF.ނ&?kndlM'1p ^?}g3иa{)6hZǾԸ$'>9/NHW'f29+v"-_"Ji,Ix{q&F l^%E HA,+/C4:6iZ苾f٣m=ktK\NPΡ8HSޞueVMEG*){ҫ4ZTЈ
-eCT<)qW,pjGG
-<Ȅ" E8Ȇc" kKhR(*seWO3tj)s{vi0 ">ๆ!z x>^Xg/&lyAOabL$EK$O>tݞ#/UY,X}
-RcSuY#:4h;. &9Tn_u*^<!KXI-yla?(|ppvf%@-*0NQٌVW]'G g; ol2=`A8t_26[3LTAb
-6{3/Z6cNJ}d4tH6{|7xj4i(2J᤭ɠv>n0FZvx!T+bH*`[ݕ@y{太h:e;\ϨYb`ִe-ӳDOm)‹Kn"3etfw2 Qn%jPG2
-Q̝HO[HbZ O`nIG኏sh%I.LuWKD9FlF +zu}|MÇV .#(
-I)=YrfI.?z,Ng_%lT hq ӆƑs^+F2es"*,J$f)9<_pĉ^RDd7Yޗ F@opjU:DYXUHq|/EIXHaL~&h4W7;
-yw- Ky e:>7o?
-GPT;}) zqBtU/q}2K}g=
- b?uqQVʠ҇yD\cR|\O#^˦ߠ<~BySiǶyV<(I-cdȟy=J?7,Mbwi{NpxMh>N5iӱĠ̚
-:. Rγf
-͗o+b/ p-yQl֑=}΄E8m*1:-iiDUg:7g2B
-ƨ*rcⳬ \WϪL˂D{. ;v/m+F)'
-h$N wtp)`E1Q&ꠣA/煚-ܼ]ybeeѾ^<% z=[k]Jip8%#+a5Yy,Y˅פ_a֩;"A8Y<R8`YC1Cn=^UM划ڪ`χ5N%ܖF(z(Gdu틓/qFl˧~&C ^zd ۗpGeրQBqnE~03ݘ-(Y>W䕰ρe9—8U#odPޭyLŹ+=-E*:T3!<ߔ
-ƌe`Ʋ?&=Ϊy;I4yd$QS
-1=Yme7{aUĸ1%)l.']YWxRƗ ʍE<Јb\{אv1ik:x i<<ID$,0rT@)k̝ #aFU/S:"tCRI8LdOb6I8s_>8/`_bMMe6mHovO H<1՘}3I H@6,s E?ضXEp~ݧ%YGF% ƺ?_>2a\HHPKS, nB.='χkE!s;m0Y:a .JSEtS?]",T3_3Ml3}+ 0ɴZ=]û-NάVpLQak! O,Li UK3
-`5~1C2[i;Dzxз ώGH)-%M_˪
-”N#5pAge- &vQ;F,-KJT'ADN$ _®وxf>skqG_L[q˃ko7}2+"|{NE6rZ/5JaJ'|K*dS~.Jyps6wqg/+$ȍDqY3SMQ' Y6y~
-rb/bѕ sKZv~ WPȷȋTUyQ(ۦ}i}Gk+㌏|b BSܒ`Ч&?U{5=~}Ӟ޲ buFYDH$0am2גqاcztCDZԤW'C6e2+k1['_ZvN!#-0 eu'ǒ/ҪZ.T,VDIW^6jqQ,8#@Iu8b`fNS`sqptsvqmj{E3=Fb݊Գ3ݪ~-rw>]O:-ͪq)t_KqFrS#$,%ıNc~%>;WX^(x & sJ10OCζYz:j P9jHŢ~A$cRGv92yq7fY|#΃֏cq޻ZGbG,I
-M;E7J]9k:2%X #PmjhB_.e&IivȒGǦّY xۛ0޾ޓZk-
-dLr_]CW֢'{YENw%t7upboqK2>j(Ds-O̒aA%X/3ť-^k_ ] dNHV|ݙʬwk̪Ɠ'x3ƯEhש&x?iww#V${tJ?oRrl0{{yhDl ^|աe1"
-Zmj߆Q:LhM*yѫ‘ z[ڰ AoARZt&|Q.DZZ |
-_83̃y #?)HheYotD&|2wfj/gJpʬr1JqpBE?aE]{'-kj'Tx3c/zn[
-Ēs%i$&r"۸1Xr!츚_"JZDv1^VxIbsd֫F,):SNC|0/4 );-2v 鷐+:!2_:@=Dj;}
-TfQq$\ۊnӎ W9Ʀ'Э-#\!L.&!]uE + &bss{/jt;Tg4ɯ22LswsO 0=mT!#oėY)h2)"xTXݢ[yE- ?QyLK^S|qpaV3 +Y GfPW6OQꄓŎ>"]B~Vj݄*NtyITg~+gNSSڽ*ӥa}?C}!^h<Շ~JV)I[4O,ՔvX{Km/=_-Wγ35bCiafߢE♿v.0DecZ PAy_Ru-DQLEZXhx94$c VR3:5+^b ҄DGl_zvw76LA
-54?5y2 =?38h":kM"hQ3M^av&cY+MGӄQH!ᙙVB]61q7!^xiۓLN=/UNPDⲫ݉\ y9ЫG#9.ޱ/ϩiD\8+'{c!k0U 2W{&B] a;dxcDjb>;b5mEMTE4;*H3suI%
-OE.`f1pDMئK+ _DIB5p
-ǚ(sˇgrП-<nJ/sJlad)W]ҵŅz zs/WM=#X<LLEb7/r׼g=wA\<Q5fT2\rf]y;Wsl1*g<GUIP$nuw{ЄԾA9C[]T<joڗs{'+h]Z9~sppK]GT /I"{m_7 I޹ͷc94{VbT|\gl`#$FsR慨; @˅bb"t/g5o"nD}~
-1[`TZ7 ~AZҢMKqAcGAA>iM@mk5DA_l/OĕnNZW7Na͵ τnHrl룵=$
-\sM+f=:HDU!-՝`*,mjٿb!BjJX\A{Lou\58C`g;14<:4E Ē0&YaI,K2۬~|UoójSkNqL1َMiZl*͸8c~UwaѰ9iOZ
-k'X8iPJ"a,}z2բ(R0?8PbҒޙU`L
-6>;(,&4HYW#FǘQdӉWS%z YM5d-YC*i<bN_׽S crKpt@8({C d1tEՕ~V4JiuJSlZCMG<0xHQ>UĬ`O6rOG5"+%3K> rMc^D2q$BRS+m]>֢ _hJznl%Ƅopa#`+^6u|Ww=^u+.}B@ݶh]$Z<ܷ?0^R^<ƪ
-gT,PCѾb z^5H^£P:ţ%Nb3|+wSZ#-GdV[<X*w;Rs UG}-w}͐a{[F<={\O7m46G>,"6
-ZAdQm%=ϊ_'<uA
-ŒO_
-0Z#v1 ;(6r9VZk`iq]ClSZK`~%)58yi@uw }ce2ޝ,TCUP -8 J 좈e>̱S$^AO*w33w'+gc *'eϧ9TJ1#?I&<8F¿%jnE.ن$ !|a52rLk+[I)pEx>ߌQ4O'Gn` GۢkG_iq|N`skfuˉ]g=)bx5'OSGU0hγUl8Ex)b ]3&ي=ʌN~h!Ÿxu|K()ȋo.692%IuۢO7zg|yK6+q OP?u
-&́c{i-4Jڦx1c.ϱP-ʄ䐉 &w:F\q1Wr{T_\-Ut1Lnq/AâH/iB]1ZVLjUL\n9Kijeri~:Fkڂ*$Nt#W\fYR4-
-2e֬~H[ M9V_byC TQ4}iSbx|{@J)pw!cbi\Щ\XT 9}%
-xs6&扠bP WEe" '@픳,ˁ
-/X5ܲcY\bK'NsVC7jƐJC=o:InƝ\Uim~Hr
-4a0ge7&y&rœ$Q)OlLQyY?11aDGV1"+(njD*?!K3.SqkNs&O}e/aOeRJwx4WQY`]WymneO(D.Qi<`
-*uD&OЃ:0ɠ6aߦycj$Dj~Aؕؾ}V9&=`[IG&,ONVJ> U0d4STNn"ʕu{Z8Ǻc%綇e͊6?c*c):{_A!]1R`c;<8wEw JB&M4X:m7P.(J7]DFq6YWkٚ#H.zH.>l”Qrs!fVC2'r89W E[f*&\:>6rI
-#5+Ds C}!Dv3箩#J*B6.EQ
-wT`b *%ٗu\ᄳ&[mJ}0yGҮWT
-k-_96ӓ* r-R!I54D}h`. ١I)t1%@d?+[|*iSs``cEdJ^)7W=rX`3=Ƅn;
-
-
-+u+hTsou>ٮ6 (H",ieW{L7:BM;2KOrsߤT~/jb%Ҟ╕d$i< D]^;E# sr6:m/m
-oR%c|FIZ`D AzȖ=F`A=
-ߙ-zh`=;*|`>?btW_)g*$l=S+Bp6f.Ӕޭ!bҟu'S7Pk1!g;ѿ {-wN 4!F=KoqHd( <p"2|v +rHCPNhX܇IH J_<K8'OoK!t$n{.zA//v,eui 7jv0r־}_
-i^jcy޾=`T A $k~MvtOBQmh !)SOE̞ܯ.>
-CZFt?z˸>jR|I4Xձ}߄*ًqnN AI;?2<[1%
-Ţ- 뉿)B/OgdtUo>}eO[b+l=\A>Ό> FA5n{Ud^ić ~,1
-{X7A4j TFjA!xB$9u&eKƂ_ksι<6!nGF]6T6f0lct~yꙈī(RŁ谩Yj`/7`"Q9;&ADJb)a"98߬k1f[Q&-U:qri 0&CBa}S4oc@5i ̓kB. 9.+Bۈ->a%(2:V_2yÞ'θ;
- ^{|g?PL,ZfENz- agPws1 sghVH%p-|eUa>?+2t4f'ps:Kq/ϧh@]j>k_w9'2J"C~YOǞ2%C:
-ԕ)9%#Dt͗:$Qp VC㰒BwQhLJ'
-o\ڙPF>!"<Mg0˼$:k(
-,u\:E{e(1f.n&dZ\pRasK};*~?-^u9 ͬ硘5-d+/lo(_s#N{mo$b 7r
-`l$6P3mxe+QB#sr4N^8"(<D uglP` :?1TATU{9پkwRJFcY/s1ECvfE7 -2~7}ؤ{l$I XO>6u6bK!GH;:RL2| v)Ѹ1
-T[A(
-FxJ~}VzW58zq+5P6I +6i6+?v~MK&r(Z}]\TwS(I15H䪺e]AtlIBGy} 7+@Xw 5( }y[&=Ys+:C
-l)yX!SXj?tudZcbsF i(GT6f!z!7˜L1-eb
-O+f}#17龙I5VD7۟}O#>L:ULOŹ /俈K/U ĘχvM^u]ISZhP,[`EПTH?*?|1)Hp e@gy>zIpHLU0rJ0ՀmP?m@ ܙ&j`(Q] $/I?yuRNR)͔|<L aY` BFƄEF2dνF)
-O|g%^2# ˝0.!Za®oFy(f(n@I,Ai1܁TC\WŜ6p`7%2:5EhYOkf;x XTU>ǡe6iߥ̴Ng"٭p[`n W3ߒ5(-Gd BJ឴(P_~mGanU-Tw"Rnx+v]=Tlx)a  h7UߐQ*e,*_Tp{ R]RoGdUJDPgfb!㜼gmwW%w呇ri崣[Iٯ25=%v5 |s.,[0w2>D~jDTE? OisTʰv)(dU$U"XPJm`a |&RN0drt(\1LJ)qS2 ˋh)ϕ\891
-VME'졶) [pp6|!5qY`4$tnL_tK[%>ĈcvP_dnDrkr|ͦ/B@Pل~FJ=؇X@^A:'SD2w8b2y2| .[ʉ,npsIAߪ<r@ҿ)29t9`=mJJ#Blʈ<U Z6j|PQI?߷l.J#Qtʸ$8`^z_e>OT[<@b.bל&|I ݴxW+_+2w|c"4QaG^ ظ* (%cƁz% fݰ 9TyXq3v
-& "X*Y4?vx+8qv*_QWA>鄑q^kxA&>gSZKs[(`&O2Cg+2i5Œđn#("s ԮST|EoE?p)#byu(ƤѶl69`
-AXVK=uEaLNj<;|ӱy[5G\o{
-rQϻ#<Ҿ@pVzS!m9,Fb1]j4xxmFikYYyty#y me7\&߇E 2|ā4=}tZG^FcwkE|I`AdbYwm"zgAˇDw4_rĵL5&_W3Y$mb-Ӎ˚oro3HHT..@
-VŠ=:W%+Gl\2Aw\FV\KiAz.*{@~ H\@]DEHȞ[QEӈMN`.**"Co!`!FcN3g!Tܭx6,#.ulwgZJY, T~VUogr 9 poY5Y|FvYADtShɉ_411.b^vAD1'!OL"BihN@S(B0Cw9]j+C!F#aJ=-4 RO'tj;e
-{(ZgL>/^a4J<~V1lSwtB Mt-"[s3ef(AmYW V߀Q9SnƸ¦L
-kSz4Ёi,
-\@QSϧ;Mev
-;&'xa{O̸79F_ZvF)]1)+qX1!#VSnK# TƟt"R<M-:]ԩ@;9l!\dyE2pL0-V"bIߵ_*Y~=2n5yk_[ޢ5a98z:tnifyq;9y|.Ql!Ȯ57_ϳ2`} A1Zv-3Ը߇[UdnH6A2u¡t~xEOS7$٤CEŀ0
-urRh/;;.bTa#JsMӶw<GIX׍](EZ$J&,atjBW~iF?'iA|F6d=!~Z+-GPꙃ-
-߇%4PGݧ/Mg7jesEZ#L0
-%O0
-mF|j:4O"Y5J[=IK J 4pm~J>2Ӻ9:L;'$$8T/aqne
-xv/K^ɓf 2 $1
-ôl6(U ^r0 y:Wе;%n*N
-) 7#mimqd13Q2<nQ0,ݾ1]ghxJ9Er6 `k/c؇OD/Mx.
-,d4|W;ٷ{Sth&y/Vp YXgc;k5$6"PfF'Z.@c<53׏툴`㊇|
-1g-u2CJ1mSYE51}9~ڙږ0vwMp
-]WtVy1ZnN{XgZ@FMCu߼
-?g? mc
-uXd;\qˎi]T`/V9^3wLݐUjo.-6©۵P,tj.SLE[aP%o2LR`Ykbp
-n $Kq01gnk3wOk]@-/
-E{|
- q\M Lu2_ͱc'T[S}?Z[ .湒<bpQ?$hUF2>@
-~e'DHtv1uHzkmV ToϮ[z_?D"QڵLW.jtkz 9r2} K삙淜kFJqdW@qe{0Ct,!wwqoq5tnԻlv0呦,R6w]IHQT]A)j@,a [=͗}
-WD7櫝tԶ.<Q#i|ѾxGa#ԬLpLytuo?AS(*64x= J$xRAqZ)ӆ/7{8fdrA|$h`0B
-{"F"\TC˗k⎎ﭕw
-(M -dv.Ǹs &:$sYߺGոitLNË'nfš͈.#)0㢔(Ԟ
-0+m@ԅFW[ϘҾ*)3s!BS<5Hã!)b!6^=16pLO^DD3A݊YW2\꙳m[6XK&pU.ޝ
+xڴeT\5
+tB&Fv.tL
+ pdѻx; 7
+`-3oD-:;y2T[ٻy& vD 4
+_?ٙ6O!P{;O p(9cSKF֔߂E7U`KgqKSKcU8Bv6eR}l t,Y
++AS/3/bf1j'Kg?.@F8u6@jElc{`+O)&F @D2
+쬅?<6@ '@r=L N?ցClef,9o{S?2/݀GPhTϨFst= jPƀĝMm-|>n I (&&`?eـsp2G"#
+<t\l
+^.PGh~ey0oRP}=(Z4i*Ջ&P5}m)T=k03W}"dMtF'v<#8Z)@kPh%2WSd~ x*J_]9ۛۈ(`FU\rk5Щ6.
+śn1J
+BtbCRӹxߜm)♭;,tˑYpMamxrQ3ԜºFZZ۪֣;KSżPѲ:B#nB|754< \9)q
+:
+WRULe5tw.Hڝ?+W*Oz+OEt3;D75v$n)(܆@~,&ĭ̻xXl-w#>h{Ӊ5(u&.falv%/K-'II$͂fz =崑џUi7# HQ8*K(cZ`ٕ q=5j-~JAoVYLo;_ӅIlO~Ϝfi*uj?AܚC~"A
+B$@SN>hD"đ:w:wN*R>~ UٸB(n8J/^g|tFt̲*-oEsddq茰H8)Dѧ T8pk[UӶό#Xy^A, {؍mK5Ij?x kSm-kgl9 ~6hix
+Yk 4ю6lİMN4|UZ&@ąJ!37+f[)J^&(Q,y CWwm5
+!+b$^F+jt ~|U>&dV{iӃ$hΕisNGQ (d)Ή?~!<ԙ!=vq. #Sq4Mk4NvI&f+>}jih$7k)饊AJ#{к:34 dncbLF7Xdhvl3Z] ?˱:&Φnwo?SܩѝqNޔT79yV*d*(>u=zq B=^DyB@ƨ
+q:L\v9z
+2\<gYr/LKgBlzd O2F_O8DmJM$J#P6յLysQРV' K^a~gRgg}cϏOĮci[sr>EXu?
+6K?g.x{?e! t ]SȽ4bx?Ŀj@ko`ބq(jիd 8]P(fc}w,gq#nFry [u{]kN9():s?ǘ5ueoH0M=̄QXc#pv:t7A#y?W*X?$8{z8IS% %MA8tWx%D8|`DE1UNB uQ8cyeLѰVq573xweg7ex;XAyqEZ][6
+6fO顡jf'Q-<iBMY]B2&De\ZR_ Α`c`H:XML&91~H^Rn9ƒ6q~~+AиVta;KWHkϹt w.$Zmq0|tm߯6u"T-و?{W8J(
+5W'rn$pBT>Spw F%n
+kgߙD3嚒eԇ[ʂ^䞣@l ,My߮um T%JԌΌd%]2M~%zѷtOcsfqcZS2L!;LmG4ӏ}qIO}s^9nK3^8>'N4e
+sWyCEZ&D\YJNLؼK6XV!2(k =_h>ulҴ}ͲGS,z֊i3F;-bй_Cs7zqXF=-›
+"zӁi%Z$g{R
+EfX1*e>|w:J5ՠfe
+.ZpaEF¢gjGU]-V/ d;(vⰃS<'ZMB˞Bum,Ԑ-.~bLҕ}Vb?K"!I{I~/;ґzŌ"Aܘ-??J] 䫕#ꮖr-6UٌVLb*j0]FPRz_̒+\bYξdK٨2ikaF #4 Wߍe )&ETX"IRhsx.sGZP nfˁ x/a5
+遚FXYu f5R_?ETØL|˿=i4óXopm >w
+k晴["M.)u|!o~}vR@b8
+_6/jd({
+b6X.[DH}M~M[շ
++6
+.-H㪻O%w[Ԣb܀SÈw#tee0!!WIH_8 D*i?2- }d6wD>}wVq.~>ZJofjL(fN95௱M5}ib+hqĂ tfY(ً5pq 4Zc~4E,2-a]ZWms#J(fYۗ2Pf6d,y3cSt_:/zL,_p1Þ"<J}=_sAJ X
+t{Ognl,wc5F}W$5{4<Mp](5>G<FAe
+-xcwv.I[ h-;$5$ܮCt@3&i?$4&"ڗU,_%BX [h y-Rn!+E{.5NHNdAP ҅OI"詜ʴR ?b)ޚ -1ưPyՐ|x*+1*;х|m-Pө$_ GpqTo<~춥#Kn(8NB91!<b z|C5o8^&#1ª؉qYcJ{S8]\O4l/!xrcK!;;bP׆uVxVy$
+44)JP 5MHiV(K )JŎaD%[O5M~|;kz`U=eXA$.*됅Ha=d֯%1Ok0HcQ cINlhev V`ceǿ7N/ C42cgG\[!`6N%C_NU]Yv!-<mԶ>/X1$KYqF<%vopDp玕ٯr횑"qf0{0ĺ=#ggUYZ'r+}Ru[U 2~Q3\V#?'f S龖2<GH1Y9Jc& J|vd!e>QMƕb`ޟRQmu$@:sԐҏE8I\5;Ha qåxrLwedn̲Fc9
+wWʏYA\wƤ6(m׫:P}E.=Yۯiya asv7"GoNIWG[|xxkKO[OX"DSGOwl-wjQq=}g[U'%+'/YX2m;
+2K
+n"=tGyQd|fP Z%ރJ'^fK[vT+h @Ȝ|3IY֬U+wI'[#O6.g_4ЮSM3Ӯ4GH L~>{=tNju@a Y38Q n2s,;S/b1CbS)EvMԾ ţu,њT (W#'6a/߂2jL\c ѵ(&pg"TGbS.ʲެtGL*d>_Z: #Yb9br%2ᄊn
+L!=S>xw*X7 R'l~yص
+]7<JܥLr
+r_sWGr]Nc_\S
+rqVN$BnDGa8e vL4v1Ƹ &k}v,ł%j3"iwTg-6aEu뀓8K
+G& Qs8*fr4PO^D1^۾CWosorh(]͛׭8Ţ/f3B4FH`Q}W-$w`5@!Z ĢD
+#ȐWg 8|mUW 9eR& 3$M/GässS:qzci Ix{EZ'L:;0,J[CE3q
+(bƺ!iUOs.-6Er\+oyOiLiCT )
+eA K6 *7`˜jWO*}!_3ZM_PAuwN zW0}2ţ-Zޤư]<_)q'0 O"mHܼfBч[a_x{;F6Ԛ1!ސ8Vbkju f`p8 ٻ:U
+[6<Z35XwN+#oUYO5UԁFFwfp@'QmjL5izQ ;^'3*u|h<i2f0\
+bP.-j(6ݱ_z1OV
+h 3g~t2o4pL4I@ڛ¤"ua"bR`O֡=)qHS8b87oڵEPÃǎ<|j;}4jZI_+ݜn͝Úk7{C ݨ\ckGk{(I߹V~*cg;{:u|-@,≪BZL;TXMfC ax#Qȹ
+ҵ""tGNq dEÜYhe0RëEչQ|l=|`qĔ%剽3m|vPXLh>F*1ɦ&wK+\'75j[8TxTW?{% ZkpP,/bp(G+tmi6٦0&x`< g'|=ЉYğl2 ؏j4EDW4lK]g4=}2S8b?v{eHʏV|6E)xD'*L O J0L7 *WGV&7?om@>{2޽%h?"W\L\cm~Hxo%ayU)*Ϩ8X(Տ㡆}j-&G3uGKtd;;@gb
+~1lxcs֚4;6BObJR^kp>+Y|vǎ #e;Y݇8ZGs}qiE}@cǧHj#tUgVgNWǜգ|+qUOˮOIstbFL$yz͛qK&f)i$] IPV5Cii(je候nVS\|hNď
+gУE 0>ӪP;
+(ע?zS=zkO
+`̝g6pH?StR*(gL%;ze-Bq^PR  0\lr0UoeJE`o #dkErGl.3)3W&VA~8
+e/d\Ĥ~>te5<Gq@pb@q8S)Fn\ԗ|؈AFe~ES5EsVmLA)@(DnO)g{*Yh990,9@ 98L
+B3^nd }f' u#57^^=oj|0U\L";SwacSxKW|EHb9ƾ|
+\
+vG85F’dv}Z"BO$G~EX%omf$<r3QD8k1q2
+intĠ5^1E-o
+"Ե%bB$6<bu^\r?^v+~v!KӖi=Nhd05rIt`9lY|Dz)P6 I|#6Kk °7]҇~ߚ͏ۛfdڴdP3[cc_O.dTiYw
+Tipcu y6x{d@\Coީ3;WE&$hޒt`Q_!0T<pG:
+8g1"ܧR n\gY]&ח
+\+3)܈3+?NpA&hrov\H+QO$C@^yBM$RE(M\p
+.Otf(ɸ
+yNym4$ĪOBT8L M9ܝ+i"=-c`v86q oBtM[Jۭ7F9!2c1+gAɮJ1b:gyhI^H_?
+O4P81`
+xYeb\ _7jSVsr2@of2dUXP,(&S_-^Ptx?8k~,d1چﺧR3u'rL*+JQngSFɯ<%E&K
+f];>RL/B ;W]kmYߍ'WvSCoUŸ2vηmGwY&(Ks6pev
+D f8G&QRѐ˧Î'򧌻%X
+s;xJ`Tս?\8l|BVtcF}G:5 F/mSS&+ٜyx|쩅ъ_<+4=@u&ПE?zj~<VM< #5.OERG%+M?@o8BRe|
+$6C
+F
+3?v j<%kW7tImVVFП 3 *֡cgƺPT|=mj$ &U<|, הe8ĂAAh<H)@rx*uu1\H1,ES{8>o_
+:UC
+eӵ/WCVK(sZ$h~"׮vVC$G]Pm?;sj̧g
+W!UKG#ߑy:Ł̍+hr>e1EMR9oGuhe\
+?iN9 . y4-^HJ{ |aL`h3f=1R6b)SvtUdkf%rT..s ER*c;w%L[ݫo(^ sIK
+QJF:9 *E5-?>N]s3N]a\/Ʌiu^%Һ0R8yv^/Oz.C*Jc?npfLܱPm;^q"yUv;dz =4L%2,-=ok
+TimTDrqrwG9㡋N>
+X1cD8M^'"և;s[l:jX5Puo? ֎"+k}7JO1#ۙK H](2CJeY[}K$(D*^;,u`ƵE>P"F .wN
+ẘx8qXm,kځDUw4T
+5|[/C:3qtN1n"8VTϞ",h}&],kd4\It_~$G`[g?LeV\ҳ!q>};0IXԎ!K҆&Y$ !Y Q40Ax>~p%U/.4M1\Ho6IS qx5N9BC$~dfQS '⩿ɶڣ!eib>d.b`WUSa·G~1qy2J]&@SL9a2#Wkb¹(+\:h*#nYvZ
+A %Shv~Kibc3rtYbp E oMYꄸÕPII_EF])?* W .c]z@ a\C̊9u{(#6SZL9PC@?X?\c^TΘ<b6i"Q( B{ӸL G6ӠPhz'?';l,/І|{1y+=l!/y, ߌ<r&Xu?\X>&,lYe6UӺ%>+ rGҪ'̖*|QSN.h1ֻg=lo=k24NZk얭:쮘 KIG [Tht34TZ(O8
+%R[S Ј/'Ad4h0tQo!`R+aCAW
+Zp6۳Tunuw'
+ ZP#ATA
+-x
+.}ͩlZY$.߉8"$乂ev+~uSnǓ8k^*BC<Cbx$dVI1ՌnPB ROX>VjkaiA3~ss#[P% 8bSPgM9x`HRg~D+Ttj8LԪum=X\k͵ʄɂ?o$W$fH_[=Yo^|-!Zo`eML(JnJ)@"FKKﺲPו"-ºQ5‡9̻$u<g=J!^^8ڙ%'Q'W4Z]f;KԟVyܰ807?c HT$v+ f4%PkY-2_jRǍw)5b_DžY\C Ʉ*pe6e_0&ؾ6?ʳhحn?}}pD)oj #r?oJϪS{C(d p.7L~d)jpm2`Ç~ay\14;$.TXߠEAARS\Ա\tő~mN+Z,L
+@'nSIhLi/{Iifsbrn.kk]ù櫏6z1Zs7Ey1*?ksao4F
+qO*պ>ptRvmYnyߞ4;oeA!>OX﷥f ݐO\pn#oF}S:e@LiFG_0udžp}_%"CASz?y/6_3Pc]ĩ7$ 7`:
+|B66)p9(EmH=
+Kb#eAT<eNilj8Rް1kl
+׆P2Wg8n,5$`ioS|$)Fa~/j8:Ω,s7w-t"v%ie ?:|K"qK^ E02|xkan믱5?ypJ!≃%r׋%ՉpbaG:<q+f_mO͡ȱ_^9P8`;0 [p^CT}EULRd\1 BQF=@/j[f!֭eqO#$ ps6/u w䛫pU#<1PM.nh-"uҮ0VwU|OU\ |TO)m t^V3k0M!W6HiK:'f7wTEA&3|ǣ=N\.qCj_YU ]f1%2|
+޼ð9\DJ+QRZP<`iN(tZ{7:~`"H{;5A7ҜXA'ѣm&n`P!|%.-3ɈץhfTzTTSВ;riOތ*?S3
+y{VU>#U߄2\+O+$KXV2{}E9@?=D0 -ǟMg_0'뒌 <iqNTѲH.9?L϶^~ a[M V8 Ѭp.=Rtuyýs}fX`G)ًVlMbC˘Ne&M>:BY,MZ 3i8؎-e`UdWYaL>[[d Mbs ̮QmRHHy+99^#U2t
+3~X4
+ju,VF#İ6eUp7*rv-:j03"UUn{Dm}:~w.B)(9C6dч| >jl9jIF;י8w
+;Opl"3aYW7A[zy*]ki N2Lbex#u/i~Y*= jbWChi%ZN.Z)E@yޮGIepqq2cf*r+vC{+JtG0}DnUn{GOMjR QO㻦WA群ps\#)>X}-V@85иF/FӮ 1yYtgT̲W.?
+ yB; <Q,QEoc\収28X(Y{r}!8g[/z`B4|=:5w+04!zq35o%@`=]ԯ!HM=G1Ď̖oًM_~d
+W|Q)ޙ=l);h? .#H_˴[2 5?{O- 5(_Ȇcx!ǵeG5x@F{ƊOOGb\,},uVb?1?q~(C
+DjW(,O &D]šy(`_bCɾx||k@O.4&:{AGl[ ܌|I<8tZډlDcid_iZ|Ϸo^?N!XP6W7~@{xl5B SJ5F@v4Lɡث ZN>?_`@Mffl{`ʹnK1ղ0ƭx u鳻xF6=.kX=Ϗ١Kgо :jW@2
+eѡ*4)(H){'Ėq<Z?Eժ!Hh#OCes#P;CQ^,{p+!܂U`H_|U92CLx"%> UNl`NjQfYA?Vk7GaMݔuq}!=aaf.KFcC 0,ึ^\8}"bc|)=D"USU|*zz5qZmpa6eUb),;&E %5+g~a
+BE$4H--8g@I{KO#Dz
+\VX0aJNF.D0/UfXb?b&au ?}x ~U*}}y~'v?O/LbZ.\1-o?h\<IǺE,`ZռxPZK_J_a .sz9ub?wWe6 ^vߥEfhh(&1X>ࡊMbk Z ATSɂ']x6Bz(b%-}!mwvCjR"N
+V!W[J"޿ڕ\:p%4pZԣB5 %Za{5aHݖ.-0:ʆBFwb/^
+p+n>]oŖC+00jZ dj.%T<LVVUClw,t.T
+T/S\n;C]a$ʱ09dOַBtF/,O_EYw t_׼-8RQޟG4_ ^縬?տZD!h&g~9LzU1cLij&;+5JR{7peJ\M
+h½T9+E3mTt&dTx돣t?Q\W tkZ`.Lp`qQ*OmF9&su]S Y8~
endstream
endobj
-505 0 obj
+599 0 obj
<<
/Type /FontDescriptor
-/FontName /KTPDFA+LMRoman10-Bold
+/FontName /JFISNR+LMRoman10-Bold
/Flags 4
/FontBBox [-486 -295 1607 1133]
/Ascent 686
@@ -3006,144 +3642,137 @@ endobj
/ItalicAngle 0
/StemV 114
/XHeight 444
-/CharSet (/A/C/D/E/G/I/M/N/O/P/R/S/T/a/asterisk/b/backslash/c/colon/comma/d/e/eight/f/ff/fi/five/four/g/h/hyphen/i/j/k/l/m/n/nine/o/one/p/parenleft/parenright/period/q/question/quoteright/r/s/semicolon/seven/six/slash/t/three/two/u/v/w/x/y)
-/FontFile 504 0 R
+/CharSet (/A/C/D/E/G/I/L/M/N/O/P/R/S/T/V/a/asterisk/b/backslash/c/colon/comma/d/e/eight/f/ff/fi/five/four/g/h/hyphen/i/j/k/l/m/n/nine/o/one/p/parenleft/parenright/period/q/question/quoteright/r/s/semicolon/seven/six/slash/t/three/two/u/v/w/x/y/zero)
+/FontFile 598 0 R
>>
endobj
-506 0 obj
+600 0 obj
<<
-/Length1 2391
-/Length2 26731
+/Length1 2423
+/Length2 27157
/Length3 0
-/Length 28161
+/Length 28524
/Filter /FlateDecode
>>
stream
-xڴeTM5Lpw q%KCNpw 4Xp\_r3̬z:UW592HƉ U62 Z
-NFjD"bk
-?%mLm\2MJCMlm& SDF9[agO.qg++9Ck7 Vm?&T?`7_]\ul̬@+H>zC9G:Ɩ6 GG
-᷹_^M|]sw;s_2_*+?Z_rlD~egGZlW?~m@+rtSkG5WilAny' +y's_|/ap /z+kxo=ϜT?{`e'[K:"򗉬M<___ y ۺyҳr9
-֮ ]/X g}g^~>8&==%D8
-dp* Οxe,8*9bvӥx\Q_@[$3ad!J. 곋Շ:5EjTbvM*/:gdkhAGx
-φΜ"-vb2# 4->ZXJ*Wz=F=G~$J}ıI/pW.ajPցSn[JC«[fd%TޛqR^7cx8}Zܼ y`IpYA 6`}NPT P5er^ m$2.BU'}0-
-{oW鬬!2A&O`皞ij EPY&$Ė0 {I,?.3&J86Ʃ7";ܴRe")*z*۟t;{liڗ<ō:bӰ~t2 $)yz{r/~i0m:.<|u!=MҀItCb),e2E:2"spTAldWxQ7mSȊwm@΅Kn[y~aN댂~\=[=ȔoqQJh-j"<!umr镕?ijeu=SWp(w 4РVg/Ln}r%n+ae^
-%;e|!//!kb^33`A'fƯJV*qhmrSi=_? ,rw|j_kb{}QBMB85EiUNO'=֚T|(a{\_qOb׭-QF61 #~PvXQ]w1ϳ<ZWUry=\M=_ibΞ=V0P@0o:jusIpu+0Mɽ+=H~GUoIE> *a1Жxnґr"=ٵ@k]|k1@ڼ-1y3~UEoX/K=)#x3aV%=Mn,iQ<Ȼdh/Y S/`B x$9oV<;Q|!L9ȫ3_bZ HDv}z#;]-2lXޫ.^\7>K}nD:=~#xFD`(z.Cgw/ȃ
-0O{ˋ.ibIBhj.RUyԽWAW7"{;FUjT=
-Kp$h)|IS'-F8q-WM02up1=:)+ն/h9@\#RWĈ~͉ YD}'l@歅+7"Ҩ9/i2yƵyp*0Yz7=L -%3-%i./u%n~a\P:+-@{ŝ:fy8):i?Ʉq/lON뺩]l1nN~jH#`\
-YC18,k;YIB5木t2Z*6ٔ0Ww,!i_FsXKj}RK9b0[,i<Wb)v<g=B2HaX3wh[xʗ=TVRLE֮v* 3S* +aʡ+pwXs@|R࿆ @ByxB_GLs%Ha+MѷuGGkazEGX,#K@^cۧ(ƅ2(N72r@'{ DD<ӻ"[$AK8TGʹ?츲<|פP87M0.
->"t gO>Uy6
-aaw^ ޓg E1 wj[K5n1
-9D-VRȣ `قmէh6}bڂeIkz/K_zLZh]8Ѧcۗoߵ}nTRV }$\
-Ɯ?oKu\tE!'HB$a8+):~>UNv 9u9 :Cgy gi}{9xE<C|Gw86QWUZt}>a?ފ ;[XU,c@;uR›.
-%XAO {jۦY]pnľw`Єf ;CwW/m^=FqV2'%r8ɞ=Soa
-ߎI6
-h.#6x@U58>uÕ TSeo!
-.ܡzBp LGmtsmT~i;ᙽ]CrBqm9òNFy
-85~($P5#3spꞚdG/sc3~L}2Qe~G % :/G+ |ZVb7ABJ Exods!/(;X?t6]ah<~`T) q3ke0i _`2=Tyʛ
--/OCX9̑kPOgT$=<]‘FqF3g㨽$ݪqdhE jƠp0K'z-f n v
-]Wt+t\skA zwaL)C᯲[϶)aoQO+ Q.p;RM@*ϑG]Ѷw$Q1Ib3(7)|K{a;'~) }}˸E-p? 22%niƗ4v4@
-%- 122[%&$`{8}3zn˿~X)y2jWcQ.!>Q~EAl~J{u>啟8YSW.Kf.9r[;?%tgYgwmbI!Ax.3ܽ5n.GZD-}/׬¤ICg'*-Rvs)gFɻIezB+J=1@WZJ#(K$4->$lae
-~_&e{h:H@1#S(4Fv=ӞOVcP,:
-bqMuFp'o3#Dafvk X먶H&]"lppAw.̳_=9XY{q֥^u9N K=Lo["A{b1pȠ)r@LYf f*'48kEer,{콏2mP+ SξaeZue@
- >FW Ӊ(zv(mbZ&`**ylLOIuxeT|~mқV/h\{!A(C BpqHFqGM 롬\
-D
-e)ӓ'~y*07V]k4
- rVGZ_9ѷtC`iDQ0BI[Odux/<KZp12w (54-fPdI b`F˻vv?uḴ
-(1Q3MC. S&W9]o(+xpF\3\4&)5EI3o1fґ]U4Vyx]49_Ƀ@'C{]Iv;
-6Q|9֣arطōsq󊊹 xͽx;?f<@"lE]
-[h% Q~FC ɸޜs#!ʽY\i#i!MCt=6r~=ʻr =q1I?te<.qyvo*AS2.ҏC5Oqֻ͜pXR[DԾ.!Pn4Fg-l\yzUIb˃*qGpjv:x7&j'TT %X /6Oj١y)ZNw`VNy
- k HfKOa稻!^?lc6D[w0ӧ!@8m:Veje݃|AT#F>;:}qtuNҞhԨp<ae*x
-s|vVY-xE21V&A qN:ȃ)K%#x&XRoig~^^``7_4δLդMV\0<dggzOLJVNy[^_{űdQYgOݲv
-ݎyaAV dJE"Y`pUQ_w,XUN 1l9G
-M׌W-K{*2$!)c !ڏ
-}dU\Q {GQo ՠ%oKg}a-P2VEr/]n!5"~bM}RN[
-IZkX5RILobbsmҠG^͓*PС;8"u $=N!wDQCRY]4Ǿ+k̑( .]d}L3<]oPㅑժàٌ
-[hr#UQȾLyKtטF`%;HH& UC?V;ĕۑx
-?Wyn>plR;Ɋ
-D'o 枉a=P V6nʶXV_~9*W=<,4ʂzupytx#-uQri/s]T %b'~tXϤ*ۜ5f/r?whUJ"8;$Uc& >sMߕQbe$@1GP8t b핁w:7m, #_?Hk?Uzczq&Aw/} W;pIkĢE2eNAplV|?g@(v! 5+ LQ-_W=RLDЛqYO*"\ Al-{9w
-TX%x-(ـF!h/=x+@D[mˡzyΤ`MC@g/.7S|$=a~k($bvD +|lYor .5Hv6Eu"h8a},a^Yy]>&ŭR
-iid;mf:pl
-i
- C˖Erkyϭ-捋gv`]kJi( |Jԉy(ے2=]j3._huP?l
-V~tLH|
- `bPUWU=uy7&!ڢij۾UB-wFƩ͢kE |QcF@mM8dN68.M3x_I&/p}Ŧ.}FfD
-ŦaU5W5-) 9HViyK4-:bJd:X63y_I6w%?C=D{Zyǯπ/9PאT)
-& w-2Tr p׈(EzT)Fo(s"^zba}'G)@2Fk|3}F
-g_5鵑iTl2/A H"|(/e'xw\94FX}!x0:EcA:i}*By&G_j VZI5C~[IP˴jCd /^Dsh~Fۑ
-*3δJF7i w#cFT[|hvˏ^I,6ϟ?Sd##=J4NW9#٩6r 'j djTB1
-U"xpE˒N~$94.A4^C[b[+=ᾘDC,"7"N-4Z6^.:o'h85ZrE\W)8zw ]]W=EtOk0mL:Taٰ~!eu `RʪL8 7߷ N>{SgNpR4)% #mc΂X׎56({c18|TTN,6aa֎"4Y2ܻE-`s݃4LOnqۣvd7٪EjNDwj0Hs?%?U'!aKyEQbG}Ϳ/V?e-YSDwGv2flXM=Ssz/-iacPn;Tx]EĸCܡ'6)J _&(;x>-.~g6T܎ŠFGp%D^=Mg7\g:1i>(vjA`cs.,94Lp~H?bloo~L5)=k@ڪDC15)v@
-,0ṷ#fNQLg!2}@غ㠭٩Fj(:5]&SQ\<c y |
-{R'ȝsNrR`"koF{,;#mXߤc̷;*K<OvlkR׌b/oqK "ř`_=e&ۚ0#L8r >$ni;06Uɛn/ ?ʹ~}#+W݈0k;M*lWQ{kơog%_~j]NME$W%(4-͵;s͕ca
-X%749 =+wּ:}a2h#lyIbZ>0Qox67uF9}04سP{C¡\B#2IT7!' 1qT[p,0;N`v!7W1QvXOgv8ƣ^3a1T~'͊܄3;34@pו&mGߗcK;˧'T+Q(v45T(:d{|{o# KNnC '#pMp.wr%E~WU 5̓9t'Uj/x:Td3;Z*gQ!p+Anz' -Jt{ 9tc4O O“
-9Om@d$R<[,F~*Ы yS:9GcLpIL?e{ ykX|5h#a82|Cnq
-=0LTԟyrZ>뻉K/ȭ,kmQn/!Q诨cY }ny*`e)}"\we2a-#cnhPv6*
-dyUK;+:;‚gŒK`6 1ϟuKx"p e3q/33۵]1aLBEP_vbr.!/4¤2BwhB'&,ǫ+3F4Jl0 XIylxkttє Ù|86r(wF1K
-e9X\)G\J ׶RZ/G{v'gxP= +b vxw84g5r2>:zҬAshg/v dUڙ%e$H$S(:Z@!Rtʪ/Fa 3"aa{ވgH78G6h{59҅jϧ>^JJ6ȆRu2Pk⪾
-AkA2 ][K\g[ }b!X/=D#R:0*W E q?$Ɯ3TٲCZ
-bC7f69x̥nBV
-[kBW.ړ Uu Gu</|j@?
-²Kj=^h2SeO[h 8>g8/W'R1CNqk=F!㬐n5oн,qJsd70ōkTuIFb˛C4uud1Z7Ox\w#'B3I'̌"GQ`J,jF3O/'<L'2v/6D8H,0ʘs?vKKNƠ*'(
-"{f).9{1+%3ub2SkҴlj
-&wj\ެ^n r㞈y.ڏ<qo%AWZLF4lp٢i\zޡGtU)>4jG%ymu$47̄&`@—=pDUOCs?
-j9v$| ھz1ȳ*!I:*-(OIm@׿i[v 6cvˌ![\[Wou iL}L-Nwl_3EM_{?8-4qAJdq}v,F /t la!'w5A`#mCr+8GD"zc.90'.C}e΋k Jl?niEbUHڻRuDଋ;0PF5i1-KOWT`jO2!z c~LK?UMF*eH EtKKuL=ӗRnl4PúoVR=aMa p JcZfj,ڮJz5/W
->(\R\mϓvyV#!)qJʁBNc8uDukˮLwP.
-4t4/L.G
-(uUh?(컨۝9năDT$Ϳ&L tv]<ZQJ
-?ro[<
-M8J㵌 }]#YTcCd XؒOD=fLYQ wr@uxa8DؙG8wTszL.zF@joWBKUS: ʿKHQƐr 'FMe=,^G?v#P4EQkt]wRlR}GNo~$m CR*FLBa̢ˇ
-@1qPs䧼4dvvM@!{ n2t.
-6S~j~ I#V2ѯYc`J'>YP/➾iO}Ȋ|1и'Kb7tzq+rhљ| lJ 
-a"uِ16F j]9P\&o}P7CN|<늵{Wy->@g>M[k\^եMy-0LD({(G`'iI008q].6ۃnCU}}
-<YJ4o;Y,Ji(^/_ЬpdTuzBK>/J7P[\!lJg B8xn)o8"RInb:VKZq#|J.Kû-@&/BS]'+}A=MU}߱@ VNRШtl L#Ҳ5!I&;Yp z )ycIlb=t|ZD I2C߭ǡr㨼ҌxںZvӋX$SgMo,BީH|^Vv],4N9^`Yٵ-5ܡzw<Xd-oS$ӠӰ}ؗ*㥰> __jكhQ0(&hۇI@MTM_DĨ9mM'cfe %c/(4Ѿ9dW'#D2I/<I9:
-4.k@a8^n"4gX`djLea&aE2H+^#Qwq`
-G<=WX}b_Z :B;QrU(q@X:S s#w}5֩mzݰi3QCK![GҠR}Z 9md{QTۧ,$4-hȉo[IɅV2/1x'1 <=,,;ʫodRg7*δUӶ C8 ,[lk]+mz^7g)Z nV_495 M
-Ez_^ƨARXd[`‹?sBjkWlk
- jD:{ܑ%\8?ϙyjdbϨ9IJ >>W$D9NF 4]V]3E.bʫ. Do;*PkӝbWv&Fs9Qeh~Q@XqO.MWm S 9I0^mD.}X
-DO|.@ػ=D51Ar2wh)[o<^*Oy7.XD%q(1lOoNPBQϣ,o.EizMY1 d_j@MxZE
-!|(Œ "1_RͬM<9V*df ϐ[m 3w:Ru k;QdMiSEKy%_q0'9ED"e'iʧ  t#C1M _dKgC>fZ|VC*M:. ^3lx
-?57[&[CH|!J k?>SB'|w{qqf HZ[ȳ#UAKi4(iFQnZAP#N2?TQ^k0챽b1Cų-^:p1ЍPl2;e
-?92a0D>IL`1{6n\
-tJ ;8p;_ͬX[RQ}w
-N⏋E*.TsJ \adܩmoU` &EU]![8
-Y'|j+ij
-v^,/FJJ Ρ"mqƧ䴻9rnƂ[ǹϩޜZ%e3;?naWç$߹\Uz])7MBԞaS]*k3=5g <;z9(z7PE!Tc(ײ!~mL{eZ#d8!:%dQµfȊaֹ'ܮ$ίE᬴oq۽Erҫ_H[`4:H"V{<9Y)y/c@2 31N$t_I-9Þ4OuޠTweu0n -LwT\e"3o9_ d!MAį1Mcz>\&4#> QOAev`o0eMJqXOp199eY),,߯6=
-ra\0QgE'<e_R2;ޑ+8㍺6¹rNQLxfqd[LDlJ1Mܔɨ*Ol{E;s^}x6@8ۏZD Vyυ@#H eOansK Z]"O@u3w6M&~&5 z ۽Hc*ak7}BzR(cL`bv,:Ir;ZSGAk1޸W!XrPzE Fy<ظ]*B`xwk4vЁDK Pus~͵q[ZܱFh}W|&>qQ `lOxEصD}A\MOܴ
- PMtEy_{=8ʳrd֬`5iQsBG8f;RG-@Ap{Qձr{ZZGRpf@}hl-[(9)|ĶA
-GiI[s/ YUB2{tG`rC
- KZ1}R!<ႏQaɗԧxg*-5ܖh˴xnwʁKO(,q˗xeq@:ZN!nNcEN!׆9q{^?滹Ù^. hл
-%DqpYWnrepʠF8S8.}%GɴxiosVq)k0ߠGs )-E,(
-'XDXO x(.arYUa}˛"]hk6"= pRǛ>1Bh2X4kSmrQfF|R^Z0‰
-֌-VS 쎬}206(9~ڧE[vzi+=RE-$"CV[wuٺ
-BZd>"VTA`{K+%IIuZ_TPD֭Yi?!kH! +7w%g[F%տS\4Ֆ>%x}JuH5Г2kX%%1$c &Ym?2n?rҚvN>Jx涨^)UM$Pԗ2q$;+^5w%s6d<+*ȫG! ^nYhD'̉a<cq=iN"K=C+C.l,BZjL.3;XFzسC0CՆ73%޺bclkouE.
-ZkVw:Rۄ//!}M_g[U<mt/3ot`.iWڗbϚgbq" =9 u)a1DhS،?
-&
-ƁSFu6Sj䂌 }axۯfR%֘v'ՄE[ad'X-uMAؑH@'B w:w m7&uC#W" x:Ud_RB0
-U!jOVG6F@3ORv5b#uv{OY71U\F93pDݥyQ8/j࿜I~+FE3NqO"OwaP^΍G5RHO5rrE"fD?\lY
-b-|i\QSJ;֟ᖒaV'툅Re0c^b R o\K^b.Z`*L'ao|%қn
-
-eY=# u{L6iF ,H\k A-Z2n!q!A۫c;jq B#0k GgH3Gw<hؘr6sw1x]0ql5cDʑ/w`uMΣ4&rVr l䴥;֓O/
-\Ҁսx*"qN}i$bXMq]4˺Xp3ߨx,2S`ZegyC k$׌&XH6rQO{]:<Ok)(y;GaswP, k>.@BcCCfǢ~j-i\Qx@{<Tĉ8#:;v"@/Y${k,1c v*JTj!- RCzt~WBvZװn7\U oKstpm#6^XL FwމE)|SnzIJ˝؀i^'' ?)/!se=p].X1nw הz
-;FUBւ/VO۽hzu9ab˹fQHOIy6j㸧-SJUƲvϳA\iyxc4m c j[O۔{uVkFT$s=d who:! am5߅)㶛+[RіΌ(fʅb+&dR{8NYm* л s*/-0F.@-r{ Zah:v <Juc5jTsw/,AyrxT0,̞F
-vѐte3͝YtK6XP%}V"V5"`oo
-,9 hbK7N`-qo6uYm\y!l<5Hwa= n yX%
-
-
-2v+[
-a~EԚxgNw'vAb+̥Wrh8no,WUAp4brbc5
-So,-kkZ6݊{}HmYInqd-ɛ%FI̒g[͂{/㒕fu3kQ@h,'f l~h!j66 jEO5JA9zTLJ(wUe `¢;tCZo ~Lhή hBy)/v;b70JBM%W+Ȥ3 ʍ[NGúaKv5wrmJs#HR,G2'83c>o9W߾ƒGPző\]Fyh=rn͚JM" !}*RYHiCN?#`:GZ0AOsZAߞnP&k<*VCR_Zo=av6t\=ojթ\V/hh[gP/n Xɋ&I%YƜL/fܠoazU6 OKwӶshHmZ ֻ5eDQ]m|-q!Õ>oFEg &kػ ӍWw$Dp)BibN;TEV9S/.MQ1Q>G0F Tw)-L0蒌um (kz:ol7KDDx6QYd:`ǭJ%/ȶZ:Mgaw
->$Z Zr6 6?}&h1|\]c(*nߛ'sg[޺US?0}ڽӮկ8@$~ӗKnaQU^T\zpFs˺[ث~ec*+3Af]k{8Oȣܧ.&ɇX+}L RY{ 8K U "<Btbv@1~8C҆{MZz~>,VqT=Xy')f*CT MeV"%9ؾt haa'>ΩSVn.3bBJ gzz{i~z~Ǯ?4c0ǞcSU^Ox6ik@Z]RDWٯܴ
-U` _& IF]瘽,`@\hy_TW"J̩%ij~(Ipy>Uj
-
-b2y0S0; 5Nդ
-VۼSU౎K}WpBg |{69ms7n<
-vqU$B߯kJ&Mi@P vk _פ\t{8=ӴEFF`~ԹSx6<#7biC \+9: )OEVLD ]'iPn8jZ0% xv-^ƚ@eyX'n*Y|')BO3Nj|M(}TS3+͟}=NPasHHW_LTaPMxUꈻ\(9'׽; L -bg*{(zAqf5媎rt2[3͑th``(lv+'brRty61iq ެ=DǪWչL#q2S2Ӂl{ On~$kSubhh*(l4:6;ϔ5ށP2mW㾵0ۚj9ejwM`[݊#lU(r%ٯ(U=(z@4e4As V#͖Y|]" +͔,j;goF+T 0ȀK2=AKE:*pF=݆1NR_0xXF]s6zyp3(BP!*<x2}~n@C`l^P4o kؙCk[R\67b x&LLM0Sû3^A a|  ᚷ EY5
+xڴzuT6!04 0C7HJ# )H4H#"%>:~uuYRi[-@2`' ]
+-@r}QZ, 37 ,n/jEjgc w
+
+P{
+c;
+?坬
+d¦,3_dTA2wsO2J8۹y wq
+%?[ m?%x1 PCe$ζ ,^dv/E:_8~quzٿ/dqK7Av[\M*R/y@v96 J~ fWlpغKO_/_|,_JGS3+Y?X
+Y򗉲9ː_$s-!ep/' _=7_.-
+}^ ]8YOzPI 9NJ$N-
+n ʢ++ ;ѾwxZn}_5qa.<@9CZ|4WU;$K{PE'îBn~)tV[b9@{tO6c,ʨm)޳x،d4/>YA8sO>9u"5BIZI_8i0T'|2WUuj4)Z ~4*٫~BMRC7|1o@Q ήF F
+h ,z/~[7& -9J/Lмl4< czDsJy~
+#O~I73ŵ<9ˠE{y6p;רֽ,`MȑnXިA)#H
+ ?IJOy" X/p.+`YfX緲zέnN DTM4=x/돠<ܿ96TK/,n-F[[>caYF{{?6ta2s"_BD:B!#ϊ ,;jOֺBc,5. n:7z /B`f:q\z=r94 8xOFC $S`Bl>h׏:mwZ_>-qE5j+ʼ2!"YT`Ĥ4$9HMT<a&dUFd|ĴƂ? Nj8jf |Sz ߜy*<fXILjǝlZ/}H_p],ɺx>ڨSo$l}s-\ ̗oyX/Hyr?pEZ? Z)Vƙs
+t(m9FԱs>0|`E
+C!pG)ʴڪ4г~e7f͝ԅy
+A7Ȅv{k}xf
+cq%n |qq :cռ#Q!GX("MO%2"o3]Cnv1A1pdHx4Оު˝+fTO?҄~*78S "ĪO_-W NhL"C苏P5k@ɕۡ)i4Y&>DkPL#>ctiHz:,nT KԒC YGK?đl+PiGBLLOAp)ßUŕMXҭt{Y;5D\]l ߷$clLϡ}tG*XH۔T3WBۅT1T"RU:j4I?
+ \h~r*1K#/'PIǞS
+y$+{SL@j0@9L/ }vRB<T|vR :$o'4ї,9NhpXXVWS]?S~%p9y>삋o" (z XFC 6>5fy#7WNxHۯtˆɏǓqؒB! ڽ(/h
+&E^Gh=C pD
+믪qKTav+).?*RkM觅z/3ӾaKw*4y.RRrwGfzyO\bf0pG^>;;n/-ª0.KM<'A‘tK
+6;u0񳘙_on8$}\~jT2㷶`lAp0Ì8BJ+7O
+tW[fdwT1~xv\h8Y%HM̦rΙ qF$H3XmzR>DqMSt
+ueqs¡o)~Wn(-eLNfNYo|K`"Ї1<J{S}꺳cm<裷~r5ǒvw+[Iꉕ1#喣;Wfrp:Xyb[zHTT]U9h P@7^0 aǮ``r<d݉~v|,er˓Kc髼
+7!B[Xg;{b'Q<~>%5#2tJf`RǸ:0 sx ]4gM*/>LT}R8[C=b!["d|r ZȃY=^q=m(n1.PȤ͊S᜷1u,dV*~wWF2K$-%ɶi1+K(L]mA#eU~
+g"R]lᆒnAYi3 giśU*K͚(})F]+ #`eV5G2k<]{v"_]aU6.M@Ӌfύf_ & 9y
+
+KhM#F\zjLuB(`I*v|骯r4~OT]#9~Fv:؛?ȶm*D)]G 6fgkK83˝_,iCl(*#2=Q6'f39I+gU8bB8k3ٮoٖ_+|Oέ~b4M`6D;+bULN@9TJaDbڏev1=ڙ,~COF(h
+ouN1sCQmVO% y
+Ƌ̭[S|
+)xXFr0 4:YRDDR^DaTc@Aw8`u2k-˫):s9w}a>5 [},"hT41[w@+\qхTkd6 ޼**'^TuۺƬ;[X5)RC<7:_=I*t!I_|K$G9St
+np&ӎ_z}3OtfcP71J6n6Fbzϳ
+чo B,5k"1JG(7RxEx,I/%Jwԯ-2 #ÊfwrĎ8FS?Bшupg@ {}=‹˪F+)7^_ Lcc)\l]^|:uVa-!vNf +ZqS Η ?}̐MEĨn$"___y y}/1(&l59ޘP4Z5߸HڃZPs󧤁Κˮ@PCppZ/B '/WhFb/?¹MzNpm^olz6c%-UeKc{.-WȖôhf\ PlpE6 )D]篋U4aK9H?QW:v9GԖu D(~1sA5'ԏKNf<'Ͱ;E{ݸGy^&$rES,! #tpiM"{[RzlӧT 1{ٷ+V<V%P⮎?x8/F2Ѓj~rON=u)EBD%;q[,axG1mNߎb
+MnPmZ`^x?H8{駊LtVnWr(remqaBMpf8sCh4!hh'Wʩ XԈ? va82\b_ YvW"GmjG☥V4}xG,?<S)TNlRђm@ 
+W#B 0H,}ө5~eF&\{C;e71~IlCE&W^8151vgMD|RBpN7J Pq/AwS^tfi?6քƪ`-GU؍tB-) pav4+)K|h,直.!OwnGũzvdki<GtX(wQ!vSH%6<-Ȩ$=s|'[0yD5s𷏶<8˄j˷.AQey68+{_oIEsPő% i"7D%X^3N
+o8b8fIGMD 6<;Ʉ 4aQ,l '3A $3|J$s<ùiA+,^ ZUkد|o}:&iB &VDtU 4k^DM\>ezЎ:vu܌ ?=VLhTR)H,WPOm}LϥR@VfDTWc4K %lM}GY/RjHٸ5ʤ[=)nʹ\xw/cʺc3Ō ZLrz :c5}4JQ,W+YEShVh%ҎV"6n| @
+t9-/bQ@B_¶N۹$D~ȣx J~ۣ}ojٮp&0}I F_Q;`$$cr"=DVЂoXq~U{H;@qbUgTS"){)cZvjb¸k'VƮ87KarZa0zL.uGSսv&'!
+Erhbn-H5,Zע/5OkN
+wF㧜?{&pBÆerOrĭdʠbAcv;muM
+S%S,n_weר5y$V)AS'\[Ap%yN#LO P*RaWN^B+ad0au~1tgh۱O7)9
+2cLiL'HBYVζŷO`Ҕy*ZT-v29Ño*JC8>g&oٲ?0 LNx&XbQ0w8&j >;qyj$nd3-B
+@. #OǯK Ti '/iԑӓz/]g=_.hPՏc!Qr<BOWKb:W8U K|TGf}2܏zRb.a
+8-KE
+7iٹDEf%w9b(کPdte5;(*K9|
+}N [jrׄ=8IPw|6hi c/L3:;8]GJrFIIke;'w6D<9^oFJXw= m<7jTc1[
+ qI<yk%.n -hEt#q[IaA+SNaiJ,?yG1q [VZ㨥lk(6uu^uzt]tC-ś il;߶m~"o5)V-&J 4մe2Ex &1MIH:`no6/b~P ,;NVJ/~rlhT*A/##(0yV8Y_n"^ʐ@Hf+qsS ;#g?˩c.m#RH$&k Q*/1*E0Y,HOLgS.X!g;ֲ
+ yBfU:h۱˵B(M 'XN
+T[ꤓN
+m$ cIB~Wo'4Jdaa"~ia6`ʐxtӄ
+?=R7TpZ2PW-f%9ܕ?pXʞ0i8|H5{%8X[tGT87ј[N_: Oin#Μ:B⋁̾*.i ͏pS2mnI!+h4MΜvsjT3U˸"M~?J/ܲ`qa?N+)f{U:QI5ePo٫-gl|Mp#i<"<ϐi3ld#Z]羈aG7gY'û FiVμ, NG
+")E=s),}Jެ76iX
+kTwdjF[iճ`pjl 'e*$fr
+oUР{-(-=WA̋/:E&& O9#AjkCZ/^+0ԋZ\08*`k>0DM<k= uf+/W8^()(F1&
+orߛS%f:y X<ė/h}O# ď֣AoRH-]7 ffbD,[1z){*ӓ=JPD
+Do4^5vBʁY#{X9a^лS
+yY\%5҈t9 ח ^\0Ert?MG٠yyRMǪ8C 9DNBVwj⥍yI5ߚuh;fN>*0&i2#-kdqSU4hw.GO\-ڼ~snN#-pM9GE@ (zUKb~<8+d)dµ  ^ra +.wYl })ܝD7}TR:6Y+SYb
+B^DW+'FgZg3ϭt9QL3 jMP6EQ7K'Oh&S/]K ʹ0AgӉ_iߠe"Ex aSsjWjgrj"2p#<>YV&閯.<tC;)"f\^=iPDsbZnq5U9|҂ȼvYVZjLՎ:>znKg' 7TVȨn/Kb۩5^/¼h- ¥A{wl%;_J 6Kd(N!7ߖ,14 >^cpj{hi< tW'%NK?\t@{sH7*tP.xX +NV?QrTzTQ/C<"{cal/}c@ԇ/T4f%g6e]tJ_ 6_?x-n3ey}NSG3[y18:%5._,P3@WoBRWl8[bu`]j4xNb⋽bF~}EZ#+
+JAo"Q?ţg;.-d;ZQn`wu&-/]Ƴ?b
+R+YxG]wZ =4Ru~۾3DzC!!ϸOOMq6hUFUܱۧm暶9ns(,pF;١w^Q<DKvTyT1{զ Âm'j7&
+S*,"`龕ClQ\auyBpӈP
+\M%G1Z(Wii5U]1Fa@ .9g M؜PW,1|Y&E
+X- e!w*K9iYtyrSB(N'Q j}%6c3$+
++}9>ꢲM{l8QXgq=[o!-G6FU5u"
+q C9UXVY:
+Ge[EmzTMN.Zj\8p1t}aKJE'ma ;VM<# hV Nd<o)'!F')BPclF'W=T-*&]gT"8B1UVg=*Z
+oBǻv=>:duw0ʂ{=n_Ϟo{; ;wtL8 yLFn塿ubL1 چߞnVhM>`q"sphrT
+9R/<O)h0pBL39CӺm!(^ZJ4?~caO-2Nb2mq;Na3Y}G/{.nm^! C+⃤+<8 AA'"sa|#s["8/e@ijn:}g.dzQ~cZq9u)MAέfQlcoA>3d^zx:BQ>vDD)>u̯Yr`$@pԼ[[x1DoZqen
+\'-d~tQĄB
+R+&<Į)7dZAE$D:SJC.rGNP:^qEۍVYu^A3ˑc@uKRS uqPaFC$bj׮&QN3J\_v@ZFߩŃa^tVʹ#jYs,E[L>8?J&M*k|*KF [
+w2*¤%QD*tv`,0ӥ"%Emҫȃnׄy~7ke rP͢gVJ6bq ݒܽ~uJٶ+bJЩĿ~=~~!%vAJ
+=Ɩu\Ykt`scFTu\vE3'H7B=SEE(,-qGܼ8DZMݲ5^}J!EʚuWީUɸbޙa[ l3{x h.(!V9r JC4lxrʭ! N;o[&N褠|ђ^hxҜeI{(OJBᰢd42Z}dg
+keW*<Ndp%hܶ(cyqx
+ƢrTL| ?u{-ɗ TG;o5ZL$:GQ8҇#Vaݷf6RMd?Kb]'i%}Yt)0 ]gx?ρ1Yhs
+*W{
+5
+HzxJ'I;kY\gF$~%2޳,LA.V}x!nj(J7 :TcȝLPӱcoIrrȵscG` i K?H6+ُy="bj!ȏGHcQ]gGZ̧#^`Q;3;RzU bӠ5Gj\wWӫ
+3<{ !69?wVa)H_΅JuZ"L6%ԲoQu=5'|7c,c!! DkOG_EW-6ipΒY26#BvJ_{!-"x vj eE@-9+ B5s!(do)#eT6XB*a)յ9KnJ/10Yp97=vH$ao:;Xb'y!SoEyӆ~L_Ls(Gp THB;4 EXN\oB7 V7|RVlJΓIew#N'9|$x0. V
+"$n/wJs_%
+ \ hMnì YZ\3wm\XQ2hr8;hn4EWmgԠw:@}}@w[ԂOݪ`E_]XIȃ7ȘiURyǮcXG}񐴅:v S0ٹ;K
+r:AkʼnV^4gʗҁQeSπ\2QKMa CG1xaU4?T3Ud\PXe;&NSAìK}Il$TY74W*vАK ۳<IN8<_n] OP$8ۜoy<z G1$Q^{yJ&MZղC% D\5h9>;P $3/ҁC!<Ǟ<0i[̀8^
+Ys 8}~%dU^BbX[&sh]Xr3^H9vEN)a~RnXs9"\iPdrƀ0͙vkSG@Gtp~f}ipdӣb4578|P6Y ñ/0n/SNQqhPS]iܐS3n-誗8q0TȽQ$xK,bwI»8<fSsWLy``]'z]F7VtVϢߔWEb͒?+2}yNMB?yWw9&z,N+M\O{ Y#^l/d 4?q#ݽ4M/w]Ӥ4"`) KUZ ~~ Q|kuF͝$BI3}i! &p>=Fg6 Iz1MTa.:?Y??+kPS~FdψdZ5k3"as6j>W᝵3A&r"ҞW!P,z,#u|y@y'uʆz[ӣ(vፇoXxv%iBPHWK6J|m!i)LC8,<YfIro`bmІ))o
+xjx?=WhDGQ".=9.-@Nx%ӸMLJGp1
+0hrhisHRO
+">r8C9`)wyb((C4f4ƑkiuT/:1aUhPVSf4ϛMlQ&n
+S=` l)\V&6vֺg d"QBV (vz.:xENѱ ճi4iZt)`M#JQ6J%FlV7Ǔ,T/Z`+Y놻V5W hlJh
+}X8xu ' u Kp:i@T>'e4km[G<ő͂Ġp0*jߺ l0(F'Cbs6 h:QZV1+w
+TMB@^~c>i'~Yy=/H9Oy_|9t!tWJy {I4✒anŢ+!"+SxVpS$rsOS]uo
+T=Qef86`藙X?ʡN
+= h9<^ tܚ/@Oٞi^.X˭^Ц<|S$\Ο;k\~}qkSS8&E㷽Rщ]rԑ?_ Xȋ@ʃf?mm( <":0P\+4c m̂o3K<,<W?w-ԱBz! 6xc+Z0(ѕ
+}Q^d-s6, `=h_H%ǦR`Ut.nK,FVekY+{ d>k+z# lQSAK&Opζ'=aohc.S
+$$`ڞڶi쨺*vpİ;ȁs]ڳe}G9]L,|-vBm% leS_l8\q
+R6 _ad xI]9zĚF*sŒyg8s&Geش< e1yA+Fꕑ܌7c<qz ,tU:oCʭo7Hg@tMMW<R$BykvہU].؊o'|?t$?Wl'1_(>(]V|
+0vZ$+`"pV1tҺzpEL
+Sp%-cZV '؍"sG?ET%YUP`%Ry_k_ex^2!rM#6ey+>kMݿk*YMISXA(//Q7
+ ?!;Bf$( X7QBx9wఴ~0!.x~t;\^ԛa{ȻBl,c,s3)yC!Qa-S
+r,/E#!PU oT/TαGdMC0#rL+T$,DZۿ%GnzK1U}D2BBnGco z
+}XĥoZ ();13lxjtUBf;\Cld:G<5qHO햃/4y^+Ljܪh` 1& 뉆o}XEtG,)gƋ
+"jظV+J,m[ӄ!~bk:[L'W^wLyPyC(W$P QYZސ
+WMu!dvjrvtÊi&Zdp)bfT쫑ރr:XˤГ4 !Z'K2mmGevBt
+J"Է7Шw}A(̑{xo\p/v1_X1Rd{hiiˢu\b ۵ s~ >̂Sv4s9d:SfCp 󺤺sM{_|A%qa~
+fE<7bLI$d֍CRiW
+s ˗op$ ZOQ}51cX^
+|?AEk#8o&96)5h~B];> c]+L?pXL(+ "ΐkC:gXRB5!
+;emZ^P{7 L3߅߻iDXc`Dg$S
+wWCF@YB#x
+~P9!) MIa1c_pJ}e8˚}n7u9IHe$/ly3Kv3vGUgĭzlJ⍺eoۯ*`W8d}o aj-=tD[, "$ f@*`AS4r >\a1}#-D-yfN8wxy$MUd'[G%}/wfrUԜYp4[-Kw8mo<1ǠrO7TR)1?',:7n#ҎbL V+g
+
+ qR΢ *sNHSХWO
+ØрGZmbOobtDZ&ȡەh%Ś^giCeE' F댔AmZ2d\2B7%\xE@.IC7
+zr:[EYgFcŋDy]^v6g@1~s33Tbf/vZ||4pKs]v֬c]Fuړ[E)2=
+=hUO>^$Wu=2bHgu QHu L@(/T*G ЃSUoRiϽ2NMc
endstream
endobj
-507 0 obj
+601 0 obj
<<
/Type /FontDescriptor
-/FontName /WVGYQT+LMRoman12-Bold
+/FontName /POEXVF+LMRoman12-Bold
/Flags 4
/FontBBox [-476 -289 1577 1137]
/Ascent 684
@@ -3152,11 +3781,11 @@ endobj
/ItalicAngle 0
/StemV 109
/XHeight 444
-/CharSet (/A/C/D/G/I/J/M/O/P/R/S/T/V/a/b/c/colon/comma/d/e/eight/f/ff/fi/five/four/g/h/hyphen/i/l/m/n/o/one/p/period/quoteright/r/s/semicolon/seven/six/t/three/two/u/v/w/x/y)
-/FontFile 506 0 R
+/CharSet (/A/C/D/G/I/J/M/O/P/R/S/T/V/a/b/c/colon/comma/d/e/eight/f/ff/fi/five/four/g/h/hyphen/i/k/l/m/n/nine/o/one/p/period/quoteright/r/s/semicolon/seven/six/t/three/two/u/v/w/x/y)
+/FontFile 600 0 R
>>
endobj
-508 0 obj
+602 0 obj
<<
/Length1 1705
/Length2 21472
@@ -3259,7 +3888,7 @@ zeE<$8Mjl N8.奵g[AR8 8/ח)Bk.h!kյ is'qnpҲ̠
7%G"2 Lç#\1P?+ i:L8
endstream
endobj
-509 0 obj
+603 0 obj
<<
/Type /FontDescriptor
/FontName /WCAPHI+LMRoman9-Bold
@@ -3272,10 +3901,10 @@ endobj
/StemV 117
/XHeight 444
/CharSet (/A/a/b/c/r/s/t)
-/FontFile 508 0 R
+/FontFile 602 0 R
>>
endobj
-510 0 obj
+604 0 obj
<<
/Length1 1941
/Length2 2670
@@ -3305,7 +3934,7 @@ sYpY8J2c`o4M5Wםhǂ5CW)+ED2"O4*N(V*u817
~˲5?/F/t ϊחizLRtJ@ZD\D*;GePϡ 
endstream
endobj
-511 0 obj
+605 0 obj
<<
/Type /FontDescriptor
/FontName /WSBTHB+LMMathExtension10-Regular
@@ -3318,10 +3947,10 @@ endobj
/StemV 69
/XHeight 431
/CharSet (/bracketleftbigg/bracketrightbigg/parenleftBigg/parenleftbig/parenleftbigg/parenrightBigg/parenrightbig/parenrightbigg/radicalbig/vextendsingle)
-/FontFile 510 0 R
+/FontFile 604 0 R
>>
endobj
-512 0 obj
+606 0 obj
<<
/Length1 2331
/Length2 10101
@@ -3374,7 +4003,7 @@ O2 {ڿw&{8 =RDs~%GQn~G_+Zm JMJ|PHHa{Mq
`$e \bEQAZ],J1_D e֚Ng*A3ic;"bl#4&g ep5/j$hF[~t|ls.qc`HWU^)}jZ/* hlS(űRIpTTw0+82.&eHu¾+88JW/3_O;כτTEd> g\OV@E:1s-59HOU.Ab[}"f!P/7Fݕ>&lj;(- hcwPB2 {߳"0Twn
endstream
endobj
-513 0 obj
+607 0 obj
<<
/Type /FontDescriptor
/FontName /ICUZBF+LMMathItalic10-Regular
@@ -3387,10 +4016,10 @@ endobj
/StemV 60
/XHeight 431
/CharSet (/A/D/E/F/G/H/L/N/P/S/T/U/V/a/b/c/comma/d/delta/epsilon/eta/f/lambda/m/n/partialdiff/period/phi/psi/q/r/rho/slash/t/theta/u/v/vector/w/x/y/z)
-/FontFile 512 0 R
+/FontFile 606 0 R
>>
endobj
-514 0 obj
+608 0 obj
<<
/Length1 1670
/Length2 1438
@@ -3411,7 +4040,7 @@ T
[ipfkc3ӆ5Xo썹I\Ƥj[rպz g=XZsF:qh<͜%w%%a7xYBI$i ]K{'w{o ~wg: |p-q{Iڭ^۟k3'OexL!nD X4H%EUgD7zV3v:G.5\m¿2M_/X'ݸyEś &
endstream
endobj
-515 0 obj
+609 0 obj
<<
/Type /FontDescriptor
/FontName /UUTYVR+LMMathItalic5-Regular
@@ -3424,56 +4053,64 @@ endobj
/StemV 84
/XHeight 431
/CharSet (/i)
-/FontFile 514 0 R
+/FontFile 608 0 R
>>
endobj
-516 0 obj
+610 0 obj
<<
-/Length1 2167
-/Length2 8310
+/Length1 2186
+/Length2 8607
/Length3 0
-/Length 9638
+/Length 9943
/Filter /FlateDecode
>>
stream
-xڵvuXm6HH@Innۀ` "݊4"]JHH*- }y;v,+_ #h~a!  I~C   sp !@4W!2
-Bc$96Ŀk
-hL
-
-4
-G"诧ů; sPj
-ui <Q:j${ir}yBlWdAA]ڳ %AA ,vh@t>}u ) q2<?7vC@NBOtLKlkCjCe(M;l[NUh|
-;Mq5
-M]MsjOҲ~dWVta2?ʱRqx:T
-!ֆy/uveڄyq<徨.5I?=K3
-P_?9)Xb3YLT.lY\F`K)bQiH7A5&</||Qr=O[^q
-[!s6VoJtoC쏕fi- ].*sՑ -oB,zV^!z&YҋP@F!A<6i~5--ې@{tqw#^]?hWAr.~{3+3=kƌYK/wb {f^??\"X0DR]&q5<pQä&)mi`Jihv1$] ķQp-$߮^w~/̝CB Jx\Nãf[?7;
-?Qv >Y|]&opuFU47[Wvd`dYx<Sl&@c]-G=ILM?9'R-jEGzJք?|H1J1
-E8>ۋK 9pwgSZlߐ %a@>P'3?Wi]S˶UOW 7;t ń6:)\s nSd8ڼ}* my+jWɔAiC")C6שwu*XgھVR1vεB^T4ÞkRqhsXUҐ-τjvBchх7;"vf]gwR8fr~wܚ4+AEZ;ZT> Yi[.zo;mX|M~]ȫL ^ؗJDj}K>ȗ}&0)#nOOF+ь.u,?BX~Av>5)ddj
-Th>*h_ps!x+rҀAi;E2Vy>6=
-SoĢFF) j *(t3jl ?pEmF 8$5Qc}|ŋSm Y{'Շ;TDR,Kw>_X߅S~r}z"[M,.#恄n%M7AQ;-_ ʮ;WE=K@Ef] nźֽ/񭿾6Vo}fÖ2#L*c.0NUmYQ7M7ƪCa9wFNd?8IYv:E`]s28=OHh^w S1(#kgFO{iĄͰ5 %h4tR"!p@]9[
-MZMwof7pb9pYa?R?Qn55\HW+L%_CN'ʍE~)z2Xh,xߛOhk>?Nj3KV< qT!,'d0DPYX `y3[~]Q r6o2WngHN˙) z+#6wrXgykpd`\k5l̓jXɻkޤDwL+<?t /4lꃛ>5{Os~۟kRVATKic(nްл-n\bYOov|\ܥY3ŭ![/1APEꈲjm)~S./^&j)x]q٪1}x dmfhpGT$y4yjm_+o~$v۷J!|Ԋ y;Z0,K\**I:|@.b@<Z0I/Neoљ\Tk;Qau֔
-XA,sSrOizO[JbT6lBr͙:Fcy#8#BD:?)mtYRxKkzsmbU!}KרLnE➏)Hڈ hijJTm<Y]3B,U[?<hT -oWSݤ20}V#A~XMƿyoGTJ1]<M'#\Q[<M"h|ūoH=t %.'/shYMuuSa*
-Q %}T3*i[ef3-7G3UNd똒O!~rPnu)vaxy:?TCH}0C\Hu.Ot7DLD+C[pD\8|u%:hCa 弗izdOqNs`$>rq98dEo?alSf[
-6QT˪FsrFZ&3g"ξģ'7hJwζTb$}vy0},UJhVu0K\,(b~pBy,72RȃH#]/;#
-nOGTt[6N,cHyH~Pw[!&8$xKW}@d??qZ0Ѧ3[:Ct0 $CDij"2]Y$LUd^t-m7z+PjLؐ=0\{XK'v,؆c1tۤܛ7AiPq/CcXA4;(f
-{ߦ}xacB;RqF^CĢqGz1g޴a~
-fh%PV#g\Kx}|4?7`F*](&
-nvr{2ځ<3N9ujV,Y]*>!z[w}+l6WwepFHcׇvEMm41*1/-&s^S"8app ^g
-.z1F^9T6pLX-3 P'-j6P"Ifzd ֙5I[=h&m>ms@΂HUdD9ϋ/Z||E)mx0+/m :KtjmYD؆$ԾOi Ͳ]lᭁ둬^4lh|YK87O*&X<$G'I N<o rd.b0d4hRSH|yY Qu'ggyK(8n}mRKȇ*'br_懏DoIl36} '?;'bV:ܳ70W>XlDQFǘ98VFF.哳5.|$`f)ww 9ח 1l={r1A.ҶiǣHE*O1s` ;Ϣw)!Ir Lvn츬ju};@?~M0+8'Ŏ
-ĈDniHQ" Iz.> 9u74qǤ
-0Q2B/6s&xZI#QVDU]s㋍
-=B];H +Kxܻ۫wrc9%O[ZMDEN/Eceiw^e|fZ
-Qv&%\^Wo+(ϙcViJg2P"6"p;ZUvlLԞ| 9iH<P`6 ͥ!z5)oa@6S9zk89k,R;+@t2|x)A񋆤MkǢђnJOU5)&4'70?^:
-
-$g)7sK'**9o|)N!4(Yu'kb/q/Bv^NE&E'+ %{UxDM+f-GV{6ʭx.p.[`㧜_W K\ɽL -lLUl/3!Q 9$.,'eyFSP揻~M!꨺({zH X8&Y-$e.VzdÁǜœ̬Ѫ G 06`]gO"zۊ<StqI% J85Ϳe$HTvlI G%y* ڑxT X %֑W(ce_ҾHSDҍbNfkF '3fHJahxͪgMVa'
-B,+9WEoڻt2٘KZBMn~dBM՞tUbt-x`]+9*3PG.Ck_f\u$ Տo&*R)vyIE`w۟:J󶕕Tr &:p>}<8\VFWUP~ iGyRg:7&3B"i)Fcɥg`42U|!E!ӓcGpgBNRrDW:\>Ț>qWG*;/
+xڵwuX.4Jw7  00 4(tI+tIJ7HHt}ٞ}>LWַ6}C>EG=XC Jut@( 
+q3
+Q37bhħ=?&"P[ *)̩
+QV$i
+F'f<aO/_!ho
+)na:Ǽ@t4}{&qTSskVsٸ>_)P
+)2ffL)P4]c~M<Owֳoʯl-1yQi-гI5^J$fOۯJfNKS 7
+uN\$ E{,bQP8A c0TġF( o@#/ "}x'dfifF|竿 `-
+/t=em"j\p'1NL9g+e^EQî$?J|;MsouD+~~y3)ͼ^Ww3S-=ɔrm4^N'M$x?żˏa\j|#ô߽җnj"bk;R4BkRߋ3Q14fupJo"͟RMiVOuw<.‰_/|<tԇ Kd V(՝QN솈MNM"߻ktkR'm&Q0P$8UIrq=I]p}a7XLn+w
+nfGo,]jI>G,(.)}k~΂Iȗ2l ėQ='GZ%6/A =5E|$ڪA7Uv$gɬcLj%)t8&
+}x$a-G]֦N.~4M;8 mDG,=9}3gRDsoaj 0`p P2%2<eO$wY9~$eAG3Y3Nd>FqN#X<^s>+H&C6 <M+ܓ=iXP77φlNv=Әg:iB^KoVXj_&
+ZŨV2ah-SA;kj8ySD  ,^yGr׶BEacm-^*&l.X[j{;O~ ?QʨСyU&.ՊjMaUss|2XH]*BWmSxOjoc^Ճd8gϟkqvM)| J7DeDz.>k_3F@eɭ0 Ua͓>.ڶO /D߇S)QAz3Qmʢza\liď0Z $ξF^O
+qϝ=3IA&c' 3=K|Bјr #N.,VTPq7]S? aQ-6>̽8+)"Zd*V̒NjV/m~oaVyzߌ&E#S<]L^>5kBK3`Vh|mvW.JK8%pf \h#P0My^@ױr.qp#^Ny{]2 Z4C5 lLhq/FtjĪ=*awMhNa7mCiYnnTK%~Z&$HՂ.gX,rmrM>Gv *0d+])o\J!j[D
+}{,|!T_V?u@
+z1=.`dn ao<o[rփ.R^~m Nf!Q_xEI^J]V?JÁǤL,^p=e_Uve8զȲ<ڨVHڎ٩Z繅ĺ3OVZ _}#ɘ˚ķ}*wԧ։@L
+&ppPs~ձ-vDzw7
+qhkX^oU:w]ΚGW0YRUʬl}@]! | *[K~V|,qzKb^R:5l;{]wW#A[9ug1GcƯXInLA,)d50q˹m{hU$E?9W* =nZ^=Mqy\VQTʌ 3ɺI߄l>*J"俕˜;+[O4,Zڵ$Ms-><<?zܮO:RAŘ
+O~ :HV[ @!;$Z TjL^r^dNK73IfYʽ[%S숦}6N٠FLq?+E*pZTzCQue`ZEGd~ڏep8G9s곰u
+[۪_W|#lLtCt"{ʋ@Aq-}J1Hi 3潘)
+[' }6 V$4t0 xHiI'b9~j ô=8&J..SyoRoUC_.UJ^YqWƿ?3U($ēuyy|'g#gPJ4<g7I؍u8Huŏ*Đdm{zR,~U IӤM"{=MƆvo'AEWc
+^=ﳵ5E 8D HXZut+dO_f'e;hzaG$=<L쯰1h~Ƭ9Cdoخ/Я $<U<2 ߭tlMJaN ϯm S3̢9j + _*c.h-Su#ep Z~O
+~;V$&k h0Gig?W\=/2pvC?'|Y4On.PxHe PUIƿxoB7K}TKj.&SFrNz9[7cQu`xUx9,e8O_ž6GֽXL{]G*#BqEǻZ8RlGTKOyxVMPN,x 2ho7kJQ>(x{U[Vl~i
+n!flFV_N\f<^x'0r}}mkiS1I&;snjN0I|2`xxQ߶N?nS)tjCu=AsEْVeֲimɍSuk'dy,(r.;auG;{?4YvfjKda\ܑ'Ӆ)B7Um/. ^y3.#JJZ:Uz?@Z<ށY2e-o֡FRV_ZcB75h.xI_vNǦ]w\>nwӥG0^HV:TV:1iGA)r/=,ezg%3U8~3|
+)YtOy!SXG]#,Ӗ{^*rl* ׄjv.f<7xW\Xt|tJ ֲ*~mL2!4ѦiF9o[Xju0'1|7Ӎnb@bjE =c+enUѭDq/[[&"[#My<,?+. 3FC ?VQ?@e@$?zyN{^Wӓ0=JֻTo\Þ90atz"t,5mW(sA>z'ntOcK/1ySF07$2 w-[5u#ݡ( #I"J$sצ?GzoY+uO AFZr W}%璆И;bS <wܧPJ+yr.}ԧH?1gj|^]SVN\} m 8j ӉӹH3T␗>^fp^n_>#fgŢO=%lx UKznU<.!zcNgѥ#~;MI ƵKk7AݬM0~
+]#f-d
+i =~Rڵ(t^xkaAXSne Xk&|*8F^9Ȟ?Hpv(Yw
+8K|%@Tr2~v]X@O|&'
+QU2AJW6hZQ'6-ת-5OW jRвdIg#]7j&,Qe10\w6A("pP VZ㔤4DlDŢ*wJ1Lx׼@``w.nGj֣Q [M|B<@`FnAfE OV0_i;I_ذp=JJ°=FYa9D\q}E&;
+CuJpu`C/`y4_.Giw^P t2{jԇtV@Η/ ߋ8.5sn]Lh} Kes %{<[(3@!)Jjp{Ëy[J*:42KF;Py!9&fMl <1ޯum%qphy˻ )B<۹< +r!cw\ gBE3T6\bX18ъkE;J2>7d2M\41
+~)43$,W'UsA*602\JmweK|ZED[O ,ga+q^>[0Q`0uwjsj>ލzt#  &wwj$,POd^~*8ΆcAáF FC:]U1I
+<4
+"#uHX>Ne+DŐ!EL3y5z1;8
+,#V/EwY>UJ >ۧWJtdiv`Y=WxoyA2΄va7oDU2͍#&G -[aL||N&BTh٧quӘe,<^ǭK^%OGZ
+ z־ 8v7 0dBdzc!5} QHM1s;w>1wKbxP?B*o܏PrgS6zΪ Xq']1"|1?n#E;_Ɣ
+?ɖTHퟕϛIYIݭo9 }2 Qf # ُfBNgYA'H 2B4OSq[O|#5oq(νm`ܸ{᫭mQTbLt005NNAm4Ot=W *+5m#HNa볅d*_g?f1sC/gMdժJ/蓦Ȗym_5Qz(Yd_M,H LQKɰw]HG/(н6$Kr@E?ZFdܺ[~]E<! 2, Tr I%TWw6L{2{4;<>Ѭ+4WMߩreM;~4yC# <q.Nȴ,Z(Q<hyV4mQa2ÃCÝ}Ɨw=;3^!k@yH% ;Ӵ]|q
+Ēvv iIuոi#[(<?wef6=t'y(@#t'
+X}yt}4Uҧ@[^8vC{T
+f{ۅ ̄}kۯ wxԉFCUH bӮB1/k]걯*|^0Vi9>46"}{xSn
++?sb%^5DSepz?u$&D@uW{!>YLdjG
+w4nH6SV6̷RR֏̔ kSG_T3Ycx<^Wq2U NWrl>v:sb\SV@FaEXl1-4P"KO!d\`Zl
endstream
endobj
-517 0 obj
+611 0 obj
<<
/Type /FontDescriptor
-/FontName /RWHMBC+LMMathItalic7-Regular
+/FontName /HIFJJL+LMMathItalic7-Regular
/Flags 4
/FontBBox [-1 -250 1171 750]
/Ascent 694
@@ -3482,11 +4119,11 @@ endobj
/ItalicAngle -14
/StemV 72
/XHeight 431
-/CharSet (/F/N/P/S/T/U/V/alpha/b/beta/comma/d/epsilon/f/h/i/j/k/l/m/mu/n/partialdiff/pi/psi/r/sigma/slash/t/v/x/y)
-/FontFile 516 0 R
+/CharSet (/F/N/P/S/T/U/V/alpha/b/beta/comma/d/delta/epsilon/f/h/i/j/k/l/m/mu/n/partialdiff/pi/psi/r/sigma/slash/t/v/x/y)
+/FontFile 610 0 R
>>
endobj
-518 0 obj
+612 0 obj
<<
/Length1 1722
/Length2 2797
@@ -3514,7 +4151,7 @@ Sq‗]%BK5Y S$yflƸaR+얩}g&83r
G?K{UTBRۆ_1m)pwrX5{ 臗D/yw{6&Oޟ}9fB.3͞)1O}ǝ w&feR< 9^Q*$[5Vn_Qen䩔}O2g/Vyݰ Dz<`uC+=yТ)W7k~󨛹ÑK<eE*+/'y} Y1TSؑ$omWNfE+{)^AuQ&gC32(3?`on\ pb%22 =eL?BϭR>aVŞyXtLN51/C%^48HGGT_'2:v(NVnȪ:WԽU?aVG?eU5˲c_.U:CЮ)0$Z#$ho==iσvx6\(Qi6&6a֩7BڥRWhEk[Yس"s⃟F_iOωdkܚ+>v{6IS|o3',SeɐlGF<~@rԩm@yLT Duhg{nXa3Y8GIV&XY!i#SND<*yr[qzq
endstream
endobj
-519 0 obj
+613 0 obj
<<
/Type /FontDescriptor
/FontName /DWKZXN+LMMathItalic9-Regular
@@ -3527,255 +4164,262 @@ endobj
/StemV 28
/XHeight 431
/CharSet (/D/d/delta/x)
-/FontFile 518 0 R
+/FontFile 612 0 R
>>
endobj
-520 0 obj
+614 0 obj
<<
-/Length1 2973
-/Length2 35118
+/Length1 3033
+/Length2 35577
/Length3 0
-/Length 36724
+/Length 37288
/Filter /FlateDecode
>>
stream
-xڴuX>LJ#HKkݍtIwwH4-rs..XcGȉTM$. L<
-*~u gebt6e$a #bBi:_a,SRY]̀F@3/̔of
-8
-3@PH@2Wfv>h̊㗍n@o8̬ ۻ:db%
-l Ȥ(,"}YkMTYhOY\x4WA=(S~1P&@m:->z$3e*}Ej>{,s3;ENNpןqFK43a2otG >EQdܣSt\[V?܉FO_a! Lz'22xBsk`(eNN7뵏JPJA OJfE`?;Gq@|f̧yLO:vڣ/[MKɄn°3Fxqp ;F }HTylkxH˪s2l&Y7su3NkwM`DU%7\_F68/QZ[Zsu4D!.\<JX[#6o˱*/:X-iW 1ѶxeUVh]EOc؆2"\c/80y ?qm ,h!i~%s^/66B[&(ȧ/YOh>"pޘ*R*X%a9Rlh/ -TS Ii8>)z bP,
-Iʚ0}Ձ_UOjV$ U#IE
-z<PHq.K C/+ p D ͏gp[zH)Ă'̟-w,WXE5^%Z0fz{O<m<ߢ89RI'ڐ*ŎDwDEց4Y~3"…Gase~ipίXbhٰREZQדS; '[dygw`roao!+X{nk,Bu;td$_F<5uq
-ŝ@7a4>f菝l>)bQm$FqRmN e쬼 CFc(؄(r4O(5F
- UX<T?
-3;+9V{ :BUqF4* {ǁr$ϋ]Z~8HAMbGvq7yi~G1ԡ޹Gt>p͎tDQOpY_77s=Q">h0߃rbsƥD &?8mL$R"m Ҧ[Yx]m%zb2,>j+٢t]dp@`ӊB|Bv"e]b%q& L̓?4qJTEWYm) A{}Co[
-Ǟ}HF͛?6JF_&Я'ھ3{M\- `F 2ˉwmƮI̶}Ŧ)YmJm k+p#ЩД]rvkw3O{LwZ5I1 f)|CdD_E;8z'qep17tqdm6yMCmkQY.s'U3/kҽtBHRДg=}#ׇ>6cO2Aڏ;GVVtLOdL
-R `Wgj7qJ0SP>{8S|?E(]EaFJ)r썂&!Rap*XhuX8`3 f2gR xBWJ ]9 &ʄJx|8Brգ:-4jAe;N K.ۃlj˒eI 7$DW˚/u--)u Qg_>%BKh<DY7O⃚J'{dWkkHf^ƙE"XVfوk.lx<jeFvD:snPcX^/Sd~23dϋ
-s^%*!cF]G9$9 `#phzN$C;J3lw9|GqA=p%
- <j:ZG|k%GzX!63|z>n;|f
-(dNQ_ E`V;(yD!PL"&hV[ s9ʂYӇ)2 x(BX0,^(/n~+.&j<p+a Kgp9Rz)fRץ#>'  g)'_8[k?X^KOs]'o j_lJf'14 0p. ݰ'^I ąA4ghdF羏 UX@9㊜mwr}I%x/.gΰ}F!A-Z7%p<0ՎXjAP{XYYHۭ svq !Rqp\RgW:F7l1B&뼻`LNLǝkl ʷ0UhY10<ђ/Xnq/<.lT=~Nm_kYt09yE2"+SH^OiǪde Jى6s{g7{*7@ˍDΙK˙0B@p[{JdHM~<a|U[M R<HFHG{2#x y!'NJn4qp~ uX굒zmMjS|n}m
-Η~DV+\-l`cZz-fr^y'Z)-l@Ldh6[U9]hFA-zhOR@yPm}3sIni==7rT4}2\;iVX}%Rb`ɒGwPֺdIOѦMpӒT[b3{O*>[_ڴ1YRea) !=+drlpa>|uOu>(NeW-C I!=ϧkicҋoh ŭ0:&^# Nq#MyeUK}"52/B4kO!gm=>kfG["۫2ve/o=` %PY\jM3ЎiRg`pT
-]+XTḑ59.[^@!
-Id: ?z/BvֈERpXoǭ
-O#*YB#Nޤ6똿8
-0p&1*10Qs+NORw<JH/rP/|QF &StVQ*h?@ ˻Iه
-6@cs
-Sws%׎7R.z?p/[Բsz5.;<V%q \L|՘NG6(|4!Nai_9գ +]Lwq7zËt*=W1agHa`'r)DZr&2+`?
-*1tϬ9xwTsh0\+K@Ef6)[wOs3(jj:zXe7Irs#,6k@ـj*\F%'Ͱ&a ZG8Ô$dOMqc%l8܀Ae7ّZm!jq&ҽ3w uļC~č`а0XP+<d|ˢA7?eB`q-`~Nո@h< ~KJTd^z &a^ew뙨9YP@]rǵ`) Qw!:}i9
-E{z&z0Y׏oqN&'/C"hWA#G=uBfJ?MrF_50 yK;{gb=X?sąvmB%\LE<-A A.X1_E'762ưҔdTgK'oyTOV;9\*s4%E¥p !>ҟ,9xa_犎X)@a#h`4*ZC]yǂ:: X/XRUhk=x3KSVdx̞/dJi%;[Zx @lm~^AQ*-ıXL2wGOɣ^?%0('ҽؚHB
-4oW+9 VŃ|{'&ݖ()-+QnWogJAZsloY^7a r7~-0DiXq(UR{EP.L;'9 8nII|\eÈCl~O/q@+ZL eֺ/$DGش+)i'p8MIλUZ;Z
-f6Ғ(}R҆<눃L.QLiv\姁{&V*GȆC(%vRo&t.;%CV讖C,"fsq."20IT`Lf~앣,'ɖJu[rǽFsChwMSul`woĒfe6h1h,FF|n"GX-;8:V6"+ (d",С:]&2fsVO6Q"k(;
-^xn|VehxcvD!Ҷ.}[͹)s~\O
-iHb]d}P5 4D2\Mg7:)^77tpídf-J]!
-l
-DUWd?띠7lTݰ|LzKWA=DZْkRugvh:T- /íxy0_W3"<Gh~5g[ B9Zu蘆!bVEA!cw$ղj^GY ޶65$H!GDtpD.V!Ҟc#httqQNQ@}atYWxh?u8CSIy\MY85F64`aKoTqhd<-dŏ%3Z $Xonµ/gB^=bR}:޳4"`6FrJBh[r&up)'Ku͉\9#%?=XK$pw9HgNpr 
-Y}͆ u"ʪ]i!G
-*eOۙps7cy\t,sJCa9p!!;et5Y$ZX!J-͝kI]դMevAkHۧes!.z^^)_gM`yXTMm D?bDiTmcq0BJ8izBtumhY~k7 ͈I S>Z o<Eý6N̛0N4⎑m>\Da'(ZI[Ak_R697^~j gSAsSee唰ci~S:>CR-td.&gVöV=l|]j}J0Ij]ΈEܵh+mAXX(Eս`p+řڲVܝ*w <`V0{Ï;=y&iD`pAP6N
-l#I  3j&_toij^d;Nu~(hNI<&~o3\Ɣjc8nFGR]K2BnaO`X#g4d25U;MDQRz #t3!?.`e|'{w&YH _jc4 ucRrߢf)P%唳4izrȤzHB%Imj3׺
-6L{Zv5ޟ)RY#ϱX?R|MI$^"ݼq@'ͼoӉPdnm"VOGTȵ<-oՈb7y+FE'dRO=$IGT^;I;Eobj7뎦@OP+xJa42s2BaGE&<-++famk[Y%xc7(e`IJZ)Sgȏ;Bj&yZcGg5҇
-f^y8^ּ&z6Ez?}K5H֤F~`S)1cָ^
-յE?tbMO ,P̪ڎh.P܋:LZUUH9DuW#7v8Ei։ut#273~4mxVx(IQAިc5V#C~oUMGWeX9zgv 0}5U ,j.A"#FE y4N:yZ0A#o'(Ta)5RuC'TE%pDZ\[Os\]rم/|p~ԌrVt5|SNTdnYiOAUQ39DI8ܭ .
-[$7Am}xVZl!n~Kz̥m%^h01JF
- oA*_&PծV|[Us$t>rߌ׭ezVy@g6+mv.ZLe<Dv|jyhHe]DQVL<7m}/^}5YY"zpJ]TxsV }|.[$oՁ%^^ډN吧5K~{7џʽ^ay ѸH(KվlQr^y r| HpOM)1EKͯpeGf#*q
-WPG.P轩ѷ*aspmtYfW-qUy߇GKr<һK[) -QY SY&l`N͹et<iÓ r'Йvމ"u8@p=SѼ$OεN&|.V״Ÿ:m-y={[/*jFJLՁF:BJ;TٞwϘ.תzqxщ8A]}@{@:Rl"myxsu^hGVGq3S\Wei (
-&6' 32"V wqBʋF$d!/9c&zi\.X
-jn9ߕE3/pGQ]0ht:[s 7򄑿{Ļ
--)Ӧ],y3Z}B,78[šlak^L$Q4H@Ǘc5P
-Kze:ƕM}:I%Y )GɃۅ& Awy͗*GH65Zwq1YܼXDntJϮG_K}#8! dXVOgc[ag;Yy)!& :0!N~FS6qvR+t$I;ܷT"0jU_ ï(2@mܷSqv6B3'({(og|9A0+rP?J·osC{_B8]t|Z/^{ĦިLî~z(`XNJP&Io,_C:kJ[VuE,#-a{3@'bl[\I^g0,MeBாΐ1 {?u˅opqU߂-m+?}p@п +p զAdKAlN澕WJ"6q8y֦b|%-46³HV ThW dNzP\/MLG}$iPQo8:ʸ=F ̄eկhVD*\m7ꈇqL*cHMƝ[<+cSl?ߝ~r8deVKtk"<9hS1eIGV-WPidn&ES>`31ոi:z8B4Ψ=*R QogheK
-`Fҿȉ5|ĹHȍQ&-z[x͜t^GۚLJ|8T~wi׺q8hx-m 4,TDu^'fk>%Mϼ-ViA~!SF?.VE~KzF>;j|ń&h6OKr4+wNvbxc?l[K$`g)|W%lĆi22Rc7X_٤q]pm"Í][.N KVc{tO,·h͌UF.gUQ5veYסHLR+ ;%n?}v]5Oy\o
-R̷lle eP
-,sbŭ|=^H3̪쏌ֳbIO3[~~W:b$G,yi$ߪ" ؈_%͏w}lx'0
-tn#]ܐ|< ܢ |7l=.,4n?T'O!rۢ=&a\e $fGܹOZ $MJe$b2)IJNکuL>J i
+xڴuX>L7H78tݝ C twR"H7 ">g>wqp{=Y14j, g'w +
+Pq
+l554j ..n"- WђtښZj *Z_y ܕĵդl
++
+
+.g=SH5FB(UA - j~M[$'`TG9ąئYr
+JgMnދ$Ϸ1f=_gLG\;qcJE鷲npo]W ߂QII+etɯPz Ra#'0KAEty!DXSwbZG={֭M¨^ҀC;elK=G ƯHQ)Nه0#l
+(io%TH٬1a ` xN셖$*J EΨvI^#5nC.Z>39\J-72$eP y^[lZAiTOӆi9؈gCP!#aQcqCG,חHF%<;a
+ӷ̼Zk_ 0
+tmf?yҨ.ZkLŒS~C
+?]X"!nB`Jb]DMJS!^@>\LlUWg(ɢU3š:gN`u8Yz\TdCXoFNu[3G7YW٭%jOiv]g^ź<[ge+('&$98^7i79lˢ>6uļ&1+>w"5 o2:T*.
+fp
+ o VFaWl ~qBJ>m>lmrL cWΔӑLgꃅ< U#u Bɋ9TK
+JX_gm>;І ^K3މ~}cfm.ƭoP{xS$fljVɜjd=6)_Bc~u~ű\uZ,l)A J
+Hp c2蚺oנn4kM$sP3כm}Oe/6L`.sPsx|?<mv-6xL_J@'s?#Css+XS!z(ƕ0
+tlDߑ[VxnlrFa =پ[a2˺=)B5VjϏ(6ٝ#j..(Tbd63 M̼@j8̓&n; e{o^Kozs9=5ɫFóv|7Ժ>=-f]BΣϣ4f;P)N0c5&sw& 8?FE)&B>IϫWvH;EdJ~Ggr;^M0[9̂.q臉) %6Jet,D;oDz١<CyKMтO](ѤHR#X #jAǂ͟B2t*mKukLߊMx$xu0i sRyֹopi㖧(Rf.hɨH-8>-';76+b>%IF{Csذ@歖FpWTܰ`R,u˗+((\Us\$Zfxx/+e a<G |t IǞ#<\UgUNVe+CraF:l[ݵGxdyL<"0v$(gد pD 퇇 NxY`p8uhZpkW䨚,QLm
+wjPgHȂʶK2ispzJ;e w5yٞ2IBI.l9)7Υ gQ*H%_g'[u)J|T*^{ z+SOjpqVk$FSņhCrrǏpW(c@:O:fi"p9بqpJYGv]}~J'5 UBQpq]ozS& eav^b޽Ó##`OL[`2Y X0}g^.KvKB4*#x(L)'Tk/ᚕAߒ]$|~郚+ H&вEHӑ/#g[Zn Ao;m%t0X8$fUb|W`W/@>B,
+|"hwC3mzǨ֐"c
+]<H!V=p'jjEI]ƉnSvvq
+ݮ:>o(D!6'1[3Vg湿WY݋1ND\jXDY''wmQ.
+:9c
+ʼ,SMư25?YWM9dQԸt>]KbkYh= ''IppnÀ [#'x5Ѩ##nM5ѓK9uTD[+3%NrKW# [*UD[y珽L Q+\2ŋrECL-U@\3vkڊQK<
+LI ! Id&*A"#)h^wf.3CWn@ RFgc/Xo+ÖףfM0;-:e&hJYԫ+q>&jϣ]'ì{c瞣Jۃv^ǯIm踑sT DĔ4@W]w!TYiq|k|swL1c_d*bҹ5˱ Ae "'MP]̢OW2 `z&$#N
+3Vv/iuԒ,c,\~H=n_gq:'8mç*Ψ v(pnA4AB#f1gT}W,!nq]h9#DzGy%^Źwsd
+&~">⮳Oڬ'L\uvT߆k Mf^`7T'}p"˱o>ɳ!y=$ե }vAJ9/V'vE|]1/̤+vfmY8-*կȒqeY!F-I0M 1qJ]i?Yk_Dx껝To)E2oL"}*!۩84R&
+HʖhPI3i7rϺ.q'-\nLxHOG~WfL{{2B"qXr=U^1Gj\=uGr[e7*KgWĆ]/ܗ.OjqrZ{tNѭڼy2BO4%VtӍ1NMm,(ҀⱭy?hmCcQV_]0:vvĭe}w r+%o-Naz0KC*,cHvt^fƢb{%.VjŦqCǟ_.|dJ*5rZGY~EG۹
+ka(EUq0~"/IHE,OKv,␰eоFܗtBG1$c4NNWV%nZCSdD] ۊC5̼]i#̥@q$^G،Q6%*M׹dOKXV;}
+#+ H:'U0t,S]o [O^SaYS+q$X­vr#fZgMp:E-4LC,w;o-"PufD=|j uy~>:@hOB@(6k^<,Փ6:w?XxDQ>u9mNyZQar-V}݉&DqDaX{r'>GQ/VCDo.a~]n#գ=.VSӦs^rrm-d C_AsUb aQXhM*?YPAb#BND&Ȝ<T
+;2,$h<Urs.k2x7&VlDCɧ-k {N%}
+?9K45!_
+A+OWS{)iB^
+6(2hySdfc]Jp"??ɰb#5SNq_OD6^ ^9lBdw{of:x%g$ ף˫M &7uR񢔓"ټ6ÛDw\K0#,1[^Y>Q/-j%t"QsX*R1'oBx _1=QêrJcԻ.cy%QjQQ<bpg%,y#sỲh]*FȽlɀliܠV\{fe7DQ Z?;[%*oNW3>mwӗ ].)`>Zj#W>+Op~}HyxplX;w{S%U;gybW!jsc#ya/K;,_j>͵$"P6ϰG[KuԸ:RD.*j>C bǟ k"?mɯ oYeLEԿ?niͿjn }`\ߩ1"bz@g3l=I9gS5tZ#-Y SLMʹOopDF wshwS:xi4üC(N#vuD0]+@'H>KrF|=y|mـ8J}<+\}HiBpND%@nkZ%SQj"\6h0yVAm3W6LalSWݾ. rC_{DTJg Rhp>87^4^!dWG0J%ͤ;C=j8uO?_576a(:KIN|@'f:&' D{brפ}3M]YDO]sߡ1fFڳͷdV\I~cH5\>vg$ ? NK[E (ϧq"6J$}H [V`R
+rƌ jXÍ9ms mCgG!e 4La8nY؍X YzcIFumˁZ$dhVl<tcYVd$=G&ԢG(@ضfG<P̓6ep֥NTl6%U GWQoA 0cJB3%dP G9C #j6LyI|u?BIJIcg<MEB5mas>dQ8֌wu+$]6Ӈ*~qDr r946W1x{5IS{(>O6 NJT\ ZLLr '$fQWwU`qUwsɱhlp#~Ej>̉^NӳeJ#k0"
+cZ?~8놶f71''@?}B0!Vkb:r:R(N^+_UNs,H|LmŏLu *~IƧrt{wWR9:zak/{С߬!iWwn'=<LQ* ,*R%f
+%υRO| "e. zd;X0LdL9wN<yG{w۾ӧ_>@ʊu1Scgi}bgQ-&SXiߊb=Ȟ{h vM
+3S,CL@qb$ wiQ)MYFO*-ЛK7Wv}Jz>Yt[ & P{?`ʮdSXEaJhbs:i&ehmy ^=©~k鞙JDo S8΄@Bg :uV4şR}(*&I3}R'ҧb=i[$l<,Г~;XkFzys׹.X2"9L[m~*5Yn-2s=ҚGh Ge;mϴpۘsGDHVdaϞc1ĒoW7vՕ&HC[ɾ0Ի]<A]W Ӳ/¦j729X4Hͥ,w"ClR`?_b<etNW`zCwlPe VasB]"
+鈚Vc9: #>]i$*Ø >**TFI{;]TweMVrҰS8kQXG鐑ऴ=Tg2Ge[i#,
+n]&> 80ϰ&.CC,2G)EcM+g7,SK,.9<^)(i:WU!M,:s=IY!(f۝HDݠ9b x-`. -J2hqy
+EtYz,ÑX[[87fB<A=AHD\òq~k]Nq?^sOu~T=>u'MIܖh%acia;G"[[SH>*$qF-:,?1(&`oApA;.EQ3O@E7f,\yWk|=faSqݎ3w[PdW P^K
+52w"RIJ҄hNH/;-|p0>
+iդ#a)yd~x*0QKg&rBì|sq5L3+0@ gwE"d8[TEChll,QQsK{ޘ++>
+ō#;Gkz矜M1"<!AƗXҺ䟄4ۺtqsFvi40QcZ-p)ma?C`X⍫E}6pm0:{6\v|=u48^HRUrlNL[U$}b⫡1.fo% `Ƀ,U3 ;.&rXoTb.
+̧ |ܥӮ*8^>Mm̐a SOF1)?,4`ƪ%F&ÙVuTzBJ9BSONqԪCiEw]e܊Ag;O ]\:5ao=7?E椳W߃.aYcdHSHZn>LON wꮸXF;?MSL;H<sVh@ ڧ!]gf1m?_JFvl'eI>I-gH9qg<st٘ǥ"DOflV6>Nt|~P߀cP R8.7fh_W⵬>V,d :X |*`>(9L3c_*1IV{ zԽȚx=b2_j(nPyHfƞ?K]&$r2e`@+,]@763"*%cCN2*: ڽFyV7:
+{ eO2tDq^*%aP̊fVZhY 1k[%<P0!39rCEgLl)2} ocVP
+SaĚWL%50<hZQ߁߷(1|22+ qZBYh|6L)2
+61ܥE9)Ύ|Yбn9詻dJ7=Ӗr;9  {)|;!Be"t3<~ ڌ:I\S ߖڛ
+"2b͌=Ktӈ)Zi[ –+nyc8\=L-!@`T[:}+Cz,!렪vWPɽ LFto<><~ٸ_; Ҫ1;qfگvuQ|{0<NS#mu!k9I 
+ͺn8JW:ŤtkzRM'8 6l X?qzZcZSTzb)D>:
+cq4a щ}|hќPwsN!MA^Hk?CNtrƏ@{=;/a kJ PvKխM
+b65[վ
+3
+)z<VddUp~b3#vf:eja|Ub]MtzaS KE:Y\M:_>6א ~3*FcS<;KI~<GxZGH[Tfpy\Wy ;,C}8' 9+$[Q$eI^sc5}/T0)+^<C[V&V af[B\,=K L5O|crvii"gNX"wޘgpF{(+!c`>f?ofϖLCvڧo)9O%Di D~1o;wXX|[K#LJokE{*sKޯyn~SwCaE*S&`:KaJ=0ǔk/mtfԨ[hSv@ກkQh¿~p
+v Ѫ֍kD)˒dgCLeu`&U(J%v-zrG%j}{wTə)e](WEN_B 0͑Gt;]AWDCeަO/>WЌƟ6ֲ\ Pe^ LtSThڛG3F<X<ڤ)V_"ĽØ\(!j:z*_dotyf.S.R3;!%ᙳl6Oƽ
+Iv G%IN4<7{Q>3 dX;%KKC ͱ/8YN0ՑV;v IdOg#`mxZ0ȯoQTJԕu_(>+Ayp !S$k"
+#*ٷ}e(M{]nF _Mkɖ$8.%fp&LfsO~q uRm|B[}fC^9.٘nAO@&=cw[&VY\͟hOZTzvQ*or⟡表_]ʊ'aH.ݻyDNzu̠W ]!1 U6`{#Cb^k)ajKK+.bxr_{4=|Y,7#=k_4h4+!録|SMow#܂V}:aote]-eH! #[PS?ӲF "%'b}uO]b5$u^+ HoW_TIĚz=azbh2饸5<ۤ\Vkr`/'=)
+8ATr m\`ea;})x:Ә~B0j]-.Sf(-09Mi3G`~]# LQ3o<RkֳZTQ;w #RT9H5^a{+
+1ʀ<̍7c}%kZx缁|R>=/<=Jܫr'+nj燡)ίXodNX*Pה<$v4X#8e–H K$>Rgkش8#7Bu%PJZC>!Uz=SjQYz o"v?XLYя3LϰXBPlӎ0 lǶm۶m~ƶm۶m۶m{
+*JV+]=2qsh}H~Ko* ϝ"gLNrϢBg qO|OG#w$9Ei詳=
+[A%%2B-އ F4%!gF&cBk#2u<Kyvl~W& B_!lG,kgwL!s
+f%30O8A}R f0l
+ѭl>< UZoaXxcV9@p6|st8ZٹgFg6**1o`.ɋj<GԾvu~|U*| AhyWUӡ.A$)N(q1j2Nԥ ڄDkk>3[0q8欞J;W,۶Nէ ʼP;:`sFK'谝mCq48ѾU ,wPdKs߭f1;䙀5C?p0[ςr*p&et2fꕶ/t,()'7Jף=xw?cқbMhq2jRK(xat3sn*TZ_MZ
+2 {5/tIsEŹ: `Q|@(hAX #sHd-:yu5[Ӱx&dS;I_l"lhL2,ljg^2%A%$,]7#^ovF}bO_ʶҮoxbE abnw?0AFl0N<g_ȌDIş?@
+S n
+`/ Z*&,}؛ d;RH;͟5k}<&?Ɖ.y'o*b 7VR8gZ_ "kۭå]e0e4,gfy:&yCвHʐ5URb}AAwhUL!'@FdDncWjoNMsrO.@i{oJSBD*d}Y?>U6 !FKa{"
+:ɘzqSkZ3&#-wm
+r_%)TSj$z͸L 2`]Os#r|FCjZO3EDv0kE0*oiL.,"Jz{\mQ6ށ/:a `jЍ rKQw-+%᫠;WV鿷葺7>L;ɁuMLe$P/l-~N~w'B(R%@v˳R|D#0]l^;_0ݏxouНYڭbtqRP$ݩa:\k$`5 [ ,j@+l"j IcbawY75
+Cжٴ
+. @}Sa=A1zəЗ01GX,HGoyԸ8N {an\j"]ow5ha`C=7!<MdY%cYdC B眿՜IE~|7c3X >^ur "\bjͥ'&\e3Pq<p2٠Y߉ϴj9~'eva ~7(Ci^owbl2dquhŖe
+5)E Z}ey $_r@\1El"r5-`"MY3$a36i~;_)sH(ZPUZr=Z5?%6TO0\w8gBEa #)m\^W3Mq:0ݷZݰߥx #\z_h[N0 u9zJ\5;suEtG_]
+0ޟl֢m>bw#mx=U!KhC E] 4T
+4)߬[}h._l']¨A*p~X}rj-Dl}uZ?p;!eZR}lͷŁ#b*HT}CE|:jYG-RX}]~fM&w̡[LHxgpfz 2X)
+ 77:% h*IgK˪mg2
+E< /KPT q8!y|R)k=Z˄ei3Q/-m(H4Ԙ嘸e2ͮ=GhKv];.ԗQT%}r
+Z0ptbf'28gy?xӹZ$չ=q Y(u
+c :68_7=;71A>ZPۉ[_%g6~ϫ+^(CI94̗JYJȕJI4aCbެ
+ ~ы۟XBF] ˬwz8U+86:B/HzߨZQg[㓢jR =^[W#<JcGƳ-kCV7M&BһML6Zfq.-doL yƟҰ2{D?d!O
+C(6*tۇc~<i>Okh?c鬼 E3)
+rσc5탠"5~4r=ߛtO#ے\qt1Hv{pԷ#RB9 m 'Y^;NJu4{gl~!T?Ot&
+2-a~wnj.h) = F[h(Ehu n
+mS̗]K/JJAQ`3D!g0\, ê=%+5)le;̏S JӋ:5d= жnS}==r$9"^fvc_,?ufi5U'}IPzCK܃3 E6}*5yT|cbN\;6iV@}7zob os5._ ;n
+nr .gA
+w&D)4-s]oCft^w$.kw$MS4P\w | Q}O{m6up9\,X?b)6l\/ .됤0tpyv7a]g]J"2oL})+`qɨw3g,yw%'K[UgVV0XAStr0o cHj,9 1} flv;h`pT|2p&7KcK /4rPVt*7ZJÖCNWJ(l(d5T~K+ bXa֢i;W6x%YlG^LG
+hOl3a <t׿e*b ԼC2e2$@  ^<Tm9mtR@o
+R=Ϳ9*^-FQp'rbǧi ((eO'hs!
+:71b2ec\OZݭb\ (vd4ؘK';ߔ]
+6-}-i<ckYn(D A݁x:s*㩃wSw×MOX~lDIaMy-Z?#fMk~0OJ0fτ@IRb_8uYr fS'݃;g6I)VrSal ny#y퐴sn~4[YGd?"q˔پ?z5lH(g1"6Eb` ]W
+m>cފRU)y<&YA~EB_'HӨ;Y7ZVZi'O}f8kЁ|;=d|KaM.gˢ37}}c`Iwհ0Ik^! _q.[4r/Ҭ/u?=
+\ ђmaS(`QduTh n| S'dZH2lsqLP#o>UҮTR/])]D{(<av\2#.geKnXpi9^1~M is,¨aܚbgSđFT)Y6&[( 5Wގx<^Q_@g&Sh'N9^eRLnbuhQo0 B<0$MDr0[s0MWM oG MZ\F7=_v3L~j"gؑ[j[cmd,P\lU҈R 2έ2ǴI~*;S~?&{=ꘃ366ݬ2G
+T7"
+_"T
-w@5:WP$UWČSW79A볖c?{ZOF΄
-qJvJn${hOkֲȰPKpgƋ}>ȸ`k\ c0'12ii&W|C{6BBlR塠xn*lAO
-vw*,z$Aj(IMw< ua'Ș8H&f:Gл? >FoSXt0.Ǒ=P^fKB{Gݿw
-J9#ȽngNj
-m ^wS>eEi˴ ]y&xBeE ~ϭ+1hmGrig2az*kˋX%eQӪ)?5(C$~u0#~#2C Ib _,vv-šO_V|ƲBШ옓%IRٓ1Xy7ltMʰQu^&s7?va*X Ul=rII-U-K
-d^/z>)y(4gW3wTԓNsD`}OYYG0Q'UG! u@#5ED4P'udϗ:б>xS-#RyTq]p+v}grO@-o f PB6h,SLžO:T_
- D>ᔵ=k$2R7CrLC]x/Glo\PqfK}]R<$'7rtٮ>g yz(Eᔍ~A.RsI5+Y>w^9V}[`5ke7ܻ>)<u mOYm|ZsãvFC읜 iߕ>_,KGRfHI͜D "wL$?aɠ+N.vf(= n\*ڥH}5)A[cZm~G&fn<<֎l9@b/YsY^6.+ P3!1xzo_o?}V
-{m=s΁?Tg(&~32* ꙷ 7#\ۊYmX{Jo 7B94#84e7h\ot`B nu/31FR7('2 n2UL ]2}=4!T٭}ipŚxGS2|eY3YÆhIC
-x>4w56 );\.3A69F=/$D1/H^kAuBq{ ?z2׫@ aahWuaJ 4$OzX8>Xpfqe\E{(ԝ6Lu:jOq\^̠]7ջm1w6v{ˊ+sLٴ;[GjpKiYоObWH`'k>?Z783t4 _Ǹ2 ;Uyxblf!)1묗,Q(Ę1"4W46Yo[͋}M,
-bfX`HvoԘ"5qthDZ&+ҚZ8fv3>h%iBڜJPB^VSA K
-R8"b4eVR4w`
-4 ũ,:Xe'ta$g<qAR99|HZxc h&A
-~
-WܶPk#nPzDM| H5l];$ 1xKM2VӃ̣uV"/+bq c
-י > @|{:yR_L=c\NHzyXOj,gU0au
-Z>/HvѱfHRMMo噁wwjqLe'/7'
-;}՜9TMXya8U>Y|w.5S߻E74<M~4lQn)*t 6N_u-SdUCK 5?>?ܵ.W}ůR1Pʈ렁=Q){8I Z/{aG@7Rl(Rv0犤Tͯngl!"E* ^cQjOr5?TnsSH*f ޴r_;COW"/.$*#n 73o/p,TlQ\Pϛ]jmG:n~I&gJnӠln*֢eQWxz8(a_hԹzV==C3+cFkɑPKn/{Nz}e߸KŰq}VXn5<@W 7Fx5t!) bа\%<=`Ӝn'35 $K#D>iBY`LXʈ>\0{
-h`K[|=)_1MhLdg^o
-SH(܋8~#LAPq HٱN;5*ſC Tr:юkBo'>l0y%@A\mFwڛUUMg :p]#Pes "R| E+%Z^xaaW#cHVbE 6t&h vtٿjS~4X=
-RghS6ԀAS:cԫp +'y:qt H>D4X`2 GI#cQfhޤe9nƻ e\fn|FxϩB;j^d:eS9ĥFp*wHu"cp&YDBʋAֆgr"@D1 ٦Z|6jt6
-(**k~n Lҗ<. F
-v{R ea&&(|$$RH)rAbnwK*PAkT<Ύ
-
-E6咅ے>8Mk36.%9wmI2-LDBqD̿b&e=dMhk%m 'T mCTe`DYo=X~(CoQdnmuњ4LS} nqlW*Gdr18o2BO?9N2!8O@tmsBz B.r#/^ cuwD_ӼQ~jb) %5+aۦكL
-ul\&l`y' )2H,Hns$(#xљ c5Um˦ +C"ta üH@W`sPGbtZ}ު G{X%vk R_lZ˂Z\!)GSoJ'H
-UkuACw{.m)MÖ]B쪆rGmO*f!2w#'70
-7%FB:.f-&WZ3$?KM8DSء6xr| Ok6?YQ Y==eM{ >BtR*O.R71)e~D]h&c0fVw1 m!{1f)~vJBaAWC7DpN9~b!)7F뿵$DX6{N=*VGzlq̬^ak?><Pl2Fu~74?"&ږ[U
-yLd#S2G[߿j55ЀyCs'YJ)B}Oo`j-ftt[agZ"ߟ2l> A$qpʄ#.:zRSGv4AxD:]x3S՘6JJ}.dCWI%,S2%ZoVs$ ZW!W̭҃*{ˁXwFcYHŶ
-ZCW#F֭IFlD U#x{83N+?=+!8VtaӻBQ!նWu_h@-nŶD@PF$s)TW)W(';B&.AOL),#1_
-GWcV*w Db?%k7K@ vW\G5sՓzo(-kl"a&:Ν8f6eF˔=&Fb3Z|Hk%vMwm&lJ_Znxo~4*Olk%ZӰ+Fq
-h̺zP
-HM[ K`[T6V\*[6t~J6iq!?OTg; FhC3Pd*u6t~cvi7.q2eb2ݺN Q My[3bX6^] b; HW0)`!]];~b"(ї`tttn{0tk@aE'wk`D:,7W\Q
-' m94X%Y_ -MBb:u4ɝ^ =sI
-O:@E8s?_.-ˣkwQ۰R,:=y=e]{h*o.1aO!H?:.|$dG ܮ!=\WÀ3ktf\V1a?}ePˑu|5GX{ms>LєL-=FݿY%QAKӶB4*Wҿ[I鞚 WF<5ig|]9ޑhsZl- :h`9Q ^-/9mïa hϱkߍ)K@.~)]ænB' ȴu~&()4{[WG.jQqju.6&H%+\81!$-׹% .c1佐93Ѳ
-;ؒ"ٻ&h֘<
-L_ ~&Т߂ n"Q[lnZ@D+s'&uth[(WWx\.|n屗\l2{t݌?S.t`tx.  p^֔j
-r.yt.o ~^3˩a/FݭxĚ)õ"M%z%_G6#KزqWfZ4afo*oPlT8.
-}S}<Ι6`R]@, r"TboȭڛVy!qv887+=3#c5 ?R9A5=6x[@3#A$I"eXr+4#?ݕ#in.mā\@zؒ{!_h~<|g3獚*nHHKG-.wہoiuwa|ytr?(E,CV˝؎
-\Ko i37gd)_n I0K`E|
-\e#-8qduԊØO9bwK. !l`k|i@wtY}2I'uDt#]|Nx:tI>s$7YNIPîي~=m%&&3+:A-zw(DÒԗahhXT{ W<\佖jev2
-G
-\D40\ww9*тhe긊HW$qAFtyhotgZ]*ȐlqrSu~5J&Ԑ釚!/Ns%+ )Ug6Y6{m  L]TɥԞ^`\SRNbi
-/gM}&)=kVAj pl#FJ{h7˪7JxOž'Qu
-T5{$DaA gT%CңIg >Ն}I1좃V:,ݷ!GH@=Ò vk6_I-n DugY,!=N|2tIȝ<;ajJ|ۢ}hz_"BFmjlF$eL9S TJbGdΓ=ҥ(ExA{Axexl$4qwhhTN9
-E囔"g
-0!``sNzIbazL"΍ޞbMDl]3%2A Y%*P#0P7{9v)$W(Y1VUi!u,[IP>W TRxXØ HY.N)`${,eqD *ly%ǍɱV5H^sa/BmN4ufw{PhCՖs(}D.XHȁ5!#ueХq?K^{ԩƐ'z y7ܪ*C.`ˁ˽k!' BFD" RQJvAQơ"ݻ+vʝGPv9TgC-/Dc2"9%!ciEUٹyuCZB8BHɝOHr'skJ{gK0mՂ'ŮXw"vh<h`o:|@D}ŏQ܋Mt6*Vfm*GDAյ|}\BHy}F
-~nv|-/-sfp`06ViܤV1n&
- Ϊ
-<Aw'cJ4Y؀P։$Ή!x[1 @GSbt%ΎHFdu?dU݇\CVX2aNC3DlEQ} $r@HcNkg!Skͪ/4oNÿ<S&^khKiad(``.ω5'.m_TKjx9IY-$v?}IhZ"GM/P_P{awAG]UR3QQ4yB@)>Io (9heq]7%!5 ͸dvUMT%*5pifuQG0Y ͻ]J 鹑Q4RxdD
-g> %tkW.\;o-0 C[ڦ(-&}I BQ8H$gDҗ uAAI1xo&?$<ES9}gp'eenG&Da܏ =q HŒOŜCǮG`H>
-hvUQu"{:x hCfz`\
--w5'#EaR| b<z8vP p$!},\g Zθ Z0ʓ6d6?4E 4<}_#Q3)=u}vl2>=rټ
-XrVɛNF2tra@UW@Pqζ`L:#P*'ZGW(O{ə8PBoi?{NmJ7k:vgh\eEЇ,j.tUlII"<s;H=1^Fp "|m
-H潧ҽY *
-
-qnUBhTl%@v֣P@8RIUV"+Swʭ&'V7(~(dPrCb(Wr'2{V,
-n^ORsmwZ֒o <r}5
-ՙc"9EX?x#"H_44wyEPgyi۲;D}":<1ew bTV@uL
-i ,"%tX/AeY96G7Guai|x
-h3E/($:R$aw]! S0YP[KaغqƱl͔t:XϚ<ӭge>I9*(f0%e@xSc.Iόj4B47ԄyFTOY9wʬB-XqCY/3qjR !;sRm1ٿ_w#Upj' ڑ
-.tCF@Mp?PTMJr"K14K\+Mi V?+ a(*4c4ff>TVP8| ~&o!=bˆ:2r <<w)-F$f6Eg VDD٠~1FSRF֠ȎX|CrmLO~048scN|MߧY69_"o6]ۂ}v0:R"4oPES'Yє_<VGM&1{,|6!
-%ʫ+f_mx>084YgyJWJ$( =OY_oN]Ijc+WhM&/Jxѣ)R3F~ը$;WYd"MUhŤNm)~I膳>G SsgvV{500ɃL1.ByDzCt[mɷ `4_US_t&/CH%Ϙ
-!
-|GF璌\) 7Da?0+z
- X @SZpfR䓄ު : y91ecJZ=:7ia~Dk|<HwG"ߖ* 9eg:!-,F(GFGKn*Kd;,VuV/ZG q Y%D_tH|^G҇) vk1F$">FUοuE1Ӯ5x6] ?V>B ub>}ʓp @XNH `
-I)RuE``EYo]0p3c1)/;`-:sU0c=e*ݐ&[=w*<s%?Ru4щplkfȄUE0TӔt7y CGۍ%ef@}|<
-k_|{5b K
-%ڈƜˎf$xh׫8'if47v ][<yozۭޠN-H6EVzXn8vw3
-<RI֋ }dRQZ!M*xv3hb:X} mĴ<gkw->%5GNg}֣og':FչL3I^bt*Bu?2V5(:]$Frhi@Itx
-
-.ʆ/{M1$ XZinb/cp^lHv(h3v㲆ɼBo`'kr87|F "W%1eg5
-¥"Z7bᥔz]bN: x朴ES[ j11c
-nE WDֻݑ8e_d@]\A9PC7;  ^=RM}B̥ 4h^`G>.ec B}CRy=r4 aՍ32R/@}p[Qz3s =ݥ~낟2;ވX
-d%
+ź!0b"fy2R[nJ(o{`%gx]XO] b/%>US*|Bu v.#bfBR"@k,aP=_4\aK_ W{leNESbbq4^+^H.tL==J&4zp;un*XS9uk{.~6f, ׆IS d"M20QJ{T5pny
+rm\^oUDQ G3Ek;ӈ%<%uO]%=׋U͆({V_gIFeebWvSG0;gE:?ps`|2 R_(8[_
+1p<UmP3."AbcR釷 %Y)vKN(5+}izn~
+;,>sD|DͲzm[#kz?ΧƗ=՜!Q?LD4wu n`Quu)ᢩѠw[r#mLhnea(!2s;hiQ|/9FWcSܵ45+p1}* h4u& +1KxϗAJ0PZuj=JbpoV+ɼ=\Bh=ܲmaE#[~ 4l5.{܄*$ ¹e+1Ll0iDJMo<Yp FHң TT%-;~Z~ٳtnx`/mͫ5ŗ+'MOJ<<FG۲V`,H&"YezBnPpu1>+amՐKG%~*B ~4;H79^i(&3qU@ghIӔK(:A`=?jݎ2Č%mvvҴ<Ҟ&=BU;xCGSk5Gݧ s/TɜeQ
+T zQEG›mNheO<WFU
+9wtsm I bm‡丼4]4V#[`YwUڮTg l<mEZC%Y΋tYˁPyHsbե {R Kes#fn }gD#Ku 7~7ev-~@"oT Qql9
+*9bt~W)+Lt936] yʪq4a`E+ܭ[J'=bzka*
+fv-ωKHma"vvm@FPO @Tݹ
+ӿ>i(6Y^uBl\l<q=Vq)H!vQH
+} , ݎZ`:JʜD6"IX0m.6$"*|5о#VҜg)wrK_
+ޤxYÃFNΘZ
+
+S
+ݢ) UVf (م_NV$DAzmN/=a.(PjM(*#(a`,i{n u^04ss„Jaa9McM| ]E&LRH!s 0+o酧!]UGNd{zN!%LeYq41&kp}m `؏۪wjSJ>`8
+ Ep(HjrQ1{x)(9-m £,&j&;Pį@wXYg'đ%3j@:7I6i`웢$@䞫UXJ`׍L/էSInFѼ>9r ^Q6jyy1(_m=gR8R. 1TV`Z8UΣM}i:7|uЁLi3{ΒRoY$ۖ8kQ4Cl!i=ǦO+} ) o˗ 8$L9"L.g]>AW"DYs0u߳k̠&ɁZtg;?Tst[UF[ehJYyU0(JJG%nYWR
+IԕYNHc ̈́} bBlՂ]vx9^W/@~&^puQƨJxcL)+5` .ѾM~>/t`OvLuǛ}$6c pi#yj^^Nj(<^l/2\>=Agu79sF 
+v!MO- О: ]yf~D.?X{z!UmWj#µ-}cNjܭ0<_Y nlj^k0%#x J.15Gu^I' Pfh @7Jj
+N 5rlJғgܽJM%Q5-l3
+->CcoQ4*>[GqYɵVBWYRZ\|D"arhyd<^='`(F&x948 ZqyҒ&lDn(;0x/TrתdǼV{OӯpϽ\[ߊE(|VU@wAUC4+.J<oȓNkuzk|he,4lh!NYHGXXEX}i6Ǩ'}בzXUrOV_pXOH*0^zwN`#?r h!<xPڲ k_`L:?d (قd4w6Zn^ls@jxXQ^i˲EX'Wj:(xnQٺSSGIsE7B+ 7514p)k/cg,p*66ڄkSft]hP`U?G%(]*j}^!]Qڬpi=83\d|羕20;dI!U M ]:0nV<Vxssj.~XM+Q (]3;-(MJiz$ Bh׍XP554SԩD
+w8s\0FZE<*72x?'^B?5WB5VN`5J_v"6ztV% =p ( G[5hԧWEL5Xi]
+:9 #6|IGI޾ jY-:ʞzf[CגP_\Q1y؆i`[ `\s`
+dY(X
+ v`- 5Mt[ DS+QfAJg:ŴBf‡*YCuV
+c~z'q(BFDVK{t\t g>q7[x5hkq5k PaYvuO<p26l^`,% \}ܙ}<͙@bqvevS~2u-ue)`TFK`g}Kg19%`yV$}b
+3:|ZpЄ*Ghp /y7ңcTFqE/!uԳR}ǾzrzsvBgwi+/ђQ{KLbu墓*6(=I!RV&"bgrkU:;8g6.|<Fa-Y>bSR:IIk9A|kLa0sų~ ,V[7F:៸zjV<Ƨ8&.&~ϕ >C 0AHV̓18nN?tuDԴ8[<tlD@L}]B^aL.7IТq$<"Q^2`o&->e\٦ x]0,8+xy[@
+<,D>0MPR~W^QMt:qDaW_CR;g6A q]BQ•y"#{c?A|(o{.BLΆ4qt16;ʲ[|kE] |#اWd}%V;0RW/wgӫr x
+N(2X 3gާ!ۗ?ĐVԗCٍ\GHvkfƜcZ%W/YOpw*VH1>3D)ɏ71W/$`hh4Fl*1({E _iY䅉F7Z@qjSs4y3O
+{uk:~x~Iؕ( 9;Mg`2*9J ϻl ΄ 5o
+$/D ȹ>_ځ~!CueBy3ϴ`˹'1"!c)^Ӌ3K~ :Tn>D(W(SnrN;#1P" b Hb^ϸ,Ub/Gfix
+$2ړs/YզN^+bvaZ"XMIJq"d8.[0$tGީIQ0ïg1$vFcM{{7P?;Y&
+]+yL^0wT3f?:+5qV
+}kGɓhնA- Fپތ>V bŇ\l416{6H d V
+E=[@Epڎ:}2mLra\orzn\Pvcp̟O(~klzbBsm*nŠP}=)lAi#Dz!1Ϭ sucӖMYF^;0
+MjR
+ᕝ}ϸTl,6A<%XԼ +I3W4>c<'(y澪bqH,z s%xE{!<D Z-cϡ/hˬ5b%2 V'pP LQ䍡9CwZ۔*)jع*WY9Cu(-{No9dcL/=G.1ITLj(mJ%EAGL'կ+)k.k W;%H! E6
+?2=,b P/m0Eqg=&R R_] iIpwnth`iH{ȥngt)O3eJsDmx"(N1hrhDƦőr
endstream
endobj
-521 0 obj
+615 0 obj
<<
/Type /FontDescriptor
-/FontName /IYARYO+LMRoman10-Regular
+/FontName /ZDORWX+LMRoman10-Regular
/Flags 4
/FontBBox [-430 -290 1417 1127]
-/Ascent 689
-/CapHeight 689
-/Descent -194
+/Ascent 0
+/CapHeight 0
+/Descent 0
/ItalicAngle 0
/StemV 69
/XHeight 431
-/CharSet (/A/B/C/D/Delta/E/F/G/Gamma/H/I/J/K/L/M/N/O/P/Phi/R/S/T/Theta/U/V/W/X/Y/a/asterisk/b/backslash/braceleft/braceright/bracketleft/bracketright/c/colon/comma/d/dotaccent/e/eight/endash/equal/f/ff/ffi/fi/five/fl/four/g/h/hyphen/i/j/k/l/m/n/nine/o/one/p/parenleft/parenright/period/plus/q/question/quoteleft/quoteright/r/s/semicolon/seven/six/slash/t/three/two/u/v/w/x/y/z/zero)
-/FontFile 520 0 R
+/CharSet (/A/B/C/D/Delta/E/F/G/Gamma/H/I/J/K/L/M/N/O/P/Phi/R/S/T/Theta/U/V/W/X/Y/a/asterisk/b/backslash/braceleft/braceright/bracketleft/bracketright/bullet/c/colon/comma/d/dotaccent/e/eight/endash/equal/exclam/f/ff/ffi/fi/five/fl/four/g/h/hyphen/i/j/k/l/m/n/nine/o/one/p/parenleft/parenright/period/plus/q/question/quoteleft/quoteright/r/s/section/semicolon/seven/six/slash/t/three/two/u/v/w/x/y/z/zero)
+/FontFile 614 0 R
>>
endobj
-522 0 obj
+616 0 obj
<<
-/Length1 1948
-/Length2 21432
+/Length1 1931
+/Length2 21239
/Length3 0
-/Length 22659
+/Length 22455
/Filter /FlateDecode
>>
stream
-xڴeTڶ6)RwŋKqww-ww-ѽ=s߿ȈL3\ *1H Wڲ2̝
-
-QGlig+x\` -̓ 9M
-``}k &߬۬Z@n 9;I?s'a)xKqd`S'Z IJ6IABy~iyvrRމ~Z/M eצ[@oyoBqL Fu4vRB
-)"Tsnf >QV0Ė^KP8/B =hD
-7I^.ehcvPZh*e0&=pCV9KWNba,0?=Q??Qp%"-?%)
-:R@ ײ7N
-.1J9(* sH2–,Oo #W5+,pGayv}rV0#÷id
-1ɼ06ܖZr`~pyD}̲TSZRzr:  ΪBNC?EaǔY^.E1śl<zUGtS#ea2|[gZ"VL}В֖ <юy|id,R<˓r[#[Ellp~nY%) QlN#`8-pWun"Vw)rCqFp#L5nO݇aҫ:+OZ@"kbajJPLv^(9pz+ېX`y?) 0ߧ蹙̊exZ$" BY""2 a#\,y+!!8O&V9 ?ȆFX#1CgJ6Bt:w,g@Jp4IH`)YrqS^ 2 {M.WY5֚7I&9# qĵ`2<7W϶GNrq䋪Ci#Lڵ.aWgˆ: *Ϡ!Zͪ$qY50ɥx٩jZ*LYt54yJ)Ha`ޞ,Qn,~gܚ{cc<Y?9HiPRIH!(-ՇN޲{LA4x9#>fXz),ajiJ7FEV2dݘ6Iao?n…\́Jd{RFK2R10GV?ϻYrU҃tw)xnoHl{
-
-.ŦA0)j!ʏ(bϹtP&ݟ)t!Zh=MJ7IZ.|(x?yZFty6u;9w~uN?h`XKshx2$V
->G<3ӠrB&4vg5ß~ɗfM tYxgSM# M_2>S\L2YD4=IXVF}1LO$):\%tq/ّ=jUuS+@skM#4i~r4elMyCDm] zh.X:OPsp"ݖi
-x5${FI.Ű8+ )
- j0~zZ.KGVS/?rdh=Ld
-6iv~Mj(Mf5Ê}ڳ$QWPfāS/UHČci]e "t0f3$v4;y\;y&g,TOt(ϋT6- 3/i[~}ǣ? 6tFXǃb^e՟X2Wgb?;X|j Nޟ"Z(:J/EFlnWh5{дv8j/V&" e(aMs#H[IN<;zf x\ekdBg<r{^QFb"
- ^(hR?|9e^
-Uɉ֓i f|ySЋuߑՅבx2%-wW@426<5x@.5UH|tDn]FWkņ(%H.66-H،Rs A>DDerv*;Oo[~|_2j,]C}@/t& 1FQV!ڗ-bl+4|Æ͕t qsHCy7&e,r2S ٦ùvm#"RU*>0!;s%v}eI&EFMKn{1#e%\h7Z>u |u
-o[؏ӷWlthmwkSQ3 5;$FV^p'O1<ZA5 Cgv~
-χR8{W,<WKŸ_1\X1bʭd)џN#ɜgr|CՃ 4gl ;66>v5[@c }cc& v&زp-Ǵ%FgSHmi,ْD/t#IxΑ,%߯)M7,jy&S _{JN{ӀCx>mRTFhŕQӆ69WwQ9yW%Oa.V#!X<OwAxl0q^EAam.w,_u=41ZoltxZkI/ڤ>nJ8qyǜ~V FaTQR35vLQ+%+CQKHxXloO*UzB2(N/ F)
-o:c2QB#l
-R[T ;SS$'dPpc#ށt-8͙u>C$!Q6ӞPctdQz"dF-KF徶 B7H, 4jw؂.h*'u** 2Y#‹ ge˸M1F͙Qc)̻Guc9}ZB
-"U[1uC7{72R<]OM D4]
-oX<ZDpU:-j_sB&W<{vU`\:0 `/_~.yd&S$&gV99XAȋZSJޣfg4!X
-sKghĨX 儮?yE{L? ݅\_ʽ.yϿc儑>E3:?@;Nn: FgɨE\dE3~tOX`ÌbzS)‹elҤV Z'|!vtΩt`Z<.N16S0;dҹ"6Ys:
-1,kϾܬ&M9+A.W,Wt]7Rֽ[$CV|`Ƿé
-Qfu;Emgr=RXMAV%[DEM
-)޽%`,Xo˴*869J 5hG] V^F%%,ONaGNøU~\vETXH2, BZΠKufD蒏G^?hUBLIR{72',S;ѿe`WI4%$V'kڒ`U?
-8/֡&p}"'8ۿ4?p}-x4cWjs
-qc`f0^}-HL ]XƬ]'s/C+K>6`rf(TœqWoA, sGacqܲy*3?F) Ijr5bOi\Gs4>pS2cm-˨kj5OMTf<}enO ϱ~YI|Q%T13ADR9`ϭ9Fau]0e̵} Nu7/ ry
-졫,CynΕ|](Afp䡚)R+Z22njxv=f 
-E15Au!3
-WG zM-ThXy{ɷAfG_nig
-/zxpT䚊޻;Fң<2MM815jwI.…Ꮗq=C2ԛN*"lG! DG`]Q1@xT^ Sx|YJQ(N|Qh~Q`
-܉<{vu_nzNNlHf4SڳcoZdK5t
-WHL| 7T<&ǯg]辽ZMTf""Mh2nQHGiĕfӝFa:jN{`ħMuD-"L }"Xm&ldl2IrA,dY\O$&7(p% YI2ScpP<
-ٛoH
-ز,kq_%Berتxe; =iv&Vy,$eBW)~OٱI"Р.Zk
-Gv`[8.,/4?vYVo<2Oj僞;_Lһu +>c_bø:4""ŭ\PV(^sm#9%f >|yQ:424yԦ5dr_g+j $g!&@dYmU>\3%/5%A#a<ەa}z}~_gm4ьHEQ
-Vʷa6lvij,lF)>ZeM,U=GX,PѹáX]0<ӛϲ;gUvjtIO|6/AZJ+˔'~80%y&{vc~t]/“/O]p,yap43}n6ጉC㚱ɯ^ BҩA EZԖy?1b"aȊE([QN,D0ggR{LB l{(_BydSڿs_6w" V]2̾LA1PK+뾢5ٮ%q>ؿ%TďiG ]=oG;3G?CuF{ =>qL.a!HXEC=Hz./ꖀ !$ܕBo,G8fInA4yXV +Go)mܳ|ʕP/gr~]Yk_s).2 H)wR@O;sj8U 1S'p9 w*[ @,|ݑu4BrqVJ]MN\/
-ħyKw^Z ;?5FZU<eJؼ<JV[v;ז;R}QeK{p1!vUlWdsBuN#h qtqa8ޭNNn$:5@"TVHYIʮ.o,'{??\0
-ٳ+ Qć ny94M
- Vv7(W^Ҭ
-g,fohfd(1fa%|3t#ήErUfSDB@z
-0v8a~:2-辤0_?M"<
-'EvOU5CwC@7c#izFzoNPwqr+Z)" @ IOݎO\U€!>v14ystKeqUƁhb
-nT̞U˒Io)}h[c] *hyhkS3ϰxhGfDkf\vppo9^:WB'ۺ'=DݵK]d;LN0 RMG-ިfEz<ܨnvAN}aK@`яS lɼmr{Ey]?8RLmpx#h,*Mrsq)N/$|8ϥMgYwE>K7Mơf.)t43>[$&-;Pͥ)pul/<Ɂ3/*l#/a/*9j! 8>&!ffC""O\؄qR~cK,1ԃP"A/Y_(
-5rƾPT~8i`bTHn,_|cm"K>UWp?gt߽ۿЬi2dY|+%?2
-Ԭ6Nѩ \g=ݠ>qRIEZZmTueswSq'<}ѭ?NcS/p \]t!uc*|X 0gA7D~(wcL#4=EcT 7TD=ܨ}
- M?6 6Ӽ1"ǶRxe*au1Ie/GwS3?N@+b?CYbPuG) ;RT+ +C9Ɉf,:0`ܰ|ŴFPl-݊g4X-<fnؤq\ P3w< nx
-ePApx|P`gzrZ_noeG=IΘ?"+B+W3'
-ML~YOI3K0ҀB$sHyV-ln0EFO7{&<5s:_"#^i6<556hyv0CD/`</Ƅj?I]襷ꏬ^: P8
-Mݡ:qY<qH%
-YRy$ I3O
-x- }s[3s3v{8J-K^800)kUFVx%Ю*t }E~)qVOk}2Ix`_Av0z͟9*Kюpy(BWp&*vCVtHv` o& 6M9~<)RC<ːЬ^ M
-Ч?fƗ_@/MI$:4L6Hn^gK76R5ToH$/`LԻm/qxKV,5w’#̫Y];v ~Z&a k9aVTXޣ-ҴkA)B݋6PcaxݡUZsL)’)mX63H,mz. B73Ňv˒O0C6s];z)TJfWܲ.\?^sa
-OISrbcKZњ[_{(p|p*?<Em p>6[Fg~W9$ w Q4Y6:"Vgg,=LWb~LU=;JV
-uJd(벽KgC^>v<0s=P%n"DqwF"@`FE.EV 3r*NO%u G74ȶ 5L9ԉ̈́" ivh|2G!<̨ĒGM`9ZW9T1Umpw(C\0_8m/ۂk!Ps%FIt5{RlQԤ/R} q8:K]ypւ t[:/9j&k(3!X?8拖Եh ;$%7rdžXamH 9σN%55-e=6&^̱x
-M>vdr
-<f{8p NѲ?jT|R]#غ ~l Nva:QD ^b(9Ӈ}fvaTrI"T_+yAz;,G>j%ى1Ns -,ɏfYqFA1 ~PZ]*>pV;C<lBC;!d樮~Km6 /3خфQ
-WKTp~5h)W
-W' Wwi+(c(~gĻ8rNt WJ)w6_oKՅmlM2GŽ%lw=Z2YٕWyٗ/b\zʨN
-iOm: J?dF["{2OFOa?NKۊ0Ltf98d#3ylpq \}?,Hxg&#QKi;` i@R-^@:a fc̐(?o5Z
-1!$EZSvNVh*>P wʮ}M}U1xrruBvHB?~>̤MT^#CW2w ܋3ĺy{g-04/ʊ[,!Bۇ_k|bŏyzkfDlƐ Z!"n%l9e3d6y9]9ʿS{AL!7lzK93cZdX4*l.ud<ҽ1$dL6ׅ؝ȏZCRC]_4GT9;*ƢVֻAZ-퓛%`ǥ_*\OoUul
- 7.F&Gl< ^heHeGi 귴hK7r {q&@ڙ:ΰ$azUmdͩ-i-C>>\ *y tcΔtGfQ-M\~ҖDjpgrਘըg
-# H}׃`c]DFqr9xj>Ҝ`~qjڵ2_5lQ#wB^Ú,͡5OO["NBXyqn͊.r|&
-u9%Ab_'zI~%Q/Fd Kwu&ZC%WJV8Xm|KLAc'bcf6|o<3e7#W n}aQ!r!ѡ#5wGnܭ@z#éN>ܭߏn(mp Bw(u޷F1n_p>Kn& dcbiUT.O1s^e|t1T3lM˩{pO_g7 :U jS =5giEi[<ֽKYH
-HR<4Ӫ&`=jՄل]$=: C}d
-Fr=ut<}(ּ17z{7,/
-wn.|?J%=Tfs%knPVTu.NgvϊRV 
-ӈ RGR,bur!+XASᲹPuG{vso//=ϰ7 t6I%Չ+}!ѡ_>w-bm!
->͛ĮeJQ0><Ni ,1qe#{
-MT}E5Aʒ,Iބ)g \EˉcNaFH4 r>l fcߙ!Y8Y+HI@c˥QH N$dCfO]K%C3?0,KzvsPw~$._z
-xlnvQ;Ai#$SϗhĜ6p u:W̧oa (}dTr12=gh, '\_ ӕ00dZEci
-'s>Eƨ{&H@DQenl,N*%MNpх`c׾q;x.17\de寈D%h
-k:
-; ko5dAAn7QSb4_N*Yq6!l(2UcCRYm>Oc#w㲮>`}5Uh15<<U5GH<x4͌iJ>MU=RHr޿Y-q9􆜩N"
-*ԥKɖI0u]*ͥnbUSZ w<tf<y%D 79Q{F̖GB{"[#IjAJCzg}\%kYg"(N0$˷j2J7{R0Ea0`_=;%kMmAa fJb
- |mEf\)Q#a޾n\qQ{+狷<7#U {k|ՕC`zu
-sP,) CSIi>;5vz#OQ,}
-P!"owS[ԕshXu@Tu;-X1BPv+?v|pK-Sr57oMyOM_#%f7fc<g:{Kz%J~ in>/ojYFW[)2W,<K^4TBDž _7aeU-LfQGysPp'BwhV 9+u(m q3Љ[ϿG/,p'F S†XaH'kKD7J@4is>2Q2WZq$D9 S4@FHMSb&`D;]w40Pk{
-W5خܾ.
+xڴsx>7hlضmƶ4Fm;_9{kp?\3$J46@QkGZzN5#"HKO KB"d4p46pr
+Hj߆Vni_&j?lem ,Kg j
+47w42% >_іD*Vcv??tcida tp
+^2^"Y*~2K>YE3魱_*GB]WIڥ9.s Mh(KH8KSh=(gs0F%lPuP2P5B{:Q 07\qt$X ~9}eJ9&,Y[WjstG=#ƈh7 #<3ZJlC"{xP0U@ )) 'n+iI ",;^z Nِ.d
+V1SHWƯ $o&<+'AF-ɽLM-lV9-RRYlNoDj`O}V8!rUoZwS`<
+5 g "2QY|?z98]J54IΣ{b>%_i%5Q%Fo_\P[BDz^`sX<kAU ^- Lo=s1xL֠~0 M8ᡆ`ThZ#F=SiC~;S?P?hHkF[w G':b]Ă ,9]H%Gsm5J]L[ǨP!qnw2;~ cqCh?{66iD.Wت0a͓F}h6{1;3Y|+.oFZ|"2cŕCWKM3VD|vy`f Ĉ~Lm UPЭҝG а?Ca5359<?,e<! @0}"~QL @OLLn;
+:)PAcjt=A99P##dBvY^ʂY7K6m'2޻XDh69S,F=ԁSZ\^SZeݙ,lS:0mnӂܐY
+OT P߾A8BE7ܼqFAMA\KEÝu3 4+ȊiOE2vV<5:*A;_ a
+ A룋Fmv%uf̷0RJj:0xӲOFI<_ȥHDULkr%H 3)]d
+7p5gš_ļ %^M
+}xi ՝faHw F`"Eyy2Sy> Nz1 MLĭGj
+AV|8?}i f3[4X- tک,Y4M{]w(ckw9c!f̧#ic_|QxH성CD,Lj+4*:vK 1g3@ ##}]rrK&jё[8W>1o2}>}V;Ĺ5/H ^/?]+*9ypEW5N Iek
+d5V7| S/{nc[b˭jiy(87r_#.G?p%Ԫ-(;%7Pt_xScMO[SO; IõSEP_&<ꬃ
+#!
+>cv)CgnDDfD'(ʪ R&;`{<ID4WzTQC`L m'Z]1#,|\y%ǜKUG&*`vs7U%Œw덥E)n9hn5[ds `aV|qǠb 7 #Eԋy+Z CRnv[x2.bs$_]?S%fֈgS}W;Mٖ<Xv14{Iwm!}wS7ROK) OAWH藫t*lγMwk+PvsuiGn0EXԊ4cIzBjoJ*UQ)֚`h>v lOg-*~& Y*vܝъPI.m;sHtcD;KxiHo8v¦jfGq:Xs䤣^IXNM6.V58I#2?9BOJplztJX ibݼmuFG'KUӇKZ%?sYCVi[;OP5GY;@ׇj D1*ZA"zz)W%@ q$(;_@1= 齝ΎyY_8 60D\
+P4í<sk7^+B
+|o>ot3nWR_ҩNNFŐ# 긏|]gs7E\o4zb>_HZBQ%v{jK5C#)ZLqmue5QF2zmF WXܔ
+j_F!$7 !bBE]U)<F0o|A$Z lm :\F[mW>Ϥʜ䯂=!}-]ㇻNokC4z G[-ʕ.PcsMD|WoX W\閔ΐ+UB_հ41T3eS>mxӄOuEI3CG[@7r $ֆB3/3}Fm}(}xϧhS9,;FuZ^(
+jhn}45 'g
+;FMkgmd+͏ńE#"9DnW\dto<}NB6.7FLHwHTg?, 7>w UКopĊɅ| vkXK؝i*@ʦ|
+]2/і݅Fu3,\]&_/㘸&'`9nsURR헰dBKcF^48w}RbN6GMm; q=<qv>l;C
+Mh A(ZArZ`
+]FIuM)wȦ2:Asc1L%(٥RugC wAW Z"r}W RG2r=}t5.Yʩҵv[s$Lk]11fa梹PRrA-Q{s6/]xH㻴Jd(BJP."lө
+\B);b,i]`~8b_M &a„Ͻھ׽Ϝ
+VRFmv`EK7C>;̰چ ؚ`O(S'&dmXc#*^.U3Zk^6&^^ j$b4‘ۤQS ^RP\FWEZӚvue506B&+/ JƬl8VIֻ
+,uuLAQ|PچhOS0R-mC)_}1SX-B(u{q2~@QɁOiKⅳef^Y|]UՄj[zRF/>xpI/}u{iTFovN
+mql{5^
+~:uëMVl?*gg rr'(p3po ,b'd#ͨ֡z/҄BmygI?/i hc-N0en+O5JsL&ȮS HɋoDБ?U37rH>-3AK/9HxԁD V3cs$1 Im>sn#ul}@hy7(8NT~푯u_:ZJbxKu> xlj
+B74
+4XH0@\g
+AN1x(SX[dqEUrzh@x .vLVwV N zRgG V>5FAa5[ M?e8jݚt72kf-peg˄No7r8!>(z.Er8AIQ*8uGF?ǮH\^"Bnc(M # &}y[
+#vP@]
+u*\{_ձ:UnCƾ풳 %zW2A ->.1 2,w=W-S8̡LOsFw҄v"sZ>sq棗ثz ;)ƧOe8WC$5O0?
+[~y Cu2F}$I!ę=,j[ e-1ܜ H~
+Sgcc]_s6ҘfS zKŽ_m\@+߼L40)e9ٓ&s17iPӼJhLt2{ L
+J{!Z.
+Q[wբ3$PAM~vf
+6K D[ R
+^Xef,'Qv6c{!:4) ;FWEQ=q%c3+x8I7GeSNH :6+Ho"zv*y5jG:ȒCzT?Av!5Wy=TºA1NB08a mb(#kX>|l*Y+E۷q7w<9iez@ Rg2Lk t*5qR(GO
+FmO io! dqI:|V"uZG0jS%S10zw@Nu9kmOՅM,;tJlYjC(ak#_O9yxL҇C|cVb
+
+2J?9289 pB~FjH1A֑vsUtd:n#?9!ħg#N\܂s!S
+ ;MhN[</S3) k[xAOd<:钠>c?~jA<D_$_\b%ID
+1#@lͯi{ ^L0b)*)ZyWF `DpǭzcZ`XKΛ!!ڐڒiش>ݴ3i~b|#VUذq{YA6q|?37u
+rJ513YPHV\X{Pϡ/d\^s3X:.g9Hp'/eiQlqC8vG$JA"3V0P1E2._jg댮_9l~6a0zׂiS!`1p|O1_k G*4MQCFFэe-ތy/E}ِ& >I{P! \eħXنh$(}eÖ=.Oϝu@#
+q>ZI-ZP(ol^W1!O`G*!ȁ"[3nb0dԯB!ͬRQ&p XTاbKSw.aR\(X5 w trn׺fh'gAlm2߼[o{>tm(0iO tV]]',(na?uUz]yZYWC+Q^Լx\MPX\CPtۭ$>\̒E{Xl~YL7hy_W^ o3kV qZg=5WP%s w"Duy^-r+)|M? 0!ֳSJ.G!~D]P`SGD8 ͼQ&A0qأ@ 8"g)#ûgg^r+#i< o\*쐵dg`ozKiLB%2̱
+Ib`)Hh>:̅G hvB`}(ZVEȤCyYZkj*ma.;lh7`OYѡ:֏ҺH!`eizŐWL87sM﹢H-*e\ Ug-bp`:"
+<ozF i_oKVI&pQSMxV5^`b|Ě/ºWZrY9VOqbc#YC~+52zxzNrVI>R:2lu]lcvR2
+.ei~rl
+m5*nG,&y.KV̷{oe^AỦDH'Ƚn\< DWKCL,q.<vTUQV d9śsB N}fy0nn'G.nS飰b2MR)MB
+(]J+^qHОiE<0qƨA5M}3xg-ON3 E._W3,P-GM.7 &L 1%pѣb ] @ZT{L.H%$ (M|؞4J,_hw ξ{<Jy)?y9wI0!WGtSrb 5. '\5pV_$^(/-MS`+R=͡. C(5l9s
+B:sh>Vd@x1 |*Jݝ]=4$*qi
+9wXe44E˔V9VS33 6Fu!=Xy;r!t27Ts5dlb=Y?8]o.Lū'=ZI[c5 q'n[uٖ;zGo/+(
+jpDN^b'.}kQqoЃѱ8';;lQ;
+e0.r`:t]qUuhس- %!ើkմ2Mw=d%*;eA
+ϗj]@-a/%TFbX}OaIX
+{+*0,G;CI,OΫFrdiFF;)`qSE
+/S8%CFiߣc {
+ӊ9Gϵ\6F4.9ËniטlMMz8{NJiwy.(\F ["L0|6kE%`@&ዛ?v޹O*/8ʬv4cDej
+7{8rlbojeLUHdNtg&Oc>
+#p S杝`(J0ƈ<k(m`rڱbqYN1OovG&{',!*\ $hsj(sj-/)X{U|1޷ʋD^1B;g%H>[?ro%2+'Vzt
+f[Ad,w^G%XE ZʠsMH4^ONmcC,I VY^ -)[ҙ߱hIKFiBd05t@]9<4EhtOX]?C 2 ],XfDr֖j!M(Bz Req3*(@3A qiLѲ7v נ0 q%i}UOmel!HZzz֡tnɴjF5z|=E4"O׃s4ك,cN )Fb&kdݝ%EI*'W~Ɩo␃?'\"D9aZ6iqZBZЋ.On@8/.;.rm6ySEeu\P _` o'rrP
+ߛ5i~5zWzsJt!
+5W=癩%r3F NQe#2RFse C'h%[) ۃ\mvu\w]NjFYN]gٞd0Į_:P)8uI]7v𵷜vCqm]sKH"qdE2[Ո jSlV-ty
+X8+]Iq%#OOfmc T!x}eb9Sט r|edd'3 he9 [íib胱q.pR\[i*_0<O~l69mLuŞ'!ٿRH{_Y"nKceCC*!SEΣtV;4i6|j tM.ȣ&ai Kz߆OPmQx򈎇֌ ^>ܿX!}_cVSu.sl
+jkwJxW)s/ܿ|uncw)!1ix"^fB@4?Z0$b#O<8[#jL=$6Ndt'9`yEjC\Zi||;k E`?<hx<HDpĿW `7X5m*SZBcoSO+vDae-rvQOl GGwݮVpY-wtq =jG-0&䛰F
+Y 
+(:-mU
+|vO|KMOgg ǹJ3e hIlZ׵oJ] !p!!ݦFUyu{0|={zqJ"  )3 VyBu9*֙~VxcK!ֈ.>v,XCLU<NR,1P<Q;4$H>~rS?/,
+du&7Q-Q'oK荛%V=jHЂCo)-#ҍ)VkNB v%);’K>U9{*0x[.ryϢua\2$#խafK!k-_";ٳas4~,-/6?1LX
+5M 9B<i Pn+؞P%}N>*#@JDhtB&)CJQx/@ fMҽ
+Ѥ~融x-
+_4ԺK5ǵ,L"46 Zvy0CIsΫkw|&In$Q\>K*l H+`exq'd9wi `UeCj꾙o^vXrG~^!ZJc2v~RaW*Z@Y4=`iOZcKi]X{٭Cp-`.i<by7-"eT!@nZTs9
+̑
+`H6R1ݣd#uZ»hKE{` 3^uҀK[K|9K 9AV.a|bN5]D^ՊGcJf );BHT$U/ܦGkᗞۙ,WԴ 0X‹H| $ҴQ4g.!Nb_BH_X4@ΎSUɵ Uh~׉­~}hi030bWe+i
+E?4mglHy=Xx1@ʸgptd utĽ/ 'SShE{mTW)(Gb5]V څQO<Rd:BfS ȕH/W2d#X.;z"]P ͮ~e>aad%]?\©LHh~i E8t;$"6D"Fг ӞAyӛ9[F
+f)wJ_G
+?lmX<kL91b ER2E_{'_Qbh-Zam4xC++{F{ڡ ǹlz pZҘ&nw ˖u#wK4^D}筅O2R~w}3,`r2gXl/j㝿2l'7lHb{xws
+?G_`F6[Q0^sңB8cؕ^<BX>/EF_Q<`=4|};l6+j j޴>P*d/s5GtTpJ@5~"m<cz:fݺ%I C;}odτְSʦ2%?&J9
+4
+Ă]ԉ~c<y:M]džj3y*B3,-VCxwp }ZYs5p) zeO@!!dl2MRq"Zڎ?Og^oSYRzGw?IV)=>=dYq; _.?ewvG~2פ5'w]mrS~04Jqr~nMNz"*}50Dl j&8M,!-,paX|#fr {}U$+a|M{dV}ia)( KN_сGYKp R9ͲD)YYŎ(/ft`]CIrkyz8pXF9lM:'P]
+XBͦHKʁ9?f-Ҟ 'G,3Ć
+ -余ހofqL-i|u+aq 9[CJ^pa[Hg5`%X|/. ڙlQ}/=~?lڲ%Ƒ+O2^}5B6gֆL[[0*wx.oketxf w GͿ_ <-PLAۅ؞ "fJHXl: f]D ^KOg.OZ@~Z4zj/dvDz]. 6RE@5-'UZ^PsOw"ۀ9:3&{mO}~H["Z;D6,FW/a*r9H{v[18mPkM$jc458?"Hr U:;Dk\bp´h!^7_d'1<Ry5d* QW3}Qein}z,t&~7ͫ'K.UB#i?!gO1P 'ywP@|-\Q>W7SИ{9"|EY蝄~2P=E6MI^ Uw,4t"_,DVY9H8^A\(~տ_}u, XoWKwjKc
+u@'*".c62i'2Bʗ#0S/FdЋiqz :,'\7è@SyeRh
endstream
endobj
-523 0 obj
+617 0 obj
<<
/Type /FontDescriptor
-/FontName /QRFTTU+LMRoman12-Regular
+/FontName /YYNMCB+LMRoman12-Regular
/Flags 4
/FontBBox [-422 -280 1394 1127]
/Ascent 689
@@ -3784,134 +4428,118 @@ endobj
/ItalicAngle 0
/StemV 65
/XHeight 431
-/CharSet (/A/D/P/a/b/c/comma/d/e/eight/l/m/n/nine/o/one/r/s/two/w/zero)
-/FontFile 522 0 R
+/CharSet (/A/D/P/a/b/c/comma/d/e/eight/l/m/n/o/one/r/s/two/w/zero)
+/FontFile 616 0 R
>>
endobj
-524 0 obj
+618 0 obj
<<
-/Length1 2033
-/Length2 25113
+/Length1 2003
+/Length2 24612
/Length3 0
-/Length 26301
+/Length 25814
/Filter /FlateDecode
>>
stream
-xڴyUT[-
-(]B A%%Ows^Q2?[s(HDMv. ,̼
-<h $i(ߓ.">?5mp_
-`ngC9y
-MxR#-ex)P 9 ^^W/5ЮH"u%bLExO
-5i eDNͲ\\6Xk/S >ͯyaJ&:=ԉb-<>]_
-Bg]2QH&>o5L?8ENKMo$,AdbO$~Hfζdd ]ON1e%S|(& Y(rx75d&9nm _q*HhS;*'W,ܿ,%e)7^^طD+di[ gW_#Gg00æm֛Ry\+Dɯ"hM*Ho M3”ӎ]n5d 7yl`sHdk;t9L@
-WO0O=~]B
-X![S7힩a
-@iqu `h{؊1T4ͅvܘ+p-D{H$Vޖ.m45s1?/,Ss 6vj8bkU*6S8>Ͳ
-䶼'_|՘K^'Cx<6
-1zL;XfYZ>=Ë[|_TwVw}'#pJJFi.P JaT<9PIR1=􀦪x&yĨ7mf@:-]adt1#+Px.߈TfE#Ntw.цiba.r&Ha`B<mW5b$C^p'rՃa
-$zlg*3ڮne_ xޙ
-?PdU<Y 1"z<tJ;ك-8jyQX|p 3"w&W;zR VϒIe󚻌<&r[k?{vCى5vgA&4ЋV,r /:Zm},A6I-jpkx?@5/:_F4G zdF`x$Sxmҋj#ru;C %\ 
-MV/^ˢ竴NnqrTN}r5<*ۍ. 03Eeˈ6xK@; =IJHgTe0 _ hX\"ʼnPOݶV \/s5m$V
-
-Ftdv
-huB5 pX CCdHsQB<B@|M߽?MK5&e~1Vƌ݃[wKԞ***Υ@ ,cS(^dk6=wt֑KG`|\3W9@ۥ,6HqW4o]znA:ֲ-t gɫWt\rs˝"TDҷQI;s+X!98Q|nĔS;?m_~r낳EҬz6?0z6xtuű+1D̆H#S5,8Gpc#[,=
-Q0!D;MN=(N϶' rK/ $;!mei-pYǡelxYh?5NMp6GaL9dQ0Wn|L3(
-AHfy`<++oS܅Y14`l9MMe&( ޻x'!:Ĥ)Lhau«zJ8
-nf-yk(jZ_rՑ6E<h+ˮ 5'ɅDȖZQ/~*9*Uˌ ${ *(VsqSvwLsrTi3 s=1h!;$ɂ5Y~&Fv{nWܐ <dӻa">qWw/;{Bmxu8"V9qHM*TI02^Ek9\X!L٫'bKkI?닛TKiFϯ9?d'>GNXTeSdLa;0)aݧhHB"$0"QhChD-\kIأhA|̒է"A c92!  C4B"(M^]A)H&ikP9fYQi[(ٺ}HB]+}g
-LΫx(T{O P49h+]s"i D1YU{e؀DF=n%JNbY0@>-ܨ.醹kkܷߊxxܞ#<nzw*eÍ}{dG'd/F
-CفK( ¹H ' Zmt9UuOT^jÓ.n% >/
-E(hM> {$[{%zɢ+]Xp^BKIdf5,Ÿh)WgGC
-}\ 3A]XG=aMqV9jW+eB8ưRMs11/m%" (}0,9pp2OHR),U}NͮSrUdi0`E}?siQo+  }vu)2?zlhZpZ e["c/H^2RZFBN;Mཛq<h zA׷} IRHIUN"MLwF$ CiTN:en_/
-S*-|u&Q ]6˩iBW4azgg8uzk .?Xj`ا*0#N*p
-Mn\+~4_nb
-㰠T즨;S~ e7xtH(ey u9qL> N7sf29M}$Z,sX W&ƜPD$v l&8d,vX%&gPNr]Rɶ5
-x)5QR|")'zʋӰ0 i"t38AJ\1PʋH
-V\ϔ*k0k[qqix)(t]jml>pa/:BW[/pY?CMԿ`^FU񌃷?H
-oߌuR<HbFaIf>Q<ea4J5H59$6)݊_˻4P VWO[w{~M~dHΟD iN~#8/@\)N ttBC]h (oxt*rjM`/Q2ZEQƺ
-F9ARz'rp+s4"
-4㰶@ֹ0R(
-mifٔ%Խr丞 9`o.NSÏ0%[޴uAK i ^8~yA<ַ]w‹OMxA9#L&+~ ?U26_b )zô3K3"<pNF3xH 1S(9DL:v6z@) W]_B%4ڢnp>_] ~Q>nH%Ð`>ʗL4RG.!3TOf3֫^W9kࡇPnL9`gzRYLJh؊`*6?;7SH:S>$ѐ _RC5jL9ĕ
--L_{ɵ+x5{N DW?['{p s$ضpr#dw.l
-)K?_[d՘_:gtkgF+TL RSK¾dd\=Cq++~ *Mo$oP*q?'1[!Q1Ȥ7F*]A Eó o SXح[7l.6ڂֈQ{[J(ޣN0L8\_^Q0˻R 4Xt=Q;og]%*[\lhܫK5 rxCȺ4n+Q`&f֞_'hߛREs8^ZuuC-ƝD(kW @&3 aI{v-
-4C@. $TH+7yt&ě`k%4E6:e8ni {!҆>ςiX;v+Pw uB[ҋ7Ii?o]
-Yt2z=ʥu!p 6k_oW.N83}@9%(T#݃r b,bc}ԠHd Ǐ$#~k4 zVNUÕodA8J00<JjxGĭ
-Q2xk7DݦIgEnp?ri}3
-j͆b{Naosv'6ٷDI^gdg`qYЋ:E!\dҞ9ϲ^^5l˲Y址JKRoku}wex.,1IRFz2O?9f24tiڸT+y8gJ11dũMk
-UzRE,7#
-_a$[&XZ3 % fuuVƒ3S GmfB )eVgCYSa脑ӥst;B M{Mogm?)n"h(}UP@*tY=b_O<ꅯ {`Yy~[%H Mq6zQz Ӷ! d6k6+
-TTIR(Coy&_UChhZ1-7|e~s'vb:8:~L?{ISrW.Rr L:lüG'2\=C/]EaŜ)u#"fwsQoT
-csɍv nn2sll4~
-QP{TZ^Y`Ty#f S !}.?$ -.?@kxhlޏ"H@ JwU*GNYm9*"939 _WebI*UL Qŷ;w-!fDl7M:b&[J@abSAt! iC 31f|hȋk PW[A 04!Z,ZJpsI{C;LNw·vFiR>^_:~
-LuhT4o|{^/$닾2兩]RxL%uy]aP^;ؿۀ%Dh,WLLXvks_$e2XlUe48 )~/N}WxZβȣHoQh-~kahD'KQ1QfPɋ?K^KxK̏DY㪓yZPR1f{㶪5P4|śɺיWca];j@=E.ev;侥Ŏ̡o߶Q:ˎ<hŦõĔC#KCХwX(Ids_sf_Z'>IÛlŮ]BAe\XwX6b>[߰o<Cu4T (d4@$=u39ݥ@Y+>OLŧ%[?fZA~_Sqڻ<~Vާek!
-HL7Oi_U+P/-m'F)<ߚ5Dj/Ԫ:;,#TL~M3FJ35sR݆]x׮tG"ri.dɛ$UܭQBn4own@YbU}<uxi'm6~m"Q]pEm-Fp_ ׁ>,fB4lrKi ۤTZ3Kui3q7P;
-&xa֝V$IMWv
-,egqkTXI^WQy^qV~6TT{\8nh <OM6Rkh9D0\ 6#rI3Ҋ; <j#G,M3Aڠ_yj<2:؏8H0nС{ Cw@C:z]<Ie=P< 0Orð;T~0ǡF/,9$ `<"{&@iû8zԊ 5z%h"F a hء"+OG竩K ]dH3 %_1uǴUONbǰt#FlNM`AGx -Kq'$<`v{D-kg6N7O Z}%=(ɒV8KѐeϚy.
-=IvVK.&=-ƗJ",FczP,ῄ!%[8 c4!n_w234Db{RHg47 Kf]4XПxG:RLX&xS耚ఇ-Jg\bc P^9Q\M&2q?Oؑk|9KP.#s-Pzt {]VJry'D}6[o]ٲ%wl-feCٸ5Eؑ90'3| y̡窀uKӽBzZ#CWQD #g~vy?V3/FK'T͚,@sH ?_*5@$=h/A7$ᖆ}|0 WƌE8( 欳j_`QJ:Z5)f
-Jq
-#`D,/t$Pt0bREG'xۦP)" (eM>NJbTw":MEGb^RS
-R s5}S MglDdG-JzYE %J;ƾWAOcqvaR#>`h}çSvw &ʁH cϷGi-Y<Q-%)ޜ#3 B tvJu
- ~[" Eɕ }/Q(9.#zƢ\myP5 ϵP)?S+m$v= +;=L7P)_Oa>iE~ح +YUO[.`j@A-$%V;=r*WA7n>Ibdw̲
-TUCo["3?opYdo˜o*I>2!Eq_|V]$F1<N $e?24eiWZ&̙cT6WxH]gC~w;{{+K~( tflp%{ JINŇLdb>W:bؒ+J# ]LiEgluh^ kyy哛'A<s,z=iE2 f{hEdY4OYa_{RnSКEXz֖5BC!ؖQV̏
-AIm!l=W+WN<kN|q~*ɵM:|iqUXfK
-swTlO{buTGwIM'uK&(ܻ2ЅT@֘Qs- a44Eq4- 2Yݔ||(޸۹mM"ݴdʟ[\N PʒkrQş-l` ds2a6zF
-*г( g~hIw4ny]`px
-]rqRvY/^ ^^Q3қyGv~;9ڨob.[2`B)zjLK`6Dt=ӺPj!Ѫ/M}M]
-0@vm񥵚#6RC2D :Ych!$/ahbF.!
-*/x5YY,3,Fƫ׼nᶄÇ+Ϫ8M'Omx}~=q[u: FKxIgdy>4 %$,;TjAX@9 'oӠӂy\E(j
-@A91?Ol L N9v ݩ0cVt*}u.*rT}D
-5+Z%nVy¯S5p_ƽ&^@'w >۞E/y,wetB皒)aE|Nje/:Wo
-Ğ$Ɏ+2`GEv%Iv\bc]]bsG.gD貏SYY .k]OP'nJ|1PI)>FO .tv<cOUQșgH+dU+&ZmXӫGS<H͏SA|Krn  yx#j]RQ[d/yot^ $"ӛy\vX\פECt\/Xc`G! eHRoNCFl[
-^J Onb:QIUن :x5҉ʬ\:m.WP(p*
-<IS;4Qyò 9j6{f/4N7/+/d$Wdȭ?31]>W1\MùS,*Qp2h0Ȝr#k<w!Yy V|ᡟh7ap At
-C-&ʞ/z2SЕwFm N7A&)Sc|bO[HjOQ'42 m{Ku8ClR8?컝>31-F¦;=$N<N ZG+CBPqصsM)Vhvd*发a+h37x2pW sz獫Wj'Gi)8* ֗5V(焌BLZvx˅0=3i h& 8M
-եEs⭳U|\BP3 '"Cw:|,uI1h7*c*5 rڅ18R~ ,ww{CGOzU{iIJ^}ٶUP0--"_
-Ґgm'(W 'O͢ъC<ָoB m!bjV3.q펯pjqr.֣:I)bTu9^ie;FeQ2lʖ[b uy.+[B~^5pR03=wF͠ @j/WNjz?z(!{f`h2'SeM U>Zf,NِИ i8NF/h}=8Aۍ&ЎgP[ˆz7]CTt݆+_5T.~)'lMeet0u
-JCGHϐehSoXV].3Pԋ:eil6p><\w
-﹋ yׁ/
-`B='Y7]Fx˸0,ȩM^;+@S7Ж6!lB40L";oF>!˵0`G*K+(`gT .\~ܓFE2boXէݦK1TCncbncq4`@wMFh'f%d=X
-Tb?w )ɖ'xm0 1[gң3>\t:*`nt4KLxGa#a
-<drK GsVm0Ze0t_ [/׫n<jhĀ8z `9Z(54IEF%YK
-CB̢1-߽eD]z\bgQ:\2M(3NJC svˠd>{:-ka弆H%X|t5PNu젋s~?jMĩ1C_Ӆ>?)vHhCo{;_!5=0^T45e$_ůk >]%L)>kAX+N)SE o;)®QA쬸4=qQeʫ9 (-;G}R։y6mM$Fz6d{DZ\7Z8Y .쪕EPF vѦ1
-c;.$er0 sgtNcI5~}Q5fp? LƝ'$Ho N\ 3ׂ4f>ݐFa.5HJlP"V6WLy7RСi\hM+]v fXۡ3=p A0][ qZbzǭ=SUw<'lPl7>v0yHgv18Ba1ij . tKcd:NRqқzΞjW{/.4؂Vri0`^qQtpݘ5Z`[LP:X͗LKW&>B+1tHv( *-#U.<M>X9Y>K;Ɍce'mͶBnCd
-a3VT^ti[oIZ EOh2x'Nuuil$
-s
-驗,T-*=F82D/y.4%x.45.X;N/Z(Q8/11G~6wVIcϬ
-g&uZ ;ەNl`ؗ{|2U9Eؓc#+p(ϳXէK>ڕ%ؖ €'f|ٶQ ޹5tu * 0GR I"ק)RIo p% y3WR>Tc~?~S@Y5'hTg[db4Q
-j'Q< vdQ48X˦5K
-ztdfU]M5/%H)0D>:_y*N"
-j#>SUYXxOB䵑˖ 'kjؘJ,=zf 4I%;]c>4(usM \~9!c@ ^OQ\O]6ruB{3RRTso,˼an8lbqCcGG2O/ mNʗfd&Qbcoͮ ꣣b7bx_ g"<.-}fv#cN6EQcQu0`}˅lJ,! Ү-$לB5PU*9y!, ,..&.4V+ I25
-k!2pĥZsձqt+^E>֍4DQ[H2+2cSax:>M'
-FO"qOAƉ=;o<Bn`f`*?FZq-FƄo
-;RUTQKsiE)K+À2d֚fŒ
-?U6:5 PSB{rw\+q-H]aE%ۃ- P1̵4'sp/.I'8e"#1aD@C،u{NC'c6*&$+`y+lvKۭC\M Rbe{T22vi%1H_OW܉>K1(5 A}iXbZ#w@ p _'F9_ە/O@eH+lv4~ܑXN9})Î#I8)j.y$^ұႱ,Χ|vC ޾p$<wەD[ewe
-%HI& 1WC
-NC%AC#~Ι!a!h둨a T/B?:١#|S+xI*bQ4#&5!b]d{ I( o,:`VхNG,L =_M'@rDG0|=T2rqCQj`C~}0g9뵚.03nL
-ZQc'հ W6sS~؉mgKZ{bȾ
-9C F{zoev+oIoZk8RN!jճl3#w<..
-#j<p7?vPVU6pQصKXs'  )4ӟ=ī~i2A/ĠWw8ZG|,(Wogr/,0[7ٯ蚉AA6 0A.K-]Cԁ4L^X,GdUT$.ڱM7pGh[h8
-x-+3c\^( B_p`)b"Un
-͆.-[UX<XÁAIa<&gn˹ jd͝CT5d7ժ
-#{FG)9<gW b&l:^ 8D'f ʞSC<OOny#Ӫ>;=osQ+#:_ lD
-T4Ġ.[{,IkϝBq"SR[o
-5GK5{r1?@}RNaR`Te`I2j8_c8q[,% |GfdHE*Icp_ikWQPQjv軹XLu
-ˆ$$p"+).E ^с᧱H+NDT-
-N^۞SP4C~4u.rwkkjq?>vy6
-q>@֡*euu80'AgTDӝ%"['1BCIkYE|( VvUAczPqJ= `@3X`\q\ =~__-,Lum(=ޔ-^ӕ
-Q\t
-k.UaJYuZnDo(YuDct10XzJ6-e!]eeIi:Wa!>WdO^elDG7ntGu_5)x`PF½$<7P쬁4ۜ)3lï\(W9zd3]Sk(dM53jr r6 朂w񻖰&lHH4TЦQ􃅇Z‰mLI<6r3XPUAuy|8I 7W 8>h0|({ sXA
->N¸p%m%槤F:rW@!HsXG+8Ǐ,(A}w_Lhwʟ!x$ƭ04
-Irb܅dj%,'9
-zp1 V>MWA㽐+B՟Q3:RJ ODf+Grj8O%[|tEdZ|aPdW.F/"%5<'86L4z'y
-c ]sOĞ3K'9Y G`$&sO(qz8aDCĻ4ftV*Jl(cf2uD_`TnהF5>-'=-P.ȬaMşE? ^]lÔ"dXAZ_4XEIjvxb@]/V؟QSPLIXs8PNvwZ#d r=eXΛ؇bB&Ẏi"Pѡ®5݄_@H0B[(j8t2lbRc&$De@coLgm7$9r&^%wg!ItvW9 jf .( 鏓?C܌0gc&kdLqy-$Fk.zYgQ`P^ƽ(Ʉ}e׎6 P!<S< B${캙Ќ%=$+i 'c͎$&#sԾ~daG :pM$BEmߖ? ¡?Wp3Sk&=ܦ3+X2^U:g6_c1s,dg&(Aո 6DRg.2=4:EUlQK4:&^X-lS G=OkbblK ۟
-ER@uT2274p(D<Xzern~gx`R#֛ c:_2{Wi '
-o8v뛤)~?wȍ%C.@v4,*q{oJ)-DO횱-yAt7Pwa sc"ԺLBZ
+xڴsx]>ض'jl{db5IFm[McmKGckZkJ"f $ޅ '3gfTZ;ؘXX8))Ŝ.V {qc hn O ޕf
+1 (]M@{ +{ O vF?x2dMm@6V
+s+{3?7su`Vrtʈ]
+dʭmy&U]}Hpu;ˤjd[lk~zqʬI8]$Gt-z~EL4&?Ĕ&M⾝ s\0[ZɔyFӄfzaPGe1v(G!&Kں 諘f㞾IKpyMش5oɟ[T<_La~XpIۨ3W]%r[ 2~%W&nz5,[Yn|Rֈw>^ȫMX5ݫJlE"[ӡŵ3f
+v*j"Jw\<Vs赑
+bN˄g3m <UI,`trWѱT]N]͛DO&%[*qU7Ov7N//jX'!|e8hWfq\OR aد>L._L}$IÓiC7Z՚rp8@5ᣔVp%8N!.d丮 H$HT8f~FZFgەԃd'r#=xVjg$Mϕ^n}d!m8r
+7tRa[㸒fKDa{oQ7x,"@X}r- ?m<tHܻBx+9JP՚i7P!U/3W8h}նlŋt:h5kq=Y̩ܖQaCWpғ}Pχ'ZZkfί̨wty)8,g-ULAP:VHYgR'^jrפ
+MgPݺ^W;bm
+!{\3e<xXl#,
+: 1Q#C>>dny
+l(4xj5c8Qcܧ7e#4in~M))_u99G4啤mo&ɘI=\r2
+ :`_ 噜!FT XA_6|
+*n-5OOȼC=\du;VqubL}i2 V F7`?8*ߐ7JJ6:nJMPj5$kXơ/KI֏PfB3z#[a,IP"Z!kHg(+
+Q #j_<P[2b<w^Jr9;+0*Ajx1{.bXZ2]WxʨMTo3&rTrA`,JVeeBzf-v/5w {68bq`5frn|
+Q_$%RL<UCς&|\{94t`
+VH2O{I Ky@}XqRt=,$DiD34^
+g^`0qx8SAju7,!^Ŗ V`uڨ?;O lـ#2ݐ뽙3utUjb,Jq@飬L'NV'F+=8||t gpH̑{2_/T*6?G|('z}4vc_j͢\ sI¡F^ cEnAsuKkXg ?n6ٟr~AbŰC^{|ЊoH;W"y݀G`/`Ή=`[#Qwovԇ]B.phԒWX_~S>Q͚WGw>H<ˡ t7̱(Y}Nc_lݣؘ3:Y`p R83
+K9<6UDuY-Zս gdGaU%̯$|rr˃EʽuG%X(-_%Kנ4vx5?!|nц솴Ы_N:0LhY?!kj]ae3 $MhV]%ۼ|-w;%#֒VYJ/ՙ$v';4 2]
+VS%|^z3,Zr;X, OV'wŸgnw',ohoIj&D_m)Ih Z~W|gÝ9>"LA(Rw$&K#٣]YWRWN1-sV!k>_8O`XEfYJ4*۹OaP P+c*CIak*r>mKul=Ms 5U^-fڴ[wsu׃Kc,h.˧>݈L{o/?<=b˸R.`a>zE%=ФgePn-+ڏPNxZmJ4=>ez 5>7߉)0 @x8,yk;羽I +j¶G[b?yu#hW< <c꽒̺bRv#hK!aQ;s&a
+Y5tՑaM irh@`usJr#R/'WW
+n$gH/u$wհ`*hAr1Kd$l֤S1`l6l\-U}nXO"Ș|Oh0N`+5b+q]gvnH\
+Y<~K+C$2
+inPw
+uI2H:c,T2P%*Ο? -=lem$;O$+lT+VɌ_ѲfLo(BJ!KrwWٴ-0fPLĐY@S0$hw na88?<Ap]hLКY&ӵģ`^lԒͻ<^0m9".  pA{Cz#Lv1]E2Z>R`&[[Py\Dբ菐 ʆTSZ:ܞPh%~(uYߚ0p쉫xSoґHC푺14%;Q-,C<"DMx@*L; q.u)-qM+,kP:֫ކ Z*&^pkjϚ
+8M,rg{nPVQPMMh8k.VL*ҟgʨ\ui ?]"aǗ )6tXx)j- <8F#{1? (Z!10&o ge " L0=0V:Tm3OgU<Q x,(}H
+QwmƠHQ6v(EwaJz}\JP!7g%㦣Zi aV|eH~}
+XL:4yG wݒ 4ؕZ0.> @yʳ
+ XW:4ZsIi9뀐e⋲b!83y4\σ=6+FYpI!{2rqM]oP2Z wi6Rle%w[)k`x0;IJ_."ͨ0n$~kC{tNFm[h:r/!"9n1_ & H LcyAkVz8B;fx:kQc{=՘k'.<,hOApڋSTA0G+VXzop`qL$8Env` zBϵc;{9*Ts9~3M>~68j\>ziy%J%߶2
+b2?pW2X2 矝Y
+e%,yd]4gN_uGY\Ϩaptmꛜ`ETї=}0=rH+?(`/nK}KrT,` 8 ~}q*ԭ`{H {ҟݡ~I:Poy&NE<*DU@EhHi jV OcP"V\]zhFpꎵ^C _þk( ^xoEwj7Ǐ9iJ{M B<ty#-:\I~.?rK
+ !^)ZW0?[q<"wakѢ'U^٤}Cq)HՕKjC#A#Y G UЉ`nw'о&R]BC?<s#!pz"َmjވ3p f/CeM4 kQ!cQ659=9PN;r'g>U!}zsaDH%#697ڣ*F>@E`qEٳd;f~e]^JIM4 GfQof'FoZOe=E}f9>Ӹű{JtO|" kDз3yy*YI2Buߨ>GL 3!!ݿhd1%0-Θ"kb7ow8,5zop<pҊic1q\O|
+8'13fk 6TYJ P:MY Z؀#Ym=MsĔ8= 1fk!zQI)\J<! syMˋ:h0`A|~T^M
+[ oaQ'u2tPqPURrdOқhywy|G%&Ou&;ޡ~h7
+jg`d""W]-}}<cR? &AFT[(|,B(=3fRS}b^2.D=#ecYU2 A]3Us
+<{@Qqr/jࢆRT^TRYc6-[0=`a[%cWkXkFgp0sT%+/gٌw㔆q箺r`c(N+tK 9
+PEcxQnF
+ձɰEc+~:**MPY̢kRL'V,]\jo`Je)^DvVVW"}0u$4+nUdx΀jxtLj1n+^Z4JI.*ɋ䎹xu-̭$BG`%\7~|YUs+R?.݈9l}¹IAR\>O1|h)ϸ#nHO79Z/d%7bf.ֽ6boHpdI<&ݜrD=H,FIPIyО94FCG`_zWO|z22ks1ɷXu8ZC[V}1Ɗ.͐uc<PV2r6f∨={vØwOJv_| o7/L9> L<cFAY# z"'+٬SDq<RuMA}uXO%g~Ld6͖EWdK,{o|y`ܙkU^)KƂxh_Ҋ>2߭C,/=Q!q8Mr
+CC0w%hXyͷ?'!a"0 ŌZ| RQkWyc{|1)*]Zq7Avyls<|+LIZ65*O7Pe6Zk5G*SQff؈pppx<n?J1O{ J 4 bMI1C29!lN%~;pȡev"Π9d5ξ_V"zhZ4Q9@oNZGXLEezE
+\amV{ ӊZ+/4굫%$W@Bvݍ?!>uUo3Z<?JnoE-%'P ;ӦF*.wu社N\)\29صޠh3r 13ϋMm9^{e{*Ij%#Ŭ8 ZJ+}}mr]y(Uj=~o )%p+sDs5w,=ˀl SO`e8hY&De[MS.s
++]h?u;Nh9-\;ӊRlN-QJzu
+utXI5F|\ҊqX^'y6#D}M>CM$/6|'i9v㌭&t9֨e`jpyF>Ux*qAѶQ@@]ɜb6c2%g '“Jo% v]}`Rb4>>O"2G *b{皉Udt9:qTVw|Z5_Ev(?Ca>:aJ3I-V\hWG0j'pcp8ALѪƥ*>Et63YaYP[=Ռ%E>V\ꞚD %xWQaXUX !?N3KNd@*^ ڦI
+Ci%b2-g`Z |FZw볾zֶ((|RoO&JN:dEa*:[PLyXMZ=k݉b<~ơ4\(T*nuFwGqChyઈn, =^8p!>6hv'EJ6ovA>3,:'}|H jwݙoA{?X[+pEhx>@O~:0+Kf
+i`A < } +Uqb<c3IYU|''CNTzg~0ݠMKjJ5^z1:\q F?U`/
+\iVPg<[4ߥ{! ^|3|u;7mO,fFz;XV2c/ԍ\(VB6>ગ(# ]
+Gn
+iJeUP7Bɽ}
+|DdǕ WT&q=LfWC꿃?"vwjMB؝urǧϼD2٧/`/.!,~Kd"*38+)㗘J#!NcxFȅ8DF_IX,vw;a9g VRU $AQ_7
+.[Ї/Qrha>;|K_]@GES]ŽԌ%C%U}{K`; <^mA#3EܜRM
+B2Эol8LѦWpzʏYd-KSVzU7 0sw2MdR`XG%+pg<M<V:)Ԝ#ey%̝3e0 }(pq+U溔[5ٺ4um^?*W/B;*lH:R6 |?@§³D{m3KP+H#O-ܘ/2kwV&E4bm`䆀6@Y;KU0^e䚝k.=
+U~bEQ-/>ȴXZHJ5!֒',ta%H}Ծ6DjAtUK5rnh)j}zK p-lV~Z|lҴ5JZORPvdpE كySEKu&OE~fR)S״v*US+3BP9xA/y(H STV Xciwnǭ~e3uAb6l= *:g颁 )ᣌmJ7|J9ٖo&
+R%4"exncrw&ɕWn0*%kW͵q>ok=VCWj$;ɶA>ە4(nlrsX.eSjxcյ䷑\aig^ !ن~T)$39Z+䦳gewd90GƿW!)!miµ06zv2R mx$j|4f\ruzY5$!%uAs%> >\ ">Fv O]_d \BV*(WJVli e Cz(FR6~
+ 7[Ee A c:kVQv.iKϛ%gr63!]!]Mw?:P@.v|LkSCTFPTBD[rLN`,>\bkihMѫ4ίAAg&C
+XOVBU,ϢE~m<FsX2.Ãբx`[)5"׬E>xxS995O;luI9r/HaJ``f p L<F7\:Fo>࿄}5Ϸ8kWn[U50̼uxvwOYZk7k aD6Ip;R}HzHdDV9?*͝7DbK點6zDB.:Vt=l5%2›!bjZi_<żz>Q\/-֞kBdٌY kƉui~ V̓r \_Z&bwEwoN~PPv~ uɛ; \> zg wX˾y)F/oe g U?mh<T#c?5]%<evq$y\}^`d!%a<0<bո+*َb8~
+7Ͽ ΃ۺ(a '2w6\hX ;/raZo&y`+R ^H
+R=[c^捄ݞdsߔԱ
+?@nۆՈt}jO'b놐QoѦgW;w,g ;F KD
+a-:Q=:&ݡ>OU=cpˤI h#
+x _R//j ~PC_'NROc\,ARn: ?V~#5eDX%@qW2ij}6m!OE]F&Y}alPrƋ*NPi$LC3%qR뷦!PD~A F :CA*4j2E)yYQl۳o95W
+/z}<MS
+zLHq*!Zuo)F4;lx:O OrVQ_Gs<>B/WI=!0Gh綂1!o XLt Fitt6/]
+~09gG}[[+ <NO3 r[!==֑j7$xkYR|PA^ϕd',܀e|&>.#geF?]Raz\C4'p
+5i]z *!lV3X /`H<۲O))FkqoRܑKMT'7_'N
+4vlS7q<' \RfsMNp:dmRrغ7!ZگMJ0c2)$c]\@*w DaXR*DR$W&yCdY%$k` L2>'"J3+z?y%-DT[2ѝyM.
+ddY`ϽI1RQtB풪#`lkd~Okn;,R+ pn ;W3ޡ%y>Iʶa$冱 Fb;EEtvP>?щTO%X@^T^P?;5"vu;pt_z>n\
++[>ne[B5js
+ I(bӎf0BZ*B>2A"QSlXH
+
+6qI\UP K9S-}skpB) GK&N'Ujy挩[t(m2D?pȗҨq,"_K&1ŧѵG ~x5VPOAo{!QG̨SƷr fc3j_'[ՙۨ6ebݦA 5q Vʶ{\oGcJX/^ YFzuu}ΔOTo|aw"48/
+ϸrhہ^A+hԢDkfeAN7#?=F~v w'𷄚. r'3m
++QrE/¤I]
+k6aLz uPaLjCSnGcWwӯR)b`-VܼcpAKYey®TXO8hmnͦL[R:X¯s5,o4N]}<R,-y+KQֈ=\ߞnrdr,^Cbw,b7z2Vpf:S^Z`E-,ۼ=H(On¡YuM/޻?E-Nv/]bj{, T gy#U܌g_ $F!~1(DkI!G5y)VKrҊک75]RH&bXWp3PL rD IF3[K}gM Wm"{TGX[~PRpJ;ٖc𗢐x2egt,/CE_J[gCƇ-d5BRo,t&99c7Qacʲ8I \O9iq:bZ~0@it,vCvSNOϠQ'BJx7;ghh5Ѳ*[Wt77XXYGEg+xb#uZ?*| 9)WJ0 "#*O&ޥ7Λ
+W+Ʒ _0fAs) K?]IWr ֞ ~b>իc ul_l [#\T>=/NvaG(\k2iaԹLF#ؚ ĔHjRcl dY<Ur
+3o; A5r/1'.}Oiz태[xl$Xy{MQuNdӆi5 QA(͝4TaH@6X"A7D3!
+: 뙠_4$v Hm<ve
+f 6oU葅OōC;[id:,Ѻ&; Yr1#iQlp;:-&#5/AmS L܁rևa\tQ
+>GC9Qt9.ϙS2RH[e9/R7Z~
+B^@q]:w2"63GuAN|{&yA1C`sY2@tv/p}NS[c7xںr
+W7
+aV+H &#V_a/('_ Tќ5.(vߢt൫CE)C<i6 e& Ւ|ꮤGt 65V
+"BԑVLʫfNcNCf4zF!87PE5d?1/xyqv"gqZ4s'Ȓ7o@Mf
+zr p3i},]hϥ1SPg2X?òˣf^#&Bi&"b7Tv1z0w6ÃabȎcƭ +"-VYc.:Vzߺ
+Xހ2r'ژ325Wxf[ meKޞI wl$ گbT>0kQz6,> {yXּ#K]()e5_٩m| l8%p|e'ԅF^),p*TVIR&芣QYjZ0\y{tS
+Ny(%u qMz3OIn@m[ s.\!zg|=3Bc{ꍞ:Tr&H4m'ړT޸T"-# ͗#wxx6a
+TJrdlC-64
+Fa(Г7u7
+txD# M_ya"p[t PiNnPd$ ȉpJθ)̬ΓK܆%ç-r(P|wc]~GnbGi}r0=
+Y򧸟k@)ZU[3o"B흛RA=" =OYo$˜!$fh΢[fΚ+Pެ]ѢJCeOH۷Q,%޻L$l7OK^s*;Uh Rgç']+<\=>*k
+aD"EZ/WE*Csߝ ayod?[˄G/Z +v`?'ʈWw*ғ m/ g:) ,߾&=ҥLD$D/>:O)
+GIwNJE!Foɣ~<['GМ Ydaг_E~Mo
+Bs ő^O$LD@AUT7=h_ߙPtՊ$yarMn2Sj#H-O绂f*۔:V[I%5l;k*1ZrB0
+U v&?QCY{h[N)&J5R
+d6 ?>0ackMr>ϖ-re8'T>\b:!r|?>`l؄VRF+Bcm4[u6H"j&Y9"wIJ#[ PΟzl2k?zօx/M M]WL*G'g? R
endstream
endobj
-525 0 obj
+619 0 obj
<<
/Type /FontDescriptor
-/FontName /DOSTYO+LMRoman17-Regular
+/FontName /OOKGAG+LMRoman17-Regular
/Flags 4
/FontBBox [-400 -286 1338 1125]
/Ascent 683
@@ -3920,11 +4548,11 @@ endobj
/ItalicAngle 0
/StemV 18
/XHeight 430
-/CharSet (/E/L/T/V/X/a/c/d/e/f/ff/ffi/g/h/i/k/l/n/o/p/period/r/s/t/three/two/v/w/y)
-/FontFile 524 0 R
+/CharSet (/E/L/T/V/X/a/c/d/e/f/ff/ffi/four/g/h/i/k/l/n/o/p/period/r/s/t/w/zero)
+/FontFile 618 0 R
>>
endobj
-526 0 obj
+620 0 obj
<<
/Length1 1669
/Length2 16869
@@ -4004,7 +4632,7 @@ e{cpͮNG8";uf/%zyΨfoygXZ=oBQgꉵYF9
[H+]g^?/'mIx~N, =;Rc Gg9FpTP ;G Wj̚꿸hnzzpMQ5){zҔ=K?
endstream
endobj
-527 0 obj
+621 0 obj
<<
/Type /FontDescriptor
/FontName /PSSDWM+LMRoman5-Regular
@@ -4017,103 +4645,119 @@ endobj
/StemV 106
/XHeight 431
/CharSet (/one/two/zero)
-/FontFile 526 0 R
+/FontFile 620 0 R
>>
endobj
-528 0 obj
+622 0 obj
<<
-/Length1 1770
-/Length2 21181
+/Length1 1804
+/Length2 21579
/Length3 0
-/Length 22228
+/Length 22700
/Filter /FlateDecode
>>
stream
-xڴst]>ƶ9m۶1I&ac4mv y~k58y8̬5*ꌢ掦 )G7FV&>=ЁQ dnt1pSRn֎@7
-l O 9\>
-
-2V@bTT
-0x̩  \.qgv@1߶2
-|
-
-P\h11G/_FNVN
-j5}ݒUd5yAzj2 L߾O4Ca*M!ٱj1¢ԛiۣ=M%ڗl;DfoP~f?xǮin\3#[<d9H:{bCG\t
-G}FZ,ke=!."9r]>5p]O@N߁W$=/Yo=ub}\ *R'* ѧq+
-6f5~e(AYJY~628 s&%qřC^Dn0{,/鑶y
-ѹN>t6e9xź3./ [O<̣{ЇROŇ0:TvW׆*qA ABWYK[?:(,*xɆZξc*%%J^Zv=Ls6 3 ?=
-(
-;&ԟ^w҃fIMǷJl<80 J e[B*T&[Li,(tcX:KE&V:~xbOG o$s4"4)nrܕX5=Bc,7lC>OH|Ѽ`0m{իojWWZBޝ67.c+%+IhW}Zh.NNvP`ke8,G?pr煩7S:`76&g<tF’hZYH0}|Y \|j<[oFm+t:Λ$O[y;e܃Dq8p擛q½K0wvk$g%<{[zhba(U FϙuĚYDZ
-?&4ŁRߖ7zEN9>dSCxXk5ӥWӬŔZ7#G4K;'~ڷXzWs43k-rdMy\``LO:>#Nv0?L'qr/J=qͼl=OWD3K"cƨSwޛk ǚ+.b=5/L^k_1iǕ鬧L[oHL =?_K׊U} SD%&x}A2?i_ ܥEz߽J &-@l$s'%P>ys2ڑ11zPg]|Uq83vڛG9h^ءPjϺ1X9n)0qn\dԉ@-n(+ JDcQD)dx1e0Y`h8̴o^jO)7 (T%;ѣ#cfڏj&JB.d
-di*V4+8}xM^@`oxM5ʵQfVxE4Wq9,ƹKL_v
-?cPT'7XElJ-8)*#T>.P9$ϋW^rbȩY ZQ̙;t[Aqy
-r:v
-/>>8Dk⼴Y~ηs]SDA |xWhgu5Q)2sY|:cSy'Cj@HjB65bnjA.Μs0LIӋ0N0#Fz1-&c#f]!F1>Dfuztu%1
-])ft# +k#z$Z ¼S1W$)TZELfm::xյ9_яp%^ej%"&q҃8.^H3nϿ;
-$U»[0|2F*D~(r{{yˇ>cd=)h١Ce5|KoL2*.-ۇV@šƊKfKW[1 HDs,bs(yîpwt9/ױ1K@a/ykvcN)ABҚT'9$}SJIVeتJ\;pz$0Cd+iѧW2ƹyDN%XiCE4|akUsSmz$Jxec*7cm}kذIZ܌RU 8W؜XeV6[
-x? njz&&(}(5BHY|3 سTTOvJ,f=Nmg4e!'or&? [)NpϽ2iwCQ,bȬ;?13J k<<r/@֊__tZ^=5\kS*6( =$ebFi~ڞEK.hHy=c
-?̸NbF,S_ 8q?̋ZIקYL[dzؕ1bJhʱ\Y`,'B''lEA4бl 0T_on<qd":33<ȰGj~k-U|XM8耚MtAvfm,4uSнI v*ef[)}Yh 3X:*Ɔ>/,xl)^Lw-/.8l3.jù3BJ x@Yi+R[PcCfןσ(]?!%oBYu᠉r) #H̟}=7%QÐyA)R9dwͥ\)CưSBA(†Ґ~e|$mw_TYFY47Wِ_հX|B$U 4$k?mԁro6RO_g8E^gm%GG$Aro>{T͖Oչ IT#,؏dAغG Nd8jvH<0}SyWVfWA}$E|wMTEҷ2?U{`9;/5zt0JRʀ=rfS1T
-+ێ+ܳ^H i
-ٛ-_%<l^V
-Rk,qb~qW5'X l9F}p;K;p-X=? l>*u:B՟4Ib2M$k_yٙrIDB`u"CxʌQn^fn^<;}m4UsVϦfb,/Q>`G&|s
-Zv0
-],) *2x6PnҚHfQ.t9
-H.P*Q^}Fz&T<oV~De^\E|LvzyzS&spG__\I;vo'QT4?-s'Z?n{
-Jȥh ϑ+6.J=x(:Aڅ+˺1X3J@M$Tq4ˬ|R%{K7G詏s;776z8m_3]~`6<Vux #ͷV4 wxF%#cUE4:?huFt]hl:|2XW+AU-G &A ~wVx&x9׿N7bvIFRZfy +Q9F;滱|BjD()_z5/WᎱ<ADcY:KKaUd=_ 56B͵(欅[QELH7`,Kw!p?y=~Sadu:@DEn<ޭ/~]nߵ !l. oq_
-0ǫ2t2LgM.ns@XWCrs{C/^ )'*c}6/ʳJhPaN= C %{{MeBJ !I3NJLJ85N}D`W'
-ѡȢ$d ˟yt  qq߉8F0"f*MrT({>M}eg$:*
-aRE[PuwR' K=1Gb VbP` %U1Et㬧q 4r~Q:PV)ꎵx(˶Vt}#gnWK6:=_ϼ_@F$6u7y nǗɝI ppL3S?DTcHW4"3o,LMr؉$k9¶M<%hS5 ڶn
- +V:3+:8Z;M^tԕU]['\60 \&`M m☽RVhieU!?,^He8?U*!(bz vжm)w]
-­g,YҜ4Eh|@^pG5uuwh~CyliMIoߩ˘?}MIo(M/i3ۄ-{0n iQgm?<ǡ܉׍bPB}?-ϑQՂ"ܴ5qj߾"nlES[r
-|-nU_,r6Ih?>-kcG>s|jilP>OMt 6}$TLORqkn.F,֨k)30>|쀉b/\
-d,+T&lx~ Ƿ@RDxu]5| Nhs MR<¥z#V]6q0$/>fhnmMdxؖ+= .T"A'x"c7
-zSֻQG h9QY$$“Ю8'ej9/a0ef5-*<YmY
-*{Ja=7ʽ&v% B^?*оh:n(Yg^`vIch03N=-y:F]ݪwJԵ"zF< To<@Yv[rd( ~@8䂤fδgElQaMN¦\A}q9d}q7c삤=xAļZztDuH
-n1xxG~2I/1őֺLRUǦ襇.~R)&OqvK#b1ckw(Li=Δ]u 5$gA͘,!$X:d{{; x ]Ev+bi
-{,;a ,whD{(-F ]JhxMtW$[oz^H;+k2|V 7.sBbsy+|wU,&o1P3\=ƗSֽ$5qB<YJb ="0Zc/\s,/o.`en'Wv֡_ۨo+bd$.iBC{XmP5)ψ o}}nuqͭP5ڛ><&raҭPƋv~
-e9w/EE
-AS}Yz+N-xIpПҹCLU
-pE[_]n^R;$Yi,1Kkґux1 `nfH=MR{q_"]tzC P*ݑE[S;I5,ػG;
-5pZc;<h#i
-CGܛʔ_8e^V1^dD?рQ=-W7gB vezy?s!d
-/dpSG~ ?{ nQHuk4WOAoP`&vTGb_8>sZ/0H>zӸ~Y$ڟ7xf=
-g+΍[/<W(r:ʶSi#ނn5zciAKeˇCen)qtWǡQp)Ro5S,B|["=0|5؞oC^wul3BMpdSG|3O3B6Sm( ci<y$^ܮy5>/4,ڻǍNܵn=zl}4f=FD; <{0*u
-W $&; JL5.-1 gVTEaqrTd?4[9Tq<ʉ'˹
-@*U;o;F3h޻*Daz:^he˲5'(טG*IV1
-,7fO6(cX(W01"&&;~&Th#]egYNwG/nͫHJd\ ;
-j?m<jeJB2ZĎ lQiOtM#CH %"cZpxJpM"PO$Ҟp3V
-Hmz7k.j0s3m/f
-My}UYS4& cقi3 |[F)ŧa =|Du^n28tat) SkSy25p(3.wp9%S<:
-۹в&t͵ n~QAr1C{!s*Fg F4Z~'zV)Y5{Eel/ I59_^-?>3M1N1|jŽ'Ym?-' ?%}3ӿiU7Ъ\Waʅ7n$EV&V|J=iֈ"D%
-ezmbgd3ZKff#s4p9/NԶ!RGs<T~oD*c|UΤdJcPy^*EB
-(7&fךf|l%ȣf?m՛-2Ìb8,듰[:O^͟8qy>S,v̯S@0 rUvkb ؤ?`Q7W]6=&hP vRf|hyt6$V*%E[{!?')5zC0훍Jx
-<v<Xi{qQ]6kUW*< 64û9q7!X\(rDI~$<W#LDlB[)OLILXz9 ->gW`SvXh~d&&/@<+J*x }b>z@`(7^V*#>p
-YWԐ1[-Igf8gT9d&/qkˏHaܗA>D^
-F/ <3i.=5nhs98>$ؤ_S]pJ01N>n*k Cpg@/񾥮~eͶG9 \t%7 wx O>!/f>)|`!cT^ nɦ$0Z;I~{3TFnE/6h`{шAHm$7t3n:2 %?ҒeZX
-c2~]U.kzReZ:rd@VzFfёOFUDԈbuTؚ~C1
-/&؟WOYzyaRviWŲB)Jnv'껲ٽ;X}ԏe4,F aztrpO*⌲[c8>\6M's%qRMTIyŗW
-aB71>#2Vͫ?E?0^U2 djEeWlMܡax0kDTyc$2iE S9;319TsV\1,_ῘyծUO!7KѯmJ
-.3>N^f7}}B y IJ87.iy
-RW% ֑^RR v {I,CbF5ӔCYwRx 'W,Ϭnڧdi.&qIك f֙31Aab+.5'rU[׹[h
-'mvcvW|5_<hierDžLq_2[SX3VWlm掞͢^=d ^祶"s*A0O 8V?U $TR"I٩ZU)o@g38}:/Ւzu)cjLQdsGo=7hI:x-Z>1˶TK^VcD"Q8P"1tc޹<c-[۴ccTh^b_ڰ;&ƛq%T+ۃm[N
-V=ͦo֤~X'b#{%~Ou'CG.}:$evTC,1ѯQ)*,S`-?%ھ3)< Md?h#y̡0\&]0 pVU]6$g>I۫nj.@ʒ-:%w'{|nK*Lu1l m/v f/h&I
-kF'
-͌#@8zqj3s]NjCaUh<Mt7عb^@_8HICQ?
-+`BB*l!ivVȀ#Qtϥ?n|O Nrlun&scO6OٕMuf\Zy幈F"W=.]a_;כ]НlVɽikS$l?')!{t<n;UPу_ cz\~Tg kI;Fz~syM626ikSͯݾ=ۻv
-O㾥?$&iVNS^CFPt>5úz1 Z Hp<y"(1z\nۓxW'R-[3ŸŽ!g8d-}{Uuyߺq;Un4W9Or=ŏ=ob$E+u.7<v欴;gb(BJ2s>~o<C c˷cV)(Emھ3ɍ&-a6K]ηYv.-Jz273fQE8b 6 **gCZ47pL7$HLr¥L{π3>l|2D +#xc+8# 'U=h6yP2ۙn*2\SWbQrp ҂ĉ 7ZG
-܋~?q폰')Ÿ'O-\E5"mSK<zGM
-r r:KupAa5pj]։QC%QtdB<NS({/A2
-uQ#+E>^ϣ޸U]+p miBL(3Jti>X"ZKʝ)Syt72!! mM 1v8Kۘ6V29/zJ!P:5RvX  "V0n'Zs`-П do$<^mشm%6T7@(!(
-J\{$r,}~,`_c/-NibT}VHIդ~.@ք)"| .%g^T/cPSZw:AG9FUL4v^d5 pS% /zM?~iVüb'Q:VC^UJĄRs$FWm:i,RAX5{C߬QBWB<<)#zTewME v\і27BiT^Y
-Ia{g^`maK%?{gTWFrVTf2EOoj롽bƮ](wV_7iSqW'I6f8rҶ?=0T}I4+۽KrqvtL∲{zEW} Z .Ի:_xgpqX'`E?JYJnم/N TFO7+B^̗z)`X &,#dTp=w9:9=kkQǎe:mLHYgs‰sd1izҍTч"Ԯhh< s e*hi~d=~I
-+KJ3cwm'p5kO\2x!ИDLeaC<<K&8d.[IeJ 74T}rH^'1䨑NY~S~)&uy HF{ 䞃fz-`Gi(vUN> 揺9 &
-_*Z~&$ 'EyiZ-Vj"{۫ b,@j4}^.mc-0˫!u(3vdq(.J]]V8vIƘ<(8#s\yenв:{Z*k?޸ɋ
-ߖ>je<>hK"fGLpEw4d%\Zx
+xڴeX\ͺ-$Ӹkp 4\Cpw܂ݹ[g:}]5zΦ QRa63I:302l 3k#Bt:x\
+$a4y
+vn`2ZL M
+@RYQMI#ETEUM &*
+vX>.p^N@W s00vf'_G'e?g|R;[k IC%bm
+aa\Ύ:e?^Mo""v^ ,
+gX0P&1b{i BFd;+Ѿd>Mb"k w /T?c` Blr#= f#Is&1AfajƱb&.3E4׃b;o(S a%Tha{9a3c0($7D+C $RgɻQû,1'c}Xh^!\eTKW+;ZEcHKИSLRb?f
+P7_xQaU3H͈TF:Ϻxf_wǺ
+4",XN|W:+1PJ`5INrM;a =;}Rɱyh:,B%[j?bWNb3F͔8oY2hf8}濈0 'ѳq< G*/.@F>ߥ=r{e5mLE$pP#ԔE؍ģmw1VUSZ)l ݌VniiVC
+@ aгk#J],ʏȡՊdl(B^{5sOZbwgnt~@B=1.f|_(2T+!ily \V:F_ 8Ӎ7g1B}?JL5͍36;/L:X_'gZG0Ptd=!;lXe<6b9'Kœ7OaLt rE5JI$=ŀ8gqгk1X}ȶ [or<e1L[EMޢ.V +l]FuZcrqH*z尮b=i&a͹4߱_%'݋N ɢ@T=[e~X#
+'Pϼiwd\-Ѿ/Q7a`"vRy qѐh
+/OyT"xYWvP- hE|&A5(c:(ɟSVk!$fvy!yQ~QFODjme~$8TA9Uj]zhK:I|o-֫tg(U^W:>z#JlS9UJ U,Q
+D/˾94Q TT;#jE#Է /̻ $"H} #'7,Y)ѝ_6ң{9@`(_mF:F槎ǿq]c5h׼Y9Y+N IFLEKH#.fKxQfzJ3S4q&X34 Vz0]xk}nT{M4a ~N
+~
+3`6B<HX5 f47]1
+ PqW\.Zjӳ.`Ic# Qc;bH)u%'>s9 ulU#E?hfnD$ tʜdaU_"rsp\- WI{@oyAcF$f^gfnr~wKeP AZh}rmEK>4>:ICbz(ט AW&Q\{2'틀y)ŎrnW |
+xwrhaѝZnlEб/7}߈C4bv;]Xηo)U7XMH\rdJ/֝r<?Td<| 񷫺$f^rJaB(:(nOCq͏n󔳗tbB?hq{ChQo4Mȡ
+̹oQ ~ۺHC:#d/x]D'͇(,L^tpOOpKpֶ)Û㏣}A$6sE@Bb
+ɑXPlbJMCzbPbW)PoXئQD&t3dz&b1cF]eͬIt_
+
+UY.bNuӼI$3[+=R P @LQƮC } =VP1`P;B:Nw.3)Rg`XW O+x i#IaGjr~2p/#-+{w߀4
+%inج2)FhAP`|U'K "crAGie1Y4É/3dmb7yTvRdDJ~ee;r|A޿8Z}83T*^ͭL?U97KQ$J6C ;&8b@d'o/@ ™U+K=d I?<nK'pV\7Vz ad)peFӛ& pe^m ~)sIS<
+!߀437ڀU8D4BK
+ ) vbIq"%<kM~Ls9EExD|gBdJ_(2f["=)Է#V*3M
+ Cx 5a9ڰ'~҇E .xe*92aRS\p]_pS.r\1ʌOqָT AbP4b.;xɬcye ; gl !ua[#+S&TIK|YX“NOs;5u\;E1xYQ`|%;>ldXx*#}a9&~zWUPڧzQ g0ſbYK ^<zmĜ:+O}܀kNҞ|RYi};EtӃqҿ =ܲ]BOC!n%`#tHd8R+lTEOS(̞~.; y;fuW!]Bh~H};*(!SSrO8nOU57B4 V9p^@?La^2S`"RG'4<\!!3x"ÙEzʵ3|~̵L`~#r-#7҅D`.!8| ojht9lILXi!D!ࡈ B4e!LJkyJW3X^m Ԃ=F0- ez]!jx6_V~L)q=i_'ϵw4'a$X
+Tl"hf[%rjf!~7!MnDZ ;~߉a:6DY2`gbn NX{tr,r,KxhR"}ke )_/I=$0x8k
+aJAӬڵYz׻3+y֨&: 4}@QQÓPƯ|Odo9~?*H追ڭ[o<\v*YE3RL>m!nG5]8zBidr|;
+ڦg
+d[/ +D]ay'z.iy+n]ߔj|n-ĉbeh9f&x73Ϙ4 [P?Y
+ND
+cK c#׼̞B ̬H}H uR** O}ǵ6.gS$$?ij7eЋ"Fmm2GϵĎF1!֣7u^^yuYs6W@ظ^wr99ĀHYdӛͰgif+ ~Kq{
+W¾T Q(1pZ;˗FO^%5Wo},
+@qMRUJI,c,~]lȎ"_SF\yboxM}[I,up t*΅;1ߦ0>A $T[˵ZPp5?5Tg 34bZ_ ?H\e%9 }BöqouBI7A:_E=Ym.YR!R:/r<)۴)Ukl~ʨnYjъo>$Ɋ3XF2q p,cRiX8& 틢-
+Pϓ/M8 dX眂w?Y"AF3;}+rq?_|Ac\X_r͒[+s9+&r J-ͅ)*Hba[:GL}"duk4~^G?(,$$
+vз_MTN H N$R꥿#-^%Sʐtko8 ئ]6,(f@. v[cbMg0ćCi@HTe3 [{i.8
+7Ku1&v*׋/^]FNy8Hc莈4x5~$OǏpNJA?p.;c=}rWԔ^: 8G;x<#ycɌd!\9{>=~R1 Q/:{Vs*͜w󲙀V;L}*u[
+̲vx?`qӊ~7u5[ʧT2֙P}cM1Vo%Dz7, n ߭@YtfDq 8:G_J '1N"ؘ$
+O ->$q:Udcm[R,[#Gr/w~@,Saߘ!RC/jĕ"& X1YF942#ǿ 'nWBpZ3(|:-,R:$_R-dٔ;[̉V=
+#\lTw2f zj9KoE8 hcx#,yR!7vT^"u9fǭp<^3{—"\T?1
+'ĺC27~+yJLmXF?s?inP/5v(ԧV+Ͷy4ÝF}zwGߛ[>+c뷡3 w
+%K]:6cKԎ \Z*:r4=|ݘ O#8E@3h*`q=يAwfПWb?=szJWV@ֲNDެ% * ^>h8
+ hTJ+7evPNeia,ܝ؍P*
+ cT35Rz3^ZD'HS
+up
+ Fv%j&W0Z˘F7?>I& Iky1e*Y0. LmibA0|AP|rGHJ'8ff)+q~Pz=cRB`5}JܮKa<@(rɀ1oǫ*Եjf^yJQo cc`-EVD3AFVNlXKEuq5bٌ9Xr͂Dl+[W7> |]3w̭pn*V=BKB=Pʷ<h{m">OJ[ia@hp `&A΁-bixjoYӪ5gv 4)|TB{p>Fvl33=~\FbƟxWUߝ O j}5WYdQ:Pq4fEጼ&g ^= .TXSh'IhSw+iB:0X[n̐xwe1mGuykHuo & O)H!Y(=IJH,
+bcz rdnK`/ۊLX x+,ŝL4Gk=A(F wE>;[t8_ٔIU^tpJ` nXEi NZ8a8#W<OPCf΁Grd$;Kh cѾ:ܿ~ߨ2n7V:$T-xhǑ;Lc'dC:5uCHI[D3^h 'e:UZV0%V|H) {YBsӈYlF- ӦPIM% 6s
+*T%026tjy*:it /y<E
+ !& "H},3&Io'a.>Aek^zPee?-lr£);Paw̭teln[r.!B1(6Oy
+9.Hfx,nJD}H Z IΗ5[yn~BMO=<Z:"qP\rV`1lBOP
+ǁs R3RJ^s}iL5֥.O'ld mٸ/"?k/ev~¯_ ʵ+z4oDDx5>"ã4QI ~S5M_Ãpr[7嚼ao6\9 V_ɲ) -e<KB̒X.#M/hz/+Tg,BI$P+Ӆk'Oj<آkgE#?빮sT \t Wn?K?TIήWŽ7|in6+Ec+hը(ŢCݒƲTlHϘ0X X+.at:2Y:L$A]z_W@A_fHNԤ"گe wb<0tH+"$][G;u~c_vP()]< qAͦI?hBS*c>W2 #$2}3g3s_,ExOo&7q,ZVQ-4ZurRŏymh-m#|:VJűʚN!''HN,I8ov*Yw]m79x^mP % PPy,3~FE쉾MZg%E.I`X@kw
+x!zC ϣ0@Fak 6R" 5h1A'R$>\6=:%n`
+ NZ wl '`7etB.x8$[8mH
+B6|rVgf+L
+>9_W5.$gA56s[m;#'}lWvh&ب9:#V֩w*rҫ ;!l%{jaLe#IW
+P7'ő<h'OdmA4m& mW_{ˈJtXߋUdCD94
+88,Sɓ?bd?QKH4* }wZw5$FSop 5_ѯM8鷁sTvhxdOgބTct:|+Js{x> <m=V@ʝwZc2AKX5t
+ uXK:J
+S/5*RT=kV 2@L1ZKo/b(B/B-h?|K N_w3خeg(=hѡ GmNb)Wsc2D36o&n;]n;j<HV1ec3Ơae?彵h&TKOrGZ*Lfyo>~ߚhst8?/5BN 4̆1U fl~J"1=J쑞5|!i WN&쮿ML`s=Gӛ$X\g'!nvYZQbAvXb.*<}&ǣ!37|c",?e:ݬF͙}hmsi tjg= ̣Za
+C;1]
+Gr}{J+4CccN'LD0qidi4( ZB{A #%y[
+bdۍ1R
+˙LtFRzlUd5OH{kȋNbj"0u(?7KG[BiQq^߬JD&yv.3{W)5\ G8 tL+?I]V3KQƙDG`H"Xxr@)<=-qXsb%f@a> LjKWfGZwT.#Y~ HY vxfҳxupl,Ւa,G6Hlsh"v<=o(9ȏo,4mi?lb7EOg0~9&g;GvW),yD[k" y96 ;$֖|M$8wG`֍H}Nl&0%ڼf;ޠ.U2E?Leeqj13
+챯N~{ԑZH/hRc'$`axUvg%QiD&<0ٌܑU -9t/<Y.)ث{"eMSϡNڦ P~3.]\n4YQe0kA dε?DϗF_uA缿بRS{Pzzu~fLnT:j?U[FByt|ݠ>)bV5b)!~N9QR
+~z{j7=2! SNJ=NH5h&'@NA _{S0II!JJEBQZA{!4r5A˻~s 6"z϶a[}ƺ\]V^qae 7q*aPdu䇴l6PӉnUwxݑ\7\OlVBhƔRs~ܱ'T9d8i>&;]CVRWkꎛۧ^,mlH
+^Oh65L&7&}68_d1 7YHO+ۯ׺\$l<2H<*'FܟF#:EUx%~'u Hyb?Hk)YUש\*Ҿz;vOr
+x6~ 6E
+bX'dSzIt7$fHlۈi.>h =T4;`!,FƮˆSm6BȪiyVq.9'{JȌ0+80^:|T "wT_aFKި-(ldrsfz^_ִ.DGi8\!/dIY=%R?S(Z[ۓKZU@/ R&:$]Zrg/voa7yy'BPȻj[͘+phu_vǗD*4&6j_{!t8bvM0$h kL%a!y]*K>? q ܞ,Q~7fF
+A\xnW@mN0R{M^kȀitʊ`R:2U&(W39Wɪic햴;z hq_x=5\  /ܵg' 2 ?4:@KM,^lg:sB I9u/Ut!Ʒv'fD*Z5 / VG(w׶G&807򂻹nwX8#i*cю܄Ii2?K]-B'q/]y46+DFIY]c ﵯxb$U@]WS6Gk9 .Ť7ČZag2|ig
+A+^ǧ!
+]H{L^A|1jUbߩ*۷>'C_l򅄋[gcI|EUSms\C= bGA`,1xȁɵsף',cd2 B9eFX@ͨ{<v9$t60SnA$L[8PN;62nΡx9#iuFp7n\nk0SQe(ݬbzLWR0w ㉴*ӞKLtm:);x٠v}'*<m!d[8lun;,Pyd̷qMonZν ߻ q;X:6*q vV*sImtw
+7vj Wa~bA*
+;рe$O|)\ 8ߩji<ܫOU͙Z8V[%#L lkyۛ7%Nk?̭匌߲npBH";NCݨg7T_lBY|"aM[٘F2Y]c8No:X8VL2neqJ34qr LSNcCu067<:?>ڃ-kxh5`_CW7 h$Y0~bϨa虎(/95u9]S+P^5:nLٰX6xD&݊a |\։'/+?_mf-W≮ T;:M>JQۜ'=c!4ucN!jZ7;TWFn(:
+ V`+s#bC
+Ҏv*""uE&]mֻu7S ﴦzpwY(parN[-vܘxoU2q t04Mj܂=^g9ΝՊtIkW*"r1.@CG~Hv#GA%kghi6)wD'F\XVÑAI ޓJY{9|(8v>XOnf Q~A
+J9_3Fh澎s Pɮ?´?d33xQ*~=k)qSs*jD 1E!U_E}T2L`tr
+/I\B2Pť^6sX_ WS9"vbX/k06 d~vXRji+7̛IOV^XrH0Fe!<JQ"mk<sVvZp0'pjG4,[35 j=W궘Ekvȃ|OL,G2Ϟ#}@N
+'3Km&Ugא
+P2$~Cxݚz{/;˟ۍTsՊ5{ *_crc>C_V}LXg9F^l ؗ wxsblv誗&.5`r'C*ŅFk6,8uljϦPvvTlsw"ԙ0Π g>dXv
+tϜ-y5!]qsy)&W
+HD';}\".:U4*$b;ن 2 5g3UAX6_SpBAѲf3h{4,3fDq#\CIV{{!Z"+8=i w%s8=b%ԉRBe<$ݚb4F/D qN?^97
+F3X)9'1蓕"1_ F ՠ wrB$6JUco+pPdDW~`k)+VSH'Tdsϋ
+kh>
+$V%Hx(L)U;)Dcz2K?q
+((Yd@OjpH,SY5-JOTLsJ8hB7U{CoPv9D}'Q&6B]:V+b3zFՍ~K\7yh6&r!w ;[D )\ͫ@XaL}-Rj6bOC`vلKG#Tuf ߟ_qu8)1) e aτ.4JW
+fR֣8FG0p]KuLm` m1 iV+dhNP"b[ѯg\ gF6[j!$W"X%
+4CiH(_z#2l3"v"qiR|fY?樴40{idE`Bgxs@pqfGu2y@ͿlOzA(_,@iyq6d`LBnn_" =%i- ë?_˾(
+>6?#qyk.RLzW^dsN hZ<TWY
+n1c_yF4rkScLէ?m?b".i C,AS^POJqP2q ˠE `\6phC;qCA'Nc@HE\229-1z>
+ m}7n.eN!T"Ɖs
+ǕךĸՔ] 5!hŪ?`Qsay+lH@:WA[2` @sG]tW\6w7-cJOࣧPNJFibLE:o
+='eKR5ռ5==+I@ MPn;1,Q
+۞lu.xJD>]!Dӑx=,v&k̃?qd_$"S{KJZ_i ln*t@0x (c>uh *;}wNfo^ ő04r&NnV: a)6"^4ĵR֑G5kx9'L
+asx ؅ IcAطjAʡ_6@
+!8A., -ix
+LPm~:ʀ(;u66
endstream
endobj
-529 0 obj
+623 0 obj
<<
/Type /FontDescriptor
-/FontName /QUWGJL+LMRoman6-Regular
+/FontName /TRUNAO+LMRoman6-Regular
/Flags 4
/FontBBox [-515 -298 1647 1125]
/Ascent 689
@@ -4122,121 +4766,118 @@ endobj
/ItalicAngle 0
/StemV 83
/XHeight 431
-/CharSet (/A/eight/five/four/one/seven/six/three/two)
-/FontFile 528 0 R
+/CharSet (/A/eight/five/four/nine/one/seven/six/three/two/zero)
+/FontFile 622 0 R
>>
endobj
-530 0 obj
+624 0 obj
<<
-/Length1 1868
-/Length2 21567
+/Length1 1885
+/Length2 21786
/Length3 0
-/Length 22722
+/Length 23010
/Filter /FlateDecode
>>
stream
-xڴste]=I8m۶m۶TlVmT~##d͇{=vNBJL+hbod*foBHU5cU25w1t010
-;Xۉr],
-wt4p+3-_H[ۻ;[[ L
- .zzwww:sWg:{'s:St;YޝLmL&N $kS
-+ 0wk7XAR¿6/>
-|w:CgS7S#,_ǿ_\,LWK_]@e?iV{]M-M=ECK_?-$dM ed0}02G?¿GK \uLM=LaV썹C[Df*I9Ϋ4V3g:q0ELȊe$tRJ5HC|lTOߙ(
-
-ѩeɮTtQHjeu$vTO9;{c>o҈t*:6
-K[ќlP<VpVf]>c W
-ǥ zPr;NXrDnNtZNZ&k(BDQHRq]h˷|vT*52:spBvYY%.=4K1oj>a3fM",{g7/Cc쬂TՀkUp_8k^\@g(Z|
-zJܡve}+X?-Z-_ 9t"x
-:%SH٢헹>'Tu##v]&gN gGr'[*zr+NS!it:TGIItҥ^@S)̂P+ID@GU.AF `+Rg{'O f 8+~qĂx<uZ
-3tjP}8A A4|nnkrefεW>dZb6LBsLmH,Xzz;|2C$I ؁k2]g1(٭;ס I@hD}fAJ4,zY(hxgTض8~zĕr6uu75GQ}ad-tO@\q& /Ly~~V&mNW]a/TG6d
-腱5gO qTn=]ơ]¢K+FEkgM@
-&ߥ|_?(~$4՝7@>lKy0~+#:6qSc<F׵C7XN۔F:#v|VOc=M3YϝMP;xZwcF cwMBJ(٘.o>ӭe!)J~@ू*v K^znhxKs8]'++=Y*xZX>`mQ({#uPsPZm\932~v"\nrwi}ZmxfI l(;$_ޣv`͜d&˺K&lKnBдeuDBpmg G8:2%R=l
-_6(&Ĭ"XuLVqo޾Z eCߴ䡽.7ݙ--7,E.K٭a[-lSh<F_YYݥ>B'p(
-hZ{oݥ7~2=kvKJ:| }!rҬ妝 *QᤧM"?b[]"ۧ+lT_Ť"U7VЧx
-EvWrc@`͞"NJ%Fav~ȸk~';4|dn)A}ׅ?
-ii&Fzܨقr=cud`?kgr6d;cK$5d}
-6G08'nJĸ[gwkH|em6ɍ,aᴶ\i sgJ+ixm rg)$C*ک/ێkZL0()fL>q63Rd4?!cL5=0GB$Pe|t6  'V??&ߝf#JjCn. Ҡ5WW3ߞ/e/0A)c8\T4uqlghƏ;A oF^ߒ-ܰA &e~q3oh6ϘM+5S 2fEVT
-Qe✷gc:[G\X{dڢt4! ,-2<E%Pwܶe#NgS(ݮGdhsb6GrB"[* H["¹31Bo;>NNl7L ("tZ?2dX!ziWr@pk)+f,%{j֤6mQ|JL8+sy\|EV-+jLcU%? [ţ?J{5[D\J玫fPE]g(SQkS1^<r{Muţ/G%ś$Wq:H-6e =3VviއU6GSMMBDup#^мI}INۤk8,$CN$2ߋ$6~}/p{)!>O6xhٙ.<caRS8IaXչEɼpЅÐ]!_o4 )H75O!/8\OHɯs]sZ@b|*<Xw~5v{(O&^xaLwHZI*rqJ~ބpp'.];
-zO4>ik'-ѧvx1ؿi鬊*q5Pͯg A4`4
-4m֡ *ͬ%=аnM,5{{wԳmBleT6GsjmK*07tBS Ǟiԓ8=ʸ\pjo6(eмF]h!==yl 3լ̤~E@hA5~49DA#Qd_+$ұ ̰ozljlU3UI"% Rv\ۺG+yJݧ=&yv,2)5ݞ~qWtJ|_cz/gARENbKQ%<
-O[.GƁ[m:09 t`wHXzU~{-XOI^]89Xyr``8+C0^oBǞY6o=URS%&{<'#E  &Cr^
-_ߛM~;)w#R&/qr8aX֦0QDw7h9 ܚ"+@L#a$XsK).!R#j^vtʼn9mE7
-\!vQ;'Y GnՄhQ;կ0f9;.$GgIҊ ϟopܘE*d!"`#I4:PIIy=a< O?3=9 ?紴pgom, | R)r0.E=Sub)$BVക=Bwu @?#l 'ͦV7 /azNxrfg8dzt)@i'$Cs^qf-5cdfb)ף͘v*fDH1f|҆GKXQfs ^'ژrv'PIUIѲGiKV5LL ] .O ]+\<8'ެ%󷈐VͪLUÅ
-` /Í"/d\t
-0hR5&v;;Xh0Rg?5ծ8>u"6ݯVzfKZvW
-N jI5h Afiл=r(3[
-p]: _iΖn2ߕ1H뚺RAA3@~$4MIt-)k<4!y5?^4 )@H,AMȦG )I}{- )3ܨX1 E#^mj7/$>Ӄg F E/X.x} Y5^ыc^ƪFAʸ
-ؗt+޼<a¢iҚYN O㘖$
-`p1 4H ?L )j#>:>]NWNq&kr|VcLhT^Hb\ne#1_2]7B͆*=o Vk 2eKqC7?AtMSgq='P
-(#Mfk7.Ekaf6h[gN1C=Fcݜjj_9xT|(?DVݐrtǮ07 |[;`[4<f.V7aq-:WF,n1Li̸YCc
- ~ Ms?(57ƉoNKkD'pCihpŗXfśh66/XsV .mPM
-Gd|]viėYzm= gej&؁;Fp
-6:Xa<%ce[28a9'Em/SAu;gShYhr%ۤ*"3&s]-hupPL!4 Wq!Aq{Sِ掱we(gx,.84]VjѸ8
-aɮ<(m;*[G{ݲoG^aTcBvnjxZ}i
-kWv R0
-9~bL\( QPqCLr(7B\9}gXFM778KSrFyvCC}S+(0|t̉ZR}H+c=xUէS +4*o1YYӢ B<Z" !L{? RB`,(<vɭ>W Qhf2֢|IHyIx 12  "r>1 c6:'ּӤ<%B!
-y,u`h-N_s&Pxe!LQe@z)]Iן@zfEcG ,{8-w.9LK-5(4{w x jz!:l0TRJ xB|zD`x@̟:g(MN\L`Zq5i^o~:RLI9ƵʥE ÷b
-#U_4*P$8/Ӏ
-+Ͼ8_Z?׷/ 'ZᓹXy^
-`t]C"R_{ΉO6JNOo)f0ԽaNRU`#5ÇʯԁvOS{.F׭'4,#ü^iq̅vVx"cR.! =?/CCZg\37϶w>7OSOᕝ!n(?<sd=c:oRscaX۫+/I}-7
- sݖ ɹ/1 h[OvЍVTD9Y4ުΦ<|+LnX6
--2r-&0- BB,&ˇ<A'\ D"_yAAPY^@2ozxcSo+Sێs*7J+ee~ӜlRw$];kC;k&,:F +Jtfg`4eNyP66wNB_)mVtr5Bo5}uV1y{~:y2j[^tp; tu\ɑvŻǒa0}Z_%MOg-:7~ƛe=A92=8)pw@q5v/*=Wŏ' I3'ix_^dXNz ,w4:q[dKprFo{e"~$#4oMc
-E iM
- \; ]ISy#o3TD7-ԞxzbѲR'>Tu1V +*$ܴ4}0՘ߊ1v]ۗsoqR~&9 qKm%IXC.%Q58?iv.[5 D(xgk_BeA4RnbNG(ڧ3~ 4d& yJ bysLĽ~e6dFmV~ៀˆ|DgUY1H'u-:kR!`^!!<)Jχ
-
-V)&5Y7{z„OdFcZճec=|sy:#i\w vӇT9p2){-'ncVE=BC&ȋh*O7YI?1 a=y'໡R l2mEP5r
-nPqb)42s8zD+nHcP%1#h{Fhprh|RƕSalk!``pbU=2孕pڜ
-lzXi K݀vI' ꜈6k
- iQV*,MWV",Ц=o2>(`N98w!=J)FKQȑ!'s z{i駙Fi#> ND#r~D *LȀ
-OB69_) JH51b\<CK'L"Byc`[A90FءI\,7LHV:[Dv ޳niXWxUe+p(y1p=d+o$X~ةJф B0FCR>LL
-=7gHڒ(G&GB(f:DovK( Io+Zkd!⑓[r1nxMٍ?K7\Erl%=t<he,ʲyG%nc,n _[yJ b8 1SSS/_7uJzr$P<kBI8X˫(18WۤB5%/-R&,㮰-30k튌j *(eWFioJPGF=3סK_$Z,$N,fv
-Uǂ@?'!t \lfHS,P ˮl
-L07WUuS~E\J6LlS3S/%b^uU +@9|'a-<˟nA_p:ں /^Z[c3}
-~?$awi_.r0vj^~>™SnE5Sذ8߼Z;k!$qI/ ( LmǠ1d+JN-#Cs`I?D=|Y9e6>`hU7?;6f z9/Twi:rL%ǨLwNX+Li`]
-
-.98A$\i¿t@w$C>hegÄa`\O%yoע38A9R@sJ[
-d BP8#u%rD+'PM L'J;\?7?PJ‚)pn`|ⶾNZ|ľц!zpD
-i*#DuUUy-048b!B<P~&g^S~9gE>Hַ
-GA14*v[cPx9VgVN7xB7&Xj+~PzS}-deàyj~Ʊ$:q5AiPZG\
-S 2;5.id5Uq=CAD#Q-WPe)O&2FSjpѳNB>Q50f$D*ƒ.}ns)2TXHZHS(*!r #(µ >աg߼e.dR8whshm CEbAMocky;Z;PD뵎=##O0%!wTI>=Y2(bf0"2vii5˥<Alz)
-e0{ܧ'˚m=caI4Z-gr~YaY<' {H49*"1Cʪ <
-xxoa:Xo_GҕZ+oxF0I2skՀ<{JB(['غsZѠ >xIg.)qF:ZA9jC)_WOUX&Muyc;KpN 6 n}MBX8
-q`uMzo"[ڡ =`6B3ߖ)WX1X~yC3~
-IE ' w[׆͎Jx}Bf &E4PBJŞe_n7,OoqcKVQ5 IC *}w{4#ZMBڮցrMb"`Wqf8s vD>S O YDƃoq{|q,<ENwAH^JU=/+{/LS
-px =鬝&'4VlfQ:Fs(i6RN:M=<?̏[앴-t O#q &
-}/@
-veJ.Up%($>gCN@T8qINaK
-qmsF 0Ẉt!
-k4%(?9{,]> svn.Y{m]Q@1>VyDֺ|RqVX"z%+MߟiS41p?U[RΏ(.>}OA䩜
-X#HfXX-t/O.MT.
-Rl]2AÖ15:}aKAc A2VR>ھΛɯRv d.*jwk% ISGArLpq[^[ElW&rBct6ԏ`pi} ]|=W &eխO([#I9H7U1CT+e
-Cv?dM`Bɑ~] 3>|SqM踒njzL6ѽZb* &vtnO=dnQmHFY?߀ZhqXq:B1>ASK+?E|'F$ *5dRtC0qu
-_lm7 WaF;FMɓ~z{@r?kpţ;)'^Ug3AAN|֬Ȏ5'@]gH N E1u c"&y>-Ig.[ rv)X?t%Ip[ {FX)B9i؏VpVKO9Q2n+$y 'jv[y!EStZ͔t
-KL~ZS/'= |R3-<@C@FnӉb/ m6 pUiι08Ҕϭ؏lQ Y [rL>#gXE:d7lϔ?wXAc7eW|D̪@v +aT`9C
-:+-wqm ԋ8tV} ӹ.ň{ߟ[en BhJUA5=)-䫕Q
-@Zޗ{̐;*_EN%Bm &tRF/ Z:.[zJ3nEg\HQqbvtO |{ӓld_2m`.|*> R|-O@>}*cL9m&Ӱyx6 \WgXt{wV]4Â|ʼ#Ӵ fփoUWs;%ۧW+0"-3憼;&bڴ7i*b_i8y'ϩLSg={e
-5䂸Ìc/zWk]r: kPl`Dr𸋽;~4M429%r)n4G:YbI#mM E.i
-5XX Gn*PBC'o(>3*]5$ ߈nG{4S<mMo
-\7AhtO4?hmg5;ID ͪx@,Nҡ#!j?oP7cjt_!@&Ԁ$ՂGn2&r_F%mFD{&"oW淕GosEaIټX<wl~zpIɀ=*Ϊ?U>JoZ34m^Do<-FM›*e/DjJiVQ\6xa \Z+쵥#)%e_Ǥ]VbTRp c͝8
-Lt ֺ%ςFk2t|(\vP4ƛ.D㔶vR+TBv
-i(=آfԀScYϚqMI5,?
-=]^  N*7[oR1F0(g{2I.CNc:E@'
-BE<!Fd÷hΆ؋dTt-1Arz -&z";q;A%BYVW%j$!A=yK0}05T!wS \V^k0by/28{{mG=R$})V<Ծm7P㨚J
-opn
-/kEכ9J+YFa2<WK`3xq--uk;PEބ:"iAoQ Z|Rfg
-Øx'&dzDIXS'ہ ! ܍ۅ`{*ب~Em
-:* Oȵrh7ݖ@2V,ۂ1p ndMcho|[ Є7_/&I}T{S tj0-(ci\O/bFjiPZl`5 ;~u,ʺ sOLZxZܑ/#9}~ųk1*%a_B$EE(tPli%Wg7rij@O`6F0r*vǹ׉ӌEw MTL% nB۬N1v2:!ȹFlP}f/:SmSA6ܚ.י<05IGeEEJ懘u}>{l8˞Gya]h:B(vT|* eڈN̅t;=gu u8uN Kr 7?1Iyj_6B4ʛ$}e}Y 2Ui`~Uu*`xDdJNg
- , q :٣\ئxvw9%U% 4f}
-L}>)tn޵ ,ǘd7Zg9!
-^fF
-
-RA QIA" ҶS:hf)V~BaZvX=tDFW3 -'XpC?v+ƳMvP<Oɾr
-(" VeȼtF`ٽ.8}D 茼<m4`TP
+xڴeX\ݖ5 Pwwwww-p)]Bp ܂\kܧOy޿UWƞk̵kS3Z8L,|
+9:H|
+r
+
+?;fjov
+t:xG@^g[
+/,.e:(#
+yaXȅvULctCT2Ó89mZm%Xk$+w?O$COl:w_ީm\xQM,$Rl\ Q!{FP'AG
+Sntd+e>\&jPzlb&'\|̣.΁ U.FP- @.u
+Ҥy~&#)/%6#`yjdl^۴4z gcWQD^5}u\T1%]~cٯ3l)d \~~[juFޕg^" Fr<2+<}(LԽ/ЫTUw76?tʒJ`]7ntL&W?6첋=gs5 ^J|B[O`EIoHQJ*Yfϊ974 d[xDPPU›gc*wqzU-yEx-<[`yoX[C2wjuxuf8fbbT\*~[]k.k.<xUI#$t;H4Evg-rvP!՚,\mn`ܑYQR>}`d|`N.\唗8ȵA!
+,Z>G5SqB{Ӆ9~3
+yjA…'2.,Q)AΨ"ۍ4889 "[AB3b_Ҹqr=<^RfXc8
+gP))#:H7Rec)샠}dWY7INvvjNrɺXII͹.jP'4&H_VG_͹n:#[f<S"旑BP롼Jʏe9 m Ԯvnfɯ*1)@7Jr_^b{:g+Lqo V~a|Ϗt'áIi|9 5` T()+Ȩl}:pmFPoi«ݓDtbTl!EЭƫ%Оs'SJ[b8XeOfp
+5#c( $f9L+{kݼOjڤV0^n"G)cv&DC6Y*>RA nVcY"R
+jqP9ܱ= +Bl#c>EΆ y
+k-'R=AA )rRq}P߯ƫFkbc]
+_tuah8.#\C=XVl1 祘4=ď sR& ]' 0N)>G9)Tx3aO|bK٫rN Yk4&j?|%qܤ&F.I6dG=1?:0U`ƒi } \CK#N-qdKˠ=
+d8z XS E ]?!Ƹ~ƺ8W7ӝ>.R=:hHx+gd\9r9n΃ Mv>p!eIi/r=hevuLFUE W<}WqB1gqiom/.D"ѫ~]Ov"-jy,y<W<6
+i,5^"g3]9nD|=J5PĕT@(2+)^_=xkwr0Bn.(](
+rT2yi5҂Uwr46%c%
+Ƭ$p_NO}#b8V[k
+_ LWAW۠?r i27a|"ֈ!~i'Jl]JPi/],AQǯޡM}#j&<4pewјSx V;CI=T҄pUM5[WAƭ=[ɊgQoPԖA~xϵBUɿ
+KM}b xW"vHܮ>&|49-)TS4`-$vڛk+fE]af0/*$ܩ`2TgiLxGTʼgA=x`ξ#* vnڠ<)t@7l ;31^
+gm(
+5*!O%6stQwMcHžI
+vtuKJa”Y1h~MWa\}=AWMSWxY>Z[ŸY-INu]S\<>Լ))O<8 C̼`[+ XXiD#iӾ|0NAQNEϬ;UH0pVu=+q1:^(*rK `1yq&}mboD6212/nr.-;HᏜcWx]S\܅/TWٗs1`ǝ(
+D>/NOvo;'C&w1 |U[Df؈B42֎b v8%q Aۘ7<N0DHy~fԅ:^_rø*@,cJt>ԃy9ZDUKyĎdLqN}|g̃`Y쉿ߍ)u3P9B˻;yYkݩϡ.'.j隕#*ٖTi2t!݀|*l5a/ɦ;c
+ske#$բv"RqK&]ψt_Ntj)\?=~~>RעoRäq(N~W
+m<`iQM7)yL 5ؕĘ:]$/LиYLm]{Ee׎h`]5BN.ɭ ZyQQcv-WTe
+繨|99RqyU`mUӍknJj"xƉTD&>6!122lEU4 \rvlF _rX ntŲZ.6O g>ä$ߚvc!ǿ -Zd=P%7̺"SG5!QD/7UД #6(yz_Y5"TnDUY[0;G}B$S{I6 hi|$; 78fGŚDC000Hbg9TZR1sW4~WȔ*2 :9{]D=鎑$DafWm+6jݣ= Cmf*,c&n2zbvʜe 6ʏlSF$ =Ti( KWh$#ߐNo5^Uqֆ!exϲjq݌Q8R2=)Xxih`jk7HQoUm T÷B/5c ΰv*ei~=a[ψCE6q|?\9Ɲ.Ο5ap6F2gc_KG-Nd_z!s2wdե~Aɍ0 {"%LCJPpw g]3V}m-m3(D꣭lOb3.r-0#eTgb=NF1n!I6^pyib=A襫jv y0˸͚FwaH+l߈:-xͫd+LQxʆ,M3iVZ{3WD!1; &S|^נ]p/|Tc7
+!#LGێ}PھBD
+?Iu1,`j$D ͷs6j-w3vM\Ւ_F'md~S  )w-]zvhO!mZyq3U[^as,"|z$A6Л'*͹_8h-{*s60Nz9n8r5-g=Ajgimt *|y9󝦬Vp\Op $ݶ]@ a:*'L
+K|i:lb'ރ}T72{\n'р
+b2}d(k#pUZ8.V'܍ΞO {򩒭?IoPˣw&kb<4}67-+W^aNf/֓ۑt.$M8n*|!:ӄ&S?7E{wz;MKjc䥟iݶ.$> ILh8謌7_iI:יH;!FNtI|>oraWz5xTv\o꟢" ڳ1G"^[,LK袏=R;(mƸ}Dy"-L u^W'pRϼ$Ĕw{ɓ>_sH]GC- kR\ﮒ3D_䔺LTկ_)72m)>VbhA1np2
+ݓuզ6$a>0G[Y}ino^VE);GIT7{k=26XD/ogMHeضޛWB|G Elz%s8Ƙ!tؗ%tҬ-F'Tl)6rWB濄bƦ91 C6}iʻ*Z$N/,0~5=ZA֋
+}
+
+#s{ڐTOR]?-AJ/wc8ȾL<6`K±d[ hzʗh9>6,ɐ ē8-G5d>P? (;mtu
+PGƖ=B^8wJϵa==żǸKz)%
+I8@4l%|~|I3CHҧS/+ 4{Nѣ18H22?j#zvw>hf2n1aՑ?7,Ż;S`=,Ցl+zJ|9pnL}v!<sB:a Akrob: dIg[o?N{pep=밚 OS&o@%c6G Y{D ]HGׇ/WPL:e5vPX67dj*BjqIBD+$!~B
+[Nc˺^9lUhqջ˳o,aSV ުO_OǾí)&R|,{sP(l8?RtD83JI쀽&:R "3\w@dDT<GD*\sK;Cm73gL*Ύ}?H#OD0m7 V&fݩ8pw
+b5<У`y?$ZB6 I\{EEGw_h/Zrrۼcvk=w^~þ -87)[ fĂK"CJH~.] 2p>M|8^D>8EE\WSm=9hHRJ)rwg
+t|1X[>H ԇC\PƊx
+tRLﺠގð0q_%eE8];W>-JvssI<]!zsPkE6Suk5"12&JS1+7riX#D?Mi%2DOV
+`^\!~e_K;w<+Mk]''qfo@q>0l6-%, ߛ-:, [OJ̰SL&4?ww2~};U|&ˆ<:Bd<;;"l
+7O6!կ'V !qY_M]ofuZw̺NXctJ8pؗ)?@OLI,HFg|>%Cv+J$j{>a*^بt 'qT_i.EQtќPcoVC ksE8c^98Aji>g\6 x˅bb%>GgT~lG4_=ŽBFA6ʨ::KYA
+WI 5S 47K["s^Gdr;A"ǰ|ø%\k`8["
+^r Maϣ\bV6&Uツ16Ay4"+೙w@<rGr6:{
+܏wX(Z7Zҧ3b'}9R16fV:{L[ȅ9g(1 t8= ЄYD}FϧYRc)7K}P "s{ ]'rOv
+
+RN8_dk0 _~32'_b-JT
+]seD&ogAbOi*g~atd2u5m Ț
+/sWwuݫQD(}LQr||Ѯ#%Пn]77QKfzP [=..v9wsݣ6>7#ď%zN l@x!ph7-~L q tY'<*Ĕ1.i5ukv? -c$/By&ԝ|稩rDRi/M|Hn p#cە5W?[o&(.!<|LCfΡ L!uC})FEER+n*s,WwFYaB
+Ь!0j|}ƘbRCiMnkW,<xʯ 2%?љIZF|:ns4FI.yVtBSRʘ(Ft>`&5B#t@5mk,-}"EYwziA^1G3P*mrpXm|Xe|'T
+YKtSI-e2}=#X
+7;zUopX~ $o":0.Gb0rTt| ѨG9E3d(:^s%8eZe-+
+E݁y=yOM
+BbA`~xSuǐ7@86tXV<![
+w6F#zJ\gQSʲ9~hYB?
+d<>Z67rB!FMiqv-oJv=֡Wb5?2Z6f݈PBL8C:9^XWV(@ioY.Mz/ 6s4wRo$<&jSF5АD'3Ap8KEJG
+O^ަVi7钺a XanN},l߷viVES )xhYGŐ,wJ
+q̨Q&2-R^*=0Q]lUmfEöa1׼
+bX2|v].ky.K3dTM*w'f}vS"U}VDw~]X~JgjS=4QHӜoFNhLC89\',2 ~}[ԕJHq9q'緯ccdSvJ.^%_gZTl<gOPVQ\Q>Mn7VіEK9'6O{]oE# #.Ss$.*ԅZw{Y0MOv~[qި^ w#LoZ4Yl;&1ByE@/pZQ.?QqgR,SUi7J;rXȁ f," ~Ҫd9 uiV &pz|3(1KdPY hCb1zF1ISӄȐ -]6\[/\!y/iߡyx4f5W[4>蜅} w}Lb\ȏ
+O@c&sLS#(Yi'BWב/ w.~tXE=rE,qϷC1ЋڒLŠ }m|8 Ve0`bЖk #,6EгJ::J@&(HL~q wCⳒ%<yM Y˵W~x;wk</c;ˁ1+g`AyṙЉvBJeAG:.rUWJ\mAk7dQ9_4QO
+~Ō2 u<k{y׾W4~7]:ޒ!r]kBS6*.v: %~RcY{]h[c A:ldzǹޏW.g(\鳌y~LLP)1gjxuO[6?"DC.^^ =PثUD#^~spXa;5ebLNuZr߿=' /
+;qٺ372BZ8[?#5P/`
+3I۹ CP3JR3jio`32^ f U0gwe붪scӆDi灯妦o3to؉ ;ภȱ`(C.s
+d- wBV3Йk) $,<Q?cbh?ɕEX̂#bӮ <҃8"GWS:q}̧|}iMi._
+ ]#dאV
+d<ڻ\b|Tba2KHvfR))U<r5qت}{+G~Oe/ͼE@a#R;~+5e۵5vU ؊xZ5;!L E3ޟB.In`ԐA-,ćE(C$8=ζr^sX)cȂ,vH)T5}v#7 # d|9777l`Z
+"\
+Κ{C娉?A!EWTAؙȦVPzud/n@k6,p0Fu"o h,/qUdd!ɞ
+ܢ-{muUbémNYH-zvTݞy0| xEgji.ج*!?uʎ3 [V2P`+el SI,/Oox>mCݲ9nHލ :,xfwgW̟lѽO%-UDȋيUЎ4An=Z#tߎݲwߗyk*bR>{dx8*Q$,;
+F|GJ˃HwӠ0y0Gx`73~y4@?1iF(a2ԽJ:, )>[$Ey%\E$r:@rCn` دR3znuET3o݂{$U`ON9H!sDOOlxzgR%!t\>%lfa_E)5C\<
+765bʎyĈ6\L.2DsHs'aVE $Q|!̺h!ߐZs/_&[*qPs{~ \|=k
+, Ƞ@= M𰝱N<x+bn`&.`W4!=e)LS=güp[x,`?&Vw"7*nـԐiCMfR1 ^ cgYҺKKN ]S2`IjFZBlR;V6@r[s5{ 8ղ2Qi]4n>>b#gLF심K
+^
+X#IǙ-@hƭըz9K1?Z} Ny8RY)#R%)?2Zwk3ΰk$0ACqEQ\:81(f!"+^k,4{Ƒ+X4 iU{8UcJI"߀7b!J`bK$UíϨ-؊$_}܀ٰshoCd6>m+3ZL \tr`,^0$[6.ʖF,
+(He%Q8_ Oz+4A s5(NpBvcHH ݻQ5:`[_;'/$mSeռ\Y\9o=Հ׭f}bm/΁Ft:
+PPC1JžmEuFu|K+Ds
+ϮtRͽtJ4vgQ ȓvˉ zc`
+S֩z2ƐGW{}K64./5`j;wb->.<,kE(pxZeAaB&KoO
+77u-
+#?i`F _K]~ߵ-@RaW*Z@Wrv;m8*_t^Y /uG٢0(ljP
+centBr σF'`|"* Hs'<^T1Xǯi>0$"?ϸʘvW+@j|OMGi+wVZDj&8T/=$fa/CNv#5Ѽĺ 8Ia)zZPBW<J8 xCiHEj|&|ߓIp逵Ug s YA9K!mv ġI d! ze:thnN!ߛq/bkMUT-+|6&ማٸI:KX;@xB cKMIvPn!v'6h?0P߻([㢗!t lA.K>2 AjɀAիN:A}7w-D |KL)I;`
+>ԩ NlzL@GfiՑ)P
+u!dx]-Dl黎N~.J4[ 2)X[ɻӗ|%iE7g)uD6_od>1)rHIV4
+6fDQGG3 .J.ŐE >;vRcPJ5
+aG;9:]33:ZeAQ@[3nsKϷZ~EI{՝CC|&޶-%"- ȣֈظ5ZG LFдgۍkj2+[јb
+|G?e #
+ mqzAG
+_r
+Y7U Q" I3I+ˌ47ѺJ
endstream
endobj
-531 0 obj
+625 0 obj
<<
/Type /FontDescriptor
-/FontName /FPSNHG+LMRoman7-Regular
+/FontName /OGJSOL+LMRoman7-Regular
/Flags 4
/FontBBox [-483 -292 1562 1124]
/Ascent 689
@@ -4245,151 +4886,133 @@ endobj
/ItalicAngle 0
/StemV 79
/XHeight 431
-/CharSet (/A/Theta/eight/equal/five/four/one/parenleft/parenright/plus/seven/six/three/two/zero)
-/FontFile 530 0 R
+/CharSet (/A/Theta/eight/equal/five/four/nine/one/parenleft/parenright/plus/seven/six/three/two/zero)
+/FontFile 624 0 R
>>
endobj
-532 0 obj
+626 0 obj
<<
-/Length1 2402
-/Length2 28740
+/Length1 2415
+/Length2 28779
/Length3 0
-/Length 30113
+/Length 30194
/Filter /FlateDecode
>>
stream
-xڴeTڲ5wиkpwo,Ѝ$]w <Ͻgs 4tVZ: ( 01 ^&5J hbI
-
-obRuxb
-
-
-ֆ"?t,ԔTe&2[؀
-`q
-VQYO sBW!UPQ}b~D3k76
-})K&wc9׸\֯9 j6zIٱas*Vmr.RZV'FG˙lMF~-yߞtls–.[xPLdj쮌1H<Z!>MP畗c|Մ 8]'r7=QLlIϏv34)7arV<Mݕ2׆2& -!ۋFfc
-?W B`yPbJnwe"_V
-'"vl,sVsh UК͔1YA\P :arTl>97' c~d)7I#<rPJf7oYK$c¨w(; xBY?%Tޛ=u,ްqZ,(#0ar44㻯#xFi [^?Sxpe,H,}, h\O?^\T jA}( ˁ?1ȐK\H܄xQ0}
-frl3qP>GkA訰Mp*W)c>ۊ" B %!mMڃ /Os3 z_~ߑ4Sw R*.V1ϝ (PgW]UCgV]
-WHt]Y0MDm/^Eӡ{P2ϵ/\Ma˫CX!V{-H(X쒺NdB,ym(
-R&?łft?Kr cl皊ixQMzkSǦ :O%[ՠ͈1Zɑ{|~)-kDxMLY"$n }ҊV)<Qȭ u}fWK=ЮH#_-Vh,2mD`w*2l7me;!
-D~m" I{$þ\FxH/݊+i2%U+2Xgl4 ֶwu`d*UqSK KDĻNETۻ'1XDBo
-O4v3.dWɡYKRG7{oAyE礽"Aa֊%}AbpPw~5_c *ʧlA|g$A&FqLm*9)u '"0FQGgQJWY ,ƯXi%hlJ0akEƿ `5R.n"$2~~?۴1
-q0ćIa](|P@Pbbq5 u;-})dʕB<>MPsp9qytT9M뇉C +:64p0Q=:2KI$\ʇ.̏]"4WP_lH!7E$6 cnP}q',
-G;yl}!'Ć)39yZ'4yY|ך7>48) B¥{‰ݑM"je a*i YBJfL**enIId_Xx$e]Z)sNNJa^u]kѶi8/Ɇ
-̉: !3 AxIZM$%:ƫsδM`dKNl~u =gA %lH8.pHzZKWsVC)X<Ʃ"!{S7<.›ë1q4enX}%?%RXq^Ź'żchRlKYkǬ
-"&M51N`^nf a˓>Ai>zHתH L4J-/:}mkGhc煱@.zcCISrrd/'[~'ZFX8/uy{ /["ɽsN -} ~\S-GO*9tt)B~Ql/[8rܾ߮$?|OPjU(I;;'֐f4(,zI&KQd.C,X 7K{(= 
-(6Dƪƅ׏S1H0֌@I%MgY!騔U V)jqgϲHc/+XGP3_~]MQ K)$zsÍ|ş fMљPw`{J4(>H2I"SF?0Ï쥫Xj}J@I),PN{o|w 굖QHw#?\L/
-uQ=BwxJ ½+Y/ňJ v/KK("Bs DTj5P!)y 4GP~rP1L(VIe?ï>8e<J: _]M=.FoxMqP[aEjDG[NeBt[oC{Pz$b5Z;-$j((^PV$
-Zz:$.<-Dүn)ݵ[,n+3f V7/t҄:ICeI_q?#z'3#"f%&qlh'B0FiHF-=rb.ī6q $'Lλ}KuiJ͈wΗv< nqJ8իL{L-]xl;J%ZL
-I@e<v;:j꫗_+*NiBgQt @}~M)n3'\`n8;ص<SBCC'CN9@ 1'$z߰$:TMI---VJhtqP}q+$-+KM3p5 ̔Y(bT?/^Ϙ(jODit7Y6K:۰$I]x t;J՚e;#;[#ꂍMlZB?g'//l5Zx!ECM[*Dds[ٹO/'ʉE},v*O.ݿTu<0Dp*$]3Y5~ހnj RHucsVNO4|Wn`Ar",Ip 5@\0':ny]Ww=9@w\h"¶n}f;ǻ!IGyoК n<;qnF&H۞X-h@WUxż`h/-;Xi.#UsT&v#;|2eZB GE1`#ass9SJ\ýخ٠X
--Z|.!:D,\G&GMr'.{jGi#8Pv.G@pVe0C63?éٱmM{M;ߡip|-_XŖ չU'Nygaj>v/-3Oէ6_hq{0|կFjn n[K)>O$͂ ?> O748Ntw~AB]Rd_pfl"bL7AjEjEL&yL\iaRbގ $FO<nS`zvTι|Bk;h9<_4^H7)J)&J^[6v޵ẢtP<!$yI|oX6"JU<*peHW {d9lx:ш`ܡ;)1}M~*on F[~o9q/
-lzE,crKFLDL=th%-gV?(׷ׂb.u
-!ZOML}QvKF_*]#0 >TCӱ' ɤdU aޣ7G^B;^Aʜ{|6jyŌ!$\If
-݋<tЬv!lGxb7k&؍hKg_s|%KKys dž)sU(A/R7mܷ2p^N͐;IsUo[t}_! ,(8pSȊM@&k5;8Bw;r]a^T }}
-.@^"V^H F5cE 6]ߏ2SW0UrܑZԦLY%ڼp%u,>jgpTh~An= Q5fsŠx0"h8vH2Ϣ]i69Ƥ*<P- K{
->PfT3M@1!A| %vDLҡN3'^D<hX~9aoGs'ө%idM4TYQeƕ|ge,L-TBGHE!]5RȎ>W5K<)P]p|h!GU^VpX?αи`W~jW<T1"m-ͥ0Iuu
-|BTS$>a~
-}Gw[Hh!<\9ܖ QEZ!,cüeN@|<=Cu9wMx"5;ml^yKl)%[Glx
-Z+gb悉%o}&\%1R'gxUH`fԤQm݂ROh nc`rPZvQcֶsXW^^5 jغB}9nh2ȕ"
-j2+BO_vD 4knL zքMiW(4_ /L
-"[b}=`D=#6E{aܼ!kSڕ„ߴ~|v̑ _5GkD(絀_6H"0/~x:Z}|L_o '-MGT]8w.6)A4額_D@9EKU 1@IU/NstsJǚ*5<,IN8 4=L>P(RT޸ba%
--Vﮁ^eNK\޽RH cf)J.5#J")ˌAN TxnDx{q [曢C>QEgń/!p;/59K;O
-={ŨL qkG'v<C As zuÄΗR$\ߏHlaUR'Z1|t}Yu0Ej#EnpQ#O eU3-zܨ_-Ϧճc[8Ng}NfXJ)kVH=Ώ .ב?=yJUe$#/m,Yxa DP DPMu_UPq(eը5uieX{P_4 s~-*QVc.XCv`7*@I\,-F
-R&d-JKCk!gQxӈQKߴ 4 ]SW]}+P_re#z+$H֔(*e& ASq1rFճ.Tm]޸\!Yۙ+"8.O+?ٍb̈(广ݿaӝInO+`8C^gSy>ytj0{D3XKtCJX
-^}## 0p:u= ՘Uos[O8MK^*<E֙9JuA wn"܈@ ږxcXiE$N&)&Q<^YV뻛H&k9[kJ|9E]9ޏ(Fs{d/?d_5?"#,602|TRҵCԠ|8+esQ0R
-Wgo!
-x%aNPO^xQ_iyqx{S`,ckek6rb@ h]DFdEqf4; 0(F]ΆH]7~wN^ 6":C;öIA $0N,;Sk?e [["lw:R!π=`szAݴqYS4ep*\8m|i-%k'ε PJ6aSfqq 6yTԺSXux{w0Q<"B/67v;E
-s =⨳9@*\|RcOѸ
- [3m]=
-y;l)ms
-Jlaxߘ n
-L`4ho1Zjt
-9j;2KKѪKr%Qƛٟ˟>L~&%r` pL[ ]Se
-7IA`[i ;jf"\{ ;x>O0Y6Z8bh[zm/
-u;y}&Cd-A,G+'.cYܻl,<qxRfqJ8xYU&hANã$nE38OgwQB };e
- -'&p̂1!и{sݴlNU 1UXəDވ]{xq@vާK'kƼ9ۦH^:\(K1>(0MUQcf݄r,n{QBw-:4f~`j
-22y Y8^*-DgeGDM)w%(ν sͶi"ҰbJ+F
-aO?SDp)gE+ߋȕT͢+? ܪP;xd~הYh${qQJ@k
-ݴKMuQ7Lܞ{C
-%PPfvJ}v!&УR%kxz0ͣhKPJogIժ~xhN+KX^t'ϾY\6Gj
-hyo7RZwA % mR3*LY2Oa4[szd۫=V얇$)l㍸nXUs5qC߻zQͪ|<_\kkGtNcXΠ.p
-t #s* _+ d+fJ-cY@a4~\zPj%ZœB78YTB-;K'&(y#m5[k?}I~jKUv^,MxJ7{L6(dXJz .>#|=[W VC%/ RG^+x!^:{@کϧjeyNqk>]"32+nܞw'˫r|Y-
-w mumǙ*{S R,٭y\@1^fψN~Aٻ߀Ȁ/:J.zbTt80d˻>y
-wim"4L@ ݘdw"Nlښ2PR()!jkGm q<3dߩf@Gi].A~lO3XGOJ{"|6+5U(MM"Buրa,g[2)0?nt0i&9 ÂgFS/~pFuY23lB]D)ۭb/VڪD5]ƣwt+^Uc h=yrwXBXG ?Èk@.\CXecZ[t::1\
-&6p~q̱Zfout)
-IJGBDAw}iO1Dq^ո읩:_Ofr|⽤ClߪDMq`O{m'Hl~ju"sEy*0ae$FKGFކ^^w0^}5nδZKQ7N 0)ΎF)XF+=~?~ZCˤh=>xaXkv}"(n'،G&Uk_~ ots(V>=,
-/\lR\ڳtmgFNYwJKY`D/)^R2-kjo&+ye _%#hA$61ZN\>%OWG &~ /&U QuŔN͇qXNx
-5N}o(P|Hq\E25!Hb^5!;ƃVirG0] iqmz`+
-:n¨8vRN4)} /︴5[.~3L'cn=SW8!^]/ؐz0yx.}<HI1nޱc9a}C]蘪5&\ʺ}%[y ag`< mO$[|Ùv<.}y#O;$'@5 RA.j1KGE^N\V!Wz, 'X>~D@=5./)qq:Њ D"6ߋ#k?Z ×BR[CsÛ,՜Y9%0{78-%&,$8ZTKLJbmȦɳ|9>1Զ/L}aH>{^sT~'hyOƮ6çK*Y9lxcD/ULd
-9aK(bzÅB$}gCPeXH2\*9଱cW||JaeodSqw#A[ |{p)B^!5=8 L؛9Bm${bs񩈡..L[J6{t3s^n{oS*wpφ"u5LvJuUVkuMKdbkA:idXİ- L=pD\C>pWnak
-e~GHD/_}.\'$lC.K[dc7RA>h|Ǘ=2i-J=jYKR]j+(mc>>S.κȸ-l?wLl%z*ЯNpV%3qZ75p5 P1jN@ku<5Q{1{e.HZz/Ǟ黟ȤAeI YjݥB9Q:L2~]ݚ_G c/`/(ioԋ"
--S^
-Hi
-bSr3.%Xܨ:cRiŠCƘN_8v. ̩qV6Op!{fnX (ᥰSMCF63A=$}WekMM!9(\:A,HVLB<wl\Qb{ i%>j85Hp>ZS+#͜ 8lbpEv1C'<qse\S;W
-:e0jsyM'8pمqAQh])p^KD:O| )܆3DtBn?f2r*9PO^W6RZ]s.R>
-b
-:5L͊B(BtƪF\5MrDM+|4x=z켎VV}r;{$qPzd$+l,bNTd Dlnɖw~Qa?< 5P5)<TPgk؜[LB", SADי'{mR< mdkQ#U<[2i%h0! 3ɧwv+wfCA${;=n!5k) I ՜yS-|
-Uط Jc[BzZFBjc m@!逡-?0 yY;(A)` VaG9]enZY'u)7/_#yZ'-HA׆ _h̓,}8\F3U 54nu[ov(b^uXr|gGF8t82waK>6V6A?M}pbi(JХeHhyO-lZw'Sq
-Pdc=H=HG)r1Wl4> 8
--IuSD-U~,j?R4E< Z]PHd>h-o(?HYR2;P`\Rыh-<
-حX&DcEcAR+(4W+x|p~(ٿk RD
- LB*ܭNU*& RX|3YH)DT%Lkt!" tZt%[ }la.8\ts>t@[Fd)A[Z;vx! 2W1C쬯;U.4:T=`=T7kv:E0X#5zXCEJ,2ȗ/{8%)۲dP6Ɩg9}y
-s "={Qe6V?W_PA>
-EIxvs{8)|e(G
-=Q4{Z6}4ސ?屸tE/o;gԓ;Mm8"1^[
-Շ$=B
-B yo#u.AeGM!ޤn\7a5ZNaLrw^H%rwїleKNx։G<IqHFтM[euRҸ#S^pG.?ڣV+[^ eH6rve2o8~ !M~YЛ
-`o
-`nзȀnx@qR#v?^b72Yegxl.тӢoyCAV
-N
-spw}N^ƛ,e]9 :dS^$K&us$ȱOI8_i6ƕj~ɫ6kXq+iy'e5ګi4By;$Ԏ|*孍vR>rc{7`ݎ&Jߘmz
-}Vͫ sV`& Ga#FENdDU>hQu-B8FP.ZMKE) }gEr M(kM?Y( 3BwD=M&qHȏ|^rvVt$3ePKd #U=R|XOϑ)_W LSj{1_XW0
-G`
-kFQQ)y
-JdQP,
-S7Ǹ]"
-hu:
-bdL6\!
-X!s3g?=reJs\qU[-DcS؝H7":ZIh*id|)8@= v~
-}u5oa+OYA!ocvUY:M.I^Tl_K<*9c1f@[)%[k\Tc֬OYk{PaVt5wz,O%IUluZޙԻwHߠp/bGHDž=ĉKK -3dԙL 8^&XcE7XC2d~JLw ,Qۈ'ؽXg,S<zOƟXtǓ6b0Akrq
-+7Np, ڝg/9zD@ ֟XW
-{K9SV@:>B=b$*\!pWO^[eWx|W`%r,cq&+g?Oow*Fߧܸ{b6JO3NArVv' W.;G F!7ԅ?0懸?4fsArgؔs?8ǯL_K8*vV(؏ kӦJ#$9'{4{.&|yµO5zΥ5٢Qs"|/y;5vWg4zja9?,~i1U?L#~"<l{(IEjQ蘩[=_{DG={ 2K C-0܄`"Jz
-V 75t{=ћ Z?^: U?y,a2J؁5I$
-zhY^],i&}NjC\]AAvZ<ݵىVJ;+aItNf]"
-
-J՗2z\>j5T;x@8 M+ \XirCAN mEGok=Vd%@P80uot1TD:KZ+SIl=@'Ƅen^NE3
-
-l;<P&p-w8YeCڴ[@aH/2JyF#cB&L10k|f`tƚT͌)0+!~|{ئ16P\RT7sK@?g+^UAhx[goA.ٍ(?Byf
-(ߝ=Büh** 犝f\ X.bzz8Zl4Y:"hti zGAr\syJ5 n8e܌иY
-[X(nPqM J$QaՂ9uTPH秔 }z2wg α$(Y7E-09'&Ka_]2h{L-Jii (c+<(IJsMZO gI#qfRֺ<x=W2|ynqA\&}c-KC~,oX 㒽m[ SIHl'͒jD̢u=z`Pi'lJ,ghDKHy
-!| zR`!д 2U~Gq>U\ْIȘb\_ψb 9I._ %tp{y`$#GF4h "tHaSiQWs81O1n
-SjC<EZ'އˢP洘,f1?|׉(xma¸ e8Ӗ_H0WE[b62L)%,|z4$(v,}8DLE=SO
-DH$]!+ɺ٠]{S)!w m,Y$qwlHCh YK,lO2 .Q !C" #~,>hyBBC9T'.VtG ;rIX&}& TtLt+W_= 5*9}#N*^-NLv
-uM%ZZQ{x#4MQDCGB6pe'e-0=ZP hжvA,X?M[^Z*ip*cYR^19~v$^RZSatAR`j<_MzRFC^+˄i}SPde% 1l3K-z)JѭWM= 2^rJJ?rMC3r{$SbPN_C2gW7#[\9G$VmVǿ8X;IHsk|ݍPKԿ<S~
-d–DaQQ耘Aj_m-5C,}Ayw\tmk\$EƦNi~^7b!(r{.AmXbǬ\|
-2aHp|?5mXH^\u)qLi\ /j?&}SNr1QrTOR^asw#c>S^G'IwsDݿjfߞ#{u_!Upmӌ+|NJB?
-~As+I,7YiD]њg]y4F6@UU79=Й~peT yD☸~qpH
-k
- './:աpHq?-&c߸)uI Pzw+(fx潣]*!PhT:i7)|kse$iM
-B(wLk%ȯaB]6c")#
-^P 9Hjv ^w9 bq!ǜv۳vtt+Q]K7Mđ(Lmze֡74Q_z"g @8Ec_bbipM E﹕<@u!-iq"(3G< A[hb,+n}s>?ֆl?>a4=b=N^ LHܰயoܶ#͝7̢şN|p we7T''eU|qq9˕ 0_YPqUD8mm/v
-jM?c(.K5U:B:rDє G^pI'Kqzi'h赺)U{Fb!WfV%Ncu@)}6[ i$:1v=Y>XWdR"fޟ.tN=v'o40ggTf)^MHL1jDF
-.H "-u\'ijۭ俳haa+[7qE%Na;d`*4~Oc]E(ԍn˦F"d[:1-w4nI-ݷ 17P<T=mҍez sT#yZٱ&ƥATTu{KY5Mʐ -n!Cd"EXStEp#Ka ZOcKŏtQ3W-XTN}J4`(ܱRگ5 33^&Bq]Fs }BAnvߗ O ;Ե䟉UcC44<(ZErpсUyPCɭLJfzY
-TMF7A_M6f.wi6h Q`
-^%ke VP\ :KHtު(0`GTV
-D:,lI8վפJhB `YmL]2m6XtY۶Iڟ)ZONGS L_xU`$*@p9B@'TJ{
-1DoSɛ SX. ,A$ٽ{ȟEKnF]*5Kxrq͓ t8>+wqm<'-^^V5c;<TjaZA"m*RzekMfG1*9SٚǴ3n>"ޡw 
--\~Հ=GgccM*V:G&h{fKi5%rk8]v0"\D~ƓA+fTfcry.wKPQ,vjڛ=G+T Mhp3{&iT)f 2/5u6+-E Lk*QE1(,[,Ҝ{p!ϝ=S{#<t$ ;ƿrL+%cѡcl^[>!Qҗ#HqR!W>rIKh!dܫ
-N{@x[Ax+sU½' >kDe4kKHolO'fNWHSZj:ɡڮ wfڊeV$LH2C;`{ %cfY9T9+p0D$Q}IVw엦
-A&xyr0Dqq͐a.lR6yPgSzz'e'&7O2,? Dmzzc
-3Om A x;GA(t_<z|Cm5Ζh țWbNnsWqG{Z7֡/r]%ԬN,V:^_rL5o+.tӠ$eDf6P ۭ5o
-Yd/*j$!hGu|X[x@-hG#އU5L;"3b0:*Y8bգO;Em@=]]jfpt|T:N][+Lt#9q +kq:?o.80
+xڴuT>Lt7Cw7=PCtwtI ݂tHw׋}ֽw`xϬjr%UfQ3 P
+l&
+`W!@
+VQTWRgy bov.jL
+=ٜ|bfRȾ8k]4 y
+^YrFlGLyt66H;(nF!#p]XpОûEMۇ%r`q78x P9oQrPexBJYa]Iŵ9(JXD~rs^:U -Ml5Yғ4"p!eű`2)Ѡ3JW!k:Egt+@xPBO 2g1|gYlE]f"';>ɤY
+ڊɛ
+H7q ~vvhģ:]v?wR^W$SG?)p}:b j:U,EÀ&(d,=iTi)o|
+UȈuj0ߋ2
+<̆]Kj:'ҦU^)10@0 z#x7F/?(Dm>%;ܡ>< m͇~]D6,~oƛGYaAUYOoX?/z2:'[/Ҵ6lDGxwàܕ׏"
+칷]eH}ʣ @܈Y0?i ft
+nK`Eu»'2JeA<g~?"
+TXkEm$-BJ; $܈VzM<Hk)&*np1xpPɆ9$D n$?T<&Df~m \\
+ރp
+v=k~ hwoZCX[yƢjS{t}!2aqeibDo\w-jюȐz}}{W]:RN$1a{K\8%0U5T!SxG : VBg_Ӷ~Qg÷)S,
+Y7挏1uP'C'ޛ}p 1._ཷU'^ž=4_8)EF[!U#20N?$3ʾ \ 4iuVA]1CܘJt{?9I_)XDŽM:reY9R ꞥm#!,2ϡ !ePLQ4i0ٳΐ>;xbOޤA).B\<lL{s,*iU.wVܶ'
+&4do}L[ٻR:;,hqOt5'DzlB;h?eM7Ԩr_0hB]{1 >ƒrYS#\s=P4zI xL1pXwG MKnQɨIwfa[dCKT;5Mu|^@C9Aq$[JVq. M8~ 4?i9u*у H:M^Aqf>,7"A;#c/zY֟δm:h t"]/Qqewgr%sXJ0艱- "q^7~Ru#@ wb;lIB0Z`C %Q;V^x{f{Z
+Y
+ #kO"G^u49»nKAK9G_sE*j
+A)fyIMfhD .௽Pcw2_,JCflT )@a`6)sTѴSGj[3K"g~LA_VS^kM (aTJ)0BYaB/$/BZlbHW{=ZWlR7+.C$[=Nf[>*b*nI 0~rcRosp~p|"xIU"-x M%Rݾ%HN8R\3.*~Xqe] ]z/xBг._BrYY*9oY@wjmmyIkV_d[q2ѧ mf.77b:=5Ғ[Iu* u9CWᩭQaۧg% dRyj2Ssz.эikgXc)4F5dAB#qMX]GϤ Y=8duw]d IۖM aդ-F5Nde8~r@TY`".P4=X"N#\-3en!_Kc&%/&
+P ;lѺ({fR
+2 Z3WX–`Yhze$ |"
+4_FNsmf(i:j3dQ-5< 3BQWdfb'Vn>~em4zX<OOq[[e@>W"~@+\&MyY(5u룀ef Un^ q= 6uǼcH l]LA"R< ?_qu=UQ [g 0˵0v U
+x{'WA`rD;:UšvQyt˖,դ-rTn7:g_z6n ?3:Ї*nX9PM$ʭ?rUY2޳zI/_h">?4)#ÍbL F1,I &7M6}ZBtFzl vVxVvn- B;veϺ=ۊ̷<܇EoBKi !dOE 1H2 qLV;':NAhw5/{)`7h]yK_7
+Vaس >pTV0Bz37Dj,feZXUI7 Z5(b>KX)s9PIyt}::j\'yVúzTӚ۹ Jd
+kshꗍ6\Z6/P;TÁR}YUKNP|'Vv.L F\R%":4tEuSbE=/Au=|^)B=ޱ{~<MD8qs+ZF4YdXkՍ 5ܜyC1ObH:X;Q?WUarHs~"_?ZģNEE$yp|BBh:Dl/ݹ
+}n ( ¸;ulm!zaZV\d]Fe=雰|ːw /
+oJd/&7=F1 F*)U덫WAb)ι4`v ;l 4% `lvs69JӊW%e1:mop{%ˇVFL.~
+2ny+꺛dЏn#<Mĸ#jNve/6Hց/1>{uHV :2;a"_-OqydTF{l/=B'{ėʰ0vkϮ\fB=ny{ ,{3B9|4k#`? e@ebRul>uh%4;\qLB
+<WU<:J yH7' _TyԘuc^Mۋ:],<xcGg_#m}Vþf=.ꥱ>NUZGU|u
+WA}$
+C>R9W0X4.s6 |*`oDǑf4OHUx&u Y3'2$F$:6#rS6<.ьcN_>a,$w_+<_=`-2_5WuC1իP3\ߐaO5y_$hNZ=q_(fQT8mjx.>pZ.Mhh;9I@5<Ndww`t<:EKeQW&P< BY(nAm6zJJbd2^#g
+ _ 2dt7гZ?&L_J#?ʦ'`ެ&rchCh̐o6;8g/=p)Fon-&+Tp[s4@'8IJlA뵐. 9.@.[ZZ PRM0h+sbG":8}.wJ~rk2BH3hp8Mٌі1©WON3*5KpW$]
+ nUYA{$19**u"em V$̱,Wy4[&*~#5nڀ`3$'TSqdV=Y>o<QTԏgE5KF(o_PǤwMojiNp)$L ҆X#?#EҿiY bqo1X0Z.9n. W0Z]7Ml>( p0=v%9PaIC S@Pj+&̙HS"
+K_';ͨ z!DDϺaT
+H^#Fp[DE 9UXOXwB\ @C9_s6v8O"x~Z^&LsW}DH!ҮPWR}^@r^Ar]ug& EfcSd+dHtgw$<\f'|l#yPH:ihNf}֥w/zX'vYw\{)vk4Ff;x@I.>"nK!L`jz9խ۩j7c񋿆M( uC/WG텍M68V1LުyNih$i"k@
+LiL g|`b]Q d%ߵJS kYҖu͘;8r2QS|觔߹%c}Igl/f^;팯V>X䍱r!OX?V}7ͼp(|4+3f*tW&{ȍG_o*}dRoVgθݾ3"Rw;N2bA:)aem,ܝv)S*#7W“x 9]nD>1]|!R$^h~pNN~:'.c2 Nd}tw#ۼٜ0ko7ǒR4 mxn }|Q}{YKܽ*&M {K2K~-4%.hLONv""WaQWD+Ȃp3uxoLf冶I&#kUj)яCE2@uj})/4>~`|qn~{_?M4!AYԨ.ޏti{Bwj׷Uxh"ݕ_!jcFNEv'e]Fx?M [6Ejo*nZE[eFqЋ֌Py t!βQEs 6ˏ1o-_X+R܉4)zGnLfeRdӁ|C:FE7V Ӷm-ϔXg߀r,H㥭Ύak<*Inu)P:BV5IuNR #,N(AO}f U΢ }f܋^M:RZe (,%YґrZ7
+lfg67rcFtH|"pf=&?s١qo0*KD ^Cz[g!QV
+`-TBWN[@xES64ۏ}QHLf`Ye?qYIȲѶ減5qg+Ej9jCeh6!-"lry'ut
+D`ĸQiI@}#4\6f>bIXxzW65g-$K 0 n߃vkĵ1Uj-L-As83%F r `ElUKy6S@vZ|Ǎ,v[ŧMBug3D=o?>c~r k<wX
+=]J\dgiQa$USP%[H}8t=0(m }/A[m>CTop`*mV@y)!ǕgMo9pnLHBv={^u:y2<o<)Έ'驯tQ(XQNؙ̉sUT2!J;5Nz[Ts=raa!5^A?|%Z\5^ 
+6[&0_YD)G\i!7V#웼{0k9Xϖ_Lc F X]brBF﹎ԙHR vi԰jGLhhm*@*Y
+(˔Pc3ث˳9Zd כHNPC*2aȞ0<7'j:ޯ ur|!5#{*}
+ʽWŸW$P j5`O3>Z~?w肻i:eJ]j
+^Y@!d렍HNHQ썯sQ<ԪP%׊4l.gYF*թ@JGЬ$AYO
+.3Ζ`d%Fȉ3ɕ
+k:p~k`싃jqÌDL?SaZk -ܓɦ-^0McXuatcPضoh&iS
+P;H\-(0hY#@;-d5,4GD » ଑;5%QeC4&Ḃxf$H_hĆy+@}@g1\M+AK HGʮm6^Ņ\18
+^>a`(AC__aaX$]@n 8%;mk7cYbM O}wƲ@]FLGj>t"Uw_?1<?GBylYo=Hj&s6uhEf#(
+2>O%jx{n`o^_e}U'P5] 7Yxc |k`&sEp8|<OP7RC_]5֤ҜZC(3
+|yaYe"aV6.Rk7ȳOI}: [&2DMJ[ % r|w[E-:
+&5& I)2MɲZ;!ccc%A
+!]Qx0EnjJ"$yy#N) kV |un)v4s V d&r{"rO/ds Dք;VGvڑ:68G1OoƁV:Mޮz0Nf-x5gSeI2ӷ"ˡz
+X4 , CYodg*DuW7ws,(0F80Z`ytQ Uw{!>>s<(mʋD#5y)FgSo6vtX5з?8 +$͉bHz,qi d\觮1$0<AYDSr¾ee9K0yc1/Kmɿ|j
+(Q ]//ڲQkqߟ|g*7q~'Q}!]@$Ã"'QJ;=w. JN/6Y,wTc֋Zvy0CJ!&SKd:d>)2{,'H
+y5 x$?(M*<o}̧2왍M@!4Kvm_Շ֊ɖlAtКM{kW\s9whJaCwV|nSRDk==*2UAP`wĪ?u~MGWѨRAY-{jb1 sAi /Ƴs"}No<d#q
+u ~Y"Ch{,CĪ_.F呀ކ50`Zv&  f"XS3h@]eg$$A3y$3Trt1V=+wvLH2l0 >ȝ
+@q)H.b kR, 95)CbQyܖyLS%A0Eon?˄8,S9AV| ̬,3g6d~暒hKv s<{߁$c%;kDjhSkف:LǵPo!9/)[>B9" 3؅BM0 L
+{hf;:<Oݗ1-|Cm>=p
+w8~AV8EX o>i0([
+u+Og7r0H|Xj7,&rȶčhohON85 Pr4o,i"> =y0xjZl}*`1(䯉=6(Y/#w <te3y<<e E\Qn%]܇~/mq[rI<DnlMJ|I3%\Za,8?.<l3YlAQ}]wb+j6yI%9;sBPya+|?i^cwmHC%#((Yef>naOZH''_|C: k 借\.G(iiE 1e C@NT*ٴț`x4U\v/GۢP%sJ. U*XMVƿ&j-hpho}e qiPD3[:>Fo
+I
+IBԄV=8R`Apd!6z<A36m6w98NRO-ŔbmߜptkFcnгKnLF
+*(A
+%l2':o
+l3x66; fqv RbCi$d{<!OpBɪW8KoWMd;l|2wO2HǠ*\k;v〖dnF9nR;qWp,`˒#tW"<EG7vD1
+PKSTIWWaQi-z`ȰGF1 NⱡS
+FSj:^ona nxKOeSrW$$C#&'4u痵=TV_CO n%ֲ^DWIel[Ig0h+TkA`uڝpSoVI!#FM{oe
+Rc=H;
+Z"J8VSܚA
+sBL.xB#Vo%|p>
+3# 4޲'$ptmri[4źHK6o|xY)OlOMF
+ώWU%Y6$Ӛ=^ ?)}., -zdnhlDZ4?H7
+:5]M8(Qӫ|#h`B+;G 뻫 4 ;)?[1CZ\r&◒I3MÚ"{_Go+"T<AR_}@Pem:-cs1h!R8Y8`߲+ PrmZt5Ye[ (d _bvO`W.ݗ,R'H Kx`x{#<UT=&=cW}X~j|E~H
+Q1o
+_Ц^Xߜ;J(T[I $cA0 $'`Քj-oQ.6c8%κ$90\Ŏ1,XtRL`ͼ:+_x܆8"t;LPoOJZ7e*c(W#'h BQJ,(|@<"EL#U1
+W:ED0uRibo.s/H ";A(EökݡޜTDf~(V&onA}B( V~\7-pwwG"[ͅGEYugAt] bJ%mrT:kvo>Wo?J2ǃU)]|uҢI%v`O ;;K6(_[HzsMYl(?9 _,әЗ\A`[7my0,6_P//8 e>="a?;iӕ@M}0Zn. s$o(bXk|qTVFY]#P}͘c7v+@8m;QPr ea+S\ߊ Zb5"i̥Cw^pX8P@bE< W(W;%gpA7; ү-* ;pg<u}QLzw:1HLҔ>|XB 1xg*!k2h#ugn̨ېs3}BnZ)ic#3!]RV 3  it[ptL bh8T؏[[tZmyţ3(^cA!W49P/<ӂ M
+!a d *gq:fSyAy[%:1dI
+4 ƶG"pѮcM*M/{kIE 3~!\8 {Ae-a\14uHFVhLhBٰ#ԉ02wOՒ o%Q*<˷1f-<)>Ν
+| lA^5lg޹MY:JAj 5m'S$ksPj_7;NAGQR]=bp`X8t0  e+fp)9r-,Z bGƗ!؅mh4W ;tz=i0uc
+ -#xnAjx\T-G6H l場HJ4"(];mkSvAE9o*`:Ek6fZV;UsqȀB
+XG:3>`?6ߤ%Y_|J9+ky T,*[cPLC 6'绰(}/]
+J5q{zϞw;S0I
+uVrzyW0'(׌{I}+]A1]߹谨/N6n:B$`kXv[M@0cRɧ:Ԉ!}B@g(s/3U꽿3IaFVa`TWxKRmg4bF~k:YQV?G^[&$  !PRi3e侫^\g?"XwQOnܿʼniN|=;˙ˈ'@`ZK)$5g]?޸Dx<,~7&2K܁ljolHFeK͇c= >ٿځx؀'>QKcyi"R/W_gw:@$E[kó V 4% Qp >j[@ٌ.C:JrbwDt0WmG6+
+Ϗ,.&}!]U5@<1.bJX`y:8jjYM7GݸVF?xHM)'}8Lss9w_aG$,_5a7b |y[M|7udM&\6hL~zlZR/2qy [5d vr2*UI2,B윢^:{Vn?u.:ˍ-Eh #* xrM~u=]+Uަa213
+R a faIr ]!*B"
+<.SG;b7|U[ǘ5C5}Etш[fQ|Vrg垮
+&hmh, RrvZ JGq+Kj R' `Z5yA
+šuϱjCwvoƲͺ˴NZ >TٻxY'M `qHNU'[\DR>ϯyl^AK5`BW.5h?|z@\iԩ(u5X?li־1צǏĥ? ш@uJYcGgwhxئI#gOM@P.KX'gTOX'jw]$<V'd5&
+6
+j%vm?PmQ[O&#*)]+P*$U]Fj$} iQ
+J{YS8L0ڧZؤ 8sF}IjϬI-WkTq;۝aV k9=zu[l\P_iEeRW
+^aӅ?䍏5[+B\0Fru FFhԚ=%uњx3t 8z|WF㧁sK"|t*qbD.8o֔N}C{?j#t׆&y 7͸e7
+;L-3ēpôj`QXy+dyƘPmF
+NZ}HsQ#>mM
+B3*7טDy-uY[ u
+ $HJr]͟OUH%Sܠyw{ ym_A '<(Ҟ5UAT\(ED?`?EϥS\bUSMC8 oVޘxSp_Xa%UB OSF{&~R]w^{0dsiWB=: EwK›_e"2װֆNu })J'AE)nhƈa[AKo!ϸW]ڸXץ҄~x1LSRv-ŕtGSKuɥɁv#/gIV¿x|M@~W8Dmz˳1m@W-_ܭ an`%?TвWJ,HU#FT$VHPMl!5VK> +(bqG~pDI&$n@znR/Ȥil=lf=c xlYܽb-KFFl:y[қ
+tUJwo1ʤQf tHqѳ[Id8Ȧ>>"t+_Op(,.(
+/vIorv`'s$R}x=* 4(CWm');cV({A jW+>0e
+Vk@7HiZՄx^찰n(% e[ ' Upy0|e#{
+M
+6mJ[Ua<WZ5 Od2O 26#$.Lѐ:m>2\,Z
+~k'G.QEDAYFԳPVσ*nygX&֒$9hÈ\`:bzR nflnI}(b2kt`L+ϯaؖ9A7+u찔02Km3ZLІߟ=ga.c9/C9sjfURhX XKsaw%ii;Nzx/4rws?Sa^ˉ@8]B #;[~ 0,7SDaBWI|}B|dPc|fC;d랃H2셬X|a2?N7M4Fff
+%ck^xf--rJ!T!Y9\&Z
+\Edym#r|z3?:Ճ>+ĎJ%mz%& @g8Jck˲6pt{a,B3hO#9n<CnkfOAT'3۬<n׬Mi(홈t|hzW;{6?DSI
+hH㟡yț;4y5o#,z+gn
+\]A 
+hUkTC#y/
endstream
endobj
-533 0 obj
+627 0 obj
<<
/Type /FontDescriptor
-/FontName /KRNZEP+LMRoman8-Regular
+/FontName /BTHADF+LMRoman8-Regular
/Flags 4
/FontBBox [-456 -292 1497 1125]
/Ascent 689
@@ -4398,123 +5021,116 @@ endobj
/ItalicAngle 0
/StemV 76
/XHeight 431
-/CharSet (/B/C/D/E/F/I/L/N/O/S/T/X/a/b/backslash/braceright/c/comma/d/e/eight/f/ff/fi/g/h/i/k/l/m/n/o/one/p/period/quoteleft/quoteright/r/s/semicolon/slash/t/three/two/u/v/w/x/y/zero)
-/FontFile 532 0 R
+/CharSet (/B/C/E/F/H/I/L/N/O/S/T/X/a/b/c/comma/d/e/eight/f/ff/fi/four/g/h/hyphen/i/k/l/m/n/o/one/p/period/q/quoteleft/quoteright/r/s/semicolon/slash/t/three/two/u/udieresis/v/w/y/zero)
+/FontFile 626 0 R
>>
endobj
-534 0 obj
+628 0 obj
<<
-/Length1 2340
-/Length2 27855
+/Length1 2247
+/Length2 26720
/Length3 0
-/Length 29149
+/Length 28035
/Filter /FlateDecode
>>
stream
-xڴeX۲5
-u|+*ߪp,aoy-AۭV?[n8jys}<>ާyUAo)a"tvtez֘o?$ F=+4>ɿq]o
-H?^O&ITżUѝɍ7F5HAk+ݵs;&]|x"{qƘk>p@IiwwG4Zp/K v
-jqL1P.ڠ6"*Mo!#欻 \?P&4J7ia,&@\#=~)($00aj(<TYw]v ڡ;+#ĈzOҍ;gW~瘤p9?IjfM~`_Q%%*U0^kF_![I^ %+4XNϙl
-Tg/C#Frx)&'4Oqɬכvt0^H/M=24\#)EВ bAMD݄ٸmwj47v![宭T_+bCjĨT
-"f XEa=kN\n֚BJDwԘZ= 6*,+ܠ-^KQrg&g)OD!I%
-i
-yĘHbJs{ \җ; H %/XZZAT
-rvh7W"v"Eԛ)65*-+/L?qmrnuj7KIs`LD,,(4U27Sjn~@6p)%*j=,KjJUR~+sYmlV=].@aO>E]E3Ir):)b=G k&'ŃҮ'}Cos]OTrPJfy/ y͵ҙYM0 ջB]qq%BzaN!iKr՝VvmInq~W/FCh&?CG vS01k[&tWO 9\ g`!oˢ[ .MlKe/`Vf|يdU/!N E {?3gA
-fIAgŁU#FR
-RCğ ]*
-dQ GQcNC{anB|MZ0UԨ UG~ajz1S. '􍰣2Br+|sG8;MCUu:{;y4KѶ0XI uO43u<oG".C+Zǁ~ j:\w
-[ L߹+E87]łOsAncbϘu_*B?rvӧy2]ۭ ilQkcq, Mc'(+q
-y óUdfOld%`tdy
-Yjel nFﬦ Oń/BABMcǰT{ALm#P7Mk{ֆ|O.w~"ϩ0꫁5zn;zK.lkqDfe)VAĬ_%}sc+}m)a,ŔJ 0eFrr ٜw jW
-/_]ot,tkk;TnrC=kBkי%Sj{IrPv 恦=:6v^"pw!"EɫO4ȢKӜcg(w7Tr@n"hγHę"#p149&6XkMh`re|Je TxM2P׳m~xXbBr ]j}mw1^E UvN!?Ug%tڻdu. ?$yCVӆL1&rk KS#y9;*,1j,G.t8r4Mp<:i4a] AW$
-BNIUMmEG|y"( OCVqdT ftץBKAbpiehuq$]DX9הkozj~Rp{m B_dj%R/Aɘ*$8-گL,:2߭'|Ch$gtXȀwᑙV)yzmBWG-Rl$O4<5"cn=nqdΐl42-"XXYiNKy2HFG"E'y{`NJaTeXE8Rs@d+sؤ+Έȣ36A8kb^rcl9)oqb;>_X^%aB;W}Cn'/A3%Zgn] =.S|Uh w 6c1iPom3|m2+7mҹl*/jUQ4*h-nNן.#u &Q?o :AoQZЌZtk!N#+ ~H`ir̀Lhi  bmVQw!-ݖZ'-fx^N'3e!(!U6H%*<`S2ӣ8rEE4u9F߃؋$bBIy"WZm8Yn<suL Pci_:X;AW?zѢ>Zůnb)V4:b ѵPViz|\, ^efQf^;]p?eqQ~AVCXeUgd҂$&NNsӷh{)l͢ǹF ـH-S M2{f-jJǬ-FLsMfOZGC^1bpB`B-)<~iVxߧc֛b"SKsCټ%T(.qlAhS6
-#]b}y}D؇ݐ!3-BQe‡ B/=^<>S/4b#׍KnNVlXs|giTb3V!'d ]Zc#"mVRA.up]4G:3259{=VG&]~^E<wKI^|';Rsmk aw
-9Qk+*/tɇX=@Mq󞀀H,ɩXl?x3P
-,l9 d|(۬n[mMf
-u 4|z[B2۵ݽQDu$uG\rOu^j* ͘e%N㷣17`)rm:g\I-@Y! ڄ(els
-Ы )#/Ï&"}נ5¯ר69F``%JZf1,!TwF]侙P"a&u9z˼Vc1)o$$XD.~[jϱy aS3cqxJ. 57[pܢ9x99sWyqgka_K\G 蛟B!*v^ mG{sN8AMz; VdRfo r^^ӯa֓};'f'w08lٖ dgB}Y,2!Wju7SlbJTЈy^ I1>N~ n}BD'[-D֗@֤yhl 17OLVCkLLjk6Y':怘0^H mݨ,{
-KZ C]7Y<a!.Eo z:sEGn&jּ:kYG>&b.{½y-3 ߆BavNxYYΖ)PCbTw& 5fԦ snjY~Jdtzne)_|w8A6=u3qń^wjοdWjWŦ7vu$)5X e |KI
-hN lqQVFJ6=nrLzORڹ%dL̒>!|nwֿk?Nhh_2;3|Hvi:r'ԜLo H1NF1O%ȵCĊstT>Q NjEFP`"s9Rf7-9+7׀FaʫZKվ-_#x:iBOdN,| +Mq,]Sz гEkJ&Px
-
-Sxd_ ujW6|<,[gMx17Fk̭ց(9,u_i/%㯽 6
-%eFB'6"E:7'ۓr~-VU i:=(61Fv%
-U"kRHn n +y:x
-gR@=oJa7Uъ|M̎v*8T&htHs 54xj1=D&wCet\ ǢueFk* C'-n45XRhRvץrJ[҆~tDLr^!1ZDxH#1p#w͒GL)=J 'z4H8}jY
-7; 
-^l7_/<7EJCCJ#Os%t L E5V/[\ CqlܦrJޠUί횚]Q;#K;6Mezm.9K-^
-0hKdP^G˫t.ɢ"T~,8PUc8S95h2x=-C1~XEL;mb0Vz_4n%P4Ak`z'AIՈOf ÷
-cV*t)ǟ8K1du*CZ;
-
-Y!sBb_I0H\lp]mv%m0[tÌM”ӐSQf2
-WmC "p&ٕ(zHoB$ֻ89jMBݮTFB|TWf|;Ƭ 658vtD>' SKlW~>1բ'ߠr#gAQati^ޚ8U<JشP|10@t˽*!*ϓ5Z{o*7 2 cc]o7-fJV'h"%c"132W/9%\J$PnjMNkk*\j6"!d'qm ^P6Sleǖ;X=f-?t5ahcqI)
-n TPWR0|GVm\0+@jDvjy\nZ#cъ[Сa% 5\&u%Ѐ*um;QrE<m039樻n oWܰ r@L=i*MY~+3ʒ.Z_ϻߎpъHC=(] 1[{=23_H²0<IA<fs30ryR94o4ηeVD."x駿}|cɈj_ Arkڗ}PƼ53Cوa0jaA0h2f26(rgx\E@B= ^hhb9b.ٹo9$N{wtEsH::mc$i>R;{?(18T|>
-5cصG7Cf-< !CUwf=(qÑHCUcaXsq]ޏ1{J2mc(THɄI=㾢zQWLy-ߐ\(Ue<v
-
-(z {͒r5b}F5"_gE0,#zT6t>'18X{=^3Lɺ11^PGJBJϨJUߚ\~û
-狘BXh._ 35X,|V)h?.&X'%髬x^+UOMw@͋^2*X+UIGuaE ٶ9,Z5,6œv6eE[Gp&n.R"av+t dytj3^ZV
-mr]NTA-MLo%z[>p^Y= xMt i4b4rGl'tCǤEֈrn[H:9XbNQ6xh]fj?U5@>xT ?I7G"LM,<NR*^5|V*ޗX*ʽܥ<4ݮ%tŦyA+0] U{2YD^voK"%y멉b]B2=Fŀ+z/Q/~4fwW/Tpm4FH%
-'ERR@iƒNREfeU=uj Aj^DR& Nܙ>b&O*
-LWzG>6e#:}[ӑɋw^G-+%:c.7B/>9ㅙFK=cpK{쐶
-ApZy3;/\ܓK msO(26tt8DIerhUnQTu Dٹ:7N
-T+N6;h0ſy,5p4Vrm: ϸqwQ/<D0>TLs@A5o`wtAC^|@a>x& >Gǜ^ۖJ5Y2/MѴ|uSQeEsdy~Q*
-@O .jQٗDŽk}5䚕G/:1vJ7ct3F?<s`fo{'.]qDϛ% Kū a+d][M>֣c|+7Yt쑳[ʘ_>Ŵ9Z'{gzADRa,aðz\G̝S t6۪tiir?b቟} cvPmfաR6:K^AE uj-^o(VrLS,wMqm`0^Y/ |r ax$uCy; k+46/Π̌8F|rA,?ktɧfsA=˗dɌSC'd/\ 51*$Gix_i'x҈ ?)x e%TzO{)w:)E40S/Z7G Z6]lN: ++heaʖ0,_J#cN{rpJ< wΎcx6_7heO=ab"Rs cPˏy t#V*(W^ل+&D^߻S!ߒ BN MTM#~ީlOX Z -(ب+X͍91cĊ^6Kvxb%ZQLL 2Ua[5Lg7xzKF:d{+JPjkXg ~ }Ce03s軏X(aF
-7n.فANg*r7rwTk&sSɗ_sP=wL'9I)
-ZL(
-iKdl{>:%rݲпKOY;n[]J&,E"=ϩTlT1.?_k_%4m!~fΗx[x(Rn& ,G:R<׺ԑ ғqBx9|Q]OWxQE4=ʁ>?wҘ@kT|h$V4G&i9*|˃<np{G2:m2ԭp.ݘCWW9 u(UT#S<+qy*AKk3+#kQ]{<mXE.p[ڢ+ŵ"\7n|9f^J2"WMe] C%'VUhreiT޹փJmӆЧCA.R8>E?Rz^ZAInF3EWҙ ߉:3*mE5Oei'
-3V9I yzKMV:V9mm?1<%m'7yfRI)E] j&l#19/WØ?pYڜWWOS?d3C:
-~K3`
-7i 5fIrk62q3|,Q
-r֬j(tL_qPu8v%7$|TJ#P\fR,ȖUc>wӑǠ0cy#JB݈Y`32"Qt8x(!o{1a
-΄N],1/
- HZ" dc[rkĩ'4׮޹<xJt)ѿҍ9[)b5mѿ Kn͐j6cdnna{ԴỪ)Y AǯMgXvZVdCPNӧ! 䦇ư, ERًJ|܂V~BI-iifcZ<!8 '"&#'ۚ([HM[dE \
-[FBmAR)XA;V
-ʩ=z-oCA긴z%rgT>] 3
-$d,. l<\f1?ԕ&]
-1j4Ijwsӆ-IMb"@P+ɂ=ZE4q;Wj'p<󄗃OI%|-֒a4gxiYfg
-w}ZclosB˱*
-tݮ&[H_"6c܀ZꞓFgeH O&WFHiBR7( O4Tη8GCxSSIE)vŅ́\bȟpaLc<3fڴqתcDsX~P?MsğEf@eJsuiۤv5f~.v6SRo_:
--@N^5+lS.rkUzr ;݈\N{Tȃv  $Hh]IOЭJJ^:ދ?vRX;`O\PdGR/de)p8y :dh_NV`PC|7i1+rf]+w^k?E|͇L^J
--OwJICn  %r0z=.Ci+:؉evm%(+$$Gvu>Ctl?/mSyN,B*^T~m:IpB0/\vʎ"*@TZ V02A8L&Xk*CY"8,*H
-21-F{eK3MP}}S*OEz ak=Ⱥlf(v@eIkPy
-| wnBgAwC>#Mr쮠w-D^d-YS!jF&JIY| 8xCmo+SشXoYȇۜW^8ӦF&YB:۰TNɗ3Hm| 9L,-ÈGk
-nnoj
-cIvdZ}Jn
-.<&|Tns_W;j"o($;*kpq
-uvZP ڧeC@<EΝ3;qZ jOh=^O,|n<@VcEi*fOsq‚CX6 W{c w*oOx"(^]
-7ñ{;&+ֻr~b5ҟן@O&0s .\x-_z\=bا{jHsl//;\,-AJ6!Av)E\)&x}haj,IQ` %l}i'Nj=^.}90Y6%oJWtvܥd$@fS҅>5|uw v֚/bLq.{hc }+U7<Tq%{i^%wH\١a79-%t$PT3<m+uta 8-ֿQ
-\i<-/NV5]lU<
-ŝ? n@_ @(θ~K'bA6,%,g6x}P0S#ɯ٧-Z=%E֔ VGbFQ)\g{{Mr@0RHl\s͏#8k5}$c"x;YkPMÏ<i
-ڜL"a]ۥƇ\m͈V5B+0#D<ʢԹ ׬BE qlOEZ
-_̉9q{)0mg%?h50
-*LxLl<%| iԐ7؉!8 Ūoɓ񟙑>e(
-U@ٶqV1Ӣ(Z%GnmEW+f{-x*K3rLjR][? -HI5kT&Olw\ FlOO>7̑k-O_Z뢩$\I3 H"-C0 @+ǦGsh[(= )ԳXR=8aISNU4 ]
-@gj=_5F5peܼlp\-l*sE˒B" ABxjY΃{{4~/M
- eYPP{`M"g}A5?lvWF[}\{c
-0f!ܗ ˃
-LsKQ}pd%ʝ`Ob\$΍l-f RĎth Ѳwڷwf?4 s1j !4?ӈI;]o0$ Sօit*[: HOGct
-˾ syB{uM]ΣE
-\ M r"Ī"!pTi9kW[_@woi}`4d{_08i|NzD+W矅 ?pxǽf}q
-6&^R9%C_q=xqOyFqF)WMa2@t
-DU6^{˲pǗn]1=k
- b* xTdAAݑ2b[c;Nixoa
-.;ַ-W Os
-Cin0׃"H3/qݩj+o' !r4YZP.1谣
-3 DʇH@u$D7[q#,`Y>ͬt M 5y}y£ ^b(q(i"i"=Ky
-Eҗ-'՗
-R&o1To1|-XU(#A69z^WGoH}ŝO_m?@tE/5RY3:Np*a.-cLSAd, Cn"뤮0xS6; 1eUc+Z ũeR\J1vRNX2?v}ŚRrWڸwi69XMԯ)Ѿóܵd\TS̅HƮOe' Z,;;&{uyXZە\s_]Ĭę
-MMa6hY"RD踺)lb[14[&;xMG6Y if煤$)/d0Zס+
-*_Uu:`x \abY6-0OrVc4Qr !VV{dy>$ Ʉ;8+ %v*mΊ_NDeSZEE8$9$FέM3)M0^vtG@g0doIcuLմbg Y•,X=!I[x/&{r!~~WMhT%mI5{OȤy׿}[sdkjVu0ڛ\4h)k lT HǍЁ
-a.bK0ty\sӉ ;/7ff҅ |~HK]θ$`Y.֍Gi
-^%\PRotAr}|mjJ8_R$kO/}wN^SC4Wr9j l-h0] V  ˈe6^/ ]f~f/qN8I<V
-{l1a I_EP{.<VŖ5'6<
- t>Ra"vW,QtCV)
-U|aDYd00]4]iC'%Mt+׈t٧DW
+xڴuT۶>wwVZXbŭC/|t{߿ \+ {u&Q3 3+?@AQhǤp:ؙYY9ĝA@+{ b P6uys}`eCHAoJ3'@th [Xك\=,,]`b鏷3@hj
+%{  'UVf` tڻQ\=
+WD=ϞY%SUT`Rxk<{&E3xe'? `}kRI{3q;7`?哰z'k{w{+773Sy3WGM{+'WXY\
+/ E-lAoH8پc0q%MmA`0/ EXdOe&io`feo`
+\!D̉6"|Mrpa`s@u _j}UjKJOяURGfPB@Y9ݾ\ΩVRqXW4r֕|X&lg[LtvvH{`"0r;!ci$iV4#H$e
+-$ x
+_lRϱ8Ku2
+y_! l\iWLy<1'C7tEZԅx<gb8N ZY9KV7 LTDI(!C]ݻd~ 0_
+7!+
+m͕ss G E|DܾWj_i^EyG. 2N]|ir'!vσ
+>5\X`mhǴcABőTX {Q7ax5qs;XU$6In w:q#BZQBT sv1x̾ Or%z|+7EtB3RdvET$
+EK?.քc/P{h./87HaӇϑ l9j"zf٘|>NEWQMGu *.jv҇9G8gz
+Gbz BXiuͥ6G~I޺j 
+PC
+JO~}B_ȰhH[<'*֚7 z \ՐlPӬb;q_$+!hw
+Ov+dKxm 6Ռߟ|3]hI[Q@n:O?hy]AW'd
++V0@t<OJKgU{ڜC>VC(|G?$h]m&$Snw*.ynT
+.;ܳ hgcBtAh_-h\z捹szlTynQ|l%+Lkm3:;SlI6#3ºN*N鄷q`TЮy}-Hx4(^+8q\VU!u}fy~VjnqA2gǍMtV5:fcZQD?Y3u!bGYjOոHrl4X:JuP_.,dqʋș#m_8+)R!j!skcd&L= 0k
+"+{C Lµ#&*
+ ާsWY;^6?=BT._M弊79zDcaRD2Z[ kNV:u>¢o^vB0ИeP"\0-7?+CS  {N;wF 7K8v7k⡎k2
+a(!"H䯐. o08]M5?,d&(hx[*k;Q
+PH`Ga deeKK3 }/ӃO^dz*E!RkNô] "6*٫Uf4U1:'hi{s 7\6S43 ;OQ]߶:iX~Bv3\2V򐨺d_q:1w9„\8_]घ@(nԛ`JѐrB+PoN׽!$PRMDiq=BԌRpZ.fASpBdL"?E`  1n .+e`Q7w x|l)6){iπ{> pD
+ 88쾏;<:MNjzD,qس2|0M6
+U g B xjۃ X䏭j )`Ԧ>0n.w^y 5߸ "\R|a]v
+駰/*s?7,AG w%"nnk"9 Z% ,݉OP^dpmgmFڣH|6~޾@XbbMi]g }h RYU |^ߜ^f~ە_Y
+$
+ |0 )\ '<{Emxj<֍cPh 6XkKS\U^+[F*O;ց6^TJ%>ôXJE7{x-Kv(e吏Ac/!ѝ%ytdK/+qAZ5.+d'}_4u_촄*KD+K:`DD\}$L-
+h}71fylam33Ęx= _#[ @ 5N-
+"ʩC^wJpqt].%
+XD7yĂ
+{#sYq!j*\R cL5b} -WH"ş!>E<'$
+7@\y[QyzP֩(EϞ jً_!Ls˫5 YJ"}I{8+{R#aƍ@hNWv/pjeM
+qk5фK!RFSwOOaTՃݣ4 1O/~TWA*YPSwHU <4hF| ʺb"z[a9X;Yy|;rC+X- P:W RZ3$HlA=!0c%>|QkdYDI!Q5)(f9!̚,ܥehFޫ0C4Xa^Ba+OJcy[Ð {۩xz}Orp+eI=ꊧ}JL] nG!tVyWΫ`6`ʛaQU(QpL{v"`>k#w"y@rLF;u"
+F2NG17Zh/1)e@Eewp`<0}euz>_;fڨ#I']k$Ee 
+ȟ5C
+ 3/))g.L߭oH{{! J[5M=S$ ~"޽ n!JDot<f;/2 1\wPcPQ1H%Y)4-P,?ϧe3R:% Z(QĿ0Qsf5坛ޱF.K]VrGyx%mSI M"!`
+-U_kιm4\=Sach'
+9>S׶sǂ0RB-5}'/
+U2.td>4
+FJ=d&]gGڨ0hOhY -6A$)T@_jE[a!2hyo": JVb}ǩ}*VzCܶ)yUZ@C^+=#)JJöC:%* 9IZZĠl]#t"f1W[g>y[H0;-
+vej3 "BYgpա7eN.6ۭd> ƳYZ ?2ֵa!yh&$_cV {ŖS:j8Y3)FebEeƀh)1(դ]ǻ9*  ц'C8o( \GǶ^Gǩ)LO.D^\TitF×kz|W]s*s7 fYBߟJ#DP @])v
+lQDkܺ,ܷ@?CY@U!IPZ=
+ c_MWyc1>uZ*1f_3xXvާ<㔈"cZp<誥l}>Y%%W[!5;Ltp M2[Dil-Vkg ,A_W;mQZ01^{f݃s3,=PE(qk4>j,1}]LQ_oG#%qut,0{&EdQ'L=yĹة¡D"2<OӦz ASD};)'p"A!%WJ31QP6C~q!#%PIZVUR^\,%.(EĝdVq5<uW0}ЮCXI;fӞ}6y]M)5g#AwtbCZ; '15jdaeVxiSdƗ*]MgaN jݲ@܏-^\+ӒSޣu\".jizB撋+1\吭95}!0unǘB÷҈34f
+,I&zR:Χ/՗҆f@A$qʍj-k
+)YS&-5cĥ&/T`a>p>nj뗗&H1.AJ Kpy=mB+x(D&`JUQ*|8~B
+} "3(Zm#f,qW(*0$5Yj"|1Cfng#/:`",*9/,Wb&XHbxY
+8H~
+8ç*Eo~c䝓s't)9p50NLUiPx I?!2{}pCҟޕy,,H{`5ccB No76w=>b8FepO,hٍmCTV|"n e Qg̈́U~'*ޮ8 j-lJ3쉨(DU%(ŒZ7+ҕ;.}TT =J{mW+v&=Zy L壢MS TF~kgt-Sle|)t!I Q?OP8~9]%]13-7~ i{RE %g+}[${z 韊6$ZB]뼿)5.K:3sfXJ7Ă>1Nrz6i:u$w0o ;*_.. ?~_
++rxqlK`kO".Ecd[D1y|9RZҴٓbb1|KSvмQ+iz'u7-S@
+J}U]b<<?="
+2$d-K@l}Vc!-
+_Lj'v *7 jCZJX7&pGU~ΈԴh4. F߽)Jcl.yHJ&G~B~?d'g@һQ]7tGF:ezd6Wc0FX]2F$Yx{F&$F֞;~#U]~珱}
+HߪloVO&27},LPЯ]DNQez9px=s~*1ЁK{BKf<WZAbGSNlܼFoaۏTc`<ߊnMP3$nC#Œ*4zzg G{
+qsbБu=V0R0l+fLλ2OGiC$O\iMLp]R0e|uz R
+,mC0j(R\k~ (COlں=
+<&Z\=fQk)nm-4t0ƽoPCqNW߯:OۂZuGB?u3p$5c0<F?ui33i/8ՇtG0'LU* TouFƾ3(ht6^1 s6˖Ca!SbVT}O-@@M S+nqUrtY[C iso[Yc9k~Ӣ ٞb!kz;3r,Fw){F,yo]BкgjU|00/Mд 7f3y)zmDcCIzy%틠Uli!mձ*Y_rF
+FE-ݽ^G>QTcD 1GOI&r;Ks.x_*GVts+VE;~ hTzC:jxs]\u5:/pIpV8aqmck㜖+,zbɉm۶m۶mtԱm۶;6:;5u#vUkG6qp 3/'6UaMzI؉H|/u/N/': q_Ozv-hb
+9+^]Yu97=: !i#4\|)2Bx(8-0\;+@GgSlށgB9>$1t<NjPLXQ';YB\FL(唵l 1AO>.4@7?L`D*"zR1ƼC (HRDahuvKy2nàHէ@$fYx
+b
+܈ Zv+h.s|Hһ`_lGY(#WmTl#Pv±8Ezw^qtOe,=p[ S
+ucE?v7' GP*GhzڌĉǸaR{5<= *@C
+\g ǖ~V'D&˜u]?=cGyMTMLy uR`?iïLf:~cĚFTG,ۊf7ef$x~S<",6싙VNk$o]}]<)nfD^F:v;f8(jYqe7l'^7RTiYbđ
+Qi="WS @`7Ry@5D*K HX(ٌ}GC74|·
+[8UVV#z
+"mX+:-1Û+
+U72bLaR 0ȭ#^c"R&KBvrt`NJtEZ?zt=8'j.<&Mu~A*ÂC8=b^C8[a!ΖU.V Xx쾫2hW#8neL{V-uIy̸"㐁%}`W^>X DCr\)k۝8ӞFzL|o=k~O_{'m5e1bE.I
+5)»/{_ ̚Du
+
+%֋WtFn@X͸tS
+;fbVNUD i}1e¡Ug|h!.bIV}@_5~:1k cmd+40`WrDls{_fvs.~,yThL݆Pwr!;TS./п͢B%ʬP11qm~.MlY^1mj]=a~luXaa`#IDf0drM}8aA×edi'1!/KS7jjhp]dh[7ys.##je$j+Jj 2bܞIpE0",fWJ3eL:0.;{pSScZ Q: Fb
+by<K٩RLvB$Jąl 9ٷ΄>9N۬#&Z٦FW<ƣ`z'h!`LTF'?Ӝr҈͜t_*!!MuY[ues0zt7#RBZj:D1ƹXFjs'&#d}J8?EBfOWx [Fb@K
+& 0=rJ]nѽ1M}
+y:W
+thB!XA_D7i Rˡ83a\y+B$J! -9Y5+1$4$sLi>* _*zd*t^;726?b
+w~Ez\\A0\- SƦ:YmJH .abzDec)yd䐉1&=NCwK"i )yLz=>'q3+xkVQ,$ͨ_FV(L=CMTcxHFB";TIgJ
+)ԙ}hRY s;s}>\e羝 pdQfԾ* n$YɒޚYwmjJG㤐ק’¼sLvm~¾QZ Q{n1Bk?lw&^\cCiq :!ϊ)\pk3Ifǚ65L!Ε^))#_*5mSqھLȏ:^'Xk]T9;Z3hI"=$Bv.$)RĿoYG9EwdHBX
+Q pGYKͿpBDm@(cnLt[7KŐ%BkaD yWO#F!ފ)BXB3WTv/Ţ[kչv+&
+e<M,}s%NnșdpJ8h q] aAP禛KϯrqGVRʂ<\:¤ȝpRlqiߦMnc#:%ؽnG.f 9xss2{RrUr VNEwۓ>-bB=C}os'eg&QW
+g:kQ(}lޜGk!MS'4+AY6햪K4?8xVHWhZ֓=-!`Թkśgu&jŘXJ]_*K-><q?M5v.NI;<*3'"MCm!,ywSɫ(I-݌-@o8H@F~|Yh
+4#iG^3('OnL''ntq&߄|}"v{ v+ <ێ|77;!jX(͛r㒋]οfMC#c~tE~5vCݨwcPˤET%'ٔt9
+\$|ެ5;|K|z$]q~QO%(# ؠաnF6R$
+b\ ++;5ԪJ>F̈́ 6@DFŐ+22ʵ (sye*0'p^? 4K>p qT T"y;M>=%K!-sv:0["E HVZ}eBG/CgǍ wjN5Eyן;Eh)d2Jpo;0՚ 7v[cF֦Ni G&\yB I63sqYǸg*Qψl֏QAz?GqWMemJGT[Gw1= my9 T4}}ru}l$sPS2. N N^wf9?#~uޛtկ2/!ɮ;:1陕:!Opzzjw:Q]c#Pr#拻?* |o"%̚,$"6_"@f cc]d9^N)hD#5,`8Wp4|,.wmzV6}1Ml뷜Ey8w8_u6KU+1Ѝ#=9WrSN*7nu(T+&!rOMxH0aw*jgC W;}`@S Ul6CҒx`#mzY0!~8BAs937;k0jnjHb<Trp]ZWdq>#*+<K<JYߐDH!I-ܩkUS0 ]葳O 1?xj&9O aGmsJFı
+ꉢ`pTKIt8[=`SQzju>"(Qt;Wn4p][AKy@-GW]e;۞a{l1vR)`;Rk,L夡mz;-
+n4gHR/yp\0E8m[>  BBvAW4 B9?0Z=frhCiY%Ea(\ø>LE%Z0<$ݼ%P,W3 0Zy`=~F+=+"0퓚gz3." B
+a~3 K cs$l:cG/ ;XGBF(7*%\UZkK,H$ɱ;TubQx֝׏ȭ^4ղs
+,HSx7~i+mXʼn~|TwzaElW4Dh[/,)'E|בއ8T~
+Jq}(jUC!/Fv ;cgMgF!bwArrVBJ"45h-0
+=kRPƓpQHL?D॰g߉/c% jYKX+vG_uΆ؏M2>^ " X_#ۮIUtw7xRKUbX2~vjEE.ہf߷/E!en+5OHֹ >a<ܙÂAFbjQLRcmpF-PD]Mvu'`C}2CznKVތl ICx̰yGC^u5UT 5zjgo_<Ka5TtWSu6d^7<o }xgΧW @Q2(HÊ4"4*뺮 WBZ2z<pTմQl=>Jj; m\>2J*zY߯:}]}X1NzA18dU}s]w.ٰj@˛. ARYzT73m7΃$/M|P{^gzzɾGnOYNW9eu8ST6C,i5>3a$z&s/ظ H'=c39 JL'V#1Kтj0.Օ׹P%-I6.j<u3%b3F,+("P/^qj؅lڋjS2<)8+0kͷIHLl&
+ִH6nɚЛݤyVqfmCJ,"0 @CBq+wP]sY K;4 J$ M0:/'dp@Cx+#D0Gc=Lz(nz"
+ w _Gt4}v!Tbe
+RpP|1[ȹ{@V*+]։^Tdi3"MG_#+СSu0_E-.">yP J.I?fҒ
endstream
endobj
-535 0 obj
+629 0 obj
<<
/Type /FontDescriptor
-/FontName /AKVTMY+LMRoman9-Regular
+/FontName /ICLJJO+LMRoman9-Regular
/Flags 4
/FontBBox [-443 -292 1454 1128]
/Ascent 689
@@ -4523,94 +5139,85 @@ endobj
/ItalicAngle 0
/StemV 90
/XHeight 431
-/CharSet (/A/D/Delta/E/F/I/L/O/S/T/X/a/asterisk/at/b/c/colon/comma/d/e/f/ff/fi/g/h/hyphen/i/j/k/l/m/n/o/p/parenleft/parenright/period/q/r/s/slash/t/three/u/v/w/x/y)
-/FontFile 534 0 R
+/CharSet (/A/D/Delta/F/I/O/S/T/a/asterisk/at/b/c/comma/d/e/f/ff/fi/g/h/hyphen/i/j/k/l/m/n/o/p/parenleft/parenright/period/r/s/slash/t/u/v/w/x/y)
+/FontFile 628 0 R
>>
endobj
-536 0 obj
+630 0 obj
<<
-/Length1 2084
-/Length2 16952
+/Length1 2101
+/Length2 17200
/Length3 0
-/Length 18240
+/Length 18498
/Filter /FlateDecode
>>
stream
-xڴeT[5
-www!
-w
-wwwN CpO۷O~\:^U (IEM
-1 (99f@q;{wG 3sП쌌*c[ٹ:YY
-L
-3jj
-/߻4lNN
-
-C*
-SdLl h
-h=i,<b1~_H?PgS tM)ք>sׯ}F@ɢպ8!O
-@2AZ zԇ %cE#@hG7\l;-'g}B?ȦړA9}bKYό[im OgP{p _=
-$q֞k[4 8]?,2C3@YYK)bAaTdzp8/B`UDDž#p ?ʋV=Y%Mt;y1?a<Q*z
-_VMXbesKI0r
-2 vQBɨ';x|:M2>={^p>>ikW΀ٵy
-tnPL5YNM}?,*SS,0(,~8:fE"]|Ue.tM!ө
-V
-vUϭQdxmk"CjbI$\G83/v1(yg$(Ҽ|":"LȌQdmOGuV+ -"UM pʶ[ ŭY!牐)-m 6n(ӶH ˠZɜa3DOޏ/ǂ<6w>%|,n18)·2FQI8>u
-d9"ȍXiam 7⩭컈A4,:`BAtu7R(N(SEwG's۴"*geg0=M0r
-Wj_W1j<i6gX֜%M\P>&,QH\Uy->d`Iʳswd1$0]s
-B$߼zVo"Ž+$if2Ǧ؛.[Dȁ2CVBG('I~?)[ëX#15ҠO} sxC 0 0}j@A]*E0g%1T2J/\u8䍧p3T&@J"u̮@NvVw1s/>xvid˵%ce<I aBCn ?uZH3 -M䝀z~>G< Ru|DjK&Y$>'jZ@inVx<bc,\0 AvlGQ/X[%Z\3Zm'lyՉW#{_.F$=Lz(4Z`6
-Rg*`L`*/*#Tǝ xB\H$n7d;CPt?e[U/V'#WI]VHnF EcnMfBW"!xxkJcCXgHdlx|8-K(@cJ˂Z'8:%pܔ?l rf`;lWgnO9-+.-#$!"fM`({s n]Q-9SBc@տ'T孔M">syX*@D(Br r`DRmw,E<♅=eXVzvn<}y"+=W]=LzQ}Z+<FZ!&o<գ[L˜:ǝ mW{2Ntw
-K0a5^,4e0Z. yY E!;SX`oQzgiPo#2f|"6"VVo 9|B ^ 7nC`W+(!>\1c gT"Mt ~tV6tNzijY}I,{w[pEkMwg[tpH}~ Aas*<`)ݸ܁bq$kL?!B̂Qlxj<dbshK6#
-EuM5LKc D`hEAY 3f\
-IbW!IZ7T`oQX4Cm4o a5?9SK7O3fU{&
-yWԯҲe0(xv4$6Y`G4c:6'$鎱,x4>V( >"G\ͣCGcx/< ԗ
-F<?*@ c[\Zfuc>vDky4ͺfJ8͓-ktVaꊂЀs8-pyi-oɛ \68csq˕.!"
-Ӷ<Rit>s 8SZHSaܛZ|Mɋ'*4sbXAu^b,D2kIZALR4)B8S{HHz2ykM1jlyy8T*|-k%7:54j]jZTˍGN!/2wCS uVهh5rI:%R#JaT4VGdO=#aqڄ<[L='"TŻPRخuؔ>COQ Nvl]+5fy{$:"+m1t׊jxaɢԋS(pG'0vPKbr&ՎһqS?s6C;!0=]-%a%銧G_O6Vk!Qd^ Mr1qsF!V,l[.# W=(cزi0 v$KCg)52Q3CZ`^KwEf7"
- \kT}!Sê*k~J%sz^zzJ^RDK{Ma\˵q [
-ͱO޺U0½f7b6(NY7I\TR? !$ME}93;<#f eAfh{y~%fV[b1b UjK*ZK
-BXd%YV-():Z1Mo`zi ,h}jƁɟ8PU D!N.X* H
- *fU1T<=:;[z.A#݌hC+P6JfM=Lp(m&YUP>|MdG|d13Ҕ̅w':gNT0*w{#z
-%: 97M'u~3; F0܌M<f <'evN*bRA\Aiަl:Pf\hg<%iدAvŅ)|Ut:"rȣ}},ᶓzlaG~I\TAi)vt#Rt[8@N+_\b09k7*U6Ù9O
-:)
-Y\7:n[[&s:^N+
-n ~- #\$^^JeϘT Õ\^GRI6JZ
-\\z)OU#L'H4W
-×\{dg0\?l4-Y ݸ6D{ޠ28Vqkѫ_b:?mβgI&nU&R#F:nS0ݖ~3%u_eHS߂QKttwm˝ Ij-APRaꛦ򝹝|6lH *8Pj<!5 1V'*i~)5IEϋhU!2.1R;øΓaJ^QzXN£ˤ1JsFUH-(8NY
-o ہT~1,Xwoeǁ*D ƦFɈ=E
-Ky<A6]cf6vO\vڧ!&}Oq+"&aUܲM4tl)z{|-V &?tW\3pi<0#^ ^|%$}(AzÕA'/ <V550_QU@ n\J<2uCjUlmYIQ)LFgc}U""da05{PMyo` Ȩ4,Cw_Qpuo|\)%\uCVHܾRgh^4&] 6@lgouoKoWXvCڱt@GlATtnmCgT2}s8Ժ|jm㘬h}Սkj VWvRp_%[d9{#V&)e>B。%PE|SeMDnQ(ݾ򎊅 vqkҍpOȣ-Q;Sr̋=z]+Y^
-,^+ C>w͊iTӄLEK +WeEH^@a& `yڷ"ިre
-VZJ5{
-Sy &C0lxiK/-m,0Р4{3r{E-j>@3M`}#`D=^;=xǀ,"2ƍCv[tWe|QR=]þ }Fcfn3i"Uzݠa9ha%ή K(K΅2W0$h=EC_,ULgYjd"%KC
-4~
-ͨ|7)*"\Kw]#6QQflsEثq_Ҕ,TH;x)TM,N**FZhۍ,L"Nj!O%]I2|q~;o ä@"rL5zw >'-Gt7D,hw[TAs2GZkҞYXch%b.m!52jgW0^zc(+s H6?[Od}Q/Xk) (Ymۀ?һsϷh#c}W'+թ#}Ʋ{7ԅµG#c`C& {!/%L;fN1j
-qY36&Y"e?*)h). PUDɤXMy?_nmVq`tn({L.cHy& 1Usբ>efT<^IFhΏD_7qXaT3![澳Ddb j("{2JUyi&.޼30L% wKʕ׺ j(;ͧ>~W|`sm;>%[9#]o]GarT@r5|#KƎ`4bθS^^}>8'^OGt:.`B 8t?hh˘}Wɼa`tHb sEh'e=*(t~DS[@prlQ}BK 2ymp=[tsV
-0OFe#!R84']$>2qvv8l ^SȘˊxo=eFؓ"ʺAO[C k': aI%܄$4*m DܒA_Q.>$Ek7-X1ފI+ϕR44ܓ~;e47YjD) rh Q~\(9́_9A0G\fAH f?vᏫnƙ "kr "rJ,-xd=
-±P͌z;"qQljq?G{:$6rrp
-+V\M ٿ%NU zM@gY?yJc43;y
- _]3(GAāL;#-vo)ghykvVeFzZd8ɗgCӄov:lC#%R&pay;.gm^K(2J0\dȆIͣ7ȿ^wEL|sCΊ %}2O;ᎄ&7phy.6qTr_uhR>YiAQ1h/^ ^rZ ʰ_I x8GKA^ꈾi:5i|s̨`6 g1j$6-_0NJɨ,1i>6yϽ
- hqq[
-B-ݾL,k~a Rtt(a1Д,9%WvyMSo:FugݐNӜz|5r1X8/֘sb(.CֲdsR1u}|Xb%Pž.i<J}k]UZ/<]b}`>  +G VdPP";%+O4`J>ۘP]u.V\ {-1_|mS۬*`tYܞٱk#ꌳ|eLLkAV.
-` z28KF?I.2}B~H֭gO$K9t?Z9֎ [㗴JozFiEv1$
-M)J*~sǐ@QKi[ N؞W,\2/@KzIZ$Y `&ti͙_XQO迂RXJiu46/t\?>ٞhH $Jk`8L=[ O~Yg 89@xrg% I PH 7xivarjnX~F?!OKq2J53Wc
-97_݋C[l2qJV 9J-LZxb,boؓX_h0h
-;Cwwʏj 1$'!Ҹ.܈
-'KoX%ym#5= VϽ`1/$/O-3?*6'>9bYC
-,|@PVGB }fR> )( ve[Ge^a]Q^ ZngzDZ>eWTy-wNk'TQ ,x2N%*op,3Uppxp&=iyzEX.vGHI!k)QI;70# vD`IHI861iMš|ׅ6VȦ)[8ny3Q/ߔnǾ~b#.pK'ghv"N6FF-؞&
-8TLN$utݛ>&tUbQl97yۃU<F;+D{o^$
-9OPfs}Ɏ
-z^viD®!4ȊC9%kW:?AO=bs㪔ӈE^&'^}7yVY\7ǹ*2,#eTw] * t`){We$Od~j ޘB(ǻPp> "ԱPϯTS^rt-N
-)iфf"SSJͶmO{1s ""*eg\
-ob\˯C HjefVѬՐ.dZGGw3kKEtJIT3I\L&LvSYCoO>$Y2~]c0t#6cS52|ear?C_ꮕGmU}Z7 `L5bpz\sw򄞹gRo6fn~׳̱sb',^=˘f ~$7qvDŚ6w]ν&|"ƕ䎑C~DE62Y2ʘ2lGٝu]/6"#q>5E$<:%>(zt}>ľf}9j=%ʢ9|pnhَʉDm҂)~VyDccp,HQqĒ e]`q5rPep)bv 
-xd{oőK7_ ÈU!(J+ C
-*tzLIDl`‡-OעmDљ5IeW1{D{~V-|d;RҟI
-DzY?C׹șۤ(btD\N&ϤHqĽY%!QF4-uLOJda_]oiIב,oP¬7uo-jSʚ?X!h"2|j{TҨ%g4qA;Q%$U;#ib3!>6Tk5ƒ TO PW(3)͏n
-NZdX1H"~iotJޑv_ê%-C/'XiCo76(ߋcwld!=Cۛ9iiPHA |w%S+*6n?"D0 }?R,~튢 #3Й&d?S| ]!86L"<#ӶWuxGCG:AIoWOx#]h^d!XwU,b_̓YA|Yqq̆]{cͻ,2v}`$tq<@|U(Ib `, ,y?JdQ
-Ƅ<q֣N:桂_NdخCd
+xڴsx>4&m۶=c5ƶ;mfq~Z>߿5{~3x'eZA;#-#@FVЖVDKJ*
+
+_ߍ?P!YC' 7m9g$ '- +!9?|혏 _g@71ʢ1weJSHht)'i&TJt;H.п/NFK'߶X4m%rDQ`GQTp,GN5 CvٯTNf lFk\+@uX1i:Hu=µh522nt#zLa
+՜A~}O>hTK$~O*t:D0̾ѭoגOjdk.!UoMsv\Ɩ ,;Ԩm'<Dޓm rq,;E꣦ d(?)9qO%ɞY ư_#bpն4<C<ݓeϺ[!8aV
+tHij
+g ++RnDx y A2kKhK 4kvq-=!QRSSX*K`$Bq+-tAMށGș#4b}'w`=xGCsh37[]ҥ3"Q:_\dx<@R%ZR3<19ULv^SI~
+\%${;zg~mnFBxRUֽ澵m:Bג)&el E
+ !VP# KIW6I$E3Nh\FF[;TxJ> GSdO3y=g+Y]$XZ]d͉lyV'jF{b{5$%?|]:`eeЗSD昞EzGWZE I@z$=/Tϯ2syc-, ucemjR9-e
+`;Y6kݓؽxJ"}<y<|</)qY_>I>dR6
+̸# 1[X>3 6
+K>/I̱|%Y"m%*'VX(cw%/i
+`dwO!pBg4%]+<B<QF:a]Kcj4ꯀSet'HJҬ(V?Sp.|ĘV.7 秤 !<<UqƦݷO뒈 $r L &<RiKW$o!kL~c%,L qw^Z`E]rf^Ꜯ)w;[7>%~
+&p;)PUk5X>69zJmsamg|- ,
+#@9Q?QoYj^NZވgF$hx.;;b]~،^#RV=2͒MDDyhQJxy;ǀcW*TWw:<A<+ŧ"Uo<9?5:{J> S4)8K Z):-OxL'Nndq;olQxco6wB}l.à~rI/U{8`CRdǒim09&W<eE5UDhЈ)B~
+옖O5AOSFi{J?#Yز=X:Կ&roF ]޶F/$>z6Y;ACTlA6LӀe޲d
+)\ρw'QޮMNdZ MQ XBll&n4\B7;Ki1gUbU!m\)0fE+!''xq*וbo{!hǻ8N|{TIrpxBuTe1!8t E"6;.˵+iՄq962jmsh(9,-1Nr'`޺\/m.UPq~G{kvufWlݨqi]ޟXm$$
+f0c1 d;>*7GWْ6:?% /TSͰ5EI,+XBqϜ>Hl6P%'tEQ/^]c;A NTN2q7|&c~G@R6|IO"{ εVS3->1.hC֝)e>%VFUpm< 0~L֥CodTh
+ƶ u62WQ! kSy1)RL'igB'ڡʼn1 KdZI hܵ:9Fp>6ͱ64(Џ +p)>qf^B#TToIy/FY*Wl)ͳ8*%QChkϪC
+<޷-5WE Mlhf ?AдN禮
+$y&)cQX{P Ucj0X
+Z
+6[W5i,WƬXe45q'$h,934pW yo
+?>?Pړ
+BU۪C5dq|
+\ȍ>CJ[JɒhylvE1J@2j\xҰ2QbnBɮrheC;&ep"<(;1*[JT;l H?kjݛ:<[H"GI56挘9X%YS#%?l
+Txm=^CnDVX-?y`=K[7K+nUc!1w5xnh2-=#!J_vN KOS t&fS ./ME2Qyr-Gٟ<7,>[ent2lHԛNm,t4>/>"G
+T٣Ku(4թ?C 0X5ey(EZT6 ʶ6Τc9&6R~2ͺbJ ɓ-^G6 #)x(p}-oT*8}wu˕*>"֣Hn_7|#y#QPԐ DZ:[qFjxWL9%i1*Q1%!x/YD·u| rxeҿP cM?~E؛)}[gNSn*-XkY#ӥZStmbZ#=M={eGzy|N~rTפ<B
+t.LM,A6()gC%#J:!B}ڋ7=E
+g9$܍tϤgf
+PW=ٕګT} R
+O' }Ma\ǶsmS (s9e Cŗ]Q@`e`f+߂:5[Jݩ=PoOԍΟ?ͅ{->fΝ3p(f?)Ф+0oM=ϔY8uv>;2y5@i^n#`sy~zV{B |YJk2.2oמ( ^ ^:Ŀڷ<~7tO`s͡]W.lDt:"e7XiNo0VBAV9+Sӭć6:$O(ܦ%FeWV*A6ᅢgU;Zǻv$w{vp ɪ1-tĬLܺ҂AI?E qȧNdp/PE4n"elF~w/"8& RIJV5'hc " ):6PT.猙jFX!h_Dboaj>RHw͊['8 \}a:.o֏;;OPHt)uxumr!N* 7oU#ժNwe$E~Q,z/85tt cͤ=^7puU64ot-We5$>cE7]XAȧ&)tׄ֒'W@K:cxDxM=X3s&33 %]hܪ=1=^s$mA^)MEF'>Оe@z ' Z
+B83_V׮0[hvBRk/:5a'KpC_ෑSӉߏ-=T7~o!ic[B2־rĖӪU`+#Q֣]춇 6i
+/s0l8~RڟF^#ߏ`}NsAoAn&-C;~1"n1
+F= S~S<+"sUh1,鍰~;"T.*ۜ,$`32HHM{~[YBmP1O5{?5 FlRcz~Y Td~uJ>79hPʒS_[
+4<CtlyqKG88_U u\Su*nL7,Pi}L"Ij2=,d3/I W>N [Q-&ןA[AEA[xm󞊏-5./upG~znG`7kE;ÃU;6A};O|GàrS Z-^x#h@Yq$Xc!tg-l>9Z6|ߠnt蚼&q.?>&g=+6F?eb88# s*} \KTH s>|ƥRS\I?{|@ڀKYF#"H?e*FdWRIGs;Iڶy@f[qcR\16#w V+{M\sS~j t;|fYpW|v,+d%v/DPXx ^lwyB(r^j/lTG]q~=ٟpSaeX ib.oq̬3dQ:P7$;BHMp;.5A,}_.4=-|yS< 9qTܖaI7TvPE fьT'ENUPR h2RHn8tƦS눵nD0< *U߭Ba*#X514|(ĥx
+Qbd7
+̀Gba
+G%md]7aw<%R'ih[rQyUi+ÀFnL^gisM{M#cOS-ܴLQo:BRK[;{6<=K.!:QWZ{XJ;&ɪQ)]ax
+(bv N6H}<Lq(6Sn!\\EX$u
+oޠȹy{0~N׈JT4į|!^#n*chdW[3v1Il[VZ׬i$ߵۏOX|;u/ OKtVV0mk<GwnRεb(f_wL*25S63XZ?H]+{'sK|v7宅8Uʌke64x,9܏5t@Va1Ⱥe/17Mgk2L|QZO$
+V?0sr-N-𗷤slC4S* 8MvGwCjq2@5"nڎy?cOR,,(zIJ4-j:oekS4;tBحap+>s8(|@j {P 8 xQcj]fӥ1i ¦ c=b^fqe<ТDo7e>cyS>QH=6,%1g鏺y}kln|7RNz$PI=>v@4+.
+l4,f?OVn|w]O͚7
+vʇTn(1~xR\rr s IIzC
+a2! ~RR{d .}At:S]7\:MSy&)ڙW4ԓ*[3ԗ6eLd$dw+흋p$lњrcۗ@^gCLxdmF7bq굣>U d t^?fs
+q eka7&2jP6-97[㓱'x򸨐s/ks1ؿ9
+ ߬ Jz^W@eUOEPT|'4AR,ऱ^hZ|KTao A4os&maP91`cEWr"ͷ^gLg؏ПE[] F4^~EYXۉ?*@٬%=ýE &2uwTX=b4 5pnʀ+l`#1;M҂mwW<z@>:ї˛oM j c'R.PDXJ"zxh t?oXQJ6 гH h&A4gl'F>C7r-DI6?Y8@)¡rZ=!ܦ@-7UB;Svh:K3hR|`:RU'7 v|<y$BgxL/ 9o|ٺ2٤͚4#jeqF~U^ӚK!%t:*8 Q*a>vut^ԃ(7ԉt!zsm Kcʢ ґ5F Mgl!;duNɨs}~>kɥl/z_yǹ͑m'\L/D/|V!s"F5ڿik|Q!>app$~Ylҥ{Ayla]kɴ;b9RuP7ːEV(em=_:!#b2>7y;0X w+S1`
+ԋRwF`K'{ߘSf%/ S+=)Ib/g
+Ƞ`6֫ߞ/%"eHWylƜY"/mSeB )W M8`%r*6=R0a߳TSh8EF+J?3<.>K#"u2Ŋn#a1(f䜇7VM(eŌ\&+9Ԍ3[
+z.qYgf6qH. /6x|BW<DO>qT0*)?K$lڃK]s^*ͫn|edߏ6ktB^ 2u]FX?GJ+؛mZ'B\ْ+KɆpPIJ܏jU p4tps½Ƕ8rUB+N:R65X@B.=Zh;F<9Uf>M@Kɐv(Ժ/L/p
+NfaZ=FLҺG4,ݯu\@e'e|j*P#A`$؞ZĬMA"l+1*VU[:JZ/z9n_[08wا:jmƳt IGB
+ TռA",ȵP@O }E^YwHPH.[ M: qm
+ZۅvsSƞJ$f'a<ݧ<ׄ/7^y OW Lo-գHD\'zv $Le؝@h9ZG**u&kWIBܒ͋O<\ ų yk=!z9@ACkT\d
+y_t(bT`2s#pK3X:S
+p-i8Hlވs8m}1W  ^a3PR A FrhT_s˴D4ɟj:Yi.0:ԚW!oYŵ~&tK. o# Hٿ 8d3 f3R|,F 8a⬹e  >8>X2-Pr%lSfQxTP>!*i  W7!rK";w6]:!6l8(mpAҌ.Cf֕tai+ Vl=Ae))"aoIi,ִ>s0()anT)隣7< t5urU a?> lȧmT.~"xͤ]h.~;Yt:34?6-цIAu<`wͬ-Qn}JH1M&Yǿ29FBHfivNt2OIncHM 7vLF;{A೫RTh}60T+C cׯƮVuV/"3JQhꈿgJ()A5t${@U
+ڳ ig0ĖGQtE {KG/*Us(r0<C
+}?4
+ڿS0 VC#4W-a[4a=?\͟USUIT!ՏF`7(q1DgpiieV(w1=KQ˵V"qJlc
+:Fc|viJ| X Mc[) Jb€N<Az5 <u$oX$I͍A8K FX,I%^wT> n}P_ ُٔBf866b.5R&5ϑU~vˤ;7'#5ʋJ蚩+ԫ8#mDKRGޢ!i>=׹gQSU֝P#uQ! F(p-GE?82:ÖzYD[wl%S)qUU䕒4H:;HgeШEȴP暯kךfր옅 TB-b:B] D9+*=?s2<vOn|Bӏs=Ho;E}T-Y[ {Z ,/p>Ljzf18CP`n"LYRJAyx[nrN4%:d4<w_-Z$y*U1$
+|F&Ntaˇ/*F%^]n`o@X]XY@CN5Xy0[b$*i݄?^"R AXeqT4sf@NzތWNX9I7\>oPO)&v|ÁPY™1zNVJǵ{V-n顿Z8-T}\)&tnE`mI'2/K)l?qYZ5 ד]6i9Qps=ԊTSQuzRj/Cg}?`:RȨ
+
endstream
endobj
-537 0 obj
+631 0 obj
<<
/Type /FontDescriptor
-/FontName /OAWZNZ+LMRoman10-Italic
+/FontName /EZYWEQ+LMRoman10-Italic
/Flags 4
/FontBBox [-458 -290 1386 1125]
/Ascent 689
@@ -4619,11 +5226,11 @@ endobj
/ItalicAngle -14
/StemV 56
/XHeight 431
-/CharSet (/E/T/X/a/b/c/d/e/equal/f/ff/fi/g/h/hyphen/i/k/l/m/n/o/p/r/s/slash/t/u/v/w/x/y)
-/FontFile 536 0 R
+/CharSet (/E/T/X/a/b/c/d/e/equal/f/ff/fi/four/g/h/hyphen/i/k/l/m/n/o/p/r/s/slash/t/u/v/w/x/y)
+/FontFile 630 0 R
>>
endobj
-538 0 obj
+632 0 obj
<<
/Length1 1843
/Length2 16027
@@ -4693,7 +5300,7 @@ O1>;r$\ I 44ڒ#
碢*]P:Xc<)(5UITI㎅[mdJU!0&(`5XO K4Cm.`xt6 ,ySM/P77 }
endstream
endobj
-539 0 obj
+633 0 obj
<<
/Type /FontDescriptor
/FontName /PWWUQZ+LMSans10-Regular
@@ -4706,36 +5313,31 @@ endobj
/StemV 78
/XHeight 444
/CharSet (/D/S/T/a/c/e/g/i/k/n/o/plus/r/s/t)
-/FontFile 538 0 R
+/FontFile 632 0 R
>>
endobj
-540 0 obj
+634 0 obj
<<
-/Length1 1815
-/Length2 2393
+/Length1 1795
+/Length2 2230
/Length3 0
-/Length 3523
+/Length 3347
/Filter /FlateDecode
>>
stream
-xڵUy<TJET15"YYFb30sΘ9cJ*KZHD))$_IR ^~y?n8k&BF怳 h
-՚͍B$H a _
-494T(
-f2
-̴E\@^""p¿Mx5 ɒ)`(T:A16F
-bFAR|zv$0QcDEq`/H- PI`B {lu䧳;, BmLL%OpEPl<ZBǕE_i\ J"|. CbgpG5
-s$WWT{g0u>\EL^ 7II;y)Hy즌b|nvp||h,۰9M7S.sBykdzśC)FwZZdG+ ]KmV8}Kr{_Oë>]Ł{W(5/8;jiFx}|6|{QI>ҋzZjkݯ[vgiF} \4]of=ѠZvLi4x,|:L)4vF9A©YWoZx9}G>􊵮[WX>Ň[12)
-Jl{jrt Oǭَx ˊ>#8ouKesA^~
-K`.>tk^z}DE.eFKdՏe.1 ^4~ꠑ-z7=g"[XH~Ǟl]J;.u^%<1{-ײtNOE˙ٷĹ%}e򜃟;pw=)2juƸg]ĢߔU&Gi|!A2wJO,rnnܗWYc9=&| WUen% gMHq }%{NB̔7 4
-2 _#[ҿ=S훢^
-GZ,UݓsSyຸPcQyDSq*=w2ߐ^ASZ=4:h3KWUFVkiLOR:Ysݢ{ǫ:CSuB{k- Zv')F7OUOΗ= ztw/c3A@aϟhQܻmoR|yޤwAKFoߖ=1 8=P+%[dW'G}ߏї)TPn T>I=Pb3dVc,{„B.~TeoM48r
-R2 %GM{/eOost#tq"o{,)tBJBҭ餹y 4eT~DHOZyhy±^{Jٮ`jQ>1]GVY]\mp&u*i~*g7T:ޚP-MmOQeW{+b{P_QBr$|ϼ(#?0洑މ_\,55)F)>jgc/Z&~"2)\+q%rBQl?|UU5lM48ZORrYLhدj}zѵZFiVz6zZ3cL'[+t_FJHU//4MQt3v5_UpaQOS9>._NCs⭃EE+*-TY___>Y`^걶{iLgf\/bzD419iٗ{8Sך?\֕`WI_IE'൹ 8U>ͫfOw|xW),;Θ;~ Nf tC򼣴fs.UYoW,o/
+xڵUy<TeDl0fؗd2ufa1sB$QQMk)*]DIK7)IvhV^53g>>~tF`@&Z^^t4Of ,ِ FIJ\L424\BDGA+lF~  `*8< Ù
+p~_?ǟ귑9p߹8]
+[nFJs΂f-՗C{DyRHD֯IZ<yW|7Quulj Nġ-rPkSlWR*7\[{'Gjo3Ș)­qXalL98*;;AJk+u;~}eC,Cgsl$Y&Nn0GV6Qَ܃)S[ZCK.0sABV<lW/&iyBw)}ąH1ckې)Θh`s#רgr6pWcfl%1Y^nzUiHS\Km{/:]8s3*יi'wܩx鰞bw])Je<9<p20̴Hp*BmIZnMՋ-FЯS2XuckHAꙷR׃W8ȫYGopf\áu{?IwSHm{dڕ#(D|KF-<.2o#O7= +:=*vr\ȩTaϋ6kOm|&sq8;]oim/+:et^k+CxF粨Cs)6So5RW=vWdZ"ӡWɬ q~b[yxzĎ)džEVw2 |+FsIk@dcCj.WڑlygےUsS{.@dj岡׉5s5%
+  % ̷p; @d`&χ]yQ^sLRB;ҥ4ӳzϭ]᳞Nvn2iq
+[O4j$-rλb6 {t!-zyhMۚɔn8V=Iq+fݢHO\M6Rյ`P`-)Uݩu2%5ж Rd^<7 Y,]60jv
+=+=ؓZ)}eJpXX@ʪ J_d탳u#}[MYM/{& Bʺ}<㢾{aI,쥷T$ġ/;_ےB]Fm'r.̤->Cu9jgrl"._W4uǷ<:ni_9aתu>IYZc::3-Mrvob3"$XvC93nRnґyqԻ:+DlGhI[k_
+KePRrM
endstream
endobj
-541 0 obj
+635 0 obj
<<
/Type /FontDescriptor
-/FontName /HLUHEK+LMMathSymbols10-Regular
+/FontName /CCXVUN+LMMathSymbols10-Regular
/Flags 4
/FontBBox [-29 -960 1116 775]
/Ascent 750
@@ -4744,11 +5346,11 @@ endobj
/ItalicAngle -14
/StemV 40
/XHeight 431
-/CharSet (/L/arrowdblright/bar/bullet/minus/nabla/periodcentered)
-/FontFile 540 0 R
+/CharSet (/L/arrowdblright/bar/minus/nabla/periodcentered)
+/FontFile 634 0 R
>>
endobj
-542 0 obj
+636 0 obj
<<
/Length1 1687
/Length2 1361
@@ -4768,7 +5370,7 @@ DMlTD"YPf^wybQaY8i$/]/áɋY9@,n N܀^:
=|Sy~x#4w6ԗܰY;,~jbCCqZ56N34}_=e…wvM GװS4VX<y*y$lc^Sykݽ"4[n]Uڇ:BRAEKl_B%U}z2-ƻh]rLU.}g "w#+4mN7.E\#Wx$ؽhoS5uhӟ Qcm[V[6iAV:(Fs"[~ #x#7kVH͖=Ua6WG KTpΝ7涙Ote=j*xiz n4:ӖFöCx>yuE vm6Vuߕ?NI?Ku>p0Yi2t EEiuCJɝRkw^OY||N<EҪA^!]G:V| RxaEns?~`Ml?</Ǻ:jަtfxO?\xP㡸x4*?y/Y
endstream
endobj
-543 0 obj
+637 0 obj
<<
/Type /FontDescriptor
/FontName /VCFYYS+LMMathSymbols5-Regular
@@ -4781,36 +5383,38 @@ endobj
/StemV 56
/XHeight 431
/CharSet (/asteriskmath)
-/FontFile 542 0 R
+/FontFile 636 0 R
>>
endobj
-544 0 obj
+638 0 obj
<<
-/Length1 1725
-/Length2 1816
+/Length1 1744
+/Length2 1898
/Length3 0
-/Length 2888
+/Length 2981
/Filter /FlateDecode
>>
stream
-xڵT{<T^("[}̸Em 2c(913猙ÌDJ)=]%eUJtRͦDHdmmMΌg|yy}V.[ST'f <&rwJ"dNeh$2WC8L= O\XÒ8X(,#X0Ҥ0B8HNa4Aa;"ɐD\ÙBQeREPA/r T
-D-88 &<8~a\pDbnT>p8<՛GvUQy"9~t'
-eD]
-L&WaucRPN<M:èVcF J"U9ţ@_I`'H aB GS V?X`3J)2IO}0bg H1 4E|x #r\>BD Ugj(P
- #Rq%Vf{nT:CDBTc"DpLM/AB)RN|INb Kq@p2Nj`
-&Z.Ť@p")]
-݅JsvcZi&&DuvXx
-EmΌaO;p
-
- d:~h<&@puLhB N_
-?g>>2BwW:3\}6#+G-kתy0IwnasV%m9S鷿BA}\i2/"@:i=g^Vd>/,^FW;QtsA^(iݼ;_ՖUqjAE\Q[P;}=Nc{?ܠb$*&՛k_m
-C3uICJIUBTgU}e"æd.d,ĦE42+!Mhfi>|ڔ5xf-EOY6n\7a#&+{:|}I{h"=l334Kr>M>'V=k՟l]zA~~ދHtؤ2hϮ؞遶73)J!3k'Ԛmv.#VuN9WbjvhRE]fg:-d?ܰd^Yz#vOZnOIh)52Z5lyVo.2x:0ؤxR5?b&+Skp}-LPq\v#AmG
+xڵTiXW-E" {VYD$1`e C2$ `@QD
+ZQ\DA E@6An]&A?gw;\KEþST;d!\KEcR+%%H!`Pt:LV`ႋ,V
++D'6C$9
+A
+k+5gZe@B{(Ax" tN]
+1`$i}1E?.A1_XjNA P$>C@O
+H N6?a`AL*1Ov
+1Tp,pBoTʁd7koHH+PXۖ)d+Ea!cMq /T$Dra[i&&Dsv6B1V*,' &:{84(b:L"tvB%B A_'j%hTÉ OS@, iIw4%tIe4B ?Ӊh(->Atg@+r\͌k%KvE SA' poȟF d
+Pܜtf̔/"co!҉\k
+nee1o }gyu[_RĦ1-u6o*gX/Vx;y<Ƀ'Tf:w9~Q'/M:֐]*knO:vFEZߓӍ >0,_pL{k7;B"0_ azO>mń!ʞwOzݴ0u큁grE{vqK\wYN| Yg>zp!4(V=py/V|Kϝs5
+ů,N;fn; GvE]:^vJ}`\Ԯa(yڭ&HcAS鏦V޴wa<9]py1p)I=7FfݩV; I ZdgJZoKdfP,̤SĎ˾RvKt;M cU7j?ݠ^UgxޕժFv,k8Wd_rRGs^,/b5oW39ϫrC&MSww5_abKjñq&8٩fFUR'?;N盖?8gbq^[7Fj->~V\gCQ=2~98Ͻ|72b7uڝ
+3ӱ&OlTnf# 'v&AEA&h'ulyw;%I3 :f?1ޕn9煯eS ڗ0 lw}%"ǹzV
+n<x#8U8BI[cxz3+o?=cD;oseWnsˈ$MJU[X<nQIpZ,씙,O<]z:E'<zըy_ \vzϙ~Ak^}JF}/9bW̻+}{=B(܊ʛM1gNrm%#D6VaׂuzTOo/ 4Z!v B]-+d%yI7wVӷ5;^=P3,Ds]%u\.o_*
+Pn6QjuU]#)' W=Z ],Uowȳj#-:zL}YQº5/ ƇHud^ǒ3K({fP7&)Mh 2;,fX3
endstream
endobj
-545 0 obj
+639 0 obj
<<
/Type /FontDescriptor
-/FontName /QJIIYD+LMMathSymbols7-Regular
+/FontName /PVOJED+LMMathSymbols7-Regular
/Flags 4
/FontBBox [-15 -951 1252 782]
/Ascent 750
@@ -4819,125 +5423,124 @@ endobj
/ItalicAngle -14
/StemV 49
/XHeight 431
-/CharSet (/infinity/minus/nabla)
-/FontFile 544 0 R
+/CharSet (/infinity/minus/nabla/prime)
+/FontFile 638 0 R
>>
endobj
-546 0 obj
+640 0 obj
<<
-/Length1 1983
-/Length2 23879
+/Length1 2030
+/Length2 24210
/Length3 0
-/Length 25086
+/Length 25449
/Filter /FlateDecode
>>
stream
-xڴeT\5;wi !Hp Cps=fZ֬%{@AJ/lfo9330
-
-QG=H`b`fb`abF
-~wwpwtJOg?"
-jqWVVgfs
-MpR-%>N+Mk̷͠IjQbhI1S1!@`Pϐ_-$>.bhk%rw=FL]%镶B37a:ڢ-w,Ow;=bD
-c8tЦi/i *WZʼnm]u=*B8v\wGϗ%!ߙ=(KJ&L>R_1B,9_?.-sЩH"^n}Z2X;(X#fGҠWYbC7Q^&TIcXbX.5>] =G?Cӿ>Lh^
-Xg7"2Zy>Ē3w0$BgqoL{QiǯGs31׭Wc,߳rUbonm\f߼pL7q@7c4c8Lxĺ?gmŰ\CDm #Ww}8T,UYc(N_sQvx>.%@<bф ՂE;⛖R}eHݾ>*]w&G|T4;&/ݘW?bUv뿫t_/n>DVQdfvl
-RM!_=N$ еa Y![&QϤ#-EWﰮ Ɔ!dd\٬:yr2 V* ךs=r᪷SJTu MϟA.N']%[Ǜw5gu Wysŵv:$ FŅyt׻'K7w.ɢY8@1Bh_fMҁ(X`C.AZr|Vw
-':'(#O0yՏ2aeN?³oȟFJNs)]*AVf@<BGٓ^`x(ɶ _gowtE.PZu[ߏ$0%՝BxC2Yp˜q:kbœs$?SgVP຾C5z TɌKTk] Jy֮*W B DVȺf723mnsx/@p/ۼXɺV)Og nUc+wuE0P!VTcW9d%0 #m. +{ uZ+lx"+0/DZB<?55+T6T(} SwL佗T9G&6
-7vr9XBY͈\s9@$؀hdu@cZ(-
->D
-7z"[(S,qYf1A^N\-䪵Ht`\Abnټ~g$ l$DEH (.@ٮ&9 (i3k9NB)DBKka{'}t~Bǵ2P!Sc^b1a4ZVh^+ l&F%a_ۑwbاZ09_obyY%6Q?n4~6x):;1tAMmμO@e^&ŵlo(:D /ԨBWޭ&ȼj螐5jg[J9ndw
-;%n>k¶wc?f
-!DO?=r#1RD:2LarPټNOj$J&^9#B$L
-}K8'G@;cVva=k] }ky"luL)ZG(+Wn[۽"b :peʚěFn}.;\vĊ*oɁ倗r9W< !*TѶ6w!Dk_]FO^6GHg#70TͭN`
->k7{_OQ7g\:!<VD$nEy>[#XIpV\+u>2RH)c϶Anb|LXB'Iጡ-17ҧWwR\IrF .\QL^(1)vC-IT57c0ȳvZ_#"ǚTW2`j"KXI,}rC#\bT,OFU,<C䇖q(fw~ |e%J7uV}E:0
-n0Mt*'mzHc"C@QΨc5DVAf9ab-RҒa\3 HzxuR5g+`"qQEKvQ'S)õpJ![O魇Q,-݄#$6rng p)]OtG{B_A0q PkVgUӹڒҘTc:в.r|̮ҚiNuéfN_Nی!OvvM+Ox -B
-X‚mpCfZ˿ʭJAwiC;d
-:0J d
-T>>'4[UBҪuC
- #1)wb }B 8߮R6:
-LM}BavYb󞡳 w
-#nX9F#^F Lxd
-_"5{S-n_nA/<4Dțqq!$Rr\Y;bđ|g{Ǐn;vs֟p"}<`ϓ+S=:S&)5bR >XK 6?U>n~og)hޖf>!\m4GƞEZI
-WP ^3:Lx)o>lj$,DxuN //F$yaKdm^Tx?d.ru),Չ'ckOꛃ~ ,.1W5VfW˛7_a/B:k'P7?IS,76x:~E7]<V"gYec%UAڮG2-h<<ĮAᵆ{Zr}bW~\'7LR%LcG}=1-_^7%N13lʣWa* 7L6nZ )DZ81fg"-OH's#aIA!W@ipGf9no`(6<x)5T>qiӋ\5 b<[ }9% =us
-GaxN[(1+~ D]Fh@Oq y]k>T楼ErU%.LxӮZu?~6f? GvS{5hMSʘ%l'$bgyn^TLXfWiOntOQIrCR[41I0D <|<^3pc(;7)/? }._`Ő`ArF}QETZSCمy@\ /1Gm[j2ahH dJ+MR9xaHC=d ؎K(;@M] ~v^Ud
-μcI<\;/#.9ilǩ4 r!&X}$8N$|'ʷChg<T8n$جHy?җ>Z~J YB2X{<p:z[$qzq]0}J̲Ci%3e:q1Y\bbȧ6ZpปD<fMm=4jjgI;|Q7,ZFdGĀ!gpq]Ӟ-(
-KŒ08HV0wg2H*&;f1fFߞX1)ej\*Ttr?I[wqpPBJIr׺WO/0PZB\].g:.; 6hsV>1~^KSE>~ 0n%j!mg=I6RS&cljJ҃S->+1cʙ9Qk:4E^.mqfDȚzl_j!kJs`s*L0MpOhW;ٹ)a_ȉ0:Lh%֐Ke+xwPǖ5m%t7`#B2fevgܺuM!i05~Rz;~6FsIu3%^=.<.>HR-ٵUQE K=[Vԁ\w(2GW*좛ŽTtEۆ:j
-%u̠bIViq6?` z}vAz݌PG2HU!.GcL_ҖX{F_ YWrʈ+,Kzt||CSs̸Pg5>2F09HġKaK,-m[F問6N-q3F`-1y
-wXvkx 1H%&?qs}Q<2z_)Pb:YL0z2dn8;&cA_<JWsG*R4.4Xj`DMؽLAsS;Y]|Q:SV:g!yՆv8 mbCeS?tRL"r@ğЇ#Y5RI`H~% x_g(R:#tɉڵY">b[HzWUV&#`pItr#Rrrz;cirjC]w]D)ytd-bleb\}-u,日Ou
-6aD\b 54 hxDtẁf=l*Ҹc9ANCԏr!kbLxYrrS*Y:=gyJ0XM=qMz^"勽 'HAMLemL
-Sbn$הIG&Q\gg6WRV)OFB寖"V5@I_εtOZ E>(`칽 w"WL{2
-+ӨF |c.@9H;g%J1]=+<H <N#A֬KVǙ~UW_p_(g%"ch6nb
-XVu`Ĭdl3ֲQiP2_VS,&QӒ78o2:M5hſCLhY_- }E3|Zs^`8~^&T-P*0ڻLZb Ń "uaXʰH[t>rm?Ӿ}lѦdQ+y,&:|jZZ&$Eoy^BU 9P I7[VwѠcG̸[X*;qQ\n
-]1pu64JH#lk]|n%ć?hkRM7N֨` %J| 4fR"_f,Dv^$IAbZd<ԑEz `oїħd
-u,Ovc,ڙd!~< Wa-&j5!YW4s2h:ӏ:z$x 韌ʹ{V*PD~at-'2grM:0z.Lg}rbXMȍĄ"smFb؎n[ekqÌT'cƍ+5MT*(4*lD/A Y8 5 B5AeÒCmp *S|7zb&]G=V֕^0.d<QTpj,^/n9<C
-Wh]̹eWt\tQͳɑAV ǣ9x`! d+JgQ3(> uFʇ2T2%jtw<kԊjR?'aSI|`Wm S9UgAJlR{u=c%t»aczX:y2B-Ƃ8!L1 磝\J<q>ÆJ$Gpuzj 8~`Pr h`Q{TuGمshē Z}7B`YTr"]SFOA%= `TWffXCa CSAg,(BⲻsQ !7. #P4|[C¶_B$GW}ˠo #Ph
-h8eL:ѩǯ%vesQ(Nzkޯ`%; }n*_'ʅJ6|vkZ1(.DGc6xǘ![kdLɯ_(!1%ؔS9& ;:2KI\Q|H,XpA+6 a&ұ=}qĝ~ H`;m y2y旂fI3&p'$p`Jgr~4s3YoH}x&IrG8l0^-heڿK0Χ,]ne!`{ MW(korKq@cSƱ
-pHfeD{X1F bVwx@$Z&z!  y_E߰7c(ac
-ڍfHqIUʹFre*o-.tμqb! ,f[;&)؇DYED!D2.}T ;d؍8kֈo#T_?6FePh`g<Mmr㵈陴6A)3#򐳐MeVZlU+1=7TK>T4\aƨ$ӭW.5q_in,>ksxD LҨneӴ^ʉq<*$LF4£}\-9i]DyҤ۲M4n1Ƚk͌JNbKtfS^1-
-4?{`-kyK](yνlWJk-:y:jKyVuabܮ[>~Y<XLuڪ'·Z%adLG X8]w
-CNXPz`4-+ɓ-}^UU61Vn7
-Ķ5m(dy(n8<CM3 ^L`JUF( 65GqvUq-^rȗ/15BCÞ^b֏U3(ƮW~Z>>&dŬut4a-_2pK5q[%;YxҚ#l,Ж:.Q1z]~L`RU7nlT*qSp$Ŕ#"c|Өsd7X~{H*>b.Q$=2t$~:D_QKzxZ5(Di5H-+Le8f:0vu; 46=o' E0'%jK1㟢j$+_^yׅl3d"BC6hcxdC/[J>"
-R"<[<E}܄w/kQ]ԑGk\{DP:A &NWWNՐRs͕`yɰ>-q޾a$eәFXg& {hAWƺ 2dk.D_|娙=%
-N߿x<>y6@q4ǫhxW-[ 8,Oqy3Κ؝fY5Uh kKE c:C
-NEΌr&pjcpC_NoP[8 '"~PTY {+eh4x1y<afPGVp=d'jLmSA4JtYnVz՜:
-p%?5ϗwks1uciLNU%Wt+'<|2WH<:fVԳ75?Ŏvĵflv4
-soKʫu
-
-Jxn<;I%pV^mH
-] aͼ'K:l+f:N)b˳žFG?|
-s+ӂ 78I[dVK=Y+ٓ+cʝS͜D谈-$>Mt"&g`%ilfLx>w%<?-5k6Md)?%m׏O3O'F'D*]s{VB7qn <Hv$}5p
-Vkc+l愌8K!H1{!=/C%,wce^F<,UwtHх.zVT:a^4f/
-fH%AA42:JvmR(Kez^ xMZ>e thdQ->[?xhSK#W'Ru+C^
-~i٠9i"}XHqIddW|RP1Pz*(%5M ` 6Oa,^TQFq1@*t+;
-O8BcP[\oeҖx1:V% Y f DHhf}㏠DعC{~
+xڴeT\5;wi !Hp Cps=ѣ{jh
+R%Uza3{=ș '/osff5001!PP:Ab@
+TQTWRfxX񟾈KĄ@ :ڟO5 hAPP{_c]83
+_K=? ~N3{; h`^TtؒpU0ROFWGFYCI hdljWAK;׽0~$QZf՟g`r4
+XltL
+i}-6iJJ b1.^Gf8ij="Zݭ*L~jt̏<U?ʰIc;1_ԳlH Ͼ#-"+9Jq ?tYTr
+ej:T\f-sbOƋU
+sν2,NYAWtt mV/P%3V.ES5u.(Y ^ ur,YX%<#떆BbC̴͕+ncE
+JR׬Hj|PPHP1L1^R
+t۰+i˙l` e-7#r~s
+]y"l,~,^{BnRר ̟F3goo!+渽(ޙ^{:&oպOYG]9:vJ֑ڞ*$*ĒowK; ۞5?~|̷6qjmZx~R43j cp<LsS@ db~@+i_x?L& oBA=ž3пLY2ΦHΏn mVLf5<a=i=,1F.
+x+`c#n >YݚiI,Jo8*f+eQ)JϓpiGj W
+nA(F;48oĪC>#e1(_wd#$gbc{f_m]nmRhs0>tܨyѦqt'$'#(I\s1xc ($<qPX2J, G *27;b~˓>Y@kMOO|
+>le2ǩ2LJ2\n[X7l/0mi>sqn:AЄ
+R+y;JR ls!
+Jk7˖}K.T9 z&fɴĠ*,RXҴ:1/9S/mMod6~+<$`ǜs?ܙ7I A|Ja
+xz
+ZcH꧿DHxʦ25)`x!'oO4}Ut!oy_ǝHMqeGe?I#<y3Zomj=O·C4O|OvN[š2OuԈqK%`,Q0<`T!bHy[p=Ґo[{HukԪZ|'*_IBe^&x0M⽧0}*huՑ:%:lB.5{Q|!>c Sp0V'}SȮ=oj1X\0J[Q_Y.oN|ʒ|J@݌$MIoZjCkyw.[De98᎕Tbk ˴֣@b+Nz҇.z'VWti{)H^G^qܬ2.JŖ0RFȷl~-?x:
+ܤ<p3 |iūCiʝfUE}SiM eq}H 4u@"|m[Z#%)6IՇY"aS R`;V/D5u-`#9yW=
+{}w*,;yO'pKpUJW`Ӏ`?ܒė;Uxk(߂Px`TX`G^#H_k%ԯ)-d hb !R" BROTmi撈ővai+2b̨*dqe##haeJn2~7rFpGEM'owhVd*G߰k3p݃ivM{
+"Vmn p*d,Krv
+t Z܉T#b:O#Ęcw{b9
+ QqrzbPiɥ$Znq
+@E )&_
+^=mVC!hNJ QsuI ǟ,ؠͽZvhFVƸg{/MȪƶ=$ JN쮎)I:"Oԯƌ+gDAMzWř!k3}ynP1*́9bXG04e,61?]5GS
+gn#'.>3^'[Cn/HA[֠F;ݘ&ʘڝpr5YpJ_|5j$͔zt"JM0gVpWG1.lYQrݡȰj'_ŪnR5mr;m'oƏF?Ğ:P{q5xyϧ}Y5a[r!)K|mҧY75ޢl xdwQwQl SsYS J"Fwܷ@O-0k8l`X^U$
+}Qù|jTiT%
+eM
+>A i/pTjmD:DnNF8aL4ʆeS|;`[J ;Z-?t?/ޥ! B걙Fa(uEXT@ڧ!xT=ZB7
+=TF/TjKɒ 쇗hڮ]H,YVFxJ$)Z{÷ĚS?٨FO&olm\/=޲Z38
+ခVn.h~QqZA>A\B2`+wT|sC505nV~z~G36]zh+Kx0&QYvAوm:ʂl&; "u3BEt#STu0}I[b}1d]SN"B(#Ƕj//ISVׯ'M1VBɟh2 IN.JSM",ᇲ؆;[
+ W>\.:26ɆzWp$bKClAYOCki:'{*)|gH"2R06!1ER|_.ot\Q F|J%q_FbzuP?*+(a ⩃l:^"!ܛ
+Vf1 jgi[|(_HEܣӸXbC΃55a
+3mQLgu!E50OuZZRd蜥LZfKW~۝03MMdөGK3ȉC@g\H%m!1Ǘg7}IHL%'jfs܋ao.R@"j]WYa%эY7Z<HR<f^8vy tqRj,)ӱPr #q2!M"Js=x~_>)؄Gq1[I06)Hs̎}h9Q?6k1gYMTd
+ik+!hx`5=ams;D4){/z 71I0*L\Sr$}Dq+۸^J_[L?UI
+ZF~4[!\E$Cg9??i&r_(F3CDxR(TOQ.|{_
+`~YM:HDYOKޠN4a֠-1e}(2%θ_kͅbxiyMnSfBê`fjz3j%L6P
+3օac)"oee!Lf~Dr6!F0lZ04]zhm6jo ?{ U1v@6& oYV EA1nmpcEsUx4L-ma ˆڝwVأJ
+֖_H/+ǦkajN,d Qn0$'$ 3(t ^K\n
+7W4(M#D}HZvJ}`"6ZK".Z<JI}g4>.8YOBT(!8k&JD|E>HpuPx$ig20RGn/@־9*G_bJU
+-'Ngv:tASKR\Ƃ}; e&^RN۫l7/\Ia>Tjڀ`j wO͌~ScM(M<uۍ(kgc6cA4x^]PՔ^fq_?DɠL?b蹒52(ZR\Y
+~
+]_?-5Ў@u@*7㰗1D(I#,>tꪗEhEs8yj.j՗lh0ra|+Ȟs++%ڭjŠd{y ucGԇmu^T;!1%*~壄TbS:O君4BLk,"$qF"`c0vFHwrb ī%ɔ_
+n&& Nc׷Ý`å[)Y}=du"q:jD$_lp' e)Pxȣ k.;t}Kw+-%4]. ș/]Mǂb+!iboZɢMkG*]0p0}E}bߌ)h7r!9&s"|WA4əɪ<?:Ɖ4Գm5c\LH`feYh^N:|S52Sb7 ^<epZ#PyrRc|vWd/tA}X7e׋"?
+4XZqkykW|3_0$R ,
+z)':䫐03+AapuIO^6X#ӣOr @V"VMx+׻73;+U8ً-aVvtN {Ŵ(tد-EwT9_+y~;LJFDتE<.Y=օcBqb4n?xgA8b1ՁZ^jk➼
+je@O|w9Ē0-Hct >؀Cp)q:aeO@Nm
+*'OzVU?~4X(T
+U硌r
+D#J߮:7ci! ԨdVhq`S1<.ijoƧ}f\䕟&Gi9ijZƫ*~w}qǬL(rcǕW
+;ә<sut#2 O;Y 8 V*hWTdǣ 0|^M%U!dHEFˇJ%ݨW̞wWO4M!,RdMN tzZ
+>(r1iN L)` a4*PФ"ČeUӍxHЬ9Ɠ5 oԁOI_
+Bc3.@Gsa܀3,9́%l`eZ/$RҷZkmFwN-/?0FYo`Mh-:P=Ad-xv KL
+u볒W 'W0;k9- sea [H|DL86J9>$͘|vAKx~ Z4]kVm9R(xKFۮ/!gO ]O2ڵىxaU`To,l9z?AyH/kXD߁Wm =;q('C&pc0-CXę{Zo^,qS/KLY ˨xX`l -\<&u<¼i"/_;͐JVid7tDڲ1tkP,ʂU |vOBTɢX[}1-_~5K(P)L#s|GN292/;nWׇ v7WҲAs4D) ɮ`-Hc~LwUPKk20ll/&Yt%<cU=V7MT-8^ V$w
+x]K= Y f DHhf}㏠DعC{~
-A~J<R-q556iJ~34mxcdQO$aaO e3bc?6~-mT\C4]\ϭ?
+A~J<R-q556iJ~34mxcdQO$aaO e3bc?6~-mT\C4]\ϭ?
o]+r.&Y^agŅ@LYj{ՏqWaG)xGB1(gj//e) ʒ!TL%}X
ÈJ y0Jv猶5k2De%=[8aE5^o=_ᇙzdȌln_vd8^m1M߅qF"D)'dK.PrTp`n
ے ޴x{~-{z&+Zz äbi!LUŨ#_
-3Ig#7]fp~xlIY(W})XlTD9f[!QdeXaqчK謧li kʹ Uljt=whtb%$ucni
+3Ig#7]fp~xlIY(W})XlTD9f[!QdeXaqчK謧li kʹ Uljt=whtb%$ucni
c/$߮Vi8+ej$ nu dB>@*tQ;i`qn`mޕ~sEI)fee+PaĝJj/aA d"z<=,,a_F[vP֍Ynt\EUW+ϳS<;Ulՙ4HqZR<=lj ϽNjEl Jai}> Gl2x쯁
*_|m֍(+Ŕ,kBn]q^XQ7B?~dDf$854IGqѳ"k>g<D;YpN]1+EDo;|g\h.w-]a췘{xhe Jn)
-k^Q֯
+k^Q֯
B?͖P!
Xi<n&`n4)ם^1P3J}a9+ʹgԬv#J^U# g.
-9,Ȼ{c|}ԑ[IEMb-G̔ĤYS)mf8]7M옜r;Wіʽtix^1JlCʍdqlcb7yg&=|̦yB_agZcY}ѷYBID;0E4ŊXpЀš@[ZM o+Cq?CWIJk
+9,Ȼ{c|}ԑ[IEMb-G̔ĤYS)mf8]7M옜r;Wіʽtix^1JlCʍdqlcb7yg&|̦yB_agZcY}ѷYBID;0E4ŊXpЀš@[ZM o+Cq?CWIJk
`]x{{nNjJR8#%0b⍢e L
k&
-HJ8YtPv-bPԗ1Cz<~^tf^%/!Z0>8;)=*|ѱh6v@ ׶
-PF0d*x
-`m
-f
-^٪r$ Q„(KMVMm=R~6V*م5KNgvy~ǽ1v37>ܱ`#K$N;|m&6´IE<,;sD4Л3\28%D'EqGmժͯyTEݲ 5N|pҨ@2w&ݧhN ̦%c;&-߻GBFdȓ"HhE~jOMU*}
-KyeI$1R}2o
-$Ҟk|\0:Vz|,|F,=U W0jmwC('C8:%2Py_js}&uhڜ*o8=~nXRmxoj^,,"U'iQT+
-c`RMQ~{M
-p1/EH|I:oΝ3g0L23)(*~NxM.^7G}gݐG4aX_%F3ב|̸pԏ㾚 1G7]
- rJv'h/9i~͂P`Jh:(£SonBGydG:Z.ȓ.~\Yq o=3оl.C1v96`:Tڿ2?iL\L_M4=oY3,<ߌ6='re^E *efFFɬ0,Ij[uJ~H\ؔY _rv)<2[0=~T 3Hig}(iSZC5qaG
-EmF꾆} olG5l+vS-x=3UV|@oyW߶
-f?w TChmI9Ia$u;MpfJچYXqO$
-ZWUA[>g5M!$ﲔ'h"y$^(A &6-yv8jZ$(`6+-CGOl7iLN{
-xOn^âi*v<]
-~S+^X?%L[f#+ډ`"Hcr+7K//Mڣֳk=]'
-īLozeJ@r08Dg<aҧ8#w_eWOEɱح*_;G^ GY V͹HUIC!׌w{W;,cZ').>Qt])KzKWZ9x7hnξm"Md
-`Oxa6ԠL)dӵ!69xG,ύI[m`1!Nj,1V]?둓WjI7FAƗ;-a@"v ԁaRϘ~zFD֊F}C&Q&Hrأ-`]9KVS_45S<0&MJO-EoF>$eRJ<" %/&8\ss'R/JIV#"B mkh86 xSd,Vϰ ^.eKQ6t؛FQ XVo3~e~*g̯c ORrR
-лK&2˝,^
-]&ٺ@
--BG&F_K}}D'KMpn jF+a-2߮D*%f}PuR/b' Ma8}%1Hł$呒R fn(EnizF<AJ[r+=\DjnV7 &0ˀp'l 1L?x ϧy Ntt߳05ư,>7 \Q""VE.S-X+2e$ p&1gCTqsF Sðs23
-(eB1[?HkXKБж "rC(1/ [7ƋF}T/A9Z`2Zܧ</rlh5}ztq~K+@hgH1:w(xk*F *H(ZӎӶU<XшׯOGFO eGw|dHke='5c蔞zR"u!3a+q$:P3q"eQ6!wl( $&ٵEi4@8m
-/>}'Vgi
-I.$;cP'i޷~vGb>%Y-}ѹ=MT"\0˥;Z||KjmS\ s={I^Mb \21: ;6kv<|FL.pC]={TYrzW?R
-',혉TQ!aS̒Q)IaxFedh}Bwx_|<B:{jKi4{} &-8 :4lMm߆u ZC @]*6,ln5K#tTAK3Ɉ}KoTHr~7y?oZ u?+z\6+:7kwb[{b+ȐesEW❴ha Ec6^}^Pj?HR9lm]1ù4T"_n[?D3qagz|f+`guܗW I,M]I[oc̪Ypz:p ?|mSƕ_K%\1<\z`?abHgRpQhg8ti0e2}1?`g
-/m3G0 "fi5]H[$ȇzk uXQI`:m2zm,oGr}2o"Q2 ȩW{,<mDpcHw:dGdjՋKowDJf'QN.Ye^H`Y~[Bg :cWU]}7# pWr ,Pp.eӽL[@nYq;`,ήϩݶɧHK}O3{yAڎqnLzHۯt'Iް_ȰfKk [-0d4z: SQO"Vʮ ί!MMRTE`{|FN?}ժݚʵ2AƓ[ż)HwK=+9aL|.q; !@{XJZT "SempwjXi*)V~i)g}uKqm( [5R<x.q_6~y6~O?m<1fމ$ULL ֡/|hx
-`/pXlK}ߊDM}J^)2~}<o*v.rb5Y缐iUS[;"zbRI]:lN3OYIc󀥂Z^x6}u' 'C؅MQ",5LX
-p[La%7Cϝ WI C|M-N2+zCIa?XB@$/$ݿXs_]7U44>bq4" "o .H+:a
-Gf/GR8{Fg$O~V:KShJR"jѯ kw nq╩!?cYz\iBZnw H+g;miq8 vNma%MON0 B𩢅n1wzB>lo
-jBezTd8!+7^Õ3sTr3h r[b"}$&LzK4oK70^
+PF0d*x
+U.xbH({Y2+v3>Z.CK #اq H(e,zn-Fh#5@
+ رM};˄s(W<*,,Uj$#֎>Ks`"v~Cfz1Iiݶb :d4\4 HGKͳ51g*&d#q/IJ?E2c͌wà+#I^/đ"1qMAƈlg;Qu6׀]0Ro{ B)y_#F!|Fܷ$
+$R^j!з;Vz^}#Z *?Յ+^t)'Bd%_3Po<xhsд: Vf{x“pn.675oZ|z}`EK6&&Gw;1x&ޫRN&}>H[UŽ`tZKҵp%,oż:;PY_JsK~{|ڳ(0GC[<7RMVUU )囮ň $Nǃa(~7-'/Tx+25(`%{^d}ȑVc aaaōg';ڻ.͔œH}{1}T%[wŃ֬P'pFAUEs| $_]i{)2y-K ^v&e@=S=lXk*:EB`@Sam? K>utf`Q`ϫ9eV|.hg62"z^5`б?x蹱\څg>gmSyba;Kk^ơ]#A༨Gv6 h7⽚Y)C|g4xT
+ !vEwҶVf˒ʑaOkL!S`*P63@j%:Y >!z
+ShjBʐʜw_T..47a0HsLj:qvS_,
+fp1/H|_JڟEqg c Hf)Ȫ!aA.DѢ뵉mY7VI$zu"5- Ӹgr IE^ND655ͯ;H IAWp';sq:%=t\Dtjπ{x)fsǴ*J)M0p1 J*kL|7G uiߛ93ߍ6'NeRE *#FBI-Q!ĵv-:%?$ʀ𩾷9vWB &O<Ӽ}fiPM s?r32%m{
+e9##7#IBtA6w"6a{{ά"/bZ1}=.}['QD =΄8=U3)2U GEAHd$:ˮv}~{D!Y`\<3&TDyh@7ѥs4'kgeJ"4u>)5(wGD 0\[r.,nuw(׹ d%IrHZN8* 8?f׳l- j7tЁ&RT)HB:1X Q`s)gFQ4'/Yw)4 0kFl^_
+<h\((`:+##0ZՁ9gya.!HGj"L}|]AXyy6zZv >*q C+!; }xYcgYF#)#H{4;Ǩ\m1O1ȩ2R*\9׷^HF^285Pd`Ҫ$ 8,Ql2["΃d%dJ$߸8QOhZ0hh/1uzxZ=XU84Wq 3:GOoAS~f#㟜 G'I:-0D{"p7IprX,wn^Gi*v\]r~ ^hamxp
+vB0($/Q˕w̥͸77&ڣ=]n~LHݟpGxzeJ rˮxa8#{WA3q‚hVaΑQVi3ȃb=Ubx?3/vv}%y V<k0<_/%qxCoLk3 eѻMl  z"y'pX TޑP/0¢(vqP[Xv9}= ;ͺuI0 T's]w'Cmrss])즚h>HU IHjw.AYj˘*EMcXb؁ZKTi2$jپ|njθ@~7&aV$BPi\]yGk5 lӍ{4U> %5x":fh k2`aQF \.7F R'Mk0RʧMX<LfrTjPjg
+U%{A)<Kb t:e7C;GuY#RtB(*}54+o񌨴"wO գ+a(IJk RJzR[r~cFfoQ
+2m/\ w MwIvj~ |n<?}06;*0ȵ
+쭛s2&ϗ`%]^o]C[d\nE*%.guqߣ' MQ
+9}@kCM1OjvU˾ʶ>h$$#_>
+pf)E=3i{F-V{³#uLZ
+ =;U4$iё6HF.^Ƚh>1z
+;O?NL/L`݉Al 2JnI O4@ik?.ɭ6egA
+q _&bAxR3jLUٚ<^Y@Di1Kq3l)Vɇ雧,K `[{wjzQ,(egw01R^|"MOflu(./JY+G<_pq 6҈~ vBvd]CLj2, >
+n%}`BI|>u&CIri} 2]04{O ?=btO/x=1$ᙦQE_`=ڳ|:V46ZBIV[,AyLNaA1'ZW/Iw! 1rπ tSvFꟍ'Aģ]SQ*L2*# ō$ <T#q22k=3j߬>`fnf|?wgN}
+`J
+N*C,ֽGLWj4
+u/O홡ˆT󙜖t
+WEK*_?-v
+jA#0n7<NqS᛫w#" |ntj'aZu u<DB v`l'ko.Z2Y 3^Q1$UO]zGk-) kеL2(Yf-XR.j/vڦяE[3q$L&"d5&Q_d]W!et锢չw
+QHsemLA~ |,ߍxe~A3Y8ʍ],f+yQPoM͒8Dae@_`⡽*ЗKAd\\KNozW-/mcK{7.TjB8xX1nT(*dc!:++%z)د 2o8<p&T3dh&Œ"d-l\ՑIYB0_2A|:68)jhio,(b2S}JhlW( B&؍̜ 6NWɷާ0.`t.`q$]$0&4PZY": bx ,β VjK,DN F D
+oo ΀1u51(7$Gs{J g
+7pUkp!M#Ou
+-+~E~cB!vXUV 1k<XSD#r[R-'.?U
+k#6p !K f/d_)s3ڀyAf8:\g*0@ujnЏH»- ]., fl8F̣z$gwfj".ހct#J!R~MkOW-gQɐ[l:FDq?ZىM!=$87t%Ƴ5V6*h;9iܜA<kK&tDO./s4Q.eb4ؙj^+_Z)jl7(zzٱ uvQ X c+$0ן4卒f{7bsC&+֥L_aPo›8^u&evΨy9q
endstream
endobj
-547 0 obj
+641 0 obj
<<
/Type /FontDescriptor
-/FontName /FDLXKH+LMMonoLt10-Bold
+/FontName /JNCQAV+LMMonoLt10-Bold
/Flags 4
/FontBBox [-454 -308 734 1039]
/Ascent 600
@@ -4946,131 +5549,140 @@ endobj
/ItalicAngle 0
/StemV 83
/XHeight 431
-/CharSet (/D/asterisk/backslash/c/d/e/f/g/i/l/m/n/o/p/parenleft/parenright/period/s/t/u/v/w/y)
-/FontFile 546 0 R
+/CharSet (/D/asterisk/backslash/braceleft/braceright/c/d/e/f/g/i/l/m/n/o/p/parenleft/parenright/period/s/t/u/v/w/y)
+/FontFile 640 0 R
>>
endobj
-548 0 obj
+642 0 obj
<<
-/Length1 2814
-/Length2 28211
+/Length1 2866
+/Length2 28618
/Length3 0
-/Length 29748
+/Length 30194
/Filter /FlateDecode
>>
stream
-xڴuX>L 5twwww7CCKHKw4J R""-R;}[ߋ u{=PkHX, 0 + @YE`gz:Y8YٹQhh܁`{(ԬTH;
- @t8
-)
-r)-m9f
-reuu b lE([]<dA;!RB v? Bt;k; rՕ.`$l
-.6 fsڨ ]j rqXmPTA`HCk,YO''U g KqN=/ wg {
-:y199 b
-ؼb\hNflCUZo?.j|$5"{i(d
-&th@\e<)5ƒiB_ٝjĝ5ԫߝ;^n0: `i7,TQs_fTd[+-^xlZ44U 9"Zua V}io;gp}:H J8}|yA%iEцxkNLb-;ZN
-$-[zE~z_nA,޳nX5ț:x GEH>}I}SDc Mu7e!xb%hR?:n8=^TI}(u_z=:%Grrqm[tG4"pE{drjhFMIC^(
-&XWVUE 0SKqE(0(vl+?khOuN' :_28%d=ՏY#ngZ(
-lDsq8c/.KrX&#Q='tl'-`X$
-9ž(gbL2ccnLa``rtM\
-28 7ƳXwk_7V_5*T<M F31/ }u^/+M'OR,|/yx?WJ:o.sw(y6zHӳWqzNŁ$S@3S<A)AU5Wp\®KdcoicwҫK@ha܀-*VD|4M
-an<#[ة53/22ڧp Ƿ*q#ю|l(n$WpAwI$BL0+{qG\?V9qS$WpaA'FRD[Qˢ>~Wً6ޣF8D'_;]]y^~Hy<{gr>,%&k)nɪdiϝIV5ʸ1n>UEIv/{/T,G3esAh$w>Imov ^ĠƲ9&;L+Dߴ6Au՞-W\k{>2%p,LgGN֣slnJ詰{tkbVmL/3v7ۤLL7T>ZR GT1Oͭwi <#N(nݗze]g$\x!مVATiМM=mWesᏔUY[OowM@M<J2
-_*ɉIVL=KٰW1jSE+nyXdO6t>}2R yX RT})\o
-P
-'f E6@yPZ{aD,tIG~Z[`ʈ`>IKQW]7ښ$ͷs%9^j `n\`P,)R+&vݾ1!G~6T?H+79iTng0bn,'&ǚFm̖t0Y<g# pNjx7v,sL/Fs>|q`|OCpD
-ehIL1Bhu 貳91@QAGP\Yq H^X'dknV5jGЙ([DDWۓȆ*#(4ċ+ eF2jS]-VoX%BӢ9QMOC̉^pspfYB(r<?(7x9,^]]cBRu"E~`ZMm Lk$8* ܒXtoy] sJ_;73M>2=-ݛJt11t^ѯ#̣\ =YoJ"FXܡ
-T^fXO"~ٴ$#5eo0c 3Ka?]I
-yk];2/h9LzڢF>b΄zף&+XEMVU҆lNr"fF+sAlG8Y2#=i
-.a
-9ALF&l3!7^Ulgۈ{gOH)Wfoȗ*) ͅVW)6xW*_yLUfXoH^`aw6!|,PgNǍsܓ@NŚ @/6]Jt['v?lxס@xØ?ϱv76Vk-NjƯfN%M:]q7{5uǖNy9YK^du]QZG/-f(Ŧz(PY_zxGVyWqfm;uzv+xv
-z-EQr:-\zrZ+ jȼ,hqUqxR0a|;1HB5uҊZ8$De# R %t\n5h[DIʞlBS ?3E ׊ދ6E8PRs: ,ɹf4qp@T~q>td7KmW魰ÀdB]:v~2nOe-T;Ax=ɲg/ٝCݸT7Vm(H{)Jpu< w՗jt_+_Y #F;t{}wfوpkhOLE$ mfcR[N@:oSb u&d >/k뺥.lxѤ棿3CK".*e)!" S`P /!An$QЗgQsM_|NFM 4ZGbJ':%+<;?uEI4G|wM}Q k(-]
-++̯ԹX[h&1˛vUՁ 7zE$jҬ%*gjiO%4?0{n]'1%6T"N,~|ﬨSŪC)x$x6mnXXO4Ն=)>L Eff ey4M+K%+{Fcg Vo?)3b]JtPC:u`ߪ.r/iaŰ\XvfL|j/_Ɉz#U=ںo6!lgj9uդyd8Si2c"5%xɪ*҇gNL﨑
- B(#HMvX_ {F]7ۨRM(l엠{C-$¤14߼DDLlʫ(>D7w(X˖G6;wēV>oZ&™ amHt<e/ZPU2#XxHo}~z?<bF; B|
-tP1<E
-fR#VN ݷ;|M*u[d3Ja.CK J Wຜgo*ӆ`VJ؀(ņ=݋O+
-r@5]U=xA@lԤX`.hR2I^{u\z'XnIP˥0"O9. MA]h" X2,D<?&$?e1Ijtja?ü+\ڹy2U0E̔7`@OaU0yV 7tq1rӦb)CLV.a2)ڶNBqs_ѻJ`^}m4/+:%˾RT⥐R?ΏGeVL/bkkyU 񃟐L3_܀w$nhH\?N? :+F>hA~jT1/xۉ_Yah ӇVKo̝ 3OB:&w0 HFLsMa
-6g+K-RE8$|nmf?u@W^ysl݃NLuf-pn5qSf<@vYUHt MWu[Oq-}CW7Cm"xZE·Dodg*#
-3N:E],>*qeĚ5AJ$4yJ< SQAdMT:; B6FxN{xu6rL֬k5L$KW%4 Ϊ<S4@]8h9g-ɘ[%⡉rڟb_j_eȴfL&4 vC~*B5T|+c1GW&yZ*!' C;Qk/aQ+
-DI%/ogwg5>#&@nMQ#V&Z8-;>qEl'2ڄW~Z$#QP׵Oj<˰{qeyVCr H辈h)?7PkoOl|c$|h#9?5*".0kPGSnsB*ûל/ 5g
-
-^Hmrslg]h5Ap~#d=jHH"X5tdX@m=۝:Ȣ"K&"s>Mٞ]NPqo8f6xj;.ېNڡCyL&jLN~yaOUMeQԴNqThtCT:¶=A|Ȁ[ opEyV㾱i3'z!OV}r3rkvn-[hX|B^'墌~"m
-5BA.ϩS:'V2-&vɼ/흇L:)*滻0}P0VJ4|,5pHhx
-7z$ GHZn1BIQ2F{aɻV]nG'|`ġ$,8I{Pu&U::P0w_L|ҍAu$JTbە:θ=rvFͭQϓHR*#iO7\[hs}ձ-}=A Uf*LZXPs
-%Dgn7
-0XSS=V 9`r19ȣQÛgj8]tKQ_hSM9Va4Mf
-bKL% +S+)%x#_͐on0.|M;%Jn4Nt{@5wbz,;b4[o|Oʵm7,`cQ5g)ڨ~7XT; ,4S LEe[#|3e@p4^Leu4RЛdftyi^+@58jg@cl3Aw(q|rgH|t*]V6)ˈ;d^ M8V\ŭO )j]RZ˶m Y/3Xcv~q!츒πU=kzEbplŶt ~2z 3j'd[O2f7֔bFeby .[O^}M]w=D [BnCKQjkZA4e6^ŬIeYrJA{gkC\\v.%ݠuׁCv1߼7As8u.sxgu=u":r)}l]Psv`D P DAk%S@hJBY+
-T0=Έ2&ކjry I5H]L2͛t#&g!lY]|Z$囇 # (oDf):FpB- i)`4j^1哵sa."tfJmwrC=՚XX*apY2DW}d]%*Z`쟁2=۽0.3]ЧDcͨ)jw[fXL]͙B9\_KY{?]\ՠKf֯
-8v*bjy`7a33i3]F!cT(y::Pa|G塐t} ~l5;|>M:
-q9@aNОQ)~ҥ5x HrK>Bh[r,V- 2 #&Οh6ԓl,nq5^\"й1i!ܓ# C~Һ+{13|MEnwˠ$D8Yvr
-g*W;D'k=f%}d2{@bi7`V^Ȍǵ2zt j:'X0 z6xL/r$tnt.p(F(Nͣك/ez\JP$I`J:gg]ܢ<:.|MMDMC"b<{t~Щ6Ia-$'n}'eeY{(u~3)oev~V~H-T8W+gye""XVl^X!MOr
-{L6VGI]dfAlxֵm/*#<Tԑbp~B&jCRk/X{":F[k~:;G2p%N
-ɥ7xybԓ4Qd$i: mDw1َXVb9bc#b98uO QGhLK^~6<]"~63{]_ّI >L':fXJKJ̘&9[;&Aot^Hm 7kѹhۨ2SoEEdgU)#[ CKMof=k5OPTMyρy -)z>vj.04Sw\P4PKտnB"2{'o«KtvKixuE5{I\w{㹗6e9R,5&RvUK҈;̹ &sɑLQ{?`yȇx:j. vsP>}˦\Syy7b[ -_}3f{ס$Q36wԵaw7y\]2Quv(_3Έ2F圻gvݧ Zkn-QG0T9\W;|6tyrL]ؾBz ZEIƎ 򵴭qnƬQ qACqCF\wml 7 !jD6B>S9BJHVliGpT5WP7RǏv*cj[Smp
-P&_݇v6w}tPd'w+%\
-Ws`uΣO?Vl\܏X3aZ.PPX[Qb1k
-l׊R{mE'sWT<ރC cNu[Ew
-`Ѯ=<w3y(;͛즿x ء<NxAqRdomtB lѨ. 8a2!d|tҌ(~ eƢ'%EQӿ+3[ōVMQk,8[3 쏆Q)4<}~fOG/(uy9_3 Sr/'H߼) @h,@PJ+q_@3Yz5˦)T?rzFRbճ3#>Ke*>h#EIpZHZ#>+m1,Vi
-iĒ?E
-tLα`/fJr-VSX<gLDBCy(™j&iTb[!?~+{?|v9}`Jx
-V"~fTs;lC;uP/hyU1%k *`l|tguʟ] w{\`rtƛk}rL嗆 MJKdD̈́ӘLMs$l/ !WwVTJ
-rޣ e=t3YbM(wGSɘ͝&ؖPW&؎~L@BWr_)_qV͵sTRG&D?z{˩3ˆ
-bK% <\NF
--S66 ;Š zfb{ѪO#ue=þKxŔ%t3A ր8Ǯwuu?<x4mz?FV߆&rg:LrǟTHMo\{Jsv/2|+1㫺N= @N!R8PCZ<_AIR
-H%[̆HU3jC1_8T߆k*_yo c?I(
-E `}kr~m╮0^l²&h=X9%5rB/#͡+N-3Lբ0yx9o>허0ڪ]Q[*
-X~5 ?*Rg?d/zk z8ED~w7W7ځ(ʳR!8 w~>Zr|">QB,d>LjfYshȰ$9:„cж3kǖ_"FLĿ+ T~E&4G_׈Zhi9g=jL(mؙ ۘ⅖_x|rUdI^|ĮD7n
-.V:=qMA|N-اqn-<@܁GwGb^ t0,%ѯ X1F9R+oTXVp`>}"a<GAy$]m[.iU:Š v3)ϵ& agO{(GzVl Qk2a8j3%-D˂EC֪{5^4XaTۡ]+dH.c"ߒ2FdCuEKoB5nZO3TtdTz󟖦81,tX|QdsM]]9hߦ]ӊH"xknk o6U*>thjJ5|* nH\*hN̏2(נ9h c7za +
-Ӥ+z@؝UBB3#efr Jxn,UfW&k؎jON:q:K
-˭C#7$3~~% 鏜Ow9<a}b Tx'qs))8`5sdV->q]3teu`m5>i>Ҿ̮M(NV@B[~(~$륮OJ qnϞ,<^ˁ/@OfD /,7Wk YwB
-A JFҞRfҍ  qv3r]4.d"j9=櫃dOԉ`0ؔC^ѹ䑨|MÃ|Ed&xurgk?׉Y{r
-<cΗx/[t(5᢫?{~+Ce!#@WdpiYʵe1m_<:nNa˭ S,E=<]ޣ#"$;V5?>ڈ!{(vJ>`S|4F3\gun5K mq:Ne}2٥?m;[_L=73E=cht<qcWu9I {Ak%H=* a߽Atɧ
-[E5 QPH/۔+_xxeTyބrQxi0FL{W%QOtd
-YVBLhB?B6Ð
-r(R VpN[NI5/.2 w5RFS` e"3 K |֊
-gQY vgC*
-2{8 率6^S0C,C0eG]ӭ\
-Hy*w_/nB,FU&6j@Ѵ,<ܖzqp_*
-K[+(`o+Ğߌ F3t)~\?v~lx請 zr'8kd&ސW˒ԇ~LPR%ۡUWUJ^,*53X>TVGN+e Bs!NM/N]v0vd~]BR"#Y,)ȇ^ `%8=9Yxvso0Z7Ai|,E"%1~4#J4ZO)xLR.cVZ@:LMNPkՖCRڨﭻ@;UXlWU$c}0ΐͭh4Cţu=6YlA|>>FP"S
-53}OlP+*'蹾O
-䫦˸75j4ᙔs{ڌJ
-E6uĚX[]w æI䇃8,$hLV'YbqP.W_s$W7f#i `y$
-e87*yjG:?+!3\kDn.bPJ3
-[=z @}ۘK UZH2Tִ V&Lc&3Rm2JwI4 '!z%qS[`d w,ފ69S45!I:!K̀q&>x5,+
- s9=f<%N;~H=yF_
-\oc l]R莱BmLECR|sơ,vfg\A$B0w
-5>t]d`F"Qnw}le8aU"mL68ߙ[ُr t⯠!Ѕ TXûr)\qufl;R bb2ΠHkHfv_T/Y4]lf/."a*>UI\w+R.>76l9SYĚZTM ^9&:;!\̱+^ߐyҬLϖe%*ѕ29~ښlp^5Ot \P\U-Un8ʹ0Rfl \V9W5t-Rj6bOkZYŸiْ&ncuҌ:^%\X"
--fXmo,g2SICCεĽRxE% Y9!@)ҵFh澎s Pٰob}SPPM .S'b|_y Ve!1l?:-g¦KqY=kPupS6#K : =
-rn\0HkΩ'!lQVA$,>噊*&>*2? ŧ
-dRwxkr-Ys0lt#‚GA旀 C?JK&ХŤ ~au?eĹH`97CyCT%ogƠ)jؽIt7RSKEq~Z2;',jT&ih@%4O\2K alMY}1sL\.}x]|S3 K [X\1EڋM>0j{M}Bz_`^- +OG$C<KY)Cb6u@aahf5m1#U|Q
-M|g,}a9Ē\yk)T`6sY1LeR,.߲m3щG -O a[2(T
-zS/S^e#xlm,GZpL {J߾Tϼm> ya9/,O
-or'QA6pӿJ&Wir"qJ_}<ެB
-@S:CW
-͒97Dg~/Y#Oa>"Vћw5t3]),9H&o:1~2^r#LIfˮٸshE\<_`=/7/20*>X%^ih:VRf\ڣd{\d^ \;Dp10呂j_ TnM#(1O'͞/rR}YE+ErgBcSE%yTE );- Q9E̓?B/wO 5c^N-HmcwJvTå3OA%9U)]8 }p7_3hQDrHzˏ/Z|_C&Me3&3?ݰ$q*Ǘ@'ҳ%xr
-ݞ,nyxݪk'3N6u
-kŒN ܫ̰o+YԳ=Ta%x,~E nQw31Wi V/QMOQ}2 7nAyovrM
-"nb"8Gveu|i3<C(KCƚu-%qq,|ˎNKS p]ςݖ]ng%(IFlZqe|nW D=sO(ݮN45Cu%T# $gS9agڗI
-.)/8oJ @GRO vIOƟe 6|6v)$ _1sUʞԦi ZLrҐ>kސ KeQ*9Ғe
-a'r nׅ!`nr5.ttbɬcʢk7nX7A7_g"BZee.Y7
-"?0-|K]g#Bp9ټ/G Ri$"G$QϙM./ԛU+-fƊ3ʩ6vbD]@Px) F廰<;s%IMX6 F)jBE/"j`R z
-
-bD8☒y叡00= sE;j`N؉Hvj*KB!|0leE;84Um `G)Tؔ_
-
-eT\X[VF_V}
-*nM"?x+Ỷz)}>u/'@-ԝ=;@{ CO^݀^r| tTw}#DLcԶK},A+ϳ1JOLqNw>W'0. X D3E훊/xL_ jcǽ /B,6+g椡ƈmU.yHjA:
-E.zdM G20X{dg:a*g LsXPȾhi4#C "KjǴ6!dSu<i|h(=>~#`DX\e@pt"\WvnT3MQ֞=G;]ԩZ:XnrxK XH2=QYct Iv4INdObe
-7?66t_x
-ۍ Ieπ
-޷ T`Z RּY2DŦOǴ -u&z1ȫ䶚H/A.3Q#'5i =?`w:?u_B&ƻS)RYdݺm;#I`((p_S`躞&';7qp_jF%
-ٸ蒁dpN& ̵7u_LOy55FEZf)LOMe;E+_Qi&JN-؆SDf5l7drrlMAS\gRݧYg4Θ_+ΎHHJ+UDkZ7Fgi=&]KytHgt9qT|]J^&uK7Ǹ
-LCAxntuQ*3[$ߌ _-@Yӧ,|36-e
- ˜߲ƕLsTK|XC/0pvj5aE3N}UnjB5}SG7i!|kUY@ՀՇWcSCnk\ Isf7RXkY|ucp
-7 o۔YK5#V;Rd.W g~.l#/I; GLOW|3x
+xڴeXI5; wwwwwנ n Bp !̜3wއk˪Uުn&Wd[
+`acBtNR@
+`cGA+@n dЙnna H ;lldfW @f;YXY
+WWfg5
+Z! A>O-sG %#_Jvu4wM R[fywsH;8
+ [
+8~쐖z(
+P>
+xj~J\=D"|u
+hQpKP6MXIN8 5ةD:i5jJ]l<@9腴{l.
+]\mm
+|xWXDϷߚ_`jV;ۍa^rat&;N\#b,2ØBhh}Ƥ|),_fJ#͢zٍ& @ݦ7HFvLAv{FB#ܘt5ݩ\YCw۽%\}8>gwiv<ɷ̔sA_fTr5ʴ!vq6o
+n(CrAkGNȥ\)X97
+Tn]':@6JU-k59=3üf wu(Px/)H,ROH~'?=<鼩{Qu|a/w!p/Sy
++U$G86$(XW
+JR{ ;[|t^Nnb%=+D'׶Ev"We~\cW (-7k A0`A!)01(7UF-{;usNjjei?+{rIYm:{D 6c'sVO)@moLc͕ ̛ؑ%sFBx dCaJ i 1JDk5#/^8, ;3ַ<AOZ9.t,ɸlB#ry-%i;/hY2?EN;7ݠڲ f|i0
+S\.C%dNkL7t
+y{x4B~*k ۼAk*CӇDmW_sΉZqb;d,Q]CzĮѬa$pp_ss[\̳0EqvbJOWg} !bQOK? T+
+Lff\K3q{ZB顛0
+ǽ T} up %8V3J NFR,Ĩ$8ݣzvl>yi #V受}8StSw2'$ b$JG|m#|h6:Kƾqd˱Am}T
+G<Ua~ScJ>_Qœ Lxy.NƧ{Bw] oM'iR r=^5$s!/P(p-c chhXlDf̘yzblՑpR-#ޥ, .<ܙIP BSwK_T|
+| vp86GK|DoȜl|wALj60ֈ-b`Fp6Ca xt@ )AfJjw\| M8-frA%rK}'đ`\սsN{襉W3æQ2"Wc3Pf!iuG
+倏/<LaB|Q+!ܶJi \*G"E;!xrqX2>>EGW*{jӉt4XJ<hɓ2,G1d8ocPOWs|W׽[R@;Z*Ox4Y'H~=scr4*W=@Ρ;[IĞܔǢ
+l rSt\d2s
+$x~ 2/qWaI̘#em? 9=BkJe,{}
+K|+9JDwĂ(n鶞xKҰ<'бy:פ.a'!F({Q}' HL^AIzi#$暛r[Vb=6)}ּ/q\/SZm[`WI:6m]|=ÍҠ 8ɕvi^Ͻ[eT#Ylxvߑ}iԿ@R6c`hG:i./Ňr0eXٙzꄁ{dVf:"!- Ÿ[PK.z6
+$LNy|/cv9u-@ĵsT&_%sZ!㒺YWaAm#}S,>"E)"*Y_)~ԀmI?'ȝ8Q"߇i|vFM4zL'5t!yQ9mET;[:r"#W M}Qk(-]ҽ)QGOc1SFۄ,/d?-T) Q g/V(\>SIY,CYQ,`qtg
+L4\ZAtxJx捜*)m/i`>E1_YtdLR7JGfr|#Q=yd1tgjYt^x6+8UEx
+gb TCx?J &#HN[] yD^5XnTl|I?#%@3?Sf
+C'])ꛧM|i)ymcdS<Lixcvݢ8
+aMX8CZw)u ПQ< S e*>+BxG#~ @aSO߾@ӹ,/%)C“g:nh$#eø|L|
+2˧ 4q"@l 6nRtbIsDϽNpV; a{ 6q4o`{:BVmx<٪E!I)Q5>8ygs-O$,!l)oBA|-!wjXJ^
+oji)cd<pMvťDF,H# 'i8T .Ɩ}v|Ul( ¶}!RŽ'JѲҮCkErK!%+oS}Dt>6ï:_p|gjyVj4г8mHOJJON`j q_J=Hh=[I ]tzz؈u)rt |MM s$-e9Ǻ0qbd악M1a?=>ckyN}À,{Y;ܢl.$yY \dİ!=/_IXr}Cj]nY[:%3>oCW@^ZX!Ȯvv\jAX3wm̥rlc?AiB"1u"F%
+'Tk=I{'ԮCbH%A(_/6a;Aʔ5}Wﴣ7=iH2K_9uԛ(L
+8,Y"5
+z?Gz]2PS򗈆&JiDVX6zUY"՜1 Z2>]JP%%Bg >֎_MiT*yUF=]F5BdN*z"p{>:B!Y3rZ4BnF3v/b<^*LN}:i|1JD9K;і
+q^Q[WHZUGÏGs(ɭ$J@@LE DCѩ"VE!</^tkv wwd%cH->nS3B ;ϴ@IU |3PcDؠ2993,zs%1G}DƏ˒GJi co,3脏bIF_zq <-p.Rs({}Qg[ ˖rL32/9\愒i7z7EQ(Yy +־" fAڢ=]ضW#Q}:}fzr!(ͮXվǹC+RM~5bIBf\_ObnSͮ.Q_97<}$֎wu7K1}kebDRn{+?'
+,3.5s|q0z8k VߵQU
+>B+m5A@K{ƪ> Y;44}D nxUϔ٥*clٌ^ 2ɡZw(xMӓɐ/Q@n8^ ۡaWH%0fXQc6q\xJlx*Oe}R32k|6n6$őx<ˊq]#O`Lbh(W _qnbn6s&;{X- qOQ^((bsDESj"$Q݃J
+0.ɬqP:^:YjX{eεfԗBj{Ik\ld` ^גP?ܢ*U.De*f;j,PG+Zu^y&sat;t
+<Y6舆X|bx}$}jܚuTGin;2[W=m@|g;w"9~
+fuu:/W:.62@#xUEC<f
+׽iL
+#ͷ{!bb(!{ov -\;&9aĠLكHzqQ'(;:*D1w^KOļCqn$HRdݕ:[a>[=#]dp$!ø'F N ]]HM=]Aqr{VʌJLXvPs
+AD`(Byo~fBE[*kp1jVRd 8[~)̊:c1׮c(.bjrJWXp0WқtzdƊ@&xGP{D lagMs5S Q5XDCL״t#FG^"AlYk4Hk7P&y^$ L5pn
+> ui"TNu&EOV W2ֳRimWKnW \cTMVWʐ$ z.D[Fy€ zJ_zw
+hrJ(Ɣzߟj󺥛wdY1i{ 2 ZR[鑟ʾflGο]ȡ,lGg3AYFԶLog5I ב,cj[6`+Yz_IG!JD$r&J B%Ѿ#+ŀ )SnɈQ7W{
+6͟n^j(_":2i"YSG{OyW4+mK{
+\gDPY3JJ[]#.I-`&~.4ҔiC0PXdwcbvp}yƲH
+YؾBx6LJcaS)~1X3&GiF^IhocQ]z\wmL77n AJƯeJւRS qE𴫒64C#T4~on\@%܌I?+_3fjHhQvʲ?~?t%nS.gW>ny"Z>W/B!Sώتs6"JFpOgNgPD|I3:FÚuva_1S:KHƘ,> ifV<0ZS3:oq2/~삪pGJ
+Q"aصф +,56L,qjģbA=ƒ?p։٘ckDLZ;M>Rc0i2m `?buy/ 4DF,: ~yċ$iZ ==G߶N~huz3
+",7hYhf$[wfO3wEjEH{6NxvrS$S\?Q4׈F wK'}eΟ2SwlIUR~O wZ8T6: R[EIP<U_o6AU2VW&rr(FlnG?*(f-%&uLM ae;wes T0hY2~Pј;J.Uv. *tZA9L&nͪ4#AT3h,6g؝ԃ}nI [ӏ5<_2#sS}s.'H~࿉* @axAL Wߐ'OV9EȊiEl~rS<R_[
+ly̰ϒ
+Bd"D$W {v8$-/?+n}6,
+Rkǐv poc"Zzw)ח>LPI\OF[y?{fʘE'(FެvWSQyưe?oUs/ь<=OB 1Tނ֬ 5zs`J% %\! 1%k*!ol||k uʗ] w{\*o|tʓcy|L集~T+ ۸Sx;U}:{HȨ_b*C+b#kAHo#Bɶdb19E =t3I|]=z5; bkCa1;* ^~gV㨘k>TTC&@;zMОeE }+ꙋO~֫4D]UpȖ,]#-햡Kxe.a%brv :S`[ a:V03]iMFw(l u+z)g?Κ[2C W'N$'O6.}^ ˗n[d"8b[( 5b<[qB/Ta\0KR8WI>9g)TDKZѩonZ@3zG=fw_`ꤥHTGo#|d T1S>j1\ L $Pr9,-+JIF0k{?KJhX[ugH[C7; ~7emoŘR_7.S=5θ2VpD9JG/frF!ѻQ4)sQr c
+js4@իS&~ :
+۪o=˳ TBJv$#̧cH%=-bT=o`##-9oh|rEDIn\خ;Է..Z]1֤Mu͟kg.4<H@WB\n ,'o/Y@n0W<^&^
+W?<<VnO;MױzWR)-6v(;nnRV*6!nR6mf[w")ZmBZɬ>X~( #?Ճ-!//&TZFXDsVh%}Lmԁ.-0 ͩm=p,he+hs^^S@l&ym.OZe2/78m
+1Tt=.:`tK6kaP 9pY=nS6 ;~x؀D
+K:=qNۄx8^`${W)~D<gF| ԊзnTA. / .< %r슘h:#LfpzPm_Abs}_%!lhErђ8O_&<bN܅۩YnI11oE6eT7LꇦLm"Jc ^ԟ4~2M6[Hn.k5͋lIXxd`q޺21a=6_5|m(BDQzljl*}l9<He,*W)TOThC[?aQZ 쭒xe+o}6Y o{:“1YI[W)%f6;wYW
+i?k1!Ʉ&rm?]iTMqb`<4;Fka%ez5/%~tl
+Q ܛ#¼&g \ z]izc~ZlKӰ-ݗ5o)|-#X&6>ALP|L42]~䭈'Wο6X ڷvX'*di;yL:|
+Dv=j[49`&8jڠ/WDo"8##Msu-W:\ay
+<T`g67-Dv%NP U>?zv'ˡ~ SDZw yGWJTV"Y}1X'o!g rk$ Ysw.H9vF[8A`]Zתaj3_4ɺ/itq}$}^l!\E߹|*I05hK"ey7_*P mOyH7`ͥ^Ms[V32(oJ=+c#ohPdl\߈%0O&f#Rx6P=F~D
+3E{YBR@"{׊Ḽ^{cWL^.q]ų3KeP{oRgkhQc IaTԗYaT2os8xF󘧏JıɃy#NoܧӲz36;E+9 2ևܝnLzr Y? -5>hkt ͉229 D"{4Z3w l\87K'oP,X>^=im䎧ĭy]^ev>*T(ٲq溘agc%?PXk8^K5\ܮڶ.IT\bc0*v!L>u#G x@XYtαXW%ïcO`fٗ!p)Ӥoڄ4l]ِij9 %x4{-E,F:7hyJ|票;GcPnNe ⣫liQz:% C dkCPjMK}އ^`V* 7)-x}eڒk+? ݬhb͋6xt_m"l>tsaW\?'ΡuWW})K۩  q76V9d.;l8d (C=KO<Zbe7UFSLTU[`Φ3˽+3ѻwX,4KZ6&P'OMAb)[P=mк AR drZ(-#q.1 Vtf^yQ;HO.bAEjWwZt d^cy5ZJE點.D(}aQk@`(GhQpCw8G)Og:6A{G6I(bf-KI_&Ek}|6^޷h2~&I[4EݓE}- Re1Vк($ZP}k=)DZ/nwóHJQ1ݼ[&P,;29B|H Lt#oƝ)s>V8u8]k^
+q ՅMiYЦW>^+sf(&"TQ<}c%_<"[5;] k >$/ZyuCgGauFuM1jT}L9lSi)i8XZfY`HT>T
++ !lU%.HuXD0k4|z*:γ?XN^CX\uI?PlQ£!̥$Wgk HmU}+I*Lt'{C[jKlE]V066_ #WhՊ[Abn&6{:ܺ@SBƮILD79? 9kM
+Y憔})V#wSCn0;h,<nt$n;㕂zgIru[8Ǧ /3/$* 892f/gJpP,bJu~qs*P{5Φ5 mAhc-36 rJ L2DV4v UHiJloP s;DO! [az3wl5@2SFHDyGGR: v,Ţn
+}iK|UsVG͏SOxZd!+Mq1}ܫ Z-rWǩW.u.v>1> D|
+WRr zъݖOC_ wnK-?h+ IS8iD ocVFZQ@~ ПeYD#3KF˃;~\>=#ki ?nGjJ<
+AMb
+{Yj%Zԣ(E?H=3@'Bz;ees>4\h;՞#g6{L=r?%JU|)7js0530;"0H̡0I4ǜdmv"\b
+vSuuq:ƺv_vev lalL(rp;| .7,].5-1Y*3_{ay4>*fXV'E\N)Í9bY⧣nŀ58u,W
+( otMw6S%Ĭ]~ ۓņrf`$,A!|L ,0qAU{P%8&o<.>"
+!v)c;S.W0WräQو#Cv'r ,,`+7wܨXZvKFɣP<Row%oP)a{|t#~ {ZCIqU/PI2>L$RBOVGI"06SI\\3n<
+
+^f;'jalIܤ䈒y>L 瑩X ĶKO5#;Z0IVЅ-shB
+sJ NV=>'8`G=+9X饳&'$mv'qrZ~-2<u=BUuW})[\|>x!s:l_e5d>1Å2 !@d`yſ폳w^6a3 {
+4Q/jTLoq{4RN-L^1쵗ԩ⶛Ԣȣ:ݎPJqF6ty>K43Qm(a3a'EAP_ o$L.ĝ1v x@SWR8aˎODKmE(Sm+#!V%<༫!~YJlbb8QSqկY_]6`!x|]*
+(Xx<\-/ZM/2ˤQm%,W| ~VcV^2 j \yʳrDDpfhAZ W;4?ԺlV#pǘG^l2:rAt#B<$|~P!x؟3D=6.L쏴ü62`dƅ?2$q"LY,e`*5O(N᪝_""w ci- c~2iH>hdBiƗ05݂GfK#Ijxϴr#
+]e;Ž.{:k;NXrl0.9}@Kn5,#ʉzJ<O>'igJXu!"6D"Fг +`6
+i :FGFsrn_O?bWO/Bs߃`{tݬ<2;Eބ:"iAoQ TFs2 r%Isl_  7C7J2\`mT=!8騫2gy)'V;Lx\^&`h*fKA9i<GZqU-"Kb,<iQs.VF9
+M!6tH:IWӊN:a)y
+@T.XN'H/\J p~7FElӔ3 x$BX\fhdL`쮺UoR\N^ ֫Ru&FٙdðZx68^er<ڎ2`'Ƹ<#g[q1Ht` Rk P 2< 
+ʺGyir"qJ_}<ެI' zYXеvL8t<vˁTϳ ًa t"BmwP^E
+c5D'{mpUNђ3DpeE@^_ӊio]Ztq TR+e^Ԉb9,>E7q*z ؤ)ܤv^c1
+Y%OO\VILt暭
+60LEpkK9 [@`7Sm(gطn`:%\h_iC%{*>a/_2;K`b#'H}䦘 7u\-`~_rٵb քQ|V
+<zaFH#53%X#{bl~_ؠO}yms]iQT빐Ԫ#mKMb#:IFkPߓ
+F\ Ye^ώAK(S?=d`5qDlώHȇG@[XSM{*U@o_|sJd 3Z$Z9U.?9?K
+yMT~O֓rX֗=}h[RaSzԁ^3=l=t 
+} ˜2/stDjD7?=s*>1j5Rv Tk,NU۷f9BmWMhBFI&R(r^76|@l__x?uԔ8\FqYV:mV;뿨0(M$s|KUP bEmNmpVĎ㘨L#+}gE5̿E
+T_Qm %rn,<(a2􅥫X HʧC`a_q]мEqҐS6rgH꽖PQ~K/t ϏfϪYDm)_
+}[vԉMN[$
+K eG请C)
+U九'0s`oqe%O_oN4IDf4үmkj[20~oM ʹnϯ84dfJq}xe{V:ǐ]'o~-9ek<U-٩s aא#d! }R
+FMjMx{rCiISP.uqs)b((x\&3K\"bSg7Refouٌ|̗P۳^~$0V:ΡmveTv*xҊݱ1 p@`B9 ÄK2nucnj4%-?Vix`r_t\sQH+c&Fl[*)Nâ{לӹΖRw DToaߊ:z۲|ؿ"ڨf'>|e=B}DA'Epl۔3'>-đE}aqC;G8ɰd^hK4ml<z3!cv2[OBJ,|$S&2+ēAs
+[RBtWA N!6V#Ԃ-4tJE JOBJ3IqRo3 ;zF%̔:z&b-Ӫ8 6S̘9"*i66Ŏ70Ǧ>u0*<YAv㻼!bΟơ1ʰ
+XPYu|Fo݄}L+/-ӧ˙=¢)Լ3$V)q. 8SϑW3ʚ)z+caz2lVPNyXzIEPKB4wTA7NV xӥ_;%k:߿Z gjvȬ`q>qE/(CKFFpױpϷ3>|u~u\8_FoOG
+yh8+W@HVΜ ,%p˞7)?a<v5$+sIՂ]^)(7,$j\_D b-IpA67#\rBm9Kuq ̯")Ie[,;\U_ixK
+gQ=JJ }8եǤzgg mo_c+_Įe$Isb ,0I`IY0XywWkn԰c&}]0u?}p7=H>~O_mJRliáo"_ ! ꄧ,fA )ŝΪ4|=^^Ἅ,qSPs
+1
+i$[1P~dhHJP
+EzetSW6]ȷZ8IcȨ-sDP<0(S82?
+E?eL
+Dh`AEK!pDej+tĝV16SQ
+q;*+vXߑjUUaGЧ4Dlf'7ge-2;|(  x
+D
+ErYJ?m.VȸfrG5g ̘] #!ܷXÛW0 zG/9HR fN@Wf*PN9>Gƞ Tm,⿔{}^Q[Ut/aA4 > )B_q@3EΫ I]q1nZݿ`
+~bws˺Y<w;l^j%(Vsfŋ+X;* 7o;ej;1Ǻ8-$@!AJ鳋l c-27I[]Ȓs`9Tq!V7jS[x!<:bv''T7T%IW}NőIW˔ꌚ/?B5#Ox󰗐,E,, U= q C>}Wr܏D[#JB.ѷ4 Gҭ
+3tDs [Y@\m.k
+/z9A-ua4{ ReT6?@ʢQ ry:ȩ zݚ7+O;${g7NzSvUvߡ_+w[}e_8*HA"9bR"NWmg @k&oӿml3
+Ȉ(^xJM4q|z$ GA[W=ϮVXW1w?$9ļ;}E G+ܴ&u&2 SOGT'+-{(S@ -/j|",ha` "QeKHE{a<V~$V%,'/`2\Ү*{
+FKGwHI*J'+*~v\͙@z/& P2g\Qn^2A0tަ ,7h3̜a4&d~4cxxy2Úy5:TT'hrQؾ`W`ӣ[YV-7\DGXZi˭a9L[TA*>)"\
+C׫NS
endstream
endobj
-549 0 obj
+643 0 obj
<<
/Type /FontDescriptor
-/FontName /LKXBGP+LMMono10-Regular
+/FontName /XJIPSA+LMMono10-Regular
/Flags 4
/FontBBox [-451 -316 731 1016]
/Ascent 599
@@ -5079,11 +5691,11 @@ endobj
/ItalicAngle 0
/StemV 69
/XHeight 431
-/CharSet (/A/D/E/F/G/I/L/O/P/S/T/U/V/a/asciicircum/asterisk/b/backslash/bar/braceleft/braceright/bracketleft/bracketright/c/colon/comma/d/dollar/e/equal/exclam/f/five/four/g/greater/h/hyphen/i/j/k/l/less/m/n/nine/o/one/p/parenleft/parenright/percent/period/plus/q/r/s/semicolon/six/slash/t/three/two/u/underscore/v/w/x/y/z/zero)
-/FontFile 548 0 R
+/CharSet (/A/C/D/E/F/G/I/L/N/O/P/S/T/U/V/a/asciicircum/asterisk/b/backslash/bar/braceleft/braceright/bracketleft/bracketright/c/colon/comma/d/dollar/e/equal/exclam/f/five/four/g/greater/h/hyphen/i/j/k/l/less/m/n/nine/o/one/p/parenleft/parenright/percent/period/plus/q/quoteright/r/s/semicolon/six/slash/t/three/two/u/underscore/v/w/x/y/z/zero)
+/FontFile 642 0 R
>>
endobj
-550 0 obj
+644 0 obj
<<
/Length1 1708
/Length2 16455
@@ -5160,7 +5772,7 @@ daw!IJ4[!S-'zTv꧁P12*+岫i>BI)$ѥpF6f߆Lz띊G
X߂ŋnjJ>j*\;暰I}{F^!*(|>#[L%.o#~hg?:Jo<bh=|(i6yT~9#ADџ5 25/k`~6+0Bv|Cz(JkJ?MS߂VW5~sLAIk9smԺ90wi_cCh0bcK`l K_6 ;tO;-Y#--I<e1uqϼC vVNHBm%V^ʀp
endstream
endobj
-551 0 obj
+645 0 obj
<<
/Type /FontDescriptor
/FontName /BYUMNM+LMMono12-Regular
@@ -5173,99 +5785,103 @@ endobj
/StemV 65
/XHeight 431
/CharSet (/c/d/e/f/i/o)
-/FontFile 550 0 R
+/FontFile 644 0 R
>>
endobj
-552 0 obj
+646 0 obj
<<
-/Length1 2071
-/Length2 21945
+/Length1 1980
+/Length2 21129
/Length3 0
-/Length 23144
+/Length 22362
/Filter /FlateDecode
>>
stream
-xڴeT[5w (\¡pwww$@pw  n9vTͥsϨXQNd:13rd@ N:e\hd5tr8
-N\
-he05HAB
-@BYAMQ=IDU
-^^?d Z
-*R_5XؚMdzf_]`9
-"6ifz$ 0͓ XމrVp5Xkw?
-
-BGa;Q?ɔ'IDE SU.7”K6wqbc`][ 6\Fd8=CO`u,cj*ֻ848غgu_srqe0ZLní|wJ AO⛸w_&_s4b ΣN1'dT?M$].Y=Sz]x(YIOք6-ȹ> Q&K]_54j}.T31b%܀D55ecDŽ"͎Eb~aqa!v wYF8bыq3Mȸ%i8,IHv(<wkbCrNlK.heq12V\|s.I4Encp\BРʀ_9r M==͐/as':߼^[a$|_y\}Ifyvٱ>z&Qŷ}"]hwtMFT~V຿i |Ʈ;G U~ K<}$Jg"RY\YcPJdǯ:ҲPT^ Bxm0C͋(> )~6X=aLi.z47>kG{HMaNc
-44ڌ\?/ނ
-i(^J7#:ˤn%sxKA$S+3#̞=*pVWr JA7O>6݊Csqkˊvz7A~W9ÁY6*O;׮bT!TvY³DRcl:5ذ1Nܚŗޓ!KGۢWK-Jd ~-떠/{5?z
-H(wp嶘 wf<AD,=%JEVR+Z@8^Qh)z]$<jԇ+}`u=tK5GYK2IHHsJa2{#/S68K,-qr2'px9U&)ݯQZNC H\):wTs6>0 P9"BCc[nZ'a$NK +"H8B~,I| ܐ+#Iz^jq~gx-}Zgifָ5,4%#'bǥ$[7iʸsk(qUJ<gV?93R8[omg cn&I&I(2$
-vt_q|~Z73hKF<wV/ɓFK)tjgYmw
-p33]H#gl05|d2lGGJ@yz:Z?3]G;DyB!̄°inchn 4e.^L,l ,Sbx4V0 ZKL MPLڥE# YYe
-\y1F:(ŗ)blj9[˖3ⷜ.:9+:*IďvʾV#숻@?Ez(l9Tc*fjpion%j=d(/qͩUqlu-\[RaJC|'Vlᒵ)Q-"T3ANY1FXFT/p@U-f8=`EqEd߮SL/l#%uU%\]ãR]l!v(` 4=tPn*qyEo.QaX s}wwI1Bws0oeߤѕb>yX91COo$%W?~*plv}LG7 V~qwNzޥP}l]Ԡqy҄oIZ<7vbaL# Oyi[{M73_d /V]z\gob:T(˭<
-!aQ )leg]-.$ˏ;~^a
-NDv;E4m}+|EF" o4lb6Ίϧ~ V_g;: QI~p;<q!n$gDž֚_Y|xTG7Tm31uay@dP8R/7pq@n 4fWZ3ַ,UG5 wφ # )ovbDorT)&48=GC̡swX!0o^H;a1HZe4i'R25&,M,ux,fgU% ^{ >d;]s;G9@EϘ:XO53M5MN!L#XٟmNmxl.'Ո5hNO#E\؄D UEEPD$+`MUzI!JR:蕏;Qѵ}Ә$rlp+_!F` 8uV#3@W+UM3Mq\66E^S:{^ߍR 7 Yg(H[GIN<F] L>m-=A,s4Ҏ{V&O#S fm6P bI`bFU=
-uiP(5T EuyԱMW=}Qch7OX?roTd<ZM
-hgmح5i-`"Sʾ2RȵFm.-\۾fbh}
-3Ph طSt^SƜSpZw~=Ӌs͂`%jU}{hGcux?>NxR꾽&ӻs\ V?+S#l3} ޡKkH% aD:<TuE2}3yd
-\.[ K
-`B7OX?*nbmZ{fXQφAy^i[Bzop"|i$%"ͱJ^&<Tꇤ4Sr˫!^ fvRXʓH/3gϒD?"y4TŰ՘{"EΟ811^o{/{:xIN{"[[uݰ_%%f
-IW|_G~HCeR[x6aVYƼLBQ 7MP z'ayl@ s5T\sIvWw6mT㗼V}bގ<4e `E\8ZILn?EszTsN
-o`{ل MǒJS&r! NJrzDp16{<IdiYnyc4 *2tsQ'v@gÞǴ'Pm\gqW&WaĮsT0?WG^<K[!Mu dWcك)>e^Tב;{D 4]{K *ɰZcM~òG([7x|<`/]Cb>"i'c#򒭛o'OFI$/yؽwhܖNؾNJWML / 23<c/#^ش}GR3Y@NƉ^:ә {%xPߒ%%IoKPZ?5TSVÀ_[6Iݓ8nr?LL6{ikP=xOJ,sytu,-kBmw#IV9BCסӫ-P|$Qh^'ݺ.
-Z"?,w^Ͻ7<}-éd,92͐S|!\
-jt[$G<R@/ K3 xp(W9KHVf
-SwJVK뙋<DYӯS-ݶPkCtYv!y5ɐó(lɼÅflzϫgd$`vE)T=8ݾ)l6wBϤ5kp?:K
-ל5Ih)0R rys$ v⡑;wt==鉨}N.+k[)7+R)NZ33>(!Rm06ɁA]DUYZOl&Z]o=-w˿Fަ'FWjct@@p&eN1詾Ghz_I!mq|}>Hoe >@xj.$Sא CS8$Qt=/9cy 0k;3Ar rM A
- e?DnO1Ip%JBǒ TMUg|.~ U=M|V>jыЄ3Ϳ%846I M!ԥ#aH2ÿ-*19d<Nv{k)2?(xY&I U~)J#? }B~`c
-q%-OVz#ņWtܻ({.P#.R/m,6yDЇ<RV}횭BDɼޜ^'!oM`*>0% Pk
-7z [|Yn]4Y7ڣZ
-`q.ܟ:­WŻHZ%5_ 8mւTOiJ 5"_*R1xlR+b_!'sO[78DHcnCD~HC}+jymT q4EF/&oY{Ó<%%UN~o­*Tl=^ʡV^=b7DjfbXC) ~b:D *Ii7Y
-iC*Rmx'!#5엺{-mdNh~Օ76݆Oe0"yHCBnbK<h t$DtHbdiH&wNՃOuJV/`jCo&aQӱw҅ ~tc+dwn%7m<cVR~5~?$F<9=&yr7v`pcNyL[u :w<m#L}%>Z?< eckgVJheV8`}a'f&ƃb_03$`ba5tb& Y=BY 3/u9ɬ ]r&]74#Nf5{x] ǾtyE{+( ĥIbLnM4
-0ꯔ--YWZ~u2Jo^rܚ rUL6cCF]2?5P^<=Vc۶{=eʪ/p j'rv#oc `0K&"c m:/D>¡,sVr*Lq%Z>výl mjfaH=
-gWs'oX*طg?*ѝ0\@- |as1G0j0 i
-;0@8mj?zSa}׻3uZʜU>8-y3Lnx. >nb;\fJU1QWM&?lVa̎|3S[D aNM
-ڬsm[䘲HՄҵNnqϚB%RWт38Xa8?D`7[|ysU<oSë)}y@w3(g0Qm]7#`눎Y0&ᛨU1oAŊ8œkM9%\}&o0R:>KH4~[5tk`ạk^q決/1RVџlqyFWN0\^ٖMрQ?Ǡ5|\NARx]t.~SOĮF=@^ ` i[S? ?ĀExu,&]WWx =B~l"j19 :.Q|;6U^׍c|ubPfH@GgoF!}1__OFa Ɔyc;\0eMjwFOf+Ga@;bEIXMpX[K; &@=Z +Ͻyx|D8.voXMxBkT\?Qddta-cṈ&ġfO3_}eL]p>x2C&?? .KA2}?rU8 "ZD*`o.I~JSǮ?ud٘
-Op ?qhٚXd= U,e܍6SC3N2UzIOAҞ^;B$V,ÓVdoakBkq FbMؕkX<a5^*ХZT6$nb7P"Y7._ *s5nE_w۲<eQă]6}Su/}@rU[|Hl/Gov)2 uN%5A<_R1음c
-_rH'~"u}ѫk2 _2"I"5K0JT'naƵgjֳ3TРxJAJbLՉ?m
-_st~z8Qi.A›ickg5Ghs .XL/cTA]k$sUWHopҤ%k'2ٰeraJ\I1 To I;jfW
-лڭ'WC9">C+Q <JJG͌ۚ9CB .?3q`/C0 /O) 6mP_K46#ﴁhn> "$]ʃ .q#R⧳W'u]H_!U'h;@0j؏:BUqq<,˟*6k@r^!!YP[ż.XDwϩnrh )7
-U"|jav's^}1xHUv ?.s0ipO֎S*J1@XT ?iSF].YL@Z63 mFe>$S
-]Y
-F))}`b{ʜaϯ)Q24N2sD6ϙ+eppc'4cjMVqG;E =|i/| %Tv޺I"kQC+ j&^Cm>HU3 tx8I$q87p%8GjR^x|X[T77-kNUG͓tܬthQJMe 1P\FxI_T!aXsl`ʲEo)v
-C`q0GM@~.y($EXCy<T%}GaA6[}&(״wҢh5Sd`mƏb I,!u"?M*+D(6~!k d/_0G1<oG2kG Q}g 0# S1P\p=꞉k+Qe-ճS\NG~t
-EOȄD
->Xv5#
-ӝ8|Y6RѳE
-UJ=5+98!4EV$ʶH-łZԝ1#kZVg[x6dG
-JIL粩]}4I|?Cu.C1N2VJ>z#DսSpUQRD$jG9]F>^iV(⅙D8_=c#>~̑7 V"X#|}/K2B1/`~˴%a2kQoOݪon#" wT>gg$9foScyVԡEJ 1Q^s'JQRpz3VJ E"<˛OF
- U(:RthY(S[WxNiO5=g'0 ٤%yV%G7{JN拓?]9]̥zՃ2k<e/qC"/vӄgJWfqs"wPqXJR`6 ]6 _T8'r=w#m2ك|\{jTg¥h I 0#^h=j[&ҭN)V,9¾壉 &.{|[Mn皉}MTV@bȓY%ԇ~H Ԙ&^1 Z͏v.ࢄ8OJif hhM4o<Fa[C!I@34B`םB !w
-RIDY*rE;HV |J?dlG"f&/X})Qiiq̒62 ZWb@sxM5|: rFܻű^:GcpD-s5q!&TEy&c̐]1q{Ǭm<M#>RRCbSބlS5Nކ(X5ui>D9~vf*0wBvsc@,n/}A:o\{:1D6rګLk 2){Xi[wj %4g]rl:;Va&hq6MI~cTHܾZ
-' Łv q/f–ƀ<M$
-7o_s
-DLx-s.,<B /H]pz2x5[EyyLB ^g1;hϋoKaiuE]$ϱo#Մ\ &nmf9B={e 0Tb|~UWw*@'%}gP˖z1\Ocr2~s+q yK:oa֪+߽L0 JNvWX9{ %$`D %{݃N@l #{xG @P5މH֋xvh_g""ân,?k e +\ܜ#˝>i亥݉oR5#DX'M/pQgGMyij
-p3o!ǜ 5z3_=v$ADE/ՊIVWھ@T!ϣ~Ƨ`g|Ԃel\CL E|&Yꛠvd*Qj֧ʒG1 o?DhpAzi_%pP03b~qnD"Ny}ʧ<Aho-zU] w E1=P>^z/ѦmWuس(=W1vG 'yQ|!̺h!ߐZs/\1:ʗ+un=(*u44bGwo=)uaqu6h[$2Jeيx[[CD&
-GڨK@bN\ܴ̙ .S j0/>Q,%'´lݴff)0P f?LtU4:;@ƑqvΒ' -kjʲhO/(v]@39ơ
-Tʋ#OQS5O u.?h~Ohp&'$mv'qrZ~-Lĝcn <8iBuF$Ls;~Aa;QVQdVwıvgÍdAADh{$'@NzX~9'uAKtsPt@?vʸ?_ @7J~bqpTӠay5 GwU{!󋡑z)l+um3j0AH1;'de/M PK`h? r4mܱ# [(<cY@}7~ՍO
-=QChS3V 4#通,F
-*Owx!#|˨@QuF7MwB138.tvG5V^*ޒ[tc<Xw ap?kJ?Vt$o(~_,oun=MCrAet$1+;^1Zx/ړ7+`ؕNm4xaBÄڧ9PIg
-v[xH7[ [=}Zh1uÍwgijqnEGg* l_4H/>.<,kE(pxBwͯ6udslwS+F[a Jaυr0YIԂ|lP n4k$m "JpE6t27gP5kT~% -bg()*W+N5>3I+ЌРb Lwc{~Ymֱ"ź)HA?4p ,^Z35B"%5?,M&0J_L
-8ҧ^2⻇WP)?:Tu#%~|*U+_lX,'M'߂M se~$a`.'*j7b@>4<ѹj+#89FCv8a\7n A:c>MZIڲ@,:e=tCD]ey9'Y1iК@x\PO%<a}pA_j
-bbͣ a/e AOtWfK"brI`y 0b*_8ıx!ӌ:)
-z:.~|XTy *^/´lݴff)0f 8 E4R
-1Br$7_@kg?`ܣH/Gig.YqB]]PCfQR\RHI-ӗD*wWPT䐆{"O:ā$PE:ZmeKOk toWE6:??Э
--UW[Q]m'M:*9I,Njx
- [.ӟϾO,8i(Is$76kacц\nP;\ɢʢl/%}֥̘1lrXNNJFZ%zôD4aH0:^@#b^i" '~ۿ~;(X E
-vwuQvcT14~)o- 5ۤq"*B.=AFU.|keѴ^k3$<Q2Ph);-$` rH;9qءo wӁnkupY|NƬ%JD+(@'%^dx2^Կ>.6?ՊNvh`T1b|b07ӛT*<%ɢ9*܃l-8Wcj//#x* <z Ł [GdE&zoch9u.c6._e4SI㭌%x7|~Ϸ7@xlS^c=-Wf*{ zhr,m#J %l1Dh2a[[@Jg5{G:͡P
-T7rdLsRCXP
-}lHelm7~N.}#590W@37+BJ\;cJ
-# tNߣe07W@m@[eŖc<xCZuC"3WԨ8@֝
-"&W18Ԇn'%ҋs"w
-vˏ3ZϦd>< _n@$
-4Ci2ɫ<G#-tp8I)Xkh| e[Qk(=}3[U(++S#Mا{ aXPae/
-ǘ1"9Lh =3bbX)& pY;{5<S3I߯f gb  (jr٩˿qk
+xڴuTۺ=H)^(wwwwww/)Žs9|tϚk%#c:(932 0DI)4v$|
+p::YinTo
+/(ߒ&6?5mp_
+**
+
+8;
+ݜQnޘ}OLJw
+DDh4嫍YpB2MZ{yq<9꯴}&C摜i?R JX8:ŪN /nJWBD>g|9s<!B}A,I7?Z%Sך';/M;Of&F0}b:,Vȋ=Fr'ZL Y_Sqdkl}-Z֌il
+Q7dk/Fv;ʻ2DwT)IKԷA`D> }"W7y:@suE
+d.V@Ŧh
+89k>#d4
+{Cs4ǮY
+UG5Hxr4ٜm\}94`<˜ƒpy߱exFڼF6Y<ZXr|h:c<^*k5_YpԺ?7gW;@Ș R33lta:kiG^;KHm{F*X#(;\|ހ"q'b _&Y!΃ohI{LuzTBx"|b<euptǫ ؔy"2+I4kܴ<g~DC@Bf1HEl{Yy S##XFBUF̢R+W j,h:^>qN.-:jhx.xiKnx.X0⧇kiv ⼌]'i\?G~M
+AbO!̾iNaeDZs94d c A#.~ {쾠b}vƅDSi^:D0D`S1MkPeš!Ǎp*w^HnQLN~ۃbIg6Z}=jsiaBKֻ\:>tJTZo ӠlRhֺ6Ӎǀ/љ#rivii'])Wn4A4'bsd?eW[88qԢEt .^V~E]gX+C.b`-x7=x ubfX `u>B-$?ƾ2EˆSn[I&=C9]Rfxs> rd˸$Yb [,o 3HoK`H?Gsu]2sZ^[pt|l2:ilsr5\Fy~$H:Z#MAQX6@?+|U| V3L8a[tx\eE]>yY%-%p%vmP< U_t1;WWf&l>5Q Oַ4Ց\kt@Rfy 4/ B7g\!|&
+Rr$w UU-SENv'MOVpF9-"8CYh[d(37d(ŲF]SvIV76R6 S|wpx#`}hL@ɟSGBMoދOҡ#cГu}c?kA{)=_{ERQ/g қ23 ՒYí[ē@&J믜 6)S C*۔a=vlc'ɀ
+lwW~h:w2Z!^C>aܯ'\M< <Rbyd$F, R!qDQ6tL28?+y?U1R 5=-2 |2#0[/z9/~>ӭSйdARu
+S϶F .&`ٗ\ȧږA/=VM5g 1 yIur:!buL;CXI* !NWG8>nXU(=rt88Wм9P ([Kqq}ѵX2ϪY"@vUX
+ʄT='w$=R ?6B(#4-1ZNf0lb 4)NЩ > g#z~Dc&e|ECxA{mk~i׻~䫟!8]L+C|;C/9Z~׊`VBE ;kPfFUsZ2
+=qȜk^0,ï/WmOp\Z0ϡvWSEgq [ u );v-gu<~{j;4]z@7L<LΙ^nS.Ucwz\o/ Dzl 7Cu2@=qmJEk,%4#d
+_nbe6d4v= U$|Ə_>$cXT>v:/k49ѦX$%t(ujEd<+17[LvZ;iDb_&DˮNVEm:aPJ-գ܅msf3o2<Ree+!5'aͼ~݇^?˂D] @ƨNu1܀v^ .7]j[QޝWxY1m6N
+OGa-8YYt-|y5vguؤiۗtœ`$5
+65Cfqܶ"Ú#T4Dр/=W&jqػC 4$LJ=kBo^9C/'No\^Qz$B8m_xs^FY,n,:ҺN2X 9oSqcٌ=$Sp*8hjU8zm`Qg yhcܜKwX: G%5%U壭AnPU?LLZ8d8xQ͸~* gLK#-i.6)-gqGl@ĝ2zA8Ngr07>m ^I-T1y-\vFRebSˏQu {ԾT0vǀoKڇR(7t//~ Bflte!_ o=?U
+$ & @*H]$#fiYAhJHiE+6W_C(;Lި7
+:y9U*iPWe^e,I܄CC\ ֣}GKu?v V'fjĮ t*iO{;.=B_dLtW'(Y
+&F3tM=<Yм[MĚif]7VڝO?}injUǠ%z9heb
+|N j&UTVk4bٞb 92m#Z
+5 o,3<mtt#m K_J@o4T"qK|Y\RI$^wdWEkYeHB5P sgnGbm2ZR7W!-5q8AL̷O jdDuKt_H™Xe+svrqPأBQ<2xʔFE:DrMR },$aϥxElAv*O`N&
+$>cgF"۔'؅<H@an=y4 R'nՐn9gb!
+b壙N6D` B?aHg <^̹Zݬ8CKa N#RYX}EygT$YꏷJЃOrh=u:@N*((⬃=%~\tQ1V.x1#`˚5t8;Y~[h)(7PN:kvn,~`#tn*ٛRٕ'!A{4硇\ތ<OI4S{ЩYǮL:UoZny2.n>am܊Yޣ0a}Uȵ39N$o@[5m'[ >hҋ旪>tsF̊EW3ߙAr˟L=^*ƏƆe#.*0냯0)u>cNJ
+Ӈ v>95vz,$LPW}kzJO[7VNUkNTBH.J"07!/YMRVG|S,w@j% ]ҲnŃF_㝧GOFlqJ(neb[Q/f'qh ),QvSvXrE1s;g8{Mr
+_/s%ӽ ܄Kse[PsȠsCߣA?|P=zV&6Ol`|H-*B},!fb$VĶT|H?x4@*ºہ]2BYepgW%W <
+<泻zI_84n"Eg6^$`8NjL_Z( FѦT*)gCY<1 ޳DR/t&JOʬנuZF|/E= ÓI7@zK kwO1Dk݄NLST
+i:~R;bL]P:N˻Mh 4#Lt hHf|؛#ξgȌv6=R.4>t]wk|p`FNt;]M` FN U]w" 5_Y\UOP?F.֒c2lUO^K6[[?0whPIr}^$kT0VL57v H@<(p#l%Ɨ)06Ɓ;cN1PRD1ZSlf /|4>z6 4yU0UN_4;~KX#NzǺ{Z`.`
+jQ7Ct ([YK2@ `;.*\bَęZ}Ӓ;! nۀ$bl^ gQP8ڳkBs;\`iN:\]S4L&m;%t'.r~ۯ}1Sף)FIM=b`J6 1t^Œ#}\)4<$㜦qdv5E3i4))j)75!> K,b=dSFNJ.8]o5haB(TlNSೌ0ӯhw'&Ozd]fӷ%[ñQc[q|!5C#3IE6f u
+'̊ SAoR& ߽ND$op^
+z>۷[, JD#g({N&SU9b^h-©Ia#Ä(52EP[.ö3؎uvE=
+󯁓A+{+(Z$80׾ vJw
+ڴ$;>C")o\ϓi8TLߣ̚dkynM"`nEIZ“Qq-x2|~wwnRsiWUB,&Q}!B0R#VQuaO`f^Ԛfg#=KJsELbA;,Riq#T!47L'H>]2eԔVǡ/EgIR)
+}Z
+& .}),ǫ+뻯ƥZY"rN$}ui…ɴ Hao%JTGn:
+7qp?‡F({*?Eqf кN=6QT3hNwX2tq8G決ۗ>lBY Iˢfy"9/3lK="'
+D},%ܽqbh$$S!l"ߪMQTykR*NVSLzQD(]hKU9{it N[jt -?\%yMݷugUOI H] oG RwL~66f
+
+@Y\<
+ui.4]zEP@@QҼϚdkK#K}{ ψx
+@Q}i }ɻHy*ZśO9'ܺZ?Q:8c9ǘ5s[WczzrC]=<!/"X7]9fp1] b4l{2V]&x|Ywp Q9Ds+fgP@ &FFv1bD*`7oVh<kEHg3 c@KB|ere!p~wK){k|u'-ܶ&~JvI)uCatI~Vgsvbi?IĚ7V8ԉeeydNEدp 'pv z|keN>R.K.u=<q@ y B/ ,".NK$, Fxu?ʱY
+_۸_-&ҥK9f,^ON>XJt ۷϶'m ޞ2Uye*FC<%Qsz_]RC8OWplF2.Si;/`i}ҸgqĶ8~"G7,+Gѯ}09O2%ER͒>y#xE-*Q
+.xO$Gbzx
+\-eW{GꉓZGMzԀ:Asj].v }hNջc$E¾<eoLq wy$րYq)_YIw-i!hIdpr pK(ѫ(zZϟU wrVC)ҭ6<S)~+ /PِuG̾Z9 g{>*xXe/lg7$^ :χSsH3?mUDXj@E@&"GWhQ=Dvڗ,B ~%g፥d>  _Oi~
+7J1ias"%f#]&;_<2Ç9e#<s~#E/{-SX\"Ô3>r`'fj*b譿ۅt&:HsSɦ.O^]kR%&20&`IloyU}ZJ5_X :`T_ߤOk1q>?wOI#.~J5ZP>ΠY WP;TCFR3|:IDŽ
+fGՋ .#<r´=i4`;a|S!\6X5Q&(|5k>p\g4%?KG&>}3j> rhuE74*&TeJj 
++e*gmZ)[x"~RjLnü3T} k(ͪ;Įw[LӬ#滷&!bsN/f* e 1`F35i6݉lS=H6h#dm4ZSpFvuS+]rw6J{f7_Z[ y~ *^FyNX}'x/C/$~m[))@ qMcOfJ'pRRə#uw)SuhɱYfjv/#[c
+|
+~P[o\nGWmKbկ7: d
+jy89}4d>Ia$(Hi0[yΧ04Zq%(+39Լ&&3oW
+OyG!ϼc9&YGyE
+KvhZNQnaH>Cԙ\J?9<lcL|+Zd!59!skGU.MM\,h\]v==0 2Y B:XQd"ɵ?vtD&L͍[isjNsp1]lݼ
+;q( [,u
+| CmA6< i,Lz޳LM`;\ncԖʵG ߛgNbno^M
+lX2|jz?y[Npy%j4x Q
+S#C_12zmDWx}^X` > HjyR]i[Xni۴EJ
+Z'WQqHSWGDAZԍ)\!<}Nŀ2 󐆶,oըK_X?tb⻂wO0}<ǿ -?s;!/ Gzj>b Շ( ~p܋m._s-8]8&/'_Mן
+_T'9/mDA(0?wV\#d!:߽Ͳsƶvc3eh=S<v$8Gu8]_CU#;N'%s^EvWp>=7vZ-#bzڮ]էV>2p%  3Z uAG;I};9ՄL,ViSLmtݺ)m GOɖðz8AzBZn)f9%*J|b]H*"+c%s+ϬDhAQp˔$t~ŴyN~C -A qD )26PDWi0h8d<zHZoԅҖ8۵m=Ck#/?tVB)i
+).GE+Z~mѷ?wYͶCoUvl|T#BhaӻR&ilH]<ByuC-4i 7-%'pyV'> -qv@rh+k j߀)P<%P-JY>w45.?)Se3,q25I [X@I"?.:QDS&> E;/S+L->*$$}x4OVQe2]Ʀy1Q',yGww ; rДuÖ据Sˈ?OT_ɑ{ǤMonhD\|ۜPdhoꆃF[y8VӪ9M~J{~XwBe
+7; xB WH/'FK0bnUBΏrqQ<"%;S7eqJkyaj>W-ώڠ}P||.=ㅌ~Fu #s6-;s'zRAn ]ㄐwRygx
+[E)%-v uI ɤM5[DS{i8sdDMoԟ5vM RkEkqqo@ FgUOfzqb؝gXMľn䶨P=@w`4spg8%~ﱄ'Qcb7[l9^Ғ%tM?k,
++A
+VT NiRC36T!$-^;9ga+ ;4VZƳ
+dC v<Ô$oڳqȯ⺫VՓ}-RK;[rK+'\ܜ{P|
+&;!
+/I\B2C-Jxq/F`}2M.b^0.r, `~;ߗ
+s$ɏ\${LMwem4Uy:hv!ߗZCY)#!p"x ,q96yA9m"РQZlvncT#t+G>>4JgT=uo$2H-@=&=1v
+?‡4(rAٺŘۡ8İ60~hmBxrk%
+P@9,%$le
+Z|,lk&au>{SWING5R:ҷc?wEI@f+3~'&'lps-(gÜq<i6d)λ&Փ+ LrRUi'Ϻ#v!~Q\l|2kO)RGe }oDcp U-a aS5~xvsj9}1K Cʦ35P TQYe'@vA lV8`pgubifh= ItcgZ6fKW{"X+(@?-1TW5kbG1ҎhԖ?׶qoŒQ򜌜PֲAIv$>P Ւh/åc86w#
+Dw~4~7ia6Qȃծ mZtRŜMOCrT>J6͖0/ŧ➑ߡbҞ$fRE_w=#JR(>%}ޔ HC8fw"rQJ[ɎQ(B؅2CfoHmS%Sْm ;8,yh[P̂:-`Q:;mAM
+TeYZ܍`w&KD3lMoN3(9Fn1>̷7jXoXl? }NX0Jead{os+Ja=S'
+: CIUz/Hƴ߽CAxQ$A XVXk4?s1qD OHD6pyR80htCOM#v%>_=Qdxq:& ,?Q04,* }p]_p֏'RV}^E$Oq#ŗ6"B1L
+vh7żNˊЙEd mpJmdQ~받sFv̯CI.8'v72˘ފsdOvpj3h3`N=`` />2YĶep'S9ȓs3|z"o쌵Fō< jj*#*X/.wfA`B(
endstream
endobj
-553 0 obj
+647 0 obj
<<
/Type /FontDescriptor
-/FontName /PZOSJI+LMMono8-Regular
+/FontName /KLCXYN+LMMono8-Regular
/Flags 4
/FontBBox [-456 -320 743 1014]
/Ascent 601
@@ -5274,105 +5890,106 @@ endobj
/ItalicAngle 0
/StemV 76
/XHeight 431
-/CharSet (/C/D/I/N/O/S/a/backslash/braceleft/braceright/c/d/e/equal/f/i/l/m/n/o/p/period/r/s/t/u/w/x/y)
-/FontFile 552 0 R
+/CharSet (/I/O/S/a/c/d/e/equal/f/i/l/m/n/o/one/p/period/r/s/t/three/two/u/x)
+/FontFile 646 0 R
>>
endobj
-554 0 obj
+648 0 obj
<<
-/Length1 2228
-/Length2 21951
+/Length1 2199
+/Length2 21648
/Length3 0
-/Length 23305
+/Length 22974
/Filter /FlateDecode
>>
stream
-xڴuTK;CF4иkpkw ȝޙ}v:UłLUI (
-2 t1uqu}-hEpP??m>y\/l@{?{f SSdR|<Û: fT|E^
-X07IJ ^3nq\?] wjZ9o[]; }"K 3"l<p-#xYxؠrk!-3^p[R<`t62ȅRdo=noʘ˖9񨯂gFJ#CVw
-o}2%N|
-uIf¥gnN 2W1sLbn].tr)%`-#8ԺcA{uc"eD[^ڪ;cyJ܁So-KY婇"CLbxaIʁa/lSlw+HvM Z_ZI:\6,F5{=e=oNgTHtC=(b&{Bm \.{8yVxz<PJ/
-nX^#_뙞OTUyu03=oQxycEU%5{jD/X6ޜ/(;Q ܷFm8[vŚM.,='O:XcGB#vF/1--WYU,VBEjW2V^ʞP.3%Qk٦-
-3&Pw7_'u׳~RaC9j<<w9cg`Ҷu)c pW</7*"t1vz L8x0?~֒D}R:MMCoN).gY?+QV{I}ک?U;^f VF
-J/Mi^g4-Ͽ^<6R:i
-; 8W [6-xI-JJD?˔%Os8ʁ~:z0
-NӨ=ۛ7(Tql:7=iUTkXT.u|=e@]&e,ͼ(D͞s5yC6ؓWvi{  dYw we{Ay.׃xnxPOs@nppƇ:*"iҒ@ݶCtiV?)pn!PIIE_L{`.hˣ9-,~,)bEܻG(UJ,sOpc o[ 25ݩ5F*T>fAg:5^ۏDMN:7_NGA.7hв3FcQzTl_!nǯ:fxE4NkubH@^œpfu-Y9*E0epV6#8MT}hQ{ڈv(z3BkLlS/be#kASFq޽[%ѻxc+-ۼ<$ ߭EIG *b:p}>B?u0Y'A).5bF H9_* MȿC2\{=~fzk.[7Tሪs
-BY\yVbBs|yίBP' JQV5=ϕiuWPWo\%$kcNdRyx5WXiAT]sS而).qp=0k#*W^5 (yڛ8he3֔"rLhTNI8IO ]=^C1W \*}#\&K}LX_j4lvY+>܂-IAY J (#^m}xw۝eQ"Z%%<֫ 1v_5Õl٠vUv]֔ }ɰ'emͨۈ"oGr@?{ :^R!UUSf~RxT5H~V=Utȩ'ʼnژ{Ǿ3j
-Xfʸx:N[=vDhCVIEy;#c`ĺ$mVc̡ϥPyEʝ!:ɕi&u,!E%:1梨euUBcEѹ>ZĖdh8Ѵ<5X\`Ǩcy~r=ϮD= &S}W=
-3nfhͨ@9+07NFO m:L\ *Ay>0Mc 8DM/8*'9ȇ\ ƄrHQgɹOi;Cy
-2 ٶ/pX׹|֧9dȭB eJusHs >{&q-LP:-V*d[ljӡ+u F<g=NN!hb;t'Bn9*a
-8Be7/'࿹'0Vn
-3W
-nlt
-N@( c+QIn&e7#RtA^;E{sHjް\yBP8-dLBsͯ-u9/$.nQOPlhdӯ.xE<jD?
-Ԝ 9G!?A8qeEMBvXd \ScvO~˃pn59+:xKBXQ|*
-xVV QXgϚ3E}f;o]2N9[_ub!c2|G FQ'Dǩ4W:
-mWuuZv:%5;Ӷr]M]Co6p#8AwBHx⼹j=U}:Kغ"K,z6XՐ ŠTt>BЉ6u AFJ8RB5g1yu~>mj܃@[ϲh_;dmYN(0 fe%
-[$Rj½pCJZ YF14k}oO HQċr1v379|T3`4:gn̂dIw~]0_:/0b\{ ?ߕ.Y$.e`J'<j?{[~%Syb7~E8 c R}>Ivٲly!wh]K@xRJKma~-8oBw橌>h $UERufGv/ fs(।"~@M}˚߈V 7ɞNI32(9nL}5yʠA#eD[&Ulb'Ↄw.T4%n>_it2VTeuz^ۗҫ"47-ZZtDp
-_ރcMtai>\02,a9crG$vlQ< SF ]Y}z&Ԧv.8:FR>#٢ð,߃r !&DM%CX}0$1`ݲ
-[Lo:0<v{3qR[x.U!JXqOn)=!o~BǫRJgq=n6 Dkgc!g݆|J} 3VBgx _Oj5ʙaĬ;WSJ-m5Z2QC,W;L'05]_,0pBh60ף~WeY(@1!N\$dy)Q`4
-dpeO:O1,">H!h^ni"bܮ i3І T?Wc١p%oBn\ VFtM_lQ_ZE}s@9`h4L AY^,YEţ8* w@ @gIλ0t1]e\B5.D|/?$YZ&/qg>~D3}\Vܾ#D37{(y;g'Ht(TQN7+/+?&#>Ӌ3M&m9
-lߙuE]C֙wqkK}<WuTW"Zhi+XwҮҙQ"]D uI#[3mWE|巭&O;4/8_uL-@ŊUuK'wIILx2B]TZSW:KeRz')^AXi<QLyQV0QU!
-KQ)YGߜr?-CBin_aa˛2nɁ,WAS/ܢ&ǫ%u
-S%}$SD]s&Ps;ET}% QuW3|D)  3}e[>~2VYO ʓ.67M~0w)dKn.xZҒ^x`n/US*CF84(s.,)V/u ۈ1!`~v@~dQօjIEyU$6"=w)Odq %zۏ%4'yv^4f/] 5vN(򌬲0" *]#G['ܽ[MTyqQlZ3ln7r;WVuޙX6T~}{,`Giu|[
-wu'
--$B1[
-/x6'}7T0Ġ^T}2[~(,Sۤ 5Dz
-C$Si:Ěԁo=9=ԌE&L*j1m4T$&VJG.X (>Φ%i~<6 31LrvFsNh/jhuA+ urȌw!ж4} d^ةXNc̻U[]W F9Z]x?R۶]xl*Ga[
-ƾSĹXR& " 8sy&;R W_8XDGbA4-32y k̍kNӁn?UJaEl ?ʝ?Fj}qp={YWoRPeZ36h}YF1ZAL
-j>Zv .
- xj
-zSH#~I]r3pJb]ve#*#|0a(cQK%Y9ZD>*@EDXuq_MmYY/)V[+͵0.y]m_V87 Gt{ut`Н)L8ƽ!a ݏWޭB/%?1E(٣ykPr2HLc1[+~K􎼍d<`u[9ۑ*>S0b`AGVM )]W.t&-h+5<}s7:E^
-9?%^z.x7U7:1> ZMXSރs?+i /G)R4l?3NrCN&<KA.<t'ton5Zt}G?n:g'0ɥHvT!O 8"5qo63Kx˧]Cz)TfPoYq\Lyd?wtZve2VS5R#
-rq
-kIqަGMݶHR!%P_uS!J㝔6ϬmgEn!qL; fnFK8]g uh8M7ZbgFSM$f#tBg|xxŋS;0kr@C0ȅomvo巓Exl v٩6V\A5x;x/
-j~K笒+>vM!@qNEcr*R }nr<W\/E6/sZzA$m%;̠ ˪HZnr|ة=`:_jDԣ?$|Sv1+Z
-&pYs<Y>R4L]t{,\37KzF @Ħ5# -4}N~|hQ<Q抍Sb᷼r'ުGƴLk/1S4G,p}Qwvx\LDHd{AmBS%YV|^Ϛ\pI
-ǘC HCr_k+S}  w0: B|?ZME;f8HIeC{rؓ > CeW. ~`pb3!eN:yߠ9mA`l@
-CY%'
-6m5D^s& hvc?t 9^fUX@r_%D?WwM@uw?
-hA#p<zoU݆>jwb]%a+ØZkWu\%<-;[ "Jh/5*6wc -~VC=ڃʻ!~;废v0"N։QQz<-L`/nJ~ElVQI T|<m"w{ӚD|!Xy}DgM.96@'E7i<k[|nSC4F~^2B ;L[C b5Z5$,eh+2^f^Ȗ}=?%V]Zѽ|"~>{i< 4 W
-BWEoOz--p
-&L1 9Gx7hS47Y/1"meR* V|E:?bVdGV"~#`1z~6"SV˦DgO|D'd, BxE{w
-v,a!rZy̬h Nr2TA~=ngqs0Mƾ˓%f8>۝9H}~s󶫣 !JXQT
-B A"Wu D
-Tɳyd<DB"& P),Wn?EðEa_nߍ66aS{l;, ]q`~MǢԟyP:[\/z0Grt//3]x(npmٔ%
-a |~g-_2XF^Hf&ϐҡ\DXoO6/-Q /?~R vhqDL|ܠjsG
-%S~[(nXf1k1lRk7;eֻkGrXtJ2,ًߊ띖Q?uU@3#wyt Jp;]A58V} ݳHBФGv5dd90|c:_{53Aڤq;E/?tx~v`_gN<?z|D|%OL2-71H:n`͇8?ow#!* ;ݟ"l;N7c"l^^ű.[ Ao5/ט/A&0;g(M |?g%jZx?ߧgSZ6|7?V =eo)bFguAuDSZ;8PžAS6BLԷsl4wsfb;X/xYr}1Lt=Ĵ?BrՉ~<Vn>٥liiZ\#0O򴠽{p{sǺo :UV#ĠΏLqSWS7NEaAFNҚD>#fS贕_P' -|,o
-#}Q=acB`f0W}57~`/,U!R'h[ZigaJwa]dޟef5
-b~C+͈PG#M_#v?xkLK $ZW~+{0k`$fZ'Ox:n1&K̛HCUFR6{Sd3Iߞw=f5AY<^m7Y]y\J R!˦jTT_UYC ȯ ^Ź242m([0p c$@ňa"{ TSvYNfyOdQ28?no.2ܳDe't9Nf p:G۟M,m󡘢h>YDlЖwzens<w^/ phb|h:jzJت
-w nX/qç-C&4Nƶf?4{'DYC^+Dwv6OLg5h+5YMB55e/^9ԓ"$
-\tv/^TZneعB4,@fBD]:ڰ&*IЙ`vaȆ„.'7Zo[*~vNM+_VF+/rpMg#Af1>eS=4xIC}
-e~hۯRx|wiw>E["@.
-Fkgf<,PKi];cRϒkGoYAS|n.js yd
-/āSCf6̀
-z 1y䔈 ﱑUqT(vzR,Q%  "?s'I3PCI-MT["p
-;߆t؆ױ} 4MU-͘1 tzK{_!"rEcVk ˈ^
-y5\?[G@ʴ/Xȅ/|f Ai;OY@`YwS)z~)\O
- y$=-G ]
-F `AGcdΑAI &1YzAP<M$>' ~u.]: F8O0@h*|<ǏRtDA*2kSSOƧ<qhPT61I(xrLc;ꘂ9
-InIS$ a2E Cx[3n
-!bK&߈Kt:c;SPQL+2I<;_z+G&,CV1{e&p3 t.[`Dg qb3f&^ύZ9N@$͓{jZzS,dp_tMeNKAl$^Yai(eHΣtV;4i6|m. tB; pi<-
-Coa=m ?`zqy @esСt< Ncok6
-8e<-,piFӶzD(#:s-\Q֒@[zМՎ*^z* ve#jHݱA7gFj-BJQJh$]䎩"o C*MPuˏG>pfp["JBQ4^Zx_.J~DДh8Ës[ŋ`9%< sSYs*IFSaIDgpt1UsOi1~t'}C5,Row{
-VXFMd ͌oM"5 ̝C>7uzh !7o
-D;t|(\w/Lj5d$S3û_O*()58~2$zeVNg, Q^<( ~LKug,HZ\N&,ۭz#/?@mfKO#7 i)
-OuȝtvnMt|Og䜕73>"<<74LҾ!`s$ݥz C.L L#j@
-}p
-Mj3W2YhGx wö]zyF4 Sɲ5Ve1?C퇑xa/>>yХ<S'5~Ab1.  jS%w&彯s#=)
-mAT3.5_l5<7Yv@ϖ)rr'M{h7c{oӶa=k,!k3EcڔgvH~o,oS\,zSNJĺ>3*q[z=mV<
-r/0
-J vk$*
-*X9t`G-Ha`9k/+S%E;FX.~4Ϡ }U+"زTj|o4D;dClÜC*Je+kNqix8r 6;Ve*
-oSǦבf"weWq7}&Ma,Y)'5('ڑ\HBZca"hes$xXW&WC>Y $n"d:Y`47lMSIKD5!e AIL FwމE)T|ll!sЮgIo6#kRRFQM_<B; fjXf
-)P܌6B+ ؤ)ܤ6.*zټ/k6Rykr]-*e" M`M<AM=op?!ښV{Mx^c?8 vQfס#s6y#|fZ({7}d):ApQSzMMB`_6sHxvt!XI|d-^X^Iρ R$- (RH ظ9k "? 2E=KYxz pq{-)mg4x̩Hs7cG0UU*˭5[4;Ƒ/L=5qnx#Wg[t}& \7^ۂ76 yU}?ZW ԥ%d@VqA#_A؀a36<?9\VFL_
+xڴeT۲5;k%hpqww ,;N}ν{ݿ`@SlZJ&F@ [=3@N^dM4s6t
+j?y ˋ i)339tpQ3M
+6pp(Y8UNc/ 2w/d>k3}@@GG
+hC-On
+mxt}AŚAX֯~\( }Qg!WIB}$U6J<v,2vLu-ڵhm STfla2ͬA~1.Tmڔ|5nԖ¹ ]۟?G|$bC6]2/4LŅ.ڔO jMBJBt;z"ÏE ?.`$"ŎO1x"_]<_W>v5q{ P >&QnDJ9fnTnhO&oZ
+?=0LjhrL`~xzNw*72 Ƚ
+CTue9ui:w2ƀ'ԫ$V,`y=~ \U^IvwOu6kY?oՎ*%Yq~-šE-[J0ů?5.&\7^{fܲ^[rp72Kp#Wkf'){ܰ&rYXuTM >qqҫc'Eh5NM2-< Fnȃ:g 8.Ǐ,q7F.hW~+'S_7rhw:xDH9kf,_ԦL
+yݳJw я'2cBMIgrz_$Vұ 9+@PT7 0ݠ_ ^/1m Yv&:4= I>z¾X
+,pLkk*-Q^Îaȍ$T ̻q͋ 5 ~Ʊ* ݵ8r,Wb'xXAƚk3P%Yfah0o%5`E`@j{19-oSJ$Egh.<U\"DA[n_" +]l8+st]#EaCk
+
++a'>O]YSHIIP{FX7)z":v4%,qPV
+\2{{ ]ܭ](}͒<#l`jpcC"u-Z= yΥ v v蒦J<x
+e =C-74Z@CV\H-ݽJE{"Xz\[.%:
+&# U_`, L\Uf6Rb)chy\\jYRjÁTV;B/p<bEj2O
+xF  OW$.O~x;fVlͻpg'FhϾJc]'#iz[Q`g|bJf0_ՐCHr!bHx_dweLsqS'ަB57I\0!suU__:XR9ѩZ;er0)8J_Vẘah
+Yc\20#-!<ê[Ci~4l"$fKXIvf 8*"ߛfI~2qy&mUp?<RuգFm!=[jxdhw<-| lihÌ9fRch$jG
+II #%-,qRo]ZgQIW0~C5::u!`%RvH;71<9>ar!c` H]َ{GRN>p̨
+5"Zg_9Kʸ75 O]LD$@ԓ4}_=7VlDڸ!:_:y+ 7Ñ=J>g]0ǏHKu__$
+'<ۇu>z:{#vPaV SD2TӐTǿόEvaFaԲt]{j<do)Yc[ytP5oFyy5-?{ '$`D 'y݃Qޱq9GbϯA՛>3^ A ԏSK&4zt߬H"&e$ [x>㮟52t"ʘb`|ρ%*rWJpjRn Hc;.zD2QR6)2#d|_5KR\=
+XXvII/\ay+<F{&yIgk`a*JuL5 _9duM<vS|
+Q8׫ r钯Ζhm y%G,ڸ6ZE*zFyǫf I)bo.K]:ϲ!h+ K,<'XlQ\[WVG._jjUJv4=߃܈oG {jNo}^MDYC_&j+gۉ
+k5[ׇfBH:Hj|>!i ɋ%-tC6^ -ˠ ۯd򮸶hu5In3p<Y)HGj!Q Z?rGܱ,D >!B]FHGfQ'pϪ&Fm~K{6
+v"F;Ի;pνqH4< rҬkߟa`h^&phDuY;\n\:d6 0D$%LZSعt' -)V;M&M">07JF=Is5ZS4 Vы.事m [ުl$,;
+/6Ŗd~<G-[\ $[&t!?z1ߡ_JQySk+U yJ1ͣL-ml;xTlAޑOK/wY::xxNDqS<r62ig-yT@U>j}4%z4V<x1 8퍡/(mR^l| m y qIH#-d`ޭ8$b;J%t# 3X u_&j(5>6f{~nw&^ѩmfkTٞ6)6Sgg#+uўѕJp V(}ci6`I>yɣ1hۊ:L?Z&ɀ`Wc;3P`XFM3;xa';w%T@AK l-''nY;!F|Q#yu_GKRx喇
+aKxmu]j<٘s^K/l4Oc_.P~&FS6KR>י\bB?D`잸}yY`Q b1 nְn_s|BAWA[=rU//W!?+FR[e&\T0rd$T3e;{›T
+OAipY 8k7z1'a:̓`G-0)|6:{Z:!,D1S, $^`"8UCjQ7Zrf~ۯB[!ɓV|
+uxb[qZEzvQ(Թ尚=g|f"QS;xv#"gEz ѿL_TnD‹]$YY'PA_Q}â3~OH< 48dT,쯔m!܌= e#7ufElۀ7#`|ZΊw)G%@z=^ʍRQaU)e". +B
+H*9DP3հp:ićfgPQq)
+>er)ݟ;DCV*BgˋlƩ1eh($?t!+!hъN"3.̝7TtI`ںԦ IxtB9PL/^Vak|ӈ26WJGLW<Yo<r:'\ڌ?%MCvgW[xz7 Ug 'XP2;-[;rC?a'PfOiq}K(|rɄnrӴ<w^iܬ-o4|L0'mMVʦNj+#{ꁉ=#$Gk>aVKFjǠ㺶`9EB< kϢLNkTC87qz?S\ vR0́]hd]V-W|?>161X
+
+5'&.*6qQڒPg̛ANRxgZKu9e:F`fDELD q&xwI;'(h6Fu7[Bd̹ٚ|Ioby[˾HAC6^C@JKY412;HXŚ(HmN⹠*343b##!BvQf4fCח;`oU~ %IxI}\?NBUNJl=I7]I=avbzȫ=Z3z
+0ڡhb1bT%,d]]˓+\]{WgJ_9HN6Ph)_p[ڞ'1Y4AF}Hd3tnk 8Fӝu\|lI#Dy-QRZ.)K,7n25u^rQp* InsRRGbm>z۹;Av Cr|ɸ3b
+T33х
+$☾@: <ZYfR-w;SoT[hUS2K&i8Xx7[ `\6hzeAek7V%RmV&h"lE
+P>9̱+o@:%X*%{e47ICx,:e{3POFoeAAHhU6c꯮|iyԊh% K i+yR*'>pUA7sʼnZ.8x
+ wp`V9VC@̾[4gm]&{ABb\fy
+.BT٬ߟfmUR+LsyI'"?Hw,]"OAqؚ)$'ry=#e-F":ÙpZhy+O(f|BzFpLvq7@2Cb.S^|ˡ~#;!*6Vm aHXylQAѧo
+BJY.$L_VK9.i.g
+͏}yY%4>f3; )NiLQ†w5/M(mSGV4 #DD)+!ڹ{Q;zUw4}Z4_`"NmǕT?Qolr Wrn8wHދiH״*wN{SW/֤yt~v89ux!_+S+|5 S{Ϫ$GMڨah*)q{X}Mvi8Ѐ3FD+(!;կjފsW^|,+/t|tJq-tqxc_[i\Em2jr/\apeJl:=bmuԴ"IL2=Cژc1EɼanD}L o;-r7.!-; R/9~Dvn^+ŕT(P%ї&Ύ]ٔ+2hjXD&wpk`A@־*6Vo1)v"j;$WfI}_V⛳`|hgvrG+<:X}K7x<hf^i49 YOE&ݹm}QǜCǙ
+NN ֠6`jn5TK;w7b#3 Ji-/T:VoJR.-\}) b6W5@Q >|#+PByiϱ)O`sX® 6WܗqTtyH`sp,9 !\Ͻ/:PI 7aX$lϴk <4rHY{Lmj4g!Vk
+)ikA-V6´`P]qyޕrBS~v;ME`c7'hRĵ0g&ly
+)Y&5gr9>Z6: &37 "uSE<|H?
+RY!9Qv~5o
+
+1oJɄG ~IJ ` eKw>I
+ڞA6V,=DCgB#g;L!}zC.qߨO2ECMtthW
+u[DӋ}0e LDC
+gi{iUzC@x2n}f6XA ûUfU&)u{ #WW'iEXAXbߚ1[KmIB柎zН.=퓵2xt|i0y蹕!tSf(;T#9cvj6 6RE=._c 6VVҀ eA<x^1 fS
+KppbS?
+ii)>L]Hzr=`/-Q*Q dq#OIR04.WK?fx%Ԉw=]#$ȡUWwa7 eNh؜:a".e#-B}D8ݢ{|/.
+u%V7>d
+wwg jgVlZLg"1;C0Vh:":iBkg Fa0Bs1_6eWiM.3C܀%휩#5 E2b_BmY)Nڈ
+A0|Ɗ7SII GڜeV~e
+rja+*J]duٺVԦ¦Yn?@:Bu /W뇜\HkPW?5} lAM(Rq/<jeqxHqt{~\9'ľ qV|4%E<He.~J)WVK,Y yw5i&*%: wY[%10qp i &dw A.
+5@;Z"IYf"w;-s5^ !I,>S]KAg ߑ[^)4δO]B?UՉeڟ ?8Ďzڨ^X+d/%%T X*H<hƺeu3x<3`y'h ma\-P'1t%nC>6ot
+o(s _&ɢC@m=85` yĮvY=N?ݺVn&|+O22\<!=]զ}#Ѻ6Bt9ƍU]vPYZ!+ht!ګfXPc 䶾~aI_[hća`Խܵp<p[߾#E^ v呆Ǽhhɐ1uS!|
+u$tvdY!x,6B5fF暱f,6Whj^j*\G/<L~fYt'6gfP?2B?'xuheV%K*QƯ ϩ ;U
+<ş/Ʃœ>k/O `h,B'L٠)P.Ļe*lE5llW3K$|uiTv<y%qi3lQpTJxYqi XlAχ".U}t8یނ܎.vpfXJ{ϾQvM34*յlاxWsWxe^hpf񽡀$CAcv
+!M)eɖgmB÷*h<.8y<{ z-`dz\]؎f0ʜH Qg?-8>y α.6^דѲ-}XESo(|\3Do'MԺ[.;,Nv=}C$\UQJb#lZi47N
+}ϡC,e\rF`g]T M/רbI[=߉Yx/+LȱkE0}4ٱjii -.,&QVTu/p4gE~=B [BZu
+n2̮rJ
+f,U֏
+ME!R %RjQakzpv n(s".L¢ Y̊m2TM=,lRF,,b1)e6kqW bS鶕V[ި.z\VgbcSwNwHh~v_!3;$?}K&X̧@kDsiBɡâ{ yrpi-ƧY|MUj':v*>^\׍OA=G@ZO9"[mP&kt棐MڕKzhntXgS|Wׯ]秮%A^R=M Y5%[LƗفd bnaX3wN,\ɃT2}V)2CYvʤ[fMp&3 PM$iUB[` ΛBR>b|E:8jfCF?AեjSZ4Z؉16JƤ%V۪_=`Av5ߕ]=бS"`Z8W!IN`]Mf-D.$:+E"RQϛۏAd|އ/2<,ws`o޲x}HT}m黟_Lk?6xA{ʾq=?h<Sy-yT} Bۯlfbc+ WkLQq@}{O5WPiI8ˏTYSWA\ 0>R9kx^W`yH.p{W V?2.XNV KF?b }y3rZ~B
+͎d"S3vGrI܏YxӲxޒ
+ա}~g,3i]xBly?k=XcAC)Q25'A mʭ޲C/ 1kXdI옴%6UaMu=},uَB;s~۟2p=Pp461%g Js?3,eQDyA;M}7:OӺӛB2ٽ`yxEto)W<yd?_2h;qql~GBl;XJ[v'b}5&R܋$=#Mttx˨{"cfZw]it6ډQGR!eѡju<qҧ^G;16l %ƲsE\0X*$ KG7" +3SluyA^<KqY9٤Yf*!*D:mJ,!z؈MSd~ o N2BP~7vq04*5M7&bmUd_*92UE041qjG<n+k[@JP'=ʕrry꾂V]AvHyR&B䮤RO3尭O$
+;*H{@VS~b-Fvt]n!RYz*^tMV|d쭉4ZO)xOj*/aqҚt(~VDoK5VHEDCЎ3"Vgt$B+ Xۣ/o>Xe-}voUW_]-Qb~+aHxMb>Č/?->0{_2bjCv-}"DX1\]CvUR~v!=#6L8ű떽m6WawTQMeGW,Y~c=EyFHvOb5o5u-qDcL'jūٓ@SE%¡cXq]53R^r(=V=Cg9+ YF|4Q^یsaf)K լtÒ3h/61ؒ
+I[0
+4Bs fk6#c.׬璖v_Kho=g"#,MPVmrTiM!gM6{`k/ J!mQ Qm?Ưzt89`ZÂşx,!
+gZa9+º'm"4N=j;l{BB0M-{ȦP|r?[XhUVrE'`U|Z GKpXO&ԝȆZ}X1NGz5 e$
+̥xt[\4vŏ"Q+L vҜepe
+X]U,ܞ`>/aE2I=1,v"  ci?ڋ>|5ZAޜj,[,`]Q!o!ox䋁$!B1T%UuɤFZ:7T0LKHMhGІɺ&H)˸9XN\94<;4=`9Jf-MoWmupҲ:ߞz<H;"mag0P-vKu
+74myDD)Th #T_x> t`~@0;L/h|#]WLI= }-:C"5LpU8ε_Bه nҎ&GmlI,ĨTCaqǢ=߾]KGdfz_`OJ|ŎRF7 0c<\{'պR)%$QDQɫFN2U?حTMUu/`?S4›Z!s}ؓw)OOj%I-<Na)1ه!x&IЩK8?w&j5՝r6~%C+ rv(~ѼKtkpKXňE"`_B3. onjUxHFaZ/8t;JcB⸻SAAfVa9aBD?di∃l腲S;ߥٞN`o_Zj]xD50<O ]zE叶Jl}ՕfB"1HYZu
+HA=J1R5[y|T
+nevP@6ߏ
+Hz48-^9e:!Md%q֠\֌tHG?[ _,~ua>05Wm\dmBYp aOUi,Fe*eõ*,*ޗIhUɿz~㲚lٍ.r0 깮4+ᖑ?zUԔ>g֭0!,hّdOj?=|$XmϜEZ|7C-KqeTW|ʥ$ ypc t.\n,! N1Ͷ-ĪNN!Q}+#) ' Ix'nϘUĴz>$2@ZѯEudžq(tЇۭ 2 ܆=D AUE?ʀhf"~{ɍ',Mί0씩5|lf|&?"6VY0`wiF.Fځҭy8;WOTӁ=)o Uwuv)n]R ;
+- t엙5&w:b&tC %@USU#.e\)fx"o^JpyW\*Ƽygr#bFC# eJi;9T׈N ';E;T=ž&gW}d>X`gsxB_uer2!fl3}Ë~\.^HJ3{U\xj(
+&CByp"\Y}{<w|ڏ* L.]{*F>ip"fϸ 2/ms Ap;ԫ{-J7 I%IKت>'l
+=C
+3
+gpF+ߦug"Z&F%z#iwckԤZP@['|vkKC:&Q_D%%#fl5h˓j'?+I{$B x>3+2W/yv<tˣX
+هT/P\d ½"!EYyBB,oV@#fziq*rߝ&!13nv
endstream
endobj
-555 0 obj
+649 0 obj
<<
/Type /FontDescriptor
-/FontName /KXHWAY+LMMono9-Regular
+/FontName /HHYVKF+LMMono9-Regular
/Flags 4
/FontBBox [-451 -318 734 1016]
/Ascent 600
@@ -5381,480 +5998,968 @@ endobj
/ItalicAngle 0
/StemV 74
/XHeight 431
-/CharSet (/a/b/backslash/bar/braceleft/braceright/c/comma/d/e/equal/f/g/h/hyphen/i/k/l/m/n/o/one/p/parenleft/parenright/period/r/s/six/t/three/two/u/v/x/y/zero)
-/FontFile 554 0 R
+/CharSet (/a/b/backslash/bar/braceleft/braceright/d/e/equal/f/g/h/hyphen/i/l/m/n/o/one/p/parenleft/parenright/period/r/s/six/slash/t/three/two/u/v/x/y/zero)
+/FontFile 648 0 R
>>
endobj
-467 0 obj
+559 0 obj
<<
/Type /Encoding
-/Differences [21/endash 27/ff/fi/fl/ffi 33/exclam 36/dollar/percent 39/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P 82/R/S/T/U/V/W/X/Y 91/bracketleft/backslash/bracketright/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright]
+/Differences [21/endash 27/ff/fi/fl/ffi 33/exclam 36/dollar/percent 39/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P 82/R/S/T/U/V/W/X/Y 91/bracketleft/backslash/bracketright/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright 159/section 252/udieresis]
>>
endobj
-480 0 obj
+575 0 obj
<<
/Type /Encoding
/Differences [0/parenleftbig/parenrightbig 12/vextendsingle 18/parenleftbigg/parenrightbigg/bracketleftbigg/bracketrightbigg 32/parenleftBigg/parenrightBigg 112/radicalbig]
>>
endobj
-470 0 obj
+561 0 obj
<<
/Type /Encoding
/Differences [11/alpha/beta 14/delta 17/eta/theta 21/lambda/mu 25/pi/rho/sigma 30/phi 32/psi 34/epsilon 58/period/comma 61/slash 64/partialdiff/A 68/D/E/F/G/H 76/L 78/N 80/P 83/S/T/U/V 97/a/b/c/d 102/f 104/h/i/j/k/l/m/n 113/q/r 116/t/u/v/w/x/y/z 126/vector]
>>
endobj
-472 0 obj
+569 0 obj
<<
/Type /Encoding
-/Differences [0/minus/periodcentered 3/asteriskmath 15/bullet 41/arrowdblright 49/infinity 76/L 106/bar 114/nabla]
+/Differences [0/minus/periodcentered 3/asteriskmath 41/arrowdblright 48/prime/infinity 76/L 106/bar 114/nabla]
>>
endobj
-475 0 obj
+571 0 obj
<<
/Type /Encoding
/Differences [0/Gamma/Delta/Theta 8/Phi 40/parenleft/parenright 43/plus 48/zero/one/two/three/four 54/six 61/equal 95/dotaccent 99/c/d 105/i 108/l 110/n/o 113/q 115/s 117/u 120/x]
>>
endobj
-193 0 obj
+567 0 obj
+<<
+/Type /Encoding
+/Differences [136/bullet]
+>>
+endobj
+650 0 obj
+<<
+/Length 844
+/Filter /FlateDecode
+>>
+stream
+xmUMo@Wla_BZX&
+Q+K62 5fI`x;fͳضߺItճ;סqT}s=ùֵA= }vu[Uyk֍I{wQ/5qhe9xSTQO7}̽][GLrFMG}}"Im!00jEV%H^/v}0<_7RyL U~C`PރSӯ|'
+imXYӷ|4nt.kP^k?IFsuB`nlB
+=@ )U 9yI(ѥ
+S*043``ÍSqf|kiCc, pDˆzF:x0)ljsn l9u}Sr
+МQV14Ld5cY9Y?=C9돡'g ?%>O:ShYg{ΈrYgDk>[bghX|&^V|sig33qgng3tZ[Yog,g-g B|B|\3gg|2?f)<O5]TߓT+&#{U-'H8x?0.t<wtOȢ\: r
+endstream
+endobj
+214 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /KTPDFA+LMRoman10-Bold
-/FontDescriptor 505 0 R
+/BaseFont /JFISNR+LMRoman10-Bold
+/FontDescriptor 599 0 R
/FirstChar 27
/LastChar 121
-/Widths 491 0 R
-/Encoding 467 0 R
+/Widths 586 0 R
+/Encoding 559 0 R
+/ToUnicode 650 0 R
>>
endobj
-192 0 obj
+651 0 obj
+<<
+/Length 844
+/Filter /FlateDecode
+>>
+stream
+xmUMo@Wla_BZX&
+Q+K62 5fI`x;fͳضߺItճ;סqT}s=ùֵA= }vu[Uyk֍I{wQ/5qDŽ r Gէn8A{,쏘LEvDB``B9zK~;_q`>Wgy o.>ݫﭯAbZ%?6G_Nzy;9ڰoiܰ^]0zu\~3ݍܥ: ل0%1 " 0Z{q́0R0r0QK5<T`,if,1gT Hӆp1X:,p8}u
+8alSM3?r>x\i"EܰpJMkl4\?ǚc:#?^YHwuprQF^odž1BЖEQ?1^׆ƨАԗ039+ãbLi~jЙ}s~zrCOe fYJ|֟uМ8gΈrY׆}ŊϘъ1LҊkgigϘ݊og3f3|3ߊY[3 =L3f/gd ,' f)Rx jb&'W *.MGZN(:p~7a?}]TyԟE}Ư%Vu'e%
+endstream
+endobj
+213 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /WVGYQT+LMRoman12-Bold
-/FontDescriptor 507 0 R
+/BaseFont /POEXVF+LMRoman12-Bold
+/FontDescriptor 601 0 R
/FirstChar 27
/LastChar 121
-/Widths 492 0 R
-/Encoding 467 0 R
+/Widths 587 0 R
+/Encoding 559 0 R
+/ToUnicode 651 0 R
>>
endobj
-186 0 obj
+652 0 obj
+<<
+/Length 843
+/Filter /FlateDecode
+>>
+stream
+xmUMo@+H.Ȳ|hQի Ԓ w̐4Uof<`ضߺItճ;סqT}s=ùֵA= }vu[Uyk֍I{wQ/5q'w` r/AEI?p݃2ZkXvm195];7Yѽ9z?~;_q`>Wgy o.>ݫ,oAbZ?6G_yy;9ڰoiܰ^]0zu\g$eKյ: ل0%1 " 0Z{q́0R0r0QK5<T`,if,1gT Hӆp1X:,p8}u
+8alSM3?r>x\i"EܰpJMkl4\?ǚc:#/w,': fyRy(#c^g!ch"ƨ/kC^d cRx~h K^|
+МQV14Nd5cY9Y?C9돡'g ?%>O:ShYggΈrYgDg>[bghX|&^V|{ig33qgng3tZ[Yog,g-g B|B|\3gg|2?f)O5[TT+&#{U-'H8x?0-t<wsOȢ[: $S
+endstream
+endobj
+208 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /WCAPHI+LMRoman9-Bold
-/FontDescriptor 509 0 R
+/FontDescriptor 603 0 R
/FirstChar 65
/LastChar 116
-/Widths 497 0 R
-/Encoding 467 0 R
+/Widths 591 0 R
+/Encoding 559 0 R
+/ToUnicode 652 0 R
>>
endobj
-194 0 obj
+653 0 obj
+<<
+/Length 841
+/Filter /FlateDecode
+>>
+stream
+xmUMo0+J! ᫊"RVmk
+N)$̛3njNelܬ=WW\?;׺v=ݩqhY]jwOҺ=po]IAu~\3FXҝA5(O)suߖcHQIܮQW Lڮ9ˊ6nK5NoغWi~r<d(Vu;_=85vѩֆu5CNmm悥+U=#)\][|, MHS"#p
+endstream
+endobj
+215 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /IYARYO+LMRoman10-Regular
-/FontDescriptor 521 0 R
+/BaseFont /ZDORWX+LMRoman10-Regular
+/FontDescriptor 615 0 R
/FirstChar 21
-/LastChar 125
-/Widths 490 0 R
-/Encoding 467 0 R
+/LastChar 159
+/Widths 585 0 R
+/Encoding 559 0 R
+/ToUnicode 653 0 R
>>
endobj
-184 0 obj
+654 0 obj
+<<
+/Length 841
+/Filter /FlateDecode
+>>
+stream
+xmUMo0+J! ᫊"RVmk
+N)$̛3njNelܬ=WW\?;׺v=ݩqhY]jwOҺ=po]IAu~\3F;;=}kPQ/7SVk-8s擸]׷QPP]sݛ麟;l,j7O4uc׿x;P:XTv~{pjS! j֝ƍKWjY׫{FR^wwPG*X$D F @F@k} 89@FJuFF#`R0Jt
+5 5553<pb
+9LsQ.(ulgYˊx/V|V|&٭ V|N+>cv+>7+>S} ~!>_Sϔ+>cB|&LOr`B,&+jwRP{x${y儢 1~g|sGӿNu]>~?,5(z
+endstream
+endobj
+206 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /QRFTTU+LMRoman12-Regular
-/FontDescriptor 523 0 R
+/BaseFont /YYNMCB+LMRoman12-Regular
+/FontDescriptor 617 0 R
/FirstChar 44
/LastChar 119
-/Widths 499 0 R
-/Encoding 467 0 R
+/Widths 593 0 R
+/Encoding 559 0 R
+/ToUnicode 654 0 R
>>
endobj
-183 0 obj
+655 0 obj
+<<
+/Length 841
+/Filter /FlateDecode
+>>
+stream
+xmUMo0+J! ᫊"RVmk
+N)$̛3njNelܬ=WW\?;׺v=ݩqhY]jwOҺ=po]IAu~\3F;;=}kPQ/7SVk-8s擸]׷QPP]sݛ麟;l,j7O4uc׿x;P:XTv~{pjS! j֝ƍKWjY׫{FR^wwPG*X$D F @F@k} 89@FJuFF#`R0Jt
+5 5553<pb
+9LsQ.(ulgYˊx/V|V|&٭ V|N+>cv+>7+>S} ~!>_Sϔ+>cB|&LOr`B,&+jwRP{x${y儢 1~g|sGӿNu]>~?,5(z6
+endstream
+endobj
+205 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /DOSTYO+LMRoman17-Regular
-/FontDescriptor 525 0 R
+/BaseFont /OOKGAG+LMRoman17-Regular
+/FontDescriptor 619 0 R
/FirstChar 27
-/LastChar 121
-/Widths 500 0 R
-/Encoding 467 0 R
+/LastChar 119
+/Widths 594 0 R
+/Encoding 559 0 R
+/ToUnicode 655 0 R
>>
endobj
-190 0 obj
+656 0 obj
+<<
+/Length 841
+/Filter /FlateDecode
+>>
+stream
+xmUMo0+J! ᫊"RVmk
+N)$̛3njNelܬ=WW\?;׺v=ݩqhY]jwOҺ=po]IAu~\3
+imXU3t6no.XjR˺^o3򺛸kյ:W ل0%1 " 0Z{q́0R0r0QK5<T`if1T͟(Hӆp
+8alSM3?r>x\i"EܰpJMkl4\?皞c:/w"': fyRy(#c^g!ch"ƨ-kC^d cRx~h K^|
+МQV14Nd5cY9Y?C9돡'g ?%>O:ShYggΈrYgDg>[bghX|&^V|{ig33qgng3tZ[Yog,g-g B|B|\3gg|2?f)O5[TT+&#{U-'H888ӟ,t<z9GdEC| <
+endstream
+endobj
+311 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /QUWGJL+LMRoman6-Regular
-/FontDescriptor 529 0 R
-/FirstChar 49
+/BaseFont /TRUNAO+LMRoman6-Regular
+/FontDescriptor 623 0 R
+/FirstChar 48
/LastChar 65
-/Widths 493 0 R
-/Encoding 467 0 R
+/Widths 566 0 R
+/Encoding 559 0 R
+/ToUnicode 656 0 R
>>
endobj
-231 0 obj
+657 0 obj
+<<
+/Length 841
+/Filter /FlateDecode
+>>
+stream
+xmUMo0+J! ᫊"RVmk
+N)$̛3njNelܬ=WW\?;׺v=ݩqhY]jwOҺ=po]IAu~\3
+imXU3t6no.XjR˺^o3򺛸kյ:W ل0%1 " 0Z{q́0R0r0QK5<T`if1T͟(Hӆp
+8alSM3?r>x\i"EܰpJMkl4\?皞c:/w"': fyRy(#c^g!ch"ƨ-kC^d cRx~h K^|
+МQV14Nd5cY9Y?C9돡'g ?%>O:ShYggΈrYgDg>[bghX|&^V|{ig33qgng3tZ[Yog,g-g B|B|\3gg|2?f)O5[TT+&#{U-'H888ӟ,t<z9GdECiA
+endstream
+endobj
+255 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /FPSNHG+LMRoman7-Regular
-/FontDescriptor 531 0 R
-/FirstChar 49
+/BaseFont /OGJSOL+LMRoman7-Regular
+/FontDescriptor 625 0 R
+/FirstChar 48
/LastChar 65
-/Widths 488 0 R
-/Encoding 467 0 R
+/Widths 583 0 R
+/Encoding 559 0 R
+/ToUnicode 657 0 R
>>
endobj
-266 0 obj
+658 0 obj
+<<
+/Length 841
+/Filter /FlateDecode
+>>
+stream
+xmUn0CƆ
+N7RIU70W?'^$Is}=}exǡ}'u]U=ow_XߓJ?)裮_o'h P=mbKLQ/?C̭:}W {pCM/6۾EzĪ۶'Yѽ3~< |OaxIM4};?n7uEYy>;JG& ߯^M~*aUaqݿhB͛foH]n-I&H8@l: ld`TYg``&Bkk0jNXXр0#` w]jG1 F60q'kgqScsnl9Ns`qKK%pNI8qJ9q4Ϯ%p 2\XWkz,_8x1g1=ia4c̓˳G6ڀ cxmcfƨog!/lmΘ8+^P_-C#[34IN؆1t?E߂ޡSrY ֟gg9433.XgB3\iafq3fts
+,>G|F/'>t3:~:83fw3;:ٝ ߜLgw3t33 ~)>CO)>SK3- ,YJa)SMV襤:?85JC4I^ E'b4><? 8Ϸ袿CF
+endstream
+endobj
+313 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /KRNZEP+LMRoman8-Regular
-/FontDescriptor 533 0 R
+/BaseFont /BTHADF+LMRoman8-Regular
+/FontDescriptor 627 0 R
/FirstChar 27
-/LastChar 125
-/Widths 479 0 R
-/Encoding 467 0 R
+/LastChar 252
+/Widths 565 0 R
+/Encoding 559 0 R
+/ToUnicode 658 0 R
>>
endobj
-185 0 obj
+659 0 obj
+<<
+/Length 841
+/Filter /FlateDecode
+>>
+stream
+xmUMo0+J! ᫊"RVmk
+N)$̛3njNelܬ=WW\?;׺v=ݩqhY]jwOҺ=po]IAu~\3
+imXU3t6no.XjR˺^o3򺛸kյ:W ل0%1 " 0Z{q́0R0r0QK5<T`if1T͟(Hӆp
+8alSM3?r>x\i"EܰpJMkl4\?皞c:/w"': fyRy(#c^g!ch"ƨ-kC^d cRx~h K^|
+МQV14Nd5cY9Y?C9돡'g ?%>O:ShYggΈrYgDg>[bghX|&^V|{ig33qgng3tZ[Yog,g-g B|B|\3gg|2?f)O5[TT+&#{U-'H888ӟ,t<z9GdEC%K
+endstream
+endobj
+207 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /AKVTMY+LMRoman9-Regular
-/FontDescriptor 535 0 R
+/BaseFont /ICLJJO+LMRoman9-Regular
+/FontDescriptor 629 0 R
/FirstChar 27
/LastChar 121
-/Widths 498 0 R
-/Encoding 467 0 R
+/Widths 592 0 R
+/Encoding 559 0 R
+/ToUnicode 659 0 R
>>
endobj
-243 0 obj
+660 0 obj
+<<
+/Length 843
+/Filter /FlateDecode
+>>
+stream
+xmUMo0+J! ᫊"RVmk
+N)$ݪ70W?g^,ɝظYs{ \wu{S<.7զ7u{R޺>f? Kw{KTQ/7SVk-&9sQ擾]׷HRP]s6o Ogw!X.o; cƮS_wСtZ|I1?H/GBZV ; ZԲW/{FR^ww?U4H6!L@@B@q\s *<G`Rq eF)kk0j0jfx)4Ug;5Ҵ!\,18"\aD E_sN[sS9)9^
+?BXIAup*Çq G潪N$p|eO_:qw
+endstream
+endobj
+267 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /OAWZNZ+LMRoman10-Italic
-/FontDescriptor 537 0 R
+/BaseFont /EZYWEQ+LMRoman10-Italic
+/FontDescriptor 631 0 R
/FirstChar 27
/LastChar 121
-/Widths 487 0 R
-/Encoding 467 0 R
+/Widths 582 0 R
+/Encoding 559 0 R
+/ToUnicode 660 0 R
>>
endobj
-418 0 obj
+661 0 obj
+<<
+/Length 843
+/Filter /FlateDecode
+>>
+stream
+xmUMo0+J! ᫊"RVmk
+N7R$ݪ70W?g_,ɍehܬ=WWU\;;׺v7MOtҺ=po>fv8 | G՗_n}w̭][GL2sQ擾ݾk^!00jYV%H~~v}\; C}h{ϗC`Rރѩc~^ON6[7ݛ ZԲW/{FR^ww?U4H6!L@@B@q\s *<G`Rq eF)kk0j0jfx)4Ug;5Ҵ!\,18"\aD E_sN[sS9)9^
+?BXIAup*Çq G潪N$p|eO_:q;:'dE_kCvW
+endstream
+endobj
+474 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /PWWUQZ+LMSans10-Regular
-/FontDescriptor 539 0 R
+/FontDescriptor 633 0 R
/FirstChar 43
/LastChar 116
-/Widths 468 0 R
-/Encoding 467 0 R
+/Widths 560 0 R
+/Encoding 559 0 R
+/ToUnicode 661 0 R
>>
endobj
-291 0 obj
+662 0 obj
+<<
+/Length 844
+/Filter /FlateDecode
+>>
+stream
+xmUMo@+H.Ȳ|h%Qի ۇ6웙7X=<l;Ytգ; q\]UCs9ùֵN=CT;xoMI{
+gkpcBܝ5AUӍnZoIN\Ԩo( &TmלeE[䧷6nK5F*oغ_'m~r<t(Vu;_{c{pj緣S! +k֝ƍKWjY׫=#)/\]PG*X$D F @F@k} 89@FJuFF#`R0Jt
+5 5553<pb
+a!SM~W,:?8C8…I^U E'b|82 8ϻ޽YtїkZbu_G4
+endstream
+endobj
+329 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /FDLXKH+LMMonoLt10-Bold
-/FontDescriptor 547 0 R
+/BaseFont /JNCQAV+LMMonoLt10-Bold
+/FontDescriptor 641 0 R
/FirstChar 40
-/LastChar 121
-/Widths 474 0 R
-/Encoding 467 0 R
+/LastChar 125
+/Widths 563 0 R
+/Encoding 559 0 R
+/ToUnicode 662 0 R
>>
endobj
-195 0 obj
+663 0 obj
+<<
+/Length 843
+/Filter /FlateDecode
+>>
+stream
+xmUMo0+J! ᫊"RVmk
+N7R!ݪ70W?g_,ɝиYs{
+]7;׺v=ߩǡoݨM'opiT}IAu~\3;he?<{Q%(SVk-#&9sQ擾ݾk^!00j(+m$?Gwt>X.oTuþ{S_tpСtZ|I1?H/'BZV;ݛ ZԲW/{FR^ww?U4H6!L@@B@q\s *<G`Rq eF)kk0j0jfx)4Ug;5Ҵ!\,18"\aD E_sN[sS9)9^
+?BXIAup*Çq G潪N$p|eO_:q;:'dE_kCa
+endstream
+endobj
+216 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /LKXBGP+LMMono10-Regular
-/FontDescriptor 549 0 R
+/BaseFont /XJIPSA+LMMono10-Regular
+/FontDescriptor 643 0 R
/FirstChar 33
/LastChar 125
-/Widths 489 0 R
-/Encoding 467 0 R
+/Widths 584 0 R
+/Encoding 559 0 R
+/ToUnicode 663 0 R
>>
endobj
-182 0 obj
+664 0 obj
+<<
+/Length 843
+/Filter /FlateDecode
+>>
+stream
+xmUMo0+J! ᫊"RVmk
+N7R!ݪ70W?g_,ɝиYs{
+]7;׺v=ߩǡoݨM'opiT}IAu~\3;ф ~<xKTQ/7}w̭][GLrF'}}"IB``BQV%H~~?v}\<; C}h{ϗC`Rރѩc~^ON6[w>m7l7,^e]׵_&suB`ilB
+=@ )U 9yI(ѥ
+S*043``MSiv|kiCX
+МQV14Ld5cY9Y?=C9돡'g ?%>O:ShYg{ΈrYgDk>[bghX|&^V|sig33qgng3tZ[Yog,g-g B|B|\3gg|2?f)<O5]TߓT+&#{U-'H880.t<wtOȢ\: k
+endstream
+endobj
+204 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /BYUMNM+LMMono12-Regular
-/FontDescriptor 551 0 R
+/FontDescriptor 645 0 R
/FirstChar 99
/LastChar 111
-/Widths 501 0 R
-/Encoding 467 0 R
+/Widths 595 0 R
+/Encoding 559 0 R
+/ToUnicode 664 0 R
>>
endobj
-378 0 obj
+665 0 obj
+<<
+/Length 842
+/Filter /FlateDecode
+>>
+stream
+xmUn0CƆ
+N7R!L̛O3 /~\kil9DО|w=ިqh.MW|۷oΟYߓJ?).ogoiA~Mo
+A5(QZk뾫=8Fsgq]ߍG@]dbIVto$?'C\c<N;ic].J [OCj: wWog<imXW;txش~>ZjR˦YE3=sׁpuRA)`*R2$!`8li9UEХGSj043`4`4Ý(?Q  rt\e #q5p眛[q>x \iEܰpNMk l4\? 皞c:gN5^ ELOup3%M6`^ۘ1ل150ym 1F}3&ԗ0 bKl+֌>oRa Oѷ`)w`)?\֟agYg ֙P.L(ulgYˉx/N|N|&ٝ N|N'>cv'>7'>S} ~)>_Sϔ+>cR|&L|'a9i0K)cR{XTG5;)NͽRPs<Mph=¼W7rBщ3=c8B:]?~?,uQbuDה
+endstream
+endobj
+323 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /PZOSJI+LMMono8-Regular
-/FontDescriptor 553 0 R
+/BaseFont /KLCXYN+LMMono8-Regular
+/FontDescriptor 647 0 R
/FirstChar 46
-/LastChar 125
-/Widths 469 0 R
-/Encoding 467 0 R
+/LastChar 120
+/Widths 564 0 R
+/Encoding 559 0 R
+/ToUnicode 665 0 R
>>
endobj
-187 0 obj
+666 0 obj
+<<
+/Length 842
+/Filter /FlateDecode
+>>
+stream
+xmUMo0+J! ᫊"RVmk
+N7R!̛3njehܬ=WWU\k];7nTtƓ7]snb}O*۾~qg;e?<}kPQ/7}w̭][Gq"E'q}GB]`BQVto$?Gwt>X.o4uþ{S_tptZ|E??8/'BZ;ݛ ZԲW&suoU4H6!L@@B@q\s *<G`Rq eF)kk0j0jfx)4Ug;5Ҵ!\,18"\aD E_sN[sS9)9^
+a!SMV,鸞:?8C8…I^U E'b6>2  8י
+endstream
+endobj
+209 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /KXHWAY+LMMono9-Regular
-/FontDescriptor 555 0 R
+/BaseFont /HHYVKF+LMMono9-Regular
+/FontDescriptor 649 0 R
/FirstChar 40
/LastChar 125
-/Widths 496 0 R
-/Encoding 467 0 R
+/Widths 590 0 R
+/Encoding 559 0 R
+/ToUnicode 666 0 R
>>
endobj
-426 0 obj
+667 0 obj
+<<
+/Length 846
+/Filter /FlateDecode
+>>
+stream
+xmUn@Cz ,ei#&JW6)R Ƈ}͌6v̛,W_~|ޟEcw=0e]Mcgu]7C? 䛡}9wT~x~ыa~BT}*JS?ߕUQˋ~&Xu};ˊ!X7jy6OJ*F۩S?<x|Сt٨?W|#=imXY;vtܵ~ >ZkQD~>I?]M:)6 0): ld&*뀣uFQ `r0*ԨF55`liflhh0LQ.SvZ#M
+cʀ5F+8)k97'~ 8|%%Nf'Q$a %8l0aXjW={e.5=}M5/x104c̓3#K^`m11c cԴ+[`ڐ6c6gL3C/oV–vڊ1|5cO3>چ1t?E߂ޡSrY ֟gg9433.XgBq: }63fq3fts
+,>G|F/'>t3:~:83fw3;:ٝ ߜLgw3t33 ~)>CO)>SK3- ,YJa)SM>o:?85JC4I^ E'b8<M 8Ytџ궉r2]
+endstream
+endobj
+489 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /OIUXCD+esint10
-/FontDescriptor 503 0 R
+/FontDescriptor 597 0 R
/FirstChar 1
/LastChar 6
-/Widths 466 0 R
+/Widths 558 0 R
+/ToUnicode 667 0 R
>>
endobj
-263 0 obj
+668 0 obj
+<<
+/Length 430
+/Filter /FlateDecode
+>>
+stream
+xun0~HbM+ e5Q-')RyzlH]
+a+|GVZ=Bt90- Cfp{Ȣd%aޢ]ިfi
+M9;7,|1M06g۾iNHF,OۇF8E;7[GޛۦhJuDrAZC%rW~i#Ɨ, Kg'29.c_|8̉{vw^_x9"~/<ψ^xyE~/ I ă+g4ˍ{Yn P+qitCUqs67^
+ ^
+endstream
+endobj
+288 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /WSBTHB+LMMathExtension10-Regular
-/FontDescriptor 511 0 R
+/FontDescriptor 605 0 R
/FirstChar 0
/LastChar 112
-/Widths 481 0 R
-/Encoding 480 0 R
+/Widths 576 0 R
+/Encoding 575 0 R
+/ToUnicode 668 0 R
>>
endobj
-245 0 obj
+669 0 obj
+<<
+/Length 600
+/Filter /FlateDecode
+>>
+stream
+xuTn@+fH@!BHMV{5@,lsw m6n냝g)>mW_NiFq]J[o6nWbmmUON%О[:b',t_2~"!~PGGZPvE]
+,tĦʣD37ⱨJSZENJ7]omuRL?e׷WMܶEuGsrwi!Jr9:
+Mg޲:]fMR2IV;e8p<_9"*G(dS>sQ  DDr "qX+&Gha:$r5PHi@S91jU|s(V8>l;JۈYDI aoykrA)ς1R;JS΄U!ar .Qsy4M纑9Ҍi~h7!cD<`1 ySMgg>2 cs(>ZC@ f fP7Fo?],}/Kۺ=/mS7m'{L:
+endstream
+endobj
+271 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /ICUZBF+LMMathItalic10-Regular
-/FontDescriptor 513 0 R
+/FontDescriptor 607 0 R
/FirstChar 14
/LastChar 126
-/Widths 486 0 R
-/Encoding 470 0 R
+/Widths 581 0 R
+/Encoding 561 0 R
+/ToUnicode 669 0 R
>>
endobj
-360 0 obj
+670 0 obj
+<<
+/Length 598
+/Filter /FlateDecode
+>>
+stream
+xmTM@+z&?DƉ1LF+BG
+) }"g0CcE
+Ч }g?i{4 Z76C 0b S.0Y0XjGiʙ`2$C5%^s=j# \7c C1 ݏ7< &dL8f>0Ozʣ)LPקZFw?a ~NTKx6Ĭ# ᯋUEvi[1؀mQ]/8}&?K^
+endstream
+endobj
+419 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /UUTYVR+LMMathItalic5-Regular
-/FontDescriptor 515 0 R
+/FontDescriptor 609 0 R
/FirstChar 105
/LastChar 105
-/Widths 471 0 R
-/Encoding 470 0 R
+/Widths 562 0 R
+/Encoding 561 0 R
+/ToUnicode 670 0 R
>>
endobj
-259 0 obj
+671 0 obj
+<<
+/Length 598
+/Filter /FlateDecode
+>>
+stream
+xmTM@+z&?DƉ1LF+BG
+) }"g0CcE
+Ч }g?i{4 Z76C 0b S.0Y0XjGiʙ`2$C5%^s=j# \7c C1 ݏ7< &dL8f>0Ozʣ)LPקZFw?a ~NTKx6Ĭ# ᯋUEvi[1؀mQ]/8}&?Kh
+endstream
+endobj
+283 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /RWHMBC+LMMathItalic7-Regular
-/FontDescriptor 517 0 R
+/BaseFont /HIFJJL+LMMathItalic7-Regular
+/FontDescriptor 611 0 R
/FirstChar 11
/LastChar 121
-/Widths 484 0 R
-/Encoding 470 0 R
+/Widths 580 0 R
+/Encoding 561 0 R
+/ToUnicode 671 0 R
>>
endobj
-188 0 obj
+672 0 obj
+<<
+/Length 598
+/Filter /FlateDecode
+>>
+stream
+xmTM@+z&?DƉ1LF+BG
+ٔB15*f€H֊zAl@e R3TE`̇G=O3~6"i0'DoR3l3`\aʳ`LԎҔ3!>teHkK1z\7FunƤAN4cAox*Mc7p|aGSYOF~4J2P-m-YYG_v_ҶnchiEe+ G>|_pLKr
+endstream
+endobj
+210 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /DWKZXN+LMMathItalic9-Regular
-/FontDescriptor 519 0 R
+/FontDescriptor 613 0 R
/FirstChar 14
/LastChar 120
-/Widths 495 0 R
-/Encoding 470 0 R
+/Widths 589 0 R
+/Encoding 561 0 R
+/ToUnicode 672 0 R
>>
endobj
-261 0 obj
+673 0 obj
+<<
+/Length 790
+/Filter /FlateDecode
+>>
+stream
+xuUMo0Wx B
+HJ+ML ~fVyyfln~=&iټwͥ-d{nn|?z_r|=)vm.uq~T_U%AqNdGwH_d?(DwZ?~^JM]6EU]+Ң~xŻkӶ>4b!/e׷WyMҷU.n /waDh?vz[є; w-\E/#_iKvr'ht1 b 6aA8iHAxx*%) BSDjn@P˄AȘʠ0a8F
+
+8An)  +4bX*^cH`&f P;6 <9Bi2)LeTV.>HEW0*50^ s غ~${S$2ˀQ lC]j{Q\8jFجA`Z1Fcf1ur=#1SƤx- 907O`aaeVrLӔhVje y Q( a0<x?hkSIc/ -ur^vҁ7#!}BzUaQRZa~JÃy1KNqHC4cmӹy 7]t"jy3Vч.OOy/
+endstream
+endobj
+286 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /HLUHEK+LMMathSymbols10-Regular
-/FontDescriptor 541 0 R
+/BaseFont /CCXVUN+LMMathSymbols10-Regular
+/FontDescriptor 635 0 R
/FirstChar 0
/LastChar 114
-/Widths 482 0 R
-/Encoding 472 0 R
+/Widths 577 0 R
+/Encoding 569 0 R
+/ToUnicode 673 0 R
>>
endobj
-278 0 obj
+674 0 obj
+<<
+/Length 789
+/Filter /FlateDecode
+>>
+stream
+xmUMo0Wx B
+HJ+ML ~fTq zyyy_IZ6~bx]si ?Yޟ).'_ޗvOmzmm]/UE+Y%#]WwH߫T"+hvUS? ( Ħ. ;FLG.HiQVE?ѳ8`MX[\>DӗmU·|>z2Z.E!d6E׳;+w}}飅Ke7-ya΂VCyJ 3 "ac9Ċh2^؀ȉp 4%@d%L8
+c2h@B#E!%0f9K 6absns\ dqVK-dJM]FUkXkZT|Rs0`KkG7Ir! =9ۥ氇ŵfx@Kn
+cњ1jS'g3>eL›0s+ (`ʫ[k%W4MɊf%aLqVƐ(%yR Kg
+c&a8%|4r|Z,uo8i9/Hy3'Z؋
+*58nq4<xׁ+1ȑkI1F_܆1N
+endstream
+endobj
+301 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /VCFYYS+LMMathSymbols5-Regular
-/FontDescriptor 543 0 R
+/FontDescriptor 637 0 R
/FirstChar 3
/LastChar 3
-/Widths 477 0 R
-/Encoding 472 0 R
+/Widths 573 0 R
+/Encoding 569 0 R
+/ToUnicode 674 0 R
>>
endobj
-324 0 obj
+675 0 obj
+<<
+/Length 788
+/Filter /FlateDecode
+>>
+stream
+xmUMo0Wx B
+HJ+ML ~fTq zyyy_IZ6~bx]si ?Yޟ).'_ޗvOmzmm]/UE+Y%#]]xNNN$U XozRbS愝ttp#CU`I|`(YBIxwzև&Z,-|J.K[?or>=|-2ybz{ߢ MMBʥX2u㛖0jgA+<YF VH1 HD
+bK4S/IAl@D8 VsX&GTA 1RU rKpHHXâV؜F‡01z99.8|tHHa2ݦ.z,wohE*rQ gpL|N[֥#ٛB$YjdʜRsC XQ3f <g
+%7[Պ1hk5{3I2&}kMoρy
+ k c0-õ+`dE08T+cH{fx<E)nx%Sijg1@^c>H{Ixgl_>c o:ķCĴ sb sjL7
+V\Yr<Wt
+݌@zȏ/nØEX'&7nۭmZ YUܜ~tex{ɣ]
+endstream
+endobj
+303 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /QJIIYD+LMMathSymbols7-Regular
-/FontDescriptor 545 0 R
+/BaseFont /PVOJED+LMMathSymbols7-Regular
+/FontDescriptor 639 0 R
/FirstChar 0
/LastChar 114
-/Widths 473 0 R
-/Encoding 472 0 R
+/Widths 570 0 R
+/Encoding 569 0 R
+/ToUnicode 675 0 R
>>
endobj
-279 0 obj
+676 0 obj
+<<
+/Length 963
+/Filter /FlateDecode
+>>
+stream
+xmVn0+C,* ȡ4Aѫ#1X6dhu9R˙$ۅa~G8͗!jy0^?~ 'uܴ71o< }R+k1O?F?hﶧzz3gYOZ8Mc1Y{N,=&ƪq;dD.F)n}RUj#<gR1Y~0oGuF[w{>t(j ef}/CPƆ 1!̛1$kU: I-"W;>['M#9&tq7Ӛ'\H38rqi"*phH(ѣ,0z4dTq8Zێ&"N%t(PsI%=D FftZB~kuly"uʸ^13 "tΘqXc'g0n^pqqϐ"rqÐ̅>Ct&5j8C4{`ǵ)y'[!o&þz⳧8s,0u
+姥.w==8)LI9z2yҐIƜ cА =s|h(Z`~>뤽t~g#OgK֭Yq1匩g8$Qfs^!g0>1g %ϰn3KOI3)YN?g9Yg%,Δ3Z֙R-4UJ%gx3>I^r&䌵gKXKKđK%g3{yəK%g%g[Kג3 =L3ג3%g}yGZ6h-C S#ܚ_* jp@L[06e~יkh +ӗo8s<ĥgv
+/a@]t_[A"B
+endstream
+endobj
+302 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /KTPDFA+LMRoman10-Bold
-/FontDescriptor 505 0 R
+/BaseFont /JFISNR+LMRoman10-Bold
+/FontDescriptor 599 0 R
/FirstChar 113
/LastChar 120
-/Widths 476 0 R
-/Encoding 475 0 R
+/Widths 572 0 R
+/Encoding 571 0 R
+/ToUnicode 676 0 R
>>
endobj
-246 0 obj
+677 0 obj
+<<
+/Length 962
+/Filter /FlateDecode
+>>
+stream
+xmVn8+
+h ɨ%X8Zێ
+'U[:th鹥CK["OntZB~kul:e\ow:gLsJԋ84sy3ݾ_7~_9x<xe. 0y!Vz) ou/ Ϟṯֵ*跖` )<3'jIC&s2pBCֳ/5h~s
+I{8g 0F2|2F0Ƴ(gĉ1q#9~IȣAήa}t-c/9c]:K֟aݒggSzY%/sKY)YgJ3^i૔K%g|Lkyπ#9ûK%gx3r3͗KYKX%gkzjəz%gx%gK',S/9GZ6h-C S#ܚ_* jp@L[06e~_g!}/\XN8Jν,HN:q).~~:
+endstream
+endobj
+285 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /IYARYO+LMRoman10-Regular
-/FontDescriptor 521 0 R
+/BaseFont /ZDORWX+LMRoman10-Regular
+/FontDescriptor 615 0 R
/FirstChar 0
/LastChar 115
-/Widths 485 0 R
-/Encoding 475 0 R
+/Widths 578 0 R
+/Encoding 571 0 R
+/ToUnicode 677 0 R
>>
endobj
-273 0 obj
+678 0 obj
+<<
+/Length 962
+/Filter /FlateDecode
+>>
+stream
+xmVn8+
+endstream
+endobj
+291 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /PSSDWM+LMRoman5-Regular
-/FontDescriptor 527 0 R
+/FontDescriptor 621 0 R
/FirstChar 48
/LastChar 50
-/Widths 478 0 R
-/Encoding 475 0 R
+/Widths 574 0 R
+/Encoding 571 0 R
+/ToUnicode 678 0 R
>>
endobj
-260 0 obj
+679 0 obj
+<<
+/Length 962
+/Filter /FlateDecode
+>>
+stream
+xmVn8+
+endstream
+endobj
+284 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /FPSNHG+LMRoman7-Regular
-/FontDescriptor 531 0 R
+/BaseFont /OGJSOL+LMRoman7-Regular
+/FontDescriptor 625 0 R
/FirstChar 2
/LastChar 61
-/Widths 483 0 R
-/Encoding 475 0 R
+/Widths 579 0 R
+/Encoding 571 0 R
+/ToUnicode 679 0 R
>>
endobj
-189 0 obj
+680 0 obj
+<<
+/Length 962
+/Filter /FlateDecode
+>>
+stream
+xmVn8+
+endstream
+endobj
+211 0 obj
<<
/Type /Font
/Subtype /Type1
-/BaseFont /AKVTMY+LMRoman9-Regular
-/FontDescriptor 535 0 R
+/BaseFont /ICLJJO+LMRoman9-Regular
+/FontDescriptor 629 0 R
/FirstChar 1
/LastChar 100
-/Widths 494 0 R
-/Encoding 475 0 R
+/Widths 588 0 R
+/Encoding 571 0 R
+/ToUnicode 680 0 R
>>
endobj
-196 0 obj
+681 0 obj
+<<
+/Length 700
+/Filter /FlateDecode
+>>
+stream
+xuTMo0+J!m0U !mTto4j{z<?xҺ{s^7tr]u>v|tv ںQf|6'op݅uM{}ugfci"Amƃ}>,%rtPRJ(:X'Ab~oںT7h uSӌ]Acq`sy̟M.n? D`އщ7+d~4Wj7vw VRŪ,ׁk/bxO0+,F )1<c8PÆ\ 6>!Pp #]QxQTv)#ZBYLt/X^r<1u%pr_d9٢PSi0@WQ_Uh֩h諵"qFM]RrCpt39Âж~j3Fezp888Q:1bc7~}Hq('bĄ>^m# &zd}4)`
+"H,4%!%AQ߄B[B~)ҙ́ _)M?DM;豬;kyoQnNRd\Ӎ;WA}
+zoZZgbT$Z|U
+endstream
+endobj
+310 0 obj
+<<
+/Type /Font
+/Subtype /Type1
+/BaseFont /ZDORWX+LMRoman10-Regular
+/FontDescriptor 615 0 R
+/FirstChar 136
+/LastChar 136
+/Widths 568 0 R
+/Encoding 567 0 R
+/ToUnicode 681 0 R
+>>
+endobj
+217 0 obj
<<
/Type /Pages
/Count 6
-/Parent 556 0 R
-/Kids [166 0 R 228 0 R 238 0 R 249 0 R 269 0 R 282 0 R]
+/Parent 682 0 R
+/Kids [186 0 R 252 0 R 263 0 R 279 0 R 296 0 R 307 0 R]
>>
endobj
-292 0 obj
+324 0 obj
<<
/Type /Pages
/Count 6
-/Parent 556 0 R
-/Kids [288 0 R 296 0 R 300 0 R 306 0 R 311 0 R 315 0 R]
+/Parent 682 0 R
+/Kids [319 0 R 326 0 R 334 0 R 339 0 R 346 0 R 350 0 R]
>>
endobj
-325 0 obj
+359 0 obj
<<
/Type /Pages
/Count 6
-/Parent 556 0 R
-/Kids [321 0 R 328 0 R 333 0 R 339 0 R 350 0 R 357 0 R]
+/Parent 682 0 R
+/Kids [356 0 R 362 0 R 366 0 R 372 0 R 376 0 R 383 0 R]
>>
endobj
-365 0 obj
+393 0 obj
<<
/Type /Pages
/Count 6
-/Parent 556 0 R
-/Kids [362 0 R 373 0 R 384 0 R 391 0 R 396 0 R 402 0 R]
+/Parent 682 0 R
+/Kids [388 0 R 395 0 R 405 0 R 412 0 R 416 0 R 422 0 R]
>>
endobj
-412 0 obj
+440 0 obj
<<
/Type /Pages
/Count 6
-/Parent 556 0 R
-/Kids [407 0 R 415 0 R 423 0 R 431 0 R 435 0 R 439 0 R]
+/Parent 682 0 R
+/Kids [434 0 R 443 0 R 449 0 R 455 0 R 460 0 R 465 0 R]
>>
endobj
-456 0 obj
+475 0 obj
<<
/Type /Pages
-/Count 2
-/Parent 556 0 R
-/Kids [444 0 R 458 0 R]
+/Count 6
+/Parent 682 0 R
+/Kids [471 0 R 478 0 R 486 0 R 493 0 R 497 0 R 501 0 R]
>>
endobj
-556 0 obj
+509 0 obj
<<
/Type /Pages
-/Count 32
-/Kids [196 0 R 292 0 R 325 0 R 365 0 R 412 0 R 456 0 R]
+/Count 4
+/Parent 683 0 R
+/Kids [506 0 R 514 0 R 529 0 R 552 0 R]
>>
endobj
-557 0 obj
+682 0 obj
+<<
+/Type /Pages
+/Count 36
+/Parent 684 0 R
+/Kids [217 0 R 324 0 R 359 0 R 393 0 R 440 0 R 475 0 R]
+>>
+endobj
+683 0 obj
+<<
+/Type /Pages
+/Count 4
+/Parent 684 0 R
+/Kids [509 0 R]
+>>
+endobj
+684 0 obj
+<<
+/Type /Pages
+/Count 40
+/Kids [682 0 R 683 0 R]
+>>
+endobj
+685 0 obj
<<
/Type /Outlines
/First 3 0 R
-/Last 163 0 R
-/Count 27
+/Last 183 0 R
+/Count 29
+>>
+endobj
+183 0 obj
+<<
+/Title 184 0 R
+/A 181 0 R
+/Parent 685 0 R
+/Prev 179 0 R
+>>
+endobj
+179 0 obj
+<<
+/Title 180 0 R
+/A 177 0 R
+/Parent 685 0 R
+/Prev 171 0 R
+/Next 183 0 R
+>>
+endobj
+175 0 obj
+<<
+/Title 176 0 R
+/A 173 0 R
+/Parent 171 0 R
+>>
+endobj
+171 0 obj
+<<
+/Title 172 0 R
+/A 169 0 R
+/Parent 685 0 R
+/Prev 155 0 R
+/Next 179 0 R
+/First 175 0 R
+/Last 175 0 R
+/Count 1
+>>
+endobj
+167 0 obj
+<<
+/Title 168 0 R
+/A 165 0 R
+/Parent 159 0 R
+/Prev 163 0 R
>>
endobj
163 0 obj
<<
/Title 164 0 R
/A 161 0 R
-/Parent 557 0 R
-/Prev 155 0 R
+/Parent 159 0 R
+/Next 167 0 R
>>
endobj
159 0 obj
@@ -5862,15 +6967,18 @@ endobj
/Title 160 0 R
/A 157 0 R
/Parent 155 0 R
+/First 163 0 R
+/Last 167 0 R
+/Count -2
>>
endobj
155 0 obj
<<
/Title 156 0 R
/A 153 0 R
-/Parent 557 0 R
-/Prev 143 0 R
-/Next 163 0 R
+/Parent 685 0 R
+/Prev 107 0 R
+/Next 171 0 R
/First 159 0 R
/Last 159 0 R
/Count 1
@@ -5880,7 +6988,8 @@ endobj
<<
/Title 152 0 R
/A 149 0 R
-/Parent 147 0 R
+/Parent 143 0 R
+/Prev 147 0 R
>>
endobj
147 0 obj
@@ -5888,21 +6997,18 @@ endobj
/Title 148 0 R
/A 145 0 R
/Parent 143 0 R
-/First 151 0 R
-/Last 151 0 R
-/Count -1
+/Next 151 0 R
>>
endobj
143 0 obj
<<
/Title 144 0 R
/A 141 0 R
-/Parent 557 0 R
-/Prev 99 0 R
-/Next 155 0 R
+/Parent 107 0 R
+/Prev 131 0 R
/First 147 0 R
-/Last 147 0 R
-/Count 1
+/Last 151 0 R
+/Count -2
>>
endobj
139 0 obj
@@ -5925,8 +7031,9 @@ endobj
<<
/Title 132 0 R
/A 129 0 R
-/Parent 99 0 R
-/Prev 119 0 R
+/Parent 107 0 R
+/Prev 123 0 R
+/Next 143 0 R
/First 135 0 R
/Last 139 0 R
/Count -2
@@ -5936,35 +7043,35 @@ endobj
<<
/Title 128 0 R
/A 125 0 R
-/Parent 119 0 R
-/Prev 123 0 R
+/Parent 123 0 R
>>
endobj
123 0 obj
<<
/Title 124 0 R
/A 121 0 R
-/Parent 119 0 R
-/Next 127 0 R
+/Parent 107 0 R
+/Prev 119 0 R
+/Next 131 0 R
+/First 127 0 R
+/Last 127 0 R
+/Count -1
>>
endobj
119 0 obj
<<
/Title 120 0 R
/A 117 0 R
-/Parent 99 0 R
+/Parent 107 0 R
/Prev 115 0 R
-/Next 131 0 R
-/First 123 0 R
-/Last 127 0 R
-/Count -2
+/Next 123 0 R
>>
endobj
115 0 obj
<<
/Title 116 0 R
/A 113 0 R
-/Parent 99 0 R
+/Parent 107 0 R
/Prev 111 0 R
/Next 119 0 R
>>
@@ -5973,8 +7080,7 @@ endobj
<<
/Title 112 0 R
/A 109 0 R
-/Parent 99 0 R
-/Prev 107 0 R
+/Parent 107 0 R
/Next 115 0 R
>>
endobj
@@ -5982,36 +7088,36 @@ endobj
<<
/Title 108 0 R
/A 105 0 R
-/Parent 99 0 R
-/Prev 103 0 R
-/Next 111 0 R
+/Parent 685 0 R
+/Prev 51 0 R
+/Next 155 0 R
+/First 111 0 R
+/Last 143 0 R
+/Count 6
>>
endobj
103 0 obj
<<
/Title 104 0 R
/A 101 0 R
-/Parent 99 0 R
-/Next 107 0 R
+/Parent 51 0 R
+/Prev 99 0 R
>>
endobj
99 0 obj
<<
/Title 100 0 R
/A 97 0 R
-/Parent 557 0 R
-/Prev 43 0 R
-/Next 143 0 R
-/First 103 0 R
-/Last 131 0 R
-/Count 6
+/Parent 51 0 R
+/Prev 71 0 R
+/Next 103 0 R
>>
endobj
95 0 obj
<<
/Title 96 0 R
/A 93 0 R
-/Parent 43 0 R
+/Parent 71 0 R
/Prev 91 0 R
>>
endobj
@@ -6019,8 +7125,8 @@ endobj
<<
/Title 92 0 R
/A 89 0 R
-/Parent 43 0 R
-/Prev 63 0 R
+/Parent 71 0 R
+/Prev 87 0 R
/Next 95 0 R
>>
endobj
@@ -6028,15 +7134,16 @@ endobj
<<
/Title 88 0 R
/A 85 0 R
-/Parent 63 0 R
+/Parent 71 0 R
/Prev 83 0 R
+/Next 91 0 R
>>
endobj
83 0 obj
<<
/Title 84 0 R
/A 81 0 R
-/Parent 63 0 R
+/Parent 71 0 R
/Prev 79 0 R
/Next 87 0 R
>>
@@ -6045,7 +7152,7 @@ endobj
<<
/Title 80 0 R
/A 77 0 R
-/Parent 63 0 R
+/Parent 71 0 R
/Prev 75 0 R
/Next 83 0 R
>>
@@ -6054,8 +7161,7 @@ endobj
<<
/Title 76 0 R
/A 73 0 R
-/Parent 63 0 R
-/Prev 71 0 R
+/Parent 71 0 R
/Next 79 0 R
>>
endobj
@@ -6063,16 +7169,20 @@ endobj
<<
/Title 72 0 R
/A 69 0 R
-/Parent 63 0 R
+/Parent 51 0 R
/Prev 67 0 R
-/Next 75 0 R
+/Next 99 0 R
+/First 75 0 R
+/Last 95 0 R
+/Count -6
>>
endobj
67 0 obj
<<
/Title 68 0 R
/A 65 0 R
-/Parent 63 0 R
+/Parent 51 0 R
+/Prev 63 0 R
/Next 71 0 R
>>
endobj
@@ -6080,60 +7190,56 @@ endobj
<<
/Title 64 0 R
/A 61 0 R
-/Parent 43 0 R
-/Prev 59 0 R
-/Next 91 0 R
-/First 67 0 R
-/Last 87 0 R
-/Count -6
+/Parent 51 0 R
+/Prev 55 0 R
+/Next 67 0 R
>>
endobj
59 0 obj
<<
/Title 60 0 R
/A 57 0 R
-/Parent 43 0 R
-/Prev 55 0 R
-/Next 63 0 R
+/Parent 55 0 R
>>
endobj
55 0 obj
<<
/Title 56 0 R
/A 53 0 R
-/Parent 43 0 R
-/Prev 47 0 R
-/Next 59 0 R
+/Parent 51 0 R
+/Next 63 0 R
+/First 59 0 R
+/Last 59 0 R
+/Count -1
>>
endobj
51 0 obj
<<
/Title 52 0 R
/A 49 0 R
-/Parent 47 0 R
+/Parent 685 0 R
+/Prev 15 0 R
+/Next 107 0 R
+/First 55 0 R
+/Last 103 0 R
+/Count 6
>>
endobj
47 0 obj
<<
/Title 48 0 R
/A 45 0 R
-/Parent 43 0 R
-/Next 55 0 R
-/First 51 0 R
-/Last 51 0 R
-/Count -1
+/Parent 15 0 R
+/Prev 43 0 R
>>
endobj
43 0 obj
<<
/Title 44 0 R
/A 41 0 R
-/Parent 557 0 R
-/Prev 15 0 R
-/Next 99 0 R
-/First 47 0 R
-/Last 95 0 R
-/Count 6
+/Parent 15 0 R
+/Prev 35 0 R
+/Next 47 0 R
>>
endobj
39 0 obj
@@ -6149,6 +7255,7 @@ endobj
/A 33 0 R
/Parent 15 0 R
/Prev 31 0 R
+/Next 43 0 R
/First 39 0 R
/Last 39 0 R
/Count -1
@@ -6159,7 +7266,7 @@ endobj
/Title 32 0 R
/A 29 0 R
/Parent 15 0 R
-/Prev 23 0 R
+/Prev 19 0 R
/Next 35 0 R
>>
endobj
@@ -6167,19 +7274,16 @@ endobj
<<
/Title 28 0 R
/A 25 0 R
-/Parent 23 0 R
+/Parent 19 0 R
+/Prev 23 0 R
>>
endobj
23 0 obj
<<
/Title 24 0 R
/A 21 0 R
-/Parent 15 0 R
-/Prev 19 0 R
-/Next 31 0 R
-/First 27 0 R
-/Last 27 0 R
-/Count -1
+/Parent 19 0 R
+/Next 27 0 R
>>
endobj
19 0 obj
@@ -6187,26 +7291,29 @@ endobj
/Title 20 0 R
/A 17 0 R
/Parent 15 0 R
-/Next 23 0 R
+/Next 31 0 R
+/First 23 0 R
+/Last 27 0 R
+/Count -2
>>
endobj
15 0 obj
<<
/Title 16 0 R
/A 13 0 R
-/Parent 557 0 R
+/Parent 685 0 R
/Prev 11 0 R
-/Next 43 0 R
+/Next 51 0 R
/First 19 0 R
-/Last 35 0 R
-/Count 4
+/Last 47 0 R
+/Count 5
>>
endobj
11 0 obj
<<
/Title 12 0 R
/A 9 0 R
-/Parent 557 0 R
+/Parent 685 0 R
/Prev 3 0 R
/Next 15 0 R
>>
@@ -6222,788 +7329,958 @@ endobj
<<
/Title 4 0 R
/A 1 0 R
-/Parent 557 0 R
+/Parent 685 0 R
/Next 11 0 R
/First 7 0 R
/Last 7 0 R
/Count 1
>>
endobj
-558 0 obj
+686 0 obj
<<
-/Names [(Doc-Start) 181 0 R (Hfootnote.1) 265 0 R (Hfootnote.2) 353 0 R (Hfootnote.3) 377 0 R (Hfootnote.4) 394 0 R (Hfootnote.5) 411 0 R]
-/Limits [(Doc-Start) (Hfootnote.5)]
+/Names [(Doc-Start) 203 0 R (Hfootnote.1) 312 0 R (Hfootnote.10) 525 0 R (Hfootnote.2) 322 0 R (Hfootnote.3) 337 0 R (Hfootnote.4) 408 0 R]
+/Limits [(Doc-Start) (Hfootnote.4)]
>>
endobj
-559 0 obj
+687 0 obj
<<
-/Names [(Hfootnote.6) 419 0 R (Hfootnote.7) 427 0 R (Hfootnote.8) 428 0 R (Item.1) 241 0 R (Item.10) 448 0 R (Item.11) 449 0 R]
-/Limits [(Hfootnote.6) (Item.11)]
+/Names [(Hfootnote.5) 439 0 R (Hfootnote.6) 458 0 R (Hfootnote.7) 481 0 R (Hfootnote.8) 490 0 R (Hfootnote.9) 491 0 R (Item.1) 269 0 R]
+/Limits [(Hfootnote.5) (Item.1)]
>>
endobj
-560 0 obj
+688 0 obj
<<
-/Names [(Item.12) 450 0 R (Item.13) 451 0 R (Item.14) 452 0 R (Item.15) 453 0 R (Item.16) 454 0 R (Item.17) 455 0 R]
-/Limits [(Item.12) (Item.17)]
+/Names [(Item.10) 519 0 R (Item.11) 520 0 R (Item.12) 521 0 R (Item.13) 522 0 R (Item.14) 523 0 R (Item.15) 524 0 R]
+/Limits [(Item.10) (Item.15)]
>>
endobj
-561 0 obj
+689 0 obj
<<
-/Names [(Item.18) 461 0 R (Item.19) 462 0 R (Item.2) 242 0 R (Item.20) 463 0 R (Item.21) 464 0 R (Item.22) 465 0 R]
-/Limits [(Item.18) (Item.22)]
+/Names [(Item.16) 532 0 R (Item.17) 533 0 R (Item.18) 534 0 R (Item.19) 535 0 R (Item.2) 270 0 R (Item.20) 536 0 R]
+/Limits [(Item.16) (Item.20)]
>>
endobj
-562 0 obj
+690 0 obj
<<
-/Names [(Item.3) 244 0 R (Item.4) 252 0 R (Item.5) 253 0 R (Item.6) 254 0 R (Item.7) 255 0 R (Item.8) 256 0 R]
-/Limits [(Item.3) (Item.8)]
+/Names [(Item.21) 537 0 R (Item.22) 538 0 R (Item.23) 539 0 R (Item.24) 540 0 R (Item.25) 541 0 R (Item.26) 542 0 R]
+/Limits [(Item.21) (Item.26)]
>>
endobj
-563 0 obj
+691 0 obj
<<
-/Names [(Item.9) 447 0 R (equation.2.1) 258 0 R (equation.2.2) 262 0 R (equation.2.3) 264 0 R (equation.2.4) 272 0 R (equation.2.5) 274 0 R]
-/Limits [(Item.9) (equation.2.5)]
+/Names [(Item.27) 543 0 R (Item.28) 544 0 R (Item.29) 545 0 R (Item.3) 272 0 R (Item.30) 546 0 R (Item.31) 547 0 R]
+/Limits [(Item.27) (Item.31)]
>>
endobj
-564 0 obj
+692 0 obj
<<
-/Names [(equation.2.6) 275 0 R (equation.2.7) 276 0 R (equation.2.8) 277 0 R (page.1) 180 0 R (page.10) 308 0 R (page.11) 313 0 R]
-/Limits [(equation.2.6) (page.11)]
+/Names [(Item.32) 548 0 R (Item.33) 549 0 R (Item.34) 550 0 R (Item.35) 555 0 R (Item.36) 556 0 R (Item.37) 557 0 R]
+/Limits [(Item.32) (Item.37)]
>>
endobj
-565 0 obj
+693 0 obj
<<
-/Names [(page.12) 317 0 R (page.13) 323 0 R (page.14) 330 0 R (page.15) 335 0 R (page.16) 341 0 R (page.17) 352 0 R]
-/Limits [(page.12) (page.17)]
+/Names [(Item.4) 273 0 R (Item.5) 274 0 R (Item.6) 275 0 R (Item.7) 276 0 R (Item.8) 517 0 R (Item.9) 518 0 R]
+/Limits [(Item.4) (Item.9)]
>>
endobj
-566 0 obj
+694 0 obj
<<
-/Names [(page.18) 359 0 R (page.19) 364 0 R (page.2) 230 0 R (page.20) 375 0 R (page.21) 386 0 R (page.22) 393 0 R]
-/Limits [(page.18) (page.22)]
+/Names [(equation.2.1) 282 0 R (equation.2.2) 287 0 R (equation.2.3) 289 0 R (equation.2.4) 290 0 R (equation.2.5) 292 0 R (equation.2.6) 293 0 R]
+/Limits [(equation.2.1) (equation.2.6)]
>>
endobj
-567 0 obj
+695 0 obj
<<
-/Names [(page.23) 398 0 R (page.24) 404 0 R (page.25) 409 0 R (page.26) 417 0 R (page.27) 425 0 R (page.28) 433 0 R]
-/Limits [(page.23) (page.28)]
+/Names [(equation.2.7) 299 0 R (equation.2.8) 300 0 R (page.1) 202 0 R (page.10) 341 0 R (page.11) 348 0 R (page.12) 352 0 R]
+/Limits [(equation.2.7) (page.12)]
>>
endobj
-568 0 obj
+696 0 obj
<<
-/Names [(page.29) 437 0 R (page.3) 240 0 R (page.30) 441 0 R (page.31) 446 0 R (page.32) 460 0 R (page.4) 251 0 R]
-/Limits [(page.29) (page.4)]
+/Names [(page.13) 358 0 R (page.14) 364 0 R (page.15) 368 0 R (page.16) 374 0 R (page.17) 378 0 R (page.18) 385 0 R]
+/Limits [(page.13) (page.18)]
>>
endobj
-569 0 obj
+697 0 obj
<<
-/Names [(page.5) 271 0 R (page.6) 284 0 R (page.7) 290 0 R (page.8) 298 0 R (page.9) 302 0 R (section*.1) 191 0 R]
-/Limits [(page.5) (section*.1)]
+/Names [(page.19) 390 0 R (page.2) 254 0 R (page.20) 397 0 R (page.21) 407 0 R (page.22) 414 0 R (page.23) 418 0 R]
+/Limits [(page.19) (page.23)]
>>
endobj
-570 0 obj
+698 0 obj
<<
-/Names [(section*.2) 257 0 R (section*.3) 336 0 R (section*.4) 337 0 R (section*.5) 342 0 R (section*.6) 343 0 R (section*.7) 344 0 R]
-/Limits [(section*.2) (section*.7)]
+/Names [(page.24) 424 0 R (page.25) 436 0 R (page.26) 445 0 R (page.27) 451 0 R (page.28) 457 0 R (page.29) 462 0 R]
+/Limits [(page.24) (page.29)]
>>
endobj
-571 0 obj
+699 0 obj
<<
-/Names [(section*.8) 410 0 R (section.1) 2 0 R (section.2) 10 0 R (section.3) 14 0 R (section.4) 42 0 R (section.5) 98 0 R]
-/Limits [(section*.8) (section.5)]
+/Names [(page.3) 265 0 R (page.30) 467 0 R (page.31) 473 0 R (page.32) 480 0 R (page.33) 488 0 R (page.34) 495 0 R]
+/Limits [(page.3) (page.34)]
>>
endobj
-572 0 obj
+700 0 obj
<<
-/Names [(section.6) 142 0 R (section.7) 154 0 R (section.8) 162 0 R (subsection.1.1) 6 0 R (subsection.3.1) 18 0 R (subsection.3.2) 22 0 R]
-/Limits [(section.6) (subsection.3.2)]
+/Names [(page.35) 499 0 R (page.36) 503 0 R (page.37) 508 0 R (page.38) 516 0 R (page.39) 531 0 R (page.4) 281 0 R]
+/Limits [(page.35) (page.4)]
>>
endobj
-573 0 obj
+701 0 obj
<<
-/Names [(subsection.3.3) 30 0 R (subsection.3.4) 34 0 R (subsection.4.1) 46 0 R (subsection.4.2) 54 0 R (subsection.4.3) 58 0 R (subsection.4.4) 62 0 R]
-/Limits [(subsection.3.3) (subsection.4.4)]
+/Names [(page.40) 554 0 R (page.5) 298 0 R (page.6) 309 0 R (page.7) 321 0 R (page.8) 328 0 R (page.9) 336 0 R]
+/Limits [(page.40) (page.9)]
>>
endobj
-574 0 obj
+702 0 obj
<<
-/Names [(subsection.4.5) 90 0 R (subsection.4.6) 94 0 R (subsection.5.1) 102 0 R (subsection.5.2) 106 0 R (subsection.5.3) 110 0 R (subsection.5.4) 114 0 R]
-/Limits [(subsection.4.5) (subsection.5.4)]
+/Names [(section*.1) 212 0 R (section*.10) 468 0 R (section*.2) 266 0 R (section*.3) 268 0 R (section*.4) 386 0 R (section*.5) 391 0 R]
+/Limits [(section*.1) (section*.5)]
>>
endobj
-575 0 obj
+703 0 obj
<<
-/Names [(subsection.5.5) 118 0 R (subsection.5.6) 130 0 R (subsection.6.1) 146 0 R (subsection.7.1) 158 0 R (subsubsection.3.2.1) 26 0 R (subsubsection.3.4.1) 38 0 R]
-/Limits [(subsection.5.5) (subsubsection.3.4.1)]
+/Names [(section*.6) 392 0 R (section*.7) 398 0 R (section*.8) 399 0 R (section*.9) 452 0 R (section.1) 2 0 R (section.2) 10 0 R]
+/Limits [(section*.6) (section.2)]
>>
endobj
-576 0 obj
+704 0 obj
+<<
+/Names [(section.3) 14 0 R (section.4) 50 0 R (section.5) 106 0 R (section.6) 154 0 R (section.7) 170 0 R (section.8) 178 0 R]
+/Limits [(section.3) (section.8)]
+>>
+endobj
+705 0 obj
<<
-/Names [(subsubsection.4.1.1) 50 0 R (subsubsection.4.4.1) 66 0 R (subsubsection.4.4.2) 70 0 R (subsubsection.4.4.3) 74 0 R (subsubsection.4.4.4) 78 0 R (subsubsection.4.4.5) 82 0 R]
+/Names [(section.9) 182 0 R (subsection.1.1) 6 0 R (subsection.3.1) 18 0 R (subsection.3.2) 30 0 R (subsection.3.3) 34 0 R (subsection.3.4) 42 0 R]
+/Limits [(section.9) (subsection.3.4)]
+>>
+endobj
+706 0 obj
+<<
+/Names [(subsection.3.5) 46 0 R (subsection.4.1) 54 0 R (subsection.4.2) 62 0 R (subsection.4.3) 66 0 R (subsection.4.4) 70 0 R (subsection.4.5) 98 0 R]
+/Limits [(subsection.3.5) (subsection.4.5)]
+>>
+endobj
+707 0 obj
+<<
+/Names [(subsection.4.6) 102 0 R (subsection.5.1) 110 0 R (subsection.5.2) 114 0 R (subsection.5.3) 118 0 R (subsection.5.4) 122 0 R (subsection.5.5) 130 0 R]
+/Limits [(subsection.4.6) (subsection.5.5)]
+>>
+endobj
+708 0 obj
+<<
+/Names [(subsection.5.6) 142 0 R (subsection.6.1) 158 0 R (subsection.7.1) 174 0 R (subsubsection.3.1.1) 22 0 R (subsubsection.3.1.2) 26 0 R (subsubsection.3.3.1) 38 0 R]
+/Limits [(subsection.5.6) (subsubsection.3.3.1)]
+>>
+endobj
+709 0 obj
+<<
+/Names [(subsubsection.4.1.1) 58 0 R (subsubsection.4.4.1) 74 0 R (subsubsection.4.4.2) 78 0 R (subsubsection.4.4.3) 82 0 R (subsubsection.4.4.4) 86 0 R (subsubsection.4.4.5) 90 0 R]
/Limits [(subsubsection.4.1.1) (subsubsection.4.4.5)]
>>
endobj
-577 0 obj
+710 0 obj
<<
-/Names [(subsubsection.4.4.6) 86 0 R (subsubsection.5.5.1) 122 0 R (subsubsection.5.5.2) 126 0 R (subsubsection.5.6.1) 134 0 R (subsubsection.5.6.2) 138 0 R (subsubsection.6.1.1) 150 0 R]
-/Limits [(subsubsection.4.4.6) (subsubsection.6.1.1)]
+/Names [(subsubsection.4.4.6) 94 0 R (subsubsection.5.4.1) 126 0 R (subsubsection.5.5.1) 134 0 R (subsubsection.5.5.2) 138 0 R (subsubsection.5.6.1) 146 0 R (subsubsection.5.6.2) 150 0 R]
+/Limits [(subsubsection.4.4.6) (subsubsection.5.6.2)]
>>
endobj
-578 0 obj
+711 0 obj
<<
-/Names [(table.1) 354 0 R (table.2) 376 0 R (table.3) 387 0 R]
-/Limits [(table.1) (table.3)]
+/Names [(subsubsection.6.1.1) 162 0 R (subsubsection.6.1.2) 166 0 R (table.1) 409 0 R (table.2) 437 0 R (table.3) 438 0 R (table.4) 446 0 R]
+/Limits [(subsubsection.6.1.1) (table.4)]
>>
endobj
-579 0 obj
+712 0 obj
<<
-/Kids [558 0 R 559 0 R 560 0 R 561 0 R 562 0 R 563 0 R]
-/Limits [(Doc-Start) (equation.2.5)]
+/Kids [686 0 R 687 0 R 688 0 R 689 0 R 690 0 R 691 0 R]
+/Limits [(Doc-Start) (Item.31)]
>>
endobj
-580 0 obj
+713 0 obj
<<
-/Kids [564 0 R 565 0 R 566 0 R 567 0 R 568 0 R 569 0 R]
-/Limits [(equation.2.6) (section*.1)]
+/Kids [692 0 R 693 0 R 694 0 R 695 0 R 696 0 R 697 0 R]
+/Limits [(Item.32) (page.23)]
>>
endobj
-581 0 obj
+714 0 obj
<<
-/Kids [570 0 R 571 0 R 572 0 R 573 0 R 574 0 R 575 0 R]
-/Limits [(section*.2) (subsubsection.3.4.1)]
+/Kids [698 0 R 699 0 R 700 0 R 701 0 R 702 0 R 703 0 R]
+/Limits [(page.24) (section.2)]
>>
endobj
-582 0 obj
+715 0 obj
<<
-/Kids [576 0 R 577 0 R 578 0 R]
-/Limits [(subsubsection.4.1.1) (table.3)]
+/Kids [704 0 R 705 0 R 706 0 R 707 0 R 708 0 R 709 0 R]
+/Limits [(section.3) (subsubsection.4.4.5)]
>>
endobj
-583 0 obj
+716 0 obj
<<
-/Kids [579 0 R 580 0 R 581 0 R 582 0 R]
-/Limits [(Doc-Start) (table.3)]
+/Kids [710 0 R 711 0 R]
+/Limits [(subsubsection.4.4.6) (table.4)]
>>
endobj
-584 0 obj
+717 0 obj
<<
-/Dests 583 0 R
+/Kids [712 0 R 713 0 R 714 0 R 715 0 R 716 0 R]
+/Limits [(Doc-Start) (table.4)]
>>
endobj
-585 0 obj
+718 0 obj
+<<
+/Dests 717 0 R
+>>
+endobj
+719 0 obj
<<
/Type /Catalog
-/Pages 556 0 R
-/Outlines 557 0 R
-/Names 584 0 R
+/Pages 684 0 R
+/Outlines 685 0 R
+/Names 718 0 R
/PageMode/FullScreen
-/OpenAction 165 0 R
+/OpenAction 185 0 R
>>
endobj
-586 0 obj
+720 0 obj
<<
-/Producer (MiKTeX pdfTeX-1.40.20)
-/Author(\376\377\000A\000n\000d\000r\000e\000w\000\040\000P\000a\000r\000s\000l\000o\000e\000,\000\040\000\050\000a\000j\000p\000a\000r\000s\000l\000o\000e\000@\000g\000m\000a\000i\000l\000.\000c\000o\000m\000\051)/Title(\376\377\000d\000i\000f\000f\000c\000o\000e\000f\000f\000\040\000\040\000a\000\040\000L\000a\000T\000e\000X\000\040\000p\000a\000c\000k\000a\000g\000e\000\040\000t\000o\000\040\000e\000a\000s\000e\000\040\000t\000h\000e\000\040\000\040\000w\000r\000i\000t\000i\000n\000g\000\040\000o\000f\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000l\000\040\000c\000o\000e\000f\000f\000i\000c\000i\000e\000n\000t\000s\000\040\000\040\000i\000n\000\040\000a\000l\000l\000\040\000t\000h\000e\000i\000r\000\040\000v\000a\000r\000i\000e\000t\000y\000\040\000V\000e\000r\000s\000i\000o\000n\000\040\0003\000.\0002)/Subject()/Creator(LaTeX with hyperref)/Keywords()
-/CreationDate (D:20191228091648+13'00')
-/ModDate (D:20191228091648+13'00')
+/Producer (MiKTeX pdfTeX-1.40.24)
+/Author(\376\377\000A\000n\000d\000r\000e\000w\000\040\000P\000a\000r\000s\000l\000o\000e\000,\000\040\000\050\000a\000j\000p\000a\000r\000s\000l\000o\000e\000@\000g\000m\000a\000i\000l\000.\000c\000o\000m\000\051)/Title(\376\377\000d\000i\000f\000f\000c\000o\000e\000f\000f\000\040\000\040\000a\000\040\000L\000a\000T\000e\000X\000\040\000p\000a\000c\000k\000a\000g\000e\000\040\000t\000o\000\040\000e\000a\000s\000e\000\040\000t\000h\000e\000\040\000\040\000w\000r\000i\000t\000i\000n\000g\000\040\000o\000f\000\040\000d\000i\000f\000f\000e\000r\000e\000n\000t\000i\000a\000l\000\040\000c\000o\000e\000f\000f\000i\000c\000i\000e\000n\000t\000s\000\040\000\040\000V\000e\000r\000s\000i\000o\000n\000\040\0004\000.\0000)/Subject()/Creator(LaTeX with hyperref)/Keywords()
+/CreationDate (D:20211228085626+13'00')
+/ModDate (D:20211228085626+13'00')
/Trapped /False
-/PTEX.Fullbanner (This is MiKTeX-pdfTeX 2.9.7029 (1.40.20))
+/PTEX.Fullbanner (This is MiKTeX-pdfTeX 4.10.0 (1.40.24))
>>
endobj
xref
-0 587
+0 721
0000000000 65535 f
0000000015 00000 n
-0000020338 00000 n
-0000654263 00000 n
+0000022268 00000 n
+0000710171 00000 n
0000000060 00000 n
0000000159 00000 n
-0000024028 00000 n
-0000654206 00000 n
+0000025790 00000 n
+0000710114 00000 n
0000000209 00000 n
-0000000351 00000 n
-0000028310 00000 n
-0000654120 00000 n
-0000000396 00000 n
-0000000608 00000 n
-0000036009 00000 n
-0000653996 00000 n
-0000000654 00000 n
-0000000805 00000 n
-0000036070 00000 n
-0000653922 00000 n
-0000000856 00000 n
-0000001032 00000 n
-0000036131 00000 n
-0000653798 00000 n
-0000001083 00000 n
-0000001362 00000 n
-0000039640 00000 n
-0000653737 00000 n
-0000001418 00000 n
-0000001579 00000 n
-0000042990 00000 n
-0000653650 00000 n
-0000001630 00000 n
-0000001867 00000 n
-0000043051 00000 n
-0000653539 00000 n
-0000001918 00000 n
-0000002069 00000 n
-0000046491 00000 n
-0000653478 00000 n
-0000002125 00000 n
-0000002245 00000 n
-0000046552 00000 n
-0000653354 00000 n
-0000002291 00000 n
-0000002429 00000 n
-0000049763 00000 n
-0000653243 00000 n
-0000002480 00000 n
-0000002651 00000 n
-0000049824 00000 n
-0000653182 00000 n
-0000002707 00000 n
-0000002880 00000 n
-0000053676 00000 n
-0000653095 00000 n
-0000002931 00000 n
-0000003122 00000 n
-0000053737 00000 n
-0000653008 00000 n
-0000003173 00000 n
-0000003326 00000 n
-0000056975 00000 n
-0000652884 00000 n
-0000003377 00000 n
-0000003558 00000 n
-0000057036 00000 n
-0000652810 00000 n
-0000003614 00000 n
-0000003824 00000 n
-0000060432 00000 n
-0000652723 00000 n
-0000003880 00000 n
-0000004124 00000 n
-0000060493 00000 n
-0000652636 00000 n
-0000004180 00000 n
-0000004313 00000 n
-0000063938 00000 n
-0000652549 00000 n
-0000004369 00000 n
-0000004560 00000 n
-0000063999 00000 n
-0000652462 00000 n
-0000004616 00000 n
-0000004901 00000 n
-0000067859 00000 n
-0000652388 00000 n
-0000004957 00000 n
-0000005110 00000 n
-0000071625 00000 n
-0000652301 00000 n
-0000005161 00000 n
-0000005440 00000 n
-0000075550 00000 n
-0000652227 00000 n
-0000005491 00000 n
-0000005586 00000 n
-0000075611 00000 n
-0000652099 00000 n
-0000005632 00000 n
-0000005842 00000 n
-0000075672 00000 n
-0000652021 00000 n
-0000005894 00000 n
-0000006134 00000 n
-0000087018 00000 n
-0000651929 00000 n
-0000006186 00000 n
-0000006300 00000 n
-0000090962 00000 n
-0000651837 00000 n
-0000006352 00000 n
-0000006501 00000 n
-0000091086 00000 n
-0000651745 00000 n
-0000006553 00000 n
-0000006794 00000 n
-0000091148 00000 n
-0000651614 00000 n
-0000006846 00000 n
-0000006965 00000 n
-0000097530 00000 n
-0000651535 00000 n
-0000007022 00000 n
-0000007287 00000 n
-0000100468 00000 n
-0000651456 00000 n
-0000007344 00000 n
-0000007593 00000 n
-0000104012 00000 n
-0000651339 00000 n
-0000007645 00000 n
-0000007767 00000 n
-0000107447 00000 n
-0000651260 00000 n
-0000007824 00000 n
-0000008027 00000 n
-0000107509 00000 n
-0000651181 00000 n
-0000008084 00000 n
-0000008210 00000 n
-0000111406 00000 n
-0000651051 00000 n
-0000008257 00000 n
-0000008467 00000 n
-0000114928 00000 n
-0000650947 00000 n
-0000008519 00000 n
-0000008605 00000 n
-0000114990 00000 n
-0000650882 00000 n
-0000008662 00000 n
-0000008758 00000 n
-0000118184 00000 n
-0000650751 00000 n
-0000008805 00000 n
-0000008891 00000 n
-0000118246 00000 n
-0000650686 00000 n
-0000008943 00000 n
-0000009059 00000 n
-0000124629 00000 n
-0000650607 00000 n
-0000009106 00000 n
-0000009187 00000 n
-0000011069 00000 n
-0000011273 00000 n
-0000011425 00000 n
-0000011582 00000 n
-0000011734 00000 n
-0000011885 00000 n
-0000012042 00000 n
-0000012199 00000 n
-0000012360 00000 n
-0000012514 00000 n
-0000012670 00000 n
-0000015391 00000 n
-0000013015 00000 n
-0000009237 00000 n
-0000012830 00000 n
-0000012891 00000 n
-0000646828 00000 n
-0000645282 00000 n
-0000645109 00000 n
-0000645969 00000 n
-0000644767 00000 n
-0000647171 00000 n
-0000648197 00000 n
-0000649588 00000 n
-0000645455 00000 n
-0000012953 00000 n
-0000644597 00000 n
-0000644427 00000 n
-0000644936 00000 n
-0000646656 00000 n
-0000649759 00000 n
-0000015543 00000 n
-0000015700 00000 n
-0000015860 00000 n
-0000016017 00000 n
-0000016174 00000 n
-0000016331 00000 n
-0000016492 00000 n
-0000016653 00000 n
-0000016814 00000 n
-0000016975 00000 n
-0000017136 00000 n
-0000017297 00000 n
-0000017454 00000 n
-0000017611 00000 n
-0000017763 00000 n
-0000017920 00000 n
-0000018077 00000 n
-0000018233 00000 n
-0000018390 00000 n
-0000018547 00000 n
-0000018708 00000 n
-0000018869 00000 n
-0000019026 00000 n
-0000019187 00000 n
-0000019348 00000 n
-0000019500 00000 n
-0000019657 00000 n
-0000019817 00000 n
-0000019969 00000 n
-0000020126 00000 n
-0000020398 00000 n
-0000015019 00000 n
-0000013243 00000 n
-0000020277 00000 n
-0000645626 00000 n
-0000023339 00000 n
-0000023491 00000 n
-0000023648 00000 n
-0000023805 00000 n
-0000027569 00000 n
-0000024272 00000 n
-0000023183 00000 n
-0000020522 00000 n
-0000023967 00000 n
-0000024087 00000 n
-0000024149 00000 n
-0000646141 00000 n
-0000024210 00000 n
-0000647664 00000 n
-0000649075 00000 n
-0000027722 00000 n
-0000028618 00000 n
-0000027429 00000 n
-0000024422 00000 n
-0000027877 00000 n
-0000027938 00000 n
-0000028000 00000 n
-0000028062 00000 n
-0000028124 00000 n
-0000028186 00000 n
-0000028248 00000 n
-0000028371 00000 n
-0000648020 00000 n
-0000649418 00000 n
-0000648374 00000 n
-0000028433 00000 n
-0000647484 00000 n
-0000028495 00000 n
-0000028556 00000 n
-0000645797 00000 n
-0000032437 00000 n
-0000032959 00000 n
-0000032305 00000 n
-0000028859 00000 n
-0000032589 00000 n
-0000032650 00000 n
-0000649247 00000 n
-0000032712 00000 n
-0000032774 00000 n
-0000032836 00000 n
-0000032897 00000 n
-0000648552 00000 n
-0000648904 00000 n
-0000035798 00000 n
-0000036192 00000 n
-0000035666 00000 n
-0000033174 00000 n
-0000035948 00000 n
-0000039273 00000 n
-0000039428 00000 n
-0000039701 00000 n
-0000039133 00000 n
-0000036355 00000 n
-0000039579 00000 n
-0000646485 00000 n
-0000649876 00000 n
-0000042779 00000 n
-0000046279 00000 n
-0000043112 00000 n
-0000042647 00000 n
-0000039877 00000 n
-0000042929 00000 n
-0000046613 00000 n
-0000046147 00000 n
-0000043327 00000 n
-0000046430 00000 n
-0000049550 00000 n
-0000053301 00000 n
-0000049885 00000 n
-0000049418 00000 n
-0000046815 00000 n
-0000049702 00000 n
-0000053463 00000 n
-0000053798 00000 n
-0000053161 00000 n
-0000050087 00000 n
-0000053615 00000 n
-0000057096 00000 n
-0000056802 00000 n
-0000053987 00000 n
-0000056914 00000 n
-0000060058 00000 n
-0000060210 00000 n
-0000060554 00000 n
-0000059918 00000 n
-0000057272 00000 n
-0000060371 00000 n
-0000648727 00000 n
-0000649993 00000 n
-0000067420 00000 n
-0000064060 00000 n
-0000063765 00000 n
-0000060756 00000 n
-0000063877 00000 n
-0000067575 00000 n
-0000067982 00000 n
-0000067280 00000 n
-0000064249 00000 n
-0000067736 00000 n
-0000067797 00000 n
-0000067920 00000 n
-0000071686 00000 n
-0000071266 00000 n
-0000068184 00000 n
-0000071378 00000 n
-0000071439 00000 n
-0000071501 00000 n
-0000071563 00000 n
-0000074882 00000 n
-0000075034 00000 n
-0000075185 00000 n
-0000075335 00000 n
-0000075796 00000 n
-0000074726 00000 n
-0000071901 00000 n
-0000075489 00000 n
-0000075734 00000 n
-0000079449 00000 n
-0000079226 00000 n
-0000079510 00000 n
-0000079094 00000 n
-0000075998 00000 n
-0000079388 00000 n
-0000647842 00000 n
-0000082813 00000 n
-0000082640 00000 n
-0000079725 00000 n
-0000082752 00000 n
-0000650110 00000 n
-0000086044 00000 n
-0000086198 00000 n
-0000086346 00000 n
-0000086496 00000 n
-0000086646 00000 n
-0000086795 00000 n
-0000087204 00000 n
-0000085872 00000 n
-0000082976 00000 n
-0000086957 00000 n
-0000087080 00000 n
-0000087142 00000 n
-0000647000 00000 n
-0000090301 00000 n
-0000090451 00000 n
-0000090600 00000 n
-0000090749 00000 n
-0000091210 00000 n
-0000090145 00000 n
-0000087407 00000 n
-0000090901 00000 n
-0000091024 00000 n
-0000094258 00000 n
-0000094415 00000 n
-0000094692 00000 n
-0000094118 00000 n
-0000091412 00000 n
-0000094569 00000 n
-0000094630 00000 n
-0000097592 00000 n
-0000097357 00000 n
-0000094907 00000 n
-0000097469 00000 n
-0000100252 00000 n
-0000103584 00000 n
-0000100529 00000 n
-0000100120 00000 n
-0000097781 00000 n
-0000100407 00000 n
-0000103738 00000 n
-0000104136 00000 n
-0000103444 00000 n
-0000100718 00000 n
-0000103889 00000 n
-0000103950 00000 n
-0000104074 00000 n
-0000650227 00000 n
-0000107233 00000 n
-0000107633 00000 n
-0000107101 00000 n
-0000104352 00000 n
-0000107386 00000 n
-0000646313 00000 n
-0000107571 00000 n
-0000111037 00000 n
-0000111191 00000 n
-0000111592 00000 n
-0000110897 00000 n
-0000107824 00000 n
-0000111345 00000 n
-0000647342 00000 n
-0000111468 00000 n
-0000111530 00000 n
-0000114716 00000 n
-0000115052 00000 n
-0000114584 00000 n
-0000111834 00000 n
-0000114867 00000 n
-0000118308 00000 n
-0000118011 00000 n
-0000115241 00000 n
-0000118123 00000 n
-0000121533 00000 n
-0000121360 00000 n
-0000118510 00000 n
-0000121472 00000 n
-0000124407 00000 n
-0000125249 00000 n
-0000124275 00000 n
-0000121722 00000 n
-0000124568 00000 n
-0000124691 00000 n
-0000124753 00000 n
-0000124815 00000 n
-0000124877 00000 n
-0000124939 00000 n
-0000125001 00000 n
-0000125063 00000 n
-0000125125 00000 n
-0000125187 00000 n
-0000650344 00000 n
-0000126685 00000 n
-0000126202 00000 n
-0000125386 00000 n
-0000126314 00000 n
-0000126375 00000 n
-0000126437 00000 n
-0000126499 00000 n
-0000126561 00000 n
-0000126623 00000 n
-0000126822 00000 n
-0000643066 00000 n
-0000126879 00000 n
-0000127312 00000 n
-0000643757 00000 n
-0000127807 00000 n
-0000644054 00000 n
-0000127832 00000 n
-0000128549 00000 n
-0000644208 00000 n
+0000000336 00000 n
+0000029962 00000 n
+0000710028 00000 n
+0000000381 00000 n
+0000000593 00000 n
+0000037821 00000 n
+0000709904 00000 n
+0000000639 00000 n
+0000000790 00000 n
+0000037882 00000 n
+0000709793 00000 n
+0000000841 00000 n
+0000001060 00000 n
+0000042179 00000 n
+0000709719 00000 n
+0000001116 00000 n
+0000001234 00000 n
+0000044977 00000 n
+0000709645 00000 n
+0000001290 00000 n
+0000001433 00000 n
+0000045038 00000 n
+0000709558 00000 n
+0000001484 00000 n
+0000001721 00000 n
+0000048601 00000 n
+0000709434 00000 n
+0000001772 00000 n
+0000001923 00000 n
+0000051485 00000 n
+0000709373 00000 n
+0000001979 00000 n
+0000002099 00000 n
+0000051546 00000 n
+0000709286 00000 n
+0000002150 00000 n
+0000002326 00000 n
+0000051607 00000 n
+0000709212 00000 n
+0000002377 00000 n
+0000002656 00000 n
+0000055212 00000 n
+0000709086 00000 n
+0000002702 00000 n
+0000002840 00000 n
+0000058347 00000 n
+0000708975 00000 n
+0000002891 00000 n
+0000003062 00000 n
+0000061730 00000 n
+0000708914 00000 n
+0000003118 00000 n
+0000003291 00000 n
+0000061791 00000 n
+0000708827 00000 n
+0000003342 00000 n
+0000003533 00000 n
+0000064804 00000 n
+0000708740 00000 n
+0000003584 00000 n
+0000003737 00000 n
+0000067632 00000 n
+0000708616 00000 n
+0000003788 00000 n
+0000003969 00000 n
+0000070983 00000 n
+0000708542 00000 n
+0000004025 00000 n
+0000004235 00000 n
+0000071044 00000 n
+0000708455 00000 n
+0000004291 00000 n
+0000004535 00000 n
+0000073976 00000 n
+0000708368 00000 n
+0000004591 00000 n
+0000004724 00000 n
+0000074037 00000 n
+0000708281 00000 n
+0000004780 00000 n
+0000004971 00000 n
+0000077397 00000 n
+0000708194 00000 n
+0000005027 00000 n
+0000005312 00000 n
+0000080871 00000 n
+0000708120 00000 n
+0000005368 00000 n
+0000005521 00000 n
+0000084323 00000 n
+0000708031 00000 n
+0000005572 00000 n
+0000005852 00000 n
+0000087921 00000 n
+0000707954 00000 n
+0000005904 00000 n
+0000006000 00000 n
+0000087983 00000 n
+0000707824 00000 n
+0000006047 00000 n
+0000006257 00000 n
+0000088045 00000 n
+0000707745 00000 n
+0000006309 00000 n
+0000006549 00000 n
+0000101885 00000 n
+0000707652 00000 n
+0000006601 00000 n
+0000006715 00000 n
+0000102009 00000 n
+0000707559 00000 n
+0000006767 00000 n
+0000006916 00000 n
+0000105618 00000 n
+0000707427 00000 n
+0000006968 00000 n
+0000007209 00000 n
+0000105680 00000 n
+0000707362 00000 n
+0000007266 00000 n
+0000007486 00000 n
+0000108761 00000 n
+0000707230 00000 n
+0000007538 00000 n
+0000007657 00000 n
+0000114589 00000 n
+0000707151 00000 n
+0000007714 00000 n
+0000007979 00000 n
+0000117788 00000 n
+0000707072 00000 n
+0000008036 00000 n
+0000008285 00000 n
+0000121534 00000 n
+0000706954 00000 n
+0000008337 00000 n
+0000008459 00000 n
+0000124725 00000 n
+0000706875 00000 n
+0000008516 00000 n
+0000008719 00000 n
+0000124787 00000 n
+0000706796 00000 n
+0000008776 00000 n
+0000008902 00000 n
+0000128422 00000 n
+0000706665 00000 n
+0000008949 00000 n
+0000009159 00000 n
+0000128483 00000 n
+0000706561 00000 n
+0000009211 00000 n
+0000009297 00000 n
+0000131750 00000 n
+0000706482 00000 n
+0000009354 00000 n
+0000009518 00000 n
+0000131812 00000 n
+0000706403 00000 n
+0000009575 00000 n
+0000009671 00000 n
+0000134800 00000 n
+0000706272 00000 n
+0000009718 00000 n
+0000009804 00000 n
+0000134862 00000 n
+0000706207 00000 n
+0000009856 00000 n
+0000009972 00000 n
+0000145224 00000 n
+0000706114 00000 n
+0000010019 00000 n
+0000010153 00000 n
+0000148880 00000 n
+0000706035 00000 n
+0000010200 00000 n
+0000010281 00000 n
+0000012029 00000 n
+0000012249 00000 n
+0000012401 00000 n
+0000012558 00000 n
+0000012710 00000 n
+0000012862 00000 n
+0000013019 00000 n
+0000013180 00000 n
+0000013340 00000 n
+0000013493 00000 n
+0000013649 00000 n
+0000013808 00000 n
+0000013965 00000 n
+0000016847 00000 n
+0000014307 00000 n
+0000010331 00000 n
+0000014122 00000 n
+0000014183 00000 n
+0000686835 00000 n
+0000676809 00000 n
+0000675695 00000 n
+0000681260 00000 n
+0000673471 00000 n
+0000689062 00000 n
+0000694358 00000 n
+0000703727 00000 n
+0000014245 00000 n
+0000672358 00000 n
+0000671244 00000 n
+0000674581 00000 n
+0000685720 00000 n
+0000704891 00000 n
+0000016999 00000 n
+0000017156 00000 n
+0000017316 00000 n
+0000017473 00000 n
+0000017630 00000 n
+0000017787 00000 n
+0000017948 00000 n
+0000018109 00000 n
+0000018270 00000 n
+0000018431 00000 n
+0000018592 00000 n
+0000018753 00000 n
+0000018910 00000 n
+0000019067 00000 n
+0000019219 00000 n
+0000019376 00000 n
+0000019533 00000 n
+0000019689 00000 n
+0000019846 00000 n
+0000020007 00000 n
+0000020164 00000 n
+0000020325 00000 n
+0000020486 00000 n
+0000020643 00000 n
+0000020804 00000 n
+0000020965 00000 n
+0000021117 00000 n
+0000021273 00000 n
+0000021434 00000 n
+0000021595 00000 n
+0000021747 00000 n
+0000021904 00000 n
+0000022055 00000 n
+0000022328 00000 n
+0000016451 00000 n
+0000014522 00000 n
+0000022207 00000 n
+0000679035 00000 n
+0000024580 00000 n
+0000024731 00000 n
+0000024887 00000 n
+0000025049 00000 n
+0000025200 00000 n
+0000029589 00000 n
+0000026035 00000 n
+0000024416 00000 n
+0000022452 00000 n
+0000025357 00000 n
+0000025418 00000 n
+0000682375 00000 n
+0000025480 00000 n
+0000025542 00000 n
+0000025604 00000 n
+0000691731 00000 n
+0000025666 00000 n
+0000025728 00000 n
+0000025849 00000 n
+0000025911 00000 n
+0000025973 00000 n
+0000029746 00000 n
+0000030392 00000 n
+0000029449 00000 n
+0000026172 00000 n
+0000029901 00000 n
+0000030023 00000 n
+0000693483 00000 n
+0000702495 00000 n
+0000700028 00000 n
+0000695425 00000 n
+0000030085 00000 n
+0000690851 00000 n
+0000030146 00000 n
+0000030207 00000 n
+0000701262 00000 n
+0000030269 00000 n
+0000030331 00000 n
+0000033610 00000 n
+0000033945 00000 n
+0000033478 00000 n
+0000030581 00000 n
+0000033761 00000 n
+0000033822 00000 n
+0000033883 00000 n
+0000696492 00000 n
+0000698795 00000 n
+0000697555 00000 n
+0000037456 00000 n
+0000037608 00000 n
+0000038005 00000 n
+0000037316 00000 n
+0000034160 00000 n
+0000037760 00000 n
+0000704698 00000 n
+0000677923 00000 n
+0000037943 00000 n
+0000680147 00000 n
+0000041498 00000 n
+0000041652 00000 n
+0000041804 00000 n
+0000041966 00000 n
+0000042302 00000 n
+0000041342 00000 n
+0000038233 00000 n
+0000042118 00000 n
+0000042240 00000 n
+0000687949 00000 n
+0000705008 00000 n
+0000045099 00000 n
+0000044804 00000 n
+0000042543 00000 n
+0000044916 00000 n
+0000684606 00000 n
+0000048083 00000 n
+0000048235 00000 n
+0000048388 00000 n
+0000048723 00000 n
+0000047935 00000 n
+0000045289 00000 n
+0000048540 00000 n
+0000048661 00000 n
+0000051668 00000 n
+0000051312 00000 n
+0000048977 00000 n
+0000051424 00000 n
+0000054844 00000 n
+0000054999 00000 n
+0000058129 00000 n
+0000055273 00000 n
+0000054704 00000 n
+0000051857 00000 n
+0000055151 00000 n
+0000058408 00000 n
+0000057997 00000 n
+0000055449 00000 n
+0000058286 00000 n
+0000061355 00000 n
+0000061507 00000 n
+0000061852 00000 n
+0000061215 00000 n
+0000058597 00000 n
+0000061669 00000 n
+0000705125 00000 n
+0000064591 00000 n
+0000064865 00000 n
+0000064459 00000 n
+0000062054 00000 n
+0000064743 00000 n
+0000067693 00000 n
+0000067459 00000 n
+0000065054 00000 n
+0000067571 00000 n
+0000070608 00000 n
+0000070760 00000 n
+0000071105 00000 n
+0000070468 00000 n
+0000067856 00000 n
+0000070922 00000 n
+0000074098 00000 n
+0000073803 00000 n
+0000071294 00000 n
+0000073915 00000 n
+0000077020 00000 n
+0000077175 00000 n
+0000080648 00000 n
+0000077520 00000 n
+0000076880 00000 n
+0000074300 00000 n
+0000077336 00000 n
+0000077458 00000 n
+0000081055 00000 n
+0000080516 00000 n
+0000077683 00000 n
+0000080810 00000 n
+0000080931 00000 n
+0000080993 00000 n
+0000705242 00000 n
+0000084384 00000 n
+0000084026 00000 n
+0000081257 00000 n
+0000084138 00000 n
+0000084199 00000 n
+0000084261 00000 n
+0000087252 00000 n
+0000087404 00000 n
+0000087556 00000 n
+0000087706 00000 n
+0000088169 00000 n
+0000087096 00000 n
+0000084599 00000 n
+0000087860 00000 n
+0000088107 00000 n
+0000090755 00000 n
+0000090532 00000 n
+0000090817 00000 n
+0000090400 00000 n
+0000088371 00000 n
+0000090694 00000 n
+0000093816 00000 n
+0000093643 00000 n
+0000090967 00000 n
+0000093755 00000 n
+0000692607 00000 n
+0000100461 00000 n
+0000097048 00000 n
+0000096875 00000 n
+0000093979 00000 n
+0000096987 00000 n
+0000100615 00000 n
+0000100763 00000 n
+0000100913 00000 n
+0000101063 00000 n
+0000101213 00000 n
+0000101375 00000 n
+0000101525 00000 n
+0000101675 00000 n
+0000102195 00000 n
+0000100265 00000 n
+0000097212 00000 n
+0000101824 00000 n
+0000101947 00000 n
+0000102071 00000 n
+0000102133 00000 n
+0000705359 00000 n
+0000105405 00000 n
+0000105803 00000 n
+0000105273 00000 n
+0000102436 00000 n
+0000105557 00000 n
+0000105741 00000 n
+0000108483 00000 n
+0000108822 00000 n
+0000108351 00000 n
+0000105980 00000 n
+0000108638 00000 n
+0000108699 00000 n
+0000111715 00000 n
+0000111992 00000 n
+0000111583 00000 n
+0000108959 00000 n
+0000111869 00000 n
+0000111930 00000 n
+0000114651 00000 n
+0000114416 00000 n
+0000112207 00000 n
+0000114528 00000 n
+0000117572 00000 n
+0000117912 00000 n
+0000117440 00000 n
+0000114827 00000 n
+0000117727 00000 n
+0000117850 00000 n
+0000121322 00000 n
+0000121596 00000 n
+0000121190 00000 n
+0000118101 00000 n
+0000121473 00000 n
+0000683490 00000 n
+0000705476 00000 n
+0000124511 00000 n
+0000124911 00000 n
+0000124379 00000 n
+0000121748 00000 n
+0000124664 00000 n
+0000124849 00000 n
+0000127902 00000 n
+0000128055 00000 n
+0000128209 00000 n
+0000128668 00000 n
+0000127754 00000 n
+0000125088 00000 n
+0000128361 00000 n
+0000690179 00000 n
+0000128544 00000 n
+0000128606 00000 n
+0000131873 00000 n
+0000131577 00000 n
0000128896 00000 n
-0000128957 00000 n
-0000128982 00000 n
-0000129019 00000 n
-0000643545 00000 n
-0000129631 00000 n
-0000130327 00000 n
-0000130985 00000 n
-0000131348 00000 n
-0000132030 00000 n
-0000132673 00000 n
-0000133316 00000 n
-0000133883 00000 n
-0000134000 00000 n
-0000134391 00000 n
-0000134976 00000 n
-0000135513 00000 n
-0000136066 00000 n
-0000136183 00000 n
-0000136784 00000 n
-0000137447 00000 n
-0000137810 00000 n
-0000138137 00000 n
-0000138697 00000 n
-0000139115 00000 n
-0000139694 00000 n
-0000139791 00000 n
-0000147255 00000 n
-0000147477 00000 n
-0000178399 00000 n
-0000178857 00000 n
-0000207139 00000 n
-0000207531 00000 n
-0000230206 00000 n
-0000230448 00000 n
-0000234387 00000 n
-0000234765 00000 n
-0000246391 00000 n
-0000246766 00000 n
-0000249349 00000 n
-0000249584 00000 n
-0000259342 00000 n
-0000259679 00000 n
-0000263678 00000 n
-0000263925 00000 n
-0000300770 00000 n
-0000301372 00000 n
-0000324152 00000 n
-0000324443 00000 n
-0000350865 00000 n
-0000351168 00000 n
-0000369263 00000 n
-0000369507 00000 n
-0000391856 00000 n
-0000392128 00000 n
-0000414971 00000 n
-0000415286 00000 n
-0000445520 00000 n
-0000445922 00000 n
-0000475192 00000 n
-0000475575 00000 n
-0000493936 00000 n
-0000494245 00000 n
-0000511575 00000 n
-0000511838 00000 n
-0000515481 00000 n
-0000515772 00000 n
-0000518292 00000 n
-0000518539 00000 n
-0000521547 00000 n
-0000521804 00000 n
-0000547011 00000 n
-0000547322 00000 n
-0000577191 00000 n
-0000577737 00000 n
-0000595437 00000 n
-0000595678 00000 n
-0000618943 00000 n
-0000619263 00000 n
-0000642689 00000 n
-0000650429 00000 n
-0000650531 00000 n
-0000654369 00000 n
-0000654567 00000 n
-0000654752 00000 n
-0000654922 00000 n
-0000655091 00000 n
-0000655253 00000 n
-0000655451 00000 n
-0000655640 00000 n
-0000655810 00000 n
-0000655979 00000 n
-0000656149 00000 n
-0000656316 00000 n
-0000656486 00000 n
-0000656680 00000 n
-0000656862 00000 n
-0000657064 00000 n
-0000657284 00000 n
-0000657508 00000 n
-0000657747 00000 n
-0000658007 00000 n
-0000658272 00000 n
-0000658388 00000 n
-0000658504 00000 n
-0000658621 00000 n
-0000658745 00000 n
-0000658842 00000 n
-0000658937 00000 n
-0000658975 00000 n
-0000659102 00000 n
+0000131689 00000 n
+0000134924 00000 n
+0000134627 00000 n
+0000132062 00000 n
+0000134739 00000 n
+0000138032 00000 n
+0000137859 00000 n
+0000135140 00000 n
+0000137971 00000 n
+0000141383 00000 n
+0000141605 00000 n
+0000141251 00000 n
+0000138234 00000 n
+0000141544 00000 n
+0000705593 00000 n
+0000144691 00000 n
+0000144847 00000 n
+0000145009 00000 n
+0000145843 00000 n
+0000144543 00000 n
+0000141729 00000 n
+0000145163 00000 n
+0000145286 00000 n
+0000145348 00000 n
+0000145410 00000 n
+0000145472 00000 n
+0000145534 00000 n
+0000145596 00000 n
+0000145658 00000 n
+0000145720 00000 n
+0000145782 00000 n
+0000148005 00000 n
+0000148162 00000 n
+0000149619 00000 n
+0000147865 00000 n
+0000146019 00000 n
+0000148323 00000 n
+0000148384 00000 n
+0000148446 00000 n
+0000148508 00000 n
+0000148570 00000 n
+0000148632 00000 n
+0000148694 00000 n
+0000148756 00000 n
+0000148818 00000 n
+0000148942 00000 n
+0000149004 00000 n
+0000149066 00000 n
+0000149127 00000 n
+0000149189 00000 n
+0000149251 00000 n
+0000149313 00000 n
+0000149375 00000 n
+0000149437 00000 n
+0000149498 00000 n
+0000149559 00000 n
+0000150935 00000 n
+0000150576 00000 n
+0000149757 00000 n
+0000150688 00000 n
+0000150749 00000 n
+0000150811 00000 n
+0000150873 00000 n
+0000151073 00000 n
+0000668871 00000 n
+0000151130 00000 n
+0000669588 00000 n
+0000151563 00000 n
+0000151588 00000 n
+0000151951 00000 n
+0000152416 00000 n
+0000153792 00000 n
+0000670254 00000 n
+0000153915 00000 n
+0000669885 00000 n
+0000153940 00000 n
+0000670035 00000 n
+0000154657 00000 n
+0000154718 00000 n
+0000154743 00000 n
+0000669376 00000 n
+0000154780 00000 n
+0000155476 00000 n
+0000156134 00000 n
+0000156777 00000 n
+0000157140 00000 n
+0000157822 00000 n
+0000158465 00000 n
+0000159032 00000 n
+0000159155 00000 n
+0000159546 00000 n
+0000160311 00000 n
+0000160848 00000 n
+0000161401 00000 n
+0000162002 00000 n
+0000162665 00000 n
+0000163028 00000 n
+0000163355 00000 n
+0000163915 00000 n
+0000164333 00000 n
+0000164900 00000 n
+0000164997 00000 n
+0000172461 00000 n
+0000172683 00000 n
+0000204032 00000 n
+0000204499 00000 n
+0000233144 00000 n
+0000233543 00000 n
+0000256218 00000 n
+0000256460 00000 n
+0000260399 00000 n
+0000260777 00000 n
+0000272403 00000 n
+0000272778 00000 n
+0000275361 00000 n
+0000275596 00000 n
+0000285659 00000 n
+0000286002 00000 n
+0000290001 00000 n
+0000290248 00000 n
+0000327657 00000 n
+0000328274 00000 n
+0000350850 00000 n
+0000351136 00000 n
+0000377071 00000 n
+0000377370 00000 n
+0000395465 00000 n
+0000395709 00000 n
+0000418530 00000 n
+0000418812 00000 n
+0000441943 00000 n
+0000442263 00000 n
+0000472578 00000 n
+0000472981 00000 n
+0000501137 00000 n
+0000501500 00000 n
+0000520119 00000 n
+0000520433 00000 n
+0000537763 00000 n
+0000538026 00000 n
+0000541493 00000 n
+0000541777 00000 n
+0000544297 00000 n
+0000544544 00000 n
+0000547645 00000 n
+0000547908 00000 n
+0000573478 00000 n
+0000573810 00000 n
+0000604125 00000 n
+0000604686 00000 n
+0000622386 00000 n
+0000622627 00000 n
+0000645110 00000 n
+0000645403 00000 n
+0000668498 00000 n
+0000670319 00000 n
+0000671433 00000 n
+0000672547 00000 n
+0000673659 00000 n
+0000674773 00000 n
+0000675887 00000 n
+0000677001 00000 n
+0000678113 00000 n
+0000679225 00000 n
+0000680338 00000 n
+0000681451 00000 n
+0000682566 00000 n
+0000683681 00000 n
+0000684796 00000 n
+0000685911 00000 n
+0000687026 00000 n
+0000688139 00000 n
+0000689252 00000 n
+0000690340 00000 n
+0000691050 00000 n
+0000691928 00000 n
+0000692804 00000 n
+0000693679 00000 n
+0000694554 00000 n
+0000695622 00000 n
+0000696686 00000 n
+0000697751 00000 n
+0000698985 00000 n
+0000700219 00000 n
+0000701452 00000 n
+0000702684 00000 n
+0000703917 00000 n
+0000705694 00000 n
+0000705812 00000 n
+0000705889 00000 n
+0000705959 00000 n
+0000710277 00000 n
+0000710476 00000 n
+0000710668 00000 n
+0000710838 00000 n
+0000711007 00000 n
+0000711177 00000 n
+0000711346 00000 n
+0000711516 00000 n
+0000711678 00000 n
+0000711888 00000 n
+0000712072 00000 n
+0000712242 00000 n
+0000712411 00000 n
+0000712581 00000 n
+0000712749 00000 n
+0000712917 00000 n
+0000713081 00000 n
+0000713276 00000 n
+0000713464 00000 n
+0000713648 00000 n
+0000713858 00000 n
+0000714078 00000 n
+0000714304 00000 n
+0000714547 00000 n
+0000714807 00000 n
+0000715072 00000 n
+0000715278 00000 n
+0000715389 00000 n
+0000715498 00000 n
+0000715609 00000 n
+0000715732 00000 n
+0000715821 00000 n
+0000715924 00000 n
+0000715962 00000 n
+0000716089 00000 n
trailer
-<< /Size 587
-/Root 585 0 R
-/Info 586 0 R
-/ID [<E8F61294C63DC4A2AD1F7ADD4C5ADEFE> <E8F61294C63DC4A2AD1F7ADD4C5ADEFE>] >>
+<< /Size 721
+/Root 719 0 R
+/Info 720 0 R
+/ID [<6A2E810568CCB03581CD451C3B7655E7> <6A2E810568CCB03581CD451C3B7655E7>] >>
startxref
-660198
+717066
%%EOF
diff --git a/macros/latex/contrib/diffcoeff/diffcoeff.sty b/macros/latex/contrib/diffcoeff/diffcoeff.sty
index 3d952355fa..8ecaf59950 100644
--- a/macros/latex/contrib/diffcoeff/diffcoeff.sty
+++ b/macros/latex/contrib/diffcoeff/diffcoeff.sty
@@ -9,22 +9,26 @@
%
\RequirePackage{expl3}
\RequirePackage{xparse,l3keys2e,xtemplate}
-\ProvidesExplPackage {diffcoeff} {2019/12/28} {3.2}
+\ProvidesExplPackage {diffcoeff} {2021/12/24} {4.0}
{Write differential coefficients consistently and easily.}
-%
+%
\keys_define:nn { diffcoeff }
{
- ISO .bool_gset:N = \g__diffcoeff_ISO_bool,
- def-file .tl_gset:N = \g__diffcoeff_def_tl ,
- def-file .initial:n = diffcoeff ,
+ ISO .bool_set:N = \l__diffcoeff_ISO_bool,
+ spaced .int_set:N = \l__diffcoeff_spaced_int,
+ spaced .default:n = 1,
+ spaced .initial:n = 0,
+ def-file .tl_gset:N = \g__diffcoeff_def_tl,
+ def-file .initial:n = diffcoeff,
def-file .default:n = diffcoeff
}
\ProcessKeysPackageOptions { diffcoeff }
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\cs_generate_variant:Nn \tl_if_eq:nnTF { nV }
\tl_new:N \l__diffcoeff_oporder_tl
-\tl_new:N \l__diffcoeff_differentiand_tl
+\tl_new:N \l__diffcoeff_derivand_tl
\tl_new:N \l__diffcoeff_type_tl
\tl_new:N \l__diffcoeff_tot_order_tl
\tl_new:N \l__diffcoeff_curr_num_tl
@@ -45,6 +49,8 @@
\bool_new:N \l__diffcoeff_single_var_bool
\bool_new:N \l__diffcoeff_opwrap_bool
\bool_new:N \l__diffcoeff_integ_bool
+\bool_new:N \l__diffcoeff_spaced_bool
+\bool_new:N \l__diffcoeff_altsep_bool
\int_new:N \l__diffcoeff_vars_int
\int_new:N \l__diffcoeff_format_int
@@ -62,36 +68,36 @@
op-symbol : tokenlist = d ,
op-symbol-alt : tokenlist = \KeyValue { op-symbol },
op-order-sep : muskip = 1 mu ,
- /-op-order-sep : muskip = 1 mu ,
- *-op-left : boolean = false ,
- *-italic-nudge : muskip = 3 mu ,
- */-op-wrap : boolean = true ,
+ derivand-sep : muskip = 3 mu plus 1 mu minus 2 mu,
long-var-wrap : choice { dv, d(v), (dv) }
= d(v) ,
denom-term-sep : muskip = 2 mu ,
- /-denom-term-sep : muskip = 1 mu ,
term-sep-adjust : muskip = -1 mu ,
left-delim : tokenlist = \left . ,
right-delim : tokenlist = \right |,
elbowroom : muskip = 0 mu ,
subscr-nudge : muskip = 0 mu ,
+ *-derivand-sep : muskip = \KeyValue { derivand-sep },
+ *-op-left : boolean = false ,
+ *-italic-nudge : muskip = 3 mu ,
+ /-derivand-sep : muskip = \KeyValue { derivand-sep },
+ /-denom-term-sep : muskip = 1 mu ,
/-left-delim : tokenlist = ( ,
/-right-delim : tokenlist = ) ,
/-elbowroom : muskip = 0 mu ,
- /-subscr-nudge : muskip = 0 mu
+ /-subscr-nudge : muskip = 0 mu ,
+ */-derivand-sep : muskip = \KeyValue { /-derivand-sep },
+ */-op-wrap : boolean = true
}
% #1 order spec(seqvar); #2 order override(tlvar)
-% #3 differentiand(tlvar); #4 denominator(seqvar)
+% #3 derivand(tlvar); #4 denominator(seqvar)
% #5 subscript(tlvar)
\DeclareTemplateCode { derivative } { DERIV } { 5 }
{
- op-symbol = \l__diffcoeff_op_tl ,
- op-symbol-alt = \l__diffcoeff_op_alt_tl ,
- op-order-sep = \l__diffcoeff_oporder_muskip ,
- /-op-order-sep = \l_tmpa_muskip ,
- *-op-left = \l__diffcoeff_op_left_bool ,
- *-italic-nudge = \l__diffcoeff_opnudge_muskip ,
- */-op-wrap = \l__diffcoeff_opwrap_bool ,
+ op-symbol = \l__diffcoeff_op_tl,
+ op-symbol-alt = \l__diffcoeff_op_alt_tl,
+ op-order-sep = \l__diffcoeff_oporder_muskip,
+ derivand-sep = \l__diffcoeff_derivsep_muskip,
long-var-wrap = {
dv = \cs_set:Npn \__diffcoeff_wrap_longvars:nn #1#2
{ \l__diffcoeff_op_alt_tl {#2}^{#1} },
@@ -101,18 +107,24 @@
{ (\l__diffcoeff_op_alt_tl {#2)}^{#1} },
unknown = \cs_set:Npn \__diffcoeff_wrap_longvars:nn #1#2
{ \l__diffcoeff_op_alt_tl {(#2)}^{#1} }
- } ,
- denom-term-sep = \l__diffcoeff_varsep_muskip ,
- /-denom-term-sep = \l_tmpb_muskip ,
- term-sep-adjust = \l__diffcoeff_sep_adj_muskip ,
- left-delim = \l__diffcoeff_ldelim_tl ,
- right-delim = \l__diffcoeff_rdelim_tl ,
+ },
+ denom-term-sep = \l__diffcoeff_varsep_muskip,
+ term-sep-adjust = \l__diffcoeff_sep_adj_muskip,
+ left-delim = \l__diffcoeff_ldelim_tl,
+ right-delim = \l__diffcoeff_rdelim_tl,
elbowroom = \l__diffcoeff_elbowrm_muskip ,
subscr-nudge = \l__diffcoeff_subnudge_muskip,
- /-left-delim = \l_tmpa_tl ,
- /-right-delim = \l_tmpb_tl ,
- /-elbowroom = \l_tmpc_muskip ,
- /-subscr-nudge = \l_tmpd_muskip
+ *-derivand-sep = \l__diffcoeff_derivsepi_muskip,
+ *-op-left = \l__diffcoeff_op_left_bool,
+ *-italic-nudge = \l__diffcoeff_opnudge_muskip,
+ /-derivand-sep = \l__diffcoeff_derivsepii_muskip,
+ /-denom-term-sep = \l_tmpb_muskip,
+ /-left-delim = \l__diffcoeff_ldelimi_tl,
+ /-right-delim = \l__diffcoeff_rdelimi_tl,
+ /-elbowroom = \l_tmpc_muskip,
+ /-subscr-nudge = \l_tmpd_muskip,
+ */-derivand-sep = \l__diffcoeff_derivsepiii_muskip,
+ */-op-wrap = \l__diffcoeff_opwrap_bool
}
{
\AssignTemplateKeys
@@ -127,32 +139,43 @@
%%%%%%%%%%
\cs_new:Npn \__diffcoeff_slash_vals:
{
- \muskip_set:Nn \l__diffcoeff_oporder_muskip \l_tmpa_muskip
- \muskip_set:Nn \l__diffcoeff_varsep_muskip \l_tmpb_muskip
- \muskip_set:Nn \l__diffcoeff_elbowrm_muskip \l_tmpc_muskip
+ \muskip_set:Nn \l__diffcoeff_varsep_muskip \l_tmpb_muskip
+ \muskip_set:Nn \l__diffcoeff_elbowrm_muskip \l_tmpc_muskip
\muskip_set:Nn \l__diffcoeff_subnudge_muskip \l_tmpd_muskip
- \tl_set:NV \l__diffcoeff_ldelim_tl \l_tmpa_tl
- \tl_set:NV \l__diffcoeff_rdelim_tl \l_tmpb_tl
+ \tl_set:NV \l__diffcoeff_ldelim_tl \l__diffcoeff_ldelimi_tl
+ \tl_set:NV \l__diffcoeff_rdelim_tl \l__diffcoeff_rdelimi_tl
}
\cs_new:Npn \__diffcoeff_build:NNNNN #1#2#3#4#5
{
- \bool_if:NF \l__diffcoeff_opwrap_bool
+ \bool_if:nT
+ {
+ !\l__diffcoeff_opwrap_bool &&
+ \int_compare_p:nNn { \l__diffcoeff_format_int } > { 1 }
+ }
{ \int_set:Nn \l__diffcoeff_format_int { 4 } }
+ \__diffcoeff_spaced:n { \l__diffcoeff_spaced_int }
+ \bool_if:nTF
+ {
+ ( \l__diffcoeff_altsep_bool && !\l__diffcoeff_spaced_bool )
+ || ( !\l__diffcoeff_altsep_bool && \l__diffcoeff_spaced_bool )
+ }
+ { \__diffcoeff_derivsep: }
+ { \tl_put_left:Nn \l__diffcoeff_derivand_tl { \mskip 0 mu } }
\exp_args:NV\tl_if_novalue:nF #5
- { \l__diffcoeff_ldelim_tl \mkern \l__diffcoeff_elbowrm_muskip }
+ { \l__diffcoeff_ldelim_tl \mskip \l__diffcoeff_elbowrm_muskip }
\bool_if:NTF \l__diffcoeff_single_var_bool
{
\tl_set:Nx \l_tmpa_tl { \seq_use:Nn #4 { , } }
\__diffcoeff_single:NNN #2 #3 \l_tmpa_tl
}
- {
+ {
\int_zero:N \l_tmpa_int
\seq_mapthread_function:NNN #1 #4 \__diffcoeff_map_orders:nn
\__diffcoeff_mixed:NNN #2 #3 \l__diffcoeff_denom_seq
}
\exp_args:NV\tl_if_novalue:nF #5
{
- \mkern \l__diffcoeff_elbowrm_muskip \l__diffcoeff_rdelim_tl
+ \mskip \l__diffcoeff_elbowrm_muskip \l__diffcoeff_rdelim_tl
\exp_args:NV\tl_if_empty:nF #5
{
\c_math_subscript_token
@@ -161,6 +184,35 @@
}
}
%%%%%%%%%%%%%%%%%%%%
+\cs_new_protected:Npn \__diffcoeff_spaced:n #1
+ {
+ \int_case:nn { \int_sign:n { #1 } }
+ {
+ { 1 } { \bool_set_true:N \l__diffcoeff_spaced_bool }
+ { 0 } { \bool_set_false:N \l__diffcoeff_spaced_bool }
+ { -1 }
+ {
+ \int_compare:nNnTF { 1 } <
+ { \tl_count:N \l__diffcoeff_derivand_tl }
+ { \bool_set_true:N \l__diffcoeff_spaced_bool }
+ { \bool_set_false:N \l__diffcoeff_spaced_bool }
+ }
+ }
+ }
+\cs_new_protected:Npn \__diffcoeff_derivsep:
+ {
+ \tl_put_left:Nx \l__diffcoeff_derivand_tl
+ {
+ \int_case:nn { \l__diffcoeff_format_int }
+ {
+ { 0 } { \mskip \l__diffcoeff_derivsep_muskip }
+ { 1 } { \mskip \l__diffcoeff_derivsepi_muskip }
+ { 2 } { \mskip \l__diffcoeff_derivsepii_muskip }
+ { 3 } { \mskip \l__diffcoeff_derivsepiii_muskip }
+ { 4 } { \mskip \l__diffcoeff_derivsepiii_muskip }
+ }
+ }
+ }
% (ptl) form denom from #1 orders seq & #2 vars seq
\cs_new_protected:Npn \__diffcoeff_map_orders:nn #1#2
{
@@ -184,16 +236,16 @@
\__diffcoeff_numer:N { #1 }
\__diffcoeff_form_deriv:NNn
\l__diffcoeff_oporder_tl
- \l__diffcoeff_differentiand_tl
+ \l__diffcoeff_derivand_tl
{ \__diffcoeff_denom_single:NN #1 #3 }
}
-% #1 total order; #2 differentiand; #3 denom seq
+% #1 total order; #2 derivand; #3 denom seq
\cs_new_protected:Npn \__diffcoeff_mixed:NNN #1#2#3
{
\__diffcoeff_numer:N #1
\__diffcoeff_form_deriv:NNn
\l__diffcoeff_oporder_tl
- \l__diffcoeff_differentiand_tl
+ \l__diffcoeff_derivand_tl
{ \__diffcoeff_denom_sep:N #3 }
}
\cs_new:Npn \__diffcoeff_denom_sep:N #1
@@ -206,9 +258,9 @@
{
\seq_pop:NN \l__diffcoeff_orders_seq \l_tmpa_tl
\str_if_eq:VnTF \l_tmpa_tl { 1 }
- { \mkern \l__diffcoeff_varsep_muskip }
+ { \mskip \l__diffcoeff_varsep_muskip }
{
- \mkern \muskip_eval:n { \l__diffcoeff_varsep_muskip +
+ \mskip \muskip_eval:n { \l__diffcoeff_varsep_muskip +
\l__diffcoeff_sep_adj_muskip }
}
}
@@ -244,16 +296,16 @@
}
}
% #1 op+order; #2 diff'iand; #3 denom
-% 0 frac; 1 frac append; 2 slash ; 3 slash append
+% 0 frac; 1 frac append; 2 slash ; 3 ( slash ) append; 4 slash append
\cs_new:Npn \__diffcoeff_form_deriv:NNn #1#2#3
{
\int_case:nn { \l__diffcoeff_format_int }
{
{ 0 } { \frac { #1 #2 } { #3 } }
- { 1 } { \frac { #1 } { #3 } { #2 } }
+ { 1 } { \frac { #1 } { #3 } #2 }
{ 2 } { #1 #2 / #3 }
- { 3 } { ( #1 / #3 ) { #2 } }
- { 4 } { #1 / #3 { #2 } }
+ { 3 } { ( #1 / #3 ) #2 }
+ { 4 } { #1 / #3 #2 }
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -274,25 +326,27 @@
\l__diffcoeff_orders_seq \l__diffcoeff_tot_order_tl
\c_empty_tl \c_empty_seq \c_empty_tl
\tl_if_in:NnTF \c__diffcoeff_digits_tl { #3 }
- { \mkern \IfBooleanT #2 { - }#3 mu \l__diffcoeff_op_tl \group_end: }
+ { \mskip \IfBooleanT #2 { - }#3 mu \l__diffcoeff_op_tl \group_end: }
{ \l__diffcoeff_op_tl \group_end: {} #3 }
}
-\NewDocumentCommand \negmu {} { \mkern -1 mu }
-\NewDocumentCommand \nilmu {} { \mkern 0 mu }
-\NewDocumentCommand \onemu {} { \mkern 1 mu }
-\NewDocumentCommand \twomu {} { \mkern 2 mu }
+\NewDocumentCommand \negmu {} { \mskip -1 mu }
+\NewDocumentCommand \nilmu {} { \mskip 0 mu }
+\NewDocumentCommand \onemu {} { \mskip 1 mu }
+\NewDocumentCommand \twomu {} { \mskip 2 mu }
% derivative
% #1(tl) = name of variant; #2(*)= append diff'iand boolean
% #3(clist) = orders of diff. in each var.; #4(tl) = order override
-% #5(tl) = diff'iand; #6( / ) = slash boolean
-% #7(clist) = vars of diff.; #8(tl) = pt of eval./vars held const
-% #9(tl) = as #8 (for backwards compat)
-\NewDocumentCommand \diff { d.. s O{1} o m t/ m !O{#9} g }
+% #5(bool) spacing switch; #6(tl) = diff'iand; #7( / ) = slash boolean
+% #8(clist) = vars of diff.; #9(tl) = pt of eval./vars held const
+\NewDocumentCommand \diff { d.. s O{1} o t! >{\TrimSpaces} m t/ m !o }
{
\group_begin:
- \tl_set:Nn \l__diffcoeff_differentiand_tl { #5 }
- \tl_set:Nn \l__diffcoeff_trailing_tl { #8 }
- \seq_set_from_clist:Nn \l__diffcoeff_vars_seq { #7 }
+ \IfBooleanTF #5
+ { \bool_set_true:N \l__diffcoeff_altsep_bool }
+ { \bool_set_false:N \l__diffcoeff_altsep_bool }
+ \tl_set:Nn \l__diffcoeff_derivand_tl { #6 }
+ \tl_set:Nn \l__diffcoeff_trailing_tl { #9 }
+ \seq_set_from_clist:Nn \l__diffcoeff_vars_seq { #8 }
\seq_set_from_clist:Nn \l__diffcoeff_orders_seq { #3 }
\int_set:Nn \l__diffcoeff_vars_int
{ \seq_count:N \l__diffcoeff_vars_seq }
@@ -330,12 +384,11 @@
% append? slash?
\int_zero:N \l__diffcoeff_format_int
\IfBooleanT #2 { \int_incr:N \l__diffcoeff_format_int }
- \IfBooleanT #6 { \int_add:Nn \l__diffcoeff_format_int { 2 } }
-
+ \IfBooleanT #7 { \int_add:Nn \l__diffcoeff_format_int { 2 } }
\UseInstance { derivative } { ord\l__diffcoeff_type_tl }
\l__diffcoeff_orders_seq
\l__diffcoeff_tot_order_tl
- \l__diffcoeff_differentiand_tl
+ \l__diffcoeff_derivand_tl
\l__diffcoeff_vars_seq
\l__diffcoeff_trailing_tl
\group_end:
@@ -616,7 +669,7 @@
% ordinary & D
\DeclareInstance { derivative } { ord } { DERIV } { }
-\bool_if:NTF \g__diffcoeff_ISO_bool
+\bool_if:NTF \l__diffcoeff_ISO_bool
{
\diffdef { }
{
@@ -638,7 +691,8 @@
right-delim = \right ) ,
subscr-nudge = -6 mu
}
-\NewDocumentCommand \diffp { } { \diff.p. }
+\NewDocumentCommand \diffp {} { \diff.p. }
+\NewDocumentCommand \dlp {} { \dl.p. }
% delta
\diffdef { delta }
diff --git a/macros/latex/contrib/diffcoeff/diffcoeff.tex b/macros/latex/contrib/diffcoeff/diffcoeff.tex
index 9ade962edd..ffe2645c6a 100644
--- a/macros/latex/contrib/diffcoeff/diffcoeff.tex
+++ b/macros/latex/contrib/diffcoeff/diffcoeff.tex
@@ -1,10 +1,11 @@
-%% LyX 2.3.3 created this file. For more info, see http://www.lyx.org/.
+%% LyX 2.4.0-alpha3 created this file. For more info, see https://www.lyx.org/.
%% Do not edit unless you really know what you are doing.
\documentclass[english]{article}
\usepackage{lmodern}
\renewcommand{\sfdefault}{lmss}
\renewcommand{\ttdefault}{lmtt}
\usepackage[T1]{fontenc}
+\usepackage{textcomp}
\usepackage[latin9]{inputenc}
\synctex=-1
\usepackage{color}
@@ -29,6 +30,8 @@
\providecommand{\tabularnewline}{\\}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
+\newenvironment{centred}%
+ {\begin{center}\baselineskip=13pt\parskip=1pt}{\end{center}}
\newenvironment{example}%
{\begin{center}\ttfamily}{\end{center}}
\newenvironment{lyxcode}
@@ -52,117 +55,97 @@
\title{\texttt{diffcoeff}~\\
a \LaTeX{} package to ease\texttt{ }the~\\
writing of differential coefficients \\
- in all their variety\\
- Version 3.2}
+ Version 4.0}
\author{Andrew Parsloe\\
-{\small{}(ajparsloe@gmail.com)}}
+{\small (ajparsloe@gmail.com)}}
\maketitle
\begin{abstract}
-\noindent This package allows the easy and consistent writing of ordinary,
-partial and other derivatives of arbitrary (algebraic or numeric) order.
-For mixed partial derivatives, the total order of differentiation is calculated
-by the package. Optional arguments allow for points of evaluation (ordinary
-derivatives), or variables held constant (partial derivatives), and the
-placement of the differentiand (numerator or appended). The package uses
-\texttt{xtemplate,} allowing systematic fine-tuning of the display and
-generation and use of variant forms, including derivatives built from $D$,
-$\Delta$ or $\delta$. A command for differentials ensures the $\dl x$
-(or $\dl.up.x$) used in integrals is consistent with the form used in
-derivatives. The package requires the \LaTeX 3 bundles \texttt{l3kernel}
-and \texttt{l3packages}.
+\noindent This package eases the consistent writing of ordinary, partial
+and other derivatives of arbitrary (algebraic or numeric) order. For
+mixed partial derivatives, the total order of differentiation is calculated
+by the package. Optional arguments allow for points of evaluation
+(ordinary derivatives), or variables held constant (partial derivatives),
+and the placement of the differentiand in numerator or appended. The
+package uses \texttt{xtemplate}, allowing systematic fine-tuning of
+the display and generation and use of variant forms, including derivatives
+built from $D$, $\Delta$ or $\delta$. A command for differentials
+ensures the $\dl x$ (or $\dl.up.x$) used in integrals is consistent
+with the form used in derivatives.
\end{abstract}
\tableofcontents{}
\section{Introduction}
-The \LaTeX{} package \texttt{diffcoeff.sty} is written in the expl3 language
-of \LaTeX 3\texttt{ }and requires the bundles \texttt{l3kernel} and \texttt{l3packages}
+The \LaTeX{} package \texttt{diffcoeff.sty} is written in the expl3
+language of \LaTeX 3\texttt{ }and requires the bundles \texttt{l3kernel}
+which is now is part of standard \LaTeX{} (since early 2020) and \texttt{l3packages}
(the latter for the \texttt{xparse}, \texttt{l3keys2e} and \texttt{xtemplate}
packages\texttt{)}. The package is invoked in the usual way by entering
\begin{lyxcode}
\textbackslash usepackage\{diffcoeff\}
\end{lyxcode}
-in the preamble of your document. There are two package options. The first
-is a switch, \texttt{ISO}, which turns on formatting conforming to ISO
-recommendations:
+in the preamble of your document.
+
+\subsubsection*{Note on terminology}
+
+I refer throughout to the quantity or function being differentiated
+as the \emph{differentiand} or \emph{derivand }(in line with \emph{integrand},
+\emph{operand}, etc.).
+
+\subsubsection*{New in version 4.0}
+
+(See \ref{sec:Version-comparison} for a comparison of versions.)
+Version 4.0
+\begin{enumerate}
+\item enables the insertion of a small space before the differentiand, either
+as the default behaviour (package option \verb`spaced`) or at explicit
+request (argument \verb`!` of the \verb`\diff` command); see \ref{subsec:Spacing-before-derivand};
+\item prevents the ligature $df$ that marred previous versions; this is
+now rendered $\dl f$;
+\item offers the document command \verb`\dlp` for the \emph{partial} differential;
+see \ref{subsec:Partial-differential};
+\item no longer accepts \emph{the braced form} of the\emph{ }trailing optional
+argument specifying a point of evaluation or (for partial derivatives)
+variables held constant. This was a relic from version 1 of \texttt{diffcoeff},
+and has been deprecated since version 2.
+\end{enumerate}
+
+\subsection{Package options}
+
+\label{subsec:Package-options}There are three package options, which
+are entered in a comma-separated list in the optional argument of
+the \texttt{\textbackslash usepackage} command.
+\begin{enumerate}
+\item The first is a switch, \texttt{ISO}, which turns on formatting conforming
+to ISO recommendations, principally upright `d's:
\begin{lyxcode}
\textbackslash usepackage{[}ISO{]}\{diffcoeff\}
\end{lyxcode}
-The effect of this is discussed in Section~\ref{sec:Changing-defaults}.
-The second is a filename for a file of extension \texttt{.def} containing
-definitions of variant forms of derivative:
+The full effect of this option is disscussed in \ref{sec:Changing-defaults}.
+\item The second is another switch, \texttt{spaced}, and \emph{is new with
+version 4 }of \texttt{diffcoeff}. This switch ensures a small space
+is inserted before the differentiand:
\begin{lyxcode}
-\textbackslash usepackage{[}def-file=<filename>{]}\{diffcoeff\}
+\textbackslash usepackage{[}spaced{]}\{diffcoeff\}
\end{lyxcode}
-This is discussed in Subsection~\ref{subsec:The-.def-file}. Of course
-both options can be used in the same call if desired:
+This is discussed in \ref{subsec:Spacing-before-derivand}.
+\item The third requires a filename \texttt{<filename>} for a file \texttt{<filename>.def}
+containing definitions of variant forms of derivative:
\begin{lyxcode}
-\textbackslash usepackage{[}ISO,def-file=<filename>{]}\{diffcoeff\}
+\textbackslash usepackage{[}def-file=<filename>{]}\{diffcoeff\}
\end{lyxcode}
-For the present document, the call is
+This is discussed in \ref{subsec:The-.def-file}. For the present
+document, the call is
\begin{lyxcode}
\textbackslash usepackage{[}def-file=diffcoeff-doc{]}\{diffcoeff\}
\end{lyxcode}
-with the file \texttt{diffcoeff-doc.def} in the same directory as \texttt{diffcoeff.tex}.
-
-\subsection{Version comparison}
-
-Unlike version 1, version 2 and later are built on the the \texttt{xtemplate}
-package (included in the \texttt{l3packages} bundle) which makes certain
-facilities available which it would be silly not to exploit. Hence the
-coding in the later versions is completely different and there are consequences.
-\begin{enumerate}
-\item The \texttt{\textbackslash diffset} command, formerly used to tweak the
-display of derivatives, has been superseded by the \texttt{\textbackslash diffdef}
-command. \texttt{\textbackslash diffset} now sends a message warning of
-its obsolescence to the terminal and \LaTeX{} log but is otherwise functionless.
-It should not interfere with the compilation of a document but any intended
-fine-tuning of the display by means of the \texttt{\textbackslash diffset}
-command\texttt{ }will not eventuate. The warning message is: \texttt{Obsolete
-command: \textbackslash diffset has been superseded by the \textbackslash diffdef
-command. See the diffcoeff documentation for further information.} The
-\texttt{\textbackslash diffdef} command is discussed in Subsection~\ref{subsec:diffdef}.
-\item The optional trailing argument used to indicate a point of evaluation or
-variables held constant is now delimited by square brackets, \texttt{{[}}
-and \texttt{{]}}, as other optional arguments are. For compatibility with
-version 1, braces can still be used but their use to delimit an \emph{optional}
-argument is now deprecated in \texttt{xparse} on which \texttt{diffcoeff}
-depends. Presumably at some stage this provision will be removed from \texttt{xparse}.
-For future-proofing documents use square brackets.
-\item The commands \texttt{\textbackslash Diff}, \texttt{\textbackslash diffd}
-and \texttt{\textbackslash Diffd} used to construct derivatives from $D$,
-$\delta$ and $\Delta$ in version 1, are still available in versions 2
-and 3, but deprecated. A new optional argument in the \texttt{\textbackslash diff}
-command offers these and a host of other possibilities and is now the preferred
-method of forming such variants; see Subsection~\ref{subsec:D-delta-Delta}.
-\item Version 3 adds a command, \texttt{\textbackslash dl} (from \emph{d}ifferentia\emph{l})
-to write differentials like $dx$ that occur in integrals and in other
-contexts in a manner consistent with the form used in derivatives. After
-all, if one is using upright `d's in derivatives, similarly upright `d's
-should occur in these other contexts.\footnote{This rather obvious lack in version 2 was pointed out to me by Sergio Callegari.}
-\item Version 3.1 enables the differential command to be used before forms like
-\texttt{\textbackslash vec\{x\}} (an overlooked possibility causing an
-error in version 3).
-\item Version 3 also provides some simple spacing commands that can be useful
-for tweaking standard spacing.
-\item Version 3.2 fixes a bug in which an ordinary derivative as the differentiand
-of a partial derivative displayed as a partial derivative. It now displays,
-as it should, as an ordinary derivative.
-\item In version 3.2, the differential command \texttt{\textbackslash dl} now
-also allows negative spacing before it.
\end{enumerate}
-\subsubsection*{Note on terminology}
-
-I refer throughout to the quantity or function being differentiated as
-the \emph{differentiand} (in line with \emph{integrand}, \emph{operand},
-etc.).
-
\section{A Rogues' Gallery of derivatives}
-\label{sec:Rogues'-gallery}Browsing through texts on statistical mechanics,
-relativity and classical mechanics I find the following choice examples
-of derivatives `disporting every which way'.
+\label{sec:Rogues'-gallery}Browsing through texts on statistical
+mechanics, relativity and classical mechanics I find the following
+choice examples of derivatives `disporting every which way'.
Multi-character variables of differentiation un-parenthesized:
@@ -173,29 +156,31 @@ Multi-character variables of differentiation parenthesized:
\begin{equation}
\diffp H{\displaystyle \diffp S{q_{k}}[]},\quad\diffp\varepsilon{(1/\Theta)}.\label{eq:eg2}
\end{equation}
-Higher-order derivatives where the parentheses do not or do include the
-operator:
+Higher-order derivatives where the parentheses do not or sometimes
+do include the operator:
\begin{equation}
\diffp[2]q{\frac{1}{\Theta}},\quad\diffp[2]q{1/\Theta},\quad\diffp[2]\varepsilon{a_{i}},\quad\diff.wrapall.[2]{\phi^{i}(x^{i})}{x^{i}}.\label{eq:eg3}
\end{equation}
-Should the $d$ or $\partial$ be included within the parentheses, as in
-the last of (\ref{eq:eg3}), or not, as in the others? Logic says `yes';
-practice suggests (generally) `no'.
+Should the $d$ or $\partial$ be included within the parentheses,
+as in the last of (\ref{eq:eg3}), or not, as in the others? Logic
+says `yes'; practice suggests (generally) `no'.
Indicating a point of evaluation is similarly varied:
\begin{equation}
\diff.pvrule.\phi\varepsilon[\varepsilon=\varepsilon_{0}],\quad\diff.pvrule.[2]\phi\varepsilon[\varepsilon=\varepsilon_{0}],\quad\diff.psqbra.{b^{\beta}}{a^{\alpha}}[b=0],\quad\diff.paren.uv[v=0].\label{eq:eg4}
\end{equation}
-ISO 80000-2 (item 2.11.13) favours the last of these -- parentheses --
-for ordinary derivatives. Presumably, partial derivatives should follow
-suit, although parentheses are also used to indicate variables held constant:
+ISO 80000-2 (item 2.11.13) favours the last of these -- parentheses
+-- for ordinary derivatives. Presumably, partial derivatives should
+follow suit, although parentheses are also used to indicate variables
+held constant:
\begin{equation}
\diffp*{\frac{P}{T}}U[V],\quad\diffp S{N_{2}}[U,V,N_{1}],\quad\diffp S/T[V].\label{eq:eg5}
\end{equation}
Other symbols besides $d$ and $\partial$ are used to denote derivative-like
-quantities. From introductory calculus, classical mechanics and thermodynamics
-come $\delta$ and $\Delta$, from fluid mechanics comes $D$:
+quantities. From introductory calculus and from classical mechanics
+and thermodynamics come $\delta$ and $\Delta$, from fluid mechanics
+comes $D$:
\begin{equation}
\diff.delta.yx,\quad\diff.D.\rho t,\quad\diff.pDelta.UT[V],\quad\diff.Delta.U/T,\quad\diff.delta.{\mathcal{L}}{\eta^{(r)}}.\label{eq:eg6}
\end{equation}
@@ -205,465 +190,597 @@ There are those, like the International Organization for Standardization
\begin{equation}
\diff.up.yx.\label{eq:eg11}
\end{equation}
-When the differentiand is too big or awkward to sit in the numerator and
-is appended to the operator, the $d$ or $\partial$ in the numerator is
-generally centred -- but not always. In texts prior to the age of computerised
-typesetting one will sometimes find the symbol pushed to the \emph{left}:
+When the differentiand is too big or awkward to sit in the numerator
+and is appended to the operator, the $d$ or $\partial$ in the numerator
+is generally centred -- but not always. In texts prior to the age
+of computerised typesetting one will sometimes find the symbol pushed
+to the \emph{left}:
\begin{equation}
\diff.pleft.*{\diffp{x^{i^{*}}}{x^{k^{*}}}{}}{x^{l^{*}}},\quad\diff.left.*{\left(\frac{m\mathbf{q}_{x}}{\sqrt{1-q^{2}}}\right)}{t}.\label{eq:eg12}
\end{equation}
The observant will note an italic adjustment with the first expression,
-so that the $\partial$ in the numerator and the $\partial$ in the denominator
-line up in a slanting column, but no such adjustment for the $d$-s in
-the second derivative.
+so that the $\partial$ in the numerator and the $\partial$ in the
+denominator line up in a slanting column, but no such adjustment for
+the $d$-s in the second derivative.
-And finally, the operator in the numerator may differ from that in the
-denominator. For instance, in tensor calculus acceleration is sometimes
-written
+Then there is the case when the operator in the numerator differs
+from that in the denominator. For instance, in tensor calculus acceleration
+is sometimes written
\[
\diff.nabla.{v^{i}}t=\diff{v^{i}}t+\Gamma_{k\hphantom{i}h}^{\hphantom{k}i}v^{h}\diff{y^{k}}t
\]
-where $\nabla v^{i}$ is the `absolute differential' of the velocity $v^{i}$.
+where $\nabla v^{i}$ is the `absolute differential' of the velocity
+$v^{i}$.
Version 2 or later of the \texttt{diffcoeff} package has the generative
-power to cope with all these variations -- see Section~\ref{sec:Changing-defaults}
--- although it is unlikely an author should need to call on this capacity
-to anything like the extent required for this Rogues' Gallery.
+power to cope with all these variations -- see \ref{sec:Changing-defaults}
+-- although it is unlikely an author should need to call on this
+capacity to anything like the extent required for this Rogues' Gallery.
+
+Finally and new with version 4 of \texttt{diffcoeff}, is the ability
+to insert space before the differentiand, something that had to be
+done explicitly by the user before. One way of thinking of a derivative
+is as an operator $\diff{}x$ applied to a function $F(x)$ producing
+another function $F'(x)$, a \emph{derived }function, the derivative.
+Although the original function is included in the numerator of the
+differential coefficient, a small space between the $d$ and $F$
+feels natural to separate the thing operated on from the thing operating:
+\[
+F'(x)=\diff!{F(x)}x.
+\]
+\texttt{diffcoeff} can now produce such spaced derivatives, either
+as the default behaviour or at explicit request.
+
+\newpage{}
-\section{Ordinary derivatives \label{sec:Ordinary-derivatives}}
+\section{Ordinary derivatives \protect\label{sec:Ordinary-derivatives}}
-Writing\textbf{ }\texttt{\textbackslash diff\{y\}\{x\}} will produce $\diff{y}{x}$
-in text style (i.e., placed between \texttt{\$ \$}) or
+Writing\textbf{ }\texttt{\textbackslash diff\{y\}\{x\}} will produce
+$\diff{y}{x}$ in text style (i.e., placed between \texttt{\textbackslash (
+\textbackslash )} or \texttt{\$ \$}) or
\[
\diff{y}{x}
\]
-in display style (i.e., placed between \texttt{\textbackslash{[} \textbackslash{]}}
-). In fact \texttt{\textbackslash diff yx} (omitting the braces) will
-produce these results, with a saving on keystrokes. The braces are needed
-only when an argument -- differentiand, variable of differentiation --
-is more than a single token.
+in display style (i.e., placed between \texttt{\textbackslash{[}
+\textbackslash{]}} ). In fact \texttt{\textbackslash diff yx} (omitting
+the braces) will produce these results, with a saving on keystrokes.
+The braces are needed only when an argument -- the differentiand
+or the variable of differentiation -- is multi-token.
\begin{itemize}
\item If you want upright `$\mathrm{d}$'s as default, as ISO 80000-2 recommends,
-rather than the math-italic `$d$'s used here, this can easily be done;
-see Section~\ref{sec:Changing-defaults} on changing default settings.
+rather than the math-italic `$d$'s used here, this can easily be
+done with the package option \texttt{ISO}; see \ref{sec:Changing-defaults}
+on changing default settings.
\end{itemize}
For inclusion in a line of text you might prefer to use a slash-fraction
form of derivative. That is achieved by inserting a slash, `/', between
numerator and denominator arguments: \texttt{\textbackslash diff\{\textbackslash ln
-x\}/x} produces $\diff{\ln x}/x$. (Braces are required for the numerator
-in this case since it contains more than one token.)
-
-\subsection{Order of differentiation}
-
-An optional first argument allows the order of differentiation to be specified.
-The order need not be a number; an algebraic order of differentiation is
-perfectly acceptable as is a mix of the two:
-\begin{example}
-\textbackslash diff{[}2{]}yx $\Longrightarrow\quad{\displaystyle \diff[2]yx,}$\medskip{}
-
-\textbackslash diff{[}n+1{]}yx $\Longrightarrow\quad{\displaystyle \diff[n+1]yx}.$
-\end{example}
-
-As mentioned, the braces can be and have been omitted around the $x$ and
-$y$; the square brackets around the optional argument, the order of differentiation,
-are essential. For a first-order derivative, no optional argument is needed
-and entering \texttt{1} as the optional argument has no effect:
-\begin{example}
-\textbackslash diff{[}1{]}yx $\Longrightarrow\quad{\displaystyle \diff[1]yx.}$
-\end{example}
-
-\noindent In slash style, \texttt{\textbackslash diff{[}2{]}y/x} produces
-$\diff[2]y/x$, and \texttt{\textbackslash diff{[}n+1{]}y/x} produces
-$\diff[n+1]y/x$.
-
-\subsection{Multi-character variables of differentiation}
-
-Differentiating a function of a function may involve a multi-character
-differentiation variable. For instance, to differentiate $\ln\sin x$ in
-$x$ means forming the product
-\begin{example}
-\textbackslash diff\{\textbackslash ln\textbackslash sin x\}\{\textbackslash sin
-x\}\textbackslash diff\{\textbackslash sin x\}x $\Longrightarrow\quad{\displaystyle \diff{\ln\sin x}{\sin x}\diff{\sin x}x.}$
-\end{example}
-
-\noindent Forming the \emph{second} derivative of $\ln\sin x$ will now
-involve forming (among other quantities)
-\begin{example}
-\noindent \textbackslash diff{[}2{]}\{\textbackslash ln\textbackslash sin
-x\}\{\textbackslash sin x\} $\Longrightarrow\quad{\displaystyle \diff[2]{\ln\sin x}{\sin x}.}$
-\end{example}
-
-\noindent Parentheses have been inserted automatically by \texttt{diffcoeff}
-around $\sin x$ in the denominator to avoid any visual hint that we are
-differentiating in the sine of the square of $x$.
-
-The question is: are the parentheses in the right place? Logically, no.
-They should include the $d$: $(d\sin x)^{2}$ -- it is the differential
-$d\sin x$ that is of the second order. But as the examples in the Rogues'
-Gallery show -- see particularly (\ref{eq:eg3}) -- the inclination seems
-to be to do otherwise. This may be because one wants, in any case, to parenthesise
-the variable. A second, outer pair of parentheses then seems too fussy
-and detracts from comprehending the symbol `at a glance':
+x\}/x} produces $\diff{\ln x}/x$. Braces are required for the numerator
+in this case since it contains more than one token.
+
+\subsection{Spacing before the differentiand}
+
+\label{subsec:Spacing-before-derivand}There are (at least) two different
+ways in which we think of derivatives.\footnote{I thank Hans Schlein for first raising this issue with me and for
+subsequent thoughtful comments. } We are all familiar with the argument presented in elementary calculus
+books where a curve is shown, and a point on the curve through which
+a chord has been drawn. The chord is a side -- the hypotenuse --
+of a small right-angled triangle, the other sides having lengths $\delta x$
+and $\delta y$ and being parallel to the coordinate axes. The slope
+of the chord is $\diffd yx$. By drawing smaller and smaller chords
+through the point, the ratio $\diffd yx$ approaches the slope of
+the tangent to the curve at the point. We write
\[
-\diff.wrapall.[2]{f(x)}{(1/x)}.
+\diff yx
\]
+for the limit of $\diffd yx$. It is natural to think of $\dl y$
+and $\dl x$ as tiny lengths, like $\delta y$ and $\delta x$, in
+which case it would be quite wrong to insert space between the $d$
+and the $y$ (let alone the $d$ and the $x$). $dy$ is a single
+object, called a differential, and we write expressions like
+\begin{centred}
+\verb`\[ dy=\diff yx dx \]` $\Longrightarrow$
+\[
+\dl y=\diff yx\dl x
+\]
+\end{centred}
+and justly call the `fraction' in this expression a differential
+coefficient.
+
+But there is another way of viewing differentiation: as a process
+producing (or \emph{deriving}) one function, $f'(x)$, from another,
+$f(x)$. Here the sense is of applying $\diff{}x$ to $f(x)$. Although
+we include $f(x)$ in the numerator it is not attached to the $d$
+and should be separated from it by a small space:
+\begin{centred}
+\verb`\[ f'(x)=\diff!{f(x)}x \]` $\Longrightarrow$
+\[
+f'(x)=\diff!{f(x)}x.
+\]
+\end{centred}
+Here the `fraction' on the right is another name for the derived
+function $f'$ and is justly called the derivative of $f$. As you
+can see a small space has been inserted between the $d$ and the $f$
+in the numerator. By default the space is \texttt{3 mu} but with the
+ability to stretch \texttt{1 mu} or shrink\texttt{ 2 mu}{\ttfamily\footnote{In \TeX -speak, \texttt{3mu plus 1mu minus 2mu}. }}
+as \TeX{} adjusts lines to fit on the page. (A `mu' is a `math unit'
+and is one eighteenth of a quad.) To achieve this result I have inserted
+an exclamation mark \verb`!` before the braces delimiting the differentiand.
+\begin{itemize}
+\item You may want all or most of your derivatives to have this space and
+therefore will not want to be inserting exclamation marks in every
+\texttt{\textbackslash diff} command. The \texttt{spaced} package
+option switches the default behaviour to spaced derivatives (in which
+case the \texttt{!} switch now creates an \emph{un-spaced} derivative).
+The size of the space inserted by default can be easily changed; see
+\ref{sec:Changing-defaults}.
+\end{itemize}
+The present document uses the un-spaced default. For backwards compatibility
+(and perhaps because the author has done this for the last 60 years),
+this is the \textquoteleft out-of-the-box\textquoteright{} default
+that \texttt{diffcoeff} uses. Authors should make a habit of using
+one form predominantly. (There is also the possibility which I haven't
+emphasized of spacing multi-token differentiands and leaving single-token
+differentiands unspaced; see \ref{subsec:A-final-flourish}.)
+
+Slash-form derivatives also allow space before the differentiand.
+By default this has the same value as applied to the fraction form
+of derivative (but can be changed; see \ref{sec:Changing-defaults}):
+\begin{centred}
+\verb`$ \diff!{\ln\sin x}/x $` $\Longrightarrow$ $ \diff!{\ln\sin x}/x$.
+\end{centred}
+The \verb`\diff` command has other optional arguments (e.g. to specify
+the order of differentiation) but always the exclamation mark, if
+used, immediately precedes the differentiand. It is the positioning
+of the differentiand that it affects after all and its placement immediately
+before that argument seems natural.
+
+\subsubsection{Ligatures: }
+
+Prior to v.4 of \texttt{diffcoeff}, \texttt{\textbackslash diff fx}
+produced the tight pairing evident in
+\[
+\frac{df}{dx}.
+\]
+This was a bug. From version 4.0 of \texttt{diffcoeff}, such ligatures
+are prevented: \verb`\[ \diff fx \]` $\Longrightarrow$ \[ \diff fx.\]
-Customary but illogical notations are familiar in mathematics -- think
-of the position of the superscripts in an identity like $\sin^{2}\theta+\cos^{2}\theta=1$.
-But, like other features of the derivative, the manner of this wrapping
-in parentheses of long variables for \emph{higher order} derivatives is
-customisable; see Section~\ref{sec:Changing-defaults}.
-
-For first order derivatives, parenthesising does not occur. If you want
-the variable of differentiation to be parenthesised, you need to insert
-them yourself:
-\begin{example}
-\textbackslash diff \{f(x)\}\{1/x\}, \textbackslash quad\textbackslash diff
-\{f(x)\}\{(1/x)\} $\Longrightarrow\quad{\displaystyle \diff{f(x)}{1/x},\quad\diff{f(x)}{(1/x)}.}$
-\end{example}
-
-
-\subsubsection{Minutiae of spacing}
+\subsubsection{Spacing commands}
-You may find the spacing between the `d' and the `f' in the last example
-uncomfortably close. The \texttt{diffcoeff} package offers four simple
-spacing commands to fine-tune the display. These are
+\label{subsec:Spacing-commands}The \texttt{diffcoeff} package also
+offers four simple spacing commands to fine-tune the display of derivatives
+and of other quantities. These are
\begin{description}
\item [{\texttt{\textbackslash negmu}}] insert spacing of $-1$ mu
-\item [{\texttt{\textbackslash nilmu}}] insert spacing of $0$ mu
+\item [{\texttt{\textbackslash nilmu}}] insert spacing of $0$ mu (cf.
+use of an empty brace pair \texttt{\textbf{\{\}}} )
\item [{\texttt{\textbackslash onemu}}] insert spacing of $1$ mu
\item [{\texttt{\textbackslash twomu}}] insert spacing of $2$ mu
\end{description}
-Thus for the last example, inserting \texttt{\textbackslash nilmu} and
-\texttt{\textbackslash onemu} in the appropriate places produces
-\begin{example}
-\textbackslash diff \{\textbackslash nilmu f(x)\}\{\textbackslash onemu
-1/x\}, \textbackslash quad \textbackslash diff \{\textbackslash nilmu
-f(x)\}\{(1/x)\} $\Longrightarrow\quad{\displaystyle \diff{\nilmu f(x)}{\onemu1/x},\quad\diff{\nilmu f(x)}{(1/x)}.}$
-\end{example}
-
\subsection{Appending the differentiand: \texttt{\textbackslash diff{*}}}
-Some differentiands are too big or awkward to be placed neatly in the numerator
-of a derivative and it is natural to append them to a preceding differential
-operator. One way to do this is to leave the numerator argument empty in
-the \texttt{\textbackslash diff} command and follow the command with the
-differentiand. A better way is to star the \texttt{\textbackslash diff}
-command. This tells \texttt{diffcoeff} to append the differentiand. Thus
-suppose the differentiand is a polynomial, say $ax^{2}+bx+c$. Add a star
-(an asterisk) to the \texttt{\textbackslash diff} command:
-\begin{example}
-\textbackslash diff{*}\{(ax\textasciicircum 2+bx+c)\}x $\Longrightarrow\quad{\displaystyle \diff*{(ax^{2}+bx+c)}x.}$
-\end{example}
-
-A virtue of using an asterisk is that if one isn't sure whether a differentiand
-should be appended or not, it is an easy matter to simply insert or delete
-the asterisk to compare the results. For example, a second derivative is
-an iterated derivative -- one in which a derivative forms the differentiand
-of another derivative:
-\begin{example}
-\textbackslash diff{[}2{]}yx = \textbackslash diff{*}\{\textbackslash diff
-yx\}x $\Longrightarrow\quad{\displaystyle \diff[2]yx=\diff*{\diff yx}x},$
-\end{example}
-
+Some differentiands are too big or awkward to be placed neatly in
+the numerator of a derivative and it is natural to append them to
+a preceding differential operator. One way to do this is to leave
+the numerator argument empty in the \texttt{\textbackslash diff}
+command and follow the command with the differentiand. A better way
+is to star the \texttt{\textbackslash diff} command. This tells \texttt{diffcoeff}
+to append the differentiand. Thus suppose the differentiand is a polynomial,
+say $ax^{2}+bx+c$. Add a star (an asterisk) to the \texttt{\textbackslash diff}
+command:
+\begin{centred}
+\verb`\[ \diff*{(ax^2+bx+c)}x \]` $\Longrightarrow$ \[\diff*{(ax^{2}+bx+c)}x\]
+\end{centred}
+With the \texttt{!} switch or \texttt{spaced} package option, additional
+space (by default \texttt{3mu plus 1mu minus 2mu}) is inserted between
+the operator and the differentiand:
+\begin{centred}
+\verb`\[ \diff*!{(ax^2+bx+c)}x \]` $\Longrightarrow$ \[\diff*!{(ax^{2}+bx+c)}x.\]
+\end{centred}
+A virtue of using an asterisk to append the differentiand is that
+if one isn't sure whether a differentiand should be appended or not,
+it is an easy matter to simply insert or delete the asterisk to compare
+the results. For example, a second derivative is an iterated derivative
+-- one in which a derivative forms the differentiand of another derivative:
+\begin{centred}
+\verb`\[ \diff[2]yx = \diff*{\diff yx}x \]` $\Longrightarrow$ \[ \diff[2]yx=\diff*{\diff yx}x \]
+\end{centred}
\noindent which is more elegant to my eye than
-\begin{example}
-\noindent \textbackslash diff{[}2{]}yx = \textbackslash diff\{\textbackslash diff
-yx\}x $\Longrightarrow\quad{\displaystyle \diff[2]yx=\diff{\diff yx}x},$
-\end{example}
-
+\begin{centred}
+\noindent \verb`\[ \diff[2]yx = \diff!{\diff yx}x \]` $\Longrightarrow$
+\[ \diff[2]yx=\diff!{\diff yx}x \]
+\end{centred}
\noindent although whether the \emph{meaning} is clearer is moot.\emph{
-}It is easy to switch between the two forms on the right, simply by inserting
-or removing the asterisk.
+}It is easy to switch between the two forms on the right, simply by
+inserting or removing the asterisk.
In slash style with the star option, the polynomial example becomes
-\begin{example}
-\textbackslash diff{*}\{(ax\textasciicircum 2+bx+c)\}/x $\Longrightarrow\quad\text{\ensuremath{{\displaystyle (\diff{}/{x})(ax^{2}+bx+c)}}, }$
-\end{example}
-
-\noindent where the parentheses around the differential operator are automatically
-inserted by \texttt{diffcoeff}. Like other elements of automatic formatting,
-this is user-adjustable; see Section~\ref{sec:Changing-defaults}.
-
-\subsection{Point of evaluation\label{subsec:Point-of-evaluation}}
-
-If you want to specify a point at which the derivative is evaluated, append
-a final optional argument. Note that there \emph{must be no space} before
-the left square bracket of the argument:
-\begin{example}
-\textbackslash diff{[}2{]}yx{[}0{]} $\Longrightarrow\quad{\displaystyle \diff[2]yx[0]}$
-\end{example}
-
-\noindent If a space does slip in before the final optional argument, it
-will not cause a \LaTeX{} error. Instead, the argument will be treated as
-a square-bracketed mathematical expression following the derivative, and
-typeset as such.
+\begin{centred}
+\verb`\[ \diff*{(ax^2+bx+c)}/x \]` $\Longrightarrow$ \[ \diff*{(ax^2+bx+c)}/x \]
+\end{centred}
+\noindent where the parentheses around the differential operator are
+automatically inserted by \texttt{diffcoeff}. Like other elements
+of automatic formatting, this is user-adjustable; see \ref{sec:Changing-defaults}.
+
+With the \texttt{!} switch or \texttt{spaced} package option, this
+becomes
+\begin{centred}
+\verb`\[ \diff*!{(ax^2+bx+c)}/x \]` $\Longrightarrow$ \[ \diff*!{(ax^2+bx+c)}/x \]
+\end{centred}
+
+\subsection{Point of evaluation\protect\label{subsec:Point-of-evaluation}}
+
+If you want to specify a point at which the derivative is evaluated,
+append a final optional argument. Note that there \emph{must be no
+space} before the left square bracket of the argument:\footnote{In v.1 of \texttt{diffcoeff}, this was brace-delimited. From v.2,
+square-brackets have been used and braces deprecated. From v.4, braces
+are no longer accepted.}
+\begin{centred}
+\verb`\[ \diff[2]yx[0] \]` $\Longrightarrow\quad{\displaystyle \diff[2]yx[0]}$
+\end{centred}
+\noindent If a space does slip in before the final optional argument,
+it will not cause a \LaTeX{} error. Instead, the argument will be treated
+as a square-bracketed mathematical expression following the derivative,
+and typeset as such.
\begin{itemize}
\item If you prefer to use subscripted \emph{parentheses} around the derivative
-to indicate a point of evaluation -- as ISO 80000-2 recommends -- then
-this can easily be done; see Section~\ref{sec:Changing-defaults} on changing
-default settings. Or use the \texttt{ISO} package option; see the introduction.
+to indicate a point of evaluation -- as ISO 80000-2 recommends --
+then this can easily be done; see \ref{sec:Changing-defaults} on
+changing default settings. Or, more simply, use the \texttt{ISO} package
+option.
\end{itemize}
Because the slash form spreads the derivative out horizontally, parentheses
are preferred here to indicate a point of evaluation:
-\begin{example}
-\textbackslash diff\{\textbackslash ln sin x\}/\{sin x\}{[}x=\textbackslash pi/6{]}
-$\Longrightarrow\quad{\displaystyle \diff{\ln\sin x}/{\sin x}[x=\pi/6]}$
-\end{example}
-
-\noindent A vertical rule (or `pipe') can become too remote from the opening
-$d$ of the differential coefficient: $\diff.svrule.{\ln\sin x}/{\sin x}[x=\pi/6]$;
+\begin{centred}
+\verb`$ \diff{\ln sin x}/{sin x}[x=\pi/6] $` $\Longrightarrow$ $ \diff{\ln\sin x}/{\sin x}[x=\pi/6] $.
+\end{centred}
+\noindent A vertical rule (or `pipe') can easily become too remote
+from the opening $d$ of the differential coefficient: $\diff.svrule.{\ln\sin x}/{\sin x}[x=\pi/6]$;
parentheses tie the whole cluster of symbols together.
\subsubsection{Superscripts}
It is easy to add a superscript to a derivative to indicate evaluation
at two points and the difference between the values:
-\begin{example}
-\textbackslash diff \{\textbackslash sin x\}x{[}0{]}\textasciicircum\{\textbackslash pi/2\}
-${\displaystyle \Longrightarrow\quad\diff{\sin x}x[0]^{\pi/2}}$
-\end{example}
+\begin{centred}
+\verb`\[ \diff {\sin x}x[0]^{\pi/2} \]` ${\displaystyle \Longrightarrow}$
+\[ \diff{\sin x}x[0]^{\pi/2} \]
+\end{centred}
+\noindent If you want only the superscript, no subscript, include
+the final optional argument but leave it empty. Thus, for a particle
+of mass $m$ moving along a line, distance $x$ at time $t$, the
+kinetic energy is:
+\begin{centred}
+\noindent \verb`$ \tfrac 12 m \diff x/t[]^2 $` $\Longrightarrow$
+$\tfrac{1}{2}m\diff x/t[]^{2}$.
+\end{centred}
-\noindent If you want only the superscript, no subscript, include the final
-optional argument but leave it empty. Thus, for a particle of mass $m$
-moving along a line, distance $x$ at time $t$, the kinetic energy is:
-\begin{example}
-\noindent \textbackslash tfrac 12 m \textbackslash diff x/t{[}{]}\textasciicircum 2
-$\Longrightarrow\quad{\displaystyle \tfrac{1}{2}m\diff x/t[]^{2}}.$
-\end{example}
+\subsection{Order of differentiation}
+
+An optional first argument allows the order of differentiation to
+be specified. The order need not be a number; an algebraic order of
+differentiation is perfectly acceptable as is a mix of the two:
+\begin{centred}
+\verb`\[ \diff[2]yx \]` $\Longrightarrow$ \[ \diff[2]yx,\]\verb`\[ \diff[n+1]yx \]`
+$\Longrightarrow$ \[ \diff[n+1]yx.\]
+\end{centred}
+As mentioned, the braces can be and have been omitted around the $x$
+and $y$; the square brackets around the optional argument, the order
+of differentiation, are essential. For a first-order derivative, no
+optional argument is needed and entering \texttt{1} as the optional
+argument has no effect:
+\begin{centred}
+\verb`$ \diff[1]yx $` $\Longrightarrow$$\diff[1]yx$.
+\end{centred}
+In slash style, \texttt{\$\textbackslash diff{[}2{]}y/x\$} produces
+$\diff[2]y/x$, and \texttt{\$\textbackslash diff{[}n+1{]}y/x\$}
+produces $\diff[n+1]y/x$.
+\subsection{Multi-character variables of differentiation}
+
+Differentiating a function of a function may involve a multi-character
+differentiation variable. For instance, to differentiate $\ln\sin x$
+in $x$ means forming the product
+\begin{centred}
+\verb`\[ \diff!{\ln\sin x}{\sin x}\diff{\sin x}x \]` $\Longrightarrow$
+\[\diff!{\ln\sin x}{\sin x}\diff{\sin x}x.\]
+\end{centred}
+\noindent (Although I am mainly using un-spaced differentiands in
+this document, a space before the differentiand in the first of these
+derivatives -- the \verb`!` switch -- improves the appearance of
+the expression to my eye.)
+
+Forming the \emph{second} derivative of $\ln\sin x$ will now involve
+forming (among other quantities)
+\begin{centred}
+\noindent \verb`\[\diff[2]{\ln\sin x}{\sin x}\]` $\Longrightarrow$
+\[\diff[2]{\ln\sin x}{\sin x}\]
+\end{centred}
+\noindent Parentheses have been inserted automatically by \texttt{diffcoeff}
+around $\sin x$ in the denominator to avoid any visual hint that
+we are differentiating in the sine of $x^{2}$.
+
+The question is: are the parentheses in the right place? Logically,
+no. They should include the $d$: $(d\sin x)^{2}$ -- it is the differential
+$d\sin x$ that is of the second order. But as the examples in the
+Rogues' Gallery show -- see particularly (\ref{eq:eg3}) -- the
+inclination seems to be to do otherwise. This may be because one wants,
+in any case, to parenthesise the variable. A second, outer pair of
+parentheses then seems too fussy and detracts from comprehending the
+symbol `at a glance':
+\[
+\diff.wrapall.[2]{f(x)}{(1/x)}.
+\]
-\section{Partial derivatives\label{sec:Partial-derivatives}}
-\noindent \begin{flushleft}
-Partial derivatives follow the same pattern as ordinary derivatives, with
-some extensions. The command this time is \texttt{\textbackslash diffp}.
-Thus \texttt{\textbackslash diffp\{F\}\{x\}}, or, with a saving on keystrokes,\texttt{
-\textbackslash diffp Fx}, produces $\diffp Fx$ in text style and
+Customary but illogical notations are familiar in mathematics --
+think of the position of the superscripts in an identity like $\sin^{2}\theta+\cos^{2}\theta=1$.
+But, like other features of the derivative, the manner of this wrapping
+in parentheses of long variables for \emph{higher order} derivatives
+is customisable; see \ref{sec:Changing-defaults}.
+
+For first order derivatives, parenthesising does not occur. If you
+want the variable of differentiation to be parenthesised, you need
+to insert them yourself:
+\begin{centred}
+\verb`\[\diff {f(x)}{1/x}, \quad \diff {f(x)}{(1/x)}.\]` $\Longrightarrow$
+\[ \diff {f(x)}{1/x}, \quad\diff {f(x)}{(1/x)}.\]
+\end{centred}
+
+\section{Partial derivatives\protect\label{sec:Partial-derivatives}}
+
+\noindent Partial derivatives follow the same pattern as ordinary
+derivatives, with some extensions. The command this time is \texttt{\textbackslash diffp}.
+Thus \texttt{\textbackslash diffp\{F\}\{x\}}, or, with a saving on
+keystrokes,\texttt{ \textbackslash diffp Fx}, produces $\diffp Fx$
+in text style and
\[
\diffp{F}{x}
\]
-in display style. (As for \texttt{\textbackslash diff}, the omission of
-braces is possible when the differentiand or the differentiation variable
-are single tokens.) As for \texttt{\textbackslash diff}, there is a slash
-form, generally preferred for inline use, \texttt{\textbackslash diffp
+in display style. (As for \texttt{\textbackslash diff}, the omission
+of braces is possible when the differentiand or the differentiation
+variable are single tokens.) As for \texttt{\textbackslash diff},
+there is a slash form, generally preferred for inline use, \texttt{\textbackslash diffp
F/x}, displaying as $\diffp F/x$. Given that \texttt{\textbackslash partial}
-takes 8 keystrokes to type, the slash form \emph{does }economise on keystrokes
-for a partial derivative.
-\par\end{flushleft}
-
-\begin{flushleft}
-Again an optional argument allows the specification of the order of differentiation
-and it may be numeric or algebraic or a mix of the two:
-\par\end{flushleft}
-\begin{example}
-\textbackslash diffp{[}3{]}F/x , \textbackslash quad \textbackslash diffp{[}n{]}F/x
-$\Longrightarrow\quad{\displaystyle {\displaystyle {\displaystyle \diffp[3]F/x}},\quad{\displaystyle \diffp[n]F/x.}}$\medskip{}
- \textbackslash diffp{[}n+1{]}Fx $\Longrightarrow\quad{\displaystyle {\displaystyle \diffp[n+1]Fx,}}$
-\end{example}
-
+takes 8 keystrokes to type, the slash form \emph{does }economise on
+keystrokes for a partial derivative.
+
+With either the \verb`spaced` package option (see \ref{subsec:Package-options})
+or the \verb`!` switch a space, defaulting to \verb`3 mu` with some
+stretch and shrink, can be inserted before the differentiand: \verb`\[ \diffp!{F(x,y)}x \]`
+$\Longrightarrow$ \[ \diffp!{F(x,y)}x. \]
+
+\noindent (But note that if the \verb`spaced` package option is used,
+the \verb`!` switch \emph{removes} any extra space.)
+
+Again an optional argument allows the specification of the order of
+differentiation which may be numeric or algebraic or a mix of the
+two:
+\begin{centred}
+\verb`\[ \diffp[3]F/x , \quad \diffp[n]F/x \]` $\Longrightarrow$
+\[\diffp[3]F/x , \quad \diffp[n]F/x\] \verb`\[ \diffp[n+1]Fx. \]`
+$\Longrightarrow$ \[ \diffp[n+1]Fx. \]
+\end{centred}
\subsection{Variables held constant}
-In a subject like thermodynamics, there is a need to indicate which variable
-or variables are held constant when the differentiation occurs. To show
-this, append a final square-bracketed optional argument and ensure that
-it follows \emph{immediately} on the preceding mandatory argument. A space
-here will detach the argument from the derivative and result in it being
-treated as a mathematical expression following the derivative. Thus to
-differentiate the entropy $S$ in temperature $T$ while holding the volume
-$V$ constant, write
-\begin{example}
-\textbackslash diffp ST{[}V{]} $\Longrightarrow\quad{\displaystyle \diffp ST[V]}$
-\end{example}
-
+In a subject like thermodynamics, there is a need to indicate which
+variables are held constant when the differentiation occurs. To show
+this, append a final square-bracketed optional argument and ensure
+that it follows \emph{immediately} on the preceding mandatory argument.
+A space here will detach the argument from the derivative and result
+in it being treated as a mathematical expression following the derivative.
+Thus to differentiate the entropy $S$ in temperature $T$ while holding
+the volume $V$ constant, write
+\begin{centred}
+\verb`\[ \diffp ST[V] \]` $\Longrightarrow$ \[ \diffp ST[V]. \]
+\end{centred}
\noindent In slash form the same expression looks like
-\begin{example}
-\noindent \textbackslash diffp S/T{[}V{]} $\Longrightarrow\quad{\displaystyle \diffp{S}/{T}[V]}.$
-\end{example}
-
-This use of a parenthesised, subscripted form to indicate a variable or
-variables held constant, leaves open the question: how do we represent
+\begin{centred}
+\noindent \verb`$ \diffp S/T[V] $` $\Longrightarrow$ $ \diffp S/T[V] $.
+\end{centred}
+This use of a parenthesised, subscripted form to indicate a variable
+or variables held constant, leaves open the question: how do we represent
a point of evaluation? ISO 80000-2 makes no recommendation for \emph{partial}
derivatives; presumably we follow the same practice as their recommendation
for ordinary derivatives:
\begin{example}
-\textbackslash diffp \{F(x,y)\}x{[}(0,0){]} $\Longrightarrow\quad{\displaystyle \diffp{F(x,y)}x[(0,0)]}$
+\verb`\[ \diffp {F(x,y)}x[(0,0)] \]` $\Longrightarrow$ \[ \diffp {F(x,y)}x[(0,0)] \]
\end{example}
-However, you may prefer (as many do) to use a vertical rule for this purpose:
+However, you may prefer (as many do) to use a vertical rule for this
+purpose:
\[
\diff.pvrule.{F(x,y)}x[(0,0)]
\]
-Making this possibility available is discussed in Section~\ref{sec:Changing-defaults}.
-
-An empty final argument produces a parenthesised derivative with no subscript:
-\begin{example}
-\textbackslash diffp yx{[}{]}${\displaystyle \Longrightarrow\quad\diffp yx[]}.$
-\end{example}
-
-\noindent This can be useful sometimes, e.g. for writing Lagrange's equations
-of motion in analytic mechanics:
-\begin{example}
-\noindent \textbackslash diffp L\{q\_k\}-\textbackslash diff{*}\{\textbackslash diffp
-L\{\textbackslash dot\{q\}\_k\}{[}{]}\}t = 0 $\Longrightarrow\quad{\displaystyle \diffp L{q_{k}}-\diff*{\diffp L{\dot{q}_{k}}[]}t}=0.$
-\end{example}
-
+Making this possibility available is discussed in \ref{sec:Changing-defaults}.
+
+An empty final argument produces a parenthesised derivative with no
+subscript,
+\begin{centred}
+\verb`\[ \diffp yx[] \]` ${\displaystyle \Longrightarrow}$ \[ \diffp yx[] \]
+\end{centred}
+\noindent which can be useful sometimes. An instance is the writing
+of Lagrange's equations of motion in analytic mechanics:
+\begin{centred}
+\noindent \verb`\[ \diffp L{q_k}-\diff*{\diffp L{\dot{q}_k}[]}t = 0 \]`
+$\Longrightarrow$ \[ \diffp L{q_k}-\diff*{\diffp L{\dot{q}_k}[]}t = 0. \]
+\end{centred}
\subsubsection{Text-style derivatives}
-The \texttt{diffcoeff} package assumes that derivatives formed as `numerator
-over denominator' will be used in display-style expressions, and that the
-slash form will be used for inline use (text style). This is the familiar
-practice in the literature. If one \emph{does} use the first form in an
-inline expression where a variable is held constant, say \texttt{\textbackslash diffp
-ST{[}V{]}} as here $\diffp ST[V]$, the result is unsatisfactory, the subscript
-too tight on the closing parenthesis and too much space between parentheses
-and derivative. The matter is easily resolved using `variant forms' --
-see Subsection~\ref{subsec:Text-and-script-style} below -- giving, for
-our example, $\diff.ptxt.ST[V]$.
+The \texttt{diffcoeff} package assumes that derivatives formed as
+`numerator over denominator' will be used in display-style expressions,
+and that the slash form will be used for inline use (text style).
+This is the familiar practice in the literature. If one \emph{does}
+use the first form in an inline expression where a variable is held
+constant, say \texttt{\textbackslash diffp ST{[}V{]}} as here $\diffp ST[V]$,
+the result is unsatisfactory, the subscript too tight on the closing
+parenthesis and too much space between parentheses and derivative.
+The matter is easily resolved using `variant forms' -- see \ref{subsec:Text-and-script-style}
+below -- giving, for our example, $\diff.ptxt.ST[V]$.
-\subsection{Appending the differentiand\label{subsec:Partial-appending}}
+\subsection{Appending the differentiand\protect\label{subsec:Partial-appending}}
For a long or awkward differentiand, it is generally better to \emph{append}
it to a preceding differential operator, rather than create a fractional
form with the long expression in the numerator. As with ordinary derivatives,
this is achieved by adding an asterisk to (i.e. by starring) the \texttt{\textbackslash diffp}
-command.
-\begin{example}
-\textbackslash diffp{*}{[}2{]}\{\textbackslash Phi(x,y,z)\}x $\Longrightarrow\quad{\displaystyle \diffp*[2]{\Phi(x,y,z)}x.}$
-\end{example}
-
-\noindent Alternatively you could leave the first mandatory argument empty
-and manually append the differentiand, but by deleting or inserting an
+command.
+\begin{centred}
+\verb`\[ \diffp*[2]{\Phi(x,y,z)}x \]` $\Longrightarrow$ \[ \diffp*[2]{\Phi(x,y,z)}x. \]
+\end{centred}
+With the \verb`spaced` package option, or with the \verb`!` switch
+if the package option is not used (which is the case for this document),
+one gets
+\begin{centred}
+\verb`\[ \diffp*[2]!{\Phi(x,y,z)}x \]` $\Longrightarrow$ \[ \diffp*[2]!{\Phi(x,y,z)}x \]
+\end{centred}
+which is an improvement (to my eye).
+
+Alternatively you could leave the first mandatory argument empty and
+manually append the differentiand, but by deleting or inserting an
asterisk, it is easy to compare the two forms, differentiand-in-the-numerator,
differentiand-appended, and see which is preferable.
In slash form, parentheses are automatically inserted around the differential
operator when the differentiand is appended,
-\begin{example}
-\textbackslash diffp{*}{[}n{]}\{f(x)\}/x $\Longrightarrow\quad{\displaystyle \diffp*[n]{f(x)}/x,}$
-\end{example}
-
-\noindent although this behaviour can be changed (Section~\ref{sec:Changing-defaults}
+\begin{centred}
+\verb`\[ \diffp*[n]{f(x)}/x \]` $\Longrightarrow$ \[ \diffp*[n]{f(x)}/x, \]
+\end{centred}
+\noindent although this behaviour can be changed (\ref{sec:Changing-defaults}
again).
If you wish to both append the differentiand \emph{and} indicate variables
held constant, then the starred form is much the easier way to achieve
this. Thus, to express a relation in thermodynamics,
-\begin{example}
-\textbackslash diffp{*}\{\textbackslash frac PT\}U{[}V{]} = \textbackslash diffp{*}\{\textbackslash frac
-1T\}V{[}U{]} $\Longrightarrow\quad{\displaystyle \diffp*{\frac{P}{T}}U[V]=\diffp*{\frac{1}{T}}V[U]}$
-\end{example}
-
+\begin{centred}
+\verb`\[ \diffp*{\frac PT}U[V] = \diffp*{\frac 1T}V[U] \]` $\Longrightarrow$
+\[ \diffp*{\frac PT}U[V] = \diffp*{\frac 1T}V[U], \]
+\end{centred}
\noindent where the starring automatically takes care of the parentheses
and subscripts.
\subsection{Iterated derivatives}
-Derivatives can be the differentiands of derivatives, as seen above when
-writing Lagrange's equations,
-\begin{example}
-\textbackslash diffp L\{q\_k\}-\textbackslash diff{*}\{\textbackslash diffp
-L\{\textbackslash dot\{q\}\_k\}{[}{]}\}t = 0 $\Longrightarrow\quad{\displaystyle \diffp L{q_{k}}-\diff*{\diffp L{\dot{q}_{k}}[]}t}=0.$
-\end{example}
-
-\noindent However, in versions of \texttt{diffcoeff} before version 3.2,
-an ordinary derivative within a partial derivative rendered as a partial
-derivative. That is now corrected, the ordinary derivative rendering correctly:
-\begin{example}
-\textbackslash diffp{*}\{\textbackslash diff\{x\textasciicircum\textbackslash mu\}\{\textbackslash lambda\}\}\{x\textasciicircum\textbackslash sigma\}
-$\Longrightarrow\quad{\displaystyle \diffp*{\diff{x^{\mu}}{\lambda}}{x^{\sigma}}}$
-\end{example}
-
+Derivatives can be the differentiands of derivatives, as seen above
+when writing Lagrange's equations,
+\begin{centred}
+\noindent \verb`\[ \diffp L{q_k}-\diff*{\diffp L{\dot{q}_k}[]}t = 0 \]`
+$\Longrightarrow$ \[ \diffp L{q_k}-\diff*{\diffp L{\dot{q}_k}[]}t = 0. \]
+\end{centred}
+\noindent However, in versions of \texttt{diffcoeff} before version
+3.2, an ordinary derivative within a partial derivative rendered as
+a partial derivative. That is now corrected, the ordinary derivative
+rendering correctly:
+\begin{centred}
+\verb`\[ \diffp*{\diff{x^\mu}{\lambda}}{x^\sigma} \]` $\Longrightarrow$
+\[ \diffp*{\diff{x^\mu}{\lambda}}{x^\sigma}. \]
+\end{centred}
\subsection{Mixed partial derivatives}
-The new thing with partial derivatives, not present with ordinary derivatives,
-is \emph{mixed} partial derivatives, where there is more than one variable
-of differentiation. If each variable is differentiated only to the first
-order, then it is easy to specify the derivative. Suppose $F$ is a function
-of three variables, $x$, $y$ and $z$. Then
-\begin{example}
-\textbackslash diffp F\{x,y,z\} $\Longrightarrow\quad{\displaystyle \diffp F{x,y,z}}.$
-\end{example}
-
-The variables of differentiation are listed in order in a comma list forming
-the second mandatory argument. The total order of differentiation (3 in
-this example) is inserted automatically -- \texttt{diffcoeff} does the
-calculation. There is also a slash form:
-\begin{example}
-\textbackslash diffp F/\{x,y,z\} $\Longrightarrow\quad{\displaystyle \diffp F/{x,y,z}}.$
-\end{example}
-
-If we want to differentiate variables to higher order, then their orders
-need to be specified explicitly. To do so use a comma list for the optional
-argument:
-\begin{example}
-\textbackslash diffp{[}2,3{]}F\{x,y,z\} $\Longrightarrow\quad{\displaystyle \diffp[2,3]F{x,y,z}.}$
-\end{example}
-
-\noindent Notice that the overall order of the derivative -- 6 -- is
-again automatically calculated and inserted as a superscript on the $\partial$
-symbol in the numerator. In this example, the comma list of orders has
-only two members, even though there are three variables. It is assumed
-that the orders given in the comma list apply in sequence to the variables,
-the first order to the first variable, the second to the second variable,
-and so on, and that any subsequent orders not listed in the optional argument
-are, by default, 1. Thus we need to specify only 2 and 3 in the example;
-the order of differentiation of $z$ is 1 by default. But you \emph{cannot}
-use an order specification like \texttt{{[} , ,2{]}}. Instead write \texttt{{[}1,1,2{]}}.\textbf{
-}It is only the \emph{tail} of an order specification which can be omitted.
-
-\subsubsection{Minutiae of spacing (again)\label{subsec:Minutiae-of-spacing}}
-
-In Chapter 18 of the \emph{The\TeX book}, Knuth suggests inserting a thin
-space, \texttt{\textbackslash ,} (or 3 mu), between differentials in appropriate
-contexts, giving as an example $dx\,dy=r\,dr\,d\theta$. In the denominator
-of a derivative, however, that degree of extra spacing seems too great
-(to my eye), interfering with seeing the derivative `as a whole',
+The new thing with partial derivatives, not present with ordinary
+derivatives, is \emph{mixed} partial derivatives, where there is more
+than one variable of differentiation. If each variable is differentiated
+only to the first order, then it is easy to specify the derivative.
+Suppose $F$ is a function of three variables, $x$, $y$ and $z$.
+Then
+\begin{centred}
+\verb`\[ \diffp F{x,y,z} \]` $\Longrightarrow$ \[ \diffp F{x,y,z}, \]
+
+\verb`\[ \diffp !{F(x,y,z)}{x,y,z} \]` $\Longrightarrow$ \[ \diffp !{F(x,y,z)}{x,y,z}. \]
+\end{centred}
+In the second of these I have inserted space before the differentiand
+by using the \verb`!` switch. If the \verb`spaced` package option
+was being used, this would have been done automatically.
+
+The variables of differentiation are listed in order in a comma list
+forming the second mandatory argument. The total order of differentiation
+(3 in this example) is inserted automatically -- \texttt{diffcoeff}
+does the calculation. There is also a slash form:
+\begin{centred}
+\verb`$ \diffp F/{x,y,z} $` $\Longrightarrow$ $ \diffp F/{x,y,z}$.
+\end{centred}
+If we want to differentiate variables to higher order, then their
+orders need to be specified explicitly. To do so use a comma list
+for the optional argument:
+\begin{centred}
+\verb`\[ \diffp[2,3]F{x,y,z} \]` $\Longrightarrow$ \[ \diffp[2,3]F{x,y,z}. \]
+\end{centred}
+\noindent Notice that the overall order of the derivative -- 6 --
+is again automatically calculated and inserted as a superscript on
+the $\partial$ symbol in the numerator. In this example, the comma
+list of orders has only two members, even though there are three variables.
+It is assumed that the orders given in the comma list apply in sequence
+to the variables, the first order to the first variable, the second
+to the second variable, and so on, and that any subsequent orders
+not listed in the optional argument are, by default, 1. Thus we need
+to specify only 2 and 3 in the example; the order of differentiation
+of $z$ is 1 by default. But you \emph{cannot} use an order specification
+like \texttt{{[} , ,2{]}}. Instead write \texttt{{[}1,1,2{]}}.\textbf{
+}It is only the \emph{tail} of an order specification which can be
+omitted.
+
+\subsubsection{Minutiae of spacing (again)\protect\label{subsec:Minutiae-of-spacing}}
+
+In Chapter 18 of the \emph{The\TeX book}, Knuth suggests inserting
+a thin space, {\ttfamily\verb`\,`} (or {\ttfamily\verb`3 mu`}),
+between differentials in appropriate contexts, giving as an example
+$dx\,dy=r\,dr\,d\theta$. In the denominator of a derivative, however,
+that degree of extra spacing seems too great (to my eye), interfering
+with seeing the derivative `as a whole',
\[
\diff.pwide.F{x,y,z},
\]
especially for the slash-form of derivative: $\diff.pwide.F/{x,y,z}$.
-Some spacing is desirable, but less; by default \texttt{diffcoeff} inserts
-2 mu between the differentials in the fraction form of derivative and 1
-mu in the slash form.
+Some spacing is desirable, but less; by default \texttt{diffcoeff}
+inserts \verb`2 mu` between the differentials in the fraction form
+of derivative and \verb`1 mu`\texttt{ }in the slash form.
Should a differentiation occur to higher order and so a variable acquire
-a superscript, an adjustment is made to the extra spacing. By default 1
-mu is subtracted from the default spacing. Thus in
+a superscript, an adjustment is made to the extra spacing. By default
+\verb`1 mu` is subtracted from the default spacing. Thus in
\[
\diffp[2]F{x,y,z},
\]
-2 mu of spacing is inserted between the $\partial y$ and $\partial z$,
-but because the superscript already provides some separation between them,
-only 1 mu is inserted between $\partial x^{2}$ and $\partial y$.
-
-The values used for the spacing and its adjustment in the presence of a
-superscript can be adjusted by the user; see Section~\ref{sec:Changing-defaults}.
-Some other minutiae of spacing are discussed below in Subsection~\ref{subsec:Comma-list-of-vars}
-when the variables themselves are super- or subscripted (as happens in
-tensor calculus, for instance).
+\verb`2 mu` of spacing is inserted between the $\partial y$ and
+$\partial z$, but because the superscript already provides some separation
+between them, only \verb`1 mu` is inserted between $\partial x^{2}$
+and $\partial y$.
+
+The values used for the spacing and its adjustment in the presence
+of a superscript can be changed by the user; see \ref{sec:Changing-defaults}.
+Some other minutiae of spacing are discussed below in \ref{subsec:Comma-list-of-vars}
+when the variables themselves are super- or subscripted (as happens
+in tensor calculus, for instance).
+
+Note that the \verb`!` switch, if used, is inserted \emph{immediately
+before} the differentiand. It is the placement of the differentiand,
+after all, that it is affecting:
+\begin{centred}
+\verb`\[ \diffp[2]!F{x,y,z} \]` $\Longrightarrow$ \[ \diffp[2]!F{x,y,z}. \]
+\end{centred}
\subsubsection{Algebraic orders of differentiation}
-Calculation of the overall order of differentiation still occurs even when
-some or all of the individual orders are algebraic variables rather than
-numbers. For example, differentiating in three variables to orders \texttt{1,
-m+1, m-1},
-\begin{example}
-\textbackslash diffp{[}1,m+1,m-1{]}\{F(x,y,z)\}\{x,y,z\} $\Longrightarrow\quad{\displaystyle \diffp[1,m+1,m-1]{F(x,y,z)}{x,y,z}.}$
-\end{example}
-
+Calculation of the overall order of differentiation still occurs even
+when some or all of the individual orders are algebraic variables
+rather than numbers. For example, differentiating in three variables
+to orders \texttt{1, m+1, m-1},
+\begin{centred}
+\verb`\[ \diffp[1,m+1,m-1]{F(x,y,z)}{x,y,z} \]` $\Longrightarrow$
+\[ \diffp[1,m+1,m-1]{F(x,y,z)}{x,y,z}. \]
+\end{centred}
\subsubsection{Error messages}
-Should you specify \emph{more} orders in the comma list of the order specification
-than there are variables, compilation will fail and an error message will
-be sent to the terminal and \LaTeX{} log . For example, if on line 53 (say)
-of my document I specify \texttt{{[}1,m-1,m+1,2{]}} for the orders of differentiation
-but list only \texttt{\{x,y,z\}} for the variables, the message will be
+Should you specify \emph{more} orders in the comma list of the order
+specification than there are variables, compilation will fail and
+an error message will be sent to the terminal and \LaTeX{} log . For
+example, if on (say) line 53 of my document I specify \texttt{{[}1,m-1,m+1,2{]}}
+for the orders of differentiation but list only \texttt{\{x,y,z\}}
+for the variables, the message will be
\begin{lyxcode}
!~Package~diffcoeff~Error:~4~orders~of~differentiation~
@@ -671,9 +788,9 @@ specified~for~3~variables;~orders~{[}1,m+1,m-1,2{]}
(on~line~53)~for~variables~x,y,z.
\end{lyxcode}
-Should you try using a \emph{number} raised to a power in an order specification,
-it will cause an error. For example, if on line 53 (say) of my document
-I try to form \texttt{\textbackslash diffp{[}2\textasciicircum 2{]}f\{x,y,z\}}
+Should you try using a \emph{number} raised to a power in an order
+specification, it will cause an error. For example, if on line 53
+(say) of my document I try to form \texttt{\textbackslash diffp{[}2\textasciicircum 2{]}f\{x,y,z\}}
compilation will fail with the message
\begin{lyxcode}
!~Package~diffcoeff~Error:~number~followed~by~\textasciicircum ~in~the~
@@ -686,120 +803,118 @@ in~this~case.~Use~the~order-override~option~to~enter~
the~overall~order.
\end{lyxcode}
-Similarly, you cannot use multiplication (\texttt{\textbackslash times}
-or \texttt{{*}})\texttt{ }or division (\texttt{/} or \texttt{\textbackslash div})
-signs after \emph{numbers} in an order specification; only \texttt{+} or
-\texttt{-} or a left parenthesis (see below) are allowed.
+The order-overide option mentioned here is discussed next. Similarly,
+you cannot use multiplication (\texttt{\textbackslash times} or \texttt{{*}})\texttt{
+}or division (\texttt{/} or \texttt{\textbackslash div}) signs after
+\emph{numbers} in an order specification; only \texttt{+} or \texttt{-}
+or a left parenthesis (see below) are allowed.
\subsubsection{The order-override option}
\noindent Perhaps the differentiations are to orders \texttt{{[}2km,m-1,m+1{]}}:
-\begin{example}
-\noindent \textbackslash diffp{[}2km,m-1,m+1{]}\{F(x,y,z)\}\{x,y,z\} $\Longrightarrow\quad{\displaystyle \diffp[2km,m-1,m+1]{F(x,y,z)}{x,y,z}.}$
-\end{example}
-
-\noindent Here the overall order is presented as \texttt{2km+2m}. You might
-prefer this to be presented as \texttt{2m(k+1)}. Although \texttt{diffcoeff}
-takes some steps to present the overall order appropriately, it is not
-a computer algebra system and does not factorise expressions. If you want
-to present the order in a manner distinct from that presented by \texttt{diffcoeff},
-use the \emph{order-override option}.
-
-This is a second optional argument immediately following the order specification.
-For our last example, filling the override option with \texttt{2m(k+1)}
-gives the desired result:
-\begin{example}
-\textbackslash diffp{[}2km,m-1,m+1{]}{[}2m(k+1){]}\{F(x,y,z)\}\{x,y,z\}
-$\Longrightarrow\quad{\displaystyle \diffp[2km,m-1,m+1][2m(k+1)]{F(x,y,z)}{x,y,z}}.$
-\end{example}
-
+\begin{centred}
+\noindent \verb`\[ \diffp[2km,m-1,m+1]{F(x,y,z)}{x,y,z} \]` $\Longrightarrow$
+\[ \diffp[2km,m-1,m+1]{F(x,y,z)}{x,y,z}. \]
+\end{centred}
+\noindent Here the overall order is presented as \texttt{2km+2m}.
+You might prefer this to be presented as \texttt{2m(k+1)}. Although
+\texttt{diffcoeff} takes some steps to present the overall order appropriately,
+it is not a computer algebra system and does not factorise expressions.
+If you want to present the order in a manner distinct from that presented
+by \texttt{diffcoeff}, use the \emph{order-override option}.
+
+This is a second optional argument immediately following the order
+specification. For our last example, filling the override option with
+\texttt{2m(k+1)} gives the desired result:
+\begin{centred}
+\verb`\[ \diffp[2km,m-1,m+1][2m(k+1)]{F(x,y,z)}{x,y,z} \]` $\Longrightarrow$
+\[ \diffp[2km,m-1,m+1][2m(k+1)]{F(x,y,z)}{x,y,z}. \]
+\end{centred}
\noindent As another example, left to its own devices, \texttt{diffcoeff}
produces
-\begin{example}
-\noindent \textbackslash diffp{[}m/2+n/2,m/2,n/2{]}F\{x,y,z\} $\Longrightarrow\quad{\displaystyle \diffp[m/2+n/2,m/2,n/2]F{x,y,z},}$
-\end{example}
-
-\noindent whereas we would like the total order to be presented as $m+n$.
-Using the override option,
-\begin{example}
-\noindent \textbackslash diffp{[}m/2+n/2,m/2,n/2{]}{[}m+n{]}F\{x,y,z\}
-$\Longrightarrow\quad{\displaystyle \diffp[m/2+n/2,m/2,n/2][m+n]F{x,y,z}}.$
-\end{example}
-
+\begin{centred}
+\noindent \verb`\[ \diffp[m/2+n/2,m/2,n/2]F{x,y,z} \]` $\Longrightarrow$
+\[ \diffp[m/2+n/2,m/2,n/2]F{x,y,z}, \]
+\end{centred}
+\noindent whereas we would like the total order to be presented as
+$m+n$. Using the override option,
+\begin{centred}
+\noindent \verb`\[ \diffp[m/2+n/2,m/2,n/2][m+n]F{x,y,z} \]` $\Longrightarrow$
+\[ \diffp[m/2+n/2,m/2,n/2][m+n]F{x,y,z}. \]
+\end{centred}
The order-override option does exactly that: overrides the presentation
of the calculated order with the manually given one. In fact the calculation
-algorithm does not get called at all when the override option is used so
-that one can in this way present the total order in whatever manner one
-wishes or, indeed, add essentially arbitrary material as a superscript
+algorithm does not get called at all when the override option is used
+so that one can in this way present the total order in whatever manner
+one wishes or, indeed, add essentially arbitrary material as a superscript
to the $\partial$ symbol in the numerator.
-\subsubsection{Comma list of variables of differentiation\label{subsec:Comma-list-of-vars}}
-
-In tensor calculus the differentiations are almost always in terms of super-
-or subscripted coordinates. In many other contexts this is the case too
--- the reciprocal of the temperature in thermodynamics or generalized
-coordinates in analytical mechanics. This is why a comma list is used in
-\texttt{diffcoeff} for specifying variables of differentiation for mixed
-partial derivatives. Although it would be nice to write the minimal \texttt{\{xy\}}
-rather than \texttt{\{x,y}\} when two variables $x$ and $y$ are involved,
-the extra writing is trivial and the comma list allows a simpler handling
-of multi-character variables. For instance in tensor calculus we get expressions
-like
-\begin{example}
-\textbackslash diffp\{A\_i\}\{ x\textasciicircum j,x\textasciicircum k
-\} $\Longrightarrow\quad{\displaystyle \diffp{A_{i}}{x^{j},x^{k}}.}$
-\end{example}
-
+\subsubsection{Comma list of variables of differentiation\protect\label{subsec:Comma-list-of-vars}}
+
+In tensor calculus the differentiations are almost always in terms
+of super- or subscripted coordinates. In many other contexts this
+is the case too -- the reciprocal of the temperature in thermodynamics
+or generalized coordinates in analytical mechanics. This is why a
+comma list is used in \texttt{diffcoeff} for specifying variables
+of differentiation for mixed partial derivatives. Although it would
+be nice to write the minimal \texttt{\{xy\}} rather than \texttt{\{x,y}\}
+when two variables $x$ and $y$ are involved, the extra writing is
+trivial and the comma list allows a simpler handling of multi-character
+variables. For instance in tensor calculus we get expressions like
+\begin{centred}
+\verb`\[ \diffp{A_i}{ x^j,x^k } \]` $\Longrightarrow$ \[ \diffp{A_i}{ x^j,x^k }. \]
+\end{centred}
\noindent It is easier to write \texttt{\{x\textasciicircum j,x\textasciicircum k\}}
here than, say, \texttt{\{\{x\textasciicircum j\}\{x\textasciicircum k\}\}}
-to distinguish the variables. It does mean that should the variable of
-differentiation include a comma then that comma needs to be enclosed in
-braces. There are plenty of instances of this out in the world (see, e.g.,
-the last equation of (\ref{eq:eg1})) but it is overall a rare occurrence.
+to distinguish the variables. It does mean that should the variable
+of differentiation include a comma then that comma needs to be enclosed
+in braces. There are plenty of instances of this out in the world
+(see, e.g., the last equation of (\ref{eq:eg1})) but it is overall
+a rare occurrence.
\paragraph*{Minutiae of spacing (yet again):}
-In Subsection~\ref{subsec:Minutiae-of-spacing} above, I discussed a slight
-reduction in the space inserted between the terms occurring in the denominator
-of a mixed partial derivative when a higher order differentiation is involved.
-The superscript appearing on a differentiation variable in that case \emph{of
-itself} introduced a spacing adjustment between the terms. But the present
-discussion involves only first order differentiations and no such reduction
-is automatically made by \texttt{diffcoeff}. However it is still possible
-to explicitly make such an adjustment with the \texttt{\textbackslash negmu}
-command, which inserts \texttt{-1 mu} of spacing. For our example,
-\begin{example}
-\textbackslash diffp\{A\_i\}\{ x\textasciicircum j\textbackslash negmu,x\textasciicircum k
-\} $\Longrightarrow\quad{\displaystyle \diffp{A_{i}}{x^{j}\negmu,x^{k}},}$
-\end{example}
-
-\noindent the \texttt{\textbackslash negmu} decreasing the spacing between
-the terms from the default 2 mu to 1 mu.
+In \ref{subsec:Minutiae-of-spacing} above, I discussed a slight
+reduction in the space inserted between the terms occurring in the
+denominator of a mixed partial derivative when a higher order differentiation
+is involved. The superscript appearing on a differentiation variable
+in that case \emph{of itself} introduced a spacing adjustment between
+the terms. But the present discussion involves only first order differentiations
+and no such reduction is automatically made by \texttt{diffcoeff}.
+However it is still possible to explicitly make such an adjustment
+with the \texttt{\textbackslash negmu} command introduced earlier
+(\ref{subsec:Spacing-commands}), which inserts \texttt{-1 mu} of
+spacing. For our example, in
+\begin{centred}
+\verb`\[ \diffp{A_i}{ x^j\negmu,x^k } \]` $\Longrightarrow$ \[ \diffp{A_i}{ x^j\negmu,x^k } \]
+\end{centred}
+\noindent the \texttt{\textbackslash negmu} decreases the spacing
+between the terms from the default \verb`2 mu` to \verb`1 mu`.
\subsubsection{Overkill territory}
-Two previous examples illustrate limitations of the algorithm that calculates
-the overall order of differentiation: \texttt{2m/2+2n/2} is not simplified
-to \texttt{m+n} and \texttt{2km+2m} is not factorised to \texttt{2m(k+1)}.
-But there is much that the algorithm \emph{can} handle -- for instance,
-the simple use of parentheses:
-\begin{example}
-\textbackslash diffp{[}2m-(k+1),2(k+1)-m{]}\{F(x,y,z)\}\{x,y,z\} $\Longrightarrow\quad{\displaystyle \diffp[2m-(k+1),2(k+1)-m]{F(x,y,z)}{x,y,z}}.$
-\end{example}
-
+Two previous examples illustrate limitations of the algorithm that
+calculates the overall order of differentiation: \texttt{2m/2+2n/2}
+is not simplified to \texttt{m+n} and \texttt{2km+2m} is not factorised
+to \texttt{2m(k+1)}. But there is much that the algorithm \emph{can}
+handle -- for instance, the simple use of parentheses:
+\begin{centred}
+\verb`\[ \diffp[2m-(k+1),2(k+1)-m]{F(x,y,z)}{x,y,z} \]` $\Longrightarrow$
+\[ \diffp[2m-(k+1),2(k+1)-m]{F(x,y,z)}{x,y,z}. \]
+\end{centred}
\paragraph*{Dynamic use of parentheses}
\noindent For parenthetic expressions to be evaluated as in this example
--- the \emph{dynamic} use of parentheses -- the left parenthesis must
-be preceded at most by a sign or a number; the right parenthesis must be
-followed at most by a sign.
+-- the \emph{dynamic} use of parentheses -- the left parenthesis
+must be preceded at most by a sign or a number; the right parenthesis
+must be followed at most by a sign.
If a right parenthesis is followed by a \emph{variable}, say by \texttt{m}
-as in the order spec. \texttt{{[}(2n+1)m,(2n-1)m{]}}, it will throw an
-error and halt compilation. A message will be sent to the terminal and
-the \LaTeX{} log like the following (which assumes the order spec. was on
-line 53 of the document):
+as in the order spec. \texttt{{[}(2n+1)m,(2n-1)m{]}}, it will throw
+an error and halt compilation. A message will be sent to the terminal
+and the \LaTeX{} log like the following (which assumes the order spec.
+was on line 53 of the document):
\begin{lyxcode}
!~Package~diffcoeff~Error:~)~followed~by~m~in~the~
@@ -811,378 +926,461 @@ differentiation~in~this~case.~Use~the~order-override~
option~to~enter~the~overall~order.
\end{lyxcode}
-This is a limitation on the dynamic use of parentheses -- but they \emph{can}
-be nested.
+This is a limitation on the dynamic use of parentheses -- but they
+\emph{can} be nested.
\paragraph*{Static use of parentheses}
-If a left parenthesis is preceded by a \emph{variable} (i.e., not a sign
-or a number) this signals to \texttt{diffcoeff} the \emph{static} use of
-parentheses. No attempt is made to evaluate what is between them and they
-are treated simply as an extension of the variable. For example,
-\begin{example}
-\textbackslash diffp{[}f(k+1)+1,f(k-1)-1{]}\{F(x,y)\}\{x,y\} $\Longrightarrow\quad{\displaystyle \diffp[f(k+1)+1,f(k-1)-1]{F(x,y)}{x,y}}.$
-\end{example}
-
+If a left parenthesis is preceded by a \emph{variable} (i.e., not
+a sign or a number) this signals to \texttt{diffcoeff} the \emph{static}
+use of parentheses. No attempt is made to evaluate what is between
+them and they are treated simply as an extension of the variable.
+For example,
+\begin{centred}
+\verb`\[ \diffp[f(k+1)+1,f(k-1)-1]{F(x,y)}{x,y} \]` $\Longrightarrow$
+\[ \diffp[f(k+1)+1,f(k-1)-1]{F(x,y)}{x,y}. \]
+\end{centred}
\noindent In the static case you \emph{can} follow the right parenthesis
-by a variable without generating an error.\emph{ }You can nest them, and
-you can include static parentheses within a dynamic pair; for example,
-\begin{example}
-\noindent \textbackslash diffp{[}2(3+f(k))+1,1-3(f(k)-2){]}\{F(x,y)\}\{x,y\}
-$\Longrightarrow\quad{\displaystyle \diffp[2(3+f(k))+1,1-3(f(k)-2)]{F(x,y)}{x,y}}.$
-\end{example}
-
+by a variable without generating an error.\emph{ }You can nest them,
+and you can include static parentheses within a dynamic pair; for
+example,
+\begin{centred}
+\noindent \verb`\[ \diffp[2(3+f(k))+1,1-3(f(k)-2)]{F(x,y)}{x,y} \]`
+$\Longrightarrow$ \[ \diffp[2(3+f(k))+1,1-3(f(k)-2)]{F(x,y)}{x,y}. \]
+\end{centred}
\noindent However, the reverse is not possible: you can't have dynamic
parentheses within a static pair.
\paragraph*{Other refinements}
-Exponents and subscripts on a \emph{variable} are fine in an order specification,
-so long as the exponent or subscript consists of a \emph{single} token:
-\begin{example}
-\textbackslash diffp{[}m\textasciicircum 2+2(k-1),m\textasciicircum 2-(k+1){]}F\{x,y,z,w\}
-$\Longrightarrow\quad{\displaystyle \diffp[m^{2}+2(k-1),m^{2}-(k+1)]F{x,y,z,w}}.$
-\end{example}
-
+Exponents and subscripts on a \emph{variable} are fine in an order
+specification, so long as the exponent or subscript consists of a
+\emph{single} token:
+\begin{centred}
+\verb`\[ \diffp[m^2+2(k-1),m^2-(k+1)]F{x,y,z,w} \]` $\Longrightarrow$
+\[ \diffp[m^2+2(k-1),m^2-(k+1)]F{x,y,z,w}. \]
+\end{centred}
\noindent Braced arguments containing \emph{multiple} tokens as exponents
-or subscripts to variables will generally not halt compilation but will
-usually give nonsensical results, as will \emph{signs} treated as superscripts
-or subscripts. Neither circumstance is checked for by \texttt{diffcoeff}.
+or subscripts to variables will generally not halt compilation but
+will usually give nonsensical results, as will \emph{signs} treated
+as superscripts or subscripts. Neither circumstance is checked for
+by \texttt{diffcoeff}.
\paragraph*{Override}
There are limitations on what order specifications the \texttt{diffcoeff}
-package can `digest'; equally, it can digest a wide variety of such constructs,
-but it is \emph{not} a computer algebra system. In all those cases where
-it fails to calculate or present a correct total order, the order-override
-option is available. Yes, this is not as convenient as having the overall
-order calculated automatically but (let's remind ourselves) we are deep
-in overkill territory. Mixed partial derivatives are used far less often
-than the pure derivatives, and when they \emph{are} used it is nearly always
-to orders 1 or 2 in the variables. Mixed partial derivatives to exotic
-orders of differentiation are rarely used, so that the limitations of the
-calculational algorithm are of little real moment -- and the override
-option is always available for such cases.
+package can `digest'; equally, it can digest a wide variety of such
+constructs, but it is \emph{not} a computer algebra system. In all
+those cases where it fails to calculate or present a correct total
+order, the order-override option is available. Yes, this is not as
+convenient as having the overall order calculated automatically but
+(let's remind ourselves) we are deep in overkill territory. Mixed
+partial derivatives are used far less often than the pure derivatives,
+and when they \emph{are} used it is nearly always to orders 1 or 2
+in the variables. Mixed partial derivatives to exotic orders of differentiation
+are rarely used, so that the limitations of the calculational algorithm
+are of little real moment -- and the override option is always available
+for such cases.
\subsection{Parentheses around multi-character variables}
In thermodynamics and statistical mechanics one may want to differentiate
in the reciprocal of the temperature, $1/T$ (or $1/\Theta$):
-\begin{example}
-\textbackslash diffp{[}2{]}q\{\textbackslash frac 1\textbackslash Theta\}
-$\Longrightarrow\quad{\displaystyle \diffp[2]q{\frac{1}{\Theta}}.}$
-\end{example}
-
-\noindent In this case and for other \emph{higher order} derivatives of
-multi-character variables of differentiation, the parentheses are inserted
-automatically by \texttt{diffcoeff}. Precisely where parentheses should
-be placed is moot. The placement in this example is not strictly logical,
-although it feels intuitive, but the placement can be customised (Section~\ref{sec:Changing-defaults}).
+\begin{centred}
+\verb`\[ \diffp[2]q{\frac 1\Theta} \]` $\Longrightarrow$ \[ \diffp[2]q{\frac 1\Theta}. \]
+\end{centred}
+\noindent In this case and for other \emph{higher order} derivatives
+of multi-character variables of differentiation, the parentheses are
+inserted automatically by \texttt{diffcoeff}. Precisely where parentheses
+should be placed is moot. The placement in this example is not strictly
+logical, although it feels intuitive, but the placement can be customised
+(\ref{sec:Changing-defaults}).
Parentheses are automatically inserted like this only for higher order
derivatives. When the differentiation is to first order, parenthesising
is up to the user:
-\begin{example}
-\textbackslash diffp q\{(\textbackslash frac 1\textbackslash Theta),V\}
-$\Longrightarrow{\displaystyle \quad\diffp q{(\frac{1}{\Theta}),V}.}$
-\end{example}
-
+\begin{centred}
+\verb`\[ \diffp q{(\frac 1\Theta),V} \]` $\Longrightarrow$ \[ \diffp q{(\frac 1\Theta),V}. \]
+\end{centred}
\subsection{Jacobians}
-\texttt{diffcoeff} provides a command \texttt{\textbackslash jacob} for
-constructing Jacobians. For example
-\begin{example}
-\textbackslash jacob\{u,v,w\}\{x,y,z\} $\Longrightarrow\quad{\displaystyle \jacob{u,v,w}{x,y,z}.}$
-\end{example}
-
+\texttt{diffcoeff} provides a command \texttt{\textbackslash jacob}
+for constructing Jacobians. For example
+\begin{centred}
+\verb`\[ \jacob{u,v,w}{x,y,z} \]` $\Longrightarrow$ \[ \jacob{u,v,w}{x,y,z}. \]
+\end{centred}
The comma lists can contain any number of variables. \texttt{\textbackslash jacob}
-does \emph{not} check that the two arguments contain the same number of
-variables, so it is perfectly possible to form an object like \texttt{\textbackslash jacob\{u,v,w\}\{x,y\}}
+does \emph{not} check that the two arguments contain the same number
+of variables, so it is perfectly possible to form an object like \texttt{\textbackslash jacob\{u,v,w\}\{x,y\}}
which as far as I know has no meaning.
-\section{Changing defaults; variant forms\label{sec:Changing-defaults}}
+\section{Changing defaults; variant forms\protect\label{sec:Changing-defaults}}
-To write the range of different examples displayed in the Rogues' Gallery
-(Section~\ref{sec:Rogues'-gallery}) I have had to make extensive use
-of forms of derivative other than the default. \texttt{Diffcoeff} is built
-on the facilities offered by the \texttt{xtemplate} package (included in
-the \LaTeX 3 bundle \texttt{l3packages)}. These facilities are harnessed
-by means of a command, \texttt{\textbackslash diffdef}, and a further
-optional argument of the \texttt{\textbackslash diff} command.\texttt{ }
-
-How a derivative is displayed in a document is determined by specifying
-values in a `key = value' list. This is done with the \texttt{\textbackslash diffdef}
-command, which also allows a name to be associated with the list. By using
-that name as an argument in the \texttt{\textbackslash diff} command,
-a derivative is formed shaped by those values. Examples will make the process
-clear.
+To write the range of different examples displayed in the Rogues'
+Gallery (\ref{sec:Rogues'-gallery}) I have had to make extensive
+use of forms of derivative other than the default. \texttt{diffcoeff}
+is built on the facilities offered by the \texttt{xtemplate} package
+(included in the \LaTeX 3 bundle \texttt{l3packages)}. These facilities
+are harnessed by means of a command, \texttt{\textbackslash diffdef},
+and a further optional argument of the \texttt{\textbackslash diff}
+command.\texttt{ }
\subsection{Default values: ordinary derivatives}
-Table~\ref{tab:Ordinary-derivatives} lists the keys available for forming
-derivatives and the default values\footnote{Note that a mu is a `math unit', 1/18 of an em in the math font used.}
-they have been assigned. These default values have been chosen to coincide
-with those relevant for \emph{ordinary} derivatives -- apart from the
-keys \texttt{denom-term-sep}, \texttt{/-denom-term-sep} and \texttt{term-sep-adjust
-}which are ignored for ordinary derivatives but apply to the case of mixed
-partial derivatives when there is more than one variable of differentiation.
-Keys with an opening slash, /, apply only to the slash form of the derivative;
-keys with an opening asterisk, {*}, apply only when the differentiand is
-appended.
-
-\begin{wraptable}[22]{o}{0.5\columnwidth}%
-\noindent \begin{centering}
-\vspace{-4.5ex}
- \caption{{\small{}Defaults (ordinary derivatives})\label{tab:Ordinary-derivatives}}
-\par\end{centering}
-\noindent \centering{}\abovetopsep=.5ex{}%
+Table~\ref{tab:Ordinary-derivatives} lists the keys available for
+forming derivatives and the default values\footnote{Note that a mu is a `math unit', 1/18 of a quad.}
+they have been assigned. These default values have been chosen to
+coincide with those relevant for \emph{ordinary} derivatives -- apart
+from the keys \texttt{denom-term-sep}, \texttt{/-denom-term-sep},
+\texttt{term-sep-adjust} and \texttt{/-term-sep-adjust} which are
+ignored for ordinary derivatives but apply to the case of mixed partial
+derivatives when there is more than one variable of differentiation.
+Keys with an opening slash, /, apply only to the slash form of the
+derivative; keys with an opening asterisk, {*}, apply only when the
+differentiand is appended.
+
+Note that these settings are, in general, font dependent. The values
+given are (in the author's opinion) appropriate for the default \LaTeX{}
+math fonts. There are also likely to be variations required for whether
+a derivative is used in a display-style or text-style or script-style
+expression. That matter is discussed below in \ref{subsec:Text-and-script-style}.
+All values specifying a space require the unit (\texttt{mu}) to be
+given; a number alone does not suffice.
+\noindent \begin{center}
+\begin{table}
+\centering{}\caption{{\small Defaults (ordinary derivatives})\protect\label{tab:Ordinary-derivatives}}
\begin{tabular}{lr}
\toprule
-{\small{}key} & {\small{}default}\tabularnewline
+{\small key} & {\small default}\tabularnewline
\midrule
-{\small{}op-symbol} & \texttt{\small{}d}\tabularnewline
-{\small{}op-symbol-alt} & \texttt{\small{}= op-symbol}\tabularnewline
-{\small{}op-order-sep} & \texttt{\small{}1 mu}\tabularnewline
-{\small{}{*}-op-left} & \texttt{\small{}false}\tabularnewline
-{\small{}{*}-italic-nudge} & \texttt{\small{}3 mu}\tabularnewline
-{\small{}{*}/-op-wrap} & \texttt{\small{}true}\tabularnewline
-{\small{}long-var-wrap} & \texttt{\small{}d(v)}\tabularnewline
-{\small{}denom-term-sep} & \texttt{\small{}2 mu}\tabularnewline
-{\small{}/-denom-term-sep} & \texttt{\small{}1 mu}\tabularnewline
-term-sep-adjust & \texttt{-1 mu}\tabularnewline
-{\small{}left-delim} & \texttt{\small{}\textbackslash left .}\tabularnewline
-{\small{}right-delim} & \texttt{\small{}\textbackslash right |}\tabularnewline
-{\small{}elbowroom} & \texttt{\small{}0 mu}\tabularnewline
-{\small{}subscr-nudge} & \texttt{\small{}0 mu}\tabularnewline
-{\small{}/-left-delim} & \texttt{\small{}(}\tabularnewline
-{\small{}/-right-delim} & \texttt{\small{})}\tabularnewline
-{\small{}/-elbowroom} & \texttt{\small{}0 mu}\tabularnewline
-{\small{}/-subscr-nudge} & \texttt{\small{}0 mu}\tabularnewline
+{\small op-symbol} & {\small\texttt{d}}\tabularnewline
+{\small op-symbol-alt} & {\small\texttt{= op-symbol}}\tabularnewline
+{\small op-order-sep} & {\small\texttt{1 mu}}\tabularnewline
+{\small derivand-sep} & {\small\texttt{3 mu plus 1 mu minus 2 mu}}\tabularnewline
+{\small /-derivand-sep} & {\small\texttt{= derivand-sep}}\tabularnewline
+{\small{*}-derivand-sep} & {\small\texttt{= derivand-sep}}\tabularnewline
+{\small{*}/-derivand-sep} & {\small\texttt{= /-derivand-sep}}\tabularnewline
+{\small denom-term-sep} & {\small\texttt{2 mu}}\tabularnewline
+{\small /-denom-term-sep} & {\small\texttt{1 mu}}\tabularnewline
+{\small term-sep-adjust} & {\small\texttt{-1 mu}}\tabularnewline
+{\small left-delim} & {\small\texttt{\textbackslash left .}}\tabularnewline
+{\small right-delim} & {\small\texttt{\textbackslash right |}}\tabularnewline
+{\small /-left-delim} & {\small\texttt{(}}\tabularnewline
+{\small /-right-delim} & {\small\texttt{)}}\tabularnewline
+{\small elbowroom} & {\small\texttt{0 mu}}\tabularnewline
+{\small /-elbowroom} & {\small\texttt{0 mu}}\tabularnewline
+{\small subscr-nudge} & {\small\texttt{0 mu}}\tabularnewline
+{\small /-subscr-nudge} & {\small\texttt{0 mu}}\tabularnewline
+{\small long-var-wrap} & {\small\texttt{d(v)}}\tabularnewline
+{\small{*}/-op-wrap} & {\small\texttt{true}}\tabularnewline
+{\small{*}-op-left} & {\small\texttt{false}}\tabularnewline
+{\small{*}-italic-nudge} & {\small\texttt{3 mu}}\tabularnewline
\bottomrule
-\end{tabular}\end{wraptable}%
-Note that these settings are, in general, font dependent. The values given
-are (in the author's opinion) appropriate for the default \LaTeX{} math
-fonts. There are also likely to be variations required for whether a derivative
-is used in a display-style or text-style or script-style expression. That
-matter is discussed below in Subsection~\ref{subsec:Text-and-script-style}.
-All values specifying a space require the unit (\texttt{mu}) to be given;
-a number alone does not suffice.
+\end{tabular}
+\end{table}
+\par\end{center}
\begin{description}
\item [{op-symbol}] the operator symbol; for ordinary derivatives, generally
-one of \texttt{d} or \texttt{\textbackslash mathrm\{d\}}, \texttt{D} or
-\texttt{\textbackslash mathrm\{D\}}, \texttt{\textbackslash delta} or
-\texttt{\textbackslash Delta}; for partial derivatives \texttt{\textbackslash partial};
+one of \texttt{d} or \texttt{\textbackslash mathrm\{d\}}, \texttt{D}
+or \texttt{\textbackslash mathrm\{D\}}, \texttt{\textbackslash delta}
+or \texttt{\textbackslash Delta}; for partial derivatives \texttt{\textbackslash partial};
default = \texttt{d}
-\item [{op-symbol-alt}] if different from \textbf{op-symbol} then used in the
-denominator while \textbf{op-symbol} is used in the numerator; e.g. for
-$\diff.nabla.{v^{i}}t$, \texttt{op-symbol = \textbackslash nabla} and
-\texttt{op-symbol-alt = d}; otherwise (and usually) defaults to \textbf{op-symbol}
-\end{description}
-~\vspace{-5ex}
-
-\begin{description}
-\item [{op-order-sep}] extra horizontal space added between the op-symbol and
-the superscripted order of differentiation in higher order derivatives;
-compare $d^{2}$ with $d^{\mkern1mu 2}$, $\partial^{2}$ with $\partial^{\mkern1mu 2}$
-where the first symbol in each case has no extra space and the second has
-an extra 1 mu; default = \texttt{1 mu}
-\item [{{*}-op-left}] a choice of \texttt{true} or \texttt{false} indicating
-whether the op-symbol is left-aligned or not when the differentiand is
-appended; generally it is centred; does not apply to slash forms of the
-derivative; default = \texttt{false}
-\item [{{*}-italic-nudge}] if \textbf{{*}-op-left} is \texttt{true}, makes an
-italic adjustment in the numerator, so that the op-symbols in numerator
-and denominator align in the same slanting column; for an upright \texttt{d}
-this would be set to \texttt{0 mu}; default = \texttt{3 mu}
-\item [{{*}/-op-wrap}] a choice of \texttt{true} or \texttt{false} for slash
-forms of the derivative when the differentiand is appended, dictating whether
-the derivative is wrapped in parentheses, as here $\diffp*{F(x,y)}/x$,
-or not; default = \texttt{true}
-\item [{long-var-wrap}] to avoid ambiguity in higher order derivatives it may
-be advisable to wrap multi-token variables of differentiation in parentheses;
-default = \texttt{d(v)}; the choices are
-\begin{description}
-\item [{\texttt{dv}}] no wrapping, e.g. $dx_{i}^{2}$ or $d\frac{1}{\Theta}^{2}$,
-$\partial x_{i}^{2}$ or $\partial\frac{1}{\Theta}^{2}$,
-\item [{\texttt{d(v)}}] wrap the variable only, e.g. $d(x_{i})^{2}$ or $d(\frac{1}{\Theta})^{2}$,
-$\partial(x_{i})^{2}$ or $\partial(\frac{1}{\Theta})^{2}$
-\item [{\texttt{(dv)}}] wrap the op-symbol and variable, e.g. $(dx_{i})^{2}$
-or $(d\frac{1}{\Theta})^{2}$, $(\partial x_{i})^{2}$ or $(\partial\frac{1}{\Theta})^{2}$
-\end{description}
+\item [{op-symbol-alt}] if different from \textbf{op-symbol} then used
+in the denominator while \textbf{op-symbol} is used in the numerator;
+e.g. for $\diff.nabla.{v^{i}}t$, \texttt{op-symbol = \textbackslash nabla}
+and \texttt{op-symbol-alt = d}; otherwise (and usually) defaults to
+\textbf{op-symbol}
+\item [{op-order-sep}] extra horizontal space added between the op-symbol
+and the superscripted order of differentiation in higher order derivatives;
+for the math-italic forms compare $d^{2}$ with $d^{\mkern1mu 2}$,
+$\partial^{2}$ with $\partial^{\mkern1mu 2}$ where the first symbol
+in each case has no extra space and the second has an extra 1 mu;
+default = \texttt{1 mu}
+\item [{derivand-sep}] horizontal space added before the differentiand
+(derivand) if the \verb`spaced` package option is used, or by the
+\verb`!` switch if it is not; the default has some stretch and shrink;
+default = \verb`3mu plus 1mu minus 2mu`
+\item [{/-derivand-sep}] for the slash form of derivative, horizontal space
+added before the differentiand (derivand) if the \verb`spaced` package
+option is used, or by the \verb`!` switch if it is not; default =
+\verb`derivand-sep`
+\item [{{*}-derivand-sep}] when the derivand is appended, horizontal space
+added before the differentiand (derivand) if the \verb`spaced` package
+option is used, or by the \verb`!` switch if it is not; default =
+\verb`derivand-sep`
+\item [{{*}/-derivand-sep}] for the slash form of derivative when the derivand
+is appended, horizontal space added before the differentiand (derivand)
+if the \verb`spaced` package option is used, or by the \verb`!`
+switch if it is not; default = \verb`/-derivand-sep`
\item [{denom-term-sep}] (mixed partial derivatives only) horizontal spacing
inserted between the differentials in the denominator of a mixed partial
derivative to avoid a solid cluster like $\partial x\partial y\partial z$;
-with the default 2 mu this is $\dl.p.x\dl.p.2y\dl.p.2z$; default = \texttt{2
+with the default 2 mu this is $\dl.p.x\dl.p.2y\dl.p.2z$; default
+= \texttt{2 mu}
+\item [{/-denom-term-sep}] (mixed partial derivatives only) horizontal
+spacing inserted between the differentials in the denominator of a
+slash-form mixed partial derivative; because a slash-form derivative
+is already spread out horizontally, the default spacing is less than
+for the \texttt{\textbackslash frac} form derivative; default = \texttt{1
mu}
-\item [{/-denom-term-sep}] (mixed partial derivatives only) horizontal spacing
-inserted between the differentials in the denominator of a slash-form mixed
-partial derivative; because a slash-form derivative is already spread out
-horizontally, the default spacing is less than for the \texttt{\textbackslash frac}
-form derivative; default = \texttt{1 mu}
\item [{term-sep-adjust}] (mixed partial derivatives only) adjustment (i.e.
-reduction) to \textbf{(/-)denom-term-sep} when differentiation in a variable
-occurs to an order other than 1; if, e.g., $\dl.p.x^{2}\dl.p.1y\dl.p.2z$
-is the denominator of a mixed partial derivative in three variables, because
-of the superscript the spacing between $\partial x^{2}$ and $\partial y$
-is reduced by\textbf{ term-sep-adjust} from the spacing between $\partial y$
+reduction) to \textbf{denom-term-sep} or \textbf{/-denom-term-sep}
+when differentiation in a variable occurs to an order other than 1;
+if, e.g., $\dl.p.x^{2}\dl.p.1y\dl.p.2z$ is the denominator of a mixed
+partial derivative in three variables, because of the superscript
+the spacing between $\partial x^{2}$ and $\partial y$ is reduced
+by\textbf{ term-sep-adjust} from the spacing between $\partial y$
and $\partial z$; default = \texttt{-1 mu}
\item [{left-delim}] the left member of a delimiter pair wrapping the derivative,
the right member of which is subscripted to indicate a point of evaluation
-or variables held constant; default = \texttt{\textbackslash left .}
-\item [{right-delim}] the right member of a delimiter pair wrapping the derivative
-and subscripted to indicate a point of evaluation or variables held constant;
-default = \texttt{\textbackslash right |}
+or variables held constant; default = \texttt{\textbackslash left
+.}
+\item [{right-delim}] the right member of a delimiter pair wrapping the
+derivative and subscripted to indicate a point of evaluation or variables
+held constant; default = \texttt{\textbackslash right |}
+\item [{/-left-delim}] for the slash form of derivative, the left member
+of a delimiter pair wrapping the derivative and subscripted to indicate
+a point of evaluation or variables held constant; default = \texttt{(}
+\item [{/-right-delim}] for the slash form of derivative, the right member
+of a delimiter pair wrapping the derivative, the right member of which
+is subscripted to indicate a point of evaluation or variables held
+constant; default = \texttt{)}
\item [{elbowroom}] adjustment to the whitespace between the left and right
-delimiters and the enclosed derivative; negative values reduce the space;
-default = \texttt{0 mu}
-\item [{subscr-nudge}] horizontal adjustment of the subscript's placing relative
-to the \textbf{right-delim}iter, e.g., a negative value compensates for
-the curving inwards of a large right parenthesis; may be font dependent;
-default = \texttt{0 mu}
-\item [{/-left-delim}] for the slash form of derivative, the left member of
-a delimiter pair wrapping the derivative and subscripted to indicate a
-point of evaluation or variables held constant; default = \texttt{(}
-\item [{/-right-delim}] for the slash form of derivative, the right member of
-a delimiter pair wrapping the derivative, the right member of which is
-subscripted to indicate a point of evaluation or variables held constant;
-default = \texttt{)}
-\item [{/-elbowroom}] adjustment to the whitespace between the left and right
-delimiters and the enclosed slash-form derivative; default = \texttt{0
-mu}
+delimiters and the enclosed derivative; negative values reduce the
+space; default = \texttt{0 mu}
+\item [{/-elbowroom}] adjustment to the whitespace between the left and
+right delimiters and the enclosed slash-form derivative; default =
+\texttt{0 mu}
+\item [{subscr-nudge}] horizontal adjustment of the subscript's placing
+relative to the \textbf{right-delim}iter, e.g., a negative value compensates
+for the curving inwards of a large right parenthesis; may be font
+dependent; default = \texttt{0 mu}
\item [{/-subscr-nudge}] for the slash form of derivative, horizontal adjustment
of the subscript's placing relative to the /-\textbf{right-delim}iter;
may be font dependent; default = \texttt{0 mu}
+\item [{long-var-wrap}] to avoid ambiguity in higher order derivatives
+it may be advisable to wrap multi-token variables of differentiation
+in parentheses; default = \texttt{d(v)}; the choices are
+\begin{description}
+\item [{\texttt{dv}}] no wrapping, e.g. $dx_{i}^{2}$ or $d\frac{1}{\Theta}^{2}$,
+$\partial x_{i}^{2}$ or $\partial\frac{1}{\Theta}^{2}$,
+\item [{\texttt{d(v)}}] wrap the variable only, e.g. $d(x_{i})^{2}$ or
+$d(\frac{1}{\Theta})^{2}$, $\partial(x_{i})^{2}$ or $\partial(\frac{1}{\Theta})^{2}$
+\item [{\texttt{(dv)}}] wrap the op-symbol and variable, e.g. $(dx_{i})^{2}$
+or $(d\frac{1}{\Theta})^{2}$, $(\partial x_{i})^{2}$ or $(\partial\frac{1}{\Theta})^{2}$
+\end{description}
+\item [{{*}/-op-wrap}] a choice of \texttt{true} or \texttt{false} for
+slash forms of the derivative when the differentiand is appended,
+dictating whether the derivative is wrapped in parentheses, as here
+$\diffp*{F(x,y)}/x$, or not; default = \texttt{true}
+\item [{{*}-op-left}] a choice of \texttt{true} or \texttt{false} indicating
+whether the op-symbol is left-aligned or not when the differentiand
+is appended; generally it is centred; does not apply to slash forms
+of the derivative; default = \texttt{false}
+\item [{{*}-italic-nudge}] if \textbf{{*}-op-left} is \texttt{true}, makes
+an italic adjustment in the numerator, so that the op-symbols in numerator
+and denominator align in the same slanting column; for an upright
+\texttt{d} this would be set to \texttt{0 mu}; default = \texttt{3
+mu}
\end{description}
\subsection{ISO defaults}
-You may not like the default settings that come with \texttt{diffcoeff}.
-The package does not follow ISO 80000-2 -- it does not use upright `d's
-nor does it wrap an ordinary differential coefficient in subscripted parentheses
-to indicate a point of evaluation. Both `defects' can be remedied by calling
-the package with the option \texttt{ISO}:\footnote{One can also use \texttt{ISO=true} to turn the option on and \texttt{ISO=false
+\label{subsec:ISO-defaults}You may not like the default settings
+that come with \texttt{diffcoeff}. The package does not follow ISO
+80000-2 -- it does not use upright `d's nor does it wrap an ordinary
+differential coefficient in subscripted parentheses to indicate a
+point of evaluation. Both `defects' can be remedied by calling the
+package with the option \texttt{ISO}:\footnote{One can also use \texttt{ISO=true} to turn the option on and \texttt{ISO=false
}to turn the option off. }
\begin{lyxcode}
\textbackslash usepackage{[}ISO{]}\{diffcoeff\}
\end{lyxcode}
-\begin{wraptable}[9]{o}{0.4\columnwidth}%
+\begin{wraptable}[10]{o}{0.4\columnwidth}%
\centering{}\vspace{-4ex}
- \caption{{\small{}ISO default changes}\label{tab:ISO-setting-changes}}
+ \caption{{\small ISO default changes}\protect\label{tab:ISO-setting-changes}}
\abovetopsep=.5ex %
\begin{tabular}{lr}
\toprule
-{\small{}key} & {\small{}default}\tabularnewline
+{\small key} & {\small default}\tabularnewline
\midrule
-{\small{}op-symbol} & \texttt{\small{}\textbackslash mathrm\{d\}}\tabularnewline
-{\small{}op-order-sep} & \texttt{\small{}0 mu}\tabularnewline
-{\small{}left-delim} & \texttt{\small{}\textbackslash left (}\tabularnewline
-{\small{}right-delim} & \texttt{\small{}\textbackslash right )}\tabularnewline
-{\small{}subscr-nudge} & \texttt{\small{}-6 mu}\tabularnewline
+{\small op-symbol} & {\small\texttt{\textbackslash mathrm\{d\}}}\tabularnewline
+{\small op-order-sep} & {\small\texttt{0 mu}}\tabularnewline
+{\small left-delim} & {\small\texttt{\textbackslash left (}}\tabularnewline
+{\small right-delim} & {\small\texttt{\textbackslash right )}}\tabularnewline
+{\small subscr-nudge} & {\small\texttt{-6 mu}}\tabularnewline
\bottomrule
\end{tabular}\end{wraptable}%
The uppercase is essential -- an option \texttt{iso} is not recognised.
-The \texttt{ISO} option results in changes to the default settings of Table~\ref{tab:Ordinary-derivatives}
-as listed in Table~\ref{tab:ISO-setting-changes}. Any settings not mentioned
-in Table~\ref{tab:ISO-setting-changes} retain the values presented in
-Table~\ref{tab:Ordinary-derivatives}. Note that the subscript nudge figure
-specified here is \emph{not} part of the standard, which makes no recommendation
-about the subscript's positioning. But: the \texttt{-6 mu} figure with
-a default or latin modern font gives a better representation of what is
-displayed in the standard than a zero figure.
-
-Because the `d' is upright with the \texttt{ISO} option, no extra space
-is required between the symbol and the superscript in a higher order derivative.
-Hence the zero value for the \texttt{op-order-sep}. ISO recommends subscripted
-parentheses to indicate a point of evaluation. Hence the other entries
-in the table. Because a large right parenthesis (penultimate setting) bends
-inwards, to the left, a negative value for the last entry ensures the subscript
-does not become detached from the derivative, looking lost in a sea of
-whitespace.
-
-Note that the \texttt{ISO} option will also produce upright `D's in derivatives
-formed from `D'; see Subsection~\ref{subsec:D-delta-Delta} below.
+The \texttt{ISO} option results in changes to the default settings
+of Table~\ref{tab:Ordinary-derivatives} as listed in Table~\ref{tab:ISO-setting-changes}.
+Any settings not mentioned in Table~\ref{tab:ISO-setting-changes}
+retain the values presented in Table~\ref{tab:Ordinary-derivatives}.
+Note that the subscript nudge figure specified here is \emph{not}
+part of the standard, which makes no recommendation about the subscript's
+positioning. But: the \texttt{-6 mu} figure with a default or latin
+modern font gives a better representation of what is displayed in
+the standard than a zero figure.
+
+Because the `d' is upright with the \texttt{ISO} option, no extra
+space is required between the symbol and the superscript in a higher
+order derivative. Hence the zero value for the \texttt{op-order-sep}.
+ISO recommends subscripted parentheses to indicate a point of evaluation.
+Hence the other entries in the table. Because a large right parenthesis
+(penultimate setting) bends inwards, to the left, a negative value
+for the last entry ensures the subscript does not become detached
+from the derivative, looking lost in a sea of whitespace.
+
+Note that the \texttt{ISO} option will also produce upright `D's in
+derivatives formed from `D'; see \ref{subsec:D-delta-Delta} below.
\subsection{Partial derivatives}
\begin{wraptable}{o}{0.4\columnwidth}%
-\centering{}\vspace{-4.5ex}
- \caption{{\small{}Default changes: partial derivatives}\label{tab:Partial-deriv-defaults}}
+\centering{}\vspace{-4ex}
+ \caption{{\small Default changes for partial derivatives}\protect\label{tab:Partial-deriv-defaults}}
\abovetopsep=.5ex %
\begin{tabular}{lr}
\toprule
-{\small{}key} & {\small{}default}\tabularnewline
+{\small key} & {\small default}\tabularnewline
\midrule
-{\small{}op-symbol } & \texttt{\small{}\textbackslash partial}\tabularnewline
-{\small{}left-delim} & \texttt{\small{}\textbackslash left (}\tabularnewline
-{\small{}right-delim} & \texttt{\small{}\textbackslash right )}\tabularnewline
-{\small{}subscr-nudge } & \texttt{\small{}-6 mu}\tabularnewline
+{\small op-symbol } & {\small\texttt{\textbackslash partial}}\tabularnewline
+{\small left-delim} & {\small\texttt{\textbackslash left (}}\tabularnewline
+{\small right-delim} & {\small\texttt{\textbackslash right )}}\tabularnewline
+{\small subscr-nudge } & {\small\texttt{-6 mu}}\tabularnewline
\bottomrule
\end{tabular}\end{wraptable}%
-The default values given in Table~\ref{tab:Ordinary-derivatives}, when
-they are relevant, apply to \emph{ordinary} derivatives. For partial derivatives,
-the defaults are those of Table~\ref{tab:Partial-deriv-defaults}. All
-other keys take the default values listed in Table~\ref{tab:Ordinary-derivatives}.
-The last three entries here are not an attempt at ISO compatibility but
-reflect the use of subscripted parentheses with partial derivatives to
-indicate variables held constant, for instance in the Maxwell relations
+The default values given in Table~\ref{tab:Ordinary-derivatives},
+when they are relevant, apply to \emph{ordinary} derivatives. For
+partial derivatives, the defaults are those of Table~\ref{tab:Partial-deriv-defaults}.
+All other keys take the default values listed in Table~\ref{tab:Ordinary-derivatives}.
+The last three entries here are not an attempt at ISO compatibility
+but reflect the use of subscripted parentheses with partial derivatives
+to indicate variables held constant, for instance in the Maxwell relations
of thermodynamics, one of which is
\[
\diffp SV[T]=\diffp PT[V].
\]
-\subsection{Setting your own defaults: \texttt{\textbackslash diffdef\label{subsec:diffdef}}}
+\subsection{Setting your own defaults: \texttt{\textbackslash diffdef\protect\label{subsec:diffdef}}}
Versions 2 and later of the \texttt{diffcoeff} package provide a command,
-\texttt{\textbackslash diffdef}, that enables users to set their own defaults.\texttt{ }For
-example, if you wish to use upright `d's but not follow the ISO's use of
-subscripted parentheses to indicate a point of evaluation, enter in the
-preamble of your document the command\vspace{-2ex}
-
-\begin{lyxcode}
-\noindent %
-\noindent\begin{minipage}[t]{1\columnwidth}%
+\texttt{\textbackslash diffdef}, that enables users to set their
+own defaults.\texttt{ }For example, if you wish to use upright `d's
+but not follow the ISO's use of subscripted parentheses to indicate
+a point of evaluation, enter in the preamble of your document the
+command
\begin{lyxcode}
\textbackslash diffdef~\{\}~~~~
-\begin{lyxcode}
-\{~~~~~~
-\begin{lyxcode}
-op-symbol~~~~=~\textbackslash mathrm\{d\},~~~~
-op-order-sep~=~0~mu
-\end{lyxcode}
-\}
-\end{lyxcode}
-\end{lyxcode}
-%
-\end{minipage}
+~~\{~~~~~~
+
+~~~~op-symbol~~~~=~\textbackslash mathrm\{d\},~~~~
+
+~~~~op-order-sep~=~0~mu
+
+~~\}
\end{lyxcode}
\noindent Since a list of settings, like this one, is a comma-\emph{separated}
list, no comma is required for the last entry. That entry is a consequence
-of the first: upright symbols do not require any extra separation between
-the `d' and the superscript in a higher order derivative.
+of the first: upright symbols do not require any extra separation
+between the `d' and the superscript in a higher order derivative.
The other point to note is the empty pair of braces after the \texttt{\textbackslash diffdef}
-command. \emph{They matter}. Their emptiness is what determines that it
-is the \emph{default} values that are changed. If they contain some content,
-then that content provides a \emph{name} for the particular set of values
-in the following list. The \texttt{diffcoeff} package exploits this facility
-to cope with the wide variety of forms displayed in the Rogues' Gallery
-of Section~\ref{sec:Rogues'-gallery}.
+command. \emph{They matter}. Their emptiness is what determines that
+it is the \emph{default} values that are changed. If they contain
+some content, then that content provides a \emph{name} for the particular
+set of values in the following list. The \texttt{diffcoeff} package
+exploits this facility to cope with the wide variety of forms displayed
+in the Rogues' Gallery of \ref{sec:Rogues'-gallery}.
+
+\subsubsection{Space before the differentiand}
+
+\label{subsec:A-final-flourish}\begin{wraptable}{o}{0.6\columnwidth}%
+\begin{centering}
+\caption{Keys for spacing the derivand}
+\medskip{}
+\begin{tabular}{lr}
+\toprule
+{\small key} & {\small default}\tabularnewline
+\midrule
+{\small derivand-sep} & {\small\texttt{3mu plus 1mu minus 2mu}}\tabularnewline
+{\small{*}-derivand-sep} & {\small\texttt{= derivand-sep}}\tabularnewline
+{\small /-derivand-sep} & {\small\texttt{= derivand-sep}}\tabularnewline
+{\small{*}/-derivand-sep} & {\small\texttt{= /-derivand-sep}}\tabularnewline
+\bottomrule
+\end{tabular}
+\par\end{centering}
+\end{wraptable}%
+The insertion of a small space before the differentiand is effected
+by the \verb`!` key inserted immediately before the differentiand
+argument in the \verb`\diff` command. You may wish to make the insertion
+of this space the \emph{default} behaviour. This is done by using
+the \verb`spaced` package option (which makes the \verb`!` switch
+now reverse this new default and put \emph{no} extra space before
+the derivand). The amount of space inserted is, by default, \verb`3mu plus 1mu minus 2mu`,
+meaning the space is generally $3$mu but can stretch to $4$mu or
+shrink to $1$mu as \TeX{} strives to fit content in a line or on the
+page.
+
+Perhaps this doesn't suit. You may want a fixed space here, with no
+stretch or shrink. The key to change is \verb`derivand-sep`. By default,
+this setting applies not only to the fraction form of derivative,
+but also to the slash form and to when the derivand is appended.
+
+If you feel a little less space should be used for slash derivatives,
+then the key to change is \verb`/-deriv-sep`. This changed value
+will also be used for an appended derivand in a slash derivative.
+
+Thus to meet both wishes you might put in the preamble of your document
+something like
+\begin{lyxcode}
+\textbackslash diffdef~\{\}~~~~
+
+~~\{~~~~~~
+
+~~~~derivand-sep~~~=~3~mu,~~~~
+
+~~~~/-derivand-sep~=~2~mu
+
+~~\}
+\end{lyxcode}
+This will insert a fixed space of $3$mu before the differentiand
+in both the numerator and when appended in the fraction form of derivative,
+and a fixed space of $2$mu in the slash form of derivative, both
+in the numerator and when appended.
+
+If you want a different spacing when the derivand is appended, the
+keys to change are \verb`*-derivand-sep` and \verb`*/-derivand-sep`.
+
+\paragraph{Selective spacing}
+
+I have treated the \verb`spaced` package option thus far as if it
+were an \verb`ON/OFF` switch and, indeed, the presence of the package
+option \verb`spaced` behaves as \verb`ON` and its absence as \verb`OFF`.
+Internally, however, \verb`spaced` is equivalent to \verb`spaced=1`
+and its absence to \verb`spaced=0`. Entering \verb`spaced=n` in
+the package option where \verb`n` is a positive integer is equivalent
+to entering \verb`spaced=1` (and hence to simply entering \verb`spaced`),
+but if \verb`n` is a negative integer, a new effect is produced.
+
+Entering \verb`spaced=-1` (or any negative integer) will insert a
+space (by default \verb`3mu plus 1mu minus 2mu`) before the differentiand
+provided the differentiand\emph{ is longer than a single token} but
+will insert no space before single-token differentiands. The switch
+\verb`!` reverses this behaviour.
\subsection{Variant forms}
-For this package I needed to have a number of variant forms available to
-illustrate the wide variety of ways in which derivatives are displayed.
+For this package I needed to have a number of variant forms available
+to illustrate the wide variety of ways in which derivatives are displayed.
The \texttt{\textbackslash diffdef} command in which the first argument
-is \emph{filled} provides one half of the means of doing this. I've given
-the single-letter name \texttt{p} to the following settings:
-
-\noindent %
-\noindent\begin{minipage}[t]{1\columnwidth}%
+is \emph{filled} provides one half of the means of doing this. I've
+given the single-letter name \texttt{p} to the following settings:
\begin{lyxcode}
\textbackslash diffdef~\{~p~\}
@@ -1198,34 +1396,28 @@ the single-letter name \texttt{p} to the following settings:
~~\}
\end{lyxcode}
-%
-\end{minipage}
-
-The second half of providing variant forms is to insert this name, \texttt{p},
-between dots (periods, full stops) as the \emph{first} argument of the
-\texttt{\textbackslash diff} command. Thus, repeating an example at the
-end of Subsection~\ref{subsec:Partial-appending},
-\begin{example}
-\textbackslash diff.p.{*}\{\textbackslash frac PT\}U{[}V{]} = \textbackslash diff.p.{*}\{\textbackslash frac
-1T\}V{[}U{]} $\Longrightarrow\quad{\displaystyle \diff.p.*{\frac{P}{T}}U[V]=\diff.p.*{\frac{1}{T}}V[U]}$
-\end{example}
-
+The second half of providing variant forms is to insert this name,
+\texttt{p}, between dots (periods, full stops) as the \emph{first}
+argument of the \texttt{\textbackslash diff} command. Thus, repeating
+an example at the end of \ref{subsec:Partial-appending},
+\begin{centred}
+\verb`\[ \diff.p.*{\frac PT}U[V] = \diff.p.*{\frac 1T}V[U] \]` $\Longrightarrow$
+\[ \diff.p.*{\frac PT}U[V] = \diff.p.*{\frac 1T}V[U] \]
+\end{centred}
\noindent The effect is exactly the same as previously, when the \texttt{\textbackslash diffp}
command was used. Indeed, \texttt{diffcoeff} identifies \texttt{\textbackslash diffp}
-with \texttt{\textbackslash diff.p.}, saving a few keystrokes and maintaining
-compatibility with version 1 of the package. In \LaTeXe{} synatx,
+with \texttt{\textbackslash diff.p.}:
\begin{lyxcode}
-\textbackslash newcommand~\{~\textbackslash diffp~\}~\{~\textbackslash diff.p.~\}
+\textbackslash NewDocumentCommand~\textbackslash diffp~\{~\}~\{~\textbackslash diff.p.~\}
\end{lyxcode}
-Note that this identification of \texttt{\textbackslash diffp} with \texttt{\textbackslash diff.p. }means
-there is no equivalent dot-delimited argument available for \texttt{\textbackslash diffp}.
-The dot-delimited argument applies only to \texttt{\textbackslash diff}.
-
-For example, to illustrate the upright-d form of derivative, without changing
-the default math-italic form (which I prefer), one might enter in the preamble
-\begin{lyxcode}
-\noindent %
-\noindent\begin{minipage}[t]{1\columnwidth}%
+Note that this identification of \texttt{\textbackslash diffp} with
+\texttt{\textbackslash diff.p. }means there is no equivalent dot-delimited
+argument available for \texttt{\textbackslash diffp}. The \emph{dot-delimited
+argument applies only to} \texttt{\textbackslash diff}.
+
+For example, to illustrate the upright-d form of derivative, without
+changing the default math-italic form (which I prefer), one might
+enter in the preamble
\begin{lyxcode}
\textbackslash diffdef~\{~up~\}~
@@ -1237,83 +1429,69 @@ the default math-italic form (which I prefer), one might enter in the preamble
~~\}
\end{lyxcode}
-%
-\end{minipage}
-\end{lyxcode}
-Apart from the key = value settings, the critical feature here is the name,
-\texttt{up} (which is at your discretion and could equally be \texttt{upright}
-or \texttt{roman} or even \texttt{Fred} if you so fancied). This ensures
-that the changed settings apply only to this particular variant and do
-not `infect' the overall defaults. To use this variant, all that is needed
-is to add the name, between dots, to the \texttt{\textbackslash diff}
-command:
-\begin{example}
-\textbackslash diff.up.yx $\Longrightarrow\quad{\displaystyle \diff.up.yx}.$
-\end{example}
-
-\noindent Each variant derivative inherits all the default values that
-it does not explicitly countermand. Thus a point of evaluation is indicated
-by a vertical rule which is the \texttt{diffcoeff} default\footnote{\noindent But not the ISO recommendation.}:
-\begin{example}
-\noindent \textbackslash diff.up.{*}\{\textbackslash frac\{F(x)\}\{G(x)\}\}x{[}x=1{]}
-$\Longrightarrow\quad{\displaystyle \diff.up.*{\frac{F(x)}{G(x)}}x[x=1]}$
-\end{example}
-
-\noindent Dot-delimited arguments must always be the \emph{first} argument
-of the \texttt{\textbackslash diff} command, even preceding an asterisk
-(star) as in this example.
+Apart from the \emph{key = value} settings, the critical feature here
+is the name, \texttt{up} (which is at your discretion and could equally
+be \texttt{upright} or \texttt{roman} or even \texttt{Fred} if you
+so fancied). This ensures that the changed settings apply only to
+this particular variant and do not `infect' the overall defaults.
+To use this variant, all that is needed is to add the name, between
+dots, to the \texttt{\textbackslash diff} command:
+\begin{centred}
+\verb`\[ \diff.up.yx \]` $\Longrightarrow$ \[ \diff.up.yx. \]
+\end{centred}
+\noindent Each variant derivative inherits all the default values
+that it does not explicitly countermand. Thus a point of evaluation
+is indicated by a vertical rule which is the \texttt{diffcoeff} default\footnote{\noindent But not the ISO recommendation.}:
+\begin{centred}
+\noindent \verb`\[ \diff.up.*{\frac{F(x)}{G(x)}}x[x=1] \]` $\Longrightarrow$
+\[ \diff.up.*{\frac{F(x)}{G(x)}}x[x=1] \]
+\end{centred}
+\noindent Dot-delimited arguments must always be the \emph{first}
+argument of the \texttt{\textbackslash diff} command, even preceding
+an asterisk (star) as in this example.
As another example, suppose for the subscripted indication of variables
held constant in a partial derivative that you want to see what things
-look like if the subscript is \emph{not }nudged in towards the right parenthesis.
-In that case define a variant form
+look like if the subscript is \emph{not }nudged in towards the right
+parenthesis. In that case define a variant form
\begin{lyxcode}
\textbackslash diffdef~\{~padrift~\}~\{~subscr-nudge~=~0~mu~\}
\end{lyxcode}
I have attached a name, \texttt{padrift},\texttt{ }to this setting,
-\begin{example}
-\textbackslash diff.padrift.Fx{[}y{]} $\Longrightarrow{\displaystyle \diff.padrift.Fx[y]}$
-\end{example}
-
-\noindent since, to my eye, the subscript seems detached from the expression
-it qualifies -- is it perhaps a typo? -- and `adrift in a sea of whitespace'.
-This is to be compared with the default
-\begin{example}
-\noindent \textbackslash diffp Fx{[}y{]} $\Longrightarrow{\displaystyle \diffp Fx[y]}$
-\end{example}
+\begin{centred}
+\verb`\[ \diff.padrift.Fx[y] \]` $\Longrightarrow$ \[ \diff.padrift.Fx[y] \]
+\end{centred}
+\noindent since, to my eye, the subscript seems detached from the
+expression it qualifies -- is it perhaps a typo? -- and `adrift
+in a sea of whitespace'. This is to be compared with the default \verb`\[ \diffp Fx[y] \]`
+$\Longrightarrow$ \[ \diffp Fx[y] \]
\noindent where the subscript is tucked in close to the right parenthesis
and is clearly connected to it and the expression it delimits.
-Some might want to distinguish notationally a point of evaluation for a
-partial derivative from variables held constant, perhaps using a vertical
-rule for the former and (the default) parentheses for the latter. It would
-suffice then to add to the preamble
-\begin{lyxcode}
-\noindent %
-\noindent\begin{minipage}[t]{1\columnwidth}%
+Some might want to distinguish notationally a point of evaluation
+for a partial derivative from variables held constant, perhaps using
+a vertical rule for the former and (the default) parentheses for the
+latter. It would suffice then to add to the preamble
\begin{lyxcode}
\textbackslash diffdef~\{~pvrule~\}~\{~op-symbol~=~\textbackslash partial~\}~
\end{lyxcode}
-%
-\end{minipage}
-\end{lyxcode}
(or some other name of your choosing). This gives
-\begin{example}
-\textbackslash diff.pvrule.\{F(x,y)\}x{[}x=1{]}$\Longrightarrow{\displaystyle \diff.pvrule.{F(x,y)}x[x=1]}$
-\end{example}
-
+\begin{centred}
+\verb`\[ \diff.pvrule.{F(x,y)}x[x=1] \]`$\Longrightarrow$ \[ \diff.pvrule.{F(x,y)}x[x=1] \]
+\end{centred}
-\subsubsection{Text-style and script-style derivatives\label{subsec:Text-and-script-style}}
+\subsubsection{Text-style and script-style derivatives\protect\label{subsec:Text-and-script-style}}
As noted earlier, the \texttt{diffcoeff} package assumes that derivatives
-of fraction-like form will be used in display-style expressions and that
-the slash form will be used for inline use (text style). This is the usual
-practice. But if one does want to use the fraction form in an inline expression,
-say \texttt{\textbackslash diffp ST{[}V{]}} displaying as $\diffp ST[V]$,
-then some tweaking of settings is necessary: the subscript is obviously
-too close to the right parenthesis and, to my eye, there is too much `elbowroom'
-between the derivative and the enclosing parentheses. Hence define
+of fraction-like form will be used in display-style expressions and
+that the slash form will be used for inline use (text style). This
+is the usual practice. But if one does want to use the fraction form
+in an inline expression, say \texttt{\textbackslash diffp ST{[}V{]}}
+displaying as $\diffp ST[V]$, then some tweaking of settings is necessary:
+the subscript is obviously too close to the right parenthesis and,
+to my eye, there is too much `elbowroom' between the derivative and
+the enclosing parentheses. Hence define
\noindent %
\noindent\begin{minipage}[t]{1\columnwidth}%
@@ -1339,34 +1517,28 @@ between the derivative and the enclosing parentheses. Hence define
%
\end{minipage}
-This gives, for the same example, \texttt{\textbackslash diff.ptxt.ST{[}V{]}}
-displaying as $\diff.ptxt.ST[V]$, where the subscript is better positioned
-and there is a better fit between parentheses and derivative.
+We can now write, for the same example, \texttt{\textbackslash diff.ptxt.ST{[}V{]}}
+which displays as $\diff.ptxt.ST[V]$, where the subscript is better
+positioned and there is a better fit between parentheses and derivative.
-\subsubsection{Derivatives from D, \textbackslash delta, \textbackslash Delta\label{subsec:D-delta-Delta}}
+\subsubsection{Derivatives from D, \textbackslash delta, \textbackslash Delta\protect\label{subsec:D-delta-Delta}}
-In addition to \texttt{\textbackslash diff.p.},\texttt{ diffcoeff} has
-three other \emph{built-in} variant forms that are commonly used: \texttt{\textbackslash diff.D.},
-\texttt{\textbackslash diff.delta.}, and \texttt{\textbackslash diff.Delta.},
-corresponding to derivatives formed from $D$, $\delta$ and $\Delta$
-respectively.
+In addition to \texttt{\textbackslash diff.p.},\texttt{ diffcoeff}
+has three other \emph{built-in} variant forms that are commonly used:
+\texttt{\textbackslash diff.D.}, \texttt{\textbackslash diff.delta.},
+and \texttt{\textbackslash diff.Delta.}, corresponding to derivatives
+formed from $D$, $\delta$ and $\Delta$ respectively.
In fluid dynamics the \emph{material }or \emph{substantive} derivative
-uses an uppercase $D$ in place of $d$. For example, the continuity equation
-is,
-\begin{example}
-\textbackslash diff.D.\{\textbackslash rho\}t=\textbackslash diffp\textbackslash rho
-t + \textbackslash mathbf\{u\textbackslash cdot\}\textbackslash nabla\textbackslash rho
-$\Longrightarrow{\displaystyle \diff.D.\rho t=\diffp\rho t+\mathbf{u\cdot}\nabla\rho}$
-\end{example}
-
+uses an uppercase $D$ in place of $d$. For example, the continuity
+equation is,
+\begin{centred}
+\verb`\[ \diff.D.{\rho}t=\diffp\rho t + \mathbf{u\cdot}\nabla\rho \]`$\Longrightarrow$
+\[ \diff.D.{\rho}t=\diffp\rho t + \mathbf{u\cdot}\nabla\rho \]
+\end{centred}
\noindent where \texttt{\textbackslash diff.D.} produces the D-derivative.
-If you want upright `D's, then the \texttt{ISO} package option will produce
-that effect. Alternatively, \vspace{-2ex}
-
-\begin{lyxcode}
-\noindent %
-\noindent\begin{minipage}[t]{1\columnwidth}%
+If you want upright `D's, then the \texttt{ISO} package option will
+produce that effect. Alternatively,
\begin{lyxcode}
\textbackslash diffdef~\{~Up~\}~
@@ -1378,84 +1550,78 @@ that effect. Alternatively, \vspace{-2ex}
~~\}
\end{lyxcode}
-%
-\end{minipage}
-\end{lyxcode}
\noindent provides a variant with upright `D's.
-In introductory calculus texts the simple $\delta$-derivative is used.
-This is achieved with the \texttt{\textbackslash diff.delta.} command
-\begin{example}
-\textbackslash diff.delta.yx $\Longrightarrow{\displaystyle \diff.delta.yx}.$
-\end{example}
+In introductory calculus texts the simple $\delta$-derivative is
+used. This is achieved with the \texttt{\textbackslash diff.delta.}
+command: \verb`\[ \diff.delta.yx \]` $\Longrightarrow$ \[ \diff.delta.yx. \]
-\noindent This form also features in analytical mechanics (in the Rogues'
-Gallery, the final example at (\ref{eq:eg6})).
+\noindent This form also features in analytical mechanics (in the
+Rogues' Gallery, the final example at (\ref{eq:eg6})).
-Similarly, \texttt{\textbackslash diff.Delta.} forms a derivative from
-$\Delta$:
-\begin{example}
-\textbackslash diff.Delta.y/x $\Longrightarrow{\displaystyle \diff.Delta.y/x,}$
-\end{example}
-
-\noindent where the slash form of the derivative is shown in this instance.
+Similarly, \texttt{\textbackslash diff.Delta.} forms a derivative
+from $\Delta$:
+\begin{centred}
+\verb`$ \diff.Delta.y/x $` $\Longrightarrow$ $ \diff.Delta.y/x $
+\end{centred}
+\noindent where the slash form of the derivative is shown in this
+instance.
Higher order forms of these derivatives, points of evaluation, appending
-the differentiand with a star argument, all follow exactly as for the `pure'
-\texttt{\textbackslash diff} command.
+the differentiand with a star argument, all follow exactly as for
+the `pure' \texttt{\textbackslash diff} command.
\paragraph{The commands \textbackslash Diff, \textbackslash diffd, \textbackslash Diffd}
-For compatibility with version 1 of \texttt{diffcoeff}, the commands \texttt{\textbackslash Diff},
-\texttt{\textbackslash diffd} and \texttt{\textbackslash Diffd} are available
-and also produce the $D$, $\delta$ and $\Delta$ derivatives. Just as
-\texttt{\textbackslash diffp} is identified with \texttt{\textbackslash diff.p.}
-for partial derivatives, these commands are identified with \texttt{\textbackslash diff.D.},
+For compatibility with version 1 of \texttt{diffcoeff}, the commands
+\texttt{\textbackslash Diff}, \texttt{\textbackslash diffd} and
+\texttt{\textbackslash Diffd} are available and also produce the
+$D$, $\delta$ and $\Delta$ derivatives. Just as \texttt{\textbackslash diffp}
+is identified with \texttt{\textbackslash diff.p.} for partial derivatives,
+these commands are identified with \texttt{\textbackslash diff.D.},
\texttt{\textbackslash diff.delta.}, and \texttt{\textbackslash diff.Delta}
-through commands equivalent to\footnote{In fact the actual commands in \texttt{diffcoeff.sty} use the syntax of
-the \texttt{xparse} package, e.g. \texttt{\textbackslash NewDocumentCommand
-\{ \textbackslash Diff \} \{ \} \{ }\textbackslash diff.D. \}, and similarly
-for the others.}
+through the commands
\begin{lyxcode}
-\textbackslash newcommand\{\textbackslash Diff\}\{\textbackslash diff.D.\}
+\textbackslash NewDocumentCommand~\textbackslash Diff~\{\}~~\{\textbackslash diff.D.\}
-\textbackslash newcommand\{\textbackslash diffd\}\{\textbackslash diff.delta.\}
+\textbackslash NewDocumentCommand~\textbackslash diffd~\{\}~\{\textbackslash diff.delta.\}
-\textbackslash newcommand\{\textbackslash Diffd\}\{\textbackslash diff.Delta.\}
+\textbackslash NewDocumentCommand~\textbackslash Diffd~\{\}~\{\textbackslash diff.Delta.\}
\end{lyxcode}
-Unless one is using such variant forms frequently, it seems simpler to
-remember that they are available as dot-delimited arguments to the \texttt{\textbackslash diff}
-command, using the obvious name in each case, rather than having to remember
-the precise camel-case form of name of the \texttt{\textbackslash Diff},
-\texttt{\textbackslash diffd} and \texttt{\textbackslash Diffd} commands.
+Unless one is using such variant forms frequently, it seems simpler
+to remember that they are available as dot-delimited arguments to
+the \texttt{\textbackslash diff} command, using the obvious name
+in each case, rather than having to remember the precise camel-case
+form of name of the \texttt{\textbackslash Diff}, \texttt{\textbackslash diffd}
+and \texttt{\textbackslash Diffd} commands.
-\subsection{The \texttt{.def} file\label{subsec:The-.def-file}}
+\subsection{The \texttt{.def} file\protect\label{subsec:The-.def-file}}
This mechanism of variant formation is how I have been able to illustrate
-in the Rogues' Gallery, Section~\ref{sec:Rogues'-gallery}, the wide variety
+in the Rogues' Gallery, \ref{sec:Rogues'-gallery}, the wide variety
of different usages culled from the literature. But the thought arises:
-if a variant is to be used only once or twice, isn't this a lot of bother?
-Why not just construct the variant derivative `by hand' out of \texttt{\textbackslash frac}
-and \texttt{\textbackslash mkern} for example? The reason for making such
-definitions is that they can be transferred from document to document.
-For instance, definitions placed in the preamble can be copied to the preamble
-of another document.
-
-But that is hardly optimal. Instead, \texttt{diffcoeff} allows such definitions
-to be placed in a text file with the the extension \texttt{.def} and a
-name of your choosing. For the present document the file is called \texttt{diffcoeff-doc.def}
-and has been placed in the same directory as \texttt{diffcoeff.tex}. To
-use these definitions, the \texttt{diffcoeff} package is called with the
-command
+if a variant is to be used only once or twice, isn't this a lot of
+bother? Why not just construct the variant derivative `by hand' out
+of \texttt{\textbackslash frac} and \texttt{\textbackslash mskip}
+for example? The reason for making such definitions is that they can
+be transferred from document to document. For instance, definitions
+placed in the preamble can be copied to the preamble of another document.
+
+But that is hardly optimal. Instead, \texttt{diffcoeff} allows such
+definitions to be placed in a text file with the the extension \texttt{.def}
+and a name of your choosing. For the present document the file is
+called \texttt{diffcoeff-doc.def} and has been placed in the same
+directory as \texttt{diffcoeff.tex}. To use these definitions, the
+\texttt{diffcoeff} package is called with the command
\begin{lyxcode}
\textbackslash usepackage{[}def-file=diffcoeff-doc{]}\{diffcoeff\}
\end{lyxcode}
But even this process still means copying a definition file from directory
-to directory as one works on different documents. The solution is to make
-a definition file available for \emph{all} documents and the way to do
-that is by placing it in the texmf tree, preferably not the one created
-by your \TeX{} distribution (perhaps MiKTeX or TexLive), but your own \emph{personal}
-texmf tree.
+to directory as one works on different documents. The solution is
+to make a definition file available for \emph{all} documents and the
+way to do that is by placing it in the texmf tree, preferably not
+the one created by your \TeX{} distribution (perhaps MiKTeX or TexLive),
+but your own \emph{personal} texmf tree.
\texttt{\vspace{2ex}
}
@@ -1464,19 +1630,20 @@ texmf tree.
\noindent\fbox{\begin{minipage}[t]{1\linewidth - 2\fboxsep - 2\fboxrule}%
\textbf{Personal texmf tree? }
-This is a directory for `waifs and strays' of the \TeX{} system that are
-not included in standard distributions like MiK\TeX{} or \TeX Live. For
-instance, it is the place for personal packages designed for your own particular
-circumstances or preferences, and is structured like the standard MiK\TeX{}
-or \TeX Live hierarchy but placed in another location so that there is
-no chance of its being overwritten when MiK\TeX{} or \TeX Live are updated.
-However, those distributions need to be alerted to its existence. For MiK\TeX ,
-open the MiK\TeX{} console, click on \textsf{Settings} and then the \textsf{Directories}
-tab. Click the \textsf{+} button and navigate to your personal texmf tree
-to add it to the MiK\TeX{} search path. Having added it, you will then need
-to refresh the filename database by clicking on the \textsf{Tasks} menu
-and selecting the obvious entry. I am not familiar with \TeX Live but presume
-a similar process will apply there.%
+This is a directory for `waifs and strays' of the \TeX{} system that
+are not included in standard distributions like MiK\TeX{} or \TeX Live.
+For instance, it is the place for personal packages designed for your
+own particular circumstances or preferences, and is structured like
+the standard MiK\TeX{} or \TeX Live hierarchy but placed in another
+location so that there is no chance of its being overwritten when
+MiK\TeX{} or \TeX Live are updated. However, those distributions need
+to be alerted to its existence. For MiK\TeX , open the MiK\TeX{} console,
+click on \textsf{Settings} and then the \textsf{Directories} tab.
+Click the \textsf{+} button and navigate to your personal texmf tree
+to add it to the MiK\TeX{} search path. Having added it, you will then
+need to refresh the filename database by clicking on the \textsf{Tasks}
+menu and selecting the obvious entry. I am not familiar with \TeX Live
+but presume an analogous process will apply there.%
\end{minipage}}
\medskip{}
@@ -1487,68 +1654,61 @@ to all documents.
\subsubsection{Structure of the \texttt{.def} file}
-The best way to see what a \texttt{.def} file looks like is to view \texttt{diffcoeff-doc.def
-}in a text editor.\footnote{This file should be in the same directory as \texttt{diffcoeff.pdf} and
-\texttt{diffcoeff.tex} in your \LaTeX{} distribution.}
+The best way to see what a \texttt{.def} file looks like is to view
+\texttt{diffcoeff-doc.def }in a text editor.\footnote{This file should be in the same directory as \texttt{diffcoeff.pdf}
+and \texttt{diffcoeff.tex} in your \LaTeX{} distribution.}
-If you want your variant definitions to use defaults different from those
-supplied with the \texttt{diffcoeff} package, then the first definition
-in the \texttt{.def} file should be the one setting the new defaults, with
-an \emph{empty} first argument to the \texttt{\textbackslash diffdef}
+If you want your variant definitions to use defaults different from
+those supplied with the \texttt{diffcoeff} package, then the first
+definition in the \texttt{.def} file should be the one setting the
+new defaults, with an \emph{empty} first argument to the \texttt{\textbackslash diffdef}
command:
\begin{lyxcode}
-\noindent %
-\noindent\begin{minipage}[t]{1\columnwidth}%
-\begin{lyxcode}
\textbackslash diffdef~\{\}~~~~
-\begin{lyxcode}
-\{~~~~~~
-\begin{lyxcode}
-key-1~=~value-1,~~~~
-key-2~=~value-2,
+~~\{~~~~~~
-...
+~~~~key-1~=~value-1,~~~~
-key-n~=~value-n
-\end{lyxcode}
-\}
-\end{lyxcode}
-\end{lyxcode}
-%
-\end{minipage}
+~~~~key-2~=~value-2,
+
+~~~~...
+
+~~~~key-n~=~value-n
+
+~~\}
\end{lyxcode}
-The key-value list is a comma-separated list; hence the last entry doesn't
-need to end with a comma. Nudge and separation values need to include the
-unit, \texttt{mu}; a numerical value alone will result in error.\texttt{ }Because
-a \texttt{.def} file\texttt{ }is a \LaTeX{} file, comments need to start
-with a \texttt{\%} character.
+The key-value list is a comma-separated list; hence the last entry
+doesn't need to end with a comma. Nudge and separation values need
+to include the unit, \texttt{mu}; a numerical value alone will result
+in error.\texttt{ }Because a \texttt{.def} file\texttt{ }is a \LaTeX{}
+file, comments need to start with a \texttt{\%} character.
\subsubsection{\texttt{diffcoeff.def}}
-Note that if the \texttt{diffcoeff} package is invoked without an explicit
-\texttt{def-file= <filename>} option statement, as here,
+Note that if the \texttt{diffcoeff} package is invoked without an
+explicit \texttt{def-file= <filename>} option statement, as here,
\begin{lyxcode}
\textbackslash usepackage\{diffcoeff\}
\end{lyxcode}
-then it will search in the texmf tree (the \LaTeX{} distribution's and your
-personal one) and the document directory for a file \texttt{diffcoeff.def}
-and if found will load that. This file should contain definitions of those
-variants you are likely to use in multiple documents. In my personal texmf
-tree (which I've put at \texttt{D:\textbackslash texmf\textbackslash}
-on a Windows machine) the file \texttt{diffcoeff.def} is located in the
-directory \texttt{D:\textbackslash texmf\textbackslash tex\textbackslash latex\textbackslash diffcoeff\textbackslash}.
+then it will search in the texmf tree (the \LaTeX{} distribution's
+and your personal one) and the document directory for a file \texttt{diffcoeff.def}
+and if found will load that. This file should contain definitions
+of those variants you are likely to use in multiple documents. In
+my personal texmf tree (which I've put at \texttt{E:\textbackslash texmf\textbackslash}
+on a Windows machine) the file \texttt{diffcoeff.def} is located in
+the directory \texttt{E:\textbackslash texmf\textbackslash tex\textbackslash latex\textbackslash diffcoeff\textbackslash}.
(The backslashes are replaced by forward slashes on linux machines.)
-Variants likely to be of value only to a specific document should be added
-to the preamble of that document. Alternatively, they could be added to
-\texttt{diffcoeff.def} but that added-to file saved to the document directory
-under a \emph{different} name -- e.g. I've saved the variants required
-for the present document under the name \texttt{diffcoeff-doc.def}. Many
-of these variants were created solely to illustrate points in the present
-document and I have no intention of using them in my own work. Consequently
-my \texttt{diffcoeff.def} file is smaller, containing only a selection
-from \texttt{diffcoeff-doc.def}.
+Variants likely to be of value only to a specific document should
+be added to the preamble of that document. Alternatively, they could
+be added to \texttt{diffcoeff.def} but that added-to file saved to
+the document directory under a \emph{different} name -- e.g. I've
+saved the variants required for the present document under the name
+\texttt{diffcoeff-doc.def}. Many of these variants were created solely
+to illustrate points in the present document and I have no intention
+of using them in my own work. Consequently my \texttt{diffcoeff.def}
+file is smaller, containing only a selection from \texttt{diffcoeff-doc.def}.
\section{Differentials in integrals, etc.}
@@ -1557,261 +1717,359 @@ point, and its omission from previous versions of \texttt{diffcoeff}.} for examp
\[
\dl P=\diffp Px\dl x+\diffp Py\dl y+\diffp Pz\dl z,
\]
-or an integral like $\int\sin x\dl2x$, or a multi-variable integral like
+or an integral like $\int\sin x\dl2x$, or a multi-variable integral
+like
\[
\iiintop_{-\infty}^{\infty}V(x,y,z)\dl3x\dl2y\dl2z.
\]
-Surely we want the `d's in these expressions to correspond to their form
-(upright or math italic) in derivatives? If, for instance, the \texttt{ISO}
-package option has been set, one doesn't want to be writing \texttt{\textbackslash mathrm\{d\}}
-in every (or indeed any) integral. To this end, \texttt{diffcoeff} provides
-a command \texttt{\textbackslash dl} to write the `d' in a differential
-in a manner consistent with the default form used in derivatives. In the
-present document, the default form is math-italic and so
-\begin{example}
-\textbackslash dl x $\Longrightarrow\dl x.$
-\end{example}
-
-\noindent It is also possible\footnote{\noindent From version 3.1 of \texttt{diffcoeff}; version 3.0 of the package
-produced a \LaTeX{} error.} to use the command before, for instance, \texttt{\textbackslash vec\{x\}}
-or \texttt{\textbackslash mathbf\{x\}}:
-\begin{example}
-\textbackslash dl \textbackslash vec\{x\} $\Longrightarrow\dl\vec{x}$~~~~\textbackslash dl
-\textbackslash mathbf\{x\} $\Longrightarrow\dl0\mathbf{x}.$
-\end{example}
-
+Surely we want the `d's in these expressions to correspond to their
+form (upright or math italic) in derivatives? If, for instance, the
+\texttt{ISO} package option has been set, one doesn't want to be writing
+\texttt{\textbackslash mathrm\{d\}} in every (or indeed any) integral.
+To this end, \texttt{diffcoeff} provides a command \texttt{\textbackslash dl}
+to write the `d' in a differential in a manner consistent with the
+default form used in derivatives. In the present document, the default
+form is math-italic and so
+\begin{centred}
+\verb`$ \dl x $` $\Longrightarrow$ $ \dl x. $
+\end{centred}
+\noindent It is also possible\footnote{\noindent From version 3.1 of \texttt{diffcoeff}; version 3.0 of the
+package produced a \LaTeX{} error.} to use the command before, for instance, \texttt{\textbackslash mathbf\{x\}}
+or \texttt{\textbackslash vec\{x\}}:
+\begin{centred}
+\verb`$ \dl \vec{x} $` $\Longrightarrow$ $ \dl \vec{x} $,~~~~\verb`$ \dl \mathbf{x} $`
+$\Longrightarrow$$ \dl \mathbf{x}. $
+\end{centred}
\subsection{Options}
There are two options available with the differential command.
-The first is the dotted name option discussed in Section~\ref{sec:Changing-defaults}.
+The first is the dotted name option discussed in \ref{sec:Changing-defaults}.
Thus, to illustrate a differential with an upright `d', write
-\begin{example}
-\textbackslash dl.up.x $\Longrightarrow\dl.up.x.$
-\end{example}
-
-\noindent This presumes that a variant derivative with upright `d's has
-been defined and the definition is available, either in the preamble or
-in an accessible \texttt{.def} file, as discussed in the previous section.
-Alternatively, if you have defined your default derivative to use upright
-`d's (perhaps with the \texttt{ISO} option) then \texttt{\textbackslash dl}
-alone will suffice to produce an upright `d'.
-
-Since the variant \texttt{\textbackslash diff.p.} is defined in \texttt{diffcoeff.sty}
-itself, \texttt{\textbackslash dl.p.} is always available and at 6 keystrokes
-offers a slightly shorter way of writing \texttt{\textbackslash partial}
-(8 keystrokes). But the only reason one might use this variant `in earnest'
-is because of the convenience offered by the second option to the \texttt{\textbackslash dl}
-command.
+\begin{centred}
+\verb`$ \dl.up.x $` $\Longrightarrow$ $ \dl.up.x. $
+\end{centred}
+\noindent This presumes that a variant derivative with upright `d's
+has been defined and the definition is available, either in the preamble
+or in an accessible \texttt{.def} file, as discussed in the previous
+section. Alternatively, if you have defined your default derivative
+to use upright `d's (perhaps with the \texttt{ISO} option) then
+\texttt{\textbackslash dl} alone will suffice to produce an upright
+`d'.
+
+\subsubsection{Partial differential}
+
+\label{subsec:Partial-differential}Since the variant \texttt{\textbackslash diff.p.}
+is defined in \texttt{diffcoeff.sty} itself, \texttt{\textbackslash dl.p.}
+is always available and at 6 keystrokes offers a slightly shorter
+way of writing \texttt{\textbackslash partial} (8 keystrokes). However,
+there are sufficient contexts where expressions like \verb`\partial_x`
+are used, perhaps as a shortcut for a partial derivative, for it to
+be worthwhile to define an appropriate command for this variant. From
+version 4.0, \texttt{diffcoeff} therefore provides \verb`\dlp`, defined
+by
+\begin{lyxcode}
+\textbackslash NewDocumentCommand~\textbackslash dlp~\{\}~\{~\textbackslash dl.p.~\}
+\end{lyxcode}
+Thus, for instance, \verb`$ \dlp_x $` $\Longrightarrow$ $ \dlp_x $.
\subsubsection{Spacing}
This second option inserts spacing before the `d'. If \texttt{\textbackslash dl}
-is followed by a digit (0, 1, 2, ..., 9) it will insert a horizontal space
-of that number of mu before the `d'; (\texttt{\textbackslash dl0x} has
-the same effect as \texttt{\textbackslash dl x}.)\texttt{ }Thus, an alternative
-way of writing an example in Chapter~18 of \emph{The \TeX book} is
-\begin{example}
-\textbackslash dl x\textbackslash dl3y=r\textbackslash dl3r\textbackslash dl3\textbackslash theta
-$\Longrightarrow\dl x\dl3y=r\dl3r\dl3\theta.$
-\end{example}
-
+is followed by a digit (0, 1, 2, ..., 9) it will insert a horizontal
+space of that number of mu before the `d'; (\texttt{\textbackslash dl0x}
+has the same effect as \texttt{\textbackslash dl x}.)\texttt{ }Thus,
+an alternative way of writing an example in Chapter~18 of \emph{The
+\TeX book} is
+\begin{centred}
+\verb`$ \dl x\dl3y=r\dl3r\dl3\theta $` $\Longrightarrow$ $ \dl x\dl3y=r\dl3r\dl3\theta. $
+\end{centred}
\noindent To my eye this is too much space; I prefer
-\begin{example}
-\noindent \textbackslash dl x\textbackslash dl2y=r\textbackslash dl2r\textbackslash dl2\textbackslash theta
-$\Longrightarrow\dl x\dl2y=r\dl2r\dl2\theta$
-\end{example}
-
+\begin{centred}
+\noindent \verb`$ \dl x\dl2y=r\dl2r\dl2\theta $` $\Longrightarrow$
+$ \dl x\dl2y=r\dl2r\dl2\theta. $
+\end{centred}
\noindent I used \texttt{\textbackslash dl3x\textbackslash dl2y\textbackslash dl2z}
-when writing the triple integral above, \emph{no} extra spacing when writing
-the total differential expression, since the differentials are already
-distinct from the preceding fraction forms $\diff.ptxt.Px$ etc., and \texttt{\textbackslash dl2x}
-when writing $\int\sin x\dl2x$.
+when writing the triple integral above, \emph{no} extra spacing when
+writing the total differential expression, since the differentials
+are already distinct from the preceding fraction forms $\diff.ptxt.Px$
+etc., and \texttt{\textbackslash dl2x} when writing $\int\sin x\dl2x$.
Note that only \emph{one} digit can be used. If two are used, as here,
-\begin{example}
-\textbackslash dl20x $\Longrightarrow\dl20x$
-\end{example}
-
-\noindent the effect is unlikely to be what is wanted.
-
-From version 3.2 of \texttt{diffcoeff} it is possible to also add \emph{negative}
-space before the differential, which might be useful in special contexts,
-perhaps to construct a symbol:
-\begin{example}
-/\textbackslash dl-9x $\Longrightarrow/\dl-9x.$
-\end{example}
-
-\noindent For negative space before the differential, add a minus sign
-before the (single) digit.
+\verb`$ \dl20x $` $\Longrightarrow$ $ \dl20x $, the effect is unlikely
+to be what is wanted.
+
+From version 3.2 of \texttt{diffcoeff} it is possible to also add
+\emph{negative} space before the differential, which might be useful
+in special contexts, perhaps to construct a symbol:
+\begin{centred}
+\verb`$ /\dl-9x $` $\Longrightarrow$ $ /\dl-9x. $
+\end{centred}
+\noindent For negative space before the differential, add a minus
+sign before the (single) digit.
The spacing digit option \emph{follows} the dot-delimited name option.
-For example, to illustrate spacing in the denominator of a mixed partial
-derivative, I have earlier used \texttt{\textbackslash dl.p.x\textbackslash dl.p.2y\textbackslash dl.p.2z},
-and the variation to that spacing when a higher-order differentiation occurs:
-\begin{example}
-\textbackslash dl.p.x\textasciicircum 2\textbackslash dl.p.1y\textbackslash dl.p.2z
-$\Longrightarrow\dl.p.x^{2}\dl.p.1y\dl.p.2z.$
-\end{example}
-
+For example, earlier, in the denominator of a mixed partial derivative,
+I have used what is effectively \texttt{\textbackslash dlp x\textbackslash dlp2y\textbackslash dlp2z},
+and the variation to that spacing when a higher-order differentiation
+occurs:
+\begin{centred}
+\verb`$ \dlp x^2\dlp1y\dlp2z $` $\Longrightarrow$ $ \dlp x^2\dlp1y\dlp2z. $
+\end{centred}
\section{Rationale}
Version 1 of the \texttt{diffcoeff} package arose from a need to simplify
-the parsing of differential coefficients for another program I was working
-on which was struggling to `read' all the possible permutations of \texttt{\textbackslash frac}
-or \texttt{\textbackslash tfrac} or \texttt{\textbackslash dfrac} or
-slash forms of the derivative, of \texttt{d} or \texttt{\textbackslash mathrm\{d\}}
-or \texttt{\textbackslash partial} or \texttt{D} or \texttt{\textbackslash mathrm\{D\}}
-or \texttt{\textbackslash nabla},\texttt{ }and of points of evaluation
-delimited by vertical rules or parentheses.\texttt{ }Although regular expressions
-coped with most of these cases, it was \emph{messy}.
+the parsing of differential coefficients for another program I was
+working on which was struggling to `read' all the possible permutations
+of \texttt{\textbackslash frac} or \texttt{\textbackslash tfrac}
+or \texttt{\textbackslash dfrac} or slash forms of the derivative,
+of \texttt{d} or \texttt{\textbackslash mathrm\{d\}} or \texttt{\textbackslash partial}
+or \texttt{D} or \texttt{\textbackslash mathrm\{D\}} or \texttt{\textbackslash nabla},\texttt{
+}and of points of evaluation delimited by vertical rules or parentheses.\texttt{ }Although
+regular expressions coped with most of these cases, it was \emph{messy}.
There are other packages which have commands for the derivative (e.g.,
-\texttt{bropd}, \texttt{commath},\texttt{ esdiff}, \texttt{physymb}) but
-none quite gave what I wanted -- although they probably cope with most
-users' needs. \texttt{esdiff} came closest to what I was seeking but failed
-when it came to combining algebraic and numeric orders of differentation
-in a mixed partial derivative (and made heavier use of braces than I would
-like in that case too).
+\texttt{bropd}, \texttt{commath},\texttt{ esdiff}, \texttt{physymb})
+but none quite gave what I wanted -- although they probably cope
+with most users' needs. \texttt{esdiff} came closest to what I was
+seeking but failed when it came to combining algebraic and numeric
+orders of differentation in a mixed partial derivative (and made heavier
+use of braces than I liked in that case too).
\subsection{\texttt{diffcoeff.sty}}
-I have tried to make using \texttt{diffcoeff} intuitive. Looking at the
-other packages mentioned, writing something like \texttt{\textbackslash diff{[}n{]}\{f\}\{x\}}
-(which can be trimmed to \texttt{\textbackslash diff{[}n{]}fx} for single-token
-arguments) seems `natural' -- only \texttt{physymb} deviates from the
-pattern.
+I have tried to make using \texttt{diffcoeff} intuitive. Looking at
+the other packages mentioned, writing something like \texttt{\textbackslash diff{[}n{]}\{f\}\{x\}}
+(which can be trimmed to \texttt{\textbackslash diff{[}n{]}fx} for
+single-token arguments) seems `natural' -- only \texttt{physymb}
+deviates from the pattern.
\begin{itemize}
\item It seems consistent with this pattern to use a comma list for specifying
the orders of differentiation of the variables in a higher order mixed
partial derivative (and its suppression when all are of order 1)
\item Having specified the orders, surely the program itself should calculate
-the overall order? \texttt{esdiff} does this for numerical orders; \texttt{diffcoeff}
-does this for both numeric and algebraic orders,
+the overall order? \texttt{esdiff} does this for numerical orders;
+\texttt{diffcoeff} does this for both numeric and algebraic orders,
\end{itemize}
+\begin{centred}
+\verb`\[ \diffp[m-(k+1),m+(k-1)]{F(x,y,z)}{x,y,z} \]`
+\end{centred}
\begin{example}
-\textbackslash diffp{[}m-(k+1),m+(k-1){]}\{F(x,y,z)\}\{x,y,z\}
-
-$\Longrightarrow{\displaystyle \diffp[m-(k+1),m+(k-1)]{F(x,y,z)}{x,y,z}},$
+$\Longrightarrow$ \[ \diffp[m-(k+1),m+(k-1)]{F(x,y,z)}{x,y,z} \]
\end{example}
\begin{itemize}
-\item and where it fails, either to calculate at all or to present the result
+\item and where it fails either to calculate at all or to present the result
in a preferred form, offers the order-override option:
\end{itemize}
+\begin{centred}
+\verb`\[ \diffp[m+(k+1),m+(k-1)][2(m+k+1)]{F(x,y,z,w)}{x,y,z,w} \]`
+\end{centred}
\begin{example}
-\textbackslash diffp{[}m+(k+1),m+(k-1){]}{[}2(m+k+1){]}\{F(x,y,z,w)\}\{x,y,z,w\}
-
-$\Longrightarrow{\displaystyle \diffp[m+(k+1),m+(k-1)][2(m+k+1)]{F(x,y,z,w)}{x,y,z,w}}.$
+$\Longrightarrow$ \[ \diffp[m+(k+1),m+(k-1)][2(m+k+1)]{F(x,y,z,w)}{x,y,z,w} \]
\end{example}
\begin{itemize}
-\item I wished to avoid the unnecessary writing of superscripts, subscripts and
-brace pairs. In the examples just given, no superscript tokens \texttt{\textasciicircum}
-are written by the user despite the higher-order differentiation in $x$
-and $y$, and only the two inescapable brace pairs are required.
+\item I wished to avoid the unnecessary writing of superscripts, subscripts
+and brace pairs. In the examples just given, no superscript tokens
+\texttt{\textasciicircum} are written by the user despite the higher-order
+differentiation in $x$ and $y$, and only the two inescapable brace
+pairs are required.
\item The use of a comma list for the second mandatory argument in a partial
-derivative -- the list of variables -- makes differentiations in super-
-or subscripted symbols (as occurs prolifically in tensor calculus) easier
-to both write and read by avoiding unnecessary brace pairs.
+derivative -- the list of variables -- makes differentiations in
+super- or subscripted symbols (as occurs prolifically in tensor calculus)
+easier to both write and read by avoiding unnecessary brace pairs.
\end{itemize}
-\begin{example}
-\textbackslash diffp\{A\_i\}\{ x\textasciicircum j,x\textasciicircum k
-\} $\Longrightarrow\quad{\displaystyle \diffp{A_{i}}{x^{j},x^{k}}.}$
-\end{example}
-
+\begin{centred}
+\verb`\[ \diffp{A_i}{ x^j,x^k } \]` $\Longrightarrow$ \[ \diffp{A_i}{ x^j,x^k } \]
+\end{centred}
\begin{itemize}
-\item Should a point of evaluation or variables held constant be considered part
-of the derivative? Thermodynamic usage was decisive here. The partial derivative
-alone is ambiguous -- the parentheses and subscript are essential to understand
-what is being stated:
+\item Should a point of evaluation or variables held constant be considered
+part of the derivative? Thermodynamic usage was decisive here. The
+partial derivative alone is ambiguous -- the parentheses and subscript
+are essential to understand what is being stated:
\[
\diffp ST[V]
\]
Hence provision for these extra elements was included in the derivative
commands.
\item Given the position of the subscripted symbol in the displayed derivative,
-it's positioning as the \emph{final} argument in the derivative commands
+it's positioning as the \emph{final} argument in the derivative command
feels inevitable.
\item Version 1 of \texttt{diffcoeff} used braces for this argument to avoid
-any possible confusion with a following mathematical expression. That use
-of braces is now deprecated in \texttt{xparse}. Consequently later versions
-of the package use square brackets, conforming with familiar \LaTeX{} practice.
-The only special remembering needed is avoidance of a space before the
-argument -- and if it does slip in, it won't cause a \LaTeX{} error. It
-will be treated as part of a following mathematical expression and displayed
-as such.
-\item The star option also prompted the question: is it needed? After all, one
-can always leave the first mandatory argument empty and append the differentiand
-`by hand'. But once the provision for points of evaluation or variables
-held constant was incorporated into the derivative commands, the star option
-became the simplest way of handling appended differentiands since the parentheses
-for a variable held constant must wrap around the differential operator
-\emph{and} differentiand. Once available, it provides a simple way of switching
-between (and comparing) the appearance of differentiand-in-the-numerator
-and differentiand-appended.
-\item The slash option was added to the derivative commands after seeing how
-widely such forms are used in texts at all levels. The placement of the
-slash, between the two mandatory arguments, seems more-or-less self-evident.
-\item The final option added to \texttt{\textbackslash diff} (and not present
+any possible confusion with a following mathematical expression. That
+use of braces is now deprecated in \texttt{xparse}, has been deprecated
+in \texttt{diffcoeff} since version 2, and is no longer compatible
+with version 4. Later versions of \texttt{diffcoeff} use square brackets,
+conforming with familiar \LaTeX{} practice. The only special remembering
+needed is avoidance of a space before the argument -- and if it does
+slip in, it won't cause a \LaTeX{} error. It will be treated as part
+of a following mathematical expression and displayed as such.
+\item The star option also prompted the question: is it needed? After all,
+one can always leave the first mandatory argument empty and append
+the differentiand `by hand'. But once the provision for points of
+evaluation or variables held constant was incorporated into the derivative
+commands, the star option became the simplest way of handling appended
+differentiands since the parentheses for a variable held constant
+must wrap around the differential operator \emph{and} differentiand.
+Once available, it provides a simple way of switching between (and
+comparing) the appearance of differentiand-in-the-numerator and differentiand-appended.
+\item The slash option was added to the derivative commands after seeing
+how widely such forms are used in texts at all levels. The placement
+of the slash, between the two mandatory arguments, seems more-or-less
+self-evident.
+\item A later option added to \texttt{\textbackslash diff} (and not present
in version 1) was the dot-delimited name option. Once \texttt{xtemplate}
was used as the basis of the package this seemed the most straightforward
-way of making available, ready to hand, the wealth of variants that \texttt{xtemplate}
-makes possible. (It's just a pity that the second dot is needed, and a
-single-dot naming scheme can't be used, but \texttt{xparse} forces my hand
-here.)
-\item Having added the dot-delimited name option, the use of a \texttt{.def}
-file to store variants or preferred defaults is more-or-less forced, otherwise
-one is faced with making these definitions anew for each new document (or
-locating a previous document and copying from that to the new one).
-\item To handle possible differences between display-style and text-style (and
-script-style) derivatives (see Subsection~\ref{subsec:Text-and-script-style})
+way of making available, ready to hand, the wealth of variants that
+\texttt{xtemplate} makes possible. (It's just a pity that the second
+dot is needed, and a single-dot naming scheme can't be used, but \texttt{xparse}
+forces my hand here.)
+\item Having added the dot-delimited name option, the use of a \texttt{def}
+file to store variants or preferred defaults is more-or-less forced,
+otherwise one is faced with making these definitions anew for each
+new document (or locating a previous document and copying from that
+to the new one).
+\item To handle possible differences between display-style and text-style
+(and script-style) derivatives (see \ref{subsec:Text-and-script-style})
I considered using \TeX 's \texttt{\textbackslash mathchoice} command.
-This command takes four arguments, corresponding to display-, text-, script-
-and scriptscript-styles and would require forming four derivatives each
-time a derivative is used, `just in case'. In fact fraction-form derivatives
-are used overwhelmingly in display-style expressions, the slash form being
-used for inline use. Given the ease of defining a fraction-form variant
-for text-style use, and the rareness of such use, employing variants seemed
-the way to go. It is the one adopted and avoids the computational burden
-associated with the use of \texttt{\textbackslash mathchoice}.
-\item After version 2 of the package appeared on CTAN, it was pointed out to
-me that there was an issue of consistency between the form of `d' used
-in a derivative (upright or math-italic) and the form used in an integral.
-I had overlooked this matter completely and in version 3 of the package
-remedied the omission with the differential command \texttt{\textbackslash dl}.
-A spacing option for \texttt{\textbackslash dl} was almost inevitable.
-The demands of writing the present document forced another, the dot-delimited
-name option.
+This command takes four arguments, corresponding to display-, text-,
+script- and scriptscript-styles and would require forming four derivatives
+each time a derivative is used, `just in case'. In fact fraction-form
+derivatives are used overwhelmingly in display-style expressions,
+the slash form being used for inline use. Given the ease of defining
+a fraction-form variant for text-style use, and the rareness of such
+use, employing variants seemed the way to go. It is the one adopted
+and avoids the computational burden associated with the use of \texttt{\textbackslash mathchoice}.
+\item After version 2 of the package appeared on CTAN, it was pointed out
+to me that there was an issue of consistency between the form of `d'
+used in a derivative (upright or math-italic) and the form used in
+an integral. I had overlooked this matter completely and in version
+3 of the package remedied the omission with the differential command
+\texttt{\textbackslash dl}. A spacing option for \texttt{\textbackslash dl}
+was almost inevitable. From version 4 the partial analogue \texttt{\textbackslash dlp}
+has been added.
+\item Space before the differentiand was requested by a user. Once considered
+it became clear that there are (at least) two ways of thinking of
+a derivative: as $\diff y/x$, a ratio of differentials where $\dl y$
+is a unit and it makes no sense to insert space between the `d'
+and the `y', and as
+\[
+\diff!{F(x)}x
+\]
+where the function $F(x)$ is being operated on by $\diff{}/x$ and
+it is natural to insert space between the `d' and the `F'. With
+that realisation came the need for a simple switch-like package option
+(\verb`spaced`) to turn spacing on or off, and a switch-like argument
+(\verb`!`) to countermand the package option in exceptional cases
+(version 4).
\end{itemize}
+\section{Version comparison}
+
+\label{sec:Version-comparison}Unlike version 1, version 2 and later
+are built on the the \texttt{xtemplate} package which makes certain
+facilities available which it would be silly not to exploit. Hence
+the coding in the later versions is completely different and there
+are consequences.
+\begin{enumerate}
+\item From version 2.0
+\begin{enumerate}
+\item The \texttt{\textbackslash diffset} command, formerly used to tweak
+the display of derivatives, has been superseded by the \texttt{\textbackslash diffdef}
+command. \texttt{\textbackslash diffset} now sends a message warning
+of its obsolescence to the terminal and \LaTeX{} log but is otherwise
+functionless. It should not interfere with the compilation of a document
+but any intended fine-tuning of the display by means of the \texttt{\textbackslash diffset}
+command\texttt{ }will not eventuate. The warning message is: \texttt{Obsolete
+command: \textbackslash diffset has been superseded by the \textbackslash diffdef
+command.} \texttt{See the diffcoeff} \texttt{doc\-umentation for
+further information.} The \texttt{\textbackslash diffdef} command
+is discussed in \ref{subsec:diffdef};
+\item The optional trailing argument used to indicate a point of evaluation
+or variables held constant is now delimited by square brackets, \texttt{{[}}
+and \texttt{{]}}, as other optional arguments are. For compatibility
+with version 1, versions 2 and 3 still accepted braces to delimit
+this argument but from version 4 of \texttt{diffcoeff} only the square-bracket
+delimited argument is accepted. (The use of braces around \emph{optional}
+arguments while once accepted is now deprecated in \texttt{xparse}
+on which \texttt{diffcoeff} depends);
+\item The commands \texttt{\textbackslash Diff}, \texttt{\textbackslash diffd}
+and \texttt{\textbackslash Diffd} used to construct derivatives from
+$D$, $\delta$ and $\Delta$ in version 1, are still available but
+deprecated. A new optional argument in the \texttt{\textbackslash diff}
+command offers these and a host of other possibilities and is now
+the preferred method of forming such variants; see \ref{subsec:D-delta-Delta}.
+\end{enumerate}
+\item Version 3.0
+\begin{enumerate}
+\item adds a command, \texttt{\textbackslash dl} (from \emph{d}ifferentia\emph{l})
+to write differentials like $dx$ that occur in integrals and in other
+contexts in a manner consistent with the form used in derivatives.
+After all, if one is using upright `d's in derivatives, similarly
+upright `d's should occur in these other contexts;\footnote{This rather obvious lack in version 2 was pointed out to me by Sergio
+Callegari.}
+\item provides some simple spacing commands that can be useful for tweaking
+standard spacing.
+\end{enumerate}
+\item Version 3.1 enables the differential command to be used before forms
+like \texttt{\textbackslash vec\{x\}} (an overlooked possibility
+causing an error in earlier versions).
+\item Version 3.2
+\begin{enumerate}
+\item allows negative spacing before the differential command \texttt{\textbackslash dl};
+\item fixes a bug in which an ordinary derivative as the differentiand of
+a partial derivative displayed as a partial derivative. It now displays,
+as it should, as an ordinary derivative.
+\end{enumerate}
+\item Version 4.0
+\begin{enumerate}
+\item enables the insertion of a small space before the differentiand, either
+as the default behaviour (package option \verb`spaced`) or at explicit
+request (argument \verb`!` of the \verb`\diff` command); see \ref{subsec:Spacing-before-derivand}.
+\item prevents the ligature $df$ that marred previous versions; this is
+now rendered $\dl f$.
+\item offers the document command \verb`\dlp` for the \emph{partial} differential;
+see \ref{subsec:Partial-differential};
+\item no longer accepts \emph{the braced form} of the\emph{ }trailing optional
+argument specifying a point of evaluation or (for partial derivatives)
+variables held constant. This was a relic from version 1 of \texttt{diffcoeff},
+and has been deprecated since version 2.
+\end{enumerate}
+\end{enumerate}
+
\section{Commands}
\begin{description}
-\item [{\texttt{\textbackslash diff}}] options:
+\item [{\texttt{\textbackslash diff}}] arguments (all optional unless
+otherwise indicated):
\begin{enumerate}
\item .\emph{name}. for the given settings
\item {*} append-differentiand switch
\item {[}\emph{order}{]} or {[}\emph{comma-list of orders}{]} of differentiation
\item {[}\emph{order-override}{]}
+\item ! countermand before-differentiand spacing of the \verb`spaced` package
+option
\item \{\emph{differentiand}\} (mandatory)
\item / slash-form switch
\item \{\emph{comma list of differentiation variables}\} (mandatory)
\item {[}\emph{point of evaluation/variables held constant}{]}
-\item \{as for previous, but using braces\} (deprecated)
\end{enumerate}
-\item [{\texttt{\textbackslash diffdef}}] options:
+\item [{\texttt{\textbackslash diffdef}}] arguments (all mandatory):
\begin{enumerate}
\item \{\emph{name}\}
\item \{\emph{key=value comma list}\}
\end{enumerate}
-\item [{\texttt{\textbackslash diffp}}] \texttt{= \textbackslash diff.p.}
-\item [{\texttt{\textbackslash dl}}] options:
+\item [{\texttt{\textbackslash diffp}}] \texttt{= \textbackslash diff.p.}
+\end{description}
+\newpage{}
+\begin{description}
+\item [{\texttt{\textbackslash dl}}] arguments (all optional):
\begin{enumerate}
\item .\emph{name}. (as for \texttt{\textbackslash diff})
-\item \emph{minus sign} (optional, use only if negative spacing before the `d'
-is wanted)
+\item \emph{minus sign} (optional, use only if negative spacing before the
+`d' is wanted)
\item \emph{digit} (insert spacing of this number of mu before the `d')
\end{enumerate}
\item [{\texttt{\textbackslash negmu}}] insert a $-1$ mu space
@@ -1819,7 +2077,8 @@ is wanted)
\item [{\texttt{\textbackslash onemu}}] insert a $1$ mu space
\item [{\texttt{\textbackslash twomu}}] insert a $2$ mu space
\end{description}
-Deprecated:
+Deprecated (why try remembering the special names when the forms on
+the right are self-explanatory):
\begin{description}
\item [{\texttt{\textbackslash Diff}}] preferred form: \texttt{\textbackslash diff.D.}
\item [{\texttt{\textbackslash diffd}}] preferred form \texttt{\textbackslash diff.delta.}
diff --git a/macros/latex/contrib/wrapfig2/README.txt b/macros/latex/contrib/wrapfig2/README.txt
new file mode 100644
index 0000000000..38d2c8a284
--- /dev/null
+++ b/macros/latex/contrib/wrapfig2/README.txt
@@ -0,0 +1,24 @@
+%%%% README.txt file
+This README.txt for package wrapfig2[2021-12-25 v.4.0 ...]
+
+This work is author maintained
+
+This work consists of wrapfig2.dtx, the main file, this README.txt
+and the derived files wrapfig2.pdf and wrapfig2.sty.
+
+Licence appended to the wrapfig2.sty file.
+
+The software contained herein is a fork of Donald Arseneau wrapfig
+package. It uses most of his code, but adds a new environment,
+wraptext, to the existing wrapfigure and wraptable. In addition
+most code uses the LaTeX3 functionalities.
+
+Supposedly this software is backwards compatible with Arseneau's
+original environments. Future experience may confirm this statement.
+
+The user commands are defined by means of the LaTeX3 functionalities.
+Therefore this package does not work with LaTeX2e kernels older than about 2018, although a warning is issued if the LaTeX format file is dated with a date older than 1st January 2019.
+
+Claudio Beccari
+
+claudio dot beccari at gmail dot com \ No newline at end of file
diff --git a/macros/latex/contrib/wrapfig2/wrapfig2.dtx b/macros/latex/contrib/wrapfig2/wrapfig2.dtx
new file mode 100644
index 0000000000..5b6d9f8813
--- /dev/null
+++ b/macros/latex/contrib/wrapfig2/wrapfig2.dtx
@@ -0,0 +1,1397 @@
+% \iffalse
+% !TEX encoding = UTF-8 Unicode
+% Remember to use \StopEventually{}, otherwise no Check Sum
+%<*internal>
+\begingroup
+\input docstrip.tex
+\keepsilent
+\preamble
+
+Copyright (C) 1991-2003 by Donald Arseneau (asnd@triumf.ca)
+Copyright (C) 2021 by Claudio Beccari (claudio.beccari@gmail.com)
+License information appended
+
+\endpreamble
+
+\postamble
+
+Distributable under the LaTeX Project Public License,
+version 1.3c or higher (your choice). The latest version of
+this license is at: http://www.latex-project.org/lppl.txt
+
+This work is "maintained"
+
+This work consists of file wrapfig2.dtx, and the derived files
+wrapfig2.sty and wrapfig2.pdf, plus the auxiliary file README.txt.
+
+\endpostamble
+\askforoverwritefalse
+
+\generate{\file{wrapfig2.sty}{\from{wrapfig2.dtx}{package}}}
+
+\def\tmpa{plain}
+\ifx\tmpa\fmtname\endgroup\expandafter\bye\fi
+\endgroup
+%</internal>
+% \fi
+%
+% \iffalse
+%<*package>
+%<package>\NeedsTeXFormat{LaTeX2e}[2019/01/01]
+%</package>
+%<*driver>
+\ProvidesFile{wrapfig2.dtx}%
+%</driver>
+%<+package>\ProvidesPackage{wrapfig2}%
+%^^A<+readme>File README.txt for package wrapfig2
+%<*package|readme>
+ [2021-12-21 v.4.0 Wrapfig extended]
+%</package|readme>
+%<*driver>
+%
+\documentclass{ltxdoc}\errorcontextlines=100
+\hfuzz 10pt
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage{lmodern}
+\usepackage{mflogo}
+\usepackage{multicol,amsmath,fancyvrb,graphicx,verbatim,pict2e,trace}
+\usepackage{xfp,xcolor,wrapfig2,tcolorbox,kantlipsum,xspace}
+\GetFileInfo{wrapfig2.dtx}
+\title{The \textsf{wrapfig2} package}
+\author{Claudio Beccari\thanks{E-mail: \texttt{claudio dot beccari at gmail dot com}}}
+\date{Version \fileversion~--~Last revised \filedate.}
+\providecommand*\diff{\mathop{}\!\mathrm{d}}
+\renewcommand\meta[1]{{\normalfont\textlangle\textit{#1}\textrangle}}
+\renewcommand\marg[1]{\texttt{\{\meta{#1}\}}}
+\providecommand\opz{}
+\renewcommand\opz[1]{{\normalfont\texttt{\itshape#1}}}
+\providecommand\Marg{}
+\renewcommand\Marg[1]{\texttt{\{#1\}}}
+\providecommand\oarg{}
+\renewcommand\oarg[1]{\texttt{[\meta{#1}]}}
+\providecommand\Oarg{}
+\renewcommand\Oarg[1]{\texttt{[#1]}}
+\providecommand\aarg{}
+\renewcommand*\aarg[1]{\texttt{<\meta{#1}>}}
+\providecommand\Aarg{}
+\renewcommand\Aarg[1]{\texttt{<#1>}}
+\providecommand\barg{}
+\renewcommand\barg[1]{\texttt{\string|\meta{#1}\string|}}
+\providecommand\Barg{}
+\renewcommand\Barg[1]{\texttt{\string|#1\string|}}
+\providecommand\parg{}
+\renewcommand\parg[1]{\texttt{(\meta{#1})}}
+\providecommand\Parg{}
+\renewcommand\Parg[1]{\texttt{(#1)}}
+\providecommand\eTeX{}
+\renewcommand\eTeX{\lower0.5ex\hbox{$\varepsilon\!$}\TeX}
+\providecommand\pack{}
+\renewcommand\pack[1]{{\normalfont\texttt{#1}}}
+\providecommand\class{}
+\renewcommand\class[1]{{\normalfont\texttt{#1}}}
+\providecommand\env{}
+\renewcommand\env[1]{\meta{\textsf{\slshape#1}}}\let\amb\env
+\providecommand\Env{}
+\renewcommand\Env[1]{\textsf{\slshape#1}}\let\Amb\Env
+\providecommand*\Bambiente[1]{\texttt{\char92begin\{#1\}}}
+\providecommand*\Eambiente[1]{\texttt{\char92end\{#1\}}}
+\let\Bamb\Bambiente \let\Benv\Bamb
+\let\Eamb\Eambiente \let\Eenv\Eamb
+
+\makeatletter
+
+\AfterEndPreamble{%
+\apptocmd{\TeX}{{}\xspace}{}{}
+\apptocmd{\LaTeX}{{}\xspace}{}{}}
+
+\DeclareRobustCommand\LaTeXe{%
+ \LaTeX\@killglue\kern0.15em2$_{\textstyle \varepsilon}${}\xspace}
+\DeclareRobustCommand\LaTeXccix{%
+ \LaTeX\@killglue\nobreakspace2.09{}\xspace}
+\DeclareRobustCommand\LaTeXiii{\LaTeX\@killglue\kern0.15em3{}\xspace}
+\DeclareRobustCommand*\pdfLaTeX{pdf\/\LaTeX}
+\DeclareRobustCommand*\LuaLaTeX{Lua\LaTeX}
+\DeclareRobustCommand*\XeLaTeX{%
+X\ifdim\fontdimen1\font=0pt\kern-0.15em\fi
+\lower.5ex\hbox{\rotatebox[origin=c]{180}{E}}%
+\ifdim\fontdimen1\font=0pt\kern-0.15em\else\kern-0.275em\fi
+\LaTeX}
+
+\providecommand\setfontsize{}
+\RenewDocumentCommand\setfontsize{O{1.2} m}{%
+ \fontsize{#2}{\fpeval{#1*#2}}\selectfont}
+
+
+\newwrite\example@out
+\ProvideDocumentEnvironment{Esempio}{ O{\footnotesize} D(){0.50}}
+% All definitions and assignments are local
+% #1 := LaTeX font size command or \setfontsize{<size>}
+% %2 := \textwidth percentage for the code box; the complement, less the
+% column gap, for the resulting compiled code
+% Syntax: \begin{Esempio}[<size command>](<code-box percentage-width>)
+%
+{\par\addvspace{3.0ex plus 0.8ex minus 0.5ex}\vskip -\parskip
+\dimendef\Wboxu=2570 \dimendef\Wboxd=2572
+\Wboxu=#2\textwidth\relax
+\Wboxd=\dimexpr\linewidth-\columnsep-\Wboxu\relax
+\begingroup
+\@bsphack
+\immediate\openout\example@out\jobname-temp.tex
+\let\do\@makeother\dospecials\catcode`\^^M\active
+\def\verbatim@processline{%
+ \immediate\write\example@out{\the\verbatim@line}}%
+\verbatim@start\relax}%
+{\immediate\closeout\example@out\@esphack\endgroup
+\begin{lrbox}{0}%
+\begin{minipage}{\textwidth}%
+\begin{minipage}{\Wboxu}%
+#1\relax
+\verbatiminput{\jobname-temp.tex}
+\end{minipage}%
+\hfill
+\begin{minipage}{\Wboxd}\raggedleft
+\input{\jobname-temp}%
+\end{minipage}
+\end{minipage}%
+\end{lrbox}%
+
+\medskip
+\noindent\makebox[\textwidth]{\box0}%
+\par
+}
+
+\providecommand\hz{\hskip0pt}
+
+\newenvironment{ttsintassi}{\begin{lrbox}{0}
+ \minipage{\dimexpr\linewidth-2\fboxrule-2\fboxsep}\ttfamily\obeylines}%
+{\endminipage\end{lrbox}\center\fbox{\box0}\endcenter}
+
+
+%
+\begin{document}\errorcontextlines=100
+\maketitle
+\columnseprule=0.4pt
+\begin{multicols}{2}
+ \tableofcontents
+ \end{multicols}
+ \DocInput{wrapfig2.dtx}
+
+\end{document}
+%</driver>
+% \fi
+%
+% \begin{abstract}
+% This new package \pack{wrapfig2} is a fork that upgrades Donald
+% Arseneau's package \pack{wrapfig} (version 2.6, dated 2003) by
+% adding some \LaTeXiii definitions that accept a final optional star;
+% its presence changes the meaning of the first optional
+% argument so that it becomes a correction to the number of lines
+% that must be indented in order to receive the wrapped object.
+% A new environment is added to the traditional \Env{wrapfigure}
+% and \Env{wraptable}, namely \Env{wraptext}; it may be used
+% to wrap a small framed text block on a grey background; the
+% philosophy of this new environment is similar to that of the
+% other two environments, but the syntax is different.
+% \end{abstract}
+%
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \paragraph{Caution} This package requires a fairly recent
+% \LaTeX kernel, otherwise it won't work; any \LaTeX kernel dated
+% at least 2020 is~OK.
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \section{Introduction}
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The purpose of this package is twofold. On one side it tries
+% to modernise the original software by Donald Arseneau by
+% upgrading it to the \LaTeXiii modern language. On the other it
+% creates a new environment, with the same philosophy
+% of the original Arseneau's ones, such that a document author
+% can emphasise short blocks of text by framing them while
+% typesetting the text on a coloured background by means of
+% the \pack{tcolorbox} functionalities, and wrapping this
+% inserted text with the surrounding main text.
+%
+% The original software had some idiosyncrasies; Donald Arseneau
+% described them in the documentation of his package; I am sorry
+% to say that such idiosyncrasies have not been reduced; but in any case
+% the solution is to wrap the inserted object with a sufficient
+% number of lines, i.e. by a sufficiently long paragraph.
+%
+% The above implies that no wrapped object code should be inserted
+% by the end of a paragraph; again no object code should be inserted
+% within any list; not even close to the end or to the
+% beginning of section. Arseneau's code is capable of
+% specifying the wrapping number of lines such that two or more
+% paragraphs can be indented so as to wrap a longish insertion,
+% but it is wise to avoid such risky situations. Moreover, if the
+% inserted figure or table has a numbered caption, the number might
+% not result in the correct order with the normal corresponding
+% floating objects.
+%
+% Therefore the usefulness of the wrapping procedure depends very
+% much from the document author ability to move around his/her code
+% until a suitable position is found. Certainly a good place is
+% within a longish first section at the beginning of a new chapter.
+%
+% The code of this package does not do anything to correct such
+% idiosyncrasies. They are caused by the limitations of the
+% \cs{ShipOut} native \TeX/\LaTeXe macro, and very little can be done in
+% addition to what Arseneau already did.
+%
+% Another purpose of this package is to add an option so that the
+% \meta{number of indented lines} argument does not mean the total
+% number, but the correction number to add-to or subtract-from to the
+% value computed by the default mechanism devised by Arseneau. We assume
+% that any user first uses the software to insert an object to be wrapped
+% by the surrounding text without specifying any value with the
+% specific optional argument; then evaluates the result, and if the
+% space below the wrapped object is too large, or if such space is
+% too small s/he counts the necessary number of lines and specifies
+% it to be processed during another document compilation. When the
+% object to be wrapped is tall, it is very easy to miscount the
+% necessary number of lines, while is is very easy to evaluate the
+% necessary small correction to the default computed value.
+%
+% A third purpose of this package is to define a new environment,
+% \Env{wraptext}, to wrap a framed text block typeset on a grey
+% background as if it were a figure. On \texttt{texstackexchange}
+% a solution was suggested to a user who was asking for such an
+% arrangement; the solution resorted to a specific use of the
+% \Env{wrapfigure} environment. We thought that an \emph{ad hoc}
+% solution would be a better one, since the parameters to be used for a
+% figure have nothing or little to do with a text, therefore most
+% of them would be useless with a wrapped text. Nevertheless the
+% \meta{location} of the wrapped text and the optional correction
+% of the indented lines number would still be necessary. We added also
+% the possibility of optionally specifying the measure of the
+% wrapped text, even if this measure should not be too different
+% from a half of the wrapping text measure: with a value too different
+% from \texttt{0.5\cs{linewidth}} either the wrapped text has problems
+% with inter word spaces and hyphenation because of the small measure,
+% or, on the opposite, the indented lines of the wrapping text have
+% similar problems.
+%
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \section{Environment syntax}
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The new syntax for \Env{wrapfigure} and \Env{wraptable} is backwards
+% compatible with the original one: just a final optional star is
+% added to the original list of arguments.
+% As the list of arguments shows, the \Env{wraptext} environment has
+% similar features, but all its arguments are optional, so that they
+% may be specified independently from one another, provided that, when
+% they are more than one, they are specified in the order
+% shown in the syntax table.
+%
+% The optional star is available only for the standard \Env{wrapfigure}
+% and \Env{wraptable} environments because the backwards compatibility
+% requires the first four optional and mandatory arguments. When the
+% optional star is specified, the \meta{indented lines number} is
+% interpreted as the correction to the computed number.
+%
+% \begin{ttsintassi}\setfontsize{8.10}
+%\Bambiente{wrapfigure}\oarg{indented lines number}\marg{location}\oarg{overhang}\oarg{width}\meta{$\star$}
+%\qquad\meta{figure}
+%\Eambiente{wrapfigure}
+%~
+%\Bambiente{wraptable}\oarg{indented lines number}\marg{location}\oarg{overhang}\oarg{width}\meta{$\star$}
+%\qquad\meta{table}
+%\Eambiente{wraptable}
+%~
+%\Bambiente{wraptext}\oarg{location}\barg{width}\aarg{indented line number correction}\parg{caption label}
+%\qquad\meta{wrapped framed text}
+%\Eambiente{wraptext}
+% \end{ttsintassi}
+%
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%\section{Examples}
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% We display some examples by using fake objects such that suitably
+% long paragraphs are available; some fake language long paragraphs are
+% obtained by means of the \pack{kantlipsum} package functionalities.
+% They contain paragraphs that look as Kant's sentences, but we
+% doubt that Immanuel Kant ever wrote such texts\dots
+%
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{A wrapped figure}
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+%\begin{wrapfigure}{r}{50mm}*
+%\centering\unitlength=1mm
+%\begin{picture}(40,30)
+%\polygon(0,0)(40,0)(40,30)(0,30)
+%\Line(0,0)(40,30)\Line(0,30)(40,0)
+%\end{picture}
+%\caption{A rectangle}
+%\end{wrapfigure}
+%
+% \kant[1]
+%
+%
+% The code used to type the above figure is the following:
+%
+%\begin{flushleft}\obeylines%
+%\noindent\Bambiente{wrapfigure}\Marg{r}\Marg{50mm}
+%\cs{centering}\cs{unitlength}=1mm
+%\Bambiente{picture}\texttt{(40,30)}
+%\cs{polygon}\texttt{(0,0)(40,0)(40,30)(0,30)}
+%\cs{Line}\texttt{(0,0)(40,30)}\cs{Line}\texttt{(0,30)(40,0)}
+%\Eambiente{picture}
+%\cs{caption}\Marg{A rectangle with its diagonals}
+%\Eambiente{wrapfigure}
+%~
+%\cs{kant}\Oarg{1}
+%\end{flushleft}
+%
+% No asterisk was used because the package succeeded to correctly
+% compute the necessary number of indented lines.
+%
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{A wrapped table}
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Wrapping a small table is a little more difficult than wrapping
+% a figure, because the width of the inserted object is not known
+% exactly in advance and is difficult to estimate; therefore it is
+% possible that several trial compilations are necessary. In any
+% case a \cs{centering} command might help to center the table
+% within the indention of the wrapping text. Nevertheless the
+% software can compute the object width if a zero value is specified
+% or if the mandatory \meta{width} parameter is completely omitted;
+% this second possibility is a feature of this package, that uses a
+% \LaTeXiii property by which even a braced argument can be treated
+% as an optional argument with a predefined default value; see below
+% more details about this feature.
+%
+%\begin{wraptable}{l}
+%\centering
+% \begin{tabular}{cc}
+% \hline
+% First & Second\\
+% Third & Fourth\\
+% \hline
+%\end{tabular}
+%\caption{A small table}
+%\end{wraptable}
+%
+%\kant[2]
+%
+% The above wrapped small table has been typeset by means of the
+% following code.
+%\begin{flushleft}\ttfamily\obeylines
+%\Bambiente{wraptable}\Marg{l}
+%\quad\cs{centering}
+%\quad\Bambiente{tabular}\Marg{cc}
+%\qquad\cs{hline}
+%\qquad First \& Second\string \\
+%\qquad Third \& Fourth\string \\
+%\qquad\cs{hline}
+%\quad\Eambiente{tabular}
+%\quad\cs{caption}\Marg{A small table}
+%\Eambiente{wraptable}
+%\cs{kant}\Oarg{2}
+%\end{flushleft}
+%
+% You notice the absence of the braced width value; as said above,
+% this braced value is optional, and the software autonomously
+% computes the width of the wrapped object. This feature may be
+% useful in many instances, although we think that a smart use of
+% this width parameter might yield better looking results.
+%
+% On the opposite if the user estimates that the table with its
+% caption might use 5 lines, and specified such a value as the
+% first (optional) argument to the environment, the result would
+% be this poor one, with the last caption line overlapping the
+% wrapping text.
+%
+%\begin{wraptable}[5]{l}
+%\centering
+% \begin{tabular}{cc}
+% \hline
+% First & Second\\
+% Third & Fourth\\
+% \hline
+%\end{tabular}
+%\caption{A small table}
+%\end{wraptable}
+%\kant[2]
+%
+% If
+%
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{A wrapped text}
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \begin{wraptext}
+% Text, text, text, text, text, text, text, text, text, text, text.
+% \end{wraptext}
+% \kant[3]
+%\enlargethispage{-2\baselineskip}
+%
+% The above example was typeset with this simple code:
+%\begin{flushleft}\obeylines
+% \Bamb{wraptext}
+% \ttfamily Text, text, text, text, text, text, text, text, text, text, text.
+% \Eamb{wraptext}
+% \cs{kant}[3]
+%\end{flushleft}
+%
+% As it was previously shown, the syntax for the \Env{wraptext}
+% environment is a little different from that of the other two
+% environments. The logic behind it is substantially the same;
+% the \meta{width} parameter is optional; its preset value is
+% half the column width, that in one column typesetting mode
+% coincides with the text width. The wrapped text is typeset
+% in justified mode within a \Env{minipage} environment; the
+% measure of this mini page should not be too small (unless
+% the text is less than one line long) otherwise the inter
+% word spacing might be too large; at the same time the measure
+% of the mini page cannot be too large, otherwise the indented
+% wrapping lines, generally justified, might get a bad word
+% spacing. Therefore it is suggested to avoid specifying the
+% optional \meta{widh} outside the range of 40\% to 60\% the
+% column width. Actually specifying \texttt{0.2\cs{textwidth}}
+% or \texttt{0.4\cs{columnwidth}} when typesetting in two column
+% mode produces approximately the same result, because
+% \cs{columnwidth} is a little less than half the \cs{textwidth}.
+%
+% A warning is necessary: if a caption is entered
+% within the environment, such caption gets typeset within the
+% background coloured frame. We think that a framed text does not
+% require any caption; if such caption were necessary, then the
+% user should resort to other means, for example, to a standalone
+% small PDF file containing the framed shaded text to be imported
+% as a figure with the \amb{wrapfigure} environment.
+%
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \section{Remarks}
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The syntax of the original environments \amb{wrapfigure} and
+% \amb{wraptable} has not been changed, except for a last optional
+% star. The fact that the last braced argument is optional does not
+% change the backward compatibility with the original environments.
+%
+% Therefore the optional \meta{line number} argument maintains its
+% meaning, unless the optional star is specified; in such a case that
+% number assumes the meaning of a correction to the computed number
+% of the indented lines.
+%
+% The mandatory \meta{placement} maintains its meaning and the legal
+% values are \texttt{l} (left), \texttt{r} (right), \texttt{L}
+% (floating left), \texttt{R} (floating right), \texttt{i}
+% (inner margin), \texttt{o} (outer margin), \texttt{I}
+% (floating inner margin), \texttt{O} (floating outer margin).
+%
+% We tested all of them, but as a personal choice we prefer to
+% place the wrapped object at the left of the text, without
+% floating it and irrespective of the page number parity.
+%
+% As in the previous examples, we prefer to specify the wrapping
+% environment before a sufficiently long paragraph. Should the
+% paragraph be too short to completely wrap the object, all
+% the environments are capable of counting the number of indented
+% lines and to apply the \cs{overhang} command with the remaining
+% line number to the following paragraph(s); in these circumstances
+% it might be necessary to recourse to the optional star in order
+% to correct the indention, since the mechanism does not consider
+% the inter paragraph spacing that \TeX introduces only at ship~out
+% time.
+%
+% We avoid also to enter the wrapping environment before paragraphs
+% that are close to a page break; this action would tickle the
+% idiosyncrasies of the software, and requires moving the wrapping
+% environment some paragraphs before or after the preferred one; but
+% this can be done only while reviewing the document, because any
+% change in the previous source text might change the situation
+% if this adjustment is done while still editing the document.
+%
+% With the standard environments the optional parameter \meta{overhang}
+% does exactly what its name implies: the wrapped object protrudes
+% into the adjacent margin exactly by the specified amount. This
+% parameter is not available for the \Env{wraptext} environment;
+% we believe that a wrapped text logically pairs the wrapping text;
+% of course this opinion might be wrong and in future upgrades we
+% might add this functionality.
+%
+% The \meta{width} parameter has been already sufficiently described;
+% we just remember that for \Env{wraptext} this parameter is optional
+% and its default value amounts to half the current measure; it can
+% be specified but it should not be too different from 50\% the
+% current measure. For the standard environments this parameter value
+% is mandatory, but, we recall, for the redefined environments
+% \env{wrapfigure} and \env{wraptable}, this braced argument is optional.
+%
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \section{Other floating objects}
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Pictures and textual arrays may be floated by means of the standard
+% \amb{figure} and \amb{table} environments. But other floating
+% objects may be defined by means of the \pack{float} package,
+% just to name one, or classes. Besides floating, the main difference
+% is the name of the caption “label”: Figure, Table, Algorithm,
+% Example, and so on.
+%
+% If floating is not necessary, this package (as well as the original
+% one) allows to use the underlying environment \Env{wrapfloat}
+% that uses the same syntax as \Env{wrapfigure} plus the mandatory
+% name of the new object: even a figure might be introduced without
+% using \amb{wrapfigure}, by using instead:
+%\begin{flushleft}\ttfamily\obeylines
+%\Benv{wrapfloat}\Marg{figure}\oarg{line number}\marg{placement}\%
+%\quad \oarg{overhang}\marg{width}\meta{$\star$}
+%\qquad\qquad\meta{image}
+%\Eenv{wrapfloat}
+%\end{flushleft}
+% Another \meta{object} may be wrapped by using:
+%\begin{flushleft}\ttfamily\obeylines
+%\Benv{wrapfloat}\marg{object name}\oarg{line number}\marg{placement}\%
+%\quad \oarg{overhang}\marg{width}\meta{$\star$}
+%\qquad\qquad\meta{object}
+%\Eenv{wrapfloat}
+%\end{flushleft}
+%
+% If the floating \meta{placement} codes have to be used, another
+% floating object with the desired \meta{object name} has to be
+% previously defined by means of the functionalities of other
+% packages or classes.
+%
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \CheckSum{1061}
+% \StopEventually{}
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \section{The code}
+%^^A%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Here we describe and comment the code of this package; essentially
+% only the initial parts need some comments; because the final ones
+% are almost identical to the original Arseneau's code.
+%
+% We start with the usual specification of the format name and date,
+% and the identification of this specific package. We possibly load
+% the \pack{etoolbox} package, because we immediately need a
+% test on the existence of an @-protected macro; should this macro
+% already been defined by the class or other packages (including a
+% previous loading of this package or the previous Arseneau's one)
+% the loading is immediately aborted. If is was not previously loaded,
+% we load the \pack{xfp} package, that allows us to perform precise
+% calculations. Loading the \pack{xparse} package is necessary in
+% order to use one of its rare features that did not migrate
+% to the \LaTeX kernel. From the \LaTeX News Letter dated October 2020:
+%\begin{quote}
+% Most, but not all, of the argument types defined by \pack{xparse}
+% are now supported at the kernel level. In particular, the types
+% \texttt{g/G}, \texttt{l} and \texttt{u} are not provided by the
+% kernel code; these are \emph{deprecated} but still available by
+% explicitly loading \pack{xparse}. All other argument types are
+% now available directly within the \LaTeXe kernel.
+%\end{quote}
+% For now their availability eases the treatment of the backwards
+% compatibility of this software with the original \pack{wrapfig}
+% functionality. It deals with the mandatory \meta{width} argument
+% of the \pack{wrapfigure}, \pack{wraptable}, and \pack{wrapfloat}
+% environments, where it was possible to specify a zero value.
+% Now it is possible to omit it completely because it is a
+% \emph{braced optional argument}.
+%
+%\iffalse
+%<*package>
+%\fi
+
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}[2020-01-01]
+\ProvidesPackage{wrapfig2}%
+ [2021-11-30 v.4.0 Wrap text around figures, tables, framed text blocks]
+\@ifpackageloaded{etoolbox}{}{\RequirePackage{etoolbox}}
+\ifcsdef{c@WF@wrappedlines}{\endinput}{}
+\ifcsdef{fpeval}{}{\RequirePackage{xfp}}
+\RequirePackage{xparse}
+
+% \end{macrocode}
+%
+% Next we define some dimensions, boxes, token registers, \TeX counters,
+% and alias names. The \cs{WF@correctlines@switch} \TeX numeric register
+% (not a \LaTeX counter) is going to be used a boolean switch; if its
+% value is zero, il means “false”, otherwise is “true”; in the other
+% definitions below, it will be set only to 0 or 1, depending on the
+% presence of the optional star.
+% \begin{macrocode}
+\newdimen\wrapoverhang \wrapoverhang\z@
+\newdimen\WF@size
+\newcounter{WF@wrappedlines}
+\newbox\WF@box
+\newbox\NWF@box
+\newtoks\WF@everypar
+\newif\ifWF@float
+\newcount\WF@correctlines@switch
+\newdimen\insertwidth
+\let\@@parshape\parshape
+\let\WF@@everypar\everypar
+
+% \end{macrocode}
+%
+% In what follows we are going to use very often the functionalities
+% of the \pack{xparse} package that are mostly already included into
+% the \LaTeX kernel; but, since we use one of this functionalities that
+% have not migrated to the \LaTeX kernel, we load it, as they remain
+% available with that package; nevertheless we specified a
+% \LaTeX format date insuring that the \LaTeXiii syntax is available.
+%
+% Should the format file be an older one, a multitude of errors would be
+% produced, and the user should take care to load the \pack{xparse}
+% and \pack{xfp} packages before loading \pack{wrapfig2}.
+% Notice that most of the \pack{xparse} package functionalities
+% at the date required for the format file are already included. The
+% \pack{xparse} package has been available about in 2018; should the user
+% have available a definitely older \TeX system installation, s/he
+% should upgrade it, or must avoid using this \pack{wrapfig2} package
+% and use the original one; if s/he needs to wrap text, s/he should
+% resort to some ingenious tricks to do it.
+%
+% The opening command of the \Env{wrapfloat} environment receives
+% the mandatory and optional arguments plus the name of the particular
+% object to be wrapped. It is used to define the prefix label of the
+% caption number in case that the object is described with a caption. The
+% optional star is not explicit, because it is going to be read by
+% the \cs{WF@wr} macro.
+%
+% The closing command of \Env{wrapfloat} performs most of
+% the work necessary to wrap the box that contains the object
+% to be wrapped, but certain tasks are demanded to other service
+% macros.
+%
+% It may set the width of the box if the \meta{width} parameter
+% is specified; otherwise it closes the \cs{hbox} that was used;
+% then it closes the main vertical box \cs{WF@box}. After executing
+% \cs{WF@floatstyhook}, necessary when package \pack{float.sty}
+% has been used, it saves the \meta{overhang} value to be used when
+% wrapping is actually performed; then it verifies if the box height
+% is too high to fit, or is too short; possibly re-boxes this box
+% in the same box register with a negative initial vertical skip
+% that raises the box contents.
+%
+% The definitions of the \Env{wrapfigure} and \Env{wraptable}
+% environments are very simple by means of the underlaying
+% \Env{wrapfloat} environments.
+% \begin{macrocode}
+\NewDocumentEnvironment{wrapfigure}{o m o G{0pt}}%
+ {\wrapfloat{figure}[#1]{#2}[#3]{#4}}%
+ {\endwrapfloat}
+
+\NewDocumentEnvironment{wraptable}{o m o G{0pt}}%
+ {\wrapfloat{table}[#1]{#2}[#3]{#4}}%
+ {\endwrapfloat}
+
+% \end{macrocode}
+%
+% The definition of the \Env{wraptext} environment is more detailed,
+% because most of the computations must be done on the actual text
+% to be wrapped, that does not have a specific width; moreover the
+% inserted text must not be too wide, nor too short in order to avoid
+% problems for its justification or the justification of the wrapping
+% text. The framed box width is preset to 50\% of the normal text measure,
+% but it can be optionally specified to a different value (not too
+% different from 50\%), while for the other environments the wrapped
+% material width is an \emph{optional braced parameter}.
+%
+% For what concerns the \Env{wraptext} environment, see below,
+% because the code is a little more complicated and requires some
+% explanation.
+% In facts the first statement argument description list does not
+% contain any descriptor for an optional star. There is no need
+% because the computation of the insertion block height is pretty
+% precise and at most the user might desire one line more or less
+% depending on the measure of the whole text, and that of the
+% inserted block and/or the measure of the indented wrapped lines.
+%
+% It is true that some of the input parameters specified to the opening
+% command with \LaTeXiii are available also to the closing commands; see
+% the last paragraph of section~2 in the \pack{xparse} documentation.
+% But the following definition, besides using special delimiters for
+% optional parameters, uses the separate opening and closing
+% macros of the \Env{wrapfloat} environment; such procedure
+% apparently breaks this second availability of the input parameters,
+% therefore it is necessary to save them into local macros or count
+% registers (assignments of \TeX count registers are \emph{local},
+% while assignment of the \LaTeX\ named counters, through the
+% \cs{setcounter} macro and its siblings, are \emph{global}) so
+% that we can use their values within the closing commands.
+%
+% The \cs{NWF@box} has been assigned at the beginning; remember
+% that \LaTeXiii registers of any kind are not limited in number
+% as they were some years ago even with \LaTeXe.
+% The last opening commands are conceived to box the object to be
+% wrapped, typeset within a \Env{minipage} with the default or
+% specified width; such box, and the \Env{tcolorbox} and
+% \Env{minipage} environments are closed at the beginning of the
+% closing commands, so that what is necessary in order to place the
+% wrapped boxed text is easy to be executed.
+%
+% The number of indented lines is computed by means of the
+% \cs{fpeval} \LaTeXiii function; among the operands of this
+% function there is the value \texttt{2} used to take into
+% account the vertical space used by \Env{tcolorbox} to
+% separate the frame from its contents. It is possible that
+% a value of \texttt{3} might reduce the probability of using the
+% \meta{line number correction}. But it is not always true and we
+% found that the chosen value is a better choice.
+%
+% Eventually the opening \Env{wrapfloat} statement is created by
+% expanding the whole line complete of arguments, by means of the
+% usual trick of defining a dummy macro within a group that contains
+% among its expansion the group closing command, so that while
+% it is being executed, it deletes itself from memory.
+% \begin{macrocode}
+\NewDocumentEnvironment{wraptext}%
+ {O{l} D||{0.5\columnwidth} D<>{0} D(){figure}}%
+{% Open environment
+ \insertwidth=#2\relax
+ \def\textplacement{#1}%
+ \def\textcorrection{#3}%
+ \def\WF@caption@label{#4}%
+ \begin{lrbox}\NWF@box% This box is to contain the framed text
+ \minipage{\insertwidth}%
+ \tcolorbox
+}{% Close environment
+ \endtcolorbox\endminipage\end{lrbox}%
+ \edef\NWF@wli% \NWF@wli is a macro, not a counter
+ {%
+ \fpeval{%
+ round((\ht\NWF@box+\dp\NWF@box)/\baselineskip,0)+2+\textcorrection
+ }%
+ }%
+ \ifhmode\unskip\else\leavevmode\noindent\fi
+ \bgroup\edef\x{\egroup\noexpand\wrapfloat{\WF@caption@label}[\NWF@wli]%
+ {\textplacement}{\the\insertwidth}}\x
+ \box\NWF@box % Output framed box containing text
+ \endwrapfloat
+ \ignorespaces
+}
+
+% \end{macrocode}
+%
+% Now comes the definition of the fundamental environment \Env{wrapfloat};
+% compared to the original Arseneau's definition it is much longer,
+% but it contains the code that Arseneau, who wrote the code in
+% \LaTeXe language, had to split in several macros in order to
+% handle the multitude of interspersed mandatory and optional
+% arguments.
+%
+% The main function of this environment is to handle the box that
+% contains the figure, or the table, or the framed test, or what
+% else, so that the inserted box is preceded and followed by the
+% suitable vertical spaces, and it is possible to compute the
+% number of lines to be indented; often this computed number is correct;
+% but in certain cases, when the code is used too close or
+% within prohibited wrapping text, such number might need to be
+% corrected. As it can be seen the optional star is not among
+% the argument descriptors of the opening commands; it will be
+% the following macro \cs{WR@wr} to take care of examining
+% the list of arguments and see if a star has been specified and
+% not yet read by the preceding commands.
+%
+% In order to handle any kind of wrapped object, this environment
+% first argument is the \meta{caption label}. It may remain blank;
+% but for wrapping figures or tables their respective definitions
+% specify the name of the floating object they belong to; it is not
+% necessary that there exists a floating environment with the same
+% name of the wrapped object, when its wrapping environment is not
+% specified with a floating \meta{placement} argument.
+%
+% \begin{macrocode}
+
+\NewDocumentEnvironment{wrapfloat}{m o m o G{\z@}}%
+ {\def\@captype{#1}\WF@wr[#2]{#3}[#4]{#5}}%
+ {\ifdim\hsize>\z@
+ \par\hrule\@width\hsize\@height\z@ % force width with invisible rule
+ \else
+ \unskip \egroup \box\z@ % or close hbox
+ \fi
+ \egroup % close the vtop box; its width now is known
+ \WF@floatstyhook % support for float.sty
+ \def\width{\wd\WF@box}%
+ \setlength\wrapoverhang{\WF@ovh}%
+ \xdef\WF@ovh{\the\wrapoverhang}% save until wrapping
+ \ifdim\ht\WF@box>\topskip \ht\WF@box\z@ \fi% too high, set flag
+ \ifdim\ht\WF@box<.5\p@ % too short, move up
+ \global\setbox\WF@box\vtop{\vskip-1.4ex\unvbox\WF@box}%
+ \fi
+ \global\WF@size=% compute total box hight with \fpeval
+ \fpeval{\ht\WF@box+\dp\WF@box+1.5\baselineskip+\tw@\intextsep}\p@
+ \aftergroup\WF@startfloating % use even when not really floating
+ \unless\ifWF@float
+ \ifhmode
+ {\unskip \parfillskip\z@skip \par \vskip-\parskip}%
+ \aftergroup\noindent
+ \fi
+ \fi
+ \global\@ignoretrue
+ }
+
+% \end{macrocode}
+%
+% The working macro \cs{WF@wr} is defined with the \LaTeXiii
+% language; it grabs all the optional and mandatory arguments
+% in a single step, contrary to \LaTeXe that requires to split
+% the various steps in separate macros. In the definition code
+% we use also some commands, such as \cs{unless}, originally
+% defined by the \eTeX typesetting program extensions, that have
+% been included in the \pdfLaTeX, \XeLaTeX and \LuaLaTeX kernels
+% several years ago.
+%
+% Notice that the optional first (optional) argument, that represents
+% the number of indented lines or their correction number, is saved
+% into the macro \cs{WF@wli}, but if this argument is not specified,
+% \cs{WF@wli} is assigned the value zero. The same happens for the
+% \meta{overhang} optional argument.
+%
+% After these adjustments, it computes the box total height plus some
+% fixed amounts needed mostly to set the wrapped material below the
+% first wrapping text first line. Here is where the \LaTeXiii
+% \cs{fpeval} computing macro comes into play so as to assign such
+% height to \cs{WF@size}. Some unusual macros are executed; they
+% were devised by Arseneau to deal with possibly floating wrapped
+% objects. The optional star is not accepted by this macro; if the user
+% specified it, it is still in the input flux; notice that the
+% \Env{wraptext} environment does not accept the optional star; if
+% the user specifies it for this environment, an asterisk appears
+% at the beginning of the wrapped text.
+%
+% The mandatory \texttt{\#4} \meta{width} parameter (actually a
+% \meta{optional braced parameter}) may be specified
+% to be \texttt{0pt}; in any case \texttt{0pt} is the default parameter
+% value; if so, the object is treated at its natural width, by
+% boxing it into an hbox and using this hbox width as the working width
+% \begin{macrocode}
+\NewDocumentCommand\WF@wr{o m o m s}{%
+ \xdef\WF@wfname{wrap\@captype\space}%
+ \unless\ifvoid\WF@box
+ \WFclear \WF@collision
+ \fi
+ \xdef\WF@place{\string`\@car#2r\@nil}%
+ \ifnum\lccode\WF@place=\WF@place
+ \global\WF@floatfalse
+ \else
+ \global\WF@floattrue
+ \fi
+ \ifx\parshape\WF@fudgeparshape
+ \unless\ifWF@float\\WF@collision\fi
+ \else
+ \ifx\par\@@par
+ \ifnum\@@parshape>\z@\WF@conflict\fi
+ \else
+ \WF@conflict
+ \fi
+ \fi
+ \IfValueTF{#1}% save optional line number or correction
+ {\gdef\WF@wli{#1}}%
+ {\gdef\WF@wli{0}}%
+%
+ \IfValueTF{#3}% save optional overhang
+ {\gdef\WF@ovh{#3}}%
+ {\gdef\WF@ovh{\z@}}%
+%
+ \global\setbox\WF@box\vtop\bgroup \setlength\hsize{#4}% set width
+ \ifdim\hsize>\z@
+ \@parboxrestore
+ \else
+ \setbox\z@\hbox\bgroup
+ \let\wf@@caption\caption
+ \let\caption\wf@caption
+ \ignorespaces
+ \fi
+ \IfBooleanTF{#5}% if the asterisk is present set the numerical switch
+ {\global\WF@correctlines@switch=\@ne}%
+ {\global\WF@correctlines@switch=\z@}%
+ \global\@ignoretrue
+}
+
+% \end{macrocode}
+%
+% At this point the main box \cs{WF@box} is opened in order to
+% store the object to be wrapped; with this box height the software
+% is going to compute the number of lines to be indented, unless
+% such a number has been specified and no star was added to the
+% input parameters.
+%
+% Also the \amb{wraptext} environment uses a box to collect the
+% framed text; the name of this second box must be different from
+% \cs{WF@box} otherwise interference of the various tasks produces
+% unrecoverable errors. This is why at the beginning of this
+% package we defined two different boxes: \cs{WF@box} and \cs{NWF@box}.
+%
+% The trick of creating an alias for the \cs{caption} macro is
+% used by Arseneau to redefine one of the two macros according to
+% certain conditions. Here \cs{wf@caption} is actually redefined
+% if the \meta{width} parameter has been specified.
+% \begin{macrocode}
+\def\wf@caption{\relax% redefine \wf@caption in case \hsize is zero
+ \ifdim\hsize>\z@
+ \let\caption\wf@@caption
+ \else
+ \unskip \egroup \hsize\wd\z@ \@parboxrestore \box\z@% empty \box0
+ \fi
+ \caption
+}
+
+% \end{macrocode}
+%
+% One of these unusual macros was introduced by Arseneau
+% to deal with paragraph parameters and possibly to float the
+% object to be wrapped.
+% \begin{macrocode}
+\def\WF@startfloating{%
+ \WF@everypar\expandafter{\the\everypar}\let\everypar\WF@everypar
+ \WF@@everypar{\ifvoid\WF@box\else\WF@floathand\fi \the\everypar
+ \WF@wraphand
+}}
+
+% \end{macrocode}
+% The following macro is for floating wrapping environments.
+% \begin{macrocode}
+\def\WF@floathand{%
+ \ifx\parshape\WF@fudgeparshape
+ \WF@fltmes
+ \else
+ \ifx\par\@@par
+ \ifnum\@@parshape=\z@
+ \ifdim\hangindent=\z@
+ \setbox\z@\lastbox \begingroup
+ \@@par \WF@@everypar{}\WF@putfigmaybe
+ \endgroup % after this group start wrapping
+ \unless\ifvoid\z@ % replace indentation
+ \box\z@
+ \fi
+ \else
+ \WF@fltmes
+ \fi
+ \else
+ \WF@fltmes
+ \fi
+ \else
+ \WF@fltmes
+ \fi
+ \fi}
+
+% \end{macrocode}
+%
+% On the contrary if there is enough space or if the wrapped object
+% cannot float, it gets output here.
+% \begin{macrocode}
+\def\WF@putfigmaybe{%
+\ifinner
+ \vskip-\parskip \global\WF@floatfalse
+ \let\pagetotal\maxdimen % kludge flag for "not top of page"
+\else % outer page
+ \@tempdima\pagedepth % save page depth
+ {\advance\parskip\@tempdima\vskip-\parskip}% back up to base line
+ \penalty\interlinepenalty % update page parameters
+ \@tempdimb\pagegoal \advance\@tempdimb-\pagetotal % room left on page
+ \ifdim \@tempdimb<\z@ % page already full
+ \global\WF@floatfalse
+ \unless\ifdim-\@tempdimb>\pageshrink
+ \pagebreak
+ \fi
+ \else
+ \ifdim\WF@size>\@tempdimb% box too high does not fit in \@tempdimb
+ \ifWF@float
+ \dimen@.5\baselineskip
+ \else
+ \dimen@ 2\baselineskip
+ \fi
+ \ifdim\pagestretch>\dimen@ \dimen@\pagestretch \fi
+ \ifdim\pagefilstretch>\z@ \dimen@\@tempdimb \fi
+ \ifdim\pagefillstretch>\z@ \dimen@\@tempdimb \fi
+ \advance\dimen@.5\baselineskip
+ \ifdim\dimen@>\@tempdimb % stretch page contents
+ \global\WF@floatfalse \pagebreak
+ \fi
+ \else % box fits in \@tempdimb
+ \global\WF@floatfalse
+ \fi
+ \fi
+ \vskip\@tempdima\relax % return erased page depth
+\fi
+\noindent
+\ifWF@float
+ \WF@fltmes
+\else % place insertion here
+ \WF@info{Put \WF@wfname here:}%
+ {\ifodd
+ \if@twoside\c@page\else\@ne\fi % assign l/r to i/o placement
+ \lccode`i`l\lccode`o`r\else \lccode`i`r\lccode`o`l%
+ \fi
+ \xdef\WF@place{\the\lccode\lccode\WF@place}%
+ }% twice to get only l or r
+ \hbox to\z@{% llap o rlap depending on lor r; calc effective width
+ \@tempdima\wd\WF@box \@tempdimb\WF@ovh
+ \advance\@tempdima-\@tempdimb \advance\@tempdima\columnsep
+ \@tempdimb\hsize \advance\@tempdimb-\@tempdima
+ \xdef\WF@adjlw{\the\@tempdima}%
+ \ifnum `l=\WF@place % object on left
+ \hss
+ \def\@tempa{\kern\columnsep}% take right gap into action
+ \else % insert on light
+ \@tempdima\z@ % no left indentation
+ \kern\@tempdimb \kern\columnsep
+ \def\@tempa{\hss}% object overlaps space to the right
+ \fi
+ \ifdim\@tempdimb<\hsize
+ \xdef\WF@wrapil{\the\@tempdima \the\@tempdimb}% indent.n and length
+ \xdef\WF@adjtlm{\the\@tempdima}%
+ \else
+ \xdef\WF@wrapil{\z@ \the\hsize}%
+ \xdef\WF@adjlw{\z@}\xdef\WF@adjtlm{\z@}%
+ \fi
+ \ifdim\pagetotal=\z@ % put object at top of page \thepage
+ \global\advance\WF@size-\intextsep
+ \else % put object in middle of the page
+ \setbox\WF@box\hbox{\lower\intextsep\box\WF@box}%
+ \fi
+ \dp\WF@box\z@
+ \box\WF@box
+ \@tempa
+ }% end \hbox to 0pt
+ \aftergroup\WF@startwrapping
+\fi
+}
+
+% \end{macrocode}
+%
+% Here comes the very important macro that counts the wrapping indented
+% lines, so that wrapping is correct; of course the limitations
+% of the \TeX and \LaTeX processing (needed to ship out a complete
+% page) forbid to take into account the spaces inserted between
+% paragraphs and/or those inserted between entries of various
+% listings. The idiosyncrasies of this package arise from the
+% fact that this macro cannot preview actions that have not
+% yet taken place when this macro is executed.
+%
+% This macro is the one that counts the lines to be indented by
+% rounding the division of the box height by the current base
+% line skip. Notice that \texttt{WF@wrappedlines} is the name
+% of a \LaTeX named counter, not of a \TeX numeric register;
+% therefore special LaTeX commands, such as \cs{setocounter} or
+% \cs{value}, have to be used in order to set or access the
+% numerical value stored within the \TeX register associated
+% to the \LaTeX counter name.
+% \begin{macrocode}
+\def\WF@startwrapping{%
+ \ifnum\WF@wli=\z@ % no number was specified
+ \setcounter{WF@wrappedlines}%
+ {\fpeval{round(\WF@size/\baselineskip,0)}}%
+ \xdef\WF@wli{\value{WF@wrappedlines}}%
+ \else
+ \ifnum\WF@correctlines@switch>\z@ % line number correction
+ \setcounter{WF@wrappedlines}
+ {\fpeval{round((\WF@size)/\baselineskip,0)+\WF@wli}}%
+ \xdef\WF@wli{\value{WF@wrappedlines}}%
+ \else
+ \setcounter{WF@wrappedlines}{\WF@wli}% absolute number of lines
+ \global\advance\c@WF@wrappedlines\@ne
+ \fi
+ \fi
+ \ifnum\c@WF@wrappedlines>\@ne % fine tuning
+ \let\parshape\WF@fudgeparshape \let\WF@pspars\@empty \let\WF@@par\par
+ \def\@setpar##1{\def\WF@@par{##1}}\def\par{\@par}\let\@par\WF@mypar
+ \xdef\WF@restoretol{\tolerance\the\tolerance}\tolerance9999
+ \advance\linewidth-\WF@adjlw \advance\@totalleftmargin\WF@adjtlm
+ \fi}
+
+% \end{macrocode}
+%
+% The next macro is the one that actually indents the wrapping text lines
+% and keeps track of the number of such processed lines. It can work
+% on more than a single paragraph. It resorts to service macros that
+% reiterate as long as the number of indented lines is lower than the
+% computed number of lines. Possibly this process could be defined by
+% means od the \texttt{dowhile} or \texttt{whiledo} \LaTeXiii functions.
+% By now we did not afford this task, because first we would like to
+% see if the overall software is reliable.
+% \begin{macrocode}
+\def\WF@wraphand{% for indenting one or more paragraphs
+ \ifnum\c@WF@wrappedlines<\tw@
+ \WF@finale
+ \else \begingroup % create a parshape command
+ \@tempcnta\@ne \let\WF@wrapil\relax \gdef\WF@ps{}%
+ \@whilenum
+ \@tempcnta<\c@WF@wrappedlines\do{% repeated indentation
+ \xdef\WF@ps{\WF@ps\WF@wrapil}\advance\@tempcnta\@ne
+ }%
+ \endgroup
+ \ifx\WF@pspars\@empty
+ \@@parshape\c@WF@wrappedlines \WF@ps \WF@noil
+ \else % use external `parshape' values to modify my parshape
+ \WF@modps
+ \fi
+ \fi
+}
+
+% \end{macrocode}
+%
+% This macro resets the paragraph properties and terminates the job.
+% \begin{macrocode}
+\def\WF@mypar{\relax
+ \WF@@par
+ \ifnum\@@parshape=\z@
+ \let\WF@pspars\@empty % reset parshape
+ \fi
+ \global\advance\c@WF@wrappedlines-\prevgraf \prevgraf\z@
+ \ifnum\c@WF@wrappedlines<\tw@
+ \WF@finale
+ \fi
+}
+
+% \end{macrocode}
+%
+% These macros are to modify the paragraph settings.
+% \begin{macrocode}
+\def\WF@modps{\begingroup
+ \afterassignment\@tempdimb \@tempdima\WF@pspars % a=indent.num, b= width
+ \advance\@tempdima-\WF@adjtlm \advance\@tempdimb\WF@adjlw
+ \let\WF@wrapil\WF@pspars
+ \edef\@tempb{\@@parshape\c@WF@wrappedlines
+ \WF@ps \the\@tempdima \the\@tempdimb}%
+ \expandafter\endgroup\@tempb
+}
+
+\let\@@setpar\@setpar
+\def\WF@noil{\z@ \hsize}
+\let\WF@pspars\@empty
+
+\def\WF@fudgeparshape{\relax
+ \ifnum\c@WF@wrappedlines<\tw@
+ \WF@finale
+ \else
+ \afterassignment\WF@fudgeparshapee \fam
+ \fi
+}
+
+\def\WF@fudgeparshapee{%
+ \ifnum\fam=\@ne \expandafter
+ \WF@parshapeee
+ \else
+ \WF@conflict \@@parshape\fam
+ \fi
+}
+
+\def\WF@parshapeee#1#2{%
+ \begingroup\delimitershortfall#1%
+ \nulldelimiterspace#2% \advance \nulldelimiterspace by \WF@adjlw
+ \edef\@tempa{\def\noexpand\WF@pspars{%
+ \the\delimitershortfall \the\nulldelimiterspace}}%
+ \expandafter\endgroup\@tempa \WF@wraphand
+}
+
+% \end{macrocode}
+%
+% The following macro is the one that actually ends the single
+% wrapping job.
+% \begin{macrocode}
+\def\WF@finale{%
+ \ifx\parshape\WF@fudgeparshape
+ \WF@restoretol \let\@setpar\@@setpar \let\par\WF@@par
+ \advance\linewidth\WF@adjlw \advance\@totalleftmargin-\WF@adjtlm
+ \WF@info{Finish wrapping text}%
+ \ifx\par\@@par
+ \def\@par{\let\par\@@par\par}%
+ \else
+ \let\@par\WF@@par
+ \fi
+ \let\parshape\@@parshape
+ \parshape=\ifx\WF@pspars\@empty
+ \z@
+ \else
+ \@ne \WF@pspars
+ \fi
+ \fi
+ \ifvoid\WF@box
+ \ifx\everypar\WF@everypar
+ \let\everypar\WF@@everypar \everypar\expandafter{\the\WF@everypar}%
+ \fi
+ \fi
+}
+
+% \end{macrocode}
+%
+% At the very end everything is restored, and the used boxes are emptied.
+% \begin{macrocode}
+\newcommand{\WFclear}{\par
+ \unless\ifvoid\WF@box
+ \vskip\bigskipamount \box\WF@box
+ \let\everypar\WF@@everypar \everypar\expandafter{\the\WF@everypar}%
+ \fi
+ \global\c@WF@wrappedlines\z@ \WF@finale
+ \global\WF@correctlines@switch\z@
+}
+
+% \end{macrocode}
+%
+% The following code is one of those “dirty tricks” by which a macro
+% defined within a group is executed with the help of an
+%\cs{expandafter} command that bypasses an \cs{endgroup}; by so doing
+% nothing local to the group remains in memory.
+% \begin{macrocode}
+\begingroup
+ \toks0={\let\everypar\WF@@everypar
+ \everypar\expandafter{\the\WF@everypar}%
+ \let\parshape\@@parshape
+ \let\@setpar\@@setpar
+ }
+ \toks1=\expandafter{\@arrayparboxrestore}%
+ \toks2=\expandafter{\clearpage}%
+ \edef\@tempa{%
+ \def\noexpand\@arrayparboxrestore{\the\toks0 \the\toks1}%
+ \def\noexpand\clearpage
+ {\noexpand\protect\noexpand\WFclear \the\toks2}}%
+ \expandafter
+ \endgroup\@tempa
+
+% \end{macrocode}
+%
+% Donald Arseneau classifies the following macro as the one
+% that “pampers the RevTeX's stupidity”.
+% \begin{macrocode}
+\@ifundefined{@capwidth}{\let\@capwidth\hsize}{}%
+
+% \end{macrocode}
+%
+% This one, instead, issues a warning if a specific name conflicts
+% with another.
+% \begin{macrocode}
+\def\WF@conflict{\WF@warning
+ {\WF@wfname used inside a conflicting environment}}%
+
+% \end{macrocode}
+%
+% While this one issues a warning when a wrapping environment is
+% too close to another one.
+% \begin{macrocode}
+\def\WF@collision{\WF@warning{Collision between wrapping environments}}%
+
+% \end{macrocode}
+%
+% And this one is when two wrapping environments are too close to
+% one another so that the second one is forced to float.
+% \begin{macrocode}
+\def\WF@fltmes{% message for floats
+ \ifWF@float
+ \WF@info{\WF@wfname floats}%
+ \else
+ \WF@warning{Stationary \WF@wfname forced to float}%
+ \fi
+}
+
+% \end{macrocode}
+%
+% These two aliases are just service macros for this package; in
+% particular, the second one is used to insert info of any kind
+% within a source file.
+% \begin{macrocode}
+\let\WF@warning\@warning
+\let\WF@info\@gobble
+
+% \end{macrocode}
+%
+% Arseneau says that his \pack{wrapfig} package is already compatible
+% with package \pack{float.sty}, since, after defining a new float
+% \meta{foo}, it suffices to define the new environment
+% \Env{wrap\meta{foo}}. This fork version of his package should do
+% the same: is suffices to mimic the definitions of environments
+% \Env{wrapfigure} or \Env{wraptable}.
+%
+% Here there is some Arseneau's code that renders his \pack{wrapfig}
+% code compatible with \cs{newfloat} of class \class{memoir}, and
+% with \cs{newfoatlist} of package \pack{ccaption}. We leave his code
+% hereafter; but we did not test it with this package.
+% \begin{macrocode}
+\let\WF@floatstyhook\relax
+%
+\@ifundefined{newfloat}{}{% \newfloat comes from somewhere besides
+% float.sty
+ \@ifundefined{restylefloat}{%
+ \@ifclassloaded{memoir}{%
+ \toks@=\expandafter\expandafter\expandafter
+ {\csname\string\newfloat\endcsname [{#1}]{#2}{#3}{#4}%
+ \newenvironment{wrap#2}{\wrapfloat{#2}}{\endwrapfloat}%
+ }% Mmmm; this might be wrong. Not tested
+ \edef\@tempa{\def\expandafter\noexpand\csname\string\newfloat\endcsname
+ [##1]##2##3##4{\the\toks@}}%
+ \@tempa
+ }% end memoir support
+ {}% other origins of \newfloat here?
+ }{% float.sty handler. Ops: Two versions for different versions
+% Changing \floatstyle or \restylefloat changes \newfloat too.
+ \@ifundefined{float@restyle}%
+ {% older float.sty
+ \toks@=\expandafter{\restylefloat{#1}% env. might be undefined
+ \@namedef{wrap#1}{%
+ \def\@captype{#1}\@nameuse{fst@#1}%
+ \def\WF@floatstyhook{\let\@currbox\WF@box \columnwidth\wd\WF@box
+ \global\setbox\WF@box\float@makebox}%
+ \@ifnextchar[\WF@wr{\WF@wr[]}}%
+ \expandafter\let\csname endwrap#1\endcsname \endwrapfigure
+ }%
+ \edef\@tempa{\def\noexpand\restylefloat##1{\the\toks@}}%
+ }{% newer float.sty: uses \float@restyle, and \float@makebox
+% takes width arg
+ \toks@=\expandafter{\float@restyle{#1}% env. might be undefined
+ \@namedef{wrap#1}{\def\@captype{#1}\@nameuse{fst@#1}%
+ \def\WF@floatstyhook{\let\@currbox\WF@box
+ \global\setbox\WF@box\float@makebox{\wd\WF@box}}%
+ \@ifnextchar[\WF@wr{\WF@wr[]}}%
+ \expandafter\let\csname endwrap#1\endcsname \endwrapfigure
+ }%
+ \edef\@tempa{\def\noexpand\float@restyle##1{\the\toks@}}%
+ }%
+ \@tempa % perform redefinitions
+%
+ }% end float.sty handler
+}% end redefinitions of \newfloat
+
+\ifcsname newfloatlist\endcsname% support ccaption.sty
+ \toks@=\expandafter\expandafter\expandafter
+ {\csname\string\newfloatlist\endcsname [{#1}]{#2}{#3}{#4}{#5}%
+ \@namedef{wrap#2}{\wrapfloat{#2}}%
+ \expandafter\let\csname endwrap#2\endcsname \endwrapfloat
+ }%
+ \edef\@tempa{%
+ \def\expandafter\noexpand\csname\string\newfloatlist\endcsname
+ [##1]##2##3##4##5{\the\toks@}}%
+ \@tempa
+\fi
+
+% \end{macrocode}
+% We never described the package options; this code was present
+% in Arseneau's code and ve leave it here, with the necessary
+% package name change. We think that this \opz{verbose} option
+% was and remains useless, since the instances of command
+% \cs{WF@info} were mostly commented out in the original code;
+% in any case, input of this code is stopped if the
+% \cs{DeclareOption} command is not defined; this command was
+% defined with \LaTeXe; therefore this is a residual of the old
+% times when \LaTeXccix was still in use, more than 25 years
+% ago\dots
+% \begin{macrocode}
+\@ifundefined{DeclareOption}{\endinput}{%
+\def\WF@warning{\PackageWarning{wrapfig2}}%
+\DeclareOption{verbose}{\def\WF@info{\PackageInfo{wrapfig2}}}%
+\ProcessOptions
+\AtEndDocument{\WFclear}}%
+
+\endinput
+% \end{macrocode}
+
+%\iffalse
+%</package>
+%\fi
+% \Finale
+%
+%^^A \endinput \ No newline at end of file
diff --git a/macros/latex/contrib/wrapfig2/wrapfig2.pdf b/macros/latex/contrib/wrapfig2/wrapfig2.pdf
new file mode 100644
index 0000000000..5e60317074
--- /dev/null
+++ b/macros/latex/contrib/wrapfig2/wrapfig2.pdf
Binary files differ
diff --git a/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl b/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
index ccf33e55fe..b5dc61bcfb 100644
--- a/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
+++ b/systems/texlive/tlnet/tlpkg/installer/ctan-mirrors.pl
@@ -3,9 +3,6 @@ $mirrors = {
'Algeria' => {
'http://ctan.epst-tlemcen.dz/tex-archive/' => 1,
},
- 'Morocco' => {
- 'https://mirror.marwan.ma/ctan/' => 1,
- },
'South Africa' => {
'http://ftp.leg.uct.ac.za/pub/packages/ctan/' => 1,
'http://ftp.sun.ac.za/ftp/CTAN/' => 1,
@@ -48,7 +45,6 @@ $mirrors = {
'https://cran.asia/tex/' => 1,
'https://ftp.harukasan.org/CTAN/' => 1,
'https://ftp.kaist.ac.kr/pub/tex-archive/' => 1,
- 'https://mirror.kakao.com/CTAN/' => 1,
'https://mirror.navercorp.com/CTAN/' => 1,
'https://mirror.yongbok.net/ctan/' => 1,
},
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb b/systems/texlive/tlnet/tlpkg/texlive.tlpdb
index 46a8714ec3..8e8029e4d9 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb
@@ -26,11 +26,11 @@ depend container_split_src_files/1
depend frozen/0
depend minrelease/2016
depend release/2021
-depend revision/61408
+depend revision/61415
name 00texlive.image
category TLCore
-revision 61401
+revision 61415
shortdesc TeX Live files only in the source repository
longdesc The files here are not copied by the installer and containers
longdesc are not built for them; they exist only in the source
@@ -1087,6 +1087,7 @@ runfiles size=12497
tlpkg/tlpsrc/cntperchap.tlpsrc
tlpkg/tlpsrc/cochineal.tlpsrc
tlpkg/tlpsrc/codeanatomy.tlpsrc
+ tlpkg/tlpsrc/codebox.tlpsrc
tlpkg/tlpsrc/codedoc.tlpsrc
tlpkg/tlpsrc/codehigh.tlpsrc
tlpkg/tlpsrc/codepage.tlpsrc
@@ -4502,7 +4503,7 @@ depend setting_available_architectures:aarch64-linux amd64-freebsd amd64-netbsd
name 00texlive.installer
category TLCore
-revision 61403
+revision 61410
shortdesc TeX Live standalone installer package
longdesc This package defines the files to go into the installer
longdesc archives (install-tl-unx.tar.gz, install-tl.zip) built by the
@@ -24373,7 +24374,7 @@ catalogue-version 0.2
name asmeconf
category Package
-revision 57833
+revision 61412
shortdesc A LaTeX template for ASME conference papers
relocated 1
longdesc The asmeconf class provides a LaTeX template for ASME
@@ -24392,11 +24393,11 @@ longdesc archivability (PDF/A), and multilingual support. The code is
longdesc compatible with pdfLaTeX or LuaLaTeX. This LaTeX template is
longdesc not a publication of ASME, but it does conform to ASME's
longdesc currently published guidelines for conference papers.
-containersize 24956
-containerchecksum c9a11e0e1d2fb5ef9c674b571bf8de631fd1b329fef165cd5a1a0028f80a9447757bb769b743c69e29405b1688ae292110cf958f6bfc9092026a3277bcd78b8d
-doccontainersize 1473344
-doccontainerchecksum 11db98dc9a9556e7e03b5b5e5284b19ef97c295ba3f21a9e3e0ee2cac712d81a9bbc485b27133f8f2bba158037d4388c1bfbf4dde241715a2386b564a51c45f0
-docfiles size=793
+containersize 27720
+containerchecksum 17ae6017f0f6535a9448592a7f515283fdf859453ee93a7bc20cc5b9b4dacb0d9201666a9035366a2344493131a931635201921feb8888d49920a924db6b87b6
+doccontainersize 1453400
+doccontainerchecksum 604fb5e989c1cf9f8007fbe04947cb1211a2f009e4f07b96e2c1435d4dca295db0bb05ddb8f1c3e94c9326c5f9b8475d1445da1b305dff079ea75a8475e58d08
+docfiles size=802
RELOC/doc/latex/asmeconf/README.md details="Readme"
RELOC/doc/latex/asmeconf/asmeconf-sample.bib
RELOC/doc/latex/asmeconf/asmeconf-template.pdf details="Example of use"
@@ -24412,7 +24413,7 @@ docfiles size=793
RELOC/doc/latex/asmeconf/sample-figure-1.pdf
RELOC/doc/latex/asmeconf/sample-figure-2a.pdf
RELOC/doc/latex/asmeconf/sample-figure-2b.pdf
-runfiles size=28
+runfiles size=32
RELOC/bibtex/bst/asmeconf/asmeconf.bst
RELOC/tex/latex/asmeconf/asmeconf.cls
catalogue-contact-bugs https://github.com/John02139/asmeconf/issues
@@ -24420,7 +24421,7 @@ catalogue-contact-support https://github.com/John02139/asmeconf/issues
catalogue-ctan /macros/latex/contrib/asmeconf
catalogue-license mit
catalogue-topics bibtex-sty class confproc engineering scientific-docs
-catalogue-version 1.26
+catalogue-version 1.27
name asmejour
category Package
@@ -65074,6 +65075,41 @@ catalogue-license lppl1.3c
catalogue-topics program-doc graphics pgf-tikz expl3
catalogue-version 0.4-Alpha
+name codebox
+category Package
+revision 61415
+shortdesc Highlighted source code in a fancy box
+relocated 1
+longdesc This LaTeX3 package provides environments codebox and codeview
+longdesc to typset with an environment body, and macros \codefile and
+longdesc \cvfile to typeset programming source code from a file in a
+longdesc fancy box. Starred versions of these environments and macros
+longdesc are provided to add a comment at the bottom of the fancy box.
+longdesc The package is based on tcolorbox, minted, and listings.
+containersize 3596
+containerchecksum 1d5ac25299755e3fff1adf6e0d06daf87d5f2885ed59f65374c97a89f3060f83353fe53eef5cd9c73c680b817d8cb8b4cab090d702e0e98875f8fb5565c508b3
+doccontainersize 361352
+doccontainerchecksum 335ecc7cb568e2f06be995148a1da0e979e3fb07e294c734ec7298b9d4ca70eb270a5bcb01dadffc3bd33cde298bf44ca33009caacfc66df8a7a1edbd9ae7d8d
+docfiles size=111
+ RELOC/doc/latex/codebox/README.md details="Readme"
+ RELOC/doc/latex/codebox/build.sh
+ RELOC/doc/latex/codebox/codebox-doc-en.pdf details="Package documentation (English)"
+ RELOC/doc/latex/codebox/codebox-doc-en.tex
+ RELOC/doc/latex/codebox/codebox.dtx
+ RELOC/doc/latex/codebox/codebox.pdf details="Package documentation (Chinese)" language="zh"
+ RELOC/doc/latex/codebox/ctxdoc-en.cls
+ RELOC/doc/latex/codebox/hellojava.java
+ RELOC/doc/latex/codebox/hellopy.py
+ RELOC/doc/latex/codebox/test.c
+runfiles size=4
+ RELOC/tex/latex/codebox/codebox.sty
+catalogue-contact-bugs https://github.com/registor/codebox/issues
+catalogue-contact-repository https://github.com/registor/codebox
+catalogue-ctan /macros/latex/contrib/codebox
+catalogue-license lppl1.3c
+catalogue-topics boxing listing decoration synt-hlt expl3
+catalogue-version 1.0.0
+
name codedoc
category Package
revision 17630
@@ -67755,7 +67791,7 @@ containerchecksum 0568a3251d71fb3106fbb3961427200419ae1df22d39b5e72c608e2d94fc35
name collection-latexextra
category Collection
-revision 61391
+revision 61415
shortdesc LaTeX additional packages
relocated 1
longdesc A very large collection of add-on packages for LaTeX.
@@ -67952,6 +67988,7 @@ depend cmsd
depend cnltx
depend cntformats
depend cntperchap
+depend codebox
depend codedoc
depend codehigh
depend codepage
@@ -69171,8 +69208,8 @@ depend zref-check
depend zref-clever
depend zwgetfdate
depend zwpagelayout
-containersize 6520
-containerchecksum 3847dbf4a6898463ab7a9d6b5a8ffb82cf8c835028b3277881771acaf1e1a24473c87545bbf499c4be02568d8b5ad5121612cfb16fed668d7297a103c36a8514
+containersize 6524
+containerchecksum 87e0f99ccb8a1c83daca15bc5922588dee935eecd6e30a8d4841113a6077a621fa71a73937022ef6d5d1c9bde8f8915bd00d678c7c8402a95cd388b1abd774a2
name collection-latexrecommended
category Collection
@@ -99560,21 +99597,21 @@ catalogue-topics notes editorial
name easybook
category Package
-revision 61390
+revision 61413
shortdesc Typeset Chinese theses or books
relocated 1
longdesc Easybook is a minimalist style template based on the ctexbook
longdesc book document class.
-containersize 17976
-containerchecksum e395d9dcc90cd918699ae22d69daa3dab42fdc6b9f953f6100365bc53ec4cfeb7fd2e566768515d38daba0118627a9e74f61a76e6211373925cb81356a970d74
-doccontainersize 616096
-doccontainerchecksum beb5a3765845dbdc60e820403fae515f16cf94603a9211889a0c96e3661617ee52275e9d871c10fc9a782267c8383c960ae044046fc8245034894c35039438ba
+containersize 17960
+containerchecksum c59d18285e07b123028c441322fb1e8afa2ba18994dbc15cd468ab50e70bf5df9d5578fb2e0bef1517cf43a13cfae365f4583ce3c1269fafc1a03541123dc1e2
+doccontainersize 616460
+doccontainerchecksum 680f64ad614ad78b3e51367d41946f6a34bc1edff9029285de66f4cde79fa85bfa7b976be9f0a5fd8ee867f43b81b86209ff8bfa4313fffdc15de7e15a00949e
docfiles size=168
RELOC/doc/latex/easybook/README.md details="Readme"
RELOC/doc/latex/easybook/easybook.pdf details="Package documentation" language="zh"
RELOC/doc/latex/easybook/easybook.tex
-srccontainersize 18020
-srccontainerchecksum 7da7237423388725e4d34ce4a268f7095b621789444a02445914bb520c00c8c27098b9682318338f7d00357470b2b7ad21ed9ef0c673742c423173fd8a1c3bcb
+srccontainersize 18000
+srccontainerchecksum 50222faec79a3e413b2db338aac0662265e0929e85cec6cb5982f96317e788aac0682c7eb7e213b2e01a04bde62054bd4d5f451912040a606338babd433913a8
srcfiles size=22
RELOC/source/latex/easybook/easybook.dtx
RELOC/source/latex/easybook/easybook.ins
@@ -99587,7 +99624,7 @@ catalogue-contact-repository https://gitee.com/texl3/easybook
catalogue-ctan /macros/latex/contrib/easybook
catalogue-license lppl1.3c
catalogue-topics book-pub class chinese expl3
-catalogue-version 1.42C
+catalogue-version 1.42E
name easyfig
category Package
@@ -285604,34 +285641,36 @@ catalogue-topics comp-mgmt expl3
name termsim
category Package
-revision 61399
+revision 61414
shortdesc Simulate Win10, Ubuntu, and Mac terminals
relocated 1
longdesc This LaTeX3 package provides environments terminal and
longdesc terminal*, and macros \termfile and \termfile* to simulate
longdesc Win10, Ubuntu and Mac terminals. It is based on tcolorbox,
longdesc minted and listings.
-containersize 4028
-containerchecksum 9ccb8baf846158103d2aefccfbd37549b9e5b1ef7364cf0924819d0e1db68054d5e4179f3650a60cb3fd074904de11820c3b7c157727d77007b8e17c7e41a1c1
-doccontainersize 378116
-doccontainerchecksum 929ae3228ca6191d93ce71da6033b9e77a15a6c3da3f7f9f9fc2b1d3bb0cf0c03b9a6be2b21a68b4794212c4e02c8691cb42e84dbf822f83e4e777d0154e7ae4
-docfiles size=98
+containersize 3860
+containerchecksum 132615cbdbe257f2c7643414ef4b577053425e457a2e2ee2a9b4d8d56a7e6758db587b7f5223ef1a324931f5468ac5365b7dde7b971312bc8b8ea069ee5efb9e
+doccontainersize 390080
+doccontainerchecksum af5047a490608fbb5769b6b4d3dad3fac6b9b20abb5dbaf20d08a633045ea45ca1a01f572d3f0701567a91a8429ae0c7279fa82f054e6fe0802d413765c46ccc
+docfiles size=111
RELOC/doc/latex/termsim/README.md details="Readme"
RELOC/doc/latex/termsim/build.sh
- RELOC/doc/latex/termsim/termsim-en.pdf details="Package documentation (English)"
- RELOC/doc/latex/termsim/termsim-zh-cn.pdf details="Package documentation (Chinese)" language="zh"
-srccontainersize 9788
-srccontainerchecksum 53bc3a548c8894db2f13de8661cefa29cd4360ce59a0384f46dda6c4f79eb1a74d10acbf35ec1187426898043df53daf4efe62f1a50238c7234c493fa2a30da0
+ RELOC/doc/latex/termsim/ctxdoc-en.cls
+ RELOC/doc/latex/termsim/termsim-doc-en.pdf details="Package documentation (English)"
+ RELOC/doc/latex/termsim/termsim-doc-en.tex
+ RELOC/doc/latex/termsim/termsim.pdf details="Package documentation (Chinese)" language="zh"
+srccontainersize 9472
+srccontainerchecksum 45ad375a19ca939496f6f6546c9d2568367b3cd49c11fe1b2d94785448eb679d3e82c41a3282df054027636ca367b86b82dc3d937b42056398c23622ffa6e34a
srcfiles size=12
RELOC/source/latex/termsim/termsim.dtx
-runfiles size=5
+runfiles size=4
RELOC/tex/latex/termsim/termsim.sty
catalogue-contact-bugs https://github.com/registor/termsim/issues
catalogue-contact-repository https://github.com/registor/termsim
catalogue-ctan /macros/latex/contrib/termsim
catalogue-license lppl1.3c
catalogue-topics listing boxing comp-sci expl3
-catalogue-version 1.1.0
+catalogue-version 1.1.1
name testhyphens
category Package
@@ -298007,7 +298046,7 @@ docfiles size=376
name texlive-scripts
category TLCore
-revision 61403
+revision 61410
shortdesc TeX Live infrastructure programs
longdesc Includes install-tl, tl-portable, rungs, etc.; not needed for
longdesc tlmgr to run but still ours. Not included in tlcritical.
@@ -298015,10 +298054,10 @@ depend texlive-scripts.ARCH
depend texlive.infra
execute addMap mathpple.map
postaction shortcut type=menu name="TeX Live command-line" cmd=TEXDIR/tlpkg/installer/tl-cmd.bat
-containersize 108268
-containerchecksum dd5fa688b3d81df4a7ff7662641fa6d2b5e5edcf89fb0d07ace0ca3e0214f0e11031d80b75aef3b81158544567471e3bb43ce75f284a39c53eb63a4e582ac9cd
-doccontainersize 402264
-doccontainerchecksum 145b27ed1a045ce1a33f3f223a7489089dd894e7e48dbec9f6cb65e8cd75c2551e6b746ab03cd0832464e902fdcb945f3c9c7ccf135ecaaff779cdbd4616b65f
+containersize 108236
+containerchecksum d416567a07229a424dbc3fc7d8ca3333eebd4a176d6ded56e31648f7d94bd2ccc100996566236b598942e680973471efeb3dc8f242990f1ff8e3390460c5a52b
+doccontainersize 402268
+doccontainerchecksum e1103262c70e3d92f3ee6bf8f5b0a5ff740b5fc165270d0b11f5b63870cd6cd71b3b77ee86c8f23a4d511990e52ec3a35b82185e1e2f28793ecc54698571b2ce
docfiles size=500
doc.html
texmf-dist/doc/man/man1/fmtutil-sys.1
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5 b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
index 4ada15d4f7..7461a13b6b 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.md5
@@ -1 +1 @@
-ae1296d19630638dc4ff1c6f5de32623 texlive.tlpdb
+4f482b323f7aa9844e3f827bfd3928d1 texlive.tlpdb
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512 b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
index 5bcac15702..542ae47c95 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
@@ -1 +1 @@
-11cc4b94c09f5e65cced48d08ff29a02b47fbf888a93fd67cbd25e1920df6fcc804a164a52cfb0070497abeea4fa401f8fff244387e4614bbc41022b6899eace texlive.tlpdb
+223937b3c6d14005cd62e2271105e4b08b55c5dc4bcb9138233d2eb98a6e56158f953c13fd818a5c58ae8922c523c46895e187ea29126fce9bbe6d387602fe6e texlive.tlpdb
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
index 198be27048..5a96bdc9ee 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512.asc
@@ -1,10 +1,10 @@
-----BEGIN PGP SIGNATURE-----
-iQEcBAEBCgAGBQJhx70iAAoJEEzhh34ZQ4xwydYH/jJ93enUlSmzngK/KNU+RfaR
-kGsKCww4xD5z3DHMS8FbUSNwYLlJOml+0sV0YMeGQ6A1qX2mB/npYvNN+zUUGX4C
-ia8QB89MPgqWMqv2yVFVAxTIW/AP714sbDpytNWBsQpCHa7KAnWz5tJ7vLUe9r46
-2ITx1qzyuEnn3CeUZ67IE563FUvvC80Hyp0jzWWNufLLmYSDnkVYaRmXLu+jzQdI
-4ih47V2HfNkrF13kdklrC6E9Vd9NlOWHVtm1TuV7oZp4N22dKAoH2i5wxmOQHmnR
-0YsiMPktZdMI5SnpbNkI0TQlhiN5vAvpBcqr7RlTJpw0tjDaMLzlgEdYRhMoamg=
-=438h
+iQEcBAEBCgAGBQJhyQ6eAAoJEEzhh34ZQ4xwQMAH/3IFshkGLP73TPaBHUXUxA4J
+Uy/EYbyd5momv9+zDBN3HOFOSAQfAbshKkjG1I0yvWl1PabfP5n99mCoX2A2eScW
+qBRTlsk1qQMuIExqa2YVLuJt1C4hUgABwqTyvGTnZA9i+oR+cuhxJLq3QXXxzQv2
+zFzLe9uzZf/N+OquP3egmelH0wfi5CwNxMj/1AGjT40w3x+AwjcLLylIEDgl0gIj
+1/ZvgUOmU277ErdYyjl7SSKzgowhGodH7gj3H9/Rrb0ZhLdNQIesgtIlKVVixmZ7
+15FyaryfYjFiJ3Q+YcTwy4BYjxi6aHzJ3x+8YKSY7eVAoUlgMns2KwcH7sC/QuI=
+=vd5v
-----END PGP SIGNATURE-----
diff --git a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
index 3b6073281c..132d070980 100644
--- a/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
+++ b/systems/texlive/tlnet/tlpkg/texlive.tlpdb.xz
Binary files differ
diff --git a/systems/win32/miktex/tm/packages/next/pr.ini b/systems/win32/miktex/tm/packages/next/pr.ini
index 45b9b460c3..94a8f4909b 100644
--- a/systems/win32/miktex/tm/packages/next/pr.ini
+++ b/systems/win32/miktex/tm/packages/next/pr.ini
@@ -1,13 +1,13 @@
[repository]
-date=1640553500
+date=1640639911
lastupd=miktex-arctrl-bin-2.9 miktex-arctrl-bin-x64-2.9 miktex-asymptote-bin-2.9 miktex-asymptote-bin-x64-2.9 miktex-autosp-bin-2.9 miktex-autosp-bin-x64-2.9 miktex-axohelp-bin-2.9 miktex-axohelp-bin-x64-2.9 miktex-bibarts-bin-2.9 miktex-bibarts-bin-x64-2.9 miktex-bibtex-bin-2.9 miktex-bibtex-bin-x64-2.9 miktex-bibtex8bit-bin-2.9 miktex-bibtex8bit-bin-x64-2.9 miktex-bzip2-bin-2.9 miktex-bzip2-bin-x64-2.9 miktex-cairo-bin-2.9 miktex-cairo-bin-x64-2.9 miktex-chktex-bin-2.9 miktex-chktex-bin-x64-2.9
-lstdigest=d0f0128a8bec2f0e328b0b71d8b4d040
+lstdigest=870a5d73cef428a23cd3fa8e460ca8a2
numpkg=5156
relstate=next
-version=8030
+version=8031
;;;;This configuration file is signed by a MiKTeX maintainer. The signature follows.
;;;;-----BEGIN MIKTEX SIGNATURE-----
-;;;; signature/miktex: ktdvl2vbe3nzPUS51EFHJr9sq9uso2sdZXq6cfSvIQ0thg0cXjPOooFJTHLargDfENSHiYuVDtciQ3TDLTUoQ+rBqLDDkp+VN3MZdldMc55LtqZ/SVHk41f61n4RTKTnOEreWWWhSUCr4z3sfXLEle4EaGYnJ0aFYyoaoVhob8WJajq/anzFzyncywSx7SkUcPKHc17V0+NwoGQ0kBDh2ePEl78xGG9fqWSLfRCzFjZRqkPCvUpKdVAlfYjY44bc8FeS3nYTNh3Z5I+00eWSXU5WHHMXqAVgsW3qPqQuzT4uWwFgAovW263KD+e+/N8mFYL3ISvcThW1wtBIpVm7DA==
+;;;; signature/miktex: dvKiymANZkoruxr3Pc9AiwJ702ULlNSpQ1/JTFRgKcaGqpFIbooT9QDpghZBfsEEzbKYczzzCuWuV8dH3u0Mb8dlRF4DuHTZIDbwRlvZJwDLe5agnOdtQKrHDaVWZkU1ByOuiSs1uhoaW5mY9IfMr9sgaTemJUSL9AncL4vM9uro6ZHa2OkMo38KdXbwPy8O0XkXLSM0cyTqSP2DXCU5nkddW5Ks/F3VEzGUqv/3uquFU7NT7B4823GGPPj7LiE5FNf8pXGsumRMYwuh9SfRdPFKXO6pu4Ao/DawrLpvaGwlG8p7FnYScUl6JEcYLRS1U1978O+It6mop2Qi3kLTvQ==
;;;;-----END MIKTEX SIGNATURE-----
diff --git a/systems/win32/miktex/tm/packages/pr.ini b/systems/win32/miktex/tm/packages/pr.ini
index a5e7ace9ca..4b2033cf67 100644
--- a/systems/win32/miktex/tm/packages/pr.ini
+++ b/systems/win32/miktex/tm/packages/pr.ini
@@ -1,13 +1,13 @@
[repository]
-date=1640553106
+date=1640639498
lastupd=miktex-misc ptex-fontmaps ptex-fontmaps__source arara arara__doc arara__source autopuncitems autopuncitems__doc autopuncitems__source beaulivre beaulivre__doc beaulivre__source biblatex-spbasic biblatex-spbasic__doc biblatex-spbasic__source colorist colorist__doc colorist__source easybook easybook__doc
-lstdigest=227869799ccee98b820efe8c06926828
+lstdigest=b904c4fdc6fd9c6e35fc25f8db426795
numpkg=5154
relstate=stable
-version=8030
+version=8031
;;;;This configuration file is signed by a MiKTeX maintainer. The signature follows.
;;;;-----BEGIN MIKTEX SIGNATURE-----
-;;;; signature/miktex: ZNlcvqzz2W0aHjAES2wNin0M7EbvjHwqDv0305i8MizsFDRrOy/7n9ICz89SkNobDgJ95/TGoUC/sYcwZCtntpKcNGN9OSUSCw2EyKtKHXS949M2k90pmf8/VoEdCfmvnB5IusnnEVa0KLy3Ypq+MDXwi45cnNUIedOKhFgL8o5HF4Q+0/7rG/XTVTBp98buNn6lbfeLVBXsI55eswj9v0ZckHUtclXh4q7fuGo2kqtgdShjgvzHeWZQm8wNSN89v0zae3KmkuIE4Kq85XicWF/D2N3xJAD9BgI1hXZoTLtulrCFLHyTQEmhMEYk1DKwunkwpLk5i3DCNtRCYQx9+A==
+;;;; signature/miktex: GmRDzU48g4NR3R9ezbwPJoI2uzXg3YTQ0ggn59h7P0MbbSu2mE6r3Laha7UBbSQwurThX5qoAeAy88Fg4N3cvDzlvxZc8rFzrSPMe4L5oymkJzbCtfCgCMXY1W0lRfFXu8a4zT/I6Pw2Kgdkay39GF/L41fNIuRAxnMZdfluC2KGxbaumKy2lzoIBiumtO4vmqPfzTAhM9/TcgSz+a0wJN7grqaDDiJqZsqIwyXGkrtWfZB13EFkd6Z6iSHvQ5uU9kJA54rh/tVNHt7BOO8Rc/5TrxCI+OxnnloVY9eMME1MWtLjjkoLtGOyDjtun3240TdSBrEGJdqjJRwWypy6iQ==
;;;;-----END MIKTEX SIGNATURE-----
diff --git a/timestamp b/timestamp
index f8262ce67c..e1c2321017 100644
--- a/timestamp
+++ b/timestamp
@@ -2,4 +2,4 @@
# The source CTAN of this site's material:
dante.ctan.org
# The year-month-day-hour-minute of this site's material:
-2021-12-27-02-02
+2021-12-28-02-02